ATIF-v1.8 projection of ordered native Imp.Run.Event observations.
to_atif/2 projects one run's ordered events into a JSON-encodable ATIF
document that reads as the model saw the run:
- The first request's messages are steps marked as copied context, with their roles, an assistant message's tool calls and reasoning, and each tool message as the observation of the call it answers. A user or system message a later request appends is a step of its own.
- Each model response is one agent step (
llm_call_count: 1, or null for a response served from Imp's cache) with the response text asmessage, the provider's own reasoning asreasoning_content, the calls the loop dispatched for it astool_calls,model_name, andmetricsfrom its usage and cost. - A tool result's
contentis the tool message the model read in the next request, which may be shortened or rendered differently from what the tool returned.extra.seen_by_modelsays whether a later request carried it; when the two differ, the tool's own output is kept inextra.output. - A tool call no model response asked for, such as one a host dispatches
itself, is a step of its own with
llm_call_count: 0. agent.tool_definitionsholds every tool roster the run sent (from:tools_sent),agent.model_namethe model when every request used the same one, andfinal_metricsthe run's token and cost totals where every response reported them.
Every model request is also listed whole in extra.model_requests.
Lifecycle events and capture gaps become entries in extra.diagnostics
rather than dialogue steps. A loop's :reasoning event is the visible
thought a step wrote, which the response already carries, so it is kept on
that response step as extra.next_thought. extra.terminal_event is the
kind of the event that ended the run ("run_finished", "run_failed",
"run_cancelled"), or "unknown" when the events hold none.
A tool result's extra.outcome, on the result and on its call, is the
Imp.Tool.outcome/0 the loop recorded on the :tool_result event
(metadata.outcome); an event that carries none, and a call whose result was
not captured, is "unknown".
Stored event maps are read by their "kind". A kind that is not one of
Imp.Run.Event.kinds/0, such as one a host emitted itself, keeps its stored
string and becomes a diagnostic entry.
Inference counts, metrics, reasoning and tool results are never synthesized
from missing evidence. Step tool call IDs are scoped by run and event
sequence, with the provider's ID in extra.native_tool_call_id. A provider
tool call ID may be reused once its result has arrived, but an overlapping
reuse raises ArgumentError.
The document is a projection, not a replay and not a durable effect ledger. Redaction runs again on export, including caller metadata; prompts and results are still private application data.
Summary
Functions
Builds a JSON-encodable ATIF document from one run's ordered events or stored event maps.