refactor(vendor-channels): 收敛跨供应商兼容处理至源→目标通道并引入内容感知源推断#196
Merged
Conversation
- 删除 server/request_normalizer.py 入口通用规范化层,彻底移除「通用 Phase 1 清洗」概念; - 将 srvtoolu_* ID 重写、server_tool_use_delta 私有块剥离迁入 prepare_zhipu_to_anthropic 与 prepare_zhipu_to_copilot 通道,消除跨供应商语义与协议层耦合; - 新增 infer_source_vendor_from_body 内容感知源推断(扫描 srvtoolu_*/server_tool_use_delta/misplaced tool_result),解决首次请求无会话状态时无法定位源供应商的兜底场景; - _RouteExecutor._determine_source_vendor 扩充为三级优先级(failed_tier → session_state → body inference),两处调用点透传 body; - /v1/messages 入口移除 normalize_anthropic_request 调用,body 原样透传至 router 由通道按需清洗; - /v1/messages/count_tokens 端点移除无条件 strip_thinking_blocks 过度防御,改为基于推断源触发通道清洗,语义与 /v1/messages 对齐; 🤖 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<threefish.ai@gmail.com>
- 删除 tests/test_request_normalizer.py,所有用例迁移至通道与执行器测试; - tests/test_vendor_channels.py 新增 TestRemoveVendorBlocks、TestRewriteSrvtooluIds、TestInferSourceVendorFromBody、TestEnforceAnthropicToolPairing 以及 zhipu→anthropic/copilot 全链路清洗集成用例; - tests/test_router_executor.py 新增 Priority 3 body 推断场景(8 个用例),覆盖优先级组合、可选 body 参数、无注册通道的短路; - tests/test_app_routes.py 将入口规范化相关断言调整为「body 原样透传」,新增日志静默验证; 🤖 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<threefish.ai@gmail.com>
- CHANGELOG Unreleased 追加 refactor(vendor-channels) 与 refactor(count-tokens) 条目; - docs/framework.md 删除 request_normalizer 架构分层节点、请求流程规范化子图、文件清单行; - docs/arch/testing.md 删除 test_request_normalizer.py 行,新增 test_vendor_channels.py 行入 2.4 convert 章节; 🤖 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<threefish.ai@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更摘要
本次重构彻底贯彻「源→目标绑定」通道模型,移除所有残留的通用(非绑定)跨供应商兼容性处理,并以内容感知源推断解决首次请求无会话状态场景下无法定位源供应商的兜底问题。
主要改动
server/request_normalizer.py入口通用规范化层 — 彻底移除「通用 Phase 1 清洗」概念,消除跨供应商语义与协议层耦合。srvtoolu_*ID 重写 →prepare_zhipu_to_anthropic/prepare_zhipu_to_copilotserver_tool_use_delta私有块剥离 → 同上infer_source_vendor_from_body内容感知源推断(位于convert/vendor_channels.py):扫描请求体中srvtoolu_*ID、server_tool_use_delta块类型、assistant 消息内的tool_result块,只读识别源供应商。_RouteExecutor._determine_source_vendor扩充为三级优先级:failed_tier_name(请求内故障转移)session_record.provider_state(跨请求会话历史)body内容推断(兜底首次请求)/v1/messages入口 body 原样透传至 router,由 executor 通过通道按需清洗。/v1/messages/count_tokens端点移除无条件strip_thinking_blocks过度防御,改为基于推断源触发通道清洗,语义与/v1/messages对齐。设计权衡
request_normalizer.py后,首次请求无法通过会话状态定位源供应商;内容感知推断是无副作用的只读扫描,开销可忽略,且精准对应实际生产者(zhipu)。streaming/anthropic_compat.py的_TOOL_USE_BLOCK_TYPES:该过滤器属于 OpenAI→Anthropic 流式协议适配器的协议层白名单,与「供应商 A→供应商 B」应用层语义映射属不同抽象层,保留符合正交分解原则。count_tokens不再无条件剥离 thinking:合规的 Anthropic 客户端请求不携带跨供应商 signature,无需剥离;携带 zhipu 产物时推断源为 zhipu → 走通道(含 thinking 剥离)。消除特殊逻辑。测试说明
测试迁移与扩充
tests/test_request_normalizer.py(811 行)tests/test_vendor_channels.py新增 6 个测试类:TestRemoveVendorBlocks(4 用例)TestRewriteSrvtooluIds(6 用例)TestInferSourceVendorFromBody(8 用例,含只读/非变更验证)TestEnforceAnthropicToolPairing(12 用例,从原规范化测试迁入)TestZhipuToAnthropicChannelFullCleanup(2 用例,zhipu 产物组合场景)TestZhipuToCopilotChannelFullCleanup(1 用例)tests/test_router_executor.py新增 8 个 Priority 3 body 推断用例,覆盖优先级组合、可选 body 参数、无注册通道短路等tests/test_app_routes.py将入口规范化相关断言调整为「body 原样透传」,新增日志静默验证回归验证
全量 1268 条测试用例通过,无回归。
核心链路验证
srvtoolu_*)→ 目标 anthropic → Priority 3 推断触发通道清洗None→ 无通道调用count_tokens纯净 body → 直通上游(不再无条件剥离 thinking)count_tokens含 zhipu 产物 → 触发 zhipu→target 通道清洗影响范围
/v1/messages与/v1/messages/count_tokens的外部契约未变,客户端无感知count_tokens对纯净 Anthropic 请求不再剥离 thinking(此前为过度防御,合规客户端无影响)src/coding/proxy/server/request_normalizer.py、tests/test_request_normalizer.py(引用已全部迁移或移除)