Skip to documentation
Documentation navigation

Documentation navigation

Documentation / guides

AIMessage

Represent assistant text, reasoning, tool calls, and normalized usage.

developer

AIMessage is the assistant turn returned by an inference client. Its blocks may contain text, thinking, and tool-use requests in the order the provider produced them. It optionally carries normalized token usage.

API surface

type AIMessage struct {
	Message
	Usage *Usage
}
package main

import (
	"encoding/json"
	"github.com/looprig/core/content"
)

func main() {
	assistant := &content.AIMessage{Message: content.Message{
		Role: content.RoleAssistant,
		Blocks: []content.Block{
			&content.ThinkingBlock{Thinking: "check the source", Signature: "sig"},
			&content.TextBlock{Text: "Here is the answer."},
			&content.ToolUseBlock{ID: "call-1", Name: "search", Input: json.RawMessage(`{"q":"facts"}`)},
		},
	}}
	_ = assistant
}

Usage is optional. A non-nil usage value is validated on JSON marshal and unmarshal; in particular, ReasoningTokens cannot exceed OutputTokens. Thinking blocks are not text blocks, so structured-output extraction ignores them while preserving their position in the assistant message.

Ordering and tool calls

Provider codecs may emit thinking before text and tool calls after text. Preserve the Blocks order. A tool runner should execute each ToolUseBlock, then append a ToolResultMessage that carries the matching ID.

Proof

Related: ThinkingBlock, ToolUseBlock, Assistant messages.

← back to documentation