From c8cc38f657372e1ed65282cd074aab84f52f0f9a Mon Sep 17 00:00:00 2001 From: Deepanshu Pal <40927968+DeepanshuPal@users.noreply.github.com> Date: Wed, 7 Oct 2026 02:10:23 +0530 Subject: [PATCH 1/2] types: make ChatRequest serialization None-safe for tools without parameters --- ollama/_types.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ollama/_types.py b/ollama/_types.py index cf7264b5..5c0ff7bf 100644 --- a/ollama/_types.py +++ b/ollama/_types.py @@ -390,8 +390,9 @@ def serialize_model(self, nxt): output = nxt(self) if output.get('tools'): for tool in output['tools']: - if 'function' in tool and 'parameters' in tool['function'] and 'defs' in tool['function']['parameters']: - tool['function']['parameters']['$defs'] = tool['function']['parameters'].pop('defs') + parameters = (tool.get('function') or {}).get('parameters') + if parameters and 'defs' in parameters: + parameters['$defs'] = parameters.pop('defs') return output messages: Optional[Sequence[Union[Mapping[str, Any], Message]]] = None From c11bce679606631460e8603e4cc1ebf3988f92e8 Mon Sep 17 00:00:00 2001 From: Deepanshu Pal <40927968+DeepanshuPal@users.noreply.github.com> Date: Wed, 7 Oct 2026 02:11:00 +0530 Subject: [PATCH 2/2] tests: cover ChatRequest serialization with tools missing function or parameters Add tests for ChatRequest serialization with tools and parameters. --- tests/test_type_serialization.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/test_type_serialization.py b/tests/test_type_serialization.py index e1af3512..319b2354 100644 --- a/tests/test_type_serialization.py +++ b/tests/test_type_serialization.py @@ -4,7 +4,7 @@ import pytest -from ollama._types import ChatRequest, CreateRequest, GenerateRequest, Image +from ollama._types import ChatRequest, CreateRequest, GenerateRequest, Image, Tool def test_image_serialization_bytes(): @@ -122,3 +122,17 @@ def test_think_boolean_serialization(): assert ChatRequest(model='test-model', think=True).model_dump(exclude_none=True)['think'] is True assert ChatRequest(model='test-model', think=False).model_dump(exclude_none=True)['think'] is False assert 'think' not in ChatRequest(model='test-model', think=None).model_dump(exclude_none=True) + + +def test_chat_request_dump_with_tools_missing_function_or_parameters(): + req = ChatRequest(model='test-model', tools=[Tool(function=Tool.Function(name='f')), Tool()]) + assert req.model_dump()['tools'][0]['function']['name'] == 'f' + assert req.model_dump(exclude_none=True)['tools'][0]['function'] == {'name': 'f'} + assert 'tools' in req.model_dump_json() + + +def test_chat_request_renames_defs_for_tool_parameters(): + tool = Tool(function=Tool.Function(name='f', parameters=Tool.Function.Parameters(defs={'A': {'type': 'string'}}))) + params = ChatRequest(model='test-model', tools=[tool]).model_dump()['tools'][0]['function']['parameters'] + assert params['$defs'] == {'A': {'type': 'string'}} + assert 'defs' not in params