@sixb/core 0.1.6 → 0.1.7

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 (535) hide show
  1. package/dist/actions/index.js +37 -33
  2. package/dist/actions/index.js.map +1 -1
  3. package/dist/actions/worker.js +3 -3
  4. package/dist/agents/adapters.d.ts +33 -76
  5. package/dist/agents/adapters.d.ts.map +1 -1
  6. package/dist/agents/authority.d.ts +22 -6
  7. package/dist/agents/authority.d.ts.map +1 -1
  8. package/dist/agents/builders.d.ts +3 -11
  9. package/dist/agents/builders.d.ts.map +1 -1
  10. package/dist/agents/context.js +2 -2
  11. package/dist/agents/dispatch.d.ts +9 -1
  12. package/dist/agents/dispatch.d.ts.map +1 -1
  13. package/dist/agents/errors.d.ts +2 -2
  14. package/dist/agents/errors.d.ts.map +1 -1
  15. package/dist/agents/execution.d.ts +9 -10
  16. package/dist/agents/execution.d.ts.map +1 -1
  17. package/dist/agents/ids.d.ts +4 -0
  18. package/dist/agents/ids.d.ts.map +1 -1
  19. package/dist/agents/index.d.ts +13 -9
  20. package/dist/agents/index.d.ts.map +1 -1
  21. package/dist/agents/index.js +80 -68
  22. package/dist/agents/index.js.map +1 -1
  23. package/dist/agents/message.d.ts +17 -10
  24. package/dist/agents/message.d.ts.map +1 -1
  25. package/dist/agents/model-loop.d.ts +56 -0
  26. package/dist/agents/model-loop.d.ts.map +1 -0
  27. package/dist/agents/reference.d.ts +4 -0
  28. package/dist/agents/reference.d.ts.map +1 -0
  29. package/dist/agents/request.d.ts +10 -8
  30. package/dist/agents/request.d.ts.map +1 -1
  31. package/dist/agents/retired-config.d.ts +4 -0
  32. package/dist/agents/retired-config.d.ts.map +1 -0
  33. package/dist/agents/streams.d.ts +13 -8
  34. package/dist/agents/streams.d.ts.map +1 -1
  35. package/dist/agents/streams.js +7 -5
  36. package/dist/agents/streams.js.map +1 -1
  37. package/dist/agents/tool-catalog.d.ts +9 -0
  38. package/dist/agents/tool-catalog.d.ts.map +1 -0
  39. package/dist/agents/tool-definition.d.ts +1 -0
  40. package/dist/agents/tool-definition.d.ts.map +1 -1
  41. package/dist/agents/types.d.ts +31 -68
  42. package/dist/agents/types.d.ts.map +1 -1
  43. package/dist/agents/validation.d.ts +4 -10
  44. package/dist/agents/validation.d.ts.map +1 -1
  45. package/dist/ai-usage/execution.d.ts +53 -0
  46. package/dist/ai-usage/execution.d.ts.map +1 -0
  47. package/dist/ai-usage/index.d.ts +3 -0
  48. package/dist/ai-usage/index.d.ts.map +1 -0
  49. package/dist/auth/index.js +7 -7
  50. package/dist/authorization/decision.d.ts +5 -2
  51. package/dist/authorization/decision.d.ts.map +1 -1
  52. package/dist/authorization/grant-kinds.d.ts +24 -8
  53. package/dist/authorization/grant-kinds.d.ts.map +1 -1
  54. package/dist/authorization/index.d.ts +1 -1
  55. package/dist/authorization/index.d.ts.map +1 -1
  56. package/dist/authorization/index.js +8 -6
  57. package/dist/authorization/index.js.map +1 -1
  58. package/dist/authorization/resolve.d.ts +3 -3
  59. package/dist/authorization/resolve.d.ts.map +1 -1
  60. package/dist/authorization/types.d.ts +7 -5
  61. package/dist/authorization/types.d.ts.map +1 -1
  62. package/dist/blob-storage/browser.js +2 -2
  63. package/dist/blob-storage/index.js +3 -3
  64. package/dist/bootstrap/discovery.d.ts +1 -7
  65. package/dist/bootstrap/discovery.d.ts.map +1 -1
  66. package/dist/bootstrap/index.js +52 -48
  67. package/dist/bootstrap/index.js.map +1 -1
  68. package/dist/broker/index.js +2 -2
  69. package/dist/{chunk-zqysyfjt.js → chunk-08m3b6w8.js} +1 -1
  70. package/dist/{chunk-1g8negke.js → chunk-08twe8m6.js} +93 -8
  71. package/dist/chunk-08twe8m6.js.map +12 -0
  72. package/dist/{chunk-xkthy56g.js → chunk-1kamz6j0.js} +1 -1
  73. package/dist/{chunk-dy311asx.js → chunk-2b5qtban.js} +12 -12
  74. package/dist/{chunk-dy311asx.js.map → chunk-2b5qtban.js.map} +3 -3
  75. package/dist/{chunk-0172wgm9.js → chunk-2xns679x.js} +10 -2
  76. package/dist/{chunk-0172wgm9.js.map → chunk-2xns679x.js.map} +3 -3
  77. package/dist/{chunk-f83ka50g.js → chunk-37wk412q.js} +86 -28
  78. package/dist/{chunk-f83ka50g.js.map → chunk-37wk412q.js.map} +8 -8
  79. package/dist/{chunk-md8k0r54.js → chunk-3fqt22c4.js} +4 -4
  80. package/dist/{chunk-t9xghkva.js → chunk-3kv70xwp.js} +3 -2
  81. package/dist/{chunk-t9xghkva.js.map → chunk-3kv70xwp.js.map} +3 -3
  82. package/dist/{chunk-z3zp0bj1.js → chunk-407j3msh.js} +1 -1
  83. package/dist/{chunk-rhrbz7d4.js → chunk-4a849fr1.js} +1 -1
  84. package/dist/{chunk-62c7t4jc.js → chunk-4nxeacx7.js} +1 -1
  85. package/dist/{chunk-cy0n5dms.js → chunk-5jcdmjam.js} +1 -1
  86. package/dist/{chunk-819wnjz8.js → chunk-64sr682n.js} +7 -7
  87. package/dist/{chunk-t624af60.js → chunk-6ed5bwnd.js} +646 -67
  88. package/dist/{chunk-t624af60.js.map → chunk-6ed5bwnd.js.map} +10 -9
  89. package/dist/{chunk-x2yw73hy.js → chunk-7ds9620f.js} +1 -1
  90. package/dist/{chunk-dm72y8wt.js → chunk-7y0f6rf1.js} +29 -16
  91. package/dist/chunk-7y0f6rf1.js.map +10 -0
  92. package/dist/{chunk-72q2y8hn.js → chunk-8tsf6dmc.js} +2 -2
  93. package/dist/{chunk-nkbfrt0c.js → chunk-9aehf39w.js} +7 -7
  94. package/dist/{chunk-ezake7g1.js → chunk-agsvg9ar.js} +1 -1
  95. package/dist/{chunk-rdeagz6b.js → chunk-atmkaf60.js} +1 -1
  96. package/dist/{chunk-rdeagz6b.js.map → chunk-atmkaf60.js.map} +2 -2
  97. package/dist/chunk-c15dr03f.js +43 -0
  98. package/dist/chunk-c15dr03f.js.map +10 -0
  99. package/dist/{chunk-0hc5j867.js → chunk-d2ndstdf.js} +8 -6
  100. package/dist/{chunk-0hc5j867.js.map → chunk-d2ndstdf.js.map} +2 -2
  101. package/dist/{chunk-rnshztfq.js → chunk-d63tybny.js} +2 -2
  102. package/dist/{chunk-t0jjkep3.js → chunk-d8qkxt2v.js} +4 -2
  103. package/dist/chunk-d8qkxt2v.js.map +10 -0
  104. package/dist/{chunk-vybf6pkp.js → chunk-dbc80ad7.js} +1 -1
  105. package/dist/{chunk-4gz41why.js → chunk-dqn23610.js} +1 -1
  106. package/dist/{chunk-5sxb1168.js → chunk-e4rvtvpw.js} +13 -11
  107. package/dist/{chunk-5sxb1168.js.map → chunk-e4rvtvpw.js.map} +2 -2
  108. package/dist/{chunk-h9kxd41f.js → chunk-gbrpsx4m.js} +19 -6
  109. package/dist/chunk-gbrpsx4m.js.map +11 -0
  110. package/dist/{chunk-nva1xkjz.js → chunk-h0knpbz5.js} +468 -1236
  111. package/dist/chunk-h0knpbz5.js.map +38 -0
  112. package/dist/{chunk-tg5mee00.js → chunk-ha58tjtt.js} +6 -6
  113. package/dist/{chunk-f6erf2vv.js → chunk-hdz94br2.js} +2 -2
  114. package/dist/chunk-jecn6t54.js +307 -0
  115. package/dist/chunk-jecn6t54.js.map +12 -0
  116. package/dist/{chunk-dsrkgtnh.js → chunk-jq43kdvk.js} +1 -1
  117. package/dist/{chunk-wtmzkcht.js → chunk-k34z5rvh.js} +1 -1
  118. package/dist/{chunk-htq0qh7z.js → chunk-ka3a2ft3.js} +2 -2
  119. package/dist/{chunk-znagycq7.js → chunk-kt81c11h.js} +2 -2
  120. package/dist/chunk-n2arzn6e.js +1745 -0
  121. package/dist/chunk-n2arzn6e.js.map +20 -0
  122. package/dist/{chunk-f2rt4vkh.js → chunk-n2w475r0.js} +3 -3
  123. package/dist/{chunk-t8t39h7v.js → chunk-n6jxh8sw.js} +10 -2
  124. package/dist/chunk-n6jxh8sw.js.map +10 -0
  125. package/dist/{chunk-drjqm1aa.js → chunk-p03r0h5s.js} +310 -28
  126. package/dist/chunk-p03r0h5s.js.map +16 -0
  127. package/dist/chunk-p2vqaxkc.js +528 -0
  128. package/dist/chunk-p2vqaxkc.js.map +15 -0
  129. package/dist/{chunk-n4spznws.js → chunk-qjycjdj6.js} +84 -11
  130. package/dist/chunk-qjycjdj6.js.map +12 -0
  131. package/dist/chunk-qjzp9xyb.js +286 -0
  132. package/dist/chunk-qjzp9xyb.js.map +12 -0
  133. package/dist/{chunk-5gynx4xn.js → chunk-qv38twt8.js} +50 -69
  134. package/dist/{chunk-5gynx4xn.js.map → chunk-qv38twt8.js.map} +8 -8
  135. package/dist/{chunk-bhxaq2nn.js → chunk-qw9gvjv5.js} +1 -1
  136. package/dist/{chunk-8gv5z0zm.js → chunk-rp1mvzb4.js} +6 -6
  137. package/dist/{chunk-1e8m6yn3.js → chunk-rre42skh.js} +182 -18
  138. package/dist/chunk-rre42skh.js.map +39 -0
  139. package/dist/{chunk-ghteq96b.js → chunk-s5y30bc9.js} +2 -2
  140. package/dist/{chunk-a31h57d5.js → chunk-tn7xcs2n.js} +2 -2
  141. package/dist/{chunk-6gjqgd3d.js → chunk-tpnd31c1.js} +2 -1
  142. package/dist/chunk-tpnd31c1.js.map +11 -0
  143. package/dist/chunk-trxxmgnf.js +68 -0
  144. package/dist/chunk-trxxmgnf.js.map +11 -0
  145. package/dist/{chunk-e42bc6m3.js → chunk-vjjv9mrb.js} +2 -2
  146. package/dist/{chunk-8b55ygje.js → chunk-w3e09qqk.js} +1 -1
  147. package/dist/{chunk-ckxfnx7f.js → chunk-wjgm6jjt.js} +2 -2
  148. package/dist/{chunk-3j7573mj.js → chunk-x0qhkqje.js} +2 -2
  149. package/dist/{chunk-dysw7nsm.js → chunk-xdpwpkha.js} +2 -2
  150. package/dist/{chunk-a44d5zgd.js → chunk-y35ma3mj.js} +11 -16
  151. package/dist/{chunk-a44d5zgd.js.map → chunk-y35ma3mj.js.map} +3 -4
  152. package/dist/{chunk-qewtks41.js → chunk-z2sery1b.js} +64 -1
  153. package/dist/{chunk-qewtks41.js.map → chunk-z2sery1b.js.map} +3 -3
  154. package/dist/error-reporting/internal.js +4 -4
  155. package/dist/error-reporting/types.d.ts +7 -2
  156. package/dist/error-reporting/types.d.ts.map +1 -1
  157. package/dist/errors/catalog.d.ts +8 -0
  158. package/dist/errors/catalog.d.ts.map +1 -1
  159. package/dist/errors/internal.js +2 -2
  160. package/dist/events/index.js +4 -4
  161. package/dist/execution/agent.d.ts +18 -9
  162. package/dist/execution/agent.d.ts.map +1 -1
  163. package/dist/execution/agent.js +52 -43
  164. package/dist/execution/agent.js.map +1 -1
  165. package/dist/execution/authorization.d.ts +14 -4
  166. package/dist/execution/authorization.d.ts.map +1 -1
  167. package/dist/execution/primitive.js +45 -43
  168. package/dist/execution/primitive.js.map +2 -2
  169. package/dist/execution/request.d.ts +3 -1
  170. package/dist/execution/request.d.ts.map +1 -1
  171. package/dist/execution/request.js +46 -44
  172. package/dist/execution/request.js.map +3 -3
  173. package/dist/execution/types.d.ts +1 -1
  174. package/dist/execution/types.d.ts.map +1 -1
  175. package/dist/http/api-routes.d.ts.map +1 -1
  176. package/dist/http/index.js +1 -1
  177. package/dist/index.d.ts +9 -6
  178. package/dist/index.d.ts.map +1 -1
  179. package/dist/index.js +82 -77
  180. package/dist/index.js.map +1 -1
  181. package/dist/json.d.ts +2 -0
  182. package/dist/json.d.ts.map +1 -1
  183. package/dist/lake-storage/index.js +5 -5
  184. package/dist/logging/index.js +3 -3
  185. package/dist/logging/types.js +2 -2
  186. package/dist/materialization/index.js +2 -2
  187. package/dist/materializer/index.js +33 -29
  188. package/dist/materializer/index.js.map +1 -1
  189. package/dist/models/catalog.d.ts +40 -0
  190. package/dist/models/catalog.d.ts.map +1 -0
  191. package/dist/models/definitions.d.ts +25 -0
  192. package/dist/models/definitions.d.ts.map +1 -0
  193. package/dist/models/errors.d.ts +52 -0
  194. package/dist/models/errors.d.ts.map +1 -0
  195. package/dist/models/events.d.ts +192 -0
  196. package/dist/models/events.d.ts.map +1 -0
  197. package/dist/models/index.d.ts +17 -39
  198. package/dist/models/index.d.ts.map +1 -1
  199. package/dist/models/index.js +50 -0
  200. package/dist/models/index.js.map +9 -0
  201. package/dist/models/language-model.d.ts +90 -0
  202. package/dist/models/language-model.d.ts.map +1 -0
  203. package/dist/models/messages.d.ts +74 -0
  204. package/dist/models/messages.d.ts.map +1 -0
  205. package/dist/models/pricing.d.ts +69 -0
  206. package/dist/models/pricing.d.ts.map +1 -0
  207. package/dist/models/rate-card.d.ts +24 -0
  208. package/dist/models/rate-card.d.ts.map +1 -0
  209. package/dist/models/tools.d.ts +24 -0
  210. package/dist/models/tools.d.ts.map +1 -0
  211. package/dist/objects/index.js +38 -34
  212. package/dist/objects/index.js.map +1 -1
  213. package/dist/objects/query/index.js +32 -28
  214. package/dist/objects/query/index.js.map +1 -1
  215. package/dist/ontology/index.js +5 -5
  216. package/dist/ontology/internal.js +4 -4
  217. package/dist/pipelines/index.js +37 -35
  218. package/dist/pipelines/index.js.map +1 -1
  219. package/dist/projections/internal.js +35 -31
  220. package/dist/projections/internal.js.map +1 -1
  221. package/dist/queues/in-memory.d.ts +3 -2
  222. package/dist/queues/in-memory.d.ts.map +1 -1
  223. package/dist/queues/index.d.ts +3 -1
  224. package/dist/queues/index.d.ts.map +1 -1
  225. package/dist/queues/index.js +1 -1
  226. package/dist/queues/types.d.ts +15 -3
  227. package/dist/queues/types.d.ts.map +1 -1
  228. package/dist/runtime/create.d.ts +4 -4
  229. package/dist/runtime/create.d.ts.map +1 -1
  230. package/dist/runtime/definitions.d.ts +2 -2
  231. package/dist/runtime/definitions.d.ts.map +1 -1
  232. package/dist/runtime/host.d.ts +3 -2
  233. package/dist/runtime/host.d.ts.map +1 -1
  234. package/dist/runtime/resolve-definitions.d.ts +2 -2
  235. package/dist/runtime/resolve-definitions.d.ts.map +1 -1
  236. package/dist/runtime/sixb.d.ts +4 -2
  237. package/dist/runtime/sixb.d.ts.map +1 -1
  238. package/dist/security/every.d.ts +1 -4
  239. package/dist/security/every.d.ts.map +1 -1
  240. package/dist/security/grants.d.ts +6 -5
  241. package/dist/security/grants.d.ts.map +1 -1
  242. package/dist/security/index.d.ts +1 -1
  243. package/dist/security/index.d.ts.map +1 -1
  244. package/dist/security/registry.d.ts +1 -1
  245. package/dist/security/registry.d.ts.map +1 -1
  246. package/dist/security/types.d.ts +13 -5
  247. package/dist/security/types.d.ts.map +1 -1
  248. package/dist/security/validation.d.ts +4 -2
  249. package/dist/security/validation.d.ts.map +1 -1
  250. package/dist/storage/action-runs/failure.js +3 -3
  251. package/dist/storage/action-runs/provider.js +2 -2
  252. package/dist/storage/agents/errors.d.ts +1 -1
  253. package/dist/storage/agents/errors.d.ts.map +1 -1
  254. package/dist/storage/agents/in-memory.d.ts +3 -2
  255. package/dist/storage/agents/in-memory.d.ts.map +1 -1
  256. package/dist/storage/agents/index.d.ts +1 -1
  257. package/dist/storage/agents/index.d.ts.map +1 -1
  258. package/dist/storage/agents/provider.d.ts +11 -4
  259. package/dist/storage/agents/provider.d.ts.map +1 -1
  260. package/dist/storage/agents/provider.js +18 -15
  261. package/dist/storage/agents/provider.js.map +1 -1
  262. package/dist/storage/agents/types.d.ts +65 -17
  263. package/dist/storage/agents/types.d.ts.map +1 -1
  264. package/dist/storage/ai-cost/analytics.d.ts +2 -1
  265. package/dist/storage/ai-cost/analytics.d.ts.map +1 -1
  266. package/dist/storage/ai-cost/codec.d.ts +3 -2
  267. package/dist/storage/ai-cost/codec.d.ts.map +1 -1
  268. package/dist/storage/ai-cost/groups.d.ts +51 -0
  269. package/dist/storage/ai-cost/groups.d.ts.map +1 -0
  270. package/dist/storage/ai-cost/in-memory.d.ts +11 -1
  271. package/dist/storage/ai-cost/in-memory.d.ts.map +1 -1
  272. package/dist/storage/ai-cost/index.d.ts +1 -1
  273. package/dist/storage/ai-cost/index.d.ts.map +1 -1
  274. package/dist/storage/ai-cost/provider.d.ts +2 -0
  275. package/dist/storage/ai-cost/provider.d.ts.map +1 -1
  276. package/dist/storage/ai-cost/provider.js +29 -13
  277. package/dist/storage/ai-cost/provider.js.map +3 -3
  278. package/dist/storage/ai-cost/types.d.ts +64 -15
  279. package/dist/storage/ai-cost/types.d.ts.map +1 -1
  280. package/dist/storage/ai-cost/validation.d.ts +2 -1
  281. package/dist/storage/ai-cost/validation.d.ts.map +1 -1
  282. package/dist/storage/ai-limits/enforcement.d.ts +14 -0
  283. package/dist/storage/ai-limits/enforcement.d.ts.map +1 -0
  284. package/dist/storage/ai-limits/enforcement.js +21 -0
  285. package/dist/storage/ai-limits/enforcement.js.map +9 -0
  286. package/dist/storage/ai-limits/errors.d.ts +8 -0
  287. package/dist/storage/ai-limits/errors.d.ts.map +1 -0
  288. package/dist/storage/ai-limits/in-memory.d.ts +78 -0
  289. package/dist/storage/ai-limits/in-memory.d.ts.map +1 -0
  290. package/dist/storage/ai-limits/index.d.ts +7 -0
  291. package/dist/storage/ai-limits/index.d.ts.map +1 -0
  292. package/dist/storage/ai-limits/period.d.ts +4 -0
  293. package/dist/storage/ai-limits/period.d.ts.map +1 -0
  294. package/dist/storage/ai-limits/provider.d.ts +85 -0
  295. package/dist/storage/ai-limits/provider.d.ts.map +1 -0
  296. package/dist/storage/ai-limits/provider.js +62 -0
  297. package/dist/storage/ai-limits/provider.js.map +9 -0
  298. package/dist/storage/ai-limits/types.d.ts +175 -0
  299. package/dist/storage/ai-limits/types.d.ts.map +1 -0
  300. package/dist/storage/ai-usage/in-memory.d.ts +4 -0
  301. package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
  302. package/dist/storage/ai-usage/record.d.ts.map +1 -1
  303. package/dist/storage/ai-usage/types.d.ts +6 -2
  304. package/dist/storage/ai-usage/types.d.ts.map +1 -1
  305. package/dist/storage/auth/errors.d.ts +1 -1
  306. package/dist/storage/auth/errors.d.ts.map +1 -1
  307. package/dist/storage/auth/in-memory/auth-storage.d.ts +4 -1
  308. package/dist/storage/auth/in-memory/auth-storage.d.ts.map +1 -1
  309. package/dist/storage/auth/in-memory/device-authorizations.d.ts +29 -0
  310. package/dist/storage/auth/in-memory/device-authorizations.d.ts.map +1 -0
  311. package/dist/storage/auth/in-memory/shared.d.ts +3 -1
  312. package/dist/storage/auth/in-memory/shared.d.ts.map +1 -1
  313. package/dist/storage/auth/index.d.ts +2 -1
  314. package/dist/storage/auth/index.d.ts.map +1 -1
  315. package/dist/storage/auth/types.d.ts +66 -0
  316. package/dist/storage/auth/types.d.ts.map +1 -1
  317. package/dist/storage/connector-connections/provider.js +2 -2
  318. package/dist/storage/executions/provider.js +1 -1
  319. package/dist/storage/executions/run-link.d.ts +7 -2
  320. package/dist/storage/executions/run-link.d.ts.map +1 -1
  321. package/dist/storage/executions/validation.d.ts.map +1 -1
  322. package/dist/storage/in-memory/index.d.ts +4 -0
  323. package/dist/storage/in-memory/index.d.ts.map +1 -1
  324. package/dist/storage/index.d.ts +7 -4
  325. package/dist/storage/index.d.ts.map +1 -1
  326. package/dist/storage/index.js +51 -38
  327. package/dist/storage/index.js.map +1 -1
  328. package/dist/storage/ontology/provider.js +3 -3
  329. package/dist/storage/pipeline-runs/provider.js +2 -2
  330. package/dist/storage/projection-runs/provider.js +4 -4
  331. package/dist/storage/sync-runs/provider.js +2 -2
  332. package/dist/storage/types.d.ts +5 -1
  333. package/dist/storage/types.d.ts.map +1 -1
  334. package/dist/storage/webhook-runs/provider.js +2 -2
  335. package/dist/storage/workflow-runs/provider.d.ts +1 -1
  336. package/dist/storage/workflow-runs/provider.js +10 -11
  337. package/dist/storage/workflow-runs/provider.js.map +1 -1
  338. package/dist/storage/workflow-runs/types.d.ts +5 -4
  339. package/dist/storage/workflow-runs/types.d.ts.map +1 -1
  340. package/dist/syncs/index.js +37 -35
  341. package/dist/syncs/index.js.map +1 -1
  342. package/dist/testing/agent-execution.d.ts +3 -1
  343. package/dist/testing/agent-execution.d.ts.map +1 -1
  344. package/dist/testing/agent-storage-contract.d.ts.map +1 -1
  345. package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -1
  346. package/dist/testing/ai-limit-storage-contract.d.ts +18 -0
  347. package/dist/testing/ai-limit-storage-contract.d.ts.map +1 -0
  348. package/dist/testing/ai-model-call-groups-contract.d.ts +6 -0
  349. package/dist/testing/ai-model-call-groups-contract.d.ts.map +1 -0
  350. package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
  351. package/dist/testing/auth-storage-contract.d.ts.map +1 -1
  352. package/dist/testing/index.d.ts +2 -0
  353. package/dist/testing/index.d.ts.map +1 -1
  354. package/dist/testing/index.js +3637 -1962
  355. package/dist/testing/index.js.map +14 -12
  356. package/dist/testing/queues-contract.d.ts.map +1 -1
  357. package/dist/webhooks/internal.js +32 -28
  358. package/dist/webhooks/internal.js.map +2 -2
  359. package/dist/workers/index.js +2 -2
  360. package/dist/workflows/agent-step-identity.d.ts +3 -0
  361. package/dist/workflows/agent-step-identity.d.ts.map +1 -0
  362. package/dist/workflows/builders.d.ts +2 -3
  363. package/dist/workflows/builders.d.ts.map +1 -1
  364. package/dist/workflows/execution.d.ts +1 -1
  365. package/dist/workflows/execution.d.ts.map +1 -1
  366. package/dist/workflows/failure.d.ts +1 -1
  367. package/dist/workflows/failure.d.ts.map +1 -1
  368. package/dist/workflows/index.d.ts +3 -2
  369. package/dist/workflows/index.d.ts.map +1 -1
  370. package/dist/workflows/index.js +53 -45
  371. package/dist/workflows/index.js.map +1 -1
  372. package/dist/workflows/types.d.ts +26 -11
  373. package/dist/workflows/types.d.ts.map +1 -1
  374. package/dist/workflows/validation.d.ts +7 -1
  375. package/dist/workflows/validation.d.ts.map +1 -1
  376. package/package.json +19 -4
  377. package/src/agents/adapters.ts +109 -115
  378. package/src/agents/authority.ts +214 -32
  379. package/src/agents/builders.ts +3 -50
  380. package/src/agents/context-compaction.ts +4 -0
  381. package/src/agents/dispatch.ts +59 -2
  382. package/src/agents/errors.ts +5 -2
  383. package/src/agents/execution.ts +53 -52
  384. package/src/agents/ids.ts +16 -1
  385. package/src/agents/index.ts +23 -11
  386. package/src/agents/message.ts +18 -9
  387. package/src/agents/model-loop.ts +1023 -0
  388. package/src/agents/reference.ts +7 -0
  389. package/src/agents/request.ts +141 -74
  390. package/src/agents/retired-config.ts +20 -0
  391. package/src/agents/streams.ts +45 -19
  392. package/src/agents/tool-catalog.ts +21 -0
  393. package/src/agents/tool-definition.ts +23 -0
  394. package/src/agents/types.ts +39 -81
  395. package/src/agents/validation.ts +34 -180
  396. package/src/ai-usage/execution.ts +196 -0
  397. package/src/ai-usage/index.ts +15 -0
  398. package/src/authorization/decision.ts +27 -10
  399. package/src/authorization/grant-kinds.ts +62 -15
  400. package/src/authorization/index.ts +1 -0
  401. package/src/authorization/resolve.ts +12 -5
  402. package/src/authorization/types.ts +7 -5
  403. package/src/bootstrap/discovery.ts +0 -3
  404. package/src/error-reporting/types.ts +4 -2
  405. package/src/errors/catalog.ts +8 -0
  406. package/src/execution/agent.ts +129 -22
  407. package/src/execution/authorization.ts +48 -18
  408. package/src/execution/request.ts +4 -1
  409. package/src/execution/types.ts +1 -1
  410. package/src/http/api-routes.ts +63 -0
  411. package/src/index.ts +36 -7
  412. package/src/json.ts +9 -0
  413. package/src/models/catalog.ts +137 -0
  414. package/src/models/definitions.ts +202 -0
  415. package/src/models/errors.ts +83 -0
  416. package/src/models/events.ts +198 -0
  417. package/src/models/index.ts +89 -71
  418. package/src/models/language-model.ts +143 -0
  419. package/src/models/messages.ts +78 -0
  420. package/src/models/pricing.ts +390 -0
  421. package/src/models/rate-card.ts +101 -0
  422. package/src/models/tools.ts +29 -0
  423. package/src/queues/in-memory.ts +5 -0
  424. package/src/queues/index.ts +11 -0
  425. package/src/queues/types.ts +20 -3
  426. package/src/runtime/create.ts +7 -5
  427. package/src/runtime/definitions.ts +2 -2
  428. package/src/runtime/host.ts +3 -2
  429. package/src/runtime/resolve-definitions.ts +13 -36
  430. package/src/runtime/sixb.ts +6 -8
  431. package/src/security/every.ts +0 -4
  432. package/src/security/grants.ts +55 -11
  433. package/src/security/index.ts +2 -0
  434. package/src/security/registry.ts +6 -5
  435. package/src/security/types.ts +15 -4
  436. package/src/security/validation.ts +30 -9
  437. package/src/storage/agents/errors.ts +1 -0
  438. package/src/storage/agents/in-memory.ts +121 -11
  439. package/src/storage/agents/index.ts +7 -0
  440. package/src/storage/agents/provider.ts +150 -6
  441. package/src/storage/agents/types.ts +73 -16
  442. package/src/storage/ai-cost/analytics.ts +63 -6
  443. package/src/storage/ai-cost/codec.ts +37 -12
  444. package/src/storage/ai-cost/groups.ts +248 -0
  445. package/src/storage/ai-cost/in-memory.ts +42 -0
  446. package/src/storage/ai-cost/index.ts +6 -0
  447. package/src/storage/ai-cost/provider.ts +7 -0
  448. package/src/storage/ai-cost/types.ts +76 -14
  449. package/src/storage/ai-cost/validation.ts +147 -17
  450. package/src/storage/ai-limits/enforcement.ts +68 -0
  451. package/src/storage/ai-limits/errors.ts +23 -0
  452. package/src/storage/ai-limits/in-memory.ts +671 -0
  453. package/src/storage/ai-limits/index.ts +31 -0
  454. package/src/storage/ai-limits/period.ts +11 -0
  455. package/src/storage/ai-limits/provider.ts +430 -0
  456. package/src/storage/ai-limits/types.ts +195 -0
  457. package/src/storage/ai-usage/in-memory.ts +13 -0
  458. package/src/storage/ai-usage/record.ts +17 -0
  459. package/src/storage/ai-usage/types.ts +6 -2
  460. package/src/storage/auth/errors.ts +6 -0
  461. package/src/storage/auth/in-memory/auth-storage.ts +69 -0
  462. package/src/storage/auth/in-memory/device-authorizations.ts +145 -0
  463. package/src/storage/auth/in-memory/shared.ts +7 -0
  464. package/src/storage/auth/index.ts +7 -0
  465. package/src/storage/auth/types.ts +73 -0
  466. package/src/storage/executions/run-link.ts +16 -6
  467. package/src/storage/executions/validation.ts +36 -6
  468. package/src/storage/in-memory/index.ts +48 -4
  469. package/src/storage/index.ts +51 -1
  470. package/src/storage/types.ts +37 -0
  471. package/src/storage/workflow-runs/in-memory.ts +3 -3
  472. package/src/storage/workflow-runs/provider.ts +2 -2
  473. package/src/storage/workflow-runs/types.ts +6 -3
  474. package/src/testing/agent-execution.ts +40 -28
  475. package/src/testing/agent-storage-contract.ts +249 -28
  476. package/src/testing/ai-cost-storage-contract.ts +96 -8
  477. package/src/testing/ai-limit-storage-contract.ts +1134 -0
  478. package/src/testing/ai-model-call-groups-contract.ts +353 -0
  479. package/src/testing/ai-usage-storage-contract.ts +31 -0
  480. package/src/testing/auth-storage-contract.ts +85 -0
  481. package/src/testing/execution-storage-contract.ts +2 -2
  482. package/src/testing/index.ts +10 -0
  483. package/src/testing/queues-contract.ts +36 -1
  484. package/src/workflows/agent-step-identity.ts +4 -0
  485. package/src/workflows/builders.ts +95 -9
  486. package/src/workflows/execution.ts +2 -2
  487. package/src/workflows/failure.ts +2 -2
  488. package/src/workflows/index.ts +3 -0
  489. package/src/workflows/types.ts +23 -11
  490. package/src/workflows/validation.ts +100 -7
  491. package/dist/chunk-1e8m6yn3.js.map +0 -37
  492. package/dist/chunk-1g8negke.js.map +0 -11
  493. package/dist/chunk-6gjqgd3d.js.map +0 -11
  494. package/dist/chunk-dm72y8wt.js.map +0 -10
  495. package/dist/chunk-drjqm1aa.js.map +0 -15
  496. package/dist/chunk-fe5ev6mr.js +0 -55
  497. package/dist/chunk-fe5ev6mr.js.map +0 -11
  498. package/dist/chunk-h9kxd41f.js.map +0 -11
  499. package/dist/chunk-hceck7dq.js +0 -137
  500. package/dist/chunk-hceck7dq.js.map +0 -10
  501. package/dist/chunk-n4spznws.js.map +0 -11
  502. package/dist/chunk-nva1xkjz.js.map +0 -46
  503. package/dist/chunk-t0jjkep3.js.map +0 -10
  504. package/dist/chunk-t8t39h7v.js.map +0 -10
  505. /package/dist/{chunk-zqysyfjt.js.map → chunk-08m3b6w8.js.map} +0 -0
  506. /package/dist/{chunk-xkthy56g.js.map → chunk-1kamz6j0.js.map} +0 -0
  507. /package/dist/{chunk-md8k0r54.js.map → chunk-3fqt22c4.js.map} +0 -0
  508. /package/dist/{chunk-z3zp0bj1.js.map → chunk-407j3msh.js.map} +0 -0
  509. /package/dist/{chunk-rhrbz7d4.js.map → chunk-4a849fr1.js.map} +0 -0
  510. /package/dist/{chunk-62c7t4jc.js.map → chunk-4nxeacx7.js.map} +0 -0
  511. /package/dist/{chunk-cy0n5dms.js.map → chunk-5jcdmjam.js.map} +0 -0
  512. /package/dist/{chunk-819wnjz8.js.map → chunk-64sr682n.js.map} +0 -0
  513. /package/dist/{chunk-x2yw73hy.js.map → chunk-7ds9620f.js.map} +0 -0
  514. /package/dist/{chunk-72q2y8hn.js.map → chunk-8tsf6dmc.js.map} +0 -0
  515. /package/dist/{chunk-nkbfrt0c.js.map → chunk-9aehf39w.js.map} +0 -0
  516. /package/dist/{chunk-ezake7g1.js.map → chunk-agsvg9ar.js.map} +0 -0
  517. /package/dist/{chunk-rnshztfq.js.map → chunk-d63tybny.js.map} +0 -0
  518. /package/dist/{chunk-vybf6pkp.js.map → chunk-dbc80ad7.js.map} +0 -0
  519. /package/dist/{chunk-4gz41why.js.map → chunk-dqn23610.js.map} +0 -0
  520. /package/dist/{chunk-tg5mee00.js.map → chunk-ha58tjtt.js.map} +0 -0
  521. /package/dist/{chunk-f6erf2vv.js.map → chunk-hdz94br2.js.map} +0 -0
  522. /package/dist/{chunk-dsrkgtnh.js.map → chunk-jq43kdvk.js.map} +0 -0
  523. /package/dist/{chunk-wtmzkcht.js.map → chunk-k34z5rvh.js.map} +0 -0
  524. /package/dist/{chunk-htq0qh7z.js.map → chunk-ka3a2ft3.js.map} +0 -0
  525. /package/dist/{chunk-znagycq7.js.map → chunk-kt81c11h.js.map} +0 -0
  526. /package/dist/{chunk-f2rt4vkh.js.map → chunk-n2w475r0.js.map} +0 -0
  527. /package/dist/{chunk-bhxaq2nn.js.map → chunk-qw9gvjv5.js.map} +0 -0
  528. /package/dist/{chunk-8gv5z0zm.js.map → chunk-rp1mvzb4.js.map} +0 -0
  529. /package/dist/{chunk-ghteq96b.js.map → chunk-s5y30bc9.js.map} +0 -0
  530. /package/dist/{chunk-a31h57d5.js.map → chunk-tn7xcs2n.js.map} +0 -0
  531. /package/dist/{chunk-e42bc6m3.js.map → chunk-vjjv9mrb.js.map} +0 -0
  532. /package/dist/{chunk-8b55ygje.js.map → chunk-w3e09qqk.js.map} +0 -0
  533. /package/dist/{chunk-ckxfnx7f.js.map → chunk-wjgm6jjt.js.map} +0 -0
  534. /package/dist/{chunk-3j7573mj.js.map → chunk-x0qhkqje.js.map} +0 -0
  535. /package/dist/{chunk-dysw7nsm.js.map → chunk-xdpwpkha.js.map} +0 -0
@@ -0,0 +1,1023 @@
1
+ import { randomUUID } from "node:crypto"
2
+ import { assertJsonObject, assertJsonValue, isJsonValue, type JsonValue } from "../json"
3
+ import { ModelProviderError, ModelStreamError, StructuredOutputError } from "../models/errors"
4
+ import type {
5
+ LanguageModelStreamEvent,
6
+ ModelCallEndEvent,
7
+ ModelFinishReason,
8
+ ModelStep,
9
+ ModelUiChunk,
10
+ ModelUsage,
11
+ } from "../models/events"
12
+ import type {
13
+ LanguageModel,
14
+ ModelReasoning,
15
+ ModelToolSpecification,
16
+ } from "../models/language-model"
17
+ import type {
18
+ ModelAssistantPart,
19
+ ModelMessage,
20
+ ModelProviderStatePart,
21
+ ModelTextPart,
22
+ ModelToolCallPart,
23
+ ModelToolOutput,
24
+ ModelToolResultPart,
25
+ ProviderData,
26
+ } from "../models/messages"
27
+ import {
28
+ estimateModelCall,
29
+ type ModelCallCost,
30
+ type ModelReportedCost,
31
+ rateModelCall,
32
+ } from "../models/pricing"
33
+ import type { ModelOutput, ModelTool } from "../models/tools"
34
+
35
+ const MAX_PROVIDER_DATA_BYTES = 256 * 1024
36
+
37
+ interface ModelLoopOptions {
38
+ readonly model: LanguageModel
39
+ readonly messages: readonly ModelMessage[]
40
+ readonly tools?: readonly ModelTool[]
41
+ readonly reasoning?: ModelReasoning
42
+ readonly maxOutputTokens?: number
43
+ readonly caching?: "auto" | "off"
44
+ readonly maxSteps: number
45
+ readonly signal: AbortSignal
46
+ /** Reserve the final provider call for a tool-free synthesis response. */
47
+ readonly finalStepInstruction?: string
48
+ readonly prepareStep?: (
49
+ input: PrepareModelStepInput
50
+ ) => PrepareModelStepResult | undefined | Promise<PrepareModelStepResult | undefined>
51
+ readonly onEvent?: (event: ModelUiChunk) => void | Promise<void>
52
+ readonly onModelCallEnd?: (event: ModelCallEndEvent) => void | Promise<void>
53
+ readonly onStepEnd?: (step: ModelStep) => void | Promise<void>
54
+ readonly generateCallId?: () => string
55
+ }
56
+
57
+ /** Non-text output requires a validator; unvalidated text can only inhabit types accepting string. */
58
+ export type RunModelLoopInput<TOutput = string> = ModelLoopOptions &
59
+ (
60
+ | { readonly output: ModelOutput<TOutput> }
61
+ | (string extends TOutput ? { readonly output?: undefined } : never)
62
+ )
63
+
64
+ export interface PrepareModelStepInput {
65
+ readonly stepIndex: number
66
+ readonly messages: readonly ModelMessage[]
67
+ readonly model: LanguageModel
68
+ readonly signal: AbortSignal
69
+ }
70
+
71
+ export interface PrepareModelStepResult {
72
+ /** Replacement history retained for this request and subsequent steps. */
73
+ readonly messages?: readonly ModelMessage[]
74
+ }
75
+
76
+ export type ModelLoopResult<TOutput = string> =
77
+ | {
78
+ readonly status: "completed"
79
+ readonly output: TOutput
80
+ readonly steps: readonly ModelStep[]
81
+ readonly finishReason: ModelFinishReason
82
+ }
83
+ | {
84
+ readonly status: "aborted"
85
+ readonly steps: readonly ModelStep[]
86
+ readonly partialContent: readonly ModelAssistantPart[]
87
+ }
88
+
89
+ interface CompletedResponse {
90
+ readonly providerIds?: import("../models/events").ModelProviderIds
91
+ readonly content: readonly ModelAssistantPart[]
92
+ readonly toolCalls: readonly ParsedToolCall[]
93
+ readonly finishReason: ModelFinishReason
94
+ readonly rawFinishReason?: string
95
+ readonly usage: ModelUsage
96
+ readonly responseId?: string
97
+ readonly responseModelId?: string
98
+ readonly projectionError?: Error
99
+ readonly reportedCost?: ModelReportedCost
100
+ readonly route?: import("../models/events").ModelRoute
101
+ }
102
+
103
+ interface ParsedToolCall {
104
+ readonly part: ModelToolCallPart
105
+ readonly inputError?: Error
106
+ }
107
+
108
+ /**
109
+ * Run a provider-neutral, streaming model/tool loop.
110
+ *
111
+ * One step is exactly one provider call. Lifecycle and stream callbacks are awaited so the caller
112
+ * controls backpressure and can fail closed before another billable call starts.
113
+ */
114
+ export function runModelLoop<TOutput = string>(
115
+ input: RunModelLoopInput<TOutput>
116
+ ): Promise<ModelLoopResult<TOutput>>
117
+ export async function runModelLoop(
118
+ input: RunModelLoopInput<unknown>
119
+ ): Promise<ModelLoopResult<unknown>> {
120
+ assertLoopInput(input)
121
+ const tools = indexTools(input.tools ?? [])
122
+ const toolSpecifications = [...tools.values()].map<ModelToolSpecification>((tool) => ({
123
+ name: tool.name,
124
+ description: tool.description,
125
+ inputSchema: tool.inputSchema,
126
+ }))
127
+ let messages: readonly ModelMessage[] = [...input.messages]
128
+ const steps: ModelStep[] = []
129
+ const generateCallId = input.generateCallId ?? (() => `model_call_${randomUUID()}`)
130
+ const callIds = new Set<string>()
131
+
132
+ for (let stepIndex = 0; stepIndex < input.maxSteps; stepIndex += 1) {
133
+ if (input.signal.aborted) {
134
+ return { status: "aborted", steps, partialContent: [] }
135
+ }
136
+ await input.onEvent?.({ type: "start-step" })
137
+
138
+ let requestMessages: readonly ModelMessage[]
139
+ try {
140
+ const prepared = await input.prepareStep?.({
141
+ stepIndex,
142
+ messages,
143
+ model: input.model,
144
+ signal: input.signal,
145
+ })
146
+ requestMessages = prepared?.messages ?? messages
147
+ } catch (error) {
148
+ if (!input.signal.aborted && !isAbortError(error)) throw error
149
+ return { status: "aborted", steps, partialContent: [] }
150
+ }
151
+ if (input.signal.aborted) {
152
+ return { status: "aborted", steps, partialContent: [] }
153
+ }
154
+ let requestTools: readonly ModelToolSpecification[] = toolSpecifications
155
+ if (input.finalStepInstruction !== undefined && stepIndex === input.maxSteps - 1) {
156
+ requestMessages = [
157
+ ...requestMessages,
158
+ { role: "user", content: [{ type: "text", text: input.finalStepInstruction }] },
159
+ ]
160
+ requestTools = []
161
+ }
162
+
163
+ const callId = generateCallId()
164
+ if (!callId || callIds.has(callId)) {
165
+ throw new ModelStreamError(`[SixbModels] Model call IDs must be nonempty and unique.`)
166
+ }
167
+ callIds.add(callId)
168
+ const accumulator = new StreamAccumulator(input.onEvent)
169
+ let accepted = false
170
+ let cost: ModelCallCost = { status: "unpriceable", reason: "missing-usage" }
171
+ let terminalStreamError: { readonly error: unknown } | undefined
172
+ try {
173
+ const stream = await input.model.stream({
174
+ callId,
175
+ messages: requestMessages,
176
+ tools: requestTools,
177
+ ...(input.reasoning === undefined ? {} : { reasoning: input.reasoning }),
178
+ ...(input.maxOutputTokens === undefined ? {} : { maxOutputTokens: input.maxOutputTokens }),
179
+ ...(input.caching === undefined ? {} : { caching: input.caching }),
180
+ ...(input.output === undefined
181
+ ? {}
182
+ : {
183
+ responseFormat: {
184
+ type: "json" as const,
185
+ name: input.output.name,
186
+ ...(input.output.description === undefined
187
+ ? {}
188
+ : { description: input.output.description }),
189
+ schema: input.output.schema,
190
+ },
191
+ }),
192
+ signal: input.signal,
193
+ })
194
+ accepted = true
195
+ for await (const event of stream.events) {
196
+ await accumulator.accept(event)
197
+ }
198
+ } catch (error) {
199
+ const aborted = input.signal.aborted || isAbortError(error)
200
+ if (accumulator.isFinished()) {
201
+ if (!aborted) terminalStreamError = { error }
202
+ } else if (!aborted) {
203
+ throw error
204
+ } else {
205
+ return {
206
+ status: "aborted",
207
+ steps,
208
+ partialContent: accumulator.partialContent(),
209
+ }
210
+ }
211
+ } finally {
212
+ // Once a stream is accepted, cancellation or protocol failure cannot erase the call.
213
+ // Only a finish event establishes final meters; interrupted calls remain explicitly unknown.
214
+ if (accepted) {
215
+ const facts = accumulator.accounting()
216
+ const estimate = accumulator.isFinished() ? estimateModelCall(input.model, facts) : cost
217
+ cost = facts.reportedCost
218
+ ? rateModelCall({ usage: facts.usage, reported: facts.reportedCost })
219
+ : estimate
220
+ await input.onModelCallEnd?.({
221
+ callId,
222
+ providerId: input.model.providerId,
223
+ modelId: input.model.modelId,
224
+ responseId: facts.responseId ?? `${callId}:response`,
225
+ providerIds: facts.providerIds,
226
+ responseModelId: facts.responseModelId,
227
+ usage: facts.usage,
228
+ cost,
229
+ ...(facts.reportedCost === undefined ? {} : { estimate }),
230
+ ...(input.reasoning === undefined ? {} : { requestedReasoning: input.reasoning }),
231
+ ...(facts.route === undefined ? {} : { route: facts.route }),
232
+ })
233
+ }
234
+ }
235
+
236
+ if (input.signal.aborted && !accumulator.isFinished()) {
237
+ return { status: "aborted", steps, partialContent: accumulator.partialContent() }
238
+ }
239
+ const response = accumulator.complete()
240
+ const responseId = response.responseId ?? `${callId}:response`
241
+ if (terminalStreamError) throw terminalStreamError.error
242
+ if (response.projectionError) throw response.projectionError
243
+ if (input.signal.aborted) {
244
+ return { status: "aborted", steps, partialContent: response.content }
245
+ }
246
+
247
+ const localCalls = response.toolCalls.filter((call) => call.part.providerExecuted !== true)
248
+ if (response.finishReason === "pause" && localCalls.length === 0) {
249
+ const step = modelStep(response, responseId, response.content, cost)
250
+ steps.push(step)
251
+ await input.onStepEnd?.(step)
252
+ messages = [...requestMessages, { role: "assistant", content: response.content }]
253
+ if (stepIndex + 1 === input.maxSteps) {
254
+ throw new ModelStreamError(
255
+ "[SixbModels] Model reached the step limit while a provider continuation was pending."
256
+ )
257
+ }
258
+ continue
259
+ }
260
+ if (localCalls.length === 0) {
261
+ const step = modelStep(response, responseId, response.content, cost)
262
+ steps.push(step)
263
+ await input.onStepEnd?.(step)
264
+ if (input.output) {
265
+ const text = responseText(response)
266
+ if (response.finishReason !== "stop") {
267
+ throw new StructuredOutputError(
268
+ `[SixbModels] Structured output did not complete successfully (${response.finishReason}).`,
269
+ structuredOutputErrorContext(input, response, responseId, cost, text)
270
+ )
271
+ }
272
+ let raw: unknown
273
+ try {
274
+ raw = JSON.parse(text)
275
+ } catch (error) {
276
+ throw new StructuredOutputError("[SixbModels] Model did not produce valid JSON output.", {
277
+ cause: error,
278
+ ...structuredOutputErrorContext(input, response, responseId, cost, text),
279
+ })
280
+ }
281
+ try {
282
+ return {
283
+ status: "completed",
284
+ output: input.output.validate(raw),
285
+ steps,
286
+ finishReason: response.finishReason,
287
+ }
288
+ } catch (error) {
289
+ throw new StructuredOutputError("[SixbModels] Structured output validation failed.", {
290
+ cause: error,
291
+ ...structuredOutputErrorContext(input, response, responseId, cost, text),
292
+ })
293
+ }
294
+ }
295
+ const output = responseText(response)
296
+ return { status: "completed", output, steps, finishReason: response.finishReason }
297
+ }
298
+
299
+ const toolResults = await Promise.all(
300
+ localCalls.map((call) => executeToolCall(call, tools, callId, input.signal, input.onEvent))
301
+ )
302
+ const step = modelStep(response, responseId, [...response.content, ...toolResults], cost)
303
+ steps.push(step)
304
+ await input.onStepEnd?.(step)
305
+
306
+ if (input.signal.aborted) {
307
+ return {
308
+ status: "aborted",
309
+ steps,
310
+ partialContent: [],
311
+ }
312
+ }
313
+
314
+ const assistantContent = response.content.filter(
315
+ (part) => part.type !== "tool-result" || part.providerExecuted === true
316
+ )
317
+ messages = [
318
+ ...requestMessages,
319
+ { role: "assistant", content: assistantContent },
320
+ { role: "tool", content: toolResults },
321
+ ]
322
+
323
+ if (stepIndex + 1 === input.maxSteps) {
324
+ if (input.output) {
325
+ throw new StructuredOutputError(
326
+ "[SixbModels] Model reached the step limit without structured output.",
327
+ structuredOutputErrorContext(input, response, responseId, cost, responseText(response))
328
+ )
329
+ }
330
+ const output = responseText(response)
331
+ return { status: "completed", output, steps, finishReason: response.finishReason }
332
+ }
333
+ }
334
+
335
+ throw new ModelStreamError("[SixbModels] Model loop exited without a terminal result.")
336
+ }
337
+
338
+ function assertLoopInput(input: RunModelLoopInput<unknown>): void {
339
+ if (
340
+ input.maxOutputTokens !== undefined &&
341
+ (!Number.isSafeInteger(input.maxOutputTokens) || input.maxOutputTokens <= 0)
342
+ ) {
343
+ throw new TypeError("[SixbModels] maxOutputTokens must be a positive safe integer.")
344
+ }
345
+ if (!Number.isInteger(input.maxSteps) || input.maxSteps <= 0) {
346
+ throw new TypeError("[SixbModels] maxSteps must be a positive integer.")
347
+ }
348
+ if (!input.model.providerId.trim() || !input.model.modelId.trim()) {
349
+ throw new TypeError("[SixbModels] Model providerId and modelId must not be empty.")
350
+ }
351
+ if (
352
+ input.model.definition.providerId !== input.model.providerId ||
353
+ input.model.definition.modelId !== input.model.modelId
354
+ ) {
355
+ throw new TypeError(
356
+ `[SixbModels] Model definition for '${input.model.providerId}/${input.model.modelId}' has a different identity.`
357
+ )
358
+ }
359
+ if (input.output) {
360
+ if (!input.output.name.trim()) {
361
+ throw new TypeError("[SixbModels] Structured output names must not be empty.")
362
+ }
363
+ assertJsonObject(input.output.schema, "structured output schema")
364
+ }
365
+ }
366
+
367
+ function indexTools(tools: readonly ModelTool[]): ReadonlyMap<string, ModelTool> {
368
+ const result = new Map<string, ModelTool>()
369
+ for (const tool of tools) {
370
+ if (!tool.name.trim()) throw new TypeError("[SixbModels] Tool names must not be empty.")
371
+ if (result.has(tool.name)) {
372
+ throw new TypeError(`[SixbModels] Duplicate tool name '${tool.name}'.`)
373
+ }
374
+ assertJsonObject(tool.inputSchema, `tool '${tool.name}' input schema`)
375
+ result.set(tool.name, tool)
376
+ }
377
+ return result
378
+ }
379
+
380
+ function responseText(response: CompletedResponse): string {
381
+ return response.content
382
+ .filter((part): part is ModelTextPart => part.type === "text")
383
+ .map((part) => part.text)
384
+ .join("")
385
+ }
386
+
387
+ function structuredOutputErrorContext(
388
+ input: RunModelLoopInput<unknown>,
389
+ response: CompletedResponse,
390
+ responseId: string,
391
+ cost: ModelCallCost,
392
+ text: string
393
+ ) {
394
+ return {
395
+ text,
396
+ providerId: input.model.providerId,
397
+ modelId: input.model.modelId,
398
+ responseId,
399
+ ...(response.responseModelId === undefined
400
+ ? {}
401
+ : { responseModelId: response.responseModelId }),
402
+ finishReason: response.finishReason,
403
+ usage: response.usage,
404
+ cost,
405
+ }
406
+ }
407
+
408
+ function modelStep(
409
+ response: CompletedResponse,
410
+ responseId: string,
411
+ content: readonly ModelAssistantPart[],
412
+ cost: import("../models/pricing").ModelCallCost
413
+ ): ModelStep {
414
+ return {
415
+ content,
416
+ finishReason: response.finishReason,
417
+ ...(response.rawFinishReason === undefined
418
+ ? {}
419
+ : { rawFinishReason: response.rawFinishReason }),
420
+ usage: response.usage,
421
+ responseId,
422
+ ...(response.responseModelId === undefined
423
+ ? {}
424
+ : { responseModelId: response.responseModelId }),
425
+ cost,
426
+ ...(response.route === undefined ? {} : { route: response.route }),
427
+ }
428
+ }
429
+
430
+ async function executeToolCall(
431
+ call: ParsedToolCall,
432
+ tools: ReadonlyMap<string, ModelTool>,
433
+ callId: string,
434
+ signal: AbortSignal,
435
+ onEvent: RunModelLoopInput["onEvent"]
436
+ ): Promise<ModelToolResultPart> {
437
+ const { part } = call
438
+ if (call.inputError) {
439
+ const errorText = `Tool input is not valid JSON: ${call.inputError.message}`
440
+ await onEvent?.({
441
+ type: "tool-input-error",
442
+ toolCallId: part.toolCallId,
443
+ toolName: part.toolName,
444
+ input: part.input,
445
+ errorText,
446
+ })
447
+ return toolErrorResult(part, errorText)
448
+ }
449
+
450
+ const tool = tools.get(part.toolName)
451
+ if (!tool) {
452
+ const errorText = `Tool '${part.toolName}' is not available.`
453
+ await onEvent?.({
454
+ type: "tool-output-error",
455
+ toolCallId: part.toolCallId,
456
+ toolName: part.toolName,
457
+ errorText,
458
+ })
459
+ return toolErrorResult(part, errorText)
460
+ }
461
+
462
+ let parsed: unknown
463
+ try {
464
+ parsed = tool.parseInput(part.input)
465
+ } catch (error) {
466
+ const errorText = error instanceof Error ? error.message : "Tool input validation failed."
467
+ await onEvent?.({
468
+ type: "tool-input-error",
469
+ toolCallId: part.toolCallId,
470
+ toolName: part.toolName,
471
+ input: part.input,
472
+ errorText,
473
+ })
474
+ return toolErrorResult(part, errorText)
475
+ }
476
+
477
+ await onEvent?.({
478
+ type: "tool-input-available",
479
+ toolCallId: part.toolCallId,
480
+ toolName: part.toolName,
481
+ input: part.input,
482
+ })
483
+ let output: JsonValue
484
+ let modelOutput: ModelToolOutput
485
+ try {
486
+ const context = { signal, callId, toolCallId: part.toolCallId }
487
+ output = await tool.execute(parsed, context)
488
+ assertJsonValue(output, `tool '${part.toolName}' output`)
489
+ modelOutput = tool.toModelOutput
490
+ ? await tool.toModelOutput(output, context)
491
+ : modelToolOutput(output)
492
+ validateModelToolOutput(modelOutput, part.toolName)
493
+ } catch (error) {
494
+ const errorText = tool.errorText(error)
495
+ await onEvent?.({
496
+ type: "tool-output-error",
497
+ toolCallId: part.toolCallId,
498
+ toolName: part.toolName,
499
+ errorText,
500
+ })
501
+ return toolErrorResult(part, errorText)
502
+ }
503
+ // Publication failures belong to the caller, not the tool's recoverable error channel.
504
+ await onEvent?.({
505
+ type: "tool-output-available",
506
+ toolCallId: part.toolCallId,
507
+ toolName: part.toolName,
508
+ output,
509
+ })
510
+ return {
511
+ type: "tool-result",
512
+ toolCallId: part.toolCallId,
513
+ toolName: part.toolName,
514
+ output: modelOutput,
515
+ ...(modelOutputMatchesOriginal(modelOutput, output) ? {} : { originalOutput: output }),
516
+ }
517
+ }
518
+
519
+ function validateModelToolOutput(output: ModelToolOutput, toolName: string): void {
520
+ if (output.type === "text" || output.type === "error-text") {
521
+ if (typeof output.value !== "string") {
522
+ throw new TypeError(`[SixbModels] Tool '${toolName}' model output must contain text.`)
523
+ }
524
+ return
525
+ }
526
+ assertJsonValue(output.value, `tool '${toolName}' model output`)
527
+ }
528
+
529
+ function modelOutputMatchesOriginal(output: ModelToolOutput, original: JsonValue): boolean {
530
+ if (output.type === "text") return typeof original === "string" && output.value === original
531
+ if (output.type === "json") return output.value === original
532
+ return false
533
+ }
534
+
535
+ function modelToolOutput(value: JsonValue): ModelToolOutput {
536
+ return typeof value === "string" ? { type: "text", value } : { type: "json", value }
537
+ }
538
+
539
+ function toolErrorResult(part: ModelToolCallPart, errorText: string): ModelToolResultPart {
540
+ return {
541
+ type: "tool-result",
542
+ toolCallId: part.toolCallId,
543
+ toolName: part.toolName,
544
+ output: { type: "error-text", value: errorText },
545
+ }
546
+ }
547
+
548
+ type MutableTextPart = {
549
+ type: "text"
550
+ text: string
551
+ providerData?: ProviderData
552
+ complete: boolean
553
+ }
554
+ type MutableReasoningPart = {
555
+ type: "reasoning"
556
+ text: string
557
+ providerData?: ProviderData
558
+ complete: boolean
559
+ }
560
+ type MutableToolCall = {
561
+ type: "tool-call"
562
+ toolCallId: string
563
+ toolName: string
564
+ inputText: string
565
+ providerData?: ProviderData
566
+ providerExecuted?: boolean
567
+ dynamic?: boolean
568
+ complete: boolean
569
+ }
570
+ type MutablePart =
571
+ | MutableTextPart
572
+ | MutableReasoningPart
573
+ | MutableToolCall
574
+ | ModelToolResultPart
575
+ | ModelProviderStatePart
576
+
577
+ class StreamAccumulator {
578
+ private readonly parts: MutablePart[] = []
579
+ private readonly spans = new Map<string, MutableTextPart | MutableReasoningPart>()
580
+ private readonly toolCalls = new Map<string, MutableToolCall>()
581
+ private started = false
582
+ private finished = false
583
+ private finishReason: ModelFinishReason | undefined
584
+ private rawFinishReason: string | undefined
585
+ private usage: ModelUsage = {}
586
+ private responseId: string | undefined
587
+ private providerIds: import("../models/events").ModelProviderIds | undefined
588
+ private responseModelId: string | undefined
589
+ private projectionError: Error | undefined
590
+ private reportedCost: ModelReportedCost | undefined
591
+ private route: import("../models/events").ModelRoute | undefined
592
+
593
+ constructor(private readonly onEvent: RunModelLoopInput["onEvent"]) {}
594
+
595
+ isFinished(): boolean {
596
+ return this.finished
597
+ }
598
+
599
+ async accept(event: LanguageModelStreamEvent): Promise<void> {
600
+ if (this.finished) {
601
+ throw new ModelStreamError(`[SixbModels] Received '${event.type}' after stream finish.`)
602
+ }
603
+ switch (event.type) {
604
+ case "stream-start":
605
+ if (this.started) throw new ModelStreamError("[SixbModels] Duplicate stream-start event.")
606
+ this.started = true
607
+ return
608
+ case "response-metadata":
609
+ this.requireStarted(event.type)
610
+ this.responseId = event.id ?? this.responseId
611
+ if (event.providerIds) this.providerIds = { ...this.providerIds, ...event.providerIds }
612
+ this.responseModelId = event.modelId ?? this.responseModelId
613
+ return
614
+ case "text-start":
615
+ await this.startText(event)
616
+ return
617
+ case "text-delta":
618
+ await this.appendText(event, "text")
619
+ return
620
+ case "text-end":
621
+ await this.endText(event, "text")
622
+ return
623
+ case "reasoning-start":
624
+ await this.startReasoning(event)
625
+ return
626
+ case "reasoning-delta":
627
+ await this.appendText(event, "reasoning")
628
+ return
629
+ case "reasoning-end":
630
+ await this.endText(event, "reasoning")
631
+ return
632
+ case "tool-input-start":
633
+ await this.startTool(event)
634
+ return
635
+ case "tool-input-delta":
636
+ await this.appendTool(event)
637
+ return
638
+ case "tool-input-end":
639
+ this.endTool(event)
640
+ return
641
+ case "tool-call":
642
+ await this.completeTool(event)
643
+ return
644
+ case "tool-result":
645
+ this.addProviderToolResult(event)
646
+ return
647
+ case "provider-state":
648
+ if (this.captureProviderState(event.data)) {
649
+ this.parts.push({
650
+ type: "provider-state",
651
+ providerId: event.providerId,
652
+ data: event.data,
653
+ })
654
+ }
655
+ return
656
+ case "finish":
657
+ this.requireStarted(event.type)
658
+ validateUsage(event.usage)
659
+ this.captureProviderData(event.providerData)
660
+ this.finished = true
661
+ this.finishReason = event.finishReason
662
+ this.rawFinishReason = event.rawFinishReason
663
+ this.usage = event.usage
664
+ this.reportedCost = event.reportedCost
665
+ this.route = event.route
666
+ return
667
+ case "error":
668
+ throw event.error instanceof Error
669
+ ? event.error
670
+ : new ModelProviderError("[SixbModels] Provider stream failed.", "unknown", "unknown", {
671
+ cause: event.error,
672
+ })
673
+ }
674
+ }
675
+
676
+ complete(): CompletedResponse {
677
+ if (!this.started) throw new ModelStreamError("[SixbModels] Stream did not start.")
678
+ if (!this.finished || !this.finishReason) {
679
+ throw new ModelStreamError("[SixbModels] Stream ended without a finish event.")
680
+ }
681
+ for (const part of this.parts) {
682
+ if ("complete" in part && !part.complete) {
683
+ throw new ModelStreamError(
684
+ `[SixbModels] Stream finished with incomplete ${part.type} content.`
685
+ )
686
+ }
687
+ }
688
+ const parsed = this.parseParts(false)
689
+ return {
690
+ content: parsed.content,
691
+ toolCalls: parsed.toolCalls,
692
+ finishReason: this.finishReason,
693
+ ...(this.rawFinishReason === undefined ? {} : { rawFinishReason: this.rawFinishReason }),
694
+ ...this.accounting(),
695
+ ...(this.projectionError === undefined ? {} : { projectionError: this.projectionError }),
696
+ }
697
+ }
698
+
699
+ accounting() {
700
+ return {
701
+ usage: this.usage,
702
+ ...(this.responseId === undefined ? {} : { responseId: this.responseId }),
703
+ ...(this.providerIds === undefined ? {} : { providerIds: this.providerIds }),
704
+ ...(this.responseModelId === undefined ? {} : { responseModelId: this.responseModelId }),
705
+ ...(this.reportedCost === undefined ? {} : { reportedCost: this.reportedCost }),
706
+ ...(this.route === undefined ? {} : { route: this.route }),
707
+ }
708
+ }
709
+
710
+ partialContent(): readonly ModelAssistantPart[] {
711
+ return this.parseParts(true).content
712
+ }
713
+
714
+ private parseParts(partial: boolean): {
715
+ readonly content: ModelAssistantPart[]
716
+ readonly toolCalls: ParsedToolCall[]
717
+ } {
718
+ const content: ModelAssistantPart[] = []
719
+ const toolCalls: ParsedToolCall[] = []
720
+ for (const part of this.parts) {
721
+ if (part.type === "text") {
722
+ if ((!partial || part.text.length > 0) && (part.complete || partial)) {
723
+ content.push({
724
+ type: "text",
725
+ text: part.text,
726
+ ...(part.providerData === undefined ? {} : { providerData: part.providerData }),
727
+ })
728
+ }
729
+ } else if (part.type === "reasoning") {
730
+ if (part.complete) {
731
+ content.push({
732
+ type: "reasoning",
733
+ text: part.text,
734
+ ...(part.providerData === undefined ? {} : { providerData: part.providerData }),
735
+ })
736
+ }
737
+ } else if (part.type === "tool-call") {
738
+ if (!part.complete) continue
739
+ let value: JsonValue = null
740
+ let inputError: Error | undefined
741
+ try {
742
+ const parsed: unknown = JSON.parse(part.inputText)
743
+ if (!isJsonValue(parsed)) throw new TypeError("input is not a JSON value")
744
+ value = parsed
745
+ } catch (error) {
746
+ inputError = error instanceof Error ? error : new Error(String(error))
747
+ }
748
+ const call: ModelToolCallPart = {
749
+ type: "tool-call",
750
+ toolCallId: part.toolCallId,
751
+ toolName: part.toolName,
752
+ input: value,
753
+ ...(part.providerData === undefined ? {} : { providerData: part.providerData }),
754
+ ...(part.providerExecuted === undefined
755
+ ? {}
756
+ : { providerExecuted: part.providerExecuted }),
757
+ ...(part.dynamic === undefined ? {} : { dynamic: part.dynamic }),
758
+ }
759
+ content.push(call)
760
+ toolCalls.push({ part: call, ...(inputError === undefined ? {} : { inputError }) })
761
+ } else {
762
+ content.push(part)
763
+ }
764
+ }
765
+ return { content, toolCalls }
766
+ }
767
+
768
+ private async startText(
769
+ event: Extract<LanguageModelStreamEvent, { type: "text-start" }>
770
+ ): Promise<void> {
771
+ this.requireStarted(event.type)
772
+ this.assertNewSpan(event.id)
773
+ const providerData = this.captureProviderData(event.providerData)
774
+ const part: MutableTextPart = {
775
+ type: "text",
776
+ text: "",
777
+ complete: false,
778
+ ...(providerData === undefined ? {} : { providerData }),
779
+ }
780
+ this.spans.set(event.id, part)
781
+ this.parts.push(part)
782
+ await this.onEvent?.({ type: "text-start", id: event.id })
783
+ }
784
+
785
+ private async startReasoning(
786
+ event: Extract<LanguageModelStreamEvent, { type: "reasoning-start" }>
787
+ ): Promise<void> {
788
+ this.requireStarted(event.type)
789
+ this.assertNewSpan(event.id)
790
+ const providerData = this.captureProviderData(event.providerData)
791
+ const part: MutableReasoningPart = {
792
+ type: "reasoning",
793
+ text: "",
794
+ complete: false,
795
+ ...(providerData === undefined ? {} : { providerData }),
796
+ }
797
+ this.spans.set(event.id, part)
798
+ this.parts.push(part)
799
+ await this.onEvent?.({ type: "reasoning-start", id: event.id })
800
+ }
801
+
802
+ private async appendText(
803
+ event: Extract<LanguageModelStreamEvent, { type: "text-delta" | "reasoning-delta" }>,
804
+ expected: "text" | "reasoning"
805
+ ): Promise<void> {
806
+ const part = this.spans.get(event.id)
807
+ if (!part || part.type !== expected || part.complete) {
808
+ throw new ModelStreamError(
809
+ `[SixbModels] ${event.type} references unopened ${expected} span '${event.id}'.`
810
+ )
811
+ }
812
+ part.text += event.delta
813
+ await this.onEvent?.({ type: event.type, id: event.id, delta: event.delta })
814
+ }
815
+
816
+ private async endText(
817
+ event: Extract<LanguageModelStreamEvent, { type: "text-end" | "reasoning-end" }>,
818
+ expected: "text" | "reasoning"
819
+ ): Promise<void> {
820
+ const part = this.spans.get(event.id)
821
+ if (!part || part.type !== expected || part.complete) {
822
+ throw new ModelStreamError(
823
+ `[SixbModels] ${event.type} references unopened ${expected} span '${event.id}'.`
824
+ )
825
+ }
826
+ part.providerData = mergeProviderData(
827
+ part.providerData,
828
+ this.captureProviderData(event.providerData)
829
+ )
830
+ part.complete = true
831
+ this.spans.delete(event.id)
832
+ await this.onEvent?.({ type: event.type, id: event.id })
833
+ }
834
+
835
+ private async startTool(
836
+ event: Extract<LanguageModelStreamEvent, { type: "tool-input-start" }>
837
+ ): Promise<void> {
838
+ this.requireStarted(event.type)
839
+ if (!event.id || !event.toolName) {
840
+ throw new ModelStreamError("[SixbModels] Tool calls require nonempty IDs and names.")
841
+ }
842
+ if (this.toolCalls.has(event.id)) {
843
+ throw new ModelStreamError(`[SixbModels] Duplicate tool call ID '${event.id}'.`)
844
+ }
845
+ const providerData = this.captureProviderData(event.providerData)
846
+ const part: MutableToolCall = {
847
+ type: "tool-call",
848
+ toolCallId: event.id,
849
+ toolName: event.toolName,
850
+ inputText: "",
851
+ complete: false,
852
+ ...(providerData === undefined ? {} : { providerData }),
853
+ ...(event.providerExecuted === undefined ? {} : { providerExecuted: event.providerExecuted }),
854
+ ...(event.dynamic === undefined ? {} : { dynamic: event.dynamic }),
855
+ }
856
+ this.toolCalls.set(event.id, part)
857
+ this.parts.push(part)
858
+ await this.onEvent?.({
859
+ type: "tool-input-start",
860
+ toolCallId: event.id,
861
+ toolName: event.toolName,
862
+ })
863
+ }
864
+
865
+ private async appendTool(
866
+ event: Extract<LanguageModelStreamEvent, { type: "tool-input-delta" }>
867
+ ): Promise<void> {
868
+ const part = this.toolCalls.get(event.id)
869
+ if (!part || part.complete) {
870
+ throw new ModelStreamError(
871
+ `[SixbModels] tool-input-delta references unopened tool call '${event.id}'.`
872
+ )
873
+ }
874
+ part.inputText += event.delta
875
+ await this.onEvent?.({
876
+ type: "tool-input-delta",
877
+ toolCallId: event.id,
878
+ toolName: part.toolName,
879
+ inputTextDelta: event.delta,
880
+ })
881
+ }
882
+
883
+ private endTool(event: Extract<LanguageModelStreamEvent, { type: "tool-input-end" }>): void {
884
+ const part = this.toolCalls.get(event.id)
885
+ if (!part || part.complete) {
886
+ throw new ModelStreamError(
887
+ `[SixbModels] tool-input-end references unopened tool call '${event.id}'.`
888
+ )
889
+ }
890
+ part.providerData = mergeProviderData(
891
+ part.providerData,
892
+ this.captureProviderData(event.providerData)
893
+ )
894
+ part.complete = true
895
+ }
896
+
897
+ private async completeTool(
898
+ event: Extract<LanguageModelStreamEvent, { type: "tool-call" }>
899
+ ): Promise<void> {
900
+ await this.startTool({
901
+ type: "tool-input-start",
902
+ id: event.toolCallId,
903
+ toolName: event.toolName,
904
+ ...(event.providerData === undefined ? {} : { providerData: event.providerData }),
905
+ ...(event.providerExecuted === undefined ? {} : { providerExecuted: event.providerExecuted }),
906
+ ...(event.dynamic === undefined ? {} : { dynamic: event.dynamic }),
907
+ })
908
+ const part = this.toolCalls.get(event.toolCallId)
909
+ if (!part) throw new ModelStreamError("[SixbModels] Failed to index completed tool call.")
910
+ part.inputText = event.input
911
+ part.complete = true
912
+ }
913
+
914
+ private addProviderToolResult(
915
+ event: Extract<LanguageModelStreamEvent, { type: "tool-result" }>
916
+ ): void {
917
+ if (!this.captureJsonValue(event.output, "provider tool result")) return
918
+ const providerData = this.captureProviderData(event.providerData)
919
+ this.parts.push({
920
+ type: "tool-result",
921
+ toolCallId: event.toolCallId,
922
+ toolName: event.toolName,
923
+ output: event.isError
924
+ ? { type: "error-json", value: event.output }
925
+ : modelToolOutput(event.output),
926
+ providerExecuted: event.providerExecuted ?? true,
927
+ ...(event.dynamic === undefined ? {} : { dynamic: event.dynamic }),
928
+ ...(providerData === undefined ? {} : { providerData }),
929
+ })
930
+ }
931
+
932
+ private captureProviderData(data: ProviderData | undefined): ProviderData | undefined {
933
+ if (data === undefined) return undefined
934
+ try {
935
+ validateProviderData(data)
936
+ return data
937
+ } catch (error) {
938
+ this.captureProjectionError(error)
939
+ return undefined
940
+ }
941
+ }
942
+
943
+ private captureProviderState(value: unknown): value is JsonValue {
944
+ if (!this.captureJsonValue(value, "provider state")) return false
945
+ if (JSON.stringify(value).length > MAX_PROVIDER_DATA_BYTES) {
946
+ this.captureProjectionError(
947
+ new ModelStreamError(
948
+ `[SixbModels] Provider state exceeds the ${MAX_PROVIDER_DATA_BYTES}-byte response limit.`
949
+ )
950
+ )
951
+ return false
952
+ }
953
+ return true
954
+ }
955
+
956
+ private captureJsonValue(value: unknown, label: string): value is JsonValue {
957
+ try {
958
+ assertJsonValue(value, label)
959
+ return true
960
+ } catch (error) {
961
+ this.captureProjectionError(error)
962
+ return false
963
+ }
964
+ }
965
+
966
+ private captureProjectionError(error: unknown): void {
967
+ this.projectionError ??= error instanceof Error ? error : new Error(String(error))
968
+ }
969
+
970
+ private requireStarted(type: string): void {
971
+ if (!this.started) {
972
+ throw new ModelStreamError(`[SixbModels] Received '${type}' before stream-start.`)
973
+ }
974
+ }
975
+
976
+ private assertNewSpan(id: string): void {
977
+ if (!id) throw new ModelStreamError("[SixbModels] Content span IDs must not be empty.")
978
+ if (this.spans.has(id)) {
979
+ throw new ModelStreamError(`[SixbModels] Duplicate open content span '${id}'.`)
980
+ }
981
+ }
982
+ }
983
+
984
+ function validateUsage(usage: ModelUsage): void {
985
+ for (const [key, value] of Object.entries(usage)) {
986
+ if (key === "raw") {
987
+ if (value !== undefined) assertJsonValue(value, "raw model usage")
988
+ continue
989
+ }
990
+ if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {
991
+ throw new ModelStreamError(`[SixbModels] Usage field '${key}' must be a nonnegative integer.`)
992
+ }
993
+ }
994
+ }
995
+
996
+ function validateProviderData(data: ProviderData | undefined): void {
997
+ if (data === undefined) return
998
+ assertJsonValue(data, "provider data")
999
+ if (typeof data !== "object" || data === null || Array.isArray(data)) {
1000
+ throw new TypeError("[SixbModels] provider data must be a JSON object.")
1001
+ }
1002
+ if (JSON.stringify(data).length > MAX_PROVIDER_DATA_BYTES) {
1003
+ throw new ModelStreamError(
1004
+ `[SixbModels] Provider data exceeds the ${MAX_PROVIDER_DATA_BYTES}-byte response limit.`
1005
+ )
1006
+ }
1007
+ }
1008
+
1009
+ function mergeProviderData(
1010
+ first: ProviderData | undefined,
1011
+ second: ProviderData | undefined
1012
+ ): ProviderData | undefined {
1013
+ if (first === undefined) return second
1014
+ if (second === undefined) return first
1015
+ return { ...first, ...second }
1016
+ }
1017
+
1018
+ function isAbortError(error: unknown): boolean {
1019
+ return (
1020
+ (error instanceof DOMException && error.name === "AbortError") ||
1021
+ (error instanceof Error && error.name === "AbortError")
1022
+ )
1023
+ }