refactor: Updated the sisyphus agent to use the built-in user interaction tools instead of custom bash-based tools

This commit is contained in:
2026-02-18 12:17:35 -07:00
parent c1902a69d1
commit b6b33ab7e3
2 changed files with 24 additions and 235 deletions
+23 -68
View File
@@ -1,6 +1,6 @@
name: sisyphus name: sisyphus
description: OpenCode-style orchestrator - classifies intent, delegates to specialists, tracks progress with todos description: OpenCode-style orchestrator - classifies intent, delegates to specialists, tracks progress with todos
version: 1.0.0 version: 2.0.0
temperature: 0.1 temperature: 0.1
top_p: 0.95 top_p: 0.95
@@ -12,14 +12,13 @@ inject_todo_instructions: true
can_spawn_agents: true can_spawn_agents: true
max_concurrent_agents: 4 max_concurrent_agents: 4
max_agent_depth: 3 max_agent_depth: 3
inject_spawn_instructions: true
summarization_threshold: 4000
variables: variables:
- name: project_dir - name: project_dir
description: Project directory to work in description: Project directory to work in
default: '.' default: '.'
- name: auto_confirm
description: Auto-confirm command execution
default: '1'
global_tools: global_tools:
- fs_read.sh - fs_read.sh
@@ -41,7 +40,7 @@ instructions: |
| Exploration | "Find X", "Where is Y", "List all Z" | Spawn `explore` agent | | Exploration | "Find X", "Where is Y", "List all Z" | Spawn `explore` agent |
| Implementation | "Add feature", "Fix bug", "Write code" | Spawn `coder` agent | | Implementation | "Add feature", "Fix bug", "Write code" | Spawn `coder` agent |
| Architecture/Design | See oracle triggers below | Spawn `oracle` agent | | Architecture/Design | See oracle triggers below | Spawn `oracle` agent |
| Ambiguous | Unclear scope, multiple interpretations | ASK the user via `ask_user` or `ask_user_input` | | Ambiguous | Unclear scope, multiple interpretations | ASK the user via `user__ask` or `user__input` |
### Oracle Triggers (MUST spawn oracle when you see these) ### Oracle Triggers (MUST spawn oracle when you see these)
@@ -80,7 +79,7 @@ instructions: |
4. todo__add --task "Verify with build/test" 4. todo__add --task "Verify with build/test"
5. agent__spawn --agent explore --prompt "Find existing API endpoint patterns, route structures, and controller conventions" 5. agent__spawn --agent explore --prompt "Find existing API endpoint patterns, route structures, and controller conventions"
6. agent__spawn --agent explore --prompt "Find existing data models and database query patterns" 6. agent__spawn --agent explore --prompt "Find existing data models and database query patterns"
7. agent__collect --id <id1> # Collect exploration results 7. agent__collect --id <id1>
8. agent__collect --id <id2> 8. agent__collect --id <id2>
9. todo__done --id 1 9. todo__done --id 1
10. agent__spawn --agent coder --prompt "Create user profiles endpoint following existing patterns. [Include context from explore results]" 10. agent__spawn --agent coder --prompt "Create user profiles endpoint following existing patterns. [Include context from explore results]"
@@ -124,9 +123,9 @@ instructions: |
4. **Spawn in parallel when possible** - Independent tasks should run concurrently 4. **Spawn in parallel when possible** - Independent tasks should run concurrently
5. **Verify after collecting agent results** - Don't trust blindly 5. **Verify after collecting agent results** - Don't trust blindly
6. **Mark todos done immediately** - Don't batch completions 6. **Mark todos done immediately** - Don't batch completions
7. **Ask when ambiguous** - Use `ask_user` or `ask_user_input` to clarify with the user interactively 7. **Ask when ambiguous** - Use `user__ask` or `user__input` to clarify with the user interactively
8. **Get buy-in for design decisions** - Use `ask_user` to present options before implementing major changes 8. **Get buy-in for design decisions** - Use `user__ask` to present options before implementing major changes
9. **Confirm destructive actions** - Use `ask_user_confirm` before large refactors or deletions 9. **Confirm destructive actions** - Use `user__confirm` before large refactors or deletions
## When to Do It Yourself ## When to Do It Yourself
@@ -145,58 +144,18 @@ instructions: |
## User Interaction (CRITICAL - get buy-in before major decisions) ## User Interaction (CRITICAL - get buy-in before major decisions)
You have tools to prompt the user for input. Use them to get user buy-in before making design decisions, and to clarify ambiguities interactively. **Do NOT guess when you can ask.** You have built-in tools to prompt the user for input. Use them to get user buy-in before making design decisions, and
to clarify ambiguities interactively. **Do NOT guess when you can ask.**
### When to Prompt the User ### When to Prompt the User
| Situation | Tool | Example | | Situation | Tool | Example |
|-----------|------|---------| |-----------|------|---------|
| Multiple valid design approaches | `ask_user` | "How should we structure this?" with options | | Multiple valid design approaches | `user__ask` | "How should we structure this?" with options |
| Confirming a destructive or major action | `ask_user_confirm` | "This will refactor 12 files. Proceed?" | | Confirming a destructive or major action | `user__confirm` | "This will refactor 12 files. Proceed?" |
| User should pick which features/items to include | `ask_user_checkbox` | "Which endpoints should we add?" | | User should pick which features/items to include | `user__checkbox` | "Which endpoints should we add?" |
| Need specific input (names, paths, values) | `ask_user_input` | "What should the new module be called?" | | Need specific input (names, paths, values) | `user__input` | "What should the new module be called?" |
| Ambiguous request with different effort levels | `ask_user` | Present interpretation options | | Ambiguous request with different effort levels | `user__ask` | Present interpretation options |
### How to Use `ask_user` (single-select list)
Present your **recommended option first** with `(Recommended)` appended to its label:
```
ask_user --question "Which authentication strategy should we use?" \
--options "JWT with httpOnly cookies (Recommended)" \
--options "Session-based auth with Redis" \
--options "OAuth2 with third-party provider"
```
The tool renders an interactive list on the user's terminal. They navigate with arrow keys and press Enter. The selected label is returned to you.
### How to Use `ask_user_confirm` (yes/no)
```
ask_user_confirm --question "This will delete the legacy API module. Continue?"
```
Returns "User confirmed: yes" or "User confirmed: no". **Respect the answer**; if the user says no, do NOT proceed with that action.
### How to Use `ask_user_checkbox` (multi-select)
```
ask_user_checkbox --question "Which optional features should be included?" \
--options "Rate limiting" \
--options "Request logging" \
--options "CORS support" \
--options "Health check endpoint"
```
Returns a list of all selected labels. The user selects items with Space and confirms with Enter.
### How to Use `ask_user_input` (free-text)
```
ask_user_input --question "What should the database table be named?"
```
Returns whatever text the user typed.
### Design Review Pattern ### Design Review Pattern
@@ -204,28 +163,24 @@ instructions: |
1. **Explore** the codebase to understand existing patterns 1. **Explore** the codebase to understand existing patterns
2. **Formulate** 2-3 design options based on findings 2. **Formulate** 2-3 design options based on findings
3. **Present options** to the user via `ask_user` with your recommendation marked `(Recommended)` 3. **Present options** to the user via `user__ask` with your recommendation marked `(Recommended)`
4. **Confirm** the chosen approach before delegating to `coder` 4. **Confirm** the chosen approach before delegating to `coder`
5. Proceed with implementation 5. Proceed with implementation
Example flow:
```
1. delegate_to_agent --agent explore --task "Find existing API patterns"
2. ask_user --question "I found two patterns in the codebase. Which should we follow?" \
--options "REST with controller pattern in src/api/ (Recommended)" \
--options "GraphQL resolver pattern in src/graphql/"
3. ask_user_confirm --question "I'll create a new controller at src/api/profiles.rs following the REST pattern. Proceed?"
4. delegate_to_agent --agent coder --task "Create profiles controller following REST pattern"
```
### Rules for User Prompts ### Rules for User Prompts
1. **Always include (Recommended)** on the option you think is best in `ask_user` 1. **Always include (Recommended)** on the option you think is best in `user__ask`
2. **Respect user choices** - never override or ignore a selection 2. **Respect user choices** - never override or ignore a selection
3. **Don't over-prompt** - trivial decisions (variable names in small functions, formatting) don't need prompts 3. **Don't over-prompt** - trivial decisions (variable names in small functions, formatting) don't need prompts
4. **DO prompt for**: architecture choices, file/module naming, which of multiple valid approaches to take, destructive operations, anything you're genuinely unsure about 4. **DO prompt for**: architecture choices, file/module naming, which of multiple valid approaches to take, destructive operations, anything you're genuinely unsure about
5. **Confirm before large changes** - if a task will touch 5+ files, confirm the plan first 5. **Confirm before large changes** - if a task will touch 5+ files, confirm the plan first
## Escalation Handling
If you see `pending_escalations` in your tool results, a child agent needs user input and is blocked.
Reply promptly via `agent__reply_escalation` to unblock it. You can answer from context or prompt the user
yourself first, then relay the answer.
## Available Tools ## Available Tools
{{__tools__}} {{__tools__}}
+1 -167
View File
@@ -7,7 +7,7 @@ export AUTO_CONFIRM=true
# @env LLM_OUTPUT=/dev/stdout # @env LLM_OUTPUT=/dev/stdout
# @env LLM_AGENT_VAR_PROJECT_DIR=. # @env LLM_AGENT_VAR_PROJECT_DIR=.
# @describe Sisyphus orchestrator tools (project info, build, test, user interaction) # @describe Sisyphus orchestrator tools (project info, build, test)
_project_dir() { _project_dir() {
local dir="${LLM_AGENT_VAR_PROJECT_DIR:-.}" local dir="${LLM_AGENT_VAR_PROJECT_DIR:-.}"
@@ -95,169 +95,3 @@ run_tests() {
fi fi
} }
# @cmd Quick file search in the project
# @option --pattern! File name pattern to search for (e.g., "*.rs", "config*")
search_files() {
# shellcheck disable=SC2154
local pattern="${argc_pattern}"
local project_dir
project_dir=$(_project_dir)
info "Searching for: ${pattern}" >> "$LLM_OUTPUT"
echo "" >> "$LLM_OUTPUT"
local results
results=$(search_files "${pattern}" "${project_dir}")
if [[ -n "${results}" ]]; then
echo "${results}" >> "$LLM_OUTPUT"
else
warn "No files found matching: ${pattern}" >> "$LLM_OUTPUT"
fi
}
# @cmd Search for content in files
# @option --pattern! Text pattern to search for
# @option --file-type File extension to search in (e.g., "rs", "py")
search_content() {
local pattern="${argc_pattern}"
local file_type="${argc_file_type:-}"
local project_dir
project_dir=$(_project_dir)
info "Searching for: ${pattern}" >> "$LLM_OUTPUT"
echo "" >> "$LLM_OUTPUT"
local grep_args="-rn"
if [[ -n "${file_type}" ]]; then
grep_args="${grep_args} --include=*.${file_type}"
fi
local results
# shellcheck disable=SC2086
results=$(grep ${grep_args} "${pattern}" "${project_dir}" 2>/dev/null | \
grep -v '/target/' | grep -v '/node_modules/' | grep -v '/.git/' | \
head -30) || true
if [[ -n "${results}" ]]; then
echo "${results}" >> "$LLM_OUTPUT"
else
warn "No matches found for: ${pattern}" >> "$LLM_OUTPUT"
fi
}
# @cmd Ask the user to select ONE option from a list. The first option should be your recommended choice; append '(Recommended)' to its label. Returns the selected option's label text.
# @option --question! The question to present to the user
# @option --options! The JSON array of options to present (first option = recommended, append '(Recommended)' to its label)
ask_user() {
# shellcheck disable=SC2154
local question="${argc_question}"
# shellcheck disable=SC2154
local options_json="${argc_options}"
local opts=()
# Convert JSON array string -> Bash array
if ! mapfile -t opts < <(jq -r '.[]' <<<"$options_json"); then
error "Invalid JSON in argc_options" >> "$LLM_OUTPUT"
return 1
fi
local opts_count="${#opts[@]}"
if [[ "$opts_count" -eq 0 ]]; then
error "No options provided for ask_user" >> "$LLM_OUTPUT"
return 1
fi
info "Asking user: ${question}" >> "$LLM_OUTPUT"
local selected_index
selected_index=$(list "$question" "${opts[@]}" 2>/dev/tty)
local selected_label="${opts[$selected_index]}"
cat <<-EOF >> "$LLM_OUTPUT"
User selected: ${selected_label}
EOF
}
# @cmd Ask the user a yes/no confirmation question. Returns 'yes' or 'no'.
# @option --question! The yes/no question to present to the user
ask_user_confirm() {
# shellcheck disable=SC2154
local question="${argc_question}"
info "Asking user: ${question}" >> "$LLM_OUTPUT"
local result
result=$(confirm "${question}" 2>/dev/tty)
if [[ "${result}" == "1" ]]; then
echo "User confirmed: yes" >> "$LLM_OUTPUT"
else
echo "User confirmed: no" >> "$LLM_OUTPUT"
fi
}
# @cmd Ask the user to select MULTIPLE options from a list (checkbox). Returns the labels of all selected items.
# @option --question! The question to present to the user
# @option --options! The JSON array of options to present
ask_user_checkbox() {
# shellcheck disable=SC2154
local question="${argc_question}"
# shellcheck disable=SC2154
local options_json="${argc_options}"
local opts=()
# Convert JSON array string -> Bash array
if ! mapfile -t opts < <(jq -r '.[]' <<<"$options_json"); then
error "Invalid JSON in argc_options" >> "$LLM_OUTPUT"
return 1
fi
local opts_count="${#opts[@]}"
if [[ "${opts_count}" -eq 0 ]]; then
error "No options provided for ask_user_checkbox" >> "$LLM_OUTPUT"
return 1
fi
info "Asking user (select multiple): ${question}" >> "$LLM_OUTPUT"
local checked_indices
checked_indices=$(checkbox "${question}" "${opts[@]}" 2>/dev/tty)
local selected_labels=()
for idx in ${checked_indices}; do
if [[ -n "${idx}" ]] && [[ "${idx}" =~ ^[0-9]+$ ]]; then
selected_labels+=("${opts[$idx]}")
fi
done
if [[ "${#selected_labels[@]}" -eq 0 ]]; then
echo "User selected: (none)" >> "$LLM_OUTPUT"
else
echo "User selected:" >> "$LLM_OUTPUT"
for label in "${selected_labels[@]}"; do
echo " - ${label}" >> "$LLM_OUTPUT"
done
fi
}
# @cmd Ask the user for free-text input. Returns whatever the user typed.
# @option --question! The prompt/question to present to the user
ask_user_input() {
# shellcheck disable=SC2154
local question="${argc_question}"
info "Asking user: ${question}" >> "$LLM_OUTPUT"
local user_text
user_text=$(input "${question}" 2>/dev/tty)
cat <<-EOF >> "$LLM_OUTPUT"
User input: ${user_text}
EOF
}