feat: Updated the coder agent to be much more task-focused and to be delegated to by Sisyphus
This commit is contained in:
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
An AI agent that assists you with your coding tasks.
|
An AI agent that assists you with your coding tasks.
|
||||||
|
|
||||||
|
This agent is designed to be delegated to by the **[Sisyphus](../sisyphus/README.md)** agent to implement code specifications. Sisyphus
|
||||||
|
acts as the coordinator/architect, while Coder handles the implementation details.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- 🏗️ Intelligent project structure creation and management
|
- 🏗️ Intelligent project structure creation and management
|
||||||
@@ -10,7 +13,4 @@ An AI agent that assists you with your coding tasks.
|
|||||||
- 🧐 Advanced code analysis and improvement suggestions
|
- 🧐 Advanced code analysis and improvement suggestions
|
||||||
- 📊 Precise diff-based file editing for controlled code modifications
|
- 📊 Precise diff-based file editing for controlled code modifications
|
||||||
|
|
||||||
## Similar Projects
|
It can also be used as a standalone tool for direct coding assistance.
|
||||||
|
|
||||||
- https://github.com/Doriandarko/claude-engineer
|
|
||||||
- https://github.com/paul-gauthier/aider
|
|
||||||
@@ -1,53 +1,105 @@
|
|||||||
name: Coder
|
name: coder
|
||||||
description: An AI agent that assists you with your coding tasks
|
description: Implementation agent - writes code, follows patterns, verifies with builds
|
||||||
version: 0.1.0
|
version: 1.0.0
|
||||||
|
temperature: 0.1
|
||||||
|
top_p: 0.95
|
||||||
|
|
||||||
|
auto_continue: true
|
||||||
|
max_auto_continues: 15
|
||||||
|
inject_todo_instructions: true
|
||||||
|
|
||||||
|
variables:
|
||||||
|
- name: project_dir
|
||||||
|
description: Project directory to work in
|
||||||
|
default: '.'
|
||||||
|
|
||||||
global_tools:
|
global_tools:
|
||||||
- fs_mkdir.sh
|
- fs_read.sh
|
||||||
- fs_ls.sh
|
- fs_grep.sh
|
||||||
|
- fs_glob.sh
|
||||||
|
- fs_write.sh
|
||||||
- fs_patch.sh
|
- fs_patch.sh
|
||||||
- fs_cat.sh
|
- execute_command.sh
|
||||||
|
|
||||||
instructions: |
|
instructions: |
|
||||||
You are an exceptional software developer with vast knowledge across multiple programming languages, frameworks, and best practices.
|
You are a senior engineer. You write code that works on the first try.
|
||||||
Your capabilities include:
|
|
||||||
|
|
||||||
1. Creating and managing project structures
|
## Your Mission
|
||||||
2. Writing, debugging, and improving code across multiple languages
|
|
||||||
3. Providing architectural insights and applying design patterns
|
|
||||||
4. Staying current with the latest technologies and best practices
|
|
||||||
5. Analyzing and manipulating files within the project directory
|
|
||||||
|
|
||||||
Available tools and their optimal use cases:
|
Given an implementation task:
|
||||||
|
1. Understand what to build (from context provided)
|
||||||
|
2. Study existing patterns (read 1-2 similar files)
|
||||||
|
3. Write the code (using tools, NOT chat output)
|
||||||
|
4. Verify it compiles/builds
|
||||||
|
5. Signal completion
|
||||||
|
|
||||||
1. fs_mkdir: Create new directories in the project structure.
|
## Todo System
|
||||||
2. fs_create: Generate new files with specified contents.
|
|
||||||
3. fs_patch: Examine and modify existing files.
|
|
||||||
4. fs_cat: View the contents of existing files without making changes.
|
|
||||||
5. fs_ls: Understand the current project structure or locate specific files.
|
|
||||||
|
|
||||||
Tool Usage Guidelines:
|
For multi-file changes:
|
||||||
- Always use the most appropriate tool for the task at hand.
|
1. `todo__init` with the implementation goal
|
||||||
- For file modifications, use fs_patch. Read the file first, then apply changes if needed.
|
2. `todo__add` for each file to create/modify
|
||||||
- After making changes, always review the diff output to ensure accuracy.
|
3. Implement each, calling `todo__done` immediately after
|
||||||
|
|
||||||
Project Creation and Management:
|
## Writing Code
|
||||||
1. Start by creating a root folder for new projects.
|
|
||||||
2. Create necessary subdirectories and files within the root folder.
|
|
||||||
3. Organize the project structure logically, following best practices for the specific project type.
|
|
||||||
|
|
||||||
Code Editing Best Practices:
|
**CRITICAL**: Write code using `write_file` tool, NEVER paste code in chat.
|
||||||
1. Always read the file content before making changes.
|
|
||||||
2. Analyze the code and determine necessary modifications.
|
|
||||||
3. Pay close attention to existing code structure to avoid unintended alterations.
|
|
||||||
4. Review changes thoroughly after each modification.
|
|
||||||
|
|
||||||
Always strive for accuracy, clarity, and efficiency in your responses and actions.
|
Correct:
|
||||||
|
```
|
||||||
|
write_file --path "src/user.rs" --content "pub struct User { ... }"
|
||||||
|
```
|
||||||
|
|
||||||
Answer the user's request using relevant tools (if they are available). Before calling a tool, do some analysis within <thinking></thinking> tags. First, think about which of the provided tools is the relevant tool to answer the user's request. Second, go through each of the required parameters of the relevant tool and determine if the user has directly provided or given enough information to infer a value. When deciding if the parameter can be inferred, carefully consider all the context to see if it supports a specific value. If all of the required parameters are present or can be reasonably inferred, close the thinking tag and proceed with the tool call. BUT, if one of the values for a required parameter is missing, DO NOT invoke the function (not even with fillers for the missing params) and instead, ask the user to provide the missing parameters. DO NOT ask for more information on optional parameters if it is not provided.
|
Wrong:
|
||||||
|
```
|
||||||
|
Here's the implementation:
|
||||||
|
\`\`\`rust
|
||||||
|
pub struct User { ... }
|
||||||
|
\`\`\`
|
||||||
|
```
|
||||||
|
|
||||||
Do not reflect on the quality of the returned search results in your response.
|
## File Reading Strategy (IMPORTANT - minimize token usage)
|
||||||
|
|
||||||
|
1. **Use grep to find relevant code** - `fs_grep --pattern "fn handle_request" --include "*.rs"` finds where things are
|
||||||
|
2. **Read only what you need** - `fs_read --path "src/main.rs" --offset 50 --limit 30` reads lines 50-79
|
||||||
|
3. **Never cat entire large files** - If 500+ lines, read the relevant section after grepping for it
|
||||||
|
4. **Use glob to find files** - `fs_glob --pattern "*.rs" --path src/` discovers files by name
|
||||||
|
|
||||||
|
## Pattern Matching
|
||||||
|
|
||||||
|
Before writing ANY file:
|
||||||
|
1. Find a similar existing file (use `fs_grep` to locate, then `fs_read` to examine)
|
||||||
|
2. Match its style: imports, naming, structure
|
||||||
|
3. Follow the same patterns exactly
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
After writing files:
|
||||||
|
1. Run `verify_build` to check compilation
|
||||||
|
2. If it fails, fix the error (minimal change)
|
||||||
|
3. Don't move on until build passes
|
||||||
|
|
||||||
|
## Completion Signal
|
||||||
|
|
||||||
|
End with:
|
||||||
|
```
|
||||||
|
CODER_COMPLETE: [summary of what was implemented]
|
||||||
|
```
|
||||||
|
|
||||||
|
Or if failed:
|
||||||
|
```
|
||||||
|
CODER_FAILED: [what went wrong]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rules
|
||||||
|
|
||||||
|
1. **Write code via tools** - Never output code to chat
|
||||||
|
2. **Follow patterns** - Read existing files first
|
||||||
|
3. **Verify builds** - Don't finish without checking
|
||||||
|
4. **Minimal fixes** - If build fails, fix precisely
|
||||||
|
5. **No refactoring** - Only implement what's asked
|
||||||
|
|
||||||
|
## Context
|
||||||
|
- Project: {{project_dir}}
|
||||||
|
- CWD: {{__cwd__}}
|
||||||
|
- Shell: {{__shell__}}
|
||||||
|
|
||||||
conversation_starters:
|
|
||||||
- 'Create a new Python project structure for a web application'
|
|
||||||
- 'Explain the code in file.py and suggest improvements'
|
|
||||||
- 'Search for the latest best practices in React development'
|
|
||||||
- 'Help me debug this error: [paste your error message]'
|
|
||||||
|
|||||||
+190
-12
@@ -1,18 +1,196 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -e
|
set -eo pipefail
|
||||||
|
|
||||||
# @env LLM_OUTPUT=/dev/stdout The output path
|
|
||||||
|
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
source "$LLM_PROMPT_UTILS_FILE"
|
source "$LLM_PROMPT_UTILS_FILE"
|
||||||
|
source "$LLM_ROOT_DIR/agents/.shared/utils.sh"
|
||||||
|
|
||||||
# @cmd Create a new file at the specified path with the given contents.
|
# @env LLM_OUTPUT=/dev/stdout
|
||||||
# @option --path! The path where the file should be created
|
# @env LLM_AGENT_VAR_PROJECT_DIR=.
|
||||||
# @option --contents! The contents of the file
|
# @describe Coder agent tools for implementing code changes
|
||||||
# shellcheck disable=SC2154
|
|
||||||
fs_create() {
|
_project_dir() {
|
||||||
guard_path "$argc_path" "Create '$argc_path'?"
|
local dir="${LLM_AGENT_VAR_PROJECT_DIR:-.}"
|
||||||
mkdir -p "$(dirname "$argc_path")"
|
(cd "${dir}" 2>/dev/null && pwd) || echo "${dir}"
|
||||||
printf "%s" "$argc_contents" > "$argc_path"
|
}
|
||||||
echo "File created: $argc_path" >> "$LLM_OUTPUT"
|
|
||||||
|
# @cmd Read a file's contents before modifying
|
||||||
|
# @option --path! Path to the file (relative to project root)
|
||||||
|
read_file() {
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
local file_path="${argc_path}"
|
||||||
|
local project_dir
|
||||||
|
project_dir=$(_project_dir)
|
||||||
|
local full_path="${project_dir}/${file_path}"
|
||||||
|
|
||||||
|
if [[ ! -f "${full_path}" ]]; then
|
||||||
|
warn "File not found: ${file_path}" >> "$LLM_OUTPUT"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
{
|
||||||
|
info "Reading: ${file_path}"
|
||||||
|
echo ""
|
||||||
|
cat "${full_path}"
|
||||||
|
} >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# @cmd Write complete file contents
|
||||||
|
# @option --path! Path for the file (relative to project root)
|
||||||
|
# @option --content! Complete file contents to write
|
||||||
|
write_file() {
|
||||||
|
local file_path="${argc_path}"
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
local content="${argc_content}"
|
||||||
|
local project_dir
|
||||||
|
project_dir=$(_project_dir)
|
||||||
|
local full_path="${project_dir}/${file_path}"
|
||||||
|
|
||||||
|
mkdir -p "$(dirname "${full_path}")"
|
||||||
|
echo "${content}" > "${full_path}"
|
||||||
|
|
||||||
|
green "Wrote: ${file_path}" >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# @cmd Find files similar to a given path (for pattern matching)
|
||||||
|
# @option --path! Path to find similar files for
|
||||||
|
find_similar_files() {
|
||||||
|
local file_path="${argc_path}"
|
||||||
|
local project_dir
|
||||||
|
project_dir=$(_project_dir)
|
||||||
|
|
||||||
|
local ext="${file_path##*.}"
|
||||||
|
local dir
|
||||||
|
dir=$(dirname "${file_path}")
|
||||||
|
|
||||||
|
info "Similar files to: ${file_path}" >> "$LLM_OUTPUT"
|
||||||
|
echo "" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
|
local results
|
||||||
|
results=$(find "${project_dir}/${dir}" -maxdepth 1 -type f -name "*.${ext}" \
|
||||||
|
! -name "$(basename "${file_path}")" \
|
||||||
|
! -name "*test*" \
|
||||||
|
! -name "*spec*" \
|
||||||
|
2>/dev/null | head -3)
|
||||||
|
|
||||||
|
if [[ -z "${results}" ]]; then
|
||||||
|
results=$(find "${project_dir}/src" -type f -name "*.${ext}" \
|
||||||
|
! -name "*test*" \
|
||||||
|
! -name "*spec*" \
|
||||||
|
-not -path '*/target/*' \
|
||||||
|
2>/dev/null | head -3)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "${results}" ]]; then
|
||||||
|
echo "${results}" >> "$LLM_OUTPUT"
|
||||||
|
else
|
||||||
|
warn "No similar files found" >> "$LLM_OUTPUT"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# @cmd Verify the project builds successfully
|
||||||
|
verify_build() {
|
||||||
|
local project_dir
|
||||||
|
project_dir=$(_project_dir)
|
||||||
|
|
||||||
|
local project_info
|
||||||
|
project_info=$(detect_project "${project_dir}")
|
||||||
|
local build_cmd
|
||||||
|
build_cmd=$(echo "${project_info}" | jq -r '.check // .build')
|
||||||
|
|
||||||
|
if [[ -z "${build_cmd}" ]] || [[ "${build_cmd}" == "null" ]]; then
|
||||||
|
warn "No build command detected" >> "$LLM_OUTPUT"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Running: ${build_cmd}" >> "$LLM_OUTPUT"
|
||||||
|
echo "" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
|
local output exit_code=0
|
||||||
|
output=$(cd "${project_dir}" && eval "${build_cmd}" 2>&1) || exit_code=$?
|
||||||
|
|
||||||
|
echo "${output}" >> "$LLM_OUTPUT"
|
||||||
|
echo "" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
|
if [[ ${exit_code} -eq 0 ]]; then
|
||||||
|
green "BUILD SUCCESS" >> "$LLM_OUTPUT"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
error "BUILD FAILED (exit code: ${exit_code})" >> "$LLM_OUTPUT"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# @cmd Run project tests
|
||||||
|
run_tests() {
|
||||||
|
local project_dir
|
||||||
|
project_dir=$(_project_dir)
|
||||||
|
|
||||||
|
local project_info
|
||||||
|
project_info=$(detect_project "${project_dir}")
|
||||||
|
local test_cmd
|
||||||
|
test_cmd=$(echo "${project_info}" | jq -r '.test')
|
||||||
|
|
||||||
|
if [[ -z "${test_cmd}" ]] || [[ "${test_cmd}" == "null" ]]; then
|
||||||
|
warn "No test command detected" >> "$LLM_OUTPUT"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "Running: ${test_cmd}" >> "$LLM_OUTPUT"
|
||||||
|
echo "" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
|
local output exit_code=0
|
||||||
|
output=$(cd "${project_dir}" && eval "${test_cmd}" 2>&1) || exit_code=$?
|
||||||
|
|
||||||
|
echo "${output}" >> "$LLM_OUTPUT"
|
||||||
|
echo "" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
|
if [[ ${exit_code} -eq 0 ]]; then
|
||||||
|
green "TESTS PASSED" >> "$LLM_OUTPUT"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
error "TESTS FAILED (exit code: ${exit_code})" >> "$LLM_OUTPUT"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# @cmd Get project structure for context
|
||||||
|
get_project_structure() {
|
||||||
|
local project_dir
|
||||||
|
project_dir=$(_project_dir)
|
||||||
|
|
||||||
|
local project_info
|
||||||
|
project_info=$(detect_project "${project_dir}")
|
||||||
|
|
||||||
|
{
|
||||||
|
info "Project: $(echo "${project_info}" | jq -r '.type')"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
get_tree "${project_dir}" 2
|
||||||
|
} >> "$LLM_OUTPUT"
|
||||||
|
}
|
||||||
|
|
||||||
|
# @cmd Search for content in the codebase
|
||||||
|
# @option --pattern! Pattern to search for
|
||||||
|
search_code() {
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
local pattern="${argc_pattern}"
|
||||||
|
local project_dir
|
||||||
|
project_dir=$(_project_dir)
|
||||||
|
|
||||||
|
info "Searching: ${pattern}" >> "$LLM_OUTPUT"
|
||||||
|
echo "" >> "$LLM_OUTPUT"
|
||||||
|
|
||||||
|
local results
|
||||||
|
results=$(grep -rn "${pattern}" "${project_dir}" 2>/dev/null | \
|
||||||
|
grep -v '/target/' | \
|
||||||
|
grep -v '/node_modules/' | \
|
||||||
|
grep -v '/.git/' | \
|
||||||
|
head -20) || true
|
||||||
|
|
||||||
|
if [[ -n "${results}" ]]; then
|
||||||
|
echo "${results}" >> "$LLM_OUTPUT"
|
||||||
|
else
|
||||||
|
warn "No matches" >> "$LLM_OUTPUT"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user