Typed structs for Raxol.Agent.Stream events plus conversion helpers.
Stream.run/2 and Stream.react/2 emit events as bare tuples for
pattern-match ergonomics and backward compatibility:
{:text_delta, "hello"}
{:tool_use, %{name: "linear_graphql", arguments: %{}, id: "call_1"}}
{:tool_result, %{name: "linear_graphql", result: %{...}}}
{:turn_complete, %{content: "...", usage: %{}, iteration: 1}}
{:done, %{content: "...", tool_results: [...], usage: %{}}}
{:error, reason}Consumers that want stronger typing -- e.g., orchestrators forwarding
events to surfaces -- can use from_tuple/1 to lift each tuple into
a typed struct, and to_payload/1 to project it down to a generic
map suitable for telemetry or pubsub.
Both helpers are pure; they do not subscribe to or transform the underlying stream.
Example
stream = Raxol.Agent.Stream.run(prompt, opts)
Enum.each(stream, fn event ->
typed = Raxol.Agent.Stream.Event.from_tuple(event)
send(parent, {:run_event, key, Raxol.Agent.Stream.Event.to_payload(typed)})
end)See Raxol.Agent.EventForwarder for the common "send to parent" pattern
packaged as a single call.
Summary
Functions
Lifts a stream tuple into the corresponding typed struct.
Projects an event (tuple or struct) onto a generic map suitable for telemetry, pubsub, or surface forwarding.
Types
@type tuple_event() :: Raxol.Agent.Stream.event()
Functions
@spec from_tuple(tuple_event() | term()) :: t()
Lifts a stream tuple into the corresponding typed struct.
Unknown shapes return an Error struct rather than raising, so a single
bad event never aborts a forwarding pipeline.
@spec to_payload(t() | tuple_event()) :: map()
Projects an event (tuple or struct) onto a generic map suitable for telemetry, pubsub, or surface forwarding.
All payloads carry :event (atom name), :timestamp, and a :message
string. Specific events add :usage (TurnComplete, Done) or :payload
(ToolUse, ToolResult) when present. The shape mirrors what
Raxol.Symphony.Orchestrator already integrates so existing surface
consumers don't need to change.