fix: disable httpx proxy for Photon sidecar localhost connections

All Photon sidecar HTTP requests target 127.0.0.1 — they should
never be routed through a system HTTP proxy. When trust_env=True
(the default), httpx picks up macOS system proxy settings and
routes localhost requests through the proxy. If the proxy returns
a spurious response (e.g. 502), _reap_stale_sidecar() interprets
it as 'port in use by a non-sidecar process' and refuses to start,
yielding: 'pids: unknown, not a Photon sidecar'.

Set trust_env=False on all five httpx.AsyncClient call sites in
the Photon adapter so localhost sidecar communication bypasses
the system proxy entirely.
This commit is contained in:
DI404N 2026-06-17 23:51:40 +08:00 committed by Teknium
parent 9cf2046081
commit 6294703dec

View file

@ -485,7 +485,7 @@ class PhotonAdapter(BasePlatformAdapter):
)
return False
client = httpx.AsyncClient(timeout=30.0)
client = httpx.AsyncClient(timeout=30.0, trust_env=False)
self._http_client = client
# The sidecar holds the gRPC stream for BOTH directions, so it is
@ -981,7 +981,7 @@ class PhotonAdapter(BasePlatformAdapter):
if sys.platform == "win32": # lsof/ps; orphaning is a POSIX-only path
return
try:
async with httpx.AsyncClient(timeout=2.0) as client:
async with httpx.AsyncClient(timeout=2.0, trust_env=False) as client:
await client.post(
f"http://{self._sidecar_bind}:{self._sidecar_port}/healthz",
headers={"X-Hermes-Sidecar-Token": self._sidecar_token},
@ -1107,7 +1107,7 @@ class PhotonAdapter(BasePlatformAdapter):
# Wait for /healthz to come up — give it up to 15s on cold start.
deadline = time.time() + 15.0
last_err: Optional[Exception] = None
async with httpx.AsyncClient(timeout=2.0) as client:
async with httpx.AsyncClient(timeout=2.0, trust_env=False) as client:
while time.time() < deadline:
if self._sidecar_proc.poll() is not None:
raise RuntimeError(
@ -1670,7 +1670,7 @@ class PhotonAdapter(BasePlatformAdapter):
# _http_client directly — it always runs on the gateway's loop.
url = f"http://{self._sidecar_bind}:{self._sidecar_port}{path}"
headers = {"X-Hermes-Sidecar-Token": self._sidecar_token}
async with httpx.AsyncClient(timeout=30.0) as client:
async with httpx.AsyncClient(timeout=30.0, trust_env=False) as client:
resp = await client.post(url, json=body, headers=headers)
if resp.status_code != 200:
raise RuntimeError(
@ -1810,7 +1810,7 @@ async def _standalone_send(
headers = {"X-Hermes-Sidecar-Token": token}
last_message_id: Optional[str] = None
try:
async with httpx.AsyncClient(timeout=30.0) as client:
async with httpx.AsyncClient(timeout=30.0, trust_env=False) as client:
# 1. Text body first (if any), so it leads the conversation.
if message:
send_body: Dict[str, Any] = {