@cuylabs/agent-core 0.8.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +33 -17
  2. package/dist/chunk-2O4MCSQS.js +780 -0
  3. package/dist/chunk-2TTOLHBT.js +198 -0
  4. package/dist/chunk-5FMSGQVX.js +281 -0
  5. package/dist/chunk-5NVVNXPQ.js +288 -0
  6. package/dist/{chunk-CAA7FHIH.js → chunk-6HZBHFOL.js} +3 -103
  7. package/dist/chunk-CJI7PVS2.js +58 -0
  8. package/dist/{chunk-N6HWIEEA.js → chunk-CMYN2RCB.js} +278 -61
  9. package/dist/chunk-FII65CN7.js +117 -0
  10. package/dist/{chunk-IVUJDISU.js → chunk-GFTW23FV.js} +5 -14
  11. package/dist/chunk-I6PKJ7XQ.js +292 -0
  12. package/dist/{chunk-BDBZ3SLK.js → chunk-ICZ66572.js} +48 -4
  13. package/dist/chunk-KYLPMBHD.js +316 -0
  14. package/dist/chunk-MXAP4UG6.js +2956 -0
  15. package/dist/{chunk-RZITT45F.js → chunk-N3VX7FEE.js} +39 -6
  16. package/dist/{chunk-YSLSEQ6B.js → chunk-NDZWXCBZ.js} +218 -95
  17. package/dist/{chunk-P6YF7USR.js → chunk-Q742PSH3.js} +23 -38
  18. package/dist/chunk-QAL3OMI3.js +943 -0
  19. package/dist/{chunk-RFEKJKTO.js → chunk-RN6WZEUF.js} +330 -280
  20. package/dist/{chunk-ZXAKHMWH.js → chunk-ROTGCYDW.js} +22 -84
  21. package/dist/chunk-SPBFQXOT.js +0 -0
  22. package/dist/{chunk-LRHOS4ZN.js → chunk-SPILYYDF.js} +3 -2
  23. package/dist/chunk-SSFBF3US.js +602 -0
  24. package/dist/chunk-SZ2XBPTW.js +8 -0
  25. package/dist/chunk-T4UIX5D7.js +115 -0
  26. package/dist/chunk-TIHPYVAJ.js +102 -0
  27. package/dist/{chunk-YUUJK53A.js → chunk-TOTDGK3P.js} +1 -1
  28. package/dist/chunk-V4RFNEET.js +563 -0
  29. package/dist/chunk-VOUEJSW6.js +0 -0
  30. package/dist/{chunk-4BDA7DQY.js → chunk-WBPOZ7CL.js} +673 -273
  31. package/dist/chunk-X4VN4GIJ.js +185 -0
  32. package/dist/dispatch/index.d.ts +93 -0
  33. package/dist/dispatch/index.js +37 -0
  34. package/dist/events/index.d.ts +93 -0
  35. package/dist/events/index.js +6 -0
  36. package/dist/{runtime → execution}/index.d.ts +120 -34
  37. package/dist/{runtime → execution}/index.js +18 -13
  38. package/dist/index-BCqEGzBj.d.ts +251 -0
  39. package/dist/index.d.ts +490 -122
  40. package/dist/index.js +2104 -615
  41. package/dist/{errors → inference/errors}/index.d.ts +2 -2
  42. package/dist/{errors → inference/errors}/index.js +1 -1
  43. package/dist/inference/index.d.ts +16 -23
  44. package/dist/inference/index.js +45 -16
  45. package/dist/instance-BqV2D5pc.d.ts +5723 -0
  46. package/dist/logger/index.d.ts +50 -0
  47. package/dist/logger/index.js +11 -0
  48. package/dist/mcp/index.d.ts +5 -9
  49. package/dist/mcp/index.js +2 -3
  50. package/dist/middleware/index.d.ts +10 -149
  51. package/dist/middleware/index.js +11 -3
  52. package/dist/model-messages-B4nK9D1-.d.ts +13 -0
  53. package/dist/models/index.d.ts +23 -18
  54. package/dist/models/index.js +48 -11
  55. package/dist/models/reasoning/index.d.ts +4 -0
  56. package/dist/{reasoning → models/reasoning}/index.js +3 -3
  57. package/dist/plugin/index.d.ts +458 -0
  58. package/dist/plugin/index.js +32 -0
  59. package/dist/profiles/index.d.ts +55 -0
  60. package/dist/profiles/index.js +30 -0
  61. package/dist/prompt/index.d.ts +8 -12
  62. package/dist/prompt/index.js +3 -2
  63. package/dist/safety/index.d.ts +109 -14
  64. package/dist/safety/index.js +59 -3
  65. package/dist/sandbox/index.d.ts +81 -0
  66. package/dist/sandbox/index.js +1 -0
  67. package/dist/skill/index.d.ts +10 -8
  68. package/dist/skill/index.js +3 -3
  69. package/dist/storage/index.d.ts +12 -4
  70. package/dist/storage/index.js +1 -1
  71. package/dist/subagents/index.d.ts +177 -0
  72. package/dist/subagents/index.js +78 -0
  73. package/dist/team/index.d.ts +544 -0
  74. package/dist/team/index.js +41 -0
  75. package/dist/tool/host/index.d.ts +41 -0
  76. package/dist/tool/host/index.js +10 -0
  77. package/dist/tool/index.d.ts +125 -21
  78. package/dist/tool/index.js +20 -13
  79. package/dist/{types-VQgymC1N.d.ts → types-Bj_J8u_W.d.ts} +44 -64
  80. package/dist/{types-CHiPh8U2.d.ts → types-C_LCeYNg.d.ts} +7 -7
  81. package/dist/types-RSCv7nQ4.d.ts +59 -0
  82. package/package.json +58 -53
  83. package/dist/builder-UpOWQMW3.d.ts +0 -34
  84. package/dist/chunk-7MUFEN4K.js +0 -559
  85. package/dist/chunk-7VKQ4WPB.js +0 -73
  86. package/dist/chunk-BFM2YHNM.js +0 -222
  87. package/dist/chunk-DWYX7ASF.js +0 -26
  88. package/dist/chunk-KUVSERLJ.js +0 -50
  89. package/dist/chunk-N7P4PN3O.js +0 -84
  90. package/dist/chunk-SDSBEQXG.js +0 -157
  91. package/dist/chunk-SQU2AJHO.js +0 -305
  92. package/dist/chunk-VBWWUHWI.js +0 -724
  93. package/dist/chunk-VEKUXUVF.js +0 -41
  94. package/dist/chunk-VNQBHPCT.js +0 -398
  95. package/dist/chunk-WWYYNWEW.js +0 -259
  96. package/dist/context/index.d.ts +0 -259
  97. package/dist/context/index.js +0 -26
  98. package/dist/events-CE72w8W4.d.ts +0 -149
  99. package/dist/host/index.d.ts +0 -45
  100. package/dist/host/index.js +0 -8
  101. package/dist/index-CWSchSql.d.ts +0 -1058
  102. package/dist/messages-BYWGn8TY.d.ts +0 -110
  103. package/dist/presets/index.d.ts +0 -53
  104. package/dist/presets/index.js +0 -28
  105. package/dist/reasoning/index.d.ts +0 -116
  106. package/dist/registry-DwYqsQkX.d.ts +0 -164
  107. package/dist/runner-e2YRcUoX.d.ts +0 -786
  108. package/dist/scope/index.d.ts +0 -10
  109. package/dist/scope/index.js +0 -14
  110. package/dist/session-manager-B_CWGTsl.d.ts +0 -274
  111. package/dist/signal/index.d.ts +0 -28
  112. package/dist/signal/index.js +0 -6
  113. package/dist/sub-agent/index.d.ts +0 -23
  114. package/dist/sub-agent/index.js +0 -15
  115. package/dist/tool-BHbyUAy3.d.ts +0 -150
  116. package/dist/tool-DLXAR9Ce.d.ts +0 -145
  117. package/dist/tracker-DClqYqTj.d.ts +0 -96
  118. package/dist/tracking/index.d.ts +0 -111
  119. package/dist/tracking/index.js +0 -20
  120. package/dist/types-BfNpU8NS.d.ts +0 -270
  121. package/dist/types-BnpEOYV-.d.ts +0 -50
  122. package/dist/types-CQL-SvTn.d.ts +0 -29
  123. package/dist/types-CWm-7rvB.d.ts +0 -55
  124. package/dist/types-KKDrdU9Y.d.ts +0 -325
  125. package/dist/types-QA4WhEfz.d.ts +0 -138
  126. package/dist/types-QKHHQLLq.d.ts +0 -336
  127. package/dist/types-YuWV4ag7.d.ts +0 -72
package/dist/index.js CHANGED
@@ -1,59 +1,101 @@
1
1
  import {
2
- FileStorage,
3
- MemoryStorage,
4
- STORAGE_VERSION,
5
- SessionManager,
6
- buildEntryPath,
7
- buildMessagesFromEntries,
8
- configureDefaultSessionManager,
9
- createMessageEntry,
10
- createMetadataEntry,
11
- deserializeMessage,
12
- extractSessionInfo,
13
- generateEntryId,
14
- getDataDir,
15
- getDefaultSessionManager,
16
- getGitRootHash,
17
- getLeafId,
18
- getProjectId,
19
- getProjectSessionsDir,
20
- getSessionsDir,
21
- parseJSONL,
22
- serializeMessage,
23
- toJSONL,
24
- toJSONLBatch
25
- } from "./chunk-BDBZ3SLK.js";
2
+ DEFAULT_SUBAGENT_CONCURRENCY,
3
+ DEFAULT_SUBAGENT_DEPTH,
4
+ DEFAULT_SUBAGENT_SESSION_PREFIX,
5
+ LOCAL_SUBAGENT_BACKEND,
6
+ SUBAGENT_TOOL_IDS,
7
+ clearInstalledSubAgents,
8
+ configureSubAgents,
9
+ createCloseAgentTool,
10
+ createInvokeAgentTool,
11
+ createSubAgentTools,
12
+ createWaitAgentTool,
13
+ discoverSubAgentRoles,
14
+ formatAsyncSpawnedResult,
15
+ formatCancelledAgentResult,
16
+ formatCloseAlreadyResolvedResult,
17
+ formatCloseMissingAgentResult,
18
+ formatInvalidAgentTypeResult,
19
+ formatMissingAgentsResult,
20
+ formatSpawnBlockedResult,
21
+ formatSyncSubAgentErrorResult,
22
+ formatSyncSubAgentResult,
23
+ formatWaitErrorResult,
24
+ formatWaitResult,
25
+ formatWaitTimeoutResult,
26
+ getConfiguredSubAgents,
27
+ getInstalledSubAgentBackend,
28
+ getProjectSubAgentRolesDir,
29
+ getUserSubAgentRolesDir,
30
+ installLocalSubAgents,
31
+ installSubAgentTools,
32
+ isMarkdownSubAgentRole,
33
+ parseMarkdownSubAgentRole,
34
+ parseSubAgentRoleFrontmatter,
35
+ parseSubAgentToolSpec,
36
+ toSubAgentRole
37
+ } from "./chunk-2O4MCSQS.js";
26
38
  import {
27
- DEFAULT_MAX_CONCURRENT,
28
- DEFAULT_MAX_SPAWN_DEPTH,
29
- DEFAULT_SESSION_TITLE_PREFIX,
30
- SubAgentTracker,
31
- createSubAgentTools
32
- } from "./chunk-7MUFEN4K.js";
39
+ InMemoryMailboxStore,
40
+ InMemoryTaskBoardStore,
41
+ Mailbox,
42
+ TERMINAL_STATUSES,
43
+ TaskBoard,
44
+ TaskConflictError,
45
+ TeamCoordinator,
46
+ addTokenUsage,
47
+ buildCoordinatorNotificationEvent,
48
+ buildCoordinatorSystemPrompt,
49
+ coordinatorToolDescriptions,
50
+ createTeamCoordinator,
51
+ evaluateCoordinatorRoundTransition,
52
+ formatCoordinatorRoundMessage,
53
+ formatCoordinatorTaskNotifications,
54
+ formatCoordinatorWorkerReports,
55
+ teamPermissionPolicy
56
+ } from "./chunk-MXAP4UG6.js";
33
57
  import {
34
58
  ToolRegistry,
59
+ createToolSearchTool,
35
60
  defaultRegistry
36
- } from "./chunk-SDSBEQXG.js";
61
+ } from "./chunk-KYLPMBHD.js";
37
62
  import {
38
- TurnChangeTracker,
39
- clearCheckpoints,
40
- createCheckpointManager,
41
- createTurnTracker
42
- } from "./chunk-VBWWUHWI.js";
63
+ ToolHostRegistry,
64
+ defaultToolHostRegistry,
65
+ localHost
66
+ } from "./chunk-X4VN4GIJ.js";
67
+ import {
68
+ LayeredSettings,
69
+ NullSettings,
70
+ PluginEventBus,
71
+ PluginRegistry,
72
+ StaticSettings,
73
+ ValidatedSettings,
74
+ definePlugin,
75
+ discoverPlugins,
76
+ getPluginLoader,
77
+ isDefinedPlugin,
78
+ loadPluginModule,
79
+ resetFrameworkAliases,
80
+ resetPluginLoader,
81
+ resolveFrameworkAliases
82
+ } from "./chunk-QAL3OMI3.js";
83
+ import {
84
+ applyProfile,
85
+ createProfile,
86
+ filterTools,
87
+ mergeProfiles
88
+ } from "./chunk-TIHPYVAJ.js";
43
89
  import {
44
- Presets,
45
- applyPreset,
90
+ Profiles,
46
91
  careful,
47
92
  code,
48
- createPreset,
49
93
  explore,
50
- filterTools,
51
- mergePresets,
52
94
  plan,
53
95
  quick,
54
96
  review,
55
97
  watch
56
- } from "./chunk-CAA7FHIH.js";
98
+ } from "./chunk-6HZBHFOL.js";
57
99
  import {
58
100
  DEFAULT_INSTRUCTION_PATTERNS,
59
101
  DEFAULT_MAX_DEPTH,
@@ -75,32 +117,121 @@ import {
75
117
  getTemplate,
76
118
  loadGlobalInstructions,
77
119
  summarizeEnvironment
78
- } from "./chunk-IVUJDISU.js";
120
+ } from "./chunk-GFTW23FV.js";
121
+ import "./chunk-VOUEJSW6.js";
122
+ import {
123
+ createSkillResourceTool,
124
+ createSkillTool,
125
+ createSkillTools
126
+ } from "./chunk-TOTDGK3P.js";
127
+ import {
128
+ DEFAULT_EXTERNAL_DIRS,
129
+ DEFAULT_MAX_SCAN_DEPTH,
130
+ DEFAULT_SKILL_MAX_SIZE,
131
+ SKILL_FILENAME,
132
+ SkillRegistry,
133
+ createSkillRegistry,
134
+ discoverSkills,
135
+ emptySkillRegistry,
136
+ inferResourceType,
137
+ loadResourceContent,
138
+ loadSkillContent,
139
+ loadSkillMetadata,
140
+ parseFrontmatter
141
+ } from "./chunk-SPILYYDF.js";
142
+ import {
143
+ createCompositeDispatchTaskExecutor,
144
+ createDispatchExternalTaskControl,
145
+ createDispatchTaskExecutor,
146
+ createRuntimeDispatchExecutor,
147
+ createRuntimeDispatchTargets,
148
+ ensureNonEmpty,
149
+ mergeInspection
150
+ } from "./chunk-5FMSGQVX.js";
151
+ import {
152
+ DEFAULT_DISPATCH_TOOL_IDS,
153
+ DEFAULT_LOCAL_DISPATCH_CONCURRENCY,
154
+ DEFAULT_LOCAL_DISPATCH_DEPTH,
155
+ DEFAULT_LOCAL_DISPATCH_TITLE_PREFIX,
156
+ DISPATCH_STATES,
157
+ createDispatchTools,
158
+ createLocalDispatchRuntime,
159
+ createSubAgentRunSession,
160
+ ensureSessionLoaded,
161
+ getVisibleSessionMessages,
162
+ repairOrphanedToolCalls
163
+ } from "./chunk-SSFBF3US.js";
164
+ import {
165
+ sleep
166
+ } from "./chunk-SZ2XBPTW.js";
167
+ import {
168
+ MAX_BYTES,
169
+ MAX_LINES,
170
+ Tool,
171
+ normalizeToolReplayPolicy,
172
+ truncateOutput
173
+ } from "./chunk-Q742PSH3.js";
174
+ import {
175
+ FileStorage,
176
+ MemoryStorage,
177
+ STORAGE_VERSION,
178
+ SessionManager,
179
+ buildEntryPath,
180
+ buildMessagesFromEntries,
181
+ configureDefaultSessionManager,
182
+ createMessageEntry,
183
+ createMetadataEntry,
184
+ deserializeMessage,
185
+ extractSessionInfo,
186
+ generateEntryId,
187
+ getDataDir,
188
+ getDefaultSessionManager,
189
+ getGitRootHash,
190
+ getLeafId,
191
+ getProjectId,
192
+ getProjectSessionsDir,
193
+ getSessionsDir,
194
+ parseJSONL,
195
+ serializeMessage,
196
+ toJSONL,
197
+ toJSONLBatch
198
+ } from "./chunk-ICZ66572.js";
199
+ import {
200
+ createEventBus
201
+ } from "./chunk-2TTOLHBT.js";
79
202
  import {
80
203
  AgentTurnEngine,
204
+ ContextManager,
81
205
  ContextOverflowError,
206
+ DEFAULT_CONTEXT_LIMITS,
82
207
  DoomLoopError,
83
208
  advanceAgentTurnState,
84
209
  applyAgentWorkflowCommitResult,
85
210
  applyAgentWorkflowModelStepResult,
86
211
  applyAgentWorkflowToolBatchResult,
87
212
  applyAgentWorkflowToolCallResult,
213
+ applyWorkflowInterventions,
88
214
  cloneAgentWorkflowTurnState,
89
215
  commitOutput,
90
216
  commitStep,
91
- convertAgentMessagesToModelMessages,
92
217
  createAgentTaskRunner,
93
218
  createAgentTurnEngine,
94
219
  createAgentTurnState,
95
220
  createAgentTurnStepCommitBatch,
96
221
  createAgentWorkflowTurnState,
97
222
  defaultAgentTaskCheckpointStrategy,
223
+ drainWorkflowInterventions,
224
+ estimateConversationTokens,
225
+ estimateMessageTokens,
226
+ estimateTokens,
98
227
  failAgentTurnState,
99
228
  failAgentWorkflowTurnState,
229
+ findCutPoint,
230
+ getUsableTokenLimit,
100
231
  planNextAgentWorkflowOperation,
101
232
  prepareModelStep,
102
233
  processStepStream,
103
- processStream,
234
+ queueWorkflowFollowUps,
104
235
  recordAgentWorkflowReplayDecision,
105
236
  restoreAgentWorkflowMessage,
106
237
  restoreAgentWorkflowMessages,
@@ -108,88 +239,52 @@ import {
108
239
  runToolBatch,
109
240
  snapshotAgentWorkflowMessage,
110
241
  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";
242
+ } from "./chunk-WBPOZ7CL.js";
120
243
  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";
131
- import {
132
- DEFAULT_EXTERNAL_DIRS,
133
- DEFAULT_MAX_SCAN_DEPTH,
134
- DEFAULT_SKILL_MAX_SIZE,
135
- SKILL_FILENAME,
136
- SkillRegistry,
137
- createSkillRegistry,
138
- discoverSkills,
139
- emptySkillRegistry,
140
- inferResourceType,
141
- loadResourceContent,
142
- loadSkillContent,
143
- loadSkillMetadata,
144
- parseFrontmatter
145
- } from "./chunk-LRHOS4ZN.js";
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
244
  DEFAULT_RETRY_CONFIG,
167
245
  Inference,
168
- LLM,
169
- OUTPUT_TOKEN_MAX,
246
+ buildModelCallContext,
170
247
  buildToolSet,
171
248
  calculateDelay,
249
+ convertAgentMessagesToModelMessages,
172
250
  createRetryHandler,
173
251
  createRetryState,
174
252
  shouldRetry,
175
- sleep,
176
253
  stream,
177
254
  streamOnce,
178
255
  streamStep,
179
256
  withRetry
180
- } from "./chunk-N6HWIEEA.js";
181
- import {
182
- executeAgentToolCall
183
- } from "./chunk-7VKQ4WPB.js";
257
+ } from "./chunk-CMYN2RCB.js";
184
258
  import {
259
+ PRUNE_PROTECTED_TOOLS,
260
+ accumulateUsage,
261
+ currentScope,
262
+ executeAgentToolCall,
185
263
  extractFilePathsFromArgs,
264
+ restoreScope,
186
265
  shouldCaptureBaseline,
187
- withFileTracking
188
- } from "./chunk-VEKUXUVF.js";
266
+ snapshotScope,
267
+ streamWithinScope,
268
+ withinScope
269
+ } from "./chunk-5NVVNXPQ.js";
270
+ import {
271
+ LLMError,
272
+ getErrorCategory,
273
+ getRetryDelay,
274
+ isRetryable,
275
+ isRetryableCategory,
276
+ parseRetryDelay
277
+ } from "./chunk-N3VX7FEE.js";
189
278
  import {
279
+ CacheCapabilitySource,
280
+ CapabilityCache,
190
281
  EXTENDED_LEVELS,
191
282
  FIXED_LEVELS,
283
+ ModelCapabilityResolver,
284
+ RemoteCapabilityFetcher,
285
+ RemoteCapabilitySource,
192
286
  STANDARD_LEVELS,
287
+ applyCapabilityOverride,
193
288
  buildAnthropicOptions,
194
289
  buildBedrockOptions,
195
290
  buildGoogleOptions,
@@ -199,75 +294,717 @@ import {
199
294
  buildReasoningOptions,
200
295
  buildReasoningOptionsSync,
201
296
  buildXAIOptions,
297
+ configureResolver,
298
+ createResolver,
299
+ findCapabilityOverride,
300
+ getDefaultResolver,
301
+ getNetworkStatus,
202
302
  getProviderOptionsKey,
203
303
  getReasoningConfig,
204
304
  getReasoningConfigSync,
205
305
  shouldIncludeReasoningSummary,
206
306
  supportsReasoning,
207
307
  supportsReasoningSync
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";
308
+ } from "./chunk-RN6WZEUF.js";
309
+ import "./chunk-SPBFQXOT.js";
225
310
  import {
226
311
  createMCPManager,
227
- defineServer,
228
312
  httpServer,
229
313
  sseServer,
230
314
  stdioServer
231
- } from "./chunk-ZXAKHMWH.js";
315
+ } from "./chunk-ROTGCYDW.js";
232
316
  import {
233
317
  MiddlewareRunner,
234
318
  approvalMiddleware,
235
319
  createTelemetryConfig,
320
+ isApprovalMiddleware,
236
321
  otelMiddleware,
237
322
  promptCacheMiddleware
238
- } from "./chunk-YSLSEQ6B.js";
323
+ } from "./chunk-NDZWXCBZ.js";
239
324
  import {
240
- ApprovalDeniedError,
241
- ApprovalTimeoutError,
242
- createApprovalHandler,
243
- getToolRisk
244
- } from "./chunk-BFM2YHNM.js";
325
+ DEFAULT_AGENT_NAME,
326
+ DEFAULT_MAX_STEPS,
327
+ DEFAULT_MAX_TOKENS,
328
+ DEFAULT_SYSTEM_PROMPT,
329
+ isBlockedModelCall,
330
+ resolveAgentDefaults,
331
+ sandboxDefaultsProvider
332
+ } from "./chunk-CJI7PVS2.js";
245
333
  import {
246
- CacheCapabilitySource,
247
- CapabilityCache,
248
334
  DEFAULT_RESOLVER_OPTIONS,
249
- ModelCapabilityResolver,
250
335
  PatternCapabilitySource,
251
- RemoteCapabilityFetcher,
252
- RemoteCapabilitySource,
253
336
  SourcePriority,
254
- applyCapabilityOverride,
255
- configureResolver,
256
- createResolver,
257
337
  extractModelId,
258
338
  extractProvider,
259
- findCapabilityOverride,
260
- getDefaultResolver,
261
- getNetworkStatus,
339
+ getModelId,
262
340
  getProviderCompatibility,
341
+ getProviderId,
263
342
  inferContextWindow,
264
343
  inferProvider,
265
344
  likelySupportsReasoning
266
- } from "./chunk-RFEKJKTO.js";
345
+ } from "./chunk-I6PKJ7XQ.js";
267
346
  import {
268
- getModelId,
269
- getProviderId
270
- } from "./chunk-DWYX7ASF.js";
347
+ ApprovalDeniedError,
348
+ ApprovalTimeoutError,
349
+ allApprovalConditions,
350
+ anyApprovalConditions,
351
+ approvalRequestsOverlap,
352
+ buildApprovalRuleContext,
353
+ createApprovalCorrection,
354
+ createApprovalHandler,
355
+ createApprovalPolicyPreset,
356
+ createConditionalApprovalRule,
357
+ createDangerouslyAllowAllApprovalPolicy,
358
+ createHeadlessDenyApprovalPolicy,
359
+ createInteractiveApprovalPolicy,
360
+ createRememberedApprovalRules,
361
+ createRiskTierApprovalPolicy,
362
+ createThresholdApprovalRule,
363
+ createTrustedSessionApprovalPolicy,
364
+ formatApprovalDeniedReason,
365
+ getToolRisk,
366
+ matchApprovalArgValue,
367
+ matchApprovalNumericArg,
368
+ matchApprovalRisks,
369
+ matchApprovalSessions,
370
+ matchApprovalStringPrefixes,
371
+ normalizeApprovalCascadePolicy,
372
+ normalizeRememberScopes,
373
+ selectRememberScope,
374
+ shouldCascadeApprovalDecision
375
+ } from "./chunk-V4RFNEET.js";
376
+ import {
377
+ describeApprovalOperation,
378
+ extractApprovalPatterns,
379
+ getRequiredToolHost,
380
+ matchApprovalPattern,
381
+ requiresToolHost,
382
+ resolveCapability
383
+ } from "./chunk-FII65CN7.js";
384
+ import {
385
+ createConsoleLogger,
386
+ createFileLogger,
387
+ silentLogger
388
+ } from "./chunk-T4UIX5D7.js";
389
+
390
+ // src/tracking/turn-tracker/tracker.ts
391
+ import { spawn } from "child_process";
392
+ import { normalize, relative as relative2, resolve } from "path";
393
+
394
+ // src/tracking/turn-tracker/diff.ts
395
+ import { createHash } from "crypto";
396
+ import { mkdir, readFile, stat, unlink, writeFile } from "fs/promises";
397
+ import { dirname, relative } from "path";
398
+ async function captureTurnFileBaseline(absPath) {
399
+ try {
400
+ const content = await readFile(absPath, "utf-8");
401
+ const stats = await stat(absPath);
402
+ return {
403
+ path: absPath,
404
+ content,
405
+ mode: stats.mode,
406
+ hash: hashTurnTrackerContent(content),
407
+ capturedAt: /* @__PURE__ */ new Date()
408
+ };
409
+ } catch (error) {
410
+ if (error.code === "ENOENT") {
411
+ return {
412
+ path: absPath,
413
+ content: null,
414
+ mode: null,
415
+ hash: null,
416
+ capturedAt: /* @__PURE__ */ new Date()
417
+ };
418
+ }
419
+ throw error;
420
+ }
421
+ }
422
+ async function restoreTurnTrackedFile(absPath, baseline) {
423
+ if (baseline.content === null) {
424
+ try {
425
+ await unlink(absPath);
426
+ } catch (error) {
427
+ if (error.code !== "ENOENT") {
428
+ throw error;
429
+ }
430
+ }
431
+ return;
432
+ }
433
+ await mkdir(dirname(absPath), { recursive: true });
434
+ await writeFile(absPath, baseline.content, {
435
+ mode: baseline.mode ?? void 0
436
+ });
437
+ }
438
+ async function computeTurnTrackerFileChange(options) {
439
+ const { cwd, absPath, baseline, preferGitDiff, canUseGitDiff } = options;
440
+ const relPath = relative(cwd, absPath);
441
+ const currentContent = await readTrackedFileContent(absPath);
442
+ let type;
443
+ if (baseline.content === null && currentContent === null) {
444
+ type = "unchanged";
445
+ } else if (baseline.content === null && currentContent !== null) {
446
+ type = "created";
447
+ } else if (baseline.content !== null && currentContent === null) {
448
+ type = "deleted";
449
+ } else if (baseline.content === currentContent) {
450
+ type = "unchanged";
451
+ } else {
452
+ type = "modified";
453
+ }
454
+ if (type === "unchanged") {
455
+ return { path: relPath, type, additions: 0, deletions: 0 };
456
+ }
457
+ const diff = await generateTurnTrackerDiff({
458
+ relPath,
459
+ oldContent: baseline.content,
460
+ newContent: currentContent,
461
+ preferGitDiff,
462
+ canUseGitDiff
463
+ });
464
+ const { additions, deletions } = countUnifiedDiffStats(diff);
465
+ return {
466
+ path: relPath,
467
+ type,
468
+ additions,
469
+ deletions,
470
+ diff
471
+ };
472
+ }
473
+ async function readTrackedFileContent(absPath) {
474
+ try {
475
+ return await readFile(absPath, "utf-8");
476
+ } catch (error) {
477
+ if (error.code === "ENOENT") {
478
+ return null;
479
+ }
480
+ throw error;
481
+ }
482
+ }
483
+ async function generateTurnTrackerDiff(options) {
484
+ const { relPath, oldContent, newContent, preferGitDiff, canUseGitDiff } = options;
485
+ const oldLines = (oldContent ?? "").split("\n");
486
+ const newLines = (newContent ?? "").split("\n");
487
+ if (preferGitDiff && canUseGitDiff) {
488
+ const gitDiff = await createGitStyleDiffPlaceholder();
489
+ if (gitDiff) {
490
+ return gitDiff;
491
+ }
492
+ }
493
+ return buildSimpleUnifiedDiff({
494
+ path: relPath,
495
+ oldLines,
496
+ newLines,
497
+ wasCreated: oldContent === null,
498
+ wasDeleted: newContent === null
499
+ });
500
+ }
501
+ function buildSimpleUnifiedDiff(options) {
502
+ const { path, oldLines, newLines, wasCreated, wasDeleted } = options;
503
+ const header = [
504
+ `--- a/${path}${wasCreated ? " (new file)" : ""}`,
505
+ `+++ b/${path}${wasDeleted ? " (deleted)" : ""}`
506
+ ];
507
+ const hunks = [];
508
+ if (wasCreated) {
509
+ hunks.push(`@@ -0,0 +1,${newLines.length} @@`);
510
+ for (const line of newLines) {
511
+ hunks.push(`+${line}`);
512
+ }
513
+ } else if (wasDeleted) {
514
+ hunks.push(`@@ -1,${oldLines.length} +0,0 @@`);
515
+ for (const line of oldLines) {
516
+ hunks.push(`-${line}`);
517
+ }
518
+ } else {
519
+ hunks.push(`@@ -1,${oldLines.length} +1,${newLines.length} @@`);
520
+ for (const line of oldLines) {
521
+ hunks.push(`-${line}`);
522
+ }
523
+ for (const line of newLines) {
524
+ hunks.push(`+${line}`);
525
+ }
526
+ }
527
+ return [...header, ...hunks].join("\n");
528
+ }
529
+ function countUnifiedDiffStats(diff) {
530
+ let additions = 0;
531
+ let deletions = 0;
532
+ for (const line of diff.split("\n")) {
533
+ if (line.startsWith("+") && !line.startsWith("+++")) {
534
+ additions++;
535
+ } else if (line.startsWith("-") && !line.startsWith("---")) {
536
+ deletions++;
537
+ }
538
+ }
539
+ return { additions, deletions };
540
+ }
541
+ function hashTurnTrackerContent(content) {
542
+ return createHash("sha256").update(content).digest("hex").slice(0, 16);
543
+ }
544
+ async function createGitStyleDiffPlaceholder() {
545
+ return null;
546
+ }
547
+
548
+ // src/tracking/turn-tracker/tracker.ts
549
+ var TurnChangeTracker = class {
550
+ config;
551
+ currentTurn = null;
552
+ gitDetected = null;
553
+ log;
554
+ constructor(config, logger) {
555
+ this.config = {
556
+ cwd: resolve(config.cwd),
557
+ useGit: config.useGit ?? true,
558
+ maxTrackedFiles: config.maxTrackedFiles ?? 100
559
+ };
560
+ this.log = logger?.child("turn-tracker") ?? silentLogger;
561
+ }
562
+ startTurn(turnId) {
563
+ if (this.currentTurn && !this.currentTurn.completed) {
564
+ this.currentTurn.completed = true;
565
+ }
566
+ this.currentTurn = {
567
+ id: turnId,
568
+ startedAt: /* @__PURE__ */ new Date(),
569
+ baselines: /* @__PURE__ */ new Map(),
570
+ completed: false
571
+ };
572
+ }
573
+ async endTurn() {
574
+ if (!this.currentTurn) {
575
+ return {
576
+ turnId: "",
577
+ files: [],
578
+ totalTracked: 0,
579
+ additions: 0,
580
+ deletions: 0,
581
+ diff: null,
582
+ duration: 0
583
+ };
584
+ }
585
+ const turn = this.currentTurn;
586
+ turn.completed = true;
587
+ const files = [];
588
+ let additions = 0;
589
+ let deletions = 0;
590
+ const diffs = [];
591
+ for (const [absPath, baseline] of turn.baselines) {
592
+ const change = await this.computeFileChange(absPath, baseline);
593
+ files.push(change);
594
+ additions += change.additions;
595
+ deletions += change.deletions;
596
+ if (change.diff) {
597
+ diffs.push(change.diff);
598
+ }
599
+ }
600
+ files.sort((left, right) => left.path.localeCompare(right.path));
601
+ return {
602
+ turnId: turn.id,
603
+ files,
604
+ totalTracked: turn.baselines.size,
605
+ additions,
606
+ deletions,
607
+ diff: diffs.length > 0 ? diffs.join("\n") : null,
608
+ duration: Date.now() - turn.startedAt.getTime()
609
+ };
610
+ }
611
+ isInTurn() {
612
+ return this.currentTurn !== null && !this.currentTurn.completed;
613
+ }
614
+ getCurrentTurnId() {
615
+ return this.currentTurn?.id ?? null;
616
+ }
617
+ async beforeWrite(filePath) {
618
+ if (!this.currentTurn || this.currentTurn.completed) {
619
+ return false;
620
+ }
621
+ const absPath = resolve(this.config.cwd, filePath);
622
+ const normalizedPath = normalize(absPath);
623
+ if (this.currentTurn.baselines.has(normalizedPath)) {
624
+ return false;
625
+ }
626
+ if (this.currentTurn.baselines.size >= this.config.maxTrackedFiles) {
627
+ this.log.warn(
628
+ `Max tracked files (${this.config.maxTrackedFiles}) reached, skipping: ${filePath}`
629
+ );
630
+ return false;
631
+ }
632
+ const baseline = await captureTurnFileBaseline(normalizedPath);
633
+ this.currentTurn.baselines.set(normalizedPath, baseline);
634
+ return true;
635
+ }
636
+ getTrackedFiles() {
637
+ if (!this.currentTurn) {
638
+ return [];
639
+ }
640
+ return Array.from(this.currentTurn.baselines.keys()).map(
641
+ (path) => relative2(this.config.cwd, path)
642
+ );
643
+ }
644
+ isTracking(filePath) {
645
+ if (!this.currentTurn) {
646
+ return false;
647
+ }
648
+ const absPath = resolve(this.config.cwd, filePath);
649
+ return this.currentTurn.baselines.has(normalize(absPath));
650
+ }
651
+ async getDiff() {
652
+ if (!this.currentTurn || this.currentTurn.baselines.size === 0) {
653
+ return null;
654
+ }
655
+ const diffs = [];
656
+ for (const [absPath, baseline] of this.currentTurn.baselines) {
657
+ const change = await this.computeFileChange(absPath, baseline);
658
+ if (change.diff) {
659
+ diffs.push(change.diff);
660
+ }
661
+ }
662
+ return diffs.length > 0 ? diffs.join("\n") : null;
663
+ }
664
+ async getFileDiff(filePath) {
665
+ if (!this.currentTurn) {
666
+ return null;
667
+ }
668
+ const absPath = resolve(this.config.cwd, filePath);
669
+ const baseline = this.currentTurn.baselines.get(normalize(absPath));
670
+ if (!baseline) {
671
+ return null;
672
+ }
673
+ const change = await this.computeFileChange(absPath, baseline);
674
+ return change.diff ?? null;
675
+ }
676
+ async undoTurn() {
677
+ if (!this.currentTurn) {
678
+ return { restored: [], failed: [] };
679
+ }
680
+ const result = { restored: [], failed: [] };
681
+ for (const [absPath, baseline] of this.currentTurn.baselines) {
682
+ const relPath = relative2(this.config.cwd, absPath);
683
+ try {
684
+ await restoreTurnTrackedFile(absPath, baseline);
685
+ result.restored.push(relPath);
686
+ } catch (error) {
687
+ result.failed.push({
688
+ path: relPath,
689
+ reason: error instanceof Error ? error.message : String(error)
690
+ });
691
+ }
692
+ }
693
+ return result;
694
+ }
695
+ async undoFiles(filePaths) {
696
+ if (!this.currentTurn) {
697
+ return { restored: [], failed: [] };
698
+ }
699
+ const result = { restored: [], failed: [] };
700
+ for (const filePath of filePaths) {
701
+ const absPath = resolve(this.config.cwd, filePath);
702
+ const normalizedPath = normalize(absPath);
703
+ const baseline = this.currentTurn.baselines.get(normalizedPath);
704
+ if (!baseline) {
705
+ result.failed.push({
706
+ path: filePath,
707
+ reason: "File not tracked in current turn"
708
+ });
709
+ continue;
710
+ }
711
+ try {
712
+ await restoreTurnTrackedFile(absPath, baseline);
713
+ result.restored.push(filePath);
714
+ } catch (error) {
715
+ result.failed.push({
716
+ path: filePath,
717
+ reason: error instanceof Error ? error.message : String(error)
718
+ });
719
+ }
720
+ }
721
+ return result;
722
+ }
723
+ async computeFileChange(absPath, baseline) {
724
+ return await computeTurnTrackerFileChange({
725
+ cwd: this.config.cwd,
726
+ absPath,
727
+ baseline,
728
+ preferGitDiff: this.config.useGit,
729
+ canUseGitDiff: await this.isInGitRepo()
730
+ });
731
+ }
732
+ async isInGitRepo() {
733
+ if (!this.config.useGit) {
734
+ return false;
735
+ }
736
+ if (this.gitDetected !== null) {
737
+ return this.gitDetected;
738
+ }
739
+ return await new Promise((resolvePromise) => {
740
+ const proc = spawn("git", ["rev-parse", "--git-dir"], {
741
+ cwd: this.config.cwd,
742
+ stdio: ["ignore", "pipe", "pipe"]
743
+ });
744
+ proc.on("close", (code2) => {
745
+ this.gitDetected = code2 === 0;
746
+ resolvePromise(this.gitDetected);
747
+ });
748
+ proc.on("error", () => {
749
+ this.gitDetected = false;
750
+ resolvePromise(false);
751
+ });
752
+ });
753
+ }
754
+ };
755
+ function createTurnTracker(config, logger) {
756
+ return new TurnChangeTracker(config, logger);
757
+ }
758
+
759
+ // src/intervention/intervention.ts
760
+ var InterventionController = class {
761
+ /** Immediate interventions — applied at the next step boundary */
762
+ immediate = [];
763
+ /** Deferred messages — held until the turn completes */
764
+ deferred = [];
765
+ /**
766
+ * Callback fired when an intervention is wired into a step.
767
+ * Set by the Agent before starting a chat turn, cleared after.
768
+ */
769
+ onApplied;
770
+ /** Callback fired when a deferred follow-up is queued. */
771
+ onDeferredQueued;
772
+ // ---------------------------------------------------------------------------
773
+ // Immediate interventions (mid-turn redirect)
774
+ // ---------------------------------------------------------------------------
775
+ /**
776
+ * Inject a message at the next LLM step boundary.
777
+ *
778
+ * The message is appended as a user message to the conversation
779
+ * before the next LLM call in the current multi-step turn. The
780
+ * LLM will see it and can adjust its behavior accordingly.
781
+ *
782
+ * Safe to call from any async context while `chat()` is running.
783
+ * If called when no turn is active, the message will be picked up
784
+ * by the first step of the next `chat()` call.
785
+ *
786
+ * @param message - The user message to inject
787
+ * @returns Intervention ID for tracking
788
+ */
789
+ intervene(message) {
790
+ const id = crypto.randomUUID();
791
+ this.immediate.push(
792
+ Object.freeze({ id, message, createdAt: /* @__PURE__ */ new Date() })
793
+ );
794
+ return id;
795
+ }
796
+ /**
797
+ * Drain and return all pending immediate interventions.
798
+ * The internal queue is cleared atomically.
799
+ *
800
+ * @internal Called by the LLM stream's `prepareStep` hook
801
+ */
802
+ drainImmediate() {
803
+ if (this.immediate.length === 0) return [];
804
+ return this.immediate.splice(0);
805
+ }
806
+ /** Adopt existing immediate interventions without changing their IDs. */
807
+ adoptImmediate(items) {
808
+ if (items.length === 0) return;
809
+ this.immediate.push(...items);
810
+ }
811
+ /** Whether there are pending immediate interventions */
812
+ get hasPending() {
813
+ return this.immediate.length > 0;
814
+ }
815
+ /** Number of pending immediate interventions */
816
+ get pendingCount() {
817
+ return this.immediate.length;
818
+ }
819
+ // ---------------------------------------------------------------------------
820
+ // Deferred messages (after-turn follow-ups)
821
+ // ---------------------------------------------------------------------------
822
+ /**
823
+ * Queue a message for after the current turn completes.
824
+ *
825
+ * Unlike `intervene()`, this does **not** inject mid-turn. The
826
+ * message is held and available via `drainDeferred()` after
827
+ * `chat()` finishes. The consumer decides whether to send it
828
+ * as a new turn.
829
+ *
830
+ * @param message - The message to queue
831
+ * @returns Intervention ID for tracking
832
+ */
833
+ queueNext(message) {
834
+ const id = crypto.randomUUID();
835
+ const queued = Object.freeze({ id, message, createdAt: /* @__PURE__ */ new Date() });
836
+ this.deferred.push(queued);
837
+ this.onDeferredQueued?.(queued);
838
+ return id;
839
+ }
840
+ /**
841
+ * Drain and return all deferred messages.
842
+ * The internal queue is cleared atomically.
843
+ */
844
+ drainDeferred() {
845
+ if (this.deferred.length === 0) return [];
846
+ return this.deferred.splice(0);
847
+ }
848
+ /** Adopt existing deferred interventions without changing their IDs. */
849
+ adoptDeferred(items) {
850
+ if (items.length === 0) return;
851
+ this.deferred.push(...items);
852
+ }
853
+ /** Whether there are deferred messages */
854
+ get hasDeferred() {
855
+ return this.deferred.length > 0;
856
+ }
857
+ /** Number of deferred messages */
858
+ get deferredCount() {
859
+ return this.deferred.length;
860
+ }
861
+ // ---------------------------------------------------------------------------
862
+ // Housekeeping
863
+ // ---------------------------------------------------------------------------
864
+ /** Clear all queues (immediate + deferred) */
865
+ clear() {
866
+ this.immediate.length = 0;
867
+ this.deferred.length = 0;
868
+ }
869
+ /** Reset the controller for a new turn (clears onApplied, keeps queues) */
870
+ resetCallbacks() {
871
+ this.onApplied = void 0;
872
+ this.onDeferredQueued = void 0;
873
+ }
874
+ };
875
+
876
+ // src/agent/runtime-config.ts
877
+ function createAgentToolRecord(tools) {
878
+ const toolRecord = {};
879
+ for (const [id, tool] of tools) {
880
+ toolRecord[id] = tool;
881
+ }
882
+ return toolRecord;
883
+ }
884
+ function buildFallbackCompactionSummary(messages) {
885
+ const excerpt = messages.map((message) => {
886
+ const role = message.role.toUpperCase();
887
+ const content = typeof message.content === "string" ? message.content : JSON.stringify(message.content);
888
+ return `[${role}] ${content}`;
889
+ }).join("\n\n");
890
+ const trimmed = excerpt.length > 8e3 ? `${excerpt.slice(0, 8e3)}
891
+
892
+ ...[truncated during compaction]` : excerpt;
893
+ return trimmed.length > 0 ? trimmed : "Earlier conversation context was compacted.";
894
+ }
895
+ async function compactAgentContext(options) {
896
+ const { contextManager, sessions, logger } = options;
897
+ const log = logger ?? silentLogger;
898
+ const messages = getVisibleSessionMessages(sessions);
899
+ if (!contextManager.shouldPrune(messages)) {
900
+ return {
901
+ removedCount: 0,
902
+ tokensRemoved: 0,
903
+ summarized: false,
904
+ summary: void 0
905
+ };
906
+ }
907
+ const tokensBefore = estimateConversationTokens(messages);
908
+ let removedCount = 0;
909
+ let summarized = false;
910
+ let summary;
911
+ try {
912
+ const result = await contextManager.prune(messages);
913
+ removedCount = result.removedCount;
914
+ summarized = result.summarized;
915
+ summary = result.summary;
916
+ } catch (pruneError) {
917
+ log.warn("Context compaction LLM summarisation failed, using fallback", {
918
+ error: pruneError instanceof Error ? pruneError.message : String(pruneError)
919
+ });
920
+ }
921
+ if (removedCount === 0) {
922
+ removedCount = findCutPoint(
923
+ messages,
924
+ contextManager.getLimits().protectedTokens
925
+ );
926
+ }
927
+ if (removedCount === 0) {
928
+ return {
929
+ removedCount: 0,
930
+ tokensRemoved: 0,
931
+ summarized: false,
932
+ summary: void 0
933
+ };
934
+ }
935
+ const summaryText = summary ?? buildFallbackCompactionSummary(messages.slice(0, removedCount));
936
+ const keptMessages = messages.slice(removedCount);
937
+ const persistedMessages = [
938
+ {
939
+ id: "compaction-preview",
940
+ role: "system",
941
+ content: `## Previous Conversation Summary
942
+
943
+ ${summaryText}`,
944
+ createdAt: /* @__PURE__ */ new Date()
945
+ },
946
+ ...keptMessages
947
+ ];
948
+ const tokensAfter = estimateConversationTokens(persistedMessages);
949
+ await sessions.replaceWithCompaction({
950
+ summary: summaryText,
951
+ messages: keptMessages,
952
+ tokensBefore,
953
+ tokensAfter
954
+ });
955
+ return {
956
+ removedCount,
957
+ tokensRemoved: Math.max(0, tokensBefore - tokensAfter),
958
+ summarized,
959
+ summary: summaryText
960
+ };
961
+ }
962
+ async function buildAgentSystemPrompts(options) {
963
+ const {
964
+ config,
965
+ toolIds,
966
+ sessionId,
967
+ override,
968
+ promptBuilder,
969
+ middlewareRunner
970
+ } = options;
971
+ if (promptBuilder) {
972
+ const composedPrompt = await promptBuilder.build(
973
+ {
974
+ cwd: config.cwd,
975
+ model: config.model,
976
+ toolNames: toolIds,
977
+ ...override ? { override } : {},
978
+ sessionId
979
+ },
980
+ middlewareRunner
981
+ );
982
+ return [composedPrompt];
983
+ }
984
+ const prompts = [config.systemPrompt];
985
+ if (override) {
986
+ prompts.push(override);
987
+ }
988
+ return prompts;
989
+ }
990
+ function createAgentTurnRuntimeConfig(options) {
991
+ const { config, telemetrySettings } = options;
992
+ return {
993
+ model: config.model,
994
+ cwd: config.cwd,
995
+ ...config.temperature !== void 0 ? { temperature: config.temperature } : {},
996
+ ...config.topP !== void 0 ? { topP: config.topP } : {},
997
+ ...config.maxOutputTokens !== void 0 ? { maxOutputTokens: config.maxOutputTokens } : {},
998
+ maxSteps: config.maxSteps,
999
+ ...config.doomLoopThreshold !== void 0 ? { doomLoopThreshold: config.doomLoopThreshold } : {},
1000
+ ...config.enforceDoomLoop !== void 0 ? { enforceDoomLoop: config.enforceDoomLoop } : {},
1001
+ ...config.onDoomLoop ? { onDoomLoop: config.onDoomLoop } : {},
1002
+ ...config.contextWindow !== void 0 ? { contextWindow: config.contextWindow } : {},
1003
+ ...options.reserveTokens !== void 0 ? { reserveTokens: options.reserveTokens } : {},
1004
+ ...config.streamProvider ? { streamProvider: config.streamProvider } : {},
1005
+ ...telemetrySettings ? { telemetry: telemetrySettings } : {}
1006
+ };
1007
+ }
271
1008
 
272
1009
  // src/agent/chat-loop/commit.ts
273
1010
  function createChatLoopCommitBatchApplier(params) {
@@ -290,18 +1027,29 @@ function createChatLoopCommitBatchApplier(params) {
290
1027
 
291
1028
  // src/agent/chat-loop/compaction.ts
292
1029
  async function runAutoCompaction(params) {
293
- const { contextManager, messages } = params;
1030
+ const { contextManager, sessions, logger } = params;
1031
+ const messages = sessions.getMessages();
294
1032
  if (!contextManager.shouldPrune(messages)) {
295
1033
  return [];
296
1034
  }
297
1035
  const events = [{ type: "status", status: "processing" }];
298
- const pruneResult = await contextManager.prune(messages);
299
- if (pruneResult.removedCount > 0 || pruneResult.summarized) {
300
- const limits = contextManager.getLimits();
301
- events.push({
302
- type: "context-overflow",
303
- inputTokens: estimateConversationTokens(messages),
304
- limit: limits.contextWindow - limits.reserveTokens
1036
+ try {
1037
+ const pruneResult = await compactAgentContext({
1038
+ contextManager,
1039
+ sessions,
1040
+ logger
1041
+ });
1042
+ if (pruneResult.removedCount > 0 || pruneResult.summarized) {
1043
+ const limits = contextManager.getLimits();
1044
+ events.push({
1045
+ type: "context-overflow",
1046
+ inputTokens: estimateConversationTokens(messages),
1047
+ limit: getUsableTokenLimit(limits)
1048
+ });
1049
+ }
1050
+ } catch (error) {
1051
+ logger?.warn("Auto-compaction failed, continuing without compaction", {
1052
+ error: error instanceof Error ? error.message : String(error)
305
1053
  });
306
1054
  }
307
1055
  return events;
@@ -309,49 +1057,14 @@ async function runAutoCompaction(params) {
309
1057
 
310
1058
  // src/agent/chat-loop/prompts.ts
311
1059
  async function buildChatSystemPrompts(params) {
312
- const {
313
- promptBuilder,
314
- middlewareRunner,
315
- systemOverride,
316
- sessionId,
317
- config,
318
- tools
319
- } = params;
320
- if (promptBuilder) {
321
- const composedPrompt = await promptBuilder.build(
322
- {
323
- cwd: config.cwd,
324
- model: config.model,
325
- toolNames: Object.keys(tools),
326
- override: systemOverride,
327
- sessionId
328
- },
329
- middlewareRunner
330
- );
331
- return [composedPrompt];
332
- }
333
- const prompts = [config.systemPrompt];
334
- if (systemOverride) {
335
- prompts.push(systemOverride);
336
- }
337
- return prompts;
338
- }
339
-
340
- // src/agent/chat-loop/usage.ts
341
- function accumulateUsage(current, next) {
342
- if (!next) return current;
343
- if (!current) {
344
- return {
345
- inputTokens: next.inputTokens ?? 0,
346
- outputTokens: next.outputTokens ?? 0,
347
- totalTokens: next.totalTokens ?? 0
348
- };
349
- }
350
- return {
351
- inputTokens: (current.inputTokens ?? 0) + (next.inputTokens ?? 0),
352
- outputTokens: (current.outputTokens ?? 0) + (next.outputTokens ?? 0),
353
- totalTokens: (current.totalTokens ?? 0) + (next.totalTokens ?? 0)
354
- };
1060
+ return buildAgentSystemPrompts({
1061
+ config: params.config,
1062
+ toolIds: Object.keys(params.tools),
1063
+ sessionId: params.sessionId,
1064
+ override: params.systemOverride,
1065
+ promptBuilder: params.promptBuilder,
1066
+ middlewareRunner: params.middlewareRunner
1067
+ });
355
1068
  }
356
1069
 
357
1070
  // src/agent/chat-loop/loop.ts
@@ -365,11 +1078,12 @@ async function* runChatLoop(deps) {
365
1078
  (async function* () {
366
1079
  const {
367
1080
  sessionId,
1081
+ turnId,
368
1082
  message,
369
1083
  abort,
370
1084
  systemOverride,
371
1085
  sessions,
372
- tools: toolRecord,
1086
+ tools: liveTools,
373
1087
  config,
374
1088
  turnTracker,
375
1089
  interventionCtrl,
@@ -379,10 +1093,13 @@ async function* runChatLoop(deps) {
379
1093
  reasoningLevel,
380
1094
  promptBuilder,
381
1095
  host,
1096
+ humanInputController,
382
1097
  mcpTools,
383
1098
  toModelMessages,
384
1099
  setIsStreaming
385
1100
  } = deps;
1101
+ let toolRecord = createAgentToolRecord(liveTools);
1102
+ const isPlanMode = deps.toolExecutionMode === "plan";
386
1103
  const turnEngine = createAgentTurnEngine({
387
1104
  sessionId,
388
1105
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -407,20 +1124,24 @@ async function* runChatLoop(deps) {
407
1124
  let chatOutput;
408
1125
  try {
409
1126
  if (middlewareRunner.hasMiddleware) {
410
- await middlewareRunner.runChatStart(sessionId, message);
1127
+ await middlewareRunner.runChatStart(sessionId, message, {
1128
+ sessionId,
1129
+ turnId
1130
+ });
411
1131
  }
412
- const systemPrompts = await buildChatSystemPrompts({
413
- promptBuilder,
414
- middlewareRunner,
415
- systemOverride,
416
- sessionId,
417
- config,
418
- tools: toolRecord
419
- });
420
1132
  let step = 1;
421
1133
  let finalStepText = "";
422
1134
  let accumulatedUsage;
423
1135
  while (step <= config.maxSteps) {
1136
+ toolRecord = createAgentToolRecord(liveTools);
1137
+ const systemPrompts = await buildChatSystemPrompts({
1138
+ promptBuilder,
1139
+ middlewareRunner,
1140
+ systemOverride,
1141
+ sessionId,
1142
+ config,
1143
+ tools: toolRecord
1144
+ });
424
1145
  const preparedStep = prepareModelStep({
425
1146
  sessionId,
426
1147
  step,
@@ -432,10 +1153,12 @@ async function* runChatLoop(deps) {
432
1153
  mcpTools,
433
1154
  config,
434
1155
  host,
1156
+ humanInputController,
435
1157
  turnTracker,
436
1158
  intervention: interventionCtrl,
437
1159
  middleware: middlewareRunner,
438
- reasoningLevel
1160
+ reasoningLevel,
1161
+ toolExecutionMode: deps.toolExecutionMode
439
1162
  });
440
1163
  const stepResult = yield* runModelStep({
441
1164
  preparedStep,
@@ -448,6 +1171,7 @@ async function* runChatLoop(deps) {
448
1171
  chatError = stepResult.error;
449
1172
  return;
450
1173
  }
1174
+ const planSnapshot = isPlanMode && stepResult.finishReason === "tool-calls" ? turnEngine.createStepCommitSnapshot() : void 0;
451
1175
  yield* commitStep({
452
1176
  step,
453
1177
  finishReason: stepResult.finishReason,
@@ -468,6 +1192,31 @@ async function* runChatLoop(deps) {
468
1192
  yield errorEvent;
469
1193
  return;
470
1194
  }
1195
+ if (isPlanMode && planSnapshot && planSnapshot.toolCalls.length > 0) {
1196
+ const batchResult = await runToolBatch({
1197
+ sessionId,
1198
+ snapshot: planSnapshot,
1199
+ tools: toolRecord,
1200
+ cwd: config.cwd,
1201
+ abort,
1202
+ host,
1203
+ humanInputController,
1204
+ turnTracker,
1205
+ middleware: middlewareRunner,
1206
+ intervention: interventionCtrl
1207
+ });
1208
+ for (const event of batchResult.events) {
1209
+ turnEngine.recordEvent(event, (/* @__PURE__ */ new Date()).toISOString());
1210
+ middlewareRunner.emitEvent(event);
1211
+ yield event;
1212
+ }
1213
+ yield* commitStep({
1214
+ step,
1215
+ finishReason: "tool-calls",
1216
+ turnEngine,
1217
+ applyCommitBatch
1218
+ });
1219
+ }
471
1220
  step += 1;
472
1221
  continue;
473
1222
  }
@@ -483,7 +1232,8 @@ async function* runChatLoop(deps) {
483
1232
  if (config.compaction?.auto !== false) {
484
1233
  const compactionEvents = await runAutoCompaction({
485
1234
  contextManager,
486
- messages: sessions.getMessages()
1235
+ sessions,
1236
+ logger: deps.logger
487
1237
  });
488
1238
  for (const event of compactionEvents) {
489
1239
  yield event;
@@ -513,6 +1263,12 @@ async function* runChatLoop(deps) {
513
1263
  };
514
1264
  } catch (error) {
515
1265
  chatError = error instanceof Error ? error : new Error(String(error));
1266
+ const statusEvent = { type: "status", status: "error" };
1267
+ middlewareRunner.emitEvent(statusEvent);
1268
+ yield statusEvent;
1269
+ const errorEvent = { type: "error", error: chatError };
1270
+ middlewareRunner.emitEvent(errorEvent);
1271
+ yield errorEvent;
516
1272
  throw error;
517
1273
  } finally {
518
1274
  setIsStreaming(false);
@@ -522,6 +1278,9 @@ async function* runChatLoop(deps) {
522
1278
  usage: chatUsage,
523
1279
  error: chatError,
524
1280
  output: chatOutput
1281
+ }, {
1282
+ sessionId,
1283
+ turnId
525
1284
  });
526
1285
  }
527
1286
  }
@@ -531,10 +1290,10 @@ async function* runChatLoop(deps) {
531
1290
 
532
1291
  // src/agent/fork.ts
533
1292
  function resolveForkOptions(options, parentTools, systemPrompt) {
534
- if (!options.preset) {
1293
+ if (!options.profile) {
535
1294
  return options;
536
1295
  }
537
- const applied = applyPreset(options.preset, parentTools, systemPrompt);
1296
+ const applied = applyProfile(options.profile, parentTools, systemPrompt);
538
1297
  return {
539
1298
  ...applied,
540
1299
  ...options,
@@ -573,6 +1332,9 @@ function createForkedAgentConfig(options) {
573
1332
  parentTools,
574
1333
  reasoningLevel,
575
1334
  host,
1335
+ sandbox,
1336
+ humanInputController,
1337
+ ownsHost,
576
1338
  sessions,
577
1339
  mcpManager,
578
1340
  middlewareRunner,
@@ -588,7 +1350,8 @@ function createForkedAgentConfig(options) {
588
1350
  return {
589
1351
  model: forkOptions.model ?? parentConfig.model,
590
1352
  cwd: parentConfig.cwd,
591
- host,
1353
+ ...ownsHost ? {} : sandbox !== void 0 ? { sandbox } : { host },
1354
+ ...humanInputController ? { humanInput: humanInputController } : {},
592
1355
  maxOutputTokens: parentConfig.maxOutputTokens,
593
1356
  maxSteps: forkOptions.maxSteps ?? parentConfig.maxSteps,
594
1357
  temperature: forkOptions.temperature ?? parentConfig.temperature,
@@ -608,7 +1371,7 @@ function createForkedAgentConfig(options) {
608
1371
  }
609
1372
 
610
1373
  // src/agent/mcp-bridge.ts
611
- async function ensureMcpTools(state) {
1374
+ async function ensureMcpTools(state, logger) {
612
1375
  if (!state.manager) {
613
1376
  return { connected: false, cachedTools: void 0 };
614
1377
  }
@@ -618,17 +1381,18 @@ async function ensureMcpTools(state) {
618
1381
  cachedTools: state.cachedTools
619
1382
  };
620
1383
  }
1384
+ const log = logger.child("mcp");
621
1385
  const statuses = await state.manager.connect();
622
1386
  let connectedCount = 0;
623
1387
  for (const [name, status] of statuses) {
624
1388
  if (status.status === "connected") {
625
1389
  connectedCount++;
626
1390
  } else if (status.status === "error") {
627
- console.warn(`[mcp] Failed to connect to ${name}: ${status.error}`);
1391
+ log.warn(`Failed to connect to ${name}: ${status.error}`);
628
1392
  }
629
1393
  }
630
1394
  if (connectedCount === 0 && statuses.size > 0) {
631
- console.warn("[mcp] No MCP servers connected successfully");
1395
+ log.warn("No MCP servers connected successfully");
632
1396
  }
633
1397
  const cachedTools = await state.manager.getTools();
634
1398
  return {
@@ -646,161 +1410,392 @@ async function closeMcpManager(manager) {
646
1410
  };
647
1411
  }
648
1412
 
649
- // src/agent/session.ts
650
- async function ensureSessionLoaded(options) {
651
- const { sessionId, sessions, loadedSessions, cwd } = options;
652
- if (loadedSessions.has(sessionId) && sessions.getSessionId() === sessionId) {
653
- return;
1413
+ // src/signal/local.ts
1414
+ var LocalSignal = class {
1415
+ /** type Set<handler> for typed subscriptions */
1416
+ typed = /* @__PURE__ */ new Map();
1417
+ /** handlers that receive every event */
1418
+ wildcard = /* @__PURE__ */ new Set();
1419
+ on(type, handler) {
1420
+ let set = this.typed.get(type);
1421
+ if (!set) {
1422
+ set = /* @__PURE__ */ new Set();
1423
+ this.typed.set(type, set);
1424
+ }
1425
+ const wrapped = (event) => {
1426
+ handler(event);
1427
+ };
1428
+ set.add(wrapped);
1429
+ return () => {
1430
+ set.delete(wrapped);
1431
+ if (set.size === 0) this.typed.delete(type);
1432
+ };
654
1433
  }
655
- const exists = await sessions.sessionExists(sessionId);
656
- if (exists) {
657
- await sessions.load(sessionId);
658
- } else {
659
- await sessions.create({ id: sessionId, cwd });
1434
+ onAny(handler) {
1435
+ this.wildcard.add(handler);
1436
+ return () => {
1437
+ this.wildcard.delete(handler);
1438
+ };
660
1439
  }
661
- loadedSessions.add(sessionId);
662
- }
663
- async function repairOrphanedToolCalls(sessions) {
664
- const messages = sessions.getMessages();
665
- const pendingCallIds = /* @__PURE__ */ new Map();
666
- for (const message of messages) {
667
- if (message.role === "assistant" && message.toolCalls) {
668
- for (const toolCall of message.toolCalls) {
669
- pendingCallIds.set(toolCall.toolCallId, { toolName: toolCall.toolName });
1440
+ emit(event) {
1441
+ const set = this.typed.get(event.type);
1442
+ if (set) {
1443
+ for (const fn of set) {
1444
+ try {
1445
+ fn(event);
1446
+ } catch {
1447
+ }
670
1448
  }
671
1449
  }
672
- if (message.role === "tool" && message.toolCallId) {
673
- pendingCallIds.delete(message.toolCallId);
1450
+ for (const fn of this.wildcard) {
1451
+ try {
1452
+ fn(event);
1453
+ } catch {
1454
+ }
674
1455
  }
675
1456
  }
676
- for (const [toolCallId, { toolName }] of pendingCallIds) {
677
- const toolMessage = {
678
- id: crypto.randomUUID(),
679
- role: "tool",
680
- content: "Error: tool execution failed (result was not recorded)",
681
- toolCallId,
682
- toolName,
683
- result: "Error: tool execution failed (result was not recorded)",
684
- createdAt: /* @__PURE__ */ new Date()
685
- };
686
- await sessions.addMessage(toolMessage);
1457
+ clear() {
1458
+ this.typed.clear();
1459
+ this.wildcard.clear();
687
1460
  }
688
- }
689
- async function createSubAgentRunSession(options) {
690
- const sessionId = options.parentSessionId ? `${options.parentSessionId}:sub:${crypto.randomUUID().slice(0, 8)}` : `sub:${crypto.randomUUID().slice(0, 8)}`;
691
- await options.sessions.create({
692
- id: sessionId,
693
- cwd: options.cwd,
694
- title: options.title ?? "Sub-agent task",
695
- parentSessionId: options.parentSessionId
696
- });
697
- options.loadedSessions.add(sessionId);
698
- return sessionId;
699
- }
1461
+ };
700
1462
 
701
- // src/agent/intervention.ts
702
- var InterventionController = class {
703
- /** Immediate interventions — applied at the next step boundary */
704
- immediate = [];
705
- /** Deferred messages — held until the turn completes */
706
- deferred = [];
707
- /**
708
- * Callback fired when an intervention is wired into a step.
709
- * Set by the Agent before starting a chat turn, cleared after.
710
- */
711
- onApplied;
712
- // ---------------------------------------------------------------------------
713
- // Immediate interventions (mid-turn redirect)
714
- // ---------------------------------------------------------------------------
715
- /**
716
- * Inject a message at the next LLM step boundary.
717
- *
718
- * The message is appended as a user message to the conversation
719
- * before the next LLM call in the current multi-step turn. The
720
- * LLM will see it and can adjust its behavior accordingly.
721
- *
722
- * Safe to call from any async context while `chat()` is running.
723
- * If called when no turn is active, the message will be picked up
724
- * by the first step of the next `chat()` call.
725
- *
726
- * @param message - The user message to inject
727
- * @returns Intervention ID for tracking
728
- */
729
- intervene(message) {
730
- const id = crypto.randomUUID();
731
- this.immediate.push(
732
- Object.freeze({ id, message, createdAt: /* @__PURE__ */ new Date() })
733
- );
734
- return id;
735
- }
736
- /**
737
- * Drain and return all pending immediate interventions.
738
- * The internal queue is cleared atomically.
739
- *
740
- * @internal Called by the LLM stream's `prepareStep` hook
741
- */
742
- drainImmediate() {
743
- if (this.immediate.length === 0) return [];
744
- return this.immediate.splice(0);
1463
+ // src/human/controller.ts
1464
+ var HumanInputTimeoutError = class extends Error {
1465
+ constructor(timeoutMs) {
1466
+ super(`Human input request timed out after ${timeoutMs}ms`);
1467
+ this.name = "HumanInputTimeoutError";
745
1468
  }
746
- /** Whether there are pending immediate interventions */
747
- get hasPending() {
748
- return this.immediate.length > 0;
1469
+ };
1470
+ var HumanInputUnavailableError = class extends Error {
1471
+ constructor() {
1472
+ super("No human input controller configured");
1473
+ this.name = "HumanInputUnavailableError";
749
1474
  }
750
- /** Number of pending immediate interventions */
751
- get pendingCount() {
752
- return this.immediate.length;
1475
+ };
1476
+ function cloneRecord(record) {
1477
+ return structuredClone(record);
1478
+ }
1479
+ function normalizeStatuses(status) {
1480
+ if (!status) {
1481
+ return void 0;
753
1482
  }
754
- // ---------------------------------------------------------------------------
755
- // Deferred messages (after-turn follow-ups)
756
- // ---------------------------------------------------------------------------
757
- /**
758
- * Queue a message for after the current turn completes.
759
- *
760
- * Unlike `intervene()`, this does **not** inject mid-turn. The
761
- * message is held and available via `drainDeferred()` after
762
- * `chat()` finishes. The consumer decides whether to send it
763
- * as a new turn.
764
- *
765
- * @param message - The message to queue
766
- * @returns Intervention ID for tracking
767
- */
768
- queueNext(message) {
769
- const id = crypto.randomUUID();
770
- this.deferred.push(
771
- Object.freeze({ id, message, createdAt: /* @__PURE__ */ new Date() })
772
- );
773
- return id;
1483
+ return new Set(Array.isArray(status) ? status : [status]);
1484
+ }
1485
+ function inferKind(input) {
1486
+ if (input.kind) {
1487
+ return input.kind;
774
1488
  }
775
- /**
776
- * Drain and return all deferred messages.
777
- * The internal queue is cleared atomically.
778
- */
779
- drainDeferred() {
780
- if (this.deferred.length === 0) return [];
781
- return this.deferred.splice(0);
1489
+ if (input.options && input.options.length > 0) {
1490
+ return "choice";
782
1491
  }
783
- /** Whether there are deferred messages */
784
- get hasDeferred() {
785
- return this.deferred.length > 0;
1492
+ return "text";
1493
+ }
1494
+ function isHumanInputController(value) {
1495
+ if (!value || typeof value !== "object") {
1496
+ return false;
786
1497
  }
787
- /** Number of deferred messages */
788
- get deferredCount() {
789
- return this.deferred.length;
1498
+ const candidate = value;
1499
+ return typeof candidate.request === "function" && typeof candidate.respondToRequest === "function" && typeof candidate.getRequest === "function" && typeof candidate.listRequests === "function" && typeof candidate.cancelAll === "function";
1500
+ }
1501
+ async function emitHumanInputEvent(context, event) {
1502
+ await context?.emitEvent?.(event);
1503
+ }
1504
+ function createHumanInputController(config = {}) {
1505
+ const timeout = config.timeout ?? 5 * 60 * 1e3;
1506
+ let requestCounter = 0;
1507
+ const pending = /* @__PURE__ */ new Map();
1508
+ async function request(sessionId, input, context = {}) {
1509
+ const requestPayload = {
1510
+ id: `human-input-${++requestCounter}-${Date.now()}`,
1511
+ sessionId,
1512
+ kind: inferKind(input),
1513
+ title: input.title,
1514
+ question: input.question,
1515
+ ...input.options ? { options: input.options.map((option) => ({ ...option })) } : {},
1516
+ ...input.allowMultiple !== void 0 ? { allowMultiple: input.allowMultiple } : {},
1517
+ ...input.placeholder ? { placeholder: input.placeholder } : {},
1518
+ ...input.confirmLabel ? { confirmLabel: input.confirmLabel } : {},
1519
+ ...input.denyLabel ? { denyLabel: input.denyLabel } : {},
1520
+ ...input.toolCallId ? { toolCallId: input.toolCallId } : {},
1521
+ timestamp: Date.now()
1522
+ };
1523
+ const record = {
1524
+ id: requestPayload.id,
1525
+ sessionId,
1526
+ request: structuredClone(requestPayload),
1527
+ status: "pending",
1528
+ createdAt: requestPayload.timestamp,
1529
+ updatedAt: requestPayload.timestamp
1530
+ };
1531
+ const responsePromise = new Promise((resolve2, reject) => {
1532
+ const timeoutId = setTimeout(() => {
1533
+ const current2 = pending.get(record.id);
1534
+ if (!current2) {
1535
+ return;
1536
+ }
1537
+ pending.delete(record.id);
1538
+ current2.record = {
1539
+ ...current2.record,
1540
+ status: "timed-out",
1541
+ updatedAt: Date.now()
1542
+ };
1543
+ void emitHumanInputEvent(
1544
+ { emitEvent: current2.emitEvent },
1545
+ { type: "status", status: "processing" }
1546
+ );
1547
+ reject(new HumanInputTimeoutError(timeout));
1548
+ }, timeout);
1549
+ pending.set(record.id, {
1550
+ record,
1551
+ resolve: resolve2,
1552
+ reject,
1553
+ ready: Promise.resolve(),
1554
+ timeoutId,
1555
+ emitEvent: context.emitEvent
1556
+ });
1557
+ });
1558
+ const current = pending.get(record.id);
1559
+ if (current) {
1560
+ current.ready = (async () => {
1561
+ await emitHumanInputEvent(context, {
1562
+ type: "status",
1563
+ status: "waiting-input"
1564
+ });
1565
+ await emitHumanInputEvent(context, {
1566
+ type: "human-input-request",
1567
+ request: {
1568
+ id: requestPayload.id,
1569
+ kind: requestPayload.kind,
1570
+ title: requestPayload.title,
1571
+ question: requestPayload.question,
1572
+ ...requestPayload.options ? { options: requestPayload.options } : {},
1573
+ ...requestPayload.allowMultiple !== void 0 ? { allowMultiple: requestPayload.allowMultiple } : {},
1574
+ ...requestPayload.placeholder ? { placeholder: requestPayload.placeholder } : {},
1575
+ ...requestPayload.confirmLabel ? { confirmLabel: requestPayload.confirmLabel } : {},
1576
+ ...requestPayload.denyLabel ? { denyLabel: requestPayload.denyLabel } : {}
1577
+ }
1578
+ });
1579
+ })();
1580
+ }
1581
+ if (config.onRequest) {
1582
+ void (async () => {
1583
+ try {
1584
+ await pending.get(record.id)?.ready;
1585
+ const response = await config.onRequest(requestPayload);
1586
+ await respondToRequest(record.id, response, context);
1587
+ } catch (error) {
1588
+ if (error instanceof HumanInputTimeoutError) {
1589
+ return;
1590
+ }
1591
+ const current2 = pending.get(record.id);
1592
+ if (!current2) {
1593
+ return;
1594
+ }
1595
+ pending.delete(record.id);
1596
+ clearTimeout(current2.timeoutId);
1597
+ current2.record = {
1598
+ ...current2.record,
1599
+ status: "cancelled",
1600
+ updatedAt: Date.now()
1601
+ };
1602
+ current2.reject(
1603
+ error instanceof Error ? error : new Error(String(error))
1604
+ );
1605
+ await emitHumanInputEvent(
1606
+ { emitEvent: current2.emitEvent },
1607
+ { type: "status", status: "processing" }
1608
+ );
1609
+ }
1610
+ })();
1611
+ }
1612
+ return await responsePromise;
790
1613
  }
791
- // ---------------------------------------------------------------------------
792
- // Housekeeping
793
- // ---------------------------------------------------------------------------
794
- /** Clear all queues (immediate + deferred) */
795
- clear() {
796
- this.immediate.length = 0;
797
- this.deferred.length = 0;
1614
+ async function respondToRequest(requestId, response, context = {}) {
1615
+ const current = pending.get(requestId);
1616
+ if (!current) {
1617
+ throw new Error(`Human input request not found: ${requestId}`);
1618
+ }
1619
+ await current.ready;
1620
+ pending.delete(requestId);
1621
+ clearTimeout(current.timeoutId);
1622
+ const respondedAt = Date.now();
1623
+ const next = {
1624
+ ...current.record,
1625
+ status: "answered",
1626
+ updatedAt: respondedAt,
1627
+ respondedAt,
1628
+ response: structuredClone(response)
1629
+ };
1630
+ current.resolve(response);
1631
+ const emitEvent = context.emitEvent ?? current.emitEvent;
1632
+ await emitHumanInputEvent(
1633
+ { emitEvent },
1634
+ {
1635
+ type: "human-input-resolved",
1636
+ id: requestId,
1637
+ response
1638
+ }
1639
+ );
1640
+ await emitHumanInputEvent(
1641
+ { emitEvent },
1642
+ { type: "status", status: "processing" }
1643
+ );
1644
+ return cloneRecord(next);
798
1645
  }
799
- /** Reset the controller for a new turn (clears onApplied, keeps queues) */
800
- resetCallbacks() {
801
- this.onApplied = void 0;
1646
+ function getRequest(requestId) {
1647
+ const current = pending.get(requestId);
1648
+ return current ? cloneRecord(current.record) : void 0;
802
1649
  }
803
- };
1650
+ function listRequests(options = {}) {
1651
+ const statuses = normalizeStatuses(options.status);
1652
+ return [...pending.values()].map((entry) => cloneRecord(entry.record)).filter((record) => {
1653
+ if (options.sessionId && record.sessionId !== options.sessionId) {
1654
+ return false;
1655
+ }
1656
+ if (statuses && !statuses.has(record.status)) {
1657
+ return false;
1658
+ }
1659
+ return true;
1660
+ }).sort((left, right) => left.createdAt - right.createdAt);
1661
+ }
1662
+ function cancelAll(reason = "Cancelled") {
1663
+ for (const [requestId, current] of pending) {
1664
+ pending.delete(requestId);
1665
+ clearTimeout(current.timeoutId);
1666
+ current.record = {
1667
+ ...current.record,
1668
+ status: "cancelled",
1669
+ updatedAt: Date.now()
1670
+ };
1671
+ current.reject(new Error(reason));
1672
+ void emitHumanInputEvent(
1673
+ { emitEvent: current.emitEvent },
1674
+ { type: "status", status: "processing" }
1675
+ );
1676
+ }
1677
+ }
1678
+ return {
1679
+ get hasPendingRequests() {
1680
+ return pending.size > 0;
1681
+ },
1682
+ request,
1683
+ respondToRequest,
1684
+ getRequest,
1685
+ listRequests,
1686
+ cancelAll
1687
+ };
1688
+ }
1689
+
1690
+ // src/human/handler.ts
1691
+ function createHumanInputHandler(config = {}) {
1692
+ return createHumanInputController(config);
1693
+ }
1694
+
1695
+ // src/human/tool.ts
1696
+ import { z } from "zod";
1697
+ function createHumanInputTool(options = {}) {
1698
+ if (options.controller) {
1699
+ return createHumanInputToolWithController(options.controller, options);
1700
+ }
1701
+ if (options.onRequest || options.timeout !== void 0) {
1702
+ return createHumanInputToolWithController(
1703
+ createHumanInputController(options),
1704
+ options
1705
+ );
1706
+ }
1707
+ return createHumanInputToolWithController(void 0, options);
1708
+ }
1709
+ function createHumanInputToolWithController(controller, options = {}) {
1710
+ return Tool.define(
1711
+ options.name ?? "question",
1712
+ {
1713
+ description: options.description ?? "Ask a human for missing input, a decision, a confirmation, or a choice.",
1714
+ parameters: z.object({
1715
+ title: z.string().min(1).describe("Short heading for the request"),
1716
+ question: z.string().min(1).describe("What to ask the human"),
1717
+ kind: z.enum(["text", "confirm", "choice"]).optional(),
1718
+ options: z.array(
1719
+ z.object({
1720
+ label: z.string().min(1),
1721
+ value: z.string().optional(),
1722
+ description: z.string().optional()
1723
+ })
1724
+ ).optional(),
1725
+ allowMultiple: z.boolean().optional(),
1726
+ placeholder: z.string().optional(),
1727
+ confirmLabel: z.string().optional(),
1728
+ denyLabel: z.string().optional()
1729
+ }),
1730
+ validate: (params) => {
1731
+ const kind = params.kind ?? (params.options?.length ? "choice" : "text");
1732
+ if (kind === "choice" && (!params.options || params.options.length === 0)) {
1733
+ return {
1734
+ ok: false,
1735
+ reason: "Choice requests must include at least one option."
1736
+ };
1737
+ }
1738
+ if (kind !== "choice" && params.allowMultiple) {
1739
+ return {
1740
+ ok: false,
1741
+ reason: "allowMultiple is only valid for choice requests."
1742
+ };
1743
+ }
1744
+ return { ok: true };
1745
+ },
1746
+ capabilities: {
1747
+ readOnly: true,
1748
+ riskLevel: "safe",
1749
+ parallelSafe: false,
1750
+ humanInput: true
1751
+ },
1752
+ replayPolicy: {
1753
+ mode: "manual",
1754
+ sideEffectLevel: "external",
1755
+ reason: "Depends on a human response before execution can continue."
1756
+ },
1757
+ execute: async (params, ctx) => {
1758
+ let response;
1759
+ try {
1760
+ const activeController = controller ?? ctx.humanInputController;
1761
+ if (!activeController) {
1762
+ throw new HumanInputUnavailableError();
1763
+ }
1764
+ response = await activeController.request(ctx.sessionID, {
1765
+ ...params,
1766
+ toolCallId: typeof ctx.extra?.toolCallId === "string" ? ctx.extra.toolCallId : ctx.messageID
1767
+ }, {
1768
+ emitEvent: ctx.emitEvent
1769
+ });
1770
+ } catch (error) {
1771
+ if (error instanceof HumanInputUnavailableError) {
1772
+ throw error;
1773
+ }
1774
+ throw error;
1775
+ }
1776
+ return {
1777
+ title: params.title,
1778
+ output: response.text,
1779
+ metadata: { response }
1780
+ };
1781
+ }
1782
+ },
1783
+ {
1784
+ replayPolicy: {
1785
+ mode: "manual",
1786
+ sideEffectLevel: "external",
1787
+ reason: "Depends on a human response before execution can continue."
1788
+ },
1789
+ capabilitiesHint: {
1790
+ readOnly: true,
1791
+ riskLevel: "safe",
1792
+ parallelSafe: false,
1793
+ humanInput: true
1794
+ }
1795
+ }
1796
+ );
1797
+ }
1798
+ var createHumanInputToolWithHandler = createHumanInputToolWithController;
804
1799
 
805
1800
  // src/agent/stream-provider.ts
806
1801
  var DEFAULT_CUSTOM_STREAM_MODELS = [
@@ -808,7 +1803,7 @@ var DEFAULT_CUSTOM_STREAM_MODELS = [
808
1803
  "computer-use-preview-2025-03-11"
809
1804
  ];
810
1805
  function needsCustomStreamProvider(model, customPatterns) {
811
- const modelId = getModelId(model);
1806
+ const modelId = extractModelId(model);
812
1807
  if (!modelId || modelId === "[object Object]") return false;
813
1808
  const patterns = customPatterns ?? DEFAULT_CUSTOM_STREAM_MODELS;
814
1809
  return patterns.some((pattern) => modelId.includes(pattern));
@@ -824,7 +1819,7 @@ function autoDetectStreamProvider(model, tools, explicitProvider) {
824
1819
  const enhancedTools = tools;
825
1820
  const customPatterns = enhancedTools.__customStreamModels;
826
1821
  if (needsCustomStreamProvider(model, customPatterns) && hasStreamProviderFactory(enhancedTools)) {
827
- const modelId = getModelId(model);
1822
+ const modelId = extractModelId(model);
828
1823
  if (modelId) {
829
1824
  const streamConfig = {
830
1825
  apiKey: process.env.OPENAI_API_KEY,
@@ -838,18 +1833,6 @@ function autoDetectStreamProvider(model, tools, explicitProvider) {
838
1833
  return void 0;
839
1834
  }
840
1835
 
841
- // src/agent/defaults.ts
842
- var DEFAULT_SYSTEM_PROMPT = `You are a capable AI assistant with access to tools.
843
-
844
- Think step by step about what you need to do.
845
- Use the available tools to accomplish tasks.
846
- Verify your results after each action.
847
-
848
- If a tool fails, try an alternative approach \u2014 do not give up after a single error.
849
- Keep working until the task is fully resolved or you have exhausted all options.`;
850
- var DEFAULT_MAX_STEPS = 50;
851
- var DEFAULT_MAX_TOKENS = 32e3;
852
-
853
1836
  // src/agent/setup.ts
854
1837
  function createAgentPromptBuilder(config) {
855
1838
  if (config.prompt !== void 0) {
@@ -866,14 +1849,24 @@ function createEffectiveAgentConfig(config) {
866
1849
  config.tools,
867
1850
  config.streamProvider
868
1851
  );
1852
+ const resolvedCwd = config.cwd ?? config.sandbox?.metadata?.workingDirectory ?? process.cwd();
1853
+ const defaultsContext = {
1854
+ sandbox: config.sandbox,
1855
+ cwd: resolvedCwd,
1856
+ modelId: extractModelId(config.model)
1857
+ };
1858
+ const providers = [
1859
+ sandboxDefaultsProvider,
1860
+ ...config.defaultsProviders ?? []
1861
+ ];
1862
+ const defaults = resolveAgentDefaults(defaultsContext, providers);
869
1863
  return {
870
- systemPrompt: DEFAULT_SYSTEM_PROMPT,
871
- cwd: process.cwd(),
872
- reasoningLevel: "off",
873
1864
  ...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,
1865
+ systemPrompt: config.systemPrompt ?? defaults.systemPrompt,
1866
+ cwd: resolvedCwd,
1867
+ reasoningLevel: config.reasoningLevel ?? "off",
1868
+ maxSteps: config.maxSteps ?? defaults.maxSteps,
1869
+ maxOutputTokens: config.maxOutputTokens ?? defaults.maxOutputTokens,
877
1870
  streamProvider: effectiveStreamProvider
878
1871
  };
879
1872
  }
@@ -892,148 +1885,139 @@ function resolveInitialReasoningLevel(config) {
892
1885
  function createAgentState(config) {
893
1886
  return {
894
1887
  model: config.model,
895
- systemPrompt: config.systemPrompt,
896
- cwd: config.cwd,
897
- isStreaming: false,
898
1888
  reasoningLevel: resolveInitialReasoningLevel(config)
899
1889
  };
900
1890
  }
901
1891
  function createAgentContextManager(config) {
902
1892
  const compactionConfig = config.compaction ?? {};
903
- const modelId = getModelId(config.model);
1893
+ const modelId = extractModelId(config.model);
904
1894
  const inferredWindow = inferContextWindow(modelId);
905
1895
  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
- );
910
1896
  return new ContextManager({
911
1897
  limits: {
912
1898
  contextWindow,
913
- reserveTokens,
914
- protectedTokens: compactionConfig.protectedTokens ?? DEFAULT_CONTEXT_LIMITS.protectedTokens,
915
- pruneMinimum: compactionConfig.pruneMinimum ?? DEFAULT_CONTEXT_LIMITS.pruneMinimum
1899
+ ...resolveAgentContextLimits(contextWindow, compactionConfig)
916
1900
  },
917
1901
  model: compactionConfig.summaryModel ?? config.model,
918
1902
  summaryPrompt: compactionConfig.summaryPrompt
919
1903
  });
920
1904
  }
1905
+ function resolveAgentContextLimits(contextWindow, compactionConfig = {}) {
1906
+ const proportionalReserve = Math.round(contextWindow * 0.12);
1907
+ const reserveTokens = contextWindow >= 64e3 ? Math.min(32e3, Math.max(8e3, proportionalReserve)) : Math.min(
1908
+ Math.max(1024, Math.round(contextWindow * 0.25)),
1909
+ Math.max(512, proportionalReserve)
1910
+ );
1911
+ const usableWindow = Math.max(512, getUsableTokenLimit({ contextWindow, reserveTokens }));
1912
+ const requestedProtected = compactionConfig.protectedTokens ?? DEFAULT_CONTEXT_LIMITS.protectedTokens;
1913
+ const requestedPruneMinimum = compactionConfig.pruneMinimum ?? DEFAULT_CONTEXT_LIMITS.pruneMinimum;
1914
+ return {
1915
+ reserveTokens,
1916
+ protectedTokens: Math.min(
1917
+ requestedProtected,
1918
+ Math.max(512, Math.round(usableWindow * 0.6))
1919
+ ),
1920
+ pruneMinimum: Math.min(
1921
+ requestedPruneMinimum,
1922
+ Math.max(256, Math.round(usableWindow * 0.5))
1923
+ )
1924
+ };
1925
+ }
921
1926
  function createMiddlewareSetup(input, config) {
922
- let effectiveMiddleware = input.middleware;
1927
+ const inputMiddleware = [...input.middleware ?? []];
1928
+ const hasManualApprovalMiddleware = inputMiddleware.some(
1929
+ (mw) => isApprovalMiddleware(mw)
1930
+ );
1931
+ if (input.approval && hasManualApprovalMiddleware) {
1932
+ throw new Error(
1933
+ "createAgent() received both `approval` config and an explicit approval middleware. Use `approval` for the built-in sugar, or install `approvalMiddleware(...)` manually, but not both."
1934
+ );
1935
+ }
1936
+ let effectiveMiddleware = inputMiddleware;
923
1937
  let telemetrySettings;
924
1938
  let tracingShutdown;
1939
+ if (input.approval) {
1940
+ effectiveMiddleware.push(approvalMiddleware(input.approval));
1941
+ }
925
1942
  if (input.tracing) {
926
- const agentName = config.name ?? "agent";
1943
+ const agentName = config.name ?? DEFAULT_AGENT_NAME;
927
1944
  const telemetryResult = createTelemetryConfig({
1945
+ ...input.tracing,
928
1946
  agentName,
929
- agentDescription: input.tracing.agentDescription,
930
- recordInputs: input.tracing.recordInputs,
931
- recordOutputs: input.tracing.recordOutputs,
932
- emitToolSpans: input.tracing.emitToolSpans,
933
- spanTimeoutMs: input.tracing.spanTimeoutMs,
934
- spanProcessor: input.tracing.spanProcessor,
935
1947
  serviceName: input.tracing.serviceName ?? agentName
936
1948
  });
937
1949
  effectiveMiddleware = [
938
1950
  telemetryResult.middleware,
939
- ...input.middleware ?? []
1951
+ ...effectiveMiddleware
940
1952
  ];
941
1953
  telemetrySettings = telemetryResult.telemetry;
942
1954
  tracingShutdown = telemetryResult.shutdown;
943
1955
  }
944
1956
  return {
945
- middlewareRunner: new MiddlewareRunner(effectiveMiddleware),
1957
+ middlewareRunner: new MiddlewareRunner(effectiveMiddleware, input.logger),
946
1958
  ...telemetrySettings ? { telemetrySettings } : {},
947
1959
  ...tracingShutdown ? { tracingShutdown } : {}
948
1960
  };
949
1961
  }
1962
+ function resolveHumanInputController(input) {
1963
+ if (!input.humanInput) {
1964
+ return {};
1965
+ }
1966
+ return {
1967
+ humanInputController: isHumanInputController(input.humanInput) ? input.humanInput : createHumanInputController(input.humanInput)
1968
+ };
1969
+ }
1970
+ function resolveExecutionEnvironment(input, config) {
1971
+ if (input.host !== void 0 && input.sandbox !== void 0 && input.host !== input.sandbox.host) {
1972
+ throw new Error(
1973
+ "createAgent() received both `host` and `sandbox`, but `sandbox.host` does not match the provided host. Pass only one execution input, or reuse the same host instance for both."
1974
+ );
1975
+ }
1976
+ if (input.host !== void 0) {
1977
+ return {
1978
+ host: input.host,
1979
+ ...input.sandbox ? { sandbox: input.sandbox } : {},
1980
+ ownsHost: false
1981
+ };
1982
+ }
1983
+ if (input.sandbox !== void 0) {
1984
+ return {
1985
+ host: input.sandbox.host,
1986
+ sandbox: input.sandbox,
1987
+ ownsHost: false
1988
+ };
1989
+ }
1990
+ return {
1991
+ host: localHost(config.cwd),
1992
+ ownsHost: true
1993
+ };
1994
+ }
950
1995
  function createAgentSetup(input) {
951
1996
  const promptBuilder = createAgentPromptBuilder(input);
952
1997
  const config = createEffectiveAgentConfig(input);
953
1998
  const middlewareSetup = createMiddlewareSetup(input, config);
1999
+ const humanInputSetup = resolveHumanInputController(input);
2000
+ const executionEnvironment = resolveExecutionEnvironment(input, config);
2001
+ const logger = input.logger ?? silentLogger;
954
2002
  return {
955
2003
  config,
956
2004
  tools: createToolMap(input.tools),
957
2005
  sessions: input.sessionManager ?? getDefaultSessionManager(),
958
2006
  state: createAgentState(config),
959
2007
  contextManager: createAgentContextManager(config),
960
- turnTracker: createTurnTracker({ cwd: config.cwd }),
2008
+ turnTracker: createTurnTracker({ cwd: config.cwd }, logger),
961
2009
  ...input.mcp ? { mcpManager: input.mcp } : {},
962
2010
  ...promptBuilder ? { promptBuilder } : {},
963
2011
  interventionCtrl: new InterventionController(),
964
- host: input.host ?? localHost(config.cwd),
2012
+ ...humanInputSetup,
2013
+ ...executionEnvironment,
965
2014
  middlewareRunner: middlewareSetup.middlewareRunner,
2015
+ logger,
966
2016
  ...middlewareSetup.telemetrySettings ? { telemetrySettings: middlewareSetup.telemetrySettings } : {},
967
2017
  ...middlewareSetup.tracingShutdown ? { tracingShutdown: middlewareSetup.tracingShutdown } : {}
968
2018
  };
969
2019
  }
970
2020
 
971
- // src/agent/runtime-config.ts
972
- function createAgentToolRecord(tools) {
973
- const toolRecord = {};
974
- for (const [id, tool] of tools) {
975
- toolRecord[id] = tool;
976
- }
977
- return toolRecord;
978
- }
979
- function getAgentContextStats(contextManager, messages) {
980
- return contextManager.getStats(messages);
981
- }
982
- async function compactAgentContext(contextManager, messages) {
983
- const result = await contextManager.prune(messages);
984
- return {
985
- removedCount: result.removedCount,
986
- tokensRemoved: result.tokensRemoved,
987
- summarized: result.summarized,
988
- summary: result.summary
989
- };
990
- }
991
- async function buildAgentSystemPrompts(options) {
992
- const {
993
- config,
994
- toolIds,
995
- sessionId,
996
- override,
997
- promptBuilder,
998
- middlewareRunner
999
- } = options;
1000
- if (promptBuilder) {
1001
- const composedPrompt = await promptBuilder.build(
1002
- {
1003
- cwd: config.cwd,
1004
- model: config.model,
1005
- toolNames: toolIds,
1006
- ...override ? { override } : {},
1007
- sessionId
1008
- },
1009
- middlewareRunner
1010
- );
1011
- return [composedPrompt];
1012
- }
1013
- const prompts = [config.systemPrompt];
1014
- if (override) {
1015
- prompts.push(override);
1016
- }
1017
- return prompts;
1018
- }
1019
- function createAgentTurnRuntimeConfig(options) {
1020
- const { config, telemetrySettings } = options;
1021
- return {
1022
- model: config.model,
1023
- cwd: config.cwd,
1024
- ...config.temperature !== void 0 ? { temperature: config.temperature } : {},
1025
- ...config.topP !== void 0 ? { topP: config.topP } : {},
1026
- ...config.maxOutputTokens !== void 0 ? { maxOutputTokens: config.maxOutputTokens } : {},
1027
- maxSteps: config.maxSteps,
1028
- ...config.doomLoopThreshold !== void 0 ? { doomLoopThreshold: config.doomLoopThreshold } : {},
1029
- ...config.enforceDoomLoop !== void 0 ? { enforceDoomLoop: config.enforceDoomLoop } : {},
1030
- ...config.onDoomLoop ? { onDoomLoop: config.onDoomLoop } : {},
1031
- ...config.contextWindow !== void 0 ? { contextWindow: config.contextWindow } : {},
1032
- ...config.streamProvider ? { streamProvider: config.streamProvider } : {},
1033
- ...telemetrySettings ? { telemetry: telemetrySettings } : {}
1034
- };
1035
- }
1036
-
1037
2021
  // src/agent/instance.ts
1038
2022
  function createAgent(config) {
1039
2023
  return new Agent(config);
@@ -1042,7 +2026,6 @@ var Agent = class _Agent {
1042
2026
  config;
1043
2027
  tools;
1044
2028
  sessions;
1045
- loadedSessions = /* @__PURE__ */ new Set();
1046
2029
  state;
1047
2030
  /** Context manager for overflow detection and compaction */
1048
2031
  contextManager;
@@ -1066,6 +2049,12 @@ var Agent = class _Agent {
1066
2049
  interventionCtrl;
1067
2050
  /** Execution environment for tool operations */
1068
2051
  host;
2052
+ /** Managed sandbox session, when the agent was created from one */
2053
+ sandbox;
2054
+ /** Managed human-input controller for question-style tools */
2055
+ humanInputController;
2056
+ /** Whether the agent owns the host and can safely recreate it on cwd changes */
2057
+ ownsHost;
1069
2058
  /** Middleware runner for lifecycle hooks */
1070
2059
  middlewareRunner;
1071
2060
  /** AI SDK telemetry settings (auto-created from `tracing` config) */
@@ -1074,6 +2063,14 @@ var Agent = class _Agent {
1074
2063
  tracingShutdown;
1075
2064
  /** Multi-consumer event dispatch */
1076
2065
  _signal;
2066
+ /** Number of active turns across all sessions */
2067
+ activeTurnCount = 0;
2068
+ /** Active turn intervention controllers, keyed by turn id */
2069
+ activeTurns = /* @__PURE__ */ new Map();
2070
+ /** Per-session turn queue to prevent concurrent writes to the same history */
2071
+ sessionLocks = /* @__PURE__ */ new Map();
2072
+ /** Structured logger for diagnostic output */
2073
+ _logger;
1077
2074
  constructor(config) {
1078
2075
  const setup = createAgentSetup(config);
1079
2076
  this.config = setup.config;
@@ -1086,7 +2083,11 @@ var Agent = class _Agent {
1086
2083
  this.promptBuilder = setup.promptBuilder;
1087
2084
  this.interventionCtrl = setup.interventionCtrl;
1088
2085
  this.host = setup.host;
2086
+ this.sandbox = setup.sandbox;
2087
+ this.humanInputController = setup.humanInputController;
2088
+ this.ownsHost = setup.ownsHost;
1089
2089
  this.middlewareRunner = setup.middlewareRunner;
2090
+ this._logger = setup.logger;
1090
2091
  this.telemetrySettings = setup.telemetrySettings;
1091
2092
  this.tracingShutdown = setup.tracingShutdown;
1092
2093
  this._signal = config.signal ?? new LocalSignal();
@@ -1101,9 +2102,13 @@ var Agent = class _Agent {
1101
2102
  get signal() {
1102
2103
  return this._signal;
1103
2104
  }
2105
+ /** Structured logger — silent by default, configurable via `createAgent({ logger })`. */
2106
+ get logger() {
2107
+ return this._logger;
2108
+ }
1104
2109
  /** Agent name (identity for spans, Dapr workflows, etc.) */
1105
2110
  get name() {
1106
- return this.config.name ?? "agent";
2111
+ return this.config.name ?? DEFAULT_AGENT_NAME;
1107
2112
  }
1108
2113
  /** Working directory for file operations */
1109
2114
  get cwd() {
@@ -1119,7 +2124,7 @@ var Agent = class _Agent {
1119
2124
  }
1120
2125
  /** Is currently streaming */
1121
2126
  get isStreaming() {
1122
- return this.state.isStreaming;
2127
+ return this.activeTurnCount > 0;
1123
2128
  }
1124
2129
  /** Current reasoning level */
1125
2130
  get reasoningLevel() {
@@ -1162,6 +2167,96 @@ var Agent = class _Agent {
1162
2167
  }
1163
2168
  }
1164
2169
  }
2170
+ resetPromptScopedTools() {
2171
+ this.tools.delete("skill");
2172
+ this.tools.delete("skill_resource");
2173
+ this.skillToolsResolved = false;
2174
+ }
2175
+ createSessionManager() {
2176
+ return new SessionManager(this.sessions.getStorage());
2177
+ }
2178
+ async acquireSessionLock(sessionId) {
2179
+ const previous = this.sessionLocks.get(sessionId) ?? Promise.resolve();
2180
+ let releaseLock;
2181
+ const current = new Promise((resolve2) => {
2182
+ releaseLock = resolve2;
2183
+ });
2184
+ const chain = previous.catch(() => void 0).then(() => current);
2185
+ this.sessionLocks.set(sessionId, chain);
2186
+ await previous.catch(() => void 0);
2187
+ let released = false;
2188
+ return () => {
2189
+ if (released) return;
2190
+ released = true;
2191
+ releaseLock();
2192
+ if (this.sessionLocks.get(sessionId) === chain) {
2193
+ this.sessionLocks.delete(sessionId);
2194
+ }
2195
+ };
2196
+ }
2197
+ /**
2198
+ * Force-clear all pending session locks for a given session.
2199
+ *
2200
+ * This is an escape hatch for callers that manage sequencing
2201
+ * externally (e.g. the coordinator loop) and need to guarantee a
2202
+ * prior `chat()` generator's lock won't block the next call — even
2203
+ * if the generator's cleanup is stuck on a network read.
2204
+ *
2205
+ * **Only use when you are certain no concurrent `chat()` calls are
2206
+ * active on this session.**
2207
+ */
2208
+ clearSessionLock(sessionId) {
2209
+ this.sessionLocks.delete(sessionId);
2210
+ }
2211
+ /**
2212
+ * Acquire the same per-session turn lock used by `chat()`.
2213
+ *
2214
+ * External durable runtimes can hold this lock across a workflow-backed
2215
+ * turn so direct `chat()` calls cannot interleave with the same session.
2216
+ */
2217
+ async acquireSessionTurnLock(sessionId) {
2218
+ return await this.acquireSessionLock(sessionId);
2219
+ }
2220
+ getActiveInterventionController() {
2221
+ const active = Array.from(this.activeTurns.values());
2222
+ if (active.length === 0) {
2223
+ return void 0;
2224
+ }
2225
+ if (active.length > 1) {
2226
+ throw new Error(
2227
+ "Interventions are ambiguous while multiple agent turns are active. Use separate Agent instances or wait for one turn to finish."
2228
+ );
2229
+ }
2230
+ return active[0].interventionCtrl;
2231
+ }
2232
+ getInterventionControllerForTurn() {
2233
+ const activeController = this.getActiveInterventionController();
2234
+ return activeController ?? this.interventionCtrl;
2235
+ }
2236
+ createTurnInterventionController() {
2237
+ return this.activeTurns.size === 0 ? this.interventionCtrl : new InterventionController();
2238
+ }
2239
+ releaseTurnInterventions(controller) {
2240
+ if (controller === this.interventionCtrl) {
2241
+ controller.resetCallbacks();
2242
+ return;
2243
+ }
2244
+ this.interventionCtrl.adoptImmediate(controller.drainImmediate());
2245
+ this.interventionCtrl.adoptDeferred(controller.drainDeferred());
2246
+ controller.resetCallbacks();
2247
+ }
2248
+ syncStreamingState(active) {
2249
+ this.activeTurnCount = Math.max(
2250
+ 0,
2251
+ this.activeTurnCount + (active ? 1 : -1)
2252
+ );
2253
+ }
2254
+ async syncSessionView(sessionId) {
2255
+ if (!await this.sessions.sessionExists(sessionId)) {
2256
+ return;
2257
+ }
2258
+ await this.sessions.load(sessionId);
2259
+ }
1165
2260
  /**
1166
2261
  * Ensure MCP is connected and return tools
1167
2262
  * Lazy initialization - only connects on first use
@@ -1171,34 +2266,11 @@ var Agent = class _Agent {
1171
2266
  manager: this.mcpManager,
1172
2267
  connected: this.mcpConnected,
1173
2268
  cachedTools: this.mcpToolsCache
1174
- });
2269
+ }, this._logger);
1175
2270
  this.mcpConnected = nextState.connected;
1176
2271
  this.mcpToolsCache = nextState.cachedTools;
1177
2272
  return nextState.cachedTools ?? {};
1178
2273
  }
1179
- /**
1180
- * Repair session history by synthesising missing tool-result messages.
1181
- *
1182
- * When a tool `execute()` throws, the AI SDK emits `tool-error` instead
1183
- * of `tool-result`. If the error event wasn't persisted (e.g. because
1184
- * the fix above wasn't in place), subsequent turns will fail with
1185
- * `MissingToolResultsError`. This method detects orphaned tool-call IDs
1186
- * and adds placeholder `tool` messages so the history is valid again.
1187
- */
1188
- async repairOrphanedToolCalls() {
1189
- await repairOrphanedToolCalls(this.sessions);
1190
- }
1191
- /**
1192
- * Convert internal {@link Message} array to Vercel AI SDK {@link ModelMessage} format.
1193
- *
1194
- * Handles the role-specific mappings:
1195
- * - `user` / `system` → pass-through
1196
- * - `assistant` with tool calls → `ToolCallPart[]` content
1197
- * - `tool` → `tool-result` content part
1198
- */
1199
- toModelMessages(messages) {
1200
- return convertAgentMessagesToModelMessages(messages);
1201
- }
1202
2274
  /**
1203
2275
  * Stream a chat response.
1204
2276
  *
@@ -1212,52 +2284,79 @@ var Agent = class _Agent {
1212
2284
  * @yields {AgentEvent} Events as they occur during processing
1213
2285
  */
1214
2286
  async *chat(sessionId, message, options) {
1215
- await this.ensureSession(sessionId);
1216
- await this.ensureSkillTools();
1217
- const abort = options?.abort ?? new AbortController().signal;
2287
+ const releaseSessionLock = await this.acquireSessionLock(sessionId);
2288
+ const sessions = this.createSessionManager();
1218
2289
  const turnId = `${sessionId}-turn-${++this.turnCounter}`;
1219
- this.turnTracker.startTurn(turnId);
1220
- await this.repairOrphanedToolCalls();
1221
- const mcpTools = await this.ensureMCPConnected();
1222
- const loop = runChatLoop({
1223
- sessionId,
1224
- message,
1225
- abort,
1226
- systemOverride: options?.system,
1227
- sessions: this.sessions,
1228
- tools: createAgentToolRecord(this.tools),
1229
- config: this.config,
1230
- turnTracker: this.turnTracker,
1231
- interventionCtrl: this.interventionCtrl,
1232
- middlewareRunner: this.middlewareRunner,
1233
- contextManager: this.contextManager,
1234
- rememberedDoomLoopTools: this.rememberedDoomLoopTools,
1235
- reasoningLevel: this.state.reasoningLevel,
1236
- promptBuilder: this.promptBuilder,
1237
- host: this.host,
1238
- mcpTools,
1239
- telemetrySettings: this.telemetrySettings,
1240
- toModelMessages: this.toModelMessages.bind(this),
1241
- setIsStreaming: (v) => {
1242
- this.state.isStreaming = v;
2290
+ let turnTracker;
2291
+ let interventionCtrl = this.interventionCtrl;
2292
+ let streamingStateActive = false;
2293
+ let turnRegistered = false;
2294
+ try {
2295
+ await this.ensureSkillTools();
2296
+ const abort = options?.abort ?? new AbortController().signal;
2297
+ turnTracker = createTurnTracker({ cwd: this.config.cwd });
2298
+ interventionCtrl = this.createTurnInterventionController();
2299
+ this.activeTurns.set(turnId, { sessionId, interventionCtrl });
2300
+ turnRegistered = true;
2301
+ await ensureSessionLoaded({
2302
+ sessionId,
2303
+ sessions,
2304
+ cwd: this.config.cwd
2305
+ });
2306
+ turnTracker.startTurn(turnId);
2307
+ await repairOrphanedToolCalls(sessions);
2308
+ const mcpTools = await this.ensureMCPConnected();
2309
+ const loop = runChatLoop({
2310
+ sessionId,
2311
+ turnId,
2312
+ message,
2313
+ abort,
2314
+ systemOverride: options?.system,
2315
+ sessions,
2316
+ tools: this.tools,
2317
+ config: this.config,
2318
+ turnTracker,
2319
+ interventionCtrl,
2320
+ middlewareRunner: this.middlewareRunner,
2321
+ contextManager: this.contextManager,
2322
+ rememberedDoomLoopTools: this.rememberedDoomLoopTools,
2323
+ reasoningLevel: this.state.reasoningLevel,
2324
+ promptBuilder: this.promptBuilder,
2325
+ host: this.host,
2326
+ humanInputController: this.humanInputController,
2327
+ mcpTools,
2328
+ telemetrySettings: this.telemetrySettings,
2329
+ toModelMessages: convertAgentMessagesToModelMessages,
2330
+ setIsStreaming: (value) => {
2331
+ if (value === streamingStateActive) return;
2332
+ streamingStateActive = value;
2333
+ this.syncStreamingState(value);
2334
+ },
2335
+ toolExecutionMode: this.config.toolExecutionMode,
2336
+ logger: this._logger
2337
+ });
2338
+ for await (const event of loop) {
2339
+ this._signal.emit(event);
2340
+ yield event;
2341
+ }
2342
+ } finally {
2343
+ try {
2344
+ if (streamingStateActive) {
2345
+ this.syncStreamingState(false);
2346
+ }
2347
+ if (turnRegistered) {
2348
+ this.activeTurns.delete(turnId);
2349
+ }
2350
+ this.releaseTurnInterventions(interventionCtrl);
2351
+ if (turnRegistered && turnTracker) {
2352
+ this.turnTracker = turnTracker;
2353
+ }
2354
+ await this.syncSessionView(sessionId);
2355
+ } finally {
2356
+ releaseSessionLock();
1243
2357
  }
1244
- });
1245
- for await (const event of loop) {
1246
- this._signal.emit(event);
1247
- yield event;
1248
2358
  }
1249
2359
  }
1250
- /**
1251
- * Ensure a session is loaded or created
1252
- */
1253
- async ensureSession(sessionId) {
1254
- await ensureSessionLoaded({
1255
- sessionId,
1256
- sessions: this.sessions,
1257
- loadedSessions: this.loadedSessions,
1258
- cwd: this.config.cwd
1259
- });
1260
- }
1261
2360
  /**
1262
2361
  * Send a message and wait for the complete response (non-streaming).
1263
2362
  *
@@ -1326,13 +2425,20 @@ var Agent = class _Agent {
1326
2425
  getSessionContext() {
1327
2426
  return this.sessions.getContext();
1328
2427
  }
1329
- /** Get messages from current session */
2428
+ /**
2429
+ * Get messages from current session.
2430
+ *
2431
+ * NOTE: during an active `chat()` turn, messages are accumulated in a
2432
+ * per-turn SessionManager and synced back after the turn completes.
2433
+ * Calling this mid-turn returns the shared view, which may lag behind
2434
+ * the in-progress turn. Use `send()` or consume the `chat()` generator
2435
+ * for real-time access to turn messages.
2436
+ */
1330
2437
  getMessages() {
1331
2438
  return this.sessions.getMessages();
1332
2439
  }
1333
2440
  /** Delete a session */
1334
2441
  async deleteSession(sessionId) {
1335
- this.loadedSessions.delete(sessionId);
1336
2442
  return this.sessions.deleteSession(sessionId);
1337
2443
  }
1338
2444
  /** List all sessions */
@@ -1368,8 +2474,7 @@ var Agent = class _Agent {
1368
2474
  * ```
1369
2475
  */
1370
2476
  getContextStats() {
1371
- return getAgentContextStats(
1372
- this.contextManager,
2477
+ return this.contextManager.getStats(
1373
2478
  this.sessions.getMessages()
1374
2479
  );
1375
2480
  }
@@ -1382,10 +2487,11 @@ var Agent = class _Agent {
1382
2487
  * @returns Pruning result with details about what was removed/summarized
1383
2488
  */
1384
2489
  async compactContext() {
1385
- return await compactAgentContext(
1386
- this.contextManager,
1387
- this.sessions.getMessages()
1388
- );
2490
+ return await compactAgentContext({
2491
+ contextManager: this.contextManager,
2492
+ sessions: this.sessions,
2493
+ logger: this._logger
2494
+ });
1389
2495
  }
1390
2496
  /**
1391
2497
  * Clear remembered doom loop tools.
@@ -1415,6 +2521,8 @@ var Agent = class _Agent {
1415
2521
  *
1416
2522
  * If called when no turn is active, the message will be picked up
1417
2523
  * by the first step of the next `chat()` call.
2524
+ * If multiple turns are active concurrently, this throws because the
2525
+ * target turn would be ambiguous.
1418
2526
  *
1419
2527
  * @param message - The user message to inject mid-turn
1420
2528
  * @returns Intervention ID for tracking
@@ -1436,7 +2544,7 @@ var Agent = class _Agent {
1436
2544
  * ```
1437
2545
  */
1438
2546
  intervene(message) {
1439
- return this.interventionCtrl.intervene(message);
2547
+ return this.getInterventionControllerForTurn().intervene(message);
1440
2548
  }
1441
2549
  /**
1442
2550
  * Queue a message for after the current turn completes.
@@ -1446,6 +2554,9 @@ var Agent = class _Agent {
1446
2554
  * `chat()` finishes. The consumer decides whether to send it as a
1447
2555
  * new turn.
1448
2556
  *
2557
+ * If multiple turns are active concurrently, this throws because the
2558
+ * target turn would be ambiguous.
2559
+ *
1449
2560
  * @param message - The message to queue
1450
2561
  * @returns Intervention ID for tracking
1451
2562
  *
@@ -1468,15 +2579,15 @@ var Agent = class _Agent {
1468
2579
  * ```
1469
2580
  */
1470
2581
  queueNext(message) {
1471
- return this.interventionCtrl.queueNext(message);
2582
+ return this.getInterventionControllerForTurn().queueNext(message);
1472
2583
  }
1473
2584
  /** Whether there are deferred messages queued for after the turn */
1474
2585
  hasQueuedNext() {
1475
- return this.interventionCtrl.hasDeferred;
2586
+ return this.getInterventionControllerForTurn().hasDeferred;
1476
2587
  }
1477
2588
  /** Drain and return all deferred messages (clears the queue) */
1478
2589
  drainQueuedNext() {
1479
- return this.interventionCtrl.drainDeferred();
2590
+ return this.getInterventionControllerForTurn().drainDeferred();
1480
2591
  }
1481
2592
  /**
1482
2593
  * Get the raw intervention controller for advanced use cases.
@@ -1488,7 +2599,7 @@ var Agent = class _Agent {
1488
2599
  * @internal
1489
2600
  */
1490
2601
  getInterventionController() {
1491
- return this.interventionCtrl;
2602
+ return this.getInterventionControllerForTurn();
1492
2603
  }
1493
2604
  // ============================================================================
1494
2605
  // Turn Tracking
@@ -1563,28 +2674,37 @@ var Agent = class _Agent {
1563
2674
  */
1564
2675
  setSystemPrompt(prompt) {
1565
2676
  this.config.systemPrompt = prompt;
1566
- this.state.systemPrompt = prompt;
1567
2677
  this.promptBuilder = void 0;
2678
+ this.resetPromptScopedTools();
1568
2679
  }
1569
2680
  /** Update working directory */
1570
2681
  setCwd(cwd) {
1571
2682
  this.config.cwd = cwd;
1572
- this.state.cwd = cwd;
2683
+ this.turnTracker = createTurnTracker({ cwd });
2684
+ if (this.ownsHost) {
2685
+ this.host = localHost(cwd);
2686
+ }
2687
+ this.resetPromptScopedTools();
1573
2688
  this.promptBuilder?.clearCache();
1574
2689
  }
1575
2690
  /** Update model */
1576
2691
  setModel(model) {
1577
2692
  this.config.model = model;
1578
2693
  this.state.model = model;
2694
+ if (this.config.compaction?.summaryModel === void 0) {
2695
+ this.contextManager.setModel(model);
2696
+ }
1579
2697
  if (this.config.contextWindow === void 0) {
1580
- const modelId = getModelId(model);
2698
+ const modelId = extractModelId(model);
1581
2699
  const inferred = inferContextWindow(modelId);
1582
2700
  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 });
2701
+ this.contextManager.setLimits({
2702
+ contextWindow: inferred,
2703
+ ...resolveAgentContextLimits(
2704
+ inferred,
2705
+ this.config.compaction
2706
+ )
2707
+ });
1588
2708
  }
1589
2709
  }
1590
2710
  }
@@ -1624,6 +2744,7 @@ var Agent = class _Agent {
1624
2744
  * runtimes can start durable turns without duplicating prompt assembly.
1625
2745
  */
1626
2746
  async buildSystemPrompts(sessionId, override) {
2747
+ await this.ensureSkillTools();
1627
2748
  return await buildAgentSystemPrompts({
1628
2749
  config: this.config,
1629
2750
  toolIds: Array.from(this.tools.keys()),
@@ -1640,7 +2761,8 @@ var Agent = class _Agent {
1640
2761
  getTurnRuntimeConfig() {
1641
2762
  return createAgentTurnRuntimeConfig({
1642
2763
  config: this.config,
1643
- telemetrySettings: this.telemetrySettings
2764
+ telemetrySettings: this.telemetrySettings,
2765
+ reserveTokens: this.contextManager.getLimits().reserveTokens
1644
2766
  });
1645
2767
  }
1646
2768
  /**
@@ -1649,6 +2771,26 @@ var Agent = class _Agent {
1649
2771
  getHost() {
1650
2772
  return this.host;
1651
2773
  }
2774
+ /**
2775
+ * Get the configured sandbox session, if one was provided.
2776
+ */
2777
+ getSandbox() {
2778
+ return this.sandbox;
2779
+ }
2780
+ /**
2781
+ * Get the configured human-input controller, if one was provided.
2782
+ */
2783
+ getHumanInputController() {
2784
+ return this.humanInputController;
2785
+ }
2786
+ /**
2787
+ * Whether any registered tool advertises human-input semantics.
2788
+ */
2789
+ hasHumanInputTools() {
2790
+ return [...this.tools.values()].some(
2791
+ (tool) => tool.capabilitiesHint?.humanInput === true
2792
+ );
2793
+ }
1652
2794
  /**
1653
2795
  * Get the configured middleware runner.
1654
2796
  *
@@ -1658,6 +2800,18 @@ var Agent = class _Agent {
1658
2800
  getMiddlewareRunner() {
1659
2801
  return this.middlewareRunner;
1660
2802
  }
2803
+ /**
2804
+ * Get the configured middleware stack.
2805
+ */
2806
+ getMiddleware() {
2807
+ return this.middlewareRunner.getMiddleware();
2808
+ }
2809
+ /**
2810
+ * Ensure MCP is connected and return the current MCP tool set.
2811
+ */
2812
+ async getMcpTools() {
2813
+ return await this.ensureMCPConnected();
2814
+ }
1661
2815
  // ============================================================================
1662
2816
  // Sub-Agents (Forking)
1663
2817
  // ============================================================================
@@ -1699,6 +2853,9 @@ var Agent = class _Agent {
1699
2853
  parentTools: Array.from(this.tools.values()),
1700
2854
  reasoningLevel: this.state.reasoningLevel,
1701
2855
  host: this.host,
2856
+ sandbox: this.sandbox,
2857
+ humanInputController: this.humanInputController,
2858
+ ownsHost: this.ownsHost,
1702
2859
  sessions: this.sessions,
1703
2860
  mcpManager: this.mcpManager,
1704
2861
  middlewareRunner: this.middlewareRunner,
@@ -1707,29 +2864,29 @@ var Agent = class _Agent {
1707
2864
  );
1708
2865
  }
1709
2866
  /**
1710
- * Create a sub-agent with a preset configuration.
2867
+ * Create a sub-agent with a profile.
1711
2868
  *
1712
- * Convenience method that applies a preset and returns a forked agent.
2869
+ * Convenience method that applies a profile and returns a forked agent.
1713
2870
  *
1714
2871
  * @example
1715
2872
  * ```typescript
1716
- * import { Presets } from "@cuylabs/agent-core";
2873
+ * import { Profiles } from "@cuylabs/agent-core";
1717
2874
  *
1718
2875
  * // Create an exploration sub-agent
1719
- * const explorer = agent.withPreset(Presets.explore);
2876
+ * const explorer = agent.withProfile(Profiles.explore);
1720
2877
  * const result = await explorer.run({
1721
2878
  * message: "Find all API routes in this project",
1722
2879
  * });
1723
2880
  *
1724
2881
  * // Create a careful review sub-agent
1725
- * const reviewer = agent.withPreset(Presets.review);
2882
+ * const reviewer = agent.withProfile(Profiles.review);
1726
2883
  * const review = await reviewer.run({
1727
2884
  * message: "Review src/auth.ts for security issues",
1728
2885
  * });
1729
2886
  * ```
1730
2887
  */
1731
- withPreset(preset) {
1732
- return this.fork({ preset });
2888
+ withProfile(profile) {
2889
+ return this.fork({ profile });
1733
2890
  }
1734
2891
  /**
1735
2892
  * Run a task in an isolated sub-agent session.
@@ -1750,9 +2907,9 @@ var Agent = class _Agent {
1750
2907
  * ```
1751
2908
  */
1752
2909
  async run(options) {
2910
+ const sessions = this.createSessionManager();
1753
2911
  const sessionId = await createSubAgentRunSession({
1754
- sessions: this.sessions,
1755
- loadedSessions: this.loadedSessions,
2912
+ sessions,
1756
2913
  cwd: this.config.cwd,
1757
2914
  parentSessionId: options.parentSessionId,
1758
2915
  title: options.title
@@ -1805,6 +2962,7 @@ var Agent = class _Agent {
1805
2962
  */
1806
2963
  async close() {
1807
2964
  this._signal.clear();
2965
+ this.humanInputController?.cancelAll("Agent closed");
1808
2966
  if (this.tracingShutdown) {
1809
2967
  await this.tracingShutdown();
1810
2968
  }
@@ -1814,29 +2972,243 @@ var Agent = class _Agent {
1814
2972
  }
1815
2973
  };
1816
2974
 
1817
- // src/agent/concurrent.ts
1818
- async function runConcurrent(tasks, options) {
1819
- const maxConcurrency = options?.maxConcurrency ?? 5;
1820
- const results = new Array(tasks.length);
1821
- let currentIndex = 0;
1822
- async function runNext() {
1823
- while (currentIndex < tasks.length) {
1824
- const index = currentIndex++;
1825
- const task = tasks[index];
1826
- results[index] = await task.agent.run({
1827
- parentSessionId: task.parentSessionId,
1828
- message: task.message,
1829
- title: task.title,
1830
- abort: options?.abort
1831
- });
2975
+ // src/agent/event-printer.ts
2976
+ function createEventPrinter(options = {}) {
2977
+ const {
2978
+ tools = true,
2979
+ reasoning = true,
2980
+ steps = false,
2981
+ safety = true,
2982
+ completion = true,
2983
+ team = false,
2984
+ stdout = process.stdout,
2985
+ stderr = process.stderr
2986
+ } = options;
2987
+ return (event) => {
2988
+ switch (event.type) {
2989
+ // ── Lifecycle ─────────────────────────────────────────────────
2990
+ case "status":
2991
+ if (steps) stderr.write(`\u23F3 Status \u2192 ${event.status}
2992
+ `);
2993
+ break;
2994
+ case "step-start":
2995
+ if (steps) stderr.write(`\u{1F4CD} Step ${event.step}/${event.maxSteps}
2996
+ `);
2997
+ break;
2998
+ case "step-finish":
2999
+ break;
3000
+ // silent by default
3001
+ case "turn-boundary":
3002
+ if (steps) stderr.write(`\u{1F9F1} Boundary \u2192 ${event.boundary}
3003
+ `);
3004
+ break;
3005
+ // ── Text streaming ────────────────────────────────────────────
3006
+ case "text-start":
3007
+ break;
3008
+ // cursor is already in place
3009
+ case "text-delta":
3010
+ stdout.write(event.text);
3011
+ break;
3012
+ case "text-end":
3013
+ stdout.write("\n");
3014
+ break;
3015
+ // ── Messages ──────────────────────────────────────────────────
3016
+ case "message":
3017
+ break;
3018
+ // too noisy for CLI output
3019
+ // ── Reasoning ─────────────────────────────────────────────────
3020
+ case "reasoning-start":
3021
+ if (reasoning) stderr.write("\u{1F4AD} ");
3022
+ break;
3023
+ case "reasoning-delta":
3024
+ if (reasoning) stderr.write(event.text);
3025
+ break;
3026
+ case "reasoning-end":
3027
+ if (reasoning) stderr.write("\n");
3028
+ break;
3029
+ // ── Tool execution ────────────────────────────────────────────
3030
+ case "tool-start":
3031
+ if (tools)
3032
+ stderr.write(
3033
+ `\u{1F527} ${event.toolName}(${JSON.stringify(event.input)})
3034
+ `
3035
+ );
3036
+ break;
3037
+ case "tool-result":
3038
+ if (tools)
3039
+ stderr.write(` \u2713 ${String(event.result).slice(0, 200)}
3040
+ `);
3041
+ break;
3042
+ case "tool-error":
3043
+ if (tools) stderr.write(` \u2717 ${event.error}
3044
+ `);
3045
+ break;
3046
+ // ── Approval / intervention ───────────────────────────────────
3047
+ case "approval-request":
3048
+ if (safety)
3049
+ stderr.write(
3050
+ `\u{1F6C2} Approval needed \u2192 ${event.request.tool} [${event.request.risk}]
3051
+ `
3052
+ );
3053
+ break;
3054
+ case "approval-resolved":
3055
+ if (safety)
3056
+ stderr.write(`\u{1F6C2} Approval ${event.id} \u2192 ${event.action}
3057
+ `);
3058
+ break;
3059
+ case "intervention-applied":
3060
+ if (safety)
3061
+ stderr.write(`\u270B Intervention \u2192 ${event.message}
3062
+ `);
3063
+ break;
3064
+ case "follow-up-queued":
3065
+ if (safety)
3066
+ stderr.write(`\u{1F4CC} Follow-up queued \u2192 ${event.message}
3067
+ `);
3068
+ break;
3069
+ // ── Safety ────────────────────────────────────────────────────
3070
+ case "doom-loop":
3071
+ if (safety)
3072
+ stderr.write(
3073
+ `\u26A0\uFE0F Doom loop: ${event.toolName} repeated ${event.repeatCount}x
3074
+ `
3075
+ );
3076
+ break;
3077
+ case "context-overflow":
3078
+ if (safety)
3079
+ stderr.write(
3080
+ `\u26A0\uFE0F Context overflow: ${event.inputTokens}/${event.limit} tokens
3081
+ `
3082
+ );
3083
+ break;
3084
+ case "turn-summary":
3085
+ if (safety)
3086
+ stderr.write(
3087
+ `\u{1F5C2}\uFE0F Turn summary \u2192 ${event.files.length} file(s), +${event.additions}/-${event.deletions}
3088
+ `
3089
+ );
3090
+ break;
3091
+ // ── Computer use ──────────────────────────────────────────────
3092
+ case "computer-call":
3093
+ if (tools)
3094
+ stderr.write(`\u{1F5A5}\uFE0F Computer action \u2192 ${event.callId}
3095
+ `);
3096
+ break;
3097
+ case "computer-result":
3098
+ if (tools)
3099
+ stderr.write(`\u{1F5A5}\uFE0F Computer result \u2192 ${event.callId}
3100
+ `);
3101
+ break;
3102
+ // ── Human input ───────────────────────────────────────────────
3103
+ case "human-input-request":
3104
+ if (safety)
3105
+ stderr.write(
3106
+ `\u2753 ${event.request.title}: ${event.request.question}
3107
+ `
3108
+ );
3109
+ break;
3110
+ case "human-input-resolved":
3111
+ break;
3112
+ // host handles display
3113
+ // ── Error & retry ─────────────────────────────────────────────
3114
+ case "retry":
3115
+ stderr.write(
3116
+ `\u{1F501} Retry ${event.attempt} in ${event.delayMs}ms
3117
+ `
3118
+ );
3119
+ break;
3120
+ case "error":
3121
+ stderr.write(`\u274C ${event.error.message}
3122
+ `);
3123
+ break;
3124
+ // ── Completion ────────────────────────────────────────────────
3125
+ case "complete":
3126
+ if (completion)
3127
+ stderr.write(
3128
+ `\u2705 Done \u2014 ${event.usage?.totalTokens ?? "?"} tokens
3129
+ `
3130
+ );
3131
+ break;
3132
+ // ── Team events ───────────────────────────────────────────────
3133
+ default:
3134
+ if (team && "type" in event && event.type.startsWith("team-")) {
3135
+ printTeamEvent(stderr, event);
3136
+ }
3137
+ break;
1832
3138
  }
3139
+ };
3140
+ }
3141
+ function printTeamEvent(out, event) {
3142
+ switch (event.type) {
3143
+ case "team-started":
3144
+ out.write(`\u{1F3C1} Team started
3145
+ `);
3146
+ break;
3147
+ case "team-member-registered":
3148
+ out.write(
3149
+ ` \u{1F464} ${event.member.id} (${event.member.role})
3150
+ `
3151
+ );
3152
+ break;
3153
+ case "team-task-completed":
3154
+ out.write(
3155
+ ` \u2705 Task ${event.taskId} completed
3156
+ `
3157
+ );
3158
+ break;
3159
+ case "team-task-failed":
3160
+ out.write(
3161
+ ` \u274C Task ${event.taskId} failed
3162
+ `
3163
+ );
3164
+ break;
3165
+ case "team-stopped":
3166
+ out.write(`\u{1F3C1} Team stopped
3167
+ `);
3168
+ break;
1833
3169
  }
1834
- const workers = Array.from(
1835
- { length: Math.min(maxConcurrency, tasks.length) },
1836
- () => runNext()
1837
- );
1838
- await Promise.all(workers);
1839
- return results;
3170
+ }
3171
+
3172
+ // src/intervention/follow-up-policy.ts
3173
+ function normalizeFollowUpMode(mode) {
3174
+ return mode ?? "suggest";
3175
+ }
3176
+ function createQueuedFollowUpRecord(request, options = {}) {
3177
+ const createdAt = options.createdAt ?? new Date(request.timestamp).toISOString();
3178
+ return {
3179
+ id: request.id,
3180
+ sessionId: request.sessionId,
3181
+ message: request.message,
3182
+ createdAt,
3183
+ updatedAt: options.updatedAt ?? createdAt,
3184
+ mode: normalizeFollowUpMode(options.mode),
3185
+ status: "queued",
3186
+ ...options.sourceTurnId ? { sourceTurnId: options.sourceTurnId } : {},
3187
+ ...options.workflowInstanceId ? { workflowInstanceId: options.workflowInstanceId } : {}
3188
+ };
3189
+ }
3190
+ function resolveQueuedFollowUp(record, action, updatedAt) {
3191
+ return {
3192
+ ...record,
3193
+ status: action === "accept" ? "accepted" : "discarded",
3194
+ updatedAt,
3195
+ decidedAt: updatedAt
3196
+ };
3197
+ }
3198
+ function markQueuedFollowUpApplied(record, updatedAt, seededTurnId) {
3199
+ return {
3200
+ ...record,
3201
+ status: "applied",
3202
+ updatedAt,
3203
+ appliedAt: updatedAt,
3204
+ ...seededTurnId ? { seededTurnId } : {}
3205
+ };
3206
+ }
3207
+ function canSeedQueuedFollowUp(record) {
3208
+ if (record.status === "accepted") {
3209
+ return true;
3210
+ }
3211
+ return record.status === "queued" && record.mode === "auto-run";
1840
3212
  }
1841
3213
  export {
1842
3214
  Agent,
@@ -1847,37 +3219,49 @@ export {
1847
3219
  CapabilityCache,
1848
3220
  ContextManager,
1849
3221
  ContextOverflowError,
3222
+ DEFAULT_AGENT_NAME,
1850
3223
  DEFAULT_CONTEXT_LIMITS,
3224
+ DEFAULT_DISPATCH_TOOL_IDS,
1851
3225
  DEFAULT_EXTERNAL_DIRS,
1852
3226
  DEFAULT_INSTRUCTION_PATTERNS,
1853
- DEFAULT_MAX_CONCURRENT,
3227
+ DEFAULT_LOCAL_DISPATCH_CONCURRENCY,
3228
+ DEFAULT_LOCAL_DISPATCH_DEPTH,
3229
+ DEFAULT_LOCAL_DISPATCH_TITLE_PREFIX,
1854
3230
  DEFAULT_MAX_DEPTH,
1855
3231
  DEFAULT_MAX_FILE_SIZE,
1856
- DEFAULT_MAX_OUTPUT_TOKENS,
3232
+ DEFAULT_MAX_TOKENS as DEFAULT_MAX_OUTPUT_TOKENS,
1857
3233
  DEFAULT_MAX_SCAN_DEPTH,
1858
- DEFAULT_MAX_SPAWN_DEPTH,
1859
3234
  DEFAULT_MAX_STEPS,
1860
3235
  DEFAULT_MAX_TOKENS,
1861
3236
  DEFAULT_RESOLVER_OPTIONS,
1862
3237
  DEFAULT_RETRY_CONFIG,
1863
- DEFAULT_SESSION_TITLE_PREFIX,
1864
3238
  DEFAULT_SKILL_MAX_SIZE,
3239
+ DEFAULT_SUBAGENT_CONCURRENCY,
3240
+ DEFAULT_SUBAGENT_DEPTH,
3241
+ DEFAULT_SUBAGENT_SESSION_PREFIX,
1865
3242
  DEFAULT_SYSTEM_PROMPT,
3243
+ DISPATCH_STATES,
1866
3244
  DoomLoopError,
1867
3245
  EXTENDED_LEVELS,
1868
3246
  FIXED_LEVELS,
1869
3247
  FileStorage,
3248
+ HumanInputTimeoutError,
3249
+ HumanInputUnavailableError,
3250
+ InMemoryMailboxStore,
3251
+ InMemoryTaskBoardStore,
1870
3252
  Inference,
1871
3253
  InterventionController,
1872
- LLM,
1873
3254
  LLMError,
3255
+ LOCAL_SUBAGENT_BACKEND,
3256
+ LayeredSettings,
1874
3257
  LocalSignal,
1875
3258
  MAX_BYTES,
1876
3259
  MAX_LINES,
3260
+ Mailbox,
1877
3261
  MemoryStorage,
1878
3262
  MiddlewareRunner,
1879
3263
  ModelCapabilityResolver,
1880
- OUTPUT_TOKEN_MAX,
3264
+ NullSettings,
1881
3265
  PRIORITY_BASE,
1882
3266
  PRIORITY_CUSTOM,
1883
3267
  PRIORITY_ENVIRONMENT,
@@ -1886,37 +3270,54 @@ export {
1886
3270
  PRIORITY_SKILLS,
1887
3271
  PRUNE_PROTECTED_TOOLS,
1888
3272
  PatternCapabilitySource,
1889
- Presets,
3273
+ PluginEventBus,
3274
+ PluginRegistry,
3275
+ Profiles,
1890
3276
  PromptBuilder,
1891
3277
  RemoteCapabilityFetcher,
1892
3278
  RemoteCapabilitySource,
1893
3279
  SKILL_FILENAME,
1894
3280
  STANDARD_LEVELS,
1895
3281
  STORAGE_VERSION,
3282
+ SUBAGENT_TOOL_IDS,
1896
3283
  SessionManager,
1897
3284
  SkillRegistry,
1898
3285
  SourcePriority,
1899
- SubAgentTracker,
1900
- TRUNCATE_DIR,
1901
- TRUNCATE_GLOB,
3286
+ StaticSettings,
3287
+ TERMINAL_STATUSES,
3288
+ TaskBoard,
3289
+ TaskConflictError,
3290
+ TeamCoordinator,
1902
3291
  Tool,
3292
+ ToolHostRegistry,
1903
3293
  ToolRegistry,
1904
3294
  TurnChangeTracker,
3295
+ ValidatedSettings,
3296
+ accumulateUsage,
3297
+ addTokenUsage,
1905
3298
  advanceAgentTurnState,
3299
+ allApprovalConditions,
3300
+ anyApprovalConditions,
1906
3301
  applyAgentWorkflowCommitResult,
1907
3302
  applyAgentWorkflowModelStepResult,
1908
3303
  applyAgentWorkflowToolBatchResult,
1909
3304
  applyAgentWorkflowToolCallResult,
1910
3305
  applyCapabilityOverride,
1911
- applyPreset,
3306
+ applyProfile,
3307
+ applyWorkflowInterventions,
1912
3308
  approvalMiddleware,
3309
+ approvalRequestsOverlap,
1913
3310
  autoDetectStreamProvider,
1914
3311
  buildAnthropicOptions,
3312
+ buildApprovalRuleContext,
1915
3313
  buildBedrockOptions,
3314
+ buildCoordinatorNotificationEvent,
3315
+ buildCoordinatorSystemPrompt,
1916
3316
  buildEntryPath,
1917
3317
  buildGoogleOptions,
1918
3318
  buildGroqOptions,
1919
3319
  buildMessagesFromEntries,
3320
+ buildModelCallContext,
1920
3321
  buildOpenAIOptions,
1921
3322
  buildOpenRouterOptions,
1922
3323
  buildReasoningOptions,
@@ -1924,55 +3325,95 @@ export {
1924
3325
  buildToolSet,
1925
3326
  buildXAIOptions,
1926
3327
  calculateDelay,
3328
+ canSeedQueuedFollowUp,
1927
3329
  careful,
1928
- clearCheckpoints,
3330
+ clearInstalledSubAgents,
1929
3331
  cloneAgentWorkflowTurnState,
1930
3332
  code,
1931
3333
  commitOutput,
1932
3334
  commitStep,
1933
3335
  configureDefaultSessionManager,
1934
3336
  configureResolver,
3337
+ configureSubAgents,
1935
3338
  convertAgentMessagesToModelMessages,
3339
+ coordinatorToolDescriptions,
1936
3340
  createAgent,
1937
3341
  createAgentTaskRunner,
1938
3342
  createAgentTurnEngine,
1939
3343
  createAgentTurnState,
1940
3344
  createAgentTurnStepCommitBatch,
1941
3345
  createAgentWorkflowTurnState,
3346
+ createApprovalCorrection,
1942
3347
  createApprovalHandler,
1943
- createCheckpointManager,
3348
+ createApprovalPolicyPreset,
3349
+ createCloseAgentTool,
3350
+ createCompositeDispatchTaskExecutor,
3351
+ createConditionalApprovalRule,
3352
+ createConsoleLogger,
3353
+ createDangerouslyAllowAllApprovalPolicy,
3354
+ createDispatchExternalTaskControl,
3355
+ createDispatchTaskExecutor,
3356
+ createDispatchTools,
3357
+ createEventBus,
3358
+ createEventPrinter,
3359
+ createFileLogger,
3360
+ createHeadlessDenyApprovalPolicy,
3361
+ createHumanInputController,
3362
+ createHumanInputHandler,
3363
+ createHumanInputTool,
3364
+ createHumanInputToolWithController,
3365
+ createHumanInputToolWithHandler,
3366
+ createInteractiveApprovalPolicy,
3367
+ createInvokeAgentTool,
3368
+ createLocalDispatchRuntime,
1944
3369
  createMCPManager,
1945
3370
  createMessageEntry,
1946
3371
  createMetadataEntry,
1947
- createPreset,
3372
+ createProfile,
1948
3373
  createPromptBuilder,
3374
+ createQueuedFollowUpRecord,
3375
+ createRememberedApprovalRules,
1949
3376
  createResolver,
1950
3377
  createRetryHandler,
1951
3378
  createRetryState,
1952
- createScope,
3379
+ createRiskTierApprovalPolicy,
3380
+ createRuntimeDispatchExecutor,
3381
+ createRuntimeDispatchTargets,
1953
3382
  createSkillRegistry,
1954
3383
  createSkillResourceTool,
1955
3384
  createSkillTool,
1956
3385
  createSkillTools,
1957
3386
  createSubAgentTools,
3387
+ createTeamCoordinator,
1958
3388
  createTelemetryConfig,
3389
+ createThresholdApprovalRule,
3390
+ createToolSearchTool,
3391
+ createTrustedSessionApprovalPolicy,
1959
3392
  createTurnTracker,
3393
+ createWaitAgentTool,
1960
3394
  currentScope,
1961
3395
  defaultAgentTaskCheckpointStrategy,
1962
3396
  defaultRegistry,
1963
- defineServer,
1964
- defineTool,
3397
+ defaultToolHostRegistry,
3398
+ definePlugin,
3399
+ describeApprovalOperation,
1965
3400
  deserializeMessage,
1966
3401
  detectModelFamily,
1967
3402
  discoverInstructions,
3403
+ discoverPlugins,
1968
3404
  discoverSkills,
1969
- dockerHost,
3405
+ discoverSubAgentRoles,
3406
+ drainWorkflowInterventions,
1970
3407
  emptySkillRegistry,
3408
+ ensureNonEmpty,
3409
+ ensureSessionLoaded,
1971
3410
  estimateConversationTokens,
1972
3411
  estimateMessageTokens,
1973
3412
  estimateTokens,
3413
+ evaluateCoordinatorRoundTransition,
1974
3414
  executeAgentToolCall,
1975
3415
  explore,
3416
+ extractApprovalPatterns,
1976
3417
  extractFilePathsFromArgs,
1977
3418
  extractModelId,
1978
3419
  extractProvider,
@@ -1982,76 +3423,123 @@ export {
1982
3423
  filterTools,
1983
3424
  findCapabilityOverride,
1984
3425
  findCutPoint,
3426
+ formatApprovalDeniedReason,
3427
+ formatAsyncSpawnedResult,
3428
+ formatCancelledAgentResult,
3429
+ formatCloseAlreadyResolvedResult,
3430
+ formatCloseMissingAgentResult,
3431
+ formatCoordinatorRoundMessage,
3432
+ formatCoordinatorTaskNotifications,
3433
+ formatCoordinatorWorkerReports,
1985
3434
  formatEnvironment,
1986
3435
  formatInstructions,
1987
- formatSize,
3436
+ formatInvalidAgentTypeResult,
3437
+ formatMissingAgentsResult,
3438
+ formatSpawnBlockedResult,
3439
+ formatSyncSubAgentErrorResult,
3440
+ formatSyncSubAgentResult,
3441
+ formatWaitErrorResult,
3442
+ formatWaitResult,
3443
+ formatWaitTimeoutResult,
1988
3444
  gatherEnvironment,
1989
3445
  generateEntryId,
1990
- generateSummary,
1991
3446
  getAvailableFamilies,
3447
+ getConfiguredSubAgents,
1992
3448
  getDataDir,
1993
3449
  getDefaultResolver,
1994
3450
  getDefaultSessionManager,
1995
3451
  getErrorCategory,
1996
3452
  getGitRootHash,
3453
+ getInstalledSubAgentBackend,
1997
3454
  getLeafId,
1998
3455
  getModelId,
1999
3456
  getNetworkStatus,
3457
+ getPluginLoader,
2000
3458
  getProjectId,
2001
3459
  getProjectSessionsDir,
3460
+ getProjectSubAgentRolesDir,
2002
3461
  getProviderCompatibility,
2003
3462
  getProviderId,
2004
3463
  getProviderOptionsKey,
2005
3464
  getReasoningConfig,
2006
3465
  getReasoningConfigSync,
3466
+ getRequiredToolHost,
2007
3467
  getRetryDelay,
2008
3468
  getSessionsDir,
2009
3469
  getTemplate,
2010
3470
  getToolRisk,
2011
- hasStreamProviderFactory,
3471
+ getUsableTokenLimit,
3472
+ getUserSubAgentRolesDir,
2012
3473
  httpServer,
2013
3474
  inferContextWindow,
2014
3475
  inferProvider,
2015
3476
  inferResourceType,
2016
- isContextOverflowing,
3477
+ installLocalSubAgents,
3478
+ installSubAgentTools,
3479
+ isApprovalMiddleware,
3480
+ isBlockedModelCall,
3481
+ isDefinedPlugin,
3482
+ isHumanInputController,
3483
+ isMarkdownSubAgentRole,
2017
3484
  isRetryable,
2018
3485
  isRetryableCategory,
2019
3486
  likelySupportsReasoning,
2020
3487
  loadGlobalInstructions,
3488
+ loadPluginModule,
2021
3489
  loadResourceContent,
2022
3490
  loadSkillContent,
2023
3491
  loadSkillMetadata,
2024
3492
  localHost,
2025
- mergePresets,
2026
- needsCustomStreamProvider,
3493
+ markQueuedFollowUpApplied,
3494
+ matchApprovalArgValue,
3495
+ matchApprovalNumericArg,
3496
+ matchApprovalPattern,
3497
+ matchApprovalRisks,
3498
+ matchApprovalSessions,
3499
+ matchApprovalStringPrefixes,
3500
+ mergeInspection,
3501
+ mergeProfiles,
3502
+ normalizeApprovalCascadePolicy,
3503
+ normalizeFollowUpMode,
3504
+ normalizeRememberScopes,
2027
3505
  normalizeToolReplayPolicy,
2028
3506
  otelMiddleware,
2029
3507
  parseFrontmatter,
2030
3508
  parseJSONL,
3509
+ parseMarkdownSubAgentRole,
2031
3510
  parseRetryDelay,
3511
+ parseSubAgentRoleFrontmatter,
3512
+ parseSubAgentToolSpec,
2032
3513
  plan,
2033
3514
  planNextAgentWorkflowOperation,
2034
3515
  prepareModelStep,
2035
3516
  processStepStream,
2036
- processStream,
2037
3517
  promptCacheMiddleware,
2038
- pruneContext,
2039
- pruneToolResults,
3518
+ queueWorkflowFollowUps,
2040
3519
  quick,
2041
3520
  recordAgentWorkflowReplayDecision,
3521
+ requiresToolHost,
3522
+ resetFrameworkAliases,
3523
+ resetPluginLoader,
3524
+ resolveAgentDefaults,
3525
+ resolveCapability,
3526
+ resolveFrameworkAliases,
3527
+ resolveQueuedFollowUp,
2042
3528
  restoreAgentWorkflowMessage,
2043
3529
  restoreAgentWorkflowMessages,
2044
3530
  restoreScope,
2045
3531
  review,
2046
3532
  runChatLoop,
2047
- runConcurrent,
2048
3533
  runModelStep,
2049
3534
  runToolBatch,
3535
+ sandboxDefaultsProvider,
3536
+ selectRememberScope,
2050
3537
  serializeMessage,
2051
3538
  shouldCaptureBaseline,
3539
+ shouldCascadeApprovalDecision,
2052
3540
  shouldIncludeReasoningSummary,
2053
- shouldPruneContext,
2054
3541
  shouldRetry,
3542
+ silentLogger,
2055
3543
  sleep,
2056
3544
  snapshotAgentWorkflowMessage,
2057
3545
  snapshotAgentWorkflowMessages,
@@ -2064,11 +3552,12 @@ export {
2064
3552
  summarizeEnvironment,
2065
3553
  supportsReasoning,
2066
3554
  supportsReasoningSync,
3555
+ teamPermissionPolicy,
2067
3556
  toJSONL,
2068
3557
  toJSONLBatch,
3558
+ toSubAgentRole,
2069
3559
  truncateOutput,
2070
3560
  watch,
2071
- withFileTracking,
2072
3561
  withRetry,
2073
3562
  withinScope
2074
3563
  };