@cuylabs/agent-core 0.8.0 → 0.10.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 (127) hide show
  1. package/README.md +33 -17
  2. package/dist/chunk-2O4MCSQS.js +780 -0
  3. package/dist/chunk-2TTOLHBT.js +198 -0
  4. package/dist/chunk-5FMSGQVX.js +281 -0
  5. package/dist/chunk-5NVVNXPQ.js +288 -0
  6. package/dist/{chunk-CAA7FHIH.js → chunk-6HZBHFOL.js} +3 -103
  7. package/dist/chunk-CJI7PVS2.js +58 -0
  8. package/dist/{chunk-N6HWIEEA.js → chunk-CMYN2RCB.js} +278 -61
  9. package/dist/chunk-FII65CN7.js +117 -0
  10. package/dist/{chunk-IVUJDISU.js → chunk-GFTW23FV.js} +5 -14
  11. package/dist/chunk-I6PKJ7XQ.js +292 -0
  12. package/dist/{chunk-BDBZ3SLK.js → chunk-ICZ66572.js} +48 -4
  13. package/dist/chunk-KYLPMBHD.js +316 -0
  14. package/dist/chunk-MXAP4UG6.js +2956 -0
  15. package/dist/{chunk-RZITT45F.js → chunk-N3VX7FEE.js} +39 -6
  16. package/dist/{chunk-YSLSEQ6B.js → chunk-NDZWXCBZ.js} +218 -95
  17. package/dist/{chunk-P6YF7USR.js → chunk-Q742PSH3.js} +23 -38
  18. package/dist/chunk-QAL3OMI3.js +943 -0
  19. package/dist/{chunk-RFEKJKTO.js → chunk-RN6WZEUF.js} +330 -280
  20. package/dist/{chunk-ZXAKHMWH.js → chunk-ROTGCYDW.js} +22 -84
  21. package/dist/chunk-SPBFQXOT.js +0 -0
  22. package/dist/{chunk-LRHOS4ZN.js → chunk-SPILYYDF.js} +3 -2
  23. package/dist/chunk-SSFBF3US.js +602 -0
  24. package/dist/chunk-SZ2XBPTW.js +8 -0
  25. package/dist/chunk-T4UIX5D7.js +115 -0
  26. package/dist/chunk-TIHPYVAJ.js +102 -0
  27. package/dist/{chunk-YUUJK53A.js → chunk-TOTDGK3P.js} +1 -1
  28. package/dist/chunk-V4RFNEET.js +563 -0
  29. package/dist/chunk-VOUEJSW6.js +0 -0
  30. package/dist/{chunk-4BDA7DQY.js → chunk-WBPOZ7CL.js} +673 -273
  31. package/dist/chunk-X4VN4GIJ.js +185 -0
  32. package/dist/dispatch/index.d.ts +93 -0
  33. package/dist/dispatch/index.js +37 -0
  34. package/dist/events/index.d.ts +93 -0
  35. package/dist/events/index.js +6 -0
  36. package/dist/{runtime → execution}/index.d.ts +120 -34
  37. package/dist/{runtime → execution}/index.js +18 -13
  38. package/dist/index-BCqEGzBj.d.ts +251 -0
  39. package/dist/index.d.ts +490 -122
  40. package/dist/index.js +2104 -615
  41. package/dist/{errors → inference/errors}/index.d.ts +2 -2
  42. package/dist/{errors → inference/errors}/index.js +1 -1
  43. package/dist/inference/index.d.ts +16 -23
  44. package/dist/inference/index.js +45 -16
  45. package/dist/instance-BqV2D5pc.d.ts +5723 -0
  46. package/dist/logger/index.d.ts +50 -0
  47. package/dist/logger/index.js +11 -0
  48. package/dist/mcp/index.d.ts +5 -9
  49. package/dist/mcp/index.js +2 -3
  50. package/dist/middleware/index.d.ts +10 -149
  51. package/dist/middleware/index.js +11 -3
  52. package/dist/model-messages-B4nK9D1-.d.ts +13 -0
  53. package/dist/models/index.d.ts +23 -18
  54. package/dist/models/index.js +48 -11
  55. package/dist/models/reasoning/index.d.ts +4 -0
  56. package/dist/{reasoning → models/reasoning}/index.js +3 -3
  57. package/dist/plugin/index.d.ts +458 -0
  58. package/dist/plugin/index.js +32 -0
  59. package/dist/profiles/index.d.ts +55 -0
  60. package/dist/profiles/index.js +30 -0
  61. package/dist/prompt/index.d.ts +8 -12
  62. package/dist/prompt/index.js +3 -2
  63. package/dist/safety/index.d.ts +109 -14
  64. package/dist/safety/index.js +59 -3
  65. package/dist/sandbox/index.d.ts +81 -0
  66. package/dist/sandbox/index.js +1 -0
  67. package/dist/skill/index.d.ts +10 -8
  68. package/dist/skill/index.js +3 -3
  69. package/dist/storage/index.d.ts +12 -4
  70. package/dist/storage/index.js +1 -1
  71. package/dist/subagents/index.d.ts +177 -0
  72. package/dist/subagents/index.js +78 -0
  73. package/dist/team/index.d.ts +544 -0
  74. package/dist/team/index.js +41 -0
  75. package/dist/tool/host/index.d.ts +41 -0
  76. package/dist/tool/host/index.js +10 -0
  77. package/dist/tool/index.d.ts +125 -21
  78. package/dist/tool/index.js +20 -13
  79. package/dist/{types-VQgymC1N.d.ts → types-Bj_J8u_W.d.ts} +44 -64
  80. package/dist/{types-CHiPh8U2.d.ts → types-C_LCeYNg.d.ts} +7 -7
  81. package/dist/types-RSCv7nQ4.d.ts +59 -0
  82. package/package.json +58 -53
  83. package/dist/builder-UpOWQMW3.d.ts +0 -34
  84. package/dist/chunk-7MUFEN4K.js +0 -559
  85. package/dist/chunk-7VKQ4WPB.js +0 -73
  86. package/dist/chunk-BFM2YHNM.js +0 -222
  87. package/dist/chunk-DWYX7ASF.js +0 -26
  88. package/dist/chunk-KUVSERLJ.js +0 -50
  89. package/dist/chunk-N7P4PN3O.js +0 -84
  90. package/dist/chunk-SDSBEQXG.js +0 -157
  91. package/dist/chunk-SQU2AJHO.js +0 -305
  92. package/dist/chunk-VBWWUHWI.js +0 -724
  93. package/dist/chunk-VEKUXUVF.js +0 -41
  94. package/dist/chunk-VNQBHPCT.js +0 -398
  95. package/dist/chunk-WWYYNWEW.js +0 -259
  96. package/dist/context/index.d.ts +0 -259
  97. package/dist/context/index.js +0 -26
  98. package/dist/events-CE72w8W4.d.ts +0 -149
  99. package/dist/host/index.d.ts +0 -45
  100. package/dist/host/index.js +0 -8
  101. package/dist/index-CWSchSql.d.ts +0 -1058
  102. package/dist/messages-BYWGn8TY.d.ts +0 -110
  103. package/dist/presets/index.d.ts +0 -53
  104. package/dist/presets/index.js +0 -28
  105. package/dist/reasoning/index.d.ts +0 -116
  106. package/dist/registry-DwYqsQkX.d.ts +0 -164
  107. package/dist/runner-e2YRcUoX.d.ts +0 -786
  108. package/dist/scope/index.d.ts +0 -10
  109. package/dist/scope/index.js +0 -14
  110. package/dist/session-manager-B_CWGTsl.d.ts +0 -274
  111. package/dist/signal/index.d.ts +0 -28
  112. package/dist/signal/index.js +0 -6
  113. package/dist/sub-agent/index.d.ts +0 -23
  114. package/dist/sub-agent/index.js +0 -15
  115. package/dist/tool-BHbyUAy3.d.ts +0 -150
  116. package/dist/tool-DLXAR9Ce.d.ts +0 -145
  117. package/dist/tracker-DClqYqTj.d.ts +0 -96
  118. package/dist/tracking/index.d.ts +0 -111
  119. package/dist/tracking/index.js +0 -20
  120. package/dist/types-BfNpU8NS.d.ts +0 -270
  121. package/dist/types-BnpEOYV-.d.ts +0 -50
  122. package/dist/types-CQL-SvTn.d.ts +0 -29
  123. package/dist/types-CWm-7rvB.d.ts +0 -55
  124. package/dist/types-KKDrdU9Y.d.ts +0 -325
  125. package/dist/types-QA4WhEfz.d.ts +0 -138
  126. package/dist/types-QKHHQLLq.d.ts +0 -336
  127. package/dist/types-YuWV4ag7.d.ts +0 -72
@@ -1,786 +0,0 @@
1
- import { LanguageModel, ModelMessage, TelemetrySettings, SystemModelMessage } from 'ai';
2
- import { ProviderOptions } from '@ai-sdk/provider-utils';
3
- import { A as AgentEvent } from './events-CE72w8W4.js';
4
- import { d as SkillConfig } from './types-BfNpU8NS.js';
5
- import { T as TokenUsage } from './messages-BYWGn8TY.js';
6
- import { S as ScopeSnapshot } from './types-CQL-SvTn.js';
7
- import { b as ToolContext } from './tool-DLXAR9Ce.js';
8
- import { T as Tool } from './tool-BHbyUAy3.js';
9
- import { R as ReasoningLevel } from './types-CQaXbRsS.js';
10
-
11
- /**
12
- * Stream types for @cuylabs/agent-core
13
- *
14
- * Defines the canonical StreamChunk union and related types
15
- * for both AI SDK native and custom stream providers.
16
- */
17
- /**
18
- * Stream chunk types (AI SDK compatible + custom streams)
19
- *
20
- * This is the single canonical definition — used by both the
21
- * streaming module and custom stream providers.
22
- */
23
- type StreamChunk = {
24
- type: "text-start";
25
- } | {
26
- type: "text-delta";
27
- text: string;
28
- } | {
29
- type: "text-end";
30
- } | {
31
- type: "reasoning-start";
32
- id: string;
33
- } | {
34
- type: "reasoning-delta";
35
- id: string;
36
- text: string;
37
- } | {
38
- type: "reasoning-end";
39
- id: string;
40
- } | {
41
- type: "tool-call";
42
- toolName: string;
43
- toolCallId: string;
44
- input: unknown;
45
- } | {
46
- type: "tool-result";
47
- toolName: string;
48
- toolCallId: string;
49
- output: unknown;
50
- } | {
51
- type: "tool-error";
52
- toolName: string;
53
- toolCallId: string;
54
- error: unknown;
55
- } | {
56
- type: "finish-step";
57
- usage?: {
58
- inputTokens?: number;
59
- outputTokens?: number;
60
- totalTokens?: number;
61
- };
62
- finishReason?: string;
63
- } | {
64
- type: "finish";
65
- totalUsage?: {
66
- inputTokens?: number;
67
- outputTokens?: number;
68
- totalTokens?: number;
69
- };
70
- } | {
71
- type: "error";
72
- error: unknown;
73
- } | {
74
- type: "start-step";
75
- } | {
76
- type: "start";
77
- } | {
78
- type: "abort";
79
- } | {
80
- type: "computer-call";
81
- callId: string;
82
- action: unknown;
83
- pendingSafetyChecks?: unknown[];
84
- } | {
85
- type: "step-usage";
86
- usage: {
87
- inputTokens: number;
88
- outputTokens: number;
89
- totalTokens: number;
90
- };
91
- };
92
- /**
93
- * Custom stream provider function type.
94
- *
95
- * This matches the signature needed for agent-core's inference module,
96
- * returning a StreamProviderResult-compatible object.
97
- */
98
- type StreamProvider = (input: StreamProviderInput) => Promise<StreamProviderResult>;
99
- /**
100
- * Input for custom stream providers
101
- */
102
- interface StreamProviderInput {
103
- /** System prompt */
104
- system: string;
105
- /** Messages to send */
106
- messages: Array<{
107
- role: string;
108
- content: unknown;
109
- }>;
110
- /** Abort signal */
111
- abortSignal?: AbortSignal;
112
- /** Max iterations */
113
- maxSteps?: number;
114
- }
115
- /**
116
- * Result from custom stream providers (AI SDK StreamTextResult compatible)
117
- */
118
- interface StreamProviderResult {
119
- /** Async iterable of stream chunks */
120
- fullStream: AsyncIterable<StreamChunk>;
121
- /** Promise resolving to final text */
122
- text: Promise<string>;
123
- /** Promise resolving to usage stats */
124
- usage: Promise<{
125
- inputTokens: number;
126
- outputTokens: number;
127
- totalTokens: number;
128
- }>;
129
- /** Promise resolving to finish reason */
130
- finishReason: Promise<string>;
131
- }
132
- /**
133
- * Configuration for stream provider factory.
134
- * Contains everything needed to create a stream provider for a specific model.
135
- */
136
- interface StreamProviderConfig {
137
- /** API key to use */
138
- apiKey?: string;
139
- /** Display dimensions */
140
- display?: {
141
- width: number;
142
- height: number;
143
- };
144
- /** Environment type */
145
- environment?: string;
146
- /** Enable debug logging */
147
- debug?: boolean;
148
- }
149
- /**
150
- * Stream provider factory - creates a stream provider for a given model.
151
- *
152
- * This is attached to enhanced tools (like computer tools) to allow
153
- * the Agent to automatically configure the right stream provider
154
- * when a model requires custom handling (e.g., OpenAI computer-use-preview).
155
- */
156
- type StreamProviderFactory = (modelId: string, config: StreamProviderConfig) => StreamProvider;
157
- /**
158
- * Enhanced tools array with additional capabilities.
159
- *
160
- * This extends the standard Tool.AnyInfo[] with optional metadata
161
- * that the Agent can use for automatic configuration.
162
- */
163
- interface EnhancedTools extends Array<unknown> {
164
- /**
165
- * Factory to create a stream provider for models that need custom streaming.
166
- * Called by the Agent when it detects a model that requires special handling.
167
- */
168
- __streamProviderFactory?: StreamProviderFactory;
169
- /**
170
- * Model patterns that require the custom stream provider.
171
- * Used by the Agent to detect when to use the factory.
172
- * Default patterns: ["computer-use-preview"]
173
- */
174
- __customStreamModels?: string[];
175
- }
176
-
177
- /**
178
- * Prompt Pipeline Types
179
- *
180
- * Types for the layered system prompt architecture.
181
- * The prompt pipeline composes a system prompt from multiple sources:
182
- *
183
- * Base Template → Environment → Instructions → Custom Sections → Per-Turn
184
- *
185
- * Each layer is optional, composable, and can be toggled on/off.
186
- */
187
-
188
- /**
189
- * Model family identifier for prompt template selection.
190
- *
191
- * Each family gets a base template optimized for its strengths:
192
- * - `anthropic`: Claude models — structured sections with XML tags
193
- * - `openai`: GPT/o-series models — clear directives with markdown
194
- * - `google`: Gemini models — balanced approach
195
- * - `deepseek`: DeepSeek models — code-focused emphasis
196
- * - `default`: Generic template for any model
197
- */
198
- type ModelFamily = "anthropic" | "openai" | "google" | "deepseek" | "default";
199
- /**
200
- * Runtime environment information injected into the system prompt.
201
- * Gives the model awareness of the working context.
202
- */
203
- interface EnvironmentInfo {
204
- /** Current working directory */
205
- cwd: string;
206
- /** Operating system (e.g. "macOS (darwin arm64)") */
207
- platform: string;
208
- /** Current date/time formatted string */
209
- date: string;
210
- /** User's shell (e.g. "/bin/zsh") */
211
- shell?: string;
212
- /** Active git branch, if inside a repo */
213
- gitBranch?: string;
214
- /** Whether the working tree is clean */
215
- gitClean?: boolean;
216
- /** Git repo root path */
217
- gitRoot?: string;
218
- }
219
- /**
220
- * An instruction file discovered on disk (e.g. AGENTS.md).
221
- *
222
- * Instruction files provide project-specific or workspace-level guidance
223
- * that gets injected into every prompt. They're discovered by walking up
224
- * the directory tree from cwd.
225
- */
226
- interface InstructionFile {
227
- /** Absolute path to the file */
228
- path: string;
229
- /** File content (trimmed) */
230
- content: string;
231
- /** How the file was discovered */
232
- source: "project" | "workspace" | "global";
233
- /** Depth from cwd (0 = same directory) */
234
- depth: number;
235
- }
236
- /**
237
- * A composable section in the prompt pipeline.
238
- *
239
- * Sections are the building blocks of the final system prompt.
240
- * Each section has a priority that determines its position in the output.
241
- *
242
- * Default priority ranges:
243
- * - 10: Base template
244
- * - 20: Environment block
245
- * - 30: Instruction files
246
- * - 50: Custom sections (default for user-added)
247
- * - 70: Reserved for future use (e.g. Skills)
248
- * - 90: Per-turn overrides
249
- */
250
- interface PromptSection {
251
- /** Unique identifier for this section */
252
- id: string;
253
- /** Human-readable label (useful for debugging/logging) */
254
- label: string;
255
- /** The text content of this section */
256
- content: string;
257
- /** Sort priority — lower values appear earlier (default: 50) */
258
- priority?: number;
259
- /** Whether this section is active (default: true) */
260
- enabled?: boolean;
261
- }
262
- /**
263
- * Context passed to the builder for each prompt build.
264
- *
265
- * This provides the runtime information needed to compose
266
- * the system prompt for a specific conversation turn.
267
- */
268
- interface PromptBuildContext {
269
- /** Current working directory */
270
- cwd: string;
271
- /** The language model being used */
272
- model: LanguageModel;
273
- /** Names of available tools (for template customization) */
274
- toolNames?: string[];
275
- /** Per-turn additional instructions (from chat options) */
276
- override?: string;
277
- /** Current session ID */
278
- sessionId?: string;
279
- }
280
- /**
281
- * Configuration for the prompt pipeline.
282
- *
283
- * Controls which layers are active and how they behave.
284
- * All options have sensible defaults — an empty config `{}` gives you
285
- * the full pipeline with auto-detection.
286
- *
287
- * @example
288
- * ```typescript
289
- * // Minimal — use all defaults
290
- * const builder = createPromptBuilder();
291
- *
292
- * // Custom base template but keep environment + instructions
293
- * const builder = createPromptBuilder({
294
- * baseTemplate: "You are a security auditor...",
295
- * includeEnvironment: true,
296
- * includeInstructions: true,
297
- * });
298
- *
299
- * // Fully custom — disable auto features, add your own sections
300
- * const builder = createPromptBuilder({
301
- * includeEnvironment: false,
302
- * includeInstructions: false,
303
- * sections: [
304
- * { id: "role", label: "Role", content: "You audit code.", priority: 10 },
305
- * { id: "rules", label: "Rules", content: "Never modify files.", priority: 20 },
306
- * ],
307
- * });
308
- * ```
309
- */
310
- interface PromptConfig {
311
- /**
312
- * Override the base template entirely.
313
- * If set, replaces the model-family-specific template.
314
- */
315
- baseTemplate?: string;
316
- /**
317
- * Force a specific model family for template selection.
318
- * Auto-detected from the model if not provided.
319
- */
320
- modelFamily?: ModelFamily;
321
- /**
322
- * Inject runtime environment info (cwd, platform, git, date).
323
- * @default true
324
- */
325
- includeEnvironment?: boolean;
326
- /**
327
- * Discover and include instruction files (AGENTS.md, etc.).
328
- * @default true
329
- */
330
- includeInstructions?: boolean;
331
- /**
332
- * File name patterns to search for when discovering instructions.
333
- * Searched in each directory walking up from cwd.
334
- *
335
- * @default ["AGENTS.md", "CLAUDE.md", "COPILOT.md", ".cuylabs/instructions.md"]
336
- */
337
- instructionPatterns?: string[];
338
- /**
339
- * Absolute paths to global instruction files (always included
340
- * regardless of cwd). Useful for organization-wide rules.
341
- */
342
- globalInstructions?: string[];
343
- /**
344
- * Maximum depth to walk up from cwd when searching for instructions.
345
- * Prevents scanning the entire filesystem.
346
- * @default 10
347
- */
348
- instructionMaxDepth?: number;
349
- /**
350
- * Maximum file size in bytes for instruction files.
351
- * Files larger than this are skipped to avoid bloating the prompt.
352
- * @default 51200 (50KB)
353
- */
354
- instructionMaxSize?: number;
355
- /**
356
- * Pre-defined sections to include in every prompt build.
357
- * These are merged with auto-generated sections (template, environment, etc.).
358
- */
359
- sections?: PromptSection[];
360
- /**
361
- * Separator between sections in the final composed prompt.
362
- * @default "\n\n"
363
- */
364
- separator?: string;
365
- /**
366
- * Skill discovery and loading configuration.
367
- *
368
- * When provided, the prompt pipeline will:
369
- * 1. Discover SKILL.md files from project, user, and global directories
370
- * 2. Inject skill summaries at PRIORITY_SKILLS (70) in the system prompt
371
- * 3. Make `skill` and `skill_resource` tools available to the agent
372
- *
373
- * Skills use progressive disclosure:
374
- * - L1 (summary): always in system prompt — names + descriptions
375
- * - L2 (content): loaded on demand via `skill` tool
376
- * - L3 (resources): loaded on demand via `skill_resource` tool
377
- *
378
- * @example
379
- * ```typescript
380
- * const agent = createAgent({
381
- * model: anthropic("claude-sonnet-4-20250514"),
382
- * prompt: {
383
- * skills: {
384
- * externalDirs: [".agents", ".claude"],
385
- * roots: ["./company-skills"],
386
- * },
387
- * },
388
- * });
389
- * ```
390
- */
391
- skills?: SkillConfig;
392
- }
393
-
394
- /**
395
- * Middleware Types
396
- *
397
- * Defines the composable middleware interface for agent lifecycle hooks.
398
- *
399
- * Middleware is just a plain object with optional hook methods — no
400
- * base classes, no discovery, no installation. Pass it in code:
401
- *
402
- * ```typescript
403
- * const agent = createAgent({
404
- * middleware: [myLoggerMiddleware, myApprovalMiddleware],
405
- * });
406
- * ```
407
- *
408
- * Hooks run in array order for "before" operations and reverse order
409
- * for "after" operations (like middleware stacks everywhere).
410
- */
411
-
412
- /**
413
- * Action returned by `beforeToolCall` — determines whether
414
- * the tool call proceeds or is blocked.
415
- */
416
- interface ToolCallDecision {
417
- /** Whether to allow or deny the tool call */
418
- action: "allow" | "deny";
419
- /** Reason for denial — returned to the model as the tool output */
420
- reason?: string;
421
- }
422
- /**
423
- * Mutable model invocation payload presented to middleware before an LLM call.
424
- */
425
- interface ModelCallInput {
426
- model: LanguageModel;
427
- system: string[];
428
- messages: ModelMessage[];
429
- temperature?: number;
430
- topP?: number;
431
- maxOutputTokens?: number;
432
- maxSteps?: number;
433
- reasoningLevel?: ReasoningLevel;
434
- telemetry?: TelemetrySettings;
435
- customStreamProvider?: StreamProvider;
436
- toolExecutionMode?: "auto" | "plan";
437
- /**
438
- * Provider-specific options passed through to `streamText()`.
439
- *
440
- * Middleware can set these to enable provider features like Anthropic
441
- * prompt caching (`{ anthropic: { cacheControl: { type: "ephemeral" } } }`).
442
- *
443
- * When multiple sources set providerOptions (e.g. middleware + reasoning),
444
- * they are shallow-merged before the LLM call.
445
- */
446
- providerOptions?: ProviderOptions;
447
- /**
448
- * System messages with provider-specific options.
449
- *
450
- * When set, these take precedence over the plain `system` strings.
451
- * This allows middleware to attach per-message metadata such as
452
- * Anthropic `cacheControl` breakpoints on system content.
453
- *
454
- * Leave undefined to use the plain `system` string array.
455
- */
456
- systemMessages?: SystemModelMessage[];
457
- }
458
- /**
459
- * Context shared across model middleware hooks for a single step.
460
- */
461
- interface ModelCallContext {
462
- sessionID: string;
463
- step: number;
464
- cwd: string;
465
- abort: AbortSignal;
466
- model: LanguageModel;
467
- toolNames: string[];
468
- mcpToolNames: string[];
469
- scope?: ScopeSnapshot;
470
- }
471
- /**
472
- * Return this from `model.input(...)` to stop an LLM call entirely.
473
- */
474
- interface BlockedModelCall {
475
- block: true;
476
- reason: string;
477
- }
478
- /**
479
- * Final step result exposed to model middleware after the stream is processed.
480
- */
481
- interface ModelCallOutput {
482
- text: string;
483
- usage?: TokenUsage;
484
- finishReason?: string;
485
- }
486
- /**
487
- * Optional model-specific hooks grouped under `middleware.model`.
488
- */
489
- interface AgentModelHooks {
490
- /**
491
- * Review or rewrite the model request before the LLM is invoked.
492
- *
493
- * Return:
494
- * - `undefined` to keep the current request
495
- * - a `ModelCallInput` object to replace the request
496
- * - `{ block: true, reason }` to cancel the model call
497
- *
498
- * Hooks run in middleware array order. The first block stops the call.
499
- */
500
- input?(input: ModelCallInput, ctx: ModelCallContext): Promise<ModelCallInput | BlockedModelCall | void>;
501
- /**
502
- * Review or rewrite raw stream chunks as they arrive from the model.
503
- *
504
- * Return:
505
- * - `undefined` to keep the current chunk
506
- * - a `StreamChunk` to replace it
507
- * - `null` to drop it from downstream processing
508
- *
509
- * Hooks run in middleware array order.
510
- */
511
- chunk?(chunk: StreamChunk, ctx: ModelCallContext): Promise<StreamChunk | null | void>;
512
- /**
513
- * Review or rewrite the fully processed model result for the current step.
514
- *
515
- * Hooks run in reverse middleware order so outer middleware sees the final
516
- * shaped result, matching `afterToolCall(...)`.
517
- */
518
- output?(output: ModelCallOutput, ctx: ModelCallContext): Promise<ModelCallOutput | void>;
519
- }
520
- /**
521
- * Agent middleware — composable lifecycle hooks.
522
- *
523
- * All methods are optional. Implement only what you need.
524
- *
525
- * Ordering:
526
- * - `beforeToolCall`: runs in array order, first "deny" wins
527
- * - `afterToolCall`: runs in reverse order (innermost first)
528
- * - `model.input`: runs in array order, first block wins
529
- * - `model.chunk`: runs in array order on raw stream chunks
530
- * - `model.output`: runs in reverse order
531
- * - `promptSections`: all run, sections merged
532
- * - `onEvent`: all run in parallel (non-blocking)
533
- * - `onChatStart` / `onChatEnd`: run in array order, awaited sequentially
534
- *
535
- * @example
536
- * ```typescript
537
- * // A simple logging middleware
538
- * const logger: AgentMiddleware = {
539
- * name: "logger",
540
- * beforeToolCall: async (tool, args) => {
541
- * console.log(`→ ${tool}`, args);
542
- * return { action: "allow" };
543
- * },
544
- * afterToolCall: async (tool, args, result) => {
545
- * console.log(`← ${tool}`, result.title);
546
- * return result;
547
- * },
548
- * };
549
- * ```
550
- */
551
- interface AgentMiddleware {
552
- /** Middleware name (for logging and debugging) */
553
- name: string;
554
- /**
555
- * Optional hooks for shaping model requests, raw stream chunks,
556
- * and final step outputs.
557
- */
558
- model?: AgentModelHooks;
559
- /**
560
- * Intercept a tool call before execution.
561
- *
562
- * Return `{ action: "allow" }` to proceed, or `{ action: "deny", reason }` to
563
- * block the call. When denied, `reason` is returned to the model as the tool
564
- * output so it can adjust its approach.
565
- *
566
- * Runs in array order. The first middleware that returns "deny" short-circuits
567
- * the chain — remaining middleware and the tool itself are skipped.
568
- *
569
- * @param tool - Tool name (e.g. "bash", "write_file")
570
- * @param args - Parsed tool arguments
571
- * @param ctx - Tool execution context (cwd, sessionID, host, etc.)
572
- */
573
- beforeToolCall?(tool: string, args: unknown, ctx: ToolContext): Promise<ToolCallDecision>;
574
- /**
575
- * Transform or observe a tool result after execution.
576
- *
577
- * Receives the result and must return a result (can be the same object
578
- * or a modified copy). Runs in reverse array order so the outermost
579
- * middleware sees the final transformed result.
580
- *
581
- * @param tool - Tool name
582
- * @param args - Original tool arguments
583
- * @param result - Tool execution result
584
- * @param ctx - Tool execution context
585
- */
586
- afterToolCall?(tool: string, args: unknown, result: Tool.ExecuteResult, ctx: ToolContext): Promise<Tool.ExecuteResult>;
587
- /**
588
- * Inject dynamic prompt sections at build time.
589
- *
590
- * Called during `PromptBuilder.build()` for each middleware. Return one
591
- * or more sections to inject into the system prompt. Return `undefined`
592
- * or an empty array to inject nothing.
593
- *
594
- * Sections follow the same priority system as static sections — use
595
- * `priority` to control placement relative to base template (10),
596
- * environment (20), instructions (30), custom (50), skills (70),
597
- * and per-turn overrides (90).
598
- *
599
- * @param ctx - Build context with cwd, model, toolNames, sessionId
600
- */
601
- promptSections?(ctx: PromptBuildContext): PromptSection | PromptSection[] | undefined;
602
- /**
603
- * Observe agent events (read-only, non-blocking).
604
- *
605
- * Fires for every event emitted during `chat()`. Errors thrown by
606
- * handlers are caught and logged — they never interrupt the stream.
607
- *
608
- * This is intentionally synchronous (void return) to prevent
609
- * event observers from blocking the streaming pipeline.
610
- *
611
- * @param event - The agent event
612
- */
613
- onEvent?(event: AgentEvent): void;
614
- /**
615
- * Called when `chat()` starts, before the LLM stream is created.
616
- *
617
- * Use this for setup: initializing loggers, recording start time,
618
- * resetting per-turn state, etc. Runs in array order, awaited
619
- * sequentially.
620
- *
621
- * @param sessionId - Session identifier
622
- * @param message - The user message being sent
623
- */
624
- onChatStart?(sessionId: string, message: string): Promise<void>;
625
- /**
626
- * Called when `chat()` completes (or errors), after all events
627
- * have been yielded.
628
- *
629
- * Use this for teardown: flushing logs, recording metrics, etc.
630
- * Runs in array order, awaited sequentially. Always called, even
631
- * if the stream errored.
632
- *
633
- * @param sessionId - Session identifier
634
- * @param result - Completion info (usage stats and optional error)
635
- */
636
- onChatEnd?(sessionId: string, result: {
637
- usage?: TokenUsage;
638
- error?: Error;
639
- output?: string;
640
- }): Promise<void>;
641
- /**
642
- * Get the active OTel context for a session.
643
- *
644
- * Used internally by the LLM layer to wrap `streamText()` so that
645
- * AI SDK spans are nested under the middleware's parent span.
646
- * Only implemented by the `otelMiddleware`.
647
- */
648
- getOtelContext?(sessionId: string): unknown;
649
- }
650
- /**
651
- * A user-facing command a plugin can register.
652
- *
653
- * How commands surface depends on the host:
654
- * - CLI/TUI → slash commands (e.g. `/deploy`)
655
- * - HTTP → could be API routes
656
- * - Chatbot → chat commands
657
- *
658
- * Hosts that don't support commands can silently ignore them.
659
- */
660
- interface PluginCommand {
661
- /** Command name (without leading slash) */
662
- name: string;
663
- /** Optional aliases */
664
- alias?: string[];
665
- /** One-line description shown in help */
666
- summary: string;
667
- /** Execute the command. Return the text to display, or null for silent. */
668
- execute: (args: string) => Promise<string | null>;
669
- }
670
- /**
671
- * The context object passed to a plugin's default export.
672
- *
673
- * Through the context, plugins contribute tools, middleware, and
674
- * (optionally) host-specific commands.
675
- *
676
- * @example
677
- * ```ts
678
- * import { Tool, z, type PluginContext } from "@cuylabs/agent-code";
679
- *
680
- * export default function (ctx: PluginContext) {
681
- * ctx.addTool(Tool.define("ping", {
682
- * description: "Pong!",
683
- * parameters: z.object({}),
684
- * execute: async () => ({ title: "pong", output: "pong", metadata: {} }),
685
- * }));
686
- * }
687
- * ```
688
- */
689
- interface PluginContext {
690
- /** Working directory of the agent (project root) */
691
- cwd: string;
692
- /** Register a tool the LLM can call */
693
- addTool(tool: Tool.AnyInfo): void;
694
- /** Register middleware (model hooks, tool guards, prompt sections) */
695
- addMiddleware(mw: AgentMiddleware): void;
696
- /** Register a user-facing command (host-dependent) */
697
- addCommand(cmd: PluginCommand): void;
698
- }
699
- /** The function shape a plugin file must default-export. */
700
- type PluginInit = (ctx: PluginContext) => void | Promise<void>;
701
-
702
- /**
703
- * Middleware Runner
704
- *
705
- * Executes middleware hooks in the correct order with proper
706
- * error handling and short-circuit semantics.
707
- *
708
- * This is the internal engine — consumers never see it.
709
- * They interact with middleware through AgentConfig.middleware.
710
- */
711
-
712
- /**
713
- * Middleware runner — holds an ordered list of middleware and
714
- * exposes methods to run each hook type with correct semantics.
715
- *
716
- * Immutable after construction. Fork creates a new runner
717
- * (with inherited + additional middleware).
718
- */
719
- declare class MiddlewareRunner {
720
- private readonly stack;
721
- constructor(middleware?: AgentMiddleware[]);
722
- /** Number of registered middleware */
723
- get count(): number;
724
- /** Whether any middleware is registered */
725
- get hasMiddleware(): boolean;
726
- /** Get the middleware list (for fork inheritance) */
727
- getMiddleware(): readonly AgentMiddleware[];
728
- runModelInput(input: ModelCallInput, ctx: ModelCallContext): Promise<ModelCallInput | BlockedModelCall>;
729
- runModelChunk(chunk: StreamChunk, ctx: ModelCallContext): Promise<StreamChunk | undefined>;
730
- runModelOutput(output: ModelCallOutput, ctx: ModelCallContext): Promise<ModelCallOutput>;
731
- /**
732
- * Run all `beforeToolCall` hooks in order.
733
- *
734
- * Returns `{ action: "allow" }` if all middleware allow (or have no hook).
735
- * Returns `{ action: "deny", reason }` on first denial — remaining
736
- * middleware are skipped.
737
- */
738
- runBeforeToolCall(tool: string, args: unknown, ctx: ToolContext): Promise<ToolCallDecision>;
739
- /**
740
- * Run all `afterToolCall` hooks in reverse order.
741
- *
742
- * Each hook receives the result from the previous hook (or the
743
- * original tool result for the first hook). Errors are caught
744
- * and logged — the original result passes through.
745
- */
746
- runAfterToolCall(tool: string, args: unknown, result: Tool.ExecuteResult, ctx: ToolContext): Promise<Tool.ExecuteResult>;
747
- /**
748
- * Collect prompt sections from all middleware.
749
- *
750
- * Returns a flat array of sections. Each middleware can return a single
751
- * section, an array of sections, or undefined/empty.
752
- */
753
- collectPromptSections(ctx: PromptBuildContext): PromptSection[];
754
- /**
755
- * Broadcast an event to all middleware observers.
756
- *
757
- * Non-blocking — errors are caught and logged. This never
758
- * slows down the streaming pipeline.
759
- */
760
- emitEvent(event: AgentEvent): void;
761
- /**
762
- * Get the OTel context for a session from the telemetry middleware.
763
- * Returns undefined if no telemetry middleware is registered.
764
- */
765
- getOtelContext(sessionId: string): unknown | undefined;
766
- /**
767
- * Run all `onChatStart` hooks in order.
768
- *
769
- * Errors are caught and logged — a broken logger should not
770
- * prevent the chat from starting.
771
- */
772
- runChatStart(sessionId: string, message: string): Promise<void>;
773
- /**
774
- * Run all `onChatEnd` hooks in order.
775
- *
776
- * Always called, even when the stream errored. Errors in handlers
777
- * are caught and logged.
778
- */
779
- runChatEnd(sessionId: string, result: {
780
- usage?: TokenUsage;
781
- error?: Error;
782
- output?: string;
783
- }): Promise<void>;
784
- }
785
-
786
- export { type AgentMiddleware as A, type BlockedModelCall as B, type EnhancedTools as E, type InstructionFile as I, MiddlewareRunner as M, type PromptConfig as P, type StreamChunk as S, type ToolCallDecision as T, type PromptBuildContext as a, type PromptSection as b, type ModelFamily as c, type StreamProvider as d, type ModelCallInput as e, type AgentModelHooks as f, type EnvironmentInfo as g, type ModelCallContext as h, type ModelCallOutput as i, type PluginCommand as j, type PluginContext as k, type PluginInit as l, type StreamProviderConfig as m, type StreamProviderFactory as n, type StreamProviderInput as o, type StreamProviderResult as p };