Chat SDK
Overview
Build applications with multiple specialized agents working together. Each agent can have its own purpose, UI, and event handlers - all running simultaneously without interference.
Why Multiple Agents?
Instead of one general-purpose agent, use specialized agents for different tasks:
- Code Agent - Writes and reviews code
- Design Agent - Creates UI designs and components
- Documentation Agent - Writes technical docs
- Testing Agent - Generates and runs tests
- DevOps Agent - Handles deployments and infrastructure
Each agent focuses on what it does best, creating a powerful development environment.
Basic Multi-Instance Setup
Unique Agent IDs
Always provide unique agentId to each ChatProvider:
function MultiAgentApp() {
return (
<div className="agent-workspace">
{/* Code Writing Agent */}
<ChatProvider agentId="code-agent" authConfig={codeAgentAuth}>
<CodePanel />
</ChatProvider>
{/* Design Agent */}
<ChatProvider agentId="design-agent" authConfig={designAgentAuth}>
<DesignPanel />
</ChatProvider>
{/* Testing Agent */}
<ChatProvider agentId="test-agent" authConfig={testAgentAuth}>
<TestPanel />
</ChatProvider>
</div>
);
}Event Isolation
Each agent's events are automatically isolated:
function CodePanel() {
// Only receives events from code-agent
useForwarding('write_code', (code) => {
updateCodeEditor(code);
});
useStatusSubscription('tool_call', (status) => {
updateCodeToolStatus(status);
});
return <CodeEditor />;
}
function DesignPanel() {
// Only receives events from design-agent
useForwarding('generate_design', (design) => {
updateDesignCanvas(design);
});
useStatusSubscription('tool_call', (status) => {
updateDesignToolStatus(status);
});
return <DesignCanvas />;
}Real-World Applications
Full-Stack Development IDE
Build entire applications with specialized agents:
function DevIDE() {
const [codeAuth, setCodeAuth] = useState(null);
const [designAuth, setDesignAuth] = useState(null);
const [testAuth, setTestAuth] = useState(null);
useEffect(() => {
// Create sessions for each agent
Promise.all([
createSession({ agentId: 'code-writer' }),
createSession({ agentId: 'ui-designer' }),
createSession({ agentId: 'test-generator' })
]).then(([code, design, test]) => {
setCodeAuth(code);
setDesignAuth(design);
setTestAuth(test);
});
}, []);
if (!codeAuth || !designAuth || !testAuth) {
return <Loading />;
}
return (
<div className="grid grid-cols-3 h-screen">
{/* Backend Code Agent */}
<ChatProvider agentId="backend" authConfig={codeAuth}>
<BackendPanel />
</ChatProvider>
{/* Frontend Design Agent */}
<ChatProvider agentId="frontend" authConfig={designAuth}>
<FrontendPanel />
</ChatProvider>
{/* Testing Agent */}
<ChatProvider agentId="testing" authConfig={testAuth}>
<TestingPanel />
</ChatProvider>
</div>
);
}Content Creation Platform
Multiple agents for different content types:
function ContentPlatform() {
return (
<div className="content-workspace">
{/* Article Writer */}
<ChatProvider agentId="writer" authConfig={writerAuth}>
<ArticleEditor />
</ChatProvider>
{/* SEO Optimizer */}
<ChatProvider agentId="seo" authConfig={seoAuth}>
<SEOPanel />
</ChatProvider>
{/* Image Generator */}
<ChatProvider agentId="images" authConfig={imageAuth}>
<ImageGallery />
</ChatProvider>
{/* Social Media */}
<ChatProvider agentId="social" authConfig={socialAuth}>
<SocialPosts />
</ChatProvider>
</div>
);
}Data Analysis Dashboard
Agents for different analysis tasks:
function AnalyticsDashboard() {
return (
<div className="dashboard">
{/* Data Query Agent */}
<ChatProvider agentId="query" authConfig={queryAuth}>
<QueryBuilder />
</ChatProvider>
{/* Visualization Agent */}
<ChatProvider agentId="viz" authConfig={vizAuth}>
<ChartGenerator />
</ChatProvider>
{/* Insights Agent */}
<ChatProvider agentId="insights" authConfig={insightsAuth}>
<InsightsPanel />
</ChatProvider>
{/* Report Agent */}
<ChatProvider agentId="reports" authConfig={reportAuth}>
<ReportGenerator />
</ChatProvider>
</div>
);
}Agent Communication
Agents can work together through your application state:
function CollaborativeAgents() {
const [sharedState, setSharedState] = useState({
code: '',
design: '',
tests: ''
});
return (
<>
{/* Code Agent writes code */}
<ChatProvider agentId="coder" authConfig={coderAuth}>
<CodeAgent
onCodeChange={(code) => setSharedState(s => ({ ...s, code }))}
/>
</ChatProvider>
{/* Design Agent uses the code to generate UI */}
<ChatProvider agentId="designer" authConfig={designAuth}>
<DesignAgent
codeContext={sharedState.code}
onDesignChange={(design) => setSharedState(s => ({ ...s, design }))}
/>
</ChatProvider>
{/* Test Agent generates tests for the code */}
<ChatProvider agentId="tester" authConfig={testAuth}>
<TestAgent
codeContext={sharedState.code}
onTestsChange={(tests) => setSharedState(s => ({ ...s, tests }))}
/>
</ChatProvider>
</>
);
}Dynamic Agent Loading
Load agents on demand:
function DynamicAgentWorkspace() {
const [activeAgents, setActiveAgents] = useState(new Map());
const addAgent = async (type) => {
const session = await createSession({ agentId: type });
setActiveAgents(prev => new Map(prev).set(type, {
auth: session,
instanceId: `agent-${type}-${Date.now()}`
}));
};
const removeAgent = (type) => {
setActiveAgents(prev => {
const next = new Map(prev);
next.delete(type);
return next;
});
};
return (
<div>
<div className="agent-controls">
<button onClick={() => addAgent('code')}>Add Code Agent</button>
<button onClick={() => addAgent('design')}>Add Design Agent</button>
<button onClick={() => addAgent('docs')}>Add Docs Agent</button>
</div>
<div className="agent-panels">
{Array.from(activeAgents.entries()).map(([type, agent]) => (
<ChatProvider
key={agent.instanceId}
agentId={agent.instanceId}
authConfig={agent.auth}
>
<AgentPanel
type={type}
onClose={() => removeAgent(type)}
/>
</ChatProvider>
))}
</div>
</div>
);
}Per-Agent Configuration
Different settings for each agent:
function CustomizedAgents() {
return (
<>
{/* Fast, minimal agent */}
<ChatProvider
agentId="quick-helper"
authConfig={quickAuth}
typingAnimation={{ mode: 'instant' }}
enableHistory={false}
>
<QuickHelp />
</ChatProvider>
{/* Detailed, animated agent */}
<ChatProvider
agentId="detailed-writer"
authConfig={writerAuth}
typingAnimation={{ mode: 'char', speed: 50 }}
enableHistory={true}
>
<DetailedWriter />
</ChatProvider>
{/* Code agent with custom components */}
<ChatProvider
agentId="code-agent"
authConfig={codeAuth}
statusComponents={{
tool_call: CodeToolStatus,
edit_file: FileEditStatus
}}
>
<CodeWorkspace />
</ChatProvider>
</>
);
}Layout Patterns
Side-by-Side
<div className="flex gap-4">
<ChatProvider agentId="agent-1" authConfig={auth1}>
<div className="w-1/2"><ChatPanel /></div>
</ChatProvider>
<ChatProvider agentId="agent-2" authConfig={auth2}>
<div className="w-1/2"><ChatPanel /></div>
</ChatProvider>
</div>Tabbed Interface
function TabbedAgents() {
const [activeTab, setActiveTab] = useState('code');
return (
<div>
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList>
<TabsTrigger value="code">Code Agent</TabsTrigger>
<TabsTrigger value="design">Design Agent</TabsTrigger>
<TabsTrigger value="test">Test Agent</TabsTrigger>
</TabsList>
<TabsContent value="code">
<ChatProvider agentId="code" authConfig={codeAuth}>
<ChatPanel />
</ChatProvider>
</TabsContent>
<TabsContent value="design">
<ChatProvider agentId="design" authConfig={designAuth}>
<ChatPanel />
</ChatProvider>
</TabsContent>
<TabsContent value="test">
<ChatProvider agentId="test" authConfig={testAuth}>
<ChatPanel />
</ChatProvider>
</TabsContent>
</Tabs>
</div>
);
}Modal/Overlay
function ModalAgent() {
const [showAgent, setShowAgent] = useState(false);
return (
<>
<button onClick={() => setShowAgent(true)}>
Ask Code Agent
</button>
{showAgent && (
<Modal onClose={() => setShowAgent(false)}>
<ChatProvider agentId="modal-agent" authConfig={agentAuth}>
<ChatPanel />
</ChatProvider>
</Modal>
)}
</>
);
}Grid Layout
<div className="grid grid-cols-2 grid-rows-2 gap-4 h-screen">
<ChatProvider agentId="agent-1" authConfig={auth1}>
<ChatPanel />
</ChatProvider>
<ChatProvider agentId="agent-2" authConfig={auth2}>
<ChatPanel />
</ChatProvider>
<ChatProvider agentId="agent-3" authConfig={auth3}>
<ChatPanel />
</ChatProvider>
<ChatProvider agentId="agent-4" authConfig={auth4}>
<ChatPanel />
</ChatProvider>
</div>Performance Considerations
Lazy Loading
function LazyAgents() {
return (
<Suspense fallback={<Loading />}>
<LazyCodeAgent />
<LazyDesignAgent />
<LazyTestAgent />
</Suspense>
);
}
const LazyCodeAgent = lazy(() => import('./agents/CodeAgent'));
const LazyDesignAgent = lazy(() => import('./agents/DesignAgent'));
const LazyTestAgent = lazy(() => import('./agents/TestAgent'));Memory Management
function ManagedAgents() {
const [agents, setAgents] = useState(new Map());
// Clean up inactive agents
useEffect(() => {
const interval = setInterval(() => {
const now = Date.now();
setAgents(prev => {
const active = new Map();
prev.forEach((agent, id) => {
if (now - agent.lastActivity < 300000) { // 5 min
active.set(id, agent);
}
});
return active;
});
}, 60000); // Check every minute
return () => clearInterval(interval);
}, []);
return <div>{/* Render active agents */}</div>;
}Error Handling
Handle errors per agent:
<ChatProvider
agentId="code-agent"
authConfig={codeAuth}
onError={(error) => {
console.error('Code agent error:', error);
notifyUser('Code agent encountered an issue');
}}
>
<CodePanel />
</ChatProvider>
<ChatProvider
agentId="design-agent"
authConfig={designAuth}
onError={(error) => {
console.error('Design agent error:', error);
notifyUser('Design agent encountered an issue');
}}
>
<DesignPanel />
</ChatProvider>Best Practices
Agent Naming
// ✅ Descriptive, unique IDs
agentId="code-writer-typescript"
agentId="ui-designer-react"
agentId="api-tester-backend"
// ❌ Generic IDs
agentId="agent1"
agentId="agent2"State Management
// ✅ Centralized state for agent communication
const [appState, setAppState] = useState({
code: '',
design: '',
tests: ''
});
// Pass to agents as needed
<CodeAgent state={appState} onUpdate={setAppState} />Resource Limits
// ✅ Limit concurrent agents
const MAX_AGENTS = 5;
function addAgent(type) {
if (activeAgents.size >= MAX_AGENTS) {
alert('Maximum agents reached');
return;
}
// Add agent...
}TypeScript Support
interface AgentConfig {
id: string;
type: 'code' | 'design' | 'test';
auth: AuthConfig;
}
const agents: AgentConfig[] = [
{ id: 'coder', type: 'code', auth: codeAuth },
{ id: 'designer', type: 'design', auth: designAuth },
{ id: 'tester', type: 'test', auth: testAuth }
];Next Steps
- Forwarding - Control agent output
- Status Events - Monitor agents
- Customization - Style each agent differently