diff --git a/pipeline/conversation/agentic.py b/pipeline/conversation/agentic.py index dc57660..57123f2 100644 --- a/pipeline/conversation/agentic.py +++ b/pipeline/conversation/agentic.py @@ -68,6 +68,9 @@ class AgenticBackend: if delta: yield delta + def commit(self, text: str) -> None: + pass # remote service owns history + def reset(self) -> None: pass # session reset would require an API call if supported diff --git a/pipeline/conversation/base.py b/pipeline/conversation/base.py index 8014fad..19c70de 100644 --- a/pipeline/conversation/base.py +++ b/pipeline/conversation/base.py @@ -11,6 +11,11 @@ class ConversationBackend(Protocol): """Send a user message, yield assistant text deltas as they arrive.""" ... + def commit(self, text: str) -> None: + """Persist the assistant response after successful delivery. Call + only after the turn actually played out. No-op for managed backends.""" + ... + def reset(self) -> None: """Clear conversation history / start a new session.""" ... diff --git a/pipeline/conversation/conversational.py b/pipeline/conversation/conversational.py index b5755ff..c41ba8c 100644 --- a/pipeline/conversation/conversational.py +++ b/pipeline/conversation/conversational.py @@ -75,17 +75,17 @@ class ConversationalBackend: kwargs["stream"] = True stream = await self.client.chat.completions.create(**kwargs) - parts: list[str] = [] - try: - async for chunk in stream: - if not chunk.choices: - continue - delta = chunk.choices[0].delta.content or "" - if delta: - parts.append(delta) - yield delta - finally: - self._finalize("".join(parts)) + async for chunk in stream: + if not chunk.choices: + continue + delta = chunk.choices[0].delta.content or "" + if delta: + yield delta + + def commit(self, text: str) -> None: + """Persist the assistant response to history after successful + delivery. The caller joins whatever was actually sent to TTS.""" + self._finalize(text) def reset(self) -> None: self.messages = [{"role": "system", "content": self.cfg["system_prompt"]}] diff --git a/pipeline/main.py b/pipeline/main.py index 47925d7..4de75f0 100644 --- a/pipeline/main.py +++ b/pipeline/main.py @@ -389,6 +389,8 @@ async def process_utterances(config: dict, manager: DeviceManager, utterance_que volume=0, fade=0) response_text = " ".join(full_response) + if response_text: + device.conversation.commit(response_text) device.last_response = response_text elapsed = time.monotonic() - turn_t0 ttfs = f"{first_sentence_at - turn_t0:.2f}s" if first_sentence_at else "—"