Skip to Content
Platform
PlatformRuntimes and environments

Runtimes

A runtime is the deployable version of your agent: Pi running a pinned recipe with the policy and resources it needs.

What a runtime is

A recipe defines your agent’s behavior, but it doesn’t run on its own. Pi runs the agent loop from that recipe. An Introspection runtime makes that combination deployable: it pins the exact recipe version Pi loads, provides an isolated sandbox, and resolves the identity, policy, bindings, and resources needed for each task.

A runtime serves one or more environment lanes (typically staging and production) so you can move a version from test traffic to live traffic. A lane points to one version in a runtime group, much like a Git ref points to a commit.

Runtimes list showing customer support, returns and refunds, and escalation agents with conversation volume, active runs, failure rate, and recent activity
The Runtimes view summarizes each agent lineage and its current activity before you open a specific runtime.

Runtime groups: the lineage

Successive versions of one logical agent share a runtime group, a stable identity that ties every version of that agent together. Each new version is its own immutable runtime row; the group is the through-line across all of them.

This lineage enables:

  • Experiments to route between versions: an experiment compares arms within a single group’s lineage, on one environment.
  • Patterns that accumulate across versions: behavior and failure modes observed on one version stay attached to the lineage, so you can see how a recurring issue trends as the agent evolves.

A runtime is one immutable deployable version. A runtime group is the agent’s identity over time. You experiment and trend patterns across the group, then ship a single version into an environment lane.

Customer support runtime detail showing recent health metrics, missing staging bindings, and Git-backed versions assigned to staging and production
A runtime detail keeps operational health, required bindings, Git versions, and their active environment lanes together.

Model credential mode

The runtime can use Introspection-managed model access or credentials you provide:

PropertyOptionsMeaning
LLM modemanaged / bring-your-own-keyWhether the runtime uses Introspection-managed model access, or your own provider credentials.

Recipe dependencies

Node dependencies use the recipe’s ordinary package.json#dependencies. The managed runtime discovers the recipe root and nested packages, installs production dependencies with pnpm into a hoisted node_modules, and links the Pi peers already supplied by the runtime image. devDependencies stay authoring-only and are not installed in the sandbox.

A recipe declares Python and system requirements under pi.runtime. The managed runtime satisfies them while preparing the recipe workspace, before the first model call.

For a declared Python project, the runtime:

  1. verifies that pyproject.toml and uv.lock are inside the recipe;
  2. runs a frozen production install into .pi/python;
  3. reuses that environment while the project and lockfile digest is unchanged;
  4. runs any declared import preflights;
  5. activates the environment for Pi and recipe-owned processes through VIRTUAL_ENV and PATH.

The install never modifies system Python, includes development dependencies, or resolves a newer dependency graph than the committed lock. A missing lock, incompatible interpreter, failed install, or failed import stops the runtime before the agent starts.

System requirements use versioned capability IDs such as document.pdf-tools@1. These map to reviewed software already present in the runtime image. Recipes cannot execute apt-get, Homebrew, or arbitrary privileged boot scripts. If the image does not advertise a requested capability and version, the runtime fails closed with an actionable error.

Resolution and availability

When you start a task against a runtime by name, the platform resolves that name to the version currently active for the task’s environment lane. Resolution is sticky for the task: every run in that task keeps the same version, even if the lane moves while the task is working. Start a new task to pick up the lane’s newer version.

“Pins” here means task-level runtime resolution. It is distinct from the immutable recipe source and the environment lane assignment described below.

If a version turns out to be bad, you can yank it. A yanked runtime stops accepting new tasks while existing tasks keep their pinned version. You can reverse the decision by unyanking it. Use introspection runtimes update --yank / --unyank or the dashboard.

Environments and deployment

An environment is a lane shared across the platform: development, staging, or production. Environment-scoped API keys, bindings, experiments, and memory keep test work separate from live traffic. development is the local introspection dev lane. Staging and production are deployed lanes whose selected runtime versions can change independently.

Runtime registration is manifest-driven. A canonical .introspection/<runtime-slug>.yaml file names the runtime group, points at the recipe path, and declares its runtime configuration:

name: support-agent description: Customer support agent path: apps/support-agent runtime: llm_mode: byok resources: requests: cpu: "1" memory: 2Gi storage: 10Gi limits: cpu: "2" memory: 4Gi

Workspace repositories

runtime.github declares the repositories this runtime’s tasks may check out into the sandbox, and how much the token minted for them may do:

runtime: github: repositories: - acme/api-service - acme/web permissions: contents: write pull_requests: write

repositories is a grant, not a clone list: each entry is an owner/name slug for a repository already registered to the project (never a URL). There is no limit on how many may be granted — a grant clones nothing, so its length costs nothing. Two granted repositories cannot share a name, because the checkout always lands at workspace/repos/<repository name>.

The grant is part of the runtime version, so editing runtime.github in the manifest changes nothing until a new version is deployed from that commit, and a running task keeps the repositories it cloned at launch. An explicit PATCH /v1/runtimes/{id} on config_json is the one path that does change a live runtime’s grant, and it applies from that runtime’s next token mint. config_json is replaced wholesale, not merged — it is the same object that holds resources and the manifest’s runtime.config keys — so send the runtime’s current config_json with github edited into it, or the rest is silently dropped until the next manifest deploy rewrites the row.

A task then picks the subset it actually wants, with its ref and depth: introspection tasks create --repository OWNER/NAME[@REF][:DEPTH] (repeatable), or repositories: [{ repo, ref, depth }] on TaskCreateParams. That list has no server-side count limit either, but unlike the grant it is cloned at boot before the first turn, so its length is startup latency. An entry outside the grant is dropped by the server rather than failing the launch.

permissions mirrors the GitHub Actions permissions: block and is the ceiling, not the request. Every supported read is implicit, so authors declare only write elevations. The allow-list is contents, pull_requests, issues, checks, statuses, deployments, and discussions; keys outside it — workflows, administration, actions, packages, pages, security_events, repository_projects — are refused by name.

See Work with repositories for the end-to-end procedure, including registering the repository, what the agent can do with the checkout, and the review boundary that write access requires.

Resource sizing

Resource requests describe the capacity a task needs the environment to reserve: CPU for processing time and memory for the working set. CPU and memory limits bound how much a task may use when the target environment applies those limits. requests.storage sizes the task’s scratch volume; storage is request-only and is not a durable-artifact quota.

The platform parses these as portable resource quantities and resolves them against the target environment’s defaults, minimums, schedulability guards, and available capacity. The resolved values can therefore differ from the manifest. A CPU or memory limit cannot be lower than its resolved request. Size requests and limits from representative workload behavior and revise them when startup, capacity, or task behavior shows the workload needs a different allocation; do not assume the authored quantities were applied unchanged.

The filename stem is the stable runtime-group slug, so it must itself be a valid slug: lowercase letters, digits, and single hyphens, up to 63 characters. name is a separate display name and does not have to match it. The manifest can also set path, description, includes, strict, runtime.kind, runtime.llm_mode, runtime.config, runtime.resources, and runtime.github. strict: true turns manifest keys outside the schema into errors instead of warnings. It lives in the Git repository connected through your organization’s GitHub integration. The first introspection runtimes create --manifest ... records an immutable recipe pin and creates the runtime group; later commits produce new versions in that same lineage.

Creating the first runtime is a production bootstrap, not a staging preview. Run runtimes create from a clean, pushed main branch. The first version immediately becomes active in both staging and production. A feature branch or pull-request commit cannot bootstrap a staging-only runtime.

If the recipe begins on a feature branch, review and merge that pull request first. Then check out the resulting main commit and create the runtime from there. After the runtime group exists, pull-request commits can produce candidate versions for staging while production continues to follow main.

Staging can follow a Git branch or pull request, or be pinned to one exact commit. A lane that follows a moving ref advances when a new runtime version is built from that ref. Pinning a commit freezes the lane on that immutable version; introspection runtimes unpin returns staging to main.

Unpinned production advances with the repository’s default branch. The CLI and dashboard expose the lane controls for staging; pinning production is a Control Plane API operation.

Runtime versions themselves never change. Moving or pinning a lane only changes which immutable version receives new work. development remains the local introspection dev lane.

Use the dashboard or CLI to register runtimes, choose what staging serves, or withdraw a bad version. Application SDKs resolve runtimes and start tasks; they do not change deployment state.

Follow the Agent development lifecycle to register a recipe and test it in staging. See CLI → Runtimes for every runtime command.

How a managed task starts

Each managed task uses one recipe version from start to finish. Introspection loads the registered recipe path at the Git commit selected for the task’s environment. Moving an environment to another version affects new tasks, not a task that is already running.

Before the agent starts, Introspection:

  1. Loads the recipe source. Only the registered recipe path at the pinned commit is included.
  2. Prepares the recipe. Paths matched by the root .recipeignore are excluded. Declared production dependencies are installed or validated, and requested system capabilities are checked.
  3. Resolves the agent. The runtime resolves the recipe’s agent definitions and uses the agent configured for the task.
  4. Makes task resources available. These can include recipe-provided files, restored task files, uploads, skills, memory, and environment bindings.
  5. Starts the agent. The task begins only after the recipe and its required resources are ready.

Runtime reads show image preparation as pending, queued, building, ready, or failed. A failed build includes an error and may include a log file. A completed image may also report its size.

Keep agent behavior, dependency declarations, skills, extensions, and other portable configuration in the recipe. Keep concrete secrets and endpoint URLs in environment bindings rather than recipe source.

Cloud validation distinguishes a recipe defect from a validation attempt that could not finish. An invalid recipe includes file diagnostics and cannot start a managed task. A failed validation includes an error message. The dashboard can request a fresh validation attempt; completed results are otherwise owned by the validation service.

Files and task artifacts

Files in the recipe’s conventional files/ directory become read-only task inputs alongside restored task files and conversation uploads. Nested paths and binary contents, such as spreadsheets, are preserved. A recipe file cannot replace a file already restored into the task workspace. Conversation uploads are materialized after restored task files, so use distinct paths when both sources may contain the same filename. Files the agent creates or changes are versioned through the Files API at checkpoints and task completion. See Packaging a recipe for limits and authoring guidance.

What can prevent startup

Introspection does not start the agent when the registered commit or recipe path cannot be loaded, the recipe or configured agent is invalid, or a declared dependency or system requirement cannot be satisfied. Startup also fails when recipe-provided files exceed their limits, contain symlinks, or collide with a restored task file or upload. Correct the recipe version or required environment configuration before starting another task.

  • Recipes: the versioned behavior a runtime deploys.
  • Experiments: A/B tests that route between versions in a group’s lineage.
  • Observations & patterns: behavior that accumulates across a runtime group.
  • Deployment: where the Control Plane and Data Plane infrastructure run.
  • JavaScript SDK: resolve a runtime and open an identity-bound runner.
  • API Reference: endpoint details for the published Data Plane APIs.
Last updated on