Skip to content

fix: ensure transcript summaries flush after silence#715

Open
Shreya-nipunge wants to merge 2 commits into
shouri123:mainfrom
Shreya-nipunge:fix/714-summary-retrigger-silence
Open

fix: ensure transcript summaries flush after silence#715
Shreya-nipunge wants to merge 2 commits into
shouri123:mainfrom
Shreya-nipunge:fix/714-summary-retrigger-silence

Conversation

@Shreya-nipunge

@Shreya-nipunge Shreya-nipunge commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes #714

This change ensures transcript summaries are not silently skipped when the summarization interval guard is hit shortly before a meeting becomes inactive.

Changes

  • Add a retry alarm when summarization is deferred by the interval guard.
  • Register a global alarm listener to trigger the deferred summary when the cooldown expires.
  • Add a forced final summary flush during stopAudioCapture() before saving the session.
  • Clear pending retry alarms during shutdown.
  • Wait for any in-flight summary operation to complete before performing the final flush.
  • Add regression tests covering:
    • deferred summary retry scheduling
    • final summary generation on manual stop

Problem

Previously, if a transcript update arrived during the summarization cooldown window, summarizeTranscriptIfNeeded() returned early without scheduling a retry. If the meeting then became silent or ended before another transcript chunk arrived, the latest discussion could be missing from summaries and action items.

This change guarantees that deferred summaries are retried and that remaining transcript content is summarized before session persistence.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings

Summary by CodeRabbit

  • Tests
    • Expanded the TypeScript test run to include additional late-joiner, background, and summary-related entrypoints.
    • Added a new suite covering transcript summarization retry behavior and shutdown/flush handling.
  • Bug Fixes
    • Improved transcript summarization reliability by automatically retrying via scheduled alarms when summaries need to be reattempted.
    • Enhanced shutdown behavior to force a final transcript summary flush and clear any pending retry work before saving state.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Thank You for Contributing to Late-Meet

Please ensure that:

  • the issue was assigned to you before opening this PR
  • the PR references the related issue
  • your changes follow repository contribution guidelines
  • the project builds successfully before submission

Unassigned, duplicate, or low-quality PRs may be closed.

Thank you for contributing 💙

@github-actions github-actions Bot added gssoc Official GSSoC contribution issue gssoc:approved GSSoC: PR approved and scored bug Something isn't working size/M type:code Type: Code change type:design Type: Design / UI / UX (Optional bonus) type:config Type: Configuration change type:docs Type: Documentation type:test Type: Test files type:feature Type: New Feature security-review Requires security review before merge labels Jun 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

👋 Thank you @Shreya-nipunge for your contribution to Late-Meet!

✅ Verified: You are assigned to the linked issue #714.

Please review any automated suggestions or code review comments that may appear below! We will review your PR as soon as possible!


Please consider starring the repository ⭐ to show your support!

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR fixes a bug where transcript summarization was never retriggered after the interval guard early-returned during silence. The changes implement an alarm-based retry mechanism in background.ts, extend the shutdown sequence to force a final summary flush, and add comprehensive tests that verify both retry scheduling and shutdown behavior.

Changes

Summarization Retry and Shutdown Flush

Layer / File(s) Summary
Alarm-based retry infrastructure
src/background.ts
SUMMARY_RETRY_ALARM constant is defined and a global chrome.alarms.onAlarm listener is registered to trigger summarizeTranscriptIfNeeded(). The function signature is updated to accept an optional force flag that bypasses interval-based retry scheduling.
Interval guard with retry scheduling
src/background.ts
When force is false and elapsed time is below the configured interval, a retry alarm is scheduled for the remaining time instead of silently returning. The retry alarm is cleared when summarization proceeds.
Shutdown with forced summary flush
src/background.ts
stopAudioCapture() is extended to disable audioActive, broadcast shutdown state, clear pending retry alarms, wait for in-flight summaries, and perform a forced summarizeTranscriptIfNeeded(true) before session persistence.
Test harness and mock infrastructure
src/background.summary.test.ts
Full mock environment for Chrome runtime, alarms, and storage APIs, plus stubbed fetch. After mocks are installed, background.ts is imported. Helpers include sendMessage() to invoke registered listeners and an after() cleanup hook.
Retry and flush behavior tests
src/background.summary.test.ts
Two test cases: interval-guard test verifies a summarize-retry alarm is scheduled when elapsed time is below the interval; manual-stop test verifies the alarm is cleared and a final summary fetch is issued when MANUAL_STOP_AUDIO is sent.
Test script configuration
package.json
The scripts.test command is updated to include the new test file in the tsx --test invocation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • shouri123/Late-Meet#183: Both PRs modify package.json's scripts.test command to adjust TypeScript test entrypoints in the tsx --test invocation.
  • shouri123/Late-Meet#161: Both PRs update package.json's scripts.test to change which tsx --test TypeScript test files are executed.
  • shouri123/Late-Meet#58: Both PRs modify src/background.ts's transcript summarization flow by adjusting retry behavior, alarm/scheduling mechanisms, and in-flight guarding to control repeated summary attempts.

Suggested labels

bug, type:testing, component:background

Suggested reviewers

  • shouri123

Poem

🐰 A transcript waits for its final bow,
No silence shall silence it now,
With alarms that chime when talk runs dry,
And shutdowns that force one last goodbye,
The summary sleeps nevermore—hooray! 🔔

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: ensure transcript summaries flush after silence' directly describes the main change: implementing a mechanism to guarantee summaries are generated when meetings become silent, which is the primary objective of this PR.
Linked Issues check ✅ Passed The PR comprehensively implements all objectives from issue #714: adds a retry alarm system for deferred summaries, integrates forced final summary flush into stopAudioCapture(), implements cleanup procedures, and includes regression tests validating the functionality.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #714: package.json test command updates, new test file for validating the retry/flush mechanisms, and background.ts modifications implementing the alarm-based retry and forced flush logic.

✏️ 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.

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/background.ts (1)

2303-2312: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Pipeline failure: Test mock missing chrome.runtime.onSuspend.

All CI test runs fail because the test harness in src/background.summary.test.ts does not mock chrome.runtime.onSuspend. When this module loads, line 2303 throws TypeError: Cannot read properties of undefined (reading 'addListener').

Add the missing mock in the test file's Chrome runtime mock object:

// In src/background.summary.test.ts, inside the chrome.runtime mock:
onSuspend: { addListener: () => {} },
🤖 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 `@src/background.ts` around lines 2303 - 2312, The test harness is missing a
mock for chrome.runtime.onSuspend which causes
chrome.runtime.onSuspend.addListener to be undefined when src/background.ts
loads; update the chrome.runtime mock in src/background.summary.test.ts to
include an onSuspend object with a no-op addListener function so that calls to
chrome.runtime.onSuspend.addListener succeed during tests (target the
chrome.runtime mock where other runtime properties are defined).

Source: Pipeline failures

🧹 Nitpick comments (1)
src/background.summary.test.ts (1)

123-127: ⚡ Quick win

sendMessage() does not await async listener work, making timing assertions flaky.

Line 123-Line 127 dispatches listeners synchronously and ignores returned promises, so assertions depend on arbitrary sleeps (Line 149, Line 159, Line 174). Await listener completion to reduce nondeterminism in CI.

Suggested refactor
 async function sendMessage(msg: any) {
-  for (const listener of onMessageListeners) {
-    listener(msg, {}, () => {});
-  }
+  for (const listener of onMessageListeners) {
+    await Promise.resolve(listener(msg, {}, () => {}));
+  }
 }

Also applies to: 149-159, 174-175

🤖 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 `@src/background.summary.test.ts` around lines 123 - 127, The sendMessage
helper dispatches onMessageListeners synchronously and ignores returned
promises, causing flaky timing; modify sendMessage to collect each listener's
return value (call listener(msg, {}, () => {})) and await Promise.all on those
results (use Promise.resolve for non-promise returns or Promise.allSettled if
you want to continue despite individual failures) so tests relying on
asynchronous listener work no longer need arbitrary sleeps; update any
callers/tests that assumed synchronous behavior if necessary.
🤖 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 `@package.json`:
- Line 68: Run Prettier to reformat package.json and commit the result so CI
passes the npm run format:check step; e.g., run the project's formatting script
(npm run format -- package.json) or npx prettier --write package.json, then
stage and commit the updated package.json so the formatting drift is resolved.

In `@src/background.summary.test.ts`:
- Around line 110-112: The test's storage mock methods get, set, and remove
declare unused parameters causing TS6133; update the parameter names in the mock
for get, set, and remove inside src/background.summary.test.ts to use
underscore-prefixed names (e.g., _key, _items, _key) or otherwise consume them
so they are no longer reported as unused—locate the mock object with the get:
async (key: string) => ..., set: async (items: any) => ..., remove: async (key:
string) => ... and rename the parameters accordingly.
- Around line 53-115: The Chrome mock in installChromeMock is missing the
runtime.onSuspend listener which causes importing background.ts (which calls
chrome.runtime.onSuspend.addListener) to crash; update the mock object inside
installChromeMock (the chrome.runtime section) to include onSuspend: {
addListener: () => {} } so chrome.runtime.onSuspend.addListener(...) is defined
when background.ts is imported.

---

Outside diff comments:
In `@src/background.ts`:
- Around line 2303-2312: The test harness is missing a mock for
chrome.runtime.onSuspend which causes chrome.runtime.onSuspend.addListener to be
undefined when src/background.ts loads; update the chrome.runtime mock in
src/background.summary.test.ts to include an onSuspend object with a no-op
addListener function so that calls to chrome.runtime.onSuspend.addListener
succeed during tests (target the chrome.runtime mock where other runtime
properties are defined).

---

Nitpick comments:
In `@src/background.summary.test.ts`:
- Around line 123-127: The sendMessage helper dispatches onMessageListeners
synchronously and ignores returned promises, causing flaky timing; modify
sendMessage to collect each listener's return value (call listener(msg, {}, ()
=> {})) and await Promise.all on those results (use Promise.resolve for
non-promise returns or Promise.allSettled if you want to continue despite
individual failures) so tests relying on asynchronous listener work no longer
need arbitrary sleeps; update any callers/tests that assumed synchronous
behavior if necessary.
🪄 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: 1e9d7d08-8725-4b7c-9af2-2de5c0a6ad8c

📥 Commits

Reviewing files that changed from the base of the PR and between f4875c8 and ed213c2.

📒 Files selected for processing (3)
  • package.json
  • src/background.summary.test.ts
  • src/background.ts

Comment thread package.json Outdated
"rollup": "^2.80.0 || ^4.59.0"
}
}
} No newline at end of file

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix package.json formatting to unblock CI.

npm run format:check is currently failing due to formatting drift in this file (reported by the pipeline). Please run Prettier on package.json and commit the formatted result.

Suggested command
npm run format -- package.json
# or
npx prettier --write package.json
🤖 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 `@package.json` at line 68, Run Prettier to reformat package.json and commit
the result so CI passes the npm run format:check step; e.g., run the project's
formatting script (npm run format -- package.json) or npx prettier --write
package.json, then stage and commit the updated package.json so the formatting
drift is resolved.

Source: Pipeline failures

Comment thread src/background.summary.test.ts
Comment thread src/background.summary.test.ts Outdated
@github-actions github-actions Bot removed the type:docs Type: Documentation label Jun 10, 2026
@shouri123

Copy link
Copy Markdown
Owner

try to resolve the coderabbit usggestions and also some chcksre not running try to fix them @Shreya-nipunge

Shreya-nipunge and others added 2 commits June 14, 2026 19:54
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@Shreya-nipunge Shreya-nipunge force-pushed the fix/714-summary-retrigger-silence branch from 2350fbc to 6955be0 Compare June 14, 2026 15:41
@sonarqubecloud

Copy link
Copy Markdown

@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: 3

🧹 Nitpick comments (1)
src/background.summary.test.ts (1)

117-117: 💤 Low value

Optional: type assertion may be unnecessary.

SonarCloud flags this type assertion as unnecessary because TypeScript's control flow analysis should infer that keys is a string after the Array.isArray(keys) guard on line 107. The assertion improves readability but isn't strictly required.

♻️ Optional simplification
-          const key = keys as string;
+          const key = keys;
🤖 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 `@src/background.summary.test.ts` at line 117, The type assertion `as string`
on the `keys` variable is unnecessary because TypeScript's control flow analysis
already infers that `keys` is a string after the Array.isArray guard check.
Remove the type assertion and change `const key = keys as string;` to `const key
= keys;` to simplify the code while maintaining the same functionality and type
safety.
🤖 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/background.summary.test.ts`:
- Line 8: Add a new test case within or after the interval-guard test (lines
152-186) that verifies the alarm listener retry behavior. The test should
trigger the interval guard to create the alarm, then manually invoke the alarm
listener by calling alarmListeners[0]({ name: "summarize-retry" }) to simulate
the alarm firing, and finally verify that summarizeTranscriptIfNeeded() is
re-invoked and a summary fetch is dispatched. This ensures that the alarm
mechanism actually triggers the retry logic when the scheduled alarm fires, not
just that the alarm was created.

In `@src/background.ts`:
- Around line 1817-1825: The polling loop waits for the summaryInFlight boolean
to become false, but if it remains true after 10 seconds, the immediate call to
summarizeTranscriptIfNeeded(true) returns immediately due to a guard condition
that prevents execution when a summary is already in flight. Instead of relying
on polling and calling the function, capture and directly await the actual
in-flight summary promise or operation, or alternatively, if the summary is
still in flight after the timeout period, fail the session save path (around
line 1829) rather than persisting the session with an incomplete summary.
- Around line 1011-1016: The SUMMARY_RETRY_ALARM listener in the
chrome.alarms.onAlarm callback is missing the state hydration and persistence
steps that the normal chunk path performs. Before calling
summarizeTranscriptIfNeeded(), add a call to hydrateState() to load the current
state from storage so the function sees the correct state rather than defaults.
After summarizeTranscriptIfNeeded() completes, add a call to
broadcastStateUpdate() to persist any changes to activeMeetingState and notify
the UI of the updated summary. This ensures the deferred summary is properly
saved and not lost on the next worker suspend.

---

Nitpick comments:
In `@src/background.summary.test.ts`:
- Line 117: The type assertion `as string` on the `keys` variable is unnecessary
because TypeScript's control flow analysis already infers that `keys` is a
string after the Array.isArray guard check. Remove the type assertion and change
`const key = keys as string;` to `const key = keys;` to simplify the code while
maintaining the same functionality and type safety.
🪄 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: 6775264b-dcb6-4698-880e-554c76796e43

📥 Commits

Reviewing files that changed from the base of the PR and between ed213c2 and 6955be0.

📒 Files selected for processing (3)
  • package.json
  • src/background.summary.test.ts
  • src/background.ts

Comment thread src/background.summary.test.ts
Comment thread src/background.ts
Comment thread src/background.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working gssoc:approved GSSoC: PR approved and scored gssoc Official GSSoC contribution issue security-review Requires security review before merge size/M type:code Type: Code change type:config Type: Configuration change type:design Type: Design / UI / UX (Optional bonus) type:feature Type: New Feature type:test Type: Test files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Summary generation is never retriggered after interval-based early return during silence

2 participants