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.
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โ
| Event | Payload | Description |
|---|---|---|
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โ
- Voice conversations โ real-time audio conversations with agents
- TypeScript SDK โ installation, authentication, and shared configuration