@octavus/docs 0.0.3 → 0.0.5

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 (51) hide show
  1. package/content/01-getting-started/02-quickstart.md +38 -35
  2. package/content/02-server-sdk/01-overview.md +13 -3
  3. package/content/02-server-sdk/02-sessions.md +38 -27
  4. package/content/02-server-sdk/04-streaming.md +0 -42
  5. package/content/03-client-sdk/01-overview.md +69 -54
  6. package/content/03-client-sdk/02-messages.md +153 -125
  7. package/content/03-client-sdk/03-streaming.md +112 -111
  8. package/content/03-client-sdk/04-execution-blocks.md +80 -176
  9. package/content/04-protocol/01-overview.md +0 -3
  10. package/content/04-protocol/03-triggers.md +8 -9
  11. package/content/04-protocol/04-tools.md +17 -27
  12. package/content/04-protocol/06-agent-config.md +0 -7
  13. package/content/05-api-reference/02-sessions.md +20 -7
  14. package/dist/chunk-7F5WOCIL.js +421 -0
  15. package/dist/chunk-7F5WOCIL.js.map +1 -0
  16. package/dist/chunk-CHGY4G27.js +421 -0
  17. package/dist/chunk-CHGY4G27.js.map +1 -0
  18. package/dist/chunk-CI7JDWKU.js +421 -0
  19. package/dist/chunk-CI7JDWKU.js.map +1 -0
  20. package/dist/chunk-CVFWWRL7.js +421 -0
  21. package/dist/chunk-CVFWWRL7.js.map +1 -0
  22. package/dist/chunk-EPDM2NIJ.js +421 -0
  23. package/dist/chunk-EPDM2NIJ.js.map +1 -0
  24. package/dist/chunk-J7BMB3ZW.js +421 -0
  25. package/dist/chunk-J7BMB3ZW.js.map +1 -0
  26. package/dist/chunk-K3GFQUMC.js +421 -0
  27. package/dist/chunk-K3GFQUMC.js.map +1 -0
  28. package/dist/chunk-M2R2NDPR.js +421 -0
  29. package/dist/chunk-M2R2NDPR.js.map +1 -0
  30. package/dist/chunk-MDMRCS4W.mjs +421 -0
  31. package/dist/chunk-MDMRCS4W.mjs.map +1 -0
  32. package/dist/chunk-QCHDPR2D.js +421 -0
  33. package/dist/chunk-QCHDPR2D.js.map +1 -0
  34. package/dist/chunk-TWUMRHQ7.js +421 -0
  35. package/dist/chunk-TWUMRHQ7.js.map +1 -0
  36. package/dist/chunk-YPPXXV3I.js +421 -0
  37. package/dist/chunk-YPPXXV3I.js.map +1 -0
  38. package/dist/content.js +1 -1
  39. package/dist/content.mjs +17 -0
  40. package/dist/content.mjs.map +1 -0
  41. package/dist/docs.json +19 -19
  42. package/dist/index.js +1 -1
  43. package/dist/index.mjs +11 -0
  44. package/dist/index.mjs.map +1 -0
  45. package/dist/search-index.json +1 -1
  46. package/dist/search.js +1 -1
  47. package/dist/search.js.map +1 -1
  48. package/dist/search.mjs +30 -0
  49. package/dist/search.mjs.map +1 -0
  50. package/dist/sections.json +19 -19
  51. package/package.json +1 -1
@@ -1,230 +1,134 @@
1
1
  ---
2
- title: Execution Blocks
3
- description: Tracking agent execution progress with the Client SDK.
2
+ title: Operations
3
+ description: Showing agent operations and progress with the Client SDK.
4
4
  ---
5
5
 
6
- # Execution Blocks
6
+ # Operations
7
7
 
8
- Execution blocks let you show users what the agent is doing. Each block represents a step in the agent's execution flow.
8
+ Operations represent internal agent activities like setting resources or serializing threads. They appear as `operation` parts in messages and help users understand what the agent is doing.
9
9
 
10
- ## Block Structure
10
+ ## Operation Structure
11
11
 
12
12
  ```typescript
13
- interface ExecutionBlock {
14
- id: string;
15
- name: string; // Human-readable name from protocol
16
- type: string; // Block type (next-message, tool-call, etc.)
17
- status: BlockStatus; // pending | running | completed | error
18
- display: DisplayMode; // hidden | name | description | stream
19
- description?: string;
20
- outputToChat: boolean; // Whether output goes to main chat
13
+ interface UIOperationPart {
14
+ type: 'operation';
15
+ operationId: string;
16
+ name: string; // Human-readable name
17
+ operationType: string; // e.g., 'set-resource', 'serialize-thread'
18
+ status: 'running' | 'done';
21
19
  thread?: string; // For named threads
22
- streamingText: string; // Current streaming content
23
- reasoning?: string; // Extended reasoning content
24
- toolCalls: ToolCallWithDescription[];
25
- startedAt: Date;
26
- completedAt?: Date;
27
20
  }
28
21
  ```
29
22
 
30
- ## Accessing Blocks
23
+ ## Rendering Operations
31
24
 
32
- ```tsx
33
- const { executionBlocks, onBlockStart, onBlockEnd } = useOctavusChat({
34
- onTrigger: ...,
35
- onBlockStart: (block) => {
36
- console.log('Block started:', block.name);
37
- },
38
- onBlockEnd: (block) => {
39
- console.log('Block completed:', block.name, block.status);
40
- },
41
- });
42
- ```
43
-
44
- ## Showing Execution Progress
25
+ Operations are typically shown as compact status indicators:
45
26
 
46
27
  ```tsx
47
- function ExecutionProgress() {
48
- const { executionBlocks, status } = useOctavusChat({...});
49
-
50
- if (status !== 'streaming' || executionBlocks.length === 0) {
51
- return null;
52
- }
28
+ import type { UIOperationPart } from '@octavus/client-sdk';
53
29
 
30
+ function OperationCard({ operation }: { operation: UIOperationPart }) {
54
31
  return (
55
- <div className="space-y-2">
56
- {executionBlocks.map((block) => (
57
- <ExecutionBlockCard key={block.id} block={block} />
58
- ))}
59
- </div>
60
- );
61
- }
62
-
63
- function ExecutionBlockCard({ block }: { block: ExecutionBlock }) {
64
- return (
65
- <div className="border rounded p-3">
66
- <div className="flex items-center gap-2">
67
- <BlockStatusIcon status={block.status} />
68
- <span className="font-medium">{block.name}</span>
69
- </div>
70
-
71
- {block.description && (
72
- <p className="text-sm text-gray-500 mt-1">{block.description}</p>
73
- )}
74
-
75
- {/* Show streaming content for stream display mode */}
76
- {block.display === 'stream' && block.streamingText && (
77
- <div className="mt-2 text-sm">
78
- {block.streamingText}
79
- </div>
80
- )}
81
-
82
- {/* Show tool calls */}
83
- {block.toolCalls.length > 0 && (
84
- <div className="mt-2 space-y-1">
85
- {block.toolCalls.map((tc) => (
86
- <div key={tc.id} className="text-sm flex items-center gap-1">
87
- 🔧 {tc.description || tc.name}
88
- {tc.status === 'available' && ' ✓'}
89
- {tc.status === 'error' && ' ✗'}
90
- </div>
91
- ))}
92
- </div>
32
+ <div className="flex items-center gap-2 text-sm text-gray-500">
33
+ {operation.status === 'running' ? (
34
+ <span className="h-2 w-2 animate-pulse rounded-full bg-blue-500" />
35
+ ) : (
36
+ <span className="text-green-500">✓</span>
93
37
  )}
38
+ <span>{operation.name}</span>
94
39
  </div>
95
40
  );
96
41
  }
97
42
  ```
98
43
 
99
- ## Display Modes
100
-
101
- Blocks have different display modes that control visibility:
44
+ ## Operations in Messages
102
45
 
103
- | Mode | Description | UI Recommendation |
104
- |------|-------------|-------------------|
105
- | `hidden` | Not shown to user | Don't render |
106
- | `name` | Shows block name | Show name only |
107
- | `description` | Shows description | Show name + description |
108
- | `stream` | Streams content | Show full streaming content |
46
+ Operations appear alongside text, reasoning, and tool calls in the message's `parts` array:
109
47
 
110
48
  ```tsx
111
- function ExecutionBlockCard({ block }: { block: ExecutionBlock }) {
112
- // Hidden blocks aren't sent to client, but check just in case
113
- if (block.display === 'hidden') {
114
- return null;
115
- }
49
+ import type { UIMessage, UIMessagePart } from '@octavus/client-sdk';
116
50
 
51
+ function MessageBubble({ message }: { message: UIMessage }) {
117
52
  return (
118
- <div className="border rounded p-3">
119
- {/* Always show name */}
120
- <div className="font-medium">{block.name}</div>
121
-
122
- {/* Show description if display mode is description or stream */}
123
- {(block.display === 'description' || block.display === 'stream') &&
124
- block.description && (
125
- <p className="text-sm text-gray-500">{block.description}</p>
126
- )}
127
-
128
- {/* Show content if display mode is stream */}
129
- {block.display === 'stream' && (
130
- <div className="mt-2">
131
- {block.streamingText}
132
- </div>
133
- )}
53
+ <div>
54
+ {message.parts.map((part, i) => (
55
+ <PartRenderer key={i} part={part} />
56
+ ))}
134
57
  </div>
135
58
  );
136
59
  }
60
+
61
+ function PartRenderer({ part }: { part: UIMessagePart }) {
62
+ switch (part.type) {
63
+ case 'text':
64
+ return <TextPart part={part} />;
65
+ case 'reasoning':
66
+ return <ReasoningPart part={part} />;
67
+ case 'tool-call':
68
+ return <ToolCallCard part={part} />;
69
+ case 'operation':
70
+ return <OperationCard operation={part} />;
71
+ default:
72
+ return null;
73
+ }
74
+ }
137
75
  ```
138
76
 
139
- ## Named Threads
77
+ ## Common Operation Types
78
+
79
+ | Type | Description |
80
+ |------|-------------|
81
+ | `set-resource` | Updating a resource value |
82
+ | `serialize-thread` | Converting thread messages to text |
83
+
84
+ ## Example: Progress During Escalation
140
85
 
141
- Blocks can belong to named threads (like "summary"). Use the `thread` property:
86
+ When a user clicks "Talk to Human", multiple operations may occur:
142
87
 
143
88
  ```tsx
144
- function ExecutionProgress() {
145
- const { executionBlocks } = useOctavusChat({...});
146
-
147
- // Group by thread
148
- const mainBlocks = executionBlocks.filter(b => !b.thread || b.thread === 'main');
149
- const namedThreads = new Map<string, ExecutionBlock[]>();
150
-
151
- executionBlocks.forEach(b => {
152
- if (b.thread && b.thread !== 'main') {
153
- if (!namedThreads.has(b.thread)) {
154
- namedThreads.set(b.thread, []);
155
- }
156
- namedThreads.get(b.thread)!.push(b);
157
- }
158
- });
89
+ function EscalationProgress({ message }: { message: UIMessage }) {
90
+ const operations = message.parts.filter(
91
+ (p): p is UIOperationPart => p.type === 'operation'
92
+ );
159
93
 
160
94
  return (
161
- <div>
162
- {/* Main execution */}
163
- <div className="space-y-2">
164
- {mainBlocks.map(b => <BlockCard key={b.id} block={b} />)}
165
- </div>
166
-
167
- {/* Named threads */}
168
- {Array.from(namedThreads.entries()).map(([thread, blocks]) => (
169
- <div key={thread} className="mt-4 bg-orange-50 p-3 rounded">
170
- <div className="text-orange-600 font-medium mb-2">
171
- Thread: {thread}
172
- </div>
173
- {blocks.map(b => <BlockCard key={b.id} block={b} />)}
95
+ <div className="space-y-2">
96
+ {operations.map((op) => (
97
+ <div key={op.operationId} className="flex items-center gap-2 text-sm">
98
+ {op.status === 'running' ? '⏳' : '✓'}
99
+ <span>{op.name}</span>
174
100
  </div>
175
101
  ))}
176
102
  </div>
177
103
  );
178
104
  }
105
+
106
+ // Example output during escalation:
107
+ // ✓ Serialize conversation
108
+ // ✓ Save conversation summary
109
+ // ⏳ Creating support ticket...
179
110
  ```
180
111
 
181
- ## Block Status Icons
112
+ ## Display Modes
182
113
 
183
- ```tsx
184
- function BlockStatusIcon({ status }: { status: BlockStatus }) {
185
- switch (status) {
186
- case 'pending':
187
- return <Circle className="w-4 h-4 text-gray-400" />;
188
- case 'running':
189
- return <Loader className="w-4 h-4 text-blue-500 animate-spin" />;
190
- case 'completed':
191
- return <CheckCircle className="w-4 h-4 text-green-500" />;
192
- case 'error':
193
- return <XCircle className="w-4 h-4 text-red-500" />;
194
- }
195
- }
196
- ```
114
+ Operations are only sent to the client if their protocol block has a visible display mode (`name`, `description`, or `stream`). Hidden operations (`display: hidden`) are filtered out by the platform before reaching the client.
197
115
 
198
- ## Example: Support Chat with Escalation
116
+ This means you can safely render all operations without checking display mode — hidden ones won't be in the message parts.
199
117
 
200
- When a user clicks "Talk to Human", the agent runs multiple blocks:
118
+ ## Named Thread Operations
201
119
 
202
- ```tsx
203
- function SupportChatProgress() {
204
- const { executionBlocks } = useOctavusChat({...});
120
+ Operations can belong to named threads. Use the `thread` property to identify them:
205
121
 
206
- // Show blocks while streaming
122
+ ```tsx
123
+ function OperationCard({ operation }: { operation: UIOperationPart }) {
207
124
  return (
208
- <div className="space-y-2">
209
- {executionBlocks.map((block) => (
210
- <div key={block.id} className="flex items-center gap-2">
211
- <BlockStatusIcon status={block.status} />
212
- <span>{getBlockLabel(block)}</span>
213
- </div>
214
- ))}
125
+ <div className="flex items-center gap-2 text-sm">
126
+ {operation.thread && (
127
+ <span className="text-amber-500">[{operation.thread}]</span>
128
+ )}
129
+ <span>{operation.name}</span>
130
+ {operation.status === 'done' && <span className="text-green-500">✓</span>}
215
131
  </div>
216
132
  );
217
133
  }
218
-
219
- function getBlockLabel(block: ExecutionBlock): string {
220
- // Use description if available, otherwise name
221
- return block.description || block.name;
222
- }
223
-
224
- // Example output during escalation:
225
- // ✓ Serialize conversation
226
- // ✓ Start summary thread
227
- // ● Summarizing your conversation (streaming...)
228
- // ○ Creating a support ticket
229
- // ○ Respond with ticket info
230
134
  ```
@@ -52,9 +52,6 @@ tools:
52
52
  description: Looking up your account
53
53
  parameters:
54
54
  userId: { type: string }
55
- returns:
56
- name: { type: string }
57
- email: { type: string }
58
55
 
59
56
  # Agent configuration (model, tools, etc.)
60
57
  agent:
@@ -80,19 +80,18 @@ triggers:
80
80
  ### From Client SDK
81
81
 
82
82
  ```typescript
83
- // User message trigger
84
- await triggerAction('user-message', {
85
- USER_MESSAGE: 'How do I reset my password?'
83
+ const { send } = useOctavusChat({...});
84
+
85
+ // User message trigger with UI message
86
+ await send('user-message', { USER_MESSAGE: text }, {
87
+ userMessage: { content: text },
86
88
  });
87
89
 
88
- // User action trigger (no input)
89
- await triggerAction('request-human');
90
+ // User action trigger (no input, no UI message)
91
+ await send('request-human');
90
92
 
91
93
  // Action with input
92
- await triggerAction('submit-feedback', {
93
- RATING: 5,
94
- COMMENT: 'Great help!'
95
- });
94
+ await send('submit-feedback', { RATING: 5, COMMENT: 'Great help!' });
96
95
  ```
97
96
 
98
97
  ### From Server SDK
@@ -18,11 +18,6 @@ tools:
18
18
  userId:
19
19
  type: string
20
20
  description: The user ID to look up
21
- returns:
22
- name: { type: string }
23
- email: { type: string }
24
- plan: { type: string }
25
- createdAt: { type: string }
26
21
  ```
27
22
 
28
23
  ### Tool Fields
@@ -32,8 +27,6 @@ tools:
32
27
  | `description` | Yes | What the tool does (shown to LLM and optionally user) |
33
28
  | `display` | No | How to show in UI: `hidden`, `name`, `description`, `stream` |
34
29
  | `parameters` | No | Input parameters the tool accepts |
35
- | `required` | No | List of required parameter names |
36
- | `returns` | No | Schema of the return value (for documentation) |
37
30
 
38
31
  ### Display Modes
39
32
 
@@ -44,9 +37,19 @@ tools:
44
37
  | `description` | Shows description while executing (default) |
45
38
  | `stream` | Streams tool progress if available |
46
39
 
47
- ## Parameter Types
40
+ ## Parameters
48
41
 
49
- Supported types: `string`, `number`, `boolean`, `unknown`
42
+ ### Parameter Fields
43
+
44
+ | Field | Required | Description |
45
+ |-------|----------|-------------|
46
+ | `type` | Yes | Data type: `string`, `number`, `boolean`, `unknown` |
47
+ | `description` | No | Describes what this parameter is for |
48
+ | `optional` | No | If true, parameter is not required (default: false) |
49
+
50
+ ### Optional Parameters
51
+
52
+ Parameters are **required by default**. Use `optional: true` to make a parameter optional:
50
53
 
51
54
  ```yaml
52
55
  tools:
@@ -59,15 +62,18 @@ tools:
59
62
 
60
63
  category:
61
64
  type: string
62
- description: Filter by category (electronics, clothing, books, home)
65
+ description: Filter by category
66
+ optional: true
63
67
 
64
68
  maxPrice:
65
69
  type: number
66
70
  description: Maximum price filter
71
+ optional: true
67
72
 
68
73
  inStock:
69
74
  type: boolean
70
75
  description: Only show in-stock items
76
+ optional: true
71
77
  ```
72
78
 
73
79
  ## Making Tools Available
@@ -218,23 +224,7 @@ tools:
218
224
  description: Gets some data
219
225
  ```
220
226
 
221
- ### 2. Define Expected Returns
222
-
223
- ```yaml
224
- tools:
225
- search-products:
226
- description: Search products
227
- parameters:
228
- query: { type: string }
229
- returns:
230
- products:
231
- type: unknown
232
- description: Array of product objects
233
- totalCount:
234
- type: number
235
- ```
236
-
237
- ### 3. Document Constrained Values
227
+ ### 2. Document Constrained Values
238
228
 
239
229
  ```yaml
240
230
  tools:
@@ -57,7 +57,6 @@ agent:
57
57
  input:
58
58
  - COMPANY_NAME
59
59
  - PRODUCT_NAME
60
- - SUPPORT_POLICIES
61
60
  ```
62
61
 
63
62
  Example `prompts/system.md`:
@@ -74,12 +73,6 @@ Help users with questions about {{PRODUCT_NAME}}.
74
73
  - Be helpful and professional
75
74
  - If you can't help, offer to escalate
76
75
  - Never share internal information
77
-
78
- {{#if SUPPORT_POLICIES}}
79
- ## Support Policies
80
-
81
- {{SUPPORT_POLICIES}}
82
- {{/if}}
83
76
  ```
84
77
 
85
78
  ## Agentic Mode
@@ -60,7 +60,7 @@ curl -X POST https://octavus.ai/api/agent-sessions \
60
60
 
61
61
  ## Get Session
62
62
 
63
- Retrieve session state including messages and resources.
63
+ Retrieve session state including UI-ready messages and resources.
64
64
 
65
65
  ```
66
66
  GET /api/agent-sessions/:sessionId
@@ -68,6 +68,8 @@ GET /api/agent-sessions/:sessionId
68
68
 
69
69
  ### Response
70
70
 
71
+ The response includes `UIMessage` objects that can be passed directly to the client SDK's `initialMessages` option:
72
+
71
73
  ```json
72
74
  {
73
75
  "id": "cm5xyz123abc456def",
@@ -85,19 +87,19 @@ GET /api/agent-sessions/:sessionId
85
87
  "id": "1702345800000-xyz789a",
86
88
  "role": "user",
87
89
  "parts": [
88
- { "type": "text", "visible": true, "content": "How do I reset my password?" }
90
+ { "type": "text", "text": "How do I reset my password?", "status": "done" }
89
91
  ],
90
- "content": "How do I reset my password?",
91
- "createdAt": "2024-01-15T10:30:00Z"
92
+ "status": "done",
93
+ "createdAt": "2024-01-15T10:30:00.000Z"
92
94
  },
93
95
  {
94
96
  "id": "1702345805000-def456b",
95
97
  "role": "assistant",
96
98
  "parts": [
97
- { "type": "text", "visible": true, "content": "I can help you reset your password..." }
99
+ { "type": "text", "text": "I can help you reset your password...", "status": "done" }
98
100
  ],
99
- "content": "I can help you reset your password...",
100
- "createdAt": "2024-01-15T10:30:05Z"
101
+ "status": "done",
102
+ "createdAt": "2024-01-15T10:30:05.000Z"
101
103
  }
102
104
  ],
103
105
  "createdAt": "2024-01-15T10:30:00Z",
@@ -105,6 +107,17 @@ GET /api/agent-sessions/:sessionId
105
107
  }
106
108
  ```
107
109
 
110
+ ### UIMessage Parts
111
+
112
+ Messages contain typed `parts` that preserve content ordering:
113
+
114
+ | Part Type | Description |
115
+ |-----------|-------------|
116
+ | `text` | Text content with `text` and `status` fields |
117
+ | `reasoning` | Extended reasoning with `text` and `status` fields |
118
+ | `tool-call` | Tool execution with `toolCallId`, `toolName`, `displayName`, `args`, `result`, `status` |
119
+ | `operation` | Internal operations with `operationId`, `name`, `operationType`, `status` |
120
+
108
121
  ### Example
109
122
 
110
123
  ```bash