Skip to content

Move _transform_output from provider _parse_content to base _predict pipeline #142

Description

@Kamilbenkirane

Problem

_transform_output() is currently called inside each provider's _parse_content() method rather than at the base _predict() pipeline level. Every provider must independently remember to call self._transform_output() as the final step in _parse_content(). If any provider forgets, structured output parsing (JSON schema, Pydantic model extraction) silently breaks — no error, just raw text returned instead of a parsed object.

All 10 current text providers do it correctly, but this is a landmine for new provider implementations.

Current call chain (fragile):
```
ModalityClient._predict()
→ ProviderTextClient._parse_content(response_data, **parameters)
→ ProviderAPIMixin._parse_content(response_data) # extract raw structure
→ self._transform_output(text, **parameters) # each provider must remember this
```

Proposed call chain (safe):
```
ModalityClient._predict()
→ self._parse_content(response_data) # no **parameters needed
→ self._transform_output(raw_content, **parameters) # guaranteed at base level
```

Affected Files

  • src/celeste/client.py — move _transform_output call into _predict()
  • src/celeste/modalities/text/providers/*/client.py — remove _transform_output call from each provider's _parse_content() (10 providers)
  • Remove **parameters from _parse_content signature (no longer needed)

Impact

  • Prevents silent failures when adding new providers
  • Reduces boilerplate in every provider implementation
  • Streaming path already does this correctly (TextStream._parse_output calls _transform_output at the base level)
  • Aligns non-streaming path with the streaming path's design

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions