devboxes

Start and follow tasks

A task runs as a Session.

Start a task

In the devboxes dashboard, choose Start a task and tell devboxes what to do. In the first menu under the message, choose the Project, or type @, and the Blueprint, or type /; Automatic routing leaves either choice to devboxes. A message with a Blueprint and a Project starts the task. Any other message is answered as devboxes answers a mention of @devboxes in your team's chat app: it starts the Blueprint you picked, one from the bundle you picked, or the one that fits, in the Project you picked or the one that fits, or asks you. Automatic routing and bundles need your Organization's Chat turned on. In the model menu, choose a model, then its effort; in the task's Session, the Blueprint and model stay fixed, and you can pick another effort for your next message.

From the CLI:

task.json
{
  "organizationId": "<organization id>",
  "projectId": "<project id>",
  "title": "Fix the login redirect",
  "instruction": "After login, users land on /home instead of the page they came from. Fix it and add a test.",
  "inputs": {}
}
devboxes invoke sessions.dispatch --input @task.json

The result contains the sessionId. The task starts as soon as the Project's Runner picks it up.

The task runs the latest committed version of the Blueprint you name with "blueprint": "<blueprint name>". The Project can use the Blueprints bound to it and the Blueprints without bindings. Without a name, the task runs the Blueprint bound to the Project or, when none is bound, the Organization's one Blueprint without bindings. When several Blueprints are bound, or none is bound and several have no bindings, sessions.dispatch fails with BLUEPRINT_CHOICE_REQUIRED and lists their names and descriptions. When the version reaches a sensitive integration and no owner approved it, it fails with OWNER_APPROVAL_REQUIRED. When the Project has none, it fails with BLUEPRINT_MISSING, and its message says what to do: commit a Blueprint or bind one to the Project.

The task runs on the model and effort that the Blueprint's version sets, or, when it sets no model, on the Project's model selection. To run it on another model, add "model": { "providerId": "<provider>", "modelId": "<model>" } and optionally "effort": "<effort>" from the models and efforts that providers.models lists. A task that names a model without an effort runs at the provider's default effort. A model that no model account of the Organization runs fails with MODEL_ACCOUNT_MISSING, and an effort the model does not run at fails with EFFORT_UNSUPPORTED, whose details.efforts lists the model's efforts.

The agent starts from the latest commit on the Project's branch, so that branch must exist. In an empty repository, sessions.dispatch fails with REPOSITORY_EMPTY. When the repository has commits but not the Project's branch, it fails with PROJECT_BRANCH_MISSING. Push the Project's branch, then start the task again.

To work on an open pull request, for example a teammate's, add "pullRequest": 17. The agent then builds on that pull request.

Only one Session at a time works on a branch. When another Session's work is still running on the branch where this task would publish, sessions.dispatch and sessions.continue fail with PUBLICATION_BRANCH_BUSY. Start the task again once that work has ended.

Follow a task

To do it yourself:

session.json
{ "organizationId": "<organization id>", "sessionId": "<session id>" }
devboxes invoke sessions.inspect --input @session.json

The result lists the Session's Runs with their status, their progress through the Blueprint's nodes, and the agent's summary. Sessions, Runs, and Reviews lists the statuses, why a queued Run waits, and what the node states mean.

sessions.events shows the agent's messages and tool calls as it works. Agent events describes what it shows.

Follow tasks in the dashboard

Sessions in the devboxes dashboard lists the same Sessions, 50 at a time. Choose Show more for the next 50, and type in Search by title to find a Session by its title. A Session whose task asks you a question reads Needs your answer.

Open a Session to follow it. The conversation starts with your request. Below it, a tool call reads as what the agent did, for example "Read summary.ts" or "Ran pnpm test". Work that follows in a row folds into one summary, such as "Read 2 files". Open the summary for the separate rows, and open a row for the full path or command. The prompts that devboxes gave the agent fold into a row named Instructions devboxes gave the agent.

sessions.list lists your Organization's Sessions, most recently updated first. waitingForAnswer is true while a Session's running task asks a question that waits for an answer. Find Sessions by title with query, or by their latest Run's status with status. For the next page, pass the last Session's updatedAt and id as before. Paging follows last activity, so a Session updated while you page moves to the top and appears on the next fresh first page.

sessions.unexpected-issues lists what agents did not expect in their node reports, across your Organization's Sessions, newest first. For a node, it shows the agent's latest report, because an amendment replaces the earlier report. Limit it to one Project with projectId. For the next page, pass the last report's reportId as before.

unexpected-issues.json
{ "organizationId": "<organization id>", "limit": 20 }
devboxes invoke sessions.unexpected-issues --input @unexpected-issues.json

Answer the agent's questions

An agent can stop and ask you something.

To do it yourself, see the open questions:

devboxes invoke sessions.questions --input @session.json

Answer with the question's itemId:

answer.json
{
  "organizationId": "<organization id>",
  "sessionId": "<session id>",
  "input": { "kind": "answer", "itemId": "<item id>", "answer": { "choice": "Keep the old API" } }
}
devboxes invoke sessions.input --input @answer.json

The question lists the fields that answer needs.

Send the agent a message

While the agent works, you can steer it:

message.json
{
  "organizationId": "<organization id>",
  "sessionId": "<session id>",
  "input": { "kind": "message", "text": "Skip the migration. Only change the handler." }
}
devboxes invoke sessions.input --input @message.json

A review or recheck only reads the work, so a message to it fails with REVIEW_RUNNING. Until the automatic review has finished its review, fixes, and rechecks, continuing the Session fails with SESSION_BUSY. Continue it once the review finishes.

Give the Session more work

When a task is done, continue the same Session with a new instruction:

continue.json
{
  "organizationId": "<organization id>",
  "sessionId": "<session id>",
  "instruction": "Also cover the logout redirect.",
  "inputs": {}
}
devboxes invoke sessions.continue --input @continue.json

The agent picks up where the last Run stopped when that Run saved its work. When every earlier Run ended before its agent started, it starts the task from the beginning. Either way it works on the same branch. sessions.continue needs the work the last Run saved. When that Run ended before the Session kept its work, sessions.continue fails with CHECKPOINT_UNAVAILABLE, so start a new task instead. Dispatch inputs that you leave out of inputs keep the values the Session's latest Run was given. The new Run uses the latest committed version of the Session's Blueprint. When that Blueprint is archived or limited to other Projects, sessions.continue fails with SESSION_BLUEPRINT_UNAVAILABLE, and the work continues only in a new task. When that version works on an issue and the Session is linked to none, sessions.continue asks for it with BLUEPRINT_INPUT_MISSING: add "issue": "<issue>" to link one, as sessions.dispatch takes it. A Session keeps its Blueprint, its model and its issue, so a blueprint, model or issue other than the Session's fails with SESSION_CHOICE_LOCKED. Each Run in sessions.inspect shows its blueprintId, model, and effort.

The new Run keeps the effort of the Session's latest work Run. To continue at another effort, add "effort": "<effort>" from the efforts that providers.models lists for the Session's model, or "effort": null for the provider's default. When the catalog no longer offers the Session's model, or no model account of the Organization runs it, sessions.continue fails with SESSION_MODEL_UNAVAILABLE, and the work continues only in a new task.

The new Run uses the model account of the Session's latest work Run, even while that account is paused. To continue on another account, pick one from the accounts that sessions.inspect lists for the Session and add its accountId to continue.json. Those are the Organization's accounts that run the Session's model. A paused account's pausedUntil says when devboxes ends its pause. Any other accountId fails with MODEL_ACCOUNT_UNAVAILABLE. On another account, the provider cannot reuse its cache of the Session.

Stop a task

devboxes invoke sessions.cancel --input @session.json

Commits that the agent already pushed stay on the branch.

Download files

An agent can attach files to its Session, for example a report. The agent of a work or fix task sees the files attached in earlier tasks of the Session, so it can refer to one without attaching it again. sessions.artifacts lists them, and sessions.artifact-download gives you a link to download one. In a Slack thread, devboxes posts the media among them. See Chat.

An agent can also share a file it attaches, such as the recording in a GitHub issue comment. A shared file gets a link that anyone who has it can open, without signing in, until the Session is erased.

See what a task cost

sessions.usage shows the tokens and the cost of a task's Runs.

Terms of ServicePrivacy Policy

On this page