@octavus/docs 0.0.6 → 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.
- package/content/01-getting-started/02-quickstart.md +28 -19
- package/content/02-server-sdk/01-overview.md +34 -17
- package/content/02-server-sdk/02-sessions.md +6 -3
- package/content/02-server-sdk/03-tools.md +4 -2
- package/content/02-server-sdk/04-streaming.md +12 -4
- package/content/03-client-sdk/01-overview.md +107 -42
- package/content/03-client-sdk/02-messages.md +71 -19
- package/content/03-client-sdk/03-streaming.md +38 -28
- package/content/03-client-sdk/05-socket-transport.md +414 -0
- package/content/03-client-sdk/06-http-transport.md +280 -0
- package/content/04-protocol/03-triggers.md +48 -21
- package/content/04-protocol/04-tools.md +25 -15
- package/content/05-api-reference/01-overview.md +3 -17
- package/content/06-examples/01-overview.md +27 -0
- package/content/06-examples/02-nextjs-chat.md +343 -0
- package/content/06-examples/03-socket-chat.md +392 -0
- package/content/06-examples/_meta.md +5 -0
- 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-5M7DS4DF.js +519 -0
- package/dist/chunk-5M7DS4DF.js.map +1 -0
- package/dist/chunk-7AS4ST73.js +421 -0
- package/dist/chunk-7AS4ST73.js.map +1 -0
- package/dist/chunk-H6JGSSAJ.js +519 -0
- package/dist/chunk-H6JGSSAJ.js.map +1 -0
- package/dist/chunk-JZRABTHU.js +519 -0
- package/dist/chunk-JZRABTHU.js.map +1 -0
- package/dist/chunk-OECAPVSX.js +439 -0
- package/dist/chunk-OECAPVSX.js.map +1 -0
- package/dist/chunk-OL5QDJ42.js +483 -0
- package/dist/chunk-OL5QDJ42.js.map +1 -0
- package/dist/chunk-PMOVVTHO.js +519 -0
- package/dist/chunk-PMOVVTHO.js.map +1 -0
- package/dist/chunk-R5MTVABN.js +439 -0
- package/dist/chunk-R5MTVABN.js.map +1 -0
- package/dist/chunk-RJ4H4YVA.js +519 -0
- package/dist/chunk-RJ4H4YVA.js.map +1 -0
- package/dist/chunk-S5U4IWCR.js +439 -0
- package/dist/chunk-S5U4IWCR.js.map +1 -0
- package/dist/chunk-UCJE36LL.js +519 -0
- package/dist/chunk-UCJE36LL.js.map +1 -0
- package/dist/chunk-WW7TRC7S.js +519 -0
- package/dist/chunk-WW7TRC7S.js.map +1 -0
- package/dist/content.js +1 -1
- package/dist/docs.json +57 -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 +65 -12
- package/package.json +2 -2
|
@@ -72,6 +72,7 @@ Create an endpoint that handles triggers and streams responses:
|
|
|
72
72
|
|
|
73
73
|
```typescript
|
|
74
74
|
// app/api/trigger/route.ts
|
|
75
|
+
import { toSSEStream } from '@octavus/server-sdk';
|
|
75
76
|
import { octavus } from '@/lib/octavus';
|
|
76
77
|
|
|
77
78
|
export async function POST(request: Request) {
|
|
@@ -100,11 +101,11 @@ export async function POST(request: Request) {
|
|
|
100
101
|
},
|
|
101
102
|
});
|
|
102
103
|
|
|
103
|
-
// Trigger the action and
|
|
104
|
-
const
|
|
104
|
+
// Trigger the action and convert to SSE stream
|
|
105
|
+
const events = session.trigger(triggerName, input);
|
|
105
106
|
|
|
106
107
|
// Return as streaming response
|
|
107
|
-
return new Response(
|
|
108
|
+
return new Response(toSSEStream(events), {
|
|
108
109
|
headers: {
|
|
109
110
|
'Content-Type': 'text/event-stream',
|
|
110
111
|
'Cache-Control': 'no-cache',
|
|
@@ -118,14 +119,14 @@ export async function POST(request: Request) {
|
|
|
118
119
|
|
|
119
120
|
### 1. Create a Chat Component
|
|
120
121
|
|
|
121
|
-
Use the `useOctavusChat` hook
|
|
122
|
+
Use the `useOctavusChat` hook with the HTTP transport:
|
|
122
123
|
|
|
123
124
|
```tsx
|
|
124
125
|
// components/chat.tsx
|
|
125
126
|
'use client';
|
|
126
127
|
|
|
127
|
-
import {
|
|
128
|
-
import {
|
|
128
|
+
import { useState, useMemo } from 'react';
|
|
129
|
+
import { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';
|
|
129
130
|
|
|
130
131
|
interface ChatProps {
|
|
131
132
|
sessionId: string;
|
|
@@ -134,15 +135,21 @@ interface ChatProps {
|
|
|
134
135
|
export function Chat({ sessionId }: ChatProps) {
|
|
135
136
|
const [inputValue, setInputValue] = useState('');
|
|
136
137
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
138
|
+
// Create a stable transport instance
|
|
139
|
+
const transport = useMemo(
|
|
140
|
+
() =>
|
|
141
|
+
createHttpTransport({
|
|
142
|
+
triggerRequest: (triggerName, input) =>
|
|
143
|
+
fetch('/api/trigger', {
|
|
144
|
+
method: 'POST',
|
|
145
|
+
headers: { 'Content-Type': 'application/json' },
|
|
146
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
147
|
+
}),
|
|
148
|
+
}),
|
|
149
|
+
[sessionId],
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const { messages, status, error, send } = useOctavusChat({ transport });
|
|
146
153
|
|
|
147
154
|
const isStreaming = status === 'streaming';
|
|
148
155
|
|
|
@@ -154,9 +161,11 @@ export function Chat({ sessionId }: ChatProps) {
|
|
|
154
161
|
setInputValue('');
|
|
155
162
|
|
|
156
163
|
// Add user message and trigger in one call
|
|
157
|
-
await send(
|
|
158
|
-
|
|
159
|
-
|
|
164
|
+
await send(
|
|
165
|
+
'user-message',
|
|
166
|
+
{ USER_MESSAGE: message },
|
|
167
|
+
{ userMessage: { content: message } },
|
|
168
|
+
);
|
|
160
169
|
};
|
|
161
170
|
|
|
162
171
|
return (
|
|
@@ -208,7 +217,7 @@ function MessageBubble({ message }: { message: UIMessage }) {
|
|
|
208
217
|
}
|
|
209
218
|
return null;
|
|
210
219
|
})}
|
|
211
|
-
|
|
220
|
+
|
|
212
221
|
{/* Streaming indicator */}
|
|
213
222
|
{message.status === 'streaming' && (
|
|
214
223
|
<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,12 +63,15 @@ const session = client.agentSessions.attach(sessionId, {
|
|
|
63
63
|
All responses stream in real-time:
|
|
64
64
|
|
|
65
65
|
```typescript
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
import { toSSEStream } from '@octavus/server-sdk';
|
|
67
|
+
|
|
68
|
+
// trigger() returns an async generator of events
|
|
69
|
+
const events = session.trigger('user-message', {
|
|
70
|
+
USER_MESSAGE: 'Hello!',
|
|
68
71
|
});
|
|
69
72
|
|
|
70
|
-
//
|
|
71
|
-
return new Response(
|
|
73
|
+
// Convert to SSE stream for HTTP responses
|
|
74
|
+
return new Response(toSSEStream(events), {
|
|
72
75
|
headers: { 'Content-Type': 'text/event-stream' },
|
|
73
76
|
});
|
|
74
77
|
```
|
|
@@ -88,7 +91,7 @@ interface OctavusClientConfig {
|
|
|
88
91
|
class OctavusClient {
|
|
89
92
|
readonly agents: AgentsApi;
|
|
90
93
|
readonly agentSessions: AgentSessionsApi;
|
|
91
|
-
|
|
94
|
+
|
|
92
95
|
constructor(config: OctavusClientConfig);
|
|
93
96
|
}
|
|
94
97
|
```
|
|
@@ -101,24 +104,35 @@ Manages agent sessions.
|
|
|
101
104
|
class AgentSessionsApi {
|
|
102
105
|
// Create a new session
|
|
103
106
|
async create(agentId: string, input?: Record<string, unknown>): Promise<string>;
|
|
104
|
-
|
|
105
|
-
// Get session state (
|
|
106
|
-
async get(sessionId: string): Promise<
|
|
107
|
-
|
|
107
|
+
|
|
108
|
+
// Get full session state (for debugging/internal use)
|
|
109
|
+
async get(sessionId: string): Promise<SessionState>;
|
|
110
|
+
|
|
111
|
+
// Get UI-ready messages (for client display)
|
|
112
|
+
async getMessages(sessionId: string): Promise<UISessionState>;
|
|
113
|
+
|
|
108
114
|
// Attach to a session for triggering
|
|
109
115
|
attach(sessionId: string, options?: SessionAttachOptions): AgentSession;
|
|
110
116
|
}
|
|
111
117
|
|
|
112
|
-
|
|
118
|
+
// Full session state (internal format)
|
|
119
|
+
interface SessionState {
|
|
113
120
|
id: string;
|
|
114
121
|
agentId: string;
|
|
115
122
|
input: Record<string, unknown>;
|
|
116
123
|
variables: Record<string, unknown>;
|
|
117
124
|
resources: Record<string, unknown>;
|
|
118
|
-
messages:
|
|
125
|
+
messages: ChatMessage[]; // Internal message format
|
|
119
126
|
createdAt: string;
|
|
120
127
|
updatedAt: string;
|
|
121
128
|
}
|
|
129
|
+
|
|
130
|
+
// UI-ready session state
|
|
131
|
+
interface UISessionState {
|
|
132
|
+
sessionId: string;
|
|
133
|
+
agentId: string;
|
|
134
|
+
messages: UIMessage[]; // UI-ready messages for frontend
|
|
135
|
+
}
|
|
122
136
|
```
|
|
123
137
|
|
|
124
138
|
### AgentSession
|
|
@@ -127,15 +141,18 @@ Handles triggering and streaming for a specific session.
|
|
|
127
141
|
|
|
128
142
|
```typescript
|
|
129
143
|
class AgentSession {
|
|
130
|
-
// Trigger an action and stream
|
|
144
|
+
// Trigger an action and stream parsed events
|
|
131
145
|
trigger(
|
|
132
146
|
triggerName: string,
|
|
133
147
|
input?: Record<string, unknown>
|
|
134
|
-
):
|
|
135
|
-
|
|
148
|
+
): AsyncGenerator<StreamEvent>;
|
|
149
|
+
|
|
136
150
|
// Get the session ID
|
|
137
151
|
getSessionId(): string;
|
|
138
152
|
}
|
|
153
|
+
|
|
154
|
+
// Helper to convert events to SSE stream
|
|
155
|
+
function toSSEStream(events: AsyncIterable<StreamEvent>): ReadableStream<Uint8Array>;
|
|
139
156
|
```
|
|
140
157
|
|
|
141
158
|
## Next Steps
|
|
@@ -95,12 +95,15 @@ const session = client.agentSessions.attach(sessionId, {
|
|
|
95
95
|
Once attached, trigger actions on the session:
|
|
96
96
|
|
|
97
97
|
```typescript
|
|
98
|
-
|
|
98
|
+
import { toSSEStream } from '@octavus/server-sdk';
|
|
99
|
+
|
|
100
|
+
// trigger() returns an async generator of events
|
|
101
|
+
const events = session.trigger('user-message', {
|
|
99
102
|
USER_MESSAGE: 'How do I reset my password?',
|
|
100
103
|
});
|
|
101
104
|
|
|
102
|
-
//
|
|
103
|
-
return new Response(
|
|
105
|
+
// Convert to SSE stream for HTTP responses
|
|
106
|
+
return new Response(toSSEStream(events), {
|
|
104
107
|
headers: { 'Content-Type': 'text/event-stream' },
|
|
105
108
|
});
|
|
106
109
|
```
|
|
@@ -168,6 +168,8 @@ sequenceDiagram
|
|
|
168
168
|
For request-specific data (auth, headers), create handlers dynamically:
|
|
169
169
|
|
|
170
170
|
```typescript
|
|
171
|
+
import { toSSEStream } from '@octavus/server-sdk';
|
|
172
|
+
|
|
171
173
|
// In your API route
|
|
172
174
|
export async function POST(request: Request) {
|
|
173
175
|
const authToken = request.headers.get('Authorization');
|
|
@@ -190,8 +192,8 @@ export async function POST(request: Request) {
|
|
|
190
192
|
},
|
|
191
193
|
});
|
|
192
194
|
|
|
193
|
-
const
|
|
194
|
-
return new Response(
|
|
195
|
+
const events = session.trigger(triggerName, input);
|
|
196
|
+
return new Response(toSSEStream(events));
|
|
195
197
|
}
|
|
196
198
|
```
|
|
197
199
|
|
|
@@ -9,21 +9,29 @@ All Octavus responses stream in real-time using Server-Sent Events (SSE). This e
|
|
|
9
9
|
|
|
10
10
|
## Stream Response
|
|
11
11
|
|
|
12
|
-
When you trigger an action, you get
|
|
12
|
+
When you trigger an action, you get an async generator of parsed events:
|
|
13
13
|
|
|
14
14
|
```typescript
|
|
15
|
-
|
|
15
|
+
import { toSSEStream } from '@octavus/server-sdk';
|
|
16
|
+
|
|
17
|
+
// trigger() returns an async generator of StreamEvent
|
|
18
|
+
const events = session.trigger('user-message', {
|
|
16
19
|
USER_MESSAGE: 'Hello!'
|
|
17
20
|
});
|
|
18
21
|
|
|
19
|
-
//
|
|
20
|
-
return new Response(
|
|
22
|
+
// For HTTP endpoints, convert to SSE stream
|
|
23
|
+
return new Response(toSSEStream(events), {
|
|
21
24
|
headers: {
|
|
22
25
|
'Content-Type': 'text/event-stream',
|
|
23
26
|
'Cache-Control': 'no-cache',
|
|
24
27
|
'Connection': 'keep-alive',
|
|
25
28
|
},
|
|
26
29
|
});
|
|
30
|
+
|
|
31
|
+
// For sockets, iterate events directly
|
|
32
|
+
for await (const event of events) {
|
|
33
|
+
conn.write(JSON.stringify(event));
|
|
34
|
+
}
|
|
27
35
|
```
|
|
28
36
|
|
|
29
37
|
## Event Types
|
|
@@ -32,27 +32,50 @@ npm install @octavus/client-sdk
|
|
|
32
32
|
|
|
33
33
|
**Current version:** `{{VERSION:@octavus/client-sdk}}`
|
|
34
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 | Docs |
|
|
40
|
+
|-----------|----------|------|
|
|
41
|
+
| `createHttpTransport` | HTTP/SSE (Next.js, Express, etc.) | [HTTP Transport](/docs/client-sdk/http-transport) |
|
|
42
|
+
| `createSocketTransport` | WebSocket, SockJS, or other socket protocols | [Socket Transport](/docs/client-sdk/socket-transport) |
|
|
43
|
+
|
|
44
|
+
When the transport changes (e.g., when `sessionId` changes), the `useOctavusChat` hook automatically reinitializes with the new transport.
|
|
45
|
+
|
|
46
|
+
> **Recommendation**: Use HTTP transport unless you specifically need WebSocket features (custom real-time events, Meteor/Phoenix, etc.).
|
|
47
|
+
|
|
35
48
|
## React Usage
|
|
36
49
|
|
|
37
50
|
The `useOctavusChat` hook provides state management and streaming for React applications:
|
|
38
51
|
|
|
39
52
|
```tsx
|
|
40
|
-
import {
|
|
53
|
+
import { useMemo } from 'react';
|
|
54
|
+
import { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';
|
|
41
55
|
|
|
42
56
|
function Chat({ sessionId }: { sessionId: string }) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
// Create a stable transport instance (memoized on sessionId)
|
|
58
|
+
const transport = useMemo(
|
|
59
|
+
() =>
|
|
60
|
+
createHttpTransport({
|
|
61
|
+
triggerRequest: (triggerName, input) =>
|
|
62
|
+
fetch('/api/trigger', {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: { 'Content-Type': 'application/json' },
|
|
65
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
66
|
+
}),
|
|
67
|
+
}),
|
|
68
|
+
[sessionId],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const { messages, status, send } = useOctavusChat({ transport });
|
|
51
72
|
|
|
52
73
|
const sendMessage = async (text: string) => {
|
|
53
|
-
await send(
|
|
54
|
-
|
|
55
|
-
|
|
74
|
+
await send(
|
|
75
|
+
'user-message',
|
|
76
|
+
{ USER_MESSAGE: text },
|
|
77
|
+
{ userMessage: { content: text } },
|
|
78
|
+
);
|
|
56
79
|
};
|
|
57
80
|
|
|
58
81
|
return (
|
|
@@ -83,17 +106,19 @@ function MessageBubble({ message }: { message: UIMessage }) {
|
|
|
83
106
|
The `OctavusChat` class can be used with any framework or vanilla JavaScript:
|
|
84
107
|
|
|
85
108
|
```typescript
|
|
86
|
-
import { OctavusChat } from '@octavus/client-sdk';
|
|
109
|
+
import { OctavusChat, createHttpTransport } from '@octavus/client-sdk';
|
|
87
110
|
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
111
|
+
const transport = createHttpTransport({
|
|
112
|
+
triggerRequest: (triggerName, input) =>
|
|
113
|
+
fetch('/api/trigger', {
|
|
91
114
|
method: 'POST',
|
|
115
|
+
headers: { 'Content-Type': 'application/json' },
|
|
92
116
|
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
93
|
-
})
|
|
94
|
-
},
|
|
117
|
+
}),
|
|
95
118
|
});
|
|
96
119
|
|
|
120
|
+
const chat = new OctavusChat({ transport });
|
|
121
|
+
|
|
97
122
|
// Subscribe to state changes
|
|
98
123
|
const unsubscribe = chat.subscribe(() => {
|
|
99
124
|
console.log('Messages:', chat.messages);
|
|
@@ -102,9 +127,11 @@ const unsubscribe = chat.subscribe(() => {
|
|
|
102
127
|
});
|
|
103
128
|
|
|
104
129
|
// Send a message
|
|
105
|
-
await chat.send(
|
|
106
|
-
|
|
107
|
-
}
|
|
130
|
+
await chat.send(
|
|
131
|
+
'user-message',
|
|
132
|
+
{ USER_MESSAGE: 'Hello' },
|
|
133
|
+
{ userMessage: { content: 'Hello' } },
|
|
134
|
+
);
|
|
108
135
|
|
|
109
136
|
// Cleanup when done
|
|
110
137
|
unsubscribe();
|
|
@@ -117,12 +144,14 @@ unsubscribe();
|
|
|
117
144
|
The `send` function handles both user message display and agent triggering in one call:
|
|
118
145
|
|
|
119
146
|
```tsx
|
|
120
|
-
const { send } = useOctavusChat({
|
|
147
|
+
const { send } = useOctavusChat({ transport });
|
|
121
148
|
|
|
122
149
|
// Add user message to UI and trigger agent
|
|
123
|
-
await send(
|
|
124
|
-
|
|
125
|
-
}
|
|
150
|
+
await send(
|
|
151
|
+
'user-message',
|
|
152
|
+
{ USER_MESSAGE: text },
|
|
153
|
+
{ userMessage: { content: text } },
|
|
154
|
+
);
|
|
126
155
|
|
|
127
156
|
// Trigger without adding a user message (e.g., button click)
|
|
128
157
|
await send('request-human');
|
|
@@ -133,7 +162,7 @@ await send('request-human');
|
|
|
133
162
|
Messages contain ordered `parts` for rich content:
|
|
134
163
|
|
|
135
164
|
```tsx
|
|
136
|
-
const { messages } = useOctavusChat({
|
|
165
|
+
const { messages } = useOctavusChat({ transport });
|
|
137
166
|
|
|
138
167
|
// Each message has typed parts
|
|
139
168
|
message.parts.map((part) => {
|
|
@@ -149,7 +178,7 @@ message.parts.map((part) => {
|
|
|
149
178
|
### Status Tracking
|
|
150
179
|
|
|
151
180
|
```tsx
|
|
152
|
-
const { status } = useOctavusChat({
|
|
181
|
+
const { status } = useOctavusChat({ transport });
|
|
153
182
|
|
|
154
183
|
// status: 'idle' | 'streaming' | 'error'
|
|
155
184
|
```
|
|
@@ -157,7 +186,7 @@ const { status } = useOctavusChat({...});
|
|
|
157
186
|
### Stop Streaming
|
|
158
187
|
|
|
159
188
|
```tsx
|
|
160
|
-
const { stop } = useOctavusChat({
|
|
189
|
+
const { stop } = useOctavusChat({ transport });
|
|
161
190
|
|
|
162
191
|
// Stop current stream and finalize message
|
|
163
192
|
stop();
|
|
@@ -171,12 +200,12 @@ stop();
|
|
|
171
200
|
function useOctavusChat(options: OctavusChatOptions): UseOctavusChatReturn;
|
|
172
201
|
|
|
173
202
|
interface OctavusChatOptions {
|
|
174
|
-
// Required:
|
|
175
|
-
|
|
176
|
-
|
|
203
|
+
// Required: Transport for streaming events
|
|
204
|
+
transport: Transport;
|
|
205
|
+
|
|
177
206
|
// Optional: Pre-populate with existing messages (session restore)
|
|
178
207
|
initialMessages?: UIMessage[];
|
|
179
|
-
|
|
208
|
+
|
|
180
209
|
// Optional: Callbacks
|
|
181
210
|
onError?: (error: Error) => void;
|
|
182
211
|
onFinish?: () => void;
|
|
@@ -188,7 +217,7 @@ interface UseOctavusChatReturn {
|
|
|
188
217
|
messages: UIMessage[];
|
|
189
218
|
status: ChatStatus; // 'idle' | 'streaming' | 'error'
|
|
190
219
|
error: Error | null;
|
|
191
|
-
|
|
220
|
+
|
|
192
221
|
// Actions
|
|
193
222
|
send: (
|
|
194
223
|
triggerName: string,
|
|
@@ -198,16 +227,49 @@ interface UseOctavusChatReturn {
|
|
|
198
227
|
stop: () => void;
|
|
199
228
|
}
|
|
200
229
|
|
|
201
|
-
type TriggerFunction = (
|
|
202
|
-
triggerName: string,
|
|
203
|
-
input?: Record<string, unknown>,
|
|
204
|
-
) => Promise<Response>;
|
|
205
|
-
|
|
206
230
|
interface UserMessageInput {
|
|
207
231
|
content: string;
|
|
208
232
|
}
|
|
209
233
|
```
|
|
210
234
|
|
|
235
|
+
## Transport Reference
|
|
236
|
+
|
|
237
|
+
### createHttpTransport
|
|
238
|
+
|
|
239
|
+
Creates an HTTP/SSE transport using native `fetch()`:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { createHttpTransport } from '@octavus/react';
|
|
243
|
+
|
|
244
|
+
const transport = createHttpTransport({
|
|
245
|
+
triggerRequest: (triggerName, input) =>
|
|
246
|
+
fetch('/api/trigger', {
|
|
247
|
+
method: 'POST',
|
|
248
|
+
headers: { 'Content-Type': 'application/json' },
|
|
249
|
+
body: JSON.stringify({ sessionId, triggerName, input }),
|
|
250
|
+
}),
|
|
251
|
+
});
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### createSocketTransport
|
|
255
|
+
|
|
256
|
+
Creates a WebSocket/SockJS transport for real-time connections:
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
import { createSocketTransport } from '@octavus/react';
|
|
260
|
+
|
|
261
|
+
const transport = createSocketTransport({
|
|
262
|
+
connect: () =>
|
|
263
|
+
new Promise((resolve, reject) => {
|
|
264
|
+
const ws = new WebSocket(`wss://api.example.com/stream?sessionId=${sessionId}`);
|
|
265
|
+
ws.onopen = () => resolve(ws);
|
|
266
|
+
ws.onerror = () => reject(new Error('Connection failed'));
|
|
267
|
+
}),
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
For detailed WebSocket/SockJS usage including custom events, reconnection patterns, and server-side implementation, see [Socket Transport](/docs/client-sdk/socket-transport).
|
|
272
|
+
|
|
211
273
|
## Class Reference (Framework-Agnostic)
|
|
212
274
|
|
|
213
275
|
### OctavusChat
|
|
@@ -215,12 +277,12 @@ interface UserMessageInput {
|
|
|
215
277
|
```typescript
|
|
216
278
|
class OctavusChat {
|
|
217
279
|
constructor(options: OctavusChatOptions);
|
|
218
|
-
|
|
280
|
+
|
|
219
281
|
// State (read-only)
|
|
220
282
|
readonly messages: UIMessage[];
|
|
221
283
|
readonly status: ChatStatus;
|
|
222
284
|
readonly error: Error | null;
|
|
223
|
-
|
|
285
|
+
|
|
224
286
|
// Actions
|
|
225
287
|
send(
|
|
226
288
|
triggerName: string,
|
|
@@ -228,7 +290,7 @@ class OctavusChat {
|
|
|
228
290
|
options?: { userMessage?: UserMessageInput }
|
|
229
291
|
): Promise<void>;
|
|
230
292
|
stop(): void;
|
|
231
|
-
|
|
293
|
+
|
|
232
294
|
// Subscription
|
|
233
295
|
subscribe(callback: () => void): () => void; // Returns unsubscribe function
|
|
234
296
|
}
|
|
@@ -236,6 +298,9 @@ class OctavusChat {
|
|
|
236
298
|
|
|
237
299
|
## Next Steps
|
|
238
300
|
|
|
301
|
+
- [HTTP Transport](/docs/client-sdk/http-transport) — HTTP/SSE integration (recommended)
|
|
302
|
+
- [Socket Transport](/docs/client-sdk/socket-transport) — WebSocket and SockJS integration
|
|
239
303
|
- [Messages](/docs/client-sdk/messages) — Working with message state
|
|
240
304
|
- [Streaming](/docs/client-sdk/streaming) — Building streaming UIs
|
|
241
|
-
- [
|
|
305
|
+
- [Operations](/docs/client-sdk/execution-blocks) — Showing agent progress
|
|
306
|
+
- [Examples](/docs/examples/overview) — Complete working examples
|
|
@@ -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
|
|
|
@@ -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.
|