diff --git a/CHANGELOG.md b/CHANGELOG.md index d5cef71..e602dc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## v2.1.1 (2026-05-19) + +- Fixed proxy: map `developer` role to `system` for Chat Completions providers (DeepSeek, Qwen, etc.) +- Fixed proxy: map `developer` role to `user` for Anthropic providers +- Forward `instructions` field from Responses API as system message/param +- Fixes "unknown variant `developer`" error from providers like DeepSeek + ## v2.1.0 (2026-05-19) - Added Codex auth status detection (reads `codex login status`) diff --git a/codex-launcher_2.1.0_all.deb b/codex-launcher_2.1.0_all.deb deleted file mode 100644 index 7bee63b..0000000 Binary files a/codex-launcher_2.1.0_all.deb and /dev/null differ diff --git a/codex-launcher_2.1.1_all.deb b/codex-launcher_2.1.1_all.deb new file mode 100644 index 0000000..56b06c5 Binary files /dev/null and b/codex-launcher_2.1.1_all.deb differ diff --git a/src/codex-launcher-gui b/src/codex-launcher-gui index 9170285..ef10be8 100755 --- a/src/codex-launcher-gui +++ b/src/codex-launcher-gui @@ -24,6 +24,12 @@ model_catalog_json = "" """ CHANGELOG = [ + ("2.1.1", "2026-05-19", [ + "Fixed proxy: map 'developer' role to 'system' for Chat Completions providers", + "Fixed proxy: map 'developer' role to 'user' for Anthropic providers", + "Forward 'instructions' field from Responses API as system message/param", + "Fixes DeepSeek and other providers rejecting unknown 'developer' role", + ]), ("2.1.0", "2026-05-19", [ "Added Codex auth status detection (codex login status)", "Added Re-login button to re-authenticate via codex login", @@ -494,7 +500,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 v2.1.0") + lbl = Gtk.Label(label="Codex Launcher v2.1.1") lbl.set_use_markup(True) hdr.pack_start(lbl, False, False, 0) changelog_btn = Gtk.Button(label="Changelog") diff --git a/src/translate-proxy.py b/src/translate-proxy.py index 5f1d632..adb1e05 100755 --- a/src/translate-proxy.py +++ b/src/translate-proxy.py @@ -151,6 +151,8 @@ def oa_input_to_messages(input_data): t = item.get("type") if t == "message": role = item.get("role", "user") + if role == "developer": + role = "system" text = "" for part in item.get("content", []): pt = part.get("type", "") @@ -323,6 +325,8 @@ def an_input_to_messages(input_data): t = item.get("type") if t == "message": role = item.get("role", "user") + if role == "developer": + role = "user" text = "" for part in item.get("content", []): pt = part.get("type", "") @@ -532,7 +536,11 @@ class Handler(http.server.BaseHTTPRequestHandler): def _handle_openai_compat(self, body, model, stream): input_data = body.get("input", "") - chat_body = {"model": model, "messages": oa_input_to_messages(input_data)} + messages = oa_input_to_messages(input_data) + instructions = body.get("instructions", "").strip() + if instructions: + messages.insert(0, {"role": "system", "content": instructions}) + chat_body = {"model": model, "messages": messages} for k in ("temperature", "top_p", "max_output_tokens"): if k in body: chat_body["max_tokens" if k == "max_output_tokens" else k] = body[k] @@ -562,6 +570,9 @@ class Handler(http.server.BaseHTTPRequestHandler): input_data = body.get("input", "") an_body = {"model": model, "messages": an_input_to_messages(input_data), "max_tokens": body.get("max_output_tokens", 8192)} + instructions = body.get("instructions", "").strip() + if instructions: + an_body["system"] = instructions for k in ("temperature", "top_p"): if k in body: an_body[k] = body[k]