@octavus/docs 0.0.5 → 0.0.7
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/01-introduction.md +1 -1
- package/content/01-getting-started/02-quickstart.md +26 -18
- package/content/02-server-sdk/01-overview.md +24 -13
- package/content/03-client-sdk/01-overview.md +173 -37
- package/content/03-client-sdk/02-messages.md +73 -21
- package/content/03-client-sdk/03-streaming.md +40 -30
- package/content/03-client-sdk/04-execution-blocks.md +2 -2
- package/content/03-client-sdk/05-socket-transport.md +304 -0
- package/content/03-client-sdk/_meta.md +1 -1
- package/content/04-protocol/02-input-resources.md +2 -0
- package/content/04-protocol/03-triggers.md +39 -20
- package/content/04-protocol/04-tools.md +25 -15
- package/dist/chunk-232K4EME.js +439 -0
- package/dist/chunk-232K4EME.js.map +1 -0
- package/dist/chunk-2JDZLMS3.js +439 -0
- package/dist/chunk-2JDZLMS3.js.map +1 -0
- package/dist/chunk-4WWUKU4V.js +421 -0
- package/dist/chunk-4WWUKU4V.js.map +1 -0
- package/dist/chunk-7AS4ST73.js +421 -0
- package/dist/chunk-7AS4ST73.js.map +1 -0
- package/dist/chunk-IUKE3XDN.js +421 -0
- package/dist/chunk-IUKE3XDN.js.map +1 -0
- package/dist/chunk-JOB6YWEF.js +421 -0
- package/dist/chunk-JOB6YWEF.js.map +1 -0
- package/dist/chunk-OECAPVSX.js +439 -0
- package/dist/chunk-OECAPVSX.js.map +1 -0
- package/dist/content.js +1 -1
- package/dist/docs.json +21 -12
- 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 +22 -13
- package/package.json +2 -2
|
@@ -88,6 +88,6 @@ sequenceDiagram
|
|
|
88
88
|
|
|
89
89
|
- [Quick Start](/docs/getting-started/quickstart) — Get your first agent running in minutes
|
|
90
90
|
- [Server SDK](/docs/server-sdk/overview) — Learn about backend integration
|
|
91
|
-
- [Client SDK](/docs/client-sdk/overview) — Build chat interfaces with React
|
|
91
|
+
- [Client SDK](/docs/client-sdk/overview) — Build chat interfaces with React (or other frameworks)
|
|
92
92
|
- [Protocol Reference](/docs/protocol/overview) — Deep dive into agent protocols
|
|
93
93
|
|
|
@@ -21,8 +21,8 @@ Install the Octavus SDKs in your project:
|
|
|
21
21
|
# Server SDK for backend
|
|
22
22
|
npm install @octavus/server-sdk
|
|
23
23
|
|
|
24
|
-
#
|
|
25
|
-
npm install @octavus/
|
|
24
|
+
# React bindings for frontend
|
|
25
|
+
npm install @octavus/react
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
## Backend Setup
|
|
@@ -118,14 +118,14 @@ export async function POST(request: Request) {
|
|
|
118
118
|
|
|
119
119
|
### 1. Create a Chat Component
|
|
120
120
|
|
|
121
|
-
Use the `useOctavusChat` hook
|
|
121
|
+
Use the `useOctavusChat` hook with the HTTP transport:
|
|
122
122
|
|
|
123
123
|
```tsx
|
|
124
124
|
// components/chat.tsx
|
|
125
125
|
'use client';
|
|
126
126
|
|
|
127
|
-
import {
|
|
128
|
-
import {
|
|
127
|
+
import { useState, useMemo } from 'react';
|
|
128
|
+
import { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';
|
|
129
129
|
|
|
130
130
|
interface ChatProps {
|
|
131
131
|
sessionId: string;
|
|
@@ -134,15 +134,21 @@ interface ChatProps {
|
|
|
134
134
|
export function Chat({ sessionId }: ChatProps) {
|
|
135
135
|
const [inputValue, setInputValue] = useState('');
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
// Create a stable transport instance
|
|
138
|
+
const transport = useMemo(
|
|
139
|
+
() =>
|
|
140
|
+
createHttpTransport({
|
|
141
|
+
triggerRequest: (triggerName, input) =>
|
|
142
|
+
fetch('/api/trigger', {
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers: { 'Content-Type': 'application/json' },
|
|
145
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
146
|
+
}),
|
|
147
|
+
}),
|
|
148
|
+
[sessionId],
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const { messages, status, error, send } = useOctavusChat({ transport });
|
|
146
152
|
|
|
147
153
|
const isStreaming = status === 'streaming';
|
|
148
154
|
|
|
@@ -154,9 +160,11 @@ export function Chat({ sessionId }: ChatProps) {
|
|
|
154
160
|
setInputValue('');
|
|
155
161
|
|
|
156
162
|
// Add user message and trigger in one call
|
|
157
|
-
await send(
|
|
158
|
-
|
|
159
|
-
|
|
163
|
+
await send(
|
|
164
|
+
'user-message',
|
|
165
|
+
{ USER_MESSAGE: message },
|
|
166
|
+
{ userMessage: { content: message } },
|
|
167
|
+
);
|
|
160
168
|
};
|
|
161
169
|
|
|
162
170
|
return (
|
|
@@ -208,7 +216,7 @@ function MessageBubble({ message }: { message: UIMessage }) {
|
|
|
208
216
|
}
|
|
209
217
|
return null;
|
|
210
218
|
})}
|
|
211
|
-
|
|
219
|
+
|
|
212
220
|
{/* Streaming indicator */}
|
|
213
221
|
{message.status === 'streaming' && (
|
|
214
222
|
<span className="inline-block w-2 h-4 bg-gray-400 animate-pulse ml-1" />
|
|
@@ -34,13 +34,13 @@ Create and manage agent sessions:
|
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
36
|
// Create a new session
|
|
37
|
-
const sessionId = await client.agentSessions.create('
|
|
37
|
+
const sessionId = await client.agentSessions.create('agent-id', {
|
|
38
38
|
COMPANY_NAME: 'Acme Corp',
|
|
39
39
|
PRODUCT_NAME: 'Widget Pro',
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
// Get session
|
|
43
|
-
const
|
|
42
|
+
// Get UI-ready session messages (for session restore)
|
|
43
|
+
const session = await client.agentSessions.getMessages(sessionId);
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
### Tool Handlers
|
|
@@ -63,8 +63,8 @@ const session = client.agentSessions.attach(sessionId, {
|
|
|
63
63
|
All responses stream in real-time:
|
|
64
64
|
|
|
65
65
|
```typescript
|
|
66
|
-
const { stream } = session.trigger('user-message', {
|
|
67
|
-
USER_MESSAGE: 'Hello!'
|
|
66
|
+
const { stream } = session.trigger('user-message', {
|
|
67
|
+
USER_MESSAGE: 'Hello!',
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
// Use as a streaming response
|
|
@@ -88,7 +88,7 @@ interface OctavusClientConfig {
|
|
|
88
88
|
class OctavusClient {
|
|
89
89
|
readonly agents: AgentsApi;
|
|
90
90
|
readonly agentSessions: AgentSessionsApi;
|
|
91
|
-
|
|
91
|
+
|
|
92
92
|
constructor(config: OctavusClientConfig);
|
|
93
93
|
}
|
|
94
94
|
```
|
|
@@ -101,24 +101,35 @@ Manages agent sessions.
|
|
|
101
101
|
class AgentSessionsApi {
|
|
102
102
|
// Create a new session
|
|
103
103
|
async create(agentId: string, input?: Record<string, unknown>): Promise<string>;
|
|
104
|
-
|
|
105
|
-
// Get session state (
|
|
106
|
-
async get(sessionId: string): Promise<
|
|
107
|
-
|
|
104
|
+
|
|
105
|
+
// Get full session state (for debugging/internal use)
|
|
106
|
+
async get(sessionId: string): Promise<SessionState>;
|
|
107
|
+
|
|
108
|
+
// Get UI-ready messages (for client display)
|
|
109
|
+
async getMessages(sessionId: string): Promise<UISessionState>;
|
|
110
|
+
|
|
108
111
|
// Attach to a session for triggering
|
|
109
112
|
attach(sessionId: string, options?: SessionAttachOptions): AgentSession;
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
|
|
115
|
+
// Full session state (internal format)
|
|
116
|
+
interface SessionState {
|
|
113
117
|
id: string;
|
|
114
118
|
agentId: string;
|
|
115
119
|
input: Record<string, unknown>;
|
|
116
120
|
variables: Record<string, unknown>;
|
|
117
121
|
resources: Record<string, unknown>;
|
|
118
|
-
messages:
|
|
122
|
+
messages: ChatMessage[]; // Internal message format
|
|
119
123
|
createdAt: string;
|
|
120
124
|
updatedAt: string;
|
|
121
125
|
}
|
|
126
|
+
|
|
127
|
+
// UI-ready session state
|
|
128
|
+
interface UISessionState {
|
|
129
|
+
sessionId: string;
|
|
130
|
+
agentId: string;
|
|
131
|
+
messages: UIMessage[]; // UI-ready messages for frontend
|
|
132
|
+
}
|
|
122
133
|
```
|
|
123
134
|
|
|
124
135
|
### AgentSession
|
|
@@ -132,7 +143,7 @@ class AgentSession {
|
|
|
132
143
|
triggerName: string,
|
|
133
144
|
input?: Record<string, unknown>
|
|
134
145
|
): { stream: ReadableStream<Uint8Array> };
|
|
135
|
-
|
|
146
|
+
|
|
136
147
|
// Get the session ID
|
|
137
148
|
getSessionId(): string;
|
|
138
149
|
}
|
|
@@ -1,39 +1,77 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Overview
|
|
3
|
-
description: Introduction to the Octavus Client
|
|
3
|
+
description: Introduction to the Octavus Client SDKs for building chat interfaces.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Client SDK Overview
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Octavus provides two packages for frontend integration:
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
| Package | Purpose | Use When |
|
|
11
|
+
|---------|---------|----------|
|
|
12
|
+
| `@octavus/react` | React hooks and bindings | Building React applications |
|
|
13
|
+
| `@octavus/client-sdk` | Framework-agnostic core | Using Vue, Svelte, vanilla JS, or custom integrations |
|
|
14
|
+
|
|
15
|
+
**Most users should install `@octavus/react`** — it includes everything from `@octavus/client-sdk` plus React-specific hooks.
|
|
11
16
|
|
|
12
17
|
## Installation
|
|
13
18
|
|
|
19
|
+
### React Applications
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @octavus/react
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**Current version:** `{{VERSION:@octavus/react}}`
|
|
26
|
+
|
|
27
|
+
### Other Frameworks
|
|
28
|
+
|
|
14
29
|
```bash
|
|
15
30
|
npm install @octavus/client-sdk
|
|
16
31
|
```
|
|
17
32
|
|
|
18
|
-
|
|
33
|
+
**Current version:** `{{VERSION:@octavus/client-sdk}}`
|
|
34
|
+
|
|
35
|
+
## Transport Pattern
|
|
36
|
+
|
|
37
|
+
The Client SDK uses a **transport abstraction** to handle communication with your backend. This gives you flexibility in how events are delivered:
|
|
38
|
+
|
|
39
|
+
| Transport | Use Case |
|
|
40
|
+
|-----------|----------|
|
|
41
|
+
| `createHttpTransport` | HTTP/SSE (Next.js, Express, etc.) |
|
|
42
|
+
| `createSocketTransport` | WebSocket, SockJS, or other socket protocols |
|
|
43
|
+
|
|
44
|
+
## React Usage
|
|
45
|
+
|
|
46
|
+
The `useOctavusChat` hook provides state management and streaming for React applications:
|
|
19
47
|
|
|
20
48
|
```tsx
|
|
21
|
-
import {
|
|
49
|
+
import { useMemo } from 'react';
|
|
50
|
+
import { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';
|
|
22
51
|
|
|
23
52
|
function Chat({ sessionId }: { sessionId: string }) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
53
|
+
// Create a stable transport instance (memoized on sessionId)
|
|
54
|
+
const transport = useMemo(
|
|
55
|
+
() =>
|
|
56
|
+
createHttpTransport({
|
|
57
|
+
triggerRequest: (triggerName, input) =>
|
|
58
|
+
fetch('/api/trigger', {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers: { 'Content-Type': 'application/json' },
|
|
61
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
62
|
+
}),
|
|
63
|
+
}),
|
|
64
|
+
[sessionId],
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
const { messages, status, send } = useOctavusChat({ transport });
|
|
32
68
|
|
|
33
69
|
const sendMessage = async (text: string) => {
|
|
34
|
-
await send(
|
|
35
|
-
|
|
36
|
-
|
|
70
|
+
await send(
|
|
71
|
+
'user-message',
|
|
72
|
+
{ USER_MESSAGE: text },
|
|
73
|
+
{ userMessage: { content: text } },
|
|
74
|
+
);
|
|
37
75
|
};
|
|
38
76
|
|
|
39
77
|
return (
|
|
@@ -59,6 +97,42 @@ function MessageBubble({ message }: { message: UIMessage }) {
|
|
|
59
97
|
}
|
|
60
98
|
```
|
|
61
99
|
|
|
100
|
+
## Framework-Agnostic Usage
|
|
101
|
+
|
|
102
|
+
The `OctavusChat` class can be used with any framework or vanilla JavaScript:
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
import { OctavusChat, createHttpTransport } from '@octavus/client-sdk';
|
|
106
|
+
|
|
107
|
+
const transport = createHttpTransport({
|
|
108
|
+
triggerRequest: (triggerName, input) =>
|
|
109
|
+
fetch('/api/trigger', {
|
|
110
|
+
method: 'POST',
|
|
111
|
+
headers: { 'Content-Type': 'application/json' },
|
|
112
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
113
|
+
}),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const chat = new OctavusChat({ transport });
|
|
117
|
+
|
|
118
|
+
// Subscribe to state changes
|
|
119
|
+
const unsubscribe = chat.subscribe(() => {
|
|
120
|
+
console.log('Messages:', chat.messages);
|
|
121
|
+
console.log('Status:', chat.status);
|
|
122
|
+
// Update your UI here
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
// Send a message
|
|
126
|
+
await chat.send(
|
|
127
|
+
'user-message',
|
|
128
|
+
{ USER_MESSAGE: 'Hello' },
|
|
129
|
+
{ userMessage: { content: 'Hello' } },
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Cleanup when done
|
|
133
|
+
unsubscribe();
|
|
134
|
+
```
|
|
135
|
+
|
|
62
136
|
## Key Features
|
|
63
137
|
|
|
64
138
|
### Unified Send Function
|
|
@@ -66,12 +140,14 @@ function MessageBubble({ message }: { message: UIMessage }) {
|
|
|
66
140
|
The `send` function handles both user message display and agent triggering in one call:
|
|
67
141
|
|
|
68
142
|
```tsx
|
|
69
|
-
const { send } = useOctavusChat({
|
|
143
|
+
const { send } = useOctavusChat({ transport });
|
|
70
144
|
|
|
71
145
|
// Add user message to UI and trigger agent
|
|
72
|
-
await send(
|
|
73
|
-
|
|
74
|
-
}
|
|
146
|
+
await send(
|
|
147
|
+
'user-message',
|
|
148
|
+
{ USER_MESSAGE: text },
|
|
149
|
+
{ userMessage: { content: text } },
|
|
150
|
+
);
|
|
75
151
|
|
|
76
152
|
// Trigger without adding a user message (e.g., button click)
|
|
77
153
|
await send('request-human');
|
|
@@ -82,7 +158,7 @@ await send('request-human');
|
|
|
82
158
|
Messages contain ordered `parts` for rich content:
|
|
83
159
|
|
|
84
160
|
```tsx
|
|
85
|
-
const { messages } = useOctavusChat({
|
|
161
|
+
const { messages } = useOctavusChat({ transport });
|
|
86
162
|
|
|
87
163
|
// Each message has typed parts
|
|
88
164
|
message.parts.map((part) => {
|
|
@@ -98,7 +174,7 @@ message.parts.map((part) => {
|
|
|
98
174
|
### Status Tracking
|
|
99
175
|
|
|
100
176
|
```tsx
|
|
101
|
-
const { status } = useOctavusChat({
|
|
177
|
+
const { status } = useOctavusChat({ transport });
|
|
102
178
|
|
|
103
179
|
// status: 'idle' | 'streaming' | 'error'
|
|
104
180
|
```
|
|
@@ -106,26 +182,26 @@ const { status } = useOctavusChat({...});
|
|
|
106
182
|
### Stop Streaming
|
|
107
183
|
|
|
108
184
|
```tsx
|
|
109
|
-
const { stop } = useOctavusChat({
|
|
185
|
+
const { stop } = useOctavusChat({ transport });
|
|
110
186
|
|
|
111
187
|
// Stop current stream and finalize message
|
|
112
188
|
stop();
|
|
113
189
|
```
|
|
114
190
|
|
|
115
|
-
## Hook Reference
|
|
191
|
+
## Hook Reference (React)
|
|
116
192
|
|
|
117
193
|
### useOctavusChat
|
|
118
194
|
|
|
119
195
|
```typescript
|
|
120
|
-
function useOctavusChat(options:
|
|
196
|
+
function useOctavusChat(options: OctavusChatOptions): UseOctavusChatReturn;
|
|
197
|
+
|
|
198
|
+
interface OctavusChatOptions {
|
|
199
|
+
// Required: Transport for streaming events
|
|
200
|
+
transport: Transport;
|
|
121
201
|
|
|
122
|
-
interface UseOctavusChatOptions {
|
|
123
|
-
// Required: Function that calls your backend trigger endpoint
|
|
124
|
-
onTrigger: TriggerFunction;
|
|
125
|
-
|
|
126
202
|
// Optional: Pre-populate with existing messages (session restore)
|
|
127
203
|
initialMessages?: UIMessage[];
|
|
128
|
-
|
|
204
|
+
|
|
129
205
|
// Optional: Callbacks
|
|
130
206
|
onError?: (error: Error) => void;
|
|
131
207
|
onFinish?: () => void;
|
|
@@ -137,7 +213,7 @@ interface UseOctavusChatReturn {
|
|
|
137
213
|
messages: UIMessage[];
|
|
138
214
|
status: ChatStatus; // 'idle' | 'streaming' | 'error'
|
|
139
215
|
error: Error | null;
|
|
140
|
-
|
|
216
|
+
|
|
141
217
|
// Actions
|
|
142
218
|
send: (
|
|
143
219
|
triggerName: string,
|
|
@@ -147,18 +223,78 @@ interface UseOctavusChatReturn {
|
|
|
147
223
|
stop: () => void;
|
|
148
224
|
}
|
|
149
225
|
|
|
150
|
-
type TriggerFunction = (
|
|
151
|
-
triggerName: string,
|
|
152
|
-
input?: Record<string, unknown>,
|
|
153
|
-
) => Promise<Response>;
|
|
154
|
-
|
|
155
226
|
interface UserMessageInput {
|
|
156
227
|
content: string;
|
|
157
228
|
}
|
|
158
229
|
```
|
|
159
230
|
|
|
231
|
+
## Transport Reference
|
|
232
|
+
|
|
233
|
+
### createHttpTransport
|
|
234
|
+
|
|
235
|
+
Creates an HTTP/SSE transport using native `fetch()`:
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
import { createHttpTransport } from '@octavus/react';
|
|
239
|
+
|
|
240
|
+
const transport = createHttpTransport({
|
|
241
|
+
triggerRequest: (triggerName, input) =>
|
|
242
|
+
fetch('/api/trigger', {
|
|
243
|
+
method: 'POST',
|
|
244
|
+
headers: { 'Content-Type': 'application/json' },
|
|
245
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
246
|
+
}),
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### createSocketTransport
|
|
251
|
+
|
|
252
|
+
Creates a WebSocket/SockJS transport for real-time connections:
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
import { createSocketTransport } from '@octavus/react';
|
|
256
|
+
|
|
257
|
+
const transport = createSocketTransport({
|
|
258
|
+
connect: () =>
|
|
259
|
+
new Promise((resolve, reject) => {
|
|
260
|
+
const ws = new WebSocket(`wss://api.example.com/stream?sessionId=${sessionId}`);
|
|
261
|
+
ws.onopen = () => resolve(ws);
|
|
262
|
+
ws.onerror = () => reject(new Error('Connection failed'));
|
|
263
|
+
}),
|
|
264
|
+
});
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
For detailed WebSocket/SockJS usage including custom events, reconnection patterns, and server-side implementation, see [Socket Transport](/docs/client-sdk/socket-transport).
|
|
268
|
+
|
|
269
|
+
## Class Reference (Framework-Agnostic)
|
|
270
|
+
|
|
271
|
+
### OctavusChat
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
class OctavusChat {
|
|
275
|
+
constructor(options: OctavusChatOptions);
|
|
276
|
+
|
|
277
|
+
// State (read-only)
|
|
278
|
+
readonly messages: UIMessage[];
|
|
279
|
+
readonly status: ChatStatus;
|
|
280
|
+
readonly error: Error | null;
|
|
281
|
+
|
|
282
|
+
// Actions
|
|
283
|
+
send(
|
|
284
|
+
triggerName: string,
|
|
285
|
+
input?: Record<string, unknown>,
|
|
286
|
+
options?: { userMessage?: UserMessageInput }
|
|
287
|
+
): Promise<void>;
|
|
288
|
+
stop(): void;
|
|
289
|
+
|
|
290
|
+
// Subscription
|
|
291
|
+
subscribe(callback: () => void): () => void; // Returns unsubscribe function
|
|
292
|
+
}
|
|
293
|
+
```
|
|
294
|
+
|
|
160
295
|
## Next Steps
|
|
161
296
|
|
|
162
297
|
- [Messages](/docs/client-sdk/messages) — Working with message state
|
|
163
298
|
- [Streaming](/docs/client-sdk/streaming) — Building streaming UIs
|
|
164
|
-
- [
|
|
299
|
+
- [Operations](/docs/client-sdk/execution-blocks) — Showing agent progress
|
|
300
|
+
- [Socket Transport](/docs/client-sdk/socket-transport) — WebSocket and SockJS integration
|
|
@@ -24,10 +24,10 @@ interface UIMessage {
|
|
|
24
24
|
Messages contain ordered `parts` that preserve content ordering:
|
|
25
25
|
|
|
26
26
|
```typescript
|
|
27
|
-
type UIMessagePart =
|
|
28
|
-
| UITextPart
|
|
29
|
-
| UIReasoningPart
|
|
30
|
-
| UIToolCallPart
|
|
27
|
+
type UIMessagePart =
|
|
28
|
+
| UITextPart
|
|
29
|
+
| UIReasoningPart
|
|
30
|
+
| UIToolCallPart
|
|
31
31
|
| UIOperationPart;
|
|
32
32
|
|
|
33
33
|
// Text content
|
|
@@ -73,13 +73,35 @@ interface UIOperationPart {
|
|
|
73
73
|
## Sending Messages
|
|
74
74
|
|
|
75
75
|
```tsx
|
|
76
|
-
|
|
76
|
+
import { useMemo } from 'react';
|
|
77
|
+
import { useOctavusChat, createHttpTransport } from '@octavus/react';
|
|
78
|
+
|
|
79
|
+
function Chat({ sessionId }: { sessionId: string }) {
|
|
80
|
+
const transport = useMemo(
|
|
81
|
+
() =>
|
|
82
|
+
createHttpTransport({
|
|
83
|
+
triggerRequest: (triggerName, input) =>
|
|
84
|
+
fetch('/api/trigger', {
|
|
85
|
+
method: 'POST',
|
|
86
|
+
headers: { 'Content-Type': 'application/json' },
|
|
87
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
88
|
+
}),
|
|
89
|
+
}),
|
|
90
|
+
[sessionId],
|
|
91
|
+
);
|
|
77
92
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
93
|
+
const { send } = useOctavusChat({ transport });
|
|
94
|
+
|
|
95
|
+
async function handleSend(text: string) {
|
|
96
|
+
// Add user message to UI and trigger agent
|
|
97
|
+
await send(
|
|
98
|
+
'user-message',
|
|
99
|
+
{ USER_MESSAGE: text },
|
|
100
|
+
{ userMessage: { content: text } },
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// ...
|
|
83
105
|
}
|
|
84
106
|
```
|
|
85
107
|
|
|
@@ -121,7 +143,7 @@ function MessageBubble({ message }: { message: UIMessage }) {
|
|
|
121
143
|
### Rendering Parts
|
|
122
144
|
|
|
123
145
|
```tsx
|
|
124
|
-
import { isOtherThread, type UIMessagePart } from '@octavus/
|
|
146
|
+
import { isOtherThread, type UIMessagePart } from '@octavus/react';
|
|
125
147
|
|
|
126
148
|
function PartRenderer({ part }: { part: UIMessagePart }) {
|
|
127
149
|
// Check if part belongs to a named thread (e.g., "summary")
|
|
@@ -180,7 +202,7 @@ function TextPart({ part }: { part: UITextPart }) {
|
|
|
180
202
|
Content from named threads (like "summary") is identified by the `thread` property. Use the `isOtherThread` helper:
|
|
181
203
|
|
|
182
204
|
```tsx
|
|
183
|
-
import { isOtherThread } from '@octavus/
|
|
205
|
+
import { isOtherThread } from '@octavus/react';
|
|
184
206
|
|
|
185
207
|
function PartRenderer({ part }: { part: UIMessagePart }) {
|
|
186
208
|
if (isOtherThread(part)) {
|
|
@@ -201,24 +223,54 @@ function PartRenderer({ part }: { part: UIMessagePart }) {
|
|
|
201
223
|
|
|
202
224
|
## Session Restore
|
|
203
225
|
|
|
204
|
-
When restoring a session, pass
|
|
226
|
+
When restoring a session, fetch messages from your backend and pass them to the hook:
|
|
205
227
|
|
|
206
228
|
```tsx
|
|
207
|
-
|
|
208
|
-
|
|
229
|
+
import { useMemo } from 'react';
|
|
230
|
+
import { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';
|
|
209
231
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
initialMessages:
|
|
213
|
-
|
|
214
|
-
|
|
232
|
+
interface ChatProps {
|
|
233
|
+
sessionId: string;
|
|
234
|
+
initialMessages: UIMessage[];
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function Chat({ sessionId, initialMessages }: ChatProps) {
|
|
238
|
+
const transport = useMemo(
|
|
239
|
+
() =>
|
|
240
|
+
createHttpTransport({
|
|
241
|
+
triggerRequest: (triggerName, input) =>
|
|
242
|
+
fetch('/api/trigger', {
|
|
243
|
+
method: 'POST',
|
|
244
|
+
headers: { 'Content-Type': 'application/json' },
|
|
245
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
246
|
+
}),
|
|
247
|
+
}),
|
|
248
|
+
[sessionId],
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
// Pass existing messages to restore the conversation
|
|
252
|
+
const { messages } = useOctavusChat({
|
|
253
|
+
transport,
|
|
254
|
+
initialMessages,
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
// ...
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
On your backend, use `agentSessions.getMessages()` to fetch UI-ready messages:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
// Server-side
|
|
265
|
+
const session = await client.agentSessions.getMessages(sessionId);
|
|
266
|
+
// session.messages is UIMessage[] ready for the client
|
|
215
267
|
```
|
|
216
268
|
|
|
217
269
|
## Callbacks
|
|
218
270
|
|
|
219
271
|
```tsx
|
|
220
272
|
useOctavusChat({
|
|
221
|
-
|
|
273
|
+
transport,
|
|
222
274
|
onFinish: () => {
|
|
223
275
|
console.log('Stream completed');
|
|
224
276
|
// Scroll to bottom, play sound, etc.
|