@librechat/agents 3.6.10 → 3.6.12
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/cjs/agents/AgentContext.cjs +63 -10
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +48 -119
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/llm/contextPressureMeter.cjs +132 -0
- package/dist/cjs/llm/contextPressureMeter.cjs.map +1 -0
- package/dist/cjs/llm/invoke.cjs +46 -75
- package/dist/cjs/llm/invoke.cjs.map +1 -1
- package/dist/cjs/llm/prepareProviderRequest.cjs +108 -0
- package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -0
- package/dist/cjs/main.cjs +4 -0
- package/dist/cjs/messages/content.cjs +5 -4
- package/dist/cjs/messages/content.cjs.map +1 -1
- package/dist/cjs/stream.cjs +1 -0
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/CallerCapabilities.cjs +31 -0
- package/dist/cjs/tools/CallerCapabilities.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +23 -6
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +26 -2
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +65 -12
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +51 -122
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/llm/contextPressureMeter.mjs +132 -0
- package/dist/esm/llm/contextPressureMeter.mjs.map +1 -0
- package/dist/esm/llm/invoke.mjs +48 -75
- package/dist/esm/llm/invoke.mjs.map +1 -1
- package/dist/esm/llm/prepareProviderRequest.mjs +105 -0
- package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -0
- package/dist/esm/main.mjs +3 -2
- package/dist/esm/messages/content.mjs +5 -4
- package/dist/esm/messages/content.mjs.map +1 -1
- package/dist/esm/stream.mjs +1 -0
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/CallerCapabilities.mjs +29 -1
- package/dist/esm/tools/CallerCapabilities.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +24 -7
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +26 -4
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +11 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/llm/contextPressureMeter.d.ts +30 -0
- package/dist/types/llm/invoke.d.ts +31 -33
- package/dist/types/llm/prepareProviderRequest.d.ts +55 -0
- package/dist/types/tools/CallerCapabilities.d.ts +13 -0
- package/dist/types/tools/ToolNode.d.ts +9 -1
- package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +6 -0
- package/dist/types/types/tools.d.ts +17 -0
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +157 -15
- package/src/graphs/Graph.ts +75 -279
- package/src/index.ts +8 -0
- package/src/llm/contextPressureMeter.ts +284 -0
- package/src/llm/invoke.ts +136 -296
- package/src/llm/prepareProviderRequest.ts +357 -0
- package/src/messages/content.ts +3 -3
- package/src/stream.ts +6 -0
- package/src/tools/CallerCapabilities.ts +68 -0
- package/src/tools/ToolNode.ts +47 -4
- package/src/tools/local/resolveLocalExecutionTools.ts +77 -3
- package/src/types/tools.ts +18 -0
package/src/graphs/Graph.ts
CHANGED
|
@@ -50,8 +50,8 @@ import {
|
|
|
50
50
|
addBedrockTailCacheControl,
|
|
51
51
|
projectArtifactPayload,
|
|
52
52
|
formatContentStrings,
|
|
53
|
+
cloneMessage,
|
|
53
54
|
CALIBRATION_RATIO_MAX,
|
|
54
|
-
REPLY_PRIMER_TOKENS,
|
|
55
55
|
createPruneMessages,
|
|
56
56
|
projectToolCallInputs,
|
|
57
57
|
calculateMaxToolCallInputChars,
|
|
@@ -74,7 +74,6 @@ import {
|
|
|
74
74
|
coalesceAdjacentUserTurns,
|
|
75
75
|
strictAlternationProviders,
|
|
76
76
|
appendPredecessorHandoffCue,
|
|
77
|
-
removePredecessorHandoffCue,
|
|
78
77
|
stampSyntheticProviderMessage,
|
|
79
78
|
} from '@/messages';
|
|
80
79
|
import {
|
|
@@ -104,9 +103,9 @@ import {
|
|
|
104
103
|
tryFallbackProviders,
|
|
105
104
|
getFallbackErrorContext,
|
|
106
105
|
getFallbackOverflowCandidates,
|
|
107
|
-
projectMessagesForProvider,
|
|
108
|
-
resolveServingModelId,
|
|
109
106
|
} from '@/llm/invoke';
|
|
107
|
+
import { prepareProviderRequest } from '@/llm/prepareProviderRequest';
|
|
108
|
+
import { createContextPressureMeter } from '@/llm/contextPressureMeter';
|
|
110
109
|
import {
|
|
111
110
|
resolveStreamLimits,
|
|
112
111
|
StreamLimitExceededError,
|
|
@@ -2868,6 +2867,9 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
2868
2867
|
* the breakpoint and don't invalidate the prefix.
|
|
2869
2868
|
*/
|
|
2870
2869
|
let toolsForBinding = rawToolsForBinding;
|
|
2870
|
+
const isDeferredTool = makeIsDeferred(
|
|
2871
|
+
agentContext.getEffectiveToolDefinitions()
|
|
2872
|
+
);
|
|
2871
2873
|
if (
|
|
2872
2874
|
agentContext.provider === Providers.ANTHROPIC &&
|
|
2873
2875
|
(agentContext.clientOptions as t.AnthropicClientOptions | undefined)
|
|
@@ -2876,7 +2878,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
2876
2878
|
toolsForBinding =
|
|
2877
2879
|
partitionAndMarkAnthropicToolCache(
|
|
2878
2880
|
rawToolsForBinding,
|
|
2879
|
-
|
|
2881
|
+
isDeferredTool,
|
|
2880
2882
|
resolvePromptCacheTtl(
|
|
2881
2883
|
(
|
|
2882
2884
|
agentContext.clientOptions as
|
|
@@ -2896,7 +2898,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
2896
2898
|
toolsForBinding =
|
|
2897
2899
|
partitionAndMarkOpenRouterToolCache(
|
|
2898
2900
|
rawToolsForBinding,
|
|
2899
|
-
|
|
2901
|
+
isDeferredTool,
|
|
2900
2902
|
resolvePromptCacheTtl(
|
|
2901
2903
|
(
|
|
2902
2904
|
agentContext.clientOptions as
|
|
@@ -2923,7 +2925,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
2923
2925
|
toolsForBinding =
|
|
2924
2926
|
partitionAndMarkBedrockToolCache(
|
|
2925
2927
|
rawToolsForBinding,
|
|
2926
|
-
|
|
2928
|
+
isDeferredTool
|
|
2927
2929
|
) ?? rawToolsForBinding;
|
|
2928
2930
|
}
|
|
2929
2931
|
}
|
|
@@ -3151,105 +3153,18 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
3151
3153
|
* baseline, then attribute it across retained messages. Provider
|
|
3152
3154
|
* transforms can shrink one message while expanding or adding another;
|
|
3153
3155
|
* per-origin accounting prevents that unrelated shrink from canceling
|
|
3154
|
-
* the expansion.
|
|
3155
|
-
*/
|
|
3156
|
-
let providerMessageBaseline:
|
|
3157
|
-
| Array<{ rawTokens: number; accountingWeight: number }>
|
|
3158
|
-
| undefined;
|
|
3159
|
-
const providerMessageOrigins = new WeakMap<BaseMessage, number>();
|
|
3160
|
-
if (contextUsage != null && agentContext.tokenCounter != null) {
|
|
3161
|
-
const sourceIndices = new WeakMap<BaseMessage, number>();
|
|
3162
|
-
for (let i = 0; i < messages.length; i++) {
|
|
3163
|
-
sourceIndices.set(messages[i], i);
|
|
3164
|
-
}
|
|
3165
|
-
providerMessageBaseline = messagesToUse.map((message, index) => {
|
|
3166
|
-
const rawTokens = agentContext.tokenCounter!(message);
|
|
3167
|
-
const sourceIndex = sourceIndices.get(message);
|
|
3168
|
-
const indexedTokens =
|
|
3169
|
-
sourceIndex != null
|
|
3170
|
-
? agentContext.indexTokenCountMap[sourceIndex]
|
|
3171
|
-
: undefined;
|
|
3172
|
-
const accountingWeight =
|
|
3173
|
-
indexedTokens != null &&
|
|
3174
|
-
Number.isFinite(indexedTokens) &&
|
|
3175
|
-
indexedTokens >= 0
|
|
3176
|
-
? indexedTokens
|
|
3177
|
-
: rawTokens;
|
|
3178
|
-
if (!providerMessageOrigins.has(message)) {
|
|
3179
|
-
providerMessageOrigins.set(message, index);
|
|
3180
|
-
}
|
|
3181
|
-
return { rawTokens, accountingWeight };
|
|
3182
|
-
});
|
|
3183
|
-
}
|
|
3184
|
-
|
|
3185
|
-
const getProviderMessageOriginKey = (
|
|
3186
|
-
message: BaseMessage
|
|
3187
|
-
): string | undefined => {
|
|
3188
|
-
const type = message.getType();
|
|
3189
|
-
if (
|
|
3190
|
-
message instanceof ToolMessage &&
|
|
3191
|
-
typeof message.tool_call_id === 'string' &&
|
|
3192
|
-
message.tool_call_id.length > 0
|
|
3193
|
-
) {
|
|
3194
|
-
return `tool:call:${message.tool_call_id}`;
|
|
3195
|
-
}
|
|
3196
|
-
if (typeof message.id === 'string' && message.id.length > 0) {
|
|
3197
|
-
return `${type}:id:${message.id}`;
|
|
3198
|
-
}
|
|
3199
|
-
return undefined;
|
|
3200
|
-
};
|
|
3201
|
-
|
|
3202
|
-
/**
|
|
3203
|
-
* Provider projections clone messages. Preserve their baseline origin
|
|
3204
|
-
* without writing tracking metadata onto the wire. Synthetic fold
|
|
3205
|
-
* messages intentionally remain unattributed and are charged in full.
|
|
3156
|
+
* the expansion. Exact counts are memoized across repeated projections.
|
|
3206
3157
|
*/
|
|
3207
|
-
const
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
if (
|
|
3218
|
-
origin != null &&
|
|
3219
|
-
!providerMessageOrigins.has(after[i]) &&
|
|
3220
|
-
before[i].getType() === after[i].getType() &&
|
|
3221
|
-
!isSyntheticProviderContextMessage(after[i])
|
|
3222
|
-
) {
|
|
3223
|
-
providerMessageOrigins.set(after[i], origin);
|
|
3224
|
-
}
|
|
3225
|
-
}
|
|
3226
|
-
return after;
|
|
3227
|
-
}
|
|
3228
|
-
|
|
3229
|
-
const keyedOrigins = new Map<string, number | null>();
|
|
3230
|
-
for (const message of before) {
|
|
3231
|
-
const origin = providerMessageOrigins.get(message);
|
|
3232
|
-
const key = getProviderMessageOriginKey(message);
|
|
3233
|
-
if (origin == null || key == null) {
|
|
3234
|
-
continue;
|
|
3235
|
-
}
|
|
3236
|
-
keyedOrigins.set(key, keyedOrigins.has(key) ? null : origin);
|
|
3237
|
-
}
|
|
3238
|
-
for (const message of after) {
|
|
3239
|
-
if (
|
|
3240
|
-
providerMessageOrigins.has(message) ||
|
|
3241
|
-
isSyntheticProviderContextMessage(message)
|
|
3242
|
-
) {
|
|
3243
|
-
continue;
|
|
3244
|
-
}
|
|
3245
|
-
const key = getProviderMessageOriginKey(message);
|
|
3246
|
-
const origin = key != null ? keyedOrigins.get(key) : undefined;
|
|
3247
|
-
if (origin != null) {
|
|
3248
|
-
providerMessageOrigins.set(message, origin);
|
|
3249
|
-
}
|
|
3250
|
-
}
|
|
3251
|
-
return after;
|
|
3252
|
-
};
|
|
3158
|
+
const contextPressure = createContextPressureMeter({
|
|
3159
|
+
tokenCounter: agentContext.tokenCounter,
|
|
3160
|
+
sourceMessages: messages,
|
|
3161
|
+
retainedMessages: messagesToUse,
|
|
3162
|
+
indexTokenCountMap: agentContext.indexTokenCountMap,
|
|
3163
|
+
contextUsage,
|
|
3164
|
+
instructionTokens: agentContext.instructionTokens,
|
|
3165
|
+
calibrationRatio: agentContext.calibrationRatio,
|
|
3166
|
+
});
|
|
3167
|
+
const trackProviderMessageOrigins = contextPressure.trackProjection;
|
|
3253
3168
|
|
|
3254
3169
|
if (agentContext.useLegacyContent) {
|
|
3255
3170
|
const before = finalMessages;
|
|
@@ -3297,8 +3212,13 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
3297
3212
|
typeof lastMessageX.content === 'string'
|
|
3298
3213
|
) {
|
|
3299
3214
|
const trimmed = lastMessageX.content.trim();
|
|
3300
|
-
|
|
3301
|
-
|
|
3215
|
+
const before = finalMessages;
|
|
3216
|
+
finalMessages = [...before];
|
|
3217
|
+
finalMessages[finalMessages.length - 2] = cloneMessage(
|
|
3218
|
+
lastMessageX,
|
|
3219
|
+
trimmed.length > 0 ? [{ type: 'text' as const, text: trimmed }] : ''
|
|
3220
|
+
);
|
|
3221
|
+
finalMessages = trackProviderMessageOrigins(before, finalMessages);
|
|
3302
3222
|
}
|
|
3303
3223
|
|
|
3304
3224
|
const localProviderOverflowMeasurements = new WeakMap<
|
|
@@ -3308,123 +3228,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
3308
3228
|
estimatedPromptTokens: number;
|
|
3309
3229
|
}
|
|
3310
3230
|
>();
|
|
3311
|
-
const measureProviderPayload =
|
|
3312
|
-
candidate: BaseMessage[],
|
|
3313
|
-
contextBudgetOverride?: number,
|
|
3314
|
-
forceRawRecount = false
|
|
3315
|
-
): {
|
|
3316
|
-
fits: boolean;
|
|
3317
|
-
projectedMessageTokens?: number;
|
|
3318
|
-
availableMessageTokens?: number;
|
|
3319
|
-
contextBudget?: number;
|
|
3320
|
-
effectiveInstructionTokens?: number;
|
|
3321
|
-
} => {
|
|
3322
|
-
const contextBudget =
|
|
3323
|
-
contextBudgetOverride ?? contextUsage?.contextBudget;
|
|
3324
|
-
const effectiveInstructionTokens =
|
|
3325
|
-
contextUsage?.effectiveInstructionTokens ??
|
|
3326
|
-
(forceRawRecount ? agentContext.instructionTokens : undefined);
|
|
3327
|
-
if (
|
|
3328
|
-
agentContext.tokenCounter == null ||
|
|
3329
|
-
contextBudget == null ||
|
|
3330
|
-
effectiveInstructionTokens == null
|
|
3331
|
-
) {
|
|
3332
|
-
return { fits: true };
|
|
3333
|
-
}
|
|
3334
|
-
const availableMessageTokens = Math.max(
|
|
3335
|
-
0,
|
|
3336
|
-
contextBudget - effectiveInstructionTokens
|
|
3337
|
-
);
|
|
3338
|
-
let usageRatio =
|
|
3339
|
-
agentContext.calibrationRatio > 0 ? agentContext.calibrationRatio : 1;
|
|
3340
|
-
if (
|
|
3341
|
-
contextUsage?.calibrationRatio != null &&
|
|
3342
|
-
contextUsage.calibrationRatio > 0
|
|
3343
|
-
) {
|
|
3344
|
-
usageRatio = contextUsage.calibrationRatio;
|
|
3345
|
-
}
|
|
3346
|
-
if (forceRawRecount) {
|
|
3347
|
-
usageRatio = Math.max(1, usageRatio);
|
|
3348
|
-
}
|
|
3349
|
-
const baselineRemaining = contextUsage?.remainingContextTokens;
|
|
3350
|
-
const accountedMessageTokens =
|
|
3351
|
-
!forceRawRecount &&
|
|
3352
|
-
providerMessageBaseline != null &&
|
|
3353
|
-
baselineRemaining != null &&
|
|
3354
|
-
Number.isFinite(baselineRemaining)
|
|
3355
|
-
? availableMessageTokens -
|
|
3356
|
-
Math.min(availableMessageTokens, Math.max(0, baselineRemaining))
|
|
3357
|
-
: undefined;
|
|
3358
|
-
|
|
3359
|
-
let projectedMessageTokens: number;
|
|
3360
|
-
if (accountedMessageTokens != null && providerMessageBaseline != null) {
|
|
3361
|
-
const replyPrimerTokens = Math.round(
|
|
3362
|
-
REPLY_PRIMER_TOKENS * usageRatio
|
|
3363
|
-
);
|
|
3364
|
-
const rawWeights: Record<string, number> = {};
|
|
3365
|
-
let totalWeight = 0;
|
|
3366
|
-
for (let i = 0; i < providerMessageBaseline.length; i++) {
|
|
3367
|
-
const weight = providerMessageBaseline[i].accountingWeight;
|
|
3368
|
-
rawWeights[i] = weight;
|
|
3369
|
-
totalWeight += weight;
|
|
3370
|
-
}
|
|
3371
|
-
const attributableTokens =
|
|
3372
|
-
totalWeight > 0
|
|
3373
|
-
? Math.min(
|
|
3374
|
-
Math.max(0, accountedMessageTokens - replyPrimerTokens),
|
|
3375
|
-
Math.round(totalWeight * usageRatio)
|
|
3376
|
-
)
|
|
3377
|
-
: 0;
|
|
3378
|
-
const apportionedTokens =
|
|
3379
|
-
totalWeight > 0
|
|
3380
|
-
? apportionTokenCounts(
|
|
3381
|
-
rawWeights,
|
|
3382
|
-
attributableTokens / totalWeight,
|
|
3383
|
-
attributableTokens
|
|
3384
|
-
)
|
|
3385
|
-
: {};
|
|
3386
|
-
const attributedByOrigin = providerMessageBaseline.map(
|
|
3387
|
-
(_, origin) => apportionedTokens[origin] || 0
|
|
3388
|
-
);
|
|
3389
|
-
projectedMessageTokens = Math.max(
|
|
3390
|
-
replyPrimerTokens,
|
|
3391
|
-
accountedMessageTokens - attributableTokens
|
|
3392
|
-
);
|
|
3393
|
-
let newRawTokens = 0;
|
|
3394
|
-
const usedOrigins = new Set<number>();
|
|
3395
|
-
for (const message of candidate) {
|
|
3396
|
-
const rawTokens = agentContext.tokenCounter(message);
|
|
3397
|
-
const origin = providerMessageOrigins.get(message);
|
|
3398
|
-
if (origin == null || usedOrigins.has(origin)) {
|
|
3399
|
-
newRawTokens += rawTokens;
|
|
3400
|
-
continue;
|
|
3401
|
-
}
|
|
3402
|
-
usedOrigins.add(origin);
|
|
3403
|
-
projectedMessageTokens += Math.max(
|
|
3404
|
-
0,
|
|
3405
|
-
attributedByOrigin[origin] +
|
|
3406
|
-
Math.round(
|
|
3407
|
-
(rawTokens - providerMessageBaseline[origin].rawTokens) *
|
|
3408
|
-
usageRatio
|
|
3409
|
-
)
|
|
3410
|
-
);
|
|
3411
|
-
}
|
|
3412
|
-
projectedMessageTokens += Math.round(newRawTokens * usageRatio);
|
|
3413
|
-
} else {
|
|
3414
|
-
let rawTokens = REPLY_PRIMER_TOKENS;
|
|
3415
|
-
for (const message of candidate) {
|
|
3416
|
-
rawTokens += agentContext.tokenCounter(message);
|
|
3417
|
-
}
|
|
3418
|
-
projectedMessageTokens = Math.round(rawTokens * usageRatio);
|
|
3419
|
-
}
|
|
3420
|
-
return {
|
|
3421
|
-
fits: projectedMessageTokens <= availableMessageTokens,
|
|
3422
|
-
projectedMessageTokens,
|
|
3423
|
-
availableMessageTokens,
|
|
3424
|
-
contextBudget,
|
|
3425
|
-
effectiveInstructionTokens,
|
|
3426
|
-
};
|
|
3427
|
-
};
|
|
3231
|
+
const measureProviderPayload = contextPressure.measure;
|
|
3428
3232
|
|
|
3429
3233
|
const createProviderPayloadOverflowError = ({
|
|
3430
3234
|
projection,
|
|
@@ -3779,10 +3583,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
3779
3583
|
finalMessages = trackProviderMessageOrigins(
|
|
3780
3584
|
beforeSanitizeMessages,
|
|
3781
3585
|
sanitizeOrphanToolBlocks(beforeSanitizeMessages, (source, clone) => {
|
|
3782
|
-
|
|
3783
|
-
if (origin != null) {
|
|
3784
|
-
providerMessageOrigins.set(clone, origin);
|
|
3785
|
-
}
|
|
3586
|
+
contextPressure.trackClone(source, clone);
|
|
3786
3587
|
})
|
|
3787
3588
|
);
|
|
3788
3589
|
if (finalMessages.length !== beforeSanitize) {
|
|
@@ -3855,23 +3656,30 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
3855
3656
|
|
|
3856
3657
|
const fallbackBaseMessages = finalMessages;
|
|
3857
3658
|
const beforeFinalProviderProjection = fallbackBaseMessages;
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3659
|
+
const preparedRequest = prepareProviderRequest({
|
|
3660
|
+
model: (this.overrideModel ?? model) as t.ChatModel,
|
|
3661
|
+
messages: beforeFinalProviderProjection,
|
|
3662
|
+
provider: agentContext.provider,
|
|
3663
|
+
context: this,
|
|
3664
|
+
config,
|
|
3665
|
+
maxToolResultChars: maxProviderToolResultChars,
|
|
3666
|
+
measure: (preparedMessages) =>
|
|
3667
|
+
measureProviderPayload(
|
|
3668
|
+
trackProviderMessageOrigins(
|
|
3669
|
+
beforeFinalProviderProjection,
|
|
3670
|
+
preparedMessages
|
|
3671
|
+
)
|
|
3672
|
+
),
|
|
3673
|
+
});
|
|
3674
|
+
finalMessages = preparedRequest.messages;
|
|
3868
3675
|
|
|
3869
3676
|
/**
|
|
3870
3677
|
* Prompt-cache placement and orphan sanitization are provider-wire
|
|
3871
3678
|
* transforms too. Re-measure after both so no content added after the
|
|
3872
3679
|
* earlier artifact/synthetic compaction decision can bypass the guard.
|
|
3873
3680
|
*/
|
|
3874
|
-
finalProjection =
|
|
3681
|
+
finalProjection =
|
|
3682
|
+
preparedRequest.measurement ?? measureProviderPayload(finalMessages);
|
|
3875
3683
|
const preInvokeContextOverflowError = !finalProjection.fits
|
|
3876
3684
|
? createProviderPayloadOverflowError({
|
|
3877
3685
|
projection: finalProjection,
|
|
@@ -4080,9 +3888,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4080
3888
|
() =>
|
|
4081
3889
|
attemptInvoke(
|
|
4082
3890
|
{
|
|
4083
|
-
|
|
4084
|
-
messages: finalMessages,
|
|
4085
|
-
provider: agentContext.provider,
|
|
3891
|
+
request: preparedRequest,
|
|
4086
3892
|
context: this,
|
|
4087
3893
|
},
|
|
4088
3894
|
invokeConfig
|
|
@@ -4285,7 +4091,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4285
4091
|
estimatedPromptTokens: getEstimatedPromptTokens(contextUsage),
|
|
4286
4092
|
maxContextTokens: agentContext.maxContextTokens,
|
|
4287
4093
|
},
|
|
4288
|
-
|
|
4094
|
+
prepareProviderRequest: ({
|
|
4289
4095
|
model: fallbackModel,
|
|
4290
4096
|
messages: fallbackMessages,
|
|
4291
4097
|
provider: fallbackProvider,
|
|
@@ -4297,36 +4103,6 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4297
4103
|
calculateMaxToolResultChars(
|
|
4298
4104
|
fallbackMaxContextTokens ?? agentContext.maxContextTokens
|
|
4299
4105
|
);
|
|
4300
|
-
/**
|
|
4301
|
-
* Serving-provider cue shaping BEFORE the fallback payload
|
|
4302
|
-
* is measured: a Claude fallback behind a tolerant primary
|
|
4303
|
-
* gains the cue inside the guarded projection (a prompt
|
|
4304
|
-
* within the cue's cost of the fallback budget must take
|
|
4305
|
-
* the recovery path, not ship oversized), and a tolerant
|
|
4306
|
-
* fallback behind an Anthropic primary sheds the baked cue
|
|
4307
|
-
* before it is measured against the tighter budget. The
|
|
4308
|
-
* attemptInvoke funnel pass then finds nothing to change.
|
|
4309
|
-
*/
|
|
4310
|
-
const cueShapedFallbackMessages = trackProviderMessageOrigins(
|
|
4311
|
-
fallbackMessages,
|
|
4312
|
-
isAnthropicLike(fallbackProvider, {
|
|
4313
|
-
model: resolveServingModelId(fallbackModel),
|
|
4314
|
-
})
|
|
4315
|
-
? appendPredecessorHandoffCue(fallbackMessages, (m) =>
|
|
4316
|
-
this.isRunProducedMessage(m)
|
|
4317
|
-
)
|
|
4318
|
-
: removePredecessorHandoffCue(fallbackMessages)
|
|
4319
|
-
);
|
|
4320
|
-
const projectedFallbackMessages = trackProviderMessageOrigins(
|
|
4321
|
-
cueShapedFallbackMessages,
|
|
4322
|
-
projectMessagesForProvider({
|
|
4323
|
-
model: fallbackModel,
|
|
4324
|
-
messages: cueShapedFallbackMessages,
|
|
4325
|
-
provider: fallbackProvider,
|
|
4326
|
-
maxToolResultChars: fallbackToolResultChars,
|
|
4327
|
-
callOptions: fallbackConfig,
|
|
4328
|
-
})
|
|
4329
|
-
);
|
|
4330
4106
|
const primaryContextBudget = contextUsage?.contextBudget;
|
|
4331
4107
|
const fallbackContextBudget =
|
|
4332
4108
|
fallbackMaxContextTokens == null
|
|
@@ -4335,11 +4111,31 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4335
4111
|
primaryContextBudget ?? fallbackMaxContextTokens,
|
|
4336
4112
|
fallbackMaxContextTokens
|
|
4337
4113
|
);
|
|
4338
|
-
const
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4114
|
+
const preparedFallbackRequest = prepareProviderRequest({
|
|
4115
|
+
model: fallbackModel,
|
|
4116
|
+
messages: fallbackMessages,
|
|
4117
|
+
provider: fallbackProvider,
|
|
4118
|
+
context: this,
|
|
4119
|
+
config: fallbackConfig,
|
|
4120
|
+
maxToolResultChars: fallbackToolResultChars,
|
|
4121
|
+
measure: (preparedMessages) =>
|
|
4122
|
+
measureProviderPayload(
|
|
4123
|
+
trackProviderMessageOrigins(
|
|
4124
|
+
fallbackMessages,
|
|
4125
|
+
preparedMessages
|
|
4126
|
+
),
|
|
4127
|
+
{
|
|
4128
|
+
contextBudget: fallbackContextBudget,
|
|
4129
|
+
forceRawRecount: true,
|
|
4130
|
+
}
|
|
4131
|
+
),
|
|
4132
|
+
});
|
|
4133
|
+
const projection =
|
|
4134
|
+
preparedFallbackRequest.measurement ??
|
|
4135
|
+
measureProviderPayload(preparedFallbackRequest.messages, {
|
|
4136
|
+
contextBudget: fallbackContextBudget,
|
|
4137
|
+
forceRawRecount: true,
|
|
4138
|
+
});
|
|
4343
4139
|
if (!projection.fits) {
|
|
4344
4140
|
throw createProviderPayloadOverflowError({
|
|
4345
4141
|
projection,
|
|
@@ -4347,7 +4143,7 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
4347
4143
|
info: 'Fallback provider message formatting exceeded the context budget before invocation.',
|
|
4348
4144
|
});
|
|
4349
4145
|
}
|
|
4350
|
-
return
|
|
4146
|
+
return preparedFallbackRequest;
|
|
4351
4147
|
},
|
|
4352
4148
|
})
|
|
4353
4149
|
);
|
package/src/index.ts
CHANGED
|
@@ -88,6 +88,14 @@ export type { SmoothItem, SmoothPiece } from './llm/stream/smoother';
|
|
|
88
88
|
export { FakeChatModel, createFakeStreamingLLM } from './llm/fake';
|
|
89
89
|
export { initializeModel } from './llm/init';
|
|
90
90
|
export { attemptInvoke, tryFallbackProviders } from './llm/invoke';
|
|
91
|
+
export { prepareProviderRequest } from './llm/prepareProviderRequest';
|
|
92
|
+
export type {
|
|
93
|
+
PreparedProviderRequest,
|
|
94
|
+
PrepareProviderRequestParams,
|
|
95
|
+
ProviderMessageProjectionMode,
|
|
96
|
+
ProviderPayloadMeasurement,
|
|
97
|
+
ProviderRequestContext,
|
|
98
|
+
} from './llm/prepareProviderRequest';
|
|
91
99
|
export { canSealPreempt } from './llm/preempt';
|
|
92
100
|
export { isThinkingEnabled, getMaxOutputTokensKey } from './llm/request';
|
|
93
101
|
export {
|