diff --git a/changelog/3457.changed.md b/changelog/3457.changed.md new file mode 100644 index 000000000..d0d82ad2d --- /dev/null +++ b/changelog/3457.changed.md @@ -0,0 +1 @@ +- Changed tool result JSON serialization to use `ensure_ascii=False`, preserving UTF-8 characters instead of escaping them. This reduces context size and token usage for non-English languages. diff --git a/src/pipecat/services/anthropic/llm.py b/src/pipecat/services/anthropic/llm.py index fcaed1dfe..2f375df82 100644 --- a/src/pipecat/services/anthropic/llm.py +++ b/src/pipecat/services/anthropic/llm.py @@ -1246,7 +1246,7 @@ class AnthropicAssistantContextAggregator(LLMAssistantContextAggregator): frame: Frame containing function call result. """ if frame.result: - result = json.dumps(frame.result) + result = json.dumps(frame.result, ensure_ascii=False) await self._update_function_call_result(frame.function_name, frame.tool_call_id, result) else: await self._update_function_call_result( diff --git a/src/pipecat/services/aws/llm.py b/src/pipecat/services/aws/llm.py index 59859abf7..92049dffb 100644 --- a/src/pipecat/services/aws/llm.py +++ b/src/pipecat/services/aws/llm.py @@ -691,7 +691,7 @@ class AWSBedrockAssistantContextAggregator(LLMAssistantContextAggregator): frame: The function call result frame to handle. """ if frame.result: - result = json.dumps(frame.result) + result = json.dumps(frame.result, ensure_ascii=False) await self._update_function_call_result(frame.function_name, frame.tool_call_id, result) else: await self._update_function_call_result( diff --git a/src/pipecat/services/aws/nova_sonic/llm.py b/src/pipecat/services/aws/nova_sonic/llm.py index b1f56dbbd..0947ba1d7 100644 --- a/src/pipecat/services/aws/nova_sonic/llm.py +++ b/src/pipecat/services/aws/nova_sonic/llm.py @@ -1044,7 +1044,9 @@ class AWSNovaSonicLLMService(LLMService): "toolResult": { "promptName": self._prompt_name, "contentName": content_name, - "content": json.dumps(result) if isinstance(result, dict) else result, + "content": json.dumps(result, ensure_ascii=False) + if isinstance(result, dict) + else result, } } } diff --git a/src/pipecat/services/google/llm.py b/src/pipecat/services/google/llm.py index 698b9f97f..26ad46311 100644 --- a/src/pipecat/services/google/llm.py +++ b/src/pipecat/services/google/llm.py @@ -200,7 +200,9 @@ class GoogleAssistantContextAggregator(OpenAIAssistantContextAggregator): if message.role == "user": for part in message.parts: if part.function_response and part.function_response.id == tool_call_id: - part.function_response.response = {"value": json.dumps(result)} + part.function_response.response = { + "value": json.dumps(result, ensure_ascii=False) + } @dataclass diff --git a/src/pipecat/services/grok/realtime/llm.py b/src/pipecat/services/grok/realtime/llm.py index bfa192aad..6e37d21d2 100644 --- a/src/pipecat/services/grok/realtime/llm.py +++ b/src/pipecat/services/grok/realtime/llm.py @@ -939,7 +939,7 @@ class GrokRealtimeLLMService(LLMService): item = events.ConversationItem( type="function_call_output", call_id=tool_call_id, - output=json.dumps(result), + output=json.dumps(result, ensure_ascii=False), ) await self.send_client_event(events.ConversationItemCreateEvent(item=item)) diff --git a/src/pipecat/services/openai/llm.py b/src/pipecat/services/openai/llm.py index abb3e7eec..553733922 100644 --- a/src/pipecat/services/openai/llm.py +++ b/src/pipecat/services/openai/llm.py @@ -255,7 +255,7 @@ class OpenAIAssistantContextAggregator(LLMAssistantContextAggregator): frame: Frame containing the function call result. """ if frame.result: - result = json.dumps(frame.result) + result = json.dumps(frame.result, ensure_ascii=False) await self._update_function_call_result(frame.function_name, frame.tool_call_id, result) else: await self._update_function_call_result( diff --git a/src/pipecat/services/openai/realtime/llm.py b/src/pipecat/services/openai/realtime/llm.py index faaa19884..bd31369ae 100644 --- a/src/pipecat/services/openai/realtime/llm.py +++ b/src/pipecat/services/openai/realtime/llm.py @@ -1128,7 +1128,7 @@ class OpenAIRealtimeLLMService(LLMService): item = events.ConversationItem( type="function_call_output", call_id=tool_call_id, - output=json.dumps(result), + output=json.dumps(result, ensure_ascii=False), ) await self.send_client_event(events.ConversationItemCreateEvent(item=item)) diff --git a/src/pipecat/services/openai_realtime_beta/openai.py b/src/pipecat/services/openai_realtime_beta/openai.py index 0a6315986..0d20039b1 100644 --- a/src/pipecat/services/openai_realtime_beta/openai.py +++ b/src/pipecat/services/openai_realtime_beta/openai.py @@ -441,7 +441,7 @@ class OpenAIRealtimeBetaLLMService(LLMService): item = events.ConversationItem( type="function_call_output", call_id=frame.tool_call_id, - output=json.dumps(frame.result), + output=json.dumps(frame.result, ensure_ascii=False), ) await self.send_client_event(events.ConversationItemCreateEvent(item=item))