SDK Fundamentals

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

RoleShapeUse 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.