diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6d9297..73da9dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,27 @@
# Changelog
+## v3.10.3 (2026-05-25)
+
+**Fix Antigravity 404 Errors — Verified REST Model IDs**
+
+### Critical Fix
+- Antigravity REST API (`v1internal:generateContent`) uses slug IDs, not display names
+- Verified all model IDs with live API testing against `daily-cloudcode-pa.sandbox.googleapis.com`
+- Display names map to closest working REST model (e.g. `Gemini 3.5 Flash (High)` → `gemini-3-flash`)
+- Model list now matches agy CLI: Gemini 3.5 Flash (H/M/L), Gemini 3.1 Pro (H/L), Claude Sonnet/Opus 4.6, GPT-OSS 120B
+
+### Working REST Model IDs
+| Display Name | REST ID |
+|---|---|
+| Gemini 3.5 Flash (High) | gemini-3-flash |
+| Gemini 3.5 Flash (Medium) | gemini-3-flash |
+| Gemini 3.5 Flash (Low) | gemini-3.5-flash-low |
+| Gemini 3.1 Pro (High) | gemini-3.1-pro-low |
+| Gemini 3.1 Pro (Low) | gemini-3.1-pro-low |
+| Claude Sonnet 4.6 (Thinking) | claude-sonnet-4-6 |
+| Claude Opus 4.6 (Thinking) | claude-opus-4-6-thinking |
+| GPT-OSS 120B (Medium) | gpt-oss-120b-medium |
+
## v3.10.2 (2026-05-25)
**Fix Antigravity Model Names**
diff --git a/codex-launcher_3.10.3_all.deb b/codex-launcher_3.10.3_all.deb
new file mode 100644
index 0000000..f8dc725
Binary files /dev/null and b/codex-launcher_3.10.3_all.deb differ
diff --git a/install.sh b/install.sh
index f228284..04d7c3a 100755
--- a/install.sh
+++ b/install.sh
@@ -3,11 +3,11 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-if [ -f "$SCRIPT_DIR/codex-launcher_3.10.2_all.deb" ]; then
- echo "Installing codex-launcher_3.10.2_all.deb ..."
- sudo dpkg -i "$SCRIPT_DIR/codex-launcher_3.10.2_all.deb"
+if [ -f "$SCRIPT_DIR/codex-launcher_3.10.3_all.deb" ]; then
+ echo "Installing codex-launcher_3.10.3_all.deb ..."
+ sudo dpkg -i "$SCRIPT_DIR/codex-launcher_3.10.3_all.deb"
echo ""
- echo "Installed v3.10.2 via .deb package."
+ echo "Installed v3.10.3 via .deb package."
echo " translate-proxy.py -> /usr/bin/translate-proxy.py"
echo " codex-launcher-gui -> /usr/bin/codex-launcher-gui"
echo " cleanup-codex-stale -> /usr/bin/cleanup-codex-stale.sh"
diff --git a/src/codex-launcher-gui b/src/codex-launcher-gui
index 74c25ed..2d7d911 100755
--- a/src/codex-launcher-gui
+++ b/src/codex-launcher-gui
@@ -26,12 +26,12 @@ model_catalog_json = ""
"""
CHANGELOG = [
- ("3.10.2", "2026-05-25", [
- "Fix Antigravity models: use display names (Gemini 3.5 Flash (High)) not slugs (gemini-3.5-flash-high)",
- "Proxy maps old slugs + display names to correct Antigravity API model IDs",
- "Fetch from API returns correct display-name model list for Antigravity",
+ ("3.10.3", "2026-05-25", [
+ "Fix Antigravity 404: map display names to verified REST API model IDs",
+ "REST API uses slugs (gemini-3-flash) not display names (Gemini 3.5 Flash)",
+ "Match agy CLI model list: Gemini 3.5 Flash (H/M/L), 3.1 Pro (H/L), Claude 4.6, GPT-OSS",
]),
- ("3.10.1", "2026-05-25", [
+ ("3.10.2", "2026-05-25", [
"Fetch from API now works for Antigravity — returns current model list",
]),
("3.10.0", "2026-05-25", [
@@ -360,11 +360,11 @@ PROVIDER_PRESETS = {
"base_url": "https://daily-cloudcode-pa.sandbox.googleapis.com",
"oauth_provider": "google-antigravity",
"models": [
- "Gemini 3.5 Flash (High)", "Gemini 3.5 Flash (Medium)",
+ "Gemini 3.5 Flash (High)", "Gemini 3.5 Flash (Medium)", "Gemini 3.5 Flash (Low)",
"Gemini 3.1 Pro (High)", "Gemini 3.1 Pro (Low)",
- "Claude Sonnet 4.6 Thinking",
- "Claude Opus 4.6 Thinking",
- "GPT-OSS 120B Medium",
+ "Claude Sonnet 4.6 (Thinking)",
+ "Claude Opus 4.6 (Thinking)",
+ "GPT-OSS 120B (Medium)",
],
},
"OpenAdapter": {
@@ -758,11 +758,11 @@ def endpoint_model_headers(endpoint):
return headers
_ANTIGRAVITY_MODELS = [
- "Gemini 3.5 Flash (High)", "Gemini 3.5 Flash (Medium)",
+ "Gemini 3.5 Flash (High)", "Gemini 3.5 Flash (Medium)", "Gemini 3.5 Flash (Low)",
"Gemini 3.1 Pro (High)", "Gemini 3.1 Pro (Low)",
- "Claude Sonnet 4.6 Thinking",
- "Claude Opus 4.6 Thinking",
- "GPT-OSS 120B Medium",
+ "Claude Sonnet 4.6 (Thinking)",
+ "Claude Opus 4.6 (Thinking)",
+ "GPT-OSS 120B (Medium)",
]
def fetch_models_for_endpoint(endpoint, timeout=10):
@@ -1776,7 +1776,7 @@ class LauncherWin(Gtk.Window):
# header row
hdr = Gtk.Box(spacing=8)
vbox.pack_start(hdr, False, False, 0)
- lbl = Gtk.Label(label="Codex Launcher v3.10.2")
+ lbl = Gtk.Label(label="Codex Launcher v3.10.3")
lbl.set_use_markup(True)
hdr.pack_start(lbl, False, False, 0)
changelog_btn = Gtk.Button(label="Changelog")
@@ -3580,7 +3580,7 @@ class EditEndpointDialog(Gtk.Dialog):
auth_url = "https://codebuff.com/api/auth/cli/code"
body = json.dumps({"fingerprintId": fingerprint_id}).encode()
req = urllib.request.Request(auth_url, data=body,
- headers={"Content-Type": "application/json", "User-Agent": "codex-launcher/3.10.2"})
+ headers={"Content-Type": "application/json", "User-Agent": "codex-launcher/3.10.3"})
resp = urllib.request.urlopen(req, timeout=30)
data = json.loads(resp.read())
login_url = data.get("loginUrl", "") or data.get("login_url", "")
@@ -3605,7 +3605,7 @@ class EditEndpointDialog(Gtk.Dialog):
time.sleep(2)
try:
poll_req = urllib.request.Request(poll_url,
- headers={"User-Agent": "codex-launcher/3.10.2"})
+ headers={"User-Agent": "codex-launcher/3.10.3"})
poll_resp = urllib.request.urlopen(poll_req, timeout=10)
poll_data = json.loads(poll_resp.read())
user = poll_data.get("user")
diff --git a/src/translate-proxy.py b/src/translate-proxy.py
index 6f5adbe..ab37c02 100755
--- a/src/translate-proxy.py
+++ b/src/translate-proxy.py
@@ -335,7 +335,7 @@ def _codebuff_get_session(token, model):
req = urllib.request.Request(url, data=body, headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
- "User-Agent": "codex-launcher/3.10.2",
+ "User-Agent": "codex-launcher/3.10.3",
"x-codebuff-model": model,
})
try:
@@ -383,7 +383,7 @@ def _codebuff_start_run(token, agent_id):
req = urllib.request.Request(url, data=body, headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
- "User-Agent": "codex-launcher/3.10.2",
+ "User-Agent": "codex-launcher/3.10.3",
})
try:
resp = urllib.request.urlopen(req, timeout=15)
@@ -416,7 +416,7 @@ def _codebuff_finish_run(token, run_id, status="completed"):
req = urllib.request.Request(url, data=body, headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
- "User-Agent": "codex-launcher/3.10.2",
+ "User-Agent": "codex-launcher/3.10.3",
})
try:
urllib.request.urlopen(req, timeout=10)
@@ -4315,24 +4315,41 @@ class Handler(http.server.BaseHTTPRequestHandler):
if OAUTH_PROVIDER == "google-antigravity":
alias_map = {
- "gemini-3.5-flash-high": "Gemini 3.5 Flash (High)",
- "gemini-3.5-flash-medium": "Gemini 3.5 Flash (Medium)",
- "gemini-3.1-pro-high": "Gemini 3.1 Pro (High)",
- "gemini-3.1-pro-low": "Gemini 3.1 Pro (Low)",
- "gemini-3.1-pro-preview": "Gemini 3.1 Pro (High)",
- "gemini-3-pro-preview": "Gemini 3.1 Pro (High)",
- "gemini-3-pro": "Gemini 3.1 Pro (High)",
- "gemini-3.1-pro": "Gemini 3.1 Pro (High)",
- "gemini-3-flash-preview": "Gemini 3.5 Flash (High)",
- "gemini-3-flash": "Gemini 3.5 Flash (High)",
- "antigravity-gemini-3-flash": "Gemini 3.5 Flash (High)",
- "antigravity-gemini-3-pro": "Gemini 3.1 Pro (High)",
- "antigravity-gemini-3.1-pro": "Gemini 3.1 Pro (High)",
- "antigravity-claude-sonnet-4-6": "Claude Sonnet 4.6 Thinking",
- "antigravity-claude-opus-4-6-thinking": "Claude Opus 4.6 Thinking",
- "claude-sonnet-4.6-thinking": "Claude Sonnet 4.6 Thinking",
- "claude-opus-4.6-thinking": "Claude Opus 4.6 Thinking",
- "gpt-oss-120b-medium": "GPT-OSS 120B Medium",
+ "Gemini 3.5 Flash (High)": "gemini-3-flash",
+ "Gemini 3.5 Flash (Medium)": "gemini-3-flash",
+ "Gemini 3.5 Flash (Low)": "gemini-3.5-flash-low",
+ "gemini-3.5-flash-high": "gemini-3-flash",
+ "gemini-3.5-flash-medium": "gemini-3-flash",
+ "gemini-3.5-flash-low": "gemini-3.5-flash-low",
+ "gemini-3-flash-preview": "gemini-3-flash",
+ "gemini-3-flash": "gemini-3-flash",
+ "antigravity-gemini-3-flash": "gemini-3-flash",
+ "Gemini 3.1 Pro (High)": "gemini-3.1-pro-low",
+ "Gemini 3.1 Pro (Low)": "gemini-3.1-pro-low",
+ "gemini-3.1-pro-high": "gemini-3.1-pro-low",
+ "gemini-3.1-pro-low": "gemini-3.1-pro-low",
+ "gemini-3.1-pro-preview": "gemini-3.1-pro-low",
+ "gemini-3.1-pro": "gemini-3.1-pro-low",
+ "gemini-3-pro-preview": "gemini-3.1-pro-low",
+ "gemini-3-pro": "gemini-3.1-pro-low",
+ "gemini-3-pro-low": "gemini-3.1-pro-low",
+ "gemini-3-pro-high": "gemini-3.1-pro-low",
+ "antigravity-gemini-3-pro": "gemini-3.1-pro-low",
+ "antigravity-gemini-3.1-pro": "gemini-3.1-pro-low",
+ "Claude Sonnet 4.6 (Thinking)": "claude-sonnet-4-6",
+ "Claude Sonnet 4.6 Thinking": "claude-sonnet-4-6",
+ "claude-sonnet-4.6-thinking": "claude-sonnet-4-6",
+ "antigravity-claude-sonnet-4-6": "claude-sonnet-4-6",
+ "Claude Opus 4.6 (Thinking)": "claude-opus-4-6-thinking",
+ "Claude Opus 4.6 Thinking": "claude-opus-4-6-thinking",
+ "claude-opus-4.6-thinking": "claude-opus-4-6-thinking",
+ "antigravity-claude-opus-4-6-thinking": "claude-opus-4-6-thinking",
+ "GPT-OSS 120B (Medium)": "gpt-oss-120b-medium",
+ "GPT-OSS 120B Medium": "gpt-oss-120b-medium",
+ "gpt-oss-120b": "gpt-oss-120b-medium",
+ "gemini-2.5-flash": "gemini-2.5-flash",
+ "gemini-2.5-pro": "gemini-2.5-pro",
+ "gemini-2.5-flash-lite": "gemini-2.5-flash-lite",
}
model = alias_map.get(model, model)
if model != original_model:
@@ -5325,7 +5342,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {token}",
- "User-Agent": "codex-launcher/3.10.2",
+ "User-Agent": "codex-launcher/3.10.3",
"x-codebuff-model": model,
}
if instance_id:
@@ -5491,7 +5508,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
if body.get("tool_choice"):
chat_body["tool_choice"] = body["tool_choice"]
target = f"{_CODEBUFF_API_URL}/api/v1/chat/completions"
- headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}", "User-Agent": "codex-launcher/3.10.2", "x-codebuff-model": model}
+ headers = {"Content-Type": "application/json", "Authorization": f"Bearer {token}", "User-Agent": "codex-launcher/3.10.3", "x-codebuff-model": model}
if instance_id:
headers["x-codebuff-instance-id"] = instance_id
print(f"[codebuff] retry POST {target} model={model} stream={stream} run={run_id} (thinking disabled via DeepSeek native)", file=sys.stderr)