diff --git a/ollama/_types.py b/ollama/_types.py index 96529d63..d9f0ad4f 100644 --- a/ollama/_types.py +++ b/ollama/_types.py @@ -346,6 +346,9 @@ class Function(SubscriptableBaseModel): arguments: Mapping[str, Any] 'Arguments of the function.' + id: Optional[str] = None + 'Identifier of the tool call, when provided by the server.' + function: Function 'Function to be called.' diff --git a/tests/test_type_serialization.py b/tests/test_type_serialization.py index f458cd23..d2ac0b6a 100644 --- a/tests/test_type_serialization.py +++ b/tests/test_type_serialization.py @@ -4,7 +4,7 @@ import pytest -from ollama._types import CreateRequest, Image +from ollama._types import CreateRequest, Image, Message def test_image_serialization_bytes(): @@ -31,6 +31,22 @@ def test_image_serialization_plain_string(): assert img.model_dump() == 'not a path or base64' # Should return as-is +def test_tool_call_id_round_trips(): + # The server sends an `id` on each tool call (e.g. "call_p7o2gz50"); it must survive parsing. + message = Message( + role='assistant', + tool_calls=[{'id': 'call_p7o2gz50', 'function': {'name': 'test_function', 'arguments': {'param1': 'test1'}}}], + ) + assert message.tool_calls[0].id == 'call_p7o2gz50' + assert message.tool_calls[0].function.name == 'test_function' + assert message.model_dump()['tool_calls'][0]['id'] == 'call_p7o2gz50' + + +def test_tool_call_id_defaults_to_none(): + message = Message(role='assistant', tool_calls=[{'function': {'name': 'f', 'arguments': {}}}]) + assert message.tool_calls[0].id is None + + def test_image_serialization_path(): with tempfile.NamedTemporaryFile() as temp_file: temp_file.write(b'test file content')