Port multi-task unit tests from pipecat-subagents
Brings over 215 tests across 15 files covering the new multi-task framework: BaseTask / PipelineTask bus lifecycle, job RPC and job groups, the bus message hierarchy and serializers, TaskBus + AsyncQueueBus + RedisBus + PgmqBus (with direct and isolated backends), TaskRegistry, the BusBridgeProcessor, the WebSocket proxy tasks, the LLMTask deferral logic, and the PipelineRunner spawn-and-attach flow.
This commit is contained in:
163
tests/test_frame_adapters.py
Normal file
163
tests/test_frame_adapters.py
Normal file
@@ -0,0 +1,163 @@
|
||||
#
|
||||
# Copyright (c) 2026, Daily
|
||||
#
|
||||
# SPDX-License-Identifier: BSD 2-Clause License
|
||||
#
|
||||
|
||||
import unittest
|
||||
|
||||
from pipecat.bus.messages import BusFrameMessage
|
||||
from pipecat.bus.serializers import JSONMessageSerializer
|
||||
from pipecat.frames.frames import LLMContextFrame, TextFrame, TranscriptionFrame
|
||||
from pipecat.processors.aggregators.llm_context import (
|
||||
LLMContext,
|
||||
LLMSpecificMessage,
|
||||
NotGiven,
|
||||
)
|
||||
from pipecat.processors.frame_processor import FrameDirection
|
||||
|
||||
|
||||
class TestTextFrameRoundTrip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serializer = JSONMessageSerializer()
|
||||
|
||||
def test_round_trip(self):
|
||||
msg = BusFrameMessage(
|
||||
source="a",
|
||||
frame=TextFrame(text="hello world"),
|
||||
direction=FrameDirection.DOWNSTREAM,
|
||||
)
|
||||
data = self.serializer.serialize(msg)
|
||||
restored = self.serializer.deserialize(data)
|
||||
|
||||
self.assertIsInstance(restored.frame, TextFrame)
|
||||
self.assertEqual(restored.frame.text, "hello world")
|
||||
|
||||
|
||||
class TestTranscriptionFrameRoundTrip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serializer = JSONMessageSerializer()
|
||||
|
||||
def test_round_trip_basic(self):
|
||||
msg = BusFrameMessage(
|
||||
source="a",
|
||||
frame=TranscriptionFrame(
|
||||
text="hello",
|
||||
user_id="user-1",
|
||||
timestamp="2026-03-17T00:00:00Z",
|
||||
),
|
||||
direction=FrameDirection.DOWNSTREAM,
|
||||
)
|
||||
data = self.serializer.serialize(msg)
|
||||
restored = self.serializer.deserialize(data)
|
||||
|
||||
self.assertIsInstance(restored.frame, TranscriptionFrame)
|
||||
self.assertEqual(restored.frame.text, "hello")
|
||||
self.assertEqual(restored.frame.user_id, "user-1")
|
||||
self.assertEqual(restored.frame.timestamp, "2026-03-17T00:00:00Z")
|
||||
self.assertIsNone(restored.frame.language)
|
||||
self.assertFalse(restored.frame.finalized)
|
||||
|
||||
def test_round_trip_with_language(self):
|
||||
from pipecat.transcriptions.language import Language
|
||||
|
||||
msg = BusFrameMessage(
|
||||
source="a",
|
||||
frame=TranscriptionFrame(
|
||||
text="hola",
|
||||
user_id="user-1",
|
||||
timestamp="2026-03-17T00:00:00Z",
|
||||
language=Language.ES,
|
||||
finalized=True,
|
||||
),
|
||||
direction=FrameDirection.DOWNSTREAM,
|
||||
)
|
||||
data = self.serializer.serialize(msg)
|
||||
restored = self.serializer.deserialize(data)
|
||||
|
||||
self.assertEqual(restored.frame.language, Language.ES)
|
||||
self.assertTrue(restored.frame.finalized)
|
||||
|
||||
|
||||
class TestLLMContextFrameRoundTrip(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.serializer = JSONMessageSerializer()
|
||||
|
||||
def _round_trip_context(self, ctx):
|
||||
msg = BusFrameMessage(
|
||||
source="a",
|
||||
frame=LLMContextFrame(context=ctx),
|
||||
direction=FrameDirection.DOWNSTREAM,
|
||||
)
|
||||
data = self.serializer.serialize(msg)
|
||||
restored = self.serializer.deserialize(data)
|
||||
self.assertIsInstance(restored.frame, LLMContextFrame)
|
||||
return restored.frame.context
|
||||
|
||||
def test_round_trip_messages_only(self):
|
||||
ctx = LLMContext(
|
||||
messages=[
|
||||
{"role": "system", "content": "You are helpful"},
|
||||
{"role": "user", "content": "hello"},
|
||||
]
|
||||
)
|
||||
restored = self._round_trip_context(ctx)
|
||||
|
||||
self.assertEqual(len(restored.messages), 2)
|
||||
self.assertEqual(restored.messages[0]["role"], "system")
|
||||
self.assertEqual(restored.messages[1]["content"], "hello")
|
||||
self.assertIsInstance(restored.tools, NotGiven)
|
||||
self.assertIsInstance(restored.tool_choice, NotGiven)
|
||||
|
||||
def test_round_trip_with_specific_message(self):
|
||||
ctx = LLMContext(
|
||||
messages=[
|
||||
{"role": "user", "content": "hi"},
|
||||
LLMSpecificMessage(llm="anthropic", message={"custom": "data"}),
|
||||
]
|
||||
)
|
||||
restored = self._round_trip_context(ctx)
|
||||
|
||||
self.assertEqual(len(restored.messages), 2)
|
||||
self.assertIsInstance(restored.messages[0], dict)
|
||||
self.assertIsInstance(restored.messages[1], LLMSpecificMessage)
|
||||
self.assertEqual(restored.messages[1].llm, "anthropic")
|
||||
self.assertEqual(restored.messages[1].message, {"custom": "data"})
|
||||
|
||||
def test_round_trip_with_tools(self):
|
||||
from pipecat.adapters.schemas.function_schema import FunctionSchema
|
||||
from pipecat.adapters.schemas.tools_schema import ToolsSchema
|
||||
|
||||
tools = ToolsSchema(
|
||||
standard_tools=[
|
||||
FunctionSchema(
|
||||
name="get_weather",
|
||||
description="Get the weather",
|
||||
properties={"location": {"type": "string"}},
|
||||
required=["location"],
|
||||
),
|
||||
]
|
||||
)
|
||||
ctx = LLMContext(
|
||||
messages=[{"role": "user", "content": "weather?"}],
|
||||
tools=tools,
|
||||
)
|
||||
restored = self._round_trip_context(ctx)
|
||||
|
||||
self.assertNotIsInstance(restored.tools, NotGiven)
|
||||
self.assertEqual(len(restored.tools.standard_tools), 1)
|
||||
self.assertEqual(restored.tools.standard_tools[0].name, "get_weather")
|
||||
self.assertEqual(restored.tools.standard_tools[0].required, ["location"])
|
||||
|
||||
def test_round_trip_with_tool_choice(self):
|
||||
ctx = LLMContext(
|
||||
messages=[{"role": "user", "content": "hi"}],
|
||||
tool_choice="auto",
|
||||
)
|
||||
restored = self._round_trip_context(ctx)
|
||||
|
||||
self.assertEqual(restored.tool_choice, "auto")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user