Skip to content

fix(server): middle-truncate provider handoff only on budget overflow - #431

Merged
johnnyelwailer merged 3 commits into
mainfrom
nexi/handoff-budget-truncate-middle
Oct 7, 2026
Merged

johnnyelwailer merged 3 commits into
mainfrom
nexi/handoff-budget-truncate-middle

Conversation

@johnnyelwailer

Copy link
Copy Markdown
Owner

Summary

When provider handoff delivery would hard-fail with Insufficient context allowance for the provider handoff (ContextHandoffBudgetError), fall back to the fork-style middle-truncate path instead of blocking the switch.

  • Normal handoffs that fit the computed budget are unchanged (no always-truncate).
  • Overflow path: head+tail middle truncation of oversized bodies, then selectHistory; always keeps t3_thread_search / t3_search_thread and t3_thread_read recall instructions.
  • If the computed budget is 0 / too small for even a coverage marker, uses a small emergency floor (HANDOFF_TRUNCATE_FALLBACK_BUDGET = 2048) so the switch can proceed (slight dip into reserved headroom).
  • Coverage strings on the normal path also mention search tools for omitted-item recall.

Repro thread: 215d6410-d777-4254-8a2d-f64fb3f1286c.

Test plan

  • vp test run ContextHandoffBudget.test.ts + ProviderFailure.test.ts (33 pass)
  • ContextHandoffService.test.ts (3 pass)
  • Manual: provider-switch a long Instant thread that previously hit the insufficient-allowance error; confirm handoff succeeds with middle-truncated context + search/read guidance

Do not merge until Phil says go.

When deliverContextHandoffs would throw Insufficient context allowance,
fall back to head+tail middle truncation plus t3_thread_search /
t3_thread_read recall instead of hard-failing. Normal handoffs that fit
the budget are unchanged.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Oct 7, 2026
@johnnyelwailer
johnnyelwailer marked this pull request as ready for review October 7, 2026 12:05
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T12:09:10.285257Z 61f35ae Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

⚠️ The latest CI run did not produce a thread transfer result for e70ddff.

This comment will update automatically after the next completed run.

Intentional upstream touch for overflow-only middle-truncate on provider
handoff budget errors.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 61f35ae97e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +341 to +343
let selected = trySelect(input.messages);
if (historyCost(selected.messages, selected.context) <= effectiveBudget) {
return selected;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Truncate messages before returning the fallback selection

When overflow is caused by an oversized history item, selectHistory simply omits that item until the result fits the 2,048-byte emergency budget, so this condition immediately returns without ever reaching truncatedMessages. If the result does not fit, the excess is in the context wrapper and truncating message bodies cannot fix it. Consequently, the advertised head-and-tail fallback never preserves any part of oversized messages; for example, the new 50,000-character test messages all produce an empty message list. Apply the per-message truncation before accepting the fallback selection.

Useful? React with 👍 / 👎.

messages,
omittedItems,
budget,
threadId: String(input.providerThread.appThreadId ?? pending[0]!.threadId),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the source thread in overflow recall instructions

For a fork_delta_summary handoff, both providerThread.appThreadId and handoff.threadId identify the target thread, while handoff.history.coverage was built with the distinct source thread in prepareForkDelta. The overflow fallback discards that coverage and tells the provider to run t3_thread_read against the target, so when source messages are omitted—especially the all-oversized case—the provider cannot recover the transferred history from the supplied identifier. Derive the recall thread from the source messages/coverage or retain a bounded version of the original coverage.

Useful? React with 👍 / 👎.

Unexport handoffRecallCoverage; pass omittedItems ?? 0 into selectHistory.
@johnnyelwailer
johnnyelwailer merged commit 8414d6f into main Oct 7, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant