Skip to content

fix(devin): prevent reset waits from holding active-turn capacity - #5455

Draft
luvs01 wants to merge 2 commits into
lidge-jun:devfrom
luvs01:fix/558-devin-reset-capacity
Draft

luvs01 wants to merge 2 commits into
lidge-jun:devfrom
luvs01:fix/558-devin-reset-capacity

Conversation

@luvs01

@luvs01 luvs01 commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Motivation

  • A Devin turn that hits a provider 429 with a stated reset delay (for example limit will reset in 21 minutes) was sleeping inside the admitted HTTP turn, holding globally shared active-turn capacity for the whole wait.

Description

  • Pass maxWaitMs: 0 to streamChatEventsWithResetRetry in the Devin adapter so a provider-stated 429 surfaces its parsed Retry-After to the client instead of retaining capacity while waiting.
  • The stated-reset retry path still supports an explicit wait allowance for callers that opt in; the adapter now declines it.
  • structure/providers-and-adapters.md documents the surfaced-reset behavior.
  • Regression coverage in tests/providers/devin-stated-reset-retry.test.ts asserts a zero wait allowance surfaces the stated reset without sleeping.

Testing

  • bun test tests/providers/devin-stated-reset-retry.test.ts: 13 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

⏳ DRAFT

  • review readiness checklist open (0/4 boxes ticked).

What to do

  • Tick all four boxes in the PR description once you're done (currently 0/4).
  • New commits were pushed after the checklist was completed on df07bc6; the current head is 0e73736.
  • The checklist has been reset: re-test against the latest code and tick all four boxes again.

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.

0/4 boxes ticked.

New commits were pushed after the checklist was completed on df07bc6; the current head is 0e73736.
The checklist has been reset: re-test against the latest code and tick all four boxes again.
This PR stays in draft until every box above is ticked.

@lidge-jun

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 62 / 80

Devin이 한도를 넘기면 "21분 뒤에 풀린다" 같은 429를 돌려줍니다. 지금까지 그 요청은 이미 받은 자리(활성 턴)를 잡은 채로 그 시간 동안 잠들어 있었습니다. 이 자리는 서버 전체가 같이 씁니다. 한 요청이 오래 기다리면 다른 요청이 그 자리를 못 받습니다.

이 PR은 Devin 어댑터가 재시도 함수를 부를 때 기다림 한도를 0으로 고정합니다. 한도가 0이면, 메시지에 적힌 대기 시간이 1초라도 있으면 잠들지 않고 원래 429를 바로 던집니다. 어댑터는 그걸 실패로 끝내고 자리는 풀립니다. 설명 한 줄과, 한도 0이면 sleep이 호출되지 않는 테스트가 같이 들어갔습니다.

src/adapters/devin.ts:666 - 주석은 파싱한 Retry-After를 클라이언트에 보여 준다고 적혀 있습니다. 초 숫자는 기다릴지 말지 고를 때만 쓰이고, 그 값은 버려집니다. 스트리밍 응답은 HTTP 200으로 이미 나가고 본문은 response.failed입니다. Retry-After 헤더는 없습니다. 영어 문장 "reset in 21 minutes"만 에러 메시지 안에 남습니다. 헤더만 보고 다시 시도하는 클라이언트는 곧장 다시 들어올 수 있습니다.

tests/providers/devin-stated-reset-retry.test.ts:189 - 새 테스트는 헬퍼에 maxWaitMs: 0을 직접 넣습니다. 어댑터가 그 값을 넘기는지는 보지 않습니다. 어댑터의 그 한 줄을 지워도 이 테스트는 통과합니다.

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

35초처럼 짧은 리셋도 이제 안에서 기다리지 않습니다. 환경 변수 OPENCODEX_DEVIN_STATED_RESET_WAIT_MS는 헬퍼를 직접 부르는 쪽에만 남고, 실제 Devin 경로는 항상 0이라 이 값을 무시합니다. 콤보 시도는 첫 사건이 에러면 HTTP 502로 감싸고 Retry-After를 넣지 않습니다 (src/server/responses/run-turn-execution.ts:382). 이 429가 이제 그 길로 바로 갑니다.

너의 추천

자리를 붙잡고 잠드는 동작은 끊는 쪽이 맞습니다. 머지해도 됩니다. 실패 메시지에 클라이언트가 이미 읽는 초 단위 힌트가 들어가는지만 한 번 확인해 주세요. 테스트는 어댑터가 maxWaitMs: 0을 넘긴다는 사실만 고정하면 됩니다.

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

@luvs01

luvs01 commented Sep 21, 2026

Copy link
Copy Markdown
Contributor Author

Review feedback applied on 0e73736738:nn- New adapter-level test devin-adapter-reset-wait.test.ts mocks only the stated-reset-retry leaf module, drives the real adapter runTurn, and asserts the helper receives maxWaitMs: 0 - removing that line now fails the test.n- The comment above the call now describes what actually happens: the stated reset surfaces inside the original error message text (no Retry-After header on the streamed response) and the shared slot frees immediately.nnTests: devin-adapter-reset-wait1 pass,devin-stated-reset-retry` 13 pass.

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