Current section
Files
Jump to
Current section
Files
lib/omni/agent/step.ex
defmodule Omni.Agent.Step do
@moduledoc false
alias Omni.Response
@doc """
Starts a linked step process that streams an LLM request.
The step process sends ref-tagged messages back to the parent:
- `{ref, {:event, type, event_map, partial}}` — streaming events to
forward, with the partial `%Response{}` after applying this event
- `{ref, {:complete, %Response{}}}` — successful completion
- `{ref, {:error, reason}}` — failure
Uses `Task.start_link/1` so `$callers` is propagated automatically,
allowing process-ownership registries (Req.Test, Mox) to work.
"""
def start_link(parent, ref, model, context, opts) do
Task.start_link(fn -> run(parent, ref, model, context, opts) end)
end
defp run(parent, ref, model, context, opts) do
try do
case Omni.stream_text(model, context, opts) do
{:ok, sr} ->
response =
Enum.reduce(sr, nil, fn
{:done, _map, response}, _acc ->
response
{:error, reason, _response}, _acc ->
throw({:stream_error, reason})
{type, event_map, partial_response}, _acc ->
send(parent, {ref, {:event, type, event_map, partial_response}})
nil
end)
case response do
%Response{} -> send(parent, {ref, {:complete, response}})
nil -> send(parent, {ref, {:error, :no_response}})
end
{:error, reason} ->
send(parent, {ref, {:error, reason}})
end
rescue
e -> send(parent, {ref, {:error, e}})
catch
{:stream_error, reason} ->
send(parent, {ref, {:error, reason}})
end
end
end