@standardagents/spec 0.27.12 → 0.28.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.d.ts CHANGED
@@ -121,2073 +121,2024 @@ declare global {
121
121
  }
122
122
 
123
123
  /**
124
- * Effect definition types for Standard Agents.
125
- *
126
- * Effects are scheduled operations that run outside the tool execution context.
127
- * They enable implementation-specific side effects with optional delay support,
128
- * leveraging whichever scheduling mechanism the runtime provides.
124
+ * Tool definition types for Standard Agents.
129
125
  *
130
- * Unlike tools, effects:
131
- * - Do not return results to the LLM
132
- * - Can be delayed for future execution
133
- * - Run independently of the conversation flow
134
- * - Are ideal for notifications, cleanup, and async operations
126
+ * Tools are callable functions that agents can invoke during execution.
127
+ * They receive the current ThreadState and validated arguments,
128
+ * and return results that are included in the conversation.
135
129
  *
136
130
  * @module
137
131
  */
138
132
 
139
133
  /**
140
- * Effect function signature.
141
- *
142
- * Effects are async functions that receive a ThreadState and
143
- * optionally validated arguments. Unlike tools, they return void
144
- * since results are not included in the conversation.
145
- *
146
- * @template State - The state type (defaults to ThreadState)
147
- * @template Args - The Zod schema for effect arguments, or null for no args
148
- */
149
- type Effect<State = ThreadState, Args extends ToolArgs | null = null> = Args extends ToolArgs ? (state: State, args: z.infer<Args>) => Promise<void> | void : (state: State) => Promise<void> | void;
150
- /**
151
- * Return type of defineEffect function.
152
- *
153
- * A tuple containing:
154
- * - Effect description string
155
- * - Argument schema (or null)
156
- * - Effect implementation function
157
- */
158
- type EffectDefinition<State = ThreadState, Args extends ToolArgs | null = null> = [string, Args, Effect<State, Args>];
159
- /**
160
- * Record of a scheduled effect.
161
- *
162
- * Returned by getScheduledEffects() to inspect pending effects.
134
+ * Text content item returned by tools.
163
135
  */
164
- interface ScheduledEffect {
165
- /** Unique identifier for this scheduled effect. */
166
- id: string;
167
- /** Name of the effect to execute. */
168
- name: string;
169
- /** Arguments to pass to the effect handler. */
170
- args: Record<string, unknown>;
171
- /** When the effect is scheduled to run (microseconds since epoch). */
172
- scheduledAt: number;
173
- /** When the effect was created (microseconds since epoch). */
174
- createdAt: number;
136
+ interface TextContent {
137
+ type: 'text';
138
+ text: string;
175
139
  }
176
140
  /**
177
- * Define an effect with arguments.
178
- *
179
- * @param description - Description of what the effect does
180
- * @param args - Zod schema for validating effect arguments
181
- * @param handler - The effect implementation function
182
- * @returns A tuple containing the effect definition
141
+ * Image content item returned by tools.
183
142
  */
184
- declare function defineEffect<State = ThreadState, Args extends ToolArgs = ToolArgs>(description: string, args: Args, handler: Effect<State, Args>): EffectDefinition<State, Args>;
143
+ interface ImageContent {
144
+ type: 'image';
145
+ /** Base64-encoded image data. */
146
+ data: string;
147
+ /** MIME type of the image (e.g., 'image/png', 'image/jpeg'). */
148
+ mimeType: string;
149
+ }
185
150
  /**
186
- * Define an effect without arguments.
187
- *
188
- * @param description - Description of what the effect does
189
- * @param handler - The effect implementation function
190
- * @returns A tuple containing the effect definition
151
+ * Content types that can be returned by tools.
191
152
  */
192
- declare function defineEffect<State = ThreadState>(description: string, handler: Effect<State, null>): EffectDefinition<State, null>;
193
-
153
+ type ToolContent = TextContent | ImageContent;
194
154
  /**
195
- * Agent Skills — instance-global skill store types.
196
- *
197
- * Skills follow the Agent Skills standard (https://agentskills.io): a folder
198
- * whose root SKILL.md opens with YAML frontmatter carrying a required `name`
199
- * (lowercase kebab, ≤64 chars) and `description` (≤1024 chars), optionally
200
- * accompanied by scripts, references, and assets.
155
+ * File attachment generated by a tool.
201
156
  *
202
- * Runtimes store skills server-side as a GLOBAL, instance-wide library:
203
- * installed once, visible to every thread, nothing persisted on a client
204
- * machine. Progressive disclosure is the contract — agents see only each
205
- * skill's name + description until a skill is judged applicable, at which
206
- * point they load its SKILL.md body (and, when needed, read or execute its
207
- * bundled files).
157
+ * Attachments are stored in the thread's file system and linked to
158
+ * the tool result message. Unlike user uploads, tool attachments are
159
+ * not subject to image downsampling.
208
160
  */
209
- /** Registry view of an installed skill (metadata only — no file contents). */
210
- interface SkillMetadata {
211
- /** Kebab-case identifier from SKILL.md frontmatter. */
161
+ interface ToolAttachment {
162
+ /** File name for the attachment. */
212
163
  name: string;
213
- /** What the skill does and when to use it (from frontmatter). */
214
- description: string;
215
- /** Optional version string from frontmatter. */
216
- version?: string;
217
- /** Disabled skills stay installed but are hidden from agents. */
218
- enabled: boolean;
219
- /** Relative paths of the skill's files (always includes SKILL.md). */
220
- files: string[];
221
- /** Unix seconds of the last install/update. */
222
- updatedAt?: number;
164
+ /** MIME type of the attachment. */
165
+ mimeType: string;
166
+ /** Base64-encoded file data. */
167
+ data: string;
168
+ /** Width in pixels (for images). */
169
+ width?: number;
170
+ /** Height in pixels (for images). */
171
+ height?: number;
223
172
  }
224
- /** A file being installed into a skill (relative path + full text). */
225
- interface SkillFileInput {
173
+ /**
174
+ * Reference to a pre-existing attachment in the thread file system.
175
+ */
176
+ interface AttachmentRef {
177
+ /** Unique identifier for the attachment. */
178
+ id: string;
179
+ /** Attachment type. */
180
+ type: 'file';
181
+ /** Path in the thread file system. */
226
182
  path: string;
227
- content: string;
183
+ /** File name. */
184
+ name: string;
185
+ /** MIME type. */
186
+ mimeType: string;
187
+ /** File size in bytes. */
188
+ size: number;
189
+ /** Width in pixels (for images). */
190
+ width?: number;
191
+ /** Height in pixels (for images). */
192
+ height?: number;
193
+ /** AI-generated description. */
194
+ description?: string;
228
195
  }
229
196
  /**
230
- * ThreadState surface for the global skill library. All operations hit the
231
- * instance-wide store — there is no per-thread skill state beyond what a
232
- * thread chooses to keep in its own key-value store.
197
+ * Result returned by a tool execution.
233
198
  */
234
- interface SkillsNamespace {
235
- /** Installed skills (enabled only, unless includeDisabled). */
236
- list(options?: {
237
- includeDisabled?: boolean;
238
- }): Promise<SkillMetadata[]>;
239
- /** A skill's metadata plus its SKILL.md source (null when not installed). */
240
- get(name: string): Promise<{
241
- metadata: SkillMetadata;
242
- skillMd: string;
243
- } | null>;
244
- /** Read one bundled file's text (null when the skill or file is missing). */
245
- readFile(name: string, path: string): Promise<string | null>;
199
+ interface ToolResult {
200
+ /** Status of the tool execution. */
201
+ status: 'success' | 'error';
246
202
  /**
247
- * Install (or replace) a skill from its file set. The file set must include
248
- * a root SKILL.md with valid frontmatter; the skill's identity comes from
249
- * that frontmatter, never from a caller-supplied name.
203
+ * Text representation of the tool output.
204
+ *
205
+ * For tools that return structured content, this is derived by
206
+ * concatenating all text parts. For simple tools, this is the
207
+ * direct result string.
250
208
  */
251
- install(files: SkillFileInput[]): Promise<SkillMetadata>;
252
- /** Enable/disable an installed skill. Returns false when not installed. */
253
- setEnabled(name: string, enabled: boolean): Promise<boolean>;
254
- /** Uninstall a skill entirely. Returns false when not installed. */
255
- remove(name: string): Promise<boolean>;
209
+ result?: string;
210
+ /** Error message if status is 'error'. */
211
+ error?: string;
212
+ /**
213
+ * Machine-readable error code for structured handling.
214
+ *
215
+ * Example: `subagent_env_required` indicates the client must provide
216
+ * scoped subagent env values before execution can continue.
217
+ */
218
+ error_code?: string;
219
+ /**
220
+ * Structured error payload for machine handling.
221
+ *
222
+ * Implementations should keep this JSON-serializable.
223
+ */
224
+ error_data?: Record<string, unknown>;
225
+ /** Stack trace for error debugging. */
226
+ stack?: string;
227
+ /**
228
+ * File attachments returned by the tool.
229
+ *
230
+ * Can contain either:
231
+ * - ToolAttachment: New files with base64 data to be stored
232
+ * - AttachmentRef: References to existing files in the thread filesystem
233
+ *
234
+ * Implementations MUST store new attachments under /attachments/ directory.
235
+ */
236
+ attachments?: Array<ToolAttachment | AttachmentRef>;
256
237
  }
257
-
238
+ /** Decrement helper to limit recursion depth. */
239
+ type Dec<N extends number> = N extends 10 ? 9 : N extends 9 ? 8 : N extends 8 ? 7 : N extends 7 ? 6 : N extends 6 ? 5 : N extends 5 ? 4 : N extends 4 ? 3 : N extends 3 ? 2 : N extends 2 ? 1 : N extends 1 ? 0 : 0;
258
240
  /**
259
- * Thread state types for Standard Agents.
241
+ * Allowed Zod types for tool argument nodes.
260
242
  *
261
- * ThreadState is the unified interface for all thread operations.
262
- * It provides access to thread identity, messages, logs, resource loading,
263
- * tool invocation, event emission, and execution state.
243
+ * This is the single source of truth for which Zod types can be used
244
+ * in tool argument schemas. The depth parameter limits recursion to
245
+ * prevent infinite type expansion.
246
+ * Use ZodUnknown for arbitrary JSON slots, such as array items that can
247
+ * be strings, numbers, booleans, null, arrays, or objects.
264
248
  *
265
- * @module
249
+ * @template D - Maximum nesting depth (default: 7)
266
250
  */
267
-
251
+ type ToolArgsNode<D extends number = 7> = ZodString | ZodNumber | ZodBoolean | ZodNull | ZodLiteral<string | number | boolean | null> | ZodUnknown | ZodEnum<Readonly<Record<string, string>>> | (D extends 0 ? never : ZodOptional<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodNullable<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodDefault<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodArray<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodObject<Record<string, ToolArgsNode<Dec<D>>>>) | (D extends 0 ? never : ZodRecord<ZodString, ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodUnion<readonly [
252
+ ToolArgsNode<Dec<D>>,
253
+ ToolArgsNode<Dec<D>>,
254
+ ...ToolArgsNode<Dec<D>>[]
255
+ ]>);
268
256
  /**
269
- * Metadata about a thread.
257
+ * Raw shape for a Zod object schema containing tool argument nodes.
270
258
  *
271
- * This represents the core identity of a thread, separate from its
272
- * operational state. Thread metadata is immutable after creation.
259
+ * @template D - Maximum nesting depth (default: 7)
273
260
  */
261
+ type ToolArgsRawShape<D extends number = 7> = Record<string, ToolArgsNode<D>>;
274
262
  /**
275
- * The profile of the user a thread belongs to, as exposed by
276
- * {@link ThreadState.user}. Identity fields only — never credentials.
263
+ * Top-level tool argument schema.
264
+ *
265
+ * Tool arguments MUST be defined as a Zod object schema.
266
+ * This is required for compatibility with OpenAI's function calling API.
267
+ *
268
+ * @template D - Maximum nesting depth (default: 7)
277
269
  */
278
- interface ThreadUser {
279
- id: string;
280
- username: string;
281
- /** 'admin' | 'user' | 'api' in the reference runtime. */
282
- role: string;
283
- /** Explicit permission grants (runtime-defined strings), if any. */
284
- permissions?: string[] | null;
285
- email?: string | null;
286
- display_name?: string | null;
287
- avatar_url?: string | null;
288
- }
289
- interface ThreadMetadata {
290
- /** Unique identifier for the thread */
291
- id: string;
292
- /** Agent that owns this thread */
293
- agent_id: string;
294
- /** User associated with this thread (if any) */
295
- user_id: string | null;
296
- /** Creation timestamp (microseconds since epoch) */
297
- created_at: number;
298
- }
270
+ type ToolArgs<D extends number = 7> = z.ZodObject<ToolArgsRawShape<D>>;
299
271
  /**
300
- * Registry entry for a subagent child thread.
301
- */
302
- interface SubagentRegistryEntry {
303
- /** Child thread UUID used as stable reference address */
304
- reference: string;
305
- /** Child agent name */
306
- name: string;
307
- /** Child agent title (human-readable) */
308
- title?: string;
309
- /** Tool description shown to the parent LLM */
310
- description: string;
311
- /** Whether this subagent instance is resumable */
312
- resumable?: boolean;
313
- /** Whether parent execution blocks on this subagent */
314
- blocking?: boolean;
315
- /** Optional human-readable thread name (for example from `name:` tag) */
316
- threadName?: string;
317
- /**
318
- * Initial argument values supplied when the child was created.
319
- *
320
- * For resumable subagents, these values persist for the lifetime of the
321
- * child thread and are visible to both child sides. Runtimes SHOULD source
322
- * this object from the receiving side's prompt argument schema. The registry
323
- * copy is parent-visible metadata; the durable child-side source SHOULD live
324
- * with the child thread metadata/properties and be restored into
325
- * `ThreadState.arguments` during execution and endpoint access. Top-level
326
- * keys SHOULD also be exposed to prompt variable interpolation for whichever
327
- * child side is currently rendering.
328
- */
329
- initialArguments?: Record<string, unknown>;
330
- /** Spawn group identifier used for grouping instances created together */
331
- spawnGroupId?: string;
332
- /** Instance creation timestamp (microseconds) */
333
- createdAt?: number;
334
- /** Current status (`running`, `idle`, `terminated`, or custom text) */
335
- status: string;
336
- /** How this child reports information back to its parent thread */
337
- parentCommunication?: 'implicit' | 'explicit';
338
- }
339
- /**
340
- * Options for retrieving messages.
341
- */
342
- interface GetMessagesOptions {
343
- /** Maximum number of messages to return */
344
- limit?: number;
345
- /** Number of messages to skip */
346
- offset?: number;
347
- /** Sort order ('asc' for oldest first, 'desc' for newest first) */
348
- order?: 'asc' | 'desc';
349
- /** Include silent messages (not shown in UI) */
350
- includeSilent?: boolean;
351
- /** Maximum nesting depth for sub-prompt messages */
352
- maxDepth?: number;
353
- }
354
- /**
355
- * Result of a message query.
272
+ * Variable declaration type.
273
+ *
274
+ * - `text`: Plain string configuration value
275
+ * - `secret`: Sensitive value that should be encrypted at rest
356
276
  */
357
- interface MessagesResult {
358
- /** Array of messages */
359
- messages: Message[];
360
- /** Total number of messages matching the query */
361
- total: number;
362
- /** Whether there are more messages available */
363
- hasMore: boolean;
364
- }
277
+ type VariableType = 'text' | 'secret';
365
278
  /**
366
- * A message in the thread conversation.
279
+ * Declares a variable required or optionally consumed by a tool or prompt.
367
280
  */
368
- interface Message {
369
- /** Unique message identifier */
370
- id: string;
371
- /** Message role */
372
- role: 'system' | 'user' | 'assistant' | 'tool';
373
- /** Message content (null for tool calls without text) */
374
- content: string | null;
375
- /** Tool name (for tool result messages) */
376
- name?: string | null;
377
- /** JSON-encoded array of tool calls (for assistant messages) */
378
- tool_calls?: string | null;
379
- /** Tool call ID (for tool result messages) */
380
- tool_call_id?: string | null;
381
- /** Creation timestamp (microseconds since epoch) */
382
- created_at: number;
383
- /** Parent message ID (for sub-prompt messages) */
384
- parent_id?: string | null;
385
- /** Nesting depth (0 for top-level messages) */
386
- depth?: number;
387
- /** Whether this message is silent (not shown in UI) */
388
- silent?: boolean;
281
+ interface VariableDefinition {
282
+ /** Environment variable/property name */
283
+ name: string;
284
+ /** Value type */
285
+ type: VariableType;
286
+ /** Whether this variable is required to execute */
287
+ required: boolean;
389
288
  /**
390
- * Custom metadata.
289
+ * Whether this variable is scoped to the declarer subtree.
391
290
  *
392
- * Runtimes may attach lifecycle metadata for synthesized status messages
393
- * (for example: `status_kind`, `subagent_event`). Message APIs may also
394
- * mark send-message and durable queue entries with `queued: true` until
395
- * they are injected into stored history.
291
+ * Scoped variables do not inherit parent thread env values. Descendants of
292
+ * the declarer still inherit scoped values from that declarer thread.
293
+ *
294
+ * @default false
396
295
  */
397
- metadata?: Record<string, unknown>;
398
- /** Message processing status */
399
- status?: 'pending' | 'completed' | 'failed' | null;
400
- /** Tool execution status (for tool result messages) */
401
- tool_status?: 'success' | 'error' | null;
402
- /** Subagent reference UUID associated with this message */
403
- subagent_id?: string | null;
404
- /** Subagent agent name projected from runtime registry (when available) */
405
- subagent_name?: string | null;
406
- /** Subagent agent title projected from runtime registry (when available) */
407
- subagent_title?: string | null;
408
- /** Subagent description projected from runtime registry (when available) */
409
- subagent_description?: string | null;
410
- /** Subagent status projected from runtime registry (when available) */
411
- subagent_status?: string | null;
412
- /** Whether the associated subagent is resumable (when available) */
413
- subagent_resumable?: boolean | null;
414
- /** Whether the associated subagent is blocking (when available) */
415
- subagent_blocking?: boolean | null;
416
- /** Optional subagent instance thread name (when available) */
417
- subagent_thread_name?: string | null;
418
- /** Spawn group identifier for related subagent instances (when available) */
419
- subagent_spawn_group_id?: string | null;
420
- }
421
- /**
422
- * Input for injecting a new message.
423
- */
424
- interface InjectMessageInput {
425
- /** Message role */
426
- role: 'user' | 'assistant' | 'system';
427
- /** Message content */
428
- content: string;
429
- /** Whether to hide from UI */
430
- silent?: boolean;
431
- /** Custom metadata */
432
- metadata?: Record<string, unknown>;
296
+ scoped?: boolean;
297
+ /** Human-readable description (empty string when not provided) */
298
+ description: string;
433
299
  }
434
300
  /**
435
- * Input for queueing a message for delivery on the thread's next step.
301
+ * Legacy raw shape for `tenvs` schema - uses same pattern as ToolArgsRawShape.
302
+ * Each key is an environment variable name and each value is a Zod schema.
436
303
  *
437
- * Role mapping follows dual_ai conventions:
438
- * - `assistant` maps to side_a
439
- * - `user` maps to side_b
304
+ * @template D - Maximum nesting depth (default: 7)
440
305
  */
441
- interface QueueMessageInput {
442
- /** Message role (`user` queues side_b perspective, `assistant` queues side_a perspective) */
443
- role: 'user' | 'assistant';
444
- /** Message content */
445
- content: string;
446
- /** Optional file attachments (new files or existing refs) */
447
- attachments?: Array<ToolAttachment | AttachmentRef>;
448
- /** Whether to hide the queued message from normal UI display */
449
- silent?: boolean;
450
- /** Optional structured metadata */
451
- metadata?: Record<string, unknown>;
452
- }
306
+ type TenvRawShape<D extends number = 7> = Record<string, ToolArgsNode<D>>;
453
307
  /**
454
- * Updates to apply to an existing message.
308
+ * Top-level thread environment variable schema.
309
+ *
310
+ * Defines which thread environment variables a tool requires.
311
+ * Required values are non-optional fields, optional values use `.optional()`.
312
+ *
313
+ * @example
314
+ * ```typescript
315
+ * z.object({
316
+ * VECTOR_STORE_ID: z.string().describe('OpenAI Vector Store ID'), // Required
317
+ * USER_LOCATION: z.string().optional().describe('User location'), // Optional
318
+ * })
319
+ * ```
320
+ *
321
+ * @template D - Maximum nesting depth (default: 7)
455
322
  */
456
- interface MessageUpdates {
457
- /** New content */
458
- content?: string;
459
- /** Updated metadata (merged with existing) */
460
- metadata?: Record<string, unknown>;
461
- }
323
+ type ToolTenvs<D extends number = 7> = z.ZodObject<TenvRawShape<D>>;
462
324
  /**
463
- * A streamed fragment of an assistant message's *visible content*.
464
- *
465
- * Always broadcast (no opt-in). Clients accumulate `chunk`s by `message_id` to
466
- * render the answer as it generates; the authoritative final content still
467
- * arrives separately as a persisted message. Clients must not discard an
468
- * already-painted draft solely because a retry/reconnect exposes another id:
469
- * retain keyed drafts or treat the id as a reconciliation alias until the
470
- * terminal message record atomically supersedes it.
325
+ * @deprecated Use VariableDefinition[] via the `variables` property instead.
471
326
  */
472
- interface ThreadMessageChunkEvent {
473
- type: 'message_chunk';
474
- /** The assistant message these fragments belong to. */
475
- message_id: string;
476
- /** Message depth: 0 = top-level thread, 1+ = subagent. */
477
- depth: number;
478
- /** The next fragment of visible content. */
479
- chunk: string;
480
- }
327
+ type ToolVariables = VariableDefinition[];
481
328
  /**
482
- * A streamed fragment of a model's *internal reasoning* (chain-of-thought).
329
+ * Tool function signature.
483
330
  *
484
- * OPT-IN. Unlike content, reasoning is private by default: it is only sent to
485
- * sockets that explicitly subscribe by connecting with the
486
- * {@link THREAD_STREAM_REASONING_PARAM} query parameter set to a truthy value
487
- * (e.g. `?reasoning=1`). Standard SDK consumers therefore never receive it
488
- * unless they opt in.
331
+ * Tools are async functions that receive a ThreadState and
332
+ * optionally validated arguments, returning a ToolResult.
489
333
  *
490
- * Reasoning is ephemeral *display* output: it is streamed for live presentation
491
- * only and is NOT persisted as part of the assistant message content, so it
492
- * cannot be replayed from message history — a client that wants it must be
493
- * subscribed while the turn runs.
334
+ * @template State - The state type (defaults to ThreadState)
335
+ * @template Args - The Zod schema for tool arguments, or null for no args
494
336
  */
495
- interface ThreadReasoningChunkEvent {
496
- type: 'reasoning_chunk';
497
- /** The assistant message this reasoning accompanies. */
498
- message_id: string;
499
- /** Message depth: 0 = top-level thread, 1+ = subagent. */
500
- depth: number;
501
- /** The next fragment of internal reasoning. */
502
- chunk: string;
503
- }
337
+ type Tool<State = ThreadState, Args extends ToolArgs | null = null> = Args extends ToolArgs ? (state: State, args: z.infer<Args>) => Promise<ToolResult> : (state: State) => Promise<ToolResult>;
504
338
  /**
505
- * Query-parameter name a client sets (truthy) on the thread stream WebSocket to
506
- * opt into receiving {@link ThreadReasoningChunkEvent}s. Absent/falsey means the
507
- * server never emits reasoning to that socket.
339
+ * Helper type to check if Uses is a non-empty const array.
340
+ * Returns true only if Uses has literal string elements (from `as const`).
508
341
  */
509
- declare const THREAD_STREAM_REASONING_PARAM = "reasoning";
342
+ type IsConstArray<Uses extends readonly string[]> = string extends Uses[number] ? false : true;
510
343
  /**
511
- * Storage location identifier.
512
- *
513
- * Implementations define their own storage identifiers (e.g., 'local', 'cloud', 's3').
514
- * The spec does not mandate specific storage backends.
344
+ * Helper type to check if Uses array is empty.
515
345
  */
516
- type FileStorage = string;
346
+ type IsEmptyArray<Uses extends readonly string[]> = Uses extends readonly [] ? true : false;
517
347
  /**
518
- * Record representing a file in the thread's file system.
348
+ * A ThreadState with queueTool and invokeTool constrained to specific tool names.
349
+ *
350
+ * When a tool declares `uses: ['a', 'b'] as const`, the state passed to execute
351
+ * will only allow calling those specific tools.
352
+ *
353
+ * @template Uses - Readonly array of allowed tool names
519
354
  */
520
- interface FileRecord {
521
- /** File path (relative to thread root) */
522
- path: string;
523
- /** File name */
524
- name: string;
525
- /** MIME type */
526
- mimeType: string;
527
- /** Storage location */
528
- storage: FileStorage;
529
- /** File size in bytes */
530
- size: number;
531
- /** Whether this is a directory */
532
- isDirectory: boolean;
533
- /** Custom metadata */
534
- metadata?: Record<string, unknown>;
535
- /** Image width in pixels (if applicable) */
536
- width?: number;
537
- /** Image height in pixels (if applicable) */
538
- height?: number;
539
- /** Creation timestamp */
540
- createdAt?: number;
541
- /** Last modified timestamp */
542
- updatedAt?: number;
543
- }
544
- /**
545
- * Options for writing a file.
546
- */
547
- interface WriteFileOptions {
548
- /** Custom metadata to attach to the file */
549
- metadata?: Record<string, unknown>;
550
- /** Image width in pixels (if applicable) */
551
- width?: number;
552
- /** Image height in pixels (if applicable) */
553
- height?: number;
554
- }
555
- /**
556
- * Result of reading a directory.
557
- */
558
- interface ReaddirResult {
559
- /** Files and directories in the path */
560
- entries: FileRecord[];
561
- }
562
- /**
563
- * Statistics about the thread's file system.
564
- */
565
- interface FileStats {
566
- /** Total number of files */
567
- fileCount: number;
568
- /** Total number of directories */
569
- directoryCount: number;
570
- /** Total size in bytes */
571
- totalSize: number;
572
- }
573
- /**
574
- * Result of a grep search.
575
- */
576
- interface GrepResult {
577
- /** File path */
578
- path: string;
579
- /** Matching lines */
580
- matches: Array<{
581
- line: number;
582
- content: string;
583
- }>;
584
- }
585
- /**
586
- * Result of a find operation.
587
- */
588
- interface FindResult {
589
- /** Matching file paths */
590
- paths: string[];
591
- }
592
- /**
593
- * Options for streaming file reads.
594
- */
595
- interface ReadFileStreamOptions {
355
+ type UsesConstrainedState<Uses extends readonly string[]> = Omit<ThreadState, 'queueTool' | 'invokeTool'> & {
596
356
  /**
597
- * Abort signal for cancellation.
357
+ * Queue a tool for execution.
598
358
  *
599
- * When signaled, the stream stops yielding new chunks.
600
- * Already-yielded chunks remain valid.
359
+ * Constrained to only tools declared in `uses` array.
360
+ *
361
+ * @param toolName - Name of the tool to invoke (must be in uses array)
362
+ * @param args - Arguments to pass to the tool
601
363
  */
602
- signal?: AbortSignal;
603
- }
364
+ queueTool(toolName: Uses[number], args?: Record<string, unknown>): void;
365
+ /**
366
+ * Invoke a tool directly and wait for the result.
367
+ *
368
+ * Constrained to only tools declared in `uses` array.
369
+ *
370
+ * @param toolName - Name of the tool to invoke (must be in uses array)
371
+ * @param args - Arguments to pass to the tool
372
+ * @returns The tool result
373
+ */
374
+ invokeTool(toolName: Uses[number], args?: Record<string, unknown>): Promise<ToolResult>;
375
+ };
604
376
  /**
605
- * A chunk of file data from a streaming read.
377
+ * A ThreadState where queueTool and invokeTool cannot be called (empty uses).
606
378
  */
607
- interface FileChunk {
608
- /** Raw binary data for this chunk */
609
- data: Uint8Array;
610
- /** 0-based index of this chunk */
611
- index: number;
612
- /** Total number of chunks (1 for small files) */
613
- totalChunks: number;
614
- /** Whether this is the final chunk */
615
- isLast: boolean;
616
- }
379
+ type EmptyUsesState = Omit<ThreadState, 'queueTool' | 'invokeTool'>;
617
380
  /**
618
- * Options passed to {@link ThreadState.runCode}.
381
+ * Determines the correct state type based on the Uses array.
619
382
  *
620
- * Code execution is strictly capability-based: the sandbox starts with no
621
- * ambient capabilities (no `fs`, no `fetch`, no `console`, no host globals).
622
- * Every capability the sandbox needs must be bridged in explicitly through
623
- * `imports` or `globals`.
383
+ * - Empty `uses: [] as const` → EmptyUsesState (no queueTool/invokeTool)
384
+ * - Const `uses: ['a', 'b'] as const` → UsesConstrainedState (constrained methods)
385
+ * - Non-const `uses: ['a']` or no uses → ThreadState (unconstrained, backward compatible)
386
+ */
387
+ type ResolveUsesState<Uses extends readonly string[]> = IsEmptyArray<Uses> extends true ? EmptyUsesState : IsConstArray<Uses> extends true ? UsesConstrainedState<Uses> : ThreadState;
388
+ /**
389
+ * Tool execute function with uses-aware state.
624
390
  *
625
- * Deadlines are **not** an option. Callers impose their own by calling
626
- * `handle.terminate()` on the returned {@link CodeExecution}.
391
+ * When `uses` is declared with `as const`, the state's queueTool and invokeTool
392
+ * are constrained to only the declared tools. When `uses` is not declared or
393
+ * is a regular string[], any tool name is allowed (backward compatible).
627
394
  *
628
- * See the [Code Execution specification](https://standardagentspec.com/0.1.0/specification/threads/code-execution)
629
- * for the full contract.
395
+ * @template State - Base state type
396
+ * @template Args - Tool arguments schema
397
+ * @template Uses - Readonly array of allowed tool names
630
398
  */
631
- interface CodeExecutionOptions {
399
+ type UsesAwareExecute<State, Args extends ToolArgs | null, Uses extends readonly string[]> = Args extends ToolArgs ? (state: ResolveUsesState<Uses>, args: z.infer<Args>) => Promise<ToolResult> : (state: ResolveUsesState<Uses>) => Promise<ToolResult>;
400
+ /**
401
+ * Options for defining a tool.
402
+ *
403
+ * @template State - The state type (defaults to ThreadState)
404
+ * @template Args - The Zod schema for tool arguments, or null for no args
405
+ * @template Tenvs - The Zod schema for thread environment variables, or null
406
+ * @template Uses - Readonly array of tool names this tool can invoke
407
+ */
408
+ interface DefineToolOptions<State = ThreadState, Args extends ToolArgs | null = null, Tenvs extends ToolTenvs | null = null, Uses extends readonly string[] = readonly string[]> {
409
+ /** Description of what the tool does (shown to the LLM). */
410
+ description: string;
411
+ /** Zod schema for validating tool arguments. Omit for tools with no args. */
412
+ args?: Args;
413
+ /** The tool implementation function. */
414
+ execute: UsesAwareExecute<State, Args, Uses>;
632
415
  /**
633
- * Export to execute from the evaluated module and arguments to pass.
634
- *
635
- * By default, runtimes execute the module's `default` export with no
636
- * arguments. If the selected export is a function, it is called with
637
- * `args` and the returned value or promise is used as the run result. If the
638
- * selected export is not a function, `args` MUST be omitted or empty and the
639
- * export value itself becomes the result.
640
- *
641
- * @default { fn: 'default', args: [] }
642
- *
643
- * @example
644
- * ```ts
645
- * execute: { fn: 'increment', args: [100] }
646
- * ```
416
+ * Variable declarations required/optionally used by this tool.
647
417
  */
648
- execute?: {
649
- /** Export name to execute. Use `'default'` for the default export. */
650
- fn?: string;
651
- /** Arguments passed to the selected export when it is a function. */
652
- args?: unknown[];
653
- };
418
+ variables?: VariableDefinition[];
654
419
  /**
655
- * Map of bare module specifier → named exports exposed to the sandbox.
656
- *
657
- * Only bare specifiers resolve from `imports` (e.g., `'fs'`,
658
- * `'@scope/pkg'`). Relative specifiers resolve only from `modules`; URL
659
- * (`'https://…'`) imports MUST fail at link time.
660
- *
661
- * The key `default` within a namespace becomes that module's default export.
662
- *
663
- * @example
664
- * ```ts
665
- * imports: {
666
- * fs: { readFile: (path) => state.readFile(path) },
667
- * supervisor: { report: (payload) => telemetry.push(payload) },
668
- * }
669
- * ```
420
+ * @deprecated Use `variables` instead.
421
+ * Zod schema for thread environment variables the tool requires.
670
422
  */
671
- imports?: Record<string, Record<string, unknown>>;
423
+ tenvs?: Tenvs;
672
424
  /**
673
- * Additional relative ES modules available to the sandbox.
674
- *
675
- * Keys are relative module specifiers from the module graph root, such as
676
- * `'./helpers.js'` or `'./lib/math.js'`. Entry source imports resolve from
677
- * `filename` when one is supplied. Entry and module source may import sibling
678
- * or parent modules with `./` and `../` specifiers when those imports resolve
679
- * within the supplied module graph. Values are JavaScript or TypeScript module
680
- * source. Use this when a caller wants the entry source to import local files
681
- * while still keeping all modules inside the sandbox.
425
+ * Where this tool is executed:
426
+ * - 'local': Execute locally by the execution engine (default)
427
+ * - 'provider': Executed by the LLM provider, results come in response
682
428
  */
683
- modules?: Record<string, string>;
429
+ executionMode?: 'local' | 'provider';
684
430
  /**
685
- * Map of identifier → value installed on the sandbox's module scope.
431
+ * Which provider executes this tool (when executionMode='provider').
432
+ * e.g., 'openai', 'anthropic'
433
+ */
434
+ executionProvider?: string;
435
+ /**
436
+ * Explicit list of tools, prompts, or agents this tool can call.
686
437
  *
687
- * These identifiers are resolvable as free variables inside the sandbox
688
- * but MUST NOT appear on `globalThis`.
438
+ * When specified with `as const`, the tool's execute function's state
439
+ * will have queueTool() and invokeTool() constrained to only the
440
+ * declared tools (compile-time type safety).
441
+ *
442
+ * At runtime, attempts to call unlisted items will throw an error.
443
+ *
444
+ * This is required for packed tools to ensure namespace isolation.
445
+ * For unpacked tools, it's optional but recommended for clarity.
689
446
  *
690
447
  * @example
691
- * ```ts
692
- * globals: {
693
- * console: { log: (...args) => logger.info(...args) },
694
- * getMessage: async () => '...',
695
- * }
448
+ * ```typescript
449
+ * // Type-safe: only 'validate_input' and 'format_output' allowed
450
+ * defineTool({
451
+ * description: 'Process data using helper tools',
452
+ * uses: ['validate_input', 'format_output'] as const,
453
+ * execute: async (state) => {
454
+ * state.queueTool('validate_input', { data: '...' }); // ✓ OK
455
+ * state.queueTool('unknown_tool', {}); // ✗ TypeScript error
456
+ * // ...
457
+ * },
458
+ * });
459
+ *
460
+ * // Without `as const`, any tool name is allowed (backward compatible)
461
+ * defineTool({
462
+ * description: 'Flexible tool',
463
+ * uses: ['some_tool'],
464
+ * execute: async (state) => {
465
+ * state.queueTool('any_tool', {}); // ✓ OK (no type constraint)
466
+ * },
467
+ * });
696
468
  * ```
697
469
  */
698
- globals?: Record<string, unknown>;
470
+ uses?: Uses;
699
471
  /**
700
- * Source language. TypeScript source has its types erased before evaluation;
701
- * no type checking is performed.
472
+ * The name of an argument whose value is a short, human-readable description
473
+ * of what this tool call is doing — for example `"fixing index.html"`.
702
474
  *
703
- * @default 'typescript'
704
- */
705
- language?: 'javascript' | 'typescript';
706
- /**
707
- * Maximum sandbox heap in bytes. Exceeding this settles the handle with
708
- * `status: 'memory'`. Runtime default is implementation-defined and
709
- * documented per runtime.
710
- */
711
- memoryLimitBytes?: number;
712
- /**
713
- * Label used in stack traces and error `specifier` fields.
475
+ * When set, the `tool_call_started` hook and the `tool_call_started` thread
476
+ * event wait until **just this argument** has finished streaming from the
477
+ * model — not the whole tool call — and include its value as `progress`. This
478
+ * lets a UI show what a tool is about to do before a large argument (such as
479
+ * a file's `content`) finishes generating.
714
480
  *
715
- * @default '<runCode>'
716
- */
717
- filename?: string;
718
- /**
719
- * Optional host-side sink for the built-in `report` bridge.
481
+ * When unset, `tool_call_started` fires as soon as the tool call appears in
482
+ * the model stream (its name is known, arguments may still be incomplete).
720
483
  *
721
- * When provided, the runtime installs a `report` global that forwards values
722
- * to this callback. Reported values are also appended to the live
723
- * {@link CodeExecution.reports} view and to the final
724
- * {@link CodeExecutionResult.reports}.
484
+ * Declare the named argument early in the `args` schema and keep it short so
485
+ * it completes quickly. If the model never emits it, `tool_call_started`
486
+ * still fires once the tool call finishes, with `progress` undefined.
487
+ *
488
+ * @example
489
+ * ```typescript
490
+ * defineTool({
491
+ * description: 'Write a file to the workspace',
492
+ * progressArgument: 'description',
493
+ * args: z.object({
494
+ * description: z.string().describe('e.g. "writing index.html"'),
495
+ * path: z.string(),
496
+ * content: z.string(),
497
+ * }),
498
+ * execute: async (state, args) => { ... },
499
+ * });
500
+ * ```
725
501
  */
726
- report?: (value: unknown) => void;
502
+ progressArgument?: string;
727
503
  }
728
504
  /**
729
- * Handle returned by {@link ThreadState.runCode}.
505
+ * Tool definition object returned by defineTool().
730
506
  *
731
- * `CodeExecution` is a `PromiseLike<CodeExecutionResult>` — `await` the handle
732
- * to get the final result. The handle also exposes controls that only make
733
- * sense while the run is in flight: caller-initiated termination and a live
734
- * view of values emitted via the `report` bridge.
507
+ * Contains all the metadata and implementation needed to register
508
+ * and execute a tool.
509
+ *
510
+ * @template State - The state type (defaults to ThreadState)
511
+ * @template Args - The Zod schema for tool arguments, or null for no args
512
+ * @template Tenvs - The Zod schema for thread environment variables, or null
513
+ * @template Uses - Readonly array of tool names this tool can invoke
735
514
  */
736
- interface CodeExecution extends PromiseLike<CodeExecutionResult> {
515
+ interface ToolDefinition<State = ThreadState, Args extends ToolArgs | null = null, Tenvs extends ToolTenvs | null = null, Uses extends readonly string[] = readonly string[]> {
516
+ /** Description of what the tool does (shown to the LLM). */
517
+ description: string;
518
+ /** Zod schema for validating tool arguments, or null for no args. */
519
+ args: Args;
520
+ /** The tool implementation function. */
521
+ execute: UsesAwareExecute<State, Args, Uses>;
522
+ /** Declared variables for this tool. */
523
+ variables: VariableDefinition[];
737
524
  /**
738
- * Stop the run. Idempotent: subsequent calls are no-ops.
525
+ * @deprecated Use `variables` instead.
526
+ * Zod schema for thread environment variables, or null if none.
527
+ */
528
+ tenvs: Tenvs;
529
+ /**
530
+ * Where this tool is executed:
531
+ * - 'local': Execute locally by the execution engine (default)
532
+ * - 'provider': Executed by the LLM provider, results come in response
533
+ */
534
+ executionMode?: 'local' | 'provider';
535
+ /**
536
+ * Which provider executes this tool (when executionMode='provider').
537
+ */
538
+ executionProvider?: string;
539
+ /**
540
+ * Explicit list of tools, prompts, or agents this tool can call.
739
541
  *
740
- * Settles the handle with `status: 'terminated'` at the next ECMAScript
741
- * yield point (microtask boundary, async operation, or runtime interrupt).
742
- * Typically a few milliseconds and SHOULD be ≤ 50 ms under normal host load;
743
- * a pure-synchronous tight loop may run until the runtime's own safety cap
744
- * fires. When `reason` is provided, it surfaces in `error.message`.
542
+ * When specified with `as const`, TypeScript constrains queueTool()
543
+ * and invokeTool() at compile time. At runtime, attempts to call
544
+ * unlisted items throw an error.
545
+ *
546
+ * This is required for packed tools to ensure namespace isolation.
547
+ * For unpacked tools, it's optional but recommended for clarity.
548
+ *
549
+ * Items can be:
550
+ * - Simple names: Resolve within current namespace
551
+ * - Qualified names (e.g., 'other_pkg:agent'): Cross-package entry point
745
552
  */
746
- terminate(reason?: string): void;
747
- /** `true` until the handle settles. */
748
- readonly running: boolean;
553
+ uses?: Uses;
749
554
  /**
750
- * Snapshot of values emitted via the `report` bridge so far, in call order.
751
- * The same values appear in {@link CodeExecutionResult.reports} once the
752
- * run ends.
555
+ * The name of an argument carrying a short, human-readable description of what
556
+ * this tool call is doing (e.g. `"fixing index.html"`). Controls when the
557
+ * `tool_call_started` hook/event fires — see {@link DefineToolOptions.progressArgument}.
753
558
  */
754
- readonly reports: readonly unknown[];
559
+ progressArgument?: string;
755
560
  }
756
561
  /**
757
- * Outcome classification for {@link CodeExecutionResult.status}.
562
+ * Defines a tool that agents can call during execution.
758
563
  *
759
- * - `success` — Module evaluated and the configured export resolved.
760
- * - `error` — Uncaught runtime error inside the sandbox.
761
- * - `memory` — `memoryLimitBytes` exceeded.
762
- * - `terminated` — Caller called `handle.terminate()`, or the runtime's own
763
- * safety cap fired. `error.message` distinguishes the two (including any
764
- * `reason` the caller passed).
765
- * - `link_error` — Module graph failed to link (unknown specifier, missing
766
- * named export, parse error).
564
+ * Tools are the primary way agents interact with external systems.
565
+ * Each tool has a description (shown to the LLM), optional argument
566
+ * schema (validated at runtime), an implementation function, and
567
+ * optional variable requirements.
568
+ *
569
+ * @example
570
+ * ```typescript
571
+ * import { defineTool } from '@standardagents/spec';
572
+ * import { z } from 'zod';
573
+ *
574
+ * // Tool with arguments
575
+ * export default defineTool({
576
+ * description: 'Search the knowledge base for relevant information',
577
+ * args: z.object({
578
+ * query: z.string().describe('Search query'),
579
+ * limit: z.number().optional().describe('Max results'),
580
+ * }),
581
+ * execute: async (state, args) => {
582
+ * const results = await search(args.query, args.limit);
583
+ * return { status: 'success', result: JSON.stringify(results) };
584
+ * },
585
+ * });
586
+ *
587
+ * // Tool without arguments
588
+ * export default defineTool({
589
+ * description: 'Get the current server time',
590
+ * execute: async (state) => {
591
+ * return { status: 'success', result: new Date().toISOString() };
592
+ * },
593
+ * });
594
+ *
595
+ * // Tool with declared variables
596
+ * export default defineTool({
597
+ * description: 'Search through uploaded files',
598
+ * args: z.object({ query: z.string() }),
599
+ * execute: async (state, args) => ({ status: 'success', result: 'done' }),
600
+ * variables: [
601
+ * {
602
+ * name: 'VECTOR_STORE_ID',
603
+ * type: 'text',
604
+ * required: true,
605
+ * description: 'OpenAI Vector Store ID',
606
+ * },
607
+ * ],
608
+ * });
609
+ *
610
+ * // Provider-executed tool (e.g., OpenAI built-in tools)
611
+ * export default defineTool({
612
+ * description: 'Generate images using DALL-E',
613
+ * args: z.object({ prompt: z.string() }),
614
+ * execute: async () => ({ status: 'success', result: 'Handled by provider' }),
615
+ * executionMode: 'provider',
616
+ * executionProvider: 'openai',
617
+ * });
618
+ * ```
619
+ *
620
+ * @param options - Tool definition options
621
+ * @returns A tool definition object
767
622
  */
768
- type CodeExecutionStatus = 'success' | 'error' | 'memory' | 'terminated' | 'link_error';
769
623
  /**
770
- * A single captured `console.*` call from inside the sandbox.
624
+ * Validate a tool name does not contain reserved characters.
625
+ * Tools are typically defined without a name field (they get the filename),
626
+ * but this can be called by build tools that assign names.
627
+ */
628
+ declare function validateToolName(name: string): void;
629
+ declare function defineTool<State = ThreadState, Args extends ToolArgs | null = null, Tenvs extends ToolTenvs | null = null, Uses extends readonly string[] = readonly string[]>(options: DefineToolOptions<State, Args, Tenvs, Uses>): ToolDefinition<State, Args, Tenvs, Uses>;
630
+
631
+ /**
632
+ * Effect definition types for Standard Agents.
771
633
  *
772
- * Only populated when the runtime installs a capturing `console` (typically
773
- * when the caller does not provide one via `options.globals`).
634
+ * Effects are scheduled operations that run outside the tool execution context.
635
+ * They enable implementation-specific side effects with optional delay support,
636
+ * leveraging whichever scheduling mechanism the runtime provides.
637
+ *
638
+ * Unlike tools, effects:
639
+ * - Do not return results to the LLM
640
+ * - Can be delayed for future execution
641
+ * - Run independently of the conversation flow
642
+ * - Are ideal for notifications, cleanup, and async operations
643
+ *
644
+ * @module
774
645
  */
775
- interface CodeExecutionLog {
776
- level: 'log' | 'info' | 'warn' | 'error' | 'debug';
777
- /** Marshaled argument values, deep-cloned from the sandbox. */
778
- args: unknown[];
779
- /** Millisecond timestamp when the call occurred. */
780
- timestamp: number;
781
- }
646
+
782
647
  /**
783
- * Error surfaced when a {@link CodeExecutionResult} does not have
784
- * `status: 'success'`.
648
+ * Effect function signature.
785
649
  *
786
- * Host-side stack frames MUST NOT leak into this object — only sandbox
787
- * frames are included.
650
+ * Effects are async functions that receive a ThreadState and
651
+ * optionally validated arguments. Unlike tools, they return void
652
+ * since results are not included in the conversation.
653
+ *
654
+ * @template State - The state type (defaults to ThreadState)
655
+ * @template Args - The Zod schema for effect arguments, or null for no args
788
656
  */
789
- interface CodeExecutionError {
790
- name: string;
791
- message: string;
792
- stack?: string;
793
- /** Module specifier that failed to link (for `link_error`). */
794
- specifier?: string;
795
- /** Source filename associated with `line` and `column`, when available. */
796
- filename?: string;
797
- /** 1-based line number in source, when available. */
798
- line?: number;
799
- /** 1-based column number in source, when available. */
800
- column?: number;
801
- }
657
+ type Effect<State = ThreadState, Args extends ToolArgs | null = null> = Args extends ToolArgs ? (state: State, args: z.infer<Args>) => Promise<void> | void : (state: State) => Promise<void> | void;
802
658
  /**
803
- * Result of a {@link ThreadState.runCode} call.
659
+ * Return type of defineEffect function.
804
660
  *
805
- * The sandbox has two result channels and both may be used in the same run:
806
- * - **Configured export** → marshaled into `result` on success.
807
- * - **Bridge reports** → appended to `reports` in call order as they are emitted.
661
+ * A tuple containing:
662
+ * - Effect description string
663
+ * - Argument schema (or null)
664
+ * - Effect implementation function
808
665
  */
809
- interface CodeExecutionResult {
810
- /** Outcome classification — see {@link CodeExecutionStatus}. */
811
- status: CodeExecutionStatus;
812
- /**
813
- * Resolved configured export (after awaiting top-level promises).
814
- * Omitted when `status !== 'success'`. `undefined` is a valid success result
815
- * when the configured export resolves to `undefined`.
816
- */
817
- result?: unknown;
818
- /**
819
- * Values emitted through the built-in `report` bridge when
820
- * `options.report` is supplied, in call order. Empty when unused.
821
- */
822
- reports: unknown[];
823
- /** Captured `console.*` calls (see {@link CodeExecutionLog}). Empty when the caller supplies its own `console`. */
824
- logs: CodeExecutionLog[];
825
- /** Error detail. Present iff `status` is not `'success'`. */
826
- error?: CodeExecutionError;
827
- /** Wall-clock execution time in milliseconds. */
828
- durationMs: number;
829
- /** Peak sandbox heap in bytes, when the engine can measure it. */
830
- memoryUsedBytes?: number;
831
- }
666
+ type EffectDefinition<State = ThreadState, Args extends ToolArgs | null = null> = [string, Args, Effect<State, Args>];
832
667
  /**
833
- * Execution-specific state available during agent execution.
668
+ * Record of a scheduled effect.
834
669
  *
835
- * This is present when a thread is actively executing (during tool calls,
836
- * hook invocations, etc.) and null when accessing a thread at rest
837
- * (from endpoints, external code, etc.).
670
+ * Returned by getScheduledEffects() to inspect pending effects.
838
671
  */
839
- interface ExecutionState {
840
- /** Current flow ID (unique per execution) */
841
- readonly flowId: string;
842
- /** Current side in dual_ai agents ('a' or 'b') */
843
- readonly currentSide: 'a' | 'b';
844
- /** Total steps executed in this flow */
845
- readonly stepCount: number;
846
- /** Steps executed by side A */
847
- readonly sideAStepCount: number;
848
- /** Steps executed by side B */
849
- readonly sideBStepCount: number;
850
- /** Whether execution has been stopped */
851
- readonly stopped: boolean;
852
- /** Which side initiated the stop (if stopped) */
853
- readonly stoppedBy?: 'a' | 'b';
854
- /** Message history loaded for current execution */
855
- readonly messageHistory: Message[];
856
- /**
857
- * Force a specific side to play the next turn.
858
- *
859
- * Only valid for dual_ai agents. Has no effect on ai_human agents.
860
- *
861
- * @param side - The side to force ('a' or 'b')
862
- */
863
- forceTurn(side: 'a' | 'b'): void;
864
- /**
865
- * Stop the current execution.
866
- *
867
- * Signals the execution loop to terminate after the current operation
868
- * completes. Does not abort in-progress LLM calls.
869
- */
870
- stop(): void;
871
- /**
872
- * Abort signal for cancellation.
873
- *
874
- * Can be used to abort fetch requests or other async operations
875
- * when the execution is cancelled.
876
- */
877
- readonly abortSignal: AbortSignal;
878
- /**
879
- * Path from root prompt to current prompt.
880
- *
881
- * Tracks the current position in the prompt hierarchy:
882
- * - At root level: `['my_prompt']`
883
- * - Inside a sub-prompt: `['my_prompt', 'sub_prompt']`
884
- * - After handoff: `['new_agent_prompt']`
885
- *
886
- * This allows tools and hooks to understand their execution context depth.
887
- */
888
- readonly promptPath: string[];
672
+ interface ScheduledEffect {
673
+ /** Unique identifier for this scheduled effect. */
674
+ id: string;
675
+ /** Name of the effect to execute. */
676
+ name: string;
677
+ /** Arguments to pass to the effect handler. */
678
+ args: Record<string, unknown>;
679
+ /** When the effect is scheduled to run (microseconds since epoch). */
680
+ scheduledAt: number;
681
+ /** When the effect was created (microseconds since epoch). */
682
+ createdAt: number;
889
683
  }
890
684
  /**
891
- * Display/redaction classification for thread-scoped environment values.
685
+ * Define an effect with arguments.
892
686
  *
893
- * `secret` values should be redacted from tool output and logs. `text` values
894
- * may be displayed.
687
+ * @param description - Description of what the effect does
688
+ * @param args - Zod schema for validating effect arguments
689
+ * @param handler - The effect implementation function
690
+ * @returns A tuple containing the effect definition
895
691
  */
896
- type EnvValueType = 'text' | 'secret';
692
+ declare function defineEffect<State = ThreadState, Args extends ToolArgs = ToolArgs>(description: string, args: Args, handler: Effect<State, Args>): EffectDefinition<State, Args>;
897
693
  /**
898
- * Options for {@link ThreadState.setEnv}.
694
+ * Define an effect without arguments.
695
+ *
696
+ * @param description - Description of what the effect does
697
+ * @param handler - The effect implementation function
698
+ * @returns A tuple containing the effect definition
899
699
  */
900
- interface SetEnvOptions {
901
- /**
902
- * Display/redaction classification for this value.
903
- *
904
- * Defaults to the existing type for that key, or `secret` for new keys.
905
- */
906
- type?: EnvValueType;
700
+ declare function defineEffect<State = ThreadState>(description: string, handler: Effect<State, null>): EffectDefinition<State, null>;
701
+
702
+ /**
703
+ * Agent Skills — instance-global skill store types.
704
+ *
705
+ * Skills follow the Agent Skills standard (https://agentskills.io): a folder
706
+ * whose root SKILL.md opens with YAML frontmatter carrying a required `name`
707
+ * (lowercase kebab, ≤64 chars) and `description` (≤1024 chars), optionally
708
+ * accompanied by scripts, references, and assets.
709
+ *
710
+ * Runtimes store skills server-side as a GLOBAL, instance-wide library:
711
+ * installed once, visible to every thread, nothing persisted on a client
712
+ * machine. Progressive disclosure is the contract — agents see only each
713
+ * skill's name + description until a skill is judged applicable, at which
714
+ * point they load its SKILL.md body (and, when needed, read or execute its
715
+ * bundled files).
716
+ */
717
+ /** Registry view of an installed skill (metadata only — no file contents). */
718
+ interface SkillMetadata {
719
+ /** Kebab-case identifier from SKILL.md frontmatter. */
720
+ name: string;
721
+ /** What the skill does and when to use it (from frontmatter). */
722
+ description: string;
723
+ /** Optional version string from frontmatter. */
724
+ version?: string;
725
+ /** Disabled skills stay installed but are hidden from agents. */
726
+ enabled: boolean;
727
+ /** Relative paths of the skill's files (always includes SKILL.md). */
728
+ files: string[];
729
+ /** Unix seconds of the last install/update. */
730
+ updatedAt?: number;
731
+ }
732
+ /** A file being installed into a skill (relative path + full text). */
733
+ interface SkillFileInput {
734
+ path: string;
735
+ content: string;
907
736
  }
908
737
  /**
909
- * Options for {@link ThreadState.stopSession}.
738
+ * ThreadState surface for the global skill library. All operations hit the
739
+ * instance-wide store — there is no per-thread skill state beyond what a
740
+ * thread chooses to keep in its own key-value store.
910
741
  */
911
- interface StopSessionOptions {
912
- /**
913
- * Result text returned to a blocking parent/subagent caller.
914
- *
915
- * This does not send a parent message by itself. Use `notifyParent` when the
916
- * session stop should also queue an explicit parent notification.
917
- */
918
- result?: string;
919
- /**
920
- * Optional silent message to queue to this thread's parent before stopping.
921
- *
922
- * Omit this for no parent-message side effect.
923
- */
924
- notifyParent?: string;
742
+ interface SkillsNamespace {
743
+ /** Installed skills (enabled only, unless includeDisabled). */
744
+ list(options?: {
745
+ includeDisabled?: boolean;
746
+ }): Promise<SkillMetadata[]>;
747
+ /** A skill's metadata plus its SKILL.md source (null when not installed). */
748
+ get(name: string): Promise<{
749
+ metadata: SkillMetadata;
750
+ skillMd: string;
751
+ } | null>;
752
+ /** Read one bundled file's text (null when the skill or file is missing). */
753
+ readFile(name: string, path: string): Promise<string | null>;
925
754
  /**
926
- * Optional parent registry status to set before stopping. Runtimes may ignore
927
- * this when the thread has no parent registry entry.
928
- *
929
- * Omit this for no status side effect.
755
+ * Install (or replace) a skill from its file set. The file set must include
756
+ * a root SKILL.md with valid frontmatter; the skill's identity comes from
757
+ * that frontmatter, never from a caller-supplied name.
930
758
  */
931
- status?: string;
759
+ install(files: SkillFileInput[]): Promise<SkillMetadata>;
760
+ /** Enable/disable an installed skill. Returns false when not installed. */
761
+ setEnabled(name: string, enabled: boolean): Promise<boolean>;
762
+ /** Uninstall a skill entirely. Returns false when not installed. */
763
+ remove(name: string): Promise<boolean>;
932
764
  }
765
+
933
766
  /**
934
- * The unified interface for all thread operations.
935
- *
936
- * ThreadState provides a consistent API for interacting with threads
937
- * regardless of context - whether from tools during execution, hooks,
938
- * or HTTP endpoints. The same interface is used throughout, with
939
- * execution-specific state available when applicable.
940
- *
941
- * @example
942
- * ```typescript
943
- * // In a tool
944
- * export default defineTool(
945
- * 'Send a greeting',
946
- * z.object({ name: z.string() }),
947
- * async (state, args) => {
948
- * // Access thread identity
949
- * console.log(`Thread: ${state.threadId}`);
950
- *
951
- * // Check execution state
952
- * if (state.execution?.stepCount > 10) {
953
- * state.execution.stop();
954
- * }
955
- *
956
- * // Emit custom event
957
- * state.emit('greeting', { name: args.name });
767
+ * Thread state types for Standard Agents.
958
768
  *
959
- * return { status: 'success', result: `Hello, ${args.name}!` };
960
- * }
961
- * );
962
- * ```
769
+ * ThreadState is the unified interface for all thread operations.
770
+ * It provides access to thread identity, messages, logs, resource loading,
771
+ * tool invocation, event emission, and execution state.
963
772
  *
964
- * @example
965
- * ```typescript
966
- * // In an endpoint
967
- * export default defineThreadEndpoint(async (req, state, params) => {
968
- * // state.execution is null (not executing)
969
- * const { messages } = await state.getMessages({ limit: 50 });
970
- * return Response.json({ messages, params });
971
- * });
972
- * ```
773
+ * @module
973
774
  */
775
+
974
776
  /**
975
- * A request forwarded from a server-side tool to a connected client (CLI) for
976
- * local execution. Used by "forwarded" tools where the agent loop runs remotely
977
- * but the actual operation (read a file, run a command) must happen on the
978
- * user's own machine.
777
+ * Metadata about a thread.
778
+ *
779
+ * This represents the core identity of a thread, separate from its
780
+ * operational state. Thread metadata is immutable after creation.
979
781
  */
980
- interface ClientToolRequest {
981
- /** Logical operation name the client knows how to perform (e.g. `read_file`). */
982
- tool: string;
983
- /** Arguments for the operation. */
984
- args?: Record<string, unknown>;
985
- /**
986
- * Human-readable description of what this call will do, shown to the user when
987
- * the client needs to ask for permission. Presence signals the operation may
988
- * carry side effects.
989
- */
990
- requestPermission?: string;
991
- /** Risk level 1 (safe) – 5 (dangerous). Clients slide auto-accept on this. */
992
- risk?: number;
993
- /** Milliseconds to wait for the client before failing the call. */
994
- timeoutMs?: number;
995
- }
996
782
  /**
997
- * The result a connected client returns for a {@link ClientToolRequest}.
783
+ * The profile of the user a thread belongs to, as exposed by
784
+ * {@link ThreadState.user}. Identity fields only — never credentials.
998
785
  */
999
- interface ClientToolResponse {
1000
- /** Whether the client successfully performed the operation. */
1001
- ok: boolean;
1002
- /** Text result (e.g. file contents, command output). */
1003
- result?: string;
1004
- /** Error message when `ok` is false (including a user denial). */
1005
- error?: string;
1006
- /** Optional structured payload the tool can inspect. */
1007
- data?: unknown;
786
+ interface ThreadUser {
787
+ id: string;
788
+ username: string;
789
+ /** 'admin' | 'user' | 'api' in the reference runtime. */
790
+ role: string;
791
+ /** Explicit permission grants (runtime-defined strings), if any. */
792
+ permissions?: string[] | null;
793
+ email?: string | null;
794
+ display_name?: string | null;
795
+ avatar_url?: string | null;
1008
796
  }
1009
- interface ThreadState {
1010
- /** Unique thread identifier */
1011
- readonly threadId: string;
797
+ interface ThreadMetadata {
798
+ /** Unique identifier for the thread */
799
+ id: string;
1012
800
  /** Agent that owns this thread */
1013
- readonly agentId: string;
801
+ agent_id: string;
1014
802
  /** User associated with this thread (if any) */
1015
- readonly userId: string | null;
1016
- /** Thread creation timestamp (microseconds since epoch) */
1017
- readonly createdAt: number;
1018
- /**
1019
- * Registry of subagent child instances owned by this thread.
1020
- *
1021
- * Includes both resumable and non-resumable instances.
1022
- */
1023
- readonly children: SubagentRegistryEntry[];
1024
- /**
1025
- * Termination timestamp (microseconds) if this thread has been terminated.
1026
- * Null when the thread is active.
1027
- */
1028
- readonly terminated: number | null;
1029
- /**
1030
- * Arguments supplied when this thread was created or invoked.
1031
- *
1032
- * For resumable subagent child threads, this is the durable
1033
- * `subagent_create.arguments` object restored from child thread
1034
- * metadata/properties. Both child sides see the same object. Runtimes also
1035
- * expose these keys to prompt variable interpolation, including included
1036
- * prompts.
1037
- */
1038
- readonly arguments: Record<string, unknown>;
1039
- /**
1040
- * Get messages from the thread.
1041
- *
1042
- * @param options - Query options (limit, offset, order, etc.)
1043
- * @returns Messages and pagination info
1044
- */
1045
- getMessages(options?: GetMessagesOptions): Promise<MessagesResult>;
1046
- /**
1047
- * Get a single message by ID.
1048
- *
1049
- * @param messageId - The message ID
1050
- * @returns The message, or null if not found
1051
- */
1052
- getMessage(messageId: string): Promise<Message | null>;
1053
- /**
1054
- * Inject a message into the thread.
1055
- *
1056
- * Creates a new message in the conversation history. This can be used
1057
- * to add context, simulate user input, or insert assistant responses.
1058
- *
1059
- * @param message - The message to inject
1060
- * @returns The created message
1061
- */
1062
- injectMessage(message: InjectMessageInput): Promise<Message>;
1063
- /**
1064
- * Update an existing message.
1065
- *
1066
- * @param messageId - The message ID
1067
- * @param updates - The updates to apply
1068
- * @returns The updated message
1069
- */
1070
- updateMessage(messageId: string, updates: MessageUpdates): Promise<Message>;
1071
- /**
1072
- * Delete a message from the thread.
1073
- *
1074
- * Removes the message and any associated attachments from storage.
1075
- * Tool call results are cascade-deleted when their parent message is removed.
1076
- *
1077
- * @param messageId - The message ID to delete
1078
- * @returns true if the message was found and deleted, false if not found
1079
- */
1080
- deleteMessage(messageId: string): Promise<boolean>;
1081
- /**
1082
- * Queue a message for delivery on the thread's next step.
1083
- *
1084
- * If the thread is executing, the message is delivered before the next LLM call.
1085
- * If idle, queueing forces execution by the queued side.
1086
- */
1087
- queueMessage(message: QueueMessageInput): Promise<void>;
1088
- /**
1089
- * Load a model definition by name.
1090
- *
1091
- * @param name - The model name
1092
- * @returns The model definition
1093
- * @throws If the model is not found
1094
- */
1095
- loadModel<T = unknown>(name: string): Promise<T>;
1096
- /**
1097
- * Load a prompt definition by name.
1098
- *
1099
- * @param name - The prompt name
1100
- * @returns The prompt definition
1101
- * @throws If the prompt is not found
1102
- */
1103
- loadPrompt<T = unknown>(name: string): Promise<T>;
1104
- /**
1105
- * Load an agent definition by name.
1106
- *
1107
- * @param name - The agent name
1108
- * @returns The agent definition
1109
- * @throws If the agent is not found
1110
- */
1111
- loadAgent<T = unknown>(name: string): Promise<T>;
1112
- /**
1113
- * Get available prompt names.
1114
- *
1115
- * @returns Array of prompt names that can be loaded
1116
- */
1117
- getPromptNames(): string[];
1118
- /**
1119
- * Get available agent names.
1120
- *
1121
- * @returns Array of agent names that can be loaded
1122
- */
1123
- getAgentNames(): string[];
1124
- /**
1125
- * Get available model names.
1126
- *
1127
- * @returns Array of model names that can be loaded
1128
- */
1129
- getModelNames(): string[];
1130
- /**
1131
- * Get a child thread by its subagent reference ID.
1132
- *
1133
- * @param referenceId - Child thread UUID
1134
- * @returns Child ThreadState or null if not found
1135
- */
1136
- getChildThread(referenceId: string): Promise<ThreadState | null>;
1137
- /**
1138
- * Get this thread's parent thread (if any).
1139
- *
1140
- * @returns Parent ThreadState, or null for top-level threads
1141
- */
1142
- getParentThread(): Promise<ThreadState | null>;
1143
- /**
1144
- * Resolve an environment value for this thread by property name.
1145
- *
1146
- * Resolution order:
1147
- * 1. Thread
1148
- * 2. Agent definition
1149
- * 3. Prompt definition
1150
- * 4. User account
1151
- * 5. AgentBuilder instance
1152
- *
1153
- * @throws If the variable is not defined in any source
1154
- */
1155
- env(propertyName: string): Promise<string>;
1156
- /**
1157
- * Resolve the display/redaction type for an environment value.
1158
- *
1159
- * Resolution follows the same order as `env()`:
1160
- * thread, agent definition, prompt definition, user account, AgentBuilder instance.
1161
- * User-account and AgentBuilder-instance env stores may persist per-key
1162
- * `text` / `secret` metadata; agent/prompt defaults remain `secret` unless
1163
- * overridden by thread state.
1164
- *
1165
- * Values marked `secret` should be redacted from tool output and logs.
1166
- * Values marked `text` may be shown. Unknown values default to `secret`.
1167
- */
1168
- envType(propertyName: string): Promise<EnvValueType>;
1169
- /**
1170
- * Set a thread-scoped environment variable.
1171
- *
1172
- * This writes to thread env storage and propagates the updated thread env
1173
- * to all active descendant threads recursively. Terminated descendants are
1174
- * not modified.
1175
- *
1176
- * @param propertyName - Environment variable name
1177
- * @param value - Environment variable value
1178
- * @param options - Optional display/redaction classification for this value
1179
- */
1180
- setEnv(propertyName: string, value: string, options?: SetEnvOptions): Promise<void>;
803
+ user_id: string | null;
804
+ /** Creation timestamp (microseconds since epoch) */
805
+ created_at: number;
806
+ }
807
+ /**
808
+ * Registry entry for a subagent child thread.
809
+ */
810
+ interface SubagentRegistryEntry {
811
+ /** Child thread UUID used as stable reference address */
812
+ reference: string;
813
+ /** Child agent name */
814
+ name: string;
815
+ /** Child agent title (human-readable) */
816
+ title?: string;
817
+ /** Tool description shown to the parent LLM */
818
+ description: string;
819
+ /** Whether this subagent instance is resumable */
820
+ resumable?: boolean;
821
+ /** Whether parent execution blocks on this subagent */
822
+ blocking?: boolean;
823
+ /** Optional human-readable thread name (for example from `name:` tag) */
824
+ threadName?: string;
1181
825
  /**
1182
- * Queue a silent message to this thread's parent, if one exists.
1183
- *
1184
- * This is useful for explicit child-to-parent escalation paths where tools or
1185
- * hooks decide when the parent should be notified.
1186
- *
1187
- * Implementations SHOULD tag the queued message with the current thread's
1188
- * `subagent_id` metadata so the parent can attribute the notification.
826
+ * Initial argument values supplied when the child was created.
1189
827
  *
1190
- * @throws If content is empty
828
+ * For resumable subagents, these values persist for the lifetime of the
829
+ * child thread and are visible to both child sides. Runtimes SHOULD source
830
+ * this object from the receiving side's prompt argument schema. The registry
831
+ * copy is parent-visible metadata; the durable child-side source SHOULD live
832
+ * with the child thread metadata/properties and be restored into
833
+ * `ThreadState.arguments` during execution and endpoint access. Top-level
834
+ * keys SHOULD also be exposed to prompt variable interpolation for whichever
835
+ * child side is currently rendering.
1191
836
  */
1192
- notifyParent(content: string): Promise<void>;
837
+ initialArguments?: Record<string, unknown>;
838
+ /** Spawn group identifier used for grouping instances created together */
839
+ spawnGroupId?: string;
840
+ /** Instance creation timestamp (microseconds) */
841
+ createdAt?: number;
842
+ /** Current status (`running`, `idle`, `terminated`, or custom text) */
843
+ status: string;
844
+ /** How this child reports information back to its parent thread */
845
+ parentCommunication?: 'implicit' | 'explicit';
846
+ }
847
+ /**
848
+ * Options for retrieving messages.
849
+ */
850
+ interface GetMessagesOptions {
851
+ /** Maximum number of messages to return */
852
+ limit?: number;
853
+ /** Number of messages to skip */
854
+ offset?: number;
855
+ /** Sort order ('asc' for oldest first, 'desc' for newest first) */
856
+ order?: 'asc' | 'desc';
857
+ /** Include silent messages (not shown in UI) */
858
+ includeSilent?: boolean;
859
+ /** Maximum nesting depth for sub-prompt messages */
860
+ maxDepth?: number;
861
+ }
862
+ /**
863
+ * Result of a message query.
864
+ */
865
+ interface MessagesResult {
866
+ /** Array of messages */
867
+ messages: Message[];
868
+ /** Total number of messages matching the query */
869
+ total: number;
870
+ /** Whether there are more messages available */
871
+ hasMore: boolean;
872
+ }
873
+ /**
874
+ * A message in the thread conversation.
875
+ */
876
+ interface Message {
877
+ /** Unique message identifier */
878
+ id: string;
879
+ /** Message role */
880
+ role: 'system' | 'user' | 'assistant' | 'tool';
881
+ /** Message content (null for tool calls without text) */
882
+ content: string | null;
883
+ /** Tool name (for tool result messages) */
884
+ name?: string | null;
885
+ /** JSON-encoded array of tool calls (for assistant messages) */
886
+ tool_calls?: string | null;
887
+ /** Tool call ID (for tool result messages) */
888
+ tool_call_id?: string | null;
889
+ /** Creation timestamp (microseconds since epoch) */
890
+ created_at: number;
891
+ /** Parent message ID (for sub-prompt messages) */
892
+ parent_id?: string | null;
893
+ /** Nesting depth (0 for top-level messages) */
894
+ depth?: number;
895
+ /** Whether this message is silent (not shown in UI) */
896
+ silent?: boolean;
1193
897
  /**
1194
- * Update this thread's status in its parent registry entry.
1195
- *
1196
- * Useful for long-lived watcher/observer children that want to expose their
1197
- * current state without sending a parent message.
1198
- *
1199
- * This is a no-op when the thread has no parent registry entry.
898
+ * Custom metadata.
1200
899
  *
1201
- * @throws If status is empty
900
+ * Runtimes may attach lifecycle metadata for synthesized status messages
901
+ * (for example: `status_kind`, `subagent_event`). Message APIs may also
902
+ * mark send-message and durable queue entries with `queued: true` until
903
+ * they are injected into stored history.
1202
904
  */
1203
- setStatus(status: string): Promise<void>;
905
+ metadata?: Record<string, unknown>;
906
+ /** Message processing status */
907
+ status?: 'pending' | 'completed' | 'failed' | null;
908
+ /** Tool execution status (for tool result messages) */
909
+ tool_status?: 'success' | 'error' | null;
910
+ /** Subagent reference UUID associated with this message */
911
+ subagent_id?: string | null;
912
+ /** Subagent agent name projected from runtime registry (when available) */
913
+ subagent_name?: string | null;
914
+ /** Subagent agent title projected from runtime registry (when available) */
915
+ subagent_title?: string | null;
916
+ /** Subagent description projected from runtime registry (when available) */
917
+ subagent_description?: string | null;
918
+ /** Subagent status projected from runtime registry (when available) */
919
+ subagent_status?: string | null;
920
+ /** Whether the associated subagent is resumable (when available) */
921
+ subagent_resumable?: boolean | null;
922
+ /** Whether the associated subagent is blocking (when available) */
923
+ subagent_blocking?: boolean | null;
924
+ /** Optional subagent instance thread name (when available) */
925
+ subagent_thread_name?: string | null;
926
+ /** Spawn group identifier for related subagent instances (when available) */
927
+ subagent_spawn_group_id?: string | null;
928
+ }
929
+ /**
930
+ * Input for injecting a new message.
931
+ */
932
+ interface InjectMessageInput {
933
+ /** Message role */
934
+ role: 'user' | 'assistant' | 'system';
935
+ /** Message content */
936
+ content: string;
937
+ /** Whether to hide from UI */
938
+ silent?: boolean;
939
+ /** Custom metadata */
940
+ metadata?: Record<string, unknown>;
941
+ }
942
+ /**
943
+ * Input for queueing a message for delivery on the thread's next step.
944
+ *
945
+ * Role mapping follows dual_ai conventions:
946
+ * - `assistant` maps to side_a
947
+ * - `user` maps to side_b
948
+ */
949
+ interface QueueMessageInput {
950
+ /** Message role (`user` queues side_b perspective, `assistant` queues side_a perspective) */
951
+ role: 'user' | 'assistant';
952
+ /** Message content */
953
+ content: string;
954
+ /** Optional file attachments (new files or existing refs) */
955
+ attachments?: Array<ToolAttachment | AttachmentRef>;
956
+ /** Whether to hide the queued message from normal UI display */
957
+ silent?: boolean;
958
+ /** Optional structured metadata */
959
+ metadata?: Record<string, unknown>;
960
+ }
961
+ /**
962
+ * Updates to apply to an existing message.
963
+ */
964
+ interface MessageUpdates {
965
+ /** New content */
966
+ content?: string;
967
+ /** Updated metadata (merged with existing) */
968
+ metadata?: Record<string, unknown>;
969
+ }
970
+ /**
971
+ * A streamed fragment of an assistant message's *visible content*.
972
+ *
973
+ * Always broadcast (no opt-in). Clients accumulate `chunk`s by `message_id` to
974
+ * render the answer as it generates; the authoritative final content still
975
+ * arrives separately as a persisted message. Clients must not discard an
976
+ * already-painted draft solely because a retry/reconnect exposes another id:
977
+ * retain keyed drafts or treat the id as a reconciliation alias until the
978
+ * terminal message record atomically supersedes it.
979
+ */
980
+ interface ThreadMessageChunkEvent {
981
+ type: 'message_chunk';
982
+ /** The assistant message these fragments belong to. */
983
+ message_id: string;
984
+ /** Message depth: 0 = top-level thread, 1+ = subagent. */
985
+ depth: number;
986
+ /** The next fragment of visible content. */
987
+ chunk: string;
988
+ }
989
+ /**
990
+ * A streamed fragment of a model's *internal reasoning* (chain-of-thought).
991
+ *
992
+ * OPT-IN. Unlike content, reasoning is private by default: it is only sent to
993
+ * sockets that explicitly subscribe by connecting with the
994
+ * {@link THREAD_STREAM_REASONING_PARAM} query parameter set to a truthy value
995
+ * (e.g. `?reasoning=1`). Standard SDK consumers therefore never receive it
996
+ * unless they opt in.
997
+ *
998
+ * Reasoning is ephemeral *display* output: it is streamed for live presentation
999
+ * only and is NOT persisted as part of the assistant message content, so it
1000
+ * cannot be replayed from message history — a client that wants it must be
1001
+ * subscribed while the turn runs.
1002
+ */
1003
+ interface ThreadReasoningChunkEvent {
1004
+ type: 'reasoning_chunk';
1005
+ /** The assistant message this reasoning accompanies. */
1006
+ message_id: string;
1007
+ /** Message depth: 0 = top-level thread, 1+ = subagent. */
1008
+ depth: number;
1009
+ /** The next fragment of internal reasoning. */
1010
+ chunk: string;
1011
+ }
1012
+ /**
1013
+ * Query-parameter name a client sets (truthy) on the thread stream WebSocket to
1014
+ * opt into receiving {@link ThreadReasoningChunkEvent}s. Absent/falsey means the
1015
+ * server never emits reasoning to that socket.
1016
+ */
1017
+ declare const THREAD_STREAM_REASONING_PARAM = "reasoning";
1018
+ /**
1019
+ * Storage location identifier.
1020
+ *
1021
+ * Implementations define their own storage identifiers (e.g., 'local', 'cloud', 's3').
1022
+ * The spec does not mandate specific storage backends.
1023
+ */
1024
+ type FileStorage = string;
1025
+ /**
1026
+ * Record representing a file in the thread's file system.
1027
+ */
1028
+ interface FileRecord {
1029
+ /** File path (relative to thread root) */
1030
+ path: string;
1031
+ /** File name */
1032
+ name: string;
1033
+ /** MIME type */
1034
+ mimeType: string;
1035
+ /** Storage location */
1036
+ storage: FileStorage;
1037
+ /** File size in bytes */
1038
+ size: number;
1039
+ /** Whether this is a directory */
1040
+ isDirectory: boolean;
1041
+ /** Custom metadata */
1042
+ metadata?: Record<string, unknown>;
1043
+ /** Image width in pixels (if applicable) */
1044
+ width?: number;
1045
+ /** Image height in pixels (if applicable) */
1046
+ height?: number;
1047
+ /** Creation timestamp */
1048
+ createdAt?: number;
1049
+ /** Last modified timestamp */
1050
+ updatedAt?: number;
1051
+ }
1052
+ /**
1053
+ * Options for writing a file.
1054
+ */
1055
+ interface WriteFileOptions {
1056
+ /** Custom metadata to attach to the file */
1057
+ metadata?: Record<string, unknown>;
1058
+ /** Image width in pixels (if applicable) */
1059
+ width?: number;
1060
+ /** Image height in pixels (if applicable) */
1061
+ height?: number;
1062
+ }
1063
+ /**
1064
+ * Result of reading a directory.
1065
+ */
1066
+ interface ReaddirResult {
1067
+ /** Files and directories in the path */
1068
+ entries: FileRecord[];
1069
+ }
1070
+ /**
1071
+ * Statistics about the thread's file system.
1072
+ */
1073
+ interface FileStats {
1074
+ /** Total number of files */
1075
+ fileCount: number;
1076
+ /** Total number of directories */
1077
+ directoryCount: number;
1078
+ /** Total size in bytes */
1079
+ totalSize: number;
1080
+ }
1081
+ /**
1082
+ * Result of a grep search.
1083
+ */
1084
+ interface GrepResult {
1085
+ /** File path */
1086
+ path: string;
1087
+ /** Matching lines */
1088
+ matches: Array<{
1089
+ line: number;
1090
+ content: string;
1091
+ }>;
1092
+ }
1093
+ /**
1094
+ * Result of a find operation.
1095
+ */
1096
+ interface FindResult {
1097
+ /** Matching file paths */
1098
+ paths: string[];
1099
+ }
1100
+ /**
1101
+ * Options for streaming file reads.
1102
+ */
1103
+ interface ReadFileStreamOptions {
1204
1104
  /**
1205
- * Force the current agent session to stop successfully.
1206
- *
1207
- * This is stronger than `state.execution.stop()`: it marks the active session
1208
- * as terminal for subagent/session-boundary purposes, without requiring a
1209
- * `sessionStop` tool call. By default it has no parent-message or status side
1210
- * effects. Pass `notifyParent` and/or `status` when those effects are desired.
1105
+ * Abort signal for cancellation.
1211
1106
  *
1212
- * @throws If called outside an active execution context
1107
+ * When signaled, the stream stops yielding new chunks.
1108
+ * Already-yielded chunks remain valid.
1213
1109
  */
1214
- stopSession(options?: StopSessionOptions): Promise<void>;
1110
+ signal?: AbortSignal;
1111
+ }
1112
+ /**
1113
+ * A chunk of file data from a streaming read.
1114
+ */
1115
+ interface FileChunk {
1116
+ /** Raw binary data for this chunk */
1117
+ data: Uint8Array;
1118
+ /** 0-based index of this chunk */
1119
+ index: number;
1120
+ /** Total number of chunks (1 for small files) */
1121
+ totalChunks: number;
1122
+ /** Whether this is the final chunk */
1123
+ isLast: boolean;
1124
+ }
1125
+ /**
1126
+ * Options passed to {@link ThreadState.runCode}.
1127
+ *
1128
+ * Code execution is strictly capability-based: the sandbox starts with no
1129
+ * ambient capabilities (no `fs`, no `fetch`, no `console`, no host globals).
1130
+ * Every capability the sandbox needs must be bridged in explicitly through
1131
+ * `imports` or `globals`.
1132
+ *
1133
+ * Deadlines are **not** an option. Callers impose their own by calling
1134
+ * `handle.terminate()` on the returned {@link CodeExecution}.
1135
+ *
1136
+ * See the [Code Execution specification](https://standardagentspec.com/0.1.0/specification/threads/code-execution)
1137
+ * for the full contract.
1138
+ */
1139
+ interface CodeExecutionOptions {
1215
1140
  /**
1216
- * Queue a tool for execution.
1217
- *
1218
- * If the thread is currently executing, the tool is added to the
1219
- * execution queue. If not, this starts a new execution with the
1220
- * tool call.
1141
+ * Export to execute from the evaluated module and arguments to pass.
1221
1142
  *
1222
- * @param toolName - Name of the tool to invoke
1223
- * @param args - Arguments to pass to the tool
1224
- */
1225
- queueTool(toolName: string, args: Record<string, unknown>): void;
1226
- /**
1227
- * Invoke a tool directly and wait for the result.
1143
+ * By default, runtimes execute the module's `default` export with no
1144
+ * arguments. If the selected export is a function, it is called with
1145
+ * `args` and the returned value or promise is used as the run result. If the
1146
+ * selected export is not a function, `args` MUST be omitted or empty and the
1147
+ * export value itself becomes the result.
1228
1148
  *
1229
- * If the thread is not currently executing, this creates a minimal
1230
- * execution context for the tool. Unlike queueTool, this blocks
1231
- * until the tool completes.
1149
+ * @default { fn: 'default', args: [] }
1232
1150
  *
1233
- * @param toolName - Name of the tool to invoke
1234
- * @param args - Arguments to pass to the tool
1235
- * @returns The tool result
1151
+ * @example
1152
+ * ```ts
1153
+ * execute: { fn: 'increment', args: [100] }
1154
+ * ```
1236
1155
  */
1237
- invokeTool(toolName: string, args: Record<string, unknown>): Promise<ToolResult>;
1156
+ execute?: {
1157
+ /** Export name to execute. Use `'default'` for the default export. */
1158
+ fn?: string;
1159
+ /** Arguments passed to the selected export when it is a function. */
1160
+ args?: unknown[];
1161
+ };
1238
1162
  /**
1239
- * Schedule an effect for future execution.
1163
+ * Map of bare module specifier → named exports exposed to the sandbox.
1240
1164
  *
1241
- * Effects are executed outside the current conversation flow, making them
1242
- * ideal for delayed operations like sending notifications, triggering
1243
- * webhooks, or running cleanup tasks.
1165
+ * Only bare specifiers resolve from `imports` (e.g., `'fs'`,
1166
+ * `'@scope/pkg'`). Relative specifiers resolve only from `modules`; URL
1167
+ * (`'https://…'`) imports MUST fail at link time.
1244
1168
  *
1245
- * @param name - Name of the effect to schedule (must exist in agents/effects/)
1246
- * @param args - Arguments to pass to the effect handler
1247
- * @param delay - Delay in milliseconds before execution (default: 0 for immediate)
1248
- * @returns Unique ID of the scheduled effect (UUID)
1169
+ * The key `default` within a namespace becomes that module's default export.
1249
1170
  *
1250
1171
  * @example
1251
- * ```typescript
1252
- * // Schedule a reminder email in 30 minutes
1253
- * const effectId = await state.scheduleEffect(
1254
- * 'send_reminder_email',
1255
- * { to: 'user@example.com', subject: 'Reminder' },
1256
- * 30 * 60 * 1000
1257
- * );
1172
+ * ```ts
1173
+ * imports: {
1174
+ * fs: { readFile: (path) => state.readFile(path) },
1175
+ * supervisor: { report: (payload) => telemetry.push(payload) },
1176
+ * }
1258
1177
  * ```
1259
1178
  */
1260
- scheduleEffect(name: string, args: Record<string, unknown>, delay?: number): Promise<string>;
1261
- /**
1262
- * Get scheduled effects for this thread.
1263
- *
1264
- * Returns effects that are pending execution. Can optionally filter
1265
- * by effect name.
1266
- *
1267
- * @param name - Optional effect name to filter by
1268
- * @returns Array of scheduled effect records
1269
- */
1270
- getScheduledEffects(name?: string): Promise<ScheduledEffect[]>;
1179
+ imports?: Record<string, Record<string, unknown>>;
1271
1180
  /**
1272
- * Cancel a scheduled effect.
1273
- *
1274
- * Cancels a pending effect before it executes. Has no effect if the effect
1275
- * has already executed, was already canceled, or doesn't exist. Runtimes may
1276
- * retain canceled effects in inspection history.
1181
+ * Additional relative ES modules available to the sandbox.
1277
1182
  *
1278
- * @param id - The effect ID returned by scheduleEffect
1279
- * @returns true if the effect was found and canceled, false otherwise
1183
+ * Keys are relative module specifiers from the module graph root, such as
1184
+ * `'./helpers.js'` or `'./lib/math.js'`. Entry source imports resolve from
1185
+ * `filename` when one is supplied. Entry and module source may import sibling
1186
+ * or parent modules with `./` and `../` specifiers when those imports resolve
1187
+ * within the supplied module graph. Values are JavaScript or TypeScript module
1188
+ * source. Use this when a caller wants the entry source to import local files
1189
+ * while still keeping all modules inside the sandbox.
1280
1190
  */
1281
- removeScheduledEffect(id: string): Promise<boolean>;
1191
+ modules?: Record<string, string>;
1282
1192
  /**
1283
- * Trigger an agent to run on this thread.
1284
- *
1285
- * Starts a new agent execution asynchronously. This is useful for effects
1286
- * that need to trigger background agent work (e.g., running a finalizer
1287
- * agent after a delay).
1288
- *
1289
- * The agent runs in the background - this method returns immediately
1290
- * after queuing the execution.
1193
+ * Map of identifier → value installed on the sandbox's module scope.
1291
1194
  *
1292
- * @param agentName - Name of the agent to run (must exist in agents/agents/)
1293
- * @returns Promise that resolves when the execution is queued
1195
+ * These identifiers are resolvable as free variables inside the sandbox
1196
+ * but MUST NOT appear on `globalThis`.
1294
1197
  *
1295
1198
  * @example
1296
- * ```typescript
1297
- * // In an effect handler, trigger a finalizer agent
1298
- * await state.runAgent('booking_finalizer');
1199
+ * ```ts
1200
+ * globals: {
1201
+ * console: { log: (...args) => logger.info(...args) },
1202
+ * getMessage: async () => '...',
1203
+ * }
1299
1204
  * ```
1300
1205
  */
1301
- runAgent(agentName: string): Promise<void>;
1206
+ globals?: Record<string, unknown>;
1302
1207
  /**
1303
- * Soft-terminate the thread.
1208
+ * Source language. TypeScript source has its types erased before evaluation;
1209
+ * no type checking is performed.
1304
1210
  *
1305
- * Implementations should mark the thread as terminated, abort in-flight
1306
- * execution, and reject subsequent execution/message queue operations.
1211
+ * @default 'typescript'
1307
1212
  */
1308
- terminate(): Promise<void>;
1213
+ language?: 'javascript' | 'typescript';
1309
1214
  /**
1310
- * Emit a custom event to connected clients.
1311
- *
1312
- * Events are sent via WebSocket to any connected clients. Use this
1313
- * for real-time updates, progress notifications, or custom data.
1215
+ * Maximum sandbox heap in bytes. Exceeding this settles the handle with
1216
+ * `status: 'memory'`. Runtime default is implementation-defined and
1217
+ * documented per runtime.
1218
+ */
1219
+ memoryLimitBytes?: number;
1220
+ /**
1221
+ * Label used in stack traces and error `specifier` fields.
1314
1222
  *
1315
- * @param event - Event name
1316
- * @param data - Event data (must be JSON-serializable)
1223
+ * @default '<runCode>'
1317
1224
  */
1318
- emit(event: string, data: unknown): void;
1225
+ filename?: string;
1319
1226
  /**
1320
- * Execution-scoped key-value data available while the current agent run is
1321
- * being assembled and executed.
1227
+ * Optional host-side sink for the built-in `report` bridge.
1322
1228
  *
1323
- * Runtimes use this bag for values shared between tools/hooks/effects during
1324
- * one execution. Invocation or creation arguments belong in
1325
- * {@link ThreadState.arguments}, not in `context`.
1229
+ * When provided, the runtime installs a `report` global that forwards values
1230
+ * to this callback. Reported values are also appended to the live
1231
+ * {@link CodeExecution.reports} view and to the final
1232
+ * {@link CodeExecutionResult.reports}.
1233
+ */
1234
+ report?: (value: unknown) => void;
1235
+ }
1236
+ /**
1237
+ * Handle returned by {@link ThreadState.runCode}.
1238
+ *
1239
+ * `CodeExecution` is a `PromiseLike<CodeExecutionResult>` — `await` the handle
1240
+ * to get the final result. The handle also exposes controls that only make
1241
+ * sense while the run is in flight: caller-initiated termination and a live
1242
+ * view of values emitted via the `report` bridge.
1243
+ */
1244
+ interface CodeExecution extends PromiseLike<CodeExecutionResult> {
1245
+ /**
1246
+ * Stop the run. Idempotent: subsequent calls are no-ops.
1326
1247
  *
1327
- * User mutations persist across tool calls within a single execution, but are
1328
- * not durable after execution ends unless the runtime rehydrates a value from
1329
- * another durable source. For durable storage, use
1330
- * {@link ThreadState.getValue} and {@link ThreadState.setValue}, the file
1331
- * system, or external storage.
1248
+ * Settles the handle with `status: 'terminated'` at the next ECMAScript
1249
+ * yield point (microtask boundary, async operation, or runtime interrupt).
1250
+ * Typically a few milliseconds and SHOULD be ≤ 50 ms under normal host load;
1251
+ * a pure-synchronous tight loop may run until the runtime's own safety cap
1252
+ * fires. When `reason` is provided, it surfaces in `error.message`.
1332
1253
  */
1333
- context: Record<string, unknown>;
1254
+ terminate(reason?: string): void;
1255
+ /** `true` until the handle settles. */
1256
+ readonly running: boolean;
1334
1257
  /**
1335
- * Read a value from the thread's durable key-value store.
1258
+ * Snapshot of values emitted via the `report` bridge so far, in call order.
1259
+ * The same values appear in {@link CodeExecutionResult.reports} once the
1260
+ * run ends.
1261
+ */
1262
+ readonly reports: readonly unknown[];
1263
+ }
1264
+ /**
1265
+ * Outcome classification for {@link CodeExecutionResult.status}.
1266
+ *
1267
+ * - `success` — Module evaluated and the configured export resolved.
1268
+ * - `error` — Uncaught runtime error inside the sandbox.
1269
+ * - `memory` — `memoryLimitBytes` exceeded.
1270
+ * - `terminated` — Caller called `handle.terminate()`, or the runtime's own
1271
+ * safety cap fired. `error.message` distinguishes the two (including any
1272
+ * `reason` the caller passed).
1273
+ * - `link_error` — Module graph failed to link (unknown specifier, missing
1274
+ * named export, parse error).
1275
+ */
1276
+ type CodeExecutionStatus = 'success' | 'error' | 'memory' | 'terminated' | 'link_error';
1277
+ /**
1278
+ * A single captured `console.*` call from inside the sandbox.
1279
+ *
1280
+ * Only populated when the runtime installs a capturing `console` (typically
1281
+ * when the caller does not provide one via `options.globals`).
1282
+ */
1283
+ interface CodeExecutionLog {
1284
+ level: 'log' | 'info' | 'warn' | 'error' | 'debug';
1285
+ /** Marshaled argument values, deep-cloned from the sandbox. */
1286
+ args: unknown[];
1287
+ /** Millisecond timestamp when the call occurred. */
1288
+ timestamp: number;
1289
+ }
1290
+ /**
1291
+ * Error surfaced when a {@link CodeExecutionResult} does not have
1292
+ * `status: 'success'`.
1293
+ *
1294
+ * Host-side stack frames MUST NOT leak into this object — only sandbox
1295
+ * frames are included.
1296
+ */
1297
+ interface CodeExecutionError {
1298
+ name: string;
1299
+ message: string;
1300
+ stack?: string;
1301
+ /** Module specifier that failed to link (for `link_error`). */
1302
+ specifier?: string;
1303
+ /** Source filename associated with `line` and `column`, when available. */
1304
+ filename?: string;
1305
+ /** 1-based line number in source, when available. */
1306
+ line?: number;
1307
+ /** 1-based column number in source, when available. */
1308
+ column?: number;
1309
+ }
1310
+ /**
1311
+ * Result of a {@link ThreadState.runCode} call.
1312
+ *
1313
+ * The sandbox has two result channels and both may be used in the same run:
1314
+ * - **Configured export** → marshaled into `result` on success.
1315
+ * - **Bridge reports** → appended to `reports` in call order as they are emitted.
1316
+ */
1317
+ interface CodeExecutionResult {
1318
+ /** Outcome classification — see {@link CodeExecutionStatus}. */
1319
+ status: CodeExecutionStatus;
1320
+ /**
1321
+ * Resolved configured export (after awaiting top-level promises).
1322
+ * Omitted when `status !== 'success'`. `undefined` is a valid success result
1323
+ * when the configured export resolves to `undefined`.
1324
+ */
1325
+ result?: unknown;
1326
+ /**
1327
+ * Values emitted through the built-in `report` bridge when
1328
+ * `options.report` is supplied, in call order. Empty when unused.
1329
+ */
1330
+ reports: unknown[];
1331
+ /** Captured `console.*` calls (see {@link CodeExecutionLog}). Empty when the caller supplies its own `console`. */
1332
+ logs: CodeExecutionLog[];
1333
+ /** Error detail. Present iff `status` is not `'success'`. */
1334
+ error?: CodeExecutionError;
1335
+ /** Wall-clock execution time in milliseconds. */
1336
+ durationMs: number;
1337
+ /** Peak sandbox heap in bytes, when the engine can measure it. */
1338
+ memoryUsedBytes?: number;
1339
+ }
1340
+ /**
1341
+ * Execution-specific state available during agent execution.
1342
+ *
1343
+ * This is present when a thread is actively executing (during tool calls,
1344
+ * hook invocations, etc.) and null when accessing a thread at rest
1345
+ * (from endpoints, external code, etc.).
1346
+ */
1347
+ interface ExecutionState {
1348
+ /** Current flow ID (unique per execution) */
1349
+ readonly flowId: string;
1350
+ /** Current side in dual_ai agents ('a' or 'b') */
1351
+ readonly currentSide: 'a' | 'b';
1352
+ /** Total steps executed in this flow */
1353
+ readonly stepCount: number;
1354
+ /** Steps executed by side A */
1355
+ readonly sideAStepCount: number;
1356
+ /** Steps executed by side B */
1357
+ readonly sideBStepCount: number;
1358
+ /** Whether execution has been stopped */
1359
+ readonly stopped: boolean;
1360
+ /** Which side initiated the stop (if stopped) */
1361
+ readonly stoppedBy?: 'a' | 'b';
1362
+ /** Message history loaded for current execution */
1363
+ readonly messageHistory: Message[];
1364
+ /**
1365
+ * Force a specific side to play the next turn.
1336
1366
  *
1337
- * Values written with {@link ThreadState.setValue} persist across executions,
1338
- * tool calls, hook invocations, and endpoint requests for the lifetime of
1339
- * the thread. The key-value store is one of two ways to store persistent
1340
- * data on a thread, alongside the file system.
1367
+ * Only valid for dual_ai agents. Has no effect on ai_human agents.
1341
1368
  *
1342
- * Returns `null` when no value has been set for the given key. Values are
1343
- * returned exactly as they were stored; runtimes MUST preserve JSON-equivalent
1344
- * structure (objects, arrays, strings, numbers, booleans, `null`).
1369
+ * @param side - The side to force ('a' or 'b')
1370
+ */
1371
+ forceTurn(side: 'a' | 'b'): void;
1372
+ /**
1373
+ * Stop the current execution.
1345
1374
  *
1346
- * @param key - The key to read
1347
- * @returns The stored value, or `null` if the key has no value
1375
+ * Signals the execution loop to terminate after the current operation
1376
+ * completes. Does not abort in-progress LLM calls.
1377
+ */
1378
+ stop(): void;
1379
+ /**
1380
+ * Abort signal for cancellation.
1348
1381
  *
1349
- * @example
1350
- * ```typescript
1351
- * const count = (await state.getValue<number>('invocation_count')) ?? 0;
1352
- * await state.setValue('invocation_count', count + 1);
1353
- * ```
1382
+ * Can be used to abort fetch requests or other async operations
1383
+ * when the execution is cancelled.
1354
1384
  */
1355
- getValue<T = unknown>(key: string): Promise<T | null>;
1385
+ readonly abortSignal: AbortSignal;
1356
1386
  /**
1357
- * Write a value to the thread's durable key-value store.
1387
+ * Path from root prompt to current prompt.
1358
1388
  *
1359
- * The value persists across executions for the lifetime of the thread.
1360
- * Passing `null` or `undefined` deletes the key. Values MUST be
1361
- * JSON-serializable; implementations MAY reject non-serializable values.
1389
+ * Tracks the current position in the prompt hierarchy:
1390
+ * - At root level: `['my_prompt']`
1391
+ * - Inside a sub-prompt: `['my_prompt', 'sub_prompt']`
1392
+ * - After handoff: `['new_agent_prompt']`
1362
1393
  *
1363
- * Durable values are **not** automatically copied between threads when
1364
- * subagents are spawned — each thread maintains its own key-value store.
1394
+ * This allows tools and hooks to understand their execution context depth.
1395
+ */
1396
+ readonly promptPath: string[];
1397
+ }
1398
+ /**
1399
+ * Display/redaction classification for thread-scoped environment values.
1400
+ *
1401
+ * `secret` values should be redacted from tool output and logs. `text` values
1402
+ * may be displayed.
1403
+ */
1404
+ type EnvValueType = 'text' | 'secret';
1405
+ /**
1406
+ * Options for {@link ThreadState.setEnv}.
1407
+ */
1408
+ interface SetEnvOptions {
1409
+ /**
1410
+ * Display/redaction classification for this value.
1365
1411
  *
1366
- * @param key - The key to write
1367
- * @param value - The value to store (JSON-serializable), or `null`/`undefined`
1368
- * to delete the key
1412
+ * Defaults to the existing type for that key, or `secret` for new keys.
1369
1413
  */
1370
- setValue(key: string, value: unknown): Promise<void>;
1414
+ type?: EnvValueType;
1415
+ }
1416
+ /**
1417
+ * Options for {@link ThreadState.stopSession}.
1418
+ */
1419
+ interface StopSessionOptions {
1371
1420
  /**
1372
- * Read a value from the account-wide durable key-value store of the user
1373
- * this thread belongs to.
1374
- *
1375
- * The user store is the account-scoped sibling of the thread store: values
1376
- * persist across every thread the user owns on the instance (e.g. a coding
1377
- * client's registry of registered machines and projects). Returns `null`
1378
- * when the thread has no associated user or the key has no value.
1421
+ * Result text returned to a blocking parent/subagent caller.
1379
1422
  *
1380
- * @param key - The key to read
1423
+ * This does not send a parent message by itself. Use `notifyParent` when the
1424
+ * session stop should also queue an explicit parent notification.
1381
1425
  */
1382
- getUserValue<T = unknown>(key: string): Promise<T | null>;
1426
+ result?: string;
1383
1427
  /**
1384
- * Write a value to the account-wide durable key-value store of the user
1385
- * this thread belongs to.
1386
- *
1387
- * Passing `null` or `undefined` deletes the key. Values MUST be
1388
- * JSON-serializable. Implementations MUST reject the write when the thread
1389
- * has no associated user.
1428
+ * Optional silent message to queue to this thread's parent before stopping.
1390
1429
  *
1391
- * @param key - The key to write
1392
- * @param value - The value to store (JSON-serializable), or `null`/`undefined`
1393
- * to delete the key
1430
+ * Omit this for no parent-message side effect.
1394
1431
  */
1395
- setUserValue(key: string, value: unknown): Promise<void>;
1432
+ notifyParent?: string;
1396
1433
  /**
1397
- * List entries in the account-wide durable key-value store of the user this
1398
- * thread belongs to, optionally filtered by key prefix. Returns an empty
1399
- * list when the thread has no associated user.
1434
+ * Optional parent registry status to set before stopping. Runtimes may ignore
1435
+ * this when the thread has no parent registry entry.
1400
1436
  *
1401
- * @param options - Optional `prefix`, `limit` (default 100), and `offset`
1437
+ * Omit this for no status side effect.
1402
1438
  */
1403
- listUserValues(options?: {
1404
- prefix?: string | null;
1405
- limit?: number;
1406
- offset?: number;
1407
- }): Promise<{
1408
- entries: Array<{
1409
- key: string;
1410
- value: unknown;
1411
- updated_at: number;
1412
- }>;
1413
- total: number;
1414
- }>;
1439
+ status?: string;
1440
+ }
1441
+ /**
1442
+ * The unified interface for all thread operations.
1443
+ *
1444
+ * ThreadState provides a consistent API for interacting with threads
1445
+ * regardless of context - whether from tools during execution, hooks,
1446
+ * or HTTP endpoints. The same interface is used throughout, with
1447
+ * execution-specific state available when applicable.
1448
+ *
1449
+ * @example
1450
+ * ```typescript
1451
+ * // In a tool
1452
+ * export default defineTool(
1453
+ * 'Send a greeting',
1454
+ * z.object({ name: z.string() }),
1455
+ * async (state, args) => {
1456
+ * // Access thread identity
1457
+ * console.log(`Thread: ${state.threadId}`);
1458
+ *
1459
+ * // Check execution state
1460
+ * if (state.execution?.stepCount > 10) {
1461
+ * state.execution.stop();
1462
+ * }
1463
+ *
1464
+ * // Emit custom event
1465
+ * state.emit('greeting', { name: args.name });
1466
+ *
1467
+ * return { status: 'success', result: `Hello, ${args.name}!` };
1468
+ * }
1469
+ * );
1470
+ * ```
1471
+ *
1472
+ * @example
1473
+ * ```typescript
1474
+ * // In an endpoint
1475
+ * export default defineThreadEndpoint(async (req, state, params) => {
1476
+ * // state.execution is null (not executing)
1477
+ * const { messages } = await state.getMessages({ limit: 50 });
1478
+ * return Response.json({ messages, params });
1479
+ * });
1480
+ * ```
1481
+ */
1482
+ interface ThreadState {
1483
+ /** Unique thread identifier */
1484
+ readonly threadId: string;
1485
+ /** Agent that owns this thread */
1486
+ readonly agentId: string;
1487
+ /** User associated with this thread (if any) */
1488
+ readonly userId: string | null;
1489
+ /** Thread creation timestamp (microseconds since epoch) */
1490
+ readonly createdAt: number;
1415
1491
  /**
1416
- * The profile of the user this thread belongs to, or `null` when the thread
1417
- * has no associated user (e.g. unauthenticated local development).
1418
- *
1419
- * Lets tools and hooks personalize or gate behavior per user — e.g. an
1420
- * entitlement hook enforcing a per-user concurrency limit, or a tool
1421
- * addressing the user by name. Never includes credentials.
1492
+ * Registry of subagent child instances owned by this thread.
1422
1493
  *
1423
- * @example
1424
- * ```typescript
1425
- * const user = await state.user();
1426
- * if (user?.email) await notifyBillingService(user.email);
1427
- * ```
1494
+ * Includes both resumable and non-resumable instances.
1428
1495
  */
1429
- user(): Promise<ThreadUser | null>;
1496
+ readonly children: SubagentRegistryEntry[];
1430
1497
  /**
1431
- * The instance-global Agent Skills library (https://agentskills.io format).
1432
- *
1433
- * Skills are installed once and visible to every thread; their files live
1434
- * server-side (never on a client machine). Agents should follow progressive
1435
- * disclosure: browse metadata via `skills.list()`, and load a skill's
1436
- * SKILL.md body with `skills.get()` only when it is applicable to the task.
1437
- *
1438
- * @example
1439
- * ```typescript
1440
- * const available = await state.skills.list();
1441
- * const skill = await state.skills.get('pdf-processing');
1442
- * const script = await state.skills.readFile('pdf-processing', 'scripts/extract.py');
1443
- * ```
1498
+ * Termination timestamp (microseconds) if this thread has been terminated.
1499
+ * Null when the thread is active.
1444
1500
  */
1445
- skills: SkillsNamespace;
1501
+ readonly terminated: number | null;
1446
1502
  /**
1447
- * Forward a tool operation to the connected client (e.g. the coding CLI) and
1448
- * await its result. The agent loop runs remotely, but operations like reading
1449
- * a file or running a shell command must execute on the user's own machine;
1450
- * `callClient` bridges that gap over the thread's `bridge` WebSocket.
1451
- *
1452
- * Resolves with `{ ok: false, error }` (rather than throwing) when no client
1453
- * is connected, the request times out, or the user denies permission, so
1454
- * forwarded tools can surface a normal tool error to the model.
1503
+ * Arguments supplied when this thread was created or invoked.
1455
1504
  *
1456
- * @param request - The operation, args, and optional permission/risk metadata
1457
- * @returns The client's response
1505
+ * For resumable subagent child threads, this is the durable
1506
+ * `subagent_create.arguments` object restored from child thread
1507
+ * metadata/properties. Both child sides see the same object. Runtimes also
1508
+ * expose these keys to prompt variable interpolation, including included
1509
+ * prompts.
1458
1510
  */
1459
- callClient(request: ClientToolRequest): Promise<ClientToolResponse>;
1511
+ readonly arguments: Record<string, unknown>;
1460
1512
  /**
1461
- * Write a file to the thread's file system.
1462
- *
1463
- * Large files (>1.75MB) are automatically chunked for storage.
1513
+ * Get messages from the thread.
1464
1514
  *
1465
- * @param path - File path (relative to thread root)
1466
- * @param data - File content as ArrayBuffer or string
1467
- * @param mimeType - MIME type of the file
1468
- * @param options - Optional metadata and dimensions
1469
- * @returns The created file record
1515
+ * @param options - Query options (limit, offset, order, etc.)
1516
+ * @returns Messages and pagination info
1470
1517
  */
1471
- writeFile(path: string, data: ArrayBuffer | string, mimeType: string, options?: WriteFileOptions): Promise<FileRecord>;
1518
+ getMessages(options?: GetMessagesOptions): Promise<MessagesResult>;
1472
1519
  /**
1473
- * Read a file from the thread's file system.
1520
+ * Get a single message by ID.
1474
1521
  *
1475
- * @param path - File path
1476
- * @returns File content as ArrayBuffer, or null if not found
1522
+ * @param messageId - The message ID
1523
+ * @returns The message, or null if not found
1477
1524
  */
1478
- readFile(path: string): Promise<ArrayBuffer | null>;
1525
+ getMessage(messageId: string): Promise<Message | null>;
1479
1526
  /**
1480
- * Stream a file from the thread's file system in chunks.
1481
- *
1482
- * For large files (>1.75MB), this yields one chunk at a time, enabling
1483
- * memory-efficient access without loading the entire file. Small files
1484
- * are yielded as a single chunk.
1485
- *
1486
- * Returns null if the file is not found or stored externally (S3, R2, URL).
1527
+ * Inject a message into the thread.
1487
1528
  *
1488
- * @param path - File path
1489
- * @param options - Optional streaming options (abort signal)
1490
- * @returns Async iterable of file chunks, or null if not found/external
1529
+ * Creates a new message in the conversation history. This can be used
1530
+ * to add context, simulate user input, or insert assistant responses.
1491
1531
  *
1492
- * @example
1493
- * ```typescript
1494
- * const stream = await state.readFileStream('/uploads/video.mp4');
1495
- * if (stream) {
1496
- * for await (const chunk of stream) {
1497
- * console.log(`Chunk ${chunk.index + 1}/${chunk.totalChunks}`);
1498
- * // Process chunk.data (Uint8Array)
1499
- * }
1500
- * }
1501
- * ```
1532
+ * @param message - The message to inject
1533
+ * @returns The created message
1502
1534
  */
1503
- readFileStream(path: string, options?: ReadFileStreamOptions): Promise<AsyncIterable<FileChunk> | null>;
1535
+ injectMessage(message: InjectMessageInput): Promise<Message>;
1504
1536
  /**
1505
- * Get metadata about a file.
1537
+ * Update an existing message.
1506
1538
  *
1507
- * @param path - File path
1508
- * @returns File record, or null if not found
1539
+ * @param messageId - The message ID
1540
+ * @param updates - The updates to apply
1541
+ * @returns The updated message
1509
1542
  */
1510
- statFile(path: string): Promise<FileRecord | null>;
1543
+ updateMessage(messageId: string, updates: MessageUpdates): Promise<Message>;
1511
1544
  /**
1512
- * List contents of a directory.
1545
+ * Delete a message from the thread.
1513
1546
  *
1514
- * @param path - Directory path
1515
- * @returns Directory entries
1547
+ * Removes the message and any associated attachments from storage.
1548
+ * Tool call results are cascade-deleted when their parent message is removed.
1549
+ *
1550
+ * @param messageId - The message ID to delete
1551
+ * @returns true if the message was found and deleted, false if not found
1516
1552
  */
1517
- readdirFile(path: string): Promise<ReaddirResult>;
1553
+ deleteMessage(messageId: string): Promise<boolean>;
1518
1554
  /**
1519
- * Delete a file.
1555
+ * Queue a message for delivery on the thread's next step.
1520
1556
  *
1521
- * @param path - File path
1557
+ * If the thread is executing, the message is delivered before the next LLM call.
1558
+ * If idle, queueing forces execution by the queued side.
1522
1559
  */
1523
- unlinkFile(path: string): Promise<void>;
1560
+ queueMessage(message: QueueMessageInput): Promise<void>;
1524
1561
  /**
1525
- * Create a directory.
1562
+ * Load a model definition by name.
1526
1563
  *
1527
- * @param path - Directory path
1528
- * @returns The created directory record
1564
+ * @param name - The model name
1565
+ * @returns The model definition
1566
+ * @throws If the model is not found
1529
1567
  */
1530
- mkdirFile(path: string): Promise<FileRecord>;
1568
+ loadModel<T = unknown>(name: string): Promise<T>;
1531
1569
  /**
1532
- * Remove a directory.
1570
+ * Load a prompt definition by name.
1533
1571
  *
1534
- * @param path - Directory path (must be empty)
1572
+ * @param name - The prompt name
1573
+ * @returns The prompt definition
1574
+ * @throws If the prompt is not found
1535
1575
  */
1536
- rmdirFile(path: string): Promise<void>;
1576
+ loadPrompt<T = unknown>(name: string): Promise<T>;
1537
1577
  /**
1538
- * Move or rename a file or directory.
1539
- *
1540
- * Relocates the entry at `sourcePath` to `destinationPath`. Works for
1541
- * files and directories; moving a directory relocates its entire subtree,
1542
- * preserving the relative layout of its contents. The destination must not
1543
- * already exist, and a directory cannot be moved into itself or one of its
1544
- * own descendants.
1578
+ * Load an agent definition by name.
1545
1579
  *
1546
- * @param sourcePath - Existing file or directory path
1547
- * @param destinationPath - New path (must not already exist)
1548
- * @returns The moved entry's record at its new path
1580
+ * @param name - The agent name
1581
+ * @returns The agent definition
1582
+ * @throws If the agent is not found
1549
1583
  */
1550
- moveFile(sourcePath: string, destinationPath: string): Promise<FileRecord>;
1584
+ loadAgent<T = unknown>(name: string): Promise<T>;
1551
1585
  /**
1552
- * Rename a file or directory in place.
1553
- *
1554
- * Keeps the entry in its current parent directory and changes only its
1555
- * final path segment. `newName` must be a bare file name with no path
1556
- * separators. To relocate an entry to a different directory, use
1557
- * {@link ThreadState.moveFile} instead.
1586
+ * Get available prompt names.
1558
1587
  *
1559
- * @param path - Existing file or directory path
1560
- * @param newName - New name (no path separators)
1561
- * @returns The renamed entry's record at its new path
1588
+ * @returns Array of prompt names that can be loaded
1562
1589
  */
1563
- renameFile(path: string, newName: string): Promise<FileRecord>;
1590
+ getPromptNames(): string[];
1564
1591
  /**
1565
- * Get overall file system statistics.
1592
+ * Get available agent names.
1566
1593
  *
1567
- * @returns File count, directory count, and total size
1594
+ * @returns Array of agent names that can be loaded
1568
1595
  */
1569
- getFileStats(): Promise<FileStats>;
1596
+ getAgentNames(): string[];
1570
1597
  /**
1571
- * Search file contents for a pattern.
1598
+ * Get available model names.
1572
1599
  *
1573
- * @param pattern - Search pattern (regular expression)
1574
- * @returns Matching files and lines
1600
+ * @returns Array of model names that can be loaded
1575
1601
  */
1576
- grepFiles(pattern: string): Promise<GrepResult[]>;
1602
+ getModelNames(): string[];
1577
1603
  /**
1578
- * Find files matching a glob pattern.
1604
+ * Get a child thread by its subagent reference ID.
1579
1605
  *
1580
- * @param pattern - Glob pattern (e.g., "*.txt", "**\/*.json")
1581
- * @returns Matching file paths
1606
+ * @param referenceId - Child thread UUID
1607
+ * @returns Child ThreadState or null if not found
1582
1608
  */
1583
- findFiles(pattern: string): Promise<FindResult>;
1609
+ getChildThread(referenceId: string): Promise<ThreadState | null>;
1584
1610
  /**
1585
- * Get a thumbnail for an image file.
1611
+ * Get this thread's parent thread (if any).
1586
1612
  *
1587
- * @param path - Path to the image file
1588
- * @returns Thumbnail data as ArrayBuffer, or null if not available
1613
+ * @returns Parent ThreadState, or null for top-level threads
1589
1614
  */
1590
- getFileThumbnail(path: string): Promise<ArrayBuffer | null>;
1615
+ getParentThread(): Promise<ThreadState | null>;
1591
1616
  /**
1592
- * Execution-specific state.
1617
+ * Resolve an environment value for this thread by property name.
1593
1618
  *
1594
- * This is present when the thread is actively executing (tools, hooks)
1595
- * and null when accessing a thread at rest (endpoints, external code).
1619
+ * Resolution order:
1620
+ * 1. Thread
1621
+ * 2. Agent definition
1622
+ * 3. Prompt definition
1623
+ * 4. User account
1624
+ * 5. AgentBuilder instance
1596
1625
  *
1597
- * Use this to access step counts, force turns, or stop execution.
1626
+ * @throws If the variable is not defined in any source
1598
1627
  */
1599
- execution: ExecutionState | null;
1628
+ env(propertyName: string): Promise<string>;
1600
1629
  /**
1601
- * Execute JavaScript or TypeScript source in an isolated sandbox.
1630
+ * Resolve the display/redaction type for an environment value.
1602
1631
  *
1603
- * The sandbox has **no ambient capabilities**: no filesystem, no network,
1604
- * no timers, no host globals, no access to `state` itself. Every capability
1605
- * the sandbox needs must be bridged in explicitly via `options.imports`,
1606
- * `options.modules`, or `options.globals`.
1632
+ * Resolution follows the same order as `env()`:
1633
+ * thread, agent definition, prompt definition, user account, AgentBuilder instance.
1634
+ * User-account and AgentBuilder-instance env stores may persist per-key
1635
+ * `text` / `secret` metadata; agent/prompt defaults remain `secret` unless
1636
+ * overridden by thread state.
1607
1637
  *
1608
- * Returns a {@link CodeExecution} handle that is a
1609
- * `PromiseLike<CodeExecutionResult>` — `await` it for the final result — and
1610
- * also exposes `terminate()` for caller-initiated cancellation. The spec
1611
- * does not impose a wall-clock timeout; callers layer their own deadline
1612
- * using a timer plus `handle.terminate()`.
1638
+ * Values marked `secret` should be redacted from tool output and logs.
1639
+ * Values marked `text` may be shown. Unknown values default to `secret`.
1640
+ */
1641
+ envType(propertyName: string): Promise<EnvValueType>;
1642
+ /**
1643
+ * Set a thread-scoped environment variable.
1613
1644
  *
1614
- * Results flow back through either:
1615
- * - the module export selected by `options.execute` (marshaled into
1616
- * `result.result`; defaults to the `default` export with no arguments; if
1617
- * the selected export is a function, it is called with `execute.args` and
1618
- * any returned promise is awaited before marshaling), or
1619
- * - the built-in `report` bridge (accumulated into `result.reports` and
1620
- * visible live on `handle.reports`), or
1621
- * - caller-installed bridge callbacks that the caller owns.
1645
+ * This writes to thread env storage and propagates the updated thread env
1646
+ * to all active descendant threads recursively. Terminated descendants are
1647
+ * not modified.
1622
1648
  *
1623
- * See the [Code Execution specification](https://standardagentspec.com/0.1.0/specification/threads/code-execution)
1624
- * for isolation guarantees, module resolution rules, value marshaling, and
1625
- * conformance requirements.
1649
+ * @param propertyName - Environment variable name
1650
+ * @param value - Environment variable value
1651
+ * @param options - Optional display/redaction classification for this value
1652
+ */
1653
+ setEnv(propertyName: string, value: string, options?: SetEnvOptions): Promise<void>;
1654
+ /**
1655
+ * Queue a silent message to this thread's parent, if one exists.
1626
1656
  *
1627
- * @param source - JavaScript or TypeScript source, evaluated as an ES module.
1628
- * @param options - Export selection, imports, globals, memory cap, and language hints.
1629
- * @returns A handle that settles with the execution result and can be
1630
- * terminated at any time before settlement.
1657
+ * This is useful for explicit child-to-parent escalation paths where tools or
1658
+ * hooks decide when the parent should be notified.
1631
1659
  *
1632
- * @example
1633
- * ```typescript
1634
- * const run = state.runCode(
1635
- * `
1636
- * import { readFile } from 'fs';
1637
- * import { report } from 'supervisor';
1660
+ * Implementations SHOULD tag the queued message with the current thread's
1661
+ * `subagent_id` metadata so the parent can attribute the notification.
1638
1662
  *
1639
- * const message = await getMessage();
1640
- * if (/username/.test(message)) {
1641
- * report({ topic: 'username', message });
1642
- * }
1643
- * export default async () => ({ scanned: true });
1644
- * `,
1645
- * {
1646
- * imports: {
1647
- * fs: { readFile: (p) => state.readFile(p) },
1648
- * supervisor: { report: (payload) => flagged.push(payload) },
1649
- * },
1650
- * globals: {
1651
- * console: { log: (...a) => {} },
1652
- * getMessage: async () => 'latest user message',
1653
- * },
1654
- * },
1655
- * );
1663
+ * @throws If content is empty
1664
+ */
1665
+ notifyParent(content: string): Promise<void>;
1666
+ /**
1667
+ * Update this thread's status in its parent registry entry.
1656
1668
  *
1657
- * const deadline = setTimeout(() => run.terminate('5s budget'), 5_000);
1658
- * const result = await run;
1659
- * clearTimeout(deadline);
1669
+ * Useful for long-lived watcher/observer children that want to expose their
1670
+ * current state without sending a parent message.
1660
1671
  *
1661
- * if (result.status === 'success') {
1662
- * // result.result === { scanned: true }
1663
- * }
1664
- * ```
1672
+ * This is a no-op when the thread has no parent registry entry.
1673
+ *
1674
+ * @throws If status is empty
1665
1675
  */
1666
- runCode(source: string, options?: CodeExecutionOptions): CodeExecution;
1676
+ setStatus(status: string): Promise<void>;
1667
1677
  /**
1668
- * Runtime-specific context that cannot be packed or shared.
1678
+ * Force the current agent session to stop successfully.
1669
1679
  *
1670
- * This property lets runtime implementations inject non-portable context —
1671
- * typically host bindings, database connections, or other
1672
- * platform-specific handles the runtime chooses to expose.
1680
+ * This is stronger than `state.execution.stop()`: it marks the active session
1681
+ * as terminal for subagent/session-boundary purposes, without requiring a
1682
+ * `sessionStop` tool call. By default it has no parent-message or status side
1683
+ * effects. Pass `notifyParent` and/or `status` when those effects are desired.
1673
1684
  *
1674
- * WARNING: Tools using this property cannot be packed, shared, or
1675
- * published as they depend on runtime-specific context. A packed agent
1676
- * MUST NOT use this property for required behavior. If a reusable agent
1677
- * needs a capability that is missing from ThreadState, define that
1678
- * capability in the Standard Agent Specification and its conformance
1679
- * surface instead of creating a private runtime dependency.
1685
+ * @throws If called outside an active execution context
1680
1686
  */
1681
- readonly _notPackableRuntimeContext?: Record<string, unknown>;
1682
- }
1683
-
1684
- /**
1685
- * Tool definition types for Standard Agents.
1686
- *
1687
- * Tools are callable functions that agents can invoke during execution.
1688
- * They receive the current ThreadState and validated arguments,
1689
- * and return results that are included in the conversation.
1690
- *
1691
- * @module
1692
- */
1693
-
1694
- /**
1695
- * Text content item returned by tools.
1696
- */
1697
- interface TextContent {
1698
- type: 'text';
1699
- text: string;
1700
- }
1701
- /**
1702
- * Image content item returned by tools.
1703
- */
1704
- interface ImageContent {
1705
- type: 'image';
1706
- /** Base64-encoded image data. */
1707
- data: string;
1708
- /** MIME type of the image (e.g., 'image/png', 'image/jpeg'). */
1709
- mimeType: string;
1710
- }
1711
- /**
1712
- * Content types that can be returned by tools.
1713
- */
1714
- type ToolContent = TextContent | ImageContent;
1715
- /**
1716
- * File attachment generated by a tool.
1717
- *
1718
- * Attachments are stored in the thread's file system and linked to
1719
- * the tool result message. Unlike user uploads, tool attachments are
1720
- * not subject to image downsampling.
1721
- */
1722
- interface ToolAttachment {
1723
- /** File name for the attachment. */
1724
- name: string;
1725
- /** MIME type of the attachment. */
1726
- mimeType: string;
1727
- /** Base64-encoded file data. */
1728
- data: string;
1729
- /** Width in pixels (for images). */
1730
- width?: number;
1731
- /** Height in pixels (for images). */
1732
- height?: number;
1733
- }
1734
- /**
1735
- * Reference to a pre-existing attachment in the thread file system.
1736
- */
1737
- interface AttachmentRef {
1738
- /** Unique identifier for the attachment. */
1739
- id: string;
1740
- /** Attachment type. */
1741
- type: 'file';
1742
- /** Path in the thread file system. */
1743
- path: string;
1744
- /** File name. */
1745
- name: string;
1746
- /** MIME type. */
1747
- mimeType: string;
1748
- /** File size in bytes. */
1749
- size: number;
1750
- /** Width in pixels (for images). */
1751
- width?: number;
1752
- /** Height in pixels (for images). */
1753
- height?: number;
1754
- /** AI-generated description. */
1755
- description?: string;
1756
- }
1757
- /**
1758
- * Result returned by a tool execution.
1759
- */
1760
- interface ToolResult {
1761
- /** Status of the tool execution. */
1762
- status: 'success' | 'error';
1687
+ stopSession(options?: StopSessionOptions): Promise<void>;
1688
+ /**
1689
+ * Queue a tool for execution.
1690
+ *
1691
+ * If the thread is currently executing, the tool is added to the
1692
+ * execution queue. If not, this starts a new execution with the
1693
+ * tool call.
1694
+ *
1695
+ * @param toolName - Name of the tool to invoke
1696
+ * @param args - Arguments to pass to the tool
1697
+ */
1698
+ queueTool(toolName: string, args: Record<string, unknown>): void;
1763
1699
  /**
1764
- * Text representation of the tool output.
1700
+ * Invoke a tool directly and wait for the result.
1765
1701
  *
1766
- * For tools that return structured content, this is derived by
1767
- * concatenating all text parts. For simple tools, this is the
1768
- * direct result string.
1702
+ * If the thread is not currently executing, this creates a minimal
1703
+ * execution context for the tool. Unlike queueTool, this blocks
1704
+ * until the tool completes.
1705
+ *
1706
+ * @param toolName - Name of the tool to invoke
1707
+ * @param args - Arguments to pass to the tool
1708
+ * @returns The tool result
1769
1709
  */
1770
- result?: string;
1771
- /** Error message if status is 'error'. */
1772
- error?: string;
1710
+ invokeTool(toolName: string, args: Record<string, unknown>): Promise<ToolResult>;
1773
1711
  /**
1774
- * Machine-readable error code for structured handling.
1712
+ * Schedule an effect for future execution.
1775
1713
  *
1776
- * Example: `subagent_env_required` indicates the client must provide
1777
- * scoped subagent env values before execution can continue.
1714
+ * Effects are executed outside the current conversation flow, making them
1715
+ * ideal for delayed operations like sending notifications, triggering
1716
+ * webhooks, or running cleanup tasks.
1717
+ *
1718
+ * @param name - Name of the effect to schedule (must exist in agents/effects/)
1719
+ * @param args - Arguments to pass to the effect handler
1720
+ * @param delay - Delay in milliseconds before execution (default: 0 for immediate)
1721
+ * @returns Unique ID of the scheduled effect (UUID)
1722
+ *
1723
+ * @example
1724
+ * ```typescript
1725
+ * // Schedule a reminder email in 30 minutes
1726
+ * const effectId = await state.scheduleEffect(
1727
+ * 'send_reminder_email',
1728
+ * { to: 'user@example.com', subject: 'Reminder' },
1729
+ * 30 * 60 * 1000
1730
+ * );
1731
+ * ```
1778
1732
  */
1779
- error_code?: string;
1733
+ scheduleEffect(name: string, args: Record<string, unknown>, delay?: number): Promise<string>;
1780
1734
  /**
1781
- * Structured error payload for machine handling.
1735
+ * Get scheduled effects for this thread.
1782
1736
  *
1783
- * Implementations should keep this JSON-serializable.
1737
+ * Returns effects that are pending execution. Can optionally filter
1738
+ * by effect name.
1739
+ *
1740
+ * @param name - Optional effect name to filter by
1741
+ * @returns Array of scheduled effect records
1784
1742
  */
1785
- error_data?: Record<string, unknown>;
1786
- /** Stack trace for error debugging. */
1787
- stack?: string;
1743
+ getScheduledEffects(name?: string): Promise<ScheduledEffect[]>;
1788
1744
  /**
1789
- * File attachments returned by the tool.
1745
+ * Cancel a scheduled effect.
1790
1746
  *
1791
- * Can contain either:
1792
- * - ToolAttachment: New files with base64 data to be stored
1793
- * - AttachmentRef: References to existing files in the thread filesystem
1747
+ * Cancels a pending effect before it executes. Has no effect if the effect
1748
+ * has already executed, was already canceled, or doesn't exist. Runtimes may
1749
+ * retain canceled effects in inspection history.
1794
1750
  *
1795
- * Implementations MUST store new attachments under /attachments/ directory.
1751
+ * @param id - The effect ID returned by scheduleEffect
1752
+ * @returns true if the effect was found and canceled, false otherwise
1796
1753
  */
1797
- attachments?: Array<ToolAttachment | AttachmentRef>;
1798
- }
1799
- /** Decrement helper to limit recursion depth. */
1800
- type Dec<N extends number> = N extends 10 ? 9 : N extends 9 ? 8 : N extends 8 ? 7 : N extends 7 ? 6 : N extends 6 ? 5 : N extends 5 ? 4 : N extends 4 ? 3 : N extends 3 ? 2 : N extends 2 ? 1 : N extends 1 ? 0 : 0;
1801
- /**
1802
- * Allowed Zod types for tool argument nodes.
1803
- *
1804
- * This is the single source of truth for which Zod types can be used
1805
- * in tool argument schemas. The depth parameter limits recursion to
1806
- * prevent infinite type expansion.
1807
- * Use ZodUnknown for arbitrary JSON slots, such as array items that can
1808
- * be strings, numbers, booleans, null, arrays, or objects.
1809
- *
1810
- * @template D - Maximum nesting depth (default: 7)
1811
- */
1812
- type ToolArgsNode<D extends number = 7> = ZodString | ZodNumber | ZodBoolean | ZodNull | ZodLiteral<string | number | boolean | null> | ZodUnknown | ZodEnum<Readonly<Record<string, string>>> | (D extends 0 ? never : ZodOptional<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodNullable<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodDefault<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodArray<ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodObject<Record<string, ToolArgsNode<Dec<D>>>>) | (D extends 0 ? never : ZodRecord<ZodString, ToolArgsNode<Dec<D>>>) | (D extends 0 ? never : ZodUnion<readonly [
1813
- ToolArgsNode<Dec<D>>,
1814
- ToolArgsNode<Dec<D>>,
1815
- ...ToolArgsNode<Dec<D>>[]
1816
- ]>);
1817
- /**
1818
- * Raw shape for a Zod object schema containing tool argument nodes.
1819
- *
1820
- * @template D - Maximum nesting depth (default: 7)
1821
- */
1822
- type ToolArgsRawShape<D extends number = 7> = Record<string, ToolArgsNode<D>>;
1823
- /**
1824
- * Top-level tool argument schema.
1825
- *
1826
- * Tool arguments MUST be defined as a Zod object schema.
1827
- * This is required for compatibility with OpenAI's function calling API.
1828
- *
1829
- * @template D - Maximum nesting depth (default: 7)
1830
- */
1831
- type ToolArgs<D extends number = 7> = z.ZodObject<ToolArgsRawShape<D>>;
1832
- /**
1833
- * Variable declaration type.
1834
- *
1835
- * - `text`: Plain string configuration value
1836
- * - `secret`: Sensitive value that should be encrypted at rest
1837
- */
1838
- type VariableType = 'text' | 'secret';
1839
- /**
1840
- * Declares a variable required or optionally consumed by a tool or prompt.
1841
- */
1842
- interface VariableDefinition {
1843
- /** Environment variable/property name */
1844
- name: string;
1845
- /** Value type */
1846
- type: VariableType;
1847
- /** Whether this variable is required to execute */
1848
- required: boolean;
1754
+ removeScheduledEffect(id: string): Promise<boolean>;
1849
1755
  /**
1850
- * Whether this variable is scoped to the declarer subtree.
1756
+ * Trigger an agent to run on this thread.
1851
1757
  *
1852
- * Scoped variables do not inherit parent thread env values. Descendants of
1853
- * the declarer still inherit scoped values from that declarer thread.
1758
+ * Starts a new agent execution asynchronously. This is useful for effects
1759
+ * that need to trigger background agent work (e.g., running a finalizer
1760
+ * agent after a delay).
1854
1761
  *
1855
- * @default false
1762
+ * The agent runs in the background - this method returns immediately
1763
+ * after queuing the execution.
1764
+ *
1765
+ * @param agentName - Name of the agent to run (must exist in agents/agents/)
1766
+ * @returns Promise that resolves when the execution is queued
1767
+ *
1768
+ * @example
1769
+ * ```typescript
1770
+ * // In an effect handler, trigger a finalizer agent
1771
+ * await state.runAgent('booking_finalizer');
1772
+ * ```
1856
1773
  */
1857
- scoped?: boolean;
1858
- /** Human-readable description (empty string when not provided) */
1859
- description: string;
1860
- }
1861
- /**
1862
- * Legacy raw shape for `tenvs` schema - uses same pattern as ToolArgsRawShape.
1863
- * Each key is an environment variable name and each value is a Zod schema.
1864
- *
1865
- * @template D - Maximum nesting depth (default: 7)
1866
- */
1867
- type TenvRawShape<D extends number = 7> = Record<string, ToolArgsNode<D>>;
1868
- /**
1869
- * Top-level thread environment variable schema.
1870
- *
1871
- * Defines which thread environment variables a tool requires.
1872
- * Required values are non-optional fields, optional values use `.optional()`.
1873
- *
1874
- * @example
1875
- * ```typescript
1876
- * z.object({
1877
- * VECTOR_STORE_ID: z.string().describe('OpenAI Vector Store ID'), // Required
1878
- * USER_LOCATION: z.string().optional().describe('User location'), // Optional
1879
- * })
1880
- * ```
1881
- *
1882
- * @template D - Maximum nesting depth (default: 7)
1883
- */
1884
- type ToolTenvs<D extends number = 7> = z.ZodObject<TenvRawShape<D>>;
1885
- /**
1886
- * @deprecated Use VariableDefinition[] via the `variables` property instead.
1887
- */
1888
- type ToolVariables = VariableDefinition[];
1889
- /**
1890
- * Tool function signature.
1891
- *
1892
- * Tools are async functions that receive a ThreadState and
1893
- * optionally validated arguments, returning a ToolResult.
1894
- *
1895
- * @template State - The state type (defaults to ThreadState)
1896
- * @template Args - The Zod schema for tool arguments, or null for no args
1897
- */
1898
- type Tool<State = ThreadState, Args extends ToolArgs | null = null> = Args extends ToolArgs ? (state: State, args: z.infer<Args>) => Promise<ToolResult> : (state: State) => Promise<ToolResult>;
1899
- /**
1900
- * Helper type to check if Uses is a non-empty const array.
1901
- * Returns true only if Uses has literal string elements (from `as const`).
1902
- */
1903
- type IsConstArray<Uses extends readonly string[]> = string extends Uses[number] ? false : true;
1904
- /**
1905
- * Helper type to check if Uses array is empty.
1906
- */
1907
- type IsEmptyArray<Uses extends readonly string[]> = Uses extends readonly [] ? true : false;
1908
- /**
1909
- * A ThreadState with queueTool and invokeTool constrained to specific tool names.
1910
- *
1911
- * When a tool declares `uses: ['a', 'b'] as const`, the state passed to execute
1912
- * will only allow calling those specific tools.
1913
- *
1914
- * @template Uses - Readonly array of allowed tool names
1915
- */
1916
- type UsesConstrainedState<Uses extends readonly string[]> = Omit<ThreadState, 'queueTool' | 'invokeTool'> & {
1774
+ runAgent(agentName: string): Promise<void>;
1775
+ /**
1776
+ * Soft-terminate the thread.
1777
+ *
1778
+ * Implementations should mark the thread as terminated, abort in-flight
1779
+ * execution, and reject subsequent execution/message queue operations.
1780
+ */
1781
+ terminate(): Promise<void>;
1782
+ /**
1783
+ * Emit a custom event to connected clients.
1784
+ *
1785
+ * Events are sent via WebSocket to any connected clients. Use this
1786
+ * for real-time updates, progress notifications, or custom data.
1787
+ *
1788
+ * @param event - Event name
1789
+ * @param data - Event data (must be JSON-serializable)
1790
+ */
1791
+ emit(event: string, data: unknown): void;
1792
+ /**
1793
+ * Execution-scoped key-value data available while the current agent run is
1794
+ * being assembled and executed.
1795
+ *
1796
+ * Runtimes use this bag for values shared between tools/hooks/effects during
1797
+ * one execution. Invocation or creation arguments belong in
1798
+ * {@link ThreadState.arguments}, not in `context`.
1799
+ *
1800
+ * User mutations persist across tool calls within a single execution, but are
1801
+ * not durable after execution ends unless the runtime rehydrates a value from
1802
+ * another durable source. For durable storage, use
1803
+ * {@link ThreadState.getValue} and {@link ThreadState.setValue}, the file
1804
+ * system, or external storage.
1805
+ */
1806
+ context: Record<string, unknown>;
1807
+ /**
1808
+ * Read a value from the thread's durable key-value store.
1809
+ *
1810
+ * Values written with {@link ThreadState.setValue} persist across executions,
1811
+ * tool calls, hook invocations, and endpoint requests for the lifetime of
1812
+ * the thread. The key-value store is one of two ways to store persistent
1813
+ * data on a thread, alongside the file system.
1814
+ *
1815
+ * Returns `null` when no value has been set for the given key. Values are
1816
+ * returned exactly as they were stored; runtimes MUST preserve JSON-equivalent
1817
+ * structure (objects, arrays, strings, numbers, booleans, `null`).
1818
+ *
1819
+ * @param key - The key to read
1820
+ * @returns The stored value, or `null` if the key has no value
1821
+ *
1822
+ * @example
1823
+ * ```typescript
1824
+ * const count = (await state.getValue<number>('invocation_count')) ?? 0;
1825
+ * await state.setValue('invocation_count', count + 1);
1826
+ * ```
1827
+ */
1828
+ getValue<T = unknown>(key: string): Promise<T | null>;
1829
+ /**
1830
+ * Write a value to the thread's durable key-value store.
1831
+ *
1832
+ * The value persists across executions for the lifetime of the thread.
1833
+ * Passing `null` or `undefined` deletes the key. Values MUST be
1834
+ * JSON-serializable; implementations MAY reject non-serializable values.
1835
+ *
1836
+ * Durable values are **not** automatically copied between threads when
1837
+ * subagents are spawned — each thread maintains its own key-value store.
1838
+ *
1839
+ * @param key - The key to write
1840
+ * @param value - The value to store (JSON-serializable), or `null`/`undefined`
1841
+ * to delete the key
1842
+ */
1843
+ setValue(key: string, value: unknown): Promise<void>;
1917
1844
  /**
1918
- * Queue a tool for execution.
1845
+ * Read a value from the account-wide durable key-value store of the user
1846
+ * this thread belongs to.
1919
1847
  *
1920
- * Constrained to only tools declared in `uses` array.
1848
+ * The user store is the account-scoped sibling of the thread store: values
1849
+ * persist across every thread the user owns on the instance (e.g. a coding
1850
+ * client's registry of registered machines and projects). Returns `null`
1851
+ * when the thread has no associated user or the key has no value.
1921
1852
  *
1922
- * @param toolName - Name of the tool to invoke (must be in uses array)
1923
- * @param args - Arguments to pass to the tool
1853
+ * @param key - The key to read
1924
1854
  */
1925
- queueTool(toolName: Uses[number], args?: Record<string, unknown>): void;
1855
+ getUserValue<T = unknown>(key: string): Promise<T | null>;
1926
1856
  /**
1927
- * Invoke a tool directly and wait for the result.
1857
+ * Write a value to the account-wide durable key-value store of the user
1858
+ * this thread belongs to.
1928
1859
  *
1929
- * Constrained to only tools declared in `uses` array.
1860
+ * Passing `null` or `undefined` deletes the key. Values MUST be
1861
+ * JSON-serializable. Implementations MUST reject the write when the thread
1862
+ * has no associated user.
1930
1863
  *
1931
- * @param toolName - Name of the tool to invoke (must be in uses array)
1932
- * @param args - Arguments to pass to the tool
1933
- * @returns The tool result
1864
+ * @param key - The key to write
1865
+ * @param value - The value to store (JSON-serializable), or `null`/`undefined`
1866
+ * to delete the key
1934
1867
  */
1935
- invokeTool(toolName: Uses[number], args?: Record<string, unknown>): Promise<ToolResult>;
1936
- };
1937
- /**
1938
- * A ThreadState where queueTool and invokeTool cannot be called (empty uses).
1939
- */
1940
- type EmptyUsesState = Omit<ThreadState, 'queueTool' | 'invokeTool'>;
1941
- /**
1942
- * Determines the correct state type based on the Uses array.
1943
- *
1944
- * - Empty `uses: [] as const` → EmptyUsesState (no queueTool/invokeTool)
1945
- * - Const `uses: ['a', 'b'] as const` → UsesConstrainedState (constrained methods)
1946
- * - Non-const `uses: ['a']` or no uses → ThreadState (unconstrained, backward compatible)
1947
- */
1948
- type ResolveUsesState<Uses extends readonly string[]> = IsEmptyArray<Uses> extends true ? EmptyUsesState : IsConstArray<Uses> extends true ? UsesConstrainedState<Uses> : ThreadState;
1949
- /**
1950
- * Tool execute function with uses-aware state.
1951
- *
1952
- * When `uses` is declared with `as const`, the state's queueTool and invokeTool
1953
- * are constrained to only the declared tools. When `uses` is not declared or
1954
- * is a regular string[], any tool name is allowed (backward compatible).
1955
- *
1956
- * @template State - Base state type
1957
- * @template Args - Tool arguments schema
1958
- * @template Uses - Readonly array of allowed tool names
1959
- */
1960
- type UsesAwareExecute<State, Args extends ToolArgs | null, Uses extends readonly string[]> = Args extends ToolArgs ? (state: ResolveUsesState<Uses>, args: z.infer<Args>) => Promise<ToolResult> : (state: ResolveUsesState<Uses>) => Promise<ToolResult>;
1961
- /**
1962
- * Options for defining a tool.
1963
- *
1964
- * @template State - The state type (defaults to ThreadState)
1965
- * @template Args - The Zod schema for tool arguments, or null for no args
1966
- * @template Tenvs - The Zod schema for thread environment variables, or null
1967
- * @template Uses - Readonly array of tool names this tool can invoke
1968
- */
1969
- interface DefineToolOptions<State = ThreadState, Args extends ToolArgs | null = null, Tenvs extends ToolTenvs | null = null, Uses extends readonly string[] = readonly string[]> {
1970
- /** Description of what the tool does (shown to the LLM). */
1971
- description: string;
1972
- /** Zod schema for validating tool arguments. Omit for tools with no args. */
1973
- args?: Args;
1974
- /** The tool implementation function. */
1975
- execute: UsesAwareExecute<State, Args, Uses>;
1868
+ setUserValue(key: string, value: unknown): Promise<void>;
1976
1869
  /**
1977
- * Variable declarations required/optionally used by this tool.
1870
+ * List entries in the account-wide durable key-value store of the user this
1871
+ * thread belongs to, optionally filtered by key prefix. Returns an empty
1872
+ * list when the thread has no associated user.
1873
+ *
1874
+ * @param options - Optional `prefix`, `limit` (default 100), and `offset`
1978
1875
  */
1979
- variables?: VariableDefinition[];
1876
+ listUserValues(options?: {
1877
+ prefix?: string | null;
1878
+ limit?: number;
1879
+ offset?: number;
1880
+ }): Promise<{
1881
+ entries: Array<{
1882
+ key: string;
1883
+ value: unknown;
1884
+ updated_at: number;
1885
+ }>;
1886
+ total: number;
1887
+ }>;
1980
1888
  /**
1981
- * @deprecated Use `variables` instead.
1982
- * Zod schema for thread environment variables the tool requires.
1889
+ * The profile of the user this thread belongs to, or `null` when the thread
1890
+ * has no associated user (e.g. unauthenticated local development).
1891
+ *
1892
+ * Lets tools and hooks personalize or gate behavior per user — e.g. an
1893
+ * entitlement hook enforcing a per-user concurrency limit, or a tool
1894
+ * addressing the user by name. Never includes credentials.
1895
+ *
1896
+ * @example
1897
+ * ```typescript
1898
+ * const user = await state.user();
1899
+ * if (user?.email) await notifyBillingService(user.email);
1900
+ * ```
1983
1901
  */
1984
- tenvs?: Tenvs;
1902
+ user(): Promise<ThreadUser | null>;
1985
1903
  /**
1986
- * Where this tool is executed:
1987
- * - 'local': Execute locally by the execution engine (default)
1988
- * - 'provider': Executed by the LLM provider, results come in response
1904
+ * The instance-global Agent Skills library (https://agentskills.io format).
1905
+ *
1906
+ * Skills are installed once and visible to every thread; their files live
1907
+ * server-side (never on a client machine). Agents should follow progressive
1908
+ * disclosure: browse metadata via `skills.list()`, and load a skill's
1909
+ * SKILL.md body with `skills.get()` only when it is applicable to the task.
1910
+ *
1911
+ * @example
1912
+ * ```typescript
1913
+ * const available = await state.skills.list();
1914
+ * const skill = await state.skills.get('pdf-processing');
1915
+ * const script = await state.skills.readFile('pdf-processing', 'scripts/extract.py');
1916
+ * ```
1989
1917
  */
1990
- executionMode?: 'local' | 'provider';
1918
+ skills: SkillsNamespace;
1991
1919
  /**
1992
- * Which provider executes this tool (when executionMode='provider').
1993
- * e.g., 'openai', 'anthropic'
1920
+ * Write a file to the thread's file system.
1921
+ *
1922
+ * Large files (>1.75MB) are automatically chunked for storage.
1923
+ *
1924
+ * @param path - File path (relative to thread root)
1925
+ * @param data - File content as ArrayBuffer or string
1926
+ * @param mimeType - MIME type of the file
1927
+ * @param options - Optional metadata and dimensions
1928
+ * @returns The created file record
1994
1929
  */
1995
- executionProvider?: string;
1930
+ writeFile(path: string, data: ArrayBuffer | string, mimeType: string, options?: WriteFileOptions): Promise<FileRecord>;
1996
1931
  /**
1997
- * Explicit list of tools, prompts, or agents this tool can call.
1932
+ * Read a file from the thread's file system.
1998
1933
  *
1999
- * When specified with `as const`, the tool's execute function's state
2000
- * will have queueTool() and invokeTool() constrained to only the
2001
- * declared tools (compile-time type safety).
1934
+ * @param path - File path
1935
+ * @returns File content as ArrayBuffer, or null if not found
1936
+ */
1937
+ readFile(path: string): Promise<ArrayBuffer | null>;
1938
+ /**
1939
+ * Stream a file from the thread's file system in chunks.
2002
1940
  *
2003
- * At runtime, attempts to call unlisted items will throw an error.
1941
+ * For large files (>1.75MB), this yields one chunk at a time, enabling
1942
+ * memory-efficient access without loading the entire file. Small files
1943
+ * are yielded as a single chunk.
2004
1944
  *
2005
- * This is required for packed tools to ensure namespace isolation.
2006
- * For unpacked tools, it's optional but recommended for clarity.
1945
+ * Returns null if the file is not found or stored externally (S3, R2, URL).
1946
+ *
1947
+ * @param path - File path
1948
+ * @param options - Optional streaming options (abort signal)
1949
+ * @returns Async iterable of file chunks, or null if not found/external
2007
1950
  *
2008
1951
  * @example
2009
1952
  * ```typescript
2010
- * // Type-safe: only 'validate_input' and 'format_output' allowed
2011
- * defineTool({
2012
- * description: 'Process data using helper tools',
2013
- * uses: ['validate_input', 'format_output'] as const,
2014
- * execute: async (state) => {
2015
- * state.queueTool('validate_input', { data: '...' }); // ✓ OK
2016
- * state.queueTool('unknown_tool', {}); // ✗ TypeScript error
2017
- * // ...
2018
- * },
2019
- * });
2020
- *
2021
- * // Without `as const`, any tool name is allowed (backward compatible)
2022
- * defineTool({
2023
- * description: 'Flexible tool',
2024
- * uses: ['some_tool'],
2025
- * execute: async (state) => {
2026
- * state.queueTool('any_tool', {}); // ✓ OK (no type constraint)
2027
- * },
2028
- * });
1953
+ * const stream = await state.readFileStream('/uploads/video.mp4');
1954
+ * if (stream) {
1955
+ * for await (const chunk of stream) {
1956
+ * console.log(`Chunk ${chunk.index + 1}/${chunk.totalChunks}`);
1957
+ * // Process chunk.data (Uint8Array)
1958
+ * }
1959
+ * }
2029
1960
  * ```
2030
1961
  */
2031
- uses?: Uses;
1962
+ readFileStream(path: string, options?: ReadFileStreamOptions): Promise<AsyncIterable<FileChunk> | null>;
2032
1963
  /**
2033
- * The name of an argument whose value is a short, human-readable description
2034
- * of what this tool call is doing — for example `"fixing index.html"`.
1964
+ * Get metadata about a file.
2035
1965
  *
2036
- * When set, the `tool_call_started` hook and the `tool_call_started` thread
2037
- * event wait until **just this argument** has finished streaming from the
2038
- * model — not the whole tool call — and include its value as `progress`. This
2039
- * lets a UI show what a tool is about to do before a large argument (such as
2040
- * a file's `content`) finishes generating.
1966
+ * @param path - File path
1967
+ * @returns File record, or null if not found
1968
+ */
1969
+ statFile(path: string): Promise<FileRecord | null>;
1970
+ /**
1971
+ * List contents of a directory.
1972
+ *
1973
+ * @param path - Directory path
1974
+ * @returns Directory entries
1975
+ */
1976
+ readdirFile(path: string): Promise<ReaddirResult>;
1977
+ /**
1978
+ * Delete a file.
1979
+ *
1980
+ * @param path - File path
1981
+ */
1982
+ unlinkFile(path: string): Promise<void>;
1983
+ /**
1984
+ * Create a directory.
1985
+ *
1986
+ * @param path - Directory path
1987
+ * @returns The created directory record
1988
+ */
1989
+ mkdirFile(path: string): Promise<FileRecord>;
1990
+ /**
1991
+ * Remove a directory.
1992
+ *
1993
+ * @param path - Directory path (must be empty)
1994
+ */
1995
+ rmdirFile(path: string): Promise<void>;
1996
+ /**
1997
+ * Move or rename a file or directory.
1998
+ *
1999
+ * Relocates the entry at `sourcePath` to `destinationPath`. Works for
2000
+ * files and directories; moving a directory relocates its entire subtree,
2001
+ * preserving the relative layout of its contents. The destination must not
2002
+ * already exist, and a directory cannot be moved into itself or one of its
2003
+ * own descendants.
2004
+ *
2005
+ * @param sourcePath - Existing file or directory path
2006
+ * @param destinationPath - New path (must not already exist)
2007
+ * @returns The moved entry's record at its new path
2008
+ */
2009
+ moveFile(sourcePath: string, destinationPath: string): Promise<FileRecord>;
2010
+ /**
2011
+ * Rename a file or directory in place.
2012
+ *
2013
+ * Keeps the entry in its current parent directory and changes only its
2014
+ * final path segment. `newName` must be a bare file name with no path
2015
+ * separators. To relocate an entry to a different directory, use
2016
+ * {@link ThreadState.moveFile} instead.
2041
2017
  *
2042
- * When unset, `tool_call_started` fires as soon as the tool call appears in
2043
- * the model stream (its name is known, arguments may still be incomplete).
2018
+ * @param path - Existing file or directory path
2019
+ * @param newName - New name (no path separators)
2020
+ * @returns The renamed entry's record at its new path
2021
+ */
2022
+ renameFile(path: string, newName: string): Promise<FileRecord>;
2023
+ /**
2024
+ * Get overall file system statistics.
2044
2025
  *
2045
- * Declare the named argument early in the `args` schema and keep it short so
2046
- * it completes quickly. If the model never emits it, `tool_call_started`
2047
- * still fires once the tool call finishes, with `progress` undefined.
2026
+ * @returns File count, directory count, and total size
2027
+ */
2028
+ getFileStats(): Promise<FileStats>;
2029
+ /**
2030
+ * Search file contents for a pattern.
2048
2031
  *
2049
- * @example
2050
- * ```typescript
2051
- * defineTool({
2052
- * description: 'Write a file to the workspace',
2053
- * progressArgument: 'description',
2054
- * args: z.object({
2055
- * description: z.string().describe('e.g. "writing index.html"'),
2056
- * path: z.string(),
2057
- * content: z.string(),
2058
- * }),
2059
- * execute: async (state, args) => { ... },
2060
- * });
2061
- * ```
2032
+ * @param pattern - Search pattern (regular expression)
2033
+ * @returns Matching files and lines
2062
2034
  */
2063
- progressArgument?: string;
2064
- }
2065
- /**
2066
- * Tool definition object returned by defineTool().
2067
- *
2068
- * Contains all the metadata and implementation needed to register
2069
- * and execute a tool.
2070
- *
2071
- * @template State - The state type (defaults to ThreadState)
2072
- * @template Args - The Zod schema for tool arguments, or null for no args
2073
- * @template Tenvs - The Zod schema for thread environment variables, or null
2074
- * @template Uses - Readonly array of tool names this tool can invoke
2075
- */
2076
- interface ToolDefinition<State = ThreadState, Args extends ToolArgs | null = null, Tenvs extends ToolTenvs | null = null, Uses extends readonly string[] = readonly string[]> {
2077
- /** Description of what the tool does (shown to the LLM). */
2078
- description: string;
2079
- /** Zod schema for validating tool arguments, or null for no args. */
2080
- args: Args;
2081
- /** The tool implementation function. */
2082
- execute: UsesAwareExecute<State, Args, Uses>;
2083
- /** Declared variables for this tool. */
2084
- variables: VariableDefinition[];
2035
+ grepFiles(pattern: string): Promise<GrepResult[]>;
2085
2036
  /**
2086
- * @deprecated Use `variables` instead.
2087
- * Zod schema for thread environment variables, or null if none.
2037
+ * Find files matching a glob pattern.
2038
+ *
2039
+ * @param pattern - Glob pattern (e.g., "*.txt", "**\/*.json")
2040
+ * @returns Matching file paths
2088
2041
  */
2089
- tenvs: Tenvs;
2042
+ findFiles(pattern: string): Promise<FindResult>;
2090
2043
  /**
2091
- * Where this tool is executed:
2092
- * - 'local': Execute locally by the execution engine (default)
2093
- * - 'provider': Executed by the LLM provider, results come in response
2044
+ * Get a thumbnail for an image file.
2045
+ *
2046
+ * @param path - Path to the image file
2047
+ * @returns Thumbnail data as ArrayBuffer, or null if not available
2094
2048
  */
2095
- executionMode?: 'local' | 'provider';
2049
+ getFileThumbnail(path: string): Promise<ArrayBuffer | null>;
2096
2050
  /**
2097
- * Which provider executes this tool (when executionMode='provider').
2051
+ * Execution-specific state.
2052
+ *
2053
+ * This is present when the thread is actively executing (tools, hooks)
2054
+ * and null when accessing a thread at rest (endpoints, external code).
2055
+ *
2056
+ * Use this to access step counts, force turns, or stop execution.
2098
2057
  */
2099
- executionProvider?: string;
2058
+ execution: ExecutionState | null;
2100
2059
  /**
2101
- * Explicit list of tools, prompts, or agents this tool can call.
2060
+ * Execute JavaScript or TypeScript source in an isolated sandbox.
2102
2061
  *
2103
- * When specified with `as const`, TypeScript constrains queueTool()
2104
- * and invokeTool() at compile time. At runtime, attempts to call
2105
- * unlisted items throw an error.
2062
+ * The sandbox has **no ambient capabilities**: no filesystem, no network,
2063
+ * no timers, no host globals, no access to `state` itself. Every capability
2064
+ * the sandbox needs must be bridged in explicitly via `options.imports`,
2065
+ * `options.modules`, or `options.globals`.
2106
2066
  *
2107
- * This is required for packed tools to ensure namespace isolation.
2108
- * For unpacked tools, it's optional but recommended for clarity.
2067
+ * Returns a {@link CodeExecution} handle that is a
2068
+ * `PromiseLike<CodeExecutionResult>` — `await` it for the final result — and
2069
+ * also exposes `terminate()` for caller-initiated cancellation. The spec
2070
+ * does not impose a wall-clock timeout; callers layer their own deadline
2071
+ * using a timer plus `handle.terminate()`.
2109
2072
  *
2110
- * Items can be:
2111
- * - Simple names: Resolve within current namespace
2112
- * - Qualified names (e.g., 'other_pkg:agent'): Cross-package entry point
2073
+ * Results flow back through either:
2074
+ * - the module export selected by `options.execute` (marshaled into
2075
+ * `result.result`; defaults to the `default` export with no arguments; if
2076
+ * the selected export is a function, it is called with `execute.args` and
2077
+ * any returned promise is awaited before marshaling), or
2078
+ * - the built-in `report` bridge (accumulated into `result.reports` and
2079
+ * visible live on `handle.reports`), or
2080
+ * - caller-installed bridge callbacks that the caller owns.
2081
+ *
2082
+ * See the [Code Execution specification](https://standardagentspec.com/0.1.0/specification/threads/code-execution)
2083
+ * for isolation guarantees, module resolution rules, value marshaling, and
2084
+ * conformance requirements.
2085
+ *
2086
+ * @param source - JavaScript or TypeScript source, evaluated as an ES module.
2087
+ * @param options - Export selection, imports, globals, memory cap, and language hints.
2088
+ * @returns A handle that settles with the execution result and can be
2089
+ * terminated at any time before settlement.
2090
+ *
2091
+ * @example
2092
+ * ```typescript
2093
+ * const run = state.runCode(
2094
+ * `
2095
+ * import { readFile } from 'fs';
2096
+ * import { report } from 'supervisor';
2097
+ *
2098
+ * const message = await getMessage();
2099
+ * if (/username/.test(message)) {
2100
+ * report({ topic: 'username', message });
2101
+ * }
2102
+ * export default async () => ({ scanned: true });
2103
+ * `,
2104
+ * {
2105
+ * imports: {
2106
+ * fs: { readFile: (p) => state.readFile(p) },
2107
+ * supervisor: { report: (payload) => flagged.push(payload) },
2108
+ * },
2109
+ * globals: {
2110
+ * console: { log: (...a) => {} },
2111
+ * getMessage: async () => 'latest user message',
2112
+ * },
2113
+ * },
2114
+ * );
2115
+ *
2116
+ * const deadline = setTimeout(() => run.terminate('5s budget'), 5_000);
2117
+ * const result = await run;
2118
+ * clearTimeout(deadline);
2119
+ *
2120
+ * if (result.status === 'success') {
2121
+ * // result.result === { scanned: true }
2122
+ * }
2123
+ * ```
2113
2124
  */
2114
- uses?: Uses;
2125
+ runCode(source: string, options?: CodeExecutionOptions): CodeExecution;
2115
2126
  /**
2116
- * The name of an argument carrying a short, human-readable description of what
2117
- * this tool call is doing (e.g. `"fixing index.html"`). Controls when the
2118
- * `tool_call_started` hook/event fires — see {@link DefineToolOptions.progressArgument}.
2127
+ * Runtime-specific context that cannot be packed or shared.
2128
+ *
2129
+ * This property lets runtime implementations inject non-portable context —
2130
+ * typically host bindings, database connections, or other
2131
+ * platform-specific handles the runtime chooses to expose.
2132
+ *
2133
+ * WARNING: Tools using this property cannot be packed, shared, or
2134
+ * published as they depend on runtime-specific context. A packed agent
2135
+ * MUST NOT use this property for required behavior. If a reusable agent
2136
+ * needs a capability that is missing from ThreadState, define that
2137
+ * capability in the Standard Agent Specification and its conformance
2138
+ * surface instead of creating a private runtime dependency.
2119
2139
  */
2120
- progressArgument?: string;
2140
+ readonly _notPackableRuntimeContext?: Record<string, unknown>;
2121
2141
  }
2122
- /**
2123
- * Defines a tool that agents can call during execution.
2124
- *
2125
- * Tools are the primary way agents interact with external systems.
2126
- * Each tool has a description (shown to the LLM), optional argument
2127
- * schema (validated at runtime), an implementation function, and
2128
- * optional variable requirements.
2129
- *
2130
- * @example
2131
- * ```typescript
2132
- * import { defineTool } from '@standardagents/spec';
2133
- * import { z } from 'zod';
2134
- *
2135
- * // Tool with arguments
2136
- * export default defineTool({
2137
- * description: 'Search the knowledge base for relevant information',
2138
- * args: z.object({
2139
- * query: z.string().describe('Search query'),
2140
- * limit: z.number().optional().describe('Max results'),
2141
- * }),
2142
- * execute: async (state, args) => {
2143
- * const results = await search(args.query, args.limit);
2144
- * return { status: 'success', result: JSON.stringify(results) };
2145
- * },
2146
- * });
2147
- *
2148
- * // Tool without arguments
2149
- * export default defineTool({
2150
- * description: 'Get the current server time',
2151
- * execute: async (state) => {
2152
- * return { status: 'success', result: new Date().toISOString() };
2153
- * },
2154
- * });
2155
- *
2156
- * // Tool with declared variables
2157
- * export default defineTool({
2158
- * description: 'Search through uploaded files',
2159
- * args: z.object({ query: z.string() }),
2160
- * execute: async (state, args) => ({ status: 'success', result: 'done' }),
2161
- * variables: [
2162
- * {
2163
- * name: 'VECTOR_STORE_ID',
2164
- * type: 'text',
2165
- * required: true,
2166
- * description: 'OpenAI Vector Store ID',
2167
- * },
2168
- * ],
2169
- * });
2170
- *
2171
- * // Provider-executed tool (e.g., OpenAI built-in tools)
2172
- * export default defineTool({
2173
- * description: 'Generate images using DALL-E',
2174
- * args: z.object({ prompt: z.string() }),
2175
- * execute: async () => ({ status: 'success', result: 'Handled by provider' }),
2176
- * executionMode: 'provider',
2177
- * executionProvider: 'openai',
2178
- * });
2179
- * ```
2180
- *
2181
- * @param options - Tool definition options
2182
- * @returns A tool definition object
2183
- */
2184
- /**
2185
- * Validate a tool name does not contain reserved characters.
2186
- * Tools are typically defined without a name field (they get the filename),
2187
- * but this can be called by build tools that assign names.
2188
- */
2189
- declare function validateToolName(name: string): void;
2190
- declare function defineTool<State = ThreadState, Args extends ToolArgs | null = null, Tenvs extends ToolTenvs | null = null, Uses extends readonly string[] = readonly string[]>(options: DefineToolOptions<State, Args, Tenvs, Uses>): ToolDefinition<State, Args, Tenvs, Uses>;
2191
2142
 
2192
2143
  /**
2193
2144
  * Provider types for Standard Agents.
@@ -2735,7 +2686,9 @@ declare class ProviderError extends Error {
2735
2686
  code: ProviderErrorCode;
2736
2687
  statusCode?: number | undefined;
2737
2688
  retryAfter?: number | undefined;
2738
- constructor(message: string, code: ProviderErrorCode, statusCode?: number | undefined, retryAfter?: number | undefined);
2689
+ constructor(message: string, code: ProviderErrorCode, statusCode?: number | undefined, retryAfter?: number | undefined, options?: {
2690
+ cause?: unknown;
2691
+ });
2739
2692
  /**
2740
2693
  * Whether this error is retryable
2741
2694
  */
@@ -2791,6 +2744,13 @@ interface ProviderInstance {
2791
2744
  /** Fetch additional metadata about a completed response */
2792
2745
  getResponseMetadata?(summary: ResponseSummary, signal?: AbortSignal): Promise<Record<string, unknown> | null>;
2793
2746
  }
2747
+ /**
2748
+ * A `fetch`-compatible transport function.
2749
+ *
2750
+ * Matches the WHATWG `fetch` call signature so any standard `fetch`
2751
+ * implementation (or a wrapper around one) satisfies it.
2752
+ */
2753
+ type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
2794
2754
  /**
2795
2755
  * Configuration passed to provider factory functions.
2796
2756
  */
@@ -2798,6 +2758,16 @@ interface ProviderFactoryConfig {
2798
2758
  apiKey: string;
2799
2759
  baseUrl?: string;
2800
2760
  timeout?: number;
2761
+ /**
2762
+ * Transport override for HTTP-based providers.
2763
+ *
2764
+ * The runtime may inject a custom transport here — for mocking, proxying,
2765
+ * instrumentation, or any other request routing the host environment needs.
2766
+ * Provider packages that speak HTTP MUST honor this override and route every
2767
+ * request to the provider backend through it when present, instead of the
2768
+ * global `fetch`.
2769
+ */
2770
+ fetch?: FetchLike;
2801
2771
  /**
2802
2772
  * Extra HTTP headers sent on every request to the provider backend.
2803
2773
  * Provider packages that build an HTTP client should forward these, so a
@@ -2879,7 +2849,32 @@ interface ProviderOverrideContext {
2879
2849
  config: ProviderFactoryConfig;
2880
2850
  /** Base provider instance before overrides are applied */
2881
2851
  baseProvider: ProviderInstance;
2852
+ /**
2853
+ * The thread this request is executing for, when available.
2854
+ *
2855
+ * Only populated for request-scoped overrides (`generate`, `stream`,
2856
+ * `inspectRequest`, `getResponseMetadata`) — catalog overrides (`getModels`,
2857
+ * `getIcon`, etc.) run without a thread and leave this undefined. Lets a
2858
+ * transport override key off thread state without any product-specific
2859
+ * coupling in the specification.
2860
+ */
2861
+ state?: ThreadState;
2882
2862
  }
2863
+ /**
2864
+ * Builds a request transport for a defined provider.
2865
+ *
2866
+ * The runtime calls this per request with the executing thread's `state` and
2867
+ * uses the returned transport as `ProviderFactoryConfig.fetch`. It is a
2868
+ * generic hook — "override the fetch mechanism however you want" — with no
2869
+ * knowledge of what the transport does (proxy, instrument, tunnel, mock).
2870
+ * Because the transport can close over `state`, a provider declaring
2871
+ * `createFetch` is constructed fresh per request rather than cached.
2872
+ */
2873
+ type CreateFetch = (context: {
2874
+ providerName: string;
2875
+ config: ProviderFactoryConfig;
2876
+ state?: ThreadState;
2877
+ }) => FetchLike;
2883
2878
  type MaybePromise<T> = T | Promise<T>;
2884
2879
  type ProviderOverride<Context, Result> = (context: ProviderOverrideContext & Context, next: () => MaybePromise<Result>) => MaybePromise<Result>;
2885
2880
  type ProviderSyncOverride<Context, Result> = (context: ProviderOverrideContext & Context, next: () => Result) => Result;
@@ -2926,6 +2921,13 @@ interface ProviderDefinition<N extends string = string, Base extends ProviderFac
2926
2921
  baseProvider: Base;
2927
2922
  config?: Partial<Record<keyof ProviderFactoryConfig | string, ProviderConfigEntry>>;
2928
2923
  overrides?: ProviderMethodOverrides;
2924
+ /**
2925
+ * Per-request transport factory. When declared, the runtime builds the
2926
+ * provider fresh for each request with `ProviderFactoryConfig.fetch` set to
2927
+ * this transport (so it can close over the executing thread's state) instead
2928
+ * of using the shared provider cache.
2929
+ */
2930
+ createFetch?: CreateFetch;
2929
2931
  }
2930
2932
  /**
2931
2933
  * Provider factory with optional typed providerOptions schema.
@@ -5155,4 +5157,4 @@ interface PackedExports {
5155
5157
  __meta: PackedMeta;
5156
5158
  }
5157
5159
 
5158
- export { type AgentDefinition, type AgentType, type AttachmentRef, type ClientToolRequest, type ClientToolResponse, type CodeExecution, type CodeExecutionError, type CodeExecutionLog, type CodeExecutionOptions, type CodeExecutionResult, type CodeExecutionStatus, type ContentPart, type Controller, type ControllerContext, type ControllerReturn, type DefineToolOptions, type DefinitionLoader, type Effect, type EffectDefinition, type EmptyUsesState, type EnvValueType, type ExecutionState, type FileChunk, type FilePart, type FileRecord, type FileStats, type FileStorage, type FindResult, type GetMessagesOptions, type GlobalNamespaceContext, type GrepResult, type HookContext, type HookDefinition, type HookDefinitionOptions, type HookDefinitionResult, type HookMessage, type HookName, type HookSignatures, type HookToolCall, type HookToolResult, type ImageContent, type ImagePart, type ImageUrlPart, type InferProviderOptions, type InjectMessageInput, type InspectedRequest, type LLMMessage, type LLMProviderInterface, type MarkedThreadEndpoint, type Message, type MessageUpdates, type MessagesResult, type ModelCapabilities, type ModelDefinition, type ModelProvider, type NamespaceContext, type PackageSignature, type PackedExports, type PackedMeta, type PackedMetadata, type PackedNamespaceContext, type PromptContent, type PromptDefinition, type PromptEnvPart, type PromptIncludePart, type PromptInput, type PromptPart, type PromptTextPart, type PromptToolConfig, type ProviderAssistantMessage, type ProviderAttachment, type ProviderConfigSlot, type ProviderConfigSlots, type ProviderConfigValueSource, type ProviderDefinition, ProviderError, type ProviderErrorCode, type ProviderExecutedToolResult, type ProviderFactory, type ProviderFactoryConfig, type ProviderFactoryWithOptions, type ProviderFinishReason, type ProviderGeneratedImage, type ProviderInstance, type ProviderMessage, type ProviderMessageContent, type ProviderMethodOverrides, type ProviderModelInfo, type ProviderModelsPage, type ProviderModelsQuery, type ProviderOverride, type ProviderOverrideContext, type ProviderReasoningDetail, type ProviderRequest, type ProviderResponse, type ProviderStreamChunk, type ProviderSyncOverride, type ProviderSystemMessage, type ProviderTool, type ProviderToolCallPart, type ProviderToolMessage, type ProviderToolResultContent, type ProviderUsage, type ProviderUsagePricing, type ProviderUserMessage, type ProviderWebSearchResult, type QueueMessageInput, type ReadFileStreamOptions, type ReaddirResult, type ReasoningConfig, type ResolveUsesState, type ResponseSummary, type ScheduledEffect, type SessionToolBinding, type SessionToolConfig, type SetEnvOptions, type SideConfig, type SkillFileInput, type SkillMetadata, type SkillsNamespace, type StopSessionOptions, type StructuredPrompt, type SubagentRegistryEntry, type SubagentToolConfig, type SubpromptConfig, THREAD_ENDPOINT_SYMBOL, THREAD_STREAM_REASONING_PARAM, type TenvRawShape, type TextContent, type TextPart, type ThreadEndpointHandler, type ThreadEndpointRouteParams, type ThreadMessageChunkEvent, type ThreadMetadata, type ThreadReasoningChunkEvent, type ThreadState, type ThreadUser, type Tool, type ToolArgs, type ToolArgsNode, type ToolArgsRawShape, type ToolAttachment, type ToolConfig, type ToolContent, type ToolDefinition, type ToolResult, type ToolTenvs, type ToolVariables, type UsesAwareExecute, type UsesConstrainedState, type VariableDefinition, type VariableType, type VirtualModuleLoader, type VirtualModuleRegistry, type WriteFileOptions, belongsToPackage, defineAgent, defineController, defineEffect, defineHook, defineModel, definePrompt, defineProvider, defineThreadEndpoint, defineTool, isPacked, isThreadEndpoint, isVisibleInNamespace, mapReasoningLevel, providerConst, providerEnv, providerValue, validateToolName };
5160
+ export { type AgentDefinition, type AgentType, type AttachmentRef, type CodeExecution, type CodeExecutionError, type CodeExecutionLog, type CodeExecutionOptions, type CodeExecutionResult, type CodeExecutionStatus, type ContentPart, type Controller, type ControllerContext, type ControllerReturn, type CreateFetch, type DefineToolOptions, type DefinitionLoader, type Effect, type EffectDefinition, type EmptyUsesState, type EnvValueType, type ExecutionState, type FetchLike, type FileChunk, type FilePart, type FileRecord, type FileStats, type FileStorage, type FindResult, type GetMessagesOptions, type GlobalNamespaceContext, type GrepResult, type HookContext, type HookDefinition, type HookDefinitionOptions, type HookDefinitionResult, type HookMessage, type HookName, type HookSignatures, type HookToolCall, type HookToolResult, type ImageContent, type ImagePart, type ImageUrlPart, type InferProviderOptions, type InjectMessageInput, type InspectedRequest, type LLMMessage, type LLMProviderInterface, type MarkedThreadEndpoint, type Message, type MessageUpdates, type MessagesResult, type ModelCapabilities, type ModelDefinition, type ModelProvider, type NamespaceContext, type PackageSignature, type PackedExports, type PackedMeta, type PackedMetadata, type PackedNamespaceContext, type PromptContent, type PromptDefinition, type PromptEnvPart, type PromptIncludePart, type PromptInput, type PromptPart, type PromptTextPart, type PromptToolConfig, type ProviderAssistantMessage, type ProviderAttachment, type ProviderConfigSlot, type ProviderConfigSlots, type ProviderConfigValueSource, type ProviderDefinition, ProviderError, type ProviderErrorCode, type ProviderExecutedToolResult, type ProviderFactory, type ProviderFactoryConfig, type ProviderFactoryWithOptions, type ProviderFinishReason, type ProviderGeneratedImage, type ProviderInstance, type ProviderMessage, type ProviderMessageContent, type ProviderMethodOverrides, type ProviderModelInfo, type ProviderModelsPage, type ProviderModelsQuery, type ProviderOverride, type ProviderOverrideContext, type ProviderReasoningDetail, type ProviderRequest, type ProviderResponse, type ProviderStreamChunk, type ProviderSyncOverride, type ProviderSystemMessage, type ProviderTool, type ProviderToolCallPart, type ProviderToolMessage, type ProviderToolResultContent, type ProviderUsage, type ProviderUsagePricing, type ProviderUserMessage, type ProviderWebSearchResult, type QueueMessageInput, type ReadFileStreamOptions, type ReaddirResult, type ReasoningConfig, type ResolveUsesState, type ResponseSummary, type ScheduledEffect, type SessionToolBinding, type SessionToolConfig, type SetEnvOptions, type SideConfig, type SkillFileInput, type SkillMetadata, type SkillsNamespace, type StopSessionOptions, type StructuredPrompt, type SubagentRegistryEntry, type SubagentToolConfig, type SubpromptConfig, THREAD_ENDPOINT_SYMBOL, THREAD_STREAM_REASONING_PARAM, type TenvRawShape, type TextContent, type TextPart, type ThreadEndpointHandler, type ThreadEndpointRouteParams, type ThreadMessageChunkEvent, type ThreadMetadata, type ThreadReasoningChunkEvent, type ThreadState, type ThreadUser, type Tool, type ToolArgs, type ToolArgsNode, type ToolArgsRawShape, type ToolAttachment, type ToolConfig, type ToolContent, type ToolDefinition, type ToolResult, type ToolTenvs, type ToolVariables, type UsesAwareExecute, type UsesConstrainedState, type VariableDefinition, type VariableType, type VirtualModuleLoader, type VirtualModuleRegistry, type WriteFileOptions, belongsToPackage, defineAgent, defineController, defineEffect, defineHook, defineModel, definePrompt, defineProvider, defineThreadEndpoint, defineTool, isPacked, isThreadEndpoint, isVisibleInNamespace, mapReasoningLevel, providerConst, providerEnv, providerValue, validateToolName };