How to Format Messages for aisuite Chat Completions API
The aisuite Chat Completions API accepts a list of Message objects (or equivalent dictionaries) containing role, content, and optional tool call fields, which the library converts to provider-specific formats via OpenAICompliantMessageConverter.
Formatting messages correctly for the andrewyng/aisuite library ensures seamless interoperability across multiple LLM providers. The Chat Completions endpoint expects structured conversation data that mirrors the OpenAI Chat API specification, using specific data models defined in the framework to represent chat turns, tool calls, and function parameters.
Core Data Models
The Message Class
At the heart of aisuite's message formatting is the Message class located in aisuite/framework/message.py. This model represents a single turn in the conversation and contains the following fields:
role: Required. Must be one of"system","user","assistant", or"tool"content: Required. The text content of the messagetool_calls: Optional. A list ofChatCompletionMessageToolCallobjects when the assistant invokes functionsreasoning_content: Optional. Stores internal reasoning or "thinking" content that can be displayed separately from the main responserefusal: Optional. Indicates if the model refused to generate content
Tool Call and Function Models
For function calling workflows, aisuite uses two additional models defined in the same file:
ChatCompletionMessageToolCall: Represents a specific tool invocation with fields forid,type(always"function"), andfunctionFunction: Contains thenameof the function being called and itsargumentsas a JSON-serializable string
Message Format Rules
When assembling your conversation history, adhere to these structural requirements:
- Chronological ordering – Messages must appear in sequence, starting with the system prompt (if used), followed by alternating user and assistant turns
- Role restrictions – Only four roles are supported:
"system","user","assistant", and"tool" - Tool call syntax – Assistant messages that trigger functions must include a
tool_callslist containingChatCompletionMessageToolCallobjects - Tool result formatting – Responses from executed functions must be sent back as messages with
role="tool"andcontentcontaining the stringified result - Reasoning handling – Place internal reasoning chains in
reasoning_content; the converter automatically strips therefusalfield when processing requests
How Message Conversion Works
Before sending to the underlying provider, Chat.completions.create() forwards your message list to OpenAICompliantMessageConverter.convert_request in aisuite/providers/message_converter.py. This converter transforms Message objects (or plain dictionaries) into the exact JSON structure required by the specific LLM provider, handling role mappings and parameter normalization automatically.
Code Examples
Basic User-Assistant Exchange
from aisuite.framework.message import Message
messages = [
Message(role="system", content="You are a helpful assistant."),
Message(role="user", content="What is the capital of France?"),
]
response = client.chat.completions.create(
model="openai:gpt-4o-mini",
messages=messages,
)
print(response.choices[0].message.content) # → Paris
Function Calling Workflow
from aisuite.framework.message import Message, ChatCompletionMessageToolCall, Function
# 1️⃣ Assistant asks the model to run a tool
assistant_msg = Message(
role="assistant",
content="",
tool_calls=[
ChatCompletionMessageToolCall(
id="tool-1",
function=Function(name="search_web", arguments='{"query":"latest AI news"}')
)
],
)
messages = [
Message(role="system", content="You can search the web for up‑to‑date info."),
Message(role="user", content="Give me the latest AI headlines."),
assistant_msg,
]
# 2️⃣ Send to the model – provider will see the tool spec in the payload
response = client.chat.completions.create(
model="openai:gpt-4o-mini",
messages=messages,
tools=[ # declare the available tool for the provider
{
"type": "function",
"function": {
"name": "search_web",
"description": "Search the web and return results.",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Search query"}
},
"required": ["query"]
},
},
}
],
)
# 3️⃣ The provider returns a tool call – extract it:
tool_call = response.choices[0].message.tool_calls[0]
# Execute the real tool (here we just mock a result)
tool_result = {"results": ["AI‑generated art beats humans", "New GPT‑5 rumors"]}
# 4️⃣ Feed the tool result back as a new message
tool_msg = Message(
role="tool",
content=str(tool_result), # content must be JSON‑serialisable string
tool_calls=[tool_call] # keep the original call id for correlation
)
messages.append(tool_msg)
# 5️⃣ Continue the conversation
final = client.chat.completions.create(
model="openai:gpt-4o-mini",
messages=messages,
)
print(final.choices[0].message.content) # assistant now replies using the web data
Handling Reasoning Content
msg = Message(
role="assistant",
content="The current year is 2026.",
reasoning_content="I need to check my knowledge cutoff and calculate from there."
)
Summary
- Use the
Messageclass fromaisuite/framework/message.pyto ensure type safety and proper structure - Supported roles are strictly limited to
"system","user","assistant", and"tool" - Tool calls require
ChatCompletionMessageToolCallandFunctionobjects with proper ID correlation - Plain dictionaries work interchangeably with
Messageobjects due to theOpenAICompliantMessageConverter - Tool results must be sent back with
role="tool"and stringified content to continue the function calling loop
Frequently Asked Questions
What roles are supported in aisuite Message objects?
The role field accepts four values: "system" for initial instructions, "user" for human inputs, "assistant" for model responses, and "tool" for function execution results. These align with the OpenAI Chat API specification and are validated during conversion.
Can I use plain Python dictionaries instead of Message objects?
Yes. The OpenAICompliantMessageConverter.convert_request method in aisuite/providers/message_converter.py handles both Message instances and raw dictionaries, converting them to the provider's required JSON format before transmission.
How do I handle tool results in the conversation flow?
After executing a function, append a new Message with role="tool" to your messages list. Set content to the stringified JSON result and include the original tool_calls data to maintain correlation with the assistant's request, as shown in the function calling example.
Where does aisuite handle message format conversion?
Conversion logic resides in aisuite/providers/message_converter.py, specifically within the OpenAICompliantMessageConverter class. This utility strips unsupported fields like refusal and optionally converts tool results to strings when tool_results_as_strings is enabled, ensuring compatibility across different LLM providers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →