feat: update auth setup in codex (#472)
Closes # ## Description <!-- Briefly describe what this PR does and why --> ## Type of Change - [ ] New module - [x] Bug fix - [x] Feature/enhancement - [ ] Documentation - [ ] Other ## Module Information <!-- Delete this section if not applicable --> **Path:** `registry/coder-labs/modules/codex` **New version:** `v3.0.0` **Breaking change:** [X] Yes [ ] No ## Testing & Validation - [X] Tests pass (`bun test`) - [X] Code formatted (`bun run fmt`) - [X] Changes tested locally ## Related Issues <!-- Link related issues or write "None" if not applicable --> --------- Co-authored-by: DevCats <christofer@coder.com>
This commit is contained in:
parent
a599302774
commit
ca7bc42946
@ -13,10 +13,10 @@ Run Codex CLI in your workspace to access OpenAI's models through the Codex inte
|
|||||||
```tf
|
```tf
|
||||||
module "codex" {
|
module "codex" {
|
||||||
source = "registry.coder.com/coder-labs/codex/coder"
|
source = "registry.coder.com/coder-labs/codex/coder"
|
||||||
version = "2.1.1"
|
version = "3.0.0"
|
||||||
agent_id = coder_agent.example.id
|
agent_id = coder_agent.example.id
|
||||||
openai_api_key = var.openai_api_key
|
openai_api_key = var.openai_api_key
|
||||||
folder = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -33,10 +33,11 @@ module "codex" {
|
|||||||
module "codex" {
|
module "codex" {
|
||||||
count = data.coder_workspace.me.start_count
|
count = data.coder_workspace.me.start_count
|
||||||
source = "registry.coder.com/coder-labs/codex/coder"
|
source = "registry.coder.com/coder-labs/codex/coder"
|
||||||
version = "2.1.1"
|
version = "3.0.0"
|
||||||
agent_id = coder_agent.example.id
|
agent_id = coder_agent.example.id
|
||||||
openai_api_key = "..."
|
openai_api_key = "..."
|
||||||
folder = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
|
report_tasks = false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -60,11 +61,11 @@ module "coder-login" {
|
|||||||
|
|
||||||
module "codex" {
|
module "codex" {
|
||||||
source = "registry.coder.com/coder-labs/codex/coder"
|
source = "registry.coder.com/coder-labs/codex/coder"
|
||||||
version = "2.1.1"
|
version = "3.0.0"
|
||||||
agent_id = coder_agent.example.id
|
agent_id = coder_agent.example.id
|
||||||
openai_api_key = "..."
|
openai_api_key = "..."
|
||||||
ai_prompt = data.coder_parameter.ai_prompt.value
|
ai_prompt = data.coder_parameter.ai_prompt.value
|
||||||
folder = "/home/coder/project"
|
workdir = "/home/coder/project"
|
||||||
|
|
||||||
# Custom configuration for full auto mode
|
# Custom configuration for full auto mode
|
||||||
base_config_toml = <<-EOT
|
base_config_toml = <<-EOT
|
||||||
@ -75,7 +76,7 @@ module "codex" {
|
|||||||
```
|
```
|
||||||
|
|
||||||
> [!WARNING]
|
> [!WARNING]
|
||||||
> This module configures Codex with a `workspace-write` sandbox that allows AI tasks to read/write files in the specified folder. While the sandbox provides security boundaries, Codex can still modify files within the workspace. Use this module _only_ in trusted environments and be aware of the security implications.
|
> This module configures Codex with a `workspace-write` sandbox that allows AI tasks to read/write files in the specified workdir. While the sandbox provides security boundaries, Codex can still modify files within the workspace. Use this module _only_ in trusted environments and be aware of the security implications.
|
||||||
|
|
||||||
## How it Works
|
## How it Works
|
||||||
|
|
||||||
@ -106,7 +107,7 @@ For custom Codex configuration, use `base_config_toml` and/or `additional_mcp_se
|
|||||||
```tf
|
```tf
|
||||||
module "codex" {
|
module "codex" {
|
||||||
source = "registry.coder.com/coder-labs/codex/coder"
|
source = "registry.coder.com/coder-labs/codex/coder"
|
||||||
version = "2.1.1"
|
version = "3.0.0"
|
||||||
# ... other variables ...
|
# ... other variables ...
|
||||||
|
|
||||||
# Override default configuration
|
# Override default configuration
|
||||||
@ -137,7 +138,7 @@ module "codex" {
|
|||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> To use tasks with Codex CLI, ensure you have the `openai_api_key` variable set, and **you create a `coder_parameter` named `"AI Prompt"` and pass its value to the codex module's `ai_prompt` variable**. [Tasks Template Example](https://registry.coder.com/templates/coder-labs/tasks-docker).
|
> To use tasks with Codex CLI, ensure you have the `openai_api_key` variable set, and **you create a `coder_parameter` named `"AI Prompt"` and pass its value to the codex module's `ai_prompt` variable**. [Tasks Template Example](https://registry.coder.com/templates/coder-labs/tasks-docker).
|
||||||
> The module automatically configures Codex with your API key and model preferences.
|
> The module automatically configures Codex with your API key and model preferences.
|
||||||
> folder is a required variable for the module to function correctly.
|
> workdir is a required variable for the module to function correctly.
|
||||||
|
|
||||||
## References
|
## References
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ const setup = async (props?: SetupProps): Promise<{ id: string }> => {
|
|||||||
install_codex: props?.skipCodexMock ? "true" : "false",
|
install_codex: props?.skipCodexMock ? "true" : "false",
|
||||||
install_agentapi: props?.skipAgentAPIMock ? "true" : "false",
|
install_agentapi: props?.skipAgentAPIMock ? "true" : "false",
|
||||||
codex_model: "gpt-4-turbo",
|
codex_model: "gpt-4-turbo",
|
||||||
folder: "/home/coder",
|
workdir: "/home/coder",
|
||||||
...props?.moduleVariables,
|
...props?.moduleVariables,
|
||||||
},
|
},
|
||||||
registerCleanup,
|
registerCleanup,
|
||||||
@ -166,12 +166,12 @@ describe("codex", async () => {
|
|||||||
expect(postInstallLog).toContain("post-install-script");
|
expect(postInstallLog).toContain("post-install-script");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("folder-variable", async () => {
|
test("workdir-variable", async () => {
|
||||||
const folder = "/tmp/codex-test-folder";
|
const workdir = "/tmp/codex-test-workdir";
|
||||||
const { id } = await setup({
|
const { id } = await setup({
|
||||||
skipCodexMock: false,
|
skipCodexMock: false,
|
||||||
moduleVariables: {
|
moduleVariables: {
|
||||||
folder,
|
workdir,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
await execModuleScript(id);
|
await execModuleScript(id);
|
||||||
@ -179,7 +179,7 @@ describe("codex", async () => {
|
|||||||
id,
|
id,
|
||||||
"/home/coder/.codex-module/install.log",
|
"/home/coder/.codex-module/install.log",
|
||||||
);
|
);
|
||||||
expect(resp).toContain(folder);
|
expect(resp).toContain(workdir);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("additional-mcp-servers", async () => {
|
test("additional-mcp-servers", async () => {
|
||||||
|
|||||||
@ -36,11 +36,41 @@ variable "icon" {
|
|||||||
default = "/icon/openai.svg"
|
default = "/icon/openai.svg"
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "folder" {
|
variable "workdir" {
|
||||||
type = string
|
type = string
|
||||||
description = "The folder to run Codex in."
|
description = "The folder to run Codex in."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
variable "report_tasks" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to enable task reporting to Coder UI via AgentAPI"
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "subdomain" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to use a subdomain for AgentAPI."
|
||||||
|
default = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "cli_app" {
|
||||||
|
type = bool
|
||||||
|
description = "Whether to create a CLI app for Codex"
|
||||||
|
default = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "web_app_display_name" {
|
||||||
|
type = string
|
||||||
|
description = "Display name for the web app"
|
||||||
|
default = "Codex"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "cli_app_display_name" {
|
||||||
|
type = string
|
||||||
|
description = "Display name for the CLI app"
|
||||||
|
default = "Codex CLI"
|
||||||
|
}
|
||||||
|
|
||||||
variable "install_codex" {
|
variable "install_codex" {
|
||||||
type = bool
|
type = bool
|
||||||
description = "Whether to install Codex."
|
description = "Whether to install Codex."
|
||||||
@ -120,6 +150,7 @@ resource "coder_env" "openai_api_key" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
locals {
|
locals {
|
||||||
|
workdir = trimsuffix(var.workdir, "/")
|
||||||
app_slug = "codex"
|
app_slug = "codex"
|
||||||
install_script = file("${path.module}/scripts/install.sh")
|
install_script = file("${path.module}/scripts/install.sh")
|
||||||
start_script = file("${path.module}/scripts/start.sh")
|
start_script = file("${path.module}/scripts/start.sh")
|
||||||
@ -131,16 +162,18 @@ module "agentapi" {
|
|||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
|
||||||
agent_id = var.agent_id
|
agent_id = var.agent_id
|
||||||
folder = var.folder
|
folder = local.workdir
|
||||||
web_app_slug = local.app_slug
|
web_app_slug = local.app_slug
|
||||||
web_app_order = var.order
|
web_app_order = var.order
|
||||||
web_app_group = var.group
|
web_app_group = var.group
|
||||||
web_app_icon = var.icon
|
web_app_icon = var.icon
|
||||||
web_app_display_name = "Codex"
|
web_app_display_name = var.web_app_display_name
|
||||||
cli_app_slug = "${local.app_slug}-cli"
|
cli_app = var.cli_app
|
||||||
cli_app_display_name = "Codex CLI"
|
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
|
module_dir_name = local.module_dir_name
|
||||||
install_agentapi = var.install_agentapi
|
install_agentapi = var.install_agentapi
|
||||||
|
agentapi_subdomain = var.subdomain
|
||||||
agentapi_version = var.agentapi_version
|
agentapi_version = var.agentapi_version
|
||||||
pre_install_script = var.pre_install_script
|
pre_install_script = var.pre_install_script
|
||||||
post_install_script = var.post_install_script
|
post_install_script = var.post_install_script
|
||||||
@ -152,8 +185,9 @@ module "agentapi" {
|
|||||||
echo -n '${base64encode(local.start_script)}' | base64 -d > /tmp/start.sh
|
echo -n '${base64encode(local.start_script)}' | base64 -d > /tmp/start.sh
|
||||||
chmod +x /tmp/start.sh
|
chmod +x /tmp/start.sh
|
||||||
ARG_OPENAI_API_KEY='${var.openai_api_key}' \
|
ARG_OPENAI_API_KEY='${var.openai_api_key}' \
|
||||||
|
ARG_REPORT_TASKS='${var.report_tasks}' \
|
||||||
ARG_CODEX_MODEL='${var.codex_model}' \
|
ARG_CODEX_MODEL='${var.codex_model}' \
|
||||||
ARG_CODEX_START_DIRECTORY='${var.folder}' \
|
ARG_CODEX_START_DIRECTORY='${var.workdir}' \
|
||||||
ARG_CODEX_TASK_PROMPT='${base64encode(var.ai_prompt)}' \
|
ARG_CODEX_TASK_PROMPT='${base64encode(var.ai_prompt)}' \
|
||||||
/tmp/start.sh
|
/tmp/start.sh
|
||||||
EOT
|
EOT
|
||||||
@ -165,12 +199,14 @@ module "agentapi" {
|
|||||||
|
|
||||||
echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh
|
echo -n '${base64encode(local.install_script)}' | base64 -d > /tmp/install.sh
|
||||||
chmod +x /tmp/install.sh
|
chmod +x /tmp/install.sh
|
||||||
|
ARG_OPENAI_API_KEY='${var.openai_api_key}' \
|
||||||
|
ARG_REPORT_TASKS='${var.report_tasks}' \
|
||||||
ARG_INSTALL='${var.install_codex}' \
|
ARG_INSTALL='${var.install_codex}' \
|
||||||
ARG_CODEX_VERSION='${var.codex_version}' \
|
ARG_CODEX_VERSION='${var.codex_version}' \
|
||||||
ARG_BASE_CONFIG_TOML='${base64encode(var.base_config_toml)}' \
|
ARG_BASE_CONFIG_TOML='${base64encode(var.base_config_toml)}' \
|
||||||
ARG_ADDITIONAL_MCP_SERVERS='${base64encode(var.additional_mcp_servers)}' \
|
ARG_ADDITIONAL_MCP_SERVERS='${base64encode(var.additional_mcp_servers)}' \
|
||||||
ARG_CODER_MCP_APP_STATUS_SLUG='${local.app_slug}' \
|
ARG_CODER_MCP_APP_STATUS_SLUG='${local.app_slug}' \
|
||||||
ARG_CODEX_START_DIRECTORY='${var.folder}' \
|
ARG_CODEX_START_DIRECTORY='${var.workdir}' \
|
||||||
ARG_CODEX_INSTRUCTION_PROMPT='${base64encode(var.codex_system_prompt)}' \
|
ARG_CODEX_INSTRUCTION_PROMPT='${base64encode(var.codex_system_prompt)}' \
|
||||||
/tmp/install.sh
|
/tmp/install.sh
|
||||||
EOT
|
EOT
|
||||||
|
|||||||
@ -22,6 +22,8 @@ printf "Start Directory: %s\n" "$ARG_CODEX_START_DIRECTORY"
|
|||||||
printf "Has Base Config: %s\n" "$([ -n "$ARG_BASE_CONFIG_TOML" ] && echo "Yes" || echo "No")"
|
printf "Has Base Config: %s\n" "$([ -n "$ARG_BASE_CONFIG_TOML" ] && echo "Yes" || echo "No")"
|
||||||
printf "Has Additional MCP: %s\n" "$([ -n "$ARG_ADDITIONAL_MCP_SERVERS" ] && echo "Yes" || echo "No")"
|
printf "Has Additional MCP: %s\n" "$([ -n "$ARG_ADDITIONAL_MCP_SERVERS" ] && echo "Yes" || echo "No")"
|
||||||
printf "Has System Prompt: %s\n" "$([ -n "$ARG_CODEX_INSTRUCTION_PROMPT" ] && echo "Yes" || echo "No")"
|
printf "Has System Prompt: %s\n" "$([ -n "$ARG_CODEX_INSTRUCTION_PROMPT" ] && echo "Yes" || echo "No")"
|
||||||
|
printf "OpenAI API Key: %s\n" "$([ -n "$ARG_OPENAI_API_KEY" ] && echo "Provided" || echo "Not provided")"
|
||||||
|
printf "Report Tasks: %s\n" "$ARG_REPORT_TASKS"
|
||||||
echo "======================================"
|
echo "======================================"
|
||||||
|
|
||||||
set +o nounset
|
set +o nounset
|
||||||
@ -100,13 +102,20 @@ EOF
|
|||||||
append_mcp_servers_section() {
|
append_mcp_servers_section() {
|
||||||
local config_path="$1"
|
local config_path="$1"
|
||||||
|
|
||||||
|
if [ "${ARG_REPORT_TASKS}" == "false" ]; then
|
||||||
|
ARG_CODER_MCP_APP_STATUS_SLUG=""
|
||||||
|
CODER_MCP_AI_AGENTAPI_URL=""
|
||||||
|
else
|
||||||
|
CODER_MCP_AI_AGENTAPI_URL="http://localhost:3284"
|
||||||
|
fi
|
||||||
|
|
||||||
cat << EOF >> "$config_path"
|
cat << EOF >> "$config_path"
|
||||||
|
|
||||||
# MCP Servers Configuration
|
# MCP Servers Configuration
|
||||||
[mcp_servers.Coder]
|
[mcp_servers.Coder]
|
||||||
command = "coder"
|
command = "coder"
|
||||||
args = ["exp", "mcp", "server"]
|
args = ["exp", "mcp", "server"]
|
||||||
env = { "CODER_MCP_APP_STATUS_SLUG" = "${ARG_CODER_MCP_APP_STATUS_SLUG}", "CODER_MCP_AI_AGENTAPI_URL" = "http://localhost:3284", "CODER_AGENT_URL" = "${CODER_AGENT_URL}", "CODER_AGENT_TOKEN" = "${CODER_AGENT_TOKEN}" }
|
env = { "CODER_MCP_APP_STATUS_SLUG" = "${ARG_CODER_MCP_APP_STATUS_SLUG}", "CODER_MCP_AI_AGENTAPI_URL" = "${CODER_MCP_AI_AGENTAPI_URL}" , "CODER_AGENT_URL" = "${CODER_AGENT_URL}", "CODER_AGENT_TOKEN" = "${CODER_AGENT_TOKEN}" }
|
||||||
description = "Report ALL tasks and statuses (in progress, done, failed) you are working on."
|
description = "Report ALL tasks and statuses (in progress, done, failed) you are working on."
|
||||||
type = "stdio"
|
type = "stdio"
|
||||||
|
|
||||||
@ -159,7 +168,21 @@ function add_instruction_prompt_if_exists() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function add_auth_json() {
|
||||||
|
AUTH_JSON_PATH="$HOME/.codex/auth.json"
|
||||||
|
mkdir -p "$(dirname "$AUTH_JSON_PATH")"
|
||||||
|
AUTH_JSON=$(
|
||||||
|
cat << EOF
|
||||||
|
{
|
||||||
|
"OPENAI_API_KEY": "${ARG_OPENAI_API_KEY}"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
echo "$AUTH_JSON" > "$AUTH_JSON_PATH"
|
||||||
|
}
|
||||||
|
|
||||||
install_codex
|
install_codex
|
||||||
codex --version
|
codex --version
|
||||||
populate_config_toml
|
populate_config_toml
|
||||||
add_instruction_prompt_if_exists
|
add_instruction_prompt_if_exists
|
||||||
|
add_auth_json
|
||||||
|
|||||||
@ -22,6 +22,7 @@ printf "OpenAI API Key: %s\n" "$([ -n "$ARG_OPENAI_API_KEY" ] && echo "Provided"
|
|||||||
printf "Codex Model: %s\n" "${ARG_CODEX_MODEL:-"Default"}"
|
printf "Codex Model: %s\n" "${ARG_CODEX_MODEL:-"Default"}"
|
||||||
printf "Start Directory: %s\n" "$ARG_CODEX_START_DIRECTORY"
|
printf "Start Directory: %s\n" "$ARG_CODEX_START_DIRECTORY"
|
||||||
printf "Has Task Prompt: %s\n" "$([ -n "$ARG_CODEX_TASK_PROMPT" ] && echo "Yes" || echo "No")"
|
printf "Has Task Prompt: %s\n" "$([ -n "$ARG_CODEX_TASK_PROMPT" ] && echo "Yes" || echo "No")"
|
||||||
|
printf "Report Tasks: %s\n" "$ARG_REPORT_TASKS"
|
||||||
echo "======================================"
|
echo "======================================"
|
||||||
set +o nounset
|
set +o nounset
|
||||||
CODEX_ARGS=()
|
CODEX_ARGS=()
|
||||||
@ -57,7 +58,11 @@ fi
|
|||||||
|
|
||||||
if [ -n "$ARG_CODEX_TASK_PROMPT" ]; then
|
if [ -n "$ARG_CODEX_TASK_PROMPT" ]; then
|
||||||
printf "Running the task prompt %s\n" "$ARG_CODEX_TASK_PROMPT"
|
printf "Running the task prompt %s\n" "$ARG_CODEX_TASK_PROMPT"
|
||||||
PROMPT="Complete the task at hand in one go. Every step of the way, report your progress using coder_report_task tool with proper summary and statuses. Your task at hand: $ARG_CODEX_TASK_PROMPT"
|
if [ "${ARG_REPORT_TASKS}" == "true" ]; then
|
||||||
|
PROMPT="Complete the task at hand in one go. Every step of the way, report your progress using coder_report_task tool with proper summary and statuses. Your task at hand: $ARG_CODEX_TASK_PROMPT"
|
||||||
|
else
|
||||||
|
PROMPT="Your task at hand: $ARG_CODEX_TASK_PROMPT"
|
||||||
|
fi
|
||||||
CODEX_ARGS+=("$PROMPT")
|
CODEX_ARGS+=("$PROMPT")
|
||||||
else
|
else
|
||||||
printf "No task prompt given.\n"
|
printf "No task prompt given.\n"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user