import io import re import wave import gradio as gr import numpy as np from .fish_e2e import FishE2EAgent, FishE2EEventType from .schema import ServeMessage, ServeTextPart, ServeVQPart def wav_chunk_header(sample_rate=44100, bit_depth=16, channels=1): buffer = io.BytesIO() with wave.open(buffer, "wb") as wav_file: wav_file.setnchannels(channels) wav_file.setsampwidth(bit_depth // 8) wav_file.setframerate(sample_rate) wav_header_bytes = buffer.getvalue() buffer.close() return wav_header_bytes class ChatState: def __init__(self): self.conversation = [] self.added_systext = False self.added_sysaudio = False def get_history(self): results = [] for msg in self.conversation: results.append({"role": msg.role, "content": self.repr_message(msg)}) # Process assistant messages to extract questions and update user messages for i, msg in enumerate(results): if msg["role"] == "assistant": match = re.search(r"Question: (.*?)\n\nResponse:", msg["content"]) if match and i > 0 and results[i - 1]["role"] == "user": # Update previous user message with extracted question results[i - 1]["content"] += "\n" + match.group(1) # Remove the Question/Answer format from assistant message msg["content"] = msg["content"].split("\n\nResponse: ", 1)[1] return results def repr_message(self, msg: ServeMessage): response = "" for part in msg.parts: if isinstance(part, ServeTextPart): response += part.text elif isinstance(part, ServeVQPart): response += f"