@octavus/docs 1.0.0 → 2.0.0
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.
- package/content/01-getting-started/02-quickstart.md +8 -5
- package/content/02-server-sdk/01-overview.md +22 -6
- package/content/02-server-sdk/02-sessions.md +51 -10
- package/content/02-server-sdk/03-tools.md +39 -14
- package/content/02-server-sdk/04-streaming.md +55 -7
- package/content/02-server-sdk/05-cli.md +9 -9
- package/content/03-client-sdk/01-overview.md +22 -9
- package/content/03-client-sdk/02-messages.md +6 -4
- package/content/03-client-sdk/03-streaming.md +7 -3
- package/content/03-client-sdk/05-socket-transport.md +31 -10
- package/content/03-client-sdk/06-http-transport.md +81 -17
- package/content/03-client-sdk/07-structured-output.md +3 -2
- package/content/03-client-sdk/08-file-uploads.md +6 -4
- package/content/03-client-sdk/10-client-tools.md +557 -0
- package/content/04-protocol/02-input-resources.md +12 -0
- package/content/04-protocol/03-triggers.md +8 -5
- package/content/04-protocol/06-handlers.md +10 -0
- package/content/04-protocol/07-agent-config.md +34 -1
- package/content/05-api-reference/01-overview.md +18 -0
- package/content/05-api-reference/02-sessions.md +2 -0
- package/content/05-api-reference/03-agents.md +12 -0
- package/content/06-examples/02-nextjs-chat.md +12 -7
- package/content/06-examples/03-socket-chat.md +27 -13
- package/content/07-migration/01-v1-to-v2.md +366 -0
- package/content/07-migration/_meta.md +4 -0
- package/dist/chunk-3ER2T7S7.js +663 -0
- package/dist/chunk-3ER2T7S7.js.map +1 -0
- package/dist/{chunk-WJ2W3DUC.js → chunk-HFF2TVGV.js} +13 -13
- package/dist/chunk-HFF2TVGV.js.map +1 -0
- package/dist/chunk-S5JUVAKE.js +1409 -0
- package/dist/chunk-S5JUVAKE.js.map +1 -0
- package/dist/chunk-TMJG4CJH.js +1409 -0
- package/dist/chunk-TMJG4CJH.js.map +1 -0
- package/dist/chunk-YJPO6KOJ.js +1435 -0
- package/dist/chunk-YJPO6KOJ.js.map +1 -0
- package/dist/chunk-ZSCRYD5P.js +1409 -0
- package/dist/chunk-ZSCRYD5P.js.map +1 -0
- package/dist/content.js +1 -1
- package/dist/docs.json +44 -26
- package/dist/index.js +1 -1
- package/dist/search-index.json +1 -1
- package/dist/search.js +1 -1
- package/dist/search.js.map +1 -1
- package/dist/sections.json +52 -26
- package/package.json +1 -1
- package/dist/chunk-WJ2W3DUC.js.map +0 -1
|
@@ -7,6 +7,18 @@ description: Agent management API endpoints.
|
|
|
7
7
|
|
|
8
8
|
Manage agent definitions including protocols and prompts.
|
|
9
9
|
|
|
10
|
+
## Permissions
|
|
11
|
+
|
|
12
|
+
| Endpoint | Method | Permission Required |
|
|
13
|
+
| ---------------------- | ------ | ------------------- |
|
|
14
|
+
| `/api/agents` | GET | Agents OR Sessions |
|
|
15
|
+
| `/api/agents/:id` | GET | Agents OR Sessions |
|
|
16
|
+
| `/api/agents` | POST | Agents |
|
|
17
|
+
| `/api/agents/:id` | PATCH | Agents |
|
|
18
|
+
| `/api/agents/validate` | POST | Agents |
|
|
19
|
+
|
|
20
|
+
Read endpoints work with either permission since both the CLI (for sync) and Server SDK (for sessions) need to read agent definitions.
|
|
21
|
+
|
|
10
22
|
## List Agents
|
|
11
23
|
|
|
12
24
|
Get all agents in the project.
|
|
@@ -114,12 +114,13 @@ import { toSSEStream } from '@octavus/server-sdk';
|
|
|
114
114
|
import { octavus } from '@/lib/octavus';
|
|
115
115
|
|
|
116
116
|
export async function POST(request: Request) {
|
|
117
|
-
const
|
|
117
|
+
const body = await request.json();
|
|
118
|
+
const { sessionId, ...payload } = body;
|
|
118
119
|
|
|
119
120
|
// Attach to the session with tool handlers
|
|
120
121
|
const session = octavus.agentSessions.attach(sessionId, {
|
|
121
122
|
tools: {
|
|
122
|
-
//
|
|
123
|
+
// Server-side tool handlers run on YOUR server, not Octavus
|
|
123
124
|
'get-user-account': async (args) => {
|
|
124
125
|
const userId = args.userId as string;
|
|
125
126
|
// Fetch from your database
|
|
@@ -143,11 +144,14 @@ export async function POST(request: Request) {
|
|
|
143
144
|
estimatedResponse: '24 hours',
|
|
144
145
|
};
|
|
145
146
|
},
|
|
147
|
+
|
|
148
|
+
// Tools without handlers here are forwarded to the client
|
|
149
|
+
// See Client Tools docs for handling on frontend
|
|
146
150
|
},
|
|
147
151
|
});
|
|
148
152
|
|
|
149
|
-
//
|
|
150
|
-
const events = session.
|
|
153
|
+
// execute() handles both triggers and client tool continuations
|
|
154
|
+
const events = session.execute(payload, { signal: request.signal });
|
|
151
155
|
|
|
152
156
|
return new Response(toSSEStream(events), {
|
|
153
157
|
headers: {
|
|
@@ -159,7 +163,7 @@ export async function POST(request: Request) {
|
|
|
159
163
|
}
|
|
160
164
|
```
|
|
161
165
|
|
|
162
|
-
**Protocol Note:** Tool names and arguments are defined in your agent's protocol YAML. The tool handlers here must match those definitions.
|
|
166
|
+
**Protocol Note:** Tool names and arguments are defined in your agent's protocol YAML. The tool handlers here must match those definitions. Tools without server handlers are forwarded to the client.
|
|
163
167
|
|
|
164
168
|
## Step 7: Build the Chat Component
|
|
165
169
|
|
|
@@ -181,11 +185,12 @@ export function Chat({ sessionId }: ChatProps) {
|
|
|
181
185
|
const transport = useMemo(
|
|
182
186
|
() =>
|
|
183
187
|
createHttpTransport({
|
|
184
|
-
|
|
188
|
+
request: (payload, options) =>
|
|
185
189
|
fetch('/api/trigger', {
|
|
186
190
|
method: 'POST',
|
|
187
191
|
headers: { 'Content-Type': 'application/json' },
|
|
188
|
-
body: JSON.stringify({ sessionId,
|
|
192
|
+
body: JSON.stringify({ sessionId, ...payload }),
|
|
193
|
+
signal: options?.signal,
|
|
189
194
|
}),
|
|
190
195
|
}),
|
|
191
196
|
[sessionId],
|
|
@@ -106,10 +106,10 @@ export function createSocketHandler() {
|
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
// Handle trigger
|
|
110
|
-
if (msg.type === 'trigger') {
|
|
109
|
+
// Handle trigger and continue messages
|
|
110
|
+
if (msg.type === 'trigger' || msg.type === 'continue') {
|
|
111
111
|
// Create session lazily on first trigger
|
|
112
|
-
if (!session) {
|
|
112
|
+
if (!session && msg.type === 'trigger') {
|
|
113
113
|
const sessionId = await octavus.agentSessions.create(AGENT_ID, {
|
|
114
114
|
// Initial input variables from your protocol
|
|
115
115
|
COMPANY_NAME: 'Acme Corp',
|
|
@@ -117,6 +117,7 @@ export function createSocketHandler() {
|
|
|
117
117
|
|
|
118
118
|
session = octavus.agentSessions.attach(sessionId, {
|
|
119
119
|
tools: {
|
|
120
|
+
// Server-side tool handlers
|
|
120
121
|
'get-user-account': async () => {
|
|
121
122
|
// Fetch from your database
|
|
122
123
|
return { name: 'Demo User', plan: 'pro' };
|
|
@@ -124,14 +125,17 @@ export function createSocketHandler() {
|
|
|
124
125
|
'create-support-ticket': async () => {
|
|
125
126
|
return { ticketId: 'TKT-123', estimatedResponse: '24h' };
|
|
126
127
|
},
|
|
128
|
+
// Tools without handlers are forwarded to the client
|
|
127
129
|
},
|
|
128
130
|
});
|
|
129
131
|
}
|
|
130
132
|
|
|
133
|
+
if (!session) return;
|
|
134
|
+
|
|
131
135
|
abortController = new AbortController();
|
|
132
136
|
|
|
133
|
-
//
|
|
134
|
-
const events = session.
|
|
137
|
+
// execute() handles both triggers and continuations
|
|
138
|
+
const events = session.execute(msg, { signal: abortController.signal });
|
|
135
139
|
|
|
136
140
|
try {
|
|
137
141
|
for await (const event of events) {
|
|
@@ -358,17 +362,20 @@ conn.write(
|
|
|
358
362
|
|
|
359
363
|
## Protocol Integration
|
|
360
364
|
|
|
361
|
-
###
|
|
365
|
+
### Messages
|
|
362
366
|
|
|
363
|
-
The socket handler receives
|
|
367
|
+
The socket handler receives messages and forwards them to Octavus:
|
|
364
368
|
|
|
365
369
|
```typescript
|
|
366
|
-
// Client sends:
|
|
370
|
+
// Client sends trigger:
|
|
367
371
|
{ type: 'trigger', triggerName: 'user-message', input: { USER_MESSAGE: 'Hello' } }
|
|
368
372
|
|
|
369
|
-
//
|
|
370
|
-
|
|
371
|
-
|
|
373
|
+
// Client sends continuation (after client tool handling):
|
|
374
|
+
{ type: 'continue', executionId: '...', toolResults: [...] }
|
|
375
|
+
|
|
376
|
+
// Server handles both:
|
|
377
|
+
if (msg.type === 'trigger' || msg.type === 'continue') {
|
|
378
|
+
const events = session.execute(msg);
|
|
372
379
|
for await (const event of events) {
|
|
373
380
|
conn.write(JSON.stringify(event));
|
|
374
381
|
}
|
|
@@ -377,7 +384,7 @@ if (msg.type === 'trigger') {
|
|
|
377
384
|
|
|
378
385
|
### Tools
|
|
379
386
|
|
|
380
|
-
Tools are defined in your agent's protocol
|
|
387
|
+
Tools are defined in your agent's protocol. Server-side tools have handlers, client-side tools don't:
|
|
381
388
|
|
|
382
389
|
```yaml
|
|
383
390
|
# protocol.yaml
|
|
@@ -387,18 +394,25 @@ tools:
|
|
|
387
394
|
parameters:
|
|
388
395
|
userId:
|
|
389
396
|
type: string
|
|
397
|
+
|
|
398
|
+
get-browser-location:
|
|
399
|
+
description: Get user's location from browser
|
|
400
|
+
# No server handler - handled on client
|
|
390
401
|
```
|
|
391
402
|
|
|
392
403
|
```typescript
|
|
393
|
-
// Server tool
|
|
404
|
+
// Server tool handlers (only for server tools)
|
|
394
405
|
tools: {
|
|
395
406
|
'get-user-account': async (args) => {
|
|
396
407
|
const userId = args.userId as string;
|
|
397
408
|
return await db.users.find(userId);
|
|
398
409
|
},
|
|
410
|
+
// get-browser-location has no handler - forwarded to client
|
|
399
411
|
}
|
|
400
412
|
```
|
|
401
413
|
|
|
414
|
+
See [Client Tools](/docs/client-sdk/client-tools) for handling tools on the frontend.
|
|
415
|
+
|
|
402
416
|
## Meteor Integration Note
|
|
403
417
|
|
|
404
418
|
Meteor's bundler may have issues with ES6 imports of `sockjs-client`:
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Migrating from v1 to v2
|
|
3
|
+
description: Complete guide for upgrading from Octavus SDK v1.x to v2.0.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Migrating from v1 to v2
|
|
7
|
+
|
|
8
|
+
This guide covers all breaking changes and new features in Octavus SDK v2.0.0.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Version 2.0.0 introduces **client-side tool execution**, allowing tools to run in the browser with support for both automatic execution and interactive user input. This required changes to the transport layer and streaming protocol.
|
|
13
|
+
|
|
14
|
+
## Breaking Changes
|
|
15
|
+
|
|
16
|
+
### HTTP Transport Configuration
|
|
17
|
+
|
|
18
|
+
The `triggerRequest` option has been renamed to `request` and the function signature changed to support both trigger and continuation requests.
|
|
19
|
+
|
|
20
|
+
**Before (v1):**
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { createHttpTransport } from '@octavus/client-sdk';
|
|
24
|
+
|
|
25
|
+
const transport = createHttpTransport({
|
|
26
|
+
triggerRequest: (triggerName, input, options) =>
|
|
27
|
+
fetch('/api/trigger', {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: { 'Content-Type': 'application/json' },
|
|
30
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
31
|
+
signal: options?.signal,
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**After (v2):**
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import { createHttpTransport } from '@octavus/client-sdk';
|
|
40
|
+
|
|
41
|
+
const transport = createHttpTransport({
|
|
42
|
+
request: (payload, options) =>
|
|
43
|
+
fetch('/api/trigger', {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: { 'Content-Type': 'application/json' },
|
|
46
|
+
body: JSON.stringify({ sessionId, ...payload }),
|
|
47
|
+
signal: options?.signal,
|
|
48
|
+
}),
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The `payload` parameter is a discriminated union with `type: 'trigger' | 'continue'`:
|
|
53
|
+
|
|
54
|
+
- **Trigger request:** `{ type: 'trigger', triggerName: string, input?: Record<string, unknown> }`
|
|
55
|
+
- **Continue request:** `{ type: 'continue', executionId: string, toolResults: ToolResult[] }`
|
|
56
|
+
|
|
57
|
+
### Server SDK Route Handler
|
|
58
|
+
|
|
59
|
+
Server-side route handlers should use the new `execute()` method which handles both triggers and continuations via the request type.
|
|
60
|
+
|
|
61
|
+
**Before (v1):**
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
// app/api/trigger/route.ts
|
|
65
|
+
import { AgentSession, toSSEStream } from '@octavus/server-sdk';
|
|
66
|
+
|
|
67
|
+
export async function POST(request: Request) {
|
|
68
|
+
const { sessionId, triggerName, input } = await request.json();
|
|
69
|
+
|
|
70
|
+
const session = new AgentSession({
|
|
71
|
+
sessionId,
|
|
72
|
+
agentId: 'your-agent-id',
|
|
73
|
+
apiKey: process.env.OCTAVUS_API_KEY!,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const events = session.trigger(triggerName, input, { signal: request.signal });
|
|
77
|
+
return new Response(toSSEStream(events), {
|
|
78
|
+
headers: { 'Content-Type': 'text/event-stream' },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**After (v2):**
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
// app/api/trigger/route.ts
|
|
87
|
+
import { AgentSession, toSSEStream, type SessionRequest } from '@octavus/server-sdk';
|
|
88
|
+
|
|
89
|
+
export async function POST(request: Request) {
|
|
90
|
+
const body = (await request.json()) as { sessionId: string } & SessionRequest;
|
|
91
|
+
const { sessionId, ...sessionRequest } = body;
|
|
92
|
+
|
|
93
|
+
const session = new AgentSession({
|
|
94
|
+
sessionId,
|
|
95
|
+
agentId: 'your-agent-id',
|
|
96
|
+
apiKey: process.env.OCTAVUS_API_KEY!,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const events = session.execute(sessionRequest, { signal: request.signal });
|
|
100
|
+
return new Response(toSSEStream(events), {
|
|
101
|
+
headers: { 'Content-Type': 'text/event-stream' },
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `SessionRequest` type is a discriminated union:
|
|
107
|
+
|
|
108
|
+
- **Trigger:** `{ type: 'trigger', triggerName: string, input?: Record<string, unknown> }`
|
|
109
|
+
- **Continue:** `{ type: 'continue', executionId: string, toolResults: ToolResult[] }`
|
|
110
|
+
|
|
111
|
+
### Export Changes
|
|
112
|
+
|
|
113
|
+
The SDKs no longer use star exports (`export * from '@octavus/core'`). Instead, they use explicit type exports and value exports. This improves tree-shaking but may require import adjustments.
|
|
114
|
+
|
|
115
|
+
**If you were importing schemas:**
|
|
116
|
+
|
|
117
|
+
Some Zod schemas are no longer re-exported from `@octavus/server-sdk`. If you need validation schemas, import them directly from `@octavus/core`:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// Before (v1) - some schemas were re-exported
|
|
121
|
+
import { fileUploadRequestSchema } from '@octavus/server-sdk';
|
|
122
|
+
|
|
123
|
+
// After (v2) - import from core if needed
|
|
124
|
+
import { fileReferenceSchema } from '@octavus/core';
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Type imports remain the same:**
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
// Types are still available
|
|
131
|
+
import type { StreamEvent, UIMessage, FileReference } from '@octavus/client-sdk';
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Custom Transport Interface
|
|
135
|
+
|
|
136
|
+
Custom transport implementations must now implement the `continueWithToolResults()` method:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
interface Transport {
|
|
140
|
+
trigger(triggerName: string, input?: Record<string, unknown>): AsyncIterable<StreamEvent>;
|
|
141
|
+
continueWithToolResults(executionId: string, results: ToolResult[]): AsyncIterable<StreamEvent>;
|
|
142
|
+
stop(): void;
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### New ChatStatus Value
|
|
147
|
+
|
|
148
|
+
The `ChatStatus` type now includes `'awaiting-input'`:
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
// v1
|
|
152
|
+
type ChatStatus = 'idle' | 'streaming' | 'error';
|
|
153
|
+
|
|
154
|
+
// v2
|
|
155
|
+
type ChatStatus = 'idle' | 'streaming' | 'error' | 'awaiting-input';
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Update any status checks that assume only three values.
|
|
159
|
+
|
|
160
|
+
### Stream Event Changes
|
|
161
|
+
|
|
162
|
+
Two stream events have been modified:
|
|
163
|
+
|
|
164
|
+
**StartEvent and FinishEvent now include executionId:**
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
interface StartEvent {
|
|
168
|
+
type: 'start';
|
|
169
|
+
messageId?: string;
|
|
170
|
+
executionId?: string; // New in v2
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
interface FinishEvent {
|
|
174
|
+
type: 'finish';
|
|
175
|
+
finishReason: FinishReason;
|
|
176
|
+
executionId?: string; // New in v2
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**New FinishReason:**
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// Added 'client-tool-calls' to FinishReason
|
|
184
|
+
type FinishReason =
|
|
185
|
+
| 'stop'
|
|
186
|
+
| 'tool-calls'
|
|
187
|
+
| 'client-tool-calls' // New in v2
|
|
188
|
+
| 'length'
|
|
189
|
+
| 'content-filter'
|
|
190
|
+
| 'error'
|
|
191
|
+
| 'other';
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**New ClientToolRequestEvent:**
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
interface ClientToolRequestEvent {
|
|
198
|
+
type: 'client-tool-request';
|
|
199
|
+
executionId: string;
|
|
200
|
+
toolCalls: PendingToolCall[];
|
|
201
|
+
serverToolResults?: ToolResult[];
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## New Features
|
|
206
|
+
|
|
207
|
+
### Client-Side Tools
|
|
208
|
+
|
|
209
|
+
v2 introduces client-side tool execution, allowing tools to run in the browser. This is useful for:
|
|
210
|
+
|
|
211
|
+
- Accessing browser APIs (geolocation, clipboard, etc.)
|
|
212
|
+
- Interactive tools requiring user input (confirmations, forms, selections)
|
|
213
|
+
- Tools that need access to client-side state
|
|
214
|
+
|
|
215
|
+
See the [Client Tools guide](/docs/client-sdk/client-tools) for full documentation.
|
|
216
|
+
|
|
217
|
+
#### Automatic Client Tools
|
|
218
|
+
|
|
219
|
+
Tools that execute automatically without user interaction:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { useOctavusChat, createHttpTransport } from '@octavus/react';
|
|
223
|
+
|
|
224
|
+
function Chat() {
|
|
225
|
+
const { messages, send, status } = useOctavusChat({
|
|
226
|
+
transport: createHttpTransport({
|
|
227
|
+
request: (payload, options) =>
|
|
228
|
+
fetch('/api/trigger', {
|
|
229
|
+
method: 'POST',
|
|
230
|
+
headers: { 'Content-Type': 'application/json' },
|
|
231
|
+
body: JSON.stringify({ sessionId, ...payload }),
|
|
232
|
+
signal: options?.signal,
|
|
233
|
+
}),
|
|
234
|
+
}),
|
|
235
|
+
clientTools: {
|
|
236
|
+
'get-browser-location': async (args, ctx) => {
|
|
237
|
+
const pos = await new Promise((resolve, reject) => {
|
|
238
|
+
navigator.geolocation.getCurrentPosition(resolve, reject);
|
|
239
|
+
});
|
|
240
|
+
return { lat: pos.coords.latitude, lng: pos.coords.longitude };
|
|
241
|
+
},
|
|
242
|
+
'get-clipboard': async () => {
|
|
243
|
+
return await navigator.clipboard.readText();
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
// ... rest of component
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
#### Interactive Client Tools
|
|
253
|
+
|
|
254
|
+
Tools that require user interaction before completing:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { useOctavusChat, createHttpTransport } from '@octavus/react';
|
|
258
|
+
|
|
259
|
+
function Chat() {
|
|
260
|
+
const { messages, send, status, pendingClientTools } = useOctavusChat({
|
|
261
|
+
transport: createHttpTransport({
|
|
262
|
+
request: (payload, options) =>
|
|
263
|
+
fetch('/api/trigger', {
|
|
264
|
+
method: 'POST',
|
|
265
|
+
headers: { 'Content-Type': 'application/json' },
|
|
266
|
+
body: JSON.stringify({ sessionId, ...payload }),
|
|
267
|
+
signal: options?.signal,
|
|
268
|
+
}),
|
|
269
|
+
}),
|
|
270
|
+
clientTools: {
|
|
271
|
+
'request-confirmation': 'interactive',
|
|
272
|
+
'select-option': 'interactive',
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// Render UI for pending interactive tools
|
|
277
|
+
const confirmationTools = pendingClientTools['request-confirmation'] ?? [];
|
|
278
|
+
|
|
279
|
+
return (
|
|
280
|
+
<div>
|
|
281
|
+
{/* Chat messages */}
|
|
282
|
+
|
|
283
|
+
{/* Interactive tool UI */}
|
|
284
|
+
{confirmationTools.map((tool) => (
|
|
285
|
+
<ConfirmationModal
|
|
286
|
+
key={tool.toolCallId}
|
|
287
|
+
message={tool.args.message as string}
|
|
288
|
+
onConfirm={() => tool.submit({ confirmed: true })}
|
|
289
|
+
onCancel={() => tool.cancel('User declined')}
|
|
290
|
+
/>
|
|
291
|
+
))}
|
|
292
|
+
</div>
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### New Types for Client Tools
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// Context provided to automatic tool handlers
|
|
301
|
+
interface ClientToolContext {
|
|
302
|
+
toolCallId: string;
|
|
303
|
+
toolName: string;
|
|
304
|
+
signal: AbortSignal;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Handler types
|
|
308
|
+
type ClientToolHandler =
|
|
309
|
+
| ((args: Record<string, unknown>, ctx: ClientToolContext) => Promise<unknown>)
|
|
310
|
+
| 'interactive';
|
|
311
|
+
|
|
312
|
+
// Interactive tool with bound submit/cancel methods
|
|
313
|
+
interface InteractiveTool {
|
|
314
|
+
toolCallId: string;
|
|
315
|
+
toolName: string;
|
|
316
|
+
args: Record<string, unknown>;
|
|
317
|
+
submit: (result: unknown) => void;
|
|
318
|
+
cancel: (reason?: string) => void;
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### pendingClientTools Property
|
|
323
|
+
|
|
324
|
+
Both `OctavusChat` and `useOctavusChat` now expose `pendingClientTools`:
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
// Record keyed by tool name, with array of pending tools
|
|
328
|
+
const pendingClientTools: Record<string, InteractiveTool[]>;
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
This allows multiple simultaneous calls to the same tool (e.g., batch confirmations).
|
|
332
|
+
|
|
333
|
+
## Migration Checklist
|
|
334
|
+
|
|
335
|
+
Use this checklist to ensure you've addressed all breaking changes:
|
|
336
|
+
|
|
337
|
+
- [ ] Update all Octavus packages to v2.0.0
|
|
338
|
+
- [ ] Update HTTP transport from `triggerRequest` to `request` with new signature
|
|
339
|
+
- [ ] Update server route handlers to use `execute()` with `SessionRequest` type
|
|
340
|
+
- [ ] Update any status checks to handle `'awaiting-input'`
|
|
341
|
+
- [ ] Update custom transport implementations to include `continueWithToolResults()`
|
|
342
|
+
- [ ] Review any direct schema imports and update if needed
|
|
343
|
+
- [ ] (Optional) Add client-side tools for browser-based functionality
|
|
344
|
+
|
|
345
|
+
## Package Versions
|
|
346
|
+
|
|
347
|
+
All packages should be updated together to ensure compatibility:
|
|
348
|
+
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"dependencies": {
|
|
352
|
+
"@octavus/core": "^2.0.0",
|
|
353
|
+
"@octavus/client-sdk": "^2.0.0",
|
|
354
|
+
"@octavus/server-sdk": "^2.0.0",
|
|
355
|
+
"@octavus/react": "^2.0.0"
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
## Need Help?
|
|
361
|
+
|
|
362
|
+
If you encounter issues during migration:
|
|
363
|
+
|
|
364
|
+
- Check the [Client Tools documentation](/docs/client-sdk/client-tools) for the new features
|
|
365
|
+
- Review the [HTTP Transport](/docs/client-sdk/http-transport) and [Server SDK Sessions](/docs/server-sdk/sessions) docs for updated APIs
|
|
366
|
+
- [Open an issue](https://github.com/octavus-ai/js-sdk/issues) on GitHub if you find a bug
|