- 
                Notifications
    You must be signed in to change notification settings 
- Fork 76
feat: support codex cli #281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
  
     Merged
                    Changes from 6 commits
      Commits
    
    
            Show all changes
          
          
            53 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      5bbca30
              
                feat: add codex module
              
              
                35C4n0r be3bc0a
              
                feat: bun fmt
              
              
                35C4n0r 5ac3d7a
              
                fix: fix typo
              
              
                35C4n0r 37f85c6
              
                feat: add codex svg
              
              
                35C4n0r 13b776d
              
                feat: update readme
              
              
                35C4n0r 4e45ffd
              
                chore: update icon name
              
              
                35C4n0r 66bb40e
              
                chore: rename codex_api_key to openai_api_key
              
              
                35C4n0r b08aadf
              
                chore: rename codex_api_key to openai_api_key
              
              
                35C4n0r 93b16cb
              
                chore: update README.md
              
              
                35C4n0r 92e6bb5
              
                chore: bump agentapi_version to v0.3.2
              
              
                35C4n0r 77393b4
              
                fix: update README.md
              
              
                35C4n0r b33bbda
              
                wip: apply suggestions
              
              
                35C4n0r dc154d0
              
                fix: apply suggestions
              
              
                35C4n0r ee138e1
              
                Update registry/coder-labs/modules/codex/scripts/start.sh
              
              
                35C4n0r d32f5d9
              
                Update registry/coder-labs/modules/codex/main.tf
              
              
                35C4n0r d08a225
              
                Update registry/coder-labs/modules/codex/scripts/start.sh
              
              
                35C4n0r a4481f7
              
                Update registry/coder-labs/modules/codex/scripts/start.sh
              
              
                35C4n0r 2b7d213
              
                Update registry/coder-labs/modules/codex/scripts/start.sh
              
              
                35C4n0r 79a3f8e
              
                Update registry/coder-labs/modules/codex/scripts/install.sh
              
              
                35C4n0r 1a28cd2
              
                Update registry/coder-labs/modules/codex/main.tf
              
              
                35C4n0r 49eafc5
              
                Update registry/coder-labs/modules/codex/main.tf
              
              
                35C4n0r 723cdc4
              
                Update registry/coder-labs/modules/codex/README.md
              
              
                35C4n0r d4d9b73
              
                Update registry/coder-labs/modules/codex/main.tf
              
              
                35C4n0r d0846b7
              
                Update registry/coder-labs/modules/codex/README.md
              
              
                35C4n0r aa8a562
              
                Merge branch 'main' into feat-codex-cli
              
              
                35C4n0r 0c6e9f9
              
                Update registry/coder-labs/modules/codex/README.md
              
              
                35C4n0r b73f6dd
              
                fix: apply suggestions
              
              
                35C4n0r 340ecee
              
                Update registry/coder-labs/modules/codex/README.md
              
              
                35C4n0r 1c85858
              
                fix: README.md
              
              
                35C4n0r 3624b91
              
                fix: add test for latest version
              
              
                35C4n0r ace0930
              
                fix: add support for codex 0.20.0
              
              
                35C4n0r 58d675e
              
                fix: fix tests
              
              
                35C4n0r 55b7741
              
                Update registry/coder-labs/modules/codex/main.tf
              
              
                35C4n0r ff54181
              
                Update registry/coder-labs/modules/codex/main.tf
              
              
                35C4n0r bb460fe
              
                chore: update README.md
              
              
                35C4n0r 0f23e73
              
                Merge branch 'main' into feat-codex-cli
              
              
                35C4n0r 75472e4
              
                Merge branch 'main' into feat-codex-cli
              
              
                35C4n0r 922063f
              
                Merge branch 'main' into feat-codex-cli
              
              
                35C4n0r 82ff539
              
                feat: better prompt
              
              
                35C4n0r b567f6d
              
                Merge branch 'main' into feat-codex-cli
              
              
                DevelopmentCats ce60db3
              
                feat: source bash in install script
              
              
                35C4n0r 202be74
              
                Merge branch 'main' into feat-codex-cli
              
              
                DevelopmentCats 911110b
              
                Merge branch 'main' into feat-codex-cli
              
              
                DevelopmentCats bddde29
              
                feat: add full_auto variable and argument
              
              
                DevelopmentCats 7342d95
              
                chore: bun run fmt
              
              
                DevelopmentCats 75afc2a
              
                fix: remove accidental base64 encoding of full_auto arg
              
              
                DevelopmentCats f5a1bdd
              
                fix: update default icon for app in codex module
              
              
                DevelopmentCats 2b47e77
              
                fix: enhance README and install script for Codex module sandbox confi…
              
              
                DevelopmentCats 5e9f0dd
              
                feat: add sandbox_mode, approval_policy, and network_access variables…
              
              
                DevelopmentCats cac6483
              
                docs: update README for Codex module configuration details
              
              
                DevelopmentCats 57e7fcd
              
                chore: update default AgentAPI version to latest in Codex module
              
              
                DevelopmentCats 0a0657c
              
                chore: bun run fmt
              
              
                DevelopmentCats 28edf08
              
                feat: pin agentapi version
              
              
                35C4n0r File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
      
      Loading
      
  Sorry, something went wrong. Reload?
      Sorry, we cannot display this file.
      Sorry, this file is invalid so it cannot be displayed.
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| --- | ||
| display_name: Codex CLI | ||
| icon: ../../../../.icons/openai.svg | ||
| description: Run Codex CLI in your workspace with AgentAPI integration | ||
| verified: true | ||
| tags: [agent, codex, ai, openai, tasks] | ||
| --- | ||
|  | ||
| # Codex CLI | ||
|  | ||
| Run Codex CLI in your workspace to access OpenAI's models through the Codex interface, with custom pre/post install scripts. This module integrates with [AgentAPI](https://github.com/coder/agentapi) for Coder Tasks compatibility. | ||
|  | ||
| ```tf | ||
| module "codex" { | ||
| source = "registry.coder.com/coder-labs/codex/coder" | ||
| version = "1.0.0" | ||
| agent_id = coder_agent.example.id | ||
| codex_api_key = var.codex_api_key | ||
| agentapi_version = "v0.3.0" | ||
| } | ||
| ``` | ||
|  | ||
|         
                  35C4n0r marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| ## Prerequisites | ||
|  | ||
| - You must add the [Coder Login](https://registry.coder.com/modules/coder-login/coder) module to your template | ||
|         
                  DevelopmentCats marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| - OpenAI API key for Codex access | ||
|  | ||
| ## Usage Example | ||
|  | ||
| - Simple usage Example: | ||
|  | ||
| ```tf | ||
| module "codex" { | ||
| count = data.coder_workspace.me.start_count | ||
| source = "registry.coder.com/coder-labs/codex/coder" | ||
| version = "1.0.0" | ||
| agent_id = coder_agent.example.id | ||
| codex_api_key = "..." | ||
| codex_model = "o4-mini" | ||
|         
                  DevelopmentCats marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| install_codex = true | ||
| codex_version = "latest" | ||
| folder = "/home/coder/project" | ||
| codex_system_prompt = "You are a helpful coding assistant. Start every response with `Codex says:`" | ||
| agentapi_version = "v0.3.0" | ||
| } | ||
| ``` | ||
|  | ||
| - Example usage with Tasks: | ||
|  | ||
| ```tf | ||
| # This | ||
| data "coder_parameter" "ai_prompt" { | ||
| type = "string" | ||
| name = "AI Prompt" | ||
| default = "" | ||
| description = "Initial prompt for the Codex CLI" | ||
| mutable = true | ||
| } | ||
|  | ||
| module "coder-login" { | ||
| count = data.coder_workspace.me.start_count | ||
| source = "registry.coder.com/coder/coder-login/coder" | ||
| version = "1.0.31" | ||
| agent_id = coder_agent.example.id | ||
| } | ||
|  | ||
| module "codex" { | ||
| source = "/Users/jkmr/Documents/work/registry/registry/coder-labs/modules/codex" | ||
|         
                  35C4n0r marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| agent_id = coder_agent.example.id | ||
| codex_api_key = "..." | ||
| ai_prompt = data.coder_parameter.ai_prompt.value | ||
| agentapi_version = "v0.3.0" | ||
| } | ||
| ``` | ||
|  | ||
| ## How it Works | ||
|  | ||
| - **Install**: The module installs Codex CLI and sets up the environment | ||
| - **System Prompt**: If `codex_system_prompt` and `folder` are set, creates the directory (if needed) and writes the prompt to `AGENTS.md` | ||
| - **Start**: Launches Codex CLI in the specified directory, wrapped by AgentAPI | ||
| - **Environment**: Sets `OPENAI_API_KEY` and `CODEX_MODEL` for the CLI (if variables provided) | ||
|  | ||
| ## Troubleshooting | ||
|  | ||
| - Check logs in `/home/coder/.codex-module/` for install/start output | ||
|         
                  35C4n0r marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| - Ensure your OpenAI API key has access to the specified model | ||
|  | ||
| > [!IMPORTANT] | ||
| > To use tasks with Codex CLI, ensure you have the `codex_api_key` variable set, and **you create an `ai_prompt` `coder_parameter` and pass it's value to codex `ai_prompt` variable**. | ||
| > The module automatically configures Codex with your API key and model preferences. | ||
| > Tasks are run with `--dangerously-bypass-approvals-and-sandbox` | ||
|         
                  35C4n0r marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved         
                  35C4n0r marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
|  | ||
| ## References | ||
|  | ||
| - [OpenAI API Documentation](https://platform.openai.com/docs) | ||
| - [AgentAPI Documentation](https://github.com/coder/agentapi) | ||
| - [Coder AI Agents Guide](https://coder.com/docs/tutorials/ai-agents) | ||
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,210 @@ | ||
| import { | ||
| test, | ||
| afterEach, | ||
| describe, | ||
| setDefaultTimeout, | ||
| beforeAll, | ||
| expect, | ||
| } from "bun:test"; | ||
| import { execContainer, readFileContainer, runTerraformInit } from "~test"; | ||
| import { | ||
| loadTestFile, | ||
| writeExecutable, | ||
| setup as setupUtil, | ||
| execModuleScript, | ||
| expectAgentAPIStarted, | ||
| } from "../../../coder/modules/agentapi/test-util"; | ||
|         
                  35C4n0r marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
|  | ||
| let cleanupFunctions: (() => Promise<void>)[] = []; | ||
| const registerCleanup = (cleanup: () => Promise<void>) => { | ||
| cleanupFunctions.push(cleanup); | ||
| }; | ||
| afterEach(async () => { | ||
| const cleanupFnsCopy = cleanupFunctions.slice().reverse(); | ||
| cleanupFunctions = []; | ||
| for (const cleanup of cleanupFnsCopy) { | ||
| try { | ||
| await cleanup(); | ||
| } catch (error) { | ||
| console.error("Error during cleanup:", error); | ||
| } | ||
| } | ||
| }); | ||
|  | ||
| interface SetupProps { | ||
| skipAgentAPIMock?: boolean; | ||
| skipCodexMock?: boolean; | ||
| moduleVariables?: Record<string, string>; | ||
| agentapiMockScript?: string; | ||
| } | ||
|  | ||
| const setup = async (props?: SetupProps): Promise<{ id: string }> => { | ||
| const projectDir = "/home/coder/project"; | ||
| const { id } = await setupUtil({ | ||
| moduleDir: import.meta.dir, | ||
| moduleVariables: { | ||
| install_codex: props?.skipCodexMock ? "true" : "false", | ||
| install_agentapi: props?.skipAgentAPIMock ? "true" : "false", | ||
| codex_model: "gpt-4-turbo", | ||
| ...props?.moduleVariables, | ||
| }, | ||
| registerCleanup, | ||
| projectDir, | ||
| skipAgentAPIMock: props?.skipAgentAPIMock, | ||
| agentapiMockScript: props?.agentapiMockScript, | ||
| }); | ||
| if (!props?.skipCodexMock) { | ||
| await writeExecutable({ | ||
| containerId: id, | ||
| filePath: "/usr/bin/codex", | ||
| content: await loadTestFile(import.meta.dir, "codex-mock.sh"), | ||
| }); | ||
| } | ||
| return { id }; | ||
| }; | ||
|  | ||
| setDefaultTimeout(60 * 1000); | ||
|  | ||
| describe("codex", async () => { | ||
| beforeAll(async () => { | ||
| await runTerraformInit(import.meta.dir); | ||
| }); | ||
|  | ||
| test("happy-path", async () => { | ||
| const { id } = await setup(); | ||
| await execModuleScript(id); | ||
| await expectAgentAPIStarted(id); | ||
| }); | ||
|  | ||
| test("install-codex-version", async () => { | ||
| const version_to_install = "1.0.0"; | ||
| const { id } = await setup({ | ||
| skipCodexMock: true, | ||
| moduleVariables: { | ||
| install_codex: "true", | ||
| codex_version: version_to_install, | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
| const resp = await execContainer(id, [ | ||
| "bash", | ||
| "-c", | ||
| `cat /home/coder/.codex-module/install.log || true`, | ||
| ]); | ||
| expect(resp.stdout).toContain(version_to_install); | ||
| }); | ||
|  | ||
| test("codex-config-toml", async () => { | ||
| const settings = '[mcp_servers.CustomMCP]\n' + | ||
| 'command = "/Users/jkmr/Documents/work/coder/coder_darwin_arm64"\n' + | ||
| 'args = ["exp", "mcp", "server", "app-status-slug=codex"]\n' + | ||
| 'env = { "CODER_MCP_APP_STATUS_SLUG" = "codex", "CODER_MCP_AI_AGENTAPI_URL"= "http://localhost:3284" }\n' + | ||
| 'description = "Report ALL tasks and statuses (in progress, done, failed) you are working on."\n' + | ||
| 'enabled = true\n' + | ||
| 'type = "stdio"'; | ||
|         
                  35C4n0r marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| const { id } = await setup({ | ||
| moduleVariables: { | ||
| codex_settings_toml: settings, | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
| const resp = await readFileContainer(id, "/home/coder/.codex/config.toml"); | ||
| expect(resp).toContain("[mcp_servers.CustomMCP]"); | ||
| expect(resp).toContain("[mcp_servers.Coder]"); | ||
| }); | ||
|  | ||
| test("codex-api-key", async () => { | ||
| const apiKey = "test-api-key-123"; | ||
| const { id } = await setup({ | ||
| moduleVariables: { | ||
| codex_api_key: apiKey, | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
|  | ||
| const resp = await readFileContainer(id, "/home/coder/.codex-module/agentapi-start.log"); | ||
| expect(resp).toContain("codex_api_key provided !"); | ||
| }); | ||
|  | ||
| test("pre-post-install-scripts", async () => { | ||
| const { id } = await setup({ | ||
| moduleVariables: { | ||
| pre_install_script: "#!/bin/bash\necho 'pre-install-script'", | ||
| post_install_script: "#!/bin/bash\necho 'post-install-script'", | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
| const preInstallLog = await readFileContainer(id, "/home/coder/.codex-module/pre_install.log"); | ||
| expect(preInstallLog).toContain("pre-install-script"); | ||
| const postInstallLog = await readFileContainer(id, "/home/coder/.codex-module/post_install.log"); | ||
| expect(postInstallLog).toContain("post-install-script"); | ||
| }); | ||
|  | ||
| test("folder-variable", async () => { | ||
| const folder = "/tmp/codex-test-folder"; | ||
| const { id } = await setup({ | ||
| skipCodexMock: false, | ||
| moduleVariables: { | ||
| folder, | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
| const resp = await readFileContainer(id, "/home/coder/.codex-module/install.log"); | ||
| expect(resp).toContain(folder); | ||
| }); | ||
|  | ||
| test("additional-extensions", async () => { | ||
| const additional = '[mcp_servers.CustomMCP]\n' + | ||
|         
                  35C4n0r marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| 'command = "/Users/jkmr/Documents/work/coder/coder_darwin_arm64"\n' + | ||
| 'args = ["exp", "mcp", "server", "app-status-slug=codex"]\n' + | ||
| 'env = { "CODER_MCP_APP_STATUS_SLUG" = "codex", "CODER_MCP_AI_AGENTAPI_URL"= "http://localhost:3284" }\n' + | ||
| 'description = "Report ALL tasks and statuses (in progress, done, failed) you are working on."\n' + | ||
| 'enabled = true\n' + | ||
| 'type = "stdio"'; | ||
| const { id } = await setup({ | ||
| moduleVariables: { | ||
| additional_extensions: additional, | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
| const resp = await readFileContainer(id, "/home/coder/.codex/config.toml"); | ||
| expect(resp).toContain("[mcp_servers.CustomMCP]"); | ||
| expect(resp).toContain("[mcp_servers.Coder]"); | ||
| }); | ||
|  | ||
| test("codex-system-prompt", async () => { | ||
|         
                  35C4n0r marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
| const prompt = "This is a system prompt for Codex."; | ||
| const { id } = await setup({ | ||
| moduleVariables: { | ||
| codex_system_prompt: prompt, | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
| const resp = await readFileContainer(id, "/home/coder/AGENTS.md"); | ||
| expect(resp).toContain(prompt); | ||
| }); | ||
|  | ||
| test("codex-ai-task-prompt", async () => { | ||
| const prompt = "This is a system prompt for Codex."; | ||
| const { id } = await setup({ | ||
| moduleVariables: { | ||
| ai_prompt: prompt, | ||
| }, | ||
| }); | ||
| await execModuleScript(id); | ||
| const resp = await execContainer(id, [ | ||
| "bash", | ||
| "-c", | ||
| `cat /home/coder/.codex-module/agentapi-start.log || true`, | ||
|         
                  35C4n0r marked this conversation as resolved.
              Outdated
          
            Show resolved
            Hide resolved | ||
| ]); | ||
| expect(resp.stdout).toContain(`Every step of the way, report tasks to Coder with proper descriptions and statuses, when each part of the task is finished report with . Your task at hand: ${prompt}`); | ||
| }); | ||
|  | ||
| test("start-without-prompt", async () => { | ||
| const { id } = await setup(); | ||
| await execModuleScript(id); | ||
| const prompt = await execContainer(id, ["ls", "-l", "/home/coder/AGENTS.md"]); | ||
| expect(prompt.exitCode).not.toBe(0); | ||
| expect(prompt.stderr).toContain("No such file or directory"); | ||
| }); | ||
| }); | ||
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.