← All @molecule/* packages · App templates

@molecule/api-agent-run

Core interface · agent-run · API (Node) · v1.1.0 · Apache-2.0

Abstract unattended agent run interface — run a coding agent in an ephemeral, isolated environment and get artifacts back

npm install @molecule/api-agent-run

npm · Source on GitHub

How it works

@molecule/api-agent-run is the agent-run core interface on the API (Node) side: the API your app calls, with no vendor inside.

Choose the implementation by bonding one of its 1 provider: @molecule/api-agent-runtime-claude-code.

import { setProvider, requireProvider } from '@molecule/api-agent-run'
import { provider as claudeCode } from '@molecule/api-agent-runtime-claude-code'

setProvider(claudeCode)

const artifact = await requireProvider().run(
  {
    repoUrl: 'https://github.com/acme/widgets',
    instructions: 'Fix the failing test in src/math.test.ts.',
    timeoutMs: 600_000,
  },
  {
    env: {
      GITHUB_TOKEN: fineGrainedTokenScopedToThisRepo, // contents:read/write, TTL ≈ timeout
      ANTHROPIC_API_KEY: platformKey,
    },
    onLog: (line) => logStream.write(line),
  },
)
// artifact.patch is a unified diff. The CALLER (never the sandbox) applies it.

Providers (1): @molecule/api-agent-runtime-claude-code

Works with: @molecule/api-bond, @molecule/api-i18n

Reference

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Agent run core interface for molecule.dev.

Defines the abstract contract for running a coding agent UNATTENDED in an ephemeral, isolated environment — an ephemeral cloud sandbox that holds nothing worth stealing, so even a full-permission agent plus a prompt injection leaks nothing. Bond a concrete runtime (@molecule/api-agent-runtime-claude-code) to enable agent runs.

Quick Start

import { setProvider, requireProvider } from '@molecule/api-agent-run'
import { provider as claudeCode } from '@molecule/api-agent-runtime-claude-code'

setProvider(claudeCode)

const artifact = await requireProvider().run(
  {
    repoUrl: 'https://github.com/acme/widgets',
    instructions: 'Fix the failing test in src/math.test.ts.',
    timeoutMs: 600_000,
  },
  {
    env: {
      GITHUB_TOKEN: fineGrainedTokenScopedToThisRepo, // contents:read/write, TTL ≈ timeout
      ANTHROPIC_API_KEY: platformKey,
    },
    onLog: (line) => logStream.write(line),
  },
)
// artifact.patch is a unified diff. The CALLER (never the sandbox) applies it.

Type

core

Installation

npm install @molecule/api-agent-run @molecule/api-bond @molecule/api-i18n

API

Interfaces

AgentRunArtifact

What a completed run hands back. ARTIFACTS ONLY — the isolated environment itself (and every credential in it) is destroyed before this reaches the caller, and the runtime redacts anything credential-shaped from logs.

interface AgentRunArtifact {
  /** Whether the agent CLI exited successfully. */
  exitStatus: 'completed' | 'failed' | 'cancelled' | 'timeout'
  /** Unified diff of every change the agent left in the working tree. May be empty. */
  patch: string
  /** The agent CLI's output, credential-redacted. */
  logs: string
  /** Model token usage the CLI reported, when it reports usage. */
  usage?: AgentRunUsage
  /** The isolated environment's provider id, for audit — destroyed before return. */
  sandboxId?: string
  /** Wall-clock milliseconds the run held its sandbox. */
  computeMs?: number
}

AgentRunConfig

Configuration for the agent runtime provider.

interface AgentRunConfig {
  /** Default wall-clock budget when a spec passes none, in milliseconds. */
  timeoutMs?: number
}

AgentRunOptions

Per-run credentials and machine material, injected into the isolated environment and destroyed with it.

Deliberately separate from {@link AgentRunSpec}: the spec is storable and loggable, this is not. Least scope is the CALLER's duty — a GitHub fine-grained token scoped to the ONE repo with contents:read/write and an expiry ≈ {@link AgentRunSpec.timeoutMs}, never an account-wide token.

interface AgentRunOptions {
  /** Environment variables the agent's process sees (tokens, keys). Never logged. */
  env: Record<string, string>
  /** Reports streaming log output. Implementations must not block it. */
  onLog?: (line: string) => void
  /** Cooperative cancellation: polled between phases, checked at the deadline. */
  signal?: AbortSignal
}

AgentRunSpec

The task an agent runtime executes in its isolated environment.

Everything here is TASK material. Credentials are NOT part of the spec — they travel separately ({@link AgentRunOptions.env}) so the caller can keep them out of any store that persists specs, and inject them per run.

interface AgentRunSpec {
  /** The repository to clone and work in, as an https URL. The credential authorizes it. */
  repoUrl: string
  /** Branch to check out before the agent starts. Default: the repo's default branch. */
  baseBranch?: string
  /** What the agent should do, in plain language the CLI's model can act on. */
  instructions: string
  /**
   * Hard wall-clock budget for the WHOLE run (clone → agent → artifact), in
   * milliseconds. The runtime cancels the work at the deadline; default 600000
   * (10 minutes). The credential's TTL should be about this long.
   */
  timeoutMs?: number
  /**
   * Egress allowlist for the run, as hostnames. Enforced deny-by-default when
   * the runtime's sandbox supports network policy. The runtime ALWAYS adds the
   * hosts its own tooling needs (the model API, github.com, the npm registry) —
   * this list is for task-specific extras.
   */
  allowedHosts?: string[]
  /** Model id the CLI runs on. Interpreted by the runtime; default is its own. */
  model?: string
}

AgentRuntimeProvider

Agent runtime provider interface.

Implement this in a bond package: provision an ISOLATED environment (an ephemeral cloud sandbox — never a long-lived host), install the agent CLI at run start, run the task, and return artifacts. The implementer owns the environment's lifetime: created for the run, destroyed before the artifact is returned.

interface AgentRuntimeProvider {
  /** Runtime name (e.g. 'claude-code'). */
  readonly name: string

  /**
   * Execute one unattended agent run.
   *
   * @param spec - The task (repo, instructions, budget).
   * @param opts - Per-run credentials, log sink, cancellation.
   * @returns The artifacts: patch, redacted logs, usage, cost facts.
   */
  run(spec: AgentRunSpec, opts: AgentRunOptions): Promise<AgentRunArtifact>
}

AgentRunUsage

Token usage the agent's model reported, for cost metering.

interface AgentRunUsage {
  inputTokens: number
  outputTokens: number
  cacheReadTokens?: number
  cacheCreationTokens?: number
}

Functions

getProvider()

Retrieves the bonded agent runtime provider, or null if none is bonded.

function getProvider(): AgentRuntimeProvider | null

Returns: The bonded provider, or null.

hasProvider()

Checks whether an agent runtime provider is currently bonded.

function hasProvider(): boolean

Returns: true if a provider is bonded.

requireProvider()

Retrieves the bonded agent runtime provider, throwing if none is bonded.

function requireProvider(): AgentRuntimeProvider

Returns: The bonded agent runtime provider.

setProvider(provider)

Registers an agent runtime provider.

function setProvider(provider: AgentRuntimeProvider): void
  • provider — The agent runtime provider to bond.

Available Providers

ProviderPackage
Agent Run@molecule/api-agent-runtime-claude-code

Injection Notes

Requirements

Peer dependencies:

  • @molecule/api-bond ^1.0.1
  • @molecule/api-i18n ^1.0.1

Runtime Dependencies

  • @molecule/api-bond

  • @molecule/api-i18n

  • The containment model is the contract. The runtime MUST run each run in an environment created for it and destroyed before the artifact returns; MUST inject credentials only through the run's environment and only for the run's lifetime; MUST redact credential-shaped text from logs; and MUST return ARTIFACTS ONLY (a patch + logs) — never a shell, never filesystem access, never the environment itself.

  • Least scope is the CALLER's duty. The runtime cannot validate that a GitHub token is scoped to one repo or TTL'd to the task — pass a fine-grained token scoped to the ONE repo with contents:read/write and an expiry ≈ timeoutMs. An account-wide or org-wide token turns the isolation into theater.

  • The host keeps apply authority. Callers should treat patch as untrusted content: scan it for secrets, review it, and apply it host-side (the runtime bond never pushes to the repo itself unless the caller explicitly supplies push-capable credentials AND asks for it — the default contract is patch-only).

  • Egress is deny-by-default where the sandbox can enforce it. The runtime always allows the hosts its own tooling needs (the model API, github.com, the npm registry) plus the spec's allowedHosts; everything else is denied when the sandbox supports network policy.