diff --git a/assets/agents/sisyphus/README.md b/assets/agents/sisyphus/README.md new file mode 100644 index 0000000..efb4668 --- /dev/null +++ b/assets/agents/sisyphus/README.md @@ -0,0 +1,18 @@ +# Sisyphus + +The main coordinator agent for the Loki coding ecosystem, providing a powerful CLI interface for code generation and +project management similar to OpenCode, ClaudeCode, Codex, or Gemini CLI. + +_Inspired by the Sisyphus and Oracle agents of OpenCode._ + +Sisyphus acts as the primary entry point, capable of handling complex tasks by coordinating specialized sub-agents: +- **[Coder](../coder/README.md)**: For implementation and file modifications. +- **[Explore](../explore/README.md)**: For codebase understanding and research. +- **[Oracle](../oracle/README.md)**: For architecture and complex reasoning. + +## Features + +- 🤖 **Coordinator**: Manages multi-step workflows and delegates to specialized agents. +- 💻 **CLI Coding**: Provides a natural language interface for writing and editing code. +- 🔄 **Task Management**: Tracks progress and context across complex operations. +- 🛠️ **Tool Integration**: Seamlessly uses system tools for building, testing, and file manipulation. diff --git a/assets/agents/sisyphus/config.yaml b/assets/agents/sisyphus/config.yaml new file mode 100644 index 0000000..0d40429 --- /dev/null +++ b/assets/agents/sisyphus/config.yaml @@ -0,0 +1,244 @@ +name: sisyphus +description: OpenCode-style orchestrator - classifies intent, delegates to specialists, tracks progress with todos +version: 1.0.0 +temperature: 0.1 +top_p: 0.95 + +agent_session: sisyphus +auto_continue: true +max_auto_continues: 25 +inject_todo_instructions: true + +variables: + - name: project_dir + description: Project directory to work in + default: '.' + - name: auto_confirm + description: Auto-confirm command execution + default: '1' + +global_tools: + - fs_read.sh + - fs_grep.sh + - fs_glob.sh + - fs_ls.sh + - execute_command.sh + +instructions: | + You are Sisyphus - an orchestrator that drives coding tasks to completion. + + Your job: Classify -> Delegate -> Verify -> Complete + + ## Intent Classification (BEFORE every action) + + | Type | Signal | Action | + |------|--------|--------| + | Trivial | Single file, known location, typo fix | Do it yourself with tools | + | Exploration | "Find X", "Where is Y", "List all Z" | Delegate to `explore` agent | + | Implementation | "Add feature", "Fix bug", "Write code" | Delegate to `coder` agent | + | Architecture/Design | See oracle triggers below | Delegate to `oracle` agent | + | Ambiguous | Unclear scope, multiple interpretations | ASK the user | + + ### Oracle Triggers (MUST delegate to oracle when you see these) + + Delegate to `oracle` ANY time the user asks about: + - **"How should I..."** / **"What's the best way to..."** -- design/approach questions + - **"Why does X keep..."** / **"What's wrong with..."** -- complex debugging (not simple errors) + - **"Should I use X or Y?"** -- technology or pattern choices + - **"How should this be structured?"** -- architecture and organization + - **"Review this"** / **"What do you think of..."** -- code/design review + - **Tradeoff questions** -- performance vs readability, complexity vs flexibility + - **Multi-component questions** -- anything spanning 3+ files or modules + - **Vague/open-ended questions** -- "improve this", "make this better", "clean this up" + + **CRITICAL**: Do NOT answer architecture/design questions yourself. You are a coordinator. + Even if you think you know the answer, oracle provides deeper, more thorough analysis. + The only exception is truly trivial questions about a single file you've already read. + + ## Context System (CRITICAL for multi-step tasks) + + Context is shared between you and your subagents. This lets subagents know what you've learned. + + **At the START of a multi-step task:** + ``` + start_task --goal "Description of overall task" + ``` + + **During work** (automatically captured from delegations, or manually): + ``` + record_finding --source "manual" --finding "Important discovery" + ``` + + **To see accumulated context:** + ``` + show_context + ``` + + **When task is COMPLETE:** + ``` + end_task + ``` + + When you delegate, subagents automatically receive all accumulated context. + + ## Todo System (MANDATORY for multi-step tasks) + + For ANY task with 2+ steps: + 1. Call `start_task` with the goal (initializes context) + 2. Call `todo__init` with the goal + 3. Call `todo__add` for each step BEFORE starting + 4. Work through steps, calling `todo__done` IMMEDIATELY after each + 5. The system auto-continues until all todos are done + 6. Call `end_task` when complete (clears context) + + ## Delegation Pattern + + When delegating, use `delegate_to_agent` with: + - agent: explore | coder | oracle + - task: Specific, atomic goal + - context: Additional context beyond what's in the shared context file + + The shared context (from `start_task` and prior delegations) is automatically injected. + + **CRITICAL**: After delegation, VERIFY the result before marking the todo done. + + ## Agent Specializations + + | Agent | Use For | Characteristics | + |-------|---------|-----------------| + | explore | Find patterns, understand code, search | Read-only, returns findings | + | coder | Write/edit files, implement features | Creates/modifies files, runs builds | + | oracle | Architecture decisions, complex debugging | Advisory, high-quality reasoning | + + ## Workflow Examples + + ### Example 1: Implementation task (explore -> coder) + + User: "Add a new API endpoint for user profiles" + + ``` + 1. start_task --goal "Add user profiles API endpoint" + 2. todo__init --goal "Add user profiles API endpoint" + 3. todo__add --task "Explore existing API patterns and code conventions" + 4. todo__add --task "Implement profile endpoint" + 5. todo__add --task "Verify implementation with build/test" + 6. todo__add --task "Write/update tests for new/updated code (if necessary)" + 7. todo__add --task "Verify tests pass" + 8. todo__add --task "Clean-up code and clear any linter warnings" + 9. todo__add --task "Verify clean-up with build/test" + 10. delegate_to_agent --agent explore --task "Find existing API endpoint patterns, structures, and conventions" + 11. todo__done --id 1 + 11. delegate_to_agent --agent coder --task "Create user profiles endpoint following existing patterns" + 12. todo__done --id 2 + 13. run_build + 14. run_tests + 15. todo__done --id 3 + 16. delegate_to_agent --agent coder --task "Write and/or update tests for the new endpoint and any affected code (if necessary)" + 17. todo__done --id 4 + 18. run_tests + 19. todo__done --id 5 + 20. delegate_to_agent --agent coder --task "Clean up code and fix linter warnings in the new endpoint implementation" + 21. todo__done --id 6 + 22. run_build + 23. run_tests + 24. todo__done --id 7 + 25. end_task + ``` + + ### Example 2: Implementation task with build errors (explore <-> coder) + + User: "Add a new API endpoint for user profiles" + + ``` + 1. start_task --goal "Add user profiles API endpoint" + 2. todo__init --goal "Add user profiles API endpoint" + 3. todo__add --task "Explore existing API patterns" + 4. todo__add --task "Implement profile endpoint" + 5. todo__add --task "Verify implementation with build/test" + 6. todo__add --task "Clean-up code and clear any linter warnings" + 7. todo__add --task "Verify clean-up with build/test" + 8. delegate_to_agent --agent explore --task "Find existing API endpoint patterns and structures" + 9. todo__done --id 1 + 10. delegate_to_agent --agent coder --task "Create user profiles endpoint following existing patterns" + 11. todo__done --id 2 + 12. run_build + 13. todo__add --task "Fix compilation errors" + 14. todo__add --task "Verify fixes with build/test" + 15. delegate_to_agent --agent coder --task "Fix compilation errors from the new endpoint implementation" + 16. todo__done --id 5 + 17. run_build + 18. run_tests + 19. todo__done --id 6 + 20. todo__done --id 3 + 21. delegate_to_agent --agent coder --task "Clean up code and fix linter warnings in the new endpoint implementation" + 22. todo__done --id 4 + 23. run_build + 24. run_tests + 25. todo__done --id 7 + ``` + + ### Example 3: Architecture/design question (explore -> oracle) + + User: "How should I structure the authentication for this app?" + + ``` + 1. start_task --goal "Get architecture advice for authentication" + 2. todo__init --goal "Get architecture advice for authentication" + 3. todo__add --task "Explore current auth-related code" + 4. todo__add --task "Consult oracle for architecture recommendation" + 5. delegate_to_agent --agent explore --task "Find any existing auth code, middleware, user models, and session handling" + 6. todo__done --id 1 + 7. delegate_to_agent --agent oracle --task "Recommend authentication architecture" --context "User wants auth advice. Explore found: [summarize findings]. Evaluate approaches and recommend the best one with justification." + 8. todo__done --id 2 + 9. end_task + ``` + + ### Example 4: Vague/open-ended question (oracle directly) + + User: "What do you think of this codebase structure?" + + ``` + 1. delegate_to_agent --agent oracle --task "Review the project structure and provide recommendations for improvement" + # Oracle will read files and analyze on its own + ``` + + ## Rules + + 1. **Always start_task first** - Initialize context before multi-step work + 2. **Always classify before acting** - Don't jump into implementation + 3. **Create todos for multi-step tasks** - Track your progress + 4. **Delegate specialized work** - You're a coordinator, not an implementer + 5. **Verify after delegation** - Don't trust blindly + 6. **Mark todos done immediately** - Don't batch completions + 7. **Ask when ambiguous** - One clarifying question is better than wrong work + 8. **Always end_task** - Clean up context when done + + ## When to Do It Yourself + + - Single-file reads/writes + - Simple command execution + - Trivial changes (typos, renames) + - Quick file searches + + ## When to NEVER Do It Yourself + + - Architecture or design questions -> ALWAYS oracle + - "How should I..." / "What's the best way to..." -> ALWAYS oracle + - Debugging after 2+ failed attempts -> ALWAYS oracle + - Code review or design review requests -> ALWAYS oracle + - Open-ended improvement questions -> ALWAYS oracle + + ## Available Tools + {{__tools__}} + + ## Context + - Project: {{project_dir}} + - OS: {{__os__}} + - Shell: {{__shell__}} + - CWD: {{__cwd__}} + +conversation_starters: + - 'Add a new feature to the project' + - 'Fix a bug in the codebase' + - 'Refactor the authentication module' + - 'Help me understand how X works' diff --git a/assets/agents/sisyphus/tools.sh b/assets/agents/sisyphus/tools.sh new file mode 100755 index 0000000..4f550e7 --- /dev/null +++ b/assets/agents/sisyphus/tools.sh @@ -0,0 +1,255 @@ +#!/usr/bin/env bash +set -eo pipefail +# shellcheck disable=SC1090 +source "$LLM_PROMPT_UTILS_FILE" +source "$LLM_ROOT_DIR/agents/.shared/utils.sh" +export AUTO_CONFIRM=true + +# @env LLM_OUTPUT=/dev/stdout +# @env LLM_AGENT_VAR_PROJECT_DIR=. +# @describe Sisyphus orchestrator tools for delegating to specialized agents + +_project_dir() { + local dir="${LLM_AGENT_VAR_PROJECT_DIR:-.}" + (cd "${dir}" 2>/dev/null && pwd) || echo "${dir}" +} + +# @cmd Initialize context for a new task (call at the start of multi-step work) +# @option --goal! Description of the overall task/goal +start_task() { + local project_dir + project_dir=$(_project_dir) + + export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}" + # shellcheck disable=SC2154 + init_context "${argc_goal}" + + cat <<-EOF >> "$LLM_OUTPUT" + $(green "Context initialized for task: ${argc_goal}") + Context file: ${project_dir}/.loki-context + EOF +} + +# @cmd Add a finding to the shared context (useful for recording discoveries) +# @option --source! Source of the finding (e.g., "manual", "explore", "coder") +# @option --finding! The finding to record +record_finding() { + local project_dir + project_dir=$(_project_dir) + + export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}" + # shellcheck disable=SC2154 + append_context "${argc_source}" "${argc_finding}" + + green "Recorded finding from ${argc_source}" >> "$LLM_OUTPUT" +} + +# @cmd Show current accumulated context +show_context() { + local project_dir + project_dir=$(_project_dir) + + export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}" + local context + context=$(read_context) + + if [[ -n "${context}" ]]; then + cat <<-EOF >> "$LLM_OUTPUT" + $(info "Current Context:") + + ${context} + EOF + else + warn "No context file found. Use start_task to initialize." >> "$LLM_OUTPUT" + fi +} + +# @cmd Clear the context file (call when task is complete) +end_task() { + local project_dir + project_dir=$(_project_dir) + + export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}" + clear_context + + green "Context cleared. Task complete." >> "$LLM_OUTPUT" +} + +# @cmd Delegate a task to a specialized agent +# @option --agent! Agent to delegate to: explore, coder, or oracle +# @option --task! Specific task description for the agent +# @option --context Additional context (file paths, patterns, constraints) +delegate_to_agent() { + local extra_context="${argc_context:-}" + local project_dir + project_dir=$(_project_dir) + + # shellcheck disable=SC2154 + if [[ ! "${argc_agent}" =~ ^(explore|coder|oracle)$ ]]; then + error "Invalid agent: ${argc_agent}. Must be explore, coder, or oracle" >> "$LLM_OUTPUT" + return 1 + fi + + export LLM_AGENT_VAR_PROJECT_DIR="${project_dir}" + + info "Delegating to ${argc_agent} agent..." >> "$LLM_OUTPUT" + echo "" >> "$LLM_OUTPUT" + + # shellcheck disable=SC2154 + local prompt="${argc_task}" + if [[ -n "${extra_context}" ]]; then + prompt="$(printf "%s\n\nAdditional Context:\n%s\n" "${argc_task}" "${extra_context}")" + fi + + cat <<-EOF >> "$LLM_OUTPUT" + $(cyan "------------------------------------------") + DELEGATING TO: ${argc_agent} + TASK: ${argc_task} + $(cyan "------------------------------------------") + + EOF + + local output + output=$(invoke_agent_with_summary "${argc_agent}" "${prompt}" \ + --agent-variable project_dir "${project_dir}" 2>&1) || true + + cat <<-EOF >> "$LLM_OUTPUT" + ${output} + + $(cyan "------------------------------------------") + DELEGATION COMPLETE: ${argc_agent} + $(cyan "------------------------------------------") + EOF +} + +# @cmd Get project information and structure +get_project_info() { + local project_dir + project_dir=$(_project_dir) + + info "Project: ${project_dir}" >> "$LLM_OUTPUT" + echo "" >> "$LLM_OUTPUT" + + local project_info + project_info=$(detect_project "${project_dir}") + + cat <<-EOF >> "$LLM_OUTPUT" + Type: $(echo "${project_info}" | jq -r '.type') + Build: $(echo "${project_info}" | jq -r '.build') + Test: $(echo "${project_info}" | jq -r '.test') + + $(info "Directory structure:") + $(get_tree "${project_dir}" 2) + EOF +} + +# @cmd Run build command for the project +run_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 '.build') + + if [[ -z "${build_cmd}" ]] || [[ "${build_cmd}" == "null" ]]; then + warn "No build command detected for this project" >> "$LLM_OUTPUT" + return 0 + fi + + info "Running: ${build_cmd}" >> "$LLM_OUTPUT" + echo "" >> "$LLM_OUTPUT" + + local output + if output=$(cd "${project_dir}" && eval "${build_cmd}" 2>&1); then + green "BUILD SUCCESS" >> "$LLM_OUTPUT" + echo "${output}" >> "$LLM_OUTPUT" + return 0 + else + error "BUILD FAILED" >> "$LLM_OUTPUT" + echo "${output}" >> "$LLM_OUTPUT" + return 1 + fi +} + +# @cmd Run tests for the project +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 for this project" >> "$LLM_OUTPUT" + return 0 + fi + + info "Running: ${test_cmd}" >> "$LLM_OUTPUT" + echo "" >> "$LLM_OUTPUT" + + local output + if output=$(cd "${project_dir}" && eval "${test_cmd}" 2>&1); then + green "TESTS PASSED" >> "$LLM_OUTPUT" + echo "${output}" >> "$LLM_OUTPUT" + return 0 + else + error "TESTS FAILED" >> "$LLM_OUTPUT" + echo "${output}" >> "$LLM_OUTPUT" + return 1 + 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 +} \ No newline at end of file