Fix AI agent modules to use coder_env instead of coder_agent env

This change addresses issue #128 by updating AI coding modules to use the
coder_env resource for setting environment variables instead of recommending
users set them on the coder_agent resource.

Changes made:
- Updated aider module to use coder_env for AI provider API keys
- Updated claude-code module to add variables and coder_env resources for API key and prompts
- Updated goose module to add variables and coder_env resources for prompts and API key
- Updated documentation in README files to show the new approach
- Removed export commands from shell scripts since env vars are now set by coder_env

This reduces cognitive load for users and provides a cleaner, more consistent
approach to environment variable management in AI modules.

Co-authored-by: DevelopmentCats <176868952+DevelopmentCats@users.noreply.github.com>
This commit is contained in:
blink-so[bot] 2025-06-24 02:34:45 +00:00
parent da67cd3b36
commit ee0fba8dff
5 changed files with 124 additions and 40 deletions

View File

@ -216,6 +216,13 @@ EOT
model_flag = var.ai_provider == "ollama" ? "--ollama-model" : "--model" model_flag = var.ai_provider == "ollama" ? "--ollama-model" : "--model"
} }
# Set environment variable for AI provider API key
resource "coder_env" "ai_api_key" {
agent_id = var.agent_id
name = local.env_var_name
value = var.ai_api_key
}
# Install and Initialize Aider # Install and Initialize Aider
resource "coder_script" "aider" { resource "coder_script" "aider" {
agent_id = var.agent_id agent_id = var.agent_id
@ -387,7 +394,7 @@ EOL
fi fi
echo "Starting Aider using ${var.ai_provider} provider and model: ${var.ai_model}" echo "Starting Aider using ${var.ai_provider} provider and model: ${var.ai_model}"
tmux new-session -d -s ${var.session_name} -c ${var.folder} "export ${local.env_var_name}=\"${var.ai_api_key}\"; aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\"" tmux new-session -d -s ${var.session_name} -c ${var.folder} "aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\""
echo "Aider task started in tmux session '${var.session_name}'. Check the UI for progress." echo "Aider task started in tmux session '${var.session_name}'. Check the UI for progress."
else else
# Configure tmux for shared sessions # Configure tmux for shared sessions
@ -402,7 +409,7 @@ EOL
fi fi
echo "Starting Aider using ${var.ai_provider} provider and model: ${var.ai_model}" echo "Starting Aider using ${var.ai_provider} provider and model: ${var.ai_model}"
tmux new-session -d -s ${var.session_name} -c ${var.folder} "export ${local.env_var_name}=\"${var.ai_api_key}\"; aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${var.system_prompt}\"" tmux new-session -d -s ${var.session_name} -c ${var.folder} "aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${var.system_prompt}\""
echo "Tmux session '${var.session_name}' started. Access it by clicking the Aider button." echo "Tmux session '${var.session_name}' started. Access it by clicking the Aider button."
fi fi
else else
@ -428,7 +435,6 @@ EOL
screen -U -dmS ${var.session_name} bash -c " screen -U -dmS ${var.session_name} bash -c "
cd ${var.folder} cd ${var.folder}
export PATH=\"$HOME/bin:$HOME/.local/bin:$PATH\" export PATH=\"$HOME/bin:$HOME/.local/bin:$PATH\"
export ${local.env_var_name}=\"${var.ai_api_key}\"
aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\" aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\"
/bin/bash /bin/bash
" "
@ -455,7 +461,6 @@ EOL
screen -U -dmS ${var.session_name} bash -c " screen -U -dmS ${var.session_name} bash -c "
cd ${var.folder} cd ${var.folder}
export PATH=\"$HOME/bin:$HOME/.local/bin:$PATH\" export PATH=\"$HOME/bin:$HOME/.local/bin:$PATH\"
export ${local.env_var_name}=\"${var.ai_api_key}\"
aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\" aider --architect --yes-always ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\"
/bin/bash /bin/bash
" "
@ -489,7 +494,7 @@ resource "coder_app" "aider_cli" {
tmux attach-session -t ${var.session_name} tmux attach-session -t ${var.session_name}
else else
echo "Starting new Aider tmux session..." echo "Starting new Aider tmux session..."
tmux new-session -s ${var.session_name} -c ${var.folder} "export ${local.env_var_name}=\"${var.ai_api_key}\"; aider ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\"; exec bash" tmux new-session -s ${var.session_name} -c ${var.folder} "aider ${local.model_flag} ${var.ai_model} --message \"${local.combined_prompt}\"; exec bash"
fi fi
elif [ "${var.use_screen}" = "true" ]; then elif [ "${var.use_screen}" = "true" ]; then
if ! screen -list | grep -q "${var.session_name}"; then if ! screen -list | grep -q "${var.session_name}"; then
@ -500,7 +505,6 @@ resource "coder_app" "aider_cli" {
else else
cd "${var.folder}" cd "${var.folder}"
echo "Starting Aider directly..." echo "Starting Aider directly..."
export ${local.env_var_name}="${var.ai_api_key}"
aider ${local.model_flag} ${var.ai_model} --message "${local.combined_prompt}" aider ${local.model_flag} ${var.ai_model} --message "${local.combined_prompt}"
fi fi
EOT EOT

View File

@ -72,19 +72,6 @@ data "coder_parameter" "ai_prompt" {
mutable = true mutable = true
} }
# Set the prompt and system prompt for Claude Code via environment variables
resource "coder_agent" "main" {
# ...
env = {
CODER_MCP_CLAUDE_API_KEY = var.anthropic_api_key # or use a coder_parameter
CODER_MCP_CLAUDE_TASK_PROMPT = data.coder_parameter.ai_prompt.value
CODER_MCP_APP_STATUS_SLUG = "claude-code"
CODER_MCP_CLAUDE_SYSTEM_PROMPT = <<-EOT
You are a helpful assistant that can help with code.
EOT
}
}
module "claude-code" { module "claude-code" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/claude-code/coder" source = "registry.coder.com/coder/claude-code/coder"
@ -94,6 +81,13 @@ module "claude-code" {
install_claude_code = true install_claude_code = true
claude_code_version = "0.2.57" claude_code_version = "0.2.57"
# Set API key and prompts directly in the module
claude_api_key = var.anthropic_api_key # or use a coder_parameter
task_prompt = data.coder_parameter.ai_prompt.value
system_prompt = <<-EOT
You are a helpful assistant that can help with code.
EOT
# Enable experimental features # Enable experimental features
experiment_use_screen = true # Or use experiment_use_tmux = true to use tmux instead experiment_use_screen = true # Or use experiment_use_tmux = true to use tmux instead
experiment_report_tasks = true experiment_report_tasks = true

View File

@ -96,11 +96,64 @@ variable "experiment_tmux_session_save_interval" {
default = "15" default = "15"
} }
variable "claude_api_key" {
type = string
description = "Anthropic API key for Claude."
default = ""
sensitive = true
}
variable "task_prompt" {
type = string
description = "Task prompt for Claude Code."
default = ""
}
variable "system_prompt" {
type = string
description = "System prompt for Claude Code."
default = ""
}
variable "app_status_slug" {
type = string
description = "App status slug for Claude Code."
default = "claude-code"
}
locals { locals {
encoded_pre_install_script = var.experiment_pre_install_script != null ? base64encode(var.experiment_pre_install_script) : "" encoded_pre_install_script = var.experiment_pre_install_script != null ? base64encode(var.experiment_pre_install_script) : ""
encoded_post_install_script = var.experiment_post_install_script != null ? base64encode(var.experiment_post_install_script) : "" encoded_post_install_script = var.experiment_post_install_script != null ? base64encode(var.experiment_post_install_script) : ""
} }
# Set environment variables for Claude Code
resource "coder_env" "claude_api_key" {
count = var.claude_api_key != "" ? 1 : 0
agent_id = var.agent_id
name = "CODER_MCP_CLAUDE_API_KEY"
value = var.claude_api_key
}
resource "coder_env" "claude_task_prompt" {
count = var.task_prompt != "" ? 1 : 0
agent_id = var.agent_id
name = "CODER_MCP_CLAUDE_TASK_PROMPT"
value = var.task_prompt
}
resource "coder_env" "claude_system_prompt" {
count = var.system_prompt != "" ? 1 : 0
agent_id = var.agent_id
name = "CODER_MCP_CLAUDE_SYSTEM_PROMPT"
value = var.system_prompt
}
resource "coder_env" "claude_app_status_slug" {
agent_id = var.agent_id
name = "CODER_MCP_APP_STATUS_SLUG"
value = var.app_status_slug
}
# Install and Initialize Claude Code # Install and Initialize Claude Code
resource "coder_script" "claude_code" { resource "coder_script" "claude_code" {
agent_id = var.agent_id agent_id = var.agent_id

View File

@ -66,27 +66,6 @@ data "coder_parameter" "ai_prompt" {
mutable = true mutable = true
} }
# Set the prompt and system prompt for Goose via environment variables
resource "coder_agent" "main" {
# ...
env = {
GOOSE_SYSTEM_PROMPT = <<-EOT
You are a helpful assistant that can help write code.
Run all long running tasks (e.g. npm run dev) in the background and not in the foreground.
Periodically check in on background tasks.
Notify Coder of the status of the task before and after your steps.
EOT
GOOSE_TASK_PROMPT = data.coder_parameter.ai_prompt.value
# An API key is required for experiment_auto_configure
# See https://block.github.io/goose/docs/getting-started/providers
ANTHROPIC_API_KEY = var.anthropic_api_key # or use a coder_parameter
}
}
module "goose" { module "goose" {
count = data.coder_workspace.me.start_count count = data.coder_workspace.me.start_count
source = "registry.coder.com/coder/goose/coder" source = "registry.coder.com/coder/goose/coder"
@ -96,6 +75,19 @@ module "goose" {
install_goose = true install_goose = true
goose_version = "v1.0.16" goose_version = "v1.0.16"
# Set prompts and API key directly in the module
system_prompt = <<-EOT
You are a helpful assistant that can help write code.
Run all long running tasks (e.g. npm run dev) in the background and not in the foreground.
Periodically check in on background tasks.
Notify Coder of the status of the task before and after your steps.
EOT
task_prompt = data.coder_parameter.ai_prompt.value
anthropic_api_key = var.anthropic_api_key # or use a coder_parameter
# Enable experimental features # Enable experimental features
experiment_report_tasks = true experiment_report_tasks = true

View File

@ -114,6 +114,25 @@ variable "experiment_additional_extensions" {
default = null default = null
} }
variable "system_prompt" {
type = string
description = "System prompt for Goose."
default = ""
}
variable "task_prompt" {
type = string
description = "Task prompt for Goose."
default = ""
}
variable "anthropic_api_key" {
type = string
description = "Anthropic API key for Goose."
default = ""
sensitive = true
}
locals { locals {
base_extensions = <<-EOT base_extensions = <<-EOT
coder: coder:
@ -150,6 +169,28 @@ EOT
encoded_post_install_script = var.experiment_post_install_script != null ? base64encode(var.experiment_post_install_script) : "" encoded_post_install_script = var.experiment_post_install_script != null ? base64encode(var.experiment_post_install_script) : ""
} }
# Set environment variables for Goose
resource "coder_env" "goose_system_prompt" {
count = var.system_prompt != "" ? 1 : 0
agent_id = var.agent_id
name = "GOOSE_SYSTEM_PROMPT"
value = var.system_prompt
}
resource "coder_env" "goose_task_prompt" {
count = var.task_prompt != "" ? 1 : 0
agent_id = var.agent_id
name = "GOOSE_TASK_PROMPT"
value = var.task_prompt
}
resource "coder_env" "anthropic_api_key" {
count = var.anthropic_api_key != "" ? 1 : 0
agent_id = var.agent_id
name = "ANTHROPIC_API_KEY"
value = var.anthropic_api_key
}
# Install and Initialize Goose # Install and Initialize Goose
resource "coder_script" "goose" { resource "coder_script" "goose" {
agent_id = var.agent_id agent_id = var.agent_id