Files
VoiceAgent/test_journal.py
T

69 lines
2.9 KiB
Python

"""The journal must capture both halves of a turn.
Regression test for a placement bug: the journal originally sat at the end of
the pipeline, where the user aggregator has already consumed the transcript, so
it never recorded anything at all.
"""
import asyncio, json, sys, tempfile
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from journal import Journal, recent_prompt
from pipecat.frames.frames import EndFrame, TranscriptionFrame
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.worker import PipelineWorker
from pipecat.processors.aggregators.llm_context import LLMContext
from pipecat.processors.aggregators.llm_response_universal import (
LLMContextAggregatorPair, LLMUserAggregatorParams)
from pipecat.turns.user_start.external_user_turn_start_strategy import ExternalUserTurnStartStrategy
from pipecat.turns.user_stop.external_user_turn_stop_strategy import ExternalUserTurnStopStrategy
from pipecat.turns.user_turn_strategies import UserTurnStrategies
from pipecat.utils.time import time_now_iso8601
from pipecat.workers.runner import WorkerRunner
def test_recent_prompt_reads_last_ten_entries():
path = Path(tempfile.mkdtemp()) / "journal.jsonl"
rows = [
json.dumps({"heard": f"question {i}", "reply": f"answer {i}"})
for i in range(12)
]
path.write_text("\n".join(rows[:3]) + "\nnot json\n" + "\n".join(rows[3:]))
prompt = recent_prompt(path)
assert "User: question 0\n" not in prompt
assert "User: question 1\n" not in prompt
assert "User: question 2\n" in prompt
assert "User: question 11\n" in prompt
assert prompt.index("User: question 2\n") < prompt.index("User: question 11\n")
async def main():
path = Path(tempfile.mkdtemp()) / "journal.jsonl"
journal = Journal(path)
ctx = LLMContext()
ua, _ = LLMContextAggregatorPair(ctx, user_params=LLMUserAggregatorParams(
user_turn_strategies=UserTurnStrategies(
start=[ExternalUserTurnStartStrategy()], stop=[ExternalUserTurnStopStrategy()])))
worker = PipelineWorker(Pipeline([journal, ua]))
runner = WorkerRunner(handle_sigint=False)
await runner.add_workers(worker)
task = asyncio.create_task(runner.run())
await asyncio.sleep(0.3)
await worker.queue_frames([
TranscriptionFrame("what is the sample rate", "u", time_now_iso8601(), None)])
await asyncio.sleep(0.5)
journal.record_reply("Sixteen kilohertz.")
await asyncio.sleep(0.3)
await worker.queue_frames([EndFrame()])
await task
rows = [json.loads(l) for l in path.read_text().splitlines() if l.strip()]
print(f" {'PASS' if rows else 'FAIL'} journal file written ({len(rows)} entries)")
if rows:
r = rows[0]
print(f" {'PASS' if r['heard'] else 'FAIL'} captured what was heard: {r['heard']!r}")
print(f" {'PASS' if r['reply'] else 'FAIL'} captured the reply: {r['reply']!r}")
asyncio.run(main())