onju-v2/pipeline/conversation/base.py
justLV 44c7be03b8 Only persist assistant history after successful TTS delivery
Move the conversational backend's _finalize() call out of stream()'s
finally block and expose it as a public commit(text) method instead.
The previous behavior persisted whatever was yielded even when the
stream errored, the user interrupted, or a TTS send failed — so saved
history diverged from what the user actually heard, and the next turn
replayed phantom context to the LLM.

main.py now calls backend.commit(response_text) only after a turn
successfully completes and produced content. Agentic backend gets a
no-op commit() since history lives on the remote service.
2026-04-12 19:11:09 -07:00

29 lines
1.1 KiB
Python

from typing import AsyncIterator, Protocol, runtime_checkable
@runtime_checkable
class ConversationBackend(Protocol):
async def send(self, user_text: str, extra_context: str | None = None) -> str:
"""Send a user message, return the full assistant response."""
...
def stream(self, user_text: str, extra_context: str | None = None) -> AsyncIterator[str]:
"""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."""
...
def get_messages(self) -> list[dict]:
"""Return current message history (for persistence). May be empty for managed backends."""
...
def set_messages(self, messages: list[dict]) -> None:
"""Restore message history (from persistence). No-op for managed backends."""
...