Documentation menu
Documentation

Write an agent

Start with one durable responsibility, then add the human surface and capabilities it actually needs.

The 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.

agents/counter/agent.ts
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 workerd
  • app.tsx — browser UI for people
  • tools.ts — deployable tools in workerd
  • tools.host.ts — explicitly permissioned Bun capabilities
  • workflow.ts — durable multi-step work