@xopcai/xopc 0.0.190 → 0.0.192

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 (342) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-DstnJCS5.js → activity-store-B-tzXpDD.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-9vAbkroX.js → agent-avatar-dicebear-xOu0qNwc.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-CxuwvDk0.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-BTL9kayv.js → api-fMItZb-h.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-DkFeIdBf.js → app-management-settings-panel-D6Rv3OWI.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Bxs8Fpaj.js → appearance-settings-CKoNCwco.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-wAb5dnHZ.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-Ch2RmLCC.js → archive-plugin-BokNQBwH.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-BhMQM_Ky.js → attachment-load-Dx1HglsM.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-Drgazevs.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-D6CqlymH.js → binary-plugins-CPYAflIG.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-ClL6HEg9.js → block-editor-BFLgl8SS.js} +47 -47
  15. package/dist/gateway/static/root/assets/browser-settings-page-DmYlFJW7.js +8 -0
  16. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BYy48VhN.js → browser-workflow-inputs-CqLnqA9z.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-workflows-page-zgLibuMH.js → browser-workflows-page-Db5v3HtE.js} +2 -2
  18. package/dist/gateway/static/root/assets/capabilities-settings-panel-D7Z8T0o5.js +7 -0
  19. package/dist/gateway/static/root/assets/capability-presets-api-lov0J9A2.js +1 -0
  20. package/dist/gateway/static/root/assets/capability-presets-settings-panel-COjnwO0U.js +3 -0
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-BThDGiO3.js → channel-recipient-api-DSJznouK.js} +1 -1
  22. package/dist/gateway/static/root/assets/channels-settings-DcRYBNN7.js +1 -0
  23. package/dist/gateway/static/root/assets/channels-status-swr-C2UYdebT.js +1 -0
  24. package/dist/gateway/static/root/assets/{code-editor-D4_k-6QN.js → code-editor-dFzqyDXS.js} +1 -1
  25. package/dist/gateway/static/root/assets/{connectors-api-DS9ED-EL.js → connectors-api-3ccRyS3L.js} +1 -1
  26. package/dist/gateway/static/root/assets/connectors-page-FVmvBG9H.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-CkgsvhtW.js → cron-expression-C9hhCiuo.js} +1 -1
  28. package/dist/gateway/static/root/assets/dependency-picker-CTtZFZug.js +1 -0
  29. package/dist/gateway/static/root/assets/{desktop-pet-Cv8rGhYW.js → desktop-pet-DOUeNVmC.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-CIeJdwfV.js → desktop-pet-settings-D4704vtl.js} +1 -1
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-D8jXEiAY.js → directory-picker-path-field-DJDXeA1B.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-CCZ9u6TZ.js → extension-debug-page-C0n2NMF1.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-CV36ILRG.js → extension-page-vG-xxRNs.js} +1 -1
  34. package/dist/gateway/static/root/assets/extension-settings-page-CtuY2THd.js +1 -0
  35. package/dist/gateway/static/root/assets/{gateway-config-api-D4_r5iJM.js → gateway-config-api-CZra7GuI.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-settings-CYlntpBH.js → gateway-settings-Cz33jRkR.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-startup-retry-EO9mKvzE.js → gateway-startup-retry-BbVV0udv.js} +1 -1
  38. package/dist/gateway/static/root/assets/{heartbeat-settings-D4SyWob8.js → heartbeat-settings-D2XMlA_U.js} +1 -1
  39. package/dist/gateway/static/root/assets/home-page-CPrHkPN6.js +3 -0
  40. package/dist/gateway/static/root/assets/html-workspace-editor-bXK5tq64.js +1 -0
  41. package/dist/gateway/static/root/assets/{image-generation-api-Bu7PyVSh.js → image-generation-api-BgrOvhaJ.js} +1 -1
  42. package/dist/gateway/static/root/assets/index-Cg7Xnlu3.css +1 -0
  43. package/dist/gateway/static/root/assets/index-DzmbmOGA.js +150 -0
  44. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BMhCuVBZ.js → keyboard-shortcuts-settings-BfyAEG1G.js} +1 -1
  45. package/dist/gateway/static/root/assets/local-app-workbench-page-Clz47vSr.js +2 -0
  46. package/dist/gateway/static/root/assets/{local-apps-page-ijIe7_y2.js → local-apps-page-BYalcRSY.js} +1 -1
  47. package/dist/gateway/static/root/assets/{locale-store-deR2zRaE.js → locale-store-VOY1wMO9.js} +1 -1
  48. package/dist/gateway/static/root/assets/logs-page-Cxq9WMf5.js +2 -0
  49. package/dist/gateway/static/root/assets/{management-settings--V_fovKD.js → management-settings-BQf-6s32.js} +1 -1
  50. package/dist/gateway/static/root/assets/{markdown-editor-BvUebh3C.js → markdown-editor-TWGaF7Xa.js} +2 -2
  51. package/dist/gateway/static/root/assets/{markdown-split-Dt9-in6W.js → markdown-split-Cy_2SN1Q.js} +1 -1
  52. package/dist/gateway/static/root/assets/{media-plugins-B3pj_iO0.js → media-plugins-CkDupqb2.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-DMJ-6-1m.js +3 -0
  54. package/dist/gateway/static/root/assets/{notes-page-DZ366lIT.js → notes-page-kiGRR9jo.js} +1 -1
  55. package/dist/gateway/static/root/assets/notes-workbench-DkYkPGyB.js +4 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-C5ge434C.js → page-tabs-CvzSdYVj.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-BFa9DgSV.js → preview-open-alternatives-kZ0nco7e.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-Dc9CcWdu.js → product-open-page-DgoieqQC.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-CeSjJd-N.js +1 -0
  60. package/dist/gateway/static/root/assets/projects-page-fZ1rm4b9.js +1 -0
  61. package/dist/gateway/static/root/assets/remote-access-hub-CbYI6KC8.js +1 -0
  62. package/dist/gateway/static/root/assets/runtime-tools-settings-panel-Bud_NTEZ.js +5 -0
  63. package/dist/gateway/static/root/assets/{schema-form-B84DckWe.js → schema-form-GlbsCBmv.js} +1 -1
  64. package/dist/gateway/static/root/assets/sessions-page-sOJ_TnLm.js +1 -0
  65. package/dist/gateway/static/root/assets/settings-advanced-gate-BI0u77dt.js +1 -0
  66. package/dist/gateway/static/root/assets/{settings-form-section-Dp9itvdy.js → settings-form-section-CKLns16d.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-loading-skeleton-CCtlhoy7.js → settings-loading-skeleton-BDzpxgk0.js} +1 -1
  68. package/dist/gateway/static/root/assets/settings-page-BH0pF7QB.js +1 -0
  69. package/dist/gateway/static/root/assets/{settings-page-layout-EQIOJa_L.js → settings-page-layout-J793iqfm.js} +1 -1
  70. package/dist/gateway/static/root/assets/{setup-status-panel-Cwi-SPja.js → setup-status-panel-CGsml89P.js} +1 -1
  71. package/dist/gateway/static/root/assets/{share-preview-page-C4_B2jvf.js → share-preview-page-UTm_7r0l.js} +1 -1
  72. package/dist/gateway/static/root/assets/shares-settings-BM--lgUS.js +1 -0
  73. package/dist/gateway/static/root/assets/skill-reload-api-CGCOC-rV.js +1 -0
  74. package/dist/gateway/static/root/assets/skills-page-iLyaOl48.js +2 -0
  75. package/dist/gateway/static/root/assets/skills-page.utils-Bwid1TGB.js +1 -0
  76. package/dist/gateway/static/root/assets/style-TIDOdKy0.js +7 -0
  77. package/dist/gateway/static/root/assets/{system-settings-panel-Dpx2ags2.js → system-settings-panel-BcB3p1e3.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-DQYEf08v.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-DnBOcGXi.js → theme-store-GVZOImyb.js} +1 -1
  80. package/dist/gateway/static/root/assets/{typed-models-lib-DULmTHUB.js → typed-models-lib-CT2c85Ju.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-autosave-BrjVk5VH.js → use-autosave-CcvY7DTh.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-context-page-CGI41bfO.js +1 -0
  83. package/dist/gateway/static/root/assets/{vendor-codemirror--gTq3YAI.js → vendor-codemirror-DRr7hFaD.js} +16 -16
  84. package/dist/gateway/static/root/assets/voice-api-key-field-Ricc3QGo.js +1 -0
  85. package/dist/gateway/static/root/assets/{work-discovery-overlay-Wr-uF7VA.js → work-discovery-overlay-BoomfqhX.js} +1 -1
  86. package/dist/gateway/static/root/assets/{work-discovery-page-BWds95sL.js → work-discovery-page-mbnepbQk.js} +1 -1
  87. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DSWG2xqL.js +3 -0
  88. package/dist/gateway/static/root/assets/workflows-page-DtV0ruyk.js +5 -0
  89. package/dist/gateway/static/root/index.html +7 -7
  90. package/dist/package.js +1 -1
  91. package/dist/src/agent/agent-manager.d.ts +2 -0
  92. package/dist/src/agent/agent-manager.js +76 -0
  93. package/dist/src/agent/background-review/prompts.d.ts +1 -1
  94. package/dist/src/agent/background-review/prompts.js +1 -1
  95. package/dist/src/agent/background-review/run-background-review.js +3 -12
  96. package/dist/src/agent/embedded/run-for-session.js +3 -0
  97. package/dist/src/agent/embedded/run-turn.js +4 -1
  98. package/dist/src/agent/embedded/session-runner.js +3 -4
  99. package/dist/src/agent/embedded/types.d.ts +10 -1
  100. package/dist/src/agent/embedded/xopc-stream-bridge.js +3 -2
  101. package/dist/src/agent/external-tools/mcp-provider.d.ts +1 -0
  102. package/dist/src/agent/external-tools/mcp-provider.js +21 -6
  103. package/dist/src/agent/image/generation/openai-images-provider.d.ts +1 -1
  104. package/dist/src/agent/image/generation/openai-images-provider.js +1 -1
  105. package/dist/src/agent/image/generation/provider-registry.d.ts +2 -0
  106. package/dist/src/agent/image/generation/provider-registry.js +21 -10
  107. package/dist/src/agent/image/generation/providers/dashscope.js +20 -0
  108. package/dist/src/agent/image/generation/providers/fal.d.ts +1 -1
  109. package/dist/src/agent/image/generation/providers/fal.js +12 -6
  110. package/dist/src/agent/image/generation/providers/google.js +8 -0
  111. package/dist/src/agent/image/generation/providers/minimax.js +20 -0
  112. package/dist/src/agent/image/generation/providers/openai.js +36 -26
  113. package/dist/src/agent/image/generation/providers/xopc-cloud.d.ts +2 -0
  114. package/dist/src/agent/image/generation/providers/xopc-cloud.js +74 -0
  115. package/dist/src/agent/image/generation/types.d.ts +15 -2
  116. package/dist/src/agent/mcp/bundle-mcp-gateway.d.ts +1 -0
  117. package/dist/src/agent/mcp/bundle-mcp-gateway.js +2 -1
  118. package/dist/src/agent/mcp/bundle-mcp-policy.d.ts +5 -1
  119. package/dist/src/agent/mcp/bundle-mcp-policy.js +11 -3
  120. package/dist/src/agent/mcp/bundle-mcp-runtime.js +3 -2
  121. package/dist/src/agent/mcp/bundle-mcp-types.d.ts +2 -1
  122. package/dist/src/agent/mcp/index.js +2 -2
  123. package/dist/src/agent/mcp/mcp-stdio-transport.js +1 -1
  124. package/dist/src/agent/mcp/mcp-transport.d.ts +2 -1
  125. package/dist/src/agent/mcp/mcp-transport.js +22 -4
  126. package/dist/src/agent/memory/compaction.js +19 -17
  127. package/dist/src/agent/memory/context-budget.js +2 -3
  128. package/dist/src/agent/memory/understanding/service.d.ts +1 -0
  129. package/dist/src/agent/memory/understanding/service.js +49 -20
  130. package/dist/src/agent/memory/understanding/types.d.ts +1 -0
  131. package/dist/src/agent/memory/user-context-coordinator.js +6 -0
  132. package/dist/src/agent/orchestration/agent-orchestrator.js +15 -1
  133. package/dist/src/agent/service/direct-turn-helpers.js +14 -5
  134. package/dist/src/agent/skills/index.d.ts +1 -1
  135. package/dist/src/agent/skills/index.js +2 -2
  136. package/dist/src/agent/skills/installer.d.ts +3 -10
  137. package/dist/src/agent/skills/installer.js +99 -156
  138. package/dist/src/agent/skills/marketplace/adapter.types.d.ts +3 -1
  139. package/dist/src/agent/skills/marketplace/adapters/clawhub/adapter.js +30 -6
  140. package/dist/src/agent/skills/marketplace/adapters/skillhub/adapter.js +21 -4
  141. package/dist/src/agent/skills/marketplace/adapters/store/adapter.js +7 -4
  142. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.d.ts +3 -0
  143. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +7 -1
  144. package/dist/src/agent/skills/marketplace/search.d.ts +2 -2
  145. package/dist/src/agent/skills/marketplace/search.js +52 -21
  146. package/dist/src/agent/skills/skills-marketplace.d.ts +1 -1
  147. package/dist/src/agent/skills/skills-marketplace.js +2 -2
  148. package/dist/src/agent/skills/types.d.ts +0 -8
  149. package/dist/src/agent/tools/exec-command.d.ts +1 -0
  150. package/dist/src/agent/tools/exec-command.js +2 -1
  151. package/dist/src/agent/tools/factory.d.ts +1 -0
  152. package/dist/src/agent/tools/factory.js +17 -2
  153. package/dist/src/agent/tools/managed-job-tool.d.ts +1 -1
  154. package/dist/src/agent/tools/managed-job-tool.js +3 -2
  155. package/dist/src/agent/tools/skill-install-tool.d.ts +2 -2
  156. package/dist/src/agent/tools/skill-install-tool.js +8 -4
  157. package/dist/src/agent/tools/skills-marketplace-search-tool.js +3 -2
  158. package/dist/src/agent/tools/workflow-tool.d.ts +1 -0
  159. package/dist/src/agent/tools/workflow-tool.js +14 -4
  160. package/dist/src/agent-manifest/schema.d.ts +20 -0
  161. package/dist/src/agent-manifest/schema.js +6 -1
  162. package/dist/src/browser/providers/cloakbrowser.js +1 -1
  163. package/dist/src/cli/command-loaders.js +1 -0
  164. package/dist/src/cli/command-manifest.js +4 -0
  165. package/dist/src/cli/commands/doctor/checks/node-version.js +3 -3
  166. package/dist/src/cli/commands/doctor/checks/tool-runtimes.d.ts +2 -0
  167. package/dist/src/cli/commands/doctor/checks/tool-runtimes.js +36 -0
  168. package/dist/src/cli/commands/doctor/flow.js +2 -0
  169. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  170. package/dist/src/cli/commands/models.js +0 -1
  171. package/dist/src/cli/commands/onboard/model.d.ts +18 -0
  172. package/dist/src/cli/commands/onboard/model.js +81 -5
  173. package/dist/src/cli/commands/onboard.js +13 -1
  174. package/dist/src/cli/commands/runtime.d.ts +1 -0
  175. package/dist/src/cli/commands/runtime.js +77 -0
  176. package/dist/src/cli/commands/setup.js +15 -1
  177. package/dist/src/cli/commands/skills.js +7 -4
  178. package/dist/src/config/agent-profile.js +1 -1
  179. package/dist/src/config/index.js +2 -2
  180. package/dist/src/config/schema.d.ts +125 -0
  181. package/dist/src/config/schema.js +77 -2
  182. package/dist/src/config/voice.d.ts +6 -0
  183. package/dist/src/config/voice.js +17 -0
  184. package/dist/src/extensions/install.js +1 -1
  185. package/dist/src/extensions/types/providers.d.ts +4 -0
  186. package/dist/src/gateway/agents-admin.js +1 -1
  187. package/dist/src/gateway/capability-presets-admin.d.ts +9 -0
  188. package/dist/src/gateway/capability-presets-admin.js +24 -6
  189. package/dist/src/gateway/chat-stream/mapper.js +8 -4
  190. package/dist/src/gateway/chat-stream/protocol.d.ts +10 -1
  191. package/dist/src/gateway/heartbeat/service.js +1 -1
  192. package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
  193. package/dist/src/gateway/hono/routes/commands-skills.js +2 -1
  194. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  195. package/dist/src/gateway/hono/routes/models.js +11 -11
  196. package/dist/src/gateway/hono/routes/runtime-tools.d.ts +3 -0
  197. package/dist/src/gateway/hono/routes/runtime-tools.js +142 -0
  198. package/dist/src/gateway/hono/routes/understanding-sources.js +2 -1
  199. package/dist/src/gateway/hono/routes/voice.js +43 -2
  200. package/dist/src/gateway/hono/routes/workflows.js +1 -1
  201. package/dist/src/gateway/hono/routes/you.js +22 -25
  202. package/dist/src/gateway/image-generation-setup.d.ts +2 -3
  203. package/dist/src/gateway/image-generation-setup.js +39 -8
  204. package/dist/src/gateway/service/marketplace-service.d.ts +1 -1
  205. package/dist/src/gateway/service/marketplace-service.js +2 -2
  206. package/dist/src/heartbeat/index.js +1 -1
  207. package/dist/src/infra/update-global.js +1 -1
  208. package/dist/src/providers/extension-stream-bridge.js +8 -7
  209. package/dist/src/providers/model-catalog-store.d.ts +35 -0
  210. package/dist/src/providers/model-catalog-store.js +25 -1
  211. package/dist/src/providers/model-catalog-sync-service.js +6 -0
  212. package/dist/src/providers/model-registry.js +4 -4
  213. package/dist/src/providers/prompt-cache-payload.d.ts +13 -0
  214. package/dist/src/providers/prompt-cache-payload.js +110 -0
  215. package/dist/src/providers/register-runtime-providers.js +4 -4
  216. package/dist/src/providers/xopc-cloud-model-source.js +101 -8
  217. package/dist/src/runtime-tools/archive.d.ts +8 -0
  218. package/dist/src/runtime-tools/archive.js +99 -0
  219. package/dist/src/runtime-tools/bootstrap.d.ts +16 -0
  220. package/dist/src/runtime-tools/bootstrap.js +33 -0
  221. package/dist/src/runtime-tools/catalog.d.ts +19 -0
  222. package/dist/src/runtime-tools/catalog.js +59 -0
  223. package/dist/src/runtime-tools/command.d.ts +15 -0
  224. package/dist/src/runtime-tools/command.js +59 -0
  225. package/dist/src/runtime-tools/download-source.d.ts +24 -0
  226. package/dist/src/runtime-tools/download-source.js +125 -0
  227. package/dist/src/runtime-tools/downloader.d.ts +21 -0
  228. package/dist/src/runtime-tools/downloader.js +137 -0
  229. package/dist/src/runtime-tools/environment.d.ts +20 -0
  230. package/dist/src/runtime-tools/environment.js +113 -0
  231. package/dist/src/runtime-tools/errors.d.ts +10 -0
  232. package/dist/src/runtime-tools/errors.js +14 -0
  233. package/dist/src/runtime-tools/index.d.ts +7 -0
  234. package/dist/src/runtime-tools/index.js +7 -0
  235. package/dist/src/runtime-tools/install-lock.d.ts +1 -0
  236. package/dist/src/runtime-tools/install-lock.js +50 -0
  237. package/dist/src/runtime-tools/manager.d.ts +20 -0
  238. package/dist/src/runtime-tools/manager.js +641 -0
  239. package/dist/src/runtime-tools/manifest-store.d.ts +3 -0
  240. package/dist/src/runtime-tools/manifest-store.js +26 -0
  241. package/dist/src/runtime-tools/network.d.ts +9 -0
  242. package/dist/src/runtime-tools/network.js +41 -0
  243. package/dist/src/runtime-tools/offline-bundle.d.ts +16 -0
  244. package/dist/src/runtime-tools/offline-bundle.js +41 -0
  245. package/dist/src/runtime-tools/paths.d.ts +7 -0
  246. package/dist/src/runtime-tools/paths.js +22 -0
  247. package/dist/src/runtime-tools/probe.d.ts +7 -0
  248. package/dist/src/runtime-tools/probe.js +71 -0
  249. package/dist/src/runtime-tools/prune.d.ts +10 -0
  250. package/dist/src/runtime-tools/prune.js +93 -0
  251. package/dist/src/runtime-tools/types.d.ts +70 -0
  252. package/dist/src/runtime-tools/types.js +1 -0
  253. package/dist/src/share/share-zip.js +1 -1
  254. package/dist/src/storage/sqlite/migrations/113_memory_evidence_single_source.sql +42 -20
  255. package/dist/src/tasks/home-query-service.js +1 -5
  256. package/dist/src/tasks/index.js +2 -2
  257. package/dist/src/tasks/project-operating-view-service.d.ts +2 -1
  258. package/dist/src/tasks/project-operating-view-service.js +6 -4
  259. package/dist/src/tasks/task-dependency-service.d.ts +2 -1
  260. package/dist/src/tasks/task-dependency-service.js +15 -0
  261. package/dist/src/tunnel/frpc-binary.js +1 -1
  262. package/dist/src/user-context/domain.d.ts +2 -1
  263. package/dist/src/user-context/domain.js +12 -1
  264. package/dist/src/user-context/manual-understanding.js +8 -10
  265. package/dist/src/user-context/planner.js +1 -6
  266. package/dist/src/user-context/sources/activity-clustering.d.ts +5 -0
  267. package/dist/src/user-context/sources/activity-clustering.js +130 -0
  268. package/dist/src/user-context/sources/catalog.js +26 -0
  269. package/dist/src/user-context/sources/local-source-contract.d.ts +3 -0
  270. package/dist/src/user-context/sources/local-source-contract.js +15 -0
  271. package/dist/src/user-context/sources/repository.js +7 -1
  272. package/dist/src/user-context/sources/types.d.ts +7 -1
  273. package/dist/src/user-context/understanding.d.ts +15 -0
  274. package/dist/src/user-context/understanding.js +24 -0
  275. package/dist/src/voice/local/model-files.js +1 -1
  276. package/dist/src/voice/metadata/builtin.js +99 -32
  277. package/dist/src/voice/metadata/types.d.ts +3 -0
  278. package/dist/src/voice/stt/availability.js +4 -1
  279. package/dist/src/voice/stt/config-slice.d.ts +0 -2
  280. package/dist/src/voice/stt/config-slice.js +1 -6
  281. package/dist/src/voice/stt/factory.js +2 -2
  282. package/dist/src/voice/stt/index.d.ts +2 -3
  283. package/dist/src/voice/stt/list-providers.js +1 -1
  284. package/dist/src/voice/stt/providers/alibaba-transcription.d.ts +0 -19
  285. package/dist/src/voice/stt/providers/alibaba-transcription.js +59 -132
  286. package/dist/src/voice/stt/providers/index.d.ts +1 -0
  287. package/dist/src/voice/stt/providers/index.js +2 -1
  288. package/dist/src/voice/stt/providers/openai-transcription.d.ts +2 -2
  289. package/dist/src/voice/stt/providers/openai-transcription.js +4 -4
  290. package/dist/src/voice/stt/providers/xopc-cloud-transcription.d.ts +2 -0
  291. package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +49 -0
  292. package/dist/src/voice/stt/types.js +2 -2
  293. package/dist/src/voice/tts/providers/index.d.ts +1 -0
  294. package/dist/src/voice/tts/providers/index.js +2 -1
  295. package/dist/src/voice/tts/providers/xopc-cloud-speech.d.ts +2 -0
  296. package/dist/src/voice/tts/providers/xopc-cloud-speech.js +113 -0
  297. package/dist/src/voice/tts/types.d.ts +1 -1
  298. package/dist/src/work-discovery/analyzer.js +9 -4
  299. package/dist/src/work-discovery/candidate-discovery.d.ts +1 -0
  300. package/dist/src/work-discovery/candidate-discovery.js +3 -3
  301. package/dist/src/work-discovery/index.js +2 -2
  302. package/dist/src/work-discovery/service.d.ts +2 -1
  303. package/dist/src/work-discovery/service.js +126 -37
  304. package/dist/src/work-discovery/types.d.ts +1 -0
  305. package/dist/src/workflows/service/workflow-run-service.js +8 -0
  306. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -1
  307. package/package.json +1 -1
  308. package/dist/gateway/static/root/assets/agents-D1t4SfMQ.js +0 -68
  309. package/dist/gateway/static/root/assets/apps-page-Cgrgu5OW.js +0 -1
  310. package/dist/gateway/static/root/assets/automations-page-CtJxstKh.js +0 -6
  311. package/dist/gateway/static/root/assets/browser-settings-page-DW99iDmD.js +0 -8
  312. package/dist/gateway/static/root/assets/capabilities-settings-panel-CHUrT9EB.js +0 -7
  313. package/dist/gateway/static/root/assets/capability-presets-api-BB8t4Ja7.js +0 -1
  314. package/dist/gateway/static/root/assets/capability-presets-settings-panel-Cycrv0YV.js +0 -1
  315. package/dist/gateway/static/root/assets/channels-settings-V96gPUAU.js +0 -1
  316. package/dist/gateway/static/root/assets/channels-status-swr-Cz7SAAkm.js +0 -1
  317. package/dist/gateway/static/root/assets/connectors-page-BhlyQoQI.js +0 -2
  318. package/dist/gateway/static/root/assets/extension-settings-page-IyQrSILY.js +0 -1
  319. package/dist/gateway/static/root/assets/home-page-B2Kagoh8.js +0 -3
  320. package/dist/gateway/static/root/assets/html-workspace-editor-C3DKAkMc.js +0 -1
  321. package/dist/gateway/static/root/assets/index-CYT5DOzr.js +0 -150
  322. package/dist/gateway/static/root/assets/index-D6e3tPL-.css +0 -1
  323. package/dist/gateway/static/root/assets/local-app-workbench-page-BHYbFjqy.js +0 -2
  324. package/dist/gateway/static/root/assets/logs-page-IIn8Tess.js +0 -2
  325. package/dist/gateway/static/root/assets/messages-B4XqB8I6.js +0 -3
  326. package/dist/gateway/static/root/assets/notes-workbench-S2sBVOLw.js +0 -4
  327. package/dist/gateway/static/root/assets/project-detail-page-BilzoCJ7.js +0 -1
  328. package/dist/gateway/static/root/assets/projects-page-BoQUyacP.js +0 -1
  329. package/dist/gateway/static/root/assets/remote-access-hub-DUyUaCRF.js +0 -1
  330. package/dist/gateway/static/root/assets/sessions-page-Dzxlq1F0.js +0 -1
  331. package/dist/gateway/static/root/assets/settings-advanced-gate-TzwlZxU6.js +0 -1
  332. package/dist/gateway/static/root/assets/settings-page-DQmMKf8r.js +0 -1
  333. package/dist/gateway/static/root/assets/shares-settings-CkyuGlZK.js +0 -1
  334. package/dist/gateway/static/root/assets/skill-reload-api-BJCePQK5.js +0 -1
  335. package/dist/gateway/static/root/assets/skills-page-BYWLfmJi.js +0 -2
  336. package/dist/gateway/static/root/assets/skills-page.utils-Jhm24i4h.js +0 -1
  337. package/dist/gateway/static/root/assets/task-detail-page-DLAdxI6e.js +0 -1
  338. package/dist/gateway/static/root/assets/user-context-page-9AAFpGAL.js +0 -1
  339. package/dist/gateway/static/root/assets/voice-api-key-field-BISTPfq_.js +0 -1
  340. package/dist/gateway/static/root/assets/workflow-run-setup-panel-DHqHP8_6.js +0 -3
  341. package/dist/gateway/static/root/assets/workflows-page-0b4_DFHr.js +0 -11
  342. /package/dist/gateway/static/root/assets/{workflows-page-DLioOiRN.css → style-DLioOiRN.css} +0 -0
@@ -112,9 +112,9 @@ var GatewayMarketplaceService = class {
112
112
  const { listMarketplacePackages } = await import("../../agent/skills/skills-marketplace.js");
113
113
  return listMarketplacePackages(this.opts.getConfig(), params, provider);
114
114
  }
115
- async fetchSkillsCategories(provider) {
115
+ async fetchSkillsCategories(provider, locale) {
116
116
  const { listMarketplaceCategories } = await import("../../agent/skills/skills-marketplace.js");
117
- return listMarketplaceCategories(this.opts.getConfig(), provider);
117
+ return listMarketplaceCategories(this.opts.getConfig(), provider, locale);
118
118
  }
119
119
  async fetchSkillsPackageDetail(packageName, provider) {
120
120
  const { getMarketplacePackageDetail } = await import("../../agent/skills/skills-marketplace.js");
@@ -1,6 +1,6 @@
1
1
  import { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, shouldSilence, stripHeartbeatToken } from "./tokens.js";
2
+ import { appendCronEventLines } from "./event-prompt.js";
2
3
  import { isWithinActiveHours } from "./active-hours.js";
3
4
  import { isHeartbeatContentEmpty } from "./content-check.js";
4
- import { appendCronEventLines } from "./event-prompt.js";
5
5
  import { createHeartbeatWake } from "./wake.js";
6
6
  export { DEFAULT_ACK_MAX_CHARS, HEARTBEAT_OK, NO_REPLY, appendCronEventLines, createHeartbeatWake, isHeartbeatContentEmpty, isWithinActiveHours, shouldSilence, stripHeartbeatToken };
@@ -1,6 +1,6 @@
1
+ import { applyPathPrepend } from "./path-prepend.js";
1
2
  import { resolveExecPathBinPrepend } from "./path-env.js";
2
3
  import { readPackageVersion } from "./package-json.js";
3
- import { applyPathPrepend } from "./path-prepend.js";
4
4
  import { createDefaultCommandRunner } from "./run-command.js";
5
5
  import path from "node:path";
6
6
  import fs from "node:fs";
@@ -3,6 +3,7 @@ import { init_logger } from "../utils/logger.js";
3
3
  import "./constants.js";
4
4
  import { getProviderRegistry, init_plugin_registry } from "./plugin-registry.js";
5
5
  import { init_providers } from "./index.js";
6
+ import { stripPromptCacheBoundary } from "../agent/prompt/cache-boundary.js";
6
7
  import { createAssistantMessageEventStream, streamSimple } from "@earendil-works/pi-ai/compat";
7
8
  //#region src/providers/extension-stream-bridge.ts
8
9
  init_plugin_registry();
@@ -80,7 +81,7 @@ function createExtensionAwareStreamFn() {
80
81
  const stream = createAssistantMessageEventStream();
81
82
  const params = {
82
83
  model: model.id,
83
- systemPrompt: context.systemPrompt,
84
+ systemPrompt: context.systemPrompt ? stripPromptCacheBoundary(context.systemPrompt) : void 0,
84
85
  messages: context.messages,
85
86
  tools: context.tools,
86
87
  temperature: options?.temperature,
@@ -200,15 +201,15 @@ function createExtensionAwareStreamFn() {
200
201
  partial.usage = {
201
202
  input: chunk.usage.input,
202
203
  output: chunk.usage.output,
203
- cacheRead: 0,
204
- cacheWrite: 0,
205
- totalTokens: chunk.usage.total ?? chunk.usage.input + chunk.usage.output,
204
+ cacheRead: chunk.usage.cacheRead ?? 0,
205
+ cacheWrite: chunk.usage.cacheWrite ?? 0,
206
+ totalTokens: chunk.usage.total ?? chunk.usage.input + chunk.usage.output + (chunk.usage.cacheRead ?? 0) + (chunk.usage.cacheWrite ?? 0),
206
207
  cost: {
207
208
  input: inputCost,
208
209
  output: outputCost,
209
- cacheRead: 0,
210
- cacheWrite: 0,
211
- total: inputCost + outputCost
210
+ cacheRead: (chunk.usage.cacheRead ?? 0) / 1e6 * (model.cost?.cacheRead ?? 0),
211
+ cacheWrite: (chunk.usage.cacheWrite ?? 0) / 1e6 * (model.cost?.cacheWrite ?? 0),
212
+ total: inputCost + outputCost + (chunk.usage.cacheRead ?? 0) / 1e6 * (model.cost?.cacheRead ?? 0) + (chunk.usage.cacheWrite ?? 0) / 1e6 * (model.cost?.cacheWrite ?? 0)
212
213
  }
213
214
  };
214
215
  }
@@ -2,7 +2,42 @@ export interface CatalogModel {
2
2
  id: string;
3
3
  name: string;
4
4
  availability: 'available' | 'unavailable';
5
+ kind: 'language' | 'image' | 'stt' | 'tts';
6
+ input: Array<'text' | 'image' | 'audio'>;
7
+ output: Array<'text' | 'image' | 'audio'>;
8
+ operations: Array<'chat.completions' | 'responses' | 'images.generate' | 'images.edit' | 'audio.transcription' | 'audio.speech'>;
9
+ reasoning: boolean;
10
+ contextWindow: number;
5
11
  maxOutputTokens: number | null;
12
+ imageGeneration?: {
13
+ maxCount: number;
14
+ sizes: string[];
15
+ aspectRatios?: string[];
16
+ qualities: Array<'low' | 'medium' | 'high' | 'auto'>;
17
+ formats: Array<'png' | 'jpeg' | 'webp'>;
18
+ backgrounds: Array<'transparent' | 'opaque' | 'auto'>;
19
+ maxInputImages: number;
20
+ };
21
+ stt?: {
22
+ inputFormats: string[];
23
+ maxBytes: number;
24
+ maxDurationSeconds: number;
25
+ languages: string[];
26
+ languageHint: boolean;
27
+ prompt: boolean;
28
+ timestamps: Array<'segment' | 'word'>;
29
+ diarization: boolean;
30
+ };
31
+ tts?: {
32
+ maxCharacters: number;
33
+ languages: string[];
34
+ outputFormats: Array<'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'>;
35
+ streaming: boolean;
36
+ speed: boolean;
37
+ pitch: boolean;
38
+ instructions: boolean;
39
+ defaultVoice?: string;
40
+ };
6
41
  }
7
42
  export interface CatalogSource {
8
43
  providerId: string;
@@ -53,7 +53,31 @@ var init_model_catalog_store = __esmMin((() => {
53
53
  cloneSource(source) {
54
54
  return {
55
55
  ...source,
56
- models: source.models.map((model) => ({ ...model }))
56
+ models: source.models.map((model) => ({
57
+ ...model,
58
+ input: [...model.input],
59
+ output: [...model.output],
60
+ operations: [...model.operations],
61
+ ...model.imageGeneration ? { imageGeneration: {
62
+ ...model.imageGeneration,
63
+ sizes: [...model.imageGeneration.sizes],
64
+ aspectRatios: [...model.imageGeneration.aspectRatios ?? []],
65
+ qualities: [...model.imageGeneration.qualities],
66
+ formats: [...model.imageGeneration.formats],
67
+ backgrounds: [...model.imageGeneration.backgrounds]
68
+ } } : {},
69
+ ...model.stt ? { stt: {
70
+ ...model.stt,
71
+ inputFormats: [...model.stt.inputFormats],
72
+ languages: [...model.stt.languages],
73
+ timestamps: [...model.stt.timestamps]
74
+ } } : {},
75
+ ...model.tts ? { tts: {
76
+ ...model.tts,
77
+ languages: [...model.tts.languages],
78
+ outputFormats: [...model.tts.outputFormats]
79
+ } } : {}
80
+ }))
57
81
  };
58
82
  }
59
83
  };
@@ -110,6 +110,12 @@ var ModelCatalogSyncService = class {
110
110
  }, models.map((model) => ({
111
111
  id: model.id,
112
112
  name: model.name ?? model.id,
113
+ kind: "language",
114
+ input: ["text"],
115
+ output: ["text"],
116
+ operations: provider.api === "openai-responses" ? ["responses"] : ["chat.completions"],
117
+ reasoning: false,
118
+ contextWindow: 128e3,
113
119
  maxOutputTokens: null
114
120
  })));
115
121
  return providerId;
@@ -236,21 +236,21 @@ var init_model_registry = __esmMin((() => {
236
236
  log.warn({ err }, "Failed to load remote model catalog");
237
237
  return [];
238
238
  }
239
- return Object.values(sources).flatMap((source) => source.models.filter((model) => model.availability === "available").map((model) => ({
239
+ return Object.values(sources).flatMap((source) => source.models.filter((model) => model.availability === "available" && model.kind === "language").map((model) => ({
240
240
  id: model.id,
241
241
  name: model.name,
242
242
  api: source.api,
243
243
  provider: source.providerId,
244
244
  baseUrl: source.baseUrl,
245
- reasoning: false,
246
- input: ["text"],
245
+ reasoning: model.reasoning,
246
+ input: model.input.filter((value) => value === "text" || value === "image"),
247
247
  cost: {
248
248
  input: 0,
249
249
  output: 0,
250
250
  cacheRead: 0,
251
251
  cacheWrite: 0
252
252
  },
253
- contextWindow: 128e3,
253
+ contextWindow: model.contextWindow,
254
254
  maxTokens: model.maxOutputTokens ?? 16384
255
255
  })));
256
256
  }
@@ -0,0 +1,13 @@
1
+ import type { Api, Model, SimpleStreamOptions } from '@earendil-works/pi-ai';
2
+ export declare function transformPromptCachePayload(model: Model<Api>, payload: unknown): unknown;
3
+ export declare function buildPromptCacheKey(model: Model<Api>, context: {
4
+ systemPrompt?: string;
5
+ tools?: unknown[];
6
+ }): string;
7
+ export declare function preparePromptCacheContext<T extends {
8
+ systemPrompt?: string;
9
+ }>(model: Model<Api>, context: T): T;
10
+ export declare function withPromptCachePayloadTransform(model: Model<Api>, context: {
11
+ systemPrompt?: string;
12
+ tools?: unknown[];
13
+ }, options: SimpleStreamOptions | undefined): SimpleStreamOptions | undefined;
@@ -0,0 +1,110 @@
1
+ import { splitPromptCacheBoundary, stripPromptCacheBoundary } from "../agent/prompt/cache-boundary.js";
2
+ import { createHash } from "node:crypto";
3
+ //#region src/providers/prompt-cache-payload.ts
4
+ function asRecord(value) {
5
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
6
+ }
7
+ function supportsPromptCacheKey(model) {
8
+ if (model.api === "openai-codex-responses" || model.api === "azure-openai-responses") return true;
9
+ if (model.api !== "openai-completions" && model.api !== "openai-responses") return false;
10
+ return model.provider === "openai" || model.baseUrl?.includes("api.openai.com") === true;
11
+ }
12
+ function splitAnthropicSystem(payload) {
13
+ const record = asRecord(payload);
14
+ if (!record || !Array.isArray(record.system)) return payload;
15
+ let changed = false;
16
+ const system = record.system.flatMap((value) => {
17
+ const block = asRecord(value);
18
+ if (!block || typeof block.text !== "string") return [value];
19
+ const split = splitPromptCacheBoundary(block.text);
20
+ if (!split) return [value];
21
+ changed = true;
22
+ const { text: _text, ...rest } = block;
23
+ return [{
24
+ ...rest,
25
+ type: block.type ?? "text",
26
+ text: split.stablePrefix
27
+ }, ...split.dynamicSuffix ? [{
28
+ type: block.type ?? "text",
29
+ text: split.dynamicSuffix
30
+ }] : []];
31
+ });
32
+ return changed ? {
33
+ ...record,
34
+ system
35
+ } : payload;
36
+ }
37
+ function splitBedrockSystem(payload) {
38
+ const record = asRecord(payload);
39
+ if (!record || !Array.isArray(record.system)) return payload;
40
+ let changed = false;
41
+ const system = [];
42
+ for (let index = 0; index < record.system.length; index += 1) {
43
+ const value = record.system[index];
44
+ const block = asRecord(value);
45
+ const split = block && typeof block.text === "string" ? splitPromptCacheBoundary(block.text) : void 0;
46
+ if (!split) {
47
+ system.push(value);
48
+ continue;
49
+ }
50
+ changed = true;
51
+ system.push({
52
+ ...block,
53
+ text: split.stablePrefix
54
+ });
55
+ const next = asRecord(record.system[index + 1]);
56
+ if (next?.cachePoint) {
57
+ system.push(next);
58
+ index += 1;
59
+ }
60
+ if (split.dynamicSuffix) system.push({ text: split.dynamicSuffix });
61
+ }
62
+ return changed ? {
63
+ ...record,
64
+ system
65
+ } : payload;
66
+ }
67
+ function transformPromptCachePayload(model, payload) {
68
+ if (model.api === "anthropic-messages") return splitAnthropicSystem(payload);
69
+ if (model.api === "bedrock-converse-stream") return splitBedrockSystem(payload);
70
+ return payload;
71
+ }
72
+ function canonicalJson(value) {
73
+ if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
74
+ const record = asRecord(value);
75
+ if (record) return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`).join(",")}}`;
76
+ return JSON.stringify(value) ?? "null";
77
+ }
78
+ function buildPromptCacheKey(model, context) {
79
+ const stablePrompt = context.systemPrompt ? splitPromptCacheBoundary(context.systemPrompt)?.stablePrefix ?? stripPromptCacheBoundary(context.systemPrompt) : "";
80
+ return `xopc-${createHash("sha256").update(`${model.provider}\0${model.id}\0${stablePrompt}\0${canonicalJson(context.tools ?? [])}`).digest("base64url")}`;
81
+ }
82
+ function preparePromptCacheContext(model, context) {
83
+ if (model.api === "anthropic-messages" || model.api === "bedrock-converse-stream") return context;
84
+ if (!context.systemPrompt) return context;
85
+ return {
86
+ ...context,
87
+ systemPrompt: stripPromptCacheBoundary(context.systemPrompt)
88
+ };
89
+ }
90
+ function withPromptCachePayloadTransform(model, context, options) {
91
+ const explicitBoundary = model.api === "anthropic-messages" || model.api === "bedrock-converse-stream";
92
+ const openAiCacheKey = supportsPromptCacheKey(model) && options?.cacheRetention !== "none";
93
+ if (!explicitBoundary && !openAiCacheKey) return options;
94
+ const upstream = options?.onPayload;
95
+ const promptCacheKey = openAiCacheKey ? buildPromptCacheKey(model, context) : void 0;
96
+ return {
97
+ ...options,
98
+ onPayload: async (payload, payloadModel) => {
99
+ const upstreamPayload = await upstream?.(payload, payloadModel);
100
+ const transformed = transformPromptCachePayload(model, upstreamPayload === void 0 ? payload : upstreamPayload);
101
+ const record = asRecord(transformed);
102
+ return record && promptCacheKey ? {
103
+ ...record,
104
+ prompt_cache_key: promptCacheKey
105
+ } : transformed;
106
+ }
107
+ };
108
+ }
109
+ //#endregion
110
+ export { buildPromptCacheKey, preparePromptCacheContext, transformPromptCachePayload, withPromptCachePayloadTransform };
@@ -16,18 +16,18 @@ function registerRuntimeProvider(modelRuntime, source) {
16
16
  baseUrl: source.baseUrl,
17
17
  api: source.api,
18
18
  oauth,
19
- models: source.models.filter((model) => model.availability === "available").map((model) => ({
19
+ models: source.models.filter((model) => model.availability === "available" && model.kind === "language").map((model) => ({
20
20
  id: model.id,
21
21
  name: model.name,
22
- reasoning: false,
23
- input: ["text"],
22
+ reasoning: model.reasoning,
23
+ input: model.input.filter((value) => value === "text" || value === "image"),
24
24
  cost: {
25
25
  input: 0,
26
26
  output: 0,
27
27
  cacheRead: 0,
28
28
  cacheWrite: 0
29
29
  },
30
- contextWindow: 128e3,
30
+ contextWindow: model.contextWindow,
31
31
  maxTokens: model.maxOutputTokens ?? 16384
32
32
  }))
33
33
  });
@@ -2,6 +2,7 @@ import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-
2
2
  import { getModelRegistry, init_model_registry } from "./model-registry.js";
3
3
  import { init_xopc_cloud_config, resolveXopcModelRouterUrl } from "./xopc-cloud-config.js";
4
4
  import { getProviderAuthService, init_provider_auth_service } from "./provider-auth-service.js";
5
+ import { reloadImageGenerationProviders } from "../agent/image/generation/provider-registry.js";
5
6
  //#region src/providers/xopc-cloud-model-source.ts
6
7
  init_model_catalog_store();
7
8
  init_model_registry();
@@ -44,26 +45,118 @@ var XopcCloudModelSource = class {
44
45
  const body = await response.json().catch(() => null);
45
46
  if (!response.ok) throw new XopcCloudModelError(typeof body?.error?.message === "string" ? body.error.message : `XOPC model discovery failed (${response.status})`, response.status, typeof body?.error?.code === "string" ? body.error.code : void 0);
46
47
  if (!Array.isArray(body?.data)) throw new XopcCloudModelError("XOPC model discovery returned an invalid response", response.status, "invalid_response");
47
- const models = [...new Set(body.data.map((model) => model.id).filter((id) => typeof id === "string" && id.length > 0))];
48
+ const models = [...new Map(body.data.filter((model) => typeof model.id === "string" && model.id.length > 0).map((model) => {
49
+ const declaredInput = model.xopc?.capabilities?.input;
50
+ const parsedInput = Array.isArray(declaredInput) ? declaredInput.filter((value) => value === "text" || value === "image" || value === "audio") : [];
51
+ const kind = model.xopc?.kind === "image" || model.xopc?.kind === "stt" || model.xopc?.kind === "tts" ? model.xopc.kind : "language";
52
+ const input = kind === "stt" ? ["audio"] : kind === "tts" ? ["text"] : kind === "language" && !parsedInput.includes("text") ? ["text", ...new Set(parsedInput)] : [...new Set(parsedInput)];
53
+ const maxOutputTokens = model.xopc?.maxOutputTokens;
54
+ const declaredOutput = model.xopc?.capabilities?.output;
55
+ const output = kind === "stt" ? ["text"] : kind === "tts" ? ["audio"] : Array.isArray(declaredOutput) ? declaredOutput.filter((value) => value === "text" || value === "image" || value === "audio") : ["text"];
56
+ const declaredOperations = model.xopc?.operations ?? model.xopc?.capabilities?.operations;
57
+ const operations = kind === "stt" ? ["audio.transcription"] : kind === "tts" ? ["audio.speech"] : Array.isArray(declaredOperations) ? declaredOperations.filter((value) => value === "chat.completions" || value === "responses" || value === "images.generate" || value === "images.edit" || value === "audio.transcription" || value === "audio.speech") : ["chat.completions", "responses"];
58
+ const generation = parseImageGenerationCapabilities(model.xopc?.capabilities?.imageGeneration);
59
+ const stt = kind === "stt" ? parseSttCapabilities(model.xopc?.capabilities) : void 0;
60
+ const tts = kind === "tts" ? parseTtsCapabilities(model.xopc?.capabilities, model.xopc?.defaultVoice) : void 0;
61
+ return [model.id, {
62
+ id: model.id,
63
+ name: model.id,
64
+ kind,
65
+ input,
66
+ output,
67
+ operations,
68
+ reasoning: model.xopc?.capabilities?.reasoning === true,
69
+ contextWindow: 128e3,
70
+ maxOutputTokens: typeof maxOutputTokens === "number" && Number.isSafeInteger(maxOutputTokens) ? maxOutputTokens : null,
71
+ ...generation ? { imageGeneration: generation } : {},
72
+ ...stt ? { stt } : {},
73
+ ...tts ? { tts } : {}
74
+ }];
75
+ })).values()];
48
76
  this.catalogStore.replaceSourceModels("xopc-cloud", {
49
77
  providerId: "xopc-cloud",
50
78
  baseUrl: this.routerUrl,
51
79
  api: "openai-completions",
52
80
  etag: response.headers.get("x-xopc-model-catalog-version"),
53
- recommendedModel: models[0] ?? null,
81
+ recommendedModel: models[0]?.id ?? null,
54
82
  lastSuccessAt: Date.now()
55
- }, models.map((id) => ({
56
- id,
57
- name: id,
58
- maxOutputTokens: null
59
- })));
83
+ }, models);
60
84
  this.refreshModels();
85
+ reloadImageGenerationProviders();
61
86
  return {
62
87
  status: "updated",
63
88
  modelCount: models.length,
64
- models
89
+ models: models.map((model) => model.id)
65
90
  };
66
91
  }
67
92
  };
93
+ function parseSttCapabilities(value) {
94
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
95
+ const raw = value;
96
+ return {
97
+ inputFormats: strings(raw.inputFormats),
98
+ maxBytes: positiveInteger(raw.maxBytes),
99
+ maxDurationSeconds: positiveInteger(raw.maxDurationSeconds),
100
+ languages: strings(raw.languages),
101
+ languageHint: raw.languageHint === true,
102
+ prompt: raw.prompt === true,
103
+ timestamps: strings(raw.timestamps).filter((item) => item === "segment" || item === "word"),
104
+ diarization: raw.diarization === true
105
+ };
106
+ }
107
+ function parseTtsCapabilities(value, defaultVoice) {
108
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
109
+ const raw = value;
110
+ return {
111
+ maxCharacters: positiveInteger(raw.maxCharacters),
112
+ languages: strings(raw.languages),
113
+ outputFormats: strings(raw.outputFormats).filter((item) => [
114
+ "mp3",
115
+ "opus",
116
+ "aac",
117
+ "flac",
118
+ "wav",
119
+ "pcm"
120
+ ].includes(item)),
121
+ streaming: raw.streaming === true,
122
+ speed: raw.speed === true,
123
+ pitch: raw.pitch === true,
124
+ instructions: raw.instructions === true,
125
+ ...typeof defaultVoice === "string" && defaultVoice ? { defaultVoice } : {}
126
+ };
127
+ }
128
+ function strings(value) {
129
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
130
+ }
131
+ function positiveInteger(value) {
132
+ return Number.isSafeInteger(value) && Number(value) > 0 ? Number(value) : 0;
133
+ }
134
+ function parseImageGenerationCapabilities(value) {
135
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
136
+ const raw = value;
137
+ const strings = (candidate, allowed) => Array.isArray(candidate) ? candidate.filter((item) => typeof item === "string" && (!allowed || allowed.includes(item))) : [];
138
+ return {
139
+ maxCount: Number.isSafeInteger(raw.maxCount) && Number(raw.maxCount) > 0 ? Number(raw.maxCount) : 1,
140
+ sizes: strings(raw.sizes),
141
+ aspectRatios: strings(raw.aspectRatios),
142
+ qualities: strings(raw.qualities, [
143
+ "low",
144
+ "medium",
145
+ "high",
146
+ "auto"
147
+ ]),
148
+ formats: strings(raw.formats, [
149
+ "png",
150
+ "jpeg",
151
+ "webp"
152
+ ]),
153
+ backgrounds: strings(raw.backgrounds, [
154
+ "transparent",
155
+ "opaque",
156
+ "auto"
157
+ ]),
158
+ maxInputImages: Number.isSafeInteger(raw.maxInputImages) && Number(raw.maxInputImages) > 0 ? Number(raw.maxInputImages) : 0
159
+ };
160
+ }
68
161
  //#endregion
69
162
  export { XopcCloudModelError, XopcCloudModelSource };
@@ -0,0 +1,8 @@
1
+ import type { RuntimeKind } from './types.js';
2
+ export declare function extractRuntimeArchive(params: {
3
+ runtime: RuntimeKind;
4
+ archivePath: string;
5
+ archiveType: 'zip' | 'tar.gz';
6
+ stagingDir: string;
7
+ }): Promise<string>;
8
+ export declare function atomicInstallRuntime(extractedRoot: string, installDir: string): Promise<void>;
@@ -0,0 +1,99 @@
1
+ import { RuntimeError } from "./errors.js";
2
+ import { isAbsolute, join, posix, relative, resolve } from "node:path";
3
+ import { spawn } from "node:child_process";
4
+ import { lstat, mkdir, readdir, readlink, rename, rm, stat } from "node:fs/promises";
5
+ import AdmZip from "adm-zip";
6
+ //#region src/runtime-tools/archive.ts
7
+ const MAX_ARCHIVE_ENTRIES = 5e4;
8
+ function validateMemberPath(memberPath) {
9
+ const portablePath = memberPath.replaceAll("\\", "/");
10
+ const normalized = posix.normalize(portablePath);
11
+ if (!memberPath || isAbsolute(memberPath) || portablePath.startsWith("/") || normalized === ".." || normalized.startsWith("../")) throw new Error(`Unsafe archive member: ${memberPath}`);
12
+ }
13
+ async function validateExtractedTree(root, current = root) {
14
+ for (const entry of await readdir(current)) {
15
+ const entryPath = join(current, entry);
16
+ const details = await lstat(entryPath);
17
+ if (details.isSymbolicLink()) {
18
+ const relativeTarget = relative(root, resolve(current, await readlink(entryPath)));
19
+ if (relativeTarget.split(/[\\/]/)[0] === ".." || isAbsolute(relativeTarget)) throw new Error(`Archive symlink escapes extraction root: ${entryPath}`);
20
+ continue;
21
+ }
22
+ if (details.isDirectory()) await validateExtractedTree(root, entryPath);
23
+ }
24
+ }
25
+ async function runTar(args) {
26
+ return await new Promise((resolvePromise, reject) => {
27
+ let stdout = "";
28
+ let stderr = "";
29
+ const child = spawn("tar", args, {
30
+ shell: false,
31
+ windowsHide: true
32
+ });
33
+ child.stdout?.on("data", (chunk) => {
34
+ stdout += chunk.toString();
35
+ });
36
+ child.stderr?.on("data", (chunk) => {
37
+ stderr += chunk.toString();
38
+ });
39
+ child.once("error", reject);
40
+ child.once("close", (code) => {
41
+ if (code === 0) resolvePromise(stdout);
42
+ else reject(new Error(stderr.trim() || `tar exited with code ${code}`));
43
+ });
44
+ });
45
+ }
46
+ async function extractZip(archivePath, destination) {
47
+ const zip = new AdmZip(archivePath);
48
+ const entries = zip.getEntries();
49
+ if (entries.length > MAX_ARCHIVE_ENTRIES) throw new Error("Archive contains too many entries");
50
+ for (const entry of entries) validateMemberPath(entry.entryName);
51
+ zip.extractAllTo(destination, true, false);
52
+ }
53
+ async function extractTarGz(archivePath, destination) {
54
+ const entries = (await runTar(["-tzf", archivePath])).split(/\r?\n/).filter(Boolean);
55
+ if (entries.length > MAX_ARCHIVE_ENTRIES) throw new Error("Archive contains too many entries");
56
+ for (const entry of entries) validateMemberPath(entry);
57
+ await runTar([
58
+ "-xzf",
59
+ archivePath,
60
+ "-C",
61
+ destination
62
+ ]);
63
+ }
64
+ async function singleArchiveRoot(destination) {
65
+ const entries = (await readdir(destination)).filter((entry) => entry !== "__MACOSX");
66
+ if (entries.length !== 1) throw new Error("Archive must contain one top-level directory");
67
+ const root = join(destination, entries[0]);
68
+ if (!(await stat(root)).isDirectory()) throw new Error("Archive root is not a directory");
69
+ return root;
70
+ }
71
+ async function extractRuntimeArchive(params) {
72
+ await rm(params.stagingDir, {
73
+ recursive: true,
74
+ force: true
75
+ });
76
+ await mkdir(params.stagingDir, { recursive: true });
77
+ try {
78
+ if (params.archiveType === "zip") await extractZip(params.archivePath, params.stagingDir);
79
+ else await extractTarGz(params.archivePath, params.stagingDir);
80
+ await validateExtractedTree(params.stagingDir);
81
+ return await singleArchiveRoot(params.stagingDir);
82
+ } catch (error) {
83
+ await rm(params.stagingDir, {
84
+ recursive: true,
85
+ force: true
86
+ });
87
+ throw new RuntimeError(`Invalid ${params.runtime} archive: ${error instanceof Error ? error.message : String(error)}`, "RUNTIME_ARCHIVE_INVALID", params.runtime, "extract", true, [], { cause: error });
88
+ }
89
+ }
90
+ async function atomicInstallRuntime(extractedRoot, installDir) {
91
+ await mkdir(resolve(installDir, ".."), { recursive: true });
92
+ await rm(installDir, {
93
+ recursive: true,
94
+ force: true
95
+ });
96
+ await rename(extractedRoot, installDir);
97
+ }
98
+ //#endregion
99
+ export { atomicInstallRuntime, extractRuntimeArchive };
@@ -0,0 +1,16 @@
1
+ import type { RuntimeToolsConfig } from '../config/schema.js';
2
+ import { ManagedRuntimeManager } from './manager.js';
3
+ import type { ResolvedRuntime, RuntimeKind } from './types.js';
4
+ export type RuntimeBootstrapResult = {
5
+ runtime: RuntimeKind;
6
+ ok: boolean;
7
+ resolved?: ResolvedRuntime;
8
+ error?: string;
9
+ };
10
+ type RuntimeResolver = Pick<ManagedRuntimeManager, 'resolve'>;
11
+ export declare function provisionEagerRuntimes(params: {
12
+ stateDir: string;
13
+ config: RuntimeToolsConfig;
14
+ manager?: RuntimeResolver;
15
+ }): Promise<RuntimeBootstrapResult[]>;
16
+ export {};
@@ -0,0 +1,33 @@
1
+ import { ManagedRuntimeManager } from "./manager.js";
2
+ //#region src/runtime-tools/bootstrap.ts
3
+ async function provisionEagerRuntimes(params) {
4
+ if (!params.config.enabled) return [];
5
+ const manager = params.manager ?? new ManagedRuntimeManager({
6
+ stateDir: params.stateDir,
7
+ config: params.config
8
+ });
9
+ const requested = [];
10
+ if (params.config.node.enabled && params.config.node.provision === "eager") requested.push("node");
11
+ if (params.config.python.enabled && params.config.python.provision === "eager") requested.push("python");
12
+ const results = [];
13
+ for (const runtime of requested) try {
14
+ const resolved = await manager.resolve({
15
+ runtime,
16
+ allowProvision: true
17
+ });
18
+ results.push({
19
+ runtime,
20
+ ok: true,
21
+ resolved
22
+ });
23
+ } catch (error) {
24
+ results.push({
25
+ runtime,
26
+ ok: false,
27
+ error: error instanceof Error ? error.message : String(error)
28
+ });
29
+ }
30
+ return results;
31
+ }
32
+ //#endregion
33
+ export { provisionEagerRuntimes };
@@ -0,0 +1,19 @@
1
+ import type { RuntimeKind } from './types.js';
2
+ export declare const RUNTIME_CATALOG_VERSION = "2026-08-23";
3
+ export declare const DEFAULT_RUNTIME_VERSIONS: Record<RuntimeKind, string>;
4
+ export type RuntimePlatform = 'darwin-arm64' | 'darwin-x64' | 'win32-x64' | 'linux-x64-gnu' | 'linux-arm64-gnu';
5
+ export interface RuntimeAsset {
6
+ runtime: 'node' | 'uv';
7
+ version: string;
8
+ platform: RuntimePlatform;
9
+ archiveFile: string;
10
+ url: string;
11
+ checksumUrl: string;
12
+ archiveType: 'zip' | 'tar.gz';
13
+ }
14
+ export declare function detectRuntimePlatform(platform?: NodeJS.Platform, arch?: string): RuntimePlatform | null;
15
+ export declare function resolveRuntimeAsset(params: {
16
+ runtime: 'node' | 'uv';
17
+ version: string;
18
+ platform: RuntimePlatform;
19
+ }): RuntimeAsset;