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 & cloudMigrationsExamplesWrite an agent
Start with one durable responsibility, then add the human surface and capabilities it actually needs.
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-writing-agents --empty
cd try-writing-agents
bun install
# remove agents/alive once you are ready to add the guide's filesThe smallest useful agent
Create agents/<route>/agent.ts and default-export a class extending Ayjnt’s Agent. Code generation discovers it, creates the Durable Object binding, and routes requests from the folder path.
You may instead import Agent directly from agents. Discovery, routing, bindings, app.tsx, tools, and workflows work the same way. Use Ayjnt’s class when you want its peer-agent and session conveniences; use Cloudflare’s class when you want the upstream surface only.
import { Agent, callable } from "ayjnt";
type State = { count: number };
export default class CounterAgent extends Agent<State> {
initialState: State = { count: 0 };
@callable({ description: "Increase the counter." })
increment(by = 1) {
this.setState({ count: this.state.count + by });
return this.state.count;
}
}Add a front door
Place app.tsx beside the agent for a browser interface. Add a root cli.ts for a terminal interface. Both receive typed access generated from the agent class.
Keep privileged work out of the model loop by default. Expose narrow tools, validate their input, declare side effects, and require a person before consequential actions.
agent.ts— isolated durable behavior in workerdapp.tsx— browser UI for peopletools.ts— deployable tools in workerdtools.host.ts— explicitly permissioned Bun capabilitiesworkflow.ts— durable multi-step work
Run it and verify the result
Open the route shown in the guide, call the method once, and confirm the returned state survives a page refresh.
bun run build
bun run dev
# the local app is now available at http://localhost:8787