/** * Durable background execution for the `run-code` tool. * * The hosted agent loop runs under a soft wall-clock ceiling (~40s on * serverless): a foreground `run-code` call that outlives it is aborted and — * because `run-code` is readOnly — its result is simply lost. This module is * the queued, durable alternative wired through the existing sandbox-adapter * seam: enqueue the raw code to SQL (`sandbox_executions`), return * `{ executionId, status: "queued" }` immediately, and let an executor with * its own budget claim the row, run it through the local sandbox machinery, * and persist the result for later polling. * * Execution drivers, by deployment mode: * 1. Serverless (Netlify/Vercel/Lambda/CF): `fireInternalDispatch` POSTs to * `/_agent-native/sandbox/_process-execution` on this same deployment, so * the code runs in a FRESH function invocation with its own full budget — * the same self-dispatch pattern A2A, integration webhooks, and Agent * Teams use. HMAC-verified via the shared internal-token scheme. * 2. Long-lived Node (self-hosted, local dev): the execution starts in-process * immediately after enqueue, detached from the enqueueing tool call. * 3. Opportunistic drain: every status poll re-drives a row that is still * `queued` (lost dispatch) or whose lease expired (dead executor), and a * periodic warm-instance sweep (`drainDueSandboxExecutions`, mounted by * the core routes plugin) does the same as a backstop. * * The executor itself never re-enters adapter selection (that could recurse * into this queue when `AGENT_NATIVE_SANDBOX=background`): the runner * registered by `createRunCodeEntry` executes through the non-queued adapter * (the local child process by default), with the bridge/env-scrub/module * building unchanged from the foreground path. */ import type { ActionRunContext } from "../../action.js"; import type { SandboxAdapter, SandboxRunResult } from "./adapter.js"; import { type SandboxExecutionRow } from "./executions-store.js"; export declare const SANDBOX_PROCESS_EXECUTION_PATH = "/_agent-native/sandbox/_process-execution"; export declare const BACKGROUND_DEFAULT_TIMEOUT_MS: number; export declare const BACKGROUND_MAX_TIMEOUT_MS: number; export declare const SANDBOX_EXECUTION_LEASE_MS = 90000; export declare const SANDBOX_EXECUTION_REDRIVE_AFTER_MS = 15000; export interface SandboxExecutionRunInput { code: string; timeoutMs: number; context?: ActionRunContext; } export interface SandboxExecutionRunOutput { stdout: string; stderr: string; exitCode: number | null; timedOut: boolean; bridgeToolsUsed: string[]; } export interface SandboxExecutionRunner { execute(input: SandboxExecutionRunInput): Promise; } export declare function registerSandboxExecutionRunner(runner: SandboxExecutionRunner, options?: { replace?: boolean; }): void; export declare function getSandboxExecutionRunner(): SandboxExecutionRunner | undefined; export declare function resetSandboxBackgroundForTests(): void; export declare class BackgroundQueueAdapter implements SandboxAdapter { readonly id = "background-queue"; readonly queued: true; run(): Promise; } export declare function isQueuedSandboxAdapter(adapter: SandboxAdapter | null | undefined): boolean; export interface EnqueueSandboxExecutionInput { code: string; timeoutMs: number; maxOutputChars: number; owner: string; orgId?: string | null; threadId?: string | null; allowedActionNames?: readonly string[]; } export interface EnqueueSandboxExecutionResult { execution: SandboxExecutionRow; driveNote?: string; } export declare function enqueueSandboxExecution(input: EnqueueSandboxExecutionInput): Promise; export declare function driveSandboxExecution(executionId: string, options?: { event?: unknown; }): Promise; export interface ProcessSandboxExecutionResult { status: "completed" | "already_claimed" | "not_found" | "not_due" | "runner_unavailable"; finalStatus?: SandboxExecutionRow["status"]; } export declare function processQueuedSandboxExecution(executionId: string): Promise; export declare function drainDueSandboxExecutions(options?: { limit?: number; event?: unknown; }): Promise;