Agentuity projects keep runtime behavior in code and deployment metadata in agentuity.json.
agentuity.json
The project configuration file:
{
"$schema": "https://agentuity.dev/schema/cli/v1/agentuity.json",
"projectId": "proj_...",
"orgId": "org_...",
"region": "use",
"deployment": {
"resources": {
"memory": "500Mi",
"cpu": "500m",
"disk": "500Mi"
},
"domains": []
}
}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,
analytics: true,
});
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 analytics and service configuration 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": {
"memory": "500Mi",
"cpu": "500m",
"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.
Run Deploy Lifecycle Scripts
Run custom steps before or after deployment using predeploy and postdeploy scripts in package.json:
{
"scripts": {
"predeploy": "bun run typecheck",
"deploy": "agentuity deploy",
"postdeploy": "echo 'Deploy complete'"
}
}Package manager lifecycle hooks run when you call bun run deploy. Running agentuity deploy directly skips predeploy and postdeploy.
When deploying via the Agentuity GitHub App, the platform always runs bun install first. If predeploy is defined, it runs after dependency installation and before agentuity deploy. 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.
Agentuity Keys
Use AGENTUITY_SDK_KEY in project code. The CLI writes this key to .env when you create, import, reconcile, or pull a project environment. Runtime services, AI Gateway calls, standalone packages, and deployed app code read it when they call Agentuity services.
CLI authentication is separate. agentuity auth login stores the CLI credential in your OS keychain or Agentuity config. Automation can pass AGENTUITY_API_KEY, or AGENTUITY_CLI_API_KEY with AGENTUITY_USER_ID, so the CLI can run project and deployment commands without an interactive login. Do not read those variables from app code.
AGENTUITY_CLI_KEY is not the CLI login variable. Some standalone clients accept it as a compatibility fallback API key env var, but new examples and projects should use AGENTUITY_SDK_KEY or pass apiKey directly.
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.
Profile-specific files use the active CLI profile. See CLI Profiles for switching profiles and profile-specific defaults.
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 and .env.*. If you add differently named secret files, add them to .gitignore too.
Infrastructure as Code
Agentuity defines route infrastructure in your source files:
// src/api/index.ts
import { Hono } from 'hono';
import type { Env } from '@agentuity/runtime';
import { websocket } from '@agentuity/runtime';
import chatHandler from '@agent/chat/agent';
const api = new Hono<Env>()
// Standard HTTP endpoint
.post('/cleanup', async (c) => {
return c.text('OK');
})
// WebSocket endpoint
.get('/chat', websocket((c, ws) => {
ws.onMessage(async (event) => {
if (typeof event.data !== 'string') {
ws.send(JSON.stringify({ error: 'Only text frames are supported' }));
return;
}
const result = await chatHandler.run({ message: event.data });
ws.send(JSON.stringify(result));
});
}));
export default api;This keeps routes and agent registration in version control with the code that handles them.
Next Steps
- HTTP Routes: Define HTTP endpoints
- Schedules: Run recurring tasks
- AI Gateway: Configure LLM providers