Skip to main content
The Agent class is the primary way you build an AI agent in Vibes. It wraps the Vercel AI SDK’s generateText / streamText loop, manages multi-turn tool execution, injects dependencies, and validates structured output - all in a single cohesive interface. An agent is typed over its dependencies (TDeps) and output (TOutput), making it fully type-safe end to end.

Agent loop

Every call to agent.run(), agent.stream(), or agent.runStreamEvents() goes through the same loop:

Basic usage

import { Agent } from "@vibesjs/sdk";
import { anthropic } from "@ai-sdk/anthropic";

const agent = new Agent({
  model: anthropic("claude-sonnet-4-6"),
  systemPrompt: "You are a helpful assistant.",
});

const result = await agent.run("Hello!");
console.log(result.output);

Type parameters

Agent<TDeps, TOutput> accepts two type parameters:
  • TDeps - the shape of the dependencies object injected at run time. Defaults to undefined (no deps).
  • TOutput - the output type. Defaults to string. Specify this when using outputSchema for structured output.
type Deps = { db: Database };

const agent = new Agent<Deps, string>({
  model: anthropic("claude-haiku-4-5-20251001"),
  systemPrompt: (ctx) => `Helping user from ${ctx.deps.db.region}`,
});

// Pass deps at run time
const result = await agent.run("Hello!", { deps: { db: myDb } });
When systemPrompt is a function, it receives the full RunContext<TDeps> on every turn, giving it access to the injected deps, current usage, run ID, and more.

Constructor options

All options are passed to new Agent(opts: AgentOptions<TDeps, TOutput>).
FieldTypeDefaultDescription
modelLanguageModelrequiredVercel AI SDK model instance (e.g. anthropic("claude-sonnet-4-6"))
namestring?-Human-readable agent name
systemPromptstring | (ctx) => string-Base system prompt, static or dynamic
instructionsstring | (ctx) => string-Per-run additions appended after systemPrompt. Not recorded in result.messages
toolsToolDefinition<TDeps>[][]Static tools always available to the model
toolsetsToolset<TDeps>[][]Dynamic per-turn tool groups
outputSchemaZodType | ZodType[]-Zod schema for structured output
outputMode'tool' | 'native' | 'prompted''tool'How structured output is requested
outputTemplatebooleantrueWhether to inject the schema into the system prompt
resultValidatorsResultValidator<TDeps, TOutput>[][]Post-parse validators - throw to reject and retry
maxRetriesnumber3Max validation retries before MaxRetriesError
maxTurnsnumber10Max tool-call round trips before MaxTurnsError
usageLimitsUsageLimits?-Cap cumulative token or request usage
historyProcessorsHistoryProcessor<TDeps>[][]Per-turn message transforms (trim, summarize, filter)
modelSettingsModelSettings?-Temperature, maxTokens, topP, and other model parameters
endStrategy'early' | 'exhaustive''early'When to stop after receiving final_result
maxConcurrencynumber?unlimitedMax concurrent tool executions per turn
telemetryTelemetrySettings?-OpenTelemetry settings passed to the AI SDK

Running an agent

Vibes provides three run methods depending on how you want to consume the output:
// Awaitable - returns RunResult<TOutput> when the run completes
const result = await agent.run("What is 2 + 2?");

// Streaming - returns StreamResult<TOutput> immediately
// Consume textStream, then await output / messages / usage
const stream = agent.stream("Tell me a story.");
for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);
}
const output = await stream.output;

// Event stream - returns AsyncIterable<AgentStreamEvent<TOutput>>
// Full visibility into each turn, tool call, and text delta
for await (const event of agent.runStreamEvents("What is 2 + 2?")) {
  // switch on event.kind
}
See Streaming for the full StreamResult interface and event kinds, and Results for the RunResult API.

agent.override()

agent.override(overrides) returns a scoped runner that substitutes specific options for a single run(), stream(), or runStreamEvents() call. The original agent is never mutated.
const result = await agent
  .override({ model: testModel, maxTurns: 3 })
  .run("Test prompt", { deps: fakeDeps });
Override options mirror AgentOptions: model, systemPrompt, instructions, tools, toolsets, resultValidators, maxRetries, maxTurns, usageLimits, historyProcessors, modelSettings, endStrategy, telemetry.
Tip: Use agent.override() in tests to swap in a TestModel without modifying your production agent. Override runs also bypass the setAllowModelRequests(false) guard, so they work in any test environment.