@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.
Files changed (53) hide show
  1. package/content/01-getting-started/02-quickstart.md +28 -19
  2. package/content/02-server-sdk/01-overview.md +34 -17
  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 +107 -42
  7. package/content/03-client-sdk/02-messages.md +71 -19
  8. package/content/03-client-sdk/03-streaming.md +38 -28
  9. package/content/03-client-sdk/05-socket-transport.md +414 -0
  10. package/content/03-client-sdk/06-http-transport.md +280 -0
  11. package/content/04-protocol/03-triggers.md +48 -21
  12. package/content/04-protocol/04-tools.md +25 -15
  13. package/content/05-api-reference/01-overview.md +3 -17
  14. package/content/06-examples/01-overview.md +27 -0
  15. package/content/06-examples/02-nextjs-chat.md +343 -0
  16. package/content/06-examples/03-socket-chat.md +392 -0
  17. package/content/06-examples/_meta.md +5 -0
  18. package/dist/chunk-232K4EME.js +439 -0
  19. package/dist/chunk-232K4EME.js.map +1 -0
  20. package/dist/chunk-2JDZLMS3.js +439 -0
  21. package/dist/chunk-2JDZLMS3.js.map +1 -0
  22. package/dist/chunk-5M7DS4DF.js +519 -0
  23. package/dist/chunk-5M7DS4DF.js.map +1 -0
  24. package/dist/chunk-7AS4ST73.js +421 -0
  25. package/dist/chunk-7AS4ST73.js.map +1 -0
  26. package/dist/chunk-H6JGSSAJ.js +519 -0
  27. package/dist/chunk-H6JGSSAJ.js.map +1 -0
  28. package/dist/chunk-JZRABTHU.js +519 -0
  29. package/dist/chunk-JZRABTHU.js.map +1 -0
  30. package/dist/chunk-OECAPVSX.js +439 -0
  31. package/dist/chunk-OECAPVSX.js.map +1 -0
  32. package/dist/chunk-OL5QDJ42.js +483 -0
  33. package/dist/chunk-OL5QDJ42.js.map +1 -0
  34. package/dist/chunk-PMOVVTHO.js +519 -0
  35. package/dist/chunk-PMOVVTHO.js.map +1 -0
  36. package/dist/chunk-R5MTVABN.js +439 -0
  37. package/dist/chunk-R5MTVABN.js.map +1 -0
  38. package/dist/chunk-RJ4H4YVA.js +519 -0
  39. package/dist/chunk-RJ4H4YVA.js.map +1 -0
  40. package/dist/chunk-S5U4IWCR.js +439 -0
  41. package/dist/chunk-S5U4IWCR.js.map +1 -0
  42. package/dist/chunk-UCJE36LL.js +519 -0
  43. package/dist/chunk-UCJE36LL.js.map +1 -0
  44. package/dist/chunk-WW7TRC7S.js +519 -0
  45. package/dist/chunk-WW7TRC7S.js.map +1 -0
  46. package/dist/content.js +1 -1
  47. package/dist/docs.json +57 -12
  48. package/dist/index.js +1 -1
  49. package/dist/search-index.json +1 -1
  50. package/dist/search.js +1 -1
  51. package/dist/search.js.map +1 -1
  52. package/dist/sections.json +65 -12
  53. package/package.json +2 -2
@@ -0,0 +1,392 @@
1
+ ---
2
+ title: Socket Chat
3
+ description: Building a chat interface with SockJS for real-time frameworks.
4
+ ---
5
+
6
+ # Socket Chat Example
7
+
8
+ This example builds a chat interface using SockJS for bidirectional communication. Use this pattern for Meteor, Phoenix, or when you need custom real-time events.
9
+
10
+ ## What You're Building
11
+
12
+ A chat interface that:
13
+ - Uses SockJS for real-time streaming
14
+ - Manages sessions server-side (client doesn't need sessionId)
15
+ - Supports custom events alongside chat
16
+ - Works with frameworks that use WebSocket-like transports
17
+
18
+ ## Architecture
19
+
20
+ ```mermaid
21
+ flowchart LR
22
+ Browser["Browser<br/>(React)"] <-->|"SockJS"| Server["Your Server<br/>(Express)"]
23
+ Server --> Platform["Octavus Platform"]
24
+ ```
25
+
26
+ **Key difference from HTTP:** The server maintains a persistent socket connection and manages sessions internally. The client never needs to know about `sessionId`.
27
+
28
+ ## Prerequisites
29
+
30
+ - Express (or similar Node.js server)
31
+ - React frontend
32
+ - `sockjs` (server) and `sockjs-client` (client)
33
+ - Octavus account with API key
34
+
35
+ ## Step 1: Install Dependencies
36
+
37
+ **Server:**
38
+ ```bash
39
+ npm install @octavus/server-sdk sockjs express
40
+ npm install -D @types/sockjs @types/express
41
+ ```
42
+
43
+ **Client:**
44
+ ```bash
45
+ npm install @octavus/react sockjs-client
46
+ npm install -D @types/sockjs-client
47
+ ```
48
+
49
+ ## Step 2: Configure Environment
50
+
51
+ ```bash
52
+ # .env
53
+ OCTAVUS_API_URL=https://octavus.ai
54
+ OCTAVUS_API_KEY=your-api-key
55
+ OCTAVUS_AGENT_ID=your-agent-id
56
+ ```
57
+
58
+ ## Step 3: Create the Octavus Client (Server)
59
+
60
+ ```typescript
61
+ // server/octavus/client.ts
62
+ import { OctavusClient } from '@octavus/server-sdk';
63
+
64
+ export const octavus = new OctavusClient({
65
+ baseUrl: process.env.OCTAVUS_API_URL!,
66
+ apiKey: process.env.OCTAVUS_API_KEY!,
67
+ });
68
+
69
+ export const AGENT_ID = process.env.OCTAVUS_AGENT_ID!;
70
+ ```
71
+
72
+ ## Step 4: Create the Socket Handler (Server)
73
+
74
+ This is the core of socket integration. Each connection gets its own session:
75
+
76
+ ```typescript
77
+ // server/octavus/socket-handler.ts
78
+ import type { Connection } from 'sockjs';
79
+ import { OctavusClient, type AgentSession } from '@octavus/server-sdk';
80
+
81
+ const octavus = new OctavusClient({
82
+ baseUrl: process.env.OCTAVUS_API_URL!,
83
+ apiKey: process.env.OCTAVUS_API_KEY!,
84
+ });
85
+
86
+ const AGENT_ID = process.env.OCTAVUS_AGENT_ID!;
87
+
88
+ export function createSocketHandler() {
89
+ return (conn: Connection) => {
90
+ let session: AgentSession | null = null;
91
+ let abortController: AbortController | null = null;
92
+
93
+ conn.on('data', (rawData: string) => {
94
+ void handleMessage(rawData);
95
+ });
96
+
97
+ async function handleMessage(rawData: string) {
98
+ const msg = JSON.parse(rawData);
99
+
100
+ // Handle stop request
101
+ if (msg.type === 'stop') {
102
+ abortController?.abort();
103
+ return;
104
+ }
105
+
106
+ // Handle trigger
107
+ if (msg.type === 'trigger') {
108
+ // Create session lazily on first trigger
109
+ if (!session) {
110
+ const sessionId = await octavus.agentSessions.create(AGENT_ID, {
111
+ // Initial input variables from your protocol
112
+ COMPANY_NAME: 'Acme Corp',
113
+ });
114
+
115
+ session = octavus.agentSessions.attach(sessionId, {
116
+ tools: {
117
+ 'get-user-account': async () => {
118
+ // Fetch from your database
119
+ return { name: 'Demo User', plan: 'pro' };
120
+ },
121
+ 'create-support-ticket': async () => {
122
+ return { ticketId: 'TKT-123', estimatedResponse: '24h' };
123
+ },
124
+ },
125
+ });
126
+ }
127
+
128
+ abortController = new AbortController();
129
+
130
+ // trigger() returns parsed events — iterate directly
131
+ const events = session.trigger(msg.triggerName, msg.input);
132
+
133
+ try {
134
+ for await (const event of events) {
135
+ if (abortController.signal.aborted) break;
136
+ conn.write(JSON.stringify(event));
137
+ }
138
+ } catch {
139
+ // Handle errors
140
+ }
141
+ }
142
+ }
143
+
144
+ conn.on('close', () => {
145
+ abortController?.abort();
146
+ });
147
+ };
148
+ }
149
+ ```
150
+
151
+ ## Step 5: Set Up the Express Server
152
+
153
+ ```typescript
154
+ // server/index.ts
155
+ import express from 'express';
156
+ import http from 'http';
157
+ import sockjs from 'sockjs';
158
+ import { createSocketHandler } from './octavus/socket-handler';
159
+
160
+ const app = express();
161
+ const server = http.createServer(app);
162
+
163
+ // Create SockJS server
164
+ const sockServer = sockjs.createServer({
165
+ prefix: '/octavus',
166
+ log: () => {}, // Silence logs
167
+ });
168
+
169
+ // Attach handler
170
+ sockServer.on('connection', createSocketHandler());
171
+ sockServer.installHandlers(server);
172
+
173
+ // Serve your frontend
174
+ app.use(express.static('dist/client'));
175
+
176
+ server.listen(3001, () => {
177
+ console.log('Server running on http://localhost:3001');
178
+ });
179
+ ```
180
+
181
+ ## Step 6: Create the Socket Hook (Client)
182
+
183
+ ```typescript
184
+ // src/hooks/useOctavusSocket.ts
185
+ import { useMemo } from 'react';
186
+ import SockJS from 'sockjs-client';
187
+ import { useOctavusChat, createSocketTransport, type SocketLike } from '@octavus/react';
188
+
189
+ function connectSocket(): Promise<SocketLike> {
190
+ return new Promise((resolve, reject) => {
191
+ const sock = new SockJS('/octavus');
192
+
193
+ sock.onopen = () => resolve(sock);
194
+ sock.onerror = () => reject(new Error('Connection failed'));
195
+ });
196
+ }
197
+
198
+ export function useOctavusSocket() {
199
+ // Transport is stable - empty deps because server manages sessions
200
+ const transport = useMemo(
201
+ () => createSocketTransport({ connect: connectSocket }),
202
+ [],
203
+ );
204
+
205
+ const { messages, status, error, send, stop } = useOctavusChat({
206
+ transport,
207
+ onError: (err) => console.error('Chat error:', err),
208
+ });
209
+
210
+ const sendMessage = async (message: string) => {
211
+ await send(
212
+ 'user-message',
213
+ { USER_MESSAGE: message },
214
+ { userMessage: { content: message } },
215
+ );
216
+ };
217
+
218
+ return { messages, status, error, sendMessage, stop };
219
+ }
220
+ ```
221
+
222
+ ## Step 7: Build the Chat Component
223
+
224
+ ```tsx
225
+ // src/components/Chat.tsx
226
+ import { useState } from 'react';
227
+ import { useOctavusSocket } from '../hooks/useOctavusSocket';
228
+
229
+ export function Chat() {
230
+ const [inputValue, setInputValue] = useState('');
231
+ const { messages, status, sendMessage, stop } = useOctavusSocket();
232
+
233
+ const handleSubmit = async (e: React.FormEvent) => {
234
+ e.preventDefault();
235
+ if (!inputValue.trim() || status === 'streaming') return;
236
+
237
+ const message = inputValue.trim();
238
+ setInputValue('');
239
+ await sendMessage(message);
240
+ };
241
+
242
+ return (
243
+ <div className="flex flex-col h-screen">
244
+ {/* Messages */}
245
+ <div className="flex-1 overflow-y-auto p-4 space-y-4">
246
+ {messages.map((msg) => (
247
+ <div
248
+ key={msg.id}
249
+ className={msg.role === 'user' ? 'text-right' : 'text-left'}
250
+ >
251
+ <div
252
+ className={`inline-block p-3 rounded-lg ${
253
+ msg.role === 'user'
254
+ ? 'bg-blue-500 text-white'
255
+ : 'bg-gray-100'
256
+ }`}
257
+ >
258
+ {msg.parts.map((part, i) => {
259
+ if (part.type === 'text') return <p key={i}>{part.text}</p>;
260
+ return null;
261
+ })}
262
+ </div>
263
+ </div>
264
+ ))}
265
+ </div>
266
+
267
+ {/* Input */}
268
+ <form onSubmit={handleSubmit} className="p-4 border-t flex gap-2">
269
+ <input
270
+ type="text"
271
+ value={inputValue}
272
+ onChange={(e) => setInputValue(e.target.value)}
273
+ placeholder="Type a message..."
274
+ className="flex-1 px-4 py-2 border rounded-lg"
275
+ disabled={status === 'streaming'}
276
+ />
277
+ {status === 'streaming' ? (
278
+ <button
279
+ type="button"
280
+ onClick={stop}
281
+ className="px-4 py-2 bg-red-500 text-white rounded-lg"
282
+ >
283
+ Stop
284
+ </button>
285
+ ) : (
286
+ <button
287
+ type="submit"
288
+ className="px-4 py-2 bg-blue-500 text-white rounded-lg"
289
+ >
290
+ Send
291
+ </button>
292
+ )}
293
+ </form>
294
+ </div>
295
+ );
296
+ }
297
+ ```
298
+
299
+ ## Custom Events
300
+
301
+ Socket transport supports custom events alongside Octavus events:
302
+
303
+ ```typescript
304
+ // Client - handle custom events
305
+ const transport = useMemo(
306
+ () =>
307
+ createSocketTransport({
308
+ connect: connectSocket,
309
+ onMessage: (data) => {
310
+ const msg = data as { type: string; [key: string]: unknown };
311
+
312
+ if (msg.type === 'typing-indicator') {
313
+ setAgentTyping(msg.isTyping as boolean);
314
+ }
315
+
316
+ if (msg.type === 'custom-notification') {
317
+ showToast(msg.message as string);
318
+ }
319
+
320
+ // Octavus events (text-delta, finish, etc.) are handled automatically
321
+ },
322
+ }),
323
+ [],
324
+ );
325
+ ```
326
+
327
+ ```typescript
328
+ // Server - send custom events
329
+ conn.write(JSON.stringify({
330
+ type: 'typing-indicator',
331
+ isTyping: true,
332
+ }));
333
+ ```
334
+
335
+ ## Protocol Integration
336
+
337
+ ### Triggers
338
+
339
+ The socket handler receives trigger messages and forwards them to Octavus:
340
+
341
+ ```typescript
342
+ // Client sends:
343
+ { type: 'trigger', triggerName: 'user-message', input: { USER_MESSAGE: 'Hello' } }
344
+
345
+ // Server handles:
346
+ if (msg.type === 'trigger') {
347
+ const events = session.trigger(msg.triggerName, msg.input);
348
+ for await (const event of events) {
349
+ conn.write(JSON.stringify(event));
350
+ }
351
+ }
352
+ ```
353
+
354
+ ### Tools
355
+
356
+ Tools are defined in your agent's protocol and handled server-side:
357
+
358
+ ```yaml
359
+ # protocol.yaml
360
+ tools:
361
+ get-user-account:
362
+ description: Fetch user details
363
+ parameters:
364
+ userId:
365
+ type: string
366
+ ```
367
+
368
+ ```typescript
369
+ // Server tool handler
370
+ tools: {
371
+ 'get-user-account': async (args) => {
372
+ const userId = args.userId as string;
373
+ return await db.users.find(userId);
374
+ },
375
+ }
376
+ ```
377
+
378
+ ## Meteor Integration Note
379
+
380
+ Meteor's bundler may have issues with ES6 imports of `sockjs-client`:
381
+
382
+ ```typescript
383
+ // Use require() instead of import
384
+ const SockJS: typeof import('sockjs-client') = require('sockjs-client');
385
+ ```
386
+
387
+ ## Next Steps
388
+
389
+ - [Socket Transport](/docs/client-sdk/socket-transport) — Advanced socket patterns
390
+ - [Protocol Overview](/docs/protocol/overview) — Define agent behavior
391
+ - [Tools](/docs/protocol/tools) — Building tool handlers
392
+
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: Examples
3
+ description: Complete working examples demonstrating Octavus integration patterns.
4
+ ---
5
+