@cuylabs/agent-core 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +57 -8
  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 +210 -5736
  30. package/dist/index.js +2126 -7766
  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-BlSTfS-W.d.ts +0 -470
@@ -0,0 +1,1067 @@
1
+ import { LanguageModel } from 'ai';
2
+ import { R as ReasoningLevel } from './types-CQaXbRsS.js';
3
+ import { T as Tool } from './tool-pFAnJc5Y.js';
4
+ import { f as AgentMiddleware, P as PromptConfig, A as AgentEvent, M as MiddlewareRunner } from './runner-C7aMP_x3.js';
5
+ import { g as SessionManager, c as SessionContext, f as SessionInfo } from './session-manager-Uawm2Le7.js';
6
+ import { d as ToolHost } from './tool-DYp6-cC3.js';
7
+ import { T as TokenUsage, M as Message } from './messages-BYWGn8TY.js';
8
+ import { a as MCPManager } from './types-VQgymC1N.js';
9
+ import { U as UndoResult, T as TurnChangeTracker } from './tracker-DClqYqTj.js';
10
+ import { P as PromptBuilder } from './builder-RcTZuYnO.js';
11
+ import { x as DoomLoopHandler, Z as StreamProvider, J as PendingIntervention, I as InterventionController, q as AgentTurnStepRuntimeConfig } from './types-MM1JoX5T.js';
12
+
13
+ /**
14
+ * Configuration for automatic context compaction.
15
+ */
16
+ interface CompactionConfig {
17
+ /**
18
+ * Enable automatic compaction when context overflows.
19
+ * Default: true
20
+ */
21
+ auto?: boolean;
22
+ /**
23
+ * Enable pruning of old tool outputs before summarization.
24
+ * Default: true
25
+ */
26
+ prune?: boolean;
27
+ /**
28
+ * Protect this many recent tokens from pruning.
29
+ * Default: 40,000
30
+ */
31
+ protectedTokens?: number;
32
+ /**
33
+ * Minimum tokens to trigger pruning.
34
+ * Default: 20,000
35
+ */
36
+ pruneMinimum?: number;
37
+ /**
38
+ * Custom summarization prompt for compaction.
39
+ */
40
+ summaryPrompt?: string;
41
+ /**
42
+ * Model to use for summarization. Defaults to the agent model.
43
+ */
44
+ summaryModel?: LanguageModel;
45
+ /**
46
+ * Auto-continue after compaction with a continuation prompt.
47
+ * Default: true
48
+ */
49
+ autoContinue?: boolean;
50
+ }
51
+
52
+ /**
53
+ * Tracing configuration for `createAgent({ tracing })`.
54
+ *
55
+ * When provided, the agent auto-creates the OTel middleware and AI SDK
56
+ * telemetry settings, so callers do not need to wire them separately.
57
+ */
58
+ interface TracingConfig {
59
+ /** Agent description — recorded as `gen_ai.agent.description`. */
60
+ agentDescription?: string;
61
+ /** Record tool arguments and LLM prompts in spans. Defaults to `true`. */
62
+ recordInputs?: boolean;
63
+ /** Record tool results and LLM responses in spans. Defaults to `true`. */
64
+ recordOutputs?: boolean;
65
+ /** Emit `execute_tool` spans from our middleware. Defaults to `true`. */
66
+ emitToolSpans?: boolean;
67
+ /** TTL in ms for orphaned spans. Defaults to 5 minutes. */
68
+ spanTimeoutMs?: number;
69
+ /**
70
+ * An OTel `SpanProcessor` used to auto-create and register a tracer provider.
71
+ */
72
+ spanProcessor?: unknown;
73
+ /**
74
+ * OTel service name for the auto-created provider resource.
75
+ * Defaults to the agent `name`.
76
+ */
77
+ serviceName?: string;
78
+ }
79
+
80
+ /**
81
+ * Public configuration surface for `createAgent()`.
82
+ */
83
+ interface AgentConfig {
84
+ /**
85
+ * Agent name — used as identity in spans, workflow names, and logs.
86
+ * Defaults to `"agent"`.
87
+ */
88
+ name?: string;
89
+ /** Vercel AI SDK model instance */
90
+ model: LanguageModel;
91
+ /** Flat system prompt */
92
+ systemPrompt?: string;
93
+ /** Working directory */
94
+ cwd?: string;
95
+ /**
96
+ * Execution environment for tools.
97
+ */
98
+ host?: ToolHost;
99
+ /** Temperature (0-1) */
100
+ temperature?: number;
101
+ /** Top-p sampling */
102
+ topP?: number;
103
+ /** Max output tokens */
104
+ maxOutputTokens?: number;
105
+ /** Maximum steps (tool call iterations) */
106
+ maxSteps?: number;
107
+ /** Reasoning/thinking level for supported models */
108
+ reasoningLevel?: ReasoningLevel;
109
+ /** Require approval for dangerous operations */
110
+ requireApproval?: boolean;
111
+ /**
112
+ * Handler for doom-loop detection.
113
+ */
114
+ onDoomLoop?: DoomLoopHandler;
115
+ /**
116
+ * Strictly enforce doom-loop detection when no custom handler is provided.
117
+ * Default: true
118
+ */
119
+ enforceDoomLoop?: boolean;
120
+ /**
121
+ * Number of identical tool calls before triggering doom-loop handling.
122
+ * Default: 3
123
+ */
124
+ doomLoopThreshold?: number;
125
+ /**
126
+ * Automatic context compaction settings.
127
+ */
128
+ compaction?: CompactionConfig;
129
+ /**
130
+ * Middleware for the agent lifecycle.
131
+ */
132
+ middleware?: AgentMiddleware[];
133
+ /**
134
+ * Context window size in tokens for overflow detection.
135
+ * Defaults to 128,000.
136
+ */
137
+ contextWindow?: number;
138
+ /**
139
+ * Custom stream provider for specialized models.
140
+ */
141
+ streamProvider?: StreamProvider;
142
+ /**
143
+ * MCP manager for external tool servers.
144
+ */
145
+ mcp?: MCPManager;
146
+ /**
147
+ * Layered prompt pipeline configuration.
148
+ */
149
+ prompt?: PromptConfig;
150
+ /**
151
+ * Simplest way to enable tracing.
152
+ */
153
+ tracing?: TracingConfig;
154
+ }
155
+
156
+ /**
157
+ * Agent preset - a reusable configuration profile.
158
+ */
159
+ interface Preset {
160
+ /** Unique identifier for this preset */
161
+ name: string;
162
+ /** Human-readable description */
163
+ description: string;
164
+ /**
165
+ * Tool allow patterns (glob-like).
166
+ * If provided, only tools matching these patterns are candidates.
167
+ */
168
+ allowTools?: string[];
169
+ /**
170
+ * Tool deny patterns (glob-like).
171
+ * Deny patterns apply only after allow matching, so explicit allows win.
172
+ */
173
+ denyTools?: string[];
174
+ /**
175
+ * Override system prompt.
176
+ * Use `{basePrompt}` to include the parent's system prompt.
177
+ */
178
+ systemPrompt?: string;
179
+ /** Override temperature (0-1). */
180
+ temperature?: number;
181
+ /** Override max steps. */
182
+ maxSteps?: number;
183
+ /** Override reasoning level. */
184
+ reasoningLevel?: ReasoningLevel;
185
+ /** Override model. */
186
+ model?: LanguageModel;
187
+ }
188
+ /**
189
+ * Result of applying a preset - ready for `fork()`.
190
+ */
191
+ interface AppliedPreset {
192
+ name: string;
193
+ systemPrompt?: string;
194
+ tools?: Tool.AnyInfo[];
195
+ temperature?: number;
196
+ maxSteps?: number;
197
+ reasoningLevel?: ReasoningLevel;
198
+ model?: LanguageModel;
199
+ }
200
+
201
+ interface AgentForkOptions {
202
+ name?: string;
203
+ systemPrompt?: string;
204
+ prompt?: PromptConfig;
205
+ model?: LanguageModel;
206
+ temperature?: number;
207
+ tools?: Tool.AnyInfo[];
208
+ maxSteps?: number;
209
+ reasoningLevel?: ReasoningLevel;
210
+ preset?: Preset;
211
+ middleware?: AgentMiddleware[];
212
+ additionalMiddleware?: AgentMiddleware[];
213
+ }
214
+
215
+ type AgentConstructionOptions = AgentConfig & {
216
+ tools?: Tool.AnyInfo[];
217
+ sessionManager?: SessionManager;
218
+ };
219
+
220
+ /**
221
+ * Create an agent instance
222
+ */
223
+ declare function createAgent(config: AgentConstructionOptions): Agent;
224
+ /**
225
+ * Embeddable AI agent with tool support.
226
+ *
227
+ * The `Agent` class is the main entry-point for consumers. It manages:
228
+ * - **Sessions** — persistent conversation history
229
+ * - **Streaming** — real-time event generation via `chat()`
230
+ * - **Tools** — registry + execution context
231
+ * - **Context management** — overflow detection & auto-compaction
232
+ * - **Reasoning** — configurable thinking levels per model
233
+ * - **Sub-agents** — `fork()` / `run()` for parallel or specialised tasks
234
+ *
235
+ * @example
236
+ * ```typescript
237
+ * import { createAgent } from "@cuylabs/agent-core";
238
+ * import { anthropic } from "@ai-sdk/anthropic";
239
+ *
240
+ * const agent = createAgent({
241
+ * model: anthropic("claude-sonnet-4-20250514"),
242
+ * cwd: "/path/to/project",
243
+ * });
244
+ *
245
+ * // Streaming
246
+ * for await (const event of agent.chat("session-1", "List all TypeScript files")) {
247
+ * if (event.type === "text-delta") process.stdout.write(event.text);
248
+ * }
249
+ *
250
+ * // Non-streaming (convenience)
251
+ * const result = await agent.send("session-1", "Fix the bug in utils.ts");
252
+ * console.log(result.response);
253
+ * ```
254
+ */
255
+ declare class Agent {
256
+ private config;
257
+ private tools;
258
+ private sessions;
259
+ private loadedSessions;
260
+ private state;
261
+ /** Context manager for overflow detection and compaction */
262
+ private contextManager;
263
+ /** Tools that user said "remember" for doom loop (don't ask again) */
264
+ private rememberedDoomLoopTools;
265
+ /** Turn change tracker for file modification tracking */
266
+ private turnTracker;
267
+ /** Counter for turn IDs */
268
+ private turnCounter;
269
+ /** MCP manager for external tool servers */
270
+ private mcpManager?;
271
+ /** Whether MCP has been connected (lazy init) */
272
+ private mcpConnected;
273
+ /** Cached MCP tools (refreshed on connect) */
274
+ private mcpToolsCache?;
275
+ /** Prompt pipeline builder (when using layered prompt mode) */
276
+ private promptBuilder?;
277
+ /** Intervention controller for mid-turn message injection */
278
+ private interventionCtrl;
279
+ /** Execution environment for tool operations */
280
+ private host;
281
+ /** Middleware runner for lifecycle hooks */
282
+ private middlewareRunner;
283
+ /** AI SDK telemetry settings (auto-created from `tracing` config) */
284
+ private telemetrySettings?;
285
+ /** Tracing shutdown function (from `tracing` config auto-setup) */
286
+ private tracingShutdown?;
287
+ constructor(config: AgentConstructionOptions);
288
+ /** Agent name (identity for spans, Dapr workflows, etc.) */
289
+ get name(): string;
290
+ /** Working directory for file operations */
291
+ get cwd(): string;
292
+ /** Current model */
293
+ get model(): LanguageModel;
294
+ /** System prompt */
295
+ get systemPrompt(): string;
296
+ /** Is currently streaming */
297
+ get isStreaming(): boolean;
298
+ /** Current reasoning level */
299
+ get reasoningLevel(): ReasoningLevel;
300
+ /**
301
+ * Set reasoning level
302
+ * Will be clamped to available levels for the current model
303
+ */
304
+ setReasoningLevel(level: ReasoningLevel): void;
305
+ /**
306
+ * Get available reasoning levels for the current model
307
+ */
308
+ getAvailableReasoningLevels(): ReasoningLevel[];
309
+ /**
310
+ * Check if current model supports reasoning
311
+ */
312
+ supportsReasoning(): boolean;
313
+ /**
314
+ * Ensure MCP is connected and return tools
315
+ * Lazy initialization - only connects on first use
316
+ */
317
+ private ensureMCPConnected;
318
+ /**
319
+ * Repair session history by synthesising missing tool-result messages.
320
+ *
321
+ * When a tool `execute()` throws, the AI SDK emits `tool-error` instead
322
+ * of `tool-result`. If the error event wasn't persisted (e.g. because
323
+ * the fix above wasn't in place), subsequent turns will fail with
324
+ * `MissingToolResultsError`. This method detects orphaned tool-call IDs
325
+ * and adds placeholder `tool` messages so the history is valid again.
326
+ */
327
+ private repairOrphanedToolCalls;
328
+ /**
329
+ * Convert internal {@link Message} array to Vercel AI SDK {@link ModelMessage} format.
330
+ *
331
+ * Handles the role-specific mappings:
332
+ * - `user` / `system` → pass-through
333
+ * - `assistant` with tool calls → `ToolCallPart[]` content
334
+ * - `tool` → `tool-result` content part
335
+ */
336
+ private toModelMessages;
337
+ /**
338
+ * Stream a chat response.
339
+ *
340
+ * Sends a user message and yields real-time {@link AgentEvent}s as the
341
+ * model responds, calls tools, and finishes. Conversation state is
342
+ * persisted to the session automatically.
343
+ *
344
+ * @param sessionId - Session identifier for conversation history
345
+ * @param message - User message to send
346
+ * @param options - Abort signal, system prompt override, and approval handler
347
+ * @yields {AgentEvent} Events as they occur during processing
348
+ */
349
+ chat(sessionId: string, message: string, options?: {
350
+ abort?: AbortSignal;
351
+ system?: string;
352
+ }): AsyncGenerator<AgentEvent>;
353
+ /**
354
+ * Ensure a session is loaded or created
355
+ */
356
+ private ensureSession;
357
+ /**
358
+ * Send a message and wait for the complete response (non-streaming).
359
+ *
360
+ * This is a convenience wrapper around {@link chat} that buffers all
361
+ * events internally and returns the final response, usage, and tool
362
+ * call results. Prefer `chat()` when you need real-time streaming.
363
+ *
364
+ * @param sessionId - Session identifier
365
+ * @param message - User message
366
+ * @param options - Abort signal and optional system prompt override
367
+ */
368
+ send(sessionId: string, message: string, options?: {
369
+ abort?: AbortSignal;
370
+ system?: string;
371
+ }): Promise<{
372
+ response: string;
373
+ usage: TokenUsage;
374
+ toolCalls: Array<{
375
+ name: string;
376
+ result: unknown;
377
+ }>;
378
+ }>;
379
+ /** Add a tool at runtime */
380
+ addTool(tool: Tool.Info): void;
381
+ /** Remove a tool by ID */
382
+ removeTool(toolId: string): boolean;
383
+ /** Get all tool IDs */
384
+ getToolIds(): string[];
385
+ /** Get all tools */
386
+ getTools(): Tool.AnyInfo[];
387
+ /** Check if a tool exists */
388
+ hasTool(toolId: string): boolean;
389
+ /** Get session manager */
390
+ getSessionManager(): SessionManager;
391
+ /** Get current session context */
392
+ getSessionContext(): SessionContext;
393
+ /** Get messages from current session */
394
+ getMessages(): Message[];
395
+ /** Delete a session */
396
+ deleteSession(sessionId: string): Promise<boolean>;
397
+ /** List all sessions */
398
+ listSessions(): Promise<SessionInfo[]>;
399
+ /** Branch from current point */
400
+ branch(summary?: string): Promise<string>;
401
+ /**
402
+ * Get context window statistics.
403
+ *
404
+ * Useful for UI to display context utilization like:
405
+ * - Progress bar showing how full the context is
406
+ * - Warning when approaching limit
407
+ * - Info about when compaction will trigger
408
+ *
409
+ * @example
410
+ * ```typescript
411
+ * const stats = agent.getContextStats();
412
+ * console.log(`Context: ${stats.utilizationPercent}% used`);
413
+ * if (stats.shouldPrune) {
414
+ * console.log('Context will be compacted soon');
415
+ * }
416
+ * ```
417
+ */
418
+ getContextStats(): {
419
+ tokens: number;
420
+ limit: number;
421
+ available: number;
422
+ utilizationPercent: number;
423
+ isOverflowing: boolean;
424
+ shouldPrune: boolean;
425
+ };
426
+ /**
427
+ * Manually trigger context compaction.
428
+ *
429
+ * Usually auto-compaction handles this, but you can trigger it manually
430
+ * if needed (e.g., before a long operation).
431
+ *
432
+ * @returns Pruning result with details about what was removed/summarized
433
+ */
434
+ compactContext(): Promise<{
435
+ removedCount: number;
436
+ tokensRemoved: number;
437
+ summarized: boolean;
438
+ summary?: string;
439
+ }>;
440
+ /**
441
+ * Clear remembered doom loop tools.
442
+ *
443
+ * When a user says "remember" for a doom loop, that tool is added
444
+ * to a set that skips future doom loop checks. Call this to reset.
445
+ */
446
+ clearRememberedDoomLoopTools(): void;
447
+ /**
448
+ * Inject a message at the next step boundary of a running turn.
449
+ *
450
+ * This is the primary redirection mechanism. When the agent is
451
+ * streaming a multi-step response (calling tools, reasoning, etc.),
452
+ * this injects a user message before the next LLM call. The LLM
453
+ * sees the intervention and can adjust its behavior.
454
+ *
455
+ * Uses Vercel AI SDK v6's `prepareStep` hook — no polling, no
456
+ * custom loop code. The SDK handles the injection naturally.
457
+ *
458
+ * Safe to call from any async context (UI event handlers, WebSocket
459
+ * callbacks, timers, etc.) while `chat()` is running.
460
+ *
461
+ * If called when no turn is active, the message will be picked up
462
+ * by the first step of the next `chat()` call.
463
+ *
464
+ * @param message - The user message to inject mid-turn
465
+ * @returns Intervention ID for tracking
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * // Start a streaming turn
470
+ * const stream = agent.chat("session-1", "refactor the auth module");
471
+ *
472
+ * // From a UI handler (another async context):
473
+ * agent.intervene("stop, focus only on JWT validation in auth.ts");
474
+ *
475
+ * // The stream will yield an intervention-applied event
476
+ * for await (const event of stream) {
477
+ * if (event.type === "intervention-applied") {
478
+ * console.log(`Redirected: ${event.message}`);
479
+ * }
480
+ * }
481
+ * ```
482
+ */
483
+ intervene(message: string): string;
484
+ /**
485
+ * Queue a message for after the current turn completes.
486
+ *
487
+ * Unlike `intervene()`, this does **not** interrupt the current turn.
488
+ * The message is held and available via `drainQueuedNext()` after
489
+ * `chat()` finishes. The consumer decides whether to send it as a
490
+ * new turn.
491
+ *
492
+ * @param message - The message to queue
493
+ * @returns Intervention ID for tracking
494
+ *
495
+ * @example
496
+ * ```typescript
497
+ * agent.queueNext("now run the test suite");
498
+ *
499
+ * for await (const event of agent.chat("s1", "fix the bug")) {
500
+ * // ... handle events
501
+ * }
502
+ *
503
+ * // After turn completes, check for queued messages
504
+ * if (agent.hasQueuedNext()) {
505
+ * const next = agent.drainQueuedNext();
506
+ * for (const item of next) {
507
+ * // Send as a new turn
508
+ * for await (const ev of agent.chat("s1", item.message)) { ... }
509
+ * }
510
+ * }
511
+ * ```
512
+ */
513
+ queueNext(message: string): string;
514
+ /** Whether there are deferred messages queued for after the turn */
515
+ hasQueuedNext(): boolean;
516
+ /** Drain and return all deferred messages (clears the queue) */
517
+ drainQueuedNext(): PendingIntervention[];
518
+ /**
519
+ * Get the raw intervention controller for advanced use cases.
520
+ *
521
+ * Use this when you need fine-grained control over the intervention
522
+ * lifecycle (e.g., checking pending count, clearing queues, setting
523
+ * custom `onApplied` callbacks).
524
+ *
525
+ * @internal
526
+ */
527
+ getInterventionController(): InterventionController;
528
+ /**
529
+ * Get the unified diff for all file changes in the current/last turn.
530
+ *
531
+ * @example
532
+ * ```typescript
533
+ * const diff = await agent.getTurnDiff();
534
+ * if (diff) {
535
+ * console.log('Changes this turn:\n', diff);
536
+ * }
537
+ * ```
538
+ */
539
+ getTurnDiff(): Promise<string | null>;
540
+ /**
541
+ * Get list of files being tracked in the current turn.
542
+ */
543
+ getTrackedFiles(): string[];
544
+ /**
545
+ * Undo all file changes from the current turn.
546
+ * Restores files to their state before the turn started.
547
+ *
548
+ * @example
549
+ * ```typescript
550
+ * const result = await agent.undoTurn();
551
+ * console.log(`Restored ${result.restored.length} files`);
552
+ * if (result.failed.length > 0) {
553
+ * console.log('Failed to restore:', result.failed);
554
+ * }
555
+ * ```
556
+ */
557
+ undoTurn(): Promise<UndoResult>;
558
+ /**
559
+ * Undo changes to specific files only.
560
+ *
561
+ * @param files - Array of file paths to restore (relative to cwd)
562
+ */
563
+ undoFiles(files: string[]): Promise<UndoResult>;
564
+ /**
565
+ * Check if currently tracking a turn.
566
+ */
567
+ isTrackingTurn(): boolean;
568
+ /**
569
+ * Get access to the raw turn tracker for advanced use cases.
570
+ *
571
+ * @internal
572
+ */
573
+ getTurnTracker(): TurnChangeTracker;
574
+ /**
575
+ * Update system prompt.
576
+ *
577
+ * If the agent is using the prompt pipeline, calling this switches
578
+ * to flat string mode (disabling the pipeline). To modify the pipeline
579
+ * instead, use `getPromptBuilder()`.
580
+ */
581
+ setSystemPrompt(prompt: string): void;
582
+ /** Update working directory */
583
+ setCwd(cwd: string): void;
584
+ /** Update model */
585
+ setModel(model: LanguageModel): void;
586
+ /**
587
+ * Get the prompt builder (when using pipeline mode).
588
+ * Returns undefined if using flat string mode.
589
+ *
590
+ * Use this to add/remove sections, clear caches, or inspect
591
+ * the prompt composition without switching to flat mode.
592
+ *
593
+ * @example
594
+ * ```typescript
595
+ * const builder = agent.getPromptBuilder();
596
+ * if (builder) {
597
+ * builder.addSection({
598
+ * id: "task-context",
599
+ * label: "Task Context",
600
+ * content: "Focus on fixing authentication bugs.",
601
+ * priority: 60,
602
+ * });
603
+ * }
604
+ * ```
605
+ */
606
+ getPromptBuilder(): PromptBuilder | undefined;
607
+ /**
608
+ * Check if the agent is using the prompt pipeline.
609
+ */
610
+ isUsingPromptPipeline(): boolean;
611
+ /**
612
+ * Build the effective system prompts for a turn.
613
+ *
614
+ * This mirrors the prompt resolution path used by `chat()` so external host
615
+ * runtimes can start durable turns without duplicating prompt assembly.
616
+ */
617
+ buildSystemPrompts(sessionId: string, override?: string): Promise<string[]>;
618
+ /**
619
+ * Return the runtime configuration required by the extracted turn-step
620
+ * helpers.
621
+ */
622
+ getTurnRuntimeConfig(): AgentTurnStepRuntimeConfig;
623
+ /**
624
+ * Get the configured tool host.
625
+ */
626
+ getHost(): ToolHost;
627
+ /**
628
+ * Get the configured middleware runner.
629
+ *
630
+ * The runner is immutable after construction, so it is safe to reuse in
631
+ * durable activity helpers that need the same middleware stack.
632
+ */
633
+ getMiddlewareRunner(): MiddlewareRunner;
634
+ /**
635
+ * Fork this agent to create a sub-agent with modified configuration.
636
+ *
637
+ * Sub-agents share the same session manager but can have different:
638
+ * - System prompts (specialized for tasks)
639
+ * - Tools (restricted subset)
640
+ * - Models (cheaper/faster for simple tasks)
641
+ * - Reasoning levels
642
+ *
643
+ * @example
644
+ * ```typescript
645
+ * // Create an exploration sub-agent with read-only tools
646
+ * const explorer = agent.fork({
647
+ * name: "explore",
648
+ * systemPrompt: "You explore codebases. Only use read and search tools.",
649
+ * tools: [readTool, grepTool, globTool],
650
+ * });
651
+ *
652
+ * // Run the sub-agent
653
+ * const result = await explorer.run({
654
+ * parentSessionId: "main-session",
655
+ * message: "Find all API endpoints",
656
+ * });
657
+ * ```
658
+ */
659
+ fork(options?: AgentForkOptions): Agent;
660
+ /**
661
+ * Create a sub-agent with a preset configuration.
662
+ *
663
+ * Convenience method that applies a preset and returns a forked agent.
664
+ *
665
+ * @example
666
+ * ```typescript
667
+ * import { Presets } from "@cuylabs/agent-core";
668
+ *
669
+ * // Create an exploration sub-agent
670
+ * const explorer = agent.withPreset(Presets.explore);
671
+ * const result = await explorer.run({
672
+ * message: "Find all API routes in this project",
673
+ * });
674
+ *
675
+ * // Create a careful review sub-agent
676
+ * const reviewer = agent.withPreset(Presets.review);
677
+ * const review = await reviewer.run({
678
+ * message: "Review src/auth.ts for security issues",
679
+ * });
680
+ * ```
681
+ */
682
+ withPreset(preset: Preset): Agent;
683
+ /**
684
+ * Run a task in an isolated sub-agent session.
685
+ *
686
+ * Creates a new session linked to the parent, runs the task to completion,
687
+ * and returns the result. The sub-agent session is preserved for inspection.
688
+ *
689
+ * @example
690
+ * ```typescript
691
+ * const result = await agent.run({
692
+ * parentSessionId: "main-session",
693
+ * message: "Review this code for security issues",
694
+ * title: "Security Review",
695
+ * });
696
+ *
697
+ * console.log(result.response);
698
+ * console.log(`Sub-agent session: ${result.sessionId}`);
699
+ * ```
700
+ */
701
+ run(options: {
702
+ /** Parent session ID (for linking) */
703
+ parentSessionId?: string;
704
+ /** The task/message to execute */
705
+ message: string;
706
+ /** Title for the sub-agent session */
707
+ title?: string;
708
+ /** Abort signal */
709
+ abort?: AbortSignal;
710
+ }): Promise<{
711
+ /** Final response text */
712
+ response: string;
713
+ /** Sub-agent session ID */
714
+ sessionId: string;
715
+ /** Token usage */
716
+ usage: TokenUsage;
717
+ /** Tool calls made */
718
+ toolCalls: Array<{
719
+ name: string;
720
+ result: unknown;
721
+ }>;
722
+ }>;
723
+ /**
724
+ * Get the MCP manager (if configured)
725
+ */
726
+ getMCP(): MCPManager | undefined;
727
+ /**
728
+ * Check if MCP is configured
729
+ */
730
+ hasMCP(): boolean;
731
+ /**
732
+ * Reconnect to MCP servers
733
+ *
734
+ * Use this after network issues or when server availability changes.
735
+ * Clears tool cache and reconnects all servers.
736
+ */
737
+ reconnectMCP(): Promise<void>;
738
+ /**
739
+ * Close the agent and clean up resources
740
+ *
741
+ * Flushes and shuts down the tracing provider (when `tracing` was configured),
742
+ * closes MCP connections if configured.
743
+ * After calling close(), the agent should not be used.
744
+ */
745
+ close(): Promise<void>;
746
+ }
747
+
748
+ /**
749
+ * Sub-Agent Types
750
+ *
751
+ * Type definitions for the sub-agent system: profiles, lifecycle status,
752
+ * handles, and configuration.
753
+ *
754
+ * Following PowerShell verb-noun naming (Invoke-Agent, Get-Agent, Stop-Agent).
755
+ *
756
+ * Designed for agent-core's composable library architecture.
757
+ *
758
+ * Key design decisions:
759
+ *
760
+ * 1. **Library-first**: Unlike CLI-embedded tools, these
761
+ * are importable building blocks. The consumer creates them with
762
+ * `createSubAgentTools(parent)` and opts in — nothing auto-registered.
763
+ *
764
+ * 2. **Agent profiles over role configs**: Instead of TOML files or markdown
765
+ * agents, we use composable `AgentProfile` objects that wrap existing
766
+ * `Preset` + extra metadata the LLM can read.
767
+ *
768
+ * 3. **Progressive lifecycle**: Start with synchronous `invoke_agent` (simplest),
769
+ * add `wait_agent`/`close_agent` only when async profiles exist.
770
+ *
771
+ * 4. **Depth safety**: Hard limit on nesting with configurable max depth.
772
+ *
773
+ * @packageDocumentation
774
+ */
775
+
776
+ /**
777
+ * An agent profile defines a specialized sub-agent personality.
778
+ *
779
+ * Profiles combine a `Preset` (tool filtering, temperature, etc.) with
780
+ * LLM-facing metadata (name, description, examples) so the model knows
781
+ * when and how to delegate.
782
+ *
783
+ * Profiles define specialized sub-agent personalities with roles
784
+ * like explorer, worker, planner, and reviewer.
785
+ *
786
+ * @example
787
+ * ```typescript
788
+ * const explorer: AgentProfile = {
789
+ * name: "explorer",
790
+ * description: "Fast, read-only codebase exploration. Use when you need to find files, search code, or understand project structure.",
791
+ * preset: Presets.explore,
792
+ * maxSteps: 30,
793
+ * };
794
+ * ```
795
+ */
796
+ interface AgentProfile {
797
+ /** Unique identifier used in tool calls (lowercase, no spaces) */
798
+ name: string;
799
+ /**
800
+ * When to use this sub-agent — written for the LLM to consume.
801
+ *
802
+ * This is the most important field. The parent LLM reads this to decide
803
+ * whether to delegate. Include clear trigger phrases.
804
+ */
805
+ description: string;
806
+ /**
807
+ * Preset to apply (tool filtering, temperature, system prompt, etc.).
808
+ * If omitted, inherits the parent agent's configuration.
809
+ */
810
+ preset?: Preset;
811
+ /**
812
+ * Override system prompt for this profile.
813
+ * Takes precedence over preset's systemPrompt.
814
+ * Use `{basePrompt}` to include the parent's system prompt.
815
+ */
816
+ systemPrompt?: string;
817
+ /**
818
+ * Override model for this profile.
819
+ * Useful for using cheaper/faster models for simple tasks.
820
+ */
821
+ model?: LanguageModel;
822
+ /** Max steps for this sub-agent (default: parent's maxSteps) */
823
+ maxSteps?: number;
824
+ /**
825
+ * Additional middleware appended to the parent's middleware stack.
826
+ * Useful for adding logging or guardrails specific to this profile.
827
+ */
828
+ additionalMiddleware?: AgentMiddleware[];
829
+ /**
830
+ * Additional tools beyond what the preset allows.
831
+ * These are merged with the preset-filtered tools.
832
+ */
833
+ additionalTools?: Tool.AnyInfo[];
834
+ /**
835
+ * Whether this sub-agent can itself spawn further sub-agents.
836
+ * When false, the `invoke_agent` tool is removed from the child.
837
+ *
838
+ * @default false — sub-agents cannot nest by default (safe default)
839
+ */
840
+ canSpawn?: boolean;
841
+ }
842
+ /**
843
+ * Lifecycle status of a running or completed sub-agent.
844
+ *
845
+ * Simplified lifecycle for the fire-and-forget-with-optional-wait model.
846
+ */
847
+ type SubAgentStatus = {
848
+ state: "running";
849
+ } | {
850
+ state: "completed";
851
+ response: string;
852
+ usage: SubAgentUsage;
853
+ } | {
854
+ state: "errored";
855
+ error: string;
856
+ } | {
857
+ state: "cancelled";
858
+ };
859
+ /**
860
+ * Token usage tracking for a sub-agent run.
861
+ */
862
+ interface SubAgentUsage {
863
+ inputTokens: number;
864
+ outputTokens: number;
865
+ totalTokens: number;
866
+ }
867
+ /**
868
+ * A handle to a running or completed sub-agent.
869
+ *
870
+ * Returned by async invocations. Allows the parent to wait for completion,
871
+ * check status, or cancel.
872
+ */
873
+ interface SubAgentHandle {
874
+ /** Unique ID for this sub-agent invocation */
875
+ id: string;
876
+ /** Human-readable name (from profile or auto-generated) */
877
+ name: string;
878
+ /** Session ID of the child agent's session */
879
+ sessionId: string;
880
+ /** Current status */
881
+ status: SubAgentStatus;
882
+ /** The promise that resolves when the sub-agent completes */
883
+ promise: Promise<SubAgentCompletedResult>;
884
+ /** Abort controller to cancel this sub-agent */
885
+ abort: AbortController;
886
+ }
887
+ /**
888
+ * The final result of a completed sub-agent.
889
+ */
890
+ interface SubAgentCompletedResult {
891
+ /** Final response text */
892
+ response: string;
893
+ /** Session ID (for audit/inspection) */
894
+ sessionId: string;
895
+ /** Token usage */
896
+ usage: SubAgentUsage;
897
+ /** Tool calls the sub-agent made */
898
+ toolCalls: Array<{
899
+ name: string;
900
+ result: unknown;
901
+ }>;
902
+ }
903
+ /**
904
+ * Configuration for `createSubAgentTools()`.
905
+ *
906
+ * Controls which profiles are available, concurrency limits,
907
+ * depth limits, and whether async mode is enabled.
908
+ */
909
+ interface SubAgentToolConfig {
910
+ /**
911
+ * Available sub-agent profiles.
912
+ * Each profile defines a specialized persona the LLM can invoke.
913
+ * At least one profile is required.
914
+ */
915
+ profiles: AgentProfile[];
916
+ /**
917
+ * Maximum concurrent sub-agents (across all profiles).
918
+ * @default 6
919
+ */
920
+ maxConcurrent?: number;
921
+ /**
922
+ * Maximum nesting depth for recursive sub-agent spawning.
923
+ * Depth 0 = no spawning, 1 = one level of sub-agents, etc.
924
+ *
925
+ * When a sub-agent reaches the depth limit, the `invoke_agent`
926
+ * tool is automatically removed from its tool set.
927
+ *
928
+ * @default 2
929
+ */
930
+ maxDepth?: number;
931
+ /**
932
+ * Current depth (internal — incremented when creating child tools).
933
+ * Users should not set this directly.
934
+ *
935
+ * @internal
936
+ */
937
+ currentDepth?: number;
938
+ /**
939
+ * Enable async mode with `wait_agent` and `close_agent` tools.
940
+ *
941
+ * When false (default), `invoke_agent` blocks until the sub-agent
942
+ * completes and returns the result directly — simpler but sequential.
943
+ *
944
+ * When true, `invoke_agent` returns immediately with an agent ID,
945
+ * and the LLM must call `wait_agent` to collect results. This enables
946
+ * parallel sub-agent execution.
947
+ *
948
+ * @default false
949
+ */
950
+ async?: boolean;
951
+ /**
952
+ * Title prefix for sub-agent sessions.
953
+ * @default "Sub-agent"
954
+ */
955
+ sessionTitlePrefix?: string;
956
+ }
957
+ /** Default maximum concurrent sub-agents */
958
+ declare const DEFAULT_MAX_CONCURRENT = 6;
959
+ /** Default maximum nesting depth */
960
+ declare const DEFAULT_MAX_SPAWN_DEPTH = 2;
961
+ /** Default session title prefix */
962
+ declare const DEFAULT_SESSION_TITLE_PREFIX = "Sub-agent";
963
+
964
+ /**
965
+ * Sub-Agent Tracker — in-memory state for active sub-agents
966
+ *
967
+ * Manages the lifecycle of running sub-agents: slots, handles,
968
+ * concurrency limits, and depth enforcement.
969
+ *
970
+ * Handles spawn slot reservation and depth checking, designed for
971
+ * single-process TypeScript/async usage.
972
+ *
973
+ * @packageDocumentation
974
+ */
975
+
976
+ /**
977
+ * Tracks active sub-agent handles and enforces concurrency/depth limits.
978
+ *
979
+ * One tracker is created per `createSubAgentTools()` call and shared
980
+ * across all sub-agent tool instances for that parent agent.
981
+ */
982
+ declare class SubAgentTracker {
983
+ /** Active sub-agent handles by ID */
984
+ private readonly handles;
985
+ /** Maximum concurrent sub-agents */
986
+ readonly maxConcurrent: number;
987
+ /** Maximum nesting depth */
988
+ readonly maxDepth: number;
989
+ /** Current depth in the spawn hierarchy */
990
+ readonly currentDepth: number;
991
+ constructor(config?: Partial<SubAgentToolConfig>);
992
+ /** Number of currently active (running) sub-agents */
993
+ get activeCount(): number;
994
+ /** Total tracked handles (including completed) */
995
+ get totalCount(): number;
996
+ /**
997
+ * Check if a new sub-agent can be spawned.
998
+ * Returns an error message if not, undefined if OK.
999
+ */
1000
+ canSpawn(): string | undefined;
1001
+ /** Whether the current depth allows further spawning */
1002
+ get canNest(): boolean;
1003
+ /** Register a new sub-agent handle */
1004
+ register(handle: SubAgentHandle): void;
1005
+ /** Get a handle by ID */
1006
+ get(id: string): SubAgentHandle | undefined;
1007
+ /** Update a handle's status */
1008
+ updateStatus(id: string, status: SubAgentStatus): void;
1009
+ /** Get all handles */
1010
+ list(): SubAgentHandle[];
1011
+ /** Get all running handles */
1012
+ running(): SubAgentHandle[];
1013
+ /** Get all completed handles */
1014
+ completed(): SubAgentHandle[];
1015
+ /**
1016
+ * Cancel a running sub-agent.
1017
+ * Signals the abort controller and updates status.
1018
+ */
1019
+ cancel(id: string): boolean;
1020
+ /**
1021
+ * Cancel all running sub-agents.
1022
+ */
1023
+ cancelAll(): void;
1024
+ /**
1025
+ * Wait for a specific sub-agent to complete.
1026
+ * Returns the result or throws if not found.
1027
+ */
1028
+ wait(id: string, timeoutMs?: number): Promise<SubAgentCompletedResult>;
1029
+ /**
1030
+ * Wait for any one of the given sub-agents to complete.
1031
+ * Returns the first result.
1032
+ */
1033
+ waitAny(ids: string[], timeoutMs?: number): Promise<{
1034
+ id: string;
1035
+ result: SubAgentCompletedResult;
1036
+ } | {
1037
+ timedOut: true;
1038
+ }>;
1039
+ /**
1040
+ * Create a child tracker configuration for a nested sub-agent.
1041
+ * Increments the depth counter.
1042
+ */
1043
+ childConfig(): Partial<SubAgentToolConfig>;
1044
+ }
1045
+
1046
+ /**
1047
+ * Sub-Agent Tools — LLM-callable tools for delegating work to specialized agents
1048
+ *
1049
+ * Provides three tools:
1050
+ * - `invoke_agent` — spawn a sub-agent for a focused task
1051
+ * - `wait_agent` — collect async sub-agent results
1052
+ * - `close_agent` — cancel a running async sub-agent
1053
+ *
1054
+ * @packageDocumentation
1055
+ */
1056
+
1057
+ /**
1058
+ * Create the sub-agent tools for an agent.
1059
+ *
1060
+ * Returns an array of tools that the LLM can call to delegate tasks:
1061
+ * - `invoke_agent` — always included
1062
+ * - `wait_agent` — only in async mode
1063
+ * - `close_agent` — only in async mode
1064
+ */
1065
+ declare function createSubAgentTools(parent: Agent, config: SubAgentToolConfig): Tool.AnyInfo[];
1066
+
1067
+ export { type AppliedPreset as A, type CompactionConfig as C, DEFAULT_MAX_CONCURRENT as D, type Preset as P, type SubAgentCompletedResult as S, type TracingConfig as T, Agent as a, type AgentConfig as b, type AgentProfile as c, DEFAULT_MAX_SPAWN_DEPTH as d, DEFAULT_SESSION_TITLE_PREFIX as e, type SubAgentHandle as f, type SubAgentStatus as g, type SubAgentToolConfig as h, SubAgentTracker as i, type SubAgentUsage as j, createAgent as k, createSubAgentTools as l };