Skip to main content
A conversation is a thread of prompts and responses with its own memory. The native session of the harness holds that memory.
  • The first boat prompt on a sandbox starts a conversation.
  • Every later prompt continues it.
You never have to handle the session id. But you can get it when you want it:
  • Every prompt prints its conversation id: conversation: <id> under queued:.
  • --json and the API response give it as conversationId.
  • Every event carries one.

List conversations

boat conversations (GET /sandboxes/{id}/conversations) lists the conversations, newest first. Each row shows:
  • the prompt count
  • whether a turn is running
  • the last harness and model
  • a preview of the last prompt
  • which one is the current conversation of the sandbox
Use it to get back the id of a thread that you started yesterday, or from another shell. Then pass that id to --resume.

The current conversation is per shell

The current conversation is scoped to your shell, like the current sandbox id.
  • --new makes the new conversation the current one for this shell.
  • A bare boat prompt continues the current one.
So two shells, two people, or two machines can prompt the same sandbox. Each one keeps its own thread. They do not interfere.

Parallel conversations

Conversations run at the same time. Each one has its own harness process and its own history: The rules are the rules you would write yourself:
  • One turn at a time per conversation. A second prompt to the same conversation waits for the current turn, because it needs the context of that turn. Prompts to different conversations run at the same time.
  • A cap per sandbox on turns that run at the same time. The cap depends on the memory of the sandbox: Above the cap, prompts wait in a queue and start when turns finish. Boat drops nothing. To set an exact number, set the ASCII_MAX_PARALLEL_CONVERSATIONS environment variable on the sandbox. Or change the size of the sandbox (Machine Capabilities).
  • List them with boat conversations. Each row shows whether a turn runs in it. So you see the parallel work at a glance.
  • Events stream all conversations by default, tagged with conversationId. To watch one, run boat events --convo <id>.
  • Interrupt is scoped. boat interrupt --convo <id> stops one turn. The others keep running. A bare boat interrupt stops everything on the sandbox.
  • Steer is scoped too. boat steer --convo <id> "..." changes one running turn without a stop. Read Steer a running turn.

Agent lifecycle

A prompt moves through a small state machine. Watch it with boat events or GET /prompts/{promptId}: A steer never makes a state of its own. The turn that was running is the turn that finishes. The work your message causes is part of that turn.

Conversations survive a stop

The sandbox lifecycle is under the prompt lifecycle. Conversations move with it:
  • A stop takes a snapshot of the disk. The snapshot includes the history of every conversation and the native session files of the harness under /home/user.
  • A resumed or forked sandbox gets them back. So --resume <id> continues with full memory.
  • Conversations and every config file in Customize the harness survive a stop.
  • Processes that the harness started by hand do not survive a stop, the same as on any reboot. A dev server or a tunnel it started are examples.

Switch harness or model in a conversation

Continue a conversation on a different harness. The new harness keeps the thread:
Boat freezes the transcript of the earlier harness into the conversation. Then it gives that transcript to the new harness. So the change is one flag, not a script that rebuilds the context. To give your users a selector for harness and model, map it to provider and model on POST /prompt.