Skip to main content
Runtime Controls wrap your functions with composable guardrails so agents can run autonomously without spiraling into infinite loops, duplicate writes, or runaway tool-call volume. No API key required — they work standalone around your own code, or combined with Buildfunctions hardware-isolated sandboxes.
Runtime Controls is in beta. The SDK interface may change between releases.

Install

Why Runtime Controls

When agents run unattended, things go wrong:
  • Infinite loops - the agent retries the same failing call forever
  • Runaway tool-call volume - unchecked tool calls can spike API usage quickly
  • Duplicate side effects - the same write runs twice
  • Unsafe actions - an agent executes destructive operations
  • Cascading failures - one broken dependency can fan out failures
Runtime Controls reduce these failure modes, but you still need to configure the right controls for your workflow. maxToolCalls is a call-count guardrail, not direct provider billing telemetry.

Examples

Wrap Any Async Call (No API Key)

JavaScript

Use run() Directly

JavaScript
runtime["signal"] is available in handlers but optional. Use it when your tool call supports cancellation.

Control Layers

Every control is opt-in and composable. Enable only what you need.

Retry with Exponential Backoff

Automatically retries transient failures (503, 429, timeouts) with configurable backoff.
JavaScript
Custom retry decisions:
JavaScript

Tool-Call Budget

Per-run cap on the number of tool calls when maxToolCalls is configured. Budgets are scoped by runKey. This is a tool-call-count budget, not a dollar-based cost meter.
JavaScript

Loop Breaker

Detects repeated no-progress patterns and escalates from warning to quarantine to stop.
JavaScript

Circuit Breaker

Temporarily blocks calls to a failing dependency. Keyed by (tenant, toolName, destination).
JavaScript
When failure rate exceeds threshold inside the sliding window, the circuit opens for cooldownMs.

Timeout and Cancellation

Per-call timeout with abort signal propagation.
JavaScript

Policy Gates

Deterministic allow / deny / require_approval rules with specificity-based precedence.
JavaScript
Policy precedence (highest wins):
  1. Higher tool specificity (exact name > prefix > wildcard)
  2. Higher destination specificity (exact host > wildcard subdomain > *)
  3. Longer action prefix match
  4. Stricter action (deny > require_approval > allow)
  5. Earlier rule index on exact tie (current behavior)

Idempotency

Prevents duplicate side effects by replaying prior results for calls with the same idempotencyKey.
JavaScript

Concurrency Locks

Prevents simultaneous conflicting writes to the same resource.
JavaScript

Verifier Hooks

Custom correctness gates that run before execution, after success, and after errors.
JavaScript

Per-Tool and Per-Destination Overrides

Apply stricter or looser controls to specific tools or destinations.
JavaScript
Tool overrides win when both tool and destination set the same field.

Agent Logic Safety

applyAgentLogicSafety adds pre-execution safety checks without changing RuntimeControls internals.

Injection Guard

Scans tool name, action, destination, and args for injection patterns before execution.
JavaScript
Default patterns (when patterns is omitted):
  • ignore (all|any|previous) instructions
  • system prompt
  • developer message
  • <script
  • rm -rf

Exit Conditions

Enforces maximum steps per run and can block calls after a terminal action.
JavaScript

Intent Allowlist

Restricts which tool + action combinations are permitted. Anything not explicitly allowed is denied.
JavaScript

Combining All Three

JavaScript

Observability

Event Callback

JavaScript

Event Sinks

JavaScript

Event Types

State Adapters

By default, state is in-memory. To persist guardrail state across processes, provide adapters.
JavaScript
State is namespaced by tenantKey, so teams can scope keys when sharing adapter backends. Unit tests cover adapter contracts; validate your backend and lock semantics with integration tests before production use.

API Methods

RuntimeControls.create(config?)

Creates a new controls instance. All config is optional.

controls.run(context, fn)

Runs fn(runtime) through enabled control layers. Context fields:
  • toolName (required)
  • runKey, destination, action
  • args
  • idempotencyKey, resourceKey
  • timeoutMs (per-call override)
  • signal (caller cancellation)
JavaScript

controls.wrap(params)

Creates a reusable guarded function for repeated tool calls.
JavaScript
Dynamic context via resolver functions:
JavaScript

controls.reset(runKey=None)

Resets budget counters for the selected run key.
JavaScript

Full Configuration Reference

FAQ

Do I need a Buildfunctions API token?

No. Runtime Controls works standalone without any API token.

What should I wrap first?

Start with side-effecting calls:
  1. Repository writes (git push, branch operations)
  2. External ticket or issue creation
  3. Sandbox and test execution
  4. PR or issue comments

What should be denied by default?

Start by denying destructive actions (delete*) and requiring approval for external writes.

Can I use this without agents?

Yes. Runtime Controls wrap functions — API calls, database queries, file operations, shell commands. Validate behavior in your own integration paths.