370 lines
11 KiB
YAML
370 lines
11 KiB
YAML
name: coder
|
|
description: |
|
|
Implementation agent. Plans, implements, and runs build + tests in a
|
|
bounded fix-loop until verified. Designed to be delegated to by sisyphus.
|
|
version: "1.0"
|
|
|
|
global_tools:
|
|
- fs_cat.sh
|
|
- fs_ls.sh
|
|
- fs_write.sh
|
|
- fs_patch.sh
|
|
- execute_command.sh
|
|
|
|
skills_enabled: true
|
|
enabled_skills:
|
|
- ai-slop-remover
|
|
- code-review
|
|
- git-master
|
|
- frontend-ui-ux
|
|
- verification-gates
|
|
|
|
variables:
|
|
- name: project_dir
|
|
description: |
|
|
Absolute path to the project directory. Defaults to "." which is the
|
|
directory you invoked `coyote` from. Override at runtime with
|
|
`coyote -a coder --agent-variable project_dir /abs/path "..."`.
|
|
default: "."
|
|
|
|
settings:
|
|
max_loop_iterations: 20
|
|
log_state_snapshots: true
|
|
validate_before_run: true
|
|
timeout: 1800
|
|
|
|
initial_state:
|
|
project_dir: ""
|
|
fix_attempts: 0
|
|
max_fix_attempts: 3
|
|
fix_instructions: ""
|
|
build_output: ""
|
|
tests_output: ""
|
|
last_node_output: ""
|
|
plan_summary: ""
|
|
files_to_modify: []
|
|
files_to_create: []
|
|
risks: []
|
|
complexity_score: 0
|
|
review_attempts: 0
|
|
max_review_attempts: 1
|
|
review_clean: true
|
|
review_notes: ""
|
|
|
|
start: resolve_paths
|
|
|
|
nodes:
|
|
resolve_paths:
|
|
id: resolve_paths
|
|
type: script
|
|
description: Resolve project_dir to an absolute path from the agent variable
|
|
script: scripts/resolve_paths.sh
|
|
timeout: 5
|
|
fallback: end_failure
|
|
|
|
analyze_request:
|
|
id: analyze_request
|
|
type: llm
|
|
description: Extract a structured plan and complexity score from the orchestrator's prompt
|
|
instructions: |
|
|
You are a senior engineer's planning assistant. Read the orchestrator's
|
|
request and emit a structured plan. You only plan. You never edit files.
|
|
|
|
Score complexity from 1 to 10:
|
|
1-3: trivial - single file, <=20 lines changed, obvious approach
|
|
4-6: moderate - 2-5 files, clear approach, some pattern matching
|
|
7-10: complex - multi-component, ambiguous tradeoffs, refactoring,
|
|
or wide blast radius
|
|
|
|
Be specific in `files_to_modify` and `files_to_create`. All paths
|
|
MUST be absolute. The project root is {{project_dir}}. Prefer paths
|
|
like "{{project_dir}}/src/foo.rs" over "src/foo.rs". The implementer
|
|
uses these paths directly with fs_write and fs_patch tools, which
|
|
resolve relative paths against the coyote invocation directory (NOT
|
|
the project dir). Empty arrays are fine if no files in that category.
|
|
|
|
`risks` is a list of short strings. Anything that could derail the
|
|
implementation: unknown dependencies, brittle tests, blast radius,
|
|
etc. Empty list is fine.
|
|
|
|
Project directory: {{project_dir}}
|
|
prompt: "{{initial_prompt}}"
|
|
tools: []
|
|
output_schema:
|
|
type: object
|
|
properties:
|
|
plan_summary:
|
|
type: string
|
|
description: 1-3 sentences summarizing what will be done
|
|
files_to_modify:
|
|
type: array
|
|
items: {type: string}
|
|
files_to_create:
|
|
type: array
|
|
items: {type: string}
|
|
complexity_score:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 10
|
|
risks:
|
|
type: array
|
|
items: {type: string}
|
|
required: [plan_summary, files_to_modify, files_to_create, complexity_score, risks]
|
|
state_updates:
|
|
last_node_output: "{{output}}"
|
|
fallback: end_failure
|
|
next: route_complexity
|
|
|
|
route_complexity:
|
|
id: route_complexity
|
|
type: script
|
|
description: Route to approval gate for complex plans; skip otherwise
|
|
script: scripts/route_complexity.sh
|
|
timeout: 5
|
|
fallback: implement
|
|
|
|
gate_approval:
|
|
id: gate_approval
|
|
type: approval
|
|
description: Optional human checkpoint for high-complexity plans
|
|
question: |
|
|
## Plan
|
|
{{plan_summary}}
|
|
|
|
## Files to modify
|
|
{{files_to_modify}}
|
|
|
|
## Files to create
|
|
{{files_to_create}}
|
|
|
|
## Risks
|
|
{{risks}}
|
|
|
|
Complexity: {{complexity_score}}/10
|
|
|
|
Approve this plan?
|
|
options:
|
|
- "yes"
|
|
- "no"
|
|
routes:
|
|
"yes": implement
|
|
"no": end_rejected
|
|
on_other: end_rejected
|
|
|
|
implement:
|
|
id: implement
|
|
type: llm
|
|
description: Write code via fs tools. Bounded tool-call loop.
|
|
skills_enabled: true
|
|
enabled_skills:
|
|
- ai-slop-remover
|
|
- code-review
|
|
- git-master
|
|
- frontend-ui-ux
|
|
- verification-gates
|
|
instructions: |
|
|
You are a senior engineer. Implement the plan by writing code via
|
|
tools. Follow existing patterns in the codebase.
|
|
|
|
## Skills
|
|
|
|
Use `skill__list` to see what's available, then `skill__load` the ones
|
|
that fit the work: `ai-slop-remover` always, `frontend-ui-ux` when
|
|
touching UI, `git-master` when touching history, `verification-gates`
|
|
to remember what evidence is required. Unload when a phase ends.
|
|
|
|
## Writing code
|
|
|
|
1. Use `fs_patch` for surgical edits to existing files.
|
|
2. Use `fs_write` for new files or full rewrites.
|
|
3. NEVER output code to chat. Always use tools.
|
|
4. ALWAYS pass ABSOLUTE paths to fs_write and fs_patch. Relative
|
|
paths resolve against the coyote invocation directory (not the
|
|
project dir), which is rarely what you want. The project root
|
|
is {{project_dir}}.
|
|
|
|
## File reading
|
|
|
|
1. Use `execute_command` to grep/find:
|
|
`execute_command --command "grep -rn 'fn handle_request' --include='*.rs' ."`
|
|
`execute_command --command "find . -name '*.rs' -not -path '*/target/*'"`
|
|
2. Read only what you need:
|
|
`fs_cat --path "src/main.rs" --offset 50 --limit 30`
|
|
3. Never read entire large files. Use offset/limit.
|
|
4. Use `fs_ls` to list directory contents.
|
|
|
|
## Pattern matching
|
|
|
|
Before writing ANY file:
|
|
1. Find a similar existing file (grep, then read).
|
|
2. Match its style: imports, naming, structure, error handling.
|
|
3. Follow the same patterns exactly. Do not invent new ones.
|
|
|
|
## Fix loop
|
|
|
|
If the "Fix loop status" section in your user prompt is non-empty,
|
|
the previous attempt failed verification. Read the error, identify
|
|
the minimal fix, apply it. Do not refactor while fixing.
|
|
|
|
## Rules
|
|
|
|
1. Match existing patterns - read examples first.
|
|
2. Minimal changes - implement only what's asked.
|
|
3. Never suppress errors (`as any`, `@ts-ignore`, `#[allow(...)]`
|
|
on unfamiliar lints, etc.).
|
|
4. No dead code, no commented-out blocks, no premature abstractions.
|
|
5. End your turn when editing is done. The graph runs verification next.
|
|
|
|
Project directory: {{project_dir}}
|
|
prompt: |
|
|
## Plan summary
|
|
{{plan_summary}}
|
|
|
|
## Files involved
|
|
- Modify: {{files_to_modify}}
|
|
- Create: {{files_to_create}}
|
|
|
|
## Original request from the orchestrator
|
|
{{initial_prompt}}
|
|
|
|
## Fix loop status
|
|
{{fix_instructions}}
|
|
tools:
|
|
- fs_cat
|
|
- fs_ls
|
|
- fs_write
|
|
- fs_patch
|
|
- execute_command
|
|
max_iterations: 30
|
|
state_updates:
|
|
last_node_output: "{{output}}"
|
|
fallback: end_failure
|
|
next: verify_build
|
|
|
|
verify_build:
|
|
id: verify_build
|
|
type: script
|
|
description: Run the project's check/build command. Routes to verify_tests on success, fix_loop_gate on failure.
|
|
script: scripts/verify_build.sh
|
|
timeout: 300
|
|
fallback: fix_loop_gate
|
|
|
|
verify_tests:
|
|
id: verify_tests
|
|
type: script
|
|
description: Run the project's test command. Routes to end_success on pass, fix_loop_gate on failure.
|
|
script: scripts/verify_tests.sh
|
|
timeout: 600
|
|
fallback: fix_loop_gate
|
|
|
|
fix_loop_gate:
|
|
id: fix_loop_gate
|
|
type: script
|
|
description: Budget gate. Loops back to implement with fix_instructions populated, or terminates as end_failure.
|
|
script: scripts/fix_loop_gate.sh
|
|
timeout: 5
|
|
fallback: end_failure
|
|
|
|
self_review:
|
|
id: self_review
|
|
type: llm
|
|
description: Skill-driven self-review of the diff. Catches AI slop, dishonest naming, suppressed errors. Bounded to max_review_attempts.
|
|
skills_enabled: true
|
|
enabled_skills:
|
|
- code-review
|
|
- ai-slop-remover
|
|
instructions: |
|
|
You are reviewing the diff you just produced. Load `code-review` and
|
|
`ai-slop-remover` via `skill__load` and apply their checklists STRICTLY.
|
|
|
|
Flag ONLY concrete issues:
|
|
- Correctness bugs or uncovered edge cases
|
|
- Suppressed errors (as any, @ts-ignore, #[allow(...)] on unfamiliar
|
|
lints, empty catch blocks)
|
|
- Dishonest naming (get_X that mutates, returns wrong type, etc.)
|
|
- Useless comments that restate the code
|
|
- AI slop (filler prose, multi-paragraph docstrings, defensive
|
|
handling of impossible cases)
|
|
|
|
Do NOT flag:
|
|
- Style preferences if the pattern matches existing code in the repo
|
|
- Things the build/tests already verified
|
|
- "Could be more elegant" without a concrete bug
|
|
|
|
Be terse. The orchestrator wants signal, not noise. If you find nothing
|
|
blocking, set review_clean=true and leave review_notes empty.
|
|
|
|
Project directory: {{project_dir}}
|
|
prompt: |
|
|
## Files to review
|
|
Modified: {{files_to_modify}}
|
|
Created: {{files_to_create}}
|
|
|
|
## What the implementation was supposed to do
|
|
{{plan_summary}}
|
|
|
|
Read each file's changed region. Apply the review skills. Output your verdict.
|
|
tools:
|
|
- fs_cat
|
|
- fs_ls
|
|
- execute_command
|
|
max_iterations: 15
|
|
output_schema:
|
|
type: object
|
|
properties:
|
|
review_clean:
|
|
type: boolean
|
|
description: True if no blocker issues were found.
|
|
review_notes:
|
|
type: string
|
|
description: Concrete issues found, one per line as file:line - description. Empty when review_clean is true.
|
|
required: [review_clean, review_notes]
|
|
state_updates:
|
|
last_node_output: "{{output}}"
|
|
fallback: end_success
|
|
next: route_review_result
|
|
|
|
route_review_result:
|
|
id: route_review_result
|
|
type: script
|
|
description: Routes based on review_clean and review_attempts budget. End on clean or budget exhausted; loop to implement otherwise.
|
|
script: scripts/route_review_result.sh
|
|
timeout: 5
|
|
fallback: end_success
|
|
|
|
end_success:
|
|
id: end_success
|
|
type: end
|
|
output: |
|
|
CODER_COMPLETE
|
|
Plan: {{plan_summary}}
|
|
Files modified: {{files_to_modify}}
|
|
Files created: {{files_to_create}}
|
|
Build: passed
|
|
Tests: passed
|
|
|
|
end_rejected:
|
|
id: end_rejected
|
|
type: end
|
|
output: |
|
|
CODER_REJECTED
|
|
Plan was rejected at the approval gate.
|
|
Plan: {{plan_summary}}
|
|
|
|
end_failure:
|
|
id: end_failure
|
|
type: end
|
|
output: |
|
|
CODER_FAILED
|
|
Plan: {{plan_summary}}
|
|
Attempts: {{fix_attempts}}/{{max_fix_attempts}}
|
|
|
|
Last node output:
|
|
{{last_node_output}}
|
|
|
|
Last build output:
|
|
{{build_output}}
|
|
|
|
Last tests output:
|
|
{{tests_output}}
|