Add warning when detecting context messages referring to missing tools
This commit is contained in:
@@ -129,4 +129,42 @@ class BaseLLMAdapter(ABC, Generic[TLLMInvocationParams]):
|
||||
# Fallback to return the same tools in case they are not in a standard format
|
||||
return tools
|
||||
|
||||
def _warn_about_orphaned_tool_messages(self, context: LLMContext) -> None:
|
||||
"""Warn if context contains messages referencing tools that aren't currently available.
|
||||
|
||||
This can happen when tools are removed/deactivated but the conversation history
|
||||
still contains function calls or tool responses for those tools. Such orphaned
|
||||
messages may cause API errors from the LLM provider.
|
||||
|
||||
Args:
|
||||
context: The LLM context to check.
|
||||
"""
|
||||
# Get the set of currently available tool names
|
||||
available_tool_names: set[str] = set()
|
||||
if isinstance(context.tools, ToolsSchema):
|
||||
available_tool_names = {tool.name for tool in context.tools.standard_tools}
|
||||
# Note: We don't check custom tools as they may have varying formats
|
||||
|
||||
# Track orphaned function names found in messages
|
||||
orphaned_tools: set[str] = set()
|
||||
|
||||
for message in self.get_messages(context):
|
||||
if isinstance(message, LLMSpecificMessage):
|
||||
# Skip LLM-specific messages for now
|
||||
continue
|
||||
|
||||
# Check for tool_calls in assistant messages
|
||||
if message.get("tool_calls"):
|
||||
for tc in message["tool_calls"]:
|
||||
func_name = tc.get("function", {}).get("name")
|
||||
if func_name and available_tool_names and func_name not in available_tool_names:
|
||||
orphaned_tools.add(func_name)
|
||||
|
||||
# Log warning for orphaned messages
|
||||
if orphaned_tools:
|
||||
logger.warning(
|
||||
f"Context contains references to tools that are no longer available: "
|
||||
f"{sorted(orphaned_tools)}. This may cause unexpected behavior or API errors."
|
||||
)
|
||||
|
||||
# TODO: we can move the logic to also handle the Messages here
|
||||
|
||||
@@ -59,6 +59,9 @@ class AnthropicLLMAdapter(BaseLLMAdapter[AnthropicLLMInvocationParams]):
|
||||
Returns:
|
||||
Dictionary of parameters for invoking Anthropic's LLM API.
|
||||
"""
|
||||
# Warn about orphaned tool-related messages
|
||||
self._warn_about_orphaned_tool_messages(context)
|
||||
|
||||
messages = self._from_universal_context_messages(self.get_messages(context))
|
||||
return {
|
||||
"system": messages.system,
|
||||
|
||||
@@ -83,6 +83,9 @@ class AWSNovaSonicLLMAdapter(BaseLLMAdapter[AWSNovaSonicLLMInvocationParams]):
|
||||
Returns:
|
||||
Dictionary of parameters for invoking AWS Nova Sonic's LLM API.
|
||||
"""
|
||||
# Warn about orphaned tool-related messages
|
||||
self._warn_about_orphaned_tool_messages(context)
|
||||
|
||||
messages = self._from_universal_context_messages(self.get_messages(context))
|
||||
return {
|
||||
"system_instruction": messages.system_instruction,
|
||||
|
||||
@@ -56,6 +56,9 @@ class AWSBedrockLLMAdapter(BaseLLMAdapter[AWSBedrockLLMInvocationParams]):
|
||||
Returns:
|
||||
Dictionary of parameters for invoking AWS Bedrock's LLM API.
|
||||
"""
|
||||
# Warn about orphaned tool-related messages
|
||||
self._warn_about_orphaned_tool_messages(context)
|
||||
|
||||
messages = self._from_universal_context_messages(self.get_messages(context))
|
||||
return {
|
||||
"system": messages.system,
|
||||
|
||||
@@ -62,6 +62,9 @@ class GeminiLLMAdapter(BaseLLMAdapter[GeminiLLMInvocationParams]):
|
||||
Returns:
|
||||
Dictionary of parameters for Gemini's API.
|
||||
"""
|
||||
# Warn about orphaned tool-related messages
|
||||
self._warn_about_orphaned_tool_messages(context)
|
||||
|
||||
messages = self._from_universal_context_messages(self.get_messages(context))
|
||||
return {
|
||||
"system_instruction": messages.system_instruction,
|
||||
|
||||
@@ -59,6 +59,9 @@ class GrokRealtimeLLMAdapter(BaseLLMAdapter):
|
||||
Returns:
|
||||
Dictionary of parameters for invoking Grok's Voice Agent API.
|
||||
"""
|
||||
# Warn about orphaned tool-related messages
|
||||
self._warn_about_orphaned_tool_messages(context)
|
||||
|
||||
messages = self._from_universal_context_messages(self.get_messages(context))
|
||||
return {
|
||||
"system_instruction": messages.system_instruction,
|
||||
|
||||
@@ -60,6 +60,9 @@ class OpenAILLMAdapter(BaseLLMAdapter[OpenAILLMInvocationParams]):
|
||||
Returns:
|
||||
Dictionary of parameters for OpenAI's ChatCompletion API.
|
||||
"""
|
||||
# Warn about orphaned tool-related messages
|
||||
self._warn_about_orphaned_tool_messages(context)
|
||||
|
||||
return {
|
||||
"messages": self._from_universal_context_messages(self.get_messages(context)),
|
||||
# NOTE; LLMContext's tools are guaranteed to be a ToolsSchema (or NOT_GIVEN)
|
||||
|
||||
@@ -54,6 +54,9 @@ class OpenAIRealtimeLLMAdapter(BaseLLMAdapter):
|
||||
Returns:
|
||||
Dictionary of parameters for invoking OpenAI Realtime's API.
|
||||
"""
|
||||
# Warn about orphaned tool-related messages
|
||||
self._warn_about_orphaned_tool_messages(context)
|
||||
|
||||
messages = self._from_universal_context_messages(self.get_messages(context))
|
||||
return {
|
||||
"system_instruction": messages.system_instruction,
|
||||
|
||||
Reference in New Issue
Block a user