Types
Types let you define reusable data structures for your agent. Use them in inputs, triggers, tools, resources, variables, and structured output responses.
Why Types?
- Reusability — Define once, use in multiple places
- Validation — Catch errors at protocol validation time
- Documentation — Clear data contracts for your agent
- Tool Parameters — Use complex types in tool parameters
- Structured Output — Get typed JSON responses from the LLM
Defining Types
Types are defined in the types: section using PascalCase names:
Built-in Types
These scalar types can be used directly in inputs, resources, variables, triggers, and tool parameters:
| Type | Description | Example Values |
|---|---|---|
string | Text values | "hello", "user@example.com" |
number | Numeric values (integers or decimals) | 42, 3.14, -10 |
integer | Whole numbers only | 1, 100, -5 |
boolean | True or false | true, false |
unknown | Any value (no type checking) | Any JSON value |
Note: There is no standalone array or object type. If you need typed arrays or objects, define a custom type. If you don't care about the internal structure, use unknown.
Property Fields
Each property in a type can have these fields:
| Field | Required | Description |
|---|---|---|
type | Yes | The data type (built-in or custom type reference) |
description | No | Human-readable description |
optional | No | If true, property is not required (default: false) |
enum | No | List of allowed string values |
const | No | Fixed literal value (for discriminators) |
Required vs Optional
Properties are required by default. Use optional: true to make them optional:
Descriptions
Descriptions help document your types and guide LLM behavior:
Enums
Restrict string values to a specific set:
Arrays
There are two ways to define arrays:
Array Properties
Define array properties within object types using type: array and an items definition:
Top-Level Array Types
Define a named type that IS an array (not an object containing an array):
Top-level array types are useful when you need to pass arrays as tool parameters without wrapping them in an object.
Array Guidelines
When using arrays in structured output, use descriptions to guide the LLM on expected array sizes:
Note: Array length constraints (minItems, maxItems) are not enforced by LLM providers in structured output. Use descriptive prompts to guide the model.
Type References
Reference other types by their PascalCase name:
Discriminated Unions
Create types that can be one of several variants using anyOf. Each variant must have a discriminator field with a unique const value:
Union Requirements
- Use
anyOfwith an array of type names (minimum 2) - Specify a
discriminatorfield name - Each variant must have the discriminator field with a unique
constvalue
Multiple Unions
You can have multiple discriminated unions:
Complete Example
Here's a comprehensive example combining multiple type features:
Using Types in Tools
Custom types can be used in tool parameters. Tool calls are always objects where each parameter name maps to a value.
Basic Tool Parameters
The LLM calls this with: { productId: "prod-123", includeReviews: true }
Array Parameters
For array parameters, define a top-level array type and use it as the parameter type:
The tool receives: { cartItems: [{ productId: "...", quantity: 1 }, ...] }
Why Use Named Array Types?
Named array types provide:
- Reusability — Use the same array type in multiple tools
- Clear schema — The array structure is validated
- Clean tool calls — No unnecessary wrapper objects
Structured Output
Use responseType on a next-message block to get structured JSON responses instead of plain text.
Basic Example
Discriminated Unions for Response Variants
When you need different response formats based on context, use a discriminated union wrapped in an object. LLM providers don't allow anyOf (discriminated unions) at the schema root, so you must wrap them.
The client receives an object like { response: { responseType: "content_with_suggestions", content: "...", suggestions: [...] } }.
Response Type Requirements
The responseType 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 (OpenAI docs) - Array types — Must be wrapped in an object
- Primitives —
string,number, etc. are not valid
How It Works
- The LLM generates a structured JSON response matching the type schema
- The response is validated against the schema
- The parsed object is stored in the
outputvariable (if specified) - The client SDK receives an
objectpart instead of atextpart
Client-Side Rendering
When responseType is set, the client SDK receives a UIObjectPart that can be rendered with custom UI. See the Structured Output guide for details on building custom renderers.
Best Practices
Use descriptions to guide the LLM:
Keep types focused:
Create separate types for different response formats rather than one complex type with many optional fields. Use discriminated unions when the response can be one of several distinct variants.
Handle streaming gracefully:
The client receives partial objects during streaming. Design your UI to handle incomplete data (e.g., show skeleton loaders for missing fields).
Naming Conventions
| Element | Convention | Examples |
|---|---|---|
| Type names | PascalCase | Product, UserProfile, OrderStatus |
| Property names | camelCase | firstName, orderId, isActive |
| Enum values | lowercase_snake_case or camelCase | in_stock, pending, creditCard |
Validation
Types are validated when the protocol is loaded:
- Type names must be PascalCase
- Referenced types must exist
- Circular references are not allowed
- Union variants must have unique discriminator values
- Arrays with
type: arraymust have anitemsdefinition
Limitations
Type Definition Limits
- No standalone
arrayorobject— Define a custom type instead, or useunknownfor untyped data - No recursive types — A type cannot reference itself (directly or indirectly)
- No generic types — Types are concrete, not parameterized
- String enums only —
enumvalues must be strings - No array constraints —
minItemsandmaxItemsare not supported (LLM providers don't enforce them)
Tool Limitations
- Tool parameters are always objects — Each tool call is
{ param1: value1, param2: value2, ... } - Array parameters need named types — Use top-level array types for array parameters
Structured Output Limitations
- responseType must be an object type — Only object types can be used as responseType
- Discriminated unions need object wrapper — Unions (
anyOf) are not allowed at the schema root - Array types need object wrapper — Arrays cannot be used directly as responseType
- Primitives are not allowed —
string,number, etc. cannot be used as responseType
These limitations exist because LLM providers (OpenAI, Anthropic) require the root schema to be an object:
- OpenAI: Root objects must not be anyOf
- JSON Schema validation works best with explicit object structures at the root