feat: organize tools and enable qwen realtime calls

This commit is contained in:
Xin Wang
2026-08-14 00:15:00 +08:00
parent eb111a3890
commit 5be21f5ccc
71 changed files with 5771 additions and 2026 deletions
+28 -11
View File
@@ -1,7 +1,7 @@
import asyncio
import unittest
from models import RuntimeTool
from models import RuntimeTool, RuntimeToolBinding
from pipecat.frames.frames import (
CancelFrame,
EndFrame,
@@ -34,9 +34,6 @@ def client_tool() -> RuntimeTool:
}
],
"timeout_seconds": 3,
"dynamic_variable_assignments": {
"photo_button_visible": "visible"
},
},
},
)
@@ -47,6 +44,9 @@ class FakeClientTools:
self.result = result
self.calls = []
def supports(self, _function_name):
return True
async def call(
self,
function_name,
@@ -80,12 +80,9 @@ class ClientToolExecutorTests(unittest.IsolatedAsyncioTestCase):
"session",
)
def test_fire_and_forget_rejects_result_assignments(self):
with self.assertRaisesRegex(ValueError, "不能配置结果变量赋值"):
ClientToolConfig(
wait_for_response=False,
dynamic_variable_assignments={"visible": "visible"},
)
def test_result_assignments_are_not_a_resource_setting(self):
config = ClientToolConfig(wait_for_response=False)
self.assertNotIn("dynamic_variable_assignments", ClientToolConfig.model_fields)
async def test_success_updates_configured_variable(self):
store = DynamicVariableStore(
@@ -95,7 +92,15 @@ class ClientToolExecutorTests(unittest.IsolatedAsyncioTestCase):
port = FakeClientTools({"status": "ok", "data": {"visible": True}})
executor = ToolExecutor(store, client_tools=port)
result = await executor.execute(client_tool(), {"visible": True})
result = await executor.execute(
client_tool(),
{"visible": True},
binding=RuntimeToolBinding(
toolId="tool_photo_button",
argumentBindings={"visible": {"source": "model"}},
resultAssignments={"photo_button_visible": "visible"},
),
)
self.assertEqual(result["updated_variables"], ["photo_button_visible"])
self.assertIs(store.values["photo_button_visible"], True)
@@ -138,6 +143,18 @@ class ClientToolExecutorTests(unittest.IsolatedAsyncioTestCase):
class ClientToolBrokerTests(unittest.IsolatedAsyncioTestCase):
async def test_capability_handshake_rejects_unregistered_tool_immediately(self):
broker = ClientToolBroker()
broker.set_capabilities({"show_message"})
with self.assertRaisesRegex(ClientToolError, "未注册"):
await broker.call(
"set_photo_button_visible",
{"visible": True},
timeout_seconds=30,
)
self.assertEqual(broker._pending, {})
async def test_uses_configured_downstream_interrupt_handler(self):
broker = ClientToolBroker()
outbound = []