Skip to content

Message

Category: Agent

Source: message.dart

Conversation message types and the streaming/agent event vocabulary shared between the agent loop and the LLM strategies.

Status: part of the proposed core data model — see docs/plans/2026-04-29-harness-layers.md. Originally lived in agent/agent_core.dart; relocated so strategies (LLM clients, providers) can depend on these types without violating the layer rule.

The agent loop class itself ([AgentCore]) stays in agent/.

Enums

Role

Role of a message in the conversation.

ValueDescription
user
assistant
toolResult

Classes

Message

A single message in the conversation history.

Constructor

dart
factory Message.user(String text, {List<ContentPart>? contentParts})

Build a user message. Pass [contentParts] for multimodal input (text + images + resource links) — the LLM mappers will serialise them per provider, falling back to [text] for clients that don't support multimodal input.

dart
factory Message.assistant({String? text, List<ToolCall>? toolCalls})
dart
factory Message.toolResult({
    required ToolCallId callId,
    required String content,
    String? toolName,
    List<ContentPart>? contentParts,
  })

Properties

PropertyTypeDescription
roleRole
textString?
toolCallsList&lt;ToolCall&gt;
toolCallIdString?
toolNameString?
contentPartsList&lt;ContentPart&gt;?
textString
textString
idToolCallId
nameString
toolCallToolCall
inputTokensint
outputTokensint
cacheReadTokensint?
cacheCreationTokensint?
totalTokensint get
idToolCallId
nameString
argumentsMap&lt;String, dynamic&gt;
descriptionString
thoughtSignatureString?Provider-specific opaque token that must be echoed back on the next request. Currently set only by the Gemini provider when the model is in thinking mode; null for all other providers. See https://ai.google.dev/gemini-api/docs/thought-signatures.
totalTokensint get

sealed LlmChunk

A chunk emitted by the LLM streaming response.

TextDelta

A delta of generated text.

Constructor

dart
TextDelta(this.text)

Properties

PropertyTypeDescription
textString

ThinkingDelta

A delta of streaming reasoning/"thinking" content. Distinct from [TextDelta] so renderers can style it as deliberative-aside rather than final assistant output.

Only reasoning-capable models emit this — Claude 4.x with extended thinking, GPT-5 / o-series, DeepSeek R1, QwQ, etc. Parsers that don't see thinking blocks simply never yield this variant.

Thinking content is not appended to the assistant message that gets sent back to the model on the next turn — Anthropic explicitly forbids this without the right block structure, and including it would pollute context for other providers.

Constructor

dart
ThinkingDelta(this.text)

Properties

PropertyTypeDescription
textString

ToolCallStart

The model has started a tool call, but the arguments are still streaming in.

Use this to show early UI feedback (e.g. "preparing read_file…") before the full [ToolCallComplete] arrives with parsed arguments.

Not every provider emits this — Ollama delivers tool calls fully formed, so you may only receive [ToolCallComplete]. Always treat this event as optional.

Constructor

dart
ToolCallStart({required this.id, required this.name})

Properties

PropertyTypeDescription
idToolCallId
nameString

ToolCallComplete

A fully-formed tool call with parsed arguments, ready to execute.

Constructor

dart
ToolCallComplete(this.toolCall)

Properties

PropertyTypeDescription
toolCallToolCall

UsageInfo

Token usage reported by the LLM after a response.

[cacheReadTokens] and [cacheCreationTokens] surface provider-native prompt caching statistics when available. Both are nullable: null means the provider did not report the field (e.g. Ollama, or a cache miss on a provider that omits zeroed fields). Distinguish "not reported" from "reported as zero" — that distinction is the difference between a passive read and an unsupported provider.

inputTokens reflects only the uncached input tokens billed at the provider's standard rate. Cache reads are billed separately (Anthropic: 0.1× input price; OpenAI: ~50% discount). Total billed input across the request is roughly: inputTokens + (cacheReadTokens ?? 0) + (cacheCreationTokens ?? 0).

Constructor

dart
UsageInfo({
    required this.inputTokens,
    required this.outputTokens,
    this.cacheReadTokens,
    this.cacheCreationTokens,
  })

Properties

PropertyTypeDescription
inputTokensint
outputTokensint
cacheReadTokensint?
cacheCreationTokensint?
totalTokensint get
totalTokensint get

ToolCall

A tool invocation requested by the model.

Constructor

dart
ToolCall({
    required this.id,
    required this.name,
    required this.arguments,
    this.description = '',
    this.thoughtSignature,
  })

Properties

PropertyTypeDescription
idToolCallId
nameString
argumentsMap&lt;String, dynamic&gt;
descriptionString
thoughtSignatureString?Provider-specific opaque token that must be echoed back on the next request. Currently set only by the Gemini provider when the model is in thinking mode; null for all other providers. See https://ai.google.dev/gemini-api/docs/thought-signatures.

Released under the MIT License.