Skip to content

@Application & Runtime

Every AGBoss service has a single @Application assembly root that lists the workflows, typed environment contract, shared @ModelProvider classes, mandatory @Budget ceilings (application, tenant, and execution scopes), @PiiPolicy rules, @InputGuardrail / @OutputGuardrail policies, observers, @HealthCheck probes, and storage repositories. Both createApp(Application, options) and testWith(Application) boot this container, validating every contract at startup before any workflow executes.

How to declare an @Application and its environment contract

Section titled “How to declare an @Application and its environment contract”

An application’s environment contract is a plain class declaring field types only (environments/app.environment.ts next to the application file — never place secret() or env() property initializers on the class itself, which triggers [environment.contract-value]). Each environment file (dev.environment.ts, prod.environment.ts, test.environment.ts) exports a typed environment object using env(), env.optional(), env.integer(), env.flag(), and secret():

Option Purpose
workflows @Workflow classes exposed by the application. Calling app.execute(StartClass, input) runs the workflow owning that @WorkflowStart.
environment Environment contract class (or EmptyEnvironment when no environment variables are needed). Secret fields mask as *** everywhere except .reveal().
providers Infrastructure and shared providers: @ModelProvider classes, @Channel implementations, custom Logger / Clock, and Sqlite*Repository stores.
budgets @Budget classes covering BudgetScope.Application, BudgetScope.Tenant, and BudgetScope.Execution (checked at assembly).
piiPolicies Application-wide @PiiPolicy classes masking personal data at model boundaries and across logs, traces, and records.
guardrails Application-wide @InputGuardrail and @OutputGuardrail classes cascaded to every workflow, agent, and model router.
compaction / uncompactedTurns Application-wide @Compaction strategy (SummaryQueue, SingleSummary, None) and recent turn preservation window.
observers @Injectable() observer classes implementing hooks like OnExecutionEnd, OnAgentStart, OnExecutionRejected, or OnExecutionResume.
healthChecks @HealthCheck classes invoked by app.checkLiveness() and app.checkReadiness().
maxConcurrentSteps Instance-wide step ceiling; when saturated, app.checkReadiness() reports Degraded so Kubernetes load balancers shift new traffic to idle pods.
pauseRecordRetention How long resolved pause records are kept before the 30-second recovery sweep purges them (default hours(24)).
shutdownTimeout Graceful drain window on app.close() or SIGTERM / SIGINT (default seconds(25)), after which remaining runs release their leases for peer instances.

4-Stage Progressive Infrastructure Scaling

Section titled “4-Stage Progressive Infrastructure Scaling”

Because @Application({ providers }) resolves storage contracts by class inheritance (SqliteCheckpointSaver extends CheckpointSaver), you can scale from local unit tests to multi-pod Kubernetes clusters without changing a single line of @Workflow or @Agent code:

  1. Stage 1 — Local Dev & Isolated Tests: Default InMemory* stores, testWith(App), VirtualClock, and 8 unit runners.
  2. Stage 2 — Single-Node Durable Production (node:sqlite WAL): Register the 7 Sqlite* providers (SqliteCheckpointSaver, SqliteExecutionRecordRepository, SqlitePausedExecutionRepository, SqliteCostLedgerRepository, SqliteExecutionLeaseRepository, SqliteExecutionTreeRepository, SqliteRateLimitRepository).
  3. Stage 3 — Multi-Pod Cluster & K8s Probes: Horizontal replicas coordinate via 30s leases, 30s orphan recovery sweeps, maxConcurrentSteps, and app.checkLiveness() / app.checkReadiness().
  4. Stage 4 — Custom Enterprise Backends: Subclass any of the 7 repository contracts (PostgresCheckpointSaver extends CheckpointSaver) and list it in providers.

How app.execute, app.resume, app.cancel, and app.close work

Section titled “How app.execute, app.resume, app.cancel, and app.close work”
  • app.execute(StartClass, input, options?) — Starts or continues a workflow thread scoped by { threadId, ownerId, tenant: { tenantId, weight }, onStream }, checking all budgets before the first step.
  • app.resume({ pauseId, reply }, options?) — Atomically records a human-in-the-loop reply (Pending -> Resolved), acquires the execution tree’s 30-second lease, and continues from the checkpoint.
  • app.cancel(threadId, { tenantId, ownerId }) — Aborts a running execution before its next model or tool call (ExecutionCancelledError) or withdraws pending pauses (ChannelHandler.withdraw(info)) on a paused thread.
  • app.close({ timeout? }) — Rejects new executions with ApplicationStoppingError, stops the recovery sweep, runs onStop, waits up to timeout for active steps to finish or pause, releases remaining leases so peer instances can recover them immediately, and runs onDestroy.