Agentuity projects use explicit wiring: you define agents, routes, and configuration in code.
Creating a new agent is as simple as adding a folder to src/agent/ with an agent.ts file and registering it in src/agent/index.ts.
Directory Layout
my-project/
├── agentuity.json # Project configuration
├── vite.config.ts # Build configuration (Vite plugins, entry point)
├── app.ts # App entry point (wires agents + router)
├── .env # Environment variables
├── package.json # Dependencies
└── src/
├── agent/ # Agent code
│ ├── index.ts # Agent registry (exports array of agents)
│ └── chat/
│ └── agent.ts # Agent logic
├── api/ # HTTP routes
│ └── index.ts # Router, imports agents
└── web/ # Frontend code (scaffolded by default)
├── index.html # HTML entry point
├── frontend.tsx # React entry point
└── App.tsx # Main component
Agent names come from the first argument to createAgent(). Each agent has one file: agent.ts with your logic and schema.
You can add helper files (like types.ts, helpers.ts, utils.ts) alongside your agents and routes.
Agents and Routes
Agents and routes are separate concerns in Agentuity:
| Concept | Location | Purpose |
|---|---|---|
| Agents | src/agent/ | Core logic, schemas, validation |
| Routes | src/api/ | HTTP endpoints, triggers (cron, WebSocket, SSE) |
Agents contain your core logic with schema validation and lifecycle hooks. Routes define how agents get invoked (HTTP, cron, webhooks, etc.). This separation keeps concerns clear: agents don't know how they're called, and routes handle all transport.
app.ts
app.ts is the entry point that wires agents and routes together via createApp():
import { createApp } from '@agentuity/runtime';
import agents from './src/agent';
import api from './src/api';
export default await createApp({
router: { path: '/api', router: api },
agents,
});agent.ts
import { createAgent } from '@agentuity/runtime';
import { s } from '@agentuity/schema';
const agent = createAgent('chat', {
schema: {
input: s.object({ message: s.string() }),
output: s.object({ response: s.string() }),
},
handler: async (ctx, input) => {
return { response: `Echo: ${input.message}` };
},
});
export default agent;src/agent/index.ts
The agent registry imports all agents and exports them as an array:
import chat from './chat/agent';
export default [chat];src/api/index.ts
Routes import agents directly and call them:
import { Hono } from 'hono';
import type { Env } from '@agentuity/runtime';
import chat from '@agent/chat/agent';
const api = new Hono<Env>()
.post('/chat', chat.validator(), async (c) => {
const data = c.req.valid('json');
return c.json(await chat.run(data));
});
export type ApiRouter = typeof api;
export default api;chat.validator() validates the request body against the agent's input schema and provides type-safe access via c.req.valid('json').
When to Use Agents vs Direct Routes
| Agents | Direct Routes (no agent) | |
|---|---|---|
| Location | src/agent/ | src/api/ |
| Schema validation | Built-in with agent.validator() | Manual |
| Events & Evals | Yes | No |
| Storage access | Full | Full |
| Best for | Validated workflows, LLM processing | Health checks, webhooks, simple endpoints |
Use simple routes (without calling an agent) for lightweight endpoints like health checks. For structured processing with validation, create an agent and call it from your route.
Frontend (src/web/)
Place frontend code in src/web/ to deploy alongside your agents. The CLI bundles and serves it automatically.
React is supported out of the box. Use Hono's hc() client for type-safe API calls. For browser utilities, prefer @agentuity/frontend and @agentuity/auth/react; the older @agentuity/react package remains available as a compatibility layer.
Point hc() at the same /api mount path you configured in app.ts, then import your router type from src/api/index.ts.
// src/web/App.tsx
import { hc } from 'hono/client';
import type { ApiRouter } from '../api';
const client = hc<ApiRouter>('/api');
function App() {
const handleClick = async () => {
const res = await client.chat.$post({ json: { message: 'Hello' } });
const data = await res.json();
console.log(data.response);
};
return <button onClick={handleClick}>Say Hello</button>;
}You can also deploy your frontend elsewhere (e.g., Vercel, Netlify) and call your Agentuity API routes using the Hono hc() client with a configured base URL.
Next Steps
- App Configuration: Configure
app.tsandagentuity.json - Creating Agents: Deep dive into agent creation
- Routes: Learn about HTTP, cron, and other triggers