@jsonstudio/rcc 0.90.814 → 0.90.876
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/README.md +8 -0
- package/configsamples/provider-default/ali-coding-plan/config.v2.json +76 -0
- package/configsamples/provider-default/antigravity/config.v2.json +142 -0
- package/configsamples/provider-default/ark-coding-plan/config.v2.json +64 -0
- package/configsamples/provider-default/crs/config.v2.json +54 -0
- package/configsamples/provider-default/deepseek-web/config.v2.json +56 -0
- package/configsamples/provider-default/gemini/config.v2.json +43 -0
- package/configsamples/provider-default/gemini-cli/config.v2.json +45 -0
- package/configsamples/provider-default/gemini-native/config.v2.json +208 -0
- package/configsamples/provider-default/glm/config.v2.json +33 -0
- package/configsamples/provider-default/glm-anthropic/config.v2.json +29 -0
- package/configsamples/provider-default/kimi/config.v2.json +25 -0
- package/configsamples/provider-default/lmstudio/config.v2.json +79 -0
- package/configsamples/provider-default/lmstudio-proxy/config.v2.json +78 -0
- package/configsamples/provider-default/manifest.json +31 -0
- package/configsamples/provider-default/meituan/config.v2.json +20 -0
- package/configsamples/provider-default/mimo/config.v2.json +26 -0
- package/configsamples/provider-default/modelscope/config.v2.json +81 -0
- package/configsamples/provider-default/my-openai/config.v2.json +20 -0
- package/configsamples/provider-default/nvidia/config.v2.json +32 -0
- package/configsamples/provider-default/opencode-zen-free/config.v2.json +56 -0
- package/configsamples/provider-default/openrouter/config.v2.json +210 -0
- package/configsamples/provider-default/qwen/config.v2.json +38 -0
- package/configsamples/provider-default/qwenchat/config.v2.json +53 -0
- package/configsamples/provider-default/tab/config.v2.json +26 -0
- package/configsamples/provider-default/tabglm/config.v2.json +77 -0
- package/dist/build-info.js +2 -2
- package/dist/cli/commands/config.d.ts +5 -0
- package/dist/cli/commands/config.js +369 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/examples.js +3 -0
- package/dist/cli/commands/examples.js.map +1 -1
- package/dist/cli/commands/init.js +25 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/launcher-kernel.js +122 -46
- package/dist/cli/commands/launcher-kernel.js.map +1 -1
- package/dist/cli/commands/start.js +60 -3
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/config/bundled-provider-pack.d.ts +20 -0
- package/dist/cli/config/bundled-provider-pack.js +146 -0
- package/dist/cli/config/bundled-provider-pack.js.map +1 -0
- package/dist/cli/register/status-config-commands.d.ts +2 -0
- package/dist/cli/register/status-config-commands.js.map +1 -1
- package/dist/cli.js +81 -28
- package/dist/cli.js.map +1 -1
- package/dist/debug/snapshot-store.js +2 -1
- package/dist/debug/snapshot-store.js.map +1 -1
- package/dist/index.js +23 -14
- package/dist/index.js.map +1 -1
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js +1 -1
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js.map +1 -1
- package/dist/manager/quota/provider-quota-center.js +1 -1
- package/dist/manager/quota/provider-quota-center.js.map +1 -1
- package/dist/manager/storage/file-store.js +10 -0
- package/dist/manager/storage/file-store.js.map +1 -1
- package/dist/modules/llmswitch/bridge/snapshot-recorder-runtime.js +18 -1
- package/dist/modules/llmswitch/bridge/snapshot-recorder-runtime.js.map +1 -1
- package/dist/modules/llmswitch/bridge/snapshot-recorder.js +132 -51
- package/dist/modules/llmswitch/bridge/snapshot-recorder.js.map +1 -1
- package/dist/provider-sdk/provider-runtime-inference.js +2 -2
- package/dist/provider-sdk/provider-runtime-inference.js.map +1 -1
- package/dist/providers/auth/deepseek-account-token-acquirer.js +32 -3
- package/dist/providers/auth/deepseek-account-token-acquirer.js.map +1 -1
- package/dist/providers/core/api/provider-types.d.ts +11 -0
- package/dist/providers/core/config/service-profiles.js +1 -1
- package/dist/providers/core/runtime/deepseek-http-provider.d.ts +2 -0
- package/dist/providers/core/runtime/deepseek-http-provider.js +31 -1
- package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/qwenchat-http-provider-helpers.d.ts +3 -2
- package/dist/providers/core/runtime/qwenchat-http-provider-helpers.js +513 -96
- package/dist/providers/core/runtime/qwenchat-http-provider-helpers.js.map +1 -1
- package/dist/providers/core/runtime/standard-tool-text-harvest.d.ts +8 -0
- package/dist/providers/core/runtime/standard-tool-text-harvest.js +24 -0
- package/dist/providers/core/runtime/standard-tool-text-harvest.js.map +1 -0
- package/dist/providers/core/runtime/standard-tool-text-request-transform.d.ts +4 -1
- package/dist/providers/core/runtime/standard-tool-text-request-transform.js +129 -3
- package/dist/providers/core/runtime/standard-tool-text-request-transform.js.map +1 -1
- package/dist/providers/core/utils/snapshot-writer.js +5 -2
- package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
- package/dist/providers/profile/provider-profile-loader.js +52 -1
- package/dist/providers/profile/provider-profile-loader.js.map +1 -1
- package/dist/providers/profile/provider-profile.d.ts +3 -0
- package/dist/server/handlers/handler-response-utils.js +1 -0
- package/dist/server/handlers/handler-response-utils.js.map +1 -1
- package/dist/server/handlers/images-handler.d.ts +9 -0
- package/dist/server/handlers/images-handler.js +258 -0
- package/dist/server/handlers/images-handler.js.map +1 -0
- package/dist/server/handlers/types.d.ts +7 -0
- package/dist/server/runtime/http-server/antigravity-startup-tasks.d.ts +3 -0
- package/dist/server/runtime/http-server/antigravity-startup-tasks.js +16 -0
- package/dist/server/runtime/http-server/antigravity-startup-tasks.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +3 -18
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.d.ts +7 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.js +17 -0
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-utils.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +50 -17
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin-routes.js +32 -2
- package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
- package/dist/server/runtime/http-server/executor/provider-response-converter.js +42 -13
- package/dist/server/runtime/http-server/executor/provider-response-converter.js.map +1 -1
- package/dist/server/runtime/http-server/executor/provider-response-utils.js +41 -3
- package/dist/server/runtime/http-server/executor/provider-response-utils.js.map +1 -1
- package/dist/server/runtime/http-server/executor/usage-aggregator.js +7 -7
- package/dist/server/runtime/http-server/executor/usage-aggregator.js.map +1 -1
- package/dist/server/runtime/http-server/executor/usage-logger.d.ts +9 -0
- package/dist/server/runtime/http-server/executor/usage-logger.js +35 -2
- package/dist/server/runtime/http-server/executor/usage-logger.js.map +1 -1
- package/dist/server/runtime/http-server/executor-metadata.js +12 -4
- package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
- package/dist/server/runtime/http-server/executor-pipeline.js +24 -15
- package/dist/server/runtime/http-server/executor-pipeline.js.map +1 -1
- package/dist/server/runtime/http-server/executor-provider.d.ts +6 -1
- package/dist/server/runtime/http-server/executor-provider.js +137 -5
- package/dist/server/runtime/http-server/executor-provider.js.map +1 -1
- package/dist/server/runtime/http-server/http-server-bootstrap.js +6 -0
- package/dist/server/runtime/http-server/http-server-bootstrap.js.map +1 -1
- package/dist/server/runtime/http-server/http-server-lifecycle.js +23 -15
- package/dist/server/runtime/http-server/http-server-lifecycle.js.map +1 -1
- package/dist/server/runtime/http-server/http-server-runtime-providers.js +14 -4
- package/dist/server/runtime/http-server/http-server-runtime-providers.js.map +1 -1
- package/dist/server/runtime/http-server/http-server-runtime-setup.js +83 -1
- package/dist/server/runtime/http-server/http-server-runtime-setup.js.map +1 -1
- package/dist/server/runtime/http-server/hub-shadow-compare.js +2 -41
- package/dist/server/runtime/http-server/hub-shadow-compare.js.map +1 -1
- package/dist/server/runtime/http-server/provider-routing-scope.d.ts +9 -0
- package/dist/server/runtime/http-server/provider-routing-scope.js +20 -0
- package/dist/server/runtime/http-server/provider-routing-scope.js.map +1 -0
- package/dist/server/runtime/http-server/provider-traffic-governor.d.ts +67 -0
- package/dist/server/runtime/http-server/provider-traffic-governor.js +467 -0
- package/dist/server/runtime/http-server/provider-traffic-governor.js.map +1 -0
- package/dist/server/runtime/http-server/request-executor.d.ts +8 -0
- package/dist/server/runtime/http-server/request-executor.js +446 -21
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.js +13 -0
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/session-client-registry.js +30 -4
- package/dist/server/runtime/http-server/session-client-registry.js.map +1 -1
- package/dist/server/runtime/http-server/session-client-route-utils.d.ts +7 -0
- package/dist/server/runtime/http-server/session-client-route-utils.js +38 -0
- package/dist/server/runtime/http-server/session-client-route-utils.js.map +1 -1
- package/dist/server/runtime/http-server/session-client-routes.js +12 -2
- package/dist/server/runtime/http-server/session-client-routes.js.map +1 -1
- package/dist/server/utils/request-id-manager.js +42 -5
- package/dist/server/utils/request-id-manager.js.map +1 -1
- package/dist/server/utils/stage-logger.d.ts +1 -0
- package/dist/server/utils/stage-logger.js +27 -0
- package/dist/server/utils/stage-logger.js.map +1 -1
- package/dist/utils/errorsamples.js +3 -1
- package/dist/utils/errorsamples.js.map +1 -1
- package/dist/utils/sensitive-redaction.d.ts +1 -0
- package/dist/utils/sensitive-redaction.js +122 -0
- package/dist/utils/sensitive-redaction.js.map +1 -0
- package/dist/utils/snapshot-writer.js +162 -2
- package/dist/utils/snapshot-writer.js.map +1 -1
- package/docs/INSTALLATION_AND_QUICKSTART.md +14 -1
- package/docs/PORTS.md +12 -0
- package/docs/lmstudio-tool-calling.md +25 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwenchat-web-request.d.ts +3 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/actions/qwenchat-web-request.js +62 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-qwenchat-web.json +47 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/node-support.js +5 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/operation-table/operation-table-runner.js +68 -7
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper-from-chat.js +138 -3
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-chat-process-request-utils.js +24 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-execute-chat-process-entry.js +7 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-execute-request-stage.js +7 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-heavy-input-fastpath.d.ts +24 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-heavy-input-fastpath.js +203 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline-route-and-outbound.js +17 -12
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-stage-timing.d.ts +11 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-stage-timing.js +82 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +47 -14
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage1_semantic_map/index.js +43 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/client-remap-protocol-switch.js +222 -19
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/policy/policy-engine.js +2 -2
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/process/chat-process-pending-tool-sync.js +24 -7
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.js +90 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/snapshot-recorder.d.ts +1 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/snapshot-recorder.js +252 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge/utils.js +5 -3
- package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.js +44 -4
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/anthropic-message-utils-openai-request.d.ts +3 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/anthropic-message-utils-openai-request.js +20 -23
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-governor.js +68 -30
- package/node_modules/@jsonstudio/llms/dist/conversion/snapshot-utils.js +194 -10
- package/node_modules/@jsonstudio/llms/dist/native/router_hotpath_napi.node +0 -0
- package/node_modules/@jsonstudio/llms/dist/quota/quota-state.js +2 -2
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine/routing-state/store.js +35 -2
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.js +9 -9
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/sticky-session-store.js +104 -18
- package/node_modules/@jsonstudio/llms/dist/servertool/engine.js +79 -32
- package/node_modules/@jsonstudio/llms/dist/servertool/handlers/vision.js +49 -0
- package/node_modules/@jsonstudio/llms/dist/servertool/pending-session.js +48 -2
- package/node_modules/@jsonstudio/llms/dist/servertool/server-side-tools.js +14 -1
- package/node_modules/@jsonstudio/llms/dist/servertool/types.d.ts +1 -0
- package/node_modules/@jsonstudio/llms/package.json +1 -1
- package/node_modules/ajv/dist/compile/jtd/serialize.js +9 -2
- package/node_modules/ajv/dist/compile/jtd/serialize.js.map +1 -1
- package/node_modules/ajv/dist/core.d.ts +1 -0
- package/node_modules/ajv/dist/core.js.map +1 -1
- package/node_modules/ajv/dist/vocabularies/validation/pattern.js +13 -4
- package/node_modules/ajv/dist/vocabularies/validation/pattern.js.map +1 -1
- package/node_modules/ajv/lib/compile/jtd/serialize.ts +13 -2
- package/node_modules/ajv/lib/core.ts +1 -0
- package/node_modules/ajv/lib/vocabularies/validation/pattern.ts +15 -4
- package/node_modules/ajv/package.json +2 -1
- package/package.json +15 -10
- package/scripts/ci/repo-sanity.mjs +23 -2
- package/scripts/ci/secrets-check.mjs +48 -0
- package/scripts/ci/silent-failure-audit.mjs +192 -0
- package/scripts/mock-provider/run-regressions.mjs +1 -0
- package/scripts/monitor/memory-guard.mjs +207 -0
- package/scripts/pack-mode.mjs +32 -36
- package/scripts/publish-rcc.mjs +38 -60
- package/scripts/tests/apply-patch-loop.mjs +1 -0
- package/scripts/tests/blackbox-rcc-vs-routecodex-antigravity.mjs +2 -0
- package/scripts/tools-dev/responses-debug-client/src/index.ts +8 -3
- package/scripts/verify-e2e-toolcall.mjs +1 -0
- package/scripts/verify-install-e2e.mjs +2 -1
|
@@ -14,7 +14,7 @@ import { runRespProcessStage3ServerToolOrchestration } from '../pipeline/stages/
|
|
|
14
14
|
import { runRespOutboundStage1ClientRemap } from '../pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js';
|
|
15
15
|
import { runRespOutboundStage2SseStream } from '../pipeline/stages/resp_outbound/resp_outbound_stage2_sse_stream/index.js';
|
|
16
16
|
import { applyResponseBlacklistWithNative } from '../../../router/virtual-router/engine-selection/native-compat-action-semantics.js';
|
|
17
|
-
import { measureHubStage } from '../pipeline/hub-stage-timing.js';
|
|
17
|
+
import { measureHubStage, peekHubStageTopSummary } from '../pipeline/hub-stage-timing.js';
|
|
18
18
|
import { recordResponsesResponse } from '../../shared/responses-conversation-store.js';
|
|
19
19
|
import { saveChatProcessSessionActualUsage } from '../process/chat-process-session-usage.js';
|
|
20
20
|
import { coerceClientPayloadToCanonicalChatCompletionOrThrow, maybeCommitClockReservationFromContext, resolveProviderResponseContextSignals } from './provider-response-helpers.js';
|
|
@@ -47,6 +47,94 @@ const INTERNAL_POLICY_DEBUG_BLACKLIST_PATHS = [
|
|
|
47
47
|
'__responses_passthrough',
|
|
48
48
|
'anthropicToolNameMap'
|
|
49
49
|
];
|
|
50
|
+
function normalizeHubStageTopEntries(raw) {
|
|
51
|
+
if (!Array.isArray(raw) || raw.length === 0) {
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
return raw
|
|
55
|
+
.map((entry) => {
|
|
56
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const record = entry;
|
|
60
|
+
const stage = typeof record.stage === 'string' ? record.stage.trim() : '';
|
|
61
|
+
const totalMs = typeof record.totalMs === 'number' && Number.isFinite(record.totalMs)
|
|
62
|
+
? Math.max(0, Math.round(record.totalMs))
|
|
63
|
+
: undefined;
|
|
64
|
+
if (!stage || totalMs === undefined) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const count = typeof record.count === 'number' && Number.isFinite(record.count)
|
|
68
|
+
? Math.max(0, Math.floor(record.count))
|
|
69
|
+
: undefined;
|
|
70
|
+
const avgMs = typeof record.avgMs === 'number' && Number.isFinite(record.avgMs)
|
|
71
|
+
? Math.max(0, Math.round(record.avgMs))
|
|
72
|
+
: undefined;
|
|
73
|
+
const maxMs = typeof record.maxMs === 'number' && Number.isFinite(record.maxMs)
|
|
74
|
+
? Math.max(0, Math.round(record.maxMs))
|
|
75
|
+
: undefined;
|
|
76
|
+
return {
|
|
77
|
+
stage,
|
|
78
|
+
totalMs,
|
|
79
|
+
...(count !== undefined ? { count } : {}),
|
|
80
|
+
...(avgMs !== undefined ? { avgMs } : {}),
|
|
81
|
+
...(maxMs !== undefined ? { maxMs } : {})
|
|
82
|
+
};
|
|
83
|
+
})
|
|
84
|
+
.filter((entry) => Boolean(entry));
|
|
85
|
+
}
|
|
86
|
+
function mergeHubStageTopEntries(baseEntries, appendEntries) {
|
|
87
|
+
if (baseEntries.length === 0) {
|
|
88
|
+
return appendEntries;
|
|
89
|
+
}
|
|
90
|
+
if (appendEntries.length === 0) {
|
|
91
|
+
return baseEntries;
|
|
92
|
+
}
|
|
93
|
+
const merged = new Map();
|
|
94
|
+
const apply = (entry) => {
|
|
95
|
+
const existing = merged.get(entry.stage);
|
|
96
|
+
if (!existing) {
|
|
97
|
+
merged.set(entry.stage, { ...entry });
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const totalMs = Math.max(0, Math.round((existing.totalMs ?? 0) + (entry.totalMs ?? 0)));
|
|
101
|
+
const count = Math.max(0, Math.round((existing.count ?? 0) + (entry.count ?? 0)));
|
|
102
|
+
const maxMs = Math.max(existing.maxMs ?? 0, entry.maxMs ?? 0, entry.totalMs ?? 0);
|
|
103
|
+
merged.set(entry.stage, {
|
|
104
|
+
stage: entry.stage,
|
|
105
|
+
totalMs,
|
|
106
|
+
...(count > 0 ? { count } : {}),
|
|
107
|
+
...(count > 0 ? { avgMs: Math.max(0, Math.round(totalMs / count)) } : {}),
|
|
108
|
+
...(maxMs > 0 ? { maxMs } : {})
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
for (const item of baseEntries) {
|
|
112
|
+
apply(item);
|
|
113
|
+
}
|
|
114
|
+
for (const item of appendEntries) {
|
|
115
|
+
apply(item);
|
|
116
|
+
}
|
|
117
|
+
return Array.from(merged.values()).sort((a, b) => b.totalMs - a.totalMs);
|
|
118
|
+
}
|
|
119
|
+
function attachHubStageTopToContext(context, requestId) {
|
|
120
|
+
if (!requestId || requestId === 'unknown') {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const latest = normalizeHubStageTopEntries(peekHubStageTopSummary(requestId, { topN: 12, minMs: 1 }));
|
|
124
|
+
if (latest.length === 0) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const contextRecord = context;
|
|
128
|
+
const rt = contextRecord.__rt && typeof contextRecord.__rt === 'object' && !Array.isArray(contextRecord.__rt)
|
|
129
|
+
? contextRecord.__rt
|
|
130
|
+
: {};
|
|
131
|
+
const existing = normalizeHubStageTopEntries(rt.hubStageTop);
|
|
132
|
+
const merged = mergeHubStageTopEntries(existing, latest);
|
|
133
|
+
contextRecord.__rt = {
|
|
134
|
+
...rt,
|
|
135
|
+
hubStageTop: merged
|
|
136
|
+
};
|
|
137
|
+
}
|
|
50
138
|
export async function convertProviderResponse(options) {
|
|
51
139
|
const requestId = options.context.requestId || 'unknown';
|
|
52
140
|
const contextSignals = resolveProviderResponseContextSignals(options.context, options.entryEndpoint);
|
|
@@ -265,6 +353,7 @@ export async function convertProviderResponse(options) {
|
|
|
265
353
|
hasBody: Boolean(value.body)
|
|
266
354
|
})
|
|
267
355
|
});
|
|
356
|
+
attachHubStageTopToContext(options.context, requestId);
|
|
268
357
|
// Commit scheduled-task delivery only after a successful client payload/stream is prepared.
|
|
269
358
|
await maybeCommitClockReservationFromContext(options.context);
|
|
270
359
|
try {
|
|
@@ -4,6 +4,7 @@ export interface SnapshotStageRecorderOptions {
|
|
|
4
4
|
context: AdapterContext;
|
|
5
5
|
endpoint: string;
|
|
6
6
|
}
|
|
7
|
+
export declare function trimSnapshotHotpathPayloadForNative(stage: string, payload: unknown): unknown;
|
|
7
8
|
export declare class SnapshotStageRecorder implements StageRecorder {
|
|
8
9
|
private readonly options;
|
|
9
10
|
private readonly writer?;
|
|
@@ -1,5 +1,255 @@
|
|
|
1
1
|
import { createSnapshotWriter } from '../snapshot-utils.js';
|
|
2
2
|
import { normalizeSnapshotStagePayloadWithNative } from '../../router/virtual-router/engine-selection/native-snapshot-hooks.js';
|
|
3
|
+
const SNAPSHOT_STRING_PREVIEW_CHARS = 240;
|
|
4
|
+
const SNAPSHOT_ARRAY_PREVIEW_ITEMS = 2;
|
|
5
|
+
const FORMAT_PARSE_STAGE_NAMES = new Set([
|
|
6
|
+
'req_inbound_stage1_format_parse',
|
|
7
|
+
'chat_process.req.stage1.format_parse'
|
|
8
|
+
]);
|
|
9
|
+
const TOOL_GOVERNANCE_STAGE_NAMES = new Set([
|
|
10
|
+
'req_process_stage1_tool_governance',
|
|
11
|
+
'chat_process.req.stage4.tool_governance'
|
|
12
|
+
]);
|
|
13
|
+
function clipSnapshotString(value) {
|
|
14
|
+
const text = String(value ?? '');
|
|
15
|
+
return text.length > SNAPSHOT_STRING_PREVIEW_CHARS
|
|
16
|
+
? `${text.slice(0, SNAPSHOT_STRING_PREVIEW_CHARS)}…`
|
|
17
|
+
: text;
|
|
18
|
+
}
|
|
19
|
+
function summarizeScalar(value) {
|
|
20
|
+
if (typeof value === 'string') {
|
|
21
|
+
return clipSnapshotString(value);
|
|
22
|
+
}
|
|
23
|
+
if (value === null ||
|
|
24
|
+
value === undefined ||
|
|
25
|
+
typeof value === 'number' ||
|
|
26
|
+
typeof value === 'boolean') {
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
function summarizeValuePreview(value, depth = 0) {
|
|
32
|
+
const scalar = summarizeScalar(value);
|
|
33
|
+
if (scalar !== undefined || value === null) {
|
|
34
|
+
return scalar;
|
|
35
|
+
}
|
|
36
|
+
if (Array.isArray(value)) {
|
|
37
|
+
if (depth >= 2) {
|
|
38
|
+
return { type: 'array', count: value.length };
|
|
39
|
+
}
|
|
40
|
+
const first = value.slice(0, SNAPSHOT_ARRAY_PREVIEW_ITEMS).map((entry) => summarizeValuePreview(entry, depth + 1));
|
|
41
|
+
const last = value.slice(-SNAPSHOT_ARRAY_PREVIEW_ITEMS).map((entry) => summarizeValuePreview(entry, depth + 1));
|
|
42
|
+
return {
|
|
43
|
+
type: 'array',
|
|
44
|
+
count: value.length,
|
|
45
|
+
first,
|
|
46
|
+
last
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (!value || typeof value !== 'object') {
|
|
50
|
+
return String(value);
|
|
51
|
+
}
|
|
52
|
+
const record = value;
|
|
53
|
+
const keys = Object.keys(record);
|
|
54
|
+
const preferredKeys = ['role', 'type', 'name', 'id', 'call_id', 'content', 'text', 'input', 'output', 'status'];
|
|
55
|
+
const preview = {};
|
|
56
|
+
for (const key of preferredKeys) {
|
|
57
|
+
if (key in record) {
|
|
58
|
+
preview[key] = summarizeValuePreview(record[key], depth + 1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (!Object.keys(preview).length) {
|
|
62
|
+
for (const key of keys.slice(0, 6)) {
|
|
63
|
+
preview[key] = summarizeValuePreview(record[key], depth + 1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
type: 'object',
|
|
68
|
+
keys,
|
|
69
|
+
preview
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function summarizeCollection(value) {
|
|
73
|
+
if (!Array.isArray(value)) {
|
|
74
|
+
return summarizeValuePreview(value);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
count: value.length,
|
|
78
|
+
preview: summarizeValuePreview(value)
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function summarizeTools(value) {
|
|
82
|
+
if (!Array.isArray(value)) {
|
|
83
|
+
return summarizeValuePreview(value);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
count: value.length,
|
|
87
|
+
names: value
|
|
88
|
+
.map((tool) => {
|
|
89
|
+
if (!tool || typeof tool !== 'object') {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const node = tool;
|
|
93
|
+
if (typeof node.name === 'string' && node.name.trim()) {
|
|
94
|
+
return node.name.trim();
|
|
95
|
+
}
|
|
96
|
+
const fn = node.function;
|
|
97
|
+
if (fn && typeof fn === 'object' && typeof fn.name === 'string') {
|
|
98
|
+
return String(fn.name).trim();
|
|
99
|
+
}
|
|
100
|
+
return typeof node.type === 'string' ? node.type : null;
|
|
101
|
+
})
|
|
102
|
+
.filter((name) => Boolean(name))
|
|
103
|
+
.slice(0, 32)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function summarizeMetadata(value) {
|
|
107
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
108
|
+
return summarizeValuePreview(value);
|
|
109
|
+
}
|
|
110
|
+
const metadata = value;
|
|
111
|
+
const summary = {};
|
|
112
|
+
for (const key of [
|
|
113
|
+
'requestId',
|
|
114
|
+
'clientRequestId',
|
|
115
|
+
'providerProtocol',
|
|
116
|
+
'endpoint',
|
|
117
|
+
'entryEndpoint',
|
|
118
|
+
'originalEndpoint',
|
|
119
|
+
'processMode',
|
|
120
|
+
'sessionId',
|
|
121
|
+
'conversationId',
|
|
122
|
+
'workdir',
|
|
123
|
+
'cwd',
|
|
124
|
+
'processedAt',
|
|
125
|
+
'stage',
|
|
126
|
+
'stream'
|
|
127
|
+
]) {
|
|
128
|
+
if (key in metadata) {
|
|
129
|
+
summary[key] = summarizeValuePreview(metadata[key]);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if ('clientHeaders' in metadata) {
|
|
133
|
+
const headers = metadata.clientHeaders;
|
|
134
|
+
if (headers && typeof headers === 'object' && !Array.isArray(headers)) {
|
|
135
|
+
summary.clientHeaders = { keys: Object.keys(headers).sort() };
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
summary.clientHeaders = summarizeValuePreview(headers);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if ('capturedContext' in metadata) {
|
|
142
|
+
summary.capturedContext = summarizeValuePreview(metadata.capturedContext);
|
|
143
|
+
}
|
|
144
|
+
if ('__rt' in metadata) {
|
|
145
|
+
summary.__rt = summarizeValuePreview(metadata.__rt);
|
|
146
|
+
}
|
|
147
|
+
if ('__raw_request_body' in metadata) {
|
|
148
|
+
const raw = metadata.__raw_request_body;
|
|
149
|
+
summary.__raw_request_body = {
|
|
150
|
+
omitted: true,
|
|
151
|
+
preview: summarizeValuePreview(raw, 1)
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return summary;
|
|
155
|
+
}
|
|
156
|
+
function summarizeSemantics(value) {
|
|
157
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
158
|
+
return summarizeValuePreview(value);
|
|
159
|
+
}
|
|
160
|
+
const semantics = value;
|
|
161
|
+
const summary = {};
|
|
162
|
+
if ('tools' in semantics) {
|
|
163
|
+
const tools = semantics.tools;
|
|
164
|
+
const toolsRecord = tools && typeof tools === 'object' && !Array.isArray(tools) ? tools : null;
|
|
165
|
+
summary.tools = toolsRecord
|
|
166
|
+
? {
|
|
167
|
+
keys: Object.keys(toolsRecord).sort(),
|
|
168
|
+
toolNameAliasMap: summarizeValuePreview(toolsRecord.toolNameAliasMap, 1),
|
|
169
|
+
clientToolsRaw: summarizeTools(toolsRecord.clientToolsRaw)
|
|
170
|
+
}
|
|
171
|
+
: summarizeValuePreview(tools);
|
|
172
|
+
}
|
|
173
|
+
const responses = semantics.responses;
|
|
174
|
+
const responsesRecord = responses && typeof responses === 'object' && !Array.isArray(responses)
|
|
175
|
+
? responses
|
|
176
|
+
: null;
|
|
177
|
+
if (responsesRecord) {
|
|
178
|
+
const context = responsesRecord.context;
|
|
179
|
+
const contextRecord = context && typeof context === 'object' && !Array.isArray(context)
|
|
180
|
+
? context
|
|
181
|
+
: null;
|
|
182
|
+
summary.responses = contextRecord
|
|
183
|
+
? {
|
|
184
|
+
context: {
|
|
185
|
+
requestId: summarizeValuePreview(contextRecord.requestId),
|
|
186
|
+
isChatPayload: summarizeValuePreview(contextRecord.isChatPayload),
|
|
187
|
+
isResponsesPayload: summarizeValuePreview(contextRecord.isResponsesPayload),
|
|
188
|
+
systemInstruction: summarizeValuePreview(contextRecord.systemInstruction),
|
|
189
|
+
parameters: summarizeValuePreview(contextRecord.parameters, 1),
|
|
190
|
+
input: summarizeCollection(contextRecord.input),
|
|
191
|
+
__captured_tool_results: summarizeCollection(contextRecord.__captured_tool_results),
|
|
192
|
+
toolsRaw: summarizeTools(contextRecord.toolsRaw),
|
|
193
|
+
toolsNormalized: summarizeTools(contextRecord.toolsNormalized)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
: summarizeValuePreview(responsesRecord);
|
|
197
|
+
}
|
|
198
|
+
return summary;
|
|
199
|
+
}
|
|
200
|
+
function buildFormatParseSnapshotSummary(payload) {
|
|
201
|
+
const envelope = payload.payload && typeof payload.payload === 'object' && !Array.isArray(payload.payload)
|
|
202
|
+
? payload.payload
|
|
203
|
+
: null;
|
|
204
|
+
return {
|
|
205
|
+
__snapshot_summary: true,
|
|
206
|
+
stage: 'format_parse',
|
|
207
|
+
format: summarizeValuePreview(payload.format),
|
|
208
|
+
metadata: summarizeValuePreview(payload.metadata, 1),
|
|
209
|
+
payload: envelope
|
|
210
|
+
? {
|
|
211
|
+
model: summarizeValuePreview(envelope.model),
|
|
212
|
+
include: summarizeValuePreview(envelope.include, 1),
|
|
213
|
+
stream: summarizeValuePreview(envelope.stream),
|
|
214
|
+
tool_choice: summarizeValuePreview(envelope.tool_choice),
|
|
215
|
+
max_output_tokens: summarizeValuePreview(envelope.max_output_tokens),
|
|
216
|
+
max_tokens: summarizeValuePreview(envelope.max_tokens),
|
|
217
|
+
input: summarizeCollection(envelope.input),
|
|
218
|
+
messages: summarizeCollection(envelope.messages),
|
|
219
|
+
tools: summarizeTools(envelope.tools)
|
|
220
|
+
}
|
|
221
|
+
: summarizeValuePreview(payload.payload, 1)
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
function buildToolGovernanceSnapshotSummary(payload) {
|
|
225
|
+
return {
|
|
226
|
+
__snapshot_summary: true,
|
|
227
|
+
stage: 'tool_governance',
|
|
228
|
+
model: summarizeValuePreview(payload.model),
|
|
229
|
+
stream: summarizeValuePreview(payload.stream),
|
|
230
|
+
tool_choice: summarizeValuePreview(payload.tool_choice),
|
|
231
|
+
parameters: summarizeValuePreview(payload.parameters, 1),
|
|
232
|
+
processed: summarizeValuePreview(payload.processed, 1),
|
|
233
|
+
processingMetadata: summarizeValuePreview(payload.processingMetadata, 1),
|
|
234
|
+
messages: summarizeCollection(payload.messages),
|
|
235
|
+
tools: summarizeTools(payload.tools),
|
|
236
|
+
metadata: summarizeMetadata(payload.metadata),
|
|
237
|
+
semantics: summarizeSemantics(payload.semantics)
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
export function trimSnapshotHotpathPayloadForNative(stage, payload) {
|
|
241
|
+
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
242
|
+
return payload;
|
|
243
|
+
}
|
|
244
|
+
const record = payload;
|
|
245
|
+
if (FORMAT_PARSE_STAGE_NAMES.has(stage)) {
|
|
246
|
+
return buildFormatParseSnapshotSummary(record);
|
|
247
|
+
}
|
|
248
|
+
if (TOOL_GOVERNANCE_STAGE_NAMES.has(stage)) {
|
|
249
|
+
return buildToolGovernanceSnapshotSummary(record);
|
|
250
|
+
}
|
|
251
|
+
return payload;
|
|
252
|
+
}
|
|
3
253
|
export class SnapshotStageRecorder {
|
|
4
254
|
options;
|
|
5
255
|
writer;
|
|
@@ -21,7 +271,8 @@ export class SnapshotStageRecorder {
|
|
|
21
271
|
if (!this.writer) {
|
|
22
272
|
return;
|
|
23
273
|
}
|
|
24
|
-
const
|
|
274
|
+
const trimmed = trimSnapshotHotpathPayloadForNative(stage, payload);
|
|
275
|
+
const normalized = normalizeSnapshotStagePayloadWithNative(stage, trimmed);
|
|
25
276
|
if (!normalized) {
|
|
26
277
|
return;
|
|
27
278
|
}
|
package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge/utils.js
CHANGED
|
@@ -102,8 +102,10 @@ export function sanitizeCapturedResponsesInput(input) {
|
|
|
102
102
|
if (!sanitizedName) {
|
|
103
103
|
continue;
|
|
104
104
|
}
|
|
105
|
-
const
|
|
106
|
-
next
|
|
105
|
+
const rawName = typeof entry.name === 'string' ? String(entry.name) : '';
|
|
106
|
+
const next = rawName === sanitizedName
|
|
107
|
+
? entry
|
|
108
|
+
: { ...entry, name: sanitizedName };
|
|
107
109
|
const callId = typeof next.call_id === 'string' ? String(next.call_id).trim() : '';
|
|
108
110
|
if (callId) {
|
|
109
111
|
acceptedCallIds.add(callId);
|
|
@@ -117,7 +119,7 @@ export function sanitizeCapturedResponsesInput(input) {
|
|
|
117
119
|
continue;
|
|
118
120
|
}
|
|
119
121
|
}
|
|
120
|
-
out.push(
|
|
122
|
+
out.push(entry);
|
|
121
123
|
}
|
|
122
124
|
return out;
|
|
123
125
|
}
|
|
@@ -43,6 +43,43 @@ function filterRedundantResponsesReasoningAction(actions) {
|
|
|
43
43
|
return name !== 'reasoning.extract';
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
+
function hasToolSignalsInMessages(messages) {
|
|
47
|
+
for (const message of messages) {
|
|
48
|
+
if (!message || typeof message !== 'object') {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const role = typeof message.role === 'string' ? message.role.trim().toLowerCase() : '';
|
|
52
|
+
if (role === 'tool') {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
if (typeof message.tool_call_id === 'string' && message.tool_call_id.trim().length) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
const toolCalls = message.tool_calls;
|
|
59
|
+
if (Array.isArray(toolCalls) && toolCalls.length > 0) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
function filterResponsesInboundActionsByPayloadHints(actions, messages) {
|
|
66
|
+
if (!actions?.length) {
|
|
67
|
+
return actions;
|
|
68
|
+
}
|
|
69
|
+
const hasToolSignals = hasToolSignalsInMessages(messages);
|
|
70
|
+
if (hasToolSignals) {
|
|
71
|
+
return actions;
|
|
72
|
+
}
|
|
73
|
+
const toolOnlyActions = new Set([
|
|
74
|
+
'tools.normalize-call-ids',
|
|
75
|
+
'compat.fix-apply-patch',
|
|
76
|
+
'tools.ensure-placeholders'
|
|
77
|
+
]);
|
|
78
|
+
return actions.filter((action) => {
|
|
79
|
+
const name = typeof action?.name === 'string' ? action.name.trim().toLowerCase() : '';
|
|
80
|
+
return !toolOnlyActions.has(name);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
46
83
|
export function captureResponsesContext(payload, dto) {
|
|
47
84
|
const preservedInput = Array.isArray(payload.input)
|
|
48
85
|
? payload.input
|
|
@@ -71,9 +108,12 @@ export function captureResponsesContext(payload, dto) {
|
|
|
71
108
|
captured.systemInstruction = payload.instructions;
|
|
72
109
|
}
|
|
73
110
|
if (captured.metadata && isJsonObject(captured.metadata)) {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
111
|
+
const rawMetadata = captured.metadata;
|
|
112
|
+
if (Object.prototype.hasOwnProperty.call(rawMetadata, 'extraFields')) {
|
|
113
|
+
const cloned = jsonClone(rawMetadata);
|
|
114
|
+
delete cloned.extraFields;
|
|
115
|
+
captured.metadata = cloned;
|
|
116
|
+
}
|
|
77
117
|
}
|
|
78
118
|
return captured;
|
|
79
119
|
}
|
|
@@ -98,7 +138,7 @@ export function buildChatRequestFromResponses(payload, context) {
|
|
|
98
138
|
});
|
|
99
139
|
try {
|
|
100
140
|
const bridgePolicy = resolveBridgePolicy({ protocol: 'openai-responses', moduleType: 'openai-responses' });
|
|
101
|
-
const policyActions = filterRedundantResponsesReasoningAction(resolvePolicyActions(bridgePolicy, 'request_inbound'));
|
|
141
|
+
const policyActions = filterResponsesInboundActionsByPayloadHints(filterRedundantResponsesReasoningAction(resolvePolicyActions(bridgePolicy, 'request_inbound')), messages);
|
|
102
142
|
if (policyActions?.length) {
|
|
103
143
|
logHubStageTiming(requestId, 'req_inbound.responses.inbound_policy', 'start');
|
|
104
144
|
const policyStart = Date.now();
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
type Unknown = Record<string, unknown>;
|
|
2
|
-
export declare function buildAnthropicRequestFromOpenAIChat(chatReq: unknown
|
|
2
|
+
export declare function buildAnthropicRequestFromOpenAIChat(chatReq: unknown, options?: {
|
|
3
|
+
requestId?: string;
|
|
4
|
+
}): Unknown;
|
|
3
5
|
export {};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { createBridgeActionState, runBridgeActionPipeline } from '../bridge-actions.js';
|
|
2
|
-
import { resolveBridgePolicy, resolvePolicyActions } from '../bridge-policies.js';
|
|
3
1
|
import { mapChatToolsToAnthropicTools } from './anthropic-message-utils-tool-schema.js';
|
|
4
2
|
import { ProviderProtocolError } from '../provider-protocol-error.js';
|
|
5
3
|
import { jsonClone } from '../hub/types/json.js';
|
|
4
|
+
import { logHubStageTiming } from '../hub/pipeline/hub-stage-timing.js';
|
|
6
5
|
import { parseLenientJsonishWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
|
|
7
6
|
import { isObject, normalizeShellLikeToolInput, requireSystemText, requireTrimmedString, sanitizeToolUseId } from './anthropic-message-utils-core.js';
|
|
8
7
|
import { normalizeAnthropicToolChoice } from './anthropic-message-utils-openai-response.js';
|
|
@@ -22,30 +21,18 @@ const ANTHROPIC_TOP_LEVEL_FIELDS = new Set([
|
|
|
22
21
|
'tool_choice',
|
|
23
22
|
'thinking'
|
|
24
23
|
]);
|
|
25
|
-
export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
24
|
+
export function buildAnthropicRequestFromOpenAIChat(chatReq, options) {
|
|
26
25
|
const requestBody = isObject(chatReq) ? chatReq : {};
|
|
26
|
+
const requestId = typeof options?.requestId === 'string' && options.requestId.trim().length
|
|
27
|
+
? options.requestId.trim()
|
|
28
|
+
: 'unknown';
|
|
27
29
|
const model = String(requestBody?.model || 'unknown');
|
|
28
30
|
const messages = [];
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
messages: requestBody.messages,
|
|
35
|
-
rawRequest: requestBody
|
|
36
|
-
});
|
|
37
|
-
runBridgeActionPipeline({
|
|
38
|
-
stage: 'request_outbound',
|
|
39
|
-
actions,
|
|
40
|
-
protocol: bridgePolicy?.protocol ?? 'anthropic-messages',
|
|
41
|
-
moduleType: bridgePolicy?.moduleType ?? 'anthropic-messages',
|
|
42
|
-
state: actionState
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
// ignore policy errors
|
|
48
|
-
}
|
|
31
|
+
// IMPORTANT:
|
|
32
|
+
// The request_outbound bridge-policy pipeline was previously executed here, but
|
|
33
|
+
// its output state was never consumed by this builder. That made the whole pass
|
|
34
|
+
// pure overhead (large-message O(n) scans/clones) with zero semantic effect.
|
|
35
|
+
// To preserve payload semantics and stop latency bleed, we skip that no-op pass.
|
|
49
36
|
const collectText = (val) => {
|
|
50
37
|
if (!val)
|
|
51
38
|
return '';
|
|
@@ -65,6 +52,8 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
|
65
52
|
const mirrorShapes = extractMirrorShapesFromRequest(requestBody);
|
|
66
53
|
let mirrorIndex = 0;
|
|
67
54
|
const knownToolCallIds = new Set();
|
|
55
|
+
logHubStageTiming(requestId, 'req_outbound.anthropic.pre_scan_tool_calls', 'start');
|
|
56
|
+
const preScanStart = Date.now();
|
|
68
57
|
for (const m of msgs) {
|
|
69
58
|
if (!m || typeof m !== 'object')
|
|
70
59
|
continue;
|
|
@@ -81,6 +70,9 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
|
81
70
|
knownToolCallIds.add(id);
|
|
82
71
|
}
|
|
83
72
|
}
|
|
73
|
+
logHubStageTiming(requestId, 'req_outbound.anthropic.pre_scan_tool_calls', 'completed', {
|
|
74
|
+
elapsedMs: Date.now() - preScanStart
|
|
75
|
+
});
|
|
84
76
|
const systemBlocks = [];
|
|
85
77
|
const pushSystemBlock = (text) => {
|
|
86
78
|
const trimmed = text.trim();
|
|
@@ -117,6 +109,8 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
|
117
109
|
catch {
|
|
118
110
|
// ignore system pre-scan errors
|
|
119
111
|
}
|
|
112
|
+
logHubStageTiming(requestId, 'req_outbound.anthropic.map_messages', 'start');
|
|
113
|
+
const mapMessagesStart = Date.now();
|
|
120
114
|
for (const m of msgs) {
|
|
121
115
|
if (!m || typeof m !== 'object')
|
|
122
116
|
continue;
|
|
@@ -253,6 +247,9 @@ export function buildAnthropicRequestFromOpenAIChat(chatReq) {
|
|
|
253
247
|
messages.push({ role, content: contentNode });
|
|
254
248
|
}
|
|
255
249
|
}
|
|
250
|
+
logHubStageTiming(requestId, 'req_outbound.anthropic.map_messages', 'completed', {
|
|
251
|
+
elapsedMs: Date.now() - mapMessagesStart
|
|
252
|
+
});
|
|
256
253
|
const out = { model };
|
|
257
254
|
if (systemBlocks.length) {
|
|
258
255
|
out.system = systemBlocks;
|