Repository navigation
Conversation
|
@ker2xu hi, and thank you for this PR! 🙏 This was a pleasure to pick up. The I reproduced the failure, and your diagnosis is right: HTTPX rejects a standalone bracketed IPv6 entry such as That said, I'd suggest reworking this before it's merged, mainly because of where the fix lives. The Summary
1. The crash isn't specific to AntigravityWhere
Who receives it from there:
What breaks, for default clients, which read the environment:
So with a proxy set in codeg's Settings, the same failure can hit any Python code that inherits this list and builds a default HTTPX or SDK client: a script that an agent runs through its shell tool, a Python MCP server under another agent that passes its environment down, or a script run in the built-in terminal. This PR covers processes under Antigravity's launch environment only (connection.rs L403-L410). For reference, the mechanism: 2. It's one trade-off, and it's globalYour point about Node holds up, and it isn't only Node. I sent a request to
Removing So the choice is between:
I'd favor dropping it. Today's value stops HTTPX clients from being created at all, even for unrelated destinations, while the routing change only affects IPv6-literal loopback URLs and can be documented. The loopback traffic behind #804 uses IPv4: for OpenCode builds that support the listen flags, codeg passes The PR already makes this trade, just inside one subtree: a Node or Bun process started under Antigravity, for example an 3. Suggested directionRemoving the bracketed default where it's built takes the codeg-generated
Your helper and its unit test already live in This fixes codeg's own default. Normalizing a value that is only inherited, in a launch without a proxy variable (§4), would be a separate follow-up. 4. Smaller notes on the current diffThese mostly go away with §3, but for completeness:
5. Tests and manual checksTests:
Manual, with a proxy set in Settings. Fully restart codeg first, so that fresh terminals and agent sessions pick up the new environment:
How I measured this (macOS 27, Python 3.13, httpx 0.28.1, requests 2.34.2, Node 24.18, Bun 1.3.14, curl 8.7.1)Client construction with today's list. uv installs the pinned packages with your normal network settings first, and the bypass list is only set inside Python: uv run -q --no-project --with 'httpx==0.28.1' --with 'openai==3.26.1' python - <<'EOF'
import os
os.environ["NO_PROXY"] = os.environ["no_proxy"] = "localhost,127.0.0.1,::1,[::1]"
import httpx, openai
for name, build in [("httpx.Client()", httpx.Client), ("openai.OpenAI()", lambda: openai.OpenAI(api_key="x"))]:
try:
build()
print(f"{name}: OK")
except Exception as e:
print(f"{name}: {type(e).__module__}.{type(e).__name__}: {e}")
EOF
# httpx.Client(): httpx.InvalidURL: Invalid port: ':1]'
# openai.OpenAI(): httpx2.InvalidURL: Invalid port: ':1]'The table in §2. Save this as #!/usr/bin/env bash
# Needs uv, node (24+), bun and curl on PATH, and a working IPv6 loopback.
cd "$(mktemp -d)" || exit 1
uv venv -q .venv && uv pip install -q --python .venv 'httpx==0.28.1' 'requests==2.34.2' || exit 1
cat > servers.py <<'EOF'
import socket, threading, time
def serve(sock, tag, status):
while True:
conn, _ = sock.accept()
conn.recv(4096)
with open("hits.log", "a") as log:
log.write(tag + "\n")
conn.sendall(f"HTTP/1.1 {status}\r\nContent-Length: 0\r\nConnection: close\r\n\r\n".encode())
conn.close()
proxy = socket.create_server(("127.0.0.1", 18999)) # stands in for a proxy on another machine
target = socket.create_server(("::1", 18998), family=socket.AF_INET6)
threading.Thread(target=serve, args=(proxy, "proxy", "502 Bad Gateway"), daemon=True).start()
threading.Thread(target=serve, args=(target, "direct", "200 OK"), daemon=True).start()
open("ready", "w").close()
time.sleep(600)
EOF
.venv/bin/python servers.py 2>servers.err & SERVERS=$!
trap 'kill $SERVERS 2>/dev/null' EXIT
for _ in 1 2 3 4 5 6 7 8 9 10; do [ -e ready ] && break; sleep 0.5; done
[ -e ready ] || { echo "The listeners did not start:"; cat servers.err; exit 1; }
URL='http://[::1]:18998/'
PX='http://127.0.0.1:18999'
PY="$PWD/.venv/bin/python"
JS_FETCH="fetch('$URL', { signal: AbortSignal.timeout(3000) }).then(r => r.text()).catch(e => console.error(String(e)))"
JS_HTTP="require('http').get('$URL', r => r.resume()).setTimeout(3000, function () { this.destroy() }).on('error', e => console.error(String(e)))"
probe() { # probe <label> <command...>, run with the NO_PROXY in $NP
local label=$1; shift
: > hits.log
env -i PATH="$PATH" HOME="$HOME" HTTP_PROXY=$PX http_proxy=$PX HTTPS_PROXY=$PX https_proxy=$PX \
NO_PROXY="$NP" no_proxy="$NP" "$@" >/dev/null 2>"$label.err"
sleep 0.2
local hits; hits=$(cat hits.log)
printf ' %-11s %s\n' "$label" "${hits:-no request sent: $(tail -n 1 "$label.err")}"
}
for NP in 'localhost,127.0.0.1,::1,[::1]' 'localhost,127.0.0.1,::1'; do
echo "NO_PROXY=$NP"
probe urllib "$PY" -c "import urllib.request as u; u.urlopen('$URL', timeout=3)"
probe requests "$PY" -c "import requests; requests.get('$URL', timeout=3)"
probe httpx "$PY" -c "import httpx; httpx.get('$URL', timeout=3)"
probe node-fetch env NODE_USE_ENV_PROXY=1 node -e "$JS_FETCH"
probe node-http env NODE_USE_ENV_PROXY=1 node -e "$JS_HTTP"
probe node-noflag node -e "$JS_FETCH"
probe bun-fetch bun -e "$JS_FETCH"
probe curl curl -sS -m 3 "$URL"
done
echo "No proxy variable at all, NO_PROXY='[::1]':"
env -i NO_PROXY='[::1]' "$PY" -c 'import httpx; httpx.Client()' 2>&1 | tail -n 1Output: Thanks again! Your diagnosis is spot on and the tests are careful, and most of this carries straight over to the shared list. If anything here is unclear, or you'd rather keep the fix narrower for a reason I've missed, just reply here. I'm happy to look at the next round. |
|
codeg work task |
Launching Antigravity with a proxy gives its Python ACP server
NO_PROXY=localhost,127.0.0.1,::1,[::1]. Python MCP servers inheriting that environment can fail before initialization because HTTPX interprets[::1]as an invalid host/port pattern. The Perplexity MCP server reportsInvalid port: ':1]'and exits with EOF.Normalize standalone bracketed IPv6 bypass entries in Antigravity's launch environment, including launches without a recorded auth method. The common loopback list stays unchanged because Node's environment proxy needs
[::1]to bypass IPv6 loopback. Explicit URL entries, domains, wildcards, proxy URLs, and the credential policy retain their existing behavior.Regression coverage checks both environment-variable spellings, IPv6 alias deduplication, URL/domain preservation, empty and wildcard values, and existing credential behavior. A real Node IPv6 loopback request confirms that the shared bracketed entry remains necessary; the normalized environment allows the installed Perplexity MCP server to initialize and list its tools.
The repository's exact policy functions fail the new IPv6 regression on base and pass all five policy/credential cases with the change. The same five cases also pass in the native crate. Upstream CI has passed the complete Linux server test suite, Clippy, and frontend lint/tests/build at this PR's head. The remaining desktop and cross-platform CI jobs are still running.