Skip to content

Browser terminal, pi and the LLM gateway

Sign in and open a VM from the dashboard, or go to /vm/<name> on this site. You get a terminal in the VM and, beside it, a chat with the pi coding agent running in that VM. On a phone the chat comes first, with the terminal below it.

The console needs the VM to be running. If it is stopped, the page says so and gives the command to start it:

Terminal window
ssh turm.dev start demo

Each message runs one pi turn in the VM, as root in /root, and streams the reply. Each tool pi runs (a shell command, a file read or edit) shows as a collapsed line with the tool’s name and arguments; tap it to see its output, which fills in live while the tool runs. Failed tools are shown in red. The reply is rendered as markdown (headings, lists, code, links) once the turn ends; raw HTML in a reply is shown as text, never run. The conversation is kept in the VM, in /root/.agentcloud/chat.jsonl, next to pi’s own session files. So:

  • Reloading the page, or opening it on another device, shows the conversation and carries on from it.
  • A turn keeps running if the page goes away (a phone locks, the network drops). The page shows pi is still working and fills in the reply when the turn ends. A turn is stopped after 15 minutes.
  • One turn runs at a time per VM. A second message is refused until the first one finishes.
  • New starts a new conversation. The old transcript is renamed to /root/.agentcloud/chat-<time>.jsonl, and pi starts a new session.

The same conversation is reachable without the browser. pi’s --continue picks up the session the chat used:

Terminal window
ssh vm+demo@turm.dev pi --continue # interactive
ssh vm+demo@turm.dev "cd /root && pi --continue -p 'run the tests'" </dev/null
ssh vm+demo@turm.dev tail -n 5 /root/.agentcloud/chat.jsonl

pi -p over a non-interactive ssh keeps stdin open and waits on it. Close stdin with </dev/null.

The web chat appends its own turns to chat.jsonl; turns you run over SSH are in pi’s session but not in that file. Each line has the prompt, the reply as plain text and, for newer turns, parts: the text and tool calls in order, as the chat shows them.

Every VM ships with pi, a coding agent, already set up for the LLM gateway. Run it in the VM:

Terminal window
pi

VMs reach an OpenAI-compatible LLM gateway at http://169.254.169.254/llm/v1. The VM does not need an API key. The gateway identifies the VM by its source address and meters usage to the account that owns the VM. An account with no paid plan, including a trial, cannot call the gateway unless an admin sets a limit. A paid plan can call it, up to the monthly budget on that plan. Any OpenAI-compatible client works:

Terminal window
curl http://169.254.169.254/llm/v1/chat/completions \
-d '{"model":"turm-default","messages":[{"role":"user","content":"hi"}]}'

The gateway also serves the Responses API (Codex) and the Anthropic Messages API (Claude Code). See add-ons.

The default login in a VM is root. Codex and Claude Code read a system config as well as each home directory, so the gateway config is written for root, copied into /etc/skel for a new account, and installed as a system file that covers every login. Codex uses /etc/codex/config.toml. Claude Code uses /etc/claude-code/managed-settings.json. Switching an agent to a subscription login removes those files. pi is already set up for root, and a new account gets the same files from /etc/skel.

This deployment’s included gateway is Scaleway Generative APIs at https://api.scaleway.ai/v1. turm-default is deepseek-v4.1-flash. The list also has glm-5.3, qwen3.5-397b-a17b, qwen3-coder-30b-a3b-instruct and gpt-oss-120b.

http://169.254.169.254/latest/llm lists the VM name, each active source, and its model ids, plus a curl line for each. The response has no secrets. pi and the other agents in the VM can read it. The included gateway is turm-default. A stored key or a custom endpoint shows up as a namespaced model. A disabled provider is left out.

You can point an agent at your own provider key, or at a subscription login that runs inside the VM. Keys stay on the server. Subscription tokens stay in the VM. The FAQ has the three modes and what is billed. pi’s subscription mode does not work in this web chat until you set that VM back to the included gateway.