@standardagents/builder 0.8.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.
- package/client.d.ts +73 -0
- package/dist/built-in-routes.js +2333 -0
- package/dist/built-in-routes.js.map +1 -0
- package/dist/client/agents/monacoeditorwork/json.worker.bundle.js +21320 -0
- package/dist/client/assets/codicon.ttf +0 -0
- package/dist/client/assets/editor.worker-CdtUXE0K.js +12 -0
- package/dist/client/assets/img/meta.svg +19 -0
- package/dist/client/assets/img/moonshotai.svg +4 -0
- package/dist/client/assets/img/zai.svg +219 -0
- package/dist/client/assets/index.css +1 -0
- package/dist/client/assets/json.worker-C21G4-GD.js +49 -0
- package/dist/client/assets/monaco.css +1 -0
- package/dist/client/index.html +38 -0
- package/dist/client/index.js +39 -0
- package/dist/client/monaco.js +1508 -0
- package/dist/client/vendor.js +1 -0
- package/dist/client/vue.js +143 -0
- package/dist/index.d.ts +2962 -0
- package/dist/index.js +11016 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.js +663 -0
- package/dist/mcp.js.map +1 -0
- package/dist/plugin.d.ts +14 -0
- package/dist/plugin.js +3183 -0
- package/dist/plugin.js.map +1 -0
- package/dist/rou3.js +157 -0
- package/dist/rou3.js.map +1 -0
- package/package.json +97 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,2962 @@
|
|
|
1
|
+
export { AgentPluginOptions, agentbuilder } from './plugin.js';
|
|
2
|
+
import { DurableObjectStorage } from '@cloudflare/workers-types';
|
|
3
|
+
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { z, ZodString, ZodNumber, ZodBoolean, ZodNull, ZodLiteral, ZodEnum, ZodOptional, ZodNullable, ZodDefault, ZodArray, ZodObject, ZodRecord, ZodUnion } from 'zod';
|
|
5
|
+
import { DurableObject } from 'cloudflare:workers';
|
|
6
|
+
import 'vite';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Global namespace for AgentBuilder types.
|
|
10
|
+
*
|
|
11
|
+
* This namespace provides type-safe references for models, prompts, agents, and tools.
|
|
12
|
+
* Types are automatically populated when you run `pnpm dev` or `pnpm build`,
|
|
13
|
+
* which scans your `agentbuilder/` directories and generates types.
|
|
14
|
+
*
|
|
15
|
+
* The generated types are placed in `.agentbuilder/types.d.ts` and augment this namespace.
|
|
16
|
+
*
|
|
17
|
+
* Note: We use interfaces as type registries because TypeScript allows interface
|
|
18
|
+
* declaration merging. The user's generated types will add properties to these
|
|
19
|
+
* interfaces, and we extract the union of all property keys.
|
|
20
|
+
*/
|
|
21
|
+
declare global {
|
|
22
|
+
namespace AgentBuilder {
|
|
23
|
+
/**
|
|
24
|
+
* Interface for model type registration.
|
|
25
|
+
* Generated types add properties: interface ModelRegistry { 'gpt-4o': true; 'claude-3': true; }
|
|
26
|
+
* This gives us: type Models = keyof ModelRegistry = 'gpt-4o' | 'claude-3'
|
|
27
|
+
*/
|
|
28
|
+
interface ModelRegistry {
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Interface for prompt type registration.
|
|
32
|
+
*/
|
|
33
|
+
interface PromptRegistry {
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Interface for agent type registration.
|
|
37
|
+
*/
|
|
38
|
+
interface AgentRegistry {
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Interface for tool type registration.
|
|
42
|
+
*/
|
|
43
|
+
interface ToolRegistry {
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Interface for callable type registration (prompts, agents, tools).
|
|
47
|
+
*/
|
|
48
|
+
interface CallableRegistry {
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Union type of all model names defined in agentbuilder/models/.
|
|
52
|
+
* When ModelRegistry is empty, this defaults to string for flexibility.
|
|
53
|
+
* When populated, it narrows to the specific model names.
|
|
54
|
+
*/
|
|
55
|
+
type Models = keyof ModelRegistry extends never ? string : keyof ModelRegistry;
|
|
56
|
+
/**
|
|
57
|
+
* Union type of all prompt names defined in agentbuilder/prompts/.
|
|
58
|
+
*/
|
|
59
|
+
type Prompts = keyof PromptRegistry extends never ? string : keyof PromptRegistry;
|
|
60
|
+
/**
|
|
61
|
+
* Union type of all agent names defined in agentbuilder/agents/.
|
|
62
|
+
*/
|
|
63
|
+
type Agents = keyof AgentRegistry extends never ? string : keyof AgentRegistry;
|
|
64
|
+
/**
|
|
65
|
+
* Union type of all tool names defined in agentbuilder/tools/.
|
|
66
|
+
*/
|
|
67
|
+
type Tools = keyof ToolRegistry extends never ? string : keyof ToolRegistry;
|
|
68
|
+
/**
|
|
69
|
+
* Union type of all callable items (prompts, agents, tools) that can be used as tools.
|
|
70
|
+
*/
|
|
71
|
+
type Callables = keyof CallableRegistry extends never ? string : keyof CallableRegistry;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Callback function to execute before stream closes
|
|
77
|
+
*/
|
|
78
|
+
type BeforeClose = () => Promise<void> | void;
|
|
79
|
+
/**
|
|
80
|
+
* Manages multiplexed streaming of content (HTTP) and telemetry (WebSocket)
|
|
81
|
+
* Inspired by bod.coach MultiplexedStream pattern
|
|
82
|
+
*/
|
|
83
|
+
declare class StreamManager {
|
|
84
|
+
/**
|
|
85
|
+
* HTTP ReadableStream controller for content
|
|
86
|
+
*/
|
|
87
|
+
private httpController?;
|
|
88
|
+
/**
|
|
89
|
+
* HTTP ReadableStream for content chunks
|
|
90
|
+
*/
|
|
91
|
+
httpStream: ReadableStream<Uint8Array>;
|
|
92
|
+
/**
|
|
93
|
+
* WebSocket connections for telemetry
|
|
94
|
+
*/
|
|
95
|
+
private wsConnections;
|
|
96
|
+
/**
|
|
97
|
+
* Active channels
|
|
98
|
+
*/
|
|
99
|
+
activeChannels: number;
|
|
100
|
+
/**
|
|
101
|
+
* Before close hooks
|
|
102
|
+
*/
|
|
103
|
+
private beforeCloseHooks;
|
|
104
|
+
/**
|
|
105
|
+
* Prevent automatic close
|
|
106
|
+
*/
|
|
107
|
+
preventClose: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Text encoder for streams
|
|
110
|
+
*/
|
|
111
|
+
private encoder;
|
|
112
|
+
/**
|
|
113
|
+
* Promise that resolves when stream is completely finished
|
|
114
|
+
*/
|
|
115
|
+
then: Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Resolver for the then promise
|
|
118
|
+
*/
|
|
119
|
+
private resolver;
|
|
120
|
+
/**
|
|
121
|
+
* Whether the stream has been closed
|
|
122
|
+
*/
|
|
123
|
+
private closed;
|
|
124
|
+
constructor(beforeClose?: BeforeClose | BeforeClose[]);
|
|
125
|
+
/**
|
|
126
|
+
* Send content chunk to HTTP stream
|
|
127
|
+
*/
|
|
128
|
+
sendContent(chunk: string): void;
|
|
129
|
+
/**
|
|
130
|
+
* Send telemetry event to all WebSocket connections
|
|
131
|
+
*/
|
|
132
|
+
sendTelemetry(event: TelemetryEvent): void;
|
|
133
|
+
/**
|
|
134
|
+
* Emit a custom event to all WebSocket connections
|
|
135
|
+
*
|
|
136
|
+
* This sends a custom event message that can be received by frontend
|
|
137
|
+
* clients using the onThreadEvent hook.
|
|
138
|
+
*
|
|
139
|
+
* @param type - The event type name
|
|
140
|
+
* @param data - The event payload (any serializable data)
|
|
141
|
+
*/
|
|
142
|
+
emitEvent(type: string, data: unknown): void;
|
|
143
|
+
/**
|
|
144
|
+
* Add a WebSocket connection for telemetry
|
|
145
|
+
*/
|
|
146
|
+
addWebSocket(ws: WebSocket): void;
|
|
147
|
+
/**
|
|
148
|
+
* Add a before close hook
|
|
149
|
+
*/
|
|
150
|
+
addBeforeClose(hook: BeforeClose | BeforeClose[]): void;
|
|
151
|
+
/**
|
|
152
|
+
* Wait for a callback to complete before allowing stream to close
|
|
153
|
+
*/
|
|
154
|
+
waitFor(callback: () => Promise<void> | void): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Close a channel (decrement active channel count)
|
|
157
|
+
*/
|
|
158
|
+
closeChannel(): void;
|
|
159
|
+
/**
|
|
160
|
+
* Close all streams and connections
|
|
161
|
+
*/
|
|
162
|
+
close(): Promise<void>;
|
|
163
|
+
/**
|
|
164
|
+
* Force close the stream immediately
|
|
165
|
+
*/
|
|
166
|
+
forceClose(): void;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Decrement helper to stop recursion at depth 0 */
|
|
170
|
+
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;
|
|
171
|
+
/**
|
|
172
|
+
* Allowed Zod node for tool arguments.
|
|
173
|
+
* Tweak this union as your single source of truth for what’s allowed.
|
|
174
|
+
* Increase the default depth if you need crazier nesting.
|
|
175
|
+
*/
|
|
176
|
+
type ToolArgsNode<D extends number = 7> = ZodString | ZodNumber | ZodBoolean | ZodNull | ZodLiteral<string | number | boolean | null> | ZodEnum<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<[
|
|
177
|
+
ToolArgsNode<Dec<D>>,
|
|
178
|
+
ToolArgsNode<Dec<D>>,
|
|
179
|
+
...ToolArgsNode<Dec<D>>[]
|
|
180
|
+
]>);
|
|
181
|
+
/**
|
|
182
|
+
* Raw shape for an object whose values are ToolArgsNode.
|
|
183
|
+
* This is what users write inside z.object({ ... }).
|
|
184
|
+
*/
|
|
185
|
+
type ToolArgsRawShape<D extends number = 7> = Record<string, ToolArgsNode<D>>;
|
|
186
|
+
/** The top-level schema must be an object for OpenAI tools. */
|
|
187
|
+
type ToolArgs<D extends number = 7> = z.ZodObject<ToolArgsRawShape<D>>;
|
|
188
|
+
type StructuredToolReturn = ToolArgs;
|
|
189
|
+
/**
|
|
190
|
+
* Defines a tool function. Tools accept the current flow state as well as the arguments being passed to them.
|
|
191
|
+
*/
|
|
192
|
+
type Tool<Args extends ToolArgs | null = null> = Args extends ToolArgs ? (flow: FlowState, args: z.infer<Args>) => Promise<CallToolResult> : (flow: FlowState) => Promise<CallToolResult>;
|
|
193
|
+
/**
|
|
194
|
+
* @param toolDescription - Description of what the tool does.
|
|
195
|
+
* @param args - The arguments for the tool.
|
|
196
|
+
* @param tool - The tool function.
|
|
197
|
+
* @returns A tuple containing the description, arguments and the tool function.
|
|
198
|
+
*/
|
|
199
|
+
declare function defineTool<Args extends ToolArgs>(toolDescription: string, args: Args, tool: Tool<Args>): [string, Args, Tool<Args>, null];
|
|
200
|
+
declare function defineTool(toolDescription: string, tool: Tool<null>): [string, null, Tool<null>, null];
|
|
201
|
+
declare function defineTool<Args extends ToolArgs, RetValue extends StructuredToolReturn>(toolDescription: string, args: Args, tool: Tool<Args>, returnSchema: RetValue): [string, Args, Tool<Args>, RetValue];
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Hook signatures for all available hooks
|
|
205
|
+
*/
|
|
206
|
+
interface HookSignatures {
|
|
207
|
+
/**
|
|
208
|
+
* Called before messages are filtered and sent to the LLM
|
|
209
|
+
* Receives SQL row data with all columns before transformation
|
|
210
|
+
* Return value is transformed into chat completion format
|
|
211
|
+
*/
|
|
212
|
+
filter_messages: (state: FlowState, rows: Message[]) => Promise<Message[]>;
|
|
213
|
+
/**
|
|
214
|
+
* Called after message history is loaded and before sending to LLM
|
|
215
|
+
* Receives messages in chat completion format (already transformed)
|
|
216
|
+
*/
|
|
217
|
+
prefilter_llm_history: (state: FlowState, messages: Array<{
|
|
218
|
+
role: string;
|
|
219
|
+
content: string | null;
|
|
220
|
+
tool_calls?: any;
|
|
221
|
+
tool_call_id?: string;
|
|
222
|
+
name?: string;
|
|
223
|
+
}>) => Promise<Array<{
|
|
224
|
+
role: string;
|
|
225
|
+
content: string | null;
|
|
226
|
+
tool_calls?: any;
|
|
227
|
+
tool_call_id?: string;
|
|
228
|
+
name?: string;
|
|
229
|
+
}>>;
|
|
230
|
+
/**
|
|
231
|
+
* Called before a message is created in the database
|
|
232
|
+
*/
|
|
233
|
+
before_create_message: (state: FlowState, message: Record<string, any>) => Promise<Record<string, any>>;
|
|
234
|
+
/**
|
|
235
|
+
* Called after a message is created in the database
|
|
236
|
+
*/
|
|
237
|
+
after_create_message: (state: FlowState, message: Record<string, any>) => Promise<void>;
|
|
238
|
+
/**
|
|
239
|
+
* Called before a message is updated in the database
|
|
240
|
+
*/
|
|
241
|
+
before_update_message: (state: FlowState, messageId: string, updates: Record<string, any>) => Promise<Record<string, any>>;
|
|
242
|
+
/**
|
|
243
|
+
* Called after a message is updated in the database
|
|
244
|
+
*/
|
|
245
|
+
after_update_message: (state: FlowState, message: Message) => Promise<void>;
|
|
246
|
+
/**
|
|
247
|
+
* Called before a tool result is stored in the database
|
|
248
|
+
*/
|
|
249
|
+
before_store_tool_result: (state: FlowState, toolCall: Record<string, any>, toolResult: Record<string, any>) => Promise<Record<string, any>>;
|
|
250
|
+
/**
|
|
251
|
+
* Called after a successful tool call
|
|
252
|
+
*/
|
|
253
|
+
after_tool_call_success: (state: FlowState, toolCall: ToolCall, toolResult: ToolResult) => Promise<ToolResult | null>;
|
|
254
|
+
/**
|
|
255
|
+
* Called after a failed tool call
|
|
256
|
+
*/
|
|
257
|
+
after_tool_call_failure: (state: FlowState, toolCall: ToolCall, toolResult: ToolResult) => Promise<ToolResult | null>;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Define a hook with strict typing based on hook name
|
|
261
|
+
*
|
|
262
|
+
* @example
|
|
263
|
+
* ```typescript
|
|
264
|
+
* export default defineHook('filter_messages', async (state, rows) => {
|
|
265
|
+
* // Only include messages from last 10 turns
|
|
266
|
+
* return rows.slice(-10);
|
|
267
|
+
* });
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
declare function defineHook<K extends keyof HookSignatures>(hookName: K, implementation: HookSignatures[K]): HookSignatures[K];
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Agent configuration from D1 agents table
|
|
274
|
+
*/
|
|
275
|
+
interface Agent {
|
|
276
|
+
id: string;
|
|
277
|
+
title: string;
|
|
278
|
+
type: "dual_ai" | "ai_human";
|
|
279
|
+
created_at: number;
|
|
280
|
+
max_session_turns: number | null;
|
|
281
|
+
side_a_label: string | null;
|
|
282
|
+
side_a_agent_prompt: string | null;
|
|
283
|
+
side_a_stop_on_response: boolean;
|
|
284
|
+
side_a_stop_tool: string | null;
|
|
285
|
+
side_a_stop_tool_response_property: string | null;
|
|
286
|
+
side_a_max_turns: number | null;
|
|
287
|
+
side_a_end_conversation_tool: string | null;
|
|
288
|
+
side_b_label: string | null;
|
|
289
|
+
side_b_agent_prompt: string | null;
|
|
290
|
+
side_b_stop_on_response: boolean;
|
|
291
|
+
side_b_stop_tool: string | null;
|
|
292
|
+
side_b_stop_tool_response_property: string | null;
|
|
293
|
+
side_b_max_turns: number | null;
|
|
294
|
+
side_b_end_conversation_tool: string | null;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Message in OpenAI chat completion format
|
|
298
|
+
*/
|
|
299
|
+
interface Message {
|
|
300
|
+
id: string;
|
|
301
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
302
|
+
content: string | null;
|
|
303
|
+
name?: string | null;
|
|
304
|
+
tool_calls?: string | null;
|
|
305
|
+
tool_call_id?: string | null;
|
|
306
|
+
log_id?: string | null;
|
|
307
|
+
created_at: number;
|
|
308
|
+
request_sent_at?: number | null;
|
|
309
|
+
response_completed_at?: number | null;
|
|
310
|
+
status?: "pending" | "completed" | "failed";
|
|
311
|
+
silent?: boolean;
|
|
312
|
+
tool_status?: "success" | "error" | null;
|
|
313
|
+
reasoning_content?: string | null;
|
|
314
|
+
reasoning_details?: string | null;
|
|
315
|
+
parent_id?: string | null;
|
|
316
|
+
depth?: number;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Tool call from OpenAI format
|
|
320
|
+
*/
|
|
321
|
+
interface ToolCall {
|
|
322
|
+
id: string;
|
|
323
|
+
type: "function";
|
|
324
|
+
function: {
|
|
325
|
+
name: string;
|
|
326
|
+
arguments: string;
|
|
327
|
+
};
|
|
328
|
+
forceAllow?: boolean;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Thread metadata from DurableAgentBuilder
|
|
332
|
+
* Note: agent_id is now the agent name (not UUID) since agents are in TypeScript
|
|
333
|
+
*/
|
|
334
|
+
interface ThreadMetadata {
|
|
335
|
+
id: string;
|
|
336
|
+
agent_id: string;
|
|
337
|
+
user_id: string | null;
|
|
338
|
+
created_at: number;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Hook registry type - transforms HookSignatures into lazy-loaded optional hooks
|
|
342
|
+
*/
|
|
343
|
+
type HookRegistry = {
|
|
344
|
+
[K in keyof HookSignatures]?: () => Promise<HookSignatures[K]>;
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* Thread instance (forward reference to avoid circular dependency)
|
|
348
|
+
*/
|
|
349
|
+
interface ThreadInstance {
|
|
350
|
+
ctx: DurableObjectState;
|
|
351
|
+
env: ThreadEnv;
|
|
352
|
+
getMessages(limit?: number, offset?: number, order?: "asc" | "desc", includeSilent?: boolean, maxDepth?: number): Promise<{
|
|
353
|
+
messages: Message[];
|
|
354
|
+
total: number;
|
|
355
|
+
hasMore: boolean;
|
|
356
|
+
}>;
|
|
357
|
+
getLogs(limit?: number, offset?: number, order?: "asc" | "desc"): Promise<LogData[]>;
|
|
358
|
+
getThreadMeta(threadId: string): Promise<ThreadMetadata | null>;
|
|
359
|
+
shouldStop(): Promise<boolean>;
|
|
360
|
+
tools(): Record<string, () => Promise<ReturnType<typeof defineTool>>>;
|
|
361
|
+
hooks(): HookRegistry;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Tool call for internal flow management
|
|
365
|
+
*/
|
|
366
|
+
type FlowToolCall = {
|
|
367
|
+
tool: string;
|
|
368
|
+
args: Record<string, unknown>;
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Prompt call for internal flow management
|
|
372
|
+
*/
|
|
373
|
+
type FlowPromptCall = {
|
|
374
|
+
prompt: string;
|
|
375
|
+
args: Record<string, unknown>;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Flow call (tool or prompt)
|
|
379
|
+
*/
|
|
380
|
+
type FlowCall = FlowToolCall | FlowPromptCall;
|
|
381
|
+
/**
|
|
382
|
+
* Flow call with retry tracking
|
|
383
|
+
*/
|
|
384
|
+
type FlowCallWithRetries = FlowCall & {
|
|
385
|
+
retries: number;
|
|
386
|
+
reasons: string[];
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Tool configuration for a prompt - defines options for when a tool is used
|
|
390
|
+
*/
|
|
391
|
+
interface ToolConfig$1 {
|
|
392
|
+
name: string;
|
|
393
|
+
initUserMessageProperty?: string;
|
|
394
|
+
includeTextResponse?: boolean;
|
|
395
|
+
includeToolCalls?: boolean;
|
|
396
|
+
includeErrors?: boolean;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Prompt configuration - now loaded from TypeScript virtual modules
|
|
400
|
+
*/
|
|
401
|
+
interface PromptData {
|
|
402
|
+
id: string;
|
|
403
|
+
name: string;
|
|
404
|
+
prompt: string | any[];
|
|
405
|
+
system_prompt?: string;
|
|
406
|
+
model: string;
|
|
407
|
+
model_id?: string;
|
|
408
|
+
tool_description: string;
|
|
409
|
+
required_schema: string;
|
|
410
|
+
include_chat: boolean;
|
|
411
|
+
include_past_tools: boolean;
|
|
412
|
+
before_tool: string | null;
|
|
413
|
+
after_tool: string | null;
|
|
414
|
+
prompts: string;
|
|
415
|
+
created_at: number;
|
|
416
|
+
/** @deprecated All prompts are now automatically exposed as tools */
|
|
417
|
+
expose_as_tool?: boolean;
|
|
418
|
+
parallel_tool_calls: boolean;
|
|
419
|
+
tool_choice: "auto" | "none" | "required" | "function";
|
|
420
|
+
reasoning_effort: "low" | "medium" | "high" | null;
|
|
421
|
+
reasoning_max_tokens: number | null;
|
|
422
|
+
reasoning_exclude: boolean;
|
|
423
|
+
include_reasoning: boolean;
|
|
424
|
+
_tools?: (string | ToolConfig$1)[];
|
|
425
|
+
_handoffAgents?: string[];
|
|
426
|
+
_requiredSchema?: any;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Central state object that flows through execution
|
|
430
|
+
*/
|
|
431
|
+
interface FlowState {
|
|
432
|
+
threadId: string;
|
|
433
|
+
flowId: string;
|
|
434
|
+
thread: {
|
|
435
|
+
instance: ThreadInstance;
|
|
436
|
+
metadata: ThreadMetadata;
|
|
437
|
+
};
|
|
438
|
+
agentConfig: Agent;
|
|
439
|
+
currentSide: "a" | "b";
|
|
440
|
+
prompts: {
|
|
441
|
+
sideA: PromptData;
|
|
442
|
+
sideB: PromptData | null;
|
|
443
|
+
};
|
|
444
|
+
prompt: PromptData;
|
|
445
|
+
turnCount: number;
|
|
446
|
+
sideATurnCount: number;
|
|
447
|
+
sideBTurnCount: number;
|
|
448
|
+
stopped: boolean;
|
|
449
|
+
stoppedBy?: "a" | "b";
|
|
450
|
+
forcedNextSide?: "side_a" | "side_b";
|
|
451
|
+
pendingForceTurn?: "side_a" | "side_b";
|
|
452
|
+
abortController?: AbortController;
|
|
453
|
+
messageHistory: Message[];
|
|
454
|
+
/**
|
|
455
|
+
* Appends these messages
|
|
456
|
+
*/
|
|
457
|
+
extraMessages: Message[];
|
|
458
|
+
sequence: {
|
|
459
|
+
queue: ToolCall[];
|
|
460
|
+
isHandling: boolean;
|
|
461
|
+
};
|
|
462
|
+
active: FlowCallWithRetries;
|
|
463
|
+
queue: FlowCall[];
|
|
464
|
+
pendingHandoff?: {
|
|
465
|
+
agentId: string;
|
|
466
|
+
};
|
|
467
|
+
stream: StreamManager;
|
|
468
|
+
context: Record<string, unknown>;
|
|
469
|
+
retryCount: number;
|
|
470
|
+
retryReason?: string;
|
|
471
|
+
storage: DurableObjectStorage;
|
|
472
|
+
env: ThreadEnv;
|
|
473
|
+
emitLog?: (log: unknown) => void;
|
|
474
|
+
emitMessage?: (message: unknown) => void;
|
|
475
|
+
emitMessageChunk?: (messageId: string, chunk: string, depth?: number) => void;
|
|
476
|
+
rootState: FlowState;
|
|
477
|
+
rootMessageId?: string | null;
|
|
478
|
+
parentLogId?: string | null;
|
|
479
|
+
currentLogId?: string | null;
|
|
480
|
+
parentMessageId?: string;
|
|
481
|
+
depth: number;
|
|
482
|
+
pendingMessageId?: string;
|
|
483
|
+
allowedTools?: ToolDefinition[];
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Request context for LLM calls
|
|
487
|
+
*/
|
|
488
|
+
interface RequestContext {
|
|
489
|
+
messages: Array<{
|
|
490
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
491
|
+
content?: string;
|
|
492
|
+
tool_calls?: ToolCall[];
|
|
493
|
+
tool_call_id?: string;
|
|
494
|
+
name?: string;
|
|
495
|
+
}>;
|
|
496
|
+
model: string;
|
|
497
|
+
tools?: ToolDefinition[];
|
|
498
|
+
stream?: boolean;
|
|
499
|
+
promptName?: string;
|
|
500
|
+
systemPrompt?: string;
|
|
501
|
+
parentLogId?: string | null;
|
|
502
|
+
parallel_tool_calls?: boolean;
|
|
503
|
+
tool_choice?: "auto" | "none" | "required" | {
|
|
504
|
+
type: "function";
|
|
505
|
+
function: {
|
|
506
|
+
name: string;
|
|
507
|
+
};
|
|
508
|
+
};
|
|
509
|
+
reasoning?: {
|
|
510
|
+
effort?: "low" | "medium" | "high";
|
|
511
|
+
max_tokens?: number;
|
|
512
|
+
exclude?: boolean;
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Tool definition for LLM requests
|
|
517
|
+
*/
|
|
518
|
+
interface ToolDefinition {
|
|
519
|
+
type: "function";
|
|
520
|
+
function: {
|
|
521
|
+
name: string;
|
|
522
|
+
description: string;
|
|
523
|
+
parameters?: Record<string, any>;
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* LLM response
|
|
528
|
+
*/
|
|
529
|
+
interface LLMResponse {
|
|
530
|
+
id: string;
|
|
531
|
+
model: string;
|
|
532
|
+
content: string | null;
|
|
533
|
+
reasoning_content?: string | null;
|
|
534
|
+
reasoning_details?: any[];
|
|
535
|
+
tool_calls?: ToolCall[];
|
|
536
|
+
finish_reason: string;
|
|
537
|
+
usage: {
|
|
538
|
+
prompt_tokens: number;
|
|
539
|
+
completion_tokens: number;
|
|
540
|
+
total_tokens: number;
|
|
541
|
+
prompt_tokens_details?: {
|
|
542
|
+
cached_tokens?: number;
|
|
543
|
+
};
|
|
544
|
+
completion_tokens_details?: {
|
|
545
|
+
reasoning_tokens?: number;
|
|
546
|
+
};
|
|
547
|
+
cost?: number;
|
|
548
|
+
provider?: string;
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* Tool result
|
|
553
|
+
*/
|
|
554
|
+
interface ToolResult {
|
|
555
|
+
status: "success" | "error";
|
|
556
|
+
/**
|
|
557
|
+
* Flattened text representation of the tool output.
|
|
558
|
+
*
|
|
559
|
+
* For tools that return structured MCP-style content (an array of
|
|
560
|
+
* content parts), this will be derived by concatenating all text
|
|
561
|
+
* parts. For legacy tools that returned a plain string `result`,
|
|
562
|
+
* that value is used directly.
|
|
563
|
+
*/
|
|
564
|
+
result?: string;
|
|
565
|
+
error?: string;
|
|
566
|
+
stack?: string;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Flow execution result
|
|
570
|
+
*/
|
|
571
|
+
interface FlowResult {
|
|
572
|
+
messages: Message[];
|
|
573
|
+
stopped: boolean;
|
|
574
|
+
stoppedBy?: "a" | "b";
|
|
575
|
+
turnCount: number;
|
|
576
|
+
stream: ReadableStream<Uint8Array>;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Telemetry event types
|
|
580
|
+
*/
|
|
581
|
+
type TelemetryEvent = {
|
|
582
|
+
type: "turn_started";
|
|
583
|
+
turn: number;
|
|
584
|
+
side: "a" | "b";
|
|
585
|
+
timestamp: number;
|
|
586
|
+
} | {
|
|
587
|
+
type: "turn_completed";
|
|
588
|
+
turn: number;
|
|
589
|
+
stopped: boolean;
|
|
590
|
+
timestamp: number;
|
|
591
|
+
} | {
|
|
592
|
+
type: "llm_request";
|
|
593
|
+
model: string;
|
|
594
|
+
attempt: number;
|
|
595
|
+
timestamp: number;
|
|
596
|
+
} | {
|
|
597
|
+
type: "llm_response";
|
|
598
|
+
tokens: number;
|
|
599
|
+
latency: number;
|
|
600
|
+
timestamp: number;
|
|
601
|
+
} | {
|
|
602
|
+
type: "validation_failed";
|
|
603
|
+
error: string;
|
|
604
|
+
timestamp: number;
|
|
605
|
+
} | {
|
|
606
|
+
type: "fallback_triggered";
|
|
607
|
+
from: string;
|
|
608
|
+
to: string;
|
|
609
|
+
timestamp: number;
|
|
610
|
+
} | {
|
|
611
|
+
type: "tool_started";
|
|
612
|
+
tool: string;
|
|
613
|
+
timestamp: number;
|
|
614
|
+
} | {
|
|
615
|
+
type: "tool_completed";
|
|
616
|
+
tool: string;
|
|
617
|
+
status: string;
|
|
618
|
+
timestamp: number;
|
|
619
|
+
} | {
|
|
620
|
+
type: "stopped";
|
|
621
|
+
reason: string;
|
|
622
|
+
side: "a" | "b";
|
|
623
|
+
timestamp: number;
|
|
624
|
+
} | {
|
|
625
|
+
type: "stopped_by_user";
|
|
626
|
+
timestamp: number;
|
|
627
|
+
};
|
|
628
|
+
/**
|
|
629
|
+
* Log data for telemetry table
|
|
630
|
+
*/
|
|
631
|
+
interface LogData {
|
|
632
|
+
id: string;
|
|
633
|
+
message_id: string;
|
|
634
|
+
provider: string;
|
|
635
|
+
model: string;
|
|
636
|
+
model_name?: string;
|
|
637
|
+
endpoint?: string;
|
|
638
|
+
request_body?: string;
|
|
639
|
+
request_headers?: string;
|
|
640
|
+
response_body?: string;
|
|
641
|
+
response_headers?: string;
|
|
642
|
+
status_code?: number;
|
|
643
|
+
reasoning_content?: string | null;
|
|
644
|
+
input_tokens?: number;
|
|
645
|
+
cached_tokens?: number;
|
|
646
|
+
output_tokens?: number;
|
|
647
|
+
reasoning_tokens?: number;
|
|
648
|
+
total_tokens?: number;
|
|
649
|
+
latency_ms?: number;
|
|
650
|
+
time_to_first_token_ms?: number;
|
|
651
|
+
finish_reason?: string;
|
|
652
|
+
error?: string;
|
|
653
|
+
error_type?: string;
|
|
654
|
+
cost_input?: number;
|
|
655
|
+
cost_output?: number;
|
|
656
|
+
cost_total?: number;
|
|
657
|
+
message_history_length?: number;
|
|
658
|
+
tools_available?: number;
|
|
659
|
+
prompt_name?: string;
|
|
660
|
+
tools_called?: string;
|
|
661
|
+
parent_log_id?: string | null;
|
|
662
|
+
tools_schema?: string | null;
|
|
663
|
+
message_history?: string | null;
|
|
664
|
+
system_prompt?: string | null;
|
|
665
|
+
is_complete?: boolean;
|
|
666
|
+
errors?: string | null;
|
|
667
|
+
retry_of_log_id?: string | null;
|
|
668
|
+
created_at: number;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* Minimum required environment bindings for thread endpoints.
|
|
673
|
+
* User's Env interface should extend this.
|
|
674
|
+
*/
|
|
675
|
+
interface ThreadEnv {
|
|
676
|
+
AGENT_BUILDER_THREAD: DurableObjectNamespace;
|
|
677
|
+
AGENT_BUILDER: DurableObjectNamespace;
|
|
678
|
+
}
|
|
679
|
+
interface ControllerContext<Env = any> {
|
|
680
|
+
req: Request;
|
|
681
|
+
params: Record<string, string>;
|
|
682
|
+
env: Env;
|
|
683
|
+
url: URL;
|
|
684
|
+
}
|
|
685
|
+
type Controller<Env = any> = (context: ControllerContext<Env>) => string | Promise<string> | Response | Promise<Response> | ReadableStream | Promise<ReadableStream> | null | Promise<null> | void | Promise<void> | Promise<object> | object;
|
|
686
|
+
interface ThreadEndpointContext {
|
|
687
|
+
req: Request;
|
|
688
|
+
thread: {
|
|
689
|
+
instance: ThreadInstance;
|
|
690
|
+
metadata: ThreadMetadata;
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
declare function defineController<Env = any>(controller: Controller<Env>): Controller<Env>;
|
|
694
|
+
/**
|
|
695
|
+
* Define a thread-specific endpoint that has access to the thread's DurableObject instance and metadata.
|
|
696
|
+
* This wraps defineController and automatically looks up the thread by ID from the URL params.
|
|
697
|
+
*
|
|
698
|
+
* @param handler - Function that receives the request and thread context
|
|
699
|
+
* @returns A Controller that can be used with the router
|
|
700
|
+
*
|
|
701
|
+
* @example
|
|
702
|
+
* // agentbuilder/api/status.ts
|
|
703
|
+
* export default defineThreadEndpoint(async (req, { thread }) => {
|
|
704
|
+
* const messages = await thread.instance.getMessages();
|
|
705
|
+
* return Response.json({ status: "ok", messageCount: messages.length });
|
|
706
|
+
* });
|
|
707
|
+
*/
|
|
708
|
+
declare function defineThreadEndpoint<Env extends ThreadEnv = ThreadEnv>(handler: (req: Request, context: ThreadEndpointContext["thread"]) => Response | Promise<Response>): Controller<Env>;
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* Authentication middleware for protecting API routes
|
|
712
|
+
*
|
|
713
|
+
* Supports multiple authentication types:
|
|
714
|
+
* - Super admin token (signed with ENCRYPTION_KEY)
|
|
715
|
+
* - User session token (validated against DurableAgentBuilder)
|
|
716
|
+
* - API key (validated against DurableAgentBuilder)
|
|
717
|
+
*/
|
|
718
|
+
interface AuthUser {
|
|
719
|
+
id: string;
|
|
720
|
+
username: string;
|
|
721
|
+
role: string;
|
|
722
|
+
}
|
|
723
|
+
interface AuthContext {
|
|
724
|
+
user: AuthUser;
|
|
725
|
+
authType: 'super_admin' | 'session' | 'api_key';
|
|
726
|
+
}
|
|
727
|
+
/**
|
|
728
|
+
* Authenticate a request using various token types
|
|
729
|
+
*/
|
|
730
|
+
declare function authenticate(request: Request, env: any): Promise<AuthContext | null>;
|
|
731
|
+
/**
|
|
732
|
+
* Middleware to require authentication
|
|
733
|
+
* Returns 401 if not authenticated
|
|
734
|
+
*/
|
|
735
|
+
declare function requireAuth(request: Request, env: any): Promise<AuthContext | Response>;
|
|
736
|
+
/**
|
|
737
|
+
* Middleware to require admin role
|
|
738
|
+
* Returns 401 if not authenticated, 403 if not admin
|
|
739
|
+
*/
|
|
740
|
+
declare function requireAdmin(request: Request, env: any): Promise<AuthContext | Response>;
|
|
741
|
+
|
|
742
|
+
declare class DurableThread<Env extends ThreadEnv = ThreadEnv> extends DurableObject<Env> {
|
|
743
|
+
private migratedToVersion;
|
|
744
|
+
private logSockets;
|
|
745
|
+
private messageSockets;
|
|
746
|
+
private alarmQueue;
|
|
747
|
+
private currentAbortController;
|
|
748
|
+
private isExecuting;
|
|
749
|
+
constructor(ctx: DurableObjectState, env: Env);
|
|
750
|
+
/**
|
|
751
|
+
* Returns the tools registry for this thread.
|
|
752
|
+
* This method is implemented when you import DurableThread from 'virtual:@standardagents/builder'.
|
|
753
|
+
*
|
|
754
|
+
* @throws Error if not implemented in a subclass
|
|
755
|
+
* @returns Record of tool name to tool loader function
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* ```typescript
|
|
759
|
+
* import { DurableThread } from 'virtual:@standardagents/builder'
|
|
760
|
+
*
|
|
761
|
+
* export class Thread extends DurableThread {}
|
|
762
|
+
* ```
|
|
763
|
+
*/
|
|
764
|
+
tools(): Record<string, () => Promise<any>>;
|
|
765
|
+
/**
|
|
766
|
+
* Returns the hooks registry for this thread.
|
|
767
|
+
* This method is implemented when you import DurableThread from 'virtual:@standardagents/builder'.
|
|
768
|
+
*
|
|
769
|
+
* @throws Error if not implemented in a subclass
|
|
770
|
+
* @returns Record of hook name to hook loader function
|
|
771
|
+
*
|
|
772
|
+
* @example
|
|
773
|
+
* ```typescript
|
|
774
|
+
* import { DurableThread } from 'virtual:@standardagents/builder'
|
|
775
|
+
*
|
|
776
|
+
* export class Thread extends DurableThread {}
|
|
777
|
+
* ```
|
|
778
|
+
*/
|
|
779
|
+
hooks(): Record<string, () => Promise<any>>;
|
|
780
|
+
/**
|
|
781
|
+
* Returns the models registry for lazy-loading model definitions.
|
|
782
|
+
* This method is implemented when you import DurableThread from 'virtual:@standardagents/builder'.
|
|
783
|
+
*
|
|
784
|
+
* @throws Error if not implemented in a subclass
|
|
785
|
+
* @returns Record of model name to model loader function
|
|
786
|
+
*/
|
|
787
|
+
models(): Record<string, () => Promise<any>>;
|
|
788
|
+
/**
|
|
789
|
+
* Returns the prompts registry for lazy-loading prompt definitions.
|
|
790
|
+
* This method is implemented when you import DurableThread from 'virtual:@standardagents/builder'.
|
|
791
|
+
*
|
|
792
|
+
* @throws Error if not implemented in a subclass
|
|
793
|
+
* @returns Record of prompt name to prompt loader function
|
|
794
|
+
*/
|
|
795
|
+
prompts(): Record<string, () => Promise<any>>;
|
|
796
|
+
/**
|
|
797
|
+
* Returns the agents registry for lazy-loading agent definitions.
|
|
798
|
+
* This method is implemented when you import DurableThread from 'virtual:@standardagents/builder'.
|
|
799
|
+
*
|
|
800
|
+
* @throws Error if not implemented in a subclass
|
|
801
|
+
* @returns Record of agent name to agent loader function
|
|
802
|
+
*/
|
|
803
|
+
agents(): Record<string, () => Promise<any>>;
|
|
804
|
+
/**
|
|
805
|
+
* Load a model definition by name.
|
|
806
|
+
*/
|
|
807
|
+
loadModel(name: string): Promise<any>;
|
|
808
|
+
/**
|
|
809
|
+
* List available model names.
|
|
810
|
+
*/
|
|
811
|
+
getModelNames(): string[];
|
|
812
|
+
/**
|
|
813
|
+
* Load a prompt definition by name.
|
|
814
|
+
*/
|
|
815
|
+
loadPrompt(name: string): Promise<any>;
|
|
816
|
+
/**
|
|
817
|
+
* List available prompt names.
|
|
818
|
+
*/
|
|
819
|
+
getPromptNames(): string[];
|
|
820
|
+
/**
|
|
821
|
+
* Load an agent definition by name.
|
|
822
|
+
*/
|
|
823
|
+
loadAgent(name: string): Promise<any>;
|
|
824
|
+
/**
|
|
825
|
+
* List available agent names.
|
|
826
|
+
*/
|
|
827
|
+
getAgentNames(): string[];
|
|
828
|
+
/**
|
|
829
|
+
* Ensures the database schema is up to date.
|
|
830
|
+
* This method is called on the first request to the Durable Object.
|
|
831
|
+
* It checks the schema version and runs any pending migrations.
|
|
832
|
+
*
|
|
833
|
+
* Performance:
|
|
834
|
+
* - Already migrated to latest: ~0.1ms (single SELECT + integer comparison)
|
|
835
|
+
* - Needs migration: Runs once per Durable Object lifetime per schema version
|
|
836
|
+
* - Detects new migrations after code deployment
|
|
837
|
+
*/
|
|
838
|
+
private ensureMigrated;
|
|
839
|
+
/**
|
|
840
|
+
* Gets the current schema version from the database.
|
|
841
|
+
* Returns 0 if the metadata table doesn't exist (brand new database).
|
|
842
|
+
*/
|
|
843
|
+
private getCurrentVersion;
|
|
844
|
+
/**
|
|
845
|
+
* Runs all pending migrations sequentially.
|
|
846
|
+
* Each migration is run in order, starting from the current version + 1.
|
|
847
|
+
*/
|
|
848
|
+
private runMigrations;
|
|
849
|
+
/**
|
|
850
|
+
* Legacy fetch handler for WebSocket upgrades only
|
|
851
|
+
*/
|
|
852
|
+
fetch(request: Request): Promise<Response>;
|
|
853
|
+
/**
|
|
854
|
+
* Execute thread with initial messages (RPC method)
|
|
855
|
+
* Enqueues the execution to be processed by the alarm handler
|
|
856
|
+
*/
|
|
857
|
+
execute(threadId: string, agentId: string, initial_messages?: any[], data?: any): Promise<Response>;
|
|
858
|
+
/**
|
|
859
|
+
* Send a new message to the thread (RPC method)
|
|
860
|
+
* Enqueues the message processing to be handled by the alarm handler
|
|
861
|
+
*/
|
|
862
|
+
sendMessage(threadId: string, content: string, role?: string): Promise<Response>;
|
|
863
|
+
/**
|
|
864
|
+
* Check if execution should be stopped (called by FlowEngine)
|
|
865
|
+
* Reads from SQLite for persistence across hibernation
|
|
866
|
+
*/
|
|
867
|
+
shouldStop(): Promise<boolean>;
|
|
868
|
+
/**
|
|
869
|
+
* Stop the currently executing thread (RPC method)
|
|
870
|
+
* Simple "off" switch - stops turns, only cleared by user messages
|
|
871
|
+
*/
|
|
872
|
+
stop(): Promise<Response>;
|
|
873
|
+
/**
|
|
874
|
+
* Get message history (RPC method)
|
|
875
|
+
*
|
|
876
|
+
* By default, returns the newest messages (when truncating), but in chronological
|
|
877
|
+
* order (oldest first in the array). This is ideal for chat UIs where messages
|
|
878
|
+
* should be appended and scrolled to the bottom.
|
|
879
|
+
*
|
|
880
|
+
* The offset parameter allows "scrolling up" to view older messages.
|
|
881
|
+
*
|
|
882
|
+
* Example:
|
|
883
|
+
* - getMessages(10, 0) -> newest 10 messages, oldest first in array
|
|
884
|
+
* - getMessages(10, 10) -> next 10 older messages, oldest first in array
|
|
885
|
+
*
|
|
886
|
+
* @param limit Number of messages to return (default: 100)
|
|
887
|
+
* @param offset Number of newest messages to skip (default: 0)
|
|
888
|
+
* @param order Internal query order - "DESC" (default) fetches newest first then reverses
|
|
889
|
+
* @param includeSilent Include silent messages (UI-only messages)
|
|
890
|
+
* @param maxDepth Maximum depth to include (default: 0 for top-level only)
|
|
891
|
+
*/
|
|
892
|
+
getMessages(limit?: number, offset?: number, order?: "ASC" | "DESC", includeSilent?: boolean, maxDepth?: number): Promise<{
|
|
893
|
+
messages: {
|
|
894
|
+
id: string;
|
|
895
|
+
role: string;
|
|
896
|
+
content: string | null;
|
|
897
|
+
name: string | null;
|
|
898
|
+
tool_calls: string | null;
|
|
899
|
+
tool_call_id: string | null;
|
|
900
|
+
tool_status: "success" | "error" | null;
|
|
901
|
+
log_id: string | null;
|
|
902
|
+
created_at: number;
|
|
903
|
+
silent: boolean;
|
|
904
|
+
parent_id: string | null;
|
|
905
|
+
depth: number;
|
|
906
|
+
status: "pending" | "completed" | "failed" | null;
|
|
907
|
+
reasoning_content: string | null;
|
|
908
|
+
reasoning_details: string | null;
|
|
909
|
+
}[];
|
|
910
|
+
total: number;
|
|
911
|
+
hasMore: boolean;
|
|
912
|
+
}>;
|
|
913
|
+
/**
|
|
914
|
+
* Delete a message (RPC method)
|
|
915
|
+
*/
|
|
916
|
+
deleteMessage(messageId: string): Promise<{
|
|
917
|
+
success: boolean;
|
|
918
|
+
error?: undefined;
|
|
919
|
+
} | {
|
|
920
|
+
success: boolean;
|
|
921
|
+
error: any;
|
|
922
|
+
}>;
|
|
923
|
+
/**
|
|
924
|
+
* Seed messages directly into the database (RPC method - for testing)
|
|
925
|
+
* This bypasses the normal message processing flow
|
|
926
|
+
*/
|
|
927
|
+
seedMessages(args: {
|
|
928
|
+
messages: Array<{
|
|
929
|
+
id: string;
|
|
930
|
+
role: string;
|
|
931
|
+
content: string;
|
|
932
|
+
created_at: number;
|
|
933
|
+
}>;
|
|
934
|
+
}): Promise<{
|
|
935
|
+
success: boolean;
|
|
936
|
+
count: number;
|
|
937
|
+
error?: undefined;
|
|
938
|
+
} | {
|
|
939
|
+
success: boolean;
|
|
940
|
+
error: any;
|
|
941
|
+
count?: undefined;
|
|
942
|
+
}>;
|
|
943
|
+
/**
|
|
944
|
+
* Get logs (RPC method)
|
|
945
|
+
*/
|
|
946
|
+
getLogs(limit?: number, offset?: number, order?: "ASC" | "DESC"): Promise<{
|
|
947
|
+
logs: {
|
|
948
|
+
id: string;
|
|
949
|
+
message_id: string;
|
|
950
|
+
provider: string;
|
|
951
|
+
model: string;
|
|
952
|
+
model_name: string | null;
|
|
953
|
+
prompt_name: string | null;
|
|
954
|
+
tools_called: string | null;
|
|
955
|
+
parent_log_id: string | null;
|
|
956
|
+
retry_of_log_id: string | null;
|
|
957
|
+
error: string | null;
|
|
958
|
+
cost_total: number | null;
|
|
959
|
+
is_complete: boolean;
|
|
960
|
+
created_at: number;
|
|
961
|
+
request_body: string | null;
|
|
962
|
+
}[];
|
|
963
|
+
total: number;
|
|
964
|
+
hasMore: boolean;
|
|
965
|
+
}>;
|
|
966
|
+
/**
|
|
967
|
+
* Get detailed information for a single log (RPC method)
|
|
968
|
+
* This includes all fields including large ones like request/response bodies
|
|
969
|
+
*/
|
|
970
|
+
getLogDetails(logId: string): Promise<{
|
|
971
|
+
id: string;
|
|
972
|
+
message_id: string;
|
|
973
|
+
provider: string;
|
|
974
|
+
model: string;
|
|
975
|
+
model_name: string | null;
|
|
976
|
+
endpoint: string | null;
|
|
977
|
+
request_body: string | null;
|
|
978
|
+
request_headers: string | null;
|
|
979
|
+
response_body: string | null;
|
|
980
|
+
response_headers: string | null;
|
|
981
|
+
status_code: number | null;
|
|
982
|
+
reasoning_content: string | null;
|
|
983
|
+
input_tokens: number | null;
|
|
984
|
+
cached_tokens: number | null;
|
|
985
|
+
output_tokens: number | null;
|
|
986
|
+
reasoning_tokens: number | null;
|
|
987
|
+
total_tokens: number | null;
|
|
988
|
+
latency_ms: number | null;
|
|
989
|
+
time_to_first_token_ms: number | null;
|
|
990
|
+
finish_reason: string | null;
|
|
991
|
+
error: string | null;
|
|
992
|
+
error_type: string | null;
|
|
993
|
+
cost_input: number | null;
|
|
994
|
+
cost_output: number | null;
|
|
995
|
+
cost_total: number | null;
|
|
996
|
+
message_history_length: number | null;
|
|
997
|
+
tools_available: number | null;
|
|
998
|
+
prompt_name: string | null;
|
|
999
|
+
tools_called: string | null;
|
|
1000
|
+
parent_log_id: string | null;
|
|
1001
|
+
tools_schema: string | null;
|
|
1002
|
+
message_history: string | null;
|
|
1003
|
+
system_prompt: string | null;
|
|
1004
|
+
errors: string | null;
|
|
1005
|
+
retry_of_log_id: string | null;
|
|
1006
|
+
tool_results: string | null;
|
|
1007
|
+
is_complete: boolean;
|
|
1008
|
+
created_at: number;
|
|
1009
|
+
}>;
|
|
1010
|
+
/**
|
|
1011
|
+
* Get thread metadata (RPC method)
|
|
1012
|
+
*/
|
|
1013
|
+
getThreadMeta(threadId: string): Promise<Response | {
|
|
1014
|
+
thread: {
|
|
1015
|
+
id: any;
|
|
1016
|
+
agent_id: any;
|
|
1017
|
+
user_id: any;
|
|
1018
|
+
tags: any;
|
|
1019
|
+
created_at: any;
|
|
1020
|
+
};
|
|
1021
|
+
agent: {
|
|
1022
|
+
id: any;
|
|
1023
|
+
title: any;
|
|
1024
|
+
type: any;
|
|
1025
|
+
side_a_label: any;
|
|
1026
|
+
side_b_label: any;
|
|
1027
|
+
} | null;
|
|
1028
|
+
stats: {
|
|
1029
|
+
message_count: number;
|
|
1030
|
+
log_count: number;
|
|
1031
|
+
};
|
|
1032
|
+
}>;
|
|
1033
|
+
/**
|
|
1034
|
+
* Update thread metadata (RPC method)
|
|
1035
|
+
* Calls the DurableAgentBuilder to update the thread registry
|
|
1036
|
+
*/
|
|
1037
|
+
updateThreadMeta(threadId: string, params: {
|
|
1038
|
+
agent_name?: string;
|
|
1039
|
+
user_id?: string | null;
|
|
1040
|
+
tags?: string[] | null;
|
|
1041
|
+
}): Promise<{
|
|
1042
|
+
success: boolean;
|
|
1043
|
+
thread: {
|
|
1044
|
+
id: any;
|
|
1045
|
+
agent_id: any;
|
|
1046
|
+
user_id: any;
|
|
1047
|
+
tags: any;
|
|
1048
|
+
created_at: any;
|
|
1049
|
+
};
|
|
1050
|
+
error?: undefined;
|
|
1051
|
+
} | {
|
|
1052
|
+
success: boolean;
|
|
1053
|
+
error: any;
|
|
1054
|
+
thread?: undefined;
|
|
1055
|
+
}>;
|
|
1056
|
+
/**
|
|
1057
|
+
* Delete thread data completely (RPC method)
|
|
1058
|
+
* This will permanently delete the Durable Object instance
|
|
1059
|
+
*/
|
|
1060
|
+
deleteThread(): Promise<{
|
|
1061
|
+
success: boolean;
|
|
1062
|
+
message: string;
|
|
1063
|
+
}>;
|
|
1064
|
+
/**
|
|
1065
|
+
* Handle WebSocket upgrade for real-time log streaming
|
|
1066
|
+
* Uses Hibernation API to reduce costs during inactivity
|
|
1067
|
+
*/
|
|
1068
|
+
private handleLogsWebSocketUpgrade;
|
|
1069
|
+
/**
|
|
1070
|
+
* Handle WebSocket upgrade for real-time message streaming
|
|
1071
|
+
* Uses Hibernation API to reduce costs during inactivity
|
|
1072
|
+
*/
|
|
1073
|
+
private handleMessagesWebSocketUpgrade;
|
|
1074
|
+
/**
|
|
1075
|
+
* Broadcast a log record to all connected WebSocket clients
|
|
1076
|
+
*/
|
|
1077
|
+
private broadcastLog;
|
|
1078
|
+
/**
|
|
1079
|
+
* Broadcast a message record to all connected message WebSocket clients
|
|
1080
|
+
* Filters silent messages based on each socket's includeSilent preference
|
|
1081
|
+
*/
|
|
1082
|
+
private broadcastMessage;
|
|
1083
|
+
/**
|
|
1084
|
+
* Broadcast a content chunk for real-time streaming
|
|
1085
|
+
* Does NOT update database - only broadcasts to connected clients
|
|
1086
|
+
*/
|
|
1087
|
+
private broadcastMessageChunk;
|
|
1088
|
+
/**
|
|
1089
|
+
* WebSocket Hibernation API handler for incoming messages
|
|
1090
|
+
* Called when a message is received on a hibernated WebSocket
|
|
1091
|
+
*/
|
|
1092
|
+
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): Promise<void>;
|
|
1093
|
+
/**
|
|
1094
|
+
* WebSocket Hibernation API handler for connection close
|
|
1095
|
+
* Called when a WebSocket connection is closed
|
|
1096
|
+
*/
|
|
1097
|
+
webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): Promise<void>;
|
|
1098
|
+
/**
|
|
1099
|
+
* WebSocket Hibernation API handler for errors
|
|
1100
|
+
* Called when a WebSocket encounters an error
|
|
1101
|
+
*/
|
|
1102
|
+
webSocketError(ws: WebSocket, error: unknown): Promise<void>;
|
|
1103
|
+
/**
|
|
1104
|
+
* Alarm handler - called by Cloudflare when a scheduled alarm fires
|
|
1105
|
+
* Processes the next item in the alarm queue
|
|
1106
|
+
*
|
|
1107
|
+
* Important: This method must NEVER throw an exception, as that would break
|
|
1108
|
+
* the alarm chain. All errors are caught and logged.
|
|
1109
|
+
*/
|
|
1110
|
+
alarm(): Promise<void>;
|
|
1111
|
+
/**
|
|
1112
|
+
* Internal method: Execute a flow (called by alarm queue)
|
|
1113
|
+
* This is the actual execution logic, separate from the public execute() RPC method
|
|
1114
|
+
*/
|
|
1115
|
+
private executeFlow;
|
|
1116
|
+
/**
|
|
1117
|
+
* Internal method: Process a message (called by alarm queue)
|
|
1118
|
+
* This is the actual message processing logic, separate from the public sendMessage() RPC method
|
|
1119
|
+
*/
|
|
1120
|
+
private processMessage;
|
|
1121
|
+
/**
|
|
1122
|
+
* TEST METHOD: Queue a test operation
|
|
1123
|
+
* Used for testing alarm queue ordering and timing
|
|
1124
|
+
*/
|
|
1125
|
+
queueTestOperation(id: string, label: string, expectedOrder: number, delayMs: number): Promise<Response>;
|
|
1126
|
+
/**
|
|
1127
|
+
* TEST METHOD: Get queue state
|
|
1128
|
+
*/
|
|
1129
|
+
getQueueState(): Promise<Response>;
|
|
1130
|
+
/**
|
|
1131
|
+
* TEST METHOD: Get test execution logs
|
|
1132
|
+
*/
|
|
1133
|
+
getTestLogs(): Promise<Response>;
|
|
1134
|
+
/**
|
|
1135
|
+
* TEST METHOD: Clear test logs
|
|
1136
|
+
*/
|
|
1137
|
+
clearTestLogs(): Promise<Response>;
|
|
1138
|
+
/**
|
|
1139
|
+
* TEST METHOD: Insert a malformed message with orphaned tool calls
|
|
1140
|
+
* This allows testing the tool call filtering logic
|
|
1141
|
+
*/
|
|
1142
|
+
insertOrphanedToolCall(params: {
|
|
1143
|
+
content?: string;
|
|
1144
|
+
toolCallId: string;
|
|
1145
|
+
toolName: string;
|
|
1146
|
+
toolArgs: string;
|
|
1147
|
+
}): Promise<Response>;
|
|
1148
|
+
/**
|
|
1149
|
+
* TEST METHOD: Execute a test operation
|
|
1150
|
+
* Internal method called by alarm queue
|
|
1151
|
+
*/
|
|
1152
|
+
private testOperation;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/**
|
|
1156
|
+
* Environment type for DurableAgentBuilder.
|
|
1157
|
+
* Users extend this with their own bindings.
|
|
1158
|
+
*/
|
|
1159
|
+
interface AgentBuilderEnv {
|
|
1160
|
+
AGENT_BUILDER: DurableObjectNamespace<DurableAgentBuilder>;
|
|
1161
|
+
AGENT_BUILDER_THREAD: DurableObjectNamespace;
|
|
1162
|
+
GITHUB_TOKEN?: string;
|
|
1163
|
+
GITHUB_REPO?: string;
|
|
1164
|
+
GITHUB_BRANCH?: string;
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Thread metadata stored in the registry.
|
|
1168
|
+
*/
|
|
1169
|
+
interface ThreadRegistryEntry {
|
|
1170
|
+
id: string;
|
|
1171
|
+
agent_name: string;
|
|
1172
|
+
user_id: string | null;
|
|
1173
|
+
tags: string[] | null;
|
|
1174
|
+
created_at: number;
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Parameters for updating a thread.
|
|
1178
|
+
*/
|
|
1179
|
+
interface UpdateThreadParams {
|
|
1180
|
+
agent_name?: string;
|
|
1181
|
+
user_id?: string | null;
|
|
1182
|
+
tags?: string[] | null;
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* User record.
|
|
1186
|
+
*/
|
|
1187
|
+
interface User {
|
|
1188
|
+
id: string;
|
|
1189
|
+
username: string;
|
|
1190
|
+
password_hash: string;
|
|
1191
|
+
role: 'admin';
|
|
1192
|
+
created_at: number;
|
|
1193
|
+
updated_at: number;
|
|
1194
|
+
}
|
|
1195
|
+
/**
|
|
1196
|
+
* Provider credentials.
|
|
1197
|
+
*/
|
|
1198
|
+
interface Provider {
|
|
1199
|
+
name: string;
|
|
1200
|
+
sdk: string;
|
|
1201
|
+
api_key: string;
|
|
1202
|
+
}
|
|
1203
|
+
declare class DurableAgentBuilder<Env extends AgentBuilderEnv = AgentBuilderEnv> extends DurableObject<Env> {
|
|
1204
|
+
private migratedToVersion;
|
|
1205
|
+
private eventSockets;
|
|
1206
|
+
constructor(ctx: DurableObjectState, env: Env);
|
|
1207
|
+
/**
|
|
1208
|
+
* Returns the tools registry for lazy-loading tool definitions.
|
|
1209
|
+
* Must be overridden in a subclass.
|
|
1210
|
+
*/
|
|
1211
|
+
tools(): Record<string, () => Promise<any>>;
|
|
1212
|
+
/**
|
|
1213
|
+
* Returns the hooks registry for lazy-loading hook definitions.
|
|
1214
|
+
* Must be overridden in a subclass.
|
|
1215
|
+
*/
|
|
1216
|
+
hooks(): Record<string, () => Promise<any>>;
|
|
1217
|
+
/**
|
|
1218
|
+
* Returns the models registry for lazy-loading model definitions.
|
|
1219
|
+
* Must be overridden in a subclass.
|
|
1220
|
+
*/
|
|
1221
|
+
models(): Record<string, () => Promise<any>>;
|
|
1222
|
+
/**
|
|
1223
|
+
* Returns the prompts registry for lazy-loading prompt definitions.
|
|
1224
|
+
* Must be overridden in a subclass.
|
|
1225
|
+
*/
|
|
1226
|
+
prompts(): Record<string, () => Promise<any>>;
|
|
1227
|
+
/**
|
|
1228
|
+
* Returns the agents registry for lazy-loading agent definitions.
|
|
1229
|
+
* Must be overridden in a subclass.
|
|
1230
|
+
*/
|
|
1231
|
+
agents(): Record<string, () => Promise<any>>;
|
|
1232
|
+
private ensureMigrated;
|
|
1233
|
+
private getCurrentVersion;
|
|
1234
|
+
private runMigrations;
|
|
1235
|
+
/**
|
|
1236
|
+
* Create a new thread and add it to the registry.
|
|
1237
|
+
*/
|
|
1238
|
+
createThread(params: {
|
|
1239
|
+
agent_name: string;
|
|
1240
|
+
user_id?: string;
|
|
1241
|
+
tags?: string[];
|
|
1242
|
+
}): Promise<ThreadRegistryEntry>;
|
|
1243
|
+
/**
|
|
1244
|
+
* Get a thread by ID.
|
|
1245
|
+
*/
|
|
1246
|
+
getThread(id: string): Promise<ThreadRegistryEntry | null>;
|
|
1247
|
+
/**
|
|
1248
|
+
* List threads with optional filtering.
|
|
1249
|
+
*/
|
|
1250
|
+
listThreads(params?: {
|
|
1251
|
+
agent_name?: string;
|
|
1252
|
+
user_id?: string;
|
|
1253
|
+
limit?: number;
|
|
1254
|
+
offset?: number;
|
|
1255
|
+
}): Promise<{
|
|
1256
|
+
threads: ThreadRegistryEntry[];
|
|
1257
|
+
total: number;
|
|
1258
|
+
}>;
|
|
1259
|
+
/**
|
|
1260
|
+
* Delete a thread from the registry.
|
|
1261
|
+
*/
|
|
1262
|
+
deleteThread(id: string): Promise<boolean>;
|
|
1263
|
+
/**
|
|
1264
|
+
* Update a thread's agent_name (used during agent handoff).
|
|
1265
|
+
*/
|
|
1266
|
+
updateThreadAgent(id: string, agent_name: string): Promise<boolean>;
|
|
1267
|
+
/**
|
|
1268
|
+
* Update a thread's metadata.
|
|
1269
|
+
*/
|
|
1270
|
+
updateThread(id: string, params: UpdateThreadParams): Promise<ThreadRegistryEntry | null>;
|
|
1271
|
+
/**
|
|
1272
|
+
* Load a model definition by name.
|
|
1273
|
+
*/
|
|
1274
|
+
loadModel(name: string): Promise<any>;
|
|
1275
|
+
/**
|
|
1276
|
+
* List available model names.
|
|
1277
|
+
*/
|
|
1278
|
+
getModelNames(): string[];
|
|
1279
|
+
/**
|
|
1280
|
+
* Load a prompt definition by name.
|
|
1281
|
+
*/
|
|
1282
|
+
loadPrompt(name: string): Promise<any>;
|
|
1283
|
+
/**
|
|
1284
|
+
* List available prompt names.
|
|
1285
|
+
*/
|
|
1286
|
+
getPromptNames(): string[];
|
|
1287
|
+
/**
|
|
1288
|
+
* Load an agent definition by name.
|
|
1289
|
+
*/
|
|
1290
|
+
loadAgent(name: string): Promise<any>;
|
|
1291
|
+
/**
|
|
1292
|
+
* List available agent names.
|
|
1293
|
+
*/
|
|
1294
|
+
getAgentNames(): string[];
|
|
1295
|
+
/**
|
|
1296
|
+
* Get a provider's credentials.
|
|
1297
|
+
*/
|
|
1298
|
+
getProvider(name: string): Promise<Provider | null>;
|
|
1299
|
+
/**
|
|
1300
|
+
* Set a provider's credentials.
|
|
1301
|
+
*/
|
|
1302
|
+
setProvider(provider: Provider): Promise<void>;
|
|
1303
|
+
/**
|
|
1304
|
+
* List all providers.
|
|
1305
|
+
*/
|
|
1306
|
+
listProviders(): Promise<Provider[]>;
|
|
1307
|
+
/**
|
|
1308
|
+
* Delete a provider.
|
|
1309
|
+
*/
|
|
1310
|
+
deleteProvider(name: string): Promise<boolean>;
|
|
1311
|
+
/**
|
|
1312
|
+
* Get a user by username.
|
|
1313
|
+
*/
|
|
1314
|
+
getUserByUsername(username: string): Promise<User | null>;
|
|
1315
|
+
/**
|
|
1316
|
+
* Get a user by ID.
|
|
1317
|
+
*/
|
|
1318
|
+
getUserById(id: string): Promise<User | null>;
|
|
1319
|
+
/**
|
|
1320
|
+
* Create a new user.
|
|
1321
|
+
*/
|
|
1322
|
+
createUser(params: {
|
|
1323
|
+
username: string;
|
|
1324
|
+
password_hash: string;
|
|
1325
|
+
role?: 'admin';
|
|
1326
|
+
}): Promise<User>;
|
|
1327
|
+
/**
|
|
1328
|
+
* Check if any users exist (for first-time setup).
|
|
1329
|
+
*/
|
|
1330
|
+
hasUsers(): Promise<boolean>;
|
|
1331
|
+
/**
|
|
1332
|
+
* List all users (excludes password hash).
|
|
1333
|
+
*/
|
|
1334
|
+
listUsers(): Promise<Array<{
|
|
1335
|
+
id: string;
|
|
1336
|
+
username: string;
|
|
1337
|
+
role: 'admin';
|
|
1338
|
+
created_at: number;
|
|
1339
|
+
updated_at: number;
|
|
1340
|
+
}>>;
|
|
1341
|
+
/**
|
|
1342
|
+
* Update a user.
|
|
1343
|
+
*/
|
|
1344
|
+
updateUser(id: string, params: {
|
|
1345
|
+
username?: string;
|
|
1346
|
+
password_hash?: string;
|
|
1347
|
+
role?: 'admin';
|
|
1348
|
+
}): Promise<User | null>;
|
|
1349
|
+
/**
|
|
1350
|
+
* Delete a user.
|
|
1351
|
+
*/
|
|
1352
|
+
deleteUser(id: string): Promise<boolean>;
|
|
1353
|
+
/**
|
|
1354
|
+
* Create a new session.
|
|
1355
|
+
*/
|
|
1356
|
+
createSession(params: {
|
|
1357
|
+
user_id: string;
|
|
1358
|
+
token_hash: string;
|
|
1359
|
+
expires_at: number;
|
|
1360
|
+
}): Promise<string>;
|
|
1361
|
+
/**
|
|
1362
|
+
* Validate a session token.
|
|
1363
|
+
*/
|
|
1364
|
+
validateSession(tokenHash: string): Promise<{
|
|
1365
|
+
user_id: string;
|
|
1366
|
+
expires_at: number;
|
|
1367
|
+
} | null>;
|
|
1368
|
+
/**
|
|
1369
|
+
* Delete expired sessions.
|
|
1370
|
+
*/
|
|
1371
|
+
cleanupSessions(): Promise<number>;
|
|
1372
|
+
/**
|
|
1373
|
+
* Delete a session.
|
|
1374
|
+
*/
|
|
1375
|
+
deleteSession(tokenHash: string): Promise<void>;
|
|
1376
|
+
/**
|
|
1377
|
+
* Create an API key.
|
|
1378
|
+
*/
|
|
1379
|
+
createApiKey(params: {
|
|
1380
|
+
name: string;
|
|
1381
|
+
key_hash: string;
|
|
1382
|
+
key_prefix: string;
|
|
1383
|
+
last_five: string;
|
|
1384
|
+
user_id: string;
|
|
1385
|
+
}): Promise<string>;
|
|
1386
|
+
/**
|
|
1387
|
+
* Validate an API key.
|
|
1388
|
+
*/
|
|
1389
|
+
validateApiKey(keyHash: string): Promise<{
|
|
1390
|
+
user_id: string;
|
|
1391
|
+
id: string;
|
|
1392
|
+
} | null>;
|
|
1393
|
+
/**
|
|
1394
|
+
* List API keys for a user.
|
|
1395
|
+
*/
|
|
1396
|
+
listApiKeys(userId: string): Promise<Array<{
|
|
1397
|
+
id: string;
|
|
1398
|
+
name: string;
|
|
1399
|
+
key_prefix: string;
|
|
1400
|
+
last_five: string;
|
|
1401
|
+
created_at: number;
|
|
1402
|
+
last_used_at: number | null;
|
|
1403
|
+
}>>;
|
|
1404
|
+
/**
|
|
1405
|
+
* Delete an API key.
|
|
1406
|
+
*/
|
|
1407
|
+
deleteApiKey(id: string, userId: string): Promise<boolean>;
|
|
1408
|
+
/**
|
|
1409
|
+
* Link an OAuth account to a user.
|
|
1410
|
+
*/
|
|
1411
|
+
linkOAuthAccount(params: {
|
|
1412
|
+
user_id: string;
|
|
1413
|
+
provider: 'github' | 'google';
|
|
1414
|
+
provider_user_id: string;
|
|
1415
|
+
provider_username?: string;
|
|
1416
|
+
}): Promise<void>;
|
|
1417
|
+
/**
|
|
1418
|
+
* Find user by OAuth account.
|
|
1419
|
+
*/
|
|
1420
|
+
findUserByOAuth(provider: 'github' | 'google', providerUserId: string): Promise<User | null>;
|
|
1421
|
+
/**
|
|
1422
|
+
* Acquire edit lock for GitHub commits.
|
|
1423
|
+
*/
|
|
1424
|
+
acquireEditLock(params: {
|
|
1425
|
+
locked_by: string;
|
|
1426
|
+
lock_reason: string;
|
|
1427
|
+
}): Promise<boolean>;
|
|
1428
|
+
/**
|
|
1429
|
+
* Release edit lock.
|
|
1430
|
+
*/
|
|
1431
|
+
releaseEditLock(lockedBy: string): Promise<boolean>;
|
|
1432
|
+
/**
|
|
1433
|
+
* Get current lock state.
|
|
1434
|
+
*/
|
|
1435
|
+
getEditLockState(): Promise<{
|
|
1436
|
+
locked: boolean;
|
|
1437
|
+
locked_by: string | null;
|
|
1438
|
+
locked_at: number | null;
|
|
1439
|
+
lock_reason: string | null;
|
|
1440
|
+
pending_changes: string | null;
|
|
1441
|
+
}>;
|
|
1442
|
+
/**
|
|
1443
|
+
* Store pending changes for commit.
|
|
1444
|
+
*/
|
|
1445
|
+
setPendingChanges(changes: string): Promise<void>;
|
|
1446
|
+
/**
|
|
1447
|
+
* Get the Durable Object stub for a thread.
|
|
1448
|
+
*/
|
|
1449
|
+
getThreadStub(threadId: string): DurableObjectStub;
|
|
1450
|
+
/**
|
|
1451
|
+
* Handle fetch requests - used for WebSocket upgrades
|
|
1452
|
+
*/
|
|
1453
|
+
fetch(request: Request): Promise<Response>;
|
|
1454
|
+
/**
|
|
1455
|
+
* Handle WebSocket upgrade for events channel
|
|
1456
|
+
* Uses Hibernation API to reduce costs during inactivity
|
|
1457
|
+
*/
|
|
1458
|
+
private handleEventsWebSocketUpgrade;
|
|
1459
|
+
/**
|
|
1460
|
+
* Broadcast an event to all connected WebSocket clients
|
|
1461
|
+
*/
|
|
1462
|
+
private broadcastEvent;
|
|
1463
|
+
/**
|
|
1464
|
+
* WebSocket Hibernation API handler for incoming messages
|
|
1465
|
+
* Called when a message is received on a hibernated WebSocket
|
|
1466
|
+
*/
|
|
1467
|
+
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): Promise<void>;
|
|
1468
|
+
/**
|
|
1469
|
+
* WebSocket Hibernation API handler for connection close
|
|
1470
|
+
* Called when a WebSocket connection is closed
|
|
1471
|
+
*/
|
|
1472
|
+
webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): Promise<void>;
|
|
1473
|
+
/**
|
|
1474
|
+
* WebSocket Hibernation API handler for errors
|
|
1475
|
+
* Called when a WebSocket encounters an error
|
|
1476
|
+
*/
|
|
1477
|
+
webSocketError(ws: WebSocket, error: unknown): Promise<void>;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* Model definition module for AgentBuilder.
|
|
1482
|
+
*
|
|
1483
|
+
* Models define LLM configurations including provider, model ID, pricing,
|
|
1484
|
+
* and fallback chains. Models are referenced by name from prompts.
|
|
1485
|
+
*
|
|
1486
|
+
* @module
|
|
1487
|
+
*/
|
|
1488
|
+
/**
|
|
1489
|
+
* Supported LLM provider types.
|
|
1490
|
+
* Each provider requires a corresponding API key environment variable:
|
|
1491
|
+
* - `openai` → `OPENAI_API_KEY`
|
|
1492
|
+
* - `openrouter` → `OPENROUTER_API_KEY`
|
|
1493
|
+
* - `anthropic` → `ANTHROPIC_API_KEY`
|
|
1494
|
+
* - `google` → `GOOGLE_API_KEY`
|
|
1495
|
+
*/
|
|
1496
|
+
type ModelProvider = 'openai' | 'openrouter' | 'anthropic' | 'google';
|
|
1497
|
+
/**
|
|
1498
|
+
* Model definition configuration.
|
|
1499
|
+
*
|
|
1500
|
+
* @template N - The model name as a string literal type for type inference
|
|
1501
|
+
*
|
|
1502
|
+
* @example
|
|
1503
|
+
* ```typescript
|
|
1504
|
+
* import { defineModel } from '@standardagents/builder';
|
|
1505
|
+
*
|
|
1506
|
+
* export default defineModel({
|
|
1507
|
+
* name: 'gpt-4o',
|
|
1508
|
+
* provider: 'openai',
|
|
1509
|
+
* model: 'gpt-4o',
|
|
1510
|
+
* fallbacks: ['gpt-4-turbo', 'gpt-3.5-turbo'],
|
|
1511
|
+
* inputPrice: 2.5,
|
|
1512
|
+
* outputPrice: 10,
|
|
1513
|
+
* });
|
|
1514
|
+
* ```
|
|
1515
|
+
*/
|
|
1516
|
+
interface ModelDefinition<N extends string = string> {
|
|
1517
|
+
/**
|
|
1518
|
+
* Unique name for this model definition.
|
|
1519
|
+
* Used as the identifier when referencing from prompts.
|
|
1520
|
+
* Should be descriptive and consistent (e.g., 'gpt-4o', 'claude-3-opus').
|
|
1521
|
+
*/
|
|
1522
|
+
name: N;
|
|
1523
|
+
/**
|
|
1524
|
+
* The LLM provider to use for API calls.
|
|
1525
|
+
* The corresponding API key environment variable must be set.
|
|
1526
|
+
*/
|
|
1527
|
+
provider: ModelProvider;
|
|
1528
|
+
/**
|
|
1529
|
+
* The actual model identifier sent to the provider API.
|
|
1530
|
+
*
|
|
1531
|
+
* For OpenAI: 'gpt-4o', 'gpt-4-turbo', 'gpt-3.5-turbo', etc.
|
|
1532
|
+
* For OpenRouter: 'openai/gpt-4o', 'anthropic/claude-3-opus', etc.
|
|
1533
|
+
* For Anthropic: 'claude-3-opus-20240229', 'claude-3-sonnet-20240229', etc.
|
|
1534
|
+
* For Google: 'gemini-1.5-pro', 'gemini-1.5-flash', etc.
|
|
1535
|
+
*/
|
|
1536
|
+
model: string;
|
|
1537
|
+
/**
|
|
1538
|
+
* Optional list of additional provider prefixes for OpenRouter.
|
|
1539
|
+
* Allows routing through specific providers when using OpenRouter.
|
|
1540
|
+
*
|
|
1541
|
+
* @example ['anthropic', 'google'] - prefer Anthropic, fallback to Google
|
|
1542
|
+
*/
|
|
1543
|
+
includedProviders?: string[];
|
|
1544
|
+
/**
|
|
1545
|
+
* Fallback models to try if this model fails.
|
|
1546
|
+
* Referenced by model name (must be defined in agentbuilder/models/).
|
|
1547
|
+
* Tried in order after primary model exhausts retries.
|
|
1548
|
+
*
|
|
1549
|
+
* @example ['gpt-4', 'gpt-3.5-turbo']
|
|
1550
|
+
*/
|
|
1551
|
+
fallbacks?: AgentBuilder.Models[];
|
|
1552
|
+
/**
|
|
1553
|
+
* Cost per 1 million input tokens in USD.
|
|
1554
|
+
* Used for cost tracking and reporting in logs.
|
|
1555
|
+
*/
|
|
1556
|
+
inputPrice?: number;
|
|
1557
|
+
/**
|
|
1558
|
+
* Cost per 1 million output tokens in USD.
|
|
1559
|
+
* Used for cost tracking and reporting in logs.
|
|
1560
|
+
*/
|
|
1561
|
+
outputPrice?: number;
|
|
1562
|
+
/**
|
|
1563
|
+
* Cost per 1 million cached input tokens in USD.
|
|
1564
|
+
* Some providers offer reduced pricing for cached/repeated prompts.
|
|
1565
|
+
*/
|
|
1566
|
+
cachedPrice?: number;
|
|
1567
|
+
}
|
|
1568
|
+
/**
|
|
1569
|
+
* Defines an LLM model configuration.
|
|
1570
|
+
*
|
|
1571
|
+
* Models are the foundation of the agent system - they specify which
|
|
1572
|
+
* AI model to use and how to connect to it. Models can have fallbacks
|
|
1573
|
+
* for reliability and include pricing for cost tracking.
|
|
1574
|
+
*
|
|
1575
|
+
* @template N - The model name as a string literal type
|
|
1576
|
+
* @param options - Model configuration options
|
|
1577
|
+
* @returns The model definition for registration
|
|
1578
|
+
*
|
|
1579
|
+
* @example
|
|
1580
|
+
* ```typescript
|
|
1581
|
+
* // agentbuilder/models/gpt_4o.ts
|
|
1582
|
+
* import { defineModel } from '@standardagents/builder';
|
|
1583
|
+
*
|
|
1584
|
+
* export default defineModel({
|
|
1585
|
+
* name: 'gpt-4o',
|
|
1586
|
+
* provider: 'openai',
|
|
1587
|
+
* model: 'gpt-4o',
|
|
1588
|
+
* fallbacks: ['gpt-4-turbo'],
|
|
1589
|
+
* inputPrice: 2.5,
|
|
1590
|
+
* outputPrice: 10,
|
|
1591
|
+
* });
|
|
1592
|
+
* ```
|
|
1593
|
+
*
|
|
1594
|
+
* @example
|
|
1595
|
+
* ```typescript
|
|
1596
|
+
* // Using OpenRouter with provider preferences
|
|
1597
|
+
* export default defineModel({
|
|
1598
|
+
* name: 'claude-3-opus',
|
|
1599
|
+
* provider: 'openrouter',
|
|
1600
|
+
* model: 'anthropic/claude-3-opus',
|
|
1601
|
+
* includedProviders: ['anthropic'],
|
|
1602
|
+
* });
|
|
1603
|
+
* ```
|
|
1604
|
+
*/
|
|
1605
|
+
declare function defineModel<N extends string>(options: ModelDefinition<N>): ModelDefinition<N>;
|
|
1606
|
+
|
|
1607
|
+
/**
|
|
1608
|
+
* Prompt definition module for AgentBuilder.
|
|
1609
|
+
*
|
|
1610
|
+
* Prompts define LLM interaction configurations including the system prompt,
|
|
1611
|
+
* model selection, available tools, and various behavioral options.
|
|
1612
|
+
*
|
|
1613
|
+
* @module
|
|
1614
|
+
*/
|
|
1615
|
+
|
|
1616
|
+
/**
|
|
1617
|
+
* A text part of a prompt - static text content.
|
|
1618
|
+
*
|
|
1619
|
+
* @example
|
|
1620
|
+
* ```typescript
|
|
1621
|
+
* { type: 'text', content: 'You are a helpful assistant.\n\n' }
|
|
1622
|
+
* ```
|
|
1623
|
+
*/
|
|
1624
|
+
interface PromptTextPart {
|
|
1625
|
+
type: 'text';
|
|
1626
|
+
/** The text content */
|
|
1627
|
+
content: string;
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* A prompt inclusion part - includes another prompt's content.
|
|
1631
|
+
* Uses AgentBuilder.Prompts for type-safe autocomplete of prompt names.
|
|
1632
|
+
*
|
|
1633
|
+
* @example
|
|
1634
|
+
* ```typescript
|
|
1635
|
+
* { type: 'include', prompt: 'responder_rules' }
|
|
1636
|
+
* ```
|
|
1637
|
+
*/
|
|
1638
|
+
interface PromptIncludePart {
|
|
1639
|
+
type: 'include';
|
|
1640
|
+
/** The name of the prompt to include (type-safe with autocomplete) */
|
|
1641
|
+
prompt: AgentBuilder.Prompts;
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* A single part of a structured prompt.
|
|
1645
|
+
* Discriminated union on `type` field for TypeScript narrowing.
|
|
1646
|
+
*/
|
|
1647
|
+
type PromptPart = PromptTextPart | PromptIncludePart;
|
|
1648
|
+
/**
|
|
1649
|
+
* A structured prompt is an array of prompt parts.
|
|
1650
|
+
* Provides type-safe composition with other prompts via autocomplete.
|
|
1651
|
+
*
|
|
1652
|
+
* @example
|
|
1653
|
+
* ```typescript
|
|
1654
|
+
* prompt: [
|
|
1655
|
+
* { type: 'text', content: 'You are a helpful assistant.\n\n' },
|
|
1656
|
+
* { type: 'include', prompt: 'common_rules' },
|
|
1657
|
+
* { type: 'text', content: '\n\nBe concise.' },
|
|
1658
|
+
* ]
|
|
1659
|
+
* ```
|
|
1660
|
+
*/
|
|
1661
|
+
type StructuredPrompt = PromptPart[];
|
|
1662
|
+
/**
|
|
1663
|
+
* The prompt content can be either a plain string or a structured array.
|
|
1664
|
+
*
|
|
1665
|
+
* @example
|
|
1666
|
+
* ```typescript
|
|
1667
|
+
* // Simple string prompt:
|
|
1668
|
+
* prompt: 'You are a helpful assistant.'
|
|
1669
|
+
*
|
|
1670
|
+
* // Structured prompt with includes:
|
|
1671
|
+
* prompt: [
|
|
1672
|
+
* { type: 'text', content: 'You are a helpful assistant.\n\n' },
|
|
1673
|
+
* { type: 'include', prompt: 'common_rules' },
|
|
1674
|
+
* ]
|
|
1675
|
+
* ```
|
|
1676
|
+
*/
|
|
1677
|
+
type PromptContent = string | StructuredPrompt;
|
|
1678
|
+
/**
|
|
1679
|
+
* Tool configuration for including a tool in a prompt.
|
|
1680
|
+
*
|
|
1681
|
+
* @template T - The tool name type (for type-safe tool references)
|
|
1682
|
+
*/
|
|
1683
|
+
interface ToolConfig<T extends string = AgentBuilder.Callables> {
|
|
1684
|
+
/**
|
|
1685
|
+
* Name of the tool to include.
|
|
1686
|
+
* Must be a tool, prompt, or agent defined in agentbuilder/.
|
|
1687
|
+
*/
|
|
1688
|
+
name: T;
|
|
1689
|
+
/**
|
|
1690
|
+
* Include text response content from sub-prompt execution in the tool result.
|
|
1691
|
+
* @default true
|
|
1692
|
+
*/
|
|
1693
|
+
includeTextResponse?: boolean;
|
|
1694
|
+
/**
|
|
1695
|
+
* Include tool call details from sub-prompt execution in the tool result.
|
|
1696
|
+
* @default true
|
|
1697
|
+
*/
|
|
1698
|
+
includeToolCalls?: boolean;
|
|
1699
|
+
/**
|
|
1700
|
+
* Include error details from sub-prompt execution in the tool result.
|
|
1701
|
+
* @default true
|
|
1702
|
+
*/
|
|
1703
|
+
includeErrors?: boolean;
|
|
1704
|
+
/**
|
|
1705
|
+
* Property from the tool call arguments to use as the initial user message
|
|
1706
|
+
* when this tool triggers a sub-prompt execution.
|
|
1707
|
+
*
|
|
1708
|
+
* @example
|
|
1709
|
+
* If the tool is called with `{ query: "search term", limit: 10 }` and
|
|
1710
|
+
* `initUserMessageProperty: 'query'`, the sub-prompt will receive
|
|
1711
|
+
* "search term" as the initial user message.
|
|
1712
|
+
*/
|
|
1713
|
+
initUserMessageProperty?: string;
|
|
1714
|
+
}
|
|
1715
|
+
/**
|
|
1716
|
+
* Reasoning configuration for models that support extended thinking.
|
|
1717
|
+
* Applies to models like OpenAI o1, Anthropic Claude with extended thinking,
|
|
1718
|
+
* Google Gemini with thinking, and Qwen with reasoning.
|
|
1719
|
+
*/
|
|
1720
|
+
interface ReasoningConfig {
|
|
1721
|
+
/**
|
|
1722
|
+
* Effort level for reasoning models.
|
|
1723
|
+
* Higher effort = more thinking tokens = potentially better results.
|
|
1724
|
+
*
|
|
1725
|
+
* - `low`: Minimal reasoning, faster responses
|
|
1726
|
+
* - `medium`: Balanced reasoning and speed
|
|
1727
|
+
* - `high`: Maximum reasoning, slower but more thorough
|
|
1728
|
+
*
|
|
1729
|
+
* @default undefined (use model defaults)
|
|
1730
|
+
*/
|
|
1731
|
+
effort?: 'low' | 'medium' | 'high';
|
|
1732
|
+
/**
|
|
1733
|
+
* Maximum tokens to allocate for reasoning.
|
|
1734
|
+
* Applies to models that support token limits on reasoning
|
|
1735
|
+
* (Anthropic, Gemini, Qwen).
|
|
1736
|
+
*/
|
|
1737
|
+
maxTokens?: number;
|
|
1738
|
+
/**
|
|
1739
|
+
* Use reasoning internally but exclude from the response.
|
|
1740
|
+
* Model thinks through the problem but only returns the final answer.
|
|
1741
|
+
* Useful for cleaner outputs while maintaining reasoning quality.
|
|
1742
|
+
*/
|
|
1743
|
+
exclude?: boolean;
|
|
1744
|
+
/**
|
|
1745
|
+
* Include reasoning content in the message history for multi-turn context.
|
|
1746
|
+
* When true, reasoning is preserved and visible to subsequent turns.
|
|
1747
|
+
* @default false
|
|
1748
|
+
*/
|
|
1749
|
+
include?: boolean;
|
|
1750
|
+
}
|
|
1751
|
+
/**
|
|
1752
|
+
* Prompt definition configuration.
|
|
1753
|
+
*
|
|
1754
|
+
* @template N - The prompt name as a string literal type
|
|
1755
|
+
* @template S - The Zod schema type for requiredSchema (inferred automatically)
|
|
1756
|
+
*
|
|
1757
|
+
* @example
|
|
1758
|
+
* ```typescript
|
|
1759
|
+
* import { definePrompt } from '@standardagents/builder';
|
|
1760
|
+
* import { z } from 'zod';
|
|
1761
|
+
*
|
|
1762
|
+
* export default definePrompt({
|
|
1763
|
+
* name: 'customer_support',
|
|
1764
|
+
* toolDescription: 'Handle customer support inquiries',
|
|
1765
|
+
* model: 'gpt-4o',
|
|
1766
|
+
* // Simple string prompt:
|
|
1767
|
+
* prompt: `You are a helpful customer support agent.
|
|
1768
|
+
* Always be polite and try to resolve issues quickly.`,
|
|
1769
|
+
* // Or structured prompt with type-safe includes:
|
|
1770
|
+
* // prompt: [
|
|
1771
|
+
* // { type: 'text', content: 'You are a helpful customer support agent.\n\n' },
|
|
1772
|
+
* // { type: 'include', prompt: 'common_rules' },
|
|
1773
|
+
* // ],
|
|
1774
|
+
* tools: ['search_knowledge_base', 'create_ticket'],
|
|
1775
|
+
* requiredSchema: z.object({
|
|
1776
|
+
* query: z.string().describe('The customer inquiry'),
|
|
1777
|
+
* }),
|
|
1778
|
+
* });
|
|
1779
|
+
* ```
|
|
1780
|
+
*/
|
|
1781
|
+
interface PromptDefinition<N extends string = string, S extends z.ZodTypeAny = z.ZodTypeAny> {
|
|
1782
|
+
/**
|
|
1783
|
+
* Unique name for this prompt.
|
|
1784
|
+
* Used as the identifier when referencing from agents or as a tool.
|
|
1785
|
+
* Should be snake_case (e.g., 'customer_support', 'data_analyst').
|
|
1786
|
+
*/
|
|
1787
|
+
name: N;
|
|
1788
|
+
/**
|
|
1789
|
+
* Description shown when this prompt is exposed as a tool.
|
|
1790
|
+
* Should clearly describe what this prompt does for LLM tool selection.
|
|
1791
|
+
*/
|
|
1792
|
+
toolDescription: string;
|
|
1793
|
+
/**
|
|
1794
|
+
* The system prompt content sent to the LLM.
|
|
1795
|
+
*
|
|
1796
|
+
* Can be either:
|
|
1797
|
+
* 1. A plain string - simple prompt text
|
|
1798
|
+
* 2. A structured array - for composing prompts with type-safe includes
|
|
1799
|
+
*
|
|
1800
|
+
* @example
|
|
1801
|
+
* ```typescript
|
|
1802
|
+
* // Simple string prompt:
|
|
1803
|
+
* prompt: 'You are a helpful assistant.'
|
|
1804
|
+
*
|
|
1805
|
+
* // Structured prompt with type-safe includes:
|
|
1806
|
+
* prompt: [
|
|
1807
|
+
* { type: 'text', content: 'You are a helpful assistant.\n\n' },
|
|
1808
|
+
* { type: 'include', prompt: 'common_rules' }, // autocomplete for prompt names!
|
|
1809
|
+
* { type: 'text', content: '\n\nBe concise.' },
|
|
1810
|
+
* ]
|
|
1811
|
+
* ```
|
|
1812
|
+
*/
|
|
1813
|
+
prompt: PromptContent;
|
|
1814
|
+
/**
|
|
1815
|
+
* Model to use for this prompt.
|
|
1816
|
+
* Must reference a model defined in agentbuilder/models/.
|
|
1817
|
+
* Provides autocomplete when types are generated.
|
|
1818
|
+
*/
|
|
1819
|
+
model: AgentBuilder.Models;
|
|
1820
|
+
/**
|
|
1821
|
+
* @deprecated All prompts are now automatically exposed as tools.
|
|
1822
|
+
* This property is ignored and will be removed in a future version.
|
|
1823
|
+
*/
|
|
1824
|
+
exposeAsTool?: boolean;
|
|
1825
|
+
/**
|
|
1826
|
+
* Include full chat history in the LLM context.
|
|
1827
|
+
* When true, all previous messages in the conversation are included.
|
|
1828
|
+
* @default false
|
|
1829
|
+
*/
|
|
1830
|
+
includeChat?: boolean;
|
|
1831
|
+
/**
|
|
1832
|
+
* Include results from past tool calls in the LLM context.
|
|
1833
|
+
* When true, previous tool call results are visible to the LLM.
|
|
1834
|
+
* @default false
|
|
1835
|
+
*/
|
|
1836
|
+
includePastTools?: boolean;
|
|
1837
|
+
/**
|
|
1838
|
+
* Allow parallel execution of multiple tool calls.
|
|
1839
|
+
* When true, if the LLM requests multiple tools, they execute concurrently.
|
|
1840
|
+
* @default false
|
|
1841
|
+
*/
|
|
1842
|
+
parallelToolCalls?: boolean;
|
|
1843
|
+
/**
|
|
1844
|
+
* Tool calling strategy for the LLM.
|
|
1845
|
+
*
|
|
1846
|
+
* - `auto`: Model decides when to call tools (default)
|
|
1847
|
+
* - `none`: Disable tool calling entirely
|
|
1848
|
+
* - `required`: Force the model to call at least one tool
|
|
1849
|
+
*
|
|
1850
|
+
* @default 'auto'
|
|
1851
|
+
*/
|
|
1852
|
+
toolChoice?: 'auto' | 'none' | 'required';
|
|
1853
|
+
/**
|
|
1854
|
+
* Zod schema for validating inputs when this prompt is called as a tool.
|
|
1855
|
+
*
|
|
1856
|
+
* The schema provides:
|
|
1857
|
+
* - Runtime validation of tool call arguments
|
|
1858
|
+
* - Type inference for the prompt's input type
|
|
1859
|
+
* - Auto-generated JSON Schema for LLM tool definitions
|
|
1860
|
+
*
|
|
1861
|
+
* Use `.describe()` on schema fields to provide descriptions for the LLM.
|
|
1862
|
+
*
|
|
1863
|
+
* @example
|
|
1864
|
+
* ```typescript
|
|
1865
|
+
* requiredSchema: z.object({
|
|
1866
|
+
* query: z.string().describe('The search query'),
|
|
1867
|
+
* limit: z.number().optional().default(10).describe('Max results'),
|
|
1868
|
+
* })
|
|
1869
|
+
* ```
|
|
1870
|
+
*/
|
|
1871
|
+
requiredSchema?: S;
|
|
1872
|
+
/**
|
|
1873
|
+
* Tools available to this prompt.
|
|
1874
|
+
* Can be simple tool names or detailed configurations.
|
|
1875
|
+
*
|
|
1876
|
+
* Tools can be:
|
|
1877
|
+
* - Custom tools defined in agentbuilder/tools/
|
|
1878
|
+
* - Other prompts with exposeAsTool: true
|
|
1879
|
+
* - Agents with exposeAsTool: true
|
|
1880
|
+
*
|
|
1881
|
+
* @example
|
|
1882
|
+
* ```typescript
|
|
1883
|
+
* tools: [
|
|
1884
|
+
* 'search_docs', // Simple reference
|
|
1885
|
+
* { name: 'create_ticket', includeErrors: false }, // With config
|
|
1886
|
+
* ]
|
|
1887
|
+
* ```
|
|
1888
|
+
*/
|
|
1889
|
+
tools?: (AgentBuilder.Callables | ToolConfig)[];
|
|
1890
|
+
/**
|
|
1891
|
+
* Agents that can receive handoffs from this prompt.
|
|
1892
|
+
* Enables multi-agent workflows where this prompt can transfer
|
|
1893
|
+
* the conversation to a specialized agent.
|
|
1894
|
+
*/
|
|
1895
|
+
handoffAgents?: AgentBuilder.Agents[];
|
|
1896
|
+
/**
|
|
1897
|
+
* Tool to execute before the LLM request.
|
|
1898
|
+
* Useful for data fetching, context preparation, or preprocessing.
|
|
1899
|
+
* The tool result is available in the prompt context.
|
|
1900
|
+
*/
|
|
1901
|
+
beforeTool?: AgentBuilder.Callables;
|
|
1902
|
+
/**
|
|
1903
|
+
* Tool to execute after the LLM response.
|
|
1904
|
+
* Useful for post-processing, logging, or side effects.
|
|
1905
|
+
*/
|
|
1906
|
+
afterTool?: AgentBuilder.Callables;
|
|
1907
|
+
/**
|
|
1908
|
+
* Reasoning configuration for models that support extended thinking.
|
|
1909
|
+
* Configure effort level, token limits, and visibility of reasoning.
|
|
1910
|
+
*/
|
|
1911
|
+
reasoning?: ReasoningConfig;
|
|
1912
|
+
}
|
|
1913
|
+
/**
|
|
1914
|
+
* Helper type to extract the inferred input type from a prompt's Zod schema.
|
|
1915
|
+
*
|
|
1916
|
+
* @template T - The prompt definition type
|
|
1917
|
+
*
|
|
1918
|
+
* @example
|
|
1919
|
+
* ```typescript
|
|
1920
|
+
* const searchPrompt = definePrompt({
|
|
1921
|
+
* name: 'search',
|
|
1922
|
+
* requiredSchema: z.object({ query: z.string(), limit: z.number() }),
|
|
1923
|
+
* // ...
|
|
1924
|
+
* });
|
|
1925
|
+
*
|
|
1926
|
+
* type SearchInput = PromptInput<typeof searchPrompt>;
|
|
1927
|
+
* // { query: string; limit: number }
|
|
1928
|
+
* ```
|
|
1929
|
+
*/
|
|
1930
|
+
type PromptInput<T extends PromptDefinition<any, any>> = T['requiredSchema'] extends z.ZodTypeAny ? z.infer<T['requiredSchema']> : never;
|
|
1931
|
+
/**
|
|
1932
|
+
* Defines a prompt configuration for LLM interactions.
|
|
1933
|
+
*
|
|
1934
|
+
* Prompts are the primary way to configure how agents interact with LLMs.
|
|
1935
|
+
* They specify the system prompt, available tools, input validation,
|
|
1936
|
+
* and various behavioral options.
|
|
1937
|
+
*
|
|
1938
|
+
* @template N - The prompt name as a string literal type
|
|
1939
|
+
* @template S - The Zod schema type for requiredSchema
|
|
1940
|
+
* @param options - Prompt configuration options
|
|
1941
|
+
* @returns The prompt definition for registration
|
|
1942
|
+
*
|
|
1943
|
+
* @example
|
|
1944
|
+
* ```typescript
|
|
1945
|
+
* // agentbuilder/prompts/customer_support.ts
|
|
1946
|
+
* import { definePrompt } from '@standardagents/builder';
|
|
1947
|
+
* import { z } from 'zod';
|
|
1948
|
+
*
|
|
1949
|
+
* export default definePrompt({
|
|
1950
|
+
* name: 'customer_support',
|
|
1951
|
+
* toolDescription: 'Handle customer support inquiries',
|
|
1952
|
+
* model: 'gpt-4o',
|
|
1953
|
+
* prompt: `You are a helpful customer support agent.
|
|
1954
|
+
* Always be polite and try to resolve issues quickly.
|
|
1955
|
+
* If you cannot help, offer to escalate to a human.`,
|
|
1956
|
+
* tools: ['search_knowledge_base', 'create_ticket'],
|
|
1957
|
+
* handoffAgents: ['escalation_agent'],
|
|
1958
|
+
* includeChat: true,
|
|
1959
|
+
* exposeAsTool: true,
|
|
1960
|
+
* requiredSchema: z.object({
|
|
1961
|
+
* query: z.string().describe('The customer inquiry'),
|
|
1962
|
+
* }),
|
|
1963
|
+
* });
|
|
1964
|
+
* ```
|
|
1965
|
+
*/
|
|
1966
|
+
declare function definePrompt<N extends string, S extends z.ZodTypeAny = never>(options: PromptDefinition<N, S>): PromptDefinition<N, S>;
|
|
1967
|
+
|
|
1968
|
+
/**
|
|
1969
|
+
* Agent definition module for AgentBuilder.
|
|
1970
|
+
*
|
|
1971
|
+
* Agents orchestrate conversations between AI models (dual_ai) or between
|
|
1972
|
+
* AI and human users (ai_human). They define the prompts, stop conditions,
|
|
1973
|
+
* and behavioral rules for each side of the conversation.
|
|
1974
|
+
*
|
|
1975
|
+
* @module
|
|
1976
|
+
*/
|
|
1977
|
+
/**
|
|
1978
|
+
* Agent conversation type.
|
|
1979
|
+
*
|
|
1980
|
+
* - `ai_human`: AI conversing with a human user (most common)
|
|
1981
|
+
* - `dual_ai`: Two AI participants conversing with each other
|
|
1982
|
+
*/
|
|
1983
|
+
type AgentType = 'ai_human' | 'dual_ai';
|
|
1984
|
+
/**
|
|
1985
|
+
* Configuration for one side of an agent conversation.
|
|
1986
|
+
*
|
|
1987
|
+
* Each side has a prompt, stop conditions, and turn limits.
|
|
1988
|
+
* For `ai_human` agents, only sideA (the AI) needs configuration.
|
|
1989
|
+
* For `dual_ai` agents, both sides need configuration.
|
|
1990
|
+
*/
|
|
1991
|
+
interface SideConfig {
|
|
1992
|
+
/**
|
|
1993
|
+
* Custom label for this side of the conversation.
|
|
1994
|
+
* Used in UI and logs for clarity.
|
|
1995
|
+
*
|
|
1996
|
+
* @example 'Support Agent', 'Customer', 'ATC', 'Pilot'
|
|
1997
|
+
*/
|
|
1998
|
+
label?: string;
|
|
1999
|
+
/**
|
|
2000
|
+
* The prompt to use for this side.
|
|
2001
|
+
* Must reference a prompt defined in agentbuilder/prompts/.
|
|
2002
|
+
*/
|
|
2003
|
+
prompt: AgentBuilder.Prompts;
|
|
2004
|
+
/**
|
|
2005
|
+
* Stop this side's turn when it returns a text response (no tool calls).
|
|
2006
|
+
* When true, the side's turn ends after producing a message without tools.
|
|
2007
|
+
* @default true
|
|
2008
|
+
*/
|
|
2009
|
+
stopOnResponse?: boolean;
|
|
2010
|
+
/**
|
|
2011
|
+
* Stop this side's turn when a specific tool is called.
|
|
2012
|
+
* Overrides stopOnResponse when the named tool is invoked.
|
|
2013
|
+
* Requires stopToolResponseProperty to extract the result.
|
|
2014
|
+
*/
|
|
2015
|
+
stopTool?: AgentBuilder.Callables;
|
|
2016
|
+
/**
|
|
2017
|
+
* Property to extract from the stop tool's result.
|
|
2018
|
+
* Required when stopTool is set.
|
|
2019
|
+
* The extracted value is used to determine the conversation outcome.
|
|
2020
|
+
*/
|
|
2021
|
+
stopToolResponseProperty?: string;
|
|
2022
|
+
/**
|
|
2023
|
+
* Maximum turns for this side before forcing a stop.
|
|
2024
|
+
* Safety limit to prevent runaway conversations.
|
|
2025
|
+
* A turn is one complete request/response cycle.
|
|
2026
|
+
*/
|
|
2027
|
+
maxTurns?: number;
|
|
2028
|
+
/**
|
|
2029
|
+
* Tool that ends the entire conversation when called.
|
|
2030
|
+
* Different from stopTool - this ends the conversation for both sides,
|
|
2031
|
+
* not just this side's turn.
|
|
2032
|
+
*/
|
|
2033
|
+
endConversationTool?: AgentBuilder.Callables;
|
|
2034
|
+
/**
|
|
2035
|
+
* Enable manual stop condition handling via hooks.
|
|
2036
|
+
* When true, stop conditions are evaluated by custom hook logic
|
|
2037
|
+
* instead of the built-in rules.
|
|
2038
|
+
* @default false
|
|
2039
|
+
*/
|
|
2040
|
+
manualStopCondition?: boolean;
|
|
2041
|
+
}
|
|
2042
|
+
/**
|
|
2043
|
+
* Agent definition configuration.
|
|
2044
|
+
*
|
|
2045
|
+
* @template N - The agent name as a string literal type
|
|
2046
|
+
*
|
|
2047
|
+
* @example
|
|
2048
|
+
* ```typescript
|
|
2049
|
+
* import { defineAgent } from '@standardagents/builder';
|
|
2050
|
+
*
|
|
2051
|
+
* export default defineAgent({
|
|
2052
|
+
* name: 'support_agent',
|
|
2053
|
+
* title: 'Customer Support Agent',
|
|
2054
|
+
* type: 'ai_human',
|
|
2055
|
+
* sideA: {
|
|
2056
|
+
* label: 'Support',
|
|
2057
|
+
* prompt: 'customer_support',
|
|
2058
|
+
* stopOnResponse: true,
|
|
2059
|
+
* },
|
|
2060
|
+
* tags: ['support', 'tier-1'],
|
|
2061
|
+
* });
|
|
2062
|
+
* ```
|
|
2063
|
+
*/
|
|
2064
|
+
interface AgentDefinition<N extends string = string> {
|
|
2065
|
+
/**
|
|
2066
|
+
* Unique name for this agent.
|
|
2067
|
+
* Used as the identifier for thread creation and handoffs.
|
|
2068
|
+
* Should be snake_case (e.g., 'support_agent', 'research_flow').
|
|
2069
|
+
*/
|
|
2070
|
+
name: N;
|
|
2071
|
+
/**
|
|
2072
|
+
* Human-readable title for the agent.
|
|
2073
|
+
* Optional - if not provided, the name will be used.
|
|
2074
|
+
* @deprecated Use name instead. Title will be removed in a future version.
|
|
2075
|
+
*/
|
|
2076
|
+
title?: string;
|
|
2077
|
+
/**
|
|
2078
|
+
* Agent conversation type.
|
|
2079
|
+
*
|
|
2080
|
+
* - `ai_human`: AI conversing with a human user (default)
|
|
2081
|
+
* - `dual_ai`: Two AI participants conversing
|
|
2082
|
+
*
|
|
2083
|
+
* @default 'ai_human'
|
|
2084
|
+
*/
|
|
2085
|
+
type?: AgentType;
|
|
2086
|
+
/**
|
|
2087
|
+
* Maximum total turns across both sides.
|
|
2088
|
+
* Only applies to `dual_ai` agents.
|
|
2089
|
+
* Prevents infinite loops in AI-to-AI conversations.
|
|
2090
|
+
*/
|
|
2091
|
+
maxSessionTurns?: number;
|
|
2092
|
+
/**
|
|
2093
|
+
* Configuration for Side A.
|
|
2094
|
+
* For `ai_human`: This is the AI side.
|
|
2095
|
+
* For `dual_ai`: This is the first AI participant.
|
|
2096
|
+
*/
|
|
2097
|
+
sideA: SideConfig;
|
|
2098
|
+
/**
|
|
2099
|
+
* Configuration for Side B.
|
|
2100
|
+
* For `ai_human`: Optional, the human side doesn't need config.
|
|
2101
|
+
* For `dual_ai`: Required, the second AI participant.
|
|
2102
|
+
*/
|
|
2103
|
+
sideB?: SideConfig;
|
|
2104
|
+
/**
|
|
2105
|
+
* Expose this agent as a tool for other prompts.
|
|
2106
|
+
* Enables agent composition and handoffs.
|
|
2107
|
+
* When true, other prompts can invoke this agent as a tool.
|
|
2108
|
+
* @default false
|
|
2109
|
+
*/
|
|
2110
|
+
exposeAsTool?: boolean;
|
|
2111
|
+
/**
|
|
2112
|
+
* Description shown when agent is used as a tool.
|
|
2113
|
+
* Required if exposeAsTool is true.
|
|
2114
|
+
* Should clearly describe what this agent does.
|
|
2115
|
+
*/
|
|
2116
|
+
toolDescription?: string;
|
|
2117
|
+
/**
|
|
2118
|
+
* Tags for categorization and filtering.
|
|
2119
|
+
* Useful for organizing agents in the UI and filtering in queries.
|
|
2120
|
+
*
|
|
2121
|
+
* @example ['customer-service', 'tier-1', 'english']
|
|
2122
|
+
*/
|
|
2123
|
+
tags?: string[];
|
|
2124
|
+
}
|
|
2125
|
+
/**
|
|
2126
|
+
* Defines an agent configuration.
|
|
2127
|
+
*
|
|
2128
|
+
* Agents orchestrate conversations between AI models, or between AI and
|
|
2129
|
+
* human users. They use prompts to configure each side of the conversation
|
|
2130
|
+
* and define stop conditions to control conversation flow.
|
|
2131
|
+
*
|
|
2132
|
+
* @template N - The agent name as a string literal type
|
|
2133
|
+
* @param options - Agent configuration options
|
|
2134
|
+
* @returns The agent definition for registration
|
|
2135
|
+
*
|
|
2136
|
+
* @example
|
|
2137
|
+
* ```typescript
|
|
2138
|
+
* // agentbuilder/agents/support_agent.ts
|
|
2139
|
+
* import { defineAgent } from '@standardagents/builder';
|
|
2140
|
+
*
|
|
2141
|
+
* export default defineAgent({
|
|
2142
|
+
* name: 'support_agent',
|
|
2143
|
+
* title: 'Customer Support Agent',
|
|
2144
|
+
* type: 'ai_human',
|
|
2145
|
+
* sideA: {
|
|
2146
|
+
* label: 'Support',
|
|
2147
|
+
* prompt: 'customer_support',
|
|
2148
|
+
* stopOnResponse: true,
|
|
2149
|
+
* endConversationTool: 'close_ticket',
|
|
2150
|
+
* },
|
|
2151
|
+
* exposeAsTool: true,
|
|
2152
|
+
* toolDescription: 'Hand off to customer support',
|
|
2153
|
+
* tags: ['support', 'tier-1'],
|
|
2154
|
+
* });
|
|
2155
|
+
* ```
|
|
2156
|
+
*
|
|
2157
|
+
* @example
|
|
2158
|
+
* ```typescript
|
|
2159
|
+
* // Dual AI agent (two AIs conversing)
|
|
2160
|
+
* export default defineAgent({
|
|
2161
|
+
* name: 'debate_agent',
|
|
2162
|
+
* title: 'AI Debate',
|
|
2163
|
+
* type: 'dual_ai',
|
|
2164
|
+
* maxSessionTurns: 10,
|
|
2165
|
+
* sideA: {
|
|
2166
|
+
* label: 'Pro',
|
|
2167
|
+
* prompt: 'debate_pro',
|
|
2168
|
+
* stopOnResponse: true,
|
|
2169
|
+
* },
|
|
2170
|
+
* sideB: {
|
|
2171
|
+
* label: 'Con',
|
|
2172
|
+
* prompt: 'debate_con',
|
|
2173
|
+
* stopOnResponse: true,
|
|
2174
|
+
* endConversationTool: 'conclude_debate',
|
|
2175
|
+
* },
|
|
2176
|
+
* });
|
|
2177
|
+
* ```
|
|
2178
|
+
*/
|
|
2179
|
+
declare function defineAgent<N extends string>(options: AgentDefinition<N>): AgentDefinition<N>;
|
|
2180
|
+
|
|
2181
|
+
/**
|
|
2182
|
+
* Generate a TypeScript file for a model definition.
|
|
2183
|
+
*/
|
|
2184
|
+
declare function generateModelFile(data: ModelDefinition): string;
|
|
2185
|
+
|
|
2186
|
+
/**
|
|
2187
|
+
* Converts JSON Schema to Zod code string.
|
|
2188
|
+
*
|
|
2189
|
+
* This is used when saving prompts from the UI - the form editor works with
|
|
2190
|
+
* JSON Schema, but we need to generate Zod code for the TypeScript file.
|
|
2191
|
+
*/
|
|
2192
|
+
interface JSONSchema {
|
|
2193
|
+
type?: string;
|
|
2194
|
+
description?: string;
|
|
2195
|
+
properties?: Record<string, JSONSchema>;
|
|
2196
|
+
required?: string[];
|
|
2197
|
+
items?: JSONSchema;
|
|
2198
|
+
enum?: (string | number | boolean)[];
|
|
2199
|
+
anyOf?: JSONSchema[];
|
|
2200
|
+
oneOf?: JSONSchema[];
|
|
2201
|
+
allOf?: JSONSchema[];
|
|
2202
|
+
const?: any;
|
|
2203
|
+
default?: any;
|
|
2204
|
+
minimum?: number;
|
|
2205
|
+
maximum?: number;
|
|
2206
|
+
minLength?: number;
|
|
2207
|
+
maxLength?: number;
|
|
2208
|
+
pattern?: string;
|
|
2209
|
+
format?: string;
|
|
2210
|
+
additionalProperties?: boolean | JSONSchema;
|
|
2211
|
+
nullable?: boolean;
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
/**
|
|
2215
|
+
* Tool configuration from UI (snake_case).
|
|
2216
|
+
*/
|
|
2217
|
+
interface ToolConfigInput {
|
|
2218
|
+
name: string;
|
|
2219
|
+
include_text_response?: boolean;
|
|
2220
|
+
include_tool_calls?: boolean;
|
|
2221
|
+
include_errors?: boolean;
|
|
2222
|
+
init_user_message_property?: string | null;
|
|
2223
|
+
}
|
|
2224
|
+
/**
|
|
2225
|
+
* Prompt part as it comes from the UI/API.
|
|
2226
|
+
* Supports both new format (type: 'text'/'include') and legacy format (type: 'string'/'prompt')
|
|
2227
|
+
*/
|
|
2228
|
+
interface PromptPartInput {
|
|
2229
|
+
type: 'text' | 'include' | 'string' | 'prompt' | 'variable';
|
|
2230
|
+
content?: string;
|
|
2231
|
+
prompt?: string;
|
|
2232
|
+
value?: string;
|
|
2233
|
+
id?: string;
|
|
2234
|
+
label?: string;
|
|
2235
|
+
schema?: any;
|
|
2236
|
+
}
|
|
2237
|
+
/**
|
|
2238
|
+
* Input data for generating a prompt file.
|
|
2239
|
+
* This can include JSON Schema for requiredSchema which will be converted to Zod.
|
|
2240
|
+
*/
|
|
2241
|
+
interface PromptFileData {
|
|
2242
|
+
name: string;
|
|
2243
|
+
toolDescription?: string;
|
|
2244
|
+
/**
|
|
2245
|
+
* Prompt content can be:
|
|
2246
|
+
* - A plain string
|
|
2247
|
+
* - A structured array of prompt parts
|
|
2248
|
+
* - A JSON string of a structured array (legacy format from UI)
|
|
2249
|
+
*/
|
|
2250
|
+
prompt?: string | PromptPartInput[];
|
|
2251
|
+
model: string;
|
|
2252
|
+
includeChat?: boolean;
|
|
2253
|
+
includePastTools?: boolean;
|
|
2254
|
+
parallelToolCalls?: boolean;
|
|
2255
|
+
toolChoice?: 'auto' | 'none' | 'required';
|
|
2256
|
+
tools?: (string | ToolConfigInput)[];
|
|
2257
|
+
handoffAgents?: string[];
|
|
2258
|
+
beforeTool?: string;
|
|
2259
|
+
afterTool?: string;
|
|
2260
|
+
reasoning?: {
|
|
2261
|
+
effort?: 'low' | 'medium' | 'high';
|
|
2262
|
+
maxTokens?: number;
|
|
2263
|
+
exclude?: boolean;
|
|
2264
|
+
include?: boolean;
|
|
2265
|
+
};
|
|
2266
|
+
/**
|
|
2267
|
+
* Required schema as JSON Schema (from the UI).
|
|
2268
|
+
* Will be converted to Zod code.
|
|
2269
|
+
*/
|
|
2270
|
+
requiredSchema?: JSONSchema;
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* Generate a TypeScript file for a prompt definition.
|
|
2274
|
+
*
|
|
2275
|
+
* @param data - Prompt data including JSON Schema for requiredSchema
|
|
2276
|
+
* @returns TypeScript code as a string
|
|
2277
|
+
*/
|
|
2278
|
+
declare function generatePromptFile(data: PromptFileData): string;
|
|
2279
|
+
|
|
2280
|
+
/**
|
|
2281
|
+
* Generate a TypeScript file for an agent definition.
|
|
2282
|
+
*/
|
|
2283
|
+
declare function generateAgentFile(data: AgentDefinition): string;
|
|
2284
|
+
|
|
2285
|
+
/**
|
|
2286
|
+
* Options for injecting a message
|
|
2287
|
+
*/
|
|
2288
|
+
interface InjectMessageOptions$1 {
|
|
2289
|
+
/** The message content */
|
|
2290
|
+
content: string;
|
|
2291
|
+
/** The message role */
|
|
2292
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
2293
|
+
/** Optional message ID. If not provided, a UUID will be generated */
|
|
2294
|
+
id?: string;
|
|
2295
|
+
/** Optional message to insert before. If not provided, message is appended to the end */
|
|
2296
|
+
beforeMessageId?: string;
|
|
2297
|
+
/** Optional tool call ID (for role="tool" only) */
|
|
2298
|
+
toolCallId?: string;
|
|
2299
|
+
/** Optional name field */
|
|
2300
|
+
name?: string;
|
|
2301
|
+
/** Whether this message is silent (hidden from LLM, visible in UI only). Default: false */
|
|
2302
|
+
silent?: boolean;
|
|
2303
|
+
/** Force message to be top-level (depth 0) even when called from sub-prompts. Default: false */
|
|
2304
|
+
forceTopLevel?: boolean;
|
|
2305
|
+
/** Force a specific side to play the next turn after injecting the message */
|
|
2306
|
+
forceTurn?: "side_a" | "side_b";
|
|
2307
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* Queue a new tool call to be executed in the current flow
|
|
2310
|
+
*
|
|
2311
|
+
* This adds a tool call to the execution queue without immediately executing it.
|
|
2312
|
+
* The tool will be executed as part of the normal flow processing.
|
|
2313
|
+
*
|
|
2314
|
+
* @param flow - The current FlowState
|
|
2315
|
+
* @param toolName - The name of the tool to call
|
|
2316
|
+
* @param args - The arguments to pass to the tool
|
|
2317
|
+
*
|
|
2318
|
+
* @example
|
|
2319
|
+
* ```typescript
|
|
2320
|
+
* import { queueTool } from '@standardagents/builder';
|
|
2321
|
+
*
|
|
2322
|
+
* queueTool(flow, "search_user", { email: "user@example.com" });
|
|
2323
|
+
* ```
|
|
2324
|
+
*/
|
|
2325
|
+
declare function queueTool(flow: FlowState, toolName: string, args?: Record<string, unknown>): void;
|
|
2326
|
+
/**
|
|
2327
|
+
* Inject a message into the thread without triggering execution
|
|
2328
|
+
*
|
|
2329
|
+
* This allows you to add messages to the conversation history programmatically.
|
|
2330
|
+
* The message is persisted to storage but does not cause the agent to execute.
|
|
2331
|
+
*
|
|
2332
|
+
* By default, messages are appended to the end of the conversation.
|
|
2333
|
+
* You can optionally insert a message before another message by providing beforeMessageId.
|
|
2334
|
+
*
|
|
2335
|
+
* @param flow - The current FlowState
|
|
2336
|
+
* @param options - Message options
|
|
2337
|
+
*
|
|
2338
|
+
* @example
|
|
2339
|
+
* ```typescript
|
|
2340
|
+
* import { injectMessage } from '@standardagents/builder';
|
|
2341
|
+
*
|
|
2342
|
+
* // Append a system message
|
|
2343
|
+
* await injectMessage(flow, {
|
|
2344
|
+
* role: "system",
|
|
2345
|
+
* content: "Context has been updated"
|
|
2346
|
+
* });
|
|
2347
|
+
*
|
|
2348
|
+
* // Insert a user message before a specific message
|
|
2349
|
+
* await injectMessage(flow, {
|
|
2350
|
+
* role: "user",
|
|
2351
|
+
* content: "Additional context",
|
|
2352
|
+
* beforeMessageId: "msg-123"
|
|
2353
|
+
* });
|
|
2354
|
+
*
|
|
2355
|
+
* // Inject a message and force a specific side to play next
|
|
2356
|
+
* await injectMessage(flow, {
|
|
2357
|
+
* role: "system",
|
|
2358
|
+
* content: "New instructions for the AI",
|
|
2359
|
+
* forceTurn: "side_a" // Force side_a to respond to this message
|
|
2360
|
+
* });
|
|
2361
|
+
* ```
|
|
2362
|
+
*/
|
|
2363
|
+
declare function injectMessage(flow: FlowState, options: InjectMessageOptions$1): Promise<Message>;
|
|
2364
|
+
/**
|
|
2365
|
+
* Get messages from the thread history
|
|
2366
|
+
*
|
|
2367
|
+
* Retrieves message history from the thread's SQLite storage.
|
|
2368
|
+
* Messages are ordered by creation time (oldest first by default).
|
|
2369
|
+
*
|
|
2370
|
+
* @param flow - The current FlowState
|
|
2371
|
+
* @param limit - Maximum number of messages to retrieve (default: 100)
|
|
2372
|
+
* @param offset - Number of messages to skip (default: 0)
|
|
2373
|
+
* @param order - Sort order: "asc" (oldest first) or "desc" (newest first) (default: "asc")
|
|
2374
|
+
* @returns Array of messages
|
|
2375
|
+
*
|
|
2376
|
+
* @example
|
|
2377
|
+
* ```typescript
|
|
2378
|
+
* import { getMessages } from '@standardagents/builder';
|
|
2379
|
+
*
|
|
2380
|
+
* // Get last 10 messages
|
|
2381
|
+
* const messages = await getMessages(flow, 10);
|
|
2382
|
+
*
|
|
2383
|
+
* // Get 10 messages, skipping the first 20
|
|
2384
|
+
* const messages = await getMessages(flow, 10, 20);
|
|
2385
|
+
*
|
|
2386
|
+
* // Get newest 10 messages
|
|
2387
|
+
* const messages = await getMessages(flow, 10, 0, "desc");
|
|
2388
|
+
* ```
|
|
2389
|
+
*/
|
|
2390
|
+
declare function getMessages(flow: FlowState, limit?: number, offset?: number, order?: "asc" | "desc"): Promise<Message[]>;
|
|
2391
|
+
/**
|
|
2392
|
+
* Reload message history from storage
|
|
2393
|
+
*
|
|
2394
|
+
* Re-loads the complete message history from the thread's SQLite storage,
|
|
2395
|
+
* applying any filter_messages hooks. This is useful when you need to refresh
|
|
2396
|
+
* the message history after making changes (e.g., injecting silent messages).
|
|
2397
|
+
*
|
|
2398
|
+
* @param flow - The current FlowState
|
|
2399
|
+
* @returns Array of messages (reloaded from storage)
|
|
2400
|
+
*
|
|
2401
|
+
* @example
|
|
2402
|
+
* ```typescript
|
|
2403
|
+
* import { injectMessage, reloadHistory } from '@standardagents/builder';
|
|
2404
|
+
*
|
|
2405
|
+
* // Reload history after injecting a silent message
|
|
2406
|
+
* await injectMessage(flow, { role: "system", content: "...", silent: true });
|
|
2407
|
+
* flow.messageHistory = await reloadHistory(flow);
|
|
2408
|
+
* ```
|
|
2409
|
+
*/
|
|
2410
|
+
declare function reloadHistory(state: FlowState): Promise<Message[]>;
|
|
2411
|
+
/**
|
|
2412
|
+
* Emit a custom event to WebSocket clients via the stream
|
|
2413
|
+
*
|
|
2414
|
+
* Sends a custom event to all connected WebSocket clients on the stream channel.
|
|
2415
|
+
* This allows backend code to push arbitrary data to the frontend
|
|
2416
|
+
* outside of the standard message events.
|
|
2417
|
+
*
|
|
2418
|
+
* @param flow - The current FlowState
|
|
2419
|
+
* @param type - The event type name (e.g., "progress", "notification")
|
|
2420
|
+
* @param data - The event payload (any serializable data)
|
|
2421
|
+
*
|
|
2422
|
+
* @example
|
|
2423
|
+
* ```typescript
|
|
2424
|
+
* import { emitThreadEvent } from '@standardagents/builder';
|
|
2425
|
+
*
|
|
2426
|
+
* // Emit a progress update
|
|
2427
|
+
* emitThreadEvent(flow, "progress", { step: 3, total: 10, message: "Processing data..." });
|
|
2428
|
+
*
|
|
2429
|
+
* // Emit a custom notification
|
|
2430
|
+
* emitThreadEvent(flow, "notification", { level: "info", message: "User authenticated" });
|
|
2431
|
+
*
|
|
2432
|
+
* // Emit metadata
|
|
2433
|
+
* emitThreadEvent(flow, "metadata", { userId: "123", sessionId: "abc" });
|
|
2434
|
+
* ```
|
|
2435
|
+
*/
|
|
2436
|
+
declare function emitThreadEvent(flow: FlowState, type: string, data: unknown): void;
|
|
2437
|
+
/**
|
|
2438
|
+
* Force a specific side to play the next turn
|
|
2439
|
+
*
|
|
2440
|
+
* This queues the specified side to play next without interrupting the current turn.
|
|
2441
|
+
* The forced turn only takes effect at the END of the current turn execution.
|
|
2442
|
+
*
|
|
2443
|
+
* If the tool queue is currently being processed (sequence.isHandling is true),
|
|
2444
|
+
* the forced turn is deferred until all queued tools complete. This allows patterns like:
|
|
2445
|
+
*
|
|
2446
|
+
* ```typescript
|
|
2447
|
+
* import { queueTool, forceTurn } from '@standardagents/builder';
|
|
2448
|
+
*
|
|
2449
|
+
* queueTool(flow, 'myTool', {});
|
|
2450
|
+
* forceTurn(flow, 'side_a');
|
|
2451
|
+
* // myTool executes first, THEN the turn switches to side_a
|
|
2452
|
+
* ```
|
|
2453
|
+
*
|
|
2454
|
+
* @param flow - The current FlowState
|
|
2455
|
+
* @param side - Which side should play next ('side_a' or 'side_b')
|
|
2456
|
+
*
|
|
2457
|
+
* @example
|
|
2458
|
+
* ```typescript
|
|
2459
|
+
* import { forceTurn } from '@standardagents/builder';
|
|
2460
|
+
*
|
|
2461
|
+
* // Force current side to continue (override stop condition)
|
|
2462
|
+
* // If side_a is playing and would stop, this forces it to play at least 1 more turn
|
|
2463
|
+
* forceTurn(flow, 'side_a');
|
|
2464
|
+
*
|
|
2465
|
+
* // Force switch to other side
|
|
2466
|
+
* // If side_a is playing, this forces side_b to play next turn
|
|
2467
|
+
* forceTurn(flow, 'side_b');
|
|
2468
|
+
*
|
|
2469
|
+
* // Force human turn in ai_human agent (execution stops and waits for user input)
|
|
2470
|
+
* if (flow.agentConfig.type === 'ai_human') {
|
|
2471
|
+
* forceTurn(flow, 'side_b'); // Stops execution, awaits user input
|
|
2472
|
+
* }
|
|
2473
|
+
* ```
|
|
2474
|
+
*/
|
|
2475
|
+
declare function forceTurn(flow: FlowState, side: 'side_a' | 'side_b'): void;
|
|
2476
|
+
/**
|
|
2477
|
+
* Thread context from defineThreadEndpoint
|
|
2478
|
+
*/
|
|
2479
|
+
interface ThreadContext {
|
|
2480
|
+
instance: {
|
|
2481
|
+
updateThreadMeta: (threadId: string, params: {
|
|
2482
|
+
agent_name?: string;
|
|
2483
|
+
user_id?: string | null;
|
|
2484
|
+
tags?: string[] | null;
|
|
2485
|
+
}) => Promise<{
|
|
2486
|
+
success: boolean;
|
|
2487
|
+
error?: string;
|
|
2488
|
+
thread?: {
|
|
2489
|
+
id: string;
|
|
2490
|
+
agent_id: string;
|
|
2491
|
+
user_id: string | null;
|
|
2492
|
+
tags: string[];
|
|
2493
|
+
created_at: number;
|
|
2494
|
+
};
|
|
2495
|
+
}>;
|
|
2496
|
+
};
|
|
2497
|
+
metadata: {
|
|
2498
|
+
id: string;
|
|
2499
|
+
agent_name: string;
|
|
2500
|
+
user_id: string | null;
|
|
2501
|
+
tags: string[] | null;
|
|
2502
|
+
created_at: number;
|
|
2503
|
+
};
|
|
2504
|
+
}
|
|
2505
|
+
/**
|
|
2506
|
+
* Update a thread's metadata in the DurableAgentBuilder registry
|
|
2507
|
+
*
|
|
2508
|
+
* This allows updating the agent_name, user_id, and tags for an existing thread.
|
|
2509
|
+
* Uses the thread instance from defineThreadEndpoint context.
|
|
2510
|
+
*
|
|
2511
|
+
* @param thread - The thread context from defineThreadEndpoint ({ instance, metadata })
|
|
2512
|
+
* @param params - The fields to update (agent_name, user_id, tags)
|
|
2513
|
+
* @returns The updated thread info, or null if update failed
|
|
2514
|
+
*
|
|
2515
|
+
* @example
|
|
2516
|
+
* ```typescript
|
|
2517
|
+
* import { defineThreadEndpoint, updateThread } from '@standardagents/builder';
|
|
2518
|
+
*
|
|
2519
|
+
* export default defineThreadEndpoint(async (req, thread) => {
|
|
2520
|
+
* // Update thread's user_id
|
|
2521
|
+
* await updateThread(thread, { user_id: 'user-123' });
|
|
2522
|
+
*
|
|
2523
|
+
* // Update thread's tags
|
|
2524
|
+
* await updateThread(thread, { tags: ['support', 'urgent'] });
|
|
2525
|
+
*
|
|
2526
|
+
* // Update multiple fields
|
|
2527
|
+
* const result = await updateThread(thread, {
|
|
2528
|
+
* agent_name: 'new-agent',
|
|
2529
|
+
* user_id: 'user-456',
|
|
2530
|
+
* tags: ['sales']
|
|
2531
|
+
* });
|
|
2532
|
+
*
|
|
2533
|
+
* return Response.json(result);
|
|
2534
|
+
* });
|
|
2535
|
+
* ```
|
|
2536
|
+
*/
|
|
2537
|
+
declare function updateThread(thread: ThreadContext, params: {
|
|
2538
|
+
agent_name?: string;
|
|
2539
|
+
user_id?: string | null;
|
|
2540
|
+
tags?: string[] | null;
|
|
2541
|
+
}): Promise<{
|
|
2542
|
+
id: string;
|
|
2543
|
+
agent_id: string;
|
|
2544
|
+
user_id: string | null;
|
|
2545
|
+
tags: string[];
|
|
2546
|
+
created_at: number;
|
|
2547
|
+
} | null>;
|
|
2548
|
+
|
|
2549
|
+
/**
|
|
2550
|
+
* Options for injecting a message
|
|
2551
|
+
*/
|
|
2552
|
+
interface InjectMessageOptions {
|
|
2553
|
+
/** The message content */
|
|
2554
|
+
content: string;
|
|
2555
|
+
/** The message role */
|
|
2556
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
2557
|
+
/** Optional message ID. If not provided, a UUID will be generated */
|
|
2558
|
+
id?: string;
|
|
2559
|
+
/** Optional message to insert before. If not provided, message is appended to the end */
|
|
2560
|
+
beforeMessageId?: string;
|
|
2561
|
+
/** Optional tool call ID (for role="tool" only) */
|
|
2562
|
+
toolCallId?: string;
|
|
2563
|
+
/** Optional name field */
|
|
2564
|
+
name?: string;
|
|
2565
|
+
/** Whether this message is silent (hidden from LLM, visible in UI only). Default: false */
|
|
2566
|
+
silent?: boolean;
|
|
2567
|
+
/** Force message to be top-level (depth 0) even when called from sub-prompts. Default: false */
|
|
2568
|
+
forceTopLevel?: boolean;
|
|
2569
|
+
/** Force a specific side to play the next turn after injecting the message */
|
|
2570
|
+
forceTurn?: "side_a" | "side_b";
|
|
2571
|
+
}
|
|
2572
|
+
/**
|
|
2573
|
+
* Options for broadcasting custom data
|
|
2574
|
+
*/
|
|
2575
|
+
interface BroadcastOptions {
|
|
2576
|
+
/** The type of the broadcast message */
|
|
2577
|
+
type: string;
|
|
2578
|
+
/** The value/payload of the broadcast message */
|
|
2579
|
+
value: unknown;
|
|
2580
|
+
}
|
|
2581
|
+
/**
|
|
2582
|
+
* FlowState SDK - Utility methods for working with FlowState
|
|
2583
|
+
*
|
|
2584
|
+
* These methods extend the FlowState object with helpful utilities for:
|
|
2585
|
+
* - Queuing tool calls
|
|
2586
|
+
* - Injecting messages
|
|
2587
|
+
* - Retrieving message history
|
|
2588
|
+
* - Broadcasting custom data via WebSocket
|
|
2589
|
+
*/
|
|
2590
|
+
declare class FlowStateSdk {
|
|
2591
|
+
/**
|
|
2592
|
+
* Queue a new tool call to be executed in the current flow
|
|
2593
|
+
*
|
|
2594
|
+
* This adds a tool call to the execution queue without immediately executing it.
|
|
2595
|
+
* The tool will be executed as part of the normal flow processing.
|
|
2596
|
+
*
|
|
2597
|
+
* @param flow - The current FlowState
|
|
2598
|
+
* @param toolName - The name of the tool to call
|
|
2599
|
+
* @param args - The arguments to pass to the tool
|
|
2600
|
+
*
|
|
2601
|
+
* @example
|
|
2602
|
+
* ```typescript
|
|
2603
|
+
* FlowStateSdk.queueTool(flow, "search_user", { email: "user@example.com" });
|
|
2604
|
+
* ```
|
|
2605
|
+
*/
|
|
2606
|
+
static queueTool(flow: FlowState, toolName: string, args?: Record<string, unknown>): void;
|
|
2607
|
+
/**
|
|
2608
|
+
* Inject a message into the thread without triggering execution
|
|
2609
|
+
*
|
|
2610
|
+
* This allows you to add messages to the conversation history programmatically.
|
|
2611
|
+
* The message is persisted to storage but does not cause the agent to execute.
|
|
2612
|
+
*
|
|
2613
|
+
* By default, messages are appended to the end of the conversation.
|
|
2614
|
+
* You can optionally insert a message before another message by providing beforeMessageId.
|
|
2615
|
+
*
|
|
2616
|
+
* @param flow - The current FlowState
|
|
2617
|
+
* @param options - Message options
|
|
2618
|
+
*
|
|
2619
|
+
* @example
|
|
2620
|
+
* ```typescript
|
|
2621
|
+
* // Append a system message
|
|
2622
|
+
* await FlowStateSdk.injectMessage(flow, {
|
|
2623
|
+
* role: "system",
|
|
2624
|
+
* content: "Context has been updated"
|
|
2625
|
+
* });
|
|
2626
|
+
*
|
|
2627
|
+
* // Insert a user message before a specific message
|
|
2628
|
+
* await FlowStateSdk.injectMessage(flow, {
|
|
2629
|
+
* role: "user",
|
|
2630
|
+
* content: "Additional context",
|
|
2631
|
+
* beforeMessageId: "msg-123"
|
|
2632
|
+
* });
|
|
2633
|
+
*
|
|
2634
|
+
* // Inject a message and force a specific side to play next
|
|
2635
|
+
* await FlowStateSdk.injectMessage(flow, {
|
|
2636
|
+
* role: "system",
|
|
2637
|
+
* content: "New instructions for the AI",
|
|
2638
|
+
* forceTurn: "side_a" // Force side_a to respond to this message
|
|
2639
|
+
* });
|
|
2640
|
+
* ```
|
|
2641
|
+
*/
|
|
2642
|
+
static injectMessage(flow: FlowState, options: InjectMessageOptions): Promise<Message>;
|
|
2643
|
+
/**
|
|
2644
|
+
* Get messages from the thread history
|
|
2645
|
+
*
|
|
2646
|
+
* Retrieves message history from the thread's SQLite storage.
|
|
2647
|
+
* Messages are ordered by creation time (oldest first by default).
|
|
2648
|
+
*
|
|
2649
|
+
* @param flow - The current FlowState
|
|
2650
|
+
* @param limit - Maximum number of messages to retrieve (default: 100)
|
|
2651
|
+
* @param offset - Number of messages to skip (default: 0)
|
|
2652
|
+
* @param order - Sort order: "asc" (oldest first) or "desc" (newest first) (default: "asc")
|
|
2653
|
+
* @returns Array of messages
|
|
2654
|
+
*
|
|
2655
|
+
* @example
|
|
2656
|
+
* ```typescript
|
|
2657
|
+
* // Get last 10 messages
|
|
2658
|
+
* const messages = await FlowStateSdk.getMessages(flow, 10);
|
|
2659
|
+
*
|
|
2660
|
+
* // Get 10 messages, skipping the first 20
|
|
2661
|
+
* const messages = await FlowStateSdk.getMessages(flow, 10, 20);
|
|
2662
|
+
*
|
|
2663
|
+
* // Get newest 10 messages
|
|
2664
|
+
* const messages = await FlowStateSdk.getMessages(flow, 10, 0, "desc");
|
|
2665
|
+
* ```
|
|
2666
|
+
*/
|
|
2667
|
+
static getMessages(flow: FlowState, limit?: number, offset?: number, order?: "asc" | "desc"): Promise<Message[]>;
|
|
2668
|
+
/**
|
|
2669
|
+
* Reload message history from storage
|
|
2670
|
+
*
|
|
2671
|
+
* Re-loads the complete message history from the thread's SQLite storage,
|
|
2672
|
+
* applying any filter_messages hooks. This is useful when you need to refresh
|
|
2673
|
+
* the message history after making changes (e.g., injecting silent messages).
|
|
2674
|
+
*
|
|
2675
|
+
* @param flow - The current FlowState
|
|
2676
|
+
* @returns Array of messages (reloaded from storage)
|
|
2677
|
+
*
|
|
2678
|
+
* @example
|
|
2679
|
+
* ```typescript
|
|
2680
|
+
* // Reload history after injecting a silent message
|
|
2681
|
+
* await FlowStateSdk.injectMessage(flow, { role: "system", content: "...", silent: true });
|
|
2682
|
+
* flow.messageHistory = await FlowStateSdk.reloadHistory(flow);
|
|
2683
|
+
* ```
|
|
2684
|
+
*/
|
|
2685
|
+
static reloadHistory(state: FlowState): Promise<Message[]>;
|
|
2686
|
+
/**
|
|
2687
|
+
* Broadcast custom data to WebSocket clients
|
|
2688
|
+
*
|
|
2689
|
+
* Sends a custom message to all connected WebSocket clients.
|
|
2690
|
+
* This allows backend code to push arbitrary data to the frontend
|
|
2691
|
+
* outside of the standard telemetry events.
|
|
2692
|
+
*
|
|
2693
|
+
* The message is sent with the structure: { type: string, value: unknown }
|
|
2694
|
+
*
|
|
2695
|
+
* @param flow - The current FlowState
|
|
2696
|
+
* @param options - Broadcast options
|
|
2697
|
+
*
|
|
2698
|
+
* @example
|
|
2699
|
+
* ```typescript
|
|
2700
|
+
* // Broadcast a progress update
|
|
2701
|
+
* FlowStateSdk.broadcast(flow, {
|
|
2702
|
+
* type: "progress",
|
|
2703
|
+
* value: { step: 3, total: 10, message: "Processing data..." }
|
|
2704
|
+
* });
|
|
2705
|
+
*
|
|
2706
|
+
* // Broadcast a custom notification
|
|
2707
|
+
* FlowStateSdk.broadcast(flow, {
|
|
2708
|
+
* type: "notification",
|
|
2709
|
+
* value: { level: "info", message: "User authenticated successfully" }
|
|
2710
|
+
* });
|
|
2711
|
+
*
|
|
2712
|
+
* // Broadcast metadata
|
|
2713
|
+
* FlowStateSdk.broadcast(flow, {
|
|
2714
|
+
* type: "metadata",
|
|
2715
|
+
* value: { userId: "123", sessionId: "abc", timestamp: Date.now() }
|
|
2716
|
+
* });
|
|
2717
|
+
* ```
|
|
2718
|
+
*/
|
|
2719
|
+
static broadcast(flow: FlowState, options: BroadcastOptions): void;
|
|
2720
|
+
/**
|
|
2721
|
+
* Force a specific side to play the next turn
|
|
2722
|
+
*
|
|
2723
|
+
* This queues the specified side to play next without interrupting the current turn.
|
|
2724
|
+
* The forced turn only takes effect at the END of the current turn execution.
|
|
2725
|
+
*
|
|
2726
|
+
* If the tool queue is currently being processed (sequence.isHandling is true),
|
|
2727
|
+
* the forced turn is deferred until all queued tools complete. This allows patterns like:
|
|
2728
|
+
*
|
|
2729
|
+
* ```typescript
|
|
2730
|
+
* FlowStateSdk.queueTool(flow, 'myTool', {});
|
|
2731
|
+
* FlowStateSdk.forceTurn(flow, 'side_a');
|
|
2732
|
+
* // myTool executes first, THEN the turn switches to side_a
|
|
2733
|
+
* ```
|
|
2734
|
+
*
|
|
2735
|
+
* @param flow - The current FlowState
|
|
2736
|
+
* @param side - Which side should play next ('side_a' or 'side_b')
|
|
2737
|
+
*
|
|
2738
|
+
* @example
|
|
2739
|
+
* ```typescript
|
|
2740
|
+
* // Force current side to continue (override stop condition)
|
|
2741
|
+
* // If side_a is playing and would stop, this forces it to play at least 1 more turn
|
|
2742
|
+
* FlowStateSdk.forceTurn(flow, 'side_a');
|
|
2743
|
+
*
|
|
2744
|
+
* // Force switch to other side
|
|
2745
|
+
* // If side_a is playing, this forces side_b to play next turn
|
|
2746
|
+
* FlowStateSdk.forceTurn(flow, 'side_b');
|
|
2747
|
+
*
|
|
2748
|
+
* // Force human turn in ai_human agent (execution stops and waits for user input)
|
|
2749
|
+
* if (flow.agentConfig.type === 'ai_human') {
|
|
2750
|
+
* FlowStateSdk.forceTurn(flow, 'side_b'); // Stops execution, awaits user input
|
|
2751
|
+
* }
|
|
2752
|
+
* ```
|
|
2753
|
+
*/
|
|
2754
|
+
static forceTurn(flow: FlowState, side: 'side_a' | 'side_b'): void;
|
|
2755
|
+
}
|
|
2756
|
+
/**
|
|
2757
|
+
* Convenience methods added to FlowState (optional - can be used via static methods above)
|
|
2758
|
+
*
|
|
2759
|
+
* These are helper methods that can be added to FlowState instances for convenience.
|
|
2760
|
+
* They delegate to the static methods above.
|
|
2761
|
+
*/
|
|
2762
|
+
interface FlowStateWithSdk extends FlowState {
|
|
2763
|
+
queueTool: (toolName: string, args?: Record<string, unknown>) => void;
|
|
2764
|
+
injectMessage: (options: InjectMessageOptions) => Promise<Message>;
|
|
2765
|
+
getMessages: (limit?: number, offset?: number, order?: "asc" | "desc") => Promise<Message[]>;
|
|
2766
|
+
reloadHistory: () => Promise<Message[]>;
|
|
2767
|
+
broadcast: (options: BroadcastOptions) => void;
|
|
2768
|
+
forceTurn: (side: 'side_a' | 'side_b') => void;
|
|
2769
|
+
}
|
|
2770
|
+
/**
|
|
2771
|
+
* Enhance a FlowState object with SDK methods
|
|
2772
|
+
*
|
|
2773
|
+
* This adds convenience methods to a FlowState instance that delegate to
|
|
2774
|
+
* the static FlowStateSdk methods.
|
|
2775
|
+
*
|
|
2776
|
+
* @param flow - The FlowState to enhance
|
|
2777
|
+
* @returns The enhanced FlowState with SDK methods
|
|
2778
|
+
*
|
|
2779
|
+
* @example
|
|
2780
|
+
* ```typescript
|
|
2781
|
+
* const enhancedFlow = enhanceFlowState(flow);
|
|
2782
|
+
*
|
|
2783
|
+
* // Now you can use methods directly on the flow object
|
|
2784
|
+
* enhancedFlow.queueTool("search_user", { email: "user@example.com" });
|
|
2785
|
+
* await enhancedFlow.injectMessage({ role: "system", content: "Context updated" });
|
|
2786
|
+
* const messages = await enhancedFlow.getMessages(10);
|
|
2787
|
+
* flow.messageHistory = await enhancedFlow.reloadHistory();
|
|
2788
|
+
* enhancedFlow.broadcast({ type: "progress", value: { step: 1 } });
|
|
2789
|
+
* enhancedFlow.forceTurn('side_b'); // Force side_b to play next turn
|
|
2790
|
+
* ```
|
|
2791
|
+
*/
|
|
2792
|
+
declare function enhanceFlowState(flow: FlowState): FlowStateWithSdk;
|
|
2793
|
+
|
|
2794
|
+
/**
|
|
2795
|
+
* Types for GitHub REST API integration.
|
|
2796
|
+
*/
|
|
2797
|
+
interface GitHubConfig {
|
|
2798
|
+
token: string;
|
|
2799
|
+
owner: string;
|
|
2800
|
+
repo: string;
|
|
2801
|
+
branch: string;
|
|
2802
|
+
}
|
|
2803
|
+
interface GitHubFileChange {
|
|
2804
|
+
path: string;
|
|
2805
|
+
content: string;
|
|
2806
|
+
mode?: '100644' | '100755';
|
|
2807
|
+
}
|
|
2808
|
+
interface GitHubCommitResult {
|
|
2809
|
+
sha: string;
|
|
2810
|
+
url: string;
|
|
2811
|
+
message: string;
|
|
2812
|
+
}
|
|
2813
|
+
interface GitHubRef {
|
|
2814
|
+
ref: string;
|
|
2815
|
+
node_id: string;
|
|
2816
|
+
url: string;
|
|
2817
|
+
object: {
|
|
2818
|
+
sha: string;
|
|
2819
|
+
type: string;
|
|
2820
|
+
url: string;
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
interface GitHubTree {
|
|
2824
|
+
sha: string;
|
|
2825
|
+
url: string;
|
|
2826
|
+
truncated: boolean;
|
|
2827
|
+
tree: Array<{
|
|
2828
|
+
path: string;
|
|
2829
|
+
mode: string;
|
|
2830
|
+
type: string;
|
|
2831
|
+
sha: string;
|
|
2832
|
+
size?: number;
|
|
2833
|
+
url: string;
|
|
2834
|
+
}>;
|
|
2835
|
+
}
|
|
2836
|
+
interface GitHubBlob {
|
|
2837
|
+
sha: string;
|
|
2838
|
+
url: string;
|
|
2839
|
+
}
|
|
2840
|
+
interface GitHubCommit {
|
|
2841
|
+
sha: string;
|
|
2842
|
+
url: string;
|
|
2843
|
+
html_url: string;
|
|
2844
|
+
author: {
|
|
2845
|
+
name: string;
|
|
2846
|
+
email: string;
|
|
2847
|
+
date: string;
|
|
2848
|
+
};
|
|
2849
|
+
committer: {
|
|
2850
|
+
name: string;
|
|
2851
|
+
email: string;
|
|
2852
|
+
date: string;
|
|
2853
|
+
};
|
|
2854
|
+
message: string;
|
|
2855
|
+
tree: {
|
|
2856
|
+
sha: string;
|
|
2857
|
+
url: string;
|
|
2858
|
+
};
|
|
2859
|
+
parents: Array<{
|
|
2860
|
+
sha: string;
|
|
2861
|
+
url: string;
|
|
2862
|
+
}>;
|
|
2863
|
+
}
|
|
2864
|
+
|
|
2865
|
+
/**
|
|
2866
|
+
* GitHub REST API client for committing file changes.
|
|
2867
|
+
*
|
|
2868
|
+
* This client is used in production to commit configuration changes
|
|
2869
|
+
* (prompts, models, agents) to the repository via GitHub's REST API.
|
|
2870
|
+
*
|
|
2871
|
+
* The flow for creating a commit:
|
|
2872
|
+
* 1. Get the current branch ref to find HEAD commit SHA
|
|
2873
|
+
* 2. Get the tree SHA from the HEAD commit
|
|
2874
|
+
* 3. Create blobs for each file to be added/modified
|
|
2875
|
+
* 4. Create a new tree with the file changes
|
|
2876
|
+
* 5. Create a commit pointing to the new tree
|
|
2877
|
+
* 6. Update the branch ref to point to the new commit
|
|
2878
|
+
*/
|
|
2879
|
+
|
|
2880
|
+
declare class GitHubClient {
|
|
2881
|
+
private config;
|
|
2882
|
+
constructor(config: GitHubConfig);
|
|
2883
|
+
/**
|
|
2884
|
+
* Create a GitHubClient from environment variables.
|
|
2885
|
+
* Returns null if required env vars are missing.
|
|
2886
|
+
*/
|
|
2887
|
+
static fromEnv(env: {
|
|
2888
|
+
GITHUB_TOKEN?: string;
|
|
2889
|
+
GITHUB_REPO?: string;
|
|
2890
|
+
GITHUB_BRANCH?: string;
|
|
2891
|
+
}): GitHubClient | null;
|
|
2892
|
+
/**
|
|
2893
|
+
* Check if GitHub integration is properly configured.
|
|
2894
|
+
*/
|
|
2895
|
+
isConfigured(): boolean;
|
|
2896
|
+
/**
|
|
2897
|
+
* Make an authenticated request to GitHub API.
|
|
2898
|
+
*/
|
|
2899
|
+
private request;
|
|
2900
|
+
/**
|
|
2901
|
+
* Get the current branch reference.
|
|
2902
|
+
*/
|
|
2903
|
+
getBranchRef(): Promise<GitHubRef>;
|
|
2904
|
+
/**
|
|
2905
|
+
* Get a commit by SHA.
|
|
2906
|
+
*/
|
|
2907
|
+
getCommit(sha: string): Promise<GitHubCommit>;
|
|
2908
|
+
/**
|
|
2909
|
+
* Get a tree by SHA.
|
|
2910
|
+
*/
|
|
2911
|
+
getTree(sha: string): Promise<GitHubTree>;
|
|
2912
|
+
/**
|
|
2913
|
+
* Create a blob (file content).
|
|
2914
|
+
*/
|
|
2915
|
+
createBlob(content: string): Promise<GitHubBlob>;
|
|
2916
|
+
/**
|
|
2917
|
+
* Create a tree with file changes.
|
|
2918
|
+
*/
|
|
2919
|
+
createTree(baseTreeSha: string, files: Array<{
|
|
2920
|
+
path: string;
|
|
2921
|
+
sha: string;
|
|
2922
|
+
mode: string;
|
|
2923
|
+
}>): Promise<GitHubTree>;
|
|
2924
|
+
/**
|
|
2925
|
+
* Create a commit.
|
|
2926
|
+
*/
|
|
2927
|
+
createCommit(message: string, treeSha: string, parentSha: string): Promise<GitHubCommit>;
|
|
2928
|
+
/**
|
|
2929
|
+
* Update a branch reference to point to a new commit.
|
|
2930
|
+
*/
|
|
2931
|
+
updateRef(sha: string): Promise<GitHubRef>;
|
|
2932
|
+
/**
|
|
2933
|
+
* Commit multiple file changes atomically.
|
|
2934
|
+
*
|
|
2935
|
+
* @param message - Commit message
|
|
2936
|
+
* @param files - Array of files to add/modify
|
|
2937
|
+
* @returns The commit result with SHA
|
|
2938
|
+
*/
|
|
2939
|
+
commitFiles(message: string, files: GitHubFileChange[]): Promise<GitHubCommitResult>;
|
|
2940
|
+
/**
|
|
2941
|
+
* Delete files from the repository.
|
|
2942
|
+
*
|
|
2943
|
+
* @param message - Commit message
|
|
2944
|
+
* @param paths - Array of file paths to delete
|
|
2945
|
+
* @returns The commit result with SHA
|
|
2946
|
+
*/
|
|
2947
|
+
deleteFiles(message: string, paths: string[]): Promise<GitHubCommitResult>;
|
|
2948
|
+
/**
|
|
2949
|
+
* Get the current HEAD commit SHA.
|
|
2950
|
+
*/
|
|
2951
|
+
getHeadSha(): Promise<string>;
|
|
2952
|
+
}
|
|
2953
|
+
/**
|
|
2954
|
+
* Custom error for GitHub API errors.
|
|
2955
|
+
*/
|
|
2956
|
+
declare class GitHubApiError extends Error {
|
|
2957
|
+
status: number;
|
|
2958
|
+
details: unknown;
|
|
2959
|
+
constructor(message: string, status: number, details?: unknown);
|
|
2960
|
+
}
|
|
2961
|
+
|
|
2962
|
+
export { type Agent, type AgentBuilderEnv, type AgentDefinition, type AgentType, type AuthContext, type AuthUser, type BroadcastOptions, type Controller, type ControllerContext, DurableAgentBuilder, DurableThread, type FlowResult, type FlowState, FlowStateSdk, type FlowStateWithSdk, GitHubApiError, GitHubClient, type GitHubCommitResult, type GitHubConfig, type GitHubFileChange, type HookSignatures, type InjectMessageOptions$1 as InjectMessageOptions, type LLMResponse, type Message, type ModelDefinition, type ModelProvider, type PromptContent, type PromptDefinition, type PromptIncludePart, type PromptInput, type PromptPart, type PromptTextPart, type Provider, type ReasoningConfig, type RequestContext, type SideConfig, type StructuredPrompt, type StructuredToolReturn, type TelemetryEvent, type ThreadEndpointContext, type ThreadEnv, type ThreadInstance, type ThreadMetadata, type ThreadRegistryEntry, type Tool, type ToolArgs, type ToolArgsNode, type ToolArgsRawShape, type ToolCall, type ToolConfig, type ToolResult, type UpdateThreadParams, type User, authenticate, defineAgent, defineController, defineHook, defineModel, definePrompt, defineThreadEndpoint, defineTool, emitThreadEvent, enhanceFlowState, forceTurn, generateAgentFile, generateModelFile, generatePromptFile, getMessages, injectMessage, queueTool, reloadHistory, requireAdmin, requireAuth, updateThread };
|