@jsonstudio/rcc 0.90.323 → 0.90.352
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 +16 -16
- package/dist/build-info.js +2 -2
- package/dist/cli/commands/camoufox.js +2 -2
- package/dist/cli/commands/camoufox.js.map +1 -1
- package/dist/cli/commands/clean.js +4 -3
- package/dist/cli/commands/clean.js.map +1 -1
- package/dist/cli/commands/config.js +2 -1
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/env.js +2 -1
- package/dist/cli/commands/env.js.map +1 -1
- package/dist/cli/commands/init/basic.js +2 -1
- package/dist/cli/commands/init/basic.js.map +1 -1
- package/dist/cli/commands/init.js +4 -3
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/launcher-kernel.js +23 -13
- package/dist/cli/commands/launcher-kernel.js.map +1 -1
- package/dist/cli/commands/port.js +1 -1
- package/dist/cli/commands/port.js.map +1 -1
- package/dist/cli/commands/restart.js +3 -2
- package/dist/cli/commands/restart.js.map +1 -1
- package/dist/cli/commands/start.js +4 -3
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/stop.js +3 -2
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/config/bundled-docs.js +2 -6
- package/dist/cli/config/bundled-docs.js.map +1 -1
- package/dist/cli/config/init-config.d.ts +1 -0
- package/dist/cli/config/init-config.js +6 -3
- package/dist/cli/config/init-config.js.map +1 -1
- package/dist/cli/config/init-provider-catalog.js +4 -4
- package/dist/cli/config/init-provider-catalog.js.map +1 -1
- package/dist/cli/config/precommand-default-script.js +3 -9
- package/dist/cli/config/precommand-default-script.js.map +1 -1
- package/dist/cli/guardian/paths.js +2 -3
- package/dist/cli/guardian/paths.js.map +1 -1
- package/dist/cli.js +10 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/camoufox-fp.js +2 -3
- package/dist/commands/camoufox-fp.js.map +1 -1
- package/dist/commands/migrate-user-config.d.ts +6 -0
- package/dist/commands/migrate-user-config.js +53 -0
- package/dist/commands/migrate-user-config.js.map +1 -0
- package/dist/commands/provider-update.js +9 -9
- package/dist/commands/provider-update.js.map +1 -1
- package/dist/commands/quota-daemon.js +3 -3
- package/dist/commands/quota-daemon.js.map +1 -1
- package/dist/commands/quota-status.js +2 -2
- package/dist/commands/quota-status.js.map +1 -1
- package/dist/commands/token-daemon.js +2 -2
- package/dist/commands/token-daemon.js.map +1 -1
- package/dist/commands/validate.js +2 -3
- package/dist/commands/validate.js.map +1 -1
- package/dist/config/auth-file-resolver.js +2 -2
- package/dist/config/auth-file-resolver.js.map +1 -1
- package/dist/config/provider-v2-loader.js +9 -6
- package/dist/config/provider-v2-loader.js.map +1 -1
- package/dist/config/routecodex-config-loader.js +2 -2
- package/dist/config/routecodex-config-loader.js.map +1 -1
- package/dist/config/unified-config-paths.js +11 -9
- package/dist/config/unified-config-paths.js.map +1 -1
- package/dist/config/user-config-migration.d.ts +42 -0
- package/dist/config/user-config-migration.js +188 -0
- package/dist/config/user-config-migration.js.map +1 -0
- package/dist/config/user-data-paths.d.ts +59 -0
- package/dist/config/user-data-paths.js +174 -0
- package/dist/config/user-data-paths.js.map +1 -0
- package/dist/config/virtual-router-builder.d.ts +1 -1
- package/dist/config/virtual-router-builder.js +1 -1
- package/dist/docs/daemon-admin-ui.html +9 -9
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/manager/modules/health/index.js +2 -2
- package/dist/manager/modules/health/index.js.map +1 -1
- package/dist/manager/modules/quota/antigravity-quota-persistence.d.ts +2 -1
- package/dist/manager/modules/quota/antigravity-quota-persistence.js +11 -22
- package/dist/manager/modules/quota/antigravity-quota-persistence.js.map +1 -1
- package/dist/manager/quota/provider-quota-store.js +11 -4
- package/dist/manager/quota/provider-quota-store.js.map +1 -1
- package/dist/modules/config/pipeline-config-path.js +3 -3
- package/dist/modules/config/pipeline-config-path.js.map +1 -1
- package/dist/providers/auth/antigravity-fingerprint.js +2 -3
- package/dist/providers/auth/antigravity-fingerprint.js.map +1 -1
- package/dist/providers/auth/antigravity-reauth-state.js +2 -3
- package/dist/providers/auth/antigravity-reauth-state.js.map +1 -1
- package/dist/providers/auth/antigravity-user-agent.js +2 -2
- package/dist/providers/auth/antigravity-user-agent.js.map +1 -1
- package/dist/providers/auth/antigravity-warmup.js +2 -3
- package/dist/providers/auth/antigravity-warmup.js.map +1 -1
- package/dist/providers/auth/deepseek-account-auth.js +4 -3
- package/dist/providers/auth/deepseek-account-auth.js.map +1 -1
- package/dist/providers/auth/deepseek-account-token-acquirer.js +3 -2
- package/dist/providers/auth/deepseek-account-token-acquirer.js.map +1 -1
- package/dist/providers/auth/oauth-auth.js +2 -3
- package/dist/providers/auth/oauth-auth.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle/path-resolver.js +6 -7
- package/dist/providers/auth/oauth-lifecycle/path-resolver.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle.js +4 -4
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/auth/oauth-repair-cooldown.js +2 -3
- package/dist/providers/auth/oauth-repair-cooldown.js.map +1 -1
- package/dist/providers/auth/token-scanner/index.js +2 -3
- package/dist/providers/auth/token-scanner/index.js.map +1 -1
- package/dist/providers/auth/token-storage/token-file-resolver.js +8 -7
- package/dist/providers/auth/token-storage/token-file-resolver.js.map +1 -1
- package/dist/providers/auth/tokenfile-auth.js +5 -6
- package/dist/providers/auth/tokenfile-auth.js.map +1 -1
- package/dist/providers/core/config/camoufox-launcher.js +3 -4
- package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
- package/dist/providers/core/config/provider-oauth-configs.js +2 -2
- package/dist/providers/core/config/provider-oauth-configs.js.map +1 -1
- package/dist/providers/core/hooks/hooks-integration.js +1 -1
- package/dist/providers/core/hooks/hooks-integration.js.map +1 -1
- package/dist/providers/core/runtime/deepseek-http-provider.js +2 -1
- package/dist/providers/core/runtime/deepseek-http-provider.js.map +1 -1
- package/dist/providers/core/utils/snapshot-writer.js +2 -1
- package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
- package/dist/server/handlers/config-admin-handler.d.ts +1 -1
- package/dist/server/handlers/config-admin-handler.js +6 -6
- package/dist/server/handlers/config-admin-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/auth-store.js +2 -2
- package/dist/server/runtime/http-server/daemon-admin/auth-store.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/control-handler.js +3 -3
- package/dist/server/runtime/http-server/daemon-admin/control-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +2 -2
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-routing-utils.js +5 -4
- package/dist/server/runtime/http-server/daemon-admin/providers-handler-routing-utils.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js +3 -3
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
- package/dist/server/runtime/http-server/http-server-bootstrap.js +2 -3
- package/dist/server/runtime/http-server/http-server-bootstrap.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.js +0 -49
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.js +1 -1
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/servertool-admin-state.js +2 -2
- package/dist/server/runtime/http-server/servertool-admin-state.js.map +1 -1
- package/dist/server/runtime/http-server/session-dir.js +6 -12
- package/dist/server/runtime/http-server/session-dir.js.map +1 -1
- package/dist/server/runtime/http-server/stats-manager.js +2 -1
- package/dist/server/runtime/http-server/stats-manager.js.map +1 -1
- package/dist/server/utils/non-blocking-error-logger.js +2 -1
- package/dist/server/utils/non-blocking-error-logger.js.map +1 -1
- package/dist/token-daemon/history-store.js +2 -1
- package/dist/token-daemon/history-store.js.map +1 -1
- package/dist/token-daemon/leader-lock.js +2 -2
- package/dist/token-daemon/leader-lock.js.map +1 -1
- package/dist/token-daemon/quota-auth-issue.js +2 -4
- package/dist/token-daemon/quota-auth-issue.js.map +1 -1
- package/dist/token-daemon/server-utils.js +3 -4
- package/dist/token-daemon/server-utils.js.map +1 -1
- package/dist/token-daemon/token-daemon.js +6 -6
- package/dist/token-daemon/token-daemon.js.map +1 -1
- package/dist/token-daemon/token-utils.js +2 -1
- package/dist/token-daemon/token-utils.js.map +1 -1
- package/dist/token-portal/fingerprint-summary.js +2 -3
- package/dist/token-portal/fingerprint-summary.js.map +1 -1
- package/dist/token-portal/local-token-portal.js +1 -1
- package/dist/token-portal/local-token-portal.js.map +1 -1
- package/dist/utils/daemon-stop-intent.js +2 -2
- package/dist/utils/daemon-stop-intent.js.map +1 -1
- package/dist/utils/errorsamples.js +3 -1
- package/dist/utils/errorsamples.js.map +1 -1
- package/dist/utils/llms-engine-shadow.js +2 -2
- package/dist/utils/llms-engine-shadow.js.map +1 -1
- package/dist/utils/managed-server-pids.js +2 -2
- package/dist/utils/managed-server-pids.js.map +1 -1
- package/dist/utils/process-lifecycle-logger.js +2 -1
- package/dist/utils/process-lifecycle-logger.js.map +1 -1
- package/dist/utils/runtime-exit-forensics.js +2 -2
- package/dist/utils/runtime-exit-forensics.js.map +1 -1
- package/dist/utils/snapshot-writer.js +2 -1
- package/dist/utils/snapshot-writer.js.map +1 -1
- package/docs/CODEX_AND_CLAUDE_CODE.md +1 -1
- package/docs/CONFIG_ARCHITECTURE.md +7 -7
- package/docs/DAEMON_CONTROL_PLANE.md +2 -2
- package/docs/INSTALLATION_AND_QUICKSTART.md +2 -2
- package/docs/INSTRUCTION_MARKUP.md +2 -2
- package/docs/OAUTH.md +6 -6
- package/docs/PORTS.md +1 -1
- package/docs/PROVIDERS_BUILTIN.md +2 -2
- package/docs/QUOTA_MANAGER_V3.md +2 -2
- package/docs/ROUTING_POLICY_SCHEMA.md +1 -1
- package/docs/SERVERTOOL_CLOCK_DESIGN.md +1 -1
- package/docs/SERVERTOOL_PRE_COMMAND_HOOKS.md +4 -4
- package/docs/anthropic-request-golden-samples.md +4 -4
- package/docs/chat-glm-500-analysis.md +2 -2
- package/docs/chat-request-golden-samples.md +4 -4
- package/docs/codex-samples-replay.md +3 -3
- package/docs/daemon-admin-api-design.md +2 -2
- package/docs/daemon-admin-ui.html +9 -9
- package/docs/design/servertool-stopmessage-lifecycle.md +5 -0
- package/docs/golden-ci-library.md +8 -8
- package/docs/monitoring/Design.md +2 -2
- package/docs/multi-token-auth-guide.md +6 -6
- package/docs/oauth-authentication-guide.md +1 -1
- package/docs/oauth-iflow-implementation.md +2 -2
- package/docs/pipeline-routing-report.md +1 -1
- package/docs/plans/manager-daemon/PLAN.md +1 -1
- package/docs/plans/provider-config-v2-plan.md +8 -8
- package/docs/plans/provider-runtime-manager-plan.md +4 -4
- package/docs/provider-analysis.md +5 -5
- package/docs/provider-quota-design.md +2 -2
- package/docs/providers/antigravity-fingerprint-ua-warmup.md +5 -5
- package/docs/providers/antigravity-gemini-provider-compat.md +3 -3
- package/docs/providers/deepseek-web-provider-design.md +1 -1
- package/docs/providers/gemini-provider.md +1 -1
- package/docs/providers/provider-composite-testing.md +2 -2
- package/docs/providers/tabglm-claude-code-compat.md +1 -1
- package/docs/replay-evidence-iflow-400.txt +3 -3
- package/docs/reports/routing-classification-report.json +6 -6
- package/docs/reports/routing-classification-report.md +6 -6
- package/docs/reports/thinking-keywords-report.json +6 -6
- package/docs/responses/README.md +5 -5
- package/docs/responses-generic-provider.md +1 -1
- package/docs/responses-passthrough-provider-design.md +7 -7
- package/docs/routing-instructions.md +1 -1
- package/docs/token-daemon-preview.html +3 -3
- package/docs/token-refresh-daemon-plan.md +7 -7
- package/docs/verification/modelscope-verify.md +2 -2
- package/docs/verified-configs/README.md +2 -2
- package/docs/verified-configs/v0.45.0/README.md +5 -5
- package/docs/verified-configs/v0.45.0/merged-config.5521.json +3 -3
- package/docs/verified-configs/v0.45.0/merged-config.qwen-5522.json +3 -3
- package/package.json +2 -2
- package/scripts/anthropic-four-config-e2e.mjs +5 -5
- package/scripts/anthropic-toolcall.mjs +1 -1
- package/scripts/batch-toolcall-report.mjs +1 -1
- package/scripts/claude-e2e-listdir-all.sh +1 -1
- package/scripts/claude-e2e-listdir-per-config.sh +4 -4
- package/scripts/clean-safe.mjs +1 -1
- package/scripts/cleanup-beads-oversized-notes.mjs +182 -0
- package/scripts/config-core-compare.ts +1 -1
- package/scripts/glm1210-curl-test.sh +1 -1
- package/scripts/install-release.sh +1 -1
- package/scripts/mock-provider/capture-from-configs.mjs +1 -1
- package/scripts/outbound-network-toolcall.mjs +2 -2
- package/scripts/outbound-regression-codex-samples.mjs +1 -1
- package/scripts/provider-v2-smoke.mjs +3 -3
- package/scripts/replay-recorded-toolcall.mjs +1 -2
- package/scripts/responses-fai-capture.mjs +1 -1
- package/scripts/responses-sse-capture.mjs +1 -1
- package/scripts/responses-sse-proxy.mjs +1 -1
- package/scripts/responses-sse-replay-golden.mjs +252 -111
- package/scripts/run-bg.sh +1 -1
- package/scripts/run-fg-gtimeout.sh +1 -1
- package/scripts/tests/antigravity-codex-sample-pipeline-compare.mjs +1 -1
- package/scripts/tests/antigravity-gemini-dryrun-compare.mjs +1 -1
- package/scripts/tests/responses-provider-dry-run.mjs +1 -1
- package/scripts/tests/virtual-router-health.mjs +1 -1
- package/scripts/update-models.mjs +2 -2
- package/scripts/v2-simple-monitor.mjs +1 -1
- package/scripts/verify-e2e-gemini-followup-sample.mjs +1 -1
- package/scripts/verify-e2e-toolcall.mjs +2 -2
- package/scripts/verify-health.mjs +2 -2
- package/scripts/verify-sse-loop.mjs +1 -1
- package/scripts/virtual-router-dryrun.mjs +2 -2
- package/scripts/virtual-router-shadow-v2-real.mjs +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// One-click outbound network toolcall tests against openai-compatible providers.
|
|
3
|
-
// Reads provider configs under ~/.
|
|
3
|
+
// Reads provider configs under ~/.rcc/provider/*/config*.json
|
|
4
4
|
// Sends a function-calling prompt and reports whether a functionCall/tool_calls is returned.
|
|
5
5
|
|
|
6
6
|
import fs from 'fs';
|
|
@@ -8,7 +8,7 @@ import path from 'path';
|
|
|
8
8
|
import os from 'os';
|
|
9
9
|
import { ProviderFactory } from '../dist/providers/core/runtime/provider-factory.js';
|
|
10
10
|
|
|
11
|
-
const root = path.join(os.homedir(), '.
|
|
11
|
+
const root = path.join(os.homedir(), '.rcc', 'provider');
|
|
12
12
|
const MAX_PROVIDERS = parseInt(process.env.RCC_NET_MAX_PROVIDERS || '5', 10);
|
|
13
13
|
// Per-provider rate limit: default 3 req/min (can override by RCC_NET_RATE_MAX_PER_MINUTE)
|
|
14
14
|
const RATE_MAX_PER_MIN = parseInt(process.env.RCC_NET_RATE_MAX_PER_MINUTE || '3', 10);
|
|
@@ -12,7 +12,7 @@ import { ProviderFactory } from '../dist/providers/core/runtime/provider-factory
|
|
|
12
12
|
const CODEx_DIR = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-chat');
|
|
13
13
|
const RESPONSES_SAMPLE_DIR = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses');
|
|
14
14
|
const TARGET_TOOL_NAME = (process.env.RCC_REG_TOOL_NAME || 'add').toLowerCase();
|
|
15
|
-
const PROVIDER_DIR = path.join(os.homedir(), '.
|
|
15
|
+
const PROVIDER_DIR = path.join(os.homedir(), '.rcc', 'provider');
|
|
16
16
|
const MAX_PER_PROVIDER_PER_MIN = parseInt(process.env.RCC_NET_RATE_MAX_PER_MINUTE || '3', 10);
|
|
17
17
|
const RATE_DISABLED = (process.env.RCC_NET_RATE_DISABLED || '0') === '1';
|
|
18
18
|
const TARGET_PROTOCOLS = new Set(
|
|
@@ -6,10 +6,10 @@ import path from 'path';
|
|
|
6
6
|
|
|
7
7
|
function readJson(p){ try { return JSON.parse(fs.readFileSync(p,'utf-8')); } catch { return null; } }
|
|
8
8
|
function loadUserConfig(){
|
|
9
|
-
const explicit = process.env.ROUTECODEX_CONFIG_PATH;
|
|
9
|
+
const explicit = process.env.ROUTECODEX_CONFIG_PATH || process.env.RCC_CONFIG_PATH || process.env.ROUTECODEX_CONFIG || process.env.RCC_CONFIG;
|
|
10
10
|
const candidate = explicit && explicit.trim()
|
|
11
11
|
? path.resolve(explicit.trim())
|
|
12
|
-
: path.join(os.homedir(), '.
|
|
12
|
+
: path.join(os.homedir(), '.rcc', 'config.json');
|
|
13
13
|
return readJson(candidate);
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@ const providers = cfg?.virtualrouter?.providers || {};
|
|
|
18
18
|
const entries = Object.entries(providers);
|
|
19
19
|
const glmEntry = entries.find(([id]) => id.includes('glm')) || entries[0];
|
|
20
20
|
if (!glmEntry) {
|
|
21
|
-
console.error('no provider definition found in ~/.
|
|
21
|
+
console.error('no provider definition found in ~/.rcc/config.json');
|
|
22
22
|
process.exit(2);
|
|
23
23
|
}
|
|
24
24
|
const [providerId, providerConfig] = glmEntry;
|
|
@@ -41,7 +41,7 @@ async function sleep(ms) { await new Promise(r => setTimeout(r, ms)); }
|
|
|
41
41
|
async function getPortFromConfig() {
|
|
42
42
|
try {
|
|
43
43
|
const envPath = process.env.ROUTECODEX_CONFIG_PATH || process.env.ROUTECODEX_CONFIG || '';
|
|
44
|
-
const candidate = envPath || path.join(os.homedir(), '.
|
|
44
|
+
const candidate = envPath || path.join(os.homedir(), '.rcc', 'config.json');
|
|
45
45
|
if (fsSync.existsSync(candidate)) {
|
|
46
46
|
const cfg = await readJson(candidate);
|
|
47
47
|
const p = (cfg && cfg.httpserver && typeof cfg.httpserver.port === 'number') ? cfg.httpserver.port : cfg.port;
|
|
@@ -227,4 +227,3 @@ async function main() {
|
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
main().catch(err => { console.error(err); process.exit(1); });
|
|
230
|
-
|
|
@@ -7,7 +7,7 @@ import path from 'path';
|
|
|
7
7
|
import { pathToFileURL } from 'url';
|
|
8
8
|
|
|
9
9
|
const PROVIDER_ID = process.env.RCC_RESP_PROV || 'fai';
|
|
10
|
-
const PROVIDER_DIR = path.join(os.homedir(), '.
|
|
10
|
+
const PROVIDER_DIR = path.join(os.homedir(), '.rcc', 'provider');
|
|
11
11
|
const OUT_DIR = path.join(os.homedir(), '.routecodex', 'golden_samples', 'provider_golden_samples', 'responses', PROVIDER_ID);
|
|
12
12
|
|
|
13
13
|
function ensureDir(p) { fs.mkdirSync(p, { recursive: true }); }
|
|
@@ -10,7 +10,7 @@ import OpenAI from 'openai';
|
|
|
10
10
|
const BASEDIR = process.cwd();
|
|
11
11
|
const CODEx_DIR = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-chat');
|
|
12
12
|
const RESP_SAMPLE_DIR = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses');
|
|
13
|
-
const PROVIDER_DIR = path.join(os.homedir(), '.
|
|
13
|
+
const PROVIDER_DIR = path.join(os.homedir(), '.rcc', 'provider');
|
|
14
14
|
const OUT_DIR = path.join(os.homedir(), '.routecodex', 'logs', 'responses-sse');
|
|
15
15
|
|
|
16
16
|
function ensureDir(p) { fs.mkdirSync(p, { recursive: true }); }
|
|
@@ -17,7 +17,7 @@ const replayLog = process.env.RCC_RESP_REPLAY_LOG || getArg('--replay');
|
|
|
17
17
|
const port = Number(getArg('--port') || DEFAULT_PORT);
|
|
18
18
|
const host = getArg('--host') || DEFAULT_HOST;
|
|
19
19
|
|
|
20
|
-
const PROVIDER_ROOT = path.join(os.homedir(), '.
|
|
20
|
+
const PROVIDER_ROOT = path.join(os.homedir(), '.rcc', 'provider');
|
|
21
21
|
const CAPTURE_ROOT = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses', 'sse-proxy');
|
|
22
22
|
|
|
23
23
|
function getArg(flag) {
|
|
@@ -1,138 +1,279 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// Server-side replay for codex-samples /v1/responses requests.
|
|
3
|
+
// This script intentionally replays through RouteCodex HTTP server instead of calling provider URLs directly.
|
|
4
|
+
//
|
|
5
5
|
// Env:
|
|
6
|
-
//
|
|
7
|
-
//
|
|
6
|
+
// RCC_REPLAY_BASE server base URL (default http://127.0.0.1:5555)
|
|
7
|
+
// RCC_REPLAY_KEY x-routecodex-api-key (default routecodex-test)
|
|
8
|
+
// RCC_RESP_PROVIDER provider directory filter (optional)
|
|
9
|
+
// RCC_RESP_PICK request-id/path substring filter (optional)
|
|
10
|
+
// RCC_RESP_REQ exact request directory name, e.g. req_1773310208018_9b3ec605 (optional)
|
|
11
|
+
//
|
|
12
|
+
// Output:
|
|
13
|
+
// ~/.routecodex/logs/responses-sse/server-replay_<timestamp>.{request,response,sse,json,chat}.*
|
|
8
14
|
|
|
9
|
-
import fs from 'fs';
|
|
10
|
-
import os from 'os';
|
|
11
|
-
import path from 'path';
|
|
12
|
-
import { pathToFileURL } from 'url';
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
import os from 'node:os';
|
|
17
|
+
import path from 'node:path';
|
|
18
|
+
import { pathToFileURL } from 'node:url';
|
|
13
19
|
|
|
14
|
-
const
|
|
15
|
-
const
|
|
20
|
+
const DEFAULT_BASE = process.env.RCC_REPLAY_BASE || 'http://127.0.0.1:5555';
|
|
21
|
+
const DEFAULT_KEY =
|
|
22
|
+
process.env.RCC_REPLAY_KEY ||
|
|
23
|
+
process.env.ROUTECODEX_HTTP_APIKEY ||
|
|
24
|
+
process.env.ROUTECODEX_API_KEY ||
|
|
25
|
+
'routecodex-test';
|
|
26
|
+
const FILTER_PROVIDER = (process.env.RCC_RESP_PROVIDER || '').trim();
|
|
27
|
+
const FILTER_PICK = (process.env.RCC_RESP_PICK || '').trim();
|
|
28
|
+
const FILTER_REQ = (process.env.RCC_RESP_REQ || '').trim();
|
|
29
|
+
const SAMPLES_ROOT = path.join(os.homedir(), '.routecodex', 'codex-samples', 'openai-responses');
|
|
16
30
|
const OUT_DIR = path.join(os.homedir(), '.routecodex', 'logs', 'responses-sse');
|
|
17
31
|
|
|
18
|
-
function
|
|
19
|
-
|
|
32
|
+
function nowStamp() {
|
|
33
|
+
return new Date().toISOString().replace(/[:.]/g, '-');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function ensureDir(p) {
|
|
37
|
+
fs.mkdirSync(p, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function readJson(p) {
|
|
41
|
+
return JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function healthCheck(baseUrl) {
|
|
45
|
+
try {
|
|
46
|
+
const res = await fetch(`${baseUrl.replace(/\/$/, '')}/health`, { method: 'GET' });
|
|
47
|
+
return res.ok;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
20
52
|
|
|
21
|
-
function
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
53
|
+
function findClientRequestFiles(root) {
|
|
54
|
+
const result = [];
|
|
55
|
+
if (!fs.existsSync(root)) {
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
const providerDirs = fs.readdirSync(root, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
59
|
+
for (const providerDir of providerDirs) {
|
|
60
|
+
if (FILTER_PROVIDER && !providerDir.name.includes(FILTER_PROVIDER)) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const providerPath = path.join(root, providerDir.name);
|
|
64
|
+
const reqDirs = fs.readdirSync(providerPath, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
65
|
+
for (const reqDir of reqDirs) {
|
|
66
|
+
if (FILTER_REQ && reqDir.name !== FILTER_REQ) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (FILTER_PICK && !reqDir.name.includes(FILTER_PICK) && !providerDir.name.includes(FILTER_PICK)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
const clientReq = path.join(providerPath, reqDir.name, 'client-request.json');
|
|
73
|
+
if (!fs.existsSync(clientReq)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const stat = fs.statSync(clientReq);
|
|
77
|
+
result.push({
|
|
78
|
+
provider: providerDir.name,
|
|
79
|
+
requestId: reqDir.name,
|
|
80
|
+
file: clientReq,
|
|
81
|
+
mtimeMs: stat.mtimeMs
|
|
82
|
+
});
|
|
28
83
|
}
|
|
29
84
|
}
|
|
30
|
-
|
|
85
|
+
result.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
86
|
+
return result;
|
|
31
87
|
}
|
|
32
88
|
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
89
|
+
function extractRequestBody(doc) {
|
|
90
|
+
if (doc && typeof doc === 'object') {
|
|
91
|
+
if (doc.body && typeof doc.body === 'object' && !Array.isArray(doc.body)) {
|
|
92
|
+
if (doc.body.body && typeof doc.body.body === 'object' && !Array.isArray(doc.body.body)) {
|
|
93
|
+
return doc.body.body;
|
|
94
|
+
}
|
|
95
|
+
return doc.body;
|
|
96
|
+
}
|
|
97
|
+
if (doc.data && typeof doc.data === 'object' && !Array.isArray(doc.data)) {
|
|
98
|
+
const data = doc.data;
|
|
99
|
+
if (data.body && typeof data.body === 'object' && !Array.isArray(data.body)) {
|
|
100
|
+
if (data.body.body && typeof data.body.body === 'object' && !Array.isArray(data.body.body)) {
|
|
101
|
+
return data.body.body;
|
|
102
|
+
}
|
|
103
|
+
return data.body;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
44
108
|
}
|
|
45
109
|
|
|
46
|
-
function
|
|
47
|
-
|
|
48
|
-
|
|
110
|
+
function extractEntryEndpoint(doc) {
|
|
111
|
+
const endpoint = doc?.meta?.entryEndpoint;
|
|
112
|
+
if (typeof endpoint === 'string' && endpoint.trim().length) {
|
|
113
|
+
return endpoint.trim();
|
|
114
|
+
}
|
|
115
|
+
return '/v1/responses';
|
|
49
116
|
}
|
|
50
117
|
|
|
51
|
-
function
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
});
|
|
71
|
-
|
|
118
|
+
function extractStreamFlag(doc, body) {
|
|
119
|
+
if (typeof body?.stream === 'boolean') {
|
|
120
|
+
return body.stream;
|
|
121
|
+
}
|
|
122
|
+
if (typeof doc?.meta?.stream === 'boolean') {
|
|
123
|
+
return doc.meta.stream;
|
|
124
|
+
}
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
async function readSseFrames(stream) {
|
|
129
|
+
const reader = stream?.getReader?.();
|
|
130
|
+
if (!reader) {
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
133
|
+
const decoder = new TextDecoder();
|
|
134
|
+
let buffer = '';
|
|
135
|
+
const frames = [];
|
|
136
|
+
while (true) {
|
|
137
|
+
const { value, done } = await reader.read();
|
|
138
|
+
if (done) {
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
buffer += decoder.decode(value, { stream: true });
|
|
142
|
+
let idx = buffer.indexOf('\n\n');
|
|
143
|
+
while (idx >= 0) {
|
|
144
|
+
const frame = buffer.slice(0, idx).trim();
|
|
145
|
+
buffer = buffer.slice(idx + 2);
|
|
146
|
+
if (frame.length) {
|
|
147
|
+
frames.push(frame);
|
|
148
|
+
}
|
|
149
|
+
idx = buffer.indexOf('\n\n');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
buffer += decoder.decode(new Uint8Array(), { stream: false });
|
|
153
|
+
if (buffer.trim().length) {
|
|
154
|
+
frames.push(buffer.trim());
|
|
155
|
+
}
|
|
156
|
+
return frames;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function convertSseFramesToJson(frames, requestId, model) {
|
|
160
|
+
try {
|
|
161
|
+
const convPath = pathToFileURL(path.join(process.cwd(), 'sharedmodule/llmswitch-core/dist/sse/sse-to-json/index.js')).href;
|
|
162
|
+
const bridgePath = pathToFileURL(path.join(process.cwd(), 'sharedmodule/llmswitch-core/dist/conversion/responses/responses-openai-bridge.js')).href;
|
|
163
|
+
const { ResponsesSseToJsonConverter } = await import(convPath);
|
|
164
|
+
const { buildChatResponseFromResponses } = await import(bridgePath);
|
|
165
|
+
const converter = new ResponsesSseToJsonConverter();
|
|
166
|
+
async function* toChunks() {
|
|
167
|
+
for (const frame of frames) {
|
|
168
|
+
yield `${frame}\n\n`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const json = await converter.convertSseToJson(toChunks(), {
|
|
172
|
+
requestId,
|
|
173
|
+
model: typeof model === 'string' && model.length ? model : 'unknown'
|
|
174
|
+
});
|
|
175
|
+
const chat = buildChatResponseFromResponses(json);
|
|
176
|
+
return { json, chat };
|
|
177
|
+
} catch {
|
|
178
|
+
return { json: null, chat: null };
|
|
179
|
+
}
|
|
72
180
|
}
|
|
73
181
|
|
|
74
182
|
async function main() {
|
|
75
|
-
const
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
if (!
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
const
|
|
183
|
+
const baseUrl = DEFAULT_BASE.replace(/\/$/, '');
|
|
184
|
+
const healthy = await healthCheck(baseUrl);
|
|
185
|
+
if (!healthy) {
|
|
186
|
+
throw new Error(`routecodex server not healthy: ${baseUrl}/health`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const candidates = findClientRequestFiles(SAMPLES_ROOT);
|
|
190
|
+
if (!candidates.length) {
|
|
191
|
+
throw new Error(`no client-request samples found under ${SAMPLES_ROOT}`);
|
|
192
|
+
}
|
|
193
|
+
const picked = candidates[0];
|
|
194
|
+
const sample = readJson(picked.file);
|
|
195
|
+
const body = extractRequestBody(sample);
|
|
196
|
+
if (!body || typeof body !== 'object' || Array.isArray(body)) {
|
|
197
|
+
throw new Error(`invalid sample request body: ${picked.file}`);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const endpoint = extractEntryEndpoint(sample);
|
|
201
|
+
const wantsStream = extractStreamFlag(sample, body);
|
|
202
|
+
const requestBody = { ...body, stream: wantsStream };
|
|
203
|
+
const targetUrl = `${baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;
|
|
204
|
+
|
|
205
|
+
ensureDir(OUT_DIR);
|
|
206
|
+
const runBase = path.join(OUT_DIR, `server-replay_${nowStamp()}`);
|
|
207
|
+
const requestOut = `${runBase}.request.json`;
|
|
208
|
+
const metaOut = `${runBase}.response.meta.json`;
|
|
209
|
+
const sseOut = `${runBase}.response.sse.log`;
|
|
210
|
+
const sseNdjsonOut = `${runBase}.response.sse.ndjson`;
|
|
211
|
+
const jsonOut = `${runBase}.response.json`;
|
|
212
|
+
const chatOut = `${runBase}.chat.json`;
|
|
103
213
|
|
|
104
214
|
const headers = {
|
|
105
215
|
'Content-Type': 'application/json',
|
|
216
|
+
'Accept': wantsStream ? 'text/event-stream' : 'application/json',
|
|
106
217
|
'OpenAI-Beta': 'responses-2024-12-17',
|
|
107
|
-
'
|
|
218
|
+
'x-routecodex-api-key': DEFAULT_KEY
|
|
108
219
|
};
|
|
109
220
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
model: String(body.model||'unknown'),
|
|
123
|
-
onEvent: (evt) => {
|
|
124
|
-
try {
|
|
125
|
-
fs.appendFileSync(sseLog, `event: ${evt.type}\n`);
|
|
126
|
-
fs.appendFileSync(sseLog, `data: ${JSON.stringify(evt.data)}\n\n`);
|
|
127
|
-
} catch {}
|
|
128
|
-
}
|
|
221
|
+
fs.writeFileSync(requestOut, JSON.stringify({
|
|
222
|
+
targetUrl,
|
|
223
|
+
endpoint,
|
|
224
|
+
sample: picked,
|
|
225
|
+
headers: { ...headers, 'x-routecodex-api-key': '***' },
|
|
226
|
+
body: requestBody
|
|
227
|
+
}, null, 2));
|
|
228
|
+
|
|
229
|
+
const res = await fetch(targetUrl, {
|
|
230
|
+
method: 'POST',
|
|
231
|
+
headers,
|
|
232
|
+
body: JSON.stringify(requestBody)
|
|
129
233
|
});
|
|
130
|
-
fs.writeFileSync(
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
234
|
+
fs.writeFileSync(metaOut, JSON.stringify({
|
|
235
|
+
status: res.status,
|
|
236
|
+
statusText: res.statusText,
|
|
237
|
+
headers: Object.fromEntries(res.headers.entries())
|
|
238
|
+
}, null, 2));
|
|
239
|
+
if (!res.ok) {
|
|
240
|
+
const text = await res.text();
|
|
241
|
+
fs.writeFileSync(`${runBase}.response.error.txt`, text, 'utf-8');
|
|
242
|
+
throw new Error(`HTTP ${res.status}: ${text.slice(0, 500)}`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (!wantsStream) {
|
|
246
|
+
const json = await res.json();
|
|
247
|
+
fs.writeFileSync(jsonOut, JSON.stringify(json, null, 2));
|
|
248
|
+
console.log('[responses-sse-replay-golden] mode=json sample=%s out=%s', picked.file, jsonOut);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const frames = await readSseFrames(res.body);
|
|
253
|
+
fs.writeFileSync(sseOut, frames.map((frame) => `${frame}\n\n`).join(''), 'utf-8');
|
|
254
|
+
fs.writeFileSync(sseNdjsonOut, frames.join('\n'), 'utf-8');
|
|
255
|
+
const converted = await convertSseFramesToJson(
|
|
256
|
+
frames,
|
|
257
|
+
picked.requestId,
|
|
258
|
+
typeof (requestBody).model === 'string' ? (requestBody).model : undefined
|
|
259
|
+
);
|
|
260
|
+
if (converted.json) {
|
|
261
|
+
fs.writeFileSync(jsonOut, JSON.stringify(converted.json, null, 2));
|
|
262
|
+
}
|
|
263
|
+
if (converted.chat) {
|
|
264
|
+
fs.writeFileSync(chatOut, JSON.stringify(converted.chat, null, 2));
|
|
265
|
+
}
|
|
266
|
+
console.log(
|
|
267
|
+
'[responses-sse-replay-golden] mode=sse sample=%s frames=%d sse=%s json=%s chat=%s',
|
|
268
|
+
picked.file,
|
|
269
|
+
frames.length,
|
|
270
|
+
sseOut,
|
|
271
|
+
converted.json ? jsonOut : '(skip)',
|
|
272
|
+
converted.chat ? chatOut : '(skip)'
|
|
273
|
+
);
|
|
136
274
|
}
|
|
137
275
|
|
|
138
|
-
main().catch(
|
|
276
|
+
main().catch((err) => {
|
|
277
|
+
console.error('[responses-sse-replay-golden] failed:', err?.message || String(err));
|
|
278
|
+
process.exit(1);
|
|
279
|
+
});
|
package/scripts/run-bg.sh
CHANGED
|
@@ -44,7 +44,7 @@ detect_port() {
|
|
|
44
44
|
local p="${TARGET_PORT:-}"
|
|
45
45
|
if [[ -n "$p" ]]; then echo "$p"; return; fi
|
|
46
46
|
if [[ -n "${ROUTECODEX_PORT:-}" ]]; then echo "${ROUTECODEX_PORT}"; return; fi
|
|
47
|
-
local cfg="$HOME/.
|
|
47
|
+
local cfg="$HOME/.rcc/config.json"
|
|
48
48
|
if command -v jq >/dev/null 2>&1 && [[ -f "$cfg" ]]; then
|
|
49
49
|
p=$(jq -r '.port // empty' "$cfg" 2>/dev/null || true)
|
|
50
50
|
if [[ -n "$p" && "$p" =~ ^[0-9]+$ ]]; then echo "$p"; return; fi
|
|
@@ -38,7 +38,7 @@ detect_port() {
|
|
|
38
38
|
local p="${TARGET_PORT:-}"
|
|
39
39
|
if [[ -n "$p" ]]; then echo "$p"; return; fi
|
|
40
40
|
if [[ -n "${ROUTECODEX_PORT:-}" ]]; then echo "${ROUTECODEX_PORT}"; return; fi
|
|
41
|
-
local cfg="$HOME/.
|
|
41
|
+
local cfg="$HOME/.rcc/config.json"
|
|
42
42
|
if command -v jq >/dev/null 2>&1 && [[ -f "$cfg" ]]; then
|
|
43
43
|
p=$(jq -r '.port // empty' "$cfg" 2>/dev/null || true)
|
|
44
44
|
if [[ -n "$p" && "$p" =~ ^[0-9]+$ ]]; then echo "$p"; return; fi
|
|
@@ -180,7 +180,7 @@ async function main() {
|
|
|
180
180
|
const samplePath = args.sample || args._[0];
|
|
181
181
|
if (!samplePath) throw new Error('Missing --sample <file.json>');
|
|
182
182
|
|
|
183
|
-
const configPath = args.config || path.join(os.homedir(), '.
|
|
183
|
+
const configPath = args.config || path.join(os.homedir(), '.rcc', 'config.json');
|
|
184
184
|
const outDir = args.out || path.join(process.cwd(), 'test-results', 'antigravity-pipeline-compare');
|
|
185
185
|
fs.mkdirSync(outDir, { recursive: true });
|
|
186
186
|
|
|
@@ -85,7 +85,7 @@ async function main() {
|
|
|
85
85
|
const baselinePath = args.baseline || args._[1];
|
|
86
86
|
if (!baselinePath) throw new Error('Missing --baseline <provider-request.json>');
|
|
87
87
|
|
|
88
|
-
const configPath = args.config || path.join(os.homedir(), '.
|
|
88
|
+
const configPath = args.config || path.join(os.homedir(), '.rcc', 'config.json');
|
|
89
89
|
const outDir = args.out || path.join(process.cwd(), 'test-results', 'antigravity-gemini-dryrun');
|
|
90
90
|
fs.mkdirSync(outDir, { recursive: true });
|
|
91
91
|
|
|
@@ -21,7 +21,7 @@ function usage(err) {
|
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const args = process.argv.slice(2);
|
|
24
|
-
const configPath = args[0] || path.join(process.env.HOME || '~', '.
|
|
24
|
+
const configPath = args[0] || path.join(process.env.HOME || '~', '.rcc', 'provider', 'c4m', 'config.v1.json');
|
|
25
25
|
if (!fs.existsSync(configPath)) usage(`Config file not found: ${configPath}`);
|
|
26
26
|
const providerTarget = args[1] || 'c4m.gpt-5.1';
|
|
27
27
|
const [providerId, modelId = 'gpt-5.1'] = providerTarget.split('.');
|
|
@@ -360,7 +360,7 @@ async function scenarioRealConfig(configPath) {
|
|
|
360
360
|
async function main() {
|
|
361
361
|
const args = parseArgs(process.argv.slice(2));
|
|
362
362
|
if (args.help) {
|
|
363
|
-
console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json] [--config ~/.
|
|
363
|
+
console.log('Usage: node scripts/tests/virtual-router-health.mjs [--out summary.json] [--config ~/.rcc/config.json]');
|
|
364
364
|
return;
|
|
365
365
|
}
|
|
366
366
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Update provider models from /v1/models endpoint and write into the user's
|
|
4
|
-
* RouteCodex config (defaults to ~/.
|
|
4
|
+
* RouteCodex config (defaults to ~/.rcc/config.json).
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
7
|
* node scripts/update-models.mjs --provider qwen-provider [--write] [--config path]
|
|
@@ -27,7 +27,7 @@ function expandHome(p){ return p && p.startsWith('~/')? p.replace(/^~\//, `${pro
|
|
|
27
27
|
|
|
28
28
|
function resolveConfigPath(explicit){
|
|
29
29
|
const envPath = process.env.ROUTECODEX_CONFIG_PATH || process.env.ROUTECODEX_CONFIG;
|
|
30
|
-
const fallback = path.join(process.env.HOME || '', '.
|
|
30
|
+
const fallback = path.join(process.env.HOME || '', '.rcc', 'config.json');
|
|
31
31
|
const candidate = expandHome(explicit || envPath || fallback);
|
|
32
32
|
if (!candidate) {
|
|
33
33
|
throw new Error('Unable to resolve configuration path');
|
|
@@ -149,7 +149,7 @@ const debugLogsCount = fs.existsSync(debugLogsDir)
|
|
|
149
149
|
|
|
150
150
|
if (debugLogsCount > 0) {
|
|
151
151
|
console.log('✅ 流水线系统活跃');
|
|
152
|
-
console.log('💡 建议使用: routecodex start --config ~/.
|
|
152
|
+
console.log('💡 建议使用: routecodex start --config ~/.rcc/config.json (默认监听 5555 端口)');
|
|
153
153
|
} else {
|
|
154
154
|
console.log('⚠️ 流水线系统可能未启动');
|
|
155
155
|
console.log('💡 建议检查 5555 端口上的 RouteCodex 服务是否已启动(routecodex start)');
|
|
@@ -24,7 +24,7 @@ const VERIFY_BASE = process.env.ROUTECODEX_VERIFY_BASE_URL || `http://127.0.0.1:
|
|
|
24
24
|
const VERIFY_CONFIG =
|
|
25
25
|
process.env.ROUTECODEX_VERIFY_CONFIG ||
|
|
26
26
|
process.env.ROUTECODEX_CONFIG_PATH ||
|
|
27
|
-
`${process.env.HOME || ''}/.
|
|
27
|
+
`${process.env.HOME || ''}/.rcc/config.json`;
|
|
28
28
|
|
|
29
29
|
const DEFAULT_SAMPLE = path.join(
|
|
30
30
|
os.homedir(),
|
|
@@ -16,11 +16,11 @@ const VERIFY_BASE = process.env.ROUTECODEX_VERIFY_BASE_URL || `http://127.0.0.1:
|
|
|
16
16
|
const EXPLICIT_VERIFY_CONFIG = String(
|
|
17
17
|
process.env.ROUTECODEX_VERIFY_CONFIG || process.env.ROUTECODEX_CONFIG_PATH || ''
|
|
18
18
|
).trim();
|
|
19
|
-
const DEFAULT_USER_CONFIG = `${process.env.HOME || ''}/.
|
|
19
|
+
const DEFAULT_USER_CONFIG = `${process.env.HOME || ''}/.rcc/config.json`;
|
|
20
20
|
const USE_USER_CONFIG = String(process.env.ROUTECODEX_VERIFY_USE_USER_CONFIG || '').trim() === '1';
|
|
21
21
|
const GEMINI_CLI_CONFIG =
|
|
22
22
|
process.env.ROUTECODEX_VERIFY_GEMINI_CLI_CONFIG ||
|
|
23
|
-
`${process.env.HOME || ''}/.
|
|
23
|
+
`${process.env.HOME || ''}/.rcc/provider/gemini-cli/config.v1.json`;
|
|
24
24
|
|
|
25
25
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
26
26
|
const DEFAULT_AGENTS_PATH = path.resolve(__dirname, '..', 'AGENTS.md');
|
|
@@ -55,8 +55,8 @@ async function waitForHealth() {
|
|
|
55
55
|
async function resolveTestModel() {
|
|
56
56
|
const home = os.homedir();
|
|
57
57
|
const candidates = [
|
|
58
|
-
path.join(home, '.
|
|
59
|
-
path.join(home, '.
|
|
58
|
+
path.join(home, '.rcc', 'config', 'generated', `virtual-router-config.${port}.generated.json`),
|
|
59
|
+
path.join(home, '.rcc', 'config', 'generated', 'virtual-router-config.generated.json'),
|
|
60
60
|
];
|
|
61
61
|
for (const file of candidates) {
|
|
62
62
|
try {
|
|
@@ -42,7 +42,7 @@ function resolveSecretValue(value) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
function loadProviderEntry(providerId) {
|
|
45
|
-
const providerRoot = path.join(os.homedir(), '.
|
|
45
|
+
const providerRoot = path.join(os.homedir(), '.rcc', 'provider', providerId);
|
|
46
46
|
for (const name of PROVIDER_CONFIG_FILES) {
|
|
47
47
|
const full = path.join(providerRoot, name);
|
|
48
48
|
if (!fs.existsSync(full)) continue;
|