Skip to content

fix(responses): isolate Cursor combo shadow calls - #5460

Closed
luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:fix/480-cursor-combo-shadow
Closed

luvs01 wants to merge 1 commit into
lidge-jun:devfrom
luvs01:fix/480-cursor-combo-shadow

Conversation

@luvs01

@luvs01 luvs01 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Motivation

  • A shadow call rewritten to a combo target lost its conversation isolation on the concrete combo children: the child selectors no longer match the shadow source model, so the provider-specific helper isolation that the intercept relies on was not applied.

Description

  • Add shadowCallIntercepted to HandleResponsesOptions and set it when the early intercept rewrites the request into a combo, carrying the decision through handleComboResponses.
  • In prepareResponsesRequest, a combo child dispatched with shadowCallIntercepted === true sets parsed._cursorIsolateConversation = true, preserving the isolation the late intercept applies for non-combo replacements.
  • Regression coverage in tests/responses/responses-shadow-intercept.test.ts asserts the flag is carried into the combo dispatch and applied to parsed children.

Testing

  • bun test tests/responses/responses-shadow-intercept.test.ts: 24 tests pass.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • 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.

@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

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

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added bug Something isn't working review-ready labels Sep 21, 2026
@github-actions

github-actions Bot commented Sep 21, 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.

Automatic ready-for-review conversion failed; please mark the pull request ready manually if it is still a draft.
The review-ready label marks this PR as ready; review automation runs independently.
Maintainers: @lidge-jun @Ingwannu

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 54 / 80

이 PR은 헬퍼 호출이 그림자 가로채기로 콤보가 될 때, 콤보 안의 실제 호출이 부모 Cursor 대화를 그대로 이어 쓰던 구멍을 막습니다.

그림자 가로채기는 정해 둔 모델 이름을 다른 대상으로 바꿉니다. 대상이 콤보가 아니면, 요청을 다 읽은 뒤 늦은 자리에서 _cursorIsolateConversation을 켭니다. 이 표시가 켜지면 Cursor는 부모 대화를 이어 쓰지 않고 새 대화 번호를 만듭니다.

대상이 콤보면 순서가 달라집니다. 이름을 콤보로 바꾸는 일은 콤보 분기로 들어가기 전에 끝납니다. 그 다음 handleComboResponses가 자식 요청을 보냅니다. 자식의 모델 이름은 이미 콤보 안의 구체 모델이라, 늦은 자리의 "이 이름이 그림자 원본인가?" 검사가 실패합니다. 격리 표시가 안 켜지고, 자식이 부모 Cursor 대화에 붙습니다.

이 PR은 그 결정을 shadowCallIntercepted라는 표시로 콤보 호출에 넘깁니다. 자식이 요청을 파싱한 직후, 표시가 true일 때만 _cursorIsolateConversation을 켭니다. 보통 콤보는 false라서 격리가 켜지지 않습니다. handleComboResponses는 부모 옵션을 자식에게 펼쳐 넘기므로, 이 표시는 자식 준비 단계까지 갑니다. 베이스는 dev입니다. 파일은 옵션 타입, 요청 준비, 테스트 세 개입니다. 아직 draft입니다. 체크리스트는 4/4입니다.

라인 tests/responses/responses-shadow-intercept.test.ts — 새 테스트는 request-prepare.ts 파일을 읽어서 두 문장이 있는지만 봅니다. 콤보 자식을 준비해서 _cursorIsolateConversation이 true인지는 안 봅니다. 문장을 다른 곳으로 옮기면 동작이 맞아도 테스트가 깨집니다. 문장만 있고 handleComboResponses가 표시를 자식에게 안 넘겨도 테스트는 통과합니다. 바로 아래 429 테스트는 요청을 실제로 보냅니다.

라인 src/server/responses/request-prepare.ts 이른 가로채기 — 콤보로 바꾸는 기존 조건 그대로 shadowCallIntercepted를 켭니다. 그 조건에는 shouldInterceptShadowCall이 없습니다. 늦은 자리는 그 검사가 참일 때만 격리합니다. 그래서 늦은 자리가 거절했을 호출도, 콤보로 바뀌기만 하면 자식은 격리됩니다.

같은 표시를 가진 열린 PR이 있습니다. #5365는 이 격리에 더해, 이른 바꾸기에도 shouldInterceptShadowCall을 넣고, prepareResponsesRequest를 호출해 플래그를 확인합니다. 검색 다리 수리도 같이 들어 있습니다. 둘을 같이 머지하면 같은 옵션이 겹칩니다.

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

#5460만 남길지, #5365로 이 구멍을 닫을지입니다. #5365의 검색 다리 수리가 아직 불안하면 격리만 작은 PR로 두는 편이 맞습니다. 그때는 이 PR에 늦은 자리와 같은 shouldInterceptShadowCall 조건과, 파일 글자가 아니라 준비된 요청의 플래그를 보는 테스트를 넣어야 합니다.

너의 추천

이 PR을 그대로 머지하지 마세요. 베이스 dev는 맞습니다. types.ts/config.ts를 나누는 변경은 아닙니다. #5365가 같은 격리 표시를 이미 갖고, 조건은 더 좁고, 테스트는 실제로 요청을 준비합니다. 검색 다리까지 같이 넣을 수 있으면 #5460은 닫고 #5365를 보세요. 격리만 먼저 넣을 거면 #5365의 그 조건과 행동 테스트만 이 PR로 가져오고, #5365에서는 그 부분을 빼세요. 둘 다 열어 두지 마세요.

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

@luvs01

luvs01 commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #5365 per review: that PR carries the same shadowCallIntercepted flag but gates it on shouldInterceptShadowCall (narrower - this PR enabled isolation on any combo rewrite, including calls the late site would have rejected) and verifies it by running prepareResponsesRequest instead of matching source strings. Verified by diff readback of #5365. Superseded, not abandoned.

@luvs01 luvs01 closed this Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants