Agent
A governed AI agent for NestJS — chat, tool-calling, per-tool RBAC, token quota, cost tracking, and human-in-the-loop approval, with each turn optionally a replay-safe durable workflow and wired into the ecosystem's durable, telescope, and diagnostics glue.
@dudousxd/nestjs-agent brings an in-app AI assistant to NestJS the way Laravel brings
batteries-included features to PHP. Every app that builds a copilot rewrites the same machinery:
the agentic loop (model → tools → model), a tool registry, RBAC per tool, token quota, cost
tracking, audit, human approval for destructive actions, and resumable streaming. All of that is
mechanism — the library. Your domain (which tables, which tenant column, which roles) stays
policy you supply.
The turn can be a durable workflow
Out of the box the turn runs on an inline runner — in-process, no extra dependencies. Add
@dudousxd/nestjs-durable and flip durable: true and each turn instead runs as a durable
workflow: every model and tool call becomes a checkpointed step, so a crash mid-turn replays from
cache, and human-in-the-loop approval becomes a durable signal — the run suspends in the state
store instead of holding a connection, and resumes when a human approves. Under durable: true,
the turn's model call and tool executions are, by default, dispatched as routed durable steps
(AgentRunSteps.llm / AgentRunSteps.tool) rather than pinned to the pod that started the run —
either can land on any worker in the fleet (opt out with dispatchedSteps: false). Either way live
tokens flow on a separate data plane (a TokenStreamSink), so streaming and durability compose
instead of fighting — but a dispatched turn needs that sink to be cross-process (e.g.
RedisTokenStreamSink), since the worker executing the step may not be the pod holding the SSE
connection. The wire protocol your frontend speaks is identical, so you develop inline and flip to
durable in production without touching your tools or UI. See
Architecture for the full control/data-plane picture.
What you get
- Tool framework —
@AiTool({ kind: 'read' | 'action' })classes, auto-discovered.actiontools never auto-execute; the run pauses for approval. - Governance out of the box — RBAC per tool, per-agent system prompts and tool allow-lists, daily token quota, and an audit trail of every tool call.
- Cost accounting — a usage ledger per turn, rolled up into spend per model / per actor / over time. A gateway's real reported cost wins; otherwise a cache-aware estimate against a versioned pricing table (prompt cache-write / cache-read priced at their own rates).
- A governance console —
@dudousxd/nestjs-agent-dashboardmounts a standalone AI-gateway console (bundled React SPA + NestJS module) at its own route, no Telescope required. - Streaming — SSE with resume; reconnect replays the buffered tokens.
- Inline or durable — an in-process runner by default, or opt into the durable runner (add
@dudousxd/nestjs-durable, setdurable: true) for checkpointed, replay-safe turns — oneAgentRunnerSPI, identical wire protocol. Durable turns dispatch their model/tool steps across the worker fleet by default (AgentRunSteps.llm/.tool). - Run reliability + tracing — every run's start/end is durably recorded (
agent_run, with apromptHashof the resolved system prompt) and every turn emits diagnostics spans (traceId = runId) that Telescope renders as a waterfall in its TRACES tab. - Multi-agent — an orchestrator delegates to named sub-agents via a synthesized
ask_<name>tool; each delegation is a durable child run. - The data satellite —
@dudousxd/nestjs-agent-datapackages governed, read-only SQL (AST-validated, RBAC + tenant scoping) as an opt-in tool. - A React frontend —
@dudousxd/nestjs-agent-react'suseAgentChat(Vercel AI SDK v7) plus styling-agnostic chat components and an optional markdown renderer. - Zero provider code —
@dudousxd/nestjs-agent-ai-sdk'saiSdkModel(model)adapts any Vercel AI SDK v7LanguageModelto theModelProviderSPI, the first of a family of provider adapters, so an app suppliesmodelwithout writing a wrapper.
The four glue points
- Diagnostics — emits
aviary:agent:*point events (run.started,message,tool-call,delegated,retrieved,quota.exceeded,run.failed,run.finished) on Node'sdiagnostics_channel, plus tracing spans (llm.turn,tool.execution,retrieval,follow-ups) correlated bytraceId = runId. - Telescope —
@dudousxd/nestjs-agent-telescopeadds an "Agent" tab with the governance sections (including Reliability and Approvals); runs also appear in the durable "Workflows" tab for free, and each run's spans render as a nested waterfall in Telescope's TRACES tab. - Codegen — a
@dudousxd/nestjs-agent-codegenextension injectsapi.agent.*into the unified typed client. - Module convention —
forRoot/forRootAsync,@Agent-decorated providers discovered at boot, andSymbol.forcapabilities.
Status
Early development (0.x). The full family ships today — core, the NestJS module (inline + durable
runners, the latter dispatching model/tool steps across the fleet by default), MikroORM and Drizzle
persistence (including model pricing and run reliability), the governance read-model (spend, run
reliability, tool stats, a cross-thread approvals inbox, paginated/filterable lists), the standalone
dashboard, the telescope extension (including run tracing), governed SQL (-data), the React
frontend (-react), the AI SDK model adapter (-ai-sdk), codegen, a Redis-backed multi-replica
token sink (-transport-redis), and a runnable fully-offline end-to-end demo. The package surface
and SPIs are still stabilizing.
Where to go next
Getting Started
Install, declare a tool, register the module, and stream your first turn.
Tools
@AiTool classes, read vs. action, the handler signature, and the tool context.
Identity & Authorization
ActorResolver, role vs. ability gates, and there being no insecure default.
Human-in-the-loop & Durability
Action approval as a durable signal — the run suspends and resumes across restarts.
Multi-agent
Orchestrators delegating to named sub-agents via a synthesized ask_<name> tool.
Cost & Governance
The usage ledger, reported-cost-wins, cache-aware pricing, and the console.
Persistence
The AgentStore SPI on MikroORM or Drizzle — threads, messages, usage, pricing.
Frontend
useAgentChat, styling-agnostic components, and the markdown renderer.
Bring your own UI
No shipped components: build a chat on the headless hook, own every pixel.