ExAthena.Chat.Tui.Runner (ExAthena v0.13.0)

Copy Markdown View Source

Bridges ExAthena.run/2 with the ExAthena.Chat.Tui App process.

Owns three responsibilities:

  • build_run_opts/2 — the keyword list passed to ExAthena.run/2, with sane defaults for local providers (Ollama, llama.cpp) and a finite-but generous 24h request timeout so a slow-thinking local model doesn't trip the default 60s timeout.
  • select_initial_model/2 — reconciles a desired model against what's actually installed, returning {:ok, _}, {:fallback, _}, or {:error, _} so the App can decide how to surface the result.
  • start/2 / start/3 — spawn an unsupervised Task that runs the agent loop, sending {:athena_event, _} for each loop event and a terminal {:athena_done, _} or {:athena_error, _} when the run finishes. The task body is wrapped in try/rescue/catch so failures always reach the App (per the CLAUDE.md "Task.start silently swallows crashes" rule).

Summary

Functions

build_callback(target_pid)

@spec build_callback(pid()) :: (term() -> :ok)

build_run_opts(session, callback)

@spec build_run_opts(ExAthena.Chat.Session.t(), (term() -> term())) :: keyword()

select_initial_model(desired, arg)

@spec select_initial_model(String.t(), {:ok, [String.t()]} | {:error, term()}) ::
  {:ok, String.t()}
  | {:fallback, String.t()}
  | {:error, :no_models | :ollama_unreachable | :llamacpp_unreachable | term()}

start(session, target_pid)

@spec start(ExAthena.Chat.Session.t(), pid()) :: pid()

start(session, target_pid, extra_opts)

@spec start(ExAthena.Chat.Session.t(), pid(), keyword()) :: pid()