Skip to main content
What you deploy is a small directory:
my-agent/
├─ agent.toml      # name, model, runtime family
├─ prompt.md       # the system prompt
├─ skills/         # optional — folders the agent loads when it needs them
└─ runtime/        # optional — a custom runtime image (coming soon)
agent.toml + prompt.md are all an agent needs; skills/ and runtime/ are additive — add them only when you do. A deployment packages this directory into an immutable revision; the active revision is what new sessions use, and you roll back by re-activating an earlier one. Deploy three ways — all the same underneath: the API/SDK (send it inline), the oc CLI (bundle a local directory), or a repo push.

Revisions

A revision is an immutable snapshot of an agent’s behavior — the prompt, model, and skills from one deployment, frozen and numbered. Every deploy appends a new one (a repo push that changes nothing is skipped); the agent’s active revision is the one new sessions run. Revisions are linear (the number only goes up, like a Vercel/Fly deployment) and never rewritten — rolling back just moves the active pointer to an earlier one. In-flight sessions keep the revision they started on; only new sessions pick up a change.
Field
numberMonotonic per agent (1, 2, 3, …).
prompt / modelThe behavior at deployment time.
skill_bundle_digestThe skill files (a content-addressed bundle); null when there are no skills.
digestA content hash of the behavior (used for change detection).
The agent itself holds only identity + bindings (name, runtime, credential, limits) plus a pointer to the active revision; prompt/model are served from that revision.

Deploy

POST /agents/:id/deployments is the one command. input.type: "inline" sends behavior directly (API / CLI / dashboard); input.type: "github" deploys a linked repo — see Deploy from a repo. An inline payload is the complete behavior — omitted fields aren’t inherited (prompt is required; omitted skills means no skills).
const deployment = await oc.agents.deployments.create("agt_123", {
  input: {
    type: "inline",
    prompt: "You triage pull requests.",
    model: "anthropic/claude-opus-4-8",
    skills: [{ path: "triage/SKILL.md", content: "---\nname: triage\ndescription: Triage a PR\n---\nSummarize the diff…" }],
  },
});
The response is a deployment:
{ "deployment": { "id": "dep_…", "state": "ready", "revision_id": "rev_…", "active": true } }
Inline deployments finish synchronously (state: "ready" with a revision_id) — except flue deploys, which return state: "verifying" and boot the uploaded artifact in a throwaway sandbox before pinning the revision; poll them like an async deployment (verifyingready/failed). Asynchronous deployments (GitHub) return state: "accepted" — poll GET /agents/:id/deployments/:deployment_id until ready (or failed/skipped/superseded); a repo deploy also reports progress as a commit status on GitHub.

Staging vs activating

By default a ready deployment is activated — its revision becomes what new sessions use. Pass activate: false to stage instead: the revision is created but not made active, so you can test it before it goes live.
// 1. stage a revision (not activated)
const { deployment } = await oc.agents.deployments.create("agt_123", { input: { type: "inline", prompt: "…" }, activate: false });

// 2. test it — a session pins the agent's ACTIVE revision by default; pass `revision`
//    to run the staged one instead
const session = await oc.sessions.create({ agent: "agt_123", revision: deployment.revision_id, input: "…" });

// 3. happy? promote it
await oc.agents.revisions.activate("agt_123", deployment.revision_id);
So revision on session create is how you exercise any non-active revision (a staged one, or an old one) without touching what’s live. For repo deployments the branch decides and activate is ignored: a push to the production branch activates, every other branch stages.
Editing prompt/model via PATCH /agents/:id also deploys a revision — a shorthand for small edits.

Deploy from a repo

Keep the agent directory (above) in Git and push to deploy. Install the OpenComputer GitHub App on the repo, then connect it to an agent:
await oc.agents.deploymentSource.link("agt_123", { repo: "acme/agents", path: "issue-fixer", productionRef: "main" });
Linking deploys the current main HEAD right away (deploy_now: false / --no-deploy to skip). Then every push that touches the directory deploys:
  • push to main (production) → a new revision, activated.
  • push to another branch → a revision staged (test, then promote).
  • a push not touching the directory → no-op; identical directory content → skipped (no churn).
OpenComputer posts a commit status (queued → ready / failed) so a deployment’s result shows in GitHub. Your GitHub token never reaches the agent’s sandbox — OpenComputer pulls only the linked directory, at the exact commit, in an isolated worker; a deployment can only target the directory you connected; no code runs at deploy time. (Same token model as repos.)

Deploy from your machine

No repo needed — the CLI bundles a local agent directory and deploys it:
CLI
oc agent deploy                       # deploy ./ (the agent named in agent.toml)
oc agent deploy ./agents/issue-fixer  # a specific directory
oc agent deploy --no-activate         # stage instead of activate
Same as a repo push — handy for CI that isn’t GitHub, or trying a change before you commit.

Flue framework agents

A Flue agent ([runtime] family = "flue" in agent.toml) has no prompt.md or skills/ — its behavior lives in code — so oc agent deploy builds and ships an artifact instead:
CLI
oc agent create support-triage --runtime flue --model anthropic/claude-sonnet-5   # --prompt not needed
oc agent deploy                                                                   # build → upload → verify → activate
Deploy runs the app’s own build (oc-flue-build), uploads the content-addressed artifact, boot-verifies it in a scratch sandbox, then activates a revision — the same staging and rollback model as any other agent. See Run Flue agents.

Roll back and promote

Rollback and promote are the same primitive — set the active revision. Re-activate any earlier revision (rollback) or a staged one (promote):
await oc.agents.revisions.activate("agt_123", 3);
Instant — no rebuild. Running sessions are unaffected; new sessions use the newly-active revision.

Inspect

REST API
GET /v3/agents/agt_123/deployments              # deployment history (state, source, actor)
GET /v3/agents/agt_123/deployments/dep_123      # one deployment (poll async ones to ready|failed)
GET /v3/agents/agt_123/revisions                # revision history (newest first; active flagged)
GET /v3/agents/agt_123/revisions/5              # one revision + its skill file manifest
GET /v3/agents/agt_123/activations              # active-pointer audit log
GET /agents/:id also includes an active_revision summary (id, number, digest).

Skills

Skills — reusable instruction folders the agent loads when relevant — are part of a revision, so they’re deployed, versioned, and rolled back exactly like the prompt and model. Include them inline in a deployment (skills:[…], above), upload a .zip (PUT …/skills), or ship a skills/ directory from a repo. See the Skills page for the SKILL.md format, how skills are invoked, all three ways to add them, and limits.

Not yet supported

These are coming soon — a deployment that includes them is rejected today:
  • MCP servers (mcp.json)
  • Custom runtimes (a runtime/ directory)
  • Skills on codex agents — skills are claude-runtime only for now

Dashboard

The agent page in the dashboard mirrors all of this: a Revisions panel (history, the active revision, one-click rollback) and a Skills panel (current skills, plus upload-.zip / remove).