Conversations

Updated

The Conversation class manages multi-turn dialog with automatic history tracking, session management, and serialization. It wraps the low-level chaos.chat.responses.create() call and maintains an ordered list of InputItem messages.

import.ts
import { Chaos, Conversation } from '@chaoslabs/ai-sdk';
import type {
  AskConversationOptions,
  ConversationOptions,
  ConversationStats,
  SerializedConversation,
  WalletConversationOptions,
} from '@chaoslabs/ai-sdk';

ConversationOptions

Passed to the Conversation constructor to configure the session.

conversation-options.ts
export type ConversationOptions =
  | WalletConversationOptions
  | AskConversationOptions;
 
export interface WalletConversationOptions {
  model?: typeof WALLET_MODEL;
  maxHistoryLength?: number;
  userId: string;
  wallets?: WalletInfo[];
  sessionId?: string;
  walletContextOverride?: WalletContextOverride;
}
 
export interface AskConversationOptions {
  model: typeof ASK_MODEL;
  maxHistoryLength?: number;
  userId: string;
  sessionId?: string;
  wallets?: never;
  walletContextOverride?: never;
}
PropertyTypeRequiredDefaultDescription
userIdstringYes-Unique user identifier
modeltypeof WALLET_MODEL | typeof ASK_MODELNo*Wallet conversations default to WALLET_MODEL; ask conversations must set ASK_MODEL explicitly
maxHistoryLengthnumberNo50Maximum messages retained in history
walletsWalletInfo[]No-Wallet addresses for WALLET_MODEL conversations only
sessionIdstringNoAuto-generatedInitial session identifier
walletContextOverrideWalletContextOverrideNo-Deterministic wallet state for WALLET_MODEL conversations only

ASK_MODEL conversations cannot include wallets or walletContextOverride.

ConversationStats

Statistics about the conversation, accessible via the stats getter.

conversation-stats.ts
export interface ConversationStats {
  /** Number of user turns */
  userTurns: number;
  /** Number of assistant turns */
  assistantTurns: number;
  /** Total messages in history */
  totalMessages: number;
  /** Session ID */
  sessionId: string;
  /** When the conversation started */
  startedAt: Date;
  /** When the last message was sent */
  lastMessageAt: Date | null;
}

Constructor

Creates a new conversation bound to a Chaos client instance.

constructor.ts
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
const conversation = new Conversation(chaos, {
  userId: 'user-123',
  wallets: [
    { address: '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD21', chain: 'ethereum' },
    { address: '0x8ba1f109551bD432803012645Hac136c22C501a', chain: 'base' },
  ],
  maxHistoryLength: 100,
});

Methods

send(message)

Send a message and get a response. History is managed automatically: the user message is appended before the request, and the assistant reply is appended after a successful response.

send.ts
async send(message: string): Promise<ChatCreateResponse>;
 
// Usage
const response1 = await conversation.send("What's my portfolio value?");
const response2 = await conversation.send('Which asset has the highest allocation?');
// response2 has full context from response1

fork()

Create a branch of the conversation. The forked conversation has the same history but a new session ID, allowing you to explore alternate dialog paths without affecting the original.

fork.ts
fork(): Conversation;
 
// Usage
const forked = conversation.fork();
const altResponse = await forked.send('What if I deposit into Aave instead?');
// Original conversation is unchanged

reset()

Reset the conversation to start fresh. Clears history, resets counters, and generates a new session ID.

reset.ts
reset(): void;
 
// Usage
conversation.reset();
// History is empty, new session ID generated

clearHistory()

Clear the history and counters but keep the same session ID.

clear-history.ts
clearHistory(): void;
 
// Usage
conversation.clearHistory();
// Same session ID, empty history

addUserMessage / addAssistantMessage / addSystemMessage

Manually inject messages into the history without sending a request. Useful for restoring conversation state or injecting system context.

manual-messages.ts
addUserMessage(content: string): void;
addAssistantMessage(content: string): void;
addSystemMessage(content: string): void;
 
// Usage: pre-seed a conversation
conversation.addSystemMessage('You are a DeFi portfolio assistant.');
conversation.addUserMessage('What is Aave?');
conversation.addAssistantMessage('Aave is a decentralized lending protocol...');
 
// Next send() will include all three messages as context
const response = await conversation.send('How do I deposit into it?');

Accessors

AccessorTypeDescription
sessionIdstringCurrent session ID
messagesreadonly InputItem[]Copy of the conversation history
statsConversationStatsCurrent conversation statistics

Serialization

Conversations can be serialized to the SerializedConversation shape and restored later. Serialized snapshots must include a supported model.

toJSON()

to-json.ts
toJSON(): SerializedConversation;
 
// Usage
const snapshot: SerializedConversation = conversation.toJSON();
const json = JSON.stringify(snapshot);
// Store in database, file, localStorage, etc.

fromJSON()

Conversation.fromJSON() requires a serialized snapshot with an explicit supported model.

from-json.ts
static fromJSON(client: Chaos, data: SerializedConversation): Conversation;
 
// Usage
const stored: SerializedConversation = JSON.parse(savedJson);
const restored = Conversation.fromJSON(chaos, stored);
const response = await restored.send('Continue where we left off');

Full Example

full-example.ts
import {
  Chaos,
  Conversation,
  extractText,
  hasRisks,
  type SerializedConversation,
} from '@chaoslabs/ai-sdk';
 
const chaos = new Chaos({ apiKey: process.env.CHAOS_API_KEY! });
 
const conversation = new Conversation(chaos, {
  userId: 'user-123',
  wallets: [{ address: '0x742d35Cc...', chain: 'ethereum' }],
});
 
// Turn 1: Ask about portfolio
const r1 = await conversation.send("What's my portfolio value?");
console.log(extractText(r1));
 
// Turn 2: Follow-up with context
const r2 = await conversation.send('Which asset has the highest allocation?');
console.log(extractText(r2));
 
// Turn 3: Action with risk check
const r3 = await conversation.send('Swap 50% of my ETH to USDC');
if (hasRisks(r3)) {
  console.log('Review risks before signing');
}
 
// Check stats
console.log(conversation.stats);
// { userTurns: 3, assistantTurns: 3, totalMessages: 6, ... }
 
// Persist for later
const snapshot: SerializedConversation = conversation.toJSON();
const json = JSON.stringify(snapshot);
 
// Restore later
const stored: SerializedConversation = JSON.parse(json);
const restored = Conversation.fromJSON(chaos, stored);
const r4 = await restored.send('Actually, make it 25% instead');
[@portabletext/react] Unknown block type "callout", specify a component for it in the `components.types` prop
Was this helpful?