Skip to content

Receiver通知をSSE化してストリーミング発話を高速化 - #593

Merged
tegnike merged 2 commits into
developfrom
codex/streaming-speech-input
Aug 4, 2026
Merged

Receiver通知をSSE化してストリーミング発話を高速化#593
tegnike merged 2 commits into
developfrom
codex/streaming-speech-input

Conversation

@tegnike

@tegnike tegnike commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Summary

  • Message Receiverを認証付きSSE通知へ切り替え、発話・停止・プレゼン操作をキュー投入直後に取得します。
  • SSE切断中は1秒ポーリングへフォールバックし、接続中も15秒ごとの安全確認と指数バックオフ再接続を維持します。
  • 分割されたストリーミング回答へ共通のspeechSessionIdを渡し、同一SpeakQueueセッションでFIFO処理します。
  • TTS処理中に重なった通知をまとめて再実行し、後続チャンクの取りこぼしを防止します。

Verification

  • npm exec eslint -- <変更対象>
  • npm test -- --runInBand src/__tests__/features/api/receiverEventStream.test.ts src/__tests__/pages/api/v1/externalApi.test.ts src/__tests__/pages/api/v1/externalApiValidation.test.ts(54件通過)
  • NODE_OPTIONS="--localstorage-file=<temporary-file>" npm test -- --runInBand(202 suites、2226件通過、7件skip)
  • npm run build
  • 接続中OBS Receiverでstop_requestedからcommands_fetchedまで28msであることを実測
  • Morning Showからの音声入力で、ストリーミング発話の体感遅延が改善したことを確認

Notes

  • Node 24では--localstorage-file未指定時、既存のimages.test.tsがNode組み込みlocalStorageの保存先不足で14件失敗します。保存先を明示すると全suiteが通過します。
  • EventSourceはAuthorizationヘッダーを指定できないため、Receiver側はfetchのReadableStreamでSSEを購読します。
  • SSE障害時も既存の1秒ポーリングへ自動的に戻るため、配送経路は維持されます。

Summary by CodeRabbit

  • 新機能

    • ReceiverがSSEでイベントを受信し、メッセージやコマンドを即時処理できるようになりました。
    • SSE切断時の自動再接続、接続状態通知、フォールバックポーリングに対応しました。
    • /api/v1/speakで発話セッションIDを指定でき、分割された発話の順序を維持できます。
    • プレゼンテーション操作や停止要求のイベント通知に対応しました。
  • 改善

    • SSE接続のハートビートにより、接続状態を安定して維持します。
    • 発話セッションIDの形式・長さを検証し、不正な入力にはエラーを返します。
  • ドキュメント

    • SSE購読、発話セッション、Receiver通信の仕様を更新しました。

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: a1631ed4-f557-4d2a-aa30-357718e658d7

📥 Commits

Reviewing files that changed from the base of the PR and between 2256309 and 7654145.

📒 Files selected for processing (5)
  • src/__tests__/features/api/receiverEventStream.test.ts
  • src/__tests__/pages/api/v1/externalApi.test.ts
  • src/features/api/messageGateway.ts
  • src/features/api/receiverEventStream.ts
  • src/pages/send-message.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/pages/send-message.tsx
  • src/features/api/receiverEventStream.ts

Walkthrough

Receiver通信をSSE通知中心へ変更しました。切断時のポーリングと指数バックオフ再接続を追加しました。speechSessionIdを発話API、キュー、音声処理へ伝播しました。関連するイベント、仕様、テストを更新しました。

Changes

Receiver SSE通知と発話セッション連携

Layer / File(s) Summary
発話セッションIDの契約とキュー処理
src/pages/api/v1/speak.ts, src/features/api/messageGateway.ts, src/features/chat/speechPipeline/speakMessageHandler.ts, src/pages/send-message.tsx, src/__tests__/pages/api/v1/externalApi*.test.ts
/api/v1/speakが任意のspeechSessionIdを検証します。値をキューメッセージと音声処理へ渡します。同一セッションの高優先度メッセージをFIFOで処理します。
Receiver SSE購読とイベント配信
src/features/api/receiverEventStream.ts, src/pages/api/v1/events.ts, src/__tests__/features/api/receiverEventStream.test.ts, src/__tests__/pages/api/v1/externalApiValidation.test.ts
認証付きSSE購読、イベント変換、通知の合流、指数バックオフ再接続を追加します。SSEレスポンスにハートビートとクリーンアップ処理を追加します。
messageReceiverの起床処理とフォールバック
src/components/messageReceiver.tsx, docs/external-presentation-api-spec.md, docs/receiver-registry-api-spec.md
messageReceiverがSSEイベントでメッセージまたはコマンド取得を起動します。未接続時は1秒間隔でポーリングし、接続中は15秒間隔で確認します。取得処理を合流制御します。

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant messageReceiver
  participant receiverEventStream
  participant eventsApi as /api/v1/events
  participant messageGateway
  messageReceiver->>receiverEventStream: ReceiverごとのSSE購読
  receiverEventStream->>eventsApi: 認証付きSSE接続
  messageGateway-->>eventsApi: messagesまたはcommandsイベント
  eventsApi-->>receiverEventStream: SSEイベント送信
  receiverEventStream-->>messageReceiver: 起床通知
  messageReceiver->>messageGateway: メッセージまたはコマンド取得
Loading

Possibly related PRs

  • tegnike/aituber-kit#524: 同じ/api/v1メッセージゲートウェイ、messageReceiver、SSE機能に関連します。
  • tegnike/aituber-kit#587: messageReceiver.tsxmessageGateway.ts、外部Presentation APIのイベントフローに関連します。
  • tegnike/aituber-kit#591: Receiverのメッセージ配信とmessageReceiver.tsxの変更に関連します。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルは、Receiver通知のSSE化とストリーミング発話の高速化という変更の主目的を明確に示しています。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ 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 codex/streaming-speech-input

Comment @coderabbitai help to get the list of available commands.

@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

🤖 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/features/api/messageGateway.ts`:
- Line 337: 同一 speechSessionId の高優先度チャンクが unshift
により逆順になるため、メッセージ挿入処理を更新してください。後続チャンクは同一セッションの既存チャンク群の直後に挿入して FIFO
順を維持し、異なるセッション間の高優先度処理は変更しないでください。高優先度チャンクを同一セッションへ連続投入した際に投入順で取得できる回帰テストを追加してください。

In `@src/features/api/receiverEventStream.ts`:
- Around line 107-109: Update the reconnect handling around the
connection-success logic in the SSE receiver so reconnectDelayMs is not reset
immediately after HTTP success; reset it only after the connection has remained
established for the intended stability period. Preserve onConnectionChange
behavior, and add a regression test covering immediately closing 200 responses
that verifies delays increase from 250ms to 500ms to 1 second.

In `@src/pages/send-message.tsx`:
- Around line 142-147: Update the speechSessionId parameter definition in the
send-message API schema to document the acceptance constraint as 1–200
characters after trimming whitespace. Use the existing type/description metadata
so the API console clearly indicates that whitespace-only and over-200-character
values are invalid.
🪄 Autofix

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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0bfd7ed0-cfad-46aa-9283-f7b6ada1823a

📥 Commits

Reviewing files that changed from the base of the PR and between 072d01e and 2256309.

📒 Files selected for processing (12)
  • docs/external-presentation-api-spec.md
  • docs/receiver-registry-api-spec.md
  • src/__tests__/features/api/receiverEventStream.test.ts
  • src/__tests__/pages/api/v1/externalApi.test.ts
  • src/__tests__/pages/api/v1/externalApiValidation.test.ts
  • src/components/messageReceiver.tsx
  • src/features/api/messageGateway.ts
  • src/features/api/receiverEventStream.ts
  • src/features/chat/speechPipeline/speakMessageHandler.ts
  • src/pages/api/v1/events.ts
  • src/pages/api/v1/speak.ts
  • src/pages/send-message.tsx

Comment thread src/features/api/messageGateway.ts
Comment thread src/features/api/receiverEventStream.ts
Comment thread src/pages/send-message.tsx
@tegnike
tegnike merged commit edd0074 into develop Aug 4, 2026
7 checks passed
@tegnike
tegnike deleted the codex/streaming-speech-input branch August 4, 2026 21:06
@coderabbitai coderabbitai Bot mentioned this pull request Aug 4, 2026
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.

1 participant