Amarsia
Concepts

Client tools

Configure client-side tools that pause an agent for input, documents, or a connected application capability.

Overview

Client tools are capabilities implemented by your application or an Amarsia hosted route. They let an assistant pause a v2 agent turn, collect structured answers or a document, and continue the same run after the result arrives.

Client tools are separate from actions and messages. Client-tool calls and results are tool usage, linked server actions are action logs, and chat_messages contains only actual user and assistant messages.

The model may send an actual assistant message and request a client tool in the same turn. The message is stored and shown immediately; the tool request remains separate and blocks only when its result is required.

How it works

  1. Configure the tool on the assistant.
  2. A client advertises the tool names it can currently handle.
  3. The run returns run_status: "waiting_for_client_action" with one or more calls.
  4. The client resolves every pending call_id.
  5. The same v2 conversation endpoint resolves the pending calls with conversation_id and tool_results.

The SDK performs capability advertisement, refresh, handler invocation, and result submission. Use the REST loop only when you need to manage those steps yourself.

Configuration

Configure tools under Tools & Knowledge Base in the assistant dashboard.

FieldRequiredMeaning
nameYesUnique 1–64 character name beginning with a letter and containing only letters, numbers, underscores, or hyphens
descriptionYesExplains when and why the model should call the tool
availabilityYesalways or when_connected
AvailabilityBehaviorUse for
when_connectedExposed only when the current request advertises a matching capabilityModals, clipboard access, or other functions that need the current application
alwaysExposed even when no capable browser is connected; the latest agent run can wait until one connectsEmailed links, delayed approvals, questions, and document requests

The dashboard does not require or expose custom schema authoring. A connected SDK handler can attach inputSchema; its request-time schema is used while that client is connected.

const lookupCustomer = Object.assign(
  async ({ customerId }: Record<string, unknown>) => ({
    customerId,
    active: true,
  }),
  {
    inputSchema: {
      type: "object",
      properties: {
        customerId: { type: "string" },
      },
      required: ["customerId"],
    },
  },
)

An always tool can block without a connected browser. A when_connected tool is not offered unless a matching capability is present.

Built-in tools

ask_user

ask_user requests one or more structured questions.

ArgumentTypeRequiredMeaning
questionsarrayYesOne or more question objects
questions[].idstringYesStable answer identifier
questions[].questionstringYesPrompt shown to the person
questions[].input_typestringYessingle_select, multi_select, or text
questions[].optionsstring[]Select inputsAllowed choices
questions[].allow_otherbooleanNoWhether another choice is allowed

Return every requested ID exactly once:

{
  "answers": [
    { "id": "goal", "value": "Build strength" },
    { "id": "days", "value": ["Monday", "Thursday"] }
  ]
}

Text and single-select answers use a non-empty string. Multi-select answers use an array of strings.

upload_document

upload_document requests a file using a required prompt, optional accepted MIME types in accept, and optional multiple behavior. Return one or more uploaded files as { "content": MessageContent[] }.

{
  "content": [
    {
      "type": "url",
      "mime_type": "application/pdf",
      "file_uri": "https://files.example.com/agreement.pdf"
    }
  ]
}

The hosted /agent route uploads the selected file before submitting this output. A custom client can return multiple content parts when the call requests multiple documents.

Resolution and conflicts

A result submission must include one result for every pending call and no unknown call IDs. When multiple clients resolve the same round, the first valid matching result set wins.

An identical retry is idempotent. A later result set with the same call IDs but different outputs returns 409 action_result_conflict; refresh current state and keep the accepted result.

The latest pending client action in an agent conversation does not expire. The legacy non-agent v2 pause and resume flow retains its existing pending-run expiry.