Skip to content

Commit a6f58d0

Browse files
author
Neon Splash Agent
committed
Fix: Replace broken regex patch with direct file overwrite for shared_http_client
1 parent 00b2c2e commit a6f58d0

File tree

1 file changed

+58
-48
lines changed

1 file changed

+58
-48
lines changed

.github/workflows/build.yml

Lines changed: 58 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -65,54 +65,64 @@ jobs:
6565
next
6666
}1' crates/config/src/loader.rs > tmp.rs && mv tmp.rs crates/config/src/loader.rs
6767
68-
# ── Patch 2: Fix shared_http_client to load Termux CA certs ──
69-
cat > /tmp/http_client_patch.rs << 'RUSTPATCH'
70-
/// Shared HTTP client for LLM providers.
71-
///
72-
/// All providers that don't need custom redirect/proxy settings should
73-
/// reuse this client to share connection pools, DNS cache, and TLS sessions.
74-
///
75-
/// On Termux/Android we:
76-
/// 1. Force IPv4 to avoid broken IPv6 routing on mobile networks
77-
/// 2. Explicitly load Termux CA certs since standard paths don't exist
78-
pub fn shared_http_client() -> &'static reqwest::Client {
79-
static CLIENT: std::sync::LazyLock<reqwest::Client> =
80-
std::sync::LazyLock::new(|| {
81-
let mut builder = reqwest::ClientBuilder::new()
82-
// Force IPv4: Android/Termux often has broken IPv6 routing
83-
// which causes 5-second TCP timeouts on Cloudflare-backed domains
84-
.local_address(std::net::IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED))
85-
.connect_timeout(std::time::Duration::from_secs(15));
86-
87-
// Try to load PEM certs from SSL_CERT_FILE or common Termux path.
88-
let cert_path = std::env::var("SSL_CERT_FILE")
89-
.ok()
90-
.unwrap_or_else(|| "/data/data/com.termux/files/usr/etc/tls/cert.pem".into());
91-
92-
if let Ok(pem_data) = std::fs::read(&cert_path) {
93-
for cert_result in reqwest::tls::Certificate::from_pem_bundle(&pem_data) {
94-
builder = builder.add_root_certificate(cert_result);
95-
}
96-
}
97-
98-
builder.build().unwrap_or_else(|_| reqwest::Client::new())
99-
});
100-
&CLIENT
101-
}
102-
RUSTPATCH
103-
104-
# Use Python to do a reliable multi-line replacement
105-
python3 << 'PYEOF'
106-
import re, pathlib
107-
p = pathlib.Path("crates/agents/src/lib.rs")
108-
src = p.read_text()
109-
# Match the entire shared_http_client function
110-
pattern = r'(?s)/// Shared HTTP client.*?pub fn shared_http_client\(\)[^}]*\{[^}]*\{[^}]*\}[^}]*\}'
111-
replacement = open("/tmp/http_client_patch.rs").read().strip()
112-
new_src = re.sub(pattern, replacement, src)
113-
p.write_text(new_src)
114-
print("Patched shared_http_client in lib.rs")
115-
PYEOF
68+
# ── Patch 2: Overwrite shared_http_client with IPv4-forced, cert-loading version ──
69+
cat > crates/agents/src/lib.rs << 'RUSTEOF'
70+
//! LLM agent runtime: model selection, prompt building, tool execution, streaming.
71+
72+
// FFI wrappers for llama-cpp-2 require unsafe Send/Sync impls when local-llm feature is enabled.
73+
#![cfg_attr(feature = "local-llm", allow(unsafe_code))]
74+
75+
pub mod auth_profiles;
76+
77+
/// Shared HTTP client for LLM providers.
78+
///
79+
/// All providers that don't need custom redirect/proxy settings should
80+
/// reuse this client to share connection pools, DNS cache, and TLS sessions.
81+
///
82+
/// On Termux/Android we:
83+
/// 1. Force IPv4 to avoid broken IPv6 routing on mobile networks
84+
/// 2. Explicitly load Termux CA certs since standard paths don't exist
85+
pub fn shared_http_client() -> &'static reqwest::Client {
86+
static CLIENT: std::sync::LazyLock<reqwest::Client> =
87+
std::sync::LazyLock::new(|| {
88+
let mut builder = reqwest::ClientBuilder::new()
89+
// Force IPv4: Android/Termux often has broken IPv6 routing
90+
// which causes 5-second TCP timeouts on Cloudflare-backed domains
91+
.local_address(std::net::IpAddr::V4(std::net::Ipv4Addr::UNSPECIFIED))
92+
.connect_timeout(std::time::Duration::from_secs(15));
93+
94+
// Try to load PEM certs from SSL_CERT_FILE or common Termux path.
95+
let cert_path = std::env::var("SSL_CERT_FILE")
96+
.ok()
97+
.unwrap_or_else(|| "/data/data/com.termux/files/usr/etc/tls/cert.pem".into());
98+
99+
if let Ok(pem_data) = std::fs::read(&cert_path) {
100+
for cert_result in reqwest::tls::Certificate::from_pem_bundle(&pem_data) {
101+
builder = builder.add_root_certificate(cert_result);
102+
}
103+
}
104+
105+
builder.build().unwrap_or_else(|_| reqwest::Client::new())
106+
});
107+
&CLIENT
108+
}
109+
pub mod memory_writer;
110+
pub mod model;
111+
pub mod multimodal;
112+
pub mod prompt;
113+
pub mod providers;
114+
pub mod runner;
115+
pub use {
116+
model::{ChatMessage, ContentPart, UserContent},
117+
runner::AgentRunError,
118+
};
119+
pub mod provider_chain;
120+
pub mod silent_turn;
121+
pub mod skills;
122+
pub mod tool_registry;
123+
RUSTEOF
124+
echo "Patched lib.rs with IPv4-forced shared_http_client"
125+
cat crates/agents/src/lib.rs | head -20
116126

117127
- name: Install cross
118128
uses: taiki-e/install-action@cross

0 commit comments

Comments
 (0)