@Application
The @Application decorator defines the single assembly root (*.application.ts) of an AGBoss service. It wires your top-level @Workflow classes, typed environment contract, @ModelProvider gateways, mandatory @Budget caps, @PiiPolicy rules, ExecutionObserver hooks, and multi-instance storage repositories into one container verified at startup by createApp(Application) and in tests by testWith(Application).
Complete @Application example with all capabilities
Section titled “Complete @Application example with all capabilities”import { Application, SqliteCheckpointSaver, SqliteCostLedgerRepository, SqliteExecutionLeaseRepository, SqliteExecutionRecordRepository, SqliteExecutionTreeRepository, SqlitePausedExecutionRepository, SqliteRateLimitRepository,} from "@agboss/core";import { Reasoning, ReasoningEffort } from "@agboss/core/models";import { hours, seconds } from "@agboss/core/units";import { AppDailyBudget, ExecutionRunBudget, TenantMonthlyBudget,} from "./budgets/support.budgets.js";import { AppEnvironment, SupportExecutionContext, SupportTenantContext,} from "./support.contracts.js";import { ContactPiiPolicy, DecisionsModelProvider, MetricsObserver, OpenRouterModelProvider, SlackRefundApprovalChannel, SupportWorkflow,} from "./support.components.js";
@Application({ name: "support-application", version: "0.1.0", workflows: [SupportWorkflow], environment: AppEnvironment, tenantContext: SupportTenantContext, executionContext: SupportExecutionContext, providers: [ OpenRouterModelProvider, DecisionsModelProvider, SlackRefundApprovalChannel, SqliteCheckpointSaver, SqliteCostLedgerRepository, SqliteExecutionRecordRepository, SqlitePausedExecutionRepository, SqliteExecutionLeaseRepository, SqliteExecutionTreeRepository, SqliteRateLimitRepository, ], budgets: [ AppDailyBudget, TenantMonthlyBudget, ExecutionRunBudget, ], piiPolicies: [ContactPiiPolicy], pseudonymKey: "piiPseudonymKey", observers: [MetricsObserver], uncompactedTurns: 6, defaults: { models: { temperature: 0, reasoning: Reasoning.on({ effort: ReasoningEffort.Low }), }, router: { model: "typesafe/jev-1.13", }, tools: { maxToolCalls: 8, }, }, pauseRecordRetention: hours(48), shutdownTimeout: seconds(25),})export class SupportApplication {}
export { SupportWorkflow };import { env, secret } from "@agboss/core";import type { AppEnvironment } from "../support.contracts.js";
export const environment: AppEnvironment = { openRouterApiKey: secret("OPENROUTER_API_KEY"), piiPseudonymKey: secret("PII_PSEUDONYM_KEY"), sqlitePath: env("AGBOSS_SQLITE_PATH", { default: ".agboss/state.sqlite" }), webhookBaseUrl: env.optional("WEBHOOK_BASE_URL"),};import { Budget, BudgetPeriod, BudgetScope, type BudgetHandler } from "@agboss/core";import { usd, type Usd } from "@agboss/core/units";
@Budget({ name: "app-daily-budget", scope: BudgetScope.Application, period: BudgetPeriod.Day })export class AppDailyBudget implements BudgetHandler { maxSpend(): Usd { return usd(200); }}
@Budget({ name: "tenant-monthly-budget", scope: BudgetScope.Tenant, period: BudgetPeriod.Month })export class TenantMonthlyBudget implements BudgetHandler { maxSpend(): Usd { return usd(50); }}
@Budget({ name: "execution-run-budget", scope: BudgetScope.Execution })export class ExecutionRunBudget implements BudgetHandler { maxSpend(): Usd { return usd(0.5); }}import { ExecutionStatus, createApp } from "@agboss/core";import { seconds } from "@agboss/core/units";import { SupportApplication } from "./support.application.js";import { ChatWorkflowStart } from "./support.components.js";
export async function runSupportServer() { const app = await createApp(SupportApplication, { env: "prod" });
const result = await app.execute( ChatWorkflowStart, { text: "Please refund order #A-1042" }, { threadId: "thread-1042", ownerId: "user-42", tenant: { tenantId: "acme", weight: 3, planTier: "enterprise" }, execution: { accountId: "acc-99" }, record: true, }, );
if (result.status === ExecutionStatus.Paused) { const pause = result.pending[0]; if (pause?.pauseId !== undefined) { await app.resume( { pauseId: pause.pauseId, decision: { approved: true } }, { tenantId: "acme", answeredBy: "finance-lead" }, ); } }
process.once("SIGTERM", () => { void app.close({ timeout: seconds(25) }); });}import { expect } from "vitest";import { ExecutionStatus } from "@agboss/core";import { replyWith, testWith } from "@agboss/core/testing";import { SupportApplication } from "../src/support.application.js";import { ChatWorkflowStart, SupportAgent } from "../src/support.components.js";
const test = testWith(SupportApplication, { instances: 2 });
test("boots the application container and executes ChatWorkflowStart", async ({ app, mockLlm }) => { mockLlm(SupportAgent).thenReturn(replyWith("Refund processed.")); const res = await app.execute( ChatWorkflowStart, { text: "Refund order #194" }, { tenant: { tenantId: "acme", weight: 2, planTier: "pro" }, execution: { accountId: "acc-1" }, }, ); expect(res.status).toBe(ExecutionStatus.Finished);});What options does @Application accept?
Section titled “What options does @Application accept?”Every @Application class name ends with Application and its name option ends with -application:
| Option | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | Unique kebab-case identifier ending with -application (e.g., "job-scout-application"). |
version |
string |
Yes | Semantic release version of the application ("0.1.0"), recorded in logs and traces. |
workflows |
readonly Class[] |
Yes | Top-level @Workflow classes registered in the application; child workflows are discovered automatically. |
environment |
Class |
Yes | Environment contract class (AppEnvironment or EmptyEnvironment) validated at startup. |
providers |
readonly Provider[] |
No | Infrastructure repository implementations (Sqlite*Repository), @ModelProvider classes, @Channel implementations, and shared @Injectable services. |
budgets |
readonly Class[] |
No | @Budget classes enforcing spend caps across Application, Tenant, and Execution scopes. |
observers |
readonly ObserverClass[] |
No | @Injectable classes implementing OnExecutionEnd, OnToolEnd, OnModelEnd, OnValuesOutdated, and other observer hooks. |
healthChecks |
readonly Class[] |
No | @HealthCheck classes executed by app.checkReadiness() and app.checkLiveness() alongside built-in repository and concurrency checks. |
piiPolicies |
readonly Class[] |
No | Application-wide @PiiPolicy classes applied to every agent, router, log entry, and trace. |
guardrails |
readonly Class[] |
No | Application-wide @InputGuardrail and @OutputGuardrail classes applied to every agent and model router. |
toolInterceptors |
readonly Class[] |
No | Application-wide @ToolInterceptor classes applied to every @Tool and @McpTool call. |
maxMeshHops |
number |
No | Maximum cross-service A2A/MCP federation hops allowed (8 by default; throws HopsLimitExceededError when exceeded). |
mesh |
MeshOptions |
No | Agent Mesh Envelope signing and verification settings ({ signingKey, peers, idempotencyRetention }) for multi-service A2A/MCP deployments. |
compaction |
Class |
No | Default @Compaction class summarizing turns older than uncompactedTurns. |
uncompactedTurns |
number | TurnLimit |
No | Default number of recent turns shown in full to every agent and model router (5 by default, or TurnLimit.ALL). |
pseudonymKey |
string |
No | Name of a Secret field on the environment class used for HMAC token pseudonymization across all pods. |
tenantContext |
TenantContextClass |
No | Custom subclass of TenantContext whose decorated DTO fields (without prompt, [context.prompt-unused]) are required on app.execute(..., { tenant }). |
executionContext |
ExecutionContextClass |
No | Custom subclass of ExecutionContext carrying per-execution identity fields passed via app.execute(..., { execution }). |
defaults |
WorkflowDefaults |
No | Default models, router, guardrail, tools, and flow settings inherited by all workflows. |
exposes |
readonly Class[] |
No | @A2AExpose and @McpExpose contract classes served over A2A/MCP and exported in agboss describe --json. |
maxConcurrentSteps |
number |
No | Maximum @Agent, @Router, and @Action steps running concurrently in this process before queueing by priority and reporting step-slots as HealthStatus.Degraded. |
compensationTimeout |
Milliseconds |
No | Dedicated cleanup window for automatic LIFO saga compensation when an execution is cancelled or hits a limit (seconds(30) by default). |
pauseRecordRetention |
Milliseconds |
No | How long resolved or cancelled pause records remain stored (hours(24) by default). |
executionRecordRetention |
Milliseconds |
No | How long completed ExecutionRecord snapshots remain in ExecutionHistoryRepository (days(7) by default). |
shutdownTimeout |
Milliseconds |
No | Grace period for app.close() and SIGTERM / SIGINT drain before releasing active execution leases (seconds(25) by default). |
What related entities work with @Application?
Section titled “What related entities work with @Application?”| Related Entity | Import Path | Purpose |
|---|---|---|
createApp(AppClass, options?) |
"@agboss/core" |
Boots the container, runs onInit() and onStart() on all components, starts recovery sweeps, and returns the App handle. |
App (execute, resume, cancel, checkReadiness, checkLiveness, close, tool) |
"@agboss/core" |
Runtime handle used to start workflows, resume pauses, cancel runs (app.cancel(threadId)), report pod health (HealthStatus.Healthy / HealthStatus.Degraded / HealthStatus.Unhealthy), invoke isolated tools, and drain gracefully on shutdown. |
EmptyEnvironment |
"@agboss/core" |
Built-in empty contract class for applications that do not read environment variables. |
env(), env.optional(), secret() |
"@agboss/core" |
Readers used in environments/*.environment.ts files to bind and validate process.env variables at startup. |
ApplicationContext, Clock, Logger |
"@agboss/core" |
Built-in container singletons injectable into any service, action, tool, or observer via deps. |
Sqlite*Repository (10 classes) |
"@agboss/core" |
Zero-dependency node:sqlite WAL implementations of the 10 multi-instance durability, child work-stealing (SqliteChildExecutionQueueRepository), history (SqliteExecutionHistoryRepository), and mesh deduplication (SqliteMeshRequestRepository) contracts. |
testWith(AppClass, options?) |
"@agboss/core/testing" |
Deterministic test harness that boots one or more application instances with DI overrides and a VirtualClock. |