Merge perf/stream-segments: streaming partial transcript segments and speaker updates
This commit is contained in:
@@ -104,8 +104,13 @@ pub fn run_pipeline(
|
||||
}),
|
||||
);
|
||||
|
||||
let response = manager.send_and_receive_with_progress(&msg, |progress| {
|
||||
let _ = app.emit("pipeline-progress", &progress.payload);
|
||||
let response = manager.send_and_receive_with_progress(&msg, |msg| {
|
||||
let event_name = match msg.msg_type.as_str() {
|
||||
"pipeline.segment" => "pipeline-segment",
|
||||
"pipeline.speaker_update" => "pipeline-speaker-update",
|
||||
_ => "pipeline-progress",
|
||||
};
|
||||
let _ = app.emit(event_name, &msg.payload);
|
||||
})?;
|
||||
|
||||
if response.msg_type == "error" {
|
||||
|
||||
@@ -182,6 +182,70 @@ impl SidecarManager {
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a message and receive the response, calling a callback for intermediate messages.
|
||||
/// Intermediate messages include progress, pipeline.segment, and pipeline.speaker_update.
|
||||
pub fn send_and_receive_with_progress<F>(
|
||||
&self,
|
||||
msg: &IPCMessage,
|
||||
on_intermediate: F,
|
||||
) -> Result<IPCMessage, String>
|
||||
where
|
||||
F: Fn(&IPCMessage),
|
||||
{
|
||||
// Write to stdin
|
||||
{
|
||||
let mut stdin_guard = self.stdin.lock().map_err(|e| e.to_string())?;
|
||||
if let Some(ref mut stdin) = *stdin_guard {
|
||||
let json = serde_json::to_string(msg).map_err(|e| e.to_string())?;
|
||||
stdin
|
||||
.write_all(json.as_bytes())
|
||||
.map_err(|e| format!("Write error: {e}"))?;
|
||||
stdin
|
||||
.write_all(b"\n")
|
||||
.map_err(|e| format!("Write error: {e}"))?;
|
||||
stdin.flush().map_err(|e| format!("Flush error: {e}"))?;
|
||||
} else {
|
||||
return Err("Sidecar stdin not available".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// Read from stdout
|
||||
{
|
||||
let mut reader_guard = self.reader.lock().map_err(|e| e.to_string())?;
|
||||
if let Some(ref mut reader) = *reader_guard {
|
||||
let mut line = String::new();
|
||||
loop {
|
||||
line.clear();
|
||||
let bytes_read = reader
|
||||
.read_line(&mut line)
|
||||
.map_err(|e| format!("Read error: {e}"))?;
|
||||
if bytes_read == 0 {
|
||||
return Err("Sidecar closed stdout".to_string());
|
||||
}
|
||||
let trimmed = line.trim();
|
||||
if trimmed.is_empty() {
|
||||
continue;
|
||||
}
|
||||
let response: IPCMessage = serde_json::from_str(trimmed)
|
||||
.map_err(|e| format!("Parse error: {e}"))?;
|
||||
|
||||
// Forward intermediate messages via callback, return the final result/error
|
||||
let is_intermediate = matches!(
|
||||
response.msg_type.as_str(),
|
||||
"progress" | "pipeline.segment" | "pipeline.speaker_update"
|
||||
);
|
||||
if is_intermediate {
|
||||
on_intermediate(&response);
|
||||
} else {
|
||||
return Ok(response);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Err("Sidecar stdout not available".to_string())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop the sidecar process.
|
||||
pub fn stop(&self) -> Result<(), String> {
|
||||
// Drop stdin to signal EOF
|
||||
|
||||
Reference in New Issue
Block a user