| #1288 |
foundation: throwIfAborted + shared abort helpers + regression tests |
3b6343354 → merged as e12a42e7a |
— |
✅ MERGED (2026-09-05T01:03Z) |
✅ |
— |
| #1290 |
openai-codex |
1aa5fcd58 |
+653/−24 (5 files) |
✅ |
✅ all checks green (incl. mutation-diff) |
CHANGES_REQUESTED — all CodeRabbit findings fixed & replied (5 threads resolved) |
| #1291 |
openai-native + openai-compatible |
0488a39b7 |
+1424/−19 (6 files) |
✅ |
✅ all 15 checks pass (incl. mutation-diff, e2e-mock); PR review gate pending — "Required CI passed. Waiting for automated review of the latest commit." |
CHANGES_REQUESTED (CodeRabbit: all 11 threads resolved; check shows "Review completed") |
| #1293 |
anthropic, anthropic-vertex, xai, minimax |
895660b54 |
+214/−8 over 3d92d0656 (256 changed executable lines) |
✅ |
✅ all checks green (incl. mutation-diff, e2e-mock); PR review gate pending (same gate state as Zoo-Code-Org#1291) |
CHANGES_REQUESTED — all 10 CodeRabbit threads resolved (the 2 anthropic listener-cleanup findings fixed in 895660b54) |
| #1295 |
opencode-go, unbound, vercel-ai-gateway, zoo-gateway |
25f290cd9 |
+2397/−157 (10 files) |
✅ |
✅ all 19 checks pass (incl. mutation-diff, e2e-mock, visual regression); PR review gate pending — CodeRabbit check "Review rate limited" |
CHANGES_REQUESTED (CodeRabbit: all 8 threads resolved) |
| #1299 |
native-ollama |
192059d0b |
+1626/−98 (7 files) |
✅ |
✅ all 20 checks pass |
REVIEW_REQUIRED (CodeRabbit: all 16 threads resolved) |
| #1300 |
vscode-lm |
bf82e1e8c (main 8d296deef merged in) |
+1312/−36 (2 files) vs 8d296deef (the diff the CI gate measures) |
✅ |
✅ all checks green after the main re-merge (run 34023728901: mutation-diff 2m45s — 82 changed executable lines, 85 Killed / 16 Ignored / 0S / 0NC; e2e-mock 9s via the repo's cached pass-marker mechanism, same as Zoo-Code-Org#1538; platform-unit-test windows+ubuntu ran for real); the pre-merge head 1c75366 had mutation-diff preflight fail: 474 mutants > 400 cap (CI runs on the synthetic merge commit while the PR base.sha is pinned at 0dbd5846f, so main-side src/ changes entered the diff; 473 changed lines) — resolved by the base re-sync |
CHANGES_REQUESTED — the 2 latest findings (post-init local-cancellation guard; private-member suppression) fixed in 1c75366, replied + both threads resolved; 14/14 threads resolved |
| #1301 |
openrouter, requesty, poe |
8ed1b40e0 |
+1913/−461 (10 files) |
✅ |
❌ mutation-diff preflight: 518 mutants > 400 cap (by design) |
closed as superseded by the split PRs below (supersede comment posted) |
| #1303 |
gemini, mistral, lite-llm |
1f4b56bb9 |
+1103/−120 (10 files) |
✅ |
✅ all 16 checks pass |
REVIEW_REQUIRED (CodeRabbit: all 7 threads resolved) |
| #1309 |
lm-studio, qwen-code (round 2) |
2f8aab0b6 |
+2669/−120 (13 files) vs 0dbd5846f |
⚠️ CONFLICTING (main moved; rebase needed) |
✅ last run all green pre-conflict (incl. mutation-diff + e2e-mock) |
CHANGES_REQUESTED — all 5 CodeRabbit threads resolved |
| #1311 |
openai, base-openai-compatible, zai, kimi-code (round 2) |
42bcdab06 (main merged) |
+1479/−110 (15 files) |
✅ |
✅ all test & mutation checks pass (incl. mutation-diff) |
REVIEW_REQUIRED (CodeRabbit: all 13 threads resolved, incl. the Critical OpenAiRequestConfig export finding) |
Purpose
Tracks every PR related to the abort-signal series — making Stop/cancel actually cancel the underlying HTTP request across all API providers. Root bug: upstream #404 "[BUG] Stop does not work on OpenAI Compatible API Provider".
Snapshot updated 2026-09-06 (7) against upstream
main@8d296deef(v3.82.0; 4 commits past0dbd5846f).Where upstream main stands today
Core plumbing is shipped on
main:abortSignalmetadata plumbing insrc/api/index.ts+src/core/task/Task.ts(+src/test-utils/api.ts)#901
CompletePromptOptions(merged 2026-07-18)#1008
RequestConfigBuilder(merged 2026-08-18)#1243 openai-codex completePrompt over the streaming transport (merged 2026-08-22)
#1292 bedrock (merged 2026-09-01)
✅ #1288 foundation helpers merged 2026-09-05 (01:03Z) —
src/api/providers/utils/abort-signal.ts(mergeAbortSignalAndTimeout,mergeAbortSignals,throwIfAborted,isRequestAborted,createAbortError,OpenAiRequestOptions) is now the canonical shared file onmain. The file-overlap hazard between branches is gone.Main moved
0dbd5846f→8d296deef(4 commits):057dfeebb([Chore] Bump GitHub Actions to node24 runtimes to fix Node 20 deprecation warnings Zoo-Code-Org/Zoo-Code#1534 — CI GitHub Actions to node24 runtimes),4140c2c83([Fix] Commits fail after users interrupt mutation tests Zoo-Code-Org/Zoo-Code#1525 — Stryker sandbox isolation: per-runSTRYKER_TEMP_DIR; mutation caps unchanged),9d43817fd([Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470 — per-scopeNativeToolCallParserstate + interrupted-subtask e2e fix),8d296deef([Fix] Task history disappears when user reopens a task Zoo-Code-Org/Zoo-Code#1319 — task-history reopen fix). The [Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470 commit touchedopenrouter.ts/openrouter.spec.tsand is the conflict source that feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 was rebased to resolve. The 4 commits also carrysrc/changes (openrouter, task-persistence, NativeToolCallParser) that the mutation-diff gate counts when a PR's base is still pinned at0dbd5846f— see feat(api): abort signal support for vscode-lm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1300 in "What was fixed".The June-era series (issues Zoo-Code-Org#615/Zoo-Code-Org#616/Zoo-Code-Org#617/Zoo-Code-Org#618, PRs Zoo-Code-Org#620–Zoo-Code-Org#732) is closed; its plumbing landed via the merges above. Issues #616 / #617 / #618 remain open and still describe the outstanding pass-through work.
Provider coverage vs main
OpenAiHandler)RouterProvidersubclass)Open PRs (upstream) — snapshot 2026-09-06 (7)
Diffs are the authoritative GitHub PR diff (head vs its base; main is now at
8d296deef). Zoo-Code-Org#1288 has merged; the rest of the series is open.throwIfAborted+ shared abort helpers + regression tests3b6343354→ merged ase12a42e7a1aa5fcd580488a39b7895660b543d92d0656(256 changed executable lines)895660b54)25f290cd9192059d0bbf82e1e8c(main8d296deefmerged in)8d296deef(the diff the CI gate measures)1c75366had mutation-diff preflight fail: 474 mutants > 400 cap (CI runs on the synthetic merge commit while the PRbase.shais pinned at0dbd5846f, so main-sidesrc/changes entered the diff; 473 changed lines) — resolved by the base re-sync1c75366, replied + both threads resolved; 14/14 threads resolved8ed1b40e01f4b56bb92f8aab0b60dbd5846f42bcdab06(main merged)OpenAiRequestConfigexport finding)Zoo-Code-Org#1301 split — status — the split resolves Zoo-Code-Org#1301's gate breaches (518 changed executable lines > 500 line cap; preflight 518 > 400-mutant cap):
9bd5d6f81(rebased onto8d296deef+ CodeRabbit fixes)completePromptebd5404dfRoo Code Subtasks — API-hung interrupted child resumes and returns to parent: Error: Timeout after 30s(timing flake, unrelated to this PR's diff); re-run blocked —gh run rerunrequires admin rights we don't have; awaiting maintainer re-run or a new commit; all 9 CodeRabbit threads resolvedcreateMessagef8c87ed3745044e82a3B2 is stacked on B1 (merge B1 first). Each split carries the Zoo-Code-Org#1301 CodeRabbit fixes for its files (wait-blocks spec hardening; buffered-chunks mid-stream abort guard + regression test). Zoo-Code-Org#1301 is closed as superseded.
Fork PRs #1 / #2 (June first attempts) are closed and superseded by the upstream series.
What was fixed since the 2026-09-05 (2) snapshot
895660b54: the external abort listener is now registered as a named callback retained in a per-request remover, and detached (same reference) when the request ends — on normal stream completion, on stream failure, on early consumer stop (via a new sharedwithFinallyCleanupasync-generator helper), and on message-creation failure (both anthropic switch branches + minimax bare create). 8 new spec tests assert same-reference removal (completion, creation failure with/without signal, cached + non-cached models) plus helper unit tests. The fix landed as a minimal diff (256 changed executable lines vs 518 on the earlier attempt, which breached the 500 line cap) so it passes the mutation-diff gate: local run 0 Survived / 0 NoCoverage. All 10 CodeRabbit threads resolved.8a7d58041: the 7 real survivors (6 StringLiteral + 1 ConditionalExpression) are killed by focused tests; the 3 latest CodeRabbit findings (disabled-timeout boundary, negative-timeoutMsboundary, provider stability) are fixed and replied; mutation-diff reports 86 Killed / 16 Ignored / 0 Survived / 0 NoCoverage / 0 Timeout; all 20 checks pass.completePrompt, basemain) and B2 feat(api): abort signal support for requesty (createMessage + kill tests) Zoo-Code-Org/Zoo-Code#1538 (requestycreateMessage, stacked on B1) — both pushed and fully green. C feat(api): abort signal support for poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1535 (poe) is open and fully green at5044e82a3: its 3 latest CodeRabbit findings (same-reference listener-removal assertion, real timeout-expiration test, stop-yielding-after-cancellation inpoe.ts) are fixed, replied, and all threads resolved. A (openrouter) is open at9bd5d6f81— rebased onto the new main8d296deefto resolve the [Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470 conflict, then the 4 CodeRabbit findings fixed (item 5 below); final local Stryker run green (0 Survived / 0 NoCoverage; 319 valid < 400 cap; 1 timeout 0.3%; 30 Ignored via 11 directive lines); all CI green, CodeRabbit APPROVED, PR review gate pass.5044e82a3(incl. mutation-diff); all 3 CodeRabbit findings fixed & replied, 0/3 threads open.8d296deef— the [Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470 conflict inopenrouter.ts/openrouter.spec.tsresolved by keeping both sides (my abort-signal bridging + the upstream per-scopeNativeToolCallParserstate with the newactiveToolCallIdscompletion tracking and its 2 new tests). The spec suite is now 85 tests (26 base + 59 new), all passing; tsc/eslint/prettier clean. Local mutation gate: 282 changed executable lines, 316 valid mutants (315 killed + 1 timeout, 0.3%), 0 Survived / 0 NoCoverage, 32 Ignored via 12 directive lines. Force-pushed as470c4538c, PR body updated. CodeRabbit then reviewed470c4538c(CHANGES_REQUESTED, 4 findings): abort the per-request controller increateMessage'sfinallyso an abandoned generator cancels the in-flight stream; use the canonicalcreateAbortErrormessage for the pre-abortedcompletePromptpath; extract the duplicatedsettlesWithinhelper into sharedsrc/test-utils/promise.ts; assert the registered abort listener by identity instead ofexpect.any(Function). All 4 fixed and pushed as9bd5d6f81(plus an abandonment-regression test; spec suite 26 → 86 tests). Final CI: all checks green (incl. mutation-diff, e2e-mock, codecov/patch), PR MERGEABLE, CodeRabbit re-reviewed and APPROVED, and the PR review gate is pass (now awaiting human maintainer/CODEOWNER approval).0dbd5846f); its last CI run was fully green before the conflict — rebasing onto8d296deefis the only remaining action for that PR.f8c87ed374— all 15 checks green (incl. mutation-diff, e2e-mock, codecov/patch).1c75366: (a) the counting-abort regression was rewritten through the publiccreateMessagepath —mockLanguageModelChat.countTokensis mocked to abort the caller's controller mid-count, so the new@ts-ignore(private-member spy) is gone; only the 3 pre-existing suppressions remain. (b)createMessagenow re-checkscancellationTokenSource.token.isCancellationRequestedimmediately afterawait this.getClient()and throws the canonicalAbortError(cancel + throw) before any token counting or host invocation when the request was superseded during client initialization; new gated-initialization regression (should abort a superseded request before counting tokens when superseded during client initialization) asserts the superseded request never callscountTokens. Full spec 80/80 green; local mutation gate on the diff: 85 valid / 85 killed / 16 ignored / 0 Survived / 0 NoCoverage. Both threads replied + resolved (14/14 resolved).bf82e1e8c): after pushing1c75366, the CI mutation-diff job failed at preflight with 474 mutants > 400 cap. Root cause: the workflow runs on the synthetic merge commit (github.sha) while the PRbase.shais still0dbd5846f, so the 4 main commits since (incl. [Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470'sopenrouter.ts+ [Fix] Task history disappears when user reopens a task Zoo-Code-Org/Zoo-Code#1319's task-persistencesrc/changes) entered the diff — 473 changed executable lines instead of 82. Fix: additive merge ofupstream/main(8d296deef) into the branch, which restores the gate's diff to the 2-file scope (+1312/−36 vs8d296deef; 82 changed executable lines). Local gate at the merge head: 85 valid / 85 killed / 16 ignored / 0S / 0NC. Pushed asbf82e1e8c; fresh CI run 34023728901 fully green (09:09Z) — mutation-diff pass (82 changed executable lines), e2e-mock pass (cached marker), all other checks pass.Roo Code Subtasks — API-hung interrupted child resumes and returns to parent: Error: Timeout after 30s(suite-timing flake, unrelated to this PR's requesty diff).gh run rerun 33983285538 --failedis not available to us ("Must have admin rights to Repository") — the flake persists until a maintainer re-runs the job or a new commit re-triggers CI.f8c87ed374(incl. mutation-diff, e2e-mock, codecov/patch); only theZoo Code / PR review gateis pending — "Required CI passed. Waiting for automated review of the latest commit." (CodeRabbit incremental review of the merge commit).Zoo Code / PR review gateis pending "Waiting for automated review of the latest commit" on all three — CodeRabbit's check shows "Review completed" on feat(api): abort signal support for openai-native and openai-compatible (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1291/feat(api): abort signal support for anthropic, anthropic-vertex, xai, minimax Zoo-Code-Org/Zoo-Code#1293 and "Review rate limited" on feat(api): abort signal support for opencode-go, unbound, vercel-ai-gateway, zoo-gateway Zoo-Code-Org/Zoo-Code#1295.What still needs fixing
8d296deef(now CONFLICTING; last CI run was fully green pre-conflict). feat(api): abort signal support for vscode-lm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1300 — all required CI green atbf82e1e8c(run 34023728901, 09:09Z): mutation-diff, e2e-mock (cached marker), platform-unit-test (windows+ubuntu), compile and the rest all pass; only theZoo Code / PR review gateis pending "Waiting for automated review of the latest commit."1c75366), feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303 (7), feat(api): abort-signal wiring for lm-studio and qwen-code (round 2) Zoo-Code-Org/Zoo-Code#1309 (5), feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 (13), feat(api): abort signal support for poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1535 (3), feat(api): abort signal support for requesty (completePrompt + shared helpers) Zoo-Code-Org/Zoo-Code#1537 (9), feat(api): abort signal support for requesty (createMessage + kill tests) Zoo-Code-Org/Zoo-Code#1538 (7).kenari.ts: of the sixRouterProvidersubclasses (kenari, litellm, nanogpt, opencode-go, vercel-ai-gateway, zoo-gateway), only kenari has no abort pass-through and no PR covering it (it is a recently added provider). Fix is the same small pattern as the other subclasses (passsignalinto the OpenAI SDKcreate()calls increateMessage/completePrompt+ abort normalization + focused spec). Options: (a) open a small follow-up PR after this series lands (recommended — single provider, well under the 400-line budget), or (b) mark kenari explicitly out of scope for the series.fake-ai.ts: test-only provider with no real HTTP traffic — nothing to cancel; confirmed intentionally excluded (no action needed).Suggested merge order (updated)
(Keep the landing order; the only change since (5) is that Zoo-Code-Org#1300's head now carries the
8d296deefmerge, so it no longer risks the Zoo-Code-Org#1470/Zoo-Code-Org#1319 conflict class):895660b54)8d296deeffirst)bf82e1e8c— all required CI pass incl. mutation-diff after the main re-sync; 2 latest findings fixed in1c75366+ threads resolved; review gate pending automated review)Related