feat(sisyphus-task): add skillContent support to background agent launching
- Add optional skillContent field to LaunchInput type
- Implement buildSystemContent utility to combine skill and category prompts
- Update BackgroundManager to pass skillContent as system parameter
- Add comprehensive tests for skillContent optionality and buildSystemContent logic
🤖 Generated with assistance of oh-my-opencode
This commit is contained in:
parent
cfb6980493
commit
99d45f26cb
@ -643,3 +643,34 @@ describe("BackgroundManager.resume", () => {
|
|||||||
expect(result.progress?.toolCalls).toBe(42)
|
expect(result.progress?.toolCalls).toBe(42)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("LaunchInput.skillContent", () => {
|
||||||
|
test("skillContent should be optional in LaunchInput type", () => {
|
||||||
|
// #given
|
||||||
|
const input: import("./types").LaunchInput = {
|
||||||
|
description: "test",
|
||||||
|
prompt: "test prompt",
|
||||||
|
agent: "explore",
|
||||||
|
parentSessionID: "parent-session",
|
||||||
|
parentMessageID: "parent-msg",
|
||||||
|
}
|
||||||
|
|
||||||
|
// #when / #then - should compile without skillContent
|
||||||
|
expect(input.skillContent).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("skillContent can be provided in LaunchInput", () => {
|
||||||
|
// #given
|
||||||
|
const input: import("./types").LaunchInput = {
|
||||||
|
description: "test",
|
||||||
|
prompt: "test prompt",
|
||||||
|
agent: "explore",
|
||||||
|
parentSessionID: "parent-session",
|
||||||
|
parentMessageID: "parent-msg",
|
||||||
|
skillContent: "You are a playwright expert",
|
||||||
|
}
|
||||||
|
|
||||||
|
// #when / #then
|
||||||
|
expect(input.skillContent).toBe("You are a playwright expert")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|||||||
@ -140,6 +140,7 @@ export class BackgroundManager {
|
|||||||
path: { id: sessionID },
|
path: { id: sessionID },
|
||||||
body: {
|
body: {
|
||||||
agent: input.agent,
|
agent: input.agent,
|
||||||
|
system: input.skillContent,
|
||||||
tools: {
|
tools: {
|
||||||
task: false,
|
task: false,
|
||||||
call_omo_agent: false,
|
call_omo_agent: false,
|
||||||
|
|||||||
@ -41,6 +41,7 @@ export interface LaunchInput {
|
|||||||
parentModel?: { providerID: string; modelID: string }
|
parentModel?: { providerID: string; modelID: string }
|
||||||
model?: { providerID: string; modelID: string }
|
model?: { providerID: string; modelID: string }
|
||||||
skills?: string[]
|
skills?: string[]
|
||||||
|
skillContent?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResumeInput {
|
export interface ResumeInput {
|
||||||
|
|||||||
@ -214,4 +214,56 @@ describe("sisyphus-task", () => {
|
|||||||
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Array of skill names")
|
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Array of skill names")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("buildSystemContent", () => {
|
||||||
|
test("returns undefined when no skills and no category promptAppend", () => {
|
||||||
|
// #given
|
||||||
|
const { buildSystemContent } = require("./tools")
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = buildSystemContent({ skills: undefined, categoryPromptAppend: undefined })
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns skill content only when skills provided without category", () => {
|
||||||
|
// #given
|
||||||
|
const { buildSystemContent } = require("./tools")
|
||||||
|
const skillContent = "You are a playwright expert"
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = buildSystemContent({ skillContent, categoryPromptAppend: undefined })
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result).toBe(skillContent)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("returns category promptAppend only when no skills", () => {
|
||||||
|
// #given
|
||||||
|
const { buildSystemContent } = require("./tools")
|
||||||
|
const categoryPromptAppend = "Focus on visual design"
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = buildSystemContent({ skillContent: undefined, categoryPromptAppend })
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result).toBe(categoryPromptAppend)
|
||||||
|
})
|
||||||
|
|
||||||
|
test("combines skill content and category promptAppend with separator", () => {
|
||||||
|
// #given
|
||||||
|
const { buildSystemContent } = require("./tools")
|
||||||
|
const skillContent = "You are a playwright expert"
|
||||||
|
const categoryPromptAppend = "Focus on visual design"
|
||||||
|
|
||||||
|
// #when
|
||||||
|
const result = buildSystemContent({ skillContent, categoryPromptAppend })
|
||||||
|
|
||||||
|
// #then
|
||||||
|
expect(result).toContain(skillContent)
|
||||||
|
expect(result).toContain(categoryPromptAppend)
|
||||||
|
expect(result).toContain("\n\n")
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -90,6 +90,25 @@ export interface SisyphusTaskToolOptions {
|
|||||||
userCategories?: CategoriesConfig
|
userCategories?: CategoriesConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BuildSystemContentInput {
|
||||||
|
skillContent?: string
|
||||||
|
categoryPromptAppend?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildSystemContent(input: BuildSystemContentInput): string | undefined {
|
||||||
|
const { skillContent, categoryPromptAppend } = input
|
||||||
|
|
||||||
|
if (!skillContent && !categoryPromptAppend) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skillContent && categoryPromptAppend) {
|
||||||
|
return `${skillContent}\n\n${categoryPromptAppend}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return skillContent || categoryPromptAppend
|
||||||
|
}
|
||||||
|
|
||||||
export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefinition {
|
export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefinition {
|
||||||
const { manager, client, userCategories } = options
|
const { manager, client, userCategories } = options
|
||||||
|
|
||||||
@ -111,15 +130,14 @@ export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefini
|
|||||||
}
|
}
|
||||||
const runInBackground = args.background === true
|
const runInBackground = args.background === true
|
||||||
|
|
||||||
// Handle skills - resolve and prepend to prompt
|
let skillContent: string | undefined
|
||||||
if (args.skills && args.skills.length > 0) {
|
if (args.skills && args.skills.length > 0) {
|
||||||
const { resolved, notFound } = resolveMultipleSkills(args.skills)
|
const { resolved, notFound } = resolveMultipleSkills(args.skills)
|
||||||
if (notFound.length > 0) {
|
if (notFound.length > 0) {
|
||||||
const available = createBuiltinSkills().map(s => s.name).join(", ")
|
const available = createBuiltinSkills().map(s => s.name).join(", ")
|
||||||
return `❌ Skills not found: ${notFound.join(", ")}. Available: ${available}`
|
return `❌ Skills not found: ${notFound.join(", ")}. Available: ${available}`
|
||||||
}
|
}
|
||||||
const skillContent = Array.from(resolved.values()).join("\n\n")
|
skillContent = Array.from(resolved.values()).join("\n\n")
|
||||||
args.prompt = skillContent + "\n\n---\n\n" + args.prompt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const messageDir = getMessageDir(ctx.sessionID)
|
const messageDir = getMessageDir(ctx.sessionID)
|
||||||
@ -169,8 +187,8 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`
|
|||||||
}
|
}
|
||||||
|
|
||||||
let agentToUse: string
|
let agentToUse: string
|
||||||
|
|
||||||
let categoryModel: { providerID: string; modelID: string } | undefined
|
let categoryModel: { providerID: string; modelID: string } | undefined
|
||||||
|
let categoryPromptAppend: string | undefined
|
||||||
|
|
||||||
if (args.category) {
|
if (args.category) {
|
||||||
const resolved = resolveCategoryConfig(args.category, userCategories)
|
const resolved = resolveCategoryConfig(args.category, userCategories)
|
||||||
@ -180,6 +198,7 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`
|
|||||||
|
|
||||||
agentToUse = SISYPHUS_JUNIOR_AGENT
|
agentToUse = SISYPHUS_JUNIOR_AGENT
|
||||||
categoryModel = parseModelString(resolved.config.model)
|
categoryModel = parseModelString(resolved.config.model)
|
||||||
|
categoryPromptAppend = resolved.promptAppend || undefined
|
||||||
} else {
|
} else {
|
||||||
agentToUse = args.subagent_type!.trim()
|
agentToUse = args.subagent_type!.trim()
|
||||||
if (!agentToUse) {
|
if (!agentToUse) {
|
||||||
@ -211,6 +230,8 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const systemContent = buildSystemContent({ skillContent, categoryPromptAppend })
|
||||||
|
|
||||||
if (runInBackground) {
|
if (runInBackground) {
|
||||||
try {
|
try {
|
||||||
const task = await manager.launch({
|
const task = await manager.launch({
|
||||||
@ -222,6 +243,7 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`
|
|||||||
parentModel,
|
parentModel,
|
||||||
model: categoryModel,
|
model: categoryModel,
|
||||||
skills: args.skills,
|
skills: args.skills,
|
||||||
|
skillContent: systemContent,
|
||||||
})
|
})
|
||||||
|
|
||||||
ctx.metadata?.({
|
ctx.metadata?.({
|
||||||
@ -284,6 +306,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
|
|||||||
body: {
|
body: {
|
||||||
agent: agentToUse,
|
agent: agentToUse,
|
||||||
model: categoryModel,
|
model: categoryModel,
|
||||||
|
system: systemContent,
|
||||||
tools: {
|
tools: {
|
||||||
task: false,
|
task: false,
|
||||||
sisyphus_task: false,
|
sisyphus_task: false,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user