Queue approval prompts so a parallel run is not stranded forever - #63
Merged
Conversation
askRunApproval 이 resolve 를 필드 하나(_askRunResolve)에 담고 있었다. 실행이 하나뿐일 때는 맞는데, 이 앱은 위임으로 여러 실행이 동시에 돈다 — 한 라운드에 delegate_task 가 둘이면 하위 실행 둘이 나란히 돌고, 둘 다 셸 명령이나 엔진 작업 승인을 물을 수 있다. 그때 뒤에 온 물음이 앞의 resolve 를 덮었다. 사용자가 답하면 뒤엣것만 풀리고 앞의 실행은 영원히 await 에 매달린다. 상태는 "편집 중" 인 채로 멈추고, 그 실행이 쥔 파일 락은 finally 에 도달하지 못해 풀리지 않으며, 화면에는 아무 말도 안 나온다. 그 파일을 건드리려는 다른 에이전트는 계속 "작업 중입니다" 만 듣는다. engine/askQueue.ts 로 줄을 세운다. 하나씩 보여 주고, 답한 것만 풀고, 다음을 올린다. 모든 물음은 정확히 한 번 풀린다. 에이전트 중지는 이제 보이는 물음뿐 아니라 줄에서 기다리는 그 에이전트의 물음까지 걷어낸다. 안 그러면 중지한 에이전트가 나중에 모달로 되살아나고 그 실행은 계속 매달려 있다. 전체 중지는 줄 전체를 거절로 푼다. 단위 9개 추가(963개 통과). 실제 앱 회귀 확인 5/5.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
askRunApprovalstored itsresolvein a single field:That holds only while one run exists. This app runs several at once — a round with two
delegate_taskcalls starts two sub-runs in parallel (flyinginrunAgentTurn), and either can hit the shell-command or game-engine approval gate.When two gates land, the second overwrites the first's
resolve. Answering the dialog settles only the second. The first run stays parked onawaitforever:edit,finallythat releasesfileLocksis never reached, so other agents asking for that file keep hearing "another agent is working on it",The fix
src/engine/askQueue.tsqueues them: show one, resolve the one that was answered, then raise the next. The invariant is that every request settles exactly once.Stopping an agent now also drops that agent's queued requests, not just the visible one — otherwise a stopped agent's dialog resurfaces later while its run stays parked. Stop-all rejects the whole queue.
Verification
npm run typecheckclean.Scope note: the collision needs two live model runs to reproduce end-to-end, so it is covered by unit tests rather than a CDP probe. The real-app run here checks that the single-dialog path did not regress.