Repository navigation
Conversation
asto18089
left a comment
There was a problem hiding this comment.
First formal review — #130 fix(tui): widen local-endpoint SSE open timeout to 180s
Thanks for the PR and for the unusually well-documented reasoning (field data, per-class budget, and an env escape hatch preserved for both classes). Reviewed file by file against pinvou3-clean (fe90f72). No blockers found — this is a COMMENT review with minor items.
Per-file findings
crates/tui/Cargo.toml + Cargo.lock — url = "2"
- OK / necessary.
url 2.5.8is already inCargo.locktransitively (viareqwest), so this adds no new build nodes. Correct tool for the job: hand-parsing IPv6 bracket hosts is error-prone. Spec"2"resolves to the locked 2.5.8 and matches the neighboring direct-spec style (urlencoding = "2.1",regex = "1.11"). There is noworkspace.dependenciesentry forurl, so a direct spec is consistent with convention.
crates/tui/src/client/stream_entry.rs — stream_open_timeout_for
- Env override semantics are consistent with the existing path: presence check → delegate to
stream_open_timeout()→ same parse + clamp (5..=300, garbage falls back to 45s). The escape hatch still exceeds the local budget (up to 300s), so it works in both directions. Correct. - nit: with env set to a invalid value (e.g.
abc), a local endpoint silently drops from 180s to 45s (presence-check wins, parse falls back to default). Edge case, conservative direction — fine to leave.
crates/tui/src/client/stream_entry.rs — endpoint_is_local
- IPv4: loopback / RFC1918 / link-local via std predicates — correct.
- IPv6:
::1+ ULAfc00::/7— correct as far as it goes. - DNS names: only
localhost/*.localhostcount; a hostname that resolves to a private IP is deliberately not local (documented, no DNS on this path). This is the right conservative default (a cloud gateway behind a resolvable name would be misclassified the other way), but note it means LAN engines reachable only by hostname get 45s — only raw private IPs benefit. - Conservative-direction gaps, each falls back to today's 45s (no regression), listed so the author can decide whether to widen: (1) IPv4-mapped IPv6 (
[::ffff:127.0.0.1]) isIpv6and not loopback → remote; (2) IPv6 link-localfe80::/10→ remote (v4 link-local is covered, v6 is not); (3) CGNAT100.64.0.0/10— i.e. Tailscale-style endpoints, a very common way to reach a home GPU box, → remote; (4)0.0.0.0unspecified → remote. Givenvalidate_base_url_securityexplicitly invites "llama.cpp on a private IP" over HTTP with the insecure-http env, item (3) is the one I'd most consider following up on (non-blocking).
crates/tui/src/client/{anthropic,chat,responses}.rs — wiring
- Complete. Verified by grep on base: exactly three
stream_open_timeout()call sites exist (chat.rs:1346, anthropic.rs:354, responses.rs:269) — all three rewired with the identical comment; the only other match is doc text in client.rs:3028. The H1-fallback retry reuses the sameStreamOpenRequest, so the widened budget carries into the retry. Per-chunk idle (900s) unchanged and already ≥ the local contract, as the commit message states. - nit: classification reads
self.base_urlwhile the anthropic open goes throughmessages_transport_url; in production the transport URL derives frombase_url(the override fields are test-only), so this is fine today.
Tests
- Not flaky: no sleeps; 180s is a constant comparison, not a timing assertion.
ENV_LOCKcorrectly serializes the two env-touching tests, and no pre-existing test in this module touches the env, so no cross-test race.- MINOR (hermeticity):
local_endpoints_get_the_wider_open_budgetcallsstream_open_timeout_for, which reads ambient env. On a machine whereCODEWHALE_STREAM_OPEN_TIMEOUT_SECSis exported, the== LOCAL_STREAM_OPEN_TIMEOUTassertions fail. Please clear the var under the lock at test start (or assert onendpoint_is_localonly for the budget pair). - nit: in
env_override_wins_over_the_local_budget, if anything panics betweenset_varandremove_var, the var leaks into the process for other tests. A drop-guard (orcatch_unwind) would make cleanup panic-safe.
Process notes
- DCO: Signed-off-by matches author/committer (
l28756 <li.jiawen@h3c.com>) — DCO satisfied. The git namel28756vs GitHub accountsky11023mismatch is noted; not a blocker, but aligning them avoids future verification confusion. - Behind by 2 (
fe90f72f#114,f1eb10ef#125): zero file overlap (engine/skills/docs vsclient/*, no Cargo manifests), GitHub reports MERGEABLE. Per CONTRIBUTING, no rebase requested — the Merge Queue will gate against latestmain. - CI: no workflow runs exist for head
cb577ba5(nothing in the runs list, no check runs, combined status pending with zero statuses — the first-contribution approval gate). Nothing to approve via the API from this side; maintainers, please approve/trigger the workflow run so checks actually execute.
Conclusion
No BLOCKER, no MAJOR. MINOR items: test hermeticity vs ambient env; the enumerated conservative-direction classification gaps (CGNAT/Tailscale the most notable); optional panic-safe env cleanup. Comfortable to merge after a maintainer eyes the MINORs; comments-only, changes not requested.
|
感谢首轮正式评审的细致核对(逐文件、突变与 CI 归因都做了)。三个 MINOR 已全部处置(ca079796c):
验证:三测试精确名单 3/3 绿; DCO 备注:git 身份 |
|
Thanks @sky11023 for taking the time to contribute. This repository is observing a maintainer-managed PR intake gate in dry-run mode, so this pull request is staying open. This note helps maintainers prepare the allowlist before any enforcement is considered. Please read |
ca07979 to
fa79c99
Compare
Cloud-budget 45s header wait exists to fail fast on dead cloud hosts; a local model (loopback/private) legitimately spends minutes before response headers when it prefills a very long prompt cold — pinvou3 field data (TensorFold dual-GPU, 2026-10-29): ~25K-token agent prompt sits silent ~30s at 854 tok/s first-pass. endpoint_is_local() routes loopback/localhost/RFC1918/link-local/ULA base URLs to a 180s budget across all three streaming adapters; explicit env override still wins for both classes. Per-chunk idle stays 900s (already >= the 120s local contract). Signed-off-by: l28756 <li.jiawen@h3c.com>
Signed-off-by: l28756 <li.jiawen@h3c.com>
fa79c99 to
0f792f7
Compare
问题
品悟 Agent(约 25K token 系统提示词)冷 prefill 时,本地模型在首字节前静默约 30 秒(TensorFold 双卡 854 tok/s 实测,2026-10-29 现场)。TUI 三个流式适配器(chat / responses / anthropic)共用 45 秒的流打开(响应头)超时——这个预算是为「云主机死掉要快速失败」设计的;对本地端点,长提示词冷启动合法地超过 45s,用户侧表现为「回答被中断,当前请求超时请重试」。dspark 等卡同场景可复现,非单卡特有。
修复
crates/tui/src/client/stream_entry.rs:LOCAL_STREAM_OPEN_TIMEOUT = 180s与stream_open_timeout_for(base_url):endpoint_is_local()(loopback / localhost / RFC1918 / link-local / ULA)命中的 base URL 走 180s 打开预算,其余维持 45s。stream_open_timeout_for。验证
cargo test -p codewhale-tui --lib(精确选择)3/3 通过:local_endpoints_get_the_wider_open_budget、env_override_wins_over_the_local_budget、stream_open_timeout_defaults_and_clamps_env_values。cb577ba55)已被 pinvou3 双机从机集成分支以 gitlink 引用并完成过整包构建装机验证(integrated.20261029.2,.10 设备 worker CLI 实测 exit 0)。请按原样合并,勿 rebase 改写哈希。DCO:Signed-off-by 已带。