@jsonstudio/llms 0.6.3271 → 0.6.3379

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 (49) hide show
  1. package/dist/conversion/bridge-message-utils.d.ts +4 -4
  2. package/dist/conversion/bridge-message-utils.js +28 -538
  3. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +38 -0
  4. package/dist/conversion/compat/profiles/responses-crs.json +15 -0
  5. package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +16 -5
  6. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +1 -6
  7. package/dist/conversion/hub/response/response-runtime.js +14 -6
  8. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +11 -11
  9. package/dist/conversion/shared/anthropic-message-utils.js +2 -12
  10. package/dist/conversion/shared/chat-request-filters.js +2 -61
  11. package/dist/conversion/shared/reasoning-mapping.js +3 -0
  12. package/dist/conversion/shared/reasoning-normalizer.d.ts +1 -0
  13. package/dist/conversion/shared/reasoning-normalizer.js +35 -388
  14. package/dist/conversion/shared/reasoning-tool-normalizer.js +8 -15
  15. package/dist/conversion/shared/reasoning-utils.js +13 -35
  16. package/dist/conversion/shared/responses-tool-utils.d.ts +1 -1
  17. package/dist/conversion/shared/responses-tool-utils.js +63 -65
  18. package/dist/conversion/shared/streaming-text-extractor.d.ts +0 -5
  19. package/dist/conversion/shared/streaming-text-extractor.js +18 -111
  20. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +1 -1
  21. package/dist/conversion/shared/text-markup-normalizer/normalize.js +3 -91
  22. package/dist/conversion/shared/thought-signature-validator.js +19 -133
  23. package/dist/conversion/shared/tool-argument-repairer.js +16 -19
  24. package/dist/conversion/shared/tool-call-id-manager.d.ts +1 -5
  25. package/dist/conversion/shared/tool-call-id-manager.js +74 -98
  26. package/dist/conversion/shared/tool-harvester.js +19 -382
  27. package/dist/conversion/shared/tool-mapping.d.ts +2 -3
  28. package/dist/conversion/shared/tool-mapping.js +28 -184
  29. package/dist/conversion/shared/tooling.js +20 -151
  30. package/dist/filters/special/response-tool-arguments-stringify.js +9 -1
  31. package/dist/guidance/index.js +2 -2
  32. package/dist/native/router_hotpath_napi.node +0 -0
  33. package/dist/router/virtual-router/engine-legacy/helpers.js +1 -1
  34. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +39 -0
  35. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +196 -0
  36. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.d.ts +1 -0
  37. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js +27 -0
  38. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +34 -0
  39. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +65 -1
  40. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +836 -35
  41. package/dist/router/virtual-router/engine.js +3 -2
  42. package/dist/router/virtual-router/routing-instructions/parse.js +30 -3
  43. package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +28 -3
  44. package/dist/sse/types/anthropic-types.d.ts +3 -1
  45. package/dist/tools/apply-patch/args-normalizer/extract-patch.js +2 -2
  46. package/dist/tools/apply-patch/patch-text/looks-like-patch.js +3 -6
  47. package/dist/tools/apply-patch/patch-text/normalize.js +14 -3
  48. package/dist/tools/tool-registry.js +12 -0
  49. package/package.json +6 -1
@@ -4,16 +4,27 @@ export function maybeAugmentApplyPatchErrorContent(content, toolName) {
4
4
  return content;
5
5
  const lower = content.toLowerCase();
6
6
  const isApplyPatch = (typeof toolName === 'string' && toolName.trim() === 'apply_patch') ||
7
- lower.includes('apply_patch verification failed');
7
+ lower.includes('apply_patch verification failed') ||
8
+ lower.includes('failed to apply patch');
8
9
  if (!isApplyPatch) {
9
10
  return content;
10
11
  }
11
- // Avoid duplicate hints.
12
- if (content.includes('[apply_patch hint]')) {
12
+ if (content.includes('[apply_patch hint]') || content.includes('[RouteCodex hint] apply_patch')) {
13
13
  return content;
14
14
  }
15
- const hint = '\n\n[apply_patch hint] \u5728\u4f7f\u7528 apply_patch \u4e4b\u524d\uff0c\u8bf7\u5148\u8bfb\u53d6\u76ee\u6807\u6587\u4ef6\u7684\u6700\u65b0\u5185\u5bb9\uff0c\u5e76\u57fa\u4e8e\u8be5\u5185\u5bb9\u751f\u6210\u8865\u4e01\uff1b\u540c\u65f6\u786e\u4fdd\u8865\u4e01\u683c\u5f0f\u7b26\u5408\u5de5\u5177\u89c4\u8303\uff08\u7edf\u4e00\u8865\u4e01\u683c\u5f0f\u6216\u7ed3\u6784\u5316\u53c2\u6570\uff09\uff0c\u907f\u514d\u4e0a\u4e0b\u6587\u4e0d\u5339\u914d\u6216\u8bed\u6cd5\u9519\u8bef\u3002';
16
- return content + hint;
15
+ const sandboxSignal = lower.includes('sandbox(signal(9))') || (lower.includes('sandbox') && lower.includes('signal(9)'));
16
+ if (sandboxSignal) {
17
+ return content +
18
+ '\n\n[RouteCodex hint] apply_patch \u88ab sandbox \u7ec8\u6b62 (Signal 9)\u3002\u5e38\u89c1\u539f\u56e0\u662f\u8865\u4e01\u6d89\u53ca workspace \u4e4b\u5916\u7684\u8def\u5f84\u3002\u8bf7\u6539\u7528\u5f53\u524d workspace \u5185\u8def\u5f84\uff0c\u6216\u5c06\u76ee\u6807\u4ed3\u52a0\u5165 workspaces/workdir \u540e\u518d\u8c03\u7528 apply_patch\u3002';
19
+ }
20
+ const missingPath = lower.includes('failed to read file to update') ||
21
+ lower.includes('no such file or directory');
22
+ if (missingPath) {
23
+ return content +
24
+ '\n\n[RouteCodex hint] apply_patch \u8bfb\u53d6\u76ee\u6807\u6587\u4ef6\u5931\u8d25\uff1a\u8def\u5f84\u4e0d\u5b58\u5728\u6216\u4e0d\u5728\u5f53\u524d workspace\u3002\u8bf7\u786e\u8ba4\u8def\u5f84\u5728\u5f53\u524d workspace \u5185\u4e14\u6587\u4ef6\u771f\u5b9e\u5b58\u5728\uff1b\u8def\u5f84\u5fc5\u987b\u4e3a workspace \u76f8\u5bf9\u8def\u5f84\uff08\u5982 src/...\uff09\uff0c\u4e0d\u8981\u4ee5 / \u6216\u76d8\u7b26\u5f00\u5934\u3002\u5fc5\u8981\u65f6\u5207\u6362 workspace/workdir\u3002';
25
+ }
26
+ return content +
27
+ '\n\n[apply_patch hint] \u5728\u4f7f\u7528 apply_patch \u4e4b\u524d\uff0c\u8bf7\u5148\u8bfb\u53d6\u76ee\u6807\u6587\u4ef6\u7684\u6700\u65b0\u5185\u5bb9\uff0c\u5e76\u57fa\u4e8e\u8be5\u5185\u5bb9\u751f\u6210\u8865\u4e01\uff1b\u540c\u65f6\u786e\u4fdd\u8865\u4e01\u683c\u5f0f\u7b26\u5408\u5de5\u5177\u89c4\u8303\uff08\u7edf\u4e00\u8865\u4e01\u683c\u5f0f\u6216\u7ed3\u6784\u5316\u53c2\u6570\uff09\uff0c\u907f\u514d\u4e0a\u4e0b\u6587\u4e0d\u5339\u914d\u6216\u8bed\u6cd5\u9519\u8bef\u3002';
17
28
  }
18
29
  export class ChatSemanticMapper {
19
30
  async toChat(format, ctx) {
@@ -3,12 +3,7 @@ import { buildChatResponseFromResponses } from '../../../../../shared/responses-
3
3
  import { normalizeAssistantTextToToolCalls } from '../../../../../shared/text-markup-normalizer.js';
4
4
  import { recordStage } from '../../../stages/utils.js';
5
5
  import { applyRespProcessToolGovernanceWithNative, stripOrphanFunctionCallsTagWithNative } from '../../../../../../router/virtual-router/engine-selection/native-chat-process-governance-semantics.js';
6
- const SHELL_TOOL_NAME_ALIASES = {
7
- shell_command: 'exec_command',
8
- shell: 'exec_command',
9
- bash: 'exec_command',
10
- terminal: 'exec_command'
11
- };
6
+ const SHELL_TOOL_NAME_ALIASES = {};
12
7
  /**
13
8
  * Unified text-to-tool-calls harvest config.
14
9
  * Shared across all providers via chat process tool governance.
@@ -223,8 +223,7 @@ export function buildOpenAIChatFromAnthropicMessage(payload, options) {
223
223
  };
224
224
  const includeToolCallIds = options?.includeToolCallIds === true;
225
225
  const canonicalToolCalls = toolCalls.map((tc) => ({
226
- id: tc.id,
227
- ...(includeToolCallIds ? { call_id: tc.id, tool_call_id: tc.id } : {}),
226
+ ...(includeToolCallIds ? { id: tc.id, call_id: tc.id, tool_call_id: tc.id } : {}),
228
227
  type: 'function',
229
228
  function: { name: tc.name, arguments: tc.args }
230
229
  }));
@@ -246,6 +245,14 @@ export function buildOpenAIChatFromAnthropicMessage(payload, options) {
246
245
  if (!("tool_call_id" in inferred))
247
246
  inferred.tool_call_id = inferredId;
248
247
  }
248
+ else if (!includeToolCallIds) {
249
+ if ("id" in inferred)
250
+ delete inferred.id;
251
+ if ("call_id" in inferred)
252
+ delete inferred.call_id;
253
+ if ("tool_call_id" in inferred)
254
+ delete inferred.tool_call_id;
255
+ }
249
256
  canonicalToolCalls.push(inferred);
250
257
  if (key)
251
258
  seen.add(key);
@@ -259,9 +266,13 @@ export function buildOpenAIChatFromAnthropicMessage(payload, options) {
259
266
  call.call_id = cid;
260
267
  if (!("tool_call_id" in call))
261
268
  call.tool_call_id = cid;
269
+ if (!("id" in call))
270
+ call.id = cid;
262
271
  }
263
272
  }
264
273
  else {
274
+ if ("id" in call)
275
+ delete call.id;
265
276
  if ("call_id" in call)
266
277
  delete call.call_id;
267
278
  if ("tool_call_id" in call)
@@ -443,10 +454,7 @@ function sanitizeAnthropicMessage(message) {
443
454
  .filter((block) => block !== null);
444
455
  const usage = message.usage;
445
456
  if (usage && typeof usage === 'object') {
446
- sanitized.usage = {
447
- input_tokens: usage.input_tokens ?? 0,
448
- output_tokens: usage.output_tokens ?? 0
449
- };
457
+ sanitized.usage = JSON.parse(JSON.stringify(usage));
450
458
  }
451
459
  return sanitized;
452
460
  }
@@ -238,12 +238,6 @@ function buildClientToolIndex(toolsRaw) {
238
238
  }
239
239
  return index;
240
240
  }
241
- const CLIENT_TOOL_NAME_ALIASES = new Map([
242
- ['shell_command', 'exec_command'],
243
- ['shell', 'exec_command'],
244
- ['bash', 'exec_command'],
245
- ['terminal', 'exec_command']
246
- ]);
247
241
  function resolveClientToolName(toolIndex, rawToolName) {
248
242
  const trimmed = rawToolName.trim();
249
243
  if (!trimmed.length)
@@ -256,12 +250,18 @@ function resolveClientToolName(toolIndex, rawToolName) {
256
250
  return key;
257
251
  }
258
252
  }
259
- const aliased = CLIENT_TOOL_NAME_ALIASES.get(lower);
260
- if (!aliased)
253
+ const hasBash = Array.from(toolIndex.keys()).some((key) => key.toLowerCase() === 'bash');
254
+ if (hasBash)
261
255
  return undefined;
262
- for (const key of toolIndex.keys()) {
263
- if (key.toLowerCase() === aliased) {
264
- return key;
256
+ if (!['shell_command', 'exec_command', 'shell', 'terminal', 'bash'].includes(lower)) {
257
+ return undefined;
258
+ }
259
+ const preferred = ['shell_command', 'exec_command', 'shell', 'terminal'];
260
+ for (const candidate of preferred) {
261
+ for (const key of toolIndex.keys()) {
262
+ if (key.toLowerCase() === candidate) {
263
+ return key;
264
+ }
265
265
  }
266
266
  }
267
267
  return undefined;
@@ -186,12 +186,7 @@ function requireSystemText(block, context) {
186
186
  }
187
187
  return text;
188
188
  }
189
- const ANTHROPIC_TOOL_NAME_ALIASES = new Map([
190
- ['bash', 'shell_command'],
191
- ['shell', 'shell_command'],
192
- ['terminal', 'shell_command'],
193
- ['exec_command', 'shell_command']
194
- ]);
189
+ const ANTHROPIC_TOOL_NAME_ALIASES = new Map();
195
190
  const CANONICAL_TO_ANTHROPIC_TOOL_NAMES = new Map([['shell_command', 'Bash']]);
196
191
  const ANTHROPIC_TOP_LEVEL_FIELDS = new Set([
197
192
  'model',
@@ -1398,12 +1393,7 @@ export function buildAnthropicToolAliasMap(rawTools) {
1398
1393
  continue;
1399
1394
  }
1400
1395
  aliasMap.set(canonicalKey, rawName);
1401
- // Anthropic shell-like tools (e.g. Bash) and exec_command are treated as one family.
1402
- // Keep an explicit exec_command key so reverse mapping can preserve
1403
- // canonical exec_command when upstream already uses that name.
1404
- if (canonicalKey === 'shell_command' && !aliasMap.has('exec_command')) {
1405
- aliasMap.set('exec_command', rawName);
1406
- }
1396
+ const lowered = canonicalKey.toLowerCase();
1407
1397
  const lowerKey = canonicalKey.toLowerCase();
1408
1398
  if (lowerKey !== canonicalKey && !aliasMap.has(lowerKey)) {
1409
1399
  aliasMap.set(lowerKey, rawName);
@@ -1,6 +1,7 @@
1
1
  import { normalizeChatRequest } from '../index.js';
2
2
  import { createSnapshotWriter } from '../snapshot-utils.js';
3
3
  import { buildGovernedFilterPayloadWithNativeFallback } from '../../router/virtual-router/engine-selection/native-chat-request-filter-semantics.js';
4
+ import { pruneChatRequestPayloadWithNative } from '../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js';
4
5
  /**
5
6
  * Native-primary Chat request filters.
6
7
  *
@@ -56,67 +57,7 @@ export async function runStandardChatRequestFilters(chatRequest, profile, contex
56
57
  normalized.__rcc_disable_mcp_tools = true;
57
58
  }
58
59
  const preserveStreamField = profile.incomingProtocol === 'openai-chat' && profile.outgoingProtocol === 'openai-chat';
59
- const pruned = pruneChatRequestPayload(normalized, { preserveStreamField });
60
+ const pruned = pruneChatRequestPayloadWithNative(normalized, preserveStreamField);
60
61
  snapshotStage('req_process_filters_output', pruned);
61
62
  return pruned;
62
63
  }
63
- function pruneChatRequestPayload(chatRequest, options) {
64
- if (!chatRequest || typeof chatRequest !== 'object')
65
- return chatRequest;
66
- const stripped = { ...chatRequest };
67
- stripSentinelKeys(stripped);
68
- if ('originalStream' in stripped) {
69
- delete stripped.originalStream;
70
- }
71
- if ('_originalStreamOptions' in stripped) {
72
- delete stripped._originalStreamOptions;
73
- }
74
- if ('metadata' in stripped) {
75
- delete stripped.metadata;
76
- }
77
- if (!options?.preserveStreamField && 'stream' in stripped && stripped.stream !== true) {
78
- delete stripped.stream;
79
- }
80
- if (Array.isArray(stripped.messages)) {
81
- stripped.messages = stripped.messages.map((message) => sanitizeMessageEntry(message));
82
- }
83
- return stripped;
84
- }
85
- function sanitizeMessageEntry(message) {
86
- if (!message || typeof message !== 'object')
87
- return message;
88
- const clone = { ...message };
89
- if (Array.isArray(clone.tool_calls) && clone.tool_calls.length) {
90
- clone.tool_calls = clone.tool_calls.map((call) => sanitizeToolCallEntry(call));
91
- }
92
- if (clone.role === 'tool') {
93
- if (typeof clone.tool_call_id !== 'string' && typeof clone.call_id === 'string') {
94
- clone.tool_call_id = clone.call_id;
95
- }
96
- if ('id' in clone) {
97
- delete clone.id;
98
- }
99
- }
100
- if ('call_id' in clone) {
101
- delete clone.call_id;
102
- }
103
- return clone;
104
- }
105
- function sanitizeToolCallEntry(call) {
106
- if (!call || typeof call !== 'object')
107
- return call;
108
- const clone = { ...call };
109
- delete clone.call_id;
110
- delete clone.tool_call_id;
111
- if (clone.function && typeof clone.function === 'object') {
112
- clone.function = { ...clone.function };
113
- }
114
- return clone;
115
- }
116
- function stripSentinelKeys(record) {
117
- Object.keys(record).forEach((key) => {
118
- if (key.startsWith('__rcc_')) {
119
- delete record[key];
120
- }
121
- });
122
- }
@@ -1,4 +1,7 @@
1
1
  import { mapReasoningContentToResponsesOutputWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
2
  export function mapReasoningContentToResponsesOutput(reasoningContent) {
3
+ if (typeof mapReasoningContentToResponsesOutputWithNative !== 'function') {
4
+ throw new Error('[reasoning-mapping] native bindings unavailable');
5
+ }
3
6
  return mapReasoningContentToResponsesOutputWithNative(reasoningContent);
4
7
  }
@@ -19,4 +19,5 @@ export declare function normalizeReasoningInResponsesPayload(payload: {
19
19
  } | null | undefined, options?: ResponsesReasoningNormalizeOptions): void;
20
20
  export declare function normalizeReasoningInGeminiPayload(payload: JsonObject | null | undefined): void;
21
21
  export declare function normalizeReasoningInAnthropicPayload(payload: JsonObject | null | undefined): void;
22
+ export declare function normalizeReasoningInOpenAIPayload(payload: JsonObject | null | undefined): void;
22
23
  export {};