@octavus/docs 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/content/01-getting-started/02-quickstart.md +4 -3
  2. package/content/02-server-sdk/01-overview.md +11 -5
  3. package/content/02-server-sdk/02-sessions.md +6 -3
  4. package/content/02-server-sdk/03-tools.md +4 -2
  5. package/content/02-server-sdk/04-streaming.md +12 -4
  6. package/content/03-client-sdk/01-overview.md +11 -5
  7. package/content/03-client-sdk/05-socket-transport.md +263 -153
  8. package/content/03-client-sdk/06-http-transport.md +280 -0
  9. package/content/04-protocol/03-triggers.md +10 -2
  10. package/content/05-api-reference/01-overview.md +3 -17
  11. package/content/06-examples/01-overview.md +27 -0
  12. package/content/06-examples/02-nextjs-chat.md +343 -0
  13. package/content/06-examples/03-socket-chat.md +392 -0
  14. package/content/06-examples/_meta.md +5 -0
  15. package/dist/chunk-5M7DS4DF.js +519 -0
  16. package/dist/chunk-5M7DS4DF.js.map +1 -0
  17. package/dist/chunk-H6JGSSAJ.js +519 -0
  18. package/dist/chunk-H6JGSSAJ.js.map +1 -0
  19. package/dist/chunk-JZRABTHU.js +519 -0
  20. package/dist/chunk-JZRABTHU.js.map +1 -0
  21. package/dist/chunk-OL5QDJ42.js +483 -0
  22. package/dist/chunk-OL5QDJ42.js.map +1 -0
  23. package/dist/chunk-PMOVVTHO.js +519 -0
  24. package/dist/chunk-PMOVVTHO.js.map +1 -0
  25. package/dist/chunk-R5MTVABN.js +439 -0
  26. package/dist/chunk-R5MTVABN.js.map +1 -0
  27. package/dist/chunk-RJ4H4YVA.js +519 -0
  28. package/dist/chunk-RJ4H4YVA.js.map +1 -0
  29. package/dist/chunk-S5U4IWCR.js +439 -0
  30. package/dist/chunk-S5U4IWCR.js.map +1 -0
  31. package/dist/chunk-UCJE36LL.js +519 -0
  32. package/dist/chunk-UCJE36LL.js.map +1 -0
  33. package/dist/chunk-WW7TRC7S.js +519 -0
  34. package/dist/chunk-WW7TRC7S.js.map +1 -0
  35. package/dist/content.js +1 -1
  36. package/dist/docs.json +46 -10
  37. package/dist/index.js +1 -1
  38. package/dist/search-index.json +1 -1
  39. package/dist/search.js +1 -1
  40. package/dist/search.js.map +1 -1
  41. package/dist/sections.json +54 -10
  42. package/package.json +1 -1
@@ -0,0 +1,280 @@
1
+ ---
2
+ title: HTTP Transport
3
+ description: Using HTTP/SSE for streaming with Octavus in Next.js, Express, and other frameworks.
4
+ ---
5
+
6
+ # HTTP Transport
7
+
8
+ The HTTP transport uses standard HTTP requests with Server-Sent Events (SSE) for streaming. This is the simplest and most compatible transport option.
9
+
10
+ ## When to Use HTTP Transport
11
+
12
+ | Use Case | Recommendation |
13
+ |----------|----------------|
14
+ | Next.js, Remix, or similar frameworks | ✅ Use HTTP |
15
+ | Standard web apps without special requirements | ✅ Use HTTP |
16
+ | Serverless deployments (Vercel, etc.) | ✅ Use HTTP |
17
+ | Need custom real-time events | Consider [Socket Transport](/docs/client-sdk/socket-transport) |
18
+
19
+ ## Basic Setup
20
+
21
+ ### Client
22
+
23
+ ```tsx
24
+ import { useMemo } from 'react';
25
+ import { useOctavusChat, createHttpTransport } from '@octavus/react';
26
+
27
+ function Chat({ sessionId }: { sessionId: string }) {
28
+ const transport = useMemo(
29
+ () =>
30
+ createHttpTransport({
31
+ triggerRequest: (triggerName, input) =>
32
+ fetch('/api/trigger', {
33
+ method: 'POST',
34
+ headers: { 'Content-Type': 'application/json' },
35
+ body: JSON.stringify({ sessionId, triggerName, input }),
36
+ }),
37
+ }),
38
+ [sessionId],
39
+ );
40
+
41
+ const { messages, status, error, send, stop } = useOctavusChat({ transport });
42
+
43
+ const sendMessage = async (text: string) => {
44
+ await send(
45
+ 'user-message',
46
+ { USER_MESSAGE: text },
47
+ { userMessage: { content: text } },
48
+ );
49
+ };
50
+
51
+ // ... render chat
52
+ }
53
+ ```
54
+
55
+ ### Server (Next.js API Route)
56
+
57
+ ```typescript
58
+ // app/api/trigger/route.ts
59
+ import { OctavusClient, toSSEStream } from '@octavus/server-sdk';
60
+
61
+ const client = new OctavusClient({
62
+ baseUrl: process.env.OCTAVUS_API_URL!,
63
+ apiKey: process.env.OCTAVUS_API_KEY!,
64
+ });
65
+
66
+ export async function POST(request: Request) {
67
+ const { sessionId, triggerName, input } = await request.json();
68
+
69
+ const session = client.agentSessions.attach(sessionId, {
70
+ tools: {
71
+ 'get-user-account': async (args) => {
72
+ return { name: 'Demo User', plan: 'pro' };
73
+ },
74
+ },
75
+ });
76
+
77
+ // trigger() returns parsed events, toSSEStream() converts to SSE format
78
+ const events = session.trigger(triggerName, input);
79
+
80
+ return new Response(toSSEStream(events), {
81
+ headers: {
82
+ 'Content-Type': 'text/event-stream',
83
+ 'Cache-Control': 'no-cache',
84
+ Connection: 'keep-alive',
85
+ },
86
+ });
87
+ }
88
+ ```
89
+
90
+ ## Session Creation
91
+
92
+ Sessions should be created server-side before rendering the chat. There are two patterns:
93
+
94
+ ### Pattern 1: Create Session on Page Load
95
+
96
+ ```tsx
97
+ // app/chat/page.tsx
98
+ 'use client';
99
+
100
+ import { useEffect, useState } from 'react';
101
+ import { Chat } from '@/components/Chat';
102
+
103
+ export default function ChatPage() {
104
+ const [sessionId, setSessionId] = useState<string | null>(null);
105
+
106
+ useEffect(() => {
107
+ fetch('/api/sessions', {
108
+ method: 'POST',
109
+ headers: { 'Content-Type': 'application/json' },
110
+ body: JSON.stringify({
111
+ agentId: 'your-agent-id',
112
+ input: { COMPANY_NAME: 'Acme Corp' },
113
+ }),
114
+ })
115
+ .then(res => res.json())
116
+ .then(data => setSessionId(data.sessionId));
117
+ }, []);
118
+
119
+ if (!sessionId) {
120
+ return <LoadingSpinner />;
121
+ }
122
+
123
+ return <Chat sessionId={sessionId} />;
124
+ }
125
+ ```
126
+
127
+ ### Pattern 2: Server-Side Session Creation (App Router)
128
+
129
+ ```tsx
130
+ // app/chat/page.tsx
131
+ import { octavus } from '@/lib/octavus';
132
+ import { Chat } from '@/components/Chat';
133
+
134
+ export default async function ChatPage() {
135
+ // Create session server-side
136
+ const sessionId = await octavus.agentSessions.create('your-agent-id', {
137
+ COMPANY_NAME: 'Acme Corp',
138
+ });
139
+
140
+ return <Chat sessionId={sessionId} />;
141
+ }
142
+ ```
143
+
144
+ This pattern is cleaner as the session is ready before the component renders.
145
+
146
+ ## Error Handling
147
+
148
+ Handle errors in both the transport and the hook:
149
+
150
+ ```tsx
151
+ const { messages, status, error, send } = useOctavusChat({
152
+ transport,
153
+ onError: (err) => {
154
+ console.error('Stream error:', err);
155
+ // Show toast, update UI, etc.
156
+ },
157
+ });
158
+
159
+ // Also check error state
160
+ if (error) {
161
+ return <ErrorMessage error={error} />;
162
+ }
163
+ ```
164
+
165
+ ## Stop Streaming
166
+
167
+ Allow users to cancel ongoing streams:
168
+
169
+ ```tsx
170
+ const { send, stop, status } = useOctavusChat({ transport });
171
+
172
+ return (
173
+ <button
174
+ onClick={status === 'streaming' ? stop : () => sendMessage()}
175
+ disabled={status === 'streaming' && !inputValue}
176
+ >
177
+ {status === 'streaming' ? 'Stop' : 'Send'}
178
+ </button>
179
+ );
180
+ ```
181
+
182
+ ## Express Server
183
+
184
+ For non-Next.js backends:
185
+
186
+ ```typescript
187
+ import express from 'express';
188
+ import { OctavusClient, toSSEStream } from '@octavus/server-sdk';
189
+
190
+ const app = express();
191
+ const client = new OctavusClient({
192
+ baseUrl: process.env.OCTAVUS_API_URL!,
193
+ apiKey: process.env.OCTAVUS_API_KEY!,
194
+ });
195
+
196
+ app.post('/api/trigger', async (req, res) => {
197
+ const { sessionId, triggerName, input } = req.body;
198
+
199
+ const session = client.agentSessions.attach(sessionId, {
200
+ tools: {
201
+ // Your tool handlers
202
+ },
203
+ });
204
+
205
+ const events = session.trigger(triggerName, input);
206
+ const stream = toSSEStream(events);
207
+
208
+ // Set SSE headers
209
+ res.setHeader('Content-Type', 'text/event-stream');
210
+ res.setHeader('Cache-Control', 'no-cache');
211
+ res.setHeader('Connection', 'keep-alive');
212
+
213
+ // Pipe the stream to the response
214
+ const reader = stream.getReader();
215
+
216
+ try {
217
+ while (true) {
218
+ const { done, value } = await reader.read();
219
+ if (done) break;
220
+ res.write(value);
221
+ }
222
+ } finally {
223
+ reader.releaseLock();
224
+ res.end();
225
+ }
226
+ });
227
+ ```
228
+
229
+ ## Transport Options
230
+
231
+ ```typescript
232
+ interface HttpTransportOptions {
233
+ // Function that makes the HTTP request
234
+ triggerRequest: (
235
+ triggerName: string,
236
+ input?: Record<string, unknown>
237
+ ) => Promise<Response>;
238
+ }
239
+ ```
240
+
241
+ ## Protocol
242
+
243
+ ### Request Format
244
+
245
+ The `triggerRequest` function should send a POST request with:
246
+
247
+ ```json
248
+ {
249
+ "sessionId": "sess_abc123",
250
+ "triggerName": "user-message",
251
+ "input": {
252
+ "USER_MESSAGE": "Hello"
253
+ }
254
+ }
255
+ ```
256
+
257
+ ### Response Format
258
+
259
+ The server responds with an SSE stream:
260
+
261
+ ```
262
+ data: {"type":"start","messageId":"msg_xyz"}
263
+
264
+ data: {"type":"text-delta","id":"msg_xyz","delta":"Hello"}
265
+
266
+ data: {"type":"text-delta","id":"msg_xyz","delta":" there!"}
267
+
268
+ data: {"type":"finish","finishReason":"stop"}
269
+
270
+ data: [DONE]
271
+ ```
272
+
273
+ See [Streaming Events](/docs/server-sdk/streaming#event-types) for the full list of event types.
274
+
275
+ ## Next Steps
276
+
277
+ - [Quick Start](/docs/getting-started/quickstart) — Complete Next.js integration guide
278
+ - [Messages](/docs/client-sdk/messages) — Working with message state
279
+ - [Streaming](/docs/client-sdk/streaming) — Building streaming UIs
280
+
@@ -117,11 +117,19 @@ function Chat({ sessionId }: { sessionId: string }) {
117
117
  ### From Server SDK
118
118
 
119
119
  ```typescript
120
- const { stream } = session.trigger('user-message', {
120
+ // trigger() returns an async generator of events
121
+ const events = session.trigger('user-message', {
121
122
  USER_MESSAGE: 'Help me with billing',
122
123
  });
123
124
 
124
- const { stream } = session.trigger('request-human');
125
+ // Iterate events directly
126
+ for await (const event of events) {
127
+ console.log(event);
128
+ }
129
+
130
+ // Or convert to SSE for HTTP responses
131
+ import { toSSEStream } from '@octavus/server-sdk';
132
+ return new Response(toSSEStream(events), { headers: { 'Content-Type': 'text/event-stream' } });
125
133
  ```
126
134
 
127
135
  ## Handlers
@@ -22,7 +22,7 @@ curl -H "Authorization: Bearer YOUR_API_KEY" \
22
22
  https://octavus.ai/api/agents
23
23
  ```
24
24
 
25
- API keys can be created in the Octavus Platform under Project Settings API Keys.
25
+ API keys can be created in the Octavus Platform under your project's **API Keys** page.
26
26
 
27
27
  ## Response Format
28
28
 
@@ -57,23 +57,8 @@ All responses are JSON. Success responses return the data directly (not wrapped
57
57
  | 401 | Unauthorized - Missing or invalid API key |
58
58
  | 403 | Forbidden - Insufficient permissions |
59
59
  | 404 | Not Found |
60
- | 429 | Too Many Requests - Rate limited |
61
60
  | 500 | Internal Server Error |
62
61
 
63
- ## Rate Limits
64
-
65
- - **Standard tier**: 100 requests/minute
66
- - **Pro tier**: 1,000 requests/minute
67
- - **Enterprise**: Custom limits
68
-
69
- Rate limit headers are included in responses:
70
-
71
- ```
72
- X-RateLimit-Limit: 100
73
- X-RateLimit-Remaining: 95
74
- X-RateLimit-Reset: 1735312800
75
- ```
76
-
77
62
  ## Endpoints Overview
78
63
 
79
64
  ### Agents
@@ -131,7 +116,8 @@ data: [DONE]
131
116
  We recommend using our SDKs instead of calling the API directly:
132
117
 
133
118
  - **Server SDK**: `@octavus/server-sdk` - For Node.js backends
134
- - **Client SDK**: `@octavus/client-sdk` - For React frontends
119
+ - **React SDK**: `@octavus/react` - For React applications
120
+ - **Client SDK**: `@octavus/client-sdk` - For other frontend frameworks
135
121
 
136
122
  The SDKs handle authentication, streaming, and tool execution automatically.
137
123
 
@@ -0,0 +1,27 @@
1
+ ---
2
+ title: Overview
3
+ description: Complete integration examples for different architectures.
4
+ ---
5
+
6
+ # Examples
7
+
8
+ This section provides complete integration examples for different architectures. Each example walks through building a functional chat interface from scratch.
9
+
10
+ ## Available Examples
11
+
12
+ | Example | Transport | Best For |
13
+ |---------|-----------|----------|
14
+ | [Next.js Chat](/docs/examples/nextjs-chat) | HTTP/SSE | Next.js, Remix, standard web apps |
15
+ | [Socket Chat](/docs/examples/socket-chat) | SockJS | Meteor, Phoenix, real-time apps |
16
+
17
+ ## Choosing a Transport
18
+
19
+ **Use HTTP Transport when:**
20
+ - Building with Next.js, Remix, or similar frameworks
21
+ - You want the simplest integration
22
+ - Deploying to serverless (Vercel, Netlify, etc.)
23
+
24
+ **Use Socket Transport when:**
25
+ - Using Meteor, Phoenix, or socket-based frameworks
26
+ - Need custom real-time events (typing indicators, presence)
27
+ - Behind proxies that don't support SSE well
@@ -0,0 +1,343 @@
1
+ ---
2
+ title: Next.js Chat
3
+ description: Building a chat interface with Next.js and HTTP transport.
4
+ ---
5
+
6
+ # Next.js Chat Example
7
+
8
+ This example builds a support chat interface using Next.js App Router with HTTP/SSE transport. This is the recommended pattern for most web applications.
9
+
10
+ ## What You're Building
11
+
12
+ A chat interface that:
13
+ - Creates sessions server-side
14
+ - Streams AI responses in real-time
15
+ - Handles tool calls on your server
16
+ - Shows typing status during streaming
17
+
18
+ ## Architecture
19
+
20
+ ```mermaid
21
+ flowchart LR
22
+ Browser["Browser<br/>(React)"] -->|"POST /api/chat"| NextJS["Next.js API<br/>Routes"]
23
+ NextJS -->|"SSE"| Browser
24
+ NextJS --> Platform["Octavus Platform"]
25
+ ```
26
+
27
+ ## Prerequisites
28
+
29
+ - Next.js 14+ with App Router
30
+ - Octavus account with API key
31
+ - An agent configured in Octavus
32
+
33
+ ## Step 1: Install Dependencies
34
+
35
+ ```bash
36
+ npm install @octavus/server-sdk @octavus/react
37
+ ```
38
+
39
+ ## Step 2: Configure Environment
40
+
41
+ ```bash
42
+ # .env.local
43
+ OCTAVUS_API_URL=https://octavus.ai
44
+ OCTAVUS_API_KEY=your-api-key
45
+ ```
46
+
47
+ ## Step 3: Create the Octavus Client
48
+
49
+ ```typescript
50
+ // lib/octavus.ts
51
+ import { OctavusClient } from '@octavus/server-sdk';
52
+
53
+ export const octavus = new OctavusClient({
54
+ baseUrl: process.env.OCTAVUS_API_URL!,
55
+ apiKey: process.env.OCTAVUS_API_KEY!,
56
+ });
57
+ ```
58
+
59
+ ## Step 4: Create Session Endpoint
60
+
61
+ Sessions hold conversation state. Create one when the user opens the chat:
62
+
63
+ ```typescript
64
+ // app/api/sessions/route.ts
65
+ import { NextResponse } from 'next/server';
66
+ import { octavus } from '@/lib/octavus';
67
+
68
+ export async function POST(request: Request) {
69
+ const { agentId, input } = await request.json();
70
+
71
+ // Create a new session with initial input variables
72
+ const sessionId = await octavus.agentSessions.create(agentId, input);
73
+
74
+ return NextResponse.json({ sessionId });
75
+ }
76
+ ```
77
+
78
+ **Protocol Note:** The `input` object contains variables defined in your agent's protocol. For example, if your agent has `COMPANY_NAME` as an input variable:
79
+
80
+ ```typescript
81
+ const sessionId = await octavus.agentSessions.create(agentId, {
82
+ COMPANY_NAME: 'Acme Corp',
83
+ USER_ID: user.id,
84
+ });
85
+ ```
86
+
87
+ ## Step 5: Create Trigger Endpoint
88
+
89
+ Triggers execute agent actions. The `user-message` trigger is the most common:
90
+
91
+ ```typescript
92
+ // app/api/trigger/route.ts
93
+ import { toSSEStream } from '@octavus/server-sdk';
94
+ import { octavus } from '@/lib/octavus';
95
+
96
+ export async function POST(request: Request) {
97
+ const { sessionId, triggerName, input } = await request.json();
98
+
99
+ // Attach to the session with tool handlers
100
+ const session = octavus.agentSessions.attach(sessionId, {
101
+ tools: {
102
+ // Tool handlers run on YOUR server, not Octavus
103
+ 'get-user-account': async (args) => {
104
+ const userId = args.userId as string;
105
+ // Fetch from your database
106
+ const user = await db.users.findUnique({ where: { id: userId } });
107
+ return {
108
+ name: user.name,
109
+ email: user.email,
110
+ plan: user.plan,
111
+ };
112
+ },
113
+
114
+ 'create-support-ticket': async (args) => {
115
+ const ticket = await db.tickets.create({
116
+ data: {
117
+ summary: args.summary as string,
118
+ priority: args.priority as string,
119
+ },
120
+ });
121
+ return {
122
+ ticketId: ticket.id,
123
+ estimatedResponse: '24 hours',
124
+ };
125
+ },
126
+ },
127
+ });
128
+
129
+ // trigger() returns parsed events, toSSEStream() converts to SSE format
130
+ const events = session.trigger(triggerName, input);
131
+
132
+ return new Response(toSSEStream(events), {
133
+ headers: {
134
+ 'Content-Type': 'text/event-stream',
135
+ 'Cache-Control': 'no-cache',
136
+ Connection: 'keep-alive',
137
+ },
138
+ });
139
+ }
140
+ ```
141
+
142
+ **Protocol Note:** Tool names and arguments are defined in your agent's protocol YAML. The tool handlers here must match those definitions.
143
+
144
+ ## Step 6: Build the Chat Component
145
+
146
+ ```tsx
147
+ // components/Chat.tsx
148
+ 'use client';
149
+
150
+ import { useState, useMemo } from 'react';
151
+ import { useOctavusChat, createHttpTransport } from '@octavus/react';
152
+
153
+ interface ChatProps {
154
+ sessionId: string;
155
+ }
156
+
157
+ export function Chat({ sessionId }: ChatProps) {
158
+ const [inputValue, setInputValue] = useState('');
159
+
160
+ // Create transport - memoized on sessionId
161
+ const transport = useMemo(
162
+ () =>
163
+ createHttpTransport({
164
+ triggerRequest: (triggerName, input) =>
165
+ fetch('/api/trigger', {
166
+ method: 'POST',
167
+ headers: { 'Content-Type': 'application/json' },
168
+ body: JSON.stringify({ sessionId, triggerName, input }),
169
+ }),
170
+ }),
171
+ [sessionId],
172
+ );
173
+
174
+ const { messages, status, send } = useOctavusChat({ transport });
175
+
176
+ const handleSubmit = async (e: React.FormEvent) => {
177
+ e.preventDefault();
178
+ if (!inputValue.trim() || status === 'streaming') return;
179
+
180
+ const message = inputValue.trim();
181
+ setInputValue('');
182
+
183
+ // Send triggers the 'user-message' action
184
+ // The third argument adds the user message to the UI
185
+ await send(
186
+ 'user-message',
187
+ { USER_MESSAGE: message },
188
+ { userMessage: { content: message } },
189
+ );
190
+ };
191
+
192
+ return (
193
+ <div className="flex flex-col h-screen">
194
+ {/* Messages */}
195
+ <div className="flex-1 overflow-y-auto p-4 space-y-4">
196
+ {messages.map((msg) => (
197
+ <div
198
+ key={msg.id}
199
+ className={msg.role === 'user' ? 'text-right' : 'text-left'}
200
+ >
201
+ <div
202
+ className={`inline-block p-3 rounded-lg ${
203
+ msg.role === 'user'
204
+ ? 'bg-blue-500 text-white'
205
+ : 'bg-gray-100'
206
+ }`}
207
+ >
208
+ {msg.parts.map((part, i) => {
209
+ if (part.type === 'text') {
210
+ return <p key={i}>{part.text}</p>;
211
+ }
212
+ if (part.type === 'tool-call') {
213
+ return (
214
+ <div key={i} className="text-sm opacity-70">
215
+ Using {part.toolName}...
216
+ </div>
217
+ );
218
+ }
219
+ return null;
220
+ })}
221
+ </div>
222
+ </div>
223
+ ))}
224
+ </div>
225
+
226
+ {/* Input */}
227
+ <form onSubmit={handleSubmit} className="p-4 border-t">
228
+ <div className="flex gap-2">
229
+ <input
230
+ type="text"
231
+ value={inputValue}
232
+ onChange={(e) => setInputValue(e.target.value)}
233
+ placeholder="Type a message..."
234
+ className="flex-1 px-4 py-2 border rounded-lg"
235
+ disabled={status === 'streaming'}
236
+ />
237
+ <button
238
+ type="submit"
239
+ disabled={status === 'streaming'}
240
+ className="px-4 py-2 bg-blue-500 text-white rounded-lg"
241
+ >
242
+ {status === 'streaming' ? 'Sending...' : 'Send'}
243
+ </button>
244
+ </div>
245
+ </form>
246
+ </div>
247
+ );
248
+ }
249
+ ```
250
+
251
+ ## Step 7: Create the Page
252
+
253
+ ```tsx
254
+ // app/chat/page.tsx
255
+ 'use client';
256
+
257
+ import { useEffect, useState } from 'react';
258
+ import { Chat } from '@/components/Chat';
259
+
260
+ const AGENT_ID = 'your-agent-id'; // From Octavus dashboard
261
+
262
+ export default function ChatPage() {
263
+ const [sessionId, setSessionId] = useState<string | null>(null);
264
+
265
+ useEffect(() => {
266
+ // Create session on mount
267
+ fetch('/api/sessions', {
268
+ method: 'POST',
269
+ headers: { 'Content-Type': 'application/json' },
270
+ body: JSON.stringify({
271
+ agentId: AGENT_ID,
272
+ input: {
273
+ COMPANY_NAME: 'Acme Corp',
274
+ },
275
+ }),
276
+ })
277
+ .then((res) => res.json())
278
+ .then((data) => setSessionId(data.sessionId));
279
+ }, []);
280
+
281
+ if (!sessionId) {
282
+ return <div className="p-8">Loading...</div>;
283
+ }
284
+
285
+ return <Chat sessionId={sessionId} />;
286
+ }
287
+ ```
288
+
289
+ ## Protocol Integration
290
+
291
+ Your agent's protocol defines the triggers and tools. Here's how the code maps to protocol:
292
+
293
+ ### Triggers
294
+
295
+ ```yaml
296
+ # In your agent's protocol.yaml
297
+ triggers:
298
+ user-message:
299
+ description: User sends a chat message
300
+ input:
301
+ USER_MESSAGE:
302
+ type: string
303
+ description: The user's message
304
+ ```
305
+
306
+ The `send()` call maps directly:
307
+
308
+ ```typescript
309
+ await send(
310
+ 'user-message', // trigger name
311
+ { USER_MESSAGE: message }, // trigger inputs
312
+ { userMessage: { content: message } },
313
+ );
314
+ ```
315
+
316
+ ### Tools
317
+
318
+ ```yaml
319
+ # In your agent's protocol.yaml
320
+ tools:
321
+ get-user-account:
322
+ description: Fetch user account details
323
+ parameters:
324
+ userId:
325
+ type: string
326
+ description: The user ID to look up
327
+ ```
328
+
329
+ Tool handlers receive the parameters as `args`:
330
+
331
+ ```typescript
332
+ 'get-user-account': async (args) => {
333
+ const userId = args.userId as string;
334
+ // ...
335
+ }
336
+ ```
337
+
338
+ ## Next Steps
339
+
340
+ - [Protocol Overview](/docs/protocol/overview) — Define agent behavior
341
+ - [Messages](/docs/client-sdk/messages) — Rich message rendering
342
+ - [Streaming](/docs/client-sdk/streaming) — Advanced streaming UI
343
+