---
title: "Terminal"
description: "The boundary between the built-in shell panel and the agent's exec tool."
---

There are two ways to "run a command" in Bi, and they are easy to confuse. First, the split:

| Entry | Who uses it | Where output goes |
| --- | --- | --- |
| **Terminal panel** | You (human) | The on-screen terminal window — not the model's context |
| **`exec` tool** | The agent (model) | Back into the model's context as a tool result |

## Terminal panel

The "terminal" in the UI is a **stateful shell process** connected over WebSocket, available after login. It is for your manual use:

- One dedicated connection per terminal session; the backend spawns a persistent shell for it
- The working directory comes from the current session's `project_path`, falling back to the global workspace
- Output streams line by line; non-UTF-8 GBK output is converted to UTF-8 so Chinese text is not garbled
- Supports sending input, resize frames (recorded for front-end layout only) and an interrupt signal
- When not logged in, the WebSocket terminal is disabled and a pseudo-terminal over `workspace exec` is used instead

Its output is shown to you only; it is **not fed to the model automatically**.

## exec tool

Commands run by the agent go through the `exec` tool (`tools/exec.go`). It is fully independent of the terminal panel:

- Each call spawns a one-shot process under the workspace root
- Returns `exit_code`, `output`, `error` as a tool result that enters the model's context
- 5-minute default timeout, 64KB cap per stream (truncated beyond, with the truncation recorded)
- Governed by the tool permission system: without an allow rule, every call needs your approval
- Commands pass through [intercept rules](/en/docs/advanced/intercept-rules)

So "command output enters context" is true only for the `exec` tool. If you want the model to see a command's output, have it run the command with `exec` — not by running it in the terminal panel and pasting the result back.

## A note on network commands

`exec` and `websearch`-style plugins can reach the network (`curl`, `pip install`, `git clone`, `ssh`, and so on). That is a feature, not a bug, but it means:

- Using a local model does **not** guarantee "never online" — the command itself can make network requests
- Permission approval is the only human gate, so watch the `exec` calls you approve
- With `network_log_enabled` on, full command text is written to `.bi/logs/network/` (off by default)
