fix(team-mode): preserve per-category model for kind:"category" members
The shared resolveCategoryExecution path treats `agents.sisyphus-junior.model` (plugin config) as a higher-precedence override than the category default. That ranking is correct for plain `task(category=...)` delegations - it lets users pin sisyphus-junior to their preferred general model - but in team-mode it collapses every kind:"category" member onto the same model. Hyperplan was the visible victim: skeptic/validator/researcher/architect/creative are routed through sisyphus-junior with five distinct categories (unspecified-low / unspecified-high / deep / ultrabrain / artistry). With any sisyphus-junior model configured, all five resolved to that single override model instead of their category defaults, defeating the multi-model adversarial debate. Strip the override at the team-mode boundary in resolveMember rather than changing resolveCategoryExecution itself, so: - delegate-task callers keep the existing override semantics (3 regression tests at tools.test.ts:2832, 2958, 3020 stay green) - per-category user overrides (`categories[X].model`) and explicit fallback chains continue to apply - only the `kind:"category"` team-mode path opts out of the global override Lock the contract with a regression test in resolve-member.test.ts. Generated with assistance of [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode).
This commit is contained in:
@@ -75,6 +75,36 @@ describe("resolveMember", () => {
|
|||||||
expect(result.systemContent).toBe("resolved-system-content")
|
expect(result.systemContent).toBe("resolved-system-content")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("strips sisyphusJuniorModel before resolving category members so each declared category keeps its own model", async () => {
|
||||||
|
// given
|
||||||
|
const member = {
|
||||||
|
backendType: "in-process",
|
||||||
|
isActive: true,
|
||||||
|
kind: "category",
|
||||||
|
name: "architect",
|
||||||
|
category: "ultrabrain",
|
||||||
|
prompt: "design X",
|
||||||
|
} satisfies Member
|
||||||
|
const ctxWithJuniorOverride: ExecutorContext = {
|
||||||
|
...createExecutorContext(),
|
||||||
|
sisyphusJuniorModel: "anthropic/claude-sonnet-4-6",
|
||||||
|
}
|
||||||
|
resolveCategoryExecutionMock.mockResolvedValue({
|
||||||
|
agentToUse: "sisyphus-junior",
|
||||||
|
categoryModel: { providerID: "openai", modelID: "gpt-5.5", variant: "xhigh" },
|
||||||
|
categoryPromptAppend: "appendix",
|
||||||
|
maxPromptTokens: 256,
|
||||||
|
fallbackChain: [],
|
||||||
|
})
|
||||||
|
|
||||||
|
// when
|
||||||
|
await resolveMember(member, ctxWithJuniorOverride, "ultrabrain, deep")
|
||||||
|
|
||||||
|
// then
|
||||||
|
const [, executorCtxArg] = resolveCategoryExecutionMock.mock.calls[0]
|
||||||
|
expect(executorCtxArg.sisyphusJuniorModel).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
test("routes subagent members through resolveSubagentExecution", async () => {
|
test("routes subagent members through resolveSubagentExecution", async () => {
|
||||||
// given
|
// given
|
||||||
const member = {
|
const member = {
|
||||||
|
|||||||
@@ -51,6 +51,14 @@ function resolveSystemContent(input: {
|
|||||||
}) ?? ""
|
}) ?? ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strip global `agents.sisyphus-junior.model` override at the team-mode boundary —
|
||||||
|
// `resolveCategoryExecution` ranks it above category defaults (correct for plain
|
||||||
|
// `task(category=…)`, wrong here) and would collapse every team member to the same model.
|
||||||
|
function withoutSisyphusJuniorOverride(ctx: ExecutorContext): ExecutorContext {
|
||||||
|
if (ctx.sisyphusJuniorModel === undefined) return ctx
|
||||||
|
return { ...ctx, sisyphusJuniorModel: undefined }
|
||||||
|
}
|
||||||
|
|
||||||
export async function resolveMember(
|
export async function resolveMember(
|
||||||
member: Member,
|
member: Member,
|
||||||
ctx: ExecutorContext,
|
ctx: ExecutorContext,
|
||||||
@@ -65,7 +73,7 @@ export async function resolveMember(
|
|||||||
category: member.category,
|
category: member.category,
|
||||||
subagent_type: "sisyphus-junior",
|
subagent_type: "sisyphus-junior",
|
||||||
},
|
},
|
||||||
ctx,
|
withoutSisyphusJuniorOverride(ctx),
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user