@octavus/docs 0.0.4 → 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 (40) 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/03-client-sdk/01-overview.md +69 -54
  5. package/content/03-client-sdk/02-messages.md +153 -125
  6. package/content/03-client-sdk/03-streaming.md +112 -111
  7. package/content/03-client-sdk/04-execution-blocks.md +80 -176
  8. package/content/04-protocol/01-overview.md +0 -3
  9. package/content/04-protocol/03-triggers.md +8 -9
  10. package/content/04-protocol/04-tools.md +17 -27
  11. package/content/04-protocol/06-agent-config.md +0 -7
  12. package/content/05-api-reference/02-sessions.md +20 -7
  13. package/dist/chunk-7F5WOCIL.js +421 -0
  14. package/dist/chunk-7F5WOCIL.js.map +1 -0
  15. package/dist/chunk-CHGY4G27.js +421 -0
  16. package/dist/chunk-CHGY4G27.js.map +1 -0
  17. package/dist/chunk-CI7JDWKU.js +421 -0
  18. package/dist/chunk-CI7JDWKU.js.map +1 -0
  19. package/dist/chunk-CVFWWRL7.js +421 -0
  20. package/dist/chunk-CVFWWRL7.js.map +1 -0
  21. package/dist/chunk-J7BMB3ZW.js +421 -0
  22. package/dist/chunk-J7BMB3ZW.js.map +1 -0
  23. package/dist/chunk-K3GFQUMC.js +421 -0
  24. package/dist/chunk-K3GFQUMC.js.map +1 -0
  25. package/dist/chunk-M2R2NDPR.js +421 -0
  26. package/dist/chunk-M2R2NDPR.js.map +1 -0
  27. package/dist/chunk-QCHDPR2D.js +421 -0
  28. package/dist/chunk-QCHDPR2D.js.map +1 -0
  29. package/dist/chunk-TWUMRHQ7.js +421 -0
  30. package/dist/chunk-TWUMRHQ7.js.map +1 -0
  31. package/dist/chunk-YPPXXV3I.js +421 -0
  32. package/dist/chunk-YPPXXV3I.js.map +1 -0
  33. package/dist/content.js +1 -1
  34. package/dist/docs.json +18 -18
  35. package/dist/index.js +1 -1
  36. package/dist/search-index.json +1 -1
  37. package/dist/search.js +1 -1
  38. package/dist/search.js.map +1 -1
  39. package/dist/sections.json +18 -18
  40. package/package.json +1 -1
@@ -124,7 +124,7 @@ Use the `useOctavusChat` hook to build a chat interface:
124
124
  // components/chat.tsx
125
125
  'use client';
126
126
 
127
- import { useOctavusChat } from '@octavus/client-sdk';
127
+ import { useOctavusChat, type UIMessage } from '@octavus/client-sdk';
128
128
  import { useState } from 'react';
129
129
 
130
130
  interface ChatProps {
@@ -134,14 +134,7 @@ interface ChatProps {
134
134
  export function Chat({ sessionId }: ChatProps) {
135
135
  const [inputValue, setInputValue] = useState('');
136
136
 
137
- const {
138
- messages,
139
- status,
140
- isLoading,
141
- streamingText,
142
- addUserMessage,
143
- triggerAction,
144
- } = useOctavusChat({
137
+ const { messages, status, error, send } = useOctavusChat({
145
138
  onTrigger: async (triggerName, input) => {
146
139
  return fetch('/api/trigger', {
147
140
  method: 'POST',
@@ -151,18 +144,19 @@ export function Chat({ sessionId }: ChatProps) {
151
144
  },
152
145
  });
153
146
 
147
+ const isStreaming = status === 'streaming';
148
+
154
149
  const handleSubmit = async (e: React.FormEvent) => {
155
150
  e.preventDefault();
156
- if (!inputValue.trim() || isLoading) return;
151
+ if (!inputValue.trim() || isStreaming) return;
157
152
 
158
153
  const message = inputValue.trim();
159
154
  setInputValue('');
160
155
 
161
- // Add user message to UI
162
- addUserMessage(message);
163
-
164
- // Trigger the agent
165
- await triggerAction('user-message', { USER_MESSAGE: message });
156
+ // Add user message and trigger in one call
157
+ await send('user-message', { USER_MESSAGE: message }, {
158
+ userMessage: { content: message },
159
+ });
166
160
  };
167
161
 
168
162
  return (
@@ -170,24 +164,8 @@ export function Chat({ sessionId }: ChatProps) {
170
164
  {/* Messages */}
171
165
  <div className="flex-1 overflow-y-auto p-4 space-y-4">
172
166
  {messages.map((msg) => (
173
- <div
174
- key={msg.id}
175
- className={`p-3 rounded-lg ${
176
- msg.role === 'user'
177
- ? 'bg-blue-500 text-white ml-auto max-w-xs'
178
- : 'bg-gray-100 max-w-md'
179
- }`}
180
- >
181
- {msg.content}
182
- </div>
167
+ <MessageBubble key={msg.id} message={msg} />
183
168
  ))}
184
-
185
- {/* Streaming text */}
186
- {streamingText && (
187
- <div className="bg-gray-100 p-3 rounded-lg max-w-md">
188
- {streamingText}
189
- </div>
190
- )}
191
169
  </div>
192
170
 
193
171
  {/* Input */}
@@ -199,11 +177,11 @@ export function Chat({ sessionId }: ChatProps) {
199
177
  onChange={(e) => setInputValue(e.target.value)}
200
178
  placeholder="Type a message..."
201
179
  className="flex-1 px-4 py-2 border rounded-lg"
202
- disabled={isLoading}
180
+ disabled={isStreaming}
203
181
  />
204
182
  <button
205
183
  type="submit"
206
- disabled={isLoading}
184
+ disabled={isStreaming}
207
185
  className="px-4 py-2 bg-blue-500 text-white rounded-lg disabled:opacity-50"
208
186
  >
209
187
  Send
@@ -213,6 +191,32 @@ export function Chat({ sessionId }: ChatProps) {
213
191
  </div>
214
192
  );
215
193
  }
194
+
195
+ function MessageBubble({ message }: { message: UIMessage }) {
196
+ const isUser = message.role === 'user';
197
+
198
+ return (
199
+ <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>
200
+ <div
201
+ className={`p-3 rounded-lg max-w-md ${
202
+ isUser ? 'bg-blue-500 text-white' : 'bg-gray-100'
203
+ }`}
204
+ >
205
+ {message.parts.map((part, i) => {
206
+ if (part.type === 'text') {
207
+ return <p key={i}>{part.text}</p>;
208
+ }
209
+ return null;
210
+ })}
211
+
212
+ {/* Streaming indicator */}
213
+ {message.status === 'streaming' && (
214
+ <span className="inline-block w-2 h-4 bg-gray-400 animate-pulse ml-1" />
215
+ )}
216
+ </div>
217
+ </div>
218
+ );
219
+ }
216
220
  ```
217
221
 
218
222
  ### 2. Create Session and Render Chat
@@ -271,4 +275,3 @@ Now that you have a basic integration working:
271
275
  - [Learn about the protocol](/docs/protocol/overview) to define custom agent behavior
272
276
  - [Explore the Server SDK](/docs/server-sdk/overview) for advanced backend features
273
277
  - [Build rich UIs](/docs/client-sdk/overview) with the Client SDK
274
-
@@ -102,12 +102,23 @@ class AgentSessionsApi {
102
102
  // Create a new session
103
103
  async create(agentId: string, input?: Record<string, unknown>): Promise<string>;
104
104
 
105
- // Get session state
106
- async get(sessionId: string): Promise<SessionState>;
105
+ // Get session state (includes UI-ready messages)
106
+ async get(sessionId: string): Promise<UISessionState>;
107
107
 
108
108
  // Attach to a session for triggering
109
109
  attach(sessionId: string, options?: SessionAttachOptions): AgentSession;
110
110
  }
111
+
112
+ interface UISessionState {
113
+ id: string;
114
+ agentId: string;
115
+ input: Record<string, unknown>;
116
+ variables: Record<string, unknown>;
117
+ resources: Record<string, unknown>;
118
+ messages: UIMessage[]; // UI-ready messages for session restore
119
+ createdAt: string;
120
+ updatedAt: string;
121
+ }
111
122
  ```
112
123
 
113
124
  ### AgentSession
@@ -132,4 +143,3 @@ class AgentSession {
132
143
  - [Sessions](/docs/server-sdk/sessions) — Deep dive into session management
133
144
  - [Tools](/docs/server-sdk/tools) — Implementing tool handlers
134
145
  - [Streaming](/docs/server-sdk/streaming) — Understanding stream events
135
-
@@ -29,9 +29,35 @@ const sessionId = await client.agentSessions.create('support-chat', {
29
29
  console.log('Session created:', sessionId);
30
30
  ```
31
31
 
32
- ## Session State
32
+ ## Getting Session Messages
33
33
 
34
- Retrieve the current state of a session:
34
+ To restore a conversation on page load, use `getMessages()` to retrieve UI-ready messages:
35
+
36
+ ```typescript
37
+ const session = await client.agentSessions.getMessages(sessionId);
38
+
39
+ console.log({
40
+ sessionId: session.sessionId,
41
+ agentId: session.agentId,
42
+ messages: session.messages.length, // UIMessage[] ready for frontend
43
+ });
44
+ ```
45
+
46
+ The returned messages can be passed directly to the client SDK's `initialMessages` option.
47
+
48
+ ### UISessionState Interface
49
+
50
+ ```typescript
51
+ interface UISessionState {
52
+ sessionId: string;
53
+ agentId: string;
54
+ messages: UIMessage[]; // UI-ready conversation history
55
+ }
56
+ ```
57
+
58
+ ## Full Session State (Debug)
59
+
60
+ For debugging or internal use, you can retrieve the complete session state including all variables and internal message format:
35
61
 
36
62
  ```typescript
37
63
  const state = await client.agentSessions.get(sessionId);
@@ -39,7 +65,7 @@ const state = await client.agentSessions.get(sessionId);
39
65
  console.log({
40
66
  id: state.id,
41
67
  agentId: state.agentId,
42
- messages: state.messages.length,
68
+ messages: state.messages.length, // ChatMessage[] (internal format)
43
69
  resources: state.resources,
44
70
  variables: state.variables,
45
71
  createdAt: state.createdAt,
@@ -47,20 +73,7 @@ console.log({
47
73
  });
48
74
  ```
49
75
 
50
- ### SessionState Interface
51
-
52
- ```typescript
53
- interface SessionState {
54
- id: string;
55
- agentId: string;
56
- input: Record<string, unknown>; // Initial input (immutable)
57
- variables: Record<string, unknown>; // Mutable session variables
58
- resources: Record<string, unknown>; // Resources (synced to consumer)
59
- messages: ChatMessage[]; // Conversation history
60
- createdAt: string;
61
- updatedAt: string;
62
- }
63
- ```
76
+ > **Note**: Use `getMessages()` for client-facing code. The `get()` method returns internal message format that includes hidden content not intended for end users.
64
77
 
65
78
  ## Attaching to Sessions
66
79
 
@@ -116,8 +129,8 @@ flowchart TD
116
129
  Stream events
117
130
  Update state`"]
118
131
 
119
- D -.- D1["`**client.agentSessions.get()**
120
- Get current state
132
+ D -.- D1["`**client.agentSessions.getMessages()**
133
+ Get UI-ready messages
121
134
  Restore conversation`"]
122
135
 
123
136
  E -.- E1["`Sessions expire after
@@ -130,17 +143,16 @@ When a user returns to your app, restore their session:
130
143
 
131
144
  ```typescript
132
145
  // On page load
133
- const state = await client.agentSessions.get(sessionId);
146
+ const session = await client.agentSessions.getMessages(sessionId);
134
147
 
135
- // Pass messages to frontend to restore UI
148
+ // Pass messages to frontend - they're already UI-ready
136
149
  return {
137
- sessionId,
138
- messages: state.messages,
139
- resources: state.resources,
150
+ sessionId: session.sessionId,
151
+ messages: session.messages, // UIMessage[] with parts
140
152
  };
141
153
  ```
142
154
 
143
- The `messages` array includes all conversation history with proper content ordering (text, tool calls, thinking blocks), enabling accurate UI restoration.
155
+ The `messages` array contains `UIMessage` objects with properly structured `parts`, enabling direct use with the client SDK's `initialMessages` option.
144
156
 
145
157
  ## Error Handling
146
158
 
@@ -148,7 +160,7 @@ The `messages` array includes all conversation history with proper content order
148
160
  import { ApiError } from '@octavus/server-sdk';
149
161
 
150
162
  try {
151
- const state = await client.agentSessions.get(sessionId);
163
+ const session = await client.agentSessions.getMessages(sessionId);
152
164
  } catch (error) {
153
165
  if (error instanceof ApiError) {
154
166
  if (error.status === 404) {
@@ -161,4 +173,3 @@ try {
161
173
  throw error;
162
174
  }
163
175
  ```
164
-
@@ -5,7 +5,7 @@ description: Introduction to the Octavus Client SDK for building chat interfaces
5
5
 
6
6
  # Client SDK Overview
7
7
 
8
- The `@octavus/client-sdk` package provides React hooks for building chat interfaces with Octavus agents. It handles streaming, message state, and execution blocks.
8
+ The `@octavus/client-sdk` package provides React hooks for building chat interfaces with Octavus agents. It handles streaming, message state, and real-time updates.
9
9
 
10
10
  **Current version:** `{{VERSION:@octavus/client-sdk}}`
11
11
 
@@ -18,36 +18,42 @@ npm install @octavus/client-sdk
18
18
  ## Basic Usage
19
19
 
20
20
  ```tsx
21
- import { useOctavusChat } from '@octavus/client-sdk';
21
+ import { useOctavusChat, type UIMessage } from '@octavus/client-sdk';
22
22
 
23
23
  function Chat({ sessionId }: { sessionId: string }) {
24
- const {
25
- messages,
26
- status,
27
- isLoading,
28
- streamingText,
29
- addUserMessage,
30
- triggerAction,
31
- } = useOctavusChat({
24
+ const { messages, status, send } = useOctavusChat({
32
25
  onTrigger: async (triggerName, input) => {
33
- return fetch(`/api/chat/${sessionId}/trigger`, {
26
+ return fetch(`/api/trigger`, {
34
27
  method: 'POST',
35
- body: JSON.stringify({ triggerName, input }),
28
+ body: JSON.stringify({ sessionId, triggerName, input }),
36
29
  });
37
30
  },
38
31
  });
39
32
 
40
33
  const sendMessage = async (text: string) => {
41
- addUserMessage(text);
42
- await triggerAction('user-message', { USER_MESSAGE: text });
34
+ await send('user-message', { USER_MESSAGE: text }, {
35
+ userMessage: { content: text },
36
+ });
43
37
  };
44
38
 
45
39
  return (
46
40
  <div>
47
41
  {messages.map((msg) => (
48
- <div key={msg.id}>{msg.content}</div>
42
+ <MessageBubble key={msg.id} message={msg} />
49
43
  ))}
50
- {streamingText && <div>{streamingText}</div>}
44
+ </div>
45
+ );
46
+ }
47
+
48
+ function MessageBubble({ message }: { message: UIMessage }) {
49
+ return (
50
+ <div>
51
+ {message.parts.map((part, i) => {
52
+ if (part.type === 'text') {
53
+ return <p key={i}>{part.text}</p>;
54
+ }
55
+ return null;
56
+ })}
51
57
  </div>
52
58
  );
53
59
  }
@@ -55,51 +61,55 @@ function Chat({ sessionId }: { sessionId: string }) {
55
61
 
56
62
  ## Key Features
57
63
 
58
- ### Real-time Streaming
64
+ ### Unified Send Function
59
65
 
60
- Text streams incrementally as the LLM generates it:
66
+ The `send` function handles both user message display and agent triggering in one call:
61
67
 
62
68
  ```tsx
63
- const { streamingText, streamingParts } = useOctavusChat({...});
69
+ const { send } = useOctavusChat({...});
70
+
71
+ // Add user message to UI and trigger agent
72
+ await send('user-message', { USER_MESSAGE: text }, {
73
+ userMessage: { content: text },
74
+ });
64
75
 
65
- // streamingText: Current streaming text
66
- // streamingParts: Structured parts (text, reasoning, tool calls)
76
+ // Trigger without adding a user message (e.g., button click)
77
+ await send('request-human');
67
78
  ```
68
79
 
69
- ### Message History
80
+ ### Message Parts
70
81
 
71
- Messages are tracked automatically:
82
+ Messages contain ordered `parts` for rich content:
72
83
 
73
84
  ```tsx
74
85
  const { messages } = useOctavusChat({...});
75
86
 
76
- // Each message includes:
77
- // - id: Unique identifier
78
- // - role: 'user' | 'assistant'
79
- // - content: Text content
80
- // - parts: Ordered content parts
81
- // - toolCalls: Tool call information
82
- // - reasoning: Extended reasoning (if enabled)
87
+ // Each message has typed parts
88
+ message.parts.map((part) => {
89
+ switch (part.type) {
90
+ case 'text': // Text content
91
+ case 'reasoning': // Extended reasoning/thinking
92
+ case 'tool-call': // Tool execution
93
+ case 'operation': // Internal operations (set-resource, etc.)
94
+ }
95
+ });
83
96
  ```
84
97
 
85
- ### Execution Blocks
86
-
87
- Track what the agent is doing:
98
+ ### Status Tracking
88
99
 
89
100
  ```tsx
90
- const { executionBlocks } = useOctavusChat({...});
101
+ const { status } = useOctavusChat({...});
91
102
 
92
- // Shows active execution steps
93
- // Useful for progress indicators
103
+ // status: 'idle' | 'streaming' | 'error'
94
104
  ```
95
105
 
96
- ### Status Tracking
106
+ ### Stop Streaming
97
107
 
98
108
  ```tsx
99
- const { status, isLoading } = useOctavusChat({...});
109
+ const { stop } = useOctavusChat({...});
100
110
 
101
- // status: 'idle' | 'loading' | 'streaming' | 'error'
102
- // isLoading: true during loading or streaming
111
+ // Stop current stream and finalize message
112
+ stop();
103
113
  ```
104
114
 
105
115
  ## Hook Reference
@@ -114,31 +124,36 @@ interface UseOctavusChatOptions {
114
124
  onTrigger: TriggerFunction;
115
125
 
116
126
  // Optional: Pre-populate with existing messages (session restore)
117
- initialMessages?: Message[];
127
+ initialMessages?: UIMessage[];
118
128
 
119
129
  // Optional: Callbacks
120
- onMessage?: (message: Message) => void;
121
130
  onError?: (error: Error) => void;
122
- onDone?: () => void;
131
+ onFinish?: () => void;
123
132
  onResourceUpdate?: (name: string, value: unknown) => void;
124
- onBlockStart?: (block: ExecutionBlock) => void;
125
- onBlockEnd?: (block: ExecutionBlock) => void;
126
133
  }
127
134
 
128
135
  interface UseOctavusChatReturn {
129
136
  // State
130
- messages: Message[];
131
- status: ChatStatus;
132
- isLoading: boolean;
137
+ messages: UIMessage[];
138
+ status: ChatStatus; // 'idle' | 'streaming' | 'error'
133
139
  error: Error | null;
134
- streamingText: string;
135
- streamingParts: MessagePart[];
136
- executionBlocks: ExecutionBlock[];
137
- reasoningText: string;
138
140
 
139
141
  // Actions
140
- addUserMessage: (content: string) => void;
141
- triggerAction: (triggerName: string, input?: Record<string, unknown>) => Promise<void>;
142
+ send: (
143
+ triggerName: string,
144
+ input?: Record<string, unknown>,
145
+ options?: { userMessage?: UserMessageInput }
146
+ ) => Promise<void>;
147
+ stop: () => void;
148
+ }
149
+
150
+ type TriggerFunction = (
151
+ triggerName: string,
152
+ input?: Record<string, unknown>,
153
+ ) => Promise<Response>;
154
+
155
+ interface UserMessageInput {
156
+ content: string;
142
157
  }
143
158
  ```
144
159