smartfunc explicitly targets OpenAI-compatible providers (OpenRouter, Ollama, local/older models — README.md:32, :295), and many of those do not support response_format: {type: "json_schema", strict: True} (the block at smartfunc/__init__.py:135-146).
When the provider ignores structured output or returns prose / fenced JSON, this line:
# smartfunc/__init__.py:154 (and :283 async)
return self.response_format.model_validate_json(response_text)
raises a raw pydantic.ValidationError / JSON-decode error that never tells the user the provider can't do structured outputs. In an async + cached pipeline this is a confusing, silent-ish failure — and a None/empty return would get memoized by a caching layer, permanently poisoning the cache. Raising instead of returning is the cache-safe behaviour.
Fix
Add a small exception tree (exported from smartfunc):
class SmartfuncError(RuntimeError): ...
class StructuredOutputError(SmartfuncError): ...
Wrap the structured parse (lines 154 / 283) in try/except (pydantic.ValidationError, json.JSONDecodeError) and re-raise StructuredOutputError carrying: the raw response text, the model name, the target Pydantic class name, and the underlying error as __cause__. The message should hint that the provider may not support strict json_schema structured outputs.
Minor sub-case: if response_format is set and message.content is None, raise the same error rather than letting model_validate_json(None) throw opaquely. Keep the existing invalid-return-type error a plain ValueError (developer mistake, kept separate from model-failure exceptions).
No built-in retry loop for now (note as a possible future retries= option).
smartfunc explicitly targets OpenAI-compatible providers (OpenRouter, Ollama, local/older models —
README.md:32,:295), and many of those do not supportresponse_format: {type: "json_schema", strict: True}(the block atsmartfunc/__init__.py:135-146).When the provider ignores structured output or returns prose / fenced JSON, this line:
raises a raw
pydantic.ValidationError/ JSON-decode error that never tells the user the provider can't do structured outputs. In an async + cached pipeline this is a confusing, silent-ish failure — and aNone/empty return would get memoized by a caching layer, permanently poisoning the cache. Raising instead of returning is the cache-safe behaviour.Fix
Add a small exception tree (exported from
smartfunc):Wrap the structured parse (lines 154 / 283) in
try/except (pydantic.ValidationError, json.JSONDecodeError)and re-raiseStructuredOutputErrorcarrying: the raw response text, the model name, the target Pydantic class name, and the underlying error as__cause__. The message should hint that the provider may not support strictjson_schemastructured outputs.Minor sub-case: if
response_formatis set andmessage.contentisNone, raise the same error rather than lettingmodel_validate_json(None)throw opaquely. Keep the existing invalid-return-type error a plainValueError(developer mistake, kept separate from model-failure exceptions).No built-in retry loop for now (note as a possible future
retries=option).