Anvia
Agents

Prompt Lifecycle

Follow a prompt from request construction through provider response handling.

A prompt run starts from agent.prompt(...) and ends with either a final assistant response or an error. Anvia owns the model-tool loop during that run.

Basic Flow

  1. Convert the prompt into a user message.
  2. Combine stored history with messages created during the run.
  3. Add instructions, static context, dynamic context, tools, and output schema.
  4. Call the completion model.
  5. Run requested tools.
  6. Repeat until the model returns final text or the turn limit is reached.
const response = await agent
  .prompt("Where is order A-100?")
  .withHistory(history)
  .maxTurns(3)
  .send();

console.log(response.output);

Request-Level Options

Use request-level methods for values that change per prompt.

const response = await agent
  .prompt(userInput)
  .withHistory(history)
  .withToolConcurrency(2)
  .withTrace({
    name: "support-message",
    userId,
    metadata: { channel: "chat" },
  })
  .send();

These options do not mutate the agent. The next prompt starts from the agent defaults again.

Messages Created During a Run

response.messages contains only the new messages produced by this prompt run.

await conversations.saveMessages(conversationId, [
  ...history,
  ...response.messages,
]);

When tools are used, response.messages can include:

MessageRoleWhy it appears
PromptuserThe prompt passed to agent.prompt(...)
Tool callassistantThe model requested a tool
Tool resultuserAnvia returned tool output to the model
Final answerassistantThe model returned final text

Dynamic Context Timing

Dynamic context is searched at model-call time, using the latest prompt text for that turn.

const agent = new AgentBuilder("support", model)
  .dynamicContext(supportDocsIndex, { topK: 3 })
  .build();

Static context and dynamic context are both sent as documents to the completion model. Static context is always included; dynamic context is searched per prompt.

Send vs Stream

Use .send() when you only need the final response.

const response = await agent.prompt("Summarize this ticket.").send();

Use .stream() when your UI should receive incremental text, tool calls, tool results, and the final response.

for await (const event of agent.prompt("Where is order A-100?").stream()) {
  if (event.type === "text_delta") {
    process.stdout.write(event.delta);
  }
}