Runtime Boundaries
Understand the boundaries between clients, models, agents, tools, and application code.
Anvia is designed around explicit runtime boundaries. Each object has a small job, and your application stays in control of data, permissions, persistence, and side effects.
The Boundary Map
| Layer | Example | Responsibility |
|---|---|---|
| Application | Your server, worker, route, or job | Owns product logic, auth, database access, and deployment |
| Client | OpenAIClient, AnthropicClient, GeminiClient | Owns provider credentials and provider SDK setup |
| Model | client.completionModel(...) | Executes normalized completion requests |
| Agent | new AgentBuilder(...).build() | Adds instructions, context, tools, hooks, output schema, and turn limits |
| Tool | createTool(...) | Exposes a typed application action to the agent |
| Request | agent.prompt(...).send() | Runs one prompt through the agent runtime |
How The Pieces Connect
Application -> Client -> Model -> Agent -> Prompt Request -> Prompt Response
| |
| +-> Tools, context, history, hooks, tracing
|
+-> Extractors, pipelines, retrievalThe application creates and owns the runtime objects. Anvia coordinates the prompt run, but your app still decides what data is loaded, which tools are available, where history is stored, and how side effects are authorized.
Step By Step
1. Keep Provider Setup In a Client
import { OpenAIClient } from "@anvia/openai";
const client = new OpenAIClient({ apiKey });The client owns API keys, base URLs, default headers, and provider SDK construction.
2. Reuse Models
const model = client.completionModel("gpt-5");A model is a reusable capability. You can pass the same model to multiple agents, extractors, and pipelines.
3. Put Behavior In the Agent
import { AgentBuilder } from "@anvia/core";
const agent = new AgentBuilder("support", model)
.instructions("Answer support questions clearly.")
.defaultMaxTurns(3)
.build();The agent owns runtime behavior around the model. The stable id, support, should not change casually because it can be used by tracing, Studio, and multi-agent workflows.
4. Keep Side Effects In Tools
import { createTool } from "@anvia/core";
import { z } from "zod";
const lookupCustomer = createTool({
name: "lookup_customer",
description: "Look up a customer by email.",
input: z.object({
email: z.string().email(),
}),
async execute({ email }) {
return { email, plan: "pro" };
},
});Tools are ordinary application code with validation at the boundary. This is where you enforce product permissions and decide which side effects are allowed.
5. Run Work From Application Code
const response = await agent
.prompt("Can customer mira@example.com use priority support?")
.send();
console.log(response.output);The prompt request runs one agent workflow. It can use history, stream events, request tool approvals, attach traces, or override the turn limit.
What Anvia Does Not Own
Anvia does not need to own:
- your database connection
- user authentication
- permission checks
- durable message storage
- queueing and retries
- deployment topology
Keep those in your application. Pass only the context, tools, and model capabilities the agent needs for one workflow.
Practical Rule
If a decision affects product correctness, security, or data ownership, keep it in application code or a tool. If a decision affects how a model is prompted, constrained, streamed, or observed, configure it on the agent or prompt request.
Next
Read Clients and Models to configure provider access and reusable model capabilities.
