Everything sent to the LLM in a single request: system prompt, conversation history, and available tools.
Inference parameters (temperature, max_tokens, etc.) are NOT stored here —
they are passed as keyword options at the Planck.AI.stream/3 or
Planck.AI.complete/3 call site and forwarded directly to req_llm.
Examples
iex> %Planck.AI.Context{
...> system: "You are a helpful coding assistant.",
...> messages: [
...> %Planck.AI.Message{role: :user, content: [{:text, "Hello"}]}
...> ],
...> tools: []
...> }
Summary
Functions
Rough token estimate for the entire request this context represents — system prompt, conversation, and tool schemas.
Types
@type t() :: %Planck.AI.Context{ messages: [Planck.AI.Message.t()], system: String.t() | nil, tools: [Planck.AI.Tool.t()] }
Functions
@spec estimate_tokens(t()) :: non_neg_integer()
Rough token estimate for the entire request this context represents — system prompt, conversation, and tool schemas.
A live "how much context is used" figure needs all three: the system
prompt alone is routinely the largest single piece (tool guidance,
skills, AGENTS.md), and tool schemas sent on every request can be
substantial too once several tools are registered — estimating only the
conversation messages undercounts by everything actually sent alongside
them. This is the actual t() about to be (or just was) sent, not a
reconstruction of it from separate pieces that can drift out of sync
with each other. This is also the one place per-content-part token
counting is written — a caller holding Planck.Agent.Message.t() structs
converts via Planck.Agent.Message.to_ai_messages/1 and wraps the result
in a bare %__MODULE__{} (system/tools left at their defaults for a
messages-only estimate) rather than duplicating this logic for its own
message type.