Run Conductor-style agent tasks from code
Updated
Your Slack bot or orchestrator created Conductor Cloud workspaces through its API or CLI. Keep the code and swap the calls: a sandbox per task from the Prized Python SDK, or a run in a git worktree on your box with a signed webhook when it ends.
On this page7
Conductor Cloud stops taking new work on November 13, 2026 (Moving from Conductor Cloud). If your code drove it, such as a Slack bot that opens a workspace per request or an orchestrator that runs conductor workspace create for each plan item, keep that code and swap its calls.
A task becomes one of two things on Prized:
- A sandbox per task, like a cloud workspace: a fresh microVM clones your branch, runs the agent on a key you pass in, pushes, and is deleted. Steps 1 to 3.
- A run on your box: the agent works in a git worktree on a box you keep, on the sign-in already there, and a signed webhook tells your code when it ends (Or run it on your box).
1. Export your keys
Make a Prized API key on API keys with Sandboxes: Write. New to Prized? Open Sandboxes signs you up with free credit and no card. Export it with your agent's key and a fine-grained GitHub token for the one repo, with Contents and Pull requests at read and write:
export PRIZED_API_KEY=dcp_…
export ANTHROPIC_API_KEY=sk-ant-…
export GH_TOKEN=github_pat_…2. Save the script
python3 -m venv .venv && .venv/bin/pip install prizedimport json, os, re
import httpx # installed with prized
from prized import Sandbox
GH_TOKEN = os.environ["GH_TOKEN"]
AGENT = {"ANTHROPIC_API_KEY": os.environ["ANTHROPIC_API_KEY"]} # the agent's sign-in
def sh(sb, cmd, cwd="app", **kw):
r = sb.exec(cmd, cwd=cwd, **kw)
if r.exit_code != 0:
raise RuntimeError(f"{str(cmd)[:60]}: exit {r.exit_code}\n{r.stderr[-2000:]}")
return r.stdout
def run_task(repo, base, branch, task):
if not all(re.fullmatch(r"[\w.][\w./-]*", s) for s in (repo, base, branch)):
raise ValueError("repo, base and branch go into shell commands")
url = f"https://x-access-token:$GH_TOKEN@github.com/{repo}" # $GH_TOKEN expands in the sandbox
gh = {"GH_TOKEN": GH_TOKEN} # set for the clone and the push only, not for the agent's run
with Sandbox.create(template="prized-agent-v1", env_vars=AGENT) as sb: # deleted when the block ends
sh(sb, f"git clone -q -b {base} {url} app", cwd=".", env=gh, timeout=600)
sh(sb, f"git remote set-url origin https://github.com/{repo} && git switch -qc {branch}")
sh(sb, "git config user.name 'Prized agent' && git config user.email agent@example.com")
# Run your repository's setup script here, as Conductor did for each new workspace.
sb.files.write("task.md", task) # beside the repo, not in it
out = sh(sb, "claude -p --dangerously-skip-permissions --output-format json < ../task.md", timeout=3000)
result = json.loads(out)["result"] # the agent's last message
sh(sb, 'git add -A && (git diff --cached --quiet || git commit -qm "$MSG")', env={"MSG": task[:72]})
if not sh(sb, f"git log --oneline origin/{base}..HEAD"):
return None, result # nothing changed, so no pull request
sh(sb, f"git push -q {url} {branch}", env=gh, timeout=600)
pr = httpx.post(f"https://api.github.com/repos/{repo}/pulls", headers={"Authorization": f"Bearer {GH_TOKEN}"},
json={"title": task[:72], "head": branch, "base": base, "body": result})
pr.raise_for_status()
return pr.json()["html_url"], result
if __name__ == "__main__":
url, result = run_task("acme/app", "main", "agent/login-rate-limit", "Add rate limiting to the login endpoint, with a test. Run the tests.")
print(url or "No changes, so no pull request", result, sep="\n\n")run_task is the call your bot or orchestrator makes once per task:
- A fresh machine:
prized-agent-v1has Claude Code and Codex, with nothing signed in; thewithblock deletes the sandbox when the task ends, error or not (Templates). - The agent runs without asking inside the sandbox, which holds the repo and the agent's key (Skip permissions in an isolated VM). The task goes in as a file, so any text works.
- The GitHub token is set only for the clone and the push, so it is in neither the agent's environment nor the repo's config. The agent can still catch it at push time (a git hook, say), so keep it to the one repo with a short expiry, or take the commits out with
git bundleand push from your side. - The result is the agent's last message, and it becomes the pull request's body. The script commits whatever the agent left uncommitted, and opens no pull request when nothing changed.
For Codex, pass CODEX_API_KEY instead, run codex exec --dangerously-bypass-approvals-and-sandbox -o /, and read the result with sb.files.read("last.txt"). With a Claude plan instead of an API key, pass CLAUDE_CODE_OAUTH_TOKEN from claude setup-token.
3. Run it
.venv/bin/python run_task.py
# https://github.com/acme/app/pull/42
#
# I added a rate limit of 5 attempts per minute per IP to the login endpoint, with a test …It returns when the agent is done, so post the link and the message wherever the task came from, such as the Slack thread your bot answers in. Tasks in threads or a job queue run side by side, each in its own sandbox, up to your workspace's sandbox limit.
On the free tier a sandbox runs 60 minutes in all, so the script stops the agent at 50 (timeout=3000), and work cut off there is lost; on a paid workspace, raise it.
Or run it on your box
To keep the agent on a sign-in already on a box, such as your Claude or ChatGPT plan, run each task in a worktree there. The box needs your repo first (Moving from Conductor Cloud). These two commands do what conductor workspace create did: add a branch in its own folder from the latest main (run your setup script there the same way), then start the agent in it and return.
prized exec mango -- 'cd code/myproject && git fetch -q origin && git worktree add --no-track -b login-rate-limit ../myproject-login-rate-limit origin/main'prized prompt mango --provider claude --model opus --effort high --cwd code/myproject-login-rate-limit --auto --detach --notify https://hooks.example.com/prized - < task.mdThey use your CLI sign-in; with PRIZED_API_KEY set, the key needs Boxes: Write.
- Told when it ends: the URL, a public https address, gets one signed
prompt.finishedPOST with the run's status and links to its events, where theresultevent holds the agent's last message. The workspace owner creates the signing secret first, on API keys; until then a prompt with--notifyis refused and nothing starts (Webhooks). - Or poll: without
--notify,prized events --run pr_… --followwaits for the run and prints what the agent did, andprized prompt lslists each run's state. - From code: the same calls are
POST /execandPOST /prompts(withcwdandnotify) on the edge API (The edge API). - Several at once: a worktree per task, up to one run per 2 GB of the box's memory, at most 16 (Limits). The runs share the box's CPU and disk. Run coding agents from your own tools fans a whole plan out this way, with a Python receiver for the webhooks.
- The pull request: ask for it in the task ("commit, push, and open a pull request").
ghon the box is signed in if it was on your machine at setup, and--autolets the agent use it and run any command on the box (Approvals).
Conductor's calls on Prized
| Conductor Cloud | A sandbox per task | A run on your box |
|---|---|---|
POST /v0/workspaces, or conductor workspace create | Sandbox.create(...), then git clone -b | POST /exec with git worktree add, then POST /prompts |
projectId or repositoryUrl, and branch | The repo and branch you clone | The repo on the box, and the branch the worktree starts from |
agent, model, effort | The agent's own command line, such as claude -p --model opus --effort high | provider, model (the agent's own ids), reasoningEffort (low, medium or high) |
message, or conductor workspace create --message-file task.md | The task file you pass the agent | prompt; prized prompt … - < task.md reads a file |
env | env_vars on create, or env on one command | The box's variables (Environments) |
| The repo's setup script | Run it after the clone | Run it in the new worktree with POST /exec |
Polling GET /v0/sessions/{id}/status | run_task returns when the agent exits | The notify webhook, or GET /prompts/{runId} |
GET / | claude -p --output-format stream-json --verbose prints every step; json only the last message | GET /prompts/{runId}/events |
POST /, a follow-up | Create the sandbox without with and end with sb.pause(); later, Sandbox.connect(id), write the follow-up to task.md, and run claude -p --continue < ../task.md in app | POST /prompts with the run's conversationId |
POST /v0/sessions/{id}/cancel | Delete the sandbox | POST / |
POST / | The with block deletes the sandbox | git worktree remove through POST /exec |
What's different
- No Slack app of ours: keep your bot and point its calls at Prized.
- No multiplayer app: no Conductor chat and diff views, and no shared chats with presence. Members of a Prized workspace can open any box, and Activity lists each box's last prompt (Team activity).
- No routines: nothing on Prized starts a saved prompt from an incoming URL, so the endpoint you already run makes the call.
- No transcript SQL: read one run at a time (
GET /prompts/{runId}/events), or keep what your code saved. - Agents and efforts: the prompt API runs Claude Code, Codex, OpenCode and pi, with efforts from
lowtohigh. Conductor'scursorandacpagents have no match there, though the Cursor CLI runs on a box.
Getting help moving
Email with what your code called, and we will help you map it.