Repository navigation
Tracking: abort-signal support for API providers (upstream series for #404) #42
Description
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-07 (21) against upstream main @ a3e31e14b (v3.82.0; main advanced 4c7474d42 → a3e31e14b via Zoo-Code-Org#1425 (provider-settings contact fix, webview-only) at 02:25Z — verified zero file overlap with all 13 series PRs, so no rebase is required and all 13 stay MERGEABLE). Since (20): the delayed schedule sweep finally fired at 05:22:15Z (22 minutes after its 05:00Z slot — the 04:00Z slot having run 70+ minutes late) and completed success at 05:28:55Z; its first action cleared Zoo-Code-Org#1545's stale "Wait for GitHub to finish calculating mergeability." gate text — Zoo-Code-Org#1545's gate now reads success: "Awaiting fresh human maintainer or CODEOWNER approval." @ 05:22:39Z (head 9bd5d6f81 unchanged; CodeRabbit APPROVED intact — still do not push). Zoo-Code-Org#1545 is back in the ready-to-approve group: 5 of 13 gates now at the finish-line text (Zoo-Code-Org#1290, Zoo-Code-Org#1295, Zoo-Code-Org#1303, Zoo-Code-Org#1535, Zoo-Code-Org#1545). The other 8 gates are unchanged ("Required CI passed. Waiting for automated review of the latest commit." — CodeRabbit re-reviews still queued; no new CR reviews landed since 02:23Z — the 05:21:03Z CR comment on Zoo-Code-Org#1311 is the org-member restriction reply to the nudge, not a walkthrough). Upstream main still a3e31e14b.
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→4c7474d42(5 commits total):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),4c7474d42([Fix] Reasoning models stop thinking after model selection Zoo-Code-Org/Zoo-Code#1349 — reasoning models stop thinking after model selection; touchessrc/api/providers/nanogpt.ts+ spec + webview ThinkingBudget files). The [Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470 commit is the conflict source for the qwen-code/lm-studio branch (feat(api): abort-signal wiring for lm-studio and qwen-code (round 2) Zoo-Code-Org/Zoo-Code#1309) and changed theNativeToolCallParserstatic API to a per-scope one, which required a small spec adaptation in feat(api): abort-signal wiring for lm-studio and qwen-code (round 2) Zoo-Code-Org/Zoo-Code#1309 (see "What was fixed"). All 10 PRs with stale bases now carry an additive merge of4c7474d42, so the mutation-diff gate diff is scoped to each PR's own files only (a stale base would otherwise count main-sidesrc/changes — e.g. [Fix] Reasoning models stop thinking after model selection Zoo-Code-Org/Zoo-Code#1349's nanogpt +32 lines — against the PR's budget). -
Main advanced
4c7474d42→a3e31e14bvia [Fix] Provider settings contact unselected model services Zoo-Code-Org/Zoo-Code#1425 (webview-only provider-settings fix) at 2026-09-07 02:25Z: touches 11webview-ui/files with zero overlap against all 13 series PRs (verified per-branch), so no re-sync is required — all 13 remain MERGEABLE (no conflict) and the mutation-diff budgets are unaffected ([Fix] Provider settings contact unselected model services Zoo-Code-Org/Zoo-Code#1425 adds nosrc/lines). The main-push reconcile briefly set feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's gate to "Wait for GitHub to finish calculating mergeability" while mergeability was recomputed; feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's head is unchanged (9bd5d6f81, CodeRabbit APPROVED intact) and the gate self-heals to "Awaiting fresh human maintainer or CODEOWNER approval" on the next reconcile (hourly cron / next main push).
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
| Provider | abortSignal on main | Covered by open PR |
|---|---|---|
| bedrock | ✅ (Zoo-Code-Org#1292) | — |
| openai-codex | ✅ mostly (Zoo-Code-Org#1243) | Zoo-Code-Org#1290 (remaining diff) |
| opencode-go | ✅ partial | Zoo-Code-Org#1295 |
| friendli, nanogpt | ✅ | — |
| openai-native, openai-compatible | ❌ | Zoo-Code-Org#1291 |
openai — transitively deepseek, mimo, moonshot, kimi-code (via OpenAiHandler) |
❌ | Zoo-Code-Org#1311 |
| base-openai-compatible-provider — transitively baseten, fireworks, sambanova, zai (inheritance) | ❌ | Zoo-Code-Org#1311 |
| anthropic, anthropic-vertex, xai, minimax | ❌ | Zoo-Code-Org#1293 |
| unbound, vercel-ai-gateway, zoo-gateway | ❌ | Zoo-Code-Org#1295 |
| native-ollama | ❌ | Zoo-Code-Org#1299 |
| vscode-lm | ❌ | Zoo-Code-Org#1300 |
| openrouter, requesty, poe | ❌ | Zoo-Code-Org#1301 → split: A Zoo-Code-Org#1545 (APPROVED); B = Zoo-Code-Org#1537 + Zoo-Code-Org#1538 (stacked); C Zoo-Code-Org#1535 |
| gemini (+ vertex via inheritance), mistral, lite-llm | ❌ | Zoo-Code-Org#1303 |
| lm-studio, qwen-code | ❌ | Zoo-Code-Org#1309 |
| RouterProvider subclasses: litellm (Zoo-Code-Org#1303), nanogpt (main), opencode-go/vercel-ai-gateway/zoo-gateway (Zoo-Code-Org#1295) | ❌ | covered |
kenari (the only uncovered RouterProvider subclass) |
❌ | no PR — see gap decision below |
| fake-ai (test-only provider, no real HTTP) | ❌ | intentionally excluded — nothing to cancel |
Open PRs (upstream) — snapshot 2026-09-07 (21)
Diffs are the authoritative GitHub PR diff (head vs its current base — now a3e31e14b for Zoo-Code-Org#1311 after its 04:22:08Z resync; 4c7474d42 for the 10 re-synced PRs). All 13 open series PRs are MERGEABLE (no conflicts). Required CI is green on every head (Zoo-Code-Org#1311's resynced head a3be5ec4f39 went green by ~04:25Z); each Zoo Code / PR review gate is either pass (gate-green, awaiting human approval — now including Zoo-Code-Org#1545, whose stale mergeability-pending text was cleared at 05:22:39Z by the delayed schedule sweep) or pending — "Required CI passed. Waiting for automated review of the latest commit." (the 8 PRs whose CodeRabbit re-reviews are still queued).
| PR | Scope | Head | +/− (files) | Mergeable | CI (2026-09-07 (21)) | Review |
|---|---|---|---|---|---|---|
| #1288 | foundation: throwIfAborted + shared abort helpers + regression tests |
merged as e12a42e7a |
— | ✅ MERGED (2026-09-05T01:03Z) | ✅ | — |
| #1290 | openai-codex | 1aa5fcd58 (unchanged — gate already pass) |
+653/−24 (5 files) vs 0dbd5846f |
✅ | ✅ all checks green | PR review gate PASS — "Awaiting fresh human maintainer or CODEOWNER approval" |
| #1291 | openai-native + openai-compatible | 1e22dfef1 (main 4c7474d42 merged in) |
+1424/−19 (6 files) vs 4c7474d42 (57 changed executable lines in the gate diff) |
✅ | ✅ required CI green | CHANGES_REQUESTED — all 11 CodeRabbit threads resolved (pre-merge head); awaiting re-review of the merge commit |
| #1293 | anthropic, anthropic-vertex, xai, minimax | fca60ad1b (main merged in) |
+1665/−198 (11 files) vs 4c7474d42 (256 changed executable lines in the gate diff) |
✅ | ✅ required CI green | CHANGES_REQUESTED — all 10 CodeRabbit threads resolved; awaiting re-review of the merge commit |
| #1295 | opencode-go, unbound, vercel-ai-gateway, zoo-gateway | 4457a00b7 (CR finding addressed; main merged in) |
+2625/−158 (13 files) vs 4c7474d42 (287 changed executable lines in the gate diff) |
✅ | ✅ all checks green (required CI on 4457a00b7 green at 00:00Z) |
PR review gate PASS — CodeRabbit re-reviewed 4457a00b7 and APPROVED at 00:08Z (the 19:22Z CHANGES_REQUESTED finding resolved); awaiting fresh human maintainer or CODEOWNER approval |
| #1299 | native-ollama | c38b3768b (main merged in) |
+1626/−98 (7 files) vs 4c7474d42 (114 changed executable lines in the gate diff) |
✅ | ✅ required CI green | DISMISSED — all 16 threads resolved (pre-merge head) |
| #1300 | vscode-lm | adab22979 (main 4c7474d42 merged in) |
+1312/−36 (2 files) vs 4c7474d42 (82 changed executable lines in the gate diff) |
✅ | ✅ required CI green | COMMENTED — all 14 CodeRabbit threads resolved |
| #1301 | openrouter, requesty, poe | — | +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 | 4e9a60236 (01:52Z re-review actionable addressed: 5 duplicated base-URL rejection tests collapsed into one it.each table; the CWE-319 literal 127.0.0.0/8 fix stands; main merged in) |
+1714/−120 (10 files) vs 4c7474d42 (160 changed executable lines in the gate diff) |
✅ | ✅ required CI green on 4e9a60236 (15/15 incl. mutation-diff + e2e-mock); local mutation gate: 247 valid / 227 killed / 1 timeout (0.4%) / 0 Survived / 0 NoCoverage |
✅ APPROVED 02:23Z on 4e9a60236 (no new findings — the 01:52Z table-driven actionable was the last open item); gate success — "Awaiting fresh human maintainer or CODEOWNER approval" |
| #1309 | lm-studio, qwen-code (round 2) | 1a0877ab2 (main 4c7474d42 merged in + spec adaptation) |
+2665/−128 (13 files) vs 4c7474d42 (193 changed executable lines in the gate diff) |
✅ was CONFLICTING — resolved | ✅ required CI green | CHANGES_REQUESTED — all 5 CodeRabbit threads resolved |
| #1311 | openai, base-openai-compatible, zai, kimi-code (round 2) | a3be5ec4f39 (main a3e31e14b merged in at 04:22:08Z to re-trigger CI and re-arm the review-active condition; parent 74e406efe carries the 3 pre-merge check warning fixes: errors.spec.ts coverage fix + direct handleOpenAIRequestError tests + Kimi retry timeoutMs assertions) |
+1566/−111 (17 files) vs a3e31e14b (148 changed executable lines in the gate diff — all new specs sit under __tests__/, excluded from the gate; the 11 Zoo-Code-Org#1425 webview files are now on both sides and out of the diff) |
✅ | ✅ all 6 workflows green on a3be5ec4f39 (runs created 04:22:12Z; complete by ~04:25Z) |
re-review of bccf293b5 (03:35Z walkthrough) ran pre-merge checks 4 passed / 3 warning — all 3 addressed (74e406efe code + body re-scope + index.ts zero-diff evidence comment); CodeRabbit auto-review paused on this branch and its chat commands are org-member-only (@coderabbitai review/resume rejected 04:14Z/04:18Z); the 04:22:08Z resync re-armed the gate's review-active condition (labels awaiting-coderabbit + coderabbit-review-active re-added by the reconcile workflow once CI went green); walkthrough of a3be5ec4f39 pending |
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):
| Split | Scope | PR | Head | Gate diff | CI (2026-09-07 (21)) |
|---|---|---|---|---|---|
| A | openrouter | #1545 (open) | 9bd5d6f81 (unchanged; CodeRabbit APPROVED intact — do not push) |
283 changed lines; 319 valid < 400 | ✅ PR review gate PASS — "Awaiting fresh human maintainer or CODEOWNER approval" @ 05:22:39Z (the 02:36:29Z main-push reconcile had set stale "Wait for GitHub to finish calculating mergeability." text; the delayed schedule sweep fired at 05:22:15Z — 22 min after its 05:00Z slot — and cleared it) |
| B1 | requesty completePrompt |
#1537 | 2d915cb15 (CR finding addressed; main 4c7474d42 merged in) |
39 changed executable lines | ✅ required CI green on the new head — the re-triggered e2e-mock replaces the flake (run 33983285538: 1 of 85 subtask e2e tests, API-hung interrupted child resumes and returns to parent, 30s suite-timing flake) |
| B2 | requesty createMessage |
#1538 | 48b232ae2 (main merged in) |
113 changed executable lines | ✅ required CI green |
| C | poe | #1535 | 5044e82a3 (unchanged — gate already pass) |
80 | ✅ PR review gate PASS — "Awaiting fresh human maintainer or CODEOWNER approval" |
B2 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-06 (7) snapshot
- Main moved
8d296deef→4c7474d42([Fix] Reasoning models stop thinking after model selection Zoo-Code-Org/Zoo-Code#1349 — reasoning/thinking-budget fix;src/api/providers/nanogpt.ts+32 executable lines + webview ThinkingBudget). Every stale-base PR's mutation-diff gate would have counted those main-side lines against its own budget, so all 10 affected branches were re-synced by an additive merge ofupstream/main(no rebases, no force-pushes of shared history). - feat(api): abort-signal wiring for lm-studio and qwen-code (round 2) Zoo-Code-Org/Zoo-Code#1309 — conflict resolved and pushed as
1a0877ab2(was CONFLICTING). The additive merge ofupstream/mainauto-merged everything exceptsrc/api/providers/qwen-code.ts: upstream [Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470 replaced the staticNativeToolCallParser.processFinishReasoncall with a request-localactiveToolCallIdsSet, while the branch head carried the abort wiring (throwIfAborted,requestController,settleOnAbort, abort-normalizing try/catch/finally). Resolution keeps both — the branch's abort path plus main's localactiveToolCallIdsend-emission. A follow-up commit adapts the branch'sqwen-code.spec.tsto [Fix] Tasks stall when interrupted subtasks resume Zoo-Code-Org/Zoo-Code#1470's per-scopeNativeToolCallParserAPI: the provider no longer reads the parser tracker fortool_call_end(it emits ends from its own local tracking, exactly like main), so the stale static-state feeding/clearing in the spec was removed and the provider-output assertions are unchanged. Local gates:check-types11/11 packages, vitest 92/92 (qwen-code + lm-studio + both native-tools specs), mutation manifest 193 changed executable lines (well under the 400 cap). PR is MERGEABLE again. - feat(api): abort signal support for requesty (completePrompt + shared helpers) Zoo-Code-Org/Zoo-Code#1537 — e2e-mock flake re-triggered by the base re-sync (pushed as
5e0d29b77). The failing required check on the previous head wase2e-mock: 1 of 85 subtask e2e tests —Roo Code Subtasks — API-hung interrupted child resumes and returns to parent: Error: Timeout after 30s(suite-timing flake, unrelated to the requesty diff).gh run rerun/gh workflow runneed upstream admin rights we don't have, so the additive main merge (new commit →pull_request: synchronizere-runs the full suite, including e2e-mock) is the re-trigger. Local gates after the merge:check-types11/11, vitest 58/58 (requesty + abort-signal specs), mutation manifest 39 changed executable lines. - 8 remaining stale-base PRs re-synced and pushed (all additive merges, zero conflicts; local gates green on every branch): feat(api): abort signal support for openai-native and openai-compatible (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1291
1e22dfef1(57 gate lines; vitest 171/171), feat(api): abort signal support for anthropic, anthropic-vertex, xai, minimax Zoo-Code-Org/Zoo-Code#1293fca60ad1b(256; 223/223), feat(api): abort signal support for opencode-go, unbound, vercel-ai-gateway, zoo-gateway Zoo-Code-Org/Zoo-Code#12959e3f67975(259; 242/242), feat(api): abort signal support for native-ollama (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1299c38b3768b(114; 115/115), feat(api): abort signal support for vscode-lm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1300adab22979(82; 80/80), feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303a0ed34ffc(165; 153/153), feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#131135b1d1095(148; 278/278), feat(api): abort signal support for requesty (createMessage + kill tests) Zoo-Code-Org/Zoo-Code#153848b232ae2(113; 75/75). - feat(api): abort signal support for openai-codex (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1290 / feat(api): abort signal support for poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1535 / feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 deliberately NOT pushed — their PR review gates are already
success: Awaiting fresh human maintainer or CODEOWNER approval; a new commit would reset those approvals. All three remain MERGEABLE against the moved main (no conflicting main-side files in their diffs). - feat(api): abort signal support for opencode-go, unbound, vercel-ai-gateway, zoo-gateway Zoo-Code-Org/Zoo-Code#1295 — CodeRabbit finding addressed at
4457a00b7: the 19:22Z CHANGES_REQUESTED review (1 actionable finding) asked for thecreateMessageflow to keep model resolution pending while the external signal aborts, with cancellation winning and normalizing both pending and post-abort resolution failures, plus deterministic async regression coverage. That behavior was already present in the head — the entry fast-fail guard (createAbortError("Opencode Go")on a pre-aborted signal), therejectOnAbortrace aroundresolveModel(), and theisRequestAbortednormalization in the catch — together with the existing pending-resolution regression test (parkgetModels, abort mid-resolution, assert the standardized AbortError settlement before release, and that no request is issued after release).4457a00b7additionally hardens the head for the mutation gate: 3 standalone Stryker directives on the now-unreachable pre-abort bridge branch (the entry fast-fail + the race make that branch dead code), and the detach tests pin the bridge's listener via the lastabortregistration —rejectOnAbortregisters its ownoncelistener on the same external signal during model resolution, so first-match lookups were asserting the race's bookkeeping instead of the bridge's (5 mutants survived before the fix). Local mutation gate at4457a00b7: 384 valid mutants (376 killed / 2 timeouts, 0.5%), 0 Survived / 0 NoCoverage. Required CI is green on the new head (review gate flipped to "Required CI passed" at 00:00Z), the CodeRabbit re-review of4457a00b7landed as APPROVED at 00:08Z, and the PR review gate is now PASS. - feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303 — all 3 CodeRabbit findings addressed (heads
018edc102→8505c9ff4→2f8b22881): (a) the gemini/lite-llm/mistral detach tests now capture the registeredabortlistener and assertremoveEventListenerreceived the exact reference (instead ofexpect.any(Function)); (b) the hostname lookalike test — the review suggesteda127.0.0.1, butnew URL()rejects it outright (its mixed digit-led/letter-led label rule), so a parseable stand-in that actually discriminates the anchor was added instead:foo127.bar(accepted bynew URL(), contains the "127." substring, not a loopback), while127a.bis retained for the unescaped-dot mutation direction. This proved theStryker disable next-line Regexdirective ingemini.ts(rationale: "the ^ anchor is unobservable") was wrong, so the directive was removed — the anchor mutant is now observable and killed by the new test; (c) the 00:32Z review of018edc102raised a Major CWE-319 (Sensitive Data Exposure) — the anchored 127. prefix check accepted public hostnames like127.example.testas loopback, which would have allowed cleartext (with the API key) to a public domain. Fixed at8505c9ff4by requiring a literal 127.0.0.0/8 (exactly 4 parts: literal127label + three decimal octets 0–255) with regression tests (reject127.example.test/10.0.0.1, allow127.255.255.255). The local mutation gate at8505c9ff4then surfaced 8 surviving mutants on the new check (theevery→somedirection was a real weakness; the rest were unobservable behind thenew URL()+ NaN invariants), so2f8b22881restructures the check: the octet predicate moves to a single-lineisOctet()helper (eliminating the method-chain mutants by elimination) and the remaining unobservableConditionalExpressionvariants are pinned by twoStryker disable next-linedirectives with true per-mutant rationales (each names the invariant that makes the variant unobservable and the tests that kill the rest), plus 3 new reject tests (127.0.0.anon-numeric last octet,127.0.a.bnon-numeric middle octet,127.0.0.1.afive-part host). Local mutation gate at2f8b22881: 160 changed executable lines, 247 valid mutants (227 killed / 1 timeout, 0.4%), 0 Survived / 0 NoCoverage. Pushed 01:34Z; required CI (incl. mutation-diff and e2e-mock) green. (d) the 01:52Z re-review of2f8b22881posted exactly one actionable comment (Trivial maintainability — “Collapse the duplicated base-URL rejection cases into a table”: the rejection tests repeated an identical body five times, only the hostname differed). Addressed in4e9a60236: the five rejection cases became oneINSECURE_BASE_URL_CASESas consttable + a single sharedit.eachbody, keeping each case name, hostname, and per-casenew URL()reasoning comment as table entries (the loopback success test untouched). Net −104 lines (+13/−117); the same five hostnames and the same assertions run, so the mutation-observability invariants are unchanged — local gates: prettier clean, eslint exit 0 (suppressions unchanged), vitest 59/59, tsc exit 0. - feat(api): abort signal support for requesty (completePrompt + shared helpers) Zoo-Code-Org/Zoo-Code#1537 — CodeRabbit finding addressed at
2d915cb15: the pre-abortedcompletePrompttest now also asserts that the existingfetchModelmodel-lookup mock is not called (retaining themockCreateassertion). Required CI is green on the new head (the re-triggered e2e-mock replaces the flake run). - Correction to (8): feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303's "all 16 checks pass" referred to a check list that predated the required
mutation-diffjob; the required CI at6c2d6bf45/1b205a38aincludes mutation-diff and it is green. - Upstream main advanced
4c7474d42→a3e31e14b(via [Fix] Provider settings contact unselected model services Zoo-Code-Org/Zoo-Code#1425 — "Provider settings contact unselected model services", 11webview-ui/files only, merged 02:25Z): per-branchdiff --name-only 4c7474d42..HEADagainst the [Fix] Provider settings contact unselected model services Zoo-Code-Org/Zoo-Code#1425 file list shows zero overlap for all 13 series PRs, so no re-sync/rebase is required (re-syncing would have reset 10 PRs' green CI + CodeRabbit re-reviews and would contradict the no-push rule on feat(api): abort signal support for openai-codex (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1290/feat(api): abort signal support for poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1535/feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545). The main-push reconcile briefly set feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's gate to "Wait for GitHub to finish calculating mergeability." while GitHub recomputed mergeability; feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's head is unchanged (9bd5d6f81, CodeRabbit APPROVED intact) and the gate self-heals to "Awaiting fresh human maintainer or CODEOWNER approval" on the next reconcile (hourly cron / next main push). No pushes of any kind. - feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 — patch coverage brought to near-100% and pushed as
bccf293b5(2026-09-07, in response to the tracking-issue owner's review: "the pre-merge check is missing and test coverage is not near to 100%"). Two gaps on head35b1d1095: (a)codecov/patchwas 97.89% — 2 uncovered lines insrc/test-utils/errors.ts(thecaptureErrornon-Error re-wrap branch and the resolving-operation contract assertion; the four provider specs only exercise theinstanceof Errorpath), and (b) the latest commit had no CodeRabbit walkthrough yet, so its pre-merge checks (Regression evidence/Trust and persistence invariantsper.coderabbit.yaml) had not been evaluated for it — a greencodecov/patchcheck does not prove near-100% patch coverage (it passed at 97.89%). Fix: newsrc/test-utils/__tests__/errors.spec.ts(3 tests: Error-rejection identity, non-Error-rejection message retention, resolving-contract rejection). Local gates at push: spec 3/3, v8 coverage oferrors.ts100% stmts/branch/lines,check-types11/11, eslint--prune-suppressionsclean, mutation gate unchanged (148 gate lines — the spec is under__tests__/and excluded). The push re-runs the full CI and the CodeRabbit re-review, which closes both gaps on the new head. - feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 — the 3 CodeRabbit pre-merge check warnings addressed and pushed as
74e406efe(2026-09-07, in response to the owner's review of thebccf293b5walkthrough). The re-review landed at 03:35Z with pre-merge checks 4 passed / 3 warning: (a) Linked Issues — the body'sCloses #616/#617/#618overclaimed (each requires providers beyond this PR's OpenAI-family scope: feat(api): abort signal bridging for openai-native, openai-codex, bedrock, native-ollama Zoo-Code-Org/Zoo-Code#617 needs openai-native/openai-codex/bedrock/native-ollama, feat(api): abort signal for vscode-lm, gemini, mistral (SDK-specific quirks) Zoo-Code-Org/Zoo-Code#618 needs vscode-lm/gemini/mistral, feat(api): abort signal pass-through for simple providers Zoo-Code-Org/Zoo-Code#616 needs every listed provider); fixed via API PATCH (no commit) — the body now keepsCloses #404(which the walkthrough itself confirmed satisfied) and lists feat(api): abort signal pass-through for simple providers Zoo-Code-Org/Zoo-Code#616/feat(api): abort signal bridging for openai-native, openai-codex, bedrock, native-ollama Zoo-Code-Org/Zoo-Code#617/feat(api): abort signal for vscode-lm, gemini, mistral (SDK-specific quirks) Zoo-Code-Org/Zoo-Code#618 as Part of with the sibling PRs that cover the remaining scope (feat(api): abort signal support for openai-codex (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1290/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/feat(api): abort signal support for opencode-go, unbound, vercel-ai-gateway, zoo-gateway Zoo-Code-Org/Zoo-Code#1295/feat(api): abort signal support for native-ollama (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1299/feat(api): abort signal support for vscode-lm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1300/feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303/feat(api): abort-signal wiring for lm-studio and qwen-code (round 2) Zoo-Code-Org/Zoo-Code#1309/feat(api): abort signal support for poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1535/feat(api): abort signal support for requesty (completePrompt + shared helpers) Zoo-Code-Org/Zoo-Code#1537/feat(api): abort signal support for requesty (createMessage + kill tests) Zoo-Code-Org/Zoo-Code#1538/feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545; bedrock already on main via feat(api): abort signal support for bedrock (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1292); (b) Out of Scope Changes — the flagged indentation-only comment change insrc/api/index.tsdoes not exist in the PR's net diff: the file is byte-identical at the original base8d296deef, the pre-resync head42bcdab06, the current base4c7474d42, and the head (verified bygit diffat all four refs), and the API-confirmed 17-file PR file list does not include it — a PR comment posted the evidence (the finding describes a stale pre-resync analysis state; nothing to remove or explain); (c) Regression Evidence — two focused coverage gaps fixed in code: a newhandleOpenAIRequestErrordescribe block insrc/api/providers/utils/__tests__/error-handler.spec.ts(5 direct tests: caller-signal abort + genericError→ freshAbortErrorwith the provider abort message +cause; SDKAPIUserAbortErrorand fetch-levelAbortErrorwith no signal; non-abort provider-prefix wrap; no-signal fallback) and the Kimi OAuth 401-retry test now passestimeoutMs: 30_000and asserts on both the initial and retry calls that the per-request config carriestimeout: 30_000and a merged (not raw)AbortSignalthat follows the external abort — a regression droppingtimeoutMson either call would now fail. Local gates at push: 53/53 (both touched specs), eslint--prune-suppressionsclean with theno-explicit-anycount forerror-handler.spec.tsunchanged (35 → 35; noas anyadded),check-types11/11 (pre-push), mutation gate unchanged (148 gate lines — both specs under__tests__/are excluded). - feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 — resynced to main; review-gate protocol documented (2026-09-07). The
label-pr-review-state.ymlreconcile workflow gates "automated review of the latest commit" on two conditions: required CI triggered and passing on the latest commit AND the PR carrying the workflow-managedcoderabbit-review-activelabel (recycled per head). feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 sat CI-green at74e406efeyet label-less (gate stuck at "Required CI passed. Waiting for automated review of the latest commit.") — the owner resynced the branch to main (merge commita3be5ec4f39, 04:22:08Z; zero diff overlap with [Fix] Provider settings contact unselected model services Zoo-Code-Org/Zoo-Code#1425's 11 webview files), which re-triggered CI (6/6 workflows green by ~04:25Z) and re-armed the label via thepull_request_target synchronize+workflow_runreconcile runs. Also confirmed on feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311: CodeRabbit's auto-review was paused ("Reviews paused" block) and the@coderabbitai review/@coderabbitai resumecommands are restricted to organization members (fork-owner attempts rejected 04:14:43Z / 04:18:50Z), so thea3be5ec4f39walkthrough may require a maintainer restart if CodeRabbit does not process the queued range. The workflow's gate internals (phase table,commit_id === head.shafreshness rule, event/token matrix) are recorded in thezoo-code-coding-workflowskill. - feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 — mergeability-pending heal: all fork-side levers exhausted (2026-09-07, ~04:50–05:16Z). The 02:36:29Z main-push reconcile left feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's gate at "Wait for GitHub to finish calculating mergeability." even though
mergeablehas since settledtrue(stateblocked— branch protection only), so the status text is stale and only a fresh reconcile can clear it. That sweep is the hourlyschedulerun, and the 04:00Z slot ran 70+ minutes late (thecreated=02:40Z..05:25Zruns window shows 0scheduleruns among 50 total — GitHub delays schedule events under platform load). Every fork-owner lever to force an earlier reconcile was tested and ruled out: (a) API reviewer remove/re-add to firereview_requested→ 404 (the fork owner has no base-repo write;requested_reviewersverified still exactly the 5 CODEOWNERS — nothing changed); (b) draft toggle viaPATCH /pulls/1545→ silent no-op (200,draftstaysfalse, no timeline event, no workflow run — theready_for_reviewevent never fires); (c)workflow_dispatch→ 403 (pull-only token); (d) labeling → no permission; (e) a humanissue_comment→ the workflow skips it (onlycoderabbitai[bot]comments are trusted). Conclusion: feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 self-heals via the delayed schedule run, the nextmainpush, or a maintainer action on the base repo — all external to this fork. No push required: head9bd5d6f81stays unchanged so CodeRabbit's APPROVED is preserved. Recorded in thezoo-code-coding-workflowskill (exhausted-levers matrix). - Maintainer-facing nudge comments posted (2026-09-07, 05:20:57Z / 05:20:59Z). As of 05:18Z the upstream
Label PR review stateschedule had missed both the 04:00Z and 05:00Z slots (0scheduleruns among 50 runs in the 03:18–05:18Z window), and CodeRabbit had produced no review on any series PR since 02:23Z (7 merge-commit re-reviews still queued). Two comments posted (both @ the 5 CODEOWNERS): feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 — the gate status is stale (mergeability settledtrue, required CI green, CodeRabbit APPROVED intact on9bd5d6f81); any label toggle /workflow_dispatchwithpull_request_number: 1545/mainpush re-reconciles immediately; maintainers were explicitly asked not to push a new commit to the branch (it would invalidate the APPROVED). feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 — thea3be5ec4f39walkthrough is the last missing step while CodeRabbit's auto-review is paused on the branch and its chat commands are org-member-only (the 04:14:43Z / 04:18:50Z rejections are on record); an org-member@coderabbitairestart would unblock it. All other series state unchanged. - feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 — mergeability-pending healed by the delayed schedule sweep (2026-09-07, 05:22:15Z → 05:28:55Z). The
schedulerun that the 04:00Z and 05:00Z slots had been delaying finally fired at 05:22:15Z (22 minutes after the 05:00Z slot) and completedsuccessat 05:28:55Z. Its first reconcile cleared feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's stale "Wait for GitHub to finish calculating mergeability." gate status (set 02:36:29Z by the [Fix] Provider settings contact unselected model services Zoo-Code-Org/Zoo-Code#1425 main-push reconcile): the gate now reads success — "Awaiting fresh human maintainer or CODEOWNER approval." @ 05:22:39Z. feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's head is unchanged (9bd5d6f81) and CodeRabbit's APPROVED (07:44:43Z) remains valid — still do not push. feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 is back in the ready-to-approve group; 5 of 13 gates now sit at the finish-line text. Post-sweep verification (05:29:23Z) confirms all 13 heads identical and no new CodeRabbit reviews since 02:23Z (the 05:21:03Z CR comment on feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 is the org-member restriction reply to the 05:20:59Z nudge, not a walkthrough).
What still needs fixing
- CodeRabbit re-reviews of the new heads are pending (CodeRabbit plan: up to 4 included reviews per hour, so re-reviews of freshly pushed heads can lag): the feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303 re-review already landed — APPROVED at 02:23Z on
4e9a60236with no new findings, so its gate now reads "Awaiting fresh human maintainer or CODEOWNER approval." Remaining: feat(api): abort signal support for requesty (completePrompt + shared helpers) Zoo-Code-Org/Zoo-Code#1537 (2d915cb15— finding addressed), plus the merge-commit re-reviews for 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 / feat(api): abort signal support for native-ollama (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1299 / feat(api): abort signal support for vscode-lm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1300 / feat(api): abort-signal wiring for lm-studio and qwen-code (round 2) Zoo-Code-Org/Zoo-Code#1309 / feat(api): abort signal support for requesty (createMessage + kill tests) Zoo-Code-Org/Zoo-Code#1538 and the feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 re-review ofa3be5ec4f39(its 3 pre-merge check warnings are addressed in the74e406efeparent; the 13 review threads remain resolved; CodeRabbit is auto-paused on this branch and its chat commands are org-member-only, so the walkthrough may require a maintainer restart — the 04:22:08Z resync re-armed the review-active condition and re-triggered CI). All 8 remaining pending re-review gates read "Required CI passed. Waiting for automated review of the latest commit." — feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545's gate separately was healed by the delayed schedule sweep at 05:22:39Z (see item 16), so only the 8 re-review-pending gates remain; no code action is required on our side (maintainer-facing nudge comments posted on feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 and feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 at 05:20:57Z / 05:20:59Z — see item 15). - Fresh human maintainer / CODEOWNER approvals — feat(api): abort signal support for openai-codex (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1290, feat(api): abort signal support for opencode-go, unbound, vercel-ai-gateway, zoo-gateway Zoo-Code-Org/Zoo-Code#1295, feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303, feat(api): abort signal support for poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1535, feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 are gate-pass and merge-ready (5 of 13); the other 8 follow once their re-reviews land.
- Coverage-gap decision —
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)
(No code-order change — all 13 are conflict-free against 4c7474d42 and against the current a3e31e14b (verified per-branch after the Zoo-Code-Org#1425 move). Zoo-Code-Org#1545 is back in the ready-to-approve group (gate healed 05:22:39Z) — ready-to-approve first (Zoo-Code-Org#1290, Zoo-Code-Org#1295, Zoo-Code-Org#1303, Zoo-Code-Org#1535, Zoo-Code-Org#1545), then in landing order once the re-reviews land; B2 stays stacked on B1:)
- feat(api): abort signal support for openrouter (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1545 (✅ gate PASS @ 05:22:39Z — healed by the delayed schedule sweep; CodeRabbit APPROVED on
9bd5d6f81intact — do not push) - feat(api): abort signal support for poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1535 (gate PASS — maintainer approval)
- feat(api): abort signal support for openai-codex (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1290 (gate PASS — maintainer approval)
- feat(api): abort signal support for opencode-go, unbound, vercel-ai-gateway, zoo-gateway Zoo-Code-Org/Zoo-Code#1295 (gate PASS — CodeRabbit APPROVED
4457a00b7at 00:08Z; maintainer approval) - feat(api): abort signal support for openai-native and openai-compatible (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1291 (required CI green; awaiting re-review)
- feat(api): abort signal support for anthropic, anthropic-vertex, xai, minimax Zoo-Code-Org/Zoo-Code#1293 (required CI green; awaiting re-review)
- feat(api): abort signal support for native-ollama (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1299 (required CI green)
- feat(api): abort signal support for gemini, mistral, lite-llm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1303 (✅ gate success on
4e9a60236— CodeRabbit APPROVED 02:23Z with no new findings; ready for maintainer approval) - feat(api): abort signal support for openai, openai-compatible base, zai, kimi-code (round 2) Zoo-Code-Org/Zoo-Code#1311 (required CI green on
a3be5ec4f39; the 3 pre-merge check warnings addressed; walkthrough of the resynced head pending) - feat(api): abort-signal wiring for lm-studio and qwen-code (round 2) Zoo-Code-Org/Zoo-Code#1309 (required CI green; conflict resolved in this snapshot)
- feat(api): abort signal support for vscode-lm (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1300 (required CI green at
adab22979) - feat(api): abort signal support for openrouter, requesty, poe (completePrompt + createMessage) Zoo-Code-Org/Zoo-Code#1301 split: B1 feat(api): abort signal support for requesty (completePrompt + shared helpers) Zoo-Code-Org/Zoo-Code#1537 (CR finding addressed at
2d915cb15) → B2 feat(api): abort signal support for requesty (createMessage + kill tests) Zoo-Code-Org/Zoo-Code#1538 (required CI green at48b232ae2)
Related
- Root issue: upstream [BUG] Stop does not work on OpenAI Compatible API Provider Zoo-Code-Org/Zoo-Code#404 (open)
- Series issues (open): feat(api): abort signal pass-through for simple providers Zoo-Code-Org/Zoo-Code#616 simple providers, feat(api): abort signal bridging for openai-native, openai-codex, bedrock, native-ollama Zoo-Code-Org/Zoo-Code#617 bridging (openai-native/openai-codex/bedrock/native-ollama), feat(api): abort signal for vscode-lm, gemini, mistral (SDK-specific quirks) Zoo-Code-Org/Zoo-Code#618 vscode-lm/gemini/mistral
- Plumbing issues (closed): feat(api): abort signal core plumbing — interface, Task.ts, single-completion-handler Zoo-Code-Org/Zoo-Code#615, feat(api): introduce RequestConfigBuilder for SDK-agnostic abort signal support Zoo-Code-Org/Zoo-Code#1006/feat(api): introduce RequestConfigBuilder for SDK-agnostic abort signal support Zoo-Code-Org/Zoo-Code#1007 (RequestConfigBuilder), Extract shared provider abort helpers after #1288 Zoo-Code-Org/Zoo-Code#1315 "Extract shared provider abort helpers after feat(api): add throwIfAborted helper and completePrompt options regression tests Zoo-Code-Org/Zoo-Code#1288"
- Loosely related (terminal abort, separate work): fix(terminal): terminate running process when task is cancelled (#245) Zoo-Code-Org/Zoo-Code#261, fix(terminal): kill entire process group on Stop so child commands are not orphaned Zoo-Code-Org/Zoo-Code#525, fix(terminal): tell model when command was aborted by the user Zoo-Code-Org/Zoo-Code#880
Activity