@dexto/core 1.5.3 → 1.5.5
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.
- package/dist/agent/DextoAgent.cjs +190 -1
- package/dist/agent/DextoAgent.d.ts +71 -0
- package/dist/agent/DextoAgent.d.ts.map +1 -1
- package/dist/agent/DextoAgent.js +181 -1
- package/dist/agent/schemas.d.ts +51 -21
- package/dist/agent/schemas.d.ts.map +1 -1
- package/dist/context/compaction/overflow.cjs +6 -10
- package/dist/context/compaction/overflow.d.ts +14 -11
- package/dist/context/compaction/overflow.d.ts.map +1 -1
- package/dist/context/compaction/overflow.js +6 -10
- package/dist/context/compaction/providers/reactive-overflow-provider.cjs +15 -0
- package/dist/context/compaction/providers/reactive-overflow-provider.d.ts +15 -0
- package/dist/context/compaction/providers/reactive-overflow-provider.d.ts.map +1 -1
- package/dist/context/compaction/providers/reactive-overflow-provider.js +15 -0
- package/dist/context/compaction/schemas.cjs +22 -2
- package/dist/context/compaction/schemas.d.ts +45 -0
- package/dist/context/compaction/schemas.d.ts.map +1 -1
- package/dist/context/compaction/schemas.js +22 -2
- package/dist/context/compaction/strategies/reactive-overflow.cjs +168 -26
- package/dist/context/compaction/strategies/reactive-overflow.d.ts +22 -0
- package/dist/context/compaction/strategies/reactive-overflow.d.ts.map +1 -1
- package/dist/context/compaction/strategies/reactive-overflow.js +168 -26
- package/dist/context/compaction/types.d.ts +13 -1
- package/dist/context/compaction/types.d.ts.map +1 -1
- package/dist/context/manager.cjs +278 -31
- package/dist/context/manager.d.ts +192 -5
- package/dist/context/manager.d.ts.map +1 -1
- package/dist/context/manager.js +285 -32
- package/dist/context/types.d.ts +6 -0
- package/dist/context/types.d.ts.map +1 -1
- package/dist/context/utils.cjs +77 -11
- package/dist/context/utils.d.ts +86 -8
- package/dist/context/utils.d.ts.map +1 -1
- package/dist/context/utils.js +71 -11
- package/dist/errors/types.cjs +0 -2
- package/dist/errors/types.d.ts +1 -5
- package/dist/errors/types.d.ts.map +1 -1
- package/dist/errors/types.js +0 -2
- package/dist/events/index.cjs +2 -0
- package/dist/events/index.d.ts +21 -6
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +2 -0
- package/dist/llm/executor/stream-processor.cjs +104 -28
- package/dist/llm/executor/stream-processor.d.ts +7 -0
- package/dist/llm/executor/stream-processor.d.ts.map +1 -1
- package/dist/llm/executor/stream-processor.js +104 -28
- package/dist/llm/executor/turn-executor.cjs +147 -30
- package/dist/llm/executor/turn-executor.d.ts +28 -10
- package/dist/llm/executor/turn-executor.d.ts.map +1 -1
- package/dist/llm/executor/turn-executor.js +147 -30
- package/dist/llm/formatters/vercel.cjs +36 -28
- package/dist/llm/formatters/vercel.d.ts.map +1 -1
- package/dist/llm/formatters/vercel.js +36 -28
- package/dist/llm/services/factory.cjs +3 -2
- package/dist/llm/services/factory.d.ts +3 -1
- package/dist/llm/services/factory.d.ts.map +1 -1
- package/dist/llm/services/factory.js +3 -2
- package/dist/llm/services/vercel.cjs +31 -6
- package/dist/llm/services/vercel.d.ts +18 -3
- package/dist/llm/services/vercel.d.ts.map +1 -1
- package/dist/llm/services/vercel.js +31 -6
- package/dist/session/chat-session.cjs +29 -13
- package/dist/session/chat-session.d.ts +6 -4
- package/dist/session/chat-session.d.ts.map +1 -1
- package/dist/session/chat-session.js +29 -13
- package/dist/session/session-manager.cjs +11 -0
- package/dist/session/session-manager.d.ts +7 -0
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +11 -0
- package/dist/session/title-generator.cjs +2 -2
- package/dist/session/title-generator.js +2 -2
- package/dist/systemPrompt/in-built-prompts.cjs +36 -0
- package/dist/systemPrompt/in-built-prompts.d.ts +18 -1
- package/dist/systemPrompt/in-built-prompts.d.ts.map +1 -1
- package/dist/systemPrompt/in-built-prompts.js +25 -0
- package/dist/systemPrompt/manager.cjs +22 -0
- package/dist/systemPrompt/manager.d.ts +10 -0
- package/dist/systemPrompt/manager.d.ts.map +1 -1
- package/dist/systemPrompt/manager.js +22 -0
- package/dist/systemPrompt/registry.cjs +2 -1
- package/dist/systemPrompt/registry.d.ts +1 -1
- package/dist/systemPrompt/registry.d.ts.map +1 -1
- package/dist/systemPrompt/registry.js +2 -1
- package/dist/systemPrompt/schemas.cjs +7 -0
- package/dist/systemPrompt/schemas.d.ts +13 -13
- package/dist/systemPrompt/schemas.d.ts.map +1 -1
- package/dist/systemPrompt/schemas.js +7 -0
- package/dist/telemetry/telemetry.cjs +12 -5
- package/dist/telemetry/telemetry.d.ts.map +1 -1
- package/dist/telemetry/telemetry.js +12 -5
- package/dist/utils/index.cjs +3 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/package.json +15 -5
- package/dist/filesystem/error-codes.cjs +0 -53
- package/dist/filesystem/error-codes.d.ts +0 -31
- package/dist/filesystem/error-codes.d.ts.map +0 -1
- package/dist/filesystem/error-codes.js +0 -30
- package/dist/filesystem/errors.cjs +0 -303
- package/dist/filesystem/errors.d.ts +0 -109
- package/dist/filesystem/errors.d.ts.map +0 -1
- package/dist/filesystem/errors.js +0 -280
- package/dist/filesystem/filesystem-service.cjs +0 -534
- package/dist/filesystem/filesystem-service.d.ts +0 -97
- package/dist/filesystem/filesystem-service.d.ts.map +0 -1
- package/dist/filesystem/filesystem-service.js +0 -501
- package/dist/filesystem/index.cjs +0 -37
- package/dist/filesystem/index.d.ts +0 -11
- package/dist/filesystem/index.d.ts.map +0 -1
- package/dist/filesystem/index.js +0 -11
- package/dist/filesystem/path-validator.cjs +0 -250
- package/dist/filesystem/path-validator.d.ts +0 -103
- package/dist/filesystem/path-validator.d.ts.map +0 -1
- package/dist/filesystem/path-validator.js +0 -217
- package/dist/filesystem/types.cjs +0 -16
- package/dist/filesystem/types.d.ts +0 -175
- package/dist/filesystem/types.d.ts.map +0 -1
- package/dist/filesystem/types.js +0 -0
- package/dist/process/command-validator.cjs +0 -554
- package/dist/process/command-validator.d.ts +0 -49
- package/dist/process/command-validator.d.ts.map +0 -1
- package/dist/process/command-validator.js +0 -531
- package/dist/process/error-codes.cjs +0 -47
- package/dist/process/error-codes.d.ts +0 -25
- package/dist/process/error-codes.d.ts.map +0 -1
- package/dist/process/error-codes.js +0 -24
- package/dist/process/errors.cjs +0 -244
- package/dist/process/errors.d.ts +0 -87
- package/dist/process/errors.d.ts.map +0 -1
- package/dist/process/errors.js +0 -221
- package/dist/process/index.cjs +0 -37
- package/dist/process/index.d.ts +0 -11
- package/dist/process/index.d.ts.map +0 -1
- package/dist/process/index.js +0 -11
- package/dist/process/process-service.cjs +0 -497
- package/dist/process/process-service.d.ts +0 -69
- package/dist/process/process-service.d.ts.map +0 -1
- package/dist/process/process-service.js +0 -464
- package/dist/process/types.cjs +0 -16
- package/dist/process/types.d.ts +0 -107
- package/dist/process/types.d.ts.map +0 -1
- package/dist/process/types.js +0 -0
|
@@ -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) {
|
|
@@ -57,11 +58,13 @@ class TurnExecutor {
|
|
|
57
58
|
approvalMetadata = /* @__PURE__ */ new Map();
|
|
58
59
|
/**
|
|
59
60
|
* Get StreamProcessor config from TurnExecutor state.
|
|
61
|
+
* @param estimatedInputTokens Optional estimated input tokens for analytics
|
|
60
62
|
*/
|
|
61
|
-
getStreamProcessorConfig() {
|
|
63
|
+
getStreamProcessorConfig(estimatedInputTokens) {
|
|
62
64
|
return {
|
|
63
65
|
provider: this.llmContext.provider,
|
|
64
|
-
model: this.llmContext.model
|
|
66
|
+
model: this.llmContext.model,
|
|
67
|
+
...estimatedInputTokens !== void 0 && { estimatedInputTokens }
|
|
65
68
|
};
|
|
66
69
|
}
|
|
67
70
|
/**
|
|
@@ -117,13 +120,41 @@ class TurnExecutor {
|
|
|
117
120
|
if (coalesced) {
|
|
118
121
|
await this.injectQueuedMessages(coalesced);
|
|
119
122
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
const prepared = await this.contextManager.getFormattedMessagesWithCompression(
|
|
123
|
+
await this.pruneOldToolOutputs();
|
|
124
|
+
let prepared = await this.contextManager.getFormattedMessagesForLLM(
|
|
124
125
|
contributorContext,
|
|
125
126
|
this.llmContext
|
|
126
127
|
);
|
|
128
|
+
const toolDefinitions = supportsTools ? await this.toolManager.getAllTools() : {};
|
|
129
|
+
let estimatedTokens = await this.contextManager.getEstimatedNextInputTokens(
|
|
130
|
+
prepared.systemPrompt,
|
|
131
|
+
prepared.preparedHistory,
|
|
132
|
+
toolDefinitions
|
|
133
|
+
);
|
|
134
|
+
if (this.shouldCompact(estimatedTokens)) {
|
|
135
|
+
this.logger.debug(
|
|
136
|
+
`Pre-check: estimated ${estimatedTokens} tokens exceeds threshold, compacting`
|
|
137
|
+
);
|
|
138
|
+
const didCompact = await this.compactContext(
|
|
139
|
+
estimatedTokens,
|
|
140
|
+
contributorContext,
|
|
141
|
+
toolDefinitions
|
|
142
|
+
);
|
|
143
|
+
if (didCompact) {
|
|
144
|
+
prepared = await this.contextManager.getFormattedMessagesForLLM(
|
|
145
|
+
contributorContext,
|
|
146
|
+
this.llmContext
|
|
147
|
+
);
|
|
148
|
+
estimatedTokens = await this.contextManager.getEstimatedNextInputTokens(
|
|
149
|
+
prepared.systemPrompt,
|
|
150
|
+
prepared.preparedHistory,
|
|
151
|
+
toolDefinitions
|
|
152
|
+
);
|
|
153
|
+
this.logger.debug(
|
|
154
|
+
`Post-compaction: recomputed estimate is ${estimatedTokens} tokens`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
127
158
|
this.logger.debug(`Step ${stepCount}: Starting`);
|
|
128
159
|
const tools = supportsTools ? await this.createTools() : {};
|
|
129
160
|
const streamProcessor = new StreamProcessor(
|
|
@@ -131,7 +162,7 @@ class TurnExecutor {
|
|
|
131
162
|
this.eventBus,
|
|
132
163
|
this.resourceManager,
|
|
133
164
|
this.stepAbortController.signal,
|
|
134
|
-
this.getStreamProcessorConfig(),
|
|
165
|
+
this.getStreamProcessorConfig(estimatedTokens),
|
|
135
166
|
this.logger,
|
|
136
167
|
streaming,
|
|
137
168
|
this.approvalMetadata
|
|
@@ -170,6 +201,35 @@ class TurnExecutor {
|
|
|
170
201
|
this.logger.debug(
|
|
171
202
|
`Step ${stepCount}: Finished with reason="${result.finishReason}", tokens=${JSON.stringify(result.usage)}`
|
|
172
203
|
);
|
|
204
|
+
if (result.finishReason === "cancelled") {
|
|
205
|
+
this.logger.info(
|
|
206
|
+
`Context estimation (cancelled): keeping last known actuals, partial response (${result.text.length} chars) will be estimated`
|
|
207
|
+
);
|
|
208
|
+
} else if (result.usage?.inputTokens !== void 0) {
|
|
209
|
+
const contextInputTokens2 = this.getContextInputTokens(result.usage);
|
|
210
|
+
const actualInputTokens = contextInputTokens2 ?? result.usage.inputTokens;
|
|
211
|
+
const diff = estimatedTokens - actualInputTokens;
|
|
212
|
+
const diffPercent = actualInputTokens > 0 ? (diff / actualInputTokens * 100).toFixed(1) : "0.0";
|
|
213
|
+
this.logger.info(
|
|
214
|
+
`Context estimation accuracy: estimated=${estimatedTokens}, actual=${actualInputTokens}, error=${diff} (${diffPercent}%)`
|
|
215
|
+
);
|
|
216
|
+
this.contextManager.setLastActualInputTokens(actualInputTokens);
|
|
217
|
+
if (result.usage?.outputTokens !== void 0) {
|
|
218
|
+
this.contextManager.setLastActualOutputTokens(result.usage.outputTokens);
|
|
219
|
+
}
|
|
220
|
+
await this.contextManager.recordLastCallMessageCount();
|
|
221
|
+
}
|
|
222
|
+
const contextInputTokens = result.usage ? this.getContextInputTokens(result.usage) : null;
|
|
223
|
+
if (contextInputTokens && this.shouldCompactFromActual(contextInputTokens)) {
|
|
224
|
+
this.logger.debug(
|
|
225
|
+
`Post-response: actual ${contextInputTokens} tokens exceeds threshold, compacting`
|
|
226
|
+
);
|
|
227
|
+
await this.compactContext(
|
|
228
|
+
contextInputTokens,
|
|
229
|
+
contributorContext,
|
|
230
|
+
toolDefinitions
|
|
231
|
+
);
|
|
232
|
+
}
|
|
173
233
|
if (result.finishReason !== "tool-calls") {
|
|
174
234
|
const queuedOnTerminate = this.messageQueue.dequeueAll();
|
|
175
235
|
if (queuedOnTerminate) {
|
|
@@ -193,7 +253,6 @@ class TurnExecutor {
|
|
|
193
253
|
lastFinishReason = "max-steps";
|
|
194
254
|
break;
|
|
195
255
|
}
|
|
196
|
-
await this.pruneOldToolOutputs();
|
|
197
256
|
}
|
|
198
257
|
} catch (error) {
|
|
199
258
|
const mappedError = this.mapProviderError(error);
|
|
@@ -521,7 +580,7 @@ class TurnExecutor {
|
|
|
521
580
|
/**
|
|
522
581
|
* Prunes old tool outputs by marking them with compactedAt timestamp.
|
|
523
582
|
* Does NOT modify content - transformation happens at format time in
|
|
524
|
-
* ContextManager.
|
|
583
|
+
* ContextManager.prepareHistory().
|
|
525
584
|
*
|
|
526
585
|
* Algorithm:
|
|
527
586
|
* 1. Go backwards through history (most recent first)
|
|
@@ -590,54 +649,108 @@ class TurnExecutor {
|
|
|
590
649
|
this.messageQueue.clear();
|
|
591
650
|
}
|
|
592
651
|
/**
|
|
593
|
-
* Check if context
|
|
652
|
+
* Check if context should be compacted based on estimated token count.
|
|
653
|
+
* Uses the threshold percentage from compaction config to trigger earlier (e.g., at 90%).
|
|
654
|
+
*
|
|
655
|
+
* @param estimatedTokens Estimated token count from the current context
|
|
656
|
+
* @returns true if compaction is needed before making the LLM call
|
|
594
657
|
*/
|
|
595
|
-
|
|
658
|
+
shouldCompact(estimatedTokens) {
|
|
596
659
|
if (!this.modelLimits || !this.compactionStrategy) {
|
|
597
660
|
return false;
|
|
598
661
|
}
|
|
599
|
-
return isOverflow(
|
|
662
|
+
return isOverflow(
|
|
663
|
+
{ inputTokens: estimatedTokens },
|
|
664
|
+
this.modelLimits,
|
|
665
|
+
this.compactionThresholdPercent
|
|
666
|
+
);
|
|
600
667
|
}
|
|
601
668
|
/**
|
|
602
|
-
*
|
|
669
|
+
* Check if context should be compacted based on actual token count from API response.
|
|
670
|
+
* This is a post-response check using real token counts rather than estimates.
|
|
603
671
|
*
|
|
604
|
-
*
|
|
605
|
-
*
|
|
606
|
-
|
|
672
|
+
* @param actualTokens Actual input token count from the API response
|
|
673
|
+
* @returns true if compaction is needed
|
|
674
|
+
*/
|
|
675
|
+
shouldCompactFromActual(actualTokens) {
|
|
676
|
+
if (!this.modelLimits || !this.compactionStrategy) {
|
|
677
|
+
return false;
|
|
678
|
+
}
|
|
679
|
+
return isOverflow(
|
|
680
|
+
{ inputTokens: actualTokens },
|
|
681
|
+
this.modelLimits,
|
|
682
|
+
this.compactionThresholdPercent
|
|
683
|
+
);
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Compact context by generating a summary and adding it to the same session.
|
|
687
|
+
*
|
|
688
|
+
* The summary message is added to the conversation history with `isSummary: true` metadata.
|
|
689
|
+
* When the context is loaded via getFormattedMessagesForLLM(), filterCompacted() will
|
|
690
|
+
* exclude all messages before the summary, effectively compacting the context.
|
|
607
691
|
*
|
|
608
|
-
* @param originalTokens The
|
|
692
|
+
* @param originalTokens The estimated input token count that triggered overflow
|
|
693
|
+
* @param contributorContext Context for system prompt contributors (needed for accurate token estimation)
|
|
694
|
+
* @param tools Tool definitions (needed for accurate token estimation)
|
|
695
|
+
* @returns true if compaction occurred, false if skipped
|
|
609
696
|
*/
|
|
610
|
-
async
|
|
697
|
+
async compactContext(originalTokens, contributorContext, tools) {
|
|
611
698
|
if (!this.compactionStrategy) {
|
|
612
|
-
return;
|
|
699
|
+
return false;
|
|
613
700
|
}
|
|
614
701
|
this.logger.info(
|
|
615
|
-
`Context overflow detected (${originalTokens} tokens),
|
|
702
|
+
`Context overflow detected (${originalTokens} tokens), checking if compression is possible`
|
|
616
703
|
);
|
|
617
704
|
const history = await this.contextManager.getHistory();
|
|
705
|
+
const { filterCompacted } = await import("../../context/utils.js");
|
|
706
|
+
const originalFiltered = filterCompacted(history);
|
|
707
|
+
const originalMessages = originalFiltered.length;
|
|
708
|
+
if (history.length < 4) {
|
|
709
|
+
this.logger.debug("Compaction skipped: history too short to summarize");
|
|
710
|
+
return false;
|
|
711
|
+
}
|
|
712
|
+
this.eventBus.emit("context:compacting", {
|
|
713
|
+
estimatedTokens: originalTokens
|
|
714
|
+
});
|
|
618
715
|
const summaryMessages = await this.compactionStrategy.compact(history);
|
|
619
716
|
if (summaryMessages.length === 0) {
|
|
620
|
-
this.logger.debug(
|
|
621
|
-
|
|
717
|
+
this.logger.debug(
|
|
718
|
+
"Compaction skipped: strategy returned no summary (likely already compacted or nothing to summarize)"
|
|
719
|
+
);
|
|
720
|
+
this.eventBus.emit("context:compacted", {
|
|
721
|
+
originalTokens,
|
|
722
|
+
compactedTokens: originalTokens,
|
|
723
|
+
// No change
|
|
724
|
+
originalMessages,
|
|
725
|
+
compactedMessages: originalMessages,
|
|
726
|
+
// No change
|
|
727
|
+
strategy: this.compactionStrategy.name,
|
|
728
|
+
reason: "overflow"
|
|
729
|
+
});
|
|
730
|
+
return false;
|
|
622
731
|
}
|
|
623
732
|
for (const summary of summaryMessages) {
|
|
624
733
|
await this.contextManager.addMessage(summary);
|
|
625
734
|
}
|
|
626
|
-
|
|
627
|
-
const
|
|
628
|
-
|
|
629
|
-
|
|
735
|
+
this.contextManager.resetActualTokenTracking();
|
|
736
|
+
const afterEstimate = await this.contextManager.getContextTokenEstimate(
|
|
737
|
+
contributorContext,
|
|
738
|
+
tools
|
|
739
|
+
);
|
|
740
|
+
const compactedTokens = afterEstimate.estimated;
|
|
741
|
+
const compactedMessages = afterEstimate.stats.filteredMessageCount;
|
|
630
742
|
this.eventBus.emit("context:compacted", {
|
|
631
743
|
originalTokens,
|
|
632
744
|
compactedTokens,
|
|
633
|
-
originalMessages
|
|
634
|
-
compactedMessages
|
|
745
|
+
originalMessages,
|
|
746
|
+
compactedMessages,
|
|
635
747
|
strategy: this.compactionStrategy.name,
|
|
636
748
|
reason: "overflow"
|
|
637
749
|
});
|
|
638
750
|
this.logger.info(
|
|
639
|
-
`Compaction complete: ${originalTokens} \u2192 ~${compactedTokens} tokens (${
|
|
751
|
+
`Compaction complete: ${originalTokens} \u2192 ~${compactedTokens} tokens (${originalMessages} \u2192 ${compactedMessages} messages after filtering)`
|
|
640
752
|
);
|
|
753
|
+
return true;
|
|
641
754
|
}
|
|
642
755
|
/**
|
|
643
756
|
* Set telemetry span attributes for token usage.
|
|
@@ -660,6 +773,10 @@ class TurnExecutor {
|
|
|
660
773
|
activeSpan.setAttribute("gen_ai.usage.reasoning_tokens", usage.reasoningTokens);
|
|
661
774
|
}
|
|
662
775
|
}
|
|
776
|
+
getContextInputTokens(usage) {
|
|
777
|
+
if (usage.inputTokens === void 0) return null;
|
|
778
|
+
return usage.inputTokens + (usage.cacheReadTokens ?? 0) + (usage.cacheWriteTokens ?? 0);
|
|
779
|
+
}
|
|
663
780
|
/**
|
|
664
781
|
* Map provider errors to DextoRuntimeError.
|
|
665
782
|
*/
|
|
@@ -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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
|
206
|
-
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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:
|
|
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;
|
|
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
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
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
|
|
184
|
-
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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:
|
|
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;
|
|
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 {
|
|
@@ -92,13 +92,15 @@ class VercelLLMService {
|
|
|
92
92
|
resourceManager;
|
|
93
93
|
messageQueue;
|
|
94
94
|
compactionStrategy;
|
|
95
|
+
modelLimits;
|
|
96
|
+
compactionThresholdPercent;
|
|
95
97
|
/**
|
|
96
98
|
* Helper to extract model ID from LanguageModel union type (string | LanguageModelV2)
|
|
97
99
|
*/
|
|
98
100
|
getModelId() {
|
|
99
101
|
return typeof this.model === "string" ? this.model : this.model.modelId;
|
|
100
102
|
}
|
|
101
|
-
constructor(toolManager, model, systemPromptManager, historyProvider, sessionEventBus, config, sessionId, resourceManager, logger, compactionStrategy) {
|
|
103
|
+
constructor(toolManager, model, systemPromptManager, historyProvider, sessionEventBus, config, sessionId, resourceManager, logger, compactionStrategy, compactionConfig) {
|
|
102
104
|
this.logger = logger.createChild(import_types2.DextoLogComponent.LLM);
|
|
103
105
|
this.model = model;
|
|
104
106
|
this.config = config;
|
|
@@ -107,9 +109,20 @@ class VercelLLMService {
|
|
|
107
109
|
this.sessionId = sessionId;
|
|
108
110
|
this.resourceManager = resourceManager;
|
|
109
111
|
this.compactionStrategy = compactionStrategy ?? null;
|
|
112
|
+
this.compactionThresholdPercent = compactionConfig?.thresholdPercent ?? 0.9;
|
|
110
113
|
this.messageQueue = new import_message_queue.MessageQueueService(this.sessionEventBus, this.logger);
|
|
111
114
|
const formatter = new import_vercel.VercelMessageFormatter(this.logger);
|
|
112
115
|
const maxInputTokens = (0, import_registry.getEffectiveMaxInputTokens)(config, this.logger);
|
|
116
|
+
let effectiveContextWindow = maxInputTokens;
|
|
117
|
+
if (compactionConfig?.maxContextTokens !== void 0) {
|
|
118
|
+
effectiveContextWindow = Math.min(maxInputTokens, compactionConfig.maxContextTokens);
|
|
119
|
+
this.logger.debug(
|
|
120
|
+
`Compaction: Using maxContextTokens override: ${compactionConfig.maxContextTokens} (model max: ${maxInputTokens})`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
this.modelLimits = {
|
|
124
|
+
contextWindow: effectiveContextWindow
|
|
125
|
+
};
|
|
113
126
|
this.contextManager = new import_manager.ContextManager(
|
|
114
127
|
config,
|
|
115
128
|
formatter,
|
|
@@ -149,19 +162,23 @@ class VercelLLMService {
|
|
|
149
162
|
{ provider: this.config.provider, model: this.getModelId() },
|
|
150
163
|
this.logger,
|
|
151
164
|
this.messageQueue,
|
|
152
|
-
|
|
153
|
-
// modelLimits - TurnExecutor will use defaults
|
|
165
|
+
this.modelLimits,
|
|
154
166
|
externalSignal,
|
|
155
|
-
this.compactionStrategy
|
|
167
|
+
this.compactionStrategy,
|
|
168
|
+
this.compactionThresholdPercent
|
|
156
169
|
);
|
|
157
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Result from streaming a response.
|
|
173
|
+
*/
|
|
174
|
+
static StreamResult;
|
|
158
175
|
/**
|
|
159
176
|
* Stream a response for the given content.
|
|
160
177
|
* Primary method for running conversations with multi-image support.
|
|
161
178
|
*
|
|
162
179
|
* @param content - String or ContentPart[] (text, images, files)
|
|
163
180
|
* @param options - { signal?: AbortSignal }
|
|
164
|
-
* @returns
|
|
181
|
+
* @returns Object with text response
|
|
165
182
|
*/
|
|
166
183
|
async stream(content, options) {
|
|
167
184
|
const activeSpan = import_api.trace.getActiveSpan();
|
|
@@ -191,7 +208,9 @@ class VercelLLMService {
|
|
|
191
208
|
const executor = this.createTurnExecutor(options?.signal);
|
|
192
209
|
const contributorContext = { mcpManager: this.toolManager.getMcpManager() };
|
|
193
210
|
const result = await executor.execute(contributorContext, true);
|
|
194
|
-
return
|
|
211
|
+
return {
|
|
212
|
+
text: result.text ?? ""
|
|
213
|
+
};
|
|
195
214
|
});
|
|
196
215
|
}
|
|
197
216
|
/**
|
|
@@ -236,6 +255,12 @@ class VercelLLMService {
|
|
|
236
255
|
getMessageQueue() {
|
|
237
256
|
return this.messageQueue;
|
|
238
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Get the compaction strategy for external access (e.g., session-native compaction)
|
|
260
|
+
*/
|
|
261
|
+
getCompactionStrategy() {
|
|
262
|
+
return this.compactionStrategy;
|
|
263
|
+
}
|
|
239
264
|
}
|
|
240
265
|
_init = __decoratorStart(null);
|
|
241
266
|
VercelLLMService = __decorateElement(_init, 0, "VercelLLMService", _VercelLLMService_decorators, VercelLLMService);
|