AI.Message behaviour (fnord v0.9.40)
View SourceCanonical in-memory representation of conversation messages, modeled after the Responses API item shape.
Each message is a struct from one of the impl modules below. Pattern-matching
on %mod{} dispatches the behaviour callbacks (text/1, for_transcript/1,
to_map/1). Construction goes through the short helpers at this module's
top level (e.g. AI.Message.user/1); persistence and wire serialization go
through to_map/1; hydration from disk or API response goes through
from_map/1.
Impls
AI.Message.User- user input messageAI.Message.Assistant- assistant reply messageAI.Message.System- system/developer instructionAI.Message.FunctionCall- assistant-emitted tool call requestAI.Message.FunctionCallOutput- tool execution resultAI.Message.Reasoning- opaque reasoning item (round-tripped verbatim)
Invariants
FunctionCall.argumentsis ALWAYS a JSON string. Never decode it to a map for persistence - LLM-emitted garbage keys exhaust the BEAM atom table downstream. This is the cliff the previous Responses API attempt drove over; see the "Conversation file corruption" engram memory.- Content for User/Assistant/System is stored as a list of typed parts
matching the wire format (
%{type: "input_text" | "output_text", text: ...}). Thetext/1callback joins the parts back to a single binary.
Summary
Callbacks
Returns a transcript-formatted block (with role headers, tool-call summary,
etc.) suitable for inclusion in AI.Util.research_transcript/1-style
outputs. nil if the message is omitted from transcripts.
Returns the plain-text representation of a message, or nil if the message
has no textual content (e.g. a tool-call request or opaque reasoning blob).
Joins multi-part content lists with newlines.
Serializes a message struct to its on-the-wire (Responses API native) map shape. The result is what gets persisted to disk and sent to the API.
Functions
Build an AI.Message.Assistant from a binary or pre-built content list.
Hydrate a struct from a Responses-API-shaped map. Accepts either atom-keyed or string-keyed maps - on-disk persistence uses string keys; in-memory construction uses atoms.
Same as from_map/1 but raises on unknown shapes. Use when persistence
guarantees the shape (e.g. immediately after a successful Format migration).
Build an AI.Message.FunctionCall. arguments MUST be a JSON-encoded string
(the same form the API returns). Never pass a decoded map - see the module
doc.
Build an AI.Message.FunctionCallOutput from a tool's textual result.
Build an AI.Message.Reasoning from the raw reasoning item map returned by
the API. The struct round-trips the raw shape so reasoning continuity is
preserved when store: false.
Build an AI.Message.System. Role defaults to "developer" (OpenAI's
Responses-era convention); pass role: "system" for providers that prefer
the legacy label.
Build an AI.Message.User from a binary or pre-built content list.
Types
@type t() :: AI.Message.User.t() | AI.Message.Assistant.t() | AI.Message.System.t() | AI.Message.FunctionCall.t() | AI.Message.FunctionCallOutput.t() | AI.Message.Reasoning.t()
Callbacks
Returns a transcript-formatted block (with role headers, tool-call summary,
etc.) suitable for inclusion in AI.Util.research_transcript/1-style
outputs. nil if the message is omitted from transcripts.
Returns the plain-text representation of a message, or nil if the message
has no textual content (e.g. a tool-call request or opaque reasoning blob).
Joins multi-part content lists with newlines.
Serializes a message struct to its on-the-wire (Responses API native) map shape. The result is what gets persisted to disk and sent to the API.
Functions
@spec assistant(binary() | [map()]) :: AI.Message.Assistant.t()
Build an AI.Message.Assistant from a binary or pre-built content list.
Hydrate a struct from a Responses-API-shaped map. Accepts either atom-keyed or string-keyed maps - on-disk persistence uses string keys; in-memory construction uses atoms.
Dispatches on type (and role for "message" items). Unknown shapes
return {:error, {:unknown_message_shape, raw}}.
Same as from_map/1 but raises on unknown shapes. Use when persistence
guarantees the shape (e.g. immediately after a successful Format migration).
@spec function_call(binary(), binary(), binary()) :: AI.Message.FunctionCall.t()
Build an AI.Message.FunctionCall. arguments MUST be a JSON-encoded string
(the same form the API returns). Never pass a decoded map - see the module
doc.
@spec function_call_output(binary(), binary()) :: AI.Message.FunctionCallOutput.t()
Build an AI.Message.FunctionCallOutput from a tool's textual result.
@spec reasoning(map()) :: AI.Message.Reasoning.t()
Build an AI.Message.Reasoning from the raw reasoning item map returned by
the API. The struct round-trips the raw shape so reasoning continuity is
preserved when store: false.
@spec system( binary() | [map()], keyword() ) :: AI.Message.System.t()
Build an AI.Message.System. Role defaults to "developer" (OpenAI's
Responses-era convention); pass role: "system" for providers that prefer
the legacy label.
@spec user(binary() | [map()]) :: AI.Message.User.t()
Build an AI.Message.User from a binary or pre-built content list.