Documentation menu
Start here
IntroductionGetting startedWrite an agentProject anatomyUnderstand Ayjnt
Harness engineeringTwo runtimesHuman interfacesHow agents workHost bridgeAgent capabilities
Callable methodsState & SQLiteSessions & memorySchedulingWorkflowsDurable executionInter-agent RPCSub-agentsToolsInterfaces & integrations
Browser clientRouting & middlewareVoiceBrowser toolsMCPEmailObservabilityCLI
Command overviewnewdevrunbuildcompilemigratedeployAPI reference
AgentAgentClientWorkflow classesLocal & cloudMigrationsExamplesRouting and middleware
The folder tree is the route tree; middleware follows the same hierarchy.
Start from a fresh project
This guide is self-contained. Create an empty Ayjnt project, then replace the starter agent with the files shown below. Run commands from the new project directory unless a step says otherwise.
bunx ayjnt new try-routing --empty
cd try-routing
bun install
# remove agents/alive once you are ready to add the guide's filesRoutes from files
agents/reports/agent.ts maps to /reports/:name. Nested folders create nested prefixes. A folder may contain both an agent and descendants.
Ayjnt routes HTTP and WebSocket upgrades to the named Durable Object instance and serves a co-located app shell on the same route.
Middleware
Place middleware.ts in an agent folder to wrap that route and every descendant. Use it for authentication, tenancy, request context, and policy before an agent wakes.
import type { Middleware } from "ayjnt";
const auth: Middleware = async (context, next) => {
const token = context.request.headers.get("authorization");
if (!token) return new Response("Unauthorized", { status: 401 });
return next();
};
export default auth;Run it and verify the result
Visit two different instance names and verify they have independent state while sharing the same agent class.
bun run build
bun run dev
# the local app is now available at http://localhost:8787