Skip to content

Conversation

@wachterjohannes
Copy link
Contributor

@wachterjohannes wachterjohannes commented Feb 4, 2026

Q A
Bug fix? no
New feature? yes
Docs? yes
Issues Fix #1545
License MIT

Summary

This change implements two features for structured output:

  1. Object instances in response_format option

    • PlatformSubscriber now accepts both class-string and object instances
    • Uses Symfony Serializer's OBJECT_TO_POPULATE context
    • Preserves object identity (same instance returned)
    • Allows AI to populate missing data in partially-instantiated objects
  2. Object parameters in Message::ofUser()

    • Accepts objects as last parameter for automatic context serialization
    • Object is JSON-serialized and appended to message content
    • Provides AI with current object state as context
    • Stores object reference in message metadata

Usage example:

$city = new City(name: 'Berlin'); // Partial object
$messages = new MessageBag(
    Message::ofUser('Research missing data for this city', $city),
);
$result = $platform->invoke($messages, [
    'response_format' => $city,
]);
// Returns same instance with all fields populated

Fixes #1545

@wachterjohannes wachterjohannes changed the title Add support for object instances in structured output [Platform]Add support for object instances in structured output Feb 4, 2026
@wachterjohannes wachterjohannes changed the title [Platform]Add support for object instances in structured output [Platform] Add support for object instances in structured output Feb 4, 2026
This change implements two features for structured output:

1. Object instances in response_format option
   - PlatformSubscriber now accepts both class-string and object instances
   - Uses Symfony Serializer's OBJECT_TO_POPULATE context
   - Preserves object identity (same instance returned)
   - Allows AI to populate missing data in partially-instantiated objects

2. Object parameters in Message::ofUser()
   - Accepts objects as last parameter for automatic context serialization
   - Object is JSON-serialized and appended to message content
   - Provides AI with current object state as context
   - Stores object reference in message metadata

Usage example:
```php
$city = new City(name: 'Berlin'); // Partial object
$messages = new MessageBag(
    Message::ofUser('Research missing data for this city', $city),
);
$result = $platform->invoke($messages, [
    'response_format' => $city,
]);
// Returns same instance with all fields populated
```

Fixes symfony#1545
@wachterjohannes wachterjohannes force-pushed the feature/structured-output-object-instances branch from 5041847 to 54c8a96 Compare February 4, 2026 21:25
- Move City class from example to fixtures for cleaner code
- Use dump() instead of var_dump() for consistency
- Use Platform's InvalidArgumentException instead of native PHP exception
@wachterjohannes wachterjohannes force-pushed the feature/structured-output-object-instances branch from 2e14dfa to 7b34daf Compare February 4, 2026 21:39
@wachterjohannes wachterjohannes marked this pull request as ready for review February 4, 2026 21:40
@carsonbot carsonbot added Feature New feature Platform Issues & PRs about the AI Platform component Status: Needs Review labels Feb 4, 2026
Comment on lines +532 to +536
The AI will populate the missing fields while preserving any existing values. This is particularly useful for:

- Enriching partial data from databases
- Updating incomplete records
- Progressive data collection workflows
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i feel stuff like that would rather belong in a cookbook article

@chr-hertel
Copy link
Member

gosh, i feel like we're giving Kai Wegner too much visibility - we should keep in mind to update this after the elections in September

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for populating existing object instances in structured output and passing objects to user messages for context serialization. It implements the feature requested in issue #1545, allowing developers to provide partially-filled objects that the AI can complete.

Changes:

  • Added object instance support in response_format option using Symfony Serializer's OBJECT_TO_POPULATE context
  • Extended Message::ofUser() to accept objects as the last parameter for automatic JSON serialization as context
  • Comprehensive test coverage for both features including edge cases

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/platform/tests/StructuredOutput/ResultConverterTest.php New comprehensive test suite for ResultConverter with object population scenarios
src/platform/tests/StructuredOutput/PlatformSubscriberTest.php Added tests for object instance handling, state management, and edge cases
src/platform/tests/Message/MessageTest.php Added tests for object parameter serialization in Message::ofUser()
src/platform/tests/Fixtures/StructuredOutput/City.php New test fixture class representing a city with optional properties
src/platform/src/StructuredOutput/ResultConverter.php Added objectToPopulate parameter to support instance population via Serializer
src/platform/src/StructuredOutput/PlatformSubscriber.php Added logic to detect and handle object instances vs class strings in response_format
src/platform/src/Message/Message.php Extended ofUser() to detect objects and automatically serialize them as context
src/platform/CHANGELOG.md Documented the new features for version 0.3
examples/platform/structured-output-populate-object.php Added example demonstrating the object population feature
docs/components/platform.rst Added comprehensive documentation with examples for both features

Copy link
Contributor

@VincentLanglet VincentLanglet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about Stringable object, should they be considered as an Object instance or transformed to string to get the "class" expected.

Do we agree we're having a BC break here ?

@wachterjohannes
Copy link
Contributor Author

@VincentLanglet you are absolutly right - we should think of adding a new Message::ofUserWithContext to avoid the BC break - @chr-hertel what do you think?

- Merge "Populating Existing Objects" and "Object Context in Messages" sections
- Update model references from gpt-4o-mini to gpt-5-mini
- Combine examples to show both context approaches together
@chr-hertel
Copy link
Member

@VincentLanglet good one, with this implementation we could also just drop it, right?

$city = new City(name: 'Berlin'); // Partial object
$messages = new MessageBag(
    Message::ofUser('Research missing data for this city'),
);
$result = $platform->invoke($messages, [
    'response_format' => $city,
]);
// Returns same instance with all fields populated

and as a follow up, work with templates like?

$messages = new MessageBag(
    Message::ofUser(Template::string('Research missing data for this city: {city}')),
);
$result = $platform->invoke($messages, [
    'template_vars' => $city,
    'template_options' => [
        'encoding' => 'toon',
        'groups' => 'MySerializationGroup',
    ],
    'response_format' => $city,
]);

just thinking about that since i'm currently confronted with data in messsages as well quite often, and that would be extra value and no BC break, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature New feature Platform Issues & PRs about the AI Platform component Status: Needs Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Platform] Structured Output with Object Instances

4 participants