Closes #878 ## What Major refactor of the `coder-labs/codex` module to mirror the `coder/claude-code` v5 changes from #861. ## Changes ### Structural - Replace `module "agentapi"` with `module "coder_utils"` (`registry.coder.com/coder/coder-utils/coder v0.0.1`) - Replace `scripts/install.sh` with `scripts/install.sh.tftpl` (Terraform templatefile) - Delete `scripts/start.sh` - Module dir changed from `.codex-module` to `.coder-modules/coder-labs/codex` - Output changed from `task_app_id` to `scripts` (ordered list of coder exp sync names) - Extracted shared test helpers (`collectScripts`, `runScripts`) into `agentapi/coder-utils-test-helpers.ts` ### Removed variables All AgentAPI pass-throughs, boundary, and start-script-only variables: `order`, `group`, `report_tasks`, `subdomain`, `cli_app`, `web_app_display_name`, `cli_app_display_name`, `install_agentapi`, `agentapi_version`, `ai_prompt`, `continue`, `enable_state_persistence`, `codex_system_prompt`, `enable_boundary`, `boundary_config_path`, `boundary_version`, `compile_boundary_from_source`, `use_boundary_directly`, `codex_model` ### Retained `install_codex` (toggle for skipping npm install when CLI is pre-installed) ### Renamed - `enable_aibridge` -> `enable_ai_gateway` ### Changed - `workdir`: now optional (`default = null`) - `openai_api_key`: conditional env var with `count`, marked `sensitive = true` - `base_config_toml`: heredoc description documenting generated defaults; notes that `model_reasoning_effort` and workdir trust are only applied in default config - Default `config.toml`: stripped `sandbox_mode`, `approval_policy`, `sandbox_workspace_write`, `notice.model_migrations` - Install script: removed Node.js/NVM bootstrap (assumes npm pre-installed), sources NVM if present, fails with actionable error if npm missing - `ARG_CODEX_VERSION` and `ARG_WORKDIR` base64-encoded to prevent shell/TOML injection - Duplicate `[model_providers.aibridge]` guarded with grep before appending - Debug header uses user-facing variable names ### Tests - Terraform: 11 pass - Bun: 15 pass (rewritten to shared `collectScripts`/`runScripts` pattern) - Added: `model-reasoning-effort-standalone`, `ai-gateway-with-custom-base-config`, `ai-gateway-custom-config-no-duplicate-provider`, `install-codex-latest`, `workdir-trusted-project`, `no-workdir-no-project-section` - Negative assertions on `minimal-default-config` ### Docs - Migration guide (v4 to v5) in README - Quoted path in coder_app example - AI Gateway note about custom `base_config_toml` requiring manual `model_provider` > [!WARNING] > Breaking change. Drops support for Coder Tasks and Boundary. Keep using v4.x.x if you depend on them. --- *This PR was authored by Coder Agents.* --------- Co-authored-by: Jay Kumar <jay.kumar@coder.com> Co-authored-by: DevCats <christofer@coder.com>
186 lines
4.3 KiB
HCL
186 lines
4.3 KiB
HCL
run "test_codex_basic" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
}
|
|
|
|
assert {
|
|
condition = var.install_codex == true
|
|
error_message = "install_codex should default to true"
|
|
}
|
|
}
|
|
|
|
run "test_codex_with_api_key" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
openai_api_key = "test-key"
|
|
}
|
|
|
|
assert {
|
|
condition = coder_env.openai_api_key[0].value == "test-key"
|
|
error_message = "OpenAI API key should be set correctly"
|
|
}
|
|
}
|
|
|
|
run "test_codex_custom_options" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder/project"
|
|
icon = "/icon/custom.svg"
|
|
codex_version = "0.128.0"
|
|
}
|
|
|
|
assert {
|
|
condition = length(output.scripts) > 0
|
|
error_message = "scripts output should be non-empty with custom options"
|
|
}
|
|
}
|
|
|
|
run "test_ai_gateway_enabled" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
enable_ai_gateway = true
|
|
}
|
|
|
|
override_data {
|
|
target = data.coder_workspace_owner.me
|
|
values = {
|
|
session_token = "mock-session-token"
|
|
}
|
|
}
|
|
|
|
assert {
|
|
condition = coder_env.ai_gateway_session_token[0].name == "CODER_AIBRIDGE_SESSION_TOKEN"
|
|
error_message = "CODER_AIBRIDGE_SESSION_TOKEN should be set"
|
|
}
|
|
|
|
assert {
|
|
condition = coder_env.ai_gateway_session_token[0].value == data.coder_workspace_owner.me.session_token
|
|
error_message = "Session token should use workspace owner's token"
|
|
}
|
|
|
|
assert {
|
|
condition = length(coder_env.openai_api_key) == 0
|
|
error_message = "OPENAI_API_KEY should not be created when ai_gateway is enabled"
|
|
}
|
|
}
|
|
|
|
run "test_ai_gateway_validation_with_api_key" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
enable_ai_gateway = true
|
|
openai_api_key = "test-key"
|
|
}
|
|
|
|
expect_failures = [
|
|
var.enable_ai_gateway,
|
|
]
|
|
}
|
|
|
|
run "test_ai_gateway_disabled_with_api_key" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
enable_ai_gateway = false
|
|
openai_api_key = "test-key-xyz"
|
|
}
|
|
|
|
assert {
|
|
condition = coder_env.openai_api_key[0].value == "test-key-xyz"
|
|
error_message = "OPENAI_API_KEY should use the provided API key"
|
|
}
|
|
|
|
assert {
|
|
condition = length(coder_env.ai_gateway_session_token) == 0
|
|
error_message = "Session token should not be set when ai_gateway is disabled"
|
|
}
|
|
}
|
|
|
|
run "test_no_api_key_no_env" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
}
|
|
|
|
assert {
|
|
condition = length(coder_env.openai_api_key) == 0
|
|
error_message = "OPENAI_API_KEY should not be created when no API key is provided"
|
|
}
|
|
}
|
|
|
|
run "test_codex_with_scripts" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
pre_install_script = "echo 'Pre-install script'"
|
|
post_install_script = "echo 'Post-install script'"
|
|
}
|
|
|
|
assert {
|
|
condition = length(output.scripts) == 3
|
|
error_message = "scripts output should have 3 entries when pre/post are configured"
|
|
}
|
|
}
|
|
|
|
run "test_script_outputs_install_only" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
}
|
|
|
|
assert {
|
|
condition = length(output.scripts) == 1 && output.scripts[0] == "coder-labs-codex-install_script"
|
|
error_message = "scripts output should list only the install script when pre/post are not configured"
|
|
}
|
|
}
|
|
|
|
run "test_script_outputs_with_pre_and_post" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
workdir = "/home/coder"
|
|
pre_install_script = "echo pre"
|
|
post_install_script = "echo post"
|
|
}
|
|
|
|
assert {
|
|
condition = output.scripts == ["coder-labs-codex-pre_install_script", "coder-labs-codex-install_script", "coder-labs-codex-post_install_script"]
|
|
error_message = "scripts output should list pre_install, install, post_install in run order"
|
|
}
|
|
}
|
|
|
|
run "test_workdir_optional" {
|
|
command = plan
|
|
|
|
variables {
|
|
agent_id = "test-agent"
|
|
}
|
|
|
|
assert {
|
|
condition = length(output.scripts) == 1
|
|
error_message = "scripts output should have install script even without workdir"
|
|
}
|
|
}
|