Skip to content

Conversation

@dlarocque
Copy link
Contributor

@dlarocque dlarocque commented Apr 2, 2025

Add an AbortSignal to a new SingleRequestOptions that can be passed to all methods that make requests to the backend, allowing them to be aborted.

Fixes #8859

API Proposal: go/vinf-abort-request-api (internal)

@changeset-bot
Copy link

changeset-bot bot commented Apr 2, 2025

🦋 Changeset detected

Latest commit: 3a63e57

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
firebase Minor
@firebase/ai Minor

Not sure what this means? Click here to learn what changesets are.

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

@github-actions
Copy link
Contributor

github-actions bot commented Apr 2, 2025

Changeset File Check ✅

  • No modified packages are missing from the changeset file.
  • No changeset formatting errors detected.

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Apr 2, 2025

Size Report 1

Affected Products

  • @firebase/ai

    TypeBase (f5fc6bf)Merge (1d22fba)Diff
    browser67.4 kB68.7 kB+1.32 kB (+2.0%)
    main71.7 kB73.0 kB+1.32 kB (+1.8%)
    module67.4 kB68.7 kB+1.32 kB (+2.0%)
  • firebase

    TypeBase (f5fc6bf)Merge (1d22fba)Diff
    firebase-ai.js52.8 kB53.4 kB+564 B (+1.1%)

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/CiHMn2oSYR.html

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Apr 2, 2025

Size Analysis Report 1

Affected Products

  • @firebase/ai

    • ChatSession

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size22.3 kB22.7 kB+431 B (+1.9%)
      size-with-ext-deps40.0 kB40.5 kB+434 B (+1.1%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      26 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      defaultExpectedInputs
      errorsCausingFallback
      logger
      name
      responseLineRE
      version

      28 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      TIMEOUT_EXPIRED_MESSAGE
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      defaultExpectedInputs
      errorsCausingFallback
      logger
      name
      responseLineRE
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • GenerativeModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size26.0 kB26.5 kB+493 B (+1.9%)
      size-with-ext-deps43.8 kB44.3 kB+496 B (+1.1%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      26 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      defaultExpectedInputs
      errorsCausingFallback
      logger
      name
      responseLineRE
      version

      28 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      TIMEOUT_EXPIRED_MESSAGE
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      defaultExpectedInputs
      errorsCausingFallback
      logger
      name
      responseLineRE
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • ImagenModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size13.4 kB13.8 kB+386 B (+2.9%)
      size-with-ext-deps31.1 kB31.5 kB+393 B (+1.3%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      15 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      defaultExpectedInputs
      logger
      name
      version

      17 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      TIMEOUT_EXPIRED_MESSAGE
      defaultExpectedInputs
      logger
      name
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • TemplateGenerativeModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size18.1 kB18.5 kB+390 B (+2.2%)
      size-with-ext-deps35.9 kB36.3 kB+393 B (+1.1%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      20 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      badFinishReasons
      defaultExpectedInputs
      logger
      name
      responseLineRE
      version

      22 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      TIMEOUT_EXPIRED_MESSAGE
      badFinishReasons
      defaultExpectedInputs
      logger
      name
      responseLineRE
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • TemplateImagenModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size12.1 kB12.5 kB+368 B (+3.0%)
      size-with-ext-deps29.8 kB30.2 kB+375 B (+1.3%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      15 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      defaultExpectedInputs
      logger
      name
      version

      17 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      TIMEOUT_EXPIRED_MESSAGE
      defaultExpectedInputs
      logger
      name
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • getGenerativeModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size26.4 kB26.9 kB+493 B (+1.9%)
      size-with-ext-deps44.2 kB44.7 kB+496 B (+1.1%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      27 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_HYBRID_IN_CLOUD_MODEL
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      defaultExpectedInputs
      errorsCausingFallback
      logger
      name
      responseLineRE
      version

      29 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_HYBRID_IN_CLOUD_MODEL
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      TIMEOUT_EXPIRED_MESSAGE
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      defaultExpectedInputs
      errorsCausingFallback
      logger
      name
      responseLineRE
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • getImagenModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size13.5 kB13.9 kB+386 B (+2.9%)
      size-with-ext-deps31.2 kB31.6 kB+393 B (+1.3%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      15 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      defaultExpectedInputs
      logger
      name
      version

      17 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      TIMEOUT_EXPIRED_MESSAGE
      defaultExpectedInputs
      logger
      name
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • getTemplateGenerativeModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size18.2 kB18.5 kB+390 B (+2.1%)
      size-with-ext-deps35.9 kB36.3 kB+393 B (+1.1%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      20 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      badFinishReasons
      defaultExpectedInputs
      logger
      name
      responseLineRE
      version

      22 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      InferenceMode
      InferenceSource
      LANGUAGE_TAG
      PACKAGE_VERSION
      TIMEOUT_EXPIRED_MESSAGE
      badFinishReasons
      defaultExpectedInputs
      logger
      name
      responseLineRE
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

    • getTemplateImagenModel

      Size

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      size12.1 kB12.5 kB+368 B (+3.0%)
      size-with-ext-deps29.8 kB30.2 kB+375 B (+1.3%)

      Dependency

      TypeBase (f5fc6bf)Merge (1d22fba)Diff
      variables

      15 dependencies

      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      defaultExpectedInputs
      logger
      name
      version

      17 dependencies

      ABORT_ERROR_NAME
      AIErrorCode
      AI_TYPE
      Availability
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      InferenceMode
      LANGUAGE_TAG
      PACKAGE_VERSION
      TIMEOUT_EXPIRED_MESSAGE
      defaultExpectedInputs
      logger
      name
      version

      + ABORT_ERROR_NAME
      + TIMEOUT_EXPIRED_MESSAGE

Test Logs

  1. https://storage.googleapis.com/firebase-sdk-metric-reports/cVETCJHa2G.html

@dlarocque dlarocque marked this pull request as ready for review May 12, 2025 17:05
@dlarocque dlarocque requested review from a team as code owners May 12, 2025 17:05
Copy link
Contributor

@DellaBitta DellaBitta left a comment

Choose a reason for hiding this comment

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

Looks good, but won't approve until council review.

If provided, calling `abort()` on the corresponding `AbortController` will attempt to cancel the underlying HTTP request. An `AbortError` will be thrown if cancellation is successful.
Note that this will not cancel the request in the backend, so billing will still be applied despite cancellation.
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@hsubox76 hsubox76 left a comment

Choose a reason for hiding this comment

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

Approved, pending merge of #9011 where you'll have to update the changeset and regenerate docs and the api.md.

@dlarocque dlarocque requested a review from rachelsaunders May 22, 2025 15:11
@dlarocque
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for AbortSignal to allow cancellation of AI requests, which is a valuable feature. The implementation correctly updates GenerativeModel, ImagenModel, and ChatSession and includes a comprehensive set of tests for the new cancellation logic. The API and documentation changes are also well-executed.

However, I've identified a few critical issues. The new singleRequestOptions are not implemented for TemplateGenerativeModel and TemplateImagenModel, with TODO comments left in the code. I also found a potential memory leak in the request handling logic and some issues with test structure, such as duplication and improper nesting. I've provided specific comments with suggestions to address these points. Once these are resolved, the pull request will be in excellent shape.

@dlarocque
Copy link
Contributor Author

Re-requesting review since changes were made.

Copy link
Contributor

@hsubox76 hsubox76 left a comment

Choose a reason for hiding this comment

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

Weren't we going to have the iterator throw too if there was an error on that iteration? Does this do that? Did it already do that?

@dlarocque
Copy link
Contributor Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for AbortSignal across various methods, allowing for cancellation of in-flight requests. The implementation is robust, using AbortSignal.any() to gracefully handle both user-initiated aborts and internal timeouts. The changes are well-tested with new integration and unit tests. I've left a few comments on potential improvements, mainly around ensuring atomicity of history updates in ChatSession to prevent inconsistent states, and a couple of minor cleanup items in generated documentation files. Overall, this is a great addition to the SDK.

Comment on lines 1341 to 1342
generateContent(templateId: string, templateVariables: object, // anything!
singleRequestOptions?: SingleRequestOptions): Promise<GenerateContentResult>;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

There appears to be a leftover comment // anything! in the generateContent method signature. This should be removed for clarity in the public API documentation.

Suggested change
generateContent(templateId: string, templateVariables: object, // anything!
singleRequestOptions?: SingleRequestOptions): Promise<GenerateContentResult>;
generateContent(templateId: string, templateVariables: object, singleRequestOptions?: SingleRequestOptions): Promise<GenerateContentResult>;

Comment on lines 88 to 89
generateContent(templateId: string, templateVariables: object, // anything!
singleRequestOptions?: SingleRequestOptions): Promise<GenerateContentResult>;
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the API report file, there's a leftover comment // anything! in the generateContent method signature in this documentation file. It should be removed.

Suggested change
generateContent(templateId: string, templateVariables: object, // anything!
singleRequestOptions?: SingleRequestOptions): Promise<GenerateContentResult>;
generateContent(templateId: string, templateVariables: object, singleRequestOptions?: SingleRequestOptions): Promise<GenerateContentResult>;

Copy link
Contributor

@hsubox76 hsubox76 left a comment

Choose a reason for hiding this comment

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

LG, thanks for adding the comments and the tests.


// Simulate a response that is technically valid enough to resolve aggregation,
// but malformed in a way that causes the history update logic to throw.
// Passing `null` as a candidate causes `{ ...response.candidates[0].content }` to throw.
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a good test and we should keep it, but surfaces that we should probably fix the logic to protect against response.candidates[0].content throwing. Can you add a todo for me? In chat-session.ts line 188.

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.

FR: Support AbortSignal in generateContent() for firebase/vertexai

5 participants