From e62e4ad9532f53708a65a3e61a476b4e4569ddd3 Mon Sep 17 00:00:00 2001 From: celia-oai Date: Mon, 17 Aug 2026 16:15:42 -0700 Subject: [PATCH] Remove direct reqwest dependency from codex-otel --- codex-rs/Cargo.lock | 1 - codex-rs/deny.toml | 1 - codex-rs/otel/Cargo.toml | 1 - codex-rs/otel/src/events/session_telemetry.rs | 4 +- codex-rs/otel/src/otlp.rs | 59 ++++--------------- codex-rs/otel/src/provider.rs | 2 + 6 files changed, 16 insertions(+), 52 deletions(-) diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index a0caa62b43..e9403e3cca 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -3856,7 +3856,6 @@ dependencies = [ "opentelemetry_sdk", "os_info", "pretty_assertions", - "reqwest 0.12.28", "seccompiler", "serde", "serde_json", diff --git a/codex-rs/deny.toml b/codex-rs/deny.toml index d6ccfcc642..71e5ebd4de 100644 --- a/codex-rs/deny.toml +++ b/codex-rs/deny.toml @@ -245,7 +245,6 @@ deny = [ "codex-responses-api-proxy", # Temporary migration exceptions. "codex-app-server", - "codex-otel", # Third-party crates that own their reqwest integration. These are not part of the # first-party migration count above. "oauth2", diff --git a/codex-rs/otel/Cargo.toml b/codex-rs/otel/Cargo.toml index 40b3e70cbe..fbc0e4b4ee 100644 --- a/codex-rs/otel/Cargo.toml +++ b/codex-rs/otel/Cargo.toml @@ -47,7 +47,6 @@ opentelemetry_sdk = { workspace = true, features = [ ] } http = { workspace = true } os_info = { workspace = true } -reqwest = { workspace = true, features = ["blocking", "rustls-tls"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } strum_macros = { workspace = true } diff --git a/codex-rs/otel/src/events/session_telemetry.rs b/codex-rs/otel/src/events/session_telemetry.rs index 2ffa061308..925780042f 100644 --- a/codex-rs/otel/src/events/session_telemetry.rs +++ b/codex-rs/otel/src/events/session_telemetry.rs @@ -35,6 +35,8 @@ use crate::sanitize_metric_tag_value; use codex_api::AgentIdentityTelemetry; use codex_api::ApiError; use codex_api::ResponseEvent; +use codex_http_client::HttpError as Error; +use codex_http_client::HttpResponse as Response; use codex_protocol::ThreadId; use codex_protocol::config_types::ReasoningSummary; use codex_protocol::models::ResponseItem; @@ -48,8 +50,6 @@ use codex_protocol::user_input::UserInput; use eventsource_stream::Event as StreamEvent; use eventsource_stream::EventStreamError as StreamError; use opentelemetry_sdk::metrics::data::ResourceMetrics; -use reqwest::Error; -use reqwest::Response; use std::borrow::Cow; use std::future::Future; use std::time::Duration; diff --git a/codex-rs/otel/src/otlp.rs b/codex-rs/otel/src/otlp.rs index 527a0975e3..67d31c8369 100644 --- a/codex-rs/otel/src/otlp.rs +++ b/codex-rs/otel/src/otlp.rs @@ -3,17 +3,15 @@ use codex_http_client::HttpClientFactory; use codex_http_client::TelemetryClientTlsConfig; use codex_http_client::TelemetryHttpClient; use codex_utils_absolute_path::AbsolutePathBuf; +use http::HeaderMap; +use http::HeaderName; +use http::HeaderValue; use http::Uri; use opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT; use opentelemetry_otlp::OTEL_EXPORTER_OTLP_TIMEOUT_DEFAULT; use opentelemetry_otlp::tonic_types::transport::Certificate as TonicCertificate; use opentelemetry_otlp::tonic_types::transport::ClientTlsConfig; use opentelemetry_otlp::tonic_types::transport::Identity as TonicIdentity; -use reqwest::Certificate as ReqwestCertificate; -use reqwest::Identity as ReqwestIdentity; -use reqwest::header::HeaderMap; -use reqwest::header::HeaderName; -use reqwest::header::HeaderValue; use std::env; use std::error::Error; use std::fs; @@ -114,50 +112,17 @@ pub(crate) fn current_tokio_runtime_is_multi_thread() -> bool { } pub(crate) fn build_async_http_client( + http_client_factory: &HttpClientFactory, + endpoint: &str, tls: Option<&OtelTlsConfig>, timeout_var: &str, -) -> Result> { - let mut builder = reqwest::Client::builder().timeout(resolve_otlp_timeout(timeout_var)); - - if let Some(tls) = tls { - if let Some(path) = tls.ca_certificate.as_ref() { - let (pem, location) = read_bytes(path)?; - let certificate = ReqwestCertificate::from_pem(pem.as_slice()).map_err(|error| { - config_error(format!( - "failed to parse certificate {}: {error}", - location.display() - )) - })?; - builder = builder - .tls_built_in_root_certs(false) - .add_root_certificate(certificate); - } - - match (&tls.client_certificate, &tls.client_private_key) { - (Some(cert_path), Some(key_path)) => { - let (mut cert_pem, cert_location) = read_bytes(cert_path)?; - let (key_pem, key_location) = read_bytes(key_path)?; - cert_pem.extend_from_slice(key_pem.as_slice()); - let identity = ReqwestIdentity::from_pem(cert_pem.as_slice()).map_err(|error| { - config_error(format!( - "failed to parse client identity using {} and {}: {error}", - cert_location.display(), - key_location.display() - )) - })?; - builder = builder.identity(identity).https_only(true); - } - (Some(_), None) | (None, Some(_)) => { - return Err(config_error( - "client_certificate and client_private_key must both be provided for mTLS", - )); - } - (None, None) => {} - } - } - - builder - .build() +) -> Result, Box> { + http_client_factory + .build_async_telemetry_client( + endpoint, + resolve_otlp_timeout(timeout_var), + &telemetry_tls_config(tls), + ) .map_err(|error| Box::new(error) as Box) } diff --git a/codex-rs/otel/src/provider.rs b/codex-rs/otel/src/provider.rs index 59d4902ed8..420546ba08 100644 --- a/codex-rs/otel/src/provider.rs +++ b/codex-rs/otel/src/provider.rs @@ -555,6 +555,8 @@ fn build_tracer_provider( }; let client = crate::otlp::build_async_http_client( + http_client_factory, + &endpoint, tls.as_ref(), OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, )?;