Structured Output
When an agent uses responseType on a next-message block, the client receives a UIObjectPart instead of a UITextPart. This enables rich, custom UI for typed responses.
How It Works
- The protocol defines a type and uses it as
responseType:
- The agent generates a JSON response matching the schema
- The client SDK receives a
UIObjectPartwith progressive JSON parsing - Your app renders custom UI based on the
typeName
The UIObjectPart
During streaming, partial contains the progressively parsed object. When streaming completes, object contains the final validated result.
Building a Renderer
Create a renderer component for each type you want to customize:
Renderer Registry Pattern
For apps with multiple response types, use a registry to map type names to renderers:
Using in Part Renderer
Integrate with your part renderer:
Handling Streaming State
During streaming, the object is progressively parsed. Handle incomplete data gracefully:
Error Handling
If JSON parsing fails, status will be 'error' with details in error:
Complete Example
Here's a complete chat interface with structured output support:
Best Practices
Design types for progressive rendering:
Structure your types so the most important fields stream first. Property order in YAML is preserved during streaming.
Keep renderers resilient:
Handle missing fields gracefully since partial objects may have undefined properties:
Use TypeScript for type safety:
Define TypeScript interfaces matching your protocol types:
Test with slow connections:
Streaming is more noticeable on slow connections. Test your UI with network throttling to ensure a good experience.
Type Requirements
The responseType in your protocol must be an object type (regular custom type with properties).
The following cannot be used directly as responseType:
- Discriminated unions — LLM providers don't allow
anyOfat the schema root - Array types — Must be wrapped in an object
- Primitives —
string,number, etc. are not valid
If you need variant responses, wrap the discriminated union in an object:
If you need the LLM to return an array, wrap it in an object:
See Types - Structured Output for more details on defining response types.