ExAthena.Loop.Events (ExAthena v0.4.4)

Copy Markdown View Source

Flat, pattern-matchable event tuples the loop emits to :on_event.

Event shape inspired by ash_ai's ToolLoop.stream/2 — one tuple per logical event, exhaustive, easy to match on in LiveView handlers, OTel emitters, and cost trackers. Same events feed the OpenTelemetry span emitter (landing in PR 4).

Events:

  • {:content, text} — partial or full assistant text.
  • {:tool_call, ToolCall.t()} — model requested a tool call.
  • {:tool_result, ToolResult.t()} — tool produced a result (or error).
  • {:tool_ui, %{tool_call_id:, kind:, payload:}} — structured UI payload for hosts that render rich previews (diffs, file contents, process output). Only emitted when a tool returns the {:ok, %{llm:, ui:}} shape; the LLM-facing string still flows through :tool_result.
  • {:iteration, n} — a new iteration is starting.
  • {:compaction, %{before:, after:, reason:}} — context compacted.
  • {:subagent_spawn, %{id:, prompt:}} — a sub-agent started.
  • {:subagent_result, %{id:, text:}} — sub-agent returned.
  • {:usage, usage_map} — partial usage report from the provider.
  • {:structured_retry, %{attempt:, error:}} — extract_structured retry.
  • {:error, reason} — non-fatal warning (the loop continues).
  • {:done, Result.t()} — terminal event. Always the last event emitted; the Result carries the finish_reason.

Summary

Functions

Emit an event via the supplied callback (nil is a no-op).

Types

t()

@type t() ::
  {:content, String.t()}
  | {:tool_call, ExAthena.Messages.ToolCall.t()}
  | {:tool_result, ExAthena.Messages.ToolResult.t()}
  | {:tool_ui, %{tool_call_id: String.t(), kind: atom(), payload: map()}}
  | {:iteration, non_neg_integer()}
  | {:compaction, %{before: integer(), after: integer(), reason: term()}}
  | {:subagent_spawn, %{id: term(), prompt: String.t()}}
  | {:subagent_result, %{id: term(), text: String.t()}}
  | {:usage, map()}
  | {:structured_retry, %{attempt: non_neg_integer(), error: term()}}
  | {:error, term()}
  | {:done, ExAthena.Result.t()}

Functions

emit(callback, event)

@spec emit((t() -> term()) | nil, t()) :: :ok

Emit an event via the supplied callback (nil is a no-op).