RunContext<TDeps> is the primary dependency injection mechanism in Vibes. When you construct an Agent<TDeps>, you declare what external resources it needs. At agent.run() time you supply those resources as deps, and every callback in the agent - system prompts, instructions, tools, validators, toolsets, and history processors - receives the same RunContext carrying those deps.
This is a signature feature of Vibes: you never need to close over global variables or pass deps out-of-band. Your agent is fully self-contained and trivially testable.
RunContext fan-out
Every entry point to the agent resolves a singleRunContext<TDeps> and fans it out to all callbacks:
Defining dependencies
Define aDeps type, pass it as the first type parameter to Agent, and supply the concrete instance at run time:
The RunContext interface
The full interface available in every callback:| Field / Method | Type | Description |
|---|---|---|
deps | TDeps | User-supplied dependencies injected at run time |
usage | Usage | Accumulated token usage (inputTokens, outputTokens, totalTokens, requests) |
retryCount | number | How many result validation retries have occurred so far |
toolName | string | null | Name of the currently executing tool, or null outside a tool call |
runId | string | Unique identifier for this run (UUID) |
metadata | Record<string, unknown> | Per-run caller metadata passed via RunOptions.metadata |
toolResultMetadata | Map<string, Record<string, unknown>> | Metadata attached by tools via attachMetadata() |
attachMetadata(id, meta) | void | Attach arbitrary metadata for a specific tool call ID |
Using deps in tools
Tools receiveRunContext<TDeps> as their first argument, giving them direct access to your injected dependencies:
Using deps in system prompts
System prompts and instructions can be functions that receiveRunContext. This lets you build dynamic prompts from runtime state:
Testing with dependencies
The canonical testing pattern is to create fake deps and pass them viaagent.override():
This is the recommended testing pattern - inject test doubles via
deps, never mock the framework internals. Your agent code stays unchanged; only the dep implementations swap.History processors and privacy
History processors run before each model call and can transform or filter the message history. TheprivacyFilterProcessor is a built-in processor that redacts sensitive content before messages are sent to the model.
The PrivacyRule union type supports two shapes:
RegexPrivacyRule:{ pattern: RegExp, replacement?: string }- replace matches of the pattern with the replacement string (defaults to"[REDACTED]"if omitted).FieldPrivacyRule:{ messageType: string, fieldPath: string }- remove the value atfieldPathfrom messages of the given type.