agent-express (ctx, next) pattern for AI agents
Fast and minimalist agentic AI framework in TypeScript.
Only three concepts: Agent, Session, Middleware.
The middleware pattern from Express, Koa, and Hono — applied to building AI agents.
Everything beyond the core agent loop — retries, cost tracking, memory, tools, guardrails and other — is middleware.
const { text } = await new Agent({
model: "anthropic/claude-sonnet-4-6",
instructions: "You are a helpful assistant.",
})
.use(observe.usage())
.run("What is the meaning of life?").result const agent = new Agent({
model: "anthropic/claude-sonnet-4-6",
instructions: "You are a weather assistant.",
})
agent.use(tools.function({
name: "get_weather",
description: "Get weather for a city",
schema: z.object({ city: z.string() }),
execute: async ({ city }) => `Weather in ${city}: 72°F`,
}))
const { text } = await agent.run("Weather in Tokyo?").result const { text, state } = await new Agent({
model: "anthropic/claude-sonnet-4-6",
instructions: "You are a helpful assistant.",
})
.use(observe.usage()) // token tracking
.use(guard.budget({ limit: 1 })) // $1 cost cap
.use(model.retry({ maxRetries: 3 })) // auto-retry
.run("What is the meaning of life?").result
console.log(state["observe:usage"]) // { inputTokens, outputTokens } Every feature above is a (ctx, next) middleware. Same pattern, 6 namespaces.
Or build your own — same interface, infinite possibilities.
agent.use(guard.budget({ limit: 5 })) // $5 USD cost cap
agent.use(guard.approve({ tool: "email" })) // require approval
agent.use(guard.timeout({ turn: 30_000 })) // 30s timeout agent.use(search.file({ retrieve: myRetriever })) // RAG — knowledge base search
agent.use(search.web({ provider: braveProvider() })) // web search tool agent.use(observe.log()) // structured JSON logging with levels
agent.use(observe.metrics()) // OpenTelemetry metrics (Prometheus, OTLP)
agent.use(observe.traces()) // OpenTelemetry distributed tracing
agent.use(observe.usage()) // token tracking → state['observe:usage']
agent.use(observe.tools()) // tool call recording
agent.use(observe.duration()) // turn timing agent.use(model.retry({ maxRetries: 3 })) // exponential backoff
agent.use(model.router({ // complexity routing
tiers: [{ model: "anthropic/claude-haiku-4-5-20251001", maxTokens: 100 }]
})) agent.use(memory.store({ backend: sqliteStore() })) // session persistence
agent.use(memory.compaction({ // context window management
strategy: "hybrid",
maxTokens: 8192,
})) agent.use(tools.function({
name: "get_weather",
description: "Get weather for a city",
parameters: z.object({ city: z.string() }),
execute: async ({ city }) => `Weather in ${city}: 72°F`,
})) agent.use(dev.console()) // full lifecycle terminal trace Fewer concepts, more built-in capabilities
| Feature | agent-express | Mastra | Vercel AI SDK | LangChain.js |
|---|---|---|---|---|
| Core concepts | 3 | 15-20 | 5-8 | 30+ |
| Extension model | Middleware (ctx, next) | Processors, Tools, Workflows | Hooks, Providers | Chains, Agents, Tools, Memory |
| Built-in testing | Yes | No | No | No |
| Cost control | guard.budget() | Manual | Manual | Manual |
| Human-in-the-loop | guard.approve() | Manual | No | Manual |
| Sessions | First-class Session | Manual state | No | Memory modules |
| RAG / Search | search.file() + search.web() | Built-in RAG | No | Retrievers + chains |
| Session persistence | memory.store() | Built-in | No | Memory modules |
| Memory management | memory.compaction() | Plugin-based | No | Memory modules |
| PII protection | guard.piiRedact() | No | No | Manual |
| Observability | Logs, OTel metrics & traces | OTel tracing | OTel spans | Callbacks / LangSmith |
| Streaming | SSE via createHandler() | Built-in | First-class (streamText) | Callbacks |
| TypeScript | Strict, ESM only | TypeScript | TypeScript | TypeScript |
Minimal agent starter with one tool
Coding assistant with file tools and approval gates
Research agent with model routing and output guards
Production support bot with budget, approval, and memory
npm install @ai-sdk/google) and use "google/gemini-2.0-flash". Supports Anthropic, OpenAI, Google, Mistral, Groq, DeepSeek, Amazon Bedrock, Azure, xAI, Cohere, and more.createHandler(agent) from agent-express/http returns a Web-standard Request/Response handler. Mount it on any route. See the HTTP & Framework Integration guide.agent-express/test. Tests run without real API calls, zero cost, zero latency. See the Testing guide.(ctx, next) from Express, Koa, and Hono. Middleware composition replaces dedicated APIs for memory, guards, tools, tracing. Graph-based topology (LangGraph) is more powerful for complex state machines, but most agents are linear loops with cross-cutting concerns. Middleware is the simpler abstraction for the common case.