message

package
v0.0.0-beta Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 30, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package message defines the Message type and Messages collection for LLM conversations, including filtering, compaction, export, and rendering.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ExportConversation

type ExportConversation struct {
	Messages []ExportMessage `json:"messages"`
}

ExportConversation wraps exported messages for JSON output.

type ExportMessage

type ExportMessage struct {
	Role       string      `json:"role"`
	Content    string      `json:"content,omitempty"`
	Thinking   string      `json:"thinking,omitempty"`
	ToolCalls  []call.Call `json:"tool_calls,omitempty"`
	ToolName   string      `json:"tool_name,omitempty"`
	ToolCallID string      `json:"tool_call_id,omitempty"`
	CreatedAt  *time.Time  `json:"created_at,omitempty"`
}

ExportMessage is a clean representation of a message for export. It excludes internal fields (tokens, images, thinking signature, etc.).

type Image

type Image struct {
	Data []byte
}

Image represents an image attached to a message as raw bytes. Providers handle encoding (base64 data URL, raw bytes, etc.) in their own convert layer.

func (Image) DataURL

func (i Image) DataURL() string

DataURL returns the image as a base64-encoded JPEG data URL. Used by OpenAI-compatible providers (OpenRouter, LlamaCPP) in their message conversion.

type Images

type Images []Image

Images is a collection of images.

type Message

type Message struct {
	// ID uniquely identifies this message (for UI tracking).
	ID string
	// Role is the message sender (user, assistant, system, tool).
	Role roles.Role
	// Content is the main message text.
	Content string
	// Thinking contains reasoning or internal thought process.
	Thinking string `json:",omitempty"`
	// ThinkingSignature is an opaque signature for thinking blocks (Anthropic, Google).
	// Must be preserved unmodified when round-tripping multi-turn conversations.
	ThinkingSignature string `json:"thinking_signature,omitempty"`
	// Images contains attached images for vision models.
	Images Images `json:"images,omitempty"`
	// Calls contains tool invocation requests from the assistant.
	Calls []call.Call `json:"calls,omitempty"`
	// ToolName is the name of the tool that produced this result.
	ToolName string `json:"tool_name,omitempty"`
	// ToolCallID links this tool result to its original call.
	ToolCallID string `json:"tool_call_id,omitempty"`
	// Type classifies the message (Normal, Synthetic, Ephemeral, DisplayOnly, Bookmark, Metadata).
	Type Type `json:"type,omitempty"`
	// Parts contains ordered content for incremental UI rendering.
	Parts []part.Part `json:"-"`
	// Error is set if an error occurred during message generation.
	Error error `json:"-"`
	// Tokens holds per-message token counts (exact from API or estimated).
	Tokens Tokens `json:"tokens,omitzero"`
	// CreatedAt is when the message was created.
	CreatedAt time.Time `json:"created_at,omitzero"`
}

Message represents a single chat message with optional tool calls. This unified type serves both API communication and UI display.

func (Message) ForLog

func (m Message) ForLog() string

ForLog returns a formatted string for log file output.

func (Message) ForTranscript

func (m Message) ForTranscript() string

ForTranscript returns a compact representation for compaction transcripts. Tool result content is included as-is; callers should pre-truncate if needed.

func (Message) IsAssistant

func (m Message) IsAssistant() bool

IsAssistant returns true if the message has the assistant role.

func (Message) IsBookmark

func (m Message) IsBookmark() bool

IsBookmark returns true if this is a bookmark message (structural divider).

func (Message) IsDisplayOnly

func (m Message) IsDisplayOnly() bool

IsDisplayOnly returns true if this is a display-only message (UI-visible, never sent to LLM).

func (Message) IsEmpty

func (m Message) IsEmpty() bool

IsEmpty returns true if the message has no content, thinking, or tool calls.

func (Message) IsEphemeral

func (m Message) IsEphemeral() bool

IsEphemeral returns true if this is an ephemeral message (visible for one turn, then pruned).

func (Message) IsInternal

func (m Message) IsInternal() bool

IsInternal returns true for types that should never reach any LLM (neither primary chat nor compaction agent).

func (Message) IsMetadata

func (m Message) IsMetadata() bool

IsMetadata returns true if this is a metadata message (structured data, not rendered).

func (Message) IsSynthetic

func (m Message) IsSynthetic() bool

IsSynthetic returns true if this is a synthetic message.

func (Message) IsSystem

func (m Message) IsSystem() bool

IsSystem returns true if the message has the system role.

func (Message) IsTool

func (m Message) IsTool() bool

IsTool returns true if the message has the tool role.

func (Message) IsUser

func (m Message) IsUser() bool

IsUser returns true if the message has the user role.

func (*Message) ReconstructParts

func (m *Message) ReconstructParts()

ReconstructParts rebuilds the Parts slice from serialized fields. Called automatically by UnmarshalJSON. Can also be called directly when Parts need rebuilding outside of JSON deserialization.

func (Message) Render

func (m Message) Render() string

Render converts the message into a human-readable text representation.

func (*Message) UnmarshalJSON

func (m *Message) UnmarshalJSON(data []byte) error

UnmarshalJSON deserializes a Message from JSON and reconstructs Parts. Parts has json:"-" so it's lost during serialization; this ensures Parts are always populated after loading from any JSON source.

type Messages

type Messages []Message

Messages is a collection of chat messages.

func New

func New(messages ...Message) Messages

New creates a Messages collection from the given messages.

func (*Messages) Add

func (ms *Messages) Add(msg Message)

Add appends a message to the collection.

func (*Messages) Clear

func (ms *Messages) Clear()

Clear removes all messages except the first (system prompt) from the collection. If only one message exists, it is preserved as-is.

func (*Messages) DropN

func (ms *Messages) DropN(n int)

DropN removes the last n messages from the collection.

func (*Messages) EjectEphemeralMessages

func (ms *Messages) EjectEphemeralMessages()

EjectEphemeralMessages removes ephemeral tool result messages and their matching calls from assistant messages. This is paired removal — both the tool result and the call that triggered it are stripped, preventing orphaned tool results that Anthropic/Google would reject.

func (Messages) ExportJSON

func (ms Messages) ExportJSON() ([]byte, error)

ExportJSON returns the conversation as indented JSON. Uses structured export (includes Metadata) for machine-readable output.

func (Messages) ExportJSONL

func (ms Messages) ExportJSONL() ([]byte, error)

ExportJSONL returns the conversation as newline-delimited JSON (one message per line). Uses structured export (includes Metadata) for machine-readable output.

func (Messages) ExportMessages

func (ms Messages) ExportMessages() []ExportMessage

ExportMessages converts the message history to clean export structs for human-readable formats. Excludes Synthetic, Ephemeral, Metadata.

func (Messages) ExportStructuredMessages

func (ms Messages) ExportStructuredMessages() []ExportMessage

ExportStructuredMessages converts the message history to clean export structs for machine-readable formats. Excludes Synthetic, Ephemeral. Includes Metadata.

func (Messages) ForCompaction

func (ms Messages) ForCompaction(maxResultLen int) Messages

ForCompaction returns messages to send to the compaction LLM. Excludes Synthetic, Ephemeral, internal types, and thinking content. Tool results are truncated to maxResultLen characters.

func (Messages) ForDisplay

func (ms Messages) ForDisplay() Messages

ForDisplay returns messages suitable for UI rendering on session restore. Excludes System role, Tool role, Metadata. Includes Normal (user/assistant), DisplayOnly, Bookmark.

func (Messages) ForExport

func (ms Messages) ForExport() Messages

ForExport returns messages for human-readable export (plaintext, markdown). Excludes Synthetic, Ephemeral, Metadata. Includes Normal, DisplayOnly, Bookmark.

func (Messages) ForExportStructured

func (ms Messages) ForExportStructured() Messages

ForExportStructured returns messages for machine-readable export (JSON, JSONL). Excludes Synthetic, Ephemeral. Includes Normal, DisplayOnly, Bookmark, Metadata.

func (Messages) ForLLM

func (ms Messages) ForLLM() Messages

ForLLM returns messages to send to the LLM provider. Excludes internal types (DisplayOnly, Bookmark, Metadata). Includes Normal, Synthetic (one-turn influence), Ephemeral (one-turn errors).

func (Messages) ForPreservation

func (ms Messages) ForPreservation() Messages

ForPreservation returns messages safe to keep after compaction. Only retains Normal messages — strips one-turn types (Synthetic, Ephemeral) and internal types (DisplayOnly, Bookmark, Metadata).

func (Messages) ForSave

func (ms Messages) ForSave() Messages

ForSave returns messages to persist in session files. Excludes Ephemeral (one-turn, paired with tool calls). Includes Normal, Synthetic, DisplayOnly, Bookmark, Metadata.

func (*Messages) KeepFirstByRole

func (ms *Messages) KeepFirstByRole(role roles.Role)

KeepFirstByRole retains only the first message with the specified role, removing all others.

func (Messages) Last

func (ms Messages) Last() *Message

Last returns a pointer to the last message, or nil if empty.

func (*Messages) PruneEmptyAssistantMessages

func (ms *Messages) PruneEmptyAssistantMessages()

PruneEmptyAssistantMessages removes assistant messages with no content, thinking, or tool calls.

func (Messages) PruneToolResults

func (ms Messages) PruneToolResults(protectTokens, argThreshold int, estimate func(string) int) Messages

PruneToolResults returns a copy with old tool results and large tool call arguments replaced by short placeholders. Walks backward, accumulating token distance from the end — messages beyond protectTokens are pruned.

func (Messages) PruneToolResultsInPlace

func (ms Messages) PruneToolResultsInPlace(protectTokens, argThreshold int, estimate func(string) int)

PruneToolResultsInPlace is the mutating variant of PruneToolResults.

func (Messages) Render

func (m Messages) Render() string

Render converts the messages into a human-readable text representation.

func (Messages) RenderMarkdown

func (ms Messages) RenderMarkdown() string

RenderMarkdown returns the conversation as formatted Markdown. Tool results are paired inline under their matching tool call.

func (Messages) Save

func (m Messages) Save(filename string) error

Save writes the messages to a log file with formatted output.

func (Messages) TokensForEstimation

func (ms Messages) TokensForEstimation() int

TokensForEstimation returns the token count of messages that affect context budget. Excludes internal types (tokens that never reach the LLM).

func (Messages) TotalTokens

func (ms Messages) TotalTokens() int

TotalTokens returns the sum of Tokens.Total across all messages.

func (*Messages) TrimDuplicateSynthetics

func (ms *Messages) TrimDuplicateSynthetics()

TrimDuplicateSynthetics keeps only the most recent occurrence of each synthetic message, removing older duplicates. Non-synthetic messages are always kept.

func (Messages) TruncateResults

func (ms Messages) TruncateResults(maxLen int) Messages

TruncateResults truncates tool role message content to maxLen characters.

func (Messages) Truncated

func (ms Messages) Truncated(maxLen int) Messages

Truncated returns a copy with ephemeral messages removed and tool results truncated.

func (Messages) WithoutEphemeralMessages

func (ms Messages) WithoutEphemeralMessages() Messages

WithoutEphemeralMessages returns a copy of the Messages without ephemeral messages.

func (Messages) WithoutInternalMessages

func (ms Messages) WithoutInternalMessages() Messages

WithoutInternalMessages returns a copy of the Messages without internal messages (DisplayOnly, Bookmark, Metadata) — types that should never reach any LLM.

func (Messages) WithoutSyntheticMessages

func (ms Messages) WithoutSyntheticMessages() Messages

WithoutSyntheticMessages returns a copy of the Messages without synthetic messages.

func (Messages) WithoutThinking

func (ms Messages) WithoutThinking() Messages

WithoutThinking returns a copy with thinking fields cleared from all messages.

type Tokens

type Tokens struct {
	// Total is the overall token count for this message.
	// Assistant: exact from usageData.Output (API-reported).
	// Tool: delta-backfilled from API usage (exact).
	// User: estimated at creation time.
	Total int `json:"total,omitempty"`
	// Content is the estimated token count for the message content.
	// Populated via provider tokenizer (estimateTokens). Assistant messages only.
	Content int `json:"content,omitempty"`
	// Thinking is the estimated token count for the thinking/reasoning content.
	// Populated via provider tokenizer (estimateTokens). Assistant messages only.
	Thinking int `json:"thinking,omitempty"`
	// Tools is Total - Content - Thinking. Assistant messages only.
	// Captures the actual cost of tool call JSON, argument encoding, special tokens.
	// Derived as the exact remainder — avoids estimating structured JSON where estimation is worst.
	Tools int `json:"tools,omitempty"`
}

Tokens holds token counts for a message.

func (Tokens) String

func (t Tokens) String() string

String returns a compact summary of token counts.

type Type

type Type int

Type represents the type of message.

const (
	// Normal represents a standard message — persists, sent to LLM, saved, exported.
	Normal Type = iota
	// Synthetic represents an injector-generated message — sent to LLM one turn, ejected.
	Synthetic
	// Ephemeral represents error feedback — sent to LLM one turn, ejected with paired call.
	Ephemeral
	// DisplayOnly represents a UI notification — visible, persisted, never sent to LLM.
	DisplayOnly
	// Bookmark represents a structural divider — rendered as separator, never sent to LLM.
	Bookmark
	// Metadata represents structured data — not rendered, not sent to LLM, exported in JSON.
	Metadata
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL