Skip to content

fix(web-search): release unused OpenAI probe leases - #4946

Merged
lidge-jun merged 7 commits into
lidge-jun:devfrom
luvs01:agent/websearch-probe-lease-20260918
Sep 18, 2026
Merged

lidge-jun merged 7 commits into
lidge-jun:devfrom
luvs01:agent/websearch-probe-lease-20260918

Conversation

@luvs01

@luvs01 luvs01 commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The passthrough web-search bridge resolves an OpenAI sidecar before the routed provider reveals whether it will call web_search, and that resolution can grant the account's sole quota-recovery probe lease. When the turn ends without a search — or the client cancels — nothing settled the lease, so the cooled account stayed locked out of recovery probes until the cooldown itself expired.
  • Add an onFinalize?: () => void hook to PassthroughWebSearchBridgeStreamOptions and run it exactly once on normal completion, error, and client cancellation inside createPassthroughWebSearchBridgeStream.
  • Pass a finalizer from the Responses delivery path that calls releaseCodexAuthContextProbeLease(openAiSidecar?.authContext). After an executed search the outcome recorder has already settled the lease, so the release is a no-op on that path; on the no-search and cancellation paths it hands the lease back so a later probe can be granted.
  • Record the sidecar-authority/probe-lease lifecycle invariant in structure/runtime.md and extend the bridge tests to assert the finalizer runs on the no-search completion and on client cancellation.

Verification

  • Head SHA: f04e823da7c411892b2234f458511c047eb5c549 (tree 0dfdf8f5feb2a761caa94baab5936b6a1da3ecac), based on dev e80e571f63a52a3dbba0edeeb576060debf14190.
  • bun test tests/web-search/web-search-passthrough-bridge.test.ts: 68 pass, 0 fail.
  • bun x tsc --noEmit: clean. bun run structure:check: passed. bun run privacy:scan: passed. bun scripts/file-size-ratchet.ts: passed.
  • Fork CI dispatched: diagnostic run 35278777982 (contributor fork Actions)

Remaining gates:

Summary by CodeRabbit

  • Bug Fixes

    • Improved web-search request cleanup when searches complete, fail, or are cancelled.
    • Client cancellations now release temporary request resources immediately, preventing them from remaining reserved while an upstream operation is still pending.
    • Ensured cleanup occurs only once across all request-ending scenarios.
  • Documentation

    • Clarified hosted-search behavior for completed, failed, and cancelled requests.

@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: e83f7070-4928-492b-b44b-2e4954d193b9

📥 Commits

Reviewing files that changed from the base of the PR and between 4c0124a and f5107ef.

📒 Files selected for processing (4)
  • src/server/responses/passthrough-delivery.ts
  • src/web-search/passthrough-bridge.ts
  • structure/providers-and-adapters.md
  • tests/web-search/web-search-passthrough-bridge.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The passthrough web-search bridge now supports one-time finalization for completion, failure, and cancellation. The response path uses finalization to release an unused OpenAI sidecar probe lease. Tests and documentation cover these lifecycle paths.

Changes

Passthrough finalization

Layer / File(s) Summary
Bridge lifecycle callback
src/web-search/passthrough-bridge.ts, tests/web-search/web-search-passthrough-bridge.test.ts, structure/providers-and-adapters.md
PassthroughWebSearchBridgeStreamOptions adds onFinalize. The stream invokes it once after completion or failure and immediately during cancellation. Tests cover search-free completion and client cancellation. Documentation describes the finalization behavior.
Probe lease release wiring
src/server/responses/passthrough-delivery.ts
The response bridge passes an onFinalize callback that calls releaseCodexAuthContextProbeLease for the request’s OpenAI sidecar context.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to f5107

The finalization change has no established merge-blocking risk in the reviewed paths.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: releasing unused OpenAI probe leases in the web-search passthrough bridge.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 3 files. (1 skipped: 1 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the bug Something isn't working label Sep 17, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions

github-actions Bot commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

✅ READY

  • all PR quality gates passed; the review readiness checklist is complete.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request is already Ready for Review.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

Hygiene

Deterministic PR hygiene checks passed.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 71 / 80

이 PR은 웹검색(passthrough web-search) 다리를 만들 때 미리 잡아 둔 OpenAI 사이드카의 쿨다운 복구용 probe lease를, 실제로 검색을 쓰지 않거나 클라이언트가 중간에 끊어도 다시 돌려주는 고칩니다. 지금 dev(a0f611d · #4526 Unicode schema CoW 팁)에서는 사이드카를 고를 때 lease를 받을 수 있는데, 검색이 안 일어나거나 cancel되면 정산이 안 되어 그 계정이 쿨다운이 끝날 때까지 probe를 못 받는 구멍이 있습니다.

고치는 방법은 단순합니다. PassthroughWebSearchBridgeStreamOptionsonFinalize?를 추가하고, createPassthroughWebSearchBridgeStream이 정상 종료·에러·cancel 때 딱 한 번만 호출합니다. Responses 배달 쪽(deliverPassthroughResponse)에서는 releaseCodexAuthContextProbeLease(openAiSidecar?.authContext)를 넘깁니다. 이미 검색을 실행해 결과 기록기가 lease를 정산한 경우에는 release가 no-op이 되도록 기존 auth-context API에 맞춰 둔 형태입니다. structure/runtime.md에도 sidecar/probe-lease 생애주기 불변식을 적어 두었고, 브리지 테스트에 no-search 완료·client cancel에서 finalizer가 1회 도는 케이스를 넣었습니다.

라인 passthrough-bridge.ts createPassthroughWebSearchBridgeStream cancel - iterator.return?.(reason).finally(finalize)로 cancel 경로에서도 finalize를 보장한 점은 좋습니다. 다만 cancel이 return 없이 끝나는 환경/폴리필에서는 finally가 안 돌 수 있는지, 그리고 pull에서 done/error 직후 finalize와 cancel이 겹칠 때 finalized 플래그가 정말 한 번만 보호하는지 한 번 더 눈으로 확인하면 좋습니다.

라인 passthrough-delivery.ts onFinalize - 사이드카가 없는 경로에서 openAiSidecar?.authContext가 undefined여도 release가 안전하게 무시되는지는 현재 releaseCodexAuthContextProbeLease 시그니처상 OK로 보입니다. 다만 검색이 실행된 뒤 outcome recorder가 이미 settle한 직후 같은 finalize가 다시 불리는 이중 호출이 실제로 no-op인지, lease id가 바뀐 뒤 잘못된 계정에 release가 가지 않는지는 통합 경로(delivery + bridge + routing outcome) 한 케이스로 더 있으면 안심입니다.

라인 web-search-passthrough-bridge.test.ts cancelled client stream - 예전 AbortController.abort 기반 테스트를 getReader().cancel로 바꾼 것은 이번 finalize 계약에 맞습니다. 그런데 signal.abort와 cancel이 동시에 오는 경우·이미 pull이 close된 뒤 cancel이 오는 경우는 커버되지 않습니다. 우선순위는 낮지만 회귀 구멍이 될 수 있습니다.

메인테이너의 판단이 필요한 지점

  • draft + fork CI(macOS control 30분 캡 [Bug]: macOS control is cancelled near its 30-minute limit in full dispatch CI #4905) 완료를 기다릴지, CI 그린 확인 후 ready로 올릴지
  • probe lease release를 bridge 옵션 훅으로 둘지, delivery가 아닌 bridge 내부에서 authContext를 직접 알도록 할지(지금 분리는 테스트 용이성 측면에서 합리적)
  • 검색 실행 후 outcome settle과 onFinalize의 순서 불변식을 runtime.md에 더 세게 박을지

너의 추천
포크 CI가 그린이면 draft 해제 후 랜딩 후보로 두세요. 범위가 작고 tip(a0f611d) 기반이라 리베이스 부담도 적습니다. types.ts/config.ts 분할 캠페인과 무관하니 close-don't-rebase 대상이 아닙니다. cancel+signal 동시 경로 테스트 하나 더 있으면 72→74 쪽으로 올라갑니다.

이 댓글은 grok-bot이 작성했습니다

luvs01 and others added 3 commits September 18, 2026 09:27
…pstream read

cancel() deferred the finalizer until iterator.return() settled. A generator
suspended inside an upstream read cannot process a queued return until that
read completes, so a disconnected client left the OpenAI probe lease held for
the lifetime of an abandoned leg, which is the leak this branch fixes.
Optional chaining also short-circuited the finalizer entirely for an iterator
without a return method.

Finalize first, then request generator teardown.
…udget

structure/runtime.md sits at exactly the 600-line structure-ssot budget on dev
and is not in grace.oversizeDocs, so the two added lines fail that gate once
this branch merges. Fold the same contract into the existing sentence instead;
the file already carries 83 lines over 150 characters, so a long line is its
normal shape.
@github-actions
github-actions Bot marked this pull request as ready for review September 18, 2026 04:07
@lidge-jun
lidge-jun merged commit 0bb1f0a into lidge-jun:dev Sep 18, 2026
13 checks passed
@luvs01
luvs01 deleted the agent/websearch-probe-lease-20260918 branch September 20, 2026 06:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants