@jsonstudio/llms 0.6.3686 → 0.6.3689

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.
@@ -1,4 +1,303 @@
1
+ import { ensureProtocolState } from '../../../protocol-state.js';
2
+ import { isJsonObject, jsonClone } from '../../types/json.js';
1
3
  import { mapOpenaiChatFromChatWithNative, mapOpenaiChatToChatWithNative } from '../../../../router/virtual-router/engine-selection/native-hub-pipeline-semantic-mappers.js';
4
+ import { mapReqInboundBridgeToolsToChatWithNative } from '../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-inbound-semantics.js';
5
+ const CHAT_PARAMETER_KEYS = [
6
+ 'model',
7
+ 'temperature',
8
+ 'top_p',
9
+ 'top_k',
10
+ 'max_tokens',
11
+ 'frequency_penalty',
12
+ 'presence_penalty',
13
+ 'logit_bias',
14
+ 'response_format',
15
+ 'parallel_tool_calls',
16
+ 'tool_choice',
17
+ 'seed',
18
+ 'user',
19
+ 'metadata',
20
+ 'stop',
21
+ 'stop_sequences',
22
+ 'stream'
23
+ ];
24
+ const KNOWN_TOP_LEVEL_FIELDS = new Set([
25
+ 'messages',
26
+ 'tools',
27
+ 'tool_outputs',
28
+ ...CHAT_PARAMETER_KEYS,
29
+ 'stageExpectations',
30
+ 'stages'
31
+ ]);
32
+ function flattenSystemContent(content) {
33
+ if (typeof content === 'string') {
34
+ return content;
35
+ }
36
+ if (Array.isArray(content)) {
37
+ return content.map(flattenSystemContent).filter(Boolean).join('\n');
38
+ }
39
+ if (content && typeof content === 'object') {
40
+ const row = content;
41
+ if (typeof row.text === 'string') {
42
+ return row.text;
43
+ }
44
+ if (typeof row.content === 'string') {
45
+ return row.content;
46
+ }
47
+ if (Array.isArray(row.content)) {
48
+ return row.content.map(flattenSystemContent).filter(Boolean).join('\n');
49
+ }
50
+ }
51
+ return '';
52
+ }
53
+ function normalizeToolContent(content) {
54
+ if (content === null || content === undefined) {
55
+ return '执行成功(无输出)';
56
+ }
57
+ if (typeof content === 'string') {
58
+ return content.trim().length ? content : '执行成功(无输出)';
59
+ }
60
+ if (typeof content === 'object') {
61
+ try {
62
+ return JSON.stringify(content);
63
+ }
64
+ catch {
65
+ return String(content);
66
+ }
67
+ }
68
+ return String(content);
69
+ }
70
+ function isEmptyAssistantContent(content) {
71
+ if (content === null || content === undefined) {
72
+ return true;
73
+ }
74
+ if (typeof content === 'string') {
75
+ return content.trim().length === 0;
76
+ }
77
+ if (Array.isArray(content)) {
78
+ const joined = content
79
+ .filter((entry) => Boolean(entry) && typeof entry === 'object' && !Array.isArray(entry))
80
+ .map((entry) => (typeof entry.text === 'string' ? entry.text : ''))
81
+ .join('');
82
+ return joined.trim().length === 0;
83
+ }
84
+ return false;
85
+ }
86
+ function collectSystemRawBlocks(raw) {
87
+ if (!Array.isArray(raw)) {
88
+ return undefined;
89
+ }
90
+ const blocks = [];
91
+ for (const entry of raw) {
92
+ if (!isJsonObject(entry)) {
93
+ continue;
94
+ }
95
+ if (String(entry.role ?? '').toLowerCase() !== 'system') {
96
+ continue;
97
+ }
98
+ blocks.push(jsonClone(entry));
99
+ }
100
+ return blocks.length ? blocks : undefined;
101
+ }
102
+ function collectExtraFields(payload) {
103
+ const extras = {};
104
+ for (const [key, value] of Object.entries(payload)) {
105
+ if (KNOWN_TOP_LEVEL_FIELDS.has(key) || value === undefined) {
106
+ continue;
107
+ }
108
+ extras[key] = jsonClone(value);
109
+ }
110
+ return Object.keys(extras).length ? extras : undefined;
111
+ }
112
+ function extractParameters(payload) {
113
+ const parameters = {};
114
+ for (const key of CHAT_PARAMETER_KEYS) {
115
+ if (payload[key] !== undefined) {
116
+ parameters[key] = payload[key];
117
+ }
118
+ }
119
+ return Object.keys(parameters).length ? parameters : undefined;
120
+ }
121
+ function buildOpenaiSemantics(systemSegments, extraFields, explicitEmptyTools) {
122
+ const semantics = {};
123
+ if (systemSegments.length > 0) {
124
+ semantics.system = {
125
+ textBlocks: systemSegments
126
+ };
127
+ }
128
+ if (extraFields && Object.keys(extraFields).length > 0) {
129
+ semantics.providerExtras = {
130
+ openaiChat: {
131
+ extraFields
132
+ }
133
+ };
134
+ }
135
+ if (explicitEmptyTools) {
136
+ semantics.tools = {
137
+ explicitEmpty: true
138
+ };
139
+ }
140
+ return Object.keys(semantics).length > 0 ? semantics : undefined;
141
+ }
142
+ function normalizeAssistantToolCallsFast(message) {
143
+ if (message.tool_calls === undefined) {
144
+ return undefined;
145
+ }
146
+ if (!Array.isArray(message.tool_calls)) {
147
+ return null;
148
+ }
149
+ const normalized = [];
150
+ for (const entry of message.tool_calls) {
151
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
152
+ return null;
153
+ }
154
+ const toolCall = entry;
155
+ const functionNode = toolCall.function && typeof toolCall.function === 'object' && !Array.isArray(toolCall.function)
156
+ ? toolCall.function
157
+ : undefined;
158
+ if (!functionNode) {
159
+ return null;
160
+ }
161
+ const rawName = typeof functionNode.name === 'string' ? functionNode.name.trim() : '';
162
+ if (!rawName) {
163
+ return null;
164
+ }
165
+ const rawArguments = functionNode.arguments;
166
+ if (rawArguments !== undefined && rawArguments !== null && typeof rawArguments !== 'string') {
167
+ return null;
168
+ }
169
+ const dot = rawName.indexOf('.');
170
+ const normalizedName = dot >= 0 ? rawName.slice(dot + 1).trim() : rawName;
171
+ if (!normalizedName) {
172
+ return null;
173
+ }
174
+ normalized.push({
175
+ ...toolCall,
176
+ function: {
177
+ ...functionNode,
178
+ name: normalizedName,
179
+ arguments: typeof rawArguments === 'string' ? rawArguments : '{}'
180
+ }
181
+ });
182
+ }
183
+ return normalized;
184
+ }
185
+ function normalizeToolDefinitionsFast(rawTools) {
186
+ if (rawTools === undefined) {
187
+ return undefined;
188
+ }
189
+ if (!Array.isArray(rawTools)) {
190
+ return null;
191
+ }
192
+ if (rawTools.length === 0) {
193
+ return undefined;
194
+ }
195
+ const mapped = mapReqInboundBridgeToolsToChatWithNative(rawTools);
196
+ return mapped.length > 0 ? mapped : null;
197
+ }
198
+ function tryMapOpenaiChatToChatFast(payload, ctx) {
199
+ if (!Array.isArray(payload.messages) || payload.tool_outputs !== undefined) {
200
+ return undefined;
201
+ }
202
+ const normalizedMessages = [];
203
+ const toolOutputs = [];
204
+ const seenToolOutputIds = new Set();
205
+ const systemSegments = [];
206
+ for (const entry of payload.messages) {
207
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
208
+ return undefined;
209
+ }
210
+ const message = entry;
211
+ const role = typeof message.role === 'string' ? message.role.trim().toLowerCase() : '';
212
+ if (role !== 'system' && role !== 'user' && role !== 'assistant' && role !== 'tool') {
213
+ return undefined;
214
+ }
215
+ const nextMessage = {
216
+ ...jsonClone(message),
217
+ role: role
218
+ };
219
+ if (role === 'assistant') {
220
+ const normalizedToolCalls = normalizeAssistantToolCallsFast(message);
221
+ if (normalizedToolCalls === null) {
222
+ return undefined;
223
+ }
224
+ if (normalizedToolCalls !== undefined) {
225
+ nextMessage.tool_calls = normalizedToolCalls;
226
+ }
227
+ const content = nextMessage.content;
228
+ if (content !== undefined &&
229
+ content !== null &&
230
+ typeof content !== 'string' &&
231
+ !Array.isArray(content) &&
232
+ typeof content !== 'object') {
233
+ nextMessage.content = String(content);
234
+ }
235
+ if ((nextMessage.tool_calls?.length ?? 0) === 0 && isEmptyAssistantContent(nextMessage.content)) {
236
+ continue;
237
+ }
238
+ normalizedMessages.push(nextMessage);
239
+ continue;
240
+ }
241
+ if (role === 'tool') {
242
+ const rawToolCallId = message.tool_call_id ?? message.call_id ?? message.id;
243
+ const toolCallId = typeof rawToolCallId === 'string' ? rawToolCallId.trim() : '';
244
+ if (!toolCallId) {
245
+ return undefined;
246
+ }
247
+ nextMessage.tool_call_id = toolCallId;
248
+ nextMessage.content = normalizeToolContent(message.content ?? message.output);
249
+ const name = typeof message.name === 'string' && message.name.trim().length ? message.name.trim() : undefined;
250
+ if (!seenToolOutputIds.has(toolCallId)) {
251
+ seenToolOutputIds.add(toolCallId);
252
+ toolOutputs.push({
253
+ tool_call_id: toolCallId,
254
+ content: maybeAugmentApplyPatchErrorContent(nextMessage.content, name),
255
+ ...(name ? { name } : {})
256
+ });
257
+ }
258
+ normalizedMessages.push(nextMessage);
259
+ continue;
260
+ }
261
+ if (role === 'system') {
262
+ const segment = flattenSystemContent(message.content);
263
+ if (segment.trim().length > 0) {
264
+ systemSegments.push(segment);
265
+ }
266
+ }
267
+ else {
268
+ const content = nextMessage.content;
269
+ if (content !== undefined &&
270
+ content !== null &&
271
+ typeof content !== 'string' &&
272
+ !Array.isArray(content) &&
273
+ typeof content !== 'object') {
274
+ nextMessage.content = String(content);
275
+ }
276
+ }
277
+ normalizedMessages.push(nextMessage);
278
+ }
279
+ const tools = normalizeToolDefinitionsFast(payload.tools);
280
+ if (tools === null) {
281
+ return undefined;
282
+ }
283
+ const metadata = { context: ctx };
284
+ const rawSystemBlocks = collectSystemRawBlocks(payload.messages);
285
+ if (rawSystemBlocks) {
286
+ const protocolState = ensureProtocolState(metadata, 'openai');
287
+ protocolState.systemMessages = jsonClone(rawSystemBlocks);
288
+ }
289
+ const parameters = extractParameters(payload);
290
+ const extraFields = collectExtraFields(payload);
291
+ const semantics = buildOpenaiSemantics(systemSegments, extraFields, Array.isArray(payload.tools) && payload.tools.length === 0);
292
+ return {
293
+ messages: normalizedMessages,
294
+ ...(tools ? { tools } : {}),
295
+ ...(toolOutputs.length > 0 ? { toolOutputs } : {}),
296
+ ...(parameters ? { parameters } : {}),
297
+ ...(semantics ? { semantics } : {}),
298
+ metadata
299
+ };
300
+ }
2
301
  export function maybeAugmentApplyPatchErrorContent(content, toolName) {
3
302
  if (!content)
4
303
  return content;
@@ -28,7 +327,12 @@ export function maybeAugmentApplyPatchErrorContent(content, toolName) {
28
327
  }
29
328
  export class ChatSemanticMapper {
30
329
  async toChat(format, ctx) {
31
- return mapOpenaiChatToChatWithNative((format.payload ?? {}), ctx);
330
+ const payload = (format.payload ?? {});
331
+ const fastMapped = tryMapOpenaiChatToChatFast(payload, ctx);
332
+ if (fastMapped) {
333
+ return fastMapped;
334
+ }
335
+ return mapOpenaiChatToChatWithNative(payload, ctx);
32
336
  }
33
337
  async fromChat(chat, ctx) {
34
338
  return mapOpenaiChatFromChatWithNative(chat, ctx);
@@ -35,7 +35,7 @@ import { applyHubProviderOutboundPolicy, recordHubPolicyObservation, setHubPolic
35
35
  import { applyProviderOutboundToolSurface, } from "../tool-surface/tool-surface-engine.js";
36
36
  import { cloneRuntimeMetadata, ensureRuntimeMetadata, readRuntimeMetadata, } from "../../runtime-metadata.js";
37
37
  import { containsImageAttachment, stripHistoricalImageAttachments, stripHistoricalVisualToolOutputs, repairIncompleteToolCalls, } from "../process/chat-process-media.js";
38
- import { measureHubStage, logHubStageTiming } from "./hub-stage-timing.js";
38
+ import { measureHubStage, logHubStageTiming, clearHubStageTiming, } from "./hub-stage-timing.js";
39
39
  function isTruthyEnv(value) {
40
40
  const v = typeof value === "string" ? value.trim().toLowerCase() : "";
41
41
  return v === "1" || v === "true" || v === "yes" || v === "on";
@@ -1341,15 +1341,21 @@ export class HubPipeline {
1341
1341
  }
1342
1342
  async execute(request) {
1343
1343
  const normalized = await this.normalizeRequest(request);
1344
- if (normalized.direction === "request" &&
1345
- normalized.hubEntryMode === "chat_process") {
1346
- return await this.executeChatProcessEntryPipeline(normalized);
1344
+ clearHubStageTiming(normalized.id);
1345
+ try {
1346
+ if (normalized.direction === "request" &&
1347
+ normalized.hubEntryMode === "chat_process") {
1348
+ return await this.executeChatProcessEntryPipeline(normalized);
1349
+ }
1350
+ const hooks = this.resolveProtocolHooks(normalized.providerProtocol);
1351
+ if (!hooks) {
1352
+ throw new Error(`Unsupported provider protocol for hub pipeline: ${normalized.providerProtocol}`);
1353
+ }
1354
+ return await this.executeRequestStagePipeline(normalized, hooks);
1347
1355
  }
1348
- const hooks = this.resolveProtocolHooks(normalized.providerProtocol);
1349
- if (!hooks) {
1350
- throw new Error(`Unsupported provider protocol for hub pipeline: ${normalized.providerProtocol}`);
1356
+ finally {
1357
+ clearHubStageTiming(normalized.id);
1351
1358
  }
1352
- return await this.executeRequestStagePipeline(normalized, hooks);
1353
1359
  }
1354
1360
  captureAnthropicAliasMap(normalized, adapterContext, chatEnvelope) {
1355
1361
  if (!this.shouldCaptureAnthropicAlias(normalized.entryEndpoint)) {
@@ -1,3 +1,5 @@
1
+ export declare function isHubStageTimingDetailEnabled(): boolean;
2
+ export declare function clearHubStageTiming(requestId: string | undefined | null): void;
1
3
  export declare function logHubStageTiming(requestId: string, stage: string, phase: 'start' | 'completed' | 'error', details?: Record<string, unknown>): void;
2
4
  export declare function measureHubStage<T>(requestId: string, stage: string, fn: () => Promise<T> | T, options?: {
3
5
  startDetails?: Record<string, unknown>;
@@ -21,15 +21,11 @@ function isHubStageTimingEnabled() {
21
21
  const explicit = process.env.ROUTECODEX_STAGE_TIMING ??
22
22
  process.env.RCC_STAGE_TIMING ??
23
23
  process.env.ROUTECODEX_HUB_STAGE_TIMING ??
24
- process.env.RCC_HUB_STAGE_TIMING ??
25
- process.env.ROUTECODEX_BUILD_MODE ??
26
- process.env.RCC_BUILD_MODE ??
27
- process.env.BUILD_MODE ??
28
- process.env.LLMSWITCH_BUILD_MODE;
24
+ process.env.RCC_HUB_STAGE_TIMING;
29
25
  if (explicit !== undefined) {
30
- return resolveBool(explicit, true);
26
+ return resolveBool(explicit, false);
31
27
  }
32
- return true;
28
+ return false;
33
29
  }
34
30
  function isHubStageTimingVerboseEnabled() {
35
31
  const explicit = process.env.ROUTECODEX_STAGE_TIMING_VERBOSE ??
@@ -41,6 +37,16 @@ function isHubStageTimingVerboseEnabled() {
41
37
  }
42
38
  return false;
43
39
  }
40
+ export function isHubStageTimingDetailEnabled() {
41
+ const explicit = process.env.ROUTECODEX_STAGE_TIMING_DETAIL ??
42
+ process.env.RCC_STAGE_TIMING_DETAIL ??
43
+ process.env.ROUTECODEX_HUB_STAGE_TIMING_DETAIL ??
44
+ process.env.RCC_HUB_STAGE_TIMING_DETAIL;
45
+ if (explicit !== undefined) {
46
+ return resolveBool(explicit, false);
47
+ }
48
+ return false;
49
+ }
44
50
  function resolveHubStageTimingMinMs() {
45
51
  const raw = process.env.ROUTECODEX_STAGE_TIMING_MIN_MS ??
46
52
  process.env.RCC_STAGE_TIMING_MIN_MS ??
@@ -114,6 +120,12 @@ function renderDetails(details) {
114
120
  return '';
115
121
  }
116
122
  }
123
+ export function clearHubStageTiming(requestId) {
124
+ if (!requestId) {
125
+ return;
126
+ }
127
+ REQUEST_TIMELINES.delete(requestId);
128
+ }
117
129
  export function logHubStageTiming(requestId, stage, phase, details) {
118
130
  if (!isHubStageTimingEnabled() || !requestId || !stage) {
119
131
  return;
@@ -127,7 +139,7 @@ export function logHubStageTiming(requestId, stage, phase, details) {
127
139
  const timing = advanceTiming(requestId);
128
140
  if (phase !== 'error') {
129
141
  const forceLog = details?.forceLog === true;
130
- if (forceLog) {
142
+ if (forceLog && isHubStageTimingDetailEnabled()) {
131
143
  const detailSuffix = renderDetails(details);
132
144
  const line = `[hub.detail][${requestId}] ${stage}.${phase}${timing.label}${detailSuffix}`;
133
145
  console.log(line);
@@ -3,12 +3,10 @@ import { recordStage } from '../../../stages/utils.js';
3
3
  import { applyContextSnapshotToChatEnvelope, applyToolCallIdStyleMetadata } from './context-merge.js';
4
4
  import { shouldAttachReqOutboundContextSnapshotWithNative, standardizedToChatEnvelopeWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-req-outbound-semantics.js';
5
5
  import { validateChatEnvelopeWithNative } from '../../../../../../router/virtual-router/engine-selection/native-hub-pipeline-edge-stage-semantics.js';
6
- import { logHubStageTiming } from '../../../hub-stage-timing.js';
6
+ import { isHubStageTimingDetailEnabled, logHubStageTiming } from '../../../hub-stage-timing.js';
7
7
  export async function runReqOutboundStage1SemanticMap(options) {
8
8
  const requestId = options.adapterContext.requestId || 'unknown';
9
- const forceDetailLog = String(process.env.ROUTECODEX_HUB_STAGE_TIMING_DETAIL || '')
10
- .trim()
11
- .toLowerCase() === '1';
9
+ const forceDetailLog = isHubStageTimingDetailEnabled();
12
10
  logHubStageTiming(requestId, 'req_outbound.stage1_native_to_chat_envelope', 'start');
13
11
  const toChatStart = Date.now();
14
12
  const chatEnvelope = standardizedToChatEnvelopeWithNative({
@@ -45,6 +45,58 @@ function filterRedundantResponsesReasoningAction(actions) {
45
45
  return name !== 'reasoning.extract';
46
46
  });
47
47
  }
48
+ const RESPONSES_TOOL_PASSTHROUGH_KEYS = [
49
+ 'temperature',
50
+ 'tool_choice',
51
+ 'parallel_tool_calls',
52
+ 'response_format',
53
+ 'user',
54
+ 'top_p',
55
+ 'prompt_cache_key',
56
+ 'reasoning',
57
+ 'logit_bias',
58
+ 'seed'
59
+ ];
60
+ function pickObjectFields(value, keys) {
61
+ if (!value) {
62
+ return undefined;
63
+ }
64
+ const picked = {};
65
+ for (const key of keys) {
66
+ if (value[key] !== undefined) {
67
+ picked[key] = value[key];
68
+ }
69
+ }
70
+ return Object.keys(picked).length ? picked : undefined;
71
+ }
72
+ function buildSlimResponsesBridgeContext(context) {
73
+ if (!context || typeof context !== 'object') {
74
+ return undefined;
75
+ }
76
+ const slim = {};
77
+ if (Array.isArray(context.input) && context.input.length) {
78
+ slim.input = context.input;
79
+ }
80
+ if (Array.isArray(context.originalSystemMessages) && context.originalSystemMessages.length) {
81
+ slim.originalSystemMessages = context.originalSystemMessages;
82
+ }
83
+ if (typeof context.systemInstruction === 'string' && context.systemInstruction.trim().length) {
84
+ slim.systemInstruction = context.systemInstruction;
85
+ }
86
+ if (typeof context.toolCallIdStyle === 'string' && context.toolCallIdStyle.trim().length) {
87
+ slim.toolCallIdStyle = context.toolCallIdStyle;
88
+ }
89
+ if (context.metadata && typeof context.metadata === 'object' && !Array.isArray(context.metadata)) {
90
+ slim.metadata = context.metadata;
91
+ }
92
+ return Object.keys(slim).length ? slim : undefined;
93
+ }
94
+ function buildSlimBridgeDecisionMetadata(metadata) {
95
+ if (!metadata) {
96
+ return undefined;
97
+ }
98
+ return pickObjectFields(metadata, ['toolCallIdStyle', 'bridgeHistory']);
99
+ }
48
100
  // normalizeTools unified in ../args-mapping.ts
49
101
  // NOTE: 自修复提示已移除(统一标准:不做模糊兜底)。
50
102
  // --- Public bridge functions ---
@@ -222,10 +274,10 @@ export function buildResponsesRequestFromChat(payload, ctx, extras) {
222
274
  }
223
275
  const metadataExtraFields = extractMetadataExtraFields(envelopeMetadata);
224
276
  const bridgeDecisions = resolveResponsesRequestBridgeDecisionsWithNative({
225
- context: ctx && typeof ctx === 'object' ? ctx : undefined,
226
- requestMetadata,
227
- envelopeMetadata,
228
- bridgeMetadata,
277
+ context: buildSlimResponsesBridgeContext(ctx),
278
+ requestMetadata: buildSlimBridgeDecisionMetadata(requestMetadata),
279
+ envelopeMetadata: buildSlimBridgeDecisionMetadata(envelopeMetadata),
280
+ bridgeMetadata: buildSlimBridgeDecisionMetadata(bridgeMetadata),
229
281
  extraBridgeHistory: extras?.bridgeHistory
230
282
  });
231
283
  const forceWebSearch = bridgeDecisions.forceWebSearch === true;
@@ -241,19 +293,8 @@ export function buildResponsesRequestFromChat(payload, ctx, extras) {
241
293
  originalTools: Array.isArray(originalTools) ? originalTools : undefined,
242
294
  chatTools: Array.isArray(responsesToolsFromChat) ? responsesToolsFromChat : undefined,
243
295
  hasServerSideWebSearch: !forceWebSearch,
244
- passthroughKeys: [
245
- 'temperature',
246
- 'tool_choice',
247
- 'parallel_tool_calls',
248
- 'response_format',
249
- 'user',
250
- 'top_p',
251
- 'prompt_cache_key',
252
- 'reasoning',
253
- 'logit_bias',
254
- 'seed'
255
- ],
256
- request: chat
296
+ passthroughKeys: [...RESPONSES_TOOL_PASSTHROUGH_KEYS],
297
+ request: pickObjectFields(chat, RESPONSES_TOOL_PASSTHROUGH_KEYS)
257
298
  });
258
299
  const mergedTools = resolvedBridgeTools.mergedTools;
259
300
  if (mergedTools?.length) {
@@ -48,6 +48,11 @@ export function normalizeReasoningInChatPayload(payload) {
48
48
  assertReasoningNormalizerNativeAvailable();
49
49
  if (!payload)
50
50
  return;
51
+ const shouldNormalize = valueMayContainReasoningMarkup(payload.messages) ||
52
+ valueMayContainReasoningMarkup(payload.choices);
53
+ if (!shouldNormalize) {
54
+ return;
55
+ }
51
56
  const normalized = normalizeReasoningInChatPayloadWithNative(payload);
52
57
  if (normalized && typeof normalized === 'object') {
53
58
  Object.assign(payload, normalized);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonstudio/llms",
3
- "version": "0.6.3686",
3
+ "version": "0.6.3689",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",