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 { ConversationOptions, ConversationStats } from '@chaoslabs/ai-sdk';

ConversationOptions

Passed to the Conversation constructor to configure the session.

conversation-options.ts
export interface ConversationOptions {
  /** Model to use (defaults to WALLET_MODEL) */
  model?: string;
  /** Maximum number of messages to keep in history */
  maxHistoryLength?: number;
  /** User identifier */
  userId: string;
  /** Array of wallet addresses across multiple chains */
  wallets?: Array<{ address: string; chain: string }>;
  /** Optional initial session ID (auto-generated if not provided) */
  sessionId?: string;
  /** Optional wallet context override for deterministic testing */
  walletContextOverride?: WalletContextOverride;
}
PropertyTypeRequiredDefaultDescription
userIdstringYes-Unique user identifier
modelstringNoWALLET_MODELModel to use for requests
maxHistoryLengthnumberNo50Maximum messages retained in history
walletsArray<{ address, chain }>No-Wallet addresses for DeFi operations
sessionIdstringNoAuto-generatedInitial session identifier
walletContextOverrideWalletContextOverrideNo-Override wallet context for deterministic testing

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 JSON and restored later, enabling persistence across sessions.

toJSON()

to-json.ts
toJSON(): {
  sessionId: string;
  history: InputItem[];
  metadata: RequestMetadata;
  stats: ConversationStats;
};
 
// Usage
const data = conversation.toJSON();
const json = JSON.stringify(data);
// Store in database, file, localStorage, etc.

fromJSON()

from-json.ts
static fromJSON(
  client: Chaos,
  data: {
    sessionId: string;
    history: InputItem[];
    metadata: RequestMetadata;
  }
): Conversation;
 
// Usage
const stored = 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 } 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 = JSON.stringify(conversation.toJSON());
 
// Restore later
const restored = Conversation.fromJSON(chaos, JSON.parse(snapshot));
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?