@jsonstudio/llms 0.6.1164 → 0.6.1354
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/codecs/gemini-openai-codec.d.ts +3 -1
- package/dist/conversion/codecs/gemini-openai-codec.js +10 -4
- package/dist/conversion/compat/actions/gemini-web-search.d.ts +1 -1
- package/dist/conversion/compat/actions/gemini-web-search.js +5 -2
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.d.ts +12 -0
- package/dist/conversion/compat/actions/iflow-tool-text-fallback.js +199 -0
- package/dist/conversion/compat/actions/iflow-web-search.d.ts +1 -1
- package/dist/conversion/compat/actions/iflow-web-search.js +5 -2
- package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +47 -56
- package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +1 -13
- package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +523 -50
- package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +18 -38
- package/dist/conversion/hub/pipeline/compat/compat-pipeline-executor.js +6 -0
- package/dist/conversion/hub/pipeline/compat/compat-types.d.ts +3 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/adapter-context.d.ts +10 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/adapter-context.js +134 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/anthropic-alias-map.d.ts +6 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/anthropic-alias-map.js +79 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/apply-patch-tool-mode.d.ts +3 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/apply-patch-tool-mode.js +46 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-chat-process-entry.d.ts +8 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-chat-process-entry.js +366 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-request-stage.d.ts +9 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/execute-request-stage.js +384 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/node-results.d.ts +3 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/node-results.js +14 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/payload-normalize.d.ts +2 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/payload-normalize.js +144 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/policy.d.ts +4 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/policy.js +32 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/protocol.d.ts +8 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/protocol.js +63 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/resolve-protocol-hooks.d.ts +2 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/resolve-protocol-hooks.js +43 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/semantic-gate.d.ts +1 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/semantic-gate.js +29 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/servertool-runtime-config.d.ts +2 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/servertool-runtime-config.js +16 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/types.d.ts +116 -0
- package/dist/conversion/hub/pipeline/hub-pipeline/types.js +1 -0
- package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +3 -95
- package/dist/conversion/hub/pipeline/hub-pipeline.js +19 -1281
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js +1 -1
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +7 -0
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +65 -1
- package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +25 -22
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +1 -1
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.d.ts +1 -1
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.js +2 -2
- package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js +2 -2
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js +1 -1
- package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +1 -1
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +11 -11
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.js +1 -1
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.d.ts +1 -0
- package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.js +4 -2
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.d.ts +1 -0
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +17 -9
- package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js +2 -2
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +40 -2
- package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +1 -1
- package/dist/conversion/hub/pipeline/target-utils.js +9 -5
- package/dist/conversion/hub/process/chat-process.js +256 -16
- package/dist/conversion/hub/response/provider-response.d.ts +8 -0
- package/dist/conversion/hub/response/provider-response.js +85 -27
- package/dist/conversion/hub/response/response-mappers.d.ts +10 -3
- package/dist/conversion/hub/response/response-mappers.js +30 -6
- package/dist/conversion/hub/response/response-runtime.js +4 -38
- package/dist/conversion/hub/snapshot-recorder.js +5 -1
- package/dist/conversion/hub/standardized-bridge.js +23 -15
- package/dist/conversion/pipeline/codecs/v2/anthropic-openai-pipeline.js +36 -5
- package/dist/conversion/responses/responses-openai-bridge.js +20 -4
- package/dist/conversion/shared/gemini-tool-utils.d.ts +8 -1
- package/dist/conversion/shared/gemini-tool-utils.js +580 -108
- package/dist/conversion/shared/jsonish.js +1 -1
- package/dist/conversion/shared/mcp-injection.js +67 -33
- package/dist/conversion/shared/openai-finalizer.js +2 -1
- package/dist/conversion/shared/openai-message-normalize.js +76 -21
- package/dist/conversion/shared/responses-output-builder.js +6 -0
- package/dist/conversion/shared/runtime-metadata.d.ts +7 -0
- package/dist/conversion/shared/runtime-metadata.js +23 -0
- package/dist/conversion/shared/text-markup-normalizer.d.ts +2 -0
- package/dist/conversion/shared/text-markup-normalizer.js +284 -4
- package/dist/conversion/shared/tool-canonicalizer.js +2 -1
- package/dist/conversion/shared/tool-governor.js +3 -3
- package/dist/filters/engine.js +5 -5
- package/dist/filters/special/request-tool-list-filter.js +194 -60
- package/dist/filters/special/request-tools-normalize.js +1 -1
- package/dist/filters/special/response-tool-text-canonicalize.d.ts +4 -7
- package/dist/filters/special/response-tool-text-canonicalize.js +7 -35
- package/dist/filters/special/tool-filter-hooks.js +58 -62
- package/dist/guidance/index.js +5 -1
- package/dist/http/sse-response.js +6 -6
- package/dist/router/virtual-router/bootstrap.js +65 -5
- package/dist/router/virtual-router/context-advisor.d.ts +4 -0
- package/dist/router/virtual-router/context-advisor.js +3 -0
- package/dist/router/virtual-router/context-weighted.d.ts +31 -0
- package/dist/router/virtual-router/context-weighted.js +54 -0
- package/dist/router/virtual-router/engine-health.d.ts +1 -1
- package/dist/router/virtual-router/engine-health.js +11 -110
- package/dist/router/virtual-router/engine-selection/alias-selection.d.ts +15 -0
- package/dist/router/virtual-router/engine-selection/alias-selection.js +156 -0
- package/dist/router/virtual-router/engine-selection/context-weight-multipliers.d.ts +11 -0
- package/dist/router/virtual-router/engine-selection/context-weight-multipliers.js +23 -0
- package/dist/router/virtual-router/engine-selection/direct-provider-model.d.ts +9 -0
- package/dist/router/virtual-router/engine-selection/direct-provider-model.js +49 -0
- package/dist/router/virtual-router/engine-selection/instruction-target.d.ts +6 -0
- package/dist/router/virtual-router/engine-selection/instruction-target.js +54 -0
- package/dist/router/virtual-router/engine-selection/key-parsing.d.ts +8 -0
- package/dist/router/virtual-router/engine-selection/key-parsing.js +64 -0
- package/dist/router/virtual-router/engine-selection/route-utils.d.ts +12 -0
- package/dist/router/virtual-router/engine-selection/route-utils.js +150 -0
- package/dist/router/virtual-router/engine-selection/routing-state-filter.d.ts +4 -0
- package/dist/router/virtual-router/engine-selection/routing-state-filter.js +50 -0
- package/dist/router/virtual-router/engine-selection/selection-deps.d.ts +39 -0
- package/dist/router/virtual-router/engine-selection/selection-deps.js +1 -0
- package/dist/router/virtual-router/engine-selection/sticky-pool.d.ts +11 -0
- package/dist/router/virtual-router/engine-selection/sticky-pool.js +109 -0
- package/dist/router/virtual-router/engine-selection/tier-priority.d.ts +12 -0
- package/dist/router/virtual-router/engine-selection/tier-priority.js +55 -0
- package/dist/router/virtual-router/engine-selection/tier-selection-select.d.ts +22 -0
- package/dist/router/virtual-router/engine-selection/tier-selection-select.js +400 -0
- package/dist/router/virtual-router/engine-selection/tier-selection.d.ts +3 -0
- package/dist/router/virtual-router/engine-selection/tier-selection.js +225 -0
- package/dist/router/virtual-router/engine-selection.d.ts +4 -30
- package/dist/router/virtual-router/engine-selection.js +10 -815
- package/dist/router/virtual-router/engine.d.ts +1 -0
- package/dist/router/virtual-router/engine.js +55 -10
- package/dist/router/virtual-router/routing-instructions.js +6 -1
- package/dist/router/virtual-router/stop-message-state-sync.d.ts +5 -0
- package/dist/router/virtual-router/stop-message-state-sync.js +6 -14
- package/dist/router/virtual-router/types.d.ts +53 -1
- package/dist/servertool/clock/config.d.ts +8 -0
- package/dist/servertool/clock/config.js +22 -0
- package/dist/servertool/clock/log.d.ts +3 -0
- package/dist/servertool/clock/log.js +13 -0
- package/dist/servertool/clock/task-store.d.ts +1 -1
- package/dist/servertool/clock/task-store.js +1 -1
- package/dist/servertool/clock/tasks.js +1 -1
- package/dist/servertool/engine.js +146 -21
- package/dist/servertool/handlers/clock-auto.js +11 -6
- package/dist/servertool/handlers/clock.js +36 -10
- package/dist/servertool/handlers/followup-request-builder.js +8 -2
- package/dist/servertool/handlers/gemini-empty-reply-continue.js +15 -9
- package/dist/servertool/handlers/iflow-model-error-retry.js +6 -4
- package/dist/servertool/handlers/recursive-detection-guard.js +4 -2
- package/dist/servertool/handlers/stop-message-auto.js +100 -10
- package/dist/servertool/handlers/vision.js +4 -1
- package/dist/servertool/handlers/web-search.js +3 -1
- package/dist/servertool/pending-session.d.ts +19 -0
- package/dist/servertool/pending-session.js +97 -0
- package/dist/servertool/reenter-backend.js +5 -3
- package/dist/servertool/server-side-tools.js +235 -6
- package/dist/servertool/types.d.ts +13 -0
- package/dist/sse/json-to-sse/event-generators/responses.js +1 -1
- package/dist/sse/shared/chat-serializer.js +2 -2
- package/dist/sse/shared/constants.js +1 -1
- package/dist/sse/sse-to-json/anthropic-sse-to-json-converter.d.ts +7 -1
- package/dist/sse/sse-to-json/builders/response-builder.js +16 -0
- package/dist/sse/sse-to-json/responses-sse-to-json-converter.d.ts +1 -1
- package/dist/tools/apply-patch/execution-capturer.js +1 -1
- package/dist/tools/exec-command/normalize.js +4 -0
- package/dist/tools/exec-command/regression-capturer.js +1 -1
- package/package.json +10 -5
package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage1_format_parse/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { recordStage } from '../../../stages/utils.js';
|
|
2
2
|
export async function runReqInboundStage1FormatParse(options) {
|
|
3
3
|
const envelope = (await options.formatAdapter.parseRequest(options.rawRequest, options.adapterContext));
|
|
4
|
-
recordStage(options.stageRecorder, '
|
|
4
|
+
recordStage(options.stageRecorder, 'chat_process.req.stage1.format_parse', envelope);
|
|
5
5
|
return envelope;
|
|
6
6
|
}
|
package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts
CHANGED
|
@@ -7,6 +7,13 @@ export interface ReqInboundStage2SemanticMapOptions {
|
|
|
7
7
|
adapterContext: AdapterContext;
|
|
8
8
|
formatEnvelope: FormatEnvelope<JsonObject>;
|
|
9
9
|
semanticMapper: Pick<SemanticMapper, 'toChat'>;
|
|
10
|
+
/**
|
|
11
|
+
* Mappable cross-protocol semantics (e.g. /v1/responses submit resume) must be
|
|
12
|
+
* lifted into chat semantics before entering chat_process.
|
|
13
|
+
*
|
|
14
|
+
* This must never be stored in metadata/AdapterContext.
|
|
15
|
+
*/
|
|
16
|
+
responsesResume?: JsonObject;
|
|
10
17
|
stageRecorder?: StageRecorder;
|
|
11
18
|
}
|
|
12
19
|
export interface ReqInboundStage2SemanticMapResult {
|
package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { chatEnvelopeToStandardized } from '../../../../standardized-bridge.js';
|
|
|
2
2
|
import { validateChatEnvelope } from '../../../../../shared/chat-envelope-validator.js';
|
|
3
3
|
import { applyHubOperationTableInbound } from '../../../../operation-table/operation-table-runner.js';
|
|
4
4
|
import { recordStage } from '../../../stages/utils.js';
|
|
5
|
+
import { isJsonObject, jsonClone } from '../../../../types/json.js';
|
|
5
6
|
export async function runReqInboundStage2SemanticMap(options) {
|
|
6
7
|
const chatEnvelope = await options.semanticMapper.toChat(options.formatEnvelope, options.adapterContext);
|
|
7
8
|
applyHubOperationTableInbound({
|
|
@@ -9,11 +10,74 @@ export async function runReqInboundStage2SemanticMap(options) {
|
|
|
9
10
|
chatEnvelope,
|
|
10
11
|
adapterContext: options.adapterContext
|
|
11
12
|
});
|
|
13
|
+
// Semantic Gate (request): before entering chat_process, lift any mappable protocol semantics
|
|
14
|
+
// into ChatEnvelope.semantics. Do not persist these in metadata.
|
|
15
|
+
try {
|
|
16
|
+
if (!chatEnvelope.semantics || typeof chatEnvelope.semantics !== 'object') {
|
|
17
|
+
chatEnvelope.semantics = {};
|
|
18
|
+
}
|
|
19
|
+
const semantics = chatEnvelope.semantics;
|
|
20
|
+
if (!semantics.tools || !isJsonObject(semantics.tools)) {
|
|
21
|
+
semantics.tools = {};
|
|
22
|
+
}
|
|
23
|
+
const toolsNode = semantics.tools;
|
|
24
|
+
const rawTools = Array.isArray(options.formatEnvelope.payload?.tools)
|
|
25
|
+
? (options.formatEnvelope.payload.tools ?? [])
|
|
26
|
+
: [];
|
|
27
|
+
if (rawTools.length && toolsNode.clientToolsRaw === undefined) {
|
|
28
|
+
toolsNode.clientToolsRaw = jsonClone(rawTools);
|
|
29
|
+
}
|
|
30
|
+
if (options.responsesResume && isJsonObject(options.responsesResume)) {
|
|
31
|
+
if (!semantics.responses || !isJsonObject(semantics.responses)) {
|
|
32
|
+
semantics.responses = {};
|
|
33
|
+
}
|
|
34
|
+
const responsesNode = semantics.responses;
|
|
35
|
+
if (responsesNode.resume === undefined) {
|
|
36
|
+
responsesNode.resume = jsonClone(options.responsesResume);
|
|
37
|
+
}
|
|
38
|
+
// If this is a Responses submit/resume hop, tool outputs may exist only in resume metadata.
|
|
39
|
+
// Lift them into canonical chat.toolOutputs so chat_process sees a single unified surface.
|
|
40
|
+
const hasDirectToolOutputs = Array.isArray(chatEnvelope.toolOutputs) && chatEnvelope.toolOutputs.length > 0;
|
|
41
|
+
if (!hasDirectToolOutputs) {
|
|
42
|
+
const detailed = Array.isArray(options.responsesResume.toolOutputsDetailed)
|
|
43
|
+
? options.responsesResume.toolOutputsDetailed
|
|
44
|
+
: undefined;
|
|
45
|
+
if (detailed && detailed.length) {
|
|
46
|
+
const mapped = detailed
|
|
47
|
+
.map((entry, index) => {
|
|
48
|
+
if (!entry || typeof entry !== 'object')
|
|
49
|
+
return undefined;
|
|
50
|
+
const callId = typeof entry.callId === 'string' && String(entry.callId).trim().length
|
|
51
|
+
? String(entry.callId).trim()
|
|
52
|
+
: typeof entry.originalId === 'string' && String(entry.originalId).trim().length
|
|
53
|
+
? String(entry.originalId).trim()
|
|
54
|
+
: `resume_tool_${index + 1}`;
|
|
55
|
+
const outputText = typeof entry.outputText === 'string'
|
|
56
|
+
? entry.outputText
|
|
57
|
+
: (() => { try {
|
|
58
|
+
return JSON.stringify(entry.outputText ?? '');
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return String(entry.outputText ?? '');
|
|
62
|
+
} })();
|
|
63
|
+
return { tool_call_id: callId, content: outputText };
|
|
64
|
+
})
|
|
65
|
+
.filter(Boolean);
|
|
66
|
+
if (mapped.length) {
|
|
67
|
+
chatEnvelope.toolOutputs = mapped;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// fail-fast is enforced at chat_process entry; this gate is best-effort
|
|
75
|
+
}
|
|
12
76
|
validateChatEnvelope(chatEnvelope, {
|
|
13
77
|
stage: 'req_inbound',
|
|
14
78
|
direction: 'request'
|
|
15
79
|
});
|
|
16
|
-
recordStage(options.stageRecorder, '
|
|
80
|
+
recordStage(options.stageRecorder, 'chat_process.req.stage2.semantic_map', chatEnvelope);
|
|
17
81
|
const standardizedRequest = chatEnvelopeToStandardized(chatEnvelope, {
|
|
18
82
|
adapterContext: options.adapterContext,
|
|
19
83
|
endpoint: options.adapterContext.entryEndpoint,
|
package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js
CHANGED
|
@@ -1,26 +1,7 @@
|
|
|
1
1
|
import { captureResponsesContext, buildChatRequestFromResponses } from '../../../../../responses/responses-openai-bridge.js';
|
|
2
|
+
import { captureResponsesRequestContext } from '../../../../../shared/responses-conversation-store.js';
|
|
2
3
|
import { recordStage } from '../../../stages/utils.js';
|
|
3
4
|
export async function runReqInboundStage3ContextCapture(options) {
|
|
4
|
-
// 对由 server-side 工具触发的二跳/内部跳转请求(例如 stopMessage followup),
|
|
5
|
-
// 跳过工具输出扫描与 apply_patch 诊断日志,避免在内部流中重复放大客户端已收到的
|
|
6
|
-
// 工具错误信息。此类请求的工具治理在 chat-process 阶段完成,这里仅保留最小快照。
|
|
7
|
-
try {
|
|
8
|
-
const ctx = options.adapterContext;
|
|
9
|
-
const followupFlag = ctx?.serverToolFollowup;
|
|
10
|
-
const isFollowup = followupFlag === true ||
|
|
11
|
-
(typeof followupFlag === 'string' && followupFlag.trim().toLowerCase() === 'true');
|
|
12
|
-
if (isFollowup) {
|
|
13
|
-
const snapshot = {
|
|
14
|
-
providerProtocol: options.adapterContext.providerProtocol ?? 'unknown',
|
|
15
|
-
tool_outputs: []
|
|
16
|
-
};
|
|
17
|
-
recordStage(options.stageRecorder, 'req_inbound_stage3_context_capture', snapshot);
|
|
18
|
-
return snapshot;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
// best-effort: 若检测 serverToolFollowup 失败,则继续走通用路径
|
|
23
|
-
}
|
|
24
5
|
let context;
|
|
25
6
|
if (options.captureContext) {
|
|
26
7
|
try {
|
|
@@ -37,7 +18,7 @@ export async function runReqInboundStage3ContextCapture(options) {
|
|
|
37
18
|
const snapshot = context
|
|
38
19
|
? augmentContextSnapshot(context, fallbackSnapshot)
|
|
39
20
|
: fallbackSnapshot;
|
|
40
|
-
recordStage(options.stageRecorder, '
|
|
21
|
+
recordStage(options.stageRecorder, 'chat_process.req.stage3.context_capture', snapshot);
|
|
41
22
|
return context ?? snapshot;
|
|
42
23
|
}
|
|
43
24
|
export function runChatContextCapture(options) {
|
|
@@ -73,6 +54,28 @@ export function captureResponsesContextSnapshot(options) {
|
|
|
73
54
|
catch {
|
|
74
55
|
// best-effort context capture
|
|
75
56
|
}
|
|
57
|
+
// OpenAI Responses tool loop: store the request context keyed by requestId so that
|
|
58
|
+
// `/v1/responses/:id/submit_tool_outputs` can resume the conversation later.
|
|
59
|
+
//
|
|
60
|
+
// This must be done on the hub pipeline inbound path (not in host/provider), because:
|
|
61
|
+
// - the tool loop is a client-protocol behavior (/v1/responses), independent of providerProtocol;
|
|
62
|
+
// - providers must remain transport-only;
|
|
63
|
+
// - the host may later enhance requestId with providerKey/model for logging, which is handled via rebind.
|
|
64
|
+
try {
|
|
65
|
+
const requestId = typeof options.adapterContext.requestId === 'string' && options.adapterContext.requestId.trim().length
|
|
66
|
+
? options.adapterContext.requestId
|
|
67
|
+
: undefined;
|
|
68
|
+
if (requestId) {
|
|
69
|
+
captureResponsesRequestContext({
|
|
70
|
+
requestId,
|
|
71
|
+
payload: options.rawRequest,
|
|
72
|
+
context: context
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// best-effort: capture failures must not block the request path
|
|
78
|
+
}
|
|
76
79
|
return context;
|
|
77
80
|
}
|
|
78
81
|
function captureChatContextSnapshot(options) {
|
|
@@ -306,7 +309,7 @@ function buildApplyPatchDiagnostics(output) {
|
|
|
306
309
|
return '\n\n[RouteCodex precheck] apply_patch 参数解析失败:缺少字段 "input"。当前 RouteCodex 期望 { input, patch } 形态,并且两个字段都应包含完整统一 diff 文本。';
|
|
307
310
|
}
|
|
308
311
|
if (output.includes('invalid type: map, expected a string')) {
|
|
309
|
-
return '\n\n[RouteCodex precheck] apply_patch 参数类型错误:检测到 JSON 对象(map),但客户端期望字符串。请先对参数做 JSON.stringify 再写入 arguments,或直接提供 { patch:
|
|
312
|
+
return '\n\n[RouteCodex precheck] apply_patch 参数类型错误:检测到 JSON 对象(map),但客户端期望字符串。请先对参数做 JSON.stringify 再写入 arguments,或直接提供 { patch: "<统一 diff>" } 形式。';
|
|
310
313
|
}
|
|
311
314
|
return undefined;
|
|
312
315
|
}
|
package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js
CHANGED
|
@@ -28,7 +28,7 @@ export async function runReqOutboundStage1SemanticMap(options) {
|
|
|
28
28
|
formatEnvelope,
|
|
29
29
|
adapterContext: options.adapterContext
|
|
30
30
|
});
|
|
31
|
-
recordStage(options.stageRecorder, '
|
|
31
|
+
recordStage(options.stageRecorder, 'chat_process.req.stage6.outbound.semantic_map', chatEnvelope);
|
|
32
32
|
return { chatEnvelope, formatEnvelope };
|
|
33
33
|
}
|
|
34
34
|
function attachToolOutputsFromContext(chatEnvelope, snapshot) {
|
package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { FormatAdapter, StageRecorder } from '../../../../format-adapters/i
|
|
|
5
5
|
export interface ReqOutboundStage2FormatBuildOptions {
|
|
6
6
|
formatEnvelope: FormatEnvelope<JsonObject>;
|
|
7
7
|
adapterContext: AdapterContext;
|
|
8
|
-
formatAdapter: Pick<FormatAdapter, '
|
|
8
|
+
formatAdapter: Pick<FormatAdapter, 'buildRequest'>;
|
|
9
9
|
stageRecorder?: StageRecorder;
|
|
10
10
|
}
|
|
11
11
|
export declare function runReqOutboundStage2FormatBuild(options: ReqOutboundStage2FormatBuildOptions): Promise<JsonObject>;
|
package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage2_format_build/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { recordStage } from '../../../stages/utils.js';
|
|
2
2
|
const PRIVATE_FIELD_PREFIX = '__rcc_';
|
|
3
3
|
export async function runReqOutboundStage2FormatBuild(options) {
|
|
4
|
-
const payload = (await options.formatAdapter.
|
|
4
|
+
const payload = (await options.formatAdapter.buildRequest(options.formatEnvelope, options.adapterContext));
|
|
5
5
|
stripPrivateFields(payload);
|
|
6
|
-
recordStage(options.stageRecorder, '
|
|
6
|
+
recordStage(options.stageRecorder, 'chat_process.req.stage7.outbound.format_build', payload);
|
|
7
7
|
return payload;
|
|
8
8
|
}
|
|
9
9
|
function stripPrivateFields(value) {
|
package/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js
CHANGED
|
@@ -6,7 +6,7 @@ function pickCompatProfile(adapterContext) {
|
|
|
6
6
|
export async function runReqOutboundStage3Compat(options) {
|
|
7
7
|
const profile = pickCompatProfile(options.adapterContext);
|
|
8
8
|
const result = applyRequestCompat(profile, options.payload, { adapterContext: options.adapterContext });
|
|
9
|
-
options.stageRecorder?.record('
|
|
9
|
+
options.stageRecorder?.record('chat_process.req.stage8.outbound.compat', {
|
|
10
10
|
applied: Boolean(result.appliedProfile),
|
|
11
11
|
profile: result.appliedProfile || profile || 'passthrough'
|
|
12
12
|
});
|
|
@@ -15,7 +15,7 @@ export async function runReqOutboundStage3Compat(options) {
|
|
|
15
15
|
export function runRespInboundStageCompatResponse(options) {
|
|
16
16
|
const profile = pickCompatProfile(options.adapterContext);
|
|
17
17
|
const result = applyResponseCompat(profile, options.payload, { adapterContext: options.adapterContext });
|
|
18
|
-
options.stageRecorder?.record('
|
|
18
|
+
options.stageRecorder?.record('chat_process.resp.stage3.compat', {
|
|
19
19
|
applied: Boolean(result.appliedProfile),
|
|
20
20
|
profile: result.appliedProfile || profile || 'passthrough'
|
|
21
21
|
});
|
package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage1_tool_governance/index.js
CHANGED
|
@@ -10,7 +10,7 @@ export async function runReqProcessStage1ToolGovernance(options) {
|
|
|
10
10
|
requestId: options.requestId
|
|
11
11
|
});
|
|
12
12
|
if (result.processedRequest) {
|
|
13
|
-
recordStage(options.stageRecorder, '
|
|
13
|
+
recordStage(options.stageRecorder, 'chat_process.req.stage4.tool_governance', result.processedRequest);
|
|
14
14
|
// Best-effort: capture apply_patch execution failures reported by tool role messages.
|
|
15
15
|
// This is for errorsamples collection only and must not affect runtime behavior.
|
|
16
16
|
captureApplyPatchExecutionFailuresFromProcessedRequest(result.processedRequest);
|
package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export function runReqProcessStage2RouteSelect(options) {
|
|
|
5
5
|
const result = options.routerEngine.route(options.request, options.metadataInput);
|
|
6
6
|
applyTargetMetadata(options.normalizedMetadata, result.target, result.decision.routeName, previousModel);
|
|
7
7
|
applyTargetToSubject(options.request, result.target, previousModel);
|
|
8
|
-
recordStage(options.stageRecorder, '
|
|
8
|
+
recordStage(options.stageRecorder, 'chat_process.req.stage5.route_select', {
|
|
9
9
|
target: result.target,
|
|
10
10
|
decision: result.decision,
|
|
11
11
|
diagnostics: result.diagnostics
|
package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js
CHANGED
|
@@ -43,43 +43,43 @@ export async function runRespInboundStage1SseDecode(options) {
|
|
|
43
43
|
// 某些 mock-provider / 捕获样本在 SSE 连接被异常终止时会携带 error 标记,
|
|
44
44
|
// 即使仍保留 __sse_responses 流,也应视为上游异常并终止。
|
|
45
45
|
if (wrapperError) {
|
|
46
|
-
recordStage(options.stageRecorder, '
|
|
46
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage1.sse_decode', {
|
|
47
47
|
streamDetected: Boolean(stream),
|
|
48
48
|
decoded: false,
|
|
49
49
|
protocol: options.providerProtocol,
|
|
50
50
|
reason: 'sse_wrapper_error',
|
|
51
51
|
error: wrapperError
|
|
52
52
|
});
|
|
53
|
-
throw new ProviderProtocolError(`[
|
|
53
|
+
throw new ProviderProtocolError(`[chat_process.resp.stage1.sse_decode] Upstream SSE terminated: ${wrapperError}`, {
|
|
54
54
|
code: 'SSE_DECODE_ERROR',
|
|
55
55
|
protocol: options.providerProtocol,
|
|
56
56
|
providerType: resolveProviderType(options.providerProtocol),
|
|
57
57
|
details: {
|
|
58
|
-
phase: '
|
|
58
|
+
phase: 'chat_process.resp.stage1.sse_decode',
|
|
59
59
|
requestId: options.adapterContext.requestId,
|
|
60
60
|
message: wrapperError
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
}
|
|
64
64
|
if (!stream) {
|
|
65
|
-
recordStage(options.stageRecorder, '
|
|
65
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage1.sse_decode', {
|
|
66
66
|
streamDetected: false
|
|
67
67
|
});
|
|
68
68
|
return { payload: options.payload, decodedFromSse: false };
|
|
69
69
|
}
|
|
70
70
|
if (!supportsSseProtocol(options.providerProtocol)) {
|
|
71
|
-
recordStage(options.stageRecorder, '
|
|
71
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage1.sse_decode', {
|
|
72
72
|
streamDetected: true,
|
|
73
73
|
decoded: false,
|
|
74
74
|
reason: 'protocol_unsupported',
|
|
75
75
|
protocol: options.providerProtocol
|
|
76
76
|
});
|
|
77
|
-
throw new ProviderProtocolError(`[
|
|
77
|
+
throw new ProviderProtocolError(`[chat_process.resp.stage1.sse_decode] Protocol ${options.providerProtocol} does not support SSE decoding`, {
|
|
78
78
|
code: 'SSE_DECODE_ERROR',
|
|
79
79
|
protocol: options.providerProtocol,
|
|
80
80
|
providerType: resolveProviderType(options.providerProtocol),
|
|
81
81
|
details: {
|
|
82
|
-
phase: '
|
|
82
|
+
phase: 'chat_process.resp.stage1.sse_decode',
|
|
83
83
|
reason: 'protocol_unsupported'
|
|
84
84
|
}
|
|
85
85
|
});
|
|
@@ -90,7 +90,7 @@ export async function runRespInboundStage1SseDecode(options) {
|
|
|
90
90
|
requestId: options.adapterContext.requestId,
|
|
91
91
|
model: options.adapterContext.modelId
|
|
92
92
|
}));
|
|
93
|
-
recordStage(options.stageRecorder, '
|
|
93
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage1.sse_decode', {
|
|
94
94
|
streamDetected: true,
|
|
95
95
|
decoded: true,
|
|
96
96
|
protocol: options.providerProtocol
|
|
@@ -99,18 +99,18 @@ export async function runRespInboundStage1SseDecode(options) {
|
|
|
99
99
|
}
|
|
100
100
|
catch (error) {
|
|
101
101
|
const message = error instanceof Error ? error.message : String(error);
|
|
102
|
-
recordStage(options.stageRecorder, '
|
|
102
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage1.sse_decode', {
|
|
103
103
|
streamDetected: true,
|
|
104
104
|
decoded: false,
|
|
105
105
|
protocol: options.providerProtocol,
|
|
106
106
|
error: message
|
|
107
107
|
});
|
|
108
|
-
throw new ProviderProtocolError(`[
|
|
108
|
+
throw new ProviderProtocolError(`[chat_process.resp.stage1.sse_decode] Failed to decode SSE payload for protocol ${options.providerProtocol}: ${message}`, {
|
|
109
109
|
code: 'SSE_DECODE_ERROR',
|
|
110
110
|
protocol: options.providerProtocol,
|
|
111
111
|
providerType: resolveProviderType(options.providerProtocol),
|
|
112
112
|
details: {
|
|
113
|
-
phase: '
|
|
113
|
+
phase: 'chat_process.resp.stage1.sse_decode',
|
|
114
114
|
requestId: options.adapterContext.requestId,
|
|
115
115
|
message
|
|
116
116
|
}
|
package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage2_format_parse/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { recordStage } from '../../../stages/utils.js';
|
|
2
2
|
export async function runRespInboundStage2FormatParse(options) {
|
|
3
3
|
const envelope = (await options.formatAdapter.parseResponse(options.payload, options.adapterContext));
|
|
4
|
-
recordStage(options.stageRecorder, '
|
|
4
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage2.format_parse', envelope);
|
|
5
5
|
return envelope;
|
|
6
6
|
}
|
package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export interface RespInboundStage3SemanticMapOptions {
|
|
|
7
7
|
adapterContext: AdapterContext;
|
|
8
8
|
formatEnvelope: FormatEnvelope<JsonObject>;
|
|
9
9
|
mapper: ResponseMapper;
|
|
10
|
+
requestSemantics?: JsonObject;
|
|
10
11
|
stageRecorder?: StageRecorder;
|
|
11
12
|
}
|
|
12
13
|
export declare function runRespInboundStage3SemanticMap(options: RespInboundStage3SemanticMapOptions): Promise<ChatCompletionLike>;
|
package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage3_semantic_map/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { recordStage } from '../../../stages/utils.js';
|
|
2
2
|
export async function runRespInboundStage3SemanticMap(options) {
|
|
3
|
-
const chatResponse = await options.mapper.toChatCompletion(options.formatEnvelope, options.adapterContext
|
|
4
|
-
|
|
3
|
+
const chatResponse = await options.mapper.toChatCompletion(options.formatEnvelope, options.adapterContext, {
|
|
4
|
+
requestSemantics: options.requestSemantics
|
|
5
|
+
});
|
|
6
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage4.semantic_map_to_chat', chatResponse);
|
|
5
7
|
return chatResponse;
|
|
6
8
|
}
|
|
@@ -7,6 +7,7 @@ export interface RespOutboundStage1ClientRemapOptions {
|
|
|
7
7
|
clientProtocol: ClientProtocol;
|
|
8
8
|
requestId: string;
|
|
9
9
|
adapterContext?: AdapterContext;
|
|
10
|
+
requestSemantics?: JsonObject;
|
|
10
11
|
stageRecorder?: StageRecorder;
|
|
11
12
|
}
|
|
12
13
|
export declare function runRespOutboundStage1ClientRemap(options: RespOutboundStage1ClientRemapOptions): JsonObject;
|
package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js
CHANGED
|
@@ -8,24 +8,28 @@ export function runRespOutboundStage1ClientRemap(options) {
|
|
|
8
8
|
}
|
|
9
9
|
else if (options.clientProtocol === 'anthropic-messages') {
|
|
10
10
|
clientPayload = buildAnthropicResponseFromChat(options.payload, {
|
|
11
|
-
aliasMap:
|
|
11
|
+
aliasMap: resolveAliasMapFromSemantics(options.requestSemantics)
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
else {
|
|
15
|
-
const toolsRaw =
|
|
15
|
+
const toolsRaw = resolveClientToolsRawFromSemantics(options.requestSemantics);
|
|
16
16
|
clientPayload = buildResponsesPayloadFromChat(options.payload, {
|
|
17
17
|
requestId: options.requestId,
|
|
18
18
|
...(toolsRaw ? { toolsRaw } : {})
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
|
-
recordStage(options.stageRecorder, '
|
|
21
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage9.client_remap', clientPayload);
|
|
22
22
|
return clientPayload;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
25
|
-
if (!
|
|
24
|
+
function resolveAliasMapFromSemantics(semantics) {
|
|
25
|
+
if (!semantics || typeof semantics !== 'object' || Array.isArray(semantics)) {
|
|
26
26
|
return undefined;
|
|
27
27
|
}
|
|
28
|
-
const
|
|
28
|
+
const toolsNode = semantics.tools;
|
|
29
|
+
if (!toolsNode || typeof toolsNode !== 'object' || Array.isArray(toolsNode)) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const candidate = toolsNode.toolNameAliasMap;
|
|
29
33
|
if (!candidate || typeof candidate !== 'object' || Array.isArray(candidate)) {
|
|
30
34
|
return undefined;
|
|
31
35
|
}
|
|
@@ -43,11 +47,15 @@ function resolveAliasMapFromContext(adapterContext) {
|
|
|
43
47
|
}
|
|
44
48
|
return Object.keys(map).length ? map : undefined;
|
|
45
49
|
}
|
|
46
|
-
function
|
|
47
|
-
if (!
|
|
50
|
+
function resolveClientToolsRawFromSemantics(semantics) {
|
|
51
|
+
if (!semantics || typeof semantics !== 'object' || Array.isArray(semantics)) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
const toolsNode = semantics.tools;
|
|
55
|
+
if (!toolsNode || typeof toolsNode !== 'object' || Array.isArray(toolsNode)) {
|
|
48
56
|
return undefined;
|
|
49
57
|
}
|
|
50
|
-
const candidate =
|
|
58
|
+
const candidate = toolsNode.clientToolsRaw;
|
|
51
59
|
if (!candidate || !Array.isArray(candidate)) {
|
|
52
60
|
return undefined;
|
|
53
61
|
}
|
package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { defaultSseCodecRegistry } from '../../../../../../sse/index.js';
|
|
|
2
2
|
import { recordStage } from '../../../stages/utils.js';
|
|
3
3
|
export async function runRespOutboundStage2SseStream(options) {
|
|
4
4
|
if (!options.wantsStream) {
|
|
5
|
-
recordStage(options.stageRecorder, '
|
|
5
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage10.sse_stream', {
|
|
6
6
|
passthrough: false,
|
|
7
7
|
protocol: options.clientProtocol,
|
|
8
8
|
payload: options.clientPayload
|
|
@@ -13,7 +13,7 @@ export async function runRespOutboundStage2SseStream(options) {
|
|
|
13
13
|
const stream = await codec.convertJsonToSse(options.clientPayload, {
|
|
14
14
|
requestId: options.requestId
|
|
15
15
|
});
|
|
16
|
-
recordStage(options.stageRecorder, '
|
|
16
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage10.sse_stream', {
|
|
17
17
|
passthrough: false,
|
|
18
18
|
protocol: options.clientProtocol,
|
|
19
19
|
payload: options.clientPayload
|
|
@@ -1,17 +1,55 @@
|
|
|
1
1
|
import { runChatResponseToolFilters } from '../../../../../shared/tool-filter-pipeline.js';
|
|
2
2
|
import { normalizeApplyPatchToolCallsOnResponse } from '../../../../../shared/tool-governor.js';
|
|
3
|
+
import { buildChatResponseFromResponses } from '../../../../../shared/responses-response-utils.js';
|
|
3
4
|
import { ToolGovernanceEngine } from '../../../../tool-governance/index.js';
|
|
4
5
|
import { recordStage } from '../../../stages/utils.js';
|
|
5
6
|
const toolGovernanceEngine = new ToolGovernanceEngine();
|
|
7
|
+
function isCanonicalChatCompletion(payload) {
|
|
8
|
+
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
const obj = payload;
|
|
12
|
+
const choices = Array.isArray(obj.choices) ? obj.choices : [];
|
|
13
|
+
if (!choices.length)
|
|
14
|
+
return false;
|
|
15
|
+
const first = choices[0] && typeof choices[0] === 'object' && !Array.isArray(choices[0]) ? choices[0] : null;
|
|
16
|
+
if (!first)
|
|
17
|
+
return false;
|
|
18
|
+
const msg = first.message;
|
|
19
|
+
return Boolean(msg && typeof msg === 'object' && !Array.isArray(msg));
|
|
20
|
+
}
|
|
21
|
+
function coerceToCanonicalChatCompletion(payload) {
|
|
22
|
+
if (isCanonicalChatCompletion(payload)) {
|
|
23
|
+
return payload;
|
|
24
|
+
}
|
|
25
|
+
// ServerTool followups may re-enter via the client protocol shape (e.g. OpenAI Responses object:'response').
|
|
26
|
+
// Response tool governance requires an OpenAI-chat-like surface (choices[].message) so text tool harvesting
|
|
27
|
+
// and tool governance remain a single fixed path.
|
|
28
|
+
try {
|
|
29
|
+
const coerced = buildChatResponseFromResponses(payload);
|
|
30
|
+
if (isCanonicalChatCompletion(coerced)) {
|
|
31
|
+
return coerced;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// best-effort: keep original payload when bridge fails
|
|
36
|
+
}
|
|
37
|
+
return payload;
|
|
38
|
+
}
|
|
6
39
|
export async function runRespProcessStage1ToolGovernance(options) {
|
|
7
|
-
const
|
|
40
|
+
const canonicalInput = coerceToCanonicalChatCompletion(options.payload);
|
|
41
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage6.canonicalize_chat_completion', {
|
|
42
|
+
converted: canonicalInput !== options.payload,
|
|
43
|
+
canonicalPayload: canonicalInput
|
|
44
|
+
});
|
|
45
|
+
const filtered = await runChatResponseToolFilters(canonicalInput, {
|
|
8
46
|
entryEndpoint: options.entryEndpoint,
|
|
9
47
|
requestId: options.requestId,
|
|
10
48
|
profile: 'openai-chat'
|
|
11
49
|
});
|
|
12
50
|
const patched = normalizeApplyPatchToolCallsOnResponse(filtered);
|
|
13
51
|
const { payload: governed, summary } = toolGovernanceEngine.governResponse(patched, options.clientProtocol);
|
|
14
|
-
recordStage(options.stageRecorder, '
|
|
52
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage7.tool_governance', {
|
|
15
53
|
summary,
|
|
16
54
|
applied: summary?.applied,
|
|
17
55
|
filteredPayload: patched,
|
package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js
CHANGED
|
@@ -11,7 +11,7 @@ export async function runRespProcessStage2Finalize(options) {
|
|
|
11
11
|
const processedRequest = buildProcessedRequestFromChatResponse(finalized, {
|
|
12
12
|
stream: options.wantsStream
|
|
13
13
|
});
|
|
14
|
-
recordStage(options.stageRecorder, '
|
|
14
|
+
recordStage(options.stageRecorder, 'chat_process.resp.stage8.finalize', {
|
|
15
15
|
model: finalized.model,
|
|
16
16
|
stream: options.wantsStream
|
|
17
17
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ensureRuntimeMetadata } from '../../shared/runtime-metadata.js';
|
|
1
2
|
export function applyTargetMetadata(metadata, target, routeName, originalModel) {
|
|
2
3
|
if (!metadata || typeof metadata !== 'object') {
|
|
3
4
|
return;
|
|
@@ -9,11 +10,14 @@ export function applyTargetMetadata(metadata, target, routeName, originalModel)
|
|
|
9
10
|
metadata.providerType = target.providerType;
|
|
10
11
|
metadata.modelId = target.modelId;
|
|
11
12
|
metadata.processMode = target.processMode || 'chat';
|
|
12
|
-
if (target.forceWebSearch === true) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
if (target.forceWebSearch === true || target.forceVision === true) {
|
|
14
|
+
const rt = ensureRuntimeMetadata(metadata);
|
|
15
|
+
if (target.forceWebSearch === true) {
|
|
16
|
+
rt.forceWebSearch = true;
|
|
17
|
+
}
|
|
18
|
+
if (target.forceVision === true) {
|
|
19
|
+
rt.forceVision = true;
|
|
20
|
+
}
|
|
17
21
|
}
|
|
18
22
|
if (target.responsesConfig?.toolCallIdStyle) {
|
|
19
23
|
metadata.toolCallIdStyle = target.responsesConfig.toolCallIdStyle;
|