fix(task): append plan delegation prompt requirements
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -2,6 +2,7 @@ import type { DelegateTaskArgs, ToolContextWithMetadata } from "./types"
|
||||
import type { ExecutorContext, ParentContext } from "./executor-types"
|
||||
import type { FallbackEntry } from "../../shared/model-requirements"
|
||||
import { getTimingConfig } from "./timing"
|
||||
import { buildTaskPrompt } from "./prompt-builder"
|
||||
import { storeToolMetadata } from "../../features/tool-metadata-store"
|
||||
import { formatDetailedError } from "./error-formatting"
|
||||
import { getSessionTools } from "../../shared/session-tools-store"
|
||||
@@ -20,9 +21,10 @@ export async function executeBackgroundTask(
|
||||
const { manager } = executorCtx
|
||||
|
||||
try {
|
||||
const effectivePrompt = buildTaskPrompt(args.prompt, agentToUse)
|
||||
const task = await manager.launch({
|
||||
description: args.description,
|
||||
prompt: args.prompt,
|
||||
prompt: effectivePrompt,
|
||||
agent: agentToUse,
|
||||
parentSessionID: parentContext.sessionID,
|
||||
parentMessageID: parentContext.messageID,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export { createDelegateTask, resolveCategoryConfig, buildSystemContent } from "./tools"
|
||||
export { createDelegateTask, resolveCategoryConfig, buildSystemContent, buildTaskPrompt } from "./tools"
|
||||
export type { DelegateTaskToolOptions, SyncSessionCreatedEvent, BuildSystemContentInput } from "./tools"
|
||||
export type * from "./types"
|
||||
export * from "./constants"
|
||||
|
||||
@@ -3,6 +3,14 @@ import { buildPlanAgentSystemPrepend, isPlanAgent } from "./constants"
|
||||
import { buildSystemContentWithTokenLimit } from "./token-limiter"
|
||||
|
||||
const FREE_OR_LOCAL_PROMPT_TOKEN_LIMIT = 24000
|
||||
const PLAN_AGENT_PROMPT_APPEND = `
|
||||
|
||||
Additional requirements for this planning request:
|
||||
- Answer in English.
|
||||
- Write the plan in English.
|
||||
- Plan well for ultrawork execution.
|
||||
- Use TDD-oriented planning.
|
||||
- Include a clear atomic commit strategy.`
|
||||
|
||||
function usesFreeOrLocalModel(model: { providerID: string; modelID: string; variant?: string } | undefined): boolean {
|
||||
if (!model) {
|
||||
@@ -52,3 +60,11 @@ export function buildSystemContent(input: BuildSystemContentInput): string | und
|
||||
effectiveMaxPromptTokens
|
||||
)
|
||||
}
|
||||
|
||||
export function buildTaskPrompt(prompt: string, agentName: string | undefined): string {
|
||||
if (!isPlanAgent(agentName)) {
|
||||
return prompt
|
||||
}
|
||||
|
||||
return `${prompt}${PLAN_AGENT_PROMPT_APPEND}`
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { formatDuration } from "./time-formatter"
|
||||
import { syncContinuationDeps, type SyncContinuationDeps } from "./sync-continuation-deps"
|
||||
import { setSessionTools } from "../../shared/session-tools-store"
|
||||
import { normalizeSDKResponse } from "../../shared"
|
||||
import { buildTaskPrompt } from "./prompt-builder"
|
||||
|
||||
export async function executeSyncContinuation(
|
||||
args: DelegateTaskArgs,
|
||||
@@ -82,6 +83,7 @@ export async function executeSyncContinuation(
|
||||
}
|
||||
|
||||
const allowTask = isPlanFamily(resumeAgent)
|
||||
const effectivePrompt = buildTaskPrompt(args.prompt, resumeAgent)
|
||||
const tools = {
|
||||
...(resumeAgent ? getAgentToolRestrictions(resumeAgent) : {}),
|
||||
task: allowTask,
|
||||
@@ -97,7 +99,7 @@ export async function executeSyncContinuation(
|
||||
...(resumeModel !== undefined ? { model: resumeModel } : {}),
|
||||
...(resumeVariant !== undefined ? { variant: resumeVariant } : {}),
|
||||
tools,
|
||||
parts: [{ type: "text", text: args.prompt }],
|
||||
parts: [{ type: "text", text: effectivePrompt }],
|
||||
},
|
||||
})
|
||||
} catch (promptError) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { DelegateTaskArgs, OpencodeClient } from "./types"
|
||||
import { isPlanFamily } from "./constants"
|
||||
import { buildTaskPrompt } from "./prompt-builder"
|
||||
import {
|
||||
promptSyncWithModelSuggestionRetry,
|
||||
promptWithModelSuggestionRetry,
|
||||
@@ -43,6 +44,7 @@ export async function sendSyncPrompt(
|
||||
deps: SendSyncPromptDeps = sendSyncPromptDeps
|
||||
): Promise<string | null> {
|
||||
const allowTask = isPlanFamily(input.agentToUse)
|
||||
const effectivePrompt = buildTaskPrompt(input.args.prompt, input.agentToUse)
|
||||
const tools = {
|
||||
task: allowTask,
|
||||
call_omo_agent: true,
|
||||
@@ -57,7 +59,7 @@ export async function sendSyncPrompt(
|
||||
agent: input.agentToUse,
|
||||
system: input.systemContent,
|
||||
tools,
|
||||
parts: [createInternalAgentTextPart(input.args.prompt)],
|
||||
parts: [createInternalAgentTextPart(effectivePrompt)],
|
||||
...(input.categoryModel
|
||||
? { model: { providerID: input.categoryModel.providerID, modelID: input.categoryModel.modelID } }
|
||||
: {}),
|
||||
|
||||
@@ -2896,6 +2896,37 @@ describe("sisyphus-task", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("buildTaskPrompt", () => {
|
||||
test("appends English ULW TDD and commit guidance for plan agent", () => {
|
||||
// given
|
||||
const { buildTaskPrompt } = require("./tools")
|
||||
const prompt = "Create a work plan for this feature"
|
||||
|
||||
// when
|
||||
const result = buildTaskPrompt(prompt, "plan")
|
||||
|
||||
// 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("Use TDD-oriented planning.")
|
||||
expect(result).toContain("Include a clear atomic commit strategy.")
|
||||
})
|
||||
|
||||
test("does not append plan guidance for non-plan agents", () => {
|
||||
// given
|
||||
const { buildTaskPrompt } = require("./tools")
|
||||
const prompt = "Investigate this module"
|
||||
|
||||
// when
|
||||
const result = buildTaskPrompt(prompt, "explore")
|
||||
|
||||
// then
|
||||
expect(result).toBe(prompt)
|
||||
})
|
||||
})
|
||||
|
||||
describe("modelInfo detection via resolveCategoryConfig", () => {
|
||||
test("catalog model is used for category with catalog entry", () => {
|
||||
// given - ultrabrain has catalog entry
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
|
||||
export { resolveCategoryConfig } from "./categories"
|
||||
export type { SyncSessionCreatedEvent, DelegateTaskToolOptions, BuildSystemContentInput } from "./types"
|
||||
export { buildSystemContent } from "./prompt-builder"
|
||||
export { buildSystemContent, buildTaskPrompt } from "./prompt-builder"
|
||||
|
||||
export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefinition {
|
||||
const { userCategories } = options
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { DelegateTaskArgs, ToolContextWithMetadata } from "./types"
|
||||
import type { ExecutorContext, ParentContext, SessionMessage } from "./executor-types"
|
||||
import { DEFAULT_SYNC_POLL_TIMEOUT_MS, getTimingConfig } from "./timing"
|
||||
import { buildTaskPrompt } from "./prompt-builder"
|
||||
import { storeToolMetadata } from "../../features/tool-metadata-store"
|
||||
import { formatDuration } from "./time-formatter"
|
||||
import { formatDetailedError } from "./error-formatting"
|
||||
@@ -20,9 +21,10 @@ export async function executeUnstableAgentTask(
|
||||
const { manager, client, syncPollTimeoutMs } = executorCtx
|
||||
|
||||
try {
|
||||
const effectivePrompt = buildTaskPrompt(args.prompt, agentToUse)
|
||||
const task = await manager.launch({
|
||||
description: args.description,
|
||||
prompt: args.prompt,
|
||||
prompt: effectivePrompt,
|
||||
agent: agentToUse,
|
||||
parentSessionID: parentContext.sessionID,
|
||||
parentMessageID: parentContext.messageID,
|
||||
|
||||
Reference in New Issue
Block a user