@octavus/client-sdk 0.0.2 → 0.0.3
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/dist/index.d.ts +4 -3
- package/dist/index.js +82 -65
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ interface ExecutionStep {
|
|
|
14
14
|
outputToChat: boolean;
|
|
15
15
|
summary?: string;
|
|
16
16
|
fullOutput?: string;
|
|
17
|
+
reasoning?: string;
|
|
17
18
|
toolCalls?: ToolCallWithDescription[];
|
|
18
19
|
thread?: string;
|
|
19
20
|
}
|
|
@@ -27,7 +28,7 @@ interface Message {
|
|
|
27
28
|
visible?: boolean;
|
|
28
29
|
/** Ordered message parts - single source of truth for display */
|
|
29
30
|
parts?: MessagePart[];
|
|
30
|
-
|
|
31
|
+
reasoning?: string;
|
|
31
32
|
createdAt: Date;
|
|
32
33
|
}
|
|
33
34
|
type BlockStatus = 'pending' | 'running' | 'completed' | 'error';
|
|
@@ -43,7 +44,7 @@ interface ExecutionBlock {
|
|
|
43
44
|
thread?: string;
|
|
44
45
|
streamingText: string;
|
|
45
46
|
summary?: string;
|
|
46
|
-
|
|
47
|
+
reasoning?: string;
|
|
47
48
|
toolCalls: ToolCallWithDescription[];
|
|
48
49
|
startedAt: Date;
|
|
49
50
|
completedAt?: Date;
|
|
@@ -75,7 +76,7 @@ interface UseOctavusChatReturn {
|
|
|
75
76
|
/** Streaming parts in MessagePart format - single source of truth */
|
|
76
77
|
streamingParts: MessagePart[];
|
|
77
78
|
executionBlocks: ExecutionBlock[];
|
|
78
|
-
|
|
79
|
+
reasoningText: string;
|
|
79
80
|
}
|
|
80
81
|
declare function useOctavusChat(options: UseOctavusChatOptions): UseOctavusChatReturn;
|
|
81
82
|
|
package/dist/index.js
CHANGED
|
@@ -43,7 +43,7 @@ async function* parseSSEStream(response) {
|
|
|
43
43
|
async function parseErrorResponse(response) {
|
|
44
44
|
try {
|
|
45
45
|
const data = await response.json();
|
|
46
|
-
return data.error ?? data.message ?? `Request failed: ${response.status}`;
|
|
46
|
+
return data.error ?? data.errorText ?? data.message ?? `Request failed: ${response.status}`;
|
|
47
47
|
} catch {
|
|
48
48
|
return `Request failed: ${response.status}`;
|
|
49
49
|
}
|
|
@@ -83,7 +83,7 @@ function useOctavusChat(options) {
|
|
|
83
83
|
const [streamingText, setStreamingText] = useState("");
|
|
84
84
|
const [streamingParts, setStreamingParts] = useState([]);
|
|
85
85
|
const [executionBlocks, setExecutionBlocks] = useState([]);
|
|
86
|
-
const [
|
|
86
|
+
const [reasoningText, setReasoningText] = useState("");
|
|
87
87
|
const abortControllerRef = useRef(null);
|
|
88
88
|
const triggerAction = useCallback(
|
|
89
89
|
async (triggerName, input) => {
|
|
@@ -96,14 +96,14 @@ function useOctavusChat(options) {
|
|
|
96
96
|
setStreamingText("");
|
|
97
97
|
setStreamingParts([]);
|
|
98
98
|
setExecutionBlocks([]);
|
|
99
|
-
|
|
99
|
+
setReasoningText("");
|
|
100
100
|
const blocks = [];
|
|
101
101
|
let activeBlock = null;
|
|
102
102
|
const toolCalls = [];
|
|
103
103
|
let visibleFullText = "";
|
|
104
|
-
let
|
|
105
|
-
const
|
|
106
|
-
const
|
|
104
|
+
let executionReasoningText = "";
|
|
105
|
+
const reasoningStack = [];
|
|
106
|
+
const getCurrentReasoning = () => reasoningStack[reasoningStack.length - 1];
|
|
107
107
|
const parts = [];
|
|
108
108
|
try {
|
|
109
109
|
const response = await onTrigger(triggerName, input);
|
|
@@ -117,6 +117,8 @@ function useOctavusChat(options) {
|
|
|
117
117
|
break;
|
|
118
118
|
}
|
|
119
119
|
switch (event.type) {
|
|
120
|
+
case "start":
|
|
121
|
+
break;
|
|
120
122
|
case "block-start": {
|
|
121
123
|
const newBlock = {
|
|
122
124
|
id: event.blockId,
|
|
@@ -126,6 +128,7 @@ function useOctavusChat(options) {
|
|
|
126
128
|
display: event.display,
|
|
127
129
|
description: event.description,
|
|
128
130
|
outputToChat: event.outputToChat ?? false,
|
|
131
|
+
thread: event.thread,
|
|
129
132
|
streamingText: "",
|
|
130
133
|
toolCalls: [],
|
|
131
134
|
startedAt: /* @__PURE__ */ new Date()
|
|
@@ -149,16 +152,16 @@ function useOctavusChat(options) {
|
|
|
149
152
|
}
|
|
150
153
|
case "text-delta":
|
|
151
154
|
if (activeBlock) {
|
|
152
|
-
activeBlock.streamingText += event.
|
|
155
|
+
activeBlock.streamingText += event.delta;
|
|
153
156
|
setExecutionBlocks([...blocks]);
|
|
154
157
|
const isNonMainThread = activeBlock.thread !== void 0 && activeBlock.thread !== "main";
|
|
155
158
|
const shouldCaptureText = activeBlock.outputToChat || isNonMainThread;
|
|
156
159
|
if (shouldCaptureText) {
|
|
157
160
|
const { part, index } = findOrCreateTextPart(parts, activeBlock.thread);
|
|
158
|
-
part.content = (part.content ?? "") + event.
|
|
161
|
+
part.content = (part.content ?? "") + event.delta;
|
|
159
162
|
parts[index] = { ...part };
|
|
160
163
|
if (activeBlock.outputToChat) {
|
|
161
|
-
visibleFullText += event.
|
|
164
|
+
visibleFullText += event.delta;
|
|
162
165
|
setStreamingText(visibleFullText);
|
|
163
166
|
}
|
|
164
167
|
setStreamingParts([...parts]);
|
|
@@ -168,44 +171,37 @@ function useOctavusChat(options) {
|
|
|
168
171
|
case "text-start":
|
|
169
172
|
case "text-end":
|
|
170
173
|
break;
|
|
171
|
-
case "
|
|
172
|
-
const isNonMainThread =
|
|
174
|
+
case "reasoning-start": {
|
|
175
|
+
const isNonMainThread = activeBlock?.thread !== void 0 && activeBlock.thread !== "main";
|
|
173
176
|
const shouldCapture = (activeBlock?.outputToChat ?? false) || isNonMainThread;
|
|
174
177
|
const newPart = {
|
|
175
|
-
type: "
|
|
178
|
+
type: "reasoning",
|
|
176
179
|
visible: false,
|
|
177
180
|
content: "",
|
|
178
|
-
thread:
|
|
181
|
+
thread: activeBlock?.thread
|
|
179
182
|
};
|
|
180
183
|
parts.push(newPart);
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
reasoningStack.push({
|
|
185
|
+
id: event.id,
|
|
183
186
|
outputToChat: shouldCapture,
|
|
184
187
|
partIndex: parts.length - 1
|
|
185
188
|
});
|
|
186
|
-
|
|
187
|
-
if (activeBlock && event.thread) {
|
|
188
|
-
activeBlock.thread = event.thread;
|
|
189
|
-
setExecutionBlocks([...blocks]);
|
|
190
|
-
}
|
|
189
|
+
setReasoningText("");
|
|
191
190
|
break;
|
|
192
191
|
}
|
|
193
|
-
case "
|
|
194
|
-
const ctx =
|
|
195
|
-
const
|
|
196
|
-
if (ctx &&
|
|
197
|
-
|
|
198
|
-
parts[ctx.partIndex] = { ...
|
|
192
|
+
case "reasoning-delta": {
|
|
193
|
+
const ctx = getCurrentReasoning();
|
|
194
|
+
const reasoningPart = ctx ? parts[ctx.partIndex] : void 0;
|
|
195
|
+
if (ctx && reasoningPart) {
|
|
196
|
+
reasoningPart.content = (reasoningPart.content ?? "") + event.delta;
|
|
197
|
+
parts[ctx.partIndex] = { ...reasoningPart };
|
|
199
198
|
}
|
|
200
199
|
if (activeBlock?.outputToChat) {
|
|
201
|
-
|
|
200
|
+
executionReasoningText += event.delta;
|
|
202
201
|
}
|
|
203
|
-
|
|
202
|
+
setReasoningText((prev) => prev + event.delta);
|
|
204
203
|
if (activeBlock) {
|
|
205
|
-
activeBlock.
|
|
206
|
-
if (event.thread && !activeBlock.thread) {
|
|
207
|
-
activeBlock.thread = event.thread;
|
|
208
|
-
}
|
|
204
|
+
activeBlock.reasoning = (activeBlock.reasoning ?? "") + event.delta;
|
|
209
205
|
setExecutionBlocks([...blocks]);
|
|
210
206
|
}
|
|
211
207
|
if (ctx?.outputToChat) {
|
|
@@ -213,11 +209,11 @@ function useOctavusChat(options) {
|
|
|
213
209
|
}
|
|
214
210
|
break;
|
|
215
211
|
}
|
|
216
|
-
case "
|
|
217
|
-
const ctx =
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
if (ctx &&
|
|
212
|
+
case "reasoning-end": {
|
|
213
|
+
const ctx = reasoningStack.pop();
|
|
214
|
+
setReasoningText("");
|
|
215
|
+
const endReasoningPart = ctx ? parts[ctx.partIndex] : void 0;
|
|
216
|
+
if (ctx && endReasoningPart && !endReasoningPart.content?.trim()) {
|
|
221
217
|
parts.splice(ctx.partIndex, 1);
|
|
222
218
|
}
|
|
223
219
|
if (ctx?.outputToChat) {
|
|
@@ -225,19 +221,14 @@ function useOctavusChat(options) {
|
|
|
225
221
|
}
|
|
226
222
|
break;
|
|
227
223
|
}
|
|
228
|
-
case "tool-
|
|
224
|
+
case "tool-input-start": {
|
|
229
225
|
const newToolCall = {
|
|
230
226
|
id: event.toolCallId,
|
|
231
227
|
name: event.toolName,
|
|
232
228
|
arguments: {},
|
|
233
|
-
status: "
|
|
229
|
+
status: "streaming",
|
|
230
|
+
description: event.title
|
|
234
231
|
};
|
|
235
|
-
if ("toolDescription" in event && event.toolDescription) {
|
|
236
|
-
newToolCall.description = event.toolDescription;
|
|
237
|
-
}
|
|
238
|
-
if ("toolDisplay" in event && event.toolDisplay) {
|
|
239
|
-
newToolCall.display = event.toolDisplay;
|
|
240
|
-
}
|
|
241
232
|
toolCalls.push(newToolCall);
|
|
242
233
|
if (activeBlock) {
|
|
243
234
|
activeBlock.toolCalls = [...activeBlock.toolCalls, newToolCall];
|
|
@@ -247,7 +238,7 @@ function useOctavusChat(options) {
|
|
|
247
238
|
if (isVisibleBlock) {
|
|
248
239
|
const toolPart = {
|
|
249
240
|
type: "tool-call",
|
|
250
|
-
visible:
|
|
241
|
+
visible: true,
|
|
251
242
|
toolCall: newToolCall,
|
|
252
243
|
thread: activeBlock?.thread
|
|
253
244
|
};
|
|
@@ -256,11 +247,11 @@ function useOctavusChat(options) {
|
|
|
256
247
|
}
|
|
257
248
|
break;
|
|
258
249
|
}
|
|
259
|
-
case "tool-
|
|
250
|
+
case "tool-input-delta": {
|
|
260
251
|
const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);
|
|
261
252
|
if (toolCall) {
|
|
262
253
|
try {
|
|
263
|
-
toolCall.arguments = JSON.parse(event.
|
|
254
|
+
toolCall.arguments = JSON.parse(event.inputTextDelta);
|
|
264
255
|
} catch {
|
|
265
256
|
}
|
|
266
257
|
const argsPart = parts.find(
|
|
@@ -276,19 +267,44 @@ function useOctavusChat(options) {
|
|
|
276
267
|
}
|
|
277
268
|
break;
|
|
278
269
|
}
|
|
279
|
-
case "tool-
|
|
270
|
+
case "tool-input-end": {
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case "tool-input-available": {
|
|
274
|
+
const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);
|
|
275
|
+
if (toolCall) {
|
|
276
|
+
toolCall.arguments = event.input;
|
|
277
|
+
toolCall.status = "available";
|
|
278
|
+
const inputPart = parts.find(
|
|
279
|
+
(p) => p.type === "tool-call" && p.toolCall?.id === event.toolCallId
|
|
280
|
+
);
|
|
281
|
+
if (inputPart?.toolCall) {
|
|
282
|
+
inputPart.toolCall = {
|
|
283
|
+
...inputPart.toolCall,
|
|
284
|
+
arguments: toolCall.arguments,
|
|
285
|
+
status: "available"
|
|
286
|
+
};
|
|
287
|
+
setStreamingParts([...parts]);
|
|
288
|
+
}
|
|
289
|
+
if (activeBlock) {
|
|
290
|
+
setExecutionBlocks([...blocks]);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
case "tool-output-available": {
|
|
280
296
|
const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);
|
|
281
297
|
if (toolCall) {
|
|
282
|
-
toolCall.status = "
|
|
283
|
-
toolCall.result = event.
|
|
298
|
+
toolCall.status = "available";
|
|
299
|
+
toolCall.result = event.output;
|
|
284
300
|
const resultPart = parts.find(
|
|
285
301
|
(p) => p.type === "tool-call" && p.toolCall?.id === event.toolCallId
|
|
286
302
|
);
|
|
287
303
|
if (resultPart?.toolCall) {
|
|
288
304
|
resultPart.toolCall = {
|
|
289
305
|
...resultPart.toolCall,
|
|
290
|
-
status: "
|
|
291
|
-
result: event.
|
|
306
|
+
status: "available",
|
|
307
|
+
result: event.output
|
|
292
308
|
};
|
|
293
309
|
setStreamingParts([...parts]);
|
|
294
310
|
}
|
|
@@ -298,11 +314,11 @@ function useOctavusChat(options) {
|
|
|
298
314
|
}
|
|
299
315
|
break;
|
|
300
316
|
}
|
|
301
|
-
case "tool-
|
|
317
|
+
case "tool-output-error": {
|
|
302
318
|
const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);
|
|
303
319
|
if (toolCall) {
|
|
304
320
|
toolCall.status = "error";
|
|
305
|
-
toolCall.error = event.
|
|
321
|
+
toolCall.error = event.errorText;
|
|
306
322
|
const errorPart = parts.find(
|
|
307
323
|
(p) => p.type === "tool-call" && p.toolCall?.id === event.toolCallId
|
|
308
324
|
);
|
|
@@ -310,7 +326,7 @@ function useOctavusChat(options) {
|
|
|
310
326
|
errorPart.toolCall = {
|
|
311
327
|
...errorPart.toolCall,
|
|
312
328
|
status: "error",
|
|
313
|
-
error: event.
|
|
329
|
+
error: event.errorText
|
|
314
330
|
};
|
|
315
331
|
setStreamingParts([...parts]);
|
|
316
332
|
}
|
|
@@ -323,9 +339,9 @@ function useOctavusChat(options) {
|
|
|
323
339
|
case "resource-update":
|
|
324
340
|
onResourceUpdate?.(event.name, event.value);
|
|
325
341
|
break;
|
|
326
|
-
case "
|
|
327
|
-
while (
|
|
328
|
-
const ctx =
|
|
342
|
+
case "finish": {
|
|
343
|
+
while (reasoningStack.length > 0) {
|
|
344
|
+
const ctx = reasoningStack.pop();
|
|
329
345
|
const remainingPart = ctx ? parts[ctx.partIndex] : void 0;
|
|
330
346
|
if (ctx && remainingPart && !remainingPart.content?.trim()) {
|
|
331
347
|
parts.splice(ctx.partIndex, 1);
|
|
@@ -340,18 +356,19 @@ function useOctavusChat(options) {
|
|
|
340
356
|
outputToChat: b.outputToChat,
|
|
341
357
|
summary: b.summary,
|
|
342
358
|
fullOutput: b.streamingText || void 0,
|
|
359
|
+
reasoning: b.reasoning || void 0,
|
|
343
360
|
toolCalls: b.toolCalls.length > 0 ? b.toolCalls : void 0,
|
|
344
361
|
thread: b.thread
|
|
345
362
|
}));
|
|
346
|
-
if (visibleFullText || executionSteps.length > 0 ||
|
|
363
|
+
if (visibleFullText || executionSteps.length > 0 || executionReasoningText) {
|
|
347
364
|
const assistantMessage = {
|
|
348
365
|
id: generateId(),
|
|
349
366
|
role: "assistant",
|
|
350
367
|
content: visibleFullText,
|
|
351
|
-
toolCalls: toolCalls.filter((tc) => tc.status === "
|
|
368
|
+
toolCalls: toolCalls.filter((tc) => tc.status === "available"),
|
|
352
369
|
executionSteps: executionSteps.length > 0 ? executionSteps : void 0,
|
|
353
370
|
parts: parts.length > 0 ? parts : void 0,
|
|
354
|
-
|
|
371
|
+
reasoning: executionReasoningText || void 0,
|
|
355
372
|
createdAt: /* @__PURE__ */ new Date()
|
|
356
373
|
};
|
|
357
374
|
setMessages((prev) => [...prev, assistantMessage]);
|
|
@@ -361,12 +378,12 @@ function useOctavusChat(options) {
|
|
|
361
378
|
setStreamingText("");
|
|
362
379
|
setStreamingParts([]);
|
|
363
380
|
setExecutionBlocks([]);
|
|
364
|
-
|
|
381
|
+
setReasoningText("");
|
|
365
382
|
onDone?.();
|
|
366
383
|
break;
|
|
367
384
|
}
|
|
368
385
|
case "error":
|
|
369
|
-
throw new Error(event.
|
|
386
|
+
throw new Error(event.errorText);
|
|
370
387
|
case "tool-request":
|
|
371
388
|
break;
|
|
372
389
|
}
|
|
@@ -409,7 +426,7 @@ function useOctavusChat(options) {
|
|
|
409
426
|
streamingText,
|
|
410
427
|
streamingParts,
|
|
411
428
|
executionBlocks,
|
|
412
|
-
|
|
429
|
+
reasoningText
|
|
413
430
|
};
|
|
414
431
|
}
|
|
415
432
|
export {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hooks/use-octavus-chat.ts","../src/stream/reader.ts"],"sourcesContent":["'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { generateId, type ToolCallInfo, type DisplayMode, type MessagePart } from '@octavus/core';\nimport { parseSSEStream } from '@/stream/reader';\n\nexport interface ToolCallWithDescription extends ToolCallInfo {\n description?: string;\n display?: DisplayMode;\n}\n\nexport interface ExecutionStep {\n id: string;\n name: string;\n type: string;\n display: DisplayMode;\n description?: string;\n outputToChat: boolean;\n summary?: string;\n fullOutput?: string;\n toolCalls?: ToolCallWithDescription[];\n thread?: string;\n}\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n toolCalls?: ToolCallWithDescription[];\n executionSteps?: ExecutionStep[];\n /** If false, message is not shown to user (internal directive) */\n visible?: boolean;\n /** Ordered message parts - single source of truth for display */\n parts?: MessagePart[];\n thinking?: string;\n createdAt: Date;\n}\n\nexport type BlockStatus = 'pending' | 'running' | 'completed' | 'error';\n\nexport interface ExecutionBlock {\n id: string;\n name: string;\n type: string;\n status: BlockStatus;\n display: DisplayMode;\n description?: string;\n /** False for independent blocks */\n outputToChat: boolean;\n thread?: string;\n streamingText: string;\n summary?: string;\n thinking?: string;\n toolCalls: ToolCallWithDescription[];\n startedAt: Date;\n completedAt?: Date;\n}\n\nexport type ChatStatus = 'idle' | 'loading' | 'streaming' | 'error';\n\nexport type TriggerFunction = (\n triggerName: string,\n input?: Record<string, unknown>,\n) => Promise<Response>;\n\nexport interface UseOctavusChatOptions {\n onTrigger: TriggerFunction;\n initialMessages?: Message[];\n onMessage?: (message: Message) => void;\n onError?: (error: Error) => void;\n onDone?: () => void;\n onResourceUpdate?: (name: string, value: unknown) => void;\n onBlockStart?: (block: ExecutionBlock) => void;\n onBlockEnd?: (block: ExecutionBlock) => void;\n}\n\nexport interface UseOctavusChatReturn {\n messages: Message[];\n status: ChatStatus;\n isLoading: boolean;\n error: Error | null;\n /**\n * Add a user message to the UI state.\n * Does NOT trigger the agent - call triggerAction() after.\n */\n addUserMessage: (content: string) => void;\n triggerAction: (triggerName: string, input?: Record<string, unknown>) => Promise<void>;\n streamingText: string;\n /** Streaming parts in MessagePart format - single source of truth */\n streamingParts: MessagePart[];\n executionBlocks: ExecutionBlock[];\n thinkingText: string;\n}\n\ninterface ErrorResponse {\n error?: string;\n message?: string;\n}\n\nasync function parseErrorResponse(response: Response): Promise<string> {\n try {\n const data = (await response.json()) as ErrorResponse;\n return data.error ?? data.message ?? `Request failed: ${response.status}`;\n } catch {\n return `Request failed: ${response.status}`;\n }\n}\n\n/**\n * Helper to find or create a text part for the current block\n */\nfunction findOrCreateTextPart(\n parts: MessagePart[],\n thread: string | undefined,\n): { part: MessagePart; index: number } {\n // Look for an existing text part for this thread at the end\n for (let i = parts.length - 1; i >= 0; i--) {\n const part = parts[i];\n if (!part) continue;\n if (part.type === 'text' && part.thread === thread) {\n return { part, index: i };\n }\n // If we hit a different part type, stop looking\n if (part.type !== 'text') break;\n }\n // Create new text part\n const newPart: MessagePart = {\n type: 'text',\n visible: true,\n content: '',\n thread,\n };\n parts.push(newPart);\n return { part: newPart, index: parts.length - 1 };\n}\n\nexport function useOctavusChat(options: UseOctavusChatOptions): UseOctavusChatReturn {\n const {\n onTrigger,\n initialMessages = [],\n onMessage,\n onError,\n onDone,\n onResourceUpdate,\n onBlockStart,\n onBlockEnd,\n } = options;\n\n const [messages, setMessages] = useState<Message[]>(initialMessages);\n const [status, setStatus] = useState<ChatStatus>('idle');\n const [error, setError] = useState<Error | null>(null);\n const [streamingText, setStreamingText] = useState('');\n const [streamingParts, setStreamingParts] = useState<MessagePart[]>([]);\n const [executionBlocks, setExecutionBlocks] = useState<ExecutionBlock[]>([]);\n const [thinkingText, setThinkingText] = useState('');\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const triggerAction = useCallback(\n async (triggerName: string, input?: Record<string, unknown>) => {\n // Abort any previous request\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n setStatus('loading');\n setError(null);\n setStreamingText('');\n setStreamingParts([]);\n setExecutionBlocks([]);\n setThinkingText('');\n\n const blocks: ExecutionBlock[] = [];\n let activeBlock: ExecutionBlock | null = null;\n const toolCalls: ToolCallInfo[] = [];\n\n let visibleFullText = '';\n let executionThinkingText = '';\n\n // Track current thinking context (thread and whether to show)\n interface ThinkingContext {\n thread: string | undefined;\n outputToChat: boolean;\n partIndex: number;\n }\n const thinkingStack: ThinkingContext[] = [];\n const getCurrentThinking = () => thinkingStack[thinkingStack.length - 1];\n\n // Build MessagePart[] directly during streaming\n const parts: MessagePart[] = [];\n\n try {\n const response = await onTrigger(triggerName, input);\n\n if (!response.ok) {\n const errorMessage = await parseErrorResponse(response);\n throw new Error(errorMessage);\n }\n\n setStatus('streaming');\n\n for await (const event of parseSSEStream(response)) {\n if (abortController.signal.aborted) {\n break;\n }\n\n switch (event.type) {\n case 'block-start': {\n const newBlock: ExecutionBlock = {\n id: event.blockId,\n name: event.blockName,\n type: event.blockType,\n status: 'running',\n display: event.display,\n description: event.description,\n outputToChat: event.outputToChat ?? false,\n streamingText: '',\n toolCalls: [],\n startedAt: new Date(),\n };\n blocks.push(newBlock);\n activeBlock = newBlock;\n setExecutionBlocks([...blocks]);\n onBlockStart?.(newBlock);\n break;\n }\n\n case 'block-end': {\n if (activeBlock && activeBlock.id === event.blockId) {\n activeBlock.status = 'completed';\n activeBlock.summary = event.summary;\n activeBlock.completedAt = new Date();\n setExecutionBlocks([...blocks]);\n onBlockEnd?.(activeBlock);\n activeBlock = null;\n }\n break;\n }\n\n case 'text-delta':\n if (activeBlock) {\n activeBlock.streamingText += event.content;\n setExecutionBlocks([...blocks]);\n\n // Capture text if outputToChat OR non-main thread\n const isNonMainThread =\n activeBlock.thread !== undefined && activeBlock.thread !== 'main';\n const shouldCaptureText = activeBlock.outputToChat || isNonMainThread;\n\n if (shouldCaptureText) {\n // Find or create the text part and append content\n const { part, index } = findOrCreateTextPart(parts, activeBlock.thread);\n part.content = (part.content ?? '') + event.content;\n parts[index] = { ...part };\n\n // Update main visible text if outputToChat\n if (activeBlock.outputToChat) {\n visibleFullText += event.content;\n setStreamingText(visibleFullText);\n }\n\n setStreamingParts([...parts]);\n }\n }\n break;\n\n case 'text-start':\n case 'text-end':\n break;\n\n case 'thinking-start': {\n // Non-main threads always capture content (shown as orange cards)\n const isNonMainThread = event.thread !== undefined && event.thread !== 'main';\n const shouldCapture = (activeBlock?.outputToChat ?? false) || isNonMainThread;\n\n // Create new thinking part\n const newPart: MessagePart = {\n type: 'thinking',\n visible: false,\n content: '',\n thread: event.thread,\n };\n parts.push(newPart);\n\n // Push thinking context onto stack\n thinkingStack.push({\n thread: event.thread,\n outputToChat: shouldCapture,\n partIndex: parts.length - 1,\n });\n\n setThinkingText('');\n if (activeBlock && event.thread) {\n activeBlock.thread = event.thread;\n setExecutionBlocks([...blocks]);\n }\n break;\n }\n\n case 'thinking-delta': {\n const ctx = getCurrentThinking();\n const thinkingPart = ctx ? parts[ctx.partIndex] : undefined;\n if (ctx && thinkingPart) {\n thinkingPart.content = (thinkingPart.content ?? '') + event.content;\n parts[ctx.partIndex] = { ...thinkingPart };\n }\n\n if (activeBlock?.outputToChat) {\n executionThinkingText += event.content;\n }\n setThinkingText((prev) => prev + event.content);\n\n if (activeBlock) {\n activeBlock.thinking = (activeBlock.thinking ?? '') + event.content;\n if (event.thread && !activeBlock.thread) {\n activeBlock.thread = event.thread;\n }\n setExecutionBlocks([...blocks]);\n }\n\n // Update streaming parts if should capture\n if (ctx?.outputToChat) {\n setStreamingParts([...parts]);\n }\n break;\n }\n\n case 'thinking-end': {\n // Pop the thinking context from stack\n const ctx = thinkingStack.pop();\n setThinkingText('');\n\n // If the thinking part is empty, remove it\n const endThinkingPart = ctx ? parts[ctx.partIndex] : undefined;\n if (ctx && endThinkingPart && !endThinkingPart.content?.trim()) {\n parts.splice(ctx.partIndex, 1);\n }\n\n // Update streaming parts\n if (ctx?.outputToChat) {\n setStreamingParts([...parts]);\n }\n break;\n }\n\n case 'tool-call-start': {\n const newToolCall: ToolCallWithDescription = {\n id: event.toolCallId,\n name: event.toolName,\n arguments: {},\n status: 'in_progress',\n };\n if ('toolDescription' in event && event.toolDescription) {\n newToolCall.description = event.toolDescription;\n }\n if ('toolDisplay' in event && event.toolDisplay) {\n newToolCall.display = event.toolDisplay;\n }\n toolCalls.push(newToolCall);\n\n if (activeBlock) {\n activeBlock.toolCalls = [...activeBlock.toolCalls, newToolCall];\n setExecutionBlocks([...blocks]);\n }\n\n // Add tool call part (visible unless hidden)\n const isVisibleBlock = activeBlock?.display !== 'hidden';\n if (isVisibleBlock) {\n const toolPart: MessagePart = {\n type: 'tool-call',\n visible: newToolCall.display !== 'hidden',\n toolCall: newToolCall,\n thread: activeBlock?.thread,\n };\n parts.push(toolPart);\n setStreamingParts([...parts]);\n }\n break;\n }\n\n case 'tool-call-args': {\n const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);\n if (toolCall) {\n try {\n toolCall.arguments = JSON.parse(event.argsJson) as Record<string, unknown>;\n } catch {\n // Ignore parse errors for partial args\n }\n\n // Update the tool call in parts\n const argsPart = parts.find(\n (p) => p.type === 'tool-call' && p.toolCall?.id === event.toolCallId,\n );\n if (argsPart?.toolCall) {\n argsPart.toolCall = { ...argsPart.toolCall, arguments: toolCall.arguments };\n setStreamingParts([...parts]);\n }\n\n if (activeBlock) {\n setExecutionBlocks([...blocks]);\n }\n }\n break;\n }\n\n case 'tool-call-result': {\n const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);\n if (toolCall) {\n toolCall.status = 'completed';\n toolCall.result = event.result;\n\n // Update the tool call in parts\n const resultPart = parts.find(\n (p) => p.type === 'tool-call' && p.toolCall?.id === event.toolCallId,\n );\n if (resultPart?.toolCall) {\n resultPart.toolCall = {\n ...resultPart.toolCall,\n status: 'completed',\n result: event.result,\n };\n setStreamingParts([...parts]);\n }\n\n if (activeBlock) {\n setExecutionBlocks([...blocks]);\n }\n }\n break;\n }\n\n case 'tool-call-error': {\n const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);\n if (toolCall) {\n toolCall.status = 'error';\n toolCall.error = event.error;\n\n // Update the tool call in parts\n const errorPart = parts.find(\n (p) => p.type === 'tool-call' && p.toolCall?.id === event.toolCallId,\n );\n if (errorPart?.toolCall) {\n errorPart.toolCall = {\n ...errorPart.toolCall,\n status: 'error',\n error: event.error,\n };\n setStreamingParts([...parts]);\n }\n\n if (activeBlock) {\n setExecutionBlocks([...blocks]);\n }\n }\n break;\n }\n\n case 'resource-update':\n onResourceUpdate?.(event.name, event.value);\n break;\n\n case 'done': {\n // Finalize any remaining thinking contexts\n while (thinkingStack.length > 0) {\n const ctx = thinkingStack.pop();\n const remainingPart = ctx ? parts[ctx.partIndex] : undefined;\n if (ctx && remainingPart && !remainingPart.content?.trim()) {\n parts.splice(ctx.partIndex, 1);\n }\n }\n\n // Build execution steps\n const executionSteps: ExecutionStep[] = blocks\n .filter((b) => b.status === 'completed')\n .map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n display: b.display,\n description: b.description,\n outputToChat: b.outputToChat,\n summary: b.summary,\n fullOutput: b.streamingText || undefined,\n toolCalls: b.toolCalls.length > 0 ? b.toolCalls : undefined,\n thread: b.thread,\n }));\n\n // Create assistant message if we have any content\n if (visibleFullText || executionSteps.length > 0 || executionThinkingText) {\n const assistantMessage: Message = {\n id: generateId(),\n role: 'assistant',\n content: visibleFullText,\n toolCalls: toolCalls.filter((tc) => tc.status === 'completed'),\n executionSteps: executionSteps.length > 0 ? executionSteps : undefined,\n parts: parts.length > 0 ? parts : undefined,\n thinking: executionThinkingText || undefined,\n createdAt: new Date(),\n };\n setMessages((prev) => [...prev, assistantMessage]);\n onMessage?.(assistantMessage);\n }\n setStatus('idle');\n setStreamingText('');\n setStreamingParts([]);\n setExecutionBlocks([]);\n setThinkingText('');\n onDone?.();\n break;\n }\n\n case 'error':\n throw new Error(event.message);\n\n case 'tool-request':\n // Handled by server-sdk, should not reach client\n break;\n }\n }\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error('Unknown error');\n setError(errorObj);\n setStatus('error');\n\n if (activeBlock) {\n activeBlock.status = 'error';\n setExecutionBlocks([...blocks]);\n }\n\n onError?.(errorObj);\n } finally {\n abortControllerRef.current = null;\n }\n },\n [onTrigger, onMessage, onError, onDone, onResourceUpdate, onBlockStart, onBlockEnd],\n );\n\n const addUserMessage = useCallback(\n (content: string) => {\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content,\n createdAt: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n onMessage?.(userMessage);\n },\n [onMessage],\n );\n\n return {\n messages,\n status,\n isLoading: status === 'loading' || status === 'streaming',\n error,\n addUserMessage,\n triggerAction,\n streamingText,\n streamingParts,\n executionBlocks,\n thinkingText,\n };\n}\n","import { safeParseStreamEvent, type StreamEvent } from '@octavus/core';\n\n/**\n * Parse SSE stream events\n */\nexport async function* parseSSEStream(\n response: Response,\n): AsyncGenerator<StreamEvent, void, unknown> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is not readable');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n let reading = true;\n while (reading) {\n const { done, value } = await reader.read();\n\n if (done) {\n reading = false;\n continue;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n const parsed = safeParseStreamEvent(JSON.parse(line.slice(6)));\n if (parsed.success) {\n yield parsed.data;\n }\n // Skip malformed events silently\n } catch {\n // Skip malformed JSON - no logging in production\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/hooks/use-octavus-chat.ts","../src/stream/reader.ts"],"sourcesContent":["'use client';\n\nimport { useState, useCallback, useRef } from 'react';\nimport { generateId, type ToolCallInfo, type DisplayMode, type MessagePart } from '@octavus/core';\nimport { parseSSEStream } from '@/stream/reader';\n\nexport interface ToolCallWithDescription extends ToolCallInfo {\n description?: string;\n display?: DisplayMode;\n}\n\nexport interface ExecutionStep {\n id: string;\n name: string;\n type: string;\n display: DisplayMode;\n description?: string;\n outputToChat: boolean;\n summary?: string;\n fullOutput?: string;\n reasoning?: string;\n toolCalls?: ToolCallWithDescription[];\n thread?: string;\n}\n\nexport interface Message {\n id: string;\n role: 'user' | 'assistant' | 'system';\n content: string;\n toolCalls?: ToolCallWithDescription[];\n executionSteps?: ExecutionStep[];\n /** If false, message is not shown to user (internal directive) */\n visible?: boolean;\n /** Ordered message parts - single source of truth for display */\n parts?: MessagePart[];\n reasoning?: string;\n createdAt: Date;\n}\n\nexport type BlockStatus = 'pending' | 'running' | 'completed' | 'error';\n\nexport interface ExecutionBlock {\n id: string;\n name: string;\n type: string;\n status: BlockStatus;\n display: DisplayMode;\n description?: string;\n /** False for independent blocks */\n outputToChat: boolean;\n thread?: string;\n streamingText: string;\n summary?: string;\n reasoning?: string;\n toolCalls: ToolCallWithDescription[];\n startedAt: Date;\n completedAt?: Date;\n}\n\nexport type ChatStatus = 'idle' | 'loading' | 'streaming' | 'error';\n\nexport type TriggerFunction = (\n triggerName: string,\n input?: Record<string, unknown>,\n) => Promise<Response>;\n\nexport interface UseOctavusChatOptions {\n onTrigger: TriggerFunction;\n initialMessages?: Message[];\n onMessage?: (message: Message) => void;\n onError?: (error: Error) => void;\n onDone?: () => void;\n onResourceUpdate?: (name: string, value: unknown) => void;\n onBlockStart?: (block: ExecutionBlock) => void;\n onBlockEnd?: (block: ExecutionBlock) => void;\n}\n\nexport interface UseOctavusChatReturn {\n messages: Message[];\n status: ChatStatus;\n isLoading: boolean;\n error: Error | null;\n /**\n * Add a user message to the UI state.\n * Does NOT trigger the agent - call triggerAction() after.\n */\n addUserMessage: (content: string) => void;\n triggerAction: (triggerName: string, input?: Record<string, unknown>) => Promise<void>;\n streamingText: string;\n /** Streaming parts in MessagePart format - single source of truth */\n streamingParts: MessagePart[];\n executionBlocks: ExecutionBlock[];\n reasoningText: string;\n}\n\ninterface ErrorResponse {\n error?: string;\n message?: string;\n errorText?: string;\n}\n\nasync function parseErrorResponse(response: Response): Promise<string> {\n try {\n const data = (await response.json()) as ErrorResponse;\n return data.error ?? data.errorText ?? data.message ?? `Request failed: ${response.status}`;\n } catch {\n return `Request failed: ${response.status}`;\n }\n}\n\n/**\n * Helper to find or create a text part for the current block\n */\nfunction findOrCreateTextPart(\n parts: MessagePart[],\n thread: string | undefined,\n): { part: MessagePart; index: number } {\n // Look for an existing text part for this thread at the end\n for (let i = parts.length - 1; i >= 0; i--) {\n const part = parts[i];\n if (!part) continue;\n if (part.type === 'text' && part.thread === thread) {\n return { part, index: i };\n }\n // If we hit a different part type, stop looking\n if (part.type !== 'text') break;\n }\n // Create new text part\n const newPart: MessagePart = {\n type: 'text',\n visible: true,\n content: '',\n thread,\n };\n parts.push(newPart);\n return { part: newPart, index: parts.length - 1 };\n}\n\nexport function useOctavusChat(options: UseOctavusChatOptions): UseOctavusChatReturn {\n const {\n onTrigger,\n initialMessages = [],\n onMessage,\n onError,\n onDone,\n onResourceUpdate,\n onBlockStart,\n onBlockEnd,\n } = options;\n\n const [messages, setMessages] = useState<Message[]>(initialMessages);\n const [status, setStatus] = useState<ChatStatus>('idle');\n const [error, setError] = useState<Error | null>(null);\n const [streamingText, setStreamingText] = useState('');\n const [streamingParts, setStreamingParts] = useState<MessagePart[]>([]);\n const [executionBlocks, setExecutionBlocks] = useState<ExecutionBlock[]>([]);\n const [reasoningText, setReasoningText] = useState('');\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const triggerAction = useCallback(\n async (triggerName: string, input?: Record<string, unknown>) => {\n // Abort any previous request\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n\n const abortController = new AbortController();\n abortControllerRef.current = abortController;\n\n setStatus('loading');\n setError(null);\n setStreamingText('');\n setStreamingParts([]);\n setExecutionBlocks([]);\n setReasoningText('');\n\n const blocks: ExecutionBlock[] = [];\n let activeBlock: ExecutionBlock | null = null;\n const toolCalls: ToolCallInfo[] = [];\n\n let visibleFullText = '';\n let executionReasoningText = '';\n\n interface ReasoningContext {\n id: string;\n outputToChat: boolean;\n partIndex: number;\n }\n const reasoningStack: ReasoningContext[] = [];\n const getCurrentReasoning = () => reasoningStack[reasoningStack.length - 1];\n\n // Build MessagePart[] directly during streaming\n const parts: MessagePart[] = [];\n\n try {\n const response = await onTrigger(triggerName, input);\n\n if (!response.ok) {\n const errorMessage = await parseErrorResponse(response);\n throw new Error(errorMessage);\n }\n\n setStatus('streaming');\n\n for await (const event of parseSSEStream(response)) {\n if (abortController.signal.aborted) {\n break;\n }\n\n switch (event.type) {\n case 'start':\n break;\n\n case 'block-start': {\n const newBlock: ExecutionBlock = {\n id: event.blockId,\n name: event.blockName,\n type: event.blockType,\n status: 'running',\n display: event.display,\n description: event.description,\n outputToChat: event.outputToChat ?? false,\n thread: event.thread,\n streamingText: '',\n toolCalls: [],\n startedAt: new Date(),\n };\n blocks.push(newBlock);\n activeBlock = newBlock;\n setExecutionBlocks([...blocks]);\n onBlockStart?.(newBlock);\n break;\n }\n\n case 'block-end': {\n if (activeBlock && activeBlock.id === event.blockId) {\n activeBlock.status = 'completed';\n activeBlock.summary = event.summary;\n activeBlock.completedAt = new Date();\n setExecutionBlocks([...blocks]);\n onBlockEnd?.(activeBlock);\n activeBlock = null;\n }\n break;\n }\n\n case 'text-delta':\n if (activeBlock) {\n activeBlock.streamingText += event.delta;\n setExecutionBlocks([...blocks]);\n\n // Capture text if outputToChat OR non-main thread\n const isNonMainThread =\n activeBlock.thread !== undefined && activeBlock.thread !== 'main';\n const shouldCaptureText = activeBlock.outputToChat || isNonMainThread;\n\n if (shouldCaptureText) {\n const { part, index } = findOrCreateTextPart(parts, activeBlock.thread);\n part.content = (part.content ?? '') + event.delta;\n parts[index] = { ...part };\n\n if (activeBlock.outputToChat) {\n visibleFullText += event.delta;\n setStreamingText(visibleFullText);\n }\n\n setStreamingParts([...parts]);\n }\n }\n break;\n\n case 'text-start':\n case 'text-end':\n break;\n\n case 'reasoning-start': {\n // Non-main threads always capture content (shown as orange cards)\n const isNonMainThread =\n activeBlock?.thread !== undefined && activeBlock.thread !== 'main';\n const shouldCapture = (activeBlock?.outputToChat ?? false) || isNonMainThread;\n\n const newPart: MessagePart = {\n type: 'reasoning',\n visible: false,\n content: '',\n thread: activeBlock?.thread,\n };\n parts.push(newPart);\n\n reasoningStack.push({\n id: event.id,\n outputToChat: shouldCapture,\n partIndex: parts.length - 1,\n });\n\n setReasoningText('');\n break;\n }\n\n case 'reasoning-delta': {\n const ctx = getCurrentReasoning();\n const reasoningPart = ctx ? parts[ctx.partIndex] : undefined;\n if (ctx && reasoningPart) {\n reasoningPart.content = (reasoningPart.content ?? '') + event.delta;\n parts[ctx.partIndex] = { ...reasoningPart };\n }\n\n if (activeBlock?.outputToChat) {\n executionReasoningText += event.delta;\n }\n setReasoningText((prev) => prev + event.delta);\n\n if (activeBlock) {\n activeBlock.reasoning = (activeBlock.reasoning ?? '') + event.delta;\n setExecutionBlocks([...blocks]);\n }\n\n if (ctx?.outputToChat) {\n setStreamingParts([...parts]);\n }\n break;\n }\n\n case 'reasoning-end': {\n const ctx = reasoningStack.pop();\n setReasoningText('');\n\n const endReasoningPart = ctx ? parts[ctx.partIndex] : undefined;\n if (ctx && endReasoningPart && !endReasoningPart.content?.trim()) {\n parts.splice(ctx.partIndex, 1);\n }\n\n // Update streaming parts\n if (ctx?.outputToChat) {\n setStreamingParts([...parts]);\n }\n break;\n }\n\n case 'tool-input-start': {\n const newToolCall: ToolCallWithDescription = {\n id: event.toolCallId,\n name: event.toolName,\n arguments: {},\n status: 'streaming',\n description: event.title,\n };\n toolCalls.push(newToolCall);\n\n if (activeBlock) {\n activeBlock.toolCalls = [...activeBlock.toolCalls, newToolCall];\n setExecutionBlocks([...blocks]);\n }\n\n // Add tool call part (visible unless hidden block)\n const isVisibleBlock = activeBlock?.display !== 'hidden';\n if (isVisibleBlock) {\n const toolPart: MessagePart = {\n type: 'tool-call',\n visible: true,\n toolCall: newToolCall,\n thread: activeBlock?.thread,\n };\n parts.push(toolPart);\n setStreamingParts([...parts]);\n }\n break;\n }\n\n case 'tool-input-delta': {\n const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);\n if (toolCall) {\n try {\n toolCall.arguments = JSON.parse(event.inputTextDelta) as Record<string, unknown>;\n } catch {\n // Partial args may not be valid JSON yet\n }\n\n const argsPart = parts.find(\n (p) => p.type === 'tool-call' && p.toolCall?.id === event.toolCallId,\n );\n if (argsPart?.toolCall) {\n argsPart.toolCall = { ...argsPart.toolCall, arguments: toolCall.arguments };\n setStreamingParts([...parts]);\n }\n\n if (activeBlock) {\n setExecutionBlocks([...blocks]);\n }\n }\n break;\n }\n\n case 'tool-input-end': {\n // Tool input streaming has ended - no action needed\n // The full input is available in tool-input-available\n break;\n }\n\n case 'tool-input-available': {\n const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);\n if (toolCall) {\n toolCall.arguments = event.input as Record<string, unknown>;\n toolCall.status = 'available';\n\n const inputPart = parts.find(\n (p) => p.type === 'tool-call' && p.toolCall?.id === event.toolCallId,\n );\n if (inputPart?.toolCall) {\n inputPart.toolCall = {\n ...inputPart.toolCall,\n arguments: toolCall.arguments,\n status: 'available',\n };\n setStreamingParts([...parts]);\n }\n\n if (activeBlock) {\n setExecutionBlocks([...blocks]);\n }\n }\n break;\n }\n\n case 'tool-output-available': {\n const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);\n if (toolCall) {\n toolCall.status = 'available';\n toolCall.result = event.output;\n\n const resultPart = parts.find(\n (p) => p.type === 'tool-call' && p.toolCall?.id === event.toolCallId,\n );\n if (resultPart?.toolCall) {\n resultPart.toolCall = {\n ...resultPart.toolCall,\n status: 'available',\n result: event.output,\n };\n setStreamingParts([...parts]);\n }\n\n if (activeBlock) {\n setExecutionBlocks([...blocks]);\n }\n }\n break;\n }\n\n case 'tool-output-error': {\n const toolCall = toolCalls.find((tc) => tc.id === event.toolCallId);\n if (toolCall) {\n toolCall.status = 'error';\n toolCall.error = event.errorText;\n\n const errorPart = parts.find(\n (p) => p.type === 'tool-call' && p.toolCall?.id === event.toolCallId,\n );\n if (errorPart?.toolCall) {\n errorPart.toolCall = {\n ...errorPart.toolCall,\n status: 'error',\n error: event.errorText,\n };\n setStreamingParts([...parts]);\n }\n\n if (activeBlock) {\n setExecutionBlocks([...blocks]);\n }\n }\n break;\n }\n\n case 'resource-update':\n onResourceUpdate?.(event.name, event.value);\n break;\n\n case 'finish': {\n while (reasoningStack.length > 0) {\n const ctx = reasoningStack.pop();\n const remainingPart = ctx ? parts[ctx.partIndex] : undefined;\n if (ctx && remainingPart && !remainingPart.content?.trim()) {\n parts.splice(ctx.partIndex, 1);\n }\n }\n\n const executionSteps: ExecutionStep[] = blocks\n .filter((b) => b.status === 'completed')\n .map((b) => ({\n id: b.id,\n name: b.name,\n type: b.type,\n display: b.display,\n description: b.description,\n outputToChat: b.outputToChat,\n summary: b.summary,\n fullOutput: b.streamingText || undefined,\n reasoning: b.reasoning || undefined,\n toolCalls: b.toolCalls.length > 0 ? b.toolCalls : undefined,\n thread: b.thread,\n }));\n\n if (visibleFullText || executionSteps.length > 0 || executionReasoningText) {\n const assistantMessage: Message = {\n id: generateId(),\n role: 'assistant',\n content: visibleFullText,\n toolCalls: toolCalls.filter((tc) => tc.status === 'available'),\n executionSteps: executionSteps.length > 0 ? executionSteps : undefined,\n parts: parts.length > 0 ? parts : undefined,\n reasoning: executionReasoningText || undefined,\n createdAt: new Date(),\n };\n setMessages((prev) => [...prev, assistantMessage]);\n onMessage?.(assistantMessage);\n }\n setStatus('idle');\n setStreamingText('');\n setStreamingParts([]);\n setExecutionBlocks([]);\n setReasoningText('');\n onDone?.();\n break;\n }\n\n case 'error':\n throw new Error(event.errorText);\n\n case 'tool-request':\n // Handled by server-sdk, should not reach client\n break;\n }\n }\n } catch (err) {\n const errorObj = err instanceof Error ? err : new Error('Unknown error');\n setError(errorObj);\n setStatus('error');\n\n if (activeBlock) {\n activeBlock.status = 'error';\n setExecutionBlocks([...blocks]);\n }\n\n onError?.(errorObj);\n } finally {\n abortControllerRef.current = null;\n }\n },\n [onTrigger, onMessage, onError, onDone, onResourceUpdate, onBlockStart, onBlockEnd],\n );\n\n const addUserMessage = useCallback(\n (content: string) => {\n const userMessage: Message = {\n id: generateId(),\n role: 'user',\n content,\n createdAt: new Date(),\n };\n setMessages((prev) => [...prev, userMessage]);\n onMessage?.(userMessage);\n },\n [onMessage],\n );\n\n return {\n messages,\n status,\n isLoading: status === 'loading' || status === 'streaming',\n error,\n addUserMessage,\n triggerAction,\n streamingText,\n streamingParts,\n executionBlocks,\n reasoningText,\n };\n}\n","import { safeParseStreamEvent, type StreamEvent } from '@octavus/core';\n\n/**\n * Parse SSE stream events\n */\nexport async function* parseSSEStream(\n response: Response,\n): AsyncGenerator<StreamEvent, void, unknown> {\n const reader = response.body?.getReader();\n if (!reader) {\n throw new Error('Response body is not readable');\n }\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n try {\n let reading = true;\n while (reading) {\n const { done, value } = await reader.read();\n\n if (done) {\n reading = false;\n continue;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (line.startsWith('data: ') && line !== 'data: [DONE]') {\n try {\n const parsed = safeParseStreamEvent(JSON.parse(line.slice(6)));\n if (parsed.success) {\n yield parsed.data;\n }\n // Skip malformed events silently\n } catch {\n // Skip malformed JSON - no logging in production\n }\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octavus/client-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Client SDK for streaming Octavus agent responses",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Octavus AI <hello@octavus.ai>",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@octavus/core": "^0.0.
|
|
32
|
+
"@octavus/core": "^0.0.3"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": ">=18.0.0"
|