Skip to content

Commit 5e1d8d2

Browse files
committed
decouple UI from server
Add a mediator that sits between the sidebar and the server that handles sending messages
1 parent f22df47 commit 5e1d8d2

File tree

4 files changed

+51
-28
lines changed

4 files changed

+51
-28
lines changed

lua/eca/init.lua

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ function M._init(id)
168168
local sidebar = M.sidebars[id]
169169

170170
if not sidebar then
171-
sidebar = Sidebar.new(id)
171+
sidebar = Sidebar.new(id, M.mediator)
172172
M.sidebars[id] = sidebar
173173
end
174174
M.current = { sidebar = sidebar }
@@ -241,11 +241,9 @@ function M.setup(opts)
241241
H.keymaps()
242242
H.signs()
243243

244-
-- Initialize status bar
245-
246244
-- Initialize the ECA server with callbacks
247245
M.server = Server.new()
248-
246+
M.mediator = require("eca.mediator").new(M.server)
249247
-- Start server automatically in background
250248
vim.defer_fn(function()
251249
M.server:start()

lua/eca/mediator.lua

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---@class eca.Mediator
2+
---@field server eca.Server
3+
local mediator = {}
4+
5+
---@param server eca.Server
6+
---@return eca.Mediator
7+
function mediator.new(server)
8+
return setmetatable({
9+
server = server,
10+
}, { __index = mediator })
11+
end
12+
13+
---@param method string
14+
---@param params eca.MessageParams
15+
---@param callback fun(err: string, result: table)
16+
function mediator:send(method, params, callback)
17+
if not self.server:is_running() then
18+
callback("Server is not running, please start the server", nil)
19+
return
20+
end
21+
self.server:send_request(method, params, callback)
22+
end
23+
24+
return mediator

lua/eca/sidebar.lua

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ local Split = require("nui.split")
88
---@class eca.Sidebar
99
---@field public id integer The tab ID
1010
---@field public containers table<string, NuiSplit> The nui containers
11+
---@field mediator eca.Mediator mediator to send server requests to
1112
---@field private _initialized boolean Whether the sidebar has been initialized
1213
---@field private _current_response_buffer string Buffer for accumulating streaming response
1314
---@field private _is_streaming boolean Whether we're currently receiving a streaming response
@@ -34,10 +35,12 @@ local UI_ELEMENTS_HEIGHT = 2 -- Reserve space for statusline and tabline
3435
local SAFETY_MARGIN = 2 -- Extra margin to prevent "Not enough room" errors
3536

3637
---@param id integer Tab ID
38+
---@param mediator eca.Mediator
3739
---@return eca.Sidebar
38-
function M.new(id)
40+
function M.new(id, mediator)
3941
local instance = setmetatable({}, M)
4042
instance.id = id
43+
instance.mediator = mediator
4144
instance.containers = {}
4245
instance._initialized = false
4346
instance._current_response_buffer = ""
@@ -1158,30 +1161,24 @@ function M:_send_message(message)
11581161
-- Store the last user message to avoid duplication
11591162
self._last_user_message = message
11601163

1161-
-- Send message to ECA server
1162-
local eca = require("eca")
1163-
if eca.server and eca.server:is_running() then
1164-
-- Include active contexts in the message
1165-
local contexts = self:get_contexts()
1166-
eca.server:send_request("chat/prompt", {
1167-
chatId = self.id,
1168-
requestId = tostring(os.time()),
1169-
message = message,
1170-
contexts = contexts or {},
1171-
}, function(err, result)
1172-
if err then
1173-
Logger.error("Failed to send message to ECA server: " .. tostring(err))
1174-
self:_add_message("assistant", "❌ **Error**: Failed to send message to ECA server")
1175-
end
1176-
-- Response will come through server notification handler
1177-
self:_add_input_line()
1178-
1179-
self:handle_chat_content_received(result.params)
1180-
end)
1181-
else
1182-
self:_add_message("assistant", "❌ **Error**: ECA server is not running. Please check server status.")
1164+
local contexts = self:get_contexts()
1165+
self.mediator:send("chat/prompt", {
1166+
chatId = self.id,
1167+
requestId = tostring(os.time()),
1168+
message = message,
1169+
contexts = contexts or {},
1170+
}, function(err, result)
1171+
if err then
1172+
print("err is " .. err)
1173+
Logger.error("Failed to send message to ECA server: " .. err)
1174+
self:_add_message("assistant", "❌ **Error**: Failed to send message to ECA server: " .. err)
1175+
return
1176+
end
1177+
-- Response will come through server notification handler
11831178
self:_add_input_line()
1184-
end
1179+
1180+
self:handle_chat_content_received(result.params)
1181+
end)
11851182
end
11861183

11871184
function M:handle_chat_content(message)

lua/eca/types.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222

2323
---@alias eca.ToolCallDetails eca.FileChangedDetails
2424

25+
---TODO: flesh these out
26+
---@alias eca.MessageParams table
27+
---@alias eca.Message table
28+
2529
---@class eca.FileChangedDetails
2630
---@field type 'fileChange'
2731
---@field path string the file path of this file change

0 commit comments

Comments
 (0)