@tambo-ai/react 0.67.1 → 0.69.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 (424) hide show
  1. package/README.md +3 -5
  2. package/dist/context-helpers/context-helpers.test.js +16 -4
  3. package/dist/context-helpers/context-helpers.test.js.map +1 -1
  4. package/dist/context-helpers/current-interactables-context-helper.d.ts +2 -2
  5. package/dist/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  6. package/dist/context-helpers/current-interactables-context-helper.js +31 -12
  7. package/dist/context-helpers/current-interactables-context-helper.js.map +1 -1
  8. package/dist/context-helpers/registry.d.ts +2 -2
  9. package/dist/context-helpers/registry.d.ts.map +1 -1
  10. package/dist/context-helpers/registry.js.map +1 -1
  11. package/dist/context-helpers/types.d.ts +2 -2
  12. package/dist/context-helpers/types.d.ts.map +1 -1
  13. package/dist/context-helpers/types.js.map +1 -1
  14. package/dist/hoc/with-tambo-interactable.d.ts +50 -4
  15. package/dist/hoc/with-tambo-interactable.d.ts.map +1 -1
  16. package/dist/hoc/with-tambo-interactable.js +20 -5
  17. package/dist/hoc/with-tambo-interactable.js.map +1 -1
  18. package/dist/hooks/use-component-state.d.ts +3 -8
  19. package/dist/hooks/use-component-state.d.ts.map +1 -1
  20. package/dist/hooks/use-component-state.js +8 -0
  21. package/dist/hooks/use-component-state.js.map +1 -1
  22. package/dist/hooks/use-component-state.test.js +37 -0
  23. package/dist/hooks/use-component-state.test.js.map +1 -1
  24. package/dist/hooks/use-message-images.test.js +174 -37
  25. package/dist/hooks/use-message-images.test.js.map +1 -1
  26. package/dist/hooks/use-tambo-threads.js +1 -1
  27. package/dist/hooks/use-tambo-threads.js.map +1 -1
  28. package/dist/hooks/use-tambo-voice.d.ts +1 -1
  29. package/dist/hooks/use-tambo-voice.js +1 -1
  30. package/dist/hooks/use-tambo-voice.js.map +1 -1
  31. package/dist/hooks/use-tambo-voice.test.d.ts +2 -0
  32. package/dist/hooks/use-tambo-voice.test.d.ts.map +1 -0
  33. package/dist/hooks/use-tambo-voice.test.js +239 -0
  34. package/dist/hooks/use-tambo-voice.test.js.map +1 -0
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js.map +1 -1
  38. package/dist/mcp/elicitation.d.ts.map +1 -1
  39. package/dist/mcp/elicitation.js +12 -0
  40. package/dist/mcp/elicitation.js.map +1 -1
  41. package/dist/mcp/elicitation.test.js +8 -1
  42. package/dist/mcp/elicitation.test.js.map +1 -1
  43. package/dist/mcp/mcp-client.d.ts +6 -10
  44. package/dist/mcp/mcp-client.d.ts.map +1 -1
  45. package/dist/mcp/mcp-client.js.map +1 -1
  46. package/dist/mcp/mcp-constants.d.ts +19 -0
  47. package/dist/mcp/mcp-constants.d.ts.map +1 -0
  48. package/dist/mcp/mcp-constants.js +21 -0
  49. package/dist/mcp/mcp-constants.js.map +1 -0
  50. package/dist/mcp/mcp-hooks.d.ts +21 -40
  51. package/dist/mcp/mcp-hooks.d.ts.map +1 -1
  52. package/dist/mcp/mcp-hooks.js +130 -39
  53. package/dist/mcp/mcp-hooks.js.map +1 -1
  54. package/dist/mcp/mcp-hooks.test.js +431 -5
  55. package/dist/mcp/mcp-hooks.test.js.map +1 -1
  56. package/dist/mcp/tambo-mcp-provider.d.ts +7 -0
  57. package/dist/mcp/tambo-mcp-provider.d.ts.map +1 -1
  58. package/dist/mcp/tambo-mcp-provider.js +205 -155
  59. package/dist/mcp/tambo-mcp-provider.js.map +1 -1
  60. package/dist/mcp/tambo-mcp-provider.test.js +37 -0
  61. package/dist/mcp/tambo-mcp-provider.test.js.map +1 -1
  62. package/dist/model/component-metadata.d.ts +54 -21
  63. package/dist/model/component-metadata.d.ts.map +1 -1
  64. package/dist/model/component-metadata.js.map +1 -1
  65. package/dist/model/tambo-interactable.d.ts +13 -5
  66. package/dist/model/tambo-interactable.d.ts.map +1 -1
  67. package/dist/model/tambo-interactable.js.map +1 -1
  68. package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
  69. package/dist/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
  70. package/dist/providers/__tests__/thread-input-resource-resolution.test.js +592 -0
  71. package/dist/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
  72. package/dist/providers/index.d.ts +1 -1
  73. package/dist/providers/index.d.ts.map +1 -1
  74. package/dist/providers/index.js.map +1 -1
  75. package/dist/providers/tambo-client-provider.d.ts +8 -0
  76. package/dist/providers/tambo-client-provider.d.ts.map +1 -1
  77. package/dist/providers/tambo-client-provider.js +10 -11
  78. package/dist/providers/tambo-client-provider.js.map +1 -1
  79. package/dist/providers/tambo-client-provider.test.d.ts +2 -0
  80. package/dist/providers/tambo-client-provider.test.d.ts.map +1 -0
  81. package/dist/providers/tambo-client-provider.test.js +208 -0
  82. package/dist/providers/tambo-client-provider.test.js.map +1 -0
  83. package/dist/providers/tambo-context-attachment-provider.d.ts +34 -92
  84. package/dist/providers/tambo-context-attachment-provider.d.ts.map +1 -1
  85. package/dist/providers/tambo-context-attachment-provider.js +62 -105
  86. package/dist/providers/tambo-context-attachment-provider.js.map +1 -1
  87. package/dist/providers/tambo-context-attachment-provider.test.js +229 -463
  88. package/dist/providers/tambo-context-attachment-provider.test.js.map +1 -1
  89. package/dist/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
  90. package/dist/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  91. package/dist/providers/tambo-interactable-provider.d.ts +5 -2
  92. package/dist/providers/tambo-interactable-provider.d.ts.map +1 -1
  93. package/dist/providers/tambo-interactable-provider.js +126 -17
  94. package/dist/providers/tambo-interactable-provider.js.map +1 -1
  95. package/dist/providers/tambo-interactable-provider.test.js +242 -0
  96. package/dist/providers/tambo-interactable-provider.test.js.map +1 -1
  97. package/dist/providers/tambo-interactables-additional-context.test.js +2 -5
  98. package/dist/providers/tambo-interactables-additional-context.test.js.map +1 -1
  99. package/dist/providers/tambo-provider.d.ts +2 -3
  100. package/dist/providers/tambo-provider.d.ts.map +1 -1
  101. package/dist/providers/tambo-provider.js +6 -5
  102. package/dist/providers/tambo-provider.js.map +1 -1
  103. package/dist/providers/tambo-registry-provider.test.js +16 -0
  104. package/dist/providers/tambo-registry-provider.test.js.map +1 -1
  105. package/dist/providers/tambo-registry-schema-compat.test.js +31 -0
  106. package/dist/providers/tambo-registry-schema-compat.test.js.map +1 -1
  107. package/dist/providers/tambo-thread-input-provider.d.ts +1 -1
  108. package/dist/providers/tambo-thread-input-provider.d.ts.map +1 -1
  109. package/dist/providers/tambo-thread-input-provider.js +26 -4
  110. package/dist/providers/tambo-thread-input-provider.js.map +1 -1
  111. package/dist/providers/tambo-thread-provider-initial-messages.test.js +84 -2
  112. package/dist/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  113. package/dist/providers/tambo-thread-provider.d.ts.map +1 -1
  114. package/dist/providers/tambo-thread-provider.js +53 -42
  115. package/dist/providers/tambo-thread-provider.js.map +1 -1
  116. package/dist/providers/tambo-thread-provider.test.js +368 -262
  117. package/dist/providers/tambo-thread-provider.test.js.map +1 -1
  118. package/dist/schema/index.d.ts +1 -1
  119. package/dist/schema/index.d.ts.map +1 -1
  120. package/dist/schema/index.js +2 -1
  121. package/dist/schema/index.js.map +1 -1
  122. package/dist/schema/json-schema.d.ts +7 -0
  123. package/dist/schema/json-schema.d.ts.map +1 -1
  124. package/dist/schema/json-schema.js +40 -29
  125. package/dist/schema/json-schema.js.map +1 -1
  126. package/dist/schema/json-schema.test.d.ts +2 -0
  127. package/dist/schema/json-schema.test.d.ts.map +1 -0
  128. package/dist/schema/json-schema.test.js +204 -0
  129. package/dist/schema/json-schema.test.js.map +1 -0
  130. package/dist/schema/schema.test.js +237 -0
  131. package/dist/schema/schema.test.js.map +1 -1
  132. package/dist/schema/standard-schema.d.ts +1 -0
  133. package/dist/schema/standard-schema.d.ts.map +1 -1
  134. package/dist/schema/standard-schema.js +18 -13
  135. package/dist/schema/standard-schema.js.map +1 -1
  136. package/dist/schema/standard-schema.test.d.ts +2 -0
  137. package/dist/schema/standard-schema.test.d.ts.map +1 -0
  138. package/dist/schema/standard-schema.test.js +165 -0
  139. package/dist/schema/standard-schema.test.js.map +1 -0
  140. package/dist/schema/validate.test.js +149 -0
  141. package/dist/schema/validate.test.js.map +1 -1
  142. package/dist/schema/zod.d.ts +7 -4
  143. package/dist/schema/zod.d.ts.map +1 -1
  144. package/dist/schema/zod.js +65 -22
  145. package/dist/schema/zod.js.map +1 -1
  146. package/dist/schema/zod.test.js +112 -0
  147. package/dist/schema/zod.test.js.map +1 -1
  148. package/dist/setupTests.js +3 -0
  149. package/dist/setupTests.js.map +1 -1
  150. package/dist/testing/tools.d.ts +4 -1
  151. package/dist/testing/tools.d.ts.map +1 -1
  152. package/dist/testing/tools.js +6 -1
  153. package/dist/testing/tools.js.map +1 -1
  154. package/dist/util/generate-component.d.ts.map +1 -1
  155. package/dist/util/generate-component.js +18 -3
  156. package/dist/util/generate-component.js.map +1 -1
  157. package/dist/util/generate-component.test.d.ts +2 -0
  158. package/dist/util/generate-component.test.d.ts.map +1 -0
  159. package/dist/util/generate-component.test.js +340 -0
  160. package/dist/util/generate-component.test.js.map +1 -0
  161. package/dist/util/is-promise.d.ts +9 -0
  162. package/dist/util/is-promise.d.ts.map +1 -0
  163. package/dist/util/is-promise.js +20 -0
  164. package/dist/util/is-promise.js.map +1 -0
  165. package/dist/util/is-promise.test.d.ts +2 -0
  166. package/dist/util/is-promise.test.d.ts.map +1 -0
  167. package/dist/util/is-promise.test.js +48 -0
  168. package/dist/util/is-promise.test.js.map +1 -0
  169. package/dist/util/message-builder.d.ts +3 -1
  170. package/dist/util/message-builder.d.ts.map +1 -1
  171. package/dist/util/message-builder.js +20 -3
  172. package/dist/util/message-builder.js.map +1 -1
  173. package/dist/util/message-builder.test.js +269 -0
  174. package/dist/util/message-builder.test.js.map +1 -1
  175. package/dist/util/query-utils.test.d.ts +2 -0
  176. package/dist/util/query-utils.test.d.ts.map +1 -0
  177. package/dist/util/query-utils.test.js +382 -0
  178. package/dist/util/query-utils.test.js.map +1 -0
  179. package/dist/util/registry-validators.d.ts.map +1 -1
  180. package/dist/util/registry-validators.js +7 -0
  181. package/dist/util/registry-validators.js.map +1 -1
  182. package/dist/util/registry-validators.test.js +57 -0
  183. package/dist/util/registry-validators.test.js.map +1 -1
  184. package/dist/util/registry.d.ts.map +1 -1
  185. package/dist/util/registry.js +9 -0
  186. package/dist/util/registry.js.map +1 -1
  187. package/dist/util/registry.test.js +323 -1
  188. package/dist/util/registry.test.js.map +1 -1
  189. package/dist/util/resource-content-resolver.d.ts +20 -0
  190. package/dist/util/resource-content-resolver.d.ts.map +1 -0
  191. package/dist/util/resource-content-resolver.js +93 -0
  192. package/dist/util/resource-content-resolver.js.map +1 -0
  193. package/dist/util/resource-content-resolver.test.d.ts +2 -0
  194. package/dist/util/resource-content-resolver.test.d.ts.map +1 -0
  195. package/dist/util/resource-content-resolver.test.js +254 -0
  196. package/dist/util/resource-content-resolver.test.js.map +1 -0
  197. package/dist/util/resource-validators.test.d.ts +2 -0
  198. package/dist/util/resource-validators.test.d.ts.map +1 -0
  199. package/dist/util/resource-validators.test.js +90 -0
  200. package/dist/util/resource-validators.test.js.map +1 -0
  201. package/dist/util/tool-caller.d.ts +2 -2
  202. package/dist/util/tool-caller.d.ts.map +1 -1
  203. package/dist/util/tool-caller.js +8 -8
  204. package/dist/util/tool-caller.js.map +1 -1
  205. package/dist/util/validate-component-name.test.d.ts +2 -0
  206. package/dist/util/validate-component-name.test.d.ts.map +1 -0
  207. package/dist/util/validate-component-name.test.js +35 -0
  208. package/dist/util/validate-component-name.test.js.map +1 -0
  209. package/esm/context-helpers/context-helpers.test.js +16 -4
  210. package/esm/context-helpers/context-helpers.test.js.map +1 -1
  211. package/esm/context-helpers/current-interactables-context-helper.d.ts +2 -2
  212. package/esm/context-helpers/current-interactables-context-helper.d.ts.map +1 -1
  213. package/esm/context-helpers/current-interactables-context-helper.js +31 -12
  214. package/esm/context-helpers/current-interactables-context-helper.js.map +1 -1
  215. package/esm/context-helpers/registry.d.ts +2 -2
  216. package/esm/context-helpers/registry.d.ts.map +1 -1
  217. package/esm/context-helpers/registry.js.map +1 -1
  218. package/esm/context-helpers/types.d.ts +2 -2
  219. package/esm/context-helpers/types.d.ts.map +1 -1
  220. package/esm/context-helpers/types.js.map +1 -1
  221. package/esm/hoc/with-tambo-interactable.d.ts +50 -4
  222. package/esm/hoc/with-tambo-interactable.d.ts.map +1 -1
  223. package/esm/hoc/with-tambo-interactable.js +20 -5
  224. package/esm/hoc/with-tambo-interactable.js.map +1 -1
  225. package/esm/hooks/use-component-state.d.ts +3 -8
  226. package/esm/hooks/use-component-state.d.ts.map +1 -1
  227. package/esm/hooks/use-component-state.js +8 -0
  228. package/esm/hooks/use-component-state.js.map +1 -1
  229. package/esm/hooks/use-component-state.test.js +37 -0
  230. package/esm/hooks/use-component-state.test.js.map +1 -1
  231. package/esm/hooks/use-message-images.test.js +174 -37
  232. package/esm/hooks/use-message-images.test.js.map +1 -1
  233. package/esm/hooks/use-tambo-threads.js +1 -1
  234. package/esm/hooks/use-tambo-threads.js.map +1 -1
  235. package/esm/hooks/use-tambo-voice.d.ts +1 -1
  236. package/esm/hooks/use-tambo-voice.js +1 -1
  237. package/esm/hooks/use-tambo-voice.js.map +1 -1
  238. package/esm/hooks/use-tambo-voice.test.d.ts +2 -0
  239. package/esm/hooks/use-tambo-voice.test.d.ts.map +1 -0
  240. package/esm/hooks/use-tambo-voice.test.js +234 -0
  241. package/esm/hooks/use-tambo-voice.test.js.map +1 -0
  242. package/esm/index.d.ts +2 -2
  243. package/esm/index.d.ts.map +1 -1
  244. package/esm/index.js.map +1 -1
  245. package/esm/mcp/elicitation.d.ts.map +1 -1
  246. package/esm/mcp/elicitation.js +12 -0
  247. package/esm/mcp/elicitation.js.map +1 -1
  248. package/esm/mcp/elicitation.test.js +8 -1
  249. package/esm/mcp/elicitation.test.js.map +1 -1
  250. package/esm/mcp/mcp-client.d.ts +6 -10
  251. package/esm/mcp/mcp-client.d.ts.map +1 -1
  252. package/esm/mcp/mcp-client.js.map +1 -1
  253. package/esm/mcp/mcp-constants.d.ts +19 -0
  254. package/esm/mcp/mcp-constants.d.ts.map +1 -0
  255. package/esm/mcp/mcp-constants.js +18 -0
  256. package/esm/mcp/mcp-constants.js.map +1 -0
  257. package/esm/mcp/mcp-hooks.d.ts +21 -40
  258. package/esm/mcp/mcp-hooks.d.ts.map +1 -1
  259. package/esm/mcp/mcp-hooks.js +97 -40
  260. package/esm/mcp/mcp-hooks.js.map +1 -1
  261. package/esm/mcp/mcp-hooks.test.js +431 -5
  262. package/esm/mcp/mcp-hooks.test.js.map +1 -1
  263. package/esm/mcp/tambo-mcp-provider.d.ts +7 -0
  264. package/esm/mcp/tambo-mcp-provider.d.ts.map +1 -1
  265. package/esm/mcp/tambo-mcp-provider.js +204 -154
  266. package/esm/mcp/tambo-mcp-provider.js.map +1 -1
  267. package/esm/mcp/tambo-mcp-provider.test.js +37 -0
  268. package/esm/mcp/tambo-mcp-provider.test.js.map +1 -1
  269. package/esm/model/component-metadata.d.ts +54 -21
  270. package/esm/model/component-metadata.d.ts.map +1 -1
  271. package/esm/model/component-metadata.js.map +1 -1
  272. package/esm/model/tambo-interactable.d.ts +13 -5
  273. package/esm/model/tambo-interactable.d.ts.map +1 -1
  274. package/esm/model/tambo-interactable.js.map +1 -1
  275. package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts +2 -0
  276. package/esm/providers/__tests__/thread-input-resource-resolution.test.d.ts.map +1 -0
  277. package/esm/providers/__tests__/thread-input-resource-resolution.test.js +587 -0
  278. package/esm/providers/__tests__/thread-input-resource-resolution.test.js.map +1 -0
  279. package/esm/providers/index.d.ts +1 -1
  280. package/esm/providers/index.d.ts.map +1 -1
  281. package/esm/providers/index.js.map +1 -1
  282. package/esm/providers/tambo-client-provider.d.ts +8 -0
  283. package/esm/providers/tambo-client-provider.d.ts.map +1 -1
  284. package/esm/providers/tambo-client-provider.js +11 -12
  285. package/esm/providers/tambo-client-provider.js.map +1 -1
  286. package/esm/providers/tambo-client-provider.test.d.ts +2 -0
  287. package/esm/providers/tambo-client-provider.test.d.ts.map +1 -0
  288. package/esm/providers/tambo-client-provider.test.js +203 -0
  289. package/esm/providers/tambo-client-provider.test.js.map +1 -0
  290. package/esm/providers/tambo-context-attachment-provider.d.ts +34 -92
  291. package/esm/providers/tambo-context-attachment-provider.d.ts.map +1 -1
  292. package/esm/providers/tambo-context-attachment-provider.js +63 -106
  293. package/esm/providers/tambo-context-attachment-provider.js.map +1 -1
  294. package/esm/providers/tambo-context-attachment-provider.test.js +230 -464
  295. package/esm/providers/tambo-context-attachment-provider.test.js.map +1 -1
  296. package/esm/providers/tambo-interactable-provider-partial-updates.test.js +22 -21
  297. package/esm/providers/tambo-interactable-provider-partial-updates.test.js.map +1 -1
  298. package/esm/providers/tambo-interactable-provider.d.ts +5 -2
  299. package/esm/providers/tambo-interactable-provider.d.ts.map +1 -1
  300. package/esm/providers/tambo-interactable-provider.js +126 -17
  301. package/esm/providers/tambo-interactable-provider.js.map +1 -1
  302. package/esm/providers/tambo-interactable-provider.test.js +242 -0
  303. package/esm/providers/tambo-interactable-provider.test.js.map +1 -1
  304. package/esm/providers/tambo-interactables-additional-context.test.js +2 -5
  305. package/esm/providers/tambo-interactables-additional-context.test.js.map +1 -1
  306. package/esm/providers/tambo-provider.d.ts +2 -3
  307. package/esm/providers/tambo-provider.d.ts.map +1 -1
  308. package/esm/providers/tambo-provider.js +6 -5
  309. package/esm/providers/tambo-provider.js.map +1 -1
  310. package/esm/providers/tambo-registry-provider.test.js +16 -0
  311. package/esm/providers/tambo-registry-provider.test.js.map +1 -1
  312. package/esm/providers/tambo-registry-schema-compat.test.js +31 -0
  313. package/esm/providers/tambo-registry-schema-compat.test.js.map +1 -1
  314. package/esm/providers/tambo-thread-input-provider.d.ts +1 -1
  315. package/esm/providers/tambo-thread-input-provider.d.ts.map +1 -1
  316. package/esm/providers/tambo-thread-input-provider.js +26 -4
  317. package/esm/providers/tambo-thread-input-provider.js.map +1 -1
  318. package/esm/providers/tambo-thread-provider-initial-messages.test.js +84 -2
  319. package/esm/providers/tambo-thread-provider-initial-messages.test.js.map +1 -1
  320. package/esm/providers/tambo-thread-provider.d.ts.map +1 -1
  321. package/esm/providers/tambo-thread-provider.js +53 -42
  322. package/esm/providers/tambo-thread-provider.js.map +1 -1
  323. package/esm/providers/tambo-thread-provider.test.js +368 -262
  324. package/esm/providers/tambo-thread-provider.test.js.map +1 -1
  325. package/esm/schema/index.d.ts +1 -1
  326. package/esm/schema/index.d.ts.map +1 -1
  327. package/esm/schema/index.js +1 -1
  328. package/esm/schema/index.js.map +1 -1
  329. package/esm/schema/json-schema.d.ts +7 -0
  330. package/esm/schema/json-schema.d.ts.map +1 -1
  331. package/esm/schema/json-schema.js +11 -1
  332. package/esm/schema/json-schema.js.map +1 -1
  333. package/esm/schema/json-schema.test.d.ts +2 -0
  334. package/esm/schema/json-schema.test.d.ts.map +1 -0
  335. package/esm/schema/json-schema.test.js +202 -0
  336. package/esm/schema/json-schema.test.js.map +1 -0
  337. package/esm/schema/schema.test.js +238 -1
  338. package/esm/schema/schema.test.js.map +1 -1
  339. package/esm/schema/standard-schema.d.ts +1 -0
  340. package/esm/schema/standard-schema.d.ts.map +1 -1
  341. package/esm/schema/standard-schema.js +18 -13
  342. package/esm/schema/standard-schema.js.map +1 -1
  343. package/esm/schema/standard-schema.test.d.ts +2 -0
  344. package/esm/schema/standard-schema.test.d.ts.map +1 -0
  345. package/esm/schema/standard-schema.test.js +130 -0
  346. package/esm/schema/standard-schema.test.js.map +1 -0
  347. package/esm/schema/validate.test.js +149 -0
  348. package/esm/schema/validate.test.js.map +1 -1
  349. package/esm/schema/zod.d.ts +7 -4
  350. package/esm/schema/zod.d.ts.map +1 -1
  351. package/esm/schema/zod.js +65 -22
  352. package/esm/schema/zod.js.map +1 -1
  353. package/esm/schema/zod.test.js +113 -1
  354. package/esm/schema/zod.test.js.map +1 -1
  355. package/esm/setupTests.js +3 -0
  356. package/esm/setupTests.js.map +1 -1
  357. package/esm/testing/tools.d.ts +4 -1
  358. package/esm/testing/tools.d.ts.map +1 -1
  359. package/esm/testing/tools.js +6 -1
  360. package/esm/testing/tools.js.map +1 -1
  361. package/esm/util/generate-component.d.ts.map +1 -1
  362. package/esm/util/generate-component.js +18 -3
  363. package/esm/util/generate-component.js.map +1 -1
  364. package/esm/util/generate-component.test.d.ts +2 -0
  365. package/esm/util/generate-component.test.d.ts.map +1 -0
  366. package/esm/util/generate-component.test.js +302 -0
  367. package/esm/util/generate-component.test.js.map +1 -0
  368. package/esm/util/is-promise.d.ts +9 -0
  369. package/esm/util/is-promise.d.ts.map +1 -0
  370. package/esm/util/is-promise.js +17 -0
  371. package/esm/util/is-promise.js.map +1 -0
  372. package/esm/util/is-promise.test.d.ts +2 -0
  373. package/esm/util/is-promise.test.d.ts.map +1 -0
  374. package/esm/util/is-promise.test.js +46 -0
  375. package/esm/util/is-promise.test.js.map +1 -0
  376. package/esm/util/message-builder.d.ts +3 -1
  377. package/esm/util/message-builder.d.ts.map +1 -1
  378. package/esm/util/message-builder.js +20 -3
  379. package/esm/util/message-builder.js.map +1 -1
  380. package/esm/util/message-builder.test.js +269 -0
  381. package/esm/util/message-builder.test.js.map +1 -1
  382. package/esm/util/query-utils.test.d.ts +2 -0
  383. package/esm/util/query-utils.test.d.ts.map +1 -0
  384. package/esm/util/query-utils.test.js +380 -0
  385. package/esm/util/query-utils.test.js.map +1 -0
  386. package/esm/util/registry-validators.d.ts.map +1 -1
  387. package/esm/util/registry-validators.js +7 -0
  388. package/esm/util/registry-validators.js.map +1 -1
  389. package/esm/util/registry-validators.test.js +57 -0
  390. package/esm/util/registry-validators.test.js.map +1 -1
  391. package/esm/util/registry.d.ts.map +1 -1
  392. package/esm/util/registry.js +9 -0
  393. package/esm/util/registry.js.map +1 -1
  394. package/esm/util/registry.test.js +324 -2
  395. package/esm/util/registry.test.js.map +1 -1
  396. package/esm/util/resource-content-resolver.d.ts +20 -0
  397. package/esm/util/resource-content-resolver.d.ts.map +1 -0
  398. package/esm/util/resource-content-resolver.js +89 -0
  399. package/esm/util/resource-content-resolver.js.map +1 -0
  400. package/esm/util/resource-content-resolver.test.d.ts +2 -0
  401. package/esm/util/resource-content-resolver.test.d.ts.map +1 -0
  402. package/esm/util/resource-content-resolver.test.js +252 -0
  403. package/esm/util/resource-content-resolver.test.js.map +1 -0
  404. package/esm/util/resource-validators.test.d.ts +2 -0
  405. package/esm/util/resource-validators.test.d.ts.map +1 -0
  406. package/esm/util/resource-validators.test.js +88 -0
  407. package/esm/util/resource-validators.test.js.map +1 -0
  408. package/esm/util/tool-caller.d.ts +2 -2
  409. package/esm/util/tool-caller.d.ts.map +1 -1
  410. package/esm/util/tool-caller.js +8 -8
  411. package/esm/util/tool-caller.js.map +1 -1
  412. package/esm/util/validate-component-name.test.d.ts +2 -0
  413. package/esm/util/validate-component-name.test.d.ts.map +1 -0
  414. package/esm/util/validate-component-name.test.js +33 -0
  415. package/esm/util/validate-component-name.test.js.map +1 -0
  416. package/package.json +15 -23
  417. package/dist/schema/alias.d.ts +0 -3
  418. package/dist/schema/alias.d.ts.map +0 -1
  419. package/dist/schema/alias.js +0 -6
  420. package/dist/schema/alias.js.map +0 -1
  421. package/esm/schema/alias.d.ts +0 -3
  422. package/esm/schema/alias.d.ts.map +0 -1
  423. package/esm/schema/alias.js +0 -13
  424. package/esm/schema/alias.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EACL,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,eAAe,GACrB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC"}
@@ -1,4 +1,4 @@
1
- export { looksLikeJSONSchema } from "./json-schema";
1
+ export { looksLikeJSONSchema, makeJsonSchemaPartial } from "./json-schema";
2
2
  export { getParametersFromToolSchema, hasInputSchema, safeSchemaToJsonSchema, schemaToJsonSchema, } from "./schema";
3
3
  export { isStandardSchema } from "./standard-schema";
4
4
  export { assertNoRecordSchema } from "./validate";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,kBAAkB,GAEnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC","sourcesContent":["export { looksLikeJSONSchema } from \"./json-schema\";\nexport {\n getParametersFromToolSchema,\n hasInputSchema,\n safeSchemaToJsonSchema,\n schemaToJsonSchema,\n type SupportedSchema,\n} from \"./schema\";\nexport { isStandardSchema } from \"./standard-schema\";\nexport { assertNoRecordSchema } from \"./validate\";\nexport { getZodFunctionArgs, getZodFunctionReturns } from \"./zod\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EACL,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,kBAAkB,GAEnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC","sourcesContent":["export { looksLikeJSONSchema, makeJsonSchemaPartial } from \"./json-schema\";\nexport {\n getParametersFromToolSchema,\n hasInputSchema,\n safeSchemaToJsonSchema,\n schemaToJsonSchema,\n type SupportedSchema,\n} from \"./schema\";\nexport { isStandardSchema } from \"./standard-schema\";\nexport { assertNoRecordSchema } from \"./validate\";\nexport { getZodFunctionArgs, getZodFunctionReturns } from \"./zod\";\n"]}
@@ -32,4 +32,11 @@ export declare function isJsonSchemaTuple(schema: JSONSchema7Extended): schema i
32
32
  * @returns Array of item schemas, or undefined if not a tuple
33
33
  */
34
34
  export declare function getJsonSchemaTupleItems(schema: JSONSchema7Extended): JSONSchema7[] | undefined;
35
+ /**
36
+ * Creates a partial version of a JSON Schema by removing required constraints.
37
+ * This allows LLM to provide only the properties it wants to update.
38
+ * @param schema - The JSON Schema to make partial
39
+ * @returns A new JSON Schema with the required constraint removed
40
+ */
41
+ export declare function makeJsonSchemaPartial(schema: JSONSchema7): JSONSchema7;
35
42
  //# sourceMappingURL=json-schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../../src/schema/json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkD1C;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,WAAW,CAMpE;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,mBAAmB,GAC1B,MAAM,IAAI,mBAAmB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAgBnD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,mBAAmB,GAC1B,WAAW,EAAE,GAAG,SAAS,CAgB3B"}
1
+ {"version":3,"file":"json-schema.d.ts","sourceRoot":"","sources":["../../src/schema/json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAkD1C;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,WAAW,CAMpE;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,mBAAmB,GAC1B,MAAM,IAAI,mBAAmB,GAAG;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAgBnD;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,mBAAmB,GAC1B,WAAW,EAAE,GAAG,SAAS,CAgB3B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CAGtE"}
@@ -1,4 +1,4 @@
1
- import { z } from "./alias";
1
+ import { z } from "zod/v4";
2
2
  const jsonSchemaType = z.union([
3
3
  z.literal("object"),
4
4
  z.literal("array"),
@@ -95,4 +95,14 @@ export function getJsonSchemaTupleItems(schema) {
95
95
  }
96
96
  return undefined;
97
97
  }
98
+ /**
99
+ * Creates a partial version of a JSON Schema by removing required constraints.
100
+ * This allows LLM to provide only the properties it wants to update.
101
+ * @param schema - The JSON Schema to make partial
102
+ * @returns A new JSON Schema with the required constraint removed
103
+ */
104
+ export function makeJsonSchemaPartial(schema) {
105
+ const { required: _required, ...rest } = schema;
106
+ return rest;
107
+ }
98
108
  //# sourceMappingURL=json-schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../src/schema/json-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { JSONSchema7 } from \"json-schema\";\nimport { z } from \"./alias\";\n\nconst jsonSchemaType = z.union([\n z.literal(\"object\"),\n z.literal(\"array\"),\n z.literal(\"string\"),\n z.literal(\"number\"),\n z.literal(\"integer\"),\n z.literal(\"boolean\"),\n z.literal(\"null\"),\n z.array(\n z.union([\n z.literal(\"object\"),\n z.literal(\"array\"),\n z.literal(\"string\"),\n z.literal(\"number\"),\n z.literal(\"integer\"),\n z.literal(\"boolean\"),\n z.literal(\"null\"),\n ]),\n ),\n]);\n\nconst jsonSchemaTopLevel = z\n .looseObject({\n type: jsonSchemaType.optional(),\n properties: z.record(z.string(), z.unknown()).optional(),\n items: z.union([z.array(z.unknown()), z.unknown()]).optional(),\n required: z.array(z.string()).optional(),\n additionalProperties: z.union([z.boolean(), z.unknown()]).optional(),\n enum: z.array(z.unknown()).optional(),\n const: z.unknown().optional(),\n $ref: z.string().optional(),\n $id: z.string().optional(),\n $schema: z.string().optional(),\n title: z.string().optional(),\n description: z.string().optional(),\n })\n .refine((value) => {\n return (\n value.type !== undefined ||\n value.properties !== undefined ||\n value.items !== undefined ||\n value.enum !== undefined ||\n value.const !== undefined ||\n value.$ref !== undefined\n );\n });\n\n/**\n * Basic heuristic to check if an object looks like a JSON Schema at the top level.\n *\n * This uses a Zod schema to verify only top-level keys (type, properties, items,\n * etc.). It intentionally does not perform full JSON Schema validation; a more\n * thorough check should be done server-side.\n * @param obj - The value to check\n * @returns True if the value appears to be a JSON Schema\n */\nexport function looksLikeJSONSchema(obj: unknown): obj is JSONSchema7 {\n if (obj === null || typeof obj !== \"object\") {\n return false;\n }\n\n return jsonSchemaTopLevel.safeParse(obj).success;\n}\n\n/**\n * Extended JSON Schema type that includes draft 2020-12 features like prefixItems.\n * The json-schema package types are from draft-07 and don't include prefixItems.\n */\nexport type JSONSchema7Extended = JSONSchema7 & {\n prefixItems?: JSONSchema7[];\n};\n\n/**\n * Checks if a JSON Schema represents a tuple (array with positional items).\n * Supports both draft-07 (items as array) and draft 2020-12 (prefixItems).\n * @param schema - The JSON Schema to check\n * @returns True if the schema represents a tuple\n */\nexport function isJsonSchemaTuple(\n schema: JSONSchema7Extended,\n): schema is JSONSchema7Extended & { type: \"array\" } {\n if (schema.type !== \"array\") {\n return false;\n }\n\n // Draft 2020-12: prefixItems array\n if (schema.prefixItems && Array.isArray(schema.prefixItems)) {\n return true;\n }\n\n // Draft-07: items as array (not object)\n if (Array.isArray(schema.items)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Gets the tuple items from a JSON Schema.\n * Supports both draft-07 (items as array) and draft 2020-12 (prefixItems).\n * @param schema - The JSON Schema tuple\n * @returns Array of item schemas, or undefined if not a tuple\n */\nexport function getJsonSchemaTupleItems(\n schema: JSONSchema7Extended,\n): JSONSchema7[] | undefined {\n if (schema.type !== \"array\") {\n return undefined;\n }\n\n // Draft 2020-12: prefixItems array\n if (schema.prefixItems && Array.isArray(schema.prefixItems)) {\n return schema.prefixItems;\n }\n\n // Draft-07: items as array\n if (Array.isArray(schema.items)) {\n return schema.items as JSONSchema7[];\n }\n\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"json-schema.js","sourceRoot":"","sources":["../../src/schema/json-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { JSONSchema7 } from \"json-schema\";\nimport { z } from \"zod/v4\";\n\nconst jsonSchemaType = z.union([\n z.literal(\"object\"),\n z.literal(\"array\"),\n z.literal(\"string\"),\n z.literal(\"number\"),\n z.literal(\"integer\"),\n z.literal(\"boolean\"),\n z.literal(\"null\"),\n z.array(\n z.union([\n z.literal(\"object\"),\n z.literal(\"array\"),\n z.literal(\"string\"),\n z.literal(\"number\"),\n z.literal(\"integer\"),\n z.literal(\"boolean\"),\n z.literal(\"null\"),\n ]),\n ),\n]);\n\nconst jsonSchemaTopLevel = z\n .looseObject({\n type: jsonSchemaType.optional(),\n properties: z.record(z.string(), z.unknown()).optional(),\n items: z.union([z.array(z.unknown()), z.unknown()]).optional(),\n required: z.array(z.string()).optional(),\n additionalProperties: z.union([z.boolean(), z.unknown()]).optional(),\n enum: z.array(z.unknown()).optional(),\n const: z.unknown().optional(),\n $ref: z.string().optional(),\n $id: z.string().optional(),\n $schema: z.string().optional(),\n title: z.string().optional(),\n description: z.string().optional(),\n })\n .refine((value) => {\n return (\n value.type !== undefined ||\n value.properties !== undefined ||\n value.items !== undefined ||\n value.enum !== undefined ||\n value.const !== undefined ||\n value.$ref !== undefined\n );\n });\n\n/**\n * Basic heuristic to check if an object looks like a JSON Schema at the top level.\n *\n * This uses a Zod schema to verify only top-level keys (type, properties, items,\n * etc.). It intentionally does not perform full JSON Schema validation; a more\n * thorough check should be done server-side.\n * @param obj - The value to check\n * @returns True if the value appears to be a JSON Schema\n */\nexport function looksLikeJSONSchema(obj: unknown): obj is JSONSchema7 {\n if (obj === null || typeof obj !== \"object\") {\n return false;\n }\n\n return jsonSchemaTopLevel.safeParse(obj).success;\n}\n\n/**\n * Extended JSON Schema type that includes draft 2020-12 features like prefixItems.\n * The json-schema package types are from draft-07 and don't include prefixItems.\n */\nexport type JSONSchema7Extended = JSONSchema7 & {\n prefixItems?: JSONSchema7[];\n};\n\n/**\n * Checks if a JSON Schema represents a tuple (array with positional items).\n * Supports both draft-07 (items as array) and draft 2020-12 (prefixItems).\n * @param schema - The JSON Schema to check\n * @returns True if the schema represents a tuple\n */\nexport function isJsonSchemaTuple(\n schema: JSONSchema7Extended,\n): schema is JSONSchema7Extended & { type: \"array\" } {\n if (schema.type !== \"array\") {\n return false;\n }\n\n // Draft 2020-12: prefixItems array\n if (schema.prefixItems && Array.isArray(schema.prefixItems)) {\n return true;\n }\n\n // Draft-07: items as array (not object)\n if (Array.isArray(schema.items)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Gets the tuple items from a JSON Schema.\n * Supports both draft-07 (items as array) and draft 2020-12 (prefixItems).\n * @param schema - The JSON Schema tuple\n * @returns Array of item schemas, or undefined if not a tuple\n */\nexport function getJsonSchemaTupleItems(\n schema: JSONSchema7Extended,\n): JSONSchema7[] | undefined {\n if (schema.type !== \"array\") {\n return undefined;\n }\n\n // Draft 2020-12: prefixItems array\n if (schema.prefixItems && Array.isArray(schema.prefixItems)) {\n return schema.prefixItems;\n }\n\n // Draft-07: items as array\n if (Array.isArray(schema.items)) {\n return schema.items as JSONSchema7[];\n }\n\n return undefined;\n}\n\n/**\n * Creates a partial version of a JSON Schema by removing required constraints.\n * This allows LLM to provide only the properties it wants to update.\n * @param schema - The JSON Schema to make partial\n * @returns A new JSON Schema with the required constraint removed\n */\nexport function makeJsonSchemaPartial(schema: JSONSchema7): JSONSchema7 {\n const { required: _required, ...rest } = schema;\n return rest;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=json-schema.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema.test.d.ts","sourceRoot":"","sources":["../../src/schema/json-schema.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,202 @@
1
+ import { getJsonSchemaTupleItems, isJsonSchemaTuple, looksLikeJSONSchema, makeJsonSchemaPartial, } from "./json-schema";
2
+ describe("looksLikeJSONSchema", () => {
3
+ it("should return true for a valid object schema", () => {
4
+ const schema = {
5
+ type: "object",
6
+ properties: {
7
+ name: { type: "string" },
8
+ },
9
+ };
10
+ expect(looksLikeJSONSchema(schema)).toBe(true);
11
+ });
12
+ it("should return true for a schema with only properties", () => {
13
+ const schema = {
14
+ properties: {
15
+ name: { type: "string" },
16
+ },
17
+ };
18
+ expect(looksLikeJSONSchema(schema)).toBe(true);
19
+ });
20
+ it("should return true for a schema with items (array)", () => {
21
+ const schema = {
22
+ type: "array",
23
+ items: { type: "string" },
24
+ };
25
+ expect(looksLikeJSONSchema(schema)).toBe(true);
26
+ });
27
+ it("should return true for a schema with enum", () => {
28
+ const schema = {
29
+ enum: ["a", "b", "c"],
30
+ };
31
+ expect(looksLikeJSONSchema(schema)).toBe(true);
32
+ });
33
+ it("should return true for a schema with const", () => {
34
+ const schema = {
35
+ const: "fixed-value",
36
+ };
37
+ expect(looksLikeJSONSchema(schema)).toBe(true);
38
+ });
39
+ it("should return true for a schema with $ref", () => {
40
+ const schema = {
41
+ $ref: "#/definitions/Person",
42
+ };
43
+ expect(looksLikeJSONSchema(schema)).toBe(true);
44
+ });
45
+ it("should return false for null", () => {
46
+ expect(looksLikeJSONSchema(null)).toBe(false);
47
+ });
48
+ it("should return false for non-object", () => {
49
+ expect(looksLikeJSONSchema("string")).toBe(false);
50
+ expect(looksLikeJSONSchema(123)).toBe(false);
51
+ expect(looksLikeJSONSchema(undefined)).toBe(false);
52
+ });
53
+ it("should return false for empty object", () => {
54
+ expect(looksLikeJSONSchema({})).toBe(false);
55
+ });
56
+ it("should return false for object without schema keys", () => {
57
+ const notSchema = {
58
+ foo: "bar",
59
+ baz: 123,
60
+ };
61
+ expect(looksLikeJSONSchema(notSchema)).toBe(false);
62
+ });
63
+ });
64
+ describe("isJsonSchemaTuple", () => {
65
+ it("should return true for draft-07 tuple (items as array)", () => {
66
+ const schema = {
67
+ type: "array",
68
+ items: [{ type: "string" }, { type: "number" }],
69
+ };
70
+ expect(isJsonSchemaTuple(schema)).toBe(true);
71
+ });
72
+ it("should return true for draft 2020-12 tuple (prefixItems)", () => {
73
+ const schema = {
74
+ type: "array",
75
+ prefixItems: [{ type: "string" }, { type: "number" }],
76
+ };
77
+ expect(isJsonSchemaTuple(schema)).toBe(true);
78
+ });
79
+ it("should return false for regular array schema (items as object)", () => {
80
+ const schema = {
81
+ type: "array",
82
+ items: { type: "string" },
83
+ };
84
+ expect(isJsonSchemaTuple(schema)).toBe(false);
85
+ });
86
+ it("should return false for non-array schema", () => {
87
+ const schema = {
88
+ type: "object",
89
+ properties: {},
90
+ };
91
+ expect(isJsonSchemaTuple(schema)).toBe(false);
92
+ });
93
+ it("should return false for array without items or prefixItems", () => {
94
+ const schema = {
95
+ type: "array",
96
+ };
97
+ expect(isJsonSchemaTuple(schema)).toBe(false);
98
+ });
99
+ });
100
+ describe("getJsonSchemaTupleItems", () => {
101
+ it("should return items for draft-07 tuple", () => {
102
+ const items = [{ type: "string" }, { type: "number" }];
103
+ const schema = {
104
+ type: "array",
105
+ items: items,
106
+ };
107
+ expect(getJsonSchemaTupleItems(schema)).toEqual(items);
108
+ });
109
+ it("should return prefixItems for draft 2020-12 tuple", () => {
110
+ const prefixItems = [{ type: "string" }, { type: "number" }];
111
+ const schema = {
112
+ type: "array",
113
+ prefixItems: prefixItems,
114
+ };
115
+ expect(getJsonSchemaTupleItems(schema)).toEqual(prefixItems);
116
+ });
117
+ it("should return undefined for non-array schema", () => {
118
+ const schema = {
119
+ type: "object",
120
+ };
121
+ expect(getJsonSchemaTupleItems(schema)).toBeUndefined();
122
+ });
123
+ it("should return undefined for array without tuple items", () => {
124
+ const schema = {
125
+ type: "array",
126
+ items: { type: "string" },
127
+ };
128
+ expect(getJsonSchemaTupleItems(schema)).toBeUndefined();
129
+ });
130
+ it("should prefer prefixItems over items when both present", () => {
131
+ const prefixItems = [{ type: "boolean" }];
132
+ const items = [{ type: "string" }];
133
+ const schema = {
134
+ type: "array",
135
+ prefixItems: prefixItems,
136
+ items: items,
137
+ };
138
+ expect(getJsonSchemaTupleItems(schema)).toEqual(prefixItems);
139
+ });
140
+ });
141
+ describe("makeJsonSchemaPartial", () => {
142
+ it("should remove required array from schema", () => {
143
+ const schema = {
144
+ type: "object",
145
+ properties: {
146
+ name: { type: "string" },
147
+ age: { type: "number" },
148
+ },
149
+ required: ["name", "age"],
150
+ };
151
+ const partial = makeJsonSchemaPartial(schema);
152
+ expect(partial.required).toBeUndefined();
153
+ expect(partial.type).toBe("object");
154
+ expect(partial.properties).toEqual(schema.properties);
155
+ });
156
+ it("should preserve all other properties", () => {
157
+ const schema = {
158
+ type: "object",
159
+ properties: {
160
+ name: { type: "string", description: "The name" },
161
+ },
162
+ required: ["name"],
163
+ additionalProperties: false,
164
+ description: "A person schema",
165
+ title: "Person",
166
+ };
167
+ const partial = makeJsonSchemaPartial(schema);
168
+ expect(partial.required).toBeUndefined();
169
+ expect(partial.type).toBe("object");
170
+ expect(partial.properties).toEqual(schema.properties);
171
+ expect(partial.additionalProperties).toBe(false);
172
+ expect(partial.description).toBe("A person schema");
173
+ expect(partial.title).toBe("Person");
174
+ });
175
+ it("should handle schema without required array", () => {
176
+ const schema = {
177
+ type: "object",
178
+ properties: {
179
+ name: { type: "string" },
180
+ },
181
+ };
182
+ const partial = makeJsonSchemaPartial(schema);
183
+ expect(partial.required).toBeUndefined();
184
+ expect(partial.type).toBe("object");
185
+ expect(partial.properties).toEqual(schema.properties);
186
+ });
187
+ it("should not mutate the original schema", () => {
188
+ const schema = {
189
+ type: "object",
190
+ properties: {
191
+ name: { type: "string" },
192
+ },
193
+ required: ["name"],
194
+ };
195
+ const partial = makeJsonSchemaPartial(schema);
196
+ // Original should be unchanged
197
+ expect(schema.required).toEqual(["name"]);
198
+ // Partial should not have required
199
+ expect(partial.required).toBeUndefined();
200
+ });
201
+ });
202
+ //# sourceMappingURL=json-schema.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-schema.test.js","sourceRoot":"","sources":["../../src/schema/json-schema.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { JSONSchema7 } from \"json-schema\";\nimport {\n getJsonSchemaTupleItems,\n isJsonSchemaTuple,\n JSONSchema7Extended,\n looksLikeJSONSchema,\n makeJsonSchemaPartial,\n} from \"./json-schema\";\n\ndescribe(\"looksLikeJSONSchema\", () => {\n it(\"should return true for a valid object schema\", () => {\n const schema = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n },\n };\n expect(looksLikeJSONSchema(schema)).toBe(true);\n });\n\n it(\"should return true for a schema with only properties\", () => {\n const schema = {\n properties: {\n name: { type: \"string\" },\n },\n };\n expect(looksLikeJSONSchema(schema)).toBe(true);\n });\n\n it(\"should return true for a schema with items (array)\", () => {\n const schema = {\n type: \"array\",\n items: { type: \"string\" },\n };\n expect(looksLikeJSONSchema(schema)).toBe(true);\n });\n\n it(\"should return true for a schema with enum\", () => {\n const schema = {\n enum: [\"a\", \"b\", \"c\"],\n };\n expect(looksLikeJSONSchema(schema)).toBe(true);\n });\n\n it(\"should return true for a schema with const\", () => {\n const schema = {\n const: \"fixed-value\",\n };\n expect(looksLikeJSONSchema(schema)).toBe(true);\n });\n\n it(\"should return true for a schema with $ref\", () => {\n const schema = {\n $ref: \"#/definitions/Person\",\n };\n expect(looksLikeJSONSchema(schema)).toBe(true);\n });\n\n it(\"should return false for null\", () => {\n expect(looksLikeJSONSchema(null)).toBe(false);\n });\n\n it(\"should return false for non-object\", () => {\n expect(looksLikeJSONSchema(\"string\")).toBe(false);\n expect(looksLikeJSONSchema(123)).toBe(false);\n expect(looksLikeJSONSchema(undefined)).toBe(false);\n });\n\n it(\"should return false for empty object\", () => {\n expect(looksLikeJSONSchema({})).toBe(false);\n });\n\n it(\"should return false for object without schema keys\", () => {\n const notSchema = {\n foo: \"bar\",\n baz: 123,\n };\n expect(looksLikeJSONSchema(notSchema)).toBe(false);\n });\n});\n\ndescribe(\"isJsonSchemaTuple\", () => {\n it(\"should return true for draft-07 tuple (items as array)\", () => {\n const schema: JSONSchema7Extended = {\n type: \"array\",\n items: [{ type: \"string\" }, { type: \"number\" }],\n };\n expect(isJsonSchemaTuple(schema)).toBe(true);\n });\n\n it(\"should return true for draft 2020-12 tuple (prefixItems)\", () => {\n const schema: JSONSchema7Extended = {\n type: \"array\",\n prefixItems: [{ type: \"string\" }, { type: \"number\" }],\n };\n expect(isJsonSchemaTuple(schema)).toBe(true);\n });\n\n it(\"should return false for regular array schema (items as object)\", () => {\n const schema: JSONSchema7Extended = {\n type: \"array\",\n items: { type: \"string\" },\n };\n expect(isJsonSchemaTuple(schema)).toBe(false);\n });\n\n it(\"should return false for non-array schema\", () => {\n const schema: JSONSchema7Extended = {\n type: \"object\",\n properties: {},\n };\n expect(isJsonSchemaTuple(schema)).toBe(false);\n });\n\n it(\"should return false for array without items or prefixItems\", () => {\n const schema: JSONSchema7Extended = {\n type: \"array\",\n };\n expect(isJsonSchemaTuple(schema)).toBe(false);\n });\n});\n\ndescribe(\"getJsonSchemaTupleItems\", () => {\n it(\"should return items for draft-07 tuple\", () => {\n const items = [{ type: \"string\" }, { type: \"number\" }];\n const schema: JSONSchema7Extended = {\n type: \"array\",\n items: items as JSONSchema7[],\n };\n expect(getJsonSchemaTupleItems(schema)).toEqual(items);\n });\n\n it(\"should return prefixItems for draft 2020-12 tuple\", () => {\n const prefixItems = [{ type: \"string\" }, { type: \"number\" }];\n const schema: JSONSchema7Extended = {\n type: \"array\",\n prefixItems: prefixItems as JSONSchema7[],\n };\n expect(getJsonSchemaTupleItems(schema)).toEqual(prefixItems);\n });\n\n it(\"should return undefined for non-array schema\", () => {\n const schema: JSONSchema7Extended = {\n type: \"object\",\n };\n expect(getJsonSchemaTupleItems(schema)).toBeUndefined();\n });\n\n it(\"should return undefined for array without tuple items\", () => {\n const schema: JSONSchema7Extended = {\n type: \"array\",\n items: { type: \"string\" },\n };\n expect(getJsonSchemaTupleItems(schema)).toBeUndefined();\n });\n\n it(\"should prefer prefixItems over items when both present\", () => {\n const prefixItems = [{ type: \"boolean\" }];\n const items = [{ type: \"string\" }];\n const schema: JSONSchema7Extended = {\n type: \"array\",\n prefixItems: prefixItems as JSONSchema7[],\n items: items as JSONSchema7[],\n };\n expect(getJsonSchemaTupleItems(schema)).toEqual(prefixItems);\n });\n});\n\ndescribe(\"makeJsonSchemaPartial\", () => {\n it(\"should remove required array from schema\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n age: { type: \"number\" },\n },\n required: [\"name\", \"age\"],\n };\n\n const partial = makeJsonSchemaPartial(schema);\n\n expect(partial.required).toBeUndefined();\n expect(partial.type).toBe(\"object\");\n expect(partial.properties).toEqual(schema.properties);\n });\n\n it(\"should preserve all other properties\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"The name\" },\n },\n required: [\"name\"],\n additionalProperties: false,\n description: \"A person schema\",\n title: \"Person\",\n };\n\n const partial = makeJsonSchemaPartial(schema);\n\n expect(partial.required).toBeUndefined();\n expect(partial.type).toBe(\"object\");\n expect(partial.properties).toEqual(schema.properties);\n expect(partial.additionalProperties).toBe(false);\n expect(partial.description).toBe(\"A person schema\");\n expect(partial.title).toBe(\"Person\");\n });\n\n it(\"should handle schema without required array\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n },\n };\n\n const partial = makeJsonSchemaPartial(schema);\n\n expect(partial.required).toBeUndefined();\n expect(partial.type).toBe(\"object\");\n expect(partial.properties).toEqual(schema.properties);\n });\n\n it(\"should not mutate the original schema\", () => {\n const schema: JSONSchema7 = {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n },\n required: [\"name\"],\n };\n\n const partial = makeJsonSchemaPartial(schema);\n\n // Original should be unchanged\n expect(schema.required).toEqual([\"name\"]);\n // Partial should not have required\n expect(partial.required).toBeUndefined();\n });\n});\n"]}
@@ -1,7 +1,7 @@
1
1
  import * as z3 from "zod/v3";
2
2
  import * as z4 from "zod/v4";
3
3
  import { looksLikeJSONSchema } from "./json-schema";
4
- import { getParametersFromToolSchema } from "./schema";
4
+ import { getParametersFromToolSchema, hasInputSchema, safeSchemaToJsonSchema, schemaToJsonSchema, } from "./schema";
5
5
  import { isStandardSchema } from "./standard-schema";
6
6
  describe("schema utilities", () => {
7
7
  describe("looksLikeJSONSchema", () => {
@@ -288,6 +288,243 @@ describe("schema utilities", () => {
288
288
  expect(params.length).toBeGreaterThanOrEqual(1);
289
289
  expect(params[0].name).toBe("param1");
290
290
  });
291
+ it("handles toolSchema with JSON Schema directly", () => {
292
+ const tool = {
293
+ name: "test-tool",
294
+ description: "Test tool",
295
+ tool: jest.fn(),
296
+ toolSchema: {
297
+ type: "object",
298
+ properties: {
299
+ query: { type: "string", description: "Search query" },
300
+ },
301
+ required: ["query"],
302
+ },
303
+ };
304
+ const params = getParametersFromToolSchema(tool);
305
+ // JSON Schema in toolSchema should return params wrapped
306
+ expect(params.length).toBeGreaterThanOrEqual(1);
307
+ });
308
+ });
309
+ describe("edge cases and error handling", () => {
310
+ it("returns empty params when inputSchema is unknown type", () => {
311
+ // Create a tool with an invalid inputSchema that isn't Standard Schema or JSON Schema
312
+ const tool = {
313
+ name: "test-tool",
314
+ description: "Test tool",
315
+ tool: jest.fn(),
316
+ inputSchema: "invalid-schema", // Not a valid schema
317
+ outputSchema: z4.void(),
318
+ };
319
+ const consoleSpy = jest.spyOn(console, "warn").mockImplementation();
320
+ const params = getParametersFromToolSchema(tool);
321
+ consoleSpy.mockRestore();
322
+ expect(params).toEqual([]);
323
+ });
324
+ it("throws when toolSchema is undefined", () => {
325
+ // Create a tool with toolSchema that has undefined toolSchema
326
+ const tool = {
327
+ name: "test-tool",
328
+ description: "Test tool",
329
+ tool: jest.fn(),
330
+ toolSchema: undefined,
331
+ };
332
+ expect(() => getParametersFromToolSchema(tool)).toThrow("Unable to determine parameters from zod function schema");
333
+ });
334
+ it("throws when toolSchema args are not recognized", () => {
335
+ // Create a tool with toolSchema that is not a function schema or JSON schema
336
+ // This causes getArgsFromToolSchema to attempt extraction but fail
337
+ const tool = {
338
+ name: "test-tool",
339
+ description: "Test tool",
340
+ tool: jest.fn(),
341
+ toolSchema: { notASchema: true },
342
+ };
343
+ // This throws because it's not a Zod function schema
344
+ expect(() => getParametersFromToolSchema(tool)).toThrow("Unable to determine parameters from zod function schema");
345
+ });
346
+ });
347
+ describe("toolSchema with JSON Schema tuple", () => {
348
+ it("handles toolSchema with JSON Schema array/tuple directly", () => {
349
+ const tool = {
350
+ name: "test-tool",
351
+ description: "Test tool",
352
+ tool: jest.fn(),
353
+ // JSON Schema tuple format
354
+ toolSchema: {
355
+ type: "array",
356
+ items: [
357
+ { type: "string", description: "First param" },
358
+ { type: "number", description: "Second param" },
359
+ ],
360
+ },
361
+ };
362
+ const params = getParametersFromToolSchema(tool);
363
+ // JSON Schema tuples should be extracted as positional params
364
+ expect(params).toHaveLength(2);
365
+ expect(params[0].name).toBe("param1");
366
+ expect(params[0].type).toBe("string");
367
+ expect(params[0].description).toBe("First param");
368
+ expect(params[1].name).toBe("param2");
369
+ expect(params[1].type).toBe("number");
370
+ });
371
+ it("handles toolSchema with JSON Schema prefixItems (2020-12 format)", () => {
372
+ const tool = {
373
+ name: "test-tool",
374
+ description: "Test tool",
375
+ tool: jest.fn(),
376
+ // JSON Schema 2020-12 tuple format
377
+ toolSchema: {
378
+ type: "array",
379
+ prefixItems: [
380
+ { type: "boolean", description: "Flag" },
381
+ { type: "string" },
382
+ ],
383
+ },
384
+ };
385
+ const params = getParametersFromToolSchema(tool);
386
+ expect(params).toHaveLength(2);
387
+ expect(params[0].name).toBe("param1");
388
+ expect(params[0].type).toBe("boolean");
389
+ expect(params[0].description).toBe("Flag");
390
+ expect(params[1].name).toBe("param2");
391
+ expect(params[1].type).toBe("string");
392
+ });
393
+ it("handles toolSchema with non-tuple JSON Schema (fallback)", () => {
394
+ const tool = {
395
+ name: "test-tool",
396
+ description: "Test tool",
397
+ tool: jest.fn(),
398
+ // Non-tuple JSON Schema - should be wrapped as single param
399
+ toolSchema: {
400
+ type: "object",
401
+ properties: {
402
+ name: { type: "string" },
403
+ },
404
+ },
405
+ };
406
+ const params = getParametersFromToolSchema(tool);
407
+ // Non-tuple schemas should be wrapped as a single param
408
+ expect(params).toHaveLength(1);
409
+ expect(params[0].name).toBe("param1");
410
+ expect(params[0].type).toBe("object");
411
+ });
412
+ });
413
+ });
414
+ describe("schemaToJsonSchema", () => {
415
+ it("returns JSON Schema as-is when already a JSON Schema", () => {
416
+ const jsonSchema = {
417
+ type: "object",
418
+ properties: {
419
+ name: { type: "string" },
420
+ },
421
+ };
422
+ const result = schemaToJsonSchema(jsonSchema);
423
+ expect(result).toBe(jsonSchema); // Same reference
424
+ });
425
+ it("converts Zod 4 schema to JSON Schema", () => {
426
+ const zodSchema = z4.object({
427
+ name: z4.string(),
428
+ count: z4.number(),
429
+ });
430
+ const result = schemaToJsonSchema(zodSchema);
431
+ expect(result).toEqual(expect.objectContaining({
432
+ type: "object",
433
+ properties: expect.objectContaining({
434
+ name: expect.objectContaining({ type: "string" }),
435
+ count: expect.objectContaining({ type: "number" }),
436
+ }),
437
+ }));
438
+ });
439
+ it("converts Zod 3 schema to JSON Schema", () => {
440
+ const zodSchema = z3.object({
441
+ title: z3.string(),
442
+ });
443
+ const result = schemaToJsonSchema(zodSchema);
444
+ expect(result).toEqual(expect.objectContaining({
445
+ type: "object",
446
+ properties: expect.objectContaining({
447
+ title: expect.objectContaining({ type: "string" }),
448
+ }),
449
+ }));
450
+ });
451
+ });
452
+ describe("safeSchemaToJsonSchema", () => {
453
+ it("returns undefined for null schema", () => {
454
+ expect(safeSchemaToJsonSchema(null)).toBeUndefined();
455
+ });
456
+ it("returns undefined for undefined schema", () => {
457
+ expect(safeSchemaToJsonSchema(undefined)).toBeUndefined();
458
+ });
459
+ it("converts valid schema successfully", () => {
460
+ const zodSchema = z4.object({ name: z4.string() });
461
+ const result = safeSchemaToJsonSchema(zodSchema);
462
+ expect(result).toEqual(expect.objectContaining({
463
+ type: "object",
464
+ properties: expect.objectContaining({
465
+ name: expect.objectContaining({ type: "string" }),
466
+ }),
467
+ }));
468
+ });
469
+ it("returns undefined and calls onError for invalid schema", () => {
470
+ // Create something that looks like a Standard Schema but will fail conversion
471
+ const brokenSchema = {
472
+ "~standard": {
473
+ version: 1,
474
+ vendor: "broken",
475
+ validate: () => ({ value: {} }),
476
+ },
477
+ };
478
+ const onError = jest.fn();
479
+ const consoleSpy = jest.spyOn(console, "error").mockImplementation();
480
+ const result = safeSchemaToJsonSchema(brokenSchema, onError);
481
+ consoleSpy.mockRestore();
482
+ expect(result).toBeUndefined();
483
+ expect(onError).toHaveBeenCalled();
484
+ });
485
+ it("logs error to console when conversion fails", () => {
486
+ const brokenSchema = {
487
+ "~standard": {
488
+ version: 1,
489
+ vendor: "broken",
490
+ validate: () => ({ value: {} }),
491
+ },
492
+ };
493
+ const consoleSpy = jest.spyOn(console, "error").mockImplementation();
494
+ safeSchemaToJsonSchema(brokenSchema);
495
+ expect(consoleSpy).toHaveBeenCalledWith("Error converting schema to JSON Schema:", expect.any(Error));
496
+ consoleSpy.mockRestore();
497
+ });
498
+ });
499
+ describe("hasInputSchema", () => {
500
+ it("returns true for tool with inputSchema", () => {
501
+ const tool = {
502
+ name: "test",
503
+ description: "test",
504
+ tool: jest.fn(),
505
+ inputSchema: z4.object({ a: z4.string() }),
506
+ outputSchema: z4.void(),
507
+ };
508
+ expect(hasInputSchema(tool)).toBe(true);
509
+ });
510
+ it("returns false for tool with toolSchema (deprecated)", () => {
511
+ const tool = {
512
+ name: "test",
513
+ description: "test",
514
+ tool: jest.fn(),
515
+ toolSchema: z3.function().args(z3.string()).returns(z3.void()),
516
+ };
517
+ expect(hasInputSchema(tool)).toBe(false);
518
+ });
519
+ it("returns false for tool with null inputSchema", () => {
520
+ const tool = {
521
+ name: "test",
522
+ description: "test",
523
+ tool: jest.fn(),
524
+ inputSchema: null,
525
+ outputSchema: z4.void(),
526
+ };
527
+ expect(hasInputSchema(tool)).toBe(false);
291
528
  });
292
529
  });
293
530
  });