@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
|
@@ -13,6 +13,11 @@ import { resolveRccPath } from '../../runtime/user-data-paths.js';
|
|
|
13
13
|
function isObject(v) { return !!v && typeof v === 'object' && !Array.isArray(v); }
|
|
14
14
|
// Note: tool schema strict augmentation removed per alignment
|
|
15
15
|
function enforceChatBudget(chat, _modelId) { return chat; }
|
|
16
|
+
function logToolGovernorNonBlocking(stage, error) {
|
|
17
|
+
const message = error instanceof Error ? error.message : String(error ?? 'unknown');
|
|
18
|
+
// eslint-disable-next-line no-console
|
|
19
|
+
console.warn(`[tool-governor][non-blocking] stage=${stage} error=${message}`);
|
|
20
|
+
}
|
|
16
21
|
function tryWriteSnapshot(options, stage, data) {
|
|
17
22
|
try {
|
|
18
23
|
// 仅在 verbose 级别保存快照(环境变量)
|
|
@@ -37,7 +42,9 @@ function tryWriteSnapshot(options, stage, data) {
|
|
|
37
42
|
const payload = JSON.stringify(data, null, 2);
|
|
38
43
|
fs.writeFileSync(file, payload, 'utf-8');
|
|
39
44
|
}
|
|
40
|
-
catch {
|
|
45
|
+
catch (error) {
|
|
46
|
+
logToolGovernorNonBlocking(`snapshot_write:${stage}`, error);
|
|
47
|
+
}
|
|
41
48
|
}
|
|
42
49
|
/**
|
|
43
50
|
* Process OpenAI Chat request (messages/tools) with unified 标准 governance.
|
|
@@ -74,7 +81,9 @@ export function processChatRequestTools(request, opts) {
|
|
|
74
81
|
out.tools = augmentOpenAITools(tools);
|
|
75
82
|
}
|
|
76
83
|
}
|
|
77
|
-
catch {
|
|
84
|
+
catch (error) {
|
|
85
|
+
logToolGovernorNonBlocking('request_minimal_tool_shape_repair', error);
|
|
86
|
+
}
|
|
78
87
|
// 1) 移除工具 schema 严格化(与 统一标准,不在此处约束 tools 结构)
|
|
79
88
|
// NOTE: system guidance injection removed by design (align with parameter-level strategy)
|
|
80
89
|
try {
|
|
@@ -94,13 +103,16 @@ export function processChatRequestTools(request, opts) {
|
|
|
94
103
|
}
|
|
95
104
|
}
|
|
96
105
|
}
|
|
97
|
-
catch {
|
|
106
|
+
catch (error) {
|
|
107
|
+
logToolGovernorNonBlocking('request_tool_choice_policy', error);
|
|
108
|
+
}
|
|
98
109
|
// 4) Enforce payload budget (context bytes) with minimal loss policy
|
|
99
110
|
const modelId = typeof canonical?.model === 'string' ? String(canonical.model) : 'unknown';
|
|
100
111
|
const budgeted = enforceChatBudget(canonical, modelId);
|
|
101
112
|
return normalizeSpecialToolCallsOnRequest(budgeted);
|
|
102
113
|
}
|
|
103
|
-
catch {
|
|
114
|
+
catch (error) {
|
|
115
|
+
logToolGovernorNonBlocking('process_chat_request_tools', error);
|
|
104
116
|
return out;
|
|
105
117
|
}
|
|
106
118
|
}
|
|
@@ -150,19 +162,20 @@ export function normalizeApplyPatchToolCallsOnResponse(chat) {
|
|
|
150
162
|
// eslint-disable-next-line no-console
|
|
151
163
|
console.error(`\x1b[31m[apply_patch][precheck][response] validation_failed reason=${reason}${snippet ? ` args=${snippet}` : ''}\x1b[0m`);
|
|
152
164
|
}
|
|
153
|
-
catch {
|
|
154
|
-
|
|
165
|
+
catch (error) {
|
|
166
|
+
logToolGovernorNonBlocking('response_apply_patch_regression_capture', error);
|
|
155
167
|
}
|
|
156
168
|
}
|
|
157
169
|
}
|
|
158
|
-
catch {
|
|
159
|
-
|
|
170
|
+
catch (error) {
|
|
171
|
+
logToolGovernorNonBlocking('response_tool_call_normalize_item', error);
|
|
160
172
|
}
|
|
161
173
|
}
|
|
162
174
|
}
|
|
163
175
|
return out;
|
|
164
176
|
}
|
|
165
|
-
catch {
|
|
177
|
+
catch (error) {
|
|
178
|
+
logToolGovernorNonBlocking('normalize_apply_patch_tool_calls_on_response', error);
|
|
166
179
|
return chat;
|
|
167
180
|
}
|
|
168
181
|
}
|
|
@@ -232,8 +245,8 @@ function normalizeSpecialToolCallsOnRequest(request) {
|
|
|
232
245
|
// eslint-disable-next-line no-console
|
|
233
246
|
console.error(`\x1b[31m[apply_patch][precheck][request] validation_failed reason=${reason}${snippet ? ` args=${snippet}` : ''}\x1b[0m`);
|
|
234
247
|
}
|
|
235
|
-
catch {
|
|
236
|
-
|
|
248
|
+
catch (error) {
|
|
249
|
+
logToolGovernorNonBlocking('request_apply_patch_regression_capture', error);
|
|
237
250
|
}
|
|
238
251
|
}
|
|
239
252
|
continue;
|
|
@@ -253,7 +266,8 @@ function normalizeSpecialToolCallsOnRequest(request) {
|
|
|
253
266
|
try {
|
|
254
267
|
parsed = JSON.parse(argsStr);
|
|
255
268
|
}
|
|
256
|
-
catch {
|
|
269
|
+
catch (error) {
|
|
270
|
+
logToolGovernorNonBlocking('request_exec_command_parse_json', error);
|
|
257
271
|
parsed = parseLenient(argsStr);
|
|
258
272
|
}
|
|
259
273
|
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
@@ -262,15 +276,16 @@ function normalizeSpecialToolCallsOnRequest(request) {
|
|
|
262
276
|
try {
|
|
263
277
|
fn.arguments = JSON.stringify(next ?? {});
|
|
264
278
|
}
|
|
265
|
-
catch {
|
|
279
|
+
catch (error) {
|
|
280
|
+
logToolGovernorNonBlocking('request_exec_command_json_stringify', error);
|
|
266
281
|
fn.arguments = '{}';
|
|
267
282
|
}
|
|
268
283
|
}
|
|
269
284
|
}
|
|
270
285
|
}
|
|
271
286
|
}
|
|
272
|
-
catch {
|
|
273
|
-
|
|
287
|
+
catch (error) {
|
|
288
|
+
logToolGovernorNonBlocking('request_tool_call_normalize_item', error);
|
|
274
289
|
}
|
|
275
290
|
}
|
|
276
291
|
}
|
|
@@ -279,7 +294,8 @@ function normalizeSpecialToolCallsOnRequest(request) {
|
|
|
279
294
|
}
|
|
280
295
|
return out;
|
|
281
296
|
}
|
|
282
|
-
catch {
|
|
297
|
+
catch (error) {
|
|
298
|
+
logToolGovernorNonBlocking('normalize_special_tool_calls_on_request', error);
|
|
283
299
|
return request;
|
|
284
300
|
}
|
|
285
301
|
}
|
|
@@ -319,7 +335,8 @@ function enhanceResponseToolArguments(chat) {
|
|
|
319
335
|
out = out.replace(/(?<!\\)\(/g, '\\(').replace(/(?<!\\)\)/g, '\\)');
|
|
320
336
|
return out;
|
|
321
337
|
}
|
|
322
|
-
catch {
|
|
338
|
+
catch (error) {
|
|
339
|
+
logToolGovernorNonBlocking('enhance_response_tool_arguments_repair_find_meta', error);
|
|
323
340
|
return s;
|
|
324
341
|
}
|
|
325
342
|
};
|
|
@@ -337,7 +354,8 @@ function enhanceResponseToolArguments(chat) {
|
|
|
337
354
|
try {
|
|
338
355
|
parsed = JSON.parse(repaired);
|
|
339
356
|
}
|
|
340
|
-
catch {
|
|
357
|
+
catch (error) {
|
|
358
|
+
logToolGovernorNonBlocking('enhance_response_tool_arguments_parse_json', error);
|
|
341
359
|
parsed = parseLenient(repaired);
|
|
342
360
|
}
|
|
343
361
|
if (parsed && typeof parsed === 'object') {
|
|
@@ -367,7 +385,8 @@ function enhanceResponseToolArguments(chat) {
|
|
|
367
385
|
try {
|
|
368
386
|
finalStr = JSON.stringify(parsed);
|
|
369
387
|
}
|
|
370
|
-
catch {
|
|
388
|
+
catch (error) {
|
|
389
|
+
logToolGovernorNonBlocking('enhance_response_tool_arguments_json_stringify', error);
|
|
371
390
|
finalStr = repaired;
|
|
372
391
|
}
|
|
373
392
|
}
|
|
@@ -384,23 +403,31 @@ function enhanceResponseToolArguments(chat) {
|
|
|
384
403
|
if (fn)
|
|
385
404
|
fn.arguments = finalStr;
|
|
386
405
|
}
|
|
387
|
-
catch {
|
|
406
|
+
catch (error) {
|
|
407
|
+
logToolGovernorNonBlocking('enhance_response_tool_arguments_item', error);
|
|
408
|
+
}
|
|
388
409
|
}
|
|
389
410
|
// Ensure finish_reason/tool_calls invariant if missing (idempotent with canonicalizer)
|
|
390
411
|
try {
|
|
391
412
|
if (!ch.finish_reason)
|
|
392
413
|
ch.finish_reason = 'tool_calls';
|
|
393
414
|
}
|
|
394
|
-
catch {
|
|
415
|
+
catch (error) {
|
|
416
|
+
logToolGovernorNonBlocking('enhance_response_tool_arguments_finish_reason', error);
|
|
417
|
+
}
|
|
395
418
|
try {
|
|
396
|
-
if (msg && typeof msg === 'object' && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0)
|
|
419
|
+
if (msg && typeof msg === 'object' && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0) {
|
|
397
420
|
msg.content = null;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
catch (error) {
|
|
424
|
+
logToolGovernorNonBlocking('enhance_response_tool_arguments_message_content', error);
|
|
398
425
|
}
|
|
399
|
-
catch { /* ignore */ }
|
|
400
426
|
}
|
|
401
427
|
return out;
|
|
402
428
|
}
|
|
403
|
-
catch {
|
|
429
|
+
catch (error) {
|
|
430
|
+
logToolGovernorNonBlocking('enhance_response_tool_arguments', error);
|
|
404
431
|
return chat;
|
|
405
432
|
}
|
|
406
433
|
}
|
|
@@ -412,7 +439,8 @@ export function processChatResponseTools(resp) {
|
|
|
412
439
|
const withPatch = normalizeApplyPatchToolCallsOnResponse(canon);
|
|
413
440
|
return enhanceResponseToolArguments(withPatch);
|
|
414
441
|
}
|
|
415
|
-
catch {
|
|
442
|
+
catch (error) {
|
|
443
|
+
logToolGovernorNonBlocking('process_chat_response_tools', error);
|
|
416
444
|
return resp;
|
|
417
445
|
}
|
|
418
446
|
}
|
|
@@ -432,21 +460,27 @@ export function governTools(payload, ctx) {
|
|
|
432
460
|
const opts = { snapshot: ctx?.snapshot || { enabled: true, endpoint: ep, requestId: ctx?.requestId } };
|
|
433
461
|
tryWriteSnapshot(opts, 'response_before_canonicalize', payload);
|
|
434
462
|
}
|
|
435
|
-
catch {
|
|
463
|
+
catch (error) {
|
|
464
|
+
logToolGovernorNonBlocking('govern_tools_snapshot_before_canonicalize', error);
|
|
465
|
+
}
|
|
436
466
|
let out = processChatResponseTools(payload);
|
|
437
467
|
// 变更后快照:响应侧 canonicalize 之后
|
|
438
468
|
try {
|
|
439
469
|
const opts = { snapshot: ctx?.snapshot || { enabled: true, endpoint: ep, requestId: ctx?.requestId } };
|
|
440
470
|
tryWriteSnapshot(opts, 'response_after_canonicalize', out);
|
|
441
471
|
}
|
|
442
|
-
catch {
|
|
472
|
+
catch (error) {
|
|
473
|
+
logToolGovernorNonBlocking('govern_tools_snapshot_after_canonicalize', error);
|
|
474
|
+
}
|
|
443
475
|
if (ep === 'responses' && ctx?.stream !== true && ctx?.produceRequiredAction !== false) {
|
|
444
476
|
// 变更前快照:构造 required_action 之前
|
|
445
477
|
try {
|
|
446
478
|
const opts = { snapshot: ctx?.snapshot || { enabled: true, endpoint: ep, requestId: ctx?.requestId } };
|
|
447
479
|
tryWriteSnapshot(opts, 'response_before_required_action', out);
|
|
448
480
|
}
|
|
449
|
-
catch {
|
|
481
|
+
catch (error) {
|
|
482
|
+
logToolGovernorNonBlocking('govern_tools_snapshot_before_required_action', error);
|
|
483
|
+
}
|
|
450
484
|
try {
|
|
451
485
|
const { buildResponsesPayloadFromChat } = require('../responses/responses-openai-bridge.js');
|
|
452
486
|
const res = buildResponsesPayloadFromChat(out, { requestId: ctx?.requestId });
|
|
@@ -454,10 +488,14 @@ export function governTools(payload, ctx) {
|
|
|
454
488
|
const opts = { snapshot: ctx?.snapshot || { enabled: true, endpoint: ep, requestId: ctx?.requestId } };
|
|
455
489
|
tryWriteSnapshot(opts, 'response_after_required_action', res);
|
|
456
490
|
}
|
|
457
|
-
catch {
|
|
491
|
+
catch (error) {
|
|
492
|
+
logToolGovernorNonBlocking('govern_tools_snapshot_after_required_action', error);
|
|
493
|
+
}
|
|
458
494
|
return res;
|
|
459
495
|
}
|
|
460
|
-
catch {
|
|
496
|
+
catch (error) {
|
|
497
|
+
logToolGovernorNonBlocking('govern_tools_required_action_bridge', error);
|
|
498
|
+
}
|
|
461
499
|
}
|
|
462
500
|
return out;
|
|
463
501
|
}
|
|
@@ -18,32 +18,216 @@ export async function recordSnapshot(options) {
|
|
|
18
18
|
if (!shouldRecordSnapshots())
|
|
19
19
|
return;
|
|
20
20
|
const endpoint = options.endpoint || '/v1/chat/completions';
|
|
21
|
+
const prepared = coerceSnapshotPayloadForWrite(options.stage, options.data);
|
|
21
22
|
void writeSnapshotViaHooks({
|
|
22
23
|
endpoint,
|
|
23
24
|
stage: options.stage,
|
|
24
25
|
requestId: options.requestId,
|
|
25
26
|
providerKey: options.providerKey,
|
|
26
27
|
groupRequestId: options.groupRequestId,
|
|
27
|
-
data:
|
|
28
|
+
data: prepared.data,
|
|
28
29
|
verbosity: 'verbose'
|
|
29
30
|
}).catch(() => {
|
|
30
31
|
// ignore hook errors
|
|
31
32
|
});
|
|
32
33
|
}
|
|
34
|
+
const DEFAULT_SNAPSHOT_QUEUE_MAX_ITEMS = 10;
|
|
35
|
+
const SNAPSHOT_QUEUE_BATCH_SIZE = 64;
|
|
36
|
+
const DEFAULT_SNAPSHOT_PAYLOAD_MAX_BYTES = 256 * 1024;
|
|
37
|
+
const DEFAULT_SNAPSHOT_QUEUE_MEMORY_BUDGET_BYTES = 8 * 1024 * 1024;
|
|
38
|
+
const SNAPSHOT_QUEUE = [];
|
|
39
|
+
let snapshotQueueBytes = 0;
|
|
40
|
+
let snapshotQueueDrainScheduled = false;
|
|
41
|
+
function resolvePositiveIntegerFromEnv(names, fallback) {
|
|
42
|
+
for (const name of names) {
|
|
43
|
+
const raw = process.env[name];
|
|
44
|
+
const parsed = Number.parseInt(String(raw ?? '').trim(), 10);
|
|
45
|
+
if (Number.isFinite(parsed) && parsed > 0) {
|
|
46
|
+
return parsed;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
function resolveSnapshotPayloadMaxBytes() {
|
|
52
|
+
return resolvePositiveIntegerFromEnv(['ROUTECODEX_SNAPSHOT_PAYLOAD_MAX_BYTES', 'RCC_SNAPSHOT_PAYLOAD_MAX_BYTES'], DEFAULT_SNAPSHOT_PAYLOAD_MAX_BYTES);
|
|
53
|
+
}
|
|
54
|
+
function resolveSnapshotQueueMemoryBudgetBytes() {
|
|
55
|
+
return resolvePositiveIntegerFromEnv(['ROUTECODEX_SNAPSHOT_QUEUE_MEMORY_BUDGET_BYTES', 'RCC_SNAPSHOT_QUEUE_MEMORY_BUDGET_BYTES'], DEFAULT_SNAPSHOT_QUEUE_MEMORY_BUDGET_BYTES);
|
|
56
|
+
}
|
|
57
|
+
function resolveSnapshotQueueMaxItems() {
|
|
58
|
+
return resolvePositiveIntegerFromEnv(['ROUTECODEX_SNAPSHOT_QUEUE_MAX_ITEMS', 'RCC_SNAPSHOT_QUEUE_MAX_ITEMS'], DEFAULT_SNAPSHOT_QUEUE_MAX_ITEMS);
|
|
59
|
+
}
|
|
60
|
+
function estimateSnapshotPayloadBytes(value, options) {
|
|
61
|
+
const maxBytes = options?.maxBytes ?? Number.POSITIVE_INFINITY;
|
|
62
|
+
const depth = options?.depth ?? 0;
|
|
63
|
+
const seen = options?.seen ?? new Set();
|
|
64
|
+
if (value === null || value === undefined) {
|
|
65
|
+
return 4;
|
|
66
|
+
}
|
|
67
|
+
const valueType = typeof value;
|
|
68
|
+
if (valueType === 'string') {
|
|
69
|
+
return Math.min(maxBytes + 1, value.length * 2 + 2);
|
|
70
|
+
}
|
|
71
|
+
if (valueType === 'number') {
|
|
72
|
+
return 8;
|
|
73
|
+
}
|
|
74
|
+
if (valueType === 'boolean') {
|
|
75
|
+
return 4;
|
|
76
|
+
}
|
|
77
|
+
if (valueType === 'bigint') {
|
|
78
|
+
return String(value).length + 8;
|
|
79
|
+
}
|
|
80
|
+
if (valueType === 'symbol' || valueType === 'function') {
|
|
81
|
+
return 16;
|
|
82
|
+
}
|
|
83
|
+
if (seen.has(value)) {
|
|
84
|
+
return 8;
|
|
85
|
+
}
|
|
86
|
+
seen.add(value);
|
|
87
|
+
if (depth >= 8) {
|
|
88
|
+
return 64;
|
|
89
|
+
}
|
|
90
|
+
let bytes = 0;
|
|
91
|
+
if (Array.isArray(value)) {
|
|
92
|
+
bytes += 2;
|
|
93
|
+
for (const item of value) {
|
|
94
|
+
bytes += estimateSnapshotPayloadBytes(item, {
|
|
95
|
+
maxBytes: Math.max(0, maxBytes - bytes),
|
|
96
|
+
depth: depth + 1,
|
|
97
|
+
seen
|
|
98
|
+
});
|
|
99
|
+
if (bytes > maxBytes) {
|
|
100
|
+
return maxBytes + 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return bytes;
|
|
104
|
+
}
|
|
105
|
+
if (value && typeof value === 'object') {
|
|
106
|
+
bytes += 2;
|
|
107
|
+
for (const [key, child] of Object.entries(value)) {
|
|
108
|
+
bytes += key.length * 2 + 4;
|
|
109
|
+
bytes += estimateSnapshotPayloadBytes(child, {
|
|
110
|
+
maxBytes: Math.max(0, maxBytes - bytes),
|
|
111
|
+
depth: depth + 1,
|
|
112
|
+
seen
|
|
113
|
+
});
|
|
114
|
+
if (bytes > maxBytes) {
|
|
115
|
+
return maxBytes + 1;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return bytes;
|
|
119
|
+
}
|
|
120
|
+
return 16;
|
|
121
|
+
}
|
|
122
|
+
function summarizeSnapshotPayload(value) {
|
|
123
|
+
if (Array.isArray(value)) {
|
|
124
|
+
return {
|
|
125
|
+
type: 'array',
|
|
126
|
+
length: value.length,
|
|
127
|
+
sampleTypes: value.slice(0, 8).map((item) => typeof item)
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (value && typeof value === 'object') {
|
|
131
|
+
const record = value;
|
|
132
|
+
const keys = Object.keys(record);
|
|
133
|
+
return {
|
|
134
|
+
type: 'object',
|
|
135
|
+
keyCount: keys.length,
|
|
136
|
+
keys: keys.slice(0, 24)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (typeof value === 'string') {
|
|
140
|
+
return {
|
|
141
|
+
type: 'string',
|
|
142
|
+
length: value.length,
|
|
143
|
+
preview: value.length > 160 ? `${value.slice(0, 160)}…` : value
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
type: typeof value,
|
|
148
|
+
value: value ?? null
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function coerceSnapshotPayloadForWrite(stage, payload) {
|
|
152
|
+
const maxBytes = resolveSnapshotPayloadMaxBytes();
|
|
153
|
+
const estimatedBytes = estimateSnapshotPayloadBytes(payload, { maxBytes: maxBytes + 1 });
|
|
154
|
+
if (estimatedBytes <= maxBytes) {
|
|
155
|
+
return {
|
|
156
|
+
data: payload,
|
|
157
|
+
sizeBytes: Math.max(1, estimatedBytes)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
data: {
|
|
162
|
+
__snapshot_truncated: true,
|
|
163
|
+
stage,
|
|
164
|
+
maxBytes,
|
|
165
|
+
estimatedBytes,
|
|
166
|
+
summary: summarizeSnapshotPayload(payload)
|
|
167
|
+
},
|
|
168
|
+
sizeBytes: 512
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
function scheduleSnapshotQueueDrain() {
|
|
172
|
+
if (snapshotQueueDrainScheduled) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
snapshotQueueDrainScheduled = true;
|
|
176
|
+
setImmediate(() => {
|
|
177
|
+
snapshotQueueDrainScheduled = false;
|
|
178
|
+
let processed = 0;
|
|
179
|
+
while (SNAPSHOT_QUEUE.length > 0 && processed < SNAPSHOT_QUEUE_BATCH_SIZE) {
|
|
180
|
+
const item = SNAPSHOT_QUEUE.shift();
|
|
181
|
+
if (!item) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
snapshotQueueBytes = Math.max(0, snapshotQueueBytes - Math.max(1, item.sizeBytes));
|
|
185
|
+
try {
|
|
186
|
+
item.task();
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// snapshot write failures are non-blocking by design
|
|
190
|
+
}
|
|
191
|
+
processed += 1;
|
|
192
|
+
}
|
|
193
|
+
if (SNAPSHOT_QUEUE.length > 0) {
|
|
194
|
+
scheduleSnapshotQueueDrain();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
function enqueueSnapshotTask(task, sizeBytes) {
|
|
199
|
+
const normalizedSize = Math.max(1, Math.floor(sizeBytes));
|
|
200
|
+
const queueBudgetBytes = resolveSnapshotQueueMemoryBudgetBytes();
|
|
201
|
+
const queueMaxItems = resolveSnapshotQueueMaxItems();
|
|
202
|
+
while (SNAPSHOT_QUEUE.length > 0
|
|
203
|
+
&& (SNAPSHOT_QUEUE.length >= queueMaxItems || snapshotQueueBytes + normalizedSize > queueBudgetBytes)) {
|
|
204
|
+
const dropped = SNAPSHOT_QUEUE.shift();
|
|
205
|
+
if (!dropped) {
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
snapshotQueueBytes = Math.max(0, snapshotQueueBytes - Math.max(1, dropped.sizeBytes));
|
|
209
|
+
}
|
|
210
|
+
SNAPSHOT_QUEUE.push({ task, sizeBytes: normalizedSize });
|
|
211
|
+
snapshotQueueBytes += normalizedSize;
|
|
212
|
+
scheduleSnapshotQueueDrain();
|
|
213
|
+
}
|
|
33
214
|
export function createSnapshotWriter(opts) {
|
|
34
215
|
if (!shouldRecordSnapshots()) {
|
|
35
216
|
return undefined;
|
|
36
217
|
}
|
|
37
218
|
const endpoint = opts.endpoint || '/v1/chat/completions';
|
|
38
219
|
return (stage, payload) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
220
|
+
const prepared = coerceSnapshotPayloadForWrite(stage, payload);
|
|
221
|
+
enqueueSnapshotTask(() => {
|
|
222
|
+
void recordSnapshot({
|
|
223
|
+
stage,
|
|
224
|
+
requestId: opts.requestId,
|
|
225
|
+
endpoint,
|
|
226
|
+
folderHint: opts.folderHint,
|
|
227
|
+
providerKey: opts.providerKey,
|
|
228
|
+
groupRequestId: opts.groupRequestId,
|
|
229
|
+
data: prepared.data
|
|
230
|
+
});
|
|
231
|
+
}, prepared.sizeBytes);
|
|
48
232
|
};
|
|
49
233
|
}
|
|
Binary file
|
|
@@ -153,10 +153,10 @@ export function applyErrorEvent(state, event, nowMs = event.timestampMs ?? Date.
|
|
|
153
153
|
? COOLDOWN_SCHEDULE_FATAL_MS
|
|
154
154
|
: COOLDOWN_SCHEDULE_DEFAULT_MS;
|
|
155
155
|
const rawNextCount = sameErrorKey ? state.consecutiveErrorCount + 1 : 1;
|
|
156
|
-
const nextCount = rawNextCount
|
|
156
|
+
const nextCount = Math.min(rawNextCount, Math.max(1, schedule.length));
|
|
157
157
|
const cooldownMs = computeTransientKeepPoolCooldownMs(series, nextCount) ?? computeCooldownMsBySeries(series, nextCount);
|
|
158
158
|
const nextUntil = cooldownMs ? nowMs + cooldownMs : null;
|
|
159
|
-
const existingUntil = typeof state.cooldownUntil === 'number' ? state.cooldownUntil : null;
|
|
159
|
+
const existingUntil = sameErrorKey && typeof state.cooldownUntil === 'number' ? state.cooldownUntil : null;
|
|
160
160
|
const cooldownUntil = typeof nextUntil === 'number' && Number.isFinite(nextUntil)
|
|
161
161
|
? typeof existingUntil === 'number' && existingUntil > nextUntil
|
|
162
162
|
? existingUntil
|
package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine/routing-state/store.js
CHANGED
|
@@ -1,4 +1,36 @@
|
|
|
1
1
|
import { mergeStopMessageFromPersisted } from '../../stop-message-state-sync.js';
|
|
2
|
+
import { providerErrorCenter } from '../../error-center.js';
|
|
3
|
+
function formatError(error) {
|
|
4
|
+
if (error instanceof Error) {
|
|
5
|
+
return error.message;
|
|
6
|
+
}
|
|
7
|
+
return String(error);
|
|
8
|
+
}
|
|
9
|
+
function emitRoutingStateRefreshError(key, error) {
|
|
10
|
+
const errorMessage = formatError(error);
|
|
11
|
+
providerErrorCenter.emit({
|
|
12
|
+
code: 'STICKY_STATE_REFRESH_FAILED',
|
|
13
|
+
message: 'failed to refresh in-memory routing state from persisted sticky store',
|
|
14
|
+
stage: 'sticky_session.refresh',
|
|
15
|
+
timestamp: Date.now(),
|
|
16
|
+
runtime: {
|
|
17
|
+
requestId: 'routing-state-store',
|
|
18
|
+
providerProtocol: 'sticky-session-store',
|
|
19
|
+
providerType: 'internal'
|
|
20
|
+
},
|
|
21
|
+
details: {
|
|
22
|
+
operation: 'refresh_existing_state',
|
|
23
|
+
key,
|
|
24
|
+
error: errorMessage
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
try {
|
|
28
|
+
console.warn(`[routing-state-store] STICKY_STATE_REFRESH_FAILED key=${key} error=${errorMessage}`);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// no-op
|
|
32
|
+
}
|
|
33
|
+
}
|
|
2
34
|
function readToken(value) {
|
|
3
35
|
if (typeof value !== 'string') {
|
|
4
36
|
return '';
|
|
@@ -66,8 +98,9 @@ export function getRoutingInstructionState(stickyKey, routingInstructionState, r
|
|
|
66
98
|
existing.preCommandUpdatedAt = persisted.preCommandUpdatedAt;
|
|
67
99
|
}
|
|
68
100
|
}
|
|
69
|
-
catch {
|
|
70
|
-
//
|
|
101
|
+
catch (error) {
|
|
102
|
+
// 刷新失败不影响原有内存状态,但必须显式上报,禁止静默吞错
|
|
103
|
+
emitRoutingStateRefreshError(key, error);
|
|
71
104
|
}
|
|
72
105
|
return existing;
|
|
73
106
|
}
|
|
@@ -64,20 +64,20 @@ export class VirtualRouterEngine {
|
|
|
64
64
|
}
|
|
65
65
|
const parsed = JSON.parse(raw);
|
|
66
66
|
emitStopMessageMarkerParseLog(parseLog);
|
|
67
|
-
// Keep legacy observable behavior for callers/tests that inspect the request object
|
|
68
|
-
// after route(): instruction markers are stripped from forwarded payload structures.
|
|
69
67
|
cleanStopMessageMarkersInPlace(request);
|
|
70
68
|
const stopScope = parseLog?.stopScope || resolveStopMessageScope(metadata);
|
|
71
69
|
const stopState = stopScope ? this.getStopMessageState(metadata) : null;
|
|
72
70
|
const forceStopStatusLabel = Boolean(parseLog?.stopMessageTypes.length ||
|
|
73
71
|
parseLog?.scopedTypes.some((type) => type === 'stopMessageSet' || type === 'stopMessageMode' || type === 'stopMessageClear'));
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
if (metadata.__rt?.disableVirtualRouterHitLog !== true) {
|
|
73
|
+
emitVirtualRouterHitLog(parsed, {
|
|
74
|
+
requestId: metadata.requestId,
|
|
75
|
+
sessionId: resolveVirtualRouterLogSessionId(metadata),
|
|
76
|
+
stopScope,
|
|
77
|
+
stopState,
|
|
78
|
+
forceStopStatusLabel
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
81
|
return parsed;
|
|
82
82
|
}
|
|
83
83
|
getStopMessageState(metadata) {
|