Skip to content

raise a typed StructuredOutputError when the backend can't produce the Pydantic type #17

Description

@koaning

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions