Skip to content

Commit 6605afd

Browse files
committed
fix(subagent): keep explicit parent pin across provider rebuild
1 parent 8c1e310 commit 6605afd

2 files changed

Lines changed: 67 additions & 1 deletion

File tree

‎src/subagent/agent-fleet-effort.test.ts‎

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,63 @@ describe("custom worker efforts", () => {
247247
expect(worker?.provider.explicitReasoningEffort).toBeUndefined();
248248
});
249249

250+
test("explicit parent pin survives the applyResolvedProvider rebuild (CL-10227)", async () => {
251+
// A profile/director spawn with a resolving inference rebuilds `provider`
252+
// from settings via applyResolvedProvider. That rebuild must not drop the
253+
// operator-explicit parent-effort marker — otherwise the operator pin is
254+
// demoted to a derived parent and the leaf role default (medium) wins,
255+
// violating the CL-10227 fleet-pin contract. Here the model ladder supports
256+
// both the parent ("none") and the role default ("medium"), so only the
257+
// surviving explicit flag can pick "none".
258+
let worker: RunSubAgentParams | undefined;
259+
const pinProvider: ProviderCatalogEntry = {
260+
...provider,
261+
reasoningEfforts: ["none", "medium", "max"],
262+
};
263+
const deps = createFleetDeps(
264+
async (params) => {
265+
worker = params;
266+
return { report: "done" };
267+
},
268+
{
269+
settings: { providers: { custom: pinProvider } },
270+
catalog: [pinProvider],
271+
profiles: [
272+
{
273+
id: "custom-leaf",
274+
inference: {
275+
mode: "pin",
276+
order: [
277+
{
278+
provider: pinProvider.name,
279+
model: "custom-model",
280+
},
281+
],
282+
},
283+
},
284+
],
285+
},
286+
);
287+
deps.provider = {
288+
providerName: pinProvider.name,
289+
baseURL: pinProvider.baseURL,
290+
model: "custom-model",
291+
reasoningEffort: "none",
292+
explicitReasoningEffort: true,
293+
};
294+
const result = await callFleetToolRaw(createSpawnAgentTool(deps), {
295+
description: "inspect",
296+
prompt: "inspect",
297+
agent: "custom-leaf",
298+
});
299+
expect(result.isError).not.toBe(true);
300+
await callFleetToolRaw(fleetTools(deps).wait, { timeout_ms: 2000 });
301+
// The operator-explicit parent pin ("none") survives the rebuild and beats
302+
// the leaf role default ("medium").
303+
expect(worker?.provider.reasoningEffort).toBe("none");
304+
expect(worker?.provider.explicitReasoningEffort).toBe(true);
305+
});
306+
250307
test("explicit effortPin still wins over an explicit parent", async () => {
251308
// An explicit parent is a fleet pin, but the cascade still lets an explicit
252309
// effortPin outrank it — the legacy pin-max case stays.

‎src/subagent/agent-fleet.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,11 @@ export function createSpawnAgentTool(deps: AgentFleetDeps): AgentTool {
10151015

10161016
let provider: SubAgentProvider = resolveDep(deps.provider);
10171017
const parentEffort = provider.reasoningEffort;
1018+
// Operator-chosen parent effort signal, captured BEFORE applyResolvedProvider
1019+
// may rebuild `provider` from settings (which drops any marker). Read from
1020+
// this captured value everywhere so the explicit fleet-pin survives the
1021+
// rebuild; `true` is the only value the type allows.
1022+
const parentExplicit = provider.explicitReasoningEffort === true;
10181023
const diskSettings =
10191024
deps.settings !== undefined ? resolveDep(deps.settings) : undefined;
10201025
const catalog =
@@ -1067,6 +1072,10 @@ export function createSpawnAgentTool(deps: AgentFleetDeps): AgentTool {
10671072
? { apiKey: providerSettings.apiKey }
10681073
: {}),
10691074
model: resolved.model,
1075+
// The operator-chosen parent-effort marker is not a provider fact:
1076+
// it survived the rebuild so an effort-carrying director/profile
1077+
// spawn keeps its explicit fleet-pin signal (re-read at resolve time).
1078+
...(parentExplicit ? { explicitReasoningEffort: true } : {}),
10701079
};
10711080
return null;
10721081
};
@@ -1183,7 +1192,7 @@ export function createSpawnAgentTool(deps: AgentFleetDeps): AgentTool {
11831192
? { roleDefault: resolved.roleDefault }
11841193
: {}),
11851194
...(parentEffort !== undefined ? { parentEffort } : {}),
1186-
...(parentEffort !== undefined && provider.explicitReasoningEffort
1195+
...(parentEffort !== undefined && parentExplicit
11871196
? { explicitParentEffort: true }
11881197
: {}),
11891198
model: provider.model,

0 commit comments

Comments
 (0)