@raybase/core 0.0.2 → 0.3.3

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 (435) hide show
  1. package/LICENSE +21 -0
  2. package/dist/.admin-build/AdminApp.css +2 -0
  3. package/dist/.admin-build/AdminApp.js +77 -0
  4. package/dist/.admin-docs-build/AdminDocsApp.css +2 -0
  5. package/dist/.admin-docs-build/AdminDocsApp.js +45 -0
  6. package/dist/actions.d.ts +347 -0
  7. package/dist/actions.d.ts.map +1 -0
  8. package/dist/actions.js +661 -0
  9. package/dist/actions.js.map +1 -0
  10. package/dist/admin-assets/admin.7738f50720a8ed7b.css +2 -0
  11. package/dist/admin-assets/admin.8678cb61db34dc81.js +77 -0
  12. package/dist/admin-boot.d.ts +94 -0
  13. package/dist/admin-boot.d.ts.map +1 -0
  14. package/dist/admin-boot.js +139 -0
  15. package/dist/admin-boot.js.map +1 -0
  16. package/dist/admin-docs-content.d.ts +95 -0
  17. package/dist/admin-docs-content.d.ts.map +1 -0
  18. package/dist/admin-docs-content.js +463 -0
  19. package/dist/admin-docs-content.js.map +1 -0
  20. package/dist/admin-docs-ui.d.ts +11 -0
  21. package/dist/admin-docs-ui.d.ts.map +1 -0
  22. package/dist/admin-docs-ui.js +23 -0
  23. package/dist/admin-docs-ui.js.map +1 -0
  24. package/dist/admin-kit.d.ts +29 -0
  25. package/dist/admin-kit.js +1557 -0
  26. package/dist/admin-role.d.ts +8 -0
  27. package/dist/admin-role.d.ts.map +1 -0
  28. package/dist/admin-role.js +22 -0
  29. package/dist/admin-role.js.map +1 -0
  30. package/dist/admin-ui.d.ts +3 -0
  31. package/dist/admin-ui.d.ts.map +1 -0
  32. package/dist/admin-ui.js +16 -0
  33. package/dist/admin-ui.js.map +1 -0
  34. package/dist/agent-ai-chat.d.ts +127 -0
  35. package/dist/agent-ai-chat.d.ts.map +1 -0
  36. package/dist/agent-ai-chat.js +5975 -0
  37. package/dist/agent-ai-chat.js.map +1 -0
  38. package/dist/agent-chapter-archive.d.ts +214 -0
  39. package/dist/agent-chapter-archive.d.ts.map +1 -0
  40. package/dist/agent-chapter-archive.js +696 -0
  41. package/dist/agent-chapter-archive.js.map +1 -0
  42. package/dist/agent-chapter-search.d.ts +116 -0
  43. package/dist/agent-chapter-search.d.ts.map +1 -0
  44. package/dist/agent-chapter-search.js +605 -0
  45. package/dist/agent-chapter-search.js.map +1 -0
  46. package/dist/agent-chapter-tools.d.ts +45 -0
  47. package/dist/agent-chapter-tools.d.ts.map +1 -0
  48. package/dist/agent-chapter-tools.js +344 -0
  49. package/dist/agent-chapter-tools.js.map +1 -0
  50. package/dist/agent-chapters.d.ts +228 -0
  51. package/dist/agent-chapters.d.ts.map +1 -0
  52. package/dist/agent-chapters.js +737 -0
  53. package/dist/agent-chapters.js.map +1 -0
  54. package/dist/agent-data-parts.d.ts +167 -0
  55. package/dist/agent-data-parts.d.ts.map +1 -0
  56. package/dist/agent-data-parts.js +68 -0
  57. package/dist/agent-data-parts.js.map +1 -0
  58. package/dist/agent-errors.d.ts +41 -0
  59. package/dist/agent-errors.d.ts.map +1 -0
  60. package/dist/agent-errors.js +191 -0
  61. package/dist/agent-errors.js.map +1 -0
  62. package/dist/agent-follow-up-store.d.ts +273 -0
  63. package/dist/agent-follow-up-store.d.ts.map +1 -0
  64. package/dist/agent-follow-up-store.js +703 -0
  65. package/dist/agent-follow-up-store.js.map +1 -0
  66. package/dist/agent-follow-ups.d.ts +314 -0
  67. package/dist/agent-follow-ups.d.ts.map +1 -0
  68. package/dist/agent-follow-ups.js +840 -0
  69. package/dist/agent-follow-ups.js.map +1 -0
  70. package/dist/agent-memory.d.ts +323 -0
  71. package/dist/agent-memory.d.ts.map +1 -0
  72. package/dist/agent-memory.js +1270 -0
  73. package/dist/agent-memory.js.map +1 -0
  74. package/dist/agent-message-parts.d.ts +58 -0
  75. package/dist/agent-message-parts.d.ts.map +1 -0
  76. package/dist/agent-message-parts.js +163 -0
  77. package/dist/agent-message-parts.js.map +1 -0
  78. package/dist/agent-remote-mcp-credentials.d.ts +154 -0
  79. package/dist/agent-remote-mcp-credentials.d.ts.map +1 -0
  80. package/dist/agent-remote-mcp-credentials.js +287 -0
  81. package/dist/agent-remote-mcp-credentials.js.map +1 -0
  82. package/dist/agent-remote-mcp-crypto.d.ts +32 -0
  83. package/dist/agent-remote-mcp-crypto.d.ts.map +1 -0
  84. package/dist/agent-remote-mcp-crypto.js +101 -0
  85. package/dist/agent-remote-mcp-crypto.js.map +1 -0
  86. package/dist/agent-remote-mcp-install.d.ts +299 -0
  87. package/dist/agent-remote-mcp-install.d.ts.map +1 -0
  88. package/dist/agent-remote-mcp-install.js +785 -0
  89. package/dist/agent-remote-mcp-install.js.map +1 -0
  90. package/dist/agent-remote-mcp-oauth.d.ts +73 -0
  91. package/dist/agent-remote-mcp-oauth.d.ts.map +1 -0
  92. package/dist/agent-remote-mcp-oauth.js +344 -0
  93. package/dist/agent-remote-mcp-oauth.js.map +1 -0
  94. package/dist/agent-remote-mcp-transport.d.ts +46 -0
  95. package/dist/agent-remote-mcp-transport.d.ts.map +1 -0
  96. package/dist/agent-remote-mcp-transport.js +225 -0
  97. package/dist/agent-remote-mcp-transport.js.map +1 -0
  98. package/dist/agent-remote-mcp.d.ts +147 -0
  99. package/dist/agent-remote-mcp.d.ts.map +1 -0
  100. package/dist/agent-remote-mcp.js +681 -0
  101. package/dist/agent-remote-mcp.js.map +1 -0
  102. package/dist/agent-room-redaction.d.ts +66 -0
  103. package/dist/agent-room-redaction.d.ts.map +1 -0
  104. package/dist/agent-room-redaction.js +264 -0
  105. package/dist/agent-room-redaction.js.map +1 -0
  106. package/dist/agent-rooms.d.ts +209 -0
  107. package/dist/agent-rooms.d.ts.map +1 -0
  108. package/dist/agent-rooms.js +244 -0
  109. package/dist/agent-rooms.js.map +1 -0
  110. package/dist/agent-runtime.d.ts +541 -0
  111. package/dist/agent-runtime.d.ts.map +1 -0
  112. package/dist/agent-runtime.js +4260 -0
  113. package/dist/agent-runtime.js.map +1 -0
  114. package/dist/agent-skill-archive.d.ts +20 -0
  115. package/dist/agent-skill-archive.d.ts.map +1 -0
  116. package/dist/agent-skill-archive.js +316 -0
  117. package/dist/agent-skill-archive.js.map +1 -0
  118. package/dist/agent-skill-discovery.d.ts +96 -0
  119. package/dist/agent-skill-discovery.d.ts.map +1 -0
  120. package/dist/agent-skill-discovery.js +464 -0
  121. package/dist/agent-skill-discovery.js.map +1 -0
  122. package/dist/agent-skill-format.d.ts +57 -0
  123. package/dist/agent-skill-format.d.ts.map +1 -0
  124. package/dist/agent-skill-format.js +238 -0
  125. package/dist/agent-skill-format.js.map +1 -0
  126. package/dist/agent-skill-import.d.ts +64 -0
  127. package/dist/agent-skill-import.d.ts.map +1 -0
  128. package/dist/agent-skill-import.js +295 -0
  129. package/dist/agent-skill-import.js.map +1 -0
  130. package/dist/agent-skill-publish.d.ts +51 -0
  131. package/dist/agent-skill-publish.d.ts.map +1 -0
  132. package/dist/agent-skill-publish.js +136 -0
  133. package/dist/agent-skill-publish.js.map +1 -0
  134. package/dist/agent-skill-store.d.ts +252 -0
  135. package/dist/agent-skill-store.d.ts.map +1 -0
  136. package/dist/agent-skill-store.js +514 -0
  137. package/dist/agent-skill-store.js.map +1 -0
  138. package/dist/agent-skills.d.ts +85 -0
  139. package/dist/agent-skills.d.ts.map +1 -0
  140. package/dist/agent-skills.js +291 -0
  141. package/dist/agent-skills.js.map +1 -0
  142. package/dist/agent-transcript-pager.d.ts +77 -0
  143. package/dist/agent-transcript-pager.d.ts.map +1 -0
  144. package/dist/agent-transcript-pager.js +210 -0
  145. package/dist/agent-transcript-pager.js.map +1 -0
  146. package/dist/agent-user-data-parts.d.ts +20 -0
  147. package/dist/agent-user-data-parts.d.ts.map +1 -0
  148. package/dist/agent-user-data-parts.js +161 -0
  149. package/dist/agent-user-data-parts.js.map +1 -0
  150. package/dist/agent-user-transcript.d.ts +46 -0
  151. package/dist/agent-user-transcript.d.ts.map +1 -0
  152. package/dist/agent-user-transcript.js +106 -0
  153. package/dist/agent-user-transcript.js.map +1 -0
  154. package/dist/agent-voice-notes.d.ts +15 -0
  155. package/dist/agent-voice-notes.d.ts.map +1 -0
  156. package/dist/agent-voice-notes.js +17 -0
  157. package/dist/agent-voice-notes.js.map +1 -0
  158. package/dist/agent-wakes.d.ts +213 -0
  159. package/dist/agent-wakes.d.ts.map +1 -0
  160. package/dist/agent-wakes.js +534 -0
  161. package/dist/agent-wakes.js.map +1 -0
  162. package/dist/agent.d.ts +1780 -0
  163. package/dist/agent.d.ts.map +1 -0
  164. package/dist/agent.js +3123 -0
  165. package/dist/agent.js.map +1 -0
  166. package/dist/ai.d.ts +583 -0
  167. package/dist/ai.d.ts.map +1 -0
  168. package/dist/ai.js +1858 -0
  169. package/dist/ai.js.map +1 -0
  170. package/dist/app-manifest.d.ts +255 -0
  171. package/dist/app-manifest.d.ts.map +1 -0
  172. package/dist/app-manifest.js +372 -0
  173. package/dist/app-manifest.js.map +1 -0
  174. package/dist/app-users.d.ts +30 -0
  175. package/dist/app-users.d.ts.map +1 -0
  176. package/dist/app-users.js +91 -0
  177. package/dist/app-users.js.map +1 -0
  178. package/dist/audit-archive.d.ts +85 -0
  179. package/dist/audit-archive.d.ts.map +1 -0
  180. package/dist/audit-archive.js +178 -0
  181. package/dist/audit-archive.js.map +1 -0
  182. package/dist/audit.d.ts +54 -0
  183. package/dist/audit.d.ts.map +1 -0
  184. package/dist/audit.js +95 -0
  185. package/dist/audit.js.map +1 -0
  186. package/dist/auth-logger.d.ts +28 -0
  187. package/dist/auth-logger.d.ts.map +1 -0
  188. package/dist/auth-logger.js +53 -0
  189. package/dist/auth-logger.js.map +1 -0
  190. package/dist/auth-password-secret.d.ts +59 -0
  191. package/dist/auth-password-secret.d.ts.map +1 -0
  192. package/dist/auth-password-secret.js +409 -0
  193. package/dist/auth-password-secret.js.map +1 -0
  194. package/dist/auth-schema.d.ts +120 -0
  195. package/dist/auth-schema.d.ts.map +1 -0
  196. package/dist/auth-schema.js +285 -0
  197. package/dist/auth-schema.js.map +1 -0
  198. package/dist/auth.d.ts +321 -0
  199. package/dist/auth.d.ts.map +1 -0
  200. package/dist/auth.js +1562 -0
  201. package/dist/auth.js.map +1 -0
  202. package/dist/backup-archive.d.ts +257 -0
  203. package/dist/backup-archive.d.ts.map +1 -0
  204. package/dist/backup-archive.js +2068 -0
  205. package/dist/backup-archive.js.map +1 -0
  206. package/dist/backup-crypto.d.ts +313 -0
  207. package/dist/backup-crypto.d.ts.map +1 -0
  208. package/dist/backup-crypto.js +693 -0
  209. package/dist/backup-crypto.js.map +1 -0
  210. package/dist/backup-format.d.ts +200 -0
  211. package/dist/backup-format.d.ts.map +1 -0
  212. package/dist/backup-format.js +1247 -0
  213. package/dist/backup-format.js.map +1 -0
  214. package/dist/cli.d.ts +9 -0
  215. package/dist/cli.d.ts.map +1 -0
  216. package/dist/cli.js +15 -0
  217. package/dist/cli.js.map +1 -0
  218. package/dist/clock.d.ts +35 -0
  219. package/dist/clock.d.ts.map +1 -0
  220. package/dist/clock.js +83 -0
  221. package/dist/clock.js.map +1 -0
  222. package/dist/data-client.d.ts +187 -0
  223. package/dist/data-client.d.ts.map +1 -0
  224. package/dist/data-client.js +590 -0
  225. package/dist/data-client.js.map +1 -0
  226. package/dist/data-secrets.d.ts +164 -0
  227. package/dist/data-secrets.d.ts.map +1 -0
  228. package/dist/data-secrets.js +383 -0
  229. package/dist/data-secrets.js.map +1 -0
  230. package/dist/db.d.ts +453 -0
  231. package/dist/db.d.ts.map +1 -0
  232. package/dist/db.js +324 -0
  233. package/dist/db.js.map +1 -0
  234. package/dist/dev-activity.d.ts +48 -0
  235. package/dist/dev-activity.d.ts.map +1 -0
  236. package/dist/dev-activity.js +50 -0
  237. package/dist/dev-activity.js.map +1 -0
  238. package/dist/do.d.ts +429 -0
  239. package/dist/do.d.ts.map +1 -0
  240. package/dist/do.js +4526 -0
  241. package/dist/do.js.map +1 -0
  242. package/dist/email.d.ts +137 -0
  243. package/dist/email.d.ts.map +1 -0
  244. package/dist/email.js +527 -0
  245. package/dist/email.js.map +1 -0
  246. package/dist/generated/admin-assets.d.ts +16 -0
  247. package/dist/generated/admin-assets.d.ts.map +1 -0
  248. package/dist/generated/admin-assets.js +16 -0
  249. package/dist/generated/admin-assets.js.map +1 -0
  250. package/dist/generated/admin-docs-assets.d.ts +3 -0
  251. package/dist/generated/admin-docs-assets.d.ts.map +1 -0
  252. package/dist/generated/admin-docs-assets.js +3 -0
  253. package/dist/generated/admin-docs-assets.js.map +1 -0
  254. package/dist/handoff-consumer.d.ts +79 -0
  255. package/dist/handoff-consumer.d.ts.map +1 -0
  256. package/dist/handoff-consumer.js +300 -0
  257. package/dist/handoff-consumer.js.map +1 -0
  258. package/dist/handoff.d.ts +70 -0
  259. package/dist/handoff.d.ts.map +1 -0
  260. package/dist/handoff.js +228 -0
  261. package/dist/handoff.js.map +1 -0
  262. package/dist/host-auth.d.ts +47 -0
  263. package/dist/host-auth.d.ts.map +1 -0
  264. package/dist/host-auth.js +59 -0
  265. package/dist/host-auth.js.map +1 -0
  266. package/dist/host-user.d.ts +15 -0
  267. package/dist/host-user.d.ts.map +1 -0
  268. package/dist/host-user.js +23 -0
  269. package/dist/host-user.js.map +1 -0
  270. package/dist/html.d.ts +35 -0
  271. package/dist/html.d.ts.map +1 -0
  272. package/dist/html.js +634 -0
  273. package/dist/html.js.map +1 -0
  274. package/dist/http-error.d.ts +13 -0
  275. package/dist/http-error.d.ts.map +1 -0
  276. package/dist/http-error.js +15 -0
  277. package/dist/http-error.js.map +1 -0
  278. package/dist/imports.d.ts +219 -0
  279. package/dist/imports.d.ts.map +1 -0
  280. package/dist/imports.js +571 -0
  281. package/dist/imports.js.map +1 -0
  282. package/dist/index.d.ts +78 -0
  283. package/dist/index.d.ts.map +1 -0
  284. package/dist/index.js +76 -0
  285. package/dist/index.js.map +1 -0
  286. package/dist/inference-tape.d.ts +64 -0
  287. package/dist/inference-tape.d.ts.map +1 -0
  288. package/dist/inference-tape.js +278 -0
  289. package/dist/inference-tape.js.map +1 -0
  290. package/dist/internal.d.ts +15 -0
  291. package/dist/internal.d.ts.map +1 -0
  292. package/dist/internal.js +48 -0
  293. package/dist/internal.js.map +1 -0
  294. package/dist/jobs.d.ts +796 -0
  295. package/dist/jobs.d.ts.map +1 -0
  296. package/dist/jobs.js +538 -0
  297. package/dist/jobs.js.map +1 -0
  298. package/dist/json-schema.d.ts +91 -0
  299. package/dist/json-schema.d.ts.map +1 -0
  300. package/dist/json-schema.js +884 -0
  301. package/dist/json-schema.js.map +1 -0
  302. package/dist/knowledge.d.ts +33 -0
  303. package/dist/knowledge.d.ts.map +1 -0
  304. package/dist/knowledge.js +348 -0
  305. package/dist/knowledge.js.map +1 -0
  306. package/dist/local-dev-chrome.d.ts +29 -0
  307. package/dist/local-dev-chrome.d.ts.map +1 -0
  308. package/dist/local-dev-chrome.js +514 -0
  309. package/dist/local-dev-chrome.js.map +1 -0
  310. package/dist/local-dev-personas.d.ts +15 -0
  311. package/dist/local-dev-personas.d.ts.map +1 -0
  312. package/dist/local-dev-personas.js +46 -0
  313. package/dist/local-dev-personas.js.map +1 -0
  314. package/dist/mcp.d.ts +567 -0
  315. package/dist/mcp.d.ts.map +1 -0
  316. package/dist/mcp.js +2480 -0
  317. package/dist/mcp.js.map +1 -0
  318. package/dist/modules.d.ts +145 -0
  319. package/dist/modules.d.ts.map +1 -0
  320. package/dist/modules.js +164 -0
  321. package/dist/modules.js.map +1 -0
  322. package/dist/notification-client.d.ts +94 -0
  323. package/dist/notification-client.d.ts.map +1 -0
  324. package/dist/notification-client.js +127 -0
  325. package/dist/notification-client.js.map +1 -0
  326. package/dist/notifications.d.ts +447 -0
  327. package/dist/notifications.d.ts.map +1 -0
  328. package/dist/notifications.js +1625 -0
  329. package/dist/notifications.js.map +1 -0
  330. package/dist/operator-data-query.d.ts +117 -0
  331. package/dist/operator-data-query.d.ts.map +1 -0
  332. package/dist/operator-data-query.js +431 -0
  333. package/dist/operator-data-query.js.map +1 -0
  334. package/dist/operator-mcp.d.ts +63 -0
  335. package/dist/operator-mcp.d.ts.map +1 -0
  336. package/dist/operator-mcp.js +2828 -0
  337. package/dist/operator-mcp.js.map +1 -0
  338. package/dist/outbound-https.d.ts +24 -0
  339. package/dist/outbound-https.d.ts.map +1 -0
  340. package/dist/outbound-https.js +172 -0
  341. package/dist/outbound-https.js.map +1 -0
  342. package/dist/pitr.d.ts +60 -0
  343. package/dist/pitr.d.ts.map +1 -0
  344. package/dist/pitr.js +94 -0
  345. package/dist/pitr.js.map +1 -0
  346. package/dist/platform.d.ts +199 -0
  347. package/dist/platform.d.ts.map +1 -0
  348. package/dist/platform.js +196 -0
  349. package/dist/platform.js.map +1 -0
  350. package/dist/policies.d.ts +115 -0
  351. package/dist/policies.d.ts.map +1 -0
  352. package/dist/policies.js +158 -0
  353. package/dist/policies.js.map +1 -0
  354. package/dist/principal.d.ts +143 -0
  355. package/dist/principal.d.ts.map +1 -0
  356. package/dist/principal.js +174 -0
  357. package/dist/principal.js.map +1 -0
  358. package/dist/realtime.d.ts +280 -0
  359. package/dist/realtime.d.ts.map +1 -0
  360. package/dist/realtime.js +578 -0
  361. package/dist/realtime.js.map +1 -0
  362. package/dist/retrieval.d.ts +263 -0
  363. package/dist/retrieval.d.ts.map +1 -0
  364. package/dist/retrieval.js +602 -0
  365. package/dist/retrieval.js.map +1 -0
  366. package/dist/runtime-error-client.d.ts +10 -0
  367. package/dist/runtime-error-client.d.ts.map +1 -0
  368. package/dist/runtime-error-client.js +70 -0
  369. package/dist/runtime-error-client.js.map +1 -0
  370. package/dist/runtime-errors.d.ts +180 -0
  371. package/dist/runtime-errors.d.ts.map +1 -0
  372. package/dist/runtime-errors.js +572 -0
  373. package/dist/runtime-errors.js.map +1 -0
  374. package/dist/schema.d.ts +434 -0
  375. package/dist/schema.d.ts.map +1 -0
  376. package/dist/schema.js +232 -0
  377. package/dist/schema.js.map +1 -0
  378. package/dist/search.d.ts +216 -0
  379. package/dist/search.d.ts.map +1 -0
  380. package/dist/search.js +785 -0
  381. package/dist/search.js.map +1 -0
  382. package/dist/settings.d.ts +191 -0
  383. package/dist/settings.d.ts.map +1 -0
  384. package/dist/settings.js +478 -0
  385. package/dist/settings.js.map +1 -0
  386. package/dist/sql.d.ts +7 -0
  387. package/dist/sql.d.ts.map +1 -0
  388. package/dist/sql.js +30 -0
  389. package/dist/sql.js.map +1 -0
  390. package/dist/storage-client.d.ts +69 -0
  391. package/dist/storage-client.d.ts.map +1 -0
  392. package/dist/storage-client.js +469 -0
  393. package/dist/storage-client.js.map +1 -0
  394. package/dist/storage.d.ts +21 -0
  395. package/dist/storage.d.ts.map +1 -0
  396. package/dist/storage.js +82 -0
  397. package/dist/storage.js.map +1 -0
  398. package/dist/subject-domains.d.ts +15 -0
  399. package/dist/subject-domains.d.ts.map +1 -0
  400. package/dist/subject-domains.js +38 -0
  401. package/dist/subject-domains.js.map +1 -0
  402. package/dist/support.d.ts +132 -0
  403. package/dist/support.d.ts.map +1 -0
  404. package/dist/support.js +483 -0
  405. package/dist/support.js.map +1 -0
  406. package/dist/system-tables.d.ts +12 -0
  407. package/dist/system-tables.d.ts.map +1 -0
  408. package/dist/system-tables.js +225 -0
  409. package/dist/system-tables.js.map +1 -0
  410. package/dist/test.d.ts +57 -0
  411. package/dist/test.d.ts.map +1 -0
  412. package/dist/test.js +454 -0
  413. package/dist/test.js.map +1 -0
  414. package/dist/vite.d.ts +82 -0
  415. package/dist/vite.d.ts.map +1 -0
  416. package/dist/vite.js +82 -0
  417. package/dist/vite.js.map +1 -0
  418. package/dist/webpush-crypto.d.ts +39 -0
  419. package/dist/webpush-crypto.d.ts.map +1 -0
  420. package/dist/webpush-crypto.js +213 -0
  421. package/dist/webpush-crypto.js.map +1 -0
  422. package/dist/webpush-private.d.ts +11 -0
  423. package/dist/webpush-private.d.ts.map +1 -0
  424. package/dist/webpush-private.js +11 -0
  425. package/dist/webpush-private.js.map +1 -0
  426. package/dist/webpush.d.ts +86 -0
  427. package/dist/webpush.d.ts.map +1 -0
  428. package/dist/webpush.js +375 -0
  429. package/dist/webpush.js.map +1 -0
  430. package/dist/worker.d.ts +185 -0
  431. package/dist/worker.d.ts.map +1 -0
  432. package/dist/worker.js +13021 -0
  433. package/dist/worker.js.map +1 -0
  434. package/package.json +161 -8
  435. package/README.md +0 -3
@@ -0,0 +1,884 @@
1
+ import { z } from "zod";
2
+ import { stableJson } from "./internal.js";
3
+ export function isZodSchema(schema) {
4
+ return typeof schema.parse === "function";
5
+ }
6
+ export function jsonSchemaFor(schema, options = {}) {
7
+ if (isZodSchema(schema))
8
+ return z.toJSONSchema(schema, options);
9
+ return schema;
10
+ }
11
+ export function parseWithSchema(schema, value, path) {
12
+ if (isZodSchema(schema))
13
+ return schema.parse(value);
14
+ return validateJsonSchema(schema, value, path);
15
+ }
16
+ export function validateJsonSchema(schema, value, path) {
17
+ if (!schema.type)
18
+ return value;
19
+ if (Array.isArray(schema.enum) && !schema.enum.some((candidate) => jsonSchemaValuesEqual(candidate, value))) {
20
+ throw new Error(`${path} must be one of ${schema.enum.map(String).join(", ")}`);
21
+ }
22
+ switch (schema.type) {
23
+ case "object": {
24
+ if (!value || typeof value !== "object" || Array.isArray(value))
25
+ throw new Error(`${path} must be an object`);
26
+ const object = value;
27
+ const properties = schema.properties ?? {};
28
+ for (const required of schema.required ?? []) {
29
+ if (object[required] === undefined)
30
+ throw new Error(`${path}.${required} is required`);
31
+ }
32
+ if (schema.additionalProperties === false) {
33
+ for (const key of Object.keys(object)) {
34
+ if (!properties[key])
35
+ throw new Error(`${path}.${key} is not allowed`);
36
+ }
37
+ }
38
+ return Object.fromEntries(Object.entries(object).map(([key, item]) => [key, properties[key] ? validateJsonSchema(properties[key], item, `${path}.${key}`) : item]));
39
+ }
40
+ case "array": {
41
+ if (!Array.isArray(value))
42
+ throw new Error(`${path} must be an array`);
43
+ if (typeof schema.minItems === "number" && value.length < schema.minItems)
44
+ throw new Error(`${path} must contain at least ${schema.minItems} items`);
45
+ if (typeof schema.maxItems === "number" && value.length > schema.maxItems)
46
+ throw new Error(`${path} must contain at most ${schema.maxItems} items`);
47
+ return schema.items ? value.map((item, index) => validateJsonSchema(schema.items, item, `${path}[${index}]`)) : value;
48
+ }
49
+ case "string":
50
+ if (typeof value !== "string")
51
+ throw new Error(`${path} must be a string`);
52
+ if (typeof schema.minLength === "number" && value.length < schema.minLength)
53
+ throw new Error(`${path} must be at least ${schema.minLength} characters`);
54
+ if (typeof schema.maxLength === "number" && value.length > schema.maxLength)
55
+ throw new Error(`${path} must be at most ${schema.maxLength} characters`);
56
+ return value;
57
+ case "number":
58
+ case "integer":
59
+ if (typeof value !== "number" || !Number.isFinite(value))
60
+ throw new Error(`${path} must be a number`);
61
+ if (schema.type === "integer" && !Number.isInteger(value))
62
+ throw new Error(`${path} must be an integer`);
63
+ if (typeof schema.minimum === "number" && value < schema.minimum)
64
+ throw new Error(`${path} must be at least ${schema.minimum}`);
65
+ if (typeof schema.maximum === "number" && value > schema.maximum)
66
+ throw new Error(`${path} must be at most ${schema.maximum}`);
67
+ return value;
68
+ case "boolean":
69
+ if (typeof value !== "boolean")
70
+ throw new Error(`${path} must be a boolean`);
71
+ return value;
72
+ case "null":
73
+ if (value !== null)
74
+ throw new Error(`${path} must be null`);
75
+ return value;
76
+ default:
77
+ return value;
78
+ }
79
+ }
80
+ /**
81
+ * Keywords a strict tool-parameter schema may not carry.
82
+ *
83
+ * They are validation, not shape, and the provider rejects them outright — the
84
+ * whole request, not the one tool. Dropping them from what is published loosens
85
+ * nothing: the action still validates its input with its own schema when the
86
+ * call arrives, so a discarded `maxLength` is enforced a moment later by the
87
+ * thing that always enforced it.
88
+ */
89
+ const NON_STRUCTURAL_JSON_SCHEMA_KEYWORDS = new Set([
90
+ "minLength", "maxLength", "pattern", "format",
91
+ "minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "multipleOf",
92
+ "minItems", "maxItems", "uniqueItems",
93
+ "minProperties", "maxProperties",
94
+ "default", "examples", "contentEncoding", "contentMediaType",
95
+ "$schema", "$id", "$comment"
96
+ ]);
97
+ /**
98
+ * The strict-subset form of a schema, for publishing to a model.
99
+ *
100
+ * Providers in the OpenAI family validate every tool's `parameters` against a
101
+ * narrow subset and fail the entire request when one tool falls outside it —
102
+ * so an app whose schemas are ordinary, valid JSON Schema gets no reply at all,
103
+ * and nothing says which tool was at fault. This makes the published form
104
+ * conform without touching what the action validates with.
105
+ *
106
+ * Objects are closed. Property *requiredness* is left exactly as it was: an
107
+ * optional property could only be made strict by declaring a null union, and a
108
+ * schema derived from `.optional()` without `.nullable()` would then invite a
109
+ * `null` its own validator rejects. Where that matters, an action declares its
110
+ * tool schema itself.
111
+ *
112
+ * A reused or recursive subschema arrives as a root-relative `$ref` into
113
+ * `$defs`, and the reference is what gets published — that is the point of it.
114
+ * But every judgment about a child's *shape* — whether it permits null, whether
115
+ * it constrains anything — resolves the reference first, because a nullable
116
+ * shape lifted into `$defs` is otherwise read as one that refuses null and the
117
+ * property stays optional in a schema that must have none. `root` is the
118
+ * document those references point into; it defaults to the schema itself, which
119
+ * is right for every call that starts at a root.
120
+ */
121
+ export function strictJsonSchema(schema, root = schema) {
122
+ if (!schema || typeof schema !== "object" || Array.isArray(schema))
123
+ return schema;
124
+ // `oneOf` and `anyOf` at one path are two different claims about the same
125
+ // value, and the subset has only `anyOf`. Merging them would publish a union
126
+ // neither of them asked for, so this refuses instead of guessing: the schema
127
+ // is a mistake a person has to resolve, not a shape to invent.
128
+ if (Array.isArray(schema.oneOf) && Array.isArray(schema.anyOf)) {
129
+ throw new Error("A strict tool schema cannot combine oneOf and anyOf at the same path.");
130
+ }
131
+ const next = {};
132
+ for (const [key, value] of Object.entries(schema)) {
133
+ // Reused and recursive subschemas live in `$defs` and are reached by
134
+ // `$ref`. They are published verbatim, so a validation keyword left inside
135
+ // one refuses the request exactly like a keyword at the top level.
136
+ if ((key === "$defs" || key === "definitions") && value && typeof value === "object" && !Array.isArray(value)) {
137
+ next[key] = Object.fromEntries(Object.entries(value).map(([name, child]) => [name, strictJsonSchema(child, root)]));
138
+ continue;
139
+ }
140
+ if (NON_STRUCTURAL_JSON_SCHEMA_KEYWORDS.has(key))
141
+ continue;
142
+ if (key === "properties" && value && typeof value === "object") {
143
+ // A property whose schema constrains nothing — `{}`, from `z.unknown()`
144
+ // or a hand-written open field — has no strict form at all, and one of
145
+ // them refuses the entire request. It cannot be given a shape, so it is
146
+ // offered as a string holding JSON, which the subset does have a rule
147
+ // for. `restoreStrictActionInput` parses it back before the action's own
148
+ // schema sees it. Leaving the property out instead would publish a tool
149
+ // that quietly cannot carry the field at all.
150
+ next.properties = Object.fromEntries(Object.entries(value)
151
+ .map(([name, child]) => {
152
+ const normalized = strictJsonSchema(child, root);
153
+ return [name, isUnconstrainedJsonSchema(normalized, root) ? jsonEncodedSchema(normalized, "value") : normalized];
154
+ }));
155
+ continue;
156
+ }
157
+ if ((key === "items" || key === "not") && value && typeof value === "object") {
158
+ next[key] = strictJsonSchema(value, root);
159
+ continue;
160
+ }
161
+ // The subset has `anyOf` and no `oneOf`. Publishing the union as `anyOf`
162
+ // drops only the exclusivity claim, which the action's own schema still
163
+ // enforces when the call arrives — a value matching two branches is refused
164
+ // there, with a message, rather than here by a provider naming no tool.
165
+ if ((key === "anyOf" || key === "oneOf") && Array.isArray(value)) {
166
+ next.anyOf = value.map((entry) => strictJsonSchema(entry, root));
167
+ continue;
168
+ }
169
+ if (key === "allOf" && Array.isArray(value)) {
170
+ next[key] = value.map((entry) => strictJsonSchema(entry, root));
171
+ continue;
172
+ }
173
+ // `const` is how a literal — a discriminator, a schema version — arrives
174
+ // from every Zod-shaped schema, and the strict subset has no such keyword.
175
+ // A one-value `enum` is supported and says exactly the same thing, so this
176
+ // is a rename rather than a loosening.
177
+ if (key === "const") {
178
+ if (next.enum === undefined && typeof value === "string")
179
+ next.enum = [value];
180
+ continue;
181
+ }
182
+ // `enum` in the strict subset is a set of strings. A boolean or numeric
183
+ // literal — `z.literal(true)`, a schema version — publishes as its plain
184
+ // type; the action's own schema still refuses any other value.
185
+ if (key === "enum" && Array.isArray(value)) {
186
+ if (value.every((entry) => typeof entry === "string"))
187
+ next.enum = value;
188
+ continue;
189
+ }
190
+ next[key] = value;
191
+ }
192
+ // A union branch often carries `properties` with no `type`, and an unclosed
193
+ // object anywhere in the tree fails the whole request just the same.
194
+ const isObject = next.type === "object" || (next.type === undefined && next.properties !== undefined);
195
+ if (isObject && next.additionalProperties === undefined)
196
+ next.additionalProperties = false;
197
+ // A property whose own schema already permits null can be published as
198
+ // required without changing what anything accepts: the model may send null,
199
+ // and a validator that made the property optional-and-nullable takes null.
200
+ // This is the safe half of "derive `required` automatically" — a property
201
+ // that is merely optional keeps its optionality, because inviting a null its
202
+ // validator would reject is the one way this could bite.
203
+ if (isObject && next.properties) {
204
+ const required = new Set(next.required ?? []);
205
+ for (const [name, child] of Object.entries(next.properties)) {
206
+ if (!required.has(name) && permitsNull(child, root))
207
+ required.add(name);
208
+ }
209
+ if (required.size)
210
+ next.required = [...Object.keys(next.properties)].filter((name) => required.has(name));
211
+ }
212
+ return next;
213
+ }
214
+ /**
215
+ * The strict form of a *tool's* `parameters`, which has one rule beyond the
216
+ * rest: the root must be a single object. A discriminated union — the natural
217
+ * way to write an action that takes several shapes — publishes `anyOf` at the
218
+ * root, which is ordinary valid JSON Schema and refused outright, taking every
219
+ * other tool in the request down with it.
220
+ *
221
+ * So a union root is merged into one object: every branch's properties, each
222
+ * nullable because it belongs to only some branches, and the discriminator's
223
+ * enums unioned so the model still sees which values pair with which shape.
224
+ * This widens only what is *published*. The action still validates with its own
225
+ * union, so a call mixing two branches is refused by `parseWithSchema` with a
226
+ * real message rather than by the provider with none.
227
+ */
228
+ export function strictToolParameters(schema) {
229
+ // Normalise first so the branches are already in subset form when they merge:
230
+ // a discriminator arrives as `const`, and only once that is an `enum` can the
231
+ // branches collapse into one field offering the set of operations. Merging
232
+ // raw would leave eleven single-value unions where one enum belongs.
233
+ const normalized = strictJsonSchema(schema);
234
+ return inlineDefinitions(strictJsonSchema(flattenRootUnion(normalized, normalized)));
235
+ }
236
+ /**
237
+ * Shapes lifted into `$defs`, put back where a reader needs them.
238
+ *
239
+ * `reused: "ref"` dedupes repeated subschemas to keep a large tool list small,
240
+ * and for an object shape used many times the reference pays its way. Two
241
+ * kinds of definition cost more than they save, and each took a feature down
242
+ * in production:
243
+ *
244
+ * - A leaf — a primitive, an enum, a union of those. On 2026-08-28 a
245
+ * `.nullish()` number published as `{"$ref": "#/$defs/__schema1"}`, the live
246
+ * model never chased the pointer, guessed the field was a string, and the
247
+ * action refused the call every time.
248
+ * - A definition used exactly once. It dedupes nothing, so the reference is
249
+ * pure cost — and Zod lifts *every* property of an object carrying a root
250
+ * `.superRefine()` into `$defs` whether or not anything else uses it. On
251
+ * 2026-09-01 a union of two closed objects (a homework failure price) was
252
+ * published that way; across twenty calls the model sent the object as a
253
+ * string of JSON, and the work was never set.
254
+ *
255
+ * A model reads a published schema as text; a field's *type* has to be visible
256
+ * at the field. So a leaf, or a definition with a single use, is inlined at
257
+ * that use — under the use's own annotations, which win — and whatever no
258
+ * longer has a reference reaching it from the root is dropped from `$defs`.
259
+ * Object and array shapes with several uses keep their references, which is
260
+ * the dedupe's real value, and a definition that reaches itself while being
261
+ * inlined keeps the reference at that point, so recursion terminates.
262
+ */
263
+ function inlineDefinitions(schema) {
264
+ const defsKey = ["$defs", "definitions"].find((key) => jsonSchemaObject(schema[key]));
265
+ if (!defsKey)
266
+ return schema;
267
+ const definitions = schema[defsKey];
268
+ // Everything below is keyed by definition *name*, decoded from each `$ref`
269
+ // as a JSON Pointer: a definition called `order/line` is referenced as
270
+ // `#/$defs/order~1line`, and a key built by pasting the name into a pointer
271
+ // would never meet its own references.
272
+ const definitionName = (ref) => {
273
+ const target = typeof ref === "string" ? jsonSchemaDefinitionRef(ref) : null;
274
+ return target && target.key === defsKey ? target.name : null;
275
+ };
276
+ // Every reference to a definition under a node, once per occurrence.
277
+ const eachReference = (node, visit) => {
278
+ if (Array.isArray(node)) {
279
+ node.forEach((item) => eachReference(item, visit));
280
+ return;
281
+ }
282
+ const object = jsonSchemaObject(node);
283
+ if (!object)
284
+ return;
285
+ const name = definitionName(object.$ref);
286
+ if (name !== null)
287
+ visit(name);
288
+ Object.values(object).forEach((value) => eachReference(value, visit));
289
+ };
290
+ const bodies = new Map();
291
+ for (const [name, definition] of Object.entries(definitions)) {
292
+ const body = jsonSchemaObject(definition);
293
+ if (body)
294
+ bodies.set(name, body);
295
+ }
296
+ const uses = new Map();
297
+ eachReference(schema, (name) => uses.set(name, (uses.get(name) ?? 0) + 1));
298
+ const inlinable = new Set();
299
+ for (const [name, body] of bodies) {
300
+ if (isLeafJsonSchema(body) || (uses.get(name) ?? 0) <= 1)
301
+ inlinable.add(name);
302
+ }
303
+ if (!inlinable.size)
304
+ return schema;
305
+ const substitute = (node, stack) => {
306
+ if (Array.isArray(node))
307
+ return node.map((item) => substitute(item, stack));
308
+ const object = jsonSchemaObject(node);
309
+ if (!object)
310
+ return node;
311
+ const name = definitionName(object.$ref);
312
+ if (name !== null && inlinable.has(name) && !stack.has(name)) {
313
+ const { $ref: _ref, ...annotations } = object;
314
+ const deeper = new Set(stack).add(name);
315
+ return {
316
+ ...substitute(bodies.get(name), deeper),
317
+ ...substitute(annotations, deeper),
318
+ };
319
+ }
320
+ return Object.fromEntries(Object.entries(object).map(([key, value]) => [key, substitute(value, stack)]));
321
+ };
322
+ const { [defsKey]: _definitions, ...rest } = schema;
323
+ const inlined = substitute(rest, new Set());
324
+ const rewritten = new Map();
325
+ for (const [name, body] of bodies)
326
+ rewritten.set(name, substitute(body, new Set([name])));
327
+ // Only what the root still reaches survives: a definition inlined at its one
328
+ // use, or one nothing ever pointed at, has no reader left.
329
+ const reachable = new Set();
330
+ const frontier = new Set();
331
+ eachReference(inlined, (name) => frontier.add(name));
332
+ while (frontier.size) {
333
+ const name = frontier.values().next().value;
334
+ frontier.delete(name);
335
+ if (reachable.has(name) || !rewritten.has(name))
336
+ continue;
337
+ reachable.add(name);
338
+ eachReference(rewritten.get(name), (onward) => {
339
+ if (!reachable.has(onward))
340
+ frontier.add(onward);
341
+ });
342
+ }
343
+ const surviving = Object.fromEntries(Object.entries(definitions)
344
+ .filter(([name]) => reachable.has(name))
345
+ .map(([name]) => [name, rewritten.get(name) ?? definitions[name]]));
346
+ return Object.keys(surviving).length ? { ...inlined, [defsKey]: surviving } : inlined;
347
+ }
348
+ /**
349
+ * A shape that is finished where it stands: a primitive, an enum, or a union
350
+ * of those. No properties or items to walk into, no reference to chase — which
351
+ * is also what makes inlining one always terminate.
352
+ */
353
+ function isLeafJsonSchema(schema) {
354
+ if (!schema)
355
+ return false;
356
+ if (schema.$ref !== undefined || schema.properties !== undefined || schema.items !== undefined
357
+ || schema.additionalProperties !== undefined || schema.$defs !== undefined || schema.definitions !== undefined
358
+ || schema.type === "object" || schema.type === "array")
359
+ return false;
360
+ for (const key of ["anyOf", "oneOf", "allOf"]) {
361
+ const branches = schema[key];
362
+ if (Array.isArray(branches) && !branches.every((branch) => isLeafJsonSchema(jsonSchemaObject(branch))))
363
+ return false;
364
+ }
365
+ if (schema.not !== undefined && !isLeafJsonSchema(jsonSchemaObject(schema.not)))
366
+ return false;
367
+ return true;
368
+ }
369
+ function flattenRootUnion(schema, root = schema) {
370
+ if (!schema || typeof schema !== "object" || Array.isArray(schema))
371
+ return schema;
372
+ const key = ["anyOf", "oneOf"].find((candidate) => Array.isArray(schema[candidate]));
373
+ if (!key)
374
+ return schema;
375
+ // A branch shape used elsewhere too is lifted into `$defs` and stands here as
376
+ // a bare `$ref`, which carries no `properties` of its own. Merging needs the
377
+ // branch's real shape, so the reference is followed before the check below —
378
+ // the alternative is bailing out and publishing `anyOf` at the root, which is
379
+ // the shape a strict provider refuses.
380
+ const branches = schema[key]
381
+ .map((branch) => resolveJsonSchemaRef(jsonSchemaObject(branch), root) ?? branch)
382
+ .map((branch) => flattenRootUnion(branch, root));
383
+ if (!branches.length || !branches.every((branch) => branch && typeof branch === "object" && branch.properties && typeof branch.properties === "object")) {
384
+ return schema;
385
+ }
386
+ const names = [];
387
+ const variants = new Map();
388
+ for (const branch of branches) {
389
+ for (const [name, child] of Object.entries(branch.properties)) {
390
+ if (!variants.has(name)) {
391
+ variants.set(name, []);
392
+ names.push(name);
393
+ }
394
+ variants.get(name).push(child);
395
+ }
396
+ }
397
+ const properties = {};
398
+ for (const name of names) {
399
+ const shapes = variants.get(name);
400
+ const distinct = [];
401
+ for (const shape of shapes.flatMap(unionBranches)) {
402
+ if (!distinct.some((seen) => jsonSchemaValuesEqual(seen, shape)))
403
+ distinct.push(shape);
404
+ }
405
+ // The discriminator: one string enum per branch, which merges into the set
406
+ // of values the model may choose between rather than an opaque union.
407
+ const merged = distinct.length === 1
408
+ ? distinct[0]
409
+ : distinct.every((shape) => shape.type === "string" && Array.isArray(shape.enum))
410
+ ? { ...distinct[0], type: "string", enum: [...new Set(distinct.flatMap((shape) => shape.enum))] }
411
+ : { anyOf: distinct };
412
+ // A property carried by only some branches, or optional within its own, is
413
+ // absent on the calls that take another shape.
414
+ const universal = shapes.length === branches.length
415
+ && branches.every((branch) => Array.isArray(branch.required) && branch.required.includes(name));
416
+ properties[name] = universal || permitsNull(merged, root) ? merged : nullableJsonSchema(merged, root);
417
+ }
418
+ const { anyOf: _anyOf, oneOf: _oneOf, ...rest } = schema;
419
+ return { ...rest, type: "object", properties, required: names, additionalProperties: false };
420
+ }
421
+ /** The same schema, also accepting `null`, without nesting a union in a union. */
422
+ function nullableJsonSchema(schema, root) {
423
+ if (Array.isArray(schema.anyOf)) {
424
+ const branches = schema.anyOf;
425
+ return branches.some((branch) => permitsNull(branch, root))
426
+ ? schema
427
+ : { ...schema, anyOf: [...branches, { type: "null" }] };
428
+ }
429
+ // A `$ref` is wrapped rather than followed: the reference is what gets
430
+ // published, and a union around it says the same thing about the value.
431
+ return { anyOf: [schema, { type: "null" }] };
432
+ }
433
+ /** One flat list of branches, so merging a union with a union does not nest one. */
434
+ function unionBranches(schema) {
435
+ return Array.isArray(schema.anyOf) && Object.keys(schema).length === 1
436
+ ? schema.anyOf.flatMap(unionBranches)
437
+ : [schema];
438
+ }
439
+ function parseJson(text) {
440
+ try {
441
+ return JSON.parse(text);
442
+ }
443
+ catch {
444
+ return undefined;
445
+ }
446
+ }
447
+ // Keywords that only constrain one JSON type, so a schema carrying one with no
448
+ // `type` of its own is read as that type — the way a reader of the published
449
+ // schema reads `{"pattern": …}` as a string field.
450
+ const JSON_TYPE_IMPLYING_KEYWORDS = {
451
+ minLength: "string", maxLength: "string", pattern: "string", format: "string",
452
+ contentEncoding: "string", contentMediaType: "string",
453
+ minimum: "number", maximum: "number", exclusiveMinimum: "number", exclusiveMaximum: "number", multipleOf: "number",
454
+ properties: "object", additionalProperties: "object", patternProperties: "object", propertyNames: "object",
455
+ required: "object", minProperties: "object", maxProperties: "object", dependentRequired: "object",
456
+ dependentSchemas: "object", unevaluatedProperties: "object",
457
+ items: "array", prefixItems: "array", contains: "array", minItems: "array", maxItems: "array",
458
+ uniqueItems: "array", minContains: "array", maxContains: "array", unevaluatedItems: "array"
459
+ };
460
+ /**
461
+ * Whether a value of the given JSON type could satisfy the schema. Reads the
462
+ * declared `type` — or, without one, the type its type-specific keywords
463
+ * imply — the literal keywords (`enum`, `const`), and every union and `allOf`
464
+ * branch; a schema that names no type at all admits every type. Used to tell
465
+ * an encoding from an answer when a model hands back a string, so where it
466
+ * cannot tell (a `not`, an unresolved `$ref`) it answers that the type is
467
+ * admitted, and the string is left as it arrived.
468
+ *
469
+ * `path` holds the schemas being judged above this one, so a recursive
470
+ * reference ends instead of looping. It is a path, not a visited set: two
471
+ * `allOf` branches reaching the same definition are two judgments of it, and a
472
+ * branch that leads back to a schema already being judged says nothing new
473
+ * about it, so it is left out rather than counted either way.
474
+ */
475
+ function admitsJsonType(schema, type, root, path = new Set()) {
476
+ const resolved = resolveJsonSchemaRef(jsonSchemaObject(schema), root);
477
+ if (!resolved)
478
+ return true;
479
+ if (isUnconstrainedJsonSchema(resolved, root))
480
+ return true;
481
+ const literalType = (literal) => literal === null ? "null" : Array.isArray(literal) ? "array" : typeof literal === "object" ? "object"
482
+ : typeof literal === "number" ? "number" : typeof literal === "boolean" ? "boolean" : "string";
483
+ if (Array.isArray(resolved.enum))
484
+ return resolved.enum.some((literal) => literalType(literal) === type);
485
+ if (Object.prototype.hasOwnProperty.call(resolved, "const"))
486
+ return literalType(resolved.const) === type;
487
+ const declared = Array.isArray(resolved.type) ? resolved.type : resolved.type !== undefined ? [resolved.type] : [];
488
+ const named = declared.length
489
+ ? declared
490
+ : [...new Set(Object.keys(resolved).flatMap((key) => JSON_TYPE_IMPLYING_KEYWORDS[key] ?? []))];
491
+ if (named.length && !named.includes(type)
492
+ && !(type === "integer" && named.includes("number"))
493
+ && !(type === "number" && named.includes("integer"))) {
494
+ return false;
495
+ }
496
+ const inner = new Set(path).add(resolved);
497
+ const branches = (key) => (Array.isArray(resolved[key]) ? resolved[key] : []).filter((branch) => {
498
+ const target = resolveJsonSchemaRef(jsonSchemaObject(branch), root);
499
+ return !target || !inner.has(target);
500
+ });
501
+ const admits = (branch) => admitsJsonType(branch, type, root, inner);
502
+ for (const key of ["anyOf", "oneOf"]) {
503
+ const union = branches(key);
504
+ if (union.length && !union.some(admits))
505
+ return false;
506
+ }
507
+ return branches("allOf").every(admits);
508
+ }
509
+ /**
510
+ * Whether the schema spells this exact string out as one of its values — an
511
+ * `enum` member or a `const`, here or in any union or `allOf` branch. A
512
+ * literal the app named is an answer even when it looks like padding.
513
+ */
514
+ function namesStringLiteral(schema, literal, root, path = new Set()) {
515
+ const resolved = resolveJsonSchemaRef(jsonSchemaObject(schema), root);
516
+ if (!resolved || path.has(resolved))
517
+ return false;
518
+ if (Array.isArray(resolved.enum) && resolved.enum.includes(literal))
519
+ return true;
520
+ if (resolved.const === literal)
521
+ return true;
522
+ const inner = new Set(path).add(resolved);
523
+ return ["anyOf", "oneOf", "allOf"].some((key) => Array.isArray(resolved[key])
524
+ && resolved[key].some((branch) => namesStringLiteral(branch, literal, root, inner)));
525
+ }
526
+ /**
527
+ * Whether a schema accepts `null` outright, by type or through a union branch.
528
+ *
529
+ * With a `root` in hand a reference into that root's `$defs` is followed first,
530
+ * because the whole reason a shape is in `$defs` is that it is used twice, and
531
+ * a nullable shape read as non-nullable is what leaves a property optional in a
532
+ * schema that must have none. `seen` terminates a recursive schema, which is
533
+ * exactly the other thing `$defs` exists for.
534
+ */
535
+ function permitsNull(schema, root, seen = new Set()) {
536
+ const resolved = resolveJsonSchemaRef(jsonSchemaObject(schema), root);
537
+ if (!resolved || seen.has(resolved))
538
+ return false;
539
+ seen.add(resolved);
540
+ if (resolved.type === "null")
541
+ return true;
542
+ if (Array.isArray(resolved.type) && resolved.type.includes("null"))
543
+ return true;
544
+ for (const key of ["anyOf", "oneOf"]) {
545
+ const branches = resolved[key];
546
+ if (Array.isArray(branches) && branches.some((branch) => permitsNull(branch, root, seen)))
547
+ return true;
548
+ }
549
+ return false;
550
+ }
551
+ function jsonSchemaObject(value) {
552
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
553
+ }
554
+ /**
555
+ * A `$ref` into the schema's own `$defs`, followed so a judgment about a shape
556
+ * sees the shape rather than the reference. Only root-relative pointers into
557
+ * `$defs`/`definitions` resolve; any other form — a remote `$ref`, a pointer at
558
+ * the document root — is left as it arrived. Nothing here rewrites what is
559
+ * published: resolution informs the judgments, and the reference survives them.
560
+ */
561
+ function resolveJsonSchemaRef(schema, root, seen = new Set()) {
562
+ if (!schema || typeof schema.$ref !== "string" || !root || seen.has(schema))
563
+ return schema;
564
+ seen.add(schema);
565
+ const reference = jsonSchemaDefinitionRef(schema.$ref);
566
+ const defs = reference ? jsonSchemaObject(root[reference.key]) : null;
567
+ const target = defs && reference ? jsonSchemaObject(defs[reference.name]) : null;
568
+ // A chain of references ends at a shape or at a cycle, and `seen` is what
569
+ // makes the second one end.
570
+ return target ? resolveJsonSchemaRef(target, root, seen) : schema;
571
+ }
572
+ /**
573
+ * The definition a root-relative `$ref` names, decoded as RFC 6901 reads a
574
+ * pointer in a URI fragment: percent-decoding first, then `~1` → `/` and
575
+ * `~0` → `~` within each segment. A pointer reaching inside a definition
576
+ * (`#/$defs/a/properties/b`), or anywhere but `$defs`/`definitions`, names no
577
+ * definition.
578
+ */
579
+ function jsonSchemaDefinitionRef(ref) {
580
+ if (!ref.startsWith("#/"))
581
+ return null;
582
+ let pointer;
583
+ try {
584
+ pointer = decodeURIComponent(ref.slice(1));
585
+ }
586
+ catch {
587
+ return null;
588
+ }
589
+ const segments = pointer.slice(1).split("/").map((segment) => segment.replace(/~1/g, "/").replace(/~0/g, "~"));
590
+ const [key, name] = segments;
591
+ if (segments.length !== 2 || (key !== "$defs" && key !== "definitions") || !name)
592
+ return null;
593
+ return { key, name };
594
+ }
595
+ function jsonSchemaValuesEqual(left, right) {
596
+ if (Object.is(left, right))
597
+ return true;
598
+ try {
599
+ return stableJson(left) === stableJson(right);
600
+ }
601
+ catch {
602
+ return false;
603
+ }
604
+ }
605
+ /* ------------------------------------------------------------------------- *
606
+ * The wire form, and its inverse.
607
+ *
608
+ * `strictJsonSchema` above is the *advertised* form: it removes what the strict
609
+ * subset has no rule for and leaves everything a reader would rely on — an
610
+ * optional property is still optional, an open record is still a record. That
611
+ * form is what an action publishes to documentation, to a manifest, and to any
612
+ * caller asking what it accepts.
613
+ *
614
+ * Two more rewrites are needed before a strict provider will take it, and both
615
+ * change the shape of the *value* the model then sends back:
616
+ *
617
+ * - optionality has to be spelled as a null union with every property
618
+ * required, because the subset has no notion of an omitted key;
619
+ * - a record with open keys, or a value with no shape at all, has no strict
620
+ * form, so it travels as a string holding JSON.
621
+ *
622
+ * Neither is safe on its own: padded nulls and encoded strings reach a handler
623
+ * whose own validator refuses both. So they live here, paired with the inverse
624
+ * that undoes them before anything parses the arguments, and the pair is
625
+ * applied together at the one seam where both halves are in reach — Core's own
626
+ * chat request serialization (`strictChatTools` / `restoreStrictToolCalls` in
627
+ * ai.ts). A custom inference provider that hands tools to a strict API itself
628
+ * reuses these instead of rebuilding them.
629
+ * ------------------------------------------------------------------------- */
630
+ /** Keywords that describe a schema to a reader without constraining any value. */
631
+ const JSON_SCHEMA_ANNOTATION_KEYWORDS = new Set(["title", "description", "$comment", "deprecated", "readOnly", "writeOnly"]);
632
+ /**
633
+ * A schema that constrains nothing — `{}`, from `z.unknown()` or `z.any()`, or
634
+ * one carrying only annotations and validation keywords the subset drops. It
635
+ * reads as harmless and refuses every request, so it travels as JSON in a
636
+ * string and comes back parsed.
637
+ *
638
+ * An unconstrained shape reached through a `$ref` is the same shape, so the
639
+ * reference is followed before the keys are read; without a `root` a `$ref` is
640
+ * its own key and constrains nothing that can be seen from here.
641
+ */
642
+ function isUnconstrainedJsonSchema(schema, root) {
643
+ const resolved = resolveJsonSchemaRef(schema, root) ?? schema;
644
+ return Object.keys(resolved).every((key) => JSON_SCHEMA_ANNOTATION_KEYWORDS.has(key) || NON_STRUCTURAL_JSON_SCHEMA_KEYWORDS.has(key));
645
+ }
646
+ /** An object whose keys are open — `z.record(...)`, or a hand-written map. */
647
+ function isOpenRecordJsonSchema(schema) {
648
+ return schema.type === "object"
649
+ && (schema.propertyNames !== undefined || jsonSchemaObject(schema.additionalProperties) !== null);
650
+ }
651
+ function jsonEncodedSchema(schema, subject) {
652
+ const instruction = subject === "object"
653
+ ? "Encode this object as a JSON string."
654
+ : "Encode this value as JSON in a string.";
655
+ const description = typeof schema.description === "string" && schema.description
656
+ ? `${schema.description} ${instruction}`
657
+ : subject === "object" ? "A JSON object encoded as a string." : "A JSON value encoded as a string.";
658
+ return { type: "string", description };
659
+ }
660
+ /**
661
+ * The same schema, also accepting `null`, written the way each shape allows —
662
+ * widening a `type`, extending an existing union, or wrapping in a new one.
663
+ * A one-value `enum` gains `null` alongside so the enum keeps describing the
664
+ * whole set of permitted values rather than contradicting the type.
665
+ */
666
+ function nullPaddedJsonSchema(schema) {
667
+ const enumClosed = Array.isArray(schema.enum) && !schema.enum.includes(null);
668
+ // An `enum` that lists no `null` refuses one whatever the type says, so a
669
+ // schema that already permits null is only finished if its enum agrees.
670
+ if (permitsNull(schema) && !enumClosed)
671
+ return schema;
672
+ const enumValues = enumClosed ? [...schema.enum, null] : schema.enum;
673
+ if (Object.prototype.hasOwnProperty.call(schema, "const")) {
674
+ return { anyOf: [schema, { type: "null" }] };
675
+ }
676
+ if (typeof schema.type === "string") {
677
+ return { ...schema, type: [schema.type, "null"], ...(enumValues ? { enum: enumValues } : {}) };
678
+ }
679
+ if (Array.isArray(schema.type)) {
680
+ const types = schema.type;
681
+ return {
682
+ ...schema,
683
+ type: (types.includes("null") ? types : [...types, "null"]),
684
+ ...(enumValues ? { enum: enumValues } : {})
685
+ };
686
+ }
687
+ if (Array.isArray(schema.anyOf)) {
688
+ const branches = schema.anyOf;
689
+ return {
690
+ ...schema,
691
+ anyOf: branches.some((branch) => permitsNull(branch)) ? branches : [...branches, { type: "null" }],
692
+ ...(enumValues ? { enum: enumValues } : {})
693
+ };
694
+ }
695
+ return { anyOf: [schema, { type: "null" }] };
696
+ }
697
+ /**
698
+ * The wire form of a tool's parameters or a structured response schema: the
699
+ * advertised strict subset, plus the two rewrites that need
700
+ * `restoreStrictModelValue` on the way back.
701
+ *
702
+ * Applying it twice changes nothing — a padded property already permits null,
703
+ * and an encoded record is a string rather than a record — so a schema that has
704
+ * already been through `strictToolParameters` may pass through here safely.
705
+ */
706
+ export function strictModelSchema(schema) {
707
+ return padStrictJsonSchema(strictToolParameters(schema));
708
+ }
709
+ function padStrictJsonSchema(value, optional = false) {
710
+ const schema = jsonSchemaObject(value);
711
+ if (!schema)
712
+ return value;
713
+ if (isUnconstrainedJsonSchema(schema)) {
714
+ const encoded = jsonEncodedSchema(schema, "value");
715
+ return optional ? nullPaddedJsonSchema(encoded) : encoded;
716
+ }
717
+ if (isOpenRecordJsonSchema(schema)) {
718
+ const encoded = jsonEncodedSchema(schema, "object");
719
+ return optional ? nullPaddedJsonSchema(encoded) : encoded;
720
+ }
721
+ let next = { ...schema };
722
+ const properties = jsonSchemaObject(schema.properties);
723
+ if (properties) {
724
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
725
+ const padded = Object.fromEntries(Object.entries(properties).map(([name, child]) => [name, padStrictJsonSchema(child, !required.has(name))]));
726
+ next = { ...next, properties: padded, required: Object.keys(padded), additionalProperties: false };
727
+ }
728
+ if (schema.items !== undefined)
729
+ next.items = padStrictJsonSchema(schema.items);
730
+ for (const key of ["anyOf", "allOf"]) {
731
+ if (Array.isArray(schema[key])) {
732
+ next[key] = schema[key].map((branch) => padStrictJsonSchema(branch));
733
+ }
734
+ }
735
+ for (const key of ["$defs", "definitions"]) {
736
+ const defs = jsonSchemaObject(schema[key]);
737
+ if (defs) {
738
+ next[key] = Object.fromEntries(Object.entries(defs).map(([name, child]) => [name, padStrictJsonSchema(child)]));
739
+ }
740
+ }
741
+ return optional ? nullPaddedJsonSchema(next) : next;
742
+ }
743
+ /**
744
+ * The inverse of `strictModelSchema`, run against the schema as it was *before*
745
+ * the wire form: null padding is stripped where the original left the property
746
+ * optional, JSON-encoded records are parsed back into objects, and a union is
747
+ * followed into the branch the value actually took so the same is done inside
748
+ * it.
749
+ *
750
+ * A value that was never padded passes through unchanged, so running this over
751
+ * arguments from a provider that needed none is safe.
752
+ */
753
+ export function restoreStrictModelValue(value, schema) {
754
+ return restoreStrictValue(value, schema, schema);
755
+ }
756
+ function restoreStrictValue(value, schemaValue, root) {
757
+ const schema = resolveJsonSchemaRef(jsonSchemaObject(schemaValue), root);
758
+ if (!schema)
759
+ return value;
760
+ if (typeof value === "string" && isUnconstrainedJsonSchema(schema)) {
761
+ try {
762
+ return JSON.parse(value);
763
+ }
764
+ catch {
765
+ return value;
766
+ }
767
+ }
768
+ if (typeof value === "string" && isOpenRecordJsonSchema(schema)) {
769
+ try {
770
+ return jsonSchemaObject(JSON.parse(value)) ?? value;
771
+ }
772
+ catch {
773
+ return value;
774
+ }
775
+ }
776
+ // The strict subset makes every nullable property required, so a model must
777
+ // send *something* for a field it has nothing for — and a weak one sends the
778
+ // four letters "null". On a field that admits null, that is the padding gone
779
+ // wrong, not a value: seen live 2026-09-01 on a nullable text field meant
780
+ // for her verbatim words, where it would have filed "null" as her sentence,
781
+ // and on a nullable permission id, where it would have read as one cited.
782
+ // An app that lists the string "null" itself — an enum member, a const —
783
+ // meant it, so only a field that does not name it is read this way.
784
+ if (value === "null" && permitsNull(schema, root) && !namesStringLiteral(schema, "null", root))
785
+ return null;
786
+ if (typeof value === "string" && !admitsJsonType(schema, "string", root)) {
787
+ // A closed object or an array handed over as a string of JSON. The schema
788
+ // offers no string at this field, so the string is an encoding, not an
789
+ // answer; it is read and restored as the value it encodes. Twenty live
790
+ // calls on 2026-09-01 sent a failure price this way and every one was
791
+ // refused at the door, with the model unable to tell what was wrong.
792
+ const parsed = parseJson(value);
793
+ if ((jsonSchemaObject(parsed) && admitsJsonType(schema, "object", root))
794
+ || (Array.isArray(parsed) && admitsJsonType(schema, "array", root))) {
795
+ return restoreStrictValue(parsed, schema, root);
796
+ }
797
+ }
798
+ const branch = matchingUnionBranch(schema, value, root);
799
+ if (branch)
800
+ return restoreStrictValue(value, branch, root);
801
+ if (Array.isArray(value))
802
+ return value.map((item) => restoreStrictValue(item, schema.items, root));
803
+ const object = jsonSchemaObject(value);
804
+ const properties = jsonSchemaObject(schema.properties);
805
+ if (!object || !properties)
806
+ return value;
807
+ const required = new Set(Array.isArray(schema.required) ? schema.required.filter((name) => typeof name === "string") : []);
808
+ return Object.fromEntries(Object.entries(object).flatMap(([key, item]) => {
809
+ // The padding, undone: a key the original schema did not require was only
810
+ // sent because the strict subset has no way to leave it out.
811
+ if (item === null && !required.has(key))
812
+ return [];
813
+ return [[key, restoreStrictValue(item, properties[key], root)]];
814
+ }));
815
+ }
816
+ /**
817
+ * The branch of a union a value actually took.
818
+ *
819
+ * A discriminated union is matched by its discriminator first — the literal
820
+ * property that names the shape — because two branches of one union routinely
821
+ * share a type, and picking the wrong one would strip the wrong keys. Anything
822
+ * else falls back to the first branch whose type the value could satisfy.
823
+ */
824
+ function matchingUnionBranch(schema, value, root) {
825
+ const union = Array.isArray(schema.oneOf) ? schema.oneOf : Array.isArray(schema.anyOf) ? schema.anyOf : [];
826
+ const candidates = union
827
+ .map((candidate) => resolveJsonSchemaRef(jsonSchemaObject(candidate), root))
828
+ .filter((candidate) => Boolean(candidate));
829
+ if (!candidates.length)
830
+ return null;
831
+ const object = jsonSchemaObject(value);
832
+ if (object) {
833
+ const discriminated = candidates.find((candidate) => {
834
+ const properties = jsonSchemaObject(candidate.properties);
835
+ if (!properties)
836
+ return false;
837
+ return Object.entries(properties).some(([key, propertyValue]) => {
838
+ const property = jsonSchemaObject(propertyValue);
839
+ if (!property || object[key] === undefined)
840
+ return false;
841
+ if (Object.prototype.hasOwnProperty.call(property, "const"))
842
+ return Object.is(property.const, object[key]);
843
+ return Array.isArray(property.enum) && property.enum.length === 1 && Object.is(property.enum[0], object[key]);
844
+ });
845
+ });
846
+ if (discriminated)
847
+ return discriminated;
848
+ }
849
+ // Before settling for any object branch, prefer one whose declared
850
+ // properties cover every key the value actually carries. A strict transform
851
+ // that merges a discriminated union hoists the discriminator away from its
852
+ // siblings, so a nested union of bodies reaches here with no discriminator
853
+ // at all — and "first object branch" then restores the value against a
854
+ // stranger's `required`, deleting every explicit null the right branch
855
+ // required. Found live 2026-08-26: a maintenance card's `standingSlot: null`
856
+ // was stripped against a sibling body's schema, making null unsendable and
857
+ // teaching the model that only an invented value could pass.
858
+ if (object) {
859
+ const covering = candidates.find((candidate) => {
860
+ if (candidate.type !== "object" || isOpenRecordJsonSchema(candidate))
861
+ return false;
862
+ const properties = jsonSchemaObject(candidate.properties);
863
+ if (!properties)
864
+ return false;
865
+ return Object.keys(object).every((key) => properties[key] !== undefined);
866
+ });
867
+ if (covering)
868
+ return covering;
869
+ }
870
+ return candidates.find((candidate) => {
871
+ if (candidate.type === "null")
872
+ return value === null;
873
+ if (isOpenRecordJsonSchema(candidate))
874
+ return typeof value === "string" || Boolean(object);
875
+ if (candidate.type === "object")
876
+ return Boolean(object);
877
+ if (candidate.type === "array")
878
+ return Array.isArray(value);
879
+ if (candidate.type === "integer")
880
+ return typeof value === "number";
881
+ return typeof candidate.type === "string" && typeof value === candidate.type;
882
+ }) ?? null;
883
+ }
884
+ //# sourceMappingURL=json-schema.js.map