Description
OllamaChatClient forwards response_format straight to Ollama's format parameter without converting a Pydantic model class to its JSON schema. Ollama's format only accepts '', 'json', or a JSON-schema dict, so passing a model class — the form OpenAIChatClient/FoundryChatClient accept, and the form create_harness_agent's plan mode uses — raises a validation error at request-construction time, before the request is ever sent.
Net effect: structured output via a model class doesn't work on Ollama, and harness plan mode (create_harness_agent + PlanningOutputObserver) crashes on every Ollama model.
Code Sample
import asyncio
from agent_framework import Message
from agent_framework.ollama import OllamaChatClient
from pydantic import BaseModel
class Plan(BaseModel):
summary: str
steps: list[str]
async def main() -> None:
client = OllamaChatClient(model="llama3.2")
msgs = [Message(role="user", contents=["Give a 2-step plan to host a static site on Azure."])]
# FAILS: response_format as a Pydantic model class (what the harness plan mode passes)
await client.get_response(msgs, options={"response_format": Plan})
# WORKS: response_format as a JSON-schema dict
# await client.get_response(msgs, options={"response_format": Plan.model_json_schema()})
asyncio.run(main())
Error Messages / Stack Traces
Ollama chat request failed : 2 validation errors for ChatRequest
format.literal['','json']
Input should be '' or 'json' [type=literal_error, input_value=<class '__main__.Plan'>, input_type=ModelMetaclass]
format.dict
Input should be a valid dictionary [type=dict_type, ...]
Package Versions
agent-framework-core:1.9.0, agent-framework-ollama:1.0.0b260521
Python Version
Python 3.12.10
Additional Context
Expected
Passing a Pydantic model class as response_format produces structured output, consistent with OpenAIChatClient / FoundryChatClient (which accept a model class) and with create_harness_agent plan mode, which sets response_format to a model class.
Actual
ChatClientException wrapping a pydantic ValidationError for the ollama-python ChatRequest.format:
Ollama chat request failed : 2 validation errors for ChatRequest
format.literal['','json']
Input should be '' or 'json' [type=literal_error, input_value=<class '__main__.Plan'>, input_type=ModelMetaclass]
format.dict
Input should be a valid dictionary [type=dict_type, ...]
It fails while building the request, so it's model-independent (a larger/cloud model behaves identically), and no call reaches Ollama.
Root cause
In python/packages/ollama/agent_framework_ollama/_chat_client.py, the option is remapped and the value passed through unchanged:
OLLAMA_OPTION_TRANSLATIONS: dict[str, str] = {
"response_format": "format",
}
...
# in _prepare_options:
translated_key = OLLAMA_OPTION_TRANSLATIONS.get(key, key)
run_options[translated_key] = value # value may be a Pydantic model class
Ollama-python's ChatRequest.format is typed as Literal['', 'json'] | JsonSchemaValue (a dict). A Pydantic model class is neither, hence the validation error. (Ollama's documented structured-output usage is format=Model.model_json_schema() — see https://ollama.com/blog/structured-outputs.)
Impact
- Any caller passing a Pydantic model class as
response_format to OllamaChatClient.
create_harness_agent plan mode: PlanningOutputObserver sets response_format to a model class, so the harness console sample (python/samples/02-agents/harness) errors on every turn when run against Ollama.
- Inconsistent behavior across providers (OpenAI/Foundry accept a model class; Ollama does not).
Suggested fix
When mapping response_format → format, convert a Pydantic model class (or instance type) to its JSON schema, keeping the existing '' / 'json' / dict pass-through. For example, in _prepare_options:
from pydantic import BaseModel
value = options.get("response_format")
if isinstance(value, type) and issubclass(value, BaseModel):
value = value.model_json_schema()
# then assign `value` to run_options["format"]
Convert only the outgoing format; keep the original response_format on the value used to parse the response back so typed parsing (ChatResponse.value) still works.
Workaround
Subclass OllamaChatClient and override _prepare_options to perform the conversion before delegating to super(). Verified: with the conversion, a model-class response_format returns valid structured JSON and parses back into the model; without it, the error above occurs.
Description
OllamaChatClientforwardsresponse_formatstraight to Ollama'sformatparameter without converting a Pydantic model class to its JSON schema. Ollama'sformatonly accepts'','json', or a JSON-schema dict, so passing a model class — the formOpenAIChatClient/FoundryChatClientaccept, and the formcreate_harness_agent's plan mode uses — raises a validation error at request-construction time, before the request is ever sent.Net effect: structured output via a model class doesn't work on Ollama, and harness plan mode (
create_harness_agent+PlanningOutputObserver) crashes on every Ollama model.Code Sample
import asyncio from agent_framework import Message from agent_framework.ollama import OllamaChatClient from pydantic import BaseModel class Plan(BaseModel): summary: str steps: list[str] async def main() -> None: client = OllamaChatClient(model="llama3.2") msgs = [Message(role="user", contents=["Give a 2-step plan to host a static site on Azure."])] # FAILS: response_format as a Pydantic model class (what the harness plan mode passes) await client.get_response(msgs, options={"response_format": Plan}) # WORKS: response_format as a JSON-schema dict # await client.get_response(msgs, options={"response_format": Plan.model_json_schema()}) asyncio.run(main())Error Messages / Stack Traces
Package Versions
agent-framework-core:1.9.0, agent-framework-ollama:1.0.0b260521
Python Version
Python 3.12.10
Additional Context
Expected
Passing a Pydantic model class as
response_formatproduces structured output, consistent withOpenAIChatClient/FoundryChatClient(which accept a model class) and withcreate_harness_agentplan mode, which setsresponse_formatto a model class.Actual
ChatClientExceptionwrapping a pydanticValidationErrorfor the ollama-pythonChatRequest.format:It fails while building the request, so it's model-independent (a larger/cloud model behaves identically), and no call reaches Ollama.
Root cause
In
python/packages/ollama/agent_framework_ollama/_chat_client.py, the option is remapped and the value passed through unchanged:Ollama-python's
ChatRequest.formatis typed asLiteral['', 'json'] | JsonSchemaValue(a dict). A Pydantic model class is neither, hence the validation error. (Ollama's documented structured-output usage isformat=Model.model_json_schema()— see https://ollama.com/blog/structured-outputs.)Impact
response_formattoOllamaChatClient.create_harness_agentplan mode:PlanningOutputObserversetsresponse_formatto a model class, so the harness console sample (python/samples/02-agents/harness) errors on every turn when run against Ollama.Suggested fix
When mapping
response_format→format, convert a Pydantic model class (or instance type) to its JSON schema, keeping the existing''/'json'/ dict pass-through. For example, in_prepare_options:Convert only the outgoing
format; keep the originalresponse_formaton the value used to parse the response back so typed parsing (ChatResponse.value) still works.Workaround
Subclass
OllamaChatClientand override_prepare_optionsto perform the conversion before delegating tosuper(). Verified: with the conversion, a model-classresponse_formatreturns valid structured JSON and parses back into the model; without it, the error above occurs.