Sign in

Prompt an agent remotely

Prompt Claude Code, Codex, OpenCode or pi on your box from your machine or any script, on the model and backend you pick, follow the run as it happens, and interrupt it; the run lives on the box, so nothing depends on your laptop staying open.

On this page13

Prompt the agent

prized prompt --provider claude "fix the failing tests in app/ and run them again"

This starts a headless Claude Code run on the box (claude -p, in your home directory), streams its events to your terminal, and exits when the agent is done. The first prompt installs three small helper scripts on the box; the first OpenCode or pi prompt also installs that agent (OpenCode and pi).

CommandWhat it does
prized prompt --provider claude "…"Run Claude Code on the default box and follow it. --provider codex, opencode or pi runs that agent.
prized prompt box-a7f3 --provider codex --cwd app "…"Run on a named box, in ~/app (--cwd is relative to your home, or absolute).
prized prompt --provider claude --model opus --effort high "…"Pick the model and the reasoning effort (low, medium, high).
prized prompt --provider codex --model deepseek/deepseek-flash "…"Run on another backend: amazon-bedrock/…, openrouter/… or deepseek/… (Models and backends).
prized prompt modelsThe known --model values per agent and backend, with the efforts each takes (--provider narrows it).
prized prompt --provider claude --continue "…"Continue the provider's newest session on the box instead of starting fresh.
prized prompt --provider claude --conversation cv_… "…"Continue that conversation with the provider you name. See Conversations.
prized prompt --provider claude --auto "…"Let the agent edit and run commands without approvals. See Approvals.
prized prompt --provider claude --detach "…"Start the run and print its id; follow it later with prized events.
prized prompt --provider claude --queue "…"Run after the conversation's turn in progress instead of refusing.
cat brief.md | prized prompt --provider claude -Read the prompt from stdin.
prized prompt conversationsEvery conversation on the box, most recently active first, with its prompt count and whether a turn is running.
prized prompt lsEvery run on the box, newest first (at most 50), with its state and conversation; --conversation cv_… keeps to one.
prized events --followFollow every run in progress until none is left (or show the newest run); --conversation cv_… keeps to one conversation, --run pr_… follows one run, --after N starts after event N.
prized interruptStop every run in progress (TERM to each one's process group, KILL after 5 s); --conversation cv_… stops one conversation's, --run pr_… one run.
  • Output: the agent's text, each tool call and result as one dim line, and a last line with the verdict and event count; -v adds the provider's system events.
  • Exit code: 0 when the run ends cleanly; 1 when the provider's last verdict is an error (one it retried past does not count), it exits non-zero, or the run was interrupted; 130 on Ctrl-C, which also interrupts the run on the box (prized events --follow leaves the run alone on Ctrl-C).
  • The prompt travels as a file, never on a command line, so it stays out of the box's process list and shell history.
  • Several runs at once: prized events --follow names each run as it starts and, while more than one is in progress, starts each line with its conversation id; its exit code is the worst of the runs it followed.
  • Waking: prized prompt wakes a suspended box; prized events, prized prompt ls, prized prompt conversations and prized interrupt do not.

Sign in first

The agent runs as you, with a credential already on the box. Without one, prized prompt refuses with provider_not_signed_in and names what to set. It looks in a login shell for:

AgentCredential
Claude Code~/.claude/.credentials.json (hand yours over with prized agents handoff claude), CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, or CLAUDE_CODE_USE_BEDROCK
Codex~/.codex/auth.json (prized agents handoff codex), OPENAI_API_KEY or CODEX_API_KEY
OpenCodeNothing required: with no key it offers only its free models; opencode auth login on the box or a provider key opens the rest
pi~/.pi/agent/auth.json (pi, then /login on the box) or any provider key, such as ANTHROPIC_API_KEY or OPENROUTER_API_KEY
Any agent on a backendThat backend's key (Keys for other agents and backends)

Models and backends

--model takes the agent's own model ids and aliases. Written as <backend>/<model id>, it runs the agent on that backend with the key you set on the box as a Secret or env var:

PrefixBackendClaude CodeCodexExample
amazon-bedrock/Amazon Bedrock in your AWS accountBedrock inference profile ids and ARNsBedrock's openai.* modelsamazon-bedrock/us.anthropic.claude-sonnet-4-6
openrouter/OpenRouterAny OpenRouter idIds that serve the Responses APIopenrouter/anthropic/claude-opus-5.5
deepseek/DeepSeekdeepseek-flash, deepseek-v4-proSamedeepseek/deepseek-flash

OpenCode and pi already name models as provider/model, so the same strings work for them unchanged, along with every other provider they support (opencode models and pi --list-models on the box list them). The prefix applies per run and never edits the agent's config files; a model with no prefix runs on whatever the agent is set up for.

prized prompt models lists known ids per agent and backend. Bedrock grants model access per AWS account and region: a model your account has not enabled fails with Bedrock's error.

--effort maps onto each agent's own control: claude --effort, Codex's model_reasoning_effort, opencode run --variant (a model without that variant ignores it), pi --thinking (clamped to what the model supports). DeepSeek models take low and high.

Approvals

By default the agent can edit files but not act freely, since a headless run cannot ask you; --auto lifts that, which "run the tests and fix them" needs. Each agent draws the line its own way:

AgentDefault--auto
Claude Codeclaude --permission-mode acceptEdits: edits allowed, commands deniedclaude --dangerously-skip-permissions
CodexIts workspace-write sandbox: edits and commands inside the working directory, no networkcodex --dangerously-bypass-approvals-and-sandbox
OpenCodeShell commands set to ask, which a headless run answers with a rejection; edits and its other tools as configuredopencode run --auto: every permission not explicitly denied is approved
pipi has no approvals, so its bash tool is left out: read, edit, write, grep, find, lsThe same tools plus bash

MCP tools stay available to OpenCode and pi in both modes.

Continuity

--continue resumes the newest session of the same provider on the box, so "now also update the docs" works; --conversation resumes a given one. Each agent resumes in its own way: claude --resume <id>, codex exec resume <id>, opencode run --session <id>, pi --session-id <id>. Claude Code and pi keep sessions per working directory, so continue from the same --cwd. prized prompt ls --json shows each run's sessionId and resumedFrom. With no earlier session on the box, --continue refuses (exit 5, no_session_to_continue on the API) rather than starting fresh.

Conversations

Every prompt is a turn of a conversation: one provider session, with the agent's memory of the turns before it. A conversation's id looks like cv_0123456789ab; prized prompt prints it as the run starts, --json and the API answer it as conversationId, and prized prompt conversations lists them.

FlagThe turn's conversation
None, or --newA new one, which runs beside the others.
--continueThe provider's newest conversation on the box (Continuity).
--conversation cv_…That one; explicitly name its provider with --provider.
  • Choose the provider locally: --provider is required on every prompt, including --conversation. If omitted, the CLI exits 2 before reading stdin or contacting the box. Conversation files on the box are mutable, so they cannot authorize which agent receives your next prompt. This does not protect prompts or credentials from a compromised box.
  • One provider per conversation: a prompt for a conversation with another --provider refuses (exit 5, provider_mismatch). All four agents hold conversations the same way, and the first turn of OpenCode or pi installs it if needed.
  • Model per turn: each turn takes its own --model and --effort, a backend included; the conversation lists its newest turn's model.
  • Pauses: conversations are files on the box, so they survive a pause and ride snapshots and forks; continue one by id afterwards.

Parallel runs and the queue

A box runs several conversations at once, up to its limit: one run in progress per 2 GB of the box's memory, at most 16 (Limits). A new run beyond it answers prompt_limit_reached (exit 6). To change the limit, write a number from 1 to 64 to ~/.prized/prompts/max-runs on the box; each run is a full agent process, so raise it only on a box with memory to spare.

A conversation takes one turn at a time. A prompt for a conversation with a turn in progress answers prompt_in_progress (exit 6); with --queue it waits and runs when that turn ends, continuing its session. --queue with no other flag joins the provider's newest turn in progress, so a --queue "then lint" right after a prompt still follows it; with nothing in progress it starts a new conversation.

Two commands on the box do the same, so a setup script or the agent itself can drive it:

queuePrompt "then run the linter and fix what it finds"
stopAgent
CommandWhat it does
queuePrompt "…"Queue a prompt (from its arguments, or stdin): inside a run, behind that run's conversation; elsewhere behind the newest run in progress; with nothing running, after the next run to finish. PRIZED_CONVERSATION=cv_… queuePrompt "…" picks the conversation.
stopAgentStop every run in progress; stopAgent cv_… stops one conversation's.

Both are in ~/.prized/bin, on the PATH of login shells after the first prompt. A run sees its own conversation and run id as PRIZED_CONVERSATION and PRIZED_RUN.

  • A queued prompt keeps its request: a --queue prompt keeps its own model, effort, working directory and --auto; a queuePrompt one inherits them from the run it follows.
  • An interrupted run leaves its conversation's queue for that conversation's next turn.

Where a run lives on the box

Each run is a directory on the box, so it survives a pause, rides a snapshot, and reads with ls and tail -f:

File in ~/.prized/prompts/<run id>/Contents
prompt.txt, meta.jsonThe prompt as given; provider, model, reasoning effort, and whether --auto was on.
cmd, nextThe provider command line for this run, and the one a continuation uses.
cwd, pid, started_at, exitThe working directory, the process group id, the start time, the exit code when done.
events.jsonl, stderr.logThe provider's raw event stream (claude --output-format stream-json, codex exec --json, opencode run --format json, pi --mode json) and its stderr.
session, resume, parentThe provider's session id once seen; for a continued run, the session it resumed; for a queued one, the run it followed.
conversationThe conversation the run is a turn of.
interruptedPresent when prized interrupt or stopAgent stopped the run.

~/.prized/prompts/conversations/<id>/queue/ holds a conversation's queued prompts, one directory each; ~/.prized/prompts/queue/ holds the ones queued with nothing running.

JSON and JSON Lines

--json on prized prompt prints the started run as one object and does not follow. --jsonl follows and prints one normalized event per line; with prized events --jsonl, it is the only command that prints more than one JSON document. A follow of several runs (prized events --follow without --run) adds runId and conversationId to each event.

{"seq": 7, "type": "tool_use", "text": "Let me run the suite.", "tool": {"name": "Bash", "input": {"command": "npm test"}}, "raw": {…}}
FieldMeaning
seqThe event's line number in events.jsonl, from 1; paging and --after use it (a page holds up to 200 events or 1 MiB).
atThe provider's timestamp, when the line carries one.
typesystem, assistant, tool_use, tool_result, result, error, or raw for a line the mapping does not know.
textThe readable content: the agent's text, a command, a tool's output, the final answer, an error (capped at 8 KiB).
toolFor tool events, {name, input}; Codex's are command_execution, file_change, mcp_tool_call (server/tool), web_search.
rawThe provider's line as written.

The agents differ in what they report, and the mapping keeps one line per event:

  • OpenCode reports a tool call once, when it finishes, so each is one tool_result carrying the tool, its input and its output. The last step's finish is the result; an error event is error.
  • pi streams token deltas as system events with no text; each finished message is one assistant event, tool calls are tool_use then tool_result, and the run's final answer is the result. A failed model call is an error event, and pi may retry past it; a run whose last model call failed exits 1, so its status is failed in prized prompt ls and the API too.

A run object (prized prompt --json, prized prompt ls --json, prized events --json) has id, provider, model, reasoningEffort, auto, status (running, done, failed, interrupted), exitCode, pid, cwd, startedAt, finishedAt, sessionId, resumedFrom, parent, eventCount, prompt.

Runs also carry conversationId. A conversation object (prized prompt conversations --json, under conversations beside running and limit) has id, provider, model (its newest turn's), prompts (turns so far), queued, running, lastRunId, lastStatus, sessionId, lastPrompt (the first 160 bytes), createdAt, updatedAt.

The edge API

The same surface is HTTP for scripts that hold an API key, under $EDGE/v1/box/{box}/ with the key as the bearer, found as for running commands:

RouteWhat it does
POST /promptsStarts or queues a run; new, conversationId and continue pick its conversation. The only route that wakes a suspended box.
GET /promptsLists runs; conversation=cv_… keeps to one.
GET /prompts/conversationsLists conversations.
GET /prompts/{runId}/eventsPages the events, or streams them as Server-Sent Events (follow=1, or Accept: text/event-stream); a stream holds one of the token's concurrent request slots until the run ends.
GET /prompts/eventsStreams every run in progress as Server-Sent Events until none is left; conversation=cv_… keeps to one.
POST /prompts/{runId}/interruptStops a run.
POST /prompts/interruptStops every run in progress; conversation=cv_… stops one conversation's.

Bodies and answers are on API reference: Prompts and events.

Errors

A failed request answers {"ok": false, "error": {"code", "message"}}. Beyond the shared edge codes, these routes add invalid_provider, prompt_required, invalid_request, prompt_in_progress, provider_not_signed_in, provider_not_installed and no_session_to_continue (API reference: Errors). provider_not_installed also answers an OpenCode or pi install that failed, with the reason (no network, or a checksum that no longer matches the pin). From the CLI, a run in progress exits 6 (CONFLICT) and the rest exit 5 (CHECK_FAILED) with a hint.

Conversations add prompt_limit_reached (the box is at its limit; exit 6 from the CLI) and provider_mismatch (conversationId names a conversation of another provider; exit 5), and prompt_in_progress names the conversation whose turn is in progress.

Limits

Every cap for prompts, runs, and events is on Limits.

Compared with prized agents run

prized agents run starts the agent interactively in a tmux session you attach to and approve things in; prized prompt is the headless form, with a verdict at the end and an API for scripts. Both use the box's sign-in, and both install OpenCode and pi on first use.