defmodule LoomEx do @moduledoc """ LoomEx — An Elixir framework for weaving AI agents from OTP primitives. ## Single execution {:ok, result} = LoomEx.run(MyAgent, [LoomEx.Message.user("Hello!")], sink: fn {:text_delta, d} -> IO.write(d); _ -> :ok end) ## Long-lived agent {:ok, pid} = LoomEx.start_agent(MyAgent, context: %{user_id: 1}) {:ok, result} = LoomEx.call(pid, "Hello!", sink: fn _ -> :ok end) {:ok, result} = LoomEx.call(pid, "Follow up question") messages = LoomEx.get_messages(pid) """ alias LoomEx.Agent.{Runner, Server} @spec run(module(), [LoomEx.Message.t()], keyword()) :: {:ok, LoomEx.Agent.Result.t()} | {:error, term()} def run(agent_module, messages, opts \\ []) do Runner.run(agent_module, messages, opts) end @spec start_agent(module(), keyword()) :: {:ok, pid()} | {:error, term()} def start_agent(agent_module, opts \\ []) do DynamicSupervisor.start_child( LoomEx.AgentSupervisor, {Server, {agent_module, opts}} ) end @spec call(GenServer.server(), String.t(), keyword()) :: {:ok, LoomEx.Agent.Result.t()} | {:error, term()} def call(pid, message, opts \\ []) do Server.call(pid, message, opts) end @spec get_messages(GenServer.server()) :: [LoomEx.Message.t()] def get_messages(pid) do Server.get_messages(pid) end end