@jsonstudio/rcc 0.89.3 → 0.89.164
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 +240 -179
- package/config/modules.json +1 -11
- package/dist/build-info.js +2 -2
- package/dist/build-info.js.map +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.d.ts +16 -0
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +56 -0
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -0
- package/dist/client/openai/chat-protocol-client.js.map +1 -1
- package/dist/config/modules.json +1 -11
- package/dist/core/provider-health-manager.d.ts +17 -0
- package/dist/core/provider-health-manager.js +66 -0
- package/dist/core/provider-health-manager.js.map +1 -0
- package/dist/error-handling/route-error-hub.d.ts +48 -0
- package/dist/error-handling/route-error-hub.js +131 -0
- package/dist/error-handling/route-error-hub.js.map +1 -0
- package/dist/index.js +26 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/llmswitch/bridge.d.ts +2 -0
- package/dist/modules/llmswitch/bridge.js +17 -0
- package/dist/modules/llmswitch/bridge.js.map +1 -1
- package/dist/modules/pipeline/utils/colored-logger.d.ts +14 -0
- package/dist/modules/pipeline/utils/colored-logger.js +48 -0
- package/dist/modules/pipeline/utils/colored-logger.js.map +1 -0
- package/dist/modules/pipeline/utils/debug-logger.d.ts +2 -0
- package/dist/modules/pipeline/utils/debug-logger.js +36 -0
- package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
- package/dist/providers/auth/gemini-cli-userinfo-helper.d.ts +53 -0
- package/dist/providers/auth/gemini-cli-userinfo-helper.js +152 -0
- package/dist/providers/auth/gemini-cli-userinfo-helper.js.map +1 -0
- package/dist/providers/auth/oauth-auth.js +3 -2
- package/dist/providers/auth/oauth-auth.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle.js +21 -20
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/oauth-logger.d.ts +1 -0
- package/dist/providers/auth/oauth-logger.js +21 -0
- package/dist/providers/auth/oauth-logger.js.map +1 -0
- package/dist/providers/compat/compat-directory-loader.js +2 -55
- package/dist/providers/compat/compat-directory-loader.js.map +1 -1
- package/dist/providers/compat/compatibility-factory.d.ts +4 -4
- package/dist/providers/compat/compatibility-factory.js +108 -0
- package/dist/providers/compat/compatibility-factory.js.map +1 -1
- package/dist/providers/compat/glm/glm-compatibility.d.ts +2 -2
- package/dist/providers/compat/glm/glm-compatibility.js +7 -7
- package/dist/providers/compat/glm/glm-compatibility.js.map +1 -1
- package/dist/providers/compat/glm/index.js +0 -6
- package/dist/providers/compat/glm/index.js.map +1 -1
- package/dist/providers/compat/iflow/iflow-compatibility.d.ts +1 -1
- package/dist/providers/compat/iflow/iflow-compatibility.js +6 -6
- package/dist/providers/compat/iflow/iflow-compatibility.js.map +1 -1
- package/dist/providers/compat/index.d.ts +0 -6
- package/dist/providers/compat/index.js +0 -7
- package/dist/providers/compat/index.js.map +1 -1
- package/dist/providers/compat/lmstudio-compatibility.d.ts +2 -2
- package/dist/providers/compat/lmstudio-compatibility.js +4 -4
- package/dist/providers/compat/lmstudio-compatibility.js.map +1 -1
- package/dist/providers/compat/passthrough-compatibility.d.ts +1 -1
- package/dist/providers/compat/passthrough-compatibility.js +3 -3
- package/dist/providers/compat/passthrough-compatibility.js.map +1 -1
- package/dist/providers/compat/profiles/chat/glm/index.d.ts +6 -0
- package/dist/providers/compat/profiles/chat/glm/index.js +6 -0
- package/dist/providers/compat/profiles/chat/glm/index.js.map +1 -0
- package/dist/providers/compat/profiles/chat/iflow/index.d.ts +6 -0
- package/dist/providers/compat/profiles/chat/iflow/index.js +6 -0
- package/dist/providers/compat/profiles/chat/iflow/index.js.map +1 -0
- package/dist/providers/compat/profiles/chat/lmstudio/index.d.ts +6 -0
- package/dist/providers/compat/profiles/chat/lmstudio/index.js +6 -0
- package/dist/providers/compat/profiles/chat/lmstudio/index.js.map +1 -0
- package/dist/providers/compat/profiles/chat/qwen/index.d.ts +6 -0
- package/dist/providers/compat/profiles/chat/qwen/index.js +6 -0
- package/dist/providers/compat/profiles/chat/qwen/index.js.map +1 -0
- package/dist/providers/compat/profiles/compat/passthrough/index.d.ts +6 -0
- package/dist/providers/compat/profiles/compat/passthrough/index.js +6 -0
- package/dist/providers/compat/profiles/compat/passthrough/index.js.map +1 -0
- package/dist/providers/compat/profiles/responses/c4m/index.d.ts +6 -0
- package/dist/providers/compat/profiles/responses/c4m/index.js +6 -0
- package/dist/providers/compat/profiles/responses/c4m/index.js.map +1 -0
- package/dist/providers/compat/profiles/responses/default/index.d.ts +6 -0
- package/dist/providers/compat/profiles/responses/default/index.js +6 -0
- package/dist/providers/compat/profiles/responses/default/index.js.map +1 -0
- package/dist/providers/compat/profiles/responses/fai/index.d.ts +6 -0
- package/dist/providers/compat/profiles/responses/fai/index.js +6 -0
- package/dist/providers/compat/profiles/responses/fai/index.js.map +1 -0
- package/dist/providers/compat/profiles/responses/fc/index.d.ts +6 -0
- package/dist/providers/compat/profiles/responses/fc/index.js +6 -0
- package/dist/providers/compat/profiles/responses/fc/index.js.map +1 -0
- package/dist/providers/compat/qwen/index.js +0 -6
- package/dist/providers/compat/qwen/index.js.map +1 -1
- package/dist/providers/compat/qwen-compatibility.d.ts +2 -2
- package/dist/providers/compat/qwen-compatibility.js +4 -4
- package/dist/providers/compat/qwen-compatibility.js.map +1 -1
- package/dist/providers/compat/register-compat-module.d.ts +8 -0
- package/dist/providers/compat/register-compat-module.js +53 -0
- package/dist/providers/compat/register-compat-module.js.map +1 -0
- package/dist/providers/compat/responses/c4m-responses-compatibility.d.ts +6 -2
- package/dist/providers/compat/responses/c4m-responses-compatibility.js +85 -3
- package/dist/providers/compat/responses/c4m-responses-compatibility.js.map +1 -1
- package/dist/providers/compat/standard-compatibility-utils.js +45 -15
- package/dist/providers/compat/standard-compatibility-utils.js.map +1 -1
- package/dist/providers/core/api/provider-config.d.ts +1 -1
- package/dist/providers/core/api/provider-types.d.ts +3 -1
- package/dist/providers/core/api/provider-types.js +1 -0
- package/dist/providers/core/api/provider-types.js.map +1 -1
- package/dist/providers/core/config/service-profiles.js +5 -2
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/runtime/base-provider.d.ts +3 -0
- package/dist/providers/core/runtime/base-provider.js +101 -6
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +34 -0
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +152 -0
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -0
- package/dist/providers/core/runtime/http-transport-provider.d.ts +1 -0
- package/dist/providers/core/runtime/http-transport-provider.js +178 -123
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-factory.d.ts +1 -1
- package/dist/providers/core/runtime/provider-factory.js +8 -0
- package/dist/providers/core/runtime/provider-factory.js.map +1 -1
- package/dist/providers/core/runtime/provider-runtime-metadata.d.ts +1 -0
- package/dist/providers/core/runtime/provider-runtime-metadata.js.map +1 -1
- package/dist/providers/core/runtime/responses-provider.d.ts +7 -0
- package/dist/providers/core/runtime/responses-provider.js +228 -12
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/providers/core/strategies/oauth-auth-code-flow.js +10 -9
- package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
- package/dist/providers/core/strategies/oauth-device-flow.js +10 -9
- package/dist/providers/core/strategies/oauth-device-flow.js.map +1 -1
- package/dist/providers/core/utils/provider-error-reporter.js +63 -15
- package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
- package/dist/providers/core/utils/provider-type-utils.d.ts +1 -1
- package/dist/providers/core/utils/provider-type-utils.js +6 -1
- package/dist/providers/core/utils/provider-type-utils.js.map +1 -1
- package/dist/providers/core/utils/snapshot-writer.d.ts +10 -0
- package/dist/providers/core/utils/snapshot-writer.js +85 -0
- package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
- package/dist/providers/mock/mock-provider-runtime.js +44 -0
- package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
- package/dist/providers/profile/provider-profile-loader.js +26 -19
- package/dist/providers/profile/provider-profile-loader.js.map +1 -1
- package/dist/providers/profile/provider-profile.d.ts +2 -2
- package/dist/server/handlers/chat-handler.js +9 -3
- package/dist/server/handlers/chat-handler.js.map +1 -1
- package/dist/server/handlers/handler-utils.d.ts +7 -1
- package/dist/server/handlers/handler-utils.js +64 -52
- package/dist/server/handlers/handler-utils.js.map +1 -1
- package/dist/server/handlers/messages-handler.js +9 -3
- package/dist/server/handlers/messages-handler.js.map +1 -1
- package/dist/server/handlers/responses-handler.js +21 -13
- package/dist/server/handlers/responses-handler.js.map +1 -1
- package/dist/server/runtime/http-server/colored-logger.d.ts +1 -0
- package/dist/server/runtime/http-server/colored-logger.js +33 -0
- package/dist/server/runtime/http-server/colored-logger.js.map +1 -0
- package/dist/server/runtime/http-server/index.d.ts +3 -0
- package/dist/server/runtime/http-server/index.js +76 -19
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/provider-utils.d.ts +3 -1
- package/dist/server/runtime/http-server/provider-utils.js +12 -2
- package/dist/server/runtime/http-server/provider-utils.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.js +6 -2
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.js +31 -11
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/types.d.ts +2 -1
- package/dist/utils/error-center-payload.d.ts +7 -0
- package/dist/utils/error-center-payload.js +67 -0
- package/dist/utils/error-center-payload.js.map +1 -0
- package/dist/utils/error-handler-registry.d.ts +7 -0
- package/dist/utils/error-handler-registry.js +44 -12
- package/dist/utils/error-handler-registry.js.map +1 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/codecs/responses-openai-codec.js +16 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-glm.json +17 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-iflow.json +36 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-lmstudio.json +37 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/chat-qwen.json +18 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/compat/profiles/responses-c4m.json +45 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/config/compat-profiles.json +38 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/config/sample-config.json +314 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/config/version-switch.json +150 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.d.ts +4 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-engine.js +667 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-profile-store.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-profile-store.js +76 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-types.d.ts +62 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/compat/compat-types.js +1 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/hub-pipeline.js +110 -29
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.d.ts +14 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/req_outbound/req_outbound_stage3_compat/index.js +23 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/index.js +34 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/process/chat-process.js +4 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/hub/response/provider-response.js +26 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.d.ts +1 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/responses/responses-openai-bridge.js +71 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-conversation-store.d.ts +35 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/responses-conversation-store.js +64 -19
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-filter-pipeline.d.ts +21 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-filter-pipeline.js +138 -22
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-governor.d.ts +21 -0
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-governor.js +116 -1
- package/node_modules/@jsonstudio/llms/dist/conversion/shared/tool-mapping.js +52 -2
- package/node_modules/@jsonstudio/llms/dist/filters/config/openai-openai.fieldmap.json +18 -0
- package/node_modules/@jsonstudio/llms/dist/filters/special/request-tools-normalize.js +20 -1
- package/node_modules/@jsonstudio/llms/dist/guidance/index.js +6 -2
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/bootstrap.js +16 -7
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/classifier.js +40 -37
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/default-thinking-keywords.d.ts +1 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/default-thinking-keywords.js +13 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.d.ts +39 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/engine.js +52 -11
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/features.js +340 -11
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-counter.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/token-counter.js +105 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.d.ts +8 -0
- package/node_modules/@jsonstudio/llms/dist/router/virtual-router/types.js +2 -2
- package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/builders/response-builder.d.ts +2 -0
- package/node_modules/@jsonstudio/llms/dist/sse/sse-to-json/builders/response-builder.js +53 -11
- package/node_modules/@jsonstudio/llms/dist/test-output/virtual-router/results.json +1 -0
- package/node_modules/@jsonstudio/llms/dist/test-output/virtual-router/summary.json +12 -0
- package/node_modules/@jsonstudio/llms/dist/tools/tool-registry.js +4 -3
- package/node_modules/@jsonstudio/llms/package.json +3 -3
- package/package.json +11 -9
- package/scripts/analyze-routing-classifier.mjs +166 -0
- package/scripts/analyze-routing-samples.mjs +216 -0
- package/scripts/analyze-thinking-keywords.mjs +17 -2
- package/scripts/build-core.mjs +8 -0
- package/scripts/classify-sample-tools.mjs +252 -0
- package/scripts/ensure-llmswitch-mode.mjs +95 -0
- package/scripts/gen-build-info.mjs +58 -4
- package/scripts/install-global.sh +1 -1
- package/scripts/install-release.sh +7 -0
- package/scripts/mock-provider/run-regressions.mjs +60 -14
- package/scripts/tests/apply-patch-loop.mjs +100 -9
- package/scripts/tests/golden-provider-cycle.mjs +12 -1
- package/scripts/tests/responses-provider-dry-run.mjs +15 -1
- package/scripts/tests/virtual-router-health.mjs +12 -5
- package/scripts/tools/capture-provider-goldens.mjs +75 -25
- package/scripts/tools/responses-golden-dry-run.mjs +17 -1
- package/scripts/tools/responses-provider-replay.mjs +17 -1
- package/scripts/tools/sync-ci-goldens.mjs +131 -0
- package/scripts/verification/samples/openai-chat-list-local-files.json +19 -796
- package/scripts/verify-e2e-toolcall.mjs +52 -0
- package/dist/providers/compat/config/index.d.ts +0 -1
- package/dist/providers/compat/config/index.js +0 -5
- package/dist/providers/compat/config/index.js.map +0 -1
- package/dist/providers/compat/iflow/index.d.ts +0 -27
- package/dist/providers/compat/iflow/index.js +0 -32
- package/dist/providers/compat/iflow/index.js.map +0 -1
- package/dist/providers/compat/lmstudio/index.d.ts +0 -4
- package/dist/providers/compat/lmstudio/index.js +0 -10
- package/dist/providers/compat/lmstudio/index.js.map +0 -1
- package/dist/providers/compat/passthrough/index.d.ts +0 -4
- package/dist/providers/compat/passthrough/index.js +0 -9
- package/dist/providers/compat/passthrough/index.js.map +0 -1
- package/dist/providers/compat/responses/index.d.ts +0 -1
- package/dist/providers/compat/responses/index.js +0 -8
- package/dist/providers/compat/responses/index.js.map +0 -1
- package/dist/providers/core/composite/compat/anthropic.d.ts +0 -3
- package/dist/providers/core/composite/compat/anthropic.js +0 -7
- package/dist/providers/core/composite/compat/anthropic.js.map +0 -1
- package/dist/providers/core/composite/compat/gemini.d.ts +0 -3
- package/dist/providers/core/composite/compat/gemini.js +0 -7
- package/dist/providers/core/composite/compat/gemini.js.map +0 -1
- package/dist/providers/core/composite/compat/openai-compat-aggregator.d.ts +0 -9
- package/dist/providers/core/composite/compat/openai-compat-aggregator.js +0 -135
- package/dist/providers/core/composite/compat/openai-compat-aggregator.js.map +0 -1
- package/dist/providers/core/composite/compat/responses.d.ts +0 -3
- package/dist/providers/core/composite/compat/responses.js +0 -91
- package/dist/providers/core/composite/compat/responses.js.map +0 -1
- package/dist/providers/core/composite/provider-composite.d.ts +0 -50
- package/dist/providers/core/composite/provider-composite.js +0 -235
- package/dist/providers/core/composite/provider-composite.js.map +0 -1
- package/scripts/tests/apply-patch-loop.mjs.bak +0 -363
|
@@ -95,11 +95,12 @@ export function validateToolCall(name, argsString) {
|
|
|
95
95
|
const rawArgs = tryParseJson(typeof argsString === 'string' ? argsString : '{}');
|
|
96
96
|
switch (normalizedName) {
|
|
97
97
|
case 'apply_patch': {
|
|
98
|
-
const
|
|
98
|
+
const input = asString(rawArgs.input);
|
|
99
|
+
const patch = asString(rawArgs.patch) ?? input;
|
|
99
100
|
if (!patch) {
|
|
100
|
-
return { ok: false, reason: '
|
|
101
|
+
return { ok: false, reason: 'missing_input' };
|
|
101
102
|
}
|
|
102
|
-
return { ok: true, normalizedArgs: toJson({ patch }) };
|
|
103
|
+
return { ok: true, normalizedArgs: toJson({ input: patch, patch }) };
|
|
103
104
|
}
|
|
104
105
|
case 'shell': {
|
|
105
106
|
const rawCommand = rawArgs.command;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsonstudio/llms",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.104",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"build": "tsc -p tsconfig.json",
|
|
10
|
-
"build:dev": "tsc -p tsconfig.json",
|
|
9
|
+
"build": "node scripts/bump-version.mjs && tsc -p tsconfig.json && node scripts/tools/copy-compat-profiles.mjs",
|
|
10
|
+
"build:dev": "node scripts/bump-version.mjs && tsc -p tsconfig.json && node scripts/tools/copy-compat-profiles.mjs",
|
|
11
11
|
"lint": "eslint --no-eslintrc -c .eslintrc.json src --ext .ts --no-cache",
|
|
12
12
|
"lint:fix": "eslint --no-eslintrc -c .eslintrc.json src --ext .ts --no-cache --fix",
|
|
13
13
|
"postbuild": "node scripts/tests/run-matrix-ci.mjs",
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsonstudio/rcc",
|
|
3
|
-
"version": "0.89.
|
|
4
|
-
"description": "Multi-provider OpenAI proxy server with anthropic/responses/chat support",
|
|
3
|
+
"version": "0.89.164",
|
|
4
|
+
"description": "Multi-provider OpenAI proxy server with anthropic/responses/chat support (dev)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"bin": {
|
|
9
|
-
"rcc": "
|
|
9
|
+
"rcc": "dist/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"node": ">=20 <26"
|
|
32
32
|
},
|
|
33
33
|
"scripts": {
|
|
34
|
-
"build": "node scripts/build-core.mjs && node scripts/vendor-core.mjs && npm run clean && node scripts/gen-build-info.mjs && tsc && node scripts/copy-compat-assets.mjs && node scripts/copy-modules-config.mjs",
|
|
35
|
-
"build:dev": "npm run
|
|
36
|
-
"build:min": "node scripts/build-core.mjs && node scripts/vendor-core.mjs && npm run clean && node scripts/gen-build-info.mjs && tsc && node scripts/copy-compat-
|
|
34
|
+
"build": "npm run llmswitch:ensure && node scripts/build-core.mjs && node scripts/vendor-core.mjs && npm run clean && node scripts/gen-build-info.mjs && tsc && node scripts/copy-compat-assets.mjs && node scripts/copy-modules-config.mjs",
|
|
35
|
+
"build:dev": "BUILD_MODE=dev npm run build && npm run verify:e2e-toolcall && npm run install:global",
|
|
36
|
+
"build:min": "npm run llmswitch:ensure && node scripts/build-core.mjs && node scripts/vendor-core.mjs && npm run clean && node scripts/gen-build-info.mjs && tsc && node scripts/copy-compat-assets.mjs && node scripts/copy-modules-config.mjs",
|
|
37
37
|
"prepack": "echo skip-prepack",
|
|
38
38
|
"postbuild": "chmod +x dist/cli.js || true",
|
|
39
39
|
"build:watch": "tsc --watch",
|
|
@@ -76,6 +76,7 @@
|
|
|
76
76
|
"debug:responses:lmstudio:text": "tsx tools/responses-debug-client/src/index.ts --file tools/responses-debug-client/payloads/lmstudio-text.json --baseURL ${LMSTUDIO_BASEURL:-http://127.0.0.1:1234/v1}",
|
|
77
77
|
"debug:responses:lmstudio:tool": "tsx tools/responses-debug-client/src/index.ts --file tools/responses-debug-client/payloads/lmstudio-tool.json --baseURL ${LMSTUDIO_BASEURL:-http://127.0.0.1:1234/v1}",
|
|
78
78
|
"capture:responses:lmstudio": "node scripts/capture-responses-sse.mjs --file tools/responses-debug-client/payloads/lmstudio-tool.json",
|
|
79
|
+
"llmswitch:ensure": "node scripts/ensure-llmswitch-mode.mjs",
|
|
79
80
|
"llmswitch:link": "node scripts/link-llmswitch.mjs",
|
|
80
81
|
"llmswitch:unlink": "node scripts/link-llmswitch.mjs unlink",
|
|
81
82
|
"dry-run:responses-provider": "node scripts/tests/responses-provider-dry-run.mjs",
|
|
@@ -88,8 +89,8 @@
|
|
|
88
89
|
"config:update:providers": "node scripts/update-config-providers.mjs",
|
|
89
90
|
"models:update": "node scripts/update-models.mjs",
|
|
90
91
|
"models:update:qwen": "node scripts/update-models.mjs --provider qwen-provider --write",
|
|
91
|
-
"config:use-local": "
|
|
92
|
-
"config:use-published": "
|
|
92
|
+
"config:use-local": "BUILD_MODE=dev npm run llmswitch:ensure",
|
|
93
|
+
"config:use-published": "BUILD_MODE=release npm run llmswitch:ensure",
|
|
93
94
|
"test:modelscope": "node scripts/test-modelscope.mjs",
|
|
94
95
|
"security:audit": "npm audit --audit-level high",
|
|
95
96
|
"security:check": "npx audit-ci --config ./audit-ci.json",
|
|
@@ -116,13 +117,14 @@
|
|
|
116
117
|
"test:v2:protocol": "node tests/v2/dist/protocol-conversion-test.js",
|
|
117
118
|
"test:comprehensive": "node scripts/v2-consistency/comprehensive-consistency-test.mjs",
|
|
118
119
|
"test:golden": "node scripts/tests/golden-provider-cycle.mjs",
|
|
120
|
+
"sync:ci-goldens": "node scripts/tools/sync-ci-goldens.mjs",
|
|
119
121
|
"mock:extract": "node scripts/mock-provider/extract.mjs",
|
|
120
122
|
"mock:validate": "node scripts/mock-provider/validate.mjs",
|
|
121
123
|
"mock:clean": "node scripts/mock-provider/clean.mjs"
|
|
122
124
|
},
|
|
123
125
|
"dependencies": {
|
|
124
126
|
"@anthropic-ai/sdk": "^0.65.0",
|
|
125
|
-
"@jsonstudio/llms": "^0.6.
|
|
127
|
+
"@jsonstudio/llms": "^0.6.104",
|
|
126
128
|
"@lmstudio/sdk": "^1.5.0",
|
|
127
129
|
"@radix-ui/react-switch": "^1.2.6",
|
|
128
130
|
"@types/socket.io": "^3.0.1",
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const suffix = '_req_process_tool_filters_request_pre.json';
|
|
8
|
+
const DEFAULT_SAMPLE_ROOT = path.join(os.homedir(), '.routecodex', 'codex-samples');
|
|
9
|
+
const DEFAULT_LIMIT = 400;
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
let sampleRoot = DEFAULT_SAMPLE_ROOT;
|
|
12
|
+
let limit = DEFAULT_LIMIT;
|
|
13
|
+
|
|
14
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
15
|
+
const arg = args[i];
|
|
16
|
+
if (!arg) continue;
|
|
17
|
+
if (arg === '--limit' && i + 1 < args.length) {
|
|
18
|
+
limit = Number(args[i + 1]) || DEFAULT_LIMIT;
|
|
19
|
+
i += 1;
|
|
20
|
+
} else if (arg.startsWith('--')) {
|
|
21
|
+
continue;
|
|
22
|
+
} else if (sampleRoot === DEFAULT_SAMPLE_ROOT) {
|
|
23
|
+
sampleRoot = path.resolve(arg);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
27
|
+
const __dirname = path.dirname(__filename);
|
|
28
|
+
const ROOT = process.cwd();
|
|
29
|
+
|
|
30
|
+
const ENDPOINT_MAP = {
|
|
31
|
+
'openai-chat': '/v1/chat/completions',
|
|
32
|
+
'openai-responses': '/v1/responses',
|
|
33
|
+
'anthropic-messages': '/v1/messages'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
async function loadClassifierModules() {
|
|
37
|
+
const featuresPath = path.join(ROOT, 'sharedmodule', 'llmswitch-core', 'dist', 'router', 'virtual-router', 'features.js');
|
|
38
|
+
const classifierPath = path.join(ROOT, 'sharedmodule', 'llmswitch-core', 'dist', 'router', 'virtual-router', 'classifier.js');
|
|
39
|
+
const { buildRoutingFeatures } = await import('file://' + featuresPath);
|
|
40
|
+
const { RoutingClassifier } = await import('file://' + classifierPath);
|
|
41
|
+
return { buildRoutingFeatures, RoutingClassifier };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function loadClassifierConfig() {
|
|
45
|
+
const modulesPath = path.join(ROOT, 'config', 'modules.json');
|
|
46
|
+
const raw = await fs.readFile(modulesPath, 'utf8');
|
|
47
|
+
const json = JSON.parse(raw);
|
|
48
|
+
const cfg =
|
|
49
|
+
json?.virtualrouter?.config?.classificationConfig ||
|
|
50
|
+
json?.modules?.virtualrouter?.config?.classificationConfig ||
|
|
51
|
+
{};
|
|
52
|
+
return cfg || {};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function listCandidateFiles(dir) {
|
|
56
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
57
|
+
const files = [];
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
const full = path.join(dir, entry.name);
|
|
60
|
+
if (entry.isDirectory()) {
|
|
61
|
+
files.push(...(await listCandidateFiles(full)));
|
|
62
|
+
} else if (entry.isFile() && entry.name.endsWith(suffix)) {
|
|
63
|
+
files.push(full);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return files;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function requestKey(filePath) {
|
|
70
|
+
const base = path.basename(filePath);
|
|
71
|
+
const match = base.match(/^(req_\d+_[^_]+)/);
|
|
72
|
+
return match ? match[1] : base;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function inferEndpoint(filePath) {
|
|
76
|
+
const parts = filePath.split(path.sep);
|
|
77
|
+
for (const part of parts) {
|
|
78
|
+
if (ENDPOINT_MAP[part]) return ENDPOINT_MAP[part];
|
|
79
|
+
}
|
|
80
|
+
return '/v1/responses';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function buildMetadata(reqId, endpoint) {
|
|
84
|
+
return {
|
|
85
|
+
requestId: reqId,
|
|
86
|
+
entryEndpoint: endpoint,
|
|
87
|
+
processMode: 'chat',
|
|
88
|
+
stream: false,
|
|
89
|
+
direction: 'request'
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function main() {
|
|
94
|
+
const { buildRoutingFeatures, RoutingClassifier } = await loadClassifierModules();
|
|
95
|
+
const classifierConfig = await loadClassifierConfig();
|
|
96
|
+
const classifier = new RoutingClassifier(classifierConfig);
|
|
97
|
+
|
|
98
|
+
const protocols = await fs.readdir(sampleRoot, { withFileTypes: true });
|
|
99
|
+
const files = [];
|
|
100
|
+
for (const proto of protocols) {
|
|
101
|
+
if (!proto.isDirectory()) continue;
|
|
102
|
+
const dir = path.join(sampleRoot, proto.name);
|
|
103
|
+
files.push(...(await listCandidateFiles(dir)));
|
|
104
|
+
}
|
|
105
|
+
files.sort((a, b) => a.localeCompare(b));
|
|
106
|
+
|
|
107
|
+
let processedFiles = files;
|
|
108
|
+
if (limit && files.length > limit) {
|
|
109
|
+
processedFiles = files.slice(-limit);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const seen = new Set();
|
|
113
|
+
const stats = new Map();
|
|
114
|
+
const diagnostics = [];
|
|
115
|
+
|
|
116
|
+
for (const filePath of processedFiles) {
|
|
117
|
+
const key = requestKey(filePath);
|
|
118
|
+
if (seen.has(key)) continue;
|
|
119
|
+
seen.add(key);
|
|
120
|
+
let payload;
|
|
121
|
+
try {
|
|
122
|
+
const raw = await fs.readFile(filePath, 'utf8');
|
|
123
|
+
payload = JSON.parse(raw);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
diagnostics.push({ file: filePath, error: err.message || String(err) });
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (!payload || typeof payload !== 'object') continue;
|
|
129
|
+
const endpoint = inferEndpoint(filePath);
|
|
130
|
+
const metadata = buildMetadata(key, endpoint);
|
|
131
|
+
let features;
|
|
132
|
+
try {
|
|
133
|
+
features = buildRoutingFeatures(payload, metadata);
|
|
134
|
+
} catch (err) {
|
|
135
|
+
diagnostics.push({ file: filePath, error: err.message || String(err), stage: 'features' });
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
let classification;
|
|
139
|
+
try {
|
|
140
|
+
classification = classifier.classify(features);
|
|
141
|
+
} catch (err) {
|
|
142
|
+
diagnostics.push({ file: filePath, error: err.message || String(err), stage: 'classify' });
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const route = classification?.routeName || 'unknown';
|
|
146
|
+
stats.set(route, (stats.get(route) || 0) + 1);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const total = Array.from(stats.values()).reduce((sum, count) => sum + count, 0);
|
|
150
|
+
const summary = Array.from(stats.entries())
|
|
151
|
+
.map(([route, count]) => ({ route, count, ratio: total ? count / total : 0 }))
|
|
152
|
+
.sort((a, b) => b.count - a.count);
|
|
153
|
+
|
|
154
|
+
console.log(
|
|
155
|
+
JSON.stringify(
|
|
156
|
+
{ sampleRoot, configuredLimit: limit, evaluatedSamples: processedFiles.length, totalSamples: total, summary, diagnostics },
|
|
157
|
+
null,
|
|
158
|
+
2
|
|
159
|
+
)
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
main().catch((err) => {
|
|
164
|
+
console.error('Failed to analyze routing classifier:', err);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
});
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Analyze Codex sample requests collected under ~/.routecodex/codex-samples
|
|
4
|
+
* and summarize the last assistant tool calls observed in inbound requests.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node scripts/analyze-routing-samples.mjs [--limit N] [--root DIR] [--protocols list]
|
|
8
|
+
* --limit Number of most recent samples to scan per protocol (default: 200)
|
|
9
|
+
* --root Override sample root (default: ~/.routecodex/codex-samples)
|
|
10
|
+
* --protocols Comma-separated list of protocol folders to include
|
|
11
|
+
*/
|
|
12
|
+
import { execSync } from 'node:child_process';
|
|
13
|
+
import { promises as fs } from 'node:fs';
|
|
14
|
+
import path from 'node:path';
|
|
15
|
+
import os from 'node:os';
|
|
16
|
+
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
const options = {
|
|
19
|
+
limit: 200,
|
|
20
|
+
root: path.join(os.homedir(), '.routecodex', 'codex-samples'),
|
|
21
|
+
protocols: null,
|
|
22
|
+
};
|
|
23
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
24
|
+
const arg = args[i];
|
|
25
|
+
if (arg === '--limit' && i + 1 < args.length) {
|
|
26
|
+
options.limit = Number(args[i + 1]);
|
|
27
|
+
i += 1;
|
|
28
|
+
} else if (arg === '--root' && i + 1 < args.length) {
|
|
29
|
+
options.root = path.resolve(args[i + 1]);
|
|
30
|
+
i += 1;
|
|
31
|
+
} else if (arg === '--protocols' && i + 1 < args.length) {
|
|
32
|
+
options.protocols = args[i + 1].split(',').map((s) => s.trim()).filter(Boolean);
|
|
33
|
+
i += 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const STAGE_SUFFIX = '_req_process_tool_filters_request_pre.json';
|
|
38
|
+
|
|
39
|
+
function listProtocols(dir) {
|
|
40
|
+
return fs.readdir(dir, { withFileTypes: true })
|
|
41
|
+
.then((entries) => entries.filter((e) => e.isDirectory()).map((e) => e.name))
|
|
42
|
+
.catch(() => []);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function listStageFiles(dir) {
|
|
46
|
+
try {
|
|
47
|
+
const out = execSync(`rg --files "${dir}" -g "*${STAGE_SUFFIX}"`, { stdio: ['ignore', 'pipe', 'ignore'] })
|
|
48
|
+
.toString()
|
|
49
|
+
.trim();
|
|
50
|
+
if (!out) return [];
|
|
51
|
+
return out.split('\n').filter(Boolean);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
if (err?.status === 1 && (!err.stdout || err.stdout.length === 0)) return [];
|
|
54
|
+
throw err;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function extractTimestamp(filePath) {
|
|
59
|
+
const base = path.basename(filePath);
|
|
60
|
+
const m = base.match(/req_(\d+)_/);
|
|
61
|
+
if (!m) return 0;
|
|
62
|
+
return Number(m[1]);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function extractRequestId(filePath) {
|
|
66
|
+
const base = path.basename(filePath);
|
|
67
|
+
const m = base.match(/^(req_\d+_[^_]+)/);
|
|
68
|
+
return m ? m[1] : base;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function safeText(content) {
|
|
72
|
+
if (typeof content === 'string') return content;
|
|
73
|
+
if (Array.isArray(content)) {
|
|
74
|
+
return content.map((part) => {
|
|
75
|
+
if (!part) return '';
|
|
76
|
+
if (typeof part === 'string') return part;
|
|
77
|
+
if (typeof part === 'object') {
|
|
78
|
+
if (typeof part.text === 'string') return part.text;
|
|
79
|
+
if (Array.isArray(part.text)) return part.text.join(' ');
|
|
80
|
+
if (typeof part.content === 'string') return part.content;
|
|
81
|
+
}
|
|
82
|
+
return '';
|
|
83
|
+
}).join(' ');
|
|
84
|
+
}
|
|
85
|
+
if (content && typeof content === 'object' && typeof content.text === 'string') {
|
|
86
|
+
return content.text;
|
|
87
|
+
}
|
|
88
|
+
return '';
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function lastAssistantToolCalls(messages) {
|
|
92
|
+
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
93
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
94
|
+
const msg = messages[i];
|
|
95
|
+
if (msg?.role !== 'assistant') continue;
|
|
96
|
+
const calls = Array.isArray(msg.tool_calls) ? msg.tool_calls : null;
|
|
97
|
+
if (calls && calls.length) {
|
|
98
|
+
return calls
|
|
99
|
+
.map((call) => {
|
|
100
|
+
const name = call?.function?.name || call?.name;
|
|
101
|
+
if (!name) return null;
|
|
102
|
+
const args = typeof call?.function?.arguments === 'string' ? call.function.arguments : undefined;
|
|
103
|
+
return { name, arguments: args };
|
|
104
|
+
})
|
|
105
|
+
.filter(Boolean);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return [];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function lastUserText(messages) {
|
|
112
|
+
if (!Array.isArray(messages) || messages.length === 0) return '';
|
|
113
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
114
|
+
const msg = messages[i];
|
|
115
|
+
if (msg?.role === 'user') {
|
|
116
|
+
return safeText(msg.content).slice(0, 400);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function main() {
|
|
123
|
+
const protocols = options.protocols || await listProtocols(options.root);
|
|
124
|
+
const perProtocol = new Map();
|
|
125
|
+
const files = [];
|
|
126
|
+
for (const proto of protocols) {
|
|
127
|
+
const dir = path.join(options.root, proto);
|
|
128
|
+
const list = listStageFiles(dir);
|
|
129
|
+
if (list.length === 0) continue;
|
|
130
|
+
const sorted = list
|
|
131
|
+
.map((filePath) => ({ filePath, ts: extractTimestamp(filePath) }))
|
|
132
|
+
.sort((a, b) => b.ts - a.ts)
|
|
133
|
+
.slice(0, options.limit);
|
|
134
|
+
perProtocol.set(proto, sorted.length);
|
|
135
|
+
files.push(...sorted.map((item) => ({ ...item, proto })));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const toolCounts = new Map();
|
|
139
|
+
const toolExamples = new Map();
|
|
140
|
+
let withAssistantTools = 0;
|
|
141
|
+
for (const { filePath, proto } of files) {
|
|
142
|
+
let payload;
|
|
143
|
+
try {
|
|
144
|
+
const raw = await fs.readFile(filePath, 'utf8');
|
|
145
|
+
payload = JSON.parse(raw);
|
|
146
|
+
} catch {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const messages = Array.isArray(payload?.messages) ? payload.messages : [];
|
|
150
|
+
const calls = lastAssistantToolCalls(messages);
|
|
151
|
+
if (calls.length) {
|
|
152
|
+
withAssistantTools += 1;
|
|
153
|
+
const snippet = lastUserText(messages);
|
|
154
|
+
const reqId = extractRequestId(filePath);
|
|
155
|
+
for (const call of calls) {
|
|
156
|
+
const canonical = canonicalizeToolName(call.name);
|
|
157
|
+
const parsedArguments = parseArguments(call.arguments);
|
|
158
|
+
toolCounts.set(canonical, (toolCounts.get(canonical) || 0) + 1);
|
|
159
|
+
if (!toolExamples.has(canonical)) {
|
|
160
|
+
toolExamples.set(canonical, []);
|
|
161
|
+
}
|
|
162
|
+
const collection = toolExamples.get(canonical);
|
|
163
|
+
if (collection.length < 3) {
|
|
164
|
+
collection.push({
|
|
165
|
+
reqId,
|
|
166
|
+
proto,
|
|
167
|
+
snippet,
|
|
168
|
+
rawName: call.name,
|
|
169
|
+
command: parsedArguments?.command || parsedArguments?.input?.command
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const histogram = Array.from(toolCounts.entries())
|
|
177
|
+
.sort((a, b) => b[1] - a[1])
|
|
178
|
+
.map(([name, count]) => ({ name, count, examples: toolExamples.get(name) || [] }));
|
|
179
|
+
|
|
180
|
+
const summary = {
|
|
181
|
+
sampleRoot: options.root,
|
|
182
|
+
perProtocolCounts: Object.fromEntries(perProtocol),
|
|
183
|
+
totalSamples: files.length,
|
|
184
|
+
requestsWithAssistantTool: withAssistantTools,
|
|
185
|
+
uniqueTools: histogram.length,
|
|
186
|
+
toolHistogram: histogram,
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function canonicalizeToolName(name) {
|
|
193
|
+
if (!name) return '';
|
|
194
|
+
const trimmed = name.trim();
|
|
195
|
+
const marker = trimmed.indexOf('arg_key');
|
|
196
|
+
if (marker > 0) {
|
|
197
|
+
return trimmed.slice(0, marker);
|
|
198
|
+
}
|
|
199
|
+
return trimmed;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function parseArguments(argumentString) {
|
|
203
|
+
if (typeof argumentString !== 'string' || !argumentString.trim()) {
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
return JSON.parse(argumentString);
|
|
208
|
+
} catch {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
main().catch((err) => {
|
|
214
|
+
console.error('Failed to analyze samples:', err);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
});
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import fs from 'fs/promises';
|
|
11
11
|
import os from 'os';
|
|
12
12
|
import path from 'path';
|
|
13
|
+
import { DEFAULT_THINKING_KEYWORDS } from '@jsonstudio/llms';
|
|
13
14
|
|
|
14
15
|
const HOME = os.homedir();
|
|
15
16
|
const CHAT_DIR = path.join(HOME, '.routecodex', 'codex-samples', 'openai-chat');
|
|
@@ -85,8 +86,10 @@ function extractUserText(request, endpoint, protocolMapping) {
|
|
|
85
86
|
|
|
86
87
|
async function main() {
|
|
87
88
|
const classificationConfig = await loadClassificationConfigFromModules();
|
|
88
|
-
const thinkingKeywords = (
|
|
89
|
-
|
|
89
|
+
const thinkingKeywords = mergeKeywordLists(
|
|
90
|
+
DEFAULT_THINKING_KEYWORDS,
|
|
91
|
+
classificationConfig.thinkingKeywords,
|
|
92
|
+
classificationConfig.keywordInjections?.thinking
|
|
90
93
|
);
|
|
91
94
|
const protocolMapping = classificationConfig.protocolMapping || {};
|
|
92
95
|
|
|
@@ -167,3 +170,15 @@ main().catch((err) => {
|
|
|
167
170
|
process.exit(1);
|
|
168
171
|
});
|
|
169
172
|
|
|
173
|
+
function mergeKeywordLists(...lists) {
|
|
174
|
+
const set = new Set();
|
|
175
|
+
for (const list of lists) {
|
|
176
|
+
if (!Array.isArray(list)) continue;
|
|
177
|
+
for (const item of list) {
|
|
178
|
+
if (!item) continue;
|
|
179
|
+
const lowered = String(item).toLowerCase();
|
|
180
|
+
if (lowered) set.add(lowered);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return Array.from(set);
|
|
184
|
+
}
|
package/scripts/build-core.mjs
CHANGED
|
@@ -5,6 +5,8 @@ import path from 'node:path';
|
|
|
5
5
|
|
|
6
6
|
const root = process.cwd();
|
|
7
7
|
const skip = String(process.env.ROUTECODEX_SKIP_CORE_BUILD || process.env.SKIP_CORE_BUILD || '').trim().toLowerCase();
|
|
8
|
+
const buildModeRaw = String(process.env.BUILD_MODE || process.env.RCC_BUILD_MODE || 'release').toLowerCase();
|
|
9
|
+
const buildMode = buildModeRaw === 'dev' ? 'dev' : 'release';
|
|
8
10
|
const tsc = path.join(root, 'node_modules', 'typescript', 'bin', 'tsc');
|
|
9
11
|
const proj = path.join(root, 'sharedmodule', 'llmswitch-core', 'tsconfig.json');
|
|
10
12
|
const coreRoot = path.join(root, 'sharedmodule', 'llmswitch-core');
|
|
@@ -77,6 +79,12 @@ if (!fs.existsSync(proj)) {
|
|
|
77
79
|
process.exit(0);
|
|
78
80
|
}
|
|
79
81
|
|
|
82
|
+
// 标准流程:release 构建必须依赖 npm 包(@jsonstudio/llms),禁止编译本地 sharedmodule。
|
|
83
|
+
if (buildMode !== 'dev') {
|
|
84
|
+
console.log('[build-core] BUILD_MODE=release: skip local llmswitch-core build (use npm @jsonstudio/llms)');
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
|
|
80
88
|
// Allow skip via env or if dist already present
|
|
81
89
|
if (skip === '1' || skip === 'true' || skip === 'yes') {
|
|
82
90
|
console.log('[build-core] skip requested by env (ROUTECODEX_SKIP_CORE_BUILD/SKIP_CORE_BUILD)');
|