@octavus/docs 0.0.8 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +127 -0
  2. package/content/01-getting-started/01-introduction.md +3 -3
  3. package/content/01-getting-started/02-quickstart.md +40 -17
  4. package/content/02-server-sdk/01-overview.md +54 -11
  5. package/content/02-server-sdk/02-sessions.md +166 -15
  6. package/content/02-server-sdk/03-tools.md +21 -21
  7. package/content/02-server-sdk/04-streaming.md +50 -20
  8. package/content/02-server-sdk/05-cli.md +247 -0
  9. package/content/03-client-sdk/01-overview.md +65 -35
  10. package/content/03-client-sdk/02-messages.md +116 -8
  11. package/content/03-client-sdk/03-streaming.md +36 -17
  12. package/content/03-client-sdk/04-execution-blocks.md +8 -12
  13. package/content/03-client-sdk/05-socket-transport.md +161 -45
  14. package/content/03-client-sdk/06-http-transport.md +48 -24
  15. package/content/03-client-sdk/07-structured-output.md +412 -0
  16. package/content/03-client-sdk/08-file-uploads.md +473 -0
  17. package/content/03-client-sdk/09-error-handling.md +274 -0
  18. package/content/04-protocol/01-overview.md +25 -14
  19. package/content/04-protocol/02-input-resources.md +35 -35
  20. package/content/04-protocol/03-triggers.md +9 -11
  21. package/content/04-protocol/04-tools.md +72 -29
  22. package/content/04-protocol/05-skills.md +304 -0
  23. package/content/04-protocol/06-handlers.md +304 -0
  24. package/content/04-protocol/07-agent-config.md +334 -0
  25. package/content/04-protocol/08-provider-options.md +294 -0
  26. package/content/04-protocol/09-skills-advanced.md +439 -0
  27. package/content/04-protocol/10-types.md +719 -0
  28. package/content/05-api-reference/01-overview.md +20 -21
  29. package/content/05-api-reference/02-sessions.md +192 -37
  30. package/content/05-api-reference/03-agents.md +25 -37
  31. package/content/06-examples/01-overview.md +6 -4
  32. package/content/06-examples/02-nextjs-chat.md +28 -18
  33. package/content/06-examples/03-socket-chat.md +53 -30
  34. package/content/06-examples/_meta.md +0 -1
  35. package/dist/chunk-WJ2W3DUC.js +663 -0
  36. package/dist/chunk-WJ2W3DUC.js.map +1 -0
  37. package/dist/content.js +1 -1
  38. package/dist/docs.json +106 -34
  39. package/dist/index.js +1 -1
  40. package/dist/search-index.json +1 -1
  41. package/dist/search.js +1 -1
  42. package/dist/search.js.map +1 -1
  43. package/dist/sections.json +106 -34
  44. package/package.json +12 -2
  45. package/content/04-protocol/05-handlers.md +0 -251
  46. package/content/04-protocol/06-agent-config.md +0 -209
  47. package/dist/chunk-232K4EME.js +0 -439
  48. package/dist/chunk-232K4EME.js.map +0 -1
  49. package/dist/chunk-2JDZLMS3.js +0 -439
  50. package/dist/chunk-2JDZLMS3.js.map +0 -1
  51. package/dist/chunk-2YMRODFE.js +0 -421
  52. package/dist/chunk-2YMRODFE.js.map +0 -1
  53. package/dist/chunk-2ZBPX5QB.js +0 -421
  54. package/dist/chunk-2ZBPX5QB.js.map +0 -1
  55. package/dist/chunk-3PIIST4D.js +0 -421
  56. package/dist/chunk-3PIIST4D.js.map +0 -1
  57. package/dist/chunk-42JETGDO.js +0 -421
  58. package/dist/chunk-42JETGDO.js.map +0 -1
  59. package/dist/chunk-4WWUKU4V.js +0 -421
  60. package/dist/chunk-4WWUKU4V.js.map +0 -1
  61. package/dist/chunk-5M7DS4DF.js +0 -519
  62. package/dist/chunk-5M7DS4DF.js.map +0 -1
  63. package/dist/chunk-6JQ3OMGF.js +0 -421
  64. package/dist/chunk-6JQ3OMGF.js.map +0 -1
  65. package/dist/chunk-7AOWCJHW.js +0 -421
  66. package/dist/chunk-7AOWCJHW.js.map +0 -1
  67. package/dist/chunk-7AS4ST73.js +0 -421
  68. package/dist/chunk-7AS4ST73.js.map +0 -1
  69. package/dist/chunk-7F5WOCIL.js +0 -421
  70. package/dist/chunk-7F5WOCIL.js.map +0 -1
  71. package/dist/chunk-7FPUAWSX.js +0 -421
  72. package/dist/chunk-7FPUAWSX.js.map +0 -1
  73. package/dist/chunk-APASMJBS.js +0 -421
  74. package/dist/chunk-APASMJBS.js.map +0 -1
  75. package/dist/chunk-BCEV3WV2.js +0 -421
  76. package/dist/chunk-BCEV3WV2.js.map +0 -1
  77. package/dist/chunk-CHGY4G27.js +0 -421
  78. package/dist/chunk-CHGY4G27.js.map +0 -1
  79. package/dist/chunk-CI7JDWKU.js +0 -421
  80. package/dist/chunk-CI7JDWKU.js.map +0 -1
  81. package/dist/chunk-CVFWWRL7.js +0 -421
  82. package/dist/chunk-CVFWWRL7.js.map +0 -1
  83. package/dist/chunk-EPDM2NIJ.js +0 -421
  84. package/dist/chunk-EPDM2NIJ.js.map +0 -1
  85. package/dist/chunk-ESGSYVGK.js +0 -421
  86. package/dist/chunk-ESGSYVGK.js.map +0 -1
  87. package/dist/chunk-GDCTM2SV.js +0 -421
  88. package/dist/chunk-GDCTM2SV.js.map +0 -1
  89. package/dist/chunk-GJ6FMIPD.js +0 -421
  90. package/dist/chunk-GJ6FMIPD.js.map +0 -1
  91. package/dist/chunk-H6JGSSAJ.js +0 -519
  92. package/dist/chunk-H6JGSSAJ.js.map +0 -1
  93. package/dist/chunk-IKQHGGUZ.js +0 -421
  94. package/dist/chunk-IKQHGGUZ.js.map +0 -1
  95. package/dist/chunk-IUKE3XDN.js +0 -421
  96. package/dist/chunk-IUKE3XDN.js.map +0 -1
  97. package/dist/chunk-J26MLMLN.js +0 -421
  98. package/dist/chunk-J26MLMLN.js.map +0 -1
  99. package/dist/chunk-J7BMB3ZW.js +0 -421
  100. package/dist/chunk-J7BMB3ZW.js.map +0 -1
  101. package/dist/chunk-JCBQRD5N.js +0 -421
  102. package/dist/chunk-JCBQRD5N.js.map +0 -1
  103. package/dist/chunk-JOB6YWEF.js +0 -421
  104. package/dist/chunk-JOB6YWEF.js.map +0 -1
  105. package/dist/chunk-JZRABTHU.js +0 -519
  106. package/dist/chunk-JZRABTHU.js.map +0 -1
  107. package/dist/chunk-K3GFQUMC.js +0 -421
  108. package/dist/chunk-K3GFQUMC.js.map +0 -1
  109. package/dist/chunk-LWYMRXBF.js +0 -421
  110. package/dist/chunk-LWYMRXBF.js.map +0 -1
  111. package/dist/chunk-M2R2NDPR.js +0 -421
  112. package/dist/chunk-M2R2NDPR.js.map +0 -1
  113. package/dist/chunk-MA3P7WCA.js +0 -421
  114. package/dist/chunk-MA3P7WCA.js.map +0 -1
  115. package/dist/chunk-MDMRCS4W.mjs +0 -421
  116. package/dist/chunk-MDMRCS4W.mjs.map +0 -1
  117. package/dist/chunk-MJXTA2R6.js +0 -421
  118. package/dist/chunk-MJXTA2R6.js.map +0 -1
  119. package/dist/chunk-NFVJQNDP.js +0 -421
  120. package/dist/chunk-NFVJQNDP.js.map +0 -1
  121. package/dist/chunk-O5TLYMQP.js +0 -421
  122. package/dist/chunk-O5TLYMQP.js.map +0 -1
  123. package/dist/chunk-OECAPVSX.js +0 -439
  124. package/dist/chunk-OECAPVSX.js.map +0 -1
  125. package/dist/chunk-OL5QDJ42.js +0 -483
  126. package/dist/chunk-OL5QDJ42.js.map +0 -1
  127. package/dist/chunk-PMOVVTHO.js +0 -519
  128. package/dist/chunk-PMOVVTHO.js.map +0 -1
  129. package/dist/chunk-QCHDPR2D.js +0 -421
  130. package/dist/chunk-QCHDPR2D.js.map +0 -1
  131. package/dist/chunk-R5MTVABN.js +0 -439
  132. package/dist/chunk-R5MTVABN.js.map +0 -1
  133. package/dist/chunk-RJ4H4YVA.js +0 -519
  134. package/dist/chunk-RJ4H4YVA.js.map +0 -1
  135. package/dist/chunk-S5U4IWCR.js +0 -439
  136. package/dist/chunk-S5U4IWCR.js.map +0 -1
  137. package/dist/chunk-SCKIOGKI.js +0 -421
  138. package/dist/chunk-SCKIOGKI.js.map +0 -1
  139. package/dist/chunk-TGJSIJYP.js +0 -421
  140. package/dist/chunk-TGJSIJYP.js.map +0 -1
  141. package/dist/chunk-TQZRBMU7.js +0 -421
  142. package/dist/chunk-TQZRBMU7.js.map +0 -1
  143. package/dist/chunk-TRL4RSEO.js +0 -421
  144. package/dist/chunk-TRL4RSEO.js.map +0 -1
  145. package/dist/chunk-TWUMRHQ7.js +0 -421
  146. package/dist/chunk-TWUMRHQ7.js.map +0 -1
  147. package/dist/chunk-UCJE36LL.js +0 -519
  148. package/dist/chunk-UCJE36LL.js.map +0 -1
  149. package/dist/chunk-VCASA6KL.js +0 -421
  150. package/dist/chunk-VCASA6KL.js.map +0 -1
  151. package/dist/chunk-VWPQ6ORV.js +0 -421
  152. package/dist/chunk-VWPQ6ORV.js.map +0 -1
  153. package/dist/chunk-WPXKIHLT.js +0 -421
  154. package/dist/chunk-WPXKIHLT.js.map +0 -1
  155. package/dist/chunk-WUNFFJ32.js +0 -421
  156. package/dist/chunk-WUNFFJ32.js.map +0 -1
  157. package/dist/chunk-WW7TRC7S.js +0 -519
  158. package/dist/chunk-WW7TRC7S.js.map +0 -1
  159. package/dist/chunk-XVSMRXBJ.js +0 -421
  160. package/dist/chunk-XVSMRXBJ.js.map +0 -1
  161. package/dist/chunk-YPPXXV3I.js +0 -421
  162. package/dist/chunk-YPPXXV3I.js.map +0 -1
  163. package/dist/chunk-ZKZVV4OQ.js +0 -421
  164. package/dist/chunk-ZKZVV4OQ.js.map +0 -1
  165. package/dist/chunk-ZOFEX73I.js +0 -421
  166. package/dist/chunk-ZOFEX73I.js.map +0 -1
  167. package/dist/content.mjs +0 -17
  168. package/dist/content.mjs.map +0 -1
  169. package/dist/index.mjs +0 -11
  170. package/dist/index.mjs.map +0 -1
  171. package/dist/search.mjs +0 -30
  172. package/dist/search.mjs.map +0 -1
  173. package/dist/types-BltYGlWI.d.ts +0 -36
@@ -0,0 +1,719 @@
1
+ ---
2
+ title: Types
3
+ description: Defining custom types for structured data in your agent protocol.
4
+ ---
5
+
6
+ # Types
7
+
8
+ Types let you define reusable data structures for your agent. Use them in inputs, triggers, tools, resources, variables, and structured output responses.
9
+
10
+ ## Why Types?
11
+
12
+ - **Reusability** — Define once, use in multiple places
13
+ - **Validation** — Catch errors at protocol validation time
14
+ - **Documentation** — Clear data contracts for your agent
15
+ - **Tool Parameters** — Use complex types in tool parameters
16
+ - **Structured Output** — Get typed JSON responses from the LLM
17
+
18
+ ## Defining Types
19
+
20
+ Types are defined in the `types:` section using PascalCase names:
21
+
22
+ ```yaml
23
+ types:
24
+ Product:
25
+ id:
26
+ type: string
27
+ description: Unique product identifier
28
+ name:
29
+ type: string
30
+ description: Product display name
31
+ price:
32
+ type: number
33
+ description: Price in cents
34
+ inStock:
35
+ type: boolean
36
+ description: Whether the product is available
37
+ ```
38
+
39
+ ## Built-in Types
40
+
41
+ These scalar types can be used directly in inputs, resources, variables, triggers, and tool parameters:
42
+
43
+ | Type | Description | Example Values |
44
+ | --------- | ------------------------------------- | ------------------------------- |
45
+ | `string` | Text values | `"hello"`, `"user@example.com"` |
46
+ | `number` | Numeric values (integers or decimals) | `42`, `3.14`, `-10` |
47
+ | `integer` | Whole numbers only | `1`, `100`, `-5` |
48
+ | `boolean` | True or false | `true`, `false` |
49
+ | `unknown` | Any value (no type checking) | Any JSON value |
50
+ | `file` | Uploaded file reference | `{ id, mediaType, url, ... }` |
51
+
52
+ The `file` type represents an uploaded file (image, document, etc.) with this structure:
53
+
54
+ ```typescript
55
+ interface FileReference {
56
+ id: string; // Unique file ID
57
+ mediaType: string; // MIME type (e.g., 'image/png')
58
+ url: string; // Presigned download URL
59
+ filename?: string; // Original filename
60
+ size?: number; // File size in bytes
61
+ }
62
+ ```
63
+
64
+ > **Note:** There is no standalone `array` or `object` type. If you need typed arrays or objects, define a [custom type](#defining-types). If you don't care about the internal structure, use `unknown`.
65
+
66
+ ## Array Shorthand
67
+
68
+ For simple arrays, use the `type[]` shorthand syntax:
69
+
70
+ ```yaml
71
+ triggers:
72
+ user-message:
73
+ input:
74
+ USER_MESSAGE:
75
+ type: string
76
+ FILES:
77
+ type: file[] # Array of file references
78
+ optional: true
79
+
80
+ variables:
81
+ TAGS:
82
+ type: string[] # Array of strings
83
+ ```
84
+
85
+ This is equivalent to defining a top-level array type but more concise. Array shorthand works with any built-in type or custom type reference:
86
+
87
+ | Shorthand | Equivalent To |
88
+ | ---------- | ----------------------------- |
89
+ | `string[]` | Array of strings |
90
+ | `file[]` | Array of file references |
91
+ | `number[]` | Array of numbers |
92
+ | `MyType[]` | Array of custom type `MyType` |
93
+
94
+ ## Property Fields
95
+
96
+ Each property in a type can have these fields:
97
+
98
+ | Field | Required | Description |
99
+ | ------------- | -------- | ------------------------------------------------------ |
100
+ | `type` | Yes | The data type (built-in or custom type reference) |
101
+ | `description` | No | Human-readable description |
102
+ | `optional` | No | If `true`, property is not required (default: `false`) |
103
+ | `enum` | No | List of allowed string values |
104
+ | `const` | No | Fixed literal value (for discriminators) |
105
+
106
+ ### Required vs Optional
107
+
108
+ Properties are **required by default**. Use `optional: true` to make them optional:
109
+
110
+ ```yaml
111
+ types:
112
+ UserProfile:
113
+ email:
114
+ type: string
115
+ description: User's email address
116
+
117
+ phone:
118
+ type: string
119
+ description: User's phone number
120
+ optional: true
121
+
122
+ nickname:
123
+ type: string
124
+ optional: true
125
+ ```
126
+
127
+ ### Descriptions
128
+
129
+ Descriptions help document your types and guide LLM behavior:
130
+
131
+ ```yaml
132
+ types:
133
+ SupportTicket:
134
+ priority:
135
+ type: string
136
+ enum: [low, medium, high, urgent]
137
+ description: >
138
+ Ticket priority level. Use 'urgent' only for critical issues
139
+ affecting multiple users or causing data loss.
140
+ ```
141
+
142
+ ## Enums
143
+
144
+ Restrict string values to a specific set:
145
+
146
+ ```yaml
147
+ types:
148
+ OrderStatus:
149
+ status:
150
+ type: string
151
+ enum: [pending, processing, shipped, delivered, cancelled]
152
+ description: Current order status
153
+
154
+ paymentMethod:
155
+ type: string
156
+ enum: [credit_card, paypal, bank_transfer]
157
+ ```
158
+
159
+ ## Arrays
160
+
161
+ There are two ways to define arrays:
162
+
163
+ ### Array Properties
164
+
165
+ Define array properties within object types using `type: array` and an `items` definition:
166
+
167
+ ```yaml
168
+ types:
169
+ ShoppingCart:
170
+ items:
171
+ type: array
172
+ items:
173
+ type: CartItem
174
+ description: Items in the cart
175
+
176
+ tags:
177
+ type: array
178
+ items:
179
+ type: string
180
+ description: Cart tags for analytics
181
+
182
+ CartItem:
183
+ productId:
184
+ type: string
185
+ quantity:
186
+ type: integer
187
+ ```
188
+
189
+ ### Top-Level Array Types
190
+
191
+ Define a named type that IS an array (not an object containing an array):
192
+
193
+ ```yaml
194
+ types:
195
+ CartItem:
196
+ productId:
197
+ type: string
198
+ description: Product ID to add to cart
199
+ quantity:
200
+ type: integer
201
+ description: Number of items (1-10)
202
+
203
+ # Top-level array type - the type IS an array
204
+ CartItemList:
205
+ type: array
206
+ items:
207
+ type: CartItem
208
+ description: List of cart items
209
+ ```
210
+
211
+ Top-level array types are useful when you need to pass arrays as tool parameters without wrapping them in an object.
212
+
213
+ ### Array Guidelines
214
+
215
+ When using arrays in structured output, use descriptions to guide the LLM on expected array sizes:
216
+
217
+ ```yaml
218
+ types:
219
+ Survey:
220
+ answers:
221
+ type: array
222
+ items:
223
+ type: string
224
+ description: Survey answers (provide 1-10 responses)
225
+
226
+ TopPicks:
227
+ recommendations:
228
+ type: array
229
+ items:
230
+ type: Product
231
+ description: Top 3-5 product recommendations
232
+ ```
233
+
234
+ > **Note:** Array length constraints (`minItems`, `maxItems`) are not enforced by LLM providers in structured output. Use descriptive prompts to guide the model.
235
+
236
+ ## Type References
237
+
238
+ Reference other types by their PascalCase name:
239
+
240
+ ```yaml
241
+ types:
242
+ Address:
243
+ street:
244
+ type: string
245
+ city:
246
+ type: string
247
+ country:
248
+ type: string
249
+ postalCode:
250
+ type: string
251
+
252
+ Customer:
253
+ name:
254
+ type: string
255
+ email:
256
+ type: string
257
+ shippingAddress:
258
+ type: Address
259
+ billingAddress:
260
+ type: Address
261
+ optional: true
262
+ ```
263
+
264
+ ## Discriminated Unions
265
+
266
+ Create types that can be one of several variants using `anyOf`. Each variant must have a discriminator field with a unique `const` value:
267
+
268
+ ```yaml
269
+ types:
270
+ PaymentResult:
271
+ anyOf:
272
+ - PaymentSuccess
273
+ - PaymentFailure
274
+ discriminator: status
275
+
276
+ PaymentSuccess:
277
+ status:
278
+ type: string
279
+ const: success
280
+ transactionId:
281
+ type: string
282
+ description: Unique transaction identifier
283
+ amount:
284
+ type: number
285
+ description: Amount charged in cents
286
+
287
+ PaymentFailure:
288
+ status:
289
+ type: string
290
+ const: failure
291
+ errorCode:
292
+ type: string
293
+ description: Error code for the failure
294
+ message:
295
+ type: string
296
+ description: Human-readable error message
297
+ ```
298
+
299
+ ### Union Requirements
300
+
301
+ - Use `anyOf` with an array of type names (minimum 2)
302
+ - Specify a `discriminator` field name
303
+ - Each variant must have the discriminator field with a unique `const` value
304
+
305
+ ### Multiple Unions
306
+
307
+ You can have multiple discriminated unions:
308
+
309
+ ```yaml
310
+ types:
311
+ ApiResponse:
312
+ anyOf:
313
+ - SuccessResponse
314
+ - ErrorResponse
315
+ discriminator: status
316
+
317
+ SuccessResponse:
318
+ status:
319
+ type: string
320
+ const: success
321
+ data:
322
+ type: unknown
323
+
324
+ ErrorResponse:
325
+ status:
326
+ type: string
327
+ const: error
328
+ message:
329
+ type: string
330
+
331
+ UserAction:
332
+ anyOf:
333
+ - ClickAction
334
+ - ScrollAction
335
+ - SubmitAction
336
+ discriminator: type
337
+
338
+ ClickAction:
339
+ type:
340
+ type: string
341
+ const: click
342
+ elementId:
343
+ type: string
344
+
345
+ ScrollAction:
346
+ type:
347
+ type: string
348
+ const: scroll
349
+ position:
350
+ type: number
351
+
352
+ SubmitAction:
353
+ type:
354
+ type: string
355
+ const: submit
356
+ formData:
357
+ type: unknown
358
+ ```
359
+
360
+ ## Complete Example
361
+
362
+ Here's a comprehensive example combining multiple type features:
363
+
364
+ ```yaml
365
+ types:
366
+ # Simple object type
367
+ Price:
368
+ amount:
369
+ type: number
370
+ description: Price amount
371
+ currency:
372
+ type: string
373
+ enum: [USD, EUR, GBP]
374
+ description: Currency code
375
+
376
+ # Type with references and arrays
377
+ Product:
378
+ id:
379
+ type: string
380
+ name:
381
+ type: string
382
+ price:
383
+ type: Price
384
+ category:
385
+ type: string
386
+ enum: [electronics, clothing, home, sports]
387
+ tags:
388
+ type: array
389
+ items:
390
+ type: string
391
+ description: Product tags (up to 10)
392
+ optional: true
393
+
394
+ # Discriminated union
395
+ SearchResult:
396
+ anyOf:
397
+ - ProductResult
398
+ - CategoryResult
399
+ discriminator: resultType
400
+
401
+ ProductResult:
402
+ resultType:
403
+ type: string
404
+ const: product
405
+ product:
406
+ type: Product
407
+ relevanceScore:
408
+ type: number
409
+
410
+ CategoryResult:
411
+ resultType:
412
+ type: string
413
+ const: category
414
+ categoryName:
415
+ type: string
416
+ productCount:
417
+ type: integer
418
+
419
+ input:
420
+ STORE_NAME:
421
+ type: string
422
+
423
+ triggers:
424
+ user-message:
425
+ input:
426
+ USER_MESSAGE:
427
+ type: string
428
+
429
+ tools:
430
+ search-products:
431
+ description: Search the product catalog
432
+ parameters:
433
+ query:
434
+ type: string
435
+ category:
436
+ type: string
437
+ optional: true
438
+
439
+ agent:
440
+ model: anthropic/claude-sonnet-4-5
441
+ system: system
442
+ tools: [search-products]
443
+ agentic: true
444
+ ```
445
+
446
+ ## Using Types in Tools
447
+
448
+ Custom types can be used in tool parameters. Tool calls are always objects where each parameter name maps to a value.
449
+
450
+ ### Basic Tool Parameters
451
+
452
+ ```yaml
453
+ tools:
454
+ get-product:
455
+ description: Getting product details
456
+ parameters:
457
+ productId:
458
+ type: string
459
+ includeReviews:
460
+ type: boolean
461
+ optional: true
462
+ ```
463
+
464
+ The LLM calls this with: `{ productId: "prod-123", includeReviews: true }`
465
+
466
+ ### Array Parameters
467
+
468
+ For array parameters, define a top-level array type and use it as the parameter type:
469
+
470
+ ```yaml
471
+ types:
472
+ CartItem:
473
+ productId:
474
+ type: string
475
+ description: Product ID to add to cart
476
+ quantity:
477
+ type: integer
478
+ description: Number of items (1-10)
479
+ giftWrap:
480
+ type: boolean
481
+ description: Whether to gift wrap this item
482
+ optional: true
483
+
484
+ # Top-level array type - the type IS an array
485
+ CartItemList:
486
+ type: array
487
+ items:
488
+ type: CartItem
489
+ description: List of cart items
490
+
491
+ tools:
492
+ add-to-cart:
493
+ description: Adding products to cart
494
+ display: description
495
+ parameters:
496
+ cartItems:
497
+ type: CartItemList
498
+ description: Items to add to the cart
499
+ ```
500
+
501
+ The tool receives: `{ cartItems: [{ productId: "...", quantity: 1 }, ...] }`
502
+
503
+ ### Why Use Named Array Types?
504
+
505
+ Named array types provide:
506
+
507
+ - **Reusability** — Use the same array type in multiple tools
508
+ - **Clear schema** — The array structure is validated
509
+ - **Clean tool calls** — No unnecessary wrapper objects
510
+
511
+ ## Structured Output
512
+
513
+ Use `responseType` on a `next-message` block to get structured JSON responses instead of plain text.
514
+
515
+ ### Basic Example
516
+
517
+ ```yaml
518
+ types:
519
+ ChatResponse:
520
+ content:
521
+ type: string
522
+ description: The main response text to the user
523
+ suggestions:
524
+ type: array
525
+ items:
526
+ type: string
527
+ description: 1-3 follow-up suggestions (empty array if none)
528
+
529
+ variables:
530
+ RESPONSE:
531
+ type: ChatResponse
532
+
533
+ handlers:
534
+ user-message:
535
+ Respond to user:
536
+ block: next-message
537
+ responseType: ChatResponse
538
+ output: RESPONSE
539
+ ```
540
+
541
+ ### Discriminated Unions for Response Variants
542
+
543
+ 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.
544
+
545
+ ```yaml
546
+ types:
547
+ # ✅ Wrapper object (required - responseType must be an object, not a union)
548
+ ChatResponseWrapper:
549
+ response:
550
+ type: ChatResponseUnion
551
+ description: The response variant
552
+
553
+ # Discriminated union with 3 variants
554
+ ChatResponseUnion:
555
+ anyOf:
556
+ - ContentOnlyResponse
557
+ - ContentWithSuggestionsResponse
558
+ - ContentWithProductsResponse
559
+ discriminator: responseType
560
+
561
+ ContentOnlyResponse:
562
+ responseType:
563
+ type: string
564
+ const: content
565
+ content:
566
+ type: string
567
+
568
+ ContentWithSuggestionsResponse:
569
+ responseType:
570
+ type: string
571
+ const: content_with_suggestions
572
+ content:
573
+ type: string
574
+ suggestions:
575
+ type: array
576
+ items:
577
+ type: string
578
+
579
+ ContentWithProductsResponse:
580
+ responseType:
581
+ type: string
582
+ const: content_with_products
583
+ content:
584
+ type: string
585
+ recommendedProducts:
586
+ type: array
587
+ items:
588
+ type: ProductSummary
589
+
590
+ handlers:
591
+ user-message:
592
+ Respond to user:
593
+ block: next-message
594
+ responseType: ChatResponseWrapper # Use the wrapper, not the union directly
595
+ ```
596
+
597
+ The client receives an object like `{ response: { responseType: "content_with_suggestions", content: "...", suggestions: [...] } }`.
598
+
599
+ ### Response Type Requirements
600
+
601
+ The `responseType` must be an **object type** (regular custom type with properties).
602
+
603
+ The following cannot be used directly as `responseType`:
604
+
605
+ - **Discriminated unions** — LLM providers don't allow `anyOf` at the schema root ([OpenAI docs](https://platform.openai.com/docs/guides/structured-outputs#root-objects-must-not-be-anyof-and-must-be-an-object))
606
+ - **Array types** — Must be wrapped in an object
607
+ - **Primitives** — `string`, `number`, etc. are not valid
608
+
609
+ ```yaml
610
+ types:
611
+ # ❌ Cannot use discriminated union directly as responseType
612
+ ChatResponseUnion:
613
+ anyOf: [ContentResponse, ProductResponse]
614
+ discriminator: type
615
+
616
+ # ✅ Wrap the union in an object
617
+ ChatResponseWrapper:
618
+ response:
619
+ type: ChatResponseUnion
620
+
621
+ # ❌ Cannot use array type as responseType
622
+ ProductList:
623
+ type: array
624
+ items:
625
+ type: Product
626
+
627
+ # ✅ Wrap the array in an object
628
+ ProductListResponse:
629
+ products:
630
+ type: array
631
+ items:
632
+ type: Product
633
+ description: List of products
634
+ ```
635
+
636
+ ### How It Works
637
+
638
+ 1. The LLM generates a structured JSON response matching the type schema
639
+ 2. The response is validated against the schema
640
+ 3. The parsed object is stored in the `output` variable (if specified)
641
+ 4. The client SDK receives an `object` part instead of a `text` part
642
+
643
+ ### Client-Side Rendering
644
+
645
+ When `responseType` is set, the client SDK receives a `UIObjectPart` that can be rendered with custom UI. See the [Structured Output](/docs/client-sdk/structured-output) guide for details on building custom renderers.
646
+
647
+ ### Best Practices
648
+
649
+ **Use descriptions to guide the LLM:**
650
+
651
+ ```yaml
652
+ types:
653
+ ChatResponse:
654
+ content:
655
+ type: string
656
+ description: >
657
+ The main response to the user. Use markdown formatting
658
+ for lists and code blocks when appropriate.
659
+ suggestions:
660
+ type: array
661
+ items:
662
+ type: string
663
+ description: >
664
+ 2-3 natural follow-up questions the user might ask.
665
+ Return an empty array if no suggestions are relevant.
666
+ ```
667
+
668
+ **Keep types focused:**
669
+
670
+ 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.
671
+
672
+ **Handle streaming gracefully:**
673
+
674
+ The client receives partial objects during streaming. Design your UI to handle incomplete data (e.g., show skeleton loaders for missing fields).
675
+
676
+ ## Naming Conventions
677
+
678
+ | Element | Convention | Examples |
679
+ | -------------- | --------------------------------- | --------------------------------------- |
680
+ | Type names | PascalCase | `Product`, `UserProfile`, `OrderStatus` |
681
+ | Property names | camelCase | `firstName`, `orderId`, `isActive` |
682
+ | Enum values | lowercase_snake_case or camelCase | `in_stock`, `pending`, `creditCard` |
683
+
684
+ ## Validation
685
+
686
+ Types are validated when the protocol is loaded:
687
+
688
+ - Type names must be PascalCase
689
+ - Referenced types must exist
690
+ - Circular references are not allowed
691
+ - Union variants must have unique discriminator values
692
+ - Arrays with `type: array` must have an `items` definition
693
+
694
+ ## Limitations
695
+
696
+ ### Type Definition Limits
697
+
698
+ - **No standalone `array` or `object`** — Define a custom type instead, or use `unknown` for untyped data
699
+ - **No recursive types** — A type cannot reference itself (directly or indirectly)
700
+ - **No generic types** — Types are concrete, not parameterized
701
+ - **String enums only** — `enum` values must be strings
702
+ - **No array constraints** — `minItems` and `maxItems` are not supported (LLM providers don't enforce them)
703
+
704
+ ### Tool Limitations
705
+
706
+ - **Tool parameters are always objects** — Each tool call is `{ param1: value1, param2: value2, ... }`
707
+ - **Array parameters need named types** — Use top-level array types for array parameters
708
+
709
+ ### Structured Output Limitations
710
+
711
+ - **responseType must be an object type** — Only object types can be used as responseType
712
+ - **Discriminated unions need object wrapper** — Unions (`anyOf`) are not allowed at the schema root
713
+ - **Array types need object wrapper** — Arrays cannot be used directly as responseType
714
+ - **Primitives are not allowed** — `string`, `number`, etc. cannot be used as responseType
715
+
716
+ These limitations exist because LLM providers (OpenAI, Anthropic) require the root schema to be an object:
717
+
718
+ - [OpenAI: Root objects must not be anyOf](https://platform.openai.com/docs/guides/structured-outputs#root-objects-must-not-be-anyof-and-must-be-an-object)
719
+ - JSON Schema validation works best with explicit object structures at the root