From e7ca056ded93a58b0065eaaae518a1617bc2596d Mon Sep 17 00:00:00 2001 From: badcuban <108198679+badcuban@users.noreply.github.com> Date: Fri, 14 Aug 2026 02:26:21 -0400 Subject: [PATCH 1/2] Preserve native subagent model omissions --- apps/web/src/session-logic.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/apps/web/src/session-logic.ts b/apps/web/src/session-logic.ts index 6e9fc185d..74ba7fa39 100644 --- a/apps/web/src/session-logic.ts +++ b/apps/web/src/session-logic.ts @@ -1062,13 +1062,11 @@ function readTurnActivityModelSelection( /** * What each turn was dispatched with, keyed by turn. * - * A spawned agent inherits the parent turn's model and effort unless the spawn - * overrode them, and only Codex's `spawnAgent` item states an override. Its - * other agent lifecycle items — `wait`, `sendInput`, `closeAgent`, and the - * `subAgentActivity` spawn rows — report `model: null`, so a Codex child would - * otherwise have no model or effort to show. The turn lifecycle activities - * carry the dispatched selection for every turn, which is exactly what the - * child inherited. + * Some provider lifecycle items need the parent turn's dispatched selection as + * a seed when they first reveal a child. A native Codex `subAgentActivity` + * spawn is different: its omitted model and effort mean unknown, and later + * coordination items (`wait`, `sendInput`, `closeAgent`) must not retroactively + * replace that omission with the parent turn's settings. * * `provider.turn.preparing` is the only activity that always carries the * selection, and it is projected *before* the provider hands back a turn id, so @@ -1346,6 +1344,13 @@ function collectSubagentActivityRecords( item.type === "subAgentActivity" || turnId === null ? undefined : turnModelSelections.get(turnId); + // Inheritance is only a seed for a newly discovered child. Once a native + // spawn has established the record, later coordination items such as + // `wait` must preserve its deliberately omitted model and effort rather + // than filling them from the parent turn. + const previousOrInheritedModel = previous === undefined ? inherited?.model : previous.model; + const previousOrInheritedReasoningEffort = + previous === undefined ? inherited?.reasoningEffort : previous.reasoningEffort; byAgentId.set(agentId, { id: agentId, @@ -1365,14 +1370,8 @@ function collectSubagentActivityRecords( statusLabel: subagentProgressStatusLabel(status), resolvedModel: resolvedModel ?? previous?.resolvedModel ?? null, model: - resolvedModel ?? - previous?.resolvedModel ?? - model ?? - previous?.model ?? - inherited?.model ?? - null, - reasoningEffort: - reasoningEffort ?? previous?.reasoningEffort ?? inherited?.reasoningEffort ?? null, + resolvedModel ?? previous?.resolvedModel ?? model ?? previousOrInheritedModel ?? null, + reasoningEffort: reasoningEffort ?? previousOrInheritedReasoningEffort ?? null, liveBody, liveBodyUpdatedAt, // Claude supplies a dedicated task stream. Codex child work arrives as From f1d0744f5b42b69c63041924f80756d43b4e17b2 Mon Sep 17 00:00:00 2001 From: badcuban <108198679+badcuban@users.noreply.github.com> Date: Fri, 14 Aug 2026 02:36:53 -0400 Subject: [PATCH 2/2] Update projection snapshot expectation --- .../src/orchestration/Layers/ProjectionSnapshotQuery.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts index 8fc3596f4..255063596 100644 --- a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts +++ b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts @@ -414,6 +414,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { createdAt: "2026-02-24T00:00:06.000Z", }, ], + subagents: [], checkpoints: [ { turnId: asTurnId("turn-1"),