Rename elide_large_values to truncate_large_values
This commit is contained in:
@@ -1 +1 @@
|
||||
- Added `elide_large_values` parameter to `LLMContext.get_messages()`. When `True`, returns compact deep copies of messages with binary data (base64 images, audio) fully elided and long string values in LLM-specific messages recursively truncated. Useful for serialization, logging, and debugging tools.
|
||||
- Added `truncate_large_values` parameter to `LLMContext.get_messages()`. When `True`, returns compact deep copies of messages with binary data (base64 images, audio) fully truncated and long string values in LLM-specific messages recursively truncated. Useful for serialization, logging, and debugging tools.
|
||||
|
||||
@@ -126,20 +126,20 @@ class BaseLLMAdapter(ABC, Generic[TLLMInvocationParams]):
|
||||
return LLMSpecificMessage(llm=self.id_for_llm_specific_messages, message=message)
|
||||
|
||||
def get_messages(
|
||||
self, context: LLMContext, *, elide_large_values: bool = False
|
||||
self, context: LLMContext, *, truncate_large_values: bool = False
|
||||
) -> List[LLMContextMessage]:
|
||||
"""Get messages from the LLM context, including standard and LLM-specific messages.
|
||||
|
||||
Args:
|
||||
context: The LLM context containing messages.
|
||||
elide_large_values: If True, return deep copies of messages with
|
||||
truncate_large_values: If True, return deep copies of messages with
|
||||
large values replaced by short placeholders.
|
||||
|
||||
Returns:
|
||||
List of messages including standard and LLM-specific messages.
|
||||
"""
|
||||
return context.get_messages(
|
||||
self.id_for_llm_specific_messages, elide_large_values=elide_large_values
|
||||
self.id_for_llm_specific_messages, truncate_large_values=truncate_large_values
|
||||
)
|
||||
|
||||
def from_standard_tools(self, tools: Any) -> List[Any] | NotGiven:
|
||||
|
||||
@@ -85,7 +85,7 @@ class GrokRealtimeLLMAdapter(BaseLLMAdapter):
|
||||
Returns:
|
||||
List of messages with sensitive data redacted.
|
||||
"""
|
||||
return self.get_messages(context, elide_large_values=True)
|
||||
return self.get_messages(context, truncate_large_values=True)
|
||||
|
||||
@dataclass
|
||||
class ConvertedMessages:
|
||||
|
||||
@@ -85,7 +85,7 @@ class InworldRealtimeLLMAdapter(BaseLLMAdapter):
|
||||
Returns:
|
||||
List of messages with sensitive data redacted.
|
||||
"""
|
||||
return self.get_messages(context, elide_large_values=True)
|
||||
return self.get_messages(context, truncate_large_values=True)
|
||||
|
||||
@dataclass
|
||||
class ConvertedMessages:
|
||||
|
||||
@@ -126,7 +126,7 @@ class OpenAILLMAdapter(BaseLLMAdapter[OpenAILLMInvocationParams]):
|
||||
Returns:
|
||||
List of messages in a format ready for logging about OpenAI.
|
||||
"""
|
||||
return self.get_messages(context, elide_large_values=True)
|
||||
return self.get_messages(context, truncate_large_values=True)
|
||||
|
||||
def _from_universal_context_messages(
|
||||
self,
|
||||
|
||||
@@ -81,7 +81,7 @@ class OpenAIRealtimeLLMAdapter(BaseLLMAdapter):
|
||||
Returns:
|
||||
List of messages in a format ready for logging about OpenAI Realtime.
|
||||
"""
|
||||
return self.get_messages(context, elide_large_values=True)
|
||||
return self.get_messages(context, truncate_large_values=True)
|
||||
|
||||
@dataclass
|
||||
class ConvertedMessages:
|
||||
|
||||
@@ -143,7 +143,7 @@ class OpenAIResponsesLLMAdapter(BaseLLMAdapter[OpenAIResponsesLLMInvocationParam
|
||||
Returns:
|
||||
List of messages in a format ready for logging.
|
||||
"""
|
||||
return self.get_messages(context, elide_large_values=True)
|
||||
return self.get_messages(context, truncate_large_values=True)
|
||||
|
||||
def _convert_messages_to_input(
|
||||
self, messages: List[LLMContextMessage]
|
||||
|
||||
@@ -203,7 +203,7 @@ class LLMContext:
|
||||
self,
|
||||
llm_specific_filter: Optional[str] = None,
|
||||
*,
|
||||
elide_large_values: bool = False,
|
||||
truncate_large_values: bool = False,
|
||||
) -> List[LLMContextMessage]:
|
||||
"""Get the current messages list.
|
||||
|
||||
@@ -213,10 +213,10 @@ class LLMContext:
|
||||
messages. If messages end up being filtered, an error will be
|
||||
logged; this is intended to catch accidental use of
|
||||
incompatible LLM-specific messages.
|
||||
elide_large_values: If True, return deep copies of messages with
|
||||
truncate_large_values: If True, return deep copies of messages with
|
||||
large values replaced by short placeholders. For standard
|
||||
messages, known binary data (base64-encoded images, audio) is
|
||||
fully elided. For LLM-specific messages, long string values
|
||||
fully truncated. For LLM-specific messages, long string values
|
||||
are truncated.
|
||||
|
||||
Returns:
|
||||
@@ -235,19 +235,19 @@ class LLMContext:
|
||||
f"Attempted to use incompatible LLMSpecificMessages with LLM '{llm_specific_filter}'."
|
||||
)
|
||||
|
||||
if elide_large_values:
|
||||
messages = LLMContext._elide_large_values_from_messages(messages)
|
||||
if truncate_large_values:
|
||||
messages = LLMContext._truncate_large_values_from_messages(messages)
|
||||
|
||||
return messages
|
||||
|
||||
@staticmethod
|
||||
def _elide_large_values_from_messages(
|
||||
def _truncate_large_values_from_messages(
|
||||
messages: List[LLMContextMessage],
|
||||
) -> List[LLMContextMessage]:
|
||||
"""Return deep copies of messages with large values replaced by placeholders.
|
||||
|
||||
For standard (universal-format) messages, the following known binary
|
||||
patterns are fully elided:
|
||||
patterns are fully truncated:
|
||||
|
||||
- ``image_url`` items with ``data:image/...`` base64 URLs
|
||||
- ``input_audio`` items with ``input_audio.data`` or ``audio`` fields
|
||||
|
||||
@@ -15,13 +15,13 @@ from pipecat.processors.aggregators.llm_context import (
|
||||
)
|
||||
|
||||
|
||||
class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
"""Tests for LLMContext.get_messages(elide_large_values=True)."""
|
||||
class TestGetMessagesTruncateLargeValues(unittest.TestCase):
|
||||
"""Tests for LLMContext.get_messages(truncate_large_values=True)."""
|
||||
|
||||
# -- Standard messages: binary elision -----------------------------------
|
||||
|
||||
def test_default_preserves_all_data(self):
|
||||
"""elide_large_values defaults to False, preserving all data."""
|
||||
"""truncate_large_values defaults to False, preserving all data."""
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
@@ -57,7 +57,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result[0]["content"][0]["text"], "Describe this image")
|
||||
self.assertEqual(result[0]["content"][1]["image_url"]["url"], "data:image/...")
|
||||
@@ -76,7 +76,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(
|
||||
result[0]["content"][0]["image_url"]["url"],
|
||||
@@ -98,7 +98,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result[0]["content"][1]["input_audio"]["data"], "...")
|
||||
self.assertEqual(result[0]["content"][1]["input_audio"]["format"], "wav")
|
||||
@@ -115,7 +115,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result[0]["content"][0]["audio"], "...")
|
||||
self.assertEqual(result[0]["content"][1]["audio"], "...")
|
||||
@@ -130,7 +130,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result[0]["data"], "...")
|
||||
self.assertEqual(result[0]["mime_type"], "image/png")
|
||||
@@ -154,7 +154,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result[0]["content"][0]["text"], "Here is an image and audio")
|
||||
self.assertEqual(result[0]["content"][1]["image_url"]["url"], "data:image/...")
|
||||
@@ -168,7 +168,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
{"role": "assistant", "content": "Hi there!"},
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result, messages)
|
||||
|
||||
@@ -187,7 +187,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
_ = context.get_messages(elide_large_values=True)
|
||||
_ = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(
|
||||
context.get_messages()[0]["content"][0]["image_url"]["url"],
|
||||
@@ -216,7 +216,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
}
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result[0]["content"][0]["image_url"]["url"], "data:image/...")
|
||||
self.assertEqual(result[0]["content"][1]["image_url"]["url"], "data:image/...")
|
||||
@@ -226,7 +226,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_works_with_llm_specific_filter(self):
|
||||
"""elide_large_values works together with llm_specific_filter."""
|
||||
"""truncate_large_values works together with llm_specific_filter."""
|
||||
adapter = OpenAILLMAdapter()
|
||||
std_msg = {
|
||||
"role": "user",
|
||||
@@ -242,7 +242,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
)
|
||||
context = LLMContext(messages=[std_msg, specific_msg])
|
||||
|
||||
result = context.get_messages("openai", elide_large_values=True)
|
||||
result = context.get_messages("openai", truncate_large_values=True)
|
||||
|
||||
self.assertEqual(len(result), 2)
|
||||
self.assertEqual(result[0]["content"][0]["image_url"]["url"], "data:image/...")
|
||||
@@ -253,7 +253,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
{"role": "user", "content": "Just a string"},
|
||||
]
|
||||
context = LLMContext(messages=messages)
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(result[0]["content"], "Just a string")
|
||||
|
||||
@@ -265,7 +265,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
specific_msg = LLMSpecificMessage(llm="anthropic", message=inner)
|
||||
context = LLMContext(messages=[specific_msg])
|
||||
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertIsInstance(result[0], LLMSpecificMessage)
|
||||
self.assertEqual(result[0].message["type"], "thought")
|
||||
@@ -278,7 +278,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
specific_msg = LLMSpecificMessage(llm="anthropic", message=inner)
|
||||
context = LLMContext(messages=[specific_msg])
|
||||
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
msg = result[0].message
|
||||
self.assertEqual(msg["type"], "thought")
|
||||
@@ -298,7 +298,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
specific_msg = LLMSpecificMessage(llm="google", message=inner)
|
||||
context = LLMContext(messages=[specific_msg])
|
||||
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
msg = result[0].message
|
||||
self.assertEqual(msg["type"], "thought_signature")
|
||||
@@ -311,7 +311,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
specific_msg = LLMSpecificMessage(llm="test", message=inner)
|
||||
context = LLMContext(messages=[specific_msg])
|
||||
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
msg = result[0].message
|
||||
self.assertEqual(msg["items"][0], "short")
|
||||
@@ -323,7 +323,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
specific_msg = LLMSpecificMessage(llm="test", message=inner)
|
||||
context = LLMContext(messages=[specific_msg])
|
||||
|
||||
result = context.get_messages(elide_large_values=True)
|
||||
result = context.get_messages(truncate_large_values=True)
|
||||
|
||||
msg = result[0].message
|
||||
self.assertEqual(msg["count"], 42)
|
||||
@@ -337,7 +337,7 @@ class TestGetMessagesElideLargeValues(unittest.TestCase):
|
||||
specific_msg = LLMSpecificMessage(llm="anthropic", message=inner)
|
||||
context = LLMContext(messages=[specific_msg])
|
||||
|
||||
_ = context.get_messages(elide_large_values=True)
|
||||
_ = context.get_messages(truncate_large_values=True)
|
||||
|
||||
self.assertEqual(specific_msg.message["signature"], long_sig)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user