diff --git a/CHANGELOG.md b/CHANGELOG.md index b13074b..ace2e99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## v2.1.3 (2026-05-19) + +- **Fixed Crof mimo-v2.5-pro stopping mid-response (finish_reason=length)** + - Root cause: model emits 600+ `reasoning_content` SSE chunks that exhaust `max_tokens` before any actual content is generated + - Strip `reasoning_content` from proxy output — Codex doesn't use reasoning, avoids wasting output tokens on invisible text + - Force `max_tokens` minimum of 64000 for openai-compat providers — gives models room for both reasoning and content + - Works for all openai-compat providers (Crof, Z.AI, DeepSeek, OpenRouter, etc.) + ## v2.1.2 (2026-05-19) - **Fixed Crof.ai and providers stopping after first tool call (root cause: None tool IDs)** diff --git a/codex-launcher_2.1.2_all.deb b/codex-launcher_2.1.2_all.deb deleted file mode 100644 index 00f3d80..0000000 Binary files a/codex-launcher_2.1.2_all.deb and /dev/null differ diff --git a/codex-launcher_2.1.3_all.deb b/codex-launcher_2.1.3_all.deb new file mode 100644 index 0000000..7245e9c Binary files /dev/null and b/codex-launcher_2.1.3_all.deb differ diff --git a/src/codex-launcher-gui b/src/codex-launcher-gui index 9753029..f9de114 100755 --- a/src/codex-launcher-gui +++ b/src/codex-launcher-gui @@ -24,6 +24,11 @@ model_catalog_json = "" """ CHANGELOG = [ + ("2.1.3", "2026-05-19", [ + "Fixed Crof mimo-v2.5-pro stopping: reasoning_content exhausted all output tokens", + "Strip reasoning_content from proxy output — Codex doesn't use it, avoids token waste", + "Force max_tokens=64000 minimum for openai-compat providers — gives models room for both reasoning and content", + ]), ("2.1.2", "2026-05-19", [ "Fixed Crof.ai and providers stopping after first tool call (root cause: None tool IDs)", "Codex sends function_call items with id=None — proxy now matches tool results to calls by position", @@ -527,7 +532,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.2") + lbl = Gtk.Label(label="Codex Launcher v2.1.3") 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 6477672..ffb2d33 100755 --- a/src/translate-proxy.py +++ b/src/translate-proxy.py @@ -370,10 +370,6 @@ def oa_resp_to_responses(chat_resp, model, resp_id=None): fm = {"stop": "completed", "length": "incomplete", "tool_calls": "completed", "content_filter": "incomplete"} status = fm.get(finish, "incomplete") outputs = [] - rc = msg.get("reasoning_content") - if rc: - outputs.append({"type": "reasoning", "id": uid("rsn"), "status": "completed", - "content": [{"type": "text", "text": rc}]}) if content: outputs.append({"type": "message", "id": uid("msg"), "role": "assistant", "status": "completed", "content": [{"type": "output_text", "text": content, "annotations": []}]}) @@ -447,9 +443,7 @@ def oa_stream_to_sse(chat_stream, model, req_id): yield emit("response.output_text.delta", {"type": "response.function_call_arguments.delta", "delta": fn["arguments"], "item_id": tc_buf[idx]["id"]}) - rc = delta.get("reasoning_content") - if rc: - yield emit("response.reasoning.delta", {"type": "response.reasoning.delta", "delta": rc}) + if msg_opened: yield emit("response.output_text.done", {"type": "response.output_text.done", @@ -885,9 +879,10 @@ class Handler(http.server.BaseHTTPRequestHandler): if instructions: messages.insert(0, {"role": "system", "content": instructions}) chat_body = {"model": model, "messages": messages} - for k in ("temperature", "top_p", "max_output_tokens"): + for k in ("temperature", "top_p"): if k in body: - chat_body["max_tokens" if k == "max_output_tokens" else k] = body[k] + chat_body[k] = body[k] + chat_body["max_tokens"] = max(body.get("max_output_tokens", 0), 64000) tools = oa_convert_tools(body.get("tools")) if tools: chat_body["tools"] = tools