@octavus/client-sdk 1.0.0 → 2.1.0
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/README.md +6 -6
- package/dist/index.d.ts +168 -22
- package/dist/index.js +442 -25
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,11 +21,11 @@ import { OctavusChat, createHttpTransport } from '@octavus/client-sdk';
|
|
|
21
21
|
|
|
22
22
|
// Create transport
|
|
23
23
|
const transport = createHttpTransport({
|
|
24
|
-
|
|
25
|
-
fetch('/api/
|
|
24
|
+
request: (payload, options) =>
|
|
25
|
+
fetch('/api/trigger', {
|
|
26
26
|
method: 'POST',
|
|
27
27
|
headers: { 'Content-Type': 'application/json' },
|
|
28
|
-
body: JSON.stringify({ sessionId,
|
|
28
|
+
body: JSON.stringify({ sessionId, ...payload }),
|
|
29
29
|
signal: options?.signal,
|
|
30
30
|
}),
|
|
31
31
|
});
|
|
@@ -56,11 +56,11 @@ Best for Next.js, Express, and HTTP-based applications:
|
|
|
56
56
|
import { createHttpTransport } from '@octavus/client-sdk';
|
|
57
57
|
|
|
58
58
|
const transport = createHttpTransport({
|
|
59
|
-
|
|
60
|
-
fetch('/api/
|
|
59
|
+
request: (payload, options) =>
|
|
60
|
+
fetch('/api/trigger', {
|
|
61
61
|
method: 'POST',
|
|
62
62
|
headers: { 'Content-Type': 'application/json' },
|
|
63
|
-
body: JSON.stringify({ sessionId,
|
|
63
|
+
body: JSON.stringify({ sessionId, ...payload }),
|
|
64
64
|
signal: options?.signal,
|
|
65
65
|
}),
|
|
66
66
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { StreamEvent, FileReference, UIMessage, OctavusError } from '@octavus/core';
|
|
1
|
+
import { StreamEvent, ToolResult, FileReference, UIMessage, OctavusError } from '@octavus/core';
|
|
2
2
|
export * from '@octavus/core';
|
|
3
|
+
export { AppError, ConflictError, ForbiddenError, MAIN_THREAD, NotFoundError, OCTAVUS_SKILL_TOOLS, OctavusError, ValidationError, createApiErrorEvent, createErrorEvent, createInternalErrorEvent, errorToStreamEvent, generateId, getSkillSlugFromToolCall, isAbortError, isAuthenticationError, isFileReference, isFileReferenceArray, isMainThread, isOctavusSkillTool, isOtherThread, isProviderError, isRateLimitError, isRetryableError, isToolError, isValidationError, resolveThread, safeParseStreamEvent, safeParseUIMessage, safeParseUIMessages, threadForPart } from '@octavus/core';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Transport interface for delivering events from server to client.
|
|
@@ -15,6 +16,13 @@ interface Transport {
|
|
|
15
16
|
* @param input - Input parameters for variable substitution
|
|
16
17
|
*/
|
|
17
18
|
trigger(triggerName: string, input?: Record<string, unknown>): AsyncIterable<StreamEvent>;
|
|
19
|
+
/**
|
|
20
|
+
* Continue execution with tool results after client-side tool handling.
|
|
21
|
+
*
|
|
22
|
+
* @param executionId - The execution ID from the client-tool-request event
|
|
23
|
+
* @param results - All tool results (server + client) to send
|
|
24
|
+
*/
|
|
25
|
+
continueWithToolResults(executionId: string, results: ToolResult[]): AsyncIterable<StreamEvent>;
|
|
18
26
|
/** Stop the current stream. Safe to call when no stream is active. */
|
|
19
27
|
stop(): void;
|
|
20
28
|
}
|
|
@@ -190,7 +198,51 @@ interface UploadFilesOptions {
|
|
|
190
198
|
*/
|
|
191
199
|
declare function uploadFiles(files: FileList | File[], options: UploadFilesOptions): Promise<FileReference[]>;
|
|
192
200
|
|
|
193
|
-
type ChatStatus = 'idle' | 'streaming' | 'error';
|
|
201
|
+
type ChatStatus = 'idle' | 'streaming' | 'error' | 'awaiting-input';
|
|
202
|
+
/**
|
|
203
|
+
* Context provided to client tool handlers.
|
|
204
|
+
*/
|
|
205
|
+
interface ClientToolContext {
|
|
206
|
+
/** Unique identifier for this tool call */
|
|
207
|
+
toolCallId: string;
|
|
208
|
+
/** Name of the tool being called */
|
|
209
|
+
toolName: string;
|
|
210
|
+
/** Signal for cancellation if user stops generation */
|
|
211
|
+
signal: AbortSignal;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Handler function for client-side tool execution.
|
|
215
|
+
* Can be:
|
|
216
|
+
* - An async function that executes automatically and returns a result
|
|
217
|
+
* - The string 'interactive' to indicate the tool requires user interaction
|
|
218
|
+
*/
|
|
219
|
+
type ClientToolHandler = ((args: Record<string, unknown>, ctx: ClientToolContext) => Promise<unknown>) | 'interactive';
|
|
220
|
+
/**
|
|
221
|
+
* Interactive tool call awaiting user interaction.
|
|
222
|
+
* The `submit` and `cancel` methods are pre-bound to this tool call's ID.
|
|
223
|
+
*/
|
|
224
|
+
interface InteractiveTool {
|
|
225
|
+
/** Unique identifier for this tool call */
|
|
226
|
+
toolCallId: string;
|
|
227
|
+
/** Name of the tool being called */
|
|
228
|
+
toolName: string;
|
|
229
|
+
/** Arguments passed to the tool */
|
|
230
|
+
args: Record<string, unknown>;
|
|
231
|
+
/**
|
|
232
|
+
* Submit a result for this tool call.
|
|
233
|
+
* Call this when the user has provided input.
|
|
234
|
+
*
|
|
235
|
+
* @param result - The result from user interaction
|
|
236
|
+
*/
|
|
237
|
+
submit: (result: unknown) => void;
|
|
238
|
+
/**
|
|
239
|
+
* Cancel this tool call with an optional reason.
|
|
240
|
+
* Call this when the user dismisses the UI without providing input.
|
|
241
|
+
*
|
|
242
|
+
* @param reason - Optional reason for cancellation (default: 'User cancelled')
|
|
243
|
+
*/
|
|
244
|
+
cancel: (reason?: string) => void;
|
|
245
|
+
}
|
|
194
246
|
/**
|
|
195
247
|
* Input for creating a user message.
|
|
196
248
|
* Supports text content, structured object content, and file attachments.
|
|
@@ -233,6 +285,35 @@ interface OctavusChatOptions {
|
|
|
233
285
|
* ```
|
|
234
286
|
*/
|
|
235
287
|
requestUploadUrls?: UploadFilesOptions['requestUploadUrls'];
|
|
288
|
+
/**
|
|
289
|
+
* Client-side tool handlers.
|
|
290
|
+
* Register handlers for tools that should execute in the browser.
|
|
291
|
+
*
|
|
292
|
+
* - If a tool has a handler function: executes automatically
|
|
293
|
+
* - If a tool is marked as 'interactive': appears in `pendingClientTools` with bound `submit()`/`cancel()`
|
|
294
|
+
*
|
|
295
|
+
* @example Automatic client tool
|
|
296
|
+
* ```typescript
|
|
297
|
+
* clientTools: {
|
|
298
|
+
* 'get-browser-location': async () => {
|
|
299
|
+
* const pos = await new Promise((resolve, reject) => {
|
|
300
|
+
* navigator.geolocation.getCurrentPosition(resolve, reject);
|
|
301
|
+
* });
|
|
302
|
+
* return { lat: pos.coords.latitude, lng: pos.coords.longitude };
|
|
303
|
+
* },
|
|
304
|
+
* }
|
|
305
|
+
* ```
|
|
306
|
+
*
|
|
307
|
+
* @example Interactive client tool (user input required)
|
|
308
|
+
* ```typescript
|
|
309
|
+
* clientTools: {
|
|
310
|
+
* 'request-feedback': 'interactive',
|
|
311
|
+
* }
|
|
312
|
+
* // Then render UI based on pendingClientTools['request-feedback']
|
|
313
|
+
* // and call tool.submit(result) or tool.cancel()
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
clientTools?: Record<string, ClientToolHandler>;
|
|
236
317
|
/** Initial messages (for session refresh) */
|
|
237
318
|
initialMessages?: UIMessage[];
|
|
238
319
|
/**
|
|
@@ -275,10 +356,12 @@ type Listener = () => void;
|
|
|
275
356
|
*
|
|
276
357
|
* const chat = new OctavusChat({
|
|
277
358
|
* transport: createHttpTransport({
|
|
278
|
-
*
|
|
359
|
+
* request: (payload, options) =>
|
|
279
360
|
* fetch('/api/trigger', {
|
|
280
361
|
* method: 'POST',
|
|
281
|
-
*
|
|
362
|
+
* headers: { 'Content-Type': 'application/json' },
|
|
363
|
+
* body: JSON.stringify({ sessionId, ...payload }),
|
|
364
|
+
* signal: options?.signal,
|
|
282
365
|
* }),
|
|
283
366
|
* }),
|
|
284
367
|
* });
|
|
@@ -306,6 +389,14 @@ declare class OctavusChat {
|
|
|
306
389
|
private options;
|
|
307
390
|
private transport;
|
|
308
391
|
private streamingState;
|
|
392
|
+
private _pendingToolsByName;
|
|
393
|
+
private _pendingToolsByCallId;
|
|
394
|
+
private _pendingClientToolsCache;
|
|
395
|
+
private _completedToolResults;
|
|
396
|
+
private _clientToolAbortController;
|
|
397
|
+
private _serverToolResults;
|
|
398
|
+
private _pendingExecutionId;
|
|
399
|
+
private _readyToContinue;
|
|
309
400
|
private listeners;
|
|
310
401
|
constructor(options: OctavusChatOptions);
|
|
311
402
|
get messages(): UIMessage[];
|
|
@@ -315,6 +406,25 @@ declare class OctavusChat {
|
|
|
315
406
|
* Contains structured error information including type, source, and retryability.
|
|
316
407
|
*/
|
|
317
408
|
get error(): OctavusError | null;
|
|
409
|
+
/**
|
|
410
|
+
* Pending interactive tool calls keyed by tool name.
|
|
411
|
+
* Each tool has bound `submit()` and `cancel()` methods.
|
|
412
|
+
*
|
|
413
|
+
* @example
|
|
414
|
+
* ```tsx
|
|
415
|
+
* const feedbackTools = pendingClientTools['request-feedback'] ?? [];
|
|
416
|
+
*
|
|
417
|
+
* {feedbackTools.map(tool => (
|
|
418
|
+
* <FeedbackModal
|
|
419
|
+
* key={tool.toolCallId}
|
|
420
|
+
* {...tool.args}
|
|
421
|
+
* onSubmit={(result) => tool.submit(result)}
|
|
422
|
+
* onCancel={() => tool.cancel()}
|
|
423
|
+
* />
|
|
424
|
+
* ))}
|
|
425
|
+
* ```
|
|
426
|
+
*/
|
|
427
|
+
get pendingClientTools(): Record<string, InteractiveTool[]>;
|
|
318
428
|
/**
|
|
319
429
|
* Subscribe to state changes. The callback is called whenever messages, status, or error changes.
|
|
320
430
|
* @returns Unsubscribe function
|
|
@@ -324,6 +434,7 @@ declare class OctavusChat {
|
|
|
324
434
|
private setMessages;
|
|
325
435
|
private setStatus;
|
|
326
436
|
private setError;
|
|
437
|
+
private updatePendingClientToolsCache;
|
|
327
438
|
/**
|
|
328
439
|
* Trigger the agent and optionally add a user message to the chat.
|
|
329
440
|
*
|
|
@@ -368,10 +479,34 @@ declare class OctavusChat {
|
|
|
368
479
|
* ```
|
|
369
480
|
*/
|
|
370
481
|
uploadFiles(files: FileList | File[], onProgress?: (fileIndex: number, progress: number) => void): Promise<FileReference[]>;
|
|
482
|
+
/**
|
|
483
|
+
* Internal: Submit a result for a pending tool.
|
|
484
|
+
* Called by bound submit/cancel methods on InteractiveTool.
|
|
485
|
+
*/
|
|
486
|
+
private submitToolResult;
|
|
371
487
|
/** Stop the current streaming and finalize any partial message */
|
|
372
488
|
stop(): void;
|
|
373
489
|
private handleStreamEvent;
|
|
374
490
|
private updateStreamingMessage;
|
|
491
|
+
/**
|
|
492
|
+
* Emit a tool-output-available event for a client tool result.
|
|
493
|
+
*/
|
|
494
|
+
private emitToolOutputAvailable;
|
|
495
|
+
/**
|
|
496
|
+
* Emit a tool-output-error event for a client tool result.
|
|
497
|
+
*/
|
|
498
|
+
private emitToolOutputError;
|
|
499
|
+
/**
|
|
500
|
+
* Continue execution with collected client tool results.
|
|
501
|
+
*/
|
|
502
|
+
private continueWithClientToolResults;
|
|
503
|
+
/**
|
|
504
|
+
* Handle client tool request event.
|
|
505
|
+
*
|
|
506
|
+
* IMPORTANT: Interactive tools must be registered synchronously (before any await)
|
|
507
|
+
* to avoid a race condition where the finish event is processed before tools are added.
|
|
508
|
+
*/
|
|
509
|
+
private handleClientToolRequest;
|
|
375
510
|
}
|
|
376
511
|
|
|
377
512
|
/**
|
|
@@ -382,10 +517,22 @@ declare class OctavusChat {
|
|
|
382
517
|
*/
|
|
383
518
|
declare function parseSSEStream(response: Response, signal?: AbortSignal): AsyncGenerator<StreamEvent, void, unknown>;
|
|
384
519
|
|
|
385
|
-
/**
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
520
|
+
/** Start a new trigger execution */
|
|
521
|
+
interface TriggerRequest {
|
|
522
|
+
type: 'trigger';
|
|
523
|
+
triggerName: string;
|
|
524
|
+
input?: Record<string, unknown>;
|
|
525
|
+
}
|
|
526
|
+
/** Continue execution after client-side tool handling */
|
|
527
|
+
interface ContinueRequest {
|
|
528
|
+
type: 'continue';
|
|
529
|
+
executionId: string;
|
|
530
|
+
toolResults: ToolResult[];
|
|
531
|
+
}
|
|
532
|
+
/** All request types supported by the HTTP transport */
|
|
533
|
+
type HttpRequest = TriggerRequest | ContinueRequest;
|
|
534
|
+
/** Request options passed to the request callback */
|
|
535
|
+
interface HttpRequestOptions {
|
|
389
536
|
/** Abort signal to cancel the request */
|
|
390
537
|
signal?: AbortSignal;
|
|
391
538
|
}
|
|
@@ -394,26 +541,25 @@ interface TriggerRequestOptions {
|
|
|
394
541
|
*/
|
|
395
542
|
interface HttpTransportOptions {
|
|
396
543
|
/**
|
|
397
|
-
* Function to make
|
|
398
|
-
*
|
|
544
|
+
* Function to make requests to your backend.
|
|
545
|
+
* Receives a discriminated union with `type` to identify the request kind.
|
|
399
546
|
*
|
|
400
|
-
* @param
|
|
401
|
-
* @param
|
|
402
|
-
* @param options - Optional request options including abort signal
|
|
547
|
+
* @param request - The request payload (check `request.type` for the kind)
|
|
548
|
+
* @param options - Request options including abort signal
|
|
403
549
|
* @returns Response with SSE stream body
|
|
404
550
|
*
|
|
405
551
|
* @example
|
|
406
552
|
* ```typescript
|
|
407
|
-
*
|
|
408
|
-
* fetch('/api/
|
|
553
|
+
* request: (payload, options) =>
|
|
554
|
+
* fetch('/api/trigger', {
|
|
409
555
|
* method: 'POST',
|
|
410
556
|
* headers: { 'Content-Type': 'application/json' },
|
|
411
|
-
* body: JSON.stringify({ sessionId,
|
|
557
|
+
* body: JSON.stringify({ sessionId, ...payload }),
|
|
412
558
|
* signal: options?.signal,
|
|
413
|
-
* })
|
|
559
|
+
* })
|
|
414
560
|
* ```
|
|
415
561
|
*/
|
|
416
|
-
|
|
562
|
+
request: (request: HttpRequest, options?: HttpRequestOptions) => Promise<Response>;
|
|
417
563
|
}
|
|
418
564
|
/**
|
|
419
565
|
* Create an HTTP transport using native fetch() and SSE parsing.
|
|
@@ -422,11 +568,11 @@ interface HttpTransportOptions {
|
|
|
422
568
|
* @example
|
|
423
569
|
* ```typescript
|
|
424
570
|
* const transport = createHttpTransport({
|
|
425
|
-
*
|
|
426
|
-
* fetch('/api/
|
|
571
|
+
* request: (payload, options) =>
|
|
572
|
+
* fetch('/api/trigger', {
|
|
427
573
|
* method: 'POST',
|
|
428
574
|
* headers: { 'Content-Type': 'application/json' },
|
|
429
|
-
* body: JSON.stringify({ sessionId,
|
|
575
|
+
* body: JSON.stringify({ sessionId, ...payload }),
|
|
430
576
|
* signal: options?.signal,
|
|
431
577
|
* }),
|
|
432
578
|
* });
|
|
@@ -552,4 +698,4 @@ interface SocketTransportOptions {
|
|
|
552
698
|
*/
|
|
553
699
|
declare function createSocketTransport(options: SocketTransportOptions): SocketTransport;
|
|
554
700
|
|
|
555
|
-
export { type ChatStatus, type ConnectionState, type ConnectionStateListener, type HttpTransportOptions, OctavusChat, type OctavusChatOptions, type SocketLike, type SocketTransport, type SocketTransportOptions, type Transport, type
|
|
701
|
+
export { type ChatStatus, type ClientToolContext, type ClientToolHandler, type ConnectionState, type ConnectionStateListener, type ContinueRequest, type HttpRequest, type HttpRequestOptions, type HttpTransportOptions, type InteractiveTool, OctavusChat, type OctavusChatOptions, type SocketLike, type SocketTransport, type SocketTransportOptions, type Transport, type TriggerRequest, type UploadFilesOptions, type UploadUrlsResponse, type UserMessageInput, createHttpTransport, createSocketTransport, isSocketTransport, parseSSEStream, uploadFiles };
|