fix(delegate-task): harden child-session first-prompt fallback recovery#3825
Conversation
Capture delegated child-session retry context before the first prompt so fallback recovery still works when session history is empty. Align background and sync launch paths around the same bootstrap contract, clear session-scoped fallback state on every terminal path, and lock the behavior with regression coverage for first-prompt retries, exhaustion, isolation, and cleanup. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
There was a problem hiding this comment.
No issues found across 10 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Requires human review: Cannot guarantee 100% no regressions; risk of edge-case behavioral changes despite passing tests and AI review.
Keep the new manager-side bootstrap registration as the primary path, but restore a compatibility fallback when the parent call aborts before the child session id resolves. This preserves late delegated session wiring for already-launched background tasks without reverting the new bootstrap architecture. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
|
Follow-up fix pushed in This keeps the new manager-side bootstrap registration as the primary path, but restores a compatibility fallback for the background delegated path when the parent call aborts before the child session id resolves. Why this follow-up was needed:
What this follow-up does:
This avoids regressing the stronger new design while preserving the older tool-boundary behavior that existing CI still expects. Re-verified locally with: bun test src/tools/delegate-task/background-task.test.ts
bun test src/features/background-agent/manager.test.ts src/hooks/runtime-fallback/index.test.ts src/tools/delegate-task/sync-task.test.ts
bun run typecheckAll passed locally. |
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: While the PR provides comprehensive regression tests and logic for a valid fix, the scale of changes and introduction of new global state for session management warrant human verification to guarantee 100% regression safety.
Reconcile the latest dev branch changes with the delegated child-session fallback work. Preserve the upstream background-agent updates while keeping the delegated bootstrap cleanup and compatibility wiring fixes intact, then re-verify the affected regression suites and typecheck. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
|
Quick update after the last round of conflict resolution:
bun test src/features/background-agent/manager.test.ts src/features/background-agent/fallback-retry-handler.test.ts src/features/background-agent/spawner.test.ts src/hooks/runtime-fallback/index.test.ts src/tools/delegate-task/background-task.test.ts src/tools/delegate-task/sync-task.test.ts
bun run typecheckThose checks passed locally ( One more thing changed afterward:
So at this point:
|
Sync the PR branch with the latest dev branch and resolve the remaining conflict in sync-task.test.ts while preserving both the new upstream poll-recovery coverage and this branch's delegated bootstrap cleanup and isolation coverage. Re-verified the affected delegated fallback suites and typecheck after the merge resolution. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Sync the PR branch with the newest dev branch and resolve the new import-level conflicts in background-agent manager and runtime-fallback tests. Preserve both the delegated bootstrap coverage from this branch and the newer upstream test utilities and runtime wiring changes, then re-verify the affected delegated fallback suites and typecheck. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…strap Revert "Merge pull request #3825 from tw-yshuang/fix/delegated-child-session-early-failure-fallback"
|
Reverted on dev via #4044 — full reasoning there. Short version: after merge, the PR's own To re-land:
|
…erral PR code-yeongyu#3825 introduced a delegated child-session bootstrap to capture first-prompt retry payloads before history is persisted, addressing the empty-history fallback gap. After merge the PR's own regression test failed on clean root bun test (6828 pass / 1 fail), so PR code-yeongyu#4044 reverted it. Ship v4.2.0 with the bug documented and a workaround so users have an explicit story for the unfixed delegated child-session early-failure path. Reland will target v4.2.1. Closes BLOCKER-4 (Path B - reland deferred to v4.2.1)
…OCKER-4) PR code-yeongyu#3825's fac90d6 introduced a shared bootstrap context to fix delegated child-session fallback when the first prompt fails before any session history is persisted. PR code-yeongyu#4044 reverted that fix because its own regression test failed on a clean root suite (6828 pass / 1 fail). The bug remains unaddressed in v4.2.0; reland is deferred. This commit documents the symptom, history, workaround, and tracking issue so users have visibility. Closes BLOCKER-4 via Path B (documentation). Refs PR code-yeongyu#3825, PR code-yeongyu#4044, issue code-yeongyu#4059.
Update the v4.2.0 known issue with the filed follow-up issue and exact PR code-yeongyu#3825/code-yeongyu#4044 commit details. Refs code-yeongyu#4059.
…t deferral PR code-yeongyu#3825 added a shared bootstrap context to capture delegated child-session retry payloads before the first prompt dispatch, so empty-history failures could still retry through the fallback chain. The PR's own regression test failed on clean root bun test after merge (6828 pass / 1 fail). PR code-yeongyu#4044 reverted the merge to keep dev green. Ship v4.2.0 with the bug documented and a workaround so users have an explicit story for the unfixed delegated child-session early-failure path. Reland targets v4.2.1 once the regression test is stabilized. Closes BLOCKER-4 (Path B - documentation, reland deferred to v4.2.1)
Document all 7+ BLOCKER+HIGH fixes, breaking-change-free additions (public exports), known issue for delegated child-session fallback (PR code-yeongyu#3825 deferred to v4.2.1), and internal-only changes. Closes L14
…erral PR code-yeongyu#3825 introduced a delegated child-session bootstrap to capture first-prompt retry payloads before history is persisted, addressing the empty-history fallback gap. After merge the PR's own regression test failed on clean root bun test (6828 pass / 1 fail), so PR code-yeongyu#4044 reverted it. Ship v4.2.0 with the bug documented and a workaround so users have an explicit story for the unfixed delegated child-session early-failure path. Reland will target v4.2.1. Closes BLOCKER-4 (Path B - reland deferred to v4.2.1)
|
Follow-up note: this PR was already reverted on dev via #4044, and the underlying delegated child-session first-prompt / empty-history fallback problem has since been addressed more completely by #4074. The relevant upstream fix is in #4074, especially commit ba64868: fix(runtime-fallback): carry delegated system and tools through bootstrap retry. That implementation reuses the existing delegated child-session bootstrap state instead of adding a separate runtime-fallback cache, and it preserves the full delegated retry context:
Because #4074 covers the same failure mode with a cleaner and broader upstream implementation, I am not going to re-land the older #3825 approach. Any further validation should be based on current dev after #4074 rather than on this reverted branch. |
Summary
Background
In the delegated child-session flow, a subagent session can fail on the very first
promptAsynccall because of a provider or model error.Before this change, that path had two related problems:
session.messagesto recover the last user prompt, so empty-history first-prompt failures could not retryThat left delegated child sessions stuck in early failure without correctly advancing to fallback models.
First-prompt early-failure flow after this change
session.messagesflowchart TD A[Parent session delegates child task] --> B[Create child session] B --> C[Register delegated bootstrap context before first prompt] C --> D[Send first prompt] D -->|Success| E[Continue normal background or sync flow] D -->|Failure| F{Retryable error?} F -->|No| G[Enter terminal path] F -->|Yes| H{session.messages has user parts?} H -->|Yes| I[Use persisted user parts for retry] H -->|No| J{Delegated bootstrap exists?} J -->|No| G J -->|Yes| K[Use bootstrap retry parts] I --> L[Pick next fallback model] K --> L L --> M{Fallback chain exhausted?} M -->|No| N[Retry with next fallback model] M -->|Yes| G N --> O{Retry succeeds?} O -->|Yes| P[Continue task execution] O -->|No| F E --> Q[Terminal cleanup] P --> Q G --> Q Q --> R[Clear bootstrap prompt context] Q --> S[Clear fallback-chain registration] Q --> T[Clear category registration]What changed
Shared delegated bootstrap contract
Background path atomic registration
Runtime fallback support for empty-history retry
Sync path alignment and cleanup
Regression coverage
Affected areas
src/features/background-agent/manager.tssrc/tools/delegate-task/background-task.tssrc/tools/delegate-task/sync-task.tssrc/tools/delegate-task/sync-prompt-sender.tssrc/hooks/runtime-fallback/auto-retry.tssrc/hooks/runtime-fallback/last-user-retry-parts.tssrc/shared/delegated-child-session-bootstrap.tsVerification
bun test src/features/background-agent/manager.test.ts src/features/background-agent/fallback-retry-handler.test.ts src/features/background-agent/spawner.test.ts src/hooks/runtime-fallback/index.test.ts src/tools/delegate-task/sync-task.test.ts bun run typecheck256 pass, 0 failNeed help on this PR? Tag
@codesmithwith what you need.Summary by cubic
Fixes delegated child-session fallback when the first prompt fails before any history exists. Captures the first-prompt retry payload at launch and cleans up on every terminal path to keep state consistent and isolated.
shared/delegated-child-session-bootstrapto register retry parts, fallback chain, and category before the first prompt in both background and sync flows.sessionIDto last-user lookup and uses bootstrap retry parts when history is empty; does not invent payloads if no bootstrap exists.sendSyncPrompt, and clears per-session bootstrap/fallback context on retries and finish; concurrent sessions remain isolated.devand resolved manager/runtime-fallback conflicts while keeping delegated bootstrap wiring and upstream poll-recovery; expanded tests for empty-history retries, terminal launch cleanup, scheduled-retry cleanup, cancellation/completion cleanup, isolation, exhaustion, and non-retryable errors.Written for commit 12f5233. Summary will update on new commits.