add bool value: tdd to sisyphus_agent config
This commit is contained in:
@@ -5,6 +5,8 @@ export const SisyphusAgentConfigSchema = z.object({
|
|||||||
default_builder_enabled: z.boolean().optional(),
|
default_builder_enabled: z.boolean().optional(),
|
||||||
planner_enabled: z.boolean().optional(),
|
planner_enabled: z.boolean().optional(),
|
||||||
replace_plan: z.boolean().optional(),
|
replace_plan: z.boolean().optional(),
|
||||||
|
/** Enable TDD-oriented planning for plan agent prompts (default: true) */
|
||||||
|
tdd: z.boolean().default(true),
|
||||||
})
|
})
|
||||||
|
|
||||||
export type SisyphusAgentConfig = z.infer<typeof SisyphusAgentConfigSchema>
|
export type SisyphusAgentConfig = z.infer<typeof SisyphusAgentConfigSchema>
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ export function createToolRegistry(args: {
|
|||||||
disabledSkills: skillContext.disabledSkills,
|
disabledSkills: skillContext.disabledSkills,
|
||||||
availableCategories,
|
availableCategories,
|
||||||
availableSkills: skillContext.availableSkills,
|
availableSkills: skillContext.availableSkills,
|
||||||
|
sisyphusAgentConfig: pluginConfig.sisyphus_agent,
|
||||||
syncPollTimeoutMs: pluginConfig.background_task?.syncPollTimeoutMs,
|
syncPollTimeoutMs: pluginConfig.background_task?.syncPollTimeoutMs,
|
||||||
onSyncSessionCreated: async (event) => {
|
onSyncSessionCreated: async (event) => {
|
||||||
log("[index] onSyncSessionCreated callback", {
|
log("[index] onSyncSessionCreated callback", {
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ export async function executeBackgroundTask(
|
|||||||
const { manager } = executorCtx
|
const { manager } = executorCtx
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const effectivePrompt = buildTaskPrompt(args.prompt, agentToUse)
|
const tddEnabled = executorCtx.sisyphusAgentConfig?.tdd
|
||||||
|
const effectivePrompt = buildTaskPrompt(args.prompt, agentToUse, tddEnabled)
|
||||||
const task = await manager.launch({
|
const task = await manager.launch({
|
||||||
description: args.description,
|
description: args.description,
|
||||||
prompt: effectivePrompt,
|
prompt: effectivePrompt,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { BackgroundManager } from "../../features/background-agent"
|
import type { BackgroundManager } from "../../features/background-agent"
|
||||||
import type { CategoriesConfig, GitMasterConfig, BrowserAutomationProvider, AgentOverrides } from "../../config/schema"
|
import type { CategoriesConfig, GitMasterConfig, BrowserAutomationProvider, AgentOverrides, SisyphusAgentConfig } from "../../config/schema"
|
||||||
import type { OpencodeClient } from "./types"
|
import type { OpencodeClient } from "./types"
|
||||||
|
|
||||||
export interface ExecutorContext {
|
export interface ExecutorContext {
|
||||||
@@ -11,6 +11,7 @@ export interface ExecutorContext {
|
|||||||
sisyphusJuniorModel?: string
|
sisyphusJuniorModel?: string
|
||||||
browserProvider?: BrowserAutomationProvider
|
browserProvider?: BrowserAutomationProvider
|
||||||
agentOverrides?: AgentOverrides
|
agentOverrides?: AgentOverrides
|
||||||
|
sisyphusAgentConfig?: SisyphusAgentConfig
|
||||||
onSyncSessionCreated?: (event: { sessionID: string; parentID: string; title: string }) => Promise<void>
|
onSyncSessionCreated?: (event: { sessionID: string; parentID: string; title: string }) => Promise<void>
|
||||||
syncPollTimeoutMs?: number
|
syncPollTimeoutMs?: number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,24 @@ import { buildPlanAgentSystemPrepend, isPlanAgent } from "./constants"
|
|||||||
import { buildSystemContentWithTokenLimit } from "./token-limiter"
|
import { buildSystemContentWithTokenLimit } from "./token-limiter"
|
||||||
|
|
||||||
const FREE_OR_LOCAL_PROMPT_TOKEN_LIMIT = 24000
|
const FREE_OR_LOCAL_PROMPT_TOKEN_LIMIT = 24000
|
||||||
const PLAN_AGENT_PROMPT_APPEND = `
|
const PLAN_AGENT_PROMPT_BASE = `
|
||||||
|
|
||||||
Additional requirements for this planning request:
|
Additional requirements for this planning request:
|
||||||
- Answer in English.
|
- Answer in English.
|
||||||
- Write the plan in English.
|
- Write the plan in English.
|
||||||
- Plan well for ultrawork execution.
|
- Plan well for ultrawork execution.
|
||||||
- Use TDD-oriented planning.
|
|
||||||
- Include a clear atomic commit strategy.`
|
- Include a clear atomic commit strategy.`
|
||||||
|
|
||||||
|
const TDD_LINE = "- Use TDD-oriented planning."
|
||||||
|
|
||||||
|
function buildPlanAgentPromptAppend(tddEnabled: boolean): string {
|
||||||
|
if (tddEnabled) {
|
||||||
|
return `${PLAN_AGENT_PROMPT_BASE}
|
||||||
|
${TDD_LINE}`
|
||||||
|
}
|
||||||
|
return PLAN_AGENT_PROMPT_BASE
|
||||||
|
}
|
||||||
|
|
||||||
function usesFreeOrLocalModel(model: { providerID: string; modelID: string; variant?: string } | undefined): boolean {
|
function usesFreeOrLocalModel(model: { providerID: string; modelID: string; variant?: string } | undefined): boolean {
|
||||||
if (!model) {
|
if (!model) {
|
||||||
return false
|
return false
|
||||||
@@ -61,10 +70,11 @@ export function buildSystemContent(input: BuildSystemContentInput): string | und
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function buildTaskPrompt(prompt: string, agentName: string | undefined): string {
|
export function buildTaskPrompt(prompt: string, agentName: string | undefined, tddEnabled?: boolean): string {
|
||||||
if (!isPlanAgent(agentName)) {
|
if (!isPlanAgent(agentName)) {
|
||||||
return prompt
|
return prompt
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${prompt}${PLAN_AGENT_PROMPT_APPEND}`
|
const effectiveTdd = tddEnabled ?? true
|
||||||
|
return `${prompt}${buildPlanAgentPromptAppend(effectiveTdd)}`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export async function executeSyncContinuation(
|
|||||||
executorCtx: ExecutorContext,
|
executorCtx: ExecutorContext,
|
||||||
deps: SyncContinuationDeps = syncContinuationDeps
|
deps: SyncContinuationDeps = syncContinuationDeps
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const { client, syncPollTimeoutMs } = executorCtx
|
const { client, syncPollTimeoutMs, sisyphusAgentConfig } = executorCtx
|
||||||
const toastManager = getTaskToastManager()
|
const toastManager = getTaskToastManager()
|
||||||
const taskId = `resume_sync_${args.session_id!.slice(0, 8)}`
|
const taskId = `resume_sync_${args.session_id!.slice(0, 8)}`
|
||||||
const startTime = new Date()
|
const startTime = new Date()
|
||||||
@@ -83,7 +83,8 @@ export async function executeSyncContinuation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const allowTask = isPlanFamily(resumeAgent)
|
const allowTask = isPlanFamily(resumeAgent)
|
||||||
const effectivePrompt = buildTaskPrompt(args.prompt, resumeAgent)
|
const tddEnabled = sisyphusAgentConfig?.tdd
|
||||||
|
const effectivePrompt = buildTaskPrompt(args.prompt, resumeAgent, tddEnabled)
|
||||||
const tools = {
|
const tools = {
|
||||||
task: allowTask,
|
task: allowTask,
|
||||||
call_omo_agent: true,
|
call_omo_agent: true,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { DelegateTaskArgs, OpencodeClient, DelegatedModelConfig } from "./types"
|
import type { DelegateTaskArgs, OpencodeClient, DelegatedModelConfig } from "./types"
|
||||||
|
import type { SisyphusAgentConfig } from "../../config/schema"
|
||||||
import { isPlanFamily } from "./constants"
|
import { isPlanFamily } from "./constants"
|
||||||
import { buildTaskPrompt } from "./prompt-builder"
|
import { buildTaskPrompt } from "./prompt-builder"
|
||||||
import {
|
import {
|
||||||
@@ -41,11 +42,13 @@ export async function sendSyncPrompt(
|
|||||||
categoryModel: DelegatedModelConfig | undefined
|
categoryModel: DelegatedModelConfig | undefined
|
||||||
toastManager: { removeTask: (id: string) => void } | null | undefined
|
toastManager: { removeTask: (id: string) => void } | null | undefined
|
||||||
taskId: string | undefined
|
taskId: string | undefined
|
||||||
|
sisyphusAgentConfig?: SisyphusAgentConfig
|
||||||
},
|
},
|
||||||
deps: SendSyncPromptDeps = sendSyncPromptDeps
|
deps: SendSyncPromptDeps = sendSyncPromptDeps
|
||||||
): Promise<string | null> {
|
): Promise<string | null> {
|
||||||
const allowTask = isPlanFamily(input.agentToUse)
|
const allowTask = isPlanFamily(input.agentToUse)
|
||||||
const effectivePrompt = buildTaskPrompt(input.args.prompt, input.agentToUse)
|
const tddEnabled = input.sisyphusAgentConfig?.tdd
|
||||||
|
const effectivePrompt = buildTaskPrompt(input.args.prompt, input.agentToUse, tddEnabled)
|
||||||
const tools = {
|
const tools = {
|
||||||
task: allowTask,
|
task: allowTask,
|
||||||
call_omo_agent: true,
|
call_omo_agent: true,
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ export async function executeSyncTask(
|
|||||||
categoryModel,
|
categoryModel,
|
||||||
toastManager,
|
toastManager,
|
||||||
taskId,
|
taskId,
|
||||||
|
sisyphusAgentConfig: executorCtx.sisyphusAgentConfig,
|
||||||
})
|
})
|
||||||
if (promptError) {
|
if (promptError) {
|
||||||
return promptError
|
return promptError
|
||||||
|
|||||||
@@ -3129,6 +3129,35 @@ describe("sisyphus-task", () => {
|
|||||||
// then
|
// then
|
||||||
expect(result).toBe(prompt)
|
expect(result).toBe(prompt)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("excludes TDD line when tddEnabled is false", () => {
|
||||||
|
// given
|
||||||
|
const { buildTaskPrompt } = require("./tools")
|
||||||
|
const prompt = "Create a work plan for this feature"
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = buildTaskPrompt(prompt, "plan", false)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toContain(prompt)
|
||||||
|
expect(result).toContain("Answer in English.")
|
||||||
|
expect(result).toContain("Write the plan in English.")
|
||||||
|
expect(result).toContain("Plan well for ultrawork execution.")
|
||||||
|
expect(result).toContain("Include a clear atomic commit strategy.")
|
||||||
|
expect(result).not.toContain("Use TDD-oriented planning.")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("includes TDD line when tddEnabled is true", () => {
|
||||||
|
// given
|
||||||
|
const { buildTaskPrompt } = require("./tools")
|
||||||
|
const prompt = "Create a work plan for this feature"
|
||||||
|
|
||||||
|
// when
|
||||||
|
const result = buildTaskPrompt(prompt, "plan", true)
|
||||||
|
|
||||||
|
// then
|
||||||
|
expect(result).toContain("Use TDD-oriented planning.")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("modelInfo detection via resolveCategoryConfig", () => {
|
describe("modelInfo detection via resolveCategoryConfig", () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import type { PluginInput } from "@opencode-ai/plugin"
|
import type { PluginInput } from "@opencode-ai/plugin"
|
||||||
import type { BackgroundManager } from "../../features/background-agent"
|
import type { BackgroundManager } from "../../features/background-agent"
|
||||||
import type { CategoriesConfig, GitMasterConfig, BrowserAutomationProvider, AgentOverrides } from "../../config/schema"
|
import type { CategoriesConfig, GitMasterConfig, BrowserAutomationProvider, AgentOverrides, SisyphusAgentConfig } from "../../config/schema"
|
||||||
import type {
|
import type {
|
||||||
AvailableCategory,
|
AvailableCategory,
|
||||||
AvailableSkill,
|
AvailableSkill,
|
||||||
@@ -67,6 +67,7 @@ export interface DelegateTaskToolOptions {
|
|||||||
availableCategories?: AvailableCategory[]
|
availableCategories?: AvailableCategory[]
|
||||||
availableSkills?: AvailableSkill[]
|
availableSkills?: AvailableSkill[]
|
||||||
agentOverrides?: AgentOverrides
|
agentOverrides?: AgentOverrides
|
||||||
|
sisyphusAgentConfig?: SisyphusAgentConfig
|
||||||
onSyncSessionCreated?: (event: SyncSessionCreatedEvent) => Promise<void>
|
onSyncSessionCreated?: (event: SyncSessionCreatedEvent) => Promise<void>
|
||||||
syncPollTimeoutMs?: number
|
syncPollTimeoutMs?: number
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,12 +20,13 @@ export async function executeUnstableAgentTask(
|
|||||||
systemContent: string | undefined,
|
systemContent: string | undefined,
|
||||||
actualModel: string | undefined
|
actualModel: string | undefined
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const { manager, client, syncPollTimeoutMs } = executorCtx
|
const { manager, client, syncPollTimeoutMs, sisyphusAgentConfig } = executorCtx
|
||||||
let cleanupReason: string | undefined
|
let cleanupReason: string | undefined
|
||||||
let launchedTaskID: string | undefined
|
let launchedTaskID: string | undefined
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const effectivePrompt = buildTaskPrompt(args.prompt, agentToUse)
|
const tddEnabled = sisyphusAgentConfig?.tdd
|
||||||
|
const effectivePrompt = buildTaskPrompt(args.prompt, agentToUse, tddEnabled)
|
||||||
const task = await manager.launch({
|
const task = await manager.launch({
|
||||||
description: args.description,
|
description: args.description,
|
||||||
prompt: effectivePrompt,
|
prompt: effectivePrompt,
|
||||||
|
|||||||
Reference in New Issue
Block a user