@jsonstudio/llms 0.6.3409 → 0.6.3541

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 (85) hide show
  1. package/dist/conversion/codecs/anthropic-openai-codec.d.ts +12 -3
  2. package/dist/conversion/codecs/anthropic-openai-codec.js +32 -92
  3. package/dist/conversion/codecs/gemini-openai-codec.d.ts +6 -5
  4. package/dist/conversion/codecs/gemini-openai-codec.js +48 -685
  5. package/dist/conversion/codecs/openai-openai-codec.d.ts +1 -1
  6. package/dist/conversion/codecs/openai-openai-codec.js +34 -100
  7. package/dist/conversion/codecs/responses-openai-codec.d.ts +1 -1
  8. package/dist/conversion/codecs/responses-openai-codec.js +47 -159
  9. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.d.ts +2 -6
  10. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +29 -245
  11. package/dist/conversion/compat/actions/anthropic-claude-code-user-id.d.ts +3 -0
  12. package/dist/conversion/compat/actions/anthropic-claude-code-user-id.js +30 -0
  13. package/dist/conversion/compat/actions/antigravity-thought-signature-prepare.js +21 -232
  14. package/dist/conversion/compat/actions/deepseek-web-request.js +41 -276
  15. package/dist/conversion/compat/actions/deepseek-web-response.js +117 -855
  16. package/dist/conversion/compat/actions/gemini-cli-request.d.ts +1 -1
  17. package/dist/conversion/compat/actions/gemini-cli-request.js +20 -613
  18. package/dist/conversion/compat/actions/gemini-web-search.d.ts +1 -15
  19. package/dist/conversion/compat/actions/gemini-web-search.js +22 -69
  20. package/dist/conversion/compat/actions/glm-tool-extraction.d.ts +3 -2
  21. package/dist/conversion/compat/actions/glm-tool-extraction.js +28 -257
  22. package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +0 -8
  23. package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +24 -206
  24. package/dist/conversion/compat/actions/qwen-transform.d.ts +3 -2
  25. package/dist/conversion/compat/actions/qwen-transform.js +30 -271
  26. package/dist/conversion/compat/actions/tool-text-request-guidance.js +3 -173
  27. package/dist/conversion/compat/actions/universal-shape-filter.d.ts +6 -23
  28. package/dist/conversion/compat/actions/universal-shape-filter.js +4 -383
  29. package/dist/conversion/hub/pipeline/compat/native-adapter-context.js +1 -0
  30. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.d.ts +1 -2
  31. package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +50 -104
  32. package/dist/conversion/pipeline/codecs/v2/openai-openai-pipeline.js +12 -10
  33. package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.d.ts +0 -2
  34. package/dist/conversion/pipeline/codecs/v2/responses-openai-pipeline.js +46 -67
  35. package/dist/conversion/pipeline/codecs/v2/shared/openai-chat-helpers.js +15 -40
  36. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +47 -348
  37. package/dist/conversion/responses/responses-openai-bridge.js +129 -611
  38. package/dist/conversion/shared/chat-output-normalizer.js +6 -0
  39. package/dist/conversion/shared/chat-request-filters.js +1 -1
  40. package/dist/conversion/shared/output-content-normalizer.js +10 -0
  41. package/dist/conversion/shared/responses-conversation-store.js +22 -135
  42. package/dist/conversion/shared/responses-output-builder.d.ts +0 -2
  43. package/dist/conversion/shared/responses-output-builder.js +28 -318
  44. package/dist/conversion/shared/responses-response-utils.js +35 -86
  45. package/dist/conversion/shared/streaming-text-extractor.d.ts +1 -2
  46. package/dist/conversion/shared/streaming-text-extractor.js +13 -14
  47. package/dist/native/router_hotpath_napi.node +0 -0
  48. package/dist/quota/quota-state.js +29 -7
  49. package/dist/quota/types.d.ts +1 -0
  50. package/dist/router/virtual-router/bootstrap/routing-config.js +11 -3
  51. package/dist/router/virtual-router/engine-legacy.d.ts +3 -3
  52. package/dist/router/virtual-router/engine-legacy.js +15 -7
  53. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.d.ts +16 -0
  54. package/dist/router/virtual-router/engine-selection/native-compat-action-semantics.js +434 -46
  55. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +83 -0
  56. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +295 -0
  57. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.d.ts +1 -0
  58. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.d.ts +7 -0
  59. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-resp-semantics.js +8 -1
  60. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +383 -298
  61. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +20 -0
  62. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +201 -0
  63. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +1 -0
  64. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +37 -0
  65. package/dist/router/virtual-router/engine.js +0 -38
  66. package/dist/router/virtual-router/features.js +44 -3
  67. package/dist/router/virtual-router/routing-instructions/parse.d.ts +0 -12
  68. package/dist/router/virtual-router/routing-instructions/parse.js +9 -389
  69. package/dist/router/virtual-router/stop-message-state-sync.d.ts +3 -6
  70. package/dist/router/virtual-router/stop-message-state-sync.js +50 -21
  71. package/dist/servertool/handlers/followup-request-builder.js +12 -2
  72. package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +1 -0
  73. package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.js +26 -0
  74. package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +12 -2
  75. package/package.json +1 -1
  76. package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +0 -9
  77. package/dist/router/virtual-router/engine-legacy/route-finalize.js +0 -84
  78. package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +0 -17
  79. package/dist/router/virtual-router/engine-legacy/route-selection.js +0 -205
  80. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +0 -3
  81. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +0 -36
  82. package/dist/router/virtual-router/engine-legacy/route-state.d.ts +0 -12
  83. package/dist/router/virtual-router/engine-legacy/route-state.js +0 -386
  84. package/dist/router/virtual-router/engine-legacy/routing.d.ts +0 -8
  85. package/dist/router/virtual-router/engine-legacy/routing.js +0 -8
@@ -28,6 +28,7 @@ export declare function mapChatToolsToBridgeWithNative(rawTools: unknown, option
28
28
  }): Array<Record<string, unknown>>;
29
29
  export declare function collectToolCallsFromResponsesWithNative(response: Record<string, unknown>): Array<Record<string, unknown>>;
30
30
  export declare function resolveFinishReasonWithNative(response: Record<string, unknown>, toolCalls: Array<Record<string, unknown>>): string;
31
+ export declare function buildChatResponseFromResponsesWithNative(payload: unknown): Record<string, unknown> | null;
31
32
  export declare function hasValidThoughtSignatureWithNative(block: unknown, options?: Record<string, unknown>): boolean;
32
33
  export declare function sanitizeThinkingBlockWithNative(block: unknown): Record<string, unknown>;
33
34
  export declare function filterInvalidThinkingBlocksWithNative(messages: unknown, options?: Record<string, unknown>): unknown[];
@@ -146,6 +147,16 @@ export declare function extractStreamingToolCallsWithNative(input: {
146
147
  idCounter: number;
147
148
  toolCalls: Array<Record<string, unknown>>;
148
149
  };
150
+ export declare function createStreamingToolExtractorStateWithNative(idPrefix?: string): Record<string, unknown>;
151
+ export declare function resetStreamingToolExtractorStateWithNative(state: Record<string, unknown>): Record<string, unknown>;
152
+ export declare function feedStreamingToolExtractorWithNative(input: {
153
+ state: Record<string, unknown>;
154
+ text: string;
155
+ nowMs?: number;
156
+ }): {
157
+ state: Record<string, unknown>;
158
+ toolCalls: Array<Record<string, unknown>>;
159
+ };
149
160
  export declare function isCompactionRequestWithNative(payload: unknown): boolean;
150
161
  export declare function encodeMetadataPassthroughWithNative(parameters: unknown, prefix: string, keys: readonly string[]): Record<string, string> | undefined;
151
162
  export declare function extractMetadataPassthroughWithNative(metadataField: unknown, prefix: string, keys: readonly string[]): {
@@ -194,6 +205,15 @@ export declare function prepareGeminiToolsForBridgeWithNative(rawTools: unknown,
194
205
  export declare function buildGeminiToolsFromBridgeWithNative(defs: unknown, mode?: 'antigravity' | 'default'): Array<Record<string, unknown>> | undefined;
195
206
  export declare function pickResponsesPersistedFieldsWithNative(payload: unknown): Record<string, unknown>;
196
207
  export declare function convertResponsesOutputToInputItemsWithNative(response: unknown): Array<Record<string, unknown>>;
208
+ export declare function prepareResponsesConversationEntryWithNative(payload: unknown, context: unknown): {
209
+ basePayload: Record<string, unknown>;
210
+ input: Array<Record<string, unknown>>;
211
+ tools?: Array<Record<string, unknown>>;
212
+ };
213
+ export declare function resumeResponsesConversationPayloadWithNative(entry: unknown, responseId: string, submitPayload: unknown, requestId?: string): {
214
+ payload: Record<string, unknown>;
215
+ meta: Record<string, unknown>;
216
+ };
197
217
  export declare function enforceChatBudgetWithNative(chat: unknown, allowedBytes: number, systemTextLimit: number): unknown;
198
218
  export declare function resolveBudgetForModelWithNative(modelId: string, fallback: {
199
219
  maxBytes: number;
@@ -111,6 +111,24 @@ function parseToolDefinitionOutput(raw) {
111
111
  const parsed = parseRecord(raw);
112
112
  return parsed;
113
113
  }
114
+ function parseResponsesConversationResumeResult(raw) {
115
+ const parsed = parseRecord(raw);
116
+ if (!parsed) {
117
+ return null;
118
+ }
119
+ const payload = parsed.payload;
120
+ const meta = parsed.meta;
121
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
122
+ return null;
123
+ }
124
+ if (!meta || typeof meta !== 'object' || Array.isArray(meta)) {
125
+ return null;
126
+ }
127
+ return {
128
+ payload: payload,
129
+ meta: meta
130
+ };
131
+ }
114
132
  function parseToolDefinitionArray(raw) {
115
133
  const parsed = parseArray(raw);
116
134
  if (!parsed)
@@ -568,6 +586,32 @@ export function resolveFinishReasonWithNative(response, toolCalls) {
568
586
  return fail(reason);
569
587
  }
570
588
  }
589
+ export function buildChatResponseFromResponsesWithNative(payload) {
590
+ const capability = 'buildChatResponseFromResponsesJson';
591
+ const fail = (reason) => failNativeRequired(capability, reason);
592
+ if (isNativeDisabledByEnv()) {
593
+ return fail('native disabled');
594
+ }
595
+ const fn = readNativeFunction(capability);
596
+ if (!fn) {
597
+ return fail();
598
+ }
599
+ const payloadJson = safeStringify(payload ?? null);
600
+ if (!payloadJson) {
601
+ return fail('json stringify failed');
602
+ }
603
+ try {
604
+ const raw = fn(payloadJson);
605
+ if (typeof raw !== 'string' || !raw) {
606
+ return fail('empty result');
607
+ }
608
+ return parseRecord(raw) ?? fail('invalid payload');
609
+ }
610
+ catch (error) {
611
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
612
+ return fail(reason);
613
+ }
614
+ }
571
615
  export function hasValidThoughtSignatureWithNative(block, options) {
572
616
  const capability = 'hasValidThoughtSignatureJson';
573
617
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -1414,6 +1458,92 @@ export function extractStreamingToolCallsWithNative(input) {
1414
1458
  return fail(reason);
1415
1459
  }
1416
1460
  }
1461
+ export function createStreamingToolExtractorStateWithNative(idPrefix) {
1462
+ const capability = 'createStreamingToolExtractorStateJson';
1463
+ const fail = (reason) => failNativeRequired(capability, reason);
1464
+ if (isNativeDisabledByEnv()) {
1465
+ return fail('native disabled');
1466
+ }
1467
+ const fn = readNativeFunction(capability);
1468
+ if (!fn) {
1469
+ return fail();
1470
+ }
1471
+ const payloadJson = safeStringify(idPrefix ? { idPrefix } : {});
1472
+ if (!payloadJson) {
1473
+ return fail('json stringify failed');
1474
+ }
1475
+ try {
1476
+ const raw = fn(payloadJson);
1477
+ if (typeof raw !== 'string' || !raw) {
1478
+ return fail('empty result');
1479
+ }
1480
+ return parseRecord(raw) ?? fail('invalid payload');
1481
+ }
1482
+ catch (error) {
1483
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
1484
+ return fail(reason);
1485
+ }
1486
+ }
1487
+ export function resetStreamingToolExtractorStateWithNative(state) {
1488
+ const capability = 'resetStreamingToolExtractorStateJson';
1489
+ const fail = (reason) => failNativeRequired(capability, reason);
1490
+ if (isNativeDisabledByEnv()) {
1491
+ return fail('native disabled');
1492
+ }
1493
+ const fn = readNativeFunction(capability);
1494
+ if (!fn) {
1495
+ return fail();
1496
+ }
1497
+ const payloadJson = safeStringify(state ?? {});
1498
+ if (!payloadJson) {
1499
+ return fail('json stringify failed');
1500
+ }
1501
+ try {
1502
+ const raw = fn(payloadJson);
1503
+ if (typeof raw !== 'string' || !raw) {
1504
+ return fail('empty result');
1505
+ }
1506
+ return parseRecord(raw) ?? fail('invalid payload');
1507
+ }
1508
+ catch (error) {
1509
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
1510
+ return fail(reason);
1511
+ }
1512
+ }
1513
+ export function feedStreamingToolExtractorWithNative(input) {
1514
+ const capability = 'feedStreamingToolExtractorJson';
1515
+ const fail = (reason) => failNativeRequired(capability, reason);
1516
+ if (isNativeDisabledByEnv()) {
1517
+ return fail('native disabled');
1518
+ }
1519
+ const fn = readNativeFunction(capability);
1520
+ if (!fn) {
1521
+ return fail();
1522
+ }
1523
+ const payloadJson = safeStringify(input ?? {});
1524
+ if (!payloadJson) {
1525
+ return fail('json stringify failed');
1526
+ }
1527
+ try {
1528
+ const raw = fn(payloadJson);
1529
+ if (typeof raw !== 'string' || !raw) {
1530
+ return fail('empty result');
1531
+ }
1532
+ const parsed = parseRecord(raw);
1533
+ if (!parsed || !parsed.state || typeof parsed.state !== 'object' || Array.isArray(parsed.state)) {
1534
+ return fail('invalid payload');
1535
+ }
1536
+ const toolCalls = Array.isArray(parsed.toolCalls)
1537
+ ? parsed.toolCalls.filter((entry) => entry && typeof entry === 'object' && !Array.isArray(entry))
1538
+ .map((entry) => entry)
1539
+ : [];
1540
+ return { state: parsed.state, toolCalls };
1541
+ }
1542
+ catch (error) {
1543
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
1544
+ return fail(reason);
1545
+ }
1546
+ }
1417
1547
  export function isCompactionRequestWithNative(payload) {
1418
1548
  const capability = 'isCompactionRequestJson';
1419
1549
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -2177,6 +2307,77 @@ export function convertResponsesOutputToInputItemsWithNative(response) {
2177
2307
  return fail(reason);
2178
2308
  }
2179
2309
  }
2310
+ export function prepareResponsesConversationEntryWithNative(payload, context) {
2311
+ const capability = 'prepareResponsesConversationEntryJson';
2312
+ const fail = (reason) => failNativeRequired(capability, reason);
2313
+ if (isNativeDisabledByEnv()) {
2314
+ return fail('native disabled');
2315
+ }
2316
+ const fn = readNativeFunction(capability);
2317
+ if (!fn) {
2318
+ return fail();
2319
+ }
2320
+ const payloadJson = safeStringify(payload ?? null);
2321
+ const contextJson = safeStringify(context ?? null);
2322
+ if (!payloadJson || !contextJson) {
2323
+ return fail('json stringify failed');
2324
+ }
2325
+ try {
2326
+ const raw = fn(payloadJson, contextJson);
2327
+ if (typeof raw !== 'string' || !raw) {
2328
+ return fail('empty result');
2329
+ }
2330
+ const parsed = parseRecord(raw);
2331
+ if (!parsed) {
2332
+ return fail('invalid payload');
2333
+ }
2334
+ const basePayload = parsed.basePayload;
2335
+ const input = parsed.input;
2336
+ const tools = parsed.tools;
2337
+ if (!basePayload || typeof basePayload !== 'object' || Array.isArray(basePayload) || !Array.isArray(input)) {
2338
+ return fail('invalid payload');
2339
+ }
2340
+ return {
2341
+ basePayload: basePayload,
2342
+ input: input.filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry)),
2343
+ tools: Array.isArray(tools)
2344
+ ? tools.filter((entry) => !!entry && typeof entry === 'object' && !Array.isArray(entry))
2345
+ : undefined
2346
+ };
2347
+ }
2348
+ catch (error) {
2349
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
2350
+ return fail(reason);
2351
+ }
2352
+ }
2353
+ export function resumeResponsesConversationPayloadWithNative(entry, responseId, submitPayload, requestId) {
2354
+ const capability = 'resumeResponsesConversationPayloadJson';
2355
+ const fail = (reason) => failNativeRequired(capability, reason);
2356
+ if (isNativeDisabledByEnv()) {
2357
+ return fail('native disabled');
2358
+ }
2359
+ const fn = readNativeFunction(capability);
2360
+ if (!fn) {
2361
+ return fail();
2362
+ }
2363
+ const entryJson = safeStringify(entry ?? null);
2364
+ const submitPayloadJson = safeStringify(submitPayload ?? null);
2365
+ if (!entryJson || !submitPayloadJson) {
2366
+ return fail('json stringify failed');
2367
+ }
2368
+ try {
2369
+ const raw = fn(entryJson, String(responseId ?? ''), submitPayloadJson, requestId);
2370
+ if (typeof raw !== 'string' || !raw) {
2371
+ return fail('empty result');
2372
+ }
2373
+ const parsed = parseResponsesConversationResumeResult(raw);
2374
+ return parsed ?? fail('invalid payload');
2375
+ }
2376
+ catch (error) {
2377
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
2378
+ return fail(reason);
2379
+ }
2380
+ }
2180
2381
  export function enforceChatBudgetWithNative(chat, allowedBytes, systemTextLimit) {
2181
2382
  const capability = 'enforceChatBudgetJson';
2182
2383
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -1,2 +1,3 @@
1
1
  export declare function parseRoutingInstructionKindsWithNative(request: unknown): string[];
2
+ export declare function parseRoutingInstructionsWithNative(messages: Array<Record<string, unknown>>): Array<Record<string, unknown>>;
2
3
  export declare function cleanRoutingInstructionMarkersWithNative(request: Record<string, unknown>): Record<string, unknown>;
@@ -36,6 +36,19 @@ function parseRecordPayload(raw) {
36
36
  return null;
37
37
  }
38
38
  }
39
+ function parseRecordArrayPayload(raw) {
40
+ try {
41
+ const parsed = JSON.parse(raw);
42
+ if (!Array.isArray(parsed)) {
43
+ return null;
44
+ }
45
+ const records = parsed.filter((entry) => entry && typeof entry === 'object' && !Array.isArray(entry));
46
+ return records.length === parsed.length ? records : null;
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
39
52
  export function parseRoutingInstructionKindsWithNative(request) {
40
53
  const capability = 'parseRoutingInstructionKindsJson';
41
54
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -60,6 +73,30 @@ export function parseRoutingInstructionKindsWithNative(request) {
60
73
  return fail(reason);
61
74
  }
62
75
  }
76
+ export function parseRoutingInstructionsWithNative(messages) {
77
+ const capability = 'parseRoutingInstructionsJson';
78
+ const fail = (reason) => failNativeRequired(capability, reason);
79
+ const fn = readNativeFunction(capability);
80
+ if (!fn) {
81
+ return fail();
82
+ }
83
+ const messagesJson = safeStringify(messages);
84
+ if (!messagesJson) {
85
+ return fail('json stringify failed');
86
+ }
87
+ try {
88
+ const result = fn(messagesJson);
89
+ if (typeof result !== 'string' || !result) {
90
+ return fail('empty result');
91
+ }
92
+ const parsed = parseRecordArrayPayload(result);
93
+ return parsed ?? fail('invalid payload');
94
+ }
95
+ catch (error) {
96
+ const reason = error instanceof Error ? error.message : String(error ?? 'unknown');
97
+ return fail(reason);
98
+ }
99
+ }
63
100
  export function cleanRoutingInstructionMarkersWithNative(request) {
64
101
  const capability = 'cleanRoutingInstructionMarkersJson';
65
102
  const fail = (reason) => failNativeRequired(capability, reason);
@@ -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 latestMessageRole = getLatestMessageRole(request.messages);
22
- const latestMessage = Array.isArray(request.messages) && request.messages.length
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;