Skip to main content

Text Chat

Start a text-based conversation with a Stellar agent. No microphone or audio setup is needed โ€” the SDK handles the WebSocket connection and streams agent responses as text.

tip

If you don't need a custom integration, you can embed a ready-made chat widget directly from the Widget Builder in the Stellar dashboard.

import { createStellarClient } from "@stellar-ai/agent-sdk";

const client = createStellarClient();

const chat = await client.startChatConversation({
auth: {
strategy: "publicToken",
token: "<your-public-access-token>",
},
agentId: "<your-agent-id>",
});

chat.sendMessage("Hello, I need help with my order.");

Each client supports one active chat conversation at a time.

Sending and receiving messagesโ€‹

Send messages with chat.sendMessage(). Agent responses arrive as streaming events:

chat
.on("messageDelta", ({ messageId, delta }) => {
// Streaming text from the agent, arriving in chunks
process.stdout.write(delta);
})
.on("messageDone", ({ messageId, content }) => {
console.log("\nAgent:", content);
});

chat.sendMessage("What's the status of order ORD-12345?");

messageDelta events deliver text incrementally as the agent generates it. messageDone fires once with the complete message when the agent finishes. Both events include a messageId so you can associate deltas with their final message.

Resuming a chatโ€‹

Pass a conversationId to reconnect to a previous chat session. You'll receive the conversation ID in the started event:

// First session โ€” save the conversation ID
chat.on("started", ({ conversationId }) => {
localStorage.setItem("chatId", conversationId);
});

// Later โ€” resume the conversation
const chat = await client.startChatConversation({
auth: { strategy: "publicToken", token: "<your-token>" },
agentId: "<your-agent-id>",
conversationId: localStorage.getItem("chatId"),
});

Eventsโ€‹

EventPayloadDescription
stateChanged{ state }Connection state changed (connecting, connected, disconnected, error)
error{ error, code }An error occurred
started{ clientId, conversationId? }Chat session created
messageDelta{ messageId, delta }Streaming text chunk from the agent
messageDone{ messageId, content }Complete message from the agent
handover{}Agent initiated handover to a human
agentJoined{}A human agent joined the chat
queued{}Conversation placed in a queue
supervisorRequest{ question }Agent asked a human supervisor a question
supervisorResolved{}Supervisor question resolved
ended{}Conversation ended by the server

Human handover eventsโ€‹

The handover, agentJoined, and queued events support human-in-the-loop workflows. When the agent determines a human should take over, it emits handover. If the conversation is placed in a queue while waiting, you'll receive queued. Once a human agent picks up, agentJoined fires.

chat
.on("handover", () => {
showStatus("Connecting you to a human agent...");
})
.on("queued", () => {
showStatus("You're in the queue. We'll be with you shortly.");
})
.on("agentJoined", () => {
showStatus("A human agent has joined the conversation.");
});

Supervisor eventsโ€‹

The supervisorRequest and supervisorResolved events handle scenarios where the AI agent consults a human supervisor mid-conversation without fully handing over. The agent pauses to ask a question, and resumes after receiving an answer.

chat
.on("supervisorRequest", ({ question }) => {
showStatus("The agent is consulting a supervisor...");
})
.on("supervisorResolved", () => {
showStatus("The agent is back.");
});

Server-ended conversationsโ€‹

The ended event fires when the server terminates the conversation (for example, due to inactivity or an agent-initiated close). Clean up your UI when you receive this event.

chat.on("ended", () => {
showStatus("This conversation has ended.");
disableChatInput();
});

Methodsโ€‹

sendMessageโ€‹

Send a text message to the agent:

chat.sendMessage("What's the status of order ORD-12345?");

endโ€‹

End the chat session and close the connection:

await chat.end();

stateโ€‹

The current connection state: connecting, connected, disconnected, or error.

on, off, and onceโ€‹

  • on(event, handler) โ€” subscribe to an event. Returns the instance for chaining.
  • off(event, handler) โ€” unsubscribe a handler.
  • once(event, handler) โ€” subscribe for a single occurrence, then auto-unsubscribe.

Next stepsโ€‹