@skaile/workspaces 5.12.0 → 5.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (407) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/README.md +2 -2
  3. package/dist/app-sdk/index.js +1 -1
  4. package/dist/{asset-feeds-AM6PSSGM.js → asset-feeds-PAOX3FUT.js} +20 -20
  5. package/dist/{asset-feeds-AM6PSSGM.js.map → asset-feeds-PAOX3FUT.js.map} +1 -1
  6. package/dist/asset-manager/catalog-deployer.js +9 -9
  7. package/dist/asset-manager/index.js +15 -15
  8. package/dist/asset-manager/installer.js +11 -11
  9. package/dist/asset-manager/renderers.js +10 -10
  10. package/dist/asset-manager/src/index.d.ts +53 -10
  11. package/dist/asset-manager/src/index.d.ts.map +1 -1
  12. package/dist/asset-manager/src/installer.d.ts +0 -10
  13. package/dist/asset-manager/src/installer.d.ts.map +1 -1
  14. package/dist/bridge/drivers/claude-sdk.js +155 -18
  15. package/dist/bridge/drivers/claude-sdk.js.map +1 -1
  16. package/dist/bridge/drivers/codex.js +73 -27
  17. package/dist/bridge/drivers/codex.js.map +1 -1
  18. package/dist/bridge/drivers/continue.js +12 -11
  19. package/dist/bridge/drivers/continue.js.map +1 -1
  20. package/dist/bridge/drivers/echo.js +4 -3
  21. package/dist/bridge/drivers/echo.js.map +1 -1
  22. package/dist/bridge/drivers/gemini.js +7 -6
  23. package/dist/bridge/drivers/goose.js +12 -11
  24. package/dist/bridge/drivers/goose.js.map +1 -1
  25. package/dist/bridge/drivers/omp.js +105 -29
  26. package/dist/bridge/drivers/omp.js.map +1 -1
  27. package/dist/bridge/drivers/opencode.js +12 -11
  28. package/dist/bridge/drivers/opencode.js.map +1 -1
  29. package/dist/bridge/drivers/qwen.js +7 -6
  30. package/dist/bridge/drivers/qwen.js.map +1 -1
  31. package/dist/bridge/index.js +16 -15
  32. package/dist/bridge/src/codex/config-toml.d.ts +8 -0
  33. package/dist/bridge/src/codex/config-toml.d.ts.map +1 -1
  34. package/dist/bridge/src/drivers/claude-sdk.d.ts +2 -0
  35. package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
  36. package/dist/bridge/src/drivers/claude-self-turns.d.ts +72 -0
  37. package/dist/bridge/src/drivers/claude-self-turns.d.ts.map +1 -0
  38. package/dist/bridge/src/drivers/codex.d.ts +6 -0
  39. package/dist/bridge/src/drivers/codex.d.ts.map +1 -1
  40. package/dist/bridge/src/drivers/omp-models-yml.d.ts +32 -0
  41. package/dist/bridge/src/drivers/omp-models-yml.d.ts.map +1 -1
  42. package/dist/bridge/src/drivers/omp.d.ts +20 -6
  43. package/dist/bridge/src/drivers/omp.d.ts.map +1 -1
  44. package/dist/bridge/src/normalizer.d.ts.map +1 -1
  45. package/dist/bridge/src/types.d.ts +12 -0
  46. package/dist/bridge/src/types.d.ts.map +1 -1
  47. package/dist/{chunk-QCEKGYHF.js → chunk-2BIESC6S.js} +3 -3
  48. package/dist/{chunk-QCEKGYHF.js.map → chunk-2BIESC6S.js.map} +1 -1
  49. package/dist/{chunk-P23WJCH2.js → chunk-3NNL334S.js} +23 -18
  50. package/dist/chunk-3NNL334S.js.map +1 -0
  51. package/dist/{chunk-6VLHITAM.js → chunk-57SF6W6E.js} +4 -3
  52. package/dist/chunk-57SF6W6E.js.map +1 -0
  53. package/dist/{chunk-GWD3QNVS.js → chunk-5IMGZAKH.js} +5 -5
  54. package/dist/{chunk-GWD3QNVS.js.map → chunk-5IMGZAKH.js.map} +1 -1
  55. package/dist/{chunk-NDF24LYP.js → chunk-5NVDOEWX.js} +15 -7
  56. package/dist/chunk-5NVDOEWX.js.map +1 -0
  57. package/dist/{chunk-3HUV2LJF.js → chunk-6JKIOPT3.js} +4 -4
  58. package/dist/{chunk-3HUV2LJF.js.map → chunk-6JKIOPT3.js.map} +1 -1
  59. package/dist/{chunk-MF54ZHWT.js → chunk-6VIVUBNN.js} +4 -271
  60. package/dist/chunk-6VIVUBNN.js.map +1 -0
  61. package/dist/{chunk-2X3JBVGD.js → chunk-7LGNJJ76.js} +18 -9
  62. package/dist/chunk-7LGNJJ76.js.map +1 -0
  63. package/dist/chunk-BASMWKPM.js +649 -0
  64. package/dist/chunk-BASMWKPM.js.map +1 -0
  65. package/dist/{chunk-PNOGX36L.js → chunk-CAPKENNF.js} +92 -26
  66. package/dist/chunk-CAPKENNF.js.map +1 -0
  67. package/dist/{chunk-7QWQTA5S.js → chunk-CNZI37HV.js} +4 -4
  68. package/dist/{chunk-7QWQTA5S.js.map → chunk-CNZI37HV.js.map} +1 -1
  69. package/dist/{chunk-PMECEZK3.js → chunk-D54T2F54.js} +5 -4
  70. package/dist/chunk-D54T2F54.js.map +1 -0
  71. package/dist/{chunk-F4NJDSR7.js → chunk-D5WTOVLG.js} +7 -4
  72. package/dist/chunk-D5WTOVLG.js.map +1 -0
  73. package/dist/{chunk-XZY6SBGU.js → chunk-DHUJRIQQ.js} +3 -3
  74. package/dist/{chunk-XZY6SBGU.js.map → chunk-DHUJRIQQ.js.map} +1 -1
  75. package/dist/chunk-DWRYUWOK.js +273 -0
  76. package/dist/chunk-DWRYUWOK.js.map +1 -0
  77. package/dist/{chunk-NJV5SLEK.js → chunk-FD2IPIE2.js} +46 -46
  78. package/dist/chunk-FD2IPIE2.js.map +1 -0
  79. package/dist/{chunk-POQ6PGNE.js → chunk-GJGEDWRT.js} +22 -6
  80. package/dist/chunk-GJGEDWRT.js.map +1 -0
  81. package/dist/{chunk-CPSIPIX7.js → chunk-IG5LZ3WU.js} +8 -6
  82. package/dist/chunk-IG5LZ3WU.js.map +1 -0
  83. package/dist/{chunk-3LVB3HGH.js → chunk-IPN7N2AZ.js} +3 -3
  84. package/dist/{chunk-3LVB3HGH.js.map → chunk-IPN7N2AZ.js.map} +1 -1
  85. package/dist/{chunk-NGJIVDDD.js → chunk-IQVZIVSA.js} +3 -3
  86. package/dist/{chunk-NGJIVDDD.js.map → chunk-IQVZIVSA.js.map} +1 -1
  87. package/dist/{chunk-CTP3XBMF.js → chunk-IY5E7Y5W.js} +57 -7
  88. package/dist/chunk-IY5E7Y5W.js.map +1 -0
  89. package/dist/{chunk-PNTXHTBC.js → chunk-J4OYIYFQ.js} +2 -2
  90. package/dist/{chunk-PNTXHTBC.js.map → chunk-J4OYIYFQ.js.map} +1 -1
  91. package/dist/{chunk-XTVSNWLL.js → chunk-M3P4BYRK.js} +34 -11
  92. package/dist/chunk-M3P4BYRK.js.map +1 -0
  93. package/dist/{chunk-X6LKA3TJ.js → chunk-MCLT3BJG.js} +6 -6
  94. package/dist/{chunk-X6LKA3TJ.js.map → chunk-MCLT3BJG.js.map} +1 -1
  95. package/dist/{chunk-7CR2OZPA.js → chunk-NVO6WECE.js} +9 -8
  96. package/dist/chunk-NVO6WECE.js.map +1 -0
  97. package/dist/chunk-O3Q3MOAV.js +64 -0
  98. package/dist/chunk-O3Q3MOAV.js.map +1 -0
  99. package/dist/{chunk-C3BMXXTN.js → chunk-ODQGLELI.js} +68 -24
  100. package/dist/chunk-ODQGLELI.js.map +1 -0
  101. package/dist/chunk-OKQXY6FS.js +1336 -0
  102. package/dist/chunk-OKQXY6FS.js.map +1 -0
  103. package/dist/{chunk-T5TSLSRO.js → chunk-OX2W5YF3.js} +8 -8
  104. package/dist/{chunk-T5TSLSRO.js.map → chunk-OX2W5YF3.js.map} +1 -1
  105. package/dist/{chunk-N5M2EISA.js → chunk-PAUM35HD.js} +250 -71
  106. package/dist/chunk-PAUM35HD.js.map +1 -0
  107. package/dist/{chunk-YQU2BPQD.js → chunk-PGVSOHWE.js} +2 -2
  108. package/dist/{chunk-YQU2BPQD.js.map → chunk-PGVSOHWE.js.map} +1 -1
  109. package/dist/{chunk-WI4T3KIS.js → chunk-PUG7IWFF.js} +130 -23
  110. package/dist/chunk-PUG7IWFF.js.map +1 -0
  111. package/dist/{chunk-2H73V6XR.js → chunk-PW3TYWOI.js} +3 -3
  112. package/dist/{chunk-2H73V6XR.js.map → chunk-PW3TYWOI.js.map} +1 -1
  113. package/dist/{chunk-UTKENBB6.js → chunk-PXDWTJ3P.js} +4 -4
  114. package/dist/{chunk-UTKENBB6.js.map → chunk-PXDWTJ3P.js.map} +1 -1
  115. package/dist/{chunk-TVAR4JHA.js → chunk-QAYL3PYY.js} +320 -51
  116. package/dist/chunk-QAYL3PYY.js.map +1 -0
  117. package/dist/{chunk-7XWUJC3A.js → chunk-QELQDY5K.js} +3 -3
  118. package/dist/{chunk-7XWUJC3A.js.map → chunk-QELQDY5K.js.map} +1 -1
  119. package/dist/{chunk-VRLKHL74.js → chunk-S6FZUR5H.js} +7 -6
  120. package/dist/chunk-S6FZUR5H.js.map +1 -0
  121. package/dist/{chunk-SHQMPGOL.js → chunk-TYUJPQNX.js} +10 -5
  122. package/dist/chunk-TYUJPQNX.js.map +1 -0
  123. package/dist/chunk-U27JRO5L.js +13 -0
  124. package/dist/chunk-U27JRO5L.js.map +1 -0
  125. package/dist/{chunk-ICIYSJBQ.js → chunk-UK3LRPJ5.js} +15 -7
  126. package/dist/chunk-UK3LRPJ5.js.map +1 -0
  127. package/dist/{chunk-KVSDRB35.js → chunk-UQ4SQOR6.js} +5 -5
  128. package/dist/{chunk-KVSDRB35.js.map → chunk-UQ4SQOR6.js.map} +1 -1
  129. package/dist/{chunk-G3X4MLDB.js → chunk-USHB5KEY.js} +3 -3
  130. package/dist/{chunk-G3X4MLDB.js.map → chunk-USHB5KEY.js.map} +1 -1
  131. package/dist/{chunk-HYMERG57.js → chunk-V7AWO5FL.js} +3 -3
  132. package/dist/{chunk-HYMERG57.js.map → chunk-V7AWO5FL.js.map} +1 -1
  133. package/dist/chunk-VTG5Z3KD.js +345 -0
  134. package/dist/chunk-VTG5Z3KD.js.map +1 -0
  135. package/dist/{chunk-27L6BBAT.js → chunk-VTXXBYB3.js} +10 -10
  136. package/dist/{chunk-27L6BBAT.js.map → chunk-VTXXBYB3.js.map} +1 -1
  137. package/dist/{chunk-XMAJJPA4.js → chunk-WTEYDNTR.js} +3 -3
  138. package/dist/{chunk-XMAJJPA4.js.map → chunk-WTEYDNTR.js.map} +1 -1
  139. package/dist/{chunk-NJXR5OAM.js → chunk-YFIHFJEB.js} +4 -4
  140. package/dist/{chunk-NJXR5OAM.js.map → chunk-YFIHFJEB.js.map} +1 -1
  141. package/dist/{chunk-VMKMFS2Q.js → chunk-YIDZJHY6.js} +3 -3
  142. package/dist/{chunk-VMKMFS2Q.js.map → chunk-YIDZJHY6.js.map} +1 -1
  143. package/dist/{chunk-2JFIFDDO.js → chunk-YTZFSKWL.js} +3 -3
  144. package/dist/{chunk-2JFIFDDO.js.map → chunk-YTZFSKWL.js.map} +1 -1
  145. package/dist/{chunk-SMT3LNAG.js → chunk-ZBD6EITA.js} +4 -4
  146. package/dist/{chunk-SMT3LNAG.js.map → chunk-ZBD6EITA.js.map} +1 -1
  147. package/dist/{chunk-JQ3DXNQV.js → chunk-ZDTZGEJG.js} +6 -6
  148. package/dist/{chunk-JQ3DXNQV.js.map → chunk-ZDTZGEJG.js.map} +1 -1
  149. package/dist/{chunk-X4BAYGMT.js → chunk-ZIW34FGO.js} +3 -3
  150. package/dist/{chunk-X4BAYGMT.js.map → chunk-ZIW34FGO.js.map} +1 -1
  151. package/dist/{chunk-DCHQ6BAZ.js → chunk-ZU24LWBI.js} +3 -3
  152. package/dist/{chunk-DCHQ6BAZ.js.map → chunk-ZU24LWBI.js.map} +1 -1
  153. package/dist/cli/index.js +493 -232
  154. package/dist/cli/index.js.map +1 -1
  155. package/dist/cli/src/commands/asset-cmd.d.ts.map +1 -1
  156. package/dist/cli/src/commands/catalog-cmd.d.ts.map +1 -1
  157. package/dist/cli/src/commands/catalog.d.ts +2 -0
  158. package/dist/cli/src/commands/catalog.d.ts.map +1 -1
  159. package/dist/cli/src/commands/diff.d.ts +1 -1
  160. package/dist/cli/src/commands/diff.d.ts.map +1 -1
  161. package/dist/cli/src/commands/integration.d.ts.map +1 -1
  162. package/dist/cli/src/commands/library-cmd.d.ts.map +1 -1
  163. package/dist/cli/src/commands/library-index.d.ts +10 -0
  164. package/dist/cli/src/commands/library-index.d.ts.map +1 -1
  165. package/dist/cli/src/commands/library-publish.d.ts.map +1 -1
  166. package/dist/cli/src/commands/plugin/claude-code.d.ts.map +1 -1
  167. package/dist/cli/src/commands/plugin/types.d.ts +2 -0
  168. package/dist/cli/src/commands/plugin/types.d.ts.map +1 -1
  169. package/dist/cli/src/commands/plugin-registry-cmd.d.ts.map +1 -1
  170. package/dist/cli/src/commands/preset-apply.d.ts.map +1 -1
  171. package/dist/cli/src/commands/project.d.ts +8 -0
  172. package/dist/cli/src/commands/project.d.ts.map +1 -1
  173. package/dist/cli/src/commands/run.d.ts +9 -0
  174. package/dist/cli/src/commands/run.d.ts.map +1 -1
  175. package/dist/cli/src/commands/serve-preflight.d.ts +2 -1
  176. package/dist/cli/src/commands/serve-preflight.d.ts.map +1 -1
  177. package/dist/cli/src/commands/serve.d.ts +7 -0
  178. package/dist/cli/src/commands/serve.d.ts.map +1 -1
  179. package/dist/cli/src/commands/source-manifest.d.ts +1 -0
  180. package/dist/cli/src/commands/source-manifest.d.ts.map +1 -1
  181. package/dist/cli/src/commands/source.d.ts +9 -1
  182. package/dist/cli/src/commands/source.d.ts.map +1 -1
  183. package/dist/cli/src/commands/store.d.ts.map +1 -1
  184. package/dist/cli/src/commands/update.d.ts.map +1 -1
  185. package/dist/cli/src/commands/validate-instances.d.ts.map +1 -1
  186. package/dist/cli/src/commands/validate.d.ts +3 -2
  187. package/dist/cli/src/commands/validate.d.ts.map +1 -1
  188. package/dist/cli/src/driver-error.d.ts +7 -0
  189. package/dist/cli/src/driver-error.d.ts.map +1 -1
  190. package/dist/cli/src/helpers.d.ts +6 -0
  191. package/dist/cli/src/helpers.d.ts.map +1 -1
  192. package/dist/cli/src/plugin-store/index.d.ts +1 -1
  193. package/dist/cli/src/plugin-store/index.d.ts.map +1 -1
  194. package/dist/cli/src/plugin-store/reconcile.d.ts +24 -4
  195. package/dist/cli/src/plugin-store/reconcile.d.ts.map +1 -1
  196. package/dist/cli/src/skill-checks.d.ts +15 -4
  197. package/dist/cli/src/skill-checks.d.ts.map +1 -1
  198. package/dist/cli/src/store-addable.d.ts +7 -8
  199. package/dist/cli/src/store-addable.d.ts.map +1 -1
  200. package/dist/connectors/config.js +6 -6
  201. package/dist/connectors/index.js +20 -19
  202. package/dist/connectors/src/config.d.ts.map +1 -1
  203. package/dist/{connectors-UNKUKEPG.js → connectors-2TEGRRYC.js} +23 -22
  204. package/dist/{connectors-UNKUKEPG.js.map → connectors-2TEGRRYC.js.map} +1 -1
  205. package/dist/connectors-shared/index.js +2 -2
  206. package/dist/core/driver-targets.js +1 -1
  207. package/dist/core/index.js +8 -8
  208. package/dist/core/manifest.js +2 -2
  209. package/dist/core/models.js +1 -1
  210. package/dist/core/publish-manifest.js +4 -2
  211. package/dist/core/ref.js +1 -1
  212. package/dist/core/runtime-assets.js +6 -6
  213. package/dist/core/src/agent-instances.d.ts +5 -0
  214. package/dist/core/src/agent-instances.d.ts.map +1 -1
  215. package/dist/core/src/driver-targets.d.ts.map +1 -1
  216. package/dist/core/src/index.d.ts +2 -2
  217. package/dist/core/src/index.d.ts.map +1 -1
  218. package/dist/core/src/manifest.d.ts +9 -3
  219. package/dist/core/src/manifest.d.ts.map +1 -1
  220. package/dist/core/src/models.d.ts +8 -0
  221. package/dist/core/src/models.d.ts.map +1 -1
  222. package/dist/core/src/publish-manifest.d.ts +38 -1
  223. package/dist/core/src/publish-manifest.d.ts.map +1 -1
  224. package/dist/core/src/repo-manager.d.ts +8 -3
  225. package/dist/core/src/repo-manager.d.ts.map +1 -1
  226. package/dist/core/src/runtime-assets.d.ts.map +1 -1
  227. package/dist/core/src/store.d.ts +4 -0
  228. package/dist/core/src/store.d.ts.map +1 -1
  229. package/dist/core/src/walker.d.ts +2 -0
  230. package/dist/core/src/walker.d.ts.map +1 -1
  231. package/dist/core/src/workspace-config.d.ts +40 -2
  232. package/dist/core/src/workspace-config.d.ts.map +1 -1
  233. package/dist/core/store.js +2 -2
  234. package/dist/core/workspace-config.js +5 -5
  235. package/dist/deploy/index.js +8 -8
  236. package/dist/discovery/index.js +5 -5
  237. package/dist/discovery/src/parse-manifest.d.ts.map +1 -1
  238. package/dist/discovery/src/source-config.d.ts +5 -3
  239. package/dist/discovery/src/source-config.d.ts.map +1 -1
  240. package/dist/{ensure-sources-POMEQSTM.js → ensure-sources-EG7YKKZL.js} +18 -18
  241. package/dist/{ensure-sources-POMEQSTM.js.map → ensure-sources-EG7YKKZL.js.map} +1 -1
  242. package/dist/factory-assets/README.md +1 -1
  243. package/dist/factory-assets/connectors/box.js +20 -19
  244. package/dist/factory-assets/connectors/deploy.js +20 -19
  245. package/dist/factory-assets/connectors/devserver.js +20 -19
  246. package/dist/factory-assets/connectors/flow/adapter.js +20 -19
  247. package/dist/factory-assets/connectors/flow/engine.js +9 -9
  248. package/dist/factory-assets/connectors/flow/run-flow.d.ts.map +1 -1
  249. package/dist/factory-assets/connectors/flow/run-flow.js +22 -21
  250. package/dist/factory-assets/connectors/flow.js +20 -19
  251. package/dist/factory-assets/connectors/git.js +20 -19
  252. package/dist/factory-assets/connectors/gmail.js +20 -19
  253. package/dist/factory-assets/connectors/googledrive.js +20 -19
  254. package/dist/factory-assets/connectors/local.js +20 -19
  255. package/dist/factory-assets/connectors/mattermost.js +20 -19
  256. package/dist/factory-assets/connectors/memory.js +20 -19
  257. package/dist/factory-assets/connectors/minio.js +20 -19
  258. package/dist/factory-assets/connectors/postgres.js +20 -19
  259. package/dist/factory-assets/connectors/s3.js +20 -19
  260. package/dist/factory-assets/connectors/sharepoint.js +20 -19
  261. package/dist/factory-assets/connectors/sqlite.js +20 -19
  262. package/dist/factory-assets/connectors/static-server.js +20 -19
  263. package/dist/factory-assets/connectors/tunnel.js +20 -19
  264. package/dist/factory-assets/connectors/webdav.js +20 -19
  265. package/dist/factory-assets/connectors/xstate-store.js +20 -19
  266. package/dist/factory-assets/connectors/xstate.js +20 -19
  267. package/dist/{flows-DVKMZKM4.js → flows-5TW3XFMH.js} +13 -13
  268. package/dist/{flows-DVKMZKM4.js.map → flows-5TW3XFMH.js.map} +1 -1
  269. package/dist/{helpers-Y4OT7VIS.js → helpers-BQGXEKRP.js} +18 -18
  270. package/dist/{helpers-Y4OT7VIS.js.map → helpers-BQGXEKRP.js.map} +1 -1
  271. package/dist/library/index.js +12 -12
  272. package/dist/library/install.js +5 -3
  273. package/dist/library/src/local/local-catalog-source.d.ts +6 -0
  274. package/dist/library/src/local/local-catalog-source.d.ts.map +1 -1
  275. package/dist/library/src/manifest-writer.d.ts +1 -1
  276. package/dist/library/src/manifest-writer.d.ts.map +1 -1
  277. package/dist/library/src/remote/remote-catalog-source.d.ts.map +1 -1
  278. package/dist/library/src/user-library.d.ts +2 -0
  279. package/dist/library/src/user-library.d.ts.map +1 -1
  280. package/dist/{library-publish-DI4Q5UOG.js → library-publish-EUP524PE.js} +28 -25
  281. package/dist/library-publish-EUP524PE.js.map +1 -0
  282. package/dist/model-endpoint/index.d.ts +2 -0
  283. package/dist/model-endpoint/index.js +9 -0
  284. package/dist/model-endpoint/index.js.map +1 -0
  285. package/dist/model-endpoint/src/index.d.ts +4 -0
  286. package/dist/model-endpoint/src/index.d.ts.map +1 -0
  287. package/dist/model-endpoint/src/openai-chat.d.ts +105 -0
  288. package/dist/model-endpoint/src/openai-chat.d.ts.map +1 -0
  289. package/dist/model-endpoint/src/openai-responses.d.ts +106 -0
  290. package/dist/model-endpoint/src/openai-responses.d.ts.map +1 -0
  291. package/dist/model-endpoint/src/openai-shared.d.ts +77 -0
  292. package/dist/model-endpoint/src/openai-shared.d.ts.map +1 -0
  293. package/dist/model-endpoint/src/resolve.d.ts +36 -0
  294. package/dist/model-endpoint/src/resolve.d.ts.map +1 -0
  295. package/dist/model-endpoint/src/server.d.ts +16 -0
  296. package/dist/model-endpoint/src/server.d.ts.map +1 -0
  297. package/dist/model-endpoint/src/types.d.ts +78 -0
  298. package/dist/model-endpoint/src/types.d.ts.map +1 -0
  299. package/dist/open-library-QNMIMZYS.js +40 -0
  300. package/dist/{open-library-N6ESO6IK.js.map → open-library-QNMIMZYS.js.map} +1 -1
  301. package/dist/open-registry-BOUCBDLF.js +32 -0
  302. package/dist/{open-registry-CBZ5MWTT.js.map → open-registry-BOUCBDLF.js.map} +1 -1
  303. package/dist/paths-B6SX6J6T.js +22 -0
  304. package/dist/{paths-U6W6MQNQ.js.map → paths-B6SX6J6T.js.map} +1 -1
  305. package/dist/{plugin-store-XMZSPVBF.js → plugin-store-MLFP3WJ7.js} +62 -20
  306. package/dist/plugin-store-MLFP3WJ7.js.map +1 -0
  307. package/dist/plugins/src/catalog-source.d.ts +6 -0
  308. package/dist/plugins/src/catalog-source.d.ts.map +1 -1
  309. package/dist/project-GXCIEJGM.js +82 -0
  310. package/dist/{project-UP52HEHC.js.map → project-GXCIEJGM.js.map} +1 -1
  311. package/dist/resolver/index.js +9 -9
  312. package/dist/runner/index.js +35 -32
  313. package/dist/runner/src/agent.d.ts.map +1 -1
  314. package/dist/runner/src/composition/index.d.ts +1 -1
  315. package/dist/runner/src/composition/index.d.ts.map +1 -1
  316. package/dist/runner/src/composition/prompt-sections.d.ts +18 -6
  317. package/dist/runner/src/composition/prompt-sections.d.ts.map +1 -1
  318. package/dist/runner/src/model-endpoint-discovery.d.ts +64 -0
  319. package/dist/runner/src/model-endpoint-discovery.d.ts.map +1 -0
  320. package/dist/runner/src/serve.d.ts +6 -0
  321. package/dist/runner/src/serve.d.ts.map +1 -1
  322. package/dist/runner/src/session-builder.d.ts +8 -0
  323. package/dist/runner/src/session-builder.d.ts.map +1 -1
  324. package/dist/runner/src/session.d.ts +2 -0
  325. package/dist/runner/src/session.d.ts.map +1 -1
  326. package/dist/runner/src/ws-auth-warning.d.ts +17 -0
  327. package/dist/runner/src/ws-auth-warning.d.ts.map +1 -0
  328. package/dist/sdk/asset-manager.js +15 -15
  329. package/dist/sdk/bridge.js +16 -15
  330. package/dist/sdk/core.js +8 -8
  331. package/dist/sdk/flow.js +9 -9
  332. package/dist/sdk/index.js +35 -32
  333. package/dist/sdk/index.js.map +1 -1
  334. package/dist/sdk/resolver.js +9 -9
  335. package/dist/sdk/runner.js +35 -32
  336. package/dist/sdk/session.js +2 -2
  337. package/dist/sdk/types.js +1 -1
  338. package/dist/serve-preflight-GNBW3O4U.js +64 -0
  339. package/dist/serve-preflight-GNBW3O4U.js.map +1 -0
  340. package/dist/session/index.js +2 -2
  341. package/dist/{setup-5IRUH5OS.js → setup-HJEYEXLS.js} +26 -25
  342. package/dist/setup-HJEYEXLS.js.map +1 -0
  343. package/dist/skills-4WMYGJDL.js +26 -0
  344. package/dist/{skills-HA36RFNM.js.map → skills-4WMYGJDL.js.map} +1 -1
  345. package/dist/source-5VL6PHER.js +42 -0
  346. package/dist/{source-DX5SGWEI.js.map → source-5VL6PHER.js.map} +1 -1
  347. package/dist/{source-manifest-publish-NMRLXWVW.js → source-manifest-publish-Q66H7EJI.js} +25 -24
  348. package/dist/source-manifest-publish-Q66H7EJI.js.map +1 -0
  349. package/dist/tui/index.js +52 -39
  350. package/dist/tui/index.js.map +1 -1
  351. package/dist/tui/src/repl.d.ts.map +1 -1
  352. package/dist/types/index.js +1 -1
  353. package/dist/types/manifests.js +1 -1
  354. package/dist/types/src/delivery.d.ts.map +1 -1
  355. package/dist/types/src/events.d.ts +55 -1
  356. package/dist/types/src/events.d.ts.map +1 -1
  357. package/dist/types/src/index.d.ts +1 -1
  358. package/dist/types/src/index.d.ts.map +1 -1
  359. package/dist/types/src/lifecycle.d.ts +2 -1
  360. package/dist/types/src/lifecycle.d.ts.map +1 -1
  361. package/dist/types/src/manifests/preset.d.ts +6 -1
  362. package/dist/types/src/manifests/preset.d.ts.map +1 -1
  363. package/dist/types/src/version.d.ts +11 -1
  364. package/dist/types/src/version.d.ts.map +1 -1
  365. package/dist/workspace-plugin/adapters/mcp.js +27 -26
  366. package/dist/workspace-plugin/adapters/omp.js +14 -14
  367. package/dist/workspace-plugin/index.js +1 -1
  368. package/package.json +12 -1
  369. package/dist/chunk-2X3JBVGD.js.map +0 -1
  370. package/dist/chunk-6VLHITAM.js.map +0 -1
  371. package/dist/chunk-7CR2OZPA.js.map +0 -1
  372. package/dist/chunk-C3BMXXTN.js.map +0 -1
  373. package/dist/chunk-CPSIPIX7.js.map +0 -1
  374. package/dist/chunk-CTP3XBMF.js.map +0 -1
  375. package/dist/chunk-F4NJDSR7.js.map +0 -1
  376. package/dist/chunk-ICIYSJBQ.js.map +0 -1
  377. package/dist/chunk-ID745F3R.js +0 -625
  378. package/dist/chunk-ID745F3R.js.map +0 -1
  379. package/dist/chunk-K4VOEYOR.js +0 -21
  380. package/dist/chunk-K4VOEYOR.js.map +0 -1
  381. package/dist/chunk-MF54ZHWT.js.map +0 -1
  382. package/dist/chunk-N5M2EISA.js.map +0 -1
  383. package/dist/chunk-NDF24LYP.js.map +0 -1
  384. package/dist/chunk-NJV5SLEK.js.map +0 -1
  385. package/dist/chunk-NR7H7ZJP.js +0 -400
  386. package/dist/chunk-NR7H7ZJP.js.map +0 -1
  387. package/dist/chunk-P23WJCH2.js.map +0 -1
  388. package/dist/chunk-PMECEZK3.js.map +0 -1
  389. package/dist/chunk-PNOGX36L.js.map +0 -1
  390. package/dist/chunk-POQ6PGNE.js.map +0 -1
  391. package/dist/chunk-SHQMPGOL.js.map +0 -1
  392. package/dist/chunk-TVAR4JHA.js.map +0 -1
  393. package/dist/chunk-VRLKHL74.js.map +0 -1
  394. package/dist/chunk-WI4T3KIS.js.map +0 -1
  395. package/dist/chunk-XTVSNWLL.js.map +0 -1
  396. package/dist/library-publish-DI4Q5UOG.js.map +0 -1
  397. package/dist/open-library-N6ESO6IK.js +0 -40
  398. package/dist/open-registry-CBZ5MWTT.js +0 -32
  399. package/dist/paths-U6W6MQNQ.js +0 -22
  400. package/dist/plugin-store-XMZSPVBF.js.map +0 -1
  401. package/dist/project-UP52HEHC.js +0 -79
  402. package/dist/serve-preflight-6P2JJEJ3.js +0 -47
  403. package/dist/serve-preflight-6P2JJEJ3.js.map +0 -1
  404. package/dist/setup-5IRUH5OS.js.map +0 -1
  405. package/dist/skills-HA36RFNM.js +0 -26
  406. package/dist/source-DX5SGWEI.js +0 -41
  407. package/dist/source-manifest-publish-NMRLXWVW.js.map +0 -1
@@ -0,0 +1,1336 @@
1
+ import { selectableEntries, entryModelIds, entrySurface, entryBaseUrl } from './chunk-IQVZIVSA.js';
2
+ import { entryCredentialValue } from './chunk-6VIVUBNN.js';
3
+ import { parseModelRef } from './chunk-MJHSLODD.js';
4
+ import { createHash, timingSafeEqual, randomUUID } from 'crypto';
5
+ import { createServer } from 'http';
6
+
7
+ // model-endpoint/src/types.ts
8
+ var ModelEndpointError = class extends Error {
9
+ status;
10
+ type;
11
+ code;
12
+ constructor(status, message, code, type) {
13
+ super(message);
14
+ this.name = "ModelEndpointError";
15
+ this.status = status;
16
+ this.type = type ?? defaultErrorType(status);
17
+ if (code !== void 0) this.code = code;
18
+ }
19
+ };
20
+ function defaultErrorType(status) {
21
+ if (status === 401 || status === 403) return "authentication_error";
22
+ if (status === 404) return "not_found_error";
23
+ if (status === 502 || status === 503 || status === 504) return "upstream_error";
24
+ if (status >= 500 && status !== 501) return "server_error";
25
+ return "invalid_request_error";
26
+ }
27
+
28
+ // model-endpoint/src/resolve.ts
29
+ var DEFAULT_CONTEXT_WINDOW = 128e3;
30
+ var DEFAULT_MAX_TOKENS = 8192;
31
+ var KEYLESS_PLACEHOLDER = "unused";
32
+ function piBaseUrl(_surface, registryBaseUrl) {
33
+ return registryBaseUrl.replace(/\/+$/, "");
34
+ }
35
+ function resolveModel(selector, deps) {
36
+ const ref = parseModelRef(selector, deps.registry, deps.roles);
37
+ if (!ref || ref.modelId === void 0) {
38
+ throw new ModelEndpointError(404, `model '${selector}' not found`, "model_not_found");
39
+ }
40
+ const found = selectableEntries(deps.registry).find(([id]) => id === ref.providerId);
41
+ if (!found) {
42
+ throw new ModelEndpointError(404, `model '${selector}' not found`, "model_not_found");
43
+ }
44
+ const [providerId, entry] = found;
45
+ const logicalId = ref.modelId;
46
+ const declared = entryModelIds(entry);
47
+ if (declared.length > 0 && !declared.some(([id]) => id === logicalId)) {
48
+ throw new ModelEndpointError(
49
+ 404,
50
+ `model '${logicalId}' is not declared by provider '${providerId}'`,
51
+ "model_not_found"
52
+ );
53
+ }
54
+ const surface = entrySurface(entry);
55
+ const baseUrl = entryBaseUrl(entry);
56
+ if (!surface || !baseUrl) {
57
+ throw new ModelEndpointError(
58
+ 502,
59
+ `provider '${providerId}' is incomplete: it needs a surface and a base_url`,
60
+ "provider_incomplete"
61
+ );
62
+ }
63
+ const providerModelId = ref.providerModelId ?? logicalId;
64
+ const caps = entry.capabilities?.[logicalId];
65
+ const model = {
66
+ id: providerModelId,
67
+ name: logicalId,
68
+ api: surface,
69
+ provider: providerId,
70
+ baseUrl: piBaseUrl(surface, baseUrl),
71
+ input: caps?.images === false ? ["text"] : ["text", "image"],
72
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
73
+ reasoning: true,
74
+ contextWindow: caps?.context_window ?? DEFAULT_CONTEXT_WINDOW,
75
+ maxTokens: DEFAULT_MAX_TOKENS,
76
+ ...entry.headers ? { headers: entry.headers } : {}
77
+ };
78
+ const apiKey = entryCredentialValue(providerId, entry, { env: deps.lookupEnv, allowCommand: false }) ?? (isKeyless(entry) ? KEYLESS_PLACEHOLDER : void 0);
79
+ return {
80
+ providerId,
81
+ logicalId,
82
+ model,
83
+ ...apiKey !== void 0 ? { apiKey } : {},
84
+ ...entry.headers ? { headers: entry.headers } : {}
85
+ };
86
+ }
87
+ function isKeyless(entry) {
88
+ return !entry.preset && (!entry.credential || entry.credential.kind === "none");
89
+ }
90
+ function listModels(registry) {
91
+ return selectableEntries(registry).flatMap(
92
+ ([providerId, entry]) => entryModelIds(entry).map(([logicalId]) => ({
93
+ id: `${providerId}/${logicalId}`,
94
+ owned_by: providerId
95
+ }))
96
+ );
97
+ }
98
+
99
+ // model-endpoint/src/openai-shared.ts
100
+ var THINKING_LEVELS = [
101
+ "minimal",
102
+ "low",
103
+ "medium",
104
+ "high",
105
+ "xhigh",
106
+ "max"
107
+ ];
108
+ function badRequest(message) {
109
+ return new ModelEndpointError(400, message);
110
+ }
111
+ function isRecord(value) {
112
+ return typeof value === "object" && value !== null && !Array.isArray(value);
113
+ }
114
+ function requireModel(body) {
115
+ if (typeof body.model !== "string" || body.model.length === 0) {
116
+ throw badRequest("model is required");
117
+ }
118
+ return body.model;
119
+ }
120
+ function optionalBoolean(value, field) {
121
+ if (value === void 0 || value === null) return false;
122
+ if (typeof value !== "boolean") throw badRequest(`${field} must be a boolean`);
123
+ return value;
124
+ }
125
+ function optionalNumber(value, field) {
126
+ if (value === void 0 || value === null) return void 0;
127
+ if (typeof value !== "number" || !Number.isFinite(value))
128
+ throw badRequest(`${field} must be a number`);
129
+ return value;
130
+ }
131
+ function optionalPositiveInt(value, field) {
132
+ const n = optionalNumber(value, field);
133
+ if (n === void 0) return void 0;
134
+ if (!Number.isInteger(n) || n <= 0) throw badRequest(`${field} must be a positive integer`);
135
+ return n;
136
+ }
137
+ function isThinkingLevel(value) {
138
+ return THINKING_LEVELS.includes(value);
139
+ }
140
+ function parseReasoningEffort(value, field) {
141
+ if (value === void 0 || value === null || value === "none") return void 0;
142
+ if (typeof value === "string" && isThinkingLevel(value)) return value;
143
+ throw badRequest(`${field} must be one of none, ${THINKING_LEVELS.join(", ")}`);
144
+ }
145
+ function pickSamplingParams(body, keys) {
146
+ const picked = {};
147
+ for (const key of keys) {
148
+ const value = body[key];
149
+ if (value === void 0 || value === null) continue;
150
+ const ok = typeof value === "string" || typeof value === "number" && Number.isFinite(value) || Array.isArray(value) && value.every((v) => typeof v === "string");
151
+ if (!ok) throw badRequest(`${key} has an unsupported type`);
152
+ picked[key] = value;
153
+ }
154
+ return Object.keys(picked).length > 0 ? picked : void 0;
155
+ }
156
+ function buildOptions(parts) {
157
+ const options = {};
158
+ if (parts.temperature !== void 0) options.temperature = parts.temperature;
159
+ if (parts.maxTokens !== void 0) options.maxTokens = parts.maxTokens;
160
+ if (parts.samplingParams !== void 0) options.samplingParams = parts.samplingParams;
161
+ if (parts.reasoning !== void 0) options.reasoning = parts.reasoning;
162
+ return options;
163
+ }
164
+ var DATA_URL = /^data:([^;,]+)(?:;[^;,]*)*;base64,(.*)$/s;
165
+ function imageFromUrl(url, field) {
166
+ if (typeof url !== "string" || url.length === 0)
167
+ throw badRequest(`${field} must be a non-empty string`);
168
+ const match = DATA_URL.exec(url);
169
+ if (!match) {
170
+ throw badRequest(
171
+ `${field}: only base64 data: image URLs are supported; http(s) image URLs are not fetched`
172
+ );
173
+ }
174
+ const mimeType = match[1];
175
+ if (!mimeType.startsWith("image/"))
176
+ throw badRequest(`${field}: data URL is not an image (${mimeType})`);
177
+ return { type: "image", data: match[2], mimeType };
178
+ }
179
+ function parseToolArguments(value) {
180
+ if (isRecord(value)) return value;
181
+ if (typeof value !== "string" || value.trim().length === 0) return {};
182
+ try {
183
+ const parsed = JSON.parse(value);
184
+ return isRecord(parsed) ? parsed : {};
185
+ } catch {
186
+ return {};
187
+ }
188
+ }
189
+ var DEFAULT_TOOL_PARAMETERS = { type: "object", properties: {} };
190
+ function toPiTool(name, description, parameters) {
191
+ return {
192
+ name,
193
+ description: typeof description === "string" ? description : "",
194
+ parameters: isRecord(parameters) ? parameters : DEFAULT_TOOL_PARAMETERS
195
+ };
196
+ }
197
+ function selectTools(tools, choice, forcedName) {
198
+ if (choice === void 0 || choice === null || choice === "auto" || choice === "required")
199
+ return tools;
200
+ if (choice === "none") return [];
201
+ if (isRecord(choice)) {
202
+ const name = forcedName(choice);
203
+ const matched = tools.filter((tool) => tool.name === name);
204
+ if (typeof name !== "string" || matched.length === 0) {
205
+ throw badRequest("tool_choice references an unknown function");
206
+ }
207
+ return matched;
208
+ }
209
+ throw badRequest("tool_choice is not supported");
210
+ }
211
+ function buildContext(systemParts, messages, tools) {
212
+ const context = { messages };
213
+ if (systemParts.length > 0) context.systemPrompt = systemParts.join("\n\n");
214
+ if (tools.length > 0) context.tools = tools;
215
+ return context;
216
+ }
217
+ function emptyUsage() {
218
+ return {
219
+ input: 0,
220
+ output: 0,
221
+ cacheRead: 0,
222
+ cacheWrite: 0,
223
+ totalTokens: 0,
224
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 }
225
+ };
226
+ }
227
+ function promptTokens(usage) {
228
+ return usage.input + usage.cacheRead + usage.cacheWrite;
229
+ }
230
+ function totalTokens(usage) {
231
+ return usage.totalTokens > 0 ? usage.totalTokens : promptTokens(usage) + usage.output;
232
+ }
233
+ function historyAssistant(model, content) {
234
+ return {
235
+ role: "assistant",
236
+ content,
237
+ api: "openai-completions",
238
+ provider: "openai",
239
+ model,
240
+ usage: emptyUsage(),
241
+ stopReason: content.some((block) => block.type === "toolCall") ? "toolUse" : "stop",
242
+ timestamp: Date.now()
243
+ };
244
+ }
245
+ function historyToolResult(toolCallId, toolName, text) {
246
+ return {
247
+ role: "toolResult",
248
+ toolCallId,
249
+ toolName,
250
+ content: [{ type: "text", text }],
251
+ isError: false,
252
+ timestamp: Date.now()
253
+ };
254
+ }
255
+
256
+ // model-endpoint/src/openai-chat.ts
257
+ function textOfParts(content, field, allowed) {
258
+ if (content === void 0 || content === null) return "";
259
+ if (typeof content === "string") return content;
260
+ if (!Array.isArray(content))
261
+ throw badRequest(`${field} must be a string or an array of text parts`);
262
+ let text = "";
263
+ for (let i = 0; i < content.length; i++) {
264
+ const part = content[i];
265
+ if (!isRecord(part) || typeof part.type !== "string" || !allowed.includes(part.type)) {
266
+ throw badRequest(`${field}[${i}]: unsupported content part`);
267
+ }
268
+ const value = part.type === "refusal" ? part.refusal : part.text;
269
+ if (typeof value !== "string")
270
+ throw badRequest(
271
+ `${field}[${i}].${part.type === "refusal" ? "refusal" : "text"} must be a string`
272
+ );
273
+ text += value;
274
+ }
275
+ return text;
276
+ }
277
+ function parseUserContent(content, field) {
278
+ if (typeof content === "string") return content;
279
+ if (!Array.isArray(content))
280
+ throw badRequest(`${field} must be a string or an array of content parts`);
281
+ const parts = [];
282
+ for (let i = 0; i < content.length; i++) {
283
+ const part = content[i];
284
+ const partField = `${field}[${i}]`;
285
+ if (!isRecord(part)) throw badRequest(`${partField} must be an object`);
286
+ if (part.type === "text") {
287
+ if (typeof part.text !== "string") throw badRequest(`${partField}.text must be a string`);
288
+ parts.push({ type: "text", text: part.text });
289
+ } else if (part.type === "image_url") {
290
+ const url = isRecord(part.image_url) ? part.image_url.url : part.image_url;
291
+ parts.push(imageFromUrl(url, `${partField}.image_url.url`));
292
+ } else {
293
+ throw badRequest(`${partField}: unsupported content part type "${String(part.type)}"`);
294
+ }
295
+ }
296
+ return parts;
297
+ }
298
+ function parseAssistantMessage(raw, field, model, toolNames) {
299
+ const blocks = [];
300
+ const text = textOfParts(raw.content, `${field}.content`, ["text", "refusal"]);
301
+ if (text.length > 0) blocks.push({ type: "text", text });
302
+ if (raw.tool_calls !== void 0 && raw.tool_calls !== null) {
303
+ if (!Array.isArray(raw.tool_calls)) throw badRequest(`${field}.tool_calls must be an array`);
304
+ for (let i = 0; i < raw.tool_calls.length; i++) {
305
+ const call = raw.tool_calls[i];
306
+ const callField = `${field}.tool_calls[${i}]`;
307
+ if (!isRecord(call) || !isRecord(call.function))
308
+ throw badRequest(`${callField} must be a function tool call`);
309
+ if (call.type !== void 0 && call.type !== "function")
310
+ throw badRequest(`${callField}.type must be "function"`);
311
+ if (typeof call.id !== "string" || call.id.length === 0)
312
+ throw badRequest(`${callField}.id is required`);
313
+ if (typeof call.function.name !== "string" || call.function.name.length === 0) {
314
+ throw badRequest(`${callField}.function.name is required`);
315
+ }
316
+ toolNames.set(call.id, call.function.name);
317
+ blocks.push({
318
+ type: "toolCall",
319
+ id: call.id,
320
+ name: call.function.name,
321
+ arguments: parseToolArguments(call.function.arguments)
322
+ });
323
+ }
324
+ }
325
+ return blocks.length > 0 ? historyAssistant(model, blocks) : void 0;
326
+ }
327
+ function parseTools(value) {
328
+ if (value === void 0 || value === null) return [];
329
+ if (!Array.isArray(value)) throw badRequest("tools must be an array");
330
+ const tools = [];
331
+ for (let i = 0; i < value.length; i++) {
332
+ const tool = value[i];
333
+ if (!isRecord(tool) || tool.type !== "function" || !isRecord(tool.function)) {
334
+ throw badRequest(`tools[${i}] must be {type:"function", function:{...}}`);
335
+ }
336
+ const fn = tool.function;
337
+ if (typeof fn.name !== "string" || fn.name.length === 0)
338
+ throw badRequest(`tools[${i}].function.name is required`);
339
+ tools.push(toPiTool(fn.name, fn.description, fn.parameters));
340
+ }
341
+ return tools;
342
+ }
343
+ function parseChatCompletionRequest(body) {
344
+ if (!isRecord(body)) throw badRequest("request body must be a JSON object");
345
+ const model = requireModel(body);
346
+ if (!Array.isArray(body.messages) || body.messages.length === 0) {
347
+ throw badRequest("messages must be a non-empty array");
348
+ }
349
+ if (body.n !== void 0 && body.n !== null && body.n !== 1) {
350
+ throw badRequest("n must be 1; multiple choices are not supported");
351
+ }
352
+ const systemParts = [];
353
+ const messages = [];
354
+ const toolNames = /* @__PURE__ */ new Map();
355
+ for (let i = 0; i < body.messages.length; i++) {
356
+ const raw = body.messages[i];
357
+ const field = `messages[${i}]`;
358
+ if (!isRecord(raw)) throw badRequest(`${field} must be an object`);
359
+ switch (raw.role) {
360
+ case "system":
361
+ case "developer": {
362
+ const text = textOfParts(raw.content, `${field}.content`, ["text"]);
363
+ if (text.length > 0) systemParts.push(text);
364
+ break;
365
+ }
366
+ case "user":
367
+ messages.push({
368
+ role: "user",
369
+ content: parseUserContent(raw.content, `${field}.content`),
370
+ timestamp: Date.now()
371
+ });
372
+ break;
373
+ case "assistant": {
374
+ const assistant = parseAssistantMessage(raw, field, model, toolNames);
375
+ if (assistant) messages.push(assistant);
376
+ break;
377
+ }
378
+ case "tool": {
379
+ if (typeof raw.tool_call_id !== "string" || raw.tool_call_id.length === 0) {
380
+ throw badRequest(`${field}.tool_call_id is required`);
381
+ }
382
+ const text = textOfParts(raw.content, `${field}.content`, ["text"]);
383
+ messages.push(
384
+ historyToolResult(raw.tool_call_id, toolNames.get(raw.tool_call_id) ?? "", text)
385
+ );
386
+ break;
387
+ }
388
+ default:
389
+ throw badRequest(`${field}.role "${String(raw.role)}" is not supported`);
390
+ }
391
+ }
392
+ const tools = selectTools(
393
+ parseTools(body.tools),
394
+ body.tool_choice,
395
+ (choice) => choice.type === "function" && isRecord(choice.function) ? choice.function.name : void 0
396
+ );
397
+ const options = buildOptions({
398
+ temperature: optionalNumber(body.temperature, "temperature"),
399
+ maxTokens: optionalPositiveInt(
400
+ body.max_completion_tokens ?? body.max_tokens,
401
+ "max_completion_tokens"
402
+ ),
403
+ samplingParams: pickSamplingParams(body, [
404
+ "top_p",
405
+ "frequency_penalty",
406
+ "presence_penalty",
407
+ "seed",
408
+ "stop"
409
+ ]),
410
+ reasoning: parseReasoningEffort(body.reasoning_effort, "reasoning_effort")
411
+ });
412
+ return {
413
+ model,
414
+ context: buildContext(systemParts, messages, tools),
415
+ options,
416
+ stream: optionalBoolean(body.stream, "stream"),
417
+ includeUsage: isRecord(body.stream_options) && body.stream_options.include_usage === true
418
+ };
419
+ }
420
+ function finishReason(stopReason, errorMessage) {
421
+ switch (stopReason) {
422
+ case "length":
423
+ return "length";
424
+ case "toolUse":
425
+ return "tool_calls";
426
+ case "error":
427
+ case "aborted":
428
+ throw new ModelEndpointError(502, errorMessage ?? `upstream request ${stopReason}`);
429
+ default:
430
+ return "stop";
431
+ }
432
+ }
433
+ function toChatUsage(usage) {
434
+ const prompt = promptTokens(usage);
435
+ const result = {
436
+ prompt_tokens: prompt,
437
+ completion_tokens: usage.output,
438
+ total_tokens: totalTokens(usage),
439
+ prompt_tokens_details: { cached_tokens: usage.cacheRead }
440
+ };
441
+ if (usage.reasoning !== void 0)
442
+ result.completion_tokens_details = { reasoning_tokens: usage.reasoning };
443
+ return result;
444
+ }
445
+ function toChatCompletion(message, meta) {
446
+ const reason = finishReason(message.stopReason, message.errorMessage);
447
+ let text = "";
448
+ let thinking = "";
449
+ const toolCalls = [];
450
+ for (const block of message.content) {
451
+ if (block.type === "text") text += block.text;
452
+ else if (block.type === "thinking") thinking += block.thinking;
453
+ else {
454
+ toolCalls.push({
455
+ id: block.id,
456
+ type: "function",
457
+ function: { name: block.name, arguments: JSON.stringify(block.arguments) }
458
+ });
459
+ }
460
+ }
461
+ const out = { role: "assistant", content: text.length > 0 ? text : null };
462
+ if (thinking.length > 0) out.reasoning_content = thinking;
463
+ if (toolCalls.length > 0) out.tool_calls = toolCalls;
464
+ return {
465
+ id: meta.id,
466
+ object: "chat.completion",
467
+ created: meta.created,
468
+ model: meta.model,
469
+ choices: [{ index: 0, message: out, finish_reason: reason }],
470
+ usage: toChatUsage(message.usage)
471
+ };
472
+ }
473
+ function createChatStreamState(init) {
474
+ return { ...init, nextToolIndex: 0, toolIndexByContent: /* @__PURE__ */ new Map() };
475
+ }
476
+ function chunk(state, delta, finish = null) {
477
+ return {
478
+ id: state.id,
479
+ object: "chat.completion.chunk",
480
+ created: state.created,
481
+ model: state.model,
482
+ choices: [{ index: 0, delta, finish_reason: finish }]
483
+ };
484
+ }
485
+ function chatCompletionChunks(event, state) {
486
+ switch (event.type) {
487
+ case "start":
488
+ return [chunk(state, { role: "assistant", content: "" })];
489
+ case "text_delta":
490
+ return event.delta.length > 0 ? [chunk(state, { content: event.delta })] : [];
491
+ case "thinking_delta":
492
+ return event.delta.length > 0 ? [chunk(state, { reasoning_content: event.delta })] : [];
493
+ case "toolcall_start":
494
+ state.toolIndexByContent.set(event.contentIndex, state.nextToolIndex++);
495
+ return [];
496
+ case "toolcall_end": {
497
+ let index = state.toolIndexByContent.get(event.contentIndex);
498
+ if (index === void 0) {
499
+ index = state.nextToolIndex++;
500
+ state.toolIndexByContent.set(event.contentIndex, index);
501
+ }
502
+ return [
503
+ chunk(state, {
504
+ tool_calls: [
505
+ {
506
+ index,
507
+ id: event.toolCall.id,
508
+ type: "function",
509
+ function: {
510
+ name: event.toolCall.name,
511
+ arguments: JSON.stringify(event.toolCall.arguments)
512
+ }
513
+ }
514
+ ]
515
+ })
516
+ ];
517
+ }
518
+ case "done": {
519
+ const chunks = [chunk(state, {}, finishReason(event.reason, void 0))];
520
+ if (state.includeUsage) {
521
+ chunks.push({
522
+ id: state.id,
523
+ object: "chat.completion.chunk",
524
+ created: state.created,
525
+ model: state.model,
526
+ choices: [],
527
+ usage: toChatUsage(event.message.usage)
528
+ });
529
+ }
530
+ return chunks;
531
+ }
532
+ case "error":
533
+ state.error = event.error.errorMessage ?? `upstream request ${event.reason}`;
534
+ return [];
535
+ default:
536
+ return [];
537
+ }
538
+ }
539
+
540
+ // model-endpoint/src/openai-responses.ts
541
+ function parseParts(content, field, role) {
542
+ if (typeof content === "string") return content;
543
+ if (!Array.isArray(content))
544
+ throw badRequest(`${field} must be a string or an array of content parts`);
545
+ const textTypes = role === "assistant" ? ["output_text", "text"] : ["input_text", "text"];
546
+ const parts = [];
547
+ for (let i = 0; i < content.length; i++) {
548
+ const part = content[i];
549
+ const partField = `${field}[${i}]`;
550
+ if (!isRecord(part) || typeof part.type !== "string")
551
+ throw badRequest(`${partField} must be a content part`);
552
+ if (textTypes.includes(part.type)) {
553
+ if (typeof part.text !== "string") throw badRequest(`${partField}.text must be a string`);
554
+ parts.push({ type: "text", text: part.text });
555
+ } else if (part.type === "refusal" && role === "assistant" && typeof part.refusal === "string") {
556
+ parts.push({ type: "text", text: part.refusal });
557
+ } else if (part.type === "input_image" && role === "user") {
558
+ if (part.file_id !== void 0 && part.file_id !== null)
559
+ throw badRequest(`${partField}.file_id is not supported`);
560
+ const url = isRecord(part.image_url) ? part.image_url.url : part.image_url;
561
+ parts.push(imageFromUrl(url, `${partField}.image_url`));
562
+ } else {
563
+ throw badRequest(`${partField}: unsupported content part type "${part.type}"`);
564
+ }
565
+ }
566
+ return parts;
567
+ }
568
+ function joinText(parts) {
569
+ if (typeof parts === "string") return parts;
570
+ return parts.map((part) => part.type === "text" ? part.text : "").join("");
571
+ }
572
+ function parseOutputText(output, field) {
573
+ if (typeof output === "string") return output;
574
+ if (output === void 0 || output === null) return "";
575
+ return joinText(parseParts(output, field, "user"));
576
+ }
577
+ function parseInput(input, model, systemParts) {
578
+ if (typeof input === "string") return [{ role: "user", content: input, timestamp: Date.now() }];
579
+ if (!Array.isArray(input)) throw badRequest("input must be a string or an array of items");
580
+ const messages = [];
581
+ const toolNames = /* @__PURE__ */ new Map();
582
+ for (let i = 0; i < input.length; i++) {
583
+ const item = input[i];
584
+ const field = `input[${i}]`;
585
+ if (!isRecord(item)) throw badRequest(`${field} must be an object`);
586
+ const type = item.type ?? "message";
587
+ switch (type) {
588
+ case "message": {
589
+ const role = item.role;
590
+ if (role === "system" || role === "developer") {
591
+ const text = joinText(parseParts(item.content, `${field}.content`, "system"));
592
+ if (text.length > 0) systemParts.push(text);
593
+ } else if (role === "user") {
594
+ messages.push({
595
+ role: "user",
596
+ content: parseParts(item.content, `${field}.content`, "user"),
597
+ timestamp: Date.now()
598
+ });
599
+ } else if (role === "assistant") {
600
+ const text = joinText(parseParts(item.content, `${field}.content`, "assistant"));
601
+ if (text.length > 0) messages.push(historyAssistant(model, [{ type: "text", text }]));
602
+ } else {
603
+ throw badRequest(`${field}.role "${String(role)}" is not supported`);
604
+ }
605
+ break;
606
+ }
607
+ case "function_call": {
608
+ if (typeof item.call_id !== "string" || item.call_id.length === 0)
609
+ throw badRequest(`${field}.call_id is required`);
610
+ if (typeof item.name !== "string" || item.name.length === 0)
611
+ throw badRequest(`${field}.name is required`);
612
+ toolNames.set(item.call_id, item.name);
613
+ const call = {
614
+ type: "toolCall",
615
+ id: item.call_id,
616
+ name: item.name,
617
+ arguments: parseToolArguments(item.arguments)
618
+ };
619
+ const last = messages.at(-1);
620
+ if (last?.role === "assistant") {
621
+ last.content.push(call);
622
+ last.stopReason = "toolUse";
623
+ } else {
624
+ messages.push(historyAssistant(model, [call]));
625
+ }
626
+ break;
627
+ }
628
+ case "function_call_output": {
629
+ if (typeof item.call_id !== "string" || item.call_id.length === 0)
630
+ throw badRequest(`${field}.call_id is required`);
631
+ messages.push(
632
+ historyToolResult(
633
+ item.call_id,
634
+ toolNames.get(item.call_id) ?? "",
635
+ parseOutputText(item.output, `${field}.output`)
636
+ )
637
+ );
638
+ break;
639
+ }
640
+ case "reasoning":
641
+ break;
642
+ default:
643
+ throw badRequest(`${field}.type "${String(type)}" is not supported`);
644
+ }
645
+ }
646
+ return messages;
647
+ }
648
+ function parseTools2(value) {
649
+ if (value === void 0 || value === null) return [];
650
+ if (!Array.isArray(value)) throw badRequest("tools must be an array");
651
+ const tools = [];
652
+ for (let i = 0; i < value.length; i++) {
653
+ const tool = value[i];
654
+ if (!isRecord(tool) || tool.type !== "function") {
655
+ throw badRequest(`tools[${i}]: only function tools are supported`);
656
+ }
657
+ if (typeof tool.name !== "string" || tool.name.length === 0)
658
+ throw badRequest(`tools[${i}].name is required`);
659
+ tools.push(toPiTool(tool.name, tool.description, tool.parameters));
660
+ }
661
+ return tools;
662
+ }
663
+ function parseResponsesRequest(body) {
664
+ if (!isRecord(body)) throw badRequest("request body must be a JSON object");
665
+ const model = requireModel(body);
666
+ if (body.input === void 0 || body.input === null) throw badRequest("input is required");
667
+ if (body.previous_response_id !== void 0 && body.previous_response_id !== null) {
668
+ throw badRequest("previous_response_id is not supported; the endpoint is stateless");
669
+ }
670
+ const systemParts = [];
671
+ if (body.instructions !== void 0 && body.instructions !== null) {
672
+ if (typeof body.instructions !== "string") throw badRequest("instructions must be a string");
673
+ if (body.instructions.length > 0) systemParts.push(body.instructions);
674
+ }
675
+ const messages = parseInput(body.input, model, systemParts);
676
+ if (messages.length === 0) throw badRequest("input must contain at least one message");
677
+ const tools = selectTools(
678
+ parseTools2(body.tools),
679
+ body.tool_choice,
680
+ (choice) => choice.type === "function" ? choice.name : void 0
681
+ );
682
+ const reasoning = isRecord(body.reasoning) ? body.reasoning.effort : void 0;
683
+ const options = buildOptions({
684
+ temperature: optionalNumber(body.temperature, "temperature"),
685
+ maxTokens: optionalPositiveInt(body.max_output_tokens, "max_output_tokens"),
686
+ samplingParams: pickSamplingParams(body, ["top_p"]),
687
+ reasoning: parseReasoningEffort(reasoning, "reasoning.effort")
688
+ });
689
+ return {
690
+ model,
691
+ context: buildContext(systemParts, messages, tools),
692
+ options,
693
+ stream: optionalBoolean(body.stream, "stream"),
694
+ includeUsage: true
695
+ };
696
+ }
697
+ function itemId(prefix, responseId, index) {
698
+ return `${prefix}_${responseId.replace(/^resp_/, "")}_${index}`;
699
+ }
700
+ function toResponseUsage(usage) {
701
+ return {
702
+ input_tokens: promptTokens(usage),
703
+ output_tokens: usage.output,
704
+ total_tokens: totalTokens(usage),
705
+ input_tokens_details: { cached_tokens: usage.cacheRead },
706
+ output_tokens_details: { reasoning_tokens: usage.reasoning ?? 0 }
707
+ };
708
+ }
709
+ function messageItem(id, text, status) {
710
+ return {
711
+ type: "message",
712
+ id,
713
+ role: "assistant",
714
+ status,
715
+ content: status === "completed" ? [{ type: "output_text", text, annotations: [] }] : []
716
+ };
717
+ }
718
+ function buildOutput(message, responseId) {
719
+ const output = [];
720
+ const summaries = [];
721
+ let text = "";
722
+ const calls = [];
723
+ for (const block of message.content) {
724
+ if (block.type === "thinking") {
725
+ if (block.thinking.length > 0) summaries.push({ type: "summary_text", text: block.thinking });
726
+ } else if (block.type === "text") {
727
+ text += block.text;
728
+ } else {
729
+ calls.push({
730
+ type: "function_call",
731
+ id: "",
732
+ call_id: block.id,
733
+ name: block.name,
734
+ arguments: JSON.stringify(block.arguments),
735
+ status: "completed"
736
+ });
737
+ }
738
+ }
739
+ if (summaries.length > 0) {
740
+ output.push({
741
+ type: "reasoning",
742
+ id: itemId("rs", responseId, output.length),
743
+ summary: summaries
744
+ });
745
+ }
746
+ if (text.length > 0) {
747
+ output.push(messageItem(itemId("msg", responseId, output.length), text, "completed"));
748
+ }
749
+ for (const call of calls) {
750
+ call.id = itemId("fc", responseId, output.length);
751
+ output.push(call);
752
+ }
753
+ return output;
754
+ }
755
+ function responseObject(meta, status, output, usage) {
756
+ return {
757
+ id: meta.id,
758
+ object: "response",
759
+ created_at: meta.created,
760
+ model: meta.model,
761
+ status,
762
+ incomplete_details: status === "incomplete" ? { reason: "max_output_tokens" } : null,
763
+ error: null,
764
+ output,
765
+ usage: usage ? toResponseUsage(usage) : null
766
+ };
767
+ }
768
+ function toResponse(message, meta) {
769
+ if (message.stopReason === "error" || message.stopReason === "aborted") {
770
+ throw new ModelEndpointError(
771
+ 502,
772
+ message.errorMessage ?? `upstream request ${message.stopReason}`
773
+ );
774
+ }
775
+ const status = message.stopReason === "length" ? "incomplete" : "completed";
776
+ return responseObject(meta, status, buildOutput(message, meta.id), message.usage);
777
+ }
778
+ function createResponsesStreamState(init) {
779
+ return {
780
+ ...init,
781
+ sequence: 0,
782
+ nextOutputIndex: 0,
783
+ open: /* @__PURE__ */ new Map(),
784
+ completed: /* @__PURE__ */ new Map()
785
+ };
786
+ }
787
+ function ev(state, type, fields) {
788
+ return { type, sequence_number: state.sequence++, ...fields };
789
+ }
790
+ function openBlock(state, contentIndex, kind) {
791
+ const existing = state.open.get(contentIndex);
792
+ if (existing) return { block: existing, events: [] };
793
+ const outputIndex = state.nextOutputIndex++;
794
+ const block = {
795
+ kind,
796
+ outputIndex,
797
+ itemId: itemId(kind === "message" ? "msg" : "rs", state.id, outputIndex),
798
+ text: ""
799
+ };
800
+ state.open.set(contentIndex, block);
801
+ if (kind === "message") {
802
+ return {
803
+ block,
804
+ events: [
805
+ ev(state, "response.output_item.added", {
806
+ output_index: outputIndex,
807
+ item: messageItem(block.itemId, "", "in_progress")
808
+ }),
809
+ ev(state, "response.content_part.added", {
810
+ item_id: block.itemId,
811
+ output_index: outputIndex,
812
+ content_index: 0,
813
+ part: { type: "output_text", text: "", annotations: [] }
814
+ })
815
+ ]
816
+ };
817
+ }
818
+ return {
819
+ block,
820
+ events: [
821
+ ev(state, "response.output_item.added", {
822
+ output_index: outputIndex,
823
+ item: { type: "reasoning", id: block.itemId, summary: [] }
824
+ }),
825
+ ev(state, "response.reasoning_summary_part.added", {
826
+ item_id: block.itemId,
827
+ output_index: outputIndex,
828
+ summary_index: 0,
829
+ part: { type: "summary_text", text: "" }
830
+ })
831
+ ]
832
+ };
833
+ }
834
+ function closeBlock(state, contentIndex, kind, finalText) {
835
+ const { block, events } = openBlock(state, contentIndex, kind);
836
+ state.open.delete(contentIndex);
837
+ if (kind === "message") {
838
+ const item2 = messageItem(block.itemId, finalText, "completed");
839
+ state.completed.set(block.outputIndex, item2);
840
+ events.push(
841
+ ev(state, "response.output_text.done", {
842
+ item_id: block.itemId,
843
+ output_index: block.outputIndex,
844
+ content_index: 0,
845
+ text: finalText
846
+ }),
847
+ ev(state, "response.content_part.done", {
848
+ item_id: block.itemId,
849
+ output_index: block.outputIndex,
850
+ content_index: 0,
851
+ part: { type: "output_text", text: finalText, annotations: [] }
852
+ }),
853
+ ev(state, "response.output_item.done", { output_index: block.outputIndex, item: item2 })
854
+ );
855
+ return events;
856
+ }
857
+ const part = { type: "summary_text", text: finalText };
858
+ const item = { type: "reasoning", id: block.itemId, summary: [part] };
859
+ state.completed.set(block.outputIndex, item);
860
+ events.push(
861
+ ev(state, "response.reasoning_summary_text.done", {
862
+ item_id: block.itemId,
863
+ output_index: block.outputIndex,
864
+ summary_index: 0,
865
+ text: finalText
866
+ }),
867
+ ev(state, "response.reasoning_summary_part.done", {
868
+ item_id: block.itemId,
869
+ output_index: block.outputIndex,
870
+ summary_index: 0,
871
+ part
872
+ }),
873
+ ev(state, "response.output_item.done", { output_index: block.outputIndex, item })
874
+ );
875
+ return events;
876
+ }
877
+ function responsesEvents(event, state) {
878
+ const meta = { id: state.id, created: state.created, model: state.model };
879
+ switch (event.type) {
880
+ case "start": {
881
+ const response = responseObject(meta, "in_progress", [], void 0);
882
+ return [
883
+ ev(state, "response.created", { response }),
884
+ ev(state, "response.in_progress", { response })
885
+ ];
886
+ }
887
+ case "text_start":
888
+ return openBlock(state, event.contentIndex, "message").events;
889
+ case "text_delta": {
890
+ const { block, events } = openBlock(state, event.contentIndex, "message");
891
+ block.text += event.delta;
892
+ events.push(
893
+ ev(state, "response.output_text.delta", {
894
+ item_id: block.itemId,
895
+ output_index: block.outputIndex,
896
+ content_index: 0,
897
+ delta: event.delta
898
+ })
899
+ );
900
+ return events;
901
+ }
902
+ case "text_end":
903
+ return closeBlock(state, event.contentIndex, "message", event.content);
904
+ case "thinking_start":
905
+ return openBlock(state, event.contentIndex, "reasoning").events;
906
+ case "thinking_delta": {
907
+ const { block, events } = openBlock(state, event.contentIndex, "reasoning");
908
+ block.text += event.delta;
909
+ events.push(
910
+ ev(state, "response.reasoning_summary_text.delta", {
911
+ item_id: block.itemId,
912
+ output_index: block.outputIndex,
913
+ summary_index: 0,
914
+ delta: event.delta
915
+ })
916
+ );
917
+ return events;
918
+ }
919
+ case "thinking_end":
920
+ return closeBlock(state, event.contentIndex, "reasoning", event.content);
921
+ case "toolcall_end": {
922
+ const outputIndex = state.nextOutputIndex++;
923
+ const id = itemId("fc", state.id, outputIndex);
924
+ const args = JSON.stringify(event.toolCall.arguments);
925
+ const item = {
926
+ type: "function_call",
927
+ id,
928
+ call_id: event.toolCall.id,
929
+ name: event.toolCall.name,
930
+ arguments: args,
931
+ status: "completed"
932
+ };
933
+ state.completed.set(outputIndex, item);
934
+ return [
935
+ ev(state, "response.output_item.added", {
936
+ output_index: outputIndex,
937
+ item: { ...item, arguments: "", status: "in_progress" }
938
+ }),
939
+ ev(state, "response.function_call_arguments.delta", {
940
+ item_id: id,
941
+ output_index: outputIndex,
942
+ delta: args
943
+ }),
944
+ ev(state, "response.function_call_arguments.done", {
945
+ item_id: id,
946
+ output_index: outputIndex,
947
+ name: item.name,
948
+ arguments: args
949
+ }),
950
+ ev(state, "response.output_item.done", { output_index: outputIndex, item })
951
+ ];
952
+ }
953
+ case "done": {
954
+ const streamed = [...state.completed.entries()].sort(([a], [b]) => a - b).map(([, item]) => item);
955
+ const output = streamed.length > 0 ? streamed : buildOutput(event.message, state.id);
956
+ const incomplete = event.reason === "length";
957
+ const response = responseObject(
958
+ meta,
959
+ incomplete ? "incomplete" : "completed",
960
+ output,
961
+ event.message.usage
962
+ );
963
+ return [ev(state, incomplete ? "response.incomplete" : "response.completed", { response })];
964
+ }
965
+ case "error":
966
+ state.error = event.error.errorMessage ?? `upstream request ${event.reason}`;
967
+ return [];
968
+ default:
969
+ return [];
970
+ }
971
+ }
972
+
973
+ // model-endpoint/src/server.ts
974
+ var MAX_BODY_BYTES = 10 * 1024 * 1024;
975
+ var EMBEDDING_SURFACES = /* @__PURE__ */ new Set(["openai-completions", "openai-responses"]);
976
+ async function startModelEndpoint(options) {
977
+ if (!options.token) throw new Error("model endpoint requires a non-empty token");
978
+ const host = options.host ?? "127.0.0.1";
979
+ const log = options.log ?? (() => {
980
+ });
981
+ const loadApi = options.loadApi ?? defaultLoadApi;
982
+ const tokenDigest = digest(options.token);
983
+ const deps = () => ({
984
+ registry: options.getRegistry(),
985
+ lookupEnv: options.getLookupEnv(),
986
+ roles: options.getRoles?.()
987
+ });
988
+ function authenticate(req) {
989
+ const match = /^Bearer\s+(.+)$/i.exec(req.headers.authorization ?? "");
990
+ if (!match || !timingSafeEqual(digest(match[1] ?? ""), tokenDigest)) {
991
+ throw new ModelEndpointError(401, "invalid or missing bearer token", "invalid_api_key");
992
+ }
993
+ }
994
+ async function startUpstream(request, resolved, signal) {
995
+ const pi = await loadPi();
996
+ const surface = resolved.model.api;
997
+ let api;
998
+ try {
999
+ api = await loadApi(surface);
1000
+ } catch (cause) {
1001
+ throw new ModelEndpointError(
1002
+ 501,
1003
+ `surface '${surface}' is not supported by the installed pi-ai: ${errorText(cause)}`,
1004
+ "surface_unsupported"
1005
+ );
1006
+ }
1007
+ const { temperature, maxTokens, samplingParams, reasoning } = request.options;
1008
+ const common = {
1009
+ ...resolved.apiKey !== void 0 ? { apiKey: resolved.apiKey } : {},
1010
+ ...resolved.headers ? { headers: resolved.headers } : {},
1011
+ signal,
1012
+ ...temperature !== void 0 ? { temperature } : {},
1013
+ ...maxTokens !== void 0 ? { maxTokens } : {},
1014
+ ...samplingParams !== void 0 ? { samplingParams } : {}
1015
+ };
1016
+ const context = pi.normalizeContext(request.context);
1017
+ if (reasoning !== void 0 && api.streamSimple) {
1018
+ return api.streamSimple(resolved.model, context, { ...common, reasoning });
1019
+ }
1020
+ return api.stream(resolved.model, context, common);
1021
+ }
1022
+ async function handleChat(req, res, signal, trace) {
1023
+ const request = parseChatCompletionRequest(await readJson(req));
1024
+ const resolved = resolveModel(request.model, deps());
1025
+ trace.target = `${resolved.providerId}/${resolved.logicalId}`;
1026
+ const events = await startUpstream(request, resolved, signal);
1027
+ const id = `chatcmpl-${randomUUID().replaceAll("-", "")}`;
1028
+ const created = Math.floor(Date.now() / 1e3);
1029
+ if (!request.stream) {
1030
+ const message = await collectFinal(events);
1031
+ sendJson(res, 200, toChatCompletion(message, { id, created, model: request.model }));
1032
+ return;
1033
+ }
1034
+ const state = createChatStreamState({
1035
+ id,
1036
+ created,
1037
+ model: request.model,
1038
+ includeUsage: request.includeUsage
1039
+ });
1040
+ await pipeSse(res, events, {
1041
+ frames: (event) => chatCompletionChunks(event, state),
1042
+ errorFrame: (message) => ({ error: { message, type: "upstream_error" } }),
1043
+ terminator: "[DONE]"
1044
+ });
1045
+ }
1046
+ async function handleResponses(req, res, signal, trace) {
1047
+ const request = parseResponsesRequest(await readJson(req));
1048
+ const resolved = resolveModel(request.model, deps());
1049
+ trace.target = `${resolved.providerId}/${resolved.logicalId}`;
1050
+ const events = await startUpstream(request, resolved, signal);
1051
+ const id = `resp_${randomUUID().replaceAll("-", "")}`;
1052
+ const created = Math.floor(Date.now() / 1e3);
1053
+ if (!request.stream) {
1054
+ const message = await collectFinal(events);
1055
+ sendJson(res, 200, toResponse(message, { id, created, model: request.model }));
1056
+ return;
1057
+ }
1058
+ const state = createResponsesStreamState({ id, created, model: request.model });
1059
+ await pipeSse(res, events, {
1060
+ frames: (event) => responsesEvents(event, state),
1061
+ errorFrame: (message) => ({ type: "error", code: "upstream_error", message, param: null }),
1062
+ eventName: (frame) => isRecord2(frame) && typeof frame.type === "string" ? frame.type : void 0
1063
+ });
1064
+ }
1065
+ async function handleEmbeddings(req, res, signal, trace) {
1066
+ const body = await readJson(req);
1067
+ if (!isRecord2(body) || typeof body.model !== "string" || body.model === "") {
1068
+ throw new ModelEndpointError(400, "`model` is required", "missing_model");
1069
+ }
1070
+ const resolved = resolveModel(body.model, deps());
1071
+ trace.target = `${resolved.providerId}/${resolved.logicalId}`;
1072
+ if (!EMBEDDING_SURFACES.has(resolved.model.api)) {
1073
+ throw new ModelEndpointError(
1074
+ 501,
1075
+ `embeddings not supported for surface ${resolved.model.api}`,
1076
+ "embeddings_unsupported"
1077
+ );
1078
+ }
1079
+ const headers = {
1080
+ "content-type": "application/json",
1081
+ ...resolved.headers
1082
+ };
1083
+ if (resolved.apiKey) headers.authorization = `Bearer ${resolved.apiKey}`;
1084
+ let upstream;
1085
+ try {
1086
+ upstream = await (options.fetch ?? globalThis.fetch)(`${resolved.model.baseUrl}/embeddings`, {
1087
+ method: "POST",
1088
+ headers,
1089
+ body: JSON.stringify({ ...body, model: resolved.model.id }),
1090
+ signal
1091
+ });
1092
+ } catch (cause) {
1093
+ if (signal.aborted) return;
1094
+ throw new ModelEndpointError(
1095
+ 502,
1096
+ `embeddings upstream unreachable: ${errorText(cause)}`,
1097
+ "upstream_unreachable"
1098
+ );
1099
+ }
1100
+ const payload = Buffer.from(await upstream.arrayBuffer());
1101
+ res.writeHead(upstream.status, {
1102
+ "content-type": upstream.headers.get("content-type") ?? "application/json",
1103
+ "content-length": payload.length
1104
+ });
1105
+ res.end(payload);
1106
+ }
1107
+ async function dispatch(req, res, signal, path, trace) {
1108
+ if (!path.startsWith("/v1/")) throw notFound(path);
1109
+ authenticate(req);
1110
+ switch (`${req.method} ${path}`) {
1111
+ case "GET /v1/models":
1112
+ sendJson(res, 200, {
1113
+ object: "list",
1114
+ data: listModels(options.getRegistry()).map((m) => ({
1115
+ id: m.id,
1116
+ object: "model",
1117
+ created: 0,
1118
+ owned_by: m.owned_by
1119
+ }))
1120
+ });
1121
+ return;
1122
+ case "POST /v1/chat/completions":
1123
+ return handleChat(req, res, signal, trace);
1124
+ case "POST /v1/responses":
1125
+ return handleResponses(req, res, signal, trace);
1126
+ case "POST /v1/embeddings":
1127
+ return handleEmbeddings(req, res, signal, trace);
1128
+ default:
1129
+ throw notFound(path);
1130
+ }
1131
+ }
1132
+ async function handle(req, res) {
1133
+ const started = performance.now();
1134
+ const controller = new AbortController();
1135
+ res.on("close", () => {
1136
+ if (!res.writableFinished) controller.abort();
1137
+ });
1138
+ const trace = {};
1139
+ let path = req.url ?? "/";
1140
+ try {
1141
+ path = requestPath(req);
1142
+ await dispatch(req, res, controller.signal, path, trace);
1143
+ } catch (err) {
1144
+ if (!(err instanceof ModelEndpointError)) {
1145
+ log(
1146
+ `error ${req.method} ${path}: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
1147
+ );
1148
+ }
1149
+ sendError(res, err);
1150
+ } finally {
1151
+ const ms = Math.round(performance.now() - started);
1152
+ log(`${req.method} ${path} ${trace.target ?? "-"} ${res.statusCode} ${ms}ms`);
1153
+ }
1154
+ }
1155
+ const server = createServer((req, res) => {
1156
+ void handle(req, res);
1157
+ });
1158
+ await new Promise((resolve, reject) => {
1159
+ server.once("error", reject);
1160
+ server.listen(options.port ?? 0, host, () => {
1161
+ server.off("error", reject);
1162
+ resolve();
1163
+ });
1164
+ });
1165
+ const address = server.address();
1166
+ const hostPart = host.includes(":") ? `[${host}]` : host;
1167
+ return {
1168
+ url: `http://${hostPart}:${address.port}/v1`,
1169
+ port: address.port,
1170
+ token: options.token,
1171
+ close: () => new Promise((resolve, reject) => {
1172
+ server.close((err) => err ? reject(err) : resolve());
1173
+ server.closeAllConnections?.();
1174
+ })
1175
+ };
1176
+ }
1177
+ async function loadPi() {
1178
+ try {
1179
+ return await import('@earendil-works/pi-ai');
1180
+ } catch (cause) {
1181
+ throw new ModelEndpointError(
1182
+ 500,
1183
+ `the model endpoint needs @earendil-works/pi-ai \u2014 install it (${errorText(cause)})`,
1184
+ "pi_ai_not_installed",
1185
+ "server_error"
1186
+ );
1187
+ }
1188
+ }
1189
+ async function defaultLoadApi(surface) {
1190
+ if (!/^[a-z0-9-]+$/.test(surface)) throw new Error(`invalid surface '${surface}'`);
1191
+ return await import(
1192
+ /* @vite-ignore */
1193
+ `@earendil-works/pi-ai/api/${surface}`
1194
+ );
1195
+ }
1196
+ async function collectFinal(events) {
1197
+ for await (const event of events) {
1198
+ if (event.type === "done") return event.message;
1199
+ if (event.type === "error") throw upstreamFailure(event.error);
1200
+ }
1201
+ throw new ModelEndpointError(
1202
+ 502,
1203
+ "upstream ended without a final message",
1204
+ "upstream_incomplete"
1205
+ );
1206
+ }
1207
+ function upstreamFailure(message) {
1208
+ return new ModelEndpointError(
1209
+ 502,
1210
+ message.errorMessage ?? `upstream ${message.stopReason}`,
1211
+ "upstream_error"
1212
+ );
1213
+ }
1214
+ async function pipeSse(res, events, pipe) {
1215
+ let sse;
1216
+ const sendAll = async (frames) => {
1217
+ for (const frame of frames) await sse?.send(frame, pipe.eventName?.(frame));
1218
+ };
1219
+ try {
1220
+ for await (const event of events) {
1221
+ if (!sse) {
1222
+ if (event.type === "error") throw upstreamFailure(event.error);
1223
+ sse = openSse(res);
1224
+ }
1225
+ if (event.type === "error") {
1226
+ await sendAll([pipe.errorFrame(event.error.errorMessage ?? `upstream ${event.reason}`)]);
1227
+ break;
1228
+ }
1229
+ await sendAll(pipe.frames(event));
1230
+ }
1231
+ } catch (err) {
1232
+ if (!sse) throw err;
1233
+ await sendAll([pipe.errorFrame(errorText(err))]);
1234
+ }
1235
+ if (!sse)
1236
+ throw new ModelEndpointError(502, "upstream ended without events", "upstream_incomplete");
1237
+ if (pipe.terminator) await sse.raw(pipe.terminator);
1238
+ res.end();
1239
+ }
1240
+ function openSse(res) {
1241
+ res.writeHead(200, {
1242
+ "content-type": "text/event-stream",
1243
+ "cache-control": "no-cache",
1244
+ connection: "keep-alive"
1245
+ });
1246
+ res.flushHeaders();
1247
+ const write = async (text) => {
1248
+ if (res.destroyed || res.writableEnded) return;
1249
+ if (res.write(text)) return;
1250
+ await new Promise((resolve) => {
1251
+ const done = () => {
1252
+ res.off("drain", done);
1253
+ res.off("close", done);
1254
+ resolve();
1255
+ };
1256
+ res.once("drain", done);
1257
+ res.once("close", done);
1258
+ });
1259
+ };
1260
+ return {
1261
+ send: (frame, eventName) => write(`${eventName ? `event: ${eventName}
1262
+ ` : ""}data: ${JSON.stringify(frame)}
1263
+
1264
+ `),
1265
+ raw: (data) => write(`data: ${data}
1266
+
1267
+ `)
1268
+ };
1269
+ }
1270
+ function sendJson(res, status, body) {
1271
+ if (res.writableEnded) return;
1272
+ const payload = JSON.stringify(body);
1273
+ res.writeHead(status, {
1274
+ "content-type": "application/json",
1275
+ "content-length": Buffer.byteLength(payload)
1276
+ });
1277
+ res.end(payload);
1278
+ }
1279
+ function sendError(res, err) {
1280
+ if (res.writableEnded || res.destroyed) return;
1281
+ if (res.headersSent) {
1282
+ res.end();
1283
+ return;
1284
+ }
1285
+ const failure = err instanceof ModelEndpointError ? err : new ModelEndpointError(500, "internal server error", void 0, "server_error");
1286
+ if (failure.status === 413) res.setHeader("connection", "close");
1287
+ sendJson(res, failure.status, {
1288
+ error: {
1289
+ message: failure.message,
1290
+ type: failure.type,
1291
+ ...failure.code !== void 0 ? { code: failure.code } : {}
1292
+ }
1293
+ });
1294
+ }
1295
+ function notFound(path) {
1296
+ return new ModelEndpointError(404, `unknown route '${path}'`, void 0, "invalid_request_error");
1297
+ }
1298
+ function requestPath(req) {
1299
+ if (!URL.canParse(req.url ?? "/", "http://localhost")) {
1300
+ throw new ModelEndpointError(400, "invalid request target");
1301
+ }
1302
+ const path = new URL(req.url ?? "/", "http://localhost").pathname;
1303
+ return path.length > 1 ? path.replace(/\/+$/, "") : path;
1304
+ }
1305
+ async function readJson(req) {
1306
+ const tooLarge = () => new ModelEndpointError(413, `request body exceeds ${MAX_BODY_BYTES} bytes`, "body_too_large");
1307
+ if (Number(req.headers["content-length"]) > MAX_BODY_BYTES) throw tooLarge();
1308
+ const chunks = [];
1309
+ let size = 0;
1310
+ for await (const chunk2 of req) {
1311
+ const buffer = chunk2;
1312
+ size += buffer.length;
1313
+ if (size > MAX_BODY_BYTES) throw tooLarge();
1314
+ chunks.push(buffer);
1315
+ }
1316
+ const text = Buffer.concat(chunks).toString("utf8");
1317
+ if (text.trim() === "") throw new ModelEndpointError(400, "request body is empty", "empty_body");
1318
+ try {
1319
+ return JSON.parse(text);
1320
+ } catch {
1321
+ throw new ModelEndpointError(400, "request body is not valid JSON", "invalid_json");
1322
+ }
1323
+ }
1324
+ function digest(value) {
1325
+ return createHash("sha256").update(value).digest();
1326
+ }
1327
+ function isRecord2(value) {
1328
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1329
+ }
1330
+ function errorText(err) {
1331
+ return err instanceof Error ? err.message : String(err);
1332
+ }
1333
+
1334
+ export { ModelEndpointError, listModels, resolveModel, startModelEndpoint };
1335
+ //# sourceMappingURL=chunk-OKQXY6FS.js.map
1336
+ //# sourceMappingURL=chunk-OKQXY6FS.js.map