Skip to content

Messages API

ChatMessage is the format every provider converts to and from, which is what lets a chat history move between OpenAI, Anthropic, Groq and Mistral unchanged.

from ToolAgents.data_models.messages import ChatMessage
from ToolAgents.data_models.chat_history import ChatHistory

ChatMessage

ChatMessage

Bases: BaseModel

Model representing a chat message in the messaging protocol.

Attributes:

Name Type Description
id str

Unique identifier for the chat message.

role ChatMessageRole

The role of the message sender (e.g., system, user, assistant, tool).

content List[Union[ReasoningContent, TextContent, BinaryContent, ToolCallContent, ToolCallResultContent]]

A list of message content objects that make up the chat message.

created_at datetime

The date and time the message was created.

updated_at datetime

The date and time the message was last updated.

additional_fields Dict[str, Any]

Extra fields for the chat message (e.g., for caching).

additional_information Dict[str, Any]

Extra metadata or information related to the chat message.

token_usage Optional[TokenUsage]

Normalized token usage from the provider response, if available.

from_dictionaries staticmethod

from_dictionaries(
    messages: List[Dict[str, str]],
) -> List[ChatMessage]

Converts a list of dictionaries into a list of ChatMessage objects. Only works with simple text messages that have a role and content.

from_dict staticmethod

from_dict(data: Dict[str, Any]) -> ChatMessage

Converts a dictionary into a ChatMessage object.

to_dict

to_dict() -> Dict[str, Any]

Converts the ChatMessage object to a dictionary.

contains_tool_call

contains_tool_call() -> bool

Returns True if the chat message contains a tool call.

contains_tool_call_results

contains_tool_call_results() -> bool

Returns True if the chat message contains a tool call.

contains_reasoning

contains_reasoning() -> bool

Returns True if the chat message contains any reasoning blocks.

get_tool_calls

get_tool_calls() -> List[ToolCallContent]

Returns a list of ToolCallContent objects.

get_tool_call_results

get_tool_call_results() -> List[ToolCallResultContent]

Returns a list of ToolCallContent objects.

get_reasoning_blocks

get_reasoning_blocks() -> List[ReasoningContent]

Returns a list of ReasoningContent blocks from this message.

get_reasoning_text

get_reasoning_text() -> Optional[str]

Returns concatenated plaintext from all non-redacted reasoning blocks, or None if there are no reasoning blocks.

ChatMessageRole

Bases: str, Enum

Enum representing the role of a chat message sender.

Message content

A message's content is a list of typed parts, so text, reasoning, tool calls and binary attachments coexist in one message.

ContentType

Bases: str, Enum

Enum representing the type of content in a message.

ContentBase

Bases: BaseModel

Base class for all content models.

Attributes:

Name Type Description
type ContentType

The type of the content.

additional_fields Dict[str, Any]

Additional custom fields for content.

TextContent

Bases: ContentBase

Model for text-based content.

Attributes:

Name Type Description
type ContentType

Always 'text' for text content.

content str

The actual text content.

ReasoningContent

Bases: ContentBase

Model for reasoning/thinking blocks produced by reasoning-capable models.

These blocks contain the model's internal reasoning before its final response. They are separate from the visible text response and should be preserved for multi-turn conversations where supported.

For Anthropic models (Claude 3.7+): - thinking: The plaintext reasoning. May be None for redacted blocks. - signature: Anthropic's verification signature. Must be passed back unchanged in subsequent requests to maintain reasoning continuity. - is_redacted: True when Anthropic's safety system has redacted the block. In this case redacted_data holds the opaque payload that must be passed back to the API unchanged.

For OpenAI-compatible models via OpenRouter (e.g. MiMo-V2-Pro): - thinking: The plaintext reasoning string from message.reasoning. - signature / redacted_data: Not used by these providers (None).

Usage

Check for reasoning in a response

for block in message.content: if isinstance(block, ReasoningContent): if block.is_redacted: print("(redacted reasoning block)") else: print("Model reasoning:", block.thinking)

Round-trip back to Anthropic API format for multi-turn

anthropic_block = reasoning_block.to_anthropic_block()

Attributes:

Name Type Description
type ContentType

Always 'reasoning' for reasoning content.

thinking Optional[str]

The plaintext reasoning content from the model.

signature Optional[str]

Anthropic verification signature (must be preserved unchanged).

is_redacted bool

True if this block was safety-filtered by Anthropic.

redacted_data Optional[str]

Opaque payload for redacted blocks (must be preserved unchanged).

to_anthropic_block

to_anthropic_block() -> Dict[str, Any]

Serialise back to the Anthropic API content block format. Use this when passing reasoning blocks back in multi-turn requests.

ToolCallContent

Bases: ContentBase

Model for representing a tool call within a chat message.

Attributes:

Name Type Description
type ContentType

Always 'tool_call' for a tool call.

tool_call_id str

Unique identifier for the tool call.

tool_call_name str

The name of the tool to be invoked.

tool_call_arguments Union[Dict[str, Any] | None | str]

A dictionary of arguments to be passed to the tool.

ToolCallResultContent

Bases: ContentBase

Model for representing the result of a tool call.

Attributes:

Name Type Description
type ContentType

Always 'tool_call_result' for a tool call result.

tool_call_result_id str

Unique identifier for the tool call result.

tool_call_id str

Unique identifier for the corresponding tool call.

tool_call_name str

The name of the tool that produced the result.

tool_call_result str

The result data from the tool call.

BinaryContent

Bases: ContentBase

Model for binary content stored using different methods.

Attributes:

Name Type Description
type ContentType

Always 'binary' for binary content.

storage_type BinaryStorageType

The storage method, e.g., base64 or url.

mime_type str

The MIME type of the binary content.

content str

The actual binary data (base64 encoded or a URL).

BinaryStorageType

Bases: str, Enum

Enum representing the storage method used for binary content. Url for links and Base64 for raw file data.

Streaming and usage

StreamingChatMessage

Bases: BaseModel

Represents a streaming chat API response.

TokenUsage

Bases: BaseModel

Normalized token usage from any provider.

Populated automatically by provider response converters. After the first API call in a conversation, token counts are always available.

Attributes:

Name Type Description
input_tokens int

Number of tokens in the prompt/input.

output_tokens int

Number of tokens in the completion/output.

total_tokens int

Total tokens used (input + output).

details Dict[str, Any]

Optional provider-specific extras (e.g., cache hits, reasoning tokens).

Chat history

ChatHistory

Bases: BaseModel

Model for managing chat history with functionality to load and save to JSON files.

Attributes:

Name Type Description
id str

Unique identifier of the chat history.

title str

Title of the chat history.

messages List[ChatMessage]

List of chat messages in the history

metadata Dict[str, Any]

Optional metadata about the chat history

Chats

Bases: BaseModel

Templates and prompt construction

MessageTemplate fills {placeholder} fields in a prompt string. A placeholder may address a nested value with /, which is how a pipeline step reads a section of its results:

template = MessageTemplate.from_string("Revise {outputs/draft} for {inputs/audience}")
template.generate_message_content(results)

Pass the mapping; do not unpack it

Path resolution needs the structure intact. generate_message_content(results) resolves {outputs/draft}; generate_message_content(**results) flattens the mapping first and the path can no longer resolve. Mixing template_fields with keyword arguments flattens too.

Unmatched placeholders behave differently by shape:

  • A bare name with no matching field is blanked, and a line containing nothing else is dropped (remove_empty_template_field=True, the default).
  • A path that does not resolve is left verbatim, so text that was always literal — {a/b} — survives, and a mistyped path stays visible rather than vanishing.
  • A field whose value is None counts as absent and is blanked, rather than rendering the literal string "None". This changed in 0.3.3 — see the note in the utilities reference.

See the utilities API for the full MessageTemplate reference, and PromptBuilder for assembling multi-part prompts.