mirror of
https://github.com/coder/registry.git
synced 2026-06-03 04:58:15 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 885c19e7bf | |||
| 1040aebd8b |
@@ -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.3.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.3.0"
|
||||
version = "4.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
openai_api_key = "..."
|
||||
workdir = "/home/coder/project"
|
||||
@@ -51,7 +51,7 @@ For tasks integration with AI Bridge, add `enable_aibridge = true` to the [Usage
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "4.3.0"
|
||||
version = "4.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
workdir = "/home/coder/project"
|
||||
enable_aibridge = true
|
||||
@@ -94,7 +94,7 @@ data "coder_task" "me" {}
|
||||
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "4.3.0"
|
||||
version = "4.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
openai_api_key = "..."
|
||||
ai_prompt = data.coder_task.me.prompt
|
||||
@@ -105,26 +105,6 @@ module "codex" {
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with Agent Boundaries
|
||||
|
||||
This example shows how to configure the Codex module to run the agent behind a process-level boundary that restricts its network access.
|
||||
|
||||
By default, when `enable_boundary = true`, the module uses `coder boundary` subcommand (provided by Coder) without requiring any installation.
|
||||
|
||||
```tf
|
||||
module "codex" {
|
||||
source = "registry.coder.com/coder-labs/codex/coder"
|
||||
version = "4.3.0"
|
||||
agent_id = coder_agent.main.id
|
||||
openai_api_key = var.openai_api_key
|
||||
workdir = "/home/coder/project"
|
||||
enable_boundary = true
|
||||
}
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> For developers: The module also supports installing boundary from a release version (`use_boundary_directly = true`) or compiling from source (`compile_boundary_from_source = true`). These are escape hatches for development and testing purposes.
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This example shows additional configuration options for custom models, MCP servers, and base configuration.
|
||||
@@ -132,7 +112,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.3.0"
|
||||
version = "4.2.0"
|
||||
agent_id = coder_agent.example.id
|
||||
openai_api_key = "..."
|
||||
workdir = "/home/coder/project"
|
||||
|
||||
@@ -473,47 +473,4 @@ describe("codex", async () => {
|
||||
);
|
||||
expect(configToml).toContain('profile = "aibridge"');
|
||||
});
|
||||
|
||||
test("boundary-enabled", async () => {
|
||||
const { id } = await setup({
|
||||
moduleVariables: {
|
||||
enable_boundary: "true",
|
||||
boundary_config_path: "/tmp/test-boundary.yaml",
|
||||
},
|
||||
});
|
||||
// Write boundary config
|
||||
await execContainer(id, [
|
||||
"bash",
|
||||
"-c",
|
||||
`cat > /tmp/test-boundary.yaml <<'EOF'
|
||||
jail_type: landjail
|
||||
proxy_port: 8087
|
||||
log_level: warn
|
||||
allowlist:
|
||||
- "domain=api.openai.com"
|
||||
EOF`,
|
||||
]);
|
||||
// Add mock coder binary for boundary setup
|
||||
await writeExecutable({
|
||||
containerId: id,
|
||||
filePath: "/usr/bin/coder",
|
||||
content: `#!/bin/bash
|
||||
if [ "$1" = "boundary" ]; then
|
||||
if [ "$2" = "--help" ]; then
|
||||
echo "boundary help"
|
||||
exit 0
|
||||
fi
|
||||
shift; shift; exec "$@"
|
||||
fi
|
||||
echo "mock coder"`,
|
||||
});
|
||||
await execModuleScript(id);
|
||||
await expectAgentAPIStarted(id);
|
||||
// Verify boundary wrapper was used in start script
|
||||
const startLog = await readFileContainer(
|
||||
id,
|
||||
"/home/coder/.codex-module/agentapi-start.log",
|
||||
);
|
||||
expect(startLog).toContain("boundary");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -176,36 +176,6 @@ variable "codex_system_prompt" {
|
||||
default = "You are a helpful coding assistant. Start every response with `Codex says:`"
|
||||
}
|
||||
|
||||
variable "enable_boundary" {
|
||||
type = bool
|
||||
description = "Enable coder boundary for network filtering."
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "boundary_config_path" {
|
||||
type = string
|
||||
description = "Path to boundary config.yaml inside the workspace. If provided, exposed as BOUNDARY_CONFIG env var."
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "boundary_version" {
|
||||
type = string
|
||||
description = "Boundary version. When use_boundary_directly is true, a release version should be provided or 'latest' for the latest release."
|
||||
default = "latest"
|
||||
}
|
||||
|
||||
variable "compile_boundary_from_source" {
|
||||
type = bool
|
||||
description = "Whether to compile boundary from source instead of using the official install script."
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "use_boundary_directly" {
|
||||
type = bool
|
||||
description = "Whether to use boundary binary directly instead of coder boundary subcommand."
|
||||
default = false
|
||||
}
|
||||
|
||||
resource "coder_env" "openai_api_key" {
|
||||
agent_id = var.agent_id
|
||||
name = "OPENAI_API_KEY"
|
||||
@@ -242,31 +212,26 @@ locals {
|
||||
|
||||
module "agentapi" {
|
||||
source = "registry.coder.com/coder/agentapi/coder"
|
||||
version = "2.3.0"
|
||||
version = "2.2.0"
|
||||
|
||||
agent_id = var.agent_id
|
||||
folder = local.workdir
|
||||
web_app_slug = local.app_slug
|
||||
web_app_order = var.order
|
||||
web_app_group = var.group
|
||||
web_app_icon = var.icon
|
||||
web_app_display_name = var.web_app_display_name
|
||||
cli_app = var.cli_app
|
||||
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
|
||||
agentapi_subdomain = var.subdomain
|
||||
agentapi_version = var.agentapi_version
|
||||
enable_state_persistence = var.enable_state_persistence
|
||||
pre_install_script = var.pre_install_script
|
||||
post_install_script = var.post_install_script
|
||||
enable_boundary = var.enable_boundary
|
||||
boundary_config_path = var.boundary_config_path
|
||||
boundary_version = var.boundary_version
|
||||
compile_boundary_from_source = var.compile_boundary_from_source
|
||||
use_boundary_directly = var.use_boundary_directly
|
||||
start_script = <<-EOT
|
||||
agent_id = var.agent_id
|
||||
folder = local.workdir
|
||||
web_app_slug = local.app_slug
|
||||
web_app_order = var.order
|
||||
web_app_group = var.group
|
||||
web_app_icon = var.icon
|
||||
web_app_display_name = var.web_app_display_name
|
||||
cli_app = var.cli_app
|
||||
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
|
||||
agentapi_subdomain = var.subdomain
|
||||
agentapi_version = var.agentapi_version
|
||||
enable_state_persistence = var.enable_state_persistence
|
||||
pre_install_script = var.pre_install_script
|
||||
post_install_script = var.post_install_script
|
||||
start_script = <<-EOT
|
||||
#!/bin/bash
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
@@ -210,16 +210,7 @@ capture_session_id() {
|
||||
|
||||
start_codex() {
|
||||
printf "Starting Codex with arguments: %s\n" "${CODEX_ARGS[*]}"
|
||||
# AGENTAPI_BOUNDARY_PREFIX is set by the agentapi module's main.sh when
|
||||
# enable_boundary=true. It points to a wrapper script that runs the command
|
||||
# through coder boundary, sandboxing only the agent process.
|
||||
if [ -n "${AGENTAPI_BOUNDARY_PREFIX:-}" ]; then
|
||||
printf "Starting with coder boundary enabled\n"
|
||||
agentapi server --type codex --term-width 67 --term-height 1190 -- \
|
||||
"${AGENTAPI_BOUNDARY_PREFIX}" codex "${CODEX_ARGS[@]}" &
|
||||
else
|
||||
agentapi server --type codex --term-width 67 --term-height 1190 -- codex "${CODEX_ARGS[@]}" &
|
||||
fi
|
||||
agentapi server --type codex --term-width 67 --term-height 1190 -- codex "${CODEX_ARGS[@]}" &
|
||||
capture_session_id
|
||||
}
|
||||
|
||||
|
||||
@@ -218,6 +218,25 @@ module "claude-code" {
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with Remote Control
|
||||
|
||||
[Remote Control](https://code.claude.com/docs/en/remote-control.md) allows you to access your Claude Code session from [claude.ai/code](https://claude.ai/code) or the Claude mobile app. The session runs locally in your workspace while you interact with it from any browser or device.
|
||||
|
||||
> [!NOTE]
|
||||
> Remote Control requires a Claude subscription (Pro, Max, Team, or Enterprise). API keys are not supported. You must authenticate using `claude_code_oauth_token`.
|
||||
|
||||
```tf
|
||||
module "claude-code" {
|
||||
source = "registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.8.0"
|
||||
agent_id = coder_agent.main.id
|
||||
workdir = "/home/coder/project"
|
||||
claude_code_oauth_token = var.claude_code_oauth_token
|
||||
enable_remote_control = true
|
||||
# remote_control_name = "Custom Name" # Optional: defaults to workspace name
|
||||
}
|
||||
```
|
||||
|
||||
### Usage with AWS Bedrock
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
@@ -267,6 +267,18 @@ variable "enable_state_persistence" {
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "enable_remote_control" {
|
||||
type = bool
|
||||
description = "Enable Claude Code Remote Control, allowing the session to be accessed from claude.ai/code or the Claude mobile app. Requires a Claude subscription (Pro, Max, Team, or Enterprise). API keys are not supported. See https://code.claude.com/docs/en/remote-control.md"
|
||||
default = false
|
||||
}
|
||||
|
||||
variable "remote_control_name" {
|
||||
type = string
|
||||
description = "Custom session name for Remote Control, visible in the session list at claude.ai/code. Only used when enable_remote_control is true. Defaults to the workspace name."
|
||||
default = ""
|
||||
}
|
||||
|
||||
resource "coder_env" "claude_code_md_path" {
|
||||
count = var.claude_md_path == "" ? 0 : 1
|
||||
agent_id = var.agent_id
|
||||
@@ -401,6 +413,8 @@ module "agentapi" {
|
||||
ARG_USE_BOUNDARY_DIRECTLY='${var.use_boundary_directly}' \
|
||||
ARG_CODER_HOST='${local.coder_host}' \
|
||||
ARG_CLAUDE_BINARY_PATH='${var.claude_binary_path}' \
|
||||
ARG_ENABLE_REMOTE_CONTROL='${var.enable_remote_control}' \
|
||||
ARG_REMOTE_CONTROL_NAME='${var.remote_control_name != "" ? var.remote_control_name : data.coder_workspace.me.name}' \
|
||||
/tmp/start.sh
|
||||
EOT
|
||||
|
||||
|
||||
@@ -417,6 +417,46 @@ run "test_disable_state_persistence" {
|
||||
}
|
||||
|
||||
|
||||
run "test_enable_remote_control_default" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent"
|
||||
workdir = "/home/coder"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.enable_remote_control == false
|
||||
error_message = "enable_remote_control should default to false"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.remote_control_name == ""
|
||||
error_message = "remote_control_name should default to empty string"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_enable_remote_control" {
|
||||
command = plan
|
||||
|
||||
variables {
|
||||
agent_id = "test-agent-rc"
|
||||
workdir = "/home/coder/project"
|
||||
enable_remote_control = true
|
||||
remote_control_name = "My Project"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.enable_remote_control == true
|
||||
error_message = "enable_remote_control should be true when explicitly enabled"
|
||||
}
|
||||
|
||||
assert {
|
||||
condition = var.remote_control_name == "My Project"
|
||||
error_message = "remote_control_name should be set to 'My Project'"
|
||||
}
|
||||
}
|
||||
|
||||
run "test_no_api_key_no_env" {
|
||||
command = plan
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ ARG_BOUNDARY_VERSION=${ARG_BOUNDARY_VERSION:-"latest"}
|
||||
ARG_COMPILE_FROM_SOURCE=${ARG_COMPILE_FROM_SOURCE:-false}
|
||||
ARG_USE_BOUNDARY_DIRECTLY=${ARG_USE_BOUNDARY_DIRECTLY:-false}
|
||||
ARG_CODER_HOST=${ARG_CODER_HOST:-}
|
||||
ARG_ENABLE_REMOTE_CONTROL=${ARG_ENABLE_REMOTE_CONTROL:-false}
|
||||
ARG_REMOTE_CONTROL_NAME=${ARG_REMOTE_CONTROL_NAME:-}
|
||||
|
||||
echo "--------------------------------"
|
||||
|
||||
@@ -39,6 +41,8 @@ printf "ARG_BOUNDARY_VERSION: %s\n" "$ARG_BOUNDARY_VERSION"
|
||||
printf "ARG_COMPILE_FROM_SOURCE: %s\n" "$ARG_COMPILE_FROM_SOURCE"
|
||||
printf "ARG_USE_BOUNDARY_DIRECTLY: %s\n" "$ARG_USE_BOUNDARY_DIRECTLY"
|
||||
printf "ARG_CODER_HOST: %s\n" "$ARG_CODER_HOST"
|
||||
printf "ARG_ENABLE_REMOTE_CONTROL: %s\n" "$ARG_ENABLE_REMOTE_CONTROL"
|
||||
printf "ARG_REMOTE_CONTROL_NAME: %s\n" "$ARG_REMOTE_CONTROL_NAME"
|
||||
|
||||
echo "--------------------------------"
|
||||
|
||||
@@ -220,6 +224,15 @@ function start_agentapi() {
|
||||
[ -n "$ARG_AI_PROMPT" ] && ARGS+=(-- "$ARG_AI_PROMPT")
|
||||
fi
|
||||
|
||||
# Build the claude command - either regular or remote-control mode.
|
||||
CLAUDE_CMD=("claude")
|
||||
if [ "$ARG_ENABLE_REMOTE_CONTROL" = "true" ]; then
|
||||
CLAUDE_CMD+=("remote-control")
|
||||
if [ -n "$ARG_REMOTE_CONTROL_NAME" ]; then
|
||||
CLAUDE_CMD+=("--name" "$ARG_REMOTE_CONTROL_NAME")
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "Running claude code with args: %s\n" "$(printf '%q ' "${ARGS[@]}")"
|
||||
|
||||
if [ "$ARG_ENABLE_BOUNDARY" = "true" ]; then
|
||||
@@ -246,9 +259,9 @@ function start_agentapi() {
|
||||
|
||||
agentapi server --type claude --term-width 67 --term-height 1190 -- \
|
||||
"${BOUNDARY_CMD[@]}" "${BOUNDARY_ARGS[@]}" -- \
|
||||
claude "${ARGS[@]}"
|
||||
"${CLAUDE_CMD[@]}" "${ARGS[@]}"
|
||||
else
|
||||
agentapi server --type claude --term-width 67 --term-height 1190 -- claude "${ARGS[@]}"
|
||||
agentapi server --type claude --term-width 67 --term-height 1190 -- "${CLAUDE_CMD[@]}" "${ARGS[@]}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user