@dexto/core 1.6.25 → 1.6.27

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 (150) hide show
  1. package/dist/agent/DextoAgent.cjs +102 -104
  2. package/dist/agent/DextoAgent.d.ts +11 -10
  3. package/dist/agent/DextoAgent.d.ts.map +1 -1
  4. package/dist/agent/DextoAgent.js +103 -105
  5. package/dist/agent/error-codes.cjs +1 -0
  6. package/dist/agent/error-codes.d.ts +1 -0
  7. package/dist/agent/error-codes.d.ts.map +1 -1
  8. package/dist/agent/error-codes.js +1 -0
  9. package/dist/agent/errors.cjs +13 -0
  10. package/dist/agent/errors.d.ts +6 -0
  11. package/dist/agent/errors.d.ts.map +1 -1
  12. package/dist/agent/errors.js +13 -0
  13. package/dist/agent/index.d.ts +1 -0
  14. package/dist/agent/index.d.ts.map +1 -1
  15. package/dist/agent/schemas.d.ts +2 -2
  16. package/dist/agent/types.d.ts +11 -0
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/approval/factory.cjs +1 -0
  19. package/dist/approval/factory.d.ts.map +1 -1
  20. package/dist/approval/factory.js +1 -0
  21. package/dist/approval/manager.cjs +345 -182
  22. package/dist/approval/manager.d.ts +45 -31
  23. package/dist/approval/manager.d.ts.map +1 -1
  24. package/dist/approval/manager.js +345 -182
  25. package/dist/approval/schemas.cjs +10 -0
  26. package/dist/approval/schemas.d.ts +305 -0
  27. package/dist/approval/schemas.d.ts.map +1 -1
  28. package/dist/approval/schemas.js +10 -0
  29. package/dist/approval/session-approval-store.cjs +91 -0
  30. package/dist/approval/session-approval-store.d.ts +55 -0
  31. package/dist/approval/session-approval-store.d.ts.map +1 -0
  32. package/dist/approval/session-approval-store.js +68 -0
  33. package/dist/events/index.cjs +210 -75
  34. package/dist/events/index.d.ts +44 -181
  35. package/dist/events/index.d.ts.map +1 -1
  36. package/dist/events/index.js +206 -74
  37. package/dist/hooks/manager.cjs +5 -2
  38. package/dist/hooks/manager.d.ts +2 -0
  39. package/dist/hooks/manager.d.ts.map +1 -1
  40. package/dist/hooks/manager.js +5 -2
  41. package/dist/hooks/types.d.ts +3 -0
  42. package/dist/hooks/types.d.ts.map +1 -1
  43. package/dist/index.browser.d.ts +1 -0
  44. package/dist/index.browser.d.ts.map +1 -1
  45. package/dist/index.cjs +3 -1
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +1 -0
  49. package/dist/llm/executor/turn-executor.cjs +15 -7
  50. package/dist/llm/executor/turn-executor.d.ts +3 -1
  51. package/dist/llm/executor/turn-executor.d.ts.map +1 -1
  52. package/dist/llm/executor/turn-executor.js +15 -7
  53. package/dist/llm/services/factory.cjs +10 -4
  54. package/dist/llm/services/factory.d.ts +2 -21
  55. package/dist/llm/services/factory.d.ts.map +1 -1
  56. package/dist/llm/services/factory.js +11 -7
  57. package/dist/llm/services/types.d.ts +33 -2
  58. package/dist/llm/services/types.d.ts.map +1 -1
  59. package/dist/llm/services/vercel.cjs +33 -11
  60. package/dist/llm/services/vercel.d.ts +6 -3
  61. package/dist/llm/services/vercel.d.ts.map +1 -1
  62. package/dist/llm/services/vercel.js +29 -8
  63. package/dist/logger/default-logger-factory.d.ts +12 -12
  64. package/dist/logger/v2/schemas.d.ts +6 -6
  65. package/dist/mcp/manager.cjs +7 -2
  66. package/dist/mcp/manager.d.ts +3 -1
  67. package/dist/mcp/manager.d.ts.map +1 -1
  68. package/dist/mcp/manager.js +7 -2
  69. package/dist/mcp/mcp-client.cjs +71 -62
  70. package/dist/mcp/mcp-client.d.ts +3 -2
  71. package/dist/mcp/mcp-client.d.ts.map +1 -1
  72. package/dist/mcp/mcp-client.js +71 -62
  73. package/dist/mcp/schemas.d.ts +10 -10
  74. package/dist/resources/handlers/filesystem-handler.cjs +22 -3
  75. package/dist/resources/handlers/filesystem-handler.d.ts.map +1 -1
  76. package/dist/resources/handlers/filesystem-handler.js +22 -3
  77. package/dist/runtime/host-runtime.cjs +163 -0
  78. package/dist/runtime/host-runtime.d.ts +23 -0
  79. package/dist/runtime/host-runtime.d.ts.map +1 -0
  80. package/dist/runtime/host-runtime.js +133 -0
  81. package/dist/runtime/index.cjs +42 -0
  82. package/dist/runtime/index.d.ts +2 -0
  83. package/dist/runtime/index.d.ts.map +1 -0
  84. package/dist/runtime/index.js +21 -0
  85. package/dist/runtime/run-context.cjs +53 -0
  86. package/dist/runtime/run-context.d.ts +13 -0
  87. package/dist/runtime/run-context.d.ts.map +1 -0
  88. package/dist/runtime/run-context.js +34 -0
  89. package/dist/session/chat-session.cjs +67 -71
  90. package/dist/session/chat-session.d.ts +25 -25
  91. package/dist/session/chat-session.d.ts.map +1 -1
  92. package/dist/session/chat-session.js +68 -72
  93. package/dist/session/error-codes.cjs +1 -0
  94. package/dist/session/error-codes.d.ts +2 -1
  95. package/dist/session/error-codes.d.ts.map +1 -1
  96. package/dist/session/error-codes.js +1 -0
  97. package/dist/session/errors.cjs +13 -0
  98. package/dist/session/errors.d.ts +6 -0
  99. package/dist/session/errors.d.ts.map +1 -1
  100. package/dist/session/errors.js +13 -0
  101. package/dist/session/message-queue-store.cjs +75 -0
  102. package/dist/session/message-queue-store.d.ts +16 -0
  103. package/dist/session/message-queue-store.d.ts.map +1 -0
  104. package/dist/session/message-queue-store.js +52 -0
  105. package/dist/session/message-queue.cjs +140 -46
  106. package/dist/session/message-queue.d.ts +18 -6
  107. package/dist/session/message-queue.d.ts.map +1 -1
  108. package/dist/session/message-queue.js +140 -46
  109. package/dist/session/session-manager.cjs +130 -25
  110. package/dist/session/session-manager.d.ts +18 -1
  111. package/dist/session/session-manager.d.ts.map +1 -1
  112. package/dist/session/session-manager.js +130 -25
  113. package/dist/session/title-generator.cjs +9 -2
  114. package/dist/session/title-generator.d.ts +2 -0
  115. package/dist/session/title-generator.d.ts.map +1 -1
  116. package/dist/session/title-generator.js +9 -2
  117. package/dist/telemetry/decorators.cjs +75 -57
  118. package/dist/telemetry/decorators.d.ts +2 -0
  119. package/dist/telemetry/decorators.d.ts.map +1 -1
  120. package/dist/telemetry/decorators.js +75 -57
  121. package/dist/telemetry/errors.cjs +2 -2
  122. package/dist/telemetry/errors.js +2 -2
  123. package/dist/telemetry/index.d.ts +1 -1
  124. package/dist/telemetry/index.d.ts.map +1 -1
  125. package/dist/telemetry/index.js +3 -1
  126. package/dist/telemetry/telemetry.cjs +62 -21
  127. package/dist/telemetry/telemetry.d.ts +14 -0
  128. package/dist/telemetry/telemetry.d.ts.map +1 -1
  129. package/dist/telemetry/telemetry.js +62 -21
  130. package/dist/telemetry/utils.cjs +9 -6
  131. package/dist/telemetry/utils.d.ts +3 -0
  132. package/dist/telemetry/utils.d.ts.map +1 -1
  133. package/dist/telemetry/utils.js +9 -6
  134. package/dist/test-utils/session-state-stores.cjs +68 -0
  135. package/dist/test-utils/session-state-stores.js +42 -0
  136. package/dist/tools/session-tool-preferences-store.cjs +86 -0
  137. package/dist/tools/session-tool-preferences-store.d.ts +29 -0
  138. package/dist/tools/session-tool-preferences-store.d.ts.map +1 -0
  139. package/dist/tools/session-tool-preferences-store.js +63 -0
  140. package/dist/tools/tool-manager.cjs +223 -68
  141. package/dist/tools/tool-manager.d.ts +29 -9
  142. package/dist/tools/tool-manager.d.ts.map +1 -1
  143. package/dist/tools/tool-manager.js +223 -68
  144. package/dist/tools/types.d.ts +7 -1
  145. package/dist/tools/types.d.ts.map +1 -1
  146. package/dist/utils/service-initializer.cjs +38 -5
  147. package/dist/utils/service-initializer.d.ts +11 -1
  148. package/dist/utils/service-initializer.d.ts.map +1 -1
  149. package/dist/utils/service-initializer.js +36 -4
  150. package/package.json +1 -1
@@ -81,6 +81,24 @@ _ToolManager_decorators = [(0, import_decorators.InstrumentClass)({
81
81
  excludeMethods: ["setHookSupport", "getApprovalManager", "getAllowedToolsProvider"]
82
82
  })];
83
83
  let _ToolManager = class _ToolManager {
84
+ constructor(mcpManager, approvalManager, allowedToolsProvider, approvalMode, agentEventBus, toolPolicies, tools, logger, sessionToolPreferencesStore) {
85
+ this.sessionToolPreferencesStore = sessionToolPreferencesStore;
86
+ this.mcpManager = mcpManager;
87
+ this.approvalManager = approvalManager;
88
+ this.allowedToolsProvider = allowedToolsProvider;
89
+ this.approvalMode = approvalMode;
90
+ this.agentEventBus = agentEventBus;
91
+ this.toolPolicies = toolPolicies;
92
+ this.logger = logger.createChild(import_types2.DextoLogComponent.TOOLS);
93
+ this.setTools(tools);
94
+ this.toolExecutionContextFactory = () => {
95
+ throw import_errors.ToolError.configInvalid(
96
+ "ToolExecutionContextFactory not configured. DextoAgent.start() must configure tool execution context before tools can run."
97
+ );
98
+ };
99
+ this.setupNotificationListeners();
100
+ this.logger.debug("ToolManager initialized");
101
+ }
84
102
  mcpManager;
85
103
  agentTools = /* @__PURE__ */ new Map();
86
104
  approvalManager;
@@ -113,6 +131,8 @@ let _ToolManager = class _ToolManager {
113
131
  // Session-level auto-approve tools set by users (UI)
114
132
  sessionUserAutoApproveTools = /* @__PURE__ */ new Map();
115
133
  sessionDisabledTools = /* @__PURE__ */ new Map();
134
+ restoredSessionPreferences = /* @__PURE__ */ new Set();
135
+ sessionPreferenceLocks = /* @__PURE__ */ new Map();
116
136
  globalDisabledTools = [];
117
137
  cleanupHandlers = /* @__PURE__ */ new Set();
118
138
  cleanupStarted = false;
@@ -136,22 +156,76 @@ let _ToolManager = class _ToolManager {
136
156
  }
137
157
  return this.resolveLocalToolIdOrAlias(pattern) ?? pattern;
138
158
  }
139
- constructor(mcpManager, approvalManager, allowedToolsProvider, approvalMode, agentEventBus, toolPolicies, tools, logger) {
140
- this.mcpManager = mcpManager;
141
- this.approvalManager = approvalManager;
142
- this.allowedToolsProvider = allowedToolsProvider;
143
- this.approvalMode = approvalMode;
144
- this.agentEventBus = agentEventBus;
145
- this.toolPolicies = toolPolicies;
146
- this.logger = logger.createChild(import_types2.DextoLogComponent.TOOLS);
147
- this.setTools(tools);
148
- this.toolExecutionContextFactory = () => {
149
- throw import_errors.ToolError.configInvalid(
150
- "ToolExecutionContextFactory not configured. DextoAgent.start() must configure tool execution context before tools can run."
151
- );
159
+ async runWithSessionPreferenceLock(sessionId, fn) {
160
+ const previousLock = this.sessionPreferenceLocks.get(sessionId) ?? Promise.resolve();
161
+ const currentResult = previousLock.catch(() => {
162
+ }).then(() => fn());
163
+ const currentLock = currentResult.then(
164
+ () => void 0,
165
+ () => void 0
166
+ );
167
+ this.sessionPreferenceLocks.set(sessionId, currentLock);
168
+ try {
169
+ return await currentResult;
170
+ } finally {
171
+ if (this.sessionPreferenceLocks.get(sessionId) === currentLock) {
172
+ this.sessionPreferenceLocks.delete(sessionId);
173
+ }
174
+ }
175
+ }
176
+ applySessionToolPreferences(sessionId, preferences) {
177
+ if (preferences.userAutoApproveTools.length > 0) {
178
+ this.sessionUserAutoApproveTools.set(sessionId, [...preferences.userAutoApproveTools]);
179
+ } else {
180
+ this.sessionUserAutoApproveTools.delete(sessionId);
181
+ }
182
+ if (preferences.disabledTools.length > 0) {
183
+ this.sessionDisabledTools.set(sessionId, [...preferences.disabledTools]);
184
+ } else {
185
+ this.sessionDisabledTools.delete(sessionId);
186
+ }
187
+ }
188
+ getSessionToolPreferencesSnapshot(sessionId) {
189
+ return {
190
+ userAutoApproveTools: [...this.sessionUserAutoApproveTools.get(sessionId) ?? []],
191
+ disabledTools: [...this.sessionDisabledTools.get(sessionId) ?? []]
152
192
  };
153
- this.setupNotificationListeners();
154
- this.logger.debug("ToolManager initialized");
193
+ }
194
+ async restoreSessionState(sessionId) {
195
+ if (this.restoredSessionPreferences.has(sessionId)) {
196
+ return;
197
+ }
198
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
199
+ if (this.restoredSessionPreferences.has(sessionId)) {
200
+ return;
201
+ }
202
+ const preferences = await this.sessionToolPreferencesStore.load(sessionId);
203
+ this.applySessionToolPreferences(sessionId, preferences);
204
+ this.restoredSessionPreferences.add(sessionId);
205
+ this.logger.debug("Restored persisted session tool preferences", {
206
+ sessionId,
207
+ autoApproveCount: preferences.userAutoApproveTools.length,
208
+ disabledCount: preferences.disabledTools.length
209
+ });
210
+ });
211
+ }
212
+ evictSessionState(sessionId) {
213
+ this.sessionAutoApproveTools.delete(sessionId);
214
+ this.sessionUserAutoApproveTools.delete(sessionId);
215
+ this.sessionDisabledTools.delete(sessionId);
216
+ this.restoredSessionPreferences.delete(sessionId);
217
+ }
218
+ async deleteSessionState(sessionId) {
219
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
220
+ this.evictSessionState(sessionId);
221
+ await this.sessionToolPreferencesStore.delete(sessionId);
222
+ });
223
+ }
224
+ async persistSessionToolPreferences(sessionId) {
225
+ await this.sessionToolPreferencesStore.save(
226
+ sessionId,
227
+ this.getSessionToolPreferencesSnapshot(sessionId)
228
+ );
155
229
  }
156
230
  /**
157
231
  * Initialize the ToolManager and its components
@@ -308,15 +382,19 @@ let _ToolManager = class _ToolManager {
308
382
  /**
309
383
  * Set session-level auto-approve tools chosen by the user.
310
384
  */
311
- setSessionUserAutoApproveTools(sessionId, autoApproveTools) {
385
+ async setSessionUserAutoApproveTools(sessionId, autoApproveTools) {
386
+ await this.restoreSessionState(sessionId);
312
387
  if (autoApproveTools.length === 0) {
313
- this.clearSessionUserAutoApproveTools(sessionId);
388
+ await this.clearSessionUserAutoApproveTools(sessionId);
314
389
  return;
315
390
  }
316
391
  const normalized = autoApproveTools.map(
317
392
  (pattern) => this.normalizeToolPolicyPattern(pattern)
318
393
  );
319
- this.sessionUserAutoApproveTools.set(sessionId, normalized);
394
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
395
+ this.sessionUserAutoApproveTools.set(sessionId, normalized);
396
+ await this.persistSessionToolPreferences(sessionId);
397
+ });
320
398
  this.logger.info(
321
399
  `Session user auto-approve tools set for '${sessionId}': ${autoApproveTools.length} tools`
322
400
  );
@@ -325,9 +403,14 @@ let _ToolManager = class _ToolManager {
325
403
  /**
326
404
  * Clear session-level auto-approve tools chosen by the user.
327
405
  */
328
- clearSessionUserAutoApproveTools(sessionId) {
329
- const hadAutoApprove = this.sessionUserAutoApproveTools.has(sessionId);
330
- this.sessionUserAutoApproveTools.delete(sessionId);
406
+ async clearSessionUserAutoApproveTools(sessionId) {
407
+ await this.restoreSessionState(sessionId);
408
+ let hadAutoApprove = false;
409
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
410
+ hadAutoApprove = this.sessionUserAutoApproveTools.has(sessionId);
411
+ this.sessionUserAutoApproveTools.delete(sessionId);
412
+ await this.persistSessionToolPreferences(sessionId);
413
+ });
331
414
  if (hadAutoApprove) {
332
415
  this.logger.info(`Session user auto-approve tools cleared for '${sessionId}'`);
333
416
  }
@@ -368,12 +451,16 @@ let _ToolManager = class _ToolManager {
368
451
  /**
369
452
  * Set session-level disabled tools (overrides global list).
370
453
  */
371
- setSessionDisabledTools(sessionId, toolNames) {
454
+ async setSessionDisabledTools(sessionId, toolNames) {
455
+ await this.restoreSessionState(sessionId);
372
456
  if (toolNames.length === 0) {
373
- this.clearSessionDisabledTools(sessionId);
457
+ await this.clearSessionDisabledTools(sessionId);
374
458
  return;
375
459
  }
376
- this.sessionDisabledTools.set(sessionId, [...toolNames]);
460
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
461
+ this.sessionDisabledTools.set(sessionId, [...toolNames]);
462
+ await this.persistSessionToolPreferences(sessionId);
463
+ });
377
464
  this.logger.info("Session disabled tools updated", {
378
465
  sessionId,
379
466
  count: toolNames.length
@@ -387,9 +474,14 @@ let _ToolManager = class _ToolManager {
387
474
  /**
388
475
  * Clear session-level disabled tools.
389
476
  */
390
- clearSessionDisabledTools(sessionId) {
391
- const hadOverrides = this.sessionDisabledTools.has(sessionId);
392
- this.sessionDisabledTools.delete(sessionId);
477
+ async clearSessionDisabledTools(sessionId) {
478
+ await this.restoreSessionState(sessionId);
479
+ let hadOverrides = false;
480
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
481
+ hadOverrides = this.sessionDisabledTools.has(sessionId);
482
+ this.sessionDisabledTools.delete(sessionId);
483
+ await this.persistSessionToolPreferences(sessionId);
484
+ });
393
485
  if (hadOverrides) {
394
486
  this.logger.info("Session disabled tools cleared", { sessionId });
395
487
  }
@@ -585,7 +677,7 @@ let _ToolManager = class _ToolManager {
585
677
  }
586
678
  return snapshot;
587
679
  }
588
- getToolPresentationSnapshotForToolCallEvent(toolName, args, toolCallId, sessionId) {
680
+ getToolPresentationSnapshotForToolCallEvent(toolName, args, toolCallId, sessionId, runContext) {
589
681
  const fallback = this.buildGenericToolPresentationSnapshot(toolName);
590
682
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
591
683
  return fallback;
@@ -597,7 +689,7 @@ let _ToolManager = class _ToolManager {
597
689
  }
598
690
  try {
599
691
  const validatedArgs = this.validateLocalToolArgs(toolName, args);
600
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
692
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
601
693
  const isPromiseLike = (value) => {
602
694
  if (typeof value !== "object" || value === null) {
603
695
  return false;
@@ -631,7 +723,7 @@ let _ToolManager = class _ToolManager {
631
723
  return fallback;
632
724
  }
633
725
  }
634
- async getToolPresentationSnapshotForCall(toolName, args, toolCallId, sessionId) {
726
+ async getToolPresentationSnapshotForCall(toolName, args, toolCallId, sessionId, runContext) {
635
727
  const fallback = this.buildGenericToolPresentationSnapshot(toolName);
636
728
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
637
729
  return fallback;
@@ -642,7 +734,7 @@ let _ToolManager = class _ToolManager {
642
734
  return fallback;
643
735
  }
644
736
  try {
645
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
737
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
646
738
  const describedHeader = describeHeader ? await Promise.resolve(describeHeader(args, context)) : null;
647
739
  const describedArgs = describeArgs ? await Promise.resolve(describeArgs(args, context)) : null;
648
740
  return {
@@ -657,7 +749,7 @@ let _ToolManager = class _ToolManager {
657
749
  return fallback;
658
750
  }
659
751
  }
660
- async augmentSnapshotWithResult(toolName, snapshot, result, args, toolCallId, sessionId) {
752
+ async augmentSnapshotWithResult(toolName, snapshot, result, args, toolCallId, sessionId, runContext) {
661
753
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
662
754
  return snapshot;
663
755
  }
@@ -666,7 +758,7 @@ let _ToolManager = class _ToolManager {
666
758
  return snapshot;
667
759
  }
668
760
  try {
669
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
761
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
670
762
  const resultPresentation = await Promise.resolve(describeResult(result, args, context));
671
763
  if (!resultPresentation) {
672
764
  return snapshot;
@@ -789,7 +881,7 @@ let _ToolManager = class _ToolManager {
789
881
  return false;
790
882
  }
791
883
  if (!patternKey) return false;
792
- return this.approvalManager.matchesPattern(toolName, patternKey);
884
+ return this.approvalManager.matchesPattern(toolName, patternKey, sessionId);
793
885
  },
794
886
  { rememberPattern: void 0 }
795
887
  // Don't propagate pattern choice to auto-approved requests
@@ -820,7 +912,10 @@ let _ToolManager = class _ToolManager {
820
912
  if (!directoryAccess) {
821
913
  return false;
822
914
  }
823
- return this.approvalManager.isDirectorySessionApproved(directoryAccess.parentDir);
915
+ return this.approvalManager.isDirectorySessionApproved(
916
+ directoryAccess.parentDir,
917
+ sessionId
918
+ );
824
919
  },
825
920
  { rememberDirectory: false }
826
921
  );
@@ -897,14 +992,33 @@ let _ToolManager = class _ToolManager {
897
992
  const workspace = this.currentWorkspace;
898
993
  const baseContext = {
899
994
  sessionId: options.sessionId,
995
+ runContext: options.runContext,
900
996
  workspaceId: workspace?.id,
901
997
  workspace,
902
998
  abortSignal: options.abortSignal,
903
999
  toolCallId: options.toolCallId,
1000
+ hostRuntime: options.runContext?.hostRuntime,
904
1001
  logger: this.logger
905
1002
  };
906
1003
  return this.toolExecutionContextFactory(baseContext);
907
1004
  }
1005
+ resolveToolExecutionInvocation(invocationOrSessionId, legacyAbortSignal) {
1006
+ if (typeof invocationOrSessionId === "string") {
1007
+ return {
1008
+ sessionId: invocationOrSessionId,
1009
+ abortSignal: legacyAbortSignal,
1010
+ hostRuntime: void 0
1011
+ };
1012
+ }
1013
+ const invocation = invocationOrSessionId ?? {};
1014
+ const sessionId = invocation.runContext?.sessionId ?? invocation.sessionId;
1015
+ return {
1016
+ ...invocation,
1017
+ ...invocation.abortSignal === void 0 && legacyAbortSignal !== void 0 ? { abortSignal: legacyAbortSignal } : {},
1018
+ sessionId,
1019
+ hostRuntime: invocation.runContext?.hostRuntime
1020
+ };
1021
+ }
908
1022
  validateLocalToolArgs(toolName, args) {
909
1023
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
910
1024
  return args;
@@ -929,7 +1043,7 @@ let _ToolManager = class _ToolManager {
929
1043
  }
930
1044
  return validated;
931
1045
  }
932
- async executeLocalTool(toolName, args, sessionId, abortSignal, toolCallId) {
1046
+ async executeLocalTool(toolName, args, options) {
933
1047
  const tool = this.agentTools.get(toolName);
934
1048
  if (!tool) {
935
1049
  this.logger.error(`\u274C No local tool found: ${toolName}`);
@@ -939,7 +1053,12 @@ let _ToolManager = class _ToolManager {
939
1053
  throw import_errors.ToolError.notFound(toolName);
940
1054
  }
941
1055
  try {
942
- const context = this.buildToolExecutionContext({ sessionId, abortSignal, toolCallId });
1056
+ const context = this.buildToolExecutionContext({
1057
+ sessionId: options?.sessionId,
1058
+ abortSignal: options?.abortSignal,
1059
+ toolCallId: options?.toolCallId,
1060
+ runContext: options?.runContext
1061
+ });
943
1062
  const result = await tool.execute(args, context);
944
1063
  return result;
945
1064
  } catch (error) {
@@ -1036,10 +1155,12 @@ let _ToolManager = class _ToolManager {
1036
1155
  * @param toolName Tool name (e.g., "edit_file", "mcp--filesystem--read_file")
1037
1156
  * @param args The arguments for the tool
1038
1157
  * @param toolCallId The unique tool call ID for tracking (from LLM or generated for direct calls)
1039
- * @param sessionId Optional session ID for context
1040
- * @param abortSignal Optional abort signal for cancellation support
1158
+ * @param invocationOrSessionId Optional execution-scoped context for this tool call,
1159
+ * or the legacy positional sessionId
1160
+ * @param legacyAbortSignal Optional legacy positional abort signal
1041
1161
  */
1042
- async executeTool(toolName, args, toolCallId, sessionId, abortSignal) {
1162
+ async executeTool(toolName, args, toolCallId, invocationOrSessionId, legacyAbortSignal) {
1163
+ const { sessionId, abortSignal, runContext, hostRuntime } = this.resolveToolExecutionInvocation(invocationOrSessionId, legacyAbortSignal);
1043
1164
  const { toolArgs: rawToolArgs, meta } = (0, import_tool_call_metadata.extractToolCallMeta)(args);
1044
1165
  const eventMeta = Object.keys(meta).length > 0 ? meta : void 0;
1045
1166
  let toolArgs = rawToolArgs;
@@ -1052,7 +1173,8 @@ let _ToolManager = class _ToolManager {
1052
1173
  toolName,
1053
1174
  toolArgs,
1054
1175
  toolCallId,
1055
- sessionId
1176
+ sessionId,
1177
+ runContext
1056
1178
  );
1057
1179
  this.agentEventBus.emit("llm:tool-call", {
1058
1180
  toolName,
@@ -1061,7 +1183,8 @@ let _ToolManager = class _ToolManager {
1061
1183
  ...eventMeta !== void 0 ? { meta: eventMeta } : {},
1062
1184
  ...callDescription !== void 0 && { callDescription },
1063
1185
  callId: toolCallId,
1064
- sessionId
1186
+ sessionId,
1187
+ ...hostRuntime !== void 0 && { hostRuntime }
1065
1188
  });
1066
1189
  }
1067
1190
  const {
@@ -1074,6 +1197,7 @@ let _ToolManager = class _ToolManager {
1074
1197
  toolArgs,
1075
1198
  toolCallId,
1076
1199
  sessionId,
1200
+ runContext,
1077
1201
  callDescription
1078
1202
  );
1079
1203
  toolArgs = validatedToolArgs;
@@ -1085,7 +1209,8 @@ let _ToolManager = class _ToolManager {
1085
1209
  this.agentEventBus.emit("tool:running", {
1086
1210
  toolName,
1087
1211
  toolCallId,
1088
- sessionId
1212
+ sessionId,
1213
+ ...hostRuntime !== void 0 && { hostRuntime }
1089
1214
  });
1090
1215
  }
1091
1216
  const startTime = Date.now();
@@ -1103,6 +1228,7 @@ let _ToolManager = class _ToolManager {
1103
1228
  mcpManager: this.mcpManager,
1104
1229
  toolManager: this,
1105
1230
  stateManager: this.stateManager,
1231
+ ...runContext !== void 0 && { runContext },
1106
1232
  ...sessionId !== void 0 && { sessionId }
1107
1233
  }
1108
1234
  );
@@ -1137,6 +1263,12 @@ let _ToolManager = class _ToolManager {
1137
1263
  }
1138
1264
  this.logger.debug(`\u{1F3AF} MCP routing: '${toolName}' -> '${actualToolName}'`);
1139
1265
  const runInBackground = backgroundTasksEnabled && meta.runInBackground === true && sessionId !== void 0;
1266
+ const executeMcpTool = () => runContext === void 0 ? this.mcpManager.executeTool(actualToolName, toolArgs, sessionId) : this.mcpManager.executeTool(
1267
+ actualToolName,
1268
+ toolArgs,
1269
+ sessionId,
1270
+ runContext
1271
+ );
1140
1272
  if (meta.runInBackground === true && !backgroundTasksEnabled) {
1141
1273
  this.logger.debug(
1142
1274
  "Background tool execution disabled; running synchronously instead.",
@@ -1146,7 +1278,7 @@ let _ToolManager = class _ToolManager {
1146
1278
  if (runInBackground) {
1147
1279
  const backgroundSessionId = sessionId;
1148
1280
  const { result: backgroundResult, promise } = registerBackgroundTask(
1149
- this.mcpManager.executeTool(actualToolName, toolArgs, backgroundSessionId),
1281
+ executeMcpTool(),
1150
1282
  `MCP tool ${actualToolName}`
1151
1283
  );
1152
1284
  this.agentEventBus.emit("tool:background", {
@@ -1155,6 +1287,7 @@ let _ToolManager = class _ToolManager {
1155
1287
  sessionId: backgroundSessionId,
1156
1288
  description: backgroundResult.description,
1157
1289
  promise,
1290
+ ...hostRuntime !== void 0 && { hostRuntime },
1158
1291
  ...meta.timeoutMs !== void 0 && { timeoutMs: meta.timeoutMs },
1159
1292
  ...meta.notifyOnComplete !== void 0 && {
1160
1293
  notifyOnComplete: meta.notifyOnComplete
@@ -1162,7 +1295,7 @@ let _ToolManager = class _ToolManager {
1162
1295
  });
1163
1296
  result = backgroundResult;
1164
1297
  } else {
1165
- result = await this.mcpManager.executeTool(actualToolName, toolArgs, sessionId);
1298
+ result = await executeMcpTool();
1166
1299
  }
1167
1300
  } else {
1168
1301
  const runInBackground = backgroundTasksEnabled && meta.runInBackground === true && sessionId !== void 0;
@@ -1175,13 +1308,12 @@ let _ToolManager = class _ToolManager {
1175
1308
  if (runInBackground) {
1176
1309
  const backgroundSessionId = sessionId;
1177
1310
  const { result: backgroundResult, promise } = registerBackgroundTask(
1178
- this.executeLocalTool(
1179
- toolName,
1180
- toolArgs,
1181
- backgroundSessionId,
1311
+ this.executeLocalTool(toolName, toolArgs, {
1312
+ sessionId: backgroundSessionId,
1182
1313
  abortSignal,
1183
- toolCallId
1184
- ),
1314
+ toolCallId,
1315
+ runContext
1316
+ }),
1185
1317
  `Tool ${toolName}`
1186
1318
  );
1187
1319
  this.agentEventBus.emit("tool:background", {
@@ -1190,6 +1322,7 @@ let _ToolManager = class _ToolManager {
1190
1322
  sessionId: backgroundSessionId,
1191
1323
  description: backgroundResult.description,
1192
1324
  promise,
1325
+ ...hostRuntime !== void 0 && { hostRuntime },
1193
1326
  ...meta.timeoutMs !== void 0 && { timeoutMs: meta.timeoutMs },
1194
1327
  ...meta.notifyOnComplete !== void 0 && {
1195
1328
  notifyOnComplete: meta.notifyOnComplete
@@ -1197,13 +1330,12 @@ let _ToolManager = class _ToolManager {
1197
1330
  });
1198
1331
  result = backgroundResult;
1199
1332
  } else {
1200
- result = await this.executeLocalTool(
1201
- toolName,
1202
- toolArgs,
1333
+ result = await this.executeLocalTool(toolName, toolArgs, {
1203
1334
  sessionId,
1204
1335
  abortSignal,
1205
- toolCallId
1206
- );
1336
+ toolCallId,
1337
+ runContext
1338
+ });
1207
1339
  }
1208
1340
  }
1209
1341
  const duration = Date.now() - startTime;
@@ -1226,6 +1358,7 @@ let _ToolManager = class _ToolManager {
1226
1358
  mcpManager: this.mcpManager,
1227
1359
  toolManager: this,
1228
1360
  stateManager: this.stateManager,
1361
+ ...runContext !== void 0 && { runContext },
1229
1362
  ...sessionId !== void 0 && { sessionId }
1230
1363
  }
1231
1364
  );
@@ -1237,7 +1370,8 @@ let _ToolManager = class _ToolManager {
1237
1370
  result,
1238
1371
  toolArgs,
1239
1372
  toolCallId,
1240
- sessionId
1373
+ sessionId,
1374
+ runContext
1241
1375
  );
1242
1376
  return {
1243
1377
  result,
@@ -1262,6 +1396,7 @@ let _ToolManager = class _ToolManager {
1262
1396
  mcpManager: this.mcpManager,
1263
1397
  toolManager: this,
1264
1398
  stateManager: this.stateManager,
1399
+ ...runContext !== void 0 && { runContext },
1265
1400
  ...sessionId !== void 0 && { sessionId }
1266
1401
  });
1267
1402
  }
@@ -1370,7 +1505,7 @@ let _ToolManager = class _ToolManager {
1370
1505
  * Handle tool approval flow. Checks various precedence levels to determine
1371
1506
  * if a tool should be auto-approved, denied, or requires manual approval.
1372
1507
  */
1373
- async handleToolApproval(toolName, args, toolCallId, sessionId, callDescription) {
1508
+ async handleToolApproval(toolName, args, toolCallId, sessionId, runContext, callDescription) {
1374
1509
  if (this.isInAlwaysDenyList(toolName)) {
1375
1510
  this.logger.info(
1376
1511
  `Tool '${toolName}' is in static deny list \u2013 blocking execution (session: ${sessionId ?? "global"})`
@@ -1382,14 +1517,19 @@ let _ToolManager = class _ToolManager {
1382
1517
  toolName,
1383
1518
  validatedArgs,
1384
1519
  toolCallId,
1385
- sessionId
1520
+ sessionId,
1521
+ runContext
1386
1522
  );
1387
1523
  let directoryAccess;
1388
1524
  let directoryAccessApprovalRequest;
1389
1525
  if (!toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
1390
1526
  const getApprovalOverride = this.getToolApprovalOverrideFn(toolName);
1391
1527
  if (getApprovalOverride) {
1392
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
1528
+ const context = this.buildToolExecutionContext({
1529
+ sessionId,
1530
+ toolCallId,
1531
+ runContext
1532
+ });
1393
1533
  const approvalRequest = await getApprovalOverride(validatedArgs, context);
1394
1534
  if (approvalRequest) {
1395
1535
  if (approvalRequest.type === import_types3.ApprovalType.DIRECTORY_ACCESS) {
@@ -1408,6 +1548,9 @@ let _ToolManager = class _ToolManager {
1408
1548
  if (sessionId && !approvalRequest.sessionId) {
1409
1549
  approvalRequest.sessionId = sessionId;
1410
1550
  }
1551
+ if (runContext?.hostRuntime !== void 0 && approvalRequest.hostRuntime === void 0) {
1552
+ approvalRequest.hostRuntime = runContext.hostRuntime;
1553
+ }
1411
1554
  const response = await this.approvalManager.requestApproval(approvalRequest);
1412
1555
  if (response.status === import_types3.ApprovalStatus.APPROVED) {
1413
1556
  const onGranted = this.getToolApprovalOnGrantedFn(toolName);
@@ -1448,6 +1591,7 @@ let _ToolManager = class _ToolManager {
1448
1591
  validatedArgs,
1449
1592
  toolCallId,
1450
1593
  sessionId,
1594
+ runContext,
1451
1595
  directoryAccess,
1452
1596
  directoryAccessApprovalRequest,
1453
1597
  callDescription,
@@ -1470,7 +1614,11 @@ let _ToolManager = class _ToolManager {
1470
1614
  async tryQuickApprovalResolution(toolName, args, sessionId, directoryAccess) {
1471
1615
  if (directoryAccess) {
1472
1616
  if (this.approvalMode === "auto-approve") {
1473
- this.approvalManager.addApprovedDirectory(directoryAccess.parentDir, "once");
1617
+ await this.approvalManager.addApprovedDirectory(
1618
+ directoryAccess.parentDir,
1619
+ "once",
1620
+ sessionId
1621
+ );
1474
1622
  return { requireApproval: false };
1475
1623
  }
1476
1624
  return null;
@@ -1494,7 +1642,7 @@ let _ToolManager = class _ToolManager {
1494
1642
  return { requireApproval: false };
1495
1643
  }
1496
1644
  const patternKey = this.getToolPatternKey(toolName, args);
1497
- if (patternKey && this.approvalManager.matchesPattern(toolName, patternKey)) {
1645
+ if (patternKey && this.approvalManager.matchesPattern(toolName, patternKey, sessionId)) {
1498
1646
  this.logger.info(
1499
1647
  `Tool '${toolName}' matched approved pattern key '${patternKey}' \u2013 skipping confirmation.`
1500
1648
  );
@@ -1514,7 +1662,7 @@ let _ToolManager = class _ToolManager {
1514
1662
  * Request manual approval from the user for a tool execution.
1515
1663
  * Generates preview, sends approval request, and handles the response.
1516
1664
  */
1517
- async requestManualApproval(toolName, args, toolCallId, sessionId, directoryAccess, directoryAccessApprovalRequest, callDescription, presentationSnapshot) {
1665
+ async requestManualApproval(toolName, args, toolCallId, sessionId, runContext, directoryAccess, directoryAccessApprovalRequest, callDescription, presentationSnapshot) {
1518
1666
  this.logger.info(
1519
1667
  `Tool approval requested for ${toolName}, sessionId: ${sessionId ?? "global"}`
1520
1668
  );
@@ -1523,8 +1671,10 @@ let _ToolManager = class _ToolManager {
1523
1671
  toolName,
1524
1672
  args,
1525
1673
  toolCallId,
1526
- sessionId
1674
+ sessionId,
1675
+ runContext
1527
1676
  );
1677
+ const hostRuntime = runContext?.hostRuntime ?? directoryAccessApprovalRequest?.hostRuntime;
1528
1678
  const suggestedPatterns = this.getToolSuggestedPatterns(toolName, args);
1529
1679
  const response = await this.approvalManager.requestToolApproval({
1530
1680
  toolName,
@@ -1533,6 +1683,7 @@ let _ToolManager = class _ToolManager {
1533
1683
  args,
1534
1684
  ...callDescription !== void 0 && { description: callDescription },
1535
1685
  ...sessionId !== void 0 && { sessionId },
1686
+ ...hostRuntime !== void 0 && { hostRuntime },
1536
1687
  ...displayPreview !== void 0 && { displayPreview },
1537
1688
  ...directoryAccess !== void 0 && { directoryAccess },
1538
1689
  ...suggestedPatterns !== void 0 && { suggestedPatterns }
@@ -1540,7 +1691,11 @@ let _ToolManager = class _ToolManager {
1540
1691
  if (response.status === import_types3.ApprovalStatus.APPROVED && directoryAccessApprovalRequest !== void 0) {
1541
1692
  const onGranted = this.getToolApprovalOnGrantedFn(toolName);
1542
1693
  if (onGranted) {
1543
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
1694
+ const context = this.buildToolExecutionContext({
1695
+ sessionId,
1696
+ toolCallId,
1697
+ runContext
1698
+ });
1544
1699
  await Promise.resolve(
1545
1700
  onGranted(response, context, directoryAccessApprovalRequest)
1546
1701
  );
@@ -1566,13 +1721,13 @@ let _ToolManager = class _ToolManager {
1566
1721
  /**
1567
1722
  * Generate a preview for the tool approval UI if the tool supports it.
1568
1723
  */
1569
- async generateToolPreview(toolName, args, toolCallId, sessionId) {
1724
+ async generateToolPreview(toolName, args, toolCallId, sessionId, runContext) {
1570
1725
  const previewFn = this.getToolPreviewFn(toolName);
1571
1726
  if (!previewFn) {
1572
1727
  return void 0;
1573
1728
  }
1574
1729
  try {
1575
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
1730
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
1576
1731
  const preview = await previewFn(args, context);
1577
1732
  this.logger.debug(`Generated preview for ${toolName}`);
1578
1733
  return preview ?? void 0;
@@ -1604,7 +1759,7 @@ let _ToolManager = class _ToolManager {
1604
1759
  );
1605
1760
  this.autoApprovePendingToolRequests(toolName, allowSessionId);
1606
1761
  } else if (rememberPattern && this.getToolApprovalPatternKeyFn(toolName)) {
1607
- this.approvalManager.addPattern(toolName, rememberPattern);
1762
+ await this.approvalManager.addPattern(toolName, rememberPattern, sessionId);
1608
1763
  this.logger.info(`Pattern '${rememberPattern}' added for tool '${toolName}' approval`);
1609
1764
  this.autoApprovePendingPatternRequests(toolName, sessionId);
1610
1765
  } else if (rememberDirectory) {