Amarsia
Client Usage

Conversations

Build ordinary stateful chat with the unchanged v1 SDK, React, streaming, message history, and conversation metadata.

Overview

Use client.conversation for ordinary multi-turn chat. It uses the existing v1 conversation API, supports streaming, and remains unchanged by the durable agent protocol.

Choose client.agent instead when work must reconnect while running, wait for client tools across page closes, expose progress and tool summaries, or become permanently completed.

NeedUse
Normal request-and-response chatclient.conversation.run()
Token streamingclient.conversation.stream()
Durable client actions and reconnectclient.agent
React durable agent stateuseAgent(client)

Start a conversation

const conversation = client.conversation
conversation.start()

const data = await conversation.run({
  content: [{ type: "text", text: "Help me with order 4821." }],
  variables: { CUSTOMER_TIER: "pro" },
  meta: { userId: "user_123", channel: "web-chat" },
})

await saveConversationId(data.conversation_id)

variables, meta, and triggerId apply only when creating the conversation. Save conversation_id from the response.

Continue or stream

Bind a saved ID before continuing:

client.conversation.start(savedConversationId)

await client.conversation.run({
  content: [{ type: "text", text: "It still has not arrived." }],
  historyLimit: 10,
})

await client.conversation.stream({
  content: [{ type: "text", text: "Summarize my options." }],
  historyLimit: 10,
})

During streaming, read conversation.live. After completion, read conversation.data?.content.

Load messages and list conversations

const messages = await client.conversation.loadMessages({
  conversationId: savedConversationId,
  page: 1,
  pageSize: 20,
})

const conversations = await client.conversation.list({
  page: 1,
  pageSize: 20,
  meta: { userId: "user_123" },
})

loadMessages() returns the items array and stores pagination in messagesPageInfo. list() returns conversations and stores pagination in conversationsPageInfo.

The messages REST response now includes optional lifecycle fields used by durable agents. Existing v1 clients can ignore them; message pagination and the items shape are unchanged.

Client tools

conversation.run({ clientTools }) supports the older request-scoped v2 tool loop, but the handler promise must remain alive and pending non-agent runs can expire. Prefer client.agent for customer-facing client tools, reconnect, multiple browsers, progress, and explicit tool resolution.

await client.agent.start({
  content: [{ type: "text", text: "Start my assessment." }],
  clientTools: {
    ask_user: async ({ questions }) => ({
      answers: await showQuestions(questions),
    }),
  },
})

Common pitfalls

  • Store conversation_id after the first response.
  • Do not pass variables, meta, or triggerId after a conversation ID is active.
  • Do not use v1 streaming for durable agent turns; v2 agent execution is non-streaming.
  • Do not treat tool summaries or pending actions as chat messages.