@jsonstudio/rcc 0.89.1205 → 0.89.1348
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 +17 -0
- package/configsamples/config.json +426 -0
- package/configsamples/config.reference.json +58 -0
- package/configsamples/provider/crs/config.v1.json +46 -0
- package/configsamples/provider/glm/config.v1.json +81 -0
- package/configsamples/provider/glm-anthropic/config.v1.json +45 -0
- package/configsamples/provider/iflow/config.v1.json +74 -0
- package/configsamples/provider/kimi/config.v1.json +41 -0
- package/configsamples/provider/lmstudio/config.v1.json +101 -0
- package/configsamples/provider/mimo/config.v1.json +35 -0
- package/configsamples/provider/modelscope/config.v1.json +96 -0
- package/configsamples/provider/qwen/config.v1.json +38 -0
- package/configsamples/provider/tab/config.v1.json +50 -0
- package/configsamples/provider/tabglm/config.v1.json +49 -0
- package/dist/build-info.js +2 -2
- package/dist/cli/commands/code.js +12 -6
- package/dist/cli/commands/code.js.map +1 -1
- package/dist/cli/commands/config.d.ts +2 -1
- package/dist/cli/commands/config.js +74 -103
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/examples.js +6 -6
- package/dist/cli/commands/examples.js.map +1 -1
- package/dist/cli/commands/init.d.ts +28 -0
- package/dist/cli/commands/init.js +91 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/port.js +10 -2
- package/dist/cli/commands/port.js.map +1 -1
- package/dist/cli/commands/restart.js +5 -2
- package/dist/cli/commands/restart.js.map +1 -1
- package/dist/cli/commands/start.js +25 -22
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/status.js +1 -0
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/stop.js +1 -0
- package/dist/cli/commands/stop.js.map +1 -1
- package/dist/cli/config/bundled-docs.d.ts +20 -0
- package/dist/cli/config/bundled-docs.js +91 -0
- package/dist/cli/config/bundled-docs.js.map +1 -0
- package/dist/cli/config/init-config.d.ts +36 -0
- package/dist/cli/config/init-config.js +180 -0
- package/dist/cli/config/init-config.js.map +1 -0
- package/dist/cli/config/init-provider-catalog.d.ts +8 -0
- package/dist/cli/config/init-provider-catalog.js +187 -0
- package/dist/cli/config/init-provider-catalog.js.map +1 -0
- package/dist/cli/register/init-command.d.ts +3 -0
- package/dist/cli/register/init-command.js +5 -0
- package/dist/cli/register/init-command.js.map +1 -0
- package/dist/cli.js +28 -3
- package/dist/cli.js.map +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js +1 -1
- package/dist/client/gemini-cli/gemini-cli-protocol-client.js.map +1 -1
- package/dist/config/risk-control-config.d.ts +94 -0
- package/dist/config/risk-control-config.js +196 -0
- package/dist/config/risk-control-config.js.map +1 -0
- package/dist/constants/index.d.ts +6 -0
- package/dist/constants/index.js +13 -0
- package/dist/constants/index.js.map +1 -1
- package/dist/docs/daemon-admin-ui.html +2113 -190
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/manager/modules/health/index.d.ts +1 -1
- package/dist/manager/modules/quota/antigravity-quota-manager.d.ts +70 -0
- package/dist/manager/modules/quota/antigravity-quota-manager.js +442 -0
- package/dist/manager/modules/quota/antigravity-quota-manager.js.map +1 -0
- package/dist/manager/modules/quota/index.d.ts +3 -127
- package/dist/manager/modules/quota/index.js +2 -1093
- package/dist/manager/modules/quota/index.js.map +1 -1
- package/dist/manager/modules/quota/provider-key-normalization.d.ts +3 -0
- package/dist/manager/modules/quota/provider-key-normalization.js +155 -0
- package/dist/manager/modules/quota/provider-key-normalization.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.cooldown.d.ts +9 -0
- package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js +115 -0
- package/dist/manager/modules/quota/provider-quota-daemon.cooldown.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.d.ts +77 -0
- package/dist/manager/modules/quota/provider-quota-daemon.events.d.ts +12 -0
- package/dist/manager/modules/quota/provider-quota-daemon.events.js +237 -0
- package/dist/manager/modules/quota/provider-quota-daemon.events.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.js +404 -0
- package/dist/manager/modules/quota/provider-quota-daemon.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.d.ts +11 -0
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js +189 -0
- package/dist/manager/modules/quota/provider-quota-daemon.model-backoff.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.snapshot.d.ts +8 -0
- package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js +96 -0
- package/dist/manager/modules/quota/provider-quota-daemon.snapshot.js.map +1 -0
- package/dist/manager/modules/quota/provider-quota-daemon.view.d.ts +19 -0
- package/dist/manager/modules/quota/provider-quota-daemon.view.js +37 -0
- package/dist/manager/modules/quota/provider-quota-daemon.view.js.map +1 -0
- package/dist/manager/modules/routing/index.d.ts +1 -0
- package/dist/manager/modules/routing/index.js +11 -25
- package/dist/manager/modules/routing/index.js.map +1 -1
- package/dist/manager/quota/provider-quota-center.d.ts +2 -0
- package/dist/manager/quota/provider-quota-center.js +80 -82
- package/dist/manager/quota/provider-quota-center.js.map +1 -1
- package/dist/modules/llmswitch/bridge.d.ts +16 -18
- package/dist/modules/llmswitch/bridge.js +293 -94
- package/dist/modules/llmswitch/bridge.js.map +1 -1
- package/dist/modules/llmswitch/core-loader.d.ts +4 -2
- package/dist/modules/llmswitch/core-loader.js +32 -20
- package/dist/modules/llmswitch/core-loader.js.map +1 -1
- package/dist/modules/pipeline/utils/colored-logger.js +3 -2
- package/dist/modules/pipeline/utils/colored-logger.js.map +1 -1
- package/dist/modules/pipeline/utils/debug-logger.js +1 -1
- package/dist/modules/pipeline/utils/debug-logger.js.map +1 -1
- package/dist/providers/auth/iflow-cookie-auth.js +0 -2
- package/dist/providers/auth/iflow-cookie-auth.js.map +1 -1
- package/dist/providers/auth/oauth-lifecycle.js +2 -23
- package/dist/providers/auth/oauth-lifecycle.js.map +1 -1
- package/dist/providers/core/config/camoufox-launcher.js +35 -4
- package/dist/providers/core/config/camoufox-launcher.js.map +1 -1
- package/dist/providers/core/runtime/antigravity-quota-client.js +6 -3
- package/dist/providers/core/runtime/antigravity-quota-client.js.map +1 -1
- package/dist/providers/core/runtime/base-provider.d.ts +2 -2
- package/dist/providers/core/runtime/base-provider.js +74 -69
- package/dist/providers/core/runtime/base-provider.js.map +1 -1
- package/dist/providers/core/runtime/gemini-cli-http-provider.js +6 -4
- package/dist/providers/core/runtime/gemini-cli-http-provider.js.map +1 -1
- package/dist/providers/core/runtime/http-request-executor.js +2 -2
- package/dist/providers/core/runtime/http-request-executor.js.map +1 -1
- package/dist/providers/core/runtime/http-transport-provider.d.ts +14 -0
- package/dist/providers/core/runtime/http-transport-provider.js +111 -5
- package/dist/providers/core/runtime/http-transport-provider.js.map +1 -1
- package/dist/providers/core/runtime/provider-error-classifier.js +10 -0
- package/dist/providers/core/runtime/provider-error-classifier.js.map +1 -1
- package/dist/providers/core/runtime/provider-factory.js +7 -5
- package/dist/providers/core/runtime/provider-factory.js.map +1 -1
- package/dist/providers/core/runtime/provider-runtime-metadata.d.ts +6 -0
- package/dist/providers/core/runtime/provider-runtime-metadata.js.map +1 -1
- package/dist/providers/core/runtime/responses-provider.d.ts +1 -7
- package/dist/providers/core/runtime/responses-provider.js +12 -93
- package/dist/providers/core/runtime/responses-provider.js.map +1 -1
- package/dist/providers/core/strategies/oauth-auth-code-flow.js +12 -8
- package/dist/providers/core/strategies/oauth-auth-code-flow.js.map +1 -1
- package/dist/providers/core/utils/http-client.js +16 -3
- package/dist/providers/core/utils/http-client.js.map +1 -1
- package/dist/providers/core/utils/provider-error-logger.d.ts +1 -1
- package/dist/providers/core/utils/provider-error-reporter.d.ts +3 -1
- package/dist/providers/core/utils/provider-error-reporter.js +3 -0
- package/dist/providers/core/utils/provider-error-reporter.js.map +1 -1
- package/dist/providers/core/utils/snapshot-writer.js +1 -4
- package/dist/providers/core/utils/snapshot-writer.js.map +1 -1
- package/dist/providers/mock/mock-provider-runtime.js +57 -27
- package/dist/providers/mock/mock-provider-runtime.js.map +1 -1
- package/dist/scripts/camoufox/launch-auth.mjs +193 -58
- package/dist/server/handlers/handler-utils.js +3 -2
- package/dist/server/handlers/handler-utils.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.d.ts +2 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js +103 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-handler.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-session.d.ts +5 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-session.js +77 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-session.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-store.d.ts +18 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-store.js +89 -0
- package/dist/server/runtime/http-server/daemon-admin/auth-store.js.map +1 -0
- package/dist/server/runtime/http-server/daemon-admin/credentials-handler.js +1 -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.js +226 -24
- package/dist/server/runtime/http-server/daemon-admin/providers-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js +47 -8
- package/dist/server/runtime/http-server/daemon-admin/quota-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/restart-handler.js +1 -1
- package/dist/server/runtime/http-server/daemon-admin/restart-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/stats-handler.js +1 -1
- package/dist/server/runtime/http-server/daemon-admin/stats-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js +68 -4
- package/dist/server/runtime/http-server/daemon-admin/status-handler.js.map +1 -1
- package/dist/server/runtime/http-server/daemon-admin-routes.d.ts +3 -4
- package/dist/server/runtime/http-server/daemon-admin-routes.js +9 -14
- package/dist/server/runtime/http-server/daemon-admin-routes.js.map +1 -1
- package/dist/server/runtime/http-server/executor-metadata.js +1 -1
- package/dist/server/runtime/http-server/executor-metadata.js.map +1 -1
- package/dist/server/runtime/http-server/executor-response.js +0 -16
- package/dist/server/runtime/http-server/executor-response.js.map +1 -1
- package/dist/server/runtime/http-server/hub-shadow-compare.js +110 -34
- package/dist/server/runtime/http-server/hub-shadow-compare.js.map +1 -1
- package/dist/server/runtime/http-server/index.d.ts +5 -3
- package/dist/server/runtime/http-server/index.js +215 -109
- package/dist/server/runtime/http-server/index.js.map +1 -1
- package/dist/server/runtime/http-server/middleware.js +19 -1
- package/dist/server/runtime/http-server/middleware.js.map +1 -1
- package/dist/server/runtime/http-server/request-executor.js +10 -19
- package/dist/server/runtime/http-server/request-executor.js.map +1 -1
- package/dist/server/runtime/http-server/routes.js +8 -2
- package/dist/server/runtime/http-server/routes.js.map +1 -1
- package/dist/server/runtime/http-server/session-dir.d.ts +2 -0
- package/dist/server/runtime/http-server/session-dir.js +59 -0
- package/dist/server/runtime/http-server/session-dir.js.map +1 -0
- package/dist/server/runtime/http-server/types.d.ts +0 -4
- package/dist/server/utils/utf8-chunk-buffer.js +6 -3
- package/dist/server/utils/utf8-chunk-buffer.js.map +1 -1
- package/dist/server/utils/warmup-storm-tracker.js +1 -1
- package/dist/server/utils/warmup-storm-tracker.js.map +1 -1
- package/dist/server-factory.d.ts +6 -28
- package/dist/server-factory.js +8 -93
- package/dist/server-factory.js.map +1 -1
- package/dist/token-daemon/index.js +2 -2
- package/dist/token-daemon/index.js.map +1 -1
- package/dist/token-daemon/provider-registry.js +0 -1
- package/dist/token-daemon/provider-registry.js.map +1 -1
- package/dist/token-daemon/server-utils.js +8 -9
- package/dist/token-daemon/server-utils.js.map +1 -1
- package/dist/token-daemon/token-utils.js +1 -1
- package/dist/token-daemon/token-utils.js.map +1 -1
- package/dist/tools/semantic-replay.js +2 -2
- package/dist/tools/semantic-replay.js.map +1 -1
- package/dist/tools/stats-request-events.d.ts +1 -1
- package/dist/tools/stats-usage.js +6 -3
- package/dist/tools/stats-usage.js.map +1 -1
- package/dist/utils/llms-engine-shadow.d.ts +19 -0
- package/dist/utils/llms-engine-shadow.js +209 -0
- package/dist/utils/llms-engine-shadow.js.map +1 -0
- package/dist/utils/runtime-versions.js +2 -1
- package/dist/utils/runtime-versions.js.map +1 -1
- package/docs/ARCHITECTURE.md +402 -0
- package/docs/CODEX_AND_CLAUDE_CODE.md +69 -0
- package/docs/CONFIG_ARCHITECTURE.md +517 -0
- package/docs/ERROR_HANDLING_AUDIT.md +0 -0
- package/docs/GCLI2API_PARITY_GAPS.md +98 -0
- package/docs/INSTALLATION_AND_QUICKSTART.md +74 -0
- package/docs/INSTRUCTION_MARKUP.md +89 -0
- package/docs/MODULE_ENHANCEMENT_SYSTEM.md +666 -0
- package/docs/PORTS.md +36 -0
- package/docs/PROVIDERS_BUILTIN.md +111 -0
- package/docs/PROVIDER_TYPES.md +55 -0
- package/docs/SERVERTOOL_CLOCK_DESIGN.md +233 -0
- package/docs/USAGE_HANDLING_ANALYSIS.md +335 -0
- package/docs/USER_CONFIG_PARSER_CHANGES.md +175 -0
- package/docs/V3_INBOUND_OUTBOUND_DESIGN.md +86 -0
- package/docs/VIRTUAL_ROUTER_PRIORITY_AND_HEALTH.md +125 -0
- package/docs/anthropic-request-golden-samples.md +50 -0
- package/docs/ccr-alignment-enhancetool.md +105 -0
- package/docs/chat-glm-500-analysis.md +79 -0
- package/docs/chat-request-golden-samples.md +42 -0
- package/docs/chat-semantic-expansion-plan.md +82 -0
- package/docs/cli-command-inventory.md +76 -0
- package/docs/codex-samples-replay.md +50 -0
- package/docs/daemon-admin-api-design.md +350 -0
- package/docs/daemon-admin-module-structure.md +169 -0
- package/docs/daemon-admin-ui.html +3394 -0
- package/docs/debug-system-design.md +734 -0
- package/docs/debugging/gemini-sse-root-cause.md +52 -0
- package/docs/debugging/sse_encoding_failure_analysis.md +53 -0
- package/docs/dry-run/README.md +721 -0
- package/docs/error-handling-v2.md +92 -0
- package/docs/exec-command-guard-policy.example.v1.json +42 -0
- package/docs/fixes/gemini-protocol-mapping.md +57 -0
- package/docs/fixes/oauth-portal-timing-fix.md +202 -0
- package/docs/fixes/web-search-hop3-fix.md +265 -0
- package/docs/glm-api-reference.md +390 -0
- package/docs/glm-chat-completions.md +1779 -0
- package/docs/glm-history-inline-images.md +44 -0
- package/docs/golden-ci-library.md +66 -0
- package/docs/lmstudio-dry-run-summary.md +203 -0
- package/docs/lmstudio-tool-calling.md +214 -0
- package/docs/mapping-tables/anthropic-to-openai.json +290 -0
- package/docs/mapping-tables/iflow-to-openai.json +215 -0
- package/docs/mapping-tables/openai-passthrough.json +190 -0
- package/docs/mapping-tables/openai-to-iflow.json +227 -0
- package/docs/monitoring/Design.md +61 -0
- package/docs/multi-token-auth-guide.md +66 -0
- package/docs/oauth-authentication-guide.md +168 -0
- package/docs/oauth-iflow-implementation.md +153 -0
- package/docs/pipeline-routing-report.md +209 -0
- package/docs/plans/manager-daemon/PLAN.md +86 -0
- package/docs/plans/provider-config-v2-plan.md +176 -0
- package/docs/plans/provider-runtime-manager-plan.md +209 -0
- package/docs/plans/transparent-429-failover.md +89 -0
- package/docs/plans/unified-hub-framework-v1.md +245 -0
- package/docs/provider-config-v2-ui-design.md +181 -0
- package/docs/provider-quota-design.md +129 -0
- package/docs/providers/gemini-provider.md +62 -0
- package/docs/providers/lmstudio-v2-migration-report.md +102 -0
- package/docs/providers/provider-composite-design.md +142 -0
- package/docs/providers/provider-composite-testing.md +98 -0
- package/docs/providers/provider-type-only-migration.md +111 -0
- package/docs/rccx-wasm-migration.md +74 -0
- package/docs/refactoring/architecture-comparison-diagram.md +140 -0
- package/docs/refactoring/compatibility-v2-architecture-design.md +738 -0
- package/docs/refactoring/workflow-compatibility-refactoring-design.md +361 -0
- package/docs/reports/routing-classification-report.json +24 -0
- package/docs/reports/routing-classification-report.md +18 -0
- package/docs/reports/thinking-keywords-report.json +19 -0
- package/docs/responses/README.md +156 -0
- package/docs/responses-generic-provider.md +86 -0
- package/docs/responses-passthrough-provider-design.md +202 -0
- package/docs/routing-awrr-health-weighted-round-robin.md +179 -0
- package/docs/routing-instructions.md +393 -0
- package/docs/stop-message-auto.md +225 -0
- package/docs/streaming-flow.html +30 -0
- package/docs/streaming-flow.md +182 -0
- package/docs/token-daemon-preview.html +490 -0
- package/docs/token-refresh-daemon-plan.md +269 -0
- package/docs/transformation-tables/Gemini-FinishReason/345/256/214/346/225/264/350/275/254/346/215/242/350/241/250.json +233 -0
- package/docs/transformation-tables/README.md +225 -0
- package/docs/transformation-tables/claude-code-router-anthropic-to-gemini.json +283 -0
- package/docs/transformation-tables/claude-code-router-anthropic-to-openai.json +208 -0
- package/docs/transformation-tables/claude-code-router-openai-to-anthropic.json +261 -0
- package/docs/transformation-tables/claude-code-router-openai-to-gemini.json +208 -0
- package/docs/transformation-tables/claude-code-router-openai-to-lmstudio.json +182 -0
- package/docs/transformation-tables/claude-code-router-openai-to-ollama.json +250 -0
- package/docs/transformation-tables/claude-code-router-openai-to-textgenwebui.json +295 -0
- package/docs/transformation-tables/claude-code-router-provider-conversions.json +193 -0
- package/docs/transformation-tables//345/256/214/346/225/264/347/232/204/345/267/245/345/205/267/346/211/247/350/241/214/346/265/201/347/250/213/350/275/254/346/215/242/350/241/250.json +299 -0
- package/docs/transformation-tables//345/257/271/350/257/235/345/216/206/345/217/262/347/273/264/346/212/244/345/210/206/346/236/220.md +134 -0
- package/docs/transformation-tables//345/267/245/345/205/267/350/260/203/347/224/250/346/250/241/345/274/217/345/210/206/346/236/220.md +158 -0
- package/docs/transformation-tables//347/212/266/346/200/201/347/256/241/347/220/206/351/234/200/346/261/202/345/210/206/346/236/220.md +175 -0
- package/docs/transformation-tables//351/235/231/346/200/201/350/241/250vs/345/212/250/346/200/201/345/210/206/346/236/220.md +189 -0
- package/docs/transformation-tables//351/235/231/346/200/201/350/241/250/345/207/206/347/241/256/346/200/247/350/257/204/344/274/260.md +179 -0
- package/docs/transformation-tables//351/235/236/346/265/201/345/274/217/345/234/272/346/231/257/345/210/206/346/236/220.md +189 -0
- package/docs/v2-architecture/IMPLEMENTATION-ROADMAP.md +367 -0
- package/docs/v2-architecture/OPTIMIZED-DESIGN.md +827 -0
- package/docs/v2-architecture/PRERUN-CONNECTION-DESIGN.md +716 -0
- package/docs/v2-architecture/README.md +551 -0
- package/docs/verification/modelscope-verify.md +59 -0
- package/docs/web-search-service-design.md +322 -0
- package/package.json +12 -7
- package/scripts/camoufox/launch-auth.mjs +193 -58
- package/scripts/monitor-diff.mjs +126 -0
- package/scripts/pack-mode.mjs +19 -1
- package/scripts/pack-rcc.mjs +63 -0
- package/scripts/unified-hub-shadow-compare.mjs +33 -13
- package/scripts/verify-e2e-toolcall.mjs +115 -26
- package/dist/modules/llmswitch/pipeline-registry.d.ts +0 -57
- package/dist/modules/llmswitch/pipeline-registry.js +0 -229
- package/dist/modules/llmswitch/pipeline-registry.js.map +0 -1
- package/dist/server/RouteCodexServer.d.ts +0 -13
- package/dist/server/RouteCodexServer.js +0 -25
- package/dist/server/RouteCodexServer.js.map +0 -1
- package/dist/v2/conversion/hub/snapshot-recorder.d.ts +0 -12
- package/dist/v2/conversion/hub/snapshot-recorder.js +0 -22
- package/dist/v2/conversion/hub/snapshot-recorder.js.map +0 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
## `/v1/messages` Streaming/Tool Flow
|
|
2
|
+
|
|
3
|
+
### HTTP Entry → `req_inbound` Stages
|
|
4
|
+
|
|
5
|
+
| Stage | Payload focus | Key fields |
|
|
6
|
+
|-------|---------------|------------|
|
|
7
|
+
| HTTP handler (`src/server/handlers/messages-handler.ts`) | Raw JSON/SSE body | `jsonPayload.stream`, `rawRequestMetadata`, `metadata.stream/inboundStream/outboundStream`, `clientHeaders` |
|
|
8
|
+
| `req_inbound_stage1_format_parse` | Format envelope | Mirrors request body (Anthropic/Chat/Responses → canonical format) |
|
|
9
|
+
| `req_inbound_stage2_semantic_map` | `ChatEnvelope` + `StandardizedRequest` | `parameters.stream`, `messages`, `tools`, `metadata.context` |
|
|
10
|
+
| `req_inbound_stage3_context_capture` | Adapter context | Captures protocol-specific hints, `toolCallIdStyle`, alias maps |
|
|
11
|
+
|
|
12
|
+
**Flow**
|
|
13
|
+
|
|
14
|
+
1. Client body `stream` is taken as ground truth. Handler copies it into `jsonPayload.stream` and marks `metadata.stream/inboundStream/outboundStream`.
|
|
15
|
+
2. Format adapter normalises body into Chat envelope (Anthropic messages → canonical chat).
|
|
16
|
+
3. Semantic mapper builds `ChatEnvelope`, collecting `tools`, `tool_outputs`, `tool_choice`, `parameters.stream`.
|
|
17
|
+
4. `ChatEnvelope → StandardizedRequest` copies `parameters.stream`, `messages`, `tools`, metadata.
|
|
18
|
+
|
|
19
|
+
### Request Process (`req_process_stage1_tool_governance`)
|
|
20
|
+
|
|
21
|
+
* Input: `StandardizedRequest` with `parameters.stream` from client.
|
|
22
|
+
* Tool filters (`runChatRequestToolFilters`) govern tool list/tool choice without touching `stream`.
|
|
23
|
+
* `ProcessedRequest.processingMetadata.toolCalls` records governed tool call plan.
|
|
24
|
+
|
|
25
|
+
### Request Outbound (`req_outbound_stage*`)
|
|
26
|
+
|
|
27
|
+
| Stage | Effect |
|
|
28
|
+
|-------|--------|
|
|
29
|
+
| `req_outbound_stage1_semantic_map` | Reconstruct ChatEnvelope for provider protocol (`AdapterContext.providerProtocol`). |
|
|
30
|
+
| `req_outbound_stage2_format_build` | Produce provider payload, map `tools` & `tool_choice`. Apply provider `supportsStreaming` override. |
|
|
31
|
+
|
|
32
|
+
**Streaming rule**
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
if provider.profile.supportsStreaming === true => payload.stream = true
|
|
36
|
+
if provider.profile.supportsStreaming === false => payload.stream = false
|
|
37
|
+
else => payload.stream = StandardizedRequest.parameters.stream
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Provider Layer
|
|
41
|
+
|
|
42
|
+
* Request uses final `payload.stream`.
|
|
43
|
+
* Response can be SSE or JSON. Driver normalises it to JSON before handing to Hub.
|
|
44
|
+
|
|
45
|
+
### Response Inbound
|
|
46
|
+
|
|
47
|
+
| Stage | Effect |
|
|
48
|
+
|-------|--------|
|
|
49
|
+
| `resp_inbound_stage1_sse_decode` | Decode SSE if provider returned stream. |
|
|
50
|
+
| `resp_inbound_stage2_format_parse` | Map provider payload to format envelope. |
|
|
51
|
+
| `resp_inbound_stage3_semantic_map` | Build Chat response (tool_calls, tool outputs, finish reason). |
|
|
52
|
+
|
|
53
|
+
### Response Process
|
|
54
|
+
|
|
55
|
+
| Stage | Effect |
|
|
56
|
+
|-------|--------|
|
|
57
|
+
| `resp_process_stage1_tool_governance` | Validates provider tool calls (IDs, schema, arguments). |
|
|
58
|
+
| `resp_process_stage2_finalize` | Builds final Chat response JSON (`choices`, `usage`, `finish_reason`). |
|
|
59
|
+
|
|
60
|
+
### Response Outbound
|
|
61
|
+
|
|
62
|
+
| Stage | Effect |
|
|
63
|
+
|-------|--------|
|
|
64
|
+
| `resp_outbound_stage1_client_remap` | Convert final Chat response into client protocol (`Anthropic Messages`, `OpenAI Chat`, `Responses`). |
|
|
65
|
+
| `resp_outbound_stage2_sse_stream` | Emits SSE iff `metadata.stream === true` (entrance value). Otherwise returns JSON. |
|
|
66
|
+
|
|
67
|
+
**Important**: Outbound streaming decision ignores provider response type; it only checks client entrance metadata.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Stage Reference (request → response)
|
|
72
|
+
|
|
73
|
+
| Pipeline section | Stages |
|
|
74
|
+
|------------------|--------|
|
|
75
|
+
| Request inbound | `req_inbound_stage1_format_parse`, `req_inbound_stage2_semantic_map`, `req_inbound_stage3_context_capture` |
|
|
76
|
+
| Request process | `req_process_stage1_tool_governance`, `req_process_stage2_route_select` |
|
|
77
|
+
| Request outbound | `req_outbound_stage1_semantic_map`, `req_outbound_stage2_format_build` |
|
|
78
|
+
| Response inbound | `resp_inbound_stage1_sse_decode`, `resp_inbound_stage2_format_parse`, `resp_inbound_stage3_semantic_map` |
|
|
79
|
+
| Response process | `resp_process_stage1_tool_governance`, `resp_process_stage2_finalize` |
|
|
80
|
+
| Response outbound| `resp_outbound_stage1_client_remap`, `resp_outbound_stage2_sse_stream` |
|
|
81
|
+
|
|
82
|
+
SSE/JSON selection happens at `resp_outbound_stage2_sse_stream` based solely on `metadata.stream`.
|
|
83
|
+
|
|
84
|
+
### HTTP Response
|
|
85
|
+
|
|
86
|
+
`sendPipelineResponse` uses `options.forceSSE = metadata.stream`. SSE events follow client protocol (Anthropic `message_start/content_block_delta`, OpenAI `chat.completion.chunk`, etc.). JSON includes canonical `choices/tool_calls/tool_outputs/finish_reason`.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Field / Stage State Summary
|
|
91
|
+
|
|
92
|
+
| Field | HTTP handler | req_inbound | req_process | req_outbound | provider resp | resp_inbound | resp_process | resp_outbound |
|
|
93
|
+
|-------|--------------|-------------|-------------|--------------|---------------|--------------|--------------|---------------|
|
|
94
|
+
| `stream` | Set from client body | Copied to `parameters.stream` | Unchanged | Override only if provider config forces | n/a | Remains in metadata | Drives `wantsStream` | Controls SSE vs JSON |
|
|
95
|
+
| `tools` | Raw array | Normalised Chat tools | Tool governance (policy) | Mapped to provider schema | Provider call result | Normalised Chat tool calls | Validated/strictified | Mapped back to client schema |
|
|
96
|
+
| `tool_choice` | Raw | Stored in parameters | Governed | Provider schema | — | — | Included in final Chat response | Client schema |
|
|
97
|
+
| `tool outputs` | Raw (Responses) | Stored as `toolOutputs` | — | Provider payload (if needed) | Provider result frames | Normalised to Chat tool role msg | Packaged | Client schema (Messages, Responses) |
|
|
98
|
+
| `finish_reason` | — | — | — | Provider dependent | Provided by provider | Normalised to Chat finish reason | Finalised | Returned in client schema |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Protocol-specific Conversion Details
|
|
103
|
+
|
|
104
|
+
### OpenAI Chat (`/v1/chat/completions`)
|
|
105
|
+
|
|
106
|
+
**Inbound**
|
|
107
|
+
1. `req_inbound_stage1_format_parse` accepts OpenAI Chat JSON.
|
|
108
|
+
2. `req_inbound_stage2_semantic_map` flattens `choices[].messages` into ChatEnvelope, collects `tool_calls`, `tool_choice`.
|
|
109
|
+
3. `req_inbound_stage3_context_capture` stores `toolCallIdStyle` hints.
|
|
110
|
+
|
|
111
|
+
**Outbound**
|
|
112
|
+
1. `req_outbound_stage1_semantic_map` reconstructs OpenAI Chat payload with governed `tools`.
|
|
113
|
+
2. `req_outbound_stage2_format_build` serialises `function` schema, `tool_choice`, `stream`.
|
|
114
|
+
3. `resp_outbound_stage1_client_remap` writes `choices[].delta`, `finish_reason`, `tool_calls`.
|
|
115
|
+
4. `resp_outbound_stage2_sse_stream` emits `chat.completion.chunk` events when `stream === true`.
|
|
116
|
+
|
|
117
|
+
### Anthropic Messages (`/v1/messages`)
|
|
118
|
+
|
|
119
|
+
**Inbound**
|
|
120
|
+
1. `req_inbound_stage1_format_parse` parses Anthropic `messages[]/content_block` structure.
|
|
121
|
+
2. `req_inbound_stage2_semantic_map` converts to ChatEnvelope, capturing `anthropicMirror`, alias map, metadata.
|
|
122
|
+
3. `req_inbound_stage3_context_capture` stores Anthropics-specific aliasing + tool ID style.
|
|
123
|
+
|
|
124
|
+
**Outbound**
|
|
125
|
+
1. `req_outbound_stage1_semantic_map` builds Anthropics message list (system blocks, tool_use, tool_result).
|
|
126
|
+
2. `req_outbound_stage2_format_build` sets `tools`, `tool_choice`, `stream` (respecting provider override).
|
|
127
|
+
3. Provider response SSE → `resp_inbound_stage1_sse_decode`.
|
|
128
|
+
4. `resp_outbound_stage1_client_remap` emits `message_start`, `content_block_start/delta`, tool_use/tool_result, `message_delta.stop_reason`.
|
|
129
|
+
5. `resp_outbound_stage2_sse_stream` uses entrance `stream` to send SSE; otherwise JSON matches Anthropic schema.
|
|
130
|
+
|
|
131
|
+
### OpenAI Responses (`/v1/responses`)
|
|
132
|
+
|
|
133
|
+
**Inbound**
|
|
134
|
+
1. Handler routes `/v1/responses` to `responses-format-adapter`.
|
|
135
|
+
2. `req_inbound_stage2_semantic_map` maps `input[]` into ChatEnvelope (`messages/tools`), `tool_outputs`.
|
|
136
|
+
3. `req_inbound_stage3_context_capture` records responses context for bridging (multi-modal).
|
|
137
|
+
|
|
138
|
+
**Outbound**
|
|
139
|
+
1. `req_outbound_stage1_semantic_map` converts ChatEnvelope to Responses `input[]`.
|
|
140
|
+
2. `req_outbound_stage2_format_build` writes `metadata`, `modalities`, `instructions`, `stream`.
|
|
141
|
+
3. Provider SSE or JSON feeds `resp_inbound_*`; tool outputs appear as `response.output[]`.
|
|
142
|
+
4. `resp_outbound_stage1_client_remap` rebuilds Responses `output[]` array (tool calls, tool results, reasoning, finish status).
|
|
143
|
+
5. `resp_outbound_stage2_sse_stream` emits Responses SSE events when entrance `stream === true`.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Streaming / Tool Pipeline Flow
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
Client (/v1/messages)
|
|
153
|
+
→ HTTP handler
|
|
154
|
+
stream := body.stream
|
|
155
|
+
metadata.stream/inbound/outbound := stream
|
|
156
|
+
→ req_inbound_stage1 (format parse)
|
|
157
|
+
→ req_inbound_stage2 (semantic map)
|
|
158
|
+
ChatEnvelope.parameters.stream := stream
|
|
159
|
+
→ StandardizedRequest.parameters.stream := stream
|
|
160
|
+
→ req_process_stage1_tool_governance
|
|
161
|
+
tools/tool_choice governed (stream untouched)
|
|
162
|
+
→ req_outbound_stage1/2
|
|
163
|
+
apply provider supportsStreaming override
|
|
164
|
+
payload.stream := override or stream
|
|
165
|
+
→ Provider
|
|
166
|
+
sends SSE/JSON accordingly
|
|
167
|
+
returns SSE/JSON (tool_calls, finish_reason)
|
|
168
|
+
→ resp_inbound stages
|
|
169
|
+
decode SSE, build Chat response
|
|
170
|
+
→ resp_process
|
|
171
|
+
tool governance, final Chat response
|
|
172
|
+
→ resp_outbound_stage1
|
|
173
|
+
map Chat response -> client protocol
|
|
174
|
+
→ resp_outbound_stage2
|
|
175
|
+
if entrance stream === true -> emit client SSE
|
|
176
|
+
else -> emit JSON
|
|
177
|
+
→ HTTP response
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
See `streaming-flow.html` for a Mermaid diagram illustrating the above.
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<title>RouteCodex Token Daemon 预览(树状视图)</title>
|
|
6
|
+
<style>
|
|
7
|
+
* {
|
|
8
|
+
box-sizing: border-box;
|
|
9
|
+
}
|
|
10
|
+
body {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
14
|
+
background-color: #020617;
|
|
15
|
+
color: #e5e7eb;
|
|
16
|
+
}
|
|
17
|
+
header {
|
|
18
|
+
padding: 14px 20px;
|
|
19
|
+
border-bottom: 1px solid #111827;
|
|
20
|
+
background: radial-gradient(circle at top left, #1d4ed8 0, #020617 50%);
|
|
21
|
+
}
|
|
22
|
+
header h1 {
|
|
23
|
+
margin: 0;
|
|
24
|
+
font-size: 18px;
|
|
25
|
+
font-weight: 600;
|
|
26
|
+
}
|
|
27
|
+
header .subtitle {
|
|
28
|
+
font-size: 12px;
|
|
29
|
+
color: #cbd5f5;
|
|
30
|
+
margin-top: 4px;
|
|
31
|
+
}
|
|
32
|
+
header .meta {
|
|
33
|
+
margin-top: 4px;
|
|
34
|
+
font-size: 11px;
|
|
35
|
+
color: #9ca3af;
|
|
36
|
+
}
|
|
37
|
+
main {
|
|
38
|
+
padding: 12px 20px 24px;
|
|
39
|
+
}
|
|
40
|
+
.layout {
|
|
41
|
+
display: flex;
|
|
42
|
+
gap: 16px;
|
|
43
|
+
}
|
|
44
|
+
.panel {
|
|
45
|
+
flex: 1;
|
|
46
|
+
min-width: 0;
|
|
47
|
+
background-color: #020617;
|
|
48
|
+
border-radius: 10px;
|
|
49
|
+
border: 1px solid #111827;
|
|
50
|
+
padding: 10px 12px 12px;
|
|
51
|
+
}
|
|
52
|
+
.panel h2 {
|
|
53
|
+
margin: 0 0 8px;
|
|
54
|
+
font-size: 14px;
|
|
55
|
+
font-weight: 500;
|
|
56
|
+
}
|
|
57
|
+
.panel .hint {
|
|
58
|
+
font-size: 11px;
|
|
59
|
+
color: #6b7280;
|
|
60
|
+
margin-bottom: 6px;
|
|
61
|
+
}
|
|
62
|
+
.mono {
|
|
63
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
|
64
|
+
font-size: 12px;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* Tree */
|
|
68
|
+
.tree {
|
|
69
|
+
font-size: 12px;
|
|
70
|
+
line-height: 1.4;
|
|
71
|
+
}
|
|
72
|
+
.tree ul {
|
|
73
|
+
list-style: none;
|
|
74
|
+
margin: 0;
|
|
75
|
+
padding-left: 16px;
|
|
76
|
+
border-left: 1px solid #1f2937;
|
|
77
|
+
}
|
|
78
|
+
.tree-root {
|
|
79
|
+
font-size: 12px;
|
|
80
|
+
font-weight: 500;
|
|
81
|
+
margin-bottom: 4px;
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
gap: 6px;
|
|
85
|
+
}
|
|
86
|
+
.tree-node {
|
|
87
|
+
position: relative;
|
|
88
|
+
padding: 3px 0 3px 12px;
|
|
89
|
+
}
|
|
90
|
+
.tree-label {
|
|
91
|
+
display: inline-flex;
|
|
92
|
+
align-items: center;
|
|
93
|
+
gap: 6px;
|
|
94
|
+
}
|
|
95
|
+
.tree-node::before {
|
|
96
|
+
content: "";
|
|
97
|
+
position: absolute;
|
|
98
|
+
left: 0;
|
|
99
|
+
top: 10px;
|
|
100
|
+
width: 10px;
|
|
101
|
+
height: 1px;
|
|
102
|
+
background-color: #1f2937;
|
|
103
|
+
}
|
|
104
|
+
.icon {
|
|
105
|
+
font-size: 11px;
|
|
106
|
+
opacity: 0.8;
|
|
107
|
+
}
|
|
108
|
+
.badge {
|
|
109
|
+
display: inline-flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
padding: 0 6px;
|
|
112
|
+
border-radius: 999px;
|
|
113
|
+
font-size: 10px;
|
|
114
|
+
border: 1px solid transparent;
|
|
115
|
+
}
|
|
116
|
+
.badge.online {
|
|
117
|
+
background-color: rgba(34, 197, 94, 0.15);
|
|
118
|
+
border-color: rgba(34, 197, 94, 0.5);
|
|
119
|
+
color: #bbf7d0;
|
|
120
|
+
}
|
|
121
|
+
.badge.offline {
|
|
122
|
+
background-color: rgba(148, 163, 184, 0.15);
|
|
123
|
+
border-color: rgba(148, 163, 184, 0.5);
|
|
124
|
+
color: #e5e7eb;
|
|
125
|
+
}
|
|
126
|
+
.badge.apikey {
|
|
127
|
+
background-color: rgba(59, 130, 246, 0.1);
|
|
128
|
+
border-color: rgba(59, 130, 246, 0.6);
|
|
129
|
+
color: #bfdbfe;
|
|
130
|
+
}
|
|
131
|
+
.badge.oauth {
|
|
132
|
+
background-color: rgba(52, 211, 153, 0.1);
|
|
133
|
+
border-color: rgba(52, 211, 153, 0.6);
|
|
134
|
+
color: #a7f3d0;
|
|
135
|
+
}
|
|
136
|
+
.badge.none {
|
|
137
|
+
background-color: rgba(156, 163, 175, 0.1);
|
|
138
|
+
border-color: rgba(156, 163, 175, 0.6);
|
|
139
|
+
color: #e5e7eb;
|
|
140
|
+
}
|
|
141
|
+
.badge.status-valid {
|
|
142
|
+
background-color: rgba(34, 197, 94, 0.15);
|
|
143
|
+
border-color: rgba(34, 197, 94, 0.5);
|
|
144
|
+
color: #bbf7d0;
|
|
145
|
+
}
|
|
146
|
+
.badge.status-expiring {
|
|
147
|
+
background-color: rgba(234, 179, 8, 0.15);
|
|
148
|
+
border-color: rgba(234, 179, 8, 0.5);
|
|
149
|
+
color: #facc15;
|
|
150
|
+
}
|
|
151
|
+
.badge.status-expired {
|
|
152
|
+
background-color: rgba(239, 68, 68, 0.15);
|
|
153
|
+
border-color: rgba(239, 68, 68, 0.5);
|
|
154
|
+
color: #fecaca;
|
|
155
|
+
}
|
|
156
|
+
.badge.status-invalid {
|
|
157
|
+
background-color: rgba(148, 163, 184, 0.15);
|
|
158
|
+
border-color: rgba(148, 163, 184, 0.5);
|
|
159
|
+
color: #e5e7eb;
|
|
160
|
+
}
|
|
161
|
+
.scope-switch {
|
|
162
|
+
display: flex;
|
|
163
|
+
flex-wrap: wrap;
|
|
164
|
+
align-items: center;
|
|
165
|
+
gap: 6px;
|
|
166
|
+
margin-bottom: 4px;
|
|
167
|
+
font-size: 11px;
|
|
168
|
+
}
|
|
169
|
+
.scope-pill {
|
|
170
|
+
padding: 2px 8px;
|
|
171
|
+
border-radius: 999px;
|
|
172
|
+
border: 1px solid #1f2937;
|
|
173
|
+
background-color: #020617;
|
|
174
|
+
color: #9ca3af;
|
|
175
|
+
cursor: default;
|
|
176
|
+
}
|
|
177
|
+
.scope-pill.active {
|
|
178
|
+
border-color: rgba(59, 130, 246, 0.7);
|
|
179
|
+
background: radial-gradient(circle at top left, rgba(59, 130, 246, 0.35), #020617 60%);
|
|
180
|
+
color: #e5e7eb;
|
|
181
|
+
}
|
|
182
|
+
.tag {
|
|
183
|
+
padding: 0 4px;
|
|
184
|
+
border-radius: 4px;
|
|
185
|
+
border: 1px solid #1f2937;
|
|
186
|
+
font-size: 10px;
|
|
187
|
+
color: #9ca3af;
|
|
188
|
+
background-color: #020617;
|
|
189
|
+
}
|
|
190
|
+
.dim {
|
|
191
|
+
color: #6b7280;
|
|
192
|
+
}
|
|
193
|
+
</style>
|
|
194
|
+
</head>
|
|
195
|
+
<body>
|
|
196
|
+
<header>
|
|
197
|
+
<h1>RouteCodex Token Daemon 预览</h1>
|
|
198
|
+
<div class="subtitle">树状结构:服务器 → Providers → Tokens / Tokens → Used By</div>
|
|
199
|
+
<div class="meta">
|
|
200
|
+
所有数据为静态示例,结构对齐 CLI 输出:<span class="mono">token-daemon servers/providers/tokens --json</span>;
|
|
201
|
+
系统统计对应 <span class="mono">StatsSnapshot</span>(<span class="mono">router.global</span> / <span class="mono">providers.global</span>)
|
|
202
|
+
</div>
|
|
203
|
+
</header>
|
|
204
|
+
|
|
205
|
+
<main>
|
|
206
|
+
<!-- 顶部统计区 -->
|
|
207
|
+
<section style="margin-bottom: 12px; display:flex; gap:12px; flex-wrap:wrap;">
|
|
208
|
+
<div style="flex:1; min-width:180px; background:#020617; border:1px solid #111827; border-radius:10px; padding:8px 10px;">
|
|
209
|
+
<div style="font-size:11px; color:#9ca3af; margin-bottom:4px;">系统统计(Virtual Router)</div>
|
|
210
|
+
<div class="scope-switch">
|
|
211
|
+
<span class="dim">范围:</span>
|
|
212
|
+
<span class="scope-pill active">当前 Server(local-5555)</span>
|
|
213
|
+
<span class="scope-pill">当前 Config(~/.routecodex/config.json)</span>
|
|
214
|
+
<span class="scope-pill">所有 Server</span>
|
|
215
|
+
<span class="scope-pill">所有 Config</span>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="dim" style="font-size:11px; margin-bottom:4px;">
|
|
218
|
+
示例:当前 Server 视角,对应该进程的 <span class="mono">StatsSnapshot.router.global</span> /
|
|
219
|
+
<span class="mono">StatsSnapshot.providers.global</span>
|
|
220
|
+
</div>
|
|
221
|
+
<div style="display:flex; flex-wrap:wrap; gap:12px; font-size:12px;">
|
|
222
|
+
<div>
|
|
223
|
+
<div class="dim" style="font-size:11px;">Requests</div>
|
|
224
|
+
<div class="mono">
|
|
225
|
+
12,345
|
|
226
|
+
<span class="dim">(router.global.requestCount)</span>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
<div>
|
|
230
|
+
<div class="dim" style="font-size:11px;">Success / Error</div>
|
|
231
|
+
<div class="mono">
|
|
232
|
+
12,000 / 345
|
|
233
|
+
<span class="dim">(providers.global.successCount / errorCount)</span>
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
<div>
|
|
237
|
+
<div class="dim" style="font-size:11px;">Avg Latency</div>
|
|
238
|
+
<div class="mono">
|
|
239
|
+
210 ms
|
|
240
|
+
<span class="dim">(providers.global.latencySumMs / requestCount)</span>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
<div>
|
|
244
|
+
<div class="dim" style="font-size:11px;">Tokens</div>
|
|
245
|
+
<div class="mono">
|
|
246
|
+
prompt=23k / completion=18k / total=41k
|
|
247
|
+
<span class="dim">(providers.global.usage)</span>
|
|
248
|
+
</div>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
<div style="flex:0 0 220px; min-width:200px; background:#020617; border:1px solid #111827; border-radius:10px; padding:8px 10px;">
|
|
253
|
+
<div style="font-size:11px; color:#9ca3af; margin-bottom:4px;">操作</div>
|
|
254
|
+
<div style="display:flex; flex-direction:column; gap:6px;">
|
|
255
|
+
<button style="font-size:12px; padding:4px 8px; border-radius:6px; border:none; cursor:default; background:linear-gradient(90deg,#4f46e5,#06b6d4); color:#f9fafb;">
|
|
256
|
+
⟳ 重启所有受影响的 Providers
|
|
257
|
+
</button>
|
|
258
|
+
<div class="dim" style="font-size:11px;">
|
|
259
|
+
实际实现中,这里可以调用后端 API,例如:
|
|
260
|
+
<span class="mono">routecodex restart</span> 或 针对单个 server 的重启命令。
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
</section>
|
|
265
|
+
|
|
266
|
+
<div class="layout">
|
|
267
|
+
<!-- 左侧:Server → Providers → Tokens 视角 -->
|
|
268
|
+
<section class="panel">
|
|
269
|
+
<h2>Server 视角(自上而下)</h2>
|
|
270
|
+
<div class="hint">
|
|
271
|
+
入口:<span class="mono">servers + providers</span>,按「服务器 → Provider → TokenFile」组织。
|
|
272
|
+
</div>
|
|
273
|
+
|
|
274
|
+
<div class="tree">
|
|
275
|
+
<div class="tree-root">
|
|
276
|
+
<span class="icon">🖥</span>
|
|
277
|
+
<span class="mono">Servers</span>
|
|
278
|
+
</div>
|
|
279
|
+
<ul>
|
|
280
|
+
<li class="tree-node">
|
|
281
|
+
<div class="tree-label">
|
|
282
|
+
<span class="icon">📦</span>
|
|
283
|
+
<span class="mono">local-5520</span>
|
|
284
|
+
<span class="badge offline">offline</span>
|
|
285
|
+
<span class="dim mono">(~/.routecodex/config.json)</span>
|
|
286
|
+
</div>
|
|
287
|
+
<ul>
|
|
288
|
+
<li class="tree-node">
|
|
289
|
+
<div class="tree-label">
|
|
290
|
+
<span class="icon">🤖</span>
|
|
291
|
+
<span class="mono">glm</span>
|
|
292
|
+
<span class="tag">protocol=openai</span>
|
|
293
|
+
<span class="badge apikey">apikey</span>
|
|
294
|
+
<span class="dim mono">source=inline value=6484…ttZB</span>
|
|
295
|
+
</div>
|
|
296
|
+
</li>
|
|
297
|
+
<li class="tree-node">
|
|
298
|
+
<div class="tree-label">
|
|
299
|
+
<span class="icon">🤖</span>
|
|
300
|
+
<span class="mono">qwen</span>
|
|
301
|
+
<span class="tag">protocol=openai</span>
|
|
302
|
+
<span class="badge oauth">oauth</span>
|
|
303
|
+
<span class="dim mono">tokenFile=~/.routecodex/auth/qwen-oauth.json</span>
|
|
304
|
+
</div>
|
|
305
|
+
<ul>
|
|
306
|
+
<li class="tree-node">
|
|
307
|
+
<div class="tree-label">
|
|
308
|
+
<span class="icon">🔑</span>
|
|
309
|
+
<span class="mono">token: work (qwen-oauth-1-work.json)</span>
|
|
310
|
+
<span class="badge status-expired">expired</span>
|
|
311
|
+
<span class="dim mono">expiresAt=2025-12-25T23:10Z</span>
|
|
312
|
+
</div>
|
|
313
|
+
</li>
|
|
314
|
+
</ul>
|
|
315
|
+
</li>
|
|
316
|
+
<li class="tree-node">
|
|
317
|
+
<div class="tree-label">
|
|
318
|
+
<span class="icon">🤖</span>
|
|
319
|
+
<span class="mono">iflow</span>
|
|
320
|
+
<span class="tag">protocol=openai</span>
|
|
321
|
+
<span class="badge oauth">oauth</span>
|
|
322
|
+
<span class="dim mono">tokenFile=~/.routecodex/auth/iflow-oauth-1-186.json</span>
|
|
323
|
+
</div>
|
|
324
|
+
<ul>
|
|
325
|
+
<li class="tree-node">
|
|
326
|
+
<div class="tree-label">
|
|
327
|
+
<span class="icon">🔑</span>
|
|
328
|
+
<span class="mono">token: 186 (iflow-oauth-1-186.json)</span>
|
|
329
|
+
<span class="badge status-valid">valid</span>
|
|
330
|
+
<span class="dim mono">剩余=652min</span>
|
|
331
|
+
</div>
|
|
332
|
+
</li>
|
|
333
|
+
<li class="tree-node">
|
|
334
|
+
<div class="tree-label">
|
|
335
|
+
<span class="icon">🔑</span>
|
|
336
|
+
<span class="mono">token: 173 (iflow-oauth-2-173.json)</span>
|
|
337
|
+
<span class="badge status-expiring">expiring</span>
|
|
338
|
+
<span class="dim mono">剩余=12min</span>
|
|
339
|
+
</div>
|
|
340
|
+
</li>
|
|
341
|
+
</ul>
|
|
342
|
+
</li>
|
|
343
|
+
<li class="tree-node">
|
|
344
|
+
<div class="tree-label">
|
|
345
|
+
<span class="icon">🤖</span>
|
|
346
|
+
<span class="mono">gemini</span>
|
|
347
|
+
<span class="tag">protocol=openai</span>
|
|
348
|
+
<span class="badge apikey">apikey</span>
|
|
349
|
+
<span class="dim mono">source=inline value=AIza…3mEQ</span>
|
|
350
|
+
</div>
|
|
351
|
+
</li>
|
|
352
|
+
<li class="tree-node">
|
|
353
|
+
<div class="tree-label">
|
|
354
|
+
<span class="icon">🤖</span>
|
|
355
|
+
<span class="mono">lmstudio</span>
|
|
356
|
+
<span class="tag">protocol=responses</span>
|
|
357
|
+
<span class="badge apikey">apikey</span>
|
|
358
|
+
<span class="dim mono">value=${LM_STUDIO_API_KEY:-}</span>
|
|
359
|
+
</div>
|
|
360
|
+
</li>
|
|
361
|
+
</ul>
|
|
362
|
+
</li>
|
|
363
|
+
</ul>
|
|
364
|
+
</div>
|
|
365
|
+
</section>
|
|
366
|
+
|
|
367
|
+
<!-- 右侧:Token → Used By 视角 + 重启按钮 -->
|
|
368
|
+
<section class="panel">
|
|
369
|
+
<h2>Token 视角(自下而上)</h2>
|
|
370
|
+
<div class="hint">
|
|
371
|
+
入口:<span class="mono">tokens</span>,按「Token → 使用它的服务器/Providers」组织。
|
|
372
|
+
在这个视角下点击某个 usedBy 节点可以触发对应 Provider 的重启。
|
|
373
|
+
</div>
|
|
374
|
+
|
|
375
|
+
<div class="tree">
|
|
376
|
+
<div class="tree-root">
|
|
377
|
+
<span class="icon">🔑</span>
|
|
378
|
+
<span class="mono">Tokens</span>
|
|
379
|
+
</div>
|
|
380
|
+
<ul>
|
|
381
|
+
<li class="tree-node">
|
|
382
|
+
<div class="tree-label">
|
|
383
|
+
<span class="icon">🌐</span>
|
|
384
|
+
<span class="mono">iflow</span>
|
|
385
|
+
</div>
|
|
386
|
+
<ul>
|
|
387
|
+
<li class="tree-node">
|
|
388
|
+
<div class="tree-label">
|
|
389
|
+
<span class="icon">🗝</span>
|
|
390
|
+
<span class="mono">186 (iflow-oauth-1-186.json)</span>
|
|
391
|
+
<span class="badge status-valid">valid</span>
|
|
392
|
+
<span class="dim mono">expiresAt=2025-12-26T11:46:37Z, 剩余=652min</span>
|
|
393
|
+
</div>
|
|
394
|
+
<ul>
|
|
395
|
+
<li class="tree-node">
|
|
396
|
+
<div class="tree-label">
|
|
397
|
+
<span class="icon">📦</span>
|
|
398
|
+
<span class="mono">usedBy: local-5520:iflow</span>
|
|
399
|
+
<span class="tag">protocol=openai</span>
|
|
400
|
+
<button style="margin-left:6px; font-size:11px; padding:1px 6px; border-radius:6px; border:none; background:#1f2937; color:#e5e7eb; cursor:default;">
|
|
401
|
+
⟳ 重启该 Provider
|
|
402
|
+
</button>
|
|
403
|
+
</div>
|
|
404
|
+
</li>
|
|
405
|
+
</ul>
|
|
406
|
+
</li>
|
|
407
|
+
<li class="tree-node">
|
|
408
|
+
<div class="tree-label">
|
|
409
|
+
<span class="icon">🗝</span>
|
|
410
|
+
<span class="mono">173 (iflow-oauth-2-173.json)</span>
|
|
411
|
+
<span class="badge status-expiring">expiring</span>
|
|
412
|
+
<span class="dim mono">expiresAt=2025-12-26T11:47:24Z, 剩余=12min</span>
|
|
413
|
+
</div>
|
|
414
|
+
<ul>
|
|
415
|
+
<li class="tree-node">
|
|
416
|
+
<div class="tree-label">
|
|
417
|
+
<span class="icon">📦</span>
|
|
418
|
+
<span class="mono">usedBy: local-5520:iflow</span>
|
|
419
|
+
<span class="tag">protocol=openai</span>
|
|
420
|
+
<button style="margin-left:6px; font-size:11px; padding:1px 6px; border-radius:6px; border:none; background:#1f2937; color:#e5e7eb; cursor:default;">
|
|
421
|
+
⟳ 重启该 Provider
|
|
422
|
+
</button>
|
|
423
|
+
</div>
|
|
424
|
+
</li>
|
|
425
|
+
</ul>
|
|
426
|
+
</li>
|
|
427
|
+
</ul>
|
|
428
|
+
</li>
|
|
429
|
+
|
|
430
|
+
<li class="tree-node">
|
|
431
|
+
<div class="tree-label">
|
|
432
|
+
<span class="icon">🌐</span>
|
|
433
|
+
<span class="mono">qwen</span>
|
|
434
|
+
</div>
|
|
435
|
+
<ul>
|
|
436
|
+
<li class="tree-node">
|
|
437
|
+
<div class="tree-label">
|
|
438
|
+
<span class="icon">🗝</span>
|
|
439
|
+
<span class="mono">work (qwen-oauth-1-work.json)</span>
|
|
440
|
+
<span class="badge status-expired">expired</span>
|
|
441
|
+
<span class="dim mono">expiresAt=2025-12-25T23:10:00Z, 剩余=-5min</span>
|
|
442
|
+
</div>
|
|
443
|
+
<ul>
|
|
444
|
+
<li class="tree-node">
|
|
445
|
+
<div class="tree-label">
|
|
446
|
+
<span class="icon">📦</span>
|
|
447
|
+
<span class="mono">usedBy: local-5520:qwen</span>
|
|
448
|
+
<span class="tag">protocol=openai</span>
|
|
449
|
+
<button style="margin-left:6px; font-size:11px; padding:1px 6px; border-radius:6px; border:none; background:#1f2937; color:#e5e7eb; cursor:default;">
|
|
450
|
+
⟳ 重启该 Provider
|
|
451
|
+
</button>
|
|
452
|
+
</div>
|
|
453
|
+
</li>
|
|
454
|
+
</ul>
|
|
455
|
+
</li>
|
|
456
|
+
</ul>
|
|
457
|
+
</li>
|
|
458
|
+
|
|
459
|
+
<li class="tree-node">
|
|
460
|
+
<div class="tree-label">
|
|
461
|
+
<span class="icon">🌐</span>
|
|
462
|
+
<span class="mono">gemini-cli</span>
|
|
463
|
+
</div>
|
|
464
|
+
<ul>
|
|
465
|
+
<li class="tree-node">
|
|
466
|
+
<div class="tree-label">
|
|
467
|
+
<span class="icon">🗝</span>
|
|
468
|
+
<span class="mono">primary (gemini-oauth-1-primary.json)</span>
|
|
469
|
+
<span class="badge status-invalid">invalid</span>
|
|
470
|
+
<span class="dim mono">无有效 access_token/api_key</span>
|
|
471
|
+
</div>
|
|
472
|
+
<ul>
|
|
473
|
+
<li class="tree-node">
|
|
474
|
+
<div class="tree-label">
|
|
475
|
+
<span class="icon">📦</span>
|
|
476
|
+
<span class="mono">usedBy: -</span>
|
|
477
|
+
<span class="dim">(尚未绑定到任何 provider)</span>
|
|
478
|
+
</div>
|
|
479
|
+
</li>
|
|
480
|
+
</ul>
|
|
481
|
+
</li>
|
|
482
|
+
</ul>
|
|
483
|
+
</li>
|
|
484
|
+
</ul>
|
|
485
|
+
</div>
|
|
486
|
+
</section>
|
|
487
|
+
</div>
|
|
488
|
+
</main>
|
|
489
|
+
</body>
|
|
490
|
+
</html>
|