refactor: rename sisyphus_task to delegate_task

- Rename directories: sisyphus-task → delegate-task
- Rename types: SisyphusTaskArgs → DelegateTaskArgs, etc.
- Rename functions: createSisyphusTask → createDelegateTask
- Rename constants: SISYPHUS_TASK_* → DELEGATE_TASK_*
- Update tool name: sisyphus_task → delegate_task
- Update all prompts, docs, and tests
This commit is contained in:
justsisyphus 2026-01-16 17:34:40 +09:00
parent 6008388a4e
commit 188bbef018
46 changed files with 289 additions and 303 deletions

View File

@ -96,7 +96,7 @@ oh-my-opencode/
- **Over-exploration**: Stop searching when sufficient context found - **Over-exploration**: Stop searching when sufficient context found
- **High temperature**: Don't use >0.3 for code-related agents - **High temperature**: Don't use >0.3 for code-related agents
- **Broad tool access**: Prefer explicit `include` over unrestricted access - **Broad tool access**: Prefer explicit `include` over unrestricted access
- **Sequential agent calls**: Use `sisyphus_task` for parallel execution - **Sequential agent calls**: Use `delegate_task` for parallel execution
- **Heavy PreToolUse logic**: Slows every tool call - **Heavy PreToolUse logic**: Slows every tool call
- **Self-planning for complex tasks**: Spawn planning agent (Prometheus) instead - **Self-planning for complex tasks**: Spawn planning agent (Prometheus) instead
- **Trust agent self-reports**: ALWAYS verify results independently - **Trust agent self-reports**: ALWAYS verify results independently

View File

@ -583,7 +583,7 @@ Hand your best tools to your best colleagues. Now they can properly refactor, na
- **ast_grep_search**: AST-aware code pattern search (25 languages) - **ast_grep_search**: AST-aware code pattern search (25 languages)
- **ast_grep_replace**: AST-aware code replacement - **ast_grep_replace**: AST-aware code replacement
- **call_omo_agent**: Spawn specialized explore/librarian agents. Supports `run_in_background` parameter for async execution. - **call_omo_agent**: Spawn specialized explore/librarian agents. Supports `run_in_background` parameter for async execution.
- **sisyphus_task**: Category-based task delegation with specialized agents. Supports pre-configured categories (visual, business-logic) or direct agent targeting. Use `background_output` to retrieve results and `background_cancel` to cancel tasks. See [Categories](#categories). - **delegate_task**: Category-based task delegation with specialized agents. Supports pre-configured categories (visual, business-logic) or direct agent targeting. Use `background_output` to retrieve results and `background_cancel` to cancel tasks. See [Categories](#categories).
#### Session Management #### Session Management
@ -922,7 +922,7 @@ Available agents: `oracle`, `librarian`, `explore`, `frontend-ui-ux-engineer`, `
Oh My OpenCode includes built-in skills that provide additional capabilities: Oh My OpenCode includes built-in skills that provide additional capabilities:
- **playwright**: Browser automation with Playwright MCP. Use for web scraping, testing, screenshots, and browser interactions. - **playwright**: Browser automation with Playwright MCP. Use for web scraping, testing, screenshots, and browser interactions.
- **git-master**: Git expert for atomic commits, rebase/squash, and history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with `sisyphus_task(category='quick', skills=['git-master'], ...)` to save context. - **git-master**: Git expert for atomic commits, rebase/squash, and history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with `delegate_task(category='quick', skills=['git-master'], ...)` to save context.
Disable built-in skills via `disabled_skills` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`: Disable built-in skills via `disabled_skills` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`:
@ -1061,7 +1061,7 @@ Configure concurrency limits for background agent tasks. This controls how many
### Categories ### Categories
Categories enable domain-specific task delegation via the `sisyphus_task` tool. Each category applies runtime presets (model, temperature, prompt additions) when calling the `Sisyphus-Junior` agent. Categories enable domain-specific task delegation via the `delegate_task` tool. Each category applies runtime presets (model, temperature, prompt additions) when calling the `Sisyphus-Junior` agent.
**Default Categories:** **Default Categories:**
@ -1073,12 +1073,12 @@ Categories enable domain-specific task delegation via the `sisyphus_task` tool.
**Usage:** **Usage:**
``` ```
// Via sisyphus_task tool // Via delegate_task tool
sisyphus_task(category="visual", prompt="Create a responsive dashboard component") delegate_task(category="visual", prompt="Create a responsive dashboard component")
sisyphus_task(category="business-logic", prompt="Design the payment processing flow") delegate_task(category="business-logic", prompt="Design the payment processing flow")
// Or target a specific agent directly // Or target a specific agent directly
sisyphus_task(agent="oracle", prompt="Review this architecture") delegate_task(agent="oracle", prompt="Review this architecture")
``` ```
**Custom Categories:** **Custom Categories:**

View File

@ -580,7 +580,7 @@ gh repo star code-yeongyu/oh-my-opencode
- **ast_grep_search**AST 感知的代码模式搜索25 种语言) - **ast_grep_search**AST 感知的代码模式搜索25 种语言)
- **ast_grep_replace**AST 感知的代码替换 - **ast_grep_replace**AST 感知的代码替换
- **call_omo_agent**:生成专业的 explore/librarian 智能体。支持 `run_in_background` 参数进行异步执行。 - **call_omo_agent**:生成专业的 explore/librarian 智能体。支持 `run_in_background` 参数进行异步执行。
- **sisyphus_task**基于类别的任务委派使用专业智能体。支持预配置的类别visual、business-logic或直接指定智能体。使用 `background_output` 检索结果,使用 `background_cancel` 取消任务。参见[类别](#类别)。 - **delegate_task**基于类别的任务委派使用专业智能体。支持预配置的类别visual、business-logic或直接指定智能体。使用 `background_output` 检索结果,使用 `background_cancel` 取消任务。参见[类别](#类别)。
#### 会话管理 #### 会话管理
@ -931,7 +931,7 @@ Oh My OpenCode 从以下位置读取和执行钩子:
Oh My OpenCode 包含提供额外功能的内置技能: Oh My OpenCode 包含提供额外功能的内置技能:
- **playwright**:使用 Playwright MCP 进行浏览器自动化。用于网页抓取、测试、截图和浏览器交互。 - **playwright**:使用 Playwright MCP 进行浏览器自动化。用于网页抓取、测试、截图和浏览器交互。
- **git-master**Git 专家用于原子提交、rebase/squash 和历史搜索blame、bisect、log -S。**强烈推荐**:与 `sisyphus_task(category='quick', skills=['git-master'], ...)` 一起使用以节省上下文。 - **git-master**Git 专家用于原子提交、rebase/squash 和历史搜索blame、bisect、log -S。**强烈推荐**:与 `delegate_task(category='quick', skills=['git-master'], ...)` 一起使用以节省上下文。
通过 `~/.config/opencode/oh-my-opencode.json``.opencode/oh-my-opencode.json` 中的 `disabled_skills` 禁用内置技能: 通过 `~/.config/opencode/oh-my-opencode.json``.opencode/oh-my-opencode.json` 中的 `disabled_skills` 禁用内置技能:
@ -1070,7 +1070,7 @@ Oh My OpenCode 包含提供额外功能的内置技能:
### 类别 ### 类别
类别通过 `sisyphus_task` 工具实现领域特定的任务委派。每个类别预配置一个专业的 `Sisyphus-Junior-{category}` 智能体,带有优化的模型设置和提示。 类别通过 `delegate_task` 工具实现领域特定的任务委派。每个类别预配置一个专业的 `Sisyphus-Junior-{category}` 智能体,带有优化的模型设置和提示。
**默认类别:** **默认类别:**
@ -1082,12 +1082,12 @@ Oh My OpenCode 包含提供额外功能的内置技能:
**使用方法:** **使用方法:**
``` ```
// 通过 sisyphus_task 工具 // 通过 delegate_task 工具
sisyphus_task(category="visual", prompt="创建一个响应式仪表板组件") delegate_task(category="visual", prompt="创建一个响应式仪表板组件")
sisyphus_task(category="business-logic", prompt="设计支付处理流程") delegate_task(category="business-logic", prompt="设计支付处理流程")
// 或直接指定特定智能体 // 或直接指定特定智能体
sisyphus_task(agent="oracle", prompt="审查这个架构") delegate_task(agent="oracle", prompt="审查这个架构")
``` ```
**自定义类别:** **自定义类别:**

View File

@ -9,7 +9,7 @@ Instead of delegating everything to a single AI agent, it's far more efficient t
- **Category**: "What kind of work is this?" (determines model, temperature, prompt mindset) - **Category**: "What kind of work is this?" (determines model, temperature, prompt mindset)
- **Skill**: "What tools and knowledge are needed?" (injects specialized knowledge, MCP tools, workflows) - **Skill**: "What tools and knowledge are needed?" (injects specialized knowledge, MCP tools, workflows)
By combining these two concepts, you can generate optimal agents through `sisyphus_task`. By combining these two concepts, you can generate optimal agents through `delegate_task`.
--- ---
@ -30,10 +30,10 @@ A Category is an agent configuration preset optimized for specific domains.
### Usage ### Usage
Specify the `category` parameter when invoking the `sisyphus_task` tool. Specify the `category` parameter when invoking the `delegate_task` tool.
```typescript ```typescript
sisyphus_task( delegate_task(
category="visual-engineering", category="visual-engineering",
prompt="Add a responsive chart component to the dashboard page" prompt="Add a responsive chart component to the dashboard page"
) )
@ -72,7 +72,7 @@ A Skill is a mechanism that injects **specialized knowledge (Context)** and **to
Add desired skill names to the `skills` array. Add desired skill names to the `skills` array.
```typescript ```typescript
sisyphus_task( delegate_task(
category="quick", category="quick",
skills=["git-master"], skills=["git-master"],
prompt="Commit current changes. Follow commit message style." prompt="Commit current changes. Follow commit message style."
@ -124,7 +124,7 @@ You can create powerful specialized agents by combining Categories and Skills.
--- ---
## 5. sisyphus_task Prompt Guide ## 5. delegate_task Prompt Guide
When delegating, **clear and specific** prompts are essential. Include these 7 elements: When delegating, **clear and specific** prompts are essential. Include these 7 elements:

View File

@ -149,4 +149,4 @@ You can control related features in `oh-my-opencode.json`.
1. **Don't Rush**: Invest sufficient time in the interview with Prometheus. The more perfect the plan, the faster the execution. 1. **Don't Rush**: Invest sufficient time in the interview with Prometheus. The more perfect the plan, the faster the execution.
2. **Single Plan Principle**: No matter how large the task, contain all TODOs in one plan file (`.md`). This prevents context fragmentation. 2. **Single Plan Principle**: No matter how large the task, contain all TODOs in one plan file (`.md`). This prevents context fragmentation.
3. **Active Delegation**: During execution, delegate to specialized agents via `sisyphus_task` rather than modifying code directly. 3. **Active Delegation**: During execution, delegate to specialized agents via `delegate_task` rather than modifying code directly.

View File

@ -53,7 +53,7 @@ agents/
## ANTI-PATTERNS ## ANTI-PATTERNS
- **Trusting reports**: NEVER trust subagent self-reports; always verify outputs. - **Trusting reports**: NEVER trust subagent self-reports; always verify outputs.
- **High temp**: Don't use >0.3 for code agents (Sisyphus/Prometheus use 0.1). - **High temp**: Don't use >0.3 for code agents (Sisyphus/Prometheus use 0.1).
- **Sequential calls**: Prefer `sisyphus_task` with `run_in_background` for parallelism. - **Sequential calls**: Prefer `delegate_task` with `run_in_background` for parallelism.
## SHARED PROMPTS ## SHARED PROMPTS
- **build-prompt.ts**: Unified base for Sisyphus and Builder variants. - **build-prompt.ts**: Unified base for Sisyphus and Builder variants.

View File

@ -29,7 +29,7 @@ export function createExploreAgent(model: string = DEFAULT_MODEL): AgentConfig {
"write", "write",
"edit", "edit",
"task", "task",
"sisyphus_task", "delegate_task",
"call_omo_agent", "call_omo_agent",
]) ])

View File

@ -26,7 +26,7 @@ export function createLibrarianAgent(model: string = DEFAULT_MODEL): AgentConfig
"write", "write",
"edit", "edit",
"task", "task",
"sisyphus_task", "delegate_task",
"call_omo_agent", "call_omo_agent",
]) ])

View File

@ -275,7 +275,7 @@ const metisRestrictions = createAgentToolRestrictions([
"write", "write",
"edit", "edit",
"task", "task",
"sisyphus_task", "delegate_task",
]) ])
const DEFAULT_MODEL = "anthropic/claude-opus-4-5" const DEFAULT_MODEL = "anthropic/claude-opus-4-5"

View File

@ -353,7 +353,7 @@ export function createMomusAgent(model: string = DEFAULT_MODEL): AgentConfig {
"write", "write",
"edit", "edit",
"task", "task",
"sisyphus_task", "delegate_task",
]) ])
const base = { const base = {

View File

@ -102,7 +102,7 @@ export function createOracleAgent(model: string = DEFAULT_MODEL): AgentConfig {
"write", "write",
"edit", "edit",
"task", "task",
"sisyphus_task", "delegate_task",
]) ])
const base = { const base = {

View File

@ -2,13 +2,13 @@ import type { AgentConfig } from "@opencode-ai/sdk"
import type { AgentPromptMetadata } from "./types" import type { AgentPromptMetadata } from "./types"
import type { AvailableAgent, AvailableSkill } from "./sisyphus-prompt-builder" import type { AvailableAgent, AvailableSkill } from "./sisyphus-prompt-builder"
import type { CategoryConfig } from "../config/schema" import type { CategoryConfig } from "../config/schema"
import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../tools/sisyphus-task/constants" import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../tools/delegate-task/constants"
import { createAgentToolRestrictions } from "../shared/permission-compat" import { createAgentToolRestrictions } from "../shared/permission-compat"
/** /**
* Orchestrator Sisyphus - Master Orchestrator Agent * Orchestrator Sisyphus - Master Orchestrator Agent
* *
* Orchestrates work via sisyphus_task() to complete ALL tasks in a todo list until fully done * Orchestrates work via delegate_task() to complete ALL tasks in a todo list until fully done
* You are the conductor of a symphony of specialized agents. * You are the conductor of a symphony of specialized agents.
*/ */
@ -65,8 +65,8 @@ Categories spawn \`Sisyphus-Junior-{category}\` with optimized settings:
${categoryRows.join("\n")} ${categoryRows.join("\n")}
\`\`\`typescript \`\`\`typescript
sisyphus_task(category="visual-engineering", prompt="...") // UI/frontend work delegate_task(category="visual-engineering", prompt="...") // UI/frontend work
sisyphus_task(category="ultrabrain", prompt="...") // Backend/strategic work delegate_task(category="ultrabrain", prompt="...") // Backend/strategic work
\`\`\`` \`\`\``
} }
@ -95,9 +95,9 @@ ${skillRows.join("\n")}
**Usage:** **Usage:**
\`\`\`typescript \`\`\`typescript
sisyphus_task(category="visual-engineering", skills=["frontend-ui-ux"], prompt="...") delegate_task(category="visual-engineering", skills=["frontend-ui-ux"], prompt="...")
sisyphus_task(category="general", skills=["playwright"], prompt="...") // Browser testing delegate_task(category="general", skills=["playwright"], prompt="...") // Browser testing
sisyphus_task(category="visual-engineering", skills=["frontend-ui-ux", "playwright"], prompt="...") // UI with browser testing delegate_task(category="visual-engineering", skills=["frontend-ui-ux", "playwright"], prompt="...") // UI with browser testing
\`\`\` \`\`\`
**IMPORTANT:** **IMPORTANT:**
@ -297,8 +297,8 @@ Search **external references** (docs, OSS, web). Fire proactively when unfamilia
**ANTI-PATTERN (DO NOT DO THIS):** **ANTI-PATTERN (DO NOT DO THIS):**
\`\`\`typescript \`\`\`typescript
// ❌ WRONG: Background for simple searches // ❌ WRONG: Background for simple searches
sisyphus_task(agent="explore", prompt="Find where X is defined") // Just use grep! delegate_task(agent="explore", prompt="Find where X is defined") // Just use grep!
sisyphus_task(agent="librarian", prompt="How to use Y") // Just use context7! delegate_task(agent="librarian", prompt="How to use Y") // Just use context7!
// ✅ CORRECT: Direct tools for most cases // ✅ CORRECT: Direct tools for most cases
grep(pattern="functionName", path="src/") grep(pattern="functionName", path="src/")
@ -310,8 +310,8 @@ context7_query-docs(libraryId, query)
\`\`\`typescript \`\`\`typescript
// Only for massive parallel research with 5+ independent queries // Only for massive parallel research with 5+ independent queries
// AND you have other implementation work to do simultaneously // AND you have other implementation work to do simultaneously
sisyphus_task(agent="explore", prompt="...") // Query 1 delegate_task(agent="explore", prompt="...") // Query 1
sisyphus_task(agent="explore", prompt="...") // Query 2 delegate_task(agent="explore", prompt="...") // Query 2
// ... continue implementing other code while these run // ... continue implementing other code while these run
\`\`\` \`\`\`
@ -690,10 +690,10 @@ If the user's approach seems problematic:
</Constraints> </Constraints>
<role> <role>
You are the MASTER ORCHESTRATOR - the conductor of a symphony of specialized agents via \`sisyphus_task()\`. Your sole mission is to ensure EVERY SINGLE TASK in a todo list gets completed to PERFECTION. You are the MASTER ORCHESTRATOR - the conductor of a symphony of specialized agents via \`delegate_task()\`. Your sole mission is to ensure EVERY SINGLE TASK in a todo list gets completed to PERFECTION.
## CORE MISSION ## CORE MISSION
Orchestrate work via \`sisyphus_task()\` to complete ALL tasks in a given todo list until fully done. Orchestrate work via \`delegate_task()\` to complete ALL tasks in a given todo list until fully done.
## IDENTITY & PHILOSOPHY ## IDENTITY & PHILOSOPHY
@ -709,16 +709,16 @@ You do NOT execute tasks yourself. You DELEGATE, COORDINATE, and VERIFY. Think o
- YOU CAN: Read files, run commands, verify results, check tests, inspect outputs - YOU CAN: Read files, run commands, verify results, check tests, inspect outputs
- YOU MUST DELEGATE: Code writing, file modification, bug fixes, test creation - YOU MUST DELEGATE: Code writing, file modification, bug fixes, test creation
2. **VERIFY OBSESSIVELY**: Subagents LIE. Always verify their claims with your own tools (Read, Bash, lsp_diagnostics). 2. **VERIFY OBSESSIVELY**: Subagents LIE. Always verify their claims with your own tools (Read, Bash, lsp_diagnostics).
3. **PARALLELIZE WHEN POSSIBLE**: If tasks are independent (no dependencies, no file conflicts), invoke multiple \`sisyphus_task()\` calls in PARALLEL. 3. **PARALLELIZE WHEN POSSIBLE**: If tasks are independent (no dependencies, no file conflicts), invoke multiple \`delegate_task()\` calls in PARALLEL.
4. **ONE TASK PER CALL**: Each \`sisyphus_task()\` call handles EXACTLY ONE task. Never batch multiple tasks. 4. **ONE TASK PER CALL**: Each \`delegate_task()\` call handles EXACTLY ONE task. Never batch multiple tasks.
5. **CONTEXT IS KING**: Pass COMPLETE, DETAILED context in every \`sisyphus_task()\` prompt. 5. **CONTEXT IS KING**: Pass COMPLETE, DETAILED context in every \`delegate_task()\` prompt.
6. **WISDOM ACCUMULATES**: Gather learnings from each task and pass to the next. 6. **WISDOM ACCUMULATES**: Gather learnings from each task and pass to the next.
### CRITICAL: DETAILED PROMPTS ARE MANDATORY ### CRITICAL: DETAILED PROMPTS ARE MANDATORY
**The #1 cause of agent failure is VAGUE PROMPTS.** **The #1 cause of agent failure is VAGUE PROMPTS.**
When calling \`sisyphus_task()\`, your prompt MUST be: When calling \`delegate_task()\`, your prompt MUST be:
- **EXHAUSTIVELY DETAILED**: Include EVERY piece of context the agent needs - **EXHAUSTIVELY DETAILED**: Include EVERY piece of context the agent needs
- **EXPLICITLY STRUCTURED**: Use the 7-section format (TASK, EXPECTED OUTCOME, REQUIRED SKILLS, REQUIRED TOOLS, MUST DO, MUST NOT DO, CONTEXT) - **EXPLICITLY STRUCTURED**: Use the 7-section format (TASK, EXPECTED OUTCOME, REQUIRED SKILLS, REQUIRED TOOLS, MUST DO, MUST NOT DO, CONTEXT)
- **CONCRETE, NOT ABSTRACT**: Exact file paths, exact commands, exact expected outputs - **CONCRETE, NOT ABSTRACT**: Exact file paths, exact commands, exact expected outputs
@ -726,12 +726,12 @@ When calling \`sisyphus_task()\`, your prompt MUST be:
**BAD (will fail):** **BAD (will fail):**
\`\`\` \`\`\`
sisyphus_task(category="ultrabrain", prompt="Fix the auth bug") delegate_task(category="ultrabrain", prompt="Fix the auth bug")
\`\`\` \`\`\`
**GOOD (will succeed):** **GOOD (will succeed):**
\`\`\` \`\`\`
sisyphus_task( delegate_task(
category="ultrabrain", category="ultrabrain",
prompt=""" prompt="""
## TASK ## TASK
@ -875,7 +875,7 @@ Before processing sequentially, check if there are PARALLELIZABLE tasks:
1. **Identify parallelizable task group** from the parallelization map (from Step 1) 1. **Identify parallelizable task group** from the parallelization map (from Step 1)
2. **If parallelizable group found** (e.g., Tasks 2, 3, 4 can run simultaneously): 2. **If parallelizable group found** (e.g., Tasks 2, 3, 4 can run simultaneously):
- Prepare DETAILED execution prompts for ALL tasks in the group - Prepare DETAILED execution prompts for ALL tasks in the group
- Invoke multiple \`sisyphus_task()\` calls IN PARALLEL (single message, multiple calls) - Invoke multiple \`delegate_task()\` calls IN PARALLEL (single message, multiple calls)
- Wait for ALL to complete - Wait for ALL to complete
- Process ALL responses and update wisdom repository - Process ALL responses and update wisdom repository
- Mark ALL completed tasks - Mark ALL completed tasks
@ -889,16 +889,16 @@ Before processing sequentially, check if there are PARALLELIZABLE tasks:
- Extract the EXACT task text - Extract the EXACT task text
- Analyze the task nature - Analyze the task nature
#### 3.2: Choose Category or Agent for sisyphus_task() #### 3.2: Choose Category or Agent for delegate_task()
**sisyphus_task() has TWO modes - choose ONE:** **delegate_task() has TWO modes - choose ONE:**
{CATEGORY_SECTION} {CATEGORY_SECTION}
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="oracle", prompt="...") // Expert consultation delegate_task(agent="oracle", prompt="...") // Expert consultation
sisyphus_task(agent="explore", prompt="...") // Codebase search delegate_task(agent="explore", prompt="...") // Codebase search
sisyphus_task(agent="librarian", prompt="...") // External research delegate_task(agent="librarian", prompt="...") // External research
\`\`\` \`\`\`
{AGENT_SECTION} {AGENT_SECTION}
@ -970,7 +970,7 @@ STRATEGIC CATEGORY JUSTIFICATION (MANDATORY):
--- ---
**BEFORE invoking sisyphus_task(), you MUST state:** **BEFORE invoking delegate_task(), you MUST state:**
\`\`\` \`\`\`
Category: [general OR specific-category] Category: [general OR specific-category]
@ -987,7 +987,7 @@ Justification: [Brief for general, EXTENSIVE for strategic/most-capable]
#### 3.3: Prepare Execution Directive (DETAILED PROMPT IS EVERYTHING) #### 3.3: Prepare Execution Directive (DETAILED PROMPT IS EVERYTHING)
**CRITICAL: The quality of your \`sisyphus_task()\` prompt determines success or failure.** **CRITICAL: The quality of your \`delegate_task()\` prompt determines success or failure.**
**RULE: If your prompt is short, YOU WILL FAIL. Make it EXHAUSTIVELY DETAILED.** **RULE: If your prompt is short, YOU WILL FAIL. Make it EXHAUSTIVELY DETAILED.**
@ -1063,7 +1063,7 @@ NOTEPAD PATH: .sisyphus/notepads/{plan-name}/ (READ for wisdom, WRITE findings)
PLAN PATH: .sisyphus/plans/{plan-name}.md (READ ONLY - NEVER MODIFY) PLAN PATH: .sisyphus/plans/{plan-name}.md (READ ONLY - NEVER MODIFY)
### Inherited Wisdom from Notepad (READ BEFORE EVERY DELEGATION) ### Inherited Wisdom from Notepad (READ BEFORE EVERY DELEGATION)
[Extract from .sisyphus/notepads/{plan-name}/*.md before calling sisyphus_task] [Extract from .sisyphus/notepads/{plan-name}/*.md before calling delegate_task]
- Conventions discovered: [from learnings.md] - Conventions discovered: [from learnings.md]
- Successful approaches: [from learnings.md] - Successful approaches: [from learnings.md]
- Failed approaches to avoid: [from issues.md] - Failed approaches to avoid: [from issues.md]
@ -1082,12 +1082,12 @@ PLAN PATH: .sisyphus/plans/{plan-name}.md (READ ONLY - NEVER MODIFY)
**PROMPT LENGTH CHECK**: Your prompt should be 50-200 lines. If it's under 20 lines, it's TOO SHORT. **PROMPT LENGTH CHECK**: Your prompt should be 50-200 lines. If it's under 20 lines, it's TOO SHORT.
#### 3.4: Invoke via sisyphus_task() #### 3.4: Invoke via delegate_task()
**CRITICAL: Pass the COMPLETE 7-section directive from 3.3. SHORT PROMPTS = FAILURE.** **CRITICAL: Pass the COMPLETE 7-section directive from 3.3. SHORT PROMPTS = FAILURE.**
\`\`\`typescript \`\`\`typescript
sisyphus_task( delegate_task(
agent="[selected-agent-name]", // Agent you chose in step 3.2 agent="[selected-agent-name]", // Agent you chose in step 3.2
background=false, // ALWAYS false for task delegation - wait for completion background=false, // ALWAYS false for task delegation - wait for completion
prompt=\` prompt=\`
@ -1153,7 +1153,7 @@ Task N: [exact task description]
** CRITICAL: SUBAGENTS LIE. NEVER trust their claims. ALWAYS verify yourself.** ** CRITICAL: SUBAGENTS LIE. NEVER trust their claims. ALWAYS verify yourself.**
** YOU ARE THE QA GATE. If you don't verify, NO ONE WILL.** ** YOU ARE THE QA GATE. If you don't verify, NO ONE WILL.**
After \`sisyphus_task()\` completes, you MUST perform COMPREHENSIVE QA: After \`delegate_task()\` completes, you MUST perform COMPREHENSIVE QA:
**STEP 1: PROJECT-LEVEL CODE VERIFICATION (MANDATORY)** **STEP 1: PROJECT-LEVEL CODE VERIFICATION (MANDATORY)**
1. **Run \`lsp_diagnostics\` at DIRECTORY or PROJECT level**: 1. **Run \`lsp_diagnostics\` at DIRECTORY or PROJECT level**:
@ -1203,12 +1203,12 @@ After \`sisyphus_task()\` completes, you MUST perform COMPREHENSIVE QA:
If task reports FAILED or BLOCKED: If task reports FAILED or BLOCKED:
- **THINK**: "What information or help is needed to fix this?" - **THINK**: "What information or help is needed to fix this?"
- **IDENTIFY**: Which agent is best suited to provide that help? - **IDENTIFY**: Which agent is best suited to provide that help?
- **INVOKE**: via \`sisyphus_task()\` with MORE DETAILED prompt including failure context - **INVOKE**: via \`delegate_task()\` with MORE DETAILED prompt including failure context
- **RE-ATTEMPT**: Re-invoke with new insights/guidance and EXPANDED context - **RE-ATTEMPT**: Re-invoke with new insights/guidance and EXPANDED context
- If external blocker: Document and continue to next independent task - If external blocker: Document and continue to next independent task
- Maximum 3 retry attempts per task - Maximum 3 retry attempts per task
**NEVER try to analyze or fix failures yourself. Always delegate via \`sisyphus_task()\`.** **NEVER try to analyze or fix failures yourself. Always delegate via \`delegate_task()\`.**
**FAILURE RECOVERY PROMPT EXPANSION**: When retrying, your prompt MUST include: **FAILURE RECOVERY PROMPT EXPANSION**: When retrying, your prompt MUST include:
- What was attempted - What was attempted
@ -1256,7 +1256,7 @@ TOTAL TIME: [duration]
### THE GOLDEN RULE ### THE GOLDEN RULE
**YOU ORCHESTRATE, YOU DO NOT EXECUTE.** **YOU ORCHESTRATE, YOU DO NOT EXECUTE.**
Every time you're tempted to write code, STOP and ask: "Should I delegate this via \`sisyphus_task()\`?" Every time you're tempted to write code, STOP and ask: "Should I delegate this via \`delegate_task()\`?"
The answer is almost always YES. The answer is almost always YES.
### WHAT YOU CAN DO vs WHAT YOU MUST DELEGATE ### WHAT YOU CAN DO vs WHAT YOU MUST DELEGATE
@ -1278,11 +1278,11 @@ The answer is almost always YES.
- [X] Git commits (delegate to git-master) - [X] Git commits (delegate to git-master)
**DELEGATION TARGETS:** **DELEGATION TARGETS:**
- \`sisyphus_task(category="ultrabrain", background=false)\` → backend/logic implementation - \`delegate_task(category="ultrabrain", background=false)\` → backend/logic implementation
- \`sisyphus_task(category="visual-engineering", background=false)\` → frontend/UI implementation - \`delegate_task(category="visual-engineering", background=false)\` → frontend/UI implementation
- \`sisyphus_task(agent="git-master", background=false)\` → ALL git commits - \`delegate_task(agent="git-master", background=false)\` → ALL git commits
- \`sisyphus_task(agent="document-writer", background=false)\` → documentation - \`delegate_task(agent="document-writer", background=false)\` → documentation
- \`sisyphus_task(agent="debugging-master", background=false)\` → complex debugging - \`delegate_task(agent="debugging-master", background=false)\` → complex debugging
** CRITICAL: background=false is MANDATORY for all task delegations.** ** CRITICAL: background=false is MANDATORY for all task delegations.**
@ -1352,8 +1352,8 @@ All learnings, decisions, and insights MUST be recorded in the notepad system fo
\`\`\` \`\`\`
**Usage Protocol:** **Usage Protocol:**
1. **BEFORE each sisyphus_task() call** Read notepad files to gather accumulated wisdom 1. **BEFORE each delegate_task() call** Read notepad files to gather accumulated wisdom
2. **INCLUDE in every sisyphus_task() prompt** Pass relevant notepad content as "INHERITED WISDOM" section 2. **INCLUDE in every delegate_task() prompt** Pass relevant notepad content as "INHERITED WISDOM" section
3. After each task completion Instruct subagent to append findings to appropriate category 3. After each task completion Instruct subagent to append findings to appropriate category
4. When encountering issues Document in issues.md or problems.md 4. When encountering issues Document in issues.md or problems.md
@ -1366,7 +1366,7 @@ All learnings, decisions, and insights MUST be recorded in the notepad system fo
**READING NOTEPAD BEFORE DELEGATION (MANDATORY):** **READING NOTEPAD BEFORE DELEGATION (MANDATORY):**
Before EVERY \`sisyphus_task()\` call, you MUST: Before EVERY \`delegate_task()\` call, you MUST:
1. Check if notepad exists: \`glob(".sisyphus/notepads/{plan-name}/*.md")\` 1. Check if notepad exists: \`glob(".sisyphus/notepads/{plan-name}/*.md")\`
2. If exists, read recent entries (use Read tool, focus on recent ~50 lines per file) 2. If exists, read recent entries (use Read tool, focus on recent ~50 lines per file)
@ -1380,7 +1380,7 @@ Read(".sisyphus/notepads/my-plan/learnings.md")
Read(".sisyphus/notepads/my-plan/issues.md") Read(".sisyphus/notepads/my-plan/issues.md")
Read(".sisyphus/notepads/my-plan/decisions.md") Read(".sisyphus/notepads/my-plan/decisions.md")
# Then include in sisyphus_task prompt: # Then include in delegate_task prompt:
## INHERITED WISDOM FROM PREVIOUS TASKS ## INHERITED WISDOM FROM PREVIOUS TASKS
- Pattern discovered: Use kebab-case for file names (learnings.md) - Pattern discovered: Use kebab-case for file names (learnings.md)
- Avoid: Direct DOM manipulation - use React refs instead (issues.md) - Avoid: Direct DOM manipulation - use React refs instead (issues.md)
@ -1395,11 +1395,11 @@ Read(".sisyphus/notepads/my-plan/decisions.md")
1. **Executing tasks yourself**: NEVER write implementation code, NEVER read/write/edit files directly 1. **Executing tasks yourself**: NEVER write implementation code, NEVER read/write/edit files directly
2. **Ignoring parallelizability**: If tasks CAN run in parallel, they SHOULD run in parallel 2. **Ignoring parallelizability**: If tasks CAN run in parallel, they SHOULD run in parallel
3. **Batch delegation**: NEVER send multiple tasks to one \`sisyphus_task()\` call (one task per call) 3. **Batch delegation**: NEVER send multiple tasks to one \`delegate_task()\` call (one task per call)
4. **Losing context**: ALWAYS pass accumulated wisdom in EVERY prompt 4. **Losing context**: ALWAYS pass accumulated wisdom in EVERY prompt
5. **Giving up early**: RETRY failed tasks (max 3 attempts) 5. **Giving up early**: RETRY failed tasks (max 3 attempts)
6. **Rushing**: Quality over speed - but parallelize when possible 6. **Rushing**: Quality over speed - but parallelize when possible
7. **Direct file operations**: NEVER use Read/Write/Edit/Bash for file operations - ALWAYS use \`sisyphus_task()\` 7. **Direct file operations**: NEVER use Read/Write/Edit/Bash for file operations - ALWAYS use \`delegate_task()\`
8. **SHORT PROMPTS**: If your prompt is under 30 lines, it's TOO SHORT. EXPAND IT. 8. **SHORT PROMPTS**: If your prompt is under 30 lines, it's TOO SHORT. EXPAND IT.
9. **Wrong category/agent**: Match task type to category/agent systematically (see Decision Matrix) 9. **Wrong category/agent**: Match task type to category/agent systematically (see Decision Matrix)
@ -1441,7 +1441,7 @@ If task cannot be completed after 3 attempts:
You are the MASTER ORCHESTRATOR. Your job is to: You are the MASTER ORCHESTRATOR. Your job is to:
1. **CREATE TODO** to track overall progress 1. **CREATE TODO** to track overall progress
2. **READ** the todo list (check for parallelizability) 2. **READ** the todo list (check for parallelizability)
3. **DELEGATE** via \`sisyphus_task()\` with DETAILED prompts (parallel when possible) 3. **DELEGATE** via \`delegate_task()\` with DETAILED prompts (parallel when possible)
4. ** QA VERIFY** - Run project-level \`lsp_diagnostics\`, build, and tests after EVERY delegation 4. ** QA VERIFY** - Run project-level \`lsp_diagnostics\`, build, and tests after EVERY delegation
5. **ACCUMULATE** wisdom from completions 5. **ACCUMULATE** wisdom from completions
6. **REPORT** final status 6. **REPORT** final status
@ -1449,9 +1449,9 @@ You are the MASTER ORCHESTRATOR. Your job is to:
**CRITICAL REMINDERS:** **CRITICAL REMINDERS:**
- NEVER execute tasks yourself - NEVER execute tasks yourself
- NEVER read/write/edit files directly - NEVER read/write/edit files directly
- ALWAYS use \`sisyphus_task(category=...)\` or \`sisyphus_task(agent=...)\` - ALWAYS use \`delegate_task(category=...)\` or \`delegate_task(agent=...)\`
- PARALLELIZE when tasks are independent - PARALLELIZE when tasks are independent
- One task per \`sisyphus_task()\` call (never batch) - One task per \`delegate_task()\` call (never batch)
- Pass COMPLETE context in EVERY prompt (50+ lines minimum) - Pass COMPLETE context in EVERY prompt (50+ lines minimum)
- Accumulate and forward all learnings - Accumulate and forward all learnings
- ** RUN lsp_diagnostics AT PROJECT/DIRECTORY LEVEL after EVERY delegation** - ** RUN lsp_diagnostics AT PROJECT/DIRECTORY LEVEL after EVERY delegation**
@ -1489,7 +1489,7 @@ export function createOrchestratorSisyphusAgent(ctx?: OrchestratorContext): Agen
]) ])
return { return {
description: description:
"Orchestrates work via sisyphus_task() to complete ALL tasks in a todo list until fully done", "Orchestrates work via delegate_task() to complete ALL tasks in a todo list until fully done",
mode: "primary" as const, mode: "primary" as const,
model: ctx?.model ?? DEFAULT_MODEL, model: ctx?.model ?? DEFAULT_MODEL,
temperature: 0.1, temperature: 0.1,

View File

@ -291,8 +291,8 @@ Or should I just note down this single fix?"
**Research First:** **Research First:**
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="explore", prompt="Find all usages of [target] using lsp_find_references pattern...", background=true) delegate_task(agent="explore", prompt="Find all usages of [target] using lsp_find_references pattern...", background=true)
sisyphus_task(agent="explore", prompt="Find test coverage for [affected code]...", background=true) delegate_task(agent="explore", prompt="Find test coverage for [affected code]...", background=true)
\`\`\` \`\`\`
**Interview Focus:** **Interview Focus:**
@ -315,9 +315,9 @@ sisyphus_task(agent="explore", prompt="Find test coverage for [affected code]...
**Pre-Interview Research (MANDATORY):** **Pre-Interview Research (MANDATORY):**
\`\`\`typescript \`\`\`typescript
// Launch BEFORE asking user questions // Launch BEFORE asking user questions
sisyphus_task(agent="explore", prompt="Find similar implementations in codebase...", background=true) delegate_task(agent="explore", prompt="Find similar implementations in codebase...", background=true)
sisyphus_task(agent="explore", prompt="Find project patterns for [feature type]...", background=true) delegate_task(agent="explore", prompt="Find project patterns for [feature type]...", background=true)
sisyphus_task(agent="librarian", prompt="Find best practices for [technology]...", background=true) delegate_task(agent="librarian", prompt="Find best practices for [technology]...", background=true)
\`\`\` \`\`\`
**Interview Focus** (AFTER research): **Interview Focus** (AFTER research):
@ -356,7 +356,7 @@ Based on your stack, I'd recommend NextAuth.js - it integrates well with Next.js
Run this check: Run this check:
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="explore", prompt="Find test infrastructure: package.json test scripts, test config files (jest.config, vitest.config, pytest.ini, etc.), existing test files (*.test.*, *.spec.*, test_*). Report: 1) Does test infra exist? 2) What framework? 3) Example test file patterns.", background=true) delegate_task(agent="explore", prompt="Find test infrastructure: package.json test scripts, test config files (jest.config, vitest.config, pytest.ini, etc.), existing test files (*.test.*, *.spec.*, test_*). Report: 1) Does test infra exist? 2) What framework? 3) Example test file patterns.", background=true)
\`\`\` \`\`\`
#### Step 2: Ask the Test Question (MANDATORY) #### Step 2: Ask the Test Question (MANDATORY)
@ -445,13 +445,13 @@ Add to draft immediately:
**Research First:** **Research First:**
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="explore", prompt="Find current system architecture and patterns...", background=true) delegate_task(agent="explore", prompt="Find current system architecture and patterns...", background=true)
sisyphus_task(agent="librarian", prompt="Find architectural best practices for [domain]...", background=true) delegate_task(agent="librarian", prompt="Find architectural best practices for [domain]...", background=true)
\`\`\` \`\`\`
**Oracle Consultation** (recommend when stakes are high): **Oracle Consultation** (recommend when stakes are high):
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="oracle", prompt="Architecture consultation needed: [context]...", background=false) delegate_task(agent="oracle", prompt="Architecture consultation needed: [context]...", background=false)
\`\`\` \`\`\`
**Interview Focus:** **Interview Focus:**
@ -468,9 +468,9 @@ sisyphus_task(agent="oracle", prompt="Architecture consultation needed: [context
**Parallel Investigation:** **Parallel Investigation:**
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="explore", prompt="Find how X is currently handled...", background=true) delegate_task(agent="explore", prompt="Find how X is currently handled...", background=true)
sisyphus_task(agent="librarian", prompt="Find official docs for Y...", background=true) delegate_task(agent="librarian", prompt="Find official docs for Y...", background=true)
sisyphus_task(agent="librarian", prompt="Find OSS implementations of Z...", background=true) delegate_task(agent="librarian", prompt="Find OSS implementations of Z...", background=true)
\`\`\` \`\`\`
**Interview Focus:** **Interview Focus:**
@ -496,17 +496,17 @@ sisyphus_task(agent="librarian", prompt="Find OSS implementations of Z...", back
**For Understanding Codebase:** **For Understanding Codebase:**
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="explore", prompt="Find all files related to [topic]. Show patterns, conventions, and structure.", background=true) delegate_task(agent="explore", prompt="Find all files related to [topic]. Show patterns, conventions, and structure.", background=true)
\`\`\` \`\`\`
**For External Knowledge:** **For External Knowledge:**
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="librarian", prompt="Find official documentation for [library]. Focus on [specific feature] and best practices.", background=true) delegate_task(agent="librarian", prompt="Find official documentation for [library]. Focus on [specific feature] and best practices.", background=true)
\`\`\` \`\`\`
**For Implementation Examples:** **For Implementation Examples:**
\`\`\`typescript \`\`\`typescript
sisyphus_task(agent="librarian", prompt="Find open source implementations of [feature]. Look for production-quality examples.", background=true) delegate_task(agent="librarian", prompt="Find open source implementations of [feature]. Look for production-quality examples.", background=true)
\`\`\` \`\`\`
## Interview Mode Anti-Patterns ## Interview Mode Anti-Patterns
@ -599,7 +599,7 @@ todoWrite([
**BEFORE generating the plan**, summon Metis to catch what you might have missed: **BEFORE generating the plan**, summon Metis to catch what you might have missed:
\`\`\`typescript \`\`\`typescript
sisyphus_task( delegate_task(
agent="Metis (Plan Consultant)", agent="Metis (Plan Consultant)",
prompt=\`Review this planning session before I generate the work plan: prompt=\`Review this planning session before I generate the work plan:
@ -750,7 +750,7 @@ If no, the plan is ready. Run \`/start-work\` to begin."
\`\`\`typescript \`\`\`typescript
// After generating initial plan // After generating initial plan
while (true) { while (true) {
const result = sisyphus_task( const result = delegate_task(
agent="Momus (Plan Reviewer)", agent="Momus (Plan Reviewer)",
prompt=".sisyphus/plans/{name}.md", prompt=".sisyphus/plans/{name}.md",
background=false background=false

View File

@ -138,13 +138,13 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
}) })
}) })
describe("tool safety (task/sisyphus_task blocked, call_omo_agent allowed)", () => { describe("tool safety (task/delegate_task blocked, call_omo_agent allowed)", () => {
test("task and sisyphus_task remain blocked, call_omo_agent is allowed via tools format", () => { test("task and delegate_task remain blocked, call_omo_agent is allowed via tools format", () => {
// #given // #given
const override = { const override = {
tools: { tools: {
task: true, task: true,
sisyphus_task: true, delegate_task: true,
call_omo_agent: true, call_omo_agent: true,
read: true, read: true,
}, },
@ -158,25 +158,25 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
const permission = result.permission as Record<string, string> | undefined const permission = result.permission as Record<string, string> | undefined
if (tools) { if (tools) {
expect(tools.task).toBe(false) expect(tools.task).toBe(false)
expect(tools.sisyphus_task).toBe(false) expect(tools.delegate_task).toBe(false)
// call_omo_agent is NOW ALLOWED for subagents to spawn explore/librarian // call_omo_agent is NOW ALLOWED for subagents to spawn explore/librarian
expect(tools.call_omo_agent).toBe(true) expect(tools.call_omo_agent).toBe(true)
expect(tools.read).toBe(true) expect(tools.read).toBe(true)
} }
if (permission) { if (permission) {
expect(permission.task).toBe("deny") expect(permission.task).toBe("deny")
expect(permission.sisyphus_task).toBe("deny") expect(permission.delegate_task).toBe("deny")
// call_omo_agent is NOW ALLOWED for subagents to spawn explore/librarian // call_omo_agent is NOW ALLOWED for subagents to spawn explore/librarian
expect(permission.call_omo_agent).toBe("allow") expect(permission.call_omo_agent).toBe("allow")
} }
}) })
test("task and sisyphus_task remain blocked when using permission format override", () => { test("task and delegate_task remain blocked when using permission format override", () => {
// #given // #given
const override = { const override = {
permission: { permission: {
task: "allow", task: "allow",
sisyphus_task: "allow", delegate_task: "allow",
call_omo_agent: "allow", call_omo_agent: "allow",
read: "allow", read: "allow",
}, },
@ -185,17 +185,17 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
// #when // #when
const result = createSisyphusJuniorAgentWithOverrides(override as Parameters<typeof createSisyphusJuniorAgentWithOverrides>[0]) const result = createSisyphusJuniorAgentWithOverrides(override as Parameters<typeof createSisyphusJuniorAgentWithOverrides>[0])
// #then - task/sisyphus_task blocked, but call_omo_agent allowed for explore/librarian spawning // #then - task/delegate_task blocked, but call_omo_agent allowed for explore/librarian spawning
const tools = result.tools as Record<string, boolean> | undefined const tools = result.tools as Record<string, boolean> | undefined
const permission = result.permission as Record<string, string> | undefined const permission = result.permission as Record<string, string> | undefined
if (tools) { if (tools) {
expect(tools.task).toBe(false) expect(tools.task).toBe(false)
expect(tools.sisyphus_task).toBe(false) expect(tools.delegate_task).toBe(false)
expect(tools.call_omo_agent).toBe(true) expect(tools.call_omo_agent).toBe(true)
} }
if (permission) { if (permission) {
expect(permission.task).toBe("deny") expect(permission.task).toBe("deny")
expect(permission.sisyphus_task).toBe("deny") expect(permission.delegate_task).toBe("deny")
expect(permission.call_omo_agent).toBe("allow") expect(permission.call_omo_agent).toBe("allow")
} }
}) })

View File

@ -14,7 +14,7 @@ Execute tasks directly. NEVER delegate or spawn other agents.
<Critical_Constraints> <Critical_Constraints>
BLOCKED ACTIONS (will fail if attempted): BLOCKED ACTIONS (will fail if attempted):
- task tool: BLOCKED - task tool: BLOCKED
- sisyphus_task tool: BLOCKED - delegate_task tool: BLOCKED
ALLOWED: call_omo_agent - You CAN spawn explore/librarian agents for research. ALLOWED: call_omo_agent - You CAN spawn explore/librarian agents for research.
You work ALONE for implementation. No delegation of implementation tasks. You work ALONE for implementation. No delegation of implementation tasks.
@ -75,7 +75,7 @@ function buildSisyphusJuniorPrompt(promptAppend?: string): string {
// Core tools that Sisyphus-Junior must NEVER have access to // Core tools that Sisyphus-Junior must NEVER have access to
// Note: call_omo_agent is ALLOWED so subagents can spawn explore/librarian // Note: call_omo_agent is ALLOWED so subagents can spawn explore/librarian
const BLOCKED_TOOLS = ["task", "sisyphus_task"] const BLOCKED_TOOLS = ["task", "delegate_task"]
export const SISYPHUS_JUNIOR_DEFAULTS = { export const SISYPHUS_JUNIOR_DEFAULTS = {
model: "anthropic/claude-sonnet-4-5", model: "anthropic/claude-sonnet-4-5",

View File

@ -122,7 +122,7 @@ IMPORTANT: If codebase appears undisciplined, verify before assuming:
const SISYPHUS_PRE_DELEGATION_PLANNING = `### Pre-Delegation Planning (MANDATORY) const SISYPHUS_PRE_DELEGATION_PLANNING = `### Pre-Delegation Planning (MANDATORY)
**BEFORE every \`sisyphus_task\` call, EXPLICITLY declare your reasoning.** **BEFORE every \`delegate_task\` call, EXPLICITLY declare your reasoning.**
#### Step 1: Identify Task Requirements #### Step 1: Identify Task Requirements
@ -160,27 +160,27 @@ Ask yourself:
**MANDATORY FORMAT:** **MANDATORY FORMAT:**
\`\`\` \`\`\`
I will use sisyphus_task with: I will use delegate_task with:
- **Category/Agent**: [name] - **Category/Agent**: [name]
- **Reason**: [why this choice fits the task] - **Reason**: [why this choice fits the task]
- **Skills** (if any): [skill names] - **Skills** (if any): [skill names]
- **Expected Outcome**: [what success looks like] - **Expected Outcome**: [what success looks like]
\`\`\` \`\`\`
**Then** make the sisyphus_task call. **Then** make the delegate_task call.
#### Examples #### Examples
** CORRECT: Explicit Pre-Declaration** ** CORRECT: Explicit Pre-Declaration**
\`\`\` \`\`\`
I will use sisyphus_task with: I will use delegate_task with:
- **Category**: visual - **Category**: visual
- **Reason**: This task requires building a responsive dashboard UI with animations - visual design is the core requirement - **Reason**: This task requires building a responsive dashboard UI with animations - visual design is the core requirement
- **Skills**: ["frontend-ui-ux"] - **Skills**: ["frontend-ui-ux"]
- **Expected Outcome**: Fully styled, responsive dashboard component with smooth transitions - **Expected Outcome**: Fully styled, responsive dashboard component with smooth transitions
sisyphus_task( delegate_task(
category="visual", category="visual",
skills=["frontend-ui-ux"], skills=["frontend-ui-ux"],
prompt="Create a responsive dashboard component with..." prompt="Create a responsive dashboard component with..."
@ -190,13 +190,13 @@ sisyphus_task(
** CORRECT: Agent-Specific Delegation** ** CORRECT: Agent-Specific Delegation**
\`\`\` \`\`\`
I will use sisyphus_task with: I will use delegate_task with:
- **Agent**: oracle - **Agent**: oracle
- **Reason**: This architectural decision involves trade-offs between scalability and complexity - requires high-IQ strategic analysis - **Reason**: This architectural decision involves trade-offs between scalability and complexity - requires high-IQ strategic analysis
- **Skills**: [] - **Skills**: []
- **Expected Outcome**: Clear recommendation with pros/cons analysis - **Expected Outcome**: Clear recommendation with pros/cons analysis
sisyphus_task( delegate_task(
agent="oracle", agent="oracle",
skills=[], skills=[],
prompt="Evaluate this microservices architecture proposal..." prompt="Evaluate this microservices architecture proposal..."
@ -206,13 +206,13 @@ sisyphus_task(
** CORRECT: Background Exploration** ** CORRECT: Background Exploration**
\`\`\` \`\`\`
I will use sisyphus_task with: I will use delegate_task with:
- **Agent**: explore - **Agent**: explore
- **Reason**: Need to find all authentication implementations across the codebase - this is contextual grep - **Reason**: Need to find all authentication implementations across the codebase - this is contextual grep
- **Skills**: [] - **Skills**: []
- **Expected Outcome**: List of files containing auth patterns - **Expected Outcome**: List of files containing auth patterns
sisyphus_task( delegate_task(
agent="explore", agent="explore",
background=true, background=true,
prompt="Find all authentication implementations in the codebase" prompt="Find all authentication implementations in the codebase"
@ -223,7 +223,7 @@ sisyphus_task(
\`\`\` \`\`\`
// Immediately calling without explicit reasoning // Immediately calling without explicit reasoning
sisyphus_task(category="visual", prompt="Build a dashboard") delegate_task(category="visual", prompt="Build a dashboard")
\`\`\` \`\`\`
** WRONG: Vague Reasoning** ** WRONG: Vague Reasoning**
@ -231,12 +231,12 @@ sisyphus_task(category="visual", prompt="Build a dashboard")
\`\`\` \`\`\`
I'll use visual category because it's frontend work. I'll use visual category because it's frontend work.
sisyphus_task(category="visual", ...) delegate_task(category="visual", ...)
\`\`\` \`\`\`
#### Enforcement #### Enforcement
**BLOCKING VIOLATION**: If you call \`sisyphus_task\` without the 4-part declaration, you have violated protocol. **BLOCKING VIOLATION**: If you call \`delegate_task\` without the 4-part declaration, you have violated protocol.
**Recovery**: Stop, declare explicitly, then proceed.` **Recovery**: Stop, declare explicitly, then proceed.`
@ -247,11 +247,11 @@ const SISYPHUS_PARALLEL_EXECUTION = `### Parallel Execution (DEFAULT behavior)
\`\`\`typescript \`\`\`typescript
// CORRECT: Always background, always parallel // CORRECT: Always background, always parallel
// Contextual Grep (internal) // Contextual Grep (internal)
sisyphus_task(agent="explore", prompt="Find auth implementations in our codebase...") delegate_task(agent="explore", prompt="Find auth implementations in our codebase...")
sisyphus_task(agent="explore", prompt="Find error handling patterns here...") delegate_task(agent="explore", prompt="Find error handling patterns here...")
// Reference Grep (external) // Reference Grep (external)
sisyphus_task(agent="librarian", prompt="Find JWT best practices in official docs...") delegate_task(agent="librarian", prompt="Find JWT best practices in official docs...")
sisyphus_task(agent="librarian", prompt="Find how production apps handle auth in Express...") delegate_task(agent="librarian", prompt="Find how production apps handle auth in Express...")
// Continue working immediately. Collect with background_output when needed. // Continue working immediately. Collect with background_output when needed.
// WRONG: Sequential or blocking // WRONG: Sequential or blocking
@ -274,7 +274,7 @@ Pass \`resume=session_id\` to continue previous agent with FULL CONTEXT PRESERVE
**Example:** **Example:**
\`\`\` \`\`\`
sisyphus_task(resume="ses_abc123", prompt="The previous search missed X. Also look for Y.") delegate_task(resume="ses_abc123", prompt="The previous search missed X. Also look for Y.")
\`\`\` \`\`\`
### Search Stop Conditions ### Search Stop Conditions

View File

@ -13,7 +13,7 @@ import { createOrchestratorSisyphusAgent, orchestratorSisyphusAgent } from "./or
import { createMomusAgent } from "./momus" import { createMomusAgent } from "./momus"
import type { AvailableAgent } from "./sisyphus-prompt-builder" import type { AvailableAgent } from "./sisyphus-prompt-builder"
import { deepMerge } from "../shared" import { deepMerge } from "../shared"
import { DEFAULT_CATEGORIES } from "../tools/sisyphus-task/constants" import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants"
import { resolveMultipleSkills } from "../features/opencode-skill-loader/skill-content" import { resolveMultipleSkills } from "../features/opencode-skill-loader/skill-content"
type AgentSource = AgentFactory | AgentConfig type AgentSource = AgentFactory | AgentConfig

View File

@ -84,7 +84,7 @@ export const HookNameSchema = z.enum([
"claude-code-hooks", "claude-code-hooks",
"auto-slash-command", "auto-slash-command",
"edit-error-recovery", "edit-error-recovery",
"sisyphus-task-retry", "delegate-task-retry",
"prometheus-md-only", "prometheus-md-only",
"start-work", "start-work",
"sisyphus-orchestrator", "sisyphus-orchestrator",

View File

@ -61,7 +61,7 @@ features/
- Session-scoped MCP server lifecycle management - Session-scoped MCP server lifecycle management
## ANTI-PATTERNS ## ANTI-PATTERNS
- Sequential execution for independent tasks (use `sisyphus_task`) - Sequential execution for independent tasks (use `delegate_task`)
- Trusting agent self-reports without verification - Trusting agent self-reports without verification
- Blocking main thread during loader initialization - Blocking main thread during loader initialization
- Manual version bumping in `package.json` - Manual version bumping in `package.json`

View File

@ -980,7 +980,7 @@ describe("BackgroundManager.trackTask", () => {
sessionID: "session-1", sessionID: "session-1",
parentSessionID: "parent-session", parentSessionID: "parent-session",
description: "external task", description: "external task",
agent: "sisyphus_task", agent: "delegate_task",
concurrencyKey: "external-key", concurrencyKey: "external-key",
} }
@ -1015,7 +1015,7 @@ describe("BackgroundManager.resume concurrency key", () => {
sessionID: "session-1", sessionID: "session-1",
parentSessionID: "parent-session", parentSessionID: "parent-session",
description: "external task", description: "external task",
agent: "sisyphus_task", agent: "delegate_task",
concurrencyKey: "external-key", concurrencyKey: "external-key",
}) })

View File

@ -180,7 +180,7 @@ export class BackgroundManager {
tools: { tools: {
...getAgentToolRestrictions(input.agent), ...getAgentToolRestrictions(input.agent),
task: false, task: false,
sisyphus_task: false, delegate_task: false,
call_omo_agent: true, call_omo_agent: true,
}, },
parts: [{ type: "text", text: input.prompt }], parts: [{ type: "text", text: input.prompt }],
@ -249,7 +249,7 @@ export class BackgroundManager {
} }
/** /**
* Track a task created elsewhere (e.g., from sisyphus_task) for notification tracking. * Track a task created elsewhere (e.g., from delegate_task) for notification tracking.
* This allows tasks created by other tools to receive the same toast/prompt notifications. * This allows tasks created by other tools to receive the same toast/prompt notifications.
*/ */
async trackTask(input: { async trackTask(input: {
@ -296,7 +296,7 @@ export class BackgroundManager {
return existingTask return existingTask
} }
const concurrencyGroup = input.concurrencyKey ?? input.agent ?? "sisyphus_task" const concurrencyGroup = input.concurrencyKey ?? input.agent ?? "delegate_task"
// Acquire concurrency slot if a key is provided // Acquire concurrency slot if a key is provided
if (input.concurrencyKey) { if (input.concurrencyKey) {
@ -310,7 +310,7 @@ export class BackgroundManager {
parentMessageID: "", parentMessageID: "",
description: input.description, description: input.description,
prompt: "", prompt: "",
agent: input.agent || "sisyphus_task", agent: input.agent || "delegate_task",
status: "running", status: "running",
startedAt: new Date(), startedAt: new Date(),
progress: { progress: {
@ -409,7 +409,7 @@ export class BackgroundManager {
tools: { tools: {
...getAgentToolRestrictions(existingTask.agent), ...getAgentToolRestrictions(existingTask.agent),
task: false, task: false,
sisyphus_task: false, delegate_task: false,
call_omo_agent: true, call_omo_agent: true,
}, },
parts: [{ type: "text", text: input.prompt }], parts: [{ type: "text", text: input.prompt }],

View File

@ -45,12 +45,12 @@ Don't wait—these run async while main session works.
\`\`\` \`\`\`
// Fire all at once, collect results later // Fire all at once, collect results later
sisyphus_task(agent="explore", prompt="Project structure: PREDICT standard patterns for detected language → REPORT deviations only") delegate_task(agent="explore", prompt="Project structure: PREDICT standard patterns for detected language → REPORT deviations only")
sisyphus_task(agent="explore", prompt="Entry points: FIND main files → REPORT non-standard organization") delegate_task(agent="explore", prompt="Entry points: FIND main files → REPORT non-standard organization")
sisyphus_task(agent="explore", prompt="Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) → REPORT project-specific rules") delegate_task(agent="explore", prompt="Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) → REPORT project-specific rules")
sisyphus_task(agent="explore", prompt="Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments → LIST forbidden patterns") delegate_task(agent="explore", prompt="Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments → LIST forbidden patterns")
sisyphus_task(agent="explore", prompt="Build/CI: FIND .github/workflows, Makefile → REPORT non-standard patterns") delegate_task(agent="explore", prompt="Build/CI: FIND .github/workflows, Makefile → REPORT non-standard patterns")
sisyphus_task(agent="explore", prompt="Test patterns: FIND test configs, test structure → REPORT unique conventions") delegate_task(agent="explore", prompt="Test patterns: FIND test configs, test structure → REPORT unique conventions")
\`\`\` \`\`\`
<dynamic-agents> <dynamic-agents>
@ -76,9 +76,9 @@ max_depth=$(find . -type d -not -path '*/node_modules/*' -not -path '*/.git/*' |
Example spawning: Example spawning:
\`\`\` \`\`\`
// 500 files, 50k lines, depth 6, 15 large files → spawn 5+5+2+1 = 13 additional agents // 500 files, 50k lines, depth 6, 15 large files → spawn 5+5+2+1 = 13 additional agents
sisyphus_task(agent="explore", prompt="Large file analysis: FIND files >500 lines, REPORT complexity hotspots") delegate_task(agent="explore", prompt="Large file analysis: FIND files >500 lines, REPORT complexity hotspots")
sisyphus_task(agent="explore", prompt="Deep modules at depth 4+: FIND hidden patterns, internal conventions") delegate_task(agent="explore", prompt="Deep modules at depth 4+: FIND hidden patterns, internal conventions")
sisyphus_task(agent="explore", prompt="Cross-cutting concerns: FIND shared utilities across directories") delegate_task(agent="explore", prompt="Cross-cutting concerns: FIND shared utilities across directories")
// ... more based on calculation // ... more based on calculation
\`\`\` \`\`\`
</dynamic-agents> </dynamic-agents>
@ -240,7 +240,7 @@ Launch document-writer agents for each location:
\`\`\` \`\`\`
for loc in AGENTS_LOCATIONS (except root): for loc in AGENTS_LOCATIONS (except root):
sisyphus_task(agent="document-writer", prompt=\\\` delegate_task(agent="document-writer", prompt=\\\`
Generate AGENTS.md for: \${loc.path} Generate AGENTS.md for: \${loc.path}
- Reason: \${loc.reason} - Reason: \${loc.reason}
- 30-80 lines max - 30-80 lines max

View File

@ -1,6 +1,6 @@
--- ---
name: git-master name: git-master
description: "MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with sisyphus_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'." description: "MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with delegate_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'."
--- ---
# Git Master Agent # Git Master Agent

View File

@ -95,7 +95,7 @@ Interpret creatively and make unexpected choices that feel genuinely designed fo
const gitMasterSkill: BuiltinSkill = { const gitMasterSkill: BuiltinSkill = {
name: "git-master", name: "git-master",
description: description:
"MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with sisyphus_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'.", "MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with delegate_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'.",
template: `# Git Master Agent template: `# Git Master Agent
You are a Git expert combining three specializations: You are a Git expert combining three specializations:

View File

@ -24,7 +24,7 @@ export const TARGET_TOOLS = new Set([
export const AGENT_TOOLS = new Set([ export const AGENT_TOOLS = new Set([
"task", "task",
"call_omo_agent", "call_omo_agent",
"sisyphus_task", "delegate_task",
]); ]);
export const REMINDER_MESSAGE = ` export const REMINDER_MESSAGE = `
@ -32,13 +32,13 @@ export const REMINDER_MESSAGE = `
You called a search/fetch tool directly without leveraging specialized agents. You called a search/fetch tool directly without leveraging specialized agents.
RECOMMENDED: Use sisyphus_task with explore/librarian agents for better results: RECOMMENDED: Use delegate_task with explore/librarian agents for better results:
\`\`\` \`\`\`
// Parallel exploration - fire multiple agents simultaneously // Parallel exploration - fire multiple agents simultaneously
sisyphus_task(agent="explore", prompt="Find all files matching pattern X") delegate_task(agent="explore", prompt="Find all files matching pattern X")
sisyphus_task(agent="explore", prompt="Search for implementation of Y") delegate_task(agent="explore", prompt="Search for implementation of Y")
sisyphus_task(agent="librarian", prompt="Lookup documentation for Z") delegate_task(agent="librarian", prompt="Lookup documentation for Z")
// Then continue your work while they run in background // Then continue your work while they run in background
// System will notify you when each completes // System will notify you when each completes
@ -50,5 +50,5 @@ WHY:
- Specialized agents have domain expertise - Specialized agents have domain expertise
- Reduces context window usage in main session - Reduces context window usage in main session
ALWAYS prefer: Multiple parallel sisyphus_task calls > Direct tool calls ALWAYS prefer: Multiple parallel delegate_task calls > Direct tool calls
`; `;

View File

@ -145,13 +145,7 @@ export function createClaudeCodeHooksHook(
const hookContent = result.messages.join("\n\n") const hookContent = result.messages.join("\n\n")
log(`[claude-code-hooks] Injecting ${result.messages.length} hook messages`, { sessionID: input.sessionID, contentLength: hookContent.length, isFirstMessage }) log(`[claude-code-hooks] Injecting ${result.messages.length} hook messages`, { sessionID: input.sessionID, contentLength: hookContent.length, isFirstMessage })
if (isFirstMessage) { if (contextCollector) {
const idx = output.parts.findIndex((p) => p.type === "text" && p.text)
if (idx >= 0) {
output.parts[idx].text = `${hookContent}\n\n${output.parts[idx].text ?? ""}`
log("UserPromptSubmit hooks prepended to first message parts directly", { sessionID: input.sessionID })
}
} else if (contextCollector) {
log("[DEBUG] Registering hook content to contextCollector", { log("[DEBUG] Registering hook content to contextCollector", {
sessionID: input.sessionID, sessionID: input.sessionID,
contentLength: hookContent.length, contentLength: hookContent.length,
@ -168,14 +162,6 @@ export function createClaudeCodeHooksHook(
sessionID: input.sessionID, sessionID: input.sessionID,
contentLength: hookContent.length, contentLength: hookContent.length,
}) })
} else {
const idx = output.parts.findIndex((p) => p.type === "text" && p.text)
if (idx >= 0) {
output.parts[idx].text = `${hookContent}\n\n${output.parts[idx].text ?? ""}`
log("Hook content prepended to message (fallback)", {
sessionID: input.sessionID,
})
}
} }
} }
} }
@ -257,7 +243,7 @@ export function createClaudeCodeHooksHook(
const cachedInput = getToolInput(input.sessionID, input.tool, input.callID) || {} const cachedInput = getToolInput(input.sessionID, input.tool, input.callID) || {}
// Use metadata if available and non-empty, otherwise wrap output.output in a structured object // Use metadata if available and non-empty, otherwise wrap output.output in a structured object
// This ensures plugin tools (call_omo_agent, sisyphus_task, task) that return strings // This ensures plugin tools (call_omo_agent, delegate_task, task) that return strings
// get their results properly recorded in transcripts instead of empty {} // get their results properly recorded in transcripts instead of empty {}
const metadata = output.metadata as Record<string, unknown> | undefined const metadata = output.metadata as Record<string, unknown> | undefined
const hasMetadata = metadata && typeof metadata === "object" && Object.keys(metadata).length > 0 const hasMetadata = metadata && typeof metadata === "object" && Object.keys(metadata).length > 0

View File

@ -1,18 +1,18 @@
import { describe, expect, it } from "bun:test" import { describe, expect, it } from "bun:test"
import { import {
SISYPHUS_TASK_ERROR_PATTERNS, DELEGATE_TASK_ERROR_PATTERNS,
detectSisyphusTaskError, detectDelegateTaskError,
buildRetryGuidance, buildRetryGuidance,
} from "./index" } from "./index"
describe("sisyphus-task-retry", () => { describe("sisyphus-task-retry", () => {
describe("SISYPHUS_TASK_ERROR_PATTERNS", () => { describe("DELEGATE_TASK_ERROR_PATTERNS", () => {
// #given error patterns are defined // #given error patterns are defined
// #then should include all known sisyphus_task error types // #then should include all known delegate_task error types
it("should contain all known error patterns", () => { it("should contain all known error patterns", () => {
expect(SISYPHUS_TASK_ERROR_PATTERNS.length).toBeGreaterThan(5) expect(DELEGATE_TASK_ERROR_PATTERNS.length).toBeGreaterThan(5)
const patternTexts = SISYPHUS_TASK_ERROR_PATTERNS.map(p => p.pattern) const patternTexts = DELEGATE_TASK_ERROR_PATTERNS.map(p => p.pattern)
expect(patternTexts).toContain("run_in_background") expect(patternTexts).toContain("run_in_background")
expect(patternTexts).toContain("skills") expect(patternTexts).toContain("skills")
expect(patternTexts).toContain("category OR subagent_type") expect(patternTexts).toContain("category OR subagent_type")
@ -21,14 +21,14 @@ describe("sisyphus-task-retry", () => {
}) })
}) })
describe("detectSisyphusTaskError", () => { describe("detectDelegateTaskError", () => {
// #given tool output with run_in_background error // #given tool output with run_in_background error
// #when detecting error // #when detecting error
// #then should return matching error info // #then should return matching error info
it("should detect run_in_background missing error", () => { it("should detect run_in_background missing error", () => {
const output = "❌ Invalid arguments: 'run_in_background' parameter is REQUIRED. Use run_in_background=false for task delegation." const output = "❌ Invalid arguments: 'run_in_background' parameter is REQUIRED. Use run_in_background=false for task delegation."
const result = detectSisyphusTaskError(output) const result = detectDelegateTaskError(output)
expect(result).not.toBeNull() expect(result).not.toBeNull()
expect(result?.errorType).toBe("missing_run_in_background") expect(result?.errorType).toBe("missing_run_in_background")
@ -37,7 +37,7 @@ describe("sisyphus-task-retry", () => {
it("should detect skills missing error", () => { it("should detect skills missing error", () => {
const output = "❌ Invalid arguments: 'skills' parameter is REQUIRED. Use skills=[] if no skills needed." const output = "❌ Invalid arguments: 'skills' parameter is REQUIRED. Use skills=[] if no skills needed."
const result = detectSisyphusTaskError(output) const result = detectDelegateTaskError(output)
expect(result).not.toBeNull() expect(result).not.toBeNull()
expect(result?.errorType).toBe("missing_skills") expect(result?.errorType).toBe("missing_skills")
@ -46,7 +46,7 @@ describe("sisyphus-task-retry", () => {
it("should detect category/subagent mutual exclusion error", () => { it("should detect category/subagent mutual exclusion error", () => {
const output = "❌ Invalid arguments: Provide EITHER category OR subagent_type, not both." const output = "❌ Invalid arguments: Provide EITHER category OR subagent_type, not both."
const result = detectSisyphusTaskError(output) const result = detectDelegateTaskError(output)
expect(result).not.toBeNull() expect(result).not.toBeNull()
expect(result?.errorType).toBe("mutual_exclusion") expect(result?.errorType).toBe("mutual_exclusion")
@ -55,7 +55,7 @@ describe("sisyphus-task-retry", () => {
it("should detect unknown category error", () => { it("should detect unknown category error", () => {
const output = '❌ Unknown category: "invalid-cat". Available: visual-engineering, ultrabrain, quick' const output = '❌ Unknown category: "invalid-cat". Available: visual-engineering, ultrabrain, quick'
const result = detectSisyphusTaskError(output) const result = detectDelegateTaskError(output)
expect(result).not.toBeNull() expect(result).not.toBeNull()
expect(result?.errorType).toBe("unknown_category") expect(result?.errorType).toBe("unknown_category")
@ -64,7 +64,7 @@ describe("sisyphus-task-retry", () => {
it("should detect unknown agent error", () => { it("should detect unknown agent error", () => {
const output = '❌ Unknown agent: "fake-agent". Available agents: explore, librarian, oracle' const output = '❌ Unknown agent: "fake-agent". Available agents: explore, librarian, oracle'
const result = detectSisyphusTaskError(output) const result = detectDelegateTaskError(output)
expect(result).not.toBeNull() expect(result).not.toBeNull()
expect(result?.errorType).toBe("unknown_agent") expect(result?.errorType).toBe("unknown_agent")
@ -73,7 +73,7 @@ describe("sisyphus-task-retry", () => {
it("should return null for successful output", () => { it("should return null for successful output", () => {
const output = "Background task launched.\n\nTask ID: bg_12345\nSession ID: ses_abc" const output = "Background task launched.\n\nTask ID: bg_12345\nSession ID: ses_abc"
const result = detectSisyphusTaskError(output) const result = detectDelegateTaskError(output)
expect(result).toBeNull() expect(result).toBeNull()
}) })

View File

@ -1,12 +1,12 @@
import type { PluginInput } from "@opencode-ai/plugin" import type { PluginInput } from "@opencode-ai/plugin"
export interface SisyphusTaskErrorPattern { export interface DelegateTaskErrorPattern {
pattern: string pattern: string
errorType: string errorType: string
fixHint: string fixHint: string
} }
export const SISYPHUS_TASK_ERROR_PATTERNS: SisyphusTaskErrorPattern[] = [ export const DELEGATE_TASK_ERROR_PATTERNS: DelegateTaskErrorPattern[] = [
{ {
pattern: "run_in_background", pattern: "run_in_background",
errorType: "missing_run_in_background", errorType: "missing_run_in_background",
@ -45,7 +45,7 @@ export const SISYPHUS_TASK_ERROR_PATTERNS: SisyphusTaskErrorPattern[] = [
{ {
pattern: "Cannot call primary agent", pattern: "Cannot call primary agent",
errorType: "primary_agent", errorType: "primary_agent",
fixHint: "Primary agents cannot be called via sisyphus_task. Use a subagent like 'explore', 'oracle', or 'librarian'", fixHint: "Primary agents cannot be called via delegate_task. Use a subagent like 'explore', 'oracle', or 'librarian'",
}, },
{ {
pattern: "Skills not found", pattern: "Skills not found",
@ -59,10 +59,10 @@ export interface DetectedError {
originalOutput: string originalOutput: string
} }
export function detectSisyphusTaskError(output: string): DetectedError | null { export function detectDelegateTaskError(output: string): DetectedError | null {
if (!output.includes("❌")) return null if (!output.includes("❌")) return null
for (const errorPattern of SISYPHUS_TASK_ERROR_PATTERNS) { for (const errorPattern of DELEGATE_TASK_ERROR_PATTERNS) {
if (output.includes(errorPattern.pattern)) { if (output.includes(errorPattern.pattern)) {
return { return {
errorType: errorPattern.errorType, errorType: errorPattern.errorType,
@ -80,16 +80,16 @@ function extractAvailableList(output: string): string | null {
} }
export function buildRetryGuidance(errorInfo: DetectedError): string { export function buildRetryGuidance(errorInfo: DetectedError): string {
const pattern = SISYPHUS_TASK_ERROR_PATTERNS.find( const pattern = DELEGATE_TASK_ERROR_PATTERNS.find(
(p) => p.errorType === errorInfo.errorType (p) => p.errorType === errorInfo.errorType
) )
if (!pattern) { if (!pattern) {
return `[sisyphus_task ERROR] Fix the error and retry with correct parameters.` return `[delegate_task ERROR] Fix the error and retry with correct parameters.`
} }
let guidance = ` let guidance = `
[sisyphus_task CALL FAILED - IMMEDIATE RETRY REQUIRED] [delegate_task CALL FAILED - IMMEDIATE RETRY REQUIRED]
**Error Type**: ${errorInfo.errorType} **Error Type**: ${errorInfo.errorType}
**Fix**: ${pattern.fixHint} **Fix**: ${pattern.fixHint}
@ -101,11 +101,11 @@ export function buildRetryGuidance(errorInfo: DetectedError): string {
} }
guidance += ` guidance += `
**Action**: Retry sisyphus_task NOW with corrected parameters. **Action**: Retry delegate_task NOW with corrected parameters.
Example of CORRECT call: Example of CORRECT call:
\`\`\` \`\`\`
sisyphus_task( delegate_task(
description="Task description", description="Task description",
prompt="Detailed prompt...", prompt="Detailed prompt...",
category="general", // OR subagent_type="explore" category="general", // OR subagent_type="explore"
@ -118,15 +118,15 @@ sisyphus_task(
return guidance return guidance
} }
export function createSisyphusTaskRetryHook(_ctx: PluginInput) { export function createDelegateTaskRetryHook(_ctx: PluginInput) {
return { return {
"tool.execute.after": async ( "tool.execute.after": async (
input: { tool: string; sessionID: string; callID: string }, input: { tool: string; sessionID: string; callID: string },
output: { title: string; output: string; metadata: unknown } output: { title: string; output: string; metadata: unknown }
) => { ) => {
if (input.tool.toLowerCase() !== "sisyphus_task") return if (input.tool.toLowerCase() !== "delegate_task") return
const errorInfo = detectSisyphusTaskError(output.output) const errorInfo = detectDelegateTaskError(output.output)
if (errorInfo) { if (errorInfo) {
const guidance = buildRetryGuidance(errorInfo) const guidance = buildRetryGuidance(errorInfo)
output.output += `\n${guidance}` output.output += `\n${guidance}`

View File

@ -30,4 +30,4 @@ export { createPrometheusMdOnlyHook } from "./prometheus-md-only";
export { createTaskResumeInfoHook } from "./task-resume-info"; export { createTaskResumeInfoHook } from "./task-resume-info";
export { createStartWorkHook } from "./start-work"; export { createStartWorkHook } from "./start-work";
export { createSisyphusOrchestratorHook } from "./sisyphus-orchestrator"; export { createSisyphusOrchestratorHook } from "./sisyphus-orchestrator";
export { createSisyphusTaskRetryHook } from "./sisyphus-task-retry"; export { createDelegateTaskRetryHook } from "./delegate-task-retry";

View File

@ -12,7 +12,7 @@ You ARE the planner. You ARE NOT an implementer. You DO NOT write code. You DO N
| Write/Edit | \`.sisyphus/**/*.md\` ONLY | Everything else | | Write/Edit | \`.sisyphus/**/*.md\` ONLY | Everything else |
| Read | All files | - | | Read | All files | - |
| Bash | Research commands only | Implementation commands | | Bash | Research commands only | Implementation commands |
| sisyphus_task | explore, librarian | - | | delegate_task | explore, librarian | - |
**IF YOU TRY TO WRITE/EDIT OUTSIDE \`.sisyphus/\`:** **IF YOU TRY TO WRITE/EDIT OUTSIDE \`.sisyphus/\`:**
- System will BLOCK your action - System will BLOCK your action
@ -36,9 +36,9 @@ You ARE the planner. Your job: create bulletproof work plans.
### Research Protocol ### Research Protocol
1. **Fire parallel background agents** for comprehensive context: 1. **Fire parallel background agents** for comprehensive context:
\`\`\` \`\`\`
sisyphus_task(agent="explore", prompt="Find existing patterns for [topic] in codebase", background=true) delegate_task(agent="explore", prompt="Find existing patterns for [topic] in codebase", background=true)
sisyphus_task(agent="explore", prompt="Find test infrastructure and conventions", background=true) delegate_task(agent="explore", prompt="Find test infrastructure and conventions", background=true)
sisyphus_task(agent="librarian", prompt="Find official docs and best practices for [technology]", background=true) delegate_task(agent="librarian", prompt="Find official docs and best practices for [technology]", background=true)
\`\`\` \`\`\`
2. **Wait for results** before planning - rushed plans fail 2. **Wait for results** before planning - rushed plans fail
3. **Synthesize findings** into informed requirements 3. **Synthesize findings** into informed requirements
@ -101,14 +101,14 @@ TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
## EXECUTION RULES ## EXECUTION RULES
- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each. - **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each.
- **PARALLEL**: Fire independent agent calls simultaneously via sisyphus_task(background=true) - NEVER wait sequentially. - **PARALLEL**: Fire independent agent calls simultaneously via delegate_task(background=true) - NEVER wait sequentially.
- **BACKGROUND FIRST**: Use sisyphus_task for exploration/research agents (10+ concurrent if needed). - **BACKGROUND FIRST**: Use delegate_task for exploration/research agents (10+ concurrent if needed).
- **VERIFY**: Re-read request after completion. Check ALL requirements met before reporting done. - **VERIFY**: Re-read request after completion. Check ALL requirements met before reporting done.
- **DELEGATE**: Don't do everything yourself - orchestrate specialized agents for their strengths. - **DELEGATE**: Don't do everything yourself - orchestrate specialized agents for their strengths.
## WORKFLOW ## WORKFLOW
1. Analyze the request and identify required capabilities 1. Analyze the request and identify required capabilities
2. Spawn exploration/librarian agents via sisyphus_task(background=true) in PARALLEL (10+ if needed) 2. Spawn exploration/librarian agents via delegate_task(background=true) in PARALLEL (10+ if needed)
3. Always Use Plan agent with gathered context to create detailed work breakdown 3. Always Use Plan agent with gathered context to create detailed work breakdown
4. Execute with continuous verification against original requirements 4. Execute with continuous verification against original requirements

View File

@ -154,11 +154,11 @@ describe("prometheus-md-only", () => {
).resolves.toBeUndefined() ).resolves.toBeUndefined()
}) })
test("should inject read-only warning when Prometheus calls sisyphus_task", async () => { test("should inject read-only warning when Prometheus calls delegate_task", async () => {
// #given // #given
const hook = createPrometheusMdOnlyHook(createMockPluginInput()) const hook = createPrometheusMdOnlyHook(createMockPluginInput())
const input = { const input = {
tool: "sisyphus_task", tool: "delegate_task",
sessionID: TEST_SESSION_ID, sessionID: TEST_SESSION_ID,
callID: "call-1", callID: "call-1",
} }
@ -216,7 +216,7 @@ describe("prometheus-md-only", () => {
// #given // #given
const hook = createPrometheusMdOnlyHook(createMockPluginInput()) const hook = createPrometheusMdOnlyHook(createMockPluginInput())
const input = { const input = {
tool: "sisyphus_task", tool: "delegate_task",
sessionID: TEST_SESSION_ID, sessionID: TEST_SESSION_ID,
callID: "call-1", callID: "call-1",
} }
@ -257,11 +257,11 @@ describe("prometheus-md-only", () => {
).resolves.toBeUndefined() ).resolves.toBeUndefined()
}) })
test("should not inject warning for non-Prometheus agents calling sisyphus_task", async () => { test("should not inject warning for non-Prometheus agents calling delegate_task", async () => {
// #given // #given
const hook = createPrometheusMdOnlyHook(createMockPluginInput()) const hook = createPrometheusMdOnlyHook(createMockPluginInput())
const input = { const input = {
tool: "sisyphus_task", tool: "delegate_task",
sessionID: TEST_SESSION_ID, sessionID: TEST_SESSION_ID,
callID: "call-1", callID: "call-1",
} }

View File

@ -61,7 +61,7 @@ function getMessageDir(sessionID: string): string | null {
return null return null
} }
const TASK_TOOLS = ["sisyphus_task", "task", "call_omo_agent"] const TASK_TOOLS = ["delegate_task", "task", "call_omo_agent"]
function getAgentFromMessageFiles(sessionID: string): string | undefined { function getAgentFromMessageFiles(sessionID: string): string | undefined {
const messageDir = getMessageDir(sessionID) const messageDir = getMessageDir(sessionID)

View File

@ -66,8 +66,8 @@ describe("sisyphus-orchestrator hook", () => {
}) })
describe("tool.execute.after handler", () => { describe("tool.execute.after handler", () => {
test("should ignore non-sisyphus_task tools", async () => { test("should ignore non-delegate_task tools", async () => {
// #given - hook and non-sisyphus_task tool // #given - hook and non-delegate_task tool
const hook = createSisyphusOrchestratorHook(createMockPluginInput()) const hook = createSisyphusOrchestratorHook(createMockPluginInput())
const output = { const output = {
title: "Test Tool", title: "Test Tool",
@ -110,7 +110,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
@ -134,14 +134,14 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
// #then - standalone verification reminder appended // #then - standalone verification reminder appended
expect(output.output).toContain("Task completed successfully") expect(output.output).toContain("Task completed successfully")
expect(output.output).toContain("MANDATORY:") expect(output.output).toContain("MANDATORY:")
expect(output.output).toContain("sisyphus_task(resume=") expect(output.output).toContain("delegate_task(resume=")
cleanupMessageStorage(sessionID) cleanupMessageStorage(sessionID)
}) })
@ -171,7 +171,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
@ -180,7 +180,7 @@ describe("sisyphus-orchestrator hook", () => {
expect(output.output).toContain("SUBAGENT WORK COMPLETED") expect(output.output).toContain("SUBAGENT WORK COMPLETED")
expect(output.output).toContain("test-plan") expect(output.output).toContain("test-plan")
expect(output.output).toContain("LIE") expect(output.output).toContain("LIE")
expect(output.output).toContain("sisyphus_task(resume=") expect(output.output).toContain("delegate_task(resume=")
cleanupMessageStorage(sessionID) cleanupMessageStorage(sessionID)
}) })
@ -210,7 +210,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
@ -247,7 +247,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
@ -283,7 +283,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
@ -320,7 +320,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
@ -357,12 +357,12 @@ describe("sisyphus-orchestrator hook", () => {
// #when // #when
await hook["tool.execute.after"]( await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID }, { tool: "delegate_task", sessionID },
output output
) )
// #then - should include resume instructions and verification // #then - should include resume instructions and verification
expect(output.output).toContain("sisyphus_task(resume=") expect(output.output).toContain("delegate_task(resume=")
expect(output.output).toContain("[x]") expect(output.output).toContain("[x]")
expect(output.output).toContain("MANDATORY:") expect(output.output).toContain("MANDATORY:")
@ -398,7 +398,7 @@ describe("sisyphus-orchestrator hook", () => {
// #then // #then
expect(output.output).toContain("DELEGATION REQUIRED") expect(output.output).toContain("DELEGATION REQUIRED")
expect(output.output).toContain("ORCHESTRATOR, not an IMPLEMENTER") expect(output.output).toContain("ORCHESTRATOR, not an IMPLEMENTER")
expect(output.output).toContain("sisyphus_task") expect(output.output).toContain("delegate_task")
}) })
test("should append delegation reminder when orchestrator edits outside .sisyphus/", async () => { test("should append delegation reminder when orchestrator edits outside .sisyphus/", async () => {

View File

@ -36,7 +36,7 @@ You just performed direct file modifications outside \`.sisyphus/\`.
**You are an ORCHESTRATOR, not an IMPLEMENTER.** **You are an ORCHESTRATOR, not an IMPLEMENTER.**
As an orchestrator, you should: As an orchestrator, you should:
- **DELEGATE** implementation work to subagents via \`sisyphus_task\` - **DELEGATE** implementation work to subagents via \`delegate_task\`
- **VERIFY** the work done by subagents - **VERIFY** the work done by subagents
- **COORDINATE** multiple tasks and ensure completion - **COORDINATE** multiple tasks and ensure completion
@ -46,7 +46,7 @@ You should NOT:
- Implement features yourself - Implement features yourself
**If you need to make changes:** **If you need to make changes:**
1. Use \`sisyphus_task\` to delegate to an appropriate subagent 1. Use \`delegate_task\` to delegate to an appropriate subagent
2. Provide clear instructions in the prompt 2. Provide clear instructions in the prompt
3. Verify the subagent's work after completion 3. Verify the subagent's work after completion
@ -120,7 +120,7 @@ You (orchestrator-sisyphus) are attempting to directly modify a file outside \`.
🚫 **THIS IS FORBIDDEN** (except for VERIFICATION purposes) 🚫 **THIS IS FORBIDDEN** (except for VERIFICATION purposes)
As an ORCHESTRATOR, you MUST: As an ORCHESTRATOR, you MUST:
1. **DELEGATE** all implementation work via \`sisyphus_task\` 1. **DELEGATE** all implementation work via \`delegate_task\`
2. **VERIFY** the work done by subagents (reading files is OK) 2. **VERIFY** the work done by subagents (reading files is OK)
3. **COORDINATE** - you orchestrate, you don't implement 3. **COORDINATE** - you orchestrate, you don't implement
@ -138,11 +138,11 @@ As an ORCHESTRATOR, you MUST:
**IF THIS IS FOR VERIFICATION:** **IF THIS IS FOR VERIFICATION:**
Proceed if you are verifying subagent work by making a small fix. Proceed if you are verifying subagent work by making a small fix.
But for any substantial changes, USE \`sisyphus_task\`. But for any substantial changes, USE \`delegate_task\`.
**CORRECT APPROACH:** **CORRECT APPROACH:**
\`\`\` \`\`\`
sisyphus_task( delegate_task(
category="...", category="...",
prompt="[specific single task with clear acceptance criteria]" prompt="[specific single task with clear acceptance criteria]"
) )
@ -185,7 +185,7 @@ function buildVerificationReminder(sessionId: string): string {
**If ANY verification fails, use this immediately:** **If ANY verification fails, use this immediately:**
\`\`\` \`\`\`
sisyphus_task(resume="${sessionId}", prompt="fix: [describe the specific failure]") delegate_task(resume="${sessionId}", prompt="fix: [describe the specific failure]")
\`\`\`` \`\`\``
} }
@ -656,12 +656,12 @@ export function createSisyphusOrchestratorHook(
return return
} }
// Check sisyphus_task - inject single-task directive // Check delegate_task - inject single-task directive
if (input.tool === "sisyphus_task") { if (input.tool === "delegate_task") {
const prompt = output.args.prompt as string | undefined const prompt = output.args.prompt as string | undefined
if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) { if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
output.args.prompt = prompt + `\n<system-reminder>${SINGLE_TASK_DIRECTIVE}</system-reminder>` output.args.prompt = prompt + `\n<system-reminder>${SINGLE_TASK_DIRECTIVE}</system-reminder>`
log(`[${HOOK_NAME}] Injected single-task directive to sisyphus_task`, { log(`[${HOOK_NAME}] Injected single-task directive to delegate_task`, {
sessionID: input.sessionID, sessionID: input.sessionID,
}) })
} }
@ -695,7 +695,7 @@ export function createSisyphusOrchestratorHook(
return return
} }
if (input.tool !== "sisyphus_task") { if (input.tool !== "delegate_task") {
return return
} }

View File

@ -1,4 +1,4 @@
const TARGET_TOOLS = ["task", "Task", "call_omo_agent", "sisyphus_task"] const TARGET_TOOLS = ["task", "Task", "call_omo_agent", "delegate_task"]
const SESSION_ID_PATTERNS = [ const SESSION_ID_PATTERNS = [
/Session ID: (ses_[a-zA-Z0-9_-]+)/, /Session ID: (ses_[a-zA-Z0-9_-]+)/,
@ -27,7 +27,7 @@ export function createTaskResumeInfoHook() {
const sessionId = extractSessionId(output.output) const sessionId = extractSessionId(output.output)
if (!sessionId) return if (!sessionId) return
output.output = output.output.trimEnd() + `\n\nto resume: sisyphus_task(resume="${sessionId}", prompt="...")` output.output = output.output.trimEnd() + `\n\nto resume: delegate_task(resume="${sessionId}", prompt="...")`
} }
return { return {

View File

@ -26,7 +26,7 @@ import {
createRalphLoopHook, createRalphLoopHook,
createAutoSlashCommandHook, createAutoSlashCommandHook,
createEditErrorRecoveryHook, createEditErrorRecoveryHook,
createSisyphusTaskRetryHook, createDelegateTaskRetryHook,
createTaskResumeInfoHook, createTaskResumeInfoHook,
createStartWorkHook, createStartWorkHook,
createSisyphusOrchestratorHook, createSisyphusOrchestratorHook,
@ -64,7 +64,7 @@ import {
createSlashcommandTool, createSlashcommandTool,
discoverCommandsSync, discoverCommandsSync,
sessionExists, sessionExists,
createSisyphusTask, createDelegateTask,
interactive_bash, interactive_bash,
startTmuxCheck, startTmuxCheck,
lspManager, lspManager,
@ -193,8 +193,8 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
? createEditErrorRecoveryHook(ctx) ? createEditErrorRecoveryHook(ctx)
: null; : null;
const sisyphusTaskRetry = isHookEnabled("sisyphus-task-retry") const delegateTaskRetry = isHookEnabled("delegate-task-retry")
? createSisyphusTaskRetryHook(ctx) ? createDelegateTaskRetryHook(ctx)
: null; : null;
const startWork = isHookEnabled("start-work") const startWork = isHookEnabled("start-work")
@ -233,7 +233,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
const callOmoAgent = createCallOmoAgent(ctx, backgroundManager); const callOmoAgent = createCallOmoAgent(ctx, backgroundManager);
const lookAt = createLookAt(ctx); const lookAt = createLookAt(ctx);
const sisyphusTask = createSisyphusTask({ const delegateTask = createDelegateTask({
manager: backgroundManager, manager: backgroundManager,
client: ctx.client, client: ctx.client,
directory: ctx.directory, directory: ctx.directory,
@ -302,7 +302,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
...backgroundTools, ...backgroundTools,
call_omo_agent: callOmoAgent, call_omo_agent: callOmoAgent,
look_at: lookAt, look_at: lookAt,
sisyphus_task: sisyphusTask, delegate_task: delegateTask,
skill: skillTool, skill: skillTool,
skill_mcp: skillMcpTool, skill_mcp: skillMcpTool,
slashcommand: slashcommandTool, slashcommand: slashcommandTool,
@ -502,7 +502,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
args.tools = { args.tools = {
...(args.tools as Record<string, boolean> | undefined), ...(args.tools as Record<string, boolean> | undefined),
sisyphus_task: false, delegate_task: false,
...(isExploreOrLibrarian ? { call_omo_agent: false } : {}), ...(isExploreOrLibrarian ? { call_omo_agent: false } : {}),
}; };
} }
@ -550,7 +550,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
await agentUsageReminder?.["tool.execute.after"](input, output); await agentUsageReminder?.["tool.execute.after"](input, output);
await interactiveBashSession?.["tool.execute.after"](input, output); await interactiveBashSession?.["tool.execute.after"](input, output);
await editErrorRecovery?.["tool.execute.after"](input, output); await editErrorRecovery?.["tool.execute.after"](input, output);
await sisyphusTaskRetry?.["tool.execute.after"](input, output); await delegateTaskRetry?.["tool.execute.after"](input, output);
await sisyphusOrchestrator?.["tool.execute.after"]?.(input, output); await sisyphusOrchestrator?.["tool.execute.after"]?.(input, output);
await taskResumeInfo["tool.execute.after"](input, output); await taskResumeInfo["tool.execute.after"](input, output);
}, },

View File

@ -24,7 +24,7 @@ import type { OhMyOpenCodeConfig } from "../config";
import { log } from "../shared"; import { log } from "../shared";
import { migrateAgentConfig } from "../shared/permission-compat"; import { migrateAgentConfig } from "../shared/permission-compat";
import { PROMETHEUS_SYSTEM_PROMPT, PROMETHEUS_PERMISSION } from "../agents/prometheus-prompt"; import { PROMETHEUS_SYSTEM_PROMPT, PROMETHEUS_PERMISSION } from "../agents/prometheus-prompt";
import { DEFAULT_CATEGORIES } from "../tools/sisyphus-task/constants"; import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants";
import type { ModelCacheState } from "../plugin-state"; import type { ModelCacheState } from "../plugin-state";
import type { CategoryConfig } from "../config/schema"; import type { CategoryConfig } from "../config/schema";
@ -303,26 +303,26 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
} }
if (agentResult["orchestrator-sisyphus"]) { if (agentResult["orchestrator-sisyphus"]) {
const agent = agentResult["orchestrator-sisyphus"] as AgentWithPermission; const agent = agentResult["orchestrator-sisyphus"] as AgentWithPermission;
agent.permission = { ...agent.permission, task: "deny", call_omo_agent: "deny", sisyphus_task: "allow" }; agent.permission = { ...agent.permission, task: "deny", call_omo_agent: "deny", delegate_task: "allow" };
} }
if (agentResult.Sisyphus) { if (agentResult.Sisyphus) {
const agent = agentResult.Sisyphus as AgentWithPermission; const agent = agentResult.Sisyphus as AgentWithPermission;
agent.permission = { ...agent.permission, call_omo_agent: "deny", sisyphus_task: "allow" }; agent.permission = { ...agent.permission, call_omo_agent: "deny", delegate_task: "allow" };
} }
if (agentResult["Prometheus (Planner)"]) { if (agentResult["Prometheus (Planner)"]) {
const agent = agentResult["Prometheus (Planner)"] as AgentWithPermission; const agent = agentResult["Prometheus (Planner)"] as AgentWithPermission;
agent.permission = { ...agent.permission, call_omo_agent: "deny", sisyphus_task: "allow" }; agent.permission = { ...agent.permission, call_omo_agent: "deny", delegate_task: "allow" };
} }
if (agentResult["Sisyphus-Junior"]) { if (agentResult["Sisyphus-Junior"]) {
const agent = agentResult["Sisyphus-Junior"] as AgentWithPermission; const agent = agentResult["Sisyphus-Junior"] as AgentWithPermission;
agent.permission = { ...agent.permission, sisyphus_task: "allow" }; agent.permission = { ...agent.permission, delegate_task: "allow" };
} }
config.permission = { config.permission = {
...(config.permission as Record<string, unknown>), ...(config.permission as Record<string, unknown>),
webfetch: "allow", webfetch: "allow",
external_directory: "allow", external_directory: "allow",
sisyphus_task: "deny", delegate_task: "deny",
}; };
const mcpResult = (pluginConfig.claude_code?.mcp ?? true) const mcpResult = (pluginConfig.claude_code?.mcp ?? true)

View File

@ -10,7 +10,7 @@ const EXPLORATION_AGENT_DENYLIST: Record<string, PermissionValue> = {
write: "deny", write: "deny",
edit: "deny", edit: "deny",
task: "deny", task: "deny",
sisyphus_task: "deny", delegate_task: "deny",
call_omo_agent: "deny", call_omo_agent: "deny",
} }
@ -23,7 +23,7 @@ const AGENT_RESTRICTIONS: Record<string, Record<string, PermissionValue>> = {
write: "deny", write: "deny",
edit: "deny", edit: "deny",
task: "deny", task: "deny",
sisyphus_task: "deny", delegate_task: "deny",
}, },
"multimodal-looker": { "multimodal-looker": {
@ -33,19 +33,19 @@ const AGENT_RESTRICTIONS: Record<string, Record<string, PermissionValue>> = {
"document-writer": { "document-writer": {
task: "deny", task: "deny",
sisyphus_task: "deny", delegate_task: "deny",
call_omo_agent: "deny", call_omo_agent: "deny",
}, },
"frontend-ui-ux-engineer": { "frontend-ui-ux-engineer": {
task: "deny", task: "deny",
sisyphus_task: "deny", delegate_task: "deny",
call_omo_agent: "deny", call_omo_agent: "deny",
}, },
"Sisyphus-Junior": { "Sisyphus-Junior": {
task: "deny", task: "deny",
sisyphus_task: "deny", delegate_task: "deny",
}, },
} }

View File

@ -34,7 +34,7 @@ tools/
| AST | ast_grep_search, ast_grep_replace | Structural pattern matching/rewriting | | AST | ast_grep_search, ast_grep_replace | Structural pattern matching/rewriting |
| Search | grep, glob | Timeout-safe file and content search | | Search | grep, glob | Timeout-safe file and content search |
| Session | session_list, session_read, session_search, session_info | History navigation and retrieval | | Session | session_list, session_read, session_search, session_info | History navigation and retrieval |
| Background | sisyphus_task, background_output, background_cancel | Parallel agent orchestration | | Background | delegate_task, background_output, background_cancel | Parallel agent orchestration |
| UI/Terminal | look_at, interactive_bash | Visual analysis and tmux control | | UI/Terminal | look_at, interactive_bash | Visual analysis and tmux control |
| Execution | slashcommand, skill, skill_mcp | Command and skill-based extensibility | | Execution | slashcommand, skill, skill_mcp | Command and skill-based extensibility |

View File

@ -190,7 +190,7 @@ async function executeSync(
tools: { tools: {
...getAgentToolRestrictions(args.subagent_type), ...getAgentToolRestrictions(args.subagent_type),
task: false, task: false,
sisyphus_task: false, delegate_task: false,
}, },
parts: [{ type: "text", text: args.prompt }], parts: [{ type: "text", text: args.prompt }],
}, },

View File

@ -236,7 +236,7 @@ export const CATEGORY_DESCRIPTIONS: Record<string, string> = {
const BUILTIN_CATEGORIES = Object.keys(DEFAULT_CATEGORIES).join(", ") const BUILTIN_CATEGORIES = Object.keys(DEFAULT_CATEGORIES).join(", ")
export const SISYPHUS_TASK_DESCRIPTION = `Spawn agent task with category-based or direct agent selection. export const DELEGATE_TASK_DESCRIPTION = `Spawn agent task with category-based or direct agent selection.
MUTUALLY EXCLUSIVE: Provide EITHER category OR agent, not both (unless resuming). MUTUALLY EXCLUSIVE: Provide EITHER category OR agent, not both (unless resuming).

View File

@ -1,3 +1,3 @@
export { createSisyphusTask, type SisyphusTaskToolOptions } from "./tools" export { createDelegateTask, type DelegateTaskToolOptions } from "./tools"
export type * from "./types" export type * from "./types"
export * from "./constants" export * from "./constants"

View File

@ -1,5 +1,5 @@
import { describe, test, expect } from "bun:test" import { describe, test, expect } from "bun:test"
import { DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, SISYPHUS_TASK_DESCRIPTION } from "./constants" import { DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, DELEGATE_TASK_DESCRIPTION } from "./constants"
import type { CategoryConfig } from "../../config/schema" import type { CategoryConfig } from "../../config/schema"
function resolveCategoryConfig( function resolveCategoryConfig(
@ -101,16 +101,16 @@ describe("sisyphus-task", () => {
}) })
}) })
describe("SISYPHUS_TASK_DESCRIPTION", () => { describe("DELEGATE_TASK_DESCRIPTION", () => {
test("documents background parameter as required with default false", () => { test("documents background parameter as required with default false", () => {
// #given / #when / #then // #given / #when / #then
expect(SISYPHUS_TASK_DESCRIPTION).toContain("background") expect(DELEGATE_TASK_DESCRIPTION).toContain("background")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Default: false") expect(DELEGATE_TASK_DESCRIPTION).toContain("Default: false")
}) })
test("warns about parallel exploration usage", () => { test("warns about parallel exploration usage", () => {
// #given / #when / #then // #given / #when / #then
expect(SISYPHUS_TASK_DESCRIPTION).toContain("5+") expect(DELEGATE_TASK_DESCRIPTION).toContain("5+")
}) })
}) })
@ -257,7 +257,7 @@ describe("sisyphus-task", () => {
describe("category variant", () => { describe("category variant", () => {
test("passes variant to background model payload", async () => { test("passes variant to background model payload", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
let launchInput: any let launchInput: any
const mockManager = { const mockManager = {
@ -283,7 +283,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
userCategories: { userCategories: {
@ -320,17 +320,17 @@ describe("sisyphus-task", () => {
}) })
describe("skills parameter", () => { describe("skills parameter", () => {
test("SISYPHUS_TASK_DESCRIPTION documents skills parameter with null option", () => { test("DELEGATE_TASK_DESCRIPTION documents skills parameter with null option", () => {
// #given / #when / #then // #given / #when / #then
expect(SISYPHUS_TASK_DESCRIPTION).toContain("skills") expect(DELEGATE_TASK_DESCRIPTION).toContain("skills")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Array of skill names") expect(DELEGATE_TASK_DESCRIPTION).toContain("Array of skill names")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Empty array [] is NOT allowed") expect(DELEGATE_TASK_DESCRIPTION).toContain("Empty array [] is NOT allowed")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("null if no skills needed") expect(DELEGATE_TASK_DESCRIPTION).toContain("null if no skills needed")
}) })
test("skills parameter is required - returns error when not provided", async () => { test("skills parameter is required - returns error when not provided", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
const mockManager = { launch: async () => ({}) } const mockManager = { launch: async () => ({}) }
const mockClient = { const mockClient = {
@ -343,7 +343,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -373,7 +373,7 @@ describe("sisyphus-task", () => {
test("empty array [] returns error with available skills list", async () => { test("empty array [] returns error with available skills list", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
const mockManager = { launch: async () => ({}) } const mockManager = { launch: async () => ({}) }
const mockClient = { const mockClient = {
@ -386,7 +386,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -419,7 +419,7 @@ describe("sisyphus-task", () => {
test("null skills is allowed and proceeds without skill content", async () => { test("null skills is allowed and proceeds without skill content", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
let promptBody: any let promptBody: any
const mockManager = { launch: async () => ({}) } const mockManager = { launch: async () => ({}) }
@ -440,7 +440,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -474,7 +474,7 @@ describe("sisyphus-task", () => {
test("resume with background=false should wait for result and return content", async () => { test("resume with background=false should wait for result and return content", async () => {
// Note: This test needs extended timeout because the implementation has MIN_STABILITY_TIME_MS = 5000 // Note: This test needs extended timeout because the implementation has MIN_STABILITY_TIME_MS = 5000
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
const mockTask = { const mockTask = {
id: "task-123", id: "task-123",
@ -507,7 +507,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -538,7 +538,7 @@ describe("sisyphus-task", () => {
test("resume with background=true should return immediately without waiting", async () => { test("resume with background=true should return immediately without waiting", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
const mockTask = { const mockTask = {
id: "task-456", id: "task-456",
@ -562,7 +562,7 @@ describe("sisyphus-task", () => {
config: { get: async () => ({}) }, config: { get: async () => ({}) },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -595,7 +595,7 @@ describe("sisyphus-task", () => {
describe("sync mode new task (run_in_background=false)", () => { describe("sync mode new task (run_in_background=false)", () => {
test("sync mode prompt error returns error message immediately", async () => { test("sync mode prompt error returns error message immediately", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
const mockManager = { const mockManager = {
launch: async () => ({}), launch: async () => ({}),
@ -617,7 +617,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -651,7 +651,7 @@ describe("sisyphus-task", () => {
test("sync mode success returns task result with content", async () => { test("sync mode success returns task result with content", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
const mockManager = { const mockManager = {
launch: async () => ({}), launch: async () => ({}),
@ -678,7 +678,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -709,7 +709,7 @@ describe("sisyphus-task", () => {
test("sync mode agent not found returns helpful error", async () => { test("sync mode agent not found returns helpful error", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
const mockManager = { const mockManager = {
launch: async () => ({}), launch: async () => ({}),
@ -731,7 +731,7 @@ describe("sisyphus-task", () => {
}, },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
}) })
@ -763,7 +763,7 @@ describe("sisyphus-task", () => {
test("sync mode passes category model to prompt", async () => { test("sync mode passes category model to prompt", async () => {
// #given // #given
const { createSisyphusTask } = require("./tools") const { createDelegateTask } = require("./tools")
let promptBody: any let promptBody: any
const mockManager = { launch: async () => ({}) } const mockManager = { launch: async () => ({}) }
@ -784,7 +784,7 @@ describe("sisyphus-task", () => {
app: { agents: async () => ({ data: [] }) }, app: { agents: async () => ({ data: [] }) },
} }
const tool = createSisyphusTask({ const tool = createDelegateTask({
manager: mockManager, manager: mockManager,
client: mockClient, client: mockClient,
userCategories: { userCategories: {

View File

@ -2,9 +2,9 @@ import { tool, type PluginInput, type ToolDefinition } from "@opencode-ai/plugin
import { existsSync, readdirSync } from "node:fs" import { existsSync, readdirSync } from "node:fs"
import { join } from "node:path" import { join } from "node:path"
import type { BackgroundManager } from "../../features/background-agent" import type { BackgroundManager } from "../../features/background-agent"
import type { SisyphusTaskArgs } from "./types" import type { DelegateTaskArgs } from "./types"
import type { CategoryConfig, CategoriesConfig, GitMasterConfig } from "../../config/schema" import type { CategoryConfig, CategoriesConfig, GitMasterConfig } from "../../config/schema"
import { SISYPHUS_TASK_DESCRIPTION, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./constants" import { DELEGATE_TASK_DESCRIPTION, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./constants"
import { findNearestMessageWithFields, findFirstMessageWithAgent, MESSAGE_STORAGE } from "../../features/hook-message-injector" import { findNearestMessageWithFields, findFirstMessageWithAgent, MESSAGE_STORAGE } from "../../features/hook-message-injector"
import { resolveMultipleSkillsAsync } from "../../features/opencode-skill-loader/skill-content" import { resolveMultipleSkillsAsync } from "../../features/opencode-skill-loader/skill-content"
import { discoverSkills } from "../../features/opencode-skill-loader" import { discoverSkills } from "../../features/opencode-skill-loader"
@ -53,7 +53,7 @@ function formatDuration(start: Date, end?: Date): string {
interface ErrorContext { interface ErrorContext {
operation: string operation: string
args?: SisyphusTaskArgs args?: DelegateTaskArgs
sessionID?: string sessionID?: string
agent?: string agent?: string
category?: string category?: string
@ -143,7 +143,7 @@ function resolveCategoryConfig(
return { config, promptAppend, model } return { config, promptAppend, model }
} }
export interface SisyphusTaskToolOptions { export interface DelegateTaskToolOptions {
manager: BackgroundManager manager: BackgroundManager
client: OpencodeClient client: OpencodeClient
directory: string directory: string
@ -170,11 +170,11 @@ export function buildSystemContent(input: BuildSystemContentInput): string | und
return skillContent || categoryPromptAppend return skillContent || categoryPromptAppend
} }
export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefinition { export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefinition {
const { manager, client, directory, userCategories, gitMasterConfig } = options const { manager, client, directory, userCategories, gitMasterConfig } = options
return tool({ return tool({
description: SISYPHUS_TASK_DESCRIPTION, description: DELEGATE_TASK_DESCRIPTION,
args: { args: {
description: tool.schema.string().describe("Short task description"), description: tool.schema.string().describe("Short task description"),
prompt: tool.schema.string().describe("Full detailed prompt for the agent"), prompt: tool.schema.string().describe("Full detailed prompt for the agent"),
@ -184,7 +184,7 @@ export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefini
resume: tool.schema.string().optional().describe("Session ID to resume - continues previous agent session with full context"), resume: tool.schema.string().optional().describe("Session ID to resume - continues previous agent session with full context"),
skills: tool.schema.array(tool.schema.string()).nullable().describe("Array of skill names to prepend to the prompt. Use null if no skills needed. Empty array [] is NOT allowed."), skills: tool.schema.array(tool.schema.string()).nullable().describe("Array of skill names to prepend to the prompt. Use null if no skills needed. Empty array [] is NOT allowed."),
}, },
async execute(args: SisyphusTaskArgs, toolContext) { async execute(args: DelegateTaskArgs, toolContext) {
const ctx = toolContext as ToolContextWithMetadata const ctx = toolContext as ToolContextWithMetadata
if (args.run_in_background === undefined) { if (args.run_in_background === undefined) {
return `❌ Invalid arguments: 'run_in_background' parameter is REQUIRED. Use run_in_background=false for task delegation, run_in_background=true only for parallel exploration.` return `❌ Invalid arguments: 'run_in_background' parameter is REQUIRED. Use run_in_background=false for task delegation, run_in_background=true only for parallel exploration.`
@ -223,7 +223,7 @@ If you believe no skills are needed, you MUST explicitly explain why to the user
const sessionAgent = getSessionAgent(ctx.sessionID) const sessionAgent = getSessionAgent(ctx.sessionID)
const parentAgent = ctx.agent ?? sessionAgent ?? firstMessageAgent ?? prevMessage?.agent const parentAgent = ctx.agent ?? sessionAgent ?? firstMessageAgent ?? prevMessage?.agent
log("[sisyphus_task] parentAgent resolution", { log("[delegate_task] parentAgent resolution", {
sessionID: ctx.sessionID, sessionID: ctx.sessionID,
messageDir, messageDir,
ctxAgent: ctx.agent, ctxAgent: ctx.agent,
@ -324,7 +324,7 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`
tools: { tools: {
...(resumeAgent ? getAgentToolRestrictions(resumeAgent) : {}), ...(resumeAgent ? getAgentToolRestrictions(resumeAgent) : {}),
task: false, task: false,
sisyphus_task: false, delegate_task: false,
call_omo_agent: true, call_omo_agent: true,
}, },
parts: [{ type: "text", text: args.prompt }], parts: [{ type: "text", text: args.prompt }],
@ -502,7 +502,7 @@ ${textContent || "(No text output)"}`
if (!callableNames.includes(agentToUse)) { if (!callableNames.includes(agentToUse)) {
const isPrimaryAgent = agents.some((a) => a.name === agentToUse && a.mode === "primary") const isPrimaryAgent = agents.some((a) => a.name === agentToUse && a.mode === "primary")
if (isPrimaryAgent) { if (isPrimaryAgent) {
return `❌ Cannot call primary agent "${agentToUse}" via sisyphus_task. Primary agents are top-level orchestrators.` return `❌ Cannot call primary agent "${agentToUse}" via delegate_task. Primary agents are top-level orchestrators.`
} }
const availableAgents = callableNames const availableAgents = callableNames
@ -610,7 +610,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
system: systemContent, system: systemContent,
tools: { tools: {
task: false, task: false,
sisyphus_task: false, delegate_task: false,
call_omo_agent: true, call_omo_agent: true,
}, },
parts: [{ type: "text", text: args.prompt }], parts: [{ type: "text", text: args.prompt }],
@ -651,11 +651,11 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
let stablePolls = 0 let stablePolls = 0
let pollCount = 0 let pollCount = 0
log("[sisyphus_task] Starting poll loop", { sessionID, agentToUse }) log("[delegate_task] Starting poll loop", { sessionID, agentToUse })
while (Date.now() - pollStart < MAX_POLL_TIME_MS) { while (Date.now() - pollStart < MAX_POLL_TIME_MS) {
if (ctx.abort?.aborted) { if (ctx.abort?.aborted) {
log("[sisyphus_task] Aborted by user", { sessionID }) log("[delegate_task] Aborted by user", { sessionID })
if (toastManager && taskId) toastManager.removeTask(taskId) if (toastManager && taskId) toastManager.removeTask(taskId)
return `Task aborted.\n\nSession ID: ${sessionID}` return `Task aborted.\n\nSession ID: ${sessionID}`
} }
@ -668,7 +668,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
const sessionStatus = allStatuses[sessionID] const sessionStatus = allStatuses[sessionID]
if (pollCount % 10 === 0) { if (pollCount % 10 === 0) {
log("[sisyphus_task] Poll status", { log("[delegate_task] Poll status", {
sessionID, sessionID,
pollCount, pollCount,
elapsed: Math.floor((Date.now() - pollStart) / 1000) + "s", elapsed: Math.floor((Date.now() - pollStart) / 1000) + "s",
@ -696,7 +696,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
if (currentMsgCount === lastMsgCount) { if (currentMsgCount === lastMsgCount) {
stablePolls++ stablePolls++
if (stablePolls >= STABILITY_POLLS_REQUIRED) { if (stablePolls >= STABILITY_POLLS_REQUIRED) {
log("[sisyphus_task] Poll complete - messages stable", { sessionID, pollCount, currentMsgCount }) log("[delegate_task] Poll complete - messages stable", { sessionID, pollCount, currentMsgCount })
break break
} }
} else { } else {
@ -706,7 +706,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
} }
if (Date.now() - pollStart >= MAX_POLL_TIME_MS) { if (Date.now() - pollStart >= MAX_POLL_TIME_MS) {
log("[sisyphus_task] Poll timeout reached", { sessionID, pollCount, lastMsgCount, stablePolls }) log("[delegate_task] Poll timeout reached", { sessionID, pollCount, lastMsgCount, stablePolls })
} }
const messagesResult = await client.session.messages({ const messagesResult = await client.session.messages({

View File

@ -1,4 +1,4 @@
export interface SisyphusTaskArgs { export interface DelegateTaskArgs {
description: string description: string
prompt: string prompt: string
category?: string category?: string

View File

@ -45,7 +45,7 @@ type OpencodeClient = PluginInput["client"]
export { createCallOmoAgent } from "./call-omo-agent" export { createCallOmoAgent } from "./call-omo-agent"
export { createLookAt } from "./look-at" export { createLookAt } from "./look-at"
export { createSisyphusTask, type SisyphusTaskToolOptions, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./sisyphus-task" export { createDelegateTask, type DelegateTaskToolOptions, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./delegate-task"
export function createBackgroundTools(manager: BackgroundManager, client: OpencodeClient): Record<string, ToolDefinition> { export function createBackgroundTools(manager: BackgroundManager, client: OpencodeClient): Record<string, ToolDefinition> {
return { return {