Repository navigation
Conversation
Signed-off-by: zhuowp <9426526+zhuowp@users.noreply.github.com>
Signed-off-by: zhuowp <9426526+zhuowp@users.noreply.github.com>
asto18089
left a comment
There was a problem hiding this comment.
全新 11 分片复审(rebase 到 6f7a3a7 后重放,本地头 09c7bc690)
结论:REQUEST_CHANGES — 接缝本身设计得当、测试经突变证实真实承重、零夹带,但有 3 个 MAJOR 需先处理(其一是落地即破坏下游宿主编译)。
复审设置与证据
- 原 PR 头 16e8a8d(2 提交)基于旧底座 11cba40;
pinvou3-clean已前移 5 提交至 6f7a3a7(含 #150/#142 对client.rs的改动,均在 PR hunk 之外)。评审 worktree 中将两提交 cherry-pick 重放到新底座:自动合并零冲突,逐 hunk 比对确认与原 PR 字节等价(仅 #142 的 +6 行导致锚点平移,hunk 体逐字节一致)。本地 rebase 仅用于评审;未推送、未改写作者分支;PR 当前对最新底座 MERGEABLE。 - 上游移植声明已核实:codewhale-hq/Codewhale codewhale-hq#7251 存在(closed,同作者同特性)。
- 本地门(09c7bc690):
cargo fmt --all -- --check通过;cargo check -p codewhale-tui --lib --tests干净;transport_policy滤镜 2 passed; 0 failed;vision::tools19 passed; 0 failed;build_http_client1 passed; 0 failed。CI 在旧头全绿(早于底座前移,头更新后自动重跑)。 - 突变验证(实测,非预测):
- 基线:
2 passed; 0 failed - M-突变1 删除 client.rs:1366 策略应用 → 0 passed; 2 failed
- M-突变2 删除 config.rs:7361 视觉继承 → 1 passed; 1 failed(继承恰由测试1独占钉住)
- M-突变3 删除 vision/tools.rs:67 独立客户端策略 → 0 passed; 2 failed
- 基线:
- 夹带检查:两提交仅触及声明内 4 文件;提交 2 纯 mod 块 rustfmt 重排(3+/3-);DCO 在位;无 Cargo.lock/CI/无关修改。
值得肯定
- 按本仓 ponytail 判据这是"能用的最小实现":复用
request_idempotency_header的 host-owned 模式(serde-skip + or-merge + 视觉继承),单方法无默认体的 trait 是注入缝的固有形状(boxed closure 反而要为 Debug 手写 newtype,更大)。 - serde 双向封死:
Config/VisionModelConfig均无Serializederive,#[serde(skip)]保证 TOML/JSON 注不进,测试钉住注入拒绝。信任边界审计通过:模型/工具/会话代码不可达该字段。 - 零策略时行为与底座逐行等价;构造期拒绝传播 fail-closed(测试钉
calls == 1,HTTP/1 兄弟客户端不再构建)。
MAJOR
M1 — trait 文档承诺 "every inference HTTP client",但同 crate 内两条带钥推理路径不受策略约束。
config.rs:2964-2965 写明 "applied to every inference HTTP client";但:
crates/tui/src/commands/groups/core/voice.rs:320post_chat_completions:裸tls::reqwest_client()POST 带钥{base_url}/chat/completions,且自己调用acquire_remote_control_inference_participant()——crate 自己的词汇将其归为 inference;crates/tui/src/tui/prompt_suggestion.rs:396-401suggestion_client():进程级OnceLock静态客户端发带钥 chat/completions(静态初始化意味着即使日后接入策略,进程启动后也无法生效)。
(另client.rs:1973-2002verify_provider_api_key的 /models 探针带 provider 鉴权头自建客户端,属边界判断,请一并表态。)
两处在底座就存在、本 PR 未触碰——不是回归;但合同句是本 PR 写下的。修法二选一:(a) 文档收窄到实际交付面("model client 与独立视觉路由构建的每个推理客户端"),并在正文列出仍不受约束的模型侧出口供宿主验收 issue 跟踪;(b) 把两条路径接进策略(小改动;注意 suggestion 的静态初始化时序)。倾向 (a)。
M2 — 配置重载/供应商切换会静默丢掉宿主策略。
runtime_threads.rs:3375 reload_config 最终 *guard = new_config(3435-3437)整体替换;两个入口:POST /v1/config/reload(runtime_api.rs:6978)与 switch_provider(6560)。重载产物 model_http_policy: None,此后新建的所有客户端(client.rs:1366)与视觉路由都不再受约束。仓库已有保留先例:重载会保留 route 身份(reload_config_preserves_profile_selected_named_custom_route,runtime_api/tests.rs:9765)。修法:跨重载保留该字段(建议顺带审视同构的 request_idempotency_header 是否同样被冲掉——那是既有缺口),或至少在字段/trait 文档写明重载交互并挂跟踪项。评 MAJOR 而非 BLOCKER:仓内无生产 setter,与 sibling 缺口同构。
M3 — 落地即破坏 pinvou3 宿主编译,需同批协调。
宿主以路径依赖消费本 crate(pinvou3-app/src-tauri/Cargo.toml:102);VisionModelConfig 仅 derive Debug, Clone, Deserialize(无 Default、非 non_exhaustive),新增必填字段后,宿主 4 处字段完整字面量将编译失败:platform/bridge.rs:1398、1405、1418(生产代码)与 product_runtime/eval_tool_policy.rs:143(测试)。PR 已补齐仓内全部 9 处字面量,说明作者清楚这个破坏类,但宿主侧无法由本 PR 修补。修法:正文注明所需宿主侧一行补丁(model_http_policy: None, ×4)并绑定落地批次,或与宿主侧补丁同批落地。
MINOR
- m1
vision/tools.rs:20,79:Result<reqwest::Client, ()>+.map_err(|_| ())丢掉原因,execute 只回泛化 "Vision HTTP transport unavailable"(旧.expect至少带原因)。字段需Clone,存String即可;模型面消息保持泛化是对的(宿主内部细节不该到模型可见面),但请在构造期记一条宿主侧日志。 - m2
config.rs:2999Config.model_http_policy字段无 doc 注释;siblingrequest_idempotency_header(2988-2998)有 9 行写明 host-only/never-persisted 合同。宿主触摸的面应自带合同。 - m3
merge_config的策略优先级(config.rs:10566)无红测试覆盖(保留单侧的编译变体全绿)。 - m4
VisionModelConfig的 serde-skip 无注入拒绝测试(仅Config侧有,transport_policy_tests.rs:109-112)。 - m5 顺序脚枪未记录:策略在
build_default_headers之后运行,而 reqwestdefault_headers()是整体替换——策略一旦调用它就清掉鉴权头(fixture 演示的正是这种 clobber)。trait 文档应写明"策略最后运行、需有意识保留鉴权头"。 - m6 fleet worker 子进程从盘上 roster 配置重建客户端(fleet/exact.rs:311-323),策略不出宿主进程;文档应限定适用范围。
NIT(不阻塞)
client.rs:1098-1099陈旧名称 "Used bybuild_http_client"(实际消费者已更名build_http_builder_with_auth_mode)。- 测试名
..._denial_fails_primary_and_vision_closed的 "closed" 描述了从未执行的端口拒绝路径(fixture 守卫先于拨号触发,127.0.0.1:9不会被连)。 - 测试1
assert!(result.success)在 Ok 路径恒真(ToolResult::json硬置 true)。 vision/tools.rs构造期 IIFE 与client.rs具名闭包风格不一致。"https://api.openai.com/v1"字面量两处(tools.rs:73 新增 / :185 既有)。
判据对照
- 有用且根因完整:是——宿主确需传输约束接缝;交付面(主/HTTP1/独立视觉)完整且经突变证实;缺口在文档合同句(M1)而非交付本身。
- 优雅:是——最小实现,复用既有 host-knob 模式,未重复造轮。
- 夹带:无——逐提交字节级核验,两提交均干净。
- 无功能/性能 bug:交付路径未发现;M2/M3 属生命周期与协调缺口,非代码错误。
M1-M3 解决后可合并;MINOR 可随后续批次。
做什么
嵌入方需要在现有模型传输 builder 上应用内存策略,同时覆盖主客户端、HTTP/1 回退和独立视觉客户端。增加可选的
ModelHttpPolicy;没有策略时保持原有行为。策略不从配置文件反序列化,并随配置 clone/视觉继承传递,拒绝错误在客户端构造时传播。基于公开维护头
11cba403dc6bd6ca5c4dca55042785b03449ac8e,候选55393015d8a4905d47ca1a81ad41aead8c60962f。通用接口还在最新官方 main 上单独准备了移植,避免把维护分支的历史差异提交上游。上游贡献:codewhale-hq/Codewhale #7251。上游候选与本维护底座候选分别固定版本;不把上游提交当作当前应用已运行依赖。
验证
审核与边界
本候选四文件及主模型、HTTP/1、视觉消费者已通过独立 V3 代码与相称功能证据验收,绑定上述候选。维护分支、固定标签、CI、外审和发布资格分别判断;此次只推送候选分支供审核。
No-Issue: 从 Pinvou/pinvou3#1389 提取的通用传输策略接口;本仓未启用 Issues,应用端完整验收仍由原 issue 跟踪,本底座 PR 不关闭应用 issue。
本批修复复核
提交 16e8a8d,tree a7236fffc33e2b6f465d8c0e2f2c020bba9eb1a8。仅按 rustfmt 将 transport_policy_tests 的 cfg(test)/path/mod 完整三行块排序,模块路径、内容和属性归属不变。cargo fmt --all -- --check 通过;本批未重跑 Rust 功能测试或全工作区 Clippy。PR 已补 No-Issue 说明其来自应用 issue 的通用接口提取,本仓 Issues 未启用;不关闭应用验收 issue,不更新公开维护分支或自动合入。 本批增量通过 v3 五角色独立首审及未参与实现者裁决。新 SHA 的适用 CI、外审及合并资格分别验收。