@@ -402,20 +402,17 @@ export async function startOrResumeThread(params: {
|
402 | 402 | params.nativeCodeModeEnabled === false && |
403 | 403 | binding?.webSearchThreadConfigFingerprint === undefined && |
404 | 404 | !persistentWebSearchRestriction; |
| 405 | +let preserveForTransientWebSearchRestriction = false; |
405 | 406 | if ( |
406 | 407 | binding?.threadId && |
407 | 408 | webSearchBindingChanged && |
408 | 409 | !deferLegacyWebSearchRotationToTransientNativeSurface |
409 | 410 | ) { |
410 | 411 | const transientWebSearchRestriction = isTransientWebSearchRestriction(params); |
411 | 412 | if (transientWebSearchRestriction) { |
412 | | -embeddedAgentLog.debug( |
413 | | -"codex app-server web search restricted for turn; starting transient thread", |
414 | | -{ |
415 | | -threadId: binding.threadId, |
416 | | -}, |
417 | | -); |
418 | | -preserveExistingBinding = true; |
| 413 | +// Defer one-turn search restrictions until hard binding invalidations run; |
| 414 | +// otherwise MCP/context/env/plugin/tool changes can keep a stale thread. |
| 415 | +preserveForTransientWebSearchRestriction = true; |
419 | 416 | } else { |
420 | 417 | // Codex can ignore resume overrides for a loaded thread, so persistent |
421 | 418 | // search-policy changes and legacy bindings without metadata rotate first. |
@@ -575,6 +572,15 @@ export async function startOrResumeThread(params: {
|
575 | 572 | ); |
576 | 573 | await clearCodexAppServerBinding(params.params.sessionFile); |
577 | 574 | } |
| 575 | +} else if (preserveForTransientWebSearchRestriction) { |
| 576 | +embeddedAgentLog.debug( |
| 577 | +"codex app-server web search restricted for turn; starting transient thread", |
| 578 | +{ |
| 579 | +threadId: binding.threadId, |
| 580 | +}, |
| 581 | +); |
| 582 | +preserveExistingBinding = true; |
| 583 | +binding = undefined; |
578 | 584 | } else if ( |
579 | 585 | params.nativeCodeModeEnabled === false && |
580 | 586 | !persistentWebSearchRestriction && |
|