@cuylabs/agent-core 0.3.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.
Files changed (66) hide show
  1. package/README.md +216 -41
  2. package/dist/builder-RcTZuYnO.d.ts +34 -0
  3. package/dist/capabilities/index.d.ts +97 -0
  4. package/dist/capabilities/index.js +46 -0
  5. package/dist/chunk-6TDTQJ4P.js +116 -0
  6. package/dist/chunk-7MUFEN4K.js +559 -0
  7. package/dist/chunk-BDBZ3SLK.js +745 -0
  8. package/dist/chunk-DWYX7ASF.js +26 -0
  9. package/dist/chunk-FG4MD5MU.js +54 -0
  10. package/dist/chunk-IMGQOTU2.js +2019 -0
  11. package/dist/chunk-IVUJDISU.js +556 -0
  12. package/dist/chunk-LRHOS4ZN.js +584 -0
  13. package/dist/chunk-OTUGSCED.js +691 -0
  14. package/dist/chunk-P6YF7USR.js +182 -0
  15. package/dist/chunk-QAQADS4X.js +258 -0
  16. package/dist/chunk-QWFMX226.js +879 -0
  17. package/dist/{chunk-6VKLWNRE.js → chunk-SDSBEQXG.js} +1 -132
  18. package/dist/chunk-VBWWUHWI.js +724 -0
  19. package/dist/chunk-VEKUXUVF.js +41 -0
  20. package/dist/chunk-X635CM2F.js +305 -0
  21. package/dist/chunk-YUUJK53A.js +91 -0
  22. package/dist/chunk-ZXAKHMWH.js +283 -0
  23. package/dist/config-D2xeGEHK.d.ts +52 -0
  24. package/dist/context/index.d.ts +259 -0
  25. package/dist/context/index.js +26 -0
  26. package/dist/identifiers-BLUxFqV_.d.ts +12 -0
  27. package/dist/index-p0kOsVsE.d.ts +1067 -0
  28. package/dist/index-tmhaADz5.d.ts +198 -0
  29. package/dist/index.d.ts +185 -4316
  30. package/dist/index.js +1238 -5368
  31. package/dist/mcp/index.d.ts +26 -0
  32. package/dist/mcp/index.js +14 -0
  33. package/dist/messages-BYWGn8TY.d.ts +110 -0
  34. package/dist/middleware/index.d.ts +7 -0
  35. package/dist/middleware/index.js +12 -0
  36. package/dist/models/index.d.ts +33 -0
  37. package/dist/models/index.js +12 -0
  38. package/dist/network-D76DS5ot.d.ts +5 -0
  39. package/dist/prompt/index.d.ts +224 -0
  40. package/dist/prompt/index.js +45 -0
  41. package/dist/reasoning/index.d.ts +71 -0
  42. package/dist/reasoning/index.js +47 -0
  43. package/dist/registry-CuRWWtcT.d.ts +164 -0
  44. package/dist/resolver-DOfZ-xuk.d.ts +254 -0
  45. package/dist/runner-C7aMP_x3.d.ts +596 -0
  46. package/dist/runtime/index.d.ts +357 -0
  47. package/dist/runtime/index.js +64 -0
  48. package/dist/session-manager-Uawm2Le7.d.ts +274 -0
  49. package/dist/skill/index.d.ts +103 -0
  50. package/dist/skill/index.js +39 -0
  51. package/dist/storage/index.d.ts +167 -0
  52. package/dist/storage/index.js +50 -0
  53. package/dist/sub-agent/index.d.ts +14 -0
  54. package/dist/sub-agent/index.js +15 -0
  55. package/dist/tool/index.d.ts +173 -1
  56. package/dist/tool/index.js +12 -3
  57. package/dist/tool-DYp6-cC3.d.ts +239 -0
  58. package/dist/tool-pFAnJc5Y.d.ts +419 -0
  59. package/dist/tracker-DClqYqTj.d.ts +96 -0
  60. package/dist/tracking/index.d.ts +109 -0
  61. package/dist/tracking/index.js +20 -0
  62. package/dist/types-CQaXbRsS.d.ts +47 -0
  63. package/dist/types-MM1JoX5T.d.ts +810 -0
  64. package/dist/types-VQgymC1N.d.ts +156 -0
  65. package/package.json +89 -5
  66. package/dist/index-QR704uRr.d.ts +0 -472
@@ -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 };