From 8e4d4fcc44afcc5ef410b50eedff52d8da244011 Mon Sep 17 00:00:00 2001 From: sam-shakeybridge-software <3429163+ssjoleary@users.noreply.github.com> Date: Thu, 23 Apr 2026 17:50:26 +0100 Subject: [PATCH 1/2] fix: notify server when model is selected via EcaChatSelectModel When a model was selected via EcaChatSelectModel, the local state was updated but the server was never notified. This meant the server's last-config-notified was out of sync with the client's selected model. Send chat/selectedModelChanged to the server on model selection, matching the approach used by eca-emacs. The local state update is kept for immediate header refresh since the server's response to chat/selectedModelChanged does not include selectModel. Note: /model in chat does not update the header when the selected model matches the server's last-config-notified value. This is a server-side gap where chat-selected-model-changed should include select-model in its notify-fields-changed-only! call to keep last-config-notified in sync. --- lua/eca/commands.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/eca/commands.lua b/lua/eca/commands.lua index 522c680..e687040 100644 --- a/lua/eca/commands.lua +++ b/lua/eca/commands.lua @@ -454,6 +454,7 @@ function M.setup() }, function(choice) if choice then chat.mediator:update_selected_model(choice) + chat.mediator:send("chat/selectedModelChanged", { model = choice, variant = nil }, nil) end end) end, { From 78285a3dcf9dccf6dd10cd9f632eea73abc0560d Mon Sep 17 00:00:00 2001 From: sam-shakeybridge-software <3429163+ssjoleary@users.noreply.github.com> Date: Thu, 23 Apr 2026 18:14:26 +0100 Subject: [PATCH 2/2] fix: use vim.NIL for variant and add server notification test - Use vim.NIL instead of nil so variant is encoded as JSON null, matching eca-emacs behaviour - Add test asserting chat/selectedModelChanged is sent to the server with the correct method and model param --- lua/eca/commands.lua | 2 +- tests/test_select_commands.lua | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lua/eca/commands.lua b/lua/eca/commands.lua index e687040..c6f4a31 100644 --- a/lua/eca/commands.lua +++ b/lua/eca/commands.lua @@ -454,7 +454,7 @@ function M.setup() }, function(choice) if choice then chat.mediator:update_selected_model(choice) - chat.mediator:send("chat/selectedModelChanged", { model = choice, variant = nil }, nil) + chat.mediator:send("chat/selectedModelChanged", { model = choice, variant = vim.NIL }, nil) end end) end, { diff --git a/tests/test_select_commands.lua b/tests/test_select_commands.lua index 8274422..c563fc8 100644 --- a/tests/test_select_commands.lua +++ b/tests/test_select_commands.lua @@ -82,6 +82,28 @@ T["EcaChatSelectModel"]["updates state when model selected"] = function() eq(child.lua_get("_G.State.config.models.selected"), "model2") end +T["EcaChatSelectModel"]["notifies server of model change"] = function() + child.lua([[ + _G.State.config.models.list = { "model1", "model2", "model3" } + _G.State.config.models.selected = "model1" + + -- Capture outgoing notifications + _G.sent_notifications = {} + _G.Mediator.send = function(self, method, params, callback) + table.insert(_G.sent_notifications, { method = method, params = params }) + end + + _G.mock_select("model2") + ]]) + + child.cmd("EcaChatSelectModel") + + local notifications = child.lua_get("_G.sent_notifications") + eq(#notifications, 1) + eq(notifications[1].method, "chat/selectedModelChanged") + eq(notifications[1].params.model, "model2") +end + T["EcaChatSelectModel"]["handles nil selection"] = function() -- Setup initial state child.lua([[