Conversation context that accumulates messages for LLM projection.
A minimal context implementation that stores conversation history and projects it directly to ReqLLM message format. No policies, no windowing, no snapshots - just append and project.
Design Principle
Context = List of Messages. Projection = Context + System Prompt.
Usage
alias Jido.AI.Context
# Create a new context
context = Context.new(system_prompt: "You are helpful.")
# Accumulate messages
context = context
|> Context.append_user("Hello!")
|> Context.append_assistant("Hi there!")
# Project to ReqLLM format
messages = Context.to_messages(context)Multi-turn Conversations
The context accumulates the full conversation history, enabling multi-turn conversations where the LLM has access to prior context.
Summary
Functions
Append an entry to the thread.
Append an assistant message to the thread, optionally with tool calls and thinking content.
Convert a list of raw message maps to thread entries and append them.
Append a tool result to the thread.
Append a user message to the thread.
Clear all entries from the thread (keeps system prompt and ID).
Returns a debug-friendly view of the thread contents.
Check if the thread is empty (no entries).
Get the last assistant response content.
Get the last entry in the thread.
Count of entries in the thread.
Create a new thread.
Pretty-prints the thread to the console for IEx debugging.
Project thread to ReqLLM message format.
Types
@type t() :: %Jido.AI.Context{ entries: [Jido.AI.Context.Entry.t()], id: String.t(), system_prompt: String.t() | nil }
Functions
@spec append(t(), Jido.AI.Context.Entry.t()) :: t()
Append an entry to the thread.
If the entry already has a timestamp, it is preserved. Otherwise, the current UTC time is set.
Note: Entries are stored in reverse order internally for O(1) append performance.
They are reversed to chronological order when projected via to_messages/2.
Append an assistant message to the thread, optionally with tool calls and thinking content.
Convert a list of raw message maps to thread entries and append them.
Useful for importing existing conversation history.
@spec append_tool_result( t(), String.t(), String.t(), String.t() | [ReqLLM.Message.ContentPart.t()], keyword() ) :: t()
Append a tool result to the thread.
@spec append_user(t(), String.t() | [ReqLLM.Message.ContentPart.t()], keyword()) :: t()
Append a user message to the thread.
Clear all entries from the thread (keeps system prompt and ID).
Returns a debug-friendly view of the thread contents.
Options
:last- Number of entries to include (default: all):truncate- Max content length before truncation (default: 200)
Example
Thread.debug_view(thread, last: 5, truncate: 100)
# %{
# id: "abc123",
# length: 12,
# system_prompt: "You are a weather...",
# entries: [...]
# }
Check if the thread is empty (no entries).
Get the last assistant response content.
@spec last_entry(t()) :: Jido.AI.Context.Entry.t() | nil
Get the last entry in the thread.
@spec length(t()) :: non_neg_integer()
Count of entries in the thread.
Create a new thread.
Options
:id- Thread ID (auto-generated if not provided):system_prompt- System prompt to prepend to projected messages
@spec pp(t()) :: :ok
Pretty-prints the thread to the console for IEx debugging.
Prints each message with its role and content in a readable format.
Example
Thread.pp(thread)
# [system] You are a weather assistant...
# [user] What's the weather in Seattle?
# [asst] <tool: get_weather>
# [tool] {"temp": 62, "conditions": "cloudy"}
# [asst] The weather is 62°F and cloudy.
Project thread to ReqLLM message format.
Returns a list of message maps suitable for passing to ReqLLM.
Options
:limit- Maximum number of entries to include (takes last N, preserves system prompt)