You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(codex): experimental Codex agent mode via the Agent Client Protocol (#378)
Add an opt-in Codex (OpenAI) agent mode that drives the chat panel over the
Agent Client Protocol (ACP), the way Claude mode drives it today: streaming
replies, tool-call cards with diffs, and per-tool approval. An NBI MCP tool is
invoked end to end to prove the path.
- ACP client backend (acp_agent.py) on a persistent worker thread, mapping ACP
events onto NBI's chat surfaces, with single-flight turns and a hardened
subprocess lifecycle. A small stdio MCP server (acp_mcp_server.py) exposes an
NBI tool to the agent.
- codex_settings + a codex_mode admin policy that defaults to force-off, plus
OPENAI_API_KEY / OPENAI_BASE_URL / NBI_CODEX_CHAT_MODEL overrides, following
the existing seven-place policy and settings-override conventions.
- Frontend: a Codex settings tab (enable, model, key, base URL) mirroring the
Claude tab, and chat-panel awareness so the input and routing follow Codex.
- An in-chat agent picker (shown when more than one agent mode is enabled) that
resolves a single active agent from the enabled modes and a persisted
preference; with no preference the historical Claude-wins default holds. The
picker is a custom icon dropdown, and the agent footer is unified (Ask/Agent
and tools stay on the native model path; agent modes show only their badge).
- Consistent branding: the OpenAI mark for the Codex participant and tab.
- Admin gating parity with Claude: a codex_full_access policy (default
force-off) pins Codex to approval_policy=untrusted so it asks before risky
actions, clamped server-side; user-choice exposes a "Full access" toggle that
flips the launch to approval_policy=never. README and admin-guide document
the controls, the CODEX_HOME isolation, and the residual precedence caveat.
Unit tests cover the ACP-to-NBI mapping, approval, the policy clamps, the
active-agent resolution, the approval-arg mapping, and the credential scrub.
The live path was verified in a running JupyterLab.
Copy file name to clipboardExpand all lines: README.md
+21-19Lines changed: 21 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -105,7 +105,7 @@ Bypass Permissions never persists: starting a **New chat session** (or `/clear`)
105
105
106
106
Choosing **Bypass Permissions** does not arm it immediately. It opens a confirmation step; only after you confirm does bypass take effect, and while it is active the shield turns into a red warning icon as a persistent indicator. Bypass must be re-armed each session: starting a new chat or restarting the Claude client drops back to Default. And because the server re-checks the requested mode on every message, an armed bypass can never outlive a policy that an administrator has since turned off.
107
107
108
-
**Admin gating.** Bypass Permissions is **off by default** and hidden from the selector unless an administrator enables it: it is governed by the `claude_bypass_permissions` policy (`NBI_CLAUDE_BYPASS_PERMISSIONS_POLICY`), the only admin policy whose default is`force-off` rather than `user-choice`. The requested mode is also clamped on the server for every message, so the gate can't be bypassed by a hand-crafted request. Independently, NBI honors Claude Code's enterprise [managed settings](https://code.claude.com/docs/en/settings): `permissions.disableBypassPermissionsMode` removes the option regardless of the NBI policy, and `permissions.defaultMode` sets the selector's starting mode (Bypass excepted, since it never auto-arms). See [Allowing Bypass Permissions](docs/admin-guide.md#allowing-bypass-permissions-in-the-claude-permission-mode-selector) in the admin guide.
108
+
**Admin gating.** Bypass Permissions is **off by default** and hidden from the selector unless an administrator enables it: it is governed by the `claude_bypass_permissions` policy (`NBI_CLAUDE_BYPASS_PERMISSIONS_POLICY`), one of three admin policies that default to`force-off` rather than `user-choice` (the others gate the experimental Codex mode and Codex full access). The requested mode is also clamped on the server for every message, so the gate can't be bypassed by a hand-crafted request. Independently, NBI honors Claude Code's enterprise [managed settings](https://code.claude.com/docs/en/settings): `permissions.disableBypassPermissionsMode` removes the option regardless of the NBI policy, and `permissions.defaultMode` sets the selector's starting mode (Bypass excepted, since it never auto-arms). See [Allowing Bypass Permissions](docs/admin-guide.md#allowing-bypass-permissions-in-the-claude-permission-mode-selector) in the admin guide.
109
109
110
110
The `/enter-plan-mode` and `/exit-plan-mode` slash commands still work if typed but are no longer offered in autocomplete; the selector replaces them and will retire the commands in a future release.
111
111
@@ -196,24 +196,26 @@ Most settings panel toggles can be locked by org administrators. Two shapes:
196
196
197
197
**Boolean policies** use the `*_POLICY` suffix and accept three values: `user-choice` (default — user toggles freely), `force-on` (locked enabled), `force-off` (locked disabled). When forced, the panel control is disabled with a "Locked by your administrator" tooltip and any client-side write is ignored.
198
198
199
-
| Env var | Locks the Settings panel control for |
|`NBI_STORE_GITHUB_ACCESS_TOKEN_POLICY`| "Remember my GitHub Copilot access token" |
211
-
|`NBI_SKILLS_MANAGEMENT_POLICY`| The Skills tab (force-off hides it and 403s the API; also disables the managed-skills reconciler) |
212
-
|`NBI_CLAUDE_MCP_MANAGEMENT_POLICY`| The Claude-mode MCP Servers tab (force-off hides it and 403s `/claude-mcp/*`; independent of the non-Claude MCP Servers tab) |
213
-
|`NBI_CLAUDE_PLUGINS_MANAGEMENT_POLICY`| The Claude-mode Plugins tab (force-off hides it and 403s `/plugins/*`) |
214
-
|`NBI_CLAUDE_BYPASS_PERMISSIONS_POLICY`| "Bypass Permissions" in the Claude permission-mode selector (defaults to `force-off`, the only policy that does; `user-choice` exposes the option, which the user still arms per session) |
|`NBI_CODEX_MODE_POLICY`| "Enable Codex mode" (experimental ACP agent mode; defaults to `force-off`, set `user-choice` to allow it) |
206
+
|`NBI_CODEX_FULL_ACCESS_POLICY`| "Full access" for Codex: run tools without asking (defaults to `force-off`, so Codex asks before anything beyond trusted read-only commands; `user-choice` lets users opt into unattended runs) |
|`NBI_STORE_GITHUB_ACCESS_TOKEN_POLICY`| "Remember my GitHub Copilot access token" |
213
+
|`NBI_SKILLS_MANAGEMENT_POLICY`| The Skills tab (force-off hides it and 403s the API; also disables the managed-skills reconciler) |
214
+
|`NBI_CLAUDE_MCP_MANAGEMENT_POLICY`| The Claude-mode MCP Servers tab (force-off hides it and 403s `/claude-mcp/*`; independent of the non-Claude MCP Servers tab) |
215
+
|`NBI_CLAUDE_PLUGINS_MANAGEMENT_POLICY`| The Claude-mode Plugins tab (force-off hides it and 403s `/plugins/*`) |
216
+
|`NBI_CLAUDE_BYPASS_PERMISSIONS_POLICY`| "Bypass Permissions" in the Claude permission-mode selector (defaults to `force-off`, as do `NBI_CODEX_MODE_POLICY` and `NBI_CODEX_FULL_ACCESS_POLICY`; `user-choice` exposes the option, which the user still arms per session) |
|`NBI_REFRESH_OPEN_FILES_ON_DISK_CHANGE_POLICY`| "Refresh open files when changed on disk" |
217
219
218
220
The first three also have matching traitlets on `NotebookIntelligence` (`explain_error_policy`, `output_followup_policy`, `output_toolbar_policy`); add the others as needed in the same shape:
0 commit comments