coding-proxy 0.2.4a4__tar.gz → 0.3.0__tar.gz
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.
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/CHANGELOG.md +19 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/PKG-INFO +23 -22
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/README.md +22 -21
- coding_proxy-0.3.0/assets/dashboard-v0.2.4.png +0 -0
- coding_proxy-0.3.0/docs/arch/config-reference.md +310 -0
- coding_proxy-0.3.0/docs/arch/convert.md +101 -0
- coding_proxy-0.3.0/docs/arch/design-patterns.md +607 -0
- coding_proxy-0.3.0/docs/arch/routing.md +180 -0
- coding_proxy-0.3.0/docs/arch/testing.md +114 -0
- coding_proxy-0.3.0/docs/arch/vendors.md +404 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/docs/ci-cd.md +41 -41
- coding_proxy-0.3.0/docs/framework.md +490 -0
- coding_proxy-0.3.0/docs/guide/api-reference.md +362 -0
- coding_proxy-0.3.0/docs/guide/cli-reference.md +238 -0
- coding_proxy-0.3.0/docs/guide/dashboard.md +63 -0
- coding_proxy-0.3.0/docs/guide/monitoring.md +207 -0
- coding_proxy-0.3.0/docs/guide/quickstart.md +103 -0
- coding_proxy-0.3.0/docs/guide/vendors.md +247 -0
- coding_proxy-0.3.0/docs/user-guide.md +290 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/docs/zh-CN/README.md +22 -21
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/pyproject.toml +1 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/cli/__init__.py +2 -2
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/cli/auth_commands.py +1 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/cli/banner.py +2 -2
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/config.default.yaml +126 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/schema.py +11 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/server.py +1 -1
- coding_proxy-0.3.0/src/coding/proxy/convert/vendor_channels.py +546 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/db.py +78 -11
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/stats.py +102 -26
- coding_proxy-0.3.0/src/coding/proxy/native_api/__init__.py +84 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/config.py +110 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/__init__.py +12 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/anthropic.py +111 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/gemini.py +112 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/openai.py +231 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/handler.py +485 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/operation.py +167 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/routes.py +68 -0
- coding_proxy-0.3.0/src/coding/proxy/native_api/usage_registry.py +279 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/pricing.py +17 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/executor.py +58 -102
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/router.py +2 -8
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/usage_parser.py +65 -5
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/usage_recorder.py +39 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/app.py +26 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/dashboard.py +23 -8
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/routes.py +35 -24
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/anthropic.py +2 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_app_routes.py +17 -20
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_banner.py +2 -2
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_config_init.py +1 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_config_loader.py +6 -6
- coding_proxy-0.3.0/tests/test_native_api_base_url_override.py +166 -0
- coding_proxy-0.3.0/tests/test_native_api_extractors.py +331 -0
- coding_proxy-0.3.0/tests/test_native_api_handler.py +374 -0
- coding_proxy-0.3.0/tests/test_native_api_operation.py +130 -0
- coding_proxy-0.3.0/tests/test_native_api_routes.py +132 -0
- coding_proxy-0.3.0/tests/test_parse_usage_gemini.py +196 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_router_executor.py +265 -95
- coding_proxy-0.3.0/tests/test_token_logger_native_columns.py +334 -0
- coding_proxy-0.3.0/tests/test_vendor_channels.py +1731 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_zhipu.py +1 -1
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/uv.lock +1 -1
- coding_proxy-0.2.4a4/assets/dashboard-v0.2.3.png +0 -0
- coding_proxy-0.2.4a4/docs/framework.md +0 -1640
- coding_proxy-0.2.4a4/docs/user-guide.md +0 -1771
- coding_proxy-0.2.4a4/src/coding/proxy/server/request_normalizer.py +0 -685
- coding_proxy-0.2.4a4/tests/test_request_normalizer.py +0 -1494
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.github/workflows/ci.yml +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.github/workflows/coverage.yml +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.github/workflows/release.yml +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.gitignore +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.pre-commit-config.yaml +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/AGENTS.md +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/CLAUDE.md +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/LICENSE +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/__main__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/base.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/github.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/google.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/runtime.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/store.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/compat/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/compat/canonical.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/compat/session_store.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/auth_schema.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/loader.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/resiliency.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/routing.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/vendors.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/anthropic_to_gemini.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/anthropic_to_openai.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/gemini_sse_adapter.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/gemini_to_anthropic.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/openai_to_anthropic.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/formatters.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/auth.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/compat.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/constants.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/pricing.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/token.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/vendor.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/circuit_breaker.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/error_classifier.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/model_mapper.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/quota_guard.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/rate_limit.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/retry.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/session_manager.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/tier.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/factory.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/responses.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/streaming/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/streaming/anthropic_compat.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/alibaba.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/antigravity.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/base.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot_models.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot_token_manager.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot_urls.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/doubao.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/kimi.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/minimax.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/mixins.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/native_anthropic.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/token_manager.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/xiaomi.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/zhipu.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/__init__.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_antigravity.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_auto_login.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_circuit_breaker.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_cli_usage.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_compat.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_convert_request.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_convert_response.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_convert_sse.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_convert_request.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_convert_response.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_models.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_urls.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_currency.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_error_classifier.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_logging_dual_write.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_mixins.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_auth.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_compat.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_constants.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_mapper.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_pricing.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_token.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_vendor.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_native_vendors.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_parse_usage.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_pricing.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_quota_guard.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_rate_limit.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_router_chain.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_runtime_reauth.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_schema.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_streaming_anthropic_compat.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_tier.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_tiers_config.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_time_range.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_token_logger.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_token_manager.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_types.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_vendor_streaming.py +0 -0
- {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_vendors.py +0 -0
|
@@ -4,7 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## [v0.3.0](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.3.0) — 2026-04-20
|
|
8
|
+
|
|
9
|
+
> [!IMPORTANT]
|
|
10
|
+
>
|
|
11
|
+
> **🚀 OpenAI、Anthropic、Gemini 原生 API 进驻 Coding Proxy!**
|
|
12
|
+
>
|
|
13
|
+
> 服务对象不在局限 Claude Code,凡兼容 OpenAI、Anthropic、Gemini 三巨头 API 协议的客户端,出口 LLM 流量可统一收敛到 Coding Proxy。
|
|
14
|
+
|
|
15
|
+
### ✨ 核心亮点
|
|
16
|
+
|
|
17
|
+
- feat(native-api): 新增 `/api/{openai,gemini,anthropic}/**` 原生 LLM API 全量 catch-all 透传通道;
|
|
18
|
+
- feat(dashboard): 新增实时 Web Dashboard 页面,聚合展示流量与用量统计;
|
|
19
|
+
- feat(usage): `usage` 区分 Claude Code 场景(`'cc'`)与原生 API 场景(`'api'`);
|
|
20
|
+
- refactor(vendor-channels): 将供应商转换通道从目标专属重构为源→目标绑定模型;
|
|
21
|
+
- docs(user-guide): 补充 POST /v1/messages 完整 API 参考文档;
|
|
22
|
+
|
|
23
|
+
### 🔧 更多特性
|
|
24
|
+
|
|
25
|
+
- feat(server): 默认监听端口 `8046` → `3392`,规范化 [Negentropy](https://github.com/ThreeFish-AI/negentropy) 体系端口;
|
|
8
26
|
|
|
9
27
|
## [v0.2.3](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.2.3) — 2026-04-16
|
|
10
28
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: coding-proxy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: A High-Availability, Transparent, and Smart Multi-Vendor Proxy for Claude Code. Support Claude Plans, GitHub Copilot, Google Antigravity, ZAI/GLM, MiniMax, Qwen, Xiaomi, Kimi, Doubao...
|
|
5
5
|
Project-URL: Source Code, https://github.com/ThreeFish-AI/coding-proxy
|
|
6
6
|
Project-URL: User Guide, https://github.com/ThreeFish-AI/coding-proxy/blob/master/docs/user-guide.md
|
|
@@ -57,13 +57,13 @@ When you're deeply immersed in your coding "zone" with **Claude Code** (or any A
|
|
|
57
57
|
## 🌟 Core Features
|
|
58
58
|
|
|
59
59
|
<div align="center">
|
|
60
|
-
<img src="assets/dashboard-v0.2.
|
|
60
|
+
<img src="assets/dashboard-v0.2.4.png">
|
|
61
61
|
</div>
|
|
62
62
|
|
|
63
|
-
- **⛓️ N-tier Chained Failover**: Autonomous descending sequence, supporting Claude's official plans, as well as Coding Plans from GitHub Copilot, Z AI, MiniMax, Alibaba Qwen, Xiaomi, Kimi, Doubao, etc.
|
|
63
|
+
- **⛓️ N-tier Chained Failover**: Autonomous descending sequence, supporting Claude's official plans, as well as Coding Plans from GitHub Copilot, Google Antigravity, Z AI, MiniMax, Alibaba Qwen, Xiaomi, Kimi, Doubao, etc.
|
|
64
64
|
- **🛡️ Smart Resilience & Quota Guardians**: Every single vendor node comes fully armed with an independent **Circuit Breaker** and **Quota Guard** to proactively dodge avalanches without breaking a sweat.
|
|
65
65
|
- **👻 Phantom-like Transparency**: **100% transparent** to the client! No code tweaks required. Overwrite `ANTHROPIC_BASE_URL` with a single line, and you're good to go.
|
|
66
|
-
- **🔄 Universal Alchemy (Formats & Models)**: Native support for two-way request/streaming (SSE) translations between Anthropic ←→ Gemini. Plus, auto/DIY model name mapping (e.g., effortlessly morphing `claude-*` into `glm-*`).
|
|
66
|
+
- **🔄 Universal Alchemy (Formats & Models)**: Native support for two-way request/streaming (SSE) translations between Anthropic ←→ Gemini and Anthropic ←→ OpenAI. Plus, auto/DIY model name mapping (e.g., effortlessly morphing `claude-*` into `glm-*`).
|
|
67
67
|
- **📊 Extreme Observability**: Built-in, zero-BS local monitoring powered by a `SQLite WAL`. The CLI provides a one-click detailed Token usage dashboard (`coding-proxy usage`).
|
|
68
68
|
- **⚡ Featherweight Standalone Deployment**: A fully asynchronous architecture (`FastAPI` + `httpx`). Zero dependency on Redis, message queues, or other heavy machinery—absolutely no extra baggage for your dev rig.
|
|
69
69
|
|
|
@@ -97,9 +97,9 @@ uv run coding-proxy start
|
|
|
97
97
|
# INFO: Started server process [1403]
|
|
98
98
|
# INFO: Waiting for application startup.
|
|
99
99
|
# ...
|
|
100
|
-
# INFO: coding-proxy started: host=127.0.0.1 port=
|
|
100
|
+
# INFO: coding-proxy started: host=127.0.0.1 port=3392
|
|
101
101
|
# INFO: Application startup complete.
|
|
102
|
-
# INFO: Uvicorn running on http://127.0.0.1:
|
|
102
|
+
# INFO: Uvicorn running on http://127.0.0.1:3392 (Press CTRL+C to quit)
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
### 4. Seamless Claude Code Integration
|
|
@@ -107,7 +107,7 @@ uv run coding-proxy start
|
|
|
107
107
|
Open a fresh terminal tab and route your traffic through coding-proxy before firing up Claude Code:
|
|
108
108
|
|
|
109
109
|
```bash
|
|
110
|
-
export ANTHROPIC_BASE_URL=http://127.0.0.1:
|
|
110
|
+
export ANTHROPIC_BASE_URL=http://127.0.0.1:3392
|
|
111
111
|
|
|
112
112
|
# Enjoy blissful, silky-smooth, and uninterrupted coding nirvana:
|
|
113
113
|
claude
|
|
@@ -119,12 +119,13 @@ claude
|
|
|
119
119
|
|
|
120
120
|
`coding-proxy` comes equipped with a badass suite of CLI tools to help you boss around your proxy state.
|
|
121
121
|
|
|
122
|
-
| Command | Description
|
|
123
|
-
| :------- |
|
|
124
|
-
| `start` | **Fire up the proxy server.** Supports custom ports and configuration paths.
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
122
|
+
| Command | Description | Example Usage |
|
|
123
|
+
| :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------- |
|
|
124
|
+
| `start` | **Fire up the proxy server.** Supports custom ports and configuration paths. | `coding-proxy start -p 8080 -c ~/config.yaml` |
|
|
125
|
+
| `auth` | **Manage OAuth credentials.** Sub-commands: `login` (browser OAuth), `status` (token validity), `reauth` (re-authenticate), `logout` (clear tokens). | `coding-proxy auth login -p github` |
|
|
126
|
+
| `status` | **Check proxy health.** Shows circuit breaker states (OPEN/CLOSED) and quota status across all tiers. | `coding-proxy status` |
|
|
127
|
+
| `usage` | **Token Stats Dashboard.** Stalks every single token consumed, failovers triggered, and latency across day/vendor/model dimensions. | `coding-proxy usage -d 7 -v anthropic` |
|
|
128
|
+
| `reset` | **The emergency flush button.** Force-reset all circuit breakers and quotas instantly when you've confirmed the main vendor is back from the dead. | `coding-proxy reset` |
|
|
128
129
|
|
|
129
130
|
---
|
|
130
131
|
|
|
@@ -153,29 +154,29 @@ graph RL
|
|
|
153
154
|
subgraph NTier["N-tier"]
|
|
154
155
|
direction TB
|
|
155
156
|
|
|
156
|
-
subgraph Tier0 ["Tier 0:
|
|
157
|
+
subgraph Tier0 ["Tier 0: Zhipu"]
|
|
157
158
|
direction RL
|
|
158
|
-
G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("
|
|
159
|
+
G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("GLM API")):::api
|
|
159
160
|
end
|
|
160
161
|
|
|
161
|
-
subgraph Tier1 ["Tier 1:
|
|
162
|
+
subgraph Tier1 ["Tier 1: Anthropic"]
|
|
162
163
|
direction RL
|
|
163
|
-
G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("
|
|
164
|
+
G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Anthropic API")):::api
|
|
164
165
|
end
|
|
165
166
|
|
|
166
|
-
subgraph Tier2 ["Tier 2:
|
|
167
|
+
subgraph Tier2 ["Tier 2: GitHub Copilot"]
|
|
167
168
|
direction RL
|
|
168
|
-
G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("
|
|
169
|
+
G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Copilot API")):::api
|
|
169
170
|
end
|
|
170
171
|
|
|
171
|
-
subgraph
|
|
172
|
+
subgraph Tier3 ["Tier 3: Google Antigravity"]
|
|
172
173
|
direction RL
|
|
173
|
-
|
|
174
|
+
API3(("Gemini API")):::fallback
|
|
174
175
|
end
|
|
175
176
|
|
|
176
177
|
Tier0 -. "❌ Blocked / API Error" .-> Tier1
|
|
177
178
|
Tier1 -. "❌ Blocked / API Error" .-> Tier2
|
|
178
|
-
Tier2 -. "🆘 Safety Net Downgrade" .->
|
|
179
|
+
Tier2 -. "🆘 Safety Net Downgrade" .-> Tier3
|
|
179
180
|
end
|
|
180
181
|
|
|
181
182
|
end
|
|
@@ -30,13 +30,13 @@ When you're deeply immersed in your coding "zone" with **Claude Code** (or any A
|
|
|
30
30
|
## 🌟 Core Features
|
|
31
31
|
|
|
32
32
|
<div align="center">
|
|
33
|
-
<img src="assets/dashboard-v0.2.
|
|
33
|
+
<img src="assets/dashboard-v0.2.4.png">
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
|
-
- **⛓️ N-tier Chained Failover**: Autonomous descending sequence, supporting Claude's official plans, as well as Coding Plans from GitHub Copilot, Z AI, MiniMax, Alibaba Qwen, Xiaomi, Kimi, Doubao, etc.
|
|
36
|
+
- **⛓️ N-tier Chained Failover**: Autonomous descending sequence, supporting Claude's official plans, as well as Coding Plans from GitHub Copilot, Google Antigravity, Z AI, MiniMax, Alibaba Qwen, Xiaomi, Kimi, Doubao, etc.
|
|
37
37
|
- **🛡️ Smart Resilience & Quota Guardians**: Every single vendor node comes fully armed with an independent **Circuit Breaker** and **Quota Guard** to proactively dodge avalanches without breaking a sweat.
|
|
38
38
|
- **👻 Phantom-like Transparency**: **100% transparent** to the client! No code tweaks required. Overwrite `ANTHROPIC_BASE_URL` with a single line, and you're good to go.
|
|
39
|
-
- **🔄 Universal Alchemy (Formats & Models)**: Native support for two-way request/streaming (SSE) translations between Anthropic ←→ Gemini. Plus, auto/DIY model name mapping (e.g., effortlessly morphing `claude-*` into `glm-*`).
|
|
39
|
+
- **🔄 Universal Alchemy (Formats & Models)**: Native support for two-way request/streaming (SSE) translations between Anthropic ←→ Gemini and Anthropic ←→ OpenAI. Plus, auto/DIY model name mapping (e.g., effortlessly morphing `claude-*` into `glm-*`).
|
|
40
40
|
- **📊 Extreme Observability**: Built-in, zero-BS local monitoring powered by a `SQLite WAL`. The CLI provides a one-click detailed Token usage dashboard (`coding-proxy usage`).
|
|
41
41
|
- **⚡ Featherweight Standalone Deployment**: A fully asynchronous architecture (`FastAPI` + `httpx`). Zero dependency on Redis, message queues, or other heavy machinery—absolutely no extra baggage for your dev rig.
|
|
42
42
|
|
|
@@ -70,9 +70,9 @@ uv run coding-proxy start
|
|
|
70
70
|
# INFO: Started server process [1403]
|
|
71
71
|
# INFO: Waiting for application startup.
|
|
72
72
|
# ...
|
|
73
|
-
# INFO: coding-proxy started: host=127.0.0.1 port=
|
|
73
|
+
# INFO: coding-proxy started: host=127.0.0.1 port=3392
|
|
74
74
|
# INFO: Application startup complete.
|
|
75
|
-
# INFO: Uvicorn running on http://127.0.0.1:
|
|
75
|
+
# INFO: Uvicorn running on http://127.0.0.1:3392 (Press CTRL+C to quit)
|
|
76
76
|
```
|
|
77
77
|
|
|
78
78
|
### 4. Seamless Claude Code Integration
|
|
@@ -80,7 +80,7 @@ uv run coding-proxy start
|
|
|
80
80
|
Open a fresh terminal tab and route your traffic through coding-proxy before firing up Claude Code:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
export ANTHROPIC_BASE_URL=http://127.0.0.1:
|
|
83
|
+
export ANTHROPIC_BASE_URL=http://127.0.0.1:3392
|
|
84
84
|
|
|
85
85
|
# Enjoy blissful, silky-smooth, and uninterrupted coding nirvana:
|
|
86
86
|
claude
|
|
@@ -92,12 +92,13 @@ claude
|
|
|
92
92
|
|
|
93
93
|
`coding-proxy` comes equipped with a badass suite of CLI tools to help you boss around your proxy state.
|
|
94
94
|
|
|
95
|
-
| Command | Description
|
|
96
|
-
| :------- |
|
|
97
|
-
| `start` | **Fire up the proxy server.** Supports custom ports and configuration paths.
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
95
|
+
| Command | Description | Example Usage |
|
|
96
|
+
| :------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------- |
|
|
97
|
+
| `start` | **Fire up the proxy server.** Supports custom ports and configuration paths. | `coding-proxy start -p 8080 -c ~/config.yaml` |
|
|
98
|
+
| `auth` | **Manage OAuth credentials.** Sub-commands: `login` (browser OAuth), `status` (token validity), `reauth` (re-authenticate), `logout` (clear tokens). | `coding-proxy auth login -p github` |
|
|
99
|
+
| `status` | **Check proxy health.** Shows circuit breaker states (OPEN/CLOSED) and quota status across all tiers. | `coding-proxy status` |
|
|
100
|
+
| `usage` | **Token Stats Dashboard.** Stalks every single token consumed, failovers triggered, and latency across day/vendor/model dimensions. | `coding-proxy usage -d 7 -v anthropic` |
|
|
101
|
+
| `reset` | **The emergency flush button.** Force-reset all circuit breakers and quotas instantly when you've confirmed the main vendor is back from the dead. | `coding-proxy reset` |
|
|
101
102
|
|
|
102
103
|
---
|
|
103
104
|
|
|
@@ -126,29 +127,29 @@ graph RL
|
|
|
126
127
|
subgraph NTier["N-tier"]
|
|
127
128
|
direction TB
|
|
128
129
|
|
|
129
|
-
subgraph Tier0 ["Tier 0:
|
|
130
|
+
subgraph Tier0 ["Tier 0: Zhipu"]
|
|
130
131
|
direction RL
|
|
131
|
-
G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("
|
|
132
|
+
G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("GLM API")):::api
|
|
132
133
|
end
|
|
133
134
|
|
|
134
|
-
subgraph Tier1 ["Tier 1:
|
|
135
|
+
subgraph Tier1 ["Tier 1: Anthropic"]
|
|
135
136
|
direction RL
|
|
136
|
-
G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("
|
|
137
|
+
G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Anthropic API")):::api
|
|
137
138
|
end
|
|
138
139
|
|
|
139
|
-
subgraph Tier2 ["Tier 2:
|
|
140
|
+
subgraph Tier2 ["Tier 2: GitHub Copilot"]
|
|
140
141
|
direction RL
|
|
141
|
-
G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("
|
|
142
|
+
G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Copilot API")):::api
|
|
142
143
|
end
|
|
143
144
|
|
|
144
|
-
subgraph
|
|
145
|
+
subgraph Tier3 ["Tier 3: Google Antigravity"]
|
|
145
146
|
direction RL
|
|
146
|
-
|
|
147
|
+
API3(("Gemini API")):::fallback
|
|
147
148
|
end
|
|
148
149
|
|
|
149
150
|
Tier0 -. "❌ Blocked / API Error" .-> Tier1
|
|
150
151
|
Tier1 -. "❌ Blocked / API Error" .-> Tier2
|
|
151
|
-
Tier2 -. "🆘 Safety Net Downgrade" .->
|
|
152
|
+
Tier2 -. "🆘 Safety Net Downgrade" .-> Tier3
|
|
152
153
|
end
|
|
153
154
|
|
|
154
155
|
end
|
|
Binary file
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# 配置字段参考
|
|
2
|
+
|
|
3
|
+
> **路径约定**:本文档中模块路径均相对于 `src/coding/proxy/`。
|
|
4
|
+
>
|
|
5
|
+
> **定位**:本文档是所有配置参数的**规范来源(Single Source of Truth)**。设计模式章节和模块详情中引用参数默认值时,统一链接至此。
|
|
6
|
+
|
|
7
|
+
[TOC]
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. 配置模块结构
|
|
12
|
+
|
|
13
|
+
配置模型已从单体 `schema.py` 正交拆分为 5 个子模块:
|
|
14
|
+
|
|
15
|
+
| 子模块 | 文件 | 核心类型 |
|
|
16
|
+
| --------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
17
|
+
| **server** | [`config/server.py`](../../src/coding/proxy/config/server.py) | `ServerConfig`, `DatabaseConfig`, `LoggingConfig` |
|
|
18
|
+
| **vendors** | [`config/vendors.py`](../../src/coding/proxy/config/vendors.py) | `AnthropicConfig`, `CopilotConfig`, `AntigravityConfig`, `ZhipuConfig`, `MinimaxConfig`, `KimiConfig`, `DoubaoConfig`, `XiaomiConfig`, `AlibabaConfig` |
|
|
19
|
+
| **resiliency** | [`config/resiliency.py`](../../src/coding/proxy/config/resiliency.py) | `CircuitBreakerConfig`, `RetryConfig`, `FailoverConfig`, `QuotaGuardConfig` |
|
|
20
|
+
| **routing** | [`config/routing.py`](../../src/coding/proxy/config/routing.py) | `VendorType`, `VendorConfig`, `ModelMappingRule`, `ModelPricingEntry` |
|
|
21
|
+
| **auth_schema** | [`config/auth_schema.py`](../../src/coding/proxy/config/auth_schema.py) | `AuthConfig` |
|
|
22
|
+
|
|
23
|
+
`config/schema.py` 作为聚合入口点 re-export 所有符号,并保留 `ProxyConfig` 顶层模型及旧格式迁移逻辑。
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## 2. 配置搜索优先级
|
|
28
|
+
|
|
29
|
+
[`config/loader.py`](../../src/coding/proxy/config/loader.py) 按以下顺序搜索配置文件:
|
|
30
|
+
|
|
31
|
+
```mermaid
|
|
32
|
+
flowchart TD
|
|
33
|
+
A["CLI --config 参数<br/>(显式指定)"] -->|"未指定"| B["./config.yaml<br/>(项目根目录)"]
|
|
34
|
+
B -->|"不存在"| C["~/.coding-proxy/config.yaml<br/>(用户目录)"]
|
|
35
|
+
C -->|"不存在"| D["Pydantic 默认值"]
|
|
36
|
+
|
|
37
|
+
style A fill:#1a5276,color:#fff
|
|
38
|
+
style D fill:#7b241c,color:#fff
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**环境变量展开**:语法 `${VARIABLE_NAME}`,递归处理 dict/list/str,未定义变量保留原文。
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 3. 服务器配置
|
|
46
|
+
|
|
47
|
+
### 3.1 ServerConfig
|
|
48
|
+
|
|
49
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
50
|
+
| ------ | ---- | ------------- | -------- |
|
|
51
|
+
| `host` | str | `"127.0.0.1"` | 监听地址 |
|
|
52
|
+
| `port` | int | `3392` | 监听端口 |
|
|
53
|
+
|
|
54
|
+
### 3.2 DatabaseConfig
|
|
55
|
+
|
|
56
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
57
|
+
| -------------------------- | ---- | ----------------------------- | --------------------- |
|
|
58
|
+
| `path` | str | `"~/.coding-proxy/usage.db"` | SQLite 数据库文件路径 |
|
|
59
|
+
| `compat_state_path` | str | `"~/.coding-proxy/compat.db"` | 兼容性会话存储路径 |
|
|
60
|
+
| `compat_state_ttl_seconds` | int | `86400` | 兼容性会话 TTL(秒) |
|
|
61
|
+
|
|
62
|
+
### 3.3 LoggingConfig
|
|
63
|
+
|
|
64
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
65
|
+
| -------------- | ----------- | --------- | ---------------------------------------- |
|
|
66
|
+
| `level` | str | `"INFO"` | 控制台日志级别 |
|
|
67
|
+
| `file` | str \| null | `null` | 文件日志路径(`null` 时输出到控制台) |
|
|
68
|
+
| `max_bytes` | int | `5242880` | 单个日志文件最大字节数(5 MB),触发轮转 |
|
|
69
|
+
| `backup_count` | int | `5` | 保留的已压缩备份文件数 |
|
|
70
|
+
|
|
71
|
+
### 3.4 AuthConfig
|
|
72
|
+
|
|
73
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
74
|
+
| ------------------ | ---- | ------ | ------------------------------------ |
|
|
75
|
+
| `token_store_path` | str | `""` | Token Store 文件路径(空则使用默认) |
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 4. VendorConfig 通用字段
|
|
80
|
+
|
|
81
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
82
|
+
| ------------ | ---- | -------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
83
|
+
| `vendor` | enum | -- | 供应商类型:`anthropic` / `copilot` / `antigravity` / `zhipu` / `minimax` / `kimi` / `doubao` / `xiaomi` / `alibaba` |
|
|
84
|
+
| `enabled` | bool | `true` | 是否启用 |
|
|
85
|
+
| `base_url` | str | `""` | API 基础 URL(留空使用各供应商默认值) |
|
|
86
|
+
| `timeout_ms` | int | `300000` | 请求超时(毫秒) |
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 5. VendorConfig 弹性字段
|
|
91
|
+
|
|
92
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
93
|
+
| -------------------- | -------------- | -------------------- | --------------------------- |
|
|
94
|
+
| `circuit_breaker` | config \| None | `None` | 熔断器配置(None = 终端层) |
|
|
95
|
+
| `retry` | config | `RetryConfig()` | 重试策略配置 |
|
|
96
|
+
| `quota_guard` | config | `QuotaGuardConfig()` | 日度配额守卫配置 |
|
|
97
|
+
| `weekly_quota_guard` | config | `QuotaGuardConfig()` | 周度配额守卫配置 |
|
|
98
|
+
|
|
99
|
+
<a id="elastic-params"></a>
|
|
100
|
+
|
|
101
|
+
### 5.1 CircuitBreakerConfig — 熔断器参数
|
|
102
|
+
|
|
103
|
+
> **设计语义**:参见 [设计模式 -- Circuit Breaker](./design-patterns.md#circuit-breaker)
|
|
104
|
+
|
|
105
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
106
|
+
| -------------------------- | ---- | ------ | --------------------------------- |
|
|
107
|
+
| `failure_threshold` | int | `3` | 触发 OPEN 的连续失败次数 |
|
|
108
|
+
| `recovery_timeout_seconds` | int | `300` | OPEN → HALF_OPEN 等待秒数 |
|
|
109
|
+
| `success_threshold` | int | `2` | HALF_OPEN → CLOSED 所需连续成功数 |
|
|
110
|
+
| `max_recovery_seconds` | int | `3600` | 指数退避最大恢复时间(秒) |
|
|
111
|
+
|
|
112
|
+
### 5.2 QuotaGuardConfig — 配额守卫参数
|
|
113
|
+
|
|
114
|
+
> **设计语义**:参见 [设计模式 -- QuotaGuard State Machine](./design-patterns.md#quota-guard)
|
|
115
|
+
|
|
116
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
117
|
+
| ------------------------ | ----- | ------- | ------------------------------------ |
|
|
118
|
+
| `enabled` | bool | `false` | 是否启用配额守卫 |
|
|
119
|
+
| `token_budget` | int | `0` | 滑动窗口内的 Token 预算上限 |
|
|
120
|
+
| `window_hours` | float | `5.0` | 滑动窗口大小(小时) |
|
|
121
|
+
| `threshold_percent` | float | `99.0` | 触发 QUOTA_EXCEEDED 的用量百分比阈值 |
|
|
122
|
+
| `probe_interval_seconds` | int | `300` | QUOTA_EXCEEDED 状态下探测间隔(秒) |
|
|
123
|
+
|
|
124
|
+
### 5.3 RetryConfig — 重试策略参数
|
|
125
|
+
|
|
126
|
+
> **设计语义**:参见 [设计模式 -- Retry with Full Jitter](./design-patterns.md#retry)
|
|
127
|
+
|
|
128
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
129
|
+
| -------------------- | ----- | ------ | ---------------- |
|
|
130
|
+
| `max_retries` | int | `2` | 最大重试次数 |
|
|
131
|
+
| `initial_delay_ms` | int | `500` | 初始延迟(毫秒) |
|
|
132
|
+
| `max_delay_ms` | int | `5000` | 最大延迟(毫秒) |
|
|
133
|
+
| `backoff_multiplier` | float | `2.0` | 退避倍数 |
|
|
134
|
+
| `jitter` | bool | `true` | 是否启用抖动 |
|
|
135
|
+
|
|
136
|
+
### 5.4 FailoverConfig — 故障转移参数
|
|
137
|
+
|
|
138
|
+
> **设计语义**:参见 [请求生命周期 -- 故障转移判定](../framework.md#fault-overhead)
|
|
139
|
+
|
|
140
|
+
| 字段 | 类型 | 默认值 |
|
|
141
|
+
| ------------------------ | --------- | ---------------------------------------------------------------------------------- |
|
|
142
|
+
| `status_codes` | list[int] | `[429, 403, 503, 500, 529]` |
|
|
143
|
+
| `error_types` | list[str] | `["rate_limit_error", "overloaded_error", "api_error"]` |
|
|
144
|
+
| `error_message_patterns` | list[str] | `["quota", "limit exceeded", "usage cap", "capacity", "internal network failure"]` |
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## 6. 供应商专属字段
|
|
149
|
+
|
|
150
|
+
### 6.1 Copilot 专属字段
|
|
151
|
+
|
|
152
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
153
|
+
| -------------------------- | ---- | --------------- | -------------------------------------------------- |
|
|
154
|
+
| `github_token` | str | `""` | GitHub OAuth token / PAT(支持 `${ENV_VAR}`) |
|
|
155
|
+
| `account_type` | str | `"individual"` | 账号类型:`individual` / `business` / `enterprise` |
|
|
156
|
+
| `token_url` | str | `"https://..."` | Token 交换端点 |
|
|
157
|
+
| `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL |
|
|
158
|
+
|
|
159
|
+
### 6.2 Antigravity 专属字段
|
|
160
|
+
|
|
161
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
162
|
+
| ---------------- | ---- | ----------------------------------- | --------------------------- |
|
|
163
|
+
| `client_id` | str | `""` | Google OAuth2 Client ID |
|
|
164
|
+
| `client_secret` | str | `""` | Google OAuth2 Client Secret |
|
|
165
|
+
| `refresh_token` | str | `""` | Google OAuth2 Refresh Token |
|
|
166
|
+
| `model_endpoint` | str | `"models/claude-sonnet-4-20250514"` | Gemini 模型端点路径 |
|
|
167
|
+
|
|
168
|
+
### 6.3 原生 Anthropic 兼容供应商共用字段
|
|
169
|
+
|
|
170
|
+
适用于 `zhipu` / `minimax` / `kimi` / `doubao` / `xiaomi` / `alibaba`。
|
|
171
|
+
|
|
172
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
173
|
+
| --------- | ---- | ------ | ---------------------------- |
|
|
174
|
+
| `api_key` | str | `""` | API Key(支持 `${ENV_VAR}`) |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## 7. 模型映射规则
|
|
179
|
+
|
|
180
|
+
### 7.1 ModelMappingRule 字段
|
|
181
|
+
|
|
182
|
+
| 字段 | 类型 | 说明 |
|
|
183
|
+
| ---------- | --------- | ------------------------------------------ |
|
|
184
|
+
| `pattern` | str | 匹配模式(精确/通配符/正则) |
|
|
185
|
+
| `target` | str | 目标模型名称 |
|
|
186
|
+
| `is_regex` | bool | 是否为正则表达式(默认 `false`) |
|
|
187
|
+
| `vendors` | list[str] | 规则作用域(留空应用于所有原生兼容供应商) |
|
|
188
|
+
|
|
189
|
+
### 7.2 ModelPricingEntry 字段
|
|
190
|
+
|
|
191
|
+
| 字段 | 类型 | 说明 |
|
|
192
|
+
| --------------------------- | ----- | -------------------------------------------------- |
|
|
193
|
+
| `vendor` | str | 供应商名称 |
|
|
194
|
+
| `model` | str | 实际模型名 |
|
|
195
|
+
| `input_cost_per_mtok` | float | 输入 Token 单价($/百万 token,支持 `$`/`¥` 前缀) |
|
|
196
|
+
| `output_cost_per_mtok` | float | 输出 Token 单价 |
|
|
197
|
+
| `cache_write_cost_per_mtok` | float | 缓存创建 Token 单价 |
|
|
198
|
+
| `cache_read_cost_per_mtok` | float | 缓存读取 Token 单价 |
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 8. tiers — 显式优先级
|
|
203
|
+
|
|
204
|
+
| 字段 | 类型 | 说明 |
|
|
205
|
+
| ------- | ------------------------ | ------------------------------------------ |
|
|
206
|
+
| `tiers` | list[VendorType] \| None | 降级链路优先级(None 时回退 vendors 顺序) |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 9. vendors 列表格式(推荐)
|
|
211
|
+
|
|
212
|
+
推荐使用 `vendors` 列表格式,每个 vendor 自包含其弹性配置:
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
vendors:
|
|
216
|
+
- vendor: anthropic
|
|
217
|
+
enabled: true
|
|
218
|
+
base_url: https://api.anthropic.com
|
|
219
|
+
timeout_ms: 300000
|
|
220
|
+
circuit_breaker:
|
|
221
|
+
failure_threshold: 3
|
|
222
|
+
recovery_timeout_seconds: 300
|
|
223
|
+
quota_guard:
|
|
224
|
+
enabled: false
|
|
225
|
+
weekly_quota_guard:
|
|
226
|
+
enabled: false
|
|
227
|
+
|
|
228
|
+
- vendor: copilot
|
|
229
|
+
enabled: false
|
|
230
|
+
github_token: "${GITHUB_TOKEN}"
|
|
231
|
+
account_type: individual
|
|
232
|
+
circuit_breaker:
|
|
233
|
+
failure_threshold: 3
|
|
234
|
+
quota_guard:
|
|
235
|
+
enabled: true
|
|
236
|
+
token_budget: 3000000
|
|
237
|
+
window_hours: 4.0
|
|
238
|
+
|
|
239
|
+
- vendor: zhipu
|
|
240
|
+
enabled: true
|
|
241
|
+
api_key: "${ZHIPU_API_KEY}"
|
|
242
|
+
# 无 circuit_breaker -> 终端层
|
|
243
|
+
|
|
244
|
+
- vendor: minimax
|
|
245
|
+
enabled: false
|
|
246
|
+
api_key: "${MINIMAX_API_KEY}"
|
|
247
|
+
|
|
248
|
+
tiers: [anthropic, copilot, zhipu] # 显式优先级(可选)
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Legacy Flat 格式(向后兼容)
|
|
252
|
+
|
|
253
|
+
旧的 flat 格式字段(`primary`/`copilot`/`antigravity`/`fallback`/`circuit_breaker`/`*_quota_guard`)仍受支持,通过 `ProxyConfig._migrate_legacy_fields()` 自动迁移为 vendors 列表格式。
|
|
254
|
+
|
|
255
|
+
迁移规则:
|
|
256
|
+
1. `anthropic` 字段名 → `primary`
|
|
257
|
+
2. `zhipu` 字段名 → `fallback`
|
|
258
|
+
3. 若无 `vendors` 字段,从 legacy flat 字段自动生成 vendors 列表
|
|
259
|
+
4. 迁移时发出 INFO 日志建议迁移至新格式
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## 10. native_api — 原生 API 透传配置
|
|
264
|
+
|
|
265
|
+
> **定义位置**:[`native_api/config.py`](../../src/coding/proxy/native_api/config.py)
|
|
266
|
+
>
|
|
267
|
+
> **端点**:`/api/{openai,gemini,anthropic}/**` catch-all 透传通道;认证头由客户端自带,proxy 不保管凭据。
|
|
268
|
+
|
|
269
|
+
### 10.1 NativeApiConfig 顶层字段
|
|
270
|
+
|
|
271
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
272
|
+
| ------------- | ---------------------- | -------------------------------------- | ----------------------------------------- |
|
|
273
|
+
| `openai` | `NativeProviderConfig` | 内置官方 URL,`enabled=true` | OpenAI chat / responses / embeddings 等 |
|
|
274
|
+
| `gemini` | `NativeProviderConfig` | 内置官方 URL,`enabled=true` | Gemini generateContent / embedContent 等 |
|
|
275
|
+
| `anthropic` | `NativeProviderConfig` | 内置官方 URL,`enabled=true` | Anthropic messages / count_tokens / batches |
|
|
276
|
+
|
|
277
|
+
### 10.2 NativeProviderConfig 字段
|
|
278
|
+
|
|
279
|
+
| 字段 | 类型 | 默认值 | 说明 |
|
|
280
|
+
| --------------------- | ---- | ------------------- | --------------------------------------------------------------------- |
|
|
281
|
+
| `enabled` | bool | `true` | 是否启用该 provider 的原生透传端点(默认启用,开箱即用) |
|
|
282
|
+
| `base_url` | str | 见下方内置默认 | 上游 API base_url(纯域名前缀,不含 `/v1`) |
|
|
283
|
+
| `timeout_ms` | int | `300000` | 单次请求超时(毫秒),LLM 大模型建议 ≥ 120s |
|
|
284
|
+
| `connect_timeout_ms` | int | `15000` | 连接建立超时(毫秒) |
|
|
285
|
+
|
|
286
|
+
### 10.3 内置默认 `base_url`
|
|
287
|
+
|
|
288
|
+
| Provider | 内置默认 |
|
|
289
|
+
| ------------ | ----------------------------------------------------- |
|
|
290
|
+
| `openai` | `https://api.openai.com` |
|
|
291
|
+
| `gemini` | `https://generativelanguage.googleapis.com` |
|
|
292
|
+
| `anthropic` | `https://api.anthropic.com` |
|
|
293
|
+
|
|
294
|
+
### 10.4 `base_url` 三级覆写优先级
|
|
295
|
+
|
|
296
|
+
由 `NativeApiConfig._apply_env_overrides` `@model_validator(mode="after")` 注入:
|
|
297
|
+
|
|
298
|
+
```text
|
|
299
|
+
env var(运行时) > YAML 显式字段(部署时) > Pydantic 内置默认(兜底)
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
| 环境变量 | 覆写目标 |
|
|
303
|
+
| ---------------------------- | ------------------------- |
|
|
304
|
+
| `NATIVE_OPENAI_BASE_URL` | `openai.base_url` |
|
|
305
|
+
| `NATIVE_GEMINI_BASE_URL` | `gemini.base_url` |
|
|
306
|
+
| `NATIVE_ANTHROPIC_BASE_URL` | `anthropic.base_url` |
|
|
307
|
+
|
|
308
|
+
空串或纯空白视作未设置,保留上一层值(避免"未设置 env → 空串覆盖内置默认"陷阱)。
|
|
309
|
+
|
|
310
|
+
> `ANTHROPIC_BASE_URL`(client → proxy,Claude Code 使用)与 `NATIVE_ANTHROPIC_BASE_URL`(proxy → upstream,原生透传使用)方向正交,勿混用。参见 [用户指引 § 4.7 native_api](../user-guide.md#47-native_api--原生-api-透传)。
|