defmodule AI do @moduledoc """ Minimal public API for streaming text and tool calls. """ @type role :: String.t() @type message :: %{required(:role) => role(), optional(:content) => term()} @type tool_opts :: %{ required(:name) => String.t(), required(:description) => String.t(), required(:input_schema) => map(), required(:execute) => (map() -> term()) | (map(), map() -> term()) } @type stream_text_opts :: %{ required(:model) => AI.Model.t(), optional(:prompt) => String.t() | [message()], optional(:messages) => [message()], optional(:system) => String.t(), optional(:tools) => %{optional(String.t()) => AI.Tool.t()}, optional(:tool_choice) => :auto | :none | :required | %{tool: String.t()}, optional(:max_steps) => pos_integer(), optional(:temperature) => number(), optional(:max_tokens) => pos_integer(), optional(:stop) => [String.t()] | String.t(), optional(:headers) => map(), optional(:timeout) => pos_integer() } @type stream_event :: {:response_id, String.t() | integer()} | {:text_start, String.t() | integer()} | {:text_delta, String.t() | integer(), String.t()} | {:text_end, String.t() | integer()} | {:tool_call, map()} | {:tool_result, map()} | {:finish, map()} | {:error, term()} | {:raw, term()} @doc """ Starts a streaming request and returns a stream of normalized events. See `AI.StreamText.stream_text/1` for the full option list and event shapes. """ @spec stream_text(stream_text_opts()) :: {:ok, Enumerable.t()} | {:error, term()} def stream_text(opts), do: AI.StreamText.stream_text(opts) @doc """ Builds a tool definition from keyword or map options. """ @spec tool(tool_opts() | keyword()) :: AI.Tool.t() def tool(opts), do: AI.Tool.new(opts) end