Compare commits
2 commits
f6ce97d7fd
...
9c73895318
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c73895318 | |||
| 2efc4d1088 |
2 changed files with 20 additions and 11 deletions
|
|
@ -159,7 +159,21 @@ class OllamaClient:
|
|||
request_kwargs: dict[str, Any],
|
||||
response_schema: type[BaseModel],
|
||||
) -> dict[str, Any]:
|
||||
"""Map provider-neutral kwargs to Ollama's /api/chat body."""
|
||||
"""Map provider-neutral kwargs to Ollama's /api/chat body.
|
||||
|
||||
Schema strategy for Ollama 0.11.8: we pass ``format="json"`` (loose
|
||||
JSON mode) rather than the full Pydantic schema. The llama.cpp
|
||||
structured-output implementation in 0.11.8 segfaults on schemas
|
||||
involving ``anyOf``, ``$ref``, or ``pattern`` — which Pydantic v2
|
||||
emits for Optional / nested-model / Decimal fields.
|
||||
|
||||
In loose JSON mode Ollama guarantees only syntactically-valid
|
||||
JSON; we enforce the schema on our side by catching the Pydantic
|
||||
``ValidationError`` at parse time and raising IX_002_001. The
|
||||
system prompt (built upstream in GenAIStep) already tells the
|
||||
model what JSON shape to emit, so loose mode is the right
|
||||
abstraction layer here.
|
||||
"""
|
||||
|
||||
messages = self._translate_messages(
|
||||
list(request_kwargs.get("messages") or [])
|
||||
|
|
@ -168,9 +182,7 @@ class OllamaClient:
|
|||
"model": request_kwargs.get("model"),
|
||||
"messages": messages,
|
||||
"stream": False,
|
||||
"format": _sanitise_schema_for_ollama(
|
||||
response_schema.model_json_schema()
|
||||
),
|
||||
"format": "json",
|
||||
}
|
||||
|
||||
options: dict[str, Any] = {}
|
||||
|
|
|
|||
|
|
@ -79,13 +79,10 @@ class TestInvokeHappyPath:
|
|||
body_json = json.loads(body)
|
||||
assert body_json["model"] == "gpt-oss:20b"
|
||||
assert body_json["stream"] is False
|
||||
# Format is the pydantic schema with Optional `anyOf [T, null]`
|
||||
# patterns collapsed to just T — Ollama 0.11.8 segfaults on the
|
||||
# anyOf+null shape, so we sanitise before sending.
|
||||
fmt = body_json["format"]
|
||||
assert fmt["properties"]["bank_name"] == {"title": "Bank Name", "type": "string"}
|
||||
assert fmt["properties"]["account_number"]["type"] == "string"
|
||||
assert "anyOf" not in fmt["properties"]["account_number"]
|
||||
# format is "json" (loose mode): Ollama 0.11.8 segfaults on full
|
||||
# Pydantic schemas. We pass the schema via the system prompt
|
||||
# upstream and validate on parse.
|
||||
assert body_json["format"] == "json"
|
||||
assert body_json["options"]["temperature"] == 0.2
|
||||
assert "reasoning_effort" not in body_json
|
||||
assert body_json["messages"] == [
|
||||
|
|
|
|||
Loading…
Reference in a new issue