@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.
- package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +305 -1
- package/dist/conversion/hub/pipeline/hub-pipeline.js +14 -8
- package/dist/conversion/hub/pipeline/hub-stage-timing.d.ts +2 -0
- package/dist/conversion/hub/pipeline/hub-stage-timing.js +20 -8
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +2 -4
- package/dist/conversion/responses/responses-openai-bridge.js +58 -17
- package/dist/conversion/shared/reasoning-normalizer.js +5 -0
- package/package.json +1 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
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
|
-
|
|
1349
|
-
|
|
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,
|
|
26
|
+
return resolveBool(explicit, false);
|
|
31
27
|
}
|
|
32
|
-
return
|
|
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);
|
package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js
CHANGED
|
@@ -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 =
|
|
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
|
|
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
|
-
|
|
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);
|