Skip to content

Conversation

noobgramming
Copy link

Description

Fixes IBM WatsonX ChatWatsonx integration to properly handle AbortSignal by passing the signal parameter through to the underlying IBM SDK methods, enabling true server-side request cancellation.

Issue

Fixes a bug where abort signals were accepted but not actually passed to the IBM SDK, causing:

  • Requests to continue executing on WatsonX servers after abort
  • Users being charged for tokens generated after abort call
  • Delayed cancellation (waiting for completion instead of immediate termination)

This is the same bug pattern as:

  • #7257 - Qianfan chat models not handling abort signal (labeled auto:bug)
  • #5001 - OpenAI abort controller not working (labeled auto:bug)

Both issues involved signals being passed to AsyncCaller but not to the underlying provider SDK.

Changes

Added signal: options?.signal to 4 SDK method calls:

Non-streaming methods (_generate):

// textChat() - line 680
this.service.textChat({
  ...params,
  ...scopeId,
  messages: watsonxMessages,
  signal: options?.signal,  // Added
}, watsonxCallbacks)

// deploymentsTextChat() - line 671
this.service.deploymentsTextChat({
  ...scopeId,
  messages: watsonxMessages,
  signal: options?.signal,  // Added
}, watsonxCallbacks)

Streaming methods (_streamResponseChunks):

this.service.textChatStream({
  ...params,
  ...scopeId,
  messages: watsonxMessages,
  returnObject: true,
  signal: options?.signal,  // Added
}, watsonxCallbacks)

this.service.deploymentsTextChatStream({
  ...scopeId,
  messages: watsonxMessages,
  returnObject: true,
  signal: options?.signal,  // Added
}, watsonxCallbacks)

Also removed ineffective manual abort checks that happened after requests completed.

Technical Details

The IBM WatsonX SDK already supports AbortSignal via the DefaultParams interface:

// From @ibm-cloud/watsonx-ai
interface DefaultParams {
  signal?: AbortSignal;
  headers?: OutgoingHttpHeaders;
}

export interface TextChatParams extends DefaultParams {
  modelId: string;
  messages: TextChatMessages[];
  // signal inherited from DefaultParams ✅
}

Signal flow:

  1. LangChain accepts signal in options.signal
  2. Now passed to IBM SDK methods (this PR)
  3. IBM SDK passes to axios config
  4. Axios aborts HTTP request on signal

Testing

Added 4 unit tests to verify signal is passed to all SDK methods:

  1. textChat() with projectId
  2. deploymentsTextChat() with idOrName
  3. textChatStream() with projectId
  4. deploymentsTextChatStream() with idOrName

Documentation Reference

Per https://js.langchain.com/docs/how_to/cancel_execution/:

"Individual integrations like chat models or retrievers may have missing or differing implementations for aborting execution."

This PR fixes the "missing implementation" for IBM WatsonX by using the SDK's signal support.

…llation

The IBM WatsonX SDK natively supports AbortSignal via TextChatParams.signal
(inherited from DefaultParams interface), but the LangChain integration was
not passing options.signal to textChat() and textChatStream() methods.

This prevented true server-side request cancellation - abort signals only
threw errors AFTER requests completed, meaning users still paid for tokens
generated on the server.

Changes:
- Pass options.signal to textChat() in _generate() method
- Pass options.signal to textChatStream() in _streamResponseChunks() method
- Remove redundant manual abort checks (SDK handles this natively)

Fixes similar issue as langchain-ai#7257 (Qianfan) and langchain-ai#5001 (OpenAI).

Ref: https://js.langchain.com/docs/how_to/cancel_execution/
Copy link

changeset-bot bot commented Oct 17, 2025

⚠️ No Changeset found

Latest commit: 2218cff

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@FilipZmijewski
Copy link
Contributor

This is a valid PR for our implementation, we have previously added the abort on langchain side since we did not have aborting in our SDK, now it is supported and the above approach is correct. Thank you @noobgramming
Probably once langchain is finished with the big v1 release they will have a look at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants