Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ For each release we list user-facing changes grouped as **Added**, **Changed**,

<!-- <START NEW CHANGELOG ENTRY> -->

## [Unreleased]

### Fixed

- **ACP startup no longer lets npm projects choose the adapter.** Starting an adapter through `npx` could execute a package planted in the workspace or a shared ancestor of the user's home before any approval prompt. ACP now launches a preinstalled `codex-acp` executable directly from an absolute server `PATH` directory, excluding workspace paths and aliases from adapter discovery and the `PATH` inherited by agent commands. **Migration:** install the tested `@zed-industries/codex-acp@0.16.0` in a trusted location and maintain its version there; NBI does not verify versions found on `PATH` or through an override. `NBI_ACP_AGENT_COMMAND` must point to the installed adapter itself by absolute path, not `npx`, `npm exec`, `pnpm dlx`, `bunx`, or an `env` wrapper. An override preserves the executable's name for trusted shims and retains the full server `PATH`; it is an administrator trust decision covering the executable, its runtime and packages, and their parent directories. Readiness and startup use the same resolver, so relative, missing, malformed, and set-but-empty or whitespace-only commands are consistently blocked. Unset `NBI_ACP_AGENT_COMMAND` to restore default discovery; assigning an empty value does not reset it. The adapter starts in NBI's user directory, workspace sessions retain their explicit root, and the `nbi_workspace_root` MCP tool receives that root through an environment variable. See the [admin guidance](docs/admin-guide.md#gating-the-experimental-acp-agent-378).

## [6.0.0] - unreleased

6.0.0 adds Chatbook, a notebook whose cells can be written in English and executed as generated code, together with its admin policy, its own kernel, and the context, mention, and ruleset plumbing around it. The rest of the release is hardening: the experimental ACP agent mode gets a tighter sandbox and better approval cards, and a long tail of chat, settings, MCP, and readiness fixes. The major version marks Chatbook's arrival rather than a compatibility break: no traitlet, env var, REST route, command id, or on-disk format was renamed or removed, `requires-python` is unchanged at `>=3.10`, and the supported JupyterLab range widened rather than narrowed. Upgrading needs no migration.
Expand Down
26 changes: 13 additions & 13 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,19 @@ If your cells contain sensitive outputs (PHI, PII, secrets), clear them before i

Hosts NBI may contact, depending on which features are enabled:

| Host | Purpose |
| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `api.githubcopilot.com` | GitHub Copilot chat and inline completion |
| `api.github.com` | GitHub Copilot device-flow login; managed-skills manifest fetches when hosted on github.com; skill imports |
| `github.com`, `codeload.github.com` | Skill tarball downloads (Import from GitHub and the managed-skills reconciler) |
| `raw.githubusercontent.com` | Manifest fetches when `NBI_SKILLS_MANIFEST` points at a `raw.githubusercontent.com` URL |
| `api.anthropic.com` | Anthropic API for Claude-mode inline chat and auto-complete; also the default destination of the Claude Code CLI |
| `api.openai.com` | OpenAI-compatible provider (default Base URL) |
| Your configured Base URL | OpenAI-compatible, LiteLLM-compatible, or Claude when pointed at a self-hosted endpoint |
| `localhost:11434` (or your Ollama host) | Ollama local model serving |
| `registry.npmjs.org` and configured npm mirrors | MCP servers configured to launch via `npx -y`, and ACP mode, which launches its adapter with `npx` on every agent start unless `NBI_ACP_AGENT_COMMAND` points elsewhere |

For the configurable destinations above (Base URLs, Ollama host, MCP `npx` packages), the destination is whatever you or your admin set. NBI itself starts no other network activity. In ACP mode the agent subprocess makes its own calls, which NBI neither proxies nor enumerates: the destinations there are the agent's to document, and blocking egress at the network layer is the only way to bound them from outside.
| Host | Purpose |
| ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `api.githubcopilot.com` | GitHub Copilot chat and inline completion |
| `api.github.com` | GitHub Copilot device-flow login; managed-skills manifest fetches when hosted on github.com; skill imports |
| `github.com`, `codeload.github.com` | Skill tarball downloads (Import from GitHub and the managed-skills reconciler) |
| `raw.githubusercontent.com` | Manifest fetches when `NBI_SKILLS_MANIFEST` points at a `raw.githubusercontent.com` URL |
| `api.anthropic.com` | Anthropic API for Claude-mode inline chat and auto-complete; also the default destination of the Claude Code CLI |
| `api.openai.com` | OpenAI-compatible provider (default Base URL) |
| Your configured Base URL | OpenAI-compatible, LiteLLM-compatible, or Claude when pointed at a self-hosted endpoint |
| `localhost:11434` (or your Ollama host) | Ollama local model serving |
| `registry.npmjs.org` and configured npm mirrors | MCP servers configured to launch via `npx -y` |

For the configurable destinations above (Base URLs, Ollama host, MCP `npx` packages), the destination is whatever you or your admin set. NBI itself starts no other network activity. ACP uses a preinstalled adapter; NBI does not fetch it from npm at startup. In ACP mode the agent subprocess makes its own calls, which NBI neither proxies nor enumerates: the destinations there are the agent's to document, and blocking egress at the network layer is the only way to bound them from outside.

For air-gapped or egress-restricted environments, see [`docs/admin-guide.md`](docs/admin-guide.md#air-gap-deployment).

Expand Down
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ NBI is free and open-source. Connect it to a free or paid LLM provider of your c

- Python 3.10+
- JupyterLab 4.x
- Node.js — required for [Claude mode](#claude-mode) (the Claude Code CLI), for [ACP agent mode](#acp-agent-mode), which launches its adapter with `npx` on every start, and for MCP servers that launch via `npx`.
- Node.js — required for [Claude mode](#claude-mode) (the Claude Code CLI), for the preinstalled `codex-acp` adapter used by [ACP agent mode](#acp-agent-mode), and for MCP servers that launch via `npx`. ACP mode requires a preinstalled adapter in a trusted location; NBI does not download it at startup.
- A fresh virtualenv or conda env is recommended so NBI doesn't conflict with system Python.

## Quick start
Expand Down Expand Up @@ -292,7 +292,9 @@ Per-user preferences (default on for the cell-output features) live in `config.j

Inline chat calls the Anthropic API directly while the other Claude modes go through the Claude Code CLI, so a deployment can need a different model id for each. It uses `inline_chat_model`, falling back to `chat_model` when that is unset. `NBI_CLAUDE_CHAT_MODEL` therefore governs both surfaces: while it is set, a stored `inline_chat_model` is ignored and its control is disabled. Set `NBI_CLAUDE_INLINE_CHAT_MODEL` as well to pin inline chat to a different model — it takes precedence and re-enables nothing, so both surfaces stay administrator-controlled.

`NBI_ACP_AGENT_COMMAND` (not a settings lock) overrides the adapter command NBI launches for the selected ACP agent type; the value is shell-split. For Codex, NBI appends its `-c` approval and sandbox options to that command, so a replacement must pass them through to codex-acp. Leave it unset to use the agent's registered default command.
`NBI_ACP_AGENT_COMMAND` (not a settings lock) selects an installed adapter by absolute executable path, for example `/opt/nbi/acp/bin/codex-acp`; the value is shell-split, so quote paths containing spaces. Point it at the installed adapter itself, not `npx`, `npm exec`, `pnpm dlx`, `bunx`, or an `env` wrapper: making a package runner's path absolute does not prevent it from selecting code from a project. For Codex, the adapter must honor the `-c` approval and sandbox options NBI appends. An override is an administrator trust decision covering the command, its runtime and packages, inherited `PATH`, and their parent directories.

Leave the override unset to discover a preinstalled `codex-acp` in an absolute server `PATH` directory outside the Jupyter workspace. Empty or whitespace-only values are errors; use `unset NBI_ACP_AGENT_COMMAND` in a POSIX shell to restore default discovery. NBI follows symlinks before launching it; installations using a shim that depends on the name `codex-acp` need an explicit absolute path to that trusted shim. Default startup removes workspace directories from the `PATH` inherited by the agent and its commands, which can exclude a project's `.venv/bin`; an explicit override retains the full server `PATH`. Install the tested `@zed-industries/codex-acp@0.16.0` and maintain that version yourself: NBI does not verify or update versions for either discovery method. See the [adapter installation and migration guidance](docs/admin-guide.md#gating-the-experimental-acp-agent-378) for a concrete install command, home-directory workspace layouts, and the explicit adapter-path requirement for Windows with Python 3.10 or 3.11.

Provider IDs: `github-copilot`, `openai-compatible`, `litellm-compatible`, `ollama`, `none`. The `*_MODEL_ID` value is whatever the chosen provider exposes (e.g. `gpt-4o`, `llama3:latest`). Claude model IDs are the literal IDs from the Anthropic API (e.g. `claude-opus-4-7`, `claude-sonnet-4-6`); empty string = "Default (recommended)"; `NBI_CLAUDE_INLINE_COMPLETION_MODEL` also accepts `none` (no inline completion in Claude mode) or `inherit` (use the General-tab Auto-complete model).

Expand Down Expand Up @@ -470,7 +472,7 @@ c.NotebookIntelligence.enable_chat_feedback_always_visible = True

NBI Settings opens on a **Status** card that answers one question: is this deployment configured to work, and if not, which specific piece is missing? Each check reports `ok`, `warn`, or `blocked`, and anything that is not `ok` carries the next action rather than just the failure ("the claude CLI was not found" plus "install it, or set `NBI_CLAUDE_CLI_PATH` and restart").

It runs on open and costs nothing: it resolves your provider and model, checks the model list is reachable and that your selected model is one the endpoint actually serves, and for the agent modes checks that the CLI answers `--version` and that credentials are present. A missing key is a warning rather than an error, because the Claude CLI and ACP agents can hold their own subscription logins that NBI cannot see.
It runs on open and costs nothing: it resolves your provider and model, checks the model list is reachable and that your selected model is one the endpoint actually serves, checks the Claude CLI with `--version`, and checks ACP's adapter executable without running it. Both agent modes also check whether credentials are present. A missing key is a warning rather than an error, because the Claude CLI and ACP agents can hold their own subscription logins that NBI cannot see.

**Test the endpoint** sends one short request to your configured model, after asking first. It is the only way to catch two failures nothing cheaper can see: a gateway that returns 200s but buffers instead of streaming, and a proxy that strips the `tools` field so agent mode silently never calls a tool. No model output is kept, so the result is safe to paste into a support ticket.

Expand Down Expand Up @@ -523,7 +525,7 @@ Full guide, including the span and event reference, the probe thresholds, worked

## Roadmap

NBI 6.x is the current line. New features land in minor releases (6.1, 6.2, …); breaking changes are reserved for a major release and announced in the [changelog](CHANGELOG.md). 6.0 itself is not a breaking release: it marks Chatbook's arrival, and no traitlet, env var, REST route, or on-disk format was renamed or removed, so upgrading from 5.x needs no migration. Upgrading from 4.x? See the [5.0.0 migration note](CHANGELOG.md#migration-note) for the `fastmcp` → `mcp` dependency swap, the new path sandboxes, and the workspace-file-attach behavior change.
NBI 6.x is the current line. New features land in minor releases (6.1, 6.2, …); breaking changes are reserved for a major release and announced in the [changelog](CHANGELOG.md). 6.0 marks Chatbook's arrival, and no traitlet, env var, REST route, or on-disk format was renamed or removed. Deployments using the experimental ACP mode must now preinstall its adapter; see the [migration guidance](docs/admin-guide.md#gating-the-experimental-acp-agent-378). Upgrading from 4.x? See the [5.0.0 migration note](CHANGELOG.md#migration-note) for the `fastmcp` → `mcp` dependency swap, the new path sandboxes, and the workspace-file-attach behavior change.

## License

Expand Down
5 changes: 3 additions & 2 deletions docs/acp.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ For the admin side of this feature (the two policies, the approval posture NBI p

The **ACP** tab in Settings is hidden until an admin allows the mode, because `acp_mode_policy` defaults to `force-off`. If you do not see the tab, that is why; ask for `NBI_ACP_MODE_POLICY=user-choice`.

With the tab visible, pick the agent type, then set the chat model, API key, and base URL. The adapter is launched with `npx` on every agent start, so the server needs Node.js on its `PATH` even though nothing is installed permanently.
With the tab visible, pick the agent type, then set the chat model, API key, and base URL. An administrator must first install the tested `@zed-industries/codex-acp@0.16.0` in a trusted location outside the Jupyter workspace. NBI finds its `codex-acp` executable through absolute directories on the server's `PATH`, or uses an absolute path to the installed adapter configured through `NBI_ACP_AGENT_COMMAND`. Do not use package runners such as `npx`, `npm exec`, `pnpm dlx`, or `bunx`, or an `env` wrapper, for that override. NBI does not download an adapter at startup or verify its version; the administrator maintains the installation. Settings → Status reports a missing or invalid adapter command or declared script interpreter. See the [installation and migration guidance](admin-guide.md#gating-the-experimental-acp-agent-378), including a concrete install command, home-directory workspace layouts, and the requirements for shims and Windows with Python 3.10 or 3.11. Empty or whitespace-only `NBI_ACP_AGENT_COMMAND` values are invalid; unset the variable to restore default discovery.

## What a turn looks like

Expand All @@ -22,7 +22,8 @@ Previous sessions are listed by the history control, and picking one resumes it

## Limits worth knowing

- **The first start is slow, and it is bounded.** An agent has 60 seconds to spawn, download the adapter through `npx`, initialize, authenticate, and create a session. On a cold cache over a slow link the download alone can exceed that, and the failure reads `ACP agent did not start in time`. Run the adapter command once by hand to warm the cache, or point `NBI_ACP_AGENT_COMMAND` at a pre-installed copy.
- **Agent commands use a filtered `PATH` by default.** Workspace directories, including a project's `.venv/bin`, are removed. Commands such as `python` or `pytest` may therefore select another installation or be unavailable. An administrator's explicit adapter override retains the full server `PATH` and requires trusting its contents.
- **Startup is bounded.** An agent has 60 seconds to spawn, initialize, authenticate, and create a session. If this takes too long, the failure reads `ACP agent did not start in time`. Check the adapter installation and authentication before retrying.
- **A turn is capped at 30 minutes**, after which it fails with an agent response timeout.
- **Session listing is optional.** Resuming depends on the agent advertising the capability, and listing is an optional protocol extension. An agent that implements neither reports that it does not support listing sessions; this is the agent's limitation, not a misconfiguration.
- **Chatbook uses ACP differently.** When ACP mode is active, Chatbook generation runs in a separate session with full access forced off, no MCP servers, and permission requests denied, so a Chatbook cell cannot approve its way into running commands.
Expand Down
Loading
Loading