Project Structure — Agentuity Documentation

Project Structure

Understand how Agentuity projects are organized

Agentuity projects follow a convention-based structure that enables automatic discovery and deployment.

Directory Layout

my-project/
├── agentuity.json        # Project configuration
├── .env                  # Environment variables
├── package.json          # Dependencies
├── app.ts                # App entry point
└── src/
    ├── agent/            # Agent code (required)
    │   └── chat/
    │       └── agent.ts  # Agent logic
    ├── api/              # HTTP routes (optional)
    │   └── index.ts      # All routes, imports agents
    └── web/              # Frontend code (scaffolded by default)
        └── App.tsx

Agent names come from their directory. Each agent has one file: agent.ts with your logic and schema.

Agents and Routes

Agents and routes are separate concerns in Agentuity:

ConceptLocationPurpose
Agentssrc/agent/Core logic, schemas, validation
Routessrc/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.

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/api/index.ts

Routes import agents directly and call them:

import { createRouter } from '@agentuity/runtime';
import chat from '@agent/chat';
 
const router = createRouter();
 
router.post('/chat', chat.validator(), async (c) => {
  const data = c.req.valid('json');
  const result = await chat.run(data);
  return c.json(result);
});
 
export default router;

The chat.validator() middleware 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

AgentsDirect Routes (no agent)
Locationsrc/agent/src/api/
Schema validationBuilt-in with agent.validator()Manual
Events & EvalsYesNo
Storage accessFullFull
Best forValidated workflows, LLM processingHealth 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 currently supported via @agentuity/react, with a framework-agnostic approach that enables support for Next.js, Svelte, and others.

// src/web/App.tsx
import { useAPI } from '@agentuity/react';
 
function App() {
  const { data, invoke, isLoading } = useAPI('POST /api/hello');
 
  return (
    <button onClick={() => invoke({ name: 'World' })}>
      {isLoading ? 'Loading...' : 'Say Hello'}
    </button>
  );
}

Next Steps