69 lines
2.9 KiB
Python
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())
|