From 0fb9ffd860de7c4643b18093457bbc6ed8d25634 Mon Sep 17 00:00:00 2001 From: Marlos001 Date: Mon, 5 Oct 2026 09:03:16 -0300 Subject: [PATCH] fix: preserve connection mode in immediate action receipts --- BarWidget.qml | 11 ++++++++--- scripts/omaproxy.py | 13 ++++++++++++- tests/test_remote.py | 30 +++++++++++++++++++++++++++--- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/BarWidget.qml b/BarWidget.qml index d7dae22..9a3dbc0 100644 --- a/BarWidget.qml +++ b/BarWidget.qml @@ -108,7 +108,10 @@ Panel { if (result.error) { noticeError = true; notice = result.error; return } if (result.connection_changed) { clearConnectionState() - snapshot = ({configured: false, running: false, accounts: [], models: [], providers: [], connection_id: result.connection_id}) + snapshot = ({configured: false, running: false, accounts: [], models: [], providers: [], + connection_id: result.connection_id, mode: result.mode, + base_url: result.base_url || "", remote_base_url: result.remote_base_url || "", + has_api_key: result.has_api_key === true}) quotaData = ({accounts: []}) auth = ({}) preferences = ({}) @@ -118,6 +121,8 @@ Panel { addingAccount = false addingKey = false editRemote = false + if (result.base_url !== undefined || result.remote_base_url !== undefined) + remoteUrl.text = result.base_url || result.remote_base_url || "" } if (result.auth !== undefined) { var wasWaiting = signingIn @@ -475,7 +480,7 @@ Panel { spacing: Style.space(16) Column { - visible: !root.snapshot.configured && root.page !== 2 + visible: !root.snapshot.configured && root.page !== 2 && !root.remoteConnection width: parent.width spacing: Style.space(16) Label { text: "Your accounts. Your remaining capacity."; font.bold: true; width: parent.width; wrapMode: Text.WordWrap } @@ -779,7 +784,7 @@ Panel { } } } - ActionButton { visible: !root.snapshot.configured && !root.editRemote; text: "Set up local proxy"; enabled: !root.busy; onClicked: root.perform(["setup"]) } + ActionButton { visible: !root.snapshot.configured && !root.editRemote && !root.remoteConnection; text: "Set up local proxy"; enabled: !root.busy; onClicked: root.perform(["setup"]) } PanelSeparator { foreground: root.foreground } Label { text: "Display"; font.bold: true } ActionButton { diff --git a/scripts/omaproxy.py b/scripts/omaproxy.py index 85c16b6..e6c5299 100644 --- a/scripts/omaproxy.py +++ b/scripts/omaproxy.py @@ -151,14 +151,25 @@ def connection_save(payload): for name in ("auth-error.json", "model-error.json"): (state_dir(cfg) / name).unlink(missing_ok=True) return {"connection_changed": True, "connection_id": connection_id(cfg), + "mode": "remote", "base_url": cfg["base_url"], + "has_api_key": bool(cfg["api_key"]), "message": "Remote connection saved. Accounts and limits come from this server."} def connection_local(): connection = read_json(CONFIG / "connection.json", {}) + remote_config = connection.get("remote", {}) + if not isinstance(remote_config, dict): + remote_config = {} + remote_base_url = remote_config.get("base_url", "") + if not isinstance(remote_base_url, str): + remote_base_url = "" connection["mode"] = "local" private_write(CONFIG / "connection.json", json.dumps(connection) + "\n") - return {"connection_changed": True, "connection_id": "local", "message": "Local connection selected."} + return {"connection_changed": True, "connection_id": "local", "mode": "local", + "remote_base_url": remote_base_url, + "has_api_key": bool(remote_config.get("api_key")), + "message": "Local connection selected."} def account_rows(response): diff --git a/tests/test_remote.py b/tests/test_remote.py index a94f326..cd35aa3 100644 --- a/tests/test_remote.py +++ b/tests/test_remote.py @@ -26,6 +26,11 @@ def test_client_key_removal_is_explicit_and_preserves_management_access(self): self.assertEqual(omaproxy.settings()["api_key"], "") self.assertEqual(omaproxy.settings()["management_key"], "management-secret") self.assertNotEqual(result["connection_id"], omaproxy.connection_id(self.cfg)) + self.assertEqual(result["mode"], "remote") + self.assertEqual(result["base_url"], self.cfg["base_url"]) + self.assertFalse(result["has_api_key"]) + self.assertNotIn("management-secret", json.dumps(result)) + self.assertNotIn("client-secret", json.dumps(result)) def test_remote_repair_never_touches_local_state(self): self.save() @@ -93,12 +98,24 @@ def test_remote_setup_needs_no_binary_or_service_and_preserves_local(self): code, result = self.cli(["connection-save"], self.cfg) self.assertEqual(code, 0) self.assertTrue(result["connection_changed"]) + self.assertEqual(result["mode"], "remote") + self.assertEqual(result["base_url"], self.cfg["base_url"]) + self.assertTrue(result["has_api_key"]) + self.assertEqual(set(result), {"connection_changed", "connection_id", "mode", "base_url", "has_api_key", "message"}) self.assertEqual(self.config.joinpath("settings.json").read_text(), local) self.assertEqual((self.config / "connection.json").stat().st_mode & 0o777, 0o600) self.assertEqual(request.call_args_list[0].args, (self.cfg["base_url"] + "/v0/management/auth-files", "management-secret")) self.assertEqual(request.call_args_list[1].args, (self.cfg["base_url"] + "/v1/models", "client-secret")) - self.assertNotIn("secret", json.dumps(result)) - omaproxy.connection_local() + for secret in ("management-secret", "client-secret"): + self.assertNotIn(secret, json.dumps(result)) + local_code, local_result = self.cli(["connection-local"]) + self.assertEqual(local_code, 0) + self.assertEqual(local_result["mode"], "local") + self.assertEqual(local_result["remote_base_url"], self.cfg["base_url"]) + self.assertTrue(local_result["has_api_key"]) + self.assertEqual(set(local_result), {"connection_changed", "connection_id", "mode", "remote_base_url", "has_api_key", "message"}) + for secret in ("management-secret", "client-secret"): + self.assertNotIn(secret, json.dumps(local_result)) self.assertEqual(omaproxy.settings()["port"], 18317) def test_invalid_urls_never_receive_credentials(self): @@ -154,7 +171,14 @@ def test_url_can_be_prefilled_without_sending_unauthenticated_requests(self): def test_switch_to_unconfigured_local_retains_remote_url_without_installing(self): self.save() with patch.object(omaproxy, "run", side_effect=AssertionError("No install or service commands")): - self.assertEqual(self.cli(["connection-local"])[0], 0) + code, receipt = self.cli(["connection-local"]) + self.assertEqual(code, 0) + self.assertEqual(receipt["mode"], "local") + self.assertEqual(receipt["remote_base_url"], self.cfg["base_url"]) + self.assertTrue(receipt["has_api_key"]) + self.assertEqual(set(receipt), {"connection_changed", "connection_id", "mode", "remote_base_url", "has_api_key", "message"}) + self.assertNotIn("management-secret", json.dumps(receipt)) + self.assertNotIn("client-secret", json.dumps(receipt)) result = omaproxy.status() self.assertFalse(result["configured"]) self.assertEqual(result["remote_base_url"], self.cfg["base_url"])