Skip to content

refacto: helper refacto async sync session#35

Merged
egenthon-cmd merged 5 commits into
mainfrom
refacto/helper-refacto-async-sync-session
Jun 17, 2026
Merged

refacto: helper refacto async sync session#35
egenthon-cmd merged 5 commits into
mainfrom
refacto/helper-refacto-async-sync-session

Conversation

@egenthon-cmd

@egenthon-cmd egenthon-cmd commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • Refactor
    • Reworked Live V2 sync/async session handling to centralize shared websocket, audio resume (chunked), message parsing/filtering, acknowledgment-aware audio trimming, and session lifecycle event transitions.
  • Improvements
    • Enhanced the Live V2 session event listener API with strongly typed lifecycle statuses/events for better IDE support and type safety.
    • Exposed a standardized LiveV2SessionStatus type for consistent session-state handling across implementations.

@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aa83f03a-bc37-4b2d-9999-7a70aa66186a

📥 Commits

Reviewing files that changed from the base of the PR and between b9cd8a3 and 7bb149c.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py
  • packages/sdk-python/src/gladiaio_sdk/v2/live/async_session.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py
  • packages/sdk-python/src/gladiaio_sdk/v2/live/async_session.py

📝 Walkthrough

Walkthrough

A new _helpers.py module is introduced for the Live V2 SDK, extracting shared audio chunking, acknowledgment enforcement, WebSocket message parsing/filtering, buffer trimming, lifecycle event emission helpers, and a typed LiveV2SessionEventsMixin. LiveV2SessionStatus is moved to types.py. Both LiveV2Session and LiveV2AsyncSession are refactored to inherit the mixin and delegate to the new helpers.

Changes

Live V2 Session Helper Extraction and Refactor

Layer / File(s) Summary
LiveV2SessionStatus type alias
packages/sdk-python/src/gladiaio_sdk/v2/live/types.py
Adds LiveV2SessionStatus as a Literal type alias enumerating the six valid session state strings (starting, started, connecting, connected, ending, ended).
Core helpers: audio chunking, acknowledgments, message parsing, buffer trimming, lifecycle events
packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py
New module defines the 512 KiB WebSocket chunk constant, send_audio_in_chunks, with_acknowledgments_enabled, parse_ws_message, should_emit_ws_message, trim_acknowledged_audio_buffer, and the three lifecycle-event emission functions (emit_started_if_needed, maybe_emit_start_session_message, emit_session_ending_events).
LiveV2SessionEventsMixin typed event-listener API
packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py
Adds LiveV2SessionEventsMixin with fully overloaded on, once, off, add_listener, remove_listener, and remove_all_listeners methods delegating to _event_emitter with typed callbacks for all lifecycle and message events.
Sync and async session adoption
packages/sdk-python/src/gladiaio_sdk/v2/live/session.py, packages/sdk-python/src/gladiaio_sdk/v2/live/async_session.py
Both sessions now inherit LiveV2SessionEventsMixin, import LiveV2SessionStatus from types, and replace inline acknowledgment setup, lifecycle emission, audio chunking, WebSocket message handling, buffer trimming, and teardown logic with helper calls; local event-listener method blocks are removed.

Sequence Diagram

sequenceDiagram
  participant Client
  participant LiveV2Session
  participant _helpers
  participant WebSocket
  participant _EventEmitter

  Client->>LiveV2Session: start_session()
  LiveV2Session->>_helpers: with_acknowledgments_enabled(options)
  LiveV2Session->>_helpers: emit_started_if_needed(status="starting")
  _helpers->>_EventEmitter: emit("started", session)
  _helpers->>LiveV2Session: status="started"
  
  LiveV2Session->>_helpers: maybe_emit_start_session_message(options, session)
  _helpers->>_EventEmitter: emit("message", start_session_payload)

  LiveV2Session->>_helpers: send_audio_in_chunks(ws, audio_buffer)
  _helpers->>WebSocket: send chunks of 512 KiB
  
  WebSocket-->>LiveV2Session: incoming message
  LiveV2Session->>_helpers: parse_ws_message(raw_payload)
  _helpers-->>LiveV2Session: typed LiveV2WebSocketMessage
  
  LiveV2Session->>_helpers: should_emit_ws_message(message, config)
  _helpers-->>LiveV2Session: boolean decision
  alt message should be emitted
    LiveV2Session->>_EventEmitter: emit("message", message)
  end

  alt acknowledged audio_chunk
    LiveV2Session->>_helpers: trim_acknowledged_audio_buffer(audio_buffer, bytes_sent, byte_end)
    _helpers-->>LiveV2Session: (trimmed_buffer, updated_bytes_sent)
  end

  Client->>LiveV2Session: close_session()
  LiveV2Session->>_helpers: emit_session_ending_events(status, code, reason)
  _helpers->>_EventEmitter: emit("ending") and emit("ended")
  _helpers-->>LiveV2Session: status="ended"
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • gladiaio/sdk#34: Directly preceded this PR by fixing the reconnect resume audio buffering to send in 512 KiB chunks — the same _MAX_RESUME_CHUNK_BYTES constant and send_audio_in_chunks function extracted here.

Suggested reviewers

  • karamouche

Poem

🐇 Hippity-hop, the helpers are here,
No more inline logic to cause any fear!
A mixin for events, a chunk for the bytes,
The sessions now share all their audio delights.
One module to rule them, both sync and async bright — ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'refacto: helper refacto async sync session' is vague and uses non-descriptive terminology. 'Refacto' appears to be a typo for 'refactor', and the phrasing doesn't clearly convey what the main objective of the changes is. Clarify the title to better describe the refactoring objective, such as 'refactor: extract shared Live V2 session helpers into mixin' or similar.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refacto/helper-refacto-async-sync-session

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.

@egenthon-cmd egenthon-cmd requested a review from karamouche June 15, 2026 18:24
Comment thread packages/sdk-js/src/v2/live/session.ts
@egenthon-cmd egenthon-cmd requested a review from karamouche June 15, 2026 19:54
egenthon-cmd and others added 3 commits June 15, 2026 15:58
Extract duplicated sync/async live v2 session code into _helpers.py:
chunked audio resend, ws message parsing, lifecycle events, and the
typed event listener mixin.

Co-authored-by: Cursor <cursoragent@cursor.com>
Update _EventEmitter method signatures to match pyee EventEmitter and
AsyncIOEventEmitter so session classes type-check cleanly in CI.

Co-authored-by: Cursor <cursoragent@cursor.com>
@egenthon-cmd egenthon-cmd force-pushed the refacto/helper-refacto-async-sync-session branch from 49b2ed0 to b9cd8a3 Compare June 15, 2026 19:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py (1)

70-78: Consider using explicit type discrimination instead of hasattr for clarity

The acknowledged field exists only on LiveV2AudioChunkAckMessage (type="audio_chunk") and LiveV2StopRecordingAckMessage (type="stop_recording"). The current logic correctly preserves non-acknowledgment messages while filtering ack messages based on the config flag.

However, using hasattr(message, "acknowledged") relies on a runtime check. Since all message variants have a typed type field, prefer checking message.type not in ("audio_chunk", "stop_recording") for better clarity and type safety.

🤖 Prompt for 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.

In `@packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py` around lines 70 -
78, Replace the runtime `hasattr(message, "acknowledged")` check in the
should_emit_ws_message function with an explicit type discrimination check.
Instead of `not hasattr(message, "acknowledged")`, use `message.type not in
("audio_chunk", "stop_recording")` since the acknowledged field only exists on
LiveV2AudioChunkAckMessage and LiveV2StopRecordingAckMessage types. This
provides better clarity and type safety by explicitly checking message type
rather than relying on attribute presence detection.
🤖 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 `@packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py`:
- Around line 81-87: The trim_acknowledged_audio_buffer function at line 86 uses
`byte_end - bytes_sent` as a buffer slice index, which can become negative when
bytes_sent exceeds byte_end, causing already-acknowledged bytes to remain in the
buffer and moving the resend state backward. Clamp the trim index calculation to
a minimum of 0 to ensure you never slice from a negative position, and also
clamp the returned offset to prevent state regression. Use Python's max()
function to ensure both values stay non-negative.
- Around line 115-124: The function emit_session_ending_events does not prevent
re-emission of terminal events when the session status is already "ended".
Currently, the function only checks if status is not "ending" before emitting
the "ending" event, but if status is already "ended", it will still emit both
"ending" and "ended" events again, causing duplicates. Add an early return at
the beginning of the function to exit immediately if the status is already
"ended", since all terminal events have already been emitted and there is
nothing more to do.

In `@packages/sdk-python/src/gladiaio_sdk/v2/live/async_session.py`:
- Around line 157-158: The async session's call to send_audio_in_chunks is
unguarded while the sync session wraps this call with
contextlib.suppress(Exception) for consistency. Update the async session to wrap
the send_audio_in_chunks call with contextlib.suppress(Exception) to match the
sync session's error handling pattern and prevent unhandled exceptions from
leaving the session in an inconsistent state during WebSocket failures.

---

Nitpick comments:
In `@packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py`:
- Around line 70-78: Replace the runtime `hasattr(message, "acknowledged")`
check in the should_emit_ws_message function with an explicit type
discrimination check. Instead of `not hasattr(message, "acknowledged")`, use
`message.type not in ("audio_chunk", "stop_recording")` since the acknowledged
field only exists on LiveV2AudioChunkAckMessage and
LiveV2StopRecordingAckMessage types. This provides better clarity and type
safety by explicitly checking message type rather than relying on attribute
presence detection.
🪄 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

Run ID: 7b2a2f95-d266-4937-869c-59dbc340bc85

📥 Commits

Reviewing files that changed from the base of the PR and between 7108324 and b9cd8a3.

📒 Files selected for processing (4)
  • packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py
  • packages/sdk-python/src/gladiaio_sdk/v2/live/async_session.py
  • packages/sdk-python/src/gladiaio_sdk/v2/live/session.py
  • packages/sdk-python/src/gladiaio_sdk/v2/live/types.py

Comment thread packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py
Comment thread packages/sdk-python/src/gladiaio_sdk/v2/live/_helpers.py
Comment thread packages/sdk-python/src/gladiaio_sdk/v2/live/async_session.py Outdated
egenthon-cmd and others added 2 commits June 15, 2026 16:07
Co-authored-by: Cursor <cursoragent@cursor.com>
@egenthon-cmd egenthon-cmd dismissed karamouche’s stale review June 17, 2026 12:12

changes taken into account

@egenthon-cmd egenthon-cmd merged commit f982558 into main Jun 17, 2026
6 checks passed
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