Skip to content

Commit b8eb5d4

Browse files
committed
feat: add include_coder_system_prompt variable
1 parent b41d382 commit b8eb5d4

File tree

3 files changed

+113
-24
lines changed

3 files changed

+113
-24
lines changed

registry/coder/modules/claude-code/README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ module "claude-code" {
2626
> [!NOTE]
2727
> By default, this module is configured to run the embedded chat interface as a path-based application. In production, we recommend that you configure a [wildcard access URL](https://coder.com/docs/admin/setup#wildcard-access-url) and set `subdomain = true`. See [here](https://coder.com/docs/tutorials/best-practices/security-best-practices#disable-path-based-apps) for more details.
2828
29+
<!-- TODO(major): remove this note and update the prompt configuration example in the next major release -->
30+
> [!NOTE]
31+
> By default, `include_coder_system_prompt` is false. For proper integration with Coder (tool selection & task reporting),
32+
it is recommended to set `include_coder_system_prompt` to true. In the next major release, this will become the default.
33+
2934
## Prerequisites
3035

3136
- An **Anthropic API key** or a _Claude Session Token_ is required for tasks.
@@ -34,6 +39,26 @@ module "claude-code" {
3439

3540
## Examples
3641

42+
### Prompt configuration (recommended)
43+
44+
Include Coder’s prompt sections and optionally add your own system prompt.
45+
46+
```hcl
47+
module "claude-code" {
48+
source = "registry.coder.com/coder/claude-code/coder"
49+
version = "3.1.0"
50+
agent_id = coder_agent.example.id
51+
workdir = "/home/coder/project"
52+
53+
include_coder_system_prompt = true
54+
55+
# Optional: append additional system prompt.
56+
system_prompt = <<-EOT
57+
Additional organization-specific guidance here.
58+
EOT
59+
}
60+
```
61+
3762
### Usage with Tasks and Advanced Configuration
3863

3964
This example shows how to configure the Claude Code module with an AI prompt, API key shared by all users of the template, and other custom settings.

registry/coder/modules/claude-code/main.tf

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,15 @@ variable "claude_code_oauth_token" {
182182

183183
variable "system_prompt" {
184184
type = string
185-
description = "The additional system prompt to use for the Claude Code server. The module includes mandatory sections inside a <system> block. Leave empty to include only the mandatory sections."
186-
default = ""
185+
description = "The system prompt to use for the Claude Code server."
186+
default = "Send a task status update to notify the user that you are ready for input, and then wait for user input."
187+
}
188+
189+
variable "include_coder_system_prompt" {
190+
type = bool
191+
description = "Include Coder system prompts for proper integration with tool selection and task reporting."
192+
# TODO(major): default to true in the next major release
193+
default = false
187194
}
188195

189196
variable "claude_md_path" {
@@ -230,7 +237,7 @@ locals {
230237
module_dir_name = ".claude-module"
231238
remove_last_session_id_script_b64 = base64encode(file("${path.module}/scripts/remove-last-session-id.sh"))
232239

233-
# Required prompts for the module to properly integrate with coder
240+
# Required prompts for the module to properly integrate with Coder
234241
inner_system_prompt = <<-EOT
235242
-- Tool Selection --
236243
- coder_report_task: providing status updates or requesting user input.
@@ -258,13 +265,13 @@ locals {
258265
details, or encounter blockers
259266
EOT
260267

261-
user_system_prompt = trimspace(try(var.system_prompt, ""))
268+
custom_system_prompt = trimspace(try(var.system_prompt, ""))
262269

263-
final_system_prompt = format(
270+
final_system_prompt = var.include_coder_system_prompt ? format(
264271
"<system>\n%s\n%s\n</system>",
265272
local.inner_system_prompt,
266-
local.user_system_prompt
267-
)
273+
local.custom_system_prompt,
274+
) : local.custom_system_prompt
268275
}
269276

270277
module "agentapi" {

registry/coder/modules/claude-code/main.tftest.hcl

Lines changed: 74 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -188,28 +188,30 @@ run "test_claude_code_permission_mode_validation" {
188188
}
189189
}
190190

191-
run "test_claude_code_system_prompt_omit" {
191+
run "test_claude_code_system_prompt_default" {
192192
command = plan
193193

194194
variables {
195195
agent_id = "test-agent-system-prompt"
196196
workdir = "/home/coder/test"
197-
# system_prompt omitted: default string is used
197+
# system_prompt: default string is used
198+
# include_coder_system_prompt: default is false
198199
}
199200

200201
assert {
201202
condition = trimspace(coder_env.claude_code_system_prompt.value) != ""
202-
error_message = "System prompt must not be empty when omitted"
203+
error_message = "System prompt should not be empty when omitted"
203204
}
204205

205206
assert {
206-
condition = length(regexall("-- Tool Selection --", coder_env.claude_code_system_prompt.value)) > 0
207-
error_message = "Mandatory Tool Selection section missing"
207+
condition = length(regexall("Send a task status update to notify the user that you are ready for input, and then wait for user input.", coder_env.claude_code_system_prompt.value)) > 0
208+
error_message = "System prompt should have default value"
208209
}
209210

211+
# Ensure Coder sections are not injected when include=false
210212
assert {
211-
condition = length(regexall("-- Task Reporting --", coder_env.claude_code_system_prompt.value)) > 0
212-
error_message = "Mandatory Task Reporting section missing"
213+
condition = length(regexall("-- Tool Selection --|-- Task Reporting --", coder_env.claude_code_system_prompt.value)) == 0
214+
error_message = "Coder integration sections should not be present when include_coder_system_prompt is false"
213215
}
214216
}
215217

@@ -220,45 +222,100 @@ run "test_claude_code_system_prompt_empty" {
220222
agent_id = "test-agent-system-prompt"
221223
workdir = "/home/coder/test"
222224
system_prompt = ""
225+
# include_coder_system_prompt: default is false
226+
}
227+
228+
assert {
229+
condition = trimspace(coder_env.claude_code_system_prompt.value) == ""
230+
error_message = "System prompt should be empty"
231+
}
232+
}
233+
234+
run "test_claude_code_system_prompt" {
235+
command = plan
236+
237+
variables {
238+
agent_id = "test-agent-system-prompt"
239+
workdir = "/home/coder/test"
240+
system_prompt = "Custom addition"
241+
# include_coder_system_prompt: default is false
223242
}
224243

225244
assert {
226245
condition = trimspace(coder_env.claude_code_system_prompt.value) != ""
227-
error_message = "System prompt must not be empty when omitted"
246+
error_message = "System prompt should not be empty"
247+
}
248+
249+
assert {
250+
condition = length(regexall("Custom addition", coder_env.claude_code_system_prompt.value)) > 0
251+
error_message = "System prompt should have system_prompt variable value"
252+
}
253+
254+
# Ensure Coder sections are not injected when include=false
255+
assert {
256+
condition = length(regexall("-- Tool Selection --|-- Task Reporting --", coder_env.claude_code_system_prompt.value)) == 0
257+
error_message = "Coder integration sections should not be present when include_coder_system_prompt is false"
258+
}
259+
}
260+
261+
run "test_claude_code_include_coder_system_prompt_and_default_system_prompt" {
262+
command = plan
263+
264+
variables {
265+
agent_id = "test-agent-system-prompt"
266+
workdir = "/home/coder/test"
267+
# system_prompt: default string is used
268+
include_coder_system_prompt = true
269+
}
270+
271+
assert {
272+
condition = trimspace(coder_env.claude_code_system_prompt.value) != ""
273+
error_message = "System prompt should not be empty"
228274
}
229275

230276
assert {
231277
condition = length(regexall("-- Tool Selection --", coder_env.claude_code_system_prompt.value)) > 0
232-
error_message = "Mandatory Tool Selection section missing"
278+
error_message = "System prompt should have Tool Selection section"
233279
}
234280

235281
assert {
236282
condition = length(regexall("-- Task Reporting --", coder_env.claude_code_system_prompt.value)) > 0
237-
error_message = "Mandatory Task Reporting section missing"
283+
error_message = "System prompt should have Task Reporting section"
284+
}
285+
286+
assert {
287+
condition = length(regexall("Send a task status update to notify the user that you are ready for input, and then wait for user input.", coder_env.claude_code_system_prompt.value)) > 0
288+
error_message = "System prompt should have system_prompt variable default value"
238289
}
239290
}
240291

241-
run "test_claude_code_system_prompt" {
292+
run "test_claude_code_include_coder_system_prompt_and_custom_system_prompt" {
242293
command = plan
243294

244295
variables {
245-
agent_id = "test-agent-system-prompt"
246-
workdir = "/home/coder/test"
247-
system_prompt = "Custom addition"
296+
agent_id = "test-agent-system-prompt"
297+
workdir = "/home/coder/test"
298+
system_prompt = "Custom addition"
299+
include_coder_system_prompt = true
248300
}
249301

250302
assert {
251303
condition = trimspace(coder_env.claude_code_system_prompt.value) != ""
252-
error_message = "System prompt must not be empty when omitted"
304+
error_message = "System prompt should not be empty"
253305
}
254306

255307
assert {
256308
condition = length(regexall("-- Tool Selection --", coder_env.claude_code_system_prompt.value)) > 0
257-
error_message = "Mandatory Tool Selection section missing"
309+
error_message = "System prompt should have Tool Selection section"
258310
}
259311

260312
assert {
261313
condition = length(regexall("-- Task Reporting --", coder_env.claude_code_system_prompt.value)) > 0
262-
error_message = "Mandatory Task Reporting section missing"
314+
error_message = "System prompt should have Task Reporting section"
315+
}
316+
317+
assert {
318+
condition = length(regexall("Custom addition", coder_env.claude_code_system_prompt.value)) > 0
319+
error_message = "System prompt should have system_prompt variable value"
263320
}
264321
}

0 commit comments

Comments
 (0)