Skip to content

GLM terminal and live browser

Use ordinary GLM-5.3-Flash with the GLM workspace terminal connection. The cloud control beside the composer selects or disconnects it for a chat. The connection appears under System because administrators manage it; its grants still restrict access to the trial user. Other users can use GLM normally without access to this private terminal.

The terminal gives GLM a Linux workspace for running code, managing files, starting local previews and controlling Chromium through agent-browser. The user can also type in the Bash terminal. Model inference still follows the existing Open WebUI → LiteLLM route. No extra GLM model is created.

Open the browser

Open /home/node/workspace/Browser.html in Files, or ask GLM to display it with mode="sidebar". This uses stock Open WebUI v0.11.2's authenticated file preview; it does not require a custom frontend. The pane streams the same Chromium session the model controls, with navigation, clicks and keyboard input. Open Browser.html in Files, never inside Chromium itself.

Chromium inside the native Files preview

This is a real Chromium browser in the container. Its cookies and page state are separate from the user's desktop browser. Screenshots are ordinary files that can be displayed and downloaded. For a local application, run the server through the terminal's run_command without & or nohup, then open its localhost address. Open Terminal tracks the process and lists its port.

Automatic landing layouts, equal browser/terminal sizing, and saved dimensions are the separate frontend proposal in PR #556. This service can be operated and upgraded independently of that proposal.

Model defaults and access

The existing glm record permits Terminal and defaults to the connection glm-terminal-pilot, which attaches only when available to the current user. Other declared and observed model records deny Terminal. The old glm-terminal alias is disabled in place; its record and saved chats remain. Account default model preferences are separate and are not changed by the migration.

Connection grants are the access boundary, subject to administrator access rules. Model capability or a model default cannot grant access to a private connection. Browser instructions come from the selected terminal's /system appendix and do not replace GLM's system prompt, tools or sharing grants.

Inspect and apply the focused migration:

python3 scripts/sync_terminal_pilot.py --api-key-file /private/path/admin-token
python3 scripts/sync_terminal_pilot.py --api-key-file /private/path/admin-token --apply
python3 scripts/sync_terminal_pilot.py --api-key-file /private/path/admin-token --check

The default is a dry run. Each applied action must return an object and pass fresh field-by-field verification. Partial failure reports verified progress and uncertain/remaining actions; re-fetch before retrying. --check is read-only and runs nightly to detect later UI edits. See the migration guide for preserved fields, the broader model-sync blast radius and rollback.

The nightly policy step runs after the live goal suite with always(), so a policy failure cannot prevent the other goals from running. Its failure is named in the nightly alert. GET requests retry transient failures up to three times; writes are never retried automatically. An expired nightly admin JWT reports the credential source that needs refreshing.

Runtime and authentication

The image combines Open Terminal 0.11.34, agent-browser 0.36.0 and Chromium, running as non-root node with 2 CPUs and 2 GiB in the trial. One HTTPS tunnel serves the terminal API and browser stream. The Mac, container and tunnel must remain on; chats sharing this connection share files and browser state.

Browser.html on disk is a credential-free placeholder. Open WebUI checks access to the connection and forwards the authenticated file request; the bridge generates the viewer in memory with a one-use ticket valid for 60 seconds. The response is no-store. The ticket authenticates the first WebSocket message; the opaque iframe's Origin: null is not authentication. With the optional workspace frontend, Reconnect asks the parent page to reload the authenticated preview for a fresh ticket. On stock Open WebUI, reopen Browser.html in Files; an opaque iframe's own reload cannot send the app's SameSite cookie. Streams expire after 30 minutes.

Configuration and placeholder files are replaced atomically from private files. Restarting the upgraded bridge and regenerating Browser.html invalidates the original trial's permanent browser credential. The legacy token file is unused. Native terminal requests require their own API key, which is never in the viewer.

The trusted user's browser and terminal deliberately share the container network, including private addresses and localhost demo servers. This is not an egress firewall: redirects and page scripts also use that network. Do not mount host or cluster credentials or expose sensitive host services. A shared/public fleet requires network isolation. Arbitrary shell access can inspect its own process environment; short-lived browser tickets do not isolate a compromised terminal.

Build, connection setup, the exact accepted boundary, upgrade and stop commands are in the runtime README. Set BROWSER_PANEL_LOG_LEVEL=DEBUG for scrubbed action/cause diagnostics. The viewer distinguishes expired authentication, a stopped browser and a lost tunnel, and recovers after an undecodable frame. Keep terminal keys, full plans and diagnostic logs private and outside Git.