@jsonstudio/rcc 0.90.814 → 0.90.872
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 +16 -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 +121 -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/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/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 +48 -8
- 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/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
|
@@ -9,8 +9,60 @@ function asRecord(value) {
|
|
|
9
9
|
? value
|
|
10
10
|
: undefined;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
const
|
|
12
|
+
function stripFunctionNamespace(raw) {
|
|
13
|
+
const trimmed = raw.trim();
|
|
14
|
+
if (!trimmed) {
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
const lowered = trimmed.toLowerCase();
|
|
18
|
+
if (lowered.startsWith('functions.')) {
|
|
19
|
+
return trimmed.slice('functions.'.length).trim();
|
|
20
|
+
}
|
|
21
|
+
if (lowered.startsWith('function.')) {
|
|
22
|
+
return trimmed.slice('function.'.length).trim();
|
|
23
|
+
}
|
|
24
|
+
return trimmed;
|
|
25
|
+
}
|
|
26
|
+
function toCanonicalToolName(raw) {
|
|
27
|
+
const stripped = stripFunctionNamespace(raw).toLowerCase().trim();
|
|
28
|
+
if (!stripped) {
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
return stripped
|
|
32
|
+
.replace(/[\s_-]+/g, '.')
|
|
33
|
+
.replace(/\.{2,}/g, '.')
|
|
34
|
+
.replace(/^\.+|\.+$/g, '');
|
|
35
|
+
}
|
|
36
|
+
function toCompactToolName(raw) {
|
|
37
|
+
const canonical = toCanonicalToolName(raw);
|
|
38
|
+
if (!canonical) {
|
|
39
|
+
return '';
|
|
40
|
+
}
|
|
41
|
+
return canonical.replace(/[._-]/g, '');
|
|
42
|
+
}
|
|
43
|
+
function resolveToolFamily(raw) {
|
|
44
|
+
const canonicalLower = toCanonicalToolName(raw);
|
|
45
|
+
if (!canonicalLower) {
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
const shellCandidate = canonicalLower.replace(/\./g, '_');
|
|
49
|
+
if (isShellToolName(canonicalLower) || isShellToolName(shellCandidate) || canonicalLower === 'terminal') {
|
|
50
|
+
return 'shell_like';
|
|
51
|
+
}
|
|
52
|
+
if (canonicalLower === 'apply.patch' || canonicalLower === 'apply_patch') {
|
|
53
|
+
return 'apply_patch';
|
|
54
|
+
}
|
|
55
|
+
if (canonicalLower === 'write.stdin' || canonicalLower === 'write_stdin') {
|
|
56
|
+
return 'write_stdin';
|
|
57
|
+
}
|
|
58
|
+
return canonicalLower;
|
|
59
|
+
}
|
|
60
|
+
function extractClientToolIndex(clientToolsRaw) {
|
|
61
|
+
const byExactLower = new Map();
|
|
62
|
+
const byStrippedLower = new Map();
|
|
63
|
+
const byCanonicalLower = new Map();
|
|
64
|
+
const byCompactLower = new Map();
|
|
65
|
+
const byFamily = new Map();
|
|
14
66
|
for (const tool of clientToolsRaw ?? []) {
|
|
15
67
|
const functionBag = asRecord(tool.function);
|
|
16
68
|
const rawName = (typeof functionBag?.name === 'string' ? functionBag.name : undefined)
|
|
@@ -19,15 +71,70 @@ function extractClientToolNameMap(clientToolsRaw) {
|
|
|
19
71
|
if (!normalizedName) {
|
|
20
72
|
continue;
|
|
21
73
|
}
|
|
22
|
-
|
|
74
|
+
const entry = {
|
|
75
|
+
declaredName: normalizedName,
|
|
76
|
+
tool
|
|
77
|
+
};
|
|
78
|
+
const exactLower = normalizedName.toLowerCase();
|
|
79
|
+
const strippedLower = stripFunctionNamespace(normalizedName).toLowerCase();
|
|
80
|
+
const canonicalLower = toCanonicalToolName(normalizedName);
|
|
81
|
+
const compactLower = toCompactToolName(normalizedName);
|
|
82
|
+
const family = resolveToolFamily(normalizedName);
|
|
83
|
+
if (!byExactLower.has(exactLower)) {
|
|
84
|
+
byExactLower.set(exactLower, entry);
|
|
85
|
+
}
|
|
86
|
+
if (strippedLower && !byStrippedLower.has(strippedLower)) {
|
|
87
|
+
byStrippedLower.set(strippedLower, entry);
|
|
88
|
+
}
|
|
89
|
+
if (canonicalLower && !byCanonicalLower.has(canonicalLower)) {
|
|
90
|
+
byCanonicalLower.set(canonicalLower, entry);
|
|
91
|
+
}
|
|
92
|
+
if (compactLower && !byCompactLower.has(compactLower)) {
|
|
93
|
+
byCompactLower.set(compactLower, entry);
|
|
94
|
+
}
|
|
95
|
+
if (family && !byFamily.has(family)) {
|
|
96
|
+
byFamily.set(family, entry);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { byExactLower, byStrippedLower, byCanonicalLower, byCompactLower, byFamily };
|
|
100
|
+
}
|
|
101
|
+
function resolveClientToolFromIndex(index, rawName) {
|
|
102
|
+
const trimmed = rawName.trim();
|
|
103
|
+
if (!trimmed) {
|
|
104
|
+
return undefined;
|
|
23
105
|
}
|
|
24
|
-
|
|
106
|
+
const exactLower = trimmed.toLowerCase();
|
|
107
|
+
const strippedLower = stripFunctionNamespace(trimmed).toLowerCase();
|
|
108
|
+
const canonicalLower = toCanonicalToolName(trimmed);
|
|
109
|
+
const compactLower = toCompactToolName(trimmed);
|
|
110
|
+
const family = resolveToolFamily(trimmed);
|
|
111
|
+
return (index.byExactLower.get(exactLower)
|
|
112
|
+
?? index.byExactLower.get(strippedLower)
|
|
113
|
+
?? index.byStrippedLower.get(strippedLower)
|
|
114
|
+
?? (canonicalLower ? index.byCanonicalLower.get(canonicalLower) : undefined)
|
|
115
|
+
?? (canonicalLower ? index.byStrippedLower.get(canonicalLower) : undefined)
|
|
116
|
+
?? (compactLower ? index.byCompactLower.get(compactLower) : undefined)
|
|
117
|
+
?? (family ? index.byFamily.get(family) : undefined));
|
|
25
118
|
}
|
|
26
119
|
function remapChatToolCallsToClientNames(payload, clientToolsRaw) {
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
29
|
-
return;
|
|
120
|
+
const toolIndex = extractClientToolIndex(clientToolsRaw);
|
|
121
|
+
if (!toolIndex.byExactLower.size) {
|
|
122
|
+
return [];
|
|
30
123
|
}
|
|
124
|
+
const unknownNames = [];
|
|
125
|
+
const seenUnknown = new Set();
|
|
126
|
+
const pushUnknown = (name) => {
|
|
127
|
+
const key = name.trim();
|
|
128
|
+
if (!key || seenUnknown.has(key)) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
seenUnknown.add(key);
|
|
132
|
+
unknownNames.push(key);
|
|
133
|
+
};
|
|
134
|
+
const readSchema = (entry) => {
|
|
135
|
+
const functionBag = asRecord(entry?.tool.function);
|
|
136
|
+
return functionBag?.parameters;
|
|
137
|
+
};
|
|
31
138
|
const choices = Array.isArray(payload.choices)
|
|
32
139
|
? payload.choices
|
|
33
140
|
: [];
|
|
@@ -40,20 +147,13 @@ function remapChatToolCallsToClientNames(payload, clientToolsRaw) {
|
|
|
40
147
|
if (!currentName) {
|
|
41
148
|
continue;
|
|
42
149
|
}
|
|
43
|
-
const
|
|
44
|
-
const matchedTool = toolMap.get(normalizedCurrentName)
|
|
45
|
-
?? (isShellToolName(normalizedCurrentName)
|
|
46
|
-
? Array.from(toolMap.entries()).find(([toolName]) => isShellToolName(toolName))?.[1]
|
|
47
|
-
: undefined);
|
|
150
|
+
const matchedTool = resolveClientToolFromIndex(toolIndex, currentName);
|
|
48
151
|
if (!matchedTool) {
|
|
152
|
+
pushUnknown(currentName);
|
|
49
153
|
continue;
|
|
50
154
|
}
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
?? (typeof matchedTool.name === 'string' ? matchedTool.name : undefined)
|
|
54
|
-
?? currentName;
|
|
55
|
-
functionBag.name = clientName;
|
|
56
|
-
const schema = matchedFunction?.parameters;
|
|
155
|
+
functionBag.name = matchedTool.declaredName;
|
|
156
|
+
const schema = readSchema(matchedTool);
|
|
57
157
|
const rawArgs = functionBag?.arguments;
|
|
58
158
|
let parsedArgs = rawArgs;
|
|
59
159
|
if (typeof rawArgs === 'string') {
|
|
@@ -75,13 +175,115 @@ function remapChatToolCallsToClientNames(payload, clientToolsRaw) {
|
|
|
75
175
|
}
|
|
76
176
|
}
|
|
77
177
|
}
|
|
178
|
+
return unknownNames;
|
|
179
|
+
}
|
|
180
|
+
function remapResponsesToolCallsToClientNames(payload, clientToolsRaw) {
|
|
181
|
+
const toolIndex = extractClientToolIndex(clientToolsRaw);
|
|
182
|
+
if (!toolIndex.byExactLower.size) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
const unknownNames = [];
|
|
186
|
+
const seenUnknown = new Set();
|
|
187
|
+
const pushUnknown = (name) => {
|
|
188
|
+
const key = name.trim();
|
|
189
|
+
if (!key || seenUnknown.has(key)) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
seenUnknown.add(key);
|
|
193
|
+
unknownNames.push(key);
|
|
194
|
+
};
|
|
195
|
+
const requiredActionCalls = Array.isArray(payload?.required_action?.submit_tool_outputs?.tool_calls)
|
|
196
|
+
? payload.required_action.submit_tool_outputs.tool_calls
|
|
197
|
+
: [];
|
|
198
|
+
for (const call of requiredActionCalls) {
|
|
199
|
+
const callBag = asRecord(call);
|
|
200
|
+
if (!callBag) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
const rawName = typeof callBag.name === 'string' ? callBag.name.trim() : '';
|
|
204
|
+
if (!rawName) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const matched = resolveClientToolFromIndex(toolIndex, rawName);
|
|
208
|
+
if (!matched) {
|
|
209
|
+
pushUnknown(rawName);
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
callBag.name = matched.declaredName;
|
|
213
|
+
}
|
|
214
|
+
const outputItems = Array.isArray(payload?.output) ? payload.output : [];
|
|
215
|
+
for (const item of outputItems) {
|
|
216
|
+
const itemBag = asRecord(item);
|
|
217
|
+
if (!itemBag) {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
const type = typeof itemBag.type === 'string' ? itemBag.type.trim().toLowerCase() : '';
|
|
221
|
+
if (type !== 'function_call') {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const rawName = typeof itemBag.name === 'string' ? itemBag.name.trim() : '';
|
|
225
|
+
if (!rawName) {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const matched = resolveClientToolFromIndex(toolIndex, rawName);
|
|
229
|
+
if (!matched) {
|
|
230
|
+
pushUnknown(rawName);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
itemBag.name = matched.declaredName;
|
|
234
|
+
}
|
|
235
|
+
return unknownNames;
|
|
236
|
+
}
|
|
237
|
+
function assertNoUnknownToolNames(args) {
|
|
238
|
+
const uniqueUnknown = Array.from(new Set(args.unknownNames.map((name) => name.trim()).filter(Boolean)));
|
|
239
|
+
if (!uniqueUnknown.length) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
const declaredNames = (args.clientToolsRaw ?? [])
|
|
243
|
+
.map((tool) => {
|
|
244
|
+
const fn = asRecord(tool.function);
|
|
245
|
+
const fnName = typeof fn?.name === 'string' ? fn.name.trim() : '';
|
|
246
|
+
if (fnName) {
|
|
247
|
+
return fnName;
|
|
248
|
+
}
|
|
249
|
+
const topName = typeof tool.name === 'string' ? tool.name.trim() : '';
|
|
250
|
+
return topName || '';
|
|
251
|
+
})
|
|
252
|
+
.filter(Boolean);
|
|
253
|
+
const declaredPreview = declaredNames.slice(0, 20).join(', ');
|
|
254
|
+
const error = new Error(`[client-remap] tool name mismatch after remap: unknown=[${uniqueUnknown.join(', ')}]` +
|
|
255
|
+
` protocol=${args.clientProtocol} requestId=${args.requestId}` +
|
|
256
|
+
(declaredPreview ? ` declared=[${declaredPreview}]` : ' declared=[none]'));
|
|
257
|
+
error.code = 'CLIENT_TOOL_NAME_MISMATCH';
|
|
258
|
+
error.statusCode = 502;
|
|
259
|
+
error.retryable = true;
|
|
260
|
+
error.details = {
|
|
261
|
+
unknownToolNames: uniqueUnknown,
|
|
262
|
+
declaredToolNames: declaredNames,
|
|
263
|
+
protocol: args.clientProtocol,
|
|
264
|
+
requestId: args.requestId
|
|
265
|
+
};
|
|
266
|
+
throw error;
|
|
267
|
+
}
|
|
268
|
+
function enforceClientToolNameContract(options, payload, toolsRaw) {
|
|
269
|
+
const hasClientTools = Array.isArray(toolsRaw) && toolsRaw.length > 0;
|
|
270
|
+
if (!hasClientTools) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
const unknownFromChat = remapChatToolCallsToClientNames(payload, toolsRaw);
|
|
274
|
+
const unknownFromResponses = remapResponsesToolCallsToClientNames(payload, toolsRaw);
|
|
275
|
+
assertNoUnknownToolNames({
|
|
276
|
+
requestId: options.requestId,
|
|
277
|
+
clientProtocol: options.clientProtocol,
|
|
278
|
+
unknownNames: [...unknownFromChat, ...unknownFromResponses],
|
|
279
|
+
clientToolsRaw: toolsRaw
|
|
280
|
+
});
|
|
78
281
|
}
|
|
79
282
|
export function buildClientPayloadForProtocol(options) {
|
|
80
283
|
let clientPayload;
|
|
81
284
|
const toolsRaw = resolveClientToolsRawFromSemantics(options.requestSemantics);
|
|
82
285
|
if (options.clientProtocol === 'openai-chat') {
|
|
83
286
|
clientPayload = options.payload;
|
|
84
|
-
remapChatToolCallsToClientNames(clientPayload, toolsRaw);
|
|
85
287
|
}
|
|
86
288
|
else if (options.clientProtocol === 'anthropic-messages') {
|
|
87
289
|
clientPayload = buildAnthropicResponseFromChat(options.payload, {
|
|
@@ -99,5 +301,6 @@ export function buildClientPayloadForProtocol(options) {
|
|
|
99
301
|
if (options.clientProtocol === 'openai-responses') {
|
|
100
302
|
normalizeResponsesToolCallIds(clientPayload);
|
|
101
303
|
}
|
|
304
|
+
enforceClientToolNameContract(options, clientPayload, toolsRaw);
|
|
102
305
|
return clientPayload;
|
|
103
306
|
}
|
|
@@ -212,7 +212,7 @@ export function recordHubPolicyObservation(options) {
|
|
|
212
212
|
return;
|
|
213
213
|
}
|
|
214
214
|
const compatibilityProfile = typeof options.compatibilityProfile === 'string' ? options.compatibilityProfile.trim().toLowerCase() : '';
|
|
215
|
-
if (compatibilityProfile === 'chat:deepseek-web') {
|
|
215
|
+
if (compatibilityProfile === 'chat:deepseek-web' || compatibilityProfile === 'chat:qwenchat-web') {
|
|
216
216
|
return;
|
|
217
217
|
}
|
|
218
218
|
if (!shouldSample(effectivePolicy?.sampleRate)) {
|
|
@@ -247,7 +247,7 @@ export function applyHubProviderOutboundPolicy(options) {
|
|
|
247
247
|
}
|
|
248
248
|
const normalizedProviderProtocol = normalizeHubProviderProtocol(options.providerProtocol);
|
|
249
249
|
const compatibilityProfile = typeof options.compatibilityProfile === 'string' ? options.compatibilityProfile.trim().toLowerCase() : '';
|
|
250
|
-
if (compatibilityProfile === 'chat:deepseek-web') {
|
|
250
|
+
if (compatibilityProfile === 'chat:deepseek-web' || compatibilityProfile === 'chat:qwenchat-web') {
|
|
251
251
|
return options.payload;
|
|
252
252
|
}
|
|
253
253
|
const result = applyProviderOutboundPolicy(normalizedProviderProtocol, options.payload);
|
package/node_modules/@jsonstudio/llms/dist/conversion/hub/process/chat-process-pending-tool-sync.js
CHANGED
|
@@ -3,19 +3,34 @@ import { analyzePendingToolSync } from '../../../router/virtual-router/engine-se
|
|
|
3
3
|
function readString(value) {
|
|
4
4
|
return typeof value === 'string' ? value : undefined;
|
|
5
5
|
}
|
|
6
|
-
function
|
|
7
|
-
const
|
|
8
|
-
|
|
6
|
+
function resolvePendingSessionCandidates(metadata, request) {
|
|
7
|
+
const candidates = [
|
|
8
|
+
readString(metadata.sessionId),
|
|
9
|
+
readString(request.metadata?.sessionId),
|
|
10
|
+
readString(metadata.conversationId),
|
|
11
|
+
readString(request.metadata?.conversationId)
|
|
12
|
+
]
|
|
13
|
+
.filter((value) => typeof value === 'string' && value.trim().length > 0)
|
|
14
|
+
.map((value) => value.trim());
|
|
15
|
+
return Array.from(new Set(candidates));
|
|
9
16
|
}
|
|
10
17
|
export async function maybeInjectPendingServerToolResultsAfterClientTools(request, metadata, deps = {}) {
|
|
11
18
|
const loadFn = deps.loadPendingServerToolInjectionFn ?? loadPendingServerToolInjection;
|
|
12
19
|
const clearFn = deps.clearPendingServerToolInjectionFn ?? clearPendingServerToolInjection;
|
|
13
20
|
const analyzeFn = deps.analyzePendingToolSyncFn ?? analyzePendingToolSync;
|
|
14
|
-
const
|
|
15
|
-
if (!
|
|
21
|
+
const sessionCandidates = resolvePendingSessionCandidates(metadata, request);
|
|
22
|
+
if (!sessionCandidates.length) {
|
|
16
23
|
return request;
|
|
17
24
|
}
|
|
18
|
-
|
|
25
|
+
let loadedSessionId = null;
|
|
26
|
+
let pending = null;
|
|
27
|
+
for (const sessionId of sessionCandidates) {
|
|
28
|
+
pending = await loadFn(sessionId);
|
|
29
|
+
if (pending) {
|
|
30
|
+
loadedSessionId = sessionId;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
19
34
|
if (!pending) {
|
|
20
35
|
return request;
|
|
21
36
|
}
|
|
@@ -43,7 +58,9 @@ export async function maybeInjectPendingServerToolResultsAfterClientTools(reques
|
|
|
43
58
|
const nextMessages = messages.slice();
|
|
44
59
|
nextMessages.splice(analysis.insertAt + 1, 0, ...inject);
|
|
45
60
|
try {
|
|
46
|
-
|
|
61
|
+
if (loadedSessionId) {
|
|
62
|
+
await clearFn(loadedSessionId);
|
|
63
|
+
}
|
|
47
64
|
}
|
|
48
65
|
catch {
|
|
49
66
|
// best-effort
|
|
@@ -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?;
|