@cuylabs/agent-core 0.9.0 → 0.11.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 (116) 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-EKR6PKXU.js → chunk-6HZBHFOL.js} +3 -3
  7. package/dist/chunk-CJI7PVS2.js +58 -0
  8. package/dist/{chunk-WKHDSSXG.js → chunk-CMYN2RCB.js} +146 -46
  9. package/dist/chunk-FII65CN7.js +117 -0
  10. package/dist/{chunk-UHCJEM2E.js → chunk-ICZ66572.js} +13 -6
  11. package/dist/chunk-KYLPMBHD.js +316 -0
  12. package/dist/chunk-MXAP4UG6.js +2956 -0
  13. package/dist/{chunk-4QFNWPIF.js → chunk-N3VX7FEE.js} +35 -2
  14. package/dist/{chunk-MAZ5DY5B.js → chunk-NDZWXCBZ.js} +213 -78
  15. package/dist/{chunk-MHKK374K.js → chunk-Q742PSH3.js} +11 -27
  16. package/dist/{chunk-WGZAPU6N.js → chunk-QAL3OMI3.js} +15 -1
  17. package/dist/{chunk-UDCZ673N.js → chunk-RN6WZEUF.js} +27 -23
  18. package/dist/{chunk-ZXAKHMWH.js → chunk-ROTGCYDW.js} +22 -84
  19. package/dist/chunk-SPBFQXOT.js +0 -0
  20. package/dist/chunk-SSFBF3US.js +602 -0
  21. package/dist/chunk-SZ2XBPTW.js +8 -0
  22. package/dist/chunk-T4UIX5D7.js +115 -0
  23. package/dist/{chunk-IYWQOJMQ.js → chunk-TIHPYVAJ.js} +34 -34
  24. package/dist/{chunk-RKEW5WXI.js → chunk-TOTDGK3P.js} +1 -1
  25. package/dist/chunk-V4RFNEET.js +563 -0
  26. package/dist/chunk-VOUEJSW6.js +0 -0
  27. package/dist/{chunk-J4QDGZIA.js → chunk-WBPOZ7CL.js} +659 -275
  28. package/dist/chunk-X4VN4GIJ.js +185 -0
  29. package/dist/dispatch/index.d.ts +93 -0
  30. package/dist/dispatch/index.js +37 -0
  31. package/dist/events/index.d.ts +93 -0
  32. package/dist/events/index.js +6 -0
  33. package/dist/{runtime → execution}/index.d.ts +120 -35
  34. package/dist/{runtime → execution}/index.js +17 -11
  35. package/dist/index.d.ts +489 -115
  36. package/dist/index.js +1665 -462
  37. package/dist/inference/errors/index.js +1 -1
  38. package/dist/inference/index.d.ts +13 -21
  39. package/dist/inference/index.js +15 -12
  40. package/dist/instance-DzPiv6EK.d.ts +5723 -0
  41. package/dist/logger/index.d.ts +50 -0
  42. package/dist/logger/index.js +11 -0
  43. package/dist/mcp/index.d.ts +5 -9
  44. package/dist/mcp/index.js +2 -3
  45. package/dist/middleware/index.d.ts +10 -150
  46. package/dist/middleware/index.js +10 -2
  47. package/dist/model-messages-CJfwfzGe.d.ts +13 -0
  48. package/dist/models/index.d.ts +5 -2
  49. package/dist/models/index.js +2 -1
  50. package/dist/models/reasoning/index.js +2 -1
  51. package/dist/plugin/index.d.ts +55 -11
  52. package/dist/plugin/index.js +1 -1
  53. package/dist/profiles/index.d.ts +55 -0
  54. package/dist/{presets → profiles}/index.js +10 -10
  55. package/dist/prompt/index.d.ts +8 -13
  56. package/dist/safety/index.d.ts +109 -14
  57. package/dist/safety/index.js +59 -3
  58. package/dist/sandbox/index.d.ts +81 -0
  59. package/dist/sandbox/index.js +1 -0
  60. package/dist/skill/index.d.ts +10 -8
  61. package/dist/skill/index.js +2 -2
  62. package/dist/storage/index.d.ts +12 -4
  63. package/dist/storage/index.js +1 -1
  64. package/dist/subagents/index.d.ts +177 -0
  65. package/dist/subagents/index.js +78 -0
  66. package/dist/team/index.d.ts +544 -0
  67. package/dist/team/index.js +41 -0
  68. package/dist/tool/host/index.d.ts +41 -0
  69. package/dist/tool/host/index.js +10 -0
  70. package/dist/tool/index.d.ts +111 -21
  71. package/dist/tool/index.js +20 -13
  72. package/dist/{types-VQgymC1N.d.ts → types-Bj_J8u_W.d.ts} +44 -64
  73. package/dist/{types-CHiPh8U2.d.ts → types-C_LCeYNg.d.ts} +7 -7
  74. package/dist/types-RSCv7nQ4.d.ts +59 -0
  75. package/package.json +46 -47
  76. package/dist/builder-BgZ_j4Vs.d.ts +0 -35
  77. package/dist/chunk-5ARZJWD2.js +0 -259
  78. package/dist/chunk-DXFBQMXP.js +0 -53
  79. package/dist/chunk-H3FUYU52.js +0 -81
  80. package/dist/chunk-JLXG2SH7.js +0 -905
  81. package/dist/chunk-N7P4PN3O.js +0 -84
  82. package/dist/chunk-OFDKHNCX.js +0 -727
  83. package/dist/chunk-SDSBEQXG.js +0 -157
  84. package/dist/chunk-VEKUXUVF.js +0 -41
  85. package/dist/chunk-VNQBHPCT.js +0 -398
  86. package/dist/chunk-WWYYNWEW.js +0 -259
  87. package/dist/context/index.d.ts +0 -259
  88. package/dist/context/index.js +0 -26
  89. package/dist/events-CE72w8W4.d.ts +0 -149
  90. package/dist/host/index.d.ts +0 -45
  91. package/dist/host/index.js +0 -8
  92. package/dist/index-DQuTZ8xL.d.ts +0 -1335
  93. package/dist/messages-BYWGn8TY.d.ts +0 -110
  94. package/dist/presets/index.d.ts +0 -53
  95. package/dist/registry-DwYqsQkX.d.ts +0 -164
  96. package/dist/runner-CI-XeR16.d.ts +0 -91
  97. package/dist/scope/index.d.ts +0 -10
  98. package/dist/scope/index.js +0 -14
  99. package/dist/session-manager-KbYt2WUh.d.ts +0 -282
  100. package/dist/signal/index.d.ts +0 -28
  101. package/dist/signal/index.js +0 -6
  102. package/dist/sub-agent/index.d.ts +0 -24
  103. package/dist/sub-agent/index.js +0 -32
  104. package/dist/tool-CZWN3KbO.d.ts +0 -141
  105. package/dist/tool-DkhSCV2Y.d.ts +0 -145
  106. package/dist/tracker-DClqYqTj.d.ts +0 -96
  107. package/dist/tracking/index.d.ts +0 -111
  108. package/dist/tracking/index.js +0 -20
  109. package/dist/types-BfNpU8NS.d.ts +0 -270
  110. package/dist/types-BlOKk-Bb.d.ts +0 -330
  111. package/dist/types-BlZwmnuW.d.ts +0 -50
  112. package/dist/types-CQL-SvTn.d.ts +0 -29
  113. package/dist/types-CWm-7rvB.d.ts +0 -55
  114. package/dist/types-DTSkxakL.d.ts +0 -651
  115. package/dist/types-DmDwi2zI.d.ts +0 -339
  116. package/dist/types-YuWV4ag7.d.ts +0 -72
@@ -1,1335 +0,0 @@
1
- import { LanguageModel } from 'ai';
2
- import { P as Preset } from './types-BlZwmnuW.js';
3
- import { T as Tool } from './tool-CZWN3KbO.js';
4
- import { A as AgentMiddleware, f as StreamProvider, d as PromptConfig } from './types-DTSkxakL.js';
5
- import { S as SessionManager, f as SessionContext, i as SessionInfo } from './session-manager-KbYt2WUh.js';
6
- import { T as ToolHost } from './types-CHiPh8U2.js';
7
- import { T as TokenUsage, M as Message } from './messages-BYWGn8TY.js';
8
- import { A as AgentEvent } from './events-CE72w8W4.js';
9
- import { R as ReasoningLevel } from './types-CQaXbRsS.js';
10
- import { a as MCPManager } from './types-VQgymC1N.js';
11
- import { A as AgentSignal } from './types-YuWV4ag7.js';
12
- import { U as UndoResult, T as TurnChangeTracker } from './tracker-DClqYqTj.js';
13
- import { P as PromptBuilder } from './builder-BgZ_j4Vs.js';
14
- import { P as PendingIntervention, n as InterventionController } from './types-BlOKk-Bb.js';
15
- import { M as MiddlewareRunner } from './runner-CI-XeR16.js';
16
- import { s as DoomLoopHandler, o as AgentTurnStepRuntimeConfig } from './types-DmDwi2zI.js';
17
-
18
- /**
19
- * Tools whose outputs should never be pruned automatically.
20
- */
21
- declare const PRUNE_PROTECTED_TOOLS: readonly ["skill"];
22
- /**
23
- * Configuration for automatic context compaction.
24
- */
25
- interface CompactionConfig {
26
- /**
27
- * Enable automatic compaction when context overflows.
28
- * Default: true
29
- */
30
- auto?: boolean;
31
- /**
32
- * Enable pruning of old tool outputs before summarization.
33
- * Default: true
34
- */
35
- prune?: boolean;
36
- /**
37
- * Protect this many recent tokens from pruning.
38
- * Default: 40,000
39
- */
40
- protectedTokens?: number;
41
- /**
42
- * Minimum tokens to trigger pruning.
43
- * Default: 20,000
44
- */
45
- pruneMinimum?: number;
46
- /**
47
- * Custom summarization prompt for compaction.
48
- */
49
- summaryPrompt?: string;
50
- /**
51
- * Model to use for summarization. Defaults to the agent model.
52
- */
53
- summaryModel?: LanguageModel;
54
- /**
55
- * Auto-continue after compaction with a continuation prompt.
56
- * Default: true
57
- */
58
- autoContinue?: boolean;
59
- }
60
-
61
- /**
62
- * Tracing configuration for `createAgent({ tracing })`.
63
- *
64
- * When provided, the agent auto-creates the OTel middleware and AI SDK
65
- * telemetry settings, so callers do not need to wire them separately.
66
- */
67
- interface TracingConfig {
68
- /** Agent description — recorded as `gen_ai.agent.description`. */
69
- agentDescription?: string;
70
- /** Record tool arguments and LLM prompts in spans. Defaults to `true`. */
71
- recordInputs?: boolean;
72
- /** Record tool results and LLM responses in spans. Defaults to `true`. */
73
- recordOutputs?: boolean;
74
- /** Emit `execute_tool` spans from our middleware. Defaults to `true`. */
75
- emitToolSpans?: boolean;
76
- /** TTL in ms for orphaned spans. Defaults to 5 minutes. */
77
- spanTimeoutMs?: number;
78
- /**
79
- * An OTel `SpanProcessor` used to auto-create and register a tracer provider.
80
- */
81
- spanProcessor?: unknown;
82
- /**
83
- * OTel service name for the auto-created provider resource.
84
- * Defaults to the agent `name`.
85
- */
86
- serviceName?: string;
87
- }
88
-
89
- /**
90
- * Public configuration surface for `createAgent()`.
91
- */
92
- interface AgentConfig {
93
- /**
94
- * Agent name — used as identity in spans, workflow names, and logs.
95
- * Defaults to `"agent"`.
96
- */
97
- name?: string;
98
- /** Vercel AI SDK model instance */
99
- model: LanguageModel;
100
- /** Flat system prompt */
101
- systemPrompt?: string;
102
- /** Working directory */
103
- cwd?: string;
104
- /**
105
- * Execution environment for tools.
106
- */
107
- host?: ToolHost;
108
- /** Temperature (0-1) */
109
- temperature?: number;
110
- /** Top-p sampling */
111
- topP?: number;
112
- /** Max output tokens */
113
- maxOutputTokens?: number;
114
- /** Maximum steps (tool call iterations) */
115
- maxSteps?: number;
116
- /** Reasoning/thinking level for supported models */
117
- reasoningLevel?: ReasoningLevel;
118
- /** Require approval for dangerous operations */
119
- requireApproval?: boolean;
120
- /**
121
- * Handler for doom-loop detection.
122
- */
123
- onDoomLoop?: DoomLoopHandler;
124
- /**
125
- * Strictly enforce doom-loop detection when no custom handler is provided.
126
- * Default: true
127
- */
128
- enforceDoomLoop?: boolean;
129
- /**
130
- * Number of identical tool calls before triggering doom-loop handling.
131
- * Default: 3
132
- */
133
- doomLoopThreshold?: number;
134
- /**
135
- * Automatic context compaction settings.
136
- */
137
- compaction?: CompactionConfig;
138
- /**
139
- * Middleware for the agent lifecycle.
140
- */
141
- middleware?: AgentMiddleware[];
142
- /**
143
- * Context window size in tokens for overflow detection.
144
- * Defaults to 128,000.
145
- */
146
- contextWindow?: number;
147
- /**
148
- * Custom stream provider for specialized models.
149
- */
150
- streamProvider?: StreamProvider;
151
- /**
152
- * MCP manager for external tool servers.
153
- */
154
- mcp?: MCPManager;
155
- /**
156
- * Layered prompt pipeline configuration.
157
- */
158
- prompt?: PromptConfig;
159
- /**
160
- * Simplest way to enable tracing.
161
- */
162
- tracing?: TracingConfig;
163
- /**
164
- * Event signal for multi-consumer dispatch.
165
- *
166
- * Every event yielded by `chat()` is also emitted here, enabling
167
- * passive observers (SSE routes, TUI renderers, plugins) to
168
- * subscribe without consuming the primary generator.
169
- *
170
- * Defaults to an in-process `LocalSignal`. A distributed runtime
171
- * can supply its own implementation to bridge events externally.
172
- */
173
- signal?: AgentSignal;
174
- }
175
-
176
- interface AgentForkOptions {
177
- name?: string;
178
- systemPrompt?: string;
179
- prompt?: PromptConfig;
180
- model?: LanguageModel;
181
- temperature?: number;
182
- tools?: Tool.AnyInfo[];
183
- maxSteps?: number;
184
- reasoningLevel?: ReasoningLevel;
185
- preset?: Preset;
186
- middleware?: AgentMiddleware[];
187
- additionalMiddleware?: AgentMiddleware[];
188
- }
189
-
190
- type AgentConstructionOptions = AgentConfig & {
191
- tools?: Tool.AnyInfo[];
192
- sessionManager?: SessionManager;
193
- };
194
-
195
- /**
196
- * Create an agent instance
197
- */
198
- declare function createAgent(config: AgentConstructionOptions): Agent;
199
- /**
200
- * Embeddable AI agent with tool support.
201
- *
202
- * The `Agent` class is the main entry-point for consumers. It manages:
203
- * - **Sessions** — persistent conversation history
204
- * - **Streaming** — real-time event generation via `chat()`
205
- * - **Tools** — registry + execution context
206
- * - **Context management** — overflow detection & auto-compaction
207
- * - **Reasoning** — configurable thinking levels per model
208
- * - **Sub-agents** — `fork()` / `run()` for parallel or specialised tasks
209
- *
210
- * @example
211
- * ```typescript
212
- * import { createAgent } from "@cuylabs/agent-core";
213
- * import { anthropic } from "@ai-sdk/anthropic";
214
- *
215
- * const agent = createAgent({
216
- * model: anthropic("claude-sonnet-4-20250514"),
217
- * cwd: "/path/to/project",
218
- * });
219
- *
220
- * // Streaming
221
- * for await (const event of agent.chat("session-1", "List all TypeScript files")) {
222
- * if (event.type === "text-delta") process.stdout.write(event.text);
223
- * }
224
- *
225
- * // Non-streaming (convenience)
226
- * const result = await agent.send("session-1", "Fix the bug in utils.ts");
227
- * console.log(result.response);
228
- * ```
229
- */
230
- declare class Agent {
231
- private config;
232
- private tools;
233
- private sessions;
234
- private state;
235
- /** Context manager for overflow detection and compaction */
236
- private contextManager;
237
- /** Tools that user said "remember" for doom loop (don't ask again) */
238
- private rememberedDoomLoopTools;
239
- /** Turn change tracker for file modification tracking */
240
- private turnTracker;
241
- /** Counter for turn IDs */
242
- private turnCounter;
243
- /** MCP manager for external tool servers */
244
- private mcpManager?;
245
- /** Whether MCP has been connected (lazy init) */
246
- private mcpConnected;
247
- /** Whether skill tools have been resolved (lazy init) */
248
- private skillToolsResolved;
249
- /** Cached MCP tools (refreshed on connect) */
250
- private mcpToolsCache?;
251
- /** Prompt pipeline builder (when using layered prompt mode) */
252
- private promptBuilder?;
253
- /** Intervention controller for mid-turn message injection */
254
- private interventionCtrl;
255
- /** Execution environment for tool operations */
256
- private host;
257
- /** Whether the agent owns the host and can safely recreate it on cwd changes */
258
- private ownsHost;
259
- /** Middleware runner for lifecycle hooks */
260
- private middlewareRunner;
261
- /** AI SDK telemetry settings (auto-created from `tracing` config) */
262
- private telemetrySettings?;
263
- /** Tracing shutdown function (from `tracing` config auto-setup) */
264
- private tracingShutdown?;
265
- /** Multi-consumer event dispatch */
266
- private readonly _signal;
267
- /** Number of active turns across all sessions */
268
- private activeTurnCount;
269
- /** Active turn intervention controllers, keyed by turn id */
270
- private readonly activeTurns;
271
- /** Per-session turn queue to prevent concurrent writes to the same history */
272
- private readonly sessionLocks;
273
- constructor(config: AgentConstructionOptions);
274
- /**
275
- * Event signal — subscribe to events without consuming the generator.
276
- *
277
- * Every event yielded by `chat()` is also dispatched here, allowing
278
- * multiple passive observers (SSE routes, TUI, plugins) to listen
279
- * concurrently.
280
- */
281
- get signal(): AgentSignal;
282
- /** Agent name (identity for spans, Dapr workflows, etc.) */
283
- get name(): string;
284
- /** Working directory for file operations */
285
- get cwd(): string;
286
- /** Current model */
287
- get model(): LanguageModel;
288
- /** System prompt */
289
- get systemPrompt(): string;
290
- /** Is currently streaming */
291
- get isStreaming(): boolean;
292
- /** Current reasoning level */
293
- get reasoningLevel(): ReasoningLevel;
294
- /**
295
- * Set reasoning level
296
- * Will be clamped to available levels for the current model
297
- */
298
- setReasoningLevel(level: ReasoningLevel): void;
299
- /**
300
- * Get available reasoning levels for the current model
301
- */
302
- getAvailableReasoningLevels(): ReasoningLevel[];
303
- /**
304
- * Check if current model supports reasoning
305
- */
306
- supportsReasoning(): boolean;
307
- /**
308
- * Ensure skill tools are registered when `prompt.skills` is configured.
309
- * Lazy initialization — resolves the registry and adds tools on first use.
310
- */
311
- private ensureSkillTools;
312
- private resetPromptScopedTools;
313
- private createSessionManager;
314
- private acquireSessionLock;
315
- private getActiveInterventionController;
316
- private getInterventionControllerForTurn;
317
- private createTurnInterventionController;
318
- private releaseTurnInterventions;
319
- private syncStreamingState;
320
- private syncSessionView;
321
- /**
322
- * Ensure MCP is connected and return tools
323
- * Lazy initialization - only connects on first use
324
- */
325
- private ensureMCPConnected;
326
- /**
327
- * Repair session history by synthesising missing tool-result messages.
328
- *
329
- * When a tool `execute()` throws, the AI SDK emits `tool-error` instead
330
- * of `tool-result`. If the error event wasn't persisted (e.g. because
331
- * the fix above wasn't in place), subsequent turns will fail with
332
- * `MissingToolResultsError`. This method detects orphaned tool-call IDs
333
- * and adds placeholder `tool` messages so the history is valid again.
334
- */
335
- private repairOrphanedToolCalls;
336
- /**
337
- * Convert internal {@link Message} array to Vercel AI SDK {@link ModelMessage} format.
338
- *
339
- * Handles the role-specific mappings:
340
- * - `user` / `system` → pass-through
341
- * - `assistant` with tool calls → `ToolCallPart[]` content
342
- * - `tool` → `tool-result` content part
343
- */
344
- private toModelMessages;
345
- /**
346
- * Stream a chat response.
347
- *
348
- * Sends a user message and yields real-time {@link AgentEvent}s as the
349
- * model responds, calls tools, and finishes. Conversation state is
350
- * persisted to the session automatically.
351
- *
352
- * @param sessionId - Session identifier for conversation history
353
- * @param message - User message to send
354
- * @param options - Abort signal, system prompt override, and approval handler
355
- * @yields {AgentEvent} Events as they occur during processing
356
- */
357
- chat(sessionId: string, message: string, options?: {
358
- abort?: AbortSignal;
359
- system?: string;
360
- }): AsyncGenerator<AgentEvent>;
361
- /**
362
- * Send a message and wait for the complete response (non-streaming).
363
- *
364
- * This is a convenience wrapper around {@link chat} that buffers all
365
- * events internally and returns the final response, usage, and tool
366
- * call results. Prefer `chat()` when you need real-time streaming.
367
- *
368
- * @param sessionId - Session identifier
369
- * @param message - User message
370
- * @param options - Abort signal and optional system prompt override
371
- */
372
- send(sessionId: string, message: string, options?: {
373
- abort?: AbortSignal;
374
- system?: string;
375
- }): Promise<{
376
- response: string;
377
- usage: TokenUsage;
378
- toolCalls: Array<{
379
- name: string;
380
- result: unknown;
381
- }>;
382
- }>;
383
- /** Add a tool at runtime */
384
- addTool(tool: Tool.Info): void;
385
- /** Remove a tool by ID */
386
- removeTool(toolId: string): boolean;
387
- /** Get all tool IDs */
388
- getToolIds(): string[];
389
- /** Get all tools */
390
- getTools(): Tool.AnyInfo[];
391
- /** Check if a tool exists */
392
- hasTool(toolId: string): boolean;
393
- /** Get session manager */
394
- getSessionManager(): SessionManager;
395
- /** Get current session context */
396
- getSessionContext(): SessionContext;
397
- /** Get messages from current session */
398
- getMessages(): Message[];
399
- /** Delete a session */
400
- deleteSession(sessionId: string): Promise<boolean>;
401
- /** List all sessions */
402
- listSessions(): Promise<SessionInfo[]>;
403
- /** Branch from current point */
404
- branch(summary?: string): Promise<string>;
405
- /**
406
- * Get context window statistics.
407
- *
408
- * Useful for UI to display context utilization like:
409
- * - Progress bar showing how full the context is
410
- * - Warning when approaching limit
411
- * - Info about when compaction will trigger
412
- *
413
- * @example
414
- * ```typescript
415
- * const stats = agent.getContextStats();
416
- * console.log(`Context: ${stats.utilizationPercent}% used`);
417
- * if (stats.shouldPrune) {
418
- * console.log('Context will be compacted soon');
419
- * }
420
- * ```
421
- */
422
- getContextStats(): {
423
- tokens: number;
424
- limit: number;
425
- available: number;
426
- utilizationPercent: number;
427
- isOverflowing: boolean;
428
- shouldPrune: boolean;
429
- };
430
- /**
431
- * Manually trigger context compaction.
432
- *
433
- * Usually auto-compaction handles this, but you can trigger it manually
434
- * if needed (e.g., before a long operation).
435
- *
436
- * @returns Pruning result with details about what was removed/summarized
437
- */
438
- compactContext(): Promise<{
439
- removedCount: number;
440
- tokensRemoved: number;
441
- summarized: boolean;
442
- summary?: string;
443
- }>;
444
- /**
445
- * Clear remembered doom loop tools.
446
- *
447
- * When a user says "remember" for a doom loop, that tool is added
448
- * to a set that skips future doom loop checks. Call this to reset.
449
- */
450
- clearRememberedDoomLoopTools(): void;
451
- /**
452
- * Inject a message at the next step boundary of a running turn.
453
- *
454
- * This is the primary redirection mechanism. When the agent is
455
- * streaming a multi-step response (calling tools, reasoning, etc.),
456
- * this injects a user message before the next LLM call. The LLM
457
- * sees the intervention and can adjust its behavior.
458
- *
459
- * Uses Vercel AI SDK v6's `prepareStep` hook — no polling, no
460
- * custom loop code. The SDK handles the injection naturally.
461
- *
462
- * Safe to call from any async context (UI event handlers, WebSocket
463
- * callbacks, timers, etc.) while `chat()` is running.
464
- *
465
- * If called when no turn is active, the message will be picked up
466
- * by the first step of the next `chat()` call.
467
- * If multiple turns are active concurrently, this throws because the
468
- * target turn would be ambiguous.
469
- *
470
- * @param message - The user message to inject mid-turn
471
- * @returns Intervention ID for tracking
472
- *
473
- * @example
474
- * ```typescript
475
- * // Start a streaming turn
476
- * const stream = agent.chat("session-1", "refactor the auth module");
477
- *
478
- * // From a UI handler (another async context):
479
- * agent.intervene("stop, focus only on JWT validation in auth.ts");
480
- *
481
- * // The stream will yield an intervention-applied event
482
- * for await (const event of stream) {
483
- * if (event.type === "intervention-applied") {
484
- * console.log(`Redirected: ${event.message}`);
485
- * }
486
- * }
487
- * ```
488
- */
489
- intervene(message: string): string;
490
- /**
491
- * Queue a message for after the current turn completes.
492
- *
493
- * Unlike `intervene()`, this does **not** interrupt the current turn.
494
- * The message is held and available via `drainQueuedNext()` after
495
- * `chat()` finishes. The consumer decides whether to send it as a
496
- * new turn.
497
- *
498
- * If multiple turns are active concurrently, this throws because the
499
- * target turn would be ambiguous.
500
- *
501
- * @param message - The message to queue
502
- * @returns Intervention ID for tracking
503
- *
504
- * @example
505
- * ```typescript
506
- * agent.queueNext("now run the test suite");
507
- *
508
- * for await (const event of agent.chat("s1", "fix the bug")) {
509
- * // ... handle events
510
- * }
511
- *
512
- * // After turn completes, check for queued messages
513
- * if (agent.hasQueuedNext()) {
514
- * const next = agent.drainQueuedNext();
515
- * for (const item of next) {
516
- * // Send as a new turn
517
- * for await (const ev of agent.chat("s1", item.message)) { ... }
518
- * }
519
- * }
520
- * ```
521
- */
522
- queueNext(message: string): string;
523
- /** Whether there are deferred messages queued for after the turn */
524
- hasQueuedNext(): boolean;
525
- /** Drain and return all deferred messages (clears the queue) */
526
- drainQueuedNext(): PendingIntervention[];
527
- /**
528
- * Get the raw intervention controller for advanced use cases.
529
- *
530
- * Use this when you need fine-grained control over the intervention
531
- * lifecycle (e.g., checking pending count, clearing queues, setting
532
- * custom `onApplied` callbacks).
533
- *
534
- * @internal
535
- */
536
- getInterventionController(): InterventionController;
537
- /**
538
- * Get the unified diff for all file changes in the current/last turn.
539
- *
540
- * @example
541
- * ```typescript
542
- * const diff = await agent.getTurnDiff();
543
- * if (diff) {
544
- * console.log('Changes this turn:\n', diff);
545
- * }
546
- * ```
547
- */
548
- getTurnDiff(): Promise<string | null>;
549
- /**
550
- * Get list of files being tracked in the current turn.
551
- */
552
- getTrackedFiles(): string[];
553
- /**
554
- * Undo all file changes from the current turn.
555
- * Restores files to their state before the turn started.
556
- *
557
- * @example
558
- * ```typescript
559
- * const result = await agent.undoTurn();
560
- * console.log(`Restored ${result.restored.length} files`);
561
- * if (result.failed.length > 0) {
562
- * console.log('Failed to restore:', result.failed);
563
- * }
564
- * ```
565
- */
566
- undoTurn(): Promise<UndoResult>;
567
- /**
568
- * Undo changes to specific files only.
569
- *
570
- * @param files - Array of file paths to restore (relative to cwd)
571
- */
572
- undoFiles(files: string[]): Promise<UndoResult>;
573
- /**
574
- * Check if currently tracking a turn.
575
- */
576
- isTrackingTurn(): boolean;
577
- /**
578
- * Get access to the raw turn tracker for advanced use cases.
579
- *
580
- * @internal
581
- */
582
- getTurnTracker(): TurnChangeTracker;
583
- /**
584
- * Update system prompt.
585
- *
586
- * If the agent is using the prompt pipeline, calling this switches
587
- * to flat string mode (disabling the pipeline). To modify the pipeline
588
- * instead, use `getPromptBuilder()`.
589
- */
590
- setSystemPrompt(prompt: string): void;
591
- /** Update working directory */
592
- setCwd(cwd: string): void;
593
- /** Update model */
594
- setModel(model: LanguageModel): void;
595
- /**
596
- * Get the prompt builder (when using pipeline mode).
597
- * Returns undefined if using flat string mode.
598
- *
599
- * Use this to add/remove sections, clear caches, or inspect
600
- * the prompt composition without switching to flat mode.
601
- *
602
- * @example
603
- * ```typescript
604
- * const builder = agent.getPromptBuilder();
605
- * if (builder) {
606
- * builder.addSection({
607
- * id: "task-context",
608
- * label: "Task Context",
609
- * content: "Focus on fixing authentication bugs.",
610
- * priority: 60,
611
- * });
612
- * }
613
- * ```
614
- */
615
- getPromptBuilder(): PromptBuilder | undefined;
616
- /**
617
- * Check if the agent is using the prompt pipeline.
618
- */
619
- isUsingPromptPipeline(): boolean;
620
- /**
621
- * Build the effective system prompts for a turn.
622
- *
623
- * This mirrors the prompt resolution path used by `chat()` so external host
624
- * runtimes can start durable turns without duplicating prompt assembly.
625
- */
626
- buildSystemPrompts(sessionId: string, override?: string): Promise<string[]>;
627
- /**
628
- * Return the runtime configuration required by the extracted turn-step
629
- * helpers.
630
- */
631
- getTurnRuntimeConfig(): AgentTurnStepRuntimeConfig;
632
- /**
633
- * Get the configured tool host.
634
- */
635
- getHost(): ToolHost;
636
- /**
637
- * Get the configured middleware runner.
638
- *
639
- * The runner is immutable after construction, so it is safe to reuse in
640
- * durable activity helpers that need the same middleware stack.
641
- */
642
- getMiddlewareRunner(): MiddlewareRunner;
643
- /**
644
- * Fork this agent to create a sub-agent with modified configuration.
645
- *
646
- * Sub-agents share the same session manager but can have different:
647
- * - System prompts (specialized for tasks)
648
- * - Tools (restricted subset)
649
- * - Models (cheaper/faster for simple tasks)
650
- * - Reasoning levels
651
- *
652
- * @example
653
- * ```typescript
654
- * // Create an exploration sub-agent with read-only tools
655
- * const explorer = agent.fork({
656
- * name: "explore",
657
- * systemPrompt: "You explore codebases. Only use read and search tools.",
658
- * tools: [readTool, grepTool, globTool],
659
- * });
660
- *
661
- * // Run the sub-agent
662
- * const result = await explorer.run({
663
- * parentSessionId: "main-session",
664
- * message: "Find all API endpoints",
665
- * });
666
- * ```
667
- */
668
- fork(options?: AgentForkOptions): Agent;
669
- /**
670
- * Create a sub-agent with a preset configuration.
671
- *
672
- * Convenience method that applies a preset and returns a forked agent.
673
- *
674
- * @example
675
- * ```typescript
676
- * import { Presets } from "@cuylabs/agent-core";
677
- *
678
- * // Create an exploration sub-agent
679
- * const explorer = agent.withPreset(Presets.explore);
680
- * const result = await explorer.run({
681
- * message: "Find all API routes in this project",
682
- * });
683
- *
684
- * // Create a careful review sub-agent
685
- * const reviewer = agent.withPreset(Presets.review);
686
- * const review = await reviewer.run({
687
- * message: "Review src/auth.ts for security issues",
688
- * });
689
- * ```
690
- */
691
- withPreset(preset: Preset): Agent;
692
- /**
693
- * Run a task in an isolated sub-agent session.
694
- *
695
- * Creates a new session linked to the parent, runs the task to completion,
696
- * and returns the result. The sub-agent session is preserved for inspection.
697
- *
698
- * @example
699
- * ```typescript
700
- * const result = await agent.run({
701
- * parentSessionId: "main-session",
702
- * message: "Review this code for security issues",
703
- * title: "Security Review",
704
- * });
705
- *
706
- * console.log(result.response);
707
- * console.log(`Sub-agent session: ${result.sessionId}`);
708
- * ```
709
- */
710
- run(options: {
711
- /** Parent session ID (for linking) */
712
- parentSessionId?: string;
713
- /** The task/message to execute */
714
- message: string;
715
- /** Title for the sub-agent session */
716
- title?: string;
717
- /** Abort signal */
718
- abort?: AbortSignal;
719
- }): Promise<{
720
- /** Final response text */
721
- response: string;
722
- /** Sub-agent session ID */
723
- sessionId: string;
724
- /** Token usage */
725
- usage: TokenUsage;
726
- /** Tool calls made */
727
- toolCalls: Array<{
728
- name: string;
729
- result: unknown;
730
- }>;
731
- }>;
732
- /**
733
- * Get the MCP manager (if configured)
734
- */
735
- getMCP(): MCPManager | undefined;
736
- /**
737
- * Check if MCP is configured
738
- */
739
- hasMCP(): boolean;
740
- /**
741
- * Reconnect to MCP servers
742
- *
743
- * Use this after network issues or when server availability changes.
744
- * Clears tool cache and reconnects all servers.
745
- */
746
- reconnectMCP(): Promise<void>;
747
- /**
748
- * Close the agent and clean up resources
749
- *
750
- * Flushes and shuts down the tracing provider (when `tracing` was configured),
751
- * closes MCP connections if configured.
752
- * After calling close(), the agent should not be used.
753
- */
754
- close(): Promise<void>;
755
- }
756
-
757
- /**
758
- * Sub-Agent Types
759
- *
760
- * Type definitions for the sub-agent system: profiles, lifecycle status,
761
- * handles, and configuration.
762
- *
763
- * Following PowerShell verb-noun naming (Invoke-Agent, Get-Agent, Stop-Agent).
764
- *
765
- * Designed for agent-core's composable library architecture.
766
- *
767
- * Key design decisions:
768
- *
769
- * 1. **Library-first**: Unlike CLI-embedded tools, these
770
- * are importable building blocks. The consumer creates them with
771
- * `createSubAgentTools(parent)` and opts in — nothing auto-registered.
772
- *
773
- * 2. **Agent profiles over role configs**: Instead of TOML files or markdown
774
- * agents, we use composable `AgentProfile` objects that wrap existing
775
- * `Preset` + extra metadata the LLM can read.
776
- *
777
- * 3. **Progressive lifecycle**: Start with synchronous `invoke_agent` (simplest),
778
- * add `wait_agent`/`close_agent` only when async profiles exist.
779
- *
780
- * 4. **Depth safety**: Hard limit on nesting with configurable max depth.
781
- *
782
- * @packageDocumentation
783
- */
784
-
785
- /**
786
- * An agent profile defines a specialized sub-agent personality.
787
- *
788
- * Profiles combine a `Preset` (tool filtering, temperature, etc.) with
789
- * LLM-facing metadata (name, description, examples) so the model knows
790
- * when and how to delegate.
791
- *
792
- * Profiles define specialized sub-agent personalities with roles
793
- * like explorer, worker, planner, and reviewer.
794
- *
795
- * @example
796
- * ```typescript
797
- * const explorer: AgentProfile = {
798
- * name: "explorer",
799
- * description: "Fast, read-only codebase exploration. Use when you need to find files, search code, or understand project structure.",
800
- * preset: Presets.explore,
801
- * maxSteps: 30,
802
- * };
803
- * ```
804
- */
805
- interface AgentProfile {
806
- /** Unique identifier used in tool calls (lowercase, no spaces) */
807
- name: string;
808
- /**
809
- * When to use this sub-agent — written for the LLM to consume.
810
- *
811
- * This is the most important field. The parent LLM reads this to decide
812
- * whether to delegate. Include clear trigger phrases.
813
- */
814
- description: string;
815
- /**
816
- * Preset to apply (tool filtering, temperature, system prompt, etc.).
817
- * If omitted, inherits the parent agent's configuration.
818
- */
819
- preset?: Preset;
820
- /**
821
- * Override system prompt for this profile.
822
- * Takes precedence over preset's systemPrompt.
823
- * Use `{basePrompt}` to include the parent's system prompt.
824
- */
825
- systemPrompt?: string;
826
- /**
827
- * Override model for this profile.
828
- * Useful for using cheaper/faster models for simple tasks.
829
- */
830
- model?: LanguageModel;
831
- /** Max steps for this sub-agent (default: parent's maxSteps) */
832
- maxSteps?: number;
833
- /**
834
- * Additional middleware appended to the parent's middleware stack.
835
- * Useful for adding logging or guardrails specific to this profile.
836
- */
837
- additionalMiddleware?: AgentMiddleware[];
838
- /**
839
- * Additional tools beyond what the preset allows.
840
- * These are merged with the preset-filtered tools.
841
- */
842
- additionalTools?: Tool.AnyInfo[];
843
- /**
844
- * Whether this sub-agent can itself spawn further sub-agents.
845
- * When false, the `invoke_agent` tool is removed from the child.
846
- *
847
- * @default false — sub-agents cannot nest by default (safe default)
848
- */
849
- canSpawn?: boolean;
850
- }
851
- /**
852
- * Lifecycle status of a running or completed sub-agent.
853
- *
854
- * Simplified lifecycle for the fire-and-forget-with-optional-wait model.
855
- */
856
- type SubAgentStatus = {
857
- state: "running";
858
- } | {
859
- state: "completed";
860
- response: string;
861
- usage: SubAgentUsage;
862
- } | {
863
- state: "errored";
864
- error: string;
865
- } | {
866
- state: "cancelled";
867
- };
868
- /**
869
- * Token usage tracking for a sub-agent run.
870
- */
871
- interface SubAgentUsage {
872
- inputTokens: number;
873
- outputTokens: number;
874
- totalTokens: number;
875
- }
876
- /**
877
- * A handle to a running or completed sub-agent.
878
- *
879
- * Returned by async invocations. Allows the parent to wait for completion,
880
- * check status, or cancel.
881
- */
882
- interface SubAgentHandle {
883
- /** Unique ID for this sub-agent invocation */
884
- id: string;
885
- /** Human-readable name (from profile or auto-generated) */
886
- name: string;
887
- /** Session ID of the child agent's session */
888
- sessionId: string;
889
- /** Current status */
890
- status: SubAgentStatus;
891
- /** The promise that resolves when the sub-agent completes */
892
- promise: Promise<SubAgentCompletedResult>;
893
- /** Abort controller to cancel this sub-agent */
894
- abort: AbortController;
895
- }
896
- /**
897
- * The final result of a completed sub-agent.
898
- */
899
- interface SubAgentCompletedResult {
900
- /** Final response text */
901
- response: string;
902
- /** Session ID (for audit/inspection) */
903
- sessionId: string;
904
- /** Token usage */
905
- usage: SubAgentUsage;
906
- /** Tool calls the sub-agent made */
907
- toolCalls: Array<{
908
- name: string;
909
- result: unknown;
910
- }>;
911
- }
912
- /**
913
- * Configuration for `createSubAgentTools()`.
914
- *
915
- * Controls which profiles are available, concurrency limits,
916
- * depth limits, and whether async mode is enabled.
917
- */
918
- interface SubAgentToolConfig {
919
- /**
920
- * Available sub-agent profiles.
921
- * Each profile defines a specialized persona the LLM can invoke.
922
- * At least one profile is required.
923
- */
924
- profiles: AgentProfile[];
925
- /**
926
- * Maximum concurrent sub-agents (across all profiles).
927
- * @default 6
928
- */
929
- maxConcurrent?: number;
930
- /**
931
- * Maximum nesting depth for recursive sub-agent spawning.
932
- * Depth 0 = no spawning, 1 = one level of sub-agents, etc.
933
- *
934
- * When a sub-agent reaches the depth limit, the `invoke_agent`
935
- * tool is automatically removed from its tool set.
936
- *
937
- * @default 2
938
- */
939
- maxDepth?: number;
940
- /**
941
- * Current depth (internal — incremented when creating child tools).
942
- * Users should not set this directly.
943
- *
944
- * @internal
945
- */
946
- currentDepth?: number;
947
- /**
948
- * Enable async mode with `wait_agent` and `close_agent` tools.
949
- *
950
- * When false (default), `invoke_agent` blocks until the sub-agent
951
- * completes and returns the result directly — simpler but sequential.
952
- *
953
- * When true, `invoke_agent` returns immediately with an agent ID,
954
- * and the LLM must call `wait_agent` to collect results. This enables
955
- * parallel sub-agent execution.
956
- *
957
- * @default false
958
- */
959
- async?: boolean;
960
- /**
961
- * Title prefix for sub-agent sessions.
962
- * @default "Sub-agent"
963
- */
964
- sessionTitlePrefix?: string;
965
- }
966
- /** Default maximum concurrent sub-agents */
967
- declare const DEFAULT_MAX_CONCURRENT = 6;
968
- /** Default maximum nesting depth */
969
- declare const DEFAULT_MAX_SPAWN_DEPTH = 2;
970
- /** Default session title prefix */
971
- declare const DEFAULT_SESSION_TITLE_PREFIX = "Sub-agent";
972
-
973
- /**
974
- * Sub-Agent Tracker — in-memory state for active sub-agents
975
- *
976
- * Manages the lifecycle of running sub-agents: slots, handles,
977
- * concurrency limits, and depth enforcement.
978
- *
979
- * Handles spawn slot reservation and depth checking, designed for
980
- * single-process TypeScript/async usage.
981
- *
982
- * @packageDocumentation
983
- */
984
-
985
- /**
986
- * Tracks active sub-agent handles and enforces concurrency/depth limits.
987
- *
988
- * One tracker is created per `createSubAgentTools()` call and shared
989
- * across all sub-agent tool instances for that parent agent.
990
- */
991
- declare class SubAgentTracker {
992
- /** Active sub-agent handles by ID */
993
- private readonly handles;
994
- /** Maximum concurrent sub-agents */
995
- readonly maxConcurrent: number;
996
- /** Maximum nesting depth */
997
- readonly maxDepth: number;
998
- /** Current depth in the spawn hierarchy */
999
- readonly currentDepth: number;
1000
- constructor(config?: Partial<SubAgentToolConfig>);
1001
- /** Number of currently active (running) sub-agents */
1002
- get activeCount(): number;
1003
- /** Total tracked handles (including completed) */
1004
- get totalCount(): number;
1005
- /**
1006
- * Check if a new sub-agent can be spawned.
1007
- * Returns an error message if not, undefined if OK.
1008
- */
1009
- canSpawn(): string | undefined;
1010
- /** Whether the current depth allows further spawning */
1011
- get canNest(): boolean;
1012
- /** Register a new sub-agent handle */
1013
- register(handle: SubAgentHandle): void;
1014
- /** Get a handle by ID */
1015
- get(id: string): SubAgentHandle | undefined;
1016
- /** Update a handle's status */
1017
- updateStatus(id: string, status: SubAgentStatus): void;
1018
- /** Get all handles */
1019
- list(): SubAgentHandle[];
1020
- /** Get all running handles */
1021
- running(): SubAgentHandle[];
1022
- /** Get all completed handles */
1023
- completed(): SubAgentHandle[];
1024
- /**
1025
- * Cancel a running sub-agent.
1026
- * Signals the abort controller and updates status.
1027
- */
1028
- cancel(id: string): boolean;
1029
- /**
1030
- * Cancel all running sub-agents.
1031
- */
1032
- cancelAll(): void;
1033
- /**
1034
- * Wait for a specific sub-agent to complete.
1035
- * Returns the result or throws if not found.
1036
- */
1037
- wait(id: string, timeoutMs?: number): Promise<SubAgentCompletedResult>;
1038
- /**
1039
- * Wait for any one of the given sub-agents to complete.
1040
- * Returns the first result.
1041
- */
1042
- waitAny(ids: string[], timeoutMs?: number): Promise<{
1043
- id: string;
1044
- result: SubAgentCompletedResult;
1045
- } | {
1046
- timedOut: true;
1047
- }>;
1048
- /**
1049
- * Create a child tracker configuration for a nested sub-agent.
1050
- * Increments the depth counter.
1051
- */
1052
- childConfig(): Partial<SubAgentToolConfig>;
1053
- }
1054
-
1055
- /**
1056
- * Sub-Agent Tools — LLM-callable tools for delegating work to specialized agents
1057
- *
1058
- * Provides three tools:
1059
- * - `invoke_agent` — spawn a sub-agent for a focused task
1060
- * - `wait_agent` — collect async sub-agent results
1061
- * - `close_agent` — cancel a running async sub-agent
1062
- *
1063
- * @packageDocumentation
1064
- */
1065
-
1066
- /**
1067
- * Create the sub-agent tools for an agent.
1068
- *
1069
- * Returns an array of tools that the LLM can call to delegate tasks:
1070
- * - `invoke_agent` — always included
1071
- * - `wait_agent` — only in async mode
1072
- * - `close_agent` — only in async mode
1073
- */
1074
- declare function createSubAgentTools(parent: Agent, config: SubAgentToolConfig): Tool.AnyInfo[];
1075
-
1076
- /**
1077
- * Markdown Agent Profile Parser
1078
- *
1079
- * Parses `.md` files into `AgentProfile` objects using a hybrid approach:
1080
- *
1081
- * - **Frontmatter** (YAML between `---` fences) maps to profile config
1082
- * - **Body** (everything after frontmatter) becomes the system prompt
1083
- * - **Preset references** compose with the existing TypeScript preset system
1084
- * - **Tool modifiers** (`+tool`, `-tool*`) extend or restrict preset tool lists
1085
- * - **Inheritance** (`extends: parent-name`) layers on top of another profile
1086
- *
1087
- * No external YAML library required — the frontmatter grammar is deliberately
1088
- * restricted to flat key-value pairs and comma-separated lists.
1089
- *
1090
- * @packageDocumentation
1091
- */
1092
-
1093
- /**
1094
- * Raw frontmatter fields extracted from a markdown agent file.
1095
- *
1096
- * All values are strings at this stage — conversion to typed config
1097
- * happens in {@link toAgentProfile}.
1098
- */
1099
- interface MarkdownAgentFrontmatter {
1100
- /** Agent name (required). Lowercase, no spaces. */
1101
- name: string;
1102
- /** LLM-facing description of when to use this agent (required). */
1103
- description: string;
1104
- /** Built-in preset to inherit from (e.g. "explore", "code", "plan"). */
1105
- preset?: string;
1106
- /** Parent agent name to extend. */
1107
- extends?: string;
1108
- /** Model identifier (e.g. "anthropic/claude-sonnet-4-6"). */
1109
- model?: string;
1110
- /** Maximum agentic loop steps. */
1111
- maxSteps?: string;
1112
- /** LLM temperature (0–1). */
1113
- temperature?: string;
1114
- /** Reasoning level: off, minimal, low, medium, high, xhigh. */
1115
- reasoning?: string;
1116
- /**
1117
- * Tool modifiers or explicit tool list.
1118
- *
1119
- * Three modes:
1120
- * - **Additive/subtractive**: `"+bash, -delete*, +fetch"` — patch the preset
1121
- * - **Explicit list**: `"read, grep, bash"` — ONLY these tools
1122
- * - **Absent**: inherit preset filtering unchanged
1123
- */
1124
- tools?: string;
1125
- /** Comma-separated skill names to activate for this agent. */
1126
- skills?: string;
1127
- /** Whether this agent can spawn further sub-agents. */
1128
- canSpawn?: string;
1129
- }
1130
- /**
1131
- * Result of parsing a markdown agent file.
1132
- */
1133
- interface ParsedMarkdownAgent {
1134
- /** Parsed frontmatter fields. */
1135
- frontmatter: MarkdownAgentFrontmatter;
1136
- /** Markdown body — becomes the system prompt. */
1137
- body: string;
1138
- /** Original file path (for error messages). */
1139
- filePath: string;
1140
- }
1141
- /**
1142
- * Parsed tool modifier from frontmatter `tools` field.
1143
- */
1144
- type ToolModifier = {
1145
- kind: "add";
1146
- pattern: string;
1147
- } | {
1148
- kind: "remove";
1149
- pattern: string;
1150
- };
1151
- /**
1152
- * Parsed tool specification from frontmatter.
1153
- */
1154
- type ParsedToolSpec = {
1155
- mode: "explicit";
1156
- patterns: string[];
1157
- } | {
1158
- mode: "modifiers";
1159
- modifiers: ToolModifier[];
1160
- } | {
1161
- mode: "inherit";
1162
- };
1163
- /**
1164
- * Resolvers needed to convert parsed frontmatter into a full `AgentProfile`.
1165
- *
1166
- * These are injected by the caller so the parser stays pure (no I/O, no
1167
- * global lookups).
1168
- */
1169
- interface ProfileResolvers {
1170
- /** Look up a built-in preset by name. Returns undefined if not found. */
1171
- resolvePreset?: (name: string) => Preset | undefined;
1172
- /** Look up a parent profile by name (for `extends`). */
1173
- resolveParent?: (name: string) => AgentProfile | undefined;
1174
- }
1175
- /**
1176
- * Parse a YAML-like frontmatter block.
1177
- *
1178
- * Supports:
1179
- * - `key: value` (string values, trimmed)
1180
- * - `key: "quoted value"` (double-quoted, quotes stripped)
1181
- * - `key: 'quoted value'` (single-quoted, quotes stripped)
1182
- * - Multi-line values via `key: |` (indented block)
1183
- * - Comments (`# ...`)
1184
- * - Empty lines (skipped)
1185
- *
1186
- * Does NOT support nested objects, arrays, or advanced YAML features.
1187
- * This is intentional — agent definitions should stay flat and readable.
1188
- */
1189
- declare function parseAgentFrontmatter(raw: string): Record<string, string>;
1190
- /**
1191
- * Parse a markdown agent file into structured frontmatter + body.
1192
- *
1193
- * @param content File content (UTF-8 string)
1194
- * @param filePath Source file path (for error context)
1195
- * @returns Parsed result, or null if the file lacks valid frontmatter
1196
- */
1197
- declare function parseMarkdownAgent(content: string, filePath: string): ParsedMarkdownAgent | null;
1198
- /**
1199
- * Parse the `tools` frontmatter field into a structured spec.
1200
- *
1201
- * - `"+bash, -delete*, +fetch"` → `{ mode: "modifiers", modifiers: [...] }`
1202
- * - `"read, grep, bash"` → `{ mode: "explicit", patterns: ["read", "grep", "bash"] }`
1203
- * - `undefined` → `{ mode: "inherit" }`
1204
- */
1205
- declare function parseToolSpec(raw: string | undefined): ParsedToolSpec;
1206
- /**
1207
- * Convert a parsed markdown agent into an `AgentProfile`.
1208
- *
1209
- * Resolution order for each field:
1210
- * 1. Explicit frontmatter value (highest priority)
1211
- * 2. Parent profile (via `extends`)
1212
- * 3. Preset defaults
1213
- * 4. Built-in defaults
1214
- *
1215
- * @param parsed Parsed markdown agent
1216
- * @param resolvers Injected lookup functions
1217
- * @returns A fully-resolved `AgentProfile`
1218
- */
1219
- declare function toAgentProfile(parsed: ParsedMarkdownAgent, resolvers?: ProfileResolvers): AgentProfile;
1220
- /**
1221
- * An `AgentProfile` that originated from a markdown file.
1222
- *
1223
- * Carries extra metadata that the discovery/wiring layer can use
1224
- * to resolve model strings and activate skills.
1225
- */
1226
- interface MarkdownAgentProfile extends AgentProfile {
1227
- /** Model identifier string (e.g. "anthropic/claude-sonnet-4-6"). */
1228
- _modelId?: string;
1229
- /** Skill names to activate for this agent. */
1230
- _skillNames?: string[];
1231
- /** Source file path. */
1232
- _source?: string;
1233
- }
1234
- /**
1235
- * Type guard for markdown-sourced profiles.
1236
- */
1237
- declare function isMarkdownProfile(profile: AgentProfile): profile is MarkdownAgentProfile;
1238
-
1239
- /**
1240
- * Agent Profile Discovery
1241
- *
1242
- * Discovers agent profiles from markdown files across multiple locations
1243
- * and merges them with built-in TypeScript profiles.
1244
- *
1245
- * Discovery order (later wins by name):
1246
- * 1. Built-in TypeScript profiles (e.g. explorer, coder, planner, runner)
1247
- * 2. User global agents: `~/.cuylabs/agents/*.md`
1248
- * 3. Project local agents: `.cuylabs/agents/*.md`
1249
- * 4. Config-specified paths: `config.agents` array
1250
- *
1251
- * @packageDocumentation
1252
- */
1253
-
1254
- /** Source tier for an agent profile. */
1255
- type AgentSource = "builtin" | "user" | "project" | "config";
1256
- /** Metadata attached to discovered profiles for debugging/logging. */
1257
- interface DiscoveredProfile {
1258
- profile: AgentProfile;
1259
- source: AgentSource;
1260
- filePath?: string;
1261
- }
1262
- /**
1263
- * Options for agent profile discovery.
1264
- */
1265
- interface AgentDiscoveryOptions {
1266
- /** Project working directory. Used to find `.cuylabs/agents/`. */
1267
- cwd: string;
1268
- /**
1269
- * User-global agents directory.
1270
- * @default `~/.cuylabs/agents`
1271
- */
1272
- userDir?: string;
1273
- /**
1274
- * Project-local agents directory name (relative to cwd).
1275
- * @default `.cuylabs/agents`
1276
- */
1277
- projectDir?: string;
1278
- /**
1279
- * Additional file paths from config.json `agents` array.
1280
- * Resolved relative to cwd.
1281
- */
1282
- configPaths?: string[];
1283
- /** Built-in TypeScript profiles to merge with. */
1284
- builtInProfiles?: AgentProfile[];
1285
- /**
1286
- * Custom preset resolver. Defaults to the built-in `Presets` map.
1287
- */
1288
- resolvePreset?: (name: string) => Preset | undefined;
1289
- }
1290
- /**
1291
- * Result of agent profile discovery.
1292
- */
1293
- interface AgentDiscoveryResult {
1294
- /** Merged profiles (ready for `SubAgentToolConfig.profiles`). */
1295
- profiles: AgentProfile[];
1296
- /** All discovered entries with source metadata (for logging). */
1297
- discovered: DiscoveredProfile[];
1298
- /** Errors encountered during loading (non-fatal). */
1299
- errors: Array<{
1300
- path: string;
1301
- error: string;
1302
- }>;
1303
- }
1304
- /**
1305
- * Discover agent profiles from markdown files and merge with built-in profiles.
1306
- *
1307
- * Merge strategy: later sources override earlier ones by profile name.
1308
- * Within the same source tier, later files (alphabetical) override earlier ones.
1309
- *
1310
- * This means a project `.cuylabs/agents/explorer.md` overrides the built-in
1311
- * `explorer` profile, and a user `~/.cuylabs/agents/explorer.md` overrides it
1312
- * for all projects.
1313
- *
1314
- * @example
1315
- * ```typescript
1316
- * const { profiles } = discoverAgentProfiles({
1317
- * cwd: "/path/to/project",
1318
- * builtInProfiles: defaultCodingProfiles,
1319
- * });
1320
- *
1321
- * // profiles now includes built-ins + user + project markdown agents
1322
- * const config: SubAgentToolConfig = { profiles };
1323
- * ```
1324
- */
1325
- declare function discoverAgentProfiles(options: AgentDiscoveryOptions): AgentDiscoveryResult;
1326
- /**
1327
- * Get the default user agents directory path.
1328
- */
1329
- declare function getUserAgentsDir(): string;
1330
- /**
1331
- * Get the project agents directory path for a given cwd.
1332
- */
1333
- declare function getProjectAgentsDir(cwd: string): string;
1334
-
1335
- export { type AgentConfig as A, parseToolSpec as B, type CompactionConfig as C, DEFAULT_MAX_CONCURRENT as D, toAgentProfile as E, type MarkdownAgentFrontmatter as M, PRUNE_PROTECTED_TOOLS as P, type SubAgentCompletedResult as S, type ToolModifier as T, Agent as a, type AgentDiscoveryOptions as b, type AgentDiscoveryResult as c, type AgentProfile as d, type AgentSource as e, DEFAULT_MAX_SPAWN_DEPTH as f, DEFAULT_SESSION_TITLE_PREFIX as g, type DiscoveredProfile as h, type MarkdownAgentProfile as i, type ParsedMarkdownAgent as j, type ParsedToolSpec as k, type ProfileResolvers as l, type SubAgentHandle as m, type SubAgentStatus as n, type SubAgentToolConfig as o, SubAgentTracker as p, type SubAgentUsage as q, type TracingConfig as r, createAgent as s, createSubAgentTools as t, discoverAgentProfiles as u, getProjectAgentsDir as v, getUserAgentsDir as w, isMarkdownProfile as x, parseAgentFrontmatter as y, parseMarkdownAgent as z };