fix: compare bound method by equality, not identity

Bound methods are created fresh on each attribute access, so
'self._missing_function_call_handler is self._missing_function_call_handler'
is always False. Using 'is' meant the placeholder branch never fired and
both warnings logged when a function was missing at queue time.

Switch to == so equality compares the underlying function and instance.
Strengthen the missing-at-queue-time test to assert the second warning
does not fire.
This commit is contained in:
borislav
2026-04-27 17:34:31 +02:00
parent 822392b0d4
commit 8869e25142
2 changed files with 19 additions and 12 deletions

View File

@@ -792,7 +792,7 @@ class LLMService(UserTurnCompletionLLMServiceMixin, AIService):
item = self._functions[runner_item.function_name]
elif None in self._functions.keys():
item = self._functions[None]
elif runner_item.registry_item.handler is self._missing_function_call_handler:
elif runner_item.registry_item.handler == self._missing_function_call_handler:
item = runner_item.registry_item
else:
logger.warning(

View File

@@ -5,7 +5,7 @@
#
import unittest
from unittest.mock import AsyncMock
from unittest.mock import AsyncMock, patch
from pipecat.frames.frames import (
FunctionCallFromLLM,
@@ -60,16 +60,17 @@ class TestLLMService(unittest.IsolatedAsyncioTestCase):
service.broadcast_frame = mock_broadcast_frame
await service.run_function_calls(
[
FunctionCallFromLLM(
function_name="missing_tool",
tool_call_id="call_1",
arguments={"query": "weather"},
context=LLMContext(),
)
]
)
with patch("pipecat.services.llm_service.logger") as mock_logger:
await service.run_function_calls(
[
FunctionCallFromLLM(
function_name="missing_tool",
tool_call_id="call_1",
arguments={"query": "weather"},
context=LLMContext(),
)
]
)
self.assertEqual(
[type(frame) for frame in recorded_frames],
@@ -85,6 +86,12 @@ class TestLLMService(unittest.IsolatedAsyncioTestCase):
"Error: function 'missing_tool' is not registered.",
)
# Only the queue-time warning should fire; the execution-time
# "just unregistered" warning must not double-log.
warnings = [c.args[0] for c in mock_logger.warning.call_args_list]
self.assertTrue(any("not registered" in w for w in warnings))
self.assertFalse(any("just unregistered" in w for w in warnings))
async def test_function_unregistered_between_queue_and_execute(self):
"""Function unregistered between queuing and execution still terminates."""
service = MockLLMService()