@dexto/core 1.5.3 → 1.5.4

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 (92) hide show
  1. package/dist/agent/DextoAgent.cjs +284 -1
  2. package/dist/agent/DextoAgent.d.ts +114 -0
  3. package/dist/agent/DextoAgent.d.ts.map +1 -1
  4. package/dist/agent/DextoAgent.js +275 -1
  5. package/dist/agent/schemas.d.ts +51 -21
  6. package/dist/agent/schemas.d.ts.map +1 -1
  7. package/dist/context/compaction/overflow.cjs +6 -10
  8. package/dist/context/compaction/overflow.d.ts +14 -11
  9. package/dist/context/compaction/overflow.d.ts.map +1 -1
  10. package/dist/context/compaction/overflow.js +6 -10
  11. package/dist/context/compaction/providers/reactive-overflow-provider.cjs +15 -0
  12. package/dist/context/compaction/providers/reactive-overflow-provider.d.ts +15 -0
  13. package/dist/context/compaction/providers/reactive-overflow-provider.d.ts.map +1 -1
  14. package/dist/context/compaction/providers/reactive-overflow-provider.js +15 -0
  15. package/dist/context/compaction/schemas.cjs +22 -2
  16. package/dist/context/compaction/schemas.d.ts +45 -0
  17. package/dist/context/compaction/schemas.d.ts.map +1 -1
  18. package/dist/context/compaction/schemas.js +22 -2
  19. package/dist/context/compaction/strategies/reactive-overflow.cjs +166 -26
  20. package/dist/context/compaction/strategies/reactive-overflow.d.ts +21 -0
  21. package/dist/context/compaction/strategies/reactive-overflow.d.ts.map +1 -1
  22. package/dist/context/compaction/strategies/reactive-overflow.js +166 -26
  23. package/dist/context/manager.cjs +278 -31
  24. package/dist/context/manager.d.ts +192 -5
  25. package/dist/context/manager.d.ts.map +1 -1
  26. package/dist/context/manager.js +285 -32
  27. package/dist/context/types.d.ts +6 -0
  28. package/dist/context/types.d.ts.map +1 -1
  29. package/dist/context/utils.cjs +77 -11
  30. package/dist/context/utils.d.ts +86 -8
  31. package/dist/context/utils.d.ts.map +1 -1
  32. package/dist/context/utils.js +71 -11
  33. package/dist/events/index.cjs +4 -0
  34. package/dist/events/index.d.ts +41 -7
  35. package/dist/events/index.d.ts.map +1 -1
  36. package/dist/events/index.js +4 -0
  37. package/dist/llm/executor/stream-processor.cjs +19 -1
  38. package/dist/llm/executor/stream-processor.d.ts +3 -0
  39. package/dist/llm/executor/stream-processor.d.ts.map +1 -1
  40. package/dist/llm/executor/stream-processor.js +19 -1
  41. package/dist/llm/executor/turn-executor.cjs +219 -30
  42. package/dist/llm/executor/turn-executor.d.ts +62 -10
  43. package/dist/llm/executor/turn-executor.d.ts.map +1 -1
  44. package/dist/llm/executor/turn-executor.js +219 -30
  45. package/dist/llm/executor/types.d.ts +28 -0
  46. package/dist/llm/executor/types.d.ts.map +1 -1
  47. package/dist/llm/formatters/vercel.cjs +36 -28
  48. package/dist/llm/formatters/vercel.d.ts.map +1 -1
  49. package/dist/llm/formatters/vercel.js +36 -28
  50. package/dist/llm/services/factory.cjs +3 -2
  51. package/dist/llm/services/factory.d.ts +3 -1
  52. package/dist/llm/services/factory.d.ts.map +1 -1
  53. package/dist/llm/services/factory.js +3 -2
  54. package/dist/llm/services/vercel.cjs +34 -6
  55. package/dist/llm/services/vercel.d.ts +23 -3
  56. package/dist/llm/services/vercel.d.ts.map +1 -1
  57. package/dist/llm/services/vercel.js +34 -6
  58. package/dist/session/chat-session.cjs +20 -11
  59. package/dist/session/chat-session.d.ts +9 -4
  60. package/dist/session/chat-session.d.ts.map +1 -1
  61. package/dist/session/chat-session.js +20 -11
  62. package/dist/session/compaction-service.cjs +139 -0
  63. package/dist/session/compaction-service.d.ts +81 -0
  64. package/dist/session/compaction-service.d.ts.map +1 -0
  65. package/dist/session/compaction-service.js +106 -0
  66. package/dist/session/session-manager.cjs +146 -0
  67. package/dist/session/session-manager.d.ts +50 -0
  68. package/dist/session/session-manager.d.ts.map +1 -1
  69. package/dist/session/session-manager.js +146 -0
  70. package/dist/session/title-generator.cjs +2 -2
  71. package/dist/session/title-generator.js +2 -2
  72. package/dist/systemPrompt/in-built-prompts.cjs +36 -0
  73. package/dist/systemPrompt/in-built-prompts.d.ts +18 -1
  74. package/dist/systemPrompt/in-built-prompts.d.ts.map +1 -1
  75. package/dist/systemPrompt/in-built-prompts.js +25 -0
  76. package/dist/systemPrompt/manager.cjs +22 -0
  77. package/dist/systemPrompt/manager.d.ts +10 -0
  78. package/dist/systemPrompt/manager.d.ts.map +1 -1
  79. package/dist/systemPrompt/manager.js +22 -0
  80. package/dist/systemPrompt/registry.cjs +2 -1
  81. package/dist/systemPrompt/registry.d.ts +1 -1
  82. package/dist/systemPrompt/registry.d.ts.map +1 -1
  83. package/dist/systemPrompt/registry.js +2 -1
  84. package/dist/systemPrompt/schemas.cjs +7 -0
  85. package/dist/systemPrompt/schemas.d.ts +13 -13
  86. package/dist/systemPrompt/schemas.d.ts.map +1 -1
  87. package/dist/systemPrompt/schemas.js +7 -0
  88. package/dist/utils/index.cjs +3 -1
  89. package/dist/utils/index.d.ts +1 -0
  90. package/dist/utils/index.d.ts.map +1 -1
  91. package/dist/utils/index.js +1 -0
  92. package/package.json +1 -1
@@ -23,7 +23,7 @@ import { ReactiveOverflowStrategy } from "../../context/compaction/strategies/re
23
23
  const toolSupportCache = /* @__PURE__ */ new Map();
24
24
  const LOCAL_PROVIDERS = ["ollama", "local"];
25
25
  class TurnExecutor {
26
- constructor(model, toolManager, contextManager, eventBus, resourceManager, sessionId, config, llmContext, logger, messageQueue, modelLimits, externalSignal, compactionStrategy) {
26
+ constructor(model, toolManager, contextManager, eventBus, resourceManager, sessionId, config, llmContext, logger, messageQueue, modelLimits, externalSignal, compactionStrategy, compactionThresholdPercent = 1) {
27
27
  this.model = model;
28
28
  this.toolManager = toolManager;
29
29
  this.contextManager = contextManager;
@@ -35,6 +35,7 @@ class TurnExecutor {
35
35
  this.messageQueue = messageQueue;
36
36
  this.modelLimits = modelLimits;
37
37
  this.externalSignal = externalSignal;
38
+ this.compactionThresholdPercent = compactionThresholdPercent;
38
39
  this.logger = logger.createChild(DextoLogComponent.EXECUTOR);
39
40
  this.stepAbortController = new AbortController();
40
41
  if (compactionStrategy !== void 0) {
@@ -55,13 +56,32 @@ class TurnExecutor {
55
56
  * Used to pass approval info from tool execution to result persistence.
56
57
  */
57
58
  approvalMetadata = /* @__PURE__ */ new Map();
59
+ /**
60
+ * Tracks whether compaction occurred during this turn.
61
+ * Used to signal to the caller that session continuation may be needed.
62
+ */
63
+ compactionOccurred = false;
64
+ /**
65
+ * Compaction data captured during this turn.
66
+ * Contains summary text and preserved messages for session continuation.
67
+ * This data is passed up the call chain (NOT persisted to original session).
68
+ */
69
+ compactionData = null;
70
+ /**
71
+ * Virtual context for remaining iterations after compaction.
72
+ * When set, the main loop uses this instead of calling getFormattedMessagesForLLM().
73
+ * This provides reduced context to the LLM without persisting to the original session.
74
+ */
75
+ virtualContext = null;
58
76
  /**
59
77
  * Get StreamProcessor config from TurnExecutor state.
78
+ * @param estimatedInputTokens Optional estimated input tokens for analytics
60
79
  */
61
- getStreamProcessorConfig() {
80
+ getStreamProcessorConfig(estimatedInputTokens) {
62
81
  return {
63
82
  provider: this.llmContext.provider,
64
- model: this.llmContext.model
83
+ model: this.llmContext.model,
84
+ ...estimatedInputTokens !== void 0 && { estimatedInputTokens }
65
85
  };
66
86
  }
67
87
  /**
@@ -117,13 +137,34 @@ class TurnExecutor {
117
137
  if (coalesced) {
118
138
  await this.injectQueuedMessages(coalesced);
119
139
  }
120
- if (lastStepTokens && this.checkAndHandleOverflow(lastStepTokens)) {
121
- await this.compress(lastStepTokens.inputTokens ?? 0);
122
- }
123
- const prepared = await this.contextManager.getFormattedMessagesWithCompression(
140
+ await this.pruneOldToolOutputs();
141
+ let prepared = this.virtualContext ? await this.buildMessagesFromVirtualContext(contributorContext) : await this.contextManager.getFormattedMessagesForLLM(
124
142
  contributorContext,
125
143
  this.llmContext
126
144
  );
145
+ const toolDefinitions = supportsTools ? await this.toolManager.getAllTools() : {};
146
+ let estimatedTokens = await this.contextManager.getEstimatedNextInputTokens(
147
+ prepared.systemPrompt,
148
+ prepared.preparedHistory,
149
+ toolDefinitions
150
+ );
151
+ if (this.shouldCompact(estimatedTokens)) {
152
+ this.logger.debug(
153
+ `Pre-check: estimated ${estimatedTokens} tokens exceeds threshold, compacting`
154
+ );
155
+ await this.compactToVirtualContext(estimatedTokens);
156
+ if (this.virtualContext) {
157
+ prepared = await this.buildMessagesFromVirtualContext(contributorContext);
158
+ estimatedTokens = await this.contextManager.getEstimatedNextInputTokens(
159
+ prepared.systemPrompt,
160
+ prepared.preparedHistory,
161
+ toolDefinitions
162
+ );
163
+ this.logger.debug(
164
+ `Post-compaction: recomputed estimate is ${estimatedTokens} tokens`
165
+ );
166
+ }
167
+ }
127
168
  this.logger.debug(`Step ${stepCount}: Starting`);
128
169
  const tools = supportsTools ? await this.createTools() : {};
129
170
  const streamProcessor = new StreamProcessor(
@@ -131,7 +172,7 @@ class TurnExecutor {
131
172
  this.eventBus,
132
173
  this.resourceManager,
133
174
  this.stepAbortController.signal,
134
- this.getStreamProcessorConfig(),
175
+ this.getStreamProcessorConfig(estimatedTokens),
135
176
  this.logger,
136
177
  streaming,
137
178
  this.approvalMetadata
@@ -170,6 +211,28 @@ class TurnExecutor {
170
211
  this.logger.debug(
171
212
  `Step ${stepCount}: Finished with reason="${result.finishReason}", tokens=${JSON.stringify(result.usage)}`
172
213
  );
214
+ if (result.finishReason === "cancelled") {
215
+ this.logger.info(
216
+ `Context estimation (cancelled): keeping last known actuals, partial response (${result.text.length} chars) will be estimated`
217
+ );
218
+ } else if (result.usage?.inputTokens !== void 0) {
219
+ const diff = estimatedTokens - result.usage.inputTokens;
220
+ const diffPercent = result.usage.inputTokens > 0 ? (diff / result.usage.inputTokens * 100).toFixed(1) : "0.0";
221
+ this.logger.info(
222
+ `Context estimation accuracy: estimated=${estimatedTokens}, actual=${result.usage.inputTokens}, error=${diff} (${diffPercent}%)`
223
+ );
224
+ this.contextManager.setLastActualInputTokens(result.usage.inputTokens);
225
+ if (result.usage?.outputTokens !== void 0) {
226
+ this.contextManager.setLastActualOutputTokens(result.usage.outputTokens);
227
+ }
228
+ await this.contextManager.recordLastCallMessageCount();
229
+ }
230
+ if (!this.virtualContext && result.usage?.inputTokens && this.shouldCompactFromActual(result.usage.inputTokens)) {
231
+ this.logger.debug(
232
+ `Post-response: actual ${result.usage.inputTokens} tokens exceeds threshold, compacting`
233
+ );
234
+ await this.compactToVirtualContext(result.usage.inputTokens);
235
+ }
173
236
  if (result.finishReason !== "tool-calls") {
174
237
  const queuedOnTerminate = this.messageQueue.dequeueAll();
175
238
  if (queuedOnTerminate) {
@@ -193,7 +256,6 @@ class TurnExecutor {
193
256
  lastFinishReason = "max-steps";
194
257
  break;
195
258
  }
196
- await this.pruneOldToolOutputs();
197
259
  }
198
260
  } catch (error) {
199
261
  const mappedError = this.mapProviderError(error);
@@ -223,7 +285,14 @@ class TurnExecutor {
223
285
  text: lastText,
224
286
  stepCount,
225
287
  usage: lastStepTokens,
226
- finishReason: lastFinishReason
288
+ finishReason: lastFinishReason,
289
+ // Signal to caller that compaction occurred during this turn
290
+ // Caller can use this to trigger session-native continuation
291
+ didCompact: this.compactionOccurred,
292
+ // Pass compaction data up the chain (NOT persisted to original session)
293
+ // Caller uses this to create the continuation session with summary
294
+ // Use spread to conditionally include only when data exists (exactOptionalPropertyTypes)
295
+ ...this.compactionData && { compaction: this.compactionData }
227
296
  };
228
297
  } catch (_2) {
229
298
  var _error = _2, _hasError = true;
@@ -521,7 +590,7 @@ class TurnExecutor {
521
590
  /**
522
591
  * Prunes old tool outputs by marking them with compactedAt timestamp.
523
592
  * Does NOT modify content - transformation happens at format time in
524
- * ContextManager.getFormattedMessagesWithCompression().
593
+ * ContextManager.prepareHistory().
525
594
  *
526
595
  * Algorithm:
527
596
  * 1. Go backwards through history (most recent first)
@@ -590,55 +659,175 @@ class TurnExecutor {
590
659
  this.messageQueue.clear();
591
660
  }
592
661
  /**
593
- * Check if context has overflowed based on actual token usage from API.
662
+ * Check if context should be compacted based on estimated token count.
663
+ * Uses the threshold percentage from compaction config to trigger earlier (e.g., at 90%).
664
+ *
665
+ * @param estimatedTokens Estimated token count from the current context
666
+ * @returns true if compaction is needed before making the LLM call
594
667
  */
595
- checkAndHandleOverflow(tokens) {
668
+ shouldCompact(estimatedTokens) {
596
669
  if (!this.modelLimits || !this.compactionStrategy) {
597
670
  return false;
598
671
  }
599
- return isOverflow(tokens, this.modelLimits);
672
+ return isOverflow(
673
+ { inputTokens: estimatedTokens },
674
+ this.modelLimits,
675
+ this.compactionThresholdPercent
676
+ );
600
677
  }
601
678
  /**
602
- * Compress context using ReactiveOverflowStrategy.
679
+ * Check if context should be compacted based on actual token count from API response.
680
+ * This is a post-response check using real token counts rather than estimates.
603
681
  *
604
- * Generates a summary of older messages and adds it to history.
605
- * The actual token reduction happens at read-time via filterCompacted()
606
- * in getFormattedMessagesWithCompression().
682
+ * @param actualTokens Actual input token count from the API response
683
+ * @returns true if compaction is needed
684
+ */
685
+ shouldCompactFromActual(actualTokens) {
686
+ if (!this.modelLimits || !this.compactionStrategy) {
687
+ return false;
688
+ }
689
+ return isOverflow(
690
+ { inputTokens: actualTokens },
691
+ this.modelLimits,
692
+ this.compactionThresholdPercent
693
+ );
694
+ }
695
+ /**
696
+ * Compact context using ReactiveOverflowStrategy WITHOUT persisting to original session.
697
+ *
698
+ * Key design: Creates a virtual context (summary + preserved messages) that will be used
699
+ * for the remaining iterations of this turn. The compaction data is passed up the call chain
700
+ * so the caller can create a continuation session with the summary.
607
701
  *
608
- * @param originalTokens The actual input token count from API that triggered overflow
702
+ * The original session remains UNTOUCHED - no messages are added or modified.
703
+ *
704
+ * @param originalTokens The estimated input token count that triggered overflow
609
705
  */
610
- async compress(originalTokens) {
706
+ async compactToVirtualContext(originalTokens) {
611
707
  if (!this.compactionStrategy) {
612
708
  return;
613
709
  }
614
710
  this.logger.info(
615
- `Context overflow detected (${originalTokens} tokens), running compression`
711
+ `Context overflow detected (${originalTokens} tokens), checking if compression is possible`
616
712
  );
617
713
  const history = await this.contextManager.getHistory();
714
+ if (history.length < 4) {
715
+ this.logger.debug("Compaction skipped: history too short to summarize");
716
+ return;
717
+ }
718
+ this.eventBus.emit("context:compacting", {
719
+ estimatedTokens: originalTokens
720
+ });
618
721
  const summaryMessages = await this.compactionStrategy.compact(history);
619
722
  if (summaryMessages.length === 0) {
620
- this.logger.debug("Compaction returned no summary (history too short)");
723
+ this.logger.debug(
724
+ "Compaction skipped: strategy returned no summary (likely already compacted or nothing to summarize)"
725
+ );
726
+ this.eventBus.emit("context:compacted", {
727
+ originalTokens,
728
+ compactedTokens: originalTokens,
729
+ // No change
730
+ originalMessages: history.length,
731
+ compactedMessages: history.length,
732
+ // No change
733
+ strategy: this.compactionStrategy.name,
734
+ reason: "overflow"
735
+ });
736
+ return;
737
+ }
738
+ const summaryMessage = summaryMessages[0];
739
+ if (!summaryMessage) {
740
+ this.logger.warn("Compaction returned empty summary message array");
621
741
  return;
622
742
  }
623
- for (const summary of summaryMessages) {
624
- await this.contextManager.addMessage(summary);
743
+ const summaryText = this.extractSummaryText(summaryMessage);
744
+ const summarizedCount = summaryMessage.metadata?.originalMessageCount ?? 0;
745
+ let existingSummaryIndex = -1;
746
+ for (let i = history.length - 1; i >= 0; i--) {
747
+ const msg = history[i];
748
+ if (msg?.metadata?.isSummary === true || msg?.metadata?.isSessionSummary === true) {
749
+ existingSummaryIndex = i;
750
+ break;
751
+ }
625
752
  }
626
- const { filterCompacted, estimateMessagesTokens } = await import("../../context/utils.js");
627
- const updatedHistory = await this.contextManager.getHistory();
628
- const filteredHistory = filterCompacted(updatedHistory);
629
- const compactedTokens = estimateMessagesTokens(filteredHistory);
753
+ const baseIndex = existingSummaryIndex >= 0 ? existingSummaryIndex + 1 : 0;
754
+ const preservedMessages = history.slice(baseIndex + summarizedCount);
755
+ const firstTimestamp = summaryMessage.metadata?.originalFirstTimestamp;
756
+ const lastTimestamp = summaryMessage.metadata?.originalLastTimestamp;
757
+ this.compactionData = {
758
+ summaryText,
759
+ preservedMessages: [...preservedMessages],
760
+ // Copy to avoid mutation
761
+ summarizedCount,
762
+ ...firstTimestamp !== void 0 && { originalFirstTimestamp: firstTimestamp },
763
+ ...lastTimestamp !== void 0 && { originalLastTimestamp: lastTimestamp }
764
+ };
765
+ this.virtualContext = {
766
+ summaryMessage,
767
+ preservedMessages: [...preservedMessages]
768
+ };
769
+ this.compactionOccurred = true;
770
+ this.contextManager.resetActualTokenTracking();
771
+ const { estimateMessagesTokens: estimateTokens } = await import("../../context/utils.js");
772
+ const virtualMessages = [summaryMessage, ...preservedMessages];
773
+ const compactedTokens = estimateTokens(virtualMessages);
630
774
  this.eventBus.emit("context:compacted", {
631
775
  originalTokens,
632
776
  compactedTokens,
633
777
  originalMessages: history.length,
634
- compactedMessages: filteredHistory.length,
778
+ compactedMessages: virtualMessages.length,
635
779
  strategy: this.compactionStrategy.name,
636
780
  reason: "overflow"
637
781
  });
638
782
  this.logger.info(
639
- `Compaction complete: ${originalTokens} \u2192 ~${compactedTokens} tokens (${history.length} \u2192 ${filteredHistory.length} messages after filtering)`
783
+ `Compaction complete (virtual context): ${originalTokens} \u2192 ~${compactedTokens} tokens (${history.length} \u2192 ${virtualMessages.length} messages). Original session unchanged - summary will be passed to continuation session.`
640
784
  );
641
785
  }
786
+ /**
787
+ * Extract the summary text from a summary message.
788
+ */
789
+ extractSummaryText(summaryMessage) {
790
+ if (typeof summaryMessage.content === "string") {
791
+ return summaryMessage.content;
792
+ }
793
+ if (Array.isArray(summaryMessage.content)) {
794
+ return summaryMessage.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
795
+ }
796
+ return "";
797
+ }
798
+ /**
799
+ * Build formatted messages from virtual context (after compaction).
800
+ *
801
+ * This creates LLM-ready messages using:
802
+ * - System prompt (same as normal flow)
803
+ * - Summary message (as first message)
804
+ * - Preserved messages (formatted for LLM)
805
+ *
806
+ * Uses the same formatting pipeline as getFormattedMessagesForLLM()
807
+ * but with our virtual history instead of the stored history.
808
+ *
809
+ * @param contributorContext Context for system prompt contributors
810
+ * @returns Formatted messages ready for LLM call, matching getFormattedMessagesForLLM return type
811
+ */
812
+ async buildMessagesFromVirtualContext(contributorContext) {
813
+ if (!this.virtualContext) {
814
+ throw new Error("buildMessagesFromVirtualContext called without virtual context");
815
+ }
816
+ const { summaryMessage, preservedMessages } = this.virtualContext;
817
+ const systemPrompt = await this.contextManager.getSystemPrompt(contributorContext);
818
+ const virtualHistory = [summaryMessage, ...preservedMessages];
819
+ const formattedMessages = await this.contextManager.getFormattedMessages(
820
+ contributorContext,
821
+ this.llmContext,
822
+ systemPrompt,
823
+ virtualHistory
824
+ );
825
+ return {
826
+ formattedMessages,
827
+ systemPrompt,
828
+ preparedHistory: virtualHistory
829
+ };
830
+ }
642
831
  /**
643
832
  * Set telemetry span attributes for token usage.
644
833
  */
@@ -1,5 +1,23 @@
1
+ import type { InternalMessage } from '../../context/types.js';
1
2
  import { TokenUsage } from '../types.js';
2
3
  import { LLMFinishReason } from '../../events/index.js';
4
+ /**
5
+ * Data captured during context compaction for session-native continuation.
6
+ * This is passed through the call chain so the new session can be created
7
+ * with the summary and preserved messages.
8
+ */
9
+ export interface CompactionData {
10
+ /** The generated summary text */
11
+ summaryText: string;
12
+ /** Messages preserved (not summarized) - typically last N turns */
13
+ preservedMessages: InternalMessage[];
14
+ /** Number of messages that were summarized */
15
+ summarizedCount: number;
16
+ /** Timestamp of first summarized message */
17
+ originalFirstTimestamp?: number;
18
+ /** Timestamp of last summarized message */
19
+ originalLastTimestamp?: number;
20
+ }
3
21
  export interface ExecutorResult {
4
22
  /**
5
23
  * The accumulated text from assistant responses.
@@ -13,6 +31,16 @@ export interface ExecutorResult {
13
31
  usage: TokenUsage | null;
14
32
  /** Reason the execution finished */
15
33
  finishReason: LLMFinishReason;
34
+ /**
35
+ * Set to true if context compaction occurred during this turn.
36
+ * Caller can use this to trigger session-native continuation (create new session).
37
+ */
38
+ didCompact: boolean;
39
+ /**
40
+ * Compaction data when didCompact is true.
41
+ * Contains the summary text and preserved messages for creating the continuation session.
42
+ */
43
+ compaction?: CompactionData;
16
44
  }
17
45
  export interface StreamProcessorResult {
18
46
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/llm/executor/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,WAAW,cAAc;IAC3B;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,oCAAoC;IACpC,YAAY,EAAE,eAAe,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,eAAe,CAAC;IAC9B,KAAK,EAAE,UAAU,CAAC;CACrB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/llm/executor/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC3B,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,iBAAiB,EAAE,eAAe,EAAE,CAAC;IACrC,8CAA8C;IAC9C,eAAe,EAAE,MAAM,CAAC;IACxB,4CAA4C;IAC5C,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,2CAA2C;IAC3C,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC3B;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,qCAAqC;IACrC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,oCAAoC;IACpC,YAAY,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,cAAc,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,eAAe,CAAC;IAC9B,KAAK,EAAE,UAAU,CAAC;CACrB"}
@@ -166,16 +166,26 @@ class VercelMessageFormatter {
166
166
  formatSystemPrompt() {
167
167
  return null;
168
168
  }
169
- // Helper to format Assistant messages (with optional tool calls)
169
+ // Helper to format Assistant messages (with optional tool calls and reasoning)
170
170
  formatAssistantMessage(msg) {
171
- if (msg.toolCalls && msg.toolCalls.length > 0) {
172
- const contentParts = [];
173
- if (Array.isArray(msg.content)) {
174
- const combined = msg.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join("\n");
175
- if (combined) {
176
- contentParts.push({ type: "text", text: combined });
177
- }
171
+ const contentParts = [];
172
+ if (msg.reasoning) {
173
+ const reasoningPart = {
174
+ type: "reasoning",
175
+ text: msg.reasoning,
176
+ ...msg.reasoningMetadata && { providerOptions: msg.reasoningMetadata }
177
+ };
178
+ contentParts.push(reasoningPart);
179
+ }
180
+ if (Array.isArray(msg.content)) {
181
+ const combined = msg.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join("\n");
182
+ if (combined) {
183
+ contentParts.push({ type: "text", text: combined });
178
184
  }
185
+ } else if (typeof msg.content === "string") {
186
+ contentParts.push({ type: "text", text: msg.content });
187
+ }
188
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
179
189
  for (const toolCall of msg.toolCalls) {
180
190
  const rawArgs = toolCall.function.arguments;
181
191
  let parsed = {};
@@ -202,28 +212,26 @@ class VercelMessageFormatter {
202
212
  }
203
213
  contentParts.push(toolCallPart);
204
214
  }
205
- const firstToolCall = msg.toolCalls?.[0];
206
- if (firstToolCall) {
207
- const argString = (() => {
208
- const raw = firstToolCall.function.arguments;
209
- if (typeof raw === "string") return raw;
210
- try {
211
- return JSON.stringify(raw ?? {});
212
- } catch {
213
- return "{}";
214
- }
215
- })();
216
- return {
217
- content: contentParts,
218
- function_call: {
219
- name: firstToolCall.function.name,
220
- arguments: argString
221
- }
222
- };
223
- }
215
+ const firstToolCall = msg.toolCalls[0];
216
+ const argString = (() => {
217
+ const raw = firstToolCall.function.arguments;
218
+ if (typeof raw === "string") return raw;
219
+ try {
220
+ return JSON.stringify(raw ?? {});
221
+ } catch {
222
+ return "{}";
223
+ }
224
+ })();
225
+ return {
226
+ content: contentParts,
227
+ function_call: {
228
+ name: firstToolCall.function.name,
229
+ arguments: argString
230
+ }
231
+ };
224
232
  }
225
233
  return {
226
- content: typeof msg.content === "string" ? [{ type: "text", text: msg.content }] : msg.content === null ? [] : msg.content
234
+ content: contentParts.length > 0 ? contentParts : []
227
235
  };
228
236
  }
229
237
  // Helper to format Tool result messages
@@ -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,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAiC,MAAM,wBAAwB,CAAC;AAE7F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAmB7D;;;;;;;;;;GAUG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAGhC;;;;;;OAMG;IACH,MAAM,CACF,OAAO,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC,EACpC,OAAO,EAAE,UAAU,EACnB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC5B,YAAY,EAAE;IAsJjB;;;;;;OAMG;IACH,kBAAkB,IAAI,IAAI;IAK1B,OAAO,CAAC,sBAAsB;IA8E9B,OAAO,CAAC,iBAAiB;CAoE5B"}
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,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAiC,MAAM,wBAAwB,CAAC;AAE7F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAmB7D;;;;;;;;;;GAUG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAGhC;;;;;;OAMG;IACH,MAAM,CACF,OAAO,EAAE,QAAQ,CAAC,eAAe,EAAE,CAAC,EACpC,OAAO,EAAE,UAAU,EACnB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC5B,YAAY,EAAE;IAsJjB;;;;;;OAMG;IACH,kBAAkB,IAAI,IAAI;IAK1B,OAAO,CAAC,sBAAsB;IA0F9B,OAAO,CAAC,iBAAiB;CAoE5B"}
@@ -144,16 +144,26 @@ class VercelMessageFormatter {
144
144
  formatSystemPrompt() {
145
145
  return null;
146
146
  }
147
- // Helper to format Assistant messages (with optional tool calls)
147
+ // Helper to format Assistant messages (with optional tool calls and reasoning)
148
148
  formatAssistantMessage(msg) {
149
- if (msg.toolCalls && msg.toolCalls.length > 0) {
150
- const contentParts = [];
151
- if (Array.isArray(msg.content)) {
152
- const combined = msg.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join("\n");
153
- if (combined) {
154
- contentParts.push({ type: "text", text: combined });
155
- }
149
+ const contentParts = [];
150
+ if (msg.reasoning) {
151
+ const reasoningPart = {
152
+ type: "reasoning",
153
+ text: msg.reasoning,
154
+ ...msg.reasoningMetadata && { providerOptions: msg.reasoningMetadata }
155
+ };
156
+ contentParts.push(reasoningPart);
157
+ }
158
+ if (Array.isArray(msg.content)) {
159
+ const combined = msg.content.map((part) => part.type === "text" ? part.text : "").filter(Boolean).join("\n");
160
+ if (combined) {
161
+ contentParts.push({ type: "text", text: combined });
156
162
  }
163
+ } else if (typeof msg.content === "string") {
164
+ contentParts.push({ type: "text", text: msg.content });
165
+ }
166
+ if (msg.toolCalls && msg.toolCalls.length > 0) {
157
167
  for (const toolCall of msg.toolCalls) {
158
168
  const rawArgs = toolCall.function.arguments;
159
169
  let parsed = {};
@@ -180,28 +190,26 @@ class VercelMessageFormatter {
180
190
  }
181
191
  contentParts.push(toolCallPart);
182
192
  }
183
- const firstToolCall = msg.toolCalls?.[0];
184
- if (firstToolCall) {
185
- const argString = (() => {
186
- const raw = firstToolCall.function.arguments;
187
- if (typeof raw === "string") return raw;
188
- try {
189
- return JSON.stringify(raw ?? {});
190
- } catch {
191
- return "{}";
192
- }
193
- })();
194
- return {
195
- content: contentParts,
196
- function_call: {
197
- name: firstToolCall.function.name,
198
- arguments: argString
199
- }
200
- };
201
- }
193
+ const firstToolCall = msg.toolCalls[0];
194
+ const argString = (() => {
195
+ const raw = firstToolCall.function.arguments;
196
+ if (typeof raw === "string") return raw;
197
+ try {
198
+ return JSON.stringify(raw ?? {});
199
+ } catch {
200
+ return "{}";
201
+ }
202
+ })();
203
+ return {
204
+ content: contentParts,
205
+ function_call: {
206
+ name: firstToolCall.function.name,
207
+ arguments: argString
208
+ }
209
+ };
202
210
  }
203
211
  return {
204
- content: typeof msg.content === "string" ? [{ type: "text", text: msg.content }] : msg.content === null ? [] : msg.content
212
+ content: contentParts.length > 0 ? contentParts : []
205
213
  };
206
214
  }
207
215
  // Helper to format Tool result messages
@@ -139,7 +139,7 @@ function getOpenAICompatibleBaseURL(llmConfig) {
139
139
  }
140
140
  return "";
141
141
  }
142
- function createLLMService(config, toolManager, systemPromptManager, historyProvider, sessionEventBus, sessionId, resourceManager, logger, compactionStrategy) {
142
+ function createLLMService(config, toolManager, systemPromptManager, historyProvider, sessionEventBus, sessionId, resourceManager, logger, compactionStrategy, compactionConfig) {
143
143
  const model = createVercelModel(config);
144
144
  return new import_vercel.VercelLLMService(
145
145
  toolManager,
@@ -151,7 +151,8 @@ function createLLMService(config, toolManager, systemPromptManager, historyProvi
151
151
  sessionId,
152
152
  resourceManager,
153
153
  logger,
154
- compactionStrategy
154
+ compactionStrategy,
155
+ compactionConfig
155
156
  );
156
157
  }
157
158
  // Annotate the CommonJS export names for ESM import in node:
@@ -6,6 +6,7 @@ import { SessionEventBus } from '../../events/index.js';
6
6
  import type { IConversationHistoryProvider } from '../../session/history/types.js';
7
7
  import type { SystemPromptManager } from '../../systemPrompt/manager.js';
8
8
  import type { IDextoLogger } from '../../logger/v2/types.js';
9
+ import type { CompactionConfigInput } from '../../context/compaction/schemas.js';
9
10
  export declare function createVercelModel(llmConfig: ValidatedLLMConfig): LanguageModel;
10
11
  /**
11
12
  * Create an LLM service instance using the Vercel AI SDK.
@@ -20,7 +21,8 @@ export declare function createVercelModel(llmConfig: ValidatedLLMConfig): Langua
20
21
  * @param resourceManager Resource manager for blob storage and resource access
21
22
  * @param logger Logger instance for dependency injection
22
23
  * @param compactionStrategy Optional compaction strategy for context management
24
+ * @param compactionConfig Optional compaction configuration for thresholds
23
25
  * @returns VercelLLMService instance
24
26
  */
25
- export declare function createLLMService(config: ValidatedLLMConfig, toolManager: ToolManager, systemPromptManager: SystemPromptManager, historyProvider: IConversationHistoryProvider, sessionEventBus: SessionEventBus, sessionId: string, resourceManager: import('../../resources/index.js').ResourceManager, logger: IDextoLogger, compactionStrategy?: import('../../context/compaction/types.js').ICompactionStrategy | null): VercelLLMService;
27
+ export declare function createLLMService(config: ValidatedLLMConfig, toolManager: ToolManager, systemPromptManager: SystemPromptManager, historyProvider: IConversationHistoryProvider, sessionEventBus: SessionEventBus, sessionId: string, resourceManager: import('../../resources/index.js').ResourceManager, logger: IDextoLogger, compactionStrategy?: import('../../context/compaction/types.js').ICompactionStrategy | null, compactionConfig?: CompactionConfigInput): VercelLLMService;
26
28
  //# sourceMappingURL=factory.d.ts.map
@@ -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;AAUnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAI7D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,aAAa,CAoJ9E;AAoBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,WAAW,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,eAAe,EAAE,4BAA4B,EAC7C,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,0BAA0B,EAAE,eAAe,EACnE,MAAM,EAAE,YAAY,EACpB,kBAAkB,CAAC,EAAE,OAAO,mCAAmC,EAAE,mBAAmB,GAAG,IAAI,GAC5F,gBAAgB,CAelB"}
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;AAUnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAEjF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,kBAAkB,GAAG,aAAa,CAoJ9E;AAoBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,kBAAkB,EAC1B,WAAW,EAAE,WAAW,EACxB,mBAAmB,EAAE,mBAAmB,EACxC,eAAe,EAAE,4BAA4B,EAC7C,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,OAAO,0BAA0B,EAAE,eAAe,EACnE,MAAM,EAAE,YAAY,EACpB,kBAAkB,CAAC,EAAE,OAAO,mCAAmC,EAAE,mBAAmB,GAAG,IAAI,EAC3F,gBAAgB,CAAC,EAAE,qBAAqB,GACzC,gBAAgB,CAgBlB"}
@@ -116,7 +116,7 @@ function getOpenAICompatibleBaseURL(llmConfig) {
116
116
  }
117
117
  return "";
118
118
  }
119
- function createLLMService(config, toolManager, systemPromptManager, historyProvider, sessionEventBus, sessionId, resourceManager, logger, compactionStrategy) {
119
+ function createLLMService(config, toolManager, systemPromptManager, historyProvider, sessionEventBus, sessionId, resourceManager, logger, compactionStrategy, compactionConfig) {
120
120
  const model = createVercelModel(config);
121
121
  return new VercelLLMService(
122
122
  toolManager,
@@ -128,7 +128,8 @@ function createLLMService(config, toolManager, systemPromptManager, historyProvi
128
128
  sessionId,
129
129
  resourceManager,
130
130
  logger,
131
- compactionStrategy
131
+ compactionStrategy,
132
+ compactionConfig
132
133
  );
133
134
  }
134
135
  export {