Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ollama/_types.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
successfully downloaded text file (SHA: 96529d630ff7a59b36b34bde5fd4ede7725c5ab4)
import contextlib
import json
from base64 import b64decode, b64encode
Expand Down Expand Up @@ -335,6 +336,9 @@ class ToolCall(SubscriptableBaseModel):
Model tool calls.
"""

id: Optional[str] = None
'ID of the tool call, when provided by the model/server.'

class Function(SubscriptableBaseModel):
"""
Tool call function.
Expand Down
36 changes: 35 additions & 1 deletion tests/test_type_serialization.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
successfully downloaded text file (SHA: f458cd23da2a4e195e4cb28f61e934cfb79a2c46)
import tempfile
from base64 import b64encode
from pathlib import Path

import pytest

from ollama._types import CreateRequest, Image
from ollama._types import CreateRequest, Image, Message


def test_image_serialization_bytes():
Expand Down Expand Up @@ -92,3 +93,36 @@ def test_create_request_serialization_license_list():
request = CreateRequest(model='test-model', license=['MIT', 'Apache-2.0'])
serialized = request.model_dump()
assert serialized['license'] == ['MIT', 'Apache-2.0']


def test_message_tool_call_id_preserved():
# Server responses include an 'id' on each tool call. Ensure it is parsed and kept.
message = Message.model_validate(
{
'role': 'assistant',
'content': '',
'tool_calls': [
{
'id': 'call_p7o2gz50',
'function': {'name': 'test_function', 'arguments': {'param1': 'test1', 'param2': 123}},
}
],
}
)
assert message.tool_calls is not None
assert message.tool_calls[0].id == 'call_p7o2gz50'
assert message.tool_calls[0].function.name == 'test_function'


def test_message_tool_call_id_defaults_to_none():
# When the server omits 'id', the field should default to None (backwards compatible).
message = Message.model_validate(
{
'role': 'assistant',
'tool_calls': [
{'function': {'name': 'test_function', 'arguments': {}}},
],
}
)
assert message.tool_calls is not None
assert message.tool_calls[0].id is None