@jsonstudio/llms 0.6.3405 → 0.6.3539
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/conversion/codecs/anthropic-openai-codec.d.ts +12 -3
- package/dist/conversion/codecs/anthropic-openai-codec.js +32 -92
- package/dist/conversion/codecs/gemini-openai-codec.d.ts +6 -5
- package/dist/conversion/codecs/gemini-openai-codec.js +48 -685
- package/dist/conversion/codecs/openai-openai-codec.d.ts +1 -1
- package/dist/conversion/codecs/openai-openai-codec.js +34 -100
- package/dist/conversion/codecs/responses-openai-codec.d.ts +1 -1
- package/dist/conversion/codecs/responses-openai-codec.js +47 -159
- package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.d.ts +2 -6
- package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +29 -245
- package/dist/conversion/compat/actions/anthropic-claude-code-user-id.d.ts +3 -0
- package/dist/conversion/compat/actions/anthropic-claude-code-user-id.js +30 -0
- package/dist/conversion/compat/actions/antigravity-thought-signature-prepare.js +21 -232
- package/dist/conversion/compat/actions/deepseek-web-request.js +41 -276
- package/dist/conversion/compat/actions/deepseek-web-response.js +64 -859
- package/dist/conversion/compat/actions/gemini-cli-request.d.ts +1 -1
- package/dist/conversion/compat/actions/gemini-cli-request.js +20 -613
- package/dist/conversion/compat/actions/gemini-web-search.d.ts +1 -15
- package/dist/conversion/compat/actions/gemini-web-search.js +22 -69
- package/dist/conversion/compat/actions/glm-tool-extraction.d.ts +3 -2
- package/dist/conversion/compat/actions/glm-tool-extraction.js +28 -257
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +0 -8
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +24 -206
- package/dist/conversion/compat/actions/qwen-transform.d.ts +3 -2
- package/dist/conversion/compat/actions/qwen-transform.js +30 -271
- package/dist/conversion/compat/actions/tool-text-request-guidance.js +3 -173
- package/dist/conversion/compat/actions/universal-shape-filter.d.ts +6 -23
- package/dist/conversion/compat/actions/universal-shape-filter.js +4 -383
- package/dist/conversion/hub/pipeline/compat/native-adapter-context.js +1 -0
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.d.ts +1 -2
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +50 -104
- package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.js +12 -10
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.d.ts +0 -2
- package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +46 -67
- package/dist/conversion/pipeline/codecs/v2/shared/openai-chat-helpers.js +15 -40
- package/dist/conversion/responses/responses-openai-bridge/response-payload.js +47 -348
- package/dist/conversion/responses/responses-openai-bridge.js +129 -611
- package/dist/conversion/shared/chat-output-normalizer.js +6 -0
- package/dist/conversion/shared/chat-request-filters.js +1 -1
- package/dist/conversion/shared/output-content-normalizer.js +10 -0
- package/dist/conversion/shared/responses-conversation-store.js +22 -135
- package/dist/conversion/shared/responses-output-builder.d.ts +0 -2
- package/dist/conversion/shared/responses-output-builder.js +28 -318
- package/dist/conversion/shared/responses-response-utils.js +35 -86
- package/dist/conversion/shared/streaming-text-extractor.d.ts +1 -2
- package/dist/conversion/shared/streaming-text-extractor.js +13 -14
- package/dist/conversion/shared/tool-call-id-manager.js +18 -21
- package/dist/native/router_hotpath_napi.node +0 -0
- package/dist/router/virtual-router/bootstrap/routing-config.d.ts +2 -1
- package/dist/router/virtual-router/bootstrap/routing-config.js +57 -4
- package/dist/router/virtual-router/engine-legacy.d.ts +3 -3
- package/dist/router/virtual-router/engine-legacy.js +15 -7
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +16 -0
- package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +434 -46
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +83 -0
- package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +295 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.d.ts +1 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.d.ts +7 -0
- package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js +8 -1
- package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +383 -298
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +20 -0
- package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +201 -0
- package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +1 -0
- package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +37 -0
- package/dist/router/virtual-router/engine-selection/tier-load-balancing.d.ts +16 -0
- package/dist/router/virtual-router/engine-selection/tier-load-balancing.js +120 -0
- package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.d.ts +2 -0
- package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.js +44 -66
- package/dist/router/virtual-router/engine-selection/tier-selection-select.js +53 -84
- package/dist/router/virtual-router/engine.js +0 -38
- package/dist/router/virtual-router/features.js +44 -3
- package/dist/router/virtual-router/routing-instructions/parse.d.ts +0 -12
- package/dist/router/virtual-router/routing-instructions/parse.js +9 -389
- package/dist/router/virtual-router/stop-message-state-sync.d.ts +3 -6
- package/dist/router/virtual-router/stop-message-state-sync.js +50 -21
- package/dist/router/virtual-router/types.d.ts +16 -0
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +1 -0
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.js +26 -0
- package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +12 -2
- package/package.json +1 -1
- package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +0 -9
- package/dist/router/virtual-router/engine-legacy/route-finalize.js +0 -84
- package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +0 -17
- package/dist/router/virtual-router/engine-legacy/route-selection.js +0 -205
- package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +0 -3
- package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +0 -36
- package/dist/router/virtual-router/engine-legacy/route-state.d.ts +0 -12
- package/dist/router/virtual-router/engine-legacy/route-state.js +0 -386
- package/dist/router/virtual-router/engine-legacy/routing.d.ts +0 -8
- package/dist/router/virtual-router/engine-legacy/routing.js +0 -8
|
@@ -2,6 +2,7 @@ import { computeContextMultiplier } from '../context-weighted.js';
|
|
|
2
2
|
import { pinCandidatesByAliasQueue, resolveAliasSelectionStrategy } from './alias-selection.js';
|
|
3
3
|
import { computeContextWeightMultipliers } from './context-weight-multipliers.js';
|
|
4
4
|
import { extractKeyAlias, extractProviderId, getProviderModelId } from './key-parsing.js';
|
|
5
|
+
import { buildCandidateWeights, buildGroupWeights, hasNonUniformWeights, resolveTierLoadBalancing } from './tier-load-balancing.js';
|
|
5
6
|
import { pickPriorityGroup } from './tier-priority.js';
|
|
6
7
|
import { selectProviderKeyWithQuotaBuckets } from './tier-selection-quota-integration.js';
|
|
7
8
|
function buildPrimaryTargetGroups(candidates, deps) {
|
|
@@ -25,50 +26,6 @@ function buildPrimaryTargetGroups(candidates, deps) {
|
|
|
25
26
|
}
|
|
26
27
|
return groups;
|
|
27
28
|
}
|
|
28
|
-
function resolveGroupWeight(groupId, weights) {
|
|
29
|
-
if (!weights) {
|
|
30
|
-
return 1;
|
|
31
|
-
}
|
|
32
|
-
const direct = weights[groupId];
|
|
33
|
-
if (typeof direct === 'number' && Number.isFinite(direct) && direct > 0) {
|
|
34
|
-
return direct;
|
|
35
|
-
}
|
|
36
|
-
const providerId = groupId.split('.')[0] ?? groupId;
|
|
37
|
-
const providerOnly = weights[providerId];
|
|
38
|
-
if (typeof providerOnly === 'number' && Number.isFinite(providerOnly) && providerOnly > 0) {
|
|
39
|
-
return providerOnly;
|
|
40
|
-
}
|
|
41
|
-
return 1;
|
|
42
|
-
}
|
|
43
|
-
function buildGroupWeights(groups, weights) {
|
|
44
|
-
if (!groups.size) {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
const out = {};
|
|
48
|
-
for (const [groupId] of groups.entries()) {
|
|
49
|
-
out[groupId] = resolveGroupWeight(groupId, weights);
|
|
50
|
-
}
|
|
51
|
-
return out;
|
|
52
|
-
}
|
|
53
|
-
function hasNonUniformWeights(candidates, weights) {
|
|
54
|
-
if (!weights || candidates.length < 2) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
let ref;
|
|
58
|
-
for (const key of candidates) {
|
|
59
|
-
const raw = weights[key];
|
|
60
|
-
if (typeof raw !== 'number' || !Number.isFinite(raw)) {
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (ref === undefined) {
|
|
64
|
-
ref = raw;
|
|
65
|
-
}
|
|
66
|
-
else if (Math.abs(raw - ref) > 1e-6) {
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
29
|
function applyAliasStickyQueuePinning(opts) {
|
|
73
30
|
const { candidates, orderedTargets, deps, excludedKeys } = opts;
|
|
74
31
|
if (!Array.isArray(candidates) || candidates.length < 2) {
|
|
@@ -202,6 +159,7 @@ function preferAntigravityAliasesOnRetry(opts) {
|
|
|
202
159
|
export function selectProviderKeyFromCandidatePool(opts) {
|
|
203
160
|
const { routeName, tier, stickyKey, candidates, isSafePool, deps, options, contextResult, warnRatio, excludedKeys, isRecoveryAttempt, now, nowForWeights, healthWeightedCfg, contextWeightedCfg } = opts;
|
|
204
161
|
const quotaView = deps.quotaView;
|
|
162
|
+
const tierLoadBalancing = resolveTierLoadBalancing(tier, deps.loadBalancer.getPolicy());
|
|
205
163
|
const isAvailable = (key) => {
|
|
206
164
|
if (!quotaView) {
|
|
207
165
|
return deps.healthManager.isAvailable(key);
|
|
@@ -265,28 +223,33 @@ export function selectProviderKeyFromCandidatePool(opts) {
|
|
|
265
223
|
if (!group) {
|
|
266
224
|
return null;
|
|
267
225
|
}
|
|
268
|
-
const weights = (
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
226
|
+
const weights = buildCandidateWeights({
|
|
227
|
+
candidates: group.groupCandidates,
|
|
228
|
+
providerRegistry: deps.providerRegistry,
|
|
229
|
+
staticWeights: tierLoadBalancing.weights,
|
|
230
|
+
dynamicWeights: (() => {
|
|
231
|
+
if (!isSafePool)
|
|
232
|
+
return undefined;
|
|
233
|
+
const ctx = computeContextWeightMultipliers({ candidates: group.groupCandidates, usage: contextResult.usage, warnRatio, cfg: contextWeightedCfg });
|
|
234
|
+
if (!ctx)
|
|
235
|
+
return undefined;
|
|
236
|
+
const out = {};
|
|
237
|
+
for (const key of group.groupCandidates) {
|
|
238
|
+
const m = computeContextMultiplier({
|
|
239
|
+
effectiveSafeRefTokens: ctx.ref,
|
|
240
|
+
effectiveSafeTokens: ctx.eff[key] ?? 1,
|
|
241
|
+
cfg: contextWeightedCfg
|
|
242
|
+
});
|
|
243
|
+
out[key] = Math.max(1, Math.round(100 * m));
|
|
244
|
+
}
|
|
245
|
+
return out;
|
|
246
|
+
})()
|
|
247
|
+
});
|
|
285
248
|
const allowGrouped = !hasNonUniformWeights(group.groupCandidates, weights);
|
|
286
|
-
if (allowGrouped &&
|
|
249
|
+
if (allowGrouped && tierLoadBalancing.strategy !== 'sticky') {
|
|
287
250
|
const groups = buildPrimaryTargetGroups(group.groupCandidates, deps);
|
|
288
251
|
if (groups.size > 0) {
|
|
289
|
-
const groupWeights = buildGroupWeights(groups,
|
|
252
|
+
const groupWeights = buildGroupWeights(groups, tierLoadBalancing.weights);
|
|
290
253
|
const selected = deps.loadBalancer.selectGrouped({
|
|
291
254
|
routeName: `${routeName}:${tier.id}:priority:group:${group.groupId}`,
|
|
292
255
|
groups,
|
|
@@ -307,35 +270,40 @@ export function selectProviderKeyFromCandidatePool(opts) {
|
|
|
307
270
|
availabilityCheck: isAvailable
|
|
308
271
|
}, 'round-robin');
|
|
309
272
|
}
|
|
310
|
-
const weights = (
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
273
|
+
const weights = buildCandidateWeights({
|
|
274
|
+
candidates: pinnedCandidates,
|
|
275
|
+
providerRegistry: deps.providerRegistry,
|
|
276
|
+
staticWeights: tierLoadBalancing.weights,
|
|
277
|
+
dynamicWeights: (() => {
|
|
278
|
+
if (!isSafePool || !contextWeightedCfg.enabled)
|
|
279
|
+
return undefined;
|
|
280
|
+
const ctx = computeContextWeightMultipliers({ candidates: pinnedCandidates, usage: contextResult.usage, warnRatio, cfg: contextWeightedCfg });
|
|
281
|
+
if (!ctx)
|
|
282
|
+
return undefined;
|
|
283
|
+
const out = {};
|
|
284
|
+
for (const key of pinnedCandidates) {
|
|
285
|
+
const m = computeContextMultiplier({
|
|
286
|
+
effectiveSafeRefTokens: ctx.ref,
|
|
287
|
+
effectiveSafeTokens: ctx.eff[key] ?? 1,
|
|
288
|
+
cfg: contextWeightedCfg
|
|
289
|
+
});
|
|
290
|
+
out[key] = Math.max(1, Math.round(100 * m));
|
|
291
|
+
}
|
|
292
|
+
return out;
|
|
293
|
+
})()
|
|
294
|
+
});
|
|
327
295
|
const allowGrouped = !hasNonUniformWeights(pinnedCandidates, weights);
|
|
328
|
-
if (allowGrouped &&
|
|
296
|
+
if (allowGrouped && tierLoadBalancing.strategy !== 'sticky') {
|
|
329
297
|
const groups = buildPrimaryTargetGroups(pinnedCandidates, deps);
|
|
330
298
|
if (groups.size > 0) {
|
|
331
|
-
const groupWeights = buildGroupWeights(groups,
|
|
299
|
+
const groupWeights = buildGroupWeights(groups, tierLoadBalancing.weights);
|
|
332
300
|
const selected = deps.loadBalancer.selectGrouped({
|
|
333
301
|
routeName: `${routeName}:${tier.id}`,
|
|
334
302
|
groups,
|
|
335
303
|
stickyKey: options.allowAliasRotation ? undefined : stickyKey,
|
|
336
304
|
weights: groupWeights,
|
|
337
305
|
availabilityCheck: isAvailable
|
|
338
|
-
}, tier.mode === 'round-robin' ? 'round-robin' :
|
|
306
|
+
}, tier.mode === 'round-robin' ? 'round-robin' : tierLoadBalancing.strategy);
|
|
339
307
|
if (selected) {
|
|
340
308
|
return selected;
|
|
341
309
|
}
|
|
@@ -347,7 +315,7 @@ export function selectProviderKeyFromCandidatePool(opts) {
|
|
|
347
315
|
stickyKey: options.allowAliasRotation ? undefined : stickyKey,
|
|
348
316
|
weights,
|
|
349
317
|
availabilityCheck: isAvailable
|
|
350
|
-
}, tier.mode === 'round-robin' ? 'round-robin' :
|
|
318
|
+
}, tier.mode === 'round-robin' ? 'round-robin' : tierLoadBalancing.strategy);
|
|
351
319
|
}
|
|
352
320
|
return selectProviderKeyWithQuotaBuckets({
|
|
353
321
|
routeName,
|
|
@@ -365,6 +333,7 @@ export function selectProviderKeyFromCandidatePool(opts) {
|
|
|
365
333
|
nowForWeights,
|
|
366
334
|
healthWeightedCfg,
|
|
367
335
|
contextWeightedCfg,
|
|
336
|
+
tierLoadBalancing,
|
|
368
337
|
quotaView,
|
|
369
338
|
isAvailable,
|
|
370
339
|
selectFirstAvailable,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { VirtualRouterError, VirtualRouterErrorCode } from './types.js';
|
|
2
|
-
import { ROUTING_INSTRUCTION_MARKER_PATTERN } from './routing-instructions/types.js';
|
|
3
|
-
import { parseRoutingInstructions } from './routing-instructions/parse.js';
|
|
4
2
|
import { createVirtualRouterEngineProxy } from './engine-selection/native-virtual-router-engine-proxy.js';
|
|
5
3
|
import { cleanRoutingInstructionMarkersWithNative, parseRoutingInstructionKindsWithNative } from './engine-selection/native-virtual-router-routing-instructions-semantics.js';
|
|
6
|
-
import { getLatestUserTextFromResponsesContext, hasLatestUserRoutingInstructionMarker, hasRoutingInstructionMarkerInResponsesContext } from './engine-legacy/helpers.js';
|
|
7
4
|
import { extractMessageText, getLatestUserMessage } from './message-utils.js';
|
|
8
5
|
import { ProviderRegistry } from './provider-registry.js';
|
|
9
6
|
import { resolveStopMessageScope } from './engine/routing-state/store.js';
|
|
@@ -349,38 +346,3 @@ function cleanRoutingInstructionMarkersInPlace(request) {
|
|
|
349
346
|
}
|
|
350
347
|
}
|
|
351
348
|
}
|
|
352
|
-
function collectClientScopedInstructions(request) {
|
|
353
|
-
const messages = Array.isArray(request.messages)
|
|
354
|
-
? request.messages
|
|
355
|
-
: [];
|
|
356
|
-
const responsesContext = request.semantics && typeof request.semantics === 'object'
|
|
357
|
-
? request.semantics.responses?.context
|
|
358
|
-
: undefined;
|
|
359
|
-
const responsesHasMarker = hasRoutingInstructionMarkerInResponsesContext(responsesContext);
|
|
360
|
-
const latestUserHasMarker = hasLatestUserRoutingInstructionMarker(messages) || responsesHasMarker;
|
|
361
|
-
if (!latestUserHasMarker && !messages.some((message) => {
|
|
362
|
-
if (!message || typeof message !== 'object') {
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
|
-
const record = message;
|
|
366
|
-
return record.role === 'user' && typeof record.content === 'string' && ROUTING_INSTRUCTION_MARKER_PATTERN.test(record.content);
|
|
367
|
-
})) {
|
|
368
|
-
return { instructions: [], latestUserHasMarker };
|
|
369
|
-
}
|
|
370
|
-
let instructions = parseRoutingInstructions(messages);
|
|
371
|
-
if (instructions.length === 0 && responsesHasMarker) {
|
|
372
|
-
const responsesLatestUserText = getLatestUserTextFromResponsesContext(responsesContext);
|
|
373
|
-
if (responsesLatestUserText) {
|
|
374
|
-
instructions = parseRoutingInstructions([{ role: 'user', content: responsesLatestUserText }]);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return { instructions, latestUserHasMarker };
|
|
378
|
-
}
|
|
379
|
-
function isClientScopedInstruction(instruction) {
|
|
380
|
-
return (instruction.type === 'stopMessageSet' ||
|
|
381
|
-
instruction.type === 'stopMessageMode' ||
|
|
382
|
-
instruction.type === 'stopMessageClear' ||
|
|
383
|
-
instruction.type === 'preCommandSet' ||
|
|
384
|
-
instruction.type === 'preCommandClear' ||
|
|
385
|
-
instruction.type === 'clear');
|
|
386
|
-
}
|
|
@@ -3,6 +3,46 @@ import { extractAntigravityGeminiSessionIdWithNative } from './engine-selection/
|
|
|
3
3
|
import { detectCodingTool, detectLastAssistantToolCategory, detectVisionTool, detectWebSearchToolDeclared, detectWebTool, extractMeaningfulDeclaredToolNames } from './tool-signals.js';
|
|
4
4
|
import { computeRequestTokens } from './token-estimator.js';
|
|
5
5
|
const THINKING_KEYWORDS = ['let me think', 'chain of thought', 'cot', 'reason step', 'deliberate'];
|
|
6
|
+
function asRecord(value) {
|
|
7
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
8
|
+
? value
|
|
9
|
+
: null;
|
|
10
|
+
}
|
|
11
|
+
function getLatestResponsesContextMessage(request) {
|
|
12
|
+
const contextInput = asRecord(request.semantics)?.responses;
|
|
13
|
+
const context = asRecord(contextInput)?.context;
|
|
14
|
+
const input = Array.isArray(asRecord(context)?.input) ? asRecord(context)?.input : [];
|
|
15
|
+
for (let idx = input.length - 1; idx >= 0; idx -= 1) {
|
|
16
|
+
const entry = asRecord(input[idx]);
|
|
17
|
+
if (!entry) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const entryType = typeof entry.type === 'string' && entry.type.trim()
|
|
21
|
+
? entry.type.trim().toLowerCase()
|
|
22
|
+
: 'message';
|
|
23
|
+
if (entryType !== 'message') {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const role = typeof entry.role === 'string' && entry.role.trim()
|
|
27
|
+
? entry.role.trim().toLowerCase()
|
|
28
|
+
: 'user';
|
|
29
|
+
if (role !== 'user' && role !== 'assistant' && role !== 'tool') {
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const content = entry.content;
|
|
33
|
+
if (typeof content !== 'string' && !Array.isArray(content)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
role,
|
|
38
|
+
message: {
|
|
39
|
+
role: role,
|
|
40
|
+
content: content
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
6
46
|
export function buildRoutingFeatures(request, metadata) {
|
|
7
47
|
const antigravitySessionId = (() => {
|
|
8
48
|
try {
|
|
@@ -18,10 +58,11 @@ export function buildRoutingFeatures(request, metadata) {
|
|
|
18
58
|
return undefined;
|
|
19
59
|
}
|
|
20
60
|
})();
|
|
21
|
-
const
|
|
22
|
-
const
|
|
61
|
+
const responsesLatestMessage = getLatestResponsesContextMessage(request);
|
|
62
|
+
const latestMessageRole = responsesLatestMessage?.role || getLatestMessageRole(request.messages);
|
|
63
|
+
const latestMessage = responsesLatestMessage?.message || (Array.isArray(request.messages) && request.messages.length
|
|
23
64
|
? request.messages[request.messages.length - 1]
|
|
24
|
-
: undefined;
|
|
65
|
+
: undefined);
|
|
25
66
|
const assistantMessages = request.messages.filter((msg) => msg.role === 'assistant');
|
|
26
67
|
const latestUserText = latestMessageRole === 'user' && latestMessage
|
|
27
68
|
? extractMessageText(latestMessage)
|
|
@@ -1,18 +1,6 @@
|
|
|
1
1
|
import type { StandardizedMessage } from '../../../conversion/hub/types/standardized.js';
|
|
2
2
|
import type { RoutingInstruction } from './types.js';
|
|
3
3
|
export declare function parseRoutingInstructions(messages: StandardizedMessage[]): RoutingInstruction[];
|
|
4
|
-
/**
|
|
5
|
-
* 解析并预处理路由指令,优先处理 clear 指令,确保新指令能够覆盖旧状态。
|
|
6
|
-
* 返回清理后的指令列表,移除冗余的 stopMessageSet 指令。
|
|
7
|
-
*/
|
|
8
4
|
export declare function parseAndPreprocessRoutingInstructions(messages: StandardizedMessage[]): RoutingInstruction[];
|
|
9
|
-
/**
|
|
10
|
-
* 提取 clear 指令(如果存在)。用于在路由选择前优先执行清理操作。
|
|
11
|
-
* @returns 是否存在 clear 指令
|
|
12
|
-
*/
|
|
13
5
|
export declare function extractClearInstruction(messages: StandardizedMessage[]): boolean;
|
|
14
|
-
/**
|
|
15
|
-
* 提取 stopMessageClear 指令(如果存在)。
|
|
16
|
-
* @returns 是否存在 stopMessageClear 指令
|
|
17
|
-
*/
|
|
18
6
|
export declare function extractStopMessageClearInstruction(messages: StandardizedMessage[]): boolean;
|