@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
@@ -21,6 +21,24 @@ _ToolManager_decorators = [InstrumentClass({
21
21
  excludeMethods: ["setHookSupport", "getApprovalManager", "getAllowedToolsProvider"]
22
22
  })];
23
23
  let _ToolManager = class _ToolManager {
24
+ constructor(mcpManager, approvalManager, allowedToolsProvider, approvalMode, agentEventBus, toolPolicies, tools, logger, sessionToolPreferencesStore) {
25
+ this.sessionToolPreferencesStore = sessionToolPreferencesStore;
26
+ this.mcpManager = mcpManager;
27
+ this.approvalManager = approvalManager;
28
+ this.allowedToolsProvider = allowedToolsProvider;
29
+ this.approvalMode = approvalMode;
30
+ this.agentEventBus = agentEventBus;
31
+ this.toolPolicies = toolPolicies;
32
+ this.logger = logger.createChild(DextoLogComponent.TOOLS);
33
+ this.setTools(tools);
34
+ this.toolExecutionContextFactory = () => {
35
+ throw ToolError.configInvalid(
36
+ "ToolExecutionContextFactory not configured. DextoAgent.start() must configure tool execution context before tools can run."
37
+ );
38
+ };
39
+ this.setupNotificationListeners();
40
+ this.logger.debug("ToolManager initialized");
41
+ }
24
42
  mcpManager;
25
43
  agentTools = /* @__PURE__ */ new Map();
26
44
  approvalManager;
@@ -53,6 +71,8 @@ let _ToolManager = class _ToolManager {
53
71
  // Session-level auto-approve tools set by users (UI)
54
72
  sessionUserAutoApproveTools = /* @__PURE__ */ new Map();
55
73
  sessionDisabledTools = /* @__PURE__ */ new Map();
74
+ restoredSessionPreferences = /* @__PURE__ */ new Set();
75
+ sessionPreferenceLocks = /* @__PURE__ */ new Map();
56
76
  globalDisabledTools = [];
57
77
  cleanupHandlers = /* @__PURE__ */ new Set();
58
78
  cleanupStarted = false;
@@ -76,22 +96,76 @@ let _ToolManager = class _ToolManager {
76
96
  }
77
97
  return this.resolveLocalToolIdOrAlias(pattern) ?? pattern;
78
98
  }
79
- constructor(mcpManager, approvalManager, allowedToolsProvider, approvalMode, agentEventBus, toolPolicies, tools, logger) {
80
- this.mcpManager = mcpManager;
81
- this.approvalManager = approvalManager;
82
- this.allowedToolsProvider = allowedToolsProvider;
83
- this.approvalMode = approvalMode;
84
- this.agentEventBus = agentEventBus;
85
- this.toolPolicies = toolPolicies;
86
- this.logger = logger.createChild(DextoLogComponent.TOOLS);
87
- this.setTools(tools);
88
- this.toolExecutionContextFactory = () => {
89
- throw ToolError.configInvalid(
90
- "ToolExecutionContextFactory not configured. DextoAgent.start() must configure tool execution context before tools can run."
91
- );
99
+ async runWithSessionPreferenceLock(sessionId, fn) {
100
+ const previousLock = this.sessionPreferenceLocks.get(sessionId) ?? Promise.resolve();
101
+ const currentResult = previousLock.catch(() => {
102
+ }).then(() => fn());
103
+ const currentLock = currentResult.then(
104
+ () => void 0,
105
+ () => void 0
106
+ );
107
+ this.sessionPreferenceLocks.set(sessionId, currentLock);
108
+ try {
109
+ return await currentResult;
110
+ } finally {
111
+ if (this.sessionPreferenceLocks.get(sessionId) === currentLock) {
112
+ this.sessionPreferenceLocks.delete(sessionId);
113
+ }
114
+ }
115
+ }
116
+ applySessionToolPreferences(sessionId, preferences) {
117
+ if (preferences.userAutoApproveTools.length > 0) {
118
+ this.sessionUserAutoApproveTools.set(sessionId, [...preferences.userAutoApproveTools]);
119
+ } else {
120
+ this.sessionUserAutoApproveTools.delete(sessionId);
121
+ }
122
+ if (preferences.disabledTools.length > 0) {
123
+ this.sessionDisabledTools.set(sessionId, [...preferences.disabledTools]);
124
+ } else {
125
+ this.sessionDisabledTools.delete(sessionId);
126
+ }
127
+ }
128
+ getSessionToolPreferencesSnapshot(sessionId) {
129
+ return {
130
+ userAutoApproveTools: [...this.sessionUserAutoApproveTools.get(sessionId) ?? []],
131
+ disabledTools: [...this.sessionDisabledTools.get(sessionId) ?? []]
92
132
  };
93
- this.setupNotificationListeners();
94
- this.logger.debug("ToolManager initialized");
133
+ }
134
+ async restoreSessionState(sessionId) {
135
+ if (this.restoredSessionPreferences.has(sessionId)) {
136
+ return;
137
+ }
138
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
139
+ if (this.restoredSessionPreferences.has(sessionId)) {
140
+ return;
141
+ }
142
+ const preferences = await this.sessionToolPreferencesStore.load(sessionId);
143
+ this.applySessionToolPreferences(sessionId, preferences);
144
+ this.restoredSessionPreferences.add(sessionId);
145
+ this.logger.debug("Restored persisted session tool preferences", {
146
+ sessionId,
147
+ autoApproveCount: preferences.userAutoApproveTools.length,
148
+ disabledCount: preferences.disabledTools.length
149
+ });
150
+ });
151
+ }
152
+ evictSessionState(sessionId) {
153
+ this.sessionAutoApproveTools.delete(sessionId);
154
+ this.sessionUserAutoApproveTools.delete(sessionId);
155
+ this.sessionDisabledTools.delete(sessionId);
156
+ this.restoredSessionPreferences.delete(sessionId);
157
+ }
158
+ async deleteSessionState(sessionId) {
159
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
160
+ this.evictSessionState(sessionId);
161
+ await this.sessionToolPreferencesStore.delete(sessionId);
162
+ });
163
+ }
164
+ async persistSessionToolPreferences(sessionId) {
165
+ await this.sessionToolPreferencesStore.save(
166
+ sessionId,
167
+ this.getSessionToolPreferencesSnapshot(sessionId)
168
+ );
95
169
  }
96
170
  /**
97
171
  * Initialize the ToolManager and its components
@@ -248,15 +322,19 @@ let _ToolManager = class _ToolManager {
248
322
  /**
249
323
  * Set session-level auto-approve tools chosen by the user.
250
324
  */
251
- setSessionUserAutoApproveTools(sessionId, autoApproveTools) {
325
+ async setSessionUserAutoApproveTools(sessionId, autoApproveTools) {
326
+ await this.restoreSessionState(sessionId);
252
327
  if (autoApproveTools.length === 0) {
253
- this.clearSessionUserAutoApproveTools(sessionId);
328
+ await this.clearSessionUserAutoApproveTools(sessionId);
254
329
  return;
255
330
  }
256
331
  const normalized = autoApproveTools.map(
257
332
  (pattern) => this.normalizeToolPolicyPattern(pattern)
258
333
  );
259
- this.sessionUserAutoApproveTools.set(sessionId, normalized);
334
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
335
+ this.sessionUserAutoApproveTools.set(sessionId, normalized);
336
+ await this.persistSessionToolPreferences(sessionId);
337
+ });
260
338
  this.logger.info(
261
339
  `Session user auto-approve tools set for '${sessionId}': ${autoApproveTools.length} tools`
262
340
  );
@@ -265,9 +343,14 @@ let _ToolManager = class _ToolManager {
265
343
  /**
266
344
  * Clear session-level auto-approve tools chosen by the user.
267
345
  */
268
- clearSessionUserAutoApproveTools(sessionId) {
269
- const hadAutoApprove = this.sessionUserAutoApproveTools.has(sessionId);
270
- this.sessionUserAutoApproveTools.delete(sessionId);
346
+ async clearSessionUserAutoApproveTools(sessionId) {
347
+ await this.restoreSessionState(sessionId);
348
+ let hadAutoApprove = false;
349
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
350
+ hadAutoApprove = this.sessionUserAutoApproveTools.has(sessionId);
351
+ this.sessionUserAutoApproveTools.delete(sessionId);
352
+ await this.persistSessionToolPreferences(sessionId);
353
+ });
271
354
  if (hadAutoApprove) {
272
355
  this.logger.info(`Session user auto-approve tools cleared for '${sessionId}'`);
273
356
  }
@@ -308,12 +391,16 @@ let _ToolManager = class _ToolManager {
308
391
  /**
309
392
  * Set session-level disabled tools (overrides global list).
310
393
  */
311
- setSessionDisabledTools(sessionId, toolNames) {
394
+ async setSessionDisabledTools(sessionId, toolNames) {
395
+ await this.restoreSessionState(sessionId);
312
396
  if (toolNames.length === 0) {
313
- this.clearSessionDisabledTools(sessionId);
397
+ await this.clearSessionDisabledTools(sessionId);
314
398
  return;
315
399
  }
316
- this.sessionDisabledTools.set(sessionId, [...toolNames]);
400
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
401
+ this.sessionDisabledTools.set(sessionId, [...toolNames]);
402
+ await this.persistSessionToolPreferences(sessionId);
403
+ });
317
404
  this.logger.info("Session disabled tools updated", {
318
405
  sessionId,
319
406
  count: toolNames.length
@@ -327,9 +414,14 @@ let _ToolManager = class _ToolManager {
327
414
  /**
328
415
  * Clear session-level disabled tools.
329
416
  */
330
- clearSessionDisabledTools(sessionId) {
331
- const hadOverrides = this.sessionDisabledTools.has(sessionId);
332
- this.sessionDisabledTools.delete(sessionId);
417
+ async clearSessionDisabledTools(sessionId) {
418
+ await this.restoreSessionState(sessionId);
419
+ let hadOverrides = false;
420
+ await this.runWithSessionPreferenceLock(sessionId, async () => {
421
+ hadOverrides = this.sessionDisabledTools.has(sessionId);
422
+ this.sessionDisabledTools.delete(sessionId);
423
+ await this.persistSessionToolPreferences(sessionId);
424
+ });
333
425
  if (hadOverrides) {
334
426
  this.logger.info("Session disabled tools cleared", { sessionId });
335
427
  }
@@ -525,7 +617,7 @@ let _ToolManager = class _ToolManager {
525
617
  }
526
618
  return snapshot;
527
619
  }
528
- getToolPresentationSnapshotForToolCallEvent(toolName, args, toolCallId, sessionId) {
620
+ getToolPresentationSnapshotForToolCallEvent(toolName, args, toolCallId, sessionId, runContext) {
529
621
  const fallback = this.buildGenericToolPresentationSnapshot(toolName);
530
622
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
531
623
  return fallback;
@@ -537,7 +629,7 @@ let _ToolManager = class _ToolManager {
537
629
  }
538
630
  try {
539
631
  const validatedArgs = this.validateLocalToolArgs(toolName, args);
540
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
632
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
541
633
  const isPromiseLike = (value) => {
542
634
  if (typeof value !== "object" || value === null) {
543
635
  return false;
@@ -571,7 +663,7 @@ let _ToolManager = class _ToolManager {
571
663
  return fallback;
572
664
  }
573
665
  }
574
- async getToolPresentationSnapshotForCall(toolName, args, toolCallId, sessionId) {
666
+ async getToolPresentationSnapshotForCall(toolName, args, toolCallId, sessionId, runContext) {
575
667
  const fallback = this.buildGenericToolPresentationSnapshot(toolName);
576
668
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
577
669
  return fallback;
@@ -582,7 +674,7 @@ let _ToolManager = class _ToolManager {
582
674
  return fallback;
583
675
  }
584
676
  try {
585
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
677
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
586
678
  const describedHeader = describeHeader ? await Promise.resolve(describeHeader(args, context)) : null;
587
679
  const describedArgs = describeArgs ? await Promise.resolve(describeArgs(args, context)) : null;
588
680
  return {
@@ -597,7 +689,7 @@ let _ToolManager = class _ToolManager {
597
689
  return fallback;
598
690
  }
599
691
  }
600
- async augmentSnapshotWithResult(toolName, snapshot, result, args, toolCallId, sessionId) {
692
+ async augmentSnapshotWithResult(toolName, snapshot, result, args, toolCallId, sessionId, runContext) {
601
693
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
602
694
  return snapshot;
603
695
  }
@@ -606,7 +698,7 @@ let _ToolManager = class _ToolManager {
606
698
  return snapshot;
607
699
  }
608
700
  try {
609
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
701
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
610
702
  const resultPresentation = await Promise.resolve(describeResult(result, args, context));
611
703
  if (!resultPresentation) {
612
704
  return snapshot;
@@ -729,7 +821,7 @@ let _ToolManager = class _ToolManager {
729
821
  return false;
730
822
  }
731
823
  if (!patternKey) return false;
732
- return this.approvalManager.matchesPattern(toolName, patternKey);
824
+ return this.approvalManager.matchesPattern(toolName, patternKey, sessionId);
733
825
  },
734
826
  { rememberPattern: void 0 }
735
827
  // Don't propagate pattern choice to auto-approved requests
@@ -760,7 +852,10 @@ let _ToolManager = class _ToolManager {
760
852
  if (!directoryAccess) {
761
853
  return false;
762
854
  }
763
- return this.approvalManager.isDirectorySessionApproved(directoryAccess.parentDir);
855
+ return this.approvalManager.isDirectorySessionApproved(
856
+ directoryAccess.parentDir,
857
+ sessionId
858
+ );
764
859
  },
765
860
  { rememberDirectory: false }
766
861
  );
@@ -837,14 +932,33 @@ let _ToolManager = class _ToolManager {
837
932
  const workspace = this.currentWorkspace;
838
933
  const baseContext = {
839
934
  sessionId: options.sessionId,
935
+ runContext: options.runContext,
840
936
  workspaceId: workspace?.id,
841
937
  workspace,
842
938
  abortSignal: options.abortSignal,
843
939
  toolCallId: options.toolCallId,
940
+ hostRuntime: options.runContext?.hostRuntime,
844
941
  logger: this.logger
845
942
  };
846
943
  return this.toolExecutionContextFactory(baseContext);
847
944
  }
945
+ resolveToolExecutionInvocation(invocationOrSessionId, legacyAbortSignal) {
946
+ if (typeof invocationOrSessionId === "string") {
947
+ return {
948
+ sessionId: invocationOrSessionId,
949
+ abortSignal: legacyAbortSignal,
950
+ hostRuntime: void 0
951
+ };
952
+ }
953
+ const invocation = invocationOrSessionId ?? {};
954
+ const sessionId = invocation.runContext?.sessionId ?? invocation.sessionId;
955
+ return {
956
+ ...invocation,
957
+ ...invocation.abortSignal === void 0 && legacyAbortSignal !== void 0 ? { abortSignal: legacyAbortSignal } : {},
958
+ sessionId,
959
+ hostRuntime: invocation.runContext?.hostRuntime
960
+ };
961
+ }
848
962
  validateLocalToolArgs(toolName, args) {
849
963
  if (toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
850
964
  return args;
@@ -869,7 +983,7 @@ let _ToolManager = class _ToolManager {
869
983
  }
870
984
  return validated;
871
985
  }
872
- async executeLocalTool(toolName, args, sessionId, abortSignal, toolCallId) {
986
+ async executeLocalTool(toolName, args, options) {
873
987
  const tool = this.agentTools.get(toolName);
874
988
  if (!tool) {
875
989
  this.logger.error(`\u274C No local tool found: ${toolName}`);
@@ -879,7 +993,12 @@ let _ToolManager = class _ToolManager {
879
993
  throw ToolError.notFound(toolName);
880
994
  }
881
995
  try {
882
- const context = this.buildToolExecutionContext({ sessionId, abortSignal, toolCallId });
996
+ const context = this.buildToolExecutionContext({
997
+ sessionId: options?.sessionId,
998
+ abortSignal: options?.abortSignal,
999
+ toolCallId: options?.toolCallId,
1000
+ runContext: options?.runContext
1001
+ });
883
1002
  const result = await tool.execute(args, context);
884
1003
  return result;
885
1004
  } catch (error) {
@@ -976,10 +1095,12 @@ let _ToolManager = class _ToolManager {
976
1095
  * @param toolName Tool name (e.g., "edit_file", "mcp--filesystem--read_file")
977
1096
  * @param args The arguments for the tool
978
1097
  * @param toolCallId The unique tool call ID for tracking (from LLM or generated for direct calls)
979
- * @param sessionId Optional session ID for context
980
- * @param abortSignal Optional abort signal for cancellation support
1098
+ * @param invocationOrSessionId Optional execution-scoped context for this tool call,
1099
+ * or the legacy positional sessionId
1100
+ * @param legacyAbortSignal Optional legacy positional abort signal
981
1101
  */
982
- async executeTool(toolName, args, toolCallId, sessionId, abortSignal) {
1102
+ async executeTool(toolName, args, toolCallId, invocationOrSessionId, legacyAbortSignal) {
1103
+ const { sessionId, abortSignal, runContext, hostRuntime } = this.resolveToolExecutionInvocation(invocationOrSessionId, legacyAbortSignal);
983
1104
  const { toolArgs: rawToolArgs, meta } = extractToolCallMeta(args);
984
1105
  const eventMeta = Object.keys(meta).length > 0 ? meta : void 0;
985
1106
  let toolArgs = rawToolArgs;
@@ -992,7 +1113,8 @@ let _ToolManager = class _ToolManager {
992
1113
  toolName,
993
1114
  toolArgs,
994
1115
  toolCallId,
995
- sessionId
1116
+ sessionId,
1117
+ runContext
996
1118
  );
997
1119
  this.agentEventBus.emit("llm:tool-call", {
998
1120
  toolName,
@@ -1001,7 +1123,8 @@ let _ToolManager = class _ToolManager {
1001
1123
  ...eventMeta !== void 0 ? { meta: eventMeta } : {},
1002
1124
  ...callDescription !== void 0 && { callDescription },
1003
1125
  callId: toolCallId,
1004
- sessionId
1126
+ sessionId,
1127
+ ...hostRuntime !== void 0 && { hostRuntime }
1005
1128
  });
1006
1129
  }
1007
1130
  const {
@@ -1014,6 +1137,7 @@ let _ToolManager = class _ToolManager {
1014
1137
  toolArgs,
1015
1138
  toolCallId,
1016
1139
  sessionId,
1140
+ runContext,
1017
1141
  callDescription
1018
1142
  );
1019
1143
  toolArgs = validatedToolArgs;
@@ -1025,7 +1149,8 @@ let _ToolManager = class _ToolManager {
1025
1149
  this.agentEventBus.emit("tool:running", {
1026
1150
  toolName,
1027
1151
  toolCallId,
1028
- sessionId
1152
+ sessionId,
1153
+ ...hostRuntime !== void 0 && { hostRuntime }
1029
1154
  });
1030
1155
  }
1031
1156
  const startTime = Date.now();
@@ -1043,6 +1168,7 @@ let _ToolManager = class _ToolManager {
1043
1168
  mcpManager: this.mcpManager,
1044
1169
  toolManager: this,
1045
1170
  stateManager: this.stateManager,
1171
+ ...runContext !== void 0 && { runContext },
1046
1172
  ...sessionId !== void 0 && { sessionId }
1047
1173
  }
1048
1174
  );
@@ -1077,6 +1203,12 @@ let _ToolManager = class _ToolManager {
1077
1203
  }
1078
1204
  this.logger.debug(`\u{1F3AF} MCP routing: '${toolName}' -> '${actualToolName}'`);
1079
1205
  const runInBackground = backgroundTasksEnabled && meta.runInBackground === true && sessionId !== void 0;
1206
+ const executeMcpTool = () => runContext === void 0 ? this.mcpManager.executeTool(actualToolName, toolArgs, sessionId) : this.mcpManager.executeTool(
1207
+ actualToolName,
1208
+ toolArgs,
1209
+ sessionId,
1210
+ runContext
1211
+ );
1080
1212
  if (meta.runInBackground === true && !backgroundTasksEnabled) {
1081
1213
  this.logger.debug(
1082
1214
  "Background tool execution disabled; running synchronously instead.",
@@ -1086,7 +1218,7 @@ let _ToolManager = class _ToolManager {
1086
1218
  if (runInBackground) {
1087
1219
  const backgroundSessionId = sessionId;
1088
1220
  const { result: backgroundResult, promise } = registerBackgroundTask(
1089
- this.mcpManager.executeTool(actualToolName, toolArgs, backgroundSessionId),
1221
+ executeMcpTool(),
1090
1222
  `MCP tool ${actualToolName}`
1091
1223
  );
1092
1224
  this.agentEventBus.emit("tool:background", {
@@ -1095,6 +1227,7 @@ let _ToolManager = class _ToolManager {
1095
1227
  sessionId: backgroundSessionId,
1096
1228
  description: backgroundResult.description,
1097
1229
  promise,
1230
+ ...hostRuntime !== void 0 && { hostRuntime },
1098
1231
  ...meta.timeoutMs !== void 0 && { timeoutMs: meta.timeoutMs },
1099
1232
  ...meta.notifyOnComplete !== void 0 && {
1100
1233
  notifyOnComplete: meta.notifyOnComplete
@@ -1102,7 +1235,7 @@ let _ToolManager = class _ToolManager {
1102
1235
  });
1103
1236
  result = backgroundResult;
1104
1237
  } else {
1105
- result = await this.mcpManager.executeTool(actualToolName, toolArgs, sessionId);
1238
+ result = await executeMcpTool();
1106
1239
  }
1107
1240
  } else {
1108
1241
  const runInBackground = backgroundTasksEnabled && meta.runInBackground === true && sessionId !== void 0;
@@ -1115,13 +1248,12 @@ let _ToolManager = class _ToolManager {
1115
1248
  if (runInBackground) {
1116
1249
  const backgroundSessionId = sessionId;
1117
1250
  const { result: backgroundResult, promise } = registerBackgroundTask(
1118
- this.executeLocalTool(
1119
- toolName,
1120
- toolArgs,
1121
- backgroundSessionId,
1251
+ this.executeLocalTool(toolName, toolArgs, {
1252
+ sessionId: backgroundSessionId,
1122
1253
  abortSignal,
1123
- toolCallId
1124
- ),
1254
+ toolCallId,
1255
+ runContext
1256
+ }),
1125
1257
  `Tool ${toolName}`
1126
1258
  );
1127
1259
  this.agentEventBus.emit("tool:background", {
@@ -1130,6 +1262,7 @@ let _ToolManager = class _ToolManager {
1130
1262
  sessionId: backgroundSessionId,
1131
1263
  description: backgroundResult.description,
1132
1264
  promise,
1265
+ ...hostRuntime !== void 0 && { hostRuntime },
1133
1266
  ...meta.timeoutMs !== void 0 && { timeoutMs: meta.timeoutMs },
1134
1267
  ...meta.notifyOnComplete !== void 0 && {
1135
1268
  notifyOnComplete: meta.notifyOnComplete
@@ -1137,13 +1270,12 @@ let _ToolManager = class _ToolManager {
1137
1270
  });
1138
1271
  result = backgroundResult;
1139
1272
  } else {
1140
- result = await this.executeLocalTool(
1141
- toolName,
1142
- toolArgs,
1273
+ result = await this.executeLocalTool(toolName, toolArgs, {
1143
1274
  sessionId,
1144
1275
  abortSignal,
1145
- toolCallId
1146
- );
1276
+ toolCallId,
1277
+ runContext
1278
+ });
1147
1279
  }
1148
1280
  }
1149
1281
  const duration = Date.now() - startTime;
@@ -1166,6 +1298,7 @@ let _ToolManager = class _ToolManager {
1166
1298
  mcpManager: this.mcpManager,
1167
1299
  toolManager: this,
1168
1300
  stateManager: this.stateManager,
1301
+ ...runContext !== void 0 && { runContext },
1169
1302
  ...sessionId !== void 0 && { sessionId }
1170
1303
  }
1171
1304
  );
@@ -1177,7 +1310,8 @@ let _ToolManager = class _ToolManager {
1177
1310
  result,
1178
1311
  toolArgs,
1179
1312
  toolCallId,
1180
- sessionId
1313
+ sessionId,
1314
+ runContext
1181
1315
  );
1182
1316
  return {
1183
1317
  result,
@@ -1202,6 +1336,7 @@ let _ToolManager = class _ToolManager {
1202
1336
  mcpManager: this.mcpManager,
1203
1337
  toolManager: this,
1204
1338
  stateManager: this.stateManager,
1339
+ ...runContext !== void 0 && { runContext },
1205
1340
  ...sessionId !== void 0 && { sessionId }
1206
1341
  });
1207
1342
  }
@@ -1310,7 +1445,7 @@ let _ToolManager = class _ToolManager {
1310
1445
  * Handle tool approval flow. Checks various precedence levels to determine
1311
1446
  * if a tool should be auto-approved, denied, or requires manual approval.
1312
1447
  */
1313
- async handleToolApproval(toolName, args, toolCallId, sessionId, callDescription) {
1448
+ async handleToolApproval(toolName, args, toolCallId, sessionId, runContext, callDescription) {
1314
1449
  if (this.isInAlwaysDenyList(toolName)) {
1315
1450
  this.logger.info(
1316
1451
  `Tool '${toolName}' is in static deny list \u2013 blocking execution (session: ${sessionId ?? "global"})`
@@ -1322,14 +1457,19 @@ let _ToolManager = class _ToolManager {
1322
1457
  toolName,
1323
1458
  validatedArgs,
1324
1459
  toolCallId,
1325
- sessionId
1460
+ sessionId,
1461
+ runContext
1326
1462
  );
1327
1463
  let directoryAccess;
1328
1464
  let directoryAccessApprovalRequest;
1329
1465
  if (!toolName.startsWith(_ToolManager.MCP_TOOL_PREFIX)) {
1330
1466
  const getApprovalOverride = this.getToolApprovalOverrideFn(toolName);
1331
1467
  if (getApprovalOverride) {
1332
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
1468
+ const context = this.buildToolExecutionContext({
1469
+ sessionId,
1470
+ toolCallId,
1471
+ runContext
1472
+ });
1333
1473
  const approvalRequest = await getApprovalOverride(validatedArgs, context);
1334
1474
  if (approvalRequest) {
1335
1475
  if (approvalRequest.type === ApprovalType.DIRECTORY_ACCESS) {
@@ -1348,6 +1488,9 @@ let _ToolManager = class _ToolManager {
1348
1488
  if (sessionId && !approvalRequest.sessionId) {
1349
1489
  approvalRequest.sessionId = sessionId;
1350
1490
  }
1491
+ if (runContext?.hostRuntime !== void 0 && approvalRequest.hostRuntime === void 0) {
1492
+ approvalRequest.hostRuntime = runContext.hostRuntime;
1493
+ }
1351
1494
  const response = await this.approvalManager.requestApproval(approvalRequest);
1352
1495
  if (response.status === ApprovalStatus.APPROVED) {
1353
1496
  const onGranted = this.getToolApprovalOnGrantedFn(toolName);
@@ -1388,6 +1531,7 @@ let _ToolManager = class _ToolManager {
1388
1531
  validatedArgs,
1389
1532
  toolCallId,
1390
1533
  sessionId,
1534
+ runContext,
1391
1535
  directoryAccess,
1392
1536
  directoryAccessApprovalRequest,
1393
1537
  callDescription,
@@ -1410,7 +1554,11 @@ let _ToolManager = class _ToolManager {
1410
1554
  async tryQuickApprovalResolution(toolName, args, sessionId, directoryAccess) {
1411
1555
  if (directoryAccess) {
1412
1556
  if (this.approvalMode === "auto-approve") {
1413
- this.approvalManager.addApprovedDirectory(directoryAccess.parentDir, "once");
1557
+ await this.approvalManager.addApprovedDirectory(
1558
+ directoryAccess.parentDir,
1559
+ "once",
1560
+ sessionId
1561
+ );
1414
1562
  return { requireApproval: false };
1415
1563
  }
1416
1564
  return null;
@@ -1434,7 +1582,7 @@ let _ToolManager = class _ToolManager {
1434
1582
  return { requireApproval: false };
1435
1583
  }
1436
1584
  const patternKey = this.getToolPatternKey(toolName, args);
1437
- if (patternKey && this.approvalManager.matchesPattern(toolName, patternKey)) {
1585
+ if (patternKey && this.approvalManager.matchesPattern(toolName, patternKey, sessionId)) {
1438
1586
  this.logger.info(
1439
1587
  `Tool '${toolName}' matched approved pattern key '${patternKey}' \u2013 skipping confirmation.`
1440
1588
  );
@@ -1454,7 +1602,7 @@ let _ToolManager = class _ToolManager {
1454
1602
  * Request manual approval from the user for a tool execution.
1455
1603
  * Generates preview, sends approval request, and handles the response.
1456
1604
  */
1457
- async requestManualApproval(toolName, args, toolCallId, sessionId, directoryAccess, directoryAccessApprovalRequest, callDescription, presentationSnapshot) {
1605
+ async requestManualApproval(toolName, args, toolCallId, sessionId, runContext, directoryAccess, directoryAccessApprovalRequest, callDescription, presentationSnapshot) {
1458
1606
  this.logger.info(
1459
1607
  `Tool approval requested for ${toolName}, sessionId: ${sessionId ?? "global"}`
1460
1608
  );
@@ -1463,8 +1611,10 @@ let _ToolManager = class _ToolManager {
1463
1611
  toolName,
1464
1612
  args,
1465
1613
  toolCallId,
1466
- sessionId
1614
+ sessionId,
1615
+ runContext
1467
1616
  );
1617
+ const hostRuntime = runContext?.hostRuntime ?? directoryAccessApprovalRequest?.hostRuntime;
1468
1618
  const suggestedPatterns = this.getToolSuggestedPatterns(toolName, args);
1469
1619
  const response = await this.approvalManager.requestToolApproval({
1470
1620
  toolName,
@@ -1473,6 +1623,7 @@ let _ToolManager = class _ToolManager {
1473
1623
  args,
1474
1624
  ...callDescription !== void 0 && { description: callDescription },
1475
1625
  ...sessionId !== void 0 && { sessionId },
1626
+ ...hostRuntime !== void 0 && { hostRuntime },
1476
1627
  ...displayPreview !== void 0 && { displayPreview },
1477
1628
  ...directoryAccess !== void 0 && { directoryAccess },
1478
1629
  ...suggestedPatterns !== void 0 && { suggestedPatterns }
@@ -1480,7 +1631,11 @@ let _ToolManager = class _ToolManager {
1480
1631
  if (response.status === ApprovalStatus.APPROVED && directoryAccessApprovalRequest !== void 0) {
1481
1632
  const onGranted = this.getToolApprovalOnGrantedFn(toolName);
1482
1633
  if (onGranted) {
1483
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
1634
+ const context = this.buildToolExecutionContext({
1635
+ sessionId,
1636
+ toolCallId,
1637
+ runContext
1638
+ });
1484
1639
  await Promise.resolve(
1485
1640
  onGranted(response, context, directoryAccessApprovalRequest)
1486
1641
  );
@@ -1506,13 +1661,13 @@ let _ToolManager = class _ToolManager {
1506
1661
  /**
1507
1662
  * Generate a preview for the tool approval UI if the tool supports it.
1508
1663
  */
1509
- async generateToolPreview(toolName, args, toolCallId, sessionId) {
1664
+ async generateToolPreview(toolName, args, toolCallId, sessionId, runContext) {
1510
1665
  const previewFn = this.getToolPreviewFn(toolName);
1511
1666
  if (!previewFn) {
1512
1667
  return void 0;
1513
1668
  }
1514
1669
  try {
1515
- const context = this.buildToolExecutionContext({ sessionId, toolCallId });
1670
+ const context = this.buildToolExecutionContext({ sessionId, toolCallId, runContext });
1516
1671
  const preview = await previewFn(args, context);
1517
1672
  this.logger.debug(`Generated preview for ${toolName}`);
1518
1673
  return preview ?? void 0;
@@ -1544,7 +1699,7 @@ let _ToolManager = class _ToolManager {
1544
1699
  );
1545
1700
  this.autoApprovePendingToolRequests(toolName, allowSessionId);
1546
1701
  } else if (rememberPattern && this.getToolApprovalPatternKeyFn(toolName)) {
1547
- this.approvalManager.addPattern(toolName, rememberPattern);
1702
+ await this.approvalManager.addPattern(toolName, rememberPattern, sessionId);
1548
1703
  this.logger.info(`Pattern '${rememberPattern}' added for tool '${toolName}' approval`);
1549
1704
  this.autoApprovePendingPatternRequests(toolName, sessionId);
1550
1705
  } else if (rememberDirectory) {
@@ -13,6 +13,8 @@ import type { PromptManager } from '../prompts/prompt-manager.js';
13
13
  import type { ResourceManager } from '../resources/manager.js';
14
14
  import type { SearchService } from '../search/search-service.js';
15
15
  import type { Logger } from '../logger/v2/types.js';
16
+ import type { HostRuntimeContext } from '../runtime/index.js';
17
+ import type { AgentRunContext } from '../runtime/run-context.js';
16
18
  /**
17
19
  * Interface for forking execution to an isolated sub-agent context.
18
20
  *
@@ -48,6 +50,8 @@ export interface ToolServices {
48
50
  export interface ToolExecutionContextBase {
49
51
  /** Session ID if available */
50
52
  sessionId?: string | undefined;
53
+ /** Internal run-scoped execution context for this tool invocation */
54
+ runContext?: AgentRunContext | undefined;
51
55
  /** Workspace ID if available */
52
56
  workspaceId?: string | undefined;
53
57
  /** Workspace context if available */
@@ -56,6 +60,8 @@ export interface ToolExecutionContextBase {
56
60
  abortSignal?: AbortSignal | undefined;
57
61
  /** Unique tool call ID for tracking parallel tool calls */
58
62
  toolCallId?: string | undefined;
63
+ /** Host-owned runtime IDs for orchestration and correlation */
64
+ hostRuntime?: HostRuntimeContext | undefined;
59
65
  /**
60
66
  * Logger scoped to the tool execution.
61
67
  */
@@ -294,6 +300,6 @@ export interface ToolResult {
294
300
  */
295
301
  export interface ToolProvider {
296
302
  getTools(): Promise<ToolSet>;
297
- callTool(toolName: string, args: Record<string, unknown>): Promise<unknown>;
303
+ callTool(toolName: string, args: Record<string, unknown>, context?: Pick<ToolExecutionContextBase, 'sessionId' | 'runContext'>): Promise<unknown>;
298
304
  }
299
305
  //# sourceMappingURL=types.d.ts.map