Experimental. The supported profile below is intentionally
constrained and will widen. Flue is pre-1.0; each deploy bundles your exact
Flue version into the artifact, so upstream releases never break a deployed
agent — only new builds pick them up.
cloudflare.ts:
an optional platform-specific entry module.
src/opencomputer.ts
app.ts, channels, workflows — can add this file
unchanged and keep self-hosting: only what it imports ends up in the
OpenComputer artifact.
Template: diggerhq/oc-flue-starter.
Quickstart
oc session steer <session-id> "..." or in
the dashboard.
Add to an existing Flue app
Three files, no changes to your agent code:src/opencomputer.ts
agent.toml
oc agent deploy from the app root — it creates the agent on first
deploy. If the app sets sandbox: or has a db.ts, the build tells you
(both are supplied by the platform — see the table below).
What changes vs a stock Flue app
The sandbox, persistence, model, skills, tool-name, and credential rows are enforced at build or deploy — violations fail before a session can exist. Channels and workflows aren’t checked: code not imported bysrc/opencomputer.ts
isn’t in the artifact.
| Stock Flue | On OpenComputer | |
|---|---|---|
| Entry | Flue’s generated server (flue build --target node) | Add src/opencomputer.ts calling serveOC(agent). Your agent code is untouched; flue dev keeps working locally |
| Sandbox | You pick one (local(), containers, …) | Leave sandbox: unset — the session’s workspace sandbox is supplied (build error) |
| Persistence | db.ts (or volatile in-memory default) | No db.ts — the conversation is stored durably in the session’s state; survives restarts and hibernation (build error) |
| Model credentials | Env keys or registerProvider in code | No keys anywhere in the app — the deploy scans the artifact for key-shaped strings and fails on a hit. Managed billing or an OC credential; routing is injected at run time |
| Model choice | In code | Still in code — but declared three times total (defineAgent, agent.toml, the OC agent) and all three must be equal; the deploy rejects divergence |
| Skills | Packaged imports (with {type:'skill'}) or workspace files | src/skills/<name>/SKILL.md — ships with every deploy. Packaged imports are a build error (for now) |
| Asking the user | No human-in-the-loop primitive | An ask tool is added: the session yields needs_input and hibernates until the user replies |
| Channels / workflows | Slack/Discord ingress, defineWorkflow | Not supported — inbound is session messages + GitHub watches |
| Tool names | Anything | bash, read, write, edit, ls, grep, glob, say, ask are reserved (build error) |
What @opencomputer/flue does
serveOC(agent) runs your agent as the session’s resident process and
connects it to the platform:
- Conversation persistence. Opens Flue’s conversation store on the
session’s state volume. History survives process restarts, hibernation,
and machine moves. A
db.tsis rejected at build because a second store would fork the conversation history. - Sandbox. Flue’s built-in
read/write/edit/bash/grep/globtools execute on the session’s workspace sandbox — a separate machine from your app process, where attached repos are checked out. CustomdefineToolcode runs in-process with your app (see the network-access note below). - Two added tools.
sayposts a message to the user mid-run.askasks a question: the session yieldsneeds_inputand hibernates until the user replies, then the run continues with the answer. - Model credentials. Registers the Anthropic provider with credentials resolved from the platform — managed metering or your key. The bundle and repo contain no credentials.
- Turn handling. Each session turn is admitted into Flue’s engine with an idempotent id, so platform-level retries can’t double-run it. If the platform side of a turn dies mid-run, the retry re-attaches to the still-running engine and streams from where it left off — the model call is not repeated. Every step — model text, custom tool calls, sandbox operations — is written to the session’s event log.
- Retries and timeouts. Flue’s
durabilitysettings are overridden: one engine attempt per turn, with the timeout set to the platform’s turn deadline. Cancel, retry, and deadline behavior is the platform’s; there is no second layer to reason about.
oc-flue-build (the package’s build command, run by oc agent deploy)
bundles src/opencomputer.ts with your installed Flue version via esbuild, collects
src/skills/** into the artifact, and stamps the metadata (model, versions)
the deploy validates against.
Custom tools
PlaindefineTool — typed with valibot, running in-process:
src/tools/lookup-order.ts
- Anything a tool needs at run time must be bundled —
importfixture data and templates (as above); the repo checkout is not on the app’s filesystem. - Outbound network: custom tools currently have unrestricted outbound
access from your app’s process — where
defineToolcode runs, a separate machine from the workspace sandbox. An egress policy is planned; until it exists, don’t embed secrets in the bundle to call your own APIs — prefer self-contained tools.
Skills
Put the agent’s own skills atsrc/skills/<name>/SKILL.md
(SKILL.md format). The build packages them into the
artifact; at run time they are written into the agent’s workspace, where
Flue’s normal discovery finds them. Changing a skill is a redeploy; a
rollback also reverts skills. Separately, a repo attached as a session source
contributes its own .agents/skills/** (that convention means “skills for
agents working on that repo”); on a name clash, the app’s skill wins.
Skills take effect on OpenComputer only: flue dev’s default local
environment is an empty in-memory filesystem, so it exercises your loop and
custom tools, not skills.
Models
anthropic/<id>, same ids as the other runtimes — anthropic/claude-sonnet-5
(the template default), anthropic/claude-opus-4-8,
anthropic/claude-haiku-4-5. Managed billing and BYO keys behave exactly as
on claude/pi; see credentials.
Limitations vs full Flue
What the current profile does not cover, beyond the table above:- Channels (Slack, Discord, web ingress) don’t run here — inbound is
session messages and GitHub watches. A full app
keeps its channels when self-hosting; code not imported by
src/opencomputer.tsnever enters the artifact. - Workflows (
defineWorkflow) don’t run here; a workflow admission throws at run time. - One agent, one conversation per session.
serveOC(agent)hosts one top-level agent, and a session is one conversation instance — Flue’s per-instance routing has no equivalent; fan out by creating sessions. - Subagents (
session.task()) bundle and execute in-process, but they are outside the tested profile: their model declarations aren’t validated the way the top-level agent’s is, and subagent steps may appear incompletely in the session event log. - Anthropic models only. Flue itself supports other providers (OpenAI, Google, …); on OpenComputer there is no credential source for them yet.
durabilitysettings are ignored. The platform pins one engine attempt per turn under the turn deadline; retry and timeout policy is the platform’s. Settingdurability:indefineAgenthas no effect.- Text in, text out. Sessions exchange text; there is no way to send the agent an image or a file attachment.
- No HTTP endpoints. A Flue app’s own server doesn’t run; requests reach the agent only through the sessions API.
profile_version in the artifact), so a deployed agent never changes
behavior until you rebuild.
Deploying
oc agent deploy = build (oc-flue-build, which initializes your agent to
extract and check the profile) → upload the content-addressed artifact →
boot-verify → create and activate an immutable
revision. Sessions pin their revision at create;
rollback is repointing.
Boot-verify is the flue-specific step. Your artifact is your brain code, so
the platform boots it in a throwaway sandbox and waits for a healthy boot
before pinning a revision. A bundle that throws in initialize() — or can’t
otherwise reach a healthy boot — fails the deploy with that error; it
never reaches a session, and the previously active revision keeps serving. So
a flue deploy isn’t instant: it polls through a verifying state (tens of
seconds) while the boot runs, then activates. --no-activate still verifies —
a staged revision is a verified one that isn’t live yet. The verify sandbox is
discarded afterward and never holds your model credential.
Troubleshooting
- Build fails (
oc-flue-build) — a profile violation, named in the error:sandbox:set, adb.ts, a packaged-skill import, a reserved tool name, or a model that isn’tanthropic/…. Nothing is uploaded. - Deploy fails at verification — the bundle built but didn’t boot in the scratch sandbox; the deploy output carries the probe error. Usual cause: a top-level crash in your code (something that only happens at import time).
- Model rejected at deploy — the three model declarations diverge
(
defineAgent,agent.toml, the OC agent). provider 401on the first turn — no usable model credential. Managed billing is the default, so this usually means the org’s billing isn’t set up yet — set up billing, or attach a valid Anthropic credential to the agent.- Skill not loading — the agent’s own skills go in
src/skills/<name>/SKILL.md; skills from a codebase require that repo attached as a session source (--source).