Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
- Secret redaction regex-based pattern matching replaces whitespace tokenizer, detecting secrets in URLs, JSON, and quoted strings
- Added `hf_`, `npm_`, `dckr_pat_` to secret redaction prefixes
- A2A client stream errors truncate upstream body to 256 bytes
- Add `default_client()` HTTP helper with standard timeouts and user-agent in zeph-core and zeph-llm (#666)
- Replace 5 production `Client::new()` calls with `default_client()` for consistent HTTP config (#667)

### Fixed
- False positive: "sudoku" no longer matched by "sudo" blocked pattern (word-boundary matching)
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/zeph-channels/src/discord/rest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct EditMessage<'a> {
impl RestClient {
#[must_use]
pub fn new(token: String) -> Self {
let client = reqwest::Client::new();
let client = zeph_core::http::default_client();
Self { client, token }
}

Expand Down
2 changes: 1 addition & 1 deletion crates/zeph-channels/src/slack/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl SlackApi {
#[must_use]
pub fn new(token: String) -> Self {
Self {
client: reqwest::Client::new(),
client: zeph_core::http::default_client(),
token,
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/zeph-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ metal = ["zeph-llm/metal"]
[dependencies]
age.workspace = true
anyhow.workspace = true
reqwest = { workspace = true, features = ["rustls"] }
futures.workspace = true
notify.workspace = true
notify-debouncer-mini.workspace = true
Expand Down
32 changes: 32 additions & 0 deletions crates/zeph-core/src/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//! Shared HTTP client construction for consistent timeout and TLS configuration.

use std::time::Duration;

/// Create a shared HTTP client with standard Zeph configuration.
///
/// Config: 30s connect timeout, 60s request timeout, rustls TLS,
/// `zeph/{version}` user-agent, redirect limit 10.
///
/// # Panics
///
/// Panics if the TLS backend cannot be initialized (should never happen with rustls).
#[must_use]
pub fn default_client() -> reqwest::Client {
reqwest::Client::builder()
.connect_timeout(Duration::from_secs(30))
.timeout(Duration::from_secs(60))
.user_agent(concat!("zeph/", env!("CARGO_PKG_VERSION")))
.redirect(reqwest::redirect::Policy::limited(10))
.build()
.expect("default HTTP client construction must not fail")
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn client_builds_successfully() {
let _client = default_client();
}
}
1 change: 1 addition & 0 deletions crates/zeph-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub mod redact;
pub mod vault;

pub mod diff;
pub mod http;

pub use agent::Agent;
pub use agent::error::AgentError;
Expand Down
2 changes: 1 addition & 1 deletion crates/zeph-llm/src/claude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl ClaudeProvider {
#[must_use]
pub fn new(api_key: String, model: String, max_tokens: u32) -> Self {
Self {
client: reqwest::Client::new(),
client: crate::http::default_client(),
api_key,
model,
max_tokens,
Expand Down
18 changes: 18 additions & 0 deletions crates/zeph-llm/src/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! Shared HTTP client construction for consistent timeout and TLS configuration.

use std::time::Duration;

/// Create a shared HTTP client with standard Zeph configuration.
///
/// Config: 30s connect timeout, 60s request timeout, rustls TLS,
/// `zeph/{version}` user-agent, redirect limit 10.
#[must_use]
pub fn default_client() -> reqwest::Client {
reqwest::Client::builder()
.connect_timeout(Duration::from_secs(30))
.timeout(Duration::from_secs(60))
.user_agent(concat!("zeph/", env!("CARGO_PKG_VERSION")))
.redirect(reqwest::redirect::Policy::limited(10))
.build()
.expect("default HTTP client construction must not fail")
}
1 change: 1 addition & 0 deletions crates/zeph-llm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod claude;
pub mod compatible;
pub mod error;
pub mod extractor;
pub(crate) mod http;
#[cfg(feature = "mock")]
pub mod mock;
pub mod ollama;
Expand Down
2 changes: 1 addition & 1 deletion crates/zeph-llm/src/openai.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl OpenAiProvider {
base_url.pop();
}
Self {
client: reqwest::Client::new(),
client: crate::http::default_client(),
api_key,
base_url,
model,
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ async fn main() -> anyhow::Result<()> {
.as_ref()
.map_or(String::new(), |k| k.expose().to_string());
let whisper = zeph_llm::whisper::WhisperProvider::new(
reqwest::Client::new(),
zeph_core::http::default_client(),
api_key,
base_url,
&stt_cfg.model,
Expand Down
Loading