@cuylabs/agent-core 0.6.0 → 0.8.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 (74) hide show
  1. package/README.md +5 -1
  2. package/dist/{builder-BKkipazh.d.ts → builder-UpOWQMW3.d.ts} +2 -2
  3. package/dist/{chunk-3C4VKG4P.js → chunk-4BDA7DQY.js} +273 -807
  4. package/dist/chunk-7VKQ4WPB.js +73 -0
  5. package/dist/chunk-BFM2YHNM.js +222 -0
  6. package/dist/chunk-CAA7FHIH.js +280 -0
  7. package/dist/chunk-KUVSERLJ.js +50 -0
  8. package/dist/chunk-N6HWIEEA.js +423 -0
  9. package/dist/chunk-N7P4PN3O.js +84 -0
  10. package/dist/{chunk-QWFMX226.js → chunk-RFEKJKTO.js} +252 -13
  11. package/dist/chunk-RZITT45F.js +202 -0
  12. package/dist/{chunk-X635CM2F.js → chunk-SQU2AJHO.js} +1 -1
  13. package/dist/chunk-VNQBHPCT.js +398 -0
  14. package/dist/{chunk-QAQADS4X.js → chunk-WWYYNWEW.js} +2 -1
  15. package/dist/{chunk-O2ZCFQL6.js → chunk-YSLSEQ6B.js} +105 -220
  16. package/dist/context/index.js +1 -1
  17. package/dist/errors/index.d.ts +11 -0
  18. package/dist/errors/index.js +16 -0
  19. package/dist/events-CE72w8W4.d.ts +149 -0
  20. package/dist/host/index.d.ts +45 -0
  21. package/dist/host/index.js +8 -0
  22. package/dist/{index-DZQJD_hp.d.ts → index-CWSchSql.d.ts} +42 -51
  23. package/dist/index.d.ts +98 -190
  24. package/dist/index.js +476 -939
  25. package/dist/inference/index.d.ts +62 -0
  26. package/dist/inference/index.js +27 -0
  27. package/dist/llm-error-D93FNNLY.d.ts +32 -0
  28. package/dist/middleware/index.d.ts +246 -5
  29. package/dist/middleware/index.js +7 -3
  30. package/dist/models/index.d.ts +226 -3
  31. package/dist/models/index.js +41 -3
  32. package/dist/presets/index.d.ts +53 -0
  33. package/dist/presets/index.js +28 -0
  34. package/dist/prompt/index.d.ts +12 -7
  35. package/dist/reasoning/index.d.ts +53 -8
  36. package/dist/reasoning/index.js +2 -7
  37. package/dist/{registry-CuRWWtcT.d.ts → registry-DwYqsQkX.d.ts} +1 -1
  38. package/dist/{runner-G1wxEgac.d.ts → runner-e2YRcUoX.d.ts} +82 -148
  39. package/dist/runtime/index.d.ts +44 -7
  40. package/dist/runtime/index.js +16 -5
  41. package/dist/safety/index.d.ts +38 -0
  42. package/dist/safety/index.js +12 -0
  43. package/dist/scope/index.d.ts +10 -0
  44. package/dist/scope/index.js +14 -0
  45. package/dist/{session-manager-Uawm2Le7.d.ts → session-manager-B_CWGTsl.d.ts} +1 -1
  46. package/dist/signal/index.d.ts +28 -0
  47. package/dist/signal/index.js +6 -0
  48. package/dist/skill/index.d.ts +8 -5
  49. package/dist/storage/index.d.ts +2 -2
  50. package/dist/sub-agent/index.d.ts +17 -8
  51. package/dist/tool/index.d.ts +9 -4
  52. package/dist/tool/index.js +4 -3
  53. package/dist/tool-BHbyUAy3.d.ts +150 -0
  54. package/dist/{tool-DYp6-cC3.d.ts → tool-DLXAR9Ce.d.ts} +5 -99
  55. package/dist/tracking/index.d.ts +3 -1
  56. package/dist/{tool-pFAnJc5Y.d.ts → types-BfNpU8NS.d.ts} +1 -150
  57. package/dist/types-BnpEOYV-.d.ts +50 -0
  58. package/dist/types-CHiPh8U2.d.ts +100 -0
  59. package/dist/types-CQL-SvTn.d.ts +29 -0
  60. package/dist/types-CWm-7rvB.d.ts +55 -0
  61. package/dist/types-KKDrdU9Y.d.ts +325 -0
  62. package/dist/{resolver-DOfZ-xuk.d.ts → types-QA4WhEfz.d.ts} +1 -117
  63. package/dist/types-QKHHQLLq.d.ts +336 -0
  64. package/dist/types-YuWV4ag7.d.ts +72 -0
  65. package/package.json +74 -8
  66. package/dist/capabilities/index.d.ts +0 -97
  67. package/dist/capabilities/index.js +0 -46
  68. package/dist/chunk-6TDTQJ4P.js +0 -116
  69. package/dist/chunk-FG4MD5MU.js +0 -54
  70. package/dist/config-D2xeGEHK.d.ts +0 -52
  71. package/dist/identifiers-BLUxFqV_.d.ts +0 -12
  72. package/dist/index-ipP3_ztp.d.ts +0 -198
  73. package/dist/network-D76DS5ot.d.ts +0 -5
  74. package/dist/types-BWo810L_.d.ts +0 -648
package/dist/index.js CHANGED
@@ -1,71 +1,27 @@
1
- import {
2
- AgentTurnEngine,
3
- ContextOverflowError,
4
- DEFAULT_RETRY_CONFIG,
5
- DoomLoopError,
6
- LLM,
7
- LLMError,
8
- OUTPUT_TOKEN_MAX,
9
- advanceAgentTurnState,
10
- applyAgentWorkflowCommitResult,
11
- applyAgentWorkflowModelStepResult,
12
- applyAgentWorkflowToolBatchResult,
13
- applyAgentWorkflowToolCallResult,
14
- calculateDelay,
15
- cloneAgentWorkflowTurnState,
16
- commitOutput,
17
- commitStep,
18
- convertAgentMessagesToModelMessages,
19
- createAgentTaskRunner,
20
- createAgentTurnEngine,
21
- createAgentTurnState,
22
- createAgentTurnStepCommitBatch,
23
- createAgentWorkflowTurnState,
24
- createRetryHandler,
25
- createRetryState,
26
- defaultAgentTaskCheckpointStrategy,
27
- failAgentTurnState,
28
- failAgentWorkflowTurnState,
29
- getErrorCategory,
30
- getRetryDelay,
31
- isRetryable,
32
- isRetryableCategory,
33
- planNextAgentWorkflowOperation,
34
- prepareModelStep,
35
- processStream,
36
- recordAgentWorkflowReplayDecision,
37
- restoreAgentWorkflowMessage,
38
- restoreAgentWorkflowMessages,
39
- runModelStep,
40
- runToolBatch,
41
- shouldRetry,
42
- sleep,
43
- snapshotAgentWorkflowMessage,
44
- snapshotAgentWorkflowMessages,
45
- withRetry
46
- } from "./chunk-3C4VKG4P.js";
47
- import {
48
- createSkillResourceTool,
49
- createSkillTool,
50
- createSkillTools
51
- } from "./chunk-YUUJK53A.js";
52
1
  import {
53
2
  FileStorage,
54
3
  MemoryStorage,
55
4
  STORAGE_VERSION,
56
5
  SessionManager,
6
+ buildEntryPath,
57
7
  buildMessagesFromEntries,
58
8
  configureDefaultSessionManager,
9
+ createMessageEntry,
10
+ createMetadataEntry,
59
11
  deserializeMessage,
12
+ extractSessionInfo,
60
13
  generateEntryId,
61
14
  getDataDir,
62
15
  getDefaultSessionManager,
16
+ getGitRootHash,
63
17
  getLeafId,
18
+ getProjectId,
64
19
  getProjectSessionsDir,
65
20
  getSessionsDir,
66
21
  parseJSONL,
67
22
  serializeMessage,
68
- toJSONL
23
+ toJSONL,
24
+ toJSONLBatch
69
25
  } from "./chunk-BDBZ3SLK.js";
70
26
  import {
71
27
  DEFAULT_MAX_CONCURRENT,
@@ -78,20 +34,6 @@ import {
78
34
  ToolRegistry,
79
35
  defaultRegistry
80
36
  } from "./chunk-SDSBEQXG.js";
81
- import {
82
- executeAgentToolCall
83
- } from "./chunk-FG4MD5MU.js";
84
- import {
85
- MAX_BYTES,
86
- MAX_LINES,
87
- TRUNCATE_DIR,
88
- TRUNCATE_GLOB,
89
- Tool,
90
- defineTool,
91
- formatSize,
92
- normalizeToolReplayPolicy,
93
- truncateOutput
94
- } from "./chunk-P6YF7USR.js";
95
37
  import {
96
38
  TurnChangeTracker,
97
39
  clearCheckpoints,
@@ -99,43 +41,19 @@ import {
99
41
  createTurnTracker
100
42
  } from "./chunk-VBWWUHWI.js";
101
43
  import {
102
- extractFilePathsFromArgs,
103
- shouldCaptureBaseline,
104
- withFileTracking
105
- } from "./chunk-VEKUXUVF.js";
106
- import {
107
- ContextManager,
108
- DEFAULT_CONTEXT_LIMITS,
109
- estimateConversationTokens,
110
- estimateMessageTokens,
111
- estimateTokens,
112
- findCutPoint,
113
- generateSummary,
114
- isContextOverflowing,
115
- pruneContext,
116
- pruneToolResults,
117
- shouldPruneContext
118
- } from "./chunk-QAQADS4X.js";
119
- import {
120
- createMCPManager,
121
- defineServer,
122
- httpServer,
123
- sseServer,
124
- stdioServer
125
- } from "./chunk-ZXAKHMWH.js";
126
- import {
127
- ApprovalDeniedError,
128
- ApprovalTimeoutError,
129
- MiddlewareRunner,
130
- approvalMiddleware,
131
- createApprovalHandler,
132
- createTelemetryConfig,
133
- getToolRisk,
134
- otelMiddleware
135
- } from "./chunk-O2ZCFQL6.js";
136
- import {
137
- createResolver
138
- } from "./chunk-6TDTQJ4P.js";
44
+ Presets,
45
+ applyPreset,
46
+ careful,
47
+ code,
48
+ createPreset,
49
+ explore,
50
+ filterTools,
51
+ mergePresets,
52
+ plan,
53
+ quick,
54
+ review,
55
+ watch
56
+ } from "./chunk-CAA7FHIH.js";
139
57
  import {
140
58
  DEFAULT_INSTRUCTION_PATTERNS,
141
59
  DEFAULT_MAX_DEPTH,
@@ -158,6 +76,58 @@ import {
158
76
  loadGlobalInstructions,
159
77
  summarizeEnvironment
160
78
  } from "./chunk-IVUJDISU.js";
79
+ import {
80
+ AgentTurnEngine,
81
+ ContextOverflowError,
82
+ DoomLoopError,
83
+ advanceAgentTurnState,
84
+ applyAgentWorkflowCommitResult,
85
+ applyAgentWorkflowModelStepResult,
86
+ applyAgentWorkflowToolBatchResult,
87
+ applyAgentWorkflowToolCallResult,
88
+ cloneAgentWorkflowTurnState,
89
+ commitOutput,
90
+ commitStep,
91
+ convertAgentMessagesToModelMessages,
92
+ createAgentTaskRunner,
93
+ createAgentTurnEngine,
94
+ createAgentTurnState,
95
+ createAgentTurnStepCommitBatch,
96
+ createAgentWorkflowTurnState,
97
+ defaultAgentTaskCheckpointStrategy,
98
+ failAgentTurnState,
99
+ failAgentWorkflowTurnState,
100
+ planNextAgentWorkflowOperation,
101
+ prepareModelStep,
102
+ processStepStream,
103
+ processStream,
104
+ recordAgentWorkflowReplayDecision,
105
+ restoreAgentWorkflowMessage,
106
+ restoreAgentWorkflowMessages,
107
+ runModelStep,
108
+ runToolBatch,
109
+ snapshotAgentWorkflowMessage,
110
+ snapshotAgentWorkflowMessages
111
+ } from "./chunk-4BDA7DQY.js";
112
+ import {
113
+ LocalSignal
114
+ } from "./chunk-KUVSERLJ.js";
115
+ import {
116
+ createSkillResourceTool,
117
+ createSkillTool,
118
+ createSkillTools
119
+ } from "./chunk-YUUJK53A.js";
120
+ import {
121
+ MAX_BYTES,
122
+ MAX_LINES,
123
+ TRUNCATE_DIR,
124
+ TRUNCATE_GLOB,
125
+ Tool,
126
+ defineTool,
127
+ formatSize,
128
+ normalizeToolReplayPolicy,
129
+ truncateOutput
130
+ } from "./chunk-P6YF7USR.js";
161
131
  import {
162
132
  DEFAULT_EXTERNAL_DIRS,
163
133
  DEFAULT_MAX_SCAN_DEPTH,
@@ -174,19 +144,126 @@ import {
174
144
  parseFrontmatter
175
145
  } from "./chunk-LRHOS4ZN.js";
176
146
  import {
147
+ ContextManager,
148
+ DEFAULT_CONTEXT_LIMITS,
149
+ PRUNE_PROTECTED_TOOLS,
150
+ estimateConversationTokens,
151
+ estimateMessageTokens,
152
+ estimateTokens,
153
+ findCutPoint,
154
+ generateSummary,
155
+ isContextOverflowing,
156
+ pruneContext,
157
+ pruneToolResults,
158
+ shouldPruneContext
159
+ } from "./chunk-WWYYNWEW.js";
160
+ import {
161
+ dockerHost,
162
+ localHost
163
+ } from "./chunk-VNQBHPCT.js";
164
+ import {
165
+ DEFAULT_MAX_OUTPUT_TOKENS,
166
+ DEFAULT_RETRY_CONFIG,
167
+ Inference,
168
+ LLM,
169
+ OUTPUT_TOKEN_MAX,
170
+ buildToolSet,
171
+ calculateDelay,
172
+ createRetryHandler,
173
+ createRetryState,
174
+ shouldRetry,
175
+ sleep,
176
+ stream,
177
+ streamOnce,
178
+ streamStep,
179
+ withRetry
180
+ } from "./chunk-N6HWIEEA.js";
181
+ import {
182
+ executeAgentToolCall
183
+ } from "./chunk-7VKQ4WPB.js";
184
+ import {
185
+ extractFilePathsFromArgs,
186
+ shouldCaptureBaseline,
187
+ withFileTracking
188
+ } from "./chunk-VEKUXUVF.js";
189
+ import {
190
+ EXTENDED_LEVELS,
191
+ FIXED_LEVELS,
192
+ STANDARD_LEVELS,
193
+ buildAnthropicOptions,
194
+ buildBedrockOptions,
195
+ buildGoogleOptions,
196
+ buildGroqOptions,
197
+ buildOpenAIOptions,
198
+ buildOpenRouterOptions,
177
199
  buildReasoningOptions,
178
200
  buildReasoningOptionsSync,
201
+ buildXAIOptions,
202
+ getProviderOptionsKey,
179
203
  getReasoningConfig,
180
204
  getReasoningConfigSync,
205
+ shouldIncludeReasoningSummary,
181
206
  supportsReasoning,
182
207
  supportsReasoningSync
183
- } from "./chunk-X635CM2F.js";
208
+ } from "./chunk-SQU2AJHO.js";
209
+ import {
210
+ createScope,
211
+ currentScope,
212
+ restoreScope,
213
+ snapshotScope,
214
+ streamWithinScope,
215
+ withinScope
216
+ } from "./chunk-N7P4PN3O.js";
217
+ import {
218
+ LLMError,
219
+ getErrorCategory,
220
+ getRetryDelay,
221
+ isRetryable,
222
+ isRetryableCategory,
223
+ parseRetryDelay
224
+ } from "./chunk-RZITT45F.js";
225
+ import {
226
+ createMCPManager,
227
+ defineServer,
228
+ httpServer,
229
+ sseServer,
230
+ stdioServer
231
+ } from "./chunk-ZXAKHMWH.js";
232
+ import {
233
+ MiddlewareRunner,
234
+ approvalMiddleware,
235
+ createTelemetryConfig,
236
+ otelMiddleware,
237
+ promptCacheMiddleware
238
+ } from "./chunk-YSLSEQ6B.js";
239
+ import {
240
+ ApprovalDeniedError,
241
+ ApprovalTimeoutError,
242
+ createApprovalHandler,
243
+ getToolRisk
244
+ } from "./chunk-BFM2YHNM.js";
184
245
  import {
246
+ CacheCapabilitySource,
247
+ CapabilityCache,
248
+ DEFAULT_RESOLVER_OPTIONS,
185
249
  ModelCapabilityResolver,
250
+ PatternCapabilitySource,
251
+ RemoteCapabilityFetcher,
252
+ RemoteCapabilitySource,
253
+ SourcePriority,
254
+ applyCapabilityOverride,
186
255
  configureResolver,
256
+ createResolver,
257
+ extractModelId,
258
+ extractProvider,
259
+ findCapabilityOverride,
187
260
  getDefaultResolver,
188
- getNetworkStatus
189
- } from "./chunk-QWFMX226.js";
261
+ getNetworkStatus,
262
+ getProviderCompatibility,
263
+ inferContextWindow,
264
+ inferProvider,
265
+ likelySupportsReasoning
266
+ } from "./chunk-RFEKJKTO.js";
190
267
  import {
191
268
  getModelId,
192
269
  getProviderId
@@ -279,436 +356,179 @@ function accumulateUsage(current, next) {
279
356
 
280
357
  // src/agent/chat-loop/loop.ts
281
358
  async function* runChatLoop(deps) {
282
- const {
283
- sessionId,
284
- message,
285
- abort,
286
- systemOverride,
287
- sessions,
288
- tools: toolRecord,
289
- config,
290
- turnTracker,
291
- interventionCtrl,
292
- middlewareRunner,
293
- contextManager,
294
- rememberedDoomLoopTools,
295
- reasoningLevel,
296
- promptBuilder,
297
- host,
298
- mcpTools,
299
- toModelMessages,
300
- setIsStreaming
301
- } = deps;
302
- const turnEngine = createAgentTurnEngine({
303
- sessionId,
304
- startedAt: (/* @__PURE__ */ new Date()).toISOString(),
305
- getToolReplayPolicy: (toolName) => toolRecord[toolName] ? normalizeToolReplayPolicy(toolRecord[toolName].replayPolicy) : void 0
306
- });
307
- const applyCommitBatch = createChatLoopCommitBatchApplier({
308
- turnEngine,
309
- sessions,
310
- middlewareRunner
311
- });
312
- yield* applyCommitBatch(
313
- turnEngine.createInputCommit({
314
- content: message,
315
- system: systemOverride
316
- }),
317
- { emitMessages: true }
318
- );
319
- setIsStreaming(true);
320
- const prevOnApplied = interventionCtrl.onApplied;
321
- let chatUsage;
322
- let chatError;
323
- let chatOutput;
324
- try {
325
- if (middlewareRunner.hasMiddleware) {
326
- await middlewareRunner.runChatStart(sessionId, message);
327
- }
328
- const systemPrompts = await buildChatSystemPrompts({
329
- promptBuilder,
330
- middlewareRunner,
331
- systemOverride,
332
- sessionId,
333
- config,
334
- tools: toolRecord
335
- });
336
- let step = 1;
337
- let finalStepText = "";
338
- let accumulatedUsage;
339
- while (step <= config.maxSteps) {
340
- const preparedStep = prepareModelStep({
359
+ yield* streamWithinScope(
360
+ {
361
+ kind: "turn",
362
+ name: "agent-turn",
363
+ sessionId: deps.sessionId
364
+ },
365
+ (async function* () {
366
+ const {
341
367
  sessionId,
342
- step,
343
- systemPrompts,
344
- messages: sessions.getMessages(),
345
- toModelMessages,
368
+ message,
346
369
  abort,
370
+ systemOverride,
371
+ sessions,
347
372
  tools: toolRecord,
348
- mcpTools,
349
373
  config,
350
- host,
351
374
  turnTracker,
352
- intervention: interventionCtrl,
353
- middleware: middlewareRunner,
354
- reasoningLevel
355
- });
356
- const stepResult = yield* runModelStep({
357
- preparedStep,
358
- turnEngine,
359
- applyCommitBatch,
360
- rememberedDoomLoopTools
375
+ interventionCtrl,
376
+ middlewareRunner,
377
+ contextManager,
378
+ rememberedDoomLoopTools,
379
+ reasoningLevel,
380
+ promptBuilder,
381
+ host,
382
+ mcpTools,
383
+ toModelMessages,
384
+ setIsStreaming
385
+ } = deps;
386
+ const turnEngine = createAgentTurnEngine({
387
+ sessionId,
388
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
389
+ getToolReplayPolicy: (toolName) => toolRecord[toolName] ? normalizeToolReplayPolicy(toolRecord[toolName].replayPolicy) : void 0
361
390
  });
362
- accumulatedUsage = accumulateUsage(accumulatedUsage, stepResult.usage);
363
- if (stepResult.error) {
364
- chatError = stepResult.error;
365
- return;
366
- }
367
- yield* commitStep({
368
- step,
369
- finishReason: stepResult.finishReason,
391
+ const applyCommitBatch = createChatLoopCommitBatchApplier({
370
392
  turnEngine,
371
- applyCommitBatch
393
+ sessions,
394
+ middlewareRunner
372
395
  });
373
- if (stepResult.finishReason === "tool-calls") {
374
- if (step >= config.maxSteps) {
375
- const maxStepsError = new Error(
376
- `Maximum steps (${config.maxSteps}) reached before the turn produced a final response`
377
- );
378
- chatError = maxStepsError;
379
- const statusEvent = { type: "status", status: "error" };
380
- middlewareRunner.emitEvent(statusEvent);
381
- yield statusEvent;
382
- const errorEvent = { type: "error", error: maxStepsError };
383
- middlewareRunner.emitEvent(errorEvent);
384
- yield errorEvent;
385
- return;
396
+ yield* applyCommitBatch(
397
+ turnEngine.createInputCommit({
398
+ content: message,
399
+ system: systemOverride
400
+ }),
401
+ { emitMessages: true }
402
+ );
403
+ setIsStreaming(true);
404
+ const prevOnApplied = interventionCtrl.onApplied;
405
+ let chatUsage;
406
+ let chatError;
407
+ let chatOutput;
408
+ try {
409
+ if (middlewareRunner.hasMiddleware) {
410
+ await middlewareRunner.runChatStart(sessionId, message);
411
+ }
412
+ const systemPrompts = await buildChatSystemPrompts({
413
+ promptBuilder,
414
+ middlewareRunner,
415
+ systemOverride,
416
+ sessionId,
417
+ config,
418
+ tools: toolRecord
419
+ });
420
+ let step = 1;
421
+ let finalStepText = "";
422
+ let accumulatedUsage;
423
+ while (step <= config.maxSteps) {
424
+ const preparedStep = prepareModelStep({
425
+ sessionId,
426
+ step,
427
+ systemPrompts,
428
+ messages: sessions.getMessages(),
429
+ toModelMessages,
430
+ abort,
431
+ tools: toolRecord,
432
+ mcpTools,
433
+ config,
434
+ host,
435
+ turnTracker,
436
+ intervention: interventionCtrl,
437
+ middleware: middlewareRunner,
438
+ reasoningLevel
439
+ });
440
+ const stepResult = yield* runModelStep({
441
+ preparedStep,
442
+ turnEngine,
443
+ applyCommitBatch,
444
+ rememberedDoomLoopTools
445
+ });
446
+ accumulatedUsage = accumulateUsage(accumulatedUsage, stepResult.usage);
447
+ if (stepResult.error) {
448
+ chatError = stepResult.error;
449
+ return;
450
+ }
451
+ yield* commitStep({
452
+ step,
453
+ finishReason: stepResult.finishReason,
454
+ turnEngine,
455
+ applyCommitBatch
456
+ });
457
+ if (stepResult.finishReason === "tool-calls") {
458
+ if (step >= config.maxSteps) {
459
+ const maxStepsError = new Error(
460
+ `Maximum steps (${config.maxSteps}) reached before the turn produced a final response`
461
+ );
462
+ chatError = maxStepsError;
463
+ const statusEvent = { type: "status", status: "error" };
464
+ middlewareRunner.emitEvent(statusEvent);
465
+ yield statusEvent;
466
+ const errorEvent = { type: "error", error: maxStepsError };
467
+ middlewareRunner.emitEvent(errorEvent);
468
+ yield errorEvent;
469
+ return;
470
+ }
471
+ step += 1;
472
+ continue;
473
+ }
474
+ finalStepText = stepResult.text;
475
+ break;
476
+ }
477
+ yield* commitOutput({
478
+ text: finalStepText,
479
+ usage: accumulatedUsage,
480
+ turnEngine,
481
+ applyCommitBatch
482
+ });
483
+ if (config.compaction?.auto !== false) {
484
+ const compactionEvents = await runAutoCompaction({
485
+ contextManager,
486
+ messages: sessions.getMessages()
487
+ });
488
+ for (const event of compactionEvents) {
489
+ yield event;
490
+ }
491
+ }
492
+ const turnSummary = await turnTracker.endTurn();
493
+ if (turnSummary.totalTracked > 0) {
494
+ yield {
495
+ type: "turn-summary",
496
+ turnId: turnSummary.turnId,
497
+ files: turnSummary.files.map((file) => ({
498
+ path: file.path,
499
+ type: file.type,
500
+ additions: file.additions,
501
+ deletions: file.deletions
502
+ })),
503
+ additions: turnSummary.additions,
504
+ deletions: turnSummary.deletions
505
+ };
506
+ }
507
+ chatUsage = accumulatedUsage;
508
+ chatOutput = finalStepText || void 0;
509
+ yield {
510
+ type: "complete",
511
+ usage: accumulatedUsage,
512
+ output: finalStepText || void 0
513
+ };
514
+ } catch (error) {
515
+ chatError = error instanceof Error ? error : new Error(String(error));
516
+ throw error;
517
+ } finally {
518
+ setIsStreaming(false);
519
+ interventionCtrl.onApplied = prevOnApplied;
520
+ if (middlewareRunner.hasMiddleware) {
521
+ await middlewareRunner.runChatEnd(sessionId, {
522
+ usage: chatUsage,
523
+ error: chatError,
524
+ output: chatOutput
525
+ });
386
526
  }
387
- step += 1;
388
- continue;
389
- }
390
- finalStepText = stepResult.text;
391
- break;
392
- }
393
- yield* commitOutput({
394
- text: finalStepText,
395
- usage: accumulatedUsage,
396
- turnEngine,
397
- applyCommitBatch
398
- });
399
- if (config.compaction?.auto !== false) {
400
- const compactionEvents = await runAutoCompaction({
401
- contextManager,
402
- messages: sessions.getMessages()
403
- });
404
- for (const event of compactionEvents) {
405
- yield event;
406
527
  }
407
- }
408
- const turnSummary = await turnTracker.endTurn();
409
- if (turnSummary.totalTracked > 0) {
410
- yield {
411
- type: "turn-summary",
412
- turnId: turnSummary.turnId,
413
- files: turnSummary.files.map((file) => ({
414
- path: file.path,
415
- type: file.type,
416
- additions: file.additions,
417
- deletions: file.deletions
418
- })),
419
- additions: turnSummary.additions,
420
- deletions: turnSummary.deletions
421
- };
422
- }
423
- chatUsage = accumulatedUsage;
424
- chatOutput = finalStepText || void 0;
425
- yield {
426
- type: "complete",
427
- usage: accumulatedUsage,
428
- output: finalStepText || void 0
429
- };
430
- } catch (error) {
431
- chatError = error instanceof Error ? error : new Error(String(error));
432
- throw error;
433
- } finally {
434
- setIsStreaming(false);
435
- interventionCtrl.onApplied = prevOnApplied;
436
- if (middlewareRunner.hasMiddleware) {
437
- await middlewareRunner.runChatEnd(sessionId, {
438
- usage: chatUsage,
439
- error: chatError,
440
- output: chatOutput
441
- });
442
- }
443
- }
444
- }
445
-
446
- // src/presets/patterns.ts
447
- function globToRegex(pattern) {
448
- const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
449
- return new RegExp(`^${escaped}$`, "i");
450
- }
451
- function matchesPatterns(id, patterns) {
452
- return patterns.some((pattern) => globToRegex(pattern).test(id));
453
- }
454
- function filterTools(tools, options) {
455
- const allowPatterns = options.allow ?? [];
456
- const denyPatterns = options.deny ?? [];
457
- return tools.filter((tool) => {
458
- const matchesAllow = allowPatterns.length === 0 || matchesPatterns(tool.id, allowPatterns);
459
- if (!matchesAllow) {
460
- return false;
461
- }
462
- const matchesDeny = denyPatterns.length > 0 && matchesPatterns(tool.id, denyPatterns);
463
- if (matchesDeny && allowPatterns.length === 0) {
464
- return false;
465
- }
466
- return true;
467
- });
468
- }
469
-
470
- // src/presets/apply.ts
471
- function applyPreset(preset, availableTools, baseSystemPrompt) {
472
- const tools = filterTools(availableTools, {
473
- allow: preset.allowTools,
474
- deny: preset.denyTools
475
- });
476
- let systemPrompt = preset.systemPrompt;
477
- if (systemPrompt && baseSystemPrompt) {
478
- systemPrompt = systemPrompt.replace("{basePrompt}", baseSystemPrompt);
479
- }
480
- return {
481
- name: preset.name,
482
- systemPrompt,
483
- tools: tools.length > 0 ? tools : void 0,
484
- temperature: preset.temperature,
485
- maxSteps: preset.maxSteps,
486
- reasoningLevel: preset.reasoningLevel,
487
- model: preset.model
488
- };
489
- }
490
- function mergePresets(...presets) {
491
- if (presets.length === 0) {
492
- throw new Error("mergePresets requires at least one preset");
493
- }
494
- if (presets.length === 1) {
495
- return presets[0];
496
- }
497
- const [first, ...rest] = presets;
498
- const allAllow = [];
499
- const allDeny = [];
500
- for (const preset of presets) {
501
- if (preset.allowTools?.length) {
502
- allAllow.push(preset.allowTools);
503
- }
504
- if (preset.denyTools?.length) {
505
- allDeny.push(...preset.denyTools);
506
- }
507
- }
508
- const combinedAllow = allAllow.length > 0 ? allAllow.reduce(
509
- (left, right) => left.length <= right.length ? left : right
510
- ) : void 0;
511
- return {
512
- name: presets.map((preset) => preset.name).join("+"),
513
- description: presets.map((preset) => preset.description).join(" | "),
514
- allowTools: combinedAllow,
515
- denyTools: allDeny.length > 0 ? [...new Set(allDeny)] : void 0,
516
- systemPrompt: rest.reduce(
517
- (value, preset) => preset.systemPrompt ?? value,
518
- first.systemPrompt
519
- ),
520
- temperature: rest.reduce(
521
- (value, preset) => preset.temperature ?? value,
522
- first.temperature
523
- ),
524
- maxSteps: rest.reduce(
525
- (value, preset) => preset.maxSteps ?? value,
526
- first.maxSteps
527
- ),
528
- reasoningLevel: rest.reduce(
529
- (value, preset) => preset.reasoningLevel ?? value,
530
- first.reasoningLevel
531
- ),
532
- model: rest.reduce((value, preset) => preset.model ?? value, first.model)
533
- };
534
- }
535
- function createPreset(options) {
536
- return {
537
- description: options.description ?? `Custom preset: ${options.name}`,
538
- ...options
539
- };
528
+ })()
529
+ );
540
530
  }
541
531
 
542
- // src/presets/builtins.ts
543
- var explore = {
544
- name: "explore",
545
- description: "Read-only exploration mode for understanding content",
546
- allowTools: ["read*", "search*", "glob*", "grep*", "list*", "find*"],
547
- denyTools: ["write*", "edit*", "delete*", "bash*", "exec*", "run*"],
548
- systemPrompt: `{basePrompt}
549
-
550
- ## EXPLORATION MODE
551
-
552
- You are in **exploration mode**. Your goal is to thoroughly understand the content.
553
-
554
- Guidelines:
555
- - **Always start with glob or grep to discover correct paths** \u2014 never assume directory structure
556
- - Use search and read tools extensively to build understanding
557
- - Map out structures, dependencies, and patterns
558
- - Look for conventions, common patterns, and documentation
559
- - DO NOT modify anything \u2014 only read and analyse
560
- - Summarise findings clearly with references to specific locations
561
-
562
- Error recovery:
563
- - If a tool returns an error (ENOENT, not found, etc.), try a different path or approach
564
- - Use glob with broader patterns to discover the correct location
565
- - Keep going until you have a thorough answer \u2014 do not give up after one failure
566
- - You have multiple steps available \u2014 use them all if needed`,
567
- temperature: 0.3,
568
- maxSteps: 30
569
- };
570
- var plan = {
571
- name: "plan",
572
- description: "Planning mode for analyzing tasks and creating detailed plans",
573
- allowTools: ["read*", "search*", "glob*", "grep*", "list*", "find*"],
574
- denyTools: ["write*", "edit*", "delete*", "bash*", "exec*", "run*"],
575
- systemPrompt: `{basePrompt}
576
-
577
- ## PLANNING MODE
578
-
579
- You are in **planning mode**. Your goal is to analyze and plan before implementation.
580
-
581
- Guidelines:
582
- - Analyse the task requirements thoroughly
583
- - Research existing patterns and conventions
584
- - Identify potential impacts and dependencies
585
- - Create a clear, step-by-step implementation plan
586
- - DO NOT implement anything \u2014 only plan and document
587
- - Output a numbered list of specific, actionable steps`,
588
- temperature: 0.2,
589
- maxSteps: 20
590
- };
591
- var review = {
592
- name: "review",
593
- description: "Thorough review and analysis mode",
594
- allowTools: ["read*", "grep*", "search*", "glob*", "list*"],
595
- denyTools: ["*"],
596
- systemPrompt: `{basePrompt}
597
-
598
- ## REVIEW MODE
599
-
600
- You are in **review mode**. Your goal is to perform a thorough analysis.
601
-
602
- Review checklist:
603
- - [ ] Logic errors and edge cases
604
- - [ ] Security vulnerabilities
605
- - [ ] Performance issues
606
- - [ ] Error handling and recovery
607
- - [ ] Clarity and maintainability
608
- - [ ] Coverage gaps
609
-
610
- Guidelines:
611
- - Be thorough and systematic
612
- - Cite specific locations and details
613
- - Explain WHY something is an issue
614
- - Suggest concrete fixes
615
- - Rate severity: Critical / High / Medium / Low`,
616
- temperature: 0.1,
617
- maxSteps: 25
618
- };
619
- var quick = {
620
- name: "quick",
621
- description: "Fast mode for simple questions and quick operations",
622
- systemPrompt: `{basePrompt}
623
-
624
- ## QUICK MODE
625
-
626
- You are in **quick mode**. Be fast and focused.
627
-
628
- Guidelines:
629
- - Answer directly without lengthy explanations
630
- - Use minimal tool calls (1-3 max)
631
- - If you can't answer quickly, say so
632
- - Prioritize speed over thoroughness`,
633
- temperature: 0,
634
- maxSteps: 5
635
- };
636
- var careful = {
637
- name: "careful",
638
- description: "Extra cautious mode for sensitive operations",
639
- denyTools: ["bash*", "exec*", "run*", "delete*", "remove*"],
640
- systemPrompt: `{basePrompt}
641
-
642
- ## CAREFUL MODE
643
-
644
- You are in **careful mode**. Every action must be verified.
645
-
646
- Guidelines:
647
- - Double-check before any file modifications
648
- - Explain what you're about to do BEFORE doing it
649
- - Prefer smaller, incremental changes
650
- - Always verify changes after making them
651
- - If uncertain, ask for clarification rather than guessing`,
652
- temperature: 0,
653
- maxSteps: 50
654
- };
655
- var code = {
656
- name: "code",
657
- description: "Full-power implementation mode for writing and modifying code",
658
- systemPrompt: `{basePrompt}
659
-
660
- ## IMPLEMENTATION MODE
661
-
662
- You are a focused **implementation agent**. Your goal is to complete the assigned task fully and correctly.
663
-
664
- Guidelines:
665
- - Read existing code first to understand context and conventions before making changes
666
- - Follow the project's existing patterns, naming conventions, and style
667
- - Make minimal, targeted changes \u2014 do not refactor unrelated code
668
- - Verify your work: re-read modified files, run tests or lint if available
669
- - If the task requires multiple files, handle them systematically one at a time
670
-
671
- Error recovery:
672
- - If a command fails, read the error output carefully and fix the root cause
673
- - If a test fails, read the failure details and iterate until it passes
674
- - If you cannot find a file, use glob or grep to discover the correct path
675
- - Keep iterating until the task is DONE \u2014 do not stop at a partial solution
676
- - You have many steps available \u2014 use them all if needed`,
677
- temperature: 0,
678
- maxSteps: 50
679
- };
680
- var watch = {
681
- name: "watch",
682
- description: "Process monitoring mode for running and watching long commands",
683
- allowTools: ["bash*", "exec*", "run*", "read*", "grep*", "glob*", "list*", "find*"],
684
- denyTools: ["write*", "edit*", "delete*", "remove*"],
685
- systemPrompt: `{basePrompt}
686
-
687
- ## WATCH MODE
688
-
689
- You are a **process monitor**. Your goal is to execute a command, observe its output, and report the result.
690
-
691
- Guidelines:
692
- - Run the command as given \u2014 do not modify or "improve" it
693
- - Wait for completion and capture the full output
694
- - Parse the output for success/failure status, error counts, warnings
695
- - Report a clear summary: what ran, whether it passed, key details
696
- - If the process fails, include the relevant error output verbatim
697
- - Do NOT attempt to fix issues \u2014 only observe and report`,
698
- temperature: 0,
699
- maxSteps: 10,
700
- reasoningLevel: "low"
701
- };
702
- var Presets = {
703
- explore,
704
- plan,
705
- review,
706
- quick,
707
- careful,
708
- code,
709
- watch
710
- };
711
-
712
532
  // src/agent/fork.ts
713
533
  function resolveForkOptions(options, parentTools, systemPrompt) {
714
534
  if (!options.preset) {
@@ -787,7 +607,7 @@ function createForkedAgentConfig(options) {
787
607
  };
788
608
  }
789
609
 
790
- // src/agent/mcp.ts
610
+ // src/agent/mcp-bridge.ts
791
611
  async function ensureMcpTools(state) {
792
612
  if (!state.manager) {
793
613
  return { connected: false, cachedTools: void 0 };
@@ -878,7 +698,7 @@ async function createSubAgentRunSession(options) {
878
698
  return sessionId;
879
699
  }
880
700
 
881
- // src/intervention/controller.ts
701
+ // src/agent/intervention.ts
882
702
  var InterventionController = class {
883
703
  /** Immediate interventions — applied at the next step boundary */
884
704
  immediate = [];
@@ -982,417 +802,14 @@ var InterventionController = class {
982
802
  }
983
803
  };
984
804
 
985
- // src/host/local.ts
986
- import { spawn } from "child_process";
987
- import fs from "fs/promises";
988
- import { existsSync } from "fs";
989
- import path from "path";
990
- import process2 from "process";
991
- function getShell() {
992
- if (process2.platform === "win32") {
993
- return { shell: "cmd.exe", args: ["/c"] };
994
- }
995
- const userShell = process2.env.SHELL ?? "/bin/bash";
996
- return { shell: userShell, args: ["-c"] };
997
- }
998
- async function killProcessTree(pid) {
999
- try {
1000
- if (process2.platform !== "win32") {
1001
- process2.kill(-pid, "SIGKILL");
1002
- } else {
1003
- const { exec: execCb } = await import("child_process");
1004
- execCb(`taskkill /pid ${pid} /t /f`, () => {
1005
- });
1006
- }
1007
- } catch {
1008
- try {
1009
- process2.kill(pid, "SIGKILL");
1010
- } catch {
1011
- }
1012
- }
1013
- }
1014
- function localHost(defaultCwd) {
1015
- const cwd = defaultCwd ?? process2.cwd();
1016
- return {
1017
- name: "local",
1018
- // --------------------------------------------------------------------------
1019
- // File system
1020
- // --------------------------------------------------------------------------
1021
- async readFile(filePath) {
1022
- const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
1023
- return fs.readFile(abs, "utf-8");
1024
- },
1025
- async readBytes(filePath, offset, length) {
1026
- const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
1027
- const fh = await fs.open(abs, "r");
1028
- try {
1029
- const buf = Buffer.alloc(length);
1030
- await fh.read(buf, 0, length, offset);
1031
- return buf;
1032
- } finally {
1033
- await fh.close();
1034
- }
1035
- },
1036
- async writeFile(filePath, content) {
1037
- const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
1038
- await fs.mkdir(path.dirname(abs), { recursive: true });
1039
- await fs.writeFile(abs, content, "utf-8");
1040
- },
1041
- async exists(filePath) {
1042
- const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
1043
- return existsSync(abs);
1044
- },
1045
- async stat(filePath) {
1046
- const abs = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
1047
- const s = await fs.stat(abs);
1048
- return {
1049
- size: s.size,
1050
- mtime: s.mtime,
1051
- isDirectory: s.isDirectory(),
1052
- isFile: s.isFile()
1053
- };
1054
- },
1055
- async readdir(dirPath) {
1056
- const abs = path.isAbsolute(dirPath) ? dirPath : path.resolve(cwd, dirPath);
1057
- const entries = await fs.readdir(abs, { withFileTypes: true });
1058
- return entries.map((e) => ({
1059
- name: e.name,
1060
- isDirectory: e.isDirectory(),
1061
- isFile: e.isFile()
1062
- }));
1063
- },
1064
- async mkdir(dirPath) {
1065
- const abs = path.isAbsolute(dirPath) ? dirPath : path.resolve(cwd, dirPath);
1066
- await fs.mkdir(abs, { recursive: true });
1067
- },
1068
- // --------------------------------------------------------------------------
1069
- // Process execution
1070
- // --------------------------------------------------------------------------
1071
- exec(command, options) {
1072
- const { shell, args } = getShell();
1073
- const execCwd = options?.cwd ?? cwd;
1074
- const env = {
1075
- ...process2.env,
1076
- ...options?.env,
1077
- // Disable pagers — tools collect output, not interactive
1078
- PAGER: "cat",
1079
- GIT_PAGER: "cat"
1080
- };
1081
- return new Promise((resolve, reject) => {
1082
- let stdout = "";
1083
- let stderr = "";
1084
- let timedOut = false;
1085
- let settled = false;
1086
- const child = spawn(shell, [...args, command], {
1087
- cwd: execCwd,
1088
- detached: process2.platform !== "win32",
1089
- env,
1090
- stdio: ["ignore", "pipe", "pipe"]
1091
- });
1092
- child.stdout?.on("data", (data) => {
1093
- stdout += data.toString();
1094
- options?.onStdout?.(data);
1095
- });
1096
- child.stderr?.on("data", (data) => {
1097
- stderr += data.toString();
1098
- options?.onStderr?.(data);
1099
- });
1100
- let timer;
1101
- if (options?.timeout && options.timeout > 0) {
1102
- timer = setTimeout(() => {
1103
- timedOut = true;
1104
- if (child.pid) killProcessTree(child.pid);
1105
- }, options.timeout);
1106
- }
1107
- const onAbort = () => {
1108
- if (child.pid) killProcessTree(child.pid);
1109
- };
1110
- options?.signal?.addEventListener("abort", onAbort, { once: true });
1111
- child.on("close", (code2) => {
1112
- if (settled) return;
1113
- settled = true;
1114
- if (timer) clearTimeout(timer);
1115
- options?.signal?.removeEventListener("abort", onAbort);
1116
- resolve({ stdout, stderr, exitCode: code2, timedOut });
1117
- });
1118
- child.on("error", (err) => {
1119
- if (settled) return;
1120
- settled = true;
1121
- if (timer) clearTimeout(timer);
1122
- options?.signal?.removeEventListener("abort", onAbort);
1123
- reject(err);
1124
- });
1125
- });
1126
- }
1127
- };
1128
- }
1129
-
1130
- // src/host/docker/exec.ts
1131
- async function loadDockerode() {
1132
- try {
1133
- const module = await import("dockerode");
1134
- return module.default ?? module;
1135
- } catch {
1136
- throw new Error(
1137
- "dockerHost requires the 'dockerode' package. Install it with: npm install dockerode"
1138
- );
1139
- }
1140
- }
1141
- async function resolveDockerRuntime(options) {
1142
- const Dockerode = await loadDockerode();
1143
- if (typeof options.container === "string") {
1144
- const docker = new Dockerode(options.dockerOptions);
1145
- const container2 = docker.getContainer(options.container);
1146
- return {
1147
- docker,
1148
- container: container2,
1149
- label: options.container
1150
- };
1151
- }
1152
- const container = options.container;
1153
- return {
1154
- docker: { modem: container.modem },
1155
- container,
1156
- label: container.id?.slice(0, 12) ?? "unknown"
1157
- };
1158
- }
1159
- async function containerExec(runtime, command, options = {}) {
1160
- const envEntries = options.env ? Object.entries(options.env).filter((entry) => entry[1] !== void 0).map(([key, value]) => `${key}=${value}`) : void 0;
1161
- const exec = await runtime.container.exec({
1162
- Cmd: ["sh", "-c", command],
1163
- ...options.user ? { User: options.user } : {},
1164
- ...options.workdir ? { WorkingDir: options.workdir } : {},
1165
- ...envEntries && envEntries.length > 0 ? { Env: envEntries } : {},
1166
- AttachStdout: true,
1167
- AttachStderr: true
1168
- });
1169
- const stream = await exec.start({});
1170
- let timedOut = false;
1171
- let aborted = false;
1172
- return await new Promise((resolve, reject) => {
1173
- const stdoutChunks = [];
1174
- const stderrChunks = [];
1175
- runtime.docker.modem.demuxStream(
1176
- stream,
1177
- {
1178
- write: (chunk) => {
1179
- stdoutChunks.push(chunk);
1180
- options.onStdout?.(chunk);
1181
- return true;
1182
- },
1183
- end: function() {
1184
- return this;
1185
- }
1186
- },
1187
- {
1188
- write: (chunk) => {
1189
- stderrChunks.push(chunk);
1190
- options.onStderr?.(chunk);
1191
- return true;
1192
- },
1193
- end: function() {
1194
- return this;
1195
- }
1196
- }
1197
- );
1198
- let timer;
1199
- if (options.timeout && options.timeout > 0) {
1200
- timer = setTimeout(() => {
1201
- timedOut = true;
1202
- stream.destroy?.();
1203
- }, options.timeout);
1204
- }
1205
- const onAbort = () => {
1206
- aborted = true;
1207
- stream.destroy?.();
1208
- };
1209
- options.signal?.addEventListener("abort", onAbort, { once: true });
1210
- stream.on("end", async () => {
1211
- if (timer) {
1212
- clearTimeout(timer);
1213
- }
1214
- options.signal?.removeEventListener("abort", onAbort);
1215
- try {
1216
- const info = await exec.inspect();
1217
- resolve({
1218
- stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
1219
- stderr: Buffer.concat(stderrChunks).toString("utf-8"),
1220
- exitCode: timedOut || aborted ? null : info.ExitCode ?? 0,
1221
- timedOut
1222
- });
1223
- } catch (error) {
1224
- reject(error);
1225
- }
1226
- });
1227
- stream.on("error", (error) => {
1228
- if (timer) {
1229
- clearTimeout(timer);
1230
- }
1231
- options.signal?.removeEventListener("abort", onAbort);
1232
- if (timedOut || aborted) {
1233
- resolve({
1234
- stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
1235
- stderr: Buffer.concat(stderrChunks).toString("utf-8"),
1236
- exitCode: null,
1237
- timedOut
1238
- });
1239
- return;
1240
- }
1241
- reject(error);
1242
- });
1243
- });
1244
- }
1245
- async function runDockerCommand(options) {
1246
- const { runtime, command, defaultUser, defaultWorkdir, execOptions } = options;
1247
- return await containerExec(runtime, command, {
1248
- user: defaultUser,
1249
- workdir: execOptions?.workdir ?? execOptions?.cwd ?? defaultWorkdir,
1250
- env: execOptions?.env,
1251
- timeout: execOptions?.timeout,
1252
- signal: execOptions?.signal,
1253
- onStdout: execOptions?.onStdout,
1254
- onStderr: execOptions?.onStderr
1255
- });
1256
- }
1257
-
1258
- // src/host/docker/shell.ts
1259
- function sq(value) {
1260
- return `'${value.replace(/'/g, `'\\''`)}'`;
1261
- }
1262
- function resolveDockerPath(path2, defaultWorkdir) {
1263
- if (path2.startsWith("/")) {
1264
- return path2;
1265
- }
1266
- const base = defaultWorkdir.endsWith("/") ? defaultWorkdir : `${defaultWorkdir}/`;
1267
- return `${base}${path2}`;
1268
- }
1269
-
1270
- // src/host/docker/host.ts
1271
- async function dockerHost(options) {
1272
- const runtime = await resolveDockerRuntime(options);
1273
- const defaultUser = options.user;
1274
- const defaultWorkdir = options.workdir ?? "/";
1275
- async function run(command, execOptions) {
1276
- return await runDockerCommand({
1277
- runtime,
1278
- command,
1279
- defaultUser,
1280
- defaultWorkdir,
1281
- execOptions
1282
- });
1283
- }
1284
- return {
1285
- name: `docker:${runtime.label}`,
1286
- async readFile(filePath) {
1287
- const absPath = resolveDockerPath(filePath, defaultWorkdir);
1288
- const result = await run(`cat ${sq(absPath)}`);
1289
- if (result.exitCode !== 0) {
1290
- throw new Error(`readFile failed (${absPath}): ${result.stderr.trim()}`);
1291
- }
1292
- return result.stdout;
1293
- },
1294
- async readBytes(filePath, offset, length) {
1295
- const absPath = resolveDockerPath(filePath, defaultWorkdir);
1296
- const result = await run(
1297
- `dd if=${sq(absPath)} bs=1 skip=${offset} count=${length} 2>/dev/null`
1298
- );
1299
- if (result.exitCode !== 0) {
1300
- throw new Error(
1301
- `readBytes failed (${absPath}): ${result.stderr.trim()}`
1302
- );
1303
- }
1304
- return Buffer.from(result.stdout, "binary");
1305
- },
1306
- async writeFile(filePath, content) {
1307
- const absPath = resolveDockerPath(filePath, defaultWorkdir);
1308
- const dir = absPath.substring(0, absPath.lastIndexOf("/")) || "/";
1309
- await run(`mkdir -p ${sq(dir)}`);
1310
- const encoded = Buffer.from(content, "utf-8").toString("base64");
1311
- const result = await run(`echo ${sq(encoded)} | base64 -d > ${sq(absPath)}`);
1312
- if (result.exitCode !== 0) {
1313
- throw new Error(
1314
- `writeFile failed (${absPath}): ${result.stderr.trim()}`
1315
- );
1316
- }
1317
- },
1318
- async exists(filePath) {
1319
- const absPath = resolveDockerPath(filePath, defaultWorkdir);
1320
- const result = await run(`test -e ${sq(absPath)}`);
1321
- return result.exitCode === 0;
1322
- },
1323
- async stat(filePath) {
1324
- const absPath = resolveDockerPath(filePath, defaultWorkdir);
1325
- const result = await run(
1326
- `stat -c '%s %Y %F' ${sq(absPath)} 2>/dev/null || stat -f '%z %m %HT' ${sq(absPath)}`
1327
- );
1328
- if (result.exitCode !== 0) {
1329
- throw new Error(`stat failed (${absPath}): ${result.stderr.trim()}`);
1330
- }
1331
- const parts = result.stdout.trim().split(/\s+/);
1332
- if (parts.length < 3) {
1333
- throw new Error(
1334
- `stat: unexpected output format for ${absPath}: ${result.stdout}`
1335
- );
1336
- }
1337
- const size = parseInt(parts[0], 10);
1338
- const mtimeSec = parseInt(parts[1], 10);
1339
- const typeStr = parts.slice(2).join(" ").toLowerCase();
1340
- return {
1341
- size,
1342
- mtime: new Date(mtimeSec * 1e3),
1343
- isDirectory: typeStr.includes("directory"),
1344
- isFile: typeStr.includes("regular") || typeStr.includes("file")
1345
- };
1346
- },
1347
- async readdir(dirPath) {
1348
- const absPath = resolveDockerPath(dirPath, defaultWorkdir);
1349
- const result = await run(
1350
- `find ${sq(absPath)} -maxdepth 1 -mindepth 1 -printf '%f\\t%y\\n' 2>/dev/null || for f in ${sq(absPath)}/*; do [ -e "$f" ] || continue; n=$(basename "$f"); if [ -d "$f" ]; then printf '%s\\td\\n' "$n"; else printf '%s\\tf\\n' "$n"; fi; done`
1351
- );
1352
- if (result.exitCode !== 0) {
1353
- throw new Error(
1354
- `readdir failed (${absPath}): ${result.stderr.trim()}`
1355
- );
1356
- }
1357
- return result.stdout.trim().split("\n").filter(Boolean).map((line) => {
1358
- const [name, type] = line.split(" ");
1359
- return {
1360
- name,
1361
- isDirectory: type === "d",
1362
- isFile: type === "f"
1363
- };
1364
- });
1365
- },
1366
- async mkdir(dirPath) {
1367
- const absPath = resolveDockerPath(dirPath, defaultWorkdir);
1368
- const result = await run(`mkdir -p ${sq(absPath)}`);
1369
- if (result.exitCode !== 0) {
1370
- throw new Error(`mkdir failed (${absPath}): ${result.stderr.trim()}`);
1371
- }
1372
- },
1373
- async exec(command, execOptions) {
1374
- return await run(command, execOptions);
1375
- }
1376
- };
1377
- }
1378
-
1379
- // src/agent/model-detection.ts
805
+ // src/agent/stream-provider.ts
1380
806
  var DEFAULT_CUSTOM_STREAM_MODELS = [
1381
807
  "computer-use-preview",
1382
808
  "computer-use-preview-2025-03-11"
1383
809
  ];
1384
- function getModelId2(model) {
1385
- if (typeof model === "string") {
1386
- return model;
1387
- }
1388
- if (typeof model === "object" && model !== null && "modelId" in model) {
1389
- return String(model.modelId);
1390
- }
1391
- return void 0;
1392
- }
1393
810
  function needsCustomStreamProvider(model, customPatterns) {
1394
- const modelId = getModelId2(model);
1395
- if (!modelId) return false;
811
+ const modelId = getModelId(model);
812
+ if (!modelId || modelId === "[object Object]") return false;
1396
813
  const patterns = customPatterns ?? DEFAULT_CUSTOM_STREAM_MODELS;
1397
814
  return patterns.some((pattern) => modelId.includes(pattern));
1398
815
  }
@@ -1407,7 +824,7 @@ function autoDetectStreamProvider(model, tools, explicitProvider) {
1407
824
  const enhancedTools = tools;
1408
825
  const customPatterns = enhancedTools.__customStreamModels;
1409
826
  if (needsCustomStreamProvider(model, customPatterns) && hasStreamProviderFactory(enhancedTools)) {
1410
- const modelId = getModelId2(model);
827
+ const modelId = getModelId(model);
1411
828
  if (modelId) {
1412
829
  const streamConfig = {
1413
830
  apiKey: process.env.OPENAI_API_KEY,
@@ -1452,10 +869,11 @@ function createEffectiveAgentConfig(config) {
1452
869
  return {
1453
870
  systemPrompt: DEFAULT_SYSTEM_PROMPT,
1454
871
  cwd: process.cwd(),
1455
- maxOutputTokens: DEFAULT_MAX_TOKENS,
1456
- maxSteps: DEFAULT_MAX_STEPS,
1457
872
  reasoningLevel: "off",
1458
873
  ...config,
874
+ // Re-apply defaults after spread so explicit `undefined` from callers doesn't win.
875
+ maxSteps: config.maxSteps ?? DEFAULT_MAX_STEPS,
876
+ maxOutputTokens: config.maxOutputTokens ?? DEFAULT_MAX_TOKENS,
1459
877
  streamProvider: effectiveStreamProvider
1460
878
  };
1461
879
  }
@@ -1482,10 +900,17 @@ function createAgentState(config) {
1482
900
  }
1483
901
  function createAgentContextManager(config) {
1484
902
  const compactionConfig = config.compaction ?? {};
903
+ const modelId = getModelId(config.model);
904
+ const inferredWindow = inferContextWindow(modelId);
905
+ const contextWindow = config.contextWindow ?? inferredWindow ?? DEFAULT_CONTEXT_LIMITS.contextWindow;
906
+ const reserveTokens = Math.min(
907
+ 32e3,
908
+ Math.max(8e3, Math.round(contextWindow * 0.12))
909
+ );
1485
910
  return new ContextManager({
1486
911
  limits: {
1487
- contextWindow: config.contextWindow ?? DEFAULT_CONTEXT_LIMITS.contextWindow,
1488
- reserveTokens: DEFAULT_CONTEXT_LIMITS.reserveTokens,
912
+ contextWindow,
913
+ reserveTokens,
1489
914
  protectedTokens: compactionConfig.protectedTokens ?? DEFAULT_CONTEXT_LIMITS.protectedTokens,
1490
915
  pruneMinimum: compactionConfig.pruneMinimum ?? DEFAULT_CONTEXT_LIMITS.pruneMinimum
1491
916
  },
@@ -1631,6 +1056,8 @@ var Agent = class _Agent {
1631
1056
  mcpManager;
1632
1057
  /** Whether MCP has been connected (lazy init) */
1633
1058
  mcpConnected = false;
1059
+ /** Whether skill tools have been resolved (lazy init) */
1060
+ skillToolsResolved = false;
1634
1061
  /** Cached MCP tools (refreshed on connect) */
1635
1062
  mcpToolsCache;
1636
1063
  /** Prompt pipeline builder (when using layered prompt mode) */
@@ -1645,6 +1072,8 @@ var Agent = class _Agent {
1645
1072
  telemetrySettings;
1646
1073
  /** Tracing shutdown function (from `tracing` config auto-setup) */
1647
1074
  tracingShutdown;
1075
+ /** Multi-consumer event dispatch */
1076
+ _signal;
1648
1077
  constructor(config) {
1649
1078
  const setup = createAgentSetup(config);
1650
1079
  this.config = setup.config;
@@ -1660,6 +1089,17 @@ var Agent = class _Agent {
1660
1089
  this.middlewareRunner = setup.middlewareRunner;
1661
1090
  this.telemetrySettings = setup.telemetrySettings;
1662
1091
  this.tracingShutdown = setup.tracingShutdown;
1092
+ this._signal = config.signal ?? new LocalSignal();
1093
+ }
1094
+ /**
1095
+ * Event signal — subscribe to events without consuming the generator.
1096
+ *
1097
+ * Every event yielded by `chat()` is also dispatched here, allowing
1098
+ * multiple passive observers (SSE routes, TUI, plugins) to listen
1099
+ * concurrently.
1100
+ */
1101
+ get signal() {
1102
+ return this._signal;
1663
1103
  }
1664
1104
  /** Agent name (identity for spans, Dapr workflows, etc.) */
1665
1105
  get name() {
@@ -1706,6 +1146,22 @@ var Agent = class _Agent {
1706
1146
  supportsReasoning() {
1707
1147
  return supportsReasoningSync(this.state.model);
1708
1148
  }
1149
+ /**
1150
+ * Ensure skill tools are registered when `prompt.skills` is configured.
1151
+ * Lazy initialization — resolves the registry and adds tools on first use.
1152
+ */
1153
+ async ensureSkillTools() {
1154
+ if (this.skillToolsResolved || !this.promptBuilder) return;
1155
+ this.skillToolsResolved = true;
1156
+ const registry = await this.promptBuilder.getSkillRegistry(this.config.cwd);
1157
+ if (registry.size > 0) {
1158
+ for (const tool of createSkillTools(registry)) {
1159
+ if (!this.tools.has(tool.id)) {
1160
+ this.tools.set(tool.id, tool);
1161
+ }
1162
+ }
1163
+ }
1164
+ }
1709
1165
  /**
1710
1166
  * Ensure MCP is connected and return tools
1711
1167
  * Lazy initialization - only connects on first use
@@ -1757,12 +1213,13 @@ var Agent = class _Agent {
1757
1213
  */
1758
1214
  async *chat(sessionId, message, options) {
1759
1215
  await this.ensureSession(sessionId);
1216
+ await this.ensureSkillTools();
1760
1217
  const abort = options?.abort ?? new AbortController().signal;
1761
1218
  const turnId = `${sessionId}-turn-${++this.turnCounter}`;
1762
1219
  this.turnTracker.startTurn(turnId);
1763
1220
  await this.repairOrphanedToolCalls();
1764
1221
  const mcpTools = await this.ensureMCPConnected();
1765
- yield* runChatLoop({
1222
+ const loop = runChatLoop({
1766
1223
  sessionId,
1767
1224
  message,
1768
1225
  abort,
@@ -1785,6 +1242,10 @@ var Agent = class _Agent {
1785
1242
  this.state.isStreaming = v;
1786
1243
  }
1787
1244
  });
1245
+ for await (const event of loop) {
1246
+ this._signal.emit(event);
1247
+ yield event;
1248
+ }
1788
1249
  }
1789
1250
  /**
1790
1251
  * Ensure a session is loaded or created
@@ -2115,6 +1576,17 @@ var Agent = class _Agent {
2115
1576
  setModel(model) {
2116
1577
  this.config.model = model;
2117
1578
  this.state.model = model;
1579
+ if (this.config.contextWindow === void 0) {
1580
+ const modelId = getModelId(model);
1581
+ const inferred = inferContextWindow(modelId);
1582
+ if (inferred) {
1583
+ const reserveTokens = Math.min(
1584
+ 32e3,
1585
+ Math.max(8e3, Math.round(inferred * 0.12))
1586
+ );
1587
+ this.contextManager.setLimits({ contextWindow: inferred, reserveTokens });
1588
+ }
1589
+ }
2118
1590
  }
2119
1591
  /**
2120
1592
  * Get the prompt builder (when using pipeline mode).
@@ -2332,6 +1804,7 @@ var Agent = class _Agent {
2332
1804
  * After calling close(), the agent should not be used.
2333
1805
  */
2334
1806
  async close() {
1807
+ this._signal.clear();
2335
1808
  if (this.tracingShutdown) {
2336
1809
  await this.tracingShutdown();
2337
1810
  }
@@ -2370,6 +1843,8 @@ export {
2370
1843
  AgentTurnEngine,
2371
1844
  ApprovalDeniedError,
2372
1845
  ApprovalTimeoutError,
1846
+ CacheCapabilitySource,
1847
+ CapabilityCache,
2373
1848
  ContextManager,
2374
1849
  ContextOverflowError,
2375
1850
  DEFAULT_CONTEXT_LIMITS,
@@ -2378,16 +1853,25 @@ export {
2378
1853
  DEFAULT_MAX_CONCURRENT,
2379
1854
  DEFAULT_MAX_DEPTH,
2380
1855
  DEFAULT_MAX_FILE_SIZE,
1856
+ DEFAULT_MAX_OUTPUT_TOKENS,
2381
1857
  DEFAULT_MAX_SCAN_DEPTH,
2382
1858
  DEFAULT_MAX_SPAWN_DEPTH,
1859
+ DEFAULT_MAX_STEPS,
1860
+ DEFAULT_MAX_TOKENS,
1861
+ DEFAULT_RESOLVER_OPTIONS,
2383
1862
  DEFAULT_RETRY_CONFIG,
2384
1863
  DEFAULT_SESSION_TITLE_PREFIX,
2385
1864
  DEFAULT_SKILL_MAX_SIZE,
1865
+ DEFAULT_SYSTEM_PROMPT,
2386
1866
  DoomLoopError,
1867
+ EXTENDED_LEVELS,
1868
+ FIXED_LEVELS,
2387
1869
  FileStorage,
1870
+ Inference,
2388
1871
  InterventionController,
2389
1872
  LLM,
2390
1873
  LLMError,
1874
+ LocalSignal,
2391
1875
  MAX_BYTES,
2392
1876
  MAX_LINES,
2393
1877
  MemoryStorage,
@@ -2400,12 +1884,18 @@ export {
2400
1884
  PRIORITY_INSTRUCTIONS,
2401
1885
  PRIORITY_OVERRIDE,
2402
1886
  PRIORITY_SKILLS,
1887
+ PRUNE_PROTECTED_TOOLS,
1888
+ PatternCapabilitySource,
2403
1889
  Presets,
2404
1890
  PromptBuilder,
1891
+ RemoteCapabilityFetcher,
1892
+ RemoteCapabilitySource,
2405
1893
  SKILL_FILENAME,
1894
+ STANDARD_LEVELS,
2406
1895
  STORAGE_VERSION,
2407
1896
  SessionManager,
2408
1897
  SkillRegistry,
1898
+ SourcePriority,
2409
1899
  SubAgentTracker,
2410
1900
  TRUNCATE_DIR,
2411
1901
  TRUNCATE_GLOB,
@@ -2417,14 +1907,27 @@ export {
2417
1907
  applyAgentWorkflowModelStepResult,
2418
1908
  applyAgentWorkflowToolBatchResult,
2419
1909
  applyAgentWorkflowToolCallResult,
1910
+ applyCapabilityOverride,
2420
1911
  applyPreset,
2421
1912
  approvalMiddleware,
1913
+ autoDetectStreamProvider,
1914
+ buildAnthropicOptions,
1915
+ buildBedrockOptions,
1916
+ buildEntryPath,
1917
+ buildGoogleOptions,
1918
+ buildGroqOptions,
2422
1919
  buildMessagesFromEntries,
1920
+ buildOpenAIOptions,
1921
+ buildOpenRouterOptions,
2423
1922
  buildReasoningOptions,
2424
1923
  buildReasoningOptionsSync,
1924
+ buildToolSet,
1925
+ buildXAIOptions,
2425
1926
  calculateDelay,
1927
+ careful,
2426
1928
  clearCheckpoints,
2427
1929
  cloneAgentWorkflowTurnState,
1930
+ code,
2428
1931
  commitOutput,
2429
1932
  commitStep,
2430
1933
  configureDefaultSessionManager,
@@ -2439,11 +1942,14 @@ export {
2439
1942
  createApprovalHandler,
2440
1943
  createCheckpointManager,
2441
1944
  createMCPManager,
1945
+ createMessageEntry,
1946
+ createMetadataEntry,
2442
1947
  createPreset,
2443
1948
  createPromptBuilder,
2444
1949
  createResolver,
2445
1950
  createRetryHandler,
2446
1951
  createRetryState,
1952
+ createScope,
2447
1953
  createSkillRegistry,
2448
1954
  createSkillResourceTool,
2449
1955
  createSkillTool,
@@ -2451,6 +1957,7 @@ export {
2451
1957
  createSubAgentTools,
2452
1958
  createTelemetryConfig,
2453
1959
  createTurnTracker,
1960
+ currentScope,
2454
1961
  defaultAgentTaskCheckpointStrategy,
2455
1962
  defaultRegistry,
2456
1963
  defineServer,
@@ -2465,10 +1972,15 @@ export {
2465
1972
  estimateMessageTokens,
2466
1973
  estimateTokens,
2467
1974
  executeAgentToolCall,
1975
+ explore,
2468
1976
  extractFilePathsFromArgs,
1977
+ extractModelId,
1978
+ extractProvider,
1979
+ extractSessionInfo,
2469
1980
  failAgentTurnState,
2470
1981
  failAgentWorkflowTurnState,
2471
1982
  filterTools,
1983
+ findCapabilityOverride,
2472
1984
  findCutPoint,
2473
1985
  formatEnvironment,
2474
1986
  formatInstructions,
@@ -2481,57 +1993,82 @@ export {
2481
1993
  getDefaultResolver,
2482
1994
  getDefaultSessionManager,
2483
1995
  getErrorCategory,
1996
+ getGitRootHash,
2484
1997
  getLeafId,
2485
1998
  getModelId,
2486
1999
  getNetworkStatus,
2000
+ getProjectId,
2487
2001
  getProjectSessionsDir,
2002
+ getProviderCompatibility,
2488
2003
  getProviderId,
2004
+ getProviderOptionsKey,
2489
2005
  getReasoningConfig,
2490
2006
  getReasoningConfigSync,
2491
2007
  getRetryDelay,
2492
2008
  getSessionsDir,
2493
2009
  getTemplate,
2494
2010
  getToolRisk,
2011
+ hasStreamProviderFactory,
2495
2012
  httpServer,
2013
+ inferContextWindow,
2014
+ inferProvider,
2496
2015
  inferResourceType,
2497
2016
  isContextOverflowing,
2498
2017
  isRetryable,
2499
2018
  isRetryableCategory,
2019
+ likelySupportsReasoning,
2500
2020
  loadGlobalInstructions,
2501
2021
  loadResourceContent,
2502
2022
  loadSkillContent,
2503
2023
  loadSkillMetadata,
2504
2024
  localHost,
2505
2025
  mergePresets,
2026
+ needsCustomStreamProvider,
2506
2027
  normalizeToolReplayPolicy,
2507
2028
  otelMiddleware,
2508
2029
  parseFrontmatter,
2509
2030
  parseJSONL,
2031
+ parseRetryDelay,
2032
+ plan,
2510
2033
  planNextAgentWorkflowOperation,
2511
2034
  prepareModelStep,
2035
+ processStepStream,
2512
2036
  processStream,
2037
+ promptCacheMiddleware,
2513
2038
  pruneContext,
2514
2039
  pruneToolResults,
2040
+ quick,
2515
2041
  recordAgentWorkflowReplayDecision,
2516
2042
  restoreAgentWorkflowMessage,
2517
2043
  restoreAgentWorkflowMessages,
2044
+ restoreScope,
2045
+ review,
2046
+ runChatLoop,
2518
2047
  runConcurrent,
2519
2048
  runModelStep,
2520
2049
  runToolBatch,
2521
2050
  serializeMessage,
2522
2051
  shouldCaptureBaseline,
2052
+ shouldIncludeReasoningSummary,
2523
2053
  shouldPruneContext,
2524
2054
  shouldRetry,
2525
2055
  sleep,
2526
2056
  snapshotAgentWorkflowMessage,
2527
2057
  snapshotAgentWorkflowMessages,
2058
+ snapshotScope,
2528
2059
  sseServer,
2529
2060
  stdioServer,
2061
+ stream,
2062
+ streamOnce,
2063
+ streamStep,
2530
2064
  summarizeEnvironment,
2531
2065
  supportsReasoning,
2532
2066
  supportsReasoningSync,
2533
2067
  toJSONL,
2068
+ toJSONLBatch,
2534
2069
  truncateOutput,
2070
+ watch,
2535
2071
  withFileTracking,
2536
- withRetry
2072
+ withRetry,
2073
+ withinScope
2537
2074
  };