@standardagents/builder 0.11.12 → 0.12.1

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.
@@ -0,0 +1,1043 @@
1
+ import { DurableObjectStorage } from '@cloudflare/workers-types';
2
+ import { ZodObject, ZodRawShape } from 'zod';
3
+ import { N as NamespacedRegistry } from './types-pLkJx8vg.js';
4
+ import { ToolResult as ToolResult$1, HookName, HookSignatures, ThreadState, HookMessage, HookToolCall, HookToolResult, AgentDefinition, ControllerContext, Controller, ThreadEndpointHandler } from '@standardagents/spec';
5
+
6
+ /**
7
+ * Callback function to execute before stream closes
8
+ */
9
+ type BeforeClose = () => Promise<void> | void;
10
+ /**
11
+ * Manages HTTP streaming of content chunks.
12
+ * WebSocket telemetry is handled separately by DurableThread.
13
+ * Inspired by bod.coach MultiplexedStream pattern.
14
+ */
15
+ declare class StreamManager {
16
+ /**
17
+ * HTTP ReadableStream controller for content
18
+ */
19
+ private httpController?;
20
+ /**
21
+ * HTTP ReadableStream for content chunks
22
+ */
23
+ httpStream: ReadableStream<Uint8Array>;
24
+ /**
25
+ * Active channels
26
+ */
27
+ activeChannels: number;
28
+ /**
29
+ * Before close hooks
30
+ */
31
+ private beforeCloseHooks;
32
+ /**
33
+ * Prevent automatic close
34
+ */
35
+ preventClose: boolean;
36
+ /**
37
+ * Text encoder for streams
38
+ */
39
+ private encoder;
40
+ /**
41
+ * Promise that resolves when stream is completely finished
42
+ */
43
+ then: Promise<void>;
44
+ /**
45
+ * Resolver for the then promise
46
+ */
47
+ private resolver;
48
+ /**
49
+ * Whether the stream has been closed
50
+ */
51
+ private closed;
52
+ constructor(beforeClose?: BeforeClose | BeforeClose[]);
53
+ /**
54
+ * Send content chunk to HTTP stream
55
+ */
56
+ sendContent(chunk: string): void;
57
+ /**
58
+ * Add a before close hook
59
+ */
60
+ addBeforeClose(hook: BeforeClose | BeforeClose[]): void;
61
+ /**
62
+ * Wait for a callback to complete before allowing stream to close
63
+ */
64
+ waitFor(callback: () => Promise<void> | void): Promise<void>;
65
+ /**
66
+ * Close a channel (decrement active channel count)
67
+ */
68
+ closeChannel(): void;
69
+ /**
70
+ * Close all streams and connections
71
+ */
72
+ close(): Promise<void>;
73
+ /**
74
+ * Force close the stream immediately
75
+ */
76
+ forceClose(): void;
77
+ }
78
+
79
+ /**
80
+ * Agent configuration from D1 agents table
81
+ */
82
+ interface Agent {
83
+ id: string;
84
+ title: string;
85
+ type: "dual_ai" | "ai_human";
86
+ created_at: number;
87
+ max_session_turns: number | null;
88
+ side_a_label: string | null;
89
+ side_a_agent_prompt: string | null;
90
+ side_a_stop_on_response: boolean;
91
+ side_a_stop_tool: string | null;
92
+ side_a_stop_tool_response_property: string | null;
93
+ side_a_max_steps: number | null;
94
+ side_a_end_session_tool: string | null;
95
+ side_b_label: string | null;
96
+ side_b_agent_prompt: string | null;
97
+ side_b_stop_on_response: boolean;
98
+ side_b_stop_tool: string | null;
99
+ side_b_stop_tool_response_property: string | null;
100
+ side_b_max_steps: number | null;
101
+ side_b_end_session_tool: string | null;
102
+ hooks?: string[];
103
+ }
104
+ /**
105
+ * Message in OpenAI chat completion format
106
+ */
107
+ interface Message {
108
+ id: string;
109
+ role: "system" | "user" | "assistant" | "tool";
110
+ content: string | null;
111
+ name?: string | null;
112
+ tool_calls?: string | null;
113
+ tool_call_id?: string | null;
114
+ log_id?: string | null;
115
+ created_at: number;
116
+ request_sent_at?: number | null;
117
+ response_completed_at?: number | null;
118
+ status?: "pending" | "completed" | "failed" | null;
119
+ silent?: boolean;
120
+ tool_status?: "success" | "error" | null;
121
+ reasoning_content?: string | null;
122
+ reasoning_details?: string | null;
123
+ parent_id?: string | null;
124
+ depth?: number;
125
+ attachments?: string | null;
126
+ }
127
+ /**
128
+ * Tool call from OpenAI format
129
+ */
130
+ interface ToolCall {
131
+ id: string;
132
+ type: "function";
133
+ function: {
134
+ name: string;
135
+ arguments: string;
136
+ };
137
+ forceAllow?: boolean;
138
+ queued_at?: number;
139
+ }
140
+ /**
141
+ * Thread metadata from DurableAgentBuilder
142
+ * Note: agent_id is now the agent name (not UUID) since agents are in TypeScript
143
+ */
144
+ interface ThreadMetadata {
145
+ id: string;
146
+ agent_id: string;
147
+ user_id: string | null;
148
+ tenvs: Record<string, unknown> | null;
149
+ properties: Record<string, unknown> | null;
150
+ created_at: number;
151
+ }
152
+ /**
153
+ * A loaded hook definition with its metadata.
154
+ * Generic K preserves the hook type for type-safe execution.
155
+ *
156
+ * @template K - Hook type from HookSignatures (e.g., 'filter_messages')
157
+ */
158
+ interface LoadedHook<K extends HookName = HookName> {
159
+ /** The hook type name */
160
+ hook: K;
161
+ /** The unique hook ID */
162
+ id: string;
163
+ /** The typed execute function */
164
+ execute: HookSignatures<ThreadState, HookMessage, HookToolCall, HookToolResult>[K];
165
+ }
166
+ /**
167
+ * Union type for any loaded hook (used when hook type isn't known statically).
168
+ * This creates a discriminated union on the `hook` property.
169
+ */
170
+ type AnyLoadedHook = {
171
+ [K in HookName]: LoadedHook<K>;
172
+ }[HookName];
173
+ /**
174
+ * Hook registry type - maps hook IDs to async loaders returning typed hooks.
175
+ * The new format uses hook IDs as keys (not hook type names).
176
+ */
177
+ type HookRegistry = Record<string, () => Promise<AnyLoadedHook | null>>;
178
+ /**
179
+ * Native tool module type - represents a loaded tool definition.
180
+ * Tools can have args (with validation schema) or no args.
181
+ * Uses local Zod types for compatibility with z.toJSONSchema().
182
+ */
183
+ interface NativeToolModule {
184
+ /** Description of what the tool does (shown to the LLM). */
185
+ description: string;
186
+ /** Zod schema for validating tool arguments, or null for no args. */
187
+ args: ZodObject<ZodRawShape> | null;
188
+ /** The tool implementation function. */
189
+ execute: ((state: any, args: Record<string, unknown>) => Promise<ToolResult$1>) | ((state: any) => Promise<ToolResult$1>);
190
+ /** Zod schema for thread environment variables, or null if none. */
191
+ tenvs?: ZodObject<ZodRawShape> | null;
192
+ /**
193
+ * Where this tool is executed:
194
+ * - 'local': Execute locally by the execution engine (default)
195
+ * - 'provider': Executed by the LLM provider, results come in response
196
+ */
197
+ executionMode?: 'local' | 'provider';
198
+ /**
199
+ * Which provider executes this tool (when executionMode='provider').
200
+ */
201
+ executionProvider?: string;
202
+ }
203
+ /**
204
+ * Thread instance (forward reference to avoid circular dependency)
205
+ */
206
+ interface ThreadInstance {
207
+ ctx: DurableObjectState;
208
+ env: ThreadEnv;
209
+ getMessages(limit?: number, offset?: number, order?: "asc" | "desc", includeSilent?: boolean, maxDepth?: number): Promise<{
210
+ messages: Message[];
211
+ total: number;
212
+ hasMore: boolean;
213
+ }>;
214
+ getLogs(limit?: number, offset?: number, order?: "asc" | "desc"): Promise<LogData[]>;
215
+ getThreadMeta(threadId: string): Promise<ThreadMetadata | null>;
216
+ deleteMessage(messageId: string): Promise<{
217
+ success: boolean;
218
+ error?: string;
219
+ }>;
220
+ shouldStop(): Promise<boolean>;
221
+ tools(): Record<string, () => Promise<NativeToolModule>>;
222
+ hooks(): HookRegistry;
223
+ loadModel(name: string): Promise<any>;
224
+ loadPrompt(name: string): Promise<any>;
225
+ loadAgent(name: string): Promise<any>;
226
+ loadTool(name: string): Promise<any>;
227
+ getPromptNames(): string[];
228
+ getAgentNames(): string[];
229
+ writeFile(path: string, data: string, mimeType: string, options?: Record<string, unknown>): Promise<any>;
230
+ writeTextFile(path: string, content: string, mimeType: string, options?: Record<string, unknown>): Promise<any>;
231
+ readFile(path: string): Promise<{
232
+ success: boolean;
233
+ data?: string;
234
+ error?: string;
235
+ }>;
236
+ statFile(path: string): Promise<any>;
237
+ readdirFile(path: string): Promise<any[]>;
238
+ unlinkFile(path: string): Promise<void>;
239
+ mkdirFile(path: string): Promise<any>;
240
+ rmdirFile(path: string): Promise<void>;
241
+ getFileStats(): Promise<any>;
242
+ grepFiles(pattern: string): Promise<any[]>;
243
+ findFiles(pattern: string): Promise<any>;
244
+ getFileThumbnail(path: string): Promise<ArrayBuffer | null>;
245
+ readFileChunk(path: string, chunkIndex: number): Promise<{
246
+ success: boolean;
247
+ data?: string;
248
+ error?: string;
249
+ }>;
250
+ runAgent(threadId: string, agentName: string): Promise<void>;
251
+ scheduleEffect(threadId: string, effectName: string, effectArgs: Record<string, unknown>, delayMs?: number): Promise<string>;
252
+ getScheduledEffects(name?: string): Promise<Array<{
253
+ id: string;
254
+ name: string;
255
+ args: Record<string, unknown>;
256
+ scheduledAt: number;
257
+ createdAt: number;
258
+ }>>;
259
+ removeScheduledEffect(id: string): Promise<boolean>;
260
+ insertOrphanedToolCall(params: {
261
+ content?: string;
262
+ toolCallId: string;
263
+ toolName: string;
264
+ toolArgs: string;
265
+ }): Promise<Response>;
266
+ }
267
+ /**
268
+ * Tool call for internal flow management
269
+ */
270
+ type FlowToolCall = {
271
+ tool: string;
272
+ args: Record<string, unknown>;
273
+ };
274
+ /**
275
+ * Prompt call for internal flow management
276
+ */
277
+ type FlowPromptCall = {
278
+ prompt: string;
279
+ args: Record<string, unknown>;
280
+ };
281
+ /**
282
+ * Flow call (tool or prompt)
283
+ */
284
+ type FlowCall = FlowToolCall | FlowPromptCall;
285
+ /**
286
+ * Flow call with retry tracking
287
+ */
288
+ type FlowCallWithRetries = FlowCall & {
289
+ retries: number;
290
+ reasons: string[];
291
+ };
292
+ /**
293
+ * Sub-prompt configuration - defines options for when a sub-prompt is called as a tool
294
+ */
295
+ interface SubpromptConfig {
296
+ name: string;
297
+ initUserMessageProperty?: string;
298
+ initAttachmentsProperty?: string;
299
+ includeTextResponse?: boolean;
300
+ includeToolCalls?: boolean;
301
+ includeErrors?: boolean;
302
+ }
303
+ /**
304
+ * Prompt configuration - now loaded from TypeScript virtual modules
305
+ */
306
+ interface PromptData {
307
+ id: string;
308
+ name: string;
309
+ prompt: string | any[];
310
+ system_prompt?: string;
311
+ model: string;
312
+ model_id?: string;
313
+ tool_description: string;
314
+ required_schema: string;
315
+ include_chat: boolean;
316
+ include_past_tools: boolean;
317
+ prompts: string;
318
+ created_at: number;
319
+ /** @deprecated All prompts are now automatically exposed as tools */
320
+ expose_as_tool?: boolean;
321
+ parallel_tool_calls: boolean;
322
+ tool_choice: "auto" | "none" | "required" | "function";
323
+ reasoning_effort: "low" | "medium" | "high" | null;
324
+ reasoning_max_tokens: number | null;
325
+ reasoning_exclude: boolean;
326
+ include_reasoning: boolean;
327
+ recentImageThreshold: number | null;
328
+ _tools?: (string | SubpromptConfig)[];
329
+ _requiredSchema?: unknown;
330
+ _hooks?: string[];
331
+ }
332
+ /**
333
+ * Central state object that flows through execution
334
+ */
335
+ interface FlowState {
336
+ threadId: string;
337
+ flowId: string;
338
+ thread: {
339
+ instance: ThreadInstance;
340
+ metadata: ThreadMetadata;
341
+ };
342
+ agentConfig: Agent;
343
+ currentSide: "a" | "b";
344
+ prompts: {
345
+ sideA: PromptData;
346
+ sideB: PromptData | null;
347
+ };
348
+ prompt: PromptData;
349
+ stepCount: number;
350
+ sideAStepCount: number;
351
+ sideBStepCount: number;
352
+ stopped: boolean;
353
+ stoppedBy?: "a" | "b";
354
+ forcedNextSide?: "side_a" | "side_b";
355
+ pendingForceTurn?: "side_a" | "side_b";
356
+ abortController?: AbortController;
357
+ messageHistory: Message[];
358
+ /**
359
+ * Appends these messages
360
+ */
361
+ extraMessages: Message[];
362
+ sequence: {
363
+ queue: ToolCall[];
364
+ queuedTools: ToolCall[];
365
+ isHandling: boolean;
366
+ };
367
+ active: FlowCallWithRetries;
368
+ queue: FlowCall[];
369
+ pendingHandoff?: {
370
+ agentId: string;
371
+ args?: Record<string, unknown>;
372
+ toolConfig?: {
373
+ initUserMessageProperty?: string;
374
+ initAttachmentsProperty?: string;
375
+ };
376
+ };
377
+ stream: StreamManager;
378
+ context: Record<string, unknown>;
379
+ retryCount: number;
380
+ retryReason?: string;
381
+ storage: DurableObjectStorage;
382
+ env: ThreadEnv;
383
+ emitLog?: (log: unknown) => void;
384
+ emitMessage?: (message: unknown) => void;
385
+ emitMessageChunk?: (messageId: string, chunk: string, depth?: number) => void;
386
+ emitTelemetry?: (event: TelemetryEvent) => void;
387
+ emitEvent?: (type: string, data: unknown) => void;
388
+ rootState: FlowState;
389
+ rootMessageId?: string | null;
390
+ parentLogId?: string | null;
391
+ currentLogId?: string | null;
392
+ parentMessageId?: string;
393
+ depth: number;
394
+ /** Path from root prompt to current prompt (e.g., ['basic_prompt', 'generate_image']) */
395
+ promptPath: string[];
396
+ pendingMessageId?: string;
397
+ allowedTools?: ToolDefinition[];
398
+ pendingMetadataPromises?: Promise<void>[];
399
+ /**
400
+ * Current namespace context for execution.
401
+ * Determines what tools, prompts, and agents are visible.
402
+ * - { type: 'global' } for unpacked agents
403
+ * - { type: 'packed', packageId: '...' } for packed agents
404
+ */
405
+ namespaceContext: {
406
+ type: 'global';
407
+ } | {
408
+ type: 'packed';
409
+ packageId: string;
410
+ };
411
+ /**
412
+ * The `uses` list from the currently executing tool.
413
+ * Used by queueTool/invokeTool to validate allowed calls.
414
+ * Undefined means no restriction (global context or tool without uses).
415
+ */
416
+ currentToolUses?: string[];
417
+ }
418
+ /**
419
+ * Text content part for multimodal messages
420
+ */
421
+ interface TextContentPart {
422
+ type: "text";
423
+ text: string;
424
+ }
425
+ /**
426
+ * Image URL content part for multimodal messages (OpenAI/OpenRouter format)
427
+ */
428
+ interface ImageContentPart {
429
+ type: "image_url";
430
+ image_url: {
431
+ url: string;
432
+ detail?: "auto" | "low" | "high";
433
+ };
434
+ }
435
+ /**
436
+ * Multimodal content - array of text and image parts
437
+ */
438
+ type MultimodalContent = Array<TextContentPart | ImageContentPart>;
439
+ /**
440
+ * Message content - can be string (text only) or array (multimodal)
441
+ */
442
+ type MessageContent = string | MultimodalContent;
443
+ /**
444
+ * Request context for LLM calls
445
+ */
446
+ interface RequestContext {
447
+ messages: Array<{
448
+ role: "system" | "user" | "assistant" | "tool";
449
+ content?: MessageContent;
450
+ tool_calls?: ToolCall[];
451
+ tool_call_id?: string;
452
+ name?: string;
453
+ reasoning_content?: string;
454
+ reasoning_details?: any[];
455
+ attachments?: any[];
456
+ toolName?: string;
457
+ }>;
458
+ model: string;
459
+ tools?: ToolDefinition[];
460
+ stream?: boolean;
461
+ promptName?: string;
462
+ systemPrompt?: string;
463
+ parentLogId?: string | null;
464
+ parallel_tool_calls?: boolean;
465
+ tool_choice?: "auto" | "none" | "required" | {
466
+ type: "function";
467
+ function: {
468
+ name: string;
469
+ };
470
+ };
471
+ reasoning?: {
472
+ effort?: "low" | "medium" | "high";
473
+ max_tokens?: number;
474
+ exclude?: boolean;
475
+ };
476
+ imagePathMap?: Map<string, string>;
477
+ }
478
+ /**
479
+ * Tool definition for LLM requests
480
+ */
481
+ interface ToolDefinition {
482
+ type: "function";
483
+ function: {
484
+ name: string;
485
+ description: string;
486
+ parameters?: Record<string, any>;
487
+ };
488
+ /**
489
+ * Where this tool is executed:
490
+ * - 'local': Execute locally by the execution engine (default)
491
+ * - 'provider': Executed by the LLM provider, results come in response
492
+ */
493
+ executionMode?: 'local' | 'provider';
494
+ /**
495
+ * Which provider executes this tool (when executionMode='provider')
496
+ * e.g., 'openai', 'anthropic'
497
+ */
498
+ executionProvider?: string;
499
+ }
500
+ /**
501
+ * Image returned by an LLM response (e.g., from image generation models)
502
+ * Format follows OpenAI/OpenRouter chat completions API
503
+ */
504
+ interface LLMResponseImage {
505
+ type: "image_url";
506
+ /** Unique ID for this generated image (used to link to tool call) */
507
+ id?: string;
508
+ /** Name of the tool that generated this image (e.g., 'image_generation') */
509
+ toolName?: string;
510
+ /** The revised/actual prompt used to generate the image (from OpenAI's image_generation) */
511
+ revisedPrompt?: string;
512
+ image_url: {
513
+ url: string;
514
+ };
515
+ }
516
+ /**
517
+ * LLM response
518
+ */
519
+ interface LLMResponse {
520
+ id: string;
521
+ model: string;
522
+ content: string | null;
523
+ reasoning_content?: string | null;
524
+ reasoning_details?: any[];
525
+ tool_calls?: ToolCall[];
526
+ images?: LLMResponseImage[];
527
+ finish_reason: string;
528
+ usage: {
529
+ prompt_tokens: number;
530
+ completion_tokens: number;
531
+ total_tokens: number;
532
+ prompt_tokens_details?: {
533
+ cached_tokens?: number;
534
+ };
535
+ completion_tokens_details?: {
536
+ reasoning_tokens?: number;
537
+ };
538
+ cost?: number;
539
+ provider?: string;
540
+ };
541
+ /** @internal Provider instance reference for async metadata fetching */
542
+ _provider?: unknown;
543
+ /** @internal Provider response ID for async metadata fetching */
544
+ _providerResponseId?: string;
545
+ /** @internal Aggregate response for logging */
546
+ _aggregate_response?: unknown;
547
+ }
548
+ /**
549
+ * Attachment returned by a tool (e.g., generated images)
550
+ * Stored in thread filesystem and linked to the tool message
551
+ */
552
+ interface ToolAttachment {
553
+ name: string;
554
+ mimeType: string;
555
+ data: string;
556
+ width?: number;
557
+ height?: number;
558
+ }
559
+ /**
560
+ * Tool result
561
+ */
562
+ interface ToolResult {
563
+ status: "success" | "error";
564
+ /**
565
+ * Flattened text representation of the tool output.
566
+ *
567
+ * For tools that return structured MCP-style content (an array of
568
+ * content parts), this will be derived by concatenating all text
569
+ * parts. For legacy tools that returned a plain string `result`,
570
+ * that value is used directly.
571
+ */
572
+ result?: string;
573
+ error?: string;
574
+ stack?: string;
575
+ /**
576
+ * File attachments returned by the tool.
577
+ *
578
+ * Can contain either:
579
+ * - ToolAttachment: New files with base64 data to be stored
580
+ * - AttachmentRef: References to existing files in the thread filesystem
581
+ *
582
+ * New attachments are stored under /attachments/ directory.
583
+ */
584
+ attachments?: Array<ToolAttachment | AttachmentRef>;
585
+ }
586
+ /**
587
+ * Flow execution result
588
+ */
589
+ interface FlowResult {
590
+ messages: Message[];
591
+ stopped: boolean;
592
+ stoppedBy?: "a" | "b";
593
+ stepCount: number;
594
+ stream: ReadableStream<Uint8Array>;
595
+ }
596
+ /**
597
+ * Telemetry event types
598
+ */
599
+ type TelemetryEvent = {
600
+ type: "step_started";
601
+ step: number;
602
+ side: "a" | "b";
603
+ timestamp: number;
604
+ } | {
605
+ type: "step_completed";
606
+ step: number;
607
+ stopped: boolean;
608
+ timestamp: number;
609
+ } | {
610
+ type: "llm_request";
611
+ model: string;
612
+ attempt: number;
613
+ timestamp: number;
614
+ } | {
615
+ type: "llm_response";
616
+ tokens: number;
617
+ latency: number;
618
+ timestamp: number;
619
+ } | {
620
+ type: "validation_failed";
621
+ error: string;
622
+ timestamp: number;
623
+ } | {
624
+ type: "fallback_triggered";
625
+ from: string;
626
+ to: string;
627
+ timestamp: number;
628
+ } | {
629
+ type: "tool_started";
630
+ tool: string;
631
+ timestamp: number;
632
+ } | {
633
+ type: "tool_completed";
634
+ tool: string;
635
+ status: string;
636
+ timestamp: number;
637
+ } | {
638
+ type: "stopped";
639
+ reason: string;
640
+ side: "a" | "b";
641
+ timestamp: number;
642
+ } | {
643
+ type: "stopped_by_user";
644
+ timestamp: number;
645
+ };
646
+ /**
647
+ * Log data for telemetry table
648
+ */
649
+ interface LogData {
650
+ id: string;
651
+ message_id: string;
652
+ provider: string;
653
+ model: string;
654
+ model_name?: string;
655
+ endpoint?: string;
656
+ request_body?: string;
657
+ request_headers?: string;
658
+ response_body?: string;
659
+ response_headers?: string;
660
+ status_code?: number;
661
+ reasoning_content?: string | null;
662
+ input_tokens?: number;
663
+ cached_tokens?: number;
664
+ output_tokens?: number;
665
+ reasoning_tokens?: number;
666
+ total_tokens?: number;
667
+ latency_ms?: number;
668
+ time_to_first_token_ms?: number;
669
+ finish_reason?: string;
670
+ error?: string;
671
+ error_type?: string;
672
+ cost_input?: number;
673
+ cost_output?: number;
674
+ cost_total?: number;
675
+ message_history_length?: number;
676
+ tools_available?: number;
677
+ prompt_name?: string;
678
+ tools_called?: string;
679
+ queued_tools?: string;
680
+ actual_provider?: string | null;
681
+ parent_log_id?: string | null;
682
+ tools_schema?: string | null;
683
+ message_history?: string | null;
684
+ system_prompt?: string | null;
685
+ is_complete?: boolean;
686
+ errors?: string | null;
687
+ retry_of_log_id?: string | null;
688
+ created_at: number;
689
+ }
690
+ /**
691
+ * Base environment interface for StandardAgents.
692
+ * Extends ThreadEnv with optional provider API keys.
693
+ *
694
+ * User's Env interface should extend this or include these bindings.
695
+ */
696
+ interface Env extends ThreadEnv {
697
+ OPENAI_API_KEY?: string;
698
+ ANTHROPIC_API_KEY?: string;
699
+ OPENROUTER_API_KEY?: string;
700
+ GOOGLE_API_KEY?: string;
701
+ UI_DEV_SERVER?: string;
702
+ ASSETS?: {
703
+ fetch(request: Request | string): Promise<Response>;
704
+ };
705
+ GITHUB_TOKEN?: string;
706
+ GITHUB_REPO?: string;
707
+ GITHUB_BRANCH?: string;
708
+ SUPER_ADMIN_PASSWORD?: string;
709
+ ENCRYPTION_KEY?: string;
710
+ [key: string]: unknown;
711
+ }
712
+ /**
713
+ * Storage backend types for files
714
+ */
715
+ type StorageBackend = "local" | "url" | "s3" | "r2";
716
+ /**
717
+ * File record stored in the files table
718
+ */
719
+ interface FileRecord {
720
+ path: string;
721
+ name: string;
722
+ mimeType: string;
723
+ storage: StorageBackend;
724
+ location?: string | null;
725
+ size: number;
726
+ metadata?: Record<string, unknown> | null;
727
+ isDirectory: boolean;
728
+ createdAt: number;
729
+ width?: number | null;
730
+ height?: number | null;
731
+ isChunked?: boolean;
732
+ chunkCount?: number;
733
+ }
734
+ /**
735
+ * Image-specific metadata stored in FileRecord.metadata
736
+ */
737
+ interface ImageMetadata {
738
+ width: number;
739
+ height: number;
740
+ }
741
+ /**
742
+ * Attachment reference stored in messages.attachments (JSON array)
743
+ */
744
+ interface AttachmentRef {
745
+ id: string;
746
+ type: "file";
747
+ path: string;
748
+ name: string;
749
+ mimeType: string;
750
+ size: number;
751
+ width?: number;
752
+ height?: number;
753
+ description?: string;
754
+ }
755
+ /**
756
+ * Grep search result
757
+ */
758
+ interface GrepResult {
759
+ path: string;
760
+ name: string;
761
+ matches: string[];
762
+ lineNumbers?: number[];
763
+ }
764
+ /**
765
+ * File stats for storage tracking
766
+ */
767
+ interface FileStats {
768
+ totalSize: number;
769
+ fileCount: number;
770
+ }
771
+
772
+ /**
773
+ * Router and endpoint definition module for AgentBuilder.
774
+ *
775
+ * This module re-exports endpoint types from @standardagents/spec and provides
776
+ * the runtime router implementation for handling HTTP requests.
777
+ *
778
+ * @module
779
+ */
780
+
781
+ /**
782
+ * Durable Object namespace interface.
783
+ * This is Cloudflare-specific and used by the builder runtime.
784
+ */
785
+ interface DurableObjectNamespace<T = unknown> {
786
+ idFromName(name: string): DurableObjectId;
787
+ idFromString(id: string): DurableObjectId;
788
+ newUniqueId(): DurableObjectId;
789
+ get(id: DurableObjectId): DurableObjectStub<T>;
790
+ }
791
+ /**
792
+ * Durable Object ID interface.
793
+ */
794
+ interface DurableObjectId {
795
+ toString(): string;
796
+ equals(other: DurableObjectId): boolean;
797
+ }
798
+ /**
799
+ * Durable Object stub interface.
800
+ * The generic type T represents the RPC methods available on the stub.
801
+ */
802
+ type DurableObjectStub<T = unknown> = {
803
+ id: DurableObjectId;
804
+ name?: string;
805
+ fetch(request: Request | string, requestInitr?: RequestInit): Promise<Response>;
806
+ } & T;
807
+ /**
808
+ * Log entry from DurableThread.getLogs()
809
+ */
810
+ interface LogEntry {
811
+ id: string;
812
+ message_id: string;
813
+ provider: string;
814
+ model: string;
815
+ model_name: string | null;
816
+ prompt_name: string | null;
817
+ tools_called: string | null;
818
+ parent_log_id: string | null;
819
+ retry_of_log_id: string | null;
820
+ error: string | null;
821
+ cost_total: number | null;
822
+ is_complete: number;
823
+ created_at: number;
824
+ request_body: string | null;
825
+ }
826
+ /**
827
+ * Response from getThreadMeta()
828
+ */
829
+ interface ThreadMetaResponse {
830
+ thread: ThreadRegistryEntry;
831
+ agent: AgentDefinition | null;
832
+ stats: {
833
+ messageCount: number;
834
+ logCount: number;
835
+ lastActivity: number | null;
836
+ };
837
+ }
838
+ /**
839
+ * Log details returned by getLogDetails
840
+ */
841
+ interface LogDetails {
842
+ id: string;
843
+ message_id: string;
844
+ provider: string;
845
+ actual_provider: string | null;
846
+ model: string;
847
+ model_name: string | null;
848
+ endpoint: string | null;
849
+ request_body: string | null;
850
+ request_headers: string | null;
851
+ response_body: string | null;
852
+ response_headers: string | null;
853
+ status_code: number | null;
854
+ reasoning_content: string | null;
855
+ input_tokens: number | null;
856
+ cached_tokens: number | null;
857
+ output_tokens: number | null;
858
+ reasoning_tokens: number | null;
859
+ total_tokens: number | null;
860
+ latency_ms: number | null;
861
+ time_to_first_token_ms: number | null;
862
+ finish_reason: string | null;
863
+ error: string | null;
864
+ error_type: string | null;
865
+ cost_input: number | null;
866
+ cost_output: number | null;
867
+ cost_total: number | null;
868
+ message_history_length: number | null;
869
+ tools_available: number | null;
870
+ prompt_name: string | null;
871
+ tools_called: string | null;
872
+ provider_tools: string | null;
873
+ parent_log_id: string | null;
874
+ tools_schema: string | null;
875
+ system_prompt: string | null;
876
+ errors: string | null;
877
+ retry_of_log_id: string | null;
878
+ tool_results: string | null;
879
+ is_complete: number;
880
+ created_at: number;
881
+ }
882
+ /**
883
+ * RPC methods exposed by DurableThread for external callers.
884
+ */
885
+ interface DurableThreadRpc {
886
+ stop(): Promise<Response>;
887
+ getMessages(limit?: number, offset?: number, order?: "ASC" | "DESC", includeSilent?: boolean, maxDepth?: number): Promise<{
888
+ messages: unknown[];
889
+ total: number;
890
+ hasMore: boolean;
891
+ }>;
892
+ deleteMessage(messageId: string): Promise<{
893
+ success: boolean;
894
+ error?: string;
895
+ }>;
896
+ updateMessageContent(messageId: string, content: string): Promise<{
897
+ success: boolean;
898
+ error?: string;
899
+ }>;
900
+ getLogs(limit?: number, offset?: number, order?: "ASC" | "DESC"): Promise<{
901
+ logs: LogEntry[];
902
+ total: number;
903
+ hasMore: boolean;
904
+ }>;
905
+ getLogDetails(logId: string): Promise<LogDetails | null>;
906
+ getThreadMeta(threadId: string): Promise<ThreadMetaResponse | null>;
907
+ deleteThread(): Promise<void>;
908
+ readFile(path: string): Promise<{
909
+ success: boolean;
910
+ data?: string;
911
+ error?: string;
912
+ }>;
913
+ }
914
+ /**
915
+ * Thread registry entry from DurableAgentBuilder.
916
+ */
917
+ interface ThreadRegistryEntry {
918
+ id: string;
919
+ agent_name: string;
920
+ user_id: string | null;
921
+ tags: string[] | null;
922
+ created_at: number;
923
+ }
924
+ /**
925
+ * RPC methods exposed by DurableAgentBuilder for external callers.
926
+ */
927
+ interface DurableAgentBuilderRpc {
928
+ createThread(params: {
929
+ agent_name: string;
930
+ user_id?: string;
931
+ tags?: string[];
932
+ tenvs?: Record<string, unknown>;
933
+ properties?: Record<string, unknown>;
934
+ }): Promise<ThreadRegistryEntry>;
935
+ getThread(threadId: string): Promise<ThreadRegistryEntry | null>;
936
+ listThreads(params?: {
937
+ agent_name?: string;
938
+ user_id?: string;
939
+ search?: string;
940
+ startDate?: number;
941
+ endDate?: number;
942
+ limit?: number;
943
+ offset?: number;
944
+ }): Promise<{
945
+ threads: ThreadRegistryEntry[];
946
+ total: number;
947
+ }>;
948
+ deleteThread(threadId: string): Promise<void>;
949
+ getUserByUsername(username: string): Promise<unknown>;
950
+ createSession(session: {
951
+ user_id: string;
952
+ token_hash: string;
953
+ expires_at: number;
954
+ }): Promise<void>;
955
+ loadAgent(name: string): Promise<AgentDefinition>;
956
+ }
957
+ /**
958
+ * Minimum required environment bindings for thread endpoints.
959
+ * User's Env interface should extend this.
960
+ *
961
+ * This is Cloudflare-specific and used by the builder runtime.
962
+ */
963
+ interface ThreadEnv {
964
+ AGENT_BUILDER_THREAD: DurableObjectNamespace<DurableThreadRpc>;
965
+ AGENT_BUILDER: DurableObjectNamespace<DurableAgentBuilderRpc>;
966
+ [key: string]: unknown;
967
+ }
968
+ /**
969
+ * Builder-specific controller context with typed env.
970
+ *
971
+ * This extends the spec's ControllerContext with proper typing for
972
+ * Cloudflare environment bindings.
973
+ */
974
+ interface BuilderControllerContext<Env extends ThreadEnv = ThreadEnv> extends Omit<ControllerContext, 'env'> {
975
+ env: Env;
976
+ /** Namespaced registry for packed agent support */
977
+ registry?: NamespacedRegistry;
978
+ }
979
+ /**
980
+ * Builder-specific controller type with typed env.
981
+ */
982
+ type BuilderController<Env extends ThreadEnv = ThreadEnv> = (context: BuilderControllerContext<Env>) => ReturnType<Controller>;
983
+ /**
984
+ * Thread endpoint context with access to thread instance and metadata.
985
+ * @deprecated Use ThreadState instead
986
+ */
987
+ interface ThreadEndpointContext {
988
+ req: Request;
989
+ thread: {
990
+ instance: ThreadInstance;
991
+ metadata: ThreadMetadata;
992
+ };
993
+ }
994
+ /**
995
+ * Handler function for builder thread endpoints.
996
+ *
997
+ * Receives the request and a ThreadState object per the Standard Agents spec.
998
+ * The ThreadState provides access to thread identity, messages, logs,
999
+ * resource loading, tool invocation, and more.
1000
+ *
1001
+ * Note: `state.execution` is always null in endpoints since the thread
1002
+ * is not actively executing.
1003
+ */
1004
+ type BuilderThreadEndpointHandler = ThreadEndpointHandler;
1005
+
1006
+ /**
1007
+ * Define a controller with typed Cloudflare environment bindings.
1008
+ *
1009
+ * This is the builder's version of defineController that provides
1010
+ * proper typing for AGENT_BUILDER_THREAD and other CF bindings.
1011
+ *
1012
+ * @example
1013
+ * ```typescript
1014
+ * import { defineController } from '../router/index.js';
1015
+ *
1016
+ * export default defineController(async ({ req, env }) => {
1017
+ * const stub = env.AGENT_BUILDER.get(env.AGENT_BUILDER.idFromName('singleton'));
1018
+ * // ...
1019
+ * });
1020
+ * ```
1021
+ */
1022
+ declare function defineController<Env extends ThreadEnv = ThreadEnv>(controller: BuilderController<Env>): BuilderController<Env>;
1023
+ /**
1024
+ * Runtime implementation for defineThreadEndpoint.
1025
+ *
1026
+ * This wraps the spec's defineThreadEndpoint to provide the actual
1027
+ * thread lookup and ThreadState creation at runtime.
1028
+ *
1029
+ * @param handler - Function that receives the request and ThreadState
1030
+ * @returns A Controller that can be used with the router
1031
+ *
1032
+ * @example
1033
+ * // agentbuilder/api/threads/[id]/status.get.ts
1034
+ * import { defineThreadEndpoint } from '@standardagents/spec';
1035
+ *
1036
+ * export default defineThreadEndpoint(async (req, state) => {
1037
+ * const { messages } = await state.getMessages({ limit: 1 });
1038
+ * return Response.json({ status: "ok", messageCount: messages.length });
1039
+ * });
1040
+ */
1041
+ declare function createThreadEndpointHandler<Env extends ThreadEnv = ThreadEnv>(handler: ThreadEndpointHandler): BuilderController<Env>;
1042
+
1043
+ export { type AttachmentRef as A, type BuilderController as B, type Env as E, type FileRecord as F, type GrepResult as G, type ImageMetadata as I, type LLMResponse as L, type Message as M, type RequestContext as R, type StorageBackend as S, type ThreadEnv as T, type ThreadMetadata as a, type FlowState as b, type FileStats as c, type MessageContent as d, defineController as e, createThreadEndpointHandler as f, type BuilderControllerContext as g, type ThreadEndpointContext as h, type BuilderThreadEndpointHandler as i, type Agent as j, type ThreadInstance as k, type ToolCall as l, type ToolResult as m, type FlowResult as n, type TelemetryEvent as o, type TextContentPart as p, type ImageContentPart as q, type MultimodalContent as r };