@jsonstudio/llms 0.6.1739 → 0.6.1890
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/compat/actions/deepseek-web-request.d.ts +3 -0
- package/dist/conversion/compat/actions/deepseek-web-request.js +350 -0
- package/dist/conversion/compat/actions/deepseek-web-response.d.ts +3 -0
- package/dist/conversion/compat/actions/deepseek-web-response.js +886 -0
- package/dist/conversion/compat/actions/gemini-cli-request.js +3 -1
- package/dist/conversion/compat/profiles/chat-deepseek-web.json +18 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +166 -2
- package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +169 -0
- package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +6 -0
- package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +12 -0
- package/dist/conversion/hub/pipeline/compat/compat-profile-resolver.js +1 -0
- package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +4 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.js +365 -144
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +9 -0
- package/dist/conversion/hub/policy/policy-engine.d.ts +2 -0
- package/dist/conversion/hub/policy/policy-engine.js +8 -0
- package/dist/conversion/hub/process/chat-process.js +466 -16
- package/dist/conversion/hub/response/provider-response.js +0 -35
- package/dist/conversion/responses/responses-openai-bridge.d.ts +2 -0
- package/dist/conversion/responses/responses-openai-bridge.js +166 -8
- package/dist/conversion/shared/anthropic-message-utils.js +10 -1
- package/dist/conversion/shared/protocol-field-allowlists.d.ts +2 -2
- package/dist/conversion/shared/protocol-field-allowlists.js +4 -0
- package/dist/conversion/shared/tool-governor.js +102 -0
- package/dist/guidance/index.js +17 -0
- package/dist/router/virtual-router/bootstrap.js +46 -1
- package/dist/router/virtual-router/classifier.js +59 -4
- package/dist/router/virtual-router/engine/health/index.js +6 -6
- package/dist/router/virtual-router/engine/routing-state/store.js +16 -3
- package/dist/router/virtual-router/engine-logging.js +62 -24
- package/dist/router/virtual-router/engine-selection/route-utils.js +20 -20
- package/dist/router/virtual-router/engine-selection/tier-selection.js +2 -2
- package/dist/router/virtual-router/engine.d.ts +3 -1
- package/dist/router/virtual-router/engine.js +359 -39
- package/dist/router/virtual-router/features.js +2 -1
- package/dist/router/virtual-router/pre-command-file-resolver.d.ts +2 -0
- package/dist/router/virtual-router/pre-command-file-resolver.js +90 -0
- package/dist/router/virtual-router/provider-registry.js +3 -1
- package/dist/router/virtual-router/routing-instructions.d.ts +15 -1
- package/dist/router/virtual-router/routing-instructions.js +110 -151
- package/dist/router/virtual-router/routing-pre-command-actions.d.ts +3 -0
- package/dist/router/virtual-router/routing-pre-command-actions.js +26 -0
- package/dist/router/virtual-router/routing-pre-command-parser.d.ts +2 -0
- package/dist/router/virtual-router/routing-pre-command-parser.js +85 -0
- package/dist/router/virtual-router/routing-pre-command-state-codec.d.ts +3 -0
- package/dist/router/virtual-router/routing-pre-command-state-codec.js +24 -0
- package/dist/router/virtual-router/routing-stop-message-actions.d.ts +2 -0
- package/dist/router/virtual-router/routing-stop-message-actions.js +96 -0
- package/dist/router/virtual-router/routing-stop-message-parser.d.ts +3 -0
- package/dist/router/virtual-router/routing-stop-message-parser.js +142 -0
- package/dist/router/virtual-router/routing-stop-message-state-codec.d.ts +4 -0
- package/dist/router/virtual-router/routing-stop-message-state-codec.js +85 -0
- package/dist/router/virtual-router/sticky-session-store.js +206 -57
- package/dist/router/virtual-router/stop-message-stage-template-files.d.ts +12 -0
- package/dist/router/virtual-router/stop-message-stage-template-files.js +67 -0
- package/dist/router/virtual-router/stop-message-state-sync.d.ts +1 -1
- package/dist/router/virtual-router/stop-message-state-sync.js +5 -0
- package/dist/router/virtual-router/token-file-scanner.d.ts +9 -0
- package/dist/router/virtual-router/token-file-scanner.js +64 -3
- package/dist/router/virtual-router/tool-signals.d.ts +5 -0
- package/dist/router/virtual-router/tool-signals.js +42 -3
- package/dist/router/virtual-router/types.d.ts +19 -1
- package/dist/router/virtual-router/types.js +1 -0
- package/dist/servertool/clock/config.d.ts +1 -1
- package/dist/servertool/clock/config.js +27 -4
- package/dist/servertool/clock/state.js +41 -2
- package/dist/servertool/clock/task-store.d.ts +2 -2
- package/dist/servertool/clock/task-store.js +1 -1
- package/dist/servertool/clock/tasks.d.ts +3 -1
- package/dist/servertool/clock/tasks.js +209 -18
- package/dist/servertool/clock/types.d.ts +17 -0
- package/dist/servertool/continue-execution/log.d.ts +3 -0
- package/dist/servertool/continue-execution/log.js +13 -0
- package/dist/servertool/engine.js +414 -68
- package/dist/servertool/handlers/antigravity-thought-signature-bootstrap.js +6 -6
- package/dist/servertool/handlers/clock-auto.js +54 -71
- package/dist/servertool/handlers/clock.js +121 -6
- package/dist/servertool/handlers/continue-execution.d.ts +1 -0
- package/dist/servertool/handlers/continue-execution.js +91 -0
- package/dist/servertool/handlers/followup-request-builder.js +13 -0
- package/dist/servertool/handlers/gemini-empty-reply-continue.js +1 -1
- package/dist/servertool/handlers/iflow-model-error-retry.js +1 -1
- package/dist/servertool/handlers/recursive-detection-guard.js +1 -1
- package/dist/servertool/handlers/stop-message-auto.js +386 -257
- package/dist/servertool/handlers/stop-message-stage-policy.d.ts +43 -0
- package/dist/servertool/handlers/stop-message-stage-policy.js +684 -0
- package/dist/servertool/handlers/vision.js +1 -1
- package/dist/servertool/log/progress-file.d.ts +14 -0
- package/dist/servertool/log/progress-file.js +88 -0
- package/dist/servertool/pre-command-hooks.d.ts +17 -0
- package/dist/servertool/pre-command-hooks.js +491 -0
- package/dist/servertool/registry.d.ts +23 -6
- package/dist/servertool/registry.js +66 -1
- package/dist/servertool/server-side-tools.d.ts +1 -0
- package/dist/servertool/server-side-tools.js +216 -14
- package/dist/servertool/stop-gateway-context.d.ts +14 -0
- package/dist/servertool/stop-gateway-context.js +167 -0
- package/dist/servertool/stop-message-compare-context.d.ts +24 -0
- package/dist/servertool/stop-message-compare-context.js +133 -0
- package/dist/servertool/types.d.ts +12 -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 +36 -1
- package/dist/sse/sse-to-json/builders/anthropic-response-builder.js +3 -0
- package/dist/sse/sse-to-json/chat-sse-to-json-converter.d.ts +3 -0
- package/dist/sse/sse-to-json/chat-sse-to-json-converter.js +118 -1
- package/dist/tools/apply-patch/args-normalizer/default-actions.js +1 -1
- package/package.json +1 -1
|
@@ -520,7 +520,9 @@ function shouldEnableAntigravitySignature(adapterContext) {
|
|
|
520
520
|
// Treat the first segment as the effective provider id for compatibility checks.
|
|
521
521
|
const providerIdOrKey = providerIdOrKeyRaw.trim().toLowerCase();
|
|
522
522
|
const effectiveProviderId = providerIdOrKey.split('.')[0] ?? '';
|
|
523
|
-
|
|
523
|
+
// Antigravity-Manager alignment: thoughtSignature compat applies to both Antigravity and Gemini CLI
|
|
524
|
+
// (both route to Google Gemini internals that enforce thoughtSignature on tool loops).
|
|
525
|
+
return effectiveProviderId === 'antigravity' || effectiveProviderId === 'gemini-cli';
|
|
524
526
|
}
|
|
525
527
|
function injectAntigravityThoughtSignature(requestNode, signature) {
|
|
526
528
|
if (!signature || !signature.trim())
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "chat:deepseek-web",
|
|
3
|
+
"protocol": "openai-chat",
|
|
4
|
+
"request": {
|
|
5
|
+
"mappings": [
|
|
6
|
+
{ "action": "snapshot", "phase": "compat-pre" },
|
|
7
|
+
{ "action": "deepseek_web_request" },
|
|
8
|
+
{ "action": "snapshot", "phase": "compat-post" }
|
|
9
|
+
]
|
|
10
|
+
},
|
|
11
|
+
"response": {
|
|
12
|
+
"mappings": [
|
|
13
|
+
{ "action": "snapshot", "phase": "compat-pre" },
|
|
14
|
+
{ "action": "deepseek_web_response" },
|
|
15
|
+
{ "action": "snapshot", "phase": "compat-post" }
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -12,7 +12,8 @@ const ANTHROPIC_PARAMETER_KEYS = [
|
|
|
12
12
|
'max_output_tokens',
|
|
13
13
|
'metadata',
|
|
14
14
|
'stream',
|
|
15
|
-
'tool_choice'
|
|
15
|
+
'tool_choice',
|
|
16
|
+
'thinking'
|
|
16
17
|
];
|
|
17
18
|
const ANTHROPIC_TOP_LEVEL_FIELDS = new Set([
|
|
18
19
|
'model',
|
|
@@ -27,10 +28,20 @@ const ANTHROPIC_TOP_LEVEL_FIELDS = new Set([
|
|
|
27
28
|
'max_output_tokens',
|
|
28
29
|
'metadata',
|
|
29
30
|
'stream',
|
|
30
|
-
'tool_choice'
|
|
31
|
+
'tool_choice',
|
|
32
|
+
'thinking'
|
|
31
33
|
]);
|
|
32
34
|
const PASSTHROUGH_METADATA_PREFIX = 'rcc_passthrough_';
|
|
33
35
|
const PASSTHROUGH_PARAMETERS = ['tool_choice'];
|
|
36
|
+
const RESPONSES_DROPPED_PARAMETER_KEYS = [
|
|
37
|
+
'prompt_cache_key',
|
|
38
|
+
'response_format',
|
|
39
|
+
'parallel_tool_calls',
|
|
40
|
+
'service_tier',
|
|
41
|
+
'truncation',
|
|
42
|
+
'include',
|
|
43
|
+
'store'
|
|
44
|
+
];
|
|
34
45
|
function ensureSemantics(chat) {
|
|
35
46
|
if (!chat.semantics || typeof chat.semantics !== 'object') {
|
|
36
47
|
chat.semantics = {};
|
|
@@ -88,6 +99,86 @@ function collectParameters(payload) {
|
|
|
88
99
|
}
|
|
89
100
|
return Object.keys(params).length ? params : undefined;
|
|
90
101
|
}
|
|
102
|
+
function mapReasoningEffortToAnthropicBudget(effort) {
|
|
103
|
+
const normalized = effort.trim().toLowerCase();
|
|
104
|
+
if (normalized === 'minimal' || normalized === 'low')
|
|
105
|
+
return 1024;
|
|
106
|
+
if (normalized === 'medium')
|
|
107
|
+
return 4096;
|
|
108
|
+
if (normalized === 'high')
|
|
109
|
+
return 8192;
|
|
110
|
+
return 4096;
|
|
111
|
+
}
|
|
112
|
+
function buildAnthropicThinkingFromReasoning(reasoning) {
|
|
113
|
+
if (reasoning === undefined || reasoning === null) {
|
|
114
|
+
return undefined;
|
|
115
|
+
}
|
|
116
|
+
if (typeof reasoning === 'boolean') {
|
|
117
|
+
if (!reasoning) {
|
|
118
|
+
return { type: 'disabled' };
|
|
119
|
+
}
|
|
120
|
+
return { type: 'enabled', budget_tokens: 4096 };
|
|
121
|
+
}
|
|
122
|
+
if (typeof reasoning === 'string') {
|
|
123
|
+
const normalized = reasoning.trim().toLowerCase();
|
|
124
|
+
if (!normalized.length) {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
if (normalized === 'off' || normalized === 'none' || normalized === 'disabled' || normalized === 'false') {
|
|
128
|
+
return { type: 'disabled' };
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
type: 'enabled',
|
|
132
|
+
budget_tokens: mapReasoningEffortToAnthropicBudget(normalized)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (typeof reasoning === 'number' && Number.isFinite(reasoning)) {
|
|
136
|
+
const budget = Math.max(0, Math.floor(reasoning));
|
|
137
|
+
return budget <= 0
|
|
138
|
+
? { type: 'disabled' }
|
|
139
|
+
: { type: 'enabled', budget_tokens: budget };
|
|
140
|
+
}
|
|
141
|
+
if (!isJsonObject(reasoning)) {
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
const node = reasoning;
|
|
145
|
+
const enabledRaw = node.enabled;
|
|
146
|
+
if (enabledRaw === false) {
|
|
147
|
+
return { type: 'disabled' };
|
|
148
|
+
}
|
|
149
|
+
const effortRaw = typeof node.effort === 'string'
|
|
150
|
+
? node.effort
|
|
151
|
+
: typeof node.level === 'string'
|
|
152
|
+
? node.level
|
|
153
|
+
: undefined;
|
|
154
|
+
const budgetRaw = typeof node.budget_tokens === 'number'
|
|
155
|
+
? node.budget_tokens
|
|
156
|
+
: typeof node.budget === 'number'
|
|
157
|
+
? node.budget
|
|
158
|
+
: typeof node.max_tokens === 'number'
|
|
159
|
+
? node.max_tokens
|
|
160
|
+
: undefined;
|
|
161
|
+
if (typeof budgetRaw === 'number' && Number.isFinite(budgetRaw)) {
|
|
162
|
+
const budget = Math.max(0, Math.floor(budgetRaw));
|
|
163
|
+
return budget <= 0
|
|
164
|
+
? { type: 'disabled' }
|
|
165
|
+
: { type: 'enabled', budget_tokens: budget };
|
|
166
|
+
}
|
|
167
|
+
if (typeof effortRaw === 'string' && effortRaw.trim().length) {
|
|
168
|
+
const normalized = effortRaw.trim().toLowerCase();
|
|
169
|
+
if (normalized === 'off' || normalized === 'none' || normalized === 'disabled') {
|
|
170
|
+
return { type: 'disabled' };
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
type: 'enabled',
|
|
174
|
+
budget_tokens: mapReasoningEffortToAnthropicBudget(normalized)
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (enabledRaw === true) {
|
|
178
|
+
return { type: 'enabled', budget_tokens: 4096 };
|
|
179
|
+
}
|
|
180
|
+
return { type: 'enabled', budget_tokens: 4096 };
|
|
181
|
+
}
|
|
91
182
|
function cloneAnthropicSystemBlocks(value) {
|
|
92
183
|
if (value === undefined || value === null) {
|
|
93
184
|
return undefined;
|
|
@@ -98,6 +189,55 @@ function cloneAnthropicSystemBlocks(value) {
|
|
|
98
189
|
}
|
|
99
190
|
return blocks.map((entry) => jsonClone(entry));
|
|
100
191
|
}
|
|
192
|
+
function isResponsesOrigin(chat) {
|
|
193
|
+
const semantics = chat?.semantics;
|
|
194
|
+
if (semantics && semantics.responses && isJsonObject(semantics.responses)) {
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
const ctx = chat?.metadata && typeof chat.metadata === 'object'
|
|
198
|
+
? chat.metadata.context
|
|
199
|
+
: undefined;
|
|
200
|
+
const protocol = typeof ctx?.providerProtocol === 'string' ? ctx.providerProtocol.trim().toLowerCase() : '';
|
|
201
|
+
if (protocol === 'openai-responses') {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
const endpoint = typeof ctx?.entryEndpoint === 'string' ? ctx.entryEndpoint.trim().toLowerCase() : '';
|
|
205
|
+
return endpoint === '/v1/responses';
|
|
206
|
+
}
|
|
207
|
+
function appendMappingAudit(chat, options) {
|
|
208
|
+
const metadata = chat.metadata && typeof chat.metadata === 'object'
|
|
209
|
+
? chat.metadata
|
|
210
|
+
: (chat.metadata = { context: chat.metadata?.context ?? {} });
|
|
211
|
+
const root = metadata.mappingAudit && typeof metadata.mappingAudit === 'object' && !Array.isArray(metadata.mappingAudit)
|
|
212
|
+
? metadata.mappingAudit
|
|
213
|
+
: (metadata.mappingAudit = {});
|
|
214
|
+
const current = Array.isArray(root[options.bucket]) ? root[options.bucket] : [];
|
|
215
|
+
const duplicate = current.find((entry) => entry &&
|
|
216
|
+
entry.field === options.field &&
|
|
217
|
+
entry.targetProtocol === options.targetProtocol &&
|
|
218
|
+
entry.reason === options.reason);
|
|
219
|
+
if (!duplicate) {
|
|
220
|
+
current.push({
|
|
221
|
+
field: options.field,
|
|
222
|
+
source: options.source ?? 'chat.parameters',
|
|
223
|
+
targetProtocol: options.targetProtocol,
|
|
224
|
+
reason: options.reason
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
root[options.bucket] = current;
|
|
228
|
+
}
|
|
229
|
+
function appendDroppedFieldAudit(chat, options) {
|
|
230
|
+
appendMappingAudit(chat, {
|
|
231
|
+
bucket: 'dropped',
|
|
232
|
+
...options
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function appendLossyFieldAudit(chat, options) {
|
|
236
|
+
appendMappingAudit(chat, {
|
|
237
|
+
bucket: 'lossy',
|
|
238
|
+
...options
|
|
239
|
+
});
|
|
240
|
+
}
|
|
101
241
|
export class AnthropicSemanticMapper {
|
|
102
242
|
chatMapper = new ChatSemanticMapper();
|
|
103
243
|
async toChat(format, ctx) {
|
|
@@ -215,6 +355,19 @@ export class AnthropicSemanticMapper {
|
|
|
215
355
|
};
|
|
216
356
|
const explicitEmptyTools = hasExplicitEmptyToolsSemantics(chat);
|
|
217
357
|
const trimmedParameters = chat.parameters && typeof chat.parameters === 'object' ? chat.parameters : undefined;
|
|
358
|
+
const responsesOrigin = isResponsesOrigin(chat);
|
|
359
|
+
if (trimmedParameters && responsesOrigin) {
|
|
360
|
+
for (const field of RESPONSES_DROPPED_PARAMETER_KEYS) {
|
|
361
|
+
if (!Object.prototype.hasOwnProperty.call(trimmedParameters, field)) {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
appendDroppedFieldAudit(chat, {
|
|
365
|
+
field,
|
|
366
|
+
targetProtocol: 'anthropic-messages',
|
|
367
|
+
reason: 'unsupported_semantics_no_equivalent'
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
218
371
|
if (trimmedParameters) {
|
|
219
372
|
for (const [key, value] of Object.entries(trimmedParameters)) {
|
|
220
373
|
if (ANTHROPIC_TOP_LEVEL_FIELDS.has(key) || key === 'stop') {
|
|
@@ -242,6 +395,17 @@ export class AnthropicSemanticMapper {
|
|
|
242
395
|
if (baseRequest.max_output_tokens && !baseRequest.max_tokens) {
|
|
243
396
|
baseRequest.max_tokens = baseRequest.max_output_tokens;
|
|
244
397
|
}
|
|
398
|
+
const mappedThinking = buildAnthropicThinkingFromReasoning(trimmedParameters?.reasoning);
|
|
399
|
+
if (mappedThinking && baseRequest.thinking === undefined) {
|
|
400
|
+
baseRequest.thinking = mappedThinking;
|
|
401
|
+
}
|
|
402
|
+
if (responsesOrigin && trimmedParameters && Object.prototype.hasOwnProperty.call(trimmedParameters, 'reasoning')) {
|
|
403
|
+
appendLossyFieldAudit(chat, {
|
|
404
|
+
field: 'reasoning',
|
|
405
|
+
targetProtocol: 'anthropic-messages',
|
|
406
|
+
reason: 'normalized_to_anthropic_thinking_budget'
|
|
407
|
+
});
|
|
408
|
+
}
|
|
245
409
|
// 出站阶段不再直接透传其它协议的 providerMetadata,避免跨协议打洞;
|
|
246
410
|
// Anthropic 自身入口的 metadata 已在入站阶段通过 collectParameters/encodeMetadataPassthrough
|
|
247
411
|
// 按白名单收集,这里仅依赖这些显式映射结果。
|
|
@@ -18,6 +18,15 @@ const GENERATION_CONFIG_KEYS = [
|
|
|
18
18
|
];
|
|
19
19
|
const PASSTHROUGH_METADATA_PREFIX = 'rcc_passthrough_';
|
|
20
20
|
const PASSTHROUGH_PARAMETERS = ['tool_choice'];
|
|
21
|
+
const RESPONSES_DROPPED_PARAMETER_KEYS = [
|
|
22
|
+
'prompt_cache_key',
|
|
23
|
+
'response_format',
|
|
24
|
+
'parallel_tool_calls',
|
|
25
|
+
'service_tier',
|
|
26
|
+
'truncation',
|
|
27
|
+
'include',
|
|
28
|
+
'store'
|
|
29
|
+
];
|
|
21
30
|
// Ported from CLIProxyAPI v6.6.89 (antigravity auth constants)
|
|
22
31
|
const ANTIGRAVITY_SYSTEM_INSTRUCTION = `You are Antigravity, a powerful agentic AI coding assistant designed by the Google DeepMind team working on Advanced Agentic Coding.
|
|
23
32
|
You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.
|
|
@@ -662,6 +671,19 @@ function buildGeminiRequestFromChat(chat, metadata) {
|
|
|
662
671
|
const isGeminiCliProvider = providerIdPrefix === 'gemini-cli';
|
|
663
672
|
const requiresThoughtSignature = isAntigravityProvider || isGeminiCliProvider;
|
|
664
673
|
const parameters = chat.parameters && typeof chat.parameters === 'object' ? chat.parameters : {};
|
|
674
|
+
const responsesOrigin = isResponsesOrigin(chat);
|
|
675
|
+
if (responsesOrigin) {
|
|
676
|
+
for (const field of RESPONSES_DROPPED_PARAMETER_KEYS) {
|
|
677
|
+
if (!Object.prototype.hasOwnProperty.call(parameters, field)) {
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
appendDroppedFieldAudit(chat, {
|
|
681
|
+
field,
|
|
682
|
+
targetProtocol: 'gemini-chat',
|
|
683
|
+
reason: 'unsupported_semantics_no_equivalent'
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
}
|
|
665
687
|
const isAntigravityClaudeThinking = providerIdPrefix === 'antigravity' &&
|
|
666
688
|
typeof parameters.model === 'string' &&
|
|
667
689
|
String(parameters.model).includes('claude-sonnet-4-5-thinking');
|
|
@@ -901,6 +923,13 @@ function buildGeminiRequestFromChat(chat, metadata) {
|
|
|
901
923
|
}
|
|
902
924
|
}
|
|
903
925
|
const generationConfig = buildGenerationConfigFromParameters(chat.parameters || {});
|
|
926
|
+
if (responsesOrigin && Object.prototype.hasOwnProperty.call(parameters, 'reasoning')) {
|
|
927
|
+
appendLossyFieldAudit(chat, {
|
|
928
|
+
field: 'reasoning',
|
|
929
|
+
targetProtocol: 'gemini-chat',
|
|
930
|
+
reason: 'normalized_to_gemini_thinking_config'
|
|
931
|
+
});
|
|
932
|
+
}
|
|
904
933
|
if (semanticsNode?.generationConfig && isJsonObject(semanticsNode.generationConfig)) {
|
|
905
934
|
for (const [key, value] of Object.entries(semanticsNode.generationConfig)) {
|
|
906
935
|
if (generationConfig[key] !== undefined) {
|
|
@@ -1210,6 +1239,97 @@ function buildGenerationConfigFromParameters(parameters) {
|
|
|
1210
1239
|
config[source] = value;
|
|
1211
1240
|
}
|
|
1212
1241
|
}
|
|
1242
|
+
const reasoningRaw = parameters.reasoning;
|
|
1243
|
+
const applyThinkingDisabled = () => {
|
|
1244
|
+
config.thinkingConfig = {
|
|
1245
|
+
includeThoughts: false,
|
|
1246
|
+
thinkingBudget: 0
|
|
1247
|
+
};
|
|
1248
|
+
};
|
|
1249
|
+
const applyThinkingEnabled = (budget) => {
|
|
1250
|
+
const next = {
|
|
1251
|
+
includeThoughts: true
|
|
1252
|
+
};
|
|
1253
|
+
if (typeof budget === 'number' && Number.isFinite(budget) && budget > 0) {
|
|
1254
|
+
next.thinkingBudget = Math.floor(budget);
|
|
1255
|
+
}
|
|
1256
|
+
config.thinkingConfig = next;
|
|
1257
|
+
};
|
|
1258
|
+
if (typeof reasoningRaw === 'boolean') {
|
|
1259
|
+
if (reasoningRaw) {
|
|
1260
|
+
applyThinkingEnabled();
|
|
1261
|
+
}
|
|
1262
|
+
else {
|
|
1263
|
+
applyThinkingDisabled();
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
else if (typeof reasoningRaw === 'string') {
|
|
1267
|
+
const normalized = reasoningRaw.trim().toLowerCase();
|
|
1268
|
+
if (normalized === 'off' || normalized === 'none' || normalized === 'disabled' || normalized === 'false') {
|
|
1269
|
+
applyThinkingDisabled();
|
|
1270
|
+
}
|
|
1271
|
+
else if (normalized.length) {
|
|
1272
|
+
const effortBudget = {
|
|
1273
|
+
minimal: 1024,
|
|
1274
|
+
low: 1024,
|
|
1275
|
+
medium: 4096,
|
|
1276
|
+
high: 8192
|
|
1277
|
+
};
|
|
1278
|
+
applyThinkingEnabled(effortBudget[normalized]);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
else if (typeof reasoningRaw === 'number' && Number.isFinite(reasoningRaw)) {
|
|
1282
|
+
if (reasoningRaw <= 0) {
|
|
1283
|
+
applyThinkingDisabled();
|
|
1284
|
+
}
|
|
1285
|
+
else {
|
|
1286
|
+
applyThinkingEnabled(reasoningRaw);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
else if (isJsonObject(reasoningRaw)) {
|
|
1290
|
+
const node = reasoningRaw;
|
|
1291
|
+
const enabled = node.enabled;
|
|
1292
|
+
if (enabled === false) {
|
|
1293
|
+
applyThinkingDisabled();
|
|
1294
|
+
}
|
|
1295
|
+
else {
|
|
1296
|
+
const effort = typeof node.effort === 'string'
|
|
1297
|
+
? node.effort.trim().toLowerCase()
|
|
1298
|
+
: typeof node.level === 'string'
|
|
1299
|
+
? node.level.trim().toLowerCase()
|
|
1300
|
+
: '';
|
|
1301
|
+
const budget = typeof node.budget_tokens === 'number'
|
|
1302
|
+
? node.budget_tokens
|
|
1303
|
+
: typeof node.budget === 'number'
|
|
1304
|
+
? node.budget
|
|
1305
|
+
: typeof node.max_tokens === 'number'
|
|
1306
|
+
? node.max_tokens
|
|
1307
|
+
: undefined;
|
|
1308
|
+
if (typeof budget === 'number' && Number.isFinite(budget)) {
|
|
1309
|
+
if (budget <= 0) {
|
|
1310
|
+
applyThinkingDisabled();
|
|
1311
|
+
}
|
|
1312
|
+
else {
|
|
1313
|
+
applyThinkingEnabled(budget);
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
else if (effort === 'off' || effort === 'none' || effort === 'disabled') {
|
|
1317
|
+
applyThinkingDisabled();
|
|
1318
|
+
}
|
|
1319
|
+
else if (effort.length) {
|
|
1320
|
+
const effortBudget = {
|
|
1321
|
+
minimal: 1024,
|
|
1322
|
+
low: 1024,
|
|
1323
|
+
medium: 4096,
|
|
1324
|
+
high: 8192
|
|
1325
|
+
};
|
|
1326
|
+
applyThinkingEnabled(effortBudget[effort]);
|
|
1327
|
+
}
|
|
1328
|
+
else if (enabled === true) {
|
|
1329
|
+
applyThinkingEnabled();
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1213
1333
|
return config;
|
|
1214
1334
|
}
|
|
1215
1335
|
function mapChatRoleToGemini(role) {
|
|
@@ -1270,6 +1390,55 @@ function cloneAsJsonValue(value) {
|
|
|
1270
1390
|
return String(value ?? '');
|
|
1271
1391
|
}
|
|
1272
1392
|
}
|
|
1393
|
+
function isResponsesOrigin(chat) {
|
|
1394
|
+
const semantics = chat?.semantics;
|
|
1395
|
+
if (semantics && semantics.responses && isJsonObject(semantics.responses)) {
|
|
1396
|
+
return true;
|
|
1397
|
+
}
|
|
1398
|
+
const ctx = chat?.metadata && typeof chat.metadata === 'object'
|
|
1399
|
+
? chat.metadata.context
|
|
1400
|
+
: undefined;
|
|
1401
|
+
const protocol = typeof ctx?.providerProtocol === 'string' ? ctx.providerProtocol.trim().toLowerCase() : '';
|
|
1402
|
+
if (protocol === 'openai-responses') {
|
|
1403
|
+
return true;
|
|
1404
|
+
}
|
|
1405
|
+
const endpoint = typeof ctx?.entryEndpoint === 'string' ? ctx.entryEndpoint.trim().toLowerCase() : '';
|
|
1406
|
+
return endpoint === '/v1/responses';
|
|
1407
|
+
}
|
|
1408
|
+
function appendMappingAudit(chat, options) {
|
|
1409
|
+
const metadata = chat.metadata && typeof chat.metadata === 'object'
|
|
1410
|
+
? chat.metadata
|
|
1411
|
+
: (chat.metadata = { context: chat.metadata?.context ?? {} });
|
|
1412
|
+
const root = metadata.mappingAudit && typeof metadata.mappingAudit === 'object' && !Array.isArray(metadata.mappingAudit)
|
|
1413
|
+
? metadata.mappingAudit
|
|
1414
|
+
: (metadata.mappingAudit = {});
|
|
1415
|
+
const current = Array.isArray(root[options.bucket]) ? root[options.bucket] : [];
|
|
1416
|
+
const duplicate = current.find((entry) => entry &&
|
|
1417
|
+
entry.field === options.field &&
|
|
1418
|
+
entry.targetProtocol === options.targetProtocol &&
|
|
1419
|
+
entry.reason === options.reason);
|
|
1420
|
+
if (!duplicate) {
|
|
1421
|
+
current.push({
|
|
1422
|
+
field: options.field,
|
|
1423
|
+
source: options.source ?? 'chat.parameters',
|
|
1424
|
+
targetProtocol: options.targetProtocol,
|
|
1425
|
+
reason: options.reason
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
root[options.bucket] = current;
|
|
1429
|
+
}
|
|
1430
|
+
function appendDroppedFieldAudit(chat, options) {
|
|
1431
|
+
appendMappingAudit(chat, {
|
|
1432
|
+
bucket: 'dropped',
|
|
1433
|
+
...options
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1436
|
+
function appendLossyFieldAudit(chat, options) {
|
|
1437
|
+
appendMappingAudit(chat, {
|
|
1438
|
+
bucket: 'lossy',
|
|
1439
|
+
...options
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1273
1442
|
export class GeminiSemanticMapper {
|
|
1274
1443
|
async toChat(format, ctx) {
|
|
1275
1444
|
const payload = (format.payload ?? {});
|
|
@@ -6,11 +6,17 @@ const RESPONSES_PARAMETER_KEYS = [
|
|
|
6
6
|
'temperature',
|
|
7
7
|
'top_p',
|
|
8
8
|
'top_k',
|
|
9
|
+
'prompt_cache_key',
|
|
10
|
+
'reasoning',
|
|
9
11
|
'max_tokens',
|
|
10
12
|
'max_output_tokens',
|
|
11
13
|
'response_format',
|
|
12
14
|
'tool_choice',
|
|
13
15
|
'parallel_tool_calls',
|
|
16
|
+
'service_tier',
|
|
17
|
+
'truncation',
|
|
18
|
+
'include',
|
|
19
|
+
'store',
|
|
14
20
|
'user',
|
|
15
21
|
'logit_bias',
|
|
16
22
|
'seed',
|
|
@@ -15,6 +15,8 @@ import { applyGeminiWebSearchCompat } from '../../../compat/actions/gemini-web-s
|
|
|
15
15
|
import { applyIflowWebSearchRequestTransform } from '../../../compat/actions/iflow-web-search.js';
|
|
16
16
|
import { applyIflowToolTextFallback } from '../../../compat/actions/iflow-tool-text-fallback.js';
|
|
17
17
|
import { unwrapIflowResponseBodyEnvelope } from '../../../compat/actions/iflow-response-body-unwrap.js';
|
|
18
|
+
import { applyDeepSeekWebRequestTransform } from '../../../compat/actions/deepseek-web-request.js';
|
|
19
|
+
import { applyDeepSeekWebResponseTransform } from '../../../compat/actions/deepseek-web-response.js';
|
|
18
20
|
import { applyIflowKimiHistoryMediaPlaceholder } from '../../../compat/actions/iflow-kimi-history-media-placeholder.js';
|
|
19
21
|
import { applyIflowKimiCliDefaults } from '../../../compat/actions/iflow-kimi-cli-defaults.js';
|
|
20
22
|
import { fillIflowKimiThinkingReasoningContent } from '../../../compat/actions/iflow-kimi-thinking-reasoning-fill.js';
|
|
@@ -267,6 +269,16 @@ function applyMapping(root, mapping, state) {
|
|
|
267
269
|
replaceRoot(root, unwrapIflowResponseBodyEnvelope(root));
|
|
268
270
|
}
|
|
269
271
|
break;
|
|
272
|
+
case 'deepseek_web_request':
|
|
273
|
+
if (state.direction === 'request') {
|
|
274
|
+
replaceRoot(root, applyDeepSeekWebRequestTransform(root, state.adapterContext));
|
|
275
|
+
}
|
|
276
|
+
break;
|
|
277
|
+
case 'deepseek_web_response':
|
|
278
|
+
if (state.direction === 'response') {
|
|
279
|
+
replaceRoot(root, applyDeepSeekWebResponseTransform(root, state.adapterContext));
|
|
280
|
+
}
|
|
281
|
+
break;
|
|
270
282
|
case 'claude_thinking_tool_schema':
|
|
271
283
|
if (state.direction === 'request') {
|
|
272
284
|
replaceRoot(root, applyClaudeThinkingToolSchemaCompat(root, state.adapterContext));
|
|
@@ -132,6 +132,10 @@ export type MappingInstruction = {
|
|
|
132
132
|
models?: string[];
|
|
133
133
|
} | {
|
|
134
134
|
action: 'iflow_response_body_unwrap';
|
|
135
|
+
} | {
|
|
136
|
+
action: 'deepseek_web_request';
|
|
137
|
+
} | {
|
|
138
|
+
action: 'deepseek_web_response';
|
|
135
139
|
} | {
|
|
136
140
|
action: 'claude_thinking_tool_schema';
|
|
137
141
|
} | {
|