Start and follow Sessions
Every piece of work runs as a Session.
Start a Session
In devboxes, choose Start a Session and tell devboxes what you'd like done. In the first menu under the message, choose the Project, or type @, and the Blueprint, or type /; Automatic routing leaves that choice to devboxes. A message with a Blueprint and a Project starts the Session. Any other message gets the answer devboxes gives to 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 it asks you. Automatic routing and bundles need your Organization's Chat turned on. In the model menu, choose a model and then its effort. Within the Session, the Blueprint and model stay fixed, and you can pick a different effort for your next message.
To do it from a terminal, give your coding agent this prompt:
Ask me what devboxes should work on. Use the devboxes Project for this repository. Start a Session for it, follow it until it finishes, and tell me where the result is. If the devboxes agent asks a question, show it to me and send my answer.
Or do it yourself with the CLI:
{
"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 @dispatch.jsonThe result contains the sessionId and the sessionUrl, the Session's page in the web app, where you can follow its work. sessions.continue returns both as well. The Session's first Run starts as soon as the Project's Runner picks it up.
The Run uses 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. If you don't name one, the Run uses 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. If the Project has none, it fails with BLUEPRINT_MISSING, and the message tells you what to do: commit a Blueprint or bind one to the Project.
The Run uses the model and effort the Blueprint's version sets or, if it sets no model, the Project's model selection. To run it on a different model, add "model": { "providerId": "<provider>", "modelId": "<model>" } and optionally "effort": "<effort>" from the models and efforts that model-accounts.models lists. A Session that names a model without an effort runs at the provider's default effort. A model that none of the Organization's model accounts runs fails with MODEL_ACCOUNT_MISSING, and an effort the model doesn't 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 has to exist. In an empty repository, sessions.dispatch fails with REPOSITORY_EMPTY. If the repository has commits but not the Project's branch, it fails with PROJECT_BRANCH_MISSING. Push the Project's branch, then start the Session again.
To work on an open pull request, a teammate's for example, add "pullRequest": 17. The agent then builds on that pull request.
Only one Session at a time works on a branch. If another Session's work is still running on the branch where this Session would publish, sessions.dispatch and sessions.continue fail with PUBLICATION_BRANCH_BUSY. Start the Session again once that work has ended.
Follow a Session
In devboxes, open Sessions. Each Session shows what its latest Run is doing, and one that waits for you says Needs your answer. Open a Session to follow its work as it happens.
To do it from a terminal, give your coding agent this prompt:
Show me what my devboxes Sessions are doing right now, and list the ones that wait for an answer from me.
Or do it yourself with the CLI:
{ "organizationId": "<organization id>", "sessionId": "<session id>" }devboxes invoke sessions.inspect --input @session.jsonThe 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 is waiting, and what the node states mean.
sessions.events shows the agent's messages and tool calls while it works. Agent events describes what it shows.
Follow Sessions 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 agent is asking you a question reads Needs your answer.
Open a Session to follow it. The conversation starts with your request. Below it, each tool call reads as what the agent did, for example "Read summary.ts" or "Ran pnpm test". Consecutive work folds into one summary, such as "Read 2 files". Open the summary to see the separate rows, and open a row for the full path or command. The prompts 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 agent is asking a question that's waiting 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 the latest activity, so a Session updated while you page moves to the top and shows up on the next fresh first page.
sessions.unexpected-issues lists what agents didn't expect in their node reports, across your Organization's Sessions, newest first. In the dashboard, choose Unexpected issues on the Sessions page, and pick a Project to see only its issues. For a node, it shows the agent's latest report, because an amendment replaces the earlier one. From the CLI, limit it to one Project with projectId. For the next page, pass the last report's reportId as before.
{ "organizationId": "<organization id>", "limit": 20 }devboxes invoke sessions.unexpected-issues --input @unexpected-issues.jsonAnswer the agent's questions
An agent can stop and ask you something. In devboxes, the Session's page shows the questions in place of the message field. Answer them and choose Send answer, or Send answers for several.
To do it from a terminal, give your coding agent this prompt:
Show me the open questions of my devboxes Sessions one at a time, and send my answers.
Or do it yourself with the CLI. See the open questions:
devboxes invoke sessions.questions --input @session.jsonAnswer with the question's itemId:
{
"organizationId": "<organization id>",
"sessionId": "<session id>",
"input": { "kind": "answer", "itemId": "<item id>", "answer": { "choice": "Keep the old API" } }
}devboxes invoke sessions.input --input @answer.jsonThe question lists the fields that answer needs.
To let someone without a devboxes account answer, choose Share questions on the Session's page in the dashboard, then Create a link and password, or run question-sessions.open. Send the link and the password separately: devboxes shows them only once, and they work for 12 hours. The same dialog shows who entered and lets you close the link, as question-sessions.list and question-sessions.close do. A viewer can't share questions.
Send the agent a message
While the agent works, you can steer it:
{
"organizationId": "<organization id>",
"sessionId": "<session id>",
"input": { "kind": "message", "text": "Skip the migration. Only change the handler." }
}devboxes invoke sessions.input --input @message.jsonUntil the agent picks up the message, sessions.inputs lists it as pending, and the Session's page in the dashboard shows it where you sent it, marked as not delivered yet. If the work ends first, devboxes doesn't deliver it: sessions.inputs lists it as rejected, with the reason in error, and the page shows that reason after it. To send it again, continue the Session.
A review or recheck only reads the work, so a message sent to it fails with REVIEW_RUNNING. To change the work while the automatic review runs, continue the Session: the instruction waits as a follow-up, as the next section describes.
Give the Session more work
Continue the same Session with a new instruction:
{
"organizationId": "<organization id>",
"sessionId": "<session id>",
"instruction": "Also cover the logout redirect.",
"inputs": {}
}devboxes invoke sessions.continue --input @continue.jsonIf the Session is busy, because a Run is still queued or running, its machine hasn't stopped yet, or its automatic review is reviewing, fixing or rechecking, the instruction waits on the Session as a follow-up. The answer has its followUpId instead of a runId. When the current Run succeeds and the Session is free, devboxes starts the oldest follow-up as the next Run, as the person who asked for it. If that Run fails, is cancelled or pauses, no follow-up starts: sessions.inspect lists each under followUps, with who asked and why it didn't start. Continue the Session again to start the work, or drop a follow-up with sessions.cancel and its followUpId.
If the last Run saved its work, the agent picks up where it stopped. If every earlier Run ended before its agent started, it starts the work from the beginning. Either way, it works on the same branch. sessions.continue needs the work the last Run saved. If that Run ended before the Session kept its work, sessions.continue fails with CHECKPOINT_UNAVAILABLE, so start a new Session instead. Dispatch inputs 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. If that Blueprint is archived or limited to other Projects, sessions.continue fails with SESSION_BLUEPRINT_UNAVAILABLE, and the work can only continue in a new Session. If that version works on an issue and the Session isn't linked to one, 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 and its model; work that needs another starts a new Session. It keeps its issue too, so an 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 a different effort, add "effort": "<effort>" from the efforts that model-accounts.models lists for the Session's model, or "effort": null for the provider's default. If the catalog no longer offers the Session's model, or none of the Organization's model accounts runs it, sessions.continue fails with SESSION_MODEL_UNAVAILABLE, and the work can only continue in a new Session.
The new Run uses the model account of the Session's latest work Run, even while that account is paused. To continue on a different account in the dashboard, choose Continue on another account… in the Session's menu, pick the account and write the instruction. A paused account says until when. From the CLI, 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 tells you when devboxes ends its pause. Any other accountId fails with MODEL_ACCOUNT_UNAVAILABLE. On a different account, the provider can't reuse its cache of the Session.
Stop a Session
devboxes invoke sessions.cancel --input @session.jsonCommits the agent already pushed stay on the branch. sessions.cancel also closes a Session's paused work. Its Run ends cancelled, its open questions stop taking answers, and nothing continues it. You can still continue the Session with sessions.continue. devboxes never closes paused work on its own.
With "followUpId": "<follow-up id>", sessions.cancel drops that follow-up instead and leaves the Session's work running.
Open and download files
An agent can attach files to its Session, a report for example. The agent of a work or fix Run sees the files attached in earlier Runs of the Session, so it can refer to one without attaching it again. In Slack, Discord and Telegram, devboxes posts the media among them where the work happens, and in Microsoft Teams and Google Chat it posts a link to each in the thread. See Chat.
On the Session's page, Artifacts in the right panel shows the files as a gallery. Open one to see it in the panel, and move to the one before or after it with the arrow keys. The page's address names the open file, so you can link to it. devboxes shows images, videos, PDFs, and plain text or Markdown in place. Any other file, such as HTML or SVG, only downloads.
From the CLI, sessions.artifacts lists the files, and its inline field says which ones show in place. sessions.artifact-download gives you a link to download one. Add "disposition": "inline" for a link that shows it in your browser instead.
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. The link shows the file in the browser when its type is one devboxes shows in place, and downloads it otherwise.
See what a Session cost
sessions.usage shows the tokens and the cost of a Session's Runs.