Skip to content

[Platform] Share one result (de)normalizer between the cache bridge and recording #2413

Description

@wachterjohannes

Follow-up from @chr-hertel's review on #2129.

Two classes turn a finished ResultInterface into something storable and back:

  • Bridge\Cache\ResultNormalizer covers BinaryResult, ChoiceResult, MultiPartResult, ThinkingResult, ObjectResult, TextResult, ToolCallResult and VectorResult, and deliberately throws on StreamResult. Shape: ['class' => FQCN, 'payload' => ...], built on the Symfony Serializer with an injected ObjectNormalizer.
  • Test\Recording\ResultSerializer ([Platform] Add provider-level record/replay cassettes for test mocks #2129) covers text, object, vector, tool calls and text streams. Shape: ['type' => 'text'|'object'|...], plain static, no serializer.

Four of the five recording types are already covered by the cache one, so this should be a single implementation in the platform core that both use, gaining stream support on one side and the four missing result types on the other.

What makes it its own PR rather than a change to #2129: ResultNormalizer sits in the symfony/ai-cache-platform bridge while Test\Recording sits in the core package, so reuse today would point the core at a bridge. Moving the class down into symfony/ai-platform is a BC break for the bridge and needs a deprecation alias plus an UPGRADE.md entry.

Open questions for whoever picks this up: which serialized shape wins (the FQCN-keyed one is more extensible, a short type key diffs better in a committed cassette), and whether the merged class keeps the cache bridge's refusal to serialize a stream at its own call site.

Metadata

Metadata

Assignees

No one assigned

    Labels

    PlatformIssues & PRs about the AI Platform component

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions