@jsonstudio/rcc 0.89.3 → 0.89.168
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 +3 -3
- 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 +19 -2
- package/dist/providers/core/config/service-profiles.js.map +1 -1
- package/dist/providers/core/runtime/base-provider.d.ts +8 -0
- package/dist/providers/core/runtime/base-provider.js +79 -36
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.d.ts +33 -0
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +156 -0
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -0
- package/dist/providers/core/runtime/gemini-http-provider.d.ts +1 -2
- package/dist/providers/core/runtime/gemini-http-provider.js +0 -12
- package/dist/providers/core/runtime/gemini-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.d.ts +42 -0
- package/dist/providers/core/runtime/http-request-executor.js +133 -0
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -0
- package/dist/providers/core/runtime/http-transport-provider.d.ts +7 -11
- package/dist/providers/core/runtime/http-transport-provider.js +226 -371
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-error-classifier.d.ts +25 -0
- package/dist/providers/core/runtime/provider-error-classifier.js +139 -0
- package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -0
- package/dist/providers/core/runtime/provider-error-types.d.ts +23 -0
- package/dist/providers/core/runtime/provider-error-types.js +2 -0
- package/dist/providers/core/runtime/provider-error-types.js.map +1 -0
- package/dist/providers/core/runtime/provider-factory.d.ts +1 -1
- package/dist/providers/core/runtime/provider-factory.js +14 -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 +13 -10
- 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/pack-mode.mjs +30 -1
- package/scripts/publish-rcc.mjs +31 -0
- 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
|
@@ -0,0 +1,252 @@
|
|
|
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
|
+
|
|
6
|
+
const suffix = '_req_process_tool_filters_request_pre.json';
|
|
7
|
+
const sampleRoot = process.argv[2] || path.join(os.homedir(), '.routecodex', 'codex-samples');
|
|
8
|
+
|
|
9
|
+
const SHELL_PATTERNS = {
|
|
10
|
+
read: [
|
|
11
|
+
'ls',
|
|
12
|
+
'dir ',
|
|
13
|
+
'pwd',
|
|
14
|
+
'cat ',
|
|
15
|
+
'type ',
|
|
16
|
+
'head ',
|
|
17
|
+
'tail ',
|
|
18
|
+
'stat',
|
|
19
|
+
'tree',
|
|
20
|
+
'wc ',
|
|
21
|
+
'du ',
|
|
22
|
+
'printf "',
|
|
23
|
+
'python - <<',
|
|
24
|
+
'python -c',
|
|
25
|
+
'node - <<',
|
|
26
|
+
'node -e',
|
|
27
|
+
'codesign --display'
|
|
28
|
+
],
|
|
29
|
+
search: [
|
|
30
|
+
'rg ',
|
|
31
|
+
'rg-',
|
|
32
|
+
'grep ',
|
|
33
|
+
'grep-',
|
|
34
|
+
'ripgrep',
|
|
35
|
+
'find ',
|
|
36
|
+
'fd ',
|
|
37
|
+
'locate ',
|
|
38
|
+
'search ',
|
|
39
|
+
'codesearch',
|
|
40
|
+
'ack ',
|
|
41
|
+
'ag ',
|
|
42
|
+
'where ',
|
|
43
|
+
'which '
|
|
44
|
+
],
|
|
45
|
+
write: [
|
|
46
|
+
'apply_patch',
|
|
47
|
+
'sed -i',
|
|
48
|
+
'perl -pi',
|
|
49
|
+
'tee ',
|
|
50
|
+
'cat <<',
|
|
51
|
+
'cat >',
|
|
52
|
+
'printf >',
|
|
53
|
+
'touch ',
|
|
54
|
+
'truncate',
|
|
55
|
+
'mkdir',
|
|
56
|
+
'mktemp',
|
|
57
|
+
'rmdir',
|
|
58
|
+
'rm ',
|
|
59
|
+
'rm -',
|
|
60
|
+
'unlink',
|
|
61
|
+
'mv ',
|
|
62
|
+
'cp ',
|
|
63
|
+
'ln -',
|
|
64
|
+
'chmod',
|
|
65
|
+
'chown',
|
|
66
|
+
'chgrp',
|
|
67
|
+
'tar xf',
|
|
68
|
+
'tar cf',
|
|
69
|
+
'git add',
|
|
70
|
+
'git commit',
|
|
71
|
+
'git apply',
|
|
72
|
+
'git am',
|
|
73
|
+
'git rebase',
|
|
74
|
+
'git checkout',
|
|
75
|
+
'git merge',
|
|
76
|
+
'patch <<',
|
|
77
|
+
'npm install',
|
|
78
|
+
'pnpm install',
|
|
79
|
+
'yarn add',
|
|
80
|
+
'yarn install',
|
|
81
|
+
'pip install',
|
|
82
|
+
'pip3 install',
|
|
83
|
+
'brew install',
|
|
84
|
+
'cargo add',
|
|
85
|
+
'cargo install',
|
|
86
|
+
'go install',
|
|
87
|
+
'make install'
|
|
88
|
+
]
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
function canonicalizeToolName(name) {
|
|
92
|
+
if (!name) return '';
|
|
93
|
+
const trimmed = name.trim();
|
|
94
|
+
const idx = trimmed.indexOf('arg_');
|
|
95
|
+
if (idx > 0) return trimmed.slice(0, idx);
|
|
96
|
+
return trimmed;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function normalizeCommand(cmd) {
|
|
100
|
+
if (!cmd) return '';
|
|
101
|
+
if (Array.isArray(cmd)) return cmd.join(' ');
|
|
102
|
+
if (typeof cmd === 'object') {
|
|
103
|
+
if (cmd.command) return normalizeCommand(cmd.command);
|
|
104
|
+
if (cmd.args) return normalizeCommand(cmd.args);
|
|
105
|
+
try {
|
|
106
|
+
return JSON.stringify(cmd);
|
|
107
|
+
} catch {
|
|
108
|
+
return String(cmd);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return String(cmd || '').trim();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function detectCategory(tool, cmd) {
|
|
115
|
+
if (!tool) return 'other';
|
|
116
|
+
const lowTool = tool.toLowerCase();
|
|
117
|
+
if (lowTool === 'apply_patch') return 'write';
|
|
118
|
+
if (lowTool === 'describe_current_request') return 'read';
|
|
119
|
+
if (lowTool === 'list_mcp_resources' || lowTool === 'list_mcp_tools') return 'other';
|
|
120
|
+
if (lowTool === 'update_plan') return 'other';
|
|
121
|
+
|
|
122
|
+
const normalizedCmd = cmd.toLowerCase();
|
|
123
|
+
if (lowTool === 'shell_command' || lowTool === 'shell' || lowTool === 'bash') {
|
|
124
|
+
return detectShellCommandCategory(normalizedCmd);
|
|
125
|
+
}
|
|
126
|
+
if (matchesAny(normalizedCmd, SHELL_PATTERNS.write)) return 'write';
|
|
127
|
+
if (matchesAny(normalizedCmd, SHELL_PATTERNS.search)) return 'search';
|
|
128
|
+
if (matchesAny(normalizedCmd, SHELL_PATTERNS.read)) return 'read';
|
|
129
|
+
return 'other';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function detectShellCommandCategory(cmd) {
|
|
133
|
+
if (!cmd) return 'other';
|
|
134
|
+
const segments = splitCommandSegments(cmd);
|
|
135
|
+
if (segments.some((seg) => matchesAny(seg, SHELL_PATTERNS.write))) return 'write';
|
|
136
|
+
if (segments.some((seg) => matchesAny(seg, SHELL_PATTERNS.search))) return 'search';
|
|
137
|
+
if (segments.some((seg) => matchesAny(seg, SHELL_PATTERNS.read))) return 'read';
|
|
138
|
+
return 'other';
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function splitCommandSegments(cmd) {
|
|
142
|
+
return cmd
|
|
143
|
+
.split(/[\n;&]+/)
|
|
144
|
+
.map((segment) => segment.trim())
|
|
145
|
+
.filter(Boolean);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function matchesAny(text, patterns) {
|
|
149
|
+
const lower = text.toLowerCase();
|
|
150
|
+
return patterns.some((pattern) => lower.includes(pattern.toLowerCase()));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async function listCandidateFiles(dir) {
|
|
154
|
+
const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
155
|
+
const out = [];
|
|
156
|
+
for (const entry of entries) {
|
|
157
|
+
const full = path.join(dir, entry.name);
|
|
158
|
+
if (entry.isDirectory()) {
|
|
159
|
+
out.push(...(await listCandidateFiles(full)));
|
|
160
|
+
} else if (entry.isFile() && entry.name.endsWith(suffix)) {
|
|
161
|
+
out.push(full);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function extractRequestKey(filePath) {
|
|
168
|
+
const base = path.basename(filePath);
|
|
169
|
+
const match = base.match(/^(req_\d+_[^_]+)/);
|
|
170
|
+
return match ? match[1] : base;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function ensureSummary(summary, tool) {
|
|
174
|
+
if (!summary.has(tool)) {
|
|
175
|
+
summary.set(tool, {
|
|
176
|
+
total: 0,
|
|
177
|
+
categories: { read: 0, write: 0, search: 0, other: 0 },
|
|
178
|
+
samples: []
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return summary.get(tool);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function recordSample(summary, tool, category, command, filePath) {
|
|
185
|
+
const item = ensureSummary(summary, tool);
|
|
186
|
+
item.total += 1;
|
|
187
|
+
item.categories[category] += 1;
|
|
188
|
+
if (item.samples.length < 5) {
|
|
189
|
+
item.samples.push({ category, command, file: path.basename(filePath) });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async function main() {
|
|
194
|
+
const protocols = await fs.readdir(sampleRoot, { withFileTypes: true });
|
|
195
|
+
const files = [];
|
|
196
|
+
for (const proto of protocols) {
|
|
197
|
+
if (!proto.isDirectory()) continue;
|
|
198
|
+
const dir = path.join(sampleRoot, proto.name);
|
|
199
|
+
const protoFiles = await listCandidateFiles(dir);
|
|
200
|
+
files.push(...protoFiles);
|
|
201
|
+
}
|
|
202
|
+
files.sort((a, b) => a.localeCompare(b));
|
|
203
|
+
const summary = new Map();
|
|
204
|
+
const processedRequests = new Set();
|
|
205
|
+
for (const filePath of files) {
|
|
206
|
+
const reqKey = extractRequestKey(filePath);
|
|
207
|
+
if (processedRequests.has(reqKey)) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
processedRequests.add(reqKey);
|
|
211
|
+
let data;
|
|
212
|
+
try {
|
|
213
|
+
const raw = await fs.readFile(filePath, 'utf8');
|
|
214
|
+
data = JSON.parse(raw);
|
|
215
|
+
} catch {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const messages = Array.isArray(data?.messages) ? data.messages : [];
|
|
219
|
+
for (const msg of messages) {
|
|
220
|
+
if (!msg || msg.role !== 'assistant') continue;
|
|
221
|
+
if (!Array.isArray(msg.tool_calls)) continue;
|
|
222
|
+
for (const call of msg.tool_calls) {
|
|
223
|
+
const name = canonicalizeToolName(call?.function?.name || call?.name || '');
|
|
224
|
+
if (!name) continue;
|
|
225
|
+
let parsedArgs;
|
|
226
|
+
if (typeof call?.function?.arguments === 'string') {
|
|
227
|
+
try {
|
|
228
|
+
parsedArgs = JSON.parse(call.function.arguments);
|
|
229
|
+
} catch {
|
|
230
|
+
parsedArgs = undefined;
|
|
231
|
+
}
|
|
232
|
+
} else if (call?.function?.arguments && typeof call.function.arguments === 'object') {
|
|
233
|
+
parsedArgs = call.function.arguments;
|
|
234
|
+
}
|
|
235
|
+
const command = normalizeCommand(parsedArgs?.command || parsedArgs?.input || parsedArgs?.args || parsedArgs);
|
|
236
|
+
const category = detectCategory(name, command);
|
|
237
|
+
recordSample(summary, name, category, command, filePath);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const result = Array.from(summary.entries())
|
|
243
|
+
.map(([name, info]) => ({ name, ...info }))
|
|
244
|
+
.sort((a, b) => b.total - a.total);
|
|
245
|
+
|
|
246
|
+
console.log(JSON.stringify({ sampleRoot, toolCount: result.length, tools: result }, null, 2));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
main().catch((err) => {
|
|
250
|
+
console.error('Failed to classify tools:', err);
|
|
251
|
+
process.exit(1);
|
|
252
|
+
});
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
9
|
+
|
|
10
|
+
const rawMode = String(process.env.BUILD_MODE || process.env.RCC_BUILD_MODE || 'release').toLowerCase();
|
|
11
|
+
const mode = rawMode === 'dev' ? 'dev' : 'release';
|
|
12
|
+
|
|
13
|
+
const sharedCoreDir = path.join(PROJECT_ROOT, 'sharedmodule', 'llmswitch-core');
|
|
14
|
+
const nodeModulesScope = path.join(PROJECT_ROOT, 'node_modules', '@jsonstudio');
|
|
15
|
+
const llmsPath = path.join(nodeModulesScope, 'llms');
|
|
16
|
+
|
|
17
|
+
function runNodeScript(relativePath, args = []) {
|
|
18
|
+
const scriptPath = path.join(PROJECT_ROOT, relativePath);
|
|
19
|
+
const res = spawnSync(process.execPath, [scriptPath, ...args], { stdio: 'inherit' });
|
|
20
|
+
if ((res.status ?? 0) !== 0) {
|
|
21
|
+
process.exit(res.status ?? 2);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isSymlink(p) {
|
|
26
|
+
try {
|
|
27
|
+
return fs.lstatSync(p).isSymbolicLink();
|
|
28
|
+
} catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function readLink(p) {
|
|
34
|
+
try {
|
|
35
|
+
return fs.readlinkSync(p);
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function exists(p) {
|
|
42
|
+
try {
|
|
43
|
+
fs.accessSync(p);
|
|
44
|
+
return true;
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function ensureDevLink() {
|
|
51
|
+
if (!exists(sharedCoreDir)) {
|
|
52
|
+
console.error(`[llmswitch:ensure] BUILD_MODE=dev 但未找到 ${sharedCoreDir}`);
|
|
53
|
+
console.error('[llmswitch:ensure] 请先 clone sharedmodule/llmswitch-core,或改用 BUILD_MODE=release');
|
|
54
|
+
process.exit(2);
|
|
55
|
+
}
|
|
56
|
+
if (isSymlink(llmsPath)) {
|
|
57
|
+
const target = readLink(llmsPath);
|
|
58
|
+
if (target) {
|
|
59
|
+
const resolved = path.resolve(nodeModulesScope, target);
|
|
60
|
+
const expected = path.resolve(sharedCoreDir);
|
|
61
|
+
if (resolved === expected) {
|
|
62
|
+
console.log('[llmswitch:ensure] dev link ok: node_modules/@jsonstudio/llms -> sharedmodule/llmswitch-core');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
console.log('[llmswitch:ensure] linking dev core: node_modules/@jsonstudio/llms -> sharedmodule/llmswitch-core');
|
|
68
|
+
runNodeScript('scripts/link-llmswitch.mjs');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function ensureReleasePackage() {
|
|
72
|
+
if (isSymlink(llmsPath)) {
|
|
73
|
+
console.log('[llmswitch:ensure] release mode: unlinking node_modules/@jsonstudio/llms symlink');
|
|
74
|
+
runNodeScript('scripts/link-llmswitch.mjs', ['unlink']);
|
|
75
|
+
}
|
|
76
|
+
const pkgPath = path.join(llmsPath, 'package.json');
|
|
77
|
+
if (!exists(pkgPath)) {
|
|
78
|
+
console.log('[llmswitch:ensure] BUILD_MODE=release: installing @jsonstudio/llms via npm (missing in node_modules)');
|
|
79
|
+
const res = spawnSync('npm', ['install', '--no-audit', '--no-fund'], { cwd: PROJECT_ROOT, stdio: 'inherit' });
|
|
80
|
+
if ((res.status ?? 0) !== 0) {
|
|
81
|
+
process.exit(res.status ?? 2);
|
|
82
|
+
}
|
|
83
|
+
if (!exists(pkgPath)) {
|
|
84
|
+
console.error('[llmswitch:ensure] npm install completed but @jsonstudio/llms is still missing');
|
|
85
|
+
process.exit(2);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
console.log('[llmswitch:ensure] release package ok: using npm-installed @jsonstudio/llms');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (mode === 'dev') {
|
|
92
|
+
ensureDevLink();
|
|
93
|
+
} else {
|
|
94
|
+
ensureReleasePackage();
|
|
95
|
+
}
|
|
@@ -4,16 +4,32 @@ import path from 'node:path';
|
|
|
4
4
|
|
|
5
5
|
const cwd = process.cwd();
|
|
6
6
|
const pkgPath = path.join(cwd, 'package.json');
|
|
7
|
+
const lockPath = path.join(cwd, 'package-lock.json');
|
|
7
8
|
const outPath = path.join(cwd, 'src', 'build-info.ts');
|
|
8
9
|
|
|
9
10
|
const mode = String(process.env.BUILD_MODE || process.env.RCC_BUILD_MODE || 'release').toLowerCase();
|
|
10
11
|
const valid = new Set(['dev', 'release']);
|
|
11
12
|
const buildMode = valid.has(mode) ? mode : 'release';
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
const skipAutoBump = ['1', 'true', 'yes'].includes(
|
|
15
|
+
String(process.env.ROUTECODEX_SKIP_AUTO_BUMP || process.env.BUILD_SKIP_AUTO_BUMP || '').trim().toLowerCase()
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
const pkg = readJson(pkgPath);
|
|
19
|
+
let version = typeof pkg?.version === 'string' ? pkg.version : '0.0.0';
|
|
20
|
+
|
|
21
|
+
if (!skipAutoBump) {
|
|
22
|
+
const nextVersion = bumpPatchVersion(version);
|
|
23
|
+
if (nextVersion !== version) {
|
|
24
|
+
version = nextVersion;
|
|
25
|
+
if (pkg) {
|
|
26
|
+
pkg.version = nextVersion;
|
|
27
|
+
writeJson(pkgPath, pkg);
|
|
28
|
+
updatePackageLock(lockPath, nextVersion);
|
|
29
|
+
console.log(`[build-info] auto-bump version → ${nextVersion}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
17
33
|
|
|
18
34
|
const content = `// Auto-generated by scripts/gen-build-info.mjs
|
|
19
35
|
export interface BuildInfo { mode: 'dev' | 'release'; version: string; buildTime: string }
|
|
@@ -28,3 +44,41 @@ fs.mkdirSync(path.dirname(outPath), { recursive: true });
|
|
|
28
44
|
fs.writeFileSync(outPath, content, 'utf-8');
|
|
29
45
|
console.log(`[build-info] mode=${buildMode} version=${version} → ${outPath}`);
|
|
30
46
|
|
|
47
|
+
function readJson(targetPath) {
|
|
48
|
+
try {
|
|
49
|
+
return JSON.parse(fs.readFileSync(targetPath, 'utf-8'));
|
|
50
|
+
} catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function writeJson(targetPath, data) {
|
|
56
|
+
fs.writeFileSync(targetPath, `${JSON.stringify(data, null, 2)}\n`, 'utf-8');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function bumpPatchVersion(input) {
|
|
60
|
+
if (!input || typeof input !== 'string') {
|
|
61
|
+
return '0.0.001';
|
|
62
|
+
}
|
|
63
|
+
const segments = input.split('.');
|
|
64
|
+
while (segments.length < 3) {
|
|
65
|
+
segments.push('0');
|
|
66
|
+
}
|
|
67
|
+
const [major, minor, patchRaw] = segments;
|
|
68
|
+
const parsedPatch = Number.parseInt(patchRaw, 10);
|
|
69
|
+
const nextPatch = Number.isFinite(parsedPatch) ? parsedPatch + 1 : 1;
|
|
70
|
+
const formattedPatch = String(nextPatch).padStart(3, '0');
|
|
71
|
+
return `${major}.${minor}.${formattedPatch}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function updatePackageLock(targetPath, version) {
|
|
75
|
+
const lock = readJson(targetPath);
|
|
76
|
+
if (!lock) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
lock.version = version;
|
|
80
|
+
if (lock.packages && lock.packages['']) {
|
|
81
|
+
lock.packages[''].version = version;
|
|
82
|
+
}
|
|
83
|
+
writeJson(targetPath, lock);
|
|
84
|
+
}
|
|
@@ -82,7 +82,7 @@ build_project() {
|
|
|
82
82
|
# 构建项目
|
|
83
83
|
echo "🔨 编译TypeScript..."
|
|
84
84
|
# dev 包:显式使用 BUILD_MODE=dev 以便在编译期区分 dev/release
|
|
85
|
-
BUILD_MODE=dev timeout 300 npm run build || {
|
|
85
|
+
BUILD_MODE=dev ROUTECODEX_SKIP_AUTO_BUMP=1 timeout 300 npm run build || {
|
|
86
86
|
echo "❌ 构建超时或失败"
|
|
87
87
|
echo "💡 尝试手动构建:npm run build"
|
|
88
88
|
exit 1
|
|
@@ -18,6 +18,13 @@ echo "🔨 构建源码..."
|
|
|
18
18
|
# release 包:显式使用 BUILD_MODE=release 以便在编译期区分 dev/release
|
|
19
19
|
BUILD_MODE=release npm run build
|
|
20
20
|
|
|
21
|
+
# 构建过程可能自动 bump 版本号,因此需要重新读取
|
|
22
|
+
NEW_VERSION=$(node -p "require('./package.json').version" 2>/dev/null || echo "${VERSION}")
|
|
23
|
+
if [ "${NEW_VERSION}" != "${VERSION}" ]; then
|
|
24
|
+
echo "ℹ️ 构建后版本变更: ${VERSION} → ${NEW_VERSION}"
|
|
25
|
+
VERSION=${NEW_VERSION}
|
|
26
|
+
fi
|
|
27
|
+
|
|
21
28
|
TMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/rcc-release.XXXXXX")
|
|
22
29
|
TARBALL="routecodex-${VERSION}.tgz"
|
|
23
30
|
|
|
@@ -23,7 +23,7 @@ function resolveSamplesDir() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function parseEntryFilter() {
|
|
26
|
-
const raw = String(process.env.ROUTECODEX_MOCK_ENTRY_FILTER || 'openai-chat').trim();
|
|
26
|
+
const raw = String(process.env.ROUTECODEX_MOCK_ENTRY_FILTER || 'openai-chat,openai-responses').trim();
|
|
27
27
|
if (!raw || raw.toLowerCase() === 'all') {
|
|
28
28
|
return null;
|
|
29
29
|
}
|
|
@@ -57,15 +57,23 @@ async function loadRegistry() {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
async function loadSampleDocument(sample) {
|
|
60
|
+
async function loadSampleDocument(sample, options = {}) {
|
|
61
|
+
const fileName = options.fileName || 'request.json';
|
|
61
62
|
const sampleDir = path.join(MOCK_SAMPLES_DIR, sample.path);
|
|
62
|
-
const requestPath = path.join(sampleDir,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
const requestPath = path.join(sampleDir, fileName);
|
|
64
|
+
try {
|
|
65
|
+
const raw = await fs.readFile(requestPath, 'utf-8');
|
|
66
|
+
const doc = JSON.parse(raw);
|
|
67
|
+
if (!doc || typeof doc !== 'object' || !doc.body) {
|
|
68
|
+
throw new Error(`Sample ${sample.reqId} missing request body (${fileName})`);
|
|
69
|
+
}
|
|
70
|
+
return doc;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
if (options.optional) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
67
76
|
}
|
|
68
|
-
return doc;
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
function parseProviderKey(providerKey) {
|
|
@@ -103,7 +111,7 @@ function buildConfig(sample, port) {
|
|
|
103
111
|
type: 'mock-provider',
|
|
104
112
|
providerType: 'responses',
|
|
105
113
|
baseURL: `https://mock.local/${providerId}`,
|
|
106
|
-
|
|
114
|
+
compatibilityProfile: 'compat:passthrough',
|
|
107
115
|
providerId: sample.providerId,
|
|
108
116
|
auth: {
|
|
109
117
|
type: 'apikey',
|
|
@@ -154,7 +162,8 @@ function createServer(configPath, port) {
|
|
|
154
162
|
ROUTECODEX_PORT: String(port),
|
|
155
163
|
ROUTECODEX_CONFIG_PATH: configPath
|
|
156
164
|
};
|
|
157
|
-
const
|
|
165
|
+
const entry = path.join(PROJECT_ROOT, 'dist', 'index.js');
|
|
166
|
+
const child = spawn(process.execPath, [entry], {
|
|
158
167
|
cwd: PROJECT_ROOT,
|
|
159
168
|
env,
|
|
160
169
|
stdio: ['ignore', 'pipe', 'pipe']
|
|
@@ -255,10 +264,46 @@ function collectInvalidNames(payload) {
|
|
|
255
264
|
return failures;
|
|
256
265
|
}
|
|
257
266
|
|
|
267
|
+
function extractRequestBody(doc) {
|
|
268
|
+
const body = doc && typeof doc === 'object' ? doc.body : undefined;
|
|
269
|
+
if (!body || typeof body !== 'object') {
|
|
270
|
+
return {};
|
|
271
|
+
}
|
|
272
|
+
if (body.body && typeof body.body === 'object') {
|
|
273
|
+
return body.body;
|
|
274
|
+
}
|
|
275
|
+
if (body.payload && typeof body.payload === 'object') {
|
|
276
|
+
return body.payload;
|
|
277
|
+
}
|
|
278
|
+
return body;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function resolveRequestUrl(sample, requestDoc, port) {
|
|
282
|
+
const rawCandidate =
|
|
283
|
+
requestDoc.endpoint ||
|
|
284
|
+
(requestDoc.meta && typeof requestDoc.meta.entryEndpoint === 'string' ? requestDoc.meta.entryEndpoint : undefined) ||
|
|
285
|
+
requestDoc.url ||
|
|
286
|
+
sample.entry ||
|
|
287
|
+
'/v1/responses';
|
|
288
|
+
if (typeof rawCandidate === 'string' && /^https?:\/\//i.test(rawCandidate.trim())) {
|
|
289
|
+
return rawCandidate.trim();
|
|
290
|
+
}
|
|
291
|
+
const normalizedPath = typeof rawCandidate === 'string' && rawCandidate.trim().length
|
|
292
|
+
? rawCandidate.trim()
|
|
293
|
+
: '/v1/responses';
|
|
294
|
+
const pathWithSlash = normalizedPath.startsWith('/') ? normalizedPath : `/${normalizedPath}`;
|
|
295
|
+
return `http://127.0.0.1:${port}${pathWithSlash}`;
|
|
296
|
+
}
|
|
297
|
+
|
|
258
298
|
async function sendRequest(sample, requestDoc, port) {
|
|
259
|
-
const url =
|
|
299
|
+
const url = resolveRequestUrl(sample, requestDoc, port);
|
|
300
|
+
const payload = extractRequestBody(requestDoc);
|
|
260
301
|
const headers = { 'content-type': 'application/json' };
|
|
261
|
-
|
|
302
|
+
const wantsStream =
|
|
303
|
+
payload?.stream === true ||
|
|
304
|
+
(requestDoc.body && typeof requestDoc.body === 'object' && requestDoc.body.stream === true) ||
|
|
305
|
+
(requestDoc.meta && requestDoc.meta.stream === true);
|
|
306
|
+
if (wantsStream) {
|
|
262
307
|
headers.accept = 'text/event-stream';
|
|
263
308
|
}
|
|
264
309
|
const controller = new AbortController();
|
|
@@ -267,7 +312,7 @@ async function sendRequest(sample, requestDoc, port) {
|
|
|
267
312
|
const res = await fetch(url, {
|
|
268
313
|
method: 'POST',
|
|
269
314
|
headers,
|
|
270
|
-
body: JSON.stringify(
|
|
315
|
+
body: JSON.stringify(payload),
|
|
271
316
|
signal: controller.signal
|
|
272
317
|
});
|
|
273
318
|
const text = await res.text();
|
|
@@ -283,7 +328,8 @@ async function sendRequest(sample, requestDoc, port) {
|
|
|
283
328
|
}
|
|
284
329
|
|
|
285
330
|
async function runSample(sample, index) {
|
|
286
|
-
const
|
|
331
|
+
const clientDoc = await loadSampleDocument(sample, { fileName: 'client-request.json', optional: true });
|
|
332
|
+
const requestDoc = clientDoc || (await loadSampleDocument(sample));
|
|
287
333
|
const port = 5800 + index;
|
|
288
334
|
const { dir, file } = await writeTempConfig(sample, port);
|
|
289
335
|
const server = createServer(file, port);
|
package/scripts/pack-mode.mjs
CHANGED
|
@@ -14,14 +14,36 @@ function parseArgs(argv) {
|
|
|
14
14
|
return out;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
const projectRoot = process.cwd();
|
|
17
18
|
const args = parseArgs(process.argv);
|
|
18
19
|
if (!args.name || !args.bin) {
|
|
19
20
|
console.error('Usage: node scripts/pack-mode.mjs --name <packageName> --bin <binName>');
|
|
20
21
|
process.exit(1);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
const pkgPath = path.join(
|
|
24
|
+
const pkgPath = path.join(projectRoot, 'package.json');
|
|
24
25
|
const backupPath = pkgPath + '.bak.pack';
|
|
26
|
+
const ensureScriptPath = path.join(projectRoot, 'scripts', 'ensure-llmswitch-mode.mjs');
|
|
27
|
+
const llmsPath = path.join(projectRoot, 'node_modules', '@jsonstudio', 'llms');
|
|
28
|
+
|
|
29
|
+
function runEnsureMode(mode) {
|
|
30
|
+
const env = { ...process.env, BUILD_MODE: mode };
|
|
31
|
+
const res = spawnSync(process.execPath, [ensureScriptPath], { stdio: 'inherit', env });
|
|
32
|
+
if ((res.status ?? 0) !== 0) {
|
|
33
|
+
throw new Error(`ensure-llmswitch-mode failed for ${mode}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isSymlink(p) {
|
|
38
|
+
try {
|
|
39
|
+
return fs.lstatSync(p).isSymbolicLink();
|
|
40
|
+
} catch {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const hadDevLink = isSymlink(llmsPath);
|
|
46
|
+
runEnsureMode('release');
|
|
25
47
|
|
|
26
48
|
const original = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
27
49
|
fs.writeFileSync(backupPath, JSON.stringify(original, null, 2));
|
|
@@ -55,4 +77,11 @@ try {
|
|
|
55
77
|
// restore
|
|
56
78
|
fs.writeFileSync(pkgPath, fs.readFileSync(backupPath, 'utf-8'));
|
|
57
79
|
fs.unlinkSync(backupPath);
|
|
80
|
+
if (hadDevLink) {
|
|
81
|
+
try {
|
|
82
|
+
runEnsureMode('dev');
|
|
83
|
+
} catch (err) {
|
|
84
|
+
console.warn('[pack-mode] failed to restore dev llms link:', err);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
58
87
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { spawnSync } from 'node:child_process';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const PROJECT_ROOT = path.resolve(__dirname, '..');
|
|
9
|
+
const PACK_SCRIPT = path.join(PROJECT_ROOT, 'scripts', 'pack-mode.mjs');
|
|
10
|
+
const packageJson = JSON.parse(fs.readFileSync(path.join(PROJECT_ROOT, 'package.json'), 'utf-8'));
|
|
11
|
+
const version = packageJson.version;
|
|
12
|
+
const tarballName = `jsonstudio-rcc-${version}.tgz`;
|
|
13
|
+
const tarballPath = path.join(PROJECT_ROOT, tarballName);
|
|
14
|
+
|
|
15
|
+
function run(command, args, options = {}) {
|
|
16
|
+
const res = spawnSync(command, args, { stdio: 'inherit', ...options });
|
|
17
|
+
if ((res.status ?? 0) !== 0) {
|
|
18
|
+
throw new Error(`${command} ${args.join(' ')} failed`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
run(process.execPath, [PACK_SCRIPT, '--name', '@jsonstudio/rcc', '--bin', 'rcc'], { cwd: PROJECT_ROOT });
|
|
24
|
+
if (!fs.existsSync(tarballPath)) {
|
|
25
|
+
throw new Error(`tarball not found: ${tarballPath}`);
|
|
26
|
+
}
|
|
27
|
+
run('npm', ['publish', tarballName], { cwd: PROJECT_ROOT });
|
|
28
|
+
} catch (err) {
|
|
29
|
+
console.error('[publish-rcc] failed:', err.message);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|