@jsonstudio/llms 0.6.1892 → 0.6.2172

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 (159) hide show
  1. package/dist/conversion/compat/actions/deepseek-web-request.js +16 -2
  2. package/dist/conversion/compat/actions/deepseek-web-response.d.ts +7 -1
  3. package/dist/conversion/compat/actions/deepseek-web-response.js +302 -40
  4. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.d.ts +5 -0
  5. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.js +7 -4
  6. package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +1 -0
  7. package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +12 -0
  8. package/dist/conversion/compat/actions/strip-orphan-function-calls-tag.js +1 -1
  9. package/dist/conversion/compat/actions/tool-text-request-guidance.d.ts +9 -0
  10. package/dist/conversion/compat/actions/tool-text-request-guidance.js +177 -0
  11. package/dist/conversion/compat/antigravity-session-signature.d.ts +6 -0
  12. package/dist/conversion/compat/antigravity-session-signature.js +15 -0
  13. package/dist/conversion/compat/profiles/chat-deepseek-web.json +52 -1
  14. package/dist/conversion/compat/profiles/chat-glm.json +22 -0
  15. package/dist/conversion/compat/profiles/chat-iflow.json +4 -0
  16. package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +13 -27
  17. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +10 -1
  18. package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +13 -4
  19. package/dist/conversion/hub/pipeline/compat/compat-profile-resolver.js +1 -53
  20. package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +8 -0
  21. package/dist/conversion/hub/pipeline/hub-pipeline.js +8 -4
  22. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +191 -9
  23. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +118 -15
  24. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +65 -2
  25. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage3_servertool_orchestration/index.d.ts +34 -0
  26. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage3_servertool_orchestration/index.js +75 -0
  27. package/dist/conversion/hub/process/chat-process.js +85 -18
  28. package/dist/conversion/hub/response/provider-response.js +21 -50
  29. package/dist/conversion/hub/response/response-runtime.js +71 -10
  30. package/dist/conversion/responses/responses-openai-bridge/response-payload.d.ts +3 -0
  31. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +576 -0
  32. package/dist/conversion/responses/responses-openai-bridge/types.d.ts +42 -0
  33. package/dist/conversion/responses/responses-openai-bridge/types.js +1 -0
  34. package/dist/conversion/responses/responses-openai-bridge.d.ts +3 -44
  35. package/dist/conversion/responses/responses-openai-bridge.js +193 -504
  36. package/dist/conversion/shared/anthropic-message-utils.js +82 -2
  37. package/dist/conversion/shared/bridge-message-utils.js +92 -39
  38. package/dist/conversion/shared/snapshot-hooks.js +8 -13
  39. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.d.ts +2 -0
  40. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.js +129 -0
  41. package/dist/conversion/shared/text-markup-normalizer/extractors-json.d.ts +4 -0
  42. package/dist/conversion/shared/text-markup-normalizer/extractors-json.js +637 -0
  43. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.d.ts +21 -0
  44. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.js +177 -0
  45. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.d.ts +5 -0
  46. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.js +385 -0
  47. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.d.ts +10 -0
  48. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.js +602 -0
  49. package/dist/conversion/shared/text-markup-normalizer/extractors.d.ts +5 -0
  50. package/dist/conversion/shared/text-markup-normalizer/extractors.js +4 -0
  51. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +2 -0
  52. package/dist/conversion/shared/text-markup-normalizer/normalize.js +76 -0
  53. package/dist/conversion/shared/text-markup-normalizer.d.ts +3 -25
  54. package/dist/conversion/shared/text-markup-normalizer.js +2 -1386
  55. package/dist/conversion/shared/tool-governor.js +136 -10
  56. package/dist/filters/utils/snapshot-writer.js +3 -3
  57. package/dist/router/virtual-router/bootstrap/auth-utils.d.ts +6 -0
  58. package/dist/router/virtual-router/bootstrap/auth-utils.js +288 -0
  59. package/dist/router/virtual-router/bootstrap/claude-code-helpers.d.ts +11 -0
  60. package/dist/router/virtual-router/bootstrap/claude-code-helpers.js +18 -0
  61. package/dist/router/virtual-router/bootstrap/config-defaults.d.ts +5 -0
  62. package/dist/router/virtual-router/bootstrap/config-defaults.js +13 -0
  63. package/dist/router/virtual-router/bootstrap/config-normalizers.d.ts +4 -0
  64. package/dist/router/virtual-router/bootstrap/config-normalizers.js +106 -0
  65. package/dist/router/virtual-router/bootstrap/profile-builder.d.ts +7 -0
  66. package/dist/router/virtual-router/bootstrap/profile-builder.js +68 -0
  67. package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +40 -0
  68. package/dist/router/virtual-router/bootstrap/provider-normalization.js +212 -0
  69. package/dist/router/virtual-router/bootstrap/responses-helpers.d.ts +15 -0
  70. package/dist/router/virtual-router/bootstrap/responses-helpers.js +65 -0
  71. package/dist/router/virtual-router/bootstrap/routing-config.d.ts +23 -0
  72. package/dist/router/virtual-router/bootstrap/routing-config.js +293 -0
  73. package/dist/router/virtual-router/bootstrap/streaming-helpers.d.ts +12 -0
  74. package/dist/router/virtual-router/bootstrap/streaming-helpers.js +128 -0
  75. package/dist/router/virtual-router/bootstrap/utils.d.ts +5 -0
  76. package/dist/router/virtual-router/bootstrap/utils.js +41 -0
  77. package/dist/router/virtual-router/bootstrap/web-search-config.d.ts +4 -0
  78. package/dist/router/virtual-router/bootstrap/web-search-config.js +131 -0
  79. package/dist/router/virtual-router/bootstrap.d.ts +0 -4
  80. package/dist/router/virtual-router/bootstrap.js +31 -1275
  81. package/dist/router/virtual-router/classifier.js +32 -14
  82. package/dist/router/virtual-router/engine/antigravity/alias-lease.js +2 -2
  83. package/dist/router/virtual-router/engine/cooldown-manager.d.ts +34 -0
  84. package/dist/router/virtual-router/engine/cooldown-manager.js +118 -0
  85. package/dist/router/virtual-router/engine/route-analytics.d.ts +28 -0
  86. package/dist/router/virtual-router/engine/route-analytics.js +44 -0
  87. package/dist/router/virtual-router/engine/routing-pools/index.js +165 -4
  88. package/dist/router/virtual-router/engine/sticky-session-manager.d.ts +29 -0
  89. package/dist/router/virtual-router/engine/sticky-session-manager.js +55 -0
  90. package/dist/router/virtual-router/engine-logging.d.ts +42 -1
  91. package/dist/router/virtual-router/engine-logging.js +82 -15
  92. package/dist/router/virtual-router/engine-selection/multimodal-capability.d.ts +3 -0
  93. package/dist/router/virtual-router/engine-selection/multimodal-capability.js +26 -0
  94. package/dist/router/virtual-router/engine-selection/route-utils.js +6 -2
  95. package/dist/router/virtual-router/engine-selection/selection-deps.d.ts +1 -0
  96. package/dist/router/virtual-router/engine-selection/tier-selection.js +31 -1
  97. package/dist/router/virtual-router/engine.d.ts +21 -7
  98. package/dist/router/virtual-router/engine.js +198 -194
  99. package/dist/router/virtual-router/features.js +12 -4
  100. package/dist/router/virtual-router/message-utils.d.ts +8 -0
  101. package/dist/router/virtual-router/message-utils.js +170 -45
  102. package/dist/router/virtual-router/pre-command-file-resolver.js +40 -2
  103. package/dist/router/virtual-router/routing-instructions.d.ts +8 -0
  104. package/dist/router/virtual-router/routing-instructions.js +18 -2
  105. package/dist/router/virtual-router/routing-stop-message-actions.js +34 -10
  106. package/dist/router/virtual-router/routing-stop-message-state-codec.d.ts +2 -0
  107. package/dist/router/virtual-router/routing-stop-message-state-codec.js +50 -1
  108. package/dist/router/virtual-router/stop-message-state-sync.d.ts +1 -1
  109. package/dist/router/virtual-router/stop-message-state-sync.js +3 -0
  110. package/dist/router/virtual-router/token-counter.js +51 -10
  111. package/dist/router/virtual-router/tool-signals.js +4 -0
  112. package/dist/router/virtual-router/types.d.ts +15 -0
  113. package/dist/servertool/clock/session-scope.d.ts +3 -0
  114. package/dist/servertool/clock/session-scope.js +52 -0
  115. package/dist/servertool/clock/state.js +9 -0
  116. package/dist/servertool/clock/tasks.js +12 -1
  117. package/dist/servertool/clock/types.d.ts +3 -0
  118. package/dist/servertool/engine.js +177 -31
  119. package/dist/servertool/handlers/clock-auto.js +2 -8
  120. package/dist/servertool/handlers/clock.js +6 -9
  121. package/dist/servertool/handlers/recursive-detection-guard.js +53 -14
  122. package/dist/servertool/handlers/stop-message-auto/blocked-report.d.ts +16 -0
  123. package/dist/servertool/handlers/stop-message-auto/blocked-report.js +349 -0
  124. package/dist/servertool/handlers/stop-message-auto/iflow-followup.d.ts +23 -0
  125. package/dist/servertool/handlers/stop-message-auto/iflow-followup.js +503 -0
  126. package/dist/servertool/handlers/stop-message-auto/routing-state.d.ts +38 -0
  127. package/dist/servertool/handlers/stop-message-auto/routing-state.js +149 -0
  128. package/dist/servertool/handlers/stop-message-auto/runtime-utils.d.ts +67 -0
  129. package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +387 -0
  130. package/dist/servertool/handlers/stop-message-auto.d.ts +1 -1
  131. package/dist/servertool/handlers/stop-message-auto.js +80 -556
  132. package/dist/servertool/handlers/stop-message-stage-policy/bd-runtime.d.ts +18 -0
  133. package/dist/servertool/handlers/stop-message-stage-policy/bd-runtime.js +398 -0
  134. package/dist/servertool/handlers/stop-message-stage-policy/decision.d.ts +9 -0
  135. package/dist/servertool/handlers/stop-message-stage-policy/decision.js +127 -0
  136. package/dist/servertool/handlers/stop-message-stage-policy/observation.d.ts +2 -0
  137. package/dist/servertool/handlers/stop-message-stage-policy/observation.js +179 -0
  138. package/dist/servertool/handlers/stop-message-stage-policy/templates.d.ts +4 -0
  139. package/dist/servertool/handlers/stop-message-stage-policy/templates.js +96 -0
  140. package/dist/servertool/handlers/stop-message-stage-policy/text-utils.d.ts +9 -0
  141. package/dist/servertool/handlers/stop-message-stage-policy/text-utils.js +89 -0
  142. package/dist/servertool/handlers/stop-message-stage-policy/types.d.ts +59 -0
  143. package/dist/servertool/handlers/stop-message-stage-policy/types.js +1 -0
  144. package/dist/servertool/handlers/stop-message-stage-policy.d.ts +3 -43
  145. package/dist/servertool/handlers/stop-message-stage-policy.js +2 -684
  146. package/dist/servertool/handlers/web-search.js +117 -0
  147. package/dist/servertool/server-side-tools.d.ts +0 -1
  148. package/dist/servertool/server-side-tools.js +4 -3
  149. package/dist/sse/sse-to-json/builders/response-builder.js +16 -0
  150. package/dist/sse/sse-to-json/chat-sse-to-json-converter.d.ts +1 -0
  151. package/dist/sse/sse-to-json/chat-sse-to-json-converter.js +110 -37
  152. package/dist/telemetry/stats-center.d.ts +9 -0
  153. package/dist/telemetry/stats-center.js +29 -1
  154. package/dist/tools/apply-patch/structured/coercion.js +3 -11
  155. package/dist/tools/exec-command/validator.d.ts +1 -0
  156. package/dist/tools/exec-command/validator.js +132 -0
  157. package/dist/tools/tool-registry.d.ts +1 -0
  158. package/dist/tools/tool-registry.js +1 -1
  159. package/package.json +1 -1
@@ -0,0 +1,177 @@
1
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
2
+ function readString(value) {
3
+ return typeof value === 'string' ? value.trim() : '';
4
+ }
5
+ function collectToolNames(toolsRaw) {
6
+ const out = [];
7
+ if (!Array.isArray(toolsRaw)) {
8
+ return out;
9
+ }
10
+ for (const item of toolsRaw) {
11
+ if (!isRecord(item))
12
+ continue;
13
+ const fn = isRecord(item.function) ? item.function : item;
14
+ const name = readString(fn.name);
15
+ if (!name)
16
+ continue;
17
+ if (!out.includes(name)) {
18
+ out.push(name);
19
+ }
20
+ }
21
+ return out;
22
+ }
23
+ function isToolChoiceRequired(root) {
24
+ const toolChoice = root.tool_choice;
25
+ if (typeof toolChoice === 'string') {
26
+ const normalized = toolChoice.trim().toLowerCase();
27
+ if (normalized === 'required')
28
+ return true;
29
+ if (normalized === 'auto' || normalized === 'none')
30
+ return false;
31
+ }
32
+ if (isRecord(toolChoice)) {
33
+ return String(toolChoice.type || '').trim().toLowerCase() === 'function';
34
+ }
35
+ return false;
36
+ }
37
+ function buildDefaultInstruction(root, config) {
38
+ const toolNames = collectToolNames(root.tools);
39
+ const includeToolNames = config?.includeToolNames !== false;
40
+ const required = isToolChoiceRequired(root);
41
+ const marker = readString(config?.marker) || 'Tool-call output contract (STRICT)';
42
+ const lines = [
43
+ `${marker}:`,
44
+ '1) If calling tools, output exactly one JSON object: {"tool_calls":[{"name":"tool_name","input":{...}}]}',
45
+ '2) Use only keys: `tool_calls` + each call `name` and `input`.',
46
+ '3) Do not output markdown fences, prose, or tool transcripts around JSON.',
47
+ '4) Do NOT output pseudo tool results in text (forbidden examples: {"exec_command":...}, <function_results>...</function_results>).'
48
+ ];
49
+ if (includeToolNames && toolNames.length) {
50
+ lines.push(`5) Allowed tool names this turn: ${toolNames.join(', ')}`);
51
+ }
52
+ else {
53
+ lines.push('5) Tool name must match provided schema exactly.');
54
+ }
55
+ lines.push(required
56
+ ? '6) tool_choice is required for this turn: return at least one tool call.'
57
+ : '6) If no tool is needed, plain text is allowed.');
58
+ return lines.join('\n');
59
+ }
60
+ function ensureSystemMessage(messages) {
61
+ const first = messages[0];
62
+ if (isRecord(first) && readString(first.role).toLowerCase() === 'system') {
63
+ return first;
64
+ }
65
+ const created = { role: 'system', content: '' };
66
+ messages.unshift(created);
67
+ return created;
68
+ }
69
+ function contentToText(content) {
70
+ if (typeof content === 'string') {
71
+ return content;
72
+ }
73
+ if (Array.isArray(content)) {
74
+ const parts = [];
75
+ for (const part of content) {
76
+ if (typeof part === 'string') {
77
+ parts.push(part);
78
+ continue;
79
+ }
80
+ if (!isRecord(part))
81
+ continue;
82
+ const text = readString(part.text) || readString(part.content);
83
+ if (text)
84
+ parts.push(text);
85
+ }
86
+ return parts.join('\n').trim();
87
+ }
88
+ if (isRecord(content)) {
89
+ const text = readString(content.text) || readString(content.content);
90
+ if (text) {
91
+ return text;
92
+ }
93
+ if (Array.isArray(content.content)) {
94
+ return contentToText(content.content);
95
+ }
96
+ }
97
+ return '';
98
+ }
99
+ function contentHasMarker(content, marker) {
100
+ if (!marker) {
101
+ return false;
102
+ }
103
+ const text = contentToText(content);
104
+ return text.includes(marker);
105
+ }
106
+ function appendInstructionToContent(content, instruction) {
107
+ if (typeof content === 'string') {
108
+ return content.trim() ? `${content}\n\n${instruction}` : instruction;
109
+ }
110
+ if (Array.isArray(content)) {
111
+ return [
112
+ ...content,
113
+ {
114
+ type: 'text',
115
+ text: content.length ? `\n\n${instruction}` : instruction
116
+ }
117
+ ];
118
+ }
119
+ if (isRecord(content)) {
120
+ if (typeof content.text === 'string') {
121
+ const previous = content.text;
122
+ return {
123
+ ...content,
124
+ text: previous.trim() ? `${previous}\n\n${instruction}` : instruction
125
+ };
126
+ }
127
+ if (typeof content.content === 'string') {
128
+ const previous = content.content;
129
+ return {
130
+ ...content,
131
+ content: previous.trim() ? `${previous}\n\n${instruction}` : instruction
132
+ };
133
+ }
134
+ if (Array.isArray(content.content)) {
135
+ return {
136
+ ...content,
137
+ content: appendInstructionToContent(content.content, instruction)
138
+ };
139
+ }
140
+ return [content, { type: 'text', text: instruction }];
141
+ }
142
+ return instruction;
143
+ }
144
+ export function applyToolTextRequestGuidance(payload, config) {
145
+ const enabled = config?.enabled !== false;
146
+ if (!enabled) {
147
+ return payload;
148
+ }
149
+ const root = structuredClone(payload);
150
+ const requireTools = config?.requireTools !== false;
151
+ if (requireTools) {
152
+ const tools = Array.isArray(root.tools) ? root.tools : [];
153
+ if (!tools.length) {
154
+ return root;
155
+ }
156
+ }
157
+ if (!Array.isArray(root.messages)) {
158
+ return root;
159
+ }
160
+ const messages = root.messages.filter((item) => isRecord(item));
161
+ if (!messages.length) {
162
+ return root;
163
+ }
164
+ const instruction = readString(config?.instruction) || buildDefaultInstruction(root, config);
165
+ if (!instruction) {
166
+ return root;
167
+ }
168
+ const marker = readString(config?.marker) || 'Tool-call output contract (STRICT)';
169
+ const system = ensureSystemMessage(messages);
170
+ if (contentHasMarker(system.content, marker)) {
171
+ root.messages = messages;
172
+ return root;
173
+ }
174
+ system.content = appendInstructionToContent(system.content, instruction);
175
+ root.messages = messages;
176
+ return root;
177
+ }
@@ -34,6 +34,12 @@ export declare function lookupAntigravityPinnedAliasForSessionId(sessionIdInput:
34
34
  hydrate?: boolean;
35
35
  }): string | undefined;
36
36
  export declare function unpinAntigravitySessionAliasForSessionId(sessionIdInput: string): void;
37
+ export declare function clearAntigravitySessionAliasPins(options?: {
38
+ hydrate?: boolean;
39
+ }): {
40
+ clearedBySession: number;
41
+ clearedByAlias: number;
42
+ };
37
43
  export declare function getAntigravitySessionSignature(aliasKey: string, sessionId: string): string | undefined;
38
44
  export declare function getAntigravitySessionSignature(sessionId: string): string | undefined;
39
45
  export type AntigravityThoughtSignatureLookupSource = 'session_cache' | 'miss' | 'blocked_unknown_alias' | 'blocked_rewind' | 'expired';
@@ -881,6 +881,21 @@ export function unpinAntigravitySessionAliasForSessionId(sessionIdInput) {
881
881
  }
882
882
  schedulePersistenceFlush();
883
883
  }
884
+ export function clearAntigravitySessionAliasPins(options) {
885
+ const allowHydrate = options?.hydrate !== false;
886
+ if (allowHydrate) {
887
+ hydrateSignaturesFromDiskIfNeeded(true);
888
+ }
889
+ const clearedBySession = pinnedAliasBySession.size;
890
+ const clearedByAlias = pinnedSessionByAlias.size;
891
+ if (clearedBySession === 0 && clearedByAlias === 0) {
892
+ return { clearedBySession: 0, clearedByAlias: 0 };
893
+ }
894
+ pinnedAliasBySession.clear();
895
+ pinnedSessionByAlias.clear();
896
+ schedulePersistenceFlush();
897
+ return { clearedBySession, clearedByAlias };
898
+ }
884
899
  export function getAntigravitySessionSignature(a, b) {
885
900
  return getAntigravitySessionSignatureEntry(a, b)?.signature;
886
901
  }
@@ -4,6 +4,14 @@
4
4
  "request": {
5
5
  "mappings": [
6
6
  { "action": "snapshot", "phase": "compat-pre" },
7
+ {
8
+ "action": "tool_text_request_guidance",
9
+ "config": {
10
+ "marker": "Tool-call output contract (STRICT)",
11
+ "includeToolNames": true,
12
+ "requireTools": true
13
+ }
14
+ },
7
15
  { "action": "deepseek_web_request" },
8
16
  { "action": "snapshot", "phase": "compat-post" }
9
17
  ]
@@ -11,7 +19,50 @@
11
19
  "response": {
12
20
  "mappings": [
13
21
  { "action": "snapshot", "phase": "compat-pre" },
14
- { "action": "deepseek_web_response" },
22
+ {
23
+ "action": "deepseek_web_response",
24
+ "config": {
25
+ "textNormalizer": {
26
+ "jsonToolRepair": {
27
+ "toolNameAliases": {
28
+ "shell_command": "exec_command",
29
+ "shell": "exec_command",
30
+ "bash": "exec_command",
31
+ "terminal": "exec_command"
32
+ },
33
+ "argumentAliases": {
34
+ "exec_command": {
35
+ "cmd": ["cmd", "command", "input.command", "script"],
36
+ "command": ["cmd", "command", "input.command", "script"],
37
+ "workdir": ["workdir", "cwd", "input.cwd"]
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
43
+ },
44
+ {
45
+ "action": "harvest_tool_calls_from_text",
46
+ "config": {
47
+ "normalizer": {
48
+ "jsonToolRepair": {
49
+ "toolNameAliases": {
50
+ "shell_command": "exec_command",
51
+ "shell": "exec_command",
52
+ "bash": "exec_command",
53
+ "terminal": "exec_command"
54
+ },
55
+ "argumentAliases": {
56
+ "exec_command": {
57
+ "cmd": ["cmd", "command", "input.command", "script"],
58
+ "command": ["cmd", "command", "input.command", "script"],
59
+ "workdir": ["workdir", "cwd", "input.cwd"]
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ },
15
66
  { "action": "snapshot", "phase": "compat-post" }
16
67
  ]
17
68
  }
@@ -196,6 +196,28 @@
196
196
  { "action": "tool_schema_sanitize", "mode": "glm_shell" },
197
197
  { "action": "response_normalize" },
198
198
  { "action": "extract_glm_tool_markup" },
199
+ {
200
+ "action": "harvest_tool_calls_from_text",
201
+ "config": {
202
+ "normalizer": {
203
+ "jsonToolRepair": {
204
+ "toolNameAliases": {
205
+ "shell_command": "exec_command",
206
+ "shell": "exec_command",
207
+ "bash": "exec_command",
208
+ "terminal": "exec_command"
209
+ },
210
+ "argumentAliases": {
211
+ "exec_command": {
212
+ "cmd": ["cmd", "command", "input.command", "script"],
213
+ "command": ["cmd", "command", "input.command", "script"],
214
+ "workdir": ["workdir", "cwd", "input.cwd"]
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+ },
199
221
  { "action": "response_validate" },
200
222
  { "action": "snapshot", "phase": "compat-post" },
201
223
  { "action": "dto_rewrap" }
@@ -106,6 +106,10 @@
106
106
  ]
107
107
  },
108
108
  { "action": "tool_schema_sanitize", "mode": "glm_shell" },
109
+ {
110
+ "action": "iflow_tool_text_fallback",
111
+ "models": ["minimax-m2.5"]
112
+ },
109
113
  {
110
114
  "action": "iflow_web_search_request"
111
115
  },
@@ -50,7 +50,9 @@ const ANTIGRAVITY_DEFAULT_SAFETY_SETTINGS = [
50
50
  const ANTIGRAVITY_NETWORK_TOOL_NAMES = new Set([
51
51
  'google_search',
52
52
  'google_search_retrieval',
53
- 'web_search'
53
+ 'web_search',
54
+ 'web_search_20250305',
55
+ 'websearch'
54
56
  ]);
55
57
  function stripTierSuffix(model) {
56
58
  return model.replace(/-(minimal|low|medium|high)$/i, '');
@@ -71,7 +73,11 @@ function normalizePreviewAlias(model) {
71
73
  }
72
74
  }
73
75
  function isNetworkingToolName(name) {
74
- return ANTIGRAVITY_NETWORK_TOOL_NAMES.has(name);
76
+ const normalized = typeof name === 'string' ? name.trim().toLowerCase() : '';
77
+ if (!normalized) {
78
+ return false;
79
+ }
80
+ return ANTIGRAVITY_NETWORK_TOOL_NAMES.has(normalized);
75
81
  }
76
82
  function detectsNetworkingTool(tools) {
77
83
  if (!Array.isArray(tools))
@@ -118,25 +124,6 @@ function hasFunctionDeclarations(tools) {
118
124
  return Array.isArray(record.functionDeclarations) && record.functionDeclarations.length > 0;
119
125
  });
120
126
  }
121
- function hasNonNetworkingFunctionDeclarations(tools) {
122
- if (!Array.isArray(tools))
123
- return false;
124
- for (const tool of tools) {
125
- if (!tool || typeof tool !== 'object')
126
- continue;
127
- const record = tool;
128
- const decls = Array.isArray(record.functionDeclarations)
129
- ? record.functionDeclarations
130
- : [];
131
- for (const decl of decls) {
132
- const name = typeof decl?.name === 'string' ? String(decl.name) : '';
133
- if (name && !isNetworkingToolName(name)) {
134
- return true;
135
- }
136
- }
137
- }
138
- return false;
139
- }
140
127
  function injectGoogleSearchTool(request) {
141
128
  const toolsRaw = request.tools;
142
129
  if (!Array.isArray(toolsRaw)) {
@@ -285,13 +272,12 @@ function resolveAntigravityRequestConfig(options) {
285
272
  imageConfig: parsed.imageConfig
286
273
  };
287
274
  }
288
- // Gemini v1internal constraint (Antigravity manager alignment):
289
- // - "web_search" requests must NOT mix googleSearch with functionDeclarations.
290
- // - If the request includes any non-networking function declarations (e.g. MCP/local tools),
291
- // we must disable networking and keep the request as "agent" to avoid upstream schema errors.
275
+ // Antigravity-Manager alignment:
276
+ // - networking intent is decided only by explicit signals (-online suffix or networking tools).
277
+ // - googleSearch injection is handled later by injectGoogleSearchTool(), which will skip injection
278
+ // when functionDeclarations exist to avoid mixed-tool schema conflicts.
292
279
  const wantsNetworking = original.endsWith('-online') || detectsNetworkingTool(options.tools);
293
- const hasLocalFunctions = hasNonNetworkingFunctionDeclarations(options.tools);
294
- const enableNetworking = wantsNetworking && !hasLocalFunctions;
280
+ const enableNetworking = wantsNetworking;
295
281
  let finalModel = stripOnlineSuffix(mapped);
296
282
  finalModel = normalizePreviewAlias(finalModel);
297
283
  // Only gemini-2.5-flash reliably supports googleSearch in v1internal; downgrade for networking.
@@ -509,7 +509,7 @@ export class ResponsesSemanticMapper {
509
509
  // causes providers like FAI to reject the request (HTTP 400). Any actual
510
510
  // submit_tool_outputs call should be issued via the dedicated endpoint
511
511
  // upstream, not through this mapper.
512
- return {
512
+ const result = {
513
513
  protocol: 'openai-responses',
514
514
  direction: 'response',
515
515
  payload: responses,
@@ -517,5 +517,14 @@ export class ResponsesSemanticMapper {
517
517
  context: ctx
518
518
  }
519
519
  };
520
+ // Some responses providers (e.g. TAB) reject sampling knobs with HTTP 400.
521
+ // Filter these at mapper outbound so they never reach openai-responses providers.
522
+ const unsupportedParams = ['temperature', 'top_p', 'seed', 'logit_bias'];
523
+ for (const key of unsupportedParams) {
524
+ if (key in result.payload) {
525
+ delete result.payload[key];
526
+ }
527
+ }
528
+ return result;
520
529
  }
521
530
  }
@@ -28,10 +28,11 @@ import { prepareAntigravityThoughtSignatureForGeminiRequest } from '../../../com
28
28
  import { cacheAntigravityThoughtSignatureFromGeminiResponse } from '../../../compat/actions/antigravity-thought-signature-cache.js';
29
29
  import { applyAnthropicClaudeCodeSystemPromptCompat } from '../../../compat/actions/anthropic-claude-code-system-prompt.js';
30
30
  import { normalizeToolCallIdsInPlace } from '../../../compat/actions/normalize-tool-call-ids.js';
31
- import { harvestToolCallsFromText } from '../../../compat/actions/harvest-tool-calls-from-text.js';
31
+ import { harvestToolCallsFromTextWithConfig } from '../../../compat/actions/harvest-tool-calls-from-text.js';
32
32
  import { stripOrphanFunctionCallsTag } from '../../../compat/actions/strip-orphan-function-calls-tag.js';
33
33
  import { stringifyLmstudioResponsesInput } from '../../../compat/actions/lmstudio-responses-input-stringify.js';
34
34
  import { enforceLmstudioResponsesFcToolCallIds } from '../../../compat/actions/lmstudio-responses-fc-ids.js';
35
+ import { applyToolTextRequestGuidance } from '../../../compat/actions/tool-text-request-guidance.js';
35
36
  const RATE_LIMIT_ERROR = 'ERR_COMPAT_RATE_LIMIT_DETECTED';
36
37
  const INTERNAL_STATE = Symbol('compat.internal_state');
37
38
  export function runRequestCompatPipeline(profileId, payload, options) {
@@ -180,7 +181,12 @@ function applyMapping(root, mapping, state) {
180
181
  break;
181
182
  case 'harvest_tool_calls_from_text':
182
183
  if (state.direction === 'response') {
183
- replaceRoot(root, harvestToolCallsFromText(root));
184
+ replaceRoot(root, harvestToolCallsFromTextWithConfig(root, mapping.config));
185
+ }
186
+ break;
187
+ case 'tool_text_request_guidance':
188
+ if (state.direction === 'request') {
189
+ replaceRoot(root, applyToolTextRequestGuidance(root, mapping.config));
184
190
  }
185
191
  break;
186
192
  case 'strip_orphan_function_calls_tag':
@@ -261,7 +267,10 @@ function applyMapping(root, mapping, state) {
261
267
  break;
262
268
  case 'iflow_tool_text_fallback':
263
269
  if (state.direction === 'request') {
264
- replaceRoot(root, applyIflowToolTextFallback(root, { models: mapping.models }));
270
+ replaceRoot(root, applyIflowToolTextFallback(root, {
271
+ models: mapping.models,
272
+ routeId: typeof state.adapterContext?.routeId === 'string' ? state.adapterContext.routeId : undefined
273
+ }));
265
274
  }
266
275
  break;
267
276
  case 'iflow_response_body_unwrap':
@@ -276,7 +285,7 @@ function applyMapping(root, mapping, state) {
276
285
  break;
277
286
  case 'deepseek_web_response':
278
287
  if (state.direction === 'response') {
279
- replaceRoot(root, applyDeepSeekWebResponseTransform(root, state.adapterContext));
288
+ replaceRoot(root, applyDeepSeekWebResponseTransform(root, state.adapterContext, mapping.config));
280
289
  }
281
290
  break;
282
291
  case 'claude_thinking_tool_schema':
@@ -1,10 +1,3 @@
1
- const PROFILE_BY_PROVIDER_FAMILY = {
2
- iflow: 'chat:iflow',
3
- lmstudio: 'chat:lmstudio',
4
- deepseek: 'chat:deepseek-web',
5
- antigravity: 'chat:gemini-cli',
6
- 'gemini-cli': 'chat:gemini-cli'
7
- };
8
1
  function readNonEmptyString(value) {
9
2
  if (typeof value !== 'string') {
10
3
  return undefined;
@@ -12,53 +5,8 @@ function readNonEmptyString(value) {
12
5
  const trimmed = value.trim();
13
6
  return trimmed.length ? trimmed : undefined;
14
7
  }
15
- function normalizeProviderFamily(value) {
16
- const normalized = readNonEmptyString(value)?.toLowerCase();
17
- if (!normalized) {
18
- return undefined;
19
- }
20
- if (normalized in PROFILE_BY_PROVIDER_FAMILY) {
21
- return normalized;
22
- }
23
- if (normalized.includes('.')) {
24
- const firstToken = normalized.split('.')[0]?.trim();
25
- if (firstToken && firstToken in PROFILE_BY_PROVIDER_FAMILY) {
26
- return firstToken;
27
- }
28
- }
29
- if (normalized.includes(':')) {
30
- const firstToken = normalized.split(':')[0]?.trim();
31
- if (firstToken && firstToken in PROFILE_BY_PROVIDER_FAMILY) {
32
- return firstToken;
33
- }
34
- }
35
- if (normalized.includes('/')) {
36
- const firstToken = normalized.split('/')[0]?.trim();
37
- if (firstToken && firstToken in PROFILE_BY_PROVIDER_FAMILY) {
38
- return firstToken;
39
- }
40
- }
41
- return undefined;
42
- }
43
- function resolveDefaultProfileFromFamily(adapterContext) {
44
- const context = adapterContext;
45
- const providerFamily = normalizeProviderFamily(context.providerFamily);
46
- if (providerFamily) {
47
- return PROFILE_BY_PROVIDER_FAMILY[providerFamily];
48
- }
49
- for (const key of ['providerId', 'providerKey', 'runtimeKey', 'profileId', 'providerType']) {
50
- const family = normalizeProviderFamily(context[key]);
51
- if (family) {
52
- return PROFILE_BY_PROVIDER_FAMILY[family];
53
- }
54
- }
55
- return undefined;
56
- }
57
8
  export function resolveCompatProfileForContext(adapterContext) {
58
9
  const context = adapterContext;
59
10
  const explicit = readNonEmptyString(context.compatibilityProfile);
60
- if (explicit) {
61
- return explicit;
62
- }
63
- return resolveDefaultProfileFromFamily(adapterContext);
11
+ return explicit;
64
12
  }
@@ -6,6 +6,9 @@ import type { RequestRulesConfig } from '../../../compat/actions/request-rules.j
6
6
  import type { AutoThinkingConfig } from '../../../compat/actions/auto-thinking.js';
7
7
  import type { ResponseNormalizeConfig } from '../../../compat/actions/response-normalize.js';
8
8
  import type { ResponseValidateConfig } from '../../../compat/actions/response-validate.js';
9
+ import type { HarvestToolCallsFromTextConfig } from '../../../compat/actions/harvest-tool-calls-from-text.js';
10
+ import type { ToolTextRequestGuidanceConfig } from '../../../compat/actions/tool-text-request-guidance.js';
11
+ import type { DeepSeekWebResponseConfig } from '../../../compat/actions/deepseek-web-response.js';
9
12
  export type CompatDirection = 'request' | 'response';
10
13
  export interface CompatProfileConfig {
11
14
  id: string;
@@ -77,6 +80,10 @@ export type MappingInstruction = {
77
80
  action: 'extract_glm_tool_markup';
78
81
  } | {
79
82
  action: 'harvest_tool_calls_from_text';
83
+ config?: HarvestToolCallsFromTextConfig;
84
+ } | {
85
+ action: 'tool_text_request_guidance';
86
+ config?: ToolTextRequestGuidanceConfig;
80
87
  } | {
81
88
  action: 'strip_orphan_function_calls_tag';
82
89
  } | {
@@ -136,6 +143,7 @@ export type MappingInstruction = {
136
143
  action: 'deepseek_web_request';
137
144
  } | {
138
145
  action: 'deepseek_web_response';
146
+ config?: DeepSeekWebResponseConfig;
139
147
  } | {
140
148
  action: 'claude_thinking_tool_schema';
141
149
  } | {
@@ -1250,11 +1250,15 @@ export class HubPipeline {
1250
1250
  const providerId = (target?.providerKey || metadata.providerKey);
1251
1251
  const routeId = metadata.routeName;
1252
1252
  const profileId = (target?.providerKey || metadata.pipelineId);
1253
- const compatibilityProfile = typeof target?.compatibilityProfile === 'string' && target.compatibilityProfile.trim()
1253
+ const targetCompatProfile = typeof target?.compatibilityProfile === 'string' && target.compatibilityProfile.trim()
1254
1254
  ? target.compatibilityProfile.trim()
1255
- : typeof metadata.compatibilityProfile === 'string'
1256
- ? String(metadata.compatibilityProfile).trim()
1257
- : undefined;
1255
+ : undefined;
1256
+ const metadataCompatProfile = typeof metadata.compatibilityProfile === 'string'
1257
+ ? String(metadata.compatibilityProfile).trim()
1258
+ : undefined;
1259
+ // When routing has already selected a target runtime, compat must be target-scoped only.
1260
+ // Never inherit stale top-level metadata.compatibilityProfile from a previous hop.
1261
+ const compatibilityProfile = target ? targetCompatProfile : metadataCompatProfile;
1258
1262
  const streamingHint = normalized.stream === true ? 'force' : normalized.stream === false ? 'disable' : 'auto';
1259
1263
  const toolCallIdStyle = normalizeToolCallIdStyleCandidate(metadata.toolCallIdStyle);
1260
1264
  const adapterContext = {