@jsonstudio/llms 0.6.3238 → 0.6.3275

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 (27) hide show
  1. package/dist/conversion/bridge-actions.js +37 -322
  2. package/dist/conversion/bridge-instructions.js +12 -109
  3. package/dist/conversion/codecs/anthropic-openai-codec.js +1 -1
  4. package/dist/conversion/compat/actions/anthropic-claude-code-system-prompt.js +38 -0
  5. package/dist/conversion/compat/actions/deepseek-web-request.js +43 -110
  6. package/dist/conversion/compat/actions/deepseek-web-response.d.ts +3 -0
  7. package/dist/conversion/compat/actions/deepseek-web-response.js +150 -11
  8. package/dist/conversion/hub/response/response-runtime.d.ts +1 -0
  9. package/dist/conversion/hub/response/response-runtime.js +26 -0
  10. package/dist/conversion/shared/anthropic-message-utils.d.ts +3 -1
  11. package/dist/conversion/shared/anthropic-message-utils.js +23 -15
  12. package/dist/conversion/shared/openai-finalizer.d.ts +0 -3
  13. package/dist/conversion/shared/openai-finalizer.js +11 -169
  14. package/dist/conversion/shared/openai-message-normalize.js +11 -72
  15. package/dist/conversion/shared/tool-mapping.js +5 -0
  16. package/dist/native/router_hotpath_napi.node +0 -0
  17. package/dist/router/virtual-router/bootstrap/provider-normalization.js +11 -3
  18. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.d.ts +20 -0
  19. package/dist/router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js +71 -0
  20. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.d.ts +1 -0
  21. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js +30 -0
  22. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +6 -0
  23. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +2 -0
  24. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +61 -0
  25. package/dist/router/virtual-router/engine.js +58 -1
  26. package/dist/router/virtual-router/types.d.ts +1 -1
  27. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { applyBridgeCaptureToolResultsWithNative, applyBridgeEnsureToolPlaceholdersWithNative, applyBridgeNormalizeHistoryWithNative, applyBridgeNormalizeToolIdentifiersWithNative, applyBridgeEnsureSystemInstructionWithNative, applyBridgeInjectSystemInstructionWithNative, applyBridgeMetadataActionWithNative, applyBridgeReasoningExtractWithNative, applyBridgeResponsesOutputReasoningWithNative, ensureBridgeOutputFieldsWithNative } from '../router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js';
1
+ import { runBridgeActionPipelineWithNative } from '../router/virtual-router/engine-selection/native-hub-bridge-action-semantics.js';
2
2
  const registry = new Map();
3
3
  export function registerBridgeAction(name, action) {
4
4
  registry.set(name, action);
@@ -23,6 +23,42 @@ export function runBridgeActionPipeline(options) {
23
23
  const { stage, actions, protocol, moduleType, requestId, state } = options;
24
24
  if (!actions?.length)
25
25
  return;
26
+ const output = runBridgeActionPipelineWithNative({
27
+ stage,
28
+ actions: actions.map((entry) => ({
29
+ name: entry.name,
30
+ options: entry.options
31
+ })),
32
+ protocol,
33
+ moduleType,
34
+ requestId,
35
+ state: state
36
+ });
37
+ if (!output) {
38
+ return;
39
+ }
40
+ if (output && typeof output === 'object') {
41
+ const next = output;
42
+ const patch = {
43
+ messages: Array.isArray(next.messages) ? next.messages : state.messages,
44
+ ...(next.requiredAction && typeof next.requiredAction === 'object' && !Array.isArray(next.requiredAction)
45
+ ? { requiredAction: next.requiredAction }
46
+ : {}),
47
+ ...(Array.isArray(next.capturedToolResults)
48
+ ? { capturedToolResults: next.capturedToolResults }
49
+ : {}),
50
+ ...(next.rawRequest && typeof next.rawRequest === 'object' && !Array.isArray(next.rawRequest)
51
+ ? { rawRequest: next.rawRequest }
52
+ : {}),
53
+ ...(next.rawResponse && typeof next.rawResponse === 'object' && !Array.isArray(next.rawResponse)
54
+ ? { rawResponse: next.rawResponse }
55
+ : {}),
56
+ ...(next.metadata && typeof next.metadata === 'object' && !Array.isArray(next.metadata)
57
+ ? { metadata: next.metadata }
58
+ : {})
59
+ };
60
+ Object.assign(state, patch);
61
+ }
26
62
  for (const descriptor of actions) {
27
63
  if (!descriptor || typeof descriptor !== 'object')
28
64
  continue;
@@ -44,324 +80,3 @@ export function runBridgeActionPipeline(options) {
44
80
  }
45
81
  }
46
82
  }
47
- function ensureMessagesArray(state) {
48
- if (!Array.isArray(state.messages)) {
49
- state.messages = [];
50
- }
51
- return state.messages;
52
- }
53
- function ensureMetadataRecord(state) {
54
- if (!state.metadata || typeof state.metadata !== 'object') {
55
- state.metadata = {};
56
- }
57
- return state.metadata;
58
- }
59
- const injectSystemInstructionAction = (ctx) => {
60
- const messages = ensureMessagesArray(ctx.state);
61
- const normalized = applyBridgeInjectSystemInstructionWithNative({
62
- stage: ctx.stage,
63
- options: ctx.descriptor.options && typeof ctx.descriptor.options === 'object'
64
- ? ctx.descriptor.options
65
- : undefined,
66
- messages,
67
- rawRequest: ctx.state.rawRequest && typeof ctx.state.rawRequest === 'object'
68
- ? ctx.state.rawRequest
69
- : undefined
70
- });
71
- if (Array.isArray(normalized.messages)) {
72
- applyMessagesInPlace(messages, normalized.messages);
73
- ctx.state.messages = messages;
74
- }
75
- };
76
- const ensureToolResponsePlaceholders = (ctx) => {
77
- const messages = ensureMessagesArray(ctx.state);
78
- if (!messages.length)
79
- return;
80
- const output = applyBridgeEnsureToolPlaceholdersWithNative({
81
- stage: ctx.stage,
82
- messages,
83
- capturedToolResults: Array.isArray(ctx.state.capturedToolResults)
84
- ? ctx.state.capturedToolResults
85
- : undefined,
86
- rawRequest: ctx.state.rawRequest && typeof ctx.state.rawRequest === 'object'
87
- ? ctx.state.rawRequest
88
- : undefined,
89
- rawResponse: ctx.state.rawResponse && typeof ctx.state.rawResponse === 'object'
90
- ? ctx.state.rawResponse
91
- : undefined
92
- });
93
- if (Array.isArray(output.messages)) {
94
- applyMessagesInPlace(messages, output.messages);
95
- ctx.state.messages = messages;
96
- }
97
- ctx.state.capturedToolResults = applyCapturedToolResultsInPlace(ctx.state.capturedToolResults, output.toolOutputs);
98
- };
99
- const extractReasoningAction = (ctx) => {
100
- const messages = ensureMessagesArray(ctx.state);
101
- if (!messages.length)
102
- return;
103
- const dropFromContent = ctx.descriptor.options?.dropFromContent !== false;
104
- const idPrefixBase = typeof ctx.descriptor.options?.idPrefix === 'string' && ctx.descriptor.options.idPrefix.trim().length
105
- ? ctx.descriptor.options.idPrefix.trim()
106
- : `${ctx.protocol ?? 'bridge'}_${ctx.stage}`;
107
- const normalized = applyBridgeReasoningExtractWithNative({
108
- messages,
109
- dropFromContent,
110
- idPrefixBase
111
- });
112
- if (Array.isArray(normalized.messages)) {
113
- applyMessagesInPlace(messages, normalized.messages);
114
- ctx.state.messages = messages;
115
- }
116
- };
117
- registerBridgeAction('messages.inject-system-instruction', injectSystemInstructionAction);
118
- registerBridgeAction('reasoning.extract', extractReasoningAction);
119
- registerBridgeAction('tools.ensure-response-placeholders', ensureToolResponsePlaceholders);
120
- // (intentionally no-op: capture handled in responses-format normalization)
121
- const ensureSystemInstructionAction = (ctx) => {
122
- const messages = ensureMessagesArray(ctx.state);
123
- const normalized = applyBridgeEnsureSystemInstructionWithNative({
124
- stage: ctx.stage,
125
- messages,
126
- metadata: ctx.state.metadata && typeof ctx.state.metadata === 'object'
127
- ? ctx.state.metadata
128
- : undefined
129
- });
130
- if (Array.isArray(normalized.messages)) {
131
- applyMessagesInPlace(messages, normalized.messages);
132
- ctx.state.messages = messages;
133
- }
134
- const metadata = applyObjectInPlace(ctx.state.metadata, normalized.metadata);
135
- if (metadata) {
136
- ctx.state.metadata = metadata;
137
- }
138
- };
139
- const normalizeHistoryAction = (ctx) => {
140
- if (ctx.stage !== 'request_outbound') {
141
- return;
142
- }
143
- const messages = ensureMessagesArray(ctx.state);
144
- if (!messages.length) {
145
- return;
146
- }
147
- const toolsNode = ctx.state.rawRequest &&
148
- typeof ctx.state.rawRequest === 'object' &&
149
- Array.isArray(ctx.state.rawRequest.tools)
150
- ? ctx.state.rawRequest.tools
151
- : undefined;
152
- const normalized = applyBridgeNormalizeHistoryWithNative({
153
- messages,
154
- tools: toolsNode
155
- });
156
- if (Array.isArray(normalized.messages)) {
157
- applyMessagesInPlace(messages, normalized.messages);
158
- ctx.state.messages = messages;
159
- }
160
- if (normalized.bridgeHistory && typeof normalized.bridgeHistory === 'object' && !Array.isArray(normalized.bridgeHistory)) {
161
- const metadata = ensureMetadataRecord(ctx.state);
162
- metadata.bridgeHistory = normalized.bridgeHistory;
163
- }
164
- };
165
- const ensureOutputFieldsAction = (ctx) => {
166
- if (ctx.stage !== 'request_outbound') {
167
- return;
168
- }
169
- const messages = ensureMessagesArray(ctx.state);
170
- if (!messages.length) {
171
- return;
172
- }
173
- const fallback = typeof ctx.descriptor.options?.toolFallback === 'string' && ctx.descriptor.options.toolFallback.trim().length
174
- ? ctx.descriptor.options.toolFallback.trim()
175
- : 'Tool call completed (no output).';
176
- const assistantFallback = typeof ctx.descriptor.options?.assistantFallback === 'string' && ctx.descriptor.options.assistantFallback.trim().length
177
- ? ctx.descriptor.options.assistantFallback.trim()
178
- : 'Assistant response unavailable.';
179
- const normalized = ensureBridgeOutputFieldsWithNative({
180
- messages,
181
- toolFallback: fallback,
182
- assistantFallback
183
- });
184
- if (Array.isArray(normalized.messages)) {
185
- applyMessagesInPlace(messages, normalized.messages);
186
- ctx.state.messages = messages;
187
- }
188
- };
189
- const ensureToolPlaceholdersAction = (ctx) => {
190
- ensureToolResponsePlaceholders(ctx);
191
- };
192
- const captureToolResultsAction = (ctx) => {
193
- const output = applyBridgeCaptureToolResultsWithNative({
194
- stage: ctx.stage,
195
- capturedToolResults: Array.isArray(ctx.state.capturedToolResults)
196
- ? ctx.state.capturedToolResults
197
- : undefined,
198
- rawRequest: ctx.state.rawRequest && typeof ctx.state.rawRequest === 'object'
199
- ? ctx.state.rawRequest
200
- : undefined,
201
- rawResponse: ctx.state.rawResponse && typeof ctx.state.rawResponse === 'object'
202
- ? ctx.state.rawResponse
203
- : undefined,
204
- metadata: ctx.state.metadata && typeof ctx.state.metadata === 'object'
205
- ? ctx.state.metadata
206
- : undefined
207
- });
208
- ctx.state.capturedToolResults = applyCapturedToolResultsInPlace(ctx.state.capturedToolResults, output.capturedToolResults);
209
- const metadata = applyObjectInPlace(ctx.state.metadata, output.metadata);
210
- if (metadata) {
211
- ctx.state.metadata = metadata;
212
- }
213
- };
214
- const attachReasoningOutputAction = (ctx) => {
215
- responsesOutputReasoningAction(ctx);
216
- };
217
- registerBridgeAction('messages.ensure-system-instruction', ensureSystemInstructionAction);
218
- registerBridgeAction('messages.normalize-history', normalizeHistoryAction);
219
- registerBridgeAction('messages.ensure-output-fields', ensureOutputFieldsAction);
220
- registerBridgeAction('tools.ensure-placeholders', ensureToolPlaceholdersAction);
221
- registerBridgeAction('tools.capture-results', captureToolResultsAction);
222
- registerBridgeAction('reasoning.attach-output', attachReasoningOutputAction);
223
- function deriveToolIdPrefix(ctx) {
224
- if (typeof ctx.descriptor.options?.idPrefix === 'string' && ctx.descriptor.options.idPrefix.trim().length) {
225
- return ctx.descriptor.options.idPrefix.trim();
226
- }
227
- if (typeof ctx.requestId === 'string' && ctx.requestId.trim().length) {
228
- const safe = ctx.requestId.trim().replace(/[^A-Za-z0-9]/g, '');
229
- if (safe.length) {
230
- return `${safe.slice(-24)}_tool`;
231
- }
232
- }
233
- const base = ctx.protocol || 'bridge';
234
- return `${base}_tool`;
235
- }
236
- function overwriteRecordInPlace(target, source) {
237
- for (const key of Object.keys(target)) {
238
- delete target[key];
239
- }
240
- for (const [key, value] of Object.entries(source)) {
241
- target[key] = value;
242
- }
243
- }
244
- function applyMessagesInPlace(current, next) {
245
- const normalizedNext = next.filter((entry) => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry));
246
- const nextLength = normalizedNext.length;
247
- for (let i = 0; i < nextLength; i++) {
248
- const nextEntry = normalizedNext[i];
249
- const currentEntry = current[i];
250
- if (currentEntry && typeof currentEntry === 'object' && !Array.isArray(currentEntry)) {
251
- overwriteRecordInPlace(currentEntry, nextEntry);
252
- continue;
253
- }
254
- current[i] = { ...nextEntry };
255
- }
256
- if (current.length > nextLength) {
257
- current.splice(nextLength);
258
- }
259
- }
260
- function applyObjectInPlace(current, next) {
261
- if (!next || typeof next !== 'object' || Array.isArray(next)) {
262
- return undefined;
263
- }
264
- const nextRecord = next;
265
- if (current && typeof current === 'object' && !Array.isArray(current)) {
266
- overwriteRecordInPlace(current, nextRecord);
267
- return current;
268
- }
269
- return { ...nextRecord };
270
- }
271
- function applyCapturedToolResultsInPlace(current, next) {
272
- if (!Array.isArray(next)) {
273
- return current;
274
- }
275
- const normalizedNext = next
276
- .filter((entry) => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry))
277
- .map((entry) => ({ ...entry }));
278
- if (!Array.isArray(current)) {
279
- return normalizedNext;
280
- }
281
- current.splice(0, current.length, ...normalizedNext);
282
- return current;
283
- }
284
- const normalizeToolIdentifiersAction = (ctx) => {
285
- const messages = ensureMessagesArray(ctx.state);
286
- const idPrefix = deriveToolIdPrefix(ctx);
287
- const normalized = applyBridgeNormalizeToolIdentifiersWithNative({
288
- stage: ctx.stage,
289
- protocol: ctx.protocol,
290
- moduleType: ctx.moduleType,
291
- messages,
292
- rawRequest: ctx.state.rawRequest,
293
- capturedToolResults: Array.isArray(ctx.state.capturedToolResults)
294
- ? ctx.state.capturedToolResults
295
- : undefined,
296
- idPrefix
297
- });
298
- if (Array.isArray(normalized.messages)) {
299
- applyMessagesInPlace(messages, normalized.messages);
300
- ctx.state.messages = messages;
301
- }
302
- const rawRequest = applyObjectInPlace(ctx.state.rawRequest, normalized.rawRequest);
303
- if (rawRequest) {
304
- ctx.state.rawRequest = rawRequest;
305
- }
306
- ctx.state.capturedToolResults = applyCapturedToolResultsInPlace(ctx.state.capturedToolResults, normalized.capturedToolResults);
307
- };
308
- registerBridgeAction('tools.normalize-call-ids', normalizeToolIdentifiersAction);
309
- const responsesOutputReasoningAction = (ctx) => {
310
- if (ctx.stage !== 'response_inbound')
311
- return;
312
- const messages = ensureMessagesArray(ctx.state);
313
- const normalized = applyBridgeResponsesOutputReasoningWithNative({
314
- messages,
315
- rawResponse: ctx.state.rawResponse && typeof ctx.state.rawResponse === 'object'
316
- ? ctx.state.rawResponse
317
- : undefined,
318
- idPrefix: `${ctx.protocol ?? 'responses'}_${ctx.stage}_output`
319
- });
320
- if (Array.isArray(normalized.messages)) {
321
- applyMessagesInPlace(messages, normalized.messages);
322
- ctx.state.messages = messages;
323
- }
324
- };
325
- registerBridgeAction('responses.output-reasoning', responsesOutputReasoningAction);
326
- function applyMetadataActionWithNative(ctx, actionName) {
327
- const output = applyBridgeMetadataActionWithNative({
328
- actionName,
329
- stage: ctx.stage,
330
- options: ctx.descriptor.options && typeof ctx.descriptor.options === 'object'
331
- ? ctx.descriptor.options
332
- : undefined,
333
- rawRequest: ctx.state.rawRequest && typeof ctx.state.rawRequest === 'object'
334
- ? ctx.state.rawRequest
335
- : undefined,
336
- rawResponse: ctx.state.rawResponse && typeof ctx.state.rawResponse === 'object'
337
- ? ctx.state.rawResponse
338
- : undefined,
339
- metadata: ctx.state.metadata && typeof ctx.state.metadata === 'object'
340
- ? ctx.state.metadata
341
- : undefined
342
- });
343
- const rawRequest = applyObjectInPlace(ctx.state.rawRequest, output.rawRequest);
344
- if (rawRequest) {
345
- ctx.state.rawRequest = rawRequest;
346
- }
347
- const rawResponse = applyObjectInPlace(ctx.state.rawResponse, output.rawResponse);
348
- if (rawResponse) {
349
- ctx.state.rawResponse = rawResponse;
350
- }
351
- const metadata = applyObjectInPlace(ctx.state.metadata, output.metadata);
352
- if (metadata) {
353
- ctx.state.metadata = metadata;
354
- }
355
- }
356
- const metadataExtraFieldsAction = (ctx) => {
357
- applyMetadataActionWithNative(ctx, 'metadata.extra-fields');
358
- };
359
- const metadataProviderFieldAction = (ctx) => {
360
- applyMetadataActionWithNative(ctx, 'metadata.provider-field');
361
- };
362
- const metadataProviderSentinelAction = (ctx) => {
363
- applyMetadataActionWithNative(ctx, 'metadata.provider-sentinel');
364
- };
365
- registerBridgeAction('metadata.extra-fields', metadataExtraFieldsAction);
366
- registerBridgeAction('metadata.provider-field', metadataProviderFieldAction);
367
- registerBridgeAction('metadata.provider-sentinel', metadataProviderSentinelAction);
@@ -1,114 +1,17 @@
1
- import { sanitizeReasoningTaggedTextWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
- function collectTextFromBlocks(blocks) {
3
- const parts = [];
4
- for (const block of blocks) {
5
- if (!block || typeof block !== 'object')
6
- continue;
7
- const type = typeof block.type === 'string' ? block.type.toLowerCase() : '';
8
- if ((type === 'input_text' || type === 'output_text' || type === 'text' || type === 'commentary') && typeof block.text === 'string') {
9
- const text = block.text.trim();
10
- if (text)
11
- parts.push(text);
12
- continue;
13
- }
14
- if (type === 'message' && Array.isArray(block.content)) {
15
- const nested = collectTextFromBlocks(block.content);
16
- if (nested)
17
- parts.push(nested);
18
- continue;
19
- }
20
- if (typeof block.content === 'string') {
21
- const text = block.content.trim();
22
- if (text)
23
- parts.push(text);
24
- continue;
25
- }
26
- if (Array.isArray(block.content)) {
27
- const nested = collectTextFromBlocks(block.content);
28
- if (nested)
29
- parts.push(nested);
30
- continue;
31
- }
32
- if (typeof block.text === 'string') {
33
- const text = block.text.trim();
34
- if (text)
35
- parts.push(text);
36
- }
37
- }
38
- return parts.join('\n');
39
- }
40
- function extractSystemInstruction(entry) {
41
- if (!entry || typeof entry !== 'object')
42
- return null;
43
- const roleSource = entry.role ?? entry.message?.role;
44
- const role = typeof roleSource === 'string' ? roleSource.toLowerCase() : '';
45
- if (role !== 'system')
46
- return null;
47
- const collected = [];
48
- if (Array.isArray(entry.content)) {
49
- const text = collectTextFromBlocks(entry.content);
50
- if (text.trim())
51
- collected.push(text.trim());
52
- }
53
- else if (typeof entry.content === 'string') {
54
- const text = entry.content.trim();
55
- if (text)
56
- collected.push(text);
57
- }
58
- if (typeof entry.text === 'string') {
59
- const text = entry.text.trim();
60
- if (text)
61
- collected.push(text);
62
- }
63
- const message = entry.message;
64
- if (message && typeof message === 'object') {
65
- if (Array.isArray(message.content)) {
66
- const text = collectTextFromBlocks(message.content);
67
- if (text.trim())
68
- collected.push(text.trim());
69
- }
70
- else if (typeof message.content === 'string') {
71
- const text = message.content.trim();
72
- if (text)
73
- collected.push(text);
1
+ import { ensureBridgeInstructionsWithNative } from '../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
+ export function ensureBridgeInstructions(payload) {
3
+ const normalized = ensureBridgeInstructionsWithNative(payload);
4
+ if (normalized && typeof normalized === 'object') {
5
+ if (Object.prototype.hasOwnProperty.call(normalized, 'input')) {
6
+ payload.input = normalized.input;
74
7
  }
75
- if (typeof message.text === 'string') {
76
- const text = String(message.text).trim();
77
- if (text)
78
- collected.push(text);
8
+ if (Object.prototype.hasOwnProperty.call(normalized, 'instructions')) {
9
+ payload.instructions = normalized.instructions;
79
10
  }
80
- }
81
- const merged = sanitizeReasoningTaggedTextWithNative(collected.join('\n')).trim();
82
- return merged ? merged : null;
83
- }
84
- export function ensureBridgeInstructions(payload) {
85
- let instructions = typeof payload.instructions === 'string' ? payload.instructions : '';
86
- const hasClientInstruction = typeof payload.instructions === 'string' && payload.instructions.length > 0;
87
- const input = Array.isArray(payload.input) ? payload.input : undefined;
88
- if (input && input.length) {
89
- for (let i = 0; i < input.length; i += 1) {
90
- const entry = input[i];
91
- const roleSource = entry?.role ?? entry?.message?.role;
92
- const role = typeof roleSource === 'string' ? roleSource.toLowerCase() : '';
93
- if (role === 'system') {
94
- const text = extractSystemInstruction(entry);
95
- input.splice(i, 1);
96
- i -= 1;
97
- if (text && text.trim()) {
98
- if (!hasClientInstruction && !instructions) {
99
- instructions = text.trim();
100
- }
101
- }
102
- continue;
103
- }
11
+ else if (Object.prototype.hasOwnProperty.call(payload, 'instructions')) {
12
+ delete payload.instructions;
104
13
  }
105
14
  }
106
- if (instructions) {
107
- payload.instructions = instructions;
108
- return instructions;
109
- }
110
- if (typeof payload.instructions !== 'undefined') {
111
- delete payload.instructions;
112
- }
113
- return undefined;
15
+ const instructions = payload.instructions;
16
+ return typeof instructions === 'string' && instructions.length ? instructions : undefined;
114
17
  }
@@ -17,7 +17,7 @@ export class AnthropicOpenAIConversionCodec {
17
17
  await this.initialize();
18
18
  }
19
19
  const model = String(payload?.model || 'unknown');
20
- const { messages } = buildOpenAIChatFromAnthropic(payload);
20
+ const { messages } = buildOpenAIChatFromAnthropic(payload, { includeToolCallIds: true });
21
21
  const out = { model, messages };
22
22
  const aliasMap = buildAnthropicToolAliasMap(payload?.tools);
23
23
  if (aliasMap) {
@@ -16,6 +16,42 @@ function readTrimmedString(value) {
16
16
  const trimmed = value.trim();
17
17
  return trimmed.length ? trimmed : undefined;
18
18
  }
19
+ function shouldInjectThinking(value) {
20
+ if (value === undefined || value === null) {
21
+ return true;
22
+ }
23
+ if (typeof value === 'boolean') {
24
+ return value !== false;
25
+ }
26
+ if (isRecord(value)) {
27
+ const type = readTrimmedString(value.type);
28
+ return !type;
29
+ }
30
+ if (typeof value === 'string') {
31
+ return value.trim().length === 0;
32
+ }
33
+ return true;
34
+ }
35
+ function resolveEffort(model) {
36
+ const modelId = readTrimmedString(model)?.toLowerCase() || '';
37
+ return modelId.startsWith('glm-5') ? 'high' : 'medium';
38
+ }
39
+ function ensureAdaptiveThinking(root) {
40
+ if (shouldInjectThinking(root.thinking)) {
41
+ root.thinking = { type: 'adaptive' };
42
+ }
43
+ }
44
+ function ensureOutputEffort(root) {
45
+ const effort = resolveEffort(root.model);
46
+ if (isRecord(root.output_config)) {
47
+ const outputConfig = root.output_config;
48
+ if (!readTrimmedString(outputConfig.effort)) {
49
+ outputConfig.effort = effort;
50
+ }
51
+ return;
52
+ }
53
+ root.output_config = { effort };
54
+ }
19
55
  function isClaudeCodeUserId(value) {
20
56
  const trimmed = readTrimmedString(value);
21
57
  if (!trimmed)
@@ -209,6 +245,8 @@ export function applyAnthropicClaudeCodeSystemPromptCompat(payload, config, adap
209
245
  .filter((b) => b.text !== systemText);
210
246
  // Normalize: force system into a single text block.
211
247
  root.system = [{ type: 'text', text: systemText }];
248
+ ensureAdaptiveThinking(root);
249
+ ensureOutputEffort(root);
212
250
  if (preserveExisting && existingBlocks.length) {
213
251
  const messages = Array.isArray(root.messages) ? root.messages : [];
214
252
  if (messages.length || root.messages !== undefined) {