Skip to content

fix(app-server): bound chat-completions proxy requests in time - #6855

Merged
Hmbown merged 1 commit into
codewhale-hq:mainfrom
asto18089:upstream/app-server-proxy-timeouts
Oct 5, 2026
Merged

Hmbown merged 1 commit into
codewhale-hq:mainfrom
asto18089:upstream/app-server-proxy-timeouts

Conversation

@asto18089

Copy link
Copy Markdown
Contributor

Summary

The /v1/chat/completions handler built its upstream client from the shared platform builder, which sets no timeouts. The handler rejects streaming and reads the full upstream body, so a provider that accepts the connection and then stalls — or trickles the body — wedged the handler, and with it the caller's connection, indefinitely.

Bound the forward with a 10s connect budget (matching the connect bound used by the TUI client's non-streaming requests) and a 1800s total budget (matching the TUI client's non-streaming envelope for the same request class). A unit test pins both values and their ordering; reqwest exposes no accessor for a built client's budgets, so exercising the stall path behaviorally would need a deliberately wedged upstream and a multi-second to half-hour wait, which the test comment states.

Known follow-up: the runtime-bridge client in crates/app-server/src/lib.rs remains unbounded; that is a separate surface.

Testing

  • cargo test -p codewhale-app-server --lib upstream_deadlines_are_bounded_and_ordered
  • cargo clippy -p codewhale-app-server --all-targets --all-features --locked

Adapted from the Pinvou fork's timeout audit (Pinvou/CodeWhale d349f2537, the chat-completions proxy slice).

Checklist

  • Updated docs or comments as needed
  • Added or updated tests where relevant
  • No CHANGELOG.md changes

@asto18089
asto18089 requested a review from Hmbown as a code owner October 5, 2026 11:51
@github-actions github-actions Bot added the contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm label Oct 5, 2026
The `/v1/chat/completions` handler built its upstream client from the
shared platform builder, which sets no timeouts. The handler rejects
streaming and reads the full upstream body, so a provider that accepts
the connection and then stalls — or trickles the body — wedged the
handler, and with it the caller's connection, indefinitely.

Bound the forward with a 10s connect budget (matching the connect bound
used by the TUI client's vision requests and key verification) and a
1800s total budget (matching the TUI client's non-streaming envelope
for the same request class). A unit test pins both values and their
ordering; reqwest exposes no accessor for a built client's budgets, so
exercising the stall path behaviorally would need a deliberately wedged
upstream and a multi-second to half-hour wait, which the test comment
states.

Known follow-up: the runtime-bridge client in `crates/app-server/src/lib.rs`
remains unbounded; that is a separate surface.

Signed-off-by: asto <asto18089@126.com>
@asto18089
asto18089 force-pushed the upstream/app-server-proxy-timeouts branch from a903e7b to f180a76 Compare October 5, 2026 14:18
@Hmbown Hmbown modified the milestones: v0.10.2, v0.10.1 Oct 5, 2026
@Hmbown
Hmbown merged commit d57ec08 into codewhale-hq:main Oct 5, 2026
Hmbown pushed a commit that referenced this pull request Oct 5, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution-gate Author not yet in .github/APPROVED_CONTRIBUTORS; a maintainer grants access with /lgtm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants