goatchain 0.0.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/README.md +529 -0
- package/cli/args.mjs +113 -0
- package/cli/clack.mjs +111 -0
- package/cli/clipboard.mjs +320 -0
- package/cli/files.mjs +247 -0
- package/cli/index.mjs +299 -0
- package/cli/itermPaste.mjs +147 -0
- package/cli/persist.mjs +205 -0
- package/cli/repl.mjs +3141 -0
- package/cli/sdk.mjs +341 -0
- package/cli/sessionTransfer.mjs +118 -0
- package/cli/turn.mjs +751 -0
- package/cli/ui.mjs +138 -0
- package/cli.mjs +5 -0
- package/dist/index.cjs +4860 -0
- package/dist/index.d.cts +3479 -0
- package/dist/index.d.ts +3479 -0
- package/dist/index.js +4795 -0
- package/package.json +68 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,3479 @@
|
|
|
1
|
+
import { CallToolResult, ContentBlock, ImageContent, TextContent, Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/types/common.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Message content can be a single block or array of blocks
|
|
7
|
+
*/
|
|
8
|
+
type MessageContent = string | ContentBlock | ContentBlock[];
|
|
9
|
+
/**
|
|
10
|
+
* JSON Schema property definition for nested properties
|
|
11
|
+
*/
|
|
12
|
+
interface JSONSchemaProperty {
|
|
13
|
+
type?: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object' | 'null';
|
|
14
|
+
description?: string;
|
|
15
|
+
enum?: unknown[];
|
|
16
|
+
items?: JSONSchemaProperty;
|
|
17
|
+
properties?: Record<string, JSONSchemaProperty>;
|
|
18
|
+
required?: string[];
|
|
19
|
+
default?: unknown;
|
|
20
|
+
/** Allow additional JSON Schema properties */
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* MCP-compatible Tool input schema.
|
|
25
|
+
* Per MCP spec, tool inputSchema must have type "object".
|
|
26
|
+
*/
|
|
27
|
+
interface ToolInputSchema {
|
|
28
|
+
type: 'object';
|
|
29
|
+
properties?: Record<string, JSONSchemaProperty>;
|
|
30
|
+
required?: string[];
|
|
31
|
+
/** Allow additional JSON Schema properties */
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Tool call request from LLM
|
|
36
|
+
*/
|
|
37
|
+
interface ToolCall {
|
|
38
|
+
id: string;
|
|
39
|
+
type: 'function';
|
|
40
|
+
function: {
|
|
41
|
+
name: string;
|
|
42
|
+
arguments: string | Record<string, unknown>;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Token usage statistics
|
|
47
|
+
*/
|
|
48
|
+
interface Usage {
|
|
49
|
+
promptTokens: number;
|
|
50
|
+
completionTokens: number;
|
|
51
|
+
totalTokens: number;
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/model/types.d.ts
|
|
55
|
+
type ProviderId = string;
|
|
56
|
+
type ModelId = string;
|
|
57
|
+
/**
|
|
58
|
+
* Options for chat completion requests
|
|
59
|
+
*/
|
|
60
|
+
interface ChatOptions {
|
|
61
|
+
/**
|
|
62
|
+
* Temperature for response randomness (0-2)
|
|
63
|
+
*/
|
|
64
|
+
temperature?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Maximum tokens to generate
|
|
67
|
+
*/
|
|
68
|
+
maxTokens?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Stop sequences
|
|
71
|
+
*/
|
|
72
|
+
stop?: string[];
|
|
73
|
+
/**
|
|
74
|
+
* Tools available to the model
|
|
75
|
+
*/
|
|
76
|
+
tools?: OpenAITool[];
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* OpenAI-compatible tool format
|
|
80
|
+
*/
|
|
81
|
+
interface OpenAITool {
|
|
82
|
+
type: 'function';
|
|
83
|
+
function: {
|
|
84
|
+
name: string;
|
|
85
|
+
description: string;
|
|
86
|
+
parameters: Record<string, unknown>;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Non-streaming chat response
|
|
91
|
+
*/
|
|
92
|
+
interface ChatResponse {
|
|
93
|
+
message: Message;
|
|
94
|
+
usage?: {
|
|
95
|
+
promptTokens: number;
|
|
96
|
+
completionTokens: number;
|
|
97
|
+
totalTokens: number;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Stream event from model
|
|
102
|
+
*/
|
|
103
|
+
type StreamEvent = {
|
|
104
|
+
type: 'text_delta';
|
|
105
|
+
delta: string;
|
|
106
|
+
} | {
|
|
107
|
+
type: 'tool_call';
|
|
108
|
+
toolCall: ToolCall;
|
|
109
|
+
} | {
|
|
110
|
+
type: 'thinking_start';
|
|
111
|
+
} | {
|
|
112
|
+
type: 'thinking_delta';
|
|
113
|
+
content: string;
|
|
114
|
+
} | {
|
|
115
|
+
type: 'thinking_end';
|
|
116
|
+
} | {
|
|
117
|
+
type: 'usage';
|
|
118
|
+
usage: {
|
|
119
|
+
promptTokens: number;
|
|
120
|
+
completionTokens: number;
|
|
121
|
+
totalTokens: number;
|
|
122
|
+
};
|
|
123
|
+
} | {
|
|
124
|
+
type: 'done';
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Unified stream interface that supports both legacy and new API styles.
|
|
128
|
+
*/
|
|
129
|
+
interface ModelStreamFn {
|
|
130
|
+
/**
|
|
131
|
+
* Legacy stream method for BaseModel compatibility.
|
|
132
|
+
*/
|
|
133
|
+
(messages: Message[], options?: ChatOptions): AsyncIterable<StreamEvent | ModelStreamEvent>;
|
|
134
|
+
/**
|
|
135
|
+
* New stream method for ModelContract compatibility.
|
|
136
|
+
*/
|
|
137
|
+
(request: Omit<ModelRequest, 'model'> & {
|
|
138
|
+
model?: ModelRef;
|
|
139
|
+
}): AsyncIterable<StreamEvent | ModelStreamEvent>;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* BaseModel-compatible model client interface.
|
|
143
|
+
*
|
|
144
|
+
* This matches the shape expected by `BaseModel`/Agent.
|
|
145
|
+
* It supports both legacy API (messages array) and new ModelContract API (request object).
|
|
146
|
+
*/
|
|
147
|
+
interface ModelClient {
|
|
148
|
+
readonly modelId: string;
|
|
149
|
+
/**
|
|
150
|
+
* Set a new default model ID for subsequent requests.
|
|
151
|
+
*
|
|
152
|
+
* This allows switching the model without recreating the entire client.
|
|
153
|
+
* Only works with models from the same provider.
|
|
154
|
+
*
|
|
155
|
+
* @param modelId - New model ID to use
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```ts
|
|
159
|
+
* model.setModelId('gpt-4')
|
|
160
|
+
* // All subsequent requests will use gpt-4
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
setModelId?: (modelId: string) => void;
|
|
164
|
+
/**
|
|
165
|
+
* Legacy invoke method for BaseModel compatibility.
|
|
166
|
+
* Takes Message array and returns ChatResponse.
|
|
167
|
+
*/
|
|
168
|
+
invoke: (messages: Message[], options?: ChatOptions) => Promise<ChatResponse>;
|
|
169
|
+
/**
|
|
170
|
+
* Stream method supporting both legacy and new API styles.
|
|
171
|
+
*/
|
|
172
|
+
stream: ModelStreamFn;
|
|
173
|
+
/**
|
|
174
|
+
* Run method from ModelContractClient for new API style.
|
|
175
|
+
* Optional for legacy implementations.
|
|
176
|
+
*/
|
|
177
|
+
run?: (request: Omit<ModelRequest, 'model'> & {
|
|
178
|
+
model?: ModelRef;
|
|
179
|
+
}) => Promise<ModelRunResult>;
|
|
180
|
+
}
|
|
181
|
+
type FeatureId = `${string}@${number}`;
|
|
182
|
+
interface FeatureRequest {
|
|
183
|
+
required?: boolean;
|
|
184
|
+
config?: Record<string, unknown>;
|
|
185
|
+
}
|
|
186
|
+
type FeatureRequests = Record<FeatureId, FeatureRequest>;
|
|
187
|
+
interface FeatureGrant {
|
|
188
|
+
granted: boolean;
|
|
189
|
+
downgraded?: boolean;
|
|
190
|
+
reason?: string;
|
|
191
|
+
effectiveConfig?: Record<string, unknown>;
|
|
192
|
+
}
|
|
193
|
+
type FeatureGrants = Record<FeatureId, FeatureGrant>;
|
|
194
|
+
interface ModelRef {
|
|
195
|
+
provider: ProviderId;
|
|
196
|
+
modelId: ModelId;
|
|
197
|
+
}
|
|
198
|
+
interface CoreCapabilities {
|
|
199
|
+
streaming: boolean;
|
|
200
|
+
toolCalling: boolean;
|
|
201
|
+
vision: boolean;
|
|
202
|
+
audioIn: boolean;
|
|
203
|
+
audioOut: boolean;
|
|
204
|
+
jsonSchema: {
|
|
205
|
+
strict: boolean;
|
|
206
|
+
};
|
|
207
|
+
maxContextTokens: number;
|
|
208
|
+
maxOutputTokens?: number;
|
|
209
|
+
attachments: {
|
|
210
|
+
image: boolean;
|
|
211
|
+
file: boolean;
|
|
212
|
+
video: boolean;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
type ModelStopReason = 'final' | 'tool_call' | 'length' | 'error' | 'cancelled';
|
|
216
|
+
type ModelDeltaChunk = {
|
|
217
|
+
kind: 'text';
|
|
218
|
+
text: string;
|
|
219
|
+
} | {
|
|
220
|
+
kind: 'tool_call_delta';
|
|
221
|
+
callId: string;
|
|
222
|
+
toolId?: string;
|
|
223
|
+
argsTextDelta?: string;
|
|
224
|
+
} | {
|
|
225
|
+
kind: 'thinking_start';
|
|
226
|
+
} | {
|
|
227
|
+
kind: 'thinking_delta';
|
|
228
|
+
text: string;
|
|
229
|
+
} | {
|
|
230
|
+
kind: 'thinking_end';
|
|
231
|
+
} | {
|
|
232
|
+
kind: 'citation_delta';
|
|
233
|
+
data: unknown;
|
|
234
|
+
} | {
|
|
235
|
+
kind: 'annotation';
|
|
236
|
+
name: string;
|
|
237
|
+
data: unknown;
|
|
238
|
+
};
|
|
239
|
+
type ModelStreamEvent = {
|
|
240
|
+
type: 'response_start';
|
|
241
|
+
requestId: string;
|
|
242
|
+
model: ModelRef;
|
|
243
|
+
featureGrants: FeatureGrants;
|
|
244
|
+
} | {
|
|
245
|
+
type: 'delta';
|
|
246
|
+
requestId: string;
|
|
247
|
+
chunk: ModelDeltaChunk;
|
|
248
|
+
} | {
|
|
249
|
+
type: 'response_end';
|
|
250
|
+
requestId: string;
|
|
251
|
+
stopReason: ModelStopReason;
|
|
252
|
+
usage?: unknown;
|
|
253
|
+
} | {
|
|
254
|
+
type: 'error';
|
|
255
|
+
requestId: string;
|
|
256
|
+
error: {
|
|
257
|
+
code: string;
|
|
258
|
+
message: string;
|
|
259
|
+
retryable?: boolean;
|
|
260
|
+
};
|
|
261
|
+
};
|
|
262
|
+
interface ModelRequest {
|
|
263
|
+
requestId?: string;
|
|
264
|
+
model: ModelRef;
|
|
265
|
+
/**
|
|
266
|
+
* Simple text input (used when messages is not provided).
|
|
267
|
+
* Either `input` or `messages` should be provided.
|
|
268
|
+
*/
|
|
269
|
+
input?: string;
|
|
270
|
+
instructions?: string;
|
|
271
|
+
/**
|
|
272
|
+
* Opaque metadata for tracing/auditing across systems.
|
|
273
|
+
* Keep it JSON-serializable; providers may impose size/shape limits.
|
|
274
|
+
*/
|
|
275
|
+
metadata?: Record<string, string | number | boolean | null>;
|
|
276
|
+
/**
|
|
277
|
+
* Model "reasoning" / thinking controls (best-effort; provider-specific).
|
|
278
|
+
* For OpenAI Responses API this is passed through as `reasoning`.
|
|
279
|
+
*/
|
|
280
|
+
reasoning?: Record<string, unknown>;
|
|
281
|
+
/**
|
|
282
|
+
* Messages in OpenAI format (for multi-turn conversations).
|
|
283
|
+
* If provided, this takes precedence over `input` for building the conversation.
|
|
284
|
+
*/
|
|
285
|
+
messages?: Message[];
|
|
286
|
+
/**
|
|
287
|
+
* Tools available to the model in OpenAI format.
|
|
288
|
+
*/
|
|
289
|
+
tools?: OpenAITool[];
|
|
290
|
+
maxOutputTokens?: number;
|
|
291
|
+
temperature?: number;
|
|
292
|
+
topP?: number;
|
|
293
|
+
presencePenalty?: number;
|
|
294
|
+
frequencyPenalty?: number;
|
|
295
|
+
seed?: number;
|
|
296
|
+
features?: FeatureRequests;
|
|
297
|
+
signal?: AbortSignal;
|
|
298
|
+
stream?: boolean;
|
|
299
|
+
timeoutMs?: number;
|
|
300
|
+
}
|
|
301
|
+
interface ModelRunResult {
|
|
302
|
+
requestId: string;
|
|
303
|
+
model: ModelRef;
|
|
304
|
+
text: string;
|
|
305
|
+
stopReason: ModelStopReason;
|
|
306
|
+
usage?: unknown;
|
|
307
|
+
featureGrants: FeatureGrants;
|
|
308
|
+
}
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/tool/types.d.ts
|
|
311
|
+
/**
|
|
312
|
+
* Risk level classification for tools.
|
|
313
|
+
*
|
|
314
|
+
* Used to determine whether user approval is required before execution:
|
|
315
|
+
* - 'safe': No risk, read-only operations (e.g., Read, Glob, Grep)
|
|
316
|
+
* - 'low': Low risk, minimal side effects (e.g., WebSearch, TodoWrite)
|
|
317
|
+
* - 'medium': Medium risk, reversible changes
|
|
318
|
+
* - 'high': High risk, file modifications (e.g., Write, Edit)
|
|
319
|
+
* - 'critical': Critical risk, arbitrary command execution (e.g., Bash)
|
|
320
|
+
*/
|
|
321
|
+
type RiskLevel = 'safe' | 'low' | 'medium' | 'high' | 'critical';
|
|
322
|
+
/**
|
|
323
|
+
* Request payload for tool approval callback.
|
|
324
|
+
*/
|
|
325
|
+
interface ToolApprovalRequest {
|
|
326
|
+
/** Name of the tool requesting approval */
|
|
327
|
+
toolName: string;
|
|
328
|
+
/** The original tool call from the LLM */
|
|
329
|
+
toolCall: ToolCall;
|
|
330
|
+
/** Risk level of the tool */
|
|
331
|
+
riskLevel: RiskLevel;
|
|
332
|
+
/** Parsed arguments for the tool */
|
|
333
|
+
args: Record<string, unknown>;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Result of tool approval callback.
|
|
337
|
+
*/
|
|
338
|
+
interface ToolApprovalResult {
|
|
339
|
+
/** Whether the tool execution is approved */
|
|
340
|
+
approved: boolean;
|
|
341
|
+
/** Optional reason for rejection (shown in tool result) */
|
|
342
|
+
reason?: string;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Indicates tool approval is pending and execution should pause.
|
|
346
|
+
*
|
|
347
|
+
* Useful for UIs/servers that cannot keep a tool callback hanging while waiting
|
|
348
|
+
* for an end-user decision (e.g. HTTP request/response).
|
|
349
|
+
*/
|
|
350
|
+
interface ToolApprovalPending {
|
|
351
|
+
pending: true;
|
|
352
|
+
/**
|
|
353
|
+
* Optional hint shown to the user (or logged) while waiting.
|
|
354
|
+
*/
|
|
355
|
+
reason?: string;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Result of tool approval callback.
|
|
359
|
+
*
|
|
360
|
+
* Backward compatible: existing callbacks can keep returning ToolApprovalResult.
|
|
361
|
+
*/
|
|
362
|
+
type ToolApprovalOutcome = ToolApprovalResult | ToolApprovalPending;
|
|
363
|
+
type ToolApprovalStrategy = 'high_risk' | 'all';
|
|
364
|
+
/**
|
|
365
|
+
* Configuration for tool approval behavior.
|
|
366
|
+
*/
|
|
367
|
+
interface ToolApprovalSettings {
|
|
368
|
+
/**
|
|
369
|
+
* Which tool calls require approval.
|
|
370
|
+
* - 'high_risk' (default): only riskLevel 'high' and 'critical'
|
|
371
|
+
* - 'all': every tool call
|
|
372
|
+
*/
|
|
373
|
+
strategy?: ToolApprovalStrategy;
|
|
374
|
+
/**
|
|
375
|
+
* If true, skip all approval checks (useful for "autoApprove" mode).
|
|
376
|
+
*/
|
|
377
|
+
autoApprove?: boolean;
|
|
378
|
+
/**
|
|
379
|
+
* Pre-supplied approval decisions keyed by tool_call_id.
|
|
380
|
+
* Useful for "pause → ask user → resume" flows without a live callback.
|
|
381
|
+
*/
|
|
382
|
+
decisions?: Record<string, ToolApprovalResult>;
|
|
383
|
+
}
|
|
384
|
+
interface ToolFileSystemCapabilities {
|
|
385
|
+
readFile?: (path: string) => Promise<string>;
|
|
386
|
+
writeFile?: (path: string, content: string) => Promise<void>;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Tool-visible usage stats.
|
|
390
|
+
*
|
|
391
|
+
* Mirrors the common `Usage` shape and allows optional per-request breakdowns.
|
|
392
|
+
* This is local-only runtime data (not sent to the LLM).
|
|
393
|
+
*/
|
|
394
|
+
interface ToolRunUsage extends Usage {
|
|
395
|
+
requestUsageEntries?: unknown[];
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Runtime context passed to tools during execution.
|
|
399
|
+
*
|
|
400
|
+
* This is intentionally small and capability-oriented:
|
|
401
|
+
* - identity: sessionId/agentId
|
|
402
|
+
* - control: AbortSignal
|
|
403
|
+
* - capabilities: optional external side-effectful APIs (fetch/fs/etc.)
|
|
404
|
+
*/
|
|
405
|
+
interface ToolExecutionContext<TContext = unknown> {
|
|
406
|
+
sessionId: string;
|
|
407
|
+
agentId: string;
|
|
408
|
+
/**
|
|
409
|
+
* User-provided runtime context for tool execution.
|
|
410
|
+
* This is local-only data and is NOT sent to the LLM.
|
|
411
|
+
*
|
|
412
|
+
* Put your dependencies/state/cache/logger/userId/db client here.
|
|
413
|
+
* Prefer providing a strongly-typed `TContext` instead of `any`.
|
|
414
|
+
*/
|
|
415
|
+
context?: TContext;
|
|
416
|
+
signal?: AbortSignal;
|
|
417
|
+
/**
|
|
418
|
+
* Optional side-effectful capabilities.
|
|
419
|
+
* If a capability is undefined, tools should treat it as disabled.
|
|
420
|
+
*/
|
|
421
|
+
capabilities?: {
|
|
422
|
+
fetch?: typeof fetch;
|
|
423
|
+
fs?: ToolFileSystemCapabilities;
|
|
424
|
+
};
|
|
425
|
+
usage?: ToolRunUsage;
|
|
426
|
+
metadata?: Record<string, unknown>;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Safe input shape for callers to provide context/capabilities/metadata.
|
|
430
|
+
* Identity fields are filled by the Agent at runtime.
|
|
431
|
+
*/
|
|
432
|
+
interface ToolExecutionContextInput<TContext = unknown> {
|
|
433
|
+
context?: TContext;
|
|
434
|
+
capabilities?: ToolExecutionContext['capabilities'];
|
|
435
|
+
metadata?: Record<string, unknown>;
|
|
436
|
+
/**
|
|
437
|
+
* Optional approval configuration.
|
|
438
|
+
*/
|
|
439
|
+
approval?: ToolApprovalSettings;
|
|
440
|
+
/**
|
|
441
|
+
* Callback for tool approval before execution.
|
|
442
|
+
*
|
|
443
|
+
* When provided, this function will be called before executing tools
|
|
444
|
+
* with riskLevel 'high' or 'critical'. The tool will only execute
|
|
445
|
+
* if the callback returns { approved: true }.
|
|
446
|
+
*
|
|
447
|
+
* If not provided, all tools execute without approval (backward compatible).
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* ```ts
|
|
451
|
+
* onToolApproval: async (req) => {
|
|
452
|
+
* console.log(`Tool ${req.toolName} (${req.riskLevel}) wants to execute:`)
|
|
453
|
+
* console.log(JSON.stringify(req.args, null, 2))
|
|
454
|
+
* const answer = await readline.question('Allow? [y/n]: ')
|
|
455
|
+
* return { approved: answer === 'y' }
|
|
456
|
+
* }
|
|
457
|
+
* ```
|
|
458
|
+
*/
|
|
459
|
+
onToolApproval?: (request: ToolApprovalRequest) => Promise<ToolApprovalOutcome>;
|
|
460
|
+
}
|
|
461
|
+
//#endregion
|
|
462
|
+
//#region src/session/base.d.ts
|
|
463
|
+
/**
|
|
464
|
+
* Abstract base class for a session.
|
|
465
|
+
*
|
|
466
|
+
* A session represents a single conversation instance with an agent.
|
|
467
|
+
* One agent can have multiple concurrent sessions.
|
|
468
|
+
*/
|
|
469
|
+
declare abstract class BaseSession {
|
|
470
|
+
/**
|
|
471
|
+
* Unique session identifier
|
|
472
|
+
*/
|
|
473
|
+
abstract readonly id: string;
|
|
474
|
+
/**
|
|
475
|
+
* Agent identifier this session belongs to
|
|
476
|
+
*/
|
|
477
|
+
abstract readonly agentId: string;
|
|
478
|
+
/**
|
|
479
|
+
* Session creation timestamp (ms)
|
|
480
|
+
*/
|
|
481
|
+
abstract readonly createdAt: number;
|
|
482
|
+
/**
|
|
483
|
+
* Custom metadata associated with the session
|
|
484
|
+
*/
|
|
485
|
+
abstract metadata: Record<string, unknown>;
|
|
486
|
+
/**
|
|
487
|
+
* Current session status
|
|
488
|
+
*/
|
|
489
|
+
abstract status: SessionStatus;
|
|
490
|
+
/**
|
|
491
|
+
* Session title (user-defined)
|
|
492
|
+
*/
|
|
493
|
+
abstract title?: string;
|
|
494
|
+
/**
|
|
495
|
+
* Last update timestamp (ms)
|
|
496
|
+
*/
|
|
497
|
+
abstract updatedAt: number;
|
|
498
|
+
/**
|
|
499
|
+
* Last activity timestamp (ms)
|
|
500
|
+
*/
|
|
501
|
+
abstract lastActiveAt: number;
|
|
502
|
+
/**
|
|
503
|
+
* Error message if status is 'error'
|
|
504
|
+
*/
|
|
505
|
+
abstract errorMessage?: string;
|
|
506
|
+
/**
|
|
507
|
+
* Session-level configuration overrides
|
|
508
|
+
*/
|
|
509
|
+
abstract configOverride?: SessionConfigOverride;
|
|
510
|
+
/**
|
|
511
|
+
* Message history
|
|
512
|
+
*/
|
|
513
|
+
abstract messages: Message[];
|
|
514
|
+
/**
|
|
515
|
+
* Number of tool calls made in this session
|
|
516
|
+
*/
|
|
517
|
+
abstract toolCallCount: number;
|
|
518
|
+
/**
|
|
519
|
+
* Token usage statistics
|
|
520
|
+
*/
|
|
521
|
+
abstract usage: {
|
|
522
|
+
promptTokens: number;
|
|
523
|
+
completionTokens: number;
|
|
524
|
+
totalTokens: number;
|
|
525
|
+
};
|
|
526
|
+
/**
|
|
527
|
+
* Number of assistant responses
|
|
528
|
+
*/
|
|
529
|
+
abstract responseCount: number;
|
|
530
|
+
/**
|
|
531
|
+
* Average response time in milliseconds
|
|
532
|
+
*/
|
|
533
|
+
abstract avgResponseTime?: number;
|
|
534
|
+
/**
|
|
535
|
+
* Set model override for this session
|
|
536
|
+
*
|
|
537
|
+
* @param model - Model configuration to use for this session
|
|
538
|
+
*/
|
|
539
|
+
setModelOverride(model: ModelConfig): void;
|
|
540
|
+
/**
|
|
541
|
+
* Clear model override (use agent's default model)
|
|
542
|
+
*/
|
|
543
|
+
clearModelOverride(): void;
|
|
544
|
+
/**
|
|
545
|
+
* Set system prompt override for this session
|
|
546
|
+
*
|
|
547
|
+
* @param systemPrompt - System prompt to use for this session
|
|
548
|
+
*/
|
|
549
|
+
setSystemPromptOverride(systemPrompt: string): void;
|
|
550
|
+
/**
|
|
551
|
+
* Clear system prompt override
|
|
552
|
+
*/
|
|
553
|
+
clearSystemPromptOverride(): void;
|
|
554
|
+
/**
|
|
555
|
+
* Disable specific tools for this session
|
|
556
|
+
*
|
|
557
|
+
* @param toolNames - Names of tools to disable
|
|
558
|
+
*/
|
|
559
|
+
disableTools(toolNames: string[]): void;
|
|
560
|
+
/**
|
|
561
|
+
* Re-enable all tools for this session
|
|
562
|
+
*/
|
|
563
|
+
enableAllTools(): void;
|
|
564
|
+
/**
|
|
565
|
+
* Update session status
|
|
566
|
+
*
|
|
567
|
+
* @param status - New status
|
|
568
|
+
* @param errorMessage - Error message (if status is 'error')
|
|
569
|
+
*/
|
|
570
|
+
setStatus(status: SessionStatus, errorMessage?: string): void;
|
|
571
|
+
/**
|
|
572
|
+
* Mark session as active (update lastActiveAt)
|
|
573
|
+
*/
|
|
574
|
+
markActive(): void;
|
|
575
|
+
/**
|
|
576
|
+
* Add a message to the conversation history
|
|
577
|
+
*
|
|
578
|
+
* @param message - Message to add
|
|
579
|
+
*/
|
|
580
|
+
addMessage(message: Message): void;
|
|
581
|
+
/**
|
|
582
|
+
* Get preview of the last message (truncated for display)
|
|
583
|
+
*
|
|
584
|
+
* @param maxLength - Maximum length of preview
|
|
585
|
+
* @returns Preview string or undefined if no messages
|
|
586
|
+
*/
|
|
587
|
+
getLastMessagePreview(maxLength?: number): string | undefined;
|
|
588
|
+
/**
|
|
589
|
+
* Add usage statistics
|
|
590
|
+
*
|
|
591
|
+
* @param usage - Usage to add
|
|
592
|
+
* @param usage.promptTokens - Number of prompt tokens
|
|
593
|
+
* @param usage.completionTokens - Number of completion tokens
|
|
594
|
+
* @param usage.totalTokens - Total number of tokens
|
|
595
|
+
*/
|
|
596
|
+
addUsage(usage: {
|
|
597
|
+
promptTokens: number;
|
|
598
|
+
completionTokens: number;
|
|
599
|
+
totalTokens: number;
|
|
600
|
+
}): void;
|
|
601
|
+
/**
|
|
602
|
+
* Record a response with its duration
|
|
603
|
+
*
|
|
604
|
+
* @param durationMs - Response duration in milliseconds
|
|
605
|
+
*/
|
|
606
|
+
recordResponse(durationMs: number): void;
|
|
607
|
+
/**
|
|
608
|
+
* Increment tool call count
|
|
609
|
+
*/
|
|
610
|
+
incrementToolCallCount(): void;
|
|
611
|
+
/**
|
|
612
|
+
* Create a snapshot of the session for persistence
|
|
613
|
+
*
|
|
614
|
+
* @returns Session snapshot
|
|
615
|
+
*/
|
|
616
|
+
toSnapshot(): SessionSnapshot;
|
|
617
|
+
/**
|
|
618
|
+
* Restore session state from a snapshot
|
|
619
|
+
*
|
|
620
|
+
* @param snapshot - Session snapshot to restore from
|
|
621
|
+
*/
|
|
622
|
+
restoreFromSnapshot(snapshot: SessionSnapshot): void;
|
|
623
|
+
}
|
|
624
|
+
//#endregion
|
|
625
|
+
//#region src/session/manager.d.ts
|
|
626
|
+
/**
|
|
627
|
+
* Abstract base class for session management.
|
|
628
|
+
*
|
|
629
|
+
* Handles session lifecycle: creation, retrieval, listing, and destruction.
|
|
630
|
+
* Implement this class for different storage backends (e.g., Redis, SQLite, in-memory).
|
|
631
|
+
*/
|
|
632
|
+
declare abstract class BaseSessionManager {
|
|
633
|
+
/**
|
|
634
|
+
* Create a new session for an agent
|
|
635
|
+
*
|
|
636
|
+
* @param agentId - Agent identifier
|
|
637
|
+
* @param metadata - Optional session metadata
|
|
638
|
+
* @returns Newly created session
|
|
639
|
+
*/
|
|
640
|
+
abstract create(agentId: string, metadata?: Record<string, unknown>): Promise<BaseSession>;
|
|
641
|
+
/**
|
|
642
|
+
* Get a session by ID
|
|
643
|
+
*
|
|
644
|
+
* @param sessionId - Session identifier
|
|
645
|
+
* @returns Session or undefined if not found
|
|
646
|
+
*/
|
|
647
|
+
abstract get(sessionId: string): Promise<BaseSession | undefined>;
|
|
648
|
+
/**
|
|
649
|
+
* List all sessions for an agent
|
|
650
|
+
*
|
|
651
|
+
* @param agentId - Agent identifier
|
|
652
|
+
* @returns Array of sessions belonging to the agent
|
|
653
|
+
*/
|
|
654
|
+
abstract list(agentId: string): Promise<BaseSession[]>;
|
|
655
|
+
/**
|
|
656
|
+
* Destroy a session
|
|
657
|
+
*
|
|
658
|
+
* @param sessionId - Session identifier to destroy
|
|
659
|
+
*/
|
|
660
|
+
abstract destroy(sessionId: string): Promise<void>;
|
|
661
|
+
}
|
|
662
|
+
//#endregion
|
|
663
|
+
//#region src/agent/middleware.d.ts
|
|
664
|
+
/**
|
|
665
|
+
* Next function type for immutable middleware chain.
|
|
666
|
+
*
|
|
667
|
+
* Accepts the (potentially modified) state and returns the resulting state
|
|
668
|
+
* after all downstream middleware and core execution have completed.
|
|
669
|
+
*/
|
|
670
|
+
type NextFunction<State> = (state: State) => Promise<State>;
|
|
671
|
+
/**
|
|
672
|
+
* Middleware function type (immutable pattern)
|
|
673
|
+
*
|
|
674
|
+
* Middleware can intercept and transform state at each iteration.
|
|
675
|
+
* Unlike mutable middleware, this pattern:
|
|
676
|
+
* - Receives state as input
|
|
677
|
+
* - Passes (potentially modified) state to next()
|
|
678
|
+
* - Returns the final state after downstream processing
|
|
679
|
+
*
|
|
680
|
+
* This ensures the original state is never mutated, allowing checkpoint
|
|
681
|
+
* to save original state while LLM receives processed state.
|
|
682
|
+
*
|
|
683
|
+
* @example
|
|
684
|
+
* ```ts
|
|
685
|
+
* // Logging middleware (pass-through)
|
|
686
|
+
* const loggingMiddleware: Middleware = async (state, next) => {
|
|
687
|
+
* console.log(`Before iteration ${state.iteration}`);
|
|
688
|
+
* const result = await next(state); // Pass state unchanged
|
|
689
|
+
* console.log(`After iteration ${state.iteration}`);
|
|
690
|
+
* return result;
|
|
691
|
+
* };
|
|
692
|
+
*
|
|
693
|
+
* // Transforming middleware (compression)
|
|
694
|
+
* const compressionMiddleware: Middleware = async (state, next) => {
|
|
695
|
+
* const compressedState = { ...state, messages: compress(state.messages) };
|
|
696
|
+
* return next(compressedState); // Pass modified state
|
|
697
|
+
* };
|
|
698
|
+
* ```
|
|
699
|
+
*/
|
|
700
|
+
type Middleware<State = AgentLoopState> = (state: State, next: NextFunction<State>) => Promise<State>;
|
|
701
|
+
/**
|
|
702
|
+
* Compose multiple middleware functions into a single function.
|
|
703
|
+
*
|
|
704
|
+
* This implements an immutable onion model where each middleware:
|
|
705
|
+
* - Receives state from the previous middleware (or initial state)
|
|
706
|
+
* - Can transform state before passing to next()
|
|
707
|
+
* - Returns the result from downstream processing
|
|
708
|
+
*
|
|
709
|
+
* Execution order for each iteration:
|
|
710
|
+
* ```
|
|
711
|
+
* outer:before → inner:before → exec (model.stream) → inner:after → outer:after
|
|
712
|
+
* ```
|
|
713
|
+
*
|
|
714
|
+
* State flow:
|
|
715
|
+
* ```
|
|
716
|
+
* initialState → outer(transform?) → inner(transform?) → exec → result
|
|
717
|
+
* ```
|
|
718
|
+
*
|
|
719
|
+
* @param middleware - Array of middleware functions
|
|
720
|
+
* @returns Composed middleware function that can be invoked per iteration
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
* ```ts
|
|
724
|
+
* const composed = compose([
|
|
725
|
+
* async (state, next) => {
|
|
726
|
+
* console.log('outer:before');
|
|
727
|
+
* const result = await next(state);
|
|
728
|
+
* console.log('outer:after');
|
|
729
|
+
* return result;
|
|
730
|
+
* },
|
|
731
|
+
* async (state, next) => {
|
|
732
|
+
* console.log('inner:before');
|
|
733
|
+
* // Transform state before passing down
|
|
734
|
+
* const modified = { ...state, messages: compress(state.messages) };
|
|
735
|
+
* const result = await next(modified);
|
|
736
|
+
* console.log('inner:after');
|
|
737
|
+
* return result;
|
|
738
|
+
* },
|
|
739
|
+
* ]);
|
|
740
|
+
*
|
|
741
|
+
* // Execute with core function
|
|
742
|
+
* const result = await composed(initialState, async (s) => {
|
|
743
|
+
* // Core execution receives transformed state
|
|
744
|
+
* await model.stream(s.messages);
|
|
745
|
+
* return s;
|
|
746
|
+
* });
|
|
747
|
+
* ```
|
|
748
|
+
*/
|
|
749
|
+
declare function compose<State = AgentLoopState>(middleware: Middleware<State>[]): (initialState: State, exec?: NextFunction<State>) => Promise<State>;
|
|
750
|
+
//#endregion
|
|
751
|
+
//#region src/agent/contextCompressionMiddleware.d.ts
|
|
752
|
+
/**
|
|
753
|
+
* Configuration options for context compression middleware.
|
|
754
|
+
*/
|
|
755
|
+
interface ContextCompressionOptions {
|
|
756
|
+
/**
|
|
757
|
+
* Maximum context token limit (e.g., 128000 for GPT-4).
|
|
758
|
+
*/
|
|
759
|
+
contextLimit: number;
|
|
760
|
+
/**
|
|
761
|
+
* Reserved tokens for model output.
|
|
762
|
+
* Compression triggers when used tokens > (contextLimit - outputLimit).
|
|
763
|
+
*/
|
|
764
|
+
outputLimit: number;
|
|
765
|
+
/**
|
|
766
|
+
* Number of recent conversation turns to always protect (default: 2).
|
|
767
|
+
* A turn is a user message + assistant response pair.
|
|
768
|
+
*/
|
|
769
|
+
protectedTurns?: number;
|
|
770
|
+
/**
|
|
771
|
+
* Maximum tokens of recent tool outputs to protect (default: 40000).
|
|
772
|
+
* Tool outputs within this limit won't be cleared.
|
|
773
|
+
*/
|
|
774
|
+
protectedToolTokens?: number;
|
|
775
|
+
/**
|
|
776
|
+
* Threshold for trimming individual tool outputs (default: 20000).
|
|
777
|
+
* Protected tool outputs exceeding this will be truncated (not cleared).
|
|
778
|
+
*/
|
|
779
|
+
trimToolOutputThreshold?: number;
|
|
780
|
+
/**
|
|
781
|
+
* Whether to generate a summary of cleared content (default: false).
|
|
782
|
+
* If true, requires model or getModel to be provided.
|
|
783
|
+
*/
|
|
784
|
+
enableSummary?: boolean;
|
|
785
|
+
/**
|
|
786
|
+
* Model to use for generating summaries (only needed if enableSummary is true).
|
|
787
|
+
*/
|
|
788
|
+
model?: ModelClient;
|
|
789
|
+
/**
|
|
790
|
+
* Function to get the model for generating summaries.
|
|
791
|
+
* Useful when you want to use the agent's model: `getModel: () => agent.model`
|
|
792
|
+
*/
|
|
793
|
+
getModel?: () => ModelClient;
|
|
794
|
+
/**
|
|
795
|
+
* Custom prompt for summary generation.
|
|
796
|
+
* Supports template placeholders:
|
|
797
|
+
* - {{existingSummary}}: prior rolling summary (may be empty)
|
|
798
|
+
* - {{toolOutputs}}: formatted cleared tool outputs
|
|
799
|
+
*/
|
|
800
|
+
summaryPrompt?: string;
|
|
801
|
+
/**
|
|
802
|
+
* State store for persisting compression state.
|
|
803
|
+
* If provided, compression stats, history, and summaries will be saved.
|
|
804
|
+
*/
|
|
805
|
+
stateStore?: StateStore;
|
|
806
|
+
/**
|
|
807
|
+
* Function to get the state store.
|
|
808
|
+
* Useful when you want to use the agent's state store: `getStateStore: () => agent.stateStore`
|
|
809
|
+
*/
|
|
810
|
+
getStateStore?: () => StateStore | undefined;
|
|
811
|
+
/**
|
|
812
|
+
* Whether to persist compressed messages to state store (default: false).
|
|
813
|
+
* When enabled, each compression will save a snapshot file with compressed messages.
|
|
814
|
+
* This requires stateStore or getStateStore to be provided.
|
|
815
|
+
*
|
|
816
|
+
* Each compression saves a separate file: `compression-snapshot-${timestamp}.json`
|
|
817
|
+
* Useful for debugging or auditing compressed message states.
|
|
818
|
+
*/
|
|
819
|
+
persistClearedContent?: boolean;
|
|
820
|
+
/**
|
|
821
|
+
* Callback when compression is triggered.
|
|
822
|
+
*/
|
|
823
|
+
onCompressionStart?: (stats: CompressionStats) => void;
|
|
824
|
+
/**
|
|
825
|
+
* Callback when compression completes.
|
|
826
|
+
*/
|
|
827
|
+
onCompressionEnd?: (stats: CompressionStats) => void;
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Statistics about the compression operation.
|
|
831
|
+
*/
|
|
832
|
+
interface CompressionStats {
|
|
833
|
+
/** Token count before compression */
|
|
834
|
+
tokensBefore: number;
|
|
835
|
+
/** Token count after compression */
|
|
836
|
+
tokensAfter: number;
|
|
837
|
+
/** Number of tool outputs that were cleared */
|
|
838
|
+
clearedToolOutputs: number;
|
|
839
|
+
/** Number of tool outputs that were trimmed (but not cleared) */
|
|
840
|
+
trimmedToolOutputs: number;
|
|
841
|
+
/** Whether a summary was generated */
|
|
842
|
+
summaryGenerated: boolean;
|
|
843
|
+
/** Timestamp when this compression occurred */
|
|
844
|
+
timestamp?: number;
|
|
845
|
+
}
|
|
846
|
+
/**
|
|
847
|
+
* Create a context compression middleware.
|
|
848
|
+
*
|
|
849
|
+
* This middleware automatically compresses conversation history when it exceeds
|
|
850
|
+
* the configured token limit. It follows an immutable pattern - original messages
|
|
851
|
+
* are never modified. Instead, compressed messages are passed to the LLM while
|
|
852
|
+
* the original messages remain unchanged (preserved for checkpoint).
|
|
853
|
+
*
|
|
854
|
+
* Compression strategy:
|
|
855
|
+
* 1. Preserve message structure (all messages remain, including tool calls)
|
|
856
|
+
* 2. Protect recent N turns completely
|
|
857
|
+
* 3. Protect recent tool outputs up to token limit
|
|
858
|
+
* 4. Clear old tool outputs with placeholder: "[Old tool result content cleared]"
|
|
859
|
+
* 5. Optionally generate a summary of cleared content
|
|
860
|
+
*
|
|
861
|
+
* @param options - Compression configuration options
|
|
862
|
+
* @returns Middleware function
|
|
863
|
+
*
|
|
864
|
+
* @example
|
|
865
|
+
* ```ts
|
|
866
|
+
* const agent = new Agent({ model, ... })
|
|
867
|
+
*
|
|
868
|
+
* // Basic usage - just clear old tool outputs
|
|
869
|
+
* agent.use(createContextCompressionMiddleware({
|
|
870
|
+
* contextLimit: 128000,
|
|
871
|
+
* outputLimit: 4096,
|
|
872
|
+
* }))
|
|
873
|
+
*
|
|
874
|
+
* // With summary generation and persistence
|
|
875
|
+
* agent.use(createContextCompressionMiddleware({
|
|
876
|
+
* contextLimit: 128000,
|
|
877
|
+
* outputLimit: 4096,
|
|
878
|
+
* enableSummary: true,
|
|
879
|
+
* getModel: () => agent.model,
|
|
880
|
+
* getStateStore: () => agent.stateStore,
|
|
881
|
+
* }))
|
|
882
|
+
* ```
|
|
883
|
+
*/
|
|
884
|
+
declare function createContextCompressionMiddleware(options: ContextCompressionOptions): Middleware<AgentLoopState>;
|
|
885
|
+
/**
|
|
886
|
+
* Options for manual compression.
|
|
887
|
+
*/
|
|
888
|
+
interface ManualCompressionOptions {
|
|
889
|
+
/**
|
|
890
|
+
* Session ID for the compression.
|
|
891
|
+
*/
|
|
892
|
+
sessionId: string;
|
|
893
|
+
/**
|
|
894
|
+
* Full messages from the session (including all history).
|
|
895
|
+
* These should be the complete, uncompressed messages.
|
|
896
|
+
*/
|
|
897
|
+
fullMessages: Message[];
|
|
898
|
+
/**
|
|
899
|
+
* Model to use for generating summary.
|
|
900
|
+
*/
|
|
901
|
+
model: ModelClient;
|
|
902
|
+
/**
|
|
903
|
+
* State store for persisting compression state.
|
|
904
|
+
*/
|
|
905
|
+
stateStore: StateStore;
|
|
906
|
+
/**
|
|
907
|
+
* Custom prompt for summary generation (optional).
|
|
908
|
+
* If not provided, uses DEFAULT_SUMMARY_PROMPT.
|
|
909
|
+
*/
|
|
910
|
+
summaryPrompt?: string;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Result of manual compression.
|
|
914
|
+
*/
|
|
915
|
+
interface ManualCompressionResult {
|
|
916
|
+
/**
|
|
917
|
+
* Generated summary.
|
|
918
|
+
*/
|
|
919
|
+
summary: string;
|
|
920
|
+
/**
|
|
921
|
+
* Number of messages processed.
|
|
922
|
+
*/
|
|
923
|
+
messageCount: number;
|
|
924
|
+
/**
|
|
925
|
+
* Number of tool outputs found.
|
|
926
|
+
*/
|
|
927
|
+
toolOutputCount: number;
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Manually compress a session by generating a summary from full message history.
|
|
931
|
+
*
|
|
932
|
+
* This function extracts all tool outputs from the full messages and generates
|
|
933
|
+
* a new summary based on the complete context. The summary is saved to
|
|
934
|
+
* CompressionState and will be automatically loaded by the middleware on next run.
|
|
935
|
+
*
|
|
936
|
+
* @param options - Manual compression options
|
|
937
|
+
* @returns Compression result with generated summary
|
|
938
|
+
*
|
|
939
|
+
* @example
|
|
940
|
+
* ```ts
|
|
941
|
+
* const result = await compressSessionManually({
|
|
942
|
+
* sessionId: 'session-123',
|
|
943
|
+
* fullMessages: allMessages,
|
|
944
|
+
* model: myModel,
|
|
945
|
+
* stateStore: myStore,
|
|
946
|
+
* })
|
|
947
|
+
* console.log(`Generated summary: ${result.summary}`)
|
|
948
|
+
* ```
|
|
949
|
+
*/
|
|
950
|
+
declare function compressSessionManually(options: ManualCompressionOptions): Promise<ManualCompressionResult>;
|
|
951
|
+
//#endregion
|
|
952
|
+
//#region src/state/types.d.ts
|
|
953
|
+
/**
|
|
954
|
+
* State store configuration options.
|
|
955
|
+
*/
|
|
956
|
+
interface StateStoreOptions {
|
|
957
|
+
/**
|
|
958
|
+
* When to save checkpoints:
|
|
959
|
+
* - 'before': Save before each iteration (default)
|
|
960
|
+
* - 'after': Save after each iteration
|
|
961
|
+
* - 'both': Save before and after
|
|
962
|
+
*/
|
|
963
|
+
savePoint?: 'before' | 'after' | 'both';
|
|
964
|
+
/**
|
|
965
|
+
* Whether to delete the checkpoint after successful completion.
|
|
966
|
+
* Default: true
|
|
967
|
+
*/
|
|
968
|
+
deleteOnComplete?: boolean;
|
|
969
|
+
}
|
|
970
|
+
/**
|
|
971
|
+
* Predefined state keys for common data types.
|
|
972
|
+
*/
|
|
973
|
+
declare const StateKeys: {
|
|
974
|
+
/** AgentLoopCheckpoint data */
|
|
975
|
+
readonly CHECKPOINT: "checkpoint";
|
|
976
|
+
/** CompressionState data */
|
|
977
|
+
readonly COMPRESSION: "compression";
|
|
978
|
+
/** SessionSnapshot data */
|
|
979
|
+
readonly SESSION: "session";
|
|
980
|
+
/**
|
|
981
|
+
* Compressed messages snapshot key pattern.
|
|
982
|
+
* Use with timestamp: `compression-snapshot-${timestamp}`
|
|
983
|
+
*/
|
|
984
|
+
readonly COMPRESSION_SNAPSHOT: "compression-snapshot";
|
|
985
|
+
};
|
|
986
|
+
type StateKey = (typeof StateKeys)[keyof typeof StateKeys];
|
|
987
|
+
/**
|
|
988
|
+
* Compression state for context compression middleware.
|
|
989
|
+
*
|
|
990
|
+
* This stores all compression-related data for a session,
|
|
991
|
+
* allowing the middleware to restore its state after a restart.
|
|
992
|
+
*/
|
|
993
|
+
interface CompressionState {
|
|
994
|
+
/**
|
|
995
|
+
* Statistics from the last compression operation.
|
|
996
|
+
*/
|
|
997
|
+
lastStats?: CompressionStats;
|
|
998
|
+
/**
|
|
999
|
+
* History of all compression operations.
|
|
1000
|
+
*/
|
|
1001
|
+
history: CompressionStats[];
|
|
1002
|
+
/**
|
|
1003
|
+
* Accumulated summary content from cleared tool outputs.
|
|
1004
|
+
* This can be used when resuming from a checkpoint to provide context.
|
|
1005
|
+
*/
|
|
1006
|
+
summary?: string;
|
|
1007
|
+
/**
|
|
1008
|
+
* Last update timestamp (ms).
|
|
1009
|
+
*/
|
|
1010
|
+
updatedAt: number;
|
|
1011
|
+
}
|
|
1012
|
+
//#endregion
|
|
1013
|
+
//#region src/state/stateStore.d.ts
|
|
1014
|
+
/**
|
|
1015
|
+
* Abstract base class for state storage.
|
|
1016
|
+
*
|
|
1017
|
+
* StateStore provides a session-centric storage abstraction where all data
|
|
1018
|
+
* is organized by sessionId. Each session can have multiple keys storing
|
|
1019
|
+
* different types of data (checkpoint, compression state, session info, etc.).
|
|
1020
|
+
*
|
|
1021
|
+
* Subclasses only need to implement the low-level storage primitives:
|
|
1022
|
+
* - _write: Write data to a path
|
|
1023
|
+
* - _read: Read data from a path
|
|
1024
|
+
* - _delete: Delete data at a path
|
|
1025
|
+
* - _exists: Check if data exists at a path
|
|
1026
|
+
* - _list: List all paths with a given prefix
|
|
1027
|
+
*
|
|
1028
|
+
* The base class provides:
|
|
1029
|
+
* - High-level API for session-based storage (save, load, delete, etc.)
|
|
1030
|
+
* - Convenience methods for checkpoint operations
|
|
1031
|
+
* - JSON serialization/deserialization
|
|
1032
|
+
*
|
|
1033
|
+
* @example
|
|
1034
|
+
* ```typescript
|
|
1035
|
+
* // Using with an agent
|
|
1036
|
+
* const store = new FileStateStore({ dir: './state' })
|
|
1037
|
+
*
|
|
1038
|
+
* const agent = new Agent({
|
|
1039
|
+
* name: 'MyAgent',
|
|
1040
|
+
* stateStore: store,
|
|
1041
|
+
* // ...
|
|
1042
|
+
* })
|
|
1043
|
+
*
|
|
1044
|
+
* // Manual state operations
|
|
1045
|
+
* await store.save(sessionId, 'custom-key', { myData: 123 })
|
|
1046
|
+
* const data = await store.load(sessionId, 'custom-key')
|
|
1047
|
+
* ```
|
|
1048
|
+
*/
|
|
1049
|
+
declare abstract class StateStore {
|
|
1050
|
+
/**
|
|
1051
|
+
* When to save checkpoints during agent execution.
|
|
1052
|
+
*/
|
|
1053
|
+
readonly savePoint: 'before' | 'after' | 'both';
|
|
1054
|
+
/**
|
|
1055
|
+
* Whether to delete checkpoint after successful completion.
|
|
1056
|
+
*/
|
|
1057
|
+
readonly deleteOnComplete: boolean;
|
|
1058
|
+
constructor(options?: StateStoreOptions);
|
|
1059
|
+
/**
|
|
1060
|
+
* Save data for a session under a specific key.
|
|
1061
|
+
*
|
|
1062
|
+
* @param sessionId - Session identifier
|
|
1063
|
+
* @param key - Data key (e.g., 'checkpoint', 'compression', or custom keys)
|
|
1064
|
+
* @param data - Data to save (will be JSON serialized)
|
|
1065
|
+
*/
|
|
1066
|
+
save<T>(sessionId: string, key: string, data: T): Promise<void>;
|
|
1067
|
+
/**
|
|
1068
|
+
* Load data for a session by key.
|
|
1069
|
+
*
|
|
1070
|
+
* @param sessionId - Session identifier
|
|
1071
|
+
* @param key - Data key
|
|
1072
|
+
* @returns The data or undefined if not found
|
|
1073
|
+
*/
|
|
1074
|
+
load<T>(sessionId: string, key: string): Promise<T | undefined>;
|
|
1075
|
+
/**
|
|
1076
|
+
* Delete data for a session by key.
|
|
1077
|
+
*
|
|
1078
|
+
* @param sessionId - Session identifier
|
|
1079
|
+
* @param key - Data key
|
|
1080
|
+
*/
|
|
1081
|
+
delete(sessionId: string, key: string): Promise<void>;
|
|
1082
|
+
/**
|
|
1083
|
+
* Delete all data for a session.
|
|
1084
|
+
*
|
|
1085
|
+
* @param sessionId - Session identifier
|
|
1086
|
+
*/
|
|
1087
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
1088
|
+
/**
|
|
1089
|
+
* List all keys for a session.
|
|
1090
|
+
*
|
|
1091
|
+
* @param sessionId - Session identifier
|
|
1092
|
+
* @returns Array of keys
|
|
1093
|
+
*/
|
|
1094
|
+
listKeys(sessionId: string): Promise<string[]>;
|
|
1095
|
+
/**
|
|
1096
|
+
* Check if data exists for a session key.
|
|
1097
|
+
*
|
|
1098
|
+
* @param sessionId - Session identifier
|
|
1099
|
+
* @param key - Data key
|
|
1100
|
+
* @returns True if data exists
|
|
1101
|
+
*/
|
|
1102
|
+
exists(sessionId: string, key: string): Promise<boolean>;
|
|
1103
|
+
/**
|
|
1104
|
+
* Save an agent loop checkpoint.
|
|
1105
|
+
*
|
|
1106
|
+
* This is a convenience method that saves the checkpoint under the
|
|
1107
|
+
* predefined CHECKPOINT key with additional metadata.
|
|
1108
|
+
*
|
|
1109
|
+
* @param checkpoint - Checkpoint to save
|
|
1110
|
+
*/
|
|
1111
|
+
saveCheckpoint(checkpoint: AgentLoopCheckpoint): Promise<void>;
|
|
1112
|
+
/**
|
|
1113
|
+
* Load an agent loop checkpoint by session ID.
|
|
1114
|
+
*
|
|
1115
|
+
* @param sessionId - Session identifier
|
|
1116
|
+
* @returns Checkpoint or undefined if not found
|
|
1117
|
+
*/
|
|
1118
|
+
loadCheckpoint(sessionId: string): Promise<AgentLoopCheckpoint | undefined>;
|
|
1119
|
+
/**
|
|
1120
|
+
* Delete an agent loop checkpoint.
|
|
1121
|
+
*
|
|
1122
|
+
* @param sessionId - Session identifier
|
|
1123
|
+
*/
|
|
1124
|
+
deleteCheckpoint(sessionId: string): Promise<void>;
|
|
1125
|
+
/**
|
|
1126
|
+
* List all checkpoints across all sessions.
|
|
1127
|
+
*
|
|
1128
|
+
* @returns Array of checkpoints
|
|
1129
|
+
*/
|
|
1130
|
+
listCheckpoints(): Promise<AgentLoopCheckpoint[]>;
|
|
1131
|
+
/**
|
|
1132
|
+
* List all session IDs that have stored data.
|
|
1133
|
+
*
|
|
1134
|
+
* @returns Array of session IDs
|
|
1135
|
+
*/
|
|
1136
|
+
listSessions(): Promise<string[]>;
|
|
1137
|
+
/**
|
|
1138
|
+
* Build a storage path from sessionId and key.
|
|
1139
|
+
* Default format: `{sessionId}/{key}`
|
|
1140
|
+
*
|
|
1141
|
+
* Subclasses can override this for different path formats.
|
|
1142
|
+
*/
|
|
1143
|
+
protected buildPath(sessionId: string, key: string): string;
|
|
1144
|
+
/**
|
|
1145
|
+
* Build a prefix for listing all data under a session.
|
|
1146
|
+
* Default format: `{sessionId}/`
|
|
1147
|
+
*/
|
|
1148
|
+
protected buildPrefix(sessionId: string): string;
|
|
1149
|
+
/**
|
|
1150
|
+
* Extract the key from a full path.
|
|
1151
|
+
*/
|
|
1152
|
+
protected extractKey(sessionId: string, path: string): string;
|
|
1153
|
+
/**
|
|
1154
|
+
* Extract the sessionId from a full path.
|
|
1155
|
+
*/
|
|
1156
|
+
protected extractSessionId(path: string): string | undefined;
|
|
1157
|
+
/**
|
|
1158
|
+
* Write data to a storage path.
|
|
1159
|
+
*
|
|
1160
|
+
* @param path - Storage path
|
|
1161
|
+
* @param data - Serialized data string
|
|
1162
|
+
*/
|
|
1163
|
+
protected abstract _write(path: string, data: string): Promise<void>;
|
|
1164
|
+
/**
|
|
1165
|
+
* Read data from a storage path.
|
|
1166
|
+
*
|
|
1167
|
+
* @param path - Storage path
|
|
1168
|
+
* @returns Data string or undefined if not found
|
|
1169
|
+
*/
|
|
1170
|
+
protected abstract _read(path: string): Promise<string | undefined>;
|
|
1171
|
+
/**
|
|
1172
|
+
* Delete data at a storage path.
|
|
1173
|
+
*
|
|
1174
|
+
* @param path - Storage path
|
|
1175
|
+
*/
|
|
1176
|
+
protected abstract _delete(path: string): Promise<void>;
|
|
1177
|
+
/**
|
|
1178
|
+
* Check if data exists at a storage path.
|
|
1179
|
+
*
|
|
1180
|
+
* @param path - Storage path
|
|
1181
|
+
* @returns True if data exists
|
|
1182
|
+
*/
|
|
1183
|
+
protected abstract _exists(path: string): Promise<boolean>;
|
|
1184
|
+
/**
|
|
1185
|
+
* List all paths with a given prefix.
|
|
1186
|
+
*
|
|
1187
|
+
* @param prefix - Path prefix (empty string for all paths)
|
|
1188
|
+
* @returns Array of full paths
|
|
1189
|
+
*/
|
|
1190
|
+
protected abstract _list(prefix: string): Promise<string[]>;
|
|
1191
|
+
}
|
|
1192
|
+
//#endregion
|
|
1193
|
+
//#region src/state/FileStateStore.d.ts
|
|
1194
|
+
/**
|
|
1195
|
+
* Options for creating a FileStateStore.
|
|
1196
|
+
*/
|
|
1197
|
+
interface FileStateStoreOptions extends StateStoreOptions {
|
|
1198
|
+
/**
|
|
1199
|
+
* Directory path for storing state files.
|
|
1200
|
+
*/
|
|
1201
|
+
dir: string;
|
|
1202
|
+
}
|
|
1203
|
+
/**
|
|
1204
|
+
* File-based implementation of StateStore.
|
|
1205
|
+
*
|
|
1206
|
+
* Stores state data as JSON files in a directory structure organized by session:
|
|
1207
|
+
*
|
|
1208
|
+
* ```
|
|
1209
|
+
* <baseDir>/
|
|
1210
|
+
* <sessionId>/
|
|
1211
|
+
* checkpoint.json
|
|
1212
|
+
* compression.json
|
|
1213
|
+
* session.json
|
|
1214
|
+
* custom-key.json
|
|
1215
|
+
* ```
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```typescript
|
|
1219
|
+
* const store = new FileStateStore({
|
|
1220
|
+
* dir: './state',
|
|
1221
|
+
* savePoint: 'before',
|
|
1222
|
+
* deleteOnComplete: true,
|
|
1223
|
+
* })
|
|
1224
|
+
*
|
|
1225
|
+
* const agent = new Agent({
|
|
1226
|
+
* name: 'MyAgent',
|
|
1227
|
+
* stateStore: store,
|
|
1228
|
+
* // ...
|
|
1229
|
+
* })
|
|
1230
|
+
* ```
|
|
1231
|
+
*/
|
|
1232
|
+
declare class FileStateStore extends StateStore {
|
|
1233
|
+
private baseDir;
|
|
1234
|
+
constructor(options: FileStateStoreOptions);
|
|
1235
|
+
protected _write(storagePath: string, data: string): Promise<void>;
|
|
1236
|
+
protected _read(storagePath: string): Promise<string | undefined>;
|
|
1237
|
+
protected _delete(storagePath: string): Promise<void>;
|
|
1238
|
+
protected _exists(storagePath: string): Promise<boolean>;
|
|
1239
|
+
protected _list(prefix: string): Promise<string[]>;
|
|
1240
|
+
/**
|
|
1241
|
+
* Convert storage path to file system path.
|
|
1242
|
+
* Storage path: `{sessionId}/{key}`
|
|
1243
|
+
* File path: `{baseDir}/{sessionId}/{key}.json`
|
|
1244
|
+
*/
|
|
1245
|
+
private toFilePath;
|
|
1246
|
+
/**
|
|
1247
|
+
* Ensure a directory exists.
|
|
1248
|
+
*/
|
|
1249
|
+
private ensureDir;
|
|
1250
|
+
/**
|
|
1251
|
+
* List all JSON files in a directory.
|
|
1252
|
+
*/
|
|
1253
|
+
private listJsonFiles;
|
|
1254
|
+
/**
|
|
1255
|
+
* Get the base directory path.
|
|
1256
|
+
*/
|
|
1257
|
+
getBaseDir(): string;
|
|
1258
|
+
/**
|
|
1259
|
+
* Clear all state data from the store.
|
|
1260
|
+
* WARNING: This will delete all files in the base directory.
|
|
1261
|
+
*/
|
|
1262
|
+
clear(): void;
|
|
1263
|
+
}
|
|
1264
|
+
//#endregion
|
|
1265
|
+
//#region src/state/InMemoryStateStore.d.ts
|
|
1266
|
+
/**
|
|
1267
|
+
* In-memory implementation of StateStore.
|
|
1268
|
+
*
|
|
1269
|
+
* Useful for development, testing, and short-lived applications.
|
|
1270
|
+
* Data is lost when the process exits.
|
|
1271
|
+
*
|
|
1272
|
+
* @example
|
|
1273
|
+
* ```typescript
|
|
1274
|
+
* const store = new InMemoryStateStore({
|
|
1275
|
+
* savePoint: 'before',
|
|
1276
|
+
* deleteOnComplete: true,
|
|
1277
|
+
* })
|
|
1278
|
+
*
|
|
1279
|
+
* const agent = new Agent({
|
|
1280
|
+
* name: 'MyAgent',
|
|
1281
|
+
* stateStore: store,
|
|
1282
|
+
* // ...
|
|
1283
|
+
* })
|
|
1284
|
+
* ```
|
|
1285
|
+
*/
|
|
1286
|
+
declare class InMemoryStateStore extends StateStore {
|
|
1287
|
+
/**
|
|
1288
|
+
* Internal storage: path -> data
|
|
1289
|
+
*/
|
|
1290
|
+
private store;
|
|
1291
|
+
constructor(options?: StateStoreOptions);
|
|
1292
|
+
protected _write(path: string, data: string): Promise<void>;
|
|
1293
|
+
protected _read(path: string): Promise<string | undefined>;
|
|
1294
|
+
protected _delete(path: string): Promise<void>;
|
|
1295
|
+
protected _exists(path: string): Promise<boolean>;
|
|
1296
|
+
protected _list(prefix: string): Promise<string[]>;
|
|
1297
|
+
/**
|
|
1298
|
+
* Clear all data from the store.
|
|
1299
|
+
* Useful for testing.
|
|
1300
|
+
*/
|
|
1301
|
+
clear(): void;
|
|
1302
|
+
/**
|
|
1303
|
+
* Get statistics about the store.
|
|
1304
|
+
*/
|
|
1305
|
+
stats(): {
|
|
1306
|
+
entryCount: number;
|
|
1307
|
+
sessionCount: number;
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
//#endregion
|
|
1311
|
+
//#region src/tool/base.d.ts
|
|
1312
|
+
/**
|
|
1313
|
+
* Helper to create a text content block for CallToolResult
|
|
1314
|
+
*/
|
|
1315
|
+
declare function textContent(text: string): CallToolResult;
|
|
1316
|
+
/**
|
|
1317
|
+
* Helper to create an error result for CallToolResult
|
|
1318
|
+
*/
|
|
1319
|
+
declare function errorContent(error: string): CallToolResult;
|
|
1320
|
+
/**
|
|
1321
|
+
* Helper to create an image content block for CallToolResult
|
|
1322
|
+
*/
|
|
1323
|
+
declare function imageContent(data: string, mimeType: string): CallToolResult;
|
|
1324
|
+
/**
|
|
1325
|
+
* Abstract base class for tools.
|
|
1326
|
+
*
|
|
1327
|
+
* Tools are capabilities that the agent can invoke during execution.
|
|
1328
|
+
* Implement this class to create custom tools.
|
|
1329
|
+
*
|
|
1330
|
+
* All tool execute() methods must return MCP SDK-compliant CallToolResult:
|
|
1331
|
+
* - content: array of ContentBlock (TextContent, ImageContent, etc.)
|
|
1332
|
+
* - isError: optional boolean to indicate error
|
|
1333
|
+
* - structuredContent: optional structured data object
|
|
1334
|
+
*/
|
|
1335
|
+
declare abstract class BaseTool {
|
|
1336
|
+
/**
|
|
1337
|
+
* Unique name of the tool (used by LLM to invoke)
|
|
1338
|
+
*/
|
|
1339
|
+
abstract readonly name: string;
|
|
1340
|
+
/**
|
|
1341
|
+
* Human-readable description of what the tool does
|
|
1342
|
+
*/
|
|
1343
|
+
abstract readonly description: string;
|
|
1344
|
+
/**
|
|
1345
|
+
* JSON Schema defining the tool's input parameters
|
|
1346
|
+
*/
|
|
1347
|
+
abstract readonly parameters: ToolInputSchema;
|
|
1348
|
+
/**
|
|
1349
|
+
* Risk level of the tool, used to determine if user approval is required.
|
|
1350
|
+
*
|
|
1351
|
+
* - 'safe': No risk, read-only operations (default)
|
|
1352
|
+
* - 'low': Low risk, minimal side effects
|
|
1353
|
+
* - 'medium': Medium risk, reversible changes
|
|
1354
|
+
* - 'high': High risk, file modifications
|
|
1355
|
+
* - 'critical': Critical risk, arbitrary command execution
|
|
1356
|
+
*/
|
|
1357
|
+
readonly riskLevel: RiskLevel;
|
|
1358
|
+
/**
|
|
1359
|
+
* Execute the tool with given arguments
|
|
1360
|
+
*
|
|
1361
|
+
* @param args - Tool arguments matching the parameters schema
|
|
1362
|
+
* @param ctx - Optional runtime context provided by the Agent
|
|
1363
|
+
* @returns Tool execution result conforming to MCP SDK CallToolResult
|
|
1364
|
+
*/
|
|
1365
|
+
abstract execute(args: Record<string, unknown>, ctx?: ToolExecutionContext<any>): Promise<CallToolResult>;
|
|
1366
|
+
}
|
|
1367
|
+
//#endregion
|
|
1368
|
+
//#region src/tool/builtin/glob.d.ts
|
|
1369
|
+
/**
|
|
1370
|
+
* Result of a glob operation
|
|
1371
|
+
*/
|
|
1372
|
+
interface GlobResult {
|
|
1373
|
+
/** List of matched file paths (sorted by modification time, newest first) */
|
|
1374
|
+
files: string[];
|
|
1375
|
+
/** Total number of matches found */
|
|
1376
|
+
totalMatches: number;
|
|
1377
|
+
/** Whether results were truncated */
|
|
1378
|
+
truncated: boolean;
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Arguments for the Glob tool
|
|
1382
|
+
*/
|
|
1383
|
+
interface GlobArgs {
|
|
1384
|
+
/** The glob pattern to match files against */
|
|
1385
|
+
pattern: string;
|
|
1386
|
+
/** The directory to search in (defaults to cwd) */
|
|
1387
|
+
path?: string;
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Tool for finding files matching glob patterns.
|
|
1391
|
+
*
|
|
1392
|
+
* This tool provides fast file pattern matching that works with any codebase size,
|
|
1393
|
+
* returning matching file paths sorted by modification time.
|
|
1394
|
+
*
|
|
1395
|
+
* @example
|
|
1396
|
+
* ```typescript
|
|
1397
|
+
* const globTool = new GlobTool()
|
|
1398
|
+
* const result = await globTool.execute({
|
|
1399
|
+
* pattern: '**\/*.ts',
|
|
1400
|
+
* path: './src'
|
|
1401
|
+
* })
|
|
1402
|
+
* ```
|
|
1403
|
+
*/
|
|
1404
|
+
declare class GlobTool extends BaseTool {
|
|
1405
|
+
readonly name = "Glob";
|
|
1406
|
+
readonly description = "Fast file pattern matching tool that works with any codebase size.\n\nUsage notes:\n- Supports glob patterns like \"**/*.js\" or \"src/**/*.ts\"\n- Returns matching file paths sorted by modification time (newest first)\n- Use this tool when you need to find files by name patterns\n- You can call multiple tools in a single response for parallel searches\n\nSupported patterns:\n- `*` matches any sequence of characters except path separator\n- `**` matches any sequence of characters including path separator\n- `?` matches any single character\n- `{a,b}` matches either a or b\n- `[abc]` matches any character in brackets";
|
|
1407
|
+
readonly parameters: ToolInputSchema;
|
|
1408
|
+
/** Current working directory for search */
|
|
1409
|
+
private cwd;
|
|
1410
|
+
constructor(options?: {
|
|
1411
|
+
cwd?: string;
|
|
1412
|
+
});
|
|
1413
|
+
/**
|
|
1414
|
+
* Set the current working directory
|
|
1415
|
+
*/
|
|
1416
|
+
setCwd(cwd: string): void;
|
|
1417
|
+
/**
|
|
1418
|
+
* Get the current working directory
|
|
1419
|
+
*/
|
|
1420
|
+
getCwd(): string;
|
|
1421
|
+
/**
|
|
1422
|
+
* Execute glob pattern matching
|
|
1423
|
+
*
|
|
1424
|
+
* @param args - Glob arguments
|
|
1425
|
+
* @returns MCP-compliant CallToolResult with matching files
|
|
1426
|
+
*/
|
|
1427
|
+
execute(args: Record<string, unknown>): Promise<CallToolResult>;
|
|
1428
|
+
/**
|
|
1429
|
+
* Validate and parse arguments
|
|
1430
|
+
*/
|
|
1431
|
+
private validateArgs;
|
|
1432
|
+
/**
|
|
1433
|
+
* Recursively walk directory and collect matching files
|
|
1434
|
+
*/
|
|
1435
|
+
private walkDirectory;
|
|
1436
|
+
}
|
|
1437
|
+
//#endregion
|
|
1438
|
+
//#region src/tool/builtin/grep.d.ts
|
|
1439
|
+
/**
|
|
1440
|
+
* Output modes for grep results
|
|
1441
|
+
*/
|
|
1442
|
+
type GrepOutputMode = 'content' | 'files_with_matches' | 'count';
|
|
1443
|
+
/**
|
|
1444
|
+
* Result of a grep operation
|
|
1445
|
+
*/
|
|
1446
|
+
interface GrepResult {
|
|
1447
|
+
/** Command exit code */
|
|
1448
|
+
exitCode: number | null;
|
|
1449
|
+
/** Backend used for the search */
|
|
1450
|
+
engine?: 'rg' | 'grep';
|
|
1451
|
+
/** Search output */
|
|
1452
|
+
output: string;
|
|
1453
|
+
/** Whether output was truncated */
|
|
1454
|
+
truncated: boolean;
|
|
1455
|
+
/** Whether search timed out */
|
|
1456
|
+
timedOut: boolean;
|
|
1457
|
+
/** Number of matches found (when available) */
|
|
1458
|
+
matchCount?: number;
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Arguments for the Grep tool
|
|
1462
|
+
*/
|
|
1463
|
+
interface GrepArgs {
|
|
1464
|
+
/** The regular expression pattern to search for */
|
|
1465
|
+
pattern: string;
|
|
1466
|
+
/** File or directory to search in */
|
|
1467
|
+
path?: string;
|
|
1468
|
+
/** Glob pattern to filter files */
|
|
1469
|
+
glob?: string;
|
|
1470
|
+
/** Output mode */
|
|
1471
|
+
output_mode?: GrepOutputMode;
|
|
1472
|
+
/** Lines before match */
|
|
1473
|
+
'-B'?: number;
|
|
1474
|
+
/** Lines after match */
|
|
1475
|
+
'-A'?: number;
|
|
1476
|
+
/** Lines before and after match */
|
|
1477
|
+
'-C'?: number;
|
|
1478
|
+
/** Show line numbers */
|
|
1479
|
+
'-n'?: boolean;
|
|
1480
|
+
/** Case insensitive search */
|
|
1481
|
+
'-i'?: boolean;
|
|
1482
|
+
/** File type to search */
|
|
1483
|
+
type?: string;
|
|
1484
|
+
/** Limit output to first N lines/entries */
|
|
1485
|
+
head_limit?: number;
|
|
1486
|
+
/** Skip first N lines/entries */
|
|
1487
|
+
offset?: number;
|
|
1488
|
+
/** Enable multiline mode */
|
|
1489
|
+
multiline?: boolean;
|
|
1490
|
+
}
|
|
1491
|
+
/**
|
|
1492
|
+
* Tool for searching files using ripgrep.
|
|
1493
|
+
*
|
|
1494
|
+
* A powerful search tool built on ripgrep that supports regex patterns,
|
|
1495
|
+
* multiple output modes, and various filtering options.
|
|
1496
|
+
*
|
|
1497
|
+
* @example
|
|
1498
|
+
* ```typescript
|
|
1499
|
+
* const grepTool = new GrepTool()
|
|
1500
|
+
* const result = await grepTool.execute({
|
|
1501
|
+
* pattern: 'function\\s+\\w+',
|
|
1502
|
+
* path: './src',
|
|
1503
|
+
* type: 'ts'
|
|
1504
|
+
* })
|
|
1505
|
+
* ```
|
|
1506
|
+
*/
|
|
1507
|
+
declare class GrepTool extends BaseTool {
|
|
1508
|
+
readonly name = "Grep";
|
|
1509
|
+
readonly description = "A powerful search tool built on ripgrep.\n\nUsage notes:\n- Supports full regex syntax (e.g., \"log.*Error\", \"function\\s+\\w+\")\n- Filter files with glob parameter (e.g., \"*.js\", \"**/*.tsx\") or type parameter (e.g., \"js\", \"py\", \"rust\")\n- Output modes: \"content\" shows matching lines, \"files_with_matches\" shows only file paths (default), \"count\" shows match counts\n- Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use `interface\\{\\}` to find `interface{}` in Go code)\n- Multiline matching: By default patterns match within single lines only. For cross-line patterns, use multiline: true";
|
|
1510
|
+
readonly parameters: ToolInputSchema;
|
|
1511
|
+
/** Current working directory for search */
|
|
1512
|
+
private cwd;
|
|
1513
|
+
/** Path to ripgrep binary */
|
|
1514
|
+
private rgPath;
|
|
1515
|
+
constructor(options?: {
|
|
1516
|
+
cwd?: string;
|
|
1517
|
+
rgPath?: string;
|
|
1518
|
+
});
|
|
1519
|
+
/**
|
|
1520
|
+
* Set the current working directory
|
|
1521
|
+
*/
|
|
1522
|
+
setCwd(cwd: string): void;
|
|
1523
|
+
/**
|
|
1524
|
+
* Get the current working directory
|
|
1525
|
+
*/
|
|
1526
|
+
getCwd(): string;
|
|
1527
|
+
/**
|
|
1528
|
+
* Execute grep search
|
|
1529
|
+
*
|
|
1530
|
+
* @param args - Grep arguments
|
|
1531
|
+
* @returns MCP-compliant CallToolResult with search results
|
|
1532
|
+
*/
|
|
1533
|
+
execute(args: Record<string, unknown>): Promise<CallToolResult>;
|
|
1534
|
+
/**
|
|
1535
|
+
* Validate and parse arguments
|
|
1536
|
+
*/
|
|
1537
|
+
private validateArgs;
|
|
1538
|
+
/**
|
|
1539
|
+
* Build ripgrep command arguments
|
|
1540
|
+
*/
|
|
1541
|
+
private buildRgArgs;
|
|
1542
|
+
/**
|
|
1543
|
+
* Run ripgrep command
|
|
1544
|
+
*/
|
|
1545
|
+
private runRipgrep;
|
|
1546
|
+
private runSystemGrep;
|
|
1547
|
+
}
|
|
1548
|
+
//#endregion
|
|
1549
|
+
//#region src/tool/builtin/read.d.ts
|
|
1550
|
+
/**
|
|
1551
|
+
* Result of a file read operation
|
|
1552
|
+
*/
|
|
1553
|
+
interface ReadResult {
|
|
1554
|
+
/** File content with line numbers */
|
|
1555
|
+
content: string;
|
|
1556
|
+
/** Total number of lines in file */
|
|
1557
|
+
totalLines: number;
|
|
1558
|
+
/** Number of lines returned */
|
|
1559
|
+
linesReturned: number;
|
|
1560
|
+
/** Starting line number (1-based) */
|
|
1561
|
+
startLine: number;
|
|
1562
|
+
/** Whether any lines were truncated */
|
|
1563
|
+
truncated: boolean;
|
|
1564
|
+
/** File size in bytes */
|
|
1565
|
+
fileSize: number;
|
|
1566
|
+
/** Whether this is a binary/image file */
|
|
1567
|
+
isBinary: boolean;
|
|
1568
|
+
/** MIME type if detected */
|
|
1569
|
+
mimeType?: string;
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Arguments for the Read tool
|
|
1573
|
+
*/
|
|
1574
|
+
interface ReadArgs {
|
|
1575
|
+
/** The absolute path to the file to read */
|
|
1576
|
+
file_path: string;
|
|
1577
|
+
/** The line number to start reading from (1-based) */
|
|
1578
|
+
offset?: number;
|
|
1579
|
+
/** The number of lines to read */
|
|
1580
|
+
limit?: number;
|
|
1581
|
+
}
|
|
1582
|
+
/**
|
|
1583
|
+
* Tool for reading files from the filesystem.
|
|
1584
|
+
*
|
|
1585
|
+
* This tool reads files with line number formatting, supporting
|
|
1586
|
+
* offset/limit for large files and detecting binary content.
|
|
1587
|
+
*
|
|
1588
|
+
* @example
|
|
1589
|
+
* ```typescript
|
|
1590
|
+
* const readTool = new ReadTool()
|
|
1591
|
+
* const result = await readTool.execute({
|
|
1592
|
+
* file_path: '/path/to/file.ts',
|
|
1593
|
+
* offset: 100,
|
|
1594
|
+
* limit: 50
|
|
1595
|
+
* })
|
|
1596
|
+
* ```
|
|
1597
|
+
*
|
|
1598
|
+
* @example Restrict reads to a specific directory
|
|
1599
|
+
* ```typescript
|
|
1600
|
+
* const readTool = new ReadTool({
|
|
1601
|
+
* cwd: '/app/output',
|
|
1602
|
+
* restrictToDirectory: true
|
|
1603
|
+
* })
|
|
1604
|
+
* // All paths will be resolved relative to /app/output
|
|
1605
|
+
* // Absolute paths and path traversal (../) will be blocked
|
|
1606
|
+
* ```
|
|
1607
|
+
*/
|
|
1608
|
+
declare class ReadTool extends BaseTool {
|
|
1609
|
+
readonly name = "Read";
|
|
1610
|
+
/** Current working directory for resolving relative paths */
|
|
1611
|
+
private _cwd;
|
|
1612
|
+
/** Allowed directory for file operations (if set, restricts reads to this directory) */
|
|
1613
|
+
private _allowedDirectory?;
|
|
1614
|
+
constructor(options?: {
|
|
1615
|
+
cwd?: string;
|
|
1616
|
+
/** If set, restricts all file reads to this directory. Paths outside will be rejected. */
|
|
1617
|
+
allowedDirectory?: string;
|
|
1618
|
+
});
|
|
1619
|
+
/**
|
|
1620
|
+
* Dynamic description that includes allowed directory info if configured
|
|
1621
|
+
*/
|
|
1622
|
+
get description(): string;
|
|
1623
|
+
/**
|
|
1624
|
+
* Dynamic parameters that include allowed directory info if configured
|
|
1625
|
+
*/
|
|
1626
|
+
get parameters(): ToolInputSchema;
|
|
1627
|
+
/**
|
|
1628
|
+
* Set the current working directory
|
|
1629
|
+
*/
|
|
1630
|
+
setCwd(cwd: string): void;
|
|
1631
|
+
/**
|
|
1632
|
+
* Get the current working directory
|
|
1633
|
+
*/
|
|
1634
|
+
getCwd(): string;
|
|
1635
|
+
/**
|
|
1636
|
+
* Set the allowed directory for file operations
|
|
1637
|
+
*/
|
|
1638
|
+
setAllowedDirectory(dir: string | undefined): void;
|
|
1639
|
+
/**
|
|
1640
|
+
* Get the allowed directory for file operations
|
|
1641
|
+
*/
|
|
1642
|
+
getAllowedDirectory(): string | undefined;
|
|
1643
|
+
/**
|
|
1644
|
+
* Execute file read
|
|
1645
|
+
*
|
|
1646
|
+
* @param args - Read arguments
|
|
1647
|
+
* @returns MCP-compliant CallToolResult with file content
|
|
1648
|
+
*/
|
|
1649
|
+
execute(args: Record<string, unknown>): Promise<CallToolResult>;
|
|
1650
|
+
/**
|
|
1651
|
+
* Validate and parse arguments
|
|
1652
|
+
*/
|
|
1653
|
+
private validateArgs;
|
|
1654
|
+
/**
|
|
1655
|
+
* Handle binary file (images, PDFs, etc.)
|
|
1656
|
+
*/
|
|
1657
|
+
private handleBinaryFile;
|
|
1658
|
+
/**
|
|
1659
|
+
* Handle Jupyter notebook file
|
|
1660
|
+
*/
|
|
1661
|
+
private handleJupyterNotebook;
|
|
1662
|
+
/**
|
|
1663
|
+
* Handle text file
|
|
1664
|
+
*/
|
|
1665
|
+
private handleTextFile;
|
|
1666
|
+
/**
|
|
1667
|
+
* Format output with line numbers and apply offset/limit
|
|
1668
|
+
*/
|
|
1669
|
+
private formatOutput;
|
|
1670
|
+
/**
|
|
1671
|
+
* Format file size for display
|
|
1672
|
+
*/
|
|
1673
|
+
private formatSize;
|
|
1674
|
+
}
|
|
1675
|
+
//#endregion
|
|
1676
|
+
//#region src/tool/builtin/edit.d.ts
|
|
1677
|
+
/**
|
|
1678
|
+
* Result of an edit operation
|
|
1679
|
+
*/
|
|
1680
|
+
interface EditResult {
|
|
1681
|
+
/** Whether the edit was successful */
|
|
1682
|
+
success: boolean;
|
|
1683
|
+
/** Number of replacements made */
|
|
1684
|
+
replacements: number;
|
|
1685
|
+
/** File path that was edited */
|
|
1686
|
+
filePath: string;
|
|
1687
|
+
/** Brief description of the edit */
|
|
1688
|
+
message: string;
|
|
1689
|
+
}
|
|
1690
|
+
/**
|
|
1691
|
+
* Arguments for the Edit tool
|
|
1692
|
+
*/
|
|
1693
|
+
interface EditArgs {
|
|
1694
|
+
/** The absolute path to the file to modify */
|
|
1695
|
+
file_path: string;
|
|
1696
|
+
/** The text to replace */
|
|
1697
|
+
old_string: string;
|
|
1698
|
+
/** The text to replace it with */
|
|
1699
|
+
new_string: string;
|
|
1700
|
+
/** Replace all occurrences (default false) */
|
|
1701
|
+
replace_all?: boolean;
|
|
1702
|
+
}
|
|
1703
|
+
/**
|
|
1704
|
+
* Tool for performing exact string replacements in files.
|
|
1705
|
+
*
|
|
1706
|
+
* This tool finds and replaces text in files with careful handling
|
|
1707
|
+
* of unique matches and the option to replace all occurrences.
|
|
1708
|
+
*
|
|
1709
|
+
* @example
|
|
1710
|
+
* ```typescript
|
|
1711
|
+
* const editTool = new EditTool()
|
|
1712
|
+
* const result = await editTool.execute({
|
|
1713
|
+
* file_path: '/path/to/file.ts',
|
|
1714
|
+
* old_string: 'const foo = 1',
|
|
1715
|
+
* new_string: 'const foo = 2'
|
|
1716
|
+
* })
|
|
1717
|
+
* ```
|
|
1718
|
+
*/
|
|
1719
|
+
declare class EditTool extends BaseTool {
|
|
1720
|
+
readonly name = "Edit";
|
|
1721
|
+
readonly riskLevel: "high";
|
|
1722
|
+
readonly description = "Performs exact string replacements in files.\n\nUsage notes:\n- When editing, preserve the exact indentation (tabs/spaces) from the original file\n- The edit will FAIL if old_string is not unique in the file unless replace_all is true\n- Use replace_all for replacing/renaming strings across the entire file\n- old_string and new_string must be different\n- ALWAYS prefer editing existing files over creating new ones";
|
|
1723
|
+
readonly parameters: ToolInputSchema;
|
|
1724
|
+
/** Current working directory for resolving relative paths */
|
|
1725
|
+
private cwd;
|
|
1726
|
+
constructor(options?: {
|
|
1727
|
+
cwd?: string;
|
|
1728
|
+
});
|
|
1729
|
+
/**
|
|
1730
|
+
* Set the current working directory
|
|
1731
|
+
*/
|
|
1732
|
+
setCwd(cwd: string): void;
|
|
1733
|
+
/**
|
|
1734
|
+
* Get the current working directory
|
|
1735
|
+
*/
|
|
1736
|
+
getCwd(): string;
|
|
1737
|
+
/**
|
|
1738
|
+
* Execute file edit
|
|
1739
|
+
*
|
|
1740
|
+
* @param args - Edit arguments
|
|
1741
|
+
* @returns MCP-compliant CallToolResult with edit details
|
|
1742
|
+
*/
|
|
1743
|
+
execute(args: Record<string, unknown>): Promise<CallToolResult>;
|
|
1744
|
+
/**
|
|
1745
|
+
* Validate and parse arguments
|
|
1746
|
+
*/
|
|
1747
|
+
private validateArgs;
|
|
1748
|
+
/**
|
|
1749
|
+
* Count occurrences of a substring in a string
|
|
1750
|
+
*/
|
|
1751
|
+
private countOccurrences;
|
|
1752
|
+
/**
|
|
1753
|
+
* Truncate string for error messages
|
|
1754
|
+
*/
|
|
1755
|
+
private truncateForError;
|
|
1756
|
+
}
|
|
1757
|
+
//#endregion
|
|
1758
|
+
//#region src/tool/builtin/write.d.ts
|
|
1759
|
+
/**
|
|
1760
|
+
* Result of a write operation
|
|
1761
|
+
*/
|
|
1762
|
+
interface WriteResult {
|
|
1763
|
+
/** Whether the write was successful */
|
|
1764
|
+
success: boolean;
|
|
1765
|
+
/** File path that was written */
|
|
1766
|
+
filePath: string;
|
|
1767
|
+
/** Number of bytes written */
|
|
1768
|
+
bytesWritten: number;
|
|
1769
|
+
/** Whether an existing file was overwritten */
|
|
1770
|
+
overwritten: boolean;
|
|
1771
|
+
/** Brief description of the operation */
|
|
1772
|
+
message: string;
|
|
1773
|
+
}
|
|
1774
|
+
/**
|
|
1775
|
+
* Arguments for the Write tool
|
|
1776
|
+
*/
|
|
1777
|
+
interface WriteArgs {
|
|
1778
|
+
/** The absolute path to the file to write */
|
|
1779
|
+
file_path: string;
|
|
1780
|
+
/** The content to write to the file */
|
|
1781
|
+
content: string;
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Tool for writing files to the filesystem.
|
|
1785
|
+
*
|
|
1786
|
+
* This tool creates or overwrites files with the specified content,
|
|
1787
|
+
* automatically creating parent directories if needed.
|
|
1788
|
+
*
|
|
1789
|
+
* @example
|
|
1790
|
+
* ```typescript
|
|
1791
|
+
* const writeTool = new WriteTool()
|
|
1792
|
+
* const result = await writeTool.execute({
|
|
1793
|
+
* file_path: '/path/to/file.ts',
|
|
1794
|
+
* content: 'export const foo = 1'
|
|
1795
|
+
* })
|
|
1796
|
+
* ```
|
|
1797
|
+
*
|
|
1798
|
+
* @example Restrict writes to a specific directory
|
|
1799
|
+
* ```typescript
|
|
1800
|
+
* const writeTool = new WriteTool({
|
|
1801
|
+
* cwd: '/app/output',
|
|
1802
|
+
* restrictToDirectory: true
|
|
1803
|
+
* })
|
|
1804
|
+
* // All paths will be resolved relative to /app/output
|
|
1805
|
+
* // Absolute paths and path traversal (../) will be blocked
|
|
1806
|
+
* ```
|
|
1807
|
+
*/
|
|
1808
|
+
declare class WriteTool extends BaseTool {
|
|
1809
|
+
readonly name = "Write";
|
|
1810
|
+
readonly riskLevel: "high";
|
|
1811
|
+
/** Current working directory for resolving relative paths */
|
|
1812
|
+
private _cwd;
|
|
1813
|
+
/** Allowed directory for file operations (if set, restricts writes to this directory) */
|
|
1814
|
+
private _allowedDirectory?;
|
|
1815
|
+
constructor(options?: {
|
|
1816
|
+
cwd?: string;
|
|
1817
|
+
/** If set, restricts all file writes to this directory. Paths outside will be rejected. */
|
|
1818
|
+
allowedDirectory?: string;
|
|
1819
|
+
});
|
|
1820
|
+
/**
|
|
1821
|
+
* Dynamic description that includes allowed directory info if configured
|
|
1822
|
+
*/
|
|
1823
|
+
get description(): string;
|
|
1824
|
+
/**
|
|
1825
|
+
* Dynamic parameters that include allowed directory info if configured
|
|
1826
|
+
*/
|
|
1827
|
+
get parameters(): ToolInputSchema;
|
|
1828
|
+
/**
|
|
1829
|
+
* Set the current working directory
|
|
1830
|
+
*/
|
|
1831
|
+
setCwd(cwd: string): void;
|
|
1832
|
+
/**
|
|
1833
|
+
* Get the current working directory
|
|
1834
|
+
*/
|
|
1835
|
+
getCwd(): string;
|
|
1836
|
+
/**
|
|
1837
|
+
* Set the allowed directory for file operations
|
|
1838
|
+
*/
|
|
1839
|
+
setAllowedDirectory(dir: string | undefined): void;
|
|
1840
|
+
/**
|
|
1841
|
+
* Get the allowed directory for file operations
|
|
1842
|
+
*/
|
|
1843
|
+
getAllowedDirectory(): string | undefined;
|
|
1844
|
+
/**
|
|
1845
|
+
* Execute file write
|
|
1846
|
+
*
|
|
1847
|
+
* @param args - Write arguments
|
|
1848
|
+
* @returns MCP-compliant CallToolResult with write details
|
|
1849
|
+
*/
|
|
1850
|
+
execute(args: Record<string, unknown>): Promise<CallToolResult>;
|
|
1851
|
+
/**
|
|
1852
|
+
* Validate and parse arguments
|
|
1853
|
+
*/
|
|
1854
|
+
private validateArgs;
|
|
1855
|
+
/**
|
|
1856
|
+
* Format file size for display
|
|
1857
|
+
*/
|
|
1858
|
+
private formatSize;
|
|
1859
|
+
}
|
|
1860
|
+
//#endregion
|
|
1861
|
+
//#region src/tool/builtin/webSearch.d.ts
|
|
1862
|
+
/**
|
|
1863
|
+
* A single search result item
|
|
1864
|
+
*/
|
|
1865
|
+
interface SearchResultItem {
|
|
1866
|
+
/** Result title */
|
|
1867
|
+
title: string;
|
|
1868
|
+
/** Result URL */
|
|
1869
|
+
link: string;
|
|
1870
|
+
/** Result snippet/description */
|
|
1871
|
+
snippet: string;
|
|
1872
|
+
/** Position in search results */
|
|
1873
|
+
position: number;
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Result of a web search operation
|
|
1877
|
+
*/
|
|
1878
|
+
interface WebSearchResult {
|
|
1879
|
+
/** Whether the search was successful */
|
|
1880
|
+
success: boolean;
|
|
1881
|
+
/** The search query used */
|
|
1882
|
+
query: string;
|
|
1883
|
+
/** List of search results */
|
|
1884
|
+
results: SearchResultItem[];
|
|
1885
|
+
/** Total number of results found */
|
|
1886
|
+
totalResults: number;
|
|
1887
|
+
/** Formatted markdown content with sources */
|
|
1888
|
+
markdown: string;
|
|
1889
|
+
/** Error message if search failed */
|
|
1890
|
+
error?: string;
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Arguments for the WebSearch tool
|
|
1894
|
+
*/
|
|
1895
|
+
interface WebSearchArgs {
|
|
1896
|
+
/** The search query to use */
|
|
1897
|
+
query: string;
|
|
1898
|
+
}
|
|
1899
|
+
/**
|
|
1900
|
+
* Tool for searching the web using Serper API.
|
|
1901
|
+
*
|
|
1902
|
+
* This tool allows the agent to search the web and use the results
|
|
1903
|
+
* to inform responses with up-to-date information.
|
|
1904
|
+
*
|
|
1905
|
+
* @example
|
|
1906
|
+
* ```typescript
|
|
1907
|
+
* const webSearchTool = new WebSearchTool({ apiKey: 'your-serper-api-key' })
|
|
1908
|
+
* const result = await webSearchTool.execute({
|
|
1909
|
+
* query: 'latest TypeScript features 2025'
|
|
1910
|
+
* })
|
|
1911
|
+
* ```
|
|
1912
|
+
*/
|
|
1913
|
+
declare class WebSearchTool extends BaseTool {
|
|
1914
|
+
readonly name = "WebSearch";
|
|
1915
|
+
readonly description = "Allows the agent to search the web and use the results to inform responses.\n\nUsage notes:\n- Provides up-to-date information for current events and recent data\n- Returns search results with titles, links, and snippets\n- Use this tool for accessing information beyond the knowledge cutoff\n- After answering, include a \"Sources:\" section with relevant URLs as markdown hyperlinks";
|
|
1916
|
+
readonly parameters: ToolInputSchema;
|
|
1917
|
+
/** Serper API key */
|
|
1918
|
+
private apiKey;
|
|
1919
|
+
/** Serper API endpoint */
|
|
1920
|
+
private apiEndpoint;
|
|
1921
|
+
/** Number of results to return */
|
|
1922
|
+
private numResults;
|
|
1923
|
+
constructor(options?: {
|
|
1924
|
+
apiKey?: string;
|
|
1925
|
+
apiEndpoint?: string;
|
|
1926
|
+
numResults?: number;
|
|
1927
|
+
});
|
|
1928
|
+
/**
|
|
1929
|
+
* Set API key
|
|
1930
|
+
*/
|
|
1931
|
+
setApiKey(apiKey: string): void;
|
|
1932
|
+
/**
|
|
1933
|
+
* Execute web search
|
|
1934
|
+
*
|
|
1935
|
+
* @param args - WebSearch arguments
|
|
1936
|
+
* @returns MCP-compliant CallToolResult with search results
|
|
1937
|
+
*/
|
|
1938
|
+
execute(args: Record<string, unknown>): Promise<CallToolResult>;
|
|
1939
|
+
/**
|
|
1940
|
+
* Validate and parse arguments
|
|
1941
|
+
*/
|
|
1942
|
+
private validateArgs;
|
|
1943
|
+
/**
|
|
1944
|
+
* Format search results as markdown
|
|
1945
|
+
*/
|
|
1946
|
+
private formatMarkdown;
|
|
1947
|
+
}
|
|
1948
|
+
//#endregion
|
|
1949
|
+
//#region src/tool/registry.d.ts
|
|
1950
|
+
/**
|
|
1951
|
+
* Registry for managing tools.
|
|
1952
|
+
*
|
|
1953
|
+
* Provides methods to register, unregister, and look up tools,
|
|
1954
|
+
* as well as convert to OpenAI-compatible format.
|
|
1955
|
+
*/
|
|
1956
|
+
declare class ToolRegistry {
|
|
1957
|
+
private tools;
|
|
1958
|
+
/**
|
|
1959
|
+
* Register a tool
|
|
1960
|
+
*
|
|
1961
|
+
* @param tool - Tool to register
|
|
1962
|
+
* @throws Error if tool with same name already exists
|
|
1963
|
+
*/
|
|
1964
|
+
register(tool: BaseTool): void;
|
|
1965
|
+
/**
|
|
1966
|
+
* Unregister a tool by name
|
|
1967
|
+
*
|
|
1968
|
+
* @param name - Name of tool to remove
|
|
1969
|
+
* @returns true if tool was found and removed
|
|
1970
|
+
*/
|
|
1971
|
+
unregister(name: string): boolean;
|
|
1972
|
+
/**
|
|
1973
|
+
* Get a tool by name
|
|
1974
|
+
*
|
|
1975
|
+
* @param name - Tool name
|
|
1976
|
+
* @returns Tool instance or undefined if not found
|
|
1977
|
+
*/
|
|
1978
|
+
get(name: string): BaseTool | undefined;
|
|
1979
|
+
/**
|
|
1980
|
+
* List all registered tools
|
|
1981
|
+
*
|
|
1982
|
+
* @returns Array of all tools
|
|
1983
|
+
*/
|
|
1984
|
+
list(): BaseTool[];
|
|
1985
|
+
/**
|
|
1986
|
+
* Check if a tool is registered
|
|
1987
|
+
*
|
|
1988
|
+
* @param name - Tool name
|
|
1989
|
+
* @returns true if tool exists
|
|
1990
|
+
*/
|
|
1991
|
+
has(name: string): boolean;
|
|
1992
|
+
/**
|
|
1993
|
+
* Get count of registered tools
|
|
1994
|
+
*/
|
|
1995
|
+
get size(): number;
|
|
1996
|
+
/**
|
|
1997
|
+
* Convert all tools to OpenAI-compatible format
|
|
1998
|
+
*
|
|
1999
|
+
* @returns Array of tools in OpenAI function calling format
|
|
2000
|
+
*/
|
|
2001
|
+
toOpenAIFormat(): OpenAITool[];
|
|
2002
|
+
}
|
|
2003
|
+
//#endregion
|
|
2004
|
+
//#region src/agent/types.d.ts
|
|
2005
|
+
/**
|
|
2006
|
+
* Tool call with execution result
|
|
2007
|
+
*/
|
|
2008
|
+
interface ToolCallWithResult {
|
|
2009
|
+
/**
|
|
2010
|
+
* Original tool call from the LLM
|
|
2011
|
+
*/
|
|
2012
|
+
toolCall: ToolCall;
|
|
2013
|
+
/**
|
|
2014
|
+
* Execution result (undefined if not yet executed)
|
|
2015
|
+
*/
|
|
2016
|
+
result?: unknown;
|
|
2017
|
+
/**
|
|
2018
|
+
* Whether the execution resulted in an error
|
|
2019
|
+
*/
|
|
2020
|
+
isError?: boolean;
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* Agent Loop State - the runtime state that flows through the agent loop.
|
|
2024
|
+
*
|
|
2025
|
+
* This is the core state object that gets passed between loop iterations,
|
|
2026
|
+
* hooks, and middlewares. It contains everything needed to:
|
|
2027
|
+
* - Continue the conversation
|
|
2028
|
+
* - Execute pending tool calls
|
|
2029
|
+
* - Track progress and prevent infinite loops
|
|
2030
|
+
* - Accumulate the final response
|
|
2031
|
+
*/
|
|
2032
|
+
interface AgentLoopState {
|
|
2033
|
+
/**
|
|
2034
|
+
* Session ID for this execution
|
|
2035
|
+
*/
|
|
2036
|
+
sessionId: string;
|
|
2037
|
+
/**
|
|
2038
|
+
* Agent ID
|
|
2039
|
+
*/
|
|
2040
|
+
agentId: string;
|
|
2041
|
+
/**
|
|
2042
|
+
* Full message history including system, user, assistant, and tool messages.
|
|
2043
|
+
* This is the primary state that gets updated each iteration.
|
|
2044
|
+
*/
|
|
2045
|
+
messages: Message[];
|
|
2046
|
+
/**
|
|
2047
|
+
* Current loop iteration (0-indexed).
|
|
2048
|
+
* Used for max iterations check and debugging.
|
|
2049
|
+
*/
|
|
2050
|
+
iteration: number;
|
|
2051
|
+
/**
|
|
2052
|
+
* Pending tool calls from the current LLM response.
|
|
2053
|
+
* These need to be executed before the next iteration.
|
|
2054
|
+
*/
|
|
2055
|
+
pendingToolCalls: ToolCallWithResult[];
|
|
2056
|
+
/**
|
|
2057
|
+
* Text response accumulated so far in the current iteration.
|
|
2058
|
+
*/
|
|
2059
|
+
currentResponse: string;
|
|
2060
|
+
/**
|
|
2061
|
+
* Thinking/reasoning content from the current iteration (if model supports it).
|
|
2062
|
+
*/
|
|
2063
|
+
currentThinking?: string;
|
|
2064
|
+
/**
|
|
2065
|
+
* Whether the loop should continue.
|
|
2066
|
+
* Set to false when:
|
|
2067
|
+
* - LLM returns a final response without tool calls
|
|
2068
|
+
* - Max iterations reached
|
|
2069
|
+
* - An error occurs (depending on error handling strategy)
|
|
2070
|
+
* - Explicitly stopped by a hook
|
|
2071
|
+
*/
|
|
2072
|
+
shouldContinue: boolean;
|
|
2073
|
+
/**
|
|
2074
|
+
* Stop reason for debugging/logging.
|
|
2075
|
+
*/
|
|
2076
|
+
stopReason?: 'max_iterations' | 'final_response' | 'error' | 'cancelled' | 'hook_stopped';
|
|
2077
|
+
/**
|
|
2078
|
+
* The stop reason reported by the most recent model call (if available).
|
|
2079
|
+
*
|
|
2080
|
+
* Useful for debugging truncated outputs (e.g. `length`) vs normal completion (`final`).
|
|
2081
|
+
*/
|
|
2082
|
+
lastModelStopReason?: ModelStopReason;
|
|
2083
|
+
/**
|
|
2084
|
+
* Cumulative token usage across all iterations.
|
|
2085
|
+
*/
|
|
2086
|
+
usage: Usage;
|
|
2087
|
+
/**
|
|
2088
|
+
* Last error encountered (if any).
|
|
2089
|
+
*/
|
|
2090
|
+
error?: Error;
|
|
2091
|
+
/**
|
|
2092
|
+
* Custom metadata for hooks and middlewares.
|
|
2093
|
+
* Use this to pass data between different stages of the loop.
|
|
2094
|
+
*/
|
|
2095
|
+
metadata: Record<string, unknown>;
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* Create initial AgentLoopState from AgentInput
|
|
2099
|
+
*/
|
|
2100
|
+
declare function createInitialLoopState(input: AgentInput<any>, agentId: string, systemPrompt: string): AgentLoopState;
|
|
2101
|
+
/**
|
|
2102
|
+
* Input for agent execution that starts from an existing message history.
|
|
2103
|
+
*
|
|
2104
|
+
* Unlike {@link AgentInput}, this does not append a new user message.
|
|
2105
|
+
* This is useful for "handoff" style orchestration where a different agent
|
|
2106
|
+
* should continue from the same conversation state (with a new system prompt).
|
|
2107
|
+
*/
|
|
2108
|
+
interface AgentInputFromMessages<TContext = unknown> extends Omit<AgentInput<TContext>, 'input' | 'messages'> {
|
|
2109
|
+
/**
|
|
2110
|
+
* Full conversation history to continue from (system messages will be ignored).
|
|
2111
|
+
*/
|
|
2112
|
+
messages: Message[];
|
|
2113
|
+
}
|
|
2114
|
+
/**
|
|
2115
|
+
* Create initial AgentLoopState from an existing message history (no new user message appended).
|
|
2116
|
+
*/
|
|
2117
|
+
declare function createInitialLoopStateFromMessages(input: AgentInputFromMessages<any>, agentId: string, systemPrompt: string): AgentLoopState;
|
|
2118
|
+
/**
|
|
2119
|
+
* Options for creating an Agent
|
|
2120
|
+
*/
|
|
2121
|
+
interface AgentOptions {
|
|
2122
|
+
/**
|
|
2123
|
+
* Unique identifier for the agent (auto-generated if not provided)
|
|
2124
|
+
*/
|
|
2125
|
+
id?: string;
|
|
2126
|
+
/**
|
|
2127
|
+
* Human-readable name for the agent
|
|
2128
|
+
*/
|
|
2129
|
+
name: string;
|
|
2130
|
+
/**
|
|
2131
|
+
* System prompt that defines the agent's behavior
|
|
2132
|
+
*/
|
|
2133
|
+
systemPrompt: string;
|
|
2134
|
+
/**
|
|
2135
|
+
* LLM model to use
|
|
2136
|
+
*/
|
|
2137
|
+
model: ModelClient;
|
|
2138
|
+
/**
|
|
2139
|
+
* Tool registry (optional)
|
|
2140
|
+
*/
|
|
2141
|
+
tools?: ToolRegistry;
|
|
2142
|
+
/**
|
|
2143
|
+
* State storage backend (optional).
|
|
2144
|
+
*
|
|
2145
|
+
* When provided, the agent will automatically save checkpoints during execution,
|
|
2146
|
+
* allowing interrupted executions to be resumed. The store can also be used
|
|
2147
|
+
* by middlewares (like contextCompressionMiddleware) to persist their state.
|
|
2148
|
+
*
|
|
2149
|
+
* The state store contains its own configuration for when to save
|
|
2150
|
+
* (savePoint) and whether to delete on completion (deleteOnComplete).
|
|
2151
|
+
*/
|
|
2152
|
+
stateStore?: StateStore;
|
|
2153
|
+
/**
|
|
2154
|
+
* Session manager (optional)
|
|
2155
|
+
*/
|
|
2156
|
+
sessionManager?: BaseSessionManager;
|
|
2157
|
+
}
|
|
2158
|
+
/**
|
|
2159
|
+
* Input for agent execution
|
|
2160
|
+
*/
|
|
2161
|
+
interface AgentInput<TContext = unknown> {
|
|
2162
|
+
/**
|
|
2163
|
+
* Session ID for this execution
|
|
2164
|
+
*/
|
|
2165
|
+
sessionId: string;
|
|
2166
|
+
/**
|
|
2167
|
+
* User input message
|
|
2168
|
+
*/
|
|
2169
|
+
input: MessageContent;
|
|
2170
|
+
/**
|
|
2171
|
+
* Optional conversation history (caller manages this)
|
|
2172
|
+
*/
|
|
2173
|
+
messages?: Message[];
|
|
2174
|
+
/**
|
|
2175
|
+
* Optional model override for this execution.
|
|
2176
|
+
* If provided, this model will be used instead of the agent's default model.
|
|
2177
|
+
*
|
|
2178
|
+
* @example
|
|
2179
|
+
* ```ts
|
|
2180
|
+
* await agent.stream({
|
|
2181
|
+
* sessionId: 'xxx',
|
|
2182
|
+
* input: 'hello',
|
|
2183
|
+
* model: { provider: 'openai', modelId: 'gpt-4' }, // Use gpt-4 for this request only
|
|
2184
|
+
* })
|
|
2185
|
+
* ```
|
|
2186
|
+
*/
|
|
2187
|
+
model?: ModelRef;
|
|
2188
|
+
/**
|
|
2189
|
+
* AbortSignal for cancellation support.
|
|
2190
|
+
* When aborted, the agent loop will throw AgentAbortError.
|
|
2191
|
+
*/
|
|
2192
|
+
signal?: AbortSignal;
|
|
2193
|
+
/**
|
|
2194
|
+
* Maximum number of loop iterations (default: 10).
|
|
2195
|
+
* Prevents infinite loops when tools keep being called.
|
|
2196
|
+
*/
|
|
2197
|
+
maxIterations?: number;
|
|
2198
|
+
/**
|
|
2199
|
+
* Optional tool execution context input.
|
|
2200
|
+
*
|
|
2201
|
+
* Use this to inject capabilities (e.g. fetch/fs) and metadata.
|
|
2202
|
+
* Identity fields (sessionId/agentId) are filled by the Agent.
|
|
2203
|
+
*/
|
|
2204
|
+
toolContext?: ToolExecutionContextInput<TContext>;
|
|
2205
|
+
/**
|
|
2206
|
+
* Optional model request parameters (temperature, maxTokens, etc.).
|
|
2207
|
+
* These will be saved in checkpoints for resumption.
|
|
2208
|
+
*/
|
|
2209
|
+
requestParams?: CheckpointRequestParams;
|
|
2210
|
+
}
|
|
2211
|
+
/**
|
|
2212
|
+
* Input for agent execution that resumes from a saved checkpoint.
|
|
2213
|
+
*
|
|
2214
|
+
* Use this to resume interrupted executions from the exact state
|
|
2215
|
+
* where they were saved.
|
|
2216
|
+
*/
|
|
2217
|
+
interface AgentInputFromCheckpoint<TContext = unknown> {
|
|
2218
|
+
/**
|
|
2219
|
+
* Checkpoint to resume from
|
|
2220
|
+
*/
|
|
2221
|
+
checkpoint: AgentLoopCheckpoint;
|
|
2222
|
+
/**
|
|
2223
|
+
* Optional model override for this execution
|
|
2224
|
+
*/
|
|
2225
|
+
model?: ModelRef;
|
|
2226
|
+
/**
|
|
2227
|
+
* AbortSignal for cancellation support
|
|
2228
|
+
*/
|
|
2229
|
+
signal?: AbortSignal;
|
|
2230
|
+
/**
|
|
2231
|
+
* Maximum number of loop iterations (default: 10)
|
|
2232
|
+
*/
|
|
2233
|
+
maxIterations?: number;
|
|
2234
|
+
/**
|
|
2235
|
+
* Optional tool execution context input
|
|
2236
|
+
*/
|
|
2237
|
+
toolContext?: ToolExecutionContextInput<TContext>;
|
|
2238
|
+
/**
|
|
2239
|
+
* Optional model request parameters override.
|
|
2240
|
+
* If not provided, uses the params from the checkpoint.
|
|
2241
|
+
*/
|
|
2242
|
+
requestParams?: CheckpointRequestParams;
|
|
2243
|
+
}
|
|
2244
|
+
//#endregion
|
|
2245
|
+
//#region src/types/message.d.ts
|
|
2246
|
+
/**
|
|
2247
|
+
* Role types for messages
|
|
2248
|
+
*/
|
|
2249
|
+
type MessageRole = 'system' | 'user' | 'assistant' | 'tool';
|
|
2250
|
+
/**
|
|
2251
|
+
* System message for setting agent behavior
|
|
2252
|
+
*/
|
|
2253
|
+
interface SystemMessage {
|
|
2254
|
+
role: 'system';
|
|
2255
|
+
content: MessageContent;
|
|
2256
|
+
tools?: Tool[];
|
|
2257
|
+
}
|
|
2258
|
+
/**
|
|
2259
|
+
* User input message
|
|
2260
|
+
*/
|
|
2261
|
+
interface UserMessage {
|
|
2262
|
+
role: 'user';
|
|
2263
|
+
content: MessageContent;
|
|
2264
|
+
name?: string;
|
|
2265
|
+
}
|
|
2266
|
+
/**
|
|
2267
|
+
* Assistant response message
|
|
2268
|
+
*/
|
|
2269
|
+
interface AssistantMessage {
|
|
2270
|
+
role: 'assistant';
|
|
2271
|
+
content: MessageContent;
|
|
2272
|
+
reasoning_content?: string;
|
|
2273
|
+
tool_calls?: ToolCall[];
|
|
2274
|
+
}
|
|
2275
|
+
/**
|
|
2276
|
+
* Tool execution result message
|
|
2277
|
+
*/
|
|
2278
|
+
interface ToolMessage {
|
|
2279
|
+
role: 'tool';
|
|
2280
|
+
content: MessageContent;
|
|
2281
|
+
tool_call_id: string;
|
|
2282
|
+
name?: string;
|
|
2283
|
+
isError?: boolean;
|
|
2284
|
+
}
|
|
2285
|
+
/**
|
|
2286
|
+
* Union type for all message types
|
|
2287
|
+
*/
|
|
2288
|
+
type Message = SystemMessage | UserMessage | AssistantMessage | ToolMessage;
|
|
2289
|
+
//#endregion
|
|
2290
|
+
//#region src/types/snapshot.d.ts
|
|
2291
|
+
/**
|
|
2292
|
+
* Model configuration for snapshots (serializable)
|
|
2293
|
+
*/
|
|
2294
|
+
interface ModelConfig {
|
|
2295
|
+
/**
|
|
2296
|
+
* Model identifier (e.g., "gpt-4o", "claude-3-opus")
|
|
2297
|
+
*/
|
|
2298
|
+
modelId: string;
|
|
2299
|
+
/**
|
|
2300
|
+
* Provider name (e.g., "openai", "anthropic")
|
|
2301
|
+
*/
|
|
2302
|
+
provider?: string;
|
|
2303
|
+
/**
|
|
2304
|
+
* Model-specific configuration
|
|
2305
|
+
*/
|
|
2306
|
+
config?: Record<string, unknown>;
|
|
2307
|
+
}
|
|
2308
|
+
/**
|
|
2309
|
+
* Default chat options that can be configured at agent level
|
|
2310
|
+
*/
|
|
2311
|
+
interface DefaultChatOptions {
|
|
2312
|
+
/**
|
|
2313
|
+
* Temperature for response randomness (0-2)
|
|
2314
|
+
*/
|
|
2315
|
+
temperature?: number;
|
|
2316
|
+
/**
|
|
2317
|
+
* Maximum tokens to generate
|
|
2318
|
+
*/
|
|
2319
|
+
maxTokens?: number;
|
|
2320
|
+
/**
|
|
2321
|
+
* Stop sequences
|
|
2322
|
+
*/
|
|
2323
|
+
stop?: string[];
|
|
2324
|
+
}
|
|
2325
|
+
/**
|
|
2326
|
+
* Agent configuration (mutable settings)
|
|
2327
|
+
*/
|
|
2328
|
+
interface AgentConfig {
|
|
2329
|
+
/**
|
|
2330
|
+
* System prompt that defines the agent's behavior
|
|
2331
|
+
*/
|
|
2332
|
+
systemPrompt: string;
|
|
2333
|
+
/**
|
|
2334
|
+
* Current model configuration
|
|
2335
|
+
*/
|
|
2336
|
+
model: ModelConfig;
|
|
2337
|
+
/**
|
|
2338
|
+
* List of registered tool names
|
|
2339
|
+
*/
|
|
2340
|
+
tools: string[];
|
|
2341
|
+
/**
|
|
2342
|
+
* Default chat parameters
|
|
2343
|
+
*/
|
|
2344
|
+
defaultChatOptions?: DefaultChatOptions;
|
|
2345
|
+
}
|
|
2346
|
+
/**
|
|
2347
|
+
* Agent runtime statistics
|
|
2348
|
+
*/
|
|
2349
|
+
interface AgentStats {
|
|
2350
|
+
/**
|
|
2351
|
+
* Last update timestamp (ms)
|
|
2352
|
+
*/
|
|
2353
|
+
updatedAt: number;
|
|
2354
|
+
/**
|
|
2355
|
+
* Total number of sessions ever created
|
|
2356
|
+
*/
|
|
2357
|
+
totalSessions: number;
|
|
2358
|
+
/**
|
|
2359
|
+
* Number of currently active sessions
|
|
2360
|
+
*/
|
|
2361
|
+
activeSessions: number;
|
|
2362
|
+
/**
|
|
2363
|
+
* Cumulative token usage across all sessions
|
|
2364
|
+
*/
|
|
2365
|
+
totalUsage: {
|
|
2366
|
+
promptTokens: number;
|
|
2367
|
+
completionTokens: number;
|
|
2368
|
+
totalTokens: number;
|
|
2369
|
+
};
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* Complete Agent snapshot for serialization/persistence
|
|
2373
|
+
*/
|
|
2374
|
+
interface AgentSnapshot {
|
|
2375
|
+
/**
|
|
2376
|
+
* Unique agent identifier
|
|
2377
|
+
*/
|
|
2378
|
+
id: string;
|
|
2379
|
+
/**
|
|
2380
|
+
* Human-readable name
|
|
2381
|
+
*/
|
|
2382
|
+
name: string;
|
|
2383
|
+
/**
|
|
2384
|
+
* Creation timestamp (ms)
|
|
2385
|
+
*/
|
|
2386
|
+
createdAt: number;
|
|
2387
|
+
/**
|
|
2388
|
+
* Agent configuration
|
|
2389
|
+
*/
|
|
2390
|
+
config: AgentConfig;
|
|
2391
|
+
/**
|
|
2392
|
+
* Runtime statistics
|
|
2393
|
+
*/
|
|
2394
|
+
stats: AgentStats;
|
|
2395
|
+
/**
|
|
2396
|
+
* User-defined metadata
|
|
2397
|
+
*/
|
|
2398
|
+
metadata?: Record<string, unknown>;
|
|
2399
|
+
}
|
|
2400
|
+
/**
|
|
2401
|
+
* Session status
|
|
2402
|
+
*/
|
|
2403
|
+
type SessionStatus = 'active' | 'paused' | 'completed' | 'error' | 'archived';
|
|
2404
|
+
/**
|
|
2405
|
+
* Session state information
|
|
2406
|
+
*/
|
|
2407
|
+
interface SessionState {
|
|
2408
|
+
/**
|
|
2409
|
+
* Current session status
|
|
2410
|
+
*/
|
|
2411
|
+
status: SessionStatus;
|
|
2412
|
+
/**
|
|
2413
|
+
* Last update timestamp (ms)
|
|
2414
|
+
*/
|
|
2415
|
+
updatedAt: number;
|
|
2416
|
+
/**
|
|
2417
|
+
* Last activity timestamp (ms)
|
|
2418
|
+
*/
|
|
2419
|
+
lastActiveAt: number;
|
|
2420
|
+
/**
|
|
2421
|
+
* User-defined session title
|
|
2422
|
+
*/
|
|
2423
|
+
title?: string;
|
|
2424
|
+
/**
|
|
2425
|
+
* Error message if status is 'error'
|
|
2426
|
+
*/
|
|
2427
|
+
errorMessage?: string;
|
|
2428
|
+
}
|
|
2429
|
+
/**
|
|
2430
|
+
* Session-level configuration overrides
|
|
2431
|
+
* These override the parent agent's configuration for this session only
|
|
2432
|
+
*/
|
|
2433
|
+
interface SessionConfigOverride {
|
|
2434
|
+
/**
|
|
2435
|
+
* Override model for this session
|
|
2436
|
+
*/
|
|
2437
|
+
model?: ModelConfig;
|
|
2438
|
+
/**
|
|
2439
|
+
* Override system prompt for this session
|
|
2440
|
+
*/
|
|
2441
|
+
systemPromptOverride?: string;
|
|
2442
|
+
/**
|
|
2443
|
+
* Override chat options for this session
|
|
2444
|
+
*/
|
|
2445
|
+
chatOptions?: DefaultChatOptions;
|
|
2446
|
+
/**
|
|
2447
|
+
* Tools to disable for this session
|
|
2448
|
+
*/
|
|
2449
|
+
disabledTools?: string[];
|
|
2450
|
+
}
|
|
2451
|
+
/**
|
|
2452
|
+
* Conversation context containing message history
|
|
2453
|
+
*/
|
|
2454
|
+
interface ConversationContext {
|
|
2455
|
+
/**
|
|
2456
|
+
* Full message history
|
|
2457
|
+
*/
|
|
2458
|
+
messages: Message[];
|
|
2459
|
+
/**
|
|
2460
|
+
* Total message count
|
|
2461
|
+
*/
|
|
2462
|
+
messageCount: number;
|
|
2463
|
+
/**
|
|
2464
|
+
* Preview of the last message (for list display)
|
|
2465
|
+
*/
|
|
2466
|
+
lastMessagePreview?: string;
|
|
2467
|
+
/**
|
|
2468
|
+
* Number of tool calls made in this session
|
|
2469
|
+
*/
|
|
2470
|
+
toolCallCount: number;
|
|
2471
|
+
}
|
|
2472
|
+
/**
|
|
2473
|
+
* Session usage statistics
|
|
2474
|
+
*/
|
|
2475
|
+
interface SessionStats {
|
|
2476
|
+
/**
|
|
2477
|
+
* Token usage for this session
|
|
2478
|
+
*/
|
|
2479
|
+
usage: {
|
|
2480
|
+
promptTokens: number;
|
|
2481
|
+
completionTokens: number;
|
|
2482
|
+
totalTokens: number;
|
|
2483
|
+
};
|
|
2484
|
+
/**
|
|
2485
|
+
* Number of assistant responses
|
|
2486
|
+
*/
|
|
2487
|
+
responseCount: number;
|
|
2488
|
+
/**
|
|
2489
|
+
* Average response time in milliseconds
|
|
2490
|
+
*/
|
|
2491
|
+
avgResponseTime?: number;
|
|
2492
|
+
}
|
|
2493
|
+
/**
|
|
2494
|
+
* Complete Session snapshot for serialization/persistence
|
|
2495
|
+
*/
|
|
2496
|
+
interface SessionSnapshot {
|
|
2497
|
+
/**
|
|
2498
|
+
* Unique session identifier
|
|
2499
|
+
*/
|
|
2500
|
+
id: string;
|
|
2501
|
+
/**
|
|
2502
|
+
* Parent agent identifier
|
|
2503
|
+
*/
|
|
2504
|
+
agentId: string;
|
|
2505
|
+
/**
|
|
2506
|
+
* Creation timestamp (ms)
|
|
2507
|
+
*/
|
|
2508
|
+
createdAt: number;
|
|
2509
|
+
/**
|
|
2510
|
+
* Session state information
|
|
2511
|
+
*/
|
|
2512
|
+
state: SessionState;
|
|
2513
|
+
/**
|
|
2514
|
+
* Session-level configuration overrides
|
|
2515
|
+
*/
|
|
2516
|
+
configOverride?: SessionConfigOverride;
|
|
2517
|
+
/**
|
|
2518
|
+
* Conversation context with message history
|
|
2519
|
+
*/
|
|
2520
|
+
context: ConversationContext;
|
|
2521
|
+
/**
|
|
2522
|
+
* Usage statistics
|
|
2523
|
+
*/
|
|
2524
|
+
stats: SessionStats;
|
|
2525
|
+
/**
|
|
2526
|
+
* User-defined metadata
|
|
2527
|
+
*/
|
|
2528
|
+
metadata?: Record<string, unknown>;
|
|
2529
|
+
}
|
|
2530
|
+
/**
|
|
2531
|
+
* Model configuration stored in checkpoint (serializable)
|
|
2532
|
+
*/
|
|
2533
|
+
interface CheckpointModelConfig {
|
|
2534
|
+
/**
|
|
2535
|
+
* Model identifier (e.g., "gpt-4o", "claude-3-opus")
|
|
2536
|
+
*/
|
|
2537
|
+
modelId: string;
|
|
2538
|
+
/**
|
|
2539
|
+
* Provider name (e.g., "openai", "anthropic")
|
|
2540
|
+
*/
|
|
2541
|
+
provider?: string;
|
|
2542
|
+
/**
|
|
2543
|
+
* Model-specific configuration
|
|
2544
|
+
*/
|
|
2545
|
+
config?: Record<string, unknown>;
|
|
2546
|
+
}
|
|
2547
|
+
/**
|
|
2548
|
+
* Request parameters stored in checkpoint
|
|
2549
|
+
*/
|
|
2550
|
+
interface CheckpointRequestParams {
|
|
2551
|
+
/**
|
|
2552
|
+
* Temperature for response randomness
|
|
2553
|
+
*/
|
|
2554
|
+
temperature?: number;
|
|
2555
|
+
/**
|
|
2556
|
+
* Maximum tokens to generate
|
|
2557
|
+
*/
|
|
2558
|
+
maxTokens?: number;
|
|
2559
|
+
/**
|
|
2560
|
+
* Stop sequences
|
|
2561
|
+
*/
|
|
2562
|
+
stop?: string[];
|
|
2563
|
+
/**
|
|
2564
|
+
* Additional model-specific parameters
|
|
2565
|
+
*/
|
|
2566
|
+
[key: string]: unknown;
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Checkpoint of AgentLoopState for persistence and resumption.
|
|
2570
|
+
*
|
|
2571
|
+
* This captures the complete runtime state of an agent loop execution,
|
|
2572
|
+
* allowing it to be saved and restored for:
|
|
2573
|
+
* - Resuming interrupted executions
|
|
2574
|
+
* - Debugging and inspection
|
|
2575
|
+
* - Audit logging
|
|
2576
|
+
*/
|
|
2577
|
+
interface AgentLoopCheckpoint {
|
|
2578
|
+
/**
|
|
2579
|
+
* Session ID for this execution
|
|
2580
|
+
*/
|
|
2581
|
+
sessionId: string;
|
|
2582
|
+
/**
|
|
2583
|
+
* Agent ID
|
|
2584
|
+
*/
|
|
2585
|
+
agentId: string;
|
|
2586
|
+
/**
|
|
2587
|
+
* Agent name (for display purposes)
|
|
2588
|
+
*/
|
|
2589
|
+
agentName?: string;
|
|
2590
|
+
/**
|
|
2591
|
+
* Current loop iteration (0-indexed)
|
|
2592
|
+
*/
|
|
2593
|
+
iteration: number;
|
|
2594
|
+
/**
|
|
2595
|
+
* Current phase of execution
|
|
2596
|
+
*/
|
|
2597
|
+
phase?: 'llm_call' | 'tool_execution' | 'approval_pending' | 'completed';
|
|
2598
|
+
/**
|
|
2599
|
+
* Current status description (human readable)
|
|
2600
|
+
*/
|
|
2601
|
+
status?: string;
|
|
2602
|
+
/**
|
|
2603
|
+
* Model configuration at checkpoint time
|
|
2604
|
+
*/
|
|
2605
|
+
modelConfig?: CheckpointModelConfig;
|
|
2606
|
+
/**
|
|
2607
|
+
* Model request parameters at checkpoint time
|
|
2608
|
+
*/
|
|
2609
|
+
requestParams?: CheckpointRequestParams;
|
|
2610
|
+
/**
|
|
2611
|
+
* Full message history
|
|
2612
|
+
*/
|
|
2613
|
+
messages: Message[];
|
|
2614
|
+
/**
|
|
2615
|
+
* Pending tool calls (serialized)
|
|
2616
|
+
*/
|
|
2617
|
+
pendingToolCalls: ToolCallWithResult[];
|
|
2618
|
+
/**
|
|
2619
|
+
* Text response accumulated so far
|
|
2620
|
+
*/
|
|
2621
|
+
currentResponse: string;
|
|
2622
|
+
/**
|
|
2623
|
+
* Thinking/reasoning content (if any)
|
|
2624
|
+
*/
|
|
2625
|
+
currentThinking?: string;
|
|
2626
|
+
/**
|
|
2627
|
+
* Whether the loop should continue
|
|
2628
|
+
*/
|
|
2629
|
+
shouldContinue: boolean;
|
|
2630
|
+
/**
|
|
2631
|
+
* Stop reason (if stopped)
|
|
2632
|
+
*/
|
|
2633
|
+
stopReason?: 'max_iterations' | 'final_response' | 'error' | 'cancelled' | 'hook_stopped';
|
|
2634
|
+
/**
|
|
2635
|
+
* Stop reason reported by the last model call (if available).
|
|
2636
|
+
*/
|
|
2637
|
+
lastModelStopReason?: ModelStopReason;
|
|
2638
|
+
/**
|
|
2639
|
+
* Cumulative token usage
|
|
2640
|
+
*/
|
|
2641
|
+
usage: Usage;
|
|
2642
|
+
/**
|
|
2643
|
+
* Custom metadata
|
|
2644
|
+
*/
|
|
2645
|
+
metadata: Record<string, unknown>;
|
|
2646
|
+
/**
|
|
2647
|
+
* Timestamp when this checkpoint was saved (ms)
|
|
2648
|
+
*/
|
|
2649
|
+
savedAt: number;
|
|
2650
|
+
}
|
|
2651
|
+
//#endregion
|
|
2652
|
+
//#region src/types/event.d.ts
|
|
2653
|
+
/**
|
|
2654
|
+
* Event types for streaming responses
|
|
2655
|
+
*/
|
|
2656
|
+
type AgentEventType = 'text_delta' | 'tool_call_start' | 'tool_call_delta' | 'tool_call_end' | 'tool_result' | 'tool_approval_requested' | 'requires_action' | 'tool_skipped' | 'thinking_start' | 'thinking_delta' | 'thinking_end' | 'usage' | 'error' | 'done' | 'iteration_start' | 'iteration_end';
|
|
2657
|
+
/**
|
|
2658
|
+
* Base event interface
|
|
2659
|
+
*/
|
|
2660
|
+
interface BaseEvent {
|
|
2661
|
+
type: AgentEventType;
|
|
2662
|
+
}
|
|
2663
|
+
/**
|
|
2664
|
+
* Text delta event - partial text response
|
|
2665
|
+
*/
|
|
2666
|
+
interface TextDeltaEvent extends BaseEvent {
|
|
2667
|
+
type: 'text_delta';
|
|
2668
|
+
delta: string;
|
|
2669
|
+
}
|
|
2670
|
+
interface ToolCallStartEvent extends BaseEvent {
|
|
2671
|
+
type: 'tool_call_start';
|
|
2672
|
+
callId: string;
|
|
2673
|
+
toolName?: string;
|
|
2674
|
+
}
|
|
2675
|
+
interface ToolCallDeltaEvent extends BaseEvent {
|
|
2676
|
+
type: 'tool_call_delta';
|
|
2677
|
+
callId: string;
|
|
2678
|
+
toolName?: string;
|
|
2679
|
+
argsTextDelta?: string;
|
|
2680
|
+
}
|
|
2681
|
+
interface ToolCallEndEvent extends BaseEvent {
|
|
2682
|
+
type: 'tool_call_end';
|
|
2683
|
+
toolCall: ToolCall;
|
|
2684
|
+
}
|
|
2685
|
+
/**
|
|
2686
|
+
* Tool result event - tool execution completed
|
|
2687
|
+
*/
|
|
2688
|
+
interface ToolResultEvent extends BaseEvent {
|
|
2689
|
+
type: 'tool_result';
|
|
2690
|
+
tool_call_id: string;
|
|
2691
|
+
result: unknown;
|
|
2692
|
+
isError?: boolean;
|
|
2693
|
+
}
|
|
2694
|
+
/**
|
|
2695
|
+
* Tool approval requested event - emitted when a high-risk tool requires approval
|
|
2696
|
+
*/
|
|
2697
|
+
interface ToolApprovalRequestedEvent extends BaseEvent {
|
|
2698
|
+
type: 'tool_approval_requested';
|
|
2699
|
+
/** Tool call ID */
|
|
2700
|
+
tool_call_id: string;
|
|
2701
|
+
/** Name of the tool */
|
|
2702
|
+
toolName: string;
|
|
2703
|
+
/** Risk level of the tool */
|
|
2704
|
+
riskLevel: RiskLevel;
|
|
2705
|
+
/** Parsed arguments */
|
|
2706
|
+
args: Record<string, unknown>;
|
|
2707
|
+
}
|
|
2708
|
+
/**
|
|
2709
|
+
* Requires action event - execution is paused awaiting external input.
|
|
2710
|
+
*
|
|
2711
|
+
* This is designed for "pause → user decides → resume from checkpoint" flows.
|
|
2712
|
+
*/
|
|
2713
|
+
interface RequiresActionEvent extends BaseEvent {
|
|
2714
|
+
type: 'requires_action';
|
|
2715
|
+
kind: 'tool_approval';
|
|
2716
|
+
/** Tool call ID */
|
|
2717
|
+
tool_call_id: string;
|
|
2718
|
+
/** Name of the tool */
|
|
2719
|
+
toolName: string;
|
|
2720
|
+
/** Risk level of the tool */
|
|
2721
|
+
riskLevel: RiskLevel;
|
|
2722
|
+
/** Parsed arguments */
|
|
2723
|
+
args: Record<string, unknown>;
|
|
2724
|
+
/**
|
|
2725
|
+
* Checkpoint to resume from.
|
|
2726
|
+
* If a checkpoint store is configured, this may be omitted in favor of `checkpointRef`.
|
|
2727
|
+
*/
|
|
2728
|
+
checkpoint?: AgentLoopCheckpoint;
|
|
2729
|
+
/**
|
|
2730
|
+
* Reference for loading checkpoint from a store.
|
|
2731
|
+
*/
|
|
2732
|
+
checkpointRef?: {
|
|
2733
|
+
sessionId: string;
|
|
2734
|
+
agentId: string;
|
|
2735
|
+
};
|
|
2736
|
+
}
|
|
2737
|
+
/**
|
|
2738
|
+
* Tool skipped event - emitted when a tool execution is skipped (e.g., approval denied)
|
|
2739
|
+
*/
|
|
2740
|
+
interface ToolSkippedEvent extends BaseEvent {
|
|
2741
|
+
type: 'tool_skipped';
|
|
2742
|
+
/** Tool call ID */
|
|
2743
|
+
tool_call_id: string;
|
|
2744
|
+
/** Name of the tool */
|
|
2745
|
+
toolName: string;
|
|
2746
|
+
/** Reason for skipping */
|
|
2747
|
+
reason: string;
|
|
2748
|
+
}
|
|
2749
|
+
/**
|
|
2750
|
+
* Thinking start event - marks the beginning of a thinking phase
|
|
2751
|
+
*/
|
|
2752
|
+
interface ThinkingStartEvent extends BaseEvent {
|
|
2753
|
+
type: 'thinking_start';
|
|
2754
|
+
}
|
|
2755
|
+
/**
|
|
2756
|
+
* Thinking delta event - model's reasoning process (incremental)
|
|
2757
|
+
*/
|
|
2758
|
+
interface ThinkingDeltaEvent extends BaseEvent {
|
|
2759
|
+
type: 'thinking_delta';
|
|
2760
|
+
delta: string;
|
|
2761
|
+
}
|
|
2762
|
+
/**
|
|
2763
|
+
* Thinking end event - marks the end of a thinking phase
|
|
2764
|
+
*/
|
|
2765
|
+
interface ThinkingEndEvent extends BaseEvent {
|
|
2766
|
+
type: 'thinking_end';
|
|
2767
|
+
}
|
|
2768
|
+
/**
|
|
2769
|
+
* Usage event - token consumption
|
|
2770
|
+
*/
|
|
2771
|
+
interface UsageEvent extends BaseEvent {
|
|
2772
|
+
type: 'usage';
|
|
2773
|
+
usage: Usage;
|
|
2774
|
+
}
|
|
2775
|
+
/**
|
|
2776
|
+
* Error event - something went wrong
|
|
2777
|
+
*/
|
|
2778
|
+
interface ErrorEvent extends BaseEvent {
|
|
2779
|
+
type: 'error';
|
|
2780
|
+
error: Error;
|
|
2781
|
+
}
|
|
2782
|
+
/**
|
|
2783
|
+
* Done event - stream completed
|
|
2784
|
+
*/
|
|
2785
|
+
interface DoneEvent extends BaseEvent {
|
|
2786
|
+
type: 'done';
|
|
2787
|
+
/** Final accumulated response text */
|
|
2788
|
+
finalResponse?: string;
|
|
2789
|
+
/** Stop reason for the loop */
|
|
2790
|
+
stopReason?: 'max_iterations' | 'final_response' | 'error' | 'cancelled' | 'hook_stopped';
|
|
2791
|
+
/** Stop reason reported by the last model call (if available) */
|
|
2792
|
+
modelStopReason?: ModelStopReason;
|
|
2793
|
+
}
|
|
2794
|
+
/**
|
|
2795
|
+
* Iteration start event - beginning of a loop iteration
|
|
2796
|
+
*/
|
|
2797
|
+
interface IterationStartEvent extends BaseEvent {
|
|
2798
|
+
type: 'iteration_start';
|
|
2799
|
+
/** Current iteration number (0-indexed) */
|
|
2800
|
+
iteration: number;
|
|
2801
|
+
}
|
|
2802
|
+
/**
|
|
2803
|
+
* Iteration end event - end of a loop iteration
|
|
2804
|
+
*/
|
|
2805
|
+
interface IterationEndEvent extends BaseEvent {
|
|
2806
|
+
type: 'iteration_end';
|
|
2807
|
+
/** Current iteration number (0-indexed) */
|
|
2808
|
+
iteration: number;
|
|
2809
|
+
/** Whether the loop will continue to the next iteration */
|
|
2810
|
+
willContinue: boolean;
|
|
2811
|
+
/** Number of tool calls made in this iteration */
|
|
2812
|
+
toolCallCount: number;
|
|
2813
|
+
}
|
|
2814
|
+
/**
|
|
2815
|
+
* Union type for all agent events
|
|
2816
|
+
*/
|
|
2817
|
+
type AgentEvent = TextDeltaEvent | ToolCallStartEvent | ToolCallDeltaEvent | ToolCallEndEvent | ToolResultEvent | ToolApprovalRequestedEvent | RequiresActionEvent | ToolSkippedEvent | ThinkingStartEvent | ThinkingDeltaEvent | ThinkingEndEvent | UsageEvent | ErrorEvent | DoneEvent | IterationStartEvent | IterationEndEvent;
|
|
2818
|
+
//#endregion
|
|
2819
|
+
//#region src/model/base.d.ts
|
|
2820
|
+
/**
|
|
2821
|
+
* Abstract base class for LLM model providers.
|
|
2822
|
+
*
|
|
2823
|
+
* Implement this class to create custom model integrations
|
|
2824
|
+
* (e.g., OpenAI, Anthropic, local models).
|
|
2825
|
+
*/
|
|
2826
|
+
declare abstract class BaseModel {
|
|
2827
|
+
/**
|
|
2828
|
+
* Model identifier
|
|
2829
|
+
*/
|
|
2830
|
+
abstract readonly modelId: string;
|
|
2831
|
+
/**
|
|
2832
|
+
* One-shot completion.
|
|
2833
|
+
*
|
|
2834
|
+
* @param messages - Conversation history
|
|
2835
|
+
* @param options - Optional chat parameters
|
|
2836
|
+
* @returns Complete response with message and usage
|
|
2837
|
+
*/
|
|
2838
|
+
abstract invoke(messages: Message[], options?: ChatOptions): Promise<ChatResponse>;
|
|
2839
|
+
/**
|
|
2840
|
+
* Streaming completion.
|
|
2841
|
+
*
|
|
2842
|
+
* @param messages - Conversation history
|
|
2843
|
+
* @param options - Optional chat parameters
|
|
2844
|
+
* @returns Async iterable of stream events
|
|
2845
|
+
*/
|
|
2846
|
+
abstract stream(messages: Message[], options?: ChatOptions): AsyncIterable<StreamEvent>;
|
|
2847
|
+
}
|
|
2848
|
+
//#endregion
|
|
2849
|
+
//#region src/model/adapter.d.ts
|
|
2850
|
+
interface ModelAdapter {
|
|
2851
|
+
readonly provider: string;
|
|
2852
|
+
readonly defaultModelId?: string;
|
|
2853
|
+
getDefaultCapabilities?: (modelId: string) => Partial<CoreCapabilities>;
|
|
2854
|
+
supportsFeature?: (modelId: string, featureId: string) => boolean;
|
|
2855
|
+
stream: (args: {
|
|
2856
|
+
request: ModelRequest;
|
|
2857
|
+
featureGrants: FeatureGrants;
|
|
2858
|
+
featureRequests?: FeatureRequests;
|
|
2859
|
+
}) => AsyncIterable<ModelStreamEvent>;
|
|
2860
|
+
}
|
|
2861
|
+
//#endregion
|
|
2862
|
+
//#region src/model/utils/retry.d.ts
|
|
2863
|
+
/**
|
|
2864
|
+
* Retry strategies for calculating delay between attempts.
|
|
2865
|
+
*
|
|
2866
|
+
* - exponential: delay = base * 2^(attempt-1) — doubles each time (most common for APIs)
|
|
2867
|
+
* - linear: delay = base * attempt — increases linearly
|
|
2868
|
+
* - fixed: delay = base — constant delay
|
|
2869
|
+
*/
|
|
2870
|
+
type RetryStrategy = 'exponential' | 'linear' | 'fixed';
|
|
2871
|
+
/**
|
|
2872
|
+
* Jitter strategies to avoid thundering herd problem.
|
|
2873
|
+
*
|
|
2874
|
+
* - full: delay = random(0, calculatedDelay)
|
|
2875
|
+
* - equal: delay = calculatedDelay/2 + random(0, calculatedDelay/2)
|
|
2876
|
+
* - decorrelated: delay = random(base, previousDelay * 3) — AWS-style
|
|
2877
|
+
* - none: no jitter
|
|
2878
|
+
*/
|
|
2879
|
+
type JitterStrategy = 'full' | 'equal' | 'decorrelated' | 'none';
|
|
2880
|
+
interface RetryPolicyOptions {
|
|
2881
|
+
/**
|
|
2882
|
+
* Maximum number of attempts (including the first one).
|
|
2883
|
+
* @default 3
|
|
2884
|
+
*/
|
|
2885
|
+
maxAttempts?: number;
|
|
2886
|
+
/**
|
|
2887
|
+
* Base delay in milliseconds.
|
|
2888
|
+
* @default 500
|
|
2889
|
+
*/
|
|
2890
|
+
baseDelayMs?: number;
|
|
2891
|
+
/**
|
|
2892
|
+
* Maximum delay cap in milliseconds.
|
|
2893
|
+
* @default 30000
|
|
2894
|
+
*/
|
|
2895
|
+
maxDelayMs?: number;
|
|
2896
|
+
/**
|
|
2897
|
+
* Backoff strategy.
|
|
2898
|
+
* @default 'exponential'
|
|
2899
|
+
*/
|
|
2900
|
+
strategy?: RetryStrategy;
|
|
2901
|
+
/**
|
|
2902
|
+
* Jitter strategy to randomize delays.
|
|
2903
|
+
* @default 'equal'
|
|
2904
|
+
*/
|
|
2905
|
+
jitter?: JitterStrategy;
|
|
2906
|
+
/**
|
|
2907
|
+
* Multiplier for exponential/linear backoff.
|
|
2908
|
+
* For exponential: delay = base * multiplier^(attempt-1)
|
|
2909
|
+
* @default 2
|
|
2910
|
+
*/
|
|
2911
|
+
multiplier?: number;
|
|
2912
|
+
}
|
|
2913
|
+
/**
|
|
2914
|
+
* Retry policy for model requests with exponential backoff and jitter.
|
|
2915
|
+
*
|
|
2916
|
+
* Implements industry-standard retry patterns:
|
|
2917
|
+
* - Exponential backoff: prevents overwhelming recovering services
|
|
2918
|
+
* - Jitter: prevents thundering herd when many clients retry simultaneously
|
|
2919
|
+
* - Max delay cap: prevents unbounded wait times
|
|
2920
|
+
*
|
|
2921
|
+
* @example
|
|
2922
|
+
* ```ts
|
|
2923
|
+
* // Default: exponential backoff with equal jitter
|
|
2924
|
+
* const policy = new RetryPolicy()
|
|
2925
|
+
*
|
|
2926
|
+
* // Custom: 5 attempts, 1s base, 60s max, full jitter
|
|
2927
|
+
* const policy = new RetryPolicy({
|
|
2928
|
+
* maxAttempts: 5,
|
|
2929
|
+
* baseDelayMs: 1000,
|
|
2930
|
+
* maxDelayMs: 60000,
|
|
2931
|
+
* jitter: 'full',
|
|
2932
|
+
* })
|
|
2933
|
+
*
|
|
2934
|
+
* // Usage
|
|
2935
|
+
* for (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {
|
|
2936
|
+
* try {
|
|
2937
|
+
* await makeRequest()
|
|
2938
|
+
* break
|
|
2939
|
+
* } catch (err) {
|
|
2940
|
+
* if (!policy.canRetry(attempt)) throw err
|
|
2941
|
+
* await sleep(policy.getDelay(attempt))
|
|
2942
|
+
* }
|
|
2943
|
+
* }
|
|
2944
|
+
* ```
|
|
2945
|
+
*/
|
|
2946
|
+
declare class RetryPolicy {
|
|
2947
|
+
readonly maxAttempts: number;
|
|
2948
|
+
readonly baseDelayMs: number;
|
|
2949
|
+
readonly maxDelayMs: number;
|
|
2950
|
+
readonly strategy: RetryStrategy;
|
|
2951
|
+
readonly jitter: JitterStrategy;
|
|
2952
|
+
readonly multiplier: number;
|
|
2953
|
+
private _previousDelay;
|
|
2954
|
+
constructor(options?: RetryPolicyOptions);
|
|
2955
|
+
/**
|
|
2956
|
+
* Calculate delay for a given attempt.
|
|
2957
|
+
*
|
|
2958
|
+
* @param attempt - Current attempt number (1-indexed)
|
|
2959
|
+
* @returns Delay in milliseconds with jitter applied
|
|
2960
|
+
*/
|
|
2961
|
+
getDelay(attempt: number): number;
|
|
2962
|
+
/**
|
|
2963
|
+
* Apply jitter to the calculated delay.
|
|
2964
|
+
*/
|
|
2965
|
+
private applyJitter;
|
|
2966
|
+
/**
|
|
2967
|
+
* Check if another retry is allowed.
|
|
2968
|
+
*
|
|
2969
|
+
* @param attempt - Current attempt number (1-indexed)
|
|
2970
|
+
* @returns true if more retries are allowed
|
|
2971
|
+
*/
|
|
2972
|
+
canRetry(attempt: number): boolean;
|
|
2973
|
+
/**
|
|
2974
|
+
* Reset internal state (useful for decorrelated jitter).
|
|
2975
|
+
*/
|
|
2976
|
+
reset(): void;
|
|
2977
|
+
/**
|
|
2978
|
+
* Get a human-readable description of the policy.
|
|
2979
|
+
*/
|
|
2980
|
+
toString(): string;
|
|
2981
|
+
/**
|
|
2982
|
+
* Create default retry policy for API calls.
|
|
2983
|
+
* - 3 attempts
|
|
2984
|
+
* - 500ms base delay
|
|
2985
|
+
* - 30s max delay
|
|
2986
|
+
* - Exponential backoff with equal jitter
|
|
2987
|
+
*/
|
|
2988
|
+
static readonly default: RetryPolicy;
|
|
2989
|
+
/**
|
|
2990
|
+
* Create aggressive retry policy for critical operations.
|
|
2991
|
+
* - 5 attempts
|
|
2992
|
+
* - 1s base delay
|
|
2993
|
+
* - 60s max delay
|
|
2994
|
+
*/
|
|
2995
|
+
static readonly aggressive: RetryPolicy;
|
|
2996
|
+
/**
|
|
2997
|
+
* Create gentle retry policy for rate-limited APIs.
|
|
2998
|
+
* - 3 attempts
|
|
2999
|
+
* - 2s base delay
|
|
3000
|
+
* - 30s max delay
|
|
3001
|
+
* - Full jitter for better spread
|
|
3002
|
+
*/
|
|
3003
|
+
static readonly gentle: RetryPolicy;
|
|
3004
|
+
}
|
|
3005
|
+
//#endregion
|
|
3006
|
+
//#region src/model/health.d.ts
|
|
3007
|
+
/**
|
|
3008
|
+
* Health state for a single model.
|
|
3009
|
+
*/
|
|
3010
|
+
interface ModelHealthState {
|
|
3011
|
+
failures: number;
|
|
3012
|
+
nextRetryAt: number;
|
|
3013
|
+
lastError?: {
|
|
3014
|
+
code: string;
|
|
3015
|
+
message: string;
|
|
3016
|
+
};
|
|
3017
|
+
}
|
|
3018
|
+
/**
|
|
3019
|
+
* Model health manager.
|
|
3020
|
+
* Follows SRP: only handles health state tracking.
|
|
3021
|
+
*/
|
|
3022
|
+
declare class ModelHealth {
|
|
3023
|
+
private readonly state;
|
|
3024
|
+
get(ref: ModelRef): ModelHealthState;
|
|
3025
|
+
markSuccess(ref: ModelRef): void;
|
|
3026
|
+
markFailure(ref: ModelRef, options: {
|
|
3027
|
+
now: number;
|
|
3028
|
+
baseDelayMs: number;
|
|
3029
|
+
maxDelayMs: number;
|
|
3030
|
+
code: string;
|
|
3031
|
+
message: string;
|
|
3032
|
+
}): void;
|
|
3033
|
+
isAvailable(ref: ModelRef, now: number): boolean;
|
|
3034
|
+
private keyOf;
|
|
3035
|
+
}
|
|
3036
|
+
/**
|
|
3037
|
+
* In-memory implementation for backward compatibility.
|
|
3038
|
+
*/
|
|
3039
|
+
declare class InMemoryModelHealth extends ModelHealth {}
|
|
3040
|
+
//#endregion
|
|
3041
|
+
//#region src/model/errors.d.ts
|
|
3042
|
+
/**
|
|
3043
|
+
* Model error class.
|
|
3044
|
+
* Follows SRP: only handles error representation.
|
|
3045
|
+
*/
|
|
3046
|
+
declare class ModelError extends Error {
|
|
3047
|
+
readonly code: string;
|
|
3048
|
+
readonly retryable: boolean;
|
|
3049
|
+
readonly status?: number;
|
|
3050
|
+
constructor(message: string, options: {
|
|
3051
|
+
code: string;
|
|
3052
|
+
retryable?: boolean;
|
|
3053
|
+
status?: number;
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
//#endregion
|
|
3057
|
+
//#region src/model/createModel.d.ts
|
|
3058
|
+
/**
|
|
3059
|
+
* Model client returned by createModel with guaranteed setModelId method
|
|
3060
|
+
*/
|
|
3061
|
+
interface CreateModelResult extends Omit<ModelClient, 'setModelId'> {
|
|
3062
|
+
setModelId: (modelId: string) => void;
|
|
3063
|
+
}
|
|
3064
|
+
interface CreateModelOptions {
|
|
3065
|
+
/**
|
|
3066
|
+
* Provider adapters。
|
|
3067
|
+
*
|
|
3068
|
+
* 为什么是数组:
|
|
3069
|
+
* - 一个 `ModelClient` 通常需要同时支持多个 provider(openai/anthropic/...),因此需要"可插拔"的 adapter 列表。
|
|
3070
|
+
* - `createModel()` 会把它们按 `adapter.provider` 建索引,在路由/降级时根据 `ModelRef.provider` 选择对应 adapter。
|
|
3071
|
+
*
|
|
3072
|
+
* 约束:同一个 `provider` 只应出现一次(后者会覆盖前者的索引键)。
|
|
3073
|
+
*/
|
|
3074
|
+
adapters: ModelAdapter[];
|
|
3075
|
+
/**
|
|
3076
|
+
* 路由与降级策略。
|
|
3077
|
+
*
|
|
3078
|
+
* 作用:当调用方没有在 `client.stream/run({ model })` 明确指定模型时,`createModel()` 会:
|
|
3079
|
+
* - 根据 `fallbackOrder` 给出"尝试顺序"(primary + fallback)。
|
|
3080
|
+
* - 结合 `health`(熔断/退避窗口)跳过当前不可用的模型。
|
|
3081
|
+
* - 结合 `features` 里 `required:true` 的 feature 做硬筛选(必须满足才会尝试)。
|
|
3082
|
+
*
|
|
3083
|
+
* @remarks 如果不提供,会自动从 adapters 的 `defaultModelId` 推导。
|
|
3084
|
+
*/
|
|
3085
|
+
routing?: {
|
|
3086
|
+
/**
|
|
3087
|
+
* 候选模型的尝试顺序(从前到后)。
|
|
3088
|
+
*
|
|
3089
|
+
* - 当某个模型在本次尝试中失败(或被熔断判定暂不可用)时,会继续尝试下一个。
|
|
3090
|
+
* - 如果所有模型都失败,`createModel()` 会抛出最后一个错误。
|
|
3091
|
+
*/
|
|
3092
|
+
fallbackOrder: ModelRef[];
|
|
3093
|
+
};
|
|
3094
|
+
/**
|
|
3095
|
+
* 重试策略(可选)。
|
|
3096
|
+
*
|
|
3097
|
+
* 注意:这里是 "per-model 重试" —— 每个候选模型都会单独做最多 N 次重试;
|
|
3098
|
+
* 若该模型最终失败,会进入 `fallbackOrder` 的下一个模型。
|
|
3099
|
+
*
|
|
3100
|
+
* 支持 Exponential Backoff(指数退避)+ Jitter(随机抖动):
|
|
3101
|
+
* - 指数退避:防止压垮正在恢复的服务
|
|
3102
|
+
* - 随机抖动:防止多个客户端同时重试(雷群效应)
|
|
3103
|
+
*/
|
|
3104
|
+
retry?: {
|
|
3105
|
+
/**
|
|
3106
|
+
* 单个模型的最大尝试次数(包含第一次请求)。
|
|
3107
|
+
*
|
|
3108
|
+
* - 例如 `3` 表示:首次失败且可重试时,最多再重试 2 次。
|
|
3109
|
+
* - 仅当错误被判定为 `retryable`(见 `ModelError.retryable` / http 408/409/429/5xx 等)才会触发重试。
|
|
3110
|
+
* @default 3
|
|
3111
|
+
*/
|
|
3112
|
+
maxAttemptsPerModel?: number;
|
|
3113
|
+
/**
|
|
3114
|
+
* 重试基础延迟(毫秒)。
|
|
3115
|
+
* @default 500
|
|
3116
|
+
*/
|
|
3117
|
+
baseDelayMs?: number;
|
|
3118
|
+
/**
|
|
3119
|
+
* 最大退避延迟上限(毫秒)。
|
|
3120
|
+
* @default 30000
|
|
3121
|
+
*/
|
|
3122
|
+
maxDelayMs?: number;
|
|
3123
|
+
/**
|
|
3124
|
+
* 退避策略。
|
|
3125
|
+
* - exponential: delay = base * 2^(attempt-1) — 每次翻倍(最常用)
|
|
3126
|
+
* - linear: delay = base * attempt — 线性增长
|
|
3127
|
+
* - fixed: delay = base — 固定延迟
|
|
3128
|
+
* @default 'exponential'
|
|
3129
|
+
*/
|
|
3130
|
+
strategy?: RetryStrategy;
|
|
3131
|
+
/**
|
|
3132
|
+
* 随机抖动策略,防止雷群效应。
|
|
3133
|
+
* - full: delay = random(0, calculatedDelay)
|
|
3134
|
+
* - equal: delay = calculatedDelay/2 + random(0, calculatedDelay/2)
|
|
3135
|
+
* - decorrelated: AWS 风格,基于上次延迟计算
|
|
3136
|
+
* - none: 不加抖动
|
|
3137
|
+
* @default 'equal'
|
|
3138
|
+
*/
|
|
3139
|
+
jitter?: JitterStrategy;
|
|
3140
|
+
/**
|
|
3141
|
+
* 重试时的回调函数,用于 debug 或日志记录。
|
|
3142
|
+
*
|
|
3143
|
+
* @param info - 重试信息
|
|
3144
|
+
* @param info.attempt - 当前尝试次数(1-indexed)
|
|
3145
|
+
* @param info.maxAttempts - 最大尝试次数
|
|
3146
|
+
* @param info.delayMs - 即将等待的延迟时间(毫秒)
|
|
3147
|
+
* @param info.error - 导致重试的错误
|
|
3148
|
+
* @param info.model - 当前尝试的模型
|
|
3149
|
+
* @param info.request - 请求详细内容(用于调试)
|
|
3150
|
+
*/
|
|
3151
|
+
onRetry?: (info: {
|
|
3152
|
+
attempt: number;
|
|
3153
|
+
maxAttempts: number;
|
|
3154
|
+
delayMs: number;
|
|
3155
|
+
error: {
|
|
3156
|
+
code: string;
|
|
3157
|
+
message: string;
|
|
3158
|
+
retryable: boolean;
|
|
3159
|
+
};
|
|
3160
|
+
model: ModelRef;
|
|
3161
|
+
request: ModelRequest;
|
|
3162
|
+
}) => void;
|
|
3163
|
+
};
|
|
3164
|
+
/**
|
|
3165
|
+
* 默认超时时间(毫秒)。
|
|
3166
|
+
*
|
|
3167
|
+
* - 如果单次请求未显式传 `request.timeoutMs`,就使用这里的默认值。
|
|
3168
|
+
* - 超时通过 `AbortController` 触发取消,adapter 应尊重 `request.signal`。
|
|
3169
|
+
*/
|
|
3170
|
+
timeoutMs?: number;
|
|
3171
|
+
/**
|
|
3172
|
+
* 模型健康度/熔断状态(可选)。
|
|
3173
|
+
*
|
|
3174
|
+
* - 默认使用内置 `InMemoryModelHealth`(进程内存级别)。
|
|
3175
|
+
* - 当某模型失败时,会记录 failures 并计算 `nextRetryAt`,在该时间之前路由会尽量跳过它。
|
|
3176
|
+
* - 你可以注入自己的实例来共享健康状态(例如在同进程多处创建 client 时复用)。
|
|
3177
|
+
*/
|
|
3178
|
+
health?: InMemoryModelHealth;
|
|
3179
|
+
}
|
|
3180
|
+
declare function createModel(options: CreateModelOptions): CreateModelResult;
|
|
3181
|
+
//#endregion
|
|
3182
|
+
//#region src/model/utils/secrets.d.ts
|
|
3183
|
+
interface SecretProvider {
|
|
3184
|
+
get: (name: string) => string | undefined;
|
|
3185
|
+
}
|
|
3186
|
+
//#endregion
|
|
3187
|
+
//#region src/model/openai/createOpenAIAdapter.d.ts
|
|
3188
|
+
interface OpenAIAdapterOptions {
|
|
3189
|
+
baseUrl?: string;
|
|
3190
|
+
apiKeySecretName?: string;
|
|
3191
|
+
secretProvider?: SecretProvider;
|
|
3192
|
+
defaultModelId?: string;
|
|
3193
|
+
organization?: string;
|
|
3194
|
+
project?: string;
|
|
3195
|
+
}
|
|
3196
|
+
declare function createOpenAIAdapter(options?: OpenAIAdapterOptions): ModelAdapter;
|
|
3197
|
+
//#endregion
|
|
3198
|
+
//#region src/agent/agent.d.ts
|
|
3199
|
+
/**
|
|
3200
|
+
* Agent class - the main orchestrator.
|
|
3201
|
+
*
|
|
3202
|
+
* Agent is a blueprint/configuration that can handle multiple sessions.
|
|
3203
|
+
* It composes model, tools, state store, and session manager.
|
|
3204
|
+
*
|
|
3205
|
+
* Supports middleware pattern for extensible hooks at each loop iteration.
|
|
3206
|
+
*/
|
|
3207
|
+
declare class Agent {
|
|
3208
|
+
readonly id: string;
|
|
3209
|
+
readonly name: string;
|
|
3210
|
+
readonly systemPrompt: string;
|
|
3211
|
+
readonly createdAt: number;
|
|
3212
|
+
private _model;
|
|
3213
|
+
private _tools?;
|
|
3214
|
+
private _stateStore?;
|
|
3215
|
+
private _sessionManager?;
|
|
3216
|
+
private _metadata?;
|
|
3217
|
+
private _middlewares;
|
|
3218
|
+
private _stats;
|
|
3219
|
+
constructor(options: AgentOptions);
|
|
3220
|
+
/**
|
|
3221
|
+
* Get the current model
|
|
3222
|
+
*/
|
|
3223
|
+
get model(): ModelClient;
|
|
3224
|
+
/**
|
|
3225
|
+
* Get the tool registry
|
|
3226
|
+
*/
|
|
3227
|
+
get tools(): ToolRegistry | undefined;
|
|
3228
|
+
/**
|
|
3229
|
+
* Get the state store
|
|
3230
|
+
*/
|
|
3231
|
+
get stateStore(): StateStore | undefined;
|
|
3232
|
+
/**
|
|
3233
|
+
* Get the session manager
|
|
3234
|
+
*/
|
|
3235
|
+
get sessionManager(): BaseSessionManager | undefined;
|
|
3236
|
+
/**
|
|
3237
|
+
* Get runtime statistics
|
|
3238
|
+
*/
|
|
3239
|
+
get stats(): {
|
|
3240
|
+
updatedAt: number;
|
|
3241
|
+
totalSessions: number;
|
|
3242
|
+
activeSessions: number;
|
|
3243
|
+
totalUsage: {
|
|
3244
|
+
promptTokens: number;
|
|
3245
|
+
completionTokens: number;
|
|
3246
|
+
totalTokens: number;
|
|
3247
|
+
};
|
|
3248
|
+
};
|
|
3249
|
+
/**
|
|
3250
|
+
* Get metadata
|
|
3251
|
+
*/
|
|
3252
|
+
get metadata(): Record<string, unknown> | undefined;
|
|
3253
|
+
/**
|
|
3254
|
+
* Set metadata
|
|
3255
|
+
*/
|
|
3256
|
+
set metadata(value: Record<string, unknown> | undefined);
|
|
3257
|
+
/**
|
|
3258
|
+
* Add middleware to the agent.
|
|
3259
|
+
*
|
|
3260
|
+
* Middleware runs at each loop iteration and can intercept/transform the loop state.
|
|
3261
|
+
* Middleware follows an immutable pattern - it receives state and returns new state via next().
|
|
3262
|
+
*
|
|
3263
|
+
* @param fn - Middleware function
|
|
3264
|
+
* @returns this for chaining
|
|
3265
|
+
*
|
|
3266
|
+
* @example
|
|
3267
|
+
* ```ts
|
|
3268
|
+
* // Logging middleware (pass-through)
|
|
3269
|
+
* agent.use(async (state, next) => {
|
|
3270
|
+
* console.log('Before iteration', state.iteration);
|
|
3271
|
+
* const result = await next(state);
|
|
3272
|
+
* console.log('After iteration', state.iteration);
|
|
3273
|
+
* return result;
|
|
3274
|
+
* });
|
|
3275
|
+
*
|
|
3276
|
+
* // Transforming middleware (e.g., compression)
|
|
3277
|
+
* agent.use(async (state, next) => {
|
|
3278
|
+
* const compressed = { ...state, messages: compress(state.messages) };
|
|
3279
|
+
* return next(compressed);
|
|
3280
|
+
* });
|
|
3281
|
+
* ```
|
|
3282
|
+
*/
|
|
3283
|
+
use(fn: Middleware<AgentLoopState>): this;
|
|
3284
|
+
/**
|
|
3285
|
+
* Switch to a different model
|
|
3286
|
+
*
|
|
3287
|
+
* @param model - New model to use
|
|
3288
|
+
*/
|
|
3289
|
+
setModel(model: ModelClient): void;
|
|
3290
|
+
/**
|
|
3291
|
+
* Update session counts
|
|
3292
|
+
*
|
|
3293
|
+
* @param total - Total sessions
|
|
3294
|
+
* @param active - Active sessions
|
|
3295
|
+
*/
|
|
3296
|
+
updateSessionCounts(total: number, active: number): void;
|
|
3297
|
+
/**
|
|
3298
|
+
* Add to total usage statistics
|
|
3299
|
+
*
|
|
3300
|
+
* @param usage - Usage to add
|
|
3301
|
+
* @param usage.promptTokens - Number of prompt tokens
|
|
3302
|
+
* @param usage.completionTokens - Number of completion tokens
|
|
3303
|
+
* @param usage.totalTokens - Total number of tokens
|
|
3304
|
+
*/
|
|
3305
|
+
addUsage(usage: {
|
|
3306
|
+
promptTokens: number;
|
|
3307
|
+
completionTokens: number;
|
|
3308
|
+
totalTokens: number;
|
|
3309
|
+
}): void;
|
|
3310
|
+
/**
|
|
3311
|
+
* Create a snapshot of the agent for persistence
|
|
3312
|
+
*
|
|
3313
|
+
* @returns Agent snapshot
|
|
3314
|
+
*/
|
|
3315
|
+
toSnapshot(): AgentSnapshot;
|
|
3316
|
+
/**
|
|
3317
|
+
* Restore agent state from a snapshot
|
|
3318
|
+
*
|
|
3319
|
+
* Note: This restores mutable state (stats, metadata) from a snapshot.
|
|
3320
|
+
* The model and tools must be provided separately as they contain runtime instances.
|
|
3321
|
+
*
|
|
3322
|
+
* @param snapshot - Agent snapshot to restore from
|
|
3323
|
+
*/
|
|
3324
|
+
restoreFromSnapshot(snapshot: AgentSnapshot): void;
|
|
3325
|
+
/**
|
|
3326
|
+
* Execute model stream and collect events.
|
|
3327
|
+
* This is the core execution that middleware wraps around.
|
|
3328
|
+
*/
|
|
3329
|
+
private executeModelStream;
|
|
3330
|
+
/**
|
|
3331
|
+
* Execute a single tool call and return the result event.
|
|
3332
|
+
*/
|
|
3333
|
+
private executeToolCall;
|
|
3334
|
+
private createToolExecutionContext;
|
|
3335
|
+
/**
|
|
3336
|
+
* Merge execution results from processedState back to original state.
|
|
3337
|
+
*
|
|
3338
|
+
* This preserves original messages (for checkpoint) while keeping:
|
|
3339
|
+
* - currentResponse, currentThinking (from LLM)
|
|
3340
|
+
* - pendingToolCalls (from LLM)
|
|
3341
|
+
* - usage (accumulated)
|
|
3342
|
+
* - metadata (middleware may update this)
|
|
3343
|
+
*
|
|
3344
|
+
* Note: If processedState shares references with state (shallow copy),
|
|
3345
|
+
* some fields are already synced. This method ensures all fields are merged.
|
|
3346
|
+
*/
|
|
3347
|
+
private mergeStateResults;
|
|
3348
|
+
/**
|
|
3349
|
+
* Add tool result to message history.
|
|
3350
|
+
*/
|
|
3351
|
+
private addToolResultToHistory;
|
|
3352
|
+
/**
|
|
3353
|
+
* Add assistant message with tool calls to history.
|
|
3354
|
+
*/
|
|
3355
|
+
private addAssistantMessageWithToolCalls;
|
|
3356
|
+
/**
|
|
3357
|
+
* Add final assistant response to history.
|
|
3358
|
+
*/
|
|
3359
|
+
private addFinalAssistantMessage;
|
|
3360
|
+
/**
|
|
3361
|
+
* Stream agent execution with proper agentic loop.
|
|
3362
|
+
*
|
|
3363
|
+
* The execution follows an immutable middleware pattern with checkpoint support:
|
|
3364
|
+
* ```
|
|
3365
|
+
* checkpoint:before (save original state)
|
|
3366
|
+
* → middleware chain (transforms state immutably)
|
|
3367
|
+
* → exec (model.stream with processed state)
|
|
3368
|
+
* → merge results back (except messages)
|
|
3369
|
+
* checkpoint:after (save original state with original messages)
|
|
3370
|
+
* ```
|
|
3371
|
+
*
|
|
3372
|
+
* Key invariant: checkpoint always saves the original messages, while
|
|
3373
|
+
* LLM receives potentially transformed messages (e.g., compressed).
|
|
3374
|
+
*/
|
|
3375
|
+
private streamWithState;
|
|
3376
|
+
stream<TContext = unknown>(input: AgentInput<TContext>): AsyncIterable<AgentEvent>;
|
|
3377
|
+
/**
|
|
3378
|
+
* Stream agent execution starting from an existing message history (no new user message appended).
|
|
3379
|
+
*
|
|
3380
|
+
* Useful for orchestration patterns like "handoff", where a different agent should
|
|
3381
|
+
* continue the same conversation state under a different system prompt.
|
|
3382
|
+
*/
|
|
3383
|
+
streamFromMessages<TContext = unknown>(input: AgentInputFromMessages<TContext>): AsyncIterable<AgentEvent>;
|
|
3384
|
+
/**
|
|
3385
|
+
* Stream agent execution from a saved checkpoint.
|
|
3386
|
+
*
|
|
3387
|
+
* This allows resuming interrupted executions from the exact state
|
|
3388
|
+
* where they were saved (e.g., during tool approval waiting).
|
|
3389
|
+
*
|
|
3390
|
+
* @param input - Input containing the checkpoint to resume from
|
|
3391
|
+
*
|
|
3392
|
+
* @example
|
|
3393
|
+
* ```typescript
|
|
3394
|
+
* // Load checkpoint from store
|
|
3395
|
+
* const checkpoint = await store.loadLoopCheckpoint(sessionId)
|
|
3396
|
+
*
|
|
3397
|
+
* if (checkpoint) {
|
|
3398
|
+
* // Resume execution from checkpoint
|
|
3399
|
+
* for await (const event of agent.streamFromCheckpoint({
|
|
3400
|
+
* checkpoint,
|
|
3401
|
+
* maxIterations: 10,
|
|
3402
|
+
* })) {
|
|
3403
|
+
* console.log(event)
|
|
3404
|
+
* }
|
|
3405
|
+
* }
|
|
3406
|
+
* ```
|
|
3407
|
+
*/
|
|
3408
|
+
streamFromCheckpoint<TContext = unknown>(input: AgentInputFromCheckpoint<TContext>): AsyncIterable<AgentEvent>;
|
|
3409
|
+
/**
|
|
3410
|
+
* Risk levels that require user approval before execution.
|
|
3411
|
+
*/
|
|
3412
|
+
private static readonly APPROVAL_REQUIRED_LEVELS;
|
|
3413
|
+
/**
|
|
3414
|
+
* Check if a tool requires approval based on its risk level.
|
|
3415
|
+
*/
|
|
3416
|
+
private requiresApproval;
|
|
3417
|
+
/**
|
|
3418
|
+
* Handle tool calls: execute tools, yield results, continue loop.
|
|
3419
|
+
*/
|
|
3420
|
+
private handleToolCalls;
|
|
3421
|
+
/**
|
|
3422
|
+
* Handle final response: add to history, emit done.
|
|
3423
|
+
*/
|
|
3424
|
+
private handleFinalResponse;
|
|
3425
|
+
}
|
|
3426
|
+
//#endregion
|
|
3427
|
+
//#region src/agent/checkpointMiddleware.d.ts
|
|
3428
|
+
/**
|
|
3429
|
+
* Options for converting AgentLoopState to checkpoint
|
|
3430
|
+
*/
|
|
3431
|
+
interface ToCheckpointOptions {
|
|
3432
|
+
agentName?: string;
|
|
3433
|
+
phase?: 'llm_call' | 'tool_execution' | 'approval_pending' | 'completed';
|
|
3434
|
+
status?: string;
|
|
3435
|
+
/**
|
|
3436
|
+
* Model configuration to save in checkpoint
|
|
3437
|
+
*/
|
|
3438
|
+
modelConfig?: CheckpointModelConfig;
|
|
3439
|
+
/**
|
|
3440
|
+
* Model request parameters to save in checkpoint
|
|
3441
|
+
*/
|
|
3442
|
+
requestParams?: CheckpointRequestParams;
|
|
3443
|
+
}
|
|
3444
|
+
/**
|
|
3445
|
+
* Convert AgentLoopState to AgentLoopCheckpoint
|
|
3446
|
+
*/
|
|
3447
|
+
declare function toLoopCheckpoint(state: AgentLoopState, options?: ToCheckpointOptions): AgentLoopCheckpoint;
|
|
3448
|
+
/**
|
|
3449
|
+
* Restore AgentLoopState from AgentLoopCheckpoint
|
|
3450
|
+
*
|
|
3451
|
+
* Note: agentName, phase, and status are display-only fields and are not
|
|
3452
|
+
* part of AgentLoopState. They will be recalculated when a new checkpoint is saved.
|
|
3453
|
+
*/
|
|
3454
|
+
declare function fromLoopCheckpoint(checkpoint: AgentLoopCheckpoint): AgentLoopState;
|
|
3455
|
+
//#endregion
|
|
3456
|
+
//#region src/agent/errors.d.ts
|
|
3457
|
+
/**
|
|
3458
|
+
* Error thrown when agent execution is aborted via AbortSignal
|
|
3459
|
+
*/
|
|
3460
|
+
declare class AgentAbortError extends Error {
|
|
3461
|
+
constructor(message?: string);
|
|
3462
|
+
}
|
|
3463
|
+
/**
|
|
3464
|
+
* Error thrown when agent exceeds maximum iterations
|
|
3465
|
+
*/
|
|
3466
|
+
declare class AgentMaxIterationsError extends Error {
|
|
3467
|
+
readonly iterations: number;
|
|
3468
|
+
constructor(iterations: number, message?: string);
|
|
3469
|
+
}
|
|
3470
|
+
/**
|
|
3471
|
+
* Check if the abort signal has been triggered and throw if so.
|
|
3472
|
+
*
|
|
3473
|
+
* @param signal - AbortSignal to check
|
|
3474
|
+
* @param context - Optional context for error message
|
|
3475
|
+
* @throws AgentAbortError if signal is aborted
|
|
3476
|
+
*/
|
|
3477
|
+
declare function ensureNotAborted(signal?: AbortSignal, context?: string): void;
|
|
3478
|
+
//#endregion
|
|
3479
|
+
export { Agent, AgentAbortError, type AgentEvent, type AgentEventType, type AgentInput, type AgentInputFromCheckpoint, type AgentInputFromMessages, type AgentLoopCheckpoint, type AgentLoopState, AgentMaxIterationsError, type AgentOptions, type AssistantMessage, type BaseEvent, BaseModel, BaseSession, BaseSessionManager, BaseTool, type CallToolResult, type ChatOptions, type ChatResponse, type StateStore as CheckpointStore, StateStore, type StateStoreOptions as CheckpointStoreOptions, type StateStoreOptions, type CompressionState, type CompressionStats, type ContentBlock, type ContextCompressionOptions, CreateModelResult, type DoneEvent, type EditArgs, type EditResult, EditTool, type ErrorEvent, FeatureGrant, FeatureGrants, FeatureId, FeatureRequest, FeatureRequests, FileStateStore as FileCheckpointStore, FileStateStore, type FileStateStoreOptions as FileCheckpointStoreOptions, type FileStateStoreOptions, type GlobArgs, type GlobResult, GlobTool, type GrepArgs, type GrepOutputMode, type GrepResult, GrepTool, type ImageContent, InMemoryStateStore as InMemoryCheckpointStore, InMemoryStateStore, InMemoryModelHealth, type IterationEndEvent, type IterationStartEvent, type JSONSchemaProperty, JitterStrategy, type ManualCompressionOptions, type ManualCompressionResult, type Message, type MessageContent, type MessageRole, type Middleware, type ModelAdapter, ModelClient, ModelDeltaChunk, ModelError, ModelId, ModelRef, ModelRequest, ModelRunResult, ModelStopReason, ModelStreamEvent, ModelStreamFn, type NextFunction, OpenAIAdapterOptions, type OpenAITool, ProviderId, type ReadArgs, type ReadResult, ReadTool, RetryPolicy, RetryPolicyOptions, RetryStrategy, type RiskLevel, type StateKey, StateKeys, type StreamEvent, type SystemMessage, type TextContent, type TextDeltaEvent, type ThinkingDeltaEvent, type ToCheckpointOptions, type Tool, type ToolApprovalOutcome, type ToolApprovalPending, type ToolApprovalRequest, type ToolApprovalResult, type ToolApprovalSettings, type ToolApprovalStrategy, type ToolCall, type ToolCallDeltaEvent, type ToolCallEndEvent, type ToolCallStartEvent, type ToolCallWithResult, type ToolExecutionContext, type ToolExecutionContextInput, type ToolFileSystemCapabilities, type ToolMessage, ToolRegistry, type ToolResultEvent, type ToolRunUsage, type Usage, type UsageEvent, type UserMessage, type WebSearchArgs, type WebSearchResult, WebSearchTool, type WriteArgs, type WriteResult, WriteTool, compose, compressSessionManually, createContextCompressionMiddleware, createInitialLoopState, createInitialLoopStateFromMessages, createModel, createOpenAIAdapter, ensureNotAborted, errorContent, fromLoopCheckpoint, imageContent, textContent, toLoopCheckpoint };
|