Files
Josh Knapp 67ed69df00 Stream transcript segments to frontend as they are transcribed
Send each segment to the frontend immediately after transcription via
a new pipeline.segment IPC message, then send speaker assignments as a
batch pipeline.speaker_update message after diarization completes. This
lets the UI display segments progressively instead of waiting for the
entire pipeline to finish.

Changes:
- Add partial_segment_message and speaker_update_message IPC factories
- Add on_segment callback parameter to TranscribeService.transcribe()
- Emit partial segments and speaker updates from PipelineService.run()
- Add send_and_receive_with_progress to SidecarManager (Rust)
- Route pipeline.segment/speaker_update events in run_pipeline command
- Listen for streaming events in Svelte frontend (+page.svelte)
- Add tests for new message types, callback signature, and update logic

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 13:47:57 -07:00

55 lines
1.5 KiB
Python

"""IPC message type definitions."""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any
@dataclass
class IPCMessage:
"""A message exchanged between Rust and Python via JSON-line protocol."""
id: str
type: str
payload: dict[str, Any] = field(default_factory=dict)
def to_dict(self) -> dict[str, Any]:
return {"id": self.id, "type": self.type, "payload": self.payload}
@classmethod
def from_dict(cls, data: dict[str, Any]) -> IPCMessage:
return cls(
id=data.get("id", ""),
type=data.get("type", ""),
payload=data.get("payload", {}),
)
def progress_message(request_id: str, percent: int, stage: str, message: str) -> IPCMessage:
return IPCMessage(
id=request_id,
type="progress",
payload={"percent": percent, "stage": stage, "message": message},
)
def partial_segment_message(request_id: str, segment_data: dict) -> IPCMessage:
return IPCMessage(id=request_id, type="pipeline.segment", payload=segment_data)
def speaker_update_message(request_id: str, updates: list[dict]) -> IPCMessage:
return IPCMessage(id=request_id, type="pipeline.speaker_update", payload={"updates": updates})
def error_message(request_id: str, code: str, message: str) -> IPCMessage:
return IPCMessage(
id=request_id,
type="error",
payload={"code": code, "message": message},
)
def ready_message() -> IPCMessage:
return IPCMessage(id="system", type="ready", payload={"version": "0.1.0"})