Skip to content

Live API v1 #9205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: dl/live
Choose a base branch
from
Open

Live API v1 #9205

wants to merge 9 commits into from

Conversation

dlarocque
Copy link
Contributor

@dlarocque dlarocque commented Aug 12, 2025

Adds support for the Public Preview Live API, with foundational methods to reach parity with Flutter, Android, and Unity.

API

  • LiveGenerativeModel class establishes a WebSocket connection and configures a LiveSession
  • LiveSession includes foundational methods for live content generation: receive(), send(), sendMediaChunks(), sendMediaStream()
  • Adds id property to FunctionCall and FunctionResponse, which is used by the Google AI backend to map function responses to calls. This property won't be in Vertex AI responses.

Testing

  • Unit tests: Uses a mock WebSocketHandler to simulate server messages.
  • Integration tests: Run against the live backend for both Vertex AI and Google AI. The function calling tests are very unreliable, so they will be skipped.

Copy link

changeset-bot bot commented Aug 12, 2025

⚠️ No Changeset found

Latest commit: 3f1a4be

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

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 12, 2025

Size Report 1

Affected Products

  • @firebase/ai

    TypeBase (2e03df7)Merge (c3f5a96)Diff
    browser39.4 kB47.2 kB+7.88 kB (+20.0%)
    main42.4 kB50.6 kB+8.25 kB (+19.5%)
    module39.4 kB47.2 kB+7.88 kB (+20.0%)
  • firebase

    TypeBase (2e03df7)Merge (c3f5a96)Diff
    firebase-ai.js31.1 kB37.3 kB+6.22 kB (+20.0%)

Test Logs

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

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 12, 2025

Size Analysis Report 1

Affected Products

  • @firebase/ai

    • AIError

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.40 kB2.43 kB+32 B (+1.3%)
      size-with-ext-deps19.9 kB20.0 kB+32 B (+0.2%)
    • AIErrorCode

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.40 kB2.43 kB+32 B (+1.3%)
      size-with-ext-deps19.9 kB20.0 kB+32 B (+0.2%)
    • AIModel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size3.94 kB3.97 kB+32 B (+0.8%)
      size-with-ext-deps21.5 kB21.6 kB+32 B (+0.1%)
    • AnyOfSchema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • ArraySchema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • Backend

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.40 kB2.43 kB+32 B (+1.3%)
      size-with-ext-deps19.9 kB20.0 kB+32 B (+0.2%)
    • BackendType

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.40 kB2.43 kB+32 B (+1.3%)
      size-with-ext-deps19.9 kB20.0 kB+32 B (+0.2%)
    • BlockReason

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.50 kB2.53 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.1 kB+32 B (+0.2%)
    • BooleanSchema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • ChatSession

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size16.9 kB17.0 kB+37 B (+0.2%)
      size-with-ext-deps34.6 kB34.7 kB+37 B (+0.1%)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      variables

      22 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_BASE_URL
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      Task
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      logger
      name
      responseLineRE
      version

      22 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      Task
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      logger
      name
      responseLineRE
      version

      + DEFAULT_DOMAIN
      - DEFAULT_BASE_URL

    • FinishReason

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.65 kB2.68 kB+32 B (+1.2%)
      size-with-ext-deps20.2 kB20.2 kB+32 B (+0.2%)
    • FunctionCallingMode

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.45 kB2.48 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.0 kB+32 B (+0.2%)
    • GenerativeModel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size20.3 kB20.3 kB+37 B (+0.2%)
      size-with-ext-deps38.0 kB38.1 kB+37 B (+0.1%)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      variables

      22 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_BASE_URL
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      Task
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      logger
      name
      responseLineRE
      version

      22 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      Task
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      logger
      name
      responseLineRE
      version

      + DEFAULT_DOMAIN
      - DEFAULT_BASE_URL

    • GoogleAIBackend

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.40 kB2.44 kB+32 B (+1.3%)
      size-with-ext-deps19.9 kB20.0 kB+32 B (+0.2%)
    • HarmBlockMethod

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.46 kB2.49 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.0 kB+32 B (+0.2%)
    • HarmBlockThreshold

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.58 kB2.61 kB+32 B (+1.2%)
      size-with-ext-deps20.1 kB20.1 kB+32 B (+0.2%)
    • HarmCategory

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.65 kB2.68 kB+32 B (+1.2%)
      size-with-ext-deps20.2 kB20.2 kB+32 B (+0.2%)
    • HarmProbability

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.48 kB2.51 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.0 kB+32 B (+0.2%)
    • HarmSeverity

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.64 kB2.67 kB+32 B (+1.2%)
      size-with-ext-deps20.2 kB20.2 kB+32 B (+0.2%)
    • ImagenAspectRatio

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.51 kB2.54 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.1 kB+32 B (+0.2%)
    • ImagenImageFormat

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.69 kB2.72 kB+32 B (+1.2%)
      size-with-ext-deps20.2 kB20.2 kB+32 B (+0.2%)
    • ImagenModel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size8.84 kB8.88 kB+37 B (+0.4%)
      size-with-ext-deps26.5 kB26.5 kB+37 B (+0.1%)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      variables

      13 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_BASE_URL
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      LANGUAGE_TAG
      PACKAGE_VERSION
      Task
      logger
      name
      version

      13 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      LANGUAGE_TAG
      PACKAGE_VERSION
      Task
      logger
      name
      version

      + DEFAULT_DOMAIN
      - DEFAULT_BASE_URL

    • ImagenPersonFilterLevel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.49 kB2.53 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.1 kB+32 B (+0.2%)
    • ImagenSafetyFilterLevel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.57 kB2.60 kB+32 B (+1.2%)
      size-with-ext-deps20.1 kB20.1 kB+32 B (+0.2%)
    • IntegerSchema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • LiveGenerativeModel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size?8.39 kB? (?)
      size-with-ext-deps?26.0 kB? (?)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      functions?

      assignRoleToPartsAndValidateSendMessageRequest
      decodeInstanceIdentifier
      formatNewContent
      formatSystemInstruction
      registerAI

      ?
      classes?

      AIError
      AIModel
      AIService
      Backend
      GoogleAIBackend
      LiveGenerativeModel
      LiveSession
      VertexAIBackend
      WebSocketUrl

      ?
      variables?

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_DOMAIN
      DEFAULT_LOCATION
      LiveResponseType
      Task
      logger
      name
      version

      ?
      enums??

      External Dependency

      ModuleBase (2e03df7)Merge (c3f5a96)Diff
      @firebase/app?

      _isFirebaseServerApp
      _registerComponent
      registerVersion

      ?
      @firebase/component?

      Component

      ?
      @firebase/logger?

      Logger

      ?
      @firebase/util?

      FirebaseError

      ?
    • LiveResponseType

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size?2.55 kB? (?)
      size-with-ext-deps?20.1 kB? (?)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      functions?

      decodeInstanceIdentifier
      registerAI

      ?
      classes?

      AIError
      AIService
      Backend
      GoogleAIBackend
      VertexAIBackend

      ?
      variables?

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_LOCATION
      LiveResponseType
      Task
      name
      version

      ?
      enums??

      External Dependency

      ModuleBase (2e03df7)Merge (c3f5a96)Diff
      @firebase/app?

      _registerComponent
      registerVersion

      ?
      @firebase/component?

      Component

      ?
      @firebase/logger?

      Logger

      ?
      @firebase/util?

      FirebaseError

      ?
    • LiveSession

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size?4.92 kB? (?)
      size-with-ext-deps?22.5 kB? (?)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      functions?

      assignRoleToPartsAndValidateSendMessageRequest
      decodeInstanceIdentifier
      formatNewContent
      registerAI

      ?
      classes?

      AIError
      AIService
      Backend
      GoogleAIBackend
      LiveSession
      VertexAIBackend

      ?
      variables?

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_LOCATION
      LiveResponseType
      Task
      logger
      name
      version

      ?
      enums??

      External Dependency

      ModuleBase (2e03df7)Merge (c3f5a96)Diff
      @firebase/app?

      _registerComponent
      registerVersion

      ?
      @firebase/component?

      Component

      ?
      @firebase/logger?

      Logger

      ?
      @firebase/util?

      FirebaseError

      ?
    • Modality

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.53 kB2.56 kB+32 B (+1.3%)
      size-with-ext-deps20.1 kB20.1 kB+32 B (+0.2%)
    • NumberSchema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • ObjectSchema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • POSSIBLE_ROLES

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.45 kB2.48 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.0 kB+32 B (+0.2%)
    • ResponseModality

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.44 kB2.47 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.0 kB+32 B (+0.2%)
    • Schema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • SchemaType

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.51 kB2.54 kB+32 B (+1.3%)
      size-with-ext-deps20.0 kB20.1 kB+32 B (+0.2%)
    • StringSchema

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size4.72 kB4.75 kB+32 B (+0.7%)
      size-with-ext-deps22.3 kB22.3 kB+32 B (+0.1%)
    • VertexAIBackend

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.40 kB2.44 kB+32 B (+1.3%)
      size-with-ext-deps19.9 kB20.0 kB+32 B (+0.2%)
    • getAI

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size2.76 kB2.79 kB+32 B (+1.2%)
      size-with-ext-deps27.4 kB27.5 kB+32 B (+0.1%)
    • getGenerativeModel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size20.4 kB20.5 kB+37 B (+0.2%)
      size-with-ext-deps38.2 kB38.2 kB+37 B (+0.1%)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      variables

      22 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_BASE_URL
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      Task
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      logger
      name
      responseLineRE
      version

      22 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      FinishReason
      HarmSeverity
      LANGUAGE_TAG
      PACKAGE_VERSION
      POSSIBLE_ROLES
      SILENT_ERROR
      Task
      VALID_PARTS_PER_ROLE
      VALID_PART_FIELDS
      VALID_PREVIOUS_CONTENT_ROLES
      badFinishReasons
      logger
      name
      responseLineRE
      version

      + DEFAULT_DOMAIN
      - DEFAULT_BASE_URL

    • getImagenModel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size9.00 kB9.04 kB+37 B (+0.4%)
      size-with-ext-deps26.7 kB26.7 kB+37 B (+0.1%)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      variables

      13 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_BASE_URL
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      LANGUAGE_TAG
      PACKAGE_VERSION
      Task
      logger
      name
      version

      13 dependencies

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_API_VERSION
      DEFAULT_DOMAIN
      DEFAULT_FETCH_TIMEOUT_MS
      DEFAULT_LOCATION
      LANGUAGE_TAG
      PACKAGE_VERSION
      Task
      logger
      name
      version

      + DEFAULT_DOMAIN
      - DEFAULT_BASE_URL

    • getLiveGenerativeModel

      Size

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      size?10.8 kB? (?)
      size-with-ext-deps?28.5 kB? (?)

      Dependency

      TypeBase (2e03df7)Merge (c3f5a96)Diff
      functions?

      assignRoleToPartsAndValidateSendMessageRequest
      createWebSocketHandler
      decodeInstanceIdentifier
      formatNewContent
      formatSystemInstruction
      getLiveGenerativeModel
      registerAI

      ?
      classes?

      AIError
      AIModel
      AIService
      Backend
      BrowserWebSocketHandler
      GoogleAIBackend
      LiveGenerativeModel
      LiveSession
      VertexAIBackend
      WebSocketUrl

      ?
      variables?

      AIErrorCode
      AI_TYPE
      BackendType
      DEFAULT_DOMAIN
      DEFAULT_LOCATION
      LiveResponseType
      Task
      logger
      name
      version

      ?
      enums??

      External Dependency

      ModuleBase (2e03df7)Merge (c3f5a96)Diff
      @firebase/app?

      _isFirebaseServerApp
      _registerComponent
      registerVersion

      ?
      @firebase/component?

      Component

      ?
      @firebase/logger?

      Logger

      ?
      @firebase/util?

      FirebaseError

      ?

Test Logs

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

@dlarocque dlarocque marked this pull request as ready for review August 13, 2025 16:29
@dlarocque dlarocque requested review from a team as code owners August 13, 2025 16:29
@dlarocque dlarocque requested a review from hsubox76 August 13, 2025 16:31
@@ -295,3 +362,83 @@ export interface ThinkingConfig {
*/
thinkingBudget?: number;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I think I would just put these internal types in a separate file and then in types/index.ts don't export from that file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done- do you think it's worth keeping @internal tag? I feel like it's convenient for readability (don't have to check index.ts to see if it's exported), but it's not needed anymore.

Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't hurt I guess.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wow. Would it be messy to store this as some native audio file and then load and convert it to base64 in this file? Would that require a third party library?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No we wouldn't need a third-party library. In Node we could read the file from disk and encode it, but in the Browser tests I think it'd be tricky to get a hold of the file on disk. Maybe there's a Karma config that will load the file into browser memory.

In my opinion storing it as an already base64 encoded string is the simplest option.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's fine to leave it as is (as base64) but for what it's worth, this is how convert-mocks.ts works, it gets called with a yarn testsetup step before tests run, and it runs in node and uses fs to open and convert the golden json files to a js file that even the browser tests can import.

@@ -128,7 +134,12 @@ export class BrowserWebSocketHandler implements WebSocketHandler {
}
};

const closeListener = (): void => {
const closeListener = (event: CloseEvent): void => {
Copy link
Contributor

Choose a reason for hiding this comment

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

These two websocket implementations have a lot of shared code, is it worth having a base class, or a bunch of utility functions they both use?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, right now there's only one line that's different (this.ws.binaryType = 'blob' in Node).
If we were to do this, I think we could share everything except for a initializeWebSocket(). The reason they're not shared right now is because I am concerned that small runtime differences between Node and Browser WebSocket APIs may appear, and justify adding more platform-specific code. I haven't found any instances of this so far, so maybe this concern isn't justified.

Could we postpone refactoring this until the Live API works with the current implementation? I want to be certain that there are no other runtime differences that I haven't encountered yet in my testing.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can avoid using a base class for that reason, but it might be good to have importable standalone functions for shared code that would shorten some of the methods and reduce duplication.

@dlarocque dlarocque requested a review from hsubox76 August 15, 2025 17:56
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.

3 participants