Skip to content

Fix Pydantic content lowering for text messages and tool results #266

Description

@Kamilbenkirane

Problem

Message.content accepts Pydantic models, and ToolResult inherits that contract through Message. Some request builders currently lower Pydantic content incorrectly when preparing provider payloads.

The important boundary is text message/tool-result lowering, not a generic celeste.tools serialization helper:

  • Chat Completions and OpenResponses currently do message lowering from lower protocol tools.py modules that import Message / ToolResult.
  • That lowering belongs in the text modality protocol layer.
  • Anthropic, Google, and Cohere already lower messages in text provider clients and should be patched in place.

Use direct Pydantic APIs at the exact boundary:

  • BaseModel.model_dump_json() for provider fields that require JSON text.
  • BaseModel.model_dump(mode="json") for provider fields that accept JSON objects.
  • model_dump(mode="json", serialize_as_any=True, exclude_none=True) when dumping a Message that may contain nested Pydantic content.

Do not add a generic Celeste serialization helper. Serialization remains owned by Pydantic.

Definition of Done

  • Chat Completions serializes ToolResult(content=ToolOutput(...)) as JSON text.
  • OpenResponses serializes ToolResult(content=ToolOutput(...)) as JSON text.
  • Anthropic serializes ToolResult(content=ToolOutput(...)) as JSON text.
  • Google emits JSON-compatible object content for Pydantic tool results.
  • Cohere preserves nested Pydantic Message.content instead of dumping it as {}.
  • Plain string tool results keep existing behavior.
  • Focused tests cover the contract.

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