fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix(codex): show sub-agent models - #136

Merged
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models
Aug 29, 2026
Merged

fix(codex): show sub-agent models#136
rynfar merged 2 commits into
pylonfrom
upstream/2026-08-28-codex-subagent-models

Conversation

@rynfar

@rynfarrynfar commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.

Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent, so a
child never claims a model it is not running.

Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).

Adaptation

Two conflicts, both in the same place conceptually: Pylon and upstream had each
added fields to the child-identity payload.

  • CodexAdapter.ts — kept Pylon's toolUseId alongside upstream's model
    and effort. The linkage object immediately below already spread all three,
    so this was a "both added a const" conflict with an unambiguous answer.
  • CodexSessionRuntime.ts — adopted upstream's new collabChildIdentity
    helper and spread Pylon's toolUseId at the call site rather than folding it
    into the helper. The helper describes the child; toolUseId names the
    child's live turn, and turn/started overrides it with the id the
    notification itself carries. Merging the two would have conflated different
    lifetimes.

Verification

  • vp test run across CodexAdapter.test.ts,
    CodexCollabRuntime.integration.test.ts, CodexCollabWire.test.ts,
    ThreadBackgroundLiveness.test.ts, subagentRuntime.test.ts — 121 passed

  • vp run -F t3 typecheck and -F @t3tools/client-runtime typecheck — clean

  • vp lint on both conflicted files — clean

  • Mutation probes on both halves of the resolution, since silently dropping
    one side is the whole risk here:

    • removing Pylon's toolUseId spread fails "terminal rows retain the
      activation id for deterministic persisted folding";
    • removing upstream's model/effort fails two assertions with
      expected { …(3) } to have deep property 'model'.

    So each side is independently guarded, and the merge kept both.

Claude Opus 5 via Claude Code.


View with [code]smithAutofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

@github-actionsgithub-actionsBot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Aug 28, 2026
@github-actions

github-actionsBot commented Aug 28, 2026

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire13.3 KiB13.3 KiB+13 B (+0.1%)15.1 KiB
CodexThread snapshot wire6.9 KiB6.9 KiB+2 B (+0.0%)7.3 KiB
CodexLive turn WebSocket wire6.4 KiB6.4 KiB+11 B (+0.2%)7.8 KiB
CodexLive turn WebSocket decoded55.5 KiB55.5 KiB0 B (0.0%)66.4 KiB
CodexLive turn messages990 (0.0%)21
ClaudeTotal thread wire13.3 KiB13.2 KiB−161 B (−1.2%)15.1 KiB
ClaudeThread snapshot wire6.9 KiB6.9 KiB+15 B (+0.2%)7.3 KiB
ClaudeLive turn WebSocket wire6.5 KiB6.3 KiB−176 B (−2.7%)7.8 KiB
ClaudeLive turn WebSocket decoded56.4 KiB55.5 KiB−928 B (−1.6%)66.4 KiB
ClaudeLive turn messages119−2 (−18.2%)21

Baseline: 3d6035f · PR result: 08820bc · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 109.4 KiB
  • Claude decoded thread snapshot: 110.1 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@rynfar

Copy link
Copy Markdown
CollaboratorAuthor

Independent review pass. Five findings — one fixed, four are upstream bugs I am
documenting rather than changing blind, since none can be verified without a real
Codex 0.150 app-server.

Fixed in 03db9fab3 — the adopted paragraph in docs/user/providers-codex.md
said "T3 Code leaves it out" in a shipped-product page. My conflict resolution
missed it. (The install.md mentions of T3 Code are deliberate: they describe
Pylon installing beside it.)

thread/resume is sent with a parameter that does not exist.
CodexSessionRuntime.ts:1360 passes excludeTurns: true, and the comment above
it claims that "avoids loading or replaying its history". excludeTurns appears
0 times in the generated schema; includeTurns appears 15, and only on
thread/read. client.raw.request is untyped, so this compiles. Against a real
app-server it either errors — swallowed by Effect.catch, meaning no sub-agent
ever shows a model while the mock-peer test still passes — or is ignored, loading
the child's full rollout history and resuming a possibly mid-turn child. This is
upstream's line, added by 49f6241dd, not a Pylon adaptation. I left it because
both failure modes are plausible and removing it blind could as easily break the
feature as fix it.

A transient timeout permanently loses a child's model.lookupStarted is
latched before the request and never reset on failure or timeout, so one 5s
timeout leaves that child without model/effort for the session. The
closed + lookupStarted pair likewise blocks re-lookup for a re-registered
child.

Cleared effort keeps a stale value.updateCollabChildMetadata only assigns
truthy values, so an effort cleared by thread/settings/updated retains the old
one even with overwriteKnown: true.

collabChildMetadataRef grows without bound. Entries are only flagged
closed, never deleted, and the new intercept inserts one for any non-root
thread id — unlike the sibling maps, which clean up on thread/closed.

The review separately cleared the parts I most wanted checked: the contracts
already carry model/effort on task payloads and the client fold consumes them,
the thread/settings/updated and model/rerouted schemas match the field
accesses, the routing/suppression change is consistent, and the
ThreadBackgroundLiveness widening is required by the new status-free
task.updated without regressing another adapter path.

t3dotggand others added 2 commits August 28, 2026 20:55
Codex sub-agents did not carry their model metadata into task events, so the
Agents panel could not show a child's model or reasoning effort.
Reads model and effort from each spawned child thread, updates them when Codex
reports a settings change or a model reroute, and includes them in later task
events. Unknown values are omitted rather than inherited from the parent.
Adopted from T3 Code 49f6241ddeee2a5d20ec181b5b94ec0a9ac72f7b
(pingdotgg/t3code#8502).
Adaptation: two conflicts, both places where Pylon and upstream had each added
fields to the same child-identity payload.
CodexAdapter kept Pylon's toolUseId alongside upstream's model and effort; the
linkage object below already spread all three.
CodexSessionRuntime adopted upstream's collabChildIdentity helper and spreads
Pylon's toolUseId at the call site. The helper describes the child, while
toolUseId names the child's live turn, and turn/started overrides it with the id
the notification carries — so folding it into the helper would have conflated
two different lifetimes.
Review follow-up. The paragraph adopted from upstream #8502 named T3 Code in a
docs/user page, which is shipped-product voice. The remaining T3 Code mentions in
install.md are deliberate: they describe Pylon installing beside T3 Code.
@rynfar
rynfarforce-pushed the upstream/2026-08-28-codex-subagent-models branch from 03db9fa to 08820bcCompareAugust 29, 2026 02:55
@rynfar
rynfar merged commit 68e3560 into pylonAug 29, 2026
15 checks passed
@rynfar
rynfar deleted the upstream/2026-08-28-codex-subagent-models branch August 29, 2026 03:05
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:Lvouch:trustedPR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@rynfar@t3dotgg