@cuylabs/agent-core 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -8
- package/dist/builder-RcTZuYnO.d.ts +34 -0
- package/dist/capabilities/index.d.ts +97 -0
- package/dist/capabilities/index.js +46 -0
- package/dist/chunk-6TDTQJ4P.js +116 -0
- package/dist/chunk-7MUFEN4K.js +559 -0
- package/dist/chunk-BDBZ3SLK.js +745 -0
- package/dist/chunk-DWYX7ASF.js +26 -0
- package/dist/chunk-FG4MD5MU.js +54 -0
- package/dist/chunk-IMGQOTU2.js +2019 -0
- package/dist/chunk-IVUJDISU.js +556 -0
- package/dist/chunk-LRHOS4ZN.js +584 -0
- package/dist/chunk-OTUGSCED.js +691 -0
- package/dist/chunk-P6YF7USR.js +182 -0
- package/dist/chunk-QAQADS4X.js +258 -0
- package/dist/chunk-QWFMX226.js +879 -0
- package/dist/{chunk-6VKLWNRE.js → chunk-SDSBEQXG.js} +1 -132
- package/dist/chunk-VBWWUHWI.js +724 -0
- package/dist/chunk-VEKUXUVF.js +41 -0
- package/dist/chunk-X635CM2F.js +305 -0
- package/dist/chunk-YUUJK53A.js +91 -0
- package/dist/chunk-ZXAKHMWH.js +283 -0
- package/dist/config-D2xeGEHK.d.ts +52 -0
- package/dist/context/index.d.ts +259 -0
- package/dist/context/index.js +26 -0
- package/dist/identifiers-BLUxFqV_.d.ts +12 -0
- package/dist/index-p0kOsVsE.d.ts +1067 -0
- package/dist/index-tmhaADz5.d.ts +198 -0
- package/dist/index.d.ts +210 -5736
- package/dist/index.js +2126 -7766
- package/dist/mcp/index.d.ts +26 -0
- package/dist/mcp/index.js +14 -0
- package/dist/messages-BYWGn8TY.d.ts +110 -0
- package/dist/middleware/index.d.ts +7 -0
- package/dist/middleware/index.js +12 -0
- package/dist/models/index.d.ts +33 -0
- package/dist/models/index.js +12 -0
- package/dist/network-D76DS5ot.d.ts +5 -0
- package/dist/prompt/index.d.ts +224 -0
- package/dist/prompt/index.js +45 -0
- package/dist/reasoning/index.d.ts +71 -0
- package/dist/reasoning/index.js +47 -0
- package/dist/registry-CuRWWtcT.d.ts +164 -0
- package/dist/resolver-DOfZ-xuk.d.ts +254 -0
- package/dist/runner-C7aMP_x3.d.ts +596 -0
- package/dist/runtime/index.d.ts +357 -0
- package/dist/runtime/index.js +64 -0
- package/dist/session-manager-Uawm2Le7.d.ts +274 -0
- package/dist/skill/index.d.ts +103 -0
- package/dist/skill/index.js +39 -0
- package/dist/storage/index.d.ts +167 -0
- package/dist/storage/index.js +50 -0
- package/dist/sub-agent/index.d.ts +14 -0
- package/dist/sub-agent/index.js +15 -0
- package/dist/tool/index.d.ts +173 -1
- package/dist/tool/index.js +12 -3
- package/dist/tool-DYp6-cC3.d.ts +239 -0
- package/dist/tool-pFAnJc5Y.d.ts +419 -0
- package/dist/tracker-DClqYqTj.d.ts +96 -0
- package/dist/tracking/index.d.ts +109 -0
- package/dist/tracking/index.js +20 -0
- package/dist/types-CQaXbRsS.d.ts +47 -0
- package/dist/types-MM1JoX5T.d.ts +810 -0
- package/dist/types-VQgymC1N.d.ts +156 -0
- package/package.json +89 -5
- package/dist/index-BlSTfS-W.d.ts +0 -470
|
@@ -0,0 +1,596 @@
|
|
|
1
|
+
import * as ai from 'ai';
|
|
2
|
+
import { LanguageModel } from 'ai';
|
|
3
|
+
import { T as TokenUsage, M as Message } from './messages-BYWGn8TY.js';
|
|
4
|
+
import { d as SkillConfig, T as Tool } from './tool-pFAnJc5Y.js';
|
|
5
|
+
import { b as ToolContext } from './tool-DYp6-cC3.js';
|
|
6
|
+
|
|
7
|
+
/** Agent status for UI display */
|
|
8
|
+
type AgentStatus = "idle" | "processing" | "thinking" | "reasoning" | "calling-tool" | "waiting-approval" | "error";
|
|
9
|
+
/** Approval request for UI */
|
|
10
|
+
interface ApprovalEvent {
|
|
11
|
+
id: string;
|
|
12
|
+
tool: string;
|
|
13
|
+
args: unknown;
|
|
14
|
+
description: string;
|
|
15
|
+
risk: "safe" | "moderate" | "dangerous";
|
|
16
|
+
}
|
|
17
|
+
/** Neutral turn-commit boundaries for runtime/durability integrations */
|
|
18
|
+
type AgentTurnBoundaryKind = "input-commit-start" | "input-commit-finish" | "intervention-commit-start" | "intervention-commit-finish" | "step-commit-start" | "step-commit-finish" | "output-commit-start" | "output-commit-finish";
|
|
19
|
+
/**
|
|
20
|
+
* Events emitted during agent execution
|
|
21
|
+
*
|
|
22
|
+
* These events are designed for UI consumption:
|
|
23
|
+
* - status: Overall agent state for status indicators
|
|
24
|
+
* - approval-request: User confirmation needed
|
|
25
|
+
* - progress: Step counts for progress bars
|
|
26
|
+
*/
|
|
27
|
+
type AgentEvent = {
|
|
28
|
+
type: "status";
|
|
29
|
+
status: AgentStatus;
|
|
30
|
+
} | {
|
|
31
|
+
type: "approval-request";
|
|
32
|
+
request: ApprovalEvent;
|
|
33
|
+
} | {
|
|
34
|
+
type: "approval-resolved";
|
|
35
|
+
id: string;
|
|
36
|
+
action: "allow" | "deny" | "remember";
|
|
37
|
+
} | {
|
|
38
|
+
type: "step-start";
|
|
39
|
+
step: number;
|
|
40
|
+
maxSteps: number;
|
|
41
|
+
} | {
|
|
42
|
+
type: "step-finish";
|
|
43
|
+
step: number;
|
|
44
|
+
usage?: TokenUsage;
|
|
45
|
+
finishReason?: string;
|
|
46
|
+
} | {
|
|
47
|
+
type: "turn-boundary";
|
|
48
|
+
boundary: AgentTurnBoundaryKind;
|
|
49
|
+
step?: number;
|
|
50
|
+
messageRole?: Message["role"];
|
|
51
|
+
pendingToolCallCount?: number;
|
|
52
|
+
} | {
|
|
53
|
+
type: "message";
|
|
54
|
+
message: Message;
|
|
55
|
+
} | {
|
|
56
|
+
type: "text-start";
|
|
57
|
+
} | {
|
|
58
|
+
type: "text-delta";
|
|
59
|
+
text: string;
|
|
60
|
+
} | {
|
|
61
|
+
type: "text-end";
|
|
62
|
+
} | {
|
|
63
|
+
type: "reasoning-start";
|
|
64
|
+
id: string;
|
|
65
|
+
} | {
|
|
66
|
+
type: "reasoning-delta";
|
|
67
|
+
id: string;
|
|
68
|
+
text: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "reasoning-end";
|
|
71
|
+
id: string;
|
|
72
|
+
} | {
|
|
73
|
+
type: "tool-start";
|
|
74
|
+
toolName: string;
|
|
75
|
+
toolCallId: string;
|
|
76
|
+
input: unknown;
|
|
77
|
+
} | {
|
|
78
|
+
type: "tool-result";
|
|
79
|
+
toolName: string;
|
|
80
|
+
toolCallId: string;
|
|
81
|
+
result: unknown;
|
|
82
|
+
} | {
|
|
83
|
+
type: "tool-error";
|
|
84
|
+
toolName: string;
|
|
85
|
+
toolCallId: string;
|
|
86
|
+
error: string;
|
|
87
|
+
} | {
|
|
88
|
+
type: "computer-call";
|
|
89
|
+
callId: string;
|
|
90
|
+
action: unknown;
|
|
91
|
+
pendingSafetyChecks?: unknown[];
|
|
92
|
+
} | {
|
|
93
|
+
type: "computer-result";
|
|
94
|
+
callId: string;
|
|
95
|
+
result: unknown;
|
|
96
|
+
} | {
|
|
97
|
+
type: "intervention-applied";
|
|
98
|
+
id: string;
|
|
99
|
+
message: string;
|
|
100
|
+
} | {
|
|
101
|
+
type: "doom-loop";
|
|
102
|
+
toolName: string;
|
|
103
|
+
repeatCount: number;
|
|
104
|
+
} | {
|
|
105
|
+
type: "context-overflow";
|
|
106
|
+
inputTokens: number;
|
|
107
|
+
limit: number;
|
|
108
|
+
} | {
|
|
109
|
+
type: "turn-summary";
|
|
110
|
+
turnId: string;
|
|
111
|
+
files: Array<{
|
|
112
|
+
path: string;
|
|
113
|
+
type: "created" | "modified" | "deleted" | "unchanged";
|
|
114
|
+
additions: number;
|
|
115
|
+
deletions: number;
|
|
116
|
+
}>;
|
|
117
|
+
additions: number;
|
|
118
|
+
deletions: number;
|
|
119
|
+
} | {
|
|
120
|
+
type: "retry";
|
|
121
|
+
attempt: number;
|
|
122
|
+
delayMs: number;
|
|
123
|
+
error: Error;
|
|
124
|
+
} | {
|
|
125
|
+
type: "error";
|
|
126
|
+
error: Error;
|
|
127
|
+
} | {
|
|
128
|
+
type: "complete";
|
|
129
|
+
usage?: TokenUsage;
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Processor result - what happens after processing a turn
|
|
133
|
+
*/
|
|
134
|
+
type ProcessorResult = "continue" | "stop" | "compact";
|
|
135
|
+
/**
|
|
136
|
+
* Stream input for the LLM
|
|
137
|
+
*/
|
|
138
|
+
interface StreamInput {
|
|
139
|
+
sessionID: string;
|
|
140
|
+
model: ai.LanguageModel;
|
|
141
|
+
system: string[];
|
|
142
|
+
messages: ai.ModelMessage[];
|
|
143
|
+
abort: AbortSignal;
|
|
144
|
+
tools: Record<string, unknown>;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Prompt Pipeline Types
|
|
149
|
+
*
|
|
150
|
+
* Types for the layered system prompt architecture.
|
|
151
|
+
* The prompt pipeline composes a system prompt from multiple sources:
|
|
152
|
+
*
|
|
153
|
+
* Base Template → Environment → Instructions → Custom Sections → Per-Turn
|
|
154
|
+
*
|
|
155
|
+
* Each layer is optional, composable, and can be toggled on/off.
|
|
156
|
+
*/
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Model family identifier for prompt template selection.
|
|
160
|
+
*
|
|
161
|
+
* Each family gets a base template optimized for its strengths:
|
|
162
|
+
* - `anthropic`: Claude models — structured sections with XML tags
|
|
163
|
+
* - `openai`: GPT/o-series models — clear directives with markdown
|
|
164
|
+
* - `google`: Gemini models — balanced approach
|
|
165
|
+
* - `deepseek`: DeepSeek models — code-focused emphasis
|
|
166
|
+
* - `default`: Generic template for any model
|
|
167
|
+
*/
|
|
168
|
+
type ModelFamily = "anthropic" | "openai" | "google" | "deepseek" | "default";
|
|
169
|
+
/**
|
|
170
|
+
* Runtime environment information injected into the system prompt.
|
|
171
|
+
* Gives the model awareness of the working context.
|
|
172
|
+
*/
|
|
173
|
+
interface EnvironmentInfo {
|
|
174
|
+
/** Current working directory */
|
|
175
|
+
cwd: string;
|
|
176
|
+
/** Operating system (e.g. "macOS (darwin arm64)") */
|
|
177
|
+
platform: string;
|
|
178
|
+
/** Current date/time formatted string */
|
|
179
|
+
date: string;
|
|
180
|
+
/** User's shell (e.g. "/bin/zsh") */
|
|
181
|
+
shell?: string;
|
|
182
|
+
/** Active git branch, if inside a repo */
|
|
183
|
+
gitBranch?: string;
|
|
184
|
+
/** Whether the working tree is clean */
|
|
185
|
+
gitClean?: boolean;
|
|
186
|
+
/** Git repo root path */
|
|
187
|
+
gitRoot?: string;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* An instruction file discovered on disk (e.g. AGENTS.md).
|
|
191
|
+
*
|
|
192
|
+
* Instruction files provide project-specific or workspace-level guidance
|
|
193
|
+
* that gets injected into every prompt. They're discovered by walking up
|
|
194
|
+
* the directory tree from cwd.
|
|
195
|
+
*/
|
|
196
|
+
interface InstructionFile {
|
|
197
|
+
/** Absolute path to the file */
|
|
198
|
+
path: string;
|
|
199
|
+
/** File content (trimmed) */
|
|
200
|
+
content: string;
|
|
201
|
+
/** How the file was discovered */
|
|
202
|
+
source: "project" | "workspace" | "global";
|
|
203
|
+
/** Depth from cwd (0 = same directory) */
|
|
204
|
+
depth: number;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* A composable section in the prompt pipeline.
|
|
208
|
+
*
|
|
209
|
+
* Sections are the building blocks of the final system prompt.
|
|
210
|
+
* Each section has a priority that determines its position in the output.
|
|
211
|
+
*
|
|
212
|
+
* Default priority ranges:
|
|
213
|
+
* - 10: Base template
|
|
214
|
+
* - 20: Environment block
|
|
215
|
+
* - 30: Instruction files
|
|
216
|
+
* - 50: Custom sections (default for user-added)
|
|
217
|
+
* - 70: Reserved for future use (e.g. Skills)
|
|
218
|
+
* - 90: Per-turn overrides
|
|
219
|
+
*/
|
|
220
|
+
interface PromptSection {
|
|
221
|
+
/** Unique identifier for this section */
|
|
222
|
+
id: string;
|
|
223
|
+
/** Human-readable label (useful for debugging/logging) */
|
|
224
|
+
label: string;
|
|
225
|
+
/** The text content of this section */
|
|
226
|
+
content: string;
|
|
227
|
+
/** Sort priority — lower values appear earlier (default: 50) */
|
|
228
|
+
priority?: number;
|
|
229
|
+
/** Whether this section is active (default: true) */
|
|
230
|
+
enabled?: boolean;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Context passed to the builder for each prompt build.
|
|
234
|
+
*
|
|
235
|
+
* This provides the runtime information needed to compose
|
|
236
|
+
* the system prompt for a specific conversation turn.
|
|
237
|
+
*/
|
|
238
|
+
interface PromptBuildContext {
|
|
239
|
+
/** Current working directory */
|
|
240
|
+
cwd: string;
|
|
241
|
+
/** The language model being used */
|
|
242
|
+
model: LanguageModel;
|
|
243
|
+
/** Names of available tools (for template customization) */
|
|
244
|
+
toolNames?: string[];
|
|
245
|
+
/** Per-turn additional instructions (from chat options) */
|
|
246
|
+
override?: string;
|
|
247
|
+
/** Current session ID */
|
|
248
|
+
sessionId?: string;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Configuration for the prompt pipeline.
|
|
252
|
+
*
|
|
253
|
+
* Controls which layers are active and how they behave.
|
|
254
|
+
* All options have sensible defaults — an empty config `{}` gives you
|
|
255
|
+
* the full pipeline with auto-detection.
|
|
256
|
+
*
|
|
257
|
+
* @example
|
|
258
|
+
* ```typescript
|
|
259
|
+
* // Minimal — use all defaults
|
|
260
|
+
* const builder = createPromptBuilder();
|
|
261
|
+
*
|
|
262
|
+
* // Custom base template but keep environment + instructions
|
|
263
|
+
* const builder = createPromptBuilder({
|
|
264
|
+
* baseTemplate: "You are a security auditor...",
|
|
265
|
+
* includeEnvironment: true,
|
|
266
|
+
* includeInstructions: true,
|
|
267
|
+
* });
|
|
268
|
+
*
|
|
269
|
+
* // Fully custom — disable auto features, add your own sections
|
|
270
|
+
* const builder = createPromptBuilder({
|
|
271
|
+
* includeEnvironment: false,
|
|
272
|
+
* includeInstructions: false,
|
|
273
|
+
* sections: [
|
|
274
|
+
* { id: "role", label: "Role", content: "You audit code.", priority: 10 },
|
|
275
|
+
* { id: "rules", label: "Rules", content: "Never modify files.", priority: 20 },
|
|
276
|
+
* ],
|
|
277
|
+
* });
|
|
278
|
+
* ```
|
|
279
|
+
*/
|
|
280
|
+
interface PromptConfig {
|
|
281
|
+
/**
|
|
282
|
+
* Override the base template entirely.
|
|
283
|
+
* If set, replaces the model-family-specific template.
|
|
284
|
+
*/
|
|
285
|
+
baseTemplate?: string;
|
|
286
|
+
/**
|
|
287
|
+
* Force a specific model family for template selection.
|
|
288
|
+
* Auto-detected from the model if not provided.
|
|
289
|
+
*/
|
|
290
|
+
modelFamily?: ModelFamily;
|
|
291
|
+
/**
|
|
292
|
+
* Inject runtime environment info (cwd, platform, git, date).
|
|
293
|
+
* @default true
|
|
294
|
+
*/
|
|
295
|
+
includeEnvironment?: boolean;
|
|
296
|
+
/**
|
|
297
|
+
* Discover and include instruction files (AGENTS.md, etc.).
|
|
298
|
+
* @default true
|
|
299
|
+
*/
|
|
300
|
+
includeInstructions?: boolean;
|
|
301
|
+
/**
|
|
302
|
+
* File name patterns to search for when discovering instructions.
|
|
303
|
+
* Searched in each directory walking up from cwd.
|
|
304
|
+
*
|
|
305
|
+
* @default ["AGENTS.md", "CLAUDE.md", "COPILOT.md", ".cuylabs/instructions.md"]
|
|
306
|
+
*/
|
|
307
|
+
instructionPatterns?: string[];
|
|
308
|
+
/**
|
|
309
|
+
* Absolute paths to global instruction files (always included
|
|
310
|
+
* regardless of cwd). Useful for organization-wide rules.
|
|
311
|
+
*/
|
|
312
|
+
globalInstructions?: string[];
|
|
313
|
+
/**
|
|
314
|
+
* Maximum depth to walk up from cwd when searching for instructions.
|
|
315
|
+
* Prevents scanning the entire filesystem.
|
|
316
|
+
* @default 10
|
|
317
|
+
*/
|
|
318
|
+
instructionMaxDepth?: number;
|
|
319
|
+
/**
|
|
320
|
+
* Maximum file size in bytes for instruction files.
|
|
321
|
+
* Files larger than this are skipped to avoid bloating the prompt.
|
|
322
|
+
* @default 51200 (50KB)
|
|
323
|
+
*/
|
|
324
|
+
instructionMaxSize?: number;
|
|
325
|
+
/**
|
|
326
|
+
* Pre-defined sections to include in every prompt build.
|
|
327
|
+
* These are merged with auto-generated sections (template, environment, etc.).
|
|
328
|
+
*/
|
|
329
|
+
sections?: PromptSection[];
|
|
330
|
+
/**
|
|
331
|
+
* Separator between sections in the final composed prompt.
|
|
332
|
+
* @default "\n\n"
|
|
333
|
+
*/
|
|
334
|
+
separator?: string;
|
|
335
|
+
/**
|
|
336
|
+
* Skill discovery and loading configuration.
|
|
337
|
+
*
|
|
338
|
+
* When provided, the prompt pipeline will:
|
|
339
|
+
* 1. Discover SKILL.md files from project, user, and global directories
|
|
340
|
+
* 2. Inject skill summaries at PRIORITY_SKILLS (70) in the system prompt
|
|
341
|
+
* 3. Make `skill` and `skill_resource` tools available to the agent
|
|
342
|
+
*
|
|
343
|
+
* Skills use progressive disclosure:
|
|
344
|
+
* - L1 (summary): always in system prompt — names + descriptions
|
|
345
|
+
* - L2 (content): loaded on demand via `skill` tool
|
|
346
|
+
* - L3 (resources): loaded on demand via `skill_resource` tool
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```typescript
|
|
350
|
+
* const agent = createAgent({
|
|
351
|
+
* model: anthropic("claude-sonnet-4-20250514"),
|
|
352
|
+
* prompt: {
|
|
353
|
+
* skills: {
|
|
354
|
+
* externalDirs: [".agents", ".claude"],
|
|
355
|
+
* roots: ["./company-skills"],
|
|
356
|
+
* },
|
|
357
|
+
* },
|
|
358
|
+
* });
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
skills?: SkillConfig;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Middleware Types
|
|
366
|
+
*
|
|
367
|
+
* Defines the composable middleware interface for agent lifecycle hooks.
|
|
368
|
+
*
|
|
369
|
+
* Middleware is just a plain object with optional hook methods — no
|
|
370
|
+
* base classes, no discovery, no installation. Pass it in code:
|
|
371
|
+
*
|
|
372
|
+
* ```typescript
|
|
373
|
+
* const agent = createAgent({
|
|
374
|
+
* middleware: [myLoggerMiddleware, myApprovalMiddleware],
|
|
375
|
+
* });
|
|
376
|
+
* ```
|
|
377
|
+
*
|
|
378
|
+
* Hooks run in array order for "before" operations and reverse order
|
|
379
|
+
* for "after" operations (like middleware stacks everywhere).
|
|
380
|
+
*/
|
|
381
|
+
|
|
382
|
+
/**
|
|
383
|
+
* Action returned by `beforeToolCall` — determines whether
|
|
384
|
+
* the tool call proceeds or is blocked.
|
|
385
|
+
*/
|
|
386
|
+
interface ToolCallDecision {
|
|
387
|
+
/** Whether to allow or deny the tool call */
|
|
388
|
+
action: "allow" | "deny";
|
|
389
|
+
/** Reason for denial — returned to the model as the tool output */
|
|
390
|
+
reason?: string;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Agent middleware — composable lifecycle hooks.
|
|
394
|
+
*
|
|
395
|
+
* All methods are optional. Implement only what you need.
|
|
396
|
+
*
|
|
397
|
+
* Ordering:
|
|
398
|
+
* - `beforeToolCall`: runs in array order, first "deny" wins
|
|
399
|
+
* - `afterToolCall`: runs in reverse order (innermost first)
|
|
400
|
+
* - `promptSections`: all run, sections merged
|
|
401
|
+
* - `onEvent`: all run in parallel (non-blocking)
|
|
402
|
+
* - `onChatStart` / `onChatEnd`: run in array order, awaited sequentially
|
|
403
|
+
*
|
|
404
|
+
* @example
|
|
405
|
+
* ```typescript
|
|
406
|
+
* // A simple logging middleware
|
|
407
|
+
* const logger: AgentMiddleware = {
|
|
408
|
+
* name: "logger",
|
|
409
|
+
* beforeToolCall: async (tool, args) => {
|
|
410
|
+
* console.log(`→ ${tool}`, args);
|
|
411
|
+
* return { action: "allow" };
|
|
412
|
+
* },
|
|
413
|
+
* afterToolCall: async (tool, args, result) => {
|
|
414
|
+
* console.log(`← ${tool}`, result.title);
|
|
415
|
+
* return result;
|
|
416
|
+
* },
|
|
417
|
+
* };
|
|
418
|
+
* ```
|
|
419
|
+
*/
|
|
420
|
+
interface AgentMiddleware {
|
|
421
|
+
/** Middleware name (for logging and debugging) */
|
|
422
|
+
name: string;
|
|
423
|
+
/**
|
|
424
|
+
* Intercept a tool call before execution.
|
|
425
|
+
*
|
|
426
|
+
* Return `{ action: "allow" }` to proceed, or `{ action: "deny", reason }` to
|
|
427
|
+
* block the call. When denied, `reason` is returned to the model as the tool
|
|
428
|
+
* output so it can adjust its approach.
|
|
429
|
+
*
|
|
430
|
+
* Runs in array order. The first middleware that returns "deny" short-circuits
|
|
431
|
+
* the chain — remaining middleware and the tool itself are skipped.
|
|
432
|
+
*
|
|
433
|
+
* @param tool - Tool name (e.g. "bash", "write_file")
|
|
434
|
+
* @param args - Parsed tool arguments
|
|
435
|
+
* @param ctx - Tool execution context (cwd, sessionID, host, etc.)
|
|
436
|
+
*/
|
|
437
|
+
beforeToolCall?(tool: string, args: unknown, ctx: ToolContext): Promise<ToolCallDecision>;
|
|
438
|
+
/**
|
|
439
|
+
* Transform or observe a tool result after execution.
|
|
440
|
+
*
|
|
441
|
+
* Receives the result and must return a result (can be the same object
|
|
442
|
+
* or a modified copy). Runs in reverse array order so the outermost
|
|
443
|
+
* middleware sees the final transformed result.
|
|
444
|
+
*
|
|
445
|
+
* @param tool - Tool name
|
|
446
|
+
* @param args - Original tool arguments
|
|
447
|
+
* @param result - Tool execution result
|
|
448
|
+
* @param ctx - Tool execution context
|
|
449
|
+
*/
|
|
450
|
+
afterToolCall?(tool: string, args: unknown, result: Tool.ExecuteResult, ctx: ToolContext): Promise<Tool.ExecuteResult>;
|
|
451
|
+
/**
|
|
452
|
+
* Inject dynamic prompt sections at build time.
|
|
453
|
+
*
|
|
454
|
+
* Called during `PromptBuilder.build()` for each middleware. Return one
|
|
455
|
+
* or more sections to inject into the system prompt. Return `undefined`
|
|
456
|
+
* or an empty array to inject nothing.
|
|
457
|
+
*
|
|
458
|
+
* Sections follow the same priority system as static sections — use
|
|
459
|
+
* `priority` to control placement relative to base template (10),
|
|
460
|
+
* environment (20), instructions (30), custom (50), skills (70),
|
|
461
|
+
* and per-turn overrides (90).
|
|
462
|
+
*
|
|
463
|
+
* @param ctx - Build context with cwd, model, toolNames, sessionId
|
|
464
|
+
*/
|
|
465
|
+
promptSections?(ctx: PromptBuildContext): PromptSection | PromptSection[] | undefined;
|
|
466
|
+
/**
|
|
467
|
+
* Observe agent events (read-only, non-blocking).
|
|
468
|
+
*
|
|
469
|
+
* Fires for every event emitted during `chat()`. Errors thrown by
|
|
470
|
+
* handlers are caught and logged — they never interrupt the stream.
|
|
471
|
+
*
|
|
472
|
+
* This is intentionally synchronous (void return) to prevent
|
|
473
|
+
* event observers from blocking the streaming pipeline.
|
|
474
|
+
*
|
|
475
|
+
* @param event - The agent event
|
|
476
|
+
*/
|
|
477
|
+
onEvent?(event: AgentEvent): void;
|
|
478
|
+
/**
|
|
479
|
+
* Called when `chat()` starts, before the LLM stream is created.
|
|
480
|
+
*
|
|
481
|
+
* Use this for setup: initializing loggers, recording start time,
|
|
482
|
+
* resetting per-turn state, etc. Runs in array order, awaited
|
|
483
|
+
* sequentially.
|
|
484
|
+
*
|
|
485
|
+
* @param sessionId - Session identifier
|
|
486
|
+
* @param message - The user message being sent
|
|
487
|
+
*/
|
|
488
|
+
onChatStart?(sessionId: string, message: string): Promise<void>;
|
|
489
|
+
/**
|
|
490
|
+
* Called when `chat()` completes (or errors), after all events
|
|
491
|
+
* have been yielded.
|
|
492
|
+
*
|
|
493
|
+
* Use this for teardown: flushing logs, recording metrics, etc.
|
|
494
|
+
* Runs in array order, awaited sequentially. Always called, even
|
|
495
|
+
* if the stream errored.
|
|
496
|
+
*
|
|
497
|
+
* @param sessionId - Session identifier
|
|
498
|
+
* @param result - Completion info (usage stats and optional error)
|
|
499
|
+
*/
|
|
500
|
+
onChatEnd?(sessionId: string, result: {
|
|
501
|
+
usage?: TokenUsage;
|
|
502
|
+
error?: Error;
|
|
503
|
+
output?: string;
|
|
504
|
+
}): Promise<void>;
|
|
505
|
+
/**
|
|
506
|
+
* Get the active OTel context for a session.
|
|
507
|
+
*
|
|
508
|
+
* Used internally by the LLM layer to wrap `streamText()` so that
|
|
509
|
+
* AI SDK spans are nested under the middleware's parent span.
|
|
510
|
+
* Only implemented by the `otelMiddleware`.
|
|
511
|
+
*/
|
|
512
|
+
getOtelContext?(sessionId: string): unknown;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* Middleware Runner
|
|
517
|
+
*
|
|
518
|
+
* Executes middleware hooks in the correct order with proper
|
|
519
|
+
* error handling and short-circuit semantics.
|
|
520
|
+
*
|
|
521
|
+
* This is the internal engine — consumers never see it.
|
|
522
|
+
* They interact with middleware through AgentConfig.middleware.
|
|
523
|
+
*/
|
|
524
|
+
|
|
525
|
+
/**
|
|
526
|
+
* Middleware runner — holds an ordered list of middleware and
|
|
527
|
+
* exposes methods to run each hook type with correct semantics.
|
|
528
|
+
*
|
|
529
|
+
* Immutable after construction. Fork creates a new runner
|
|
530
|
+
* (with inherited + additional middleware).
|
|
531
|
+
*/
|
|
532
|
+
declare class MiddlewareRunner {
|
|
533
|
+
private readonly stack;
|
|
534
|
+
constructor(middleware?: AgentMiddleware[]);
|
|
535
|
+
/** Number of registered middleware */
|
|
536
|
+
get count(): number;
|
|
537
|
+
/** Whether any middleware is registered */
|
|
538
|
+
get hasMiddleware(): boolean;
|
|
539
|
+
/** Get the middleware list (for fork inheritance) */
|
|
540
|
+
getMiddleware(): readonly AgentMiddleware[];
|
|
541
|
+
/**
|
|
542
|
+
* Run all `beforeToolCall` hooks in order.
|
|
543
|
+
*
|
|
544
|
+
* Returns `{ action: "allow" }` if all middleware allow (or have no hook).
|
|
545
|
+
* Returns `{ action: "deny", reason }` on first denial — remaining
|
|
546
|
+
* middleware are skipped.
|
|
547
|
+
*/
|
|
548
|
+
runBeforeToolCall(tool: string, args: unknown, ctx: ToolContext): Promise<ToolCallDecision>;
|
|
549
|
+
/**
|
|
550
|
+
* Run all `afterToolCall` hooks in reverse order.
|
|
551
|
+
*
|
|
552
|
+
* Each hook receives the result from the previous hook (or the
|
|
553
|
+
* original tool result for the first hook). Errors are caught
|
|
554
|
+
* and logged — the original result passes through.
|
|
555
|
+
*/
|
|
556
|
+
runAfterToolCall(tool: string, args: unknown, result: Tool.ExecuteResult, ctx: ToolContext): Promise<Tool.ExecuteResult>;
|
|
557
|
+
/**
|
|
558
|
+
* Collect prompt sections from all middleware.
|
|
559
|
+
*
|
|
560
|
+
* Returns a flat array of sections. Each middleware can return a single
|
|
561
|
+
* section, an array of sections, or undefined/empty.
|
|
562
|
+
*/
|
|
563
|
+
collectPromptSections(ctx: PromptBuildContext): PromptSection[];
|
|
564
|
+
/**
|
|
565
|
+
* Broadcast an event to all middleware observers.
|
|
566
|
+
*
|
|
567
|
+
* Non-blocking — errors are caught and logged. This never
|
|
568
|
+
* slows down the streaming pipeline.
|
|
569
|
+
*/
|
|
570
|
+
emitEvent(event: AgentEvent): void;
|
|
571
|
+
/**
|
|
572
|
+
* Get the OTel context for a session from the telemetry middleware.
|
|
573
|
+
* Returns undefined if no telemetry middleware is registered.
|
|
574
|
+
*/
|
|
575
|
+
getOtelContext(sessionId: string): unknown | undefined;
|
|
576
|
+
/**
|
|
577
|
+
* Run all `onChatStart` hooks in order.
|
|
578
|
+
*
|
|
579
|
+
* Errors are caught and logged — a broken logger should not
|
|
580
|
+
* prevent the chat from starting.
|
|
581
|
+
*/
|
|
582
|
+
runChatStart(sessionId: string, message: string): Promise<void>;
|
|
583
|
+
/**
|
|
584
|
+
* Run all `onChatEnd` hooks in order.
|
|
585
|
+
*
|
|
586
|
+
* Always called, even when the stream errored. Errors in handlers
|
|
587
|
+
* are caught and logged.
|
|
588
|
+
*/
|
|
589
|
+
runChatEnd(sessionId: string, result: {
|
|
590
|
+
usage?: TokenUsage;
|
|
591
|
+
error?: Error;
|
|
592
|
+
output?: string;
|
|
593
|
+
}): Promise<void>;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
export { type AgentEvent as A, type EnvironmentInfo as E, type InstructionFile as I, MiddlewareRunner as M, type PromptConfig as P, type StreamInput as S, type ToolCallDecision as T, type PromptBuildContext as a, type PromptSection as b, type ModelFamily as c, type ProcessorResult as d, type AgentTurnBoundaryKind as e, type AgentMiddleware as f, type AgentStatus as g, type ApprovalEvent as h };
|