Built-in tool that exposes Language Server Protocol queries to the model.
Dispatches four LSP actions — definition, references, hover,
diagnostics — by delegating to the running ExAthena.Lsp.Client for the
file's language, managed by ExAthena.Lsp.Manager.
Before every position-based request the tool sends textDocument/didOpen
so the server has an up-to-date buffer. Repeated didOpen calls are
tolerated by LSP servers — they re-sync the buffer.
The diagnostics action reads push-cached diagnostics
(textDocument/publishDiagnostics notifications stored by the client).
It polls every 50 ms up to @diagnostics_poll_ms (default 1 500 ms,
overridable via config :ex_athena, :lsp_diagnostics_poll_ms, ms).
Servers that only support the LSP 3.17 pull protocol return an empty list —
this is a valid result, not an error.
Compact schema line
lsp(action: string, file: string, line?: integer, character?: integer, include_declaration?: boolean) — Query LSP for definition / references / hover / diagnostics.Position params
line and character are 0-indexed (LSP wire format). The read
tool returns 1-indexed line prefixes — subtract 1 before passing here.
Return shape
{:ok, formatted_string, ui_payload} on success.
formatted_string per action:
definition—path:line:colentries joined by newline.references— count header + onepath:line:colper line.hover— stripped markdown value string.diagnostics—<severity>: <message> at :<line>:<col>per line, or"count: 0"when none.
ui_payload — %{kind: :lsp, payload: %{action: atom, file: path, results: list}}.
Errors
{:error, :missing_action}—"action"key absent.{:error, :invalid_action}— unrecognised action string.{:error, :missing_file}—"file"key absent.{:error, :missing_position}—line/characterabsent for position actions.{:error, :unsupported_language}— no LSP server for the file's extension.{:error, {:lsp_error, map}}— server replied with a JSON-RPC error object.{:error, :timeout}— LSP request exceeded the default 30 s timeout.{:error, {:lsp_port_exit, status}}— server process died mid-flight.