mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: bump to refactored Claude and Codex modules (#24981)
Bumps the dogfood template to the refactored Claude Code and Codex modules and removes the Coder Tasks integration. Claude and Codex now use slim-window app buttons that launch each tool in its own tmux session. This replaces the task-specific `develop.sh` and `preview` apps that were only created for Coder Tasks workspaces. The PR also wires the OpenAI dogfood secret through the deployment template so Codex can fall back to template configured BYOK when AI Gateway is disabled. Tested with this template version: [https://dev.coder.com/templates/coder/coder/versions/outstanding_hermann97](<https://dev.coder.com/templates/coder/coder/versions/outstanding_hermann97>)
This commit is contained in:
+65
-100
@@ -240,17 +240,17 @@ data "coder_parameter" "devcontainer_autostart" {
|
||||
mutable = true
|
||||
}
|
||||
|
||||
data "coder_parameter" "use_ai_bridge" {
|
||||
data "coder_parameter" "enable_ai_gateway" {
|
||||
type = "bool"
|
||||
name = "Use AI Bridge"
|
||||
name = "Use AI Gateway"
|
||||
default = true
|
||||
description = "If enabled, AI requests will be sent via AI Bridge."
|
||||
description = "If enabled, AI requests will be sent via AI Gateway."
|
||||
mutable = true
|
||||
}
|
||||
|
||||
# Only used if AI Bridge is disabled.
|
||||
# Only used if AI Gateway is disabled.
|
||||
# dogfood/main.tf injects this value from a GH Actions secret;
|
||||
# `coderd_template.dogfood` passes the value injected by .github/workflows/dogfood.yaml in `TF_VAR_CODER_DOGFOOD_ANTHROPIC_API_KEY`.
|
||||
# `coderd_template.dogfood` passes the value injected by .github/workflows/dogfood.yaml in `TF_VAR_CODER_DOGFOOD_ANTHROPIC_API_KEY` and `TF_VAR_CODER_DOGFOOD_OPENAI_API_KEY`.
|
||||
variable "anthropic_api_key" {
|
||||
type = string
|
||||
description = "The API key used to authenticate with the Anthropic API, if AI Bridge is disabled."
|
||||
@@ -258,6 +258,13 @@ variable "anthropic_api_key" {
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "openai_api_key" {
|
||||
type = string
|
||||
description = "The API key used to authenticate with the OpenAI API, if AI Gateway is disabled."
|
||||
default = ""
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
provider "docker" {
|
||||
host = lookup(local.docker_host, data.coder_parameter.region.value)
|
||||
}
|
||||
@@ -503,7 +510,7 @@ resource "coder_agent" "dev" {
|
||||
OIDC_TOKEN : data.coder_workspace_owner.me.oidc_access_token,
|
||||
CODER_AGENT_EXP_MCP_CONFIG_FILES : "~/.mcp.json,.mcp.json",
|
||||
},
|
||||
data.coder_parameter.use_ai_bridge.value ? {
|
||||
data.coder_parameter.enable_ai_gateway.value ? {
|
||||
ANTHROPIC_BASE_URL : "https://dev.coder.com/api/v2/aibridge/anthropic",
|
||||
ANTHROPIC_AUTH_TOKEN : data.coder_workspace_owner.me.session_token,
|
||||
OPENAI_BASE_URL : "https://dev.coder.com/api/v2/aibridge/openai/v1",
|
||||
@@ -891,36 +898,6 @@ resource "coder_metadata" "container_info" {
|
||||
}
|
||||
}
|
||||
|
||||
locals {
|
||||
claude_system_prompt = <<-EOT
|
||||
-- Framing --
|
||||
You are a helpful coding assistant. Aim to autonomously investigate
|
||||
and solve issues the user gives you and test your work, whenever possible.
|
||||
|
||||
Avoid shortcuts like mocking tests. When you get stuck, you can ask the user
|
||||
but opt for autonomy.
|
||||
|
||||
-- Tool Selection --
|
||||
- playwright: previewing your changes after you made them
|
||||
to confirm it worked as expected
|
||||
- Built-in tools - use for everything else:
|
||||
(file operations, git commands, builds & installs, one-off shell commands)
|
||||
|
||||
-- Workflow --
|
||||
When starting new work:
|
||||
1. If given a GitHub issue URL, use the `gh` CLI to read the full issue details with `gh issue view <issue-number>`.
|
||||
2. Create a feature branch for the work using a descriptive name based on the issue or task.
|
||||
Example: `git checkout -b fix/issue-123-oauth-error` or `git checkout -b feat/add-dark-mode`
|
||||
3. Proceed with implementation following the CLAUDE.md guidelines.
|
||||
|
||||
-- Context --
|
||||
There is an existing application in the current directory.
|
||||
Be sure to read CLAUDE.md before making any changes.
|
||||
|
||||
This is a real-world production application. As such, make sure to think carefully, use TODO lists, and plan carefully before making changes.
|
||||
EOT
|
||||
}
|
||||
|
||||
resource "coder_script" "boundary_config_setup" {
|
||||
agent_id = coder_agent.dev.id
|
||||
display_name = "Boundary Setup Configuration"
|
||||
@@ -939,76 +916,64 @@ resource "coder_script" "boundary_config_setup" {
|
||||
}
|
||||
|
||||
module "claude-code" {
|
||||
count = data.coder_task.me.enabled ? data.coder_workspace.me.start_count : 0
|
||||
source = "dev.registry.coder.com/coder/claude-code/coder"
|
||||
version = "4.9.2"
|
||||
enable_boundary = true
|
||||
agent_id = coder_agent.dev.id
|
||||
workdir = local.repo_dir
|
||||
claude_code_version = "latest"
|
||||
model = "opus"
|
||||
order = 999
|
||||
claude_api_key = data.coder_parameter.use_ai_bridge.value ? data.coder_workspace_owner.me.session_token : var.anthropic_api_key
|
||||
agentapi_version = "latest"
|
||||
count = data.coder_workspace.me.start_count
|
||||
source = "dev.registry.coder.com/coder/claude-code/coder"
|
||||
version = "5.1.0"
|
||||
enable_ai_gateway = data.coder_parameter.enable_ai_gateway.value
|
||||
anthropic_api_key = data.coder_parameter.enable_ai_gateway.value ? "" : var.anthropic_api_key
|
||||
agent_id = coder_agent.dev.id
|
||||
workdir = local.repo_dir
|
||||
mcp = <<-EOF
|
||||
{
|
||||
"mcpServers": {
|
||||
"playwright": {
|
||||
"command": "npx",
|
||||
"args": ["--", "@playwright/mcp@latest", "--headless", "--isolated", "--no-sandbox"]
|
||||
}
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
system_prompt = local.claude_system_prompt
|
||||
ai_prompt = data.coder_task.me.prompt
|
||||
post_install_script = <<-EOT
|
||||
cd $HOME/coder
|
||||
claude mcp add playwright npx -- @playwright/mcp@latest --headless --isolated --no-sandbox
|
||||
resource "coder_app" "claude" {
|
||||
agent_id = coder_agent.dev.id
|
||||
slug = "claude"
|
||||
display_name = "Claude Code"
|
||||
icon = "/icon/claude.svg"
|
||||
open_in = "slim-window"
|
||||
command = <<-EOT
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd "${local.repo_dir}"
|
||||
exec tmux new-session -A -s claude claude
|
||||
EOT
|
||||
}
|
||||
|
||||
resource "coder_ai_task" "task" {
|
||||
count = data.coder_task.me.enabled ? data.coder_workspace.me.start_count : 0
|
||||
app_id = module.claude-code[count.index].task_app_id
|
||||
}
|
||||
|
||||
resource "coder_app" "develop_sh" {
|
||||
count = data.coder_task.me.enabled ? data.coder_workspace.me.start_count : 0
|
||||
agent_id = coder_agent.dev.id
|
||||
slug = "develop-sh"
|
||||
display_name = "develop.sh"
|
||||
icon = "${data.coder_workspace.me.access_url}/emojis/1f4bb.png" // 💻
|
||||
command = "screen -x develop_sh"
|
||||
share = "authenticated"
|
||||
open_in = "tab"
|
||||
order = 0
|
||||
}
|
||||
|
||||
resource "coder_script" "develop_sh" {
|
||||
count = data.coder_task.me.enabled ? data.coder_workspace.me.start_count : 0
|
||||
display_name = "develop.sh"
|
||||
agent_id = coder_agent.dev.id
|
||||
run_on_start = true
|
||||
start_blocks_login = false
|
||||
icon = "${data.coder_workspace.me.access_url}/emojis/1f4bb.png" // 💻
|
||||
script = <<-EOT
|
||||
#!/usr/bin/env bash
|
||||
set -eux -o pipefail
|
||||
|
||||
trap 'coder exp sync complete develop-sh' EXIT
|
||||
coder exp sync want develop-sh install-deps
|
||||
coder exp sync start develop-sh
|
||||
|
||||
cd "${local.repo_dir}" && screen -dmS develop_sh /bin/sh -c 'while true; do ./scripts/develop.sh --; echo "develop.sh exited with code $? restarting in 30s"; sleep 30; done'
|
||||
module "codex" {
|
||||
source = "dev.registry.coder.com/coder-labs/codex/coder"
|
||||
version = "5.0.0"
|
||||
agent_id = coder_agent.dev.id
|
||||
workdir = local.repo_dir
|
||||
enable_ai_gateway = data.coder_parameter.enable_ai_gateway.value
|
||||
openai_api_key = data.coder_parameter.enable_ai_gateway.value ? "" : var.openai_api_key
|
||||
mcp = <<-EOT
|
||||
[mcp_servers.playwright]
|
||||
command = "npx"
|
||||
args = ["--", "@playwright/mcp@latest", "--headless", "--isolated", "--no-sandbox"]
|
||||
type = "stdio"
|
||||
EOT
|
||||
}
|
||||
|
||||
resource "coder_app" "preview" {
|
||||
count = data.coder_task.me.enabled ? data.coder_workspace.me.start_count : 0
|
||||
resource "coder_app" "codex" {
|
||||
agent_id = coder_agent.dev.id
|
||||
slug = "preview"
|
||||
display_name = "Preview"
|
||||
icon = "${data.coder_workspace.me.access_url}/emojis/1f50e.png" // 🔎
|
||||
url = "http://localhost:8080"
|
||||
share = "authenticated"
|
||||
subdomain = true
|
||||
open_in = "tab"
|
||||
order = 1
|
||||
healthcheck {
|
||||
url = "http://localhost:8080/healthz"
|
||||
interval = 5
|
||||
threshold = 15
|
||||
}
|
||||
slug = "codex"
|
||||
display_name = "Codex"
|
||||
icon = "/icon/openai-codex.svg"
|
||||
open_in = "slim-window"
|
||||
command = <<-EOT
|
||||
#!/bin/bash
|
||||
set -e
|
||||
cd "${local.repo_dir}"
|
||||
exec tmux new-session -A -s codex codex
|
||||
EOT
|
||||
}
|
||||
|
||||
@@ -51,6 +51,13 @@ variable "CODER_DOGFOOD_ANTHROPIC_API_KEY" {
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "CODER_DOGFOOD_OPENAI_API_KEY" {
|
||||
type = string
|
||||
description = "The API key that workspaces will use to authenticate with the OpenAI API."
|
||||
default = ""
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
resource "coderd_template" "dogfood" {
|
||||
name = var.CODER_TEMPLATE_NAME
|
||||
display_name = "Write Coder on Coder"
|
||||
@@ -67,6 +74,10 @@ resource "coderd_template" "dogfood" {
|
||||
{
|
||||
name = "anthropic_api_key"
|
||||
value = var.CODER_DOGFOOD_ANTHROPIC_API_KEY
|
||||
},
|
||||
{
|
||||
name = "openai_api_key"
|
||||
value = var.CODER_DOGFOOD_OPENAI_API_KEY
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user