Skip to content
46 changes: 46 additions & 0 deletions lua/eca/commands.lua
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,52 @@ function M.setup()
desc = "Restart ECA server",
})

vim.api.nvim_create_user_command("EcaServerMessages", function()
local has_snacks, snacks = pcall(require, "snacks")
if not has_snacks then
Logger.notify("snacks.nvim is not available", vim.log.levels.ERROR)
return
end

snacks.picker(
---@type snacks.picker.Config
{
source = "eca messages",
finder = function(opts, ctx)
---@type snacks.picker.finder.Item[]
local items = {}
local eca = require("eca")
if not eca or not eca.server then
Logger.notify("ECA plugin is not available", vim.log.levels.ERROR)
return items
end

for msg in vim.iter(eca.server.messages) do
print(msg)
Comment thread
joaopluigi marked this conversation as resolved.
Outdated
local decoded = vim.json.decode(msg.content)
table.insert(items, {
text = decoded.method,
idx = decoded.id,
preview = {
text = vim.inspect(decoded),
ft = "lua",
},
})
end
return items
end,
preview = "preview",
format = "text",
confirm = function(self, item, _)
vim.fn.setreg("", item.preview.text)
self:close()
end,
}
)
end, {
desc = "Display Messages Sent to and Received by ECA server",
})

vim.api.nvim_create_user_command("EcaLogs", function(opts)
local Api = require("eca.api")
local subcommand = opts.args and opts.args:match("%S+") or "show"
Expand Down
3 changes: 2 additions & 1 deletion lua/eca/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,9 @@ function M.setup(opts)
H.signs()

-- Initialize the ECA server with callbacks
M.state = require("eca.state").new()
M.server = Server.new()
M.mediator = require("eca.mediator").new(M.server)
M.mediator = require("eca.mediator").new(M.server, M.state)
-- Start server automatically in background
vim.defer_fn(function()
M.server:start()
Expand Down
45 changes: 44 additions & 1 deletion lua/eca/mediator.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
---@class eca.Mediator
---@field server eca.Server
---@field state eca.State
local mediator = {}

---@param server eca.Server
---@param state eca.State
---@return eca.Mediator
function mediator.new(server)
function mediator.new(server, state)
return setmetatable({
server = server,
state = state,
}, { __index = mediator })
end

Expand All @@ -23,4 +26,44 @@ function mediator:send(method, params, callback)
self.server:send_request(method, params, callback)
end

function mediator:selected_behavior()
return self.state.config.behaviors.selected
end

function mediator:selected_model()
return self.state.config.models.selected
end

function mediator:tokens_session()
return self.state.usage.tokens.session
end

function mediator:tokens_limit()
return self.state.usage.tokens.limit
end

function mediator:costs_session()
return self.state.usage.costs.session
end

function mediator:status_state()
return self.state.status.state
end

function mediator:status_text()
return self.state.status.text
end

function mediator:mcps()
local mcps = {}

for _, tool in pairs(self.state.tools) do
if tool.type == "mcp" then
table.insert(mcps, tool)
end
end

return mcps
end

return mediator
4 changes: 2 additions & 2 deletions lua/eca/observer.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
local observer = {}

---@type { [integer]: fun(message: table) }
---@type { [string]: fun(message: table) }
local subscriptions = {}

---@param id integer
---@param id string
---@param on_update fun(message: table)
function observer.subscribe(id, on_update)
subscriptions[id] = on_update
Expand Down
11 changes: 4 additions & 7 deletions lua/eca/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ local Logger = require("eca.logger")
---@field on_stop function Callback when the server stops
---Called when a notification is received(message without an ID)
---@field on_notification fun(server: eca.Server, message: table)
---@field capabilities eca.ServerCapabilities Server capabilities
---@field private path_finder eca.PathFinder Server path finder
---@field pending_requests {id: fun(err, data)} -- outgoing requests with callbacks
local M = {}
Expand Down Expand Up @@ -50,7 +49,6 @@ function M.new(opts)
path_finder = opts.path_finder,
messages = {},
pending_requests = {},
capabilities = {},
initialized = false,
next_id = 0,
}, { __index = M })
Expand All @@ -67,7 +65,7 @@ local function on_stdout(server)
if #message.content ~= message.content_length then
return
end
table.insert(messages, message)
table.insert(server.messages, message)
local msg = vim.json.decode(message.content)
server:handle_message(msg)
end)
Expand Down Expand Up @@ -171,20 +169,18 @@ function M:initialize()
},
},
workspaceFolders = workspace_folders,
}, function(err, result)
}, function(err, _)
if err then
Logger.notify("Could not initialize server: " .. err, vim.log.levels.ERROR)
return
end
if result then
self.capabilities = result
end

self:send_notification("initialized", {})

if self.on_initialize then
self.on_initialize()
end
self.initialized = true
end)
end

Expand Down Expand Up @@ -259,6 +255,7 @@ function M:send_request(method, params, callback)
end

local json = vim.json.encode(message)
table.insert(self.messages, { content = json, content_length = #json })
local content = string.format("Content-Length: %d\r\n\r\n%s", #json, json)
self.process:write(content)
end
Expand Down
Loading