Agentuity projects use minimal configuration. Most setup happens in code, not config files.
agentuity.json
The project configuration file:
{
"projectId": "proj_...",
"orgId": "org_...",
"region": "use"
}No agent definitions, no trigger configurations. Those live in your code.
app.ts
The app entry point wires agents, routes, and configuration together:
import { createApp } from '@agentuity/runtime';
import agents from './src/agent';
import api from './src/api';
const app = await createApp({
router: { path: '/api', router: api },
agents,
workbench: { route: '/workbench' },
});
app.logger.debug('Running %s', app.server.url);
export default app;With Startup and Cleanup Logic
Initialize shared resources in modules or startup code, then register cleanup with registerShutdownHook():
import { createApp, registerShutdownHook } from '@agentuity/runtime';
const db = await connectDatabase();
registerShutdownHook(async () => {
await db.close();
});
const app = await createApp({
router: { path: '/api', router: api },
agents,
});
app.logger.debug('Running %s', app.server.url);
export default app;With Additional Options
import { createApp } from '@agentuity/runtime';
import agents from './src/agent';
import api from './src/api';
const app = await createApp({
router: { path: '/api', router: api },
agents,
// CORS configuration
cors: {
sameOrigin: true,
allowedOrigins: ['https://myapp.com'],
},
// Response compression (gzip/deflate)
compression: {
threshold: 1024, // Compress responses larger than 1KB (default)
},
// Custom storage implementations (optional)
services: {
keyvalue: myCustomKV,
vector: myCustomVector,
},
});
export default app;Compression Options
| Option | Type | Default | Description |
|---|---|---|---|
enabled | boolean | true | Enable/disable compression |
threshold | number | 1024 | Minimum response size (bytes) to compress |
filter | (c) => boolean | - | Custom filter function |
Compression automatically bypasses WebSocket upgrades and requests without Accept-Encoding headers.
Event Listeners
Listen for agent lifecycle events using the top-level addEventListener:
import { addEventListener } from '@agentuity/runtime';
addEventListener('agent.started', (eventName, agent, ctx) => {
ctx.logger.info('Agent started', { name: agent.metadata.name });
});
addEventListener('agent.completed', (eventName, agent, ctx) => {
ctx.logger.info('Agent completed', { session: ctx.sessionId });
});Build Configuration
Use vite.config.ts for build settings (plugins, entry point, rollup options). Runtime settings like workbench and analytics belong in createApp().
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';
import { defineConfig } from 'vite';
import { join } from 'node:path';
export default defineConfig({
plugins: [react(), tailwindcss()],
root: '.',
build: {
rollupOptions: {
input: join(import.meta.dirname, 'src/web/index.html'),
},
},
});Most projects only need to change plugins in vite.config.ts. The default template includes React and Tailwind CSS. Replace them with your framework of choice (e.g., @sveltejs/vite-plugin-svelte).
See the reference page for all options and examples.
Configuring Deployment and Build Resources
Configure how your project runs and builds in the cloud using the deployment and build sections of agentuity.json.
deployment
The deployment section controls resources allocated when your project is handling requests, and any custom domains:
deployment.resources: CPU, memory, and disk allocated to the running servicedeployment.domains: custom domains attached to the project
build
The build section controls the sandbox where your project compiles during cloud deployment:
build.timeout: maximum time allowed for the build (e.g.,"30m")build.resources: memory, CPU, and disk for the build sandbox
{
"projectId": "proj_...",
"orgId": "org_...",
"region": "use",
"deployment": {
"resources": {
"cpu": "500m",
"memory": "500Mi",
"disk": "500Mi"
},
"domains": []
},
"build": {
"timeout": "30m",
"resources": {
"memory": "4Gi",
"cpu": "2",
"disk": "4Gi"
}
}
}deployment.resources controls what your service gets when handling requests. build.resources controls the isolated sandbox where your project compiles. Increase build resources if you have large dependencies or complex compilation steps.
For detailed options, see Deploying to the Cloud.
Running Deploy Lifecycle Scripts
Run custom steps before or after deployment using predeploy and postdeploy scripts in package.json:
{
"scripts": {
"predeploy": "cd ../.. && bun install && bun run build:packages",
"deploy": "agentuity deploy",
"postdeploy": "echo 'Deploy complete'"
}
}When deploying via the Agentuity GitHub App, defining predeploy gives you full control over the install step. Without it, the platform runs bun install automatically. See Running Deploy Lifecycle Scripts for the full reference.
Environment Variables
# Required
AGENTUITY_SDK_KEY=... # API key for Agentuity services
# Optional
AGENTUITY_LOG_LEVEL=info # trace, debug, info, warn, error
PORT=3500 # Dev server port (default: 3500)
# Resource Credentials (auto-added by CLI when creating resources)
DATABASE_URL=postgresql://... # Added by: agentuity cloud db create
# S3 credentials # Added by: agentuity cloud s3 create
# REDIS_URL=redis://... # From: agentuity cloud redis show
# LLM Provider Keys (optional; if using your own API keys instead of the AI Gateway)
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
# Frontend-accessible (exposed to browser)
AGENTUITY_PUBLIC_API_URL=... # Any of these prefixes work:
VITE_MY_VAR=... # - AGENTUITY_PUBLIC_*
PUBLIC_MY_VAR=... # - VITE_*
# - PUBLIC_*If you don't set provider API keys, LLM requests are routed through the Agentuity AI Gateway using your SDK key. This provides unified billing and monitoring.
Environment variables prefixed with AGENTUITY_PUBLIC_, VITE_, or PUBLIC_ are exposed to the frontend bundle and visible in the browser. Never put secrets or API keys in these variables.
Environment-Specific Files
Use separate .env files instead of commenting/uncommenting variables when switching between local development and deployed contexts.
File loading order today:
| Mode | Files checked |
|---|---|
agentuity dev / local profile | .env.{profile} → .env.development → .env |
| Production build or non-local profile | .env.{profile} → .env → .env.production |
Files loaded later in the chain override earlier ones. For agentuity dev, the order is .env.{profile} then .env.development then .env, so .env wins when keys conflict. For deployed or non-local profiles, the order is .env.{profile} then .env then .env.production, so .env.production wins.
Example setup:
# Shared defaults loaded in development and production
AGENTUITY_SDK_KEY=sdk_...
OPENAI_API_KEY=sk-...
AGENTUITY_PUBLIC_API_URL=https://your-project.agentuity.run# Development-only values
DEBUG=true
TRUSTED_ORIGINS=http://localhost:3000Instead of commenting out lines when switching contexts, put shared defaults in .env and values that only exist in local development in .env.development. Be careful with duplicate keys: the CLI loads .env.development before .env, so .env (loaded last) wins when both define the same variable.
Additional files:
.env.local: Bun may use this for app runtime behavior, but the Agentuity CLI does not currently include.env.localwhen it searches forAGENTUITY_SDK_KEYduringagentuity devor deploy preflight. Keep required CLI credentials in one of the files listed above.
Git behavior: The default .gitignore ignores .env. Other env files (.env.development, .env.local, profile-specific files) are not ignored by default. Add any files containing secrets to your .gitignore.
Infrastructure as Code
Unlike traditional platforms, Agentuity defines infrastructure in your route files:
// src/api/index.ts
import { Hono } from 'hono';
import type { Env } from '@agentuity/runtime';
import { cron, websocket } from '@agentuity/runtime';
import scheduler from '@agent/scheduler/agent';
import chatHandler from '@agent/chat/agent';
const api = new Hono<Env>()
// Cron job - runs every hour
.post('/cleanup', cron('0 * * * *', { auth: true }, async (c) => {
await scheduler.run({ task: 'cleanup' });
return c.text('OK');
}))
// WebSocket endpoint
.get('/chat', websocket((c, ws) => {
ws.onMessage(async (event) => {
const result = await chatHandler.run({ message: event.data as string });
ws.send(JSON.stringify(result));
});
}));
export default api;This approach means:
- Deployments are self-contained: rolling back restores exact configuration
- Version control: your infrastructure changes are tracked in Git
- No config drift: what's in code is what runs
Next Steps
- HTTP Routes: Define HTTP endpoints
- Cron Jobs: Schedule recurring tasks
- AI Gateway: Configure LLM providers