From e18caa5a468aea346d471b2b6ed5b244a43042ed Mon Sep 17 00:00:00 2001 From: Atif Ali Date: Wed, 4 Feb 2026 07:12:00 +0000 Subject: [PATCH] feat(codex): optimize for standalone usage with optional workdir and default AI Bridge profile - Add 'enable_tasks' variable (defaults to true) for better discoverability - Make 'workdir' optional when enable_tasks=false for standalone CLI usage - Keep 'install_agentapi' as deprecated alias for backward compatibility - Prepend 'profile = "aibridge"' to config.toml when AI Bridge is enabled so users can run 'codex' directly without --profile flag - Update README with standalone usage examples and version 4.2.0 - Add tests for aibridge profile at config top and standalone mode --- registry/coder-labs/modules/codex/README.md | 34 +++++++++++++++---- .../coder-labs/modules/codex/main.test.ts | 23 +++++++++++++ registry/coder-labs/modules/codex/main.tf | 24 ++++++++++--- .../modules/codex/scripts/install.sh | 9 +++++ 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/registry/coder-labs/modules/codex/README.md b/registry/coder-labs/modules/codex/README.md index 1ca7c9c5..7181f41e 100644 --- a/registry/coder-labs/modules/codex/README.md +++ b/registry/coder-labs/modules/codex/README.md @@ -13,7 +13,7 @@ Run Codex CLI in your workspace to access OpenAI's models through the Codex inte ```tf module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.1.0" + version = "4.2.0" agent_id = coder_agent.example.id openai_api_key = var.openai_api_key workdir = "/home/coder/project" @@ -32,7 +32,7 @@ module "codex" { module "codex" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder-labs/codex/coder" - version = "4.1.0" + version = "4.2.0" agent_id = coder_agent.example.id openai_api_key = "..." workdir = "/home/coder/project" @@ -48,10 +48,27 @@ For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage #### Standalone usage with AI Bridge +For simple Codex CLI usage without Tasks UI, set `enable_tasks = false`. This is ideal when you just want Codex installed with AI Bridge configuration for manual use. + ```tf module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.1.0" + version = "4.2.0" + agent_id = coder_agent.example.id + enable_aibridge = true + enable_tasks = false # Standalone mode - just CLI, no Tasks UI + # workdir not required in standalone mode! +} +``` + +Users can then run `codex` from any directory and it will automatically use the AI Bridge profile. + +#### Tasks usage with AI Bridge + +```tf +module "codex" { + source = "registry.coder.com/coder-labs/codex/coder" + version = "4.2.0" agent_id = coder_agent.example.id workdir = "/home/coder/project" enable_aibridge = true @@ -61,8 +78,11 @@ module "codex" { When `enable_aibridge = true`, the module: - Configures Codex to use the AI Bridge profile with `base_url` pointing to `${data.coder_workspace.me.access_url}/api/v2/aibridge/openai/v1` and `env_key` pointing to the workspace owner's session token +- Sets `profile = "aibridge"` at the top of `config.toml` so Codex uses AI Bridge by default ```toml +profile = "aibridge" + [model_providers.aibridge] name = "AI Bridge" base_url = "https://example.coder.com/api/v2/aibridge/openai/v1" @@ -75,7 +95,7 @@ model = "" # as configured in the module input model_reasoning_effort = "" # as configured in the module input ``` -Codex then runs with `--profile aibridge` +When running `codex` manually (without the Tasks UI), it automatically uses the AI Bridge profile. This allows Codex to route API requests through Coder's AI Bridge instead of directly to OpenAI's API. Template build will fail if `openai_api_key` is provided alongside `enable_aibridge = true`. @@ -94,7 +114,7 @@ data "coder_task" "me" {} module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.1.0" + version = "4.2.0" agent_id = coder_agent.example.id openai_api_key = "..." ai_prompt = data.coder_task.me.prompt @@ -112,7 +132,7 @@ This example shows additional configuration options for custom models, MCP serve ```tf module "codex" { source = "registry.coder.com/coder-labs/codex/coder" - version = "4.1.0" + version = "4.2.0" agent_id = coder_agent.example.id openai_api_key = "..." workdir = "/home/coder/project" @@ -174,7 +194,7 @@ network_access = true > [!IMPORTANT] > To use tasks with Codex CLI, ensure you have the `openai_api_key` variable set. [Tasks Template Example](https://registry.coder.com/templates/coder-labs/tasks-docker). > The module automatically configures Codex with your API key and model preferences. -> workdir is a required variable for the module to function correctly. +> `workdir` is required when `enable_tasks = true` (default). For standalone CLI usage, set `enable_tasks = false` and `workdir` becomes optional. ## References diff --git a/registry/coder-labs/modules/codex/main.test.ts b/registry/coder-labs/modules/codex/main.test.ts index a4edd818..1e9ed218 100644 --- a/registry/coder-labs/modules/codex/main.test.ts +++ b/registry/coder-labs/modules/codex/main.test.ts @@ -481,5 +481,28 @@ describe("codex", async () => { expect(configToml).toContain( "[profiles.aibridge]\n" + 'model_provider = "aibridge"', ); + // Verify profile = "aibridge" is set at the top of the config + expect(configToml.startsWith('profile = "aibridge"')).toBe(true); + }); + + test("codex-standalone-mode", async () => { + // Test standalone mode without tasks (enable_tasks = false) + // workdir should default to /home/coder when not explicitly provided + const { id } = await setup({ + moduleVariables: { + enable_tasks: "false", + enable_aibridge: "true", + }, + }); + + await execModuleScript(id); + + const configToml = await readFileContainer( + id, + "/home/coder/.codex/config.toml", + ); + // In standalone mode, config should still have aibridge profile set as default + expect(configToml.startsWith('profile = "aibridge"')).toBe(true); + expect(configToml).toContain("[profiles.aibridge]"); }); }); diff --git a/registry/coder-labs/modules/codex/main.tf b/registry/coder-labs/modules/codex/main.tf index 2f65df86..9c540bf4 100644 --- a/registry/coder-labs/modules/codex/main.tf +++ b/registry/coder-labs/modules/codex/main.tf @@ -38,7 +38,19 @@ variable "icon" { variable "workdir" { type = string - description = "The folder to run Codex in." + description = "The folder to run Codex in. Required when enable_tasks is true." + default = null + + validation { + condition = var.workdir != null || !local.tasks_enabled + error_message = "workdir is required when enable_tasks is true. Set workdir or set enable_tasks = false for standalone CLI usage." + } +} + +variable "enable_tasks" { + type = bool + description = "Enable Tasks UI for Codex (requires workdir). When false, only installs Codex CLI with config for standalone usage." + default = true } variable "report_tasks" { @@ -124,8 +136,8 @@ variable "openai_api_key" { variable "install_agentapi" { type = bool - description = "Whether to install AgentAPI." - default = true + description = "DEPRECATED: Use enable_tasks instead. Whether to install AgentAPI." + default = null } variable "agentapi_version" { @@ -184,7 +196,9 @@ resource "coder_env" "coder_aibridge_session_token" { } locals { - workdir = trimsuffix(var.workdir, "/") + # Use enable_tasks, but fall back to install_agentapi if explicitly set (for backward compat) + tasks_enabled = var.install_agentapi != null ? var.install_agentapi : var.enable_tasks + workdir = var.workdir != null ? trimsuffix(var.workdir, "/") : "/home/coder" app_slug = "codex" install_script = file("${path.module}/scripts/install.sh") start_script = file("${path.module}/scripts/start.sh") @@ -218,7 +232,7 @@ module "agentapi" { cli_app_slug = var.cli_app ? "${local.app_slug}-cli" : null cli_app_display_name = var.cli_app ? var.cli_app_display_name : null module_dir_name = local.module_dir_name - install_agentapi = var.install_agentapi + install_agentapi = local.tasks_enabled agentapi_subdomain = var.subdomain agentapi_version = var.agentapi_version pre_install_script = var.pre_install_script diff --git a/registry/coder-labs/modules/codex/scripts/install.sh b/registry/coder-labs/modules/codex/scripts/install.sh index 97d539a8..c8e88c6f 100644 --- a/registry/coder-labs/modules/codex/scripts/install.sh +++ b/registry/coder-labs/modules/codex/scripts/install.sh @@ -151,6 +151,15 @@ function populate_config_toml() { write_minimal_default_config "$CONFIG_PATH" fi + # Set aibridge as default profile when AI Bridge is enabled + # This allows users to run `codex` without --profile flag + if [ "$ARG_ENABLE_AIBRIDGE" = "true" ]; then + printf "Setting aibridge as default profile\n" + local temp_config + temp_config=$(cat "$CONFIG_PATH") + echo -e "profile = \"aibridge\"\n\n$temp_config" > "$CONFIG_PATH" + fi + append_mcp_servers_section "$CONFIG_PATH" if [ "$ARG_ENABLE_AIBRIDGE" = "true" ]; then