diff --git a/crates/goose/src/providers/codex_acp.rs b/crates/goose/src/providers/codex_acp.rs index 93502a71c..c280f4112 100644 --- a/crates/goose/src/providers/codex_acp.rs +++ b/crates/goose/src/providers/codex_acp.rs @@ -13,7 +13,7 @@ use crate::providers::base::{ }; pub(crate) const CODEX_ACP_PROVIDER_NAME: &str = "codex-acp"; -const CODEX_ACP_DOC_URL: &str = "https://github.com/zed-industries/codex-acp"; +const CODEX_ACP_DOC_URL: &str = "https://github.com/agentclientprotocol/codex-acp"; pub struct CodexAcpProvider; @@ -22,17 +22,19 @@ impl goose_providers::base::ProviderDescriptor for CodexAcpProvider { ProviderMetadata::new( CODEX_ACP_PROVIDER_NAME, "Codex CLI", - "Use goose with your ChatGPT Plus/Pro subscription via the codex-acp adapter.", + "Use goose with ChatGPT Plus/Pro or OpenAI API credits via the codex-acp adapter.", ACP_CURRENT_MODEL, vec![], CODEX_ACP_DOC_URL, vec![], ) .with_setup_steps(vec![ - "Install the ACP adapter: `npm install -g @zed-industries/codex-acp`", - "Run `codex` once to authenticate with your OpenAI account", - "Add to your goose config file (`~/.config/goose/config.yaml` on macOS/Linux):\n GOOSE_PROVIDER: codex-acp\n GOOSE_MODEL: current\n codex-acp_configured: true", - "Restart goose for changes to take effect", + "Verify `codex-acp --version` shows `@agentclientprotocol/codex-acp`", + "If `--version` is rejected, remove `@zed-industries/codex-acp`: `npm uninstall -g @zed-industries/codex-acp`", + "If `codex-acp` is missing or was removed, install `@agentclientprotocol/codex-acp`: `npm install -g @agentclientprotocol/codex-acp`", + "Authenticate with OpenAI: run `codex` and follow the prompts", + "Configure goose in `~/.config/goose/config.yaml`:\n GOOSE_PROVIDER: codex-acp\n GOOSE_MODEL: current", + "Restart goose", ]) } } @@ -58,54 +60,26 @@ impl ProviderDef for CodexAcpProvider { let resolved_command = SearchPaths::builder() .with_npm() .resolve(CODEX_ACP_PROVIDER_NAME)?; - let env = vec![]; let goose_mode = config.get_goose_mode().unwrap_or(GooseMode::Auto); let mcp_servers = extension_configs_to_mcp_servers(&extensions); - // fixed goose mode via -c overrides until session/set-mode works - let (approval_policy, sandbox_mode) = map_goose_mode(goose_mode); - let mut args = vec![ - "-c".to_string(), - format!("approval_policy={approval_policy}"), - "-c".to_string(), - format!("sandbox_mode={sandbox_mode}"), - ]; - - // Codex sandbox blocks network by default. Enable it when HTTP MCP - // servers are configured so codex-acp can connect to them. - let has_http_mcp = mcp_servers - .iter() - .any(|s| matches!(s, agent_client_protocol::schema::v1::McpServer::Http(_))); - if has_http_mcp { - args.extend([ - "-c".to_string(), - "sandbox_workspace_write.network_access=true".to_string(), - ]); - } - let mode_mapping = HashMap::from([ - ( - GooseMode::Auto, - vec!["full-access".to_string(), "agent-full-access".to_string()], - ), - ( - GooseMode::SmartApprove, - vec!["auto".to_string(), "agent".to_string()], - ), + (GooseMode::Auto, vec!["agent-full-access".to_string()]), + (GooseMode::SmartApprove, vec!["agent".to_string()]), (GooseMode::Approve, vec!["read-only".to_string()]), (GooseMode::Chat, vec!["read-only".to_string()]), ]); let provider_config = AcpProviderConfig { command: resolved_command, - args, - env, + args: vec![], + env: vec![], env_remove: vec![], work_dir: working_dir, mcp_servers, session_mode_id: None, session_config_options: vec![], - model_config_option_id: None, + model_config_option_id: Some("model".to_string()), mode_mapping, notification_callback: None, }; @@ -115,31 +89,3 @@ impl ProviderDef for CodexAcpProvider { }) } } - -// Codex sandbox scope determines what needs approval: operations within the -// sandbox are auto-approved, operations outside it trigger on-request prompts. -// So Approve uses read-only sandbox to force write approvals through goose. -fn map_goose_mode(goose_mode: GooseMode) -> (&'static str, &'static str) { - match goose_mode { - GooseMode::Auto => ("never", "danger-full-access"), - GooseMode::SmartApprove => ("on-request", "workspace-write"), - GooseMode::Approve => ("on-request", "read-only"), - GooseMode::Chat => ("never", "read-only"), - } -} - -#[cfg(test)] -mod tests { - use super::*; - use test_case::test_case; - - #[test_case(GooseMode::Auto, "never", "danger-full-access")] - #[test_case(GooseMode::SmartApprove, "on-request", "workspace-write")] - #[test_case(GooseMode::Approve, "on-request", "read-only")] - #[test_case(GooseMode::Chat, "never", "read-only")] - fn test_map_goose_mode(mode: GooseMode, expected_approval: &str, expected_sandbox: &str) { - let (approval, sandbox) = map_goose_mode(mode); - assert_eq!(approval, expected_approval); - assert_eq!(sandbox, expected_sandbox); - } -} diff --git a/crates/goose/tests/providers.rs b/crates/goose/tests/providers.rs index 5ef6518a4..36e080f35 100644 --- a/crates/goose/tests/providers.rs +++ b/crates/goose/tests/providers.rs @@ -506,10 +506,11 @@ impl ProviderFixture { assert!(!models.is_empty()); let resolved = &self.model_config.model_name; - assert_ne!(resolved.as_str(), ACP_CURRENT_MODEL); - assert!(models - .iter() - .any(|m| m == resolved || m.contains(resolved) || resolved.contains(m))); + if resolved != ACP_CURRENT_MODEL { + assert!(models + .iter() + .any(|m| m == resolved || m.contains(resolved) || resolved.contains(m))); + } if let Some(alt) = &self.model_switch_name { assert!(models .iter() @@ -898,7 +899,7 @@ async fn test_claude_acp_provider() -> Result<()> { .await } -// Requires: npm install -g @zed-industries/codex-acp +// Requires: npm install -g @agentclientprotocol/codex-acp #[tokio::test] async fn test_codex_acp_provider() -> Result<()> { ProviderTestConfig::with_agentic_provider("codex-acp", ACP_CURRENT_MODEL, "codex-acp") diff --git a/documentation/docs/getting-started/providers.md b/documentation/docs/getting-started/providers.md index ed50231db..75af7375e 100644 --- a/documentation/docs/getting-started/providers.md +++ b/documentation/docs/getting-started/providers.md @@ -81,7 +81,7 @@ goose supports [Agent Client Protocol (ACP)](https://agentclientprotocol.com/) a | Provider | Description | Requirements | |-----------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | [Claude ACP](https://github.com/agentclientprotocol/claude-agent-acp) (`claude-acp`) | Uses Claude Code via ACP. Passes goose extensions to the agent as MCP servers. | `npm install -g @agentclientprotocol/claude-agent-acp`, active Claude Code subscription | -| [Codex ACP](https://github.com/zed-industries/codex-acp) (`codex-acp`) | Uses OpenAI Codex via ACP. Passes goose extensions to the agent as MCP servers. | `npm install -g @zed-industries/codex-acp`, active ChatGPT Plus/Pro subscription | +| [Codex ACP](https://github.com/agentclientprotocol/codex-acp) (`codex-acp`) | Uses OpenAI Codex via ACP. Passes goose extensions to the agent as MCP servers. | `npm install -g @agentclientprotocol/codex-acp`, active ChatGPT Plus/Pro subscription or OpenAI API credits | :::tip ACP Providers See the [ACP Providers guide](/docs/guides/acp-providers) for detailed setup instructions. diff --git a/documentation/docs/guides/acp-providers.md b/documentation/docs/guides/acp-providers.md index cdedcddc3..61d3d81d6 100644 --- a/documentation/docs/guides/acp-providers.md +++ b/documentation/docs/guides/acp-providers.md @@ -43,7 +43,7 @@ Wraps [claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp ### Codex ACP -Wraps [codex-acp](https://github.com/zed-industries/codex-acp), an ACP adapter for OpenAI's Codex. Uses the same ChatGPT subscription as the deprecated `codex` CLI provider. Codex's sandbox blocks network by default; goose automatically enables network access when HTTP MCP servers are configured. +Use goose with ChatGPT Plus/Pro or OpenAI API credits via the [codex-acp](https://github.com/agentclientprotocol/codex-acp) adapter. **Requirements:** - Node.js and npm @@ -126,21 +126,38 @@ Wraps `pi-acp`, an ACP adapter for Pi. Uses your existing Pi installation. ### Codex ACP -1. **Install the ACP adapter** +1. **Check the installed package** ```bash - npm install -g @zed-industries/codex-acp + codex-acp --version ``` -2. **Authenticate with OpenAI** + The output should start with `@agentclientprotocol/codex-acp`. If it does, continue to authentication. - Run `codex` and follow the authentication prompts. You can use your ChatGPT account or API key. +2. **Install or replace only if needed** -3. **Configure goose** + If `--version` is rejected, remove `@zed-industries/codex-acp`: - Set the provider environment variable: + ```bash + npm uninstall -g @zed-industries/codex-acp + ``` + + If `codex-acp` is missing or was removed, install `@agentclientprotocol/codex-acp`: + + ```bash + npm install -g @agentclientprotocol/codex-acp + ``` + +3. **Authenticate with OpenAI** + + Run `codex` and follow the authentication prompts. A compatible existing Codex login can be reused. + +4. **Configure goose** + + Set the provider and use `current` to let Codex choose its default model: ```bash export GOOSE_PROVIDER=codex-acp + export GOOSE_MODEL=current ``` Or configure through the goose CLI using `goose configure`: @@ -157,9 +174,11 @@ Wraps `pi-acp`, an ACP adapter for Pi. Uses your existing Pi installation. ◇ Model fetch complete │ ◇ Enter a model from that provider: - │ gpt-5.2-codex + │ current ``` +Replacing the npm package does not change `~/.codex` or require recreating your goose configuration. goose does not replace the package automatically. + ### Pi ACP 1. **Install the Pi CLI and ACP adapter** @@ -239,28 +258,24 @@ See [claude-agent-acp](https://github.com/agentclientprotocol/claude-agent-acp) ### Codex ACP Configuration -| Environment Variable | Description | Default | -|----------------------|--------------------|-----------------| -| `GOOSE_PROVIDER` | Set to `codex-acp` | None | -| `GOOSE_MODEL` | Model to use | `gpt-5.2-codex` | -| `GOOSE_MODE` | Permission mode | `auto` | +| Environment Variable | Description | Default | +|----------------------|--------------------|-----------| +| `GOOSE_PROVIDER` | Set to `codex-acp` | None | +| `GOOSE_MODEL` | Model to use | `current` | +| `GOOSE_MODE` | Permission mode | `auto` | -**Known Models:** -- `gpt-5.2-codex` -- `gpt-5.2` -- `gpt-5.1-codex-max` -- `gpt-5.1-codex-mini` +Codex ACP reports its available models dynamically. Keep `current` to use Codex's default, or select a discovered model explicitly. **Permission Modes (`GOOSE_MODE`):** -| Mode | Approval / Sandbox | Behavior | -|-----------------|-----------------------------|----------------------------------------------------------------| -| `auto` | No approvals, full access | Bypasses all approvals and sandbox restrictions | -| `smart-approve` | On-request, workspace-write | Workspace write access, prompts for operations outside sandbox | -| `approve` | On-request, read-only | Read-only sandbox, prompts for all write operations | -| `chat` | No approvals, read-only | Read-only sandbox, no tool execution | +| goose mode | Codex ACP mode | +|-----------------|---------------------| +| `auto` | `agent-full-access` | +| `smart-approve` | `agent` | +| `approve` | `read-only` | +| `chat` | `read-only` | -See [codex-acp](https://github.com/zed-industries/codex-acp) for approval policy and sandbox details. +See [codex-acp](https://github.com/agentclientprotocol/codex-acp) for session mode details. ### Pi ACP Configuration