Cleaner Structured-Output Contract
v2.5 makes the requested output target authoritative and removes the implicit DynamicStructure fallback from Instructor’s core pipeline.
x-php-class or
intoInstanceOf() opts into class hydration. intoArray() explicitly overrides a
class-backed schema. intoStdClass() explicitly requests stdClass.
An unknown root x-php-class now fails during response-model preparation instead of
silently falling back to another target.
Passing a Dynamic Structure explicitly now returns that Structure; call its
toArray() method when an array conversion is wanted.
Validation and Materialization
- Array, class,
stdClass, and self-deserializing targets share schema validation. - Completed streaming and synchronous extraction use the same final materialization path.
- Configured and self transformations run exactly once.
- Transformation failures fail the attempt and may retry instead of returning unchanged data.
- Nested Dynamic hydration failures report their field or index path.
Public API
- Added
intoStdClass(). - Added
intoSelfDeserializing();intoObject()remains as a deprecated compatibility alias. - Removed the unused
outputClass/withDefaultOutputClass()configuration surface. - Deprecated global
defaultToStdClass; use per-requestintoStdClass()instead. - Existing
PendingStructuredOutput::toJsonObject(),toJson(), andtoArray()remain concise raw-response inspection methods.get()and typedget*()methods return the final structured result. - Typed result mismatches now throw
UnexpectedStructuredOutputTypeExceptionand include the concrete actual type. - Requests containing a live self-deserializing target fail explicitly when serialized or restored; Instructor no longer fabricates uninitialized target instances with reflection.
Events
Use the result-neutral materialization and retry events:Cognesy\Instructor\Events\Response\ResponseMaterializedCognesy\Instructor\Events\Response\ResponseMaterializationFailedCognesy\Instructor\Events\Attempt\ResponseRetryScheduledCognesy\Instructor\Events\Attempt\ResponseRecoveryExhausted
ResponseConvertedToObject, and
ResponseGenerationFailed were removed. Event payloads include correlation identifiers,
failure stage, and safe type information without adding raw prompt or response content.
Event namespace aliases were removed. Update imports from
Events\PartialsGenerator\* to Events\Streaming\*, from
Events\Request\ResponseModel* to Events\ResponseModel\ResponseModel*, and from
Events\Request\SequenceUpdated to Events\Streaming\SequenceUpdated.
Prompts and Dependencies
StructuredPromptRequestMaterializer is the default. Bundled structured-output prompt
classes use the bundled Twig templates. Custom prompt classes remain the supported
extension seam.
The legacy RequestMaterializer and inline modePrompts, retryPrompt, and
chatStructure settings remain available only through explicit legacy injection in 2.5
and are scheduled for removal in 2.6.
The generic templates package continues to support Twig, Blade, and Arrowpipe.
cognesy/instructor-struct no longer requires the Dynamic package unless the
application uses Dynamic structures directly.
Twig remains a required dependency of cognesy/instructor-struct because every bundled
structured-output prompt uses a Twig template. The root meta-package no longer also
lists Twig as an optional suggestion.
Package Highlights
- Schema: added the shared
SchemaDataValidatorfor required and nullable fields, primitive types, nested objects and collections, and scalar or backed-enum values. - Dynamic:
Structurenow delegates validation to the shared validator and no longer exposes the removedtransform()or no-opwithValidation()methods. - Laravel: published extraction configuration now uses
retry_prompt_class; the inlineretry_promptkey remains only as deprecated legacy compatibility until 2.6. - Symfony: removed the unused
output_class/outputClassconfiguration keys. - Events: removed class-alias canonicalization after the deprecated event namespace aliases were deleted.
- Addons: function-call argument schemas no longer leak root
x-php-classhydration metadata into tool definitions. - Agents: added
UseCodingToolswith boundedread,bash,edit, andwritetools; file operations now stream bounded data and edits commit through a temporary file instead of loading and rewriting unbounded content. - Sandbox: host execution now uses the bounded
ProcRunner, retains stream tails after capture limits, and reports command-start failures with a stable exit code.
Upgrade Notes
-
Remove
Structurechecks andtoArray()calls around plain JSON Schema results;get()now returns the associative array directly. -
If you pass a Dynamic
Structureintentionally, expectget()to return thatStructure; calltoArray()explicitly when conversion is wanted. -
Use
x-php-classorintoInstanceOf()for class hydration,intoStdClass()forstdClass, andintoArray()to override a class-backed schema. -
Correct or remove unknown root
x-php-classmetadata before execution. -
Replace
intoObject()withintoSelfDeserializing(). Replace globaldefaultToStdClasswith per-requestintoStdClass(). -
Remove
outputClass,output_class, andwithDefaultOutputClass()configuration. RemovethrowOnTransformationFailure; transformation failures now always fail the attempt. - Update event listener imports to the canonical namespaces listed above and migrate removed recovery/materialization events to the new result-neutral events.
-
Replace inline
modePrompts,retryPrompt, andchatStructurecustomization with prompt classes. The legacy values work only with an explicitly injected deprecatedRequestMaterializerin 2.5 and are scheduled for removal in 2.6. -
If your application imports
Cognesy\Dynamicdirectly, add the dependency explicitly: - Expect schema, deserialization, object-validation, and transformation failures to fail the attempt and enter the configured retry policy rather than returning a partially materialized or unchanged value.
-
Remove calls to Dynamic
Structure::transform()and the no-opStructure::withValidation()compatibility method; calltoArray()only when an explicit Structure-to-array conversion is required.