@tai42/studio-sdk 0.2.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 (422) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +15 -0
  3. package/README.md +318 -0
  4. package/SECURITY.md +51 -0
  5. package/dist/components/badge.d.ts +13 -0
  6. package/dist/components/badge.d.ts.map +1 -0
  7. package/dist/components/badge.js +14 -0
  8. package/dist/components/badge.js.map +1 -0
  9. package/dist/components/checkbox.d.ts +24 -0
  10. package/dist/components/checkbox.d.ts.map +1 -0
  11. package/dist/components/checkbox.js +31 -0
  12. package/dist/components/checkbox.js.map +1 -0
  13. package/dist/components/code-block.d.ts +7 -0
  14. package/dist/components/code-block.d.ts.map +1 -0
  15. package/dist/components/code-block.js +23 -0
  16. package/dist/components/code-block.js.map +1 -0
  17. package/dist/components/completion-input.d.ts +31 -0
  18. package/dist/components/completion-input.d.ts.map +1 -0
  19. package/dist/components/completion-input.js +61 -0
  20. package/dist/components/completion-input.js.map +1 -0
  21. package/dist/components/components.css +2212 -0
  22. package/dist/components/confirm-dialog.d.ts +40 -0
  23. package/dist/components/confirm-dialog.d.ts.map +1 -0
  24. package/dist/components/confirm-dialog.js +11 -0
  25. package/dist/components/confirm-dialog.js.map +1 -0
  26. package/dist/components/control-styles.d.ts +12 -0
  27. package/dist/components/control-styles.d.ts.map +1 -0
  28. package/dist/components/control-styles.js +14 -0
  29. package/dist/components/control-styles.js.map +1 -0
  30. package/dist/components/copy-field.d.ts +8 -0
  31. package/dist/components/copy-field.d.ts.map +1 -0
  32. package/dist/components/copy-field.js +106 -0
  33. package/dist/components/copy-field.js.map +1 -0
  34. package/dist/components/dialog.d.ts +21 -0
  35. package/dist/components/dialog.d.ts.map +1 -0
  36. package/dist/components/dialog.js +25 -0
  37. package/dist/components/dialog.js.map +1 -0
  38. package/dist/components/drawer.d.ts +22 -0
  39. package/dist/components/drawer.d.ts.map +1 -0
  40. package/dist/components/drawer.js +32 -0
  41. package/dist/components/drawer.js.map +1 -0
  42. package/dist/components/error-boundary.d.ts +33 -0
  43. package/dist/components/error-boundary.d.ts.map +1 -0
  44. package/dist/components/error-boundary.js +36 -0
  45. package/dist/components/error-boundary.js.map +1 -0
  46. package/dist/components/extension-combo-builder.d.ts +70 -0
  47. package/dist/components/extension-combo-builder.d.ts.map +1 -0
  48. package/dist/components/extension-combo-builder.js +154 -0
  49. package/dist/components/extension-combo-builder.js.map +1 -0
  50. package/dist/components/extension-grouping.d.ts +65 -0
  51. package/dist/components/extension-grouping.d.ts.map +1 -0
  52. package/dist/components/extension-grouping.js +78 -0
  53. package/dist/components/extension-grouping.js.map +1 -0
  54. package/dist/components/extension-picker.d.ts +35 -0
  55. package/dist/components/extension-picker.d.ts.map +1 -0
  56. package/dist/components/extension-picker.js +31 -0
  57. package/dist/components/extension-picker.js.map +1 -0
  58. package/dist/components/external-link.d.ts +19 -0
  59. package/dist/components/external-link.d.ts.map +1 -0
  60. package/dist/components/external-link.js +12 -0
  61. package/dist/components/external-link.js.map +1 -0
  62. package/dist/components/field.d.ts +64 -0
  63. package/dist/components/field.d.ts.map +1 -0
  64. package/dist/components/field.js +56 -0
  65. package/dist/components/field.js.map +1 -0
  66. package/dist/components/fleet-report.d.ts +39 -0
  67. package/dist/components/fleet-report.d.ts.map +1 -0
  68. package/dist/components/fleet-report.js +50 -0
  69. package/dist/components/fleet-report.js.map +1 -0
  70. package/dist/components/fonts.css +22 -0
  71. package/dist/components/icons.d.ts +142 -0
  72. package/dist/components/icons.d.ts.map +1 -0
  73. package/dist/components/icons.js +139 -0
  74. package/dist/components/icons.js.map +1 -0
  75. package/dist/components/inputs.d.ts +52 -0
  76. package/dist/components/inputs.d.ts.map +1 -0
  77. package/dist/components/inputs.js +35 -0
  78. package/dist/components/inputs.js.map +1 -0
  79. package/dist/components/json-diff.d.ts +40 -0
  80. package/dist/components/json-diff.d.ts.map +1 -0
  81. package/dist/components/json-diff.js +119 -0
  82. package/dist/components/json-diff.js.map +1 -0
  83. package/dist/components/json-tree.d.ts +8 -0
  84. package/dist/components/json-tree.d.ts.map +1 -0
  85. package/dist/components/json-tree.js +70 -0
  86. package/dist/components/json-tree.js.map +1 -0
  87. package/dist/components/modal-focus.d.ts +15 -0
  88. package/dist/components/modal-focus.d.ts.map +1 -0
  89. package/dist/components/modal-focus.js +136 -0
  90. package/dist/components/modal-focus.js.map +1 -0
  91. package/dist/components/page-header.d.ts +56 -0
  92. package/dist/components/page-header.d.ts.map +1 -0
  93. package/dist/components/page-header.js +24 -0
  94. package/dist/components/page-header.js.map +1 -0
  95. package/dist/components/primitives.d.ts +186 -0
  96. package/dist/components/primitives.d.ts.map +1 -0
  97. package/dist/components/primitives.js +204 -0
  98. package/dist/components/primitives.js.map +1 -0
  99. package/dist/components/progress-bar.d.ts +29 -0
  100. package/dist/components/progress-bar.d.ts.map +1 -0
  101. package/dist/components/progress-bar.js +48 -0
  102. package/dist/components/progress-bar.js.map +1 -0
  103. package/dist/components/radio-group.d.ts +37 -0
  104. package/dist/components/radio-group.d.ts.map +1 -0
  105. package/dist/components/radio-group.js +56 -0
  106. package/dist/components/radio-group.js.map +1 -0
  107. package/dist/components/reveal-input.d.ts +13 -0
  108. package/dist/components/reveal-input.d.ts.map +1 -0
  109. package/dist/components/reveal-input.js +31 -0
  110. package/dist/components/reveal-input.js.map +1 -0
  111. package/dist/components/scroll-region.d.ts +85 -0
  112. package/dist/components/scroll-region.d.ts.map +1 -0
  113. package/dist/components/scroll-region.js +574 -0
  114. package/dist/components/scroll-region.js.map +1 -0
  115. package/dist/components/select.d.ts +53 -0
  116. package/dist/components/select.d.ts.map +1 -0
  117. package/dist/components/select.js +33 -0
  118. package/dist/components/select.js.map +1 -0
  119. package/dist/components/table.d.ts +59 -0
  120. package/dist/components/table.d.ts.map +1 -0
  121. package/dist/components/table.js +20 -0
  122. package/dist/components/table.js.map +1 -0
  123. package/dist/components/tabs.d.ts +15 -0
  124. package/dist/components/tabs.d.ts.map +1 -0
  125. package/dist/components/tabs.js +13 -0
  126. package/dist/components/tabs.js.map +1 -0
  127. package/dist/components/tags.d.ts +46 -0
  128. package/dist/components/tags.d.ts.map +1 -0
  129. package/dist/components/tags.js +68 -0
  130. package/dist/components/tags.js.map +1 -0
  131. package/dist/components/tokens.css +392 -0
  132. package/dist/components/tokens.d.ts +15 -0
  133. package/dist/components/tokens.d.ts.map +1 -0
  134. package/dist/components/tokens.js +101 -0
  135. package/dist/components/tokens.js.map +1 -0
  136. package/dist/components/tool-picker.d.ts +24 -0
  137. package/dist/components/tool-picker.d.ts.map +1 -0
  138. package/dist/components/tool-picker.js +97 -0
  139. package/dist/components/tool-picker.js.map +1 -0
  140. package/dist/components/tooltip.d.ts +17 -0
  141. package/dist/components/tooltip.d.ts.map +1 -0
  142. package/dist/components/tooltip.js +18 -0
  143. package/dist/components/tooltip.js.map +1 -0
  144. package/dist/components/version-history-panel.d.ts +71 -0
  145. package/dist/components/version-history-panel.d.ts.map +1 -0
  146. package/dist/components/version-history-panel.js +148 -0
  147. package/dist/components/version-history-panel.js.map +1 -0
  148. package/dist/download.d.ts +7 -0
  149. package/dist/download.d.ts.map +1 -0
  150. package/dist/download.js +18 -0
  151. package/dist/download.js.map +1 -0
  152. package/dist/element-slot.d.ts +4 -0
  153. package/dist/element-slot.d.ts.map +1 -0
  154. package/dist/element-slot.js +20 -0
  155. package/dist/element-slot.js.map +1 -0
  156. package/dist/elicitation/ElicitationForm.d.ts +34 -0
  157. package/dist/elicitation/ElicitationForm.d.ts.map +1 -0
  158. package/dist/elicitation/ElicitationForm.js +24 -0
  159. package/dist/elicitation/ElicitationForm.js.map +1 -0
  160. package/dist/errors.d.ts +9 -0
  161. package/dist/errors.d.ts.map +1 -0
  162. package/dist/errors.js +15 -0
  163. package/dist/errors.js.map +1 -0
  164. package/dist/extension-combos.d.ts +13 -0
  165. package/dist/extension-combos.d.ts.map +1 -0
  166. package/dist/extension-combos.js +9 -0
  167. package/dist/extension-combos.js.map +1 -0
  168. package/dist/hooks/useApi.d.ts +1222 -0
  169. package/dist/hooks/useApi.d.ts.map +1 -0
  170. package/dist/hooks/useApi.js +22 -0
  171. package/dist/hooks/useApi.js.map +1 -0
  172. package/dist/hooks/useAuth.d.ts +13 -0
  173. package/dist/hooks/useAuth.d.ts.map +1 -0
  174. package/dist/hooks/useAuth.js +53 -0
  175. package/dist/hooks/useAuth.js.map +1 -0
  176. package/dist/hooks/useBreakpoint.d.ts +10 -0
  177. package/dist/hooks/useBreakpoint.d.ts.map +1 -0
  178. package/dist/hooks/useBreakpoint.js +66 -0
  179. package/dist/hooks/useBreakpoint.js.map +1 -0
  180. package/dist/hooks/useCapabilities.d.ts +88 -0
  181. package/dist/hooks/useCapabilities.d.ts.map +1 -0
  182. package/dist/hooks/useCapabilities.js +203 -0
  183. package/dist/hooks/useCapabilities.js.map +1 -0
  184. package/dist/hooks/useSse.d.ts +13 -0
  185. package/dist/hooks/useSse.d.ts.map +1 -0
  186. package/dist/hooks/useSse.js +298 -0
  187. package/dist/hooks/useSse.js.map +1 -0
  188. package/dist/hooks/useTheme.d.ts +20 -0
  189. package/dist/hooks/useTheme.d.ts.map +1 -0
  190. package/dist/hooks/useTheme.js +97 -0
  191. package/dist/hooks/useTheme.js.map +1 -0
  192. package/dist/hooks/useUnauthorized.d.ts +3 -0
  193. package/dist/hooks/useUnauthorized.d.ts.map +1 -0
  194. package/dist/hooks/useUnauthorized.js +18 -0
  195. package/dist/hooks/useUnauthorized.js.map +1 -0
  196. package/dist/host.d.ts +11 -0
  197. package/dist/host.d.ts.map +1 -0
  198. package/dist/host.js +10 -0
  199. package/dist/host.js.map +1 -0
  200. package/dist/index.d.ts +118 -0
  201. package/dist/index.d.ts.map +1 -0
  202. package/dist/index.js +91 -0
  203. package/dist/index.js.map +1 -0
  204. package/dist/navigation/context.d.ts +25 -0
  205. package/dist/navigation/context.d.ts.map +1 -0
  206. package/dist/navigation/context.js +45 -0
  207. package/dist/navigation/context.js.map +1 -0
  208. package/dist/navigation/index.d.ts +4 -0
  209. package/dist/navigation/index.d.ts.map +1 -0
  210. package/dist/navigation/index.js +2 -0
  211. package/dist/navigation/index.js.map +1 -0
  212. package/dist/navigation/types.d.ts +97 -0
  213. package/dist/navigation/types.d.ts.map +1 -0
  214. package/dist/navigation/types.js +16 -0
  215. package/dist/navigation/types.js.map +1 -0
  216. package/dist/plugin/host-state.d.ts +45 -0
  217. package/dist/plugin/host-state.d.ts.map +1 -0
  218. package/dist/plugin/host-state.js +62 -0
  219. package/dist/plugin/host-state.js.map +1 -0
  220. package/dist/plugin/registry.d.ts +35 -0
  221. package/dist/plugin/registry.d.ts.map +1 -0
  222. package/dist/plugin/registry.js +129 -0
  223. package/dist/plugin/registry.js.map +1 -0
  224. package/dist/plugin/types.d.ts +165 -0
  225. package/dist/plugin/types.d.ts.map +1 -0
  226. package/dist/plugin/types.js +2 -0
  227. package/dist/plugin/types.js.map +1 -0
  228. package/dist/plugin/version.d.ts +34 -0
  229. package/dist/plugin/version.d.ts.map +1 -0
  230. package/dist/plugin/version.js +37 -0
  231. package/dist/plugin/version.js.map +1 -0
  232. package/dist/query-keys.d.ts +31 -0
  233. package/dist/query-keys.d.ts.map +1 -0
  234. package/dist/query-keys.js +31 -0
  235. package/dist/query-keys.js.map +1 -0
  236. package/dist/schema-editor/SchemaEditor.d.ts +43 -0
  237. package/dist/schema-editor/SchemaEditor.d.ts.map +1 -0
  238. package/dist/schema-editor/SchemaEditor.js +106 -0
  239. package/dist/schema-editor/SchemaEditor.js.map +1 -0
  240. package/dist/schema-editor/index.d.ts +10 -0
  241. package/dist/schema-editor/index.d.ts.map +1 -0
  242. package/dist/schema-editor/index.js +8 -0
  243. package/dist/schema-editor/index.js.map +1 -0
  244. package/dist/schema-editor/lint.d.ts +37 -0
  245. package/dist/schema-editor/lint.d.ts.map +1 -0
  246. package/dist/schema-editor/lint.js +49 -0
  247. package/dist/schema-editor/lint.js.map +1 -0
  248. package/dist/schema-form/SchemaForm.d.ts +70 -0
  249. package/dist/schema-form/SchemaForm.d.ts.map +1 -0
  250. package/dist/schema-form/SchemaForm.js +13 -0
  251. package/dist/schema-form/SchemaForm.js.map +1 -0
  252. package/dist/schema-form/array-field.d.ts +20 -0
  253. package/dist/schema-form/array-field.d.ts.map +1 -0
  254. package/dist/schema-form/array-field.js +39 -0
  255. package/dist/schema-form/array-field.js.map +1 -0
  256. package/dist/schema-form/classify.d.ts +87 -0
  257. package/dist/schema-form/classify.d.ts.map +1 -0
  258. package/dist/schema-form/classify.js +199 -0
  259. package/dist/schema-form/classify.js.map +1 -0
  260. package/dist/schema-form/context.d.ts +4 -0
  261. package/dist/schema-form/context.d.ts.map +1 -0
  262. package/dist/schema-form/context.js +14 -0
  263. package/dist/schema-form/context.js.map +1 -0
  264. package/dist/schema-form/default-value.d.ts +8 -0
  265. package/dist/schema-form/default-value.d.ts.map +1 -0
  266. package/dist/schema-form/default-value.js +64 -0
  267. package/dist/schema-form/default-value.js.map +1 -0
  268. package/dist/schema-form/enum-field.d.ts +19 -0
  269. package/dist/schema-form/enum-field.d.ts.map +1 -0
  270. package/dist/schema-form/enum-field.js +26 -0
  271. package/dist/schema-form/enum-field.js.map +1 -0
  272. package/dist/schema-form/field-group.d.ts +9 -0
  273. package/dist/schema-form/field-group.d.ts.map +1 -0
  274. package/dist/schema-form/field-group.js +32 -0
  275. package/dist/schema-form/field-group.js.map +1 -0
  276. package/dist/schema-form/field-node.d.ts +24 -0
  277. package/dist/schema-form/field-node.d.ts.map +1 -0
  278. package/dist/schema-form/field-node.js +51 -0
  279. package/dist/schema-form/field-node.js.map +1 -0
  280. package/dist/schema-form/index.d.ts +13 -0
  281. package/dist/schema-form/index.d.ts.map +1 -0
  282. package/dist/schema-form/index.js +11 -0
  283. package/dist/schema-form/index.js.map +1 -0
  284. package/dist/schema-form/media-field.d.ts +24 -0
  285. package/dist/schema-form/media-field.d.ts.map +1 -0
  286. package/dist/schema-form/media-field.js +169 -0
  287. package/dist/schema-form/media-field.js.map +1 -0
  288. package/dist/schema-form/media.d.ts +40 -0
  289. package/dist/schema-form/media.d.ts.map +1 -0
  290. package/dist/schema-form/media.js +65 -0
  291. package/dist/schema-form/media.js.map +1 -0
  292. package/dist/schema-form/object-fields.d.ts +20 -0
  293. package/dist/schema-form/object-fields.d.ts.map +1 -0
  294. package/dist/schema-form/object-fields.js +24 -0
  295. package/dist/schema-form/object-fields.js.map +1 -0
  296. package/dist/schema-form/resolve.d.ts +41 -0
  297. package/dist/schema-form/resolve.d.ts.map +1 -0
  298. package/dist/schema-form/resolve.js +102 -0
  299. package/dist/schema-form/resolve.js.map +1 -0
  300. package/dist/schema-form/string-field.d.ts +20 -0
  301. package/dist/schema-form/string-field.d.ts.map +1 -0
  302. package/dist/schema-form/string-field.js +68 -0
  303. package/dist/schema-form/string-field.js.map +1 -0
  304. package/dist/schema-form/styles.d.ts +18 -0
  305. package/dist/schema-form/styles.d.ts.map +1 -0
  306. package/dist/schema-form/styles.js +18 -0
  307. package/dist/schema-form/styles.js.map +1 -0
  308. package/dist/schema-form/types.d.ts +67 -0
  309. package/dist/schema-form/types.d.ts.map +1 -0
  310. package/dist/schema-form/types.js +10 -0
  311. package/dist/schema-form/types.js.map +1 -0
  312. package/dist/schema-form/union-field.d.ts +24 -0
  313. package/dist/schema-form/union-field.d.ts.map +1 -0
  314. package/dist/schema-form/union-field.js +55 -0
  315. package/dist/schema-form/union-field.js.map +1 -0
  316. package/dist/schema-form/union.d.ts +4 -0
  317. package/dist/schema-form/union.d.ts.map +1 -0
  318. package/dist/schema-form/union.js +68 -0
  319. package/dist/schema-form/union.js.map +1 -0
  320. package/dist/schema-form/unsupported-notice.d.ts +18 -0
  321. package/dist/schema-form/unsupported-notice.d.ts.map +1 -0
  322. package/dist/schema-form/unsupported-notice.js +8 -0
  323. package/dist/schema-form/unsupported-notice.js.map +1 -0
  324. package/dist/schema-form/validate.d.ts +18 -0
  325. package/dist/schema-form/validate.d.ts.map +1 -0
  326. package/dist/schema-form/validate.js +162 -0
  327. package/dist/schema-form/validate.js.map +1 -0
  328. package/dist/structured-output/StructuredOutput.d.ts +27 -0
  329. package/dist/structured-output/StructuredOutput.d.ts.map +1 -0
  330. package/dist/structured-output/StructuredOutput.js +41 -0
  331. package/dist/structured-output/StructuredOutput.js.map +1 -0
  332. package/dist/testing.d.ts +80 -0
  333. package/dist/testing.d.ts.map +1 -0
  334. package/dist/testing.js +207 -0
  335. package/dist/testing.js.map +1 -0
  336. package/package.json +101 -0
  337. package/src/components/badge.tsx +31 -0
  338. package/src/components/checkbox.tsx +93 -0
  339. package/src/components/code-block.tsx +37 -0
  340. package/src/components/completion-input.tsx +137 -0
  341. package/src/components/components.css +2212 -0
  342. package/src/components/confirm-dialog.tsx +77 -0
  343. package/src/components/control-styles.ts +14 -0
  344. package/src/components/copy-field.tsx +178 -0
  345. package/src/components/dialog.tsx +76 -0
  346. package/src/components/drawer.tsx +83 -0
  347. package/src/components/error-boundary.tsx +56 -0
  348. package/src/components/extension-combo-builder.tsx +305 -0
  349. package/src/components/extension-grouping.ts +116 -0
  350. package/src/components/extension-picker.tsx +97 -0
  351. package/src/components/external-link.tsx +40 -0
  352. package/src/components/field.tsx +169 -0
  353. package/src/components/fleet-report.tsx +136 -0
  354. package/src/components/fonts.css +22 -0
  355. package/src/components/icons.tsx +504 -0
  356. package/src/components/inputs.tsx +125 -0
  357. package/src/components/json-diff.tsx +192 -0
  358. package/src/components/json-tree.tsx +129 -0
  359. package/src/components/modal-focus.ts +150 -0
  360. package/src/components/page-header.tsx +107 -0
  361. package/src/components/primitives.tsx +489 -0
  362. package/src/components/progress-bar.tsx +100 -0
  363. package/src/components/radio-group.tsx +160 -0
  364. package/src/components/reveal-input.tsx +87 -0
  365. package/src/components/scroll-region.tsx +703 -0
  366. package/src/components/select.tsx +149 -0
  367. package/src/components/table.tsx +94 -0
  368. package/src/components/tabs.tsx +51 -0
  369. package/src/components/tags.tsx +137 -0
  370. package/src/components/tokens.css +392 -0
  371. package/src/components/tokens.ts +102 -0
  372. package/src/components/tool-picker.tsx +175 -0
  373. package/src/components/tooltip.tsx +46 -0
  374. package/src/components/version-history-panel.tsx +407 -0
  375. package/src/css.d.ts +2 -0
  376. package/src/download.ts +17 -0
  377. package/src/element-slot.ts +22 -0
  378. package/src/elicitation/ElicitationForm.tsx +87 -0
  379. package/src/errors.ts +12 -0
  380. package/src/extension-combos.ts +18 -0
  381. package/src/hooks/useApi.ts +27 -0
  382. package/src/hooks/useAuth.ts +67 -0
  383. package/src/hooks/useBreakpoint.ts +78 -0
  384. package/src/hooks/useCapabilities.ts +242 -0
  385. package/src/hooks/useSse.ts +314 -0
  386. package/src/hooks/useTheme.ts +133 -0
  387. package/src/hooks/useUnauthorized.ts +20 -0
  388. package/src/host.ts +15 -0
  389. package/src/index.ts +267 -0
  390. package/src/navigation/context.tsx +90 -0
  391. package/src/navigation/index.ts +9 -0
  392. package/src/navigation/types.ts +90 -0
  393. package/src/plugin/host-state.ts +93 -0
  394. package/src/plugin/registry.ts +174 -0
  395. package/src/plugin/types.ts +178 -0
  396. package/src/plugin/version.ts +44 -0
  397. package/src/query-keys.ts +34 -0
  398. package/src/schema-editor/SchemaEditor.tsx +186 -0
  399. package/src/schema-editor/index.ts +9 -0
  400. package/src/schema-editor/lint.ts +70 -0
  401. package/src/schema-form/SchemaForm.tsx +107 -0
  402. package/src/schema-form/array-field.tsx +110 -0
  403. package/src/schema-form/classify.ts +302 -0
  404. package/src/schema-form/context.ts +17 -0
  405. package/src/schema-form/default-value.ts +65 -0
  406. package/src/schema-form/enum-field.tsx +65 -0
  407. package/src/schema-form/field-group.tsx +71 -0
  408. package/src/schema-form/field-node.tsx +161 -0
  409. package/src/schema-form/index.ts +12 -0
  410. package/src/schema-form/media-field.tsx +281 -0
  411. package/src/schema-form/media.ts +69 -0
  412. package/src/schema-form/object-fields.tsx +74 -0
  413. package/src/schema-form/resolve.ts +114 -0
  414. package/src/schema-form/string-field.tsx +161 -0
  415. package/src/schema-form/styles.ts +20 -0
  416. package/src/schema-form/types.ts +71 -0
  417. package/src/schema-form/union-field.tsx +122 -0
  418. package/src/schema-form/union.ts +78 -0
  419. package/src/schema-form/unsupported-notice.tsx +39 -0
  420. package/src/schema-form/validate.ts +183 -0
  421. package/src/structured-output/StructuredOutput.tsx +81 -0
  422. package/src/testing.ts +235 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * `SchemaForm` — the controlled, JSON-Schema-driven auto-form. Given a schema
3
+ * (as Pydantic v2 emits) plus a value and `onChange`, it renders the form and
4
+ * emits a plain JS value; the CALLER owns the submit button. It is the
5
+ * load-bearing renderer reused by the tools run panel and the interactions form
6
+ * answer format, which is why it lives in the SDK (features cannot import each
7
+ * other).
8
+ *
9
+ * SAFETY: every schema-derived string (title, description, enum label, notice)
10
+ * is rendered as TEXT through the DS components — React escapes it. No markdown,
11
+ * no HTML, no `dangerouslySetInnerHTML` sink ever touches a schema-supplied
12
+ * string. Pinned by a test.
13
+ *
14
+ * MEDIA UPLOADS: a string field renders as a file-upload / drag-drop control
15
+ * (instead of a text box) when its schema carries media annotations, so an
16
+ * image/file input stays a JSON-serializable string that round-trips through the
17
+ * normal submit path. The annotation contract:
18
+ * - `contentEncoding: "base64"` + `contentMediaType` (e.g. `"image/*"`,
19
+ * `"application/pdf"`) → the emitted value is the raw base64 body (no
20
+ * `data:` prefix); `contentMediaType` also constrains the accepted MIME.
21
+ * - `format: "data-url"` (optionally with `contentMediaType`) → the emitted
22
+ * value is a full `data:<mime>;base64,<body>` URL.
23
+ * - `contentMaxBytes` pins a per-field size cap (bytes); otherwise the
24
+ * {@link SchemaFormProps.maxUploadBytes} prop, else {@link DEFAULT_MAX_UPLOAD_BYTES}.
25
+ * An over-cap value or a MIME that does not match `contentMediaType` is REJECTED
26
+ * with a visible error — never silently truncated or accepted. The cap holds on
27
+ * EVERY input path (file picker, the paste fallback, and `validateAgainstSchema`),
28
+ * measured against the value's DECODED byte size. A text fallback (paste a
29
+ * URL/base64) stays available. The uploaded filename renders ESCAPED.
30
+ *
31
+ * `contentMaxBytes` is a NONSTANDARD JSON-Schema extension keyword (a standard
32
+ * validator ignores it); these client-side caps are UX guards, and the SERVER
33
+ * MUST independently validate the decoded size. The base64 decoding and cap
34
+ * checks live in the sibling `media` module.
35
+ */
36
+ import type { ReactNode } from 'react';
37
+ import type { JsonSchema, SchemaFormErrors } from './types';
38
+ /**
39
+ * Fetch argument-value suggestions for a string field. `argName` is the field's
40
+ * path within the form (a property key at the root, a dotted path when nested);
41
+ * `partial` is the value typed so far. The caller owns the source (e.g. an MCP
42
+ * `completion/complete` call) — SchemaForm only routes string fields through the
43
+ * completion-backed input when a provider is supplied.
44
+ */
45
+ export type CompletionProvider = (argName: string, partial: string) => Promise<string[]>;
46
+ export interface SchemaFormProps {
47
+ readonly schema: JsonSchema;
48
+ readonly value: unknown;
49
+ readonly onChange: (value: unknown) => void;
50
+ readonly errors?: SchemaFormErrors;
51
+ readonly idPrefix?: string;
52
+ /**
53
+ * Optional. When supplied, every string field renders through the
54
+ * completion-backed input (argument autocomplete); when omitted, string fields
55
+ * render as a plain text input — the default, unchanged behaviour.
56
+ */
57
+ readonly completionProvider?: CompletionProvider;
58
+ /**
59
+ * Optional. Default byte cap for media-upload fields (see the module
60
+ * doc-comment). A field's own `contentMaxBytes` annotation overrides it;
61
+ * absent both, {@link DEFAULT_MAX_UPLOAD_BYTES} applies.
62
+ */
63
+ readonly maxUploadBytes?: number;
64
+ }
65
+ /**
66
+ * Render a controlled form for `schema`. The root is usually an object (a tool's
67
+ * input schema); a scalar/array/union root renders as a single field group.
68
+ */
69
+ export declare function SchemaForm({ schema, value, onChange, errors, idPrefix, completionProvider, maxUploadBytes, }: SchemaFormProps): ReactNode;
70
+ //# sourceMappingURL=SchemaForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaForm.d.ts","sourceRoot":"","sources":["../../src/schema-form/SchemaForm.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAI5D;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AAEzF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACjD;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAwB,EACxB,kBAAkB,EAClB,cAAyC,GAC1C,EAAE,eAAe,GAAG,SAAS,CAoB7B"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { CompletionProviderContext, MaxUploadBytesContext } from './context';
3
+ import { FieldNode } from './field-node';
4
+ import { DEFAULT_MAX_UPLOAD_BYTES } from './media';
5
+ import { stackClass } from './styles';
6
+ /**
7
+ * Render a controlled form for `schema`. The root is usually an object (a tool's
8
+ * input schema); a scalar/array/union root renders as a single field group.
9
+ */
10
+ export function SchemaForm({ schema, value, onChange, errors, idPrefix = 'schema-form', completionProvider, maxUploadBytes = DEFAULT_MAX_UPLOAD_BYTES, }) {
11
+ return (_jsx(CompletionProviderContext.Provider, { value: completionProvider, children: _jsx(MaxUploadBytesContext.Provider, { value: maxUploadBytes, children: _jsx("div", { className: stackClass, "data-testid": idPrefix, children: _jsx(FieldNode, { schema: schema, root: schema, value: value, onChange: onChange, path: "", label: undefined, required: true, errors: errors, idPrefix: idPrefix }) }) }) }));
12
+ }
13
+ //# sourceMappingURL=SchemaForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaForm.js","sourceRoot":"","sources":["../../src/schema-form/SchemaForm.tsx"],"names":[],"mappings":";AAqCA,OAAO,EAAE,yBAAyB,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAkCtC;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,GAAG,aAAa,EACxB,kBAAkB,EAClB,cAAc,GAAG,wBAAwB,GACzB;IAChB,OAAO,CACL,KAAC,yBAAyB,CAAC,QAAQ,IAAC,KAAK,EAAE,kBAAkB,YAC3D,KAAC,qBAAqB,CAAC,QAAQ,IAAC,KAAK,EAAE,cAAc,YACnD,cAAK,SAAS,EAAE,UAAU,iBAAe,QAAQ,YAC/C,KAAC,SAAS,IACR,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAC,EAAE,EACP,KAAK,EAAE,SAAS,EAChB,QAAQ,QACR,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,GAClB,GACE,GACyB,GACE,CACtC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * The array field renderer. Each item is a nested {@link FieldNode}; edits map
3
+ * the list to a new array (add appends a seeded item, remove filters by index).
4
+ * The whole list re-renders as one controlled value, so index keys are correct.
5
+ */
6
+ import type { ReactNode } from 'react';
7
+ import type { JsonSchema, SchemaFormErrors } from './types';
8
+ export declare function ArrayField({ heading, description, error, items, root, value, onChange, path, errors, idPrefix, }: {
9
+ heading: string;
10
+ description: string | undefined;
11
+ error: string | undefined;
12
+ items: JsonSchema;
13
+ root: JsonSchema;
14
+ value: unknown;
15
+ onChange: (value: unknown) => void;
16
+ path: string;
17
+ errors: SchemaFormErrors | undefined;
18
+ idPrefix: string;
19
+ }): ReactNode;
20
+ //# sourceMappingURL=array-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/array-field.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAQvC,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE5D,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,WAAW,EACX,KAAK,EACL,KAAK,EACL,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,SAAS,CA0DZ"}
@@ -0,0 +1,39 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CloseIcon } from '../components/icons';
3
+ import { Button } from '../components/primitives';
4
+ import { classifySchema } from './classify';
5
+ import { defaultValueForSchema } from './default-value';
6
+ import { FieldGroup } from './field-group';
7
+ import { FieldNode } from './field-node';
8
+ export function ArrayField({ heading, description, error, items, root, value, onChange, path, errors, idPrefix, }) {
9
+ const list = Array.isArray(value) ? value : [];
10
+ const addItem = () => {
11
+ onChange([...list, newItemValue(items, root)]);
12
+ };
13
+ const removeItem = (index) => {
14
+ onChange(list.filter((_, position) => position !== index));
15
+ };
16
+ const setItem = (index, next) => {
17
+ onChange(list.map((item, position) => (position === index ? next : item)));
18
+ };
19
+ return (_jsxs(FieldGroup, { heading: heading, description: description, error: error, atRoot: false, children: [list.length === 0 ? _jsx("span", { className: "tai-field-hint", children: "No items" }) : null, list.map((item, index) => (_jsxs("div", { className: "tai-row", children: [_jsx("div", { style: { flex: 1 }, children: _jsx(FieldNode, { schema: items, root: root, value: item, onChange: (next) => {
20
+ setItem(index, next);
21
+ }, path: `${path}[${String(index)}]`, label: `Item ${String(index + 1)}`, required: true, errors: errors, idPrefix: idPrefix }) }), _jsxs(Button, { type: "button", variant: "secondary", "aria-label": `Remove item ${String(index + 1)}`, onClick: () => {
22
+ removeItem(index);
23
+ }, children: [_jsx(CloseIcon, {}), "Remove"] })] }, index))), _jsx("div", { children: _jsx(Button, { type: "button", variant: "secondary", onClick: addItem, children: "Add item" }) })] }));
24
+ }
25
+ function newItemValue(schema, root) {
26
+ const seeded = defaultValueForSchema(schema, root);
27
+ if (seeded !== undefined)
28
+ return seeded;
29
+ const classified = classifySchema(schema, root);
30
+ switch (classified.model.kind) {
31
+ case 'string':
32
+ return '';
33
+ case 'boolean':
34
+ return false;
35
+ default:
36
+ return undefined;
37
+ }
38
+ }
39
+ //# sourceMappingURL=array-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array-field.js","sourceRoot":"","sources":["../../src/schema-form/array-field.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * The single source of truth for "what kind of field is this schema?". Both the
3
+ * renderer and the validator classify through here so a construct is treated
4
+ * identically everywhere. Classification resolves `$ref`, normalizes `anyOf`/
5
+ * `oneOf` (null-union → nullable single field; multi-member → variant selector),
6
+ * and lands every unrecognized construct on the explicit `unsupported` kind —
7
+ * a field is never silently dropped.
8
+ */
9
+ import { type EnumOption } from './resolve';
10
+ import type { JsonSchema } from './types';
11
+ /**
12
+ * How a string field accepts binary content as a JSON-serializable string.
13
+ * Derived from a field's JSON-Schema media annotations (see the `SchemaForm` module).
14
+ */
15
+ export interface MediaUpload {
16
+ /**
17
+ * `base64` — the emitted value is the raw base64 body (no `data:` prefix),
18
+ * matching `contentEncoding: "base64"`. `data-url` — the emitted value is a
19
+ * full `data:<mime>;base64,<body>` URL, matching `format: "data-url"`.
20
+ */
21
+ readonly encoding: 'base64' | 'data-url';
22
+ /**
23
+ * The `contentMediaType` constraint (e.g. `image/*`, `application/pdf`), used
24
+ * for MIME validation and the file picker's `accept`. `undefined` for a bare
25
+ * `format: "data-url"` field with no declared type.
26
+ */
27
+ readonly mediaType: string | undefined;
28
+ /** A per-field byte cap from `contentMaxBytes`, if the schema pins one. */
29
+ readonly maxBytes: number | undefined;
30
+ }
31
+ /** One selectable variant of a union field. */
32
+ export interface UnionVariant {
33
+ readonly label: string;
34
+ /** The discriminator tag value, or `undefined` for a non-discriminated union. */
35
+ readonly tag: unknown;
36
+ /** The variant schema as written (unresolved — the renderer resolves it). */
37
+ readonly schema: JsonSchema;
38
+ }
39
+ /** The renderer-facing classification of a schema node. */
40
+ export type FieldModel = {
41
+ readonly kind: 'const';
42
+ readonly value: unknown;
43
+ } | {
44
+ readonly kind: 'enum';
45
+ readonly options: readonly EnumOption[];
46
+ } | {
47
+ readonly kind: 'string';
48
+ readonly format: string | undefined;
49
+ /** Present when media annotations opt the field into the upload control. */
50
+ readonly media: MediaUpload | undefined;
51
+ } | {
52
+ readonly kind: 'number';
53
+ readonly integer: boolean;
54
+ } | {
55
+ readonly kind: 'boolean';
56
+ } | {
57
+ readonly kind: 'array';
58
+ readonly items: JsonSchema;
59
+ } | {
60
+ readonly kind: 'object';
61
+ readonly properties: readonly (readonly [string, JsonSchema])[];
62
+ readonly required: ReadonlySet<string>;
63
+ } | {
64
+ readonly kind: 'union';
65
+ readonly variants: readonly UnionVariant[];
66
+ readonly discriminator: string | undefined;
67
+ } | {
68
+ readonly kind: 'unsupported';
69
+ readonly reason: string;
70
+ };
71
+ /** A fully classified field: its model plus resolved metadata. */
72
+ export interface ClassifiedField {
73
+ readonly model: FieldModel;
74
+ /** True when JSON `null` is an accepted value (a null-union member). */
75
+ readonly nullable: boolean;
76
+ /** The effective (ref-resolved) schema this classification describes. */
77
+ readonly schema: JsonSchema;
78
+ readonly title: string | undefined;
79
+ readonly description: string | undefined;
80
+ }
81
+ /**
82
+ * Classify a schema node (resolving `$ref` first). `wrapper` metadata (a
83
+ * ref-site title/description) is threaded down so a `{ $ref, title }` or a
84
+ * null-union wrapper keeps its property-level label.
85
+ */
86
+ export declare function classifySchema(raw: JsonSchema, root: JsonSchema): ClassifiedField;
87
+ //# sourceMappingURL=classify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/schema-form/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAQL,KAAK,UAAU,EAChB,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iFAAiF;IACjF,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;CAC7B;AAED,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,GAClE;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;CACzC,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACtD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GACtD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;IAChE,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACxC,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5C,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D,kEAAkE;AAClE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C;AAuCD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,GAAG,eAAe,CA6KjF"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * The single source of truth for "what kind of field is this schema?". Both the
3
+ * renderer and the validator classify through here so a construct is treated
4
+ * identically everywhere. Classification resolves `$ref`, normalizes `anyOf`/
5
+ * `oneOf` (null-union → nullable single field; multi-member → variant selector),
6
+ * and lands every unrecognized construct on the explicit `unsupported` kind —
7
+ * a field is never silently dropped.
8
+ */
9
+ import { isNullSchema, resolveRef, scalarLabel, typeList, unionMembers, variantLabel, variantTag, } from './resolve';
10
+ function firstString(...values) {
11
+ for (const value of values) {
12
+ if (typeof value === 'string' && value.length > 0)
13
+ return value;
14
+ }
15
+ return undefined;
16
+ }
17
+ /**
18
+ * Detect the media-upload annotations on a (ref-resolved) string schema. A field
19
+ * opts into the upload control when it carries `contentEncoding: "base64"` plus a
20
+ * `contentMediaType`, OR `format: "data-url"`. Anything else is a plain string.
21
+ */
22
+ function mediaUpload(schema) {
23
+ const mediaType = typeof schema.contentMediaType === 'string' ? schema.contentMediaType : undefined;
24
+ const maxBytes = typeof schema.contentMaxBytes === 'number' && schema.contentMaxBytes > 0
25
+ ? schema.contentMaxBytes
26
+ : undefined;
27
+ if (schema.format === 'data-url') {
28
+ return { encoding: 'data-url', mediaType, maxBytes };
29
+ }
30
+ if (schema.contentEncoding === 'base64' && mediaType !== undefined) {
31
+ return { encoding: 'base64', mediaType, maxBytes };
32
+ }
33
+ return undefined;
34
+ }
35
+ function unsupported(schema, reason, title, description) {
36
+ return { model: { kind: 'unsupported', reason }, nullable: false, schema, title, description };
37
+ }
38
+ /**
39
+ * Classify a schema node (resolving `$ref` first). `wrapper` metadata (a
40
+ * ref-site title/description) is threaded down so a `{ $ref, title }` or a
41
+ * null-union wrapper keeps its property-level label.
42
+ */
43
+ export function classifySchema(raw, root) {
44
+ const resolved = resolveRef(raw, root);
45
+ const title = firstString(raw.title, resolved.title);
46
+ const description = firstString(raw.description, resolved.description);
47
+ // const pins a single value.
48
+ if ('const' in resolved) {
49
+ return {
50
+ model: { kind: 'const', value: resolved.const },
51
+ nullable: false,
52
+ schema: resolved,
53
+ title,
54
+ description,
55
+ };
56
+ }
57
+ // enum → a fixed choice list.
58
+ if (resolved.enum !== undefined) {
59
+ const options = resolved.enum.map((value) => ({
60
+ value,
61
+ label: scalarLabel(value),
62
+ }));
63
+ const nullable = resolved.enum.some((value) => value === null);
64
+ return { model: { kind: 'enum', options }, nullable, schema: resolved, title, description };
65
+ }
66
+ // anyOf/oneOf union normalization.
67
+ const members = unionMembers(resolved);
68
+ if (members !== undefined) {
69
+ const nonNull = members.filter((member) => !isNullSchema(resolveRef(member, root)));
70
+ const nullable = nonNull.length !== members.length;
71
+ const soleNonNull = nonNull[0];
72
+ if (soleNonNull === undefined) {
73
+ return unsupported(resolved, 'union with no non-null members', title, description);
74
+ }
75
+ if (nonNull.length === 1) {
76
+ const inner = classifySchema(soleNonNull, root);
77
+ // Media annotations (`contentEncoding`/`contentMediaType`/`format: data-url`)
78
+ // that land on the OUTER null-union wrapper of an OPTIONAL field would
79
+ // otherwise be lost when delegating to the inner string member, silently
80
+ // degrading an optional upload field to a plain text box. Re-detect them on
81
+ // the wrapper and attach to the inner string model.
82
+ const model = inner.model.kind === 'string' && inner.model.media === undefined
83
+ ? { ...inner.model, media: mediaUpload(resolved) }
84
+ : inner.model;
85
+ return {
86
+ model,
87
+ nullable: nullable || inner.nullable,
88
+ schema: inner.schema,
89
+ title: title ?? inner.title,
90
+ description: description ?? inner.description,
91
+ };
92
+ }
93
+ const discriminator = resolved.discriminator?.propertyName;
94
+ const variants = nonNull.map((member, index) => {
95
+ const tag = discriminator === undefined ? undefined : variantTag(member, discriminator, root);
96
+ return { label: variantLabel(member, index, tag, root), tag, schema: member };
97
+ });
98
+ return {
99
+ model: { kind: 'union', variants, discriminator },
100
+ nullable,
101
+ schema: resolved,
102
+ title,
103
+ description,
104
+ };
105
+ }
106
+ // allOf: Pydantic wraps a single $ref this way; a multi-member intersection is
107
+ // not a form-renderable construct.
108
+ if (resolved.allOf !== undefined) {
109
+ const soleAllOf = resolved.allOf[0];
110
+ if (resolved.allOf.length === 1 && soleAllOf !== undefined) {
111
+ const inner = classifySchema(soleAllOf, root);
112
+ return {
113
+ model: inner.model,
114
+ nullable: inner.nullable,
115
+ schema: inner.schema,
116
+ title: title ?? inner.title,
117
+ description: description ?? inner.description,
118
+ };
119
+ }
120
+ return unsupported(resolved, 'allOf intersection of multiple schemas', title, description);
121
+ }
122
+ // Type-driven classification.
123
+ const types = typeList(resolved);
124
+ const nonNullTypes = types.filter((type) => type !== 'null');
125
+ const nullableByType = nonNullTypes.length !== types.length;
126
+ if (nonNullTypes.length === 0) {
127
+ return unsupported(resolved, 'schema declares no renderable type', title, description);
128
+ }
129
+ if (nonNullTypes.length > 1) {
130
+ return unsupported(resolved, `multiple JSON types (${nonNullTypes.join(', ')}) without a discriminator`, title, description);
131
+ }
132
+ const type = nonNullTypes[0];
133
+ if (type === undefined) {
134
+ return unsupported(resolved, 'schema declares no renderable type', title, description);
135
+ }
136
+ switch (type) {
137
+ case 'string':
138
+ return {
139
+ model: { kind: 'string', format: resolved.format, media: mediaUpload(resolved) },
140
+ nullable: nullableByType,
141
+ schema: resolved,
142
+ title,
143
+ description,
144
+ };
145
+ case 'number':
146
+ return {
147
+ model: { kind: 'number', integer: false },
148
+ nullable: nullableByType,
149
+ schema: resolved,
150
+ title,
151
+ description,
152
+ };
153
+ case 'integer':
154
+ return {
155
+ model: { kind: 'number', integer: true },
156
+ nullable: nullableByType,
157
+ schema: resolved,
158
+ title,
159
+ description,
160
+ };
161
+ case 'boolean':
162
+ return {
163
+ model: { kind: 'boolean' },
164
+ nullable: nullableByType,
165
+ schema: resolved,
166
+ title,
167
+ description,
168
+ };
169
+ case 'array': {
170
+ if (resolved.items === undefined) {
171
+ return unsupported(resolved, 'array without an items schema', title, description);
172
+ }
173
+ return {
174
+ model: { kind: 'array', items: resolved.items },
175
+ nullable: nullableByType,
176
+ schema: resolved,
177
+ title,
178
+ description,
179
+ };
180
+ }
181
+ case 'object': {
182
+ if (resolved.properties === undefined) {
183
+ return unsupported(resolved, 'free-form object (additionalProperties map) is not supported', title, description);
184
+ }
185
+ const properties = Object.entries(resolved.properties);
186
+ const required = new Set(resolved.required ?? []);
187
+ return {
188
+ model: { kind: 'object', properties, required },
189
+ nullable: nullableByType,
190
+ schema: resolved,
191
+ title,
192
+ description,
193
+ };
194
+ }
195
+ default:
196
+ return unsupported(resolved, `unrecognized type "${String(type)}"`, title, description);
197
+ }
198
+ }
199
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/schema-form/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { CompletionProvider } from './SchemaForm';
2
+ export declare const CompletionProviderContext: import("react").Context<CompletionProvider | undefined>;
3
+ export declare const MaxUploadBytesContext: import("react").Context<number>;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/schema-form/context.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAIvD,eAAO,MAAM,yBAAyB,yDAA2D,CAAC;AAIlG,eAAO,MAAM,qBAAqB,iCAAkD,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Ambient React contexts for the schema-form tree: the optional argument
3
+ * completion provider and the default media-upload byte cap. A field deep in the
4
+ * tree reads these here rather than every intermediate node drilling the prop.
5
+ */
6
+ import { createContext } from 'react';
7
+ import { DEFAULT_MAX_UPLOAD_BYTES } from './media';
8
+ // Ambient completion provider for the whole form. A string field deep in the
9
+ // tree reads it here rather than every intermediate node drilling the prop.
10
+ export const CompletionProviderContext = createContext(undefined);
11
+ // Ambient default upload cap for the whole form; a media field reads it here so
12
+ // intermediate object/array nodes never drill the prop.
13
+ export const MaxUploadBytesContext = createContext(DEFAULT_MAX_UPLOAD_BYTES);
14
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/schema-form/context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAGnD,6EAA6E;AAC7E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,yBAAyB,GAAG,aAAa,CAAiC,SAAS,CAAC,CAAC;AAElG,gFAAgF;AAChF,wDAAwD;AACxD,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAAS,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { JsonSchema } from './types';
2
+ /**
3
+ * The initial value for a schema. `root` carries the `$defs` document for
4
+ * `$ref` resolution and defaults to the schema itself (the common
5
+ * whole-tool-schema call).
6
+ */
7
+ export declare function defaultValueForSchema(schema: JsonSchema, root?: JsonSchema): unknown;
8
+ //# sourceMappingURL=default-value.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-value.d.ts","sourceRoot":"","sources":["../../src/schema-form/default-value.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAY1C;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,GAAE,UAAmB,GAAG,OAAO,CAiC5F"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * `defaultValueForSchema` — the initial form value for a schema, honoring
3
+ * `default`/`const` and seeding required nested structure.
4
+ *
5
+ * Inclusion rules keep the seed honest:
6
+ * - a REQUIRED property is seeded (objects → a nested seed, arrays → `[]`); a
7
+ * required scalar with no default is left ABSENT so validation flags it
8
+ * rather than inventing a value;
9
+ * - an OPTIONAL property is included only when it carries an explicit
10
+ * `default` — an optional object/array is NOT auto-materialized, so its own
11
+ * required children can't raise spurious errors on a field the user never
12
+ * opted into.
13
+ */
14
+ import { classifySchema } from './classify';
15
+ /** The explicit `default` (wrapper takes precedence over the resolved node), if any. */
16
+ function explicitDefault(raw, resolved) {
17
+ if ('default' in raw)
18
+ return { present: true, value: raw.default };
19
+ if ('default' in resolved)
20
+ return { present: true, value: resolved.default };
21
+ return { present: false, value: undefined };
22
+ }
23
+ /**
24
+ * The initial value for a schema. `root` carries the `$defs` document for
25
+ * `$ref` resolution and defaults to the schema itself (the common
26
+ * whole-tool-schema call).
27
+ */
28
+ export function defaultValueForSchema(schema, root = schema) {
29
+ const classified = classifySchema(schema, root);
30
+ const explicit = explicitDefault(schema, classified.schema);
31
+ if (explicit.present)
32
+ return explicit.value;
33
+ const { model } = classified;
34
+ switch (model.kind) {
35
+ case 'const':
36
+ return model.value;
37
+ case 'object': {
38
+ const result = {};
39
+ for (const [name, propSchema] of model.properties) {
40
+ if (model.required.has(name)) {
41
+ const seeded = defaultValueForSchema(propSchema, root);
42
+ if (seeded !== undefined)
43
+ result[name] = seeded;
44
+ continue;
45
+ }
46
+ const propClassified = classifySchema(propSchema, root);
47
+ const propDefault = explicitDefault(propSchema, propClassified.schema);
48
+ if (propDefault.present)
49
+ result[name] = propDefault.value;
50
+ }
51
+ return result;
52
+ }
53
+ case 'array':
54
+ return [];
55
+ case 'enum':
56
+ case 'string':
57
+ case 'number':
58
+ case 'boolean':
59
+ case 'union':
60
+ case 'unsupported':
61
+ return undefined;
62
+ }
63
+ }
64
+ //# sourceMappingURL=default-value.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-value.js","sourceRoot":"","sources":["../../src/schema-form/default-value.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG5C,wFAAwF;AACxF,SAAS,eAAe,CACtB,GAAe,EACf,QAAoB;IAEpB,IAAI,SAAS,IAAI,GAAG;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACnE,IAAI,SAAS,IAAI,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;IAC7E,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAkB,EAAE,OAAmB,MAAM;IACjF,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC,KAAK,CAAC;IAE5C,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC;IAC7B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,KAAK,CAAC;QACrB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,MAAM,GAA4B,EAAE,CAAC;YAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBAClD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7B,MAAM,MAAM,GAAG,qBAAqB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;oBACvD,IAAI,MAAM,KAAK,SAAS;wBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;oBAChD,SAAS;gBACX,CAAC;gBACD,MAAM,cAAc,GAAG,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;gBACxD,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;gBACvE,IAAI,WAAW,CAAC,OAAO;oBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;YAC5D,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,KAAK,OAAO;YACV,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,OAAO,CAAC;QACb,KAAK,aAAa;YAChB,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The enum field renderer. A short enum (up to {@link RADIO_MAX_OPTIONS}
3
+ * options) renders as a radio group; a longer one renders as a select. Options
4
+ * are keyed by index so a non-string enum value round-trips through the string
5
+ * control.
6
+ */
7
+ import type { ReactNode } from 'react';
8
+ import type { FieldModel } from './classify';
9
+ export declare function EnumField({ heading, description, error, model, value, onChange, }: {
10
+ heading: string;
11
+ description: string | undefined;
12
+ error: string | undefined;
13
+ model: Extract<FieldModel, {
14
+ kind: 'enum';
15
+ }>;
16
+ value: unknown;
17
+ onChange: (value: unknown) => void;
18
+ }): ReactNode;
19
+ //# sourceMappingURL=enum-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enum-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/enum-field.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,WAAW,EACX,KAAK,EACL,KAAK,EACL,KAAK,EACL,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7C,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,GAAG,SAAS,CAmCZ"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Field } from '../components/field';
3
+ import { RadioGroup } from '../components/radio-group';
4
+ import { Select } from '../components/select';
5
+ const RADIO_MAX_OPTIONS = 3;
6
+ export function EnumField({ heading, description, error, model, value, onChange, }) {
7
+ const options = model.options.map((option, index) => ({
8
+ key: String(index),
9
+ label: option.label,
10
+ value: option.value,
11
+ }));
12
+ const selected = options.find((option) => option.value === value);
13
+ // Always a defined string so the control stays controlled from first render
14
+ // (an `undefined` → string transition warns about uncontrolled→controlled).
15
+ const selectedKey = selected?.key ?? '';
16
+ const emit = (key) => {
17
+ const match = options.find((option) => option.key === key);
18
+ if (match !== undefined)
19
+ onChange(match.value);
20
+ };
21
+ if (options.length <= RADIO_MAX_OPTIONS) {
22
+ return (_jsx(Field, { label: heading, description: description, error: error, group: true, children: _jsx(RadioGroup, { options: options.map((option) => ({ value: option.key, label: option.label })), value: selectedKey, onValueChange: emit }) }));
23
+ }
24
+ return (_jsx(Field, { label: heading, description: description, error: error, children: _jsx(Select, { options: options.map((option) => ({ value: option.key, label: option.label })), value: selectedKey, onValueChange: emit }) }));
25
+ }
26
+ //# sourceMappingURL=enum-field.js.map