API Reference

Configuration options, middleware, caching, and budget tracking.

createAgentTools

The main entry point. Creates all tools configured for a given sandbox.

import { createLocalSandbox, createAgentTools } from 'bashkit';
const sandbox = createLocalSandbox({ workingDirectory: '.' });
const { tools, budget } = await createAgentTools(sandbox, {
defaultTimeout: 30000,
tools: { Bash: { timeout: 10000 } },
webSearch: { apiKey: process.env.PARALLEL_API_KEY },
cache: true,
modelRegistry: { provider: 'openRouter' },
budget: { maxUsd: 5.00 },
});

Returns an object with:

  • tools — Tool set for Vercel AI SDK
  • budget — Budget tracker (when budget config provided)
  • openRouterModels — Model registry map (when modelRegistry config provided)
  • contextLayers — Applied context layers (empty array when no context config). Use with applyContextLayers() for late-added tools.

Configuration

AgentConfig

defaultTimeoutnumberdefault: 120000

Default timeout in milliseconds for all tools.

toolsToolConfig

Per-tool configuration. Keys are tool names (Bash, Read, Write, etc.).

webSearchWebSearchConfig

Web search configuration. Presence enables WebSearch and WebFetch tools.

cacheboolean | CacheConfig

Enable tool result caching. Pass true for defaults or an object for fine-grained control.

modelRegistryModelRegistryConfig

Fetch model info (pricing + context lengths) from a provider.

budgetBudgetConfig

Budget tracking configuration. Requires modelRegistry or pricingProvider.

contextContextConfig

Context layer config. Opt-in — wraps tools with execution and output policies. See the Context page.

ToolConfig (per-tool)

timeoutnumber

Override timeout for this tool.

blockedCommandsstring[]

Bash only. Commands that will be rejected.

allowedPathsstring[]

Read/Write only. Glob patterns for allowed file paths.

maxFileSizenumber

Write only. Maximum file size in bytes.

maxOutputLengthnumber

Maximum output length before truncation.

Middleware

BashKit includes middleware for the Vercel AI SDK's wrapLanguageModel:

anthropicPromptCacheMiddleware

Automatically adds cache control headers to Anthropic messages, reducing cost and latency for repeated prompts.

import { anthropicPromptCacheMiddleware } from 'bashkit';
import { wrapLanguageModel } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
const model = wrapLanguageModel({
model: anthropic('claude-sonnet-4-5'),
middleware: anthropicPromptCacheMiddleware,
});

Effective when conversations have 3+ messages. The middleware marks the system prompt and early messages for caching.

Caching

Optional LRU caching for tool execution results. Caches identical tool calls to avoid redundant work.

// Enable with defaults (LRU, 5min TTL)
const { tools } = await createAgentTools(sandbox, { cache: true });
// Per-tool control
const { tools } = await createAgentTools(sandbox, {
cache: {
ttl: 10 * 60 * 1000, // 10 minutes
debug: true, // Log cache hits/misses
Read: true,
Glob: true,
Grep: true,
WebFetch: false, // Disable for this tool
},
});

Default cached tools: Read, Glob, Grep, WebFetch, WebSearch

Not cached by default: Bash, Write, Edit (they have side effects)

Standalone Caching

import { cached } from 'bashkit';
const cachedTool = cached(myTool, 'MyTool', { ttl: 60000 });
// Check cache stats
const stats = cachedTool.getStats();
// { hits: 5, misses: 2, hitRate: 0.71, size: 2 }

Budget Tracking

Track cumulative costs across agentic loop steps and stop when a budget is exceeded. Pricing data is auto-fetched from OpenRouter (free API, cached 24h).

const { tools, budget } = await createAgentTools(sandbox, {
modelRegistry: { provider: 'openRouter' },
budget: { maxUsd: 5.00 },
});
const result = await generateText({
model,
tools,
stopWhen: [stepCountIs(50), budget.stopWhen],
onStepFinish: (step) => {
budget.onStepFinish(step);
console.log(budget.getStatus());
// { totalCostUsd: 0.12, maxUsd: 5, remainingUsd: 4.88, ... }
},
});

Budget tracking auto-wires into Task tool sub-agents when configured.

Model ID Matching

Uses PostHog's 3-tier matching strategy:

  1. Exact match (case-insensitive)
  2. Longest contained match (model variant contains cost variant)
  3. Reverse containment (cost variant contains model variant)

Message Pruning

Keep conversations within token limits by pruning older messages:

import { pruneMessages } from 'bashkit';
const pruned = pruneMessages(messages, {
maxTokens: 100000,
protectRecentUserMessages: 3,
});

Removes the oldest messages first while protecting the most recent user messages and the system prompt.