feat: add deterministic message interaction stages
This commit is contained in:
@@ -5,65 +5,15 @@ from __future__ import annotations
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
from pipecat.frames.frames import OutputTransportMessageUrgentFrame, TTSSpeakFrame
|
||||
from pipecat.frames.frames import OutputTransportMessageUrgentFrame
|
||||
from pipecat.utils.time import time_now_iso8601
|
||||
|
||||
from services.brains.base import BrainRuntime
|
||||
from services.runtime_variables import DynamicVariableStore
|
||||
from services.fixed_speech import FixedSpeechOutput
|
||||
|
||||
|
||||
class WorkflowOutput:
|
||||
class WorkflowOutput(FixedSpeechOutput):
|
||||
"""Publish debug events and fixed speech without duplicating persistence."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
store: DynamicVariableStore,
|
||||
runtime: BrainRuntime,
|
||||
) -> None:
|
||||
self._store = store
|
||||
self._runtime = runtime
|
||||
self._client_ready = False
|
||||
self._pending_transcripts: list[dict[str, Any]] = []
|
||||
|
||||
async def mark_client_ready(self) -> None:
|
||||
self._client_ready = True
|
||||
pending = self._pending_transcripts
|
||||
self._pending_transcripts = []
|
||||
for message in pending:
|
||||
await self.emit(message)
|
||||
|
||||
async def speak(
|
||||
self,
|
||||
text: str,
|
||||
*,
|
||||
source: str,
|
||||
node_id: str | None = None,
|
||||
) -> None:
|
||||
"""Record, display and synthesize one Workflow-owned utterance."""
|
||||
content = text.strip()
|
||||
if not content:
|
||||
return
|
||||
self._store.record("agent", content)
|
||||
transcript = {
|
||||
"type": "transcript",
|
||||
"role": "assistant",
|
||||
"content": content,
|
||||
"timestamp": time_now_iso8601(),
|
||||
"source": source,
|
||||
**({"nodeId": node_id} if node_id else {}),
|
||||
}
|
||||
if self._client_ready:
|
||||
await self.emit(transcript)
|
||||
else:
|
||||
self._pending_transcripts.append(transcript)
|
||||
|
||||
track_speech = getattr(self._runtime.call_end, "track_speech", None)
|
||||
if callable(track_speech):
|
||||
track_speech()
|
||||
await self._runtime.queue_frame(
|
||||
TTSSpeakFrame(content, append_to_context=False)
|
||||
)
|
||||
|
||||
async def emit_node_active(self, node_id: str | None) -> None:
|
||||
if node_id:
|
||||
await self.emit({"type": "node-active", "nodeId": node_id})
|
||||
|
||||
Reference in New Issue
Block a user