@dexto/core 1.8.11 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/dist/approval/manager.cjs +37 -325
  2. package/dist/approval/manager.d.ts +10 -109
  3. package/dist/approval/manager.d.ts.map +1 -1
  4. package/dist/approval/manager.js +37 -316
  5. package/dist/approval/schemas.cjs +8 -51
  6. package/dist/approval/schemas.d.ts +5 -179
  7. package/dist/approval/schemas.d.ts.map +1 -1
  8. package/dist/approval/schemas.js +8 -47
  9. package/dist/approval/types.cjs +0 -6
  10. package/dist/approval/types.d.ts +2 -27
  11. package/dist/approval/types.d.ts.map +1 -1
  12. package/dist/approval/types.js +0 -6
  13. package/dist/context/content-clone.cjs +12 -8
  14. package/dist/context/content-clone.d.ts.map +1 -1
  15. package/dist/context/content-clone.js +12 -8
  16. package/dist/errors/DextoRuntimeError.cjs +3 -1
  17. package/dist/errors/DextoRuntimeError.d.ts +5 -3
  18. package/dist/errors/DextoRuntimeError.d.ts.map +1 -1
  19. package/dist/errors/DextoRuntimeError.js +3 -1
  20. package/dist/errors/index.d.ts +1 -1
  21. package/dist/errors/index.d.ts.map +1 -1
  22. package/dist/errors/types.d.ts +1 -0
  23. package/dist/errors/types.d.ts.map +1 -1
  24. package/dist/events/index.d.ts +2 -2
  25. package/dist/events/index.d.ts.map +1 -1
  26. package/dist/llm/executor/provider-error.cjs +25 -4
  27. package/dist/llm/executor/provider-error.d.ts.map +1 -1
  28. package/dist/llm/executor/provider-error.js +25 -4
  29. package/dist/llm/executor/stream-processor.cjs +61 -0
  30. package/dist/llm/executor/stream-processor.d.ts.map +1 -1
  31. package/dist/llm/executor/stream-processor.js +61 -0
  32. package/dist/llm/executor/turn-executor.cjs +93 -26
  33. package/dist/llm/executor/turn-executor.d.ts +2 -0
  34. package/dist/llm/executor/turn-executor.d.ts.map +1 -1
  35. package/dist/llm/executor/turn-executor.js +93 -26
  36. package/dist/llm/formatters/vercel.cjs +66 -0
  37. package/dist/llm/formatters/vercel.d.ts.map +1 -1
  38. package/dist/llm/formatters/vercel.js +66 -0
  39. package/dist/llm/services/factory.cjs +3 -2
  40. package/dist/llm/services/factory.d.ts.map +1 -1
  41. package/dist/llm/services/factory.js +3 -2
  42. package/dist/llm/services/types.d.ts +8 -0
  43. package/dist/llm/services/types.d.ts.map +1 -1
  44. package/dist/llm/services/vercel.cjs +6 -1
  45. package/dist/llm/services/vercel.d.ts +3 -2
  46. package/dist/llm/services/vercel.d.ts.map +1 -1
  47. package/dist/llm/services/vercel.js +6 -1
  48. package/dist/session/chat-session.cjs +3 -0
  49. package/dist/session/chat-session.d.ts +2 -1
  50. package/dist/session/chat-session.d.ts.map +1 -1
  51. package/dist/session/chat-session.js +3 -0
  52. package/dist/session/message-queue.cjs +48 -75
  53. package/dist/session/message-queue.d.ts +1 -2
  54. package/dist/session/message-queue.d.ts.map +1 -1
  55. package/dist/session/message-queue.js +48 -75
  56. package/dist/session/session-manager.cjs +14 -32
  57. package/dist/session/session-manager.d.ts +5 -2
  58. package/dist/session/session-manager.d.ts.map +1 -1
  59. package/dist/session/session-manager.js +14 -32
  60. package/dist/storage/approvals/types.cjs +2 -9
  61. package/dist/storage/approvals/types.d.ts +4 -16
  62. package/dist/storage/approvals/types.d.ts.map +1 -1
  63. package/dist/storage/approvals/types.js +2 -8
  64. package/dist/storage/database/types.d.ts +5 -0
  65. package/dist/storage/database/types.d.ts.map +1 -1
  66. package/dist/storage/index.cjs +0 -2
  67. package/dist/storage/index.d.ts +2 -2
  68. package/dist/storage/index.d.ts.map +1 -1
  69. package/dist/storage/index.js +1 -2
  70. package/dist/storage/message-queue/types.d.ts +14 -6
  71. package/dist/storage/message-queue/types.d.ts.map +1 -1
  72. package/dist/storage/stores/backend.cjs +68 -32
  73. package/dist/storage/stores/backend.d.ts +17 -8
  74. package/dist/storage/stores/backend.d.ts.map +1 -1
  75. package/dist/storage/stores/backend.js +69 -33
  76. package/dist/storage/stores/in-memory.cjs +26 -11
  77. package/dist/storage/stores/in-memory.d.ts.map +1 -1
  78. package/dist/storage/stores/in-memory.js +27 -12
  79. package/dist/test-utils/in-memory-storage.cjs +11 -0
  80. package/dist/test-utils/in-memory-storage.js +11 -0
  81. package/dist/test-utils/session-state-stores.cjs +25 -9
  82. package/dist/test-utils/session-state-stores.js +26 -10
  83. package/dist/tools/approval/tool-approval-policy.cjs +87 -0
  84. package/dist/tools/approval/tool-approval-policy.d.ts +34 -0
  85. package/dist/tools/approval/tool-approval-policy.d.ts.map +1 -0
  86. package/dist/tools/approval/tool-approval-policy.js +64 -0
  87. package/dist/tools/error-codes.cjs +0 -1
  88. package/dist/tools/error-codes.d.ts +0 -1
  89. package/dist/tools/error-codes.d.ts.map +1 -1
  90. package/dist/tools/error-codes.js +0 -1
  91. package/dist/tools/errors.cjs +0 -15
  92. package/dist/tools/errors.d.ts +0 -9
  93. package/dist/tools/errors.d.ts.map +1 -1
  94. package/dist/tools/errors.js +0 -15
  95. package/dist/tools/index.cjs +2 -0
  96. package/dist/tools/index.d.ts +1 -1
  97. package/dist/tools/index.d.ts.map +1 -1
  98. package/dist/tools/index.js +5 -1
  99. package/dist/tools/tool-manager.cjs +94 -312
  100. package/dist/tools/tool-manager.d.ts +4 -19
  101. package/dist/tools/tool-manager.d.ts.map +1 -1
  102. package/dist/tools/tool-manager.js +95 -316
  103. package/dist/tools/types.d.ts +10 -9
  104. package/dist/tools/types.d.ts.map +1 -1
  105. package/dist/utils/service-initializer.cjs +3 -0
  106. package/dist/utils/service-initializer.d.ts +2 -1
  107. package/dist/utils/service-initializer.d.ts.map +1 -1
  108. package/dist/utils/service-initializer.js +3 -0
  109. package/package.json +2 -2
  110. package/dist/tools/pattern-utils.cjs +0 -33
  111. package/dist/tools/pattern-utils.d.ts +0 -20
  112. package/dist/tools/pattern-utils.d.ts.map +0 -1
  113. package/dist/tools/pattern-utils.js +0 -10
@@ -51,6 +51,7 @@ var import_types3 = require("../../approval/types.js");
51
51
  var import_content_audit = require("../../context/content-audit.js");
52
52
  const MCP_TOOL_PREFIX = "mcp--";
53
53
  const MODEL_REQUEST_MAX_RETRIES = 2;
54
+ const TOOL_SUPPORT_PROBE_TIMEOUT_MS = 5e3;
54
55
  const LLMFinishReasonStateSchema = import_zod.z.enum([
55
56
  "stop",
56
57
  "tool-calls",
@@ -182,6 +183,24 @@ function toModelStepRequestState(request) {
182
183
  }
183
184
  const toolSupportCache = /* @__PURE__ */ new Map();
184
185
  const LOCAL_PROVIDERS = ["ollama", "local"];
186
+ function isManagedGatewayProvider(provider) {
187
+ return provider === "dexto-nova";
188
+ }
189
+ function toolSupportValidationAttributes(result) {
190
+ const attributes = {
191
+ "llm.tool_support.cache_hit": result.cacheHit,
192
+ "llm.tool_support.validation_mode": result.validationMode,
193
+ "llm.tools_supported": result.supported
194
+ };
195
+ if (result.validationMode !== "probe") {
196
+ return attributes;
197
+ }
198
+ return {
199
+ ...attributes,
200
+ "llm.tool_support.probe_outcome": result.probeOutcome,
201
+ "llm.tool_support.probe_timeout_ms": result.probeTimeoutMs
202
+ };
203
+ }
185
204
  class TurnExecutor {
186
205
  constructor(model, toolManager, contextManager, eventBus, resourceManager, sessionId, config, llmContext, logger, steerQueue, followUpQueue, modelLimits, externalSignal, compactionStrategy = null, runContext) {
187
206
  this.model = model;
@@ -607,7 +626,21 @@ class TurnExecutor {
607
626
  }
608
627
  async startTurn() {
609
628
  this.eventBus.emit("llm:thinking", {});
610
- const supportsTools = await this.validateToolSupport();
629
+ const toolSupportValidation = await (0, import_operation_span.recordOperationSpan)(
630
+ {
631
+ name: "llm.tool_support_validation",
632
+ componentName: "TurnExecutor",
633
+ attributes: {
634
+ "llm.model": this.llmContext.model,
635
+ "llm.provider": this.llmContext.provider,
636
+ "llm.base_url_present": this.config.baseURL !== void 0
637
+ },
638
+ resultAttributes: toolSupportValidationAttributes
639
+ },
640
+ () => this.validateToolSupport(),
641
+ this.logger
642
+ );
643
+ const supportsTools = toolSupportValidation.supported;
611
644
  if (!supportsTools) {
612
645
  const modelKey = `${this.llmContext.provider}:${this.llmContext.model}`;
613
646
  this.eventBus.emit("llm:unsupported-input", {
@@ -758,14 +791,16 @@ class TurnExecutor {
758
791
  result.finishReason
759
792
  );
760
793
  }
761
- await this.followUpQueue.refresh();
762
- if (this.followUpQueue.hasPending()) {
763
- return this.continueWithQueuedInput(
764
- "follow-up",
765
- this.followUpQueue,
766
- stepCount,
767
- result.finishReason
768
- );
794
+ if (this.config.executionControl?.followUpQueueMode !== "host-run") {
795
+ await this.followUpQueue.refresh();
796
+ if (this.followUpQueue.hasPending()) {
797
+ return this.continueWithQueuedInput(
798
+ "follow-up",
799
+ this.followUpQueue,
800
+ stepCount,
801
+ result.finishReason
802
+ );
803
+ }
769
804
  }
770
805
  this.logger.debug(`Terminating: finishReason is "${result.finishReason}"`);
771
806
  return {
@@ -808,14 +843,33 @@ class TurnExecutor {
808
843
  async validateToolSupport() {
809
844
  const modelKey = `${this.llmContext.provider}:${this.llmContext.model}:${this.config.baseURL ?? ""}`;
810
845
  if (toolSupportCache.has(modelKey)) {
811
- return toolSupportCache.get(modelKey);
846
+ return {
847
+ supported: toolSupportCache.get(modelKey),
848
+ cacheHit: true,
849
+ validationMode: "cache"
850
+ };
812
851
  }
813
852
  if ((0, import_codex_base_url.isCodexBaseURL)(this.config.baseURL)) {
814
853
  this.logger.debug(
815
854
  `Skipping tool validation for ${modelKey} - Codex app-server integration manages tool support internally`
816
855
  );
817
856
  toolSupportCache.set(modelKey, true);
818
- return true;
857
+ return {
858
+ supported: true,
859
+ cacheHit: false,
860
+ validationMode: "codex_base_url_skip"
861
+ };
862
+ }
863
+ if (isManagedGatewayProvider(this.llmContext.provider)) {
864
+ this.logger.debug(
865
+ `Skipping tool validation for ${modelKey} - managed gateway provider controls tool support`
866
+ );
867
+ toolSupportCache.set(modelKey, true);
868
+ return {
869
+ supported: true,
870
+ cacheHit: false,
871
+ validationMode: "managed_gateway_assumed"
872
+ };
819
873
  }
820
874
  const isLocalProvider = LOCAL_PROVIDERS.includes(this.llmContext.provider);
821
875
  if (!this.config.baseURL && !isLocalProvider) {
@@ -823,7 +877,11 @@ class TurnExecutor {
823
877
  `Skipping tool validation for ${modelKey} - known cloud provider without custom baseURL`
824
878
  );
825
879
  toolSupportCache.set(modelKey, true);
826
- return true;
880
+ return {
881
+ supported: true,
882
+ cacheHit: false,
883
+ validationMode: "cloud_provider_assumed"
884
+ };
827
885
  }
828
886
  this.logger.debug(
829
887
  `Testing tool support for ${isLocalProvider ? "local provider" : "custom endpoint"} model: ${modelKey}`
@@ -839,7 +897,7 @@ class TurnExecutor {
839
897
  }
840
898
  };
841
899
  const testAbort = new AbortController();
842
- const testTimeout = setTimeout(() => testAbort.abort(), 5e3);
900
+ const testTimeout = setTimeout(() => testAbort.abort(), TOOL_SUPPORT_PROBE_TIMEOUT_MS);
843
901
  try {
844
902
  await (0, import_ai.generateText)({
845
903
  model: this.model,
@@ -851,7 +909,13 @@ class TurnExecutor {
851
909
  clearTimeout(testTimeout);
852
910
  toolSupportCache.set(modelKey, true);
853
911
  this.logger.debug(`Model ${modelKey} supports tools`);
854
- return true;
912
+ return {
913
+ supported: true,
914
+ cacheHit: false,
915
+ validationMode: "probe",
916
+ probeOutcome: "supported",
917
+ probeTimeoutMs: TOOL_SUPPORT_PROBE_TIMEOUT_MS
918
+ };
855
919
  } catch (error) {
856
920
  clearTimeout(testTimeout);
857
921
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -860,13 +924,25 @@ class TurnExecutor {
860
924
  this.logger.debug(
861
925
  `Detected that model ${modelKey} does not support tool calling - tool functionality will be disabled`
862
926
  );
863
- return false;
927
+ return {
928
+ supported: false,
929
+ cacheHit: false,
930
+ validationMode: "probe",
931
+ probeOutcome: "unsupported",
932
+ probeTimeoutMs: TOOL_SUPPORT_PROBE_TIMEOUT_MS
933
+ };
864
934
  }
865
935
  this.logger.debug(
866
936
  `Tool validation error for ${modelKey}, assuming supported: ${errorMessage}`
867
937
  );
868
938
  toolSupportCache.set(modelKey, true);
869
- return true;
939
+ return {
940
+ supported: true,
941
+ cacheHit: false,
942
+ validationMode: "probe",
943
+ probeOutcome: "error_assumed_supported",
944
+ probeTimeoutMs: TOOL_SUPPORT_PROBE_TIMEOUT_MS
945
+ };
870
946
  }
871
947
  }
872
948
  async prepareNextModelRequest(input) {
@@ -1331,11 +1407,7 @@ class TurnExecutor {
1331
1407
  return approval.modelVisibleResult;
1332
1408
  }
1333
1409
  const decision = this.toApprovalDecisionInput(approval.response);
1334
- const applied = await this.toolManager.applyApprovalDecision(
1335
- recorded,
1336
- decision,
1337
- this.runContext
1338
- );
1410
+ const applied = await this.toolManager.applyApprovalDecision(recorded, decision);
1339
1411
  if (applied.kind === "terminal") {
1340
1412
  return applied.modelVisibleResult;
1341
1413
  }
@@ -1657,11 +1729,6 @@ class TurnExecutor {
1657
1729
  if (!this.stepAbortController.signal.aborted) {
1658
1730
  this.stepAbortController.abort();
1659
1731
  }
1660
- void this.steerQueue.clear().catch((error) => {
1661
- this.logger.warn(
1662
- `Failed to clear queued steer messages during cleanup: ${error instanceof Error ? error.message : String(error)}`
1663
- );
1664
- });
1665
1732
  }
1666
1733
  /**
1667
1734
  * Check if context should be compacted based on estimated token count.
@@ -14,6 +14,7 @@ import type { MessageQueueService } from '../../session/message-queue.js';
14
14
  import type { CompactionStrategy } from '../../context/compaction/types.js';
15
15
  import type { ModelLimits } from '../../context/compaction/overflow.js';
16
16
  import type { AgentRunContext } from '../../runtime/run-context.js';
17
+ import type { LLMExecutionControl } from '../services/types.js';
17
18
  export declare const ModelStepResultStateSchema: z.ZodObject<{
18
19
  text: z.ZodString;
19
20
  finishReason: z.ZodEnum<{
@@ -274,6 +275,7 @@ export declare class TurnExecutor {
274
275
  temperature?: number | undefined;
275
276
  baseURL?: string | undefined;
276
277
  usageScopeId?: string | undefined;
278
+ executionControl?: LLMExecutionControl | undefined;
277
279
  reasoning?: LLMReasoningConfig | undefined;
278
280
  }, llmContext: LLMContext, logger: Logger, steerQueue: MessageQueueService, followUpQueue: MessageQueueService, modelLimits?: ModelLimits | undefined, externalSignal?: AbortSignal | undefined, compactionStrategy?: CompactionStrategy | null, runContext?: AgentRunContext | undefined);
279
281
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"turn-executor.d.ts","sourceRoot":"","sources":["../../../src/llm/executor/turn-executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"turn-executor.d.ts","sourceRoot":"","sources":["../../../src/llm/executor/turn-executor.ts"],"names":[],"mappings":"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"}
@@ -28,6 +28,7 @@ import {
28
28
  } from "../../context/content-audit.js";
29
29
  const MCP_TOOL_PREFIX = "mcp--";
30
30
  const MODEL_REQUEST_MAX_RETRIES = 2;
31
+ const TOOL_SUPPORT_PROBE_TIMEOUT_MS = 5e3;
31
32
  const LLMFinishReasonStateSchema = z.enum([
32
33
  "stop",
33
34
  "tool-calls",
@@ -159,6 +160,24 @@ function toModelStepRequestState(request) {
159
160
  }
160
161
  const toolSupportCache = /* @__PURE__ */ new Map();
161
162
  const LOCAL_PROVIDERS = ["ollama", "local"];
163
+ function isManagedGatewayProvider(provider) {
164
+ return provider === "dexto-nova";
165
+ }
166
+ function toolSupportValidationAttributes(result) {
167
+ const attributes = {
168
+ "llm.tool_support.cache_hit": result.cacheHit,
169
+ "llm.tool_support.validation_mode": result.validationMode,
170
+ "llm.tools_supported": result.supported
171
+ };
172
+ if (result.validationMode !== "probe") {
173
+ return attributes;
174
+ }
175
+ return {
176
+ ...attributes,
177
+ "llm.tool_support.probe_outcome": result.probeOutcome,
178
+ "llm.tool_support.probe_timeout_ms": result.probeTimeoutMs
179
+ };
180
+ }
162
181
  class TurnExecutor {
163
182
  constructor(model, toolManager, contextManager, eventBus, resourceManager, sessionId, config, llmContext, logger, steerQueue, followUpQueue, modelLimits, externalSignal, compactionStrategy = null, runContext) {
164
183
  this.model = model;
@@ -584,7 +603,21 @@ class TurnExecutor {
584
603
  }
585
604
  async startTurn() {
586
605
  this.eventBus.emit("llm:thinking", {});
587
- const supportsTools = await this.validateToolSupport();
606
+ const toolSupportValidation = await recordOperationSpan(
607
+ {
608
+ name: "llm.tool_support_validation",
609
+ componentName: "TurnExecutor",
610
+ attributes: {
611
+ "llm.model": this.llmContext.model,
612
+ "llm.provider": this.llmContext.provider,
613
+ "llm.base_url_present": this.config.baseURL !== void 0
614
+ },
615
+ resultAttributes: toolSupportValidationAttributes
616
+ },
617
+ () => this.validateToolSupport(),
618
+ this.logger
619
+ );
620
+ const supportsTools = toolSupportValidation.supported;
588
621
  if (!supportsTools) {
589
622
  const modelKey = `${this.llmContext.provider}:${this.llmContext.model}`;
590
623
  this.eventBus.emit("llm:unsupported-input", {
@@ -735,14 +768,16 @@ class TurnExecutor {
735
768
  result.finishReason
736
769
  );
737
770
  }
738
- await this.followUpQueue.refresh();
739
- if (this.followUpQueue.hasPending()) {
740
- return this.continueWithQueuedInput(
741
- "follow-up",
742
- this.followUpQueue,
743
- stepCount,
744
- result.finishReason
745
- );
771
+ if (this.config.executionControl?.followUpQueueMode !== "host-run") {
772
+ await this.followUpQueue.refresh();
773
+ if (this.followUpQueue.hasPending()) {
774
+ return this.continueWithQueuedInput(
775
+ "follow-up",
776
+ this.followUpQueue,
777
+ stepCount,
778
+ result.finishReason
779
+ );
780
+ }
746
781
  }
747
782
  this.logger.debug(`Terminating: finishReason is "${result.finishReason}"`);
748
783
  return {
@@ -785,14 +820,33 @@ class TurnExecutor {
785
820
  async validateToolSupport() {
786
821
  const modelKey = `${this.llmContext.provider}:${this.llmContext.model}:${this.config.baseURL ?? ""}`;
787
822
  if (toolSupportCache.has(modelKey)) {
788
- return toolSupportCache.get(modelKey);
823
+ return {
824
+ supported: toolSupportCache.get(modelKey),
825
+ cacheHit: true,
826
+ validationMode: "cache"
827
+ };
789
828
  }
790
829
  if (isCodexBaseURL(this.config.baseURL)) {
791
830
  this.logger.debug(
792
831
  `Skipping tool validation for ${modelKey} - Codex app-server integration manages tool support internally`
793
832
  );
794
833
  toolSupportCache.set(modelKey, true);
795
- return true;
834
+ return {
835
+ supported: true,
836
+ cacheHit: false,
837
+ validationMode: "codex_base_url_skip"
838
+ };
839
+ }
840
+ if (isManagedGatewayProvider(this.llmContext.provider)) {
841
+ this.logger.debug(
842
+ `Skipping tool validation for ${modelKey} - managed gateway provider controls tool support`
843
+ );
844
+ toolSupportCache.set(modelKey, true);
845
+ return {
846
+ supported: true,
847
+ cacheHit: false,
848
+ validationMode: "managed_gateway_assumed"
849
+ };
796
850
  }
797
851
  const isLocalProvider = LOCAL_PROVIDERS.includes(this.llmContext.provider);
798
852
  if (!this.config.baseURL && !isLocalProvider) {
@@ -800,7 +854,11 @@ class TurnExecutor {
800
854
  `Skipping tool validation for ${modelKey} - known cloud provider without custom baseURL`
801
855
  );
802
856
  toolSupportCache.set(modelKey, true);
803
- return true;
857
+ return {
858
+ supported: true,
859
+ cacheHit: false,
860
+ validationMode: "cloud_provider_assumed"
861
+ };
804
862
  }
805
863
  this.logger.debug(
806
864
  `Testing tool support for ${isLocalProvider ? "local provider" : "custom endpoint"} model: ${modelKey}`
@@ -816,7 +874,7 @@ class TurnExecutor {
816
874
  }
817
875
  };
818
876
  const testAbort = new AbortController();
819
- const testTimeout = setTimeout(() => testAbort.abort(), 5e3);
877
+ const testTimeout = setTimeout(() => testAbort.abort(), TOOL_SUPPORT_PROBE_TIMEOUT_MS);
820
878
  try {
821
879
  await generateText({
822
880
  model: this.model,
@@ -828,7 +886,13 @@ class TurnExecutor {
828
886
  clearTimeout(testTimeout);
829
887
  toolSupportCache.set(modelKey, true);
830
888
  this.logger.debug(`Model ${modelKey} supports tools`);
831
- return true;
889
+ return {
890
+ supported: true,
891
+ cacheHit: false,
892
+ validationMode: "probe",
893
+ probeOutcome: "supported",
894
+ probeTimeoutMs: TOOL_SUPPORT_PROBE_TIMEOUT_MS
895
+ };
832
896
  } catch (error) {
833
897
  clearTimeout(testTimeout);
834
898
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -837,13 +901,25 @@ class TurnExecutor {
837
901
  this.logger.debug(
838
902
  `Detected that model ${modelKey} does not support tool calling - tool functionality will be disabled`
839
903
  );
840
- return false;
904
+ return {
905
+ supported: false,
906
+ cacheHit: false,
907
+ validationMode: "probe",
908
+ probeOutcome: "unsupported",
909
+ probeTimeoutMs: TOOL_SUPPORT_PROBE_TIMEOUT_MS
910
+ };
841
911
  }
842
912
  this.logger.debug(
843
913
  `Tool validation error for ${modelKey}, assuming supported: ${errorMessage}`
844
914
  );
845
915
  toolSupportCache.set(modelKey, true);
846
- return true;
916
+ return {
917
+ supported: true,
918
+ cacheHit: false,
919
+ validationMode: "probe",
920
+ probeOutcome: "error_assumed_supported",
921
+ probeTimeoutMs: TOOL_SUPPORT_PROBE_TIMEOUT_MS
922
+ };
847
923
  }
848
924
  }
849
925
  async prepareNextModelRequest(input) {
@@ -1308,11 +1384,7 @@ class TurnExecutor {
1308
1384
  return approval.modelVisibleResult;
1309
1385
  }
1310
1386
  const decision = this.toApprovalDecisionInput(approval.response);
1311
- const applied = await this.toolManager.applyApprovalDecision(
1312
- recorded,
1313
- decision,
1314
- this.runContext
1315
- );
1387
+ const applied = await this.toolManager.applyApprovalDecision(recorded, decision);
1316
1388
  if (applied.kind === "terminal") {
1317
1389
  return applied.modelVisibleResult;
1318
1390
  }
@@ -1634,11 +1706,6 @@ class TurnExecutor {
1634
1706
  if (!this.stepAbortController.signal.aborted) {
1635
1707
  this.stepAbortController.abort();
1636
1708
  }
1637
- void this.steerQueue.clear().catch((error) => {
1638
- this.logger.warn(
1639
- `Failed to clear queued steer messages during cleanup: ${error instanceof Error ? error.message : String(error)}`
1640
- );
1641
- });
1642
1709
  }
1643
1710
  /**
1644
1711
  * Check if context should be compacted based on estimated token count.
@@ -41,6 +41,70 @@ function normalizeToolMediaData(data) {
41
41
  }
42
42
  return data;
43
43
  }
44
+ function isTextLikeMimeType(mimeType) {
45
+ const normalized = mimeType.toLowerCase().split(";", 1)[0]?.trim() ?? "";
46
+ if (normalized.startsWith("text/")) return true;
47
+ if (normalized.endsWith("+json") || normalized.endsWith("+xml")) return true;
48
+ return [
49
+ "application/json",
50
+ "application/ld+json",
51
+ "application/xml",
52
+ "application/yaml",
53
+ "application/x-yaml",
54
+ "application/toml",
55
+ "application/x-toml",
56
+ "application/javascript",
57
+ "application/typescript",
58
+ "application/x-sh",
59
+ "application/sql"
60
+ ].includes(normalized);
61
+ }
62
+ function isRemoteFileData(data) {
63
+ return data instanceof URL || typeof data === "string" && (/^https?:\/\//i.test(data) || data.startsWith("blob:") || data.startsWith("@blob:"));
64
+ }
65
+ function decodeLikelyBase64Text(value) {
66
+ const normalized = value.replace(/\s/g, "");
67
+ if (normalized.length === 0 || normalized.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(normalized)) {
68
+ return null;
69
+ }
70
+ const decoded = Buffer.from(normalized, "base64");
71
+ const canonical = decoded.toString("base64").replace(/=+$/, "");
72
+ if (canonical !== normalized.replace(/=+$/, "")) return null;
73
+ const text = decoded.toString("utf8");
74
+ const hasInvalidControlCharacter = [...text].some((char) => {
75
+ const code = char.charCodeAt(0);
76
+ return code < 32 && code !== 9 && code !== 10 && code !== 13;
77
+ });
78
+ if (text.includes("\uFFFD") || hasInvalidControlCharacter) {
79
+ return null;
80
+ }
81
+ return text;
82
+ }
83
+ function decodeBase64Text(value) {
84
+ return Buffer.from(value.replace(/\s/g, ""), "base64").toString("utf8");
85
+ }
86
+ function decodeTextFileData(data) {
87
+ if (data instanceof URL) return null;
88
+ if (typeof data === "string") {
89
+ const dataUri = (0, import_utils.parseDataUri)(data);
90
+ if (dataUri) return decodeBase64Text(dataUri.base64);
91
+ if (isRemoteFileData(data)) return null;
92
+ return decodeLikelyBase64Text(data) ?? data;
93
+ }
94
+ return Buffer.from(data instanceof ArrayBuffer ? new Uint8Array(data) : data).toString("utf8");
95
+ }
96
+ function filePartToText(part) {
97
+ if (!isTextLikeMimeType(part.mimeType) || isRemoteFileData(part.data)) return null;
98
+ const text = decodeTextFileData(part.data);
99
+ if (text === null) return null;
100
+ const filename = part.filename ?? "attachment";
101
+ return {
102
+ type: "text",
103
+ text: `Attached file "${filename}" (${part.mimeType}):
104
+
105
+ ${text}`
106
+ };
107
+ }
44
108
  class VercelMessageFormatter {
45
109
  logger;
46
110
  constructor(logger) {
@@ -89,6 +153,8 @@ class VercelMessageFormatter {
89
153
  (part) => part.type !== "ui-resource" && part.type !== "resource"
90
154
  ).map((part) => {
91
155
  if (part.type === "file") {
156
+ const textPart = filePartToText(part);
157
+ if (textPart) return textPart;
92
158
  return {
93
159
  type: "file",
94
160
  data: toUrlIfString(part.data),
@@ -1 +1 @@
1
- {"version":3,"file":"vercel.d.ts","sourceRoot":"","sources":["../../../src/llm/formatters/vercel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAiD,MAAM,IAAI,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAiC,MAAM,wBAAwB,CAAC;AAO7F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AA8BvD;;;;;;;;;;GAUG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAG1B;;;;;;OAMG;IACH,MAAM,CACF,OAAO,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC,EACpC,OAAO,EAAE,UAAU,EACnB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC5B,YAAY,EAAE;IAkKjB;;;;;;OAMG;IACH,kBAAkB,IAAI,IAAI;IAI1B,OAAO,CAAC,wBAAwB;IAUhC,OAAO,CAAC,sBAAsB;IAmG9B,OAAO,CAAC,iBAAiB;CA6E5B"}
1
+ {"version":3,"file":"vercel.d.ts","sourceRoot":"","sources":["../../../src/llm/formatters/vercel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAiD,MAAM,IAAI,CAAC;AACtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EACR,eAAe,EAIlB,MAAM,wBAAwB,CAAC;AAOhC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAqHvD;;;;;;;;;;GAUG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAG1B;;;;;;OAMG;IACH,MAAM,CACF,OAAO,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC,EACpC,OAAO,EAAE,UAAU,EACnB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC5B,YAAY,EAAE;IAqKjB;;;;;;OAMG;IACH,kBAAkB,IAAI,IAAI;IAI1B,OAAO,CAAC,wBAAwB;IAUhC,OAAO,CAAC,sBAAsB;IAmG9B,OAAO,CAAC,iBAAiB;CA6E5B"}
@@ -24,6 +24,70 @@ function normalizeToolMediaData(data) {
24
24
  }
25
25
  return data;
26
26
  }
27
+ function isTextLikeMimeType(mimeType) {
28
+ const normalized = mimeType.toLowerCase().split(";", 1)[0]?.trim() ?? "";
29
+ if (normalized.startsWith("text/")) return true;
30
+ if (normalized.endsWith("+json") || normalized.endsWith("+xml")) return true;
31
+ return [
32
+ "application/json",
33
+ "application/ld+json",
34
+ "application/xml",
35
+ "application/yaml",
36
+ "application/x-yaml",
37
+ "application/toml",
38
+ "application/x-toml",
39
+ "application/javascript",
40
+ "application/typescript",
41
+ "application/x-sh",
42
+ "application/sql"
43
+ ].includes(normalized);
44
+ }
45
+ function isRemoteFileData(data) {
46
+ return data instanceof URL || typeof data === "string" && (/^https?:\/\//i.test(data) || data.startsWith("blob:") || data.startsWith("@blob:"));
47
+ }
48
+ function decodeLikelyBase64Text(value) {
49
+ const normalized = value.replace(/\s/g, "");
50
+ if (normalized.length === 0 || normalized.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(normalized)) {
51
+ return null;
52
+ }
53
+ const decoded = Buffer.from(normalized, "base64");
54
+ const canonical = decoded.toString("base64").replace(/=+$/, "");
55
+ if (canonical !== normalized.replace(/=+$/, "")) return null;
56
+ const text = decoded.toString("utf8");
57
+ const hasInvalidControlCharacter = [...text].some((char) => {
58
+ const code = char.charCodeAt(0);
59
+ return code < 32 && code !== 9 && code !== 10 && code !== 13;
60
+ });
61
+ if (text.includes("\uFFFD") || hasInvalidControlCharacter) {
62
+ return null;
63
+ }
64
+ return text;
65
+ }
66
+ function decodeBase64Text(value) {
67
+ return Buffer.from(value.replace(/\s/g, ""), "base64").toString("utf8");
68
+ }
69
+ function decodeTextFileData(data) {
70
+ if (data instanceof URL) return null;
71
+ if (typeof data === "string") {
72
+ const dataUri = parseDataUri(data);
73
+ if (dataUri) return decodeBase64Text(dataUri.base64);
74
+ if (isRemoteFileData(data)) return null;
75
+ return decodeLikelyBase64Text(data) ?? data;
76
+ }
77
+ return Buffer.from(data instanceof ArrayBuffer ? new Uint8Array(data) : data).toString("utf8");
78
+ }
79
+ function filePartToText(part) {
80
+ if (!isTextLikeMimeType(part.mimeType) || isRemoteFileData(part.data)) return null;
81
+ const text = decodeTextFileData(part.data);
82
+ if (text === null) return null;
83
+ const filename = part.filename ?? "attachment";
84
+ return {
85
+ type: "text",
86
+ text: `Attached file "${filename}" (${part.mimeType}):
87
+
88
+ ${text}`
89
+ };
90
+ }
27
91
  class VercelMessageFormatter {
28
92
  logger;
29
93
  constructor(logger) {
@@ -72,6 +136,8 @@ class VercelMessageFormatter {
72
136
  (part) => part.type !== "ui-resource" && part.type !== "resource"
73
137
  ).map((part) => {
74
138
  if (part.type === "file") {
139
+ const textPart = filePartToText(part);
140
+ if (textPart) return textPart;
75
141
  return {
76
142
  type: "file",
77
143
  data: toUrlIfString(part.data),
@@ -46,7 +46,7 @@ function isLanguageModel(value) {
46
46
  const candidate = value;
47
47
  return typeof candidate["modelId"] === "string" && (typeof candidate["doGenerate"] === "function" || typeof candidate["doStream"] === "function");
48
48
  }
49
- const DEFAULT_DEXTO_GATEWAY_BASE_URL = "https://api.dexto.ai/v1";
49
+ const DEFAULT_DEXTO_GATEWAY_BASE_URL = "https://app.dexto.ai/v1";
50
50
  function trimTrailingSlash(value) {
51
51
  return value.trim().replace(/\/$/, "");
52
52
  }
@@ -327,7 +327,7 @@ function createVercelModel(llmConfig, context) {
327
327
  }
328
328
  }
329
329
  function createLLMService(config, toolManager, systemPromptManager, conversationStore, sessionEventBus, sessionId, resourceManager, logger, options, languageModelFactory) {
330
- const { usageScopeId, compactionStrategy, steerQueue, followUpQueue } = options;
330
+ const { usageScopeId, compactionStrategy, executionControl, steerQueue, followUpQueue } = options;
331
331
  const providerContext = {
332
332
  sessionId,
333
333
  ...options.cwd !== void 0 ? { cwd: options.cwd } : {},
@@ -359,6 +359,7 @@ function createLLMService(config, toolManager, systemPromptManager, conversation
359
359
  steerQueue,
360
360
  followUpQueue,
361
361
  usageScopeId,
362
+ executionControl,
362
363
  compactionStrategy
363
364
  );
364
365
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/llm/services/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAYnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,KAAK,EACR,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACvB,MAAM,YAAY,CAAC;AAqHpB;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC7B,SAAS,EAAE,kBAAkB,EAC7B,OAAO,CAAC,EAAE,oBAAoB,GAC/B,aAAa,CAsSf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,WAAW,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,0BAA0B,EAAE,eAAe,EACnE,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,uBAAuB,EAChC,oBAAoB,CAAC,EAAE,oBAAoB,GAC5C,gBAAgB,CAuClB"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/llm/services/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAYnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,KAAK,EACR,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACvB,MAAM,YAAY,CAAC;AAqHpB;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC7B,SAAS,EAAE,kBAAkB,EAC7B,OAAO,CAAC,EAAE,oBAAoB,GAC/B,aAAa,CAsSf;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,WAAW,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,0BAA0B,EAAE,eAAe,EACnE,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,uBAAuB,EAChC,oBAAoB,CAAC,EAAE,oBAAoB,GAC5C,gBAAgB,CAyClB"}
@@ -28,7 +28,7 @@ function isLanguageModel(value) {
28
28
  const candidate = value;
29
29
  return typeof candidate["modelId"] === "string" && (typeof candidate["doGenerate"] === "function" || typeof candidate["doStream"] === "function");
30
30
  }
31
- const DEFAULT_DEXTO_GATEWAY_BASE_URL = "https://api.dexto.ai/v1";
31
+ const DEFAULT_DEXTO_GATEWAY_BASE_URL = "https://app.dexto.ai/v1";
32
32
  function trimTrailingSlash(value) {
33
33
  return value.trim().replace(/\/$/, "");
34
34
  }
@@ -309,7 +309,7 @@ function createVercelModel(llmConfig, context) {
309
309
  }
310
310
  }
311
311
  function createLLMService(config, toolManager, systemPromptManager, conversationStore, sessionEventBus, sessionId, resourceManager, logger, options, languageModelFactory) {
312
- const { usageScopeId, compactionStrategy, steerQueue, followUpQueue } = options;
312
+ const { usageScopeId, compactionStrategy, executionControl, steerQueue, followUpQueue } = options;
313
313
  const providerContext = {
314
314
  sessionId,
315
315
  ...options.cwd !== void 0 ? { cwd: options.cwd } : {},
@@ -341,6 +341,7 @@ function createLLMService(config, toolManager, systemPromptManager, conversation
341
341
  steerQueue,
342
342
  followUpQueue,
343
343
  usageScopeId,
344
+ executionControl,
344
345
  compactionStrategy
345
346
  );
346
347
  }