Messages and History
Understand Anvia message objects and the history arrays built from them.
Anvia history is a plain Message[]. For explicit stateless history, pass the whole transcript to agent.prompt([...]); the last message is the active prompt and earlier messages are history.
Message Roles
| Role | Shape | Use for |
|---|---|---|
system | { role: "system", content: string } | System-level instructions in raw message history |
user | { role: "user", content: UserContent[] } | User text, images, and documents |
assistant | { role: "assistant", content: AssistantContent[] } | Assistant text, reasoning, images, and tool calls |
tool | { role: "tool", content: ToolContent[] } | Tool results returned after assistant tool calls |
Most application history contains user and assistant messages. Tool-using runs can also include tool messages.
Text History
import type { Message } from "@anvia/core";
const history: Message[] = [
{
role: "user",
content: [{ type: "text", text: "My checkout failed." }],
},
{
role: "assistant",
content: [
{
type: "text",
text: "I can help. What error did you see?",
},
],
},
];You can create the same shape with helpers:
import { Message } from "@anvia/core";
const history = [
Message.user("My checkout failed."),
Message.assistant("I can help. What error did you see?"),
];Persisting History
response.messages contains only the new messages created by one run. Append those messages to your stored conversation.
const history = await conversations.loadMessages(conversationId);
const currentPrompt = Message.user(userInput);
const response = await agent.prompt([...history, currentPrompt]).send();
await conversations.saveMessages(conversationId, [
...history,
...response.messages,
]);Persist the plain message objects returned by Anvia. JSON storage is enough for most applications.
Tool Calls In History
Tool calls are assistant content. Tool results are tool content.
import type { Message } from "@anvia/core";
const historyWithToolCall: Message[] = [
{
role: "user",
content: [{ type: "text", text: "Where is order A-100?" }],
},
{
role: "assistant",
content: [
{
type: "tool_call",
id: "call_1",
function: {
name: "lookup_order",
arguments: { orderId: "A-100" },
},
},
],
},
{
role: "tool",
content: [
{
type: "tool_result",
id: "call_1",
content: [{ type: "text", text: "{\"status\":\"shipped\"}" }],
},
],
},
{
role: "assistant",
content: [{ type: "text", text: "Order A-100 has shipped." }],
},
];Only create tool-call history yourself when importing an existing transcript or replaying a known run. For live runs, persist response.messages.
Reasoning In History
Assistant messages can include provider-returned reasoning content. The stable display field is reasoning.text; adapters may also include structured content blocks for text, summaries, encrypted state, and redacted state.
import { AssistantContent, Message } from "@anvia/core";
const assistant = Message.assistant([
AssistantContent.reasoningFromContent([
{ type: "summary", text: "Checked the policy and the tool result." },
{ type: "encrypted", data: "provider-opaque-state" },
]),
AssistantContent.text("Order A-100 has shipped."),
]);Persist reasoning objects exactly as returned when you store history. Provider adapters use signatures, encrypted blocks, and redacted blocks to maintain reasoning continuity across tool calls.
Attachments
User messages can include text, images, and documents:
import { Message, UserContent } from "@anvia/core";
const message = Message.user([
UserContent.text("Summarize this report."),
UserContent.documentUrl("https://example.com/report.pdf", "application/pdf", {
filename: "report.pdf",
}),
]);Provider support for attachments varies. Check the provider and model before building a workflow that depends on images or documents.
Next
Read Prompt Responses to see what an agent run returns.
