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.
Files changed (183) hide show
  1. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/CHANGELOG.md +19 -1
  2. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/PKG-INFO +23 -22
  3. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/README.md +22 -21
  4. coding_proxy-0.3.0/assets/dashboard-v0.2.4.png +0 -0
  5. coding_proxy-0.3.0/docs/arch/config-reference.md +310 -0
  6. coding_proxy-0.3.0/docs/arch/convert.md +101 -0
  7. coding_proxy-0.3.0/docs/arch/design-patterns.md +607 -0
  8. coding_proxy-0.3.0/docs/arch/routing.md +180 -0
  9. coding_proxy-0.3.0/docs/arch/testing.md +114 -0
  10. coding_proxy-0.3.0/docs/arch/vendors.md +404 -0
  11. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/docs/ci-cd.md +41 -41
  12. coding_proxy-0.3.0/docs/framework.md +490 -0
  13. coding_proxy-0.3.0/docs/guide/api-reference.md +362 -0
  14. coding_proxy-0.3.0/docs/guide/cli-reference.md +238 -0
  15. coding_proxy-0.3.0/docs/guide/dashboard.md +63 -0
  16. coding_proxy-0.3.0/docs/guide/monitoring.md +207 -0
  17. coding_proxy-0.3.0/docs/guide/quickstart.md +103 -0
  18. coding_proxy-0.3.0/docs/guide/vendors.md +247 -0
  19. coding_proxy-0.3.0/docs/user-guide.md +290 -0
  20. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/docs/zh-CN/README.md +22 -21
  21. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/pyproject.toml +1 -1
  22. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/cli/__init__.py +2 -2
  23. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/cli/auth_commands.py +1 -1
  24. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/cli/banner.py +2 -2
  25. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/config.default.yaml +126 -1
  26. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/schema.py +11 -0
  27. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/server.py +1 -1
  28. coding_proxy-0.3.0/src/coding/proxy/convert/vendor_channels.py +546 -0
  29. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/db.py +78 -11
  30. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/stats.py +102 -26
  31. coding_proxy-0.3.0/src/coding/proxy/native_api/__init__.py +84 -0
  32. coding_proxy-0.3.0/src/coding/proxy/native_api/config.py +110 -0
  33. coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/__init__.py +12 -0
  34. coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/anthropic.py +111 -0
  35. coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/gemini.py +112 -0
  36. coding_proxy-0.3.0/src/coding/proxy/native_api/extractors/openai.py +231 -0
  37. coding_proxy-0.3.0/src/coding/proxy/native_api/handler.py +485 -0
  38. coding_proxy-0.3.0/src/coding/proxy/native_api/operation.py +167 -0
  39. coding_proxy-0.3.0/src/coding/proxy/native_api/routes.py +68 -0
  40. coding_proxy-0.3.0/src/coding/proxy/native_api/usage_registry.py +279 -0
  41. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/pricing.py +17 -1
  42. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/executor.py +58 -102
  43. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/router.py +2 -8
  44. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/usage_parser.py +65 -5
  45. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/usage_recorder.py +39 -1
  46. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/app.py +26 -0
  47. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/dashboard.py +23 -8
  48. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/routes.py +35 -24
  49. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/anthropic.py +2 -1
  50. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_app_routes.py +17 -20
  51. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_banner.py +2 -2
  52. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_config_init.py +1 -1
  53. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_config_loader.py +6 -6
  54. coding_proxy-0.3.0/tests/test_native_api_base_url_override.py +166 -0
  55. coding_proxy-0.3.0/tests/test_native_api_extractors.py +331 -0
  56. coding_proxy-0.3.0/tests/test_native_api_handler.py +374 -0
  57. coding_proxy-0.3.0/tests/test_native_api_operation.py +130 -0
  58. coding_proxy-0.3.0/tests/test_native_api_routes.py +132 -0
  59. coding_proxy-0.3.0/tests/test_parse_usage_gemini.py +196 -0
  60. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_router_executor.py +265 -95
  61. coding_proxy-0.3.0/tests/test_token_logger_native_columns.py +334 -0
  62. coding_proxy-0.3.0/tests/test_vendor_channels.py +1731 -0
  63. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_zhipu.py +1 -1
  64. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/uv.lock +1 -1
  65. coding_proxy-0.2.4a4/assets/dashboard-v0.2.3.png +0 -0
  66. coding_proxy-0.2.4a4/docs/framework.md +0 -1640
  67. coding_proxy-0.2.4a4/docs/user-guide.md +0 -1771
  68. coding_proxy-0.2.4a4/src/coding/proxy/server/request_normalizer.py +0 -685
  69. coding_proxy-0.2.4a4/tests/test_request_normalizer.py +0 -1494
  70. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.github/workflows/ci.yml +0 -0
  71. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.github/workflows/coverage.yml +0 -0
  72. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.github/workflows/release.yml +0 -0
  73. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.gitignore +0 -0
  74. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/.pre-commit-config.yaml +0 -0
  75. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/AGENTS.md +0 -0
  76. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/CLAUDE.md +0 -0
  77. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/LICENSE +0 -0
  78. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/__init__.py +0 -0
  79. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/__init__.py +0 -0
  80. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/__main__.py +0 -0
  81. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/__init__.py +0 -0
  82. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/__init__.py +0 -0
  83. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/base.py +0 -0
  84. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/github.py +0 -0
  85. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/providers/google.py +0 -0
  86. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/runtime.py +0 -0
  87. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/auth/store.py +0 -0
  88. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/compat/__init__.py +0 -0
  89. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/compat/canonical.py +0 -0
  90. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/compat/session_store.py +0 -0
  91. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/__init__.py +0 -0
  92. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/auth_schema.py +0 -0
  93. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/loader.py +0 -0
  94. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/resiliency.py +0 -0
  95. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/routing.py +0 -0
  96. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/config/vendors.py +0 -0
  97. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/__init__.py +0 -0
  98. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/anthropic_to_gemini.py +0 -0
  99. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/anthropic_to_openai.py +0 -0
  100. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/gemini_sse_adapter.py +0 -0
  101. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/gemini_to_anthropic.py +0 -0
  102. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/convert/openai_to_anthropic.py +0 -0
  103. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/__init__.py +0 -0
  104. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/logging/formatters.py +0 -0
  105. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/__init__.py +0 -0
  106. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/auth.py +0 -0
  107. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/compat.py +0 -0
  108. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/constants.py +0 -0
  109. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/pricing.py +0 -0
  110. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/token.py +0 -0
  111. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/model/vendor.py +0 -0
  112. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/__init__.py +0 -0
  113. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/circuit_breaker.py +0 -0
  114. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/error_classifier.py +0 -0
  115. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/model_mapper.py +0 -0
  116. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/quota_guard.py +0 -0
  117. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/rate_limit.py +0 -0
  118. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/retry.py +0 -0
  119. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/session_manager.py +0 -0
  120. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/routing/tier.py +0 -0
  121. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/__init__.py +0 -0
  122. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/factory.py +0 -0
  123. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/server/responses.py +0 -0
  124. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/streaming/__init__.py +0 -0
  125. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/streaming/anthropic_compat.py +0 -0
  126. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/__init__.py +0 -0
  127. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/alibaba.py +0 -0
  128. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/antigravity.py +0 -0
  129. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/base.py +0 -0
  130. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot.py +0 -0
  131. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot_models.py +0 -0
  132. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot_token_manager.py +0 -0
  133. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/copilot_urls.py +0 -0
  134. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/doubao.py +0 -0
  135. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/kimi.py +0 -0
  136. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/minimax.py +0 -0
  137. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/mixins.py +0 -0
  138. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/native_anthropic.py +0 -0
  139. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/token_manager.py +0 -0
  140. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/xiaomi.py +0 -0
  141. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/src/coding/proxy/vendors/zhipu.py +0 -0
  142. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/__init__.py +0 -0
  143. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_antigravity.py +0 -0
  144. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_auto_login.py +0 -0
  145. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_circuit_breaker.py +0 -0
  146. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_cli_usage.py +0 -0
  147. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_compat.py +0 -0
  148. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_convert_request.py +0 -0
  149. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_convert_response.py +0 -0
  150. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_convert_sse.py +0 -0
  151. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot.py +0 -0
  152. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_convert_request.py +0 -0
  153. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_convert_response.py +0 -0
  154. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_models.py +0 -0
  155. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_copilot_urls.py +0 -0
  156. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_currency.py +0 -0
  157. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_error_classifier.py +0 -0
  158. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_logging_dual_write.py +0 -0
  159. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_mixins.py +0 -0
  160. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_auth.py +0 -0
  161. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_compat.py +0 -0
  162. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_constants.py +0 -0
  163. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_mapper.py +0 -0
  164. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_pricing.py +0 -0
  165. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_token.py +0 -0
  166. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_model_vendor.py +0 -0
  167. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_native_vendors.py +0 -0
  168. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_parse_usage.py +0 -0
  169. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_pricing.py +0 -0
  170. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_quota_guard.py +0 -0
  171. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_rate_limit.py +0 -0
  172. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_router_chain.py +0 -0
  173. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_runtime_reauth.py +0 -0
  174. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_schema.py +0 -0
  175. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_streaming_anthropic_compat.py +0 -0
  176. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_tier.py +0 -0
  177. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_tiers_config.py +0 -0
  178. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_time_range.py +0 -0
  179. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_token_logger.py +0 -0
  180. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_token_manager.py +0 -0
  181. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_types.py +0 -0
  182. {coding_proxy-0.2.4a4 → coding_proxy-0.3.0}/tests/test_vendor_streaming.py +0 -0
  183. {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
- - fix(request-normalizer): 重设计 zhipu→anthropic 跨供应商 tool_use/tool_result 配对修复——以单遍自包含 `enforce_anthropic_tool_pairing` 替代原有多步串联管线(剥离→重定位→孤儿修复),消除步骤间隐式依赖导致的孤儿 tool_use 漏修问题,彻底根治 `tool_use ids were found without tool_result blocks` 400 异常;
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.2.4a4
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.3.png">
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=8046
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:8046 (Press CTRL+C to quit)
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:8046
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 | 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
- | `status` | **Check proxy health.** Shows circuit breaker states (OPEN/CLOSED) and quota status across all tiers. | `coding-proxy status` |
126
- | `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` |
127
- | `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` |
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: Anthropic"]
157
+ subgraph Tier0 ["Tier 0: Zhipu"]
157
158
  direction RL
158
- G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("Anthropic API")):::api
159
+ G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("GLM API")):::api
159
160
  end
160
161
 
161
- subgraph Tier1 ["Tier 1: GitHub Copilot"]
162
+ subgraph Tier1 ["Tier 1: Anthropic"]
162
163
  direction RL
163
- G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Copilot API")):::api
164
+ G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Anthropic API")):::api
164
165
  end
165
166
 
166
- subgraph Tier2 ["Tier 2: Google Antigravity"]
167
+ subgraph Tier2 ["Tier 2: GitHub Copilot"]
167
168
  direction RL
168
- G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Gemini API")):::api
169
+ G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Copilot API")):::api
169
170
  end
170
171
 
171
- subgraph TierN ["Tier N: Zhipu"]
172
+ subgraph Tier3 ["Tier 3: Google Antigravity"]
172
173
  direction RL
173
- APIN(("GLM API")):::fallback
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" .-> TierN
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.3.png">
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=8046
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:8046 (Press CTRL+C to quit)
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:8046
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 | 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
- | `status` | **Check proxy health.** Shows circuit breaker states (OPEN/CLOSED) and quota status across all tiers. | `coding-proxy status` |
99
- | `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` |
100
- | `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` |
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: Anthropic"]
130
+ subgraph Tier0 ["Tier 0: Zhipu"]
130
131
  direction RL
131
- G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("Anthropic API")):::api
132
+ G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("GLM API")):::api
132
133
  end
133
134
 
134
- subgraph Tier1 ["Tier 1: GitHub Copilot"]
135
+ subgraph Tier1 ["Tier 1: Anthropic"]
135
136
  direction RL
136
- G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Copilot API")):::api
137
+ G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Anthropic API")):::api
137
138
  end
138
139
 
139
- subgraph Tier2 ["Tier 2: Google Antigravity"]
140
+ subgraph Tier2 ["Tier 2: GitHub Copilot"]
140
141
  direction RL
141
- G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Gemini API")):::api
142
+ G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Copilot API")):::api
142
143
  end
143
144
 
144
- subgraph TierN ["Tier N: Zhipu"]
145
+ subgraph Tier3 ["Tier 3: Google Antigravity"]
145
146
  direction RL
146
- APIN(("GLM API")):::fallback
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" .-> TierN
152
+ Tier2 -. "🆘 Safety Net Downgrade" .-> Tier3
152
153
  end
153
154
 
154
155
  end
@@ -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-透传)。