feat(http): add timeouts and identifying user-agent to all provider HTTP calls#27
Conversation
CI failure is pre-existing on
|
97166ea to
2640f09
Compare
enowdev
left a comment
There was a problem hiding this comment.
I reviewed the feature and the main blocker now is merge state, not the timeout/user-agent idea itself. This PR conflicts with newer provider-routing changes already on main, especially in src-tauri/src/agents/runner.rs, src-tauri/src/services/chat_service.rs, and src-tauri/src/services/model_service.rs. When rebasing, please keep the newer Anthropics/gateway endpoint resolution from main and re-apply only the shared HTTP client changes (timeouts + User-Agent).
…TTP calls Every outbound HTTP client (chat, models, titles, tools, agent runner) was being created with reqwest::Client::new() — no timeouts of any kind. A stalled provider, dead TCP connection, or silently rate-limited upstream would freeze the agent loop indefinitely with no error path. Adds a small services::http_client module with two shared builders: - streaming_client(): used for SSE chat completions - 10s connect timeout - 60s per-read timeout (catches dead streams between chunks) - 600s total ceiling (long completions still finish) - request_client(): used for non-streaming calls (model lists, titles) - 10s connect timeout - 120s total timeout Both clients carry a 'enowX-Coder/<version>' User-Agent so providers, proxies, and the user's own firewall can attribute traffic correctly (several providers reject empty UAs). Migrates all 9 call sites: - services/chat_service.rs (5 sites) - services/model_service.rs (2 sites) - agents/runner.rs (2 sites) - tools/executor.rs (1 site, web_search) No behavior change for healthy paths — only adds bounded failure on unhealthy ones.
2640f09 to
6baea78
Compare
Summary
Every outbound HTTP client in the backend (chat, models, titles, tool runner, agent loop) was being created with
reqwest::Client::new()— no timeouts of any kind. A stalled provider, dead TCP connection, or silently rate-limited upstream freezes the agent loop indefinitely with no error path and no recovery.This PR adds a small shared
services::http_clientmodule with two builders that all 9 call sites now use.What was wrong
reqwest::Client::new()produces a client with no connect, read, or total timeout. In production this means:What this PR does
Adds
src-tauri/src/services/http_client.rswith two shared constructors:streaming_client()— SSE chat completionsrequest_client()— non-streaming (model lists, title generation, single-shot completions)Both clients carry a
enowX-Coder/<version>User-Agent (sourced fromCARGO_PKG_VERSION) so providers, proxies, and the user's own firewall can attribute traffic correctly.Migrates all 9 call sites:
services/chat_service.rs— 5 sitesservices/model_service.rs— 2 sitesagents/runner.rs— 2 sitestools/executor.rs— 1 site (web_search)Behavior change
AppErrorand the UI can recover.Test plan
cargo checkpasses locally on all touched files (no schema errors)Client::new()call sites migrated —rgreturns 0 hits insrc/after the change-D warnings/ cargo test) covers the rest