Skip to content

feat: add abort signal core plumbing#674

Merged
edelauna merged 2 commits into
Zoo-Code-Org:mainfrom
easonLiangWorldedtech:feat/abort-signal-core-pr
Jun 23, 2026
Merged

feat: add abort signal core plumbing#674
edelauna merged 2 commits into
Zoo-Code-Org:mainfrom
easonLiangWorldedtech:feat/abort-signal-core-pr

Conversation

@easonLiangWorldedtech

@easonLiangWorldedtech easonLiangWorldedtech commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Core plumbing to pass AbortSignal through the API layer so HTTP requests can be cancelled mid-stream when the user clicks stop. Prevents wasted API tokens/compute on the provider side.

Changes

  • src/api/index.ts: Add abortSignal?: AbortSignal to ApiHandlerCreateMessageMetadata interface
  • src/core/task/Task.ts: Wire Task's AbortController.signal into createMessage metadata
  • src/core/task/tests/Task.spec.ts: Tests verifying signal is passed and matches currentRequestAbortController

Related

Closes #434

Summary by CodeRabbit

  • New Features
    • Added support for cancelling in-flight streaming responses by forwarding the active abort signal to the underlying streaming request.
  • Bug Fixes
    • Improved consistency of abort-signal propagation across context condensation and automatic context-management so cancellation is respected in all flows.
  • Tests
    • Expanded coverage to verify abort-signal forwarding during context condensation, request attempts, and forced context-management, including rejection when cancellation occurs mid-stream.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an optional abortSignal?: AbortSignal field to ApiHandlerCreateMessageMetadata with JSDoc documenting pass-through to the AI SDK. Per-request AbortController signals are propagated through attemptApiRequest(), condenseContext(), handleContextWindowExceededError(), and context-management flows. Comprehensive tests validate signal presence, instance type, reference equality, and propagation across all paths.

Changes

AbortSignal propagation to API metadata and task execution

Layer / File(s) Summary
AbortSignal contract definition
src/api/index.ts
Adds optional abortSignal?: AbortSignal property with JSDoc to ApiHandlerCreateMessageMetadata, documenting pass-through to AI SDK streaming for mid-stream HTTP cancellation.
Core Task abortSignal wiring in API request
src/core/task/Task.ts
In attemptApiRequest(), creates currentRequestAbortController, extracts its signal, and assigns it to metadata.abortSignal before calling api.createMessage(), enabling the streaming request to observe cancellation.
AbortSignal propagation through context-management flows
src/core/task/Task.ts
Propagates abortSignal from the current request's AbortController into metadata used by condenseContext(), handleContextWindowExceededError(), and manageContext() calls, ensuring context-management operations respect cancellation.
AbortSignal propagation test coverage
src/core/task/__tests__/Task.spec.ts
Comprehensive test suite with new describe("abortSignal") block verifying signal presence, AbortSignal instance type, and reference equality in condenseContext() and attemptApiRequest() paths; tests cancelCurrentRequest() behavior; validates signal propagation during forced context-management with and without an active request; and confirms streaming cancellation between chunks rejects with "Request cancelled by user".

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Poem

🐇 A signal travels through every stream,
"Stop, abort!" cries the rabbit's dream.
Through metadata's flight,
Context flows right,
No wasteful API calls intervene! ✂️

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding foundational abort signal infrastructure to enable request cancellation.
Description check ✅ Passed The description covers the objective, changes across three files, and issue reference, but lacks explicit test procedure details and missing pre-submission checklist items.
Linked Issues check ✅ Passed The PR successfully implements the foundational core plumbing required by #434: adding abortSignal to API metadata interface, wiring signal propagation through Task execution chain, and including comprehensive test coverage for abort signal flow.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing core abort signal infrastructure as defined in #434, with no unrelated modifications to other systems or features.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.71429% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/core/task/Task.ts 85.71% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@edelauna edelauna left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this. Would like to see an additional test case, and also could you update Condensing/context-management API calls, three ApiHandlerCreateMessageMetadata construction sites in Task.ts — at lines 1555, 3763, and 3979 — do not set abortSignal. These are used for long-running condensing and context-management API calls that are also cancellable, but the "core plumbing" claim is incomplete if these paths are excluded.

Suggested fix: Pass the active currentRequestAbortController?.signal to these metadata objects, or document explicitly that condensing calls are intentionally out of scope with a comment at each site.

Comment thread src/core/task/Task.ts Outdated
// Create an AbortController to allow cancelling the request mid-stream
this.currentRequestAbortController = new AbortController()
const abortSignal = this.currentRequestAbortController.signal
metadata.abortSignal = abortSignal

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Promise.race between firstChunkPromise and abortPromise (lines 4187–4198) is the core behaviour this adds — if the signal fires before the first chunk, attemptApiRequest should throw "Request cancelled by user". Is that path covered by a test? The new tests verify the signal is passed correctly, but I don't see one that actually calls abort() during iterator.next() and asserts the error.

Comment thread src/core/task/Task.ts Outdated
// Create an AbortController to allow cancelling the request mid-stream
this.currentRequestAbortController = new AbortController()
const abortSignal = this.currentRequestAbortController.signal
metadata.abortSignal = abortSignal

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: abortSignal is grafted onto metadata after the object literal closes (line 4144), while every other field is set inline. Worth pulling the AbortController creation up above the literal and including abortSignal there?

@github-actions github-actions Bot added the awaiting-author PR is waiting for the author to address requested changes label Jun 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/task/__tests__/Task.spec.ts`:
- Around line 1957-2002: The test for AbortController signal propagation in the
handleContextWindowExceededError method bypasses the production request
lifecycle by pre-seeding the currentRequestAbortController and directly invoking
handleContextWindowExceededError(). Instead, refactor this test to drive the
assertion through the attemptApiRequest() method by setting up conditions that
force a context-window failure, which will validate that the AbortSignal is
properly propagated through the real error/retry path where controller timing is
critical to the production behavior.

In `@src/core/task/Task.ts`:
- Around line 3771-3775: The abort signal propagation issue occurs because
this.currentRequestAbortController is created too late in the
attemptApiRequest() method (at line 4177) relative to when it's accessed at
lines 3771 and 3992 for context-management calls. Move the creation of
this.currentRequestAbortController to the beginning of the attemptApiRequest()
method, before any code that references it for the abortSignal metadata field.
This ensures the abort controller is available throughout the entire request
attempt lifecycle, including during context-window handler execution, allowing
stop/cancel operations to reliably terminate HTTP requests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: aabfd282-d122-4ea7-aa26-8db27f118753

📥 Commits

Reviewing files that changed from the base of the PR and between 60a0dcf and 7e4c53b.

📒 Files selected for processing (2)
  • src/core/task/Task.ts
  • src/core/task/__tests__/Task.spec.ts

Comment thread src/core/task/__tests__/Task.spec.ts Outdated
Comment thread src/core/task/Task.ts
@easonLiangWorldedtech easonLiangWorldedtech force-pushed the feat/abort-signal-core-pr branch 4 times, most recently from 3b56639 to 9d02617 Compare June 22, 2026 15:55
@easonLiangWorldedtech easonLiangWorldedtech force-pushed the feat/abort-signal-core-pr branch from 9d02617 to 11cc3ad Compare June 22, 2026 16:13
@easonLiangWorldedtech easonLiangWorldedtech force-pushed the feat/abort-signal-core-pr branch from 11cc3ad to b26ec5d Compare June 22, 2026 16:20
@github-actions github-actions Bot added awaiting-review PR changes are ready and waiting for maintainer re-review and removed awaiting-author PR is waiting for the author to address requested changes labels Jun 22, 2026

@edelauna edelauna left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you for breaking this up

@edelauna edelauna added this pull request to the merge queue Jun 23, 2026
Merged via the queue into Zoo-Code-Org:main with commit 28c54a7 Jun 23, 2026
10 checks passed
@easonLiangWorldedtech easonLiangWorldedtech deleted the feat/abort-signal-core-pr branch June 23, 2026 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants