API Reference
Complete reference for all Capstan framework packages. The AI agent package (@zauso-ai/capstan-ai) is documented first and in greatest detail; other packages follow in condensed form.
@zauso-ai/capstan-ai (Smart Agent)
Standalone AI toolkit. Works independently or with the Capstan framework. Includes the smart agent loop, tool validation, token budgets, skills, memory, evolution, compression, harness mode, and utility functions.
createSmartAgent(config)
Create a fully-configured smart agent with tool validation, token budgets, skills, evolution, and lifecycle hooks.
function createSmartAgent(config: SmartAgentConfig): SmartAgentSmartAgentConfig -- full configuration:
interface SmartAgentConfig {
llm: LLMProvider; // Primary LLM (required)
tools: AgentTool[]; // Available tools (required)
tasks?: AgentTask[]; // Background tasks via task fabric
memory?: SmartAgentMemoryConfig; // Scoped memory with pluggable backend
prompt?: PromptComposerConfig; // System prompt layering
stopHooks?: StopHook[]; // Post-response quality gates
maxIterations?: number; // Max loop iterations (default: 10)
contextWindowSize?: number; // Context window for compression
compaction?: Partial<{
snip: SnipConfig;
microcompact: MicrocompactConfig;
autocompact: AutocompactConfig;
}>;
streaming?: StreamingExecutorConfig; // Concurrent tool execution
toolCatalog?: ToolCatalogConfig; // Deferred tool loading
hooks?: SmartAgentHooks; // Lifecycle hooks
fallbackLlm?: LLMProvider; // Backup model on primary failure
tokenBudget?: number | TokenBudgetConfig; // Output token budget
toolResultBudget?: ToolResultBudgetConfig; // Tool result size limits
skills?: AgentSkill[]; // Activatable strategies
evolution?: EvolutionConfig; // Self-evolution configuration
llmTimeout?: LLMTimeoutConfig; // Timeout and stall detection
}Usage:
import { createSmartAgent, defineSkill } from "@zauso-ai/capstan-ai";
const agent = createSmartAgent({
llm: myProvider,
tools: [readFile, writeFile],
maxIterations: 20,
fallbackLlm: cheaperProvider,
tokenBudget: { maxOutputTokensPerTurn: 8192, nudgeAtPercent: 85 },
toolResultBudget: { maxChars: 50_000, persistDir: "./overflow" },
llmTimeout: { chatTimeoutMs: 120_000, streamIdleTimeoutMs: 90_000 },
skills: [codeReviewSkill],
evolution: {
store: myEvolutionStore,
capture: "every-run",
distillation: "post-run",
},
});
const result = await agent.run("Refactor the auth module");SmartAgent
interface SmartAgent {
run(goal: string): Promise<AgentRunResult>;
resume(checkpoint: AgentCheckpoint, message: string): Promise<AgentRunResult>;
}AgentTool
Tool definition with optional input validation and per-tool timeout.
interface AgentTool {
name: string; // Unique tool identifier
description: string; // LLM-facing description
parameters?: Record<string, unknown>; // JSON Schema for input
isConcurrencySafe?: boolean; // Safe for parallel execution
failureMode?: "soft" | "hard"; // "soft" = non-fatal, "hard" = aborts
execute(args: Record<string, unknown>): Promise<unknown>;
validate?: (args: Record<string, unknown>) => { valid: boolean; error?: string };
timeout?: number; // Per-tool timeout in ms
}AgentTask
Background task submitted via the task fabric.
type AgentTaskKind = "shell" | "workflow" | "remote" | "subagent" | "custom";
interface AgentTask {
name: string;
description: string;
kind?: AgentTaskKind;
parameters?: Record<string, unknown>;
isConcurrencySafe?: boolean;
failureMode?: "soft" | "hard";
execute(args: Record<string, unknown>, context: AgentTaskExecutionContext): Promise<unknown>;
}Task factory helpers: createShellTask, createWorkflowTask, createRemoteTask, createSubagentTask.
AgentSkill
interface AgentSkill {
name: string; // Unique skill identifier
description: string; // What the skill does
trigger: string; // When to use this skill
prompt: string; // Guidance text injected on activation
tools?: string[]; // Preferred tool names when active
source?: "developer" | "evolved"; // Origin
utility?: number; // Effectiveness score (0.0 - 1.0)
metadata?: Record<string, unknown>;
}Skill Functions
defineSkill(def)-- create a skill with sensible defaults (source: "developer", utility: 1.0)createActivateSkillTool(skills)-- create theactivate_skillmeta-toolformatSkillDescriptions(skills)-- format skills for system prompt inclusion
LLMProvider
interface LLMProvider {
name: string;
chat(messages: LLMMessage[], options?: LLMOptions): Promise<LLMResponse>;
stream?(messages: LLMMessage[], options?: LLMOptions): AsyncIterable<LLMStreamChunk>;
}
interface LLMMessage {
role: "system" | "user" | "assistant";
content: string;
}
interface LLMResponse {
content: string;
model: string;
usage?: { promptTokens: number; completionTokens: number; totalTokens: number };
finishReason?: string;
}LLMTimeoutConfig
interface LLMTimeoutConfig {
chatTimeoutMs?: number; // Max wait for chat() response (default: 120_000)
streamIdleTimeoutMs?: number; // Max idle between stream chunks (default: 90_000)
stallWarningMs?: number; // Warning threshold (default: 30_000)
}TokenBudgetConfig
interface TokenBudgetConfig {
maxOutputTokensPerTurn: number; // Hard cap on output tokens per LLM call
nudgeAtPercent?: number; // Inject "wrapping up" nudge at this %
}When tokenBudget is set to a plain number, it is treated as { maxOutputTokensPerTurn: n }.
ToolResultBudgetConfig
interface ToolResultBudgetConfig {
maxChars: number; // Max chars per individual tool result
preserveStructure?: boolean; // Preserve JSON structure when truncating
persistDir?: string; // Save overflow results to disk
maxAggregateCharsPerIteration?: number; // Cap total result chars per iteration (default: 200_000)
}SmartAgentHooks
Lifecycle hooks for observability, policy enforcement, and post-run processing.
| Hook | When | Return |
|---|---|---|
beforeToolCall | Before each tool execution | { allowed, reason? } |
afterToolCall | After each tool execution | void (receives status: "success" | "error") |
beforeTaskCall | Before each task submission | { allowed, reason? } |
afterTaskCall | After each task completes | void |
onCheckpoint | At init, tool_result, completion | AgentCheckpoint | void |
getControlState | Before LLM, before/after tools | { action: "continue" | "pause" | "cancel" } |
onRunComplete | Once at end of run | void |
afterIteration | After each iteration | void (receives IterationSnapshot) |
AgentRunResult
type AgentRunStatus =
| "completed" | "max_iterations" | "approval_required"
| "paused" | "canceled" | "fatal";
interface AgentRunResult {
result: unknown; // The agent's final output
iterations: number; // Loop iterations executed
toolCalls: AgentToolCallRecord[]; // All tool calls made
taskCalls: AgentTaskCallRecord[]; // All task calls made
status: AgentRunStatus; // Terminal status
error?: string; // Error message (when "fatal")
checkpoint?: AgentCheckpoint; // Resumable checkpoint
pendingApproval?: { // Blocked approval details
kind: "tool" | "task";
tool: string;
args: unknown;
reason: string;
};
}AgentCheckpoint
Serializable checkpoint for pause/resume workflows.
interface AgentCheckpoint {
stage: "initialized" | "tool_result" | "task_wait" | "approval_required"
| "paused" | "completed" | "max_iterations" | "canceled";
goal: string;
messages: LLMMessage[];
iterations: number;
toolCalls: AgentToolCallRecord[];
taskCalls: AgentTaskCallRecord[];
maxOutputTokens: number;
compaction: { autocompactFailures: number; reactiveCompactRetries: number; tokenEscalations: number };
pendingApproval?: { kind: "tool" | "task"; tool: string; args: unknown; reason: string };
}Compression Config
interface SnipConfig { preserveTail: number }
interface MicrocompactConfig { maxToolResultChars: number; protectedTail: number }
interface AutocompactConfig { threshold: number; maxFailures: number; bufferTokens?: number }
interface StreamingExecutorConfig { maxConcurrency: number }
interface ToolCatalogConfig { deferThreshold: number }StopHook
interface StopHook {
name: string;
evaluate(context: StopHookContext): Promise<StopHookResult>;
}
interface StopHookContext { response: string; messages: LLMMessage[]; toolCalls: AgentToolCallRecord[]; goal: string }
interface StopHookResult { pass: boolean; feedback?: string }Prompt Composer
interface PromptComposerConfig {
base?: string;
layers?: PromptLayer[];
dynamicLayers?: (context: PromptContext) => PromptLayer[];
}
interface PromptLayer {
id: string;
content: string;
position: "prepend" | "append" | "replace_base";
priority?: number;
}Memory
interface MemoryBackend {
store(entry: Omit<MemoryEntry, "id" | "createdAt">): Promise<string>;
query(scope: MemoryScope, text: string, k: number): Promise<MemoryEntry[]>;
remove(id: string): Promise<boolean>;
clear(scope: MemoryScope): Promise<void>;
}
interface SmartAgentMemoryConfig {
store: MemoryBackend;
scope: MemoryScope;
readScopes?: MemoryScope[];
embedding?: MemoryEmbedder;
maxMemoryTokens?: number;
saveSessionSummary?: boolean;
}Built-in backends: BuiltinMemoryBackend (in-memory), SqliteMemoryBackend (persistent). Use createMemoryAccessor() for the high-level remember / recall / forget / about / assembleContext API.
Evolution
interface EvolutionConfig {
store: EvolutionStore;
capture?: "every-run" | "on-failure" | "on-success" | ((result: AgentRunResult) => boolean);
distillation?: "post-run" | "manual";
distiller?: Distiller;
pruning?: PruningConfig;
skillPromotion?: SkillPromotionConfig;
}
interface EvolutionStore {
recordExperience(exp: Omit<Experience, "id" | "recordedAt">): Promise<string>;
queryExperiences(query: ExperienceQuery): Promise<Experience[]>;
storeStrategy(strategy: Omit<Strategy, "id" | "createdAt" | "updatedAt">): Promise<string>;
queryStrategies(query: string, k: number): Promise<Strategy[]>;
updateStrategyUtility(id: string, delta: number): Promise<void>;
incrementStrategyApplications(id: string): Promise<void>;
storeSkill(skill: AgentSkill): Promise<string>;
querySkills(query: string, k: number): Promise<AgentSkill[]>;
pruneStrategies(config: PruningConfig): Promise<number>;
getStats(): Promise<EvolutionStats>;
}Two built-in stores: InMemoryEvolutionStore (testing) and SqliteEvolutionStore (production persistence).
Key types:
interface Experience {
id: string; goal: string; outcome: "success" | "failure" | "partial";
trajectory: TrajectoryStep[]; iterations: number; tokenUsage: number;
duration: number; skillsUsed: string[]; recordedAt: string;
}
interface Strategy {
id: string; content: string; source: string[];
utility: number; applications: number; createdAt: string; updatedAt: string;
}
interface PruningConfig { maxStrategies?: number; minUtility?: number; maxAgeDays?: number }
interface SkillPromotionConfig { enabled?: boolean; minApplications?: number; minUtility?: number }Engine functions: buildExperience(), shouldCapture(), runPostRunEvolution(), buildStrategyLayer(). The LlmDistiller class handles distillation and consolidation.
Utility Functions
| Function | Description |
|---|---|
validateArgs(args, schema) | JSON Schema validator for tool inputs; collects all errors |
normalizeMessages(messages) | Merge same-role, filter empties, convert duplicate system messages |
estimateTokens(messages) | Rough token estimate (content length / 4) |
memoryFreshnessText(timestampMs) | Staleness caveat text for the LLM |
think(llm, prompt, opts?) | Single LLM call with optional Zod schema parsing |
generate(llm, prompt, opts?) | Single LLM call returning raw text |
thinkStream / generateStream | Streaming variants of think/generate |
@zauso-ai/capstan-agent
LLM providers, machine surfaces, and interop.
LLM Providers
import { openaiProvider, anthropicProvider } from "@zauso-ai/capstan-agent";
const openai = openaiProvider({ apiKey: "...", model: "gpt-4o", baseUrl: "..." });
const claude = anthropicProvider({ apiKey: "...", model: "claude-sonnet-4-20250514" });CapabilityRegistry
Collects all defineAPI() routes and projects them to MCP tools, A2A skills, and OpenAPI operations.
MCP
createMcpServer()-- MCP server with stdio or streamable-http transportcreateMcpClient()-- consume tools from external MCP servers
A2A
createA2AHandler()-- JSON-RPC handler for the A2A protocolgenerateAgentCard()-- generate the agent card at/.well-known/agent.json
LangChain Integration
import { toLangChainTools } from "@zauso-ai/capstan-agent";
const tools = toLangChainTools(registry, { filter: (r) => r.capability === "read" });@zauso-ai/capstan-core
Core framework: server, routing primitives, policy engine, approval workflow, verification.
defineAPI(def)
Define a typed API route handler with input/output validation and agent introspection.
function defineAPI<TInput, TOutput>(def: APIDefinition<TInput, TOutput>): APIDefinition<TInput, TOutput>
interface APIDefinition<TInput, TOutput> {
input?: z.ZodType<TInput>;
output?: z.ZodType<TOutput>;
description?: string;
capability?: "read" | "write" | "external";
resource?: string;
policy?: string;
handler: (args: { input: TInput; ctx: CapstanContext }) => Promise<TOutput>;
}defineConfig(config)
Identity function providing type-checking for the app configuration.
function defineConfig(config: CapstanConfig): CapstanConfigdefinePolicy(def)
function definePolicy(def: PolicyDefinition): PolicyDefinition
interface PolicyDefinition {
key: string;
title: string;
effect: "allow" | "deny" | "approve" | "redact";
check: (args: { ctx: CapstanContext; input?: unknown }) => Promise<PolicyCheckResult>;
}defineMiddleware(def)
function defineMiddleware(def: MiddlewareDefinition | MiddlewareHandler): MiddlewareDefinitiondefineRateLimit(config)
interface RateLimitConfig {
default: { requests: number; window: string };
perAuthType?: { anonymous?: ...; human?: ...; agent?: ... };
}Other Core Exports
enforcePolicies(policies, ctx, input?)-- evaluate all policies, return most restrictiveenv(key)-- read env variable (returns "" if unset)createCapstanApp(config)-- build a Hono-backed Capstan appdefinePlugin(def)-- extend with routes, policies, middlewaredefineWebSocket(path, handlers)-- WebSocket endpointWebSocketRoom-- pub/sub room for broadcastingdefineCompliance(config)-- EU AI Act compliance primitivescreateApproval / resolveApproval / clearApprovals-- approval workflowRedisStore-- Redis backend for approvals, rate limits, DPoP, audit
@zauso-ai/capstan-db
Data modeling, Drizzle ORM integration, migrations, vector search, and CRUD generation.
defineModel(name, fields)-- define a data model with fields, relations, indexesfield-- field builders:id(), string(), text(), integer(), number(), boolean(), date(), datetime(), json(), enum(), vector()relation-- relation builders:belongsTo(), hasMany(), hasOne(), manyToMany()generateCrudRoutes(model)-- auto-generate CRUD API routes from a modeldefineEmbedding(name, config)-- configure an embedding model for RAGvectorSearch(db, opts)-- query by cosine similarity- Providers:
sqlite,libsql,postgres,mysql
@zauso-ai/capstan-auth
Dual authentication for humans (JWT) and agents (API keys), plus OAuth, DPoP, and SPIFFE/mTLS.
signSession(payload, secret, maxAge?)-- create signed JWTverifySession(token, secret)-- verify JWT (timing-safe)generateApiKey()-- returns { key, hash, prefix }verifyApiKey(key, hash)-- timing-safe verificationcreateAuthMiddleware(config, finders)-- resolve auth context from requestsgoogleProvider() / githubProvider()-- OAuth provider helperscreateOAuthHandlers(config)-- full OAuth code flow handlerscheckPermission(required, granted)-- resource:action permission checking with wildcards
@zauso-ai/capstan-router
File-based route discovery and manifest generation.
scanRoutes(dir)-- scan directory tree, return route manifest with diagnosticsmatchRoute(url, manifest)-- match a URL against the route manifest- Supports:
*.api.ts,*.page.tsx,_layout.tsx,_middleware.ts,_loading.tsx,_error.tsx,not-found.tsx
@zauso-ai/capstan-react
Human application shell: streaming SSR, selective hydration, layouts, client router.
Outlet-- render child routes inside layoutsuseLoaderData<T>()-- read server loader dataServerOnly-- skip hydration for componentsLink(client) -- SPA navigation with prefetchuseRouter()(client) -- navigation, params, search paramswithViewTransition()-- View Transitions API integration
@zauso-ai/capstan-cli
| Command | Description |
|---|---|
capstan dev | Start development server with hot reload |
capstan build | Build for production |
capstan start | Start production server |
capstan mcp | Start MCP server over stdio |
capstan verify | Run the 8-step verification cascade |
capstan db:migrate | Generate migration from model changes |
capstan db:push | Apply pending migrations |
capstan db:status | Show migration status |
capstan add api|page|model|policy <name> | Scaffold new files |
capstan deploy:init --target <target> | Generate deployment files |
capstan ops:events|incidents|health|tail | Inspect semantic ops store |
Other Packages
@zauso-ai/capstan-cron
Recurring execution for agent jobs and long-running automation. Pair with the harness runtime for scheduled agent tasks.
@zauso-ai/capstan-ops
Semantic operations kernel: events, incidents, snapshots, SQLite persistence, querying, and CLI/operator consumption.
@zauso-ai/capstan-dev
Local development runtime with CSS pipeline, file watching, and hot route reloading. Creates dev server with createDevServer().
create-capstan-app
Project scaffolder. Supports blank and tickets templates. Generates AGENTS.md for AI coding agents.