ALLM.Thread (allm v0.3.0)

Copy Markdown View Source

An ordered message log. See spec §5.6 and §14.

Layer A — pure serializable data. A thread is the canonical container for the message history threaded through a session or chat loop; it is append-only at the API surface (helpers build new threads rather than mutating an existing one).

Summary

Functions

Append an assistant-role message with the given text content.

Append a single message to the end of the thread.

Append multiple messages to the end of the thread, preserving order.

Append a system-role message with the given text content.

Append a user-role message with the given text content.

Build a thread from an existing list of messages.

Return the last message in the thread, or nil when the thread is empty.

Return the ordered list of messages in the thread.

Build a %Thread{} from keyword opts.

Types

t()

@type t() :: %ALLM.Thread{messages: [ALLM.Message.t()], metadata: map()}

Functions

add_assistant(t, text)

@spec add_assistant(t(), String.t()) :: t()

Append an assistant-role message with the given text content.

Examples

iex> ALLM.Thread.new() |> ALLM.Thread.add_assistant("hello") |> ALLM.Thread.last_message()
%ALLM.Message{role: :assistant, content: "hello", name: nil, tool_call_id: nil, metadata: %{}}

add_message(t, m)

@spec add_message(t(), ALLM.Message.t()) :: t()

Append a single message to the end of the thread.

Examples

iex> t = ALLM.Thread.new() |> ALLM.Thread.add_message(%ALLM.Message{role: :user, content: "hi"})
iex> length(t.messages)
1

add_messages(t, more)

@spec add_messages(t(), [ALLM.Message.t()]) :: t()

Append multiple messages to the end of the thread, preserving order.

Examples

iex> t = ALLM.Thread.new() |> ALLM.Thread.add_messages([
...>   %ALLM.Message{role: :user, content: "a"},
...>   %ALLM.Message{role: :assistant, content: "b"}
...> ])
iex> Enum.map(t.messages, & &1.content)
["a", "b"]

add_system(t, text)

@spec add_system(t(), String.t()) :: t()

Append a system-role message with the given text content.

Examples

iex> ALLM.Thread.new() |> ALLM.Thread.add_system("be nice") |> ALLM.Thread.last_message()
%ALLM.Message{role: :system, content: "be nice", name: nil, tool_call_id: nil, metadata: %{}}

add_user(t, text)

@spec add_user(t(), String.t()) :: t()

Append a user-role message with the given text content.

Examples

iex> ALLM.Thread.new() |> ALLM.Thread.add_user("hi") |> ALLM.Thread.last_message()
%ALLM.Message{role: :user, content: "hi", name: nil, tool_call_id: nil, metadata: %{}}

from_messages(messages)

@spec from_messages([ALLM.Message.t()]) :: t()

Build a thread from an existing list of messages.

Examples

iex> t = ALLM.Thread.from_messages([%ALLM.Message{role: :user, content: "hi"}])
iex> length(t.messages)
1

last_message(thread)

@spec last_message(t()) :: ALLM.Message.t() | nil

Return the last message in the thread, or nil when the thread is empty.

Examples

iex> ALLM.Thread.last_message(ALLM.Thread.new())
nil

iex> ALLM.Thread.new()
...> |> ALLM.Thread.add_user("first")
...> |> ALLM.Thread.add_user("last")
...> |> ALLM.Thread.last_message()
...> |> Map.get(:content)
"last"

messages(thread)

@spec messages(t()) :: [ALLM.Message.t()]

Return the ordered list of messages in the thread.

Examples

iex> ALLM.Thread.messages(ALLM.Thread.new())
[]

new(opts \\ [])

@spec new(keyword()) :: t()

Build a %Thread{} from keyword opts.

Examples

iex> ALLM.Thread.new()
%ALLM.Thread{messages: [], metadata: %{}}

iex> ALLM.Thread.new(metadata: %{trace: "x"}).metadata
%{trace: "x"}