A new Agentuity project created with agentuity create.
A fully configured Agentuity project with:
- ✅ TypeScript - Full type safety out of the box
- ✅ Bun runtime - Fast JavaScript runtime and package manager
- ✅ Hot reload - Development server with auto-rebuild
- ✅ Example agent - Sample "hello" agent to get started
- ✅ React frontend - Pre-configured web interface
- ✅ API routes - Example API endpoints
- ✅ Type checking - TypeScript configuration ready to go
my-app/
├── src/
│ ├── agent/ # Agent definitions
│ │ └── hello/
│ │ ├── agent.ts # Example agent
│ │ └── index.ts # Default exports
│ ├── api/ # API definitions
│ │ └── index.ts # Example routes
│ └── web/ # React web application
│ ├── public/ # Static assets
│ ├── App.tsx # Main React component
│ ├── frontend.tsx # Entry point
│ └── index.html # HTML template
├── AGENTS.md # Agent guidelines
├── app.ts # Application entry point
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies and scripts
└── README.md # Project documentation
After creating your project, you can run:
bun devStarts the development server at http://localhost:3500
bun buildCompiles your application into the .agentuity/ directory
bun typecheckRuns TypeScript type checking
bun run deployDeploys your application to the Agentuity cloud
After creating your project:
- Customize the example agent - Edit
src/agent/hello/agent.ts - Add new agents - Create new folders in
src/agent/ - Add new APIs - Create new folders in
src/api/ - Add Web files - Create new routes in
src/web/ - Customize the UI - Edit
src/web/app.tsx - Configure your app - Modify
app.tsto add middleware, configure services, etc.
Create a new agent by adding a folder in src/agent/:
// src/agent/my-agent/agent.ts
import { createAgent } from '@agentuity/runtime';
import { s } from '@agentuity/schema';
const agent = createAgent({
description: 'My amazing agent',
schema: {
input: s.object({
name: s.string(),
}),
output: s.string(),
},
handler: async (_ctx, { name }) => {
return `Hello, ${name}! This is my custom agent.`;
},
});
export default agent;Create custom routes in src/api/:
// src/api/my-agent/route.ts
import { createRouter } from '@agentuity/runtime';
import myAgent from './agent';
const router = createRouter();
router.get('/', async (c) => {
const result = await myAgent.run({ message: 'Hello!' });
return c.json(result);
});
router.post('/', myAgent.validator(), async (c) => {
const data = c.req.valid('json');
const result = await myAgent.run(data);
return c.json(result);
});
export default router;This project includes an AI layer for perception → reasoning → planning → action on top of Plaid transactions and Supabase goals.
- Perception: Plaid sends webhooks to
POST /api/webhooks/plaidwhen new transactions are available (e.g.SYNC_UPDATES_AVAILABLE,DEFAULT_UPDATE). Optionally setPLAID_WEBHOOK_FORWARD_URLso this service forwards the webhook to your Django backend; Django can then fetch new transactions from Plaid and call the analyze API. - Reasoning + Planning: Your backend (e.g. Django) calls
POST /api/insights/analyzewith the new transaction plus user context (goals from Supabase, budgets, recent transactions). The agent reasons (e.g. “merchant is a streaming service; user has 3 already and is $40 over Entertainment budget”) and produces a plan (e.g. “flag zombie sub, suggest trade-off for savings goal”). - Action: If the agent decides the user should be notified, a notification is stored and returned. Your NextJS app can poll
GET /api/notifications?userId=...to show items in the notification bar.
| Method | Path | Description |
|---|---|---|
GET |
/api/transactions?userId= |
Fetch all transactions from Plaid for the user. Uses access_token from Supabase user_plaid_items. Results are cached in memory for the session (not persisted). |
POST |
/api/insights/analyze |
Run financial insights agent. Body: { userId, transaction } only. Server fetches access_token from Supabase user_plaid_items, goals from Supabase goals, and transaction history from in-memory cache (or Plaid if not cached). Returns { reasoning, plan, notification, shouldNotify }. |
GET |
/api/notifications?userId= |
List notifications for the user (for the notification bar). |
POST |
/api/webhooks/plaid |
Plaid webhook receiver. Returns 200 immediately. Optionally forwards to PLAID_WEBHOOK_FORWARD_URL. |
- user_plaid_items — columns:
user_id,access_token,item_id(optional). Used to get Plaid access token byuser_id. - goals — columns:
user_id,name,target_amount,current_amount,deadline,category(optional). Fetched for the agent context.
# 1. Load transactions (caches in memory)
curl "https://your-ledgerly-ai.run/api/transactions?userId=user-uuid"
# 2. Analyze a new (e.g. manual) transaction; server fetches goals + history
curl -X POST https://your-ledgerly-ai.run/api/insights/analyze \
-H "Content-Type: application/json" \
-d '{
"userId": "user-uuid",
"transaction": {
"name": "STREAMING CO",
"amount": -19.99,
"date": "2025-02-07",
"category": ["Subscription"],
"personal_finance_category": { "primary": "ENTERTAINMENT" }
}
}'- Supabase:
SUPABASE_URL,SUPABASE_SERVICE_ROLE_KEY(orSUPABASE_ANON_KEY) foruser_plaid_itemsandgoals. - Plaid:
PLAID_CLIENT_ID,PLAID_SECRET. Optional:PLAID_ENV=development(default) orproduction. PLAID_WEBHOOK_FORWARD_URL(optional): URL to POST the raw Plaid webhook payload (e.g. your Django endpoint).- OpenAI (or AI Gateway) is used by the financial-insights agent; ensure your Agentuity/OpenAI config is set.
- Bun v1.0 or higher
- TypeScript 5+