A single LLM request. See spec §5.4.
Layer A — pure serializable data. Carries the :messages list, optional
:model, :tools, :tool_choice, :temperature, :max_tokens,
:response_format, and adapter-opaque :options and :metadata.
Validation lives in ALLM.Validate.request/1 (sub-phase 1.4). Per spec
§9 and the Phase 1 design (non-obvious decision #7), new/2 itself does
not validate — it stays composable so callers can opt into validation
explicitly.
Summary
Functions
Build a %Request{} from a list of messages and keyword opts.
Types
@type t() :: %ALLM.Request{ max_tokens: non_neg_integer() | nil, messages: [ALLM.Message.t()], metadata: map(), model: String.t() | nil, options: map(), response_format: response_format(), stream: boolean(), structured_finalize: boolean(), temperature: number() | nil, tool_choice: tool_choice(), tools: [ALLM.Tool.t()] }
Functions
@spec new( [ALLM.Message.t()], keyword() ) :: t()
Build a %Request{} from a list of messages and keyword opts.
messages is required and becomes the :messages field. opts may set any
other struct field; unknown keys raise ArgumentError via struct!/2.
Examples
iex> req = ALLM.Request.new([%ALLM.Message{role: :user, content: "hi"}])
iex> req.stream
false
iex> length(req.messages)
1
iex> req = ALLM.Request.new([%ALLM.Message{role: :user, content: "hi"}], model: "fake:x", temperature: 0.2)
iex> {req.model, req.temperature}
{"fake:x", 0.2}