@octavus/server-sdk 2.19.0 → 2.20.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/dist/index.cjs +1109 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +552 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +32 -12
- package/dist/index.js.map +1 -1
- package/package.json +12 -5
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
import { ZodType, z } from 'zod';
|
|
2
|
+
import { ToolHandlers, ToolSchema, ToolResult, StreamEvent, ChatMessage, UIMessage, ToolProvider } from '@octavus/core';
|
|
3
|
+
export * from '@octavus/core';
|
|
4
|
+
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';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Error thrown when API request fails
|
|
8
|
+
*/
|
|
9
|
+
declare class ApiError extends Error {
|
|
10
|
+
status: number;
|
|
11
|
+
code?: string | undefined;
|
|
12
|
+
constructor(message: string, status: number, code?: string | undefined);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface ApiClientConfig {
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
getHeaders: () => Record<string, string>;
|
|
18
|
+
}
|
|
19
|
+
/** Base class for API clients with shared HTTP utilities */
|
|
20
|
+
declare abstract class BaseApiClient {
|
|
21
|
+
protected readonly config: ApiClientConfig;
|
|
22
|
+
constructor(config: ApiClientConfig);
|
|
23
|
+
protected httpGet<T>(path: string, schema: ZodType<T>): Promise<T>;
|
|
24
|
+
protected httpPost<T>(path: string, body: unknown, schema: ZodType<T>): Promise<T>;
|
|
25
|
+
protected httpPatch<T>(path: string, body: unknown, schema: ZodType<T>): Promise<T>;
|
|
26
|
+
protected httpDelete<T>(path: string, schema: ZodType<T>): Promise<T>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Agent format - interactive (chat) or worker (background task) */
|
|
30
|
+
type AgentFormat = 'interactive' | 'worker';
|
|
31
|
+
/** Agent settings */
|
|
32
|
+
interface AgentSettings {
|
|
33
|
+
slug: string;
|
|
34
|
+
name: string;
|
|
35
|
+
description?: string;
|
|
36
|
+
format: AgentFormat;
|
|
37
|
+
}
|
|
38
|
+
/** Agent prompt */
|
|
39
|
+
interface AgentPrompt {
|
|
40
|
+
name: string;
|
|
41
|
+
content: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Agent summary returned from list endpoint
|
|
45
|
+
*/
|
|
46
|
+
interface Agent {
|
|
47
|
+
/** Agent slug (human-readable identifier within project) */
|
|
48
|
+
slug: string;
|
|
49
|
+
/** Agent ID - use this for API calls */
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
description: string | null;
|
|
53
|
+
format: AgentFormat;
|
|
54
|
+
createdAt: string;
|
|
55
|
+
updatedAt: string;
|
|
56
|
+
projectId: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Full agent definition returned from get endpoint
|
|
60
|
+
*/
|
|
61
|
+
interface AgentDefinition {
|
|
62
|
+
settings: AgentSettings;
|
|
63
|
+
protocol: string;
|
|
64
|
+
prompts: AgentPrompt[];
|
|
65
|
+
/** Agent ID - use this for API calls like createSession */
|
|
66
|
+
id: string;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* API for listing and retrieving agent definitions.
|
|
71
|
+
*
|
|
72
|
+
* Note: Agent management (create, update, sync) should be done via the @octavus/cli package.
|
|
73
|
+
* This API uses agent IDs only - use CLI for slug-based operations.
|
|
74
|
+
*/
|
|
75
|
+
declare class AgentsApi extends BaseApiClient {
|
|
76
|
+
/** List all agents in the project */
|
|
77
|
+
list(): Promise<Agent[]>;
|
|
78
|
+
/** Get a single agent by ID */
|
|
79
|
+
get(agentId: string): Promise<AgentDefinition>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Base class for agent-managed resources.
|
|
84
|
+
* Extend this class to define how each resource should be persisted when the agent updates it.
|
|
85
|
+
*/
|
|
86
|
+
declare abstract class Resource {
|
|
87
|
+
/** The resource name as defined in the agent protocol */
|
|
88
|
+
abstract readonly name: string;
|
|
89
|
+
/** Called when the agent updates this resource */
|
|
90
|
+
abstract onUpdate(value: unknown): Promise<void> | void;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Start a new trigger execution */
|
|
94
|
+
interface TriggerRequest {
|
|
95
|
+
type: 'trigger';
|
|
96
|
+
triggerName: string;
|
|
97
|
+
input?: Record<string, unknown>;
|
|
98
|
+
/** ID of the last message to keep. Messages after this are removed before execution. `null` = truncate all. */
|
|
99
|
+
rollbackAfterMessageId?: string | null;
|
|
100
|
+
}
|
|
101
|
+
/** Continue execution after client-side tool handling */
|
|
102
|
+
interface ContinueRequest {
|
|
103
|
+
type: 'continue';
|
|
104
|
+
executionId: string;
|
|
105
|
+
toolResults: ToolResult[];
|
|
106
|
+
}
|
|
107
|
+
/** All request types supported by the session */
|
|
108
|
+
type SessionRequest = TriggerRequest | ContinueRequest;
|
|
109
|
+
/** Stop message to abort in-flight requests */
|
|
110
|
+
interface StopMessage {
|
|
111
|
+
type: 'stop';
|
|
112
|
+
}
|
|
113
|
+
/** All socket protocol messages (trigger, continue, stop) */
|
|
114
|
+
type SocketMessage = TriggerRequest | ContinueRequest | StopMessage;
|
|
115
|
+
/** Handlers for socket message streaming */
|
|
116
|
+
interface SocketMessageHandlers {
|
|
117
|
+
/** Called for each stream event */
|
|
118
|
+
onEvent: (event: StreamEvent) => void;
|
|
119
|
+
/** Called after streaming completes (not called if aborted) */
|
|
120
|
+
onFinish?: () => void | Promise<void>;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Converts an async iterable of stream events to an SSE-formatted ReadableStream.
|
|
124
|
+
* Use this when you need to return an SSE response (e.g., HTTP endpoints).
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const events = session.trigger('user-message', input);
|
|
129
|
+
* return new Response(toSSEStream(events), {
|
|
130
|
+
* headers: { 'Content-Type': 'text/event-stream' },
|
|
131
|
+
* });
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
declare function toSSEStream(events: AsyncIterable<StreamEvent>): ReadableStream<Uint8Array>;
|
|
135
|
+
interface SessionConfig {
|
|
136
|
+
sessionId: string;
|
|
137
|
+
config: ApiClientConfig;
|
|
138
|
+
tools?: ToolHandlers;
|
|
139
|
+
resources?: Resource[];
|
|
140
|
+
/** Tool schemas to send to the platform on the first trigger (device MCP tools, etc.) */
|
|
141
|
+
additionalToolSchemas?: ToolSchema[];
|
|
142
|
+
/** Called after server-side tools execute, before yielding events or continuing. Use to normalize tool results (e.g., upload base64 images). */
|
|
143
|
+
onToolResults?: (results: ToolResult[]) => Promise<void>;
|
|
144
|
+
/** When true, unhandled tool calls return errors instead of being emitted as client-tool-request events. */
|
|
145
|
+
rejectClientToolCalls?: boolean;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Options for trigger execution.
|
|
149
|
+
*/
|
|
150
|
+
interface TriggerOptions {
|
|
151
|
+
/** Abort signal to cancel the trigger execution */
|
|
152
|
+
signal?: AbortSignal;
|
|
153
|
+
}
|
|
154
|
+
/** Handles streaming and tool continuation for agent sessions */
|
|
155
|
+
declare class AgentSession {
|
|
156
|
+
private sessionId;
|
|
157
|
+
private config;
|
|
158
|
+
private toolHandlers;
|
|
159
|
+
private resourceMap;
|
|
160
|
+
private additionalToolSchemas;
|
|
161
|
+
private additionalToolSchemasSent;
|
|
162
|
+
private socketAbortController;
|
|
163
|
+
private onToolResults?;
|
|
164
|
+
private rejectClientToolCalls;
|
|
165
|
+
constructor(sessionConfig: SessionConfig);
|
|
166
|
+
/**
|
|
167
|
+
* Execute a session request and stream the response.
|
|
168
|
+
*
|
|
169
|
+
* This is the unified method that handles both triggers and continuations.
|
|
170
|
+
* Use this when you want to pass through requests from the client directly.
|
|
171
|
+
*
|
|
172
|
+
* @param request - The request (check `request.type` for the kind)
|
|
173
|
+
* @param options - Optional configuration including abort signal
|
|
174
|
+
*
|
|
175
|
+
* @example HTTP route (simple passthrough)
|
|
176
|
+
* ```typescript
|
|
177
|
+
* const events = session.execute(body, { signal: request.signal });
|
|
178
|
+
* return new Response(toSSEStream(events));
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* @example WebSocket handler
|
|
182
|
+
* ```typescript
|
|
183
|
+
* socket.on('message', (data) => {
|
|
184
|
+
* const events = session.execute(data);
|
|
185
|
+
* for await (const event of events) {
|
|
186
|
+
* socket.send(JSON.stringify(event));
|
|
187
|
+
* }
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
execute(request: SessionRequest, options?: TriggerOptions): AsyncGenerator<StreamEvent>;
|
|
192
|
+
getSessionId(): string;
|
|
193
|
+
/**
|
|
194
|
+
* Handle a WebSocket protocol message (trigger, continue, or stop).
|
|
195
|
+
* Manages abort controller lifecycle internally.
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* conn.on('data', (raw) => {
|
|
200
|
+
* session.handleSocketMessage(JSON.parse(raw), {
|
|
201
|
+
* onEvent: (event) => conn.write(JSON.stringify(event)),
|
|
202
|
+
* onFinish: async () => {
|
|
203
|
+
* // Fetch messages and persist to your database for restoration
|
|
204
|
+
* },
|
|
205
|
+
* });
|
|
206
|
+
* });
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
handleSocketMessage(message: SocketMessage, handlers: SocketMessageHandlers): Promise<void>;
|
|
210
|
+
private executeStream;
|
|
211
|
+
private handleResourceUpdate;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Session status indicating whether it's active or expired */
|
|
215
|
+
type SessionStatus = 'active' | 'expired';
|
|
216
|
+
interface SessionState {
|
|
217
|
+
id: string;
|
|
218
|
+
agentId: string;
|
|
219
|
+
input: Record<string, unknown>;
|
|
220
|
+
variables: Record<string, unknown>;
|
|
221
|
+
resources: Record<string, unknown>;
|
|
222
|
+
messages: ChatMessage[];
|
|
223
|
+
status?: 'active';
|
|
224
|
+
createdAt: string;
|
|
225
|
+
updatedAt: string;
|
|
226
|
+
}
|
|
227
|
+
interface UISessionState {
|
|
228
|
+
sessionId: string;
|
|
229
|
+
agentId: string;
|
|
230
|
+
messages: UIMessage[];
|
|
231
|
+
status?: 'active';
|
|
232
|
+
}
|
|
233
|
+
interface ExpiredSessionState {
|
|
234
|
+
sessionId: string;
|
|
235
|
+
agentId: string;
|
|
236
|
+
status: 'expired';
|
|
237
|
+
createdAt: string;
|
|
238
|
+
}
|
|
239
|
+
interface RestoreSessionResult {
|
|
240
|
+
sessionId: string;
|
|
241
|
+
/** True if session was restored from messages, false if already active */
|
|
242
|
+
restored: boolean;
|
|
243
|
+
}
|
|
244
|
+
interface ClearSessionResult {
|
|
245
|
+
sessionId: string;
|
|
246
|
+
cleared: boolean;
|
|
247
|
+
}
|
|
248
|
+
interface SessionAttachOptions {
|
|
249
|
+
tools?: ToolHandlers;
|
|
250
|
+
resources?: Resource[];
|
|
251
|
+
/** Computer capability provider (browser, filesystem, shell via MCP). */
|
|
252
|
+
computer?: ToolProvider;
|
|
253
|
+
/** Called after server-side tools execute, before yielding events or continuing. Use to normalize tool results (e.g., upload base64 images). */
|
|
254
|
+
onToolResults?: (results: ToolResult[]) => Promise<void>;
|
|
255
|
+
/** When true, unhandled tool calls return errors instead of being emitted as client-tool-request events. */
|
|
256
|
+
rejectClientToolCalls?: boolean;
|
|
257
|
+
}
|
|
258
|
+
/** API for managing agent sessions */
|
|
259
|
+
declare class AgentSessionsApi extends BaseApiClient {
|
|
260
|
+
/** Create a new session for an agent */
|
|
261
|
+
create(agentId: string, input?: Record<string, unknown>): Promise<string>;
|
|
262
|
+
/**
|
|
263
|
+
* Get full session state (for internal/debug use)
|
|
264
|
+
* Note: Contains all messages including hidden content
|
|
265
|
+
*
|
|
266
|
+
* Returns SessionState for active sessions, ExpiredSessionState for expired sessions.
|
|
267
|
+
* Check `status` field to determine which type was returned.
|
|
268
|
+
*/
|
|
269
|
+
get(sessionId: string): Promise<SessionState | ExpiredSessionState>;
|
|
270
|
+
/**
|
|
271
|
+
* Get UI-ready session messages (for client display)
|
|
272
|
+
* Returns only visible messages with hidden content filtered out.
|
|
273
|
+
*
|
|
274
|
+
* For expired sessions, returns status: 'expired' without messages.
|
|
275
|
+
* Use restore() to restore from stored messages before continuing.
|
|
276
|
+
*/
|
|
277
|
+
getMessages(sessionId: string): Promise<UISessionState | ExpiredSessionState>;
|
|
278
|
+
/**
|
|
279
|
+
* Restore an expired session from stored messages.
|
|
280
|
+
*
|
|
281
|
+
* Use this to restore a session after its state has expired.
|
|
282
|
+
* The consumer should have stored the UIMessage[] array from previous interactions.
|
|
283
|
+
*
|
|
284
|
+
* @param sessionId - The session ID to restore
|
|
285
|
+
* @param messages - Previously stored UIMessage[] array
|
|
286
|
+
* @param input - Optional session input for system prompt interpolation (same as create)
|
|
287
|
+
* @returns { sessionId, restored: true } if restored, { sessionId, restored: false } if already active
|
|
288
|
+
*/
|
|
289
|
+
restore(sessionId: string, messages: UIMessage[], input?: Record<string, unknown>): Promise<RestoreSessionResult>;
|
|
290
|
+
/**
|
|
291
|
+
* Clear session state from the server.
|
|
292
|
+
* The session will transition to 'expired' status and can be restored with restore().
|
|
293
|
+
* Idempotent: succeeds even if state was already cleared/expired.
|
|
294
|
+
*/
|
|
295
|
+
clear(sessionId: string): Promise<ClearSessionResult>;
|
|
296
|
+
/** Attach to an existing session for triggering events */
|
|
297
|
+
attach(sessionId: string, options?: SessionAttachOptions): AgentSession;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Schema for a single file upload request
|
|
302
|
+
*/
|
|
303
|
+
declare const fileUploadRequestSchema: z.ZodObject<{
|
|
304
|
+
filename: z.ZodString;
|
|
305
|
+
mediaType: z.ZodString;
|
|
306
|
+
size: z.ZodNumber;
|
|
307
|
+
}, z.core.$strip>;
|
|
308
|
+
/**
|
|
309
|
+
* Schema for a single file upload response
|
|
310
|
+
*/
|
|
311
|
+
declare const fileUploadInfoSchema: z.ZodObject<{
|
|
312
|
+
id: z.ZodString;
|
|
313
|
+
uploadUrl: z.ZodURL;
|
|
314
|
+
downloadUrl: z.ZodURL;
|
|
315
|
+
}, z.core.$strip>;
|
|
316
|
+
/**
|
|
317
|
+
* Schema for the upload URLs response
|
|
318
|
+
*/
|
|
319
|
+
declare const uploadUrlsResponseSchema: z.ZodObject<{
|
|
320
|
+
files: z.ZodArray<z.ZodObject<{
|
|
321
|
+
id: z.ZodString;
|
|
322
|
+
uploadUrl: z.ZodURL;
|
|
323
|
+
downloadUrl: z.ZodURL;
|
|
324
|
+
}, z.core.$strip>>;
|
|
325
|
+
}, z.core.$strip>;
|
|
326
|
+
type FileUploadRequest = z.infer<typeof fileUploadRequestSchema>;
|
|
327
|
+
type FileUploadInfo = z.infer<typeof fileUploadInfoSchema>;
|
|
328
|
+
type UploadUrlsResponse = z.infer<typeof uploadUrlsResponseSchema>;
|
|
329
|
+
/**
|
|
330
|
+
* API for file operations.
|
|
331
|
+
*
|
|
332
|
+
* Provides methods to generate presigned URLs for file uploads.
|
|
333
|
+
* Files are uploaded directly to S3, not through the platform.
|
|
334
|
+
*
|
|
335
|
+
* @example
|
|
336
|
+
* ```typescript
|
|
337
|
+
* // Get upload URLs
|
|
338
|
+
* const { files } = await client.files.getUploadUrls(sessionId, [
|
|
339
|
+
* { filename: 'image.png', mediaType: 'image/png', size: 12345 }
|
|
340
|
+
* ]);
|
|
341
|
+
*
|
|
342
|
+
* // Upload directly to S3
|
|
343
|
+
* await fetch(files[0].uploadUrl, {
|
|
344
|
+
* method: 'PUT',
|
|
345
|
+
* body: imageFile,
|
|
346
|
+
* headers: { 'Content-Type': 'image/png' }
|
|
347
|
+
* });
|
|
348
|
+
*
|
|
349
|
+
* // Use downloadUrl as FileReference in trigger input
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
declare class FilesApi extends BaseApiClient {
|
|
353
|
+
/**
|
|
354
|
+
* Get presigned URLs for uploading files to a session.
|
|
355
|
+
*
|
|
356
|
+
* Returns upload URLs (PUT) and download URLs (GET) for each file.
|
|
357
|
+
* Upload URLs expire in 15 minutes, download URLs match session TTL (24 hours).
|
|
358
|
+
*
|
|
359
|
+
* @param sessionId - The session ID to associate files with
|
|
360
|
+
* @param files - Array of file metadata (filename, mediaType, size)
|
|
361
|
+
* @returns Upload info with presigned URLs for each file
|
|
362
|
+
*
|
|
363
|
+
* @throws ApiError if session doesn't exist or validation fails
|
|
364
|
+
*
|
|
365
|
+
* @example
|
|
366
|
+
* ```typescript
|
|
367
|
+
* const { files } = await client.files.getUploadUrls(sessionId, [
|
|
368
|
+
* { filename: 'photo.jpg', mediaType: 'image/jpeg', size: 102400 },
|
|
369
|
+
* { filename: 'doc.pdf', mediaType: 'application/pdf', size: 204800 },
|
|
370
|
+
* ]);
|
|
371
|
+
*
|
|
372
|
+
* // files[0].id - Use in FileReference
|
|
373
|
+
* // files[0].uploadUrl - PUT to this URL
|
|
374
|
+
* // files[0].downloadUrl - Use as FileReference.url
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
getUploadUrls(sessionId: string, files: FileUploadRequest[]): Promise<UploadUrlsResponse>;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/** Start a new worker execution */
|
|
381
|
+
interface WorkerStartRequest {
|
|
382
|
+
type: 'start';
|
|
383
|
+
input: Record<string, unknown>;
|
|
384
|
+
}
|
|
385
|
+
/** Continue execution after client-side tool handling */
|
|
386
|
+
interface WorkerContinueRequest {
|
|
387
|
+
type: 'continue';
|
|
388
|
+
executionId: string;
|
|
389
|
+
toolResults: ToolResult[];
|
|
390
|
+
}
|
|
391
|
+
/** All request types supported by workers */
|
|
392
|
+
type WorkerRequest = WorkerStartRequest | WorkerContinueRequest;
|
|
393
|
+
/** Options for worker execution */
|
|
394
|
+
interface WorkerExecuteOptions {
|
|
395
|
+
/** Tool handlers for server-side tool execution */
|
|
396
|
+
tools?: ToolHandlers;
|
|
397
|
+
/** Abort signal to cancel the execution */
|
|
398
|
+
signal?: AbortSignal;
|
|
399
|
+
}
|
|
400
|
+
/** Result from a non-streaming worker execution via `generate()` */
|
|
401
|
+
interface WorkerGenerateResult {
|
|
402
|
+
/** The worker's output value */
|
|
403
|
+
output: unknown;
|
|
404
|
+
/** Session ID for the worker execution (usable for debugging/session URLs) */
|
|
405
|
+
sessionId: string;
|
|
406
|
+
}
|
|
407
|
+
/** API for executing worker agents */
|
|
408
|
+
declare class WorkersApi extends BaseApiClient {
|
|
409
|
+
/**
|
|
410
|
+
* Execute a worker agent and stream the response.
|
|
411
|
+
*
|
|
412
|
+
* Worker agents execute steps sequentially and return an output value.
|
|
413
|
+
* Unlike interactive sessions, workers don't maintain persistent state.
|
|
414
|
+
*
|
|
415
|
+
* The execution handles the tool continuation pattern automatically:
|
|
416
|
+
* - Server tools (with handlers provided) are executed automatically
|
|
417
|
+
* - Client tools (without handlers) emit a client-tool-request event
|
|
418
|
+
*
|
|
419
|
+
* @param agentId - The worker agent ID
|
|
420
|
+
* @param input - Input values for the worker
|
|
421
|
+
* @param options - Optional configuration including tools and abort signal
|
|
422
|
+
* @returns An async generator of stream events
|
|
423
|
+
*
|
|
424
|
+
* @example Basic execution
|
|
425
|
+
* ```typescript
|
|
426
|
+
* const events = client.workers.execute(agentId, { TOPIC: 'AI safety' });
|
|
427
|
+
* for await (const event of events) {
|
|
428
|
+
* if (event.type === 'worker-start') {
|
|
429
|
+
* console.log(`Worker ${event.workerSlug} started (${event.workerId})`);
|
|
430
|
+
* }
|
|
431
|
+
* if (event.type === 'worker-result') {
|
|
432
|
+
* if (event.error) {
|
|
433
|
+
* console.error('Worker failed:', event.error);
|
|
434
|
+
* } else {
|
|
435
|
+
* console.log('Output:', event.output);
|
|
436
|
+
* }
|
|
437
|
+
* }
|
|
438
|
+
* }
|
|
439
|
+
* ```
|
|
440
|
+
*
|
|
441
|
+
* @example With tool handlers
|
|
442
|
+
* ```typescript
|
|
443
|
+
* const events = client.workers.execute(agentId, { TOPIC: 'AI safety' }, {
|
|
444
|
+
* tools: {
|
|
445
|
+
* 'web-search': async (args) => {
|
|
446
|
+
* return await searchWeb(args.query);
|
|
447
|
+
* },
|
|
448
|
+
* },
|
|
449
|
+
* });
|
|
450
|
+
* ```
|
|
451
|
+
*/
|
|
452
|
+
execute(agentId: string, input: Record<string, unknown>, options?: WorkerExecuteOptions): AsyncGenerator<StreamEvent>;
|
|
453
|
+
/**
|
|
454
|
+
* Execute a worker agent and return the final output.
|
|
455
|
+
*
|
|
456
|
+
* Non-streaming equivalent of `execute()` — runs the worker to completion
|
|
457
|
+
* and returns the output value directly. Use this when you don't need to
|
|
458
|
+
* observe intermediate streaming events.
|
|
459
|
+
*
|
|
460
|
+
* @param agentId - The worker agent ID
|
|
461
|
+
* @param input - Input values for the worker
|
|
462
|
+
* @param options - Optional configuration including tools and abort signal
|
|
463
|
+
* @returns The worker output and session ID
|
|
464
|
+
* @throws {WorkerError} If the worker fails or completes without output
|
|
465
|
+
*
|
|
466
|
+
* @example Basic usage
|
|
467
|
+
* ```typescript
|
|
468
|
+
* const { output, sessionId } = await client.workers.generate(agentId, {
|
|
469
|
+
* TOPIC: 'AI safety',
|
|
470
|
+
* });
|
|
471
|
+
* console.log(output);
|
|
472
|
+
* console.log(`Debug: ${client.baseUrl}/platform/sessions/${sessionId}`);
|
|
473
|
+
* ```
|
|
474
|
+
*
|
|
475
|
+
* @example With timeout
|
|
476
|
+
* ```typescript
|
|
477
|
+
* const { output } = await client.workers.generate(agentId, input, {
|
|
478
|
+
* signal: AbortSignal.timeout(120_000),
|
|
479
|
+
* });
|
|
480
|
+
* ```
|
|
481
|
+
*/
|
|
482
|
+
generate(agentId: string, input: Record<string, unknown>, options?: WorkerExecuteOptions): Promise<WorkerGenerateResult>;
|
|
483
|
+
/**
|
|
484
|
+
* Continue a worker execution after client-side tool handling.
|
|
485
|
+
*
|
|
486
|
+
* Use this when your worker has tools without server-side handlers.
|
|
487
|
+
* The execution returns a client-tool-request event with an executionId.
|
|
488
|
+
* Execute the tools client-side, then call this method to continue.
|
|
489
|
+
*
|
|
490
|
+
* @param agentId - The worker agent ID
|
|
491
|
+
* @param executionId - The execution ID from the client-tool-request event
|
|
492
|
+
* @param toolResults - Results from client-side tool execution
|
|
493
|
+
* @param options - Optional configuration including tools and abort signal
|
|
494
|
+
* @returns An async generator of stream events
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```typescript
|
|
498
|
+
* // Start execution
|
|
499
|
+
* for await (const event of client.workers.execute(agentId, input)) {
|
|
500
|
+
* if (event.type === 'client-tool-request') {
|
|
501
|
+
* // Execute tools client-side
|
|
502
|
+
* const results = await executeToolsClientSide(event.toolCalls);
|
|
503
|
+
* // Continue execution
|
|
504
|
+
* for await (const ev of client.workers.continue(agentId, event.executionId, results)) {
|
|
505
|
+
* // Handle remaining events
|
|
506
|
+
* }
|
|
507
|
+
* }
|
|
508
|
+
* }
|
|
509
|
+
* ```
|
|
510
|
+
*/
|
|
511
|
+
continue(agentId: string, executionId: string, toolResults: ToolResult[], options?: WorkerExecuteOptions): AsyncGenerator<StreamEvent>;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
interface OctavusClientConfig {
|
|
515
|
+
baseUrl: string;
|
|
516
|
+
apiKey?: string;
|
|
517
|
+
/** Enable model request tracing to capture full payloads sent to providers (default: false) */
|
|
518
|
+
traceModelRequests?: boolean;
|
|
519
|
+
}
|
|
520
|
+
/** Client for interacting with the Octavus platform API */
|
|
521
|
+
declare class OctavusClient {
|
|
522
|
+
readonly agents: AgentsApi;
|
|
523
|
+
readonly agentSessions: AgentSessionsApi;
|
|
524
|
+
readonly files: FilesApi;
|
|
525
|
+
readonly workers: WorkersApi;
|
|
526
|
+
readonly baseUrl: string;
|
|
527
|
+
private readonly apiKey?;
|
|
528
|
+
private readonly traceModelRequests;
|
|
529
|
+
constructor(config: OctavusClientConfig);
|
|
530
|
+
getHeaders(): Record<string, string>;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/** Error thrown when a worker execution fails */
|
|
534
|
+
declare class WorkerError extends Error {
|
|
535
|
+
/** Session ID if the worker started before failing (for debugging URLs) */
|
|
536
|
+
readonly sessionId?: string | undefined;
|
|
537
|
+
constructor(message: string,
|
|
538
|
+
/** Session ID if the worker started before failing (for debugging URLs) */
|
|
539
|
+
sessionId?: string | undefined);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Extract base64 image blobs from tool results, upload them to S3 via
|
|
544
|
+
* presigned URLs, and replace inline data with compact metadata +
|
|
545
|
+
* FileReference entries.
|
|
546
|
+
*
|
|
547
|
+
* Runs at the server-sdk streaming layer so images are uploaded before
|
|
548
|
+
* tool results travel over the network (WebSocket, HTTP continuation).
|
|
549
|
+
*/
|
|
550
|
+
declare function normalizeToolResultImages(toolResults: ToolResult[], filesApi: FilesApi, sessionId: string): Promise<void>;
|
|
551
|
+
|
|
552
|
+
export { type Agent, type AgentDefinition, type AgentFormat, type AgentPrompt, AgentSession, AgentSessionsApi, type AgentSettings, AgentsApi, ApiError, type ClearSessionResult, type ContinueRequest, type ExpiredSessionState, type FileUploadInfo, type FileUploadRequest, FilesApi, OctavusClient, type OctavusClientConfig, Resource, type RestoreSessionResult, type SessionAttachOptions, type SessionConfig, type SessionRequest, type SessionState, type SessionStatus, type SocketMessage, type SocketMessageHandlers, type StopMessage, type TriggerOptions, type TriggerRequest, type UISessionState, type UploadUrlsResponse, type WorkerContinueRequest, WorkerError, type WorkerExecuteOptions, type WorkerGenerateResult, type WorkerRequest, type WorkerStartRequest, WorkersApi, normalizeToolResultImages, toSSEStream };
|
package/dist/index.d.ts
CHANGED
|
@@ -141,6 +141,8 @@ interface SessionConfig {
|
|
|
141
141
|
additionalToolSchemas?: ToolSchema[];
|
|
142
142
|
/** Called after server-side tools execute, before yielding events or continuing. Use to normalize tool results (e.g., upload base64 images). */
|
|
143
143
|
onToolResults?: (results: ToolResult[]) => Promise<void>;
|
|
144
|
+
/** When true, unhandled tool calls return errors instead of being emitted as client-tool-request events. */
|
|
145
|
+
rejectClientToolCalls?: boolean;
|
|
144
146
|
}
|
|
145
147
|
/**
|
|
146
148
|
* Options for trigger execution.
|
|
@@ -159,6 +161,7 @@ declare class AgentSession {
|
|
|
159
161
|
private additionalToolSchemasSent;
|
|
160
162
|
private socketAbortController;
|
|
161
163
|
private onToolResults?;
|
|
164
|
+
private rejectClientToolCalls;
|
|
162
165
|
constructor(sessionConfig: SessionConfig);
|
|
163
166
|
/**
|
|
164
167
|
* Execute a session request and stream the response.
|
|
@@ -249,6 +252,8 @@ interface SessionAttachOptions {
|
|
|
249
252
|
computer?: ToolProvider;
|
|
250
253
|
/** Called after server-side tools execute, before yielding events or continuing. Use to normalize tool results (e.g., upload base64 images). */
|
|
251
254
|
onToolResults?: (results: ToolResult[]) => Promise<void>;
|
|
255
|
+
/** When true, unhandled tool calls return errors instead of being emitted as client-tool-request events. */
|
|
256
|
+
rejectClientToolCalls?: boolean;
|
|
252
257
|
}
|
|
253
258
|
/** API for managing agent sessions */
|
|
254
259
|
declare class AgentSessionsApi extends BaseApiClient {
|
package/dist/index.js
CHANGED
|
@@ -294,18 +294,34 @@ async function* executeStream(config, payload, signal) {
|
|
|
294
294
|
}
|
|
295
295
|
}
|
|
296
296
|
if (clientTools.length > 0) {
|
|
297
|
-
if (
|
|
298
|
-
|
|
299
|
-
|
|
297
|
+
if (config.rejectClientToolCalls) {
|
|
298
|
+
const rejectedResults = clientTools.map((tc) => ({
|
|
299
|
+
toolCallId: tc.toolCallId,
|
|
300
|
+
toolName: tc.toolName,
|
|
301
|
+
error: `Tool "${tc.toolName}" is not available. No handler is registered for this tool.`,
|
|
302
|
+
outputVariable: tc.outputVariable,
|
|
303
|
+
blockIndex: tc.blockIndex,
|
|
304
|
+
thread: tc.thread,
|
|
305
|
+
workerId: tc.workerId
|
|
306
|
+
}));
|
|
307
|
+
for (const tr of rejectedResults) {
|
|
308
|
+
yield { type: "tool-output-error", toolCallId: tr.toolCallId, error: tr.error };
|
|
309
|
+
}
|
|
310
|
+
toolResults = [...serverResults, ...rejectedResults];
|
|
311
|
+
} else {
|
|
312
|
+
if (!executionId) {
|
|
313
|
+
yield createInternalErrorEvent("Missing executionId for client-tool-request");
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
yield {
|
|
317
|
+
type: "client-tool-request",
|
|
318
|
+
executionId,
|
|
319
|
+
toolCalls: clientTools,
|
|
320
|
+
serverToolResults: serverResults.length > 0 ? serverResults : void 0
|
|
321
|
+
};
|
|
322
|
+
yield { type: "finish", finishReason: "client-tool-calls", executionId };
|
|
323
|
+
continueLoop = false;
|
|
300
324
|
}
|
|
301
|
-
yield {
|
|
302
|
-
type: "client-tool-request",
|
|
303
|
-
executionId,
|
|
304
|
-
toolCalls: clientTools,
|
|
305
|
-
serverToolResults: serverResults.length > 0 ? serverResults : void 0
|
|
306
|
-
};
|
|
307
|
-
yield { type: "finish", finishReason: "client-tool-calls", executionId };
|
|
308
|
-
continueLoop = false;
|
|
309
325
|
} else {
|
|
310
326
|
toolResults = serverResults;
|
|
311
327
|
}
|
|
@@ -360,12 +376,14 @@ var AgentSession = class {
|
|
|
360
376
|
additionalToolSchemasSent = false;
|
|
361
377
|
socketAbortController = null;
|
|
362
378
|
onToolResults;
|
|
379
|
+
rejectClientToolCalls;
|
|
363
380
|
constructor(sessionConfig) {
|
|
364
381
|
this.sessionId = sessionConfig.sessionId;
|
|
365
382
|
this.config = sessionConfig.config;
|
|
366
383
|
this.toolHandlers = sessionConfig.tools ?? {};
|
|
367
384
|
this.additionalToolSchemas = sessionConfig.additionalToolSchemas;
|
|
368
385
|
this.onToolResults = sessionConfig.onToolResults;
|
|
386
|
+
this.rejectClientToolCalls = sessionConfig.rejectClientToolCalls ?? false;
|
|
369
387
|
this.resourceMap = /* @__PURE__ */ new Map();
|
|
370
388
|
for (const resource of sessionConfig.resources ?? []) {
|
|
371
389
|
this.resourceMap.set(resource.name, resource);
|
|
@@ -480,6 +498,7 @@ var AgentSession = class {
|
|
|
480
498
|
},
|
|
481
499
|
onResourceUpdate: (name, value) => this.handleResourceUpdate(name, value),
|
|
482
500
|
onToolResults: this.onToolResults,
|
|
501
|
+
rejectClientToolCalls: this.rejectClientToolCalls,
|
|
483
502
|
errorContext: "Failed to trigger"
|
|
484
503
|
},
|
|
485
504
|
{ executionId: payload.executionId, toolResults: payload.toolResults },
|
|
@@ -622,7 +641,8 @@ var AgentSessionsApi = class extends BaseApiClient {
|
|
|
622
641
|
tools: mergedTools,
|
|
623
642
|
resources: options.resources,
|
|
624
643
|
additionalToolSchemas: options.computer?.toolSchemas(),
|
|
625
|
-
onToolResults: options.onToolResults
|
|
644
|
+
onToolResults: options.onToolResults,
|
|
645
|
+
rejectClientToolCalls: options.rejectClientToolCalls
|
|
626
646
|
});
|
|
627
647
|
}
|
|
628
648
|
};
|