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
+1 -1
View File
@@ -34,7 +34,7 @@ tools/
| AST | ast_grep_search, ast_grep_replace | Structural pattern matching/rewriting |
| Search | grep, glob | Timeout-safe file and content search |
| 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 |
| Execution | slashcommand, skill, skill_mcp | Command and skill-based extensibility |
+1 -1
View File
@@ -190,7 +190,7 @@ async function executeSync(
tools: {
...getAgentToolRestrictions(args.subagent_type),
task: false,
sisyphus_task: false,
delegate_task: false,
},
parts: [{ type: "text", text: args.prompt }],
},
@@ -236,7 +236,7 @@ export const CATEGORY_DESCRIPTIONS: Record<string, string> = {
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).
@@ -1,3 +1,3 @@
export { createSisyphusTask, type SisyphusTaskToolOptions } from "./tools"
export { createDelegateTask, type DelegateTaskToolOptions } from "./tools"
export type * from "./types"
export * from "./constants"
@@ -1,5 +1,5 @@
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"
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", () => {
// #given / #when / #then
expect(SISYPHUS_TASK_DESCRIPTION).toContain("background")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Default: false")
expect(DELEGATE_TASK_DESCRIPTION).toContain("background")
expect(DELEGATE_TASK_DESCRIPTION).toContain("Default: false")
})
test("warns about parallel exploration usage", () => {
// #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", () => {
test("passes variant to background model payload", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
let launchInput: any
const mockManager = {
@@ -283,7 +283,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
userCategories: {
@@ -320,17 +320,17 @@ describe("sisyphus-task", () => {
})
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
expect(SISYPHUS_TASK_DESCRIPTION).toContain("skills")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Array of skill names")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Empty array [] is NOT allowed")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("null if no skills needed")
expect(DELEGATE_TASK_DESCRIPTION).toContain("skills")
expect(DELEGATE_TASK_DESCRIPTION).toContain("Array of skill names")
expect(DELEGATE_TASK_DESCRIPTION).toContain("Empty array [] is NOT allowed")
expect(DELEGATE_TASK_DESCRIPTION).toContain("null if no skills needed")
})
test("skills parameter is required - returns error when not provided", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = { launch: async () => ({}) }
const mockClient = {
@@ -343,7 +343,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -373,7 +373,7 @@ describe("sisyphus-task", () => {
test("empty array [] returns error with available skills list", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = { launch: async () => ({}) }
const mockClient = {
@@ -386,7 +386,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -419,7 +419,7 @@ describe("sisyphus-task", () => {
test("null skills is allowed and proceeds without skill content", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
let promptBody: any
const mockManager = { launch: async () => ({}) }
@@ -440,7 +440,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -474,7 +474,7 @@ describe("sisyphus-task", () => {
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
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockTask = {
id: "task-123",
@@ -507,7 +507,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -538,7 +538,7 @@ describe("sisyphus-task", () => {
test("resume with background=true should return immediately without waiting", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockTask = {
id: "task-456",
@@ -562,7 +562,7 @@ describe("sisyphus-task", () => {
config: { get: async () => ({}) },
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -595,7 +595,7 @@ describe("sisyphus-task", () => {
describe("sync mode new task (run_in_background=false)", () => {
test("sync mode prompt error returns error message immediately", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = {
launch: async () => ({}),
@@ -617,7 +617,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -651,7 +651,7 @@ describe("sisyphus-task", () => {
test("sync mode success returns task result with content", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = {
launch: async () => ({}),
@@ -678,7 +678,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -709,7 +709,7 @@ describe("sisyphus-task", () => {
test("sync mode agent not found returns helpful error", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = {
launch: async () => ({}),
@@ -731,7 +731,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -763,7 +763,7 @@ describe("sisyphus-task", () => {
test("sync mode passes category model to prompt", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
let promptBody: any
const mockManager = { launch: async () => ({}) }
@@ -784,7 +784,7 @@ describe("sisyphus-task", () => {
app: { agents: async () => ({ data: [] }) },
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
userCategories: {
@@ -2,9 +2,9 @@ import { tool, type PluginInput, type ToolDefinition } from "@opencode-ai/plugin
import { existsSync, readdirSync } from "node:fs"
import { join } from "node:path"
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 { 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 { resolveMultipleSkillsAsync } from "../../features/opencode-skill-loader/skill-content"
import { discoverSkills } from "../../features/opencode-skill-loader"
@@ -53,7 +53,7 @@ function formatDuration(start: Date, end?: Date): string {
interface ErrorContext {
operation: string
args?: SisyphusTaskArgs
args?: DelegateTaskArgs
sessionID?: string
agent?: string
category?: string
@@ -143,7 +143,7 @@ function resolveCategoryConfig(
return { config, promptAppend, model }
}
export interface SisyphusTaskToolOptions {
export interface DelegateTaskToolOptions {
manager: BackgroundManager
client: OpencodeClient
directory: string
@@ -170,11 +170,11 @@ export function buildSystemContent(input: BuildSystemContentInput): string | und
return skillContent || categoryPromptAppend
}
export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefinition {
export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefinition {
const { manager, client, directory, userCategories, gitMasterConfig } = options
return tool({
description: SISYPHUS_TASK_DESCRIPTION,
description: DELEGATE_TASK_DESCRIPTION,
args: {
description: tool.schema.string().describe("Short task description"),
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"),
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
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.`
@@ -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 parentAgent = ctx.agent ?? sessionAgent ?? firstMessageAgent ?? prevMessage?.agent
log("[sisyphus_task] parentAgent resolution", {
log("[delegate_task] parentAgent resolution", {
sessionID: ctx.sessionID,
messageDir,
ctxAgent: ctx.agent,
@@ -324,7 +324,7 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`
tools: {
...(resumeAgent ? getAgentToolRestrictions(resumeAgent) : {}),
task: false,
sisyphus_task: false,
delegate_task: false,
call_omo_agent: true,
},
parts: [{ type: "text", text: args.prompt }],
@@ -502,7 +502,7 @@ ${textContent || "(No text output)"}`
if (!callableNames.includes(agentToUse)) {
const isPrimaryAgent = agents.some((a) => a.name === agentToUse && a.mode === "primary")
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
@@ -610,7 +610,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
system: systemContent,
tools: {
task: false,
sisyphus_task: false,
delegate_task: false,
call_omo_agent: true,
},
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 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) {
if (ctx.abort?.aborted) {
log("[sisyphus_task] Aborted by user", { sessionID })
log("[delegate_task] Aborted by user", { sessionID })
if (toastManager && taskId) toastManager.removeTask(taskId)
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]
if (pollCount % 10 === 0) {
log("[sisyphus_task] Poll status", {
log("[delegate_task] Poll status", {
sessionID,
pollCount,
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) {
stablePolls++
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
}
} 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) {
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({
@@ -1,4 +1,4 @@
export interface SisyphusTaskArgs {
export interface DelegateTaskArgs {
description: string
prompt: string
category?: string
+1 -1
View File
@@ -45,7 +45,7 @@ type OpencodeClient = PluginInput["client"]
export { createCallOmoAgent } from "./call-omo-agent"
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> {
return {