Skip to content

Commit c2ba3d0

Browse files
committed
fix: use fallback for json.dumps in build_tool_calls
Use str to non-serializable types. This should effectively avoid TypeError (in normal situations). Signed-off-by: Mark Sturdevant <mark.sturdevant@ibm.com>
1 parent e710a96 commit c2ba3d0

2 files changed

Lines changed: 31 additions & 3 deletions

File tree

mellea/helpers/openai_compatible_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ def build_tool_calls(output: ModelOutputThunk) -> list[ToolCallDict] | None:
286286
# Generate a unique ID for this tool call
287287
tool_call_id = f"call_{uuid.uuid4().hex[:24]}"
288288

289-
# Serialize the arguments to JSON string
290-
args_json = json.dumps(model_tool_call.args)
289+
# Serialize arguments to JSON with str fallback for non-serializable types
290+
args_json = json.dumps(model_tool_call.args, default=str)
291291

292292
tool_call: ToolCallDict = {
293293
"id": tool_call_id,

test/helpers/test_openai_compatible_helpers.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22

33
import base64
44
import json
5+
from datetime import datetime
6+
from decimal import Decimal
57

68
import pytest
79

810
from mellea.backends.tools import MelleaTool
9-
from mellea.core.base import ImageBlock
11+
from mellea.core.base import ImageBlock, ModelOutputThunk, ModelToolCall
1012
from mellea.helpers.openai_compatible_helpers import (
13+
build_tool_calls,
1114
chat_completion_delta_merge,
1215
extract_model_tool_requests,
1316
message_to_openai_message,
@@ -359,5 +362,30 @@ def test_docs_across_messages(self):
359362
assert result[1]["text"] == "b"
360363

361364

365+
# --- build_tool_calls ---
366+
367+
368+
class TestBuildToolCalls:
369+
def test_with_non_json_serializable_args(self):
370+
"""Non-JSON-serializable values (datetime, Decimal) are converted to strings."""
371+
tool = _make_tool("test_tool")
372+
tool_call = ModelToolCall(
373+
name="test_tool",
374+
func=tool,
375+
args={"timestamp": datetime(2024, 1, 15), "amount": Decimal("123.45")},
376+
)
377+
output = ModelOutputThunk(value="test", tool_calls={"test_tool": tool_call})
378+
379+
result = build_tool_calls(output)
380+
381+
assert result is not None
382+
assert len(result) == 1
383+
# Verify arguments are valid JSON and values were converted to strings
384+
args = json.loads(result[0]["function"]["arguments"])
385+
assert isinstance(args["timestamp"], str)
386+
assert "2024-01-15" in args["timestamp"]
387+
assert args["amount"] == "123.45"
388+
389+
362390
if __name__ == "__main__":
363391
pytest.main([__file__])

0 commit comments

Comments
 (0)