diff --git a/CHANGELOG.md b/CHANGELOG.md index 72c44cf..23ecd76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Strip `reasoning_content` from proxy output — Codex doesn't use it, avoids token waste - Force `max_tokens=64000` minimum for openai-compat providers — room for both reasoning and content - Inspired by unsloth's reasoning control patterns for Qwen/GPT-OSS models +- Styled reasoning switch: green = ON, orange = OFF, gentle rounded pill shape +- Added error handling to endpoint manager Add/Edit/Manage dialogs (prevents silent failures) ## v2.1.3 (2026-05-19) diff --git a/codex-launcher_2.2.0_all.deb b/codex-launcher_2.2.0_all.deb index c3e9789..1a10bc3 100644 Binary files a/codex-launcher_2.2.0_all.deb and b/codex-launcher_2.2.0_all.deb differ diff --git a/src/codex-launcher-gui b/src/codex-launcher-gui index 0fdaa07..c59ee71 100755 --- a/src/codex-launcher-gui +++ b/src/codex-launcher-gui @@ -810,8 +810,13 @@ class LauncherWin(Gtk.Window): # ── endpoint mgr ───────────────────────────────────────────── def _open_mgr(self): - self._mgr_window = EndpointMgr(self) - self._mgr_window.connect("destroy", lambda *_: setattr(self, "_mgr_window", None)) + try: + self._mgr_window = EndpointMgr(self) + self._mgr_window.connect("destroy", lambda *_: setattr(self, "_mgr_window", None)) + except Exception as e: + import traceback; traceback.print_exc() + d = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, f"Error: {e}") + d.run(); d.destroy() def _backup_profile(self): chooser = Gtk.FileChooserDialog( @@ -1328,14 +1333,24 @@ class EndpointMgr(Gtk.Window): return self._store[i][0] def _add(self): - self._dialog = EditEndpointDialog(self, None) - self._dialog.connect("destroy", lambda *_: setattr(self, "_dialog", None)) + try: + self._dialog = EditEndpointDialog(self, None) + self._dialog.connect("destroy", lambda *_: setattr(self, "_dialog", None)) + except Exception as e: + import traceback; traceback.print_exc() + d = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, f"Error: {e}") + d.run(); d.destroy() def _edit(self): name = self._selected() if name: - self._dialog = EditEndpointDialog(self, name) - self._dialog.connect("destroy", lambda *_: setattr(self, "_dialog", None)) + try: + self._dialog = EditEndpointDialog(self, name) + self._dialog.connect("destroy", lambda *_: setattr(self, "_dialog", None)) + except Exception as e: + import traceback; traceback.print_exc() + d = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, f"Error: {e}") + d.run(); d.destroy() def _delete(self): name = self._selected() @@ -1430,13 +1445,12 @@ class EditEndpointDialog(Gtk.Dialog): self._entry_cc_ver.set_placeholder_text("e.g. 0.26.8 (Command Code only)") add_row(5, "CC Version:", self._entry_cc_ver) - reasoning_css = """ + reasoning_css = b""" switch.reasoning-toggle { min-width: 56px; min-height: 28px; border-radius: 14px; background: #e67e22; border: 2px solid #cf6d17; - padding: 0; } switch.reasoning-toggle:checked { background: #2ecc71; @@ -1447,18 +1461,19 @@ class EditEndpointDialog(Gtk.Dialog): border-radius: 12px; background: white; border: 1px solid #bbb; - box-shadow: 0 1px 3px rgba(0,0,0,0.2); } """ - css_provider = Gtk.CssProvider() - css_provider.load_from_data(reasoning_css.encode()) - reasoning_style = Gtk.StyleContext() - reasoning_style.add_provider(css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER) - reasoning_box = Gtk.Box(spacing=10) self._switch_reasoning = Gtk.Switch() self._switch_reasoning.set_name("reasoning-toggle") - reasoning_style.add_class(self._switch_reasoning.get_style_context(), "reasoning-toggle") + ctx = self._switch_reasoning.get_style_context() + ctx.add_class("reasoning-toggle") + try: + css_prov = Gtk.CssProvider() + css_prov.load_from_data(reasoning_css) + ctx.add_provider(css_prov, Gtk.STYLE_PROVIDER_PRIORITY_USER) + except Exception: + pass self._switch_reasoning.set_active(self._data.get("reasoning_enabled", True)) self._switch_reasoning.connect("notify::active", lambda *a: self._on_reasoning_toggled()) reasoning_box.pack_start(self._switch_reasoning, False, False, 0)