@@ -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