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:
+1
-1
@@ -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 |
|
||||
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user