Skip to content

Client tools ​

A client tool is a function in your page that the agent can call: add a product to the cart, open a page, fill in a form, read what's on screen. You describe it (a name, what it does, a JSON Schema for its arguments) and give a handler; when the agent decides to use it, the server sends the call to the visitor's page, your handler runs, and its result goes back to the agent.

js
WirefaceChat.registerTool('add_to_cart', {
  description: 'Add a product to the visitor\'s cart. Use the SKU from the product list.',
  parameters: {
    type: 'object',
    properties: {
      sku: { type: 'string', description: 'The product SKU' },
      quantity: { type: 'integer', minimum: 1, default: 1 },
    },
    required: ['sku'],
  },
  confirm: true,
  async handler({ sku, quantity = 1 }, { signal }) {
    const res = await fetch('/api/cart', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({ sku, quantity }),
      signal,
    });
    if (!res.ok) throw new Error(`The cart said ${res.status}`);
    return { added: sku, cartCount: (await res.json()).count };
  },
});

You can also pass tools to boot() as tools: { add_to_cart: { ... } }, or use useWirefaceTool() in React.

1. Allow them on the bot ​

Page tools are off by default: a page could register anything, so the bot decides which it accepts. In the bot's Tools tab (tools.client):

  • turn on client tools (tools.client.enabled);
  • list the tool names it may use (tools.client.allow), or * for any. The default, an empty list, allows none;
  • publish.

The page's tools then reach the agent with the conversation, in text chat and with every voice engine. A tool name can't reuse a built-in tool's name, and an HTTP or MCP tool of the same name wins.

2. Describe it well ​

The agent only knows what you tell it:

  • Names are letters, digits and _, up to 64 characters, not starting with a digit. Make them say what they do.
  • The description (up to 2,000 characters) should say when to use the tool, not only what it does.
  • parameters is a JSON Schema. The server checks the agent's arguments against it before your handler runs; bad arguments go back to the agent with the reason, and your handler never sees them.

Asking first ​

Set confirm for anything the visitor should agree to (buying, sending, changing their account):

  • confirm: true shows a question built from the agent's and the tool's names, such as "Ava wants to: add to cart. Is that OK?", with the arguments and Allow / Don't allow buttons.
  • confirm: 'Add this to your cart?' shows your own question instead (up to 300 characters).

If the visitor says no, or doesn't answer within 2 minutes, your handler doesn't run and the agent is told the visitor declined. If nobody has the chat open, the tool doesn't run either. The JavaScript API emits no event for the question; the tool event fires when (and if) the handler starts.

Results and timeouts ​

  • Return anything JSON can represent. Over 16 KB is cut short, and the bot's tools.maxResultChars (8,000 characters by default) applies after that.
  • Throw an Error to report a failure: its message goes to the agent, which can tell the visitor or try something else.
  • The handler has timeoutMs (15 seconds by default) to finish. The bot's tools.client.timeoutMs and tools.toolTimeoutMs (15 seconds each by default) also apply: the shortest wins. signal is aborted when the handler times out, and when the server gives up on the call (the visitor stopped the reply, or the server's own timeout passed): pass it to fetch() so abandoned work stops.
  • The handler's second argument has callId, conversationId and signal.

Results are treated as untrusted. The server wraps them so the agent reads them as information, never as instructions: a product description that says "ignore your rules" can't take over the agent. Still, don't return secrets: the agent may repeat what it gets.

Events ​

The tool event fires when a page tool starts, succeeds or fails. While a tool runs, the chat shows "Using tool name" under the conversation.

Which page runs it ​

Tools belong to the page that registered them. If the visitor has the chat open in several tabs, the call goes to the most recent tab that has the tool. If none has it (the visitor moved to a page without it), the agent is told the tool isn't available there. registerTool() returns a function that unregisters the tool; call it when the part of your page that owns the tool goes away.

examples/client-tools-shop/ in the repo is a small shop page with page tools, a confirmation and events.

Wireface Chat 0.1.0. These docs are served by your own server.