From 2ca646ae208151f9584d5b71b029d62d442c69ae Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 11:48:50 +0800 Subject: [PATCH 01/32] =?UTF-8?q?docs(changelog):=20=E4=BF=AE=E6=AD=A3=20v?= =?UTF-8?q?0.2.3=20=E5=8F=91=E5=B8=83=E9=93=BE=E6=8E=A5=E4=B8=8E=E6=97=A5?= =?UTF-8?q?=E6=9C=9F;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c895603..a498dc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ## [Unreleased] -## [v0.2.3](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.2.3a1) — 2026-04-15 +## [v0.2.3](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.2.3) — 2026-04-16 - feat(dashboard): 新增实时 Web Dashboard 页面,聚合展示流量与用量统计; - docs(user-guide): 补充 POST /v1/messages 完整 API 参考文档; From 1b2e2d603d346455457c5364336c1e2f099130d8 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 15:31:37 +0800 Subject: [PATCH 02/32] =?UTF-8?q?style(dashboard):=20=E7=BC=A9=E5=B0=8F?= =?UTF-8?q?=E3=80=8C=E4=BB=8A=E6=97=A5=E8=B4=B9=E7=94=A8=E4=BC=B0=E7=AE=97?= =?UTF-8?q?=E3=80=8D=E5=8D=A1=E7=89=87=E8=B4=B9=E7=94=A8=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E5=AD=97=E4=BD=93=E4=BD=BF=E5=85=B6=E5=8D=95=E8=A1=8C=E6=98=BE?= =?UTF-8?q?=E7=A4=BA;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/server/dashboard.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coding/proxy/server/dashboard.py b/src/coding/proxy/server/dashboard.py index ef8595e..c6f866b 100644 --- a/src/coding/proxy/server/dashboard.py +++ b/src/coding/proxy/server/dashboard.py @@ -201,6 +201,7 @@ def _build_favicon() -> bytes: font-family: 'JetBrains Mono', monospace; letter-spacing: -1px; } + #kpi-cost-today { font-size: 20px; white-space: nowrap; } .kpi-sub { font-size: 13px; color: var(--text-tertiary); margin-top: 5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; } .color-blue { color: var(--accent-blue); } .color-green { color: var(--accent-green); } From 27d7cb048d835570ec94717d55f6e4847866f524 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 21:29:31 +0800 Subject: [PATCH 03/32] =?UTF-8?q?refactor(thinking-strip):=20=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=8C=96=20thinking=20block=20=E5=89=A5=E7=A6=BB?= =?UTF-8?q?=EF=BC=8C=E4=BB=85=E8=B7=A8=E4=BE=9B=E5=BA=94=E5=95=86=E5=9C=BA?= =?UTF-8?q?=E6=99=AF=E8=A7=A6=E5=8F=91;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 thinking block 剥离从 AnthropicVendor._prepare_request()(无条件执行) 提升至 _RouteExecutor._prepare_body_for_tier()(条件执行),基于请求规范化 信号(has_cross_vendor_signals)和会话历史信号(provider_state)判断是否 需要剥离。纯 Anthropic 会话中 thinking blocks 保持原样以维持上下文连续性。 - 新增 NormalizationResult.has_cross_vendor_signals 属性 - 迁移 strip_thinking_blocks() 至 request_normalizer.py - 新增 _RouteExecutor._needs_thinking_strip() 条件判断方法 - 补充 count_tokens 端点的安全剥离(无会话上下文时回退到始终剥离) 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/routing/executor.py | 85 ++++- src/coding/proxy/server/request_normalizer.py | 77 +++++ src/coding/proxy/server/routes.py | 7 + src/coding/proxy/vendors/anthropic.py | 55 +--- tests/test_request_normalizer.py | 297 ++++++++++++++++++ tests/test_router_executor.py | 183 +++++++++++ tests/test_vendors.py | 113 +++---- 7 files changed, 671 insertions(+), 146 deletions(-) diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index 1f30c2d..fd3fab9 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -228,33 +228,80 @@ def _prepare_body_for_tier( body: dict[str, Any], tier: VendorTier, normalization: Any = None, + session_record: Any = None, ) -> dict[str, Any]: """为指定 tier 准备请求体,必要时应用 Anthropic 专属修复(Phase 2). - 仅当 tier 为 Anthropic 且 NormalizationResult 标记需要修复时, - 才执行 deep copy + Phase 2 修复,确保 Zhipu 等其他 vendor 不受影响。 + 仅当 tier 为 Anthropic 时才执行以下处理: + 1. tool_result 重定位 + 孤儿修复(需 normalization.has_anthropic_fixes) + 2. 条件化 thinking block 剥离(仅跨供应商场景) + + 确保 Zhipu 等其他 vendor 不受影响。 """ - if normalization is None or not normalization.has_anthropic_fixes: - return body if tier.name != "anthropic": return body - from ..server.request_normalizer import apply_anthropic_specific_fixes + needs_tool_fixes = normalization is not None and normalization.has_anthropic_fixes + needs_thinking_strip = self._needs_thinking_strip(normalization, session_record) - body_for_vendor = copy.deepcopy(body) - fixes = apply_anthropic_specific_fixes( - body_for_vendor.get("messages", []), - normalization.misplaced_tool_results, - normalization.misplaced_log_info, + if not needs_tool_fixes and not needs_thinking_strip: + return body + + from ..server.request_normalizer import ( + apply_anthropic_specific_fixes, + strip_thinking_blocks, ) - if fixes: - logger.debug( - "Applied Anthropic-specific fixes for tier %s: %s", - tier.name, - ", ".join(fixes), + + body_for_vendor = copy.deepcopy(body) + + if needs_tool_fixes: + fixes = apply_anthropic_specific_fixes( + body_for_vendor.get("messages", []), + normalization.misplaced_tool_results, + normalization.misplaced_log_info, ) + if fixes: + logger.debug( + "Applied Anthropic-specific fixes for tier %s: %s", + tier.name, + ", ".join(fixes), + ) + + if needs_thinking_strip: + stripped = strip_thinking_blocks(body_for_vendor) + if stripped: + logger.debug( + "Stripped %d thinking block(s) for cross-vendor compatibility", + stripped, + ) + return body_for_vendor + @staticmethod + def _needs_thinking_strip(normalization: Any, session_record: Any) -> bool: + """判断是否需要剥离 thinking blocks(仅跨供应商场景). + + 信号优先级: + 1. 请求规范化信号 — 当前请求体中检测到跨供应商产物 + 2. 会话历史信号 — provider_state 中存在非 Anthropic 供应商记录 + + 安全默认:当无法确定会话来源时(session_record 为 None), + 回退到始终剥离,确保与 compat_session_store 未配置时的向后兼容。 + """ + # Signal 1: normalization 检测到跨供应商产物 + if normalization is not None and normalization.has_cross_vendor_signals: + return True + # Signal 2: 无会话追踪能力 → 无法判断是否跨供应商 → 安全回退到剥离 + if session_record is None: + return True + # Signal 3: 会话历史中有非 Anthropic 供应商 + if session_record.provider_state: + non_anthropic = {v for v in session_record.provider_state if v != "anthropic"} + if non_anthropic: + return True + # 纯 Anthropic 会话,无跨供应商信号 → 保留 thinking blocks + return False + async def execute_stream( self, body: dict[str, Any], @@ -291,7 +338,9 @@ async def execute_stream( usage: dict[str, Any] = {} try: - body_for_tier = self._prepare_body_for_tier(body, tier, normalization) + body_for_tier = self._prepare_body_for_tier( + body, tier, normalization, session_record=session_record + ) async for chunk in tier.vendor.send_message_stream( body_for_tier, headers ): @@ -455,7 +504,9 @@ async def execute_message( continue try: - body_for_tier = self._prepare_body_for_tier(body, tier, normalization) + body_for_tier = self._prepare_body_for_tier( + body, tier, normalization, session_record=session_record + ) resp = await tier.vendor.send_message(body_for_tier, headers) if resp.status_code < 400: diff --git a/src/coding/proxy/server/request_normalizer.py b/src/coding/proxy/server/request_normalizer.py index cd366b0..fd42065 100644 --- a/src/coding/proxy/server/request_normalizer.py +++ b/src/coding/proxy/server/request_normalizer.py @@ -22,6 +22,13 @@ "server_tool_use_delta", } +# 标识跨供应商迁移产物的 adaptation 名称集合(用于条件化 thinking block 剥离) +_CROSS_VENDOR_ADAPTATIONS = frozenset({ + "vendor_block_removed", + "server_tool_use_id_rewritten_for_anthropic", + "invalid_tool_use_id_rewritten_for_anthropic", +}) + @dataclass class NormalizationResult: @@ -46,6 +53,22 @@ def has_anthropic_fixes(self) -> bool: """是否需要应用 Anthropic 专属修复(重定位 + 孤儿修复).""" return bool(self.misplaced_tool_results) or bool(self.tool_id_map) + @property + def has_cross_vendor_signals(self) -> bool: + """是否检测到跨供应商迁移信号(用于条件化 thinking block 剥离). + + 当请求体中包含非 Anthropic 原生格式的产物(如非标准 tool_use ID、 + 供应商私有块、错位的 tool_result 等)时返回 True。 + """ + if self.tool_id_map: + return True + if self.misplaced_tool_results: + return True + return any( + any(a.startswith(prefix) for prefix in _CROSS_VENDOR_ADAPTATIONS) + for a in self.adaptations + ) + def normalize_anthropic_request(body: dict[str, Any]) -> NormalizationResult: """清洗供应商私有块,尽量恢复为合法 Anthropic Messages 请求. @@ -460,3 +483,57 @@ def _repair_orphaned_tool_use( i += 1 return repaired + + +# ── Phase 2: Thinking block 剥离 ────────────────────────────── + +# 需要从 assistant messages 中剥离的 thinking block 类型 +_THINKING_BLOCK_TYPES = {"thinking", "redacted_thinking"} + + +def strip_thinking_blocks(body: dict[str, Any]) -> int: + """从 assistant messages 中移除 thinking / redacted_thinking blocks. + + Anthropic API 要求 thinking blocks 的 ``signature`` 必须是其签发的有效签名。 + 跨供应商迁移(如 Zhipu → Anthropic)后,conversation history 中可能包含 + 非 Anthropic 签发的 signature,导致 400 ``invalid_request_error``。 + 根据 Anthropic 官方文档,thinking blocks 可以被安全省略,不影响模型行为。 + + 此函数仅在 executor 检测到跨供应商信号时调用(条件化剥离), + 纯 Anthropic 会话中 thinking blocks 保持原样以维持上下文连续性。 + + Args: + body: 请求体(就地修改)。 + + Returns: + 被移除的 thinking block 数量。 + """ + stripped = 0 + for message in body.get("messages", []): + if not isinstance(message, dict) or message.get("role") != "assistant": + continue + content = message.get("content") + if not isinstance(content, list): + continue + original_len = len(content) + new_content = [ + block + for block in content + if not ( + isinstance(block, dict) and block.get("type") in _THINKING_BLOCK_TYPES + ) + ] + removed = original_len - len(new_content) + if removed and not new_content: + # 剥离所有 thinking blocks 后 content 为空 —— + # Anthropic API 要求非末尾 assistant message 的 content 必须非空。 + # 插入最小占位 text block 以保持消息结构合法性。 + new_content = [{"type": "text", "text": "[thinking]"}] + logger.info( + "anthropic: inserted placeholder text block after stripping " + "%d thinking block(s) to avoid empty assistant content", + removed, + ) + message["content"] = new_content + stripped += removed + return stripped diff --git a/src/coding/proxy/server/routes.py b/src/coding/proxy/server/routes.py index 2058a89..d105ebe 100644 --- a/src/coding/proxy/server/routes.py +++ b/src/coding/proxy/server/routes.py @@ -155,6 +155,13 @@ async def count_tokens(request: Request) -> Response: body = await request.json() headers = dict(request.headers) + + # count_tokens 无会话上下文,无法判断 thinking block 来源, + # 安全剥离以防止跨供应商 signature 导致 400 错误。 + from .request_normalizer import strip_thinking_blocks + + strip_thinking_blocks(body) + prepared_body, prepared_headers = await target_vendor._prepare_request( body, headers ) diff --git a/src/coding/proxy/vendors/anthropic.py b/src/coding/proxy/vendors/anthropic.py index e663ad0..df454f1 100644 --- a/src/coding/proxy/vendors/anthropic.py +++ b/src/coding/proxy/vendors/anthropic.py @@ -11,51 +11,6 @@ logger = logging.getLogger(__name__) -# 需要从 assistant messages 中剥离的 thinking block 类型 -_THINKING_BLOCK_TYPES = {"thinking", "redacted_thinking"} - - -def _strip_thinking_blocks(body: dict[str, Any]) -> int: - """从 assistant messages 中移除 thinking / redacted_thinking blocks. - - Anthropic API 要求 thinking blocks 的 ``signature`` 必须是其签发的有效签名。 - 跨供应商迁移(如 Zhipu → Anthropic)后,conversation history 中可能包含 - 非 Anthropic 签发的 signature,导致 400 ``invalid_request_error``。 - 根据 Anthropic 官方文档,thinking blocks 可以被安全省略,不影响模型行为。 - - Returns: - 被移除的 thinking block 数量。 - """ - stripped = 0 - for message in body.get("messages", []): - if not isinstance(message, dict) or message.get("role") != "assistant": - continue - content = message.get("content") - if not isinstance(content, list): - continue - original_len = len(content) - new_content = [ - block - for block in content - if not ( - isinstance(block, dict) and block.get("type") in _THINKING_BLOCK_TYPES - ) - ] - removed = original_len - len(new_content) - if removed and not new_content: - # 剥离所有 thinking blocks 后 content 为空 —— - # Anthropic API 要求非末尾 assistant message 的 content 必须非空。 - # 插入最小占位 text block 以保持消息结构合法性。 - new_content = [{"type": "text", "text": "[thinking]"}] - logger.info( - "anthropic: inserted placeholder text block after stripping " - "%d thinking block(s) to avoid empty assistant content", - removed, - ) - message["content"] = new_content - stripped += removed - return stripped - def _strip_misplaced_tool_results(body: dict[str, Any]) -> int: """从非 user 角色的消息中剥离 tool_result blocks(纵深防御). @@ -131,19 +86,13 @@ async def _prepare_request( request_body: dict[str, Any], headers: dict[str, str], ) -> tuple[dict[str, Any], dict[str, str]]: - """深拷贝请求体、剥离历史 thinking blocks 和错位的 tool_result blocks,过滤无关请求头. + """深拷贝请求体、剥离错位的 tool_result blocks,过滤无关请求头. 深拷贝确保 Anthropic 的请求体修改不会污染后续 tier 的输入。 - 剥离 thinking blocks 防止跨供应商 signature 不兼容导致 400 错误。 + thinking block 剥离已提升至 executor 层条件执行(仅跨供应商场景)。 剥离错位的 tool_result blocks 防止跨供应商 tool_result 放置位置不合规导致 400 错误。 """ body = copy.deepcopy(request_body) - stripped_thinking = _strip_thinking_blocks(body) - if stripped_thinking: - logger.debug( - "anthropic: stripped %d thinking block(s) from conversation history", - stripped_thinking, - ) stripped_tool_results = _strip_misplaced_tool_results(body) if stripped_tool_results: diff --git a/tests/test_request_normalizer.py b/tests/test_request_normalizer.py index 8fc31de..3a7ce85 100644 --- a/tests/test_request_normalizer.py +++ b/tests/test_request_normalizer.py @@ -5,8 +5,10 @@ import copy from coding.proxy.server.request_normalizer import ( + NormalizationResult, apply_anthropic_specific_fixes, normalize_anthropic_request, + strip_thinking_blocks, ) @@ -685,3 +687,298 @@ def test_repair_with_normalized_ids(self): assert len(text_blocks) == 1 assert len(synthetic_results) == 2 assert {r["tool_use_id"] for r in synthetic_results} == set(new_ids) + + +# ── has_cross_vendor_signals 属性测试 ────────────────────────── + + +class TestHasCrossVendorSignals: + """验证 NormalizationResult.has_cross_vendor_signals 属性.""" + + def test_true_when_tool_id_map_nonempty(self): + """tool_id_map 非空时标识为跨供应商信号.""" + result = normalize_anthropic_request( + { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "server_tool_use", + "id": "srvtoolu_abc", + "name": "Bash", + "input": {"command": "ls"}, + }, + ], + }, + ], + } + ) + assert result.tool_id_map # 非空 + assert result.has_cross_vendor_signals is True + + def test_true_when_misplaced_tool_results_exist(self): + """misplaced_tool_results 非空时标识为跨供应商信号.""" + result = normalize_anthropic_request( + { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_123", + "name": "Bash", + "input": {"command": "ls"}, + }, + { + "type": "tool_result", + "tool_use_id": "toolu_123", + "content": "output", + }, + ], + }, + ], + } + ) + assert result.misplaced_tool_results # 非空 + assert result.has_cross_vendor_signals is True + + def test_true_when_vendor_block_removed(self): + """vendor block 被移除时标识为跨供应商信号.""" + result = normalize_anthropic_request( + { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "text", "text": "hello"}, + { + "type": "server_tool_use_delta", + "partial_json": '{"cmd":"pwd"}', + }, + ], + }, + ], + } + ) + assert "vendor_block_removed:server_tool_use_delta" in result.adaptations + assert result.has_cross_vendor_signals is True + + def test_true_when_invalid_tool_id_rewritten(self): + """非标准 tool_use ID 被重写时标识为跨供应商信号.""" + result = normalize_anthropic_request( + { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "glm_custom_id_123", + "name": "Bash", + "input": {"command": "ls"}, + }, + ], + }, + ], + } + ) + assert "invalid_tool_use_id_rewritten_for_anthropic" in result.adaptations + assert result.has_cross_vendor_signals is True + + def test_false_for_pure_anthropic_request(self): + """纯 Anthropic 请求不应标识为跨供应商信号.""" + result = normalize_anthropic_request( + { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "thinking", + "thinking": "let me think", + "signature": "anthropic-valid-sig", + }, + {"type": "text", "text": "response"}, + ], + }, + {"role": "user", "content": "follow up"}, + ], + } + ) + assert not result.tool_id_map + assert not result.misplaced_tool_results + assert not result.adaptations + assert result.has_cross_vendor_signals is False + + def test_false_for_standard_tool_use(self): + """标准 toolu_ ID 不应标识为跨供应商信号.""" + result = normalize_anthropic_request( + { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_standard_abc", + "name": "Bash", + "input": {"command": "ls"}, + }, + ], + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_standard_abc", + "content": "output", + }, + ], + }, + ], + } + ) + assert result.has_cross_vendor_signals is False + + +# ── strip_thinking_blocks 函数测试 ────────────────────────────── + + +class TestStripThinkingBlocks: + """验证 strip_thinking_blocks 函数(从 vendors/anthropic.py 迁入).""" + + def test_strips_thinking_blocks(self): + """剥离 assistant 消息中的 thinking blocks.""" + body = { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "thinking", + "thinking": "Let me think...", + "signature": "sig", + }, + {"type": "text", "text": "Here is my answer."}, + ], + }, + ], + } + stripped = strip_thinking_blocks(body) + assert stripped == 1 + content = body["messages"][0]["content"] + assert len(content) == 1 + assert content[0]["type"] == "text" + + def test_strips_redacted_thinking_blocks(self): + """剥离 redacted_thinking blocks.""" + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "redacted_thinking", "data": "base64"}, + {"type": "text", "text": "response"}, + ], + }, + ], + } + stripped = strip_thinking_blocks(body) + assert stripped == 1 + assert body["messages"][0]["content"][0]["type"] == "text" + + def test_inserts_placeholder_when_content_becomes_empty(self): + """剥离后 content 为空时插入占位 text block.""" + body = { + "messages": [ + {"role": "user", "content": "hello"}, + { + "role": "assistant", + "content": [ + { + "type": "thinking", + "thinking": "thought", + "signature": "sig", + }, + ], + }, + {"role": "user", "content": "follow up"}, + ], + } + stripped = strip_thinking_blocks(body) + assert stripped == 1 + content = body["messages"][1]["content"] + assert len(content) == 1 + assert content[0]["type"] == "text" + assert content[0]["text"] == "[thinking]" + + def test_preserves_user_messages(self): + """user 消息不受影响.""" + body = { + "messages": [ + {"role": "user", "content": [{"type": "text", "text": "hello"}]}, + ], + } + stripped = strip_thinking_blocks(body) + assert stripped == 0 + assert body["messages"][0]["content"][0]["text"] == "hello" + + def test_preserves_top_level_thinking_param(self): + """body 顶层的 thinking 参数不受影响.""" + body = { + "thinking": {"type": "enabled", "budget_tokens": 10000}, + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "old", "signature": "sig"}, + {"type": "text", "text": "response"}, + ], + }, + ], + } + stripped = strip_thinking_blocks(body) + assert stripped == 1 + assert body["thinking"] == {"type": "enabled", "budget_tokens": 10000} + + def test_multi_turn_strips_all(self): + """多轮对话中所有 assistant thinking blocks 均被剥离.""" + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t1", "signature": "s1"}, + {"type": "text", "text": "r1"}, + ], + }, + {"role": "user", "content": "follow up"}, + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t2", "signature": "s2"}, + {"type": "text", "text": "r2"}, + ], + }, + ], + } + stripped = strip_thinking_blocks(body) + assert stripped == 2 + assert len(body["messages"][0]["content"]) == 1 + assert len(body["messages"][2]["content"]) == 1 + + def test_returns_zero_when_no_thinking(self): + """无 thinking blocks 时返回 0.""" + body = { + "messages": [ + { + "role": "assistant", + "content": [{"type": "text", "text": "response"}], + }, + ], + } + stripped = strip_thinking_blocks(body) + assert stripped == 0 diff --git a/tests/test_router_executor.py b/tests/test_router_executor.py index 80f67b3..1c50d03 100644 --- a/tests/test_router_executor.py +++ b/tests/test_router_executor.py @@ -1550,3 +1550,186 @@ async def test_non_last_tier_500_still_failovers(self): assert resp.status_code == 200 assert good.send_message.called + + +# ── _needs_thinking_strip 条件判断测试 ────────────────────────── + + +class TestNeedsThinkingStrip: + """验证 _RouteExecutor._needs_thinking_strip 静态方法.""" + + def test_true_when_normalization_has_cross_vendor_signals(self): + """normalization 有跨供应商信号时返回 True.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = True + session_record = MagicMock() + session_record.provider_state = {"anthropic": {}} + + assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + + def test_true_when_session_record_is_none(self): + """session_record 为 None 时安全回退到 True.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + + assert _RouteExecutor._needs_thinking_strip(normalization, None) is True + + def test_true_when_no_normalization_and_no_session(self): + """normalization 和 session_record 均为 None 时返回 True.""" + assert _RouteExecutor._needs_thinking_strip(None, None) is True + + def test_true_when_session_has_non_anthropic_vendor(self): + """会话历史中有非 Anthropic 供应商时返回 True.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + session_record = MagicMock() + session_record.provider_state = {"anthropic": {}, "zhipu": {}} + + assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + + def test_false_when_anthropic_only_session(self): + """纯 Anthropic 会话且无跨供应商信号时返回 False.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + session_record = MagicMock() + session_record.provider_state = {"anthropic": {"compat_mode": "native"}} + + assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + + def test_false_when_empty_provider_state(self): + """空 provider_state(首次请求)且无跨供应商信号时返回 False.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + session_record = MagicMock() + session_record.provider_state = {} + + assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + + def test_true_when_normalization_none_but_session_has_non_anthropic(self): + """normalization 为 None 但会话有非 Anthropic 供应商时返回 True.""" + session_record = MagicMock() + session_record.provider_state = {"copilot": {}} + + assert _RouteExecutor._needs_thinking_strip(None, session_record) is True + + +# ── _prepare_body_for_tier 条件化 thinking 剥离测试 ──────────────── + + +class TestPrepareBodyForTierThinkingStrip: + """验证 _prepare_body_for_tier 的条件化 thinking block 剥离行为.""" + + @staticmethod + def _body_with_thinking(): + return { + "model": "claude-opus-4-6", + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "thinking", + "thinking": "Let me think...", + "signature": "zhipu-sig", + }, + {"type": "text", "text": "response"}, + ], + }, + ], + } + + def test_strips_thinking_when_cross_vendor_signals(self): + """normalization 有跨供应商信号时剥离 thinking blocks.""" + normalization = MagicMock() + normalization.has_anthropic_fixes = False + normalization.has_cross_vendor_signals = True + + tier = MagicMock() + tier.name = "anthropic" + + exec_inst = _executor([]) + body = self._body_with_thinking() + result = exec_inst._prepare_body_for_tier( + body, tier, normalization, session_record=None + ) + + # thinking block 被剥离 + assert len(result["messages"][0]["content"]) == 1 + assert result["messages"][0]["content"][0]["type"] == "text" + # 原始 body 未被修改 + assert len(body["messages"][0]["content"]) == 2 + + def test_strips_thinking_when_session_has_non_anthropic(self): + """会话中有非 Anthropic 供应商时剥离 thinking blocks.""" + normalization = MagicMock() + normalization.has_anthropic_fixes = False + normalization.has_cross_vendor_signals = False + + tier = MagicMock() + tier.name = "anthropic" + + session_record = MagicMock() + session_record.provider_state = {"zhipu": {"compat_mode": "native"}} + + exec_inst = _executor([]) + body = self._body_with_thinking() + result = exec_inst._prepare_body_for_tier( + body, tier, normalization, session_record=session_record + ) + + # thinking block 被剥离 + assert len(result["messages"][0]["content"]) == 1 + assert result["messages"][0]["content"][0]["type"] == "text" + + def test_preserves_thinking_when_anthropic_only_session(self): + """纯 Anthropic 会话保留 thinking blocks.""" + normalization = MagicMock() + normalization.has_anthropic_fixes = False + normalization.has_cross_vendor_signals = False + + tier = MagicMock() + tier.name = "anthropic" + + session_record = MagicMock() + session_record.provider_state = {"anthropic": {"compat_mode": "native"}} + + exec_inst = _executor([]) + body = self._body_with_thinking() + result = exec_inst._prepare_body_for_tier( + body, tier, normalization, session_record=session_record + ) + + # 原始 body 直接返回(无 deep copy) + assert result is body + assert len(result["messages"][0]["content"]) == 2 + assert result["messages"][0]["content"][0]["type"] == "thinking" + + def test_strips_thinking_when_no_session_record(self): + """无会话记录时安全回退剥离.""" + normalization = MagicMock() + normalization.has_anthropic_fixes = False + normalization.has_cross_vendor_signals = False + + tier = MagicMock() + tier.name = "anthropic" + + exec_inst = _executor([]) + body = self._body_with_thinking() + result = exec_inst._prepare_body_for_tier( + body, tier, normalization, session_record=None + ) + + # thinking block 被剥离(安全回退) + assert len(result["messages"][0]["content"]) == 1 + assert result["messages"][0]["content"][0]["type"] == "text" + + def test_skips_for_non_anthropic_tier(self): + """非 Anthropic tier 不执行任何处理.""" + tier = MagicMock() + tier.name = "zhipu" + + exec_inst = _executor([]) + body = self._body_with_thinking() + result = exec_inst._prepare_body_for_tier(body, tier) + + assert result is body # 原始 body 直接返回 diff --git a/tests/test_vendors.py b/tests/test_vendors.py index e9fc241..578b0b0 100644 --- a/tests/test_vendors.py +++ b/tests/test_vendors.py @@ -46,8 +46,8 @@ async def test_anthropic_prepare_request_filters_headers(): @pytest.mark.asyncio -async def test_anthropic_prepare_request_strips_thinking_blocks(): - """Anthropic vendor 应剥离 assistant messages 中的 thinking blocks.""" +async def test_anthropic_prepare_request_preserves_thinking_blocks(): + """Anthropic vendor 不再剥离 thinking blocks(已提升至 executor 层条件执行).""" vendor = AnthropicVendor(AnthropicConfig(), FailoverConfig()) body = { "model": "claude-opus-4-6", @@ -58,7 +58,7 @@ async def test_anthropic_prepare_request_strips_thinking_blocks(): { "type": "thinking", "thinking": "Let me think about this...", - "signature": "zhipu-issued-signature", + "signature": "anthropic-issued-signature", }, {"type": "text", "text": "Here is my answer."}, ], @@ -67,16 +67,16 @@ async def test_anthropic_prepare_request_strips_thinking_blocks(): } prepared_body, _ = await vendor._prepare_request(body, {}) - # thinking block 被剥离,text block 保留 + # thinking block 保留(剥离逻辑已迁移至 executor 层条件执行) content = prepared_body["messages"][0]["content"] - assert len(content) == 1 - assert content[0]["type"] == "text" - assert content[0]["text"] == "Here is my answer." + assert len(content) == 2 + assert content[0]["type"] == "thinking" + assert content[1]["type"] == "text" @pytest.mark.asyncio -async def test_anthropic_prepare_request_strips_redacted_thinking_blocks(): - """Anthropic vendor 应剥离 assistant messages 中的 redacted_thinking blocks.""" +async def test_anthropic_prepare_request_preserves_redacted_thinking_blocks(): + """Anthropic vendor 不再剥离 redacted_thinking blocks(已提升至 executor 层).""" vendor = AnthropicVendor(AnthropicConfig(), FailoverConfig()) body = { "model": "claude-opus-4-6", @@ -93,8 +93,9 @@ async def test_anthropic_prepare_request_strips_redacted_thinking_blocks(): prepared_body, _ = await vendor._prepare_request(body, {}) content = prepared_body["messages"][0]["content"] - assert len(content) == 1 - assert content[0]["type"] == "text" + assert len(content) == 2 + assert content[0]["type"] == "redacted_thinking" + assert content[1]["type"] == "text" @pytest.mark.asyncio @@ -119,9 +120,10 @@ async def test_anthropic_prepare_request_preserves_thinking_param(): # 顶层 thinking 参数保留 assert prepared_body["thinking"] == {"type": "enabled", "budget_tokens": 10000} - # assistant message 的 thinking block 被剥离 - assert len(prepared_body["messages"][0]["content"]) == 1 - assert prepared_body["messages"][0]["content"][0]["type"] == "text" + # assistant message 的 thinking block 也保留(剥离逻辑已迁移至 executor 层) + assert len(prepared_body["messages"][0]["content"]) == 2 + assert prepared_body["messages"][0]["content"][0]["type"] == "thinking" + assert prepared_body["messages"][0]["content"][1]["type"] == "text" @pytest.mark.asyncio @@ -184,8 +186,8 @@ async def test_anthropic_prepare_request_handles_string_content(): @pytest.mark.asyncio -async def test_anthropic_prepare_request_thinking_only_gets_placeholder(): - """assistant message 仅含 thinking blocks 时,剥离后应插入占位 text block.""" +async def test_anthropic_prepare_request_preserves_thinking_only_message(): + """assistant message 仅含 thinking blocks 时,_prepare_request 不再剥离(由 executor 处理).""" vendor = AnthropicVendor(AnthropicConfig(), FailoverConfig()) body = { "model": "claude-opus-4-6", @@ -206,59 +208,15 @@ async def test_anthropic_prepare_request_thinking_only_gets_placeholder(): } prepared_body, _ = await vendor._prepare_request(body, {}) + # thinking blocks 保留(不再由 _prepare_request 剥离) content = prepared_body["messages"][1]["content"] assert len(content) == 1 - assert content[0]["type"] == "text" - assert content[0]["text"] == "[thinking]" - - -@pytest.mark.asyncio -async def test_anthropic_prepare_request_thinking_only_with_tool_result_context(): - """多轮对话:thinking-only assistant + 后续 user tool_result 不应触发结构错误.""" - vendor = AnthropicVendor(AnthropicConfig(), FailoverConfig()) - body = { - "model": "claude-opus-4-6", - "messages": [ - {"role": "user", "content": "hello"}, - { - "role": "assistant", - "content": [ - { - "type": "thinking", - "thinking": "thought 1", - "signature": "sig-1", - }, - {"type": "redacted_thinking", "data": "base64data"}, - ], - }, - { - "role": "user", - "content": [ - { - "type": "tool_result", - "tool_use_id": "toolu_123", - "content": "result data", - }, - ], - }, - ], - } - prepared_body, _ = await vendor._prepare_request(body, {}) - - # assistant message 应包含占位 text block - content = prepared_body["messages"][1]["content"] - assert len(content) == 1 - assert content[0]["type"] == "text" - assert content[0]["text"] == "[thinking]" - - # user message 的 tool_result 应完整保留 - user_content = prepared_body["messages"][2]["content"] - assert user_content[0]["type"] == "tool_result" + assert content[0]["type"] == "thinking" @pytest.mark.asyncio -async def test_anthropic_prepare_request_multi_turn_strips_all_thinking(): - """多轮对话中所有 assistant thinking blocks 均应被剥离.""" +async def test_anthropic_prepare_request_preserves_multi_turn_thinking(): + """多轮对话中 assistant thinking blocks 不再被 _prepare_request 剥离.""" vendor = AnthropicVendor(AnthropicConfig(), FailoverConfig()) body = { "model": "claude-opus-4-6", @@ -288,19 +246,21 @@ async def test_anthropic_prepare_request_multi_turn_strips_all_thinking(): } prepared_body, _ = await vendor._prepare_request(body, {}) - # 第一条 assistant message: thinking 被剥离,text 保留 + # 第一条 assistant message: thinking + text 均保留 content_0 = prepared_body["messages"][0]["content"] - assert len(content_0) == 1 - assert content_0[0]["type"] == "text" + assert len(content_0) == 2 + assert content_0[0]["type"] == "thinking" + assert content_0[1]["type"] == "text" # user message 不变 assert prepared_body["messages"][1]["content"] == "follow up" - # 第三条 assistant message: thinking 被剥离,text + tool_use 保留 + # 第三条 assistant message: thinking + text + tool_use 均保留 content_2 = prepared_body["messages"][2]["content"] - assert len(content_2) == 2 - assert content_2[0]["type"] == "text" - assert content_2[1]["type"] == "tool_use" + assert len(content_2) == 3 + assert content_2[0]["type"] == "thinking" + assert content_2[1]["type"] == "text" + assert content_2[2]["type"] == "tool_use" @pytest.mark.asyncio @@ -870,8 +830,8 @@ async def test_anthropic_preserves_tool_result_in_user_message(): @pytest.mark.asyncio -async def test_anthropic_strips_both_thinking_and_misplaced_tool_result(): - """Anthropic vendor 应同时剥离 thinking 和错位的 tool_result.""" +async def test_anthropic_strips_misplaced_tool_result_preserves_thinking(): + """Anthropic vendor 仅剥离错位的 tool_result(纵深防御),保留 thinking blocks.""" vendor = AnthropicVendor(AnthropicConfig(), FailoverConfig()) body = { "model": "claude-opus-4-6", @@ -901,10 +861,11 @@ async def test_anthropic_strips_both_thinking_and_misplaced_tool_result(): } prepared_body, _ = await vendor._prepare_request(body, {}) - # thinking 和 misplaced tool_result 都被剥离 + # misplaced tool_result 被剥离(纵深防御),thinking 保留 assistant_content = prepared_body["messages"][0]["content"] - assert len(assistant_content) == 1 - assert assistant_content[0]["type"] == "tool_use" + assert len(assistant_content) == 2 + assert assistant_content[0]["type"] == "thinking" + assert assistant_content[1]["type"] == "tool_use" @pytest.mark.asyncio From e3bc9127b4b0f2dc584e44f9c57b05e6c3965f57 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 22:28:20 +0800 Subject: [PATCH 04/32] =?UTF-8?q?style(format):=20=E6=8B=86=E5=88=86?= =?UTF-8?q?=E9=95=BF=E8=A1=8C=E5=B9=B6=E7=A7=BB=E9=99=A4=E6=9C=AA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E5=AF=BC=E5=85=A5=EF=BC=8C=E6=8F=90=E5=8D=87=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=8F=AF=E8=AF=BB=E6=80=A7;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/routing/executor.py | 8 ++++++-- src/coding/proxy/server/request_normalizer.py | 12 +++++++----- tests/test_request_normalizer.py | 1 - tests/test_router_executor.py | 16 ++++++++++++---- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index fd3fab9..7ec0f14 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -241,7 +241,9 @@ def _prepare_body_for_tier( if tier.name != "anthropic": return body - needs_tool_fixes = normalization is not None and normalization.has_anthropic_fixes + needs_tool_fixes = ( + normalization is not None and normalization.has_anthropic_fixes + ) needs_thinking_strip = self._needs_thinking_strip(normalization, session_record) if not needs_tool_fixes and not needs_thinking_strip: @@ -296,7 +298,9 @@ def _needs_thinking_strip(normalization: Any, session_record: Any) -> bool: return True # Signal 3: 会话历史中有非 Anthropic 供应商 if session_record.provider_state: - non_anthropic = {v for v in session_record.provider_state if v != "anthropic"} + non_anthropic = { + v for v in session_record.provider_state if v != "anthropic" + } if non_anthropic: return True # 纯 Anthropic 会话,无跨供应商信号 → 保留 thinking blocks diff --git a/src/coding/proxy/server/request_normalizer.py b/src/coding/proxy/server/request_normalizer.py index fd42065..d2adc74 100644 --- a/src/coding/proxy/server/request_normalizer.py +++ b/src/coding/proxy/server/request_normalizer.py @@ -23,11 +23,13 @@ } # 标识跨供应商迁移产物的 adaptation 名称集合(用于条件化 thinking block 剥离) -_CROSS_VENDOR_ADAPTATIONS = frozenset({ - "vendor_block_removed", - "server_tool_use_id_rewritten_for_anthropic", - "invalid_tool_use_id_rewritten_for_anthropic", -}) +_CROSS_VENDOR_ADAPTATIONS = frozenset( + { + "vendor_block_removed", + "server_tool_use_id_rewritten_for_anthropic", + "invalid_tool_use_id_rewritten_for_anthropic", + } +) @dataclass diff --git a/tests/test_request_normalizer.py b/tests/test_request_normalizer.py index 3a7ce85..7c34c5a 100644 --- a/tests/test_request_normalizer.py +++ b/tests/test_request_normalizer.py @@ -5,7 +5,6 @@ import copy from coding.proxy.server.request_normalizer import ( - NormalizationResult, apply_anthropic_specific_fixes, normalize_anthropic_request, strip_thinking_blocks, diff --git a/tests/test_router_executor.py b/tests/test_router_executor.py index 1c50d03..9b1d452 100644 --- a/tests/test_router_executor.py +++ b/tests/test_router_executor.py @@ -1565,7 +1565,9 @@ def test_true_when_normalization_has_cross_vendor_signals(self): session_record = MagicMock() session_record.provider_state = {"anthropic": {}} - assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + assert ( + _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + ) def test_true_when_session_record_is_none(self): """session_record 为 None 时安全回退到 True.""" @@ -1585,7 +1587,9 @@ def test_true_when_session_has_non_anthropic_vendor(self): session_record = MagicMock() session_record.provider_state = {"anthropic": {}, "zhipu": {}} - assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + assert ( + _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + ) def test_false_when_anthropic_only_session(self): """纯 Anthropic 会话且无跨供应商信号时返回 False.""" @@ -1594,7 +1598,9 @@ def test_false_when_anthropic_only_session(self): session_record = MagicMock() session_record.provider_state = {"anthropic": {"compat_mode": "native"}} - assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + assert ( + _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + ) def test_false_when_empty_provider_state(self): """空 provider_state(首次请求)且无跨供应商信号时返回 False.""" @@ -1603,7 +1609,9 @@ def test_false_when_empty_provider_state(self): session_record = MagicMock() session_record.provider_state = {} - assert _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + assert ( + _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + ) def test_true_when_normalization_none_but_session_has_non_anthropic(self): """normalization 为 None 但会话有非 Anthropic 供应商时返回 True.""" From 9bee5b3825a189b32fdbee63af4aad03651acdfd Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 22:34:06 +0800 Subject: [PATCH 05/32] =?UTF-8?q?build(version):=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E5=8D=87=E7=BA=A7=E8=87=B3=200.2.4a1=20=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E4=B8=8B=E4=B8=80=E8=BF=AD=E4=BB=A3=E5=91=A8=E6=9C=9F?= =?UTF-8?q?;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index b71efa6..6d356bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "coding-proxy" -version = "0.2.3" +version = "0.2.4a1" description = "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..." readme = "README.md" requires-python = ">=3.12" diff --git a/uv.lock b/uv.lock index 6ef84e8..1a52b5b 100644 --- a/uv.lock +++ b/uv.lock @@ -65,7 +65,7 @@ wheels = [ [[package]] name = "coding-proxy" -version = "0.2.3" +version = "0.2.4a1" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From e7437e6817cef02072a38096d61f4528a283aedb Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 22:59:22 +0800 Subject: [PATCH 06/32] =?UTF-8?q?chore(config):=20=E8=B0=83=E6=95=B4=20tok?= =?UTF-8?q?en=5Fbudget=20=E8=87=B3=2060000000;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/config/config.default.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coding/proxy/config/config.default.yaml b/src/coding/proxy/config/config.default.yaml index 2f8284b..4f0bf7b 100644 --- a/src/coding/proxy/config/config.default.yaml +++ b/src/coding/proxy/config/config.default.yaml @@ -52,7 +52,7 @@ vendors: success_threshold: 2 quota_guard: enabled: true - token_budget: 50000000 # 5 小时 token 预算(根据订阅计划调整) + token_budget: 60000000 # 5 小时 token 预算(根据订阅计划调整) window_hours: 5.0 threshold_percent: 99.0 probe_interval_seconds: 300 From 5c7fa01e1538ba1c502eca86c590e2ecd0aa0618 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 23:05:12 +0800 Subject: [PATCH 07/32] =?UTF-8?q?chore(config):=20=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=85=B3=E9=97=AD=20quota=5Fguard=20=E4=B8=8E=20antigravity=20?= =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=95=86;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/config/config.default.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coding/proxy/config/config.default.yaml b/src/coding/proxy/config/config.default.yaml index 4f0bf7b..03cd5a7 100644 --- a/src/coding/proxy/config/config.default.yaml +++ b/src/coding/proxy/config/config.default.yaml @@ -51,13 +51,13 @@ vendors: recovery_timeout_seconds: 300 success_threshold: 2 quota_guard: - enabled: true + enabled: false token_budget: 60000000 # 5 小时 token 预算(根据订阅计划调整) window_hours: 5.0 threshold_percent: 99.0 probe_interval_seconds: 300 weekly_quota_guard: - enabled: true + enabled: false token_budget: 800000000 # 一周 token 预算(根据订阅计划调整) window_hours: 168.0 # 7 天滑动窗口 threshold_percent: 99.0 @@ -84,7 +84,7 @@ vendors: # Vendor 2: Google Antigravity Plans(中间层,默认禁用) - vendor: antigravity - enabled: true # 启用需配置 OAuth 凭据 + enabled: false # 启用需配置 OAuth 凭据 client_id: "${GOOG_CLIENT_ID}" # Google OAuth2 Client ID client_secret: "${GOOG_CLIENT_SECRET}" # Google OAuth2 Client Secret refresh_token: "${GOOG_REFRESH_TOKEN}" # Google OAuth2 Refresh Token @@ -96,7 +96,7 @@ vendors: recovery_timeout_seconds: 300 success_threshold: 2 quota_guard: - enabled: true # 启用后按 Premium Requests 配额管理 + enabled: false # 启用后按 Premium Requests 配额管理 token_budget: 0 window_hours: 24.0 threshold_percent: 95.0 From ca48eacacffe439db34f1a7db1742da28ae757f5 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Thu, 16 Apr 2026 23:08:38 +0800 Subject: [PATCH 08/32] =?UTF-8?q?style(cost-format):=20=E8=B4=B9=E7=94=A8?= =?UTF-8?q?=E9=87=91=E9=A2=9D=E6=98=BE=E7=A4=BA=E7=B2=BE=E5=BA=A6=E4=BB=8E?= =?UTF-8?q?=204=20=E4=BD=8D=E7=BC=A9=E5=87=8F=E8=87=B3=202=20=E4=BD=8D?= =?UTF-8?q?=E5=B0=8F=E6=95=B0;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/logging/stats.py | 2 +- src/coding/proxy/model/pricing.py | 4 ++-- src/coding/proxy/server/dashboard.py | 2 +- tests/test_currency.py | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coding/proxy/logging/stats.py b/src/coding/proxy/logging/stats.py index bb1bf49..cbfe86a 100644 --- a/src/coding/proxy/logging/stats.py +++ b/src/coding/proxy/logging/stats.py @@ -198,7 +198,7 @@ async def show_usage( if cost_totals: total_cost_str = " + ".join( - f"{cur.symbol}{amt:.4f}" for cur, amt in cost_totals.items() + f"{cur.symbol}{amt:.2f}" for cur, amt in cost_totals.items() ) else: total_cost_str = "-" diff --git a/src/coding/proxy/model/pricing.py b/src/coding/proxy/model/pricing.py index 72ed35b..94fce72 100644 --- a/src/coding/proxy/model/pricing.py +++ b/src/coding/proxy/model/pricing.py @@ -50,8 +50,8 @@ class CostValue: amount: float currency: Currency = Currency.default() - def format(self, precision: int = 4) -> str: - """格式化为 ``$0.1234`` 或 ``¥0.1234``.""" + def format(self, precision: int = 2) -> str: + """格式化为 ``$0.12`` 或 ``¥0.12``.""" return f"{self.currency.symbol}{self.amount:.{precision}f}" @property diff --git a/src/coding/proxy/server/dashboard.py b/src/coding/proxy/server/dashboard.py index c6f866b..cf525c1 100644 --- a/src/coding/proxy/server/dashboard.py +++ b/src/coding/proxy/server/dashboard.py @@ -1340,7 +1340,7 @@ def _compute_cost_str(rows: list[dict], pricing_table: Any) -> str: if not cost_totals: return "–" - return " + ".join(f"{cur.symbol}{amt:.4f}" for cur, amt in cost_totals.items()) + return " + ".join(f"{cur.symbol}{amt:.2f}" for cur, amt in cost_totals.items()) # ── 路由注册 ────────────────────────────────────────────────────────────── diff --git a/tests/test_currency.py b/tests/test_currency.py index 86c07f2..c50eb09 100644 --- a/tests/test_currency.py +++ b/tests/test_currency.py @@ -45,11 +45,11 @@ class TestCostValue: def test_format_usd(self): cv = CostValue(amount=0.3421, currency=Currency.USD) - assert cv.format() == "$0.3421" + assert cv.format() == "$0.34" def test_format_cny(self): cv = CostValue(amount=0.0953, currency=Currency.CNY) - assert cv.format() == "\u00a50.0953" + assert cv.format() == "\u00a50.10" def test_format_precision(self): cv = CostValue(amount=0.12345678, currency=Currency.USD) @@ -58,7 +58,7 @@ def test_format_precision(self): def test_format_zero(self): cv = CostValue(amount=0.0, currency=Currency.USD) - assert cv.format() == "$0.0000" + assert cv.format() == "$0.00" def test_equality_same_currency(self): a = CostValue(1.0, Currency.USD) From b5550a6ed00af0ee0f58dd584af40a00ff59eda1 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 09:27:14 +0800 Subject: [PATCH 09/32] =?UTF-8?q?build(version):=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7=E5=8D=87=E7=BA=A7=E8=87=B3=200.2.4a2=20=E8=BF=9B?= =?UTF-8?q?=E5=85=A5=E4=B8=8B=E4=B8=80=E8=BF=AD=E4=BB=A3=E5=91=A8=E6=9C=9F?= =?UTF-8?q?;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6d356bd..8ee4b4f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "coding-proxy" -version = "0.2.4a1" +version = "0.2.4a2" description = "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..." readme = "README.md" requires-python = ">=3.12" diff --git a/uv.lock b/uv.lock index 1a52b5b..fd45741 100644 --- a/uv.lock +++ b/uv.lock @@ -65,7 +65,7 @@ wheels = [ [[package]] name = "coding-proxy" -version = "0.2.4a1" +version = "0.2.4a2" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From 7cefa0d24baac1f54cbc7c77147274d9b210a445 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 09:35:27 +0800 Subject: [PATCH 10/32] =?UTF-8?q?ci(release):=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E6=B5=81=E6=B0=B4=E7=BA=BF=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=20Update=20Changelog=20=E8=87=AA=E5=8A=A8=E5=8C=96=E9=98=B6?= =?UTF-8?q?=E6=AE=B5;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- .github/workflows/release.yml | 134 +--------------------------------- 1 file changed, 2 insertions(+), 132 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4bc793f..dea457d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,15 +1,14 @@ # ============================================================================= -# coding-proxy: PyPI Publishing Pipeline (4-Stage Unified Pipeline) +# coding-proxy: PyPI Publishing Pipeline (3-Stage Unified Pipeline) # ============================================================================= # Trigger: GitHub Release publication event (release.types: [published]) # -# Architecture: 4-Stage Serial Pipeline (prerelease only — 所有生产发布均走预发布) +# Architecture: 3-Stage Serial Pipeline (prerelease only — 所有生产发布均走预发布) # # Stage 1 (build): 矩阵构建 3.12/3.13/3.14,上传 artifacts # Stage 2 (publish-testpypi): 发布到 TestPyPI 供验证 # Stage 3 (publish-to-pypi): ⏸ Production Approval Gate (environment: pypi) # 审批通过后自动:Promote Release + Publish to PyPI -# Stage 4 (update-changelog): 从 Release notes 生成 Changelog PR → master # # 设计决策 — Stage 3 合并审批与发布的理由: # pypa/gh-action-pypi-publish@release/v1 始终优先尝试 OIDC Trusted Publishing。 @@ -21,9 +20,6 @@ # Pre-requisites — 需要在 GitHub Settings 一次性手动配置: # 1. repo → Settings → Environments → "pypi" # → Required reviewers: 添加审批人员(Production Approval Gate 所需) -# 2. repo → Settings → Actions → General → Workflow permissions -# → "Read and write permissions"(Stage 4 推分支所需) -# → 勾选 "Allow GitHub Actions to create and approve pull requests" # # Authentication: # - TEST_PYPI_API_TOKEN: TestPyPI API Token(repository secret) @@ -198,129 +194,3 @@ jobs: skip-existing: true verbose: true - # =========================================================================== - # Stage 5: UPDATE CHANGELOG -- 自动生成 Changelog PR → master - # =========================================================================== - update-changelog: - name: Update Changelog - runs-on: ubuntu-latest - needs: publish-to-pypi - if: github.event.release.prerelease == true - timeout-minutes: 10 - permissions: - contents: write # git push 新分支 - pull-requests: write # 创建 PR - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - persist-credentials: true - - - name: Extract stable version from prerelease tag - id: version - run: | - PRERELEASE_TAG="${{ github.ref_name }}" - # v0.2.0a1 → v0.2.0(移除预发布后缀 a*/b*/rc*) - STABLE_VERSION=$(echo "$PRERELEASE_TAG" | sed 's/\(v[0-9]*\.[0-9]*\.[0-9]*\).*/\1/') - echo "prerelease_tag=$PRERELEASE_TAG" >> "$GITHUB_OUTPUT" - echo "stable_version=$STABLE_VERSION" >> "$GITHUB_OUTPUT" - echo "branch_name=chore/changelog-$STABLE_VERSION" >> "$GITHUB_OUTPUT" - echo "Extracted: $PRERELEASE_TAG → $STABLE_VERSION" - - - name: Check if Changelog entry already exists - id: check - run: | - STABLE="${{ steps.version.outputs.stable_version }}" - if grep -qF "[$STABLE]" CHANGELOG.md; then - echo "exists=true" >> "$GITHUB_OUTPUT" - echo "ℹ️ Changelog entry for $STABLE already exists, skipping PR creation" - else - echo "exists=false" >> "$GITHUB_OUTPUT" - echo "✅ No existing entry for $STABLE, will create PR" - fi - - - name: Fetch release body and update CHANGELOG.md - if: steps.check.outputs.exists == 'false' - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const { owner, repo } = context.repo; - - // 通过 API 获取 Release body,避免 shell 特殊字符注入问题 - const release = await github.rest.repos.getReleaseByTag({ - owner, - repo, - tag: '${{ steps.version.outputs.prerelease_tag }}', - }); - - const stable = '${{ steps.version.outputs.stable_version }}'; - const date = new Date().toISOString().slice(0, 10); - const releaseUrl = `https://github.com/${owner}/${repo}/releases/tag/${{ steps.version.outputs.prerelease_tag }}`; - const body = release.data.body || ''; - - // 构建新条目 - const newEntry = `\n## [${stable}](${releaseUrl}) — ${date}\n\n${body}\n`; - - // 读取 CHANGELOG.md,在 ## [Unreleased] 行后插入新条目 - let content = fs.readFileSync('CHANGELOG.md', 'utf8'); - const marker = '## [Unreleased]'; - const idx = content.indexOf(marker); - if (idx === -1) { - core.setFailed('CHANGELOG.md 中未找到 ## [Unreleased] 标记,无法插入条目'); - return; - } - const insertPos = idx + marker.length; - content = content.slice(0, insertPos) + newEntry + content.slice(insertPos); - fs.writeFileSync('CHANGELOG.md', content, 'utf8'); - core.info(`✅ CHANGELOG.md updated with entry for ${stable}`); - - - name: Create branch and commit - if: steps.check.outputs.exists == 'false' - run: | - BRANCH="${{ steps.version.outputs.branch_name }}" - STABLE="${{ steps.version.outputs.stable_version }}" - - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - - git checkout -b "$BRANCH" - git add CHANGELOG.md - git commit -m "docs(changelog): add entry for $STABLE" - git push origin "$BRANCH" - - - name: Create Pull Request - if: steps.check.outputs.exists == 'false' - uses: actions/github-script@v7 - with: - script: | - const { owner, repo } = context.repo; - const stable = '${{ steps.version.outputs.stable_version }}'; - const branch = '${{ steps.version.outputs.branch_name }}'; - const prereleaseTag = '${{ steps.version.outputs.prerelease_tag }}'; - const runUrl = `https://github.com/${owner}/${repo}/actions/runs/${{ github.run_id }}`; - - const pr = await github.rest.pulls.create({ - owner, - repo, - title: `docs(changelog): 补充 ${stable} 发版说明`, - body: [ - `## 摘要`, - ``, - `自动生成的 PR,为 **${stable}** 正式版补充 CHANGELOG 条目。`, - ``, - `- 来源:[\`${prereleaseTag}\`](https://github.com/${owner}/${repo}/releases/tag/${prereleaseTag}) Release notes`, - `- 目标分支:\`master\``, - ``, - `请审阅 CHANGELOG 条目后合并。`, - ``, - `> 🤖 由 [发布流水线](${runUrl}) 自动生成`, - ].join('\n'), - head: branch, - base: 'master', - }); - - core.notice(`✅ PR created: ${pr.data.html_url}`); - From 065af97f474429f0dcfb1017e90dc656c9b441ae Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 10:14:36 +0800 Subject: [PATCH 11/32] =?UTF-8?q?fix(dashboard-legend):=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E4=B8=89=E4=B8=AA=E5=9B=BE=E8=A1=A8=E7=9A=84=20Legend?= =?UTF-8?q?=20=E6=8E=92=E5=BA=8F=E4=B8=8E=E4=BE=9B=E5=BA=94=E5=95=86?= =?UTF-8?q?=E7=8A=B6=E6=80=81=20Tiers=20=E9=A1=BA=E5=BA=8F=E4=B8=80?= =?UTF-8?q?=E8=87=B4;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 sortByTierOrder 辅助函数,将请求量趋势、供应商请求分布、Token 量趋势 三个图表的 Legend 排序策略从各自独立的字母序/数量降序统一为 /api/status 返回 的 tiers 优先级顺序,确保图表间视觉语义一致。 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/server/dashboard.py | 32 ++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/coding/proxy/server/dashboard.py b/src/coding/proxy/server/dashboard.py index cf525c1..8221125 100644 --- a/src/coding/proxy/server/dashboard.py +++ b/src/coding/proxy/server/dashboard.py @@ -911,8 +911,21 @@ def _build_favicon() -> bytes: }).join(''); } +// ── 按 tiers 顺序排序 vendor 列表 ───────────────────────── +function sortByTierOrder(vendors, tierOrder) { + if (!tierOrder || !tierOrder.length) return vendors.sort(); + const orderMap = {}; + tierOrder.forEach((name, i) => { orderMap[name] = i; }); + const maxIdx = tierOrder.length; + return vendors.sort((a, b) => { + const ia = orderMap[a] ?? maxIdx; + const ib = orderMap[b] ?? maxIdx; + return ia !== ib ? ia - ib : a.localeCompare(b); + }); +} + // ── 时序折线图(请求量,按 vendor)──────────────────────── -function buildTimeline(rows) { +function buildTimeline(rows, tierOrder) { const vendorDateMap = {}; const allDates = new Set(); for (const r of rows) { @@ -923,7 +936,7 @@ def _build_favicon() -> bytes: allDates.add(d); } const dates = [...allDates].sort(); - const vendors = Object.keys(vendorDateMap).sort(); + const vendors = sortByTierOrder(Object.keys(vendorDateMap), tierOrder); if (chartTimeline) chartTimeline.destroy(); const ctx = document.getElementById('chart-timeline').getContext('2d'); @@ -962,14 +975,14 @@ def _build_favicon() -> bytes: } // ── 供应商分布环形图 ────────────────────────────────────── -function buildVendorDist(rows) { +function buildVendorDist(rows, tierOrder) { const vendorTotals = {}; for (const r of rows) { const v = r.vendor; if (!isValidLabel(v)) continue; vendorTotals[v] = (vendorTotals[v] || 0) + (r.total_requests || 0); } - const labels = Object.keys(vendorTotals).sort((a,b) => vendorTotals[b]-vendorTotals[a]); + const labels = sortByTierOrder(Object.keys(vendorTotals), tierOrder); const data = labels.map(v => vendorTotals[v]); if (chartVendorDist) chartVendorDist.destroy(); @@ -1027,7 +1040,7 @@ def _build_favicon() -> bytes: } // ── Token 量趋势折线图(按 vendor)─────────────────────── -function buildTokenTimeline(rows) { +function buildTokenTimeline(rows, tierOrder) { const vendorDateMap = {}; const allDates = new Set(); for (const r of rows) { @@ -1040,7 +1053,7 @@ def _build_favicon() -> bytes: allDates.add(d); } const dates = [...allDates].sort(); - const vendors = Object.keys(vendorDateMap).sort(); + const vendors = sortByTierOrder(Object.keys(vendorDateMap), tierOrder); if (chartTokenTimeline) chartTokenTimeline.destroy(); const ctx = document.getElementById('chart-token-timeline').getContext('2d'); @@ -1258,9 +1271,10 @@ def _build_favicon() -> bytes: updateChartTitles(days); const rows = timeline.rows || []; - buildTimeline(rows); - buildVendorDist(rows); - buildTokenTimeline(rows); + const tierOrder = (status.tiers || []).map(t => t.name); + buildTimeline(rows, tierOrder); + buildVendorDist(rows, tierOrder); + buildTokenTimeline(rows, tierOrder); buildModelTokenTimeline(rows); document.getElementById('refresh-time').textContent = '上次刷新: ' + now(); From fc8826c139f27287f647a195170ccced97f5c167 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 17:04:59 +0800 Subject: [PATCH 12/32] =?UTF-8?q?feat(pre-commit):=20=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?pre-commit=20hooks=20=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=9C=A8=20com?= =?UTF-8?q?mit=20=E5=89=8D=E8=87=AA=E5=8A=A8=E6=89=A7=E8=A1=8C=20Ruff=20li?= =?UTF-8?q?nt/format=20=E5=8F=8A=E9=80=9A=E7=94=A8=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=8D=AB=E7=94=9F=E6=A3=80=E6=9F=A5;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 .pre-commit-config.yaml:使用 local hook(language: system + uv run)调用 uv.lock 锁定的 Ruff, 确保本地 hooks 与 CI 流水线使用完全一致的版本(Single Source of Truth); 并集成 pre-commit-hooks 通用卫生检查(trailing-whitespace、end-of-file-fixer、check-yaml 等) - pyproject.toml:dev 依赖组追加 pre-commit>=4.0 - uv.lock:同步锁定 pre-commit==4.5.1 及其依赖 - AGENTS.md:卓越运营规范追加第 5 条 Pre-commit Hooks 安装与使用说明 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- .pre-commit-config.yaml | 57 +++++++++++++++++++++++ AGENTS.md | 1 + pyproject.toml | 1 + uv.lock | 100 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+) create mode 100644 .pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..fdd726d --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,57 @@ +# ============================================================================= +# coding-proxy: Pre-commit Hooks Configuration +# ============================================================================= +# 目的: 在代码提交前自动执行 Ruff lint/format 及通用卫生检查,作为 CI 的前置守护 +# +# 设计决策:使用 local hook(language: system + uv run)而非 astral-sh/ruff-pre-commit +# - 遵循 Single Source of Truth 原则:Ruff 版本由 uv.lock 唯一管控,消除版本漂移 +# - 与 CI 命令形态完全镜像(uv run ruff check/format) +# - 符合 AGENTS.md 包管理规范(统一使用 uv) +# +# 安装:uv run pre-commit install +# 手动全量检查:uv run pre-commit run --all-files +# ============================================================================= + +minimum_pre_commit_version: "4.0.0" + +repos: + # --------------------------------------------------------------------------- + # 通用代码卫生检查(pre-commit-hooks 官方钩子集) + # 轻量级、无额外依赖、执行极快 + # --------------------------------------------------------------------------- + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: trailing-whitespace # 去除行尾空白 + - id: end-of-file-fixer # 确保文件以换行符结尾 + - id: check-yaml + args: ["--unsafe"] # 兼容 GitHub Actions ${{ }} 表达式语法 + - id: check-toml # 校验 TOML 语法(pyproject.toml) + - id: check-merge-conflict # 阻止提交含未解决 merge conflict 标记的文件 + - id: check-added-large-files + args: ["--maxkb=1024"] # 阈值 1MB(assets/dashboard-v0.2.3.png 为 944KB) + + # --------------------------------------------------------------------------- + # Ruff: local hook,直接调用 uv 安装的 Ruff(与 CI 版本完全一致) + # 前置条件:uv sync --dev 已执行 + # --------------------------------------------------------------------------- + - repo: local + hooks: + # 对应 CI: uv run ruff check . + # --fix: 自动修复安全可修复问题(isort、UP 现代化等),降低开发摩擦 + # --exit-non-zero-on-fix: 修复后返回非零码,触发 git 重新暂存已修复文件 + - id: ruff-lint + name: Ruff (lint + auto-fix) + language: system + entry: uv run ruff check --fix --exit-non-zero-on-fix + types_or: [python, pyi] + require_serial: false + + # 对应 CI: uv run ruff format --check . + # 本地直接 format(自动修复格式),CI 保留 --check 模式作为最终防线 + - id: ruff-format + name: Ruff (format) + language: system + entry: uv run ruff format + types_or: [python, pyi] + require_serial: false diff --git a/AGENTS.md b/AGENTS.md index 7750c88..ab7bd32 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,6 +46,7 @@ 2. **Temp Management**: 临时产物(执行计划等)一律收敛至 `.temp/` 并及时清理; 3. **Link Validity**: 确保所有引用的 URL 可访问且具备明确的上下文价值; 4. **Git Commit**: 在需要提交变更到 Git 时,一律使用 Shell 调用 Claude Code 的自定义 Slash Command: `/commit` 进行 git commit 操作(若环境中未安装 Claude Code,则直接读取 `~/.claude/commands/commit.md`,按照其中的规则进行 git commit 操作)。不要执行 Rebase。 + 5. **Pre-commit Hooks**: 克隆仓库后执行 `uv run pre-commit install` 激活本地 Git hooks,使 Ruff lint(含 auto-fix)、Ruff format 及通用代码卫生检查在每次 commit 前自动运行。若 hooks 自动修复了问题,提交会被中断,执行 `git add -p` 审阅修复内容后重新提交即可。 - **Package Management Standardization (包管理规范)**: 1. **Python**: 严禁使用 pip/poetry,**必须**统一使用 `uv` 进行包管理与脚本执行(如 `uv run`); 2. **JavaScript/TypeScript**: 严禁使用 npm/yarn,**必须**统一使用 `pnpm` 进行包管理与脚本执行。 diff --git a/pyproject.toml b/pyproject.toml index 8ee4b4f..9cc7851 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ dev = [ "pytest-asyncio>=1.3", "pytest-cov>=6.0", "ruff>=0.9.0", + "pre-commit>=4.0", ] # ── Ruff: Linter & Formatter(替代 flake8 + isort + Black + pyupgrade 等 6+ 工具) ── diff --git a/uv.lock b/uv.lock index fd45741..5ef7e3a 100644 --- a/uv.lock +++ b/uv.lock @@ -51,6 +51,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, ] +[[package]] +name = "cfgv" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, +] + [[package]] name = "click" version = "8.3.1" @@ -80,6 +89,7 @@ dependencies = [ [package.dev-dependencies] dev = [ + { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, @@ -100,6 +110,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ + { name = "pre-commit", specifier = ">=4.0" }, { name = "pytest", specifier = ">=9.0" }, { name = "pytest-asyncio", specifier = ">=1.3" }, { name = "pytest-cov", specifier = ">=6.0" }, @@ -199,6 +210,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346, upload-time = "2026-03-17T10:33:15.691Z" }, ] +[[package]] +name = "distlib" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, +] + [[package]] name = "fastapi" version = "0.135.2" @@ -215,6 +235,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8f/ea/18f6d0457f9efb2fc6fa594857f92810cadb03024975726db6546b3d6fcf/fastapi-0.135.2-py3-none-any.whl", hash = "sha256:0af0447d541867e8db2a6a25c23a8c4bd80e2394ac5529bd87501bbb9e240ca5", size = 117407, upload-time = "2026-03-23T14:12:43.284Z" }, ] +[[package]] +name = "filelock" +version = "3.28.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/17/6e8890271880903e3538660a21d63a6c1fea969ac71d0d6b608b78727fa9/filelock-3.28.0.tar.gz", hash = "sha256:4ed1010aae813c4ee8d9c660e4792475ee60c4a0ba76073ceaf862bd317e3ca6", size = 56474, upload-time = "2026-04-14T22:54:33.625Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/21/2f728888c45033d34a417bfcd248ea2564c9e08ab1bfd301377cf05d5586/filelock-3.28.0-py3-none-any.whl", hash = "sha256:de9af6712788e7171df1b28b15eba2446c69721433fa427a9bee07b17820a9db", size = 39189, upload-time = "2026-04-14T22:54:32.037Z" }, +] + [[package]] name = "h11" version = "0.16.0" @@ -252,6 +281,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] +[[package]] +name = "identify" +version = "2.6.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/c4/7fb4db12296cdb11893d61c92048fe617ee853f8523b9b296ac03b43757e/identify-2.6.18.tar.gz", hash = "sha256:873ac56a5e3fd63e7438a7ecbc4d91aca692eb3fefa4534db2b7913f3fc352fd", size = 99580, upload-time = "2026-03-15T18:39:50.319Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/33/92ef41c6fad0233e41d3d84ba8e8ad18d1780f1e5d99b3c683e6d7f98b63/identify-2.6.18-py2.py3-none-any.whl", hash = "sha256:8db9d3c8ea9079db92cafb0ebf97abdc09d52e97f4dcf773a2e694048b7cd737", size = 99394, upload-time = "2026-03-15T18:39:48.915Z" }, +] + [[package]] name = "idna" version = "3.11" @@ -291,6 +329,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + [[package]] name = "packaging" version = "26.0" @@ -300,6 +347,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] +[[package]] +name = "platformdirs" +version = "4.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -309,6 +365,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pre-commit" +version = "4.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f1/6d86a29246dfd2e9b6237f0b5823717f60cad94d47ddc26afa916d21f525/pre_commit-4.5.1.tar.gz", hash = "sha256:eb545fcff725875197837263e977ea257a402056661f09dae08e4b149b030a61", size = 198232, upload-time = "2025-12-16T21:14:33.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/19/fd3ef348460c80af7bb4669ea7926651d1f95c23ff2df18b9d24bab4f3fa/pre_commit-4.5.1-py2.py3-none-any.whl", hash = "sha256:3b3afd891e97337708c1674210f8eba659b52a38ea5f822ff142d10786221f77", size = 226437, upload-time = "2025-12-16T21:14:32.409Z" }, +] + [[package]] name = "pydantic" version = "2.12.5" @@ -447,6 +519,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, ] +[[package]] +name = "python-discovery" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/ef/3bae0e537cfe91e8431efcba4434463d2c5a65f5a89edd47c6cf2f03c55f/python_discovery-1.2.2.tar.gz", hash = "sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb", size = 58872, upload-time = "2026-04-07T17:28:49.249Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl", hash = "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size = 31894, upload-time = "2026-04-07T17:28:48.09Z" }, +] + [[package]] name = "pyyaml" version = "6.0.3" @@ -601,3 +686,18 @@ sdist = { url = "https://files.pythonhosted.org/packages/e3/ad/4a96c425be6fb67e0 wheels = [ { url = "https://files.pythonhosted.org/packages/0a/89/f8827ccff89c1586027a105e5630ff6139a64da2515e24dafe860bd9ae4d/uvicorn-0.42.0-py3-none-any.whl", hash = "sha256:96c30f5c7abe6f74ae8900a70e92b85ad6613b745d4879eb9b16ccad15645359", size = 68830, upload-time = "2026-03-16T06:19:48.325Z" }, ] + +[[package]] +name = "virtualenv" +version = "21.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "python-discovery" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0c/98/3a7e644e19cb26133488caff231be390579860bbbb3da35913c49a1d0a46/virtualenv-21.2.4.tar.gz", hash = "sha256:b294ef68192638004d72524ce7ef303e9d0cf5a44c95ce2e54a7500a6381cada", size = 5850742, upload-time = "2026-04-14T22:15:31.438Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/8d/edd0bd910ff803c308ee9a6b7778621af0d10252219ad9f19ef4d4982a61/virtualenv-21.2.4-py3-none-any.whl", hash = "sha256:29d21e941795206138d0f22f4e45ff7050e5da6c6472299fb7103318763861ac", size = 5831232, upload-time = "2026-04-14T22:15:29.342Z" }, +] From c2ee5524a95a3ee3340c15c00e2520be78d391e8 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 17:05:05 +0800 Subject: [PATCH 13/32] =?UTF-8?q?style(whitespace):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E8=A1=8C=E5=B0=BE=E7=A9=BA=E7=99=BD=E4=B8=8E=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=9C=AB=E5=B0=BE=E6=8D=A2=E8=A1=8C=E7=AC=A6=E7=BC=BA=E5=A4=B1?= =?UTF-8?q?=EF=BC=8C=E7=94=B1=20pre-commit=20hooks=20=E9=A6=96=E6=AC=A1?= =?UTF-8?q?=E5=85=A8=E9=87=8F=E6=89=AB=E6=8F=8F=E8=87=AA=E5=8A=A8=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- .github/workflows/release.yml | 1 - CHANGELOG.md | 6 +++--- README.md | 4 ++-- docs/zh-CN/README.md | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dea457d..863a0eb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -193,4 +193,3 @@ jobs: with: skip-existing: true verbose: true - diff --git a/CHANGELOG.md b/CHANGELOG.md index a498dc9..c59507c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,9 +71,9 @@ ## [v0.1.1](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.1.1) — 2026-04-05 > [!IMPORTANT] -> -> **🎉 coding-proxy MVP 惊艳登场!** -> +> +> **🎉 coding-proxy MVP 惊艳登场!** +> > 仅需配置一行环境变量,立刻为你的 Claude Code 接入“永不宕机”的多源智能引擎。主供应商打盹?毫秒级自动无缝切换备用通道,全天候护航你的编码心流,向打断大声说不! ### ✨ 核心亮点 diff --git a/README.md b/README.md index d24fe37..fdf91ed 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ graph RL subgraph CodingProxy["⚡ coding-proxy"] direction RL - + Router["RequestRouter
routing/router.py"]:::router Router -->NTier @@ -151,7 +151,7 @@ graph RL Tier2 -. "🆘 Safety Net Downgrade" .-> TierN end - end + end Client -->|"POST /v1/messages"| CodingProxy ``` diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md index 7a1a7a0..b22cdda 100644 --- a/docs/zh-CN/README.md +++ b/docs/zh-CN/README.md @@ -118,7 +118,7 @@ graph RL subgraph CodingProxy["⚡ coding-proxy"] direction RL - + Router["RequestRouter
routing/router.py"]:::router Router -->NTier @@ -151,7 +151,7 @@ graph RL Tier2 -. "🆘 Safety Net Downgrade" .-> TierN end - end + end Client -->|"POST /v1/messages"| CodingProxy ``` From b5a26bbf95cae17bae57b308e8df81e3218ada55 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 20:34:08 +0800 Subject: [PATCH 14/32] =?UTF-8?q?build(version):=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E8=87=B3=200.2.4a3;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude) Co-Authored-By: Aurelius Huang --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9cc7851..3015d05 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "coding-proxy" -version = "0.2.4a2" +version = "0.2.4a3" description = "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..." readme = "README.md" requires-python = ">=3.12" diff --git a/uv.lock b/uv.lock index 5ef7e3a..26854a9 100644 --- a/uv.lock +++ b/uv.lock @@ -74,7 +74,7 @@ wheels = [ [[package]] name = "coding-proxy" -version = "0.2.4a2" +version = "0.2.4a3" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From a1ab8d9bcf39e88376b44cc22ce0efdfbb3e77ba Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 20:34:14 +0800 Subject: [PATCH 15/32] =?UTF-8?q?chore(config):=20=E4=B8=8A=E8=B0=83=20Cla?= =?UTF-8?q?ude=20=E4=BE=9B=E5=BA=94=E5=95=86=20token=5Fbudget=20=E8=87=B3?= =?UTF-8?q?=2065,000,000;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude) Co-Authored-By: Aurelius Huang --- src/coding/proxy/config/config.default.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coding/proxy/config/config.default.yaml b/src/coding/proxy/config/config.default.yaml index 03cd5a7..be5cc83 100644 --- a/src/coding/proxy/config/config.default.yaml +++ b/src/coding/proxy/config/config.default.yaml @@ -52,7 +52,7 @@ vendors: success_threshold: 2 quota_guard: enabled: false - token_budget: 60000000 # 5 小时 token 预算(根据订阅计划调整) + token_budget: 65000000 # 5 小时 token 预算(根据订阅计划调整) window_hours: 5.0 threshold_percent: 99.0 probe_interval_seconds: 300 From 3a06c09b1e37dfdaeb22cb07885f119108db9276 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 21:22:55 +0800 Subject: [PATCH 16/32] =?UTF-8?q?fix(request-normalizer):=20=E9=87=8D?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=20zhipu=E2=86=92anthropic=20=E8=B7=A8?= =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=95=86=20tool=5Fuse/tool=5Fresult=20?= =?UTF-8?q?=E9=85=8D=E5=AF=B9=E4=BF=AE=E5=A4=8D=EF=BC=8C=E4=BB=A5=E5=8D=95?= =?UTF-8?q?=E9=81=8D=E8=87=AA=E5=8C=85=E5=90=AB=E5=87=BD=E6=95=B0=E6=9B=BF?= =?UTF-8?q?=E4=BB=A3=E5=A4=9A=E6=AD=A5=E4=B8=B2=E8=81=94=E7=AE=A1=E7=BA=BF?= =?UTF-8?q?;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 以 `enforce_anthropic_tool_pairing` 单次正向遍历替代原有多步串联管线 (剥离→重定位→孤儿修复),消除步骤间隐式依赖导致的孤儿 tool_use 漏修, 彻底根治 `tool_use ids were found without tool_result blocks` 400 异常。 - 新增 `enforce_anthropic_tool_pairing()` 函数(单遍、自包含、幂等) - 新增 `_needs_tool_pairing_enforcement()` 扩展触发条件,覆盖会话历史含非 Anthropic 供应商的场景 - 新增 13 个测试用例覆盖全部场景(含真实 bug 复现) 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- CHANGELOG.md | 2 + src/coding/proxy/routing/executor.py | 52 +- src/coding/proxy/server/request_normalizer.py | 144 +++++ tests/test_request_normalizer.py | 511 ++++++++++++++++++ 4 files changed, 699 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c59507c..1af56a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ## [Unreleased] +- 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 异常; + ## [v0.2.3](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.2.3) — 2026-04-16 - feat(dashboard): 新增实时 Web Dashboard 页面,聚合展示流量与用量统计; diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index 7ec0f14..d2fb489 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -233,7 +233,7 @@ def _prepare_body_for_tier( """为指定 tier 准备请求体,必要时应用 Anthropic 专属修复(Phase 2). 仅当 tier 为 Anthropic 时才执行以下处理: - 1. tool_result 重定位 + 孤儿修复(需 normalization.has_anthropic_fixes) + 1. 跨供应商 tool_use/tool_result 配对强制修复(单遍自包含扫描) 2. 条件化 thinking block 剥离(仅跨供应商场景) 确保 Zhipu 等其他 vendor 不受影响。 @@ -241,30 +241,28 @@ def _prepare_body_for_tier( if tier.name != "anthropic": return body - needs_tool_fixes = ( - normalization is not None and normalization.has_anthropic_fixes + needs_tool_pairing = self._needs_tool_pairing_enforcement( + normalization, session_record ) needs_thinking_strip = self._needs_thinking_strip(normalization, session_record) - if not needs_tool_fixes and not needs_thinking_strip: + if not needs_tool_pairing and not needs_thinking_strip: return body from ..server.request_normalizer import ( - apply_anthropic_specific_fixes, + enforce_anthropic_tool_pairing, strip_thinking_blocks, ) body_for_vendor = copy.deepcopy(body) - if needs_tool_fixes: - fixes = apply_anthropic_specific_fixes( + if needs_tool_pairing: + fixes = enforce_anthropic_tool_pairing( body_for_vendor.get("messages", []), - normalization.misplaced_tool_results, - normalization.misplaced_log_info, ) if fixes: logger.debug( - "Applied Anthropic-specific fixes for tier %s: %s", + "Applied tool pairing enforcement for tier %s: %s", tier.name, ", ".join(fixes), ) @@ -279,6 +277,40 @@ def _prepare_body_for_tier( return body_for_vendor + @staticmethod + def _needs_tool_pairing_enforcement( + normalization: Any, session_record: Any + ) -> bool: + """判断是否需要强制执行 Anthropic tool_use/tool_result 配对修复. + + 此方法扩展了原有 ``has_anthropic_fixes`` 的触发条件,覆盖以下场景: + + 1. 请求体中检测到跨供应商产物(如非标准 ID、misplaced tool_result) + 2. Phase 1 检测到需要 Anthropic 修复(misplaced 或 ID 重写) + 3. 会话历史中存在非 Anthropic 供应商记录(如 zhipu) + 4. 无会话追踪能力时安全回退 + + 条件 3 和 4 确保即使请求体本身无跨供应商产物(如 zhipu 使用标准 + ``toolu_*`` ID 时),只要会话曾经过非 Anthropic 供应商,仍会执行配对修复。 + """ + # Signal 1: 当前请求体有跨供应商产物 + if normalization is not None and normalization.has_cross_vendor_signals: + return True + # Signal 2: Phase 1 检测到需要 Anthropic 修复 + if normalization is not None and normalization.has_anthropic_fixes: + return True + # Signal 3: 无会话追踪 → 安全回退 + if session_record is None: + return True + # Signal 4: 会话历史中有非 Anthropic 供应商 + if session_record.provider_state: + non_anthropic = { + v for v in session_record.provider_state if v != "anthropic" + } + if non_anthropic: + return True + return False + @staticmethod def _needs_thinking_strip(normalization: Any, session_record: Any) -> bool: """判断是否需要剥离 thinking blocks(仅跨供应商场景). diff --git a/src/coding/proxy/server/request_normalizer.py b/src/coding/proxy/server/request_normalizer.py index d2adc74..e445870 100644 --- a/src/coding/proxy/server/request_normalizer.py +++ b/src/coding/proxy/server/request_normalizer.py @@ -487,6 +487,150 @@ def _repair_orphaned_tool_use( return repaired +# ── Phase 2: 跨供应商 tool_use/tool_result 配对强制修复 ───────── + + +def enforce_anthropic_tool_pairing( + messages_list: list[dict[str, Any]], +) -> list[str]: + """为跨供应商场景强制保证 Anthropic tool_use/tool_result 配对约束. + + 单次正向遍历所有消息,对每个 assistant 消息执行: + + 1. 剥离所有 tool_result 块(跨供应商产物,如 GLM-5 内联的 tool_result) + 2. 收集所有 tool_use ID + 3. 确保紧邻的下一条消息是 user 消息且包含所有必需的 tool_result + 4. 将剥离的 tool_result 重定位到正确的 user 消息 + 5. 为仍缺失的 tool_result 合成 ``is_error=True`` 的占位块 + + 此函数是一个**自包含的单遍处理**,不依赖 Phase 1 收集的 misplaced 信息, + 通过直接扫描消息列表确保处理的完备性。替代此前多步串联管线 + (剥离 → 重定位 → 孤儿修复)因步骤间隐式依赖导致的漏修问题。 + + 仅在请求实际发送给 Anthropic tier 且检测到跨供应商信号时调用, + 确保 Zhipu 等其他 vendor 不受影响。 + + Args: + messages_list: 消息列表(就地修改)。 + + Returns: + 新增的 adaptation 标签列表。 + """ + adaptations: list[str] = [] + relocated_count = 0 + synthesized_ids: list[str] = [] + + i = 0 + while i < len(messages_list): + msg = messages_list[i] + if not isinstance(msg, dict) or msg.get("role") != "assistant": + i += 1 + continue + + content = msg.get("content") + if not isinstance(content, list): + i += 1 + continue + + # ── A. 从 assistant 消息中剥离所有 tool_result 块 ───────── + extracted_tool_results: dict[str, dict[str, Any]] = {} # tool_use_id → block + retained_content: list[Any] = [] + for block in content: + if isinstance(block, dict) and block.get("type") == "tool_result": + tid = block.get("tool_use_id") + if tid: + extracted_tool_results[tid] = block + relocated_count += 1 + # 无 tool_use_id 的 tool_result 直接丢弃(无效块) + else: + retained_content.append(block) + + if extracted_tool_results: + msg["content"] = retained_content + + # ── B. 收集所有 tool_use ID ─────────────────────────────── + tool_use_ids: list[str] = [ + b["id"] + for b in ( + msg.get("content") if isinstance(msg.get("content"), list) else [] + ) + if isinstance(b, dict) and b.get("type") == "tool_use" and b.get("id") + ] + if not tool_use_ids: + # 无 tool_use 块:若剥离后 content 为空,插入占位 + current_content = msg.get("content") + if isinstance(current_content, list) and not current_content: + msg["content"] = [{"type": "text", "text": ""}] + i += 1 + continue + + # ── C. 确保 messages[i+1] 是 user 消息 ─────────────────── + next_idx = i + 1 + if ( + next_idx < len(messages_list) + and isinstance(messages_list[next_idx], dict) + and messages_list[next_idx].get("role") == "user" + ): + user_msg = messages_list[next_idx] + else: + # 插入合成 user 消息 + user_msg: dict[str, Any] = {"role": "user", "content": []} + messages_list.insert(next_idx, user_msg) + + # ── D. 确保 user_msg.content 是 list ───────────────────── + user_content = user_msg.get("content") + if isinstance(user_content, str): + user_msg["content"] = [{"type": "text", "text": user_content}] + elif not isinstance(user_content, list): + user_msg["content"] = [] + + # ── E. 收集 user 消息中已有的 tool_result IDs ───────────── + existing_result_ids: set[str] = { + b["tool_use_id"] + for b in user_msg["content"] + if isinstance(b, dict) + and b.get("type") == "tool_result" + and b.get("tool_use_id") + } + + # ── F. 为每个 tool_use_id 确保 tool_result 存在 ────────── + for uid in tool_use_ids: + if uid in existing_result_ids: + continue # 已有匹配的 tool_result + + if uid in extracted_tool_results: + # 从 assistant 剥离的 tool_result 重定位到 user + user_msg["content"].append(extracted_tool_results[uid]) + else: + # 完全缺失:合成 is_error=True 占位块 + user_msg["content"].append( + { + "type": "tool_result", + "tool_use_id": uid, + "content": "", + "is_error": True, + } + ) + synthesized_ids.append(uid) + + i += 1 + + # ── 构建 adaptation 标签与日志 ──────────────────────────── + if relocated_count: + adaptations.append("misplaced_tool_result_relocated") + if synthesized_ids: + adaptations.append("orphaned_tool_use_repaired") + logger.warning( + "Vendor degradation adaptation: synthesized %d tool_result block(s) " + "for orphaned tool_use to satisfy Anthropic pairing constraint. " + "Affected tool_use_ids: %s", + len(synthesized_ids), + ", ".join(synthesized_ids), + ) + + return adaptations + + # ── Phase 2: Thinking block 剥离 ────────────────────────────── # 需要从 assistant messages 中剥离的 thinking block 类型 diff --git a/tests/test_request_normalizer.py b/tests/test_request_normalizer.py index 7c34c5a..98ea238 100644 --- a/tests/test_request_normalizer.py +++ b/tests/test_request_normalizer.py @@ -6,6 +6,7 @@ from coding.proxy.server.request_normalizer import ( apply_anthropic_specific_fixes, + enforce_anthropic_tool_pairing, normalize_anthropic_request, strip_thinking_blocks, ) @@ -981,3 +982,513 @@ def test_returns_zero_when_no_thinking(self): } stripped = strip_thinking_blocks(body) assert stripped == 0 + + +# ── enforce_anthropic_tool_pairing 函数测试 ────────────────────── + + +def _enforce_pairing(messages): + """在 messages 上直接执行 enforce_anthropic_tool_pairing,返回 (messages, fixes).""" + fixes = enforce_anthropic_tool_pairing(messages) + return messages, fixes + + +class TestEnforceAnthropicToolPairing: + """验证 enforce_anthropic_tool_pairing 单遍强制配对函数. + + 此函数替代原有多步串联管线(apply_anthropic_specific_fixes), + 通过单次正向遍历完成 tool_result 剥离、重定位和孤儿合成。 + """ + + # ── 基础场景 ──────────────────────────────────────────── + + def test_no_change_when_correctly_paired(self): + """正确配对的 tool_use/tool_result 不受影响.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_ok", + "name": "Bash", + "input": {"command": "ls"}, + }, + ], + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_ok", + "content": "file.txt", + }, + ], + }, + ] + _, fixes = _enforce_pairing(messages) + assert not fixes + assert len(messages) == 2 + assert messages[1]["content"][0]["tool_use_id"] == "toolu_ok" + + def test_strips_tool_result_from_assistant_and_relocates(self): + """从 assistant 剥离 tool_result 并重定位到紧邻 user 消息.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_123", + "name": "Bash", + "input": {"command": "ls"}, + }, + { + "type": "tool_result", + "tool_use_id": "toolu_123", + "content": "output", + }, + ], + }, + { + "role": "user", + "content": "thanks", + }, + ] + _, fixes = _enforce_pairing(messages) + assert "misplaced_tool_result_relocated" in fixes + # assistant 只保留 tool_use + assert len(messages[0]["content"]) == 1 + assert messages[0]["content"][0]["type"] == "tool_use" + # user 消息包含原始文本 + 重定位的 tool_result + user_content = messages[1]["content"] + assert isinstance(user_content, list) + text_blocks = [b for b in user_content if b.get("type") == "text"] + result_blocks = [b for b in user_content if b.get("type") == "tool_result"] + assert len(text_blocks) == 1 + assert text_blocks[0]["text"] == "thanks" + assert len(result_blocks) == 1 + assert result_blocks[0]["tool_use_id"] == "toolu_123" + + def test_synthesizes_missing_tool_result(self): + """缺失 tool_result 时合成 is_error=True 占位块.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_orphan", + "name": "Bash", + "input": {"command": "pwd"}, + }, + ], + }, + { + "role": "user", + "content": [ + {"type": "text", "text": "continue"}, + ], + }, + ] + _, fixes = _enforce_pairing(messages) + assert "orphaned_tool_use_repaired" in fixes + user_content = messages[1]["content"] + synthetic = [b for b in user_content if b.get("is_error") is True] + assert len(synthetic) == 1 + assert synthetic[0]["tool_use_id"] == "toolu_orphan" + + # ── Zhipu 特征场景 ────────────────────────────────────── + + def test_zhipu_3_tool_use_1_misplaced_result(self): + """zhipu 典型产物: 3 tool_use + 1 misplaced tool_result,修复后完整配对.""" + messages = [ + {"role": "user", "content": "run tools"}, + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_normalized_5", + "name": "Bash", + "input": {}, + }, + { + "type": "tool_use", + "id": "toolu_normalized_6", + "name": "Read", + "input": {}, + }, + { + "type": "tool_use", + "id": "toolu_normalized_7", + "name": "Write", + "input": {}, + }, + { + "type": "tool_result", + "tool_use_id": "toolu_normalized_5", + "content": "result from zhipu", + }, + ], + }, + {"role": "user", "content": "continue"}, + ] + _, fixes = _enforce_pairing(messages) + assert "misplaced_tool_result_relocated" in fixes + assert "orphaned_tool_use_repaired" in fixes + # assistant 只保留 3 个 tool_use + assert len(messages[1]["content"]) == 3 + assert all(b["type"] == "tool_use" for b in messages[1]["content"]) + # user 消息包含所有 3 个 tool_result + user_content = messages[2]["content"] + result_ids = { + b["tool_use_id"] + for b in user_content + if isinstance(b, dict) and b.get("type") == "tool_result" + } + assert result_ids == { + "toolu_normalized_5", + "toolu_normalized_6", + "toolu_normalized_7", + } + + def test_zhipu_all_3_results_in_assistant(self): + """zhipu 产物: 3 tool_use + 3 tool_result 都在 assistant 中.""" + messages = [ + { + "role": "assistant", + "content": [ + {"type": "tool_use", "id": "toolu_A", "name": "Bash", "input": {}}, + {"type": "tool_use", "id": "toolu_B", "name": "Read", "input": {}}, + {"type": "tool_use", "id": "toolu_C", "name": "Write", "input": {}}, + {"type": "tool_result", "tool_use_id": "toolu_A", "content": "a"}, + {"type": "tool_result", "tool_use_id": "toolu_B", "content": "b"}, + {"type": "tool_result", "tool_use_id": "toolu_C", "content": "c"}, + ], + }, + {"role": "user", "content": "thanks"}, + ] + _, fixes = _enforce_pairing(messages) + assert "misplaced_tool_result_relocated" in fixes + assert "orphaned_tool_use_repaired" not in fixes + # assistant 只保留 tool_use + assert len(messages[0]["content"]) == 3 + # user 消息含所有 tool_result + result_ids = { + b["tool_use_id"] + for b in messages[1]["content"] + if b.get("type") == "tool_result" + } + assert result_ids == {"toolu_A", "toolu_B", "toolu_C"} + + def test_no_subsequent_user_message_inserts_synthetic(self): + """assistant 是最后一条消息时插入合成 user 消息.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_last", + "name": "Bash", + "input": {}, + }, + { + "type": "tool_result", + "tool_use_id": "toolu_last", + "content": "done", + }, + ], + }, + ] + _, fixes = _enforce_pairing(messages) + assert "misplaced_tool_result_relocated" in fixes + assert len(messages) == 2 + assert messages[1]["role"] == "user" + assert messages[1]["content"][0]["tool_use_id"] == "toolu_last" + + # ── 边缘情况 ────────────────────────────────────────── + + def test_user_content_string_converted_to_list(self): + """next user 消息 content 为字符串时正确转换为 list.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_str", + "name": "Bash", + "input": {}, + }, + ], + }, + {"role": "user", "content": "hello"}, + ] + _, fixes = _enforce_pairing(messages) + assert "orphaned_tool_use_repaired" in fixes + user_content = messages[1]["content"] + assert isinstance(user_content, list) + assert user_content[0] == {"type": "text", "text": "hello"} + assert user_content[1]["type"] == "tool_result" + assert user_content[1]["tool_use_id"] == "toolu_str" + + def test_assistant_content_becomes_empty_gets_placeholder(self): + """assistant 仅含 tool_result 无 tool_use,剥离后插入占位块.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_stray", + "content": "x", + }, + ], + }, + {"role": "user", "content": "next"}, + ] + _, fixes = _enforce_pairing(messages) + assert "misplaced_tool_result_relocated" in fixes + # assistant content 不为空(有占位) + assert len(messages[0]["content"]) == 1 + assert messages[0]["content"][0] == {"type": "text", "text": ""} + + def test_duplicate_tool_result_in_user_not_duplicated(self): + """user 已有 tool_result 时不重复添加.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_dup", + "name": "Bash", + "input": {}, + }, + { + "type": "tool_result", + "tool_use_id": "toolu_dup", + "content": "misplaced", + }, + ], + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_dup", + "content": "correct", + }, + ], + }, + ] + _, fixes = _enforce_pairing(messages) + # misplaced 被剥离但不重复添加(user 已有) + result_blocks = [ + b for b in messages[1]["content"] if b.get("type") == "tool_result" + ] + assert len(result_blocks) == 1 + assert result_blocks[0]["content"] == "correct" + + def test_idempotent_multiple_runs(self): + """多次调用结果一致(幂等性).""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_idem", + "name": "Bash", + "input": {}, + }, + ], + }, + {"role": "user", "content": "go"}, + ] + _enforce_pairing(messages) + snapshot = copy.deepcopy(messages) + _, fixes2 = _enforce_pairing(messages) + # 第二次运行不应产生新的修复 + assert not fixes2 + assert messages == snapshot + + def test_complex_multi_turn_conversation(self): + """模拟真实 bug 场景:多轮 tool_use,部分有 misplaced,部分纯孤儿.""" + messages = [ + {"role": "user", "content": "start"}, + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_normalized_1", + "name": "Bash", + "input": {}, + }, + { + "type": "tool_use", + "id": "toolu_normalized_2", + "name": "Read", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_normalized_1", + "content": "ok1", + }, + { + "type": "tool_result", + "tool_use_id": "toolu_normalized_2", + "content": "ok2", + }, + ], + }, + { + "role": "assistant", + "content": [ + {"type": "text", "text": "Now running more tools..."}, + { + "type": "tool_use", + "id": "toolu_normalized_5", + "name": "Bash", + "input": {}, + }, + { + "type": "tool_use", + "id": "toolu_normalized_6", + "name": "Read", + "input": {}, + }, + { + "type": "tool_use", + "id": "toolu_normalized_7", + "name": "Write", + "input": {}, + }, + { + "type": "tool_result", + "tool_use_id": "toolu_normalized_5", + "content": "zhipu inline result", + }, + ], + }, + {"role": "user", "content": "continue"}, + ] + _, fixes = _enforce_pairing(messages) + # 第一个 assistant(索引 1)已正确配对,不受影响 + assert len(messages[1]["content"]) == 2 + assert messages[2]["content"][0]["tool_use_id"] == "toolu_normalized_1" + # 第二个 assistant(索引 3): misplaced 被剥离,孤儿被合成 + assert "misplaced_tool_result_relocated" in fixes + assert "orphaned_tool_use_repaired" in fixes + assistant_content = messages[3]["content"] + assert all(b["type"] != "tool_result" for b in assistant_content) + assert assistant_content[0] == { + "type": "text", + "text": "Now running more tools...", + } + # user 消息(索引 4)包含所有 3 个 tool_result + user_content = messages[4]["content"] + result_ids = { + b["tool_use_id"] + for b in user_content + if isinstance(b, dict) and b.get("type") == "tool_result" + } + assert result_ids == { + "toolu_normalized_5", + "toolu_normalized_6", + "toolu_normalized_7", + } + + def test_next_message_is_assistant_inserts_user(self): + """下一条消息不是 user 而是 assistant 时,插入合成 user 消息.""" + messages = [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_gap", + "name": "Bash", + "input": {}, + }, + ], + }, + { + "role": "assistant", + "content": [{"type": "text", "text": "follow up"}], + }, + ] + _, fixes = _enforce_pairing(messages) + assert "orphaned_tool_use_repaired" in fixes + assert len(messages) == 3 + assert messages[0]["content"][0]["type"] == "tool_use" + assert messages[1]["role"] == "user" + assert messages[1]["content"][0]["type"] == "tool_result" + assert messages[2]["role"] == "assistant" + + def test_phase1_then_enforce_pairing(self): + """Phase 1 + enforce_anthropic_tool_pairing 端到端测试(模拟完整链路).""" + result = normalize_anthropic_request( + { + "messages": [ + {"role": "user", "content": "hello"}, + { + "role": "assistant", + "content": [ + { + "type": "server_tool_use", + "id": "srvtoolu_X", + "name": "Bash", + "input": {"command": "ls"}, + }, + { + "type": "server_tool_use", + "id": "srvtoolu_Y", + "name": "Read", + "input": {"path": "/tmp"}, + }, + { + "type": "tool_result", + "tool_use_id": "srvtoolu_X", + "content": "zhipu result", + }, + ], + }, + {"role": "user", "content": "continue"}, + ], + } + ) + assert result.recoverable + # Phase 1 重写了 ID,收集了 misplaced + assert result.tool_id_map + assert result.misplaced_tool_results + + # 在 deep copy 上执行 enforce_anthropic_tool_pairing(模拟 executor) + body_copy = copy.deepcopy(result.body) + fixes = enforce_anthropic_tool_pairing(body_copy.get("messages", [])) + assert "misplaced_tool_result_relocated" in fixes + assert "orphaned_tool_use_repaired" in fixes + + messages = body_copy["messages"] + # assistant 只保留 2 个 tool_use + assistant_content = messages[1]["content"] + assert len(assistant_content) == 2 + assert all(b["type"] == "tool_use" for b in assistant_content) + # user 消息包含 2 个 tool_result + user_content = messages[2]["content"] + result_blocks = [b for b in user_content if b.get("type") == "tool_result"] + assert len(result_blocks) == 2 + expected_ids = {b["id"] for b in assistant_content} + result_ids = {b["tool_use_id"] for b in result_blocks} + assert result_ids == expected_ids From a4778f1d1e3d89fa8367324f911d5f5887ad2bd5 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 21:34:30 +0800 Subject: [PATCH 17/32] =?UTF-8?q?build(version):=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8D=87=E7=BA=A7=E8=87=B3=200.2.4a4;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude) Co-Authored-By: Aurelius Huang --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index 26854a9..a7dd386 100644 --- a/uv.lock +++ b/uv.lock @@ -74,7 +74,7 @@ wheels = [ [[package]] name = "coding-proxy" -version = "0.2.4a3" +version = "0.2.4a4" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From 62b4ad27b179d60b8dfb88d95f13f2c5b01ba8bc Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 21:35:03 +0800 Subject: [PATCH 18/32] =?UTF-8?q?build(version):=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=20pyproject.toml=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E8=87=B3=200.2.4a4;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude) Co-Authored-By: Aurelius Huang --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 3015d05..37c929d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "coding-proxy" -version = "0.2.4a3" +version = "0.2.4a4" description = "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..." readme = "README.md" requires-python = ">=3.12" From 51e43fc74f42b943ec1b9ed39bc0106d8d029d71 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 22:37:54 +0800 Subject: [PATCH 19/32] =?UTF-8?q?docs(framework):=20=E6=AD=A3=E4=BA=A4?= =?UTF-8?q?=E5=88=86=E8=A7=A3=E6=9E=B6=E6=9E=84=E6=96=87=E6=A1=A3=E4=B8=BA?= =?UTF-8?q?=E6=9E=A2=E7=BA=BD+=E4=B8=93=E9=A2=98=E5=AD=90=E6=96=87?= =?UTF-8?q?=E6=A1=A3=EF=BC=8C=E5=90=8C=E6=AD=A5=E4=BB=A3=E7=A0=81=E5=BA=93?= =?UTF-8?q?=E4=BA=8B=E5=AE=9E;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 1,641 行单体 framework.md 拆分为 499 行枢纽文档 + 6 个专题子文档: - arch/config-reference.md:弹性参数规范来源(SSOT),消除 3 倍重复 - arch/design-patterns.md:13 种设计模式,补充 NativeAnthropicVendor 层级 - arch/vendors.md:供应商分类体系(直接/协议转换/原生兼容),补全 9 个供应商 - arch/routing.md:12 个路由子模块详解 - arch/convert.md:三向格式转换 - arch/testing.md:48 个测试文件按子系统分组 修正:删除不存在的 backends/ 引用,修正 compat_state.db → compat.db 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- docs/arch/config-reference.md | 259 ++++++ docs/arch/convert.md | 101 +++ docs/arch/design-patterns.md | 608 ++++++++++++++ docs/arch/routing.md | 180 +++++ docs/arch/testing.md | 114 +++ docs/arch/vendors.md | 396 +++++++++ docs/framework.md | 1413 ++++----------------------------- 7 files changed, 1794 insertions(+), 1277 deletions(-) create mode 100644 docs/arch/config-reference.md create mode 100644 docs/arch/convert.md create mode 100644 docs/arch/design-patterns.md create mode 100644 docs/arch/routing.md create mode 100644 docs/arch/testing.md create mode 100644 docs/arch/vendors.md diff --git a/docs/arch/config-reference.md b/docs/arch/config-reference.md new file mode 100644 index 0000000..b82ac42 --- /dev/null +++ b/docs/arch/config-reference.md @@ -0,0 +1,259 @@ +# 配置字段参考 + +> **路径约定**:本文档中模块路径均相对于 `src/coding/proxy/`。 +> +> **定位**:本文档是所有配置参数的**规范来源(Single Source of Truth)**。设计模式章节和模块详情中引用参数默认值时,统一链接至此。 + +[TOC] + +--- + +## 1. 配置模块结构 + +配置模型已从单体 `schema.py` 正交拆分为 5 个子模块: + +| 子模块 | 文件 | 核心类型 | +| --------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **server** | [`config/server.py`](../../src/coding/proxy/config/server.py) | `ServerConfig`, `DatabaseConfig`, `LoggingConfig` | +| **vendors** | [`config/vendors.py`](../../src/coding/proxy/config/vendors.py) | `AnthropicConfig`, `CopilotConfig`, `AntigravityConfig`, `ZhipuConfig`, `MinimaxConfig`, `KimiConfig`, `DoubaoConfig`, `XiaomiConfig`, `AlibabaConfig` | +| **resiliency** | [`config/resiliency.py`](../../src/coding/proxy/config/resiliency.py) | `CircuitBreakerConfig`, `RetryConfig`, `FailoverConfig`, `QuotaGuardConfig` | +| **routing** | [`config/routing.py`](../../src/coding/proxy/config/routing.py) | `VendorType`, `VendorConfig`, `ModelMappingRule`, `ModelPricingEntry` | +| **auth_schema** | [`config/auth_schema.py`](../../src/coding/proxy/config/auth_schema.py) | `AuthConfig` | + +`config/schema.py` 作为聚合入口点 re-export 所有符号,并保留 `ProxyConfig` 顶层模型及旧格式迁移逻辑。 + +--- + +## 2. 配置搜索优先级 + +[`config/loader.py`](../../src/coding/proxy/config/loader.py) 按以下顺序搜索配置文件: + +```mermaid +flowchart TD + A["CLI --config 参数
(显式指定)"] -->|"未指定"| B["./config.yaml
(项目根目录)"] + B -->|"不存在"| C["~/.coding-proxy/config.yaml
(用户目录)"] + C -->|"不存在"| D["Pydantic 默认值"] + + style A fill:#1a5276,color:#fff + style D fill:#7b241c,color:#fff +``` + +**环境变量展开**:语法 `${VARIABLE_NAME}`,递归处理 dict/list/str,未定义变量保留原文。 + +--- + +## 3. 服务器配置 + +### 3.1 ServerConfig + +| 字段 | 类型 | 默认值 | 说明 | +| ------ | ---- | ------------- | -------- | +| `host` | str | `"127.0.0.1"` | 监听地址 | +| `port` | int | `8046` | 监听端口 | + +### 3.2 DatabaseConfig + +| 字段 | 类型 | 默认值 | 说明 | +| -------------------------- | ---- | ----------------------------- | --------------------- | +| `path` | str | `"~/.coding-proxy/usage.db"` | SQLite 数据库文件路径 | +| `compat_state_path` | str | `"~/.coding-proxy/compat.db"` | 兼容性会话存储路径 | +| `compat_state_ttl_seconds` | int | `86400` | 兼容性会话 TTL(秒) | + +### 3.3 LoggingConfig + +| 字段 | 类型 | 默认值 | 说明 | +| -------------- | ----------- | -------- | ------------------------------------------------------------ | +| `level` | str | `"INFO"` | 控制台日志级别 | +| `file` | str \| null | `null` | 文件日志路径(`null` 时输出到控制台) | +| `max_bytes` | int | `5242880` | 单个日志文件最大字节数(5 MB),触发轮转 | +| `backup_count` | int | `5` | 保留的已压缩备份文件数 | + +### 3.4 AuthConfig + +| 字段 | 类型 | 默认值 | 说明 | +| ------------------ | ---- | ------ | ------------------------------------ | +| `token_store_path` | str | `""` | Token Store 文件路径(空则使用默认) | + +--- + +## 4. VendorConfig 通用字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ------------ | ---- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `vendor` | enum | -- | 供应商类型:`anthropic` / `copilot` / `antigravity` / `zhipu` / `minimax` / `kimi` / `doubao` / `xiaomi` / `alibaba` | +| `enabled` | bool | `true` | 是否启用 | +| `base_url` | str | `""` | API 基础 URL(留空使用各供应商默认值) | +| `timeout_ms` | int | `300000` | 请求超时(毫秒) | + +--- + +## 5. VendorConfig 弹性字段 + +| 字段 | 类型 | 默认值 | 说明 | +| -------------------- | -------------- | -------------------- | --------------------------- | +| `circuit_breaker` | config \| None | `None` | 熔断器配置(None = 终端层) | +| `retry` | config | `RetryConfig()` | 重试策略配置 | +| `quota_guard` | config | `QuotaGuardConfig()` | 日度配额守卫配置 | +| `weekly_quota_guard` | config | `QuotaGuardConfig()` | 周度配额守卫配置 | + + + +### 5.1 CircuitBreakerConfig — 熔断器参数 + +> **设计语义**:参见 [设计模式 -- Circuit Breaker](./design-patterns.md#circuit-breaker) + +| 字段 | 类型 | 默认值 | 说明 | +| -------------------------- | ---- | ------ | -------------------------------- | +| `failure_threshold` | int | `3` | 触发 OPEN 的连续失败次数 | +| `recovery_timeout_seconds` | int | `300` | OPEN → HALF_OPEN 等待秒数 | +| `success_threshold` | int | `2` | HALF_OPEN → CLOSED 所需连续成功数 | +| `max_recovery_seconds` | int | `3600` | 指数退避最大恢复时间(秒) | + +### 5.2 QuotaGuardConfig — 配额守卫参数 + +> **设计语义**:参见 [设计模式 -- QuotaGuard State Machine](./design-patterns.md#quota-guard) + +| 字段 | 类型 | 默认值 | 说明 | +| ------------------------ | ----- | ------- | ------------------------------------ | +| `enabled` | bool | `false` | 是否启用配额守卫 | +| `token_budget` | int | `0` | 滑动窗口内的 Token 预算上限 | +| `window_hours` | float | `5.0` | 滑动窗口大小(小时) | +| `threshold_percent` | float | `99.0` | 触发 QUOTA_EXCEEDED 的用量百分比阈值 | +| `probe_interval_seconds` | int | `300` | QUOTA_EXCEEDED 状态下探测间隔(秒) | + +### 5.3 RetryConfig — 重试策略参数 + +> **设计语义**:参见 [设计模式 -- Retry with Full Jitter](./design-patterns.md#retry) + +| 字段 | 类型 | 默认值 | 说明 | +| -------------------- | ----- | ------ | ------------ | +| `max_retries` | int | `2` | 最大重试次数 | +| `initial_delay_ms` | int | `500` | 初始延迟(毫秒) | +| `max_delay_ms` | int | `5000` | 最大延迟(毫秒) | +| `backoff_multiplier` | float | `2.0` | 退避倍数 | +| `jitter` | bool | `true` | 是否启用抖动 | + +### 5.4 FailoverConfig — 故障转移参数 + +> **设计语义**:参见 [请求生命周期 -- 故障转移判定](../framework.md#fault-overhead) + +| 字段 | 类型 | 默认值 | +| ------------------------- | ------------ | ----------------------------------------------- | +| `status_codes` | list[int] | `[429, 403, 503, 500]` | +| `error_types` | list[str] | `["rate_limit_error", "overloaded_error", "api_error"]` | +| `error_message_patterns` | list[str] | `["quota", "limit exceeded", "usage cap", "capacity"]` | + +--- + +## 6. 供应商专属字段 + +### 6.1 Copilot 专属字段 + +| 字段 | 类型 | 默认值 | 说明 | +| -------------------------- | ---- | --------------- | -------------------------------------------------- | +| `github_token` | str | `""` | GitHub OAuth token / PAT(支持 `${ENV_VAR}`) | +| `account_type` | str | `"individual"` | 账号类型:`individual` / `business` / `enterprise` | +| `token_url` | str | `"https://..."` | Token 交换端点 | +| `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL | + +### 6.2 Antigravity 专属字段 + +| 字段 | 类型 | 默认值 | 说明 | +| ---------------- | ---- | ----------------------------------- | --------------------------- | +| `client_id` | str | `""` | Google OAuth2 Client ID | +| `client_secret` | str | `""` | Google OAuth2 Client Secret | +| `refresh_token` | str | `""` | Google OAuth2 Refresh Token | +| `model_endpoint` | str | `"models/claude-sonnet-4-20250514"` | Gemini 模型端点路径 | + +### 6.3 原生 Anthropic 兼容供应商共用字段 + +适用于 `zhipu` / `minimax` / `kimi` / `doubao` / `xiaomi` / `alibaba`。 + +| 字段 | 类型 | 默认值 | 说明 | +| --------- | ---- | ------ | ------------------------------ | +| `api_key` | str | `""` | API Key(支持 `${ENV_VAR}`) | + +--- + +## 7. 模型映射规则 + +### 7.1 ModelMappingRule 字段 + +| 字段 | 类型 | 说明 | +| ---------- | --------- | ------------------------------------------ | +| `pattern` | str | 匹配模式(精确/通配符/正则) | +| `target` | str | 目标模型名称 | +| `is_regex` | bool | 是否为正则表达式(默认 `false`) | +| `vendors` | list[str] | 规则作用域(留空应用于所有原生兼容供应商) | + +### 7.2 ModelPricingEntry 字段 + +| 字段 | 类型 | 说明 | +| --------------------------- | ----- | ---------------------------------------------------- | +| `vendor` | str | 供应商名称 | +| `model` | str | 实际模型名 | +| `input_cost_per_mtok` | float | 输入 Token 单价($/百万 token,支持 `$`/`¥` 前缀) | +| `output_cost_per_mtok` | float | 输出 Token 单价 | +| `cache_write_cost_per_mtok` | float | 缓存创建 Token 单价 | +| `cache_read_cost_per_mtok` | float | 缓存读取 Token 单价 | + +--- + +## 8. tiers — 显式优先级 + +| 字段 | 类型 | 说明 | +| ------- | ------------------------ | ------------------------------------------- | +| `tiers` | list[VendorType] \| None | 降级链路优先级(None 时回退 vendors 顺序) | + +--- + +## 9. vendors 列表格式(推荐) + +推荐使用 `vendors` 列表格式,每个 vendor 自包含其弹性配置: + +```yaml +vendors: + - vendor: anthropic + enabled: true + base_url: https://api.anthropic.com + timeout_ms: 300000 + circuit_breaker: + failure_threshold: 3 + recovery_timeout_seconds: 300 + quota_guard: + enabled: false + weekly_quota_guard: + enabled: false + + - vendor: copilot + enabled: false + github_token: "${GITHUB_TOKEN}" + account_type: individual + circuit_breaker: + failure_threshold: 3 + quota_guard: + enabled: true + token_budget: 3000000 + window_hours: 4.0 + + - vendor: zhipu + enabled: true + api_key: "${ZHIPU_API_KEY}" + # 无 circuit_breaker -> 终端层 + + - vendor: minimax + enabled: false + api_key: "${MINIMAX_API_KEY}" + +tiers: [anthropic, copilot, zhipu] # 显式优先级(可选) +``` + +### Legacy Flat 格式(向后兼容) + +旧的 flat 格式字段(`primary`/`copilot`/`antigravity`/`fallback`/`circuit_breaker`/`*_quota_guard`)仍受支持,通过 `ProxyConfig._migrate_legacy_fields()` 自动迁移为 vendors 列表格式。 + +迁移规则: +1. `anthropic` 字段名 → `primary` +2. `zhipu` 字段名 → `fallback` +3. 若无 `vendors` 字段,从 legacy flat 字段自动生成 vendors 列表 +4. 迁移时发出 INFO 日志建议迁移至新格式 diff --git a/docs/arch/convert.md b/docs/arch/convert.md new file mode 100644 index 0000000..1697247 --- /dev/null +++ b/docs/arch/convert.md @@ -0,0 +1,101 @@ +# 格式转换模块(convert/) + +> **路径约定**:本文档中模块路径均相对于 `src/coding/proxy/`。 +> +> **定位**:从 `framework.md` 提取,详述 Anthropic ↔ Gemini ↔ OpenAI 三向格式转换。 + +[TOC] + +--- + +## 1. 模块总览 + +[`convert/`](../../src/coding/proxy/convert/) 模块提供独立的纯函数适配器层,支持三向格式转换: + +| 转换方向 | 模块 | 说明 | +| --------------------------- | ---------------------------------------------------------------------------------------------- | ------------------ | +| Anthropic → Gemini | [`convert/anthropic_to_gemini.py`](../../src/coding/proxy/convert/anthropic_to_gemini.py) | 请求格式转换 | +| Gemini → Anthropic | [`convert/gemini_to_anthropic.py`](../../src/coding/proxy/convert/gemini_to_anthropic.py) | 响应格式转换 | +| Gemini SSE → Anthropic SSE | [`convert/gemini_sse_adapter.py`](../../src/coding/proxy/convert/gemini_sse_adapter.py) | 流式事件重构 | +| Anthropic → OpenAI | [`convert/anthropic_to_openai.py`](../../src/coding/proxy/convert/anthropic_to_openai.py) | Copilot 请求适配 | +| OpenAI → Anthropic | [`convert/openai_to_anthropic.py`](../../src/coding/proxy/convert/openai_to_anthropic.py) | Copilot 响应逆适配 | + +--- + +## 2. 请求转换(Anthropic → Gemini) + +**应用位置**:[`convert/anthropic_to_gemini.py`](../../src/coding/proxy/convert/anthropic_to_gemini.py) -- `convert_request()` + +**转换映射**: + +| Anthropic 字段 | Gemini 字段 | 说明 | +| --------------------------------- | ---------------------------------- | -------------------------------------------------- | +| `system`(str \| list) | `systemInstruction.parts[].text` | 支持字符串和文本块列表两种格式 | +| `messages[]` | `contents[]` | 角色映射:`assistant` → `model`,`user` → `user` | +| `content`(text) | `parts[].text` | 文本内容块 | +| `content`(image) | `parts[].inlineData` | Base64 数据 + MIME 类型 | +| `content`(tool_use) | `parts[].functionCall` | `name` + `input` → `args` | +| `content`(tool_result) | `parts[].functionResponse` | `tool_use_id` → `name`,`content` → `result` | +| `max_tokens` | `generationConfig.maxOutputTokens` | | +| `temperature` / `top_p` / `top_k` | `generationConfig.*` | 参数名驼峰转换 | +| `stop_sequences` | `generationConfig.stopSequences` | | + +**不支持的字段**(静默剥离并记录 WARNING):`tools`、`tool_choice`、`metadata`、`extended_thinking`、`thinking` + +--- + +## 3. 响应转换(Gemini → Anthropic) + +**应用位置**:[`convert/gemini_to_anthropic.py`](../../src/coding/proxy/convert/gemini_to_anthropic.py) -- `convert_response()` / `extract_usage()` + +**finishReason 映射**: + +| Gemini | Anthropic | +| --------------------------------- | ------------ | +| `STOP` | `end_turn` | +| `MAX_TOKENS` | `max_tokens` | +| `SAFETY` / `RECITATION` / `OTHER` | `end_turn` | + +**Parts 转换**: +- `text` → `{"type": "text", "text": "..."}` +- `functionCall` → `{"type": "tool_use", "id": "toolu_...", "name": "...", "input": {...}}` + +**Usage 提取**: +- `usageMetadata.promptTokenCount` → `input_tokens` +- `usageMetadata.candidatesTokenCount` → `output_tokens` +- 缓存字段填 0(Gemini 不直接暴露缓存信息) + +--- + +## 4. SSE 流适配 + +**应用位置**:[`convert/gemini_sse_adapter.py`](../../src/coding/proxy/convert/gemini_sse_adapter.py) -- `adapt_sse_stream()` + +将 Gemini SSE 流重构为 Anthropic 消息生命周期事件序列: + +```mermaid +flowchart LR + Input["Gemini SSE chunks"] --> MS["message_start
← 首次收到内容时发出"] + MS --> CBS["content_block_start
← 内容块开始"] + CBS --> CBD["content_block_delta*
← 增量文本"] + CBD --> CBS2["content_block_stop
← 内容块结束"] + CBS2 --> MD["message_delta
← stop_reason + output_tokens"] + MD --> MSP["message_stop
← 消息结束"] + + style Input fill:#1a5276,color:#fff + style MSP fill:#196f3d,color:#fff +``` + +**边界情况处理**: +- 空 parts 后跟有 text 的 chunk → 延迟发出 `message_start` + `content_block_start` +- 流结束但未收到 `finishReason` → 补发默认 `message_delta`(`stop_reason: "end_turn"`)+ `message_stop` + +--- + +## 5. OpenAI 格式转换 + +**应用位置**: +- [`convert/anthropic_to_openai.py`](../../src/coding/proxy/convert/anthropic_to_openai.py) -- Anthropic → OpenAI Chat Completions 请求格式 +- [`convert/openai_to_anthropic.py`](../../src/coding/proxy/convert/openai_to_anthropic.py) -- OpenAI Chat Completions → Anthropic 响应格式 + +专为 CopilotVendor 适配,处理 Anthropic Messages API 与 OpenAI Chat Completions API 之间的双向格式差异(角色映射、工具格式、usage 字段名等)。 diff --git a/docs/arch/design-patterns.md b/docs/arch/design-patterns.md new file mode 100644 index 0000000..1187a0b --- /dev/null +++ b/docs/arch/design-patterns.md @@ -0,0 +1,608 @@ +# 设计模式详解 + +> **路径约定**:本文档中模块路径均相对于 `src/coding/proxy/`。 +> +> **定位**:本文档从 `framework.md` 中提取,详细阐述 coding-proxy 中运用的 13 种设计模式与工程模式。 + +[TOC] + +--- + +本章涵盖 coding-proxy 中运用的 **13 种设计模式与工程模式**,按职责域正交分为三类:**创建型**(对象构建策略)、**结构型**(组件组织方式)、**行为型与并发**(运行时行为控制)。 + +```mermaid +mindmap + root((设计模式)) + 创建型 + Strategy + Factory + Template Method + 结构型 + Proxy :: 整体架构 + Adapter :: Vendor层 + Composite :: VendorTier + Facade :: RequestRouter + 行为型/并发 + Circuit Breaker + Priority Chain + State Machine :: QuotaGuard + Double-Check Locking + Capability Routing + Retry Full Jitter + Rate Limit Deadline +``` + +--- + +## 3.1 Template Method(模板方法模式) + +> **经典出处**:GoF《Design Patterns: Elements of Reusable Object-Oriented Software》[[1]](#ref1) — 定义算法骨架,将某些步骤延迟到子类实现。 + +**应用位置**:[`vendors/base.py`](../../src/coding/proxy/vendors/base.py) — `BaseVendor` 抽象基类 + +**设计要点**: + +`BaseVendor` 定义了请求处理的算法骨架,将差异化的逻辑延迟到子类: + +```mermaid +classDiagram + direction TB + + class BaseVendor { + <> + +send_message() VendorResponse + +send_message_stream() AsyncIterator + +get_name()* str + +_prepare_request()* tuple + +map_model() str + +_get_endpoint() str + +_pre_send_check() + +_normalize_error_response() + +_on_error_status() + +get_capabilities() VendorCapabilities + +supports_request() tuple + +make_compatibility_decision() CompatibilityDecision + +check_health() bool + +should_trigger_failover() bool + +close() + } + + class NativeAnthropicVendor { + <> + _prepare_request() 模型映射+API Key + map_model() 委托ModelMapper + _normalize_error_response() 401归一化 + } + + class AnthropicVendor { + _prepare_request() 过滤 hop-by-hop 头 + } + + class CopilotVendor { + _prepare_request() 过滤头+异步token注入 + _on_error_status() 401/403 token失效 + } + + class AntigravityVendor { + _prepare_request() Gemini格式转换+OAuth + check_health() OAuth有效性检查 + _on_error_status() 401/403 token失效 + } + + class ZhipuVendor { + _vendor_name = "zhipu" + } + + class MinimaxVendor { + _vendor_name = "minimax" + } + + BaseVendor <|-- NativeAnthropicVendor + BaseVendor <|-- AnthropicVendor + BaseVendor <|-- CopilotVendor + BaseVendor <|-- AntigravityVendor + NativeAnthropicVendor <|-- ZhipuVendor + NativeAnthropicVendor <|-- MinimaxVendor + + style BaseVendor fill:#1a5276,color:#fff + style NativeAnthropicVendor fill:#2e4053,color:#fff + style AnthropicVendor fill:#2874a6,color:#fff + style CopilotVendor fill:#2874a6,color:#fff + style AntigravityVendor fill:#2874a6,color:#fff + style ZhipuVendor fill:#7b241c,color:#fff + style MinimaxVendor fill:#7b241c,color:#fff +``` + +三类 Vendor 子类的差异化实现: + +| 方法 | AnthropicVendor(直接透传) | CopilotVendor(协议转换) | AntigravityVendor(协议转换) | NativeAnthropicVendor 子类(薄透传) | +| -------------------- | --------------------------- | ------------------------------- | ---------------------------------- | ------------------------------------ | +| `_prepare_request()` | 过滤 hop-by-hop 头 | 过滤头 + 异步 token 注入 | Gemini 格式转换 + OAuth token | 模型映射 + API Key 替换 | +| `map_model()` | 恒等映射 | 恒等映射 | 恒等映射 | **委托 ModelMapper** | +| `_get_endpoint()` | `/v1/messages` | `/v1/chat/completions` | `/{model}:generateContent` | `/v1/messages`(继承) | +| `_on_error_status()` | 继承基类(空操作) | 401/403 token 失效 | 401/403 token 失效 | 继承基类(空操作) | +| `get_capabilities()` | 全部支持 | 不支持 thinking | 不支持 tools/thinking/metadata | 全部支持(NATIVE) | +| `check_health()` | 继承(True) | 继承(True) | **覆写**(OAuth token 有效性检查) | 继承(True) | + +> **供应商分类体系**详情参见 [供应商模块 -- 分类体系](./vendors.md#vendor-classification)。 + +--- + +## 3.2 Circuit Breaker(熔断器模式) + + + +> **经典出处**:Martin Fowler "CircuitBreaker" (2014)[[2]](#ref2);M. Nygard《Release It! Design and Deploy Production-Ready Software》第 5 章[[3]](#ref3) — 通过快速失败防止级联故障。 + +**应用位置**:[`routing/circuit_breaker.py`](../../src/coding/proxy/routing/circuit_breaker.py) — `CircuitBreaker` 类 + +**状态机**: + +```mermaid +stateDiagram-v2 + [*] --> CLOSED + + CLOSED --> OPEN : 连续 N 次失败\n(failure_threshold) + note right of OPEN : 熔断状态 — 快速失败 + + OPEN --> HALF_OPEN : 超时恢复\n(recovery_timeout_seconds) + + HALF_OPEN --> CLOSED : 连续 M 次成功\n(success_threshold) + note right of HALF_OPEN : 试探状态 + + HALF_OPEN --> OPEN : 任意一次失败\n(退避 × 2) + + CLOSED --> [*] +``` + +**状态转换条件**: + +| 转换 | 条件 | +| ------------------ | --------------------------------------- | +| CLOSED → OPEN | 连续失败次数 ≥ `failure_threshold` | +| OPEN → HALF_OPEN | 距上次失败 ≥ `recovery_timeout_seconds` | +| HALF_OPEN → CLOSED | 连续成功次数 ≥ `success_threshold` | +| HALF_OPEN → OPEN | 任意一次失败 | + +**指数退避 (Exponential Backoff)**:每次从 HALF_OPEN 回退到 OPEN 时,恢复等待时间翻倍(`recovery_timeout *= 2`),上限为 `max_recovery_seconds`。避免对仍未恢复的后端频繁重试。 + +**线程安全**:所有状态变更通过 `threading.Lock` 保护,确保并发请求下状态一致。 + +> **参数默认值**:参见 [配置参考 -- CircuitBreakerConfig](./config-reference.md#elastic-params) + +--- + +## 3.3 Priority Chain(优先级匹配链) + +**应用位置**:[`routing/model_mapper.py`](../../src/coding/proxy/routing/model_mapper.py) — `ModelMapper` 类 + +**设计要点**: + +ModelMapper 采用三级优先级匹配链,按精确度递减依次尝试: + +```mermaid +flowchart TD + A["输入模型名称"] --> B{"① 精确匹配
pattern == model"} + + B -- "命中" --> C["返回 target"] + B -- "未命中" --> D{"② 模式匹配
Regex / Glob"} + + D -- "is_regex=true" --> E["re.fullmatch()"] + D -- "含 *" --> F["fnmatch.fnmatch()"] + E --> G{"命中?"} + F --> G + + G -- "是" --> C + G -- "否" --> H["③ 默认回退
返回 glm-5.1"] + + style A fill:#1a5276,color:#fff + style C fill:#196f3d,color:#fff + style H fill:#7b241c,color:#fff +``` + +**默认映射规则**: + +| 模式 | 目标 | 类型 | +| ------------------ | ------------- | ------------ | +| `claude-sonnet-.*` | `glm-5.1` | 正则 | +| `claude-opus-.*` | `glm-5.1` | 正则 | +| `claude-haiku-.*` | `glm-4.5-air` | 正则 | +| `claude-.*` | `glm-5.1` | 正则(兜底) | + +正则表达式在 `__init__` 时预编译(`re.compile()`),`map()` 调用时直接使用编译后的对象,避免重复编译开销。 + +--- + +## 3.4 Strategy + Factory(策略 + 工厂方法模式) + +> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 定义创建对象的接口,由策略选择决定实例化哪个类。 + +**应用位置**:[`server/factory.py`](../../src/coding/proxy/server/factory.py) — `_create_vendor_from_config()` 函数 + +**组装顺序**(两阶段构建): + +```mermaid +flowchart TD + Start["create_app(config)"] --> Phase1 + + subgraph Phase1 ["阶段一:构建 vendor → VendorTier 映射表"] + direction TB + P1_Loop["for vendor_cfg in config.vendors"] --> Match["match vendor_cfg.vendor"] + Match --> A["anthropic → AnthropicVendor"] + Match --> B["copilot → CopilotVendor
+ 凭证解析"] + Match --> C["antigravity → AntigravityVendor
+ 凭证解析"] + Match --> D["zhipu/minimax/... →
NativeAnthropicVendor 子类"] + A & B & C & D --> BuildCB["_build_circuit_breaker()"] + BuildCB --> BuildQG["_build_quota_guard()"] + BuildQG --> Map["_vendor_map[name] =
VendorTier(vendor, cb, qg, wqg)"] + Map --> P1_Loop + end + + Phase1 --> Phase2 + + subgraph Phase2 ["阶段二:按 tiers 显式排序"] + direction TB + HasTiers{"config.tiers
存在?"} + HasTiers -- "是" --> Explicit["tiers = [_vendor_map[name]
for name in config.tiers]"] + HasTiers -- "否" --> Implicit["tiers = vendors 原始顺序"] + end + + Phase2 --> Phase3["构建 RuntimeReauthCoordinator
(若有 OAuth provider)"] + Phase3 --> Final["RequestRouter(tiers, ...)"] + + style Start fill:#1a5276,color:#fff + style Final fill:#196f3d,color:#fff + style Phase1 fill:#2e4053,color:#fff + style Phase2 fill:#2e4053,color:#fff +``` + +**凭证合并优先级**:Token Store(持久化) > config.yaml(显式配置)。确保用户通过 CLI 认证命令获取的凭证优先于配置文件中的硬编码值。 + +--- + +## 3.5 Proxy(代理模式)— 整体架构 + +> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 为其他对象提供一种代理以控制对这个对象的访问。 + +**应用位置**:整体架构 + +coding-proxy 本身即是一个代理服务: + +- 对外暴露与 Anthropic Messages API 完全兼容的 `POST /v1/messages` 接口 +- Claude Code 客户端只需将 `ANTHROPIC_BASE_URL` 指向代理地址 +- 代理在幕后完成后端选择、故障转移、模型映射、用量记录、请求标准化等增值逻辑 +- 支持流式(SSE `text/event-stream`)和非流式(JSON)两种响应模式 +- 额外透传 `/v1/messages/count_tokens` 端点至 Anthropic 主供应商 + +--- + +## 3.6 Composite(组合模式)— VendorTier + +> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 将对象组合成树形结构以表示"部分-整体"的层次结构。 + +**应用位置**:[`routing/tier.py`](../../src/coding/proxy/routing/tier.py) — `VendorTier` 数据类 + +**设计要点**: + +VendorTier 将多个正交关注点聚合为路由器的最小调度单元: + +```mermaid +classDiagram + class VendorTier { + <> + -vendor : BaseVendor + -circuit_breaker : CircuitBreaker | None + -quota_guard : QuotaGuard | None + -weekly_quota_guard : QuotaGuard | None + -retry_config : RetryConfig | None + -_rate_limit_deadline : float + -- + +name : str + +is_terminal : bool + +can_execute() bool + +can_execute_with_health_check() bool + +record_success(usage_tokens) + +record_failure(...) + +is_rate_limited : bool + } + + note for VendorTier "路由器的最小调度单元\n聚合 vendor + CB + QG + WQG + Retry + RL" + + style VendorTier fill:#1a5276,color:#fff +``` + +**关键方法**: + +| 方法 | 逻辑 | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------- | +| `name` | → `vendor.get_name()` | +| `is_terminal` | → `circuit_breaker is None`(终端层无故障转移) | +| `can_execute()` | CB.can_execute() AND QG.can_use_primary() AND WQG.can_use_primary() | +| `can_execute_with_health_check()` | 三层恢复门控:Rate Limit Deadline → Health Check → Cautious Probe | +| `record_success(usage_tokens)` | CB.record_success() + QG/WQG 探测恢复 + 用量记录 + 清除 RL deadline | +| `record_failure(is_cap_error, retry_after_seconds, rate_limit_deadline)` | CB.record_failure(+retry) + 若 cap error 则通知 QG/WQG + 更新 RL deadline | +| `is_rate_limited` | `_rate_limit_deadline > time.monotonic()` | + +--- + +## 3.7 State Machine(状态机模式)— QuotaGuard + + + +**应用位置**:[`routing/quota_guard.py`](../../src/coding/proxy/routing/quota_guard.py) — `QuotaGuard` 类 + +**设计要点**: + +基于滑动窗口的双态状态机,通过 Token 预算追踪主动避免触发上游配额限制: + +```mermaid +stateDiagram-v2 + [*] --> WITHIN_QUOTA + + WITHIN_QUOTA --> QUOTA_EXCEEDED : 窗口用量 >= budget × threshold%\n或检测到 cap error + note right of QUOTA_EXCEEDED : 超限状态 — 仅允许探测请求 + + QUOTA_EXCEEDED --> WITHIN_QUOTA : 窗口自然滑出 < threshold%\n或探测请求成功 + + WITHIN_QUOTA --> [*] + QUOTA_EXCEEDED --> [*] +``` + +**核心机制**: + +- **滑动窗口**:`deque[(timestamp, tokens)]`,`_expire()` 清除超出 `window_seconds` 的条目 +- **双窗口支持**:同一 `QuotaGuard` 类同时服务于日度 (`quota_guard`) 和周度 (`weekly_quota_guard`) 两个独立实例 +- **探测恢复**:QUOTA_EXCEEDED 状态下,每隔 `probe_interval_seconds` 放行一个探测请求 +- **cap error 模式**:由外部 `_is_cap_error()` 触发,不做预算自动恢复,仅允许探测恢复 +- **基线加载**:启动时从数据库加载历史用量,防止重启后误判配额状态 +- **线程安全**:所有状态变更通过 `threading.Lock` 保护 + +> **参数默认值**:参见 [配置参考 -- QuotaGuardConfig](./config-reference.md#elastic-params) + +--- + +## 3.8 Double-Check Locking(双重检查锁模式) + +**应用位置**: +- [`vendors/copilot.py`](../../src/coding/proxy/vendors/copilot.py) — `CopilotTokenManager` +- [`vendors/antigravity.py`](../../src/coding/proxy/vendors/antigravity.py) — `GoogleOAuthTokenManager` + +**设计要点**: + +两个 Token Manager 均采用相同的异步 DCL 模式,确保高并发下 token 交换仅执行一次: + +```python +# 快速路径(无锁) +if self._access_token and time.monotonic() < self._expires_at: + return self._access_token + +# 慢路径(加锁后二次检查) +async with self._lock: + if self._access_token and time.monotonic() < self._expires_at: + return self._access_token + await self._exchange() # 或 self._refresh() +``` + +| Token Manager | 认证流程 | 有效期 | 提前刷新余量 | +| ------------------------- | ------------------------------------------------------------------------- | -------- | ------------ | +| `CopilotTokenManager` | GitHub token -> GET `copilot_internal/v2/token` -> `token`/`access_token` | ~30 分钟 | 60 秒 | +| `GoogleOAuthTokenManager` | refresh_token -> POST oauth2.googleapis.com/token -> access_token | ~1 小时 | 120 秒 | + +两者均支持**被动刷新**:当后端返回 401/403 时,通过 `_on_error_status()` 调用 `invalidate()` 标记 token 失效,下次请求自动触发重新获取。若 `needs_reauth=True`,还会联动 `RuntimeReauthCoordinator` 触发后台重认证流程。 + +--- + +## 3.9 Facade(外观模式) + +> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 为子系统中的一组接口提供一个统一的高层接口。 + +**应用位置**:[`routing/router.py`](../../src/coding/proxy/routing/router.py) — `RequestRouter` 类 + +**设计要点**: + +`RequestRouter` 作为薄代理门面(Facade),将路由系统的复杂内部实现封装为简洁的公开接口,内部委托给三个正交分解的子组件: + +```mermaid +graph LR + RR["RequestRouter
(Facade)"] + + RE["_RouteExecutor
tier 迭代门控引擎"] + UR["UsageRecorder
用量/定价/证据"] + SM["RouteSessionManager
兼容性会话管理"] + + RR -->|"route_stream()"| RE + RR -->|"route_message()"| RE + RR -->|"set_pricing_table()"| UR + RR -->|"构造注入"| SM + + RE -->|"execute_stream()
execute_message()"| VT["VendorTier 链"] + UR -->|"record()
log_model_call()"| TL["TokenLogger"] + SM -->|"get_or_create_record()
apply_compat_context()
persist_session()"| CSS["CompatSessionStore"] +``` + +**委托关系**: + +| 公开方法 | 内部委托 | +| ------------------------------ | --------------------------------------------- | +| `route_stream(body, headers)` | -> `_executor.execute_stream(body, headers)` | +| `route_message(body, headers)` | -> `_executor.execute_message(body, headers)` | +| `set_pricing_table(table)` | -> `_recorder.set_pricing_table(table)` | +| `close()` | -> 遍历 `tiers` 调用 `tier.vendor.close()` | + +这种正交 decomposition 使得每个子组件可以独立演进和测试,同时 `RequestRouter` 保持对外接口稳定。 + +--- + +## 3.10 Adapter(适配器模式)— Vendor 层 + +> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 将一个类的接口转换成客户期望的另一个接口。 + +**应用位置**:[`vendors/`](../../src/coding/proxy/vendors/) — `BaseVendor` 及其具体实现 + +**设计要点**: + +每个 Vendor 子类充当 Adapter 角色,将异构的上游 API 适配为统一的 `BaseVendor` 接口: + +| Vendor | 上游协议 | 适配行为 | +| ----------------------------- | --------------------------- | ------------------------------------------------------ | +| `AnthropicVendor` | Anthropic Messages API | 透传(近乎零适配开销) | +| `CopilotVendor` | OpenAI Chat Completions API | 请求体/响应体双向格式转换 + token 注入 | +| `AntigravityVendor` | Gemini GenerateContent API | Anthropic ↔ Gemini 双向格式转换 + SSE 流适配 + OAuth | +| `ZhipuVendor` 等 6 个原生兼容 | Anthropic-compatible API | 模型名映射 + API Key 认证头替换(继承 NativeAnthropicVendor) | + +此外,[`convert/`](../../src/coding/proxy/convert/) 模块提供独立的纯函数适配器层,支持三向格式转换: + +| 转换方向 | 模块 | 说明 | +| --------------------------- | -------------------------------------------------------------------------------------------- | ------------------ | +| Anthropic -> Gemini | [`convert/anthropic_to_gemini.py`](../../src/coding/proxy/convert/anthropic_to_gemini.py) | 请求格式转换 | +| Gemini -> Anthropic | [`convert/gemini_to_anthropic.py`](../../src/coding/proxy/convert/gemini_to_anthropic.py) | 响应格式转换 | +| Gemini SSE -> Anthropic SSE | [`convert/gemini_sse_adapter.py`](../../src/coding/proxy/convert/gemini_sse_adapter.py) | 流式事件重构 | +| Anthropic -> OpenAI | [`convert/anthropic_to_openai.py`](../../src/coding/proxy/convert/anthropic_to_openai.py) | Copilot 请求适配 | +| OpenAI -> Anthropic | [`convert/openai_to_anthropic.py`](../../src/coding/proxy/convert/openai_to_anthropic.py) | Copilot 响应逆适配 | + +--- + +## 3.11 Capability-Based Routing(基于能力的路由) + +**应用位置**: +- [`routing/error_classifier.py`](../../src/coding/proxy/routing/error_classifier.py) — `build_request_capabilities()` +- [`vendors/base.py`](../../src/coding/proxy/vendors/base.py) — `BaseVendor.supports_request()` / `get_capabilities()` / `make_compatibility_decision()` +- [`model/vendor.py`](../../src/coding/proxy/model/vendor.py) — `RequestCapabilities` / `VendorCapabilities` / `CapabilityLossReason` + +**设计要点**: + +基于请求能力画像与供应商能力声明的正交匹配矩阵,在路由阶段即排除无法无损承接请求的层级: + +| 维度 \ 能力 | `tools` | `thinking` | `images` | `metadata` | `vend_tools` | +| :----------- | :-----: | :--------: | :------: | :--------: | :----------: | +| **tools** | ✅ OK | — | — | — | ❌ skip | +| **thinking** | — | ✅ OK | — | — | — | +| **images** | — | — | ✅ OK | — | — | +| **metadata** | — | — | — | ✅ OK | — | + +> ✅ = 可承接;❌ = `CapabilityLossReason`(跳过此 tier) + +**匹配流程**: + +1. **能力硬过滤**:`supports_request(request_caps)` -> 返回 `(bool, list[CapabilityLossReason])` + - 若有任何 `CapabilityLossReason`,直接跳过该 tier 并记录原因 +2. **兼容性决策**:`make_compatibility_decision(canonical_request)` -> 返回 `CompatibilityDecision` + - `NATIVE`:完全原生支持,直接放行 + - `SIMULATED`:可通过模拟/投影方式支持(如 thinking 剥离、tool_calling 降级) + - `UNSAFE`:存在不可弥补的语义缺失,跳过该 tier + +**CompatibilityDecision 三态决策矩阵**: + +| 请求特征 | NATIVE | SIMULATED | UNSAFE | +| -------------------------- | ------ | ----------------------- | ------ | +| thinking + 支持 thinking | OK | | | +| thinking + 不支持 thinking | | thinking_simulation | X | +| tools + 支持 tools | OK | | | +| tools + 不支持 tools | | tool_calling_simulation | X | +| metadata + 支持 metadata | OK | | | +| metadata + 不支持 metadata | | metadata_projection | X | +| json_output + 支持 | OK | | | +| json_output + 不支持 | | json_output_projection | X | + +--- + +## 3.12 Retry with Full Jitter(带完全抖动的重试模式) + + + +> **参考**:M. Nygard《Release It!》第 5 章[[3]](#ref3);AWS Architecture Center "Retry Pattern"[[4]](#ref4) + +**应用位置**:[`routing/retry.py`](../../src/coding/proxy/routing/retry.py) — `RetryConfig` / `calculate_delay()` + +**设计要点**: + +传输层重试策略处理瞬态网络故障,与 CircuitBreaker 形成正交互补: + +| 维度 | Retry | CircuitBreaker | +| ------------ | ------------------------------------- | ---------------------- | +| 处理范围 | 单次请求内的瞬态抖动 | 跨请求的持续故障 | +| 恢复时间尺度 | 秒级(500ms ~ 5s) | 分钟级(300s ~ 3600s) | +| 触发条件 | TimeoutException / ConnectError / 5xx | 连续 N 次失败 | +| 失败贡献 | 每次 retry 失败仅向 CB 贡献 1 次计数 | 累积计数触发 OPEN | + +**Full Jitter 计算**: + +$$ +\text{delay} = \text{random}\left(0,\; \min\left(\text{initial\_delay} \times \text{backoff}^{\text{attempt}},\; \text{max\_delay}\right)\right) +$$ + +**可重试异常判定**(`is_retryable_error()`): + +| 异常类型 | 可重试 | 原因 | +| ----------------------------- | ------ | -------------------------- | +| `httpx.TimeoutException` | OK | 瞬态超时 | +| `httpx.ConnectError` | OK | 网络连接失败 | +| `httpx.HTTPStatusError` (5xx) | OK | 服务端瞬时错误 | +| `httpx.HTTPStatusError` (4xx) | NO | 客户端错误(不应重试) | +| `TokenAcquireError` | NO | 认证层错误(应触发重认证) | + +> **参数默认值**:参见 [配置参考 -- RetryConfig](./config-reference.md#elastic-params) + +--- + +## 3.13 Rate Limit Deadline Tracking(速率限制截止追踪) + +**应用位置**: +- [`routing/rate_limit.py`](../../src/coding/proxy/routing/rate_limit.py) — `RateLimitInfo` / `parse_rate_limit_headers()` / `compute_rate_limit_deadline()` +- [`routing/tier.py`](../../src/coding/proxy/routing/tier.py) — `VendorTier._rate_limit_deadline` / `is_rate_limited` / `can_execute_with_health_check()` + +**设计要点**: + +从 HTTP 429/403 响应头精确解析上游速率限制信息,并转化为 monotonic 时间戳用于门控: + +**解析的信息源**: + +| Header | 格式 | 含义 | +| ------------------------------------ | ----------------- | -------------------- | +| `Retry-After` | 秒数或 HTTP Date | 标准速率限制恢复时间 | +| `anthropic-ratelimit-requests-reset` | ISO 8601 datetime | 请求计数重置时间 | +| `anthropic-ratelimit-tokens-reset` | ISO 8601 datetime | Token 配额重置时间 | + +**计算策略**: + +- 取所有可用信号的最大值,并加 **10% 安全余量** +- `compute_effective_retry_seconds()` -> 返回相对秒数(供 CircuitBreaker 退避计算) +- `compute_rate_limit_deadline()` -> 返回绝对 monotonic 时间戳(供 VendorTier 精确门控) + +**三层恢复门控集成**: + +`can_execute_with_health_check()` 方法实现了三层渐进式恢复机制: + +```mermaid +flowchart TD + Entry["can_execute_with_health_check()"] --> L1{"第一层
Rate Limit Deadline"} + L1 -- "_deadline > now?
YES" --> Reject["直接拒绝
(~0 开销)"] + L1 -- "NO" --> L2{"第二层
CB + QG + WQG
综合判断"} + + L2 -- "全部拒绝" --> Skip["直接跳过"] + L2 -- "至少一个允许" --> ProbeCheck{"探测场景?
CB=HALF_OPEN 或
QG=QUOTA_EXCEEDED"} + + ProbeCheck -- "否" --> Result["返回综合结果"] + ProbeCheck -- "是" --> L3{"第三层
Health Check
(慢路径)"} + + L3 -- "check_health()
= False" --> FailRec["record_failure()
→ 拒绝"] + L3 -- "= True" --> Pass["放行
(Cautious Probe)"] + + style Entry fill:#1a5276,color:#fff + style Reject fill:#7b241c,color:#fff + style Pass fill:#196f3d,color:#fff + style FailRec fill:#7b241c,color:#fff + style Skip fill:#7b241c,color:#fff + style Result fill:#2874a6,color:#fff +``` + +--- + +## 参考文献 + +[1] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, *Design Patterns: Elements of Reusable Object-Oriented Software*, Addison-Wesley, 1994. + +[2] M. Fowler, "CircuitBreaker," *martinfowler.com*, 2014. + +[3] M. Nygard, *Release It!: Design and Deploy Production-Ready Software*, 2nd ed., Pragmatic Bookshelf, 2018. + +[4] AWS Architecture Center, "Retry Pattern," *docs.aws.amazon.com*, 2022. diff --git a/docs/arch/routing.md b/docs/arch/routing.md new file mode 100644 index 0000000..7f396fe --- /dev/null +++ b/docs/arch/routing.md @@ -0,0 +1,180 @@ +# 路由模块(routing/) + +> **路径约定**:本文档中模块路径均相对于 `src/coding/proxy/`。 +> +> **定位**:从 `framework.md` 提取,详述 N-tier 链式路由核心的 13 个子模块。 + +[TOC] + +--- + +## 1. 模块总览 + +路由模块正交分解为 13 个子模块,每个子模块职责单一: + +| 子模块 | 文件 | 职责 | +| ------------------- | ------------------------------------------------------------------ | ------------------------------------------- | +| **router** | [`routing/router.py`](../../src/coding/proxy/routing/router.py) | `RequestRouter` — 路由门面(Facade) | +| **executor** | [`routing/executor.py`](../../src/coding/proxy/routing/executor.py)| `_RouteExecutor` — tier 迭代门控引擎 | +| **tier** | [`routing/tier.py`](../../src/coding/proxy/routing/tier.py) | `VendorTier` — 最小调度单元(Composite) | +| **circuit_breaker** | [`routing/circuit_breaker.py`](../../src/coding/proxy/routing/circuit_breaker.py) | `CircuitBreaker` — 熔断器状态机 | +| **quota_guard** | [`routing/quota_guard.py`](../../src/coding/proxy/routing/quota_guard.py) | `QuotaGuard` — 配额守卫状态机 | +| **retry** | [`routing/retry.py`](../../src/coding/proxy/routing/retry.py) | `RetryConfig` / `calculate_delay()` — 重试策略 | +| **rate_limit** | [`routing/rate_limit.py`](../../src/coding/proxy/routing/rate_limit.py) | `RateLimitInfo` / 解析与截止时间计算 | +| **error_classifier**| [`routing/error_classifier.py`](../../src/coding/proxy/routing/error_classifier.py) | 请求能力画像 + 语义拒绝判定 | +| **model_mapper** | [`routing/model_mapper.py`](../../src/coding/proxy/routing/model_mapper.py) | `ModelMapper` — 三级优先级匹配链 | +| **usage_recorder** | [`routing/usage_recorder.py`](../../src/coding/proxy/routing/usage_recorder.py) | 用量记录、定价计算与证据构建 | +| **usage_parser** | [`routing/usage_parser.py`](../../src/coding/proxy/routing/usage_parser.py) | SSE chunk Token 用量提取 | +| **session_manager** | [`routing/session_manager.py`](../../src/coding/proxy/routing/session_manager.py) | 兼容性会话生命周期管理 | + +--- + +## 2. VendorTier + +**文件**:[`routing/tier.py`](../../src/coding/proxy/routing/tier.py) + +```python +@dataclass +class VendorTier: + vendor: BaseVendor + circuit_breaker: CircuitBreaker | None = None + quota_guard: QuotaGuard | None = None + weekly_quota_guard: QuotaGuard | None = None + retry_config: RetryConfig | None = None + _rate_limit_deadline: float = 0.0 +``` + +**向后兼容别名**:`BackendTier = VendorTier`(deprecated) + +**关键方法**: + +| 方法 | 逻辑 | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------- | +| `name` | → `vendor.get_name()` | +| `is_terminal` | → `circuit_breaker is None`(终端层无故障转移) | +| `can_execute()` | CB.can_execute() AND QG.can_use_primary() AND WQG.can_use_primary() | +| `can_execute_with_health_check()` | 三层恢复门控:Rate Limit Deadline → Health Check → Cautious Probe | +| `record_success(usage_tokens)` | CB.record_success() + QG/WQG 探测恢复 + 用量记录 + 清除 RL deadline | +| `record_failure(is_cap_error, retry_after_seconds, rate_limit_deadline)` | CB.record_failure(+retry) + 若 cap error 则通知 QG/WQG + 更新 RL deadline | +| `is_rate_limited` | `_rate_limit_deadline > time.monotonic()` | + +> **设计模式**:Composite 模式,参见 [设计模式 -- Composite](./design-patterns.md#composite) + +--- + +## 3. _RouteExecutor + +**文件**:[`routing/executor.py`](../../src/coding/proxy/routing/executor.py) + +统一的 tier 迭代门控引擎,封装 `execute_stream()` / `execute_message()` 共享的循环逻辑。 + +| 方法 | 说明 | +| ------------------------------------------------------------------ | -------------------------------------------------------------------- | +| `execute_stream(body, headers)` | 流式路由主循环,yield `(chunk, vendor_name)` | +| `execute_message(body, headers)` | 非流式路由主循环,返回 `VendorResponse` | +| `_try_gate_tier(tier, is_last, caps, canonical, session, reasons)` | 单 tier 门控:能力匹配 → 兼容性决策 → 上下文应用 → 健康检查 | +| `_handle_token_error(tier, exc, is_last, failed_name)` | TokenAcquireError 处理 + reauth 触发 | +| `_handle_http_error(tier, exc, ...)` | HTTP 错误处理:语义拒绝 / cap error / rate limit 解析 / failure 记录 | +| `_is_cap_error(resp)` | 静态方法:检测 429/403 + 配额关键词 | + +--- + +## 4. UsageRecorder + +**文件**:[`routing/usage_recorder.py`](../../src/coding/proxy/routing/usage_recorder.py) + +| 方法 | 说明 | +| ------------------------------------------------------------------------ | -------------------------------------------------------- | +| `set_pricing_table(table)` | 注入 PricingTable(lifespan 启动时调用) | +| `build_usage_info(usage_dict)` | 从原始 dict 构建结构化 UsageInfo | +| `log_model_call(vendor, model_requested, model_served, duration, usage)` | 输出 ModelCall 级别 Access Log(含定价) | +| `record(vendor, ..., evidence_records)` | 持久化用量到 TokenLogger + evidence 记录(Copilot 专用) | +| `build_nonstream_evidence_records(...)` | 构建非流式证据记录 | + +--- + +## 5. RouteSessionManager + +**文件**:[`routing/session_manager.py`](../../src/coding/proxy/routing/session_manager.py) + +| 方法 | 说明 | +| ---------------------------------------------------------- | ------------------------------------- | +| `get_or_create_record(session_key, trace_id)` | 获取或创建会话记录 | +| `apply_compat_context(tier, canonical, decision, session)` | 构建 CompatibilityTrace 并注入 vendor | +| `persist_session(trace, session)` | 持久化会话状态到 CompatSessionStore | + +--- + +## 6. Error Classifier + +**文件**:[`routing/error_classifier.py`](../../src/coding/proxy/routing/error_classifier.py) + +| 函数 | 说明 | +| --------------------------------------------------------------- | ------------------------------------------------------ | +| `build_request_capabilities(body)` | 从请求体提取能力画像(tools/thinking/images/metadata) | +| `is_semantic_rejection(status_code, error_type, error_message)` | 判断是否为语义拒绝(400 + 特定模式) | +| `extract_error_payload_from_http_status(exc)` | 从 HTTPStatusError 安全提取 JSON payload | + +--- + +## 7. Rate Limit + +**文件**:[`routing/rate_limit.py`](../../src/coding/proxy/routing/rate_limit.py) + +| 函数/类 | 说明 | +| ------------------------------------------------------- | ------------------------------------------------------------------------ | +| `RateLimitInfo` | 数据类:retry_after / requests_reset_at / tokens_reset_at / is_cap_error | +| `parse_rate_limit_headers(headers, status, error_body)` | 从响应头解析所有速率限制信号 | +| `compute_effective_retry_seconds(info)` | 计算最保守恢复等待时间(相对秒数,+10% 余量) | +| `compute_rate_limit_deadline(info)` | 计算最保守恢复截止时间(绝对 monotonic 时间戳,+10% 余量) | + +--- + +## 8. Retry + +**文件**:[`routing/retry.py`](../../src/coding/proxy/routing/retry.py) + +| 函数/类 | 说明 | +| ------------------------------- | ----------------------------------------------------------------------------------- | +| `RetryConfig` | 数据类:max_retries / initial_delay_ms / max_delay_ms / backoff_multiplier / jitter | +| `is_retryable_error(exc)` | 判断异常是否值得重试 | +| `is_retryable_status(code)` | 判断状态码是否值得重试(5xx) | +| `calculate_delay(attempt, cfg)` | 计算第 N 次重试延迟(含 Full Jitter) | + +> **参数默认值**:参见 [配置参考 -- RetryConfig](./config-reference.md#elastic-params) + +--- + +## 9. CircuitBreaker + +**文件**:[`routing/circuit_breaker.py`](../../src/coding/proxy/routing/circuit_breaker.py) + +状态机:CLOSED → OPEN → HALF_OPEN → CLOSED,含指数退避。 + +> **参数默认值**:参见 [配置参考 -- CircuitBreakerConfig](./config-reference.md#elastic-params) +> +> **设计语义**:参见 [设计模式 -- Circuit Breaker](./design-patterns.md#circuit-breaker) + +--- + +## 10. QuotaGuard + +**文件**:[`routing/quota_guard.py`](../../src/coding/proxy/routing/quota_guard.py) + +基于滑动窗口的双态状态机(WITHIN_QUOTA / QUOTA_EXCEEDED)。 + +**公共方法**: + +| 方法 | 说明 | +| ----------------------------- | ------------------------------------------------ | +| `can_use_primary()` | 综合判断是否允许使用此后端 | +| `record_usage(tokens)` | 记录 Token 用量到滑动窗口 | +| `record_primary_success()` | 探测成功后恢复为 WITHIN_QUOTA | +| `notify_cap_error()` | 外部通知检测到 cap 错误,强制进入 QUOTA_EXCEEDED | +| `load_baseline(total_tokens)` | 从数据库加载历史用量基线 | +| `reset()` | 手动重置为 WITHIN_QUOTA | +| `get_info()` | 获取状态信息(供 `/api/status` 使用) | + +> **参数默认值**:参见 [配置参考 -- QuotaGuardConfig](./config-reference.md#elastic-params) +> +> **设计语义**:参见 [设计模式 -- QuotaGuard State Machine](./design-patterns.md#quota-guard) diff --git a/docs/arch/testing.md b/docs/arch/testing.md new file mode 100644 index 0000000..30ab6ba --- /dev/null +++ b/docs/arch/testing.md @@ -0,0 +1,114 @@ +# 测试策略 + +> **定位**:从 `framework.md` 提取,详述测试覆盖与工具链。 + +[TOC] + +--- + +## 1. 测试工具 + +- **pytest** (>=9.0) — 测试框架 +- **pytest-asyncio** (>=1.3) — 异步测试支持 +- **monkeypatch** — 环境变量和工作目录隔离 +- **tmp_path** — 临时文件测试 +- **respx** — httpx Mock(用于 vendor 集成测试) + +--- + +## 2. 测试覆盖 + +### 2.1 供应商(vendors) + +| 测试文件 | 覆盖范围 | +| -------------------------------- | --------------------------------------------------------------- | +| `test_vendors.py` | 请求头过滤、模型映射、故障转移判断、数据类默认值 | +| `test_copilot.py` | CopilotTokenManager 交换/缓存/过期/失效、CopilotVendor 请求准备 | +| `test_antigravity.py` | GoogleOAuthTokenManager 刷新/缓存/过期/失效、格式转换+token注入 | +| `test_native_vendors.py` | NativeAnthropicVendor 基类行为、401 归一化、子类继承 | +| `test_zhipu.py` | ZhipuVendor 特定行为 | +| `test_mixins.py` | TokenBackendMixin 行为 | +| `test_token_manager.py` | BaseTokenManager 抽象行为 | +| `test_copilot_models.py` | CopilotModelResolver 模型解析与误导向处理 | +| `test_copilot_urls.py` | Copilot URL 工具函数 | +| `test_vendor_streaming.py` | Vendor 流式响应行为 | + +### 2.2 路由(routing) + +| 测试文件 | 覆盖范围 | +| -------------------------------- | --------------------------------------------------------------- | +| `test_circuit_breaker.py` | 状态转换(CLOSED→OPEN→HALF_OPEN→CLOSED)、恢复超时、指数退避、手动重置 | +| `test_quota_guard.py` | 配额守卫状态机、预算追踪、探测机制、基线加载 | +| `test_model_mapper.py` | 精确匹配、正则匹配、Glob 匹配、默认回退、空规则集 | +| `test_tier.py` | VendorTier 可执行判断、成功/失败记录、终端判定、三层门控、RL deadline | +| `test_router_chain.py` | N-tier 链式路由(2/3/4-tier 降级、CB/QG 跳过、流式/非流式、连接异常) | +| `test_router_executor.py` | _RouteExecutor 门控逻辑、能力匹配、兼容性决策、语义拒绝 | +| `test_error_classifier.py` | 请求能力画像提取、语义拒绝判定、错误 payload 解析 | +| `test_rate_limit.py` | Rate limit header 解析、deadline 计算、cap error 检测 | +| `test_retry.py` | RetryConfig 参数、delay 计算、可重试异常判定 | +| `test_usage_recorder.py` | UsageRecorder 用量构建、定价日志、evidence 记录 | + +### 2.3 配置(config) + +| 测试文件 | 覆盖范围 | +| -------------------------------- | --------------------------------------------------------------- | +| `test_config_loader.py` | 配置文件搜索优先级、环境变量展开、缺失文件处理、vendors 格式解析 | +| `test_config_init.py` | 配置模块初始化与 re-export 验证 | +| `test_schema.py` | ProxyConfig 校验、legacy 迁移、tiers 引用校验、vendor 专属字段 warning | + +### 2.4 格式转换(convert) + +| 测试文件 | 覆盖范围 | +| ------------------------------------- | --------------------------------------------------------------- | +| `test_convert_request.py` | Anthropic→Gemini 请求转换(文本、多轮、system、图片、工具、参数映射) | +| `test_convert_response.py` | Gemini→Anthropic 响应转换(文本、多部件、usage 提取、finishReason 映射) | +| `test_convert_sse.py` | Gemini SSE→Anthropic SSE 流适配(单/多 chunk、各 finishReason、边界情况) | +| `test_copilot_convert_request.py` | Anthropic→OpenAI 请求格式转换 | +| `test_copilot_convert_response.py` | OpenAI→Anthropic 响应格式转换 | + +### 2.5 数据模型(model) + +| 测试文件 | 覆盖范围 | +| -------------------------------- | --------------------------------------------------------------- | +| `test_model_vendor.py` | UsageInfo/VendorResponse/RequestCapabilities 数据类 | +| `test_model_compat.py` | CanonicalRequest/CompatibilityDecision 数据模型 | +| `test_model_constants.py` | 常量定义与使用 | +| `test_model_pricing.py` | ModelPricingEntry 校验、币种一致性 | +| `test_model_token.py` | Token 相关模型 | +| `test_model_auth.py` | 认证相关模型 | + +### 2.6 认证(auth) + +| 测试文件 | 覆盖范围 | +| -------------------------------- | --------------------------------------------------------------- | +| `test_runtime_reauth.py` | RuntimeReauthCoordinator 状态机、幂等触发、锁保护 | +| `test_auto_login.py` | 自动登录流程 | + +### 2.7 流式处理(streaming) + +| 测试文件 | 覆盖范围 | +| ------------------------------------- | ------------------------------------------------- | +| `test_streaming_anthropic_compat.py` | Anthropic 流式兼容层行为 | + +### 2.8 服务端与 CLI(server/cli) + +| 测试文件 | 覆盖范围 | +| -------------------------------- | --------------------------------------------------------------- | +| `test_app_routes.py` | FastAPI 路由端点测试 | +| `test_request_normalizer.py` | 请求标准化:私有块清洗、tool_use_id 重写、fatal_reasons | +| `test_cli_usage.py` | CLI 用量查询命令 | +| `test_banner.py` | CLI Banner 显示 | +| `test_logging_dual_write.py` | 日志双写机制 | + +### 2.9 其他 + +| 测试文件 | 覆盖范围 | +| -------------------------------- | --------------------------------------------------------------- | +| `test_pricing.py` | PricingTable 加载、单价查询(精确+规范化)、费用计算、币种一致性 | +| `test_token_logger.py` | 用量记录、窗口查询、按供应商/模型过滤、evidence 记录 | +| `test_compat.py` | CanonicalRequest 构建、session_key 派生 | +| `test_parse_usage.py` | 用量解析工具函数 | +| `test_currency.py` | 币种检测与转换 | +| `test_types.py` | 公共类型定义 | +| `test_time_range.py` | 时间范围工具 | +| `test_tiers_config.py` | Tiers 配置验证 | diff --git a/docs/arch/vendors.md b/docs/arch/vendors.md new file mode 100644 index 0000000..f6936d6 --- /dev/null +++ b/docs/arch/vendors.md @@ -0,0 +1,396 @@ +# 供应商模块(vendors/) + +> 路径约定:相对于 `src/coding/proxy/` +> 定位:从 [framework.md](./framework.md) 提取,详述供应商分类体系与各供应商实现。 + +[TOC] + +## 1. 供应商分类体系 + +供应商模块按协议适配深度分为三个层级: + +### Class 1: 直接 Anthropic(Direct) + +- **基类**: [BaseVendor](../../src/coding/proxy/vendors/base.py)(直接子类) +- **供应商**: `AnthropicVendor` — 零适配,直接透传 +- **能力**: 全能力支持,客户端 OAuth token 原样转发 + +### Class 2: 协议转换(Protocol Conversion) + +- **基类**: `BaseVendor` + [TokenBackendMixin](../../src/coding/proxy/vendors/mixins.py) +- **供应商**: + - `CopilotVendor` — Anthropic ↔ OpenAI 双向协议转换 + token 注入 + - `AntigravityVendor` — Anthropic ↔ Gemini 双向协议转换 + SSE 适配 + OAuth2 +- **能力**: 部分能力支持(因供应商而异,通过 `CompatibilityProfile` 声明) + +### Class 3: 原生 Anthropic 兼容(Native Anthropic Compatible) + +- **基类**: [NativeAnthropicVendor](../../src/coding/proxy/vendors/native_anthropic.py)(继承 `BaseVendor`) +- **供应商**: `ZhipuVendor`、`MinimaxVendor`、`KimiVendor`、`DoubaoVendor`、`XiaomiVendor`、`AlibabaVendor` +- **适配方式**: 薄透传 — 仅模型名映射 + API Key 认证头替换 + 401 错误归一化 +- **能力**: 全 NATIVE 能力画像 + +### 类层次结构 + +```mermaid +classDiagram + direction TB + + class BaseVendor { + <> + +get_name() str + +_prepare_request(body, headers) tuple + +send_message(body, headers) VendorResponse + +send_message_stream(body, headers) AsyncIterator + +get_capabilities() VendorCapabilities + +supports_request(caps) tuple + +make_compatibility_decision(req) CompatibilityDecision + +map_model(model) str + +check_health() bool + +close() + } + + class TokenBackendMixin { + +_on_error_status(status_code) + +check_health() bool + +_get_token_diagnostics() dict + } + + class NativeAnthropicVendor { + <> + +_vendor_name: str + +_display_name: str + +_prepare_request(body, headers) tuple + +send_message(body, headers) VendorResponse + +send_message_stream(body, headers) AsyncIterator + } + + class AnthropicVendor { + +get_name() str + } + + class CopilotVendor { + +get_name() str + +_get_endpoint() str + } + + class AntigravityVendor { + +get_name() str + +map_model(model) str + } + + class ZhipuVendor { + +_vendor_name = "zhipu" + } + class MinimaxVendor { + +_vendor_name = "minimax" + } + class KimiVendor { + +_vendor_name = "kimi" + } + class DoubaoVendor { + +_vendor_name = "doubao" + } + class XiaomiVendor { + +_vendor_name = "xiaomi" + } + class AlibabaVendor { + +_vendor_name = "alibaba" + } + + BaseVendor <|-- AnthropicVendor : Class 1 直接透传 + BaseVendor <|-- CopilotVendor : Class 2 协议转换 + BaseVendor <|-- AntigravityVendor : Class 2 协议转换 + BaseVendor <|-- NativeAnthropicVendor : Class 3 薄透传基类 + NativeAnthropicVendor <|-- ZhipuVendor + NativeAnthropicVendor <|-- MinimaxVendor + NativeAnthropicVendor <|-- KimiVendor + NativeAnthropicVendor <|-- DoubaoVendor + NativeAnthropicVendor <|-- XiaomiVendor + NativeAnthropicVendor <|-- AlibabaVendor + + TokenBackendMixin o-- CopilotVendor : mixin + TokenBackendMixin o-- AntigravityVendor : mixin +``` + +## 2. BaseVendor 抽象基类 + +文件: [vendors/base.py](../../src/coding/proxy/vendors/base.py) + +`BaseVendor` 采用**模板方法模式**,固化了请求发送的核心流程,子类仅通过抽象方法和钩子方法注入差异化逻辑。 + +### API 签名 + +```python +class BaseVendor(ABC): + def __init__(self, base_url: str, timeout_ms: int, failover_config: FailoverConfig | None = None) + + # ── 抽象方法(子类必须实现) ────────────────────────── + @abstractmethod + def get_name(self) -> str + + @abstractmethod + async def _prepare_request(self, body: dict, headers: dict) -> tuple[dict, dict] + + # ── 核心方法(模板固定流程) ────────────────────────── + async def send_message(self, body: dict, headers: dict) -> VendorResponse + async def send_message_stream(self, body: dict, headers: dict) -> AsyncIterator[bytes] + + # ── 能力与兼容性 ───────────────────────────────────── + def get_capabilities(self) -> VendorCapabilities + def supports_request(self, caps: RequestCapabilities) -> tuple[bool, list[CapabilityLossReason]] + def make_compatibility_decision(self, request: CanonicalRequest) -> CompatibilityDecision + def map_model(self, model: str) -> str # 默认恒等映射 + + # ── 钩子方法(子类可选覆写) ────────────────────────── + def _get_endpoint(self) -> str # 默认 /v1/messages + def _pre_send_check(self, body, headers) -> None # 快速失败(如缺少 API key) + def _normalize_error_response(self, status, resp, vendor_resp) -> VendorResponse + def _on_error_status(self, status_code: int) -> None # 错误状态码钩子 + async def check_health(self) -> bool # 默认 True + + # ── 故障转移 ───────────────────────────────────────── + def should_trigger_failover(self, status_code: int, body: dict | None) -> bool + + # ── 生命周期 ───────────────────────────────────────── + async def close() -> None +``` + +### 模板方法流程 + +`send_message` / `send_message_stream` 遵循固定流程: + +1. **`_pre_send_check()`** — 发送前快速失败检查 +2. **`_prepare_request()`** — 子类注入差异化逻辑(协议转换、认证注入等) +3. **HTTP 请求** — 通过惰性创建的 `httpx.AsyncClient` 发送 +4. **错误处理** — `_on_error_status()` 钩子 + `_normalize_error_response()` 归一化 +5. **响应解析** — 构建标准化的 `VendorResponse` + +## 3. NativeAnthropicVendor 基类 + +文件: [vendors/native_anthropic.py](../../src/coding/proxy/vendors/native_anthropic.py) + +适用于端点已完整支持 Anthropic Messages API 协议的供应商。仅执行两项最小适配: + +1. **模型名映射** — Claude 模型名 → 供应商模型名(完全委托 `ModelMapper`) +2. **认证头替换** — 剥离原始 `authorization` / `x-api-key`,注入供应商 `x-api-key` + +此外提供 **401 错误归一化**,覆盖流式和非流式两种响应路径,确保跨供应商错误格式一致性。 + +### 子类约定 + +子类仅需覆写两个类属性: + +| 属性 | 类型 | 说明 | +|------|------|------| +| `_vendor_name` | `str` | 供应商标识名(`get_name()` 返回值 & `ModelMapper` 的 vendor 参数) | +| `_display_name` | `str` | 错误消息中的显示名(如 `"Zhipu"`、`"MiniMax"`) | + +### 能力声明 + +所有 `NativeAnthropicVendor` 子类自动继承全 NATIVE 能力画像: + +``` +thinking=NATIVE, tool_calling=NATIVE, tool_streaming=NATIVE, +mcp_tools=NATIVE, images=NATIVE, metadata=NATIVE, +json_output=NATIVE, usage_tokens=NATIVE +``` + +## 4. 供应商注册表 + +| 供应商 | 文件 | 协议 | 认证方式 | 能力 | +|--------|------|------|----------|------| +| AnthropicVendor | [vendors/anthropic.py](../../src/coding/proxy/vendors/anthropic.py) | Anthropic Messages API | OAuth token 透传 | 全能力支持 | +| CopilotVendor | [vendors/copilot.py](../../src/coding/proxy/vendors/copilot.py) | OpenAI Chat Completions | GitHub token → Copilot token 交换 | thinking 为 SIMULATED | +| AntigravityVendor | [vendors/antigravity.py](../../src/coding/proxy/vendors/antigravity.py) | Gemini GenerateContent | Google OAuth2 refresh_token | tool_streaming / metadata / usage_tokens 为 SIMULATED | +| ZhipuVendor | [vendors/zhipu.py](../../src/coding/proxy/vendors/zhipu.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| MinimaxVendor | [vendors/minimax.py](../../src/coding/proxy/vendors/minimax.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| KimiVendor | [vendors/kimi.py](../../src/coding/proxy/vendors/kimi.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| DoubaoVendor | [vendors/doubao.py](../../src/coding/proxy/vendors/doubao.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| XiaomiVendor | [vendors/xiaomi.py](../../src/coding/proxy/vendors/xiaomi.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| AlibabaVendor | [vendors/alibaba.py](../../src/coding/proxy/vendors/alibaba.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | + +> 各供应商的默认 `base_url`、超时等配置项详见 [config-reference.md](./config-reference.md)。 + +## 5. 数据类型 + +文件: [model/vendor.py](../../src/coding/proxy/model/vendor.py) + +### UsageInfo + +```python +@dataclass +class UsageInfo: + """一次调用的 Token 用量.""" + input_tokens: int = 0 + output_tokens: int = 0 + cache_creation_tokens: int = 0 + cache_read_tokens: int = 0 + request_id: str = "" +``` + +### VendorResponse + +```python +@dataclass +class VendorResponse: + """供应商响应结果.""" + status_code: int = 200 + usage: UsageInfo = field(default_factory=UsageInfo) + is_streaming: bool = False + raw_body: bytes = b"{}" + error_type: str | None = None + error_message: str | None = None + model_served: str | None = None + response_headers: dict[str, str] = field(default_factory=dict) +``` + +### CapabilityLossReason + +```python +class CapabilityLossReason(Enum): + """请求语义与供应商能力不匹配的原因.""" + TOOLS = "tools" + THINKING = "thinking" + IMAGES = "images" + VENDOR_TOOLS = "vendor_tools" + METADATA = "metadata" +``` + +### RequestCapabilities + +```python +@dataclass(frozen=True) +class RequestCapabilities: + """一次请求实际使用到的能力画像.""" + has_tools: bool = False + has_thinking: bool = False + has_images: bool = False + has_metadata: bool = False +``` + +### VendorCapabilities + +```python +@dataclass(frozen=True) +class VendorCapabilities: + """供应商能力声明.""" + supports_tools: bool = True + supports_thinking: bool = True + supports_images: bool = True + emits_vendor_tool_events: bool = False + supports_metadata: bool = True +``` + +### NoCompatibleVendorError + +```python +class NoCompatibleVendorError(RuntimeError): + """当前请求没有可安全承接的供应商.""" + def __init__(self, message: str, *, reasons: list[str] | None = None) -> None +``` + +## 6. 辅助模块 + +### TokenBackendMixin + +文件: [vendors/mixins.py](../../src/coding/proxy/vendors/mixins.py) + +为基于 token 的供应商(Copilot、Antigravity)提供共享行为: + +- `_on_error_status()` — 401/403 时自动调用 `token_manager.invalidate()` 触发被动刷新 +- `check_health()` — 基于 token 可获取性的健康检查 +- `_get_token_diagnostics()` — 收集 token 管理、模型解析、请求适配等诊断信息 + +使用方式:通过 Python Mixin 模式与 `BaseVendor` 组合,需在 `__init__` 中显式调用 `TokenBackendMixin.__init__(self, token_manager)`。 + +### BaseTokenManager + +文件: [vendors/token_manager.py](../../src/coding/proxy/vendors/token_manager.py) + +Token 缓存与自动刷新的抽象基类,提供 **DCL(Double-Check Locking)** 并发安全骨架: + +- `get_token()` — 获取有效 token(带缓存 + 自动刷新 + DCL 并发安全) +- `invalidate()` — 标记当前 token 失效(触发下次请求时被动刷新) +- `_acquire()` — 抽象方法,子类实现具体 token 获取逻辑 + +子类仅需实现 `_acquire()` 返回 `(access_token, expires_in_seconds)` 元组。内置 `_REFRESH_MARGIN = 60s` 提前刷新余量。 + +### CopilotTokenManager + +文件: [vendors/copilot_token_manager.py](../../src/coding/proxy/vendors/copilot_token_manager.py) + +GitHub token → Copilot token 交换管理: + +- **流程**: `GitHub token` → `GET copilot_internal/v2/token` → `Copilot access_token` +- **有效期**: ~30 分钟,内置 60s 提前刷新余量 +- **诊断**: 维护 `CopilotExchangeDiagnostics` 记录最近一次交换详情 +- **热更新**: `update_github_token()` 支持运行时重认证后 token 替换 + +### CopilotModelResolver + +文件: [vendors/copilot_models.py](../../src/coding/proxy/vendors/copilot_models.py) + +Copilot 模型目录管理与解析策略: + +- **目录缓存**: 维护 `CopilotModelCatalog`,基于可配置 TTL 判断新鲜度 +- **依赖倒置**: 通过 `request_fn` 回调注入 HTTP 请求能力,不直接持有 client 引用 +- **解析策略**: 优先配置规则显式映射 → 次级内部家族匹配策略(同家族优先,不跨家族降级) +- **错误处理**: `build_model_not_supported_response()` 构建标准化的模型不支持错误响应 + +## 7. 向后兼容别名 + +代码库从 "Backend" 命名体系迁移至 "Vendor" 命名体系,保留了以下别名(计划 v2 移除): + +| 旧名称 | 新名称 | 定义位置 | +|--------|--------|----------| +| `BaseBackend` | `BaseVendor` | [vendors/base.py](../../src/coding/proxy/vendors/base.py) | +| `NoCompatibleBackendError` | `NoCompatibleVendorError` | [vendors/base.py](../../src/coding/proxy/vendors/base.py) | +| `BackendCapabilities` | `VendorCapabilities` | [model/vendor.py](../../src/coding/proxy/model/vendor.py) | +| `BackendResponse` | `VendorResponse` | [model/vendor.py](../../src/coding/proxy/model/vendor.py) | +| `TierConfig` | `VendorConfig` | [config/routing.py](../../src/coding/proxy/config/routing.py) | +| `BackendType` | `VendorType` | [config/routing.py](../../src/coding/proxy/config/routing.py) | +| `AnthropicBackend` | `AnthropicVendor` | [vendors/anthropic.py](../../src/coding/proxy/vendors/anthropic.py) | +| `CopilotBackend` | `CopilotVendor` | [vendors/copilot.py](../../src/coding/proxy/vendors/copilot.py) | +| `AntigravityBackend` | `AntigravityVendor` | [vendors/antigravity.py](../../src/coding/proxy/vendors/antigravity.py) | +| `ZhipuBackend` | `ZhipuVendor` | [vendors/zhipu.py](../../src/coding/proxy/vendors/zhipu.py) | + +## 8. 添加新供应商指南 + +### Path A: 原生 Anthropic 兼容供应商(推荐,适用于简单场景) + +当新供应商的端点已完整支持 Anthropic Messages API 协议时,仅需薄透传: + +1. **创建子类** — 在 [vendors/](../../src/coding/proxy/vendors/) 目录下新建文件,继承 `NativeAnthropicVendor` + +```python +# vendors/example.py +from ..config.schema import FailoverConfig +from ..config.vendors import ExampleConfig +from ..routing.model_mapper import ModelMapper +from .native_anthropic import NativeAnthropicVendor + + +class ExampleVendor(NativeAnthropicVendor): + _vendor_name = "example" + _display_name = "Example" + + def __init__(self, config: ExampleConfig, model_mapper: ModelMapper, + failover_config: FailoverConfig | None = None) -> None: + super().__init__(config, model_mapper, failover_config) +``` + +2. **添加 `VendorType` 枚举值** — 在 [config/routing.py](../../src/coding/proxy/config/routing.py) 的 `VendorType` Literal 中追加 `"example"` +3. **添加供应商配置类** — 在 [config/schema.py](../../src/coding/proxy/config/schema.py) 或 [config/vendors.py](../../src/coding/proxy/config/vendors.py) 中定义 `ExampleConfig`(或复用已有的 `api_key` 字段) +4. **添加工厂分支** — 在 [server/factory.py](../../src/coding/proxy/server/factory.py) 的 `_create_vendor_from_config()` 中添加 `case "example":` 分支 +5. **添加配置条目** — 在 `config.yaml` 的 `vendors` 列表中添加对应条目 + +### Path B: 自定义协议供应商(适用于需要协议转换的场景) + +当新供应商使用非 Anthropic 协议(如 OpenAI、Gemini 等)时: + +1. **创建子类** — 在 [vendors/](../../src/coding/proxy/vendors/) 目录下新建文件,继承 `BaseVendor` +2. **实现抽象方法** — `get_name()` 和 `_prepare_request()` +3. **覆写钩子方法** — 按需覆写 `map_model()`、`get_capabilities()`、`get_compatibility_profile()`、`_get_endpoint()` 等 +4. **如需 token 管理** — 组合 `TokenBackendMixin`,实现 `BaseTokenManager` 子类 +5. **后续步骤** — 同 Path A 的 2-5 步 diff --git a/docs/framework.md b/docs/framework.md index e4023f5..4902e3a 100644 --- a/docs/framework.md +++ b/docs/framework.md @@ -2,7 +2,9 @@ > **路径约定**:本文档中模块路径均相对于 `src/coding/proxy/`,例如 `vendors/base.py` 指 `src/coding/proxy/vendors/base.py`。 > -> **版本**:v2 — 反映当前代码库实际架构(vendors 主架构 + 正交分解路由系统)。 +> **版本**:v3 — 正交分解架构:枢纽文档 + 专题子文档([`arch/`](./arch/))。 +> +> **专题子文档索引**:[设计模式](./arch/design-patterns.md) · [供应商模块](./arch/vendors.md) · [路由模块](./arch/routing.md) · [配置参考](./arch/config-reference.md) · [格式转换](./arch/convert.md) · [测试策略](./arch/testing.md) [TOC] @@ -24,7 +26,7 @@ Claude Code 作为日常 AI 编程助手,其底层依赖 Anthropic Messages AP - **GitHub Copilot**:提供 Anthropic 兼容(实际为 OpenAI Chat Completions 协议)的 Claude API 端点,通过 GitHub OAuth token / PAT 完成 token 交换 - **Google Antigravity Claude**:通过 Google Gemini/Vertex AI 端点提供 Claude 模型访问,需 Anthropic ↔ Gemini 双向格式转换 -- **智谱 (Zhipu)**:提供与 Anthropic 兼容的 GLM API 接口(`/api/anthropic`),作为终端兜底 +- **智谱 (Zhipu)** / **MiniMax** / **Kimi** / **豆包 (Doubao)** / **小米 (Xiaomi)** / **阿里 (Alibaba)**:提供原生 Anthropic 兼容端点,仅需模型映射 + API Key 替换 **coding-proxy 的核心诉求**:当任一后端不可用时,自动、无缝地沿 N-tier 层级链降级到下一个可用后端,对 Claude Code 客户端完全透明,用户无需手动干预。 @@ -68,6 +70,7 @@ graph TD Routes["routes.py
路由注册"] Factory["factory.py
Vendor/Tier 构建工厂"] Normalizer["request_normalizer.py
请求标准化"] + Dashboard["dashboard.py
状态面板"] end subgraph Router["RequestRouter (Facade)
routing/router.py"] @@ -106,8 +109,8 @@ graph TD G_WQG["WQG"] end - subgraph TN["VendorTier N: ZhipuVendor(终端)"] - Z_V["ZhipuVendor"] + subgraph TN["VendorTier N: 原生兼容终端
Zhipu / Minimax / Kimi / ..."] + Z_V["NativeAnthropicVendor 子类"] end Gate --> T0 @@ -118,7 +121,7 @@ graph TD A_V --> API_A["Anthropic API"] C_V --> API_C["GitHub Copilot API
(OpenAI Chat Completions)"] G_V --> API_G["Google Gemini API"] - Z_V --> API_Z["智谱 GLM API"] + Z_V --> API_Z["各原生兼容端点"] style Server fill:#1a5276,color:#fff style Router fill:#2874a6,color:#fff @@ -138,570 +141,40 @@ graph TD | **RL** | Rate Limit Deadline(速率限制截止) | [`routing/tier.py`](../src/coding/proxy/routing/tier.py) + [`routing/rate_limit.py`](../src/coding/proxy/routing/rate_limit.py) | | **Tier** | VendorTier(供应商层级) | [`routing/tier.py`](../src/coding/proxy/routing/tier.py) | -### 2.2 模块职责一览 - -| 模块 | 路径 | 职责 | -| ------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| **vendors** | [`vendors/`](../src/coding/proxy/vendors/) | **供应商适配器(主架构)**:`BaseVendor` 抽象基类 + 4 个具体实现(Anthropic/Copilot/Antigravity/Zhipu) | -| **backends** | [`backends/`](../src/coding/proxy/backends/) | 向后兼容层(遗留),类型别名指向 `vendors/` 模块 | -| **routing** | [`routing/`](../src/coding/proxy/routing/) | N-tier 链式路由核心(正交分解为 executor/tier/CB/QG/retry/rate_limit/error_classifier/session_manager/usage_recorder/usage_parser/model_mapper) | -| **compat** | [`compat/`](../src/coding/proxy/compat/) | 兼容性抽象系统:`CanonicalRequest` / `CompatibilityDecision` / `session_store` | -| **auth** | [`auth/`](../src/coding/proxy/auth/) | 认证系统:OAuth providers(GitHub Device Flow / Google OAuth2)/ runtime reauth / token store | -| **model** | [`model/`](../src/coding/proxy/model/) | 数据模型正交分解:vendor / compat / constants / pricing / token / backend | -| **config** | [`config/`](../src/coding/proxy/config/) | Pydantic v2 配置模型(正交拆分为 server/vendors/resiliency/routing/auth_schema)+ YAML 加载器 | -| **convert** | [`convert/`](../src/coding/proxy/convert/) | API 格式转换(Anthropic ↔ Gemini ↔ OpenAI 三向转换,含 SSE 流适配) | -| **logging** | [`logging/`](../src/coding/proxy/logging/) | Token 用量 SQLite 持久化、evidence 记录、统计查询与 Rich 格式化展示 | -| **server** | [`server/`](../src/coding/proxy/server/) | FastAPI 应用工厂与生命周期管理(正交拆分为 app.py/factory.py/routes.py/request_normalizer.py/responses.py) | -| **cli** | [`cli/`](../src/coding/proxy/cli/) | Typer 命令行入口(start/status/usage/reset/auth) | -| **streaming** | [`streaming/`](../src/coding/proxy/streaming/) | Anthropic 兼容流式处理 | -| **pricing** | [`pricing.py`](../src/coding/pricing.py) | 定价表(`PricingTable`):按 (vendor, model) 查询单价并计算费用 | - ---- - -## 3. 设计模式详解 - -本章涵盖 coding-proxy 中运用的 **13 种设计模式与工程模式**,按职责域正交分为三类:**创建型**(对象构建策略)、**结构型**(组件组织方式)、**行为型与并发**(运行时行为控制)。 - -```mermaid -mindmap - root((设计模式)) - 创建型 - Strategy + Factory - Template Method - 结构型 - Proxy :: 整体架构 - Adapter :: Vendor层 - Composite :: VendorTier - Facade :: RequestRouter - 行为型/并发 - Circuit Breaker - Priority Chain - State Machine :: QuotaGuard - Double-Check Locking - Capability Routing - Retry Full Jitter - Rate Limit Deadline -``` - -### 3.1 Template Method(模板方法模式) - -> **经典出处**:GoF《Design Patterns: Elements of Reusable Object-Oriented Software》[[1]](#ref1) — 定义算法骨架,将某些步骤延迟到子类实现。 - -**应用位置**:[`vendors/base.py`](../src/coding/proxy/vendors/base.py) — `BaseVendor` 抽象基类 - -**设计要点**: - -`BaseVendor` 定义了请求处理的算法骨架,将差异化的逻辑延迟到子类: - -```mermaid -classDiagram - direction TB - - class BaseVendor { - <> - +send_message() VendorResponse - +send_message_stream() AsyncIterator - +get_name()* str - +_prepare_request()* tuple - +map_model() str - +_get_endpoint() str - +_pre_send_check() - +_normalize_error_response() - +_on_error_status() - +get_capabilities() VendorCapabilities - +supports_request() tuple - +make_compatibility_decision() CompatibilityDecision - +check_health() bool - +should_trigger_failover() bool - +close() - } - - class AnthropicVendor { - _prepare_request() 过滤 hop-by-hop 头 - } - - class CopilotVendor { - _prepare_request() 过滤头+异步token注入 - _on_error_status() 401/403 token失效 - } - - class AntigravityVendor { - _prepare_request() Gemini格式转换+OAuth - check_health() OAuth有效性检查 - _on_error_status() 401/403 token失效 - } - - class ZhipuVendor { - _prepare_request() 模型映射+API Key - map_model() claude-* → glm-* - } - - BaseVendor <|-- AnthropicVendor - BaseVendor <|-- CopilotVendor - BaseVendor <|-- AntigravityVendor - BaseVendor <|-- ZhipuVendor - - style BaseVendor fill:#1a5276,color:#fff - style AnthropicVendor fill:#2874a6,color:#fff - style CopilotVendor fill:#2874a6,color:#fff - style AntigravityVendor fill:#2874a6,color:#fff - style ZhipuVendor fill:#7b241c,color:#fff -``` - -四个具体 Vendor 子类的差异化实现: - -| 方法 | AnthropicVendor | CopilotVendor | AntigravityVendor | ZhipuVendor | -| -------------------- | ------------------ | ------------------------ | ---------------------------------- | ------------------------------- | -| `_prepare_request()` | 过滤 hop-by-hop 头 | 过滤头 + 异步 token 注入 | Gemini 格式转换 + OAuth token | 模型映射 + API Key | -| `map_model()` | 恒等映射 | 恒等映射 | 恒等映射 | **覆写**(claude-* → glm-*) | -| `_get_endpoint()` | `/v1/messages` | `/v1/chat/completions` | `/{model}:generateContent` | `/api/anthropic/v1/messages` | -| `_on_error_status()` | 继承基类(空操作) | 401/403 token 失效 | 401/403 token 失效 | 继承基类(空操作) | -| `get_capabilities()` | 全部支持 | 不支持 thinking | 不支持 tools/thinking/metadata | 不支持 thinking/images/metadata | -| `check_health()` | 继承(True) | 继承(True) | **覆写**(OAuth token 有效性检查) | 继承(True) | - -### 3.2 Circuit Breaker(熔断器模式) - -> **经典出处**:Martin Fowler "CircuitBreaker" (2014)[[2]](#ref2);M. Nygard《Release It! Design and Deploy Production-Ready Software》第 5 章[[3]](#ref3) — 通过快速失败防止级联故障。 - -**应用位置**:[`routing/circuit_breaker.py`](../src/coding/proxy/routing/circuit_breaker.py) — `CircuitBreaker` 类 - -**状态机**: - -```mermaid -stateDiagram-v2 - [*] --> CLOSED - - CLOSED --> OPEN : 连续 N 次失败\n(failure_threshold) - note right of OPEN : 熔断状态 — 快速失败 - - OPEN --> HALF_OPEN : 超时恢复\n(recovery_timeout_seconds) - - HALF_OPEN --> CLOSED : 连续 M 次成功\n(success_threshold) - note right of HALF_OPEN : 试探状态 - - HALF_OPEN --> OPEN : 任意一次失败\n(退避 × 2) - - CLOSED --> [*] -``` - -**状态转换条件**: - -| 转换 | 条件 | 默认值 | -| ------------------ | --------------------------------------- | ------ | -| CLOSED → OPEN | 连续失败次数 ≥ `failure_threshold` | 3 次 | -| OPEN → HALF_OPEN | 距上次失败 ≥ `recovery_timeout_seconds` | 300 秒 | -| HALF_OPEN → CLOSED | 连续成功次数 ≥ `success_threshold` | 2 次 | -| HALF_OPEN → OPEN | 任意一次失败 | — | - -**指数退避 (Exponential Backoff)**:每次从 HALF_OPEN 回退到 OPEN 时,恢复等待时间翻倍(`recovery_timeout *= 2`),上限为 `max_recovery_seconds`(默认 3600 秒)。避免对仍未恢复的后端频繁重试。 - -**线程安全**:所有状态变更通过 `threading.Lock` 保护,确保并发请求下状态一致。 - -### 3.3 Priority Chain(优先级匹配链) - -**应用位置**:[`routing/model_mapper.py`](../src/coding/proxy/routing/model_mapper.py) — `ModelMapper` 类 - -**设计要点**: - -ModelMapper 采用三级优先级匹配链,按精确度递减依次尝试: - -```mermaid -flowchart TD - A["输入模型名称"] --> B{"① 精确匹配
pattern == model"} - - B -- "命中" --> C["返回 target"] - B -- "未命中" --> D{"② 模式匹配
Regex / Glob"} - - D -- "is_regex=true" --> E["re.fullmatch()"] - D -- "含 *" --> F["fnmatch.fnmatch()"] - E --> G{"命中?"} - F --> G - - G -- "是" --> C - G -- "否" --> H["③ 默认回退
返回 glm-5.1"] - - style A fill:#1a5276,color:#fff - style C fill:#196f3d,color:#fff - style H fill:#7b241c,color:#fff -``` - -**默认映射规则**: - -| 模式 | 目标 | 类型 | -| ------------------ | ------------- | ------------ | -| `claude-sonnet-.*` | `glm-5.1` | 正则 | -| `claude-opus-.*` | `glm-5.1` | 正则 | -| `claude-haiku-.*` | `glm-4.5-air` | 正则 | -| `claude-.*` | `glm-5.1` | 正则(兜底) | - -正则表达式在 `__init__` 时预编译(`re.compile()`),`map()` 调用时直接使用编译后的对象,避免重复编译开销。 - -### 3.4 Strategy + Factory(策略 + 工厂方法模式) - -> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 定义创建对象的接口,由策略选择决定实例化哪个类。 - -**应用位置**:[`server/factory.py`](../src/coding/proxy/server/factory.py) — `_create_vendor_from_config()` 函数 - -**组装顺序**(两阶段构建): - -```mermaid -flowchart TD - Start["create_app(config)"] --> Phase1 - - subgraph Phase1 ["阶段一:构建 vendor → VendorTier 映射表"] - direction TB - P1_Loop["for vendor_cfg in config.vendors"] --> Match["match vendor_cfg.vendor"] - Match --> A["anthropic → AnthropicVendor"] - Match --> B["copilot → CopilotVendor
+ 凭证解析"] - Match --> C["antigravity → AntigravityVendor
+ 凭证解析"] - Match --> D["zhipu → ZhipuVendor"] - A & B & C & D --> BuildCB["_build_circuit_breaker()"] - BuildCB --> BuildQG["_build_quota_guard()"] - BuildQG --> Map["_vendor_map[name] =
VendorTier(vendor, cb, qg, wqg)"] - Map --> P1_Loop - end - - Phase1 --> Phase2 - - subgraph Phase2 ["阶段二:按 tiers 显式排序"] - direction TB - HasTiers{"config.tiers
存在?"} - HasTiers -- "是" --> Explicit["tiers = [_vendor_map[name]
for name in config.tiers]"] - HasTiers -- "否" --> Implicit["tiers = vendors 原始顺序"] - end - - Phase2 --> Phase3["构建 RuntimeReauthCoordinator
(若有 OAuth provider)"] - Phase3 --> Final["RequestRouter(tiers, ...)"] - - style Start fill:#1a5276,color:#fff - style Final fill:#196f3d,color:#fff - style Phase1 fill:#2e4053,color:#fff - style Phase2 fill:#2e4053,color:#fff -``` - -**凭证合并优先级**:Token Store(持久化) > config.yaml(显式配置)。确保用户通过 CLI 认证命令获取的凭证优先于配置文件中的硬编码值。 - -### 3.5 Proxy(代理模式)— 整体架构 - -> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 为其他对象提供一种代理以控制对这个对象的访问。 - -**应用位置**:整体架构 - -coding-proxy 本身即是一个代理服务: - -- 对外暴露与 Anthropic Messages API 完全兼容的 `POST /v1/messages` 接口 -- Claude Code 客户端只需将 `ANTHROPIC_BASE_URL` 指向代理地址 -- 代理在幕后完成后端选择、故障转移、模型映射、用量记录、请求标准化等增值逻辑 -- 支持流式(SSE `text/event-stream`)和非流式(JSON)两种响应模式 -- 额外透传 `/v1/messages/count_tokens` 端点至 Anthropic 主供应商 - -### 3.6 Composite(组合模式)— VendorTier - -> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 将对象组合成树形结构以表示"部分-整体"的层次结构。 - -**应用位置**:[`routing/tier.py`](../src/coding/proxy/routing/tier.py) — `VendorTier` 数据类 - -**设计要点**: - -VendorTier 将多个正交关注点聚合为路由器的最小调度单元: - -```mermaid -classDiagram - class VendorTier { - <> - -vendor : BaseVendor - -circuit_breaker : CircuitBreaker | None - -quota_guard : QuotaGuard | None - -weekly_quota_guard : QuotaGuard | None - -retry_config : RetryConfig | None - -_rate_limit_deadline : float - -- - +name : str - +is_terminal : bool - +can_execute() bool - +can_execute_with_health_check() bool - +record_success(usage_tokens) - +record_failure(...) - +is_rate_limited : bool - } - - note for VendorTier "路由器的最小调度单元\n聚合 vendor + CB + QG + WQG + Retry + RL" - - style VendorTier fill:#1a5276,color:#fff -``` - -**关键方法**: - -| 方法 | 逻辑 | -| ------------------------------------------------------------------------ | ------------------------------------------------------------------------- | -| `name` | → `vendor.get_name()` | -| `is_terminal` | → `circuit_breaker is None`(终端层无故障转移) | -| `can_execute()` | CB.can_execute() AND QG.can_use_primary() AND WQG.can_use_primary() | -| `can_execute_with_health_check()` | 三层恢复门控:Rate Limit Deadline → Health Check → Cautious Probe | -| `record_success(usage_tokens)` | CB.record_success() + QG/WQG 探测恢复 + 用量记录 + 清除 RL deadline | -| `record_failure(is_cap_error, retry_after_seconds, rate_limit_deadline)` | CB.record_failure(+retry) + 若 cap error 则通知 QG/WQG + 更新 RL deadline | -| `is_rate_limited` | `_rate_limit_deadline > time.monotonic()` | - -### 3.7 State Machine(状态机模式)— QuotaGuard - -**应用位置**:[`routing/quota_guard.py`](../src/coding/proxy/routing/quota_guard.py) — `QuotaGuard` 类 - -**设计要点**: - -基于滑动窗口的双态状态机,通过 Token 预算追踪主动避免触发上游配额限制: - -```mermaid -stateDiagram-v2 - [*] --> WITHIN_QUOTA - - WITHIN_QUOTA --> QUOTA_EXCEEDED : 窗口用量 >= budget × threshold%\n或检测到 cap error - note right of QUOTA_EXCEEDED : 超限状态 — 仅允许探测请求 - - QUOTA_EXCEEDED --> WITHIN_QUOTA : 窗口自然滑出 < threshold%\n或探测请求成功 - - WITHIN_QUOTA --> [*] - QUOTA_EXCEEDED --> [*] -``` - -**核心机制**: - -- **滑动窗口**:`deque[(timestamp, tokens)]`,`_expire()` 清除超出 `window_seconds` 的条目 -- **双窗口支持**:同一 `QuotaGuard` 类同时服务于日度 (`quota_guard`) 和周度 (`weekly_quota_guard`) 两个独立实例 -- **探测恢复**:QUOTA_EXCEEDED 状态下,每隔 `probe_interval_seconds` 放行一个探测请求 -- **cap error 模式**:由外部 `_is_cap_error()` 触发,不做预算自动恢复,仅允许探测恢复 -- **基线加载**:启动时从数据库加载历史用量,防止重启后误判配额状态 -- **线程安全**:所有状态变更通过 `threading.Lock` 保护 - -### 3.8 Double-Check Locking(双重检查锁模式) - -**应用位置**: -- [`vendors/copilot.py`](../src/coding/proxy/vendors/copilot.py) — `CopilotTokenManager` -- [`vendors/antigravity.py`](../src/coding/proxy/vendors/antigravity.py) — `GoogleOAuthTokenManager` - -**设计要点**: - -两个 Token Manager 均采用相同的异步 DCL 模式,确保高并发下 token 交换仅执行一次: - -```python -# 快速路径(无锁) -if self._access_token and time.monotonic() < self._expires_at: - return self._access_token - -# 慢路径(加锁后二次检查) -async with self._lock: - if self._access_token and time.monotonic() < self._expires_at: - return self._access_token - await self._exchange() # 或 self._refresh() -``` - -| Token Manager | 认证流程 | 有效期 | 提前刷新余量 | -| ------------------------- | ------------------------------------------------------------------------- | -------- | ------------ | -| `CopilotTokenManager` | GitHub token -> GET `copilot_internal/v2/token` -> `token`/`access_token` | ~30 分钟 | 60 秒 | -| `GoogleOAuthTokenManager` | refresh_token -> POST oauth2.googleapis.com/token -> access_token | ~1 小时 | 120 秒 | - -两者均支持**被动刷新**:当后端返回 401/403 时,通过 `_on_error_status()` 调用 `invalidate()` 标记 token 失效,下次请求自动触发重新获取。若 `needs_reauth=True`,还会联动 `RuntimeReauthCoordinator` 触发后台重认证流程。 - -### 3.9 Facade(外观模式) - -> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 为子系统中的一组接口提供一个统一的高层接口。 - -**应用位置**:[`routing/router.py`](../src/coding/proxy/routing/router.py) — `RequestRouter` 类 - -**设计要点**: - -`RequestRouter` 作为薄代理门面(Facade),将路由系统的复杂内部实现封装为简洁的公开接口,内部委托给三个正交分解的子组件: - -```mermaid -graph LR - RR["RequestRouter
(Facade)"] - - RE["_RouteExecutor
tier 迭代门控引擎"] - UR["UsageRecorder
用量/定价/证据"] - SM["RouteSessionManager
兼容性会话管理"] - - RR -->|"route_stream()"| RE - RR -->|"route_message()"| RE - RR -->|"set_pricing_table()"| UR - RR -->|"构造注入"| SM - - RE -->|"execute_stream()
execute_message()"| VT["VendorTier 链"] - UR -->|"record()
log_model_call()"| TL["TokenLogger"] - SM -->|"get_or_create_record()
apply_compat_context()
persist_session()"| CSS["CompatSessionStore"] -``` - -**委托关系**: - -| 公开方法 | 内部委托 | -| ------------------------------ | --------------------------------------------- | -| `route_stream(body, headers)` | -> `_executor.execute_stream(body, headers)` | -| `route_message(body, headers)` | -> `_executor.execute_message(body, headers)` | -| `set_pricing_table(table)` | -> `_recorder.set_pricing_table(table)` | -| `close()` | -> 遍历 `tiers` 调用 `tier.vendor.close()` | - -这种正交 decomposition 使得每个子组件可以独立演进和测试,同时 `RequestRouter` 保持对外接口稳定。 - -### 3.10 Adapter(适配器模式)— Vendor 层 - -> **经典出处**:GoF《Design Patterns》[[1]](#ref1) — 将一个类的接口转换成客户期望的另一个接口。 - -**应用位置**:[`vendors/`](../src/coding/proxy/vendors/) — `BaseVendor` 及其具体实现 - -**设计要点**: - -每个 Vendor 子类充当 Adapter 角色,将异构的上游 API 适配为统一的 `BaseVendor` 接口: - -| Vendor | 上游协议 | 适配行为 | -| ------------------- | --------------------------- | ------------------------------------------------------ | -| `AnthropicVendor` | Anthropic Messages API | 透传(近乎零适配开销) | -| `CopilotVendor` | OpenAI Chat Completions API | 请求体/响应体双向格式转换 + token 注入 | -| `AntigravityVendor` | Gemini GenerateContent API | Anthropic <-> Gemini 双向格式转换 + SSE 流适配 + OAuth | -| `ZhipuVendor` | Anthropic-compatible API | 模型名映射 + API Key 认证头替换 | - -此外,[`convert/`](../src/coding/proxy/convert/) 模块提供独立的纯函数适配器层,支持三向格式转换: - -| 转换方向 | 模块 | 说明 | -| --------------------------- | -------------------------------------------------------------------------------------- | ------------------ | -| Anthropic -> Gemini | [`convert/anthropic_to_gemini.py`](../src/coding/proxy/convert/anthropic_to_gemini.py) | 请求格式转换 | -| Gemini -> Anthropic | [`convert/gemini_to_anthropic.py`](../src/coding/proxy/convert/gemini_to_anthropic.py) | 响应格式转换 | -| Gemini SSE -> Anthropic SSE | [`convert/gemini_sse_adapter.py`](../src/coding/proxy/convert/gemini_sse_adapter.py) | 流式事件重构 | -| Anthropic -> OpenAI | [`convert/anthropic_to_openai.py`](../src/coding/proxy/convert/anthropic_to_openai.py) | Copilot 请求适配 | -| OpenAI -> Anthropic | [`convert/openai_to_anthropic.py`](../src/coding/proxy/convert/openai_to_anthropic.py) | Copilot 响应逆适配 | - -### 3.11 Capability-Based Routing(基于能力的路由) - -**应用位置**: -- [`routing/error_classifier.py`](../src/coding/proxy/routing/error_classifier.py) — `build_request_capabilities()` -- [`vendors/base.py`](../src/coding/proxy/vendors/base.py) — `BaseVendor.supports_request()` / `get_capabilities()` / `make_compatibility_decision()` -- [`model/vendor.py`](../src/coding/proxy/model/vendor.py) — `RequestCapabilities` / `VendorCapabilities` / `CapabilityLossReason` - -**设计要点**: - -基于请求能力画像与供应商能力声明的正交匹配矩阵,在路由阶段即排除无法无损承接请求的层级: - -| 维度 \ 能力 | `tools` | `thinking` | `images` | `metadata` | `vend_tools` | -| :----------- | :-----: | :--------: | :------: | :--------: | :----------: | -| **tools** | ✅ OK | — | — | — | ❌ skip | -| **thinking** | — | ✅ OK | — | — | — | -| **images** | — | — | ✅ OK | — | — | -| **metadata** | — | — | — | ✅ OK | — | - -> ✅ = 可承接;❌ = `CapabilityLossReason`(跳过此 tier) - -**匹配流程**: - -1. **能力硬过滤**:`supports_request(request_caps)` -> 返回 `(bool, list[CapabilityLossReason])` - - 若有任何 `CapabilityLossReason`,直接跳过该 tier 并记录原因 -2. **兼容性决策**:`make_compatibility_decision(canonical_request)` -> 返回 `CompatibilityDecision` - - `NATIVE`:完全原生支持,直接放行 - - `SIMULATED`:可通过模拟/投影方式支持(如 thinking 剥离、tool_calling 降级) - - `UNSAFE`:存在不可弥补的语义缺失,跳过该 tier - -**CompatibilityDecision 三态决策矩阵**: - -| 请求特征 | NATIVE | SIMULATED | UNSAFE | -| -------------------------- | ------ | ----------------------- | ------ | -| thinking + 支持 thinking | OK | | | -| thinking + 不支持 thinking | | thinking_simulation | X | -| tools + 支持 tools | OK | | | -| tools + 不支持 tools | | tool_calling_simulation | X | -| metadata + 支持 metadata | OK | | | -| metadata + 不支持 metadata | | metadata_projection | X | -| json_output + 支持 | OK | | | -| json_output + 不支持 | | json_output_projection | X | - -### 3.12 Retry with Full Jitter(带完全抖动的重试模式) - -> **参考**:M. Nygard《Release It!》第 5 章[[3]](#ref3);AWS Architecture Center "Retry Pattern"[[4]](#ref4) - -**应用位置**:[`routing/retry.py`](../src/coding/proxy/routing/retry.py) — `RetryConfig` / `calculate_delay()` - -**设计要点**: - -传输层重试策略处理瞬态网络故障,与 CircuitBreaker 形成正交互补: - -| 维度 | Retry | CircuitBreaker | -| ------------ | ------------------------------------- | ---------------------- | -| 处理范围 | 单次请求内的瞬态抖动 | 跨请求的持续故障 | -| 恢复时间尺度 | 秒级(500ms ~ 5s) | 分钟级(300s ~ 3600s) | -| 触发条件 | TimeoutException / ConnectError / 5xx | 连续 N 次失败 | -| 失败贡献 | 每次 retry 失败仅向 CB 贡献 1 次计数 | 累积计数触发 OPEN | - -**Full Jitter 计算**: - -$$ -\text{delay} = \text{random}\left(0,\; \min\left(\text{initial\_delay} \times \text{backoff}^{\text{attempt}},\; \text{max\_delay}\right)\right) -$$ - -| 参数 | `max_retries` | `initial_delay_ms` | `max_delay_ms` | `backoff_multiplier` | `jitter` | -| ------ | :-----------: | :----------------: | :------------: | :------------------: | :------: | -| 默认值 | 2 | 500 | 5000 | 2.0 | ✅ true | - -**可重试异常判定**(`is_retryable_error()`): - -| 异常类型 | 可重试 | 原因 | -| ----------------------------- | ------ | -------------------------- | -| `httpx.TimeoutException` | OK | 瞬态超时 | -| `httpx.ConnectError` | OK | 网络连接失败 | -| `httpx.HTTPStatusError` (5xx) | OK | 服务端瞬时错误 | -| `httpx.HTTPStatusError` (4xx) | NO | 客户端错误(不应重试) | -| `TokenAcquireError` | NO | 认证层错误(应触发重认证) | - -### 3.13 Rate Limit Deadline Tracking(速率限制截止追踪) - -**应用位置**: -- [`routing/rate_limit.py`](../src/coding/proxy/routing/rate_limit.py) — `RateLimitInfo` / `parse_rate_limit_headers()` / `compute_rate_limit_deadline()` -- [`routing/tier.py`](../src/coding/proxy/routing/tier.py) — `VendorTier._rate_limit_deadline` / `is_rate_limited` / `can_execute_with_health_check()` +### 2.2 供应商分类体系 -**设计要点**: +系统支持 9 种供应商类型(`VendorType`),按适配复杂度分为三组: -从 HTTP 429/403 响应头精确解析上游速率限制信息,并转化为 monotonic 时间戳用于门控: +| 分类 | 基类 | 适配行为 | 供应商 | +| -------------------- | ------------------------ | -------------------------------- | ------------------------------------------------------------ | +| **直接 Anthropic** | `BaseVendor` | 零适配,直接透传 | Anthropic | +| **协议转换** | `BaseVendor` + Mixin | 双向格式转换 + Token 管理 | Copilot(OpenAI)、Antigravity(Gemini) | +| **原生 Anthropic 兼容** | `NativeAnthropicVendor` | 薄透传:模型映射 + API Key 替换 | Zhipu、MiniMax、Kimi、Doubao、Xiaomi、Alibaba | -**解析的信息源**: +> **供应商模块完整文档**:参见 [供应商模块(vendors/)](./arch/vendors.md) -| Header | 格式 | 含义 | -| ------------------------------------ | ----------------- | -------------------- | -| `Retry-After` | 秒数或 HTTP Date | 标准速率限制恢复时间 | -| `anthropic-ratelimit-requests-reset` | ISO 8601 datetime | 请求计数重置时间 | -| `anthropic-ratelimit-tokens-reset` | ISO 8601 datetime | Token 配额重置时间 | +### 2.3 模块职责一览 -**计算策略**: - -- 取所有可用信号的最大值,并加 **10% 安全余量** -- `compute_effective_retry_seconds()` -> 返回相对秒数(供 CircuitBreaker 退避计算) -- `compute_rate_limit_deadline()` -> 返回绝对 monotonic 时间戳(供 VendorTier 精确门控) - -**三层恢复门控集成**: - -`can_execute_with_health_check()` 方法实现了三层渐进式恢复机制: - -```mermaid -flowchart TD - Entry["can_execute_with_health_check()"] --> L1{"第一层
Rate Limit Deadline"} - L1 -- "_deadline > now?
YES" --> Reject["直接拒绝
(~0 开销)"] - L1 -- "NO" --> L2{"第二层
CB + QG + WQG
综合判断"} - - L2 -- "全部拒绝" --> Skip["直接跳过"] - L2 -- "至少一个允许" --> ProbeCheck{"探测场景?
CB=HALF_OPEN 或
QG=QUOTA_EXCEEDED"} - - ProbeCheck -- "否" --> Result["返回综合结果"] - ProbeCheck -- "是" --> L3{"第三层
Health Check
(慢路径)"} - - L3 -- "check_health()
= False" --> FailRec["record_failure()
→ 拒绝"] - L3 -- "= True" --> Pass["放行
(Cautious Probe)"] - - style Entry fill:#1a5276,color:#fff - style Reject fill:#7b241c,color:#fff - style Pass fill:#196f3d,color:#fff - style FailRec fill:#7b241c,color:#fff - style Skip fill:#7b241c,color:#fff - style Result fill:#2874a6,color:#fff -``` +| 模块 | 路径 | 职责 | 专题文档 | +| ------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | +| **vendors** | [`vendors/`](../src/coding/proxy/vendors/) | **供应商适配器(主架构)**:`BaseVendor` 抽象基类 + `NativeAnthropicVendor` + 9 个具体实现 | [供应商模块](./arch/vendors.md) | +| **routing** | [`routing/`](../src/coding/proxy/routing/) | N-tier 链式路由核心(正交分解为 executor/tier/CB/QG/retry/rate_limit 等 12 个子模块) | [路由模块](./arch/routing.md) | +| **compat** | [`compat/`](../src/coding/proxy/compat/) | 兼容性抽象系统:`CanonicalRequest` / `CompatibilityDecision` / `session_store` | | +| **auth** | [`auth/`](../src/coding/proxy/auth/) | 认证系统:OAuth providers(GitHub Device Flow / Google OAuth2)/ runtime reauth / token store | | +| **model** | [`model/`](../src/coding/proxy/model/) | 数据模型正交分解:vendor / compat / constants / pricing / token / auth | | +| **config** | [`config/`](../src/coding/proxy/config/) | Pydantic v2 配置模型(正交拆分为 server/vendors/resiliency/routing/auth_schema)+ YAML 加载器 | [配置参考](./arch/config-reference.md) | +| **convert** | [`convert/`](../src/coding/proxy/convert/) | API 格式转换(Anthropic ↔ Gemini ↔ OpenAI 三向转换,含 SSE 流适配) | [格式转换](./arch/convert.md) | +| **logging** | [`logging/`](../src/coding/proxy/logging/) | Token 用量 SQLite 持久化([`db.py`](../src/coding/proxy/logging/db.py))、统计查询([`stats.py`](../src/coding/proxy/logging/stats.py))、Rich 格式化 | | +| **server** | [`server/`](../src/coding/proxy/server/) | FastAPI 应用工厂与生命周期管理(app/factory/routes/normalizer/responses/dashboard) | | +| **streaming** | [`streaming/`](../src/coding/proxy/streaming/) | Anthropic 兼容流式处理([`anthropic_compat.py`](../src/coding/proxy/streaming/anthropic_compat.py)) | | +| **cli** | [`cli/`](../src/coding/proxy/cli/) | Typer 命令行入口(start/status/usage/reset/auth)+ Banner 显示 | | +| **pricing** | [`pricing.py`](../src/coding/pricing.py) | 定价表(`PricingTable`):按 (vendor, model) 查询单价并计算费用 | | --- -## 4. 请求生命周期 +## 3. 请求生命周期 -### 4.1 完整请求流程 +### 3.1 完整请求流程 ```mermaid flowchart TD @@ -778,7 +251,7 @@ flowchart TD style Normalize fill:#2874a6,color:#fff ``` -### 4.2 流式请求处理 +### 3.2 流式请求处理 流式请求使用 `StreamingResponse` + 异步生成器 `_stream_proxy()`: @@ -790,10 +263,10 @@ flowchart TD 4. 流结束后: - `UsageRecorder.build_usage_info(usage)` 构建结构化用量信息 - 检查缺失信号并 WARNING 日志 - - `tier.record_success(input_tokens + output_tokens)` -- 通知 CB 成功 + QG/WQG 记录用量 + 清除 RL deadline - - `UsageRecorder.log_model_call()` -- 输出含定价信息的 Access Log - - `RouteSessionManager.persist_session()` -- 持久化兼容性会话状态 - - `UsageRecorder.record()` -- 记录完整用量到 TokenLogger(含 evidence_records) + - `tier.record_success(input_tokens + output_tokens)` — 通知 CB 成功 + QG/WQG 记录用量 + 清除 RL deadline + - `UsageRecorder.log_model_call()` — 输出含定价信息的 Access Log + - `RouteSessionManager.persist_session()` — 持久化兼容性会话状态 + - `UsageRecorder.record()` — 记录完整用量到 TokenLogger(含 evidence_records) **故障转移时**:清空已收集的 usage 数据,从下一个 tier 重新开始流式传输。 @@ -806,7 +279,7 @@ flowchart TD | `TimeoutException/ConnectError/ReadError` | `error` event + `api_error` | | `HTTPStatusError` | `error` event + 提取的 error type/message | -### 4.3 非流式请求处理 +### 3.3 非流式请求处理 非流式请求直接调用 `send_message()` 获取完整 `VendorResponse`: @@ -818,14 +291,16 @@ flowchart TD 3. 捕获 `TokenAcquireError` -> `handle_token_error()` + 触发 reauth -> 下一 tier(非最后一层) 4. 捕获 `TimeoutException/ConnectError/ReadError` -> `record_failure()` -> 下一 tier -**VendorResponse 新增字段**: +**VendorResponse 关键字段**: | 字段 | 类型 | 说明 | | ------------------ | ---------------- | --------------------------------------------- | | `model_served` | `str \| None` | 后端实际使用的模型名(可能经 map_model 转换) | | `response_headers` | `dict[str, str]` | 原始响应头(用于 rate limit 解析) | -### 4.4 故障转移判定逻辑 +### 3.4 故障转移判定逻辑 + + 故障转移的判定在 `BaseVendor.should_trigger_failover()` 中实现,依据三层条件(可通过配置文件自定义): @@ -839,486 +314,105 @@ flowchart TD **语义拒绝独立路径**:`is_semantic_rejection()` 检测 400 状态码下的 `invalid_request_error` 类型或特定消息模式(如 `should match pattern`、`validation`、`tool_use_id`、`server_tool_use`),此类错误**不记录 failure** 且**不触发故障转移计数**,直接跳至下一 tier。 -**终端供应商行为**:ZhipuVendor 因构造时不传入 `failover_config`,`should_trigger_failover()` 始终返回 `False`。 +**终端供应商行为**:无 `circuit_breaker` 配置的供应商(终端层),`should_trigger_failover()` 始终返回 `False`。 -### 4.5 生命周期管理 +### 3.5 生命周期管理 通过 `lifespan` 异步上下文管理器管理应用生命周期([`server/app.py`](../src/coding/proxy/server/app.py)): **启动 (Startup)**: -1. `TokenLogger.init()` -- 创建 SQLite 数据库表和索引 -2. `CompatSessionStore.init()` -- 初始化兼容性会话存储 -3. `PricingTable(config.pricing)` -- 加载模型定价表并注入 Router +1. `TokenLogger.init()` — 创建 SQLite 数据库表和索引 +2. `CompatSessionStore.init()` — 初始化兼容性会话存储 +3. `PricingTable(config.pricing)` — 加载模型定价表并注入 Router 4. 为每个启用了 QuotaGuard 的 tier 加载基线: - `token_logger.query_window_total(qg.window_hours, vendor=tier.name)` -> `quota_guard.load_baseline(total)` - 同理处理 `weekly_quota_guard` **关闭 (Shutdown)**: -1. `router.close()` -- 关闭所有 vendor 的 HTTP 客户端(含 TokenManager 客户端) -2. `compat_session_store.close()` -- 关闭会话存储连接 -3. `token_logger.close()` -- 关闭数据库连接 +1. `router.close()` — 关闭所有 vendor 的 HTTP 客户端(含 TokenManager 客户端) +2. `compat_session_store.close()` — 关闭会话存储连接 +3. `token_logger.close()` — 关闭数据库连接 --- -## 5. 模块详细设计 - -### 5.1 vendors/ -- 供应商模块(主架构) - -**BaseVendor**([`vendors/base.py`](../src/coding/proxy/vendors/base.py))-- 抽象基类,模板方法模式的核心: - -```python -class BaseVendor(ABC): - def __init__(self, base_url, timeout_ms, failover_config=None) - - # -- 抽象方法 -- - @abstractmethod - def get_name(self) -> str: ... - @abstractmethod - async def _prepare_request(self, body, headers) -> tuple[dict, dict]: ... - - # -- 核心方法(模板固定流程) -- - async def send_message(self, body, headers) -> VendorResponse: ... - async def send_message_stream(self, body, headers) -> AsyncIterator[bytes]: ... - - # -- 能力与兼容性 -- - def get_capabilities(self) -> VendorCapabilities: ... - def supports_request(self, caps) -> tuple[bool, list[CapabilityLossReason]]: ... - def make_compatibility_decision(self, request) -> CompatibilityDecision: ... - def map_model(self, model) -> str: ... - - # -- 钩子方法(子类可选覆写) -- - def _get_endpoint(self) -> str: ... # 默认 /v1/messages - def _pre_send_check(self, body, headers): ... # 默认 no-op - def _normalize_error_response(self, status, response, resp) -> VendorResponse: ... - def _on_error_status(self, status_code): ... # 默认 no-op - def check_health() -> Awaitable[bool]: ... # 默认返回 True - - # -- 故障转移 -- - def should_trigger_failover(self, status_code, body) -> bool: ... - - # -- 生命周期 -- - async def close(): ... -``` - -**数据类型**(定义于 [`model/vendor.py`](../src/coding/proxy/model/vendor.py),由 `base.py` re-export): - -```python -@dataclass -class UsageInfo: - input_tokens: int = 0 - output_tokens: int = 0 - cache_creation_tokens: int = 0 - cache_read_tokens: int = 0 - request_id: str = "" - -@dataclass -class VendorResponse: - status_code: int = 200 - usage: UsageInfo = field(default_factory=UsageInfo) - is_streaming: bool = False - raw_body: bytes = b"{}" - error_type: str | None = None - error_message: str | None = None - model_served: str | None = None # 后端实际使用的模型 - response_headers: dict[str, str] = field(default_factory=dict) - -class NoCompatibleVendorError(RuntimeError): - def __init__(self, message, *, reasons=None): ... - reasons: list[str] - -class CapabilityLossReason(Enum): - TOOLS = "tools" - THINKING = "thinking" - IMAGES = "images" - VENDOR_TOOLS = "vendor_tools" - METADATA = "metadata" - -@dataclass(frozen=True) -class RequestCapabilities: - has_tools: bool = False - has_thinking: bool = False - has_images: bool = False - has_metadata: bool = False - -@dataclass(frozen=True) -class VendorCapabilities: - supports_tools: bool = True - supports_thinking: bool = True - supports_images: bool = True - emits_vendor_tool_events: bool = False - supports_metadata: bool = True -``` - -**四个具体 Vendor 实现**: - -| Vendor | 文件 | 协议 | 认证方式 | 特殊能力 | -| --------------------- | ---------------------------------------------------------------------- | ------------------------ | ---------------------------------- | ------------------------------------------------- | -| **AnthropicVendor** | [`vendors/anthropic.py`](../src/coding/proxy/vendors/anthropic.py) | Anthropic Messages API | 透传 OAuth token | 全能力支持,旁路 count_tokens | -| **CopilotVendor** | [`vendors/copilot.py`](../src/coding/proxy/vendors/copilot.py) | OpenAI Chat Completions | GitHub token -> Copilot token 交换 | 不支持 thinking;内置模型探测 | -| **AntigravityVendor** | [`vendors/antigravity.py`](../src/coding/proxy/vendors/antigravity.py) | Gemini GenerateContent | Google OAuth2 refresh_token | 不支持 tools/thinking/metadata;覆写 health check | -| **ZhipuVendor** | [`vendors/zhipu.py`](../src/coding/proxy/vendors/zhipu.py) | Anthropic-compatible API | x-api-key | 不支持 thinking/images/metadata;覆写 map_model | - -**向后兼容别名汇总**(均标记 `deprecated`,保障迁移期兼容性): - -| 旧名称 | 新名称 | 定义位置 | -| -------------------------- | ------------------------- | ----------------- | -| `BaseBackend` | `BaseVendor` | `vendors/base.py` | -| `NoCompatibleBackendError` | `NoCompatibleVendorError` | `vendors/base.py` | -| `BackendTier` | `VendorTier` | `routing/tier.py` | -| `BackendCapabilities` | `VendorCapabilities` | `model/vendor.py` | -| `BackendResponse` | `VendorResponse` | `model/vendor.py` | - -### 5.2 routing/ -- 路由模块 - -#### 5.2.1 VendorTier([`routing/tier.py`](../src/coding/proxy/routing/tier.py)) - -```python -@dataclass -class VendorTier: - vendor: BaseVendor - circuit_breaker: CircuitBreaker | None = None - quota_guard: QuotaGuard | None = None - weekly_quota_guard: QuotaGuard | None = None # 周度配额守卫 - retry_config: RetryConfig | None = None # 重试策略参数 - _rate_limit_deadline: float = 0.0 # Rate Limit 截止 monotonic 时间戳 -``` - -**向后兼容别名**:`BackendTier = VendorTier`(deprecated,详见 [§5.1 别名汇总表](#51-vendors--供应商模块主架构)) - -#### 5.2.2 _RouteExecutor([`routing/executor.py`](../src/coding/proxy/routing/executor.py)) - -统一的 tier 迭代门控引擎,封装 `execute_stream()` / `execute_message()` 共享的循环逻辑: - -**职责**: -- 按优先级遍历 tiers,执行能力门控与健康检查 -- 委托具体的流式/非流式执行给 vendor -- 统一处理 `TokenAcquireError` / HTTP 错误 / 语义拒绝 -- 成功后委托 UsageRecorder 记录用量与定价日志 - -**关键方法**: - -| 方法 | 说明 | -| ------------------------------------------------------------------ | -------------------------------------------------------------------- | -| `execute_stream(body, headers)` | 流式路由主循环,yield `(chunk, vendor_name)` | -| `execute_message(body, headers)` | 非流式路由主循环,返回 `VendorResponse` | -| `_try_gate_tier(tier, is_last, caps, canonical, session, reasons)` | 单 tier 门控:能力匹配 -> 兼容性决策 -> 上下文应用 -> 健康检查 | -| `_handle_token_error(tier, exc, is_last, failed_name)` | TokenAcquireError 处理 + reauth 触发 | -| `_handle_http_error(tier, exc, ...)` | HTTP 错误处理:语义拒绝 / cap error / rate limit 解析 / failure 记录 | -| `_is_cap_error(resp)` | 静态方法:检测 429/403 + 配额关键词 | - -#### 5.2.3 UsageRecorder([`routing/usage_recorder.py`](../src/coding/proxy/routing/usage_recorder.py)) - -封装路由层的用量记录、定价计算与证据构建: - -| 方法 | 说明 | -| ------------------------------------------------------------------------ | -------------------------------------------------------- | -| `set_pricing_table(table)` | 注入 PricingTable(lifespan 启动时调用) | -| `build_usage_info(usage_dict)` | 从原始 dict 构建结构化 UsageInfo | -| `log_model_call(vendor, model_requested, model_served, duration, usage)` | 输出 ModelCall 级别 Access Log(含定价) | -| `record(vendor, ..., evidence_records)` | 持久化用量到 TokenLogger + evidence 记录(Copilot 专用) | -| `build_nonstream_evidence_records(...)` | 构建非流式证据记录 | - -#### 5.2.4 RouteSessionManager([`routing/session_manager.py`](../src/coding/proxy/routing/session_manager.py)) - -管理单次路由请求的兼容性会话生命周期: - -| 方法 | 说明 | -| ---------------------------------------------------------- | ------------------------------------- | -| `get_or_create_record(session_key, trace_id)` | 获取或创建会话记录 | -| `apply_compat_context(tier, canonical, decision, session)` | 构建 CompatibilityTrace 并注入 vendor | -| `persist_session(trace, session)` | 持久化会话状态到 CompatSessionStore | - -#### 5.2.5 Error Classifier([`routing/error_classifier.py`](../src/coding/proxy/routing/error_classifier.py)) - -HTTP 错误分类与请求能力画像提取: - -| 函数 | 说明 | -| --------------------------------------------------------------- | ------------------------------------------------------ | -| `build_request_capabilities(body)` | 从请求体提取能力画像(tools/thinking/images/metadata) | -| `is_semantic_rejection(status_code, error_type, error_message)` | 判断是否为语义拒绝(400 + 特定模式) | -| `extract_error_payload_from_http_status(exc)` | 从 HTTPStatusError 安全提取 JSON payload | - -#### 5.2.6 Rate Limit([`routing/rate_limit.py`](../src/coding/proxy/routing/rate_limit.py)) - -速率限制信息解析与截止时间计算: - -| 函数/类 | 说明 | -| ------------------------------------------------------- | ------------------------------------------------------------------------ | -| `RateLimitInfo` | 数据类:retry_after / requests_reset_at / tokens_reset_at / is_cap_error | -| `parse_rate_limit_headers(headers, status, error_body)` | 从响应头解析所有速率限制信号 | -| `compute_effective_retry_seconds(info)` | 计算最保守恢复等待时间(相对秒数,+10% 余量) | -| `compute_rate_limit_deadline(info)` | 计算最保守恢复截止时间(绝对 monotonic 时间戳,+10% 余量) | - -#### 5.2.7 Retry([`routing/retry.py`](../src/coding/proxy/routing/retry.py)) - -传输层重试策略: - -| 函数/类 | 说明 | -| ------------------------------- | ----------------------------------------------------------------------------------- | -| `RetryConfig` | 数据类:max_retries / initial_delay_ms / max_delay_ms / backoff_multiplier / jitter | -| `is_retryable_error(exc)` | 判断异常是否值得重试 | -| `is_retryable_status(code)` | 判断状态码是否值得重试(5xx) | -| `calculate_delay(attempt, cfg)` | 计算第 N 次重试延迟(含 Full Jitter) | - -#### 5.2.8 CircuitBreaker 参数([`routing/circuit_breaker.py`](../src/coding/proxy/routing/circuit_breaker.py)) - -| 参数 | 类型 | 默认值 | 说明 | -| -------------------------- | ---- | ------ | ------------------------------------ | -| `failure_threshold` | int | 3 | 触发 OPEN 的连续失败次数 | -| `recovery_timeout_seconds` | int | 300 | OPEN -> HALF_OPEN 等待秒数 | -| `success_threshold` | int | 2 | HALF_OPEN -> CLOSED 所需连续成功次数 | -| `max_recovery_seconds` | int | 3600 | 指数退避最大恢复时间(秒) | - -#### 5.2.9 QuotaGuard 参数([`routing/quota_guard.py`](../src/coding/proxy/routing/quota_guard.py)) - -| 参数 | 类型 | 默认值 | 说明 | -| ------------------------ | ----- | ------ | ------------------------------------ | -| `enabled` | bool | False | 是否启用配额守卫 | -| `token_budget` | int | 0 | 滑动窗口内的 Token 预算上限 | -| `window_hours` | float | 5.0 | 滑动窗口大小(小时),默认 5 小时 | -| `threshold_percent` | float | 99.0 | 触发 QUOTA_EXCEEDED 的用量百分比阈值 | -| `probe_interval_seconds` | int | 300 | QUOTA_EXCEEDED 状态下探测间隔(秒) | - -**QuotaGuard 公共方法**: - -| 方法 | 说明 | -| ----------------------------- | ------------------------------------------------ | -| `can_use_primary()` | 综合判断是否允许使用此后端 | -| `record_usage(tokens)` | 记录 Token 用量到滑动窗口 | -| `record_primary_success()` | 探测成功后恢复为 WITHIN_QUOTA | -| `notify_cap_error()` | 外部通知检测到 cap 错误,强制进入 QUOTA_EXCEEDED | -| `load_baseline(total_tokens)` | 从数据库加载历史用量基线 | -| `reset()` | 手动重置为 WITHIN_QUOTA | -| `get_info()` | 获取状态信息(供 `/api/status` 使用) | - -### 5.3 compat/ -- 兼容性抽象模块 - -#### 5.3.1 CanonicalRequest([`compat/canonical.py`](../src/coding/proxy/compat/canonical.py) + [`model/compat.py`](../src/coding/proxy/model/compat.py)) - -供应商无关的 Claude/Anthropic 语义抽象,从原始请求体提取: - -```python -@dataclass -class CanonicalRequest: - session_key: str # 会话标识(用于兼容性状态关联) - trace_id: str # 追踪 ID(UUID) - request_id: str # 原始请求 ID - model: str # 请求模型名 - messages: list[CanonicalMessagePart] # 消息内容(正交分解) - thinking: CanonicalThinking # 思考模式配置 - metadata: dict # 元数据 - tool_names: list[str] # 工具名称列表 - supports_json_output: bool # 是否要求 JSON 结构化输出 -``` - -**session_key 派生策略**(优先级从高到低): -1. `x-claude-session-id` / `x-session-id` / `session-id` 请求头 -2. `metadata.session_id` / `conversation_id` / `user_id` -3. SHA-256 哈希(model + system + tools + 最近 6 条消息) - -#### 5.3.2 CompatibilityDecision([`model/compat.py`](../src/coding/proxy/model/compat.py)) - -```python -class CompatibilityStatus(Enum): - NATIVE = "native" # 完全原生支持 - SIMULATED = "simulated" # 可通过模拟/投影方式支持 - UNSAFE = "unsafe" # 存在不可弥补的语义缺失 - UNKNOWN = "unknown" # 未知(保守处理) - -@dataclass -class CompatibilityDecision: - status: CompatibilityStatus - simulation_actions: list[str] # 需要执行的模拟动作 - unsupported_semantics: list[str] # 不支持的语义列表 -``` - -#### 5.3.3 CompatibilityProfile([`vendors/base.py`](../src/coding/proxy/vendors/base.py) -> `get_compatibility_profile()`) - -将 `VendorCapabilities` 映射为细粒度的兼容性状态: - -| VendorCapabilities | thinking | tool_calling | tool_streaming | mcp_tools | images | metadata | json_output | usage_tokens | -| ------------------ | -------- | ------------ | -------------- | --------- | ------ | -------- | ----------- | ------------ | -| supports=True | NATIVE | NATIVE | SIMULATED | UNKNOWN | NATIVE | NATIVE | UNKNOWN | SIMULATED | -| supports=False | UNSAFE | UNSAFE | UNSAFE | UNSAFE | UNSAFE | UNSAFE | UNSAFE | SIMULATED | - -#### 5.3.4 CompatSessionStore([`compat/session_store.py`](../src/coding/proxy/compat/session_store.py)) - -兼容性会话持久化存储,跨请求保持供应商适配状态: - -- 基于 SQLite / JSON 文件的 KV 存储 -- TTL 自动过期清理 -- `upsert()` 原子更新会话状态 - -### 5.4 model/ -- 数据模型模块 - -数据模型的正交分解,遵循单一职责原则: - -| 子模块 | 文件 | 核心类型 | -| ------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **vendor** | [`model/vendor.py`](../src/coding/proxy/model/vendor.py) | `UsageInfo`, `VendorResponse`, `NoCompatibleVendorError`, `RequestCapabilities`, `VendorCapabilities`, `CapabilityLossReason`, 兼容别名(`Backend*`),Copilot 诊断类, 工具函数 | -| **compat** | [`model/compat.py`](../src/coding/proxy/model/compat.py) | `CanonicalRequest`, `CanonicalMessagePart`, `CanonicalThinking`, `CanonicalToolCall`, `CompatibilityDecision`, `CompatibilityProfile`, `CompatibilityStatus`, `CompatibilityTrace` | -| **constants** | [`model/constants.py`](../src/coding/proxy/model/constants.py) | `PROXY_SKIP_HEADERS`, `RESPONSE_SANITIZE_SKIP_HEADERS` 等常量 | -| **pricing** | [`model/pricing.py`](../src/coding/proxy/model/pricing.py) | `ModelPricing`, `CostValue`, `Currency` | -| **token** | [`model/token.py`](../src/coding/proxy/model/token.py) | Token 相关模型 | - -### 5.5 auth/ -- 认证模块 - -#### 5.5.1 OAuth Provider 架构([`auth/providers/`](../src/coding/proxy/auth/providers/)) - -| Provider | 文件 | OAuth 流程 | 用途 | -| ---------------------------- | --------------------------------------------------------------------- | -------------------------------------------- | ---------------------- | -| **GitHubDeviceFlowProvider** | [`providers/github.py`](../src/coding/proxy/auth/providers/github.py) | GitHub Device Authorization Grant | Copilot token 获取 | -| **GoogleOAuthProvider** | [`providers/google.py`](../src/coding/proxy/auth/providers/google.py) | OAuth 2.0 Authorization Code + Refresh Token | Antigravity token 获取 | -| **BaseOAuthProvider** | [`providers/base.py`](../src/coding/proxy/auth/providers/base.py) | 抽象基类 | 统一 login() 接口 | - -#### 5.5.2 RuntimeReauthCoordinator([`auth/runtime.py`](../src/coding/proxy/auth/runtime.py)) - -运行时 OAuth 重认证协调器,当 TokenManager 报告凭证过期时后台触发浏览器登录: - -**状态机**:`IDLE -> PENDING -> COMPLETED / FAILED` - -**关键方法**: +## 4. 模块概览 -| 方法 | 说明 | -| ------------------------------- | -------------------------------------------------------------- | -| `request_reauth(provider_name)` | 幂等触发重认证(后台 asyncio.Task) | -| `get_status()` | 返回所有 provider 的 `{state, error?, completed_ago_seconds?}` | +### 4.1 compat/ — 兼容性抽象 -**与熔断器的协同**:重认证期间 TokenManager 持续抛 `TokenAcquireError` -> Router 触发 failover -> CB 可能 OPEN -> 请求路由到下一层级 -> 重认证完成 -> CB 恢复 -> 后端重新可用。 +供应商无关的语义抽象,跨请求保持供应商适配状态: -#### 5.5.3 TokenStoreManager([`auth/store.py`](../src/coding/proxy/auth/store.py)) +- **CanonicalRequest**([`compat/canonical.py`](../src/coding/proxy/compat/canonical.py)):从原始请求体提取供应商无关的语义结构(session_key / model / messages / thinking / tool_names 等) +- **CompatibilityDecision**([`model/compat.py`](../src/coding/proxy/model/compat.py)):三态决策(NATIVE / SIMULATED / UNSAFE),指导路由层跳过或适配 +- **CompatSessionStore**([`compat/session_store.py`](../src/coding/proxy/compat/session_store.py)):兼容性会话持久化存储,基于 SQLite KV,支持 TTL 自动过期 -Token 持久化管理器,支持凭证的跨进程/跨重启保持: +### 4.2 model/ — 数据模型 -- 存储:JSON 文件(`~/.coding-proxy/tokens.json` 或自定义路径) -- 按 provider 名称(`"github"` / `"google"`)分区存储 -- 提供 `get(name)` / `set(name, tokens)` / `load()` 接口 +数据模型正交分解,遵循单一职责原则: -**凭证合并优先级**(在 `server/factory.py` 中实现):Token Store > config.yaml +| 子模块 | 文件 | 核心类型 | +| ------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| **vendor** | [`model/vendor.py`](../src/coding/proxy/model/vendor.py) | `UsageInfo`, `VendorResponse`, `NoCompatibleVendorError`, `RequestCapabilities`, `VendorCapabilities`, `CapabilityLossReason` | +| **compat** | [`model/compat.py`](../src/coding/proxy/model/compat.py) | `CanonicalRequest`, `CompatibilityDecision`, `CompatibilityProfile`, `CompatibilityStatus`, `CompatibilityTrace` | +| **constants** | [`model/constants.py`](../src/coding/proxy/model/constants.py) | `PROXY_SKIP_HEADERS`, `RESPONSE_SANITIZE_SKIP_HEADERS` 等常量 | +| **pricing** | [`model/pricing.py`](../src/coding/proxy/model/pricing.py) | `ModelPricing`, `CostValue`, `Currency` | +| **token** | [`model/token.py`](../src/coding/proxy/model/token.py) | Token 相关模型 | +| **auth** | [`model/auth.py`](../src/coding/proxy/model/auth.py) | 认证相关模型 | -### 5.6 config/ -- 配置模块 +### 4.3 auth/ — 认证模块 -#### 5.6.1 正交分解结构 +| 组件 | 文件 | 职责 | +| ---------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------- | +| **GitHubDeviceFlowProvider** | [`providers/github.py`](../src/coding/proxy/auth/providers/github.py) | GitHub Device Authorization Grant | +| **GoogleOAuthProvider** | [`providers/google.py`](../src/coding/proxy/auth/providers/google.py) | OAuth 2.0 Authorization Code + Refresh Token | +| **RuntimeReauthCoordinator** | [`runtime.py`](../src/coding/proxy/auth/runtime.py) | 运行时 OAuth 重认证协调(IDLE → PENDING → COMPLETED / FAILED) | +| **TokenStoreManager** | [`store.py`](../src/coding/proxy/auth/store.py) | Token 持久化(JSON 文件),按 provider 分区存储 | -配置模型已从单体 `schema.py` 正交拆分为 5 个子模块: +### 4.4 logging/ — 日志模块 -| 子模块 | 文件 | 核心类型 | -| --------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | -| **server** | [`config/server.py`](../src/coding/proxy/config/server.py) | `ServerConfig`, `DatabaseConfig`, `LoggingConfig` | -| **vendors** | [`config/vendors.py`](../src/coding/proxy/config/vendors.py) | `VendorConfig`, `VendorType`, `AnthropicConfig`, `CopilotConfig`, `AntigravityConfig`, `ZhipuConfig` | -| **resiliency** | [`config/resiliency.py`](../src/coding/proxy/config/resiliency.py) | `CircuitBreakerConfig`, `RetryConfig`, `FailoverConfig`, `QuotaGuardConfig` | -| **routing** | [`config/routing.py`](../src/coding/proxy/config/routing.py) | `VendorType`, `VendorConfig`, `ModelMappingRule`, `ModelPricingEntry` | -| **auth_schema** | [`config/auth_schema.py`](../src/coding/proxy/config/auth_schema.py) | `AuthConfig` | +| 组件 | 文件 | 职责 | +| ----------------- | -------------------------------------------------------------- | -------------------------------------- | +| **TokenLogger** | [`db.py`](../src/coding/proxy/logging/db.py) | SQLite 用量持久化、窗口查询、evidence 记录 | +| **统计工具** | [`stats.py`](../src/coding/proxy/logging/stats.py) | 统计查询与 Rich 格式化展示 | -`config/schema.py` 作为聚合入口点 re-export 所有符号,并保留 `ProxyConfig` 顶层模型及旧格式迁移逻辑。 +**usage_log 表结构**: -#### 5.6.2 vendors 列表格式(推荐) +| 列名 | 类型 | 说明 | +| ----------------------- | ---------- | ------------ | +| `id` | INTEGER PK | 自增主键 | +| `ts` | TEXT | ISO 8601 UTC | +| `vendor` | TEXT | 供应商标识 | +| `model_requested` | TEXT | 请求模型名 | +| `model_served` | TEXT | 实际模型名 | +| `input_tokens` | INTEGER | 输入 Token | +| `output_tokens` | INTEGER | 输出 Token | +| `cache_creation_tokens` | INTEGER | 缓存创建 | +| `cache_read_tokens` | INTEGER | 缓存读取 | +| `duration_ms` | INTEGER | 耗时(ms) | +| `success` | BOOLEAN | 是否成功 | +| `failover` | BOOLEAN | 是否故障转移 | +| `request_id` | TEXT | 请求 ID | -新的 `vendors` 列表格式是推荐配置方式,每个 vendor 自包含其弹性配置: - -```yaml -vendors: - - vendor: anthropic - enabled: true - base_url: https://api.anthropic.com - timeout_ms: 300000 - circuit_breaker: - failure_threshold: 3 - recovery_timeout_seconds: 300 - quota_guard: - enabled: false - weekly_quota_guard: - enabled: false - - - vendor: copilot - enabled: false - github_token: "${GITHUB_TOKEN}" - account_type: individual - circuit_breaker: - failure_threshold: 3 - quota_guard: - enabled: true - token_budget: 3000000 - window_hours: 4.0 - - - vendor: zhipu - enabled: true - api_key: "${ZHIPU_API_KEY}" - # 无 circuit_breaker -> 终端层 - -tiers: [anthropic, copilot, zhipu] # 显式优先级(可选) -``` - -#### 5.6.3 Legacy Flat 格式(向后兼容) - -旧的 flat 格式字段(`primary`/`copilot`/`antigravity`/`fallback`/`circuit_breaker`/`*_quota_guard`)仍受支持,通过 `ProxyConfig._migrate_legacy_fields()` 自动迁移为 vendors 列表格式。 - -迁移规则: -1. `anthropic` 字段名 -> `primary` -2. `zhipu` 字段名 -> `fallback` -3. 若无 `vendors` 字段,从 legacy flat 字段自动生成 vendors 列表 -4. 迁移时发出 INFO 日志建议迁移至新格式 - -#### 5.6.4 配置搜索优先级([`config/loader.py`](../src/coding/proxy/config/loader.py)) - -```mermaid -flowchart TD - A["CLI --config 参数
(显式指定)"] -->|"未指定"| B["./config.yaml
(项目根目录)"] - B -->|"不存在"| C["~/.coding-proxy/config.yaml
(用户目录)"] - C -->|"不存在"| D["Pydantic 默认值"] - - style A fill:#1a5276,color:#fff - style D fill:#7b241c,color:#fff -``` - -**环境变量展开**:语法 `${VARIABLE_NAME}`,递归处理 dict/list/str,未定义变量保留原文。 - -### 5.7 logging/ -- 日志模块 - -#### 5.7.1 usage_log 表结构([`logging/db.py`](../src/coding/proxy/logging/db.py)) - -| 列名 | 类型 | 说明 | -| ----------------------- | ---------- | ----------------------------------------------------------------------- | -| `id` | INTEGER PK | 自增主键 | -| `ts` | TEXT | 时间戳(ISO 8601 格式,UTC) | -| `vendor` | TEXT | 供应商标识(`"anthropic"` / `"copilot"` / `"antigravity"` / `"zhipu"`) | -| `model_requested` | TEXT | 客户端请求的模型名称 | -| `model_served` | TEXT | 实际使用的模型名称 | -| `input_tokens` | INTEGER | 输入 Token 数 | -| `output_tokens` | INTEGER | 输出 Token 数 | -| `cache_creation_tokens` | INTEGER | 缓存创建 Token 数 | -| `cache_read_tokens` | INTEGER | 缓存读取 Token 数 | -| `duration_ms` | INTEGER | 请求耗时(毫秒) | -| `success` | BOOLEAN | 是否成功 | -| `failover` | BOOLEAN | 是否经过故障转移 | -| `request_id` | TEXT | 请求 ID | - -**索引**:`idx_usage_ts`(时间戳)、`idx_usage_vendor`(供应商名) - -**Evidence 记录**(Copilot 专用):`log_evidence()` 方法记录原始用量 JSON 与解析结果的对照,用于诊断 OpenAI -> Anthropic 用量映射准确性。 - -### 5.8 server/ -- 服务模块 - -#### 5.8.1 正交分解 +### 4.5 server/ — 服务模块 | 文件 | 职责 | | ---------------------------------------------------------------------------------- | --------------------------------------------------------- | -| [`server/app.py`](../src/coding/proxy/server/app.py) | FastAPI 应用工厂 `create_app()` + `lifespan` 生命周期管理 | -| [`server/factory.py`](../src/coding/proxy/server/factory.py) | Vendor/Tier 构建工厂 + 凭证解析 | -| [`server/routes.py`](../src/coding/proxy/server/routes.py) | 路由端点按职责分组注册 | -| [`server/request_normalizer.py`](../src/coding/proxy/server/request_normalizer.py) | 入站请求标准化(清洗供应商私有块) | -| [`server/responses.py`](../src/coding/proxy/server/responses.py) | 响应辅助工具(JSON error / stream error 构建) | +| [`app.py`](../src/coding/proxy/server/app.py) | FastAPI 应用工厂 `create_app()` + `lifespan` 生命周期管理 | +| [`factory.py`](../src/coding/proxy/server/factory.py) | Vendor/Tier 构建工厂 + 凭证解析 | +| [`routes.py`](../src/coding/proxy/server/routes.py) | 路由端点按职责分组注册 | +| [`request_normalizer.py`](../src/coding/proxy/server/request_normalizer.py) | 入站请求标准化(清洗供应商私有块) | +| [`responses.py`](../src/coding/proxy/server/responses.py) | 响应辅助工具(JSON error / stream error 构建) | +| [`dashboard.py`](../src/coding/proxy/server/dashboard.py) | 状态面板(Web Dashboard) | -#### 5.8.2 API 端点清单 +**API 端点清单**: | 端点 | 方法 | 分组 | 说明 | | --------------------------- | -------- | ------- | -------------------------------------------- | | `/v1/messages` | POST | core | 代理 Anthropic Messages API(流式 + 非流式) | | `/v1/messages/count_tokens` | POST | core | Token 计数透传(旁路直通 Anthropic) | | `/health` | GET | health | 健康检查 | -| `HEAD /` / `GET /` | HEAD/GET | health | 根路径连通性探测(Claude Code 建连前发送) | +| `HEAD /` / `GET /` | HEAD/GET | health | 根路径连通性探测 | | `/api/status` | GET | status | 各 tier 的 CB/QG/WQG/RL/诊断状态 | | `/api/reset` | POST | admin | 重置所有 tier 的熔断器和配额守卫 | | `/api/copilot/diagnostics` | GET | copilot | Copilot 认证与交换链路脱敏诊断 | @@ -1326,143 +420,35 @@ flowchart TD | `/api/reauth/status` | GET | reauth | 运行时重认证状态查询 | | `/api/reauth/{provider}` | POST | reauth | 手动触发指定 provider 重认证 | ---- - -## 6. 配置系统设计 - -### 6.1 完整配置字段参考(vendors 列表格式) - -**server -- 服务器配置** - -| 字段 | 类型 | 默认值 | 说明 | -| ------ | ---- | ------------- | -------- | -| `host` | str | `"127.0.0.1"` | 监听地址 | -| `port` | int | `8046` | 监听端口 | - -**database -- 数据库配置** - -| 字段 | 类型 | 默认值 | 说明 | -| -------------------------- | ---- | ----------------------------------- | --------------------- | -| `path` | str | `"~/.coding-proxy/usage.db"` | SQLite 数据库文件路径 | -| `compat_state_path` | str | `"~/.coding-proxy/compat_state.db"` | 兼容性会话存储路径 | -| `compat_state_ttl_seconds` | int | `86400` | 兼容性会话 TTL(秒) | - -**logging -- 日志配置** - -| 字段 | 类型 | 默认值 | 说明 | -| ------- | ----------- | -------- | --------------------------------- | -| `level` | str | `"INFO"` | 日志级别 | -| `file` | str \| null | `null` | 日志文件路径(null 输出到控制台) | - -**auth -- 认证配置** - -| 字段 | 类型 | 默认值 | 说明 | -| ------------------ | ---- | ------ | ------------------------------------ | -| `token_store_path` | str | `""` | Token Store 文件路径(空则使用默认) | - -**VendorConfig 通用字段** - -| 字段 | 类型 | 默认值 | 说明 | -| ------------ | ---- | -------- | ------------------------------------------------------------- | -| `vendor` | enum | -- | 供应商类型:`anthropic` / `copilot` / `antigravity` / `zhipu` | -| `enabled` | bool | `true` | 是否启用 | -| `base_url` | str | `""` | API 基础 URL(留空使用默认值) | -| `timeout_ms` | int | `300000` | 请求超时(毫秒) | - -**VendorConfig 弹性字段** - -| 字段 | 类型 | 默认值 | 说明 | -| -------------------- | -------------- | -------------------- | --------------------------- | -| `circuit_breaker` | config \| None | `None` | 熔断器配置(None = 终端层) | -| `retry` | config | `RetryConfig()` | 重试策略配置 | -| `quota_guard` | config | `QuotaGuardConfig()` | 日度配额守卫配置 | -| `weekly_quota_guard` | config | `QuotaGuardConfig()` | 周度配额守卫配置 | - -**Copilot 专属字段** +### 4.6 streaming/ — 流式处理 -| 字段 | 类型 | 默认值 | 说明 | -| -------------------------- | ---- | --------------- | -------------------------------------------------- | -| `github_token` | str | `""` | GitHub OAuth token / PAT(支持 `${ENV_VAR}`) | -| `account_type` | str | `"individual"` | 账号类型:`individual` / `business` / `enterprise` | -| `token_url` | str | `"https://..."` | Token 交换端点 | -| `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL | +[`streaming/anthropic_compat.py`](../src/coding/proxy/streaming/anthropic_compat.py) 提供 Anthropic 兼容的流式处理层,负责 SSE 事件的重构与适配。 -**Antigravity 专属字段** - -| 字段 | 类型 | 默认值 | 说明 | -| ---------------- | ---- | ----------------------------------- | --------------------------- | -| `client_id` | str | `""` | Google OAuth2 Client ID | -| `client_secret` | str | `""` | Google OAuth2 Client Secret | -| `refresh_token` | str | `""` | Google OAuth2 Refresh Token | -| `model_endpoint` | str | `"models/claude-sonnet-4-20250514"` | Gemini 模型端点路径 | - -**Zhipu 专属字段** - -| 字段 | 类型 | 默认值 | 说明 | -| --------- | ---- | ------ | --------------------------------- | -| `api_key` | str | `""` | 智谱 API Key(支持 `${ENV_VAR}`) | - -> **弹性参数速查**:以下 4 类参数的详细语义参见对应设计模式章节——[§3.2 CircuitBreaker](#32-circuit-breaker熔断器模式)、[§3.7 QuotaGuard](#37-state-machine状态机模式--quotaguard)、[§3.12 Retry](#312-retry-with-full-jitter带完全抖动的重试模式)、[§4.4 故障转移判定](#44-故障转移判定逻辑)。 - -**CircuitBreakerConfig / QuotaGuardConfig / RetryConfig / FailoverConfig — 弹性参数一览** - -| 配置类 | 字段 | 类型 | 默认值 | -| ------------ | ----------------------------------------------------------------------------------------------- | --------------------------------- | --------------------------------------- | -| **CB** | `failure_threshold` / `recovery_timeout_seconds` / `success_threshold` / `max_recovery_seconds` | int / int / int / int | `3` / `300` / `2` / `3600` | -| **QG** | `enabled` / `token_budget` / `window_hours` / `threshold_percent` / `probe_interval_seconds` | bool / int / float / float / int | `false` / `0` / `5.0` / `99.0` / `300` | -| **Retry** | `max_retries` / `initial_delay_ms` / `max_delay_ms` / `backoff_multiplier` / `jitter` | int / int / int / float / bool | `2` / `500` / `5000` / `2.0` / `true` | -| **Failover** | `status_codes` / `error_types` / `error_message_patterns` | list[int] / list[str] / list[str] | `[429,403,503,500]` / 见 §4.4 / 见 §4.4 | +--- -**ModelMappingRule 字段** +## 5. 可扩展性设计 -| 字段 | 类型 | 说明 | -| ---------- | --------- | ----------------------------------------- | -| `pattern` | str | 匹配模式(精确/通配符/正则) | -| `target` | str | 目标模型名称 | -| `is_regex` | bool | 是否为正则表达式(默认 `false`) | -| `vendors` | list[str] | 规则作用域(留空仅作用于 fallback/zhipu) | +### 5.1 添加新供应商 -**ModelPricingEntry 字段** +根据供应商端点协议,有两条路径: -| 字段 | 类型 | 说明 | -| --------------------------- | ----- | ---------------------------------------------------- | -| `vendor` | str | 供应商名称 | -| `model` | str | 实际模型名 | -| `input_cost_per_mtok` | float | 输入 Token 单价($/百万 token,支持 `$`/`yen` 前缀) | -| `output_cost_per_mtok` | float | 输出 Token 单价 | -| `cache_write_cost_per_mtok` | float | 缓存创建 Token 单价 | -| `cache_read_cost_per_mtok` | float | 缓存读取 Token 单价 | +#### 路径 A:原生 Anthropic 兼容供应商(推荐,适用于端点已支持 Anthropic Messages API 的场景) -**tiers -- 显式优先级** +1. 在 `vendors/` 下创建新模块,继承 [`NativeAnthropicVendor`](../src/coding/proxy/vendors/native_anthropic.py) +2. 设置 `_vendor_name` 和 `_display_name` 类属性 +3. 在 [`config/routing.py`](../src/coding/proxy/config/routing.py) 的 `VendorType` 中添加新类型 +4. 在 [`config/vendors.py`](../src/coding/proxy/config/vendors.py) 中添加专属 Config(或复用 `api_key` 字段) +5. 在 [`server/factory.py`](../src/coding/proxy/server/factory.py) 的工厂函数中添加新分支 +6. 在配置文件的 `vendors` 列表中添加新条目 -| 字段 | 类型 | 说明 | -| ------- | ------------------------ | ------------------------------------------ | -| `tiers` | list[VendorType] \| None | 降级链路优先级(None 时回退 vendors 顺序) | +#### 路径 B:自定义协议供应商(适用于需要格式转换的场景) ---- +1. 在 `vendors/` 下创建新模块,继承 [`BaseVendor`](../src/coding/proxy/vendors/base.py) +2. 实现必需的抽象方法:`get_name()` 和 `_prepare_request()` +3. 按需覆写钩子方法:`map_model()`、`get_capabilities()`、`check_health()`、`_on_error_status()` 等 +4. 同路径 A 的步骤 3-6 -## 7. 可扩展性设计 - -### 7.1 添加新供应商 - -1. 在 `vendors/` 下创建新模块,继承 `BaseVendor` -2. 实现必需的抽象方法: - - `get_name()` -- 返回供应商标识字符串 - - `_prepare_request()` -- 转换请求体和请求头(异步,支持 token 刷新等异步操作) -3. 按需覆写钩子方法: - - `map_model()` -- 模型名称映射 - - `get_capabilities()` -- 能力声明 - - `check_health()` -- 健康探测 - - `_on_error_status()` -- 错误时标记 token 失效 - - `_get_endpoint()` -- 自定义端点 - - `send_message()` / `send_message_stream()` -- 自定义端点或格式转换 - - `close()` -- 释放额外资源 -4. 在 [`config/routing.py`](../src/coding/proxy/config/routing.py) 的 `VendorType` 中添加新类型 -5. 在 [`config/routing.py`](../src/coding/proxy/config/routing.py) 的 `VendorConfig` 中添加专属字段 -6. 在 [`server/factory.py`](../src/coding/proxy/server/factory.py) 的 `_create_vendor_from_config()` 中添加新分支 -7. 在配置文件的 `vendors` 列表中添加新条目 - -### 7.2 添加新映射规则 +### 5.2 添加新映射规则 在配置文件的 `model_mapping` 节添加规则即可,无需修改代码: @@ -1479,153 +465,26 @@ model_mapping: 匹配优先级确保精确匹配不会被通配符覆盖。 -### 7.3 自定义故障转移策略 - -通过配置文件调整 `failover` 节的三个字段即可自定义触发条件: +### 5.3 自定义故障转移策略 -- 增减 `status_codes` 控制哪些 HTTP 状态码触发切换 -- 增减 `error_types` 控制哪些 Anthropic 错误类型触发切换 -- 增减 `error_message_patterns` 控制哪些错误消息关键词触发切换 +通过配置文件调整 `failover` 节的三个字段即可自定义触发条件。参见 [配置参考 -- FailoverConfig](./arch/config-reference.md#elastic-params)。 -如需更复杂的策略,可覆写子类的 `should_trigger_failover()` 方法。 +### 5.4 自定义配额管理策略 -### 7.4 自定义配额管理策略 - -通过配置文件分别调整 `quota_guard` / `weekly_quota_guard` 的参数,可为每个供应商独立配置多层级配额管理策略: - -```yaml -vendors: - - vendor: anthropic - quota_guard: # 日度配额 - enabled: true - token_budget: 5000000 - window_hours: 5.0 - threshold_percent: 95.0 - weekly_quota_guard: # 周度配额 - enabled: true - token_budget: 20000000 - window_hours: 168.0 # 7 天 - threshold_percent: 90.0 -``` +通过配置文件分别调整 `quota_guard` / `weekly_quota_guard` 的参数,可为每个供应商独立配置多层级配额管理策略。参见 [配置参考 -- QuotaGuardConfig](./arch/config-reference.md#elastic-params)。 --- -## 8. convert/ 模块设计 - -### 8.1 请求转换(Anthropic -> Gemini) - -**应用位置**:[`convert/anthropic_to_gemini.py`](../src/coding/proxy/convert/anthropic_to_gemini.py) -- `convert_request()` - -**转换映射**: - -| Anthropic 字段 | Gemini 字段 | 说明 | -| --------------------------------- | ---------------------------------- | -------------------------------------------------- | -| `system`(str \| list) | `systemInstruction.parts[].text` | 支持字符串和文本块列表两种格式 | -| `messages[]` | `contents[]` | 角色映射:`assistant` -> `model`,`user` -> `user` | -| `content`(text) | `parts[].text` | 文本内容块 | -| `content`(image) | `parts[].inlineData` | Base64 数据 + MIME 类型 | -| `content`(tool_use) | `parts[].functionCall` | `name` + `input` -> `args` | -| `content`(tool_result) | `parts[].functionResponse` | `tool_use_id` -> `name`,`content` -> `result` | -| `max_tokens` | `generationConfig.maxOutputTokens` | | -| `temperature` / `top_p` / `top_k` | `generationConfig.*` | 参数名驼峰转换 | -| `stop_sequences` | `generationConfig.stopSequences` | | - -**不支持的字段**(静默剥离并记录 WARNING):`tools`、`tool_choice`、`metadata`、`extended_thinking`、`thinking` - -### 8.2 响应转换(Gemini -> Anthropic) - -**应用位置**:[`convert/gemini_to_anthropic.py`](../src/coding/proxy/convert/gemini_to_anthropic.py) -- `convert_response()` / `extract_usage()` - -**finishReason 映射**: - -| Gemini | Anthropic | -| --------------------------------- | ------------ | -| `STOP` | `end_turn` | -| `MAX_TOKENS` | `max_tokens` | -| `SAFETY` / `RECITATION` / `OTHER` | `end_turn` | - -**Parts 转换**: -- `text` -> `{"type": "text", "text": "..."}` -- `functionCall` -> `{"type": "tool_use", "id": "toolu_...", "name": "...", "input": {...}}` - -**Usage 提取**: -- `usageMetadata.promptTokenCount` -> `input_tokens` -- `usageMetadata.candidatesTokenCount` -> `output_tokens` -- 缓存字段填 0(Gemini 不直接暴露缓存信息) - -### 8.3 SSE 流适配 - -**应用位置**:[`convert/gemini_sse_adapter.py`](../src/coding/proxy/convert/gemini_sse_adapter.py) -- `adapt_sse_stream()` - -将 Gemini SSE 流重构为 Anthropic 消息生命周期事件序列: - -```mermaid -flowchart LR - Input["Gemini SSE chunks"] --> MS["message_start
← 首次收到内容时发出"] - MS --> CBS["content_block_start
← 内容块开始"] - CBS --> CBD["content_block_delta*
← 增量文本"] - CBD --> CBS2["content_block_stop
← 内容块结束"] - CBS2 --> MD["message_delta
← stop_reason + output_tokens"] - MD --> MSP["message_stop
← 消息结束"] - - style Input fill:#1a5276,color:#fff - style MSP fill:#196f3d,color:#fff -``` - -**边界情况处理**: -- 空 parts 后跟有 text 的 chunk -> 延迟发出 `message_start` + `content_block_start` -- 流结束但未收到 `finishReason` -> 补发默认 `message_delta`(`stop_reason: "end_turn"`)+ `message_stop` - -### 8.4 OpenAI 格式转换 - -**应用位置**: -- [`convert/anthropic_to_openai.py`](../src/coding/proxy/convert/anthropic_to_openai.py) -- Anthropic -> OpenAI Chat Completions 请求格式 -- [`convert/openai_to_anthropic.py`](../src/coding/proxy/convert/openai_to_anthropic.py) -- OpenAI Chat Completions -> Anthropic 响应格式 - -专为 CopilotVendor 适配,处理 Anthropic Messages API 与 OpenAI Chat Completions API 之间的双向格式差异(角色映射、工具格式、usage 字段名等)。 - ---- +## 6. 文档索引 -## 9. 测试策略 - -### 9.1 单元测试覆盖 - -| 测试文件 | 覆盖范围 | -| ---------------------------- | ---------------------------------------------------------------------------------- | -| `test_circuit_breaker.py` | 状态转换(CLOSED->OPEN->HALF_OPEN->CLOSED)、恢复超时、指数退避、手动重置 | -| `test_quota_guard.py` | 配额守卫状态机、预算追踪、探测机制、基线加载 | -| `test_model_mapper.py` | 精确匹配、正则匹配、Glob 匹配、默认回退、空规则集 | -| `test_vendor_tier.py` | VendorTier 可执行判断、成功/失败记录、终端判定、三层门控、Rate Limit deadline | -| `test_vendors.py` | 请求头过滤、模型映射、故障转移判断、数据类默认值 | -| `test_copilot_vendor.py` | CopilotTokenManager 交换/缓存/过期/失效、CopilotVendor 请求准备 | -| `test_antigravity_vendor.py` | GoogleOAuthTokenManager 刷新/缓存/过期/失效、AntigravityVendor 格式转换+token 注入 | -| `test_convert_request.py` | Anthropic->Gemini 请求转换(文本、多轮、system、图片、工具、参数映射) | -| `test_convert_response.py` | Gemini->Anthropic 响应转换(文本、多部件、usage 提取、finishReason 映射) | -| `test_convert_sse.py` | Gemini SSE->Anthropic SSE 流适配(单/多 chunk、各 finishReason、边界情况) | -| `test_convert_openai.py` | Anthropic<->OpenAI 双向格式转换 | -| `test_router_chain.py` | N-tier 链式路由(2/3/4-tier 降级、CB/QG 跳过、流式/非流式、连接异常) | -| `test_executor.py` | _RouteExecutor 门控逻辑、能力匹配、兼容性决策、语义拒绝、错误分类 | -| `test_error_classifier.py` | 请求能力画像提取、语义拒绝判定、错误 payload 解析 | -| `test_rate_limit.py` | Rate limit header 解析、deadline 计算、cap error 检测 | -| `test_retry.py` | RetryConfig 参数、delay 计算、可重试异常判定 | -| `test_usage_recorder.py` | UsageRecorder 用量构建、定价日志、evidence 记录 | -| `test_session_manager.py` | RouteSessionManager 会话创建/上下文应用/持久化 | -| `test_compat_canonical.py` | CanonicalRequest 构建、session_key 派生、thinking 提取、消息部分解析 | -| `test_config_loader.py` | 配置文件搜索优先级、环境变量展开、缺失文件处理、vendors 格式解析 | -| `test_config_schema.py` | ProxyConfig 校验、legacy 迁移、tiers 引用校验、vendor 专属字段 warning | -| `test_token_logger.py` | 用量记录、窗口查询、按供应商/模型过滤、evidence 记录 | -| `test_auth_runtime.py` | RuntimeReauthCoordinator 状态机、幂等触发、锁保护 | -| `test_auth_store.py` | TokenStoreManager 存取、load/save、TTL | -| `test_request_normalizer.py` | 请求标准化:私有块清洗、tool_use_id 重写、fatal_reasons | -| `test_pricing.py` | PricingTable 加载、单价查询(精确+规范化)、费用计算、币种一致性 | - -### 9.2 测试工具 - -- **pytest** (>=9.0) -- 测试框架 -- **pytest-asyncio** (>=1.3) -- 异步测试支持 -- **monkeypatch** -- 环境变量和工作目录隔离 -- **tmp_path** -- 临时文件测试 -- **respx** -- httpx Mock(用于 vendor 集成测试) +| 文档 | 内容 | +| ---------------------------------------------------------------------- | ---------------------------------------- | +| [设计模式详解](./arch/design-patterns.md) | 13 种设计模式(Template Method / Circuit Breaker / State Machine 等)与工程模式 | +| [供应商模块](./arch/vendors.md) | 供应商分类体系、9 个具体供应商 + 2 个抽象基类、数据类型 | +| [路由模块](./arch/routing.md) | 12 个路由子模块详解(VendorTier / Executor / CB / QG / Retry 等) | +| [配置参考](./arch/config-reference.md) | 完整配置字段参考、弹性参数规范来源(SSOT) | +| [格式转换](./arch/convert.md) | Anthropic ↔ Gemini ↔ OpenAI 三向格式转换详解 | +| [测试策略](./arch/testing.md) | 48 个测试文件按子系统分组的覆盖范围与工具链 | --- From 461f8b632524f692c586b9003174db06f383ce04 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 22:53:21 +0800 Subject: [PATCH 20/32] =?UTF-8?q?docs(arch):=20=E4=BA=8C=E8=BD=AE=E6=A0=A1?= =?UTF-8?q?=E5=87=86=E4=BF=AE=E6=AD=A3=E4=BA=8B=E5=AE=9E=E6=80=A7=E5=81=8F?= =?UTF-8?q?=E5=B7=AE=20=E2=80=94=20NativeAnthropicVendor=20=E5=8E=BB?= =?UTF-8?q?=E6=8A=BD=E8=B1=A1=E5=8C=96=E3=80=81FailoverConfig=20=E8=A1=A5?= =?UTF-8?q?=E5=85=A8=E9=BB=98=E8=AE=A4=E5=80=BC=E3=80=81routing=20?= =?UTF-8?q?=E5=AD=90=E6=A8=A1=E5=9D=97=E8=AE=A1=E6=95=B0=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - vendors.md / design-patterns.md: 移除 NativeAnthropicVendor 错误的 <> 标记(实际为具体基类,子类仅需覆写 _vendor_name 和 _display_name) - vendors.md: 补充 GoogleOAuthTokenManager 辅助模块文档(内嵌于 antigravity.py) - vendors.md: 修正 Path B 钩子方法措辞,区分可覆写方法与钩子方法 - config-reference.md / framework.md: FailoverConfig 默认值补全 status_codes 增加 529、error_message_patterns 增加 "internal network failure" - routing.md: 子模块计数从 13 修正为 12 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- docs/arch/config-reference.md | 4 ++-- docs/arch/design-patterns.md | 1 - docs/arch/routing.md | 4 ++-- docs/arch/vendors.md | 16 ++++++++++++---- docs/framework.md | 4 ++-- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/arch/config-reference.md b/docs/arch/config-reference.md index b82ac42..4f9f6bb 100644 --- a/docs/arch/config-reference.md +++ b/docs/arch/config-reference.md @@ -139,9 +139,9 @@ flowchart TD | 字段 | 类型 | 默认值 | | ------------------------- | ------------ | ----------------------------------------------- | -| `status_codes` | list[int] | `[429, 403, 503, 500]` | +| `status_codes` | list[int] | `[429, 403, 503, 500, 529]` | | `error_types` | list[str] | `["rate_limit_error", "overloaded_error", "api_error"]` | -| `error_message_patterns` | list[str] | `["quota", "limit exceeded", "usage cap", "capacity"]` | +| `error_message_patterns` | list[str] | `["quota", "limit exceeded", "usage cap", "capacity", "internal network failure"]` | --- diff --git a/docs/arch/design-patterns.md b/docs/arch/design-patterns.md index 1187a0b..ac8ec8f 100644 --- a/docs/arch/design-patterns.md +++ b/docs/arch/design-patterns.md @@ -67,7 +67,6 @@ classDiagram } class NativeAnthropicVendor { - <> _prepare_request() 模型映射+API Key map_model() 委托ModelMapper _normalize_error_response() 401归一化 diff --git a/docs/arch/routing.md b/docs/arch/routing.md index 7f396fe..ad90664 100644 --- a/docs/arch/routing.md +++ b/docs/arch/routing.md @@ -2,7 +2,7 @@ > **路径约定**:本文档中模块路径均相对于 `src/coding/proxy/`。 > -> **定位**:从 `framework.md` 提取,详述 N-tier 链式路由核心的 13 个子模块。 +> **定位**:从 `framework.md` 提取,详述 N-tier 链式路由核心的 12 个子模块。 [TOC] @@ -10,7 +10,7 @@ ## 1. 模块总览 -路由模块正交分解为 13 个子模块,每个子模块职责单一: +路由模块正交分解为 12 个子模块,每个子模块职责单一: | 子模块 | 文件 | 职责 | | ------------------- | ------------------------------------------------------------------ | ------------------------------------------- | diff --git a/docs/arch/vendors.md b/docs/arch/vendors.md index f6936d6..39fef86 100644 --- a/docs/arch/vendors.md +++ b/docs/arch/vendors.md @@ -57,9 +57,8 @@ classDiagram } class NativeAnthropicVendor { - <> - +_vendor_name: str - +_display_name: str + _vendor_name: str 子类覆写 + _display_name: str 子类覆写 +_prepare_request(body, headers) tuple +send_message(body, headers) VendorResponse +send_message_stream(body, headers) AsyncIterator @@ -327,6 +326,15 @@ GitHub token → Copilot token 交换管理: - **诊断**: 维护 `CopilotExchangeDiagnostics` 记录最近一次交换详情 - **热更新**: `update_github_token()` 支持运行时重认证后 token 替换 +### GoogleOAuthTokenManager + +文件: [vendors/antigravity.py](../../src/coding/proxy/vendors/antigravity.py)(内嵌) + +Google OAuth2 refresh_token → access_token 刷新管理: + +- 继承 `BaseTokenManager`,实现 `_acquire()` 通过 Google OAuth2 token endpoint 刷新 access_token +- 内嵌于 `antigravity.py` 而非独立文件,因仅 AntigravityVendor 使用 + ### CopilotModelResolver 文件: [vendors/copilot_models.py](../../src/coding/proxy/vendors/copilot_models.py) @@ -391,6 +399,6 @@ class ExampleVendor(NativeAnthropicVendor): 1. **创建子类** — 在 [vendors/](../../src/coding/proxy/vendors/) 目录下新建文件,继承 `BaseVendor` 2. **实现抽象方法** — `get_name()` 和 `_prepare_request()` -3. **覆写钩子方法** — 按需覆写 `map_model()`、`get_capabilities()`、`get_compatibility_profile()`、`_get_endpoint()` 等 +3. **覆写可扩展方法** — 按需覆写 `map_model()`、`get_capabilities()`、`_get_endpoint()` 等;如需声明非默认兼容性画像则覆写 `get_compatibility_profile()` 4. **如需 token 管理** — 组合 `TokenBackendMixin`,实现 `BaseTokenManager` 子类 5. **后续步骤** — 同 Path A 的 2-5 步 diff --git a/docs/framework.md b/docs/framework.md index 4902e3a..a048bc6 100644 --- a/docs/framework.md +++ b/docs/framework.md @@ -306,9 +306,9 @@ flowchart TD | 层级 | 条件 | 默认值 | | ----------- | ------------------------------------------ | ------------------------------------------------------- | -| HTTP 状态码 | `status_code in failover.status_codes` | `[429, 403, 503, 500]` | +| HTTP 状态码 | `status_code in failover.status_codes` | `[429, 403, 503, 500, 529]` | | 错误类型 | `error.type in failover.error_types` | `["rate_limit_error", "overloaded_error", "api_error"]` | -| 错误消息 | `pattern in error.message`(不区分大小写) | `["quota", "limit exceeded", "usage cap", "capacity"]` | +| 错误消息 | `pattern in error.message`(不区分大小写) | `["quota", "limit exceeded", "usage cap", "capacity", "internal network failure"]` | **特殊规则**:对于 429 和 503 状态码,即使无法解析响应体(body),也会强制触发故障转移。 From 2c9319aeb04fd18052949fd4fbf11c4f5394acd0 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 23:27:35 +0800 Subject: [PATCH 21/32] =?UTF-8?q?docs(user-guide):=20=E6=AD=A3=E4=BA=A4?= =?UTF-8?q?=E5=88=86=E8=A7=A3=E7=94=A8=E6=88=B7=E6=8C=87=E5=8D=97=E4=B8=BA?= =?UTF-8?q?=E6=9E=A2=E7=BA=BD+=E4=B8=93=E9=A2=98=E5=AD=90=E6=96=87?= =?UTF-8?q?=E6=A1=A3=EF=BC=8C=E6=A0=A1=E5=87=86=E5=85=A8=E9=83=A8=E8=AF=AD?= =?UTF-8?q?=E4=B9=89=E5=81=8F=E5=B7=AE;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 1772 行单体 user-guide.md 正交分解为枢纽文档(~254 行) + 6 个专题子文档: - guide/vendors.md: 供应商配置(覆盖全部 9 种供应商,含新增 minimax/alibaba/xiaomi/kimi/doubao) - guide/cli-reference.md: CLI 命令参考(补充 --week/-w, --month/-m, --total/-t, --vendor/-v) - guide/api-reference.md: HTTP API 端点(补充 Dashboard 端点、count_tokens 501、reset body) - guide/dashboard.md: Dashboard 看板(全新文档,此前未记录) - guide/quickstart.md: 快速上手(合并原 §2 + §6) - guide/monitoring.md: 监控·运维·排查(合并原 §7 + §8 + §9) 语义修正: 默认 tiers 顺序(zhipu-first)、zhipu 已有 circuit_breaker 不再是终端层、 copilot enabled 默认为 true、新增 5 种 NativeAnthropicVendor 文档; 配置详解章节委托给 arch/config-reference.md 消除重复; 枢纽文档 -85.7%(1772→254),总文档 -17.2%(1772→1467),供应商覆盖 +125%(4→9); 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- docs/guide/api-reference.md | 356 +++++++ docs/guide/cli-reference.md | 237 +++++ docs/guide/dashboard.md | 63 ++ docs/guide/monitoring.md | 207 ++++ docs/guide/quickstart.md | 103 ++ docs/guide/vendors.md | 247 +++++ docs/user-guide.md | 1769 +++-------------------------------- 7 files changed, 1339 insertions(+), 1643 deletions(-) create mode 100644 docs/guide/api-reference.md create mode 100644 docs/guide/cli-reference.md create mode 100644 docs/guide/dashboard.md create mode 100644 docs/guide/monitoring.md create mode 100644 docs/guide/quickstart.md create mode 100644 docs/guide/vendors.md diff --git a/docs/guide/api-reference.md b/docs/guide/api-reference.md new file mode 100644 index 0000000..f943491 --- /dev/null +++ b/docs/guide/api-reference.md @@ -0,0 +1,356 @@ +# HTTP API 端点 + +
+📑 目录(点击展开) + +- [1. HEAD / 和 GET /](#1-head--和-get-) +- [2. POST /v1/messages](#2-post-v1messages) + - [2.1 请求格式](#21-请求格式) + - [2.2 非流式响应](#22-非流式响应) + - [2.3 流式响应(SSE)](#23-流式响应sse) + - [2.4 错误响应](#24-错误响应) + - [2.5 请求规范化行为](#25-请求规范化行为) +- [3. POST /v1/messages/count_tokens](#3-post-v1messagescount_tokens) +- [4. GET /health](#4-get-health) +- [5. GET /api/status](#5-get-apistatus) +- [6. POST /api/reset](#6-post-apireset) +- [7. GET /api/copilot/diagnostics](#7-get-apicopilotdiagnostics) +- [8. GET /api/copilot/models](#8-get-apicopilotmodels) +- [9. GET /api/reauth/status](#9-get-apireauthstatus) +- [10. POST /api/reauth/{provider}](#10-post-apireauthprovider) +- [11. Dashboard 端点](#11-dashboard-端点) + +
+ +## 1. HEAD / 和 GET / + +根路径连通性探针。Claude Code 在建立连接前发送 `HEAD /` 作为健康检查,代理返回 HTTP 200 空响应。 + +```bash +curl -I http://127.0.0.1:8046/ +# HTTP/1.1 200 OK +``` + +## 2. POST /v1/messages + +代理 Anthropic Messages API,支持流式(SSE)与非流式请求。请求经过规范化处理后,路由至配置的 vendor tier 链;若当前 tier 不可用或返回可恢复错误,自动故障转移至下一 tier。 + +### 2.1 请求格式 + +**请求头** + +| 请求头 | 必填 | 说明 | +|--------|------|------| +| `Content-Type` | ✓ | 固定为 `application/json` | +| `Authorization` | ✗ | 格式 `Bearer `;对 Anthropic vendor 透传,对其他 vendor 由代理内部凭证管理 | +| `anthropic-version` | ✗ | Anthropic API 版本,建议传 `2023-06-01`;透传至上游 | +| `anthropic-beta` | ✗ | Beta 功能标识,透传至上游 | + +> `hop-by-hop` 头(如 `Connection`、`Transfer-Encoding`)会在转发前自动过滤。 + +**请求体参数** + +| 字段 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------| +| `model` | string | ✓ | 非空 | 目标模型标识。经 [`model_mapping`](./vendors.md#5-model_mapping--模型映射规则) 规则映射后路由至实际 vendor 模型 | +| `messages` | array | ✓ | 至少 1 条;`user`/`assistant` 交替;末尾必须为 `user` | 对话历史 | +| `max_tokens` | integer | ✗ | > 0 | 最大输出 token 数 | +| `stream` | boolean | ✗ | 默认 `false` | 是否以 SSE 流式返回 | +| `temperature` | number | ✗ | `[0, 2]` | 采样温度 | +| `top_p` | number | ✗ | `(0, 1]` | Top-p 采样 | +| `top_k` | integer | ✗ | ≥ 1 | Top-k 采样 | +| `stop_sequences` | array[string] | ✗ | | 提前停止的字符串序列 | +| `system` | string \| array | ✗ | | 系统提示词 | +| `tools` | array | ✗ | | 工具定义 | +| `tool_choice` | object | ✗ | | 工具选择策略 | +| `thinking` | object | ✗ | 需 `budget_tokens`;部分 vendor 不支持 | Extended Thinking 配置 | +| `metadata` | object | ✗ | | 用户元数据,透传至上游 | + +**消息 content block 类型** + +| 类型 | 适用角色 | 必填字段 | 说明 | +|------|---------|---------|------| +| `text` | `user`/`assistant` | `text` | 纯文本 | +| `image` | `user` | `source` | 图片;部分 vendor 不支持 | +| `tool_use` | `assistant` | `id`(`toolu_` 前缀)、`name`、`input` | 模型发起工具调用 | +| `tool_result` | `user` | `tool_use_id`、`content` | 工具调用结果 | +| `thinking` | `assistant` | `thinking`、`signature` | Extended Thinking;跨 vendor 时自动剥离 | + +### 2.2 非流式响应 + +**成功响应(HTTP 200)** + +```json +{ + "id": "msg_01XFDUDYJgAACzvnptvVoYEL", + "type": "message", + "role": "assistant", + "content": [ + { "type": "text", "text": "你好!我是 Claude。" } + ], + "model": "claude-sonnet-4-6", + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 14, + "output_tokens": 32, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0 + } +} +``` + +**`stop_reason` 枚举** + +| 值 | 含义 | +|----|------| +| `end_turn` | 模型自然输出完毕 | +| `tool_use` | 模型发起工具调用 | +| `stop_sequence` | 触发了停止序列 | +| `max_tokens` | 达到 `max_tokens` 上限 | + +### 2.3 流式响应(SSE) + +设置 `"stream": true`,响应以 `text/event-stream` 格式逐块下发。 + +**SSE 事件类型** + +| 事件类型 | 说明 | +|---------|------| +| `message_start` | 消息开始,包含初始元数据 | +| `content_block_start` | 新的 content block 开始 | +| `content_block_delta` | 增量数据(`text_delta` 或 `input_json_delta`) | +| `content_block_stop` | 当前 content block 结束 | +| `message_delta` | 消息级增量(`stop_reason` + `usage`) | +| `message_stop` | 消息结束 | +| `ping` | 心跳 | +| `error` | 流式错误 | + +> 流式模式下,一旦 SSE 流开始发送,代理不再进行 tier 级别的故障转移。若中途出现错误,以 `event: error` 事件通知客户端。 + +### 2.4 错误响应 + +**错误结构** + +```json +{ + "error": { + "type": "invalid_request_error", + "message": "详细错误描述", + "details": ["原因1", "原因2"] + } +} +``` + +**HTTP 状态码对照** + +| HTTP 状态码 | `error.type` | 触发场景 | 可重试 | +|------------|-------------|---------|--------| +| `400` | `invalid_request_error` | 请求格式不合规、无兼容 vendor | ✗ | +| `401` | `authentication_error` | 无有效认证凭证 | ✗ | +| `403` | `permission_error` | 权限不足 | ✗ | +| `429` | `rate_limit_error` | 所有 vendor 均触发速率限制 | ✓ | +| `500` | `api_error` | 代理内部异常 | ✓ | +| `502` | `api_error` | 所有 vendor 均不可达 | ✓ | +| `503` | `authentication_error` | Token 获取失败 | ✓ | +| `501` | `not_implemented` | 请求的端点无可用 vendor 处理 | ✗ | + +### 2.5 请求规范化行为 + +代理在转发前自动进行规范化,对调用方透明。 + +**自动修复(静默处理)** + +| 问题 | 处理方式 | +|------|---------| +| `tool_use_id` 格式不符(非 `toolu_` 前缀) | 自动重写为合规格式 | +| `tool_result` 出现在 `assistant` 消息中 | 剥离该 block(首次触发 WARNING 日志) | +| `tool_use` 缺少合法 ID | 自动生成新 ID | + +**致命验证错误(返回 HTTP 400)** + +| 场景 | 错误示例 | +|------|---------| +| `tool_use` block 缺少 `id` 字段 | `"tool_use block is missing 'id' field"` | +| `tool_result` block 缺少 `tool_use_id` 字段 | `"tool_result block is missing 'tool_use_id' field"` | +| 消息角色不交替 | `"messages must alternate between user and assistant"` | +| `messages` 末尾不是 `user` 消息 | `"last message must be from user"` | + +**Thinking Block 跨 Vendor 处理**:请求路由至非 Anthropic vendor 时,assistant 历史消息中的 `thinking` block 会被自动剥离(包含仅 Anthropic 可验证的 `signature`)。不影响当前轮次的 `thinking` 功能配置。 + +## 3. POST /v1/messages/count_tokens + +Token 计数 API 透传。支持所有提供 Anthropic 兼容端点的供应商。 + +```bash +curl -X POST http://127.0.0.1:8046/v1/messages/count_tokens \ + -H "Content-Type: application/json" \ + -H "anthropic-version: 2023-06-01" \ + -d '{"model":"claude-sonnet-4-6","messages":[{"role":"user","content":"Hello"}]}' +``` + +| 响应码 | 说明 | +|--------|------| +| `200` | 成功,返回 token 计数结果 | +| `501` | 无可用 vendor 处理此端点 | +| `502` | 上游 API 不可达 | + +## 4. GET /health + +健康检查。 + +```bash +curl http://127.0.0.1:8046/health +# {"status":"ok"} +``` + +## 5. GET /api/status + +查询所有层级的熔断器、配额守卫、周级配额守卫、Rate Limit 及诊断信息。 + +```bash +curl http://127.0.0.1:8046/api/status +``` + +**返回示例**: + +```json +{ + "tiers": [ + { + "name": "zhipu", + "circuit_breaker": { + "state": "closed", + "failure_count": 0, + "current_recovery_seconds": 30 + }, + "quota_guard": { + "state": "within_quota", + "window_usage_tokens": 452000000, + "budget_tokens": 1000000000, + "usage_percent": 45.2 + }, + "rate_limit": { + "is_rate_limited": false, + "remaining_seconds": 0 + } + }, + { + "name": "anthropic", + "circuit_breaker": { + "state": "closed", + "failure_count": 0 + } + } + ] +} +``` + +## 6. POST /api/reset + +重置所有层级的弹性设施。支持可选 JSON body 进行运行时 tier 重排序。 + +```bash +# 仅重置(向后兼容) +curl -X POST http://127.0.0.1:8046/api/reset + +# 重置 + 提升 anthropic 到最高优先级 +curl -X POST http://127.0.0.1:8046/api/reset \ + -H "Content-Type: application/json" \ + -d '{"vendors": ["anthropic"]}' + +# 重置 + 替换整条链路顺序 +curl -X POST http://127.0.0.1:8046/api/reset \ + -H "Content-Type: application/json" \ + -d '{"vendors": ["zhipu", "anthropic", "copilot"]}' +``` + +**重排序语义**: +- 单个 vendor:提升到最高优先级,其余保持相对顺序 +- 多个 vendor:替换整个 N-tier 链路顺序 + +**重置范围**:circuit_breaker(→ CLOSED)、quota_guard(→ WITHIN_QUOTA)、weekly_quota_guard(→ WITHIN_QUOTA)、rate_limit deadline(→ 清除)。 + +## 7. GET /api/copilot/diagnostics + +返回 Copilot 认证与交换链路的脱敏诊断信息。 + +```bash +curl http://127.0.0.1:8046/api/copilot/diagnostics +``` + +若 Copilot 供应商未启用,返回 404。 + +## 8. GET /api/copilot/models + +按需探测当前 Copilot 会话可见的模型列表。 + +```bash +curl http://127.0.0.1:8046/api/copilot/models +``` + +需要有效的 Copilot 凭证;凭证无效时返回 503。 + +## 9. GET /api/reauth/status + +查询运行时重认证状态。 + +```bash +curl http://127.0.0.1:8046/api/reauth/status +``` + +## 10. POST /api/reauth/{provider} + +手动触发指定 provider 的运行时重认证。 + +```bash +curl -X POST http://127.0.0.1:8046/api/reauth/github +# HTTP/1.1 202 Accepted +# {"status":"reauth requested"} +``` + +| 参数 | 说明 | +|------|------| +| `{provider}` | provider 名称:`github` / `google` | + +返回 202 表示重认证请求已接收,用户需在浏览器中完成授权。 + +## 11. Dashboard 端点 + +为 [Dashboard 看板](./dashboard.md)提供数据的 API 端点。 + +### 11.1 GET /dashboard + +返回 Dashboard HTML 页面。 + +```bash +curl http://127.0.0.1:8046/dashboard +``` + +### 11.2 GET /api/dashboard/summary + +返回 Dashboard 汇总数据(今日 + 所选区间)。 + +```bash +curl "http://127.0.0.1:8046/api/dashboard/summary?days=7" +``` + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `days` | int | `7` | 统计天数(1~90) | + +**返回结构**:`version`(版本号)、`today`(今日 KPI)、`range`(区间 KPI)、`failover_stats`(故障转移统计)。 + +### 11.3 GET /api/dashboard/timeline + +返回按天分组的时序数据(用于图表绘制)。 + +```bash +curl "http://127.0.0.1:8046/api/dashboard/timeline?days=30" +``` + +| 参数 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `days` | int | `7` | 统计天数(1~90) | + +**返回结构**:`period`(`"day"`)、`count`(天数)、`rows`(按天分组的用量数组)。 diff --git a/docs/guide/cli-reference.md b/docs/guide/cli-reference.md new file mode 100644 index 0000000..3c268d9 --- /dev/null +++ b/docs/guide/cli-reference.md @@ -0,0 +1,237 @@ +# CLI 命令参考 + +
+📑 目录(点击展开) + +- [1. coding-proxy start](#1-coding-proxy-start) +- [2. coding-proxy status](#2-coding-proxy-status) +- [3. coding-proxy usage](#3-coding-proxy-usage) +- [4. coding-proxy reset](#4-coding-proxy-reset) +- [5. coding-proxy auth login](#5-coding-proxy-auth-login) +- [6. coding-proxy auth status](#6-coding-proxy-auth-status) +- [7. coding-proxy auth reauth](#7-coding-proxy-auth-reauth) +- [8. coding-proxy auth logout](#8-coding-proxy-auth-logout) + +
+ +## 1. coding-proxy start + +启动代理服务。 + +```bash +coding-proxy start [OPTIONS] +``` + +| 参数 | 缩写 | 说明 | +|------|------|------| +| `--config` | `-c` | 配置文件路径 | +| `--port` | `-p` | 监听端口(覆盖配置文件) | +| `--host` | `-h` | 监听地址(覆盖配置文件) | + +**示例**: + +```bash +# 默认配置启动 +coding-proxy start + +# 自定义端口和配置 +coding-proxy start -p 9000 -c ~/my-config.yaml + +# 自定义监听地址和端口 +coding-proxy start --host 0.0.0.0 --port 8046 +``` + +> 若启用了 Copilot 或 Antigravity 供应商但未配置凭证,启动时会自动触发 OAuth 浏览器登录流程。 + +## 2. coding-proxy status + +查看当前代理状态和各供应商层级信息。 + +```bash +coding-proxy status [OPTIONS] +``` + +| 参数 | 缩写 | 说明 | +|------|------|------| +| `--port` | `-p` | 代理服务端口(默认 8046) | + +**输出示例**: + +``` +zhipu + 熔断器: closed 失败=0 + 配额: within_quota 45.2% (452000000/1000000000) + +anthropic + 熔断器: closed 失败=0 +``` + +每个 tier 独立展示名称、熔断器状态和配额守卫状态。 + +**熔断器状态说明**: + +| 状态 | 含义 | +|------|------| +| `closed` | 正常运行 | +| `open` | 熔断中,跳过该层降级到下一层 | +| `half_open` | 恢复测试中 | + +## 3. coding-proxy usage + +查看 Token 使用统计与费用估算。 + +```bash +coding-proxy usage [OPTIONS] +``` + +| 参数 | 缩写 | 说明 | +|------|------|------| +| `--days` | `-d` | 统计天数(默认 7) | +| `--week` | `-w` | 最近第 N 周统计(按周聚合,默认 1) | +| `--month` | `-m` | 最近第 N 月统计(按月聚合,默认 1) | +| `--total` | `-t` | 统计全部历史记录(按供应商+模型聚合) | +| `--vendor` | `-v` | 过滤供应商(支持逗号分隔多选,如 `anthropic,zhipu`) | +| `--model` | — | 过滤实际服务模型(支持逗号分隔多选,如 `glm-5v-turbo,glm-5.1`) | +| `--db` | — | 数据库文件路径 | + +> **时间维度互斥**,优先级:`-t > -m > -w > -d`。 + +**示例**: + +```bash +# 查看最近 7 天统计(默认) +coding-proxy usage + +# 本周统计 +coding-proxy usage -w + +# 本月统计 +coding-proxy usage -m + +# 全部历史,按供应商+模型聚合 +coding-proxy usage -t + +# 最近 30 天,仅 Anthropic 和智谱供应商 +coding-proxy usage -d 30 -v anthropic,zhipu + +# 按实际服务模型过滤 +coding-proxy usage --model glm-5v-turbo,claude-sonnet-4-6 +``` + +**输出字段说明**: + +| 字段 | 说明 | +|------|------| +| 日期 | 统计日期 | +| 供应商 | 处理请求的供应商名称 | +| 请求模型 | 客户端请求的原始模型名称 | +| 实际模型 | 供应商实际使用的模型名称(经映射后) | +| 请求数 | 总请求数 | +| 输入/输出/缓存创建/缓存读取 Token | 各维度 Token 消耗 | +| 总 Token | 所有维度之和 | +| Cost | 基于定价配置计算的费用;未配置定价时显示 `-` | +| 平均耗时(ms) | 平均响应时间 | + +## 4. coding-proxy reset + +手动重置所有层级的熔断器和配额守卫,恢复使用最高优先级供应商。支持运行时重排序 N-tier 链路。 + +```bash +coding-proxy reset [OPTIONS] +``` + +| 参数 | 缩写 | 说明 | +|------|------|------| +| `--port` | `-p` | 代理服务端口(默认 8046) | +| `--vendor` | `-v` | 提升/重排序 vendor 优先级(单个或逗号分隔多个) | + +**重排序语义**: +- 单个 vendor:提升该 vendor 到最高优先级,其余保持相对顺序 + ```bash + # 提升 anthropic 到最高优先级 + coding-proxy reset -v anthropic + ``` +- 多个 vendor:替换整个 N-tier 链路顺序 + ```bash + # 替换整条链路 + coding-proxy reset -v anthropic,zhipu,copilot + ``` + +**重置范围**:所有层级的熔断器状态(→ CLOSED)、配额守卫状态(→ WITHIN_QUOTA)、周级配额守卫状态(→ WITHIN_QUOTA)、Rate Limit 截止时间(→ 清除)。 + +## 5. coding-proxy auth login + +执行 OAuth 浏览器登录,获取供应商访问凭证。 + +```bash +coding-proxy auth login [OPTIONS] +``` + +| 参数 | 缩写 | 说明 | +|------|------|------| +| `--provider` | `-p` | 指定 provider(`github` / `google`);省略则依次登录两者 | + +**示例**: + +```bash +# 仅登录 GitHub(Copilot) +coding-proxy auth login -p github + +# 仅登录 Google(Antigravity) +coding-proxy auth login -p google + +# 依次登录两者 +coding-proxy auth login +``` + +## 6. coding-proxy auth status + +查看已登录的 OAuth 凭证状态。 + +```bash +coding-proxy auth status +``` + +**输出示例**: + +``` +github: 有效 有 refresh_token +google: 已过期 无 refresh_token +``` + +## 7. coding-proxy auth reauth + +触发运行中代理的 OAuth 重认证。 + +```bash +coding-proxy auth reauth PROVIDER [OPTIONS] +``` + +| 参数 | 缩写 | 说明 | +|------|------|------| +| `PROVIDER` | — | provider 名称(必填):`github` / `google` | +| `--port` | `-p` | 代理服务端口(默认 8046) | + +**示例**: + +```bash +# 触发 GitHub 重认证 +coding-proxy auth reauth github + +# 指定端口 +coding-proxy auth reauth google -p 9090 +``` + +> 此命令通过 [`POST /api/reauth/{provider}`](./api-reference.md#510-post-apireauthprovider) 向运行中的代理发送重认证请求,无需重启服务。 + +## 8. coding-proxy auth logout + +清除已存储的 OAuth 凭证。 + +```bash +coding-proxy auth logout [OPTIONS] +``` + +| 参数 | 缩写 | 说明 | +|------|------|------| +| `--provider` | `-p` | 指定 provider;省略则登出所有 provider | diff --git a/docs/guide/dashboard.md b/docs/guide/dashboard.md new file mode 100644 index 0000000..93bb009 --- /dev/null +++ b/docs/guide/dashboard.md @@ -0,0 +1,63 @@ +# Dashboard 看板 + +coding-proxy 内置 Web 可视化看板,提供流量、用量、故障转移等关键指标的实时监控。 + +## 访问 + +启动代理后,浏览器访问: + +``` +http://127.0.0.1:8046/dashboard +``` + +## 功能概览 + +### KPI 卡片 + +顶部展示核心指标: + +| 卡片 | 说明 | +|------|------| +| 今日请求 | 当日总请求数 | +| 今日 Token | 当日总 Token 消耗(输入 + 输出 + 缓存) | +| 今日费用 | 基于定价配置的费用估算 | +| 故障转移次数 | 所选时间范围内的故障转移事件数 | +| 平均耗时 | 请求平均响应时间 | +| 区间请求 | 所选时间范围的总请求数 | + +### 图表 + +| 图表 | 说明 | +|------|------| +| 供应商状态 | 各供应商实时状态(熔断器、配额守卫) | +| 请求时间线 | 按天的请求量趋势图 | +| 供应商分布 | 各供应商请求占比甜甜圈图 | +| Token 时间线(按供应商) | 各供应商按天的 Token 消耗堆叠图 | +| Token 时间线(按供应商+模型) | 细粒度的模型级 Token 消耗堆叠图 | + +### 时间范围选择器 + +页面右上角提供时间范围选择: + +- **7 天**(默认) +- **30 天** +- **自定义天数**(1~90 天) + +### 自动刷新 + +看板每 **10 分钟**自动刷新数据。也可点击右上角「刷新」按钮手动刷新。 + +### 图表交互 + +- **单击**图例项:隔离显示该系列 +- **Ctrl+单击**图例项:多选显示 +- **Shift+单击**图例项:排除该系列 + +## 数据源 + +看板数据来自以下 API 端点,详见 [API 参考 — Dashboard 端点](./api-reference.md#59-dashboard-端点): + +| 端点 | 说明 | +|------|------| +| `GET /api/dashboard/summary` | KPI 汇总数据 | +| `GET /api/dashboard/timeline` | 按天分组的时间线数据 | diff --git a/docs/guide/monitoring.md b/docs/guide/monitoring.md new file mode 100644 index 0000000..7437cc6 --- /dev/null +++ b/docs/guide/monitoring.md @@ -0,0 +1,207 @@ +# 监控·运维·排查 + +
+📑 目录(点击展开) + +- [1. 日志查看](#1-日志查看) +- [2. 用量统计](#2-用量统计) +- [3. 健康检查](#3-健康检查) +- [4. Dashboard 监控](#4-dashboard-监控) +- [5. 数据库维护](#5-数据库维护) +- [6. 性能调优参考](#6-性能调优参考) +- [7. 常见使用场景](#7-常见使用场景) +- [8. 故障排查](#8-故障排查) + +
+ +## 1. 日志查看 + +代理日志默认输出到控制台,包含以下关键事件: + +| 事件 | 日志级别 | 示例 | +|------|---------|------| +| 熔断器状态转换 | INFO/WARNING | `Circuit breaker: CLOSED → OPEN (3 consecutive failures)` | +| 故障转移触发 | WARNING | `Primary error 429, failing over` | +| 恢复成功 | INFO | `Circuit breaker: HALF_OPEN → CLOSED (recovered)` | +| Rate Limit 生效 | INFO | `Tier zhipu: rate limit deadline active, 30.0s remaining` | +| 自动登录 | INFO | `Copilot 层缺少有效凭证,启动 GitHub OAuth 登录...` | + +配置调整: + +```yaml +logging: + level: "DEBUG" # 查看详细的模型映射和路由决策 + file: "coding-proxy.log" # 输出到文件 + max_bytes: 5242880 # 单文件 5 MB,触发轮转 + backup_count: 5 # 保留 5 个 gzip 压缩备份 +``` + +## 2. 用量统计 + +```bash +# 最近 7 天(默认) +coding-proxy usage + +# 本周统计 +coding-proxy usage -w + +# 本月统计 +coding-proxy usage -m + +# 全部历史 +coding-proxy usage -t + +# 过滤供应商(逗号分隔多选) +coding-proxy usage -v anthropic,zhipu + +# 过滤模型 +coding-proxy usage --model glm-5v-turbo + +# 指定数据库 +coding-proxy usage --db /path/to/usage.db +``` + +> 完整 CLI 选项参见 [CLI 参考 — usage](./cli-reference.md#3-coding-proxy-usage)。 + +## 3. 健康检查 + +```bash +# 基础检查 +curl http://127.0.0.1:8046/health + +# 详细状态(所有层级的熔断器、配额守卫、Rate Limit、诊断信息) +curl http://127.0.0.1:8046/api/status +``` + +> 端点详情参见 [API 参考](./api-reference.md)。 + +## 4. Dashboard 监控 + +浏览器访问 `http://127.0.0.1:8046/dashboard` 查看 Web 可视化看板。详见 [Dashboard 文档](./dashboard.md)。 + +## 5. 数据库维护 + +用量数据库位于 `~/.coding-proxy/usage.db`(可通过配置修改)。 + +- 采用 SQLite WAL 模式,支持读写并发 +- 当前版本不自动清理历史数据 +- 如需清理,可直接删除数据库文件(重启后自动重建) + +## 6. 性能调优参考 + +| 参数 | 默认值 | 稳定优先 | 敏感快速 | 说明 | +|------|--------|---------|---------|------| +| `timeout_ms` | 300000 | `300000` | `120000` | 长对话保持 5 分钟;短查询可缩短至 2 分钟 | +| `failure_threshold` | 3 | `5` | `2` | 网络稳定环境降低以更快触发降级 | +| `recovery_timeout_seconds` | 300 | `600` | `120` | 给供应商更多恢复时间 vs 更快尝试恢复 | +| `token_budget` | 按计划 | 按计划设定 | — | 设为订阅额度的 95%~99% | +| `window_hours` (quota_guard) | 5.0 | `8.0` | `3.0` | 长窗口更平滑,短窗口更灵敏 | +| `max_retries` | 2 | `3` | `1` | 网络不稳定时增加重试 | + +> 完整弹性参数表参见 [配置字段参考 — 弹性字段](../arch/config-reference.md#5-vendorconfig-弹性字段)。 + +## 7. 常见使用场景 + +### 7.1 上游 API 限流自动降级 + +**现象**:Claude Code 响应变慢或提示 "rate limited" + +**代理行为**:检测到上游返回 `429` → 解析 `retry-after` → 设置 Rate Limit 截止时间 → 熔断器记录失败 → 自动降级到下一供应商 → 恢复后自动切回。 + +**用户操作**:无需干预。通过 [`GET /api/status`](./api-reference.md#5-get-apistatus) 中的 `rate_limit` 字段查看限速状态。 + +### 7.2 配额耗尽后自动降级 + +**现象**:上游供应商返回 `403` 错误,消息含 "usage cap" 或 "quota" + +**代理行为**:识别关键词 → 配额守卫标记 QUOTA_EXCEEDED → 后续请求自动路由到下一层级。 + +**用户操作**:无需干预。通过 `coding-proxy usage` 查看各供应商请求分布。 + +### 7.3 手动恢复使用主供应商 + +```bash +coding-proxy reset + +# 同时提升指定供应商优先级 +coding-proxy reset -v anthropic +``` + +### 7.4 禁用特定供应商 + +在 `vendors` 列表中设置 `enabled: false`,或通过 [`tiers`](./vendors.md#4-tiers--降级链路优先级) 从降级链中排除。 + +### 7.5 运行时 OAuth 重认证 + +```bash +# CLI +coding-proxy auth reauth github + +# API +curl -X POST http://127.0.0.1:8046/api/reauth/github +``` + +重认证请求发出后(HTTP 202),在浏览器中完成授权即可,无需重启。 + +## 8. 故障排查 + +### 8.1 代理服务无法启动 + +**端口占用**: + +```bash +lsof -i :8046 +coding-proxy start --port 8080 +``` + +**配置文件语法错误**:检查 YAML 缩进、冒号后空格。 + +**Python 版本**:`python --version`(需要 >= 3.12) + +### 8.2 Claude Code 无法连接代理 + +1. 确认代理正在运行:`coding-proxy status` +2. 确认环境变量:`echo $ANTHROPIC_BASE_URL`(应为 `http://127.0.0.1:8046`) +3. 确认端口一致 + +### 8.3 频繁触发故障转移 + +1. 检查上游 API 状态 +2. 查看 `GET /api/status` 中的 `rate_limit` 信息 +3. 适当调高 `failure_threshold`(如 3 → 5) +4. 适当调高 `recovery_timeout_seconds` + +### 8.4 供应商返回错误(通用) + +适用于所有原生 Anthropic 兼容供应商(zhipu、minimax、alibaba、xiaomi、kimi、doubao): + +1. **API Key 错误**:确认对应环境变量已正确设置 +2. **模型不存在**:检查 [`model_mapping`](./vendors.md#5-model_mapping--模型映射规则) 中的 `target` 是否有效 +3. **网络问题**:确认可以访问对应供应商的 `base_url` + +### 8.5 Copilot 认证问题 + +**现象**:GitHub Device Flow 显示 "Congratulations, you're all set!" 但请求仍失败。 + +```bash +# 查看诊断信息 +curl http://127.0.0.1:8046/api/copilot/diagnostics + +# 探查可用模型 +curl http://127.0.0.1:8046/api/copilot/models + +# 重认证 +coding-proxy auth reauth github +``` + +### 8.6 Token 用量不记录 + +1. 确认数据库目录可写:`ls -la ~/.coding-proxy/` +2. 目录不存在时代理会自动创建 +3. 流式请求的用量提取依赖 SSE 事件格式,非标准格式可能无法正确解析 + +### 8.7 count_tokens 请求失败 + +**返回 501**:无可用 vendor 处理此端点。确认至少有一个 Anthropic 兼容供应商已启用。 + +**返回 502**:上游 API 不可达。此端点直接透传,不经过故障转移链。 diff --git a/docs/guide/quickstart.md b/docs/guide/quickstart.md new file mode 100644 index 0000000..1acf989 --- /dev/null +++ b/docs/guide/quickstart.md @@ -0,0 +1,103 @@ +# 快速开始 + +## 1. 环境要求 + +- **Python** >= 3.12 +- **UV** 包管理器(推荐)或 pip +- **API Key**:至少一个供应商的 API Key(如 [智谱](https://open.bigmodel.cn) 的 `ZHIPU_API_KEY`) +- **Claude Code** 已安装并可用 + +## 2. 安装 + +```bash +# 方式一:使用 UV(推荐) +uv sync + +# 方式二:使用 pip +pip install -e . +``` + +安装完成后,`coding-proxy` 命令即可使用。 + +## 3. 最小配置 + +```bash +# 复制配置模板到项目根目录(模板已内置完整默认值,仅需覆盖密钥) +cp config.default.yaml config.yaml +``` + +设置智谱 API Key(默认 Tier 0 供应商): + +```bash +export ZHIPU_API_KEY="your-api-key-here" +``` + +配置文件中使用 `${ZHIPU_API_KEY}` 引用,代理启动时自动替换。 + +> **安全最佳实践**: +> - API Key 优先使用 `${ENV_VAR}` 环境变量引用,避免明文写入配置文件 +> - `config.yaml` 已在 `.gitignore` 中,不会被提交到版本库 +> - OAuth Token 存储于 `~/.coding-proxy/tokens.json`,建议 `chmod 600` 限制访问 +> - 若设置 `server.host: "0.0.0.0"` 接受外部连接,确保在可信网络环境中运行 + +## 4. 启动服务 + +```bash +# 使用默认配置启动 +coding-proxy start + +# 指定端口 +coding-proxy start --port 8080 + +# 指定配置文件 +coding-proxy start --config /path/to/config.yaml +``` + +启动成功后输出: + +``` +INFO: Started server process [75773] +INFO: Waiting for application startup. +INFO: Application startup complete. +INFO: Uvicorn running on http://127.0.0.1:8046 (Press CTRL+C to quit) +``` + +> 若启用了 Copilot 或 Antigravity 供应商但未配置凭证,启动时会自动触发 OAuth 浏览器登录。 + +## 5. 验证服务 + +```bash +# 健康检查 +curl http://127.0.0.1:8046/health +# 期望返回: {"status":"ok"} + +# 查看代理状态 +coding-proxy status +``` + +## 6. 配置 Claude Code + +将 Claude Code 的 API 端点指向 coding-proxy: + +```bash +export ANTHROPIC_BASE_URL=http://127.0.0.1:8046 +``` + +Claude Code 使用的 OAuth token 会被代理透传到 Anthropic API,无需额外配置认证信息。 + +### 验证集成 + +1. 确保 coding-proxy 正在运行:`coding-proxy status` +2. 使用 Claude Code 发送一条消息 +3. 查看 coding-proxy 的终端日志,确认请求经过代理 +4. 使用 `coding-proxy usage` 查看是否有新的用量记录 + +### 日常使用流程 + +1. **启动代理**:`coding-proxy start`(可使用 `tmux` 后台运行) +2. **OAuth 认证**(如启用 Copilot/Antigravity):启动时自动检查凭证,缺失则触发浏览器登录 +3. **正常使用 Claude Code**:代理在后台透明工作 +4. **定期查看用量**:[`coding-proxy usage`](./cli-reference.md#3-coding-proxy-usage) +5. **按需手动干预**:[`coding-proxy reset`](./cli-reference.md#4-coding-proxy-reset) 强制切回最高优先级供应商 +6. **运行时重认证**:[`coding-proxy auth reauth`](./cli-reference.md#7-coding-proxy-auth-reauth) 无需重启即可刷新凭证 +7. **查看可视化看板**:浏览器访问 `http://127.0.0.1:8046/dashboard` diff --git a/docs/guide/vendors.md b/docs/guide/vendors.md new file mode 100644 index 0000000..1b51c5f --- /dev/null +++ b/docs/guide/vendors.md @@ -0,0 +1,247 @@ +# 供应商配置 + +
+📑 目录(点击展开) + +- [1. 供应商分类](#1-供应商分类) +- [2. 通用字段](#2-通用字段) +- [3. 供应商配置详情](#3-供应商配置详情) + - [3.1 anthropic — Anthropic Claude](#31-anthropic--anthropic-claude) + - [3.2 copilot — GitHub Copilot](#32-copilot--github-copilot) + - [3.3 antigravity — Google Antigravity](#33-antigravity--google-antigravity) + - [3.4 zhipu — 智谱 GLM](#34-zhipu--智谱-glm) + - [3.5 minimax — MiniMax](#35-minimax--minimax) + - [3.6 alibaba — 阿里 Qwen](#36-alibaba--阿里-qwen) + - [3.7 xiaomi — 小米 MiMo](#37-xiaomi--小米-mimo) + - [3.8 kimi — Kimi](#38-kimi--kimi) + - [3.9 doubao — 豆包 Doubao](#39-doubao--豆包-doubao) +- [4. tiers — 降级链路优先级](#4-tiers--降级链路优先级) +- [5. model_mapping — 模型映射规则](#5-model_mapping--模型映射规则) +- [6. pricing — 模型定价](#6-pricing--模型定价) + +
+ +## 1. 供应商分类 + +coding-proxy 支持三类供应商,共 9 种: + +| 类别 | 供应商 | 说明 | +|------|--------|------| +| **直连 Anthropic** | `anthropic` | 直接透传请求到 Anthropic API | +| **协议转换** | `copilot`、`antigravity` | 内部完成认证交换与格式转换(Anthropic ↔ Gemini) | +| **原生 Anthropic 兼容** | `zhipu`、`minimax`、`alibaba`、`xiaomi`、`kimi`、`doubao` | 提供原生 Anthropic 兼容端点,仅需 `api_key` + `base_url` | + +> 类层次结构与设计细节参见 [架构文档 — 供应商模块](../arch/vendors.md)。 + +## 2. 通用字段 + +所有供应商共享以下字段。完整参数表参见 [配置字段参考 — 通用字段](../arch/config-reference.md#4-vendorconfig-通用字段)。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `vendor` | string | — | 供应商类型标识 | +| `enabled` | bool | `true` | 是否启用 | +| `base_url` | string | `""` | API 基础 URL;留空使用供应商默认值 | +| `timeout_ms` | int | `300000` | 请求超时(毫秒) | + +弹性设施字段(`circuit_breaker`、`quota_guard`、`weekly_quota_guard`、`retry`)参见 [配置字段参考 — 弹性字段](../arch/config-reference.md#5-vendorconfig-弹性字段)。 + +## 3. 供应商配置详情 + +### 3.1 anthropic — Anthropic Claude + +直连 Anthropic API,无额外配置字段。OAuth token 由 Claude Code 透传。 + +```yaml +- vendor: anthropic + base_url: "https://api.anthropic.com" + timeout_ms: 300000 + circuit_breaker: + failure_threshold: 3 + recovery_timeout_seconds: 300 + success_threshold: 2 + quota_guard: + enabled: false + token_budget: 65000000 + window_hours: 5.0 +``` + +### 3.2 copilot — GitHub Copilot + +通过 GitHub Copilot 内部 API 调用 Claude 模型。需 OAuth 登录或手动配置 token。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `github_token` | string | `""` | GitHub OAuth token / PAT,支持 `${ENV_VAR}` | +| `account_type` | string | `"individual"` | 账号类型:`individual` / `business` / `enterprise` | +| `token_url` | string | `"https://api.github.com/copilot_internal/v2/token"` | Token 交换端点 | +| `base_url` | string | `""` | 留空时按 `account_type` 自动解析 | +| `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL(秒) | + +> 默认已启用(`enabled: true`)。首次启动时若缺少有效凭证,自动触发 GitHub Device Flow 浏览器登录。 +> 可通过 [`GET /api/copilot/diagnostics`](./api-reference.md#57-get-apicopilotdiagnostics) 和 [`GET /api/copilot/models`](./api-reference.md#58-get-apicopilotmodels) 排查认证状态。 + +### 3.3 antigravity — Google Antigravity + +通过 Google Generative Language API 调用 Claude / Gemini 模型。代理自动处理 Anthropic ↔ Gemini 格式双向转换。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `client_id` | string | `""` | Google OAuth2 Client ID,支持 `${ENV_VAR}` | +| `client_secret` | string | `""` | Google OAuth2 Client Secret,支持 `${ENV_VAR}` | +| `refresh_token` | string | `""` | Google OAuth2 Refresh Token,支持 `${ENV_VAR}` | +| `base_url` | string | `"https://generativelanguage.googleapis.com/v1beta"` | Gemini API 基础地址 | +| `model_endpoint` | string | `"models/claude-sonnet-4-20250514"` | 模型端点路径(仅作为未命中映射时的默认模型) | +| `safety_settings` | dict or null | `null` | Gemini API 安全设置键值对(如 `{"HARASSMENT": "block_none"}`) | + +> 默认禁用(`enabled: false`)。启用需配置 OAuth 凭据,启动时自动触发 Google OAuth 登录。access_token 过期时优先静默刷新,无需重新登录。 + +### 3.4 zhipu — 智谱 GLM + +通过智谱 GLM 官方 Anthropic 兼容端点调用模型。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `api_key` | string | `""` | 智谱 API Key,支持 `${ENV_VAR}` | +| `base_url` | string | `"https://open.bigmodel.cn/api/anthropic"` | API 基础地址 | + +> 默认已启用(`enabled: true`),且配置了 `circuit_breaker`(`recovery_timeout_seconds: 30`)和 `quota_guard`(`enabled: true`),属于中间层参与故障转移。默认作为 `tiers` 链路中的最高优先级(Tier 0)。 + +### 3.5 minimax — MiniMax + +通过 MiniMax 原生 Anthropic 兼容端点调用模型。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `api_key` | string | `""` | MiniMax API Key,支持 `${ENV_VAR}`(`${MINIMAX_API_KEY}`) | +| `base_url` | string | `"https://api.minimaxi.com/anthropic"` | API 基础地址 | + +> 默认禁用(`enabled: false`)。默认模型映射:`minimax-m2.7`。 + +### 3.6 alibaba — 阿里 Qwen + +通过阿里云 DashScope Anthropic 兼容端点调用 Qwen 模型。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `api_key` | string | `""` | 阿里 API Key,支持 `${ENV_VAR}`(`${ALIBABA_API_KEY}`) | +| `base_url` | string | `"https://coding-intl.dashscope.aliyuncs.com/apps/anthropic"` | API 基础地址 | + +> 默认禁用(`enabled: false`)。默认模型映射:`qwen3.6-plus`。 + +### 3.7 xiaomi — 小米 MiMo + +通过小米 Anthropic 兼容端点调用 MiMo 模型。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `api_key` | string | `""` | 小米 API Key,支持 `${ENV_VAR}`(`${XIAOMI_API_KEY}`) | +| `base_url` | string | `"https://token-plan-cn.xiaomimimo.com/anthropic"` | API 基础地址 | + +> 默认禁用(`enabled: false`)。默认模型映射:`mimo-v2-pro`。 + +### 3.8 kimi — Kimi + +通过 Kimi Anthropic 兼容端点调用模型。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `api_key` | string | `""` | Kimi API Key,支持 `${ENV_VAR}`(`${KIMI_API_KEY}`) | +| `base_url` | string | `"https://api.kimi.com/coding/"` | API 基础地址 | + +> 默认禁用(`enabled: false`)。默认模型映射:`kimi-k2.5`。 + +### 3.9 doubao — 豆包 Doubao + +通过字节跳动 Volcengine Anthropic 兼容端点调用模型。 + +| 字段 | 类型 | 默认值 | 说明 | +|------|------|--------|------| +| `api_key` | string | `""` | Volcengine API Key,支持 `${ENV_VAR}`(`${ARK_API_KEY}`) | +| `base_url` | string | `"https://ark.cn-beijing.volces.com/api/coding"` | API 基础地址 | + +> 默认禁用(`enabled: false`)。三档模型映射:`claude-opus-*` → `doubao-seed-2.0-code`,`claude-sonnet-*` → `doubao-seed-2.0-pro`,`claude-haiku-*` → `doubao-seed-2.0-lite`。 + +## 4. tiers — 降级链路优先级 + +可选字段,显式指定故障转移时的供应商尝试顺序。 + +```yaml +tiers: ["zhipu", "anthropic", "copilot", "antigravity"] +``` + +**规则**: +- 未配置时回退到 `vendors` 列表原始顺序 +- 引用的 vendor 名称必须在 `vendors` 中定义且 `enabled=true` +- 可用于在不改变 `vendors` 定义顺序的情况下灵活调整降级策略 + +**示例**: + +| 场景 | 配置 | 效果 | +|------|------|------| +| 默认链路 | `["zhipu", "anthropic", "copilot", "antigravity"]` | 智谱首选,Anthropic 作后备 | +| Anthropic 首选 | `["anthropic", "zhipu"]` | 仅保留首尾两级 | +| 全部启用 | `["zhipu", "anthropic", "copilot", "minimax", "antigravity"]` | 五层降级 | + +> **终端层**:未配置 `circuit_breaker` 的 vendor 自动成为终端层(始终接受请求,不触发向下故障转移)。`config.default.yaml` 中所有已启用 vendor 均配置了 `circuit_breaker`,因此默认无终端层;若需设置终端层,移除对应 vendor 的 `circuit_breaker` 配置即可。 +> +> **故障转移触发条件**:详见 [配置字段参考 — FailoverConfig](../arch/config-reference.md#54-failoverconfig--故障转移参数)。 + +## 5. model_mapping — 模型映射规则 + +将 Claude 模型名自动转换为各供应商对应的实际模型名。完整规则列表参见 [`config.default.yaml`](../../config.default.yaml)。 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `pattern` | string | 匹配模式(精确匹配或正则) | +| `vendors` | list[str] | 规则作用的供应商范围 | +| `target` | string | 目标模型名称 | +| `is_regex` | bool | 是否为正则表达式(默认 `false`) | + +**匹配优先级**:同一供应商内精确匹配 > 正则匹配(按规则顺序) > 供应商默认值。 + +**典型配置**: + +```yaml +model_mapping: + # GitHub Copilot + - pattern: "claude-sonnet-.*" + vendors: ["copilot"] + target: "claude-sonnet-4.6" + is_regex: true + # 智谱 GLM + - pattern: "claude-sonnet-.*" + vendors: ["zhipu"] + target: "glm-5v-turbo" + is_regex: true + # 豆包 Doubao(三档模型) + - pattern: "claude-opus-.*" + vendors: ["doubao"] + target: "doubao-seed-2.0-code" + is_regex: true + - pattern: "claude-sonnet-.*" + vendors: ["doubao"] + target: "doubao-seed-2.0-pro" + is_regex: true + - pattern: "claude-haiku-.*" + vendors: ["doubao"] + target: "doubao-seed-2.0-lite" + is_regex: true +``` + +> **兼容规则**:未设置 `vendors` 的历史规则默认只作用于原生 Anthropic 兼容供应商,避免映射误套。 + +## 6. pricing — 模型定价 + +按 `(vendor, model)` 配置四维定价,用于 [`coding-proxy usage`](./cli-reference.md#43-coding-proxy-usage) 的费用统计展示。完整定价表参见 [`config.default.yaml`](../../config.default.yaml)。 + +| 字段 | 类型 | 说明 | +|------|------|------| +| `vendor` | string | 供应商名称 | +| `model` | string | 实际模型名 | +| `input_cost_per_mtok` | price | 输入 Token 单价(支持 `$` USD / `¥` CNY) | +| `output_cost_per_mtok` | price | 输出 Token 单价 | +| `cache_write_cost_per_mtok` | price | 缓存创建 Token 单价 | +| `cache_read_cost_per_mtok` | price | 缓存读取 Token 单价 | + +> **币种规则**:同一模型的所有价格必须使用相同币种。未配置定价的模型在 `usage` 统计中 Cost 列显示 `-`。 diff --git a/docs/user-guide.md b/docs/user-guide.md index fa2836f..7a5e73f 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -1,4 +1,4 @@ -# coding-proxy 用户操作指引 +# coding-proxy 用户指引
📑 目录(点击展开) @@ -7,32 +7,18 @@ - [1.1 什么是 coding-proxy](#11-什么是-coding-proxy) - [1.2 工作原理](#12-工作原理) - [1.3 请求生命周期](#13-请求生命周期) -- [2. 快速开始](#2-快速开始) - - [2.1 环境要求](#21-环境要求) - - [2.2 安装](#22-安装) - - [2.3 最小配置](#23-最小配置) - - [2.4 启动服务](#24-启动服务) - - [2.5 验证服务](#25-验证服务) - - [2.6 配置 Claude Code](#26-配置-claude-code) -- [3. 配置详解](#3-配置详解) - - [3.1 配置文件位置与加载优先级](#31-配置文件位置与加载优先级) - - [3.2 vendors — 供应商定义](#32-vendors-供应商定义) - - [3.3 tiers — 降级链路优先级](#33-tiers-降级链路优先级) - - [3.4 failover — 故障转移触发条件](#34-failover-故障转移触发条件) - - [3.5 model_mapping — 模型映射规则](#35-model_mapping-模型映射规则) - - [3.6 pricing — 模型定价](#36-pricing-模型定价) - - [3.7 auth — OAuth 登录配置](#37-auth-oauth-登录配置) - - [3.8 server / database / logging](#38-server-database-logging-基础设施配置) - - [3.9 环境变量引用](#39-环境变量引用) - - [3.10 旧 flat 格式兼容说明(已废弃)](#310-旧-flat-格式兼容说明已废弃) -- [4. CLI 命令参考](#4-cli-命令参考) -- [5. HTTP API 端点](#5-http-api-端点) -- [6. Claude Code 集成指南](#6-claude-code-集成指南) -- [7. 监控与运维](#7-监控与运维) -- [8. 常见使用场景](#8-常见使用场景) -- [9. 故障排查](#9-故障排查) -- [附录 A:术语对照表](#附录-a术语对照表) -- [附录 B:完整配置参考](#附录-b完整配置参考) +- [2. 文档导航](#2-文档导航) +- [3. 快速上手入门](#3-快速上手入门) +- [4. 配置概览](#4-配置概览) + - [4.1 配置文件位置与加载优先级](#41-配置文件位置与加载优先级) + - [4.2 vendors — 供应商列表](#42-vendors--供应商列表) + - [4.3 tiers — 降级链路优先级](#43-tiers--降级链路优先级) + - [4.4 环境变量引用](#44-环境变量引用) + - [4.5 auth — OAuth 登录配置](#45-auth--oauth-登录配置) + - [4.6 server / database / logging](#46-server--database--logging) + - [4.7 旧 flat 格式兼容说明(已废弃)](#47-旧-flat-格式兼容说明已废弃) +- [5. 日常操作速查](#5-日常操作速查) +- [附录:术语对照表](#附录术语对照表)
@@ -42,12 +28,14 @@ coding-proxy 是一个面向 Claude Code 的多**供应商(vendor)**智能代理服务。它在 Claude Code 和 API 供应商之间充当透明代理,具备以下核心能力: -- **N-tier 自动故障转移(failover)**:支持多层供应商链式降级(Anthropic → Copilot → Antigravity → 智谱 GLM),恢复后自动切回 +- **N-tier 自动故障转移(failover)**:支持多层供应商链式降级(默认链路:智谱 → Anthropic → Copilot → Antigravity),恢复后自动切回 +- **9 种供应商支持**:Anthropic Claude、GitHub Copilot、Google Antigravity、智谱 GLM、MiniMax、阿里 Qwen、小米 MiMo、Kimi、豆包 Doubao - **模型名称映射**:自动将 Claude 模型名转换为各供应商对应的实际模型名 - **格式双向转换**:自动转换 Anthropic ↔ Gemini 格式,支持非 Anthropic 兼容供应商 -- **Token 用量追踪与定价统计**:记录每次请求的 Token 消耗(含缓存 Token)、供应商选择、响应时间等指标;支持按 (vendor, model) 配置四维定价($ / ¥) -- **弹性设施保护**:每层供应商独立配备熔断器(Circuit Breaker)、滑动窗口配额守卫(Quota Guard)(支持小时级与周级双窗口)、Rate Limit 精确截止控制 +- **Token 用量追踪与定价统计**:记录每次请求的 Token 消耗、供应商选择、响应时间等指标;支持按 (vendor, model) 配置四维定价($ / ¥) +- **弹性设施保护**:每层供应商独立配备熔断器(Circuit Breaker)、滑动窗口配额守卫(Quota Guard)(支持日级与周级双窗口)、Rate Limit 精确截止控制 - **OAuth 认证管理**:内置 GitHub Device Flow 与 Google OAuth 登录流程,支持运行时重认证与凭证自动刷新 +- **Web 可视化看板**:内置 Dashboard 提供流量、用量、故障转移等指标的实时监控 ### 1.2 工作原理 @@ -64,10 +52,10 @@ graph TD subgraph Tiers["N-tier 降级链路"] direction LR - T0["Tier 0: Anthropic
中间层"] - T1["Tier 1: Copilot
中间层"] - T2["Tier 2: Antigravity
中间层"] - T3["Tier 3: 智谱 GLM
终端层"] + T0["Tier 0: 智谱 GLM
中间层"] + T1["Tier 1: Anthropic
中间层"] + T2["Tier 2: Copilot
中间层"] + T3["Tier 3: Antigravity
中间层"] end CC -->|"POST /v1/messages"| Router @@ -82,1690 +70,185 @@ graph TD style T0 fill:#1a5276,color:#fff style T1 fill:#1a5276,color:#fff style T2 fill:#1a5276,color:#fff - style T3 fill:#7b241c,color:#fff + style T3 fill:#1a5276,color:#fff ``` -正常情况下,coding-proxy 将请求透传到 **Tier 0(Anthropic API)**。当检测到限流、配额耗尽或服务过载等错误时,按优先级链自动降级到下一层供应商。每层独立配备熔断器和配额守卫——**未配置 `circuit_breaker` 的 vendor 自动成为终端层**(如智谱 GLM),始终接受请求且不触发进一步故障转移。供应商恢复后,代理会自动尝试切回更高优先级的层级。整个过程对用户透明,无需手动干预。 +正常情况下,coding-proxy 将请求透传到 **Tier 0(默认为智谱 GLM)**。当检测到限流、配额耗尽或服务过载等错误时,按优先级链自动降级到下一层供应商。每层独立配备熔断器和配额守卫——**未配置 `circuit_breaker` 的 vendor 自动成为终端层**,始终接受请求且不触发进一步故障转移。供应商恢复后,代理会自动尝试切回更高优先级的层级。整个过程对用户透明。 + +> `tiers` 链路可通过配置自定义,不限于上图所示的 4 层。详见 [供应商配置 — tiers](./guide/vendors.md#4-tiers--降级链路优先级)。 ### 1.3 请求生命周期 -```mermaid -flowchart TD - A["接收请求
POST /v1/messages"] --> B["normalize_anthropic_request()
请求规范化"] - B --> C["_RouteExecutor.execute()"] - C --> D{"遍历 Tier 链"} - D --> E{"能力门控
can_serve_model()"} - E -->|"能力不兼容"| F["跳过 → 下一 Tier"] - F --> D - E -->|"通过能力检查"| G{"三层恢复门控
can_execute_with_health_check()"} - G -->|"Rate Limit 截止中"| H["跳过 → 下一 Tier"] - H --> D - G -->|"CB/QG/WQG 拒绝"| I["跳过 → 下一 Tier"] - I --> D - G -->|"通过所有门控"| J["vendor.send_message()
发送请求"] - J -->|"成功"| K["record_success()
记录用量 & 定价"] - K --> L["返回响应给 Claude Code"] - J -->|"失败"| M{"错误分类"} - M -->|"语义拒绝 400"| N["静默降级 → 下一 Tier"] - N --> D - M -->|"可故障转移"| O["record_failure()
+ Rate Limit 解析"] - O --> G - M -->|"最后一层 / 不可转移"| P["返回原始错误"] - - style A fill:#2c3e50,color:#fff - style L fill:#27ae60,color:#fff - style P fill:#e74c3c,color:#fff - style D fill:#f39c12,color:#000 -``` +每个请求经过 **规范化 → 遍历 Tier 链 → 能力门控 → 三层恢复门控(Rate Limit / 熔断器 / 配额守卫)→ 发送请求 → 错误分类** 的完整链路。 -每个请求经过 **规范化 → 遍历 Tier 链 → 能力门控 → 三层恢复门控(Rate Limit / 熔断器 / 配额守卫)→ 发送请求 → 错误分类** 的完整链路。三层恢复门控确保在供应商不稳定时快速跳过,避免无效等待;错误分类决定是触发故障转移、静默降级还是直接返回错误给客户端。 +> 详细的请求生命周期流程图参见 [架构文档 — 请求路由](./arch/routing.md)。 --- -## 2. 快速开始 +## 2. 文档导航 + +| 文档 | 说明 | +|------|------| +| **[快速开始](./guide/quickstart.md)** | 环境要求、安装、最小配置、启动服务、Claude Code 集成 | +| **[供应商配置](./guide/vendors.md)** | 全部 9 种供应商配置详情、模型映射、定价 | +| **[CLI 命令参考](./guide/cli-reference.md)** | start / status / usage / reset / auth 全部命令 | +| **[HTTP API 端点](./guide/api-reference.md)** | /v1/messages、health、status、reset、copilot、reauth、dashboard | +| **[Dashboard 看板](./guide/dashboard.md)** | Web 可视化看板功能与操作 | +| **[监控·运维·排查](./guide/monitoring.md)** | 日志、用量统计、性能调优、常见场景、故障排查 | +| [配置字段参考](./arch/config-reference.md) | 所有配置参数的完整字段定义(Single Source of Truth) | +| [架构设计文档](./arch/design-patterns.md) | 设计模式、熔断器状态机、配额守卫等架构细节 | +| [供应商模块文档](./arch/vendors.md) | Vendor 类层次结构与实现细节 | +| [请求路由文档](./arch/routing.md) | 路由引擎工作原理 | -### 2.1 环境要求 +--- -- **Python** >= 3.12 -- **UV** 包管理器(推荐)或 pip -- **智谱 API Key**:从 [open.bigmodel.cn](https://open.bigmodel.cn) 获取 -- **Claude Code** 已安装并可用 +## 3. 快速上手入门 -### 2.2 安装 +> 详细步骤参见 [快速开始](./guide/quickstart.md)。 ```bash -# 方式一:使用 UV(推荐) +# 1. 安装 uv sync -# 方式二:使用 pip -pip install -e . -``` - -安装完成后,`coding-proxy` 命令即可使用。 - -### 2.3 最小配置 - -```bash -# 复制配置模板到项目根目录(模板已内置完整默认值,仅需覆盖密钥) -cp config.default.yaml config.yaml -``` - -设置智谱 API Key(二选一): - -**方式一:环境变量(推荐)** - -```bash +# 2. 配置(仅需设置 API Key) export ZHIPU_API_KEY="your-api-key-here" -``` - -配置文件中使用 `${ZHIPU_API_KEY}` 引用,代理启动时自动替换。 - -**方式二:直接写入配置文件** - -编辑 `config.yaml`,在 `vendors` 列表中找到 `vendor: zhipu` 条目,将 `api_key` 设为实际的 API Key: - -```yaml -vendors: - # ... 其他供应商 ... - - vendor: zhipu - api_key: "your-api-key-here" -``` - -> **安全提示**:`config.yaml` 已在 `.gitignore` 中,不会被提交到版本库。推荐使用环境变量方式避免密钥泄露。 -> -> **安全最佳实践**: -> - **API Key 存储**:优先使用 `${ENV_VAR}` 环境变量引用,避免将明文密钥写入配置文件 -> - **OAuth Token 保护**:`~/.coding-proxy/tokens.json` 存储 OAuth 凭证,建议设置文件权限 `chmod 600` 限制访问 -> - **网络暴露**:若设置 `server.host: "0.0.0.0"` 接受外部连接,确保在可信网络环境中运行或配合防火墙使用 -> - **密钥透传**:代理不存储 `ANTHROPIC_API_KEY`,仅透传至上游 API;建议定期轮换密钥 - -### 2.4 启动服务 +cp config.default.yaml config.yaml -```bash -# 使用默认配置启动 +# 3. 启动 coding-proxy start -# 指定端口 -coding-proxy start --port 8080 - -# 指定配置文件 -coding-proxy start --config /path/to/config.yaml - -# 自定义监听地址和端口 -coding-proxy start --host 0.0.0.0 --port 8046 -``` - -启动成功后会看到类似输出: - -```bash -INFO: Started server process [75773] -INFO: Waiting for application startup. -INFO: Application startup complete. -INFO: Uvicorn running on http://127.0.0.1:8046 (Press CTRL+C to quit) -``` - -> **注意**:若启用了 Copilot 或 Antigravity 供应商但未配置凭证,启动时会自动触发 OAuth 浏览器登录流程(参见 [§4.5](#45-coding-proxy-auth-login))。 - -### 2.5 验证服务 +# 4. 配置 Claude Code +export ANTHROPIC_BASE_URL=http://127.0.0.1:8046 -```bash -# 健康检查 +# 5. 验证 curl http://127.0.0.1:8046/health -# 期望返回: {"status":"ok"} - -# 查看代理状态 -coding-proxy status -``` - -### 2.6 配置 Claude Code - -将 Claude Code 的 API 端点指向 coding-proxy: - -```bash -export ANTHROPIC_BASE_URL=http://127.0.0.1:8046 ``` -设置后,Claude Code 发出的所有 API 请求将经过 coding-proxy 代理。 - --- -## 3. 配置详解 +## 4. 配置概览 -### 3.1 配置文件位置与加载优先级 +### 4.1 配置文件位置与加载优先级 -配置文件按以下优先级加载(找到第一个即停止): +按以下优先级加载(找到第一个即停止): 1. `--config` 参数指定的路径(最高优先级) 2. `./config.yaml`(项目根目录) 3. `~/.coding-proxy/config.yaml`(用户主目录) 4. 内置默认值(无需配置文件也可启动) -加载器会以 `config.default.yaml` 为基础模板进行深度合并,用户配置中的字段覆盖模板默认值。 - -### 3.2 vendors — 供应商定义 - -`vendors` 是配置的核心部分,以列表形式定义所有供应商及其弹性设施。每个 vendor 通过 `vendor` 字段指定类型:`anthropic` | `copilot` | `antigravity` | `zhipu`。 - -**优先级规则**: -- 若配置了 [`tiers`](#33-tiers--降级链路优先级),以其指定的顺序为准 -- 否则 `vendors` 列表顺序即为优先级(index 越小越优先) -- 无 `circuit_breaker` 的 vendor 自动成为终端层(不再向下故障转移) - -#### 完整配置示例 - -```yaml -# === 供应商定义(vendors 列表) === -vendors: - # Vendor 0: Anthropic Claude(最高优先级) - - vendor: anthropic - base_url: "https://api.anthropic.com" - timeout_ms: 300000 # 5 分钟 - circuit_breaker: # 有此字段 = 中间层(参与故障转移) - failure_threshold: 3 - recovery_timeout_seconds: 300 - success_threshold: 2 - quota_guard: # 小时级滑动窗口配额守卫 - enabled: true - token_budget: 45000000 - window_hours: 5.0 - threshold_percent: 99.0 - probe_interval_seconds: 300 - weekly_quota_guard: # 周级滑动窗口配额守卫 - enabled: true - token_budget: 250000000 - window_hours: 168.0 # 7 天滑动窗口 - threshold_percent: 99.0 - probe_interval_seconds: 1800 - - # Vendor 1: GitHub Copilot(中间层,默认禁用) - - vendor: copilot - enabled: false # 启用需 OAuth 登录或手动配置 github_token - github_token: "${GITHUB_TOKEN}" - account_type: "individual" # individual / business / enterprise - token_url: "https://api.github.com/copilot_internal/v2/token" - base_url: "" # 留空时按 account_type 自动解析 - timeout_ms: 300000 - models_cache_ttl_seconds: 300 # 模型列表缓存 TTL(秒) - circuit_breaker: - failure_threshold: 3 - recovery_timeout_seconds: 300 - success_threshold: 2 - quota_guard: - enabled: false - token_budget: 0 - window_hours: 24.0 - threshold_percent: 95.0 - probe_interval_seconds: 300 - - # Vendor 2: Google Antigravity(中间层,默认禁用) - - vendor: antigravity - enabled: false # 启用需配置 OAuth 凭据 - client_id: "${GOOG_CLIENT_ID}" - client_secret: "${GOOG_CLIENT_SECRET}" - refresh_token: "${GOOG_REFRESH_TOKEN}" - base_url: "https://generativelanguage.googleapis.com/v1beta" - model_endpoint: "models/claude-sonnet-4-20250514" - timeout_ms: 300000 - circuit_breaker: - failure_threshold: 3 - recovery_timeout_seconds: 300 - success_threshold: 2 - quota_guard: - enabled: false - token_budget: 0 - window_hours: 24.0 - threshold_percent: 95.0 - probe_interval_seconds: 300 - - # Vendor 3: 智谱 GLM(终端兜底,无 circuit_breaker) - - vendor: zhipu - base_url: "https://open.bigmodel.cn/api/anthropic" - api_key: "${ZHIPU_API_KEY}" - timeout_ms: 3000000 # 50 分钟 - # 不配置 circuit_breaker → 自动成为终端层,不触发向下故障转移 -``` - -#### 3.2.1 通用字段(所有供应商共用) - -| 字段 | 类型 | 默认值 | 说明 | -| ------------ | ------ | -------- | ----------------------------------------------------------------- | -| `vendor` | string | — | 供应商类型标识:`anthropic` / `copilot` / `antigravity` / `zhipu` | -| `enabled` | bool | `true` | 是否启用此供应商 | -| `base_url` | string | `""` | 后端 API 基础 URL;留空时使用各供应商默认值 | -| `timeout_ms` | int | `300000` | 请求超时时间(毫秒),适用于所有供应商 | - -#### 3.2.2 anthropic — Anthropic 供应商 - -| 字段 | 类型 | 默认值 | 说明 | -| -------------- | ---- | ------ | ---------------------------------- | -| (无专属字段) | — | — | 使用通用字段即可连接 Anthropic API | - -#### 3.2.3 copilot — GitHub Copilot 供应商 - -| 字段 | 类型 | 默认值 | 说明 | -| -------------------------- | ------ | ---------------------------------------------------- | -------------------------------------------------------- | -| `github_token` | string | `""` | GitHub OAuth token / PAT,支持 `${ENV_VAR}` | -| `account_type` | string | `"individual"` | 账号类型:`individual` / `business` / `enterprise` | -| `token_url` | string | `"https://api.github.com/copilot_internal/v2/token"` | Token 交换端点 | -| `base_url` | string | `""` | 留空时按 `account_type` 自动解析;企业网络场景可显式覆盖 | -| `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL(秒) | - -> **说明**:浏览器显示 `Congratulations, you're all set!` 仅表示 GitHub Device Flow 完成,不代表当前会话已经成功交换 Copilot chat token,也不代表 Claude Opus 4.6 已对该账号开放。可通过 [`GET /api/copilot/diagnostics`](#57-get-apicopilotdiagnostics) 与 [`GET /api/copilot/models`](#58-get-apicopilotmodels) 做按需排查。 - -#### 3.2.4 antigravity — Google Antigravity 供应商 - -| 字段 | 类型 | 默认值 | 说明 | -| ----------------- | ------------ | ---------------------------------------------------- | ---------------------------------------------------------------------------------------- | -| `client_id` | string | `""` | Google OAuth2 Client ID,支持 `${ENV_VAR}` | -| `client_secret` | string | `""` | Google OAuth2 Client Secret,支持 `${ENV_VAR}` | -| `refresh_token` | string | `""` | Google OAuth2 Refresh Token,支持 `${ENV_VAR}` | -| `base_url` | string | `"https://generativelanguage.googleapis.com/v1beta"` | Gemini API 基础地址 | -| `model_endpoint` | string | `"models/claude-sonnet-4-20250514"` | 模型端点路径(仅作为未命中映射时的默认模型) | -| `safety_settings` | dict or null | `null` | Gemini API 安全设置键值对(如 `{"HARASSMENT": "block_none"}`);留空使用 Google 默认策略 | - -> **Antigravity 说明**:Antigravity 供应商通过 Google Generative Language API 调用 Claude / Gemini 模型。代理自动处理 Anthropic ↔ Gemini 格式的双向转换,并对 `thinking`、通用 `tools`、搜索类工具与 `metadata` 做兼容适配;无法安全透传的字段会记录到 diagnostics。 - -#### 3.2.5 zhipu — 智谱 GLM 供应商(终端层) +加载器以 `config.default.yaml` 为基础模板进行深度合并,用户配置覆盖模板默认值。 -| 字段 | 类型 | 默认值 | 说明 | -| --------- | ------ | ------ | ------------------------------------ | -| `api_key` | string | `""` | 智谱 API Key,支持 `${ENV_VAR}` 引用 | +### 4.2 vendors — 供应商列表 -> **终端层特性**:zhipu 作为终端兜底供应商,不配置 `circuit_breaker`,因此不参与熔断机制,始终接受请求。当所有上游中间层均不可用时,请求直接路由到此层。 +`vendors` 以列表形式定义所有供应商及其弹性设施。支持 9 种供应商类型: -#### 3.2.6 circuit_breaker — 熔断器 +| 类型 | 类别 | 默认状态 | +|------|------|---------| +| `anthropic` | 直连 Anthropic | 启用 | +| `copilot` | 协议转换(GitHub) | 启用(需 OAuth) | +| `antigravity` | 协议转换(Google) | 禁用 | +| `zhipu` | 原生 Anthropic 兼容 | 启用(Tier 0) | +| `minimax` | 原生 Anthropic 兼容 | 禁用 | +| `alibaba` | 原生 Anthropic 兼容 | 禁用 | +| `xiaomi` | 原生 Anthropic 兼容 | 禁用 | +| `kimi` | 原生 Anthropic 兼容 | 禁用 | +| `doubao` | 原生 Anthropic 兼容 | 禁用 | -| 字段 | 类型 | 默认值 | 说明 | -| -------------------------- | ---- | ------ | -------------------------------------------- | -| `failure_threshold` | int | `3` | 连续失败多少次后触发熔断(切换到下一供应商) | -| `recovery_timeout_seconds` | int | `300` | 熔断后等待多久尝试恢复(秒) | -| `success_threshold` | int | `2` | 恢复测试阶段需要连续成功多少次才关闭熔断 | -| `max_recovery_seconds` | int | `3600` | 指数退避的最大等待时间(秒) | +> 各供应商的专属字段、弹性配置和模型映射详见 [供应商配置](./guide/vendors.md)。所有字段的完整定义参见 [配置字段参考](./arch/config-reference.md)。 -**指数退避机制**:如果恢复测试失败,等待时间会翻倍(300s → 600s → 1200s → ...),直到达到 `max_recovery_seconds` 上限。 +### 4.3 tiers — 降级链路优先级 -```mermaid -stateDiagram-v2 - [*] --> CLOSED - - CLOSED --> OPEN : 连续 failure_threshold 次失败
(如 3 次) - - OPEN --> HALF_OPEN : recovery_timeout 后
(指数退避,上限 max_recovery_seconds) - - HALF_OPEN --> CLOSED : 连续 success_threshold 次成功
(如 2 次) - HALF_OPEN --> OPEN : 任意一次失败
(退避时间翻倍) - - note right of CLOSED - **正常运行** - 接受所有请求到该供应商 - end note - - note right of OPEN - **熔断中** - 快速拒绝请求,跳过该层 - 等待恢复超时后进入探测 - end note - - note right of HALF_OPEN - **探测中** - 允许少量请求作为探针 - 成功则关闭熔断,失败则重新打开 - end note -``` - -#### 3.2.7 quota_guard — 滑动窗口配额守卫(小时级) - -| 字段 | 类型 | 默认值 | 说明 | -| ------------------------ | ----- | ------- | --------------------------------------------- | -| `enabled` | bool | `false` | 是否启用配额守卫 | -| `token_budget` | int | `0` | 滑动窗口内的 Token 预算上限 | -| `window_hours` | float | `5.0` | 滑动窗口大小(小时) | -| `threshold_percent` | float | `99.0` | 触发 QUOTA_EXCEEDED 的用量百分比阈值 | -| `probe_interval_seconds` | int | `300` | QUOTA_EXCEEDED 状态下允许探测请求的间隔(秒) | - -**配额状态说明**: - -| 状态 | 含义 | -| ---------------- | --------------------------------------------- | -| `within_quota` | 用量在预算内,正常使用该层供应商 | -| `quota_exceeded` | 用量超限或检测到 cap 错误,跳过该层降到下一层 | - -**工作机制**: -- 启动时从数据库加载窗口内的历史用量基线 -- 窗口用量达到 `token_budget × threshold_percent%` 时自动触发 QUOTA_EXCEEDED -- 检测到上游 cap 错误(429/403 + "usage cap"/"quota" 等关键词)时立即触发 QUOTA_EXCEEDED -- QUOTA_EXCEEDED 状态下每隔 `probe_interval_seconds` 秒允许一次探测请求,成功则恢复 - -#### 3.2.8 weekly_quota_guard — 周级配额守卫 - -字段结构与 [quota_guard](#327-quota_guard--滑动窗口配额守卫小时级) 完全相同,用于独立管理更长周期的 Token 预算。 - -典型配置(7 天滑动窗口): +可选字段,显式指定故障转移时的供应商尝试顺序。默认值: ```yaml -weekly_quota_guard: - enabled: true - token_budget: 250000000 # 一周 token 预算(根据订阅计划调整) - window_hours: 168.0 # 7 天 = 168 小时 - threshold_percent: 99.0 - probe_interval_seconds: 1800 # 每 30 分钟探测一次 -``` - -> **与 hour-level quota_guard 的关系**:两者独立运行、独立判定。任一守卫进入 EXCEEDED 状态均会导致该层被跳过。适用于同时管理小时级突发限制与周级总量上限的场景。 - -#### 3.2.9 retry — 传输层重试策略 - -| 字段 | 类型 | 默认值 | 说明 | -| -------------------- | ----- | ------ | -------------------------------- | -| `max_retries` | int | `2` | 最大重试次数 | -| `initial_delay_ms` | int | `500` | 首次重试延迟(毫秒) | -| `max_delay_ms` | int | `5000` | 最大重试延迟(毫秒) | -| `backoff_multiplier` | float | `2.0` | 退避倍率(每次重试延迟乘以此值) | -| `jitter` | bool | `true` | 是否添加随机抖动(避免惊群效应) | - -### 3.3 tiers — 降级链路优先级 - -可选字段,显式指定故障转移时的供应商尝试顺序。 - -```yaml -tiers: ["anthropic", "copilot", "antigravity", "zhipu"] -``` - -**规则**: -- 未配置时回退到 `vendors` 列表原始顺序 -- 引用的 vendor 名称必须在上方 `vendors` 中定义且 `enabled=true` -- 可用于在不改变 `vendors` 定义顺序的情况下灵活调整降级策略 - -**示例**: - -| 场景 | 配置 | 效果 | -| ------------ | -------------------------------------------------- | ---------------------------- | -| 完整四层链路 | `["anthropic", "copilot", "antigravity", "zhipu"]` | 默认行为等效 | -| 跳过中间层 | `["anthropic", "zhipu"]` | 仅保留首尾两级 | -| 反转优先级 | `["zhipu", "anthropic"]` | 智谱首选,Anthropic 作为后备 | - -### 3.4 failover — 故障转移触发条件 - -| 字段 | 类型 | 默认值 | 说明 | -| ------------------------ | --------- | ------------------------------------------------------- | -------------------------------------------- | -| `status_codes` | list[int] | `[429, 403, 503, 500]` | 触发故障转移的 HTTP 状态码 | -| `error_types` | list[str] | `["rate_limit_error", "overloaded_error", "api_error"]` | 触发故障转移的 Anthropic 错误类型 | -| `error_message_patterns` | list[str] | `["quota", "limit exceeded", "usage cap", "capacity"]` | 触发故障转移的错误消息关键词(不区分大小写) | - -```mermaid -flowchart TD - REQ["收到上游响应"] --> SC{"HTTP 状态码
in status_codes?"} - SC -->|"是 429/403/503/500"| ET{"error_type
in error_types?"} - SC -->|"否"| OK["正常处理响应"] - ET -->|"是"| MSG{"error_message 匹配
error_message_patterns?"} - ET -->|"否"| OK - MSG -->|"是"| FO["触发故障转移
→ 下一 Tier
record_failure()"] - MSG -->|"否"| SEM{"语义拒绝?
400 + invalid_request_error"} - SEM -->|"是"| SFO["静默降级 → 下一 Tier
(不计入失败数)"] - SEM -->|"否"| OK - - style FO fill:#e74c3c,color:#fff - style SFO fill:#f39c12,color:#000 - style OK fill:#27ae60,color:#fff +tiers: ["zhipu", "anthropic", "copilot", "antigravity"] ``` -### 3.5 model_mapping — 模型映射规则 +> 详见 [供应商配置 — tiers](./guide/vendors.md#4-tiers--降级链路优先级)。 -每条规则包含: +### 4.4 环境变量引用 -| 字段 | 类型 | 说明 | -| ---------- | --------- | -------------------------------------------------------------------------------------------------- | -| `pattern` | string | 匹配模式 | -| `vendors` | list[str] | 规则作用的供应商范围,支持 `antigravity`、`copilot`、`zhipu`;留空时为兼容旧配置,仅作用于 `zhipu` | -| `target` | string | 目标模型名称 | -| `is_regex` | bool | 是否为正则表达式(默认 `false`) | - -**匹配优先级**:同一供应商内精确匹配 > 正则匹配(按规则顺序) > 供应商默认值 - -**典型配置**(基于 `config.default.yaml`): +配置文件中可使用 `${VARIABLE_NAME}` 语法引用环境变量: ```yaml -model_mapping: - # GitHub Copilot 可用模型(通过 /api/copilot/models 诊断获取) - - pattern: "claude-sonnet-.*" - vendors: ["copilot"] - target: "claude-sonnet-4.6" - is_regex: true - - pattern: "claude-opus-.*" - vendors: ["copilot"] - target: "claude-opus-4.6" - is_regex: true - - pattern: "claude-haiku-.*" - vendors: ["copilot"] - target: "claude-haiku-4.5" - is_regex: true - # Google Antigravity 模型映射 - - pattern: "claude-sonnet-.*" - vendors: ["antigravity"] - target: "claude-sonnet-4-6-thinking" - is_regex: true - - pattern: "claude-opus-.*" - vendors: ["antigravity"] - target: "claude-opus-4-6-thinking" - is_regex: true - # 智谱 GLM 映射(官方原生 Anthropic 兼容端点) - - pattern: "claude-sonnet-.*" - vendors: ["zhipu"] - target: "glm-5v-turbo" - is_regex: true - - pattern: "claude-opus-.*" - vendors: ["zhipu"] - target: "glm-5v-turbo" - is_regex: true - - pattern: "claude-haiku-.*" - vendors: ["zhipu"] - target: "glm-4.5-air" - is_regex: true +- vendor: zhipu + api_key: "${ZHIPU_API_KEY}" ``` -> **兼容规则**:未设置 `vendors` 的历史规则默认只作用于 `zhipu`,避免旧的 `glm-*` 映射误套到 Antigravity 或 Copilot。 - -#### 内置默认映射 - -若未配置任何 `model_mapping` 规则,系统使用以下内置默认映射(作用于 zhipu 供应商): - -| pattern | target | 说明 | -| ------------------ | ------------- | ------------------- | -| `claude-sonnet-.*` | `glm-5.1` | Sonnet 系列默认映射 | -| `claude-opus-.*` | `glm-5.1` | Opus 系列默认映射 | -| `claude-haiku-.*` | `glm-4.5-air` | Haiku 系列默认映射 | -| `claude-.*` | `glm-5.1` | 兜底通配规则 | +启动时自动替换。如果环境变量未设置,保留原始文本。 -> 这些默认规则仅在用户未显式配置 `model_mapping` 时生效。一旦配置了自定义规则,默认规则被完全覆盖。 - -### 3.6 pricing — 模型定价 - -按 `(vendor, model)` 配置四维定价,用于 `usage` 命令的费用统计展示。 - -```yaml -pricing: - # ── Anthropic Claude(USD)── - - vendor: anthropic - model: claude-sonnet-4-6 - input_cost_per_mtok: $3.0 # 每百万输入 Token 价格 - output_cost_per_mtok: $15.0 # 每百万输出 Token 价格 - cache_write_cost_per_mtok: $3.75 # 每百万缓存创建 Token 价格 - cache_read_cost_per_mtok: $0.30 # 每百万缓存读取 Token 价格 - # ── 智谱 GLM(CNY / ¥)── - - vendor: zhipu - model: glm-5v-turbo - input_cost_per_mtok: ¥5.00 - output_cost_per_mtok: ¥22.00 - cache_read_cost_per_mtok: ¥1.20 -``` - -**字段说明**: - -| 字段 | 类型 | 说明 | -| --------------------------- | ------ | --------------------------------------------------- | -| `vendor` | string | 供应商名称(对应 usage 统计表的"供应商"列) | -| `model` | string | 实际模型名(对应 usage 统计表的"实际模型"列) | -| `input_cost_per_mtok` | price | 输入 Token 单价(支持 `$` 前缀 USD / `¥` 前缀 CNY) | -| `output_cost_per_mtok` | price | 输出 Token 单价 | -| `cache_write_cost_per_mtok` | price | 缓存创建 Token 单价 | -| `cache_read_cost_per_mtok` | price | 缓存读取 Token 单价 | - -> **币种规则**:同一模型的所有价格必须使用相同币种($ 或 ¥)。不带前缀的纯数字默认视为 USD。未配置定价的模型在 `usage` 统计中 Cost 列显示 `-`。 - -### 3.7 auth — OAuth 登录配置 +### 4.5 auth — OAuth 登录配置 ```yaml auth: token_store_path: "~/.coding-proxy/tokens.json" - # github_client_id: "Iv1.b507a08c87ecfe98" # 可选,默认使用 Copilot VS Code 扩展公开 ID - # google_client_id: "" # 可选,默认使用 Antigravity Enterprise 公开凭据 + # github_client_id: "..." # 可选,默认使用公开 ID + # google_client_id: "" # 可选,默认使用公开凭据 # google_client_secret: "" ``` -| 字段 | 类型 | 默认值 | 说明 | -| ---------------------- | ------ | ------------------------------- | ---------------------------------------------- | -| `token_store_path` | string | `"~/.coding-proxy/tokens.json"` | OAuth 凭证存储路径,支持 `~` 展开 | -| `github_client_id` | string | — | GitHub Device Flow Client ID(可选,有默认值) | -| `google_client_id` | string | — | Google OAuth2 Client ID(可选,有默认值) | -| `google_client_secret` | string | — | Google OAuth2 Client Secret(可选,有默认值) | - -### 3.8 server / database / logging — 基础设施配置 - -#### server — 服务器 - -| 字段 | 类型 | 默认值 | 说明 | -| ------ | ------ | ------------- | ----------------------------------------- | -| `host` | string | `"127.0.0.1"` | 监听地址。设为 `"0.0.0.0"` 可接受外部连接 | -| `port` | int | `8046` | 监听端口 | - -#### database — 数据库 - -| 字段 | 类型 | 默认值 | 说明 | -| -------------------------- | ------ | ----------------------------- | -------------------------------------------------- | -| `path` | string | `"~/.coding-proxy/usage.db"` | SQLite 数据库文件路径,支持 `~` 展开 | -| `compat_state_path` | string | `"~/.coding-proxy/compat.db"` | 兼容性会话状态数据库路径(内部使用,通常无需修改) | -| `compat_state_ttl_seconds` | int | `86400` | 兼容性状态 TTL(秒)(内部使用) | - -#### logging — 日志 - -| 字段 | 类型 | 默认值 | 说明 | -| ------- | -------------- | -------- | ------------------------------------------ | -| `level` | string | `"INFO"` | 日志级别(DEBUG / INFO / WARNING / ERROR) | -| `file` | string or null | `null` | 日志文件路径,`null` 表示输出到控制台 | +> 完整字段定义参见 [配置字段参考 — AuthConfig](./arch/config-reference.md#34-authconfig)。 -### 3.9 环境变量引用 - -配置文件中可使用 `${VARIABLE_NAME}` 语法引用环境变量: +### 4.6 server / database / logging ```yaml -# vendors 列表中引用 -- vendor: zhipu - api_key: "${ZHIPU_API_KEY}" - -# auth 节中引用 -auth: - # ... -``` - -启动时,`${ZHIPU_API_KEY}` 会被替换为环境变量 `ZHIPU_API_KEY` 的值。如果环境变量未设置,保留原始文本 `${ZHIPU_API_KEY}`。 - -### 3.10 旧 flat 格式兼容说明(已废弃) - -以下字段为 **legacy flat 格式**(已废弃,保留仅用于向后兼容迁移): - -`primary`, `copilot`, `antigravity`, `fallback`, `circuit_breaker`, `copilot_circuit_breaker`, `antigravity_circuit_breaker`, `quota_guard`, `copilot_quota_guard`, `antigravity_quota_guard` - -如果配置文件中使用上述旧格式字段(而非 `vendors` 列表),系统会在启动时**自动迁移**至 vendors 格式并输出日志提示: - -``` -检测到旧 flat 格式配置字段,已自动迁移至 vendors 列表格式。建议迁移至 config.default.yaml 中的 vendors 新格式。 -``` - -**建议**:尽快迁移至 `config.default.yaml` 中的 vendors 新格式,以获得最完整的配置能力(如 `weekly_quota_guard`、`retry`、`pricing` 等新功能仅在 vendors 格式中可用)。 - -> **迁移时间线**:旧 flat 格式自动迁移代码将在后续版本中移除。建议在新部署中直接使用 vendors 格式,避免依赖迁移逻辑。 - ---- - -## 4. CLI 命令参考 - -### 4.1 coding-proxy start - -启动代理服务。 - -```bash -coding-proxy start [OPTIONS] -``` - -| 参数 | 缩写 | 说明 | -| ---------- | ---- | ------------------------ | -| `--config` | `-c` | 配置文件路径 | -| `--port` | `-p` | 监听端口(覆盖配置文件) | -| `--host` | `-h` | 监听地址(覆盖配置文件) | - -**示例**: - -```bash -# 默认配置启动 -coding-proxy start - -# 自定义端口和配置 -coding-proxy start -p 9000 -c ~/my-config.yaml -``` - -### 4.2 coding-proxy status - -查看当前代理状态和各供应商层级信息。 - -```bash -coding-proxy status [OPTIONS] -``` - -| 参数 | 缩写 | 说明 | -| -------- | ---- | ------------------------- | -| `--port` | `-p` | 代理服务端口(默认 8046) | - -**输出示例**: - -``` -anthropic - 熔断器: closed 失败=0 - 配额: within_quota 27.8% (12500000/45000000) - -copilot - 熔断器: closed 失败=0 - -zhipu -``` - -每个 tier 独立展示名称、熔断器状态和配额守卫状态。终端层(如 zhipu)无熔断器和配额守卫,仅显示名称。 - -**熔断器状态说明**: - -| 状态 | 含义 | -| ----------- | ------------------------------ | -| `closed` | 正常运行,使用该层供应商 | -| `open` | 熔断中,跳过该层降级到下一层 | -| `half_open` | 恢复测试中,尝试使用该层供应商 | - -### 4.3 coding-proxy usage - -查看 Token 使用统计与费用估算。 - -```bash -coding-proxy usage [OPTIONS] -``` - -| 参数 | 缩写 | 说明 | -| ---------- | ---- | ------------------------------------------------------------ | -| `--days` | `-d` | 统计天数(默认 7) | -| `--vendor` | `-v` | 过滤供应商(`anthropic`、`copilot`、`antigravity`、`zhipu`) | -| `--model` | `-m` | 过滤请求模型(如 `claude-sonnet-4-*`) | -| `--db` | — | 数据库文件路径 | - -**示例**: - -```bash -# 查看最近 7 天统计 -coding-proxy usage - -# 查看最近 30 天 Anthropic 供应商统计 -coding-proxy usage -d 30 -v anthropic - -# 按请求模型过滤 -coding-proxy usage -m claude-sonnet-4-20250514 -``` - -**输出字段说明**: - -| 字段 | 说明 | -| -------------- | -------------------------------------------------------------------------------- | -| 日期 | 统计日期 | -| 供应商 | `anthropic`、`copilot`、`antigravity`、`zhipu` | -| 请求模型 | 客户端请求的原始模型名称 | -| 实际模型 | 供应商实际使用的模型名称(经映射后可能与请求模型不同) | -| 请求数 | 当日总请求数 | -| 输入 Token | 当日总输入 Token 数 | -| 输出 Token | 当日总输出 Token 数 | -| 缓存创建 Token | 当日缓存创建 Token 数 | -| 缓存读取 Token | 当日缓存读取 Token 数 | -| 总 Token | 当日总 Token 数(输入 + 输出 + 缓存创建 + 缓存读取) | -| Cost | 基于 [`pricing`](#36-pricing--模型定价) 配置计算的费用;未配置定价的模型显示 `-` | -| 平均耗时(ms) | 当日请求平均响应时间(毫秒) | - -### 4.4 coding-proxy reset - -手动重置所有层级的熔断器和配额守卫(恢复使用最高优先级供应商)。 - -```bash -coding-proxy reset [OPTIONS] -``` - -| 参数 | 缩写 | 说明 | -| -------- | ---- | ------------------------- | -| `--port` | `-p` | 代理服务端口(默认 8046) | - -**使用场景**:确认上游 API 已恢复正常后,手动强制切回最高优先级供应商,无需等待自动恢复超时。重置范围包括:所有层级的熔断器状态(→ CLOSED)、配额守卫状态(→ WITHIN_QUOTA)、周级配额守卫状态(→ WITHIN_QUOTA)、Rate Limit 截止时间(→ 清除)。 - -### 4.5 coding-proxy auth login - -执行 OAuth 浏览器登录,获取供应商访问凭证。 - -```bash -coding-proxy auth login [OPTIONS] -``` - -| 参数 | 缩写 | 说明 | -| ------------ | ---- | -------------------------------------------------------- | -| `--provider` | `-p` | 指定 provider(`github` / `google`);省略则依次登录两者 | - -**工作流程**: -1. 根据参数启动对应 Provider 的 OAuth Device Flow(GitHub)或 OAuth 授权流程(Google) -2. 浏览器打开授权页面,用户完成登录授权 -3. 获取到的凭证自动保存至 [`auth.token_store_path`](#37-auth--oauth-登录配置) 指定的存储文件 - -**示例**: - -```bash -# 仅登录 GitHub(Copilot) -coding-proxy auth login -p github - -# 仅登录 Google(Antigravity) -coding-proxy auth login -p google - -# 依次登录两者 -coding-proxy auth login -``` - -> **自动登录**:执行 `coding-proxy start` 时,若启用的供应商缺少有效凭证,会自动触发此登录流程(无需手动执行 `auth login`)。 - -### 4.6 coding-proxy auth status - -查看已登录的 OAuth 凭证状态。 - -```bash -coding-proxy auth status -``` - -**输出示例**: - -``` -github: 有效 有 refresh_token -google: 已过期 无 refresh_token -``` - -### 4.7 coding-proxy auth reauth - -触发运行中代理的 OAuth 重认证。 - -```bash -coding-proxy auth reauth PROVIDER [OPTIONS] -``` - -| 参数 | 缩写 | 说明 | -| ---------- | ---- | ------------------------------------------ | -| `PROVIDER` | — | provider 名称(必填):`github` / `google` | -| `--port` | `-p` | 代理服务端口(默认 8046) | - -**示例**: - -```bash -# 触发 GitHub 重认证 -coding-proxy auth reauth github - -# 指定端口 -coding-proxy auth reauth google -p 9090 -``` - -> 此命令通过 [`POST /api/reauth/{provider}`](#510-post-apireauthprovider) 向运行中的代理发送重认证请求,无需重启服务。 - -### 4.8 coding-proxy auth logout - -清除已存储的 OAuth 凭证。 - -```bash -coding-proxy auth logout [OPTIONS] -``` - -| 参数 | 缩写 | 说明 | -| ------------ | ---- | -------------------------------------- | -| `--provider` | `-p` | 指定 provider;省略则登出所有 provider | - ---- - -## 5. HTTP API 端点 - -### 5.1 HEAD / 和 GET / - -根路径连通性探针。Claude Code 在建立连接前发送 `HEAD /` 作为健康检查(health probe),代理返回 HTTP 200 空响应。`GET /` 行为相同。 - -```bash -curl -I http://127.0.0.1:8046/ -# HTTP/1.1 200 OK -``` - -> **背景**:Claude Code 在连接到 `ANTHROPIC_BASE_URL` 时,会先发送 `HEAD /` 探测端点可达性。如果代理未处理此路径,会返回 404,导致连接检查失败。 - -### 5.2 POST /v1/messages - -代理 Anthropic Messages API,支持流式(SSE)与非流式请求。请求经过规范化处理后,路由至配置的 vendor tier 链;若当前 tier 不可用或返回可恢复错误,自动故障转移至下一 tier。 - -#### 5.2.1 请求格式 - -**请求头** - -| 请求头 | 必填 | 说明 | -|--------|------|------| -| `Content-Type` | ✓ | 固定为 `application/json` | -| `Authorization` | ✗ | 格式 `Bearer `;对 Anthropic vendor 透传,对其他 vendor 由代理内部凭证管理 | -| `anthropic-version` | ✗ | Anthropic API 版本,建议传 `2023-06-01`;透传至上游 | -| `anthropic-beta` | ✗ | Beta 功能标识,透传至上游(如 `interleaved-thinking-2025-05-14`) | - -> **注**:`hop-by-hop` 头(如 `Connection`、`Transfer-Encoding`)会在转发前自动过滤。 - -**请求体参数** - -| 字段 | 类型 | 必填 | 约束 | 说明 | -|------|------|------|------|------| -| `model` | string | ✓ | 非空 | 目标模型标识。经 `model_mapping` 规则映射后路由至实际 vendor 模型 | -| `messages` | array | ✓ | 至少 1 条;`user`/`assistant` 交替;末尾必须为 `user` | 对话历史,详见[消息结构](#消息结构) | -| `max_tokens` | integer | ✗ | > 0 | 最大输出 token 数 | -| `stream` | boolean | ✗ | 默认 `false` | 是否以 SSE 流式返回 | -| `temperature` | number | ✗ | `[0, 2]` | 采样温度 | -| `top_p` | number | ✗ | `(0, 1]` | Top-p 采样 | -| `top_k` | integer | ✗ | ≥ 1 | Top-k 采样 | -| `stop_sequences` | array[string] | ✗ | | 提前停止的字符串序列 | -| `system` | string \| array | ✗ | | 系统提示词;可为纯字符串或 content block 数组 | -| `tools` | array | ✗ | | 工具定义;详见 Anthropic 官方文档 | -| `tool_choice` | object | ✗ | | 工具选择策略(`auto`/`any`/`tool`) | -| `thinking` | object | ✗ | 需 `budget_tokens`;部分 vendor 不支持 | Extended Thinking 配置,格式 `{"type":"enabled","budget_tokens":N}` | -| `metadata` | object | ✗ | | 用户元数据(如 `user_id`),透传至上游 | - -**消息结构** - -每条消息的 `content` 字段可为纯字符串或 content block 数组: - -```json -{ - "role": "user", - "content": [ - { "type": "text", "text": "请描述这张图片" }, - { - "type": "image", - "source": { - "type": "base64", - "media_type": "image/png", - "data": "" - } - } - ] -} -``` - -支持的 content block 类型: - -| 类型 | 适用角色 | 必填字段 | 说明 | -|------|---------|---------|------| -| `text` | `user`/`assistant` | `text` | 纯文本 | -| `image` | `user` | `source`(`type`/`media_type`/`data` 或 `url`) | 图片;部分 vendor 不支持 | -| `tool_use` | `assistant` | `id`(`toolu_` 前缀)、`name`、`input` | 模型发起工具调用 | -| `tool_result` | `user` | `tool_use_id`、`content` | 工具调用结果;**只能出现在 `user` 消息中** | -| `thinking` | `assistant` | `thinking`、`signature` | Extended Thinking 内容块;跨 vendor 时会被自动剥离 | - ---- - -#### 5.2.2 非流式请求示例 - -```bash -curl -X POST http://127.0.0.1:8046/v1/messages \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $ANTHROPIC_API_KEY" \ - -H "anthropic-version: 2023-06-01" \ - -d '{ - "model": "claude-sonnet-4-5", - "max_tokens": 1024, - "messages": [ - {"role": "user", "content": "你好,介绍一下你自己"} - ] - }' -``` - -**成功响应(HTTP 200)** - -```json -{ - "id": "msg_01XFDUDYJgAACzvnptvVoYEL", - "type": "message", - "role": "assistant", - "content": [ - { "type": "text", "text": "你好!我是 Claude,一个由 Anthropic 开发的 AI 助手。" } - ], - "model": "claude-sonnet-4-5-20251101", - "stop_reason": "end_turn", - "stop_sequence": null, - "usage": { - "input_tokens": 14, - "output_tokens": 32, - "cache_creation_input_tokens": 0, - "cache_read_input_tokens": 0 - } -} -``` - -**响应字段说明** - -| 字段 | 类型 | 说明 | -|------|------|------| -| `id` | string | 消息唯一 ID,格式 `msg_*` | -| `type` | string | 固定为 `"message"` | -| `role` | string | 固定为 `"assistant"` | -| `content` | array | 响应内容块列表(`text`/`tool_use` 等) | -| `model` | string | 实际处理请求的模型完整 ID | -| `stop_reason` | string | 停止原因,见下表 | -| `stop_sequence` | string \| null | 触发停止的序列字符串;未命中时为 `null` | -| `usage.input_tokens` | integer | 输入消耗的 token 数 | -| `usage.output_tokens` | integer | 输出消耗的 token 数 | -| `usage.cache_creation_input_tokens` | integer | 创建缓存的 token 数(Prompt Cache) | -| `usage.cache_read_input_tokens` | integer | 从缓存命中的 token 数(Prompt Cache) | - -**`stop_reason` 枚举** - -| 值 | 含义 | -|----|------| -| `end_turn` | 模型自然输出完毕 | -| `tool_use` | 模型发起工具调用,等待结果 | -| `stop_sequence` | 触发了请求中指定的停止序列 | -| `max_tokens` | 达到 `max_tokens` 上限 | - ---- - -#### 5.2.3 流式请求示例(SSE 模式) - -在请求体中设置 `"stream": true`,响应将以 `text/event-stream` 格式逐块下发: - -```bash -curl -X POST http://127.0.0.1:8046/v1/messages \ - -H "Content-Type: application/json" \ - -H "Authorization: Bearer $ANTHROPIC_API_KEY" \ - -H "anthropic-version: 2023-06-01" \ - --no-buffer \ - -d '{ - "model": "claude-sonnet-4-5", - "max_tokens": 1024, - "stream": true, - "messages": [ - {"role": "user", "content": "用一句话介绍你自己"} - ] - }' -``` - -**SSE 事件流示例** - -``` -event: message_start -data: {"type":"message_start","message":{"id":"msg_01abc","type":"message","role":"assistant","content":[],"model":"claude-sonnet-4-5-20251101","stop_reason":null,"stop_sequence":null,"usage":{"input_tokens":14,"output_tokens":1,"cache_creation_input_tokens":0,"cache_read_input_tokens":0}}} - -event: content_block_start -data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}} - -event: ping -data: {"type":"ping"} - -event: content_block_delta -data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"我是"}} - -event: content_block_delta -data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":" Claude"}} - -event: content_block_stop -data: {"type":"content_block_stop","index":0} - -event: message_delta -data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":8}} - -event: message_stop -data: {"type":"message_stop"} -``` - -**SSE 事件类型说明** - -| 事件类型 | 说明 | -|---------|------| -| `message_start` | 消息开始,包含初始元数据 | -| `content_block_start` | 新的 content block 开始(每个 block 有独立 `index`) | -| `content_block_delta` | content block 增量;`delta.type` 为 `text_delta` 或 `input_json_delta`(工具调用参数) | -| `content_block_stop` | 当前 content block 结束 | -| `message_delta` | 消息级别的增量更新,包含最终 `stop_reason` 和累计 `usage` | -| `message_stop` | 消息结束,流关闭 | -| `ping` | 心跳事件,客户端可忽略 | -| `error` | 流式处理过程中发生错误(见[错误响应](#错误响应)) | - -> **注**:流式模式下,一旦 SSE 流开始发送,代理不再进行 tier 级别的故障转移。若中途出现错误,会以 `event: error` 事件通知客户端,随后关闭流。 - ---- - -#### 5.2.4 工具调用示例 - -```bash -curl -X POST http://127.0.0.1:8046/v1/messages \ - -H "Content-Type: application/json" \ - -H "anthropic-version: 2023-06-01" \ - -d '{ - "model": "claude-sonnet-4-5", - "max_tokens": 1024, - "tools": [ - { - "name": "get_weather", - "description": "获取指定城市的当前天气", - "input_schema": { - "type": "object", - "properties": { - "city": {"type": "string", "description": "城市名称"} - }, - "required": ["city"] - } - } - ], - "messages": [ - {"role": "user", "content": "北京今天天气怎么样?"} - ] - }' -``` - ---- - - -#### 5.2.5 错误响应 - -**错误响应结构** - -```json -{ - "error": { - "type": "invalid_request_error", - "message": "详细错误描述", - "details": ["原因1", "原因2"] - } -} -``` - -> `details` 字段为可选,仅在 `NoCompatibleVendorError`(无可用 vendor)等特定场景中包含。 - -**HTTP 状态码对照** - -| HTTP 状态码 | `error.type` | 触发场景 | 是否可重试 | -|------------|-------------|---------|-----------| -| `400` | `invalid_request_error` | 请求格式/内容不合规(消息结构错误、缺少必填字段、无兼容 vendor 等) | ✗ | -| `401` | `authentication_error` | 无有效认证凭证 | ✗ | -| `403` | `permission_error` | 权限不足 | ✗ | -| `429` | `rate_limit_error` | 所有 vendor 均触发速率限制 | ✓(等待后重试) | -| `500` | `api_error` | 代理内部异常 | ✓(视情况) | -| `502` | `api_error` | 所有 vendor 均不可达(超时/连接失败) | ✓ | -| `503` | `authentication_error` | Token 获取失败(如 OAuth 凭证失效) | ✓(重新认证后) | - -**流式错误事件** - -流式响应中途发生错误时,以 SSE 事件形式通知: - -``` -event: error -data: {"type":"error","error":{"type":"api_error","message":"上游连接超时"}} -``` - ---- - -#### 5.2.6 请求规范化行为 - -代理在将请求转发至 vendor 前,会自动进行规范化处理。**以下行为对调用方透明,无需手动处理**: - -**自动修复(静默处理)** - -| 问题 | 处理方式 | -|------|---------| -| `tool_use_id` 格式不符(非 `toolu_` 前缀,如 `srvtoolu_*`) | 自动重写为合规格式,并维护映射关系 | -| `tool_result` 出现在 `assistant` 消息中 | 将该 block 从 assistant 消息中剥离(首次触发时记录 WARNING 日志) | -| `tool_use` 缺少合法 ID | 自动生成新 ID 并建立映射 | - -**致命验证错误(返回 HTTP 400)** - -| 场景 | 错误示例 | -|------|---------| -| `tool_use` block 缺少 `id` 字段 | `"tool_use block is missing 'id' field"` | -| `tool_result` block 缺少 `tool_use_id` 字段 | `"tool_result block is missing 'tool_use_id' field"` | -| 消息角色不交替(连续相同角色) | `"messages must alternate between user and assistant"` | -| `messages` 末尾不是 `user` 消息 | `"last message must be from user"` | - -**Thinking Block 跨 Vendor 处理** - -当请求被路由至非 Anthropic vendor(如 Copilot、智谱等)时,assistant 历史消息中的 `thinking` block 会被自动剥离,因为这些 block 包含仅 Anthropic 可验证的签名(`signature` 字段)。此行为不影响当前轮次的 `thinking` 功能配置(由目标 vendor 的能力决定)。 - -> **注**:示例中使用 `claude-sonnet-4-5` 作为模型 ID 示例。实际可用的模型 ID 取决于配置的 vendor 与 `model_mapping` 规则,以 [Anthropic 官方文档](https://docs.anthropic.com/en/docs/about-claude/models) 和本地配置为准。 - -### 5.3 POST /v1/messages/count_tokens - -Token 计数 API 透传。旁路直通 Anthropic 供应商,不经过路由链。仅当 Anthropic 主供应商启用时可用。 - -```bash -curl -X POST http://127.0.0.1:8046/v1/messages/count_tokens \ - -H "Content-Type: application/json" \ - -H "anthropic-version: 2023-06-01" \ - -d '{"model":"claude-sonnet-4-*","messages":[{"role":"user","content":"Hello"}]}' -``` - -> **限制**:此端点直接透传到 Anthropic API,不经过故障转移链。如果 Anthropic 主供应商未启用,返回 404;如果上游不可达,返回 502。 - -### 5.4 GET /health - -健康检查。 - -```bash -curl http://127.0.0.1:8046/health -# {"status":"ok"} -``` - -### 5.5 GET /api/status - -查询所有层级的熔断器、配额守卫、周级配额守卫、Rate Limit 及诊断信息。 - -```bash -curl http://127.0.0.1:8046/api/status -``` - -**返回示例**: - -```json -{ - "tiers": [ - { - "name": "anthropic", - "circuit_breaker": { - "state": "closed", - "failure_count": 0, - "success_count": 0, - "current_recovery_seconds": 300, - "last_failure_time": null - }, - "quota_guard": { - "state": "within_quota", - "window_usage_tokens": 12500000, - "budget_tokens": 45000000, - "usage_percent": 27.8, - "threshold_percent": 99.0 - }, - "weekly_quota_guard": { - "state": "within_quota", - "window_usage_tokens": 85000000, - "budget_tokens": 250000000, - "usage_percent": 34.0, - "threshold_percent": 99.0 - }, - "rate_limit": { - "is_rate_limited": false, - "remaining_seconds": 0 - }, - "diagnostics": {} - }, - { - "name": "zhipu" - } - ] -} -``` - -> 每个 tier 对象包含 `name` 字段。`circuit_breaker`、`quota_guard`、`weekly_quota_guard`、`rate_limit` 仅在该层配置了对应组件时出现。`diagnostics` 为供应商提供的附加诊断信息(如 Copilot 认证链路状态)。终端层(如 zhipu)通常仅含 `name`。 - -### 5.6 POST /api/reset - -手动重置所有层级的弹性设施。 - -```bash -curl -X POST http://127.0.0.1:8046/api/reset -# {"status":"ok"} -``` - -**重置范围**:circuit_breaker(→ CLOSED)、quota_guard(→ WITHIN_QUOTA)、weekly_quota_guard(→ WITHIN_QUOTA)、rate_limit deadline(→ 清除)。等同于 CLI 命令 [`coding-proxy reset`](#44-coding-proxy-reset)。 - -### 5.7 GET /api/copilot/diagnostics - -返回 Copilot 认证与交换链路的脱敏诊断信息。 - -```bash -curl http://127.0.0.1:8046/api/copilot/diagnostics -``` - -**返回示例**: - -```json -{ - "has_token": true, - "token_source": "oauth_device_flow", - "last_exchange_status": "ok", - "last_exchange_time": "2025-01-15T10:30:00Z", - "models_cached": true -} -``` - -> 若 Copilot 供应商未启用,返回 404。可用于排查 Device Flow 完成但 token exchange 失败的场景。 - -### 5.8 GET /api/copilot/models - -按需探测当前 Copilot 会话可见的模型列表。 - -```bash -curl http://127.0.0.1:8046/api/copilot/models -``` - -**返回示例**: - -```json -{ - "probe_status": "ok", - "models": [ - "claude-opus-4.6", - "Claude Sonnet 4.6", - "claude-sonnet-4.6", - "claude-haiku-4.5" - ], - "probed_at": "2025-01-15T10:30:00Z" -} -``` - -> 需要有效的 Copilot 凭证;凭证无效时返回 503。返回的模型列表可用于更新 [`model_mapping`](#35-model_mapping--模型映射规则) 中的 `target` 值。 - -### 5.9 GET /api/reauth/status - -查询运行时重认证状态。 - -```bash -curl http://127.0.0.1:8046/api/reauth/status -``` - -**返回示例**: - -```json -{ - "providers": { - "github": { "status": "idle", "last_triggered": null }, - "google": { "status": "in_progress", "last_triggered": "2025-01-15T10:30:00Z" } - } -} -``` - -### 5.10 POST /api/reauth/{provider} - -手动触发指定 provider 的运行时重认证。 - -```bash -curl -X POST http://127.0.0.1:8046/api/reauth/github -# HTTP/1.1 202 Accepted -# {"status":"reauth requested"} -``` - -| 参数 | 说明 | -| ------------ | ---------------------------------- | -| `{provider}` | provider 名称:`github` / `google` | - -> 返回 202 Accepted 表示重认证请求已接收,用户需在浏览器中完成授权流程。若代理未启用对应供应商的重认证协调器,返回 404。 - ---- - -## 6. Claude Code 集成指南 - -### 6.1 配置 Claude Code 使用代理 - -启动 coding-proxy 后,设置环境变量让 Claude Code 通过代理发送请求: - -```bash -export ANTHROPIC_BASE_URL=http://127.0.0.1:8046 -``` - -Claude Code 使用的 OAuth token 会被代理透传到 Anthropic API,无需额外配置认证信息。 - -### 6.2 验证集成 - -1. 确保 coding-proxy 正在运行:`coding-proxy status` -2. 使用 Claude Code 发送一条消息 -3. 查看 coding-proxy 的终端日志,确认请求经过代理 -4. 使用 `coding-proxy usage` 查看是否有新的用量记录 - -### 6.3 日常使用流程 - -1. **启动代理**:`coding-proxy start`(可使用 `nohup` 或 `tmux` 后台运行) -2. **OAuth 认证**(如启用 Copilot/Antigravity):启动时自动检查凭证,缺失则触发浏览器登录;也可通过 [`auth login`](#45-coding-proxy-auth-login) 手动登录 -3. **正常使用 Claude Code**:代理在后台透明工作 -4. **定期查看用量**:`coding-proxy usage` 了解 Token 消耗、费用估算和供应商分布 -5. **按需手动干预**:`coding-proxy reset` 在确认主供应商恢复后强制切回 -6. **运行时重认证**:凭证过期时通过 [`auth reauth`](#47-coding-proxy-auth-reauth) 无需重启即可刷新 - ---- - -## 7. 监控与运维 - -### 7.1 日志查看 - -代理服务日志默认输出到控制台,包含以下关键事件: - -| 事件 | 日志级别 | 示例 | -| --------------- | ------------ | ----------------------------------------------------------------------- | -| 熔断器状态转换 | INFO/WARNING | `Circuit breaker: CLOSED → OPEN (3 consecutive failures)` | -| 故障转移触发 | WARNING | `Primary error 429, failing over` | -| 恢复成功 | INFO | `Circuit breaker: HALF_OPEN → CLOSED (recovered)` | -| 连接错误 | WARNING | `Primary connection error: ConnectTimeout` | -| Rate Limit 生效 | INFO | `Tier anthropic: rate limit deadline active, 30.0s remaining, blocking` | -| 自动登录 | INFO | `Copilot 层缺少有效凭证,启动 GitHub OAuth 登录...` | +server: + host: "127.0.0.1" # 设为 "0.0.0.0" 接受外部连接 + port: 8046 -可通过配置调整日志级别: +database: + path: "~/.coding-proxy/usage.db" -```yaml logging: - level: "DEBUG" # 查看详细的模型映射和路由决策 - file: "/var/log/coding-proxy.log" # 输出到文件 -``` - -### 7.2 用量统计 - -详细用法参见 [§4.3 coding-proxy usage](#43-coding-proxy-usage)。以下为常用查询快捷参考: - -```bash -# 查看最近 7 天统计(默认) -coding-proxy usage - -# 查看最近 30 天,仅 Anthropic 供应商 -coding-proxy usage -d 30 -v anthropic - -# 查看最近 30 天,仅智谱供应商 -coding-proxy usage -d 30 -v zhipu - -# 按模型过滤 -coding-proxy usage -m claude-sonnet-4-* -``` - -### 7.3 健康检查 - -```bash -# 基础检查 -curl http://127.0.0.1:8046/health - -# 详细状态(所有层级的熔断器、配额守卫、Rate Limit、诊断信息) -curl http://127.0.0.1:8046/api/status + level: "INFO" # DEBUG / INFO / WARNING / ERROR + # file: "coding-proxy.log" # 输出到文件 + # max_bytes: 5242880 # 单文件 5 MB + # backup_count: 5 # 保留 5 个备份 ``` -> 各端点的详细说明和响应格式参见 [第 5 章 HTTP API 端点](#5-http-api-端点)。 - -### 7.4 数据库维护 - -用量数据库位于 `~/.coding-proxy/usage.db`(可通过配置修改)。 - -- 数据库采用 SQLite WAL 模式,支持读写并发 -- 当前版本不自动清理历史数据 -- 如需清理,可直接删除数据库文件(重启后自动重建) - -### 7.5 性能调优参考 - -以下参数调整建议基于典型使用场景,实际值应根据订阅计划和网络环境调校: - -| 参数 | 默认值 | 稳定优先 | 敏感快速 | 说明 | -| ---------------------------- | -------- | -------------- | -------- | -------------------------------------------------------- | -| `timeout_ms` | 300000 | `300000` | `120000` | 长对话场景建议保持 5 分钟;短查询可缩短至 2 分钟 | -| `failure_threshold` | 3 | `5` | `2` | 网络稳定环境可降低以更快触发降级;波动大则提高避免误触发 | -| `recovery_timeout_seconds` | 300 | `600` | `120` | 给主供应商更多恢复时间 vs 更快尝试恢复 | -| `token_budget` | 45000000 | 按订阅计划设定 | — | 建议设为订阅额度的 95%~99%,留余量给手动操作 | -| `window_hours` (quota_guard) | 5.0 | `8.0` | `3.0` | 滑动窗口大小:长窗口更平滑,短窗口更灵敏 | -| `max_retries` | 2 | `3` | `1` | 网络不稳定时增加重试;低延迟要求时减少重试 | -| `initial_delay_ms` | 500 | `1000` | `200` | 首次重试延迟:网络延迟高时增大 | - -**SQLite WAL 注意事项**: -- WAL 模式支持读写并发,适合单进程部署 -- 数据库文件会随时间增长(当前版本不自动清理),建议定期监控磁盘占用 -- `compat.db` 为内部兼容性状态库,通常远小于 `usage.db` - ---- - -## 8. 常见使用场景 - -### 8.1 上游 API 限流自动降级 +> 完整字段定义参见 [配置字段参考](./arch/config-reference.md#3-服务器配置)。 -**现象**:Claude Code 响应变慢或提示 "rate limited" +### 4.7 旧 flat 格式兼容说明(已废弃) -**代理行为**: -1. 检测到上游供应商返回 `429 rate_limit_error` -2. 解析响应头中的 `retry-after`,设置 Rate Limit 精确截止时间 -3. 熔断器记录失败,达到阈值后切换到 OPEN 状态 -4. 后续请求按优先级链自动降级到下一可用供应商 -5. 等待恢复超时后自动尝试切回更高优先级的供应商 +以下字段为 legacy flat 格式(已废弃,保留仅用于向后兼容): -**用户操作**:无需干预,代理自动处理。可通过 [`GET /api/status`](#55-get-apistatus) 中的 `rate_limit` 字段查看当前限速状态。 - -### 8.2 配额耗尽后自动降级 - -**现象**:上游供应商返回 `403` 错误,消息含 "usage cap" 或 "quota" - -**代理行为**: -1. 识别错误消息中的关键词("quota"、"usage cap") -2. 小时级配额守卫和/或周级配额守卫同时标记该层为 QUOTA_EXCEEDED -3. 后续请求自动路由到下一可用层级 -4. Claude Code 继续正常工作 - -**用户操作**:无需干预。可通过 `coding-proxy usage` 查看各供应商的请求分布和 Cost 估算。 - -### 8.3 手动恢复使用主供应商 - -**场景**:确认上游 API 已恢复,希望立即切回而不等待自动恢复。 - -```bash -# 重置所有层级的熔断器和配额守卫 -coding-proxy reset - -# 确认状态 -coding-proxy status -``` - -### 8.4 禁用特定供应商层级 - -如果希望跳过某个供应商层级,可在 `vendors` 列表中设置 `enabled: false`: - -```yaml -vendors: - - vendor: copilot - enabled: false # 禁用 Copilot 供应商 - - - vendor: antigravity - enabled: false # 禁用 Antigravity 供应商 -``` - -禁用后,该层级将从路由链中移除,请求不会尝试路由到该供应商。也可通过 [`tiers`](#33-tiers--降级链路优先级) 从降级链中排除特定供应商。 - -### 8.5 运行时 OAuth 重认证 - -**场景**:Copilot 或 Antigravity 凭证在代理运行期间过期,需要刷新而无需重启服务。 - -```bash -# 方法一:CLI 命令 -coding-proxy auth reauth github - -# 方法二:直接调用 API -curl -X POST http://127.0.0.1:8046/api/reauth/github -``` - -重认证请求发出后(HTTP 202),用户需在浏览器中完成授权。完成后代理自动使用新凭证,无需重启。 +`primary`, `copilot`, `antigravity`, `fallback`, `circuit_breaker`, `copilot_circuit_breaker`, `antigravity_circuit_breaker`, `quota_guard`, `copilot_quota_guard`, `antigravity_quota_guard` -> **查看进度**:通过 [`GET /api/reauth/status`](#59-get-apireauthstatus) 查询当前重认证状态。 +如果配置文件中使用上述旧格式,系统启动时**自动迁移**至 vendors 格式并输出日志提示。建议尽快迁移至 vendors 新格式。 --- -## 9. 故障排查 - -### 9.1 代理服务无法启动 - -**端口占用**: - -```bash -lsof -i :8046 -# 如有进程占用,先停止或更换端口 -coding-proxy start --port 8080 -``` - -**配置文件语法错误**: +## 5. 日常操作速查 -检查 YAML 格式是否正确(缩进、冒号后的空格等)。常见错误: +| 操作 | 命令 | +|------|------| +| 启动代理 | `coding-proxy start` | +| 查看状态 | `coding-proxy status` | +| 查看用量 | `coding-proxy usage` | +| 查看本周 | `coding-proxy usage -w` | +| 查看本月 | `coding-proxy usage -m` | +| 重置熔断器 | `coding-proxy reset` | +| 提升供应商 | `coding-proxy reset -v anthropic` | +| GitHub 登录 | `coding-proxy auth login -p github` | +| 重认证 | `coding-proxy auth reauth github` | +| 查看凭证 | `coding-proxy auth status` | +| Dashboard | 浏览器访问 `http://127.0.0.1:8046/dashboard` | -```yaml -# 错误:冒号后缺少空格 -port:8046 - -# 正确 -port: 8046 -``` - -**Python 版本不满足**: - -```bash -python --version -# 需要 Python >= 3.12 -``` - -### 9.2 Claude Code 无法连接代理 - -1. 确认代理服务正在运行: - -```bash -coding-proxy status -# 如果提示 "代理服务未运行",先启动服务 -``` - -2. 确认环境变量设置正确: - -```bash -echo $ANTHROPIC_BASE_URL -# 应输出: http://127.0.0.1:8046 -``` - -3. 确认代理端口与环境变量一致 - -### 9.3 频繁触发故障转移 - -如果发现频繁在各层供应商之间切换: - -1. 检查上游 API 状态(是否正在经历服务波动) -2. 查看 [`GET /api/status`](#55-get-apistatus) 中的 `rate_limit` 信息,确认是否受 Rate Limit 截止影响 -3. 适当调高 `failure_threshold`(如从 3 改为 5) -4. 适当调高 `recovery_timeout_seconds`(给主供应商更多恢复时间) -5. 查看日志确认触发原因(状态码、错误类型、错误消息) - -### 9.4 智谱供应商返回错误 - -1. **API Key 错误**:确认 `ZHIPU_API_KEY` 环境变量已正确设置 -2. **模型不存在**:检查 [`model_mapping`](#35-model_mapping--模型映射规则) 规则,确认目标模型名称有效 -3. **网络问题**:确认可以访问 `open.bigmodel.cn` - -### 9.5 Token 用量不记录 - -1. 确认数据库路径目录可写: - -```bash -ls -la ~/.coding-proxy/ -``` - -2. 如果目录不存在,代理会在启动时自动创建 -3. 流式请求的用量提取依赖 SSE 事件格式,如果供应商返回非标准格式可能无法正确解析 - -### 9.6 count_tokens 请求失败 - -**返回 404**:Anthropic 主供应商未启用。`count_tokens` 端点仅在 Anthropic 供应商启用时可用,请确认配置中存在 `vendor: anthropic` 且 `enabled: true`。 - -**返回 502**:Anthropic API 不可达。检查网络连通性和 Anthropic API 状态。此端点直接透传到 Anthropic,不经过故障转移链。 - -### 9.7 Copilot 认证问题 - -**现象**:GitHub Device Flow 显示 "Congratulations, you're all set!" 但请求仍失败。 - -**排查步骤**: - -1. 查看 Copilot 诊断信息: - -```bash -curl http://127.0.0.1:8046/api/copilot/diagnostics -``` - -2. 确认 token exchange 是否成功(`last_exchange_status` 字段) -3. 探查当前可见模型列表: - -```bash -curl http://127.0.0.1:8046/api/copilot/models -``` - -4. 如果凭证已过期,执行重认证: - -```bash -coding-proxy auth reauth github -``` +> 完整命令选项参见 [CLI 命令参考](./guide/cli-reference.md)。 --- -## 附录 A:术语对照表 - -| 术语 | 说明 | -| ----------------------------- | ------------------------------------------------------------------------------------------ | -| **Vendor(供应商)** | API 后端提供方,即 `vendors` 列表中的一个条目 | -| **Tier(层级)** | 一个 Vendor + 其关联弹性设施(熔断器/配额守卫等)的路由单元 | -| **Terminal Tier(终端层)** | 未配置 `circuit_breaker` 的 Vendor,始终接受请求,不触发向下故障转移 | -| **主供应商 / Tier 0** | 降级链中最高优先级的供应商(默认为 Anthropic) | -| **故障转移(Failover)** | 当前供应商不可用时自动切换到下一优先级供应商的过程 | -| **熔断器(Circuit Breaker)** | 连续失败达到阈值后暂时切断对某供应商的请求,避免雪崩 | -| **配额守卫(Quota Guard)** | 基于滑动窗口的 Token 用量预算管理,超限时跳过该供应商 | -| **Rate Limit** | 基于上游响应头的精确速率限制控制,三层恢复门控(Deadline → Health Check → Cautious Probe) | - ---- - -## 附录 B:完整配置参考 - -> **说明**:本附录为 [`config.default.yaml`](../config.default.yaml) 的精简摘要。完整注释版(含每行注释说明)请直接参阅项目根目录下的 `config.default.yaml`,它是唯一权威配置模板。 -> -> 以下省略的字段在代码中均有合理默认值(参见各配置表格中的「默认值」列),无需显式配置即可生效。 - -```yaml -server: - host: "127.0.0.1" - port: 8046 - -vendors: - - vendor: anthropic # 主供应商(中间层) - base_url: "https://api.anthropic.com" - timeout_ms: 300000 - circuit_breaker: # 中间层标识(有此字段 = 参与故障转移) - failure_threshold: 3 - recovery_timeout_seconds: 300 - success_threshold: 2 - # max_recovery_seconds: 3600 # 可选,默认 3600(指数退避上限) - quota_guard: - enabled: true - token_budget: 45000000 - window_hours: 5.0 - threshold_percent: 99.0 - probe_interval_seconds: 300 - weekly_quota_guard: # 可选:周级预算 - enabled: true - token_budget: 250000000 - window_hours: 168.0 # 7 天滑动窗口 - threshold_percent: 99.0 - probe_interval_seconds: 1800 - # retry: # 可选,传输层重试(有默认值) - - - vendor: copilot # 中间层(默认禁用) - enabled: false - github_token: "${GITHUB_TOKEN}" - account_type: "individual" - # circuit_breaker / quota_guard 结构同 anthropic - - - vendor: antigravity # 中间层(默认禁用) - enabled: false - client_id: "${GOOG_CLIENT_ID}" - client_secret: "${GOOG_CLIENT_SECRET}" - refresh_token: "${GOOG_REFRESH_TOKEN}" - base_url: "https://generativelanguage.googleapis.com/v1beta" - model_endpoint: "models/claude-sonnet-4-20250514" - # safety_settings: {} # 可选,Gemini API 安全设置 - # circuit_breaker / quota_guard 结构同 anthropic - - - vendor: zhipu # 终端层(无 circuit_breaker) - base_url: "https://open.bigmodel.cn/api/anthropic" - api_key: "${ZHIPU_API_KEY}" - timeout_ms: 3000000 - -# tiers: ["anthropic", "copilot", "antigravity", "zhipu"] # 可选,降级链路优先级 - -failover: - status_codes: [429, 403, 503, 500] - error_types: ["rate_limit_error", "overloaded_error", "api_error"] - error_message_patterns: ["quota", "usage cap"] - # 注:FailoverConfig 代码默认值额外包含 "limit exceeded" 和 "capacity" - -model_mapping: - # 完整列表参见 config.default.yaml 及 §3.5 - - pattern: "claude-sonnet-.*" - vendors: ["copilot"] - target: "claude-sonnet-4.6" - is_regex: true - # ... 更多映射规则(按供应商分组) ... - -pricing: # 可选:费用统计(四维定价 $/¥) - # 完整列表参见 config.default.yaml(~20 条,覆盖全部供应商与模型) - - vendor: anthropic - model: claude-sonnet-4-6 - input_cost_per_mtok: $3.0 - output_cost_per_mtok: $15.0 - cache_write_cost_per_mtok: $3.75 - cache_read_cost_per_mtok: $0.30 - -auth: # OAuth 配置 - token_store_path: "~/.coding-proxy/tokens.json" - -database: - path: "~/.coding-proxy/usage.db" - # compat_state_path: ~/.coding-proxy/compat.db # 内部使用 - # compat_state_ttl_seconds: 86400 # 内部使用 - -logging: - level: "INFO" - # file: null # null=控制台输出 -``` +## 附录:术语对照表 + +| 术语 | 说明 | +|------|------| +| **Vendor(供应商)** | API 后端提供方,即 `vendors` 列表中的一个条目 | +| **Tier(层级)** | 一个 Vendor + 其关联弹性设施的路由单元 | +| **Terminal Tier(终端层)** | 未配置 `circuit_breaker` 的 Vendor,始终接受请求,不触发向下故障转移 | +| **故障转移(Failover)** | 当前供应商不可用时自动切换到下一优先级供应商 | +| **熔断器(Circuit Breaker)** | 连续失败达到阈值后暂时切断对该供应商的请求 | +| **配额守卫(Quota Guard)** | 基于滑动窗口的 Token 用量预算管理,超限时跳过该供应商 | +| **Rate Limit** | 基于上游响应头的精确速率限制控制 | +| **模型映射(Model Mapping)** | 将 Claude 模型名自动转换为各供应商实际模型名 | +| **原生 Anthropic 兼容(Native Anthropic Compatible)** | 提供 Anthropic 兼容端点的供应商,仅需 `api_key` + `base_url` | From 2773c9e7fe6e5deae08764f009848c778a153092 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Fri, 17 Apr 2026 23:54:31 +0800 Subject: [PATCH 22/32] =?UTF-8?q?docs(user-guide):=20=E4=BA=8C=E8=BD=AE?= =?UTF-8?q?=E6=A0=A1=E5=87=86=E4=BF=AE=E6=AD=A3=E5=85=A8=E9=83=A8=E4=BA=8B?= =?UTF-8?q?=E5=AE=9E=E6=80=A7=E5=81=8F=E5=B7=AE=20=E2=80=94=20=E9=94=9A?= =?UTF-8?q?=E7=82=B9=E6=96=AD=E8=A3=82=E3=80=81CLI=20=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E3=80=81=E9=85=8D=E7=BD=AE=E5=8A=A0=E8=BD=BD=E8=AF=AD=E4=B9=89?= =?UTF-8?q?=E3=80=81=E8=BF=81=E7=A7=BB=E6=9D=A1=E4=BB=B6=E7=B2=BE=E7=A1=AE?= =?UTF-8?q?=E5=8C=96;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- docs/guide/api-reference.md | 4 +++- docs/guide/cli-reference.md | 8 ++++---- docs/guide/dashboard.md | 14 +++++++------- docs/guide/monitoring.md | 10 +++++----- docs/guide/vendors.md | 9 ++++----- docs/user-guide.md | 13 ++++++------- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/docs/guide/api-reference.md b/docs/guide/api-reference.md index f943491..4ff1597 100644 --- a/docs/guide/api-reference.md +++ b/docs/guide/api-reference.md @@ -164,7 +164,7 @@ curl -I http://127.0.0.1:8046/ | 问题 | 处理方式 | |------|---------| | `tool_use_id` 格式不符(非 `toolu_` 前缀) | 自动重写为合规格式 | -| `tool_result` 出现在 `assistant` 消息中 | 剥离该 block(首次触发 WARNING 日志) | +| `tool_result` 出现在 `assistant` 消息中 | 收集该 block;转发至 Anthropic tier 时执行重定位,其他 vendor 保留原位不变(首次触发 WARNING 日志) | | `tool_use` 缺少合法 ID | 自动生成新 ID | **致命验证错误(返回 HTTP 400)** @@ -172,7 +172,9 @@ curl -I http://127.0.0.1:8046/ | 场景 | 错误示例 | |------|---------| | `tool_use` block 缺少 `id` 字段 | `"tool_use block is missing 'id' field"` | +| `tool_use` block 缺少 `name` 字段 | `"tool_use block missing name for id rewrite"` | | `tool_result` block 缺少 `tool_use_id` 字段 | `"tool_result block is missing 'tool_use_id' field"` | +| `tool_result` 引用不存在的 `tool_use_id` | `"tool_result references unknown tool_use_id"` | | 消息角色不交替 | `"messages must alternate between user and assistant"` | | `messages` 末尾不是 `user` 消息 | `"last message must be from user"` | diff --git a/docs/guide/cli-reference.md b/docs/guide/cli-reference.md index 3c268d9..9fa9af6 100644 --- a/docs/guide/cli-reference.md +++ b/docs/guide/cli-reference.md @@ -102,11 +102,11 @@ coding-proxy usage [OPTIONS] # 查看最近 7 天统计(默认) coding-proxy usage -# 本周统计 -coding-proxy usage -w +# 本周统计(第 1 周) +coding-proxy usage -w 1 -# 本月统计 -coding-proxy usage -m +# 本月统计(第 1 月) +coding-proxy usage -m 1 # 全部历史,按供应商+模型聚合 coding-proxy usage -t diff --git a/docs/guide/dashboard.md b/docs/guide/dashboard.md index 93bb009..5cbeac6 100644 --- a/docs/guide/dashboard.md +++ b/docs/guide/dashboard.md @@ -18,12 +18,12 @@ http://127.0.0.1:8046/dashboard | 卡片 | 说明 | |------|------| -| 今日请求 | 当日总请求数 | -| 今日 Token | 当日总 Token 消耗(输入 + 输出 + 缓存) | -| 今日费用 | 基于定价配置的费用估算 | -| 故障转移次数 | 所选时间范围内的故障转移事件数 | -| 平均耗时 | 请求平均响应时间 | -| 区间请求 | 所选时间范围的总请求数 | +| 今日请求数 | 当日总请求数(子行显示本周累计) | +| 今日 Token 总量 | 当日总 Token 消耗(子行显示本周累计) | +| 今日输出 Token | 当日输出 Token 数(子行显示本周累计) | +| 今日费用估算 | 基于定价配置的费用估算(子行显示本周累计) | +| 故障转移(今日) | 当日故障转移事件数(子行显示本周累计) | +| 平均延迟(今日) | 当日请求平均响应时间(子行显示本周累计) | ### 图表 @@ -55,7 +55,7 @@ http://127.0.0.1:8046/dashboard ## 数据源 -看板数据来自以下 API 端点,详见 [API 参考 — Dashboard 端点](./api-reference.md#59-dashboard-端点): +看板数据来自以下 API 端点,详见 [API 参考 — Dashboard 端点](./api-reference.md#11-dashboard-端点): | 端点 | 说明 | |------|------| diff --git a/docs/guide/monitoring.md b/docs/guide/monitoring.md index 7437cc6..6f2e492 100644 --- a/docs/guide/monitoring.md +++ b/docs/guide/monitoring.md @@ -42,11 +42,11 @@ logging: # 最近 7 天(默认) coding-proxy usage -# 本周统计 -coding-proxy usage -w +# 本周统计(第 1 周) +coding-proxy usage -w 1 -# 本月统计 -coding-proxy usage -m +# 本月统计(第 1 月) +coding-proxy usage -m 1 # 全部历史 coding-proxy usage -t @@ -112,7 +112,7 @@ curl http://127.0.0.1:8046/api/status ### 7.2 配额耗尽后自动降级 -**现象**:上游供应商返回 `403` 错误,消息含 "usage cap" 或 "quota" +**现象**:上游供应商返回 `403` 错误,消息含 "quota"、"usage cap"、"limit exceeded"、"capacity" 等关键词 **代理行为**:识别关键词 → 配额守卫标记 QUOTA_EXCEEDED → 后续请求自动路由到下一层级。 diff --git a/docs/guide/vendors.md b/docs/guide/vendors.md index 1b51c5f..ce7fa8d 100644 --- a/docs/guide/vendors.md +++ b/docs/guide/vendors.md @@ -42,7 +42,7 @@ coding-proxy 支持三类供应商,共 9 种: | `vendor` | string | — | 供应商类型标识 | | `enabled` | bool | `true` | 是否启用 | | `base_url` | string | `""` | API 基础 URL;留空使用供应商默认值 | -| `timeout_ms` | int | `300000` | 请求超时(毫秒) | +| `timeout_ms` | int | `300000`/`3000000` | 请求超时(毫秒);直连/协议转换供应商默认 300000(5 分钟),原生 Anthropic 兼容供应商默认 3000000(50 分钟) | 弹性设施字段(`circuit_breaker`、`quota_guard`、`weekly_quota_guard`、`retry`)参见 [配置字段参考 — 弹性字段](../arch/config-reference.md#5-vendorconfig-弹性字段)。 @@ -79,7 +79,7 @@ coding-proxy 支持三类供应商,共 9 种: | `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL(秒) | > 默认已启用(`enabled: true`)。首次启动时若缺少有效凭证,自动触发 GitHub Device Flow 浏览器登录。 -> 可通过 [`GET /api/copilot/diagnostics`](./api-reference.md#57-get-apicopilotdiagnostics) 和 [`GET /api/copilot/models`](./api-reference.md#58-get-apicopilotmodels) 排查认证状态。 +> 可通过 [`GET /api/copilot/diagnostics`](./api-reference.md#7-get-apicopilotdiagnostics) 和 [`GET /api/copilot/models`](./api-reference.md#8-get-apicopilotmodels) 排查认证状态。 ### 3.3 antigravity — Google Antigravity @@ -92,7 +92,6 @@ coding-proxy 支持三类供应商,共 9 种: | `refresh_token` | string | `""` | Google OAuth2 Refresh Token,支持 `${ENV_VAR}` | | `base_url` | string | `"https://generativelanguage.googleapis.com/v1beta"` | Gemini API 基础地址 | | `model_endpoint` | string | `"models/claude-sonnet-4-20250514"` | 模型端点路径(仅作为未命中映射时的默认模型) | -| `safety_settings` | dict or null | `null` | Gemini API 安全设置键值对(如 `{"HARASSMENT": "block_none"}`) | > 默认禁用(`enabled: false`)。启用需配置 OAuth 凭据,启动时自动触发 Google OAuth 登录。access_token 过期时优先静默刷新,无需重新登录。 @@ -189,7 +188,7 @@ tiers: ["zhipu", "anthropic", "copilot", "antigravity"] ## 5. model_mapping — 模型映射规则 -将 Claude 模型名自动转换为各供应商对应的实际模型名。完整规则列表参见 [`config.default.yaml`](../../config.default.yaml)。 +将 Claude 模型名自动转换为各供应商对应的实际模型名。完整规则列表参见项目内置的 `config.default.yaml`(`src/coding/proxy/config/config.default.yaml`)。 | 字段 | 类型 | 说明 | |------|------|------| @@ -233,7 +232,7 @@ model_mapping: ## 6. pricing — 模型定价 -按 `(vendor, model)` 配置四维定价,用于 [`coding-proxy usage`](./cli-reference.md#43-coding-proxy-usage) 的费用统计展示。完整定价表参见 [`config.default.yaml`](../../config.default.yaml)。 +按 `(vendor, model)` 配置四维定价,用于 [`coding-proxy usage`](./cli-reference.md#3-coding-proxy-usage) 的费用统计展示。完整定价表参见项目内置的 `config.default.yaml`(`src/coding/proxy/config/config.default.yaml`)。 | 字段 | 类型 | 说明 | |------|------|------| diff --git a/docs/user-guide.md b/docs/user-guide.md index 7a5e73f..80cd646 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -28,7 +28,7 @@ coding-proxy 是一个面向 Claude Code 的多**供应商(vendor)**智能代理服务。它在 Claude Code 和 API 供应商之间充当透明代理,具备以下核心能力: -- **N-tier 自动故障转移(failover)**:支持多层供应商链式降级(默认链路:智谱 → Anthropic → Copilot → Antigravity),恢复后自动切回 +- **N-tier 自动故障转移(failover)**:支持多层供应商链式降级(默认活跃链路:智谱 → Anthropic → Copilot;Antigravity 默认禁用),恢复后自动切回 - **9 种供应商支持**:Anthropic Claude、GitHub Copilot、Google Antigravity、智谱 GLM、MiniMax、阿里 Qwen、小米 MiMo、Kimi、豆包 Doubao - **模型名称映射**:自动将 Claude 模型名转换为各供应商对应的实际模型名 - **格式双向转换**:自动转换 Anthropic ↔ Gemini 格式,支持非 Anthropic 兼容供应商 @@ -130,14 +130,13 @@ curl http://127.0.0.1:8046/health ### 4.1 配置文件位置与加载优先级 -按以下优先级加载(找到第一个即停止): +加载器先按以下顺序查找用户配置文件(找到第一个即停止): 1. `--config` 参数指定的路径(最高优先级) 2. `./config.yaml`(项目根目录) 3. `~/.coding-proxy/config.yaml`(用户主目录) -4. 内置默认值(无需配置文件也可启动) -加载器以 `config.default.yaml` 为基础模板进行深度合并,用户配置覆盖模板默认值。 +找到用户配置后,以内置 `config.default.yaml` 为基础模板进行**深度合并**,用户配置覆盖模板默认值。未找到用户配置文件时,直接使用模板默认值。 ### 4.2 vendors — 供应商列表 @@ -215,7 +214,7 @@ logging: `primary`, `copilot`, `antigravity`, `fallback`, `circuit_breaker`, `copilot_circuit_breaker`, `antigravity_circuit_breaker`, `quota_guard`, `copilot_quota_guard`, `antigravity_quota_guard` -如果配置文件中使用上述旧格式,系统启动时**自动迁移**至 vendors 格式并输出日志提示。建议尽快迁移至 vendors 新格式。 +当用户配置中**同时不存在** `vendors` 和 `tiers` 字段,但包含上述旧格式字段时,系统启动时**自动迁移**至 vendors 格式并输出日志提示。建议尽快迁移至 vendors 新格式。 --- @@ -226,8 +225,8 @@ logging: | 启动代理 | `coding-proxy start` | | 查看状态 | `coding-proxy status` | | 查看用量 | `coding-proxy usage` | -| 查看本周 | `coding-proxy usage -w` | -| 查看本月 | `coding-proxy usage -m` | +| 查看本周 | `coding-proxy usage -w 1` | +| 查看本月 | `coding-proxy usage -m 1` | | 重置熔断器 | `coding-proxy reset` | | 提升供应商 | `coding-proxy reset -v anthropic` | | GitHub 登录 | `coding-proxy auth login -p github` | From a45650e7ab839267920abca50db377f66924f218 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 07:28:53 +0800 Subject: [PATCH 23/32] =?UTF-8?q?feat(vendor-channels):=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=20zhipu/copilot=20=E4=BE=9B=E5=BA=94=E5=95=86?= =?UTF-8?q?=E4=B8=93=E5=B1=9E=E8=BD=AC=E6=8D=A2=E9=80=9A=E9=81=93=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B7=A8=E4=BE=9B=E5=BA=94=E5=95=86=E6=95=85?= =?UTF-8?q?=E9=9A=9C=E8=BD=AC=E7=A7=BB=E6=A0=BC=E5=BC=8F=E4=B8=8D=E5=85=BC?= =?UTF-8?q?=E5=AE=B9;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新建 convert/vendor_channels.py:prepare_for_zhipu(剥离 thinking+cache_control+thinking 参数+tool pairing)、prepare_for_copilot(剥离 thinking+cache_control+tool pairing)、共享辅助函数; - 扩展 executor._prepare_body_for_tier() 从仅 anthropic 扩展为按供应商通道路由,新增 _needs_vendor_channel() 统一触发条件; - 新增 29 个通道函数单元测试 + 2 个 executor 通道路由测试,全量 1257 测试通过; 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- CHANGELOG.md | 1 + src/coding/proxy/convert/vendor_channels.py | 183 ++++++ src/coding/proxy/routing/executor.py | 59 +- tests/test_router_executor.py | 42 +- tests/test_vendor_channels.py | 581 ++++++++++++++++++++ 5 files changed, 858 insertions(+), 8 deletions(-) create mode 100644 src/coding/proxy/convert/vendor_channels.py create mode 100644 tests/test_vendor_channels.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 1af56a8..18e9e40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ## [Unreleased] - 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 异常; +- feat(vendor-channels): 新增 zhipu/copilot 供应商专属转换通道(`prepare_for_zhipu` / `prepare_for_copilot`),在跨供应商故障转移时自动剥离 GLM-5 不兼容的 thinking 块、cache_control 字段、thinking 参数,并强制 tool_use/tool_result 配对,消除 `likely format incompatibility (400 + tool_results)` 错误; ## [v0.2.3](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.2.3) — 2026-04-16 diff --git a/src/coding/proxy/convert/vendor_channels.py b/src/coding/proxy/convert/vendor_channels.py new file mode 100644 index 0000000..d78bdfa --- /dev/null +++ b/src/coding/proxy/convert/vendor_channels.py @@ -0,0 +1,183 @@ +"""供应商专属转换通道 — 跨供应商故障转移时的请求体预处理. + +每个通道函数接收标准化的 Anthropic 格式请求体,返回针对目标供应商 +调整后的请求体(深拷贝)。通道函数之间无依赖关系,可独立测试。 + +通道触发条件由 executor 层根据会话历史和规范化信号判断。 + +通道矩阵: + zhipu → copilot : prepare_for_copilot (剥离 thinking + cache_control + tool pairing) + copilot → zhipu : prepare_for_zhipu (剥离 thinking + cache_control + tool pairing + 移除 thinking 参数) + * → anthropic : executor 现有逻辑 (enforce_anthropic_tool_pairing + 条件 thinking strip) +""" + +from __future__ import annotations + +import copy +import logging +from typing import Any + +logger = logging.getLogger(__name__) + +_THINKING_BLOCK_TYPES = {"thinking", "redacted_thinking"} + + +# ── 共享辅助函数 ────────────────────────────────────────────── + + +def _strip_thinking_blocks_inplace(body: dict[str, Any]) -> int: + """从 assistant 消息中移除 thinking/redacted_thinking 块(就地). + + GLM-5 等 Anthropic 兼容端点不支持非 Anthropic 签发的 thinking signature, + 跨供应商场景中必须剥离以避免 400 invalid_request_error。 + + 剥离后 content 为空时插入最小占位 text block 以保持消息结构合法性。 + + Returns: + 被移除的 thinking block 数量。 + """ + stripped = 0 + for message in body.get("messages", []): + if not isinstance(message, dict) or message.get("role") != "assistant": + continue + content = message.get("content") + if not isinstance(content, list): + continue + original_len = len(content) + new_content = [ + block + for block in content + if not ( + isinstance(block, dict) and block.get("type") in _THINKING_BLOCK_TYPES + ) + ] + removed = original_len - len(new_content) + if removed and not new_content: + new_content = [{"type": "text", "text": "[thinking]"}] + message["content"] = new_content + stripped += removed + return stripped + + +def _strip_cache_control(body: dict[str, Any]) -> int: + """从 system/messages/tools 中移除 cache_control 字段(就地). + + 部分供应商(GLM-5、OpenAI)不支持 Anthropic 的 cache_control 扩展, + 保留该字段可能导致请求被拒绝或产生意外行为。 + + Returns: + 被移除的 cache_control 字段数量。 + """ + removed = 0 + + # System prompt blocks + system = body.get("system") + if isinstance(system, list): + for block in system: + if isinstance(block, dict) and "cache_control" in block: + del block["cache_control"] + removed += 1 + + # Message content blocks + for message in body.get("messages", []): + if not isinstance(message, dict): + continue + content = message.get("content") + if not isinstance(content, list): + continue + for block in content: + if isinstance(block, dict) and "cache_control" in block: + del block["cache_control"] + removed += 1 + + # Tools + for tool in body.get("tools", []): + if isinstance(tool, dict) and "cache_control" in tool: + del tool["cache_control"] + removed += 1 + + return removed + + +# ── zhipu 专属转换通道 ──────────────────────────────────────── + + +def prepare_for_zhipu(body: dict[str, Any]) -> tuple[dict[str, Any], list[str]]: + """zhipu 专属转换通道: 清理 GLM-5 不兼容的 Anthropic 协议扩展. + + GLM-5 的 Anthropic 兼容端点对以下特性支持不完整: + - thinking / redacted_thinking 块 (signature 由非 Anthropic 签发) + - cache_control 字段 + - 跨供应商产物 (misplaced tool_result, 非标准 tool_use ID) + - 顶层 thinking / extended_thinking 参数 + + Returns: + (prepared_body, adaptations) — adaptations 为应用的变换描述列表。 + """ + prepared = copy.deepcopy(body) + adaptations: list[str] = [] + + # Step 1: 剥离 thinking/redacted_thinking 块 + stripped = _strip_thinking_blocks_inplace(prepared) + if stripped: + adaptations.append(f"stripped_{stripped}_thinking_blocks") + + # Step 2: 移除 cache_control 字段 + removed_cc = _strip_cache_control(prepared) + if removed_cc: + adaptations.append(f"removed_{removed_cc}_cache_control_fields") + + # Step 3: 移除顶层 thinking/extended_thinking 参数(GLM-5 不支持) + for param in ("thinking", "extended_thinking"): + if param in prepared: + del prepared[param] + adaptations.append(f"removed_{param}_param") + + # Step 4: 强制 tool_use/tool_result 配对 + from ..server.request_normalizer import enforce_anthropic_tool_pairing + + pairing_fixes = enforce_anthropic_tool_pairing(prepared.get("messages", [])) + if pairing_fixes: + adaptations.extend(pairing_fixes) + + return prepared, adaptations + + +# ── copilot 专属转换通道 ────────────────────────────────────── + + +def prepare_for_copilot(body: dict[str, Any]) -> tuple[dict[str, Any], list[str]]: + """copilot 专属转换通道: 清理 Anthropic 格式请求以确保 OpenAI 转换器稳定. + + Copilot 内部的 convert_openai_request() 处理 Anthropic→OpenAI 格式转换, + 但某些跨供应商产物可能导致转换器输出异常: + - 非 Anthropic 签发的 thinking signature + - cache_control 字段(OpenAI 协议不支持) + - 错位的 tool_result blocks + + 注意: 不移除顶层 thinking 参数,由 copilot converter 自行映射。 + + Returns: + (prepared_body, adaptations) — adaptations 为应用的变换描述列表。 + """ + prepared = copy.deepcopy(body) + adaptations: list[str] = [] + + # Step 1: 剥离 thinking/redacted_thinking 块 + stripped = _strip_thinking_blocks_inplace(prepared) + if stripped: + adaptations.append(f"stripped_{stripped}_thinking_blocks") + + # Step 2: 移除 cache_control 字段 + removed_cc = _strip_cache_control(prepared) + if removed_cc: + adaptations.append(f"removed_{removed_cc}_cache_control_fields") + + # Step 3: 强制 tool_use/tool_result 配对 + from ..server.request_normalizer import enforce_anthropic_tool_pairing + + pairing_fixes = enforce_anthropic_tool_pairing(prepared.get("messages", [])) + if pairing_fixes: + adaptations.extend(pairing_fixes) + + return prepared, adaptations diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index d2fb489..24bef17 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -230,14 +230,35 @@ def _prepare_body_for_tier( normalization: Any = None, session_record: Any = None, ) -> dict[str, Any]: - """为指定 tier 准备请求体,必要时应用 Anthropic 专属修复(Phase 2). + """为指定 tier 准备请求体,应用供应商专属转换通道 (Phase 2). - 仅当 tier 为 Anthropic 时才执行以下处理: - 1. 跨供应商 tool_use/tool_result 配对强制修复(单遍自包含扫描) - 2. 条件化 thinking block 剥离(仅跨供应商场景) - - 确保 Zhipu 等其他 vendor 不受影响。 + 通道路由: + - zhipu / copilot: 委托 vendor_channels 专属通道 + - anthropic: 保留现有 tool pairing + 条件 thinking strip 逻辑 + - 其他: 原样返回 """ + # ── zhipu / copilot: 供应商专属转换通道 ── + from ..convert.vendor_channels import prepare_for_copilot, prepare_for_zhipu + + channel_fn = None + if tier.name == "zhipu": + channel_fn = prepare_for_zhipu + elif tier.name == "copilot": + channel_fn = prepare_for_copilot + + if channel_fn is not None: + if not self._needs_vendor_channel(tier.name, normalization, session_record): + return body + prepared, adaptations = channel_fn(body) + if adaptations: + logger.debug( + "Applied vendor channel for tier %s: %s", + tier.name, + ", ".join(adaptations), + ) + return prepared + + # ── anthropic: 保留现有逻辑 ── if tier.name != "anthropic": return body @@ -277,6 +298,32 @@ def _prepare_body_for_tier( return body_for_vendor + @staticmethod + def _needs_vendor_channel( + tier_name: str, + normalization: Any, + session_record: Any, + ) -> bool: + """判断是否需要为目标供应商触发专属转换通道. + + 触发信号(满足任一): + 1. normalization 检测到跨供应商产物 + 2. 无会话追踪能力 → 安全回退 + 3. 会话历史中存在非当前供应商记录 + """ + # Signal 1: 跨供应商信号 + if normalization is not None and normalization.has_cross_vendor_signals: + return True + # Signal 2: 无会话追踪 → 安全回退 + if session_record is None: + return True + # Signal 3: 会话历史中有非当前供应商 + if session_record.provider_state: + non_current = {v for v in session_record.provider_state if v != tier_name} + if non_current: + return True + return False + @staticmethod def _needs_tool_pairing_enforcement( normalization: Any, session_record: Any diff --git a/tests/test_router_executor.py b/tests/test_router_executor.py index 9b1d452..f0043e2 100644 --- a/tests/test_router_executor.py +++ b/tests/test_router_executor.py @@ -1732,12 +1732,50 @@ def test_strips_thinking_when_no_session_record(self): assert result["messages"][0]["content"][0]["type"] == "text" def test_skips_for_non_anthropic_tier(self): - """非 Anthropic tier 不执行任何处理.""" + """无专属通道的非 Anthropic tier 不执行任何处理.""" tier = MagicMock() - tier.name = "zhipu" + tier.name = "antigravity" # antigravity 无 vendor channel,原样返回 exec_inst = _executor([]) body = self._body_with_thinking() result = exec_inst._prepare_body_for_tier(body, tier) assert result is body # 原始 body 直接返回 + + def test_zhipu_tier_applies_channel_when_cross_vendor(self): + """zhipu tier 在跨供应商场景下应用专属转换通道.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = True + + tier = MagicMock() + tier.name = "zhipu" + + exec_inst = _executor([]) + body = self._body_with_thinking() + result = exec_inst._prepare_body_for_tier( + body, tier, normalization, session_record=None + ) + + # zhipu 通道剥离 thinking blocks + 移除 thinking 参数 + assert result is not body + assert len(result["messages"][0]["content"]) == 1 + assert result["messages"][0]["content"][0]["type"] == "text" + + def test_zhipu_tier_skips_channel_in_pure_session(self): + """zhipu tier 在纯 zhipu 会话中不触发专属通道.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + + tier = MagicMock() + tier.name = "zhipu" + + session_record = MagicMock() + session_record.provider_state = {"zhipu"} + + exec_inst = _executor([]) + body = self._body_with_thinking() + result = exec_inst._prepare_body_for_tier( + body, tier, normalization, session_record=session_record + ) + + assert result is body # 纯 zhipu 会话,无需通道处理 diff --git a/tests/test_vendor_channels.py b/tests/test_vendor_channels.py new file mode 100644 index 0000000..7a82c12 --- /dev/null +++ b/tests/test_vendor_channels.py @@ -0,0 +1,581 @@ +"""供应商专属转换通道单元测试. + +覆盖 :mod:`coding.proxy.convert.vendor_channels` 的通道函数和辅助函数: +- zhipu 通道 (prepare_for_zhipu) +- copilot 通道 (prepare_for_copilot) +- 共享辅助函数 (_strip_thinking_blocks_inplace, _strip_cache_control) +""" + +from __future__ import annotations + +import copy + +from coding.proxy.convert.vendor_channels import ( + _strip_cache_control, + _strip_thinking_blocks_inplace, + prepare_for_copilot, + prepare_for_zhipu, +) + +# ── 辅助函数测试 ────────────────────────────────────────────── + + +class TestStripThinkingBlocksInplace: + """_strip_thinking_blocks_inplace 单元测试.""" + + def test_strips_thinking_blocks(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "thought", "signature": "sig"}, + {"type": "text", "text": "response"}, + ], + }, + ] + } + stripped = _strip_thinking_blocks_inplace(body) + assert stripped == 1 + assert body["messages"][0]["content"] == [ + {"type": "text", "text": "response"}, + ] + + def test_strips_redacted_thinking_blocks(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "redacted_thinking", "data": "redacted"}, + ], + }, + ] + } + stripped = _strip_thinking_blocks_inplace(body) + assert stripped == 1 + # content 为空时插入占位 text block + assert body["messages"][0]["content"] == [ + {"type": "text", "text": "[thinking]"}, + ] + + def test_inserts_placeholder_when_all_thinking(self): + body = { + "messages": [ + { + "role": "user", + "content": "hi", + }, + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t1"}, + {"type": "redacted_thinking", "data": "r1"}, + ], + }, + ] + } + stripped = _strip_thinking_blocks_inplace(body) + assert stripped == 2 + assert body["messages"][1]["content"] == [ + {"type": "text", "text": "[thinking]"}, + ] + + def test_no_change_when_no_thinking(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [{"type": "text", "text": "hello"}], + }, + ] + } + stripped = _strip_thinking_blocks_inplace(body) + assert stripped == 0 + assert body["messages"][0]["content"] == [{"type": "text", "text": "hello"}] + + def test_skips_non_assistant_messages(self): + body = { + "messages": [ + {"role": "user", "content": [{"type": "thinking", "thinking": "t"}]}, + ] + } + stripped = _strip_thinking_blocks_inplace(body) + assert stripped == 0 + + def test_handles_string_content(self): + body = { + "messages": [ + {"role": "assistant", "content": "plain text"}, + ] + } + stripped = _strip_thinking_blocks_inplace(body) + assert stripped == 0 + + +class TestStripCacheControl: + """_strip_cache_control 单元测试.""" + + def test_removes_cache_control_from_system(self): + body = { + "system": [ + { + "type": "text", + "text": "prompt", + "cache_control": {"type": "ephemeral"}, + }, + ], + "messages": [], + } + removed = _strip_cache_control(body) + assert removed == 1 + assert "cache_control" not in body["system"][0] + + def test_removes_cache_control_from_messages(self): + body = { + "messages": [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "hi", + "cache_control": {"type": "ephemeral"}, + }, + ], + }, + ], + } + removed = _strip_cache_control(body) + assert removed == 1 + assert "cache_control" not in body["messages"][0]["content"][0] + + def test_removes_cache_control_from_tools(self): + body = { + "messages": [], + "tools": [ + { + "name": "bash", + "input_schema": {}, + "cache_control": {"type": "ephemeral"}, + }, + ], + } + removed = _strip_cache_control(body) + assert removed == 1 + assert "cache_control" not in body["tools"][0] + + def test_removes_from_all_locations(self): + body = { + "system": [ + {"type": "text", "text": "sys", "cache_control": {"type": "ephemeral"}}, + ], + "messages": [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "msg", + "cache_control": {"type": "ephemeral"}, + }, + ], + }, + ], + "tools": [ + { + "name": "bash", + "input_schema": {}, + "cache_control": {"type": "ephemeral"}, + }, + ], + } + removed = _strip_cache_control(body) + assert removed == 3 + + def test_no_change_when_no_cache_control(self): + body = { + "system": [{"type": "text", "text": "sys"}], + "messages": [{"role": "user", "content": "hi"}], + "tools": [{"name": "bash", "input_schema": {}}], + } + removed = _strip_cache_control(body) + assert removed == 0 + + +# ── zhipu 通道测试 ──────────────────────────────────────────── + + +class TestZhipuChannel: + """prepare_for_zhipu 通道单元测试.""" + + def test_strips_thinking_blocks(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "thought", "signature": "sig"}, + {"type": "text", "text": "response"}, + ], + }, + ], + } + prepared, adaptations = prepare_for_zhipu(body) + assert any("thinking_blocks" in a for a in adaptations) + assert prepared["messages"][0]["content"] == [ + {"type": "text", "text": "response"}, + ] + # 原始 body 未被修改 + assert body["messages"][0]["content"][0]["type"] == "thinking" + + def test_removes_cache_control(self): + body = { + "system": [ + {"type": "text", "text": "sys", "cache_control": {"type": "ephemeral"}}, + ], + "messages": [], + } + prepared, adaptations = prepare_for_zhipu(body) + assert any("cache_control" in a for a in adaptations) + assert "cache_control" not in prepared["system"][0] + + def test_removes_thinking_params(self): + body = { + "messages": [], + "thinking": {"type": "enabled", "budget_tokens": 10000}, + "extended_thinking": {"type": "enabled"}, + } + prepared, adaptations = prepare_for_zhipu(body) + assert "thinking" not in prepared + assert "extended_thinking" not in prepared + assert "removed_thinking_param" in adaptations + assert "removed_extended_thinking_param" in adaptations + + def test_enforces_tool_pairing(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_1", + "name": "bash", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "next turn", + }, + ], + } + prepared, adaptations = prepare_for_zhipu(body) + # tool_use should have a corresponding tool_result + user_content = prepared["messages"][1]["content"] + tool_results = [ + b + for b in user_content + if isinstance(b, dict) and b.get("type") == "tool_result" + ] + assert len(tool_results) == 1 + assert tool_results[0]["tool_use_id"] == "toolu_1" + + def test_combined_transformations(self): + body = { + "system": [ + {"type": "text", "text": "sys", "cache_control": {"type": "ephemeral"}}, + ], + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "thought", "signature": "sig"}, + { + "type": "tool_use", + "id": "toolu_1", + "name": "bash", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "ok", + }, + ], + "thinking": {"type": "enabled", "budget_tokens": 10000}, + } + prepared, adaptations = prepare_for_zhipu(body) + # thinking blocks stripped + assert all( + b.get("type") not in ("thinking", "redacted_thinking") + for b in prepared["messages"][0]["content"] + ) + # cache_control removed + assert "cache_control" not in prepared["system"][0] + # thinking param removed + assert "thinking" not in prepared + # tool pairing enforced + user_content = prepared["messages"][1]["content"] + tool_results = [ + b + for b in user_content + if isinstance(b, dict) and b.get("type") == "tool_result" + ] + assert len(tool_results) == 1 + + def test_preserves_original_body(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t"}, + {"type": "text", "text": "hi"}, + ], + }, + ], + "thinking": {"type": "enabled"}, + } + original = copy.deepcopy(body) + prepare_for_zhipu(body) + assert body == original + + def test_noop_when_clean(self): + body = { + "messages": [ + {"role": "user", "content": "hello"}, + {"role": "assistant", "content": [{"type": "text", "text": "hi"}]}, + ], + } + prepared, adaptations = prepare_for_zhipu(body) + assert adaptations == [] + assert prepared == body + + def test_idempotency(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t"}, + { + "type": "tool_use", + "id": "toolu_1", + "name": "bash", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "ok", + }, + ], + "thinking": {"type": "enabled"}, + } + prepared1, adaptations1 = prepare_for_zhipu(body) + prepared2, adaptations2 = prepare_for_zhipu(prepared1) + assert prepared2 == prepared1 + assert adaptations2 == [] + + +# ── copilot 通道测试 ────────────────────────────────────────── + + +class TestCopilotChannel: + """prepare_for_copilot 通道单元测试.""" + + def test_strips_thinking_blocks(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "thought", "signature": "sig"}, + {"type": "text", "text": "response"}, + ], + }, + ], + } + prepared, adaptations = prepare_for_copilot(body) + assert any("thinking_blocks" in a for a in adaptations) + assert prepared["messages"][0]["content"] == [ + {"type": "text", "text": "response"}, + ] + + def test_removes_cache_control(self): + body = { + "messages": [ + { + "role": "user", + "content": [ + { + "type": "text", + "text": "hi", + "cache_control": {"type": "ephemeral"}, + }, + ], + }, + ], + } + prepared, adaptations = prepare_for_copilot(body) + assert any("cache_control" in a for a in adaptations) + assert "cache_control" not in prepared["messages"][0]["content"][0] + + def test_preserves_thinking_param(self): + """copilot 通道不移除顶层 thinking 参数(由 converter 自行映射).""" + body = { + "messages": [], + "thinking": {"type": "enabled", "budget_tokens": 10000}, + } + prepared, adaptations = prepare_for_copilot(body) + assert "thinking" in prepared + assert "removed_thinking_param" not in adaptations + + def test_enforces_tool_pairing(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_1", + "name": "read", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "next", + }, + ], + } + prepared, adaptations = prepare_for_copilot(body) + user_content = prepared["messages"][1]["content"] + tool_results = [ + b + for b in user_content + if isinstance(b, dict) and b.get("type") == "tool_result" + ] + assert len(tool_results) == 1 + + def test_preserves_original_body(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t"}, + {"type": "text", "text": "hi"}, + ], + }, + ], + } + original = copy.deepcopy(body) + prepare_for_copilot(body) + assert body == original + + def test_noop_when_clean(self): + body = { + "messages": [ + {"role": "user", "content": "hello"}, + {"role": "assistant", "content": [{"type": "text", "text": "hi"}]}, + ], + } + prepared, adaptations = prepare_for_copilot(body) + assert adaptations == [] + assert prepared == body + + def test_idempotency(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t"}, + { + "type": "tool_use", + "id": "toolu_1", + "name": "bash", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "ok", + }, + ], + } + prepared1, _ = prepare_for_copilot(body) + prepared2, adaptations2 = prepare_for_copilot(prepared1) + assert prepared2 == prepared1 + assert adaptations2 == [] + + def test_strips_redacted_thinking(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "redacted_thinking", "data": "redacted"}, + {"type": "text", "text": "response"}, + ], + }, + ], + } + prepared, adaptations = prepare_for_copilot(body) + assert any("thinking_blocks" in a for a in adaptations) + assert prepared["messages"][0]["content"] == [ + {"type": "text", "text": "response"}, + ] + + +# ── zhipu vs copilot 通道差异测试 ──────────────────────────── + + +class TestChannelDifferences: + """验证 zhipu 和 copilot 通道的关键行为差异.""" + + def test_zhipu_removes_thinking_param_copilot_preserves(self): + body = { + "messages": [], + "thinking": {"type": "enabled", "budget_tokens": 5000}, + } + zhipu_result, zhipu_adapt = prepare_for_zhipu(body) + copilot_result, copilot_adapt = prepare_for_copilot(body) + + assert "thinking" not in zhipu_result + assert "removed_thinking_param" in zhipu_adapt + + assert "thinking" in copilot_result + assert "removed_thinking_param" not in copilot_adapt + + def test_both_strip_thinking_blocks(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t"}, + {"type": "text", "text": "hi"}, + ], + }, + ], + } + zhipu_result, _ = prepare_for_zhipu(body) + copilot_result, _ = prepare_for_copilot(body) + + # 两者都剥离 thinking blocks + assert zhipu_result["messages"][0]["content"] == [ + {"type": "text", "text": "hi"} + ] + assert copilot_result["messages"][0]["content"] == [ + {"type": "text", "text": "hi"} + ] From 3d4dc54e8905e3d8088ad6387432206d595bcb7d Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 08:51:07 +0800 Subject: [PATCH 24/32] =?UTF-8?q?refactor(vendor-channels):=20=E5=90=88?= =?UTF-8?q?=E5=B9=B6=20anthropic=20=E9=80=9A=E9=81=93=E5=88=B0=20vendor=5F?= =?UTF-8?q?channels=20=E6=B3=A8=E5=86=8C=E8=A1=A8=EF=BC=8C=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E6=89=80=E6=9C=89=E4=BE=9B=E5=BA=94=E5=95=86=E8=BD=AC?= =?UTF-8?q?=E6=8D=A2=E9=80=9A=E9=81=93=E7=9A=84=E5=A4=9A=E6=80=81=E7=BB=B4?= =?UTF-8?q?=E6=8A=A4;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 prepare_for_anthropic() 到 vendor_channels.py,将 executor 中的内联 anthropic 逻辑收敛至专属通道; - 新增 VENDOR_CHANNELS 注册表 + get_channel() 查表接口,executor 通过注册表分发,不感知具体供应商; - 统一触发条件:扩展 _needs_vendor_channel() 吸收 has_anthropic_fixes 信号,替代已移除的 _needs_tool_pairing_enforcement / _needs_thinking_strip; - executor._prepare_body_for_tier() 简化为注册表查表模式,移除 copy import; - 新增 12 个测试:anthropic 通道(7 个)+ 注册表(4 个)+ has_anthropic_fixes 信号(1 个); - 全量 1269 测试通过,0 失败; 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/convert/vendor_channels.py | 68 ++++++- src/coding/proxy/routing/executor.py | 143 +++------------ tests/test_router_executor.py | 60 +++++-- tests/test_vendor_channels.py | 187 ++++++++++++++++++++ 4 files changed, 321 insertions(+), 137 deletions(-) diff --git a/src/coding/proxy/convert/vendor_channels.py b/src/coding/proxy/convert/vendor_channels.py index d78bdfa..b6aeade 100644 --- a/src/coding/proxy/convert/vendor_channels.py +++ b/src/coding/proxy/convert/vendor_channels.py @@ -3,24 +3,37 @@ 每个通道函数接收标准化的 Anthropic 格式请求体,返回针对目标供应商 调整后的请求体(深拷贝)。通道函数之间无依赖关系,可独立测试。 -通道触发条件由 executor 层根据会话历史和规范化信号判断。 +通道注册表 ``VENDOR_CHANNELS`` 提供统一的 tier_name → channel_fn 映射, +executor 层通过 ``get_channel()`` 查表分发,无需感知具体供应商。 通道矩阵: - zhipu → copilot : prepare_for_copilot (剥离 thinking + cache_control + tool pairing) - copilot → zhipu : prepare_for_zhipu (剥离 thinking + cache_control + tool pairing + 移除 thinking 参数) - * → anthropic : executor 现有逻辑 (enforce_anthropic_tool_pairing + 条件 thinking strip) + anthropic : prepare_for_anthropic (tool pairing + 条件 thinking strip) + zhipu : prepare_for_zhipu (剥离 thinking + cache_control + tool pairing + 移除 thinking 参数) + copilot : prepare_for_copilot (剥离 thinking + cache_control + tool pairing) """ from __future__ import annotations import copy import logging +from collections.abc import Callable from typing import Any logger = logging.getLogger(__name__) _THINKING_BLOCK_TYPES = {"thinking", "redacted_thinking"} +# ── 通道注册表 ──────────────────────────────────────────────── +# tier_name → (body) → (prepared_body, adaptations) +VENDOR_CHANNELS: dict[ + str, Callable[[dict[str, Any]], tuple[dict[str, Any], list[str]]] +] = {} + + +def get_channel(tier_name: str) -> Callable | None: + """查找供应商专属通道函数,不存在时返回 None.""" + return VENDOR_CHANNELS.get(tier_name) + # ── 共享辅助函数 ────────────────────────────────────────────── @@ -181,3 +194,50 @@ def prepare_for_copilot(body: dict[str, Any]) -> tuple[dict[str, Any], list[str] adaptations.extend(pairing_fixes) return prepared, adaptations + + +# ── anthropic 专属转换通道 ───────────────────────────────────── + + +def prepare_for_anthropic(body: dict[str, Any]) -> tuple[dict[str, Any], list[str]]: + """anthropic 专属转换通道: tool pairing + 条件 thinking strip. + + Anthropic API 要求: + - 每个 tool_use 必须在紧随的 user 消息中有对应 tool_result + - thinking blocks 的 signature 必须是 Anthropic 签发(跨供应商后无效) + + 此通道执行两项变换: + 1. enforce_anthropic_tool_pairing: 单遍正向扫描修复配对 + 2. strip_thinking_blocks: 移除非 Anthropic 签发的 thinking 块 + + 两项变换均为幂等操作,安全地在已清理的请求体上重复执行。 + + Returns: + (prepared_body, adaptations) — adaptations 为应用的变换描述列表。 + """ + from ..server.request_normalizer import ( + enforce_anthropic_tool_pairing, + strip_thinking_blocks, + ) + + prepared = copy.deepcopy(body) + adaptations: list[str] = [] + + # Step 1: 强制 tool_use/tool_result 配对 + pairing_fixes = enforce_anthropic_tool_pairing(prepared.get("messages", [])) + if pairing_fixes: + adaptations.extend(pairing_fixes) + + # Step 2: 剥离 thinking blocks(跨供应商 signature 无效) + stripped = strip_thinking_blocks(prepared) + if stripped: + adaptations.append(f"stripped_{stripped}_thinking_blocks") + + return prepared, adaptations + + +# ── 注册所有通道 ────────────────────────────────────────────── + +VENDOR_CHANNELS["anthropic"] = prepare_for_anthropic +VENDOR_CHANNELS["zhipu"] = prepare_for_zhipu +VENDOR_CHANNELS["copilot"] = prepare_for_copilot diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index 24bef17..6dc3254 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -6,7 +6,6 @@ from __future__ import annotations -import copy import logging import time from collections.abc import AsyncIterator @@ -232,71 +231,26 @@ def _prepare_body_for_tier( ) -> dict[str, Any]: """为指定 tier 准备请求体,应用供应商专属转换通道 (Phase 2). - 通道路由: - - zhipu / copilot: 委托 vendor_channels 专属通道 - - anthropic: 保留现有 tool pairing + 条件 thinking strip 逻辑 - - 其他: 原样返回 + 通过 vendor_channels 注册表统一分发,executor 不感知具体供应商逻辑。 + 未注册通道的 tier 原样返回请求体。 """ - # ── zhipu / copilot: 供应商专属转换通道 ── - from ..convert.vendor_channels import prepare_for_copilot, prepare_for_zhipu - - channel_fn = None - if tier.name == "zhipu": - channel_fn = prepare_for_zhipu - elif tier.name == "copilot": - channel_fn = prepare_for_copilot - - if channel_fn is not None: - if not self._needs_vendor_channel(tier.name, normalization, session_record): - return body - prepared, adaptations = channel_fn(body) - if adaptations: - logger.debug( - "Applied vendor channel for tier %s: %s", - tier.name, - ", ".join(adaptations), - ) - return prepared + from ..convert.vendor_channels import get_channel - # ── anthropic: 保留现有逻辑 ── - if tier.name != "anthropic": + channel_fn = get_channel(tier.name) + if channel_fn is None: return body - needs_tool_pairing = self._needs_tool_pairing_enforcement( - normalization, session_record - ) - needs_thinking_strip = self._needs_thinking_strip(normalization, session_record) - - if not needs_tool_pairing and not needs_thinking_strip: + if not self._needs_vendor_channel(tier.name, normalization, session_record): return body - from ..server.request_normalizer import ( - enforce_anthropic_tool_pairing, - strip_thinking_blocks, - ) - - body_for_vendor = copy.deepcopy(body) - - if needs_tool_pairing: - fixes = enforce_anthropic_tool_pairing( - body_for_vendor.get("messages", []), + prepared, adaptations = channel_fn(body) + if adaptations: + logger.debug( + "Applied vendor channel for tier %s: %s", + tier.name, + ", ".join(adaptations), ) - if fixes: - logger.debug( - "Applied tool pairing enforcement for tier %s: %s", - tier.name, - ", ".join(fixes), - ) - - if needs_thinking_strip: - stripped = strip_thinking_blocks(body_for_vendor) - if stripped: - logger.debug( - "Stripped %d thinking block(s) for cross-vendor compatibility", - stripped, - ) - - return body_for_vendor + return prepared @staticmethod def _needs_vendor_channel( @@ -308,81 +262,24 @@ def _needs_vendor_channel( 触发信号(满足任一): 1. normalization 检测到跨供应商产物 - 2. 无会话追踪能力 → 安全回退 - 3. 会话历史中存在非当前供应商记录 + 2. normalization 检测到 Anthropic 修复需求(misplaced tool_result / ID 重写) + 3. 无会话追踪能力 → 安全回退 + 4. 会话历史中存在非当前供应商记录 """ # Signal 1: 跨供应商信号 if normalization is not None and normalization.has_cross_vendor_signals: return True - # Signal 2: 无会话追踪 → 安全回退 - if session_record is None: - return True - # Signal 3: 会话历史中有非当前供应商 - if session_record.provider_state: - non_current = {v for v in session_record.provider_state if v != tier_name} - if non_current: - return True - return False - - @staticmethod - def _needs_tool_pairing_enforcement( - normalization: Any, session_record: Any - ) -> bool: - """判断是否需要强制执行 Anthropic tool_use/tool_result 配对修复. - - 此方法扩展了原有 ``has_anthropic_fixes`` 的触发条件,覆盖以下场景: - - 1. 请求体中检测到跨供应商产物(如非标准 ID、misplaced tool_result) - 2. Phase 1 检测到需要 Anthropic 修复(misplaced 或 ID 重写) - 3. 会话历史中存在非 Anthropic 供应商记录(如 zhipu) - 4. 无会话追踪能力时安全回退 - - 条件 3 和 4 确保即使请求体本身无跨供应商产物(如 zhipu 使用标准 - ``toolu_*`` ID 时),只要会话曾经过非 Anthropic 供应商,仍会执行配对修复。 - """ - # Signal 1: 当前请求体有跨供应商产物 - if normalization is not None and normalization.has_cross_vendor_signals: - return True - # Signal 2: Phase 1 检测到需要 Anthropic 修复 + # Signal 2: Phase 1 检测到 Anthropic 修复需求 if normalization is not None and normalization.has_anthropic_fixes: return True # Signal 3: 无会话追踪 → 安全回退 if session_record is None: return True - # Signal 4: 会话历史中有非 Anthropic 供应商 + # Signal 4: 会话历史中有非当前供应商 if session_record.provider_state: - non_anthropic = { - v for v in session_record.provider_state if v != "anthropic" - } - if non_anthropic: - return True - return False - - @staticmethod - def _needs_thinking_strip(normalization: Any, session_record: Any) -> bool: - """判断是否需要剥离 thinking blocks(仅跨供应商场景). - - 信号优先级: - 1. 请求规范化信号 — 当前请求体中检测到跨供应商产物 - 2. 会话历史信号 — provider_state 中存在非 Anthropic 供应商记录 - - 安全默认:当无法确定会话来源时(session_record 为 None), - 回退到始终剥离,确保与 compat_session_store 未配置时的向后兼容。 - """ - # Signal 1: normalization 检测到跨供应商产物 - if normalization is not None and normalization.has_cross_vendor_signals: - return True - # Signal 2: 无会话追踪能力 → 无法判断是否跨供应商 → 安全回退到剥离 - if session_record is None: - return True - # Signal 3: 会话历史中有非 Anthropic 供应商 - if session_record.provider_state: - non_anthropic = { - v for v in session_record.provider_state if v != "anthropic" - } - if non_anthropic: + non_current = {v for v in session_record.provider_state if v != tier_name} + if non_current: return True - # 纯 Anthropic 会话,无跨供应商信号 → 保留 thinking blocks return False async def execute_stream( diff --git a/tests/test_router_executor.py b/tests/test_router_executor.py index f0043e2..bc5f2c3 100644 --- a/tests/test_router_executor.py +++ b/tests/test_router_executor.py @@ -1552,65 +1552,100 @@ async def test_non_last_tier_500_still_failovers(self): assert good.send_message.called -# ── _needs_thinking_strip 条件判断测试 ────────────────────────── +# ── _needs_vendor_channel 条件判断测试 ────────────────────────── -class TestNeedsThinkingStrip: - """验证 _RouteExecutor._needs_thinking_strip 静态方法.""" +class TestNeedsVendorChannel: + """验证 _RouteExecutor._needs_vendor_channel 静态方法.""" def test_true_when_normalization_has_cross_vendor_signals(self): """normalization 有跨供应商信号时返回 True.""" normalization = MagicMock() normalization.has_cross_vendor_signals = True + normalization.has_anthropic_fixes = False + session_record = MagicMock() + session_record.provider_state = {"anthropic": {}} + + assert ( + _RouteExecutor._needs_vendor_channel( + "anthropic", normalization, session_record + ) + is True + ) + + def test_true_when_normalization_has_anthropic_fixes(self): + """Phase 1 检测到 Anthropic 修复需求时返回 True.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = True session_record = MagicMock() session_record.provider_state = {"anthropic": {}} assert ( - _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + _RouteExecutor._needs_vendor_channel( + "anthropic", normalization, session_record + ) + is True ) def test_true_when_session_record_is_none(self): """session_record 为 None 时安全回退到 True.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False - assert _RouteExecutor._needs_thinking_strip(normalization, None) is True + assert ( + _RouteExecutor._needs_vendor_channel("anthropic", normalization, None) + is True + ) def test_true_when_no_normalization_and_no_session(self): """normalization 和 session_record 均为 None 时返回 True.""" - assert _RouteExecutor._needs_thinking_strip(None, None) is True + assert _RouteExecutor._needs_vendor_channel("anthropic", None, None) is True def test_true_when_session_has_non_anthropic_vendor(self): """会话历史中有非 Anthropic 供应商时返回 True.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False session_record = MagicMock() session_record.provider_state = {"anthropic": {}, "zhipu": {}} assert ( - _RouteExecutor._needs_thinking_strip(normalization, session_record) is True + _RouteExecutor._needs_vendor_channel( + "anthropic", normalization, session_record + ) + is True ) def test_false_when_anthropic_only_session(self): """纯 Anthropic 会话且无跨供应商信号时返回 False.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False session_record = MagicMock() session_record.provider_state = {"anthropic": {"compat_mode": "native"}} assert ( - _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + _RouteExecutor._needs_vendor_channel( + "anthropic", normalization, session_record + ) + is False ) def test_false_when_empty_provider_state(self): """空 provider_state(首次请求)且无跨供应商信号时返回 False.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False session_record = MagicMock() session_record.provider_state = {} assert ( - _RouteExecutor._needs_thinking_strip(normalization, session_record) is False + _RouteExecutor._needs_vendor_channel( + "anthropic", normalization, session_record + ) + is False ) def test_true_when_normalization_none_but_session_has_non_anthropic(self): @@ -1618,7 +1653,10 @@ def test_true_when_normalization_none_but_session_has_non_anthropic(self): session_record = MagicMock() session_record.provider_state = {"copilot": {}} - assert _RouteExecutor._needs_thinking_strip(None, session_record) is True + assert ( + _RouteExecutor._needs_vendor_channel("anthropic", None, session_record) + is True + ) # ── _prepare_body_for_tier 条件化 thinking 剥离测试 ──────────────── @@ -1746,6 +1784,7 @@ def test_zhipu_tier_applies_channel_when_cross_vendor(self): """zhipu tier 在跨供应商场景下应用专属转换通道.""" normalization = MagicMock() normalization.has_cross_vendor_signals = True + normalization.has_anthropic_fixes = False tier = MagicMock() tier.name = "zhipu" @@ -1765,6 +1804,7 @@ def test_zhipu_tier_skips_channel_in_pure_session(self): """zhipu tier 在纯 zhipu 会话中不触发专属通道.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False tier = MagicMock() tier.name = "zhipu" diff --git a/tests/test_vendor_channels.py b/tests/test_vendor_channels.py index 7a82c12..248cbc0 100644 --- a/tests/test_vendor_channels.py +++ b/tests/test_vendor_channels.py @@ -1,9 +1,11 @@ """供应商专属转换通道单元测试. 覆盖 :mod:`coding.proxy.convert.vendor_channels` 的通道函数和辅助函数: +- anthropic 通道 (prepare_for_anthropic) - zhipu 通道 (prepare_for_zhipu) - copilot 通道 (prepare_for_copilot) - 共享辅助函数 (_strip_thinking_blocks_inplace, _strip_cache_control) +- 通道注册表 (VENDOR_CHANNELS, get_channel) """ from __future__ import annotations @@ -11,8 +13,11 @@ import copy from coding.proxy.convert.vendor_channels import ( + VENDOR_CHANNELS, _strip_cache_control, _strip_thinking_blocks_inplace, + get_channel, + prepare_for_anthropic, prepare_for_copilot, prepare_for_zhipu, ) @@ -383,6 +388,188 @@ def test_idempotency(self): assert adaptations2 == [] +# ── anthropic 通道测试 ──────────────────────────────────────── + + +class TestAnthropicChannel: + """prepare_for_anthropic 通道单元测试.""" + + def test_enforces_tool_pairing(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_1", + "name": "bash", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "next turn", + }, + ], + } + prepared, adaptations = prepare_for_anthropic(body) + user_content = prepared["messages"][1]["content"] + tool_results = [ + b + for b in user_content + if isinstance(b, dict) and b.get("type") == "tool_result" + ] + assert len(tool_results) == 1 + assert tool_results[0]["tool_use_id"] == "toolu_1" + + def test_strips_thinking_blocks(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "thought", "signature": "sig"}, + {"type": "text", "text": "response"}, + ], + }, + ], + } + prepared, adaptations = prepare_for_anthropic(body) + assert any("thinking_blocks" in a for a in adaptations) + assert prepared["messages"][0]["content"] == [ + {"type": "text", "text": "response"} + ] + + def test_combined_tool_pairing_and_thinking_strip(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t", "signature": "s"}, + { + "type": "tool_use", + "id": "toolu_1", + "name": "bash", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "ok", + }, + ], + } + prepared, adaptations = prepare_for_anthropic(body) + # thinking stripped + assert all( + b.get("type") not in ("thinking", "redacted_thinking") + for b in prepared["messages"][0]["content"] + ) + # tool pairing enforced + user_content = prepared["messages"][1]["content"] + tool_results = [ + b + for b in user_content + if isinstance(b, dict) and b.get("type") == "tool_result" + ] + assert len(tool_results) == 1 + + def test_preserves_original_body(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t"}, + {"type": "text", "text": "hi"}, + ], + }, + ], + } + original = copy.deepcopy(body) + prepare_for_anthropic(body) + assert body == original + + def test_noop_when_clean(self): + body = { + "messages": [ + {"role": "user", "content": "hello"}, + {"role": "assistant", "content": [{"type": "text", "text": "hi"}]}, + ], + } + prepared, adaptations = prepare_for_anthropic(body) + assert adaptations == [] + assert prepared == body + + def test_idempotency(self): + body = { + "messages": [ + { + "role": "assistant", + "content": [ + {"type": "thinking", "thinking": "t"}, + { + "type": "tool_use", + "id": "toolu_1", + "name": "bash", + "input": {}, + }, + ], + }, + { + "role": "user", + "content": "ok", + }, + ], + } + prepared1, _ = prepare_for_anthropic(body) + prepared2, adaptations2 = prepare_for_anthropic(prepared1) + assert prepared2 == prepared1 + assert adaptations2 == [] + + def test_preserves_thinking_param(self): + """anthropic 通道不移除顶层 thinking 参数(Anthropic API 支持).""" + body = { + "messages": [], + "thinking": {"type": "enabled", "budget_tokens": 5000}, + } + prepared, _ = prepare_for_anthropic(body) + assert "thinking" in prepared + + +# ── 注册表测试 ──────────────────────────────────────────────── + + +class TestChannelRegistry: + """通道注册表 VENDOR_CHANNELS / get_channel 单元测试.""" + + def test_all_channels_registered(self): + assert "anthropic" in VENDOR_CHANNELS + assert "zhipu" in VENDOR_CHANNELS + assert "copilot" in VENDOR_CHANNELS + + def test_get_channel_returns_function(self): + assert get_channel("anthropic") is prepare_for_anthropic + assert get_channel("zhipu") is prepare_for_zhipu + assert get_channel("copilot") is prepare_for_copilot + + def test_get_channel_returns_none_for_unknown(self): + assert get_channel("unknown") is None + assert get_channel("antigravity") is None + + def test_channel_functions_share_signature(self): + body = {"messages": []} + for name, fn in VENDOR_CHANNELS.items(): + result = fn(body) + assert isinstance(result, tuple) and len(result) == 2 + assert isinstance(result[0], dict) + assert isinstance(result[1], list) + + # ── copilot 通道测试 ────────────────────────────────────────── From 4daeba9b7f6becb1f41ad0b342b7518dad3d95af Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 09:02:07 +0800 Subject: [PATCH 25/32] =?UTF-8?q?fix(vendor-channels):=20=E5=8C=BA?= =?UTF-8?q?=E5=88=86=20anthropic=20=E5=AE=BD=E6=9D=BE=E8=A7=A6=E5=8F=91?= =?UTF-8?q?=E4=B8=8E=20zhipu/copilot=20=E4=B8=A5=E6=A0=BC=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=EF=BC=8C=E9=98=B2=E6=AD=A2=E7=BA=AF=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E8=AF=AF=E6=BF=80=E6=B4=BB=E9=80=9A=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit anthropic 通道保持原有宽松策略(Phase 1 信号 + 无会话回退 + 会话历史); zhipu/copilot 通道改为仅依赖会话历史(provider_state)确认跨供应商转换, 消除 Phase 1 信号(如 zhipu 自身 srvtoolu_* ID)在纯单供应商会话中误触 发通道导致不必要的请求体变换。 Co-Authored-By: Claude Opus 4.7 --- src/coding/proxy/routing/executor.py | 45 +++++---- tests/test_router_executor.py | 134 +++++++++++++++++++++++---- 2 files changed, 143 insertions(+), 36 deletions(-) diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index 6dc3254..55f72b8 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -260,23 +260,36 @@ def _needs_vendor_channel( ) -> bool: """判断是否需要为目标供应商触发专属转换通道. - 触发信号(满足任一): - 1. normalization 检测到跨供应商产物 - 2. normalization 检测到 Anthropic 修复需求(misplaced tool_result / ID 重写) - 3. 无会话追踪能力 → 安全回退 - 4. 会话历史中存在非当前供应商记录 + anthropic 通道(宽松触发): + Anthropic API 有严格的格式要求(tool pairing / thinking signature), + 即使纯会话中也需修复。触发信号: + 1. 跨供应商信号或 Anthropic 修复需求(Phase 1 信号) + 2. 无会话追踪 → 安全回退 + 3. 会话历史中存在非 Anthropic 供应商 + + zhipu/copilot 通道(严格触发): + Phase 1 信号 (has_cross_vendor_signals, has_anthropic_fixes) 不可靠—— + 纯 zhipu 会话中 zhipu 自身的产物(srvtoolu_* ID)也会触发。 + 唯一可靠指标是会话历史中存在非当前供应商。 """ - # Signal 1: 跨供应商信号 - if normalization is not None and normalization.has_cross_vendor_signals: - return True - # Signal 2: Phase 1 检测到 Anthropic 修复需求 - if normalization is not None and normalization.has_anthropic_fixes: - return True - # Signal 3: 无会话追踪 → 安全回退 - if session_record is None: - return True - # Signal 4: 会话历史中有非当前供应商 - if session_record.provider_state: + if tier_name == "anthropic": + # anthropic: 宽松触发 + if normalization is not None and normalization.has_cross_vendor_signals: + return True + if normalization is not None and normalization.has_anthropic_fixes: + return True + if session_record is None: + return True + if session_record.provider_state: + non_current = { + v for v in session_record.provider_state if v != "anthropic" + } + if non_current: + return True + return False + + # zhipu/copilot: 仅会话历史确认的跨供应商转换 + if session_record is not None and session_record.provider_state: non_current = {v for v in session_record.provider_state if v != tier_name} if non_current: return True diff --git a/tests/test_router_executor.py b/tests/test_router_executor.py index bc5f2c3..67420be 100644 --- a/tests/test_router_executor.py +++ b/tests/test_router_executor.py @@ -1556,10 +1556,16 @@ async def test_non_last_tier_500_still_failovers(self): class TestNeedsVendorChannel: - """验证 _RouteExecutor._needs_vendor_channel 静态方法.""" + """验证 _RouteExecutor._needs_vendor_channel 静态方法. - def test_true_when_normalization_has_cross_vendor_signals(self): - """normalization 有跨供应商信号时返回 True.""" + anthropic 采用宽松触发(Phase 1 信号 + 无会话回退 + 会话历史); + zhipu/copilot 采用严格触发(仅会话历史确认的跨供应商转换)。 + """ + + # ── anthropic 宽松触发 ── + + def test_anthropic_true_when_cross_vendor_signals(self): + """Phase 1 跨供应商信号 → anthropic 通道触发.""" normalization = MagicMock() normalization.has_cross_vendor_signals = True normalization.has_anthropic_fixes = False @@ -1573,8 +1579,8 @@ def test_true_when_normalization_has_cross_vendor_signals(self): is True ) - def test_true_when_normalization_has_anthropic_fixes(self): - """Phase 1 检测到 Anthropic 修复需求时返回 True.""" + def test_anthropic_true_when_anthropic_fixes(self): + """Phase 1 Anthropic 修复需求 → anthropic 通道触发.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False normalization.has_anthropic_fixes = True @@ -1588,8 +1594,8 @@ def test_true_when_normalization_has_anthropic_fixes(self): is True ) - def test_true_when_session_record_is_none(self): - """session_record 为 None 时安全回退到 True.""" + def test_anthropic_true_when_no_session_record(self): + """无会话记录 → anthropic 通道安全回退触发.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False normalization.has_anthropic_fixes = False @@ -1599,12 +1605,12 @@ def test_true_when_session_record_is_none(self): is True ) - def test_true_when_no_normalization_and_no_session(self): - """normalization 和 session_record 均为 None 时返回 True.""" + def test_anthropic_true_when_no_normalization_and_no_session(self): + """normalization 和 session_record 均为 None → anthropic 触发.""" assert _RouteExecutor._needs_vendor_channel("anthropic", None, None) is True - def test_true_when_session_has_non_anthropic_vendor(self): - """会话历史中有非 Anthropic 供应商时返回 True.""" + def test_anthropic_true_when_session_has_non_anthropic_vendor(self): + """会话历史中有非 Anthropic 供应商 → anthropic 通道触发.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False normalization.has_anthropic_fixes = False @@ -1618,8 +1624,8 @@ def test_true_when_session_has_non_anthropic_vendor(self): is True ) - def test_false_when_anthropic_only_session(self): - """纯 Anthropic 会话且无跨供应商信号时返回 False.""" + def test_anthropic_false_when_anthropic_only_session(self): + """纯 Anthropic 会话且无 Phase 1 信号 → anthropic 通道不触发.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False normalization.has_anthropic_fixes = False @@ -1633,8 +1639,8 @@ def test_false_when_anthropic_only_session(self): is False ) - def test_false_when_empty_provider_state(self): - """空 provider_state(首次请求)且无跨供应商信号时返回 False.""" + def test_anthropic_false_when_empty_provider_state(self): + """空 provider_state(首次请求)且无 Phase 1 信号 → anthropic 不触发.""" normalization = MagicMock() normalization.has_cross_vendor_signals = False normalization.has_anthropic_fixes = False @@ -1648,8 +1654,8 @@ def test_false_when_empty_provider_state(self): is False ) - def test_true_when_normalization_none_but_session_has_non_anthropic(self): - """normalization 为 None 但会话有非 Anthropic 供应商时返回 True.""" + def test_anthropic_true_when_normalization_none_but_session_has_other(self): + """normalization 为 None 但会话有非 Anthropic 供应商 → 触发.""" session_record = MagicMock() session_record.provider_state = {"copilot": {}} @@ -1658,6 +1664,91 @@ def test_true_when_normalization_none_but_session_has_non_anthropic(self): is True ) + # ── zhipu/copilot 严格触发 ── + + def test_zhipu_false_when_no_session_record(self): + """无会话记录 → zhipu 通道不触发(严格模式).""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = True + normalization.has_anthropic_fixes = True + + assert ( + _RouteExecutor._needs_vendor_channel("zhipu", normalization, None) is False + ) + + def test_zhipu_false_when_cross_vendor_signals_but_pure_session(self): + """Phase 1 有跨供应商信号,但纯 zhipu 会话 → zhipu 通道不触发. + + 核心场景:zhipu 自身产物(srvtoolu_* ID)触发 has_cross_vendor_signals, + 但实际是纯 zhipu 会话,不应错误触发通道。 + """ + normalization = MagicMock() + normalization.has_cross_vendor_signals = True + normalization.has_anthropic_fixes = True + session_record = MagicMock() + session_record.provider_state = {"zhipu": {}} + + assert ( + _RouteExecutor._needs_vendor_channel("zhipu", normalization, session_record) + is False + ) + + def test_zhipu_false_when_empty_provider_state(self): + """空 provider_state 且无 Phase 1 帮助 → zhipu 通道不触发.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False + session_record = MagicMock() + session_record.provider_state = {} + + assert ( + _RouteExecutor._needs_vendor_channel("zhipu", normalization, session_record) + is False + ) + + def test_zhipu_true_when_session_has_other_vendor(self): + """会话历史中有 copilot → zhipu 通道触发(跨供应商转换).""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False + session_record = MagicMock() + session_record.provider_state = {"copilot": {}, "zhipu": {}} + + assert ( + _RouteExecutor._needs_vendor_channel("zhipu", normalization, session_record) + is True + ) + + def test_copilot_true_when_session_has_other_vendor(self): + """会话历史中有 zhipu → copilot 通道触发(跨供应商转换).""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = False + normalization.has_anthropic_fixes = False + session_record = MagicMock() + session_record.provider_state = {"zhipu": {}, "copilot": {}} + + assert ( + _RouteExecutor._needs_vendor_channel( + "copilot", normalization, session_record + ) + is True + ) + + def test_copilot_false_when_pure_copilot_session(self): + """纯 copilot 会话即使有 Phase 1 信号也不触发.""" + normalization = MagicMock() + normalization.has_cross_vendor_signals = True + normalization.has_anthropic_fixes = True + session_record = MagicMock() + session_record.provider_state = {"copilot": {}} + + assert ( + _RouteExecutor._needs_vendor_channel( + "copilot", normalization, session_record + ) + is False + ) + # ── _prepare_body_for_tier 条件化 thinking 剥离测试 ──────────────── @@ -1781,18 +1872,21 @@ def test_skips_for_non_anthropic_tier(self): assert result is body # 原始 body 直接返回 def test_zhipu_tier_applies_channel_when_cross_vendor(self): - """zhipu tier 在跨供应商场景下应用专属转换通道.""" + """zhipu tier 在跨供应商场景(会话历史有 copilot)下应用专属转换通道.""" normalization = MagicMock() - normalization.has_cross_vendor_signals = True + normalization.has_cross_vendor_signals = False normalization.has_anthropic_fixes = False tier = MagicMock() tier.name = "zhipu" + session_record = MagicMock() + session_record.provider_state = {"copilot": {}, "zhipu": {}} + exec_inst = _executor([]) body = self._body_with_thinking() result = exec_inst._prepare_body_for_tier( - body, tier, normalization, session_record=None + body, tier, normalization, session_record=session_record ) # zhipu 通道剥离 thinking blocks + 移除 thinking 参数 From b82521c39de15467b368981e434e3177b1bfe57c Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 09:02:34 +0800 Subject: [PATCH 26/32] =?UTF-8?q?style(arch):=20=E7=BB=9F=E4=B8=80=20Markd?= =?UTF-8?q?own=20=E8=A1=A8=E6=A0=BC=E5=88=97=E5=AF=B9=E9=BD=90=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- docs/arch/config-reference.md | 100 ++++++++++++------------- docs/arch/convert.md | 36 ++++----- docs/arch/design-patterns.md | 40 +++++----- docs/arch/routing.md | 30 ++++---- docs/arch/testing.md | 136 +++++++++++++++++----------------- docs/arch/vendors.md | 54 +++++++------- 6 files changed, 198 insertions(+), 198 deletions(-) diff --git a/docs/arch/config-reference.md b/docs/arch/config-reference.md index 4f9f6bb..e550bec 100644 --- a/docs/arch/config-reference.md +++ b/docs/arch/config-reference.md @@ -12,13 +12,13 @@ 配置模型已从单体 `schema.py` 正交拆分为 5 个子模块: -| 子模块 | 文件 | 核心类型 | -| --------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **server** | [`config/server.py`](../../src/coding/proxy/config/server.py) | `ServerConfig`, `DatabaseConfig`, `LoggingConfig` | -| **vendors** | [`config/vendors.py`](../../src/coding/proxy/config/vendors.py) | `AnthropicConfig`, `CopilotConfig`, `AntigravityConfig`, `ZhipuConfig`, `MinimaxConfig`, `KimiConfig`, `DoubaoConfig`, `XiaomiConfig`, `AlibabaConfig` | -| **resiliency** | [`config/resiliency.py`](../../src/coding/proxy/config/resiliency.py) | `CircuitBreakerConfig`, `RetryConfig`, `FailoverConfig`, `QuotaGuardConfig` | -| **routing** | [`config/routing.py`](../../src/coding/proxy/config/routing.py) | `VendorType`, `VendorConfig`, `ModelMappingRule`, `ModelPricingEntry` | -| **auth_schema** | [`config/auth_schema.py`](../../src/coding/proxy/config/auth_schema.py) | `AuthConfig` | +| 子模块 | 文件 | 核心类型 | +| --------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **server** | [`config/server.py`](../../src/coding/proxy/config/server.py) | `ServerConfig`, `DatabaseConfig`, `LoggingConfig` | +| **vendors** | [`config/vendors.py`](../../src/coding/proxy/config/vendors.py) | `AnthropicConfig`, `CopilotConfig`, `AntigravityConfig`, `ZhipuConfig`, `MinimaxConfig`, `KimiConfig`, `DoubaoConfig`, `XiaomiConfig`, `AlibabaConfig` | +| **resiliency** | [`config/resiliency.py`](../../src/coding/proxy/config/resiliency.py) | `CircuitBreakerConfig`, `RetryConfig`, `FailoverConfig`, `QuotaGuardConfig` | +| **routing** | [`config/routing.py`](../../src/coding/proxy/config/routing.py) | `VendorType`, `VendorConfig`, `ModelMappingRule`, `ModelPricingEntry` | +| **auth_schema** | [`config/auth_schema.py`](../../src/coding/proxy/config/auth_schema.py) | `AuthConfig` | `config/schema.py` 作为聚合入口点 re-export 所有符号,并保留 `ProxyConfig` 顶层模型及旧格式迁移逻辑。 @@ -61,12 +61,12 @@ flowchart TD ### 3.3 LoggingConfig -| 字段 | 类型 | 默认值 | 说明 | -| -------------- | ----------- | -------- | ------------------------------------------------------------ | -| `level` | str | `"INFO"` | 控制台日志级别 | -| `file` | str \| null | `null` | 文件日志路径(`null` 时输出到控制台) | -| `max_bytes` | int | `5242880` | 单个日志文件最大字节数(5 MB),触发轮转 | -| `backup_count` | int | `5` | 保留的已压缩备份文件数 | +| 字段 | 类型 | 默认值 | 说明 | +| -------------- | ----------- | --------- | ---------------------------------------- | +| `level` | str | `"INFO"` | 控制台日志级别 | +| `file` | str \| null | `null` | 文件日志路径(`null` 时输出到控制台) | +| `max_bytes` | int | `5242880` | 单个日志文件最大字节数(5 MB),触发轮转 | +| `backup_count` | int | `5` | 保留的已压缩备份文件数 | ### 3.4 AuthConfig @@ -78,12 +78,12 @@ flowchart TD ## 4. VendorConfig 通用字段 -| 字段 | 类型 | 默认值 | 说明 | -| ------------ | ---- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `vendor` | enum | -- | 供应商类型:`anthropic` / `copilot` / `antigravity` / `zhipu` / `minimax` / `kimi` / `doubao` / `xiaomi` / `alibaba` | -| `enabled` | bool | `true` | 是否启用 | -| `base_url` | str | `""` | API 基础 URL(留空使用各供应商默认值) | -| `timeout_ms` | int | `300000` | 请求超时(毫秒) | +| 字段 | 类型 | 默认值 | 说明 | +| ------------ | ---- | -------- | -------------------------------------------------------------------------------------------------------------------- | +| `vendor` | enum | -- | 供应商类型:`anthropic` / `copilot` / `antigravity` / `zhipu` / `minimax` / `kimi` / `doubao` / `xiaomi` / `alibaba` | +| `enabled` | bool | `true` | 是否启用 | +| `base_url` | str | `""` | API 基础 URL(留空使用各供应商默认值) | +| `timeout_ms` | int | `300000` | 请求超时(毫秒) | --- @@ -102,12 +102,12 @@ flowchart TD > **设计语义**:参见 [设计模式 -- Circuit Breaker](./design-patterns.md#circuit-breaker) -| 字段 | 类型 | 默认值 | 说明 | -| -------------------------- | ---- | ------ | -------------------------------- | -| `failure_threshold` | int | `3` | 触发 OPEN 的连续失败次数 | -| `recovery_timeout_seconds` | int | `300` | OPEN → HALF_OPEN 等待秒数 | +| 字段 | 类型 | 默认值 | 说明 | +| -------------------------- | ---- | ------ | --------------------------------- | +| `failure_threshold` | int | `3` | 触发 OPEN 的连续失败次数 | +| `recovery_timeout_seconds` | int | `300` | OPEN → HALF_OPEN 等待秒数 | | `success_threshold` | int | `2` | HALF_OPEN → CLOSED 所需连续成功数 | -| `max_recovery_seconds` | int | `3600` | 指数退避最大恢复时间(秒) | +| `max_recovery_seconds` | int | `3600` | 指数退避最大恢复时间(秒) | ### 5.2 QuotaGuardConfig — 配额守卫参数 @@ -125,23 +125,23 @@ flowchart TD > **设计语义**:参见 [设计模式 -- Retry with Full Jitter](./design-patterns.md#retry) -| 字段 | 类型 | 默认值 | 说明 | -| -------------------- | ----- | ------ | ------------ | -| `max_retries` | int | `2` | 最大重试次数 | -| `initial_delay_ms` | int | `500` | 初始延迟(毫秒) | -| `max_delay_ms` | int | `5000` | 最大延迟(毫秒) | -| `backoff_multiplier` | float | `2.0` | 退避倍数 | -| `jitter` | bool | `true` | 是否启用抖动 | +| 字段 | 类型 | 默认值 | 说明 | +| -------------------- | ----- | ------ | ---------------- | +| `max_retries` | int | `2` | 最大重试次数 | +| `initial_delay_ms` | int | `500` | 初始延迟(毫秒) | +| `max_delay_ms` | int | `5000` | 最大延迟(毫秒) | +| `backoff_multiplier` | float | `2.0` | 退避倍数 | +| `jitter` | bool | `true` | 是否启用抖动 | ### 5.4 FailoverConfig — 故障转移参数 > **设计语义**:参见 [请求生命周期 -- 故障转移判定](../framework.md#fault-overhead) -| 字段 | 类型 | 默认值 | -| ------------------------- | ------------ | ----------------------------------------------- | -| `status_codes` | list[int] | `[429, 403, 503, 500, 529]` | -| `error_types` | list[str] | `["rate_limit_error", "overloaded_error", "api_error"]` | -| `error_message_patterns` | list[str] | `["quota", "limit exceeded", "usage cap", "capacity", "internal network failure"]` | +| 字段 | 类型 | 默认值 | +| ------------------------ | --------- | ---------------------------------------------------------------------------------- | +| `status_codes` | list[int] | `[429, 403, 503, 500, 529]` | +| `error_types` | list[str] | `["rate_limit_error", "overloaded_error", "api_error"]` | +| `error_message_patterns` | list[str] | `["quota", "limit exceeded", "usage cap", "capacity", "internal network failure"]` | --- @@ -169,9 +169,9 @@ flowchart TD 适用于 `zhipu` / `minimax` / `kimi` / `doubao` / `xiaomi` / `alibaba`。 -| 字段 | 类型 | 默认值 | 说明 | -| --------- | ---- | ------ | ------------------------------ | -| `api_key` | str | `""` | API Key(支持 `${ENV_VAR}`) | +| 字段 | 类型 | 默认值 | 说明 | +| --------- | ---- | ------ | ---------------------------- | +| `api_key` | str | `""` | API Key(支持 `${ENV_VAR}`) | --- @@ -188,22 +188,22 @@ flowchart TD ### 7.2 ModelPricingEntry 字段 -| 字段 | 类型 | 说明 | -| --------------------------- | ----- | ---------------------------------------------------- | -| `vendor` | str | 供应商名称 | -| `model` | str | 实际模型名 | -| `input_cost_per_mtok` | float | 输入 Token 单价($/百万 token,支持 `$`/`¥` 前缀) | -| `output_cost_per_mtok` | float | 输出 Token 单价 | -| `cache_write_cost_per_mtok` | float | 缓存创建 Token 单价 | -| `cache_read_cost_per_mtok` | float | 缓存读取 Token 单价 | +| 字段 | 类型 | 说明 | +| --------------------------- | ----- | -------------------------------------------------- | +| `vendor` | str | 供应商名称 | +| `model` | str | 实际模型名 | +| `input_cost_per_mtok` | float | 输入 Token 单价($/百万 token,支持 `$`/`¥` 前缀) | +| `output_cost_per_mtok` | float | 输出 Token 单价 | +| `cache_write_cost_per_mtok` | float | 缓存创建 Token 单价 | +| `cache_read_cost_per_mtok` | float | 缓存读取 Token 单价 | --- ## 8. tiers — 显式优先级 -| 字段 | 类型 | 说明 | -| ------- | ------------------------ | ------------------------------------------- | -| `tiers` | list[VendorType] \| None | 降级链路优先级(None 时回退 vendors 顺序) | +| 字段 | 类型 | 说明 | +| ------- | ------------------------ | ------------------------------------------ | +| `tiers` | list[VendorType] \| None | 降级链路优先级(None 时回退 vendors 顺序) | --- diff --git a/docs/arch/convert.md b/docs/arch/convert.md index 1697247..3933a4d 100644 --- a/docs/arch/convert.md +++ b/docs/arch/convert.md @@ -12,13 +12,13 @@ [`convert/`](../../src/coding/proxy/convert/) 模块提供独立的纯函数适配器层,支持三向格式转换: -| 转换方向 | 模块 | 说明 | -| --------------------------- | ---------------------------------------------------------------------------------------------- | ------------------ | -| Anthropic → Gemini | [`convert/anthropic_to_gemini.py`](../../src/coding/proxy/convert/anthropic_to_gemini.py) | 请求格式转换 | -| Gemini → Anthropic | [`convert/gemini_to_anthropic.py`](../../src/coding/proxy/convert/gemini_to_anthropic.py) | 响应格式转换 | -| Gemini SSE → Anthropic SSE | [`convert/gemini_sse_adapter.py`](../../src/coding/proxy/convert/gemini_sse_adapter.py) | 流式事件重构 | -| Anthropic → OpenAI | [`convert/anthropic_to_openai.py`](../../src/coding/proxy/convert/anthropic_to_openai.py) | Copilot 请求适配 | -| OpenAI → Anthropic | [`convert/openai_to_anthropic.py`](../../src/coding/proxy/convert/openai_to_anthropic.py) | Copilot 响应逆适配 | +| 转换方向 | 模块 | 说明 | +| -------------------------- | ----------------------------------------------------------------------------------------- | ------------------ | +| Anthropic → Gemini | [`convert/anthropic_to_gemini.py`](../../src/coding/proxy/convert/anthropic_to_gemini.py) | 请求格式转换 | +| Gemini → Anthropic | [`convert/gemini_to_anthropic.py`](../../src/coding/proxy/convert/gemini_to_anthropic.py) | 响应格式转换 | +| Gemini SSE → Anthropic SSE | [`convert/gemini_sse_adapter.py`](../../src/coding/proxy/convert/gemini_sse_adapter.py) | 流式事件重构 | +| Anthropic → OpenAI | [`convert/anthropic_to_openai.py`](../../src/coding/proxy/convert/anthropic_to_openai.py) | Copilot 请求适配 | +| OpenAI → Anthropic | [`convert/openai_to_anthropic.py`](../../src/coding/proxy/convert/openai_to_anthropic.py) | Copilot 响应逆适配 | --- @@ -28,17 +28,17 @@ **转换映射**: -| Anthropic 字段 | Gemini 字段 | 说明 | -| --------------------------------- | ---------------------------------- | -------------------------------------------------- | -| `system`(str \| list) | `systemInstruction.parts[].text` | 支持字符串和文本块列表两种格式 | -| `messages[]` | `contents[]` | 角色映射:`assistant` → `model`,`user` → `user` | -| `content`(text) | `parts[].text` | 文本内容块 | -| `content`(image) | `parts[].inlineData` | Base64 数据 + MIME 类型 | -| `content`(tool_use) | `parts[].functionCall` | `name` + `input` → `args` | -| `content`(tool_result) | `parts[].functionResponse` | `tool_use_id` → `name`,`content` → `result` | -| `max_tokens` | `generationConfig.maxOutputTokens` | | -| `temperature` / `top_p` / `top_k` | `generationConfig.*` | 参数名驼峰转换 | -| `stop_sequences` | `generationConfig.stopSequences` | | +| Anthropic 字段 | Gemini 字段 | 说明 | +| --------------------------------- | ---------------------------------- | ------------------------------------------------ | +| `system`(str \| list) | `systemInstruction.parts[].text` | 支持字符串和文本块列表两种格式 | +| `messages[]` | `contents[]` | 角色映射:`assistant` → `model`,`user` → `user` | +| `content`(text) | `parts[].text` | 文本内容块 | +| `content`(image) | `parts[].inlineData` | Base64 数据 + MIME 类型 | +| `content`(tool_use) | `parts[].functionCall` | `name` + `input` → `args` | +| `content`(tool_result) | `parts[].functionResponse` | `tool_use_id` → `name`,`content` → `result` | +| `max_tokens` | `generationConfig.maxOutputTokens` | | +| `temperature` / `top_p` / `top_k` | `generationConfig.*` | 参数名驼峰转换 | +| `stop_sequences` | `generationConfig.stopSequences` | | **不支持的字段**(静默剥离并记录 WARNING):`tools`、`tool_choice`、`metadata`、`extended_thinking`、`thinking` diff --git a/docs/arch/design-patterns.md b/docs/arch/design-patterns.md index ac8ec8f..0b8c31b 100644 --- a/docs/arch/design-patterns.md +++ b/docs/arch/design-patterns.md @@ -113,14 +113,14 @@ classDiagram 三类 Vendor 子类的差异化实现: -| 方法 | AnthropicVendor(直接透传) | CopilotVendor(协议转换) | AntigravityVendor(协议转换) | NativeAnthropicVendor 子类(薄透传) | -| -------------------- | --------------------------- | ------------------------------- | ---------------------------------- | ------------------------------------ | -| `_prepare_request()` | 过滤 hop-by-hop 头 | 过滤头 + 异步 token 注入 | Gemini 格式转换 + OAuth token | 模型映射 + API Key 替换 | -| `map_model()` | 恒等映射 | 恒等映射 | 恒等映射 | **委托 ModelMapper** | -| `_get_endpoint()` | `/v1/messages` | `/v1/chat/completions` | `/{model}:generateContent` | `/v1/messages`(继承) | -| `_on_error_status()` | 继承基类(空操作) | 401/403 token 失效 | 401/403 token 失效 | 继承基类(空操作) | -| `get_capabilities()` | 全部支持 | 不支持 thinking | 不支持 tools/thinking/metadata | 全部支持(NATIVE) | -| `check_health()` | 继承(True) | 继承(True) | **覆写**(OAuth token 有效性检查) | 继承(True) | +| 方法 | AnthropicVendor(直接透传) | CopilotVendor(协议转换) | AntigravityVendor(协议转换) | NativeAnthropicVendor 子类(薄透传) | +| -------------------- | --------------------------- | ------------------------- | ---------------------------------- | ------------------------------------ | +| `_prepare_request()` | 过滤 hop-by-hop 头 | 过滤头 + 异步 token 注入 | Gemini 格式转换 + OAuth token | 模型映射 + API Key 替换 | +| `map_model()` | 恒等映射 | 恒等映射 | 恒等映射 | **委托 ModelMapper** | +| `_get_endpoint()` | `/v1/messages` | `/v1/chat/completions` | `/{model}:generateContent` | `/v1/messages`(继承) | +| `_on_error_status()` | 继承基类(空操作) | 401/403 token 失效 | 401/403 token 失效 | 继承基类(空操作) | +| `get_capabilities()` | 全部支持 | 不支持 thinking | 不支持 tools/thinking/metadata | 全部支持(NATIVE) | +| `check_health()` | 继承(True) | 继承(True) | **覆写**(OAuth token 有效性检查) | 继承(True) | > **供应商分类体系**详情参见 [供应商模块 -- 分类体系](./vendors.md#vendor-classification)。 @@ -441,22 +441,22 @@ graph LR 每个 Vendor 子类充当 Adapter 角色,将异构的上游 API 适配为统一的 `BaseVendor` 接口: -| Vendor | 上游协议 | 适配行为 | -| ----------------------------- | --------------------------- | ------------------------------------------------------ | -| `AnthropicVendor` | Anthropic Messages API | 透传(近乎零适配开销) | -| `CopilotVendor` | OpenAI Chat Completions API | 请求体/响应体双向格式转换 + token 注入 | -| `AntigravityVendor` | Gemini GenerateContent API | Anthropic ↔ Gemini 双向格式转换 + SSE 流适配 + OAuth | +| Vendor | 上游协议 | 适配行为 | +| ----------------------------- | --------------------------- | ------------------------------------------------------------- | +| `AnthropicVendor` | Anthropic Messages API | 透传(近乎零适配开销) | +| `CopilotVendor` | OpenAI Chat Completions API | 请求体/响应体双向格式转换 + token 注入 | +| `AntigravityVendor` | Gemini GenerateContent API | Anthropic ↔ Gemini 双向格式转换 + SSE 流适配 + OAuth | | `ZhipuVendor` 等 6 个原生兼容 | Anthropic-compatible API | 模型名映射 + API Key 认证头替换(继承 NativeAnthropicVendor) | 此外,[`convert/`](../../src/coding/proxy/convert/) 模块提供独立的纯函数适配器层,支持三向格式转换: -| 转换方向 | 模块 | 说明 | -| --------------------------- | -------------------------------------------------------------------------------------------- | ------------------ | -| Anthropic -> Gemini | [`convert/anthropic_to_gemini.py`](../../src/coding/proxy/convert/anthropic_to_gemini.py) | 请求格式转换 | -| Gemini -> Anthropic | [`convert/gemini_to_anthropic.py`](../../src/coding/proxy/convert/gemini_to_anthropic.py) | 响应格式转换 | -| Gemini SSE -> Anthropic SSE | [`convert/gemini_sse_adapter.py`](../../src/coding/proxy/convert/gemini_sse_adapter.py) | 流式事件重构 | -| Anthropic -> OpenAI | [`convert/anthropic_to_openai.py`](../../src/coding/proxy/convert/anthropic_to_openai.py) | Copilot 请求适配 | -| OpenAI -> Anthropic | [`convert/openai_to_anthropic.py`](../../src/coding/proxy/convert/openai_to_anthropic.py) | Copilot 响应逆适配 | +| 转换方向 | 模块 | 说明 | +| --------------------------- | ----------------------------------------------------------------------------------------- | ------------------ | +| Anthropic -> Gemini | [`convert/anthropic_to_gemini.py`](../../src/coding/proxy/convert/anthropic_to_gemini.py) | 请求格式转换 | +| Gemini -> Anthropic | [`convert/gemini_to_anthropic.py`](../../src/coding/proxy/convert/gemini_to_anthropic.py) | 响应格式转换 | +| Gemini SSE -> Anthropic SSE | [`convert/gemini_sse_adapter.py`](../../src/coding/proxy/convert/gemini_sse_adapter.py) | 流式事件重构 | +| Anthropic -> OpenAI | [`convert/anthropic_to_openai.py`](../../src/coding/proxy/convert/anthropic_to_openai.py) | Copilot 请求适配 | +| OpenAI -> Anthropic | [`convert/openai_to_anthropic.py`](../../src/coding/proxy/convert/openai_to_anthropic.py) | Copilot 响应逆适配 | --- diff --git a/docs/arch/routing.md b/docs/arch/routing.md index ad90664..bb548ab 100644 --- a/docs/arch/routing.md +++ b/docs/arch/routing.md @@ -12,20 +12,20 @@ 路由模块正交分解为 12 个子模块,每个子模块职责单一: -| 子模块 | 文件 | 职责 | -| ------------------- | ------------------------------------------------------------------ | ------------------------------------------- | -| **router** | [`routing/router.py`](../../src/coding/proxy/routing/router.py) | `RequestRouter` — 路由门面(Facade) | -| **executor** | [`routing/executor.py`](../../src/coding/proxy/routing/executor.py)| `_RouteExecutor` — tier 迭代门控引擎 | -| **tier** | [`routing/tier.py`](../../src/coding/proxy/routing/tier.py) | `VendorTier` — 最小调度单元(Composite) | -| **circuit_breaker** | [`routing/circuit_breaker.py`](../../src/coding/proxy/routing/circuit_breaker.py) | `CircuitBreaker` — 熔断器状态机 | -| **quota_guard** | [`routing/quota_guard.py`](../../src/coding/proxy/routing/quota_guard.py) | `QuotaGuard` — 配额守卫状态机 | -| **retry** | [`routing/retry.py`](../../src/coding/proxy/routing/retry.py) | `RetryConfig` / `calculate_delay()` — 重试策略 | -| **rate_limit** | [`routing/rate_limit.py`](../../src/coding/proxy/routing/rate_limit.py) | `RateLimitInfo` / 解析与截止时间计算 | -| **error_classifier**| [`routing/error_classifier.py`](../../src/coding/proxy/routing/error_classifier.py) | 请求能力画像 + 语义拒绝判定 | -| **model_mapper** | [`routing/model_mapper.py`](../../src/coding/proxy/routing/model_mapper.py) | `ModelMapper` — 三级优先级匹配链 | -| **usage_recorder** | [`routing/usage_recorder.py`](../../src/coding/proxy/routing/usage_recorder.py) | 用量记录、定价计算与证据构建 | -| **usage_parser** | [`routing/usage_parser.py`](../../src/coding/proxy/routing/usage_parser.py) | SSE chunk Token 用量提取 | -| **session_manager** | [`routing/session_manager.py`](../../src/coding/proxy/routing/session_manager.py) | 兼容性会话生命周期管理 | +| 子模块 | 文件 | 职责 | +| -------------------- | ----------------------------------------------------------------------------------- | ---------------------------------------------- | +| **router** | [`routing/router.py`](../../src/coding/proxy/routing/router.py) | `RequestRouter` — 路由门面(Facade) | +| **executor** | [`routing/executor.py`](../../src/coding/proxy/routing/executor.py) | `_RouteExecutor` — tier 迭代门控引擎 | +| **tier** | [`routing/tier.py`](../../src/coding/proxy/routing/tier.py) | `VendorTier` — 最小调度单元(Composite) | +| **circuit_breaker** | [`routing/circuit_breaker.py`](../../src/coding/proxy/routing/circuit_breaker.py) | `CircuitBreaker` — 熔断器状态机 | +| **quota_guard** | [`routing/quota_guard.py`](../../src/coding/proxy/routing/quota_guard.py) | `QuotaGuard` — 配额守卫状态机 | +| **retry** | [`routing/retry.py`](../../src/coding/proxy/routing/retry.py) | `RetryConfig` / `calculate_delay()` — 重试策略 | +| **rate_limit** | [`routing/rate_limit.py`](../../src/coding/proxy/routing/rate_limit.py) | `RateLimitInfo` / 解析与截止时间计算 | +| **error_classifier** | [`routing/error_classifier.py`](../../src/coding/proxy/routing/error_classifier.py) | 请求能力画像 + 语义拒绝判定 | +| **model_mapper** | [`routing/model_mapper.py`](../../src/coding/proxy/routing/model_mapper.py) | `ModelMapper` — 三级优先级匹配链 | +| **usage_recorder** | [`routing/usage_recorder.py`](../../src/coding/proxy/routing/usage_recorder.py) | 用量记录、定价计算与证据构建 | +| **usage_parser** | [`routing/usage_parser.py`](../../src/coding/proxy/routing/usage_parser.py) | SSE chunk Token 用量提取 | +| **session_manager** | [`routing/session_manager.py`](../../src/coding/proxy/routing/session_manager.py) | 兼容性会话生命周期管理 | --- @@ -72,7 +72,7 @@ class VendorTier: | ------------------------------------------------------------------ | -------------------------------------------------------------------- | | `execute_stream(body, headers)` | 流式路由主循环,yield `(chunk, vendor_name)` | | `execute_message(body, headers)` | 非流式路由主循环,返回 `VendorResponse` | -| `_try_gate_tier(tier, is_last, caps, canonical, session, reasons)` | 单 tier 门控:能力匹配 → 兼容性决策 → 上下文应用 → 健康检查 | +| `_try_gate_tier(tier, is_last, caps, canonical, session, reasons)` | 单 tier 门控:能力匹配 → 兼容性决策 → 上下文应用 → 健康检查 | | `_handle_token_error(tier, exc, is_last, failed_name)` | TokenAcquireError 处理 + reauth 触发 | | `_handle_http_error(tier, exc, ...)` | HTTP 错误处理:语义拒绝 / cap error / rate limit 解析 / failure 记录 | | `_is_cap_error(resp)` | 静态方法:检测 429/403 + 配额关键词 | diff --git a/docs/arch/testing.md b/docs/arch/testing.md index 30ab6ba..2c3cf78 100644 --- a/docs/arch/testing.md +++ b/docs/arch/testing.md @@ -20,95 +20,95 @@ ### 2.1 供应商(vendors) -| 测试文件 | 覆盖范围 | -| -------------------------------- | --------------------------------------------------------------- | -| `test_vendors.py` | 请求头过滤、模型映射、故障转移判断、数据类默认值 | -| `test_copilot.py` | CopilotTokenManager 交换/缓存/过期/失效、CopilotVendor 请求准备 | -| `test_antigravity.py` | GoogleOAuthTokenManager 刷新/缓存/过期/失效、格式转换+token注入 | -| `test_native_vendors.py` | NativeAnthropicVendor 基类行为、401 归一化、子类继承 | -| `test_zhipu.py` | ZhipuVendor 特定行为 | -| `test_mixins.py` | TokenBackendMixin 行为 | -| `test_token_manager.py` | BaseTokenManager 抽象行为 | -| `test_copilot_models.py` | CopilotModelResolver 模型解析与误导向处理 | -| `test_copilot_urls.py` | Copilot URL 工具函数 | -| `test_vendor_streaming.py` | Vendor 流式响应行为 | +| 测试文件 | 覆盖范围 | +| -------------------------- | --------------------------------------------------------------- | +| `test_vendors.py` | 请求头过滤、模型映射、故障转移判断、数据类默认值 | +| `test_copilot.py` | CopilotTokenManager 交换/缓存/过期/失效、CopilotVendor 请求准备 | +| `test_antigravity.py` | GoogleOAuthTokenManager 刷新/缓存/过期/失效、格式转换+token注入 | +| `test_native_vendors.py` | NativeAnthropicVendor 基类行为、401 归一化、子类继承 | +| `test_zhipu.py` | ZhipuVendor 特定行为 | +| `test_mixins.py` | TokenBackendMixin 行为 | +| `test_token_manager.py` | BaseTokenManager 抽象行为 | +| `test_copilot_models.py` | CopilotModelResolver 模型解析与误导向处理 | +| `test_copilot_urls.py` | Copilot URL 工具函数 | +| `test_vendor_streaming.py` | Vendor 流式响应行为 | ### 2.2 路由(routing) -| 测试文件 | 覆盖范围 | -| -------------------------------- | --------------------------------------------------------------- | -| `test_circuit_breaker.py` | 状态转换(CLOSED→OPEN→HALF_OPEN→CLOSED)、恢复超时、指数退避、手动重置 | -| `test_quota_guard.py` | 配额守卫状态机、预算追踪、探测机制、基线加载 | -| `test_model_mapper.py` | 精确匹配、正则匹配、Glob 匹配、默认回退、空规则集 | -| `test_tier.py` | VendorTier 可执行判断、成功/失败记录、终端判定、三层门控、RL deadline | -| `test_router_chain.py` | N-tier 链式路由(2/3/4-tier 降级、CB/QG 跳过、流式/非流式、连接异常) | -| `test_router_executor.py` | _RouteExecutor 门控逻辑、能力匹配、兼容性决策、语义拒绝 | -| `test_error_classifier.py` | 请求能力画像提取、语义拒绝判定、错误 payload 解析 | -| `test_rate_limit.py` | Rate limit header 解析、deadline 计算、cap error 检测 | -| `test_retry.py` | RetryConfig 参数、delay 计算、可重试异常判定 | -| `test_usage_recorder.py` | UsageRecorder 用量构建、定价日志、evidence 记录 | +| 测试文件 | 覆盖范围 | +| -------------------------- | ---------------------------------------------------------------------- | +| `test_circuit_breaker.py` | 状态转换(CLOSED→OPEN→HALF_OPEN→CLOSED)、恢复超时、指数退避、手动重置 | +| `test_quota_guard.py` | 配额守卫状态机、预算追踪、探测机制、基线加载 | +| `test_model_mapper.py` | 精确匹配、正则匹配、Glob 匹配、默认回退、空规则集 | +| `test_tier.py` | VendorTier 可执行判断、成功/失败记录、终端判定、三层门控、RL deadline | +| `test_router_chain.py` | N-tier 链式路由(2/3/4-tier 降级、CB/QG 跳过、流式/非流式、连接异常) | +| `test_router_executor.py` | _RouteExecutor 门控逻辑、能力匹配、兼容性决策、语义拒绝 | +| `test_error_classifier.py` | 请求能力画像提取、语义拒绝判定、错误 payload 解析 | +| `test_rate_limit.py` | Rate limit header 解析、deadline 计算、cap error 检测 | +| `test_retry.py` | RetryConfig 参数、delay 计算、可重试异常判定 | +| `test_usage_recorder.py` | UsageRecorder 用量构建、定价日志、evidence 记录 | ### 2.3 配置(config) -| 测试文件 | 覆盖范围 | -| -------------------------------- | --------------------------------------------------------------- | -| `test_config_loader.py` | 配置文件搜索优先级、环境变量展开、缺失文件处理、vendors 格式解析 | -| `test_config_init.py` | 配置模块初始化与 re-export 验证 | -| `test_schema.py` | ProxyConfig 校验、legacy 迁移、tiers 引用校验、vendor 专属字段 warning | +| 测试文件 | 覆盖范围 | +| ----------------------- | ---------------------------------------------------------------------- | +| `test_config_loader.py` | 配置文件搜索优先级、环境变量展开、缺失文件处理、vendors 格式解析 | +| `test_config_init.py` | 配置模块初始化与 re-export 验证 | +| `test_schema.py` | ProxyConfig 校验、legacy 迁移、tiers 引用校验、vendor 专属字段 warning | ### 2.4 格式转换(convert) -| 测试文件 | 覆盖范围 | -| ------------------------------------- | --------------------------------------------------------------- | -| `test_convert_request.py` | Anthropic→Gemini 请求转换(文本、多轮、system、图片、工具、参数映射) | -| `test_convert_response.py` | Gemini→Anthropic 响应转换(文本、多部件、usage 提取、finishReason 映射) | -| `test_convert_sse.py` | Gemini SSE→Anthropic SSE 流适配(单/多 chunk、各 finishReason、边界情况) | -| `test_copilot_convert_request.py` | Anthropic→OpenAI 请求格式转换 | -| `test_copilot_convert_response.py` | OpenAI→Anthropic 响应格式转换 | +| 测试文件 | 覆盖范围 | +| ---------------------------------- | ------------------------------------------------------------------------- | +| `test_convert_request.py` | Anthropic→Gemini 请求转换(文本、多轮、system、图片、工具、参数映射) | +| `test_convert_response.py` | Gemini→Anthropic 响应转换(文本、多部件、usage 提取、finishReason 映射) | +| `test_convert_sse.py` | Gemini SSE→Anthropic SSE 流适配(单/多 chunk、各 finishReason、边界情况) | +| `test_copilot_convert_request.py` | Anthropic→OpenAI 请求格式转换 | +| `test_copilot_convert_response.py` | OpenAI→Anthropic 响应格式转换 | ### 2.5 数据模型(model) -| 测试文件 | 覆盖范围 | -| -------------------------------- | --------------------------------------------------------------- | -| `test_model_vendor.py` | UsageInfo/VendorResponse/RequestCapabilities 数据类 | -| `test_model_compat.py` | CanonicalRequest/CompatibilityDecision 数据模型 | -| `test_model_constants.py` | 常量定义与使用 | -| `test_model_pricing.py` | ModelPricingEntry 校验、币种一致性 | -| `test_model_token.py` | Token 相关模型 | -| `test_model_auth.py` | 认证相关模型 | +| 测试文件 | 覆盖范围 | +| ------------------------- | --------------------------------------------------- | +| `test_model_vendor.py` | UsageInfo/VendorResponse/RequestCapabilities 数据类 | +| `test_model_compat.py` | CanonicalRequest/CompatibilityDecision 数据模型 | +| `test_model_constants.py` | 常量定义与使用 | +| `test_model_pricing.py` | ModelPricingEntry 校验、币种一致性 | +| `test_model_token.py` | Token 相关模型 | +| `test_model_auth.py` | 认证相关模型 | ### 2.6 认证(auth) -| 测试文件 | 覆盖范围 | -| -------------------------------- | --------------------------------------------------------------- | -| `test_runtime_reauth.py` | RuntimeReauthCoordinator 状态机、幂等触发、锁保护 | -| `test_auto_login.py` | 自动登录流程 | +| 测试文件 | 覆盖范围 | +| ------------------------ | ------------------------------------------------- | +| `test_runtime_reauth.py` | RuntimeReauthCoordinator 状态机、幂等触发、锁保护 | +| `test_auto_login.py` | 自动登录流程 | ### 2.7 流式处理(streaming) -| 测试文件 | 覆盖范围 | -| ------------------------------------- | ------------------------------------------------- | -| `test_streaming_anthropic_compat.py` | Anthropic 流式兼容层行为 | +| 测试文件 | 覆盖范围 | +| ------------------------------------ | ------------------------ | +| `test_streaming_anthropic_compat.py` | Anthropic 流式兼容层行为 | ### 2.8 服务端与 CLI(server/cli) -| 测试文件 | 覆盖范围 | -| -------------------------------- | --------------------------------------------------------------- | -| `test_app_routes.py` | FastAPI 路由端点测试 | -| `test_request_normalizer.py` | 请求标准化:私有块清洗、tool_use_id 重写、fatal_reasons | -| `test_cli_usage.py` | CLI 用量查询命令 | -| `test_banner.py` | CLI Banner 显示 | -| `test_logging_dual_write.py` | 日志双写机制 | +| 测试文件 | 覆盖范围 | +| ---------------------------- | ------------------------------------------------------- | +| `test_app_routes.py` | FastAPI 路由端点测试 | +| `test_request_normalizer.py` | 请求标准化:私有块清洗、tool_use_id 重写、fatal_reasons | +| `test_cli_usage.py` | CLI 用量查询命令 | +| `test_banner.py` | CLI Banner 显示 | +| `test_logging_dual_write.py` | 日志双写机制 | ### 2.9 其他 -| 测试文件 | 覆盖范围 | -| -------------------------------- | --------------------------------------------------------------- | -| `test_pricing.py` | PricingTable 加载、单价查询(精确+规范化)、费用计算、币种一致性 | -| `test_token_logger.py` | 用量记录、窗口查询、按供应商/模型过滤、evidence 记录 | -| `test_compat.py` | CanonicalRequest 构建、session_key 派生 | -| `test_parse_usage.py` | 用量解析工具函数 | -| `test_currency.py` | 币种检测与转换 | -| `test_types.py` | 公共类型定义 | -| `test_time_range.py` | 时间范围工具 | -| `test_tiers_config.py` | Tiers 配置验证 | +| 测试文件 | 覆盖范围 | +| ---------------------- | ---------------------------------------------------------------- | +| `test_pricing.py` | PricingTable 加载、单价查询(精确+规范化)、费用计算、币种一致性 | +| `test_token_logger.py` | 用量记录、窗口查询、按供应商/模型过滤、evidence 记录 | +| `test_compat.py` | CanonicalRequest 构建、session_key 派生 | +| `test_parse_usage.py` | 用量解析工具函数 | +| `test_currency.py` | 币种检测与转换 | +| `test_types.py` | 公共类型定义 | +| `test_time_range.py` | 时间范围工具 | +| `test_tiers_config.py` | Tiers 配置验证 | diff --git a/docs/arch/vendors.md b/docs/arch/vendors.md index 39fef86..2ec79ad 100644 --- a/docs/arch/vendors.md +++ b/docs/arch/vendors.md @@ -180,10 +180,10 @@ class BaseVendor(ABC): 子类仅需覆写两个类属性: -| 属性 | 类型 | 说明 | -|------|------|------| -| `_vendor_name` | `str` | 供应商标识名(`get_name()` 返回值 & `ModelMapper` 的 vendor 参数) | -| `_display_name` | `str` | 错误消息中的显示名(如 `"Zhipu"`、`"MiniMax"`) | +| 属性 | 类型 | 说明 | +| --------------- | ----- | ------------------------------------------------------------------ | +| `_vendor_name` | `str` | 供应商标识名(`get_name()` 返回值 & `ModelMapper` 的 vendor 参数) | +| `_display_name` | `str` | 错误消息中的显示名(如 `"Zhipu"`、`"MiniMax"`) | ### 能力声明 @@ -197,17 +197,17 @@ json_output=NATIVE, usage_tokens=NATIVE ## 4. 供应商注册表 -| 供应商 | 文件 | 协议 | 认证方式 | 能力 | -|--------|------|------|----------|------| -| AnthropicVendor | [vendors/anthropic.py](../../src/coding/proxy/vendors/anthropic.py) | Anthropic Messages API | OAuth token 透传 | 全能力支持 | -| CopilotVendor | [vendors/copilot.py](../../src/coding/proxy/vendors/copilot.py) | OpenAI Chat Completions | GitHub token → Copilot token 交换 | thinking 为 SIMULATED | -| AntigravityVendor | [vendors/antigravity.py](../../src/coding/proxy/vendors/antigravity.py) | Gemini GenerateContent | Google OAuth2 refresh_token | tool_streaming / metadata / usage_tokens 为 SIMULATED | -| ZhipuVendor | [vendors/zhipu.py](../../src/coding/proxy/vendors/zhipu.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | -| MinimaxVendor | [vendors/minimax.py](../../src/coding/proxy/vendors/minimax.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | -| KimiVendor | [vendors/kimi.py](../../src/coding/proxy/vendors/kimi.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | -| DoubaoVendor | [vendors/doubao.py](../../src/coding/proxy/vendors/doubao.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | -| XiaomiVendor | [vendors/xiaomi.py](../../src/coding/proxy/vendors/xiaomi.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | -| AlibabaVendor | [vendors/alibaba.py](../../src/coding/proxy/vendors/alibaba.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| 供应商 | 文件 | 协议 | 认证方式 | 能力 | +| ----------------- | ----------------------------------------------------------------------- | ------------------------ | --------------------------------- | ----------------------------------------------------- | +| AnthropicVendor | [vendors/anthropic.py](../../src/coding/proxy/vendors/anthropic.py) | Anthropic Messages API | OAuth token 透传 | 全能力支持 | +| CopilotVendor | [vendors/copilot.py](../../src/coding/proxy/vendors/copilot.py) | OpenAI Chat Completions | GitHub token → Copilot token 交换 | thinking 为 SIMULATED | +| AntigravityVendor | [vendors/antigravity.py](../../src/coding/proxy/vendors/antigravity.py) | Gemini GenerateContent | Google OAuth2 refresh_token | tool_streaming / metadata / usage_tokens 为 SIMULATED | +| ZhipuVendor | [vendors/zhipu.py](../../src/coding/proxy/vendors/zhipu.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| MinimaxVendor | [vendors/minimax.py](../../src/coding/proxy/vendors/minimax.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| KimiVendor | [vendors/kimi.py](../../src/coding/proxy/vendors/kimi.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| DoubaoVendor | [vendors/doubao.py](../../src/coding/proxy/vendors/doubao.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| XiaomiVendor | [vendors/xiaomi.py](../../src/coding/proxy/vendors/xiaomi.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | +| AlibabaVendor | [vendors/alibaba.py](../../src/coding/proxy/vendors/alibaba.py) | Anthropic-compatible API | x-api-key | 全能力 (NATIVE) | > 各供应商的默认 `base_url`、超时等配置项详见 [config-reference.md](./config-reference.md)。 @@ -350,18 +350,18 @@ Copilot 模型目录管理与解析策略: 代码库从 "Backend" 命名体系迁移至 "Vendor" 命名体系,保留了以下别名(计划 v2 移除): -| 旧名称 | 新名称 | 定义位置 | -|--------|--------|----------| -| `BaseBackend` | `BaseVendor` | [vendors/base.py](../../src/coding/proxy/vendors/base.py) | -| `NoCompatibleBackendError` | `NoCompatibleVendorError` | [vendors/base.py](../../src/coding/proxy/vendors/base.py) | -| `BackendCapabilities` | `VendorCapabilities` | [model/vendor.py](../../src/coding/proxy/model/vendor.py) | -| `BackendResponse` | `VendorResponse` | [model/vendor.py](../../src/coding/proxy/model/vendor.py) | -| `TierConfig` | `VendorConfig` | [config/routing.py](../../src/coding/proxy/config/routing.py) | -| `BackendType` | `VendorType` | [config/routing.py](../../src/coding/proxy/config/routing.py) | -| `AnthropicBackend` | `AnthropicVendor` | [vendors/anthropic.py](../../src/coding/proxy/vendors/anthropic.py) | -| `CopilotBackend` | `CopilotVendor` | [vendors/copilot.py](../../src/coding/proxy/vendors/copilot.py) | -| `AntigravityBackend` | `AntigravityVendor` | [vendors/antigravity.py](../../src/coding/proxy/vendors/antigravity.py) | -| `ZhipuBackend` | `ZhipuVendor` | [vendors/zhipu.py](../../src/coding/proxy/vendors/zhipu.py) | +| 旧名称 | 新名称 | 定义位置 | +| -------------------------- | ------------------------- | ----------------------------------------------------------------------- | +| `BaseBackend` | `BaseVendor` | [vendors/base.py](../../src/coding/proxy/vendors/base.py) | +| `NoCompatibleBackendError` | `NoCompatibleVendorError` | [vendors/base.py](../../src/coding/proxy/vendors/base.py) | +| `BackendCapabilities` | `VendorCapabilities` | [model/vendor.py](../../src/coding/proxy/model/vendor.py) | +| `BackendResponse` | `VendorResponse` | [model/vendor.py](../../src/coding/proxy/model/vendor.py) | +| `TierConfig` | `VendorConfig` | [config/routing.py](../../src/coding/proxy/config/routing.py) | +| `BackendType` | `VendorType` | [config/routing.py](../../src/coding/proxy/config/routing.py) | +| `AnthropicBackend` | `AnthropicVendor` | [vendors/anthropic.py](../../src/coding/proxy/vendors/anthropic.py) | +| `CopilotBackend` | `CopilotVendor` | [vendors/copilot.py](../../src/coding/proxy/vendors/copilot.py) | +| `AntigravityBackend` | `AntigravityVendor` | [vendors/antigravity.py](../../src/coding/proxy/vendors/antigravity.py) | +| `ZhipuBackend` | `ZhipuVendor` | [vendors/zhipu.py](../../src/coding/proxy/vendors/zhipu.py) | ## 8. 添加新供应商指南 From 84d55633dc7219a55e2f6f1d53ae4002c619686e Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 09:02:39 +0800 Subject: [PATCH 27/32] =?UTF-8?q?style(docs):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=8C=87=E5=8D=97=E4=B8=8E=E8=BF=90=E7=BB=B4=E6=96=87=E6=A1=A3?= =?UTF-8?q?=20Markdown=20=E8=A1=A8=E6=A0=BC=E5=88=97=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- docs/ci-cd.md | 82 +++++++-------- docs/framework.md | 116 ++++++++++----------- docs/guide/api-reference.md | 194 ++++++++++++++++++------------------ docs/guide/cli-reference.md | 103 +++++++++---------- docs/guide/dashboard.md | 36 +++---- docs/guide/monitoring.md | 30 +++--- docs/guide/vendors.md | 165 +++++++++++++++--------------- docs/user-guide.md | 132 ++++++++++++------------ 8 files changed, 428 insertions(+), 430 deletions(-) diff --git a/docs/ci-cd.md b/docs/ci-cd.md index 8be7cea..6b35b38 100644 --- a/docs/ci-cd.md +++ b/docs/ci-cd.md @@ -209,15 +209,15 @@ graph TD CI 流水线中使用的工具及其版本均与项目实际配置严格对齐: -| 工具 | 版本 / 引用 | 来源 (Action) | 与项目配置的对齐关系 | -| -------------- | ------------ | ---------------------------------------- | -------------------------------------------------------------------------- | +| 工具 | 版本 / 引用 | 来源 (Action) | 与项目配置的对齐关系 | +| -------------- | ----------------------------------- | ---------------------------------------- | -------------------------------------------------------------------------- | | Python | `["3.12", "3.13", "3.14"]` (matrix) | `actions/setup-python@v5` | 对齐 [`pyproject.toml`](../pyproject.toml) 中 `requires-python = ">=3.12"` | -| uv | latest (v4) | `astral-sh/setup-uv@v4` | 项目强制包管理器(见 AGENTS.md 包管理规范) | -| build | latest | `uv pip install --system build` | PEP 517 构建前端,后端为 hatchling | -| twine | latest | `uv pip install --system twine` | 包元数据校验与上传工具 | -| Publish Action | `release/v1` | `pypa/gh-action-pypi-publish@release/v1` | PyPA 官方发布 Action[[3]](#ref3) | -| Checkout | v4 | `actions/checkout@v4` | 代码检出(`persist-credentials: false` 最小化凭据暴露) | -| GitHub Script | v7 | `actions/github-script@v7` | 用于 promote.yml 中的 Release 元数据查询与更新 | +| uv | latest (v4) | `astral-sh/setup-uv@v4` | 项目强制包管理器(见 AGENTS.md 包管理规范) | +| build | latest | `uv pip install --system build` | PEP 517 构建前端,后端为 hatchling | +| twine | latest | `uv pip install --system twine` | 包元数据校验与上传工具 | +| Publish Action | `release/v1` | `pypa/gh-action-pypi-publish@release/v1` | PyPA 官方发布 Action[[3]](#ref3) | +| Checkout | v4 | `actions/checkout@v4` | 代码检出(`persist-credentials: false` 最小化凭据暴露) | +| GitHub Script | v7 | `actions/github-script@v7` | 用于 promote.yml 中的 Release 元数据查询与更新 | ### 2.4 GitHub Environments 配置详情 @@ -458,12 +458,12 @@ flowchart TD #### Job 2:promote(执行提升) -| 步骤 | Action | 目的 | -| ---------------- | ------------------------------------------------------------------------ | ----------------------------------------------------------------- | -| ① Checkout | `actions/checkout@v4` with `ref: ${{ needs.validate.outputs.tag_name }}` | 从**精确的 git tag** 检出源码,确保确定性重建 | -| ② Update Release | `actions/github-script@v7` | 将 GitHub Release 更新为 `prerelease: false`, `make_latest: true` | -| ③ Build | Python [3.12, 3.13, 3.14] (matrix) + uv + build deps → `python -m build` → `twine check` | 复现与 `release.yml` 完全一致的构建过程 | -| ④ Publish | `pypa/gh-action-pypi-publish@release/v1` | 发布到 PyPI Production | +| 步骤 | Action | 目的 | +| ---------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | +| ① Checkout | `actions/checkout@v4` with `ref: ${{ needs.validate.outputs.tag_name }}` | 从**精确的 git tag** 检出源码,确保确定性重建 | +| ② Update Release | `actions/github-script@v7` | 将 GitHub Release 更新为 `prerelease: false`, `make_latest: true` | +| ③ Build | Python [3.12, 3.13, 3.14] (matrix) + uv + build deps → `python -m build` → `twine check` | 复现与 `release.yml` 完全一致的构建过程 | +| ④ Publish | `pypa/gh-action-pypi-publish@release/v1` | 发布到 PyPI Production | **为什么从 git tag 重建?** @@ -699,14 +699,14 @@ twine upload --repository-url https://test.pypi.org/legacy/ * \ CI 流水线中的工具版本选择并非随意,每一项都与项目配置严格对应: -| CI 配置 | 项目配置 | 对齐关系 | -| --------------------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------- | -| `python-version: "${{ matrix.python-version }}"` | `requires-python = ">=3.12"` in [`pyproject.toml`](../pyproject.toml) | CI 构建环境必须满足项目的最低 Python 版本要求(matrix: 3.12 / 3.13 / 3.14) | -| `hatchling.build` (build-backend) | `[build-system] requires = ["hatchling"]` | 构建后端声明必须一致 | -| `uv pip install --system` | AGENTS.md 强制使用 `uv` | GitHub Actions Runner 默认无激活的 virtualenv,需 `--system` 标志 | -| `retention-days: 14` | — | Artifact 保留两周,覆盖正常的验证窗口期(通常 1-3 天) | -| `attestations: false` (TestPyPI) | — | TestPyPI 平台不支持 PyPA attestations 功能,必须显式禁用否则报错 | -| `verbose: true` (TestPyPI) | — | 启用详细日志以便在 HTTP 400 错误时查看服务端响应体 | +| CI 配置 | 项目配置 | 对齐关系 | +| ------------------------------------------------ | --------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| `python-version: "${{ matrix.python-version }}"` | `requires-python = ">=3.12"` in [`pyproject.toml`](../pyproject.toml) | CI 构建环境必须满足项目的最低 Python 版本要求(matrix: 3.12 / 3.13 / 3.14) | +| `hatchling.build` (build-backend) | `[build-system] requires = ["hatchling"]` | 构建后端声明必须一致 | +| `uv pip install --system` | AGENTS.md 强制使用 `uv` | GitHub Actions Runner 默认无激活的 virtualenv,需 `--system` 标志 | +| `retention-days: 14` | — | Artifact 保留两周,覆盖正常的验证窗口期(通常 1-3 天) | +| `attestations: false` (TestPyPI) | — | TestPyPI 平台不支持 PyPA attestations 功能,必须显式禁用否则报错 | +| `verbose: true` (TestPyPI) | — | 启用详细日志以便在 HTTP 400 错误时查看服务端响应体 | --- @@ -716,16 +716,16 @@ CI 流水线中的工具版本选择并非随意,每一项都与项目配置 [`.github/workflows/release.yml`](../.github/workflows/release.yml) 文件结构一览: -| 行范围 | 区块 | 内容摘要 | -| ------- | ----------------------- | ----------------------------------------------------------------------------- | -| 1–37 | Header 注释 | 架构说明、前置条件、参考文献 | -| 39 | `name` | `"Release / Publish to PyPI"` | -| 41–43 | `on:` | `release: types: [published]` | -| 45–46 | `permissions` | 根级别 `contents: read` | -| 48–50 | `concurrency` | 按 workflow+ref 分组,cancel-in-progress: true | +| 行范围 | 区块 | 内容摘要 | +| ------- | ----------------------- | ---------------------------------------------------------------------------------------------------- | +| 1–37 | Header 注释 | 架构说明、前置条件、参考文献 | +| 39 | `name` | `"Release / Publish to PyPI"` | +| 41–43 | `on:` | `release: types: [published]` | +| 45–46 | `permissions` | 根级别 `contents: read` | +| 48–50 | `concurrency` | 按 workflow+ref 分组,cancel-in-progress: true | | 52–91 | `jobs.build` | 构建作业:checkout → Python [3.12, 3.13, 3.14] (matrix) → uv → build → twine check → upload artifact | -| 93–123 | `jobs.publish-testpypi` | TestPyPI 发布(条件:`prerelease == true`) | -| 125–152 | `jobs.publish-pypi` | PyPI Production 发布(条件:`prerelease == false`) | +| 93–123 | `jobs.publish-testpypi` | TestPyPI 发布(条件:`prerelease == true`) | +| 125–152 | `jobs.publish-pypi` | PyPI Production 发布(条件:`prerelease == false`) | ### 8.2 promote.yml 结构索引 @@ -743,16 +743,16 @@ CI 流水线中的工具版本选择并非随意,每一项都与项目配置 ### 8.3 关键配置参数速查 -| 参数 | `release.yml` | `promote.yml` | 说明 | -| ----------------------------------- | ---------------------- | --------------- | ---------------------------------------- | -| `runs-on` | `ubuntu-latest` | `ubuntu-latest` | GitHub-hosted runner | -| `python-version` | `${{ matrix.python-version }}` | `${{ matrix.python-version }}` | 必须与 `requires-python` 一致(matrix: 3.12 / 3.13 / 3.14) | -| `timeout-minutes` (build) | `10` | N/A | 构建超时上限 | -| `timeout-minutes` (publish/promote) | `10` | `15` | 发布超时(promote 含重建步骤,预留更长) | -| `retention-days` | `14` | N/A | Artifact 保留天数 | -| `skip-existing` | `true` (testpypi job) | N/A | TestPyPI 幂等安全(重复发布不报错) | -| `attestations` | `false` (testpypi job) | N/A | TestPyPI 不支持,必须显式禁用 | -| `verbose` | `true` (testpypi job) | N/A | 启用详细日志便于排查 400 错误 | +| 参数 | `release.yml` | `promote.yml` | 说明 | +| ----------------------------------- | ------------------------------ | ------------------------------ | ----------------------------------------------------------- | +| `runs-on` | `ubuntu-latest` | `ubuntu-latest` | GitHub-hosted runner | +| `python-version` | `${{ matrix.python-version }}` | `${{ matrix.python-version }}` | 必须与 `requires-python` 一致(matrix: 3.12 / 3.13 / 3.14) | +| `timeout-minutes` (build) | `10` | N/A | 构建超时上限 | +| `timeout-minutes` (publish/promote) | `10` | `15` | 发布超时(promote 含重建步骤,预留更长) | +| `retention-days` | `14` | N/A | Artifact 保留天数 | +| `skip-existing` | `true` (testpypi job) | N/A | TestPyPI 幂等安全(重复发布不报错) | +| `attestations` | `false` (testpypi job) | N/A | TestPyPI 不支持,必须显式禁用 | +| `verbose` | `true` (testpypi job) | N/A | 启用详细日志便于排查 400 错误 | --- diff --git a/docs/framework.md b/docs/framework.md index a048bc6..179c419 100644 --- a/docs/framework.md +++ b/docs/framework.md @@ -145,30 +145,30 @@ graph TD 系统支持 9 种供应商类型(`VendorType`),按适配复杂度分为三组: -| 分类 | 基类 | 适配行为 | 供应商 | -| -------------------- | ------------------------ | -------------------------------- | ------------------------------------------------------------ | -| **直接 Anthropic** | `BaseVendor` | 零适配,直接透传 | Anthropic | -| **协议转换** | `BaseVendor` + Mixin | 双向格式转换 + Token 管理 | Copilot(OpenAI)、Antigravity(Gemini) | -| **原生 Anthropic 兼容** | `NativeAnthropicVendor` | 薄透传:模型映射 + API Key 替换 | Zhipu、MiniMax、Kimi、Doubao、Xiaomi、Alibaba | +| 分类 | 基类 | 适配行为 | 供应商 | +| ----------------------- | ----------------------- | ------------------------------- | --------------------------------------------- | +| **直接 Anthropic** | `BaseVendor` | 零适配,直接透传 | Anthropic | +| **协议转换** | `BaseVendor` + Mixin | 双向格式转换 + Token 管理 | Copilot(OpenAI)、Antigravity(Gemini) | +| **原生 Anthropic 兼容** | `NativeAnthropicVendor` | 薄透传:模型映射 + API Key 替换 | Zhipu、MiniMax、Kimi、Doubao、Xiaomi、Alibaba | > **供应商模块完整文档**:参见 [供应商模块(vendors/)](./arch/vendors.md) ### 2.3 模块职责一览 -| 模块 | 路径 | 职责 | 专题文档 | -| ------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | -| **vendors** | [`vendors/`](../src/coding/proxy/vendors/) | **供应商适配器(主架构)**:`BaseVendor` 抽象基类 + `NativeAnthropicVendor` + 9 个具体实现 | [供应商模块](./arch/vendors.md) | -| **routing** | [`routing/`](../src/coding/proxy/routing/) | N-tier 链式路由核心(正交分解为 executor/tier/CB/QG/retry/rate_limit 等 12 个子模块) | [路由模块](./arch/routing.md) | -| **compat** | [`compat/`](../src/coding/proxy/compat/) | 兼容性抽象系统:`CanonicalRequest` / `CompatibilityDecision` / `session_store` | | -| **auth** | [`auth/`](../src/coding/proxy/auth/) | 认证系统:OAuth providers(GitHub Device Flow / Google OAuth2)/ runtime reauth / token store | | -| **model** | [`model/`](../src/coding/proxy/model/) | 数据模型正交分解:vendor / compat / constants / pricing / token / auth | | -| **config** | [`config/`](../src/coding/proxy/config/) | Pydantic v2 配置模型(正交拆分为 server/vendors/resiliency/routing/auth_schema)+ YAML 加载器 | [配置参考](./arch/config-reference.md) | -| **convert** | [`convert/`](../src/coding/proxy/convert/) | API 格式转换(Anthropic ↔ Gemini ↔ OpenAI 三向转换,含 SSE 流适配) | [格式转换](./arch/convert.md) | -| **logging** | [`logging/`](../src/coding/proxy/logging/) | Token 用量 SQLite 持久化([`db.py`](../src/coding/proxy/logging/db.py))、统计查询([`stats.py`](../src/coding/proxy/logging/stats.py))、Rich 格式化 | | -| **server** | [`server/`](../src/coding/proxy/server/) | FastAPI 应用工厂与生命周期管理(app/factory/routes/normalizer/responses/dashboard) | | -| **streaming** | [`streaming/`](../src/coding/proxy/streaming/) | Anthropic 兼容流式处理([`anthropic_compat.py`](../src/coding/proxy/streaming/anthropic_compat.py)) | | -| **cli** | [`cli/`](../src/coding/proxy/cli/) | Typer 命令行入口(start/status/usage/reset/auth)+ Banner 显示 | | -| **pricing** | [`pricing.py`](../src/coding/pricing.py) | 定价表(`PricingTable`):按 (vendor, model) 查询单价并计算费用 | | +| 模块 | 路径 | 职责 | 专题文档 | +| ------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| **vendors** | [`vendors/`](../src/coding/proxy/vendors/) | **供应商适配器(主架构)**:`BaseVendor` 抽象基类 + `NativeAnthropicVendor` + 9 个具体实现 | [供应商模块](./arch/vendors.md) | +| **routing** | [`routing/`](../src/coding/proxy/routing/) | N-tier 链式路由核心(正交分解为 executor/tier/CB/QG/retry/rate_limit 等 12 个子模块) | [路由模块](./arch/routing.md) | +| **compat** | [`compat/`](../src/coding/proxy/compat/) | 兼容性抽象系统:`CanonicalRequest` / `CompatibilityDecision` / `session_store` | | +| **auth** | [`auth/`](../src/coding/proxy/auth/) | 认证系统:OAuth providers(GitHub Device Flow / Google OAuth2)/ runtime reauth / token store | | +| **model** | [`model/`](../src/coding/proxy/model/) | 数据模型正交分解:vendor / compat / constants / pricing / token / auth | | +| **config** | [`config/`](../src/coding/proxy/config/) | Pydantic v2 配置模型(正交拆分为 server/vendors/resiliency/routing/auth_schema)+ YAML 加载器 | [配置参考](./arch/config-reference.md) | +| **convert** | [`convert/`](../src/coding/proxy/convert/) | API 格式转换(Anthropic ↔ Gemini ↔ OpenAI 三向转换,含 SSE 流适配) | [格式转换](./arch/convert.md) | +| **logging** | [`logging/`](../src/coding/proxy/logging/) | Token 用量 SQLite 持久化([`db.py`](../src/coding/proxy/logging/db.py))、统计查询([`stats.py`](../src/coding/proxy/logging/stats.py))、Rich 格式化 | | +| **server** | [`server/`](../src/coding/proxy/server/) | FastAPI 应用工厂与生命周期管理(app/factory/routes/normalizer/responses/dashboard) | | +| **streaming** | [`streaming/`](../src/coding/proxy/streaming/) | Anthropic 兼容流式处理([`anthropic_compat.py`](../src/coding/proxy/streaming/anthropic_compat.py)) | | +| **cli** | [`cli/`](../src/coding/proxy/cli/) | Typer 命令行入口(start/status/usage/reset/auth)+ Banner 显示 | | +| **pricing** | [`pricing.py`](../src/coding/pricing.py) | 定价表(`PricingTable`):按 (vendor, model) 查询单价并计算费用 | | --- @@ -304,11 +304,11 @@ flowchart TD 故障转移的判定在 `BaseVendor.should_trigger_failover()` 中实现,依据三层条件(可通过配置文件自定义): -| 层级 | 条件 | 默认值 | -| ----------- | ------------------------------------------ | ------------------------------------------------------- | -| HTTP 状态码 | `status_code in failover.status_codes` | `[429, 403, 503, 500, 529]` | -| 错误类型 | `error.type in failover.error_types` | `["rate_limit_error", "overloaded_error", "api_error"]` | -| 错误消息 | `pattern in error.message`(不区分大小写) | `["quota", "limit exceeded", "usage cap", "capacity", "internal network failure"]` | +| 层级 | 条件 | 默认值 | +| ----------- | ------------------------------------------ | ---------------------------------------------------------------------------------- | +| HTTP 状态码 | `status_code in failover.status_codes` | `[429, 403, 503, 500, 529]` | +| 错误类型 | `error.type in failover.error_types` | `["rate_limit_error", "overloaded_error", "api_error"]` | +| 错误消息 | `pattern in error.message`(不区分大小写) | `["quota", "limit exceeded", "usage cap", "capacity", "internal network failure"]` | **特殊规则**:对于 429 和 503 状态码,即使无法解析响应体(body),也会强制触发故障转移。 @@ -351,30 +351,30 @@ flowchart TD 数据模型正交分解,遵循单一职责原则: -| 子模块 | 文件 | 核心类型 | -| ------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| **vendor** | [`model/vendor.py`](../src/coding/proxy/model/vendor.py) | `UsageInfo`, `VendorResponse`, `NoCompatibleVendorError`, `RequestCapabilities`, `VendorCapabilities`, `CapabilityLossReason` | -| **compat** | [`model/compat.py`](../src/coding/proxy/model/compat.py) | `CanonicalRequest`, `CompatibilityDecision`, `CompatibilityProfile`, `CompatibilityStatus`, `CompatibilityTrace` | -| **constants** | [`model/constants.py`](../src/coding/proxy/model/constants.py) | `PROXY_SKIP_HEADERS`, `RESPONSE_SANITIZE_SKIP_HEADERS` 等常量 | -| **pricing** | [`model/pricing.py`](../src/coding/proxy/model/pricing.py) | `ModelPricing`, `CostValue`, `Currency` | -| **token** | [`model/token.py`](../src/coding/proxy/model/token.py) | Token 相关模型 | -| **auth** | [`model/auth.py`](../src/coding/proxy/model/auth.py) | 认证相关模型 | +| 子模块 | 文件 | 核心类型 | +| ------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | +| **vendor** | [`model/vendor.py`](../src/coding/proxy/model/vendor.py) | `UsageInfo`, `VendorResponse`, `NoCompatibleVendorError`, `RequestCapabilities`, `VendorCapabilities`, `CapabilityLossReason` | +| **compat** | [`model/compat.py`](../src/coding/proxy/model/compat.py) | `CanonicalRequest`, `CompatibilityDecision`, `CompatibilityProfile`, `CompatibilityStatus`, `CompatibilityTrace` | +| **constants** | [`model/constants.py`](../src/coding/proxy/model/constants.py) | `PROXY_SKIP_HEADERS`, `RESPONSE_SANITIZE_SKIP_HEADERS` 等常量 | +| **pricing** | [`model/pricing.py`](../src/coding/proxy/model/pricing.py) | `ModelPricing`, `CostValue`, `Currency` | +| **token** | [`model/token.py`](../src/coding/proxy/model/token.py) | Token 相关模型 | +| **auth** | [`model/auth.py`](../src/coding/proxy/model/auth.py) | 认证相关模型 | ### 4.3 auth/ — 认证模块 -| 组件 | 文件 | 职责 | -| ---------------------------- | ---------------------------------------------------------------------- | ---------------------------------------------- | -| **GitHubDeviceFlowProvider** | [`providers/github.py`](../src/coding/proxy/auth/providers/github.py) | GitHub Device Authorization Grant | -| **GoogleOAuthProvider** | [`providers/google.py`](../src/coding/proxy/auth/providers/google.py) | OAuth 2.0 Authorization Code + Refresh Token | -| **RuntimeReauthCoordinator** | [`runtime.py`](../src/coding/proxy/auth/runtime.py) | 运行时 OAuth 重认证协调(IDLE → PENDING → COMPLETED / FAILED) | -| **TokenStoreManager** | [`store.py`](../src/coding/proxy/auth/store.py) | Token 持久化(JSON 文件),按 provider 分区存储 | +| 组件 | 文件 | 职责 | +| ---------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------- | +| **GitHubDeviceFlowProvider** | [`providers/github.py`](../src/coding/proxy/auth/providers/github.py) | GitHub Device Authorization Grant | +| **GoogleOAuthProvider** | [`providers/google.py`](../src/coding/proxy/auth/providers/google.py) | OAuth 2.0 Authorization Code + Refresh Token | +| **RuntimeReauthCoordinator** | [`runtime.py`](../src/coding/proxy/auth/runtime.py) | 运行时 OAuth 重认证协调(IDLE → PENDING → COMPLETED / FAILED) | +| **TokenStoreManager** | [`store.py`](../src/coding/proxy/auth/store.py) | Token 持久化(JSON 文件),按 provider 分区存储 | ### 4.4 logging/ — 日志模块 -| 组件 | 文件 | 职责 | -| ----------------- | -------------------------------------------------------------- | -------------------------------------- | -| **TokenLogger** | [`db.py`](../src/coding/proxy/logging/db.py) | SQLite 用量持久化、窗口查询、evidence 记录 | -| **统计工具** | [`stats.py`](../src/coding/proxy/logging/stats.py) | 统计查询与 Rich 格式化展示 | +| 组件 | 文件 | 职责 | +| --------------- | -------------------------------------------------- | ------------------------------------------ | +| **TokenLogger** | [`db.py`](../src/coding/proxy/logging/db.py) | SQLite 用量持久化、窗口查询、evidence 记录 | +| **统计工具** | [`stats.py`](../src/coding/proxy/logging/stats.py) | 统计查询与 Rich 格式化展示 | **usage_log 表结构**: @@ -396,14 +396,14 @@ flowchart TD ### 4.5 server/ — 服务模块 -| 文件 | 职责 | -| ---------------------------------------------------------------------------------- | --------------------------------------------------------- | -| [`app.py`](../src/coding/proxy/server/app.py) | FastAPI 应用工厂 `create_app()` + `lifespan` 生命周期管理 | -| [`factory.py`](../src/coding/proxy/server/factory.py) | Vendor/Tier 构建工厂 + 凭证解析 | -| [`routes.py`](../src/coding/proxy/server/routes.py) | 路由端点按职责分组注册 | -| [`request_normalizer.py`](../src/coding/proxy/server/request_normalizer.py) | 入站请求标准化(清洗供应商私有块) | -| [`responses.py`](../src/coding/proxy/server/responses.py) | 响应辅助工具(JSON error / stream error 构建) | -| [`dashboard.py`](../src/coding/proxy/server/dashboard.py) | 状态面板(Web Dashboard) | +| 文件 | 职责 | +| --------------------------------------------------------------------------- | --------------------------------------------------------- | +| [`app.py`](../src/coding/proxy/server/app.py) | FastAPI 应用工厂 `create_app()` + `lifespan` 生命周期管理 | +| [`factory.py`](../src/coding/proxy/server/factory.py) | Vendor/Tier 构建工厂 + 凭证解析 | +| [`routes.py`](../src/coding/proxy/server/routes.py) | 路由端点按职责分组注册 | +| [`request_normalizer.py`](../src/coding/proxy/server/request_normalizer.py) | 入站请求标准化(清洗供应商私有块) | +| [`responses.py`](../src/coding/proxy/server/responses.py) | 响应辅助工具(JSON error / stream error 构建) | +| [`dashboard.py`](../src/coding/proxy/server/dashboard.py) | 状态面板(Web Dashboard) | **API 端点清单**: @@ -477,14 +477,14 @@ model_mapping: ## 6. 文档索引 -| 文档 | 内容 | -| ---------------------------------------------------------------------- | ---------------------------------------- | -| [设计模式详解](./arch/design-patterns.md) | 13 种设计模式(Template Method / Circuit Breaker / State Machine 等)与工程模式 | -| [供应商模块](./arch/vendors.md) | 供应商分类体系、9 个具体供应商 + 2 个抽象基类、数据类型 | -| [路由模块](./arch/routing.md) | 12 个路由子模块详解(VendorTier / Executor / CB / QG / Retry 等) | -| [配置参考](./arch/config-reference.md) | 完整配置字段参考、弹性参数规范来源(SSOT) | -| [格式转换](./arch/convert.md) | Anthropic ↔ Gemini ↔ OpenAI 三向格式转换详解 | -| [测试策略](./arch/testing.md) | 48 个测试文件按子系统分组的覆盖范围与工具链 | +| 文档 | 内容 | +| ----------------------------------------- | ------------------------------------------------------------------------------- | +| [设计模式详解](./arch/design-patterns.md) | 13 种设计模式(Template Method / Circuit Breaker / State Machine 等)与工程模式 | +| [供应商模块](./arch/vendors.md) | 供应商分类体系、9 个具体供应商 + 2 个抽象基类、数据类型 | +| [路由模块](./arch/routing.md) | 12 个路由子模块详解(VendorTier / Executor / CB / QG / Retry 等) | +| [配置参考](./arch/config-reference.md) | 完整配置字段参考、弹性参数规范来源(SSOT) | +| [格式转换](./arch/convert.md) | Anthropic ↔ Gemini ↔ OpenAI 三向格式转换详解 | +| [测试策略](./arch/testing.md) | 48 个测试文件按子系统分组的覆盖范围与工具链 | --- diff --git a/docs/guide/api-reference.md b/docs/guide/api-reference.md index 4ff1597..6b950cf 100644 --- a/docs/guide/api-reference.md +++ b/docs/guide/api-reference.md @@ -3,22 +3,26 @@
📑 目录(点击展开) -- [1. HEAD / 和 GET /](#1-head--和-get-) -- [2. POST /v1/messages](#2-post-v1messages) - - [2.1 请求格式](#21-请求格式) - - [2.2 非流式响应](#22-非流式响应) - - [2.3 流式响应(SSE)](#23-流式响应sse) - - [2.4 错误响应](#24-错误响应) - - [2.5 请求规范化行为](#25-请求规范化行为) -- [3. POST /v1/messages/count_tokens](#3-post-v1messagescount_tokens) -- [4. GET /health](#4-get-health) -- [5. GET /api/status](#5-get-apistatus) -- [6. POST /api/reset](#6-post-apireset) -- [7. GET /api/copilot/diagnostics](#7-get-apicopilotdiagnostics) -- [8. GET /api/copilot/models](#8-get-apicopilotmodels) -- [9. GET /api/reauth/status](#9-get-apireauthstatus) -- [10. POST /api/reauth/{provider}](#10-post-apireauthprovider) -- [11. Dashboard 端点](#11-dashboard-端点) +- [HTTP API 端点](#http-api-端点) + - [1. HEAD / 和 GET /](#1-head--和-get-) + - [2. POST /v1/messages](#2-post-v1messages) + - [2.1 请求格式](#21-请求格式) + - [2.2 非流式响应](#22-非流式响应) + - [2.3 流式响应(SSE)](#23-流式响应sse) + - [2.4 错误响应](#24-错误响应) + - [2.5 请求规范化行为](#25-请求规范化行为) + - [3. POST /v1/messages/count\_tokens](#3-post-v1messagescount_tokens) + - [4. GET /health](#4-get-health) + - [5. GET /api/status](#5-get-apistatus) + - [6. POST /api/reset](#6-post-apireset) + - [7. GET /api/copilot/diagnostics](#7-get-apicopilotdiagnostics) + - [8. GET /api/copilot/models](#8-get-apicopilotmodels) + - [9. GET /api/reauth/status](#9-get-apireauthstatus) + - [10. POST /api/reauth/{provider}](#10-post-apireauthprovider) + - [11. Dashboard 端点](#11-dashboard-端点) + - [11.1 GET /dashboard](#111-get-dashboard) + - [11.2 GET /api/dashboard/summary](#112-get-apidashboardsummary) + - [11.3 GET /api/dashboard/timeline](#113-get-apidashboardtimeline)
@@ -39,42 +43,42 @@ curl -I http://127.0.0.1:8046/ **请求头** -| 请求头 | 必填 | 说明 | -|--------|------|------| -| `Content-Type` | ✓ | 固定为 `application/json` | -| `Authorization` | ✗ | 格式 `Bearer `;对 Anthropic vendor 透传,对其他 vendor 由代理内部凭证管理 | -| `anthropic-version` | ✗ | Anthropic API 版本,建议传 `2023-06-01`;透传至上游 | -| `anthropic-beta` | ✗ | Beta 功能标识,透传至上游 | +| 请求头 | 必填 | 说明 | +| ------------------- | ---- | --------------------------------------------------------------------------------- | +| `Content-Type` | ✓ | 固定为 `application/json` | +| `Authorization` | ✗ | 格式 `Bearer `;对 Anthropic vendor 透传,对其他 vendor 由代理内部凭证管理 | +| `anthropic-version` | ✗ | Anthropic API 版本,建议传 `2023-06-01`;透传至上游 | +| `anthropic-beta` | ✗ | Beta 功能标识,透传至上游 | > `hop-by-hop` 头(如 `Connection`、`Transfer-Encoding`)会在转发前自动过滤。 **请求体参数** -| 字段 | 类型 | 必填 | 约束 | 说明 | -|------|------|------|------|------| -| `model` | string | ✓ | 非空 | 目标模型标识。经 [`model_mapping`](./vendors.md#5-model_mapping--模型映射规则) 规则映射后路由至实际 vendor 模型 | -| `messages` | array | ✓ | 至少 1 条;`user`/`assistant` 交替;末尾必须为 `user` | 对话历史 | -| `max_tokens` | integer | ✗ | > 0 | 最大输出 token 数 | -| `stream` | boolean | ✗ | 默认 `false` | 是否以 SSE 流式返回 | -| `temperature` | number | ✗ | `[0, 2]` | 采样温度 | -| `top_p` | number | ✗ | `(0, 1]` | Top-p 采样 | -| `top_k` | integer | ✗ | ≥ 1 | Top-k 采样 | -| `stop_sequences` | array[string] | ✗ | | 提前停止的字符串序列 | -| `system` | string \| array | ✗ | | 系统提示词 | -| `tools` | array | ✗ | | 工具定义 | -| `tool_choice` | object | ✗ | | 工具选择策略 | -| `thinking` | object | ✗ | 需 `budget_tokens`;部分 vendor 不支持 | Extended Thinking 配置 | -| `metadata` | object | ✗ | | 用户元数据,透传至上游 | +| 字段 | 类型 | 必填 | 约束 | 说明 | +| ---------------- | --------------- | ---- | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | +| `model` | string | ✓ | 非空 | 目标模型标识。经 [`model_mapping`](./vendors.md#5-model_mapping--模型映射规则) 规则映射后路由至实际 vendor 模型 | +| `messages` | array | ✓ | 至少 1 条;`user`/`assistant` 交替;末尾必须为 `user` | 对话历史 | +| `max_tokens` | integer | ✗ | > 0 | 最大输出 token 数 | +| `stream` | boolean | ✗ | 默认 `false` | 是否以 SSE 流式返回 | +| `temperature` | number | ✗ | `[0, 2]` | 采样温度 | +| `top_p` | number | ✗ | `(0, 1]` | Top-p 采样 | +| `top_k` | integer | ✗ | ≥ 1 | Top-k 采样 | +| `stop_sequences` | array[string] | ✗ | | 提前停止的字符串序列 | +| `system` | string \| array | ✗ | | 系统提示词 | +| `tools` | array | ✗ | | 工具定义 | +| `tool_choice` | object | ✗ | | 工具选择策略 | +| `thinking` | object | ✗ | 需 `budget_tokens`;部分 vendor 不支持 | Extended Thinking 配置 | +| `metadata` | object | ✗ | | 用户元数据,透传至上游 | **消息 content block 类型** -| 类型 | 适用角色 | 必填字段 | 说明 | -|------|---------|---------|------| -| `text` | `user`/`assistant` | `text` | 纯文本 | -| `image` | `user` | `source` | 图片;部分 vendor 不支持 | -| `tool_use` | `assistant` | `id`(`toolu_` 前缀)、`name`、`input` | 模型发起工具调用 | -| `tool_result` | `user` | `tool_use_id`、`content` | 工具调用结果 | -| `thinking` | `assistant` | `thinking`、`signature` | Extended Thinking;跨 vendor 时自动剥离 | +| 类型 | 适用角色 | 必填字段 | 说明 | +| ------------- | ------------------ | -------------------------------------- | --------------------------------------- | +| `text` | `user`/`assistant` | `text` | 纯文本 | +| `image` | `user` | `source` | 图片;部分 vendor 不支持 | +| `tool_use` | `assistant` | `id`(`toolu_` 前缀)、`name`、`input` | 模型发起工具调用 | +| `tool_result` | `user` | `tool_use_id`、`content` | 工具调用结果 | +| `thinking` | `assistant` | `thinking`、`signature` | Extended Thinking;跨 vendor 时自动剥离 | ### 2.2 非流式响应 @@ -102,12 +106,12 @@ curl -I http://127.0.0.1:8046/ **`stop_reason` 枚举** -| 值 | 含义 | -|----|------| -| `end_turn` | 模型自然输出完毕 | -| `tool_use` | 模型发起工具调用 | -| `stop_sequence` | 触发了停止序列 | -| `max_tokens` | 达到 `max_tokens` 上限 | +| 值 | 含义 | +| --------------- | ---------------------- | +| `end_turn` | 模型自然输出完毕 | +| `tool_use` | 模型发起工具调用 | +| `stop_sequence` | 触发了停止序列 | +| `max_tokens` | 达到 `max_tokens` 上限 | ### 2.3 流式响应(SSE) @@ -115,16 +119,16 @@ curl -I http://127.0.0.1:8046/ **SSE 事件类型** -| 事件类型 | 说明 | -|---------|------| -| `message_start` | 消息开始,包含初始元数据 | -| `content_block_start` | 新的 content block 开始 | +| 事件类型 | 说明 | +| --------------------- | ---------------------------------------------- | +| `message_start` | 消息开始,包含初始元数据 | +| `content_block_start` | 新的 content block 开始 | | `content_block_delta` | 增量数据(`text_delta` 或 `input_json_delta`) | -| `content_block_stop` | 当前 content block 结束 | -| `message_delta` | 消息级增量(`stop_reason` + `usage`) | -| `message_stop` | 消息结束 | -| `ping` | 心跳 | -| `error` | 流式错误 | +| `content_block_stop` | 当前 content block 结束 | +| `message_delta` | 消息级增量(`stop_reason` + `usage`) | +| `message_stop` | 消息结束 | +| `ping` | 心跳 | +| `error` | 流式错误 | > 流式模式下,一旦 SSE 流开始发送,代理不再进行 tier 级别的故障转移。若中途出现错误,以 `event: error` 事件通知客户端。 @@ -144,16 +148,16 @@ curl -I http://127.0.0.1:8046/ **HTTP 状态码对照** -| HTTP 状态码 | `error.type` | 触发场景 | 可重试 | -|------------|-------------|---------|--------| -| `400` | `invalid_request_error` | 请求格式不合规、无兼容 vendor | ✗ | -| `401` | `authentication_error` | 无有效认证凭证 | ✗ | -| `403` | `permission_error` | 权限不足 | ✗ | -| `429` | `rate_limit_error` | 所有 vendor 均触发速率限制 | ✓ | -| `500` | `api_error` | 代理内部异常 | ✓ | -| `502` | `api_error` | 所有 vendor 均不可达 | ✓ | -| `503` | `authentication_error` | Token 获取失败 | ✓ | -| `501` | `not_implemented` | 请求的端点无可用 vendor 处理 | ✗ | +| HTTP 状态码 | `error.type` | 触发场景 | 可重试 | +| ----------- | ----------------------- | ----------------------------- | ------ | +| `400` | `invalid_request_error` | 请求格式不合规、无兼容 vendor | ✗ | +| `401` | `authentication_error` | 无有效认证凭证 | ✗ | +| `403` | `permission_error` | 权限不足 | ✗ | +| `429` | `rate_limit_error` | 所有 vendor 均触发速率限制 | ✓ | +| `500` | `api_error` | 代理内部异常 | ✓ | +| `502` | `api_error` | 所有 vendor 均不可达 | ✓ | +| `503` | `authentication_error` | Token 获取失败 | ✓ | +| `501` | `not_implemented` | 请求的端点无可用 vendor 处理 | ✗ | ### 2.5 请求规范化行为 @@ -161,22 +165,22 @@ curl -I http://127.0.0.1:8046/ **自动修复(静默处理)** -| 问题 | 处理方式 | -|------|---------| -| `tool_use_id` 格式不符(非 `toolu_` 前缀) | 自动重写为合规格式 | -| `tool_result` 出现在 `assistant` 消息中 | 收集该 block;转发至 Anthropic tier 时执行重定位,其他 vendor 保留原位不变(首次触发 WARNING 日志) | -| `tool_use` 缺少合法 ID | 自动生成新 ID | +| 问题 | 处理方式 | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------- | +| `tool_use_id` 格式不符(非 `toolu_` 前缀) | 自动重写为合规格式 | +| `tool_result` 出现在 `assistant` 消息中 | 收集该 block;转发至 Anthropic tier 时执行重定位,其他 vendor 保留原位不变(首次触发 WARNING 日志) | +| `tool_use` 缺少合法 ID | 自动生成新 ID | **致命验证错误(返回 HTTP 400)** -| 场景 | 错误示例 | -|------|---------| -| `tool_use` block 缺少 `id` 字段 | `"tool_use block is missing 'id' field"` | -| `tool_use` block 缺少 `name` 字段 | `"tool_use block missing name for id rewrite"` | -| `tool_result` block 缺少 `tool_use_id` 字段 | `"tool_result block is missing 'tool_use_id' field"` | -| `tool_result` 引用不存在的 `tool_use_id` | `"tool_result references unknown tool_use_id"` | -| 消息角色不交替 | `"messages must alternate between user and assistant"` | -| `messages` 末尾不是 `user` 消息 | `"last message must be from user"` | +| 场景 | 错误示例 | +| ------------------------------------------- | ------------------------------------------------------ | +| `tool_use` block 缺少 `id` 字段 | `"tool_use block is missing 'id' field"` | +| `tool_use` block 缺少 `name` 字段 | `"tool_use block missing name for id rewrite"` | +| `tool_result` block 缺少 `tool_use_id` 字段 | `"tool_result block is missing 'tool_use_id' field"` | +| `tool_result` 引用不存在的 `tool_use_id` | `"tool_result references unknown tool_use_id"` | +| 消息角色不交替 | `"messages must alternate between user and assistant"` | +| `messages` 末尾不是 `user` 消息 | `"last message must be from user"` | **Thinking Block 跨 Vendor 处理**:请求路由至非 Anthropic vendor 时,assistant 历史消息中的 `thinking` block 会被自动剥离(包含仅 Anthropic 可验证的 `signature`)。不影响当前轮次的 `thinking` 功能配置。 @@ -191,11 +195,11 @@ curl -X POST http://127.0.0.1:8046/v1/messages/count_tokens \ -d '{"model":"claude-sonnet-4-6","messages":[{"role":"user","content":"Hello"}]}' ``` -| 响应码 | 说明 | -|--------|------| -| `200` | 成功,返回 token 计数结果 | -| `501` | 无可用 vendor 处理此端点 | -| `502` | 上游 API 不可达 | +| 响应码 | 说明 | +| ------ | ------------------------- | +| `200` | 成功,返回 token 计数结果 | +| `501` | 无可用 vendor 处理此端点 | +| `502` | 上游 API 不可达 | ## 4. GET /health @@ -311,8 +315,8 @@ curl -X POST http://127.0.0.1:8046/api/reauth/github # {"status":"reauth requested"} ``` -| 参数 | 说明 | -|------|------| +| 参数 | 说明 | +| ------------ | ---------------------------------- | | `{provider}` | provider 名称:`github` / `google` | 返回 202 表示重认证请求已接收,用户需在浏览器中完成授权。 @@ -337,9 +341,9 @@ curl http://127.0.0.1:8046/dashboard curl "http://127.0.0.1:8046/api/dashboard/summary?days=7" ``` -| 参数 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `days` | int | `7` | 统计天数(1~90) | +| 参数 | 类型 | 默认值 | 说明 | +| ------ | ---- | ------ | ---------------- | +| `days` | int | `7` | 统计天数(1~90) | **返回结构**:`version`(版本号)、`today`(今日 KPI)、`range`(区间 KPI)、`failover_stats`(故障转移统计)。 @@ -351,8 +355,8 @@ curl "http://127.0.0.1:8046/api/dashboard/summary?days=7" curl "http://127.0.0.1:8046/api/dashboard/timeline?days=30" ``` -| 参数 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `days` | int | `7` | 统计天数(1~90) | +| 参数 | 类型 | 默认值 | 说明 | +| ------ | ---- | ------ | ---------------- | +| `days` | int | `7` | 统计天数(1~90) | **返回结构**:`period`(`"day"`)、`count`(天数)、`rows`(按天分组的用量数组)。 diff --git a/docs/guide/cli-reference.md b/docs/guide/cli-reference.md index 9fa9af6..052d237 100644 --- a/docs/guide/cli-reference.md +++ b/docs/guide/cli-reference.md @@ -3,14 +3,15 @@
📑 目录(点击展开) -- [1. coding-proxy start](#1-coding-proxy-start) -- [2. coding-proxy status](#2-coding-proxy-status) -- [3. coding-proxy usage](#3-coding-proxy-usage) -- [4. coding-proxy reset](#4-coding-proxy-reset) -- [5. coding-proxy auth login](#5-coding-proxy-auth-login) -- [6. coding-proxy auth status](#6-coding-proxy-auth-status) -- [7. coding-proxy auth reauth](#7-coding-proxy-auth-reauth) -- [8. coding-proxy auth logout](#8-coding-proxy-auth-logout) +- [CLI 命令参考](#cli-命令参考) + - [1. coding-proxy start](#1-coding-proxy-start) + - [2. coding-proxy status](#2-coding-proxy-status) + - [3. coding-proxy usage](#3-coding-proxy-usage) + - [4. coding-proxy reset](#4-coding-proxy-reset) + - [5. coding-proxy auth login](#5-coding-proxy-auth-login) + - [6. coding-proxy auth status](#6-coding-proxy-auth-status) + - [7. coding-proxy auth reauth](#7-coding-proxy-auth-reauth) + - [8. coding-proxy auth logout](#8-coding-proxy-auth-logout)
@@ -22,11 +23,11 @@ coding-proxy start [OPTIONS] ``` -| 参数 | 缩写 | 说明 | -|------|------|------| -| `--config` | `-c` | 配置文件路径 | -| `--port` | `-p` | 监听端口(覆盖配置文件) | -| `--host` | `-h` | 监听地址(覆盖配置文件) | +| 参数 | 缩写 | 说明 | +| ---------- | ---- | ------------------------ | +| `--config` | `-c` | 配置文件路径 | +| `--port` | `-p` | 监听端口(覆盖配置文件) | +| `--host` | `-h` | 监听地址(覆盖配置文件) | **示例**: @@ -51,8 +52,8 @@ coding-proxy start --host 0.0.0.0 --port 8046 coding-proxy status [OPTIONS] ``` -| 参数 | 缩写 | 说明 | -|------|------|------| +| 参数 | 缩写 | 说明 | +| -------- | ---- | ------------------------- | | `--port` | `-p` | 代理服务端口(默认 8046) | **输出示例**: @@ -70,11 +71,11 @@ anthropic **熔断器状态说明**: -| 状态 | 含义 | -|------|------| -| `closed` | 正常运行 | -| `open` | 熔断中,跳过该层降级到下一层 | -| `half_open` | 恢复测试中 | +| 状态 | 含义 | +| ----------- | ---------------------------- | +| `closed` | 正常运行 | +| `open` | 熔断中,跳过该层降级到下一层 | +| `half_open` | 恢复测试中 | ## 3. coding-proxy usage @@ -84,15 +85,15 @@ anthropic coding-proxy usage [OPTIONS] ``` -| 参数 | 缩写 | 说明 | -|------|------|------| -| `--days` | `-d` | 统计天数(默认 7) | -| `--week` | `-w` | 最近第 N 周统计(按周聚合,默认 1) | -| `--month` | `-m` | 最近第 N 月统计(按月聚合,默认 1) | -| `--total` | `-t` | 统计全部历史记录(按供应商+模型聚合) | -| `--vendor` | `-v` | 过滤供应商(支持逗号分隔多选,如 `anthropic,zhipu`) | -| `--model` | — | 过滤实际服务模型(支持逗号分隔多选,如 `glm-5v-turbo,glm-5.1`) | -| `--db` | — | 数据库文件路径 | +| 参数 | 缩写 | 说明 | +| ---------- | ---- | --------------------------------------------------------------- | +| `--days` | `-d` | 统计天数(默认 7) | +| `--week` | `-w` | 最近第 N 周统计(按周聚合,默认 1) | +| `--month` | `-m` | 最近第 N 月统计(按月聚合,默认 1) | +| `--total` | `-t` | 统计全部历史记录(按供应商+模型聚合) | +| `--vendor` | `-v` | 过滤供应商(支持逗号分隔多选,如 `anthropic,zhipu`) | +| `--model` | — | 过滤实际服务模型(支持逗号分隔多选,如 `glm-5v-turbo,glm-5.1`) | +| `--db` | — | 数据库文件路径 | > **时间维度互斥**,优先级:`-t > -m > -w > -d`。 @@ -120,17 +121,17 @@ coding-proxy usage --model glm-5v-turbo,claude-sonnet-4-6 **输出字段说明**: -| 字段 | 说明 | -|------|------| -| 日期 | 统计日期 | -| 供应商 | 处理请求的供应商名称 | -| 请求模型 | 客户端请求的原始模型名称 | -| 实际模型 | 供应商实际使用的模型名称(经映射后) | -| 请求数 | 总请求数 | -| 输入/输出/缓存创建/缓存读取 Token | 各维度 Token 消耗 | -| 总 Token | 所有维度之和 | -| Cost | 基于定价配置计算的费用;未配置定价时显示 `-` | -| 平均耗时(ms) | 平均响应时间 | +| 字段 | 说明 | +| --------------------------------- | -------------------------------------------- | +| 日期 | 统计日期 | +| 供应商 | 处理请求的供应商名称 | +| 请求模型 | 客户端请求的原始模型名称 | +| 实际模型 | 供应商实际使用的模型名称(经映射后) | +| 请求数 | 总请求数 | +| 输入/输出/缓存创建/缓存读取 Token | 各维度 Token 消耗 | +| 总 Token | 所有维度之和 | +| Cost | 基于定价配置计算的费用;未配置定价时显示 `-` | +| 平均耗时(ms) | 平均响应时间 | ## 4. coding-proxy reset @@ -140,9 +141,9 @@ coding-proxy usage --model glm-5v-turbo,claude-sonnet-4-6 coding-proxy reset [OPTIONS] ``` -| 参数 | 缩写 | 说明 | -|------|------|------| -| `--port` | `-p` | 代理服务端口(默认 8046) | +| 参数 | 缩写 | 说明 | +| ---------- | ---- | ----------------------------------------------- | +| `--port` | `-p` | 代理服务端口(默认 8046) | | `--vendor` | `-v` | 提升/重排序 vendor 优先级(单个或逗号分隔多个) | **重排序语义**: @@ -167,8 +168,8 @@ coding-proxy reset [OPTIONS] coding-proxy auth login [OPTIONS] ``` -| 参数 | 缩写 | 说明 | -|------|------|------| +| 参数 | 缩写 | 说明 | +| ------------ | ---- | -------------------------------------------------------- | | `--provider` | `-p` | 指定 provider(`github` / `google`);省略则依次登录两者 | **示例**: @@ -207,10 +208,10 @@ google: 已过期 无 refresh_token coding-proxy auth reauth PROVIDER [OPTIONS] ``` -| 参数 | 缩写 | 说明 | -|------|------|------| -| `PROVIDER` | — | provider 名称(必填):`github` / `google` | -| `--port` | `-p` | 代理服务端口(默认 8046) | +| 参数 | 缩写 | 说明 | +| ---------- | ---- | ------------------------------------------ | +| `PROVIDER` | — | provider 名称(必填):`github` / `google` | +| `--port` | `-p` | 代理服务端口(默认 8046) | **示例**: @@ -232,6 +233,6 @@ coding-proxy auth reauth google -p 9090 coding-proxy auth logout [OPTIONS] ``` -| 参数 | 缩写 | 说明 | -|------|------|------| +| 参数 | 缩写 | 说明 | +| ------------ | ---- | -------------------------------------- | | `--provider` | `-p` | 指定 provider;省略则登出所有 provider | diff --git a/docs/guide/dashboard.md b/docs/guide/dashboard.md index 5cbeac6..8872b20 100644 --- a/docs/guide/dashboard.md +++ b/docs/guide/dashboard.md @@ -16,24 +16,24 @@ http://127.0.0.1:8046/dashboard 顶部展示核心指标: -| 卡片 | 说明 | -|------|------| -| 今日请求数 | 当日总请求数(子行显示本周累计) | -| 今日 Token 总量 | 当日总 Token 消耗(子行显示本周累计) | -| 今日输出 Token | 当日输出 Token 数(子行显示本周累计) | -| 今日费用估算 | 基于定价配置的费用估算(子行显示本周累计) | -| 故障转移(今日) | 当日故障转移事件数(子行显示本周累计) | -| 平均延迟(今日) | 当日请求平均响应时间(子行显示本周累计) | +| 卡片 | 说明 | +| ---------------- | ------------------------------------------ | +| 今日请求数 | 当日总请求数(子行显示本周累计) | +| 今日 Token 总量 | 当日总 Token 消耗(子行显示本周累计) | +| 今日输出 Token | 当日输出 Token 数(子行显示本周累计) | +| 今日费用估算 | 基于定价配置的费用估算(子行显示本周累计) | +| 故障转移(今日) | 当日故障转移事件数(子行显示本周累计) | +| 平均延迟(今日) | 当日请求平均响应时间(子行显示本周累计) | ### 图表 -| 图表 | 说明 | -|------|------| -| 供应商状态 | 各供应商实时状态(熔断器、配额守卫) | -| 请求时间线 | 按天的请求量趋势图 | -| 供应商分布 | 各供应商请求占比甜甜圈图 | -| Token 时间线(按供应商) | 各供应商按天的 Token 消耗堆叠图 | -| Token 时间线(按供应商+模型) | 细粒度的模型级 Token 消耗堆叠图 | +| 图表 | 说明 | +| ----------------------------- | ------------------------------------ | +| 供应商状态 | 各供应商实时状态(熔断器、配额守卫) | +| 请求时间线 | 按天的请求量趋势图 | +| 供应商分布 | 各供应商请求占比甜甜圈图 | +| Token 时间线(按供应商) | 各供应商按天的 Token 消耗堆叠图 | +| Token 时间线(按供应商+模型) | 细粒度的模型级 Token 消耗堆叠图 | ### 时间范围选择器 @@ -57,7 +57,7 @@ http://127.0.0.1:8046/dashboard 看板数据来自以下 API 端点,详见 [API 参考 — Dashboard 端点](./api-reference.md#11-dashboard-端点): -| 端点 | 说明 | -|------|------| -| `GET /api/dashboard/summary` | KPI 汇总数据 | +| 端点 | 说明 | +| ----------------------------- | -------------------- | +| `GET /api/dashboard/summary` | KPI 汇总数据 | | `GET /api/dashboard/timeline` | 按天分组的时间线数据 | diff --git a/docs/guide/monitoring.md b/docs/guide/monitoring.md index 6f2e492..69c32d2 100644 --- a/docs/guide/monitoring.md +++ b/docs/guide/monitoring.md @@ -18,13 +18,13 @@ 代理日志默认输出到控制台,包含以下关键事件: -| 事件 | 日志级别 | 示例 | -|------|---------|------| -| 熔断器状态转换 | INFO/WARNING | `Circuit breaker: CLOSED → OPEN (3 consecutive failures)` | -| 故障转移触发 | WARNING | `Primary error 429, failing over` | -| 恢复成功 | INFO | `Circuit breaker: HALF_OPEN → CLOSED (recovered)` | -| Rate Limit 生效 | INFO | `Tier zhipu: rate limit deadline active, 30.0s remaining` | -| 自动登录 | INFO | `Copilot 层缺少有效凭证,启动 GitHub OAuth 登录...` | +| 事件 | 日志级别 | 示例 | +| --------------- | ------------ | --------------------------------------------------------- | +| 熔断器状态转换 | INFO/WARNING | `Circuit breaker: CLOSED → OPEN (3 consecutive failures)` | +| 故障转移触发 | WARNING | `Primary error 429, failing over` | +| 恢复成功 | INFO | `Circuit breaker: HALF_OPEN → CLOSED (recovered)` | +| Rate Limit 生效 | INFO | `Tier zhipu: rate limit deadline active, 30.0s remaining` | +| 自动登录 | INFO | `Copilot 层缺少有效凭证,启动 GitHub OAuth 登录...` | 配置调整: @@ -89,14 +89,14 @@ curl http://127.0.0.1:8046/api/status ## 6. 性能调优参考 -| 参数 | 默认值 | 稳定优先 | 敏感快速 | 说明 | -|------|--------|---------|---------|------| -| `timeout_ms` | 300000 | `300000` | `120000` | 长对话保持 5 分钟;短查询可缩短至 2 分钟 | -| `failure_threshold` | 3 | `5` | `2` | 网络稳定环境降低以更快触发降级 | -| `recovery_timeout_seconds` | 300 | `600` | `120` | 给供应商更多恢复时间 vs 更快尝试恢复 | -| `token_budget` | 按计划 | 按计划设定 | — | 设为订阅额度的 95%~99% | -| `window_hours` (quota_guard) | 5.0 | `8.0` | `3.0` | 长窗口更平滑,短窗口更灵敏 | -| `max_retries` | 2 | `3` | `1` | 网络不稳定时增加重试 | +| 参数 | 默认值 | 稳定优先 | 敏感快速 | 说明 | +| ---------------------------- | ------ | ---------- | -------- | ---------------------------------------- | +| `timeout_ms` | 300000 | `300000` | `120000` | 长对话保持 5 分钟;短查询可缩短至 2 分钟 | +| `failure_threshold` | 3 | `5` | `2` | 网络稳定环境降低以更快触发降级 | +| `recovery_timeout_seconds` | 300 | `600` | `120` | 给供应商更多恢复时间 vs 更快尝试恢复 | +| `token_budget` | 按计划 | 按计划设定 | — | 设为订阅额度的 95%~99% | +| `window_hours` (quota_guard) | 5.0 | `8.0` | `3.0` | 长窗口更平滑,短窗口更灵敏 | +| `max_retries` | 2 | `3` | `1` | 网络不稳定时增加重试 | > 完整弹性参数表参见 [配置字段参考 — 弹性字段](../arch/config-reference.md#5-vendorconfig-弹性字段)。 diff --git a/docs/guide/vendors.md b/docs/guide/vendors.md index ce7fa8d..5c3eb05 100644 --- a/docs/guide/vendors.md +++ b/docs/guide/vendors.md @@ -3,21 +3,22 @@
📑 目录(点击展开) -- [1. 供应商分类](#1-供应商分类) -- [2. 通用字段](#2-通用字段) -- [3. 供应商配置详情](#3-供应商配置详情) - - [3.1 anthropic — Anthropic Claude](#31-anthropic--anthropic-claude) - - [3.2 copilot — GitHub Copilot](#32-copilot--github-copilot) - - [3.3 antigravity — Google Antigravity](#33-antigravity--google-antigravity) - - [3.4 zhipu — 智谱 GLM](#34-zhipu--智谱-glm) - - [3.5 minimax — MiniMax](#35-minimax--minimax) - - [3.6 alibaba — 阿里 Qwen](#36-alibaba--阿里-qwen) - - [3.7 xiaomi — 小米 MiMo](#37-xiaomi--小米-mimo) - - [3.8 kimi — Kimi](#38-kimi--kimi) - - [3.9 doubao — 豆包 Doubao](#39-doubao--豆包-doubao) -- [4. tiers — 降级链路优先级](#4-tiers--降级链路优先级) -- [5. model_mapping — 模型映射规则](#5-model_mapping--模型映射规则) -- [6. pricing — 模型定价](#6-pricing--模型定价) +- [供应商配置](#供应商配置) + - [1. 供应商分类](#1-供应商分类) + - [2. 通用字段](#2-通用字段) + - [3. 供应商配置详情](#3-供应商配置详情) + - [3.1 anthropic — Anthropic Claude](#31-anthropic--anthropic-claude) + - [3.2 copilot — GitHub Copilot](#32-copilot--github-copilot) + - [3.3 antigravity — Google Antigravity](#33-antigravity--google-antigravity) + - [3.4 zhipu — 智谱 GLM](#34-zhipu--智谱-glm) + - [3.5 minimax — MiniMax](#35-minimax--minimax) + - [3.6 alibaba — 阿里 Qwen](#36-alibaba--阿里-qwen) + - [3.7 xiaomi — 小米 MiMo](#37-xiaomi--小米-mimo) + - [3.8 kimi — Kimi](#38-kimi--kimi) + - [3.9 doubao — 豆包 Doubao](#39-doubao--豆包-doubao) + - [4. tiers — 降级链路优先级](#4-tiers--降级链路优先级) + - [5. model\_mapping — 模型映射规则](#5-model_mapping--模型映射规则) + - [6. pricing — 模型定价](#6-pricing--模型定价)
@@ -25,10 +26,10 @@ coding-proxy 支持三类供应商,共 9 种: -| 类别 | 供应商 | 说明 | -|------|--------|------| -| **直连 Anthropic** | `anthropic` | 直接透传请求到 Anthropic API | -| **协议转换** | `copilot`、`antigravity` | 内部完成认证交换与格式转换(Anthropic ↔ Gemini) | +| 类别 | 供应商 | 说明 | +| ----------------------- | --------------------------------------------------------- | -------------------------------------------------------- | +| **直连 Anthropic** | `anthropic` | 直接透传请求到 Anthropic API | +| **协议转换** | `copilot`、`antigravity` | 内部完成认证交换与格式转换(Anthropic ↔ Gemini) | | **原生 Anthropic 兼容** | `zhipu`、`minimax`、`alibaba`、`xiaomi`、`kimi`、`doubao` | 提供原生 Anthropic 兼容端点,仅需 `api_key` + `base_url` | > 类层次结构与设计细节参见 [架构文档 — 供应商模块](../arch/vendors.md)。 @@ -37,12 +38,12 @@ coding-proxy 支持三类供应商,共 9 种: 所有供应商共享以下字段。完整参数表参见 [配置字段参考 — 通用字段](../arch/config-reference.md#4-vendorconfig-通用字段)。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `vendor` | string | — | 供应商类型标识 | -| `enabled` | bool | `true` | 是否启用 | -| `base_url` | string | `""` | API 基础 URL;留空使用供应商默认值 | -| `timeout_ms` | int | `300000`/`3000000` | 请求超时(毫秒);直连/协议转换供应商默认 300000(5 分钟),原生 Anthropic 兼容供应商默认 3000000(50 分钟) | +| 字段 | 类型 | 默认值 | 说明 | +| ------------ | ------ | ------------------ | ------------------------------------------------------------------------------------------------------------ | +| `vendor` | string | — | 供应商类型标识 | +| `enabled` | bool | `true` | 是否启用 | +| `base_url` | string | `""` | API 基础 URL;留空使用供应商默认值 | +| `timeout_ms` | int | `300000`/`3000000` | 请求超时(毫秒);直连/协议转换供应商默认 300000(5 分钟),原生 Anthropic 兼容供应商默认 3000000(50 分钟) | 弹性设施字段(`circuit_breaker`、`quota_guard`、`weekly_quota_guard`、`retry`)参见 [配置字段参考 — 弹性字段](../arch/config-reference.md#5-vendorconfig-弹性字段)。 @@ -70,13 +71,13 @@ coding-proxy 支持三类供应商,共 9 种: 通过 GitHub Copilot 内部 API 调用 Claude 模型。需 OAuth 登录或手动配置 token。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `github_token` | string | `""` | GitHub OAuth token / PAT,支持 `${ENV_VAR}` | -| `account_type` | string | `"individual"` | 账号类型:`individual` / `business` / `enterprise` | -| `token_url` | string | `"https://api.github.com/copilot_internal/v2/token"` | Token 交换端点 | -| `base_url` | string | `""` | 留空时按 `account_type` 自动解析 | -| `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL(秒) | +| 字段 | 类型 | 默认值 | 说明 | +| -------------------------- | ------ | ---------------------------------------------------- | -------------------------------------------------- | +| `github_token` | string | `""` | GitHub OAuth token / PAT,支持 `${ENV_VAR}` | +| `account_type` | string | `"individual"` | 账号类型:`individual` / `business` / `enterprise` | +| `token_url` | string | `"https://api.github.com/copilot_internal/v2/token"` | Token 交换端点 | +| `base_url` | string | `""` | 留空时按 `account_type` 自动解析 | +| `models_cache_ttl_seconds` | int | `300` | 模型列表缓存 TTL(秒) | > 默认已启用(`enabled: true`)。首次启动时若缺少有效凭证,自动触发 GitHub Device Flow 浏览器登录。 > 可通过 [`GET /api/copilot/diagnostics`](./api-reference.md#7-get-apicopilotdiagnostics) 和 [`GET /api/copilot/models`](./api-reference.md#8-get-apicopilotmodels) 排查认证状态。 @@ -85,13 +86,13 @@ coding-proxy 支持三类供应商,共 9 种: 通过 Google Generative Language API 调用 Claude / Gemini 模型。代理自动处理 Anthropic ↔ Gemini 格式双向转换。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `client_id` | string | `""` | Google OAuth2 Client ID,支持 `${ENV_VAR}` | -| `client_secret` | string | `""` | Google OAuth2 Client Secret,支持 `${ENV_VAR}` | -| `refresh_token` | string | `""` | Google OAuth2 Refresh Token,支持 `${ENV_VAR}` | -| `base_url` | string | `"https://generativelanguage.googleapis.com/v1beta"` | Gemini API 基础地址 | -| `model_endpoint` | string | `"models/claude-sonnet-4-20250514"` | 模型端点路径(仅作为未命中映射时的默认模型) | +| 字段 | 类型 | 默认值 | 说明 | +| ---------------- | ------ | ---------------------------------------------------- | ---------------------------------------------- | +| `client_id` | string | `""` | Google OAuth2 Client ID,支持 `${ENV_VAR}` | +| `client_secret` | string | `""` | Google OAuth2 Client Secret,支持 `${ENV_VAR}` | +| `refresh_token` | string | `""` | Google OAuth2 Refresh Token,支持 `${ENV_VAR}` | +| `base_url` | string | `"https://generativelanguage.googleapis.com/v1beta"` | Gemini API 基础地址 | +| `model_endpoint` | string | `"models/claude-sonnet-4-20250514"` | 模型端点路径(仅作为未命中映射时的默认模型) | > 默认禁用(`enabled: false`)。启用需配置 OAuth 凭据,启动时自动触发 Google OAuth 登录。access_token 过期时优先静默刷新,无需重新登录。 @@ -99,10 +100,10 @@ coding-proxy 支持三类供应商,共 9 种: 通过智谱 GLM 官方 Anthropic 兼容端点调用模型。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `api_key` | string | `""` | 智谱 API Key,支持 `${ENV_VAR}` | -| `base_url` | string | `"https://open.bigmodel.cn/api/anthropic"` | API 基础地址 | +| 字段 | 类型 | 默认值 | 说明 | +| ---------- | ------ | ------------------------------------------ | ------------------------------- | +| `api_key` | string | `""` | 智谱 API Key,支持 `${ENV_VAR}` | +| `base_url` | string | `"https://open.bigmodel.cn/api/anthropic"` | API 基础地址 | > 默认已启用(`enabled: true`),且配置了 `circuit_breaker`(`recovery_timeout_seconds: 30`)和 `quota_guard`(`enabled: true`),属于中间层参与故障转移。默认作为 `tiers` 链路中的最高优先级(Tier 0)。 @@ -110,10 +111,10 @@ coding-proxy 支持三类供应商,共 9 种: 通过 MiniMax 原生 Anthropic 兼容端点调用模型。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `api_key` | string | `""` | MiniMax API Key,支持 `${ENV_VAR}`(`${MINIMAX_API_KEY}`) | -| `base_url` | string | `"https://api.minimaxi.com/anthropic"` | API 基础地址 | +| 字段 | 类型 | 默认值 | 说明 | +| ---------- | ------ | -------------------------------------- | ---------------------------------------------------------- | +| `api_key` | string | `""` | MiniMax API Key,支持 `${ENV_VAR}`(`${MINIMAX_API_KEY}`) | +| `base_url` | string | `"https://api.minimaxi.com/anthropic"` | API 基础地址 | > 默认禁用(`enabled: false`)。默认模型映射:`minimax-m2.7`。 @@ -121,10 +122,10 @@ coding-proxy 支持三类供应商,共 9 种: 通过阿里云 DashScope Anthropic 兼容端点调用 Qwen 模型。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `api_key` | string | `""` | 阿里 API Key,支持 `${ENV_VAR}`(`${ALIBABA_API_KEY}`) | -| `base_url` | string | `"https://coding-intl.dashscope.aliyuncs.com/apps/anthropic"` | API 基础地址 | +| 字段 | 类型 | 默认值 | 说明 | +| ---------- | ------ | ------------------------------------------------------------- | ------------------------------------------------------- | +| `api_key` | string | `""` | 阿里 API Key,支持 `${ENV_VAR}`(`${ALIBABA_API_KEY}`) | +| `base_url` | string | `"https://coding-intl.dashscope.aliyuncs.com/apps/anthropic"` | API 基础地址 | > 默认禁用(`enabled: false`)。默认模型映射:`qwen3.6-plus`。 @@ -132,10 +133,10 @@ coding-proxy 支持三类供应商,共 9 种: 通过小米 Anthropic 兼容端点调用 MiMo 模型。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `api_key` | string | `""` | 小米 API Key,支持 `${ENV_VAR}`(`${XIAOMI_API_KEY}`) | -| `base_url` | string | `"https://token-plan-cn.xiaomimimo.com/anthropic"` | API 基础地址 | +| 字段 | 类型 | 默认值 | 说明 | +| ---------- | ------ | -------------------------------------------------- | ------------------------------------------------------ | +| `api_key` | string | `""` | 小米 API Key,支持 `${ENV_VAR}`(`${XIAOMI_API_KEY}`) | +| `base_url` | string | `"https://token-plan-cn.xiaomimimo.com/anthropic"` | API 基础地址 | > 默认禁用(`enabled: false`)。默认模型映射:`mimo-v2-pro`。 @@ -143,10 +144,10 @@ coding-proxy 支持三类供应商,共 9 种: 通过 Kimi Anthropic 兼容端点调用模型。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `api_key` | string | `""` | Kimi API Key,支持 `${ENV_VAR}`(`${KIMI_API_KEY}`) | -| `base_url` | string | `"https://api.kimi.com/coding/"` | API 基础地址 | +| 字段 | 类型 | 默认值 | 说明 | +| ---------- | ------ | -------------------------------- | ---------------------------------------------------- | +| `api_key` | string | `""` | Kimi API Key,支持 `${ENV_VAR}`(`${KIMI_API_KEY}`) | +| `base_url` | string | `"https://api.kimi.com/coding/"` | API 基础地址 | > 默认禁用(`enabled: false`)。默认模型映射:`kimi-k2.5`。 @@ -154,10 +155,10 @@ coding-proxy 支持三类供应商,共 9 种: 通过字节跳动 Volcengine Anthropic 兼容端点调用模型。 -| 字段 | 类型 | 默认值 | 说明 | -|------|------|--------|------| -| `api_key` | string | `""` | Volcengine API Key,支持 `${ENV_VAR}`(`${ARK_API_KEY}`) | -| `base_url` | string | `"https://ark.cn-beijing.volces.com/api/coding"` | API 基础地址 | +| 字段 | 类型 | 默认值 | 说明 | +| ---------- | ------ | ------------------------------------------------ | --------------------------------------------------------- | +| `api_key` | string | `""` | Volcengine API Key,支持 `${ENV_VAR}`(`${ARK_API_KEY}`) | +| `base_url` | string | `"https://ark.cn-beijing.volces.com/api/coding"` | API 基础地址 | > 默认禁用(`enabled: false`)。三档模型映射:`claude-opus-*` → `doubao-seed-2.0-code`,`claude-sonnet-*` → `doubao-seed-2.0-pro`,`claude-haiku-*` → `doubao-seed-2.0-lite`。 @@ -176,11 +177,11 @@ tiers: ["zhipu", "anthropic", "copilot", "antigravity"] **示例**: -| 场景 | 配置 | 效果 | -|------|------|------| -| 默认链路 | `["zhipu", "anthropic", "copilot", "antigravity"]` | 智谱首选,Anthropic 作后备 | -| Anthropic 首选 | `["anthropic", "zhipu"]` | 仅保留首尾两级 | -| 全部启用 | `["zhipu", "anthropic", "copilot", "minimax", "antigravity"]` | 五层降级 | +| 场景 | 配置 | 效果 | +| -------------- | ------------------------------------------------------------- | -------------------------- | +| 默认链路 | `["zhipu", "anthropic", "copilot", "antigravity"]` | 智谱首选,Anthropic 作后备 | +| Anthropic 首选 | `["anthropic", "zhipu"]` | 仅保留首尾两级 | +| 全部启用 | `["zhipu", "anthropic", "copilot", "minimax", "antigravity"]` | 五层降级 | > **终端层**:未配置 `circuit_breaker` 的 vendor 自动成为终端层(始终接受请求,不触发向下故障转移)。`config.default.yaml` 中所有已启用 vendor 均配置了 `circuit_breaker`,因此默认无终端层;若需设置终端层,移除对应 vendor 的 `circuit_breaker` 配置即可。 > @@ -190,12 +191,12 @@ tiers: ["zhipu", "anthropic", "copilot", "antigravity"] 将 Claude 模型名自动转换为各供应商对应的实际模型名。完整规则列表参见项目内置的 `config.default.yaml`(`src/coding/proxy/config/config.default.yaml`)。 -| 字段 | 类型 | 说明 | -|------|------|------| -| `pattern` | string | 匹配模式(精确匹配或正则) | -| `vendors` | list[str] | 规则作用的供应商范围 | -| `target` | string | 目标模型名称 | -| `is_regex` | bool | 是否为正则表达式(默认 `false`) | +| 字段 | 类型 | 说明 | +| ---------- | --------- | -------------------------------- | +| `pattern` | string | 匹配模式(精确匹配或正则) | +| `vendors` | list[str] | 规则作用的供应商范围 | +| `target` | string | 目标模型名称 | +| `is_regex` | bool | 是否为正则表达式(默认 `false`) | **匹配优先级**:同一供应商内精确匹配 > 正则匹配(按规则顺序) > 供应商默认值。 @@ -234,13 +235,13 @@ model_mapping: 按 `(vendor, model)` 配置四维定价,用于 [`coding-proxy usage`](./cli-reference.md#3-coding-proxy-usage) 的费用统计展示。完整定价表参见项目内置的 `config.default.yaml`(`src/coding/proxy/config/config.default.yaml`)。 -| 字段 | 类型 | 说明 | -|------|------|------| -| `vendor` | string | 供应商名称 | -| `model` | string | 实际模型名 | -| `input_cost_per_mtok` | price | 输入 Token 单价(支持 `$` USD / `¥` CNY) | -| `output_cost_per_mtok` | price | 输出 Token 单价 | -| `cache_write_cost_per_mtok` | price | 缓存创建 Token 单价 | -| `cache_read_cost_per_mtok` | price | 缓存读取 Token 单价 | +| 字段 | 类型 | 说明 | +| --------------------------- | ------ | ----------------------------------------- | +| `vendor` | string | 供应商名称 | +| `model` | string | 实际模型名 | +| `input_cost_per_mtok` | price | 输入 Token 单价(支持 `$` USD / `¥` CNY) | +| `output_cost_per_mtok` | price | 输出 Token 单价 | +| `cache_write_cost_per_mtok` | price | 缓存创建 Token 单价 | +| `cache_read_cost_per_mtok` | price | 缓存读取 Token 单价 | > **币种规则**:同一模型的所有价格必须使用相同币种。未配置定价的模型在 `usage` 统计中 Cost 列显示 `-`。 diff --git a/docs/user-guide.md b/docs/user-guide.md index 80cd646..9f62902 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -3,22 +3,22 @@
📑 目录(点击展开) -- [1. 简介](#1-简介) - - [1.1 什么是 coding-proxy](#11-什么是-coding-proxy) - - [1.2 工作原理](#12-工作原理) - - [1.3 请求生命周期](#13-请求生命周期) -- [2. 文档导航](#2-文档导航) -- [3. 快速上手入门](#3-快速上手入门) -- [4. 配置概览](#4-配置概览) - - [4.1 配置文件位置与加载优先级](#41-配置文件位置与加载优先级) - - [4.2 vendors — 供应商列表](#42-vendors--供应商列表) - - [4.3 tiers — 降级链路优先级](#43-tiers--降级链路优先级) - - [4.4 环境变量引用](#44-环境变量引用) - - [4.5 auth — OAuth 登录配置](#45-auth--oauth-登录配置) - - [4.6 server / database / logging](#46-server--database--logging) - - [4.7 旧 flat 格式兼容说明(已废弃)](#47-旧-flat-格式兼容说明已废弃) -- [5. 日常操作速查](#5-日常操作速查) -- [附录:术语对照表](#附录术语对照表) +- [coding-proxy 用户指引](#coding-proxy-用户指引) + - [1. 简介](#1-简介) + - [1.1 什么是 coding-proxy](#11-什么是-coding-proxy) + - [1.2 工作原理](#12-工作原理) + - [1.3 请求生命周期](#13-请求生命周期) + - [2. 文档导航](#2-文档导航) + - [3. 快速上手入门](#3-快速上手入门) + - [4. 配置概览](#4-配置概览) + - [4.1 配置文件位置与加载优先级](#41-配置文件位置与加载优先级) + - [4.2 vendors — 供应商列表](#42-vendors--供应商列表) + - [4.3 tiers — 降级链路优先级](#43-tiers--降级链路优先级) + - [4.4 环境变量引用](#44-环境变量引用) + - [4.5 auth — OAuth 登录配置](#45-auth--oauth-登录配置) + - [4.6 server / database / logging](#46-server--database--logging) + - [5. 日常操作速查](#5-日常操作速查) + - [附录:术语对照表](#附录术语对照表)
@@ -87,18 +87,18 @@ graph TD ## 2. 文档导航 -| 文档 | 说明 | -|------|------| -| **[快速开始](./guide/quickstart.md)** | 环境要求、安装、最小配置、启动服务、Claude Code 集成 | -| **[供应商配置](./guide/vendors.md)** | 全部 9 种供应商配置详情、模型映射、定价 | -| **[CLI 命令参考](./guide/cli-reference.md)** | start / status / usage / reset / auth 全部命令 | +| 文档 | 说明 | +| --------------------------------------------- | --------------------------------------------------------------- | +| **[快速开始](./guide/quickstart.md)** | 环境要求、安装、最小配置、启动服务、Claude Code 集成 | +| **[供应商配置](./guide/vendors.md)** | 全部 9 种供应商配置详情、模型映射、定价 | +| **[CLI 命令参考](./guide/cli-reference.md)** | start / status / usage / reset / auth 全部命令 | | **[HTTP API 端点](./guide/api-reference.md)** | /v1/messages、health、status、reset、copilot、reauth、dashboard | -| **[Dashboard 看板](./guide/dashboard.md)** | Web 可视化看板功能与操作 | -| **[监控·运维·排查](./guide/monitoring.md)** | 日志、用量统计、性能调优、常见场景、故障排查 | -| [配置字段参考](./arch/config-reference.md) | 所有配置参数的完整字段定义(Single Source of Truth) | -| [架构设计文档](./arch/design-patterns.md) | 设计模式、熔断器状态机、配额守卫等架构细节 | -| [供应商模块文档](./arch/vendors.md) | Vendor 类层次结构与实现细节 | -| [请求路由文档](./arch/routing.md) | 路由引擎工作原理 | +| **[Dashboard 看板](./guide/dashboard.md)** | Web 可视化看板功能与操作 | +| **[监控·运维·排查](./guide/monitoring.md)** | 日志、用量统计、性能调优、常见场景、故障排查 | +| [配置字段参考](./arch/config-reference.md) | 所有配置参数的完整字段定义(Single Source of Truth) | +| [架构设计文档](./arch/design-patterns.md) | 设计模式、熔断器状态机、配额守卫等架构细节 | +| [供应商模块文档](./arch/vendors.md) | Vendor 类层次结构与实现细节 | +| [请求路由文档](./arch/routing.md) | 路由引擎工作原理 | --- @@ -142,17 +142,17 @@ curl http://127.0.0.1:8046/health `vendors` 以列表形式定义所有供应商及其弹性设施。支持 9 种供应商类型: -| 类型 | 类别 | 默认状态 | -|------|------|---------| -| `anthropic` | 直连 Anthropic | 启用 | -| `copilot` | 协议转换(GitHub) | 启用(需 OAuth) | -| `antigravity` | 协议转换(Google) | 禁用 | -| `zhipu` | 原生 Anthropic 兼容 | 启用(Tier 0) | -| `minimax` | 原生 Anthropic 兼容 | 禁用 | -| `alibaba` | 原生 Anthropic 兼容 | 禁用 | -| `xiaomi` | 原生 Anthropic 兼容 | 禁用 | -| `kimi` | 原生 Anthropic 兼容 | 禁用 | -| `doubao` | 原生 Anthropic 兼容 | 禁用 | +| 类型 | 类别 | 默认状态 | +| ------------- | ------------------- | ---------------- | +| `anthropic` | 直连 Anthropic | 启用 | +| `copilot` | 协议转换(GitHub) | 启用(需 OAuth) | +| `antigravity` | 协议转换(Google) | 禁用 | +| `zhipu` | 原生 Anthropic 兼容 | 启用(Tier 0) | +| `minimax` | 原生 Anthropic 兼容 | 禁用 | +| `alibaba` | 原生 Anthropic 兼容 | 禁用 | +| `xiaomi` | 原生 Anthropic 兼容 | 禁用 | +| `kimi` | 原生 Anthropic 兼容 | 禁用 | +| `doubao` | 原生 Anthropic 兼容 | 禁用 | > 各供应商的专属字段、弹性配置和模型映射详见 [供应商配置](./guide/vendors.md)。所有字段的完整定义参见 [配置字段参考](./arch/config-reference.md)。 @@ -208,31 +208,23 @@ logging: > 完整字段定义参见 [配置字段参考](./arch/config-reference.md#3-服务器配置)。 -### 4.7 旧 flat 格式兼容说明(已废弃) - -以下字段为 legacy flat 格式(已废弃,保留仅用于向后兼容): - -`primary`, `copilot`, `antigravity`, `fallback`, `circuit_breaker`, `copilot_circuit_breaker`, `antigravity_circuit_breaker`, `quota_guard`, `copilot_quota_guard`, `antigravity_quota_guard` - -当用户配置中**同时不存在** `vendors` 和 `tiers` 字段,但包含上述旧格式字段时,系统启动时**自动迁移**至 vendors 格式并输出日志提示。建议尽快迁移至 vendors 新格式。 - --- ## 5. 日常操作速查 -| 操作 | 命令 | -|------|------| -| 启动代理 | `coding-proxy start` | -| 查看状态 | `coding-proxy status` | -| 查看用量 | `coding-proxy usage` | -| 查看本周 | `coding-proxy usage -w 1` | -| 查看本月 | `coding-proxy usage -m 1` | -| 重置熔断器 | `coding-proxy reset` | -| 提升供应商 | `coding-proxy reset -v anthropic` | -| GitHub 登录 | `coding-proxy auth login -p github` | -| 重认证 | `coding-proxy auth reauth github` | -| 查看凭证 | `coding-proxy auth status` | -| Dashboard | 浏览器访问 `http://127.0.0.1:8046/dashboard` | +| 操作 | 命令 | +| ----------- | -------------------------------------------- | +| 启动代理 | `coding-proxy start` | +| 查看状态 | `coding-proxy status` | +| 查看用量 | `coding-proxy usage` | +| 查看本周 | `coding-proxy usage -w 1` | +| 查看本月 | `coding-proxy usage -m 1` | +| 重置熔断器 | `coding-proxy reset` | +| 提升供应商 | `coding-proxy reset -v anthropic` | +| GitHub 登录 | `coding-proxy auth login -p github` | +| 重认证 | `coding-proxy auth reauth github` | +| 查看凭证 | `coding-proxy auth status` | +| Dashboard | 浏览器访问 `http://127.0.0.1:8046/dashboard` | > 完整命令选项参见 [CLI 命令参考](./guide/cli-reference.md)。 @@ -240,14 +232,14 @@ logging: ## 附录:术语对照表 -| 术语 | 说明 | -|------|------| -| **Vendor(供应商)** | API 后端提供方,即 `vendors` 列表中的一个条目 | -| **Tier(层级)** | 一个 Vendor + 其关联弹性设施的路由单元 | -| **Terminal Tier(终端层)** | 未配置 `circuit_breaker` 的 Vendor,始终接受请求,不触发向下故障转移 | -| **故障转移(Failover)** | 当前供应商不可用时自动切换到下一优先级供应商 | -| **熔断器(Circuit Breaker)** | 连续失败达到阈值后暂时切断对该供应商的请求 | -| **配额守卫(Quota Guard)** | 基于滑动窗口的 Token 用量预算管理,超限时跳过该供应商 | -| **Rate Limit** | 基于上游响应头的精确速率限制控制 | -| **模型映射(Model Mapping)** | 将 Claude 模型名自动转换为各供应商实际模型名 | -| **原生 Anthropic 兼容(Native Anthropic Compatible)** | 提供 Anthropic 兼容端点的供应商,仅需 `api_key` + `base_url` | +| 术语 | 说明 | +| ------------------------------------------------------ | -------------------------------------------------------------------- | +| **Vendor(供应商)** | API 后端提供方,即 `vendors` 列表中的一个条目 | +| **Tier(层级)** | 一个 Vendor + 其关联弹性设施的路由单元 | +| **Terminal Tier(终端层)** | 未配置 `circuit_breaker` 的 Vendor,始终接受请求,不触发向下故障转移 | +| **故障转移(Failover)** | 当前供应商不可用时自动切换到下一优先级供应商 | +| **熔断器(Circuit Breaker)** | 连续失败达到阈值后暂时切断对该供应商的请求 | +| **配额守卫(Quota Guard)** | 基于滑动窗口的 Token 用量预算管理,超限时跳过该供应商 | +| **Rate Limit** | 基于上游响应头的精确速率限制控制 | +| **模型映射(Model Mapping)** | 将 Claude 模型名自动转换为各供应商实际模型名 | +| **原生 Anthropic 兼容(Native Anthropic Compatible)** | 提供 Anthropic 兼容端点的供应商,仅需 `api_key` + `base_url` | From 592945c9e03f3856daefcdb6e00c552c03f5d1dc Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 09:26:51 +0800 Subject: [PATCH 28/32] =?UTF-8?q?refactor(vendor-channels):=20=E5=B0=86?= =?UTF-8?q?=E4=BE=9B=E5=BA=94=E5=95=86=E8=BD=AC=E6=8D=A2=E9=80=9A=E9=81=93?= =?UTF-8?q?=E4=BB=8E=E7=9B=AE=E6=A0=87=E4=B8=93=E5=B1=9E=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=B8=BA=E6=BA=90=E2=86=92=E7=9B=AE=E6=A0=87=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 注册表键从 target_vendor 改为 (source, target) 二元组,通道函数从 prepare_for_X 重命名为 prepare_X_to_Y,触发逻辑从 _needs_vendor_channel 替换为 _determine_source_vendor(基于请求内 failed_tier_name 和会话历史 推断源 vendor),未注册的转换对不触发任何通道; 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- CHANGELOG.md | 3 +- src/coding/proxy/convert/vendor_channels.py | 72 +++-- src/coding/proxy/routing/executor.py | 88 +++--- tests/test_router_executor.py | 334 +++++--------------- tests/test_vendor_channels.py | 203 ++++++------ 5 files changed, 262 insertions(+), 438 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18e9e40..12ef322 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ ## [Unreleased] - 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 异常; -- feat(vendor-channels): 新增 zhipu/copilot 供应商专属转换通道(`prepare_for_zhipu` / `prepare_for_copilot`),在跨供应商故障转移时自动剥离 GLM-5 不兼容的 thinking 块、cache_control 字段、thinking 参数,并强制 tool_use/tool_result 配对,消除 `likely format incompatibility (400 + tool_results)` 错误; +- refactor(vendor-channels): 将供应商转换通道从「目标 vendor 专属」重构为「源→目标绑定」模型——注册表键从 `target_vendor` 改为 `(source, target)` 二元组,通道函数从 `prepare_for_X` 重命名为 `prepare_X_to_Y`,触发逻辑从 `_needs_vendor_channel` 替换为 `_determine_source_vendor`(基于请求内 `failed_tier_name` 和会话历史推断源 vendor),未注册的转换对(如 anthropic→zhipu)不触发任何通道; +- feat(vendor-channels): 新增 zhipu→anthropic、zhipu→copilot、copilot→zhipu 三条源→目标绑定转换通道,在跨供应商故障转移时自动清理源 vendor 产物(thinking 块、cache_control 字段、thinking 参数、tool_use/tool_result 配对),消除 `likely format incompatibility (400 + tool_results)` 错误; ## [v0.2.3](https://github.com/ThreeFish-AI/coding-proxy/releases/tag/v0.2.3) — 2026-04-16 diff --git a/src/coding/proxy/convert/vendor_channels.py b/src/coding/proxy/convert/vendor_channels.py index b6aeade..e41f842 100644 --- a/src/coding/proxy/convert/vendor_channels.py +++ b/src/coding/proxy/convert/vendor_channels.py @@ -1,15 +1,15 @@ -"""供应商专属转换通道 — 跨供应商故障转移时的请求体预处理. +"""供应商跨供应商转换通道 — 源→目标绑定的请求体预处理. -每个通道函数接收标准化的 Anthropic 格式请求体,返回针对目标供应商 -调整后的请求体(深拷贝)。通道函数之间无依赖关系,可独立测试。 +每个通道函数表示一个具体的「源 vendor → 目标 vendor」绑定转换关系, +接收标准化的 Anthropic 格式请求体,返回清理跨供应商产物后的请求体(深拷贝)。 -通道注册表 ``VENDOR_CHANNELS`` 提供统一的 tier_name → channel_fn 映射, -executor 层通过 ``get_channel()`` 查表分发,无需感知具体供应商。 +通道注册表 ``VENDOR_TRANSITIONS`` 提供统一的 (source, target) → channel_fn 映射, +executor 层通过 ``get_transition_channel()`` 查表分发,无需感知具体供应商逻辑。 -通道矩阵: - anthropic : prepare_for_anthropic (tool pairing + 条件 thinking strip) - zhipu : prepare_for_zhipu (剥离 thinking + cache_control + tool pairing + 移除 thinking 参数) - copilot : prepare_for_copilot (剥离 thinking + cache_control + tool pairing) +转换矩阵(仅注册需要转换的源→目标对,未注册的不触发任何通道): + zhipu → anthropic : prepare_zhipu_to_anthropic (剥离 thinking + tool pairing) + zhipu → copilot : prepare_zhipu_to_copilot (剥离 thinking + cache_control + tool pairing) + copilot → zhipu : prepare_copilot_to_zhipu (剥离 thinking + cache_control + 移除 thinking 参数 + tool pairing) """ from __future__ import annotations @@ -23,16 +23,18 @@ _THINKING_BLOCK_TYPES = {"thinking", "redacted_thinking"} -# ── 通道注册表 ──────────────────────────────────────────────── -# tier_name → (body) → (prepared_body, adaptations) -VENDOR_CHANNELS: dict[ - str, Callable[[dict[str, Any]], tuple[dict[str, Any], list[str]]] +# ── 转换通道注册表 ───────────────────────────────────────────── +# (source_vendor, target_vendor) → (body) → (prepared_body, adaptations) +VENDOR_TRANSITIONS: dict[ + tuple[str, str], Callable[[dict[str, Any]], tuple[dict[str, Any], list[str]]] ] = {} -def get_channel(tier_name: str) -> Callable | None: - """查找供应商专属通道函数,不存在时返回 None.""" - return VENDOR_CHANNELS.get(tier_name) +def get_transition_channel( + source: str, target: str +) -> Callable[[dict[str, Any]], tuple[dict[str, Any], list[str]]] | None: + """查找源→目标绑定转换通道,不存在时返回 None.""" + return VENDOR_TRANSITIONS.get((source, target)) # ── 共享辅助函数 ────────────────────────────────────────────── @@ -112,11 +114,13 @@ def _strip_cache_control(body: dict[str, Any]) -> int: return removed -# ── zhipu 专属转换通道 ──────────────────────────────────────── +# ── copilot → zhipu 转换通道 ───────────────────────────────────── -def prepare_for_zhipu(body: dict[str, Any]) -> tuple[dict[str, Any], list[str]]: - """zhipu 专属转换通道: 清理 GLM-5 不兼容的 Anthropic 协议扩展. +def prepare_copilot_to_zhipu( + body: dict[str, Any], +) -> tuple[dict[str, Any], list[str]]: + """copilot → zhipu 转换: 清理 copilot 产物以适配 GLM-5. GLM-5 的 Anthropic 兼容端点对以下特性支持不完整: - thinking / redacted_thinking 块 (signature 由非 Anthropic 签发) @@ -156,14 +160,16 @@ def prepare_for_zhipu(body: dict[str, Any]) -> tuple[dict[str, Any], list[str]]: return prepared, adaptations -# ── copilot 专属转换通道 ────────────────────────────────────── +# ── zhipu → copilot 转换通道 ───────────────────────────────────── -def prepare_for_copilot(body: dict[str, Any]) -> tuple[dict[str, Any], list[str]]: - """copilot 专属转换通道: 清理 Anthropic 格式请求以确保 OpenAI 转换器稳定. +def prepare_zhipu_to_copilot( + body: dict[str, Any], +) -> tuple[dict[str, Any], list[str]]: + """zhipu → copilot 转换: 清理 zhipu 产物以确保 OpenAI 转换器稳定. Copilot 内部的 convert_openai_request() 处理 Anthropic→OpenAI 格式转换, - 但某些跨供应商产物可能导致转换器输出异常: + 但 zhipu 的跨供应商产物可能导致转换器输出异常: - 非 Anthropic 签发的 thinking signature - cache_control 字段(OpenAI 协议不支持) - 错位的 tool_result blocks @@ -196,15 +202,17 @@ def prepare_for_copilot(body: dict[str, Any]) -> tuple[dict[str, Any], list[str] return prepared, adaptations -# ── anthropic 专属转换通道 ───────────────────────────────────── +# ── zhipu → anthropic 转换通道 ──────────────────────────────────── -def prepare_for_anthropic(body: dict[str, Any]) -> tuple[dict[str, Any], list[str]]: - """anthropic 专属转换通道: tool pairing + 条件 thinking strip. +def prepare_zhipu_to_anthropic( + body: dict[str, Any], +) -> tuple[dict[str, Any], list[str]]: + """zhipu → anthropic 转换: 清理 zhipu 产物以适配 Anthropic API. Anthropic API 要求: - 每个 tool_use 必须在紧随的 user 消息中有对应 tool_result - - thinking blocks 的 signature 必须是 Anthropic 签发(跨供应商后无效) + - thinking blocks 的 signature 必须是 Anthropic 签发(zhipu 签发的无效) 此通道执行两项变换: 1. enforce_anthropic_tool_pairing: 单遍正向扫描修复配对 @@ -228,7 +236,7 @@ def prepare_for_anthropic(body: dict[str, Any]) -> tuple[dict[str, Any], list[st if pairing_fixes: adaptations.extend(pairing_fixes) - # Step 2: 剥离 thinking blocks(跨供应商 signature 无效) + # Step 2: 剥离 thinking blocks(zhipu signature 无效) stripped = strip_thinking_blocks(prepared) if stripped: adaptations.append(f"stripped_{stripped}_thinking_blocks") @@ -236,8 +244,8 @@ def prepare_for_anthropic(body: dict[str, Any]) -> tuple[dict[str, Any], list[st return prepared, adaptations -# ── 注册所有通道 ────────────────────────────────────────────── +# ── 注册所有转换通道 ────────────────────────────────────────────── -VENDOR_CHANNELS["anthropic"] = prepare_for_anthropic -VENDOR_CHANNELS["zhipu"] = prepare_for_zhipu -VENDOR_CHANNELS["copilot"] = prepare_for_copilot +VENDOR_TRANSITIONS[("zhipu", "anthropic")] = prepare_zhipu_to_anthropic +VENDOR_TRANSITIONS[("zhipu", "copilot")] = prepare_zhipu_to_copilot +VENDOR_TRANSITIONS[("copilot", "zhipu")] = prepare_copilot_to_zhipu diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index 55f72b8..7bd52ac 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -226,74 +226,58 @@ def _prepare_body_for_tier( self, body: dict[str, Any], tier: VendorTier, - normalization: Any = None, - session_record: Any = None, + source_vendor: str | None = None, ) -> dict[str, Any]: - """为指定 tier 准备请求体,应用供应商专属转换通道 (Phase 2). + """为指定 tier 准备请求体,应用源→目标绑定转换通道. - 通过 vendor_channels 注册表统一分发,executor 不感知具体供应商逻辑。 - 未注册通道的 tier 原样返回请求体。 + 通过 VENDOR_TRANSITIONS 注册表查表分发,executor 不感知具体供应商逻辑。 + 未注册转换的源→目标对或 source_vendor 为 None 时原样返回请求体。 """ - from ..convert.vendor_channels import get_channel + from ..convert.vendor_channels import get_transition_channel - channel_fn = get_channel(tier.name) - if channel_fn is None: + if source_vendor is None: return body - if not self._needs_vendor_channel(tier.name, normalization, session_record): + channel_fn = get_transition_channel(source_vendor, tier.name) + if channel_fn is None: return body prepared, adaptations = channel_fn(body) if adaptations: logger.debug( - "Applied vendor channel for tier %s: %s", + "Applied transition channel %s → %s: %s", + source_vendor, tier.name, ", ".join(adaptations), ) return prepared @staticmethod - def _needs_vendor_channel( - tier_name: str, - normalization: Any, + def _determine_source_vendor( + target_name: str, + failed_tier_name: str | None, session_record: Any, - ) -> bool: - """判断是否需要为目标供应商触发专属转换通道. - - anthropic 通道(宽松触发): - Anthropic API 有严格的格式要求(tool pairing / thinking signature), - 即使纯会话中也需修复。触发信号: - 1. 跨供应商信号或 Anthropic 修复需求(Phase 1 信号) - 2. 无会话追踪 → 安全回退 - 3. 会话历史中存在非 Anthropic 供应商 - - zhipu/copilot 通道(严格触发): - Phase 1 信号 (has_cross_vendor_signals, has_anthropic_fixes) 不可靠—— - 纯 zhipu 会话中 zhipu 自身的产物(srvtoolu_* ID)也会触发。 - 唯一可靠指标是会话历史中存在非当前供应商。 + ) -> str | None: + """确定跨供应商转换的源 vendor. + + Priority 1: failed_tier_name(请求内故障转移,最可靠)。 + Priority 2: session_record.provider_state 中有已注册转换的 vendor(跨请求)。 """ - if tier_name == "anthropic": - # anthropic: 宽松触发 - if normalization is not None and normalization.has_cross_vendor_signals: - return True - if normalization is not None and normalization.has_anthropic_fixes: - return True - if session_record is None: - return True - if session_record.provider_state: - non_current = { - v for v in session_record.provider_state if v != "anthropic" - } - if non_current: - return True - return False + # 请求内:刚失败的 tier 就是源 + if failed_tier_name and failed_tier_name != target_name: + return failed_tier_name - # zhipu/copilot: 仅会话历史确认的跨供应商转换 + # 跨请求:从会话历史找有注册转换的源 if session_record is not None and session_record.provider_state: - non_current = {v for v in session_record.provider_state if v != tier_name} - if non_current: - return True - return False + from ..convert.vendor_channels import get_transition_channel + + for source in session_record.provider_state: + if source != target_name and get_transition_channel( + source, target_name + ): + return source + + return None async def execute_stream( self, @@ -331,9 +315,10 @@ async def execute_stream( usage: dict[str, Any] = {} try: - body_for_tier = self._prepare_body_for_tier( - body, tier, normalization, session_record=session_record + source_vendor = _RouteExecutor._determine_source_vendor( + tier.name, failed_tier_name, session_record ) + body_for_tier = self._prepare_body_for_tier(body, tier, source_vendor) async for chunk in tier.vendor.send_message_stream( body_for_tier, headers ): @@ -497,9 +482,10 @@ async def execute_message( continue try: - body_for_tier = self._prepare_body_for_tier( - body, tier, normalization, session_record=session_record + source_vendor = _RouteExecutor._determine_source_vendor( + tier.name, failed_tier_name, session_record ) + body_for_tier = self._prepare_body_for_tier(body, tier, source_vendor) resp = await tier.vendor.send_message(body_for_tier, headers) if resp.status_code < 400: diff --git a/tests/test_router_executor.py b/tests/test_router_executor.py index 67420be..c333707 100644 --- a/tests/test_router_executor.py +++ b/tests/test_router_executor.py @@ -1552,209 +1552,106 @@ async def test_non_last_tier_500_still_failovers(self): assert good.send_message.called -# ── _needs_vendor_channel 条件判断测试 ────────────────────────── +# ── _determine_source_vendor 源 vendor 推断测试 ────────────────────── -class TestNeedsVendorChannel: - """验证 _RouteExecutor._needs_vendor_channel 静态方法. +class TestDetermineSourceVendor: + """验证 _RouteExecutor._determine_source_vendor 静态方法. - anthropic 采用宽松触发(Phase 1 信号 + 无会话回退 + 会话历史); - zhipu/copilot 采用严格触发(仅会话历史确认的跨供应商转换)。 + Priority 1: failed_tier_name(请求内故障转移) + Priority 2: session_record.provider_state 中有已注册转换的 vendor(跨请求) """ - # ── anthropic 宽松触发 ── - - def test_anthropic_true_when_cross_vendor_signals(self): - """Phase 1 跨供应商信号 → anthropic 通道触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = True - normalization.has_anthropic_fixes = False - session_record = MagicMock() - session_record.provider_state = {"anthropic": {}} - - assert ( - _RouteExecutor._needs_vendor_channel( - "anthropic", normalization, session_record - ) - is True - ) - - def test_anthropic_true_when_anthropic_fixes(self): - """Phase 1 Anthropic 修复需求 → anthropic 通道触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = True + def test_returns_failed_tier_as_source(self): + """请求内故障转移:刚失败的 tier 就是源 vendor.""" session_record = MagicMock() - session_record.provider_state = {"anthropic": {}} - - assert ( - _RouteExecutor._needs_vendor_channel( - "anthropic", normalization, session_record - ) - is True - ) - - def test_anthropic_true_when_no_session_record(self): - """无会话记录 → anthropic 通道安全回退触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False + session_record.provider_state = {"zhipu": {}} assert ( - _RouteExecutor._needs_vendor_channel("anthropic", normalization, None) - is True + _RouteExecutor._determine_source_vendor("copilot", "zhipu", session_record) + == "zhipu" ) - def test_anthropic_true_when_no_normalization_and_no_session(self): - """normalization 和 session_record 均为 None → anthropic 触发.""" - assert _RouteExecutor._needs_vendor_channel("anthropic", None, None) is True - - def test_anthropic_true_when_session_has_non_anthropic_vendor(self): - """会话历史中有非 Anthropic 供应商 → anthropic 通道触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False - session_record = MagicMock() - session_record.provider_state = {"anthropic": {}, "zhipu": {}} - + def test_returns_failed_tier_even_with_empty_session(self): + """请求内故障转移优先于 session_record 为空.""" assert ( - _RouteExecutor._needs_vendor_channel( - "anthropic", normalization, session_record - ) - is True + _RouteExecutor._determine_source_vendor("copilot", "zhipu", None) == "zhipu" ) - def test_anthropic_false_when_anthropic_only_session(self): - """纯 Anthropic 会话且无 Phase 1 信号 → anthropic 通道不触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False + def test_returns_session_vendor_with_registered_transition(self): + """跨请求:会话历史中有已注册转换的 vendor 作为源.""" session_record = MagicMock() - session_record.provider_state = {"anthropic": {"compat_mode": "native"}} + session_record.provider_state = {"zhipu": {}, "copilot": {}} + # zhipu → copilot 有注册转换 assert ( - _RouteExecutor._needs_vendor_channel( - "anthropic", normalization, session_record - ) - is False + _RouteExecutor._determine_source_vendor("copilot", None, session_record) + == "zhipu" ) - def test_anthropic_false_when_empty_provider_state(self): - """空 provider_state(首次请求)且无 Phase 1 信号 → anthropic 不触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False + def test_returns_session_vendor_for_anthropic_target(self): + """跨请求:会话历史中有 zhipu → anthropic 已注册转换.""" session_record = MagicMock() - session_record.provider_state = {} + session_record.provider_state = {"zhipu": {}} assert ( - _RouteExecutor._needs_vendor_channel( - "anthropic", normalization, session_record - ) - is False + _RouteExecutor._determine_source_vendor("anthropic", None, session_record) + == "zhipu" ) - def test_anthropic_true_when_normalization_none_but_session_has_other(self): - """normalization 为 None 但会话有非 Anthropic 供应商 → 触发.""" + def test_returns_none_for_no_source(self): + """纯同 vendor 会话且无请求内故障 → 无源 vendor.""" session_record = MagicMock() - session_record.provider_state = {"copilot": {}} - - assert ( - _RouteExecutor._needs_vendor_channel("anthropic", None, session_record) - is True - ) - - # ── zhipu/copilot 严格触发 ── - - def test_zhipu_false_when_no_session_record(self): - """无会话记录 → zhipu 通道不触发(严格模式).""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = True - normalization.has_anthropic_fixes = True + session_record.provider_state = {"anthropic": {}} assert ( - _RouteExecutor._needs_vendor_channel("zhipu", normalization, None) is False + _RouteExecutor._determine_source_vendor("anthropic", None, session_record) + is None ) - def test_zhipu_false_when_cross_vendor_signals_but_pure_session(self): - """Phase 1 有跨供应商信号,但纯 zhipu 会话 → zhipu 通道不触发. + def test_returns_none_when_no_registered_transition(self): + """会话历史中有 vendor 但无对应已注册转换 → 无源 vendor. - 核心场景:zhipu 自身产物(srvtoolu_* ID)触发 has_cross_vendor_signals, - 但实际是纯 zhipu 会话,不应错误触发通道。 + 例如 anthropic → zhipu 未注册,不会触发转换。 """ - normalization = MagicMock() - normalization.has_cross_vendor_signals = True - normalization.has_anthropic_fixes = True session_record = MagicMock() - session_record.provider_state = {"zhipu": {}} + session_record.provider_state = {"anthropic": {}} assert ( - _RouteExecutor._needs_vendor_channel("zhipu", normalization, session_record) - is False + _RouteExecutor._determine_source_vendor("zhipu", None, session_record) + is None ) - def test_zhipu_false_when_empty_provider_state(self): - """空 provider_state 且无 Phase 1 帮助 → zhipu 通道不触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False - session_record = MagicMock() - session_record.provider_state = {} + def test_returns_none_when_session_is_none(self): + """无会话存储且无请求内故障 → 无源 vendor.""" + assert _RouteExecutor._determine_source_vendor("copilot", None, None) is None - assert ( - _RouteExecutor._needs_vendor_channel("zhipu", normalization, session_record) - is False - ) - - def test_zhipu_true_when_session_has_other_vendor(self): - """会话历史中有 copilot → zhipu 通道触发(跨供应商转换).""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False + def test_returns_none_when_empty_provider_state(self): + """空 provider_state 且无请求内故障 → 无源 vendor.""" session_record = MagicMock() - session_record.provider_state = {"copilot": {}, "zhipu": {}} + session_record.provider_state = {} assert ( - _RouteExecutor._needs_vendor_channel("zhipu", normalization, session_record) - is True + _RouteExecutor._determine_source_vendor("copilot", None, session_record) + is None ) - def test_copilot_true_when_session_has_other_vendor(self): - """会话历史中有 zhipu → copilot 通道触发(跨供应商转换).""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False + def test_returns_none_when_failed_tier_equals_target(self): + """失败的 tier 就是目标 tier → 不算跨供应商.""" session_record = MagicMock() - session_record.provider_state = {"zhipu": {}, "copilot": {}} - - assert ( - _RouteExecutor._needs_vendor_channel( - "copilot", normalization, session_record - ) - is True - ) - - def test_copilot_false_when_pure_copilot_session(self): - """纯 copilot 会话即使有 Phase 1 信号也不触发.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = True - normalization.has_anthropic_fixes = True - session_record = MagicMock() - session_record.provider_state = {"copilot": {}} + session_record.provider_state = {} assert ( - _RouteExecutor._needs_vendor_channel( - "copilot", normalization, session_record - ) - is False + _RouteExecutor._determine_source_vendor("zhipu", "zhipu", session_record) + is None ) -# ── _prepare_body_for_tier 条件化 thinking 剥离测试 ──────────────── +# ── _prepare_body_for_tier 转换通道应用测试 ──────────────────────── -class TestPrepareBodyForTierThinkingStrip: - """验证 _prepare_body_for_tier 的条件化 thinking block 剥离行为.""" +class TestPrepareBodyForTierTransition: + """验证 _prepare_body_for_tier 的源→目标转换通道应用行为.""" @staticmethod def _body_with_thinking(): @@ -1775,141 +1672,80 @@ def _body_with_thinking(): ], } - def test_strips_thinking_when_cross_vendor_signals(self): - """normalization 有跨供应商信号时剥离 thinking blocks.""" - normalization = MagicMock() - normalization.has_anthropic_fixes = False - normalization.has_cross_vendor_signals = True - + def test_applies_zhipu_to_anthropic_transition(self): + """source_vendor=zhipu, target=anthropic → 剥离 thinking + tool pairing.""" tier = MagicMock() tier.name = "anthropic" exec_inst = _executor([]) body = self._body_with_thinking() - result = exec_inst._prepare_body_for_tier( - body, tier, normalization, session_record=None - ) + result = exec_inst._prepare_body_for_tier(body, tier, source_vendor="zhipu") - # thinking block 被剥离 + assert result is not body assert len(result["messages"][0]["content"]) == 1 assert result["messages"][0]["content"][0]["type"] == "text" # 原始 body 未被修改 assert len(body["messages"][0]["content"]) == 2 - def test_strips_thinking_when_session_has_non_anthropic(self): - """会话中有非 Anthropic 供应商时剥离 thinking blocks.""" - normalization = MagicMock() - normalization.has_anthropic_fixes = False - normalization.has_cross_vendor_signals = False - + def test_applies_zhipu_to_copilot_transition(self): + """source_vendor=zhipu, target=copilot → 剥离 thinking + cache_control.""" tier = MagicMock() - tier.name = "anthropic" - - session_record = MagicMock() - session_record.provider_state = {"zhipu": {"compat_mode": "native"}} + tier.name = "copilot" exec_inst = _executor([]) body = self._body_with_thinking() - result = exec_inst._prepare_body_for_tier( - body, tier, normalization, session_record=session_record - ) + result = exec_inst._prepare_body_for_tier(body, tier, source_vendor="zhipu") - # thinking block 被剥离 + assert result is not body assert len(result["messages"][0]["content"]) == 1 assert result["messages"][0]["content"][0]["type"] == "text" - def test_preserves_thinking_when_anthropic_only_session(self): - """纯 Anthropic 会话保留 thinking blocks.""" - normalization = MagicMock() - normalization.has_anthropic_fixes = False - normalization.has_cross_vendor_signals = False - - tier = MagicMock() - tier.name = "anthropic" - - session_record = MagicMock() - session_record.provider_state = {"anthropic": {"compat_mode": "native"}} - - exec_inst = _executor([]) - body = self._body_with_thinking() - result = exec_inst._prepare_body_for_tier( - body, tier, normalization, session_record=session_record - ) - - # 原始 body 直接返回(无 deep copy) - assert result is body - assert len(result["messages"][0]["content"]) == 2 - assert result["messages"][0]["content"][0]["type"] == "thinking" - - def test_strips_thinking_when_no_session_record(self): - """无会话记录时安全回退剥离.""" - normalization = MagicMock() - normalization.has_anthropic_fixes = False - normalization.has_cross_vendor_signals = False - + def test_applies_copilot_to_zhipu_transition(self): + """source_vendor=copilot, target=zhipu → 剥离 thinking + cache_control + 移除 thinking 参数.""" + body = { + "messages": self._body_with_thinking()["messages"], + "thinking": {"type": "enabled", "budget_tokens": 10000}, + } tier = MagicMock() - tier.name = "anthropic" + tier.name = "zhipu" exec_inst = _executor([]) - body = self._body_with_thinking() - result = exec_inst._prepare_body_for_tier( - body, tier, normalization, session_record=None - ) + result = exec_inst._prepare_body_for_tier(body, tier, source_vendor="copilot") - # thinking block 被剥离(安全回退) + assert result is not body assert len(result["messages"][0]["content"]) == 1 - assert result["messages"][0]["content"][0]["type"] == "text" + assert "thinking" not in result - def test_skips_for_non_anthropic_tier(self): - """无专属通道的非 Anthropic tier 不执行任何处理.""" + def test_returns_body_when_no_source_vendor(self): + """source_vendor=None → 原样返回请求体.""" tier = MagicMock() - tier.name = "antigravity" # antigravity 无 vendor channel,原样返回 + tier.name = "anthropic" exec_inst = _executor([]) body = self._body_with_thinking() - result = exec_inst._prepare_body_for_tier(body, tier) + result = exec_inst._prepare_body_for_tier(body, tier, source_vendor=None) - assert result is body # 原始 body 直接返回 - - def test_zhipu_tier_applies_channel_when_cross_vendor(self): - """zhipu tier 在跨供应商场景(会话历史有 copilot)下应用专属转换通道.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False + assert result is body + assert len(result["messages"][0]["content"]) == 2 + def test_returns_body_for_unregistered_transition(self): + """未注册的转换对(如 anthropic → zhipu)→ 原样返回.""" tier = MagicMock() tier.name = "zhipu" - session_record = MagicMock() - session_record.provider_state = {"copilot": {}, "zhipu": {}} - exec_inst = _executor([]) body = self._body_with_thinking() - result = exec_inst._prepare_body_for_tier( - body, tier, normalization, session_record=session_record - ) - - # zhipu 通道剥离 thinking blocks + 移除 thinking 参数 - assert result is not body - assert len(result["messages"][0]["content"]) == 1 - assert result["messages"][0]["content"][0]["type"] == "text" + result = exec_inst._prepare_body_for_tier(body, tier, source_vendor="anthropic") - def test_zhipu_tier_skips_channel_in_pure_session(self): - """zhipu tier 在纯 zhipu 会话中不触发专属通道.""" - normalization = MagicMock() - normalization.has_cross_vendor_signals = False - normalization.has_anthropic_fixes = False + assert result is body + def test_returns_body_for_unknown_tier(self): + """未知 tier(无注册转换)→ 原样返回.""" tier = MagicMock() - tier.name = "zhipu" - - session_record = MagicMock() - session_record.provider_state = {"zhipu"} + tier.name = "antigravity" exec_inst = _executor([]) body = self._body_with_thinking() - result = exec_inst._prepare_body_for_tier( - body, tier, normalization, session_record=session_record - ) + result = exec_inst._prepare_body_for_tier(body, tier, source_vendor="zhipu") - assert result is body # 纯 zhipu 会话,无需通道处理 + assert result is body diff --git a/tests/test_vendor_channels.py b/tests/test_vendor_channels.py index 248cbc0..ceb9f3b 100644 --- a/tests/test_vendor_channels.py +++ b/tests/test_vendor_channels.py @@ -1,11 +1,11 @@ -"""供应商专属转换通道单元测试. +"""供应商跨供应商转换通道单元测试. -覆盖 :mod:`coding.proxy.convert.vendor_channels` 的通道函数和辅助函数: -- anthropic 通道 (prepare_for_anthropic) -- zhipu 通道 (prepare_for_zhipu) -- copilot 通道 (prepare_for_copilot) +覆盖 :mod:`coding.proxy.convert.vendor_channels` 的转换通道函数和辅助函数: +- zhipu → anthropic 转换 (prepare_zhipu_to_anthropic) +- zhipu → copilot 转换 (prepare_zhipu_to_copilot) +- copilot → zhipu 转换 (prepare_copilot_to_zhipu) - 共享辅助函数 (_strip_thinking_blocks_inplace, _strip_cache_control) -- 通道注册表 (VENDOR_CHANNELS, get_channel) +- 转换注册表 (VENDOR_TRANSITIONS, get_transition_channel) """ from __future__ import annotations @@ -13,13 +13,13 @@ import copy from coding.proxy.convert.vendor_channels import ( - VENDOR_CHANNELS, + VENDOR_TRANSITIONS, _strip_cache_control, _strip_thinking_blocks_inplace, - get_channel, - prepare_for_anthropic, - prepare_for_copilot, - prepare_for_zhipu, + get_transition_channel, + prepare_copilot_to_zhipu, + prepare_zhipu_to_anthropic, + prepare_zhipu_to_copilot, ) # ── 辅助函数测试 ────────────────────────────────────────────── @@ -208,11 +208,11 @@ def test_no_change_when_no_cache_control(self): assert removed == 0 -# ── zhipu 通道测试 ──────────────────────────────────────────── +# ── copilot → zhipu 转换通道测试 ──────────────────────────────── -class TestZhipuChannel: - """prepare_for_zhipu 通道单元测试.""" +class TestCopilotToZhipuChannel: + """prepare_copilot_to_zhipu 转换通道单元测试.""" def test_strips_thinking_blocks(self): body = { @@ -226,7 +226,7 @@ def test_strips_thinking_blocks(self): }, ], } - prepared, adaptations = prepare_for_zhipu(body) + prepared, adaptations = prepare_copilot_to_zhipu(body) assert any("thinking_blocks" in a for a in adaptations) assert prepared["messages"][0]["content"] == [ {"type": "text", "text": "response"}, @@ -241,7 +241,7 @@ def test_removes_cache_control(self): ], "messages": [], } - prepared, adaptations = prepare_for_zhipu(body) + prepared, adaptations = prepare_copilot_to_zhipu(body) assert any("cache_control" in a for a in adaptations) assert "cache_control" not in prepared["system"][0] @@ -251,7 +251,7 @@ def test_removes_thinking_params(self): "thinking": {"type": "enabled", "budget_tokens": 10000}, "extended_thinking": {"type": "enabled"}, } - prepared, adaptations = prepare_for_zhipu(body) + prepared, adaptations = prepare_copilot_to_zhipu(body) assert "thinking" not in prepared assert "extended_thinking" not in prepared assert "removed_thinking_param" in adaptations @@ -277,8 +277,7 @@ def test_enforces_tool_pairing(self): }, ], } - prepared, adaptations = prepare_for_zhipu(body) - # tool_use should have a corresponding tool_result + prepared, adaptations = prepare_copilot_to_zhipu(body) user_content = prepared["messages"][1]["content"] tool_results = [ b @@ -313,17 +312,13 @@ def test_combined_transformations(self): ], "thinking": {"type": "enabled", "budget_tokens": 10000}, } - prepared, adaptations = prepare_for_zhipu(body) - # thinking blocks stripped + prepared, adaptations = prepare_copilot_to_zhipu(body) assert all( b.get("type") not in ("thinking", "redacted_thinking") for b in prepared["messages"][0]["content"] ) - # cache_control removed assert "cache_control" not in prepared["system"][0] - # thinking param removed assert "thinking" not in prepared - # tool pairing enforced user_content = prepared["messages"][1]["content"] tool_results = [ b @@ -346,7 +341,7 @@ def test_preserves_original_body(self): "thinking": {"type": "enabled"}, } original = copy.deepcopy(body) - prepare_for_zhipu(body) + prepare_copilot_to_zhipu(body) assert body == original def test_noop_when_clean(self): @@ -356,7 +351,7 @@ def test_noop_when_clean(self): {"role": "assistant", "content": [{"type": "text", "text": "hi"}]}, ], } - prepared, adaptations = prepare_for_zhipu(body) + prepared, adaptations = prepare_copilot_to_zhipu(body) assert adaptations == [] assert prepared == body @@ -382,17 +377,17 @@ def test_idempotency(self): ], "thinking": {"type": "enabled"}, } - prepared1, adaptations1 = prepare_for_zhipu(body) - prepared2, adaptations2 = prepare_for_zhipu(prepared1) + prepared1, adaptations1 = prepare_copilot_to_zhipu(body) + prepared2, adaptations2 = prepare_copilot_to_zhipu(prepared1) assert prepared2 == prepared1 assert adaptations2 == [] -# ── anthropic 通道测试 ──────────────────────────────────────── +# ── zhipu → anthropic 转换通道测试 ──────────────────────────────── -class TestAnthropicChannel: - """prepare_for_anthropic 通道单元测试.""" +class TestZhipuToAnthropicChannel: + """prepare_zhipu_to_anthropic 转换通道单元测试.""" def test_enforces_tool_pairing(self): body = { @@ -414,7 +409,7 @@ def test_enforces_tool_pairing(self): }, ], } - prepared, adaptations = prepare_for_anthropic(body) + prepared, adaptations = prepare_zhipu_to_anthropic(body) user_content = prepared["messages"][1]["content"] tool_results = [ b @@ -436,7 +431,7 @@ def test_strips_thinking_blocks(self): }, ], } - prepared, adaptations = prepare_for_anthropic(body) + prepared, adaptations = prepare_zhipu_to_anthropic(body) assert any("thinking_blocks" in a for a in adaptations) assert prepared["messages"][0]["content"] == [ {"type": "text", "text": "response"} @@ -463,13 +458,11 @@ def test_combined_tool_pairing_and_thinking_strip(self): }, ], } - prepared, adaptations = prepare_for_anthropic(body) - # thinking stripped + prepared, adaptations = prepare_zhipu_to_anthropic(body) assert all( b.get("type") not in ("thinking", "redacted_thinking") for b in prepared["messages"][0]["content"] ) - # tool pairing enforced user_content = prepared["messages"][1]["content"] tool_results = [ b @@ -491,7 +484,7 @@ def test_preserves_original_body(self): ], } original = copy.deepcopy(body) - prepare_for_anthropic(body) + prepare_zhipu_to_anthropic(body) assert body == original def test_noop_when_clean(self): @@ -501,7 +494,7 @@ def test_noop_when_clean(self): {"role": "assistant", "content": [{"type": "text", "text": "hi"}]}, ], } - prepared, adaptations = prepare_for_anthropic(body) + prepared, adaptations = prepare_zhipu_to_anthropic(body) assert adaptations == [] assert prepared == body @@ -526,55 +519,26 @@ def test_idempotency(self): }, ], } - prepared1, _ = prepare_for_anthropic(body) - prepared2, adaptations2 = prepare_for_anthropic(prepared1) + prepared1, _ = prepare_zhipu_to_anthropic(body) + prepared2, adaptations2 = prepare_zhipu_to_anthropic(prepared1) assert prepared2 == prepared1 assert adaptations2 == [] def test_preserves_thinking_param(self): - """anthropic 通道不移除顶层 thinking 参数(Anthropic API 支持).""" + """zhipu → anthropic 通道不移除顶层 thinking 参数(Anthropic API 支持).""" body = { "messages": [], "thinking": {"type": "enabled", "budget_tokens": 5000}, } - prepared, _ = prepare_for_anthropic(body) + prepared, _ = prepare_zhipu_to_anthropic(body) assert "thinking" in prepared -# ── 注册表测试 ──────────────────────────────────────────────── +# ── zhipu → copilot 转换通道测试 ────────────────────────────── -class TestChannelRegistry: - """通道注册表 VENDOR_CHANNELS / get_channel 单元测试.""" - - def test_all_channels_registered(self): - assert "anthropic" in VENDOR_CHANNELS - assert "zhipu" in VENDOR_CHANNELS - assert "copilot" in VENDOR_CHANNELS - - def test_get_channel_returns_function(self): - assert get_channel("anthropic") is prepare_for_anthropic - assert get_channel("zhipu") is prepare_for_zhipu - assert get_channel("copilot") is prepare_for_copilot - - def test_get_channel_returns_none_for_unknown(self): - assert get_channel("unknown") is None - assert get_channel("antigravity") is None - - def test_channel_functions_share_signature(self): - body = {"messages": []} - for name, fn in VENDOR_CHANNELS.items(): - result = fn(body) - assert isinstance(result, tuple) and len(result) == 2 - assert isinstance(result[0], dict) - assert isinstance(result[1], list) - - -# ── copilot 通道测试 ────────────────────────────────────────── - - -class TestCopilotChannel: - """prepare_for_copilot 通道单元测试.""" +class TestZhipuToCopilotChannel: + """prepare_zhipu_to_copilot 转换通道单元测试.""" def test_strips_thinking_blocks(self): body = { @@ -588,7 +552,7 @@ def test_strips_thinking_blocks(self): }, ], } - prepared, adaptations = prepare_for_copilot(body) + prepared, adaptations = prepare_zhipu_to_copilot(body) assert any("thinking_blocks" in a for a in adaptations) assert prepared["messages"][0]["content"] == [ {"type": "text", "text": "response"}, @@ -609,17 +573,17 @@ def test_removes_cache_control(self): }, ], } - prepared, adaptations = prepare_for_copilot(body) + prepared, adaptations = prepare_zhipu_to_copilot(body) assert any("cache_control" in a for a in adaptations) assert "cache_control" not in prepared["messages"][0]["content"][0] def test_preserves_thinking_param(self): - """copilot 通道不移除顶层 thinking 参数(由 converter 自行映射).""" + """zhipu → copilot 通道不移除顶层 thinking 参数(由 converter 自行映射).""" body = { "messages": [], "thinking": {"type": "enabled", "budget_tokens": 10000}, } - prepared, adaptations = prepare_for_copilot(body) + prepared, adaptations = prepare_zhipu_to_copilot(body) assert "thinking" in prepared assert "removed_thinking_param" not in adaptations @@ -643,7 +607,7 @@ def test_enforces_tool_pairing(self): }, ], } - prepared, adaptations = prepare_for_copilot(body) + prepared, adaptations = prepare_zhipu_to_copilot(body) user_content = prepared["messages"][1]["content"] tool_results = [ b @@ -665,7 +629,7 @@ def test_preserves_original_body(self): ], } original = copy.deepcopy(body) - prepare_for_copilot(body) + prepare_zhipu_to_copilot(body) assert body == original def test_noop_when_clean(self): @@ -675,7 +639,7 @@ def test_noop_when_clean(self): {"role": "assistant", "content": [{"type": "text", "text": "hi"}]}, ], } - prepared, adaptations = prepare_for_copilot(body) + prepared, adaptations = prepare_zhipu_to_copilot(body) assert adaptations == [] assert prepared == body @@ -700,8 +664,8 @@ def test_idempotency(self): }, ], } - prepared1, _ = prepare_for_copilot(body) - prepared2, adaptations2 = prepare_for_copilot(prepared1) + prepared1, _ = prepare_zhipu_to_copilot(body) + prepared2, adaptations2 = prepare_zhipu_to_copilot(prepared1) assert prepared2 == prepared1 assert adaptations2 == [] @@ -717,34 +681,68 @@ def test_strips_redacted_thinking(self): }, ], } - prepared, adaptations = prepare_for_copilot(body) + prepared, adaptations = prepare_zhipu_to_copilot(body) assert any("thinking_blocks" in a for a in adaptations) assert prepared["messages"][0]["content"] == [ {"type": "text", "text": "response"}, ] -# ── zhipu vs copilot 通道差异测试 ──────────────────────────── +# ── 转换注册表测试 ──────────────────────────────────────────── + + +class TestTransitionRegistry: + """VENDOR_TRANSITIONS / get_transition_channel 单元测试.""" + def test_all_transitions_registered(self): + assert ("zhipu", "anthropic") in VENDOR_TRANSITIONS + assert ("zhipu", "copilot") in VENDOR_TRANSITIONS + assert ("copilot", "zhipu") in VENDOR_TRANSITIONS + assert len(VENDOR_TRANSITIONS) == 3 -class TestChannelDifferences: - """验证 zhipu 和 copilot 通道的关键行为差异.""" + def test_get_transition_channel_returns_function(self): + assert ( + get_transition_channel("zhipu", "anthropic") is prepare_zhipu_to_anthropic + ) + assert get_transition_channel("zhipu", "copilot") is prepare_zhipu_to_copilot + assert get_transition_channel("copilot", "zhipu") is prepare_copilot_to_zhipu + + def test_get_transition_channel_returns_none_for_unregistered(self): + assert get_transition_channel("anthropic", "zhipu") is None + assert get_transition_channel("copilot", "anthropic") is None + assert get_transition_channel("unknown", "target") is None + assert get_transition_channel("antigravity", "copilot") is None + + def test_transition_functions_share_signature(self): + body = {"messages": []} + for key, fn in VENDOR_TRANSITIONS.items(): + result = fn(body) + assert isinstance(result, tuple) and len(result) == 2 + assert isinstance(result[0], dict) + assert isinstance(result[1], list) - def test_zhipu_removes_thinking_param_copilot_preserves(self): + +# ── 转换通道差异测试 ────────────────────────────────────────── + + +class TestTransitionDifferences: + """验证不同转换通道的关键行为差异.""" + + def test_copilot_to_zhipu_removes_thinking_param_zhipu_to_copilot_preserves(self): body = { "messages": [], "thinking": {"type": "enabled", "budget_tokens": 5000}, } - zhipu_result, zhipu_adapt = prepare_for_zhipu(body) - copilot_result, copilot_adapt = prepare_for_copilot(body) + copilot_to_zhipu_result, copilot_to_zhipu_adapt = prepare_copilot_to_zhipu(body) + zhipu_to_copilot_result, zhipu_to_copilot_adapt = prepare_zhipu_to_copilot(body) - assert "thinking" not in zhipu_result - assert "removed_thinking_param" in zhipu_adapt + assert "thinking" not in copilot_to_zhipu_result + assert "removed_thinking_param" in copilot_to_zhipu_adapt - assert "thinking" in copilot_result - assert "removed_thinking_param" not in copilot_adapt + assert "thinking" in zhipu_to_copilot_result + assert "removed_thinking_param" not in zhipu_to_copilot_adapt - def test_both_strip_thinking_blocks(self): + def test_all_transitions_strip_thinking_blocks(self): body = { "messages": [ { @@ -756,13 +754,8 @@ def test_both_strip_thinking_blocks(self): }, ], } - zhipu_result, _ = prepare_for_zhipu(body) - copilot_result, _ = prepare_for_copilot(body) - - # 两者都剥离 thinking blocks - assert zhipu_result["messages"][0]["content"] == [ - {"type": "text", "text": "hi"} - ] - assert copilot_result["messages"][0]["content"] == [ - {"type": "text", "text": "hi"} - ] + for key, fn in VENDOR_TRANSITIONS.items(): + result, adaptations = fn(body) + assert result["messages"][0]["content"] == [ + {"type": "text", "text": "hi"} + ], f"Transition {key} failed to strip thinking blocks" From fbc6aa4ef2b67164eeeb5e523b9a34215fef7c12 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 10:07:38 +0800 Subject: [PATCH 29/32] =?UTF-8?q?docs(readme):=20=E6=A0=A1=E5=87=86?= =?UTF-8?q?=E6=9E=B6=E6=9E=84=E5=9B=BE=20Tier=20=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E3=80=81=E8=A1=A5=E5=85=A8=20CLI=20auth=20=E5=AD=90=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E4=B8=8E=E6=A0=BC=E5=BC=8F=E8=BD=AC=E6=8D=A2=E6=8F=8F?= =?UTF-8?q?=E8=BF=B0;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 架构图 Tier 排序与默认配置 tiers 对齐:Zhipu(T0) → Anthropic(T1) → Copilot(T2) → Antigravity(T3) - CLI 指南表补全 auth 子命令组(login/status/reauth/logout) - 格式转换描述补全 Anthropic ↔ OpenAI 双向支持 - 供应商列表显式补全 Google Antigravity 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- README.md | 23 ++++++++++++----------- docs/zh-CN/README.md | 23 ++++++++++++----------- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index fdf91ed..ef5e92b 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,10 @@ When you're deeply immersed in your coding "zone" with **Claude Code** (or any A -- **⛓️ 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. +- **⛓️ 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. - **🛡️ 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. - **👻 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. -- **🔄 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-*`). +- **🔄 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-*`). - **📊 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`). - **⚡ 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. @@ -95,6 +95,7 @@ claude | Command | Description | Example Usage | | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------- | | `start` | **Fire up the proxy server.** Supports custom ports and configuration paths. | `coding-proxy start -p 8080 -c ~/config.yaml` | +| `auth` | **Manage OAuth credentials.** Sub-commands: `login` (browser OAuth), `status` (token validity), `reauth` (re-authenticate), `logout` (clear tokens). | `coding-proxy auth login -p github` | | `status` | **Check proxy health.** Shows circuit breaker states (OPEN/CLOSED) and quota status across all tiers. | `coding-proxy status` | | `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` | | `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` | @@ -126,29 +127,29 @@ graph RL subgraph NTier["N-tier"] direction TB - subgraph Tier0 ["Tier 0: Anthropic"] + subgraph Tier0 ["Tier 0: Zhipu"] direction RL - G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("Anthropic API")):::api + G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("GLM API")):::api end - subgraph Tier1 ["Tier 1: GitHub Copilot"] + subgraph Tier1 ["Tier 1: Anthropic"] direction RL - G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Copilot API")):::api + G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Anthropic API")):::api end - subgraph Tier2 ["Tier 2: Google Antigravity"] + subgraph Tier2 ["Tier 2: GitHub Copilot"] direction RL - G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Gemini API")):::api + G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Copilot API")):::api end - subgraph TierN ["Tier N: Zhipu"] + subgraph Tier3 ["Tier 3: Google Antigravity"] direction RL - APIN(("GLM API")):::fallback + API3(("Gemini API")):::fallback end Tier0 -. "❌ Blocked / API Error" .-> Tier1 Tier1 -. "❌ Blocked / API Error" .-> Tier2 - Tier2 -. "🆘 Safety Net Downgrade" .-> TierN + Tier2 -. "🆘 Safety Net Downgrade" .-> Tier3 end end diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md index b22cdda..cc492ba 100644 --- a/docs/zh-CN/README.md +++ b/docs/zh-CN/README.md @@ -33,10 +33,10 @@ -- **⛓️ N-tier 链式故障转移 (Failover)**:自主降序序列,支持 Claude 官方 Plans,以及 GitHub Copilot、智谱、MiniMax、阿里千问、小米、Kimi、豆包等的 Coding Plan。 +- **⛓️ N-tier 链式故障转移 (Failover)**:自主降序序列,支持 Claude 官方 Plans,以及 GitHub Copilot、Google Antigravity、智谱、MiniMax、阿里千问、小米、Kimi、豆包等的 Coding Plan。 - **🛡️ 智能弹性与容灾守卫**:每个供应商节点独立配备 **熔断器 (Circuit Breaker)** 与 **配额守卫 (Quota Guard)**,防雪崩、主动避险。 - **👻 透明无感代理机制**:对客户端 **100% 透明**!无需修改任何代码,仅需一行配置覆盖 `ANTHROPIC_BASE_URL` 即可接入。 -- **🔄 跨模型与全格式转换**:原生支持 Anthropic ←→ Gemini 的请求与流式响应(SSE)双向转换,并支持自动/自助映射模型名称(如 `claude-*` 至 `glm-*`)。 +- **🔄 跨模型与全格式转换**:原生支持 Anthropic ←→ Gemini、Anthropic ←→ OpenAI 的请求与流式响应(SSE)双向转换,并支持自动/自助映射模型名称(如 `claude-*` 至 `glm-*`)。 - **📊 极致可观测性 (Observability)**:内置基于 `SQLite WAL` 的本地监控追踪,CLI 提供一键输出详细的 Token 用量统计面板(`coding-proxy usage`)。 - **⚡ 超轻量单机部署**:全异步架构 (`FastAPI` + `httpx`),无需依赖 Redis、消息队列等外部组件,对开发者机器无额外负担。 @@ -95,6 +95,7 @@ claude | 指令 | 说明 | 示例用法 | | :------- | :-------------------------------------------------------------------------------- | :-------------------------------------------- | | `start` | **启动代理服务器**。支持自定义端口与配置路径。 | `coding-proxy start -p 8080 -c ~/config.yaml` | +| `auth` | **管理 OAuth 登录凭证**。子命令:`login`(浏览器 OAuth 登录)、`status`(令牌状态)、`reauth`(重认证)、`logout`(清除令牌)。 | `coding-proxy auth login -p github` | | `status` | **查看代理健康状态**。展示各层级熔断器(OPEN/CLOSED)与配额状态。 | `coding-proxy status` | | `usage` | **Token 统计看板**。按天/供应商/模型维度追踪每一次的 Token 消耗、故障转移及耗时。 | `coding-proxy usage -d 7 -v anthropic` | | `reset` | **强制一键重置**。人工确认主供应商恢复可用后,立刻初始化所有熔断器和配额状态。 | `coding-proxy reset` | @@ -126,29 +127,29 @@ graph RL subgraph NTier["N-tier"] direction TB - subgraph Tier0 ["Tier 0: Anthropic"] + subgraph Tier0 ["Tier 0: Zhipu"] direction RL - G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("Anthropic API")):::api + G0{"CB / Quota"}:::gateway -- "✅ Pass" --> API0(("GLM API")):::api end - subgraph Tier1 ["Tier 1: GitHub Copilot"] + subgraph Tier1 ["Tier 1: Anthropic"] direction RL - G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Copilot API")):::api + G1{"CB / Quota"}:::gateway -- "✅ Pass" --> API1(("Anthropic API")):::api end - subgraph Tier2 ["Tier 2: Google Antigravity"] + subgraph Tier2 ["Tier 2: GitHub Copilot"] direction RL - G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Gemini API")):::api + G2{"CB / Quota"}:::gateway -- "✅ Pass" --> API2(("Copilot API")):::api end - subgraph TierN ["Tier N: Zhipu"] + subgraph Tier3 ["Tier 3: Google Antigravity"] direction RL - APIN(("GLM API")):::fallback + API3(("Gemini API")):::fallback end Tier0 -. "❌ Blocked / API Error" .-> Tier1 Tier1 -. "❌ Blocked / API Error" .-> Tier2 - Tier2 -. "🆘 Safety Net Downgrade" .-> TierN + Tier2 -. "🆘 Safety Net Downgrade" .-> Tier3 end end From 14ce901bc2c59b9d75ce1200395f848ae149f1e4 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 12:28:51 +0800 Subject: [PATCH 30/32] =?UTF-8?q?refactor(vendor-channels):=20=E5=B0=86=20?= =?UTF-8?q?vendor=20=E8=BD=AC=E6=8D=A2=E4=B8=93=E5=B1=9E=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E4=BB=8E=20request=5Fnormalizer=20=E8=BF=81=E5=85=A5=20vendor?= =?UTF-8?q?=5Fchannels=20=E7=BB=9F=E4=B8=80=E7=BB=B4=E6=8A=A4;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除 request_normalizer.py 中已废弃的 Phase 2 逻辑(apply_anthropic_specific_fixes、_repair_orphaned_tool_use 等), 将 enforce_anthropic_tool_pairing 和 strip_thinking_blocks 移入 vendor_channels.py, 合并重复的 _strip_thinking_blocks_inplace 为统一的 strip_thinking_blocks 公开函数, 移除 normalization 参数在 routes→router→executor 三层透传中的死参数链, 精简 NormalizationResult 仅保留 Phase 1 必要字段。 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- src/coding/proxy/convert/vendor_channels.py | 155 +++- src/coding/proxy/routing/executor.py | 2 - src/coding/proxy/routing/router.py | 10 +- src/coding/proxy/server/request_normalizer.py | 531 +------------ src/coding/proxy/server/routes.py | 16 +- tests/test_request_normalizer.py | 743 +----------------- tests/test_vendor_channels.py | 20 +- 7 files changed, 192 insertions(+), 1285 deletions(-) diff --git a/src/coding/proxy/convert/vendor_channels.py b/src/coding/proxy/convert/vendor_channels.py index e41f842..0c9146c 100644 --- a/src/coding/proxy/convert/vendor_channels.py +++ b/src/coding/proxy/convert/vendor_channels.py @@ -40,11 +40,13 @@ def get_transition_channel( # ── 共享辅助函数 ────────────────────────────────────────────── -def _strip_thinking_blocks_inplace(body: dict[str, Any]) -> int: +def strip_thinking_blocks(body: dict[str, Any]) -> int: """从 assistant 消息中移除 thinking/redacted_thinking 块(就地). - GLM-5 等 Anthropic 兼容端点不支持非 Anthropic 签发的 thinking signature, - 跨供应商场景中必须剥离以避免 400 invalid_request_error。 + Anthropic API 要求 thinking blocks 的 signature 必须是其签发的有效签名。 + 跨供应商迁移(如 Zhipu → Anthropic)后,conversation history 中可能包含 + 非 Anthropic 签发的 signature,导致 400 invalid_request_error。 + 根据 Anthropic 官方文档,thinking blocks 可以被安全省略,不影响模型行为。 剥离后 content 为空时插入最小占位 text block 以保持消息结构合法性。 @@ -69,11 +71,145 @@ def _strip_thinking_blocks_inplace(body: dict[str, Any]) -> int: removed = original_len - len(new_content) if removed and not new_content: new_content = [{"type": "text", "text": "[thinking]"}] + logger.info( + "Inserted placeholder text block after stripping " + "%d thinking block(s) to avoid empty assistant content", + removed, + ) message["content"] = new_content stripped += removed return stripped +def enforce_anthropic_tool_pairing( + messages_list: list[dict[str, Any]], +) -> list[str]: + """为跨供应商场景强制保证 Anthropic tool_use/tool_result 配对约束. + + 单次正向遍历所有消息,对每个 assistant 消息执行: + + 1. 剥离所有 tool_result 块(跨供应商产物,如 GLM-5 内联的 tool_result) + 2. 收集所有 tool_use ID + 3. 确保紧邻的下一条消息是 user 消息且包含所有必需的 tool_result + 4. 将剥离的 tool_result 重定位到正确的 user 消息 + 5. 为仍缺失的 tool_result 合成 ``is_error=True`` 的占位块 + + 此函数是一个**自包含的单遍处理**,不依赖 Phase 1 收集的 misplaced 信息。 + + Args: + messages_list: 消息列表(就地修改)。 + + Returns: + 新增的 adaptation 标签列表。 + """ + adaptations: list[str] = [] + relocated_count = 0 + synthesized_ids: list[str] = [] + + i = 0 + while i < len(messages_list): + msg = messages_list[i] + if not isinstance(msg, dict) or msg.get("role") != "assistant": + i += 1 + continue + + content = msg.get("content") + if not isinstance(content, list): + i += 1 + continue + + # A. 从 assistant 消息中剥离所有 tool_result 块 + extracted_tool_results: dict[str, dict[str, Any]] = {} + retained_content: list[Any] = [] + for block in content: + if isinstance(block, dict) and block.get("type") == "tool_result": + tid = block.get("tool_use_id") + if tid: + extracted_tool_results[tid] = block + relocated_count += 1 + else: + retained_content.append(block) + + if extracted_tool_results: + msg["content"] = retained_content + + # B. 收集所有 tool_use ID + tool_use_ids: list[str] = [ + b["id"] + for b in ( + msg.get("content") if isinstance(msg.get("content"), list) else [] + ) + if isinstance(b, dict) and b.get("type") == "tool_use" and b.get("id") + ] + if not tool_use_ids: + current_content = msg.get("content") + if isinstance(current_content, list) and not current_content: + msg["content"] = [{"type": "text", "text": ""}] + i += 1 + continue + + # C. 确保 messages[i+1] 是 user 消息 + next_idx = i + 1 + if ( + next_idx < len(messages_list) + and isinstance(messages_list[next_idx], dict) + and messages_list[next_idx].get("role") == "user" + ): + user_msg = messages_list[next_idx] + else: + user_msg: dict[str, Any] = {"role": "user", "content": []} + messages_list.insert(next_idx, user_msg) + + # D. 确保 user_msg.content 是 list + user_content = user_msg.get("content") + if isinstance(user_content, str): + user_msg["content"] = [{"type": "text", "text": user_content}] + elif not isinstance(user_content, list): + user_msg["content"] = [] + + # E. 收集 user 消息中已有的 tool_result IDs + existing_result_ids: set[str] = { + b["tool_use_id"] + for b in user_msg["content"] + if isinstance(b, dict) + and b.get("type") == "tool_result" + and b.get("tool_use_id") + } + + # F. 为每个 tool_use_id 确保 tool_result 存在 + for uid in tool_use_ids: + if uid in existing_result_ids: + continue + if uid in extracted_tool_results: + user_msg["content"].append(extracted_tool_results[uid]) + else: + user_msg["content"].append( + { + "type": "tool_result", + "tool_use_id": uid, + "content": "", + "is_error": True, + } + ) + synthesized_ids.append(uid) + + i += 1 + + if relocated_count: + adaptations.append("misplaced_tool_result_relocated") + if synthesized_ids: + adaptations.append("orphaned_tool_use_repaired") + logger.warning( + "Vendor degradation adaptation: synthesized %d tool_result block(s) " + "for orphaned tool_use to satisfy Anthropic pairing constraint. " + "Affected tool_use_ids: %s", + len(synthesized_ids), + ", ".join(synthesized_ids), + ) + + return adaptations + + def _strip_cache_control(body: dict[str, Any]) -> int: """从 system/messages/tools 中移除 cache_control 字段(就地). @@ -135,7 +271,7 @@ def prepare_copilot_to_zhipu( adaptations: list[str] = [] # Step 1: 剥离 thinking/redacted_thinking 块 - stripped = _strip_thinking_blocks_inplace(prepared) + stripped = strip_thinking_blocks(prepared) if stripped: adaptations.append(f"stripped_{stripped}_thinking_blocks") @@ -151,8 +287,6 @@ def prepare_copilot_to_zhipu( adaptations.append(f"removed_{param}_param") # Step 4: 强制 tool_use/tool_result 配对 - from ..server.request_normalizer import enforce_anthropic_tool_pairing - pairing_fixes = enforce_anthropic_tool_pairing(prepared.get("messages", [])) if pairing_fixes: adaptations.extend(pairing_fixes) @@ -183,7 +317,7 @@ def prepare_zhipu_to_copilot( adaptations: list[str] = [] # Step 1: 剥离 thinking/redacted_thinking 块 - stripped = _strip_thinking_blocks_inplace(prepared) + stripped = strip_thinking_blocks(prepared) if stripped: adaptations.append(f"stripped_{stripped}_thinking_blocks") @@ -193,8 +327,6 @@ def prepare_zhipu_to_copilot( adaptations.append(f"removed_{removed_cc}_cache_control_fields") # Step 3: 强制 tool_use/tool_result 配对 - from ..server.request_normalizer import enforce_anthropic_tool_pairing - pairing_fixes = enforce_anthropic_tool_pairing(prepared.get("messages", [])) if pairing_fixes: adaptations.extend(pairing_fixes) @@ -223,11 +355,6 @@ def prepare_zhipu_to_anthropic( Returns: (prepared_body, adaptations) — adaptations 为应用的变换描述列表。 """ - from ..server.request_normalizer import ( - enforce_anthropic_tool_pairing, - strip_thinking_blocks, - ) - prepared = copy.deepcopy(body) adaptations: list[str] = [] diff --git a/src/coding/proxy/routing/executor.py b/src/coding/proxy/routing/executor.py index 7bd52ac..d9f84b4 100644 --- a/src/coding/proxy/routing/executor.py +++ b/src/coding/proxy/routing/executor.py @@ -283,7 +283,6 @@ async def execute_stream( self, body: dict[str, Any], headers: dict[str, str], - normalization: Any = None, ) -> AsyncIterator[tuple[bytes, str]]: """路由流式请求,按优先级尝试各层级.""" last_idx = len(self._tiers) - 1 @@ -453,7 +452,6 @@ async def execute_message( self, body: dict[str, Any], headers: dict[str, str], - normalization: Any = None, ) -> VendorResponse: """路由非流式请求,按优先级尝试各层级.""" last_idx = len(self._tiers) - 1 diff --git a/src/coding/proxy/routing/router.py b/src/coding/proxy/routing/router.py index 355a91f..3a65cd6 100644 --- a/src/coding/proxy/routing/router.py +++ b/src/coding/proxy/routing/router.py @@ -134,24 +134,18 @@ async def route_stream( self, body: dict[str, Any], headers: dict[str, str], - normalization: Any = None, ) -> AsyncIterator[tuple[bytes, str]]: """路由流式请求,按优先级尝试各层级.""" - async for chunk, vendor_name in self._executor.execute_stream( - body, headers, normalization=normalization - ): + async for chunk, vendor_name in self._executor.execute_stream(body, headers): yield chunk, vendor_name async def route_message( self, body: dict[str, Any], headers: dict[str, str], - normalization: Any = None, ) -> Any: """路由非流式请求,按优先级尝试各层级.""" - return await self._executor.execute_message( - body, headers, normalization=normalization - ) + return await self._executor.execute_message(body, headers) # ── 生命周期 ─────────────────────────────────────────── diff --git a/src/coding/proxy/server/request_normalizer.py b/src/coding/proxy/server/request_normalizer.py index e445870..cbc18f5 100644 --- a/src/coding/proxy/server/request_normalizer.py +++ b/src/coding/proxy/server/request_normalizer.py @@ -10,27 +10,12 @@ logger = logging.getLogger(__name__) -# ── 跨请求日志去重:记录已报告过的 misplaced tool_use_id ────────── -# 同一 tool_use_id 仅首次输出 WARNING(含完整因果上下文), -# 后续在同一会话中重复出现时降级为 DEBUG,避免日志噪声。 -_LOGGED_MISPLACED_TOOL_IDS: set[str] = set() -_LOGGED_MISPLACED_TOOL_IDS_MAX = 500 - _ANTHROPIC_TOOL_USE_ID_RE = re.compile(r"^toolu_[A-Za-z0-9_]+$") _ANTHROPIC_SERVER_TOOL_USE_ID_RE = re.compile(r"^srvtoolu_[A-Za-z0-9_]+$") _VENDOR_TOOL_BLOCK_TYPES = { "server_tool_use_delta", } -# 标识跨供应商迁移产物的 adaptation 名称集合(用于条件化 thinking block 剥离) -_CROSS_VENDOR_ADAPTATIONS = frozenset( - { - "vendor_block_removed", - "server_tool_use_id_rewritten_for_anthropic", - "invalid_tool_use_id_rewritten_for_anthropic", - } -) - @dataclass class NormalizationResult: @@ -39,52 +24,20 @@ class NormalizationResult: body: dict[str, Any] adaptations: list[str] = field(default_factory=list) fatal_reasons: list[str] = field(default_factory=list) - # Phase 2 上下文(仅 Anthropic tier 使用) - tool_id_map: dict[str, str] = field(default_factory=dict) - misplaced_tool_results: list[tuple[int, dict[str, Any]]] = field( - default_factory=list - ) - misplaced_log_info: list[tuple[str, int, int, str]] = field(default_factory=list) @property def recoverable(self) -> bool: return not self.fatal_reasons - @property - def has_anthropic_fixes(self) -> bool: - """是否需要应用 Anthropic 专属修复(重定位 + 孤儿修复).""" - return bool(self.misplaced_tool_results) or bool(self.tool_id_map) - - @property - def has_cross_vendor_signals(self) -> bool: - """是否检测到跨供应商迁移信号(用于条件化 thinking block 剥离). - - 当请求体中包含非 Anthropic 原生格式的产物(如非标准 tool_use ID、 - 供应商私有块、错位的 tool_result 等)时返回 True。 - """ - if self.tool_id_map: - return True - if self.misplaced_tool_results: - return True - return any( - any(a.startswith(prefix) for prefix in _CROSS_VENDOR_ADAPTATIONS) - for a in self.adaptations - ) - def normalize_anthropic_request(body: dict[str, Any]) -> NormalizationResult: """清洗供应商私有块,尽量恢复为合法 Anthropic Messages 请求. - 这是 vendor-agnostic 的 Phase 1 规范化:对所有 vendor 均适用。 + vendor-agnostic 的 Phase 1 规范化:对所有 vendor 均适用。 处理策略: 1. 移除供应商私有块(如 server_tool_use_delta) 2. 重写无效/非标准的 tool_use / tool_result ID - 3. **收集**(但不应用)错位的 tool_result 块信息,供 Phase 2 使用 - - Phase 2(Anthropic 专属修复:重定位 + 孤儿修复)由 - :func:`apply_anthropic_specific_fixes` 独立执行,仅在请求实际发送给 - Anthropic tier 时调用,确保 Zhipu 等其他 vendor 不受影响。 """ normalized = copy.deepcopy(body) adaptations: list[str] = [] @@ -97,14 +50,6 @@ def next_tool_id() -> str: normalized_counter += 1 return f"toolu_normalized_{normalized_counter}" - # 收集本轮 misplaced tool_result 块(Phase 2 延迟到 Anthropic tier 执行) - collected_misplaced: list[ - tuple[int, dict[str, Any]] - ] = [] # (source_msg_idx, block) - misplaced_log_info: list[ - tuple[str, int, int, str] - ] = [] # (role, msg_idx, blk_idx, tool_use_id) - def normalize_content_block( block: Any, *, @@ -166,8 +111,6 @@ def normalize_content_block( _ANTHROPIC_TOOL_USE_ID_RE.match(tool_use_id) or _ANTHROPIC_SERVER_TOOL_USE_ID_RE.match(tool_use_id) ): - # 保持原样。对 server_tool_use_id 的用户结果,若未在当前请求体中出现, - # 交由上游决定是否接受,避免错误猜测跨轮次关联。 return normalized_block elif isinstance(tool_use_id, str) and tool_use_id: fatal_reasons.append( @@ -181,23 +124,14 @@ def normalize_content_block( return None return normalized_block - # tool_result 出现在非 user 消息中(如 assistant)—— 仅收集供 Phase 2 使用。 - # Phase 2 由 apply_anthropic_specific_fixes() 执行,仅在 Anthropic tier 时调用。 - # 对于 Zhipu 等其他 vendor,misplaced 块保留在原位不变。 + # tool_result 出现在非 user 消息中(跨供应商产物)—— 保留原样。 + # 跨供应商的 tool_use/tool_result 配对修复由 vendor_channels.py 中的 + # enforce_anthropic_tool_pairing() 在源→目标转换通道中处理。 normalized_block = dict(block) tool_use_id = normalized_block.get("tool_use_id") if isinstance(tool_use_id, str) and tool_use_id in tool_id_map: normalized_block["tool_use_id"] = tool_id_map[tool_use_id] adaptations.append("tool_result_tool_use_id_rewritten") - collected_misplaced.append((message_index, normalized_block)) - misplaced_log_info.append( - ( - message_role, - message_index, - block_index, - normalized_block.get("tool_use_id", "N/A"), - ) - ) return normalized_block return dict(block) @@ -225,461 +159,4 @@ def normalize_content_block( body=normalized, adaptations=sorted(set(adaptations)), fatal_reasons=fatal_reasons, - tool_id_map=tool_id_map, - misplaced_tool_results=collected_misplaced, - misplaced_log_info=misplaced_log_info, ) - - -def apply_anthropic_specific_fixes( - messages_list: list[dict[str, Any]], - misplaced_results: list[tuple[int, dict[str, Any]]], - misplaced_log_info: list[tuple[str, int, int, str]], -) -> list[str]: - """应用 Anthropic 专属修复(重定位 + 孤儿修复). - - 仅在请求实际发送给 Anthropic tier 时调用,确保 Zhipu 等其他 vendor 不受影响。 - Phase 1(normalize_anthropic_request)仅收集 misplaced 信息,将实际修复延迟到此函数。 - - Args: - messages_list: 消息列表(就地修改)。 - misplaced_results: Phase 1 收集的 misplaced tool_result 列表, - 每个元素为 (source_msg_idx, block)。 - misplaced_log_info: Phase 1 收集的日志信息列表, - 每个元素为 (role, msg_idx, blk_idx, tool_use_id)。 - - Returns: - 新增的 adaptation 标签列表。 - """ - adaptations: list[str] = [] - - if misplaced_results: - # ── 1. 从源消息中移除 misplaced tool_result 块 ─────────── - to_remove: dict[int, set[str]] = {} - for source_idx, block in misplaced_results: - tid = block.get("tool_use_id", "") - if tid: - to_remove.setdefault(source_idx, set()).add(tid) - - for msg_idx, tids in to_remove.items(): - if msg_idx < len(messages_list): - msg = messages_list[msg_idx] - if isinstance(msg, dict): - content = msg.get("content") - if isinstance(content, list): - msg["content"] = [ - b - for b in content - if not ( - isinstance(b, dict) - and b.get("type") == "tool_result" - and b.get("tool_use_id") in tids - ) - ] - - # ── 2. 重定位到紧邻的 user 消息 ────────────────────────── - # 按源消息索引降序处理,避免插入新消息时索引偏移。 - for source_idx, result_block in sorted( - misplaced_results, key=lambda x: x[0], reverse=True - ): - target_user_idx = None - for j in range(source_idx + 1, len(messages_list)): - if ( - isinstance(messages_list[j], dict) - and messages_list[j].get("role") == "user" - ): - target_user_idx = j - break - - if target_user_idx is not None: - target_content = messages_list[target_user_idx].get("content") - if isinstance(target_content, list): - target_content.append(result_block) - elif isinstance(target_content, str): - # string content 转为 text block 后追加,避免丢失原始文本 - messages_list[target_user_idx]["content"] = [ - {"type": "text", "text": target_content}, - result_block, - ] - else: - messages_list[target_user_idx]["content"] = [result_block] - else: - # 无后续 user 消息:插入一条合成 user 消息 - messages_list.insert( - source_idx + 1, - { - "role": "user", - "content": [result_block], - }, - ) - - adaptations.append("misplaced_tool_result_relocated") - - if misplaced_log_info: - _emit_misplaced_tool_result_summary(misplaced_log_info) - - # ── 3. 修复通道:为孤儿 tool_use 合成 tool_result ────────────── - repaired = _repair_orphaned_tool_use(messages_list) - if repaired: - adaptations.append("orphaned_tool_use_repaired") - total_synthesized = sum(repaired.values()) - logger.warning( - "Vendor degradation adaptation: synthesized %d tool_result block(s) " - "for orphaned tool_use to satisfy Anthropic pairing constraint. " - "Affected tool_use_ids: %s", - total_synthesized, - ", ".join(sorted(repaired)), - ) - - return adaptations - - -def _emit_misplaced_tool_result_summary( - stripped: list[tuple[str, int, int, str]], -) -> None: - """为被重定位的 misplaced tool_result 输出汇总日志. - - 策略: - - 将同一次请求中的多个重定位事件合并为单条日志 - - 首次出现的 tool_use_id → WARNING(含完整因果上下文) - - 同一 tool_use_id 在后续请求中再次出现 → DEBUG(避免日志噪声) - - 注意:此函数运行在 asyncio 事件循环的主线程中,set 操作无需加锁。 - - Args: - stripped: 每个元素为 (message_role, message_index, block_index, tool_use_id) - """ - # 提取去重后的 tool_use_id 集合 - unique_tool_ids = {tid for _, _, _, tid in stripped} - - # 区分首次出现 vs 已报告过的 - new_id_set = unique_tool_ids - _LOGGED_MISPLACED_TOOL_IDS - known_id_set = unique_tool_ids & _LOGGED_MISPLACED_TOOL_IDS - - # 更新已报告集合(防止无限增长:保留最近一半条目) - _LOGGED_MISPLACED_TOOL_IDS.update(unique_tool_ids) - if len(_LOGGED_MISPLACED_TOOL_IDS) > _LOGGED_MISPLACED_TOOL_IDS_MAX: - to_keep = sorted(_LOGGED_MISPLACED_TOOL_IDS)[ - _LOGGED_MISPLACED_TOOL_IDS_MAX // 2 : - ] - _LOGGED_MISPLACED_TOOL_IDS.clear() - _LOGGED_MISPLACED_TOOL_IDS.update(to_keep) - - if new_id_set: - # 首次出现:WARNING + 完整因果上下文 - positions = ", ".join( - f"messages.{mi}.content.{bi} (role={r}, tool_use_id={tid})" - for r, mi, bi, tid in stripped - if tid in new_id_set - ) - new_count = sum(1 for _, _, _, tid in stripped if tid in new_id_set) - logger.warning( - "Vendor degradation adaptation: relocated %d misplaced tool_result block(s) " - "from non-user message(s) to adjacent user message(s). Cause: cross-vendor " - "conversation history contains tool_result blocks in assistant messages " - "(typical when GLM-5 includes tool results inline in responses). Anthropic " - "API requires tool_result only in user messages, so these blocks are " - "relocated to maintain tool_use/tool_result pairing. Affected: %s. " - "Subsequent occurrences of these tool_use_ids will be logged at DEBUG level.", - new_count, - positions, - ) - - if known_id_set: - # 已报告过的:DEBUG - known_count = sum(1 for _, _, _, tid in stripped if tid in known_id_set) - logger.debug( - "Normalization: relocated %d previously reported misplaced tool_result " - "block(s) (tool_use_ids: %s)", - known_count, - ", ".join(sorted(known_id_set)), - ) - - -def _repair_orphaned_tool_use( - messages_list: list[dict[str, Any]], -) -> dict[str, int]: - """为孤儿 tool_use 块合成缺失的 tool_result. - - 遍历所有 assistant 消息,检查紧邻的 user 消息是否包含每个 tool_use - 对应的 tool_result。对于缺失的 tool_result,合成一个 ``is_error=true`` - 的占位块以满足 Anthropic API 约束。 - - Args: - messages_list: 消息列表(就地修改)。 - - Returns: - dict: 以 tool_use_id 为键、修复次数为值的映射;无修复时返回空 dict。 - """ - repaired: dict[str, int] = {} - i = 0 - while i < len(messages_list): - msg = messages_list[i] - if not isinstance(msg, dict) or msg.get("role") != "assistant": - i += 1 - continue - - content = msg.get("content") - if not isinstance(content, list): - i += 1 - continue - - # 收集当前 assistant 消息中所有 tool_use 的 id - tool_use_ids: list[str] = [ - b["id"] - for b in content - if isinstance(b, dict) and b.get("type") == "tool_use" and b.get("id") - ] - if not tool_use_ids: - i += 1 - continue - - # 检查紧邻的 user 消息中已有的 tool_result - next_msg = messages_list[i + 1] if i + 1 < len(messages_list) else None - existing_result_ids: set[str] = set() - - if isinstance(next_msg, dict) and next_msg.get("role") == "user": - next_content = next_msg.get("content") - if isinstance(next_content, list): - existing_result_ids = { - b["tool_use_id"] - for b in next_content - if isinstance(b, dict) - and b.get("type") == "tool_result" - and b.get("tool_use_id") - } - - # 找出缺失的 tool_result - orphan_ids = [uid for uid in tool_use_ids if uid not in existing_result_ids] - if not orphan_ids: - i += 1 - continue - - # 为每个孤儿 tool_use 合成 tool_result - synthetic_blocks = [ - { - "type": "tool_result", - "tool_use_id": uid, - "content": "", - "is_error": True, - } - for uid in orphan_ids - ] - - if isinstance(next_msg, dict) and next_msg.get("role") == "user": - next_content = next_msg.get("content") - if isinstance(next_content, list): - next_content.extend(synthetic_blocks) - elif isinstance(next_content, str): - next_msg["content"] = [ - {"type": "text", "text": next_content} - ] + synthetic_blocks - else: - next_msg["content"] = synthetic_blocks - else: - # 无紧邻 user 消息:插入合成 user 消息 - messages_list.insert(i + 1, {"role": "user", "content": synthetic_blocks}) - - for uid in orphan_ids: - repaired[uid] = repaired.get(uid, 0) + 1 - - i += 1 - return repaired - - -# ── Phase 2: 跨供应商 tool_use/tool_result 配对强制修复 ───────── - - -def enforce_anthropic_tool_pairing( - messages_list: list[dict[str, Any]], -) -> list[str]: - """为跨供应商场景强制保证 Anthropic tool_use/tool_result 配对约束. - - 单次正向遍历所有消息,对每个 assistant 消息执行: - - 1. 剥离所有 tool_result 块(跨供应商产物,如 GLM-5 内联的 tool_result) - 2. 收集所有 tool_use ID - 3. 确保紧邻的下一条消息是 user 消息且包含所有必需的 tool_result - 4. 将剥离的 tool_result 重定位到正确的 user 消息 - 5. 为仍缺失的 tool_result 合成 ``is_error=True`` 的占位块 - - 此函数是一个**自包含的单遍处理**,不依赖 Phase 1 收集的 misplaced 信息, - 通过直接扫描消息列表确保处理的完备性。替代此前多步串联管线 - (剥离 → 重定位 → 孤儿修复)因步骤间隐式依赖导致的漏修问题。 - - 仅在请求实际发送给 Anthropic tier 且检测到跨供应商信号时调用, - 确保 Zhipu 等其他 vendor 不受影响。 - - Args: - messages_list: 消息列表(就地修改)。 - - Returns: - 新增的 adaptation 标签列表。 - """ - adaptations: list[str] = [] - relocated_count = 0 - synthesized_ids: list[str] = [] - - i = 0 - while i < len(messages_list): - msg = messages_list[i] - if not isinstance(msg, dict) or msg.get("role") != "assistant": - i += 1 - continue - - content = msg.get("content") - if not isinstance(content, list): - i += 1 - continue - - # ── A. 从 assistant 消息中剥离所有 tool_result 块 ───────── - extracted_tool_results: dict[str, dict[str, Any]] = {} # tool_use_id → block - retained_content: list[Any] = [] - for block in content: - if isinstance(block, dict) and block.get("type") == "tool_result": - tid = block.get("tool_use_id") - if tid: - extracted_tool_results[tid] = block - relocated_count += 1 - # 无 tool_use_id 的 tool_result 直接丢弃(无效块) - else: - retained_content.append(block) - - if extracted_tool_results: - msg["content"] = retained_content - - # ── B. 收集所有 tool_use ID ─────────────────────────────── - tool_use_ids: list[str] = [ - b["id"] - for b in ( - msg.get("content") if isinstance(msg.get("content"), list) else [] - ) - if isinstance(b, dict) and b.get("type") == "tool_use" and b.get("id") - ] - if not tool_use_ids: - # 无 tool_use 块:若剥离后 content 为空,插入占位 - current_content = msg.get("content") - if isinstance(current_content, list) and not current_content: - msg["content"] = [{"type": "text", "text": ""}] - i += 1 - continue - - # ── C. 确保 messages[i+1] 是 user 消息 ─────────────────── - next_idx = i + 1 - if ( - next_idx < len(messages_list) - and isinstance(messages_list[next_idx], dict) - and messages_list[next_idx].get("role") == "user" - ): - user_msg = messages_list[next_idx] - else: - # 插入合成 user 消息 - user_msg: dict[str, Any] = {"role": "user", "content": []} - messages_list.insert(next_idx, user_msg) - - # ── D. 确保 user_msg.content 是 list ───────────────────── - user_content = user_msg.get("content") - if isinstance(user_content, str): - user_msg["content"] = [{"type": "text", "text": user_content}] - elif not isinstance(user_content, list): - user_msg["content"] = [] - - # ── E. 收集 user 消息中已有的 tool_result IDs ───────────── - existing_result_ids: set[str] = { - b["tool_use_id"] - for b in user_msg["content"] - if isinstance(b, dict) - and b.get("type") == "tool_result" - and b.get("tool_use_id") - } - - # ── F. 为每个 tool_use_id 确保 tool_result 存在 ────────── - for uid in tool_use_ids: - if uid in existing_result_ids: - continue # 已有匹配的 tool_result - - if uid in extracted_tool_results: - # 从 assistant 剥离的 tool_result 重定位到 user - user_msg["content"].append(extracted_tool_results[uid]) - else: - # 完全缺失:合成 is_error=True 占位块 - user_msg["content"].append( - { - "type": "tool_result", - "tool_use_id": uid, - "content": "", - "is_error": True, - } - ) - synthesized_ids.append(uid) - - i += 1 - - # ── 构建 adaptation 标签与日志 ──────────────────────────── - if relocated_count: - adaptations.append("misplaced_tool_result_relocated") - if synthesized_ids: - adaptations.append("orphaned_tool_use_repaired") - logger.warning( - "Vendor degradation adaptation: synthesized %d tool_result block(s) " - "for orphaned tool_use to satisfy Anthropic pairing constraint. " - "Affected tool_use_ids: %s", - len(synthesized_ids), - ", ".join(synthesized_ids), - ) - - return adaptations - - -# ── Phase 2: Thinking block 剥离 ────────────────────────────── - -# 需要从 assistant messages 中剥离的 thinking block 类型 -_THINKING_BLOCK_TYPES = {"thinking", "redacted_thinking"} - - -def strip_thinking_blocks(body: dict[str, Any]) -> int: - """从 assistant messages 中移除 thinking / redacted_thinking blocks. - - Anthropic API 要求 thinking blocks 的 ``signature`` 必须是其签发的有效签名。 - 跨供应商迁移(如 Zhipu → Anthropic)后,conversation history 中可能包含 - 非 Anthropic 签发的 signature,导致 400 ``invalid_request_error``。 - 根据 Anthropic 官方文档,thinking blocks 可以被安全省略,不影响模型行为。 - - 此函数仅在 executor 检测到跨供应商信号时调用(条件化剥离), - 纯 Anthropic 会话中 thinking blocks 保持原样以维持上下文连续性。 - - Args: - body: 请求体(就地修改)。 - - Returns: - 被移除的 thinking block 数量。 - """ - stripped = 0 - for message in body.get("messages", []): - if not isinstance(message, dict) or message.get("role") != "assistant": - continue - content = message.get("content") - if not isinstance(content, list): - continue - original_len = len(content) - new_content = [ - block - for block in content - if not ( - isinstance(block, dict) and block.get("type") in _THINKING_BLOCK_TYPES - ) - ] - removed = original_len - len(new_content) - if removed and not new_content: - # 剥离所有 thinking blocks 后 content 为空 —— - # Anthropic API 要求非末尾 assistant message 的 content 必须非空。 - # 插入最小占位 text block 以保持消息结构合法性。 - new_content = [{"type": "text", "text": "[thinking]"}] - logger.info( - "anthropic: inserted placeholder text block after stripping " - "%d thinking block(s) to avoid empty assistant content", - removed, - ) - message["content"] = new_content - stripped += removed - return stripped diff --git a/src/coding/proxy/server/routes.py b/src/coding/proxy/server/routes.py index d105ebe..5ad312d 100644 --- a/src/coding/proxy/server/routes.py +++ b/src/coding/proxy/server/routes.py @@ -24,14 +24,10 @@ logger = logging.getLogger(__name__) -async def _stream_proxy( - router: Any, body: dict, headers: dict, normalization: Any = None -) -> Any: +async def _stream_proxy(router: Any, body: dict, headers: dict) -> Any: """流式代理生成器.""" try: - async for chunk, vendor_name in router.route_stream( - body, headers, normalization=normalization - ): + async for chunk, vendor_name in router.route_stream(body, headers): yield chunk except NoCompatibleVendorError as exc: yield ( @@ -82,15 +78,13 @@ async def messages(request: Request) -> Response: if is_streaming: return StreamingResponse( - _stream_proxy(router, body, headers, normalization=normalization), + _stream_proxy(router, body, headers), media_type="text/event-stream", headers={"Cache-Control": "no-cache", "Connection": "keep-alive"}, ) try: - resp = await router.route_message( - body, headers, normalization=normalization - ) + resp = await router.route_message(body, headers) except NoCompatibleVendorError as exc: return json_error_response( 400, @@ -158,7 +152,7 @@ async def count_tokens(request: Request) -> Response: # count_tokens 无会话上下文,无法判断 thinking block 来源, # 安全剥离以防止跨供应商 signature 导致 400 错误。 - from .request_normalizer import strip_thinking_blocks + from ..convert.vendor_channels import strip_thinking_blocks strip_thinking_blocks(body) diff --git a/tests/test_request_normalizer.py b/tests/test_request_normalizer.py index 98ea238..bf653a9 100644 --- a/tests/test_request_normalizer.py +++ b/tests/test_request_normalizer.py @@ -4,23 +4,11 @@ import copy -from coding.proxy.server.request_normalizer import ( - apply_anthropic_specific_fixes, +from coding.proxy.convert.vendor_channels import ( enforce_anthropic_tool_pairing, - normalize_anthropic_request, strip_thinking_blocks, ) - - -def _apply_phase2(result): - """在 deep copy 上执行 Phase 2(Anthropic 专属修复),返回 (body, fixes).""" - body_copy = copy.deepcopy(result.body) - fixes = apply_anthropic_specific_fixes( - body_copy.get("messages", []), - result.misplaced_tool_results, - result.misplaced_log_info, - ) - return body_copy, fixes +from coding.proxy.server.request_normalizer import normalize_anthropic_request def test_rewrites_server_tool_use_to_standard_tool_use(): @@ -113,10 +101,10 @@ def test_unknown_tool_result_id_marks_fatal_reason(): class TestPhase1OnlyNormalization: - """验证 Phase 1(vendor-agnostic)不执行 Anthropic 专属修复. + """验证 Phase 1(vendor-agnostic)仅执行 ID 重写和 vendor block 移除. - Phase 1 仅执行 ID 重写、vendor block 移除、misplaced 信息收集。 - 重定位和孤儿修复由 Phase 2(apply_anthropic_specific_fixes)延迟执行。 + 跨供应商的 tool_use/tool_result 配对修复由 vendor_channels.py 中的 + enforce_anthropic_tool_pairing() 在源→目标转换通道中处理。 """ def test_phase1_keeps_misplaced_tool_result_in_place(self): @@ -147,12 +135,10 @@ def test_phase1_keeps_misplaced_tool_result_in_place(self): assert result.recoverable is True assert "misplaced_tool_result_relocated" not in result.adaptations assert "orphaned_tool_use_repaired" not in result.adaptations - # misplaced block 应仍在 assistant 消息中 + # misplaced block 应仍在 assistant 消息中(Phase 1 不处理) assistant_content = result.body["messages"][0]["content"] assert len(assistant_content) == 2 assert assistant_content[1]["type"] == "tool_result" - # Phase 2 上下文已收集 - assert len(result.misplaced_tool_results) == 1 def test_phase1_does_not_repair_orphans(self): """Phase 1 不应为孤儿 tool_use 合成 tool_result.""" @@ -178,467 +164,12 @@ def test_phase1_does_not_repair_orphans(self): assert "orphaned_tool_use_repaired" not in result.adaptations assert len(result.body["messages"]) == 1 # 无合成 user 消息 - -# ── 跨供应商 tool_result 位置错位重定位测试(Phase 1 + Phase 2)── - - -class TestMisplacedToolResultRelocation: - """验证 Phase 1 + Phase 2 组合能正确重定位 misplaced tool_result. - - Phase 1 收集 misplaced 信息,Phase 2 执行实际重定位。 - 此类测试模拟 executor 在 Anthropic tier 时的完整行为。 - """ - - def test_relocates_tool_result_from_assistant_message(self): - """assistant 消息中的 tool_result 经 Phase 2 重定位到新建的 user 消息.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "user", - "content": "run ls", - }, - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_123", - "name": "Bash", - "input": {"command": "ls"}, - }, - { - "type": "tool_result", - "tool_use_id": "toolu_123", - "content": "file1.txt\nfile2.txt", - }, - ], - }, - ], - } - ) - - # Phase 2 - body, fixes = _apply_phase2(result) - assert "misplaced_tool_result_relocated" in fixes - - messages = body["messages"] - assert len(messages) == 3 - # assistant 消息应只保留 tool_use - assistant_content = messages[1]["content"] - assert len(assistant_content) == 1 - assert assistant_content[0]["type"] == "tool_use" - assert assistant_content[0]["id"] == "toolu_123" - # 新增一条 user 消息包含被重定位的 tool_result - assert messages[2]["role"] == "user" - relocated_block = messages[2]["content"][0] - assert relocated_block["type"] == "tool_result" - assert relocated_block["tool_use_id"] == "toolu_123" - assert relocated_block["content"] == "file1.txt\nfile2.txt" - - def test_relocates_tool_result_preserves_other_blocks(self): - """重定位 tool_result 时保留同消息中的其他内容块.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - {"type": "text", "text": "Let me check."}, - { - "type": "tool_use", - "id": "toolu_456", - "name": "Read", - "input": {"path": "/etc/hosts"}, - }, - { - "type": "tool_result", - "tool_use_id": "toolu_456", - "content": "127.0.0.1 localhost", - }, - {"type": "text", "text": "Done."}, - ], - }, - ], - } - ) - - # Phase 2 - body, fixes = _apply_phase2(result) - assert "misplaced_tool_result_relocated" in fixes - - messages = body["messages"] - # assistant 消息保留 text + tool_use + text - assistant_content = messages[0]["content"] - assert len(assistant_content) == 3 - types = [b["type"] for b in assistant_content] - assert types == ["text", "tool_use", "text"] - # 新增 user 消息包含被重定位的 tool_result - assert len(messages) == 2 - assert messages[1]["role"] == "user" - assert messages[1]["content"][0]["type"] == "tool_result" - assert messages[1]["content"][0]["tool_use_id"] == "toolu_456" - - def test_tool_result_in_user_message_untouched(self): - """user 消息中的 tool_result 不受影响.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_789", - "name": "Bash", - "input": {"command": "echo hi"}, - }, - ], - }, - { - "role": "user", - "content": [ - { - "type": "tool_result", - "tool_use_id": "toolu_789", - "content": "hi", - }, - ], - }, - ], - } - ) - - assert result.recoverable is True - assert not result.misplaced_tool_results # 无 misplaced 块 - user_content = result.body["messages"][1]["content"] - assert len(user_content) == 1 - assert user_content[0]["type"] == "tool_result" - assert "misplaced_tool_result_relocated" not in result.adaptations - - def test_mixed_scenario_relocates_to_existing_user_message(self): - """assistant 和 user 消息中同时有 tool_result 时,assistant 中的被重定位到 user 消息.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_100", - "name": "Bash", - "input": {"command": "ls"}, - }, - { - "type": "tool_result", - "tool_use_id": "toolu_100", - "content": "misplaced result", - }, - ], - }, - { - "role": "user", - "content": [ - { - "type": "tool_result", - "tool_use_id": "toolu_100", - "content": "correct result", - }, - ], - }, - ], - } - ) - - # Phase 2 - body, fixes = _apply_phase2(result) - assert "misplaced_tool_result_relocated" in fixes - - # assistant 中的 tool_result 被移除 - assistant_content = body["messages"][0]["content"] - assert len(assistant_content) == 1 - assert assistant_content[0]["type"] == "tool_use" - # user 消息现在包含两个 tool_result(原有的 + 重定位来的) - user_content = body["messages"][1]["content"] - assert len(user_content) == 2 - assert all(b["type"] == "tool_result" for b in user_content) - - def test_deep_conversation_with_misplaced_tool_result_at_index_105(self): - """模拟长对话(105+ 消息)中 tool_result 出现在 assistant 消息的场景.""" - # 构建一个 106 条消息的对话历史 - messages = [] - for i in range(104): - role = "user" if i % 2 == 0 else "assistant" - messages.append( - { - "role": role, - "content": f"message {i}", - } - ) - - # 在消息 104(assistant)中放置 tool_use + tool_result - messages.append( - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_deep_1", - "name": "Bash", - "input": {"command": "find / -name '*.log'"}, - }, - { - "type": "tool_result", - "tool_use_id": "toolu_deep_1", - "content": "/var/log/system.log", - }, - ], - } - ) - # 消息 105(user) - messages.append( - { - "role": "user", - "content": "thanks", - } - ) - - result = normalize_anthropic_request({"messages": messages}) - - # Phase 2 - body, fixes = _apply_phase2(result) - assert "misplaced_tool_result_relocated" in fixes - - # 消息 104 中的 tool_result 应被移除 - assert len(body["messages"][104]["content"]) == 1 - assert body["messages"][104]["content"][0]["type"] == "tool_use" - # 消息 105(user)应包含原始文本 + 被重定位的 tool_result - user_content = body["messages"][105]["content"] - assert isinstance(user_content, list) - tool_result_blocks = [b for b in user_content if b.get("type") == "tool_result"] - text_blocks = [b for b in user_content if b.get("type") == "text"] - assert len(text_blocks) == 1 - assert text_blocks[0]["text"] == "thanks" - assert len(tool_result_blocks) == 1 - assert tool_result_blocks[0]["tool_use_id"] == "toolu_deep_1" - assert tool_result_blocks[0]["content"] == "/var/log/system.log" - - def test_rewrites_srvtoolu_id_when_relocating(self): - """重定位时同时重写 srvtoolu_ 前缀的 tool_use_id.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "server_tool_use", - "id": "srvtoolu_bad_1", - "name": "bash", - "input": {"cmd": "pwd"}, - }, - { - "type": "tool_result", - "tool_use_id": "srvtoolu_bad_1", - "content": "/home/user", - }, - ], - }, - ], - } - ) - - # Phase 2 - body, fixes = _apply_phase2(result) - assert "misplaced_tool_result_relocated" in fixes - assert "tool_result_tool_use_id_rewritten" in result.adaptations - - messages = body["messages"] - # assistant 中的 tool_use ID 已重写 - new_id = messages[0]["content"][0]["id"] - assert new_id.startswith("toolu_normalized_") - # 重定位到新 user 消息的 tool_result 使用相同的重写 ID - relocated = messages[1]["content"][0] - assert relocated["type"] == "tool_result" - assert relocated["tool_use_id"] == new_id - - -# ── 孤儿 tool_use 修复测试(Phase 1 + Phase 2)───────────────────── - - -class TestOrphanedToolUseRepair: - """验证 Phase 1 + Phase 2 组合能正确修复孤儿 tool_use. - - Phase 1 收集上下文(如 tool_id_map),Phase 2 执行孤儿修复。 - 此类测试模拟 executor 在 Anthropic tier 时的完整行为。 - """ - - def test_synthesizes_result_for_orphaned_tool_use(self): - """assistant 有 tool_use 且无后续 user 消息时,合成 user 消息含占位 tool_result.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_123", - "name": "Bash", - "input": {"command": "ls"}, - }, - ], - }, - ], - } - ) - - # Phase 2(手动调用,模拟 Anthropic tier 行为) - body, fixes = _apply_phase2(result) - assert "orphaned_tool_use_repaired" in fixes - - messages = body["messages"] - assert len(messages) == 2 - assert messages[1]["role"] == "user" - synthetic = messages[1]["content"][0] - assert synthetic["type"] == "tool_result" - assert synthetic["tool_use_id"] == "toolu_123" - assert synthetic["is_error"] is True - - def test_synthesizes_result_appends_to_existing_user(self): - """assistant 有 tool_use 且后续 user 消息为 text 时,追加合成 tool_result.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_456", - "name": "Bash", - "input": {"command": "pwd"}, - }, - ], - }, - { - "role": "user", - "content": "continue", - }, - ], - } - ) - - # Phase 2(手动调用,模拟 Anthropic tier 行为) - body, fixes = _apply_phase2(result) - assert "orphaned_tool_use_repaired" in fixes - - messages = body["messages"] - user_content = messages[1]["content"] - assert isinstance(user_content, list) - # 原始文本转为 text block + 合成的 tool_result - assert len(user_content) == 2 - assert user_content[0]["type"] == "text" - assert user_content[0]["text"] == "continue" - assert user_content[1]["type"] == "tool_result" - assert user_content[1]["tool_use_id"] == "toolu_456" - assert user_content[1]["is_error"] is True - - def test_synthesizes_only_missing_results(self): - """assistant 有 2 个 tool_use,user 仅有 1 个 tool_result 时,仅为缺失的合成.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_A", - "name": "Bash", - "input": {"command": "ls"}, - }, - { - "type": "tool_use", - "id": "toolu_B", - "name": "Read", - "input": {"path": "/etc/hosts"}, - }, - ], - }, - { - "role": "user", - "content": [ - { - "type": "tool_result", - "tool_use_id": "toolu_A", - "content": "file1.txt", - }, - ], - }, - ], - } - ) - - # Phase 2(手动调用,模拟 Anthropic tier 行为) - body, fixes = _apply_phase2(result) - assert "orphaned_tool_use_repaired" in fixes - - user_content = body["messages"][1]["content"] - assert len(user_content) == 2 - # 原有 tool_result 保持不变 - assert user_content[0]["tool_use_id"] == "toolu_A" - # 合成的 tool_result 仅针对 toolu_B - assert user_content[1]["type"] == "tool_result" - assert user_content[1]["tool_use_id"] == "toolu_B" - assert user_content[1]["is_error"] is True - - def test_no_repair_when_all_results_present(self): - """正常配对场景不应触发修复.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_ok", - "name": "Bash", - "input": {"command": "echo hi"}, - }, - ], - }, - { - "role": "user", - "content": [ - { - "type": "tool_result", - "tool_use_id": "toolu_ok", - "content": "hi", - }, - ], - }, - ], - } - ) - - assert result.recoverable is True - assert not result.misplaced_tool_results - # Phase 2 不应有任何修复 - body, fixes = _apply_phase2(result) - assert "orphaned_tool_use_repaired" not in fixes - - def test_repair_with_normalized_ids(self): - """跨供应商降级场景:srvtoolu_ ID 被重写后仍需修复孤儿 tool_use. - - 此场景下 tool_id_map 有条目,has_anthropic_fixes 为 True, - executor 会自动触发 Phase 2。 - """ + def test_phase1_then_enforce_pairing(self): + """Phase 1 + enforce_anthropic_tool_pairing 端到端测试(模拟完整链路).""" result = normalize_anthropic_request( { "messages": [ + {"role": "user", "content": "hello"}, { "role": "assistant", "content": [ @@ -654,194 +185,37 @@ def test_repair_with_normalized_ids(self): "name": "Read", "input": {"path": "/tmp"}, }, - ], - }, - { - "role": "user", - "content": "continue", - }, - ], - } - ) - - # has_anthropic_fixes 为 True(因 tool_id_map 有条目) - assert result.has_anthropic_fixes is True - - # Phase 2 - body, fixes = _apply_phase2(result) - assert "orphaned_tool_use_repaired" in fixes - - messages = body["messages"] - # assistant 中 tool_use ID 已重写 - new_ids = [b["id"] for b in messages[0]["content"]] - assert len(new_ids) == 2 - assert all(id_.startswith("toolu_normalized_") for id_ in new_ids) - # user 消息应包含原始文本 + 两个合成的 tool_result - user_content = messages[1]["content"] - text_blocks = [b for b in user_content if b.get("type") == "text"] - synthetic_results = [ - b - for b in user_content - if b.get("type") == "tool_result" and b.get("is_error") is True - ] - assert len(text_blocks) == 1 - assert len(synthetic_results) == 2 - assert {r["tool_use_id"] for r in synthetic_results} == set(new_ids) - - -# ── has_cross_vendor_signals 属性测试 ────────────────────────── - - -class TestHasCrossVendorSignals: - """验证 NormalizationResult.has_cross_vendor_signals 属性.""" - - def test_true_when_tool_id_map_nonempty(self): - """tool_id_map 非空时标识为跨供应商信号.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "server_tool_use", - "id": "srvtoolu_abc", - "name": "Bash", - "input": {"command": "ls"}, - }, - ], - }, - ], - } - ) - assert result.tool_id_map # 非空 - assert result.has_cross_vendor_signals is True - - def test_true_when_misplaced_tool_results_exist(self): - """misplaced_tool_results 非空时标识为跨供应商信号.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_123", - "name": "Bash", - "input": {"command": "ls"}, - }, { "type": "tool_result", - "tool_use_id": "toolu_123", - "content": "output", - }, - ], - }, - ], - } - ) - assert result.misplaced_tool_results # 非空 - assert result.has_cross_vendor_signals is True - - def test_true_when_vendor_block_removed(self): - """vendor block 被移除时标识为跨供应商信号.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - {"type": "text", "text": "hello"}, - { - "type": "server_tool_use_delta", - "partial_json": '{"cmd":"pwd"}', - }, - ], - }, - ], - } - ) - assert "vendor_block_removed:server_tool_use_delta" in result.adaptations - assert result.has_cross_vendor_signals is True - - def test_true_when_invalid_tool_id_rewritten(self): - """非标准 tool_use ID 被重写时标识为跨供应商信号.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "glm_custom_id_123", - "name": "Bash", - "input": {"command": "ls"}, + "tool_use_id": "srvtoolu_X", + "content": "zhipu result", }, ], }, + {"role": "user", "content": "continue"}, ], } ) - assert "invalid_tool_use_id_rewritten_for_anthropic" in result.adaptations - assert result.has_cross_vendor_signals is True + assert result.recoverable - def test_false_for_pure_anthropic_request(self): - """纯 Anthropic 请求不应标识为跨供应商信号.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "thinking", - "thinking": "let me think", - "signature": "anthropic-valid-sig", - }, - {"type": "text", "text": "response"}, - ], - }, - {"role": "user", "content": "follow up"}, - ], - } - ) - assert not result.tool_id_map - assert not result.misplaced_tool_results - assert not result.adaptations - assert result.has_cross_vendor_signals is False + # 在 deep copy 上执行 enforce_anthropic_tool_pairing(模拟 vendor channel) + body_copy = copy.deepcopy(result.body) + fixes = enforce_anthropic_tool_pairing(body_copy.get("messages", [])) + assert "misplaced_tool_result_relocated" in fixes + assert "orphaned_tool_use_repaired" in fixes - def test_false_for_standard_tool_use(self): - """标准 toolu_ ID 不应标识为跨供应商信号.""" - result = normalize_anthropic_request( - { - "messages": [ - { - "role": "assistant", - "content": [ - { - "type": "tool_use", - "id": "toolu_standard_abc", - "name": "Bash", - "input": {"command": "ls"}, - }, - ], - }, - { - "role": "user", - "content": [ - { - "type": "tool_result", - "tool_use_id": "toolu_standard_abc", - "content": "output", - }, - ], - }, - ], - } - ) - assert result.has_cross_vendor_signals is False + messages = body_copy["messages"] + # assistant 只保留 2 个 tool_use + assistant_content = messages[1]["content"] + assert len(assistant_content) == 2 + assert all(b["type"] == "tool_use" for b in assistant_content) + # user 消息包含 2 个 tool_result + user_content = messages[2]["content"] + result_blocks = [b for b in user_content if b.get("type") == "tool_result"] + assert len(result_blocks) == 2 + expected_ids = {b["id"] for b in assistant_content} + result_ids = {b["tool_use_id"] for b in result_blocks} + assert result_ids == expected_ids # ── strip_thinking_blocks 函数测试 ────────────────────────────── @@ -996,7 +370,6 @@ def _enforce_pairing(messages): class TestEnforceAnthropicToolPairing: """验证 enforce_anthropic_tool_pairing 单遍强制配对函数. - 此函数替代原有多步串联管线(apply_anthropic_specific_fixes), 通过单次正向遍历完成 tool_result 剥离、重定位和孤儿合成。 """ @@ -1436,59 +809,3 @@ def test_next_message_is_assistant_inserts_user(self): assert messages[1]["role"] == "user" assert messages[1]["content"][0]["type"] == "tool_result" assert messages[2]["role"] == "assistant" - - def test_phase1_then_enforce_pairing(self): - """Phase 1 + enforce_anthropic_tool_pairing 端到端测试(模拟完整链路).""" - result = normalize_anthropic_request( - { - "messages": [ - {"role": "user", "content": "hello"}, - { - "role": "assistant", - "content": [ - { - "type": "server_tool_use", - "id": "srvtoolu_X", - "name": "Bash", - "input": {"command": "ls"}, - }, - { - "type": "server_tool_use", - "id": "srvtoolu_Y", - "name": "Read", - "input": {"path": "/tmp"}, - }, - { - "type": "tool_result", - "tool_use_id": "srvtoolu_X", - "content": "zhipu result", - }, - ], - }, - {"role": "user", "content": "continue"}, - ], - } - ) - assert result.recoverable - # Phase 1 重写了 ID,收集了 misplaced - assert result.tool_id_map - assert result.misplaced_tool_results - - # 在 deep copy 上执行 enforce_anthropic_tool_pairing(模拟 executor) - body_copy = copy.deepcopy(result.body) - fixes = enforce_anthropic_tool_pairing(body_copy.get("messages", [])) - assert "misplaced_tool_result_relocated" in fixes - assert "orphaned_tool_use_repaired" in fixes - - messages = body_copy["messages"] - # assistant 只保留 2 个 tool_use - assistant_content = messages[1]["content"] - assert len(assistant_content) == 2 - assert all(b["type"] == "tool_use" for b in assistant_content) - # user 消息包含 2 个 tool_result - user_content = messages[2]["content"] - result_blocks = [b for b in user_content if b.get("type") == "tool_result"] - assert len(result_blocks) == 2 - expected_ids = {b["id"] for b in assistant_content} - result_ids = {b["tool_use_id"] for b in result_blocks} - assert result_ids == expected_ids diff --git a/tests/test_vendor_channels.py b/tests/test_vendor_channels.py index ceb9f3b..7de4eae 100644 --- a/tests/test_vendor_channels.py +++ b/tests/test_vendor_channels.py @@ -4,7 +4,7 @@ - zhipu → anthropic 转换 (prepare_zhipu_to_anthropic) - zhipu → copilot 转换 (prepare_zhipu_to_copilot) - copilot → zhipu 转换 (prepare_copilot_to_zhipu) -- 共享辅助函数 (_strip_thinking_blocks_inplace, _strip_cache_control) +- 共享辅助函数 (strip_thinking_blocks, _strip_cache_control) - 转换注册表 (VENDOR_TRANSITIONS, get_transition_channel) """ @@ -15,18 +15,18 @@ from coding.proxy.convert.vendor_channels import ( VENDOR_TRANSITIONS, _strip_cache_control, - _strip_thinking_blocks_inplace, get_transition_channel, prepare_copilot_to_zhipu, prepare_zhipu_to_anthropic, prepare_zhipu_to_copilot, + strip_thinking_blocks, ) # ── 辅助函数测试 ────────────────────────────────────────────── -class TestStripThinkingBlocksInplace: - """_strip_thinking_blocks_inplace 单元测试.""" +class TestStripThinkingBlocks: + """strip_thinking_blocks 单元测试.""" def test_strips_thinking_blocks(self): body = { @@ -40,7 +40,7 @@ def test_strips_thinking_blocks(self): }, ] } - stripped = _strip_thinking_blocks_inplace(body) + stripped = strip_thinking_blocks(body) assert stripped == 1 assert body["messages"][0]["content"] == [ {"type": "text", "text": "response"}, @@ -57,7 +57,7 @@ def test_strips_redacted_thinking_blocks(self): }, ] } - stripped = _strip_thinking_blocks_inplace(body) + stripped = strip_thinking_blocks(body) assert stripped == 1 # content 为空时插入占位 text block assert body["messages"][0]["content"] == [ @@ -80,7 +80,7 @@ def test_inserts_placeholder_when_all_thinking(self): }, ] } - stripped = _strip_thinking_blocks_inplace(body) + stripped = strip_thinking_blocks(body) assert stripped == 2 assert body["messages"][1]["content"] == [ {"type": "text", "text": "[thinking]"}, @@ -95,7 +95,7 @@ def test_no_change_when_no_thinking(self): }, ] } - stripped = _strip_thinking_blocks_inplace(body) + stripped = strip_thinking_blocks(body) assert stripped == 0 assert body["messages"][0]["content"] == [{"type": "text", "text": "hello"}] @@ -105,7 +105,7 @@ def test_skips_non_assistant_messages(self): {"role": "user", "content": [{"type": "thinking", "thinking": "t"}]}, ] } - stripped = _strip_thinking_blocks_inplace(body) + stripped = strip_thinking_blocks(body) assert stripped == 0 def test_handles_string_content(self): @@ -114,7 +114,7 @@ def test_handles_string_content(self): {"role": "assistant", "content": "plain text"}, ] } - stripped = _strip_thinking_blocks_inplace(body) + stripped = strip_thinking_blocks(body) assert stripped == 0 From 9343da474b89e12c17d8e2868301e7e355b1b003 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 16:19:57 +0800 Subject: [PATCH 31/32] =?UTF-8?q?build(version):=20=E5=8D=87=E7=BA=A7?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8F=B7=E8=87=B3=200.2.4a5;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 37c929d..5229ee5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "coding-proxy" -version = "0.2.4a4" +version = "0.2.4a5" description = "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..." readme = "README.md" requires-python = ">=3.12" diff --git a/uv.lock b/uv.lock index a7dd386..beb44bd 100644 --- a/uv.lock +++ b/uv.lock @@ -74,7 +74,7 @@ wheels = [ [[package]] name = "coding-proxy" -version = "0.2.4a4" +version = "0.2.4a5" source = { editable = "." } dependencies = [ { name = "aiosqlite" }, From 634814754364ce9469d1959506091fd39005dbb3 Mon Sep 17 00:00:00 2001 From: ThreeFish Date: Sat, 18 Apr 2026 17:05:46 +0800 Subject: [PATCH 32/32] =?UTF-8?q?chore(assets):=20=E6=9B=B4=E6=96=B0=20das?= =?UTF-8?q?hboard=20v0.2.3=20=E6=88=AA=E5=9B=BE;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist) Co-Authored-By: Aurelius Huang --- assets/dashboard-v0.2.3.png | Bin 966195 -> 346346 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/assets/dashboard-v0.2.3.png b/assets/dashboard-v0.2.3.png index bbd2602088ff146b2b4f694e9ed915d272b05f9c..aef75f78436e70704121e036a5f3fad767ebbccd 100644 GIT binary patch literal 346346 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

#UTvslSuU~%QTAun$%h?o`->ELR!hIAs6L^P1n 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≻=o#3n+tB*!-ty@nb4L$OI6}nCk`L47pSs5 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

_&bUs%id;H-KM$d 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 z%0AnN8A8Q@VNGRIC3TGE&QUOywrI|+=VeeB68bt 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%0DXw^)MwMbFkok~ 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
`{e4CB%{Z<xTX%c?bA2wO)_zj0i6oA9Qm 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

KtP#&$9Gx-9qX1{4`%-}` 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Ð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�M|^yU3@b$i6BI9mwrV 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 literal 966195 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