fix: resolve 3 bugs - subagent model override, empty plan completion, deep task refusal

- #2741: Pass inheritedModel as fallback in subagent-resolver when user hasn't
  configured an override, ensuring custom provider models take priority
- #2648: Fix getPlanProgress to treat plans with 0 checkboxes as incomplete
  instead of complete (total > 0 && completed === total)
- #2779: Relax Hephaestus single-task guard to accept multi-step sub-tasks
  from Atlas delegation, only rejecting genuinely independent tasks

Fixes #2741, fixes #2648, fixes #2779
This commit is contained in:
YeonGyu-Kim
2026-03-24 09:45:11 +09:00
parent 10e56badb3
commit 230ce835e5
11 changed files with 81 additions and 23 deletions
+5 -1
View File
@@ -261,12 +261,16 @@ You are NOT an interactive assistant. You are an autonomous problem-solver.
4. DO NOT ask clarifying questions - the goal is already defined
**Autonomous executor mindset**:
- You receive a GOAL, not step-by-step instructions
- You receive a GOAL. When the goal includes numbered steps or phases, treat them as one atomic task broken into sub-steps - NOT as separate independent tasks.
- Figure out HOW to achieve the goal yourself
- Thorough research before any action
- Fix hairy problems that require deep understanding
- Work independently without frequent check-ins
**Single vs. multi-step context**:
- Sub-steps of ONE goal (e.g., "Step 1: analyze X, Step 2: implement Y, Step 3: test Z" for a single feature) = execute all steps, they are phases of one atomic task.
- Genuinely independent tasks (e.g., "Task A: refactor module X" AND "Task B: fix unrelated bug Y") = flag and refuse, require separate delegations.
**Approach**:
- Explore extensively, understand deeply, then act decisively
- Prefer comprehensive solutions over quick patches
+3 -2
View File
@@ -17,7 +17,8 @@ export async function resolveSubagentExecution(
args: DelegateTaskArgs,
executorCtx: ExecutorContext,
parentAgent: string | undefined,
categoryExamples: string
categoryExamples: string,
inheritedModel?: string
): Promise<{ agentToUse: string; categoryModel: { providerID: string; modelID: string; variant?: string } | undefined; fallbackChain?: FallbackEntry[]; error?: string }> {
const { client, agentOverrides, userCategories } = executorCtx
@@ -116,7 +117,7 @@ Create the work plan directly - that's your job as the planning agent.`,
: undefined
const resolution = resolveModelForDelegateTask({
userModel: agentOverride?.model,
userModel: agentOverride?.model ?? inheritedModel,
userFallbackModels: normalizedAgentFallbackModels,
categoryDefaultModel: matchedAgentModelStr,
fallbackChain: agentRequirement?.fallbackChain,
@@ -56,7 +56,9 @@ export async function sendSyncPrompt(
const promptArgs = {
path: { id: input.sessionID },
body: {
agent: input.agentToUse,
// When a custom model is configured, omit the agent name so opencode's
// built-in agent fallback chain does not override the user-specified model.
...(input.categoryModel ? {} : { agent: input.agentToUse }),
system: input.systemContent,
tools,
parts: [createInternalAgentTextPart(effectivePrompt)],
+1 -1
View File
@@ -226,7 +226,7 @@ export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefini
return executeUnstableAgentTask(args, ctx, options, parentContext, agentToUse, categoryModel, systemContent, actualModel)
}
} else {
const resolution = await resolveSubagentExecution(args, options, parentContext.agent, categoryExamples)
const resolution = await resolveSubagentExecution(args, options, parentContext.agent, categoryExamples, inheritedModel)
if (resolution.error) {
return resolution.error
}