@dexto/core 1.5.5 → 1.5.7

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 (146) hide show
  1. package/dist/agent/DextoAgent.cjs +94 -26
  2. package/dist/agent/DextoAgent.d.ts +17 -7
  3. package/dist/agent/DextoAgent.d.ts.map +1 -1
  4. package/dist/agent/DextoAgent.js +95 -27
  5. package/dist/agent/schemas.d.ts +417 -66
  6. package/dist/agent/schemas.d.ts.map +1 -1
  7. package/dist/context/utils.cjs +49 -3
  8. package/dist/context/utils.d.ts.map +1 -1
  9. package/dist/context/utils.js +49 -3
  10. package/dist/errors/types.cjs +2 -1
  11. package/dist/errors/types.d.ts +2 -1
  12. package/dist/errors/types.d.ts.map +1 -1
  13. package/dist/errors/types.js +2 -1
  14. package/dist/image/types.d.ts +15 -0
  15. package/dist/image/types.d.ts.map +1 -1
  16. package/dist/llm/error-codes.cjs +1 -0
  17. package/dist/llm/error-codes.d.ts +1 -0
  18. package/dist/llm/error-codes.d.ts.map +1 -1
  19. package/dist/llm/error-codes.js +1 -0
  20. package/dist/llm/errors.cjs +15 -0
  21. package/dist/llm/errors.d.ts +15 -8
  22. package/dist/llm/errors.d.ts.map +1 -1
  23. package/dist/llm/errors.js +15 -0
  24. package/dist/llm/executor/turn-executor.cjs +27 -0
  25. package/dist/llm/executor/turn-executor.d.ts.map +1 -1
  26. package/dist/llm/executor/turn-executor.js +27 -0
  27. package/dist/llm/registry.cjs +472 -28
  28. package/dist/llm/registry.d.ts +80 -4
  29. package/dist/llm/registry.d.ts.map +1 -1
  30. package/dist/llm/registry.js +464 -25
  31. package/dist/llm/resolver.cjs +13 -0
  32. package/dist/llm/resolver.d.ts.map +1 -1
  33. package/dist/llm/resolver.js +16 -1
  34. package/dist/llm/schemas.d.ts +59 -59
  35. package/dist/llm/services/factory.cjs +41 -25
  36. package/dist/llm/services/factory.d.ts +20 -1
  37. package/dist/llm/services/factory.d.ts.map +1 -1
  38. package/dist/llm/services/factory.js +42 -26
  39. package/dist/llm/services/test-utils.integration.cjs +5 -1
  40. package/dist/llm/services/test-utils.integration.d.ts.map +1 -1
  41. package/dist/llm/services/test-utils.integration.js +5 -1
  42. package/dist/llm/types.cjs +5 -2
  43. package/dist/llm/types.d.ts +1 -1
  44. package/dist/llm/types.d.ts.map +1 -1
  45. package/dist/llm/types.js +5 -2
  46. package/dist/logger/logger.cjs +6 -7
  47. package/dist/logger/logger.d.ts +1 -0
  48. package/dist/logger/logger.d.ts.map +1 -1
  49. package/dist/logger/logger.js +6 -7
  50. package/dist/logger/v2/dexto-logger.cjs +4 -0
  51. package/dist/logger/v2/dexto-logger.d.ts +3 -0
  52. package/dist/logger/v2/dexto-logger.d.ts.map +1 -1
  53. package/dist/logger/v2/dexto-logger.js +4 -0
  54. package/dist/logger/v2/types.d.ts +2 -0
  55. package/dist/logger/v2/types.d.ts.map +1 -1
  56. package/dist/mcp/error-codes.cjs +1 -0
  57. package/dist/mcp/error-codes.d.ts +1 -0
  58. package/dist/mcp/error-codes.d.ts.map +1 -1
  59. package/dist/mcp/error-codes.js +1 -0
  60. package/dist/mcp/errors.cjs +13 -0
  61. package/dist/mcp/errors.d.ts +7 -0
  62. package/dist/mcp/errors.d.ts.map +1 -1
  63. package/dist/mcp/errors.js +13 -0
  64. package/dist/mcp/manager.cjs +46 -4
  65. package/dist/mcp/manager.d.ts +10 -2
  66. package/dist/mcp/manager.d.ts.map +1 -1
  67. package/dist/mcp/manager.js +46 -4
  68. package/dist/mcp/mcp-client.cjs +89 -5
  69. package/dist/mcp/mcp-client.d.ts +5 -1
  70. package/dist/mcp/mcp-client.d.ts.map +1 -1
  71. package/dist/mcp/mcp-client.js +89 -5
  72. package/dist/mcp/schemas.cjs +6 -1
  73. package/dist/mcp/schemas.d.ts +1 -1
  74. package/dist/mcp/schemas.d.ts.map +1 -1
  75. package/dist/mcp/schemas.js +6 -1
  76. package/dist/mcp/types.d.ts +5 -0
  77. package/dist/mcp/types.d.ts.map +1 -1
  78. package/dist/prompts/index.d.ts +1 -1
  79. package/dist/prompts/index.d.ts.map +1 -1
  80. package/dist/prompts/prompt-manager.cjs +90 -4
  81. package/dist/prompts/prompt-manager.d.ts +16 -6
  82. package/dist/prompts/prompt-manager.d.ts.map +1 -1
  83. package/dist/prompts/prompt-manager.js +90 -4
  84. package/dist/prompts/providers/config-prompt-provider.cjs +104 -10
  85. package/dist/prompts/providers/config-prompt-provider.d.ts.map +1 -1
  86. package/dist/prompts/providers/config-prompt-provider.js +105 -11
  87. package/dist/prompts/providers/custom-prompt-provider.cjs +1 -0
  88. package/dist/prompts/providers/custom-prompt-provider.d.ts.map +1 -1
  89. package/dist/prompts/providers/custom-prompt-provider.js +1 -0
  90. package/dist/prompts/providers/mcp-prompt-provider.cjs +1 -0
  91. package/dist/prompts/providers/mcp-prompt-provider.d.ts.map +1 -1
  92. package/dist/prompts/providers/mcp-prompt-provider.js +1 -0
  93. package/dist/prompts/schemas.cjs +28 -2
  94. package/dist/prompts/schemas.d.ts +130 -0
  95. package/dist/prompts/schemas.d.ts.map +1 -1
  96. package/dist/prompts/schemas.js +28 -2
  97. package/dist/prompts/types.d.ts +55 -3
  98. package/dist/prompts/types.d.ts.map +1 -1
  99. package/dist/session/chat-session.d.ts +1 -1
  100. package/dist/session/chat-session.d.ts.map +1 -1
  101. package/dist/session/index.d.ts +1 -1
  102. package/dist/session/index.d.ts.map +1 -1
  103. package/dist/session/session-manager.cjs +47 -3
  104. package/dist/session/session-manager.d.ts +10 -0
  105. package/dist/session/session-manager.d.ts.map +1 -1
  106. package/dist/session/session-manager.js +47 -3
  107. package/dist/systemPrompt/contributors.cjs +42 -0
  108. package/dist/systemPrompt/contributors.d.ts +13 -0
  109. package/dist/systemPrompt/contributors.d.ts.map +1 -1
  110. package/dist/systemPrompt/contributors.js +41 -0
  111. package/dist/tools/errors.cjs +7 -3
  112. package/dist/tools/errors.d.ts +5 -1
  113. package/dist/tools/errors.d.ts.map +1 -1
  114. package/dist/tools/errors.js +7 -3
  115. package/dist/tools/internal-tools/constants.cjs +2 -1
  116. package/dist/tools/internal-tools/constants.d.ts +1 -1
  117. package/dist/tools/internal-tools/constants.d.ts.map +1 -1
  118. package/dist/tools/internal-tools/constants.js +2 -1
  119. package/dist/tools/internal-tools/implementations/invoke-skill-tool.cjs +140 -0
  120. package/dist/tools/internal-tools/implementations/invoke-skill-tool.d.ts +24 -0
  121. package/dist/tools/internal-tools/implementations/invoke-skill-tool.d.ts.map +1 -0
  122. package/dist/tools/internal-tools/implementations/invoke-skill-tool.js +117 -0
  123. package/dist/tools/internal-tools/provider.cjs +15 -0
  124. package/dist/tools/internal-tools/provider.d.ts +12 -0
  125. package/dist/tools/internal-tools/provider.d.ts.map +1 -1
  126. package/dist/tools/internal-tools/provider.js +15 -0
  127. package/dist/tools/internal-tools/registry.cjs +6 -0
  128. package/dist/tools/internal-tools/registry.d.ts +34 -0
  129. package/dist/tools/internal-tools/registry.d.ts.map +1 -1
  130. package/dist/tools/internal-tools/registry.js +6 -0
  131. package/dist/tools/schemas.cjs +2 -2
  132. package/dist/tools/schemas.d.ts +1 -1
  133. package/dist/tools/schemas.d.ts.map +1 -1
  134. package/dist/tools/schemas.js +2 -2
  135. package/dist/tools/tool-manager.cjs +230 -79
  136. package/dist/tools/tool-manager.d.ts +89 -8
  137. package/dist/tools/tool-manager.d.ts.map +1 -1
  138. package/dist/tools/tool-manager.js +231 -80
  139. package/dist/utils/api-key-resolver.cjs +5 -2
  140. package/dist/utils/api-key-resolver.d.ts.map +1 -1
  141. package/dist/utils/api-key-resolver.js +5 -2
  142. package/dist/utils/service-initializer.cjs +8 -2
  143. package/dist/utils/service-initializer.d.ts +5 -1
  144. package/dist/utils/service-initializer.d.ts.map +1 -1
  145. package/dist/utils/service-initializer.js +8 -2
  146. package/package.json +1 -1
@@ -9,7 +9,7 @@ import { ToolError } from "./errors.js";
9
9
  import { ToolErrorCode } from "./error-codes.js";
10
10
  import { DextoRuntimeError } from "../errors/index.js";
11
11
  import { DextoLogComponent } from "../logger/v2/types.js";
12
- import { ApprovalStatus, ApprovalType } from "../approval/types.js";
12
+ import { ApprovalStatus, ApprovalType, DenialReason } from "../approval/types.js";
13
13
  import { InstrumentClass } from "../telemetry/decorators.js";
14
14
  import {
15
15
  generateBashPatternKey,
@@ -45,6 +45,10 @@ let _ToolManager = class _ToolManager {
45
45
  toolsCache = {};
46
46
  cacheValid = false;
47
47
  logger;
48
+ // Session-level auto-approve tools for skills
49
+ // When a skill with allowedTools is invoked, those tools are auto-approved (skip confirmation)
50
+ // This is ADDITIVE - other tools are NOT blocked, they just go through normal approval flow
51
+ sessionAutoApproveTools = /* @__PURE__ */ new Map();
48
52
  constructor(mcpManager, approvalManager, allowedToolsProvider, approvalMode, agentEventBus, toolPolicies, options, logger) {
49
53
  this.mcpManager = mcpManager;
50
54
  this.approvalManager = approvalManager;
@@ -96,6 +100,95 @@ let _ToolManager = class _ToolManager {
96
100
  this.logger.debug("Agent reference configured for custom tools");
97
101
  }
98
102
  }
103
+ /**
104
+ * Set prompt manager for invoke_skill tool (called after construction to avoid circular dependencies)
105
+ * Must be called before initialize() if invoke_skill tool is enabled
106
+ */
107
+ setPromptManager(promptManager) {
108
+ if (this.internalToolsProvider) {
109
+ this.internalToolsProvider.setPromptManager(promptManager);
110
+ this.logger.debug("PromptManager reference configured for invoke_skill tool");
111
+ }
112
+ }
113
+ /**
114
+ * Set task forker for context:fork skill execution (late-binding)
115
+ * Called by agent-spawner custom tool provider after RuntimeService is created.
116
+ * This enables invoke_skill to fork execution to an isolated subagent.
117
+ */
118
+ setTaskForker(taskForker) {
119
+ if (this.internalToolsProvider) {
120
+ this.internalToolsProvider.setTaskForker(taskForker);
121
+ this.logger.debug(
122
+ "TaskForker reference configured for invoke_skill (context:fork support)"
123
+ );
124
+ }
125
+ }
126
+ // ============= SESSION AUTO-APPROVE TOOLS =============
127
+ /**
128
+ * Set session-level auto-approve tools.
129
+ * When set, these tools will skip confirmation prompts for this session.
130
+ * This is ADDITIVE - other tools are NOT blocked, they just go through normal approval flow.
131
+ *
132
+ * @param sessionId The session ID
133
+ * @param autoApproveTools Array of tool names to auto-approve (e.g., ['custom--bash_exec', 'custom--read_file'])
134
+ */
135
+ setSessionAutoApproveTools(sessionId, autoApproveTools) {
136
+ if (autoApproveTools.length === 0) {
137
+ this.clearSessionAutoApproveTools(sessionId);
138
+ return;
139
+ }
140
+ this.sessionAutoApproveTools.set(sessionId, autoApproveTools);
141
+ this.logger.info(
142
+ `Session auto-approve tools set for '${sessionId}': ${autoApproveTools.length} tools`
143
+ );
144
+ this.logger.debug(`Auto-approve tools: ${autoApproveTools.join(", ")}`);
145
+ }
146
+ /**
147
+ * Clear session-level auto-approve tools.
148
+ * Call this when the session ends or when the skill completes.
149
+ *
150
+ * @param sessionId The session ID to clear auto-approve tools for
151
+ */
152
+ clearSessionAutoApproveTools(sessionId) {
153
+ const hadAutoApprove = this.sessionAutoApproveTools.has(sessionId);
154
+ this.sessionAutoApproveTools.delete(sessionId);
155
+ if (hadAutoApprove) {
156
+ this.logger.info(`Session auto-approve tools cleared for '${sessionId}'`);
157
+ }
158
+ }
159
+ /**
160
+ * Check if a session has auto-approve tools set.
161
+ *
162
+ * @param sessionId The session ID to check
163
+ * @returns true if the session has auto-approve tools
164
+ */
165
+ hasSessionAutoApproveTools(sessionId) {
166
+ return this.sessionAutoApproveTools.has(sessionId);
167
+ }
168
+ /**
169
+ * Get the auto-approve tools for a session.
170
+ *
171
+ * @param sessionId The session ID to check
172
+ * @returns Array of auto-approve tool names, or undefined if none set
173
+ */
174
+ getSessionAutoApproveTools(sessionId) {
175
+ return this.sessionAutoApproveTools.get(sessionId);
176
+ }
177
+ /**
178
+ * Check if a tool should be auto-approved for a session.
179
+ * Returns true if the tool is in the session's auto-approve list.
180
+ *
181
+ * @param sessionId The session ID
182
+ * @param toolName The tool name to check
183
+ * @returns true if the tool should be auto-approved
184
+ */
185
+ isToolAutoApprovedForSession(sessionId, toolName) {
186
+ const autoApproveTools = this.sessionAutoApproveTools.get(sessionId);
187
+ if (!autoApproveTools) {
188
+ return false;
189
+ }
190
+ return autoApproveTools.some((pattern) => this.matchesToolPolicy(toolName, pattern));
191
+ }
99
192
  /**
100
193
  * Invalidate the tools cache when tool sources change
101
194
  */
@@ -121,6 +214,14 @@ let _ToolManager = class _ToolManager {
121
214
  );
122
215
  this.invalidateCache();
123
216
  });
217
+ this.agentEventBus.on("run:complete", (payload) => {
218
+ if (this.hasSessionAutoApproveTools(payload.sessionId)) {
219
+ this.logger.debug(
220
+ `\u{1F513} Run complete, clearing session auto-approve tools for '${payload.sessionId}'`
221
+ );
222
+ this.clearSessionAutoApproveTools(payload.sessionId);
223
+ }
224
+ });
124
225
  }
125
226
  // ==================== Bash Pattern Approval Helpers ====================
126
227
  /**
@@ -672,21 +773,34 @@ let _ToolManager = class _ToolManager {
672
773
  throw ToolError.executionDenied(toolName, sessionId);
673
774
  }
674
775
  /**
675
- * Handle tool approval/confirmation flow
676
- * Checks allowed list, manages approval modes (manual, auto-approve, auto-deny),
677
- * and handles remember choice logic
678
- *
679
- * @param toolName The fully qualified tool name
680
- * @param args The arguments for the tool
681
- * @param toolCallId The unique tool call ID for tracking parallel tool calls
682
- * @param sessionId Optional session ID for context
776
+ * Handle tool approval flow. Checks various precedence levels to determine
777
+ * if a tool should be auto-approved, denied, or requires manual approval.
683
778
  */
684
779
  async handleToolApproval(toolName, args, toolCallId, sessionId) {
780
+ const quickResult = await this.tryQuickApprovalResolution(toolName, args, sessionId);
781
+ if (quickResult !== null) {
782
+ return quickResult;
783
+ }
784
+ return this.requestManualApproval(toolName, args, toolCallId, sessionId);
785
+ }
786
+ /**
787
+ * Try to resolve tool approval quickly based on policies and cached permissions.
788
+ * Returns null if manual approval is needed.
789
+ *
790
+ * Precedence order (highest to lowest):
791
+ * 1. Static deny list (security - always blocks)
792
+ * 2. Custom approval override (tool-specific approval flows)
793
+ * 3. Session auto-approve (skill allowed-tools)
794
+ * 4. Static allow list
795
+ * 5. Dynamic "remembered" allowed list
796
+ * 6. Bash command patterns
797
+ * 7. Approval mode (auto-approve/auto-deny)
798
+ */
799
+ async tryQuickApprovalResolution(toolName, args, sessionId) {
685
800
  if (this.isInAlwaysDenyList(toolName)) {
686
801
  this.logger.info(
687
802
  `Tool '${toolName}' is in static deny list \u2013 blocking execution (session: ${sessionId ?? "global"})`
688
803
  );
689
- this.logger.debug(`\u{1F6AB} Tool execution blocked by policy: ${toolName}`);
690
804
  throw ToolError.executionDenied(toolName, sessionId);
691
805
  }
692
806
  const customApprovalResult = await this.checkCustomApprovalOverride(
@@ -697,25 +811,29 @@ let _ToolManager = class _ToolManager {
697
811
  if (customApprovalResult.handled) {
698
812
  return { requireApproval: true, approvalStatus: "approved" };
699
813
  }
814
+ if (sessionId && this.isToolAutoApprovedForSession(sessionId, toolName)) {
815
+ this.logger.info(
816
+ `Tool '${toolName}' is in session's auto-approve list \u2013 skipping confirmation (session: ${sessionId})`
817
+ );
818
+ return { requireApproval: false };
819
+ }
700
820
  if (this.isInAlwaysAllowList(toolName)) {
701
821
  this.logger.info(
702
822
  `Tool '${toolName}' is in static allow list \u2013 skipping confirmation (session: ${sessionId ?? "global"})`
703
823
  );
704
824
  return { requireApproval: false };
705
825
  }
706
- const isAllowed = await this.allowedToolsProvider.isToolAllowed(toolName, sessionId);
707
- if (isAllowed) {
826
+ if (await this.allowedToolsProvider.isToolAllowed(toolName, sessionId)) {
708
827
  this.logger.info(
709
828
  `Tool '${toolName}' already allowed for session '${sessionId ?? "global"}' \u2013 skipping confirmation.`
710
829
  );
711
830
  return { requireApproval: false };
712
831
  }
713
- let bashPatternResult;
714
832
  if (this.isBashTool(toolName)) {
715
833
  const command = args.command;
716
834
  if (command) {
717
- bashPatternResult = this.checkBashPatternApproval(command);
718
- if (bashPatternResult.approved) {
835
+ const bashResult = this.checkBashPatternApproval(command);
836
+ if (bashResult.approved) {
719
837
  this.logger.info(
720
838
  `Bash command '${command}' matched approved pattern \u2013 skipping confirmation.`
721
839
  );
@@ -731,79 +849,37 @@ let _ToolManager = class _ToolManager {
731
849
  this.logger.debug(`\u{1F6AB} Auto-denying tool execution: ${toolName}`);
732
850
  throw ToolError.executionDenied(toolName, sessionId);
733
851
  }
852
+ return null;
853
+ }
854
+ /**
855
+ * Request manual approval from the user for a tool execution.
856
+ * Generates preview, sends approval request, and handles the response.
857
+ */
858
+ async requestManualApproval(toolName, args, toolCallId, sessionId) {
734
859
  this.logger.info(
735
860
  `Tool confirmation requested for ${toolName}, sessionId: ${sessionId ?? "global"}`
736
861
  );
737
862
  try {
738
- let displayPreview;
739
- const actualToolName = toolName.replace(/^internal--/, "").replace(/^custom--/, "");
740
- const internalTool = this.internalToolsProvider?.getTool(actualToolName);
741
- if (internalTool?.generatePreview) {
742
- try {
743
- const context = { sessionId, toolCallId };
744
- const preview = await internalTool.generatePreview(args, context);
745
- displayPreview = preview ?? void 0;
746
- this.logger.debug(`Generated preview for ${toolName}`);
747
- } catch (previewError) {
748
- if (previewError instanceof DextoRuntimeError && previewError.code === ToolErrorCode.VALIDATION_FAILED) {
749
- this.logger.debug(
750
- `Validation failed for ${toolName}: ${previewError.message}`
751
- );
752
- throw previewError;
753
- }
754
- this.logger.debug(
755
- `Preview generation failed for ${toolName}: ${previewError instanceof Error ? previewError.message : String(previewError)}`
756
- );
757
- }
758
- }
759
- const requestData = {
863
+ const displayPreview = await this.generateToolPreview(
760
864
  toolName,
865
+ args,
761
866
  toolCallId,
762
- args
763
- };
764
- if (sessionId !== void 0) {
765
- requestData.sessionId = sessionId;
766
- }
767
- if (displayPreview !== void 0) {
768
- requestData.displayPreview = displayPreview;
769
- }
770
- if (bashPatternResult?.suggestedPatterns && bashPatternResult.suggestedPatterns.length > 0) {
771
- requestData.suggestedPatterns = bashPatternResult.suggestedPatterns;
772
- }
773
- const response = await this.approvalManager.requestToolConfirmation(requestData);
867
+ sessionId
868
+ );
869
+ const suggestedPatterns = this.getBashSuggestedPatterns(toolName, args);
870
+ const response = await this.approvalManager.requestToolConfirmation({
871
+ toolName,
872
+ toolCallId,
873
+ args,
874
+ ...sessionId !== void 0 && { sessionId },
875
+ ...displayPreview !== void 0 && { displayPreview },
876
+ ...suggestedPatterns !== void 0 && { suggestedPatterns }
877
+ });
774
878
  if (response.status === ApprovalStatus.APPROVED && response.data) {
775
- const rememberChoice = "rememberChoice" in response.data ? response.data.rememberChoice : false;
776
- const rememberPattern = "rememberPattern" in response.data ? response.data.rememberPattern : void 0;
777
- if (rememberChoice) {
778
- const allowSessionId = sessionId ?? response.sessionId;
779
- await this.allowedToolsProvider.allowTool(toolName, allowSessionId);
780
- this.logger.info(
781
- `Tool '${toolName}' added to allowed tools for session '${allowSessionId ?? "global"}' (remember choice selected)`
782
- );
783
- this.autoApprovePendingToolRequests(toolName, allowSessionId);
784
- } else if (rememberPattern && typeof rememberPattern === "string" && this.isBashTool(toolName)) {
785
- this.approvalManager.addBashPattern(rememberPattern);
786
- this.logger.info(
787
- `Bash pattern '${rememberPattern}' added for session approval`
788
- );
789
- this.autoApprovePendingBashRequests(rememberPattern, sessionId);
790
- }
879
+ await this.handleRememberChoice(toolName, response, sessionId);
791
880
  }
792
- const approved = response.status === ApprovalStatus.APPROVED;
793
- if (!approved) {
794
- if (response.status === ApprovalStatus.CANCELLED && response.reason === "timeout") {
795
- this.logger.info(
796
- `Tool confirmation timed out for ${toolName}, sessionId: ${sessionId ?? "global"}`
797
- );
798
- this.logger.debug(`\u23F1\uFE0F Tool execution timed out: ${toolName}`);
799
- const timeoutMs = response.timeoutMs ?? 0;
800
- throw ToolError.executionTimeout(toolName, timeoutMs, sessionId);
801
- }
802
- this.logger.info(
803
- `Tool confirmation denied for ${toolName}, sessionId: ${sessionId ?? "global"}, reason: ${response.reason ?? "unknown"}`
804
- );
805
- this.logger.debug(`\u{1F6AB} Tool execution denied: ${toolName}`);
806
- throw ToolError.executionDenied(toolName, sessionId);
881
+ if (response.status !== ApprovalStatus.APPROVED) {
882
+ this.handleApprovalDenied(toolName, response, sessionId);
807
883
  }
808
884
  this.logger.info(
809
885
  `Tool confirmation approved for ${toolName}, sessionId: ${sessionId ?? "global"}`
@@ -816,6 +892,81 @@ let _ToolManager = class _ToolManager {
816
892
  throw error;
817
893
  }
818
894
  }
895
+ /**
896
+ * Generate a preview for the tool approval UI if the tool supports it.
897
+ */
898
+ async generateToolPreview(toolName, args, toolCallId, sessionId) {
899
+ const actualToolName = toolName.replace(/^internal--/, "").replace(/^custom--/, "");
900
+ const internalTool = this.internalToolsProvider?.getTool(actualToolName);
901
+ if (!internalTool?.generatePreview) {
902
+ return void 0;
903
+ }
904
+ try {
905
+ const context = { sessionId, toolCallId };
906
+ const preview = await internalTool.generatePreview(args, context);
907
+ this.logger.debug(`Generated preview for ${toolName}`);
908
+ return preview ?? void 0;
909
+ } catch (previewError) {
910
+ if (previewError instanceof DextoRuntimeError && previewError.code === ToolErrorCode.VALIDATION_FAILED) {
911
+ this.logger.debug(`Validation failed for ${toolName}: ${previewError.message}`);
912
+ throw previewError;
913
+ }
914
+ this.logger.debug(
915
+ `Preview generation failed for ${toolName}: ${previewError instanceof Error ? previewError.message : String(previewError)}`
916
+ );
917
+ return void 0;
918
+ }
919
+ }
920
+ /**
921
+ * Get suggested bash patterns for the approval UI.
922
+ */
923
+ getBashSuggestedPatterns(toolName, args) {
924
+ if (!this.isBashTool(toolName)) {
925
+ return void 0;
926
+ }
927
+ const command = args.command;
928
+ if (!command) {
929
+ return void 0;
930
+ }
931
+ const result = this.checkBashPatternApproval(command);
932
+ return result.suggestedPatterns?.length ? result.suggestedPatterns : void 0;
933
+ }
934
+ /**
935
+ * Handle "remember choice" or "remember pattern" when user approves a tool.
936
+ */
937
+ async handleRememberChoice(toolName, response, sessionId) {
938
+ const data = response.data;
939
+ if (!data) return;
940
+ const rememberChoice = data.rememberChoice;
941
+ const rememberPattern = data.rememberPattern;
942
+ if (rememberChoice) {
943
+ const allowSessionId = sessionId ?? response.sessionId;
944
+ await this.allowedToolsProvider.allowTool(toolName, allowSessionId);
945
+ this.logger.info(
946
+ `Tool '${toolName}' added to allowed tools for session '${allowSessionId ?? "global"}' (remember choice selected)`
947
+ );
948
+ this.autoApprovePendingToolRequests(toolName, allowSessionId);
949
+ } else if (rememberPattern && this.isBashTool(toolName)) {
950
+ this.approvalManager.addBashPattern(rememberPattern);
951
+ this.logger.info(`Bash pattern '${rememberPattern}' added for session approval`);
952
+ this.autoApprovePendingBashRequests(rememberPattern, sessionId);
953
+ }
954
+ }
955
+ /**
956
+ * Handle approval denied/timeout - throws appropriate error.
957
+ */
958
+ handleApprovalDenied(toolName, response, sessionId) {
959
+ if (response.status === ApprovalStatus.CANCELLED && response.reason === DenialReason.TIMEOUT) {
960
+ this.logger.info(
961
+ `Tool confirmation timed out for ${toolName}, sessionId: ${sessionId ?? "global"}`
962
+ );
963
+ throw ToolError.executionTimeout(toolName, response.timeoutMs ?? 0, sessionId);
964
+ }
965
+ this.logger.info(
966
+ `Tool confirmation denied for ${toolName}, sessionId: ${sessionId ?? "global"}, reason: ${response.reason ?? "unknown"}`
967
+ );
968
+ throw ToolError.executionDenied(toolName, sessionId, response.message);
969
+ }
819
970
  /**
820
971
  * Refresh tool discovery (call when MCP servers change)
821
972
  * Refreshes both MCPManager's cache (server capabilities) and ToolManager's cache (combined tools)
@@ -32,6 +32,8 @@ const PROVIDER_API_KEY_MAP = {
32
32
  groq: ["GROQ_API_KEY"],
33
33
  cohere: ["COHERE_API_KEY"],
34
34
  xai: ["XAI_API_KEY", "X_AI_API_KEY"],
35
+ minimax: ["MINIMAX_API_KEY"],
36
+ glm: ["ZHIPU_API_KEY", "ZHIPUAI_API_KEY"],
35
37
  openrouter: ["OPENROUTER_API_KEY"],
36
38
  litellm: ["LITELLM_API_KEY", "LITELLM_KEY"],
37
39
  glama: ["GLAMA_API_KEY"],
@@ -47,9 +49,10 @@ const PROVIDER_API_KEY_MAP = {
47
49
  // Local providers don't require API keys
48
50
  local: [],
49
51
  // Native node-llama-cpp execution
50
- ollama: []
52
+ ollama: [],
51
53
  // Ollama server (no authentication required)
52
- // TODO: dexto: ['DEXTO_API_KEY'],
54
+ // Dexto gateway - requires key from `dexto login`
55
+ dexto: ["DEXTO_API_KEY"]
53
56
  // perplexity: ['PERPLEXITY_API_KEY'],
54
57
  // together: ['TOGETHER_API_KEY'],
55
58
  // fireworks: ['FIREWORKS_API_KEY'],
@@ -1 +1 @@
1
- {"version":3,"file":"api-key-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/api-key-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;GAGG;AAGH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CA4B9D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAelF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAGpE"}
1
+ {"version":3,"file":"api-key-resolver.d.ts","sourceRoot":"","sources":["../../src/utils/api-key-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;GAGG;AAGH,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,CA+B9D,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,SAAS,CAelF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAGpE"}
@@ -8,6 +8,8 @@ const PROVIDER_API_KEY_MAP = {
8
8
  groq: ["GROQ_API_KEY"],
9
9
  cohere: ["COHERE_API_KEY"],
10
10
  xai: ["XAI_API_KEY", "X_AI_API_KEY"],
11
+ minimax: ["MINIMAX_API_KEY"],
12
+ glm: ["ZHIPU_API_KEY", "ZHIPUAI_API_KEY"],
11
13
  openrouter: ["OPENROUTER_API_KEY"],
12
14
  litellm: ["LITELLM_API_KEY", "LITELLM_KEY"],
13
15
  glama: ["GLAMA_API_KEY"],
@@ -23,9 +25,10 @@ const PROVIDER_API_KEY_MAP = {
23
25
  // Local providers don't require API keys
24
26
  local: [],
25
27
  // Native node-llama-cpp execution
26
- ollama: []
28
+ ollama: [],
27
29
  // Ollama server (no authentication required)
28
- // TODO: dexto: ['DEXTO_API_KEY'],
30
+ // Dexto gateway - requires key from `dexto login`
31
+ dexto: ["DEXTO_API_KEY"]
29
32
  // perplexity: ['PERPLEXITY_API_KEY'],
30
33
  // together: ['TOGETHER_API_KEY'],
31
34
  // fireworks: ['FIREWORKS_API_KEY'],
@@ -45,7 +45,7 @@ var import_manager4 = require("../approval/manager.js");
45
45
  var import_memory = require("../memory/index.js");
46
46
  var import_manager5 = require("../plugins/manager.js");
47
47
  var import_builtins = require("../plugins/registrations/builtins.js");
48
- async function createAgentServices(config, configPath, logger, agentEventBus) {
48
+ async function createAgentServices(config, configPath, logger, agentEventBus, overrides) {
49
49
  if (config.telemetry?.enabled) {
50
50
  const { Telemetry } = await import("../telemetry/telemetry.js");
51
51
  await Telemetry.init(config.telemetry);
@@ -78,6 +78,9 @@ async function createAgentServices(config, configPath, logger, agentEventBus) {
78
78
  );
79
79
  logger.debug("Approval system initialized");
80
80
  const mcpManager = new import_manager.MCPManager(logger);
81
+ if (overrides?.mcpAuthProviderFactory) {
82
+ mcpManager.setAuthProviderFactory(overrides.mcpAuthProviderFactory);
83
+ }
81
84
  await mcpManager.initializeFromConfig(config.mcpServers);
82
85
  mcpManager.setApprovalManager(approvalManager);
83
86
  logger.debug("Approval manager connected to MCP manager for elicitation support");
@@ -170,7 +173,10 @@ async function createAgentServices(config, configPath, logger, agentEventBus) {
170
173
  },
171
174
  {
172
175
  maxSessions: config.sessions?.maxSessions,
173
- sessionTTL: config.sessions?.sessionTTL
176
+ sessionTTL: config.sessions?.sessionTTL,
177
+ ...overrides?.sessionLoggerFactory !== void 0 && {
178
+ sessionLoggerFactory: overrides.sessionLoggerFactory
179
+ }
174
180
  },
175
181
  logger
176
182
  );
@@ -35,7 +35,11 @@ export type AgentServices = {
35
35
  * @param configPath Optional path to the config file (for relative path resolution)
36
36
  * @param logger Logger instance for this agent (dependency injection)
37
37
  * @param agentEventBus Pre-created event bus from DextoAgent constructor
38
+ * @param overrides Optional service overrides for customization (e.g., sessionLoggerFactory)
38
39
  * @returns All the initialized services required for a Dexto agent
39
40
  */
40
- export declare function createAgentServices(config: ValidatedAgentConfig, configPath: string | undefined, logger: IDextoLogger, agentEventBus: AgentEventBus): Promise<AgentServices>;
41
+ export declare function createAgentServices(config: ValidatedAgentConfig, configPath: string | undefined, logger: IDextoLogger, agentEventBus: AgentEventBus, overrides?: {
42
+ sessionLoggerFactory?: import('../session/session-manager.js').SessionLoggerFactory;
43
+ mcpAuthProviderFactory?: import('../mcp/types.js').McpAuthProviderFactory | null;
44
+ }): Promise<AgentServices>;
41
45
  //# sourceMappingURL=service-initializer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service-initializer.d.ts","sourceRoot":"","sources":["../../src/utils/service-initializer.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAwB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,iBAAiB,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,aAAa,CAAC;CAChC,CAAC;AAGF;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,oBAAoB,EAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,aAAa,GAC7B,OAAO,CAAC,aAAa,CAAC,CAgMxB"}
1
+ {"version":3,"file":"service-initializer.d.ts","sourceRoot":"","sources":["../../src/utils/service-initializer.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAwB,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,iBAAiB,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,EAAE,cAAc,CAAC;IAC/B,eAAe,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,aAAa,CAAC;CAChC,CAAC;AAGF;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACrC,MAAM,EAAE,oBAAoB,EAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,aAAa,EAC5B,SAAS,CAAC,EAAE;IACR,oBAAoB,CAAC,EAAE,OAAO,+BAA+B,EAAE,oBAAoB,CAAC;IACpF,sBAAsB,CAAC,EAAE,OAAO,iBAAiB,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACpF,GACF,OAAO,CAAC,aAAa,CAAC,CAsMxB"}
@@ -13,7 +13,7 @@ import { ApprovalManager } from "../approval/manager.js";
13
13
  import { MemoryManager } from "../memory/index.js";
14
14
  import { PluginManager } from "../plugins/manager.js";
15
15
  import { registerBuiltInPlugins } from "../plugins/registrations/builtins.js";
16
- async function createAgentServices(config, configPath, logger, agentEventBus) {
16
+ async function createAgentServices(config, configPath, logger, agentEventBus, overrides) {
17
17
  if (config.telemetry?.enabled) {
18
18
  const { Telemetry } = await import("../telemetry/telemetry.js");
19
19
  await Telemetry.init(config.telemetry);
@@ -46,6 +46,9 @@ async function createAgentServices(config, configPath, logger, agentEventBus) {
46
46
  );
47
47
  logger.debug("Approval system initialized");
48
48
  const mcpManager = new MCPManager(logger);
49
+ if (overrides?.mcpAuthProviderFactory) {
50
+ mcpManager.setAuthProviderFactory(overrides.mcpAuthProviderFactory);
51
+ }
49
52
  await mcpManager.initializeFromConfig(config.mcpServers);
50
53
  mcpManager.setApprovalManager(approvalManager);
51
54
  logger.debug("Approval manager connected to MCP manager for elicitation support");
@@ -138,7 +141,10 @@ async function createAgentServices(config, configPath, logger, agentEventBus) {
138
141
  },
139
142
  {
140
143
  maxSessions: config.sessions?.maxSessions,
141
- sessionTTL: config.sessions?.sessionTTL
144
+ sessionTTL: config.sessions?.sessionTTL,
145
+ ...overrides?.sessionLoggerFactory !== void 0 && {
146
+ sessionLoggerFactory: overrides.sessionLoggerFactory
147
+ }
142
148
  },
143
149
  logger
144
150
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexto/core",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",