@xopcai/xopc 0.0.210 → 0.0.213

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 (326) 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-JLmEb1p0.js → activity-store-Xw-pOm9A.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CI1zQfzY.js → agent-avatar-dicebear-Ca1bciiK.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-DD3TqNrC.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-C6MmWfcb.js → api-CZK-lRew.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cd02GGpV.js → app-management-settings-panel-BLFIG09j.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Db-h2I3G.js → appearance-settings-BsTWUq1i.js} +1 -1
  9. package/dist/gateway/static/root/assets/apps-page-cJkDKn72.js +1 -0
  10. package/dist/gateway/static/root/assets/{archive-plugin-CMHzJT2a.js → archive-plugin-B9LsFfEx.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-BzhI2LoH.js → attachment-load-CsWiFfmN.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-CbjU2e75.js +1 -0
  13. package/dist/gateway/static/root/assets/automations-workspace-C4xyo0c4.js +6 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-DsUeHvZO.js → binary-plugins-DbqhT_JB.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-CFfsIeZ4.js → block-editor-BGpHwxZ5.js} +4 -4
  16. package/dist/gateway/static/root/assets/browser-settings-page-CrhpQl-e.js +8 -0
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BiWghvJ0.js → browser-workflow-inputs-BXlon_hL.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-DPLdT6Zn.js → browser-workflows-page-B3BBDM_r.js} +2 -2
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-B9MoPW9u.js +7 -0
  20. package/dist/gateway/static/root/assets/{capability-presets-api-CTxGFvsS.js → capability-presets-api-BqvMm6UW.js} +1 -1
  21. package/dist/gateway/static/root/assets/capability-presets-settings-panel-BmwldV9R.js +3 -0
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-BklVUOxC.js → channel-recipient-api-9uca5kDa.js} +1 -1
  23. package/dist/gateway/static/root/assets/channels-settings-CwLqWcy_.js +1 -0
  24. package/dist/gateway/static/root/assets/channels-status-swr-DeBw3du9.js +1 -0
  25. package/dist/gateway/static/root/assets/{chat-terminal-dock-0F4Jmma2.js → chat-terminal-dock-DJjYT3WX.js} +2 -2
  26. package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-BMhrPKJC.js → chunk-KS7C4IRE-BaASWQor.js} +1 -1
  27. package/dist/gateway/static/root/assets/{connectors-api-BvIZ51ty.js → connectors-api-XCLfuDrN.js} +1 -1
  28. package/dist/gateway/static/root/assets/connectors-page-CVkGtcMS.js +2 -0
  29. package/dist/gateway/static/root/assets/{cron-expression-BHmwaMbO.js → cron-expression-DzQN7zBR.js} +1 -1
  30. package/dist/gateway/static/root/assets/{date-picker-fj_pPCv5.js → date-picker-B-r5O5qd.js} +1 -1
  31. package/dist/gateway/static/root/assets/{dependency-picker-DsWvwOv-.js → dependency-picker-Ch2XBU2s.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-mjkF0Xxh.js → desktop-pet-BdjX8jde.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-settings-ClwUpRYu.js → desktop-pet-settings-CzjjgMMn.js} +1 -1
  34. package/dist/gateway/static/root/assets/directory-picker-path-field-BCTgGTk4.js +1 -0
  35. package/dist/gateway/static/root/assets/{extension-debug-page-DC69wplH.js → extension-debug-page-6OGgOucD.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-page-DCtk6zdJ.js → extension-page-Cf6MUfCF.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-settings-page-Bkm4zzv-.js → extension-settings-page-pSY_ZvQZ.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-config-api-Dr_NQt7v.js → gateway-config-api-CFJMng9v.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-config-swr-CEfv8N1J.js → gateway-config-swr-DpiY6aub.js} +1 -1
  40. package/dist/gateway/static/root/assets/gateway-settings-aQYxNePf.js +1 -0
  41. package/dist/gateway/static/root/assets/{gateway-startup-retry-B8hebJ7s.js → gateway-startup-retry-BZ_6ChP4.js} +1 -1
  42. package/dist/gateway/static/root/assets/heartbeat-settings-CI33q9i1.js +1 -0
  43. package/dist/gateway/static/root/assets/home-page-CAIaWs6r.js +1 -0
  44. package/dist/gateway/static/root/assets/image-generation-api-DPndEWOU.js +1 -0
  45. package/dist/gateway/static/root/assets/index-BhstAl5i.js +108 -0
  46. package/dist/gateway/static/root/assets/index-DQzjgIkQ.css +2 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DCQvf05d.js → keyboard-shortcuts-settings-CbLJRGXR.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-BqFnCaKT.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-B3Ugd0my.js → local-apps-page-Crf6c3SK.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-hDBVeG3G.js → locale-store-BYSRjM6g.js} +1 -1
  51. package/dist/gateway/static/root/assets/{logs-page-nXdF3wOT.js → logs-page-BpfLQWex.js} +2 -2
  52. package/dist/gateway/static/root/assets/{management-settings-C-S5Llq3.js → management-settings-mxyYWKgM.js} +1 -1
  53. package/dist/gateway/static/root/assets/{markdown-split-DuVq37Uh.js → markdown-split-kZaPrUTM.js} +1 -1
  54. package/dist/gateway/static/root/assets/markdown-view-DD_PgVue.css +1 -0
  55. package/dist/gateway/static/root/assets/{markdown-view-D8eO_6h3.js → markdown-view-DlsczsQ1.js} +1 -1
  56. package/dist/gateway/static/root/assets/{media-plugins-C1V6pkX3.js → media-plugins-Dk67jaG6.js} +1 -1
  57. package/dist/gateway/static/root/assets/messages-DyM8OOVG.js +3 -0
  58. package/dist/gateway/static/root/assets/notes-api-DaeeQw8A.js +1 -0
  59. package/dist/gateway/static/root/assets/{notes-page-Dn71ZV8c.js → notes-page-CQDzw8fX.js} +1 -1
  60. package/dist/gateway/static/root/assets/notes-workbench-BYiROmRJ.js +4 -0
  61. package/dist/gateway/static/root/assets/{page-tabs-B5a5aSoS.js → page-tabs-C4UkhX2U.js} +1 -1
  62. package/dist/gateway/static/root/assets/{preview-open-alternatives-5041AIBX.js → preview-open-alternatives-nzcjh6y0.js} +1 -1
  63. package/dist/gateway/static/root/assets/{product-open-page-7UkouFQU.js → product-open-page-3FvW5cHm.js} +1 -1
  64. package/dist/gateway/static/root/assets/project-detail-page-p45i1sMj.js +1 -0
  65. package/dist/gateway/static/root/assets/projects-page-Y9yXB4DX.js +1 -0
  66. package/dist/gateway/static/root/assets/registry-api-Bu6OGEY2.js +2 -0
  67. package/dist/gateway/static/root/assets/remote-access-hub-CNsGY0VS.js +1 -0
  68. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DvaXzHYS.js → runtime-tools-settings-panel-CVqPSfUb.js} +2 -2
  69. package/dist/gateway/static/root/assets/{schema-form-Dlxl_5X0.js → schema-form-Dz6eZpqv.js} +1 -1
  70. package/dist/gateway/static/root/assets/sessions-page-BAtpgb1t.js +1 -0
  71. package/dist/gateway/static/root/assets/settings-advanced-gate-pgBQ21Oe.js +1 -0
  72. package/dist/gateway/static/root/assets/{settings-form-section-CSaiuuer.js → settings-form-section-BaWFAZv4.js} +1 -1
  73. package/dist/gateway/static/root/assets/{settings-loading-skeleton-H3mJwt3r.js → settings-loading-skeleton-BWmdZfNg.js} +1 -1
  74. package/dist/gateway/static/root/assets/{settings-page-Cs7zA4BS.js → settings-page-Btcb-Dc8.js} +1 -1
  75. package/dist/gateway/static/root/assets/setup-status-panel-BNllZUFP.js +1 -0
  76. package/dist/gateway/static/root/assets/{share-preview-page-Bdpw5m7M.js → share-preview-page-CGzY3S0N.js} +1 -1
  77. package/dist/gateway/static/root/assets/shares-settings-CncwbTHY.js +1 -0
  78. package/dist/gateway/static/root/assets/skill-reload-api-CcW2dhSW.js +1 -0
  79. package/dist/gateway/static/root/assets/{skills-page-Bup3Lg1Z.js → skills-page-Bi2IWpU0.js} +1 -1
  80. package/dist/gateway/static/root/assets/{skills-page.utils-D22ORR21.js → skills-page.utils-BancvwN2.js} +1 -1
  81. package/dist/gateway/static/root/assets/{system-settings-panel-GmtWsfjB.js → system-settings-panel-CihjIzWx.js} +1 -1
  82. package/dist/gateway/static/root/assets/task-detail-page-SSNFtY-d.js +1 -0
  83. package/dist/gateway/static/root/assets/{theme-store-CtY8RwMX.js → theme-store-D1_t_31B.js} +1 -1
  84. package/dist/gateway/static/root/assets/{typed-models-lib-C2aOdlEA.js → typed-models-lib-C2LhiQq5.js} +1 -1
  85. package/dist/gateway/static/root/assets/{use-autosave-DOj5i8d_.js → use-autosave-tf_8rxAK.js} +1 -1
  86. package/dist/gateway/static/root/assets/user-context-page-BnPTFEar.js +1 -0
  87. package/dist/gateway/static/root/assets/{voice-api-key-field-5WfurWYa.js → voice-api-key-field-DN-y7Zfe.js} +1 -1
  88. package/dist/gateway/static/root/assets/work-discovery-overlay-bqqH4aZ9.js +1 -0
  89. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-bBA8LinI.js → workflow-run-setup-panel-2H33iXOB.js} +2 -2
  90. package/dist/gateway/static/root/assets/workflows-page-BnfxRf1q.js +5 -0
  91. package/dist/gateway/static/root/index.html +13 -11
  92. package/dist/package.js +1 -1
  93. package/dist/src/agent/agent-manager.js +1 -1
  94. package/dist/src/agent/image/generation/providers/xopc-cloud.js +2 -1
  95. package/dist/src/agent/image/tool-model-config.js +15 -9
  96. package/dist/src/agent/memory/builtin-provider.js +0 -1
  97. package/dist/src/agent/memory/create-memory-manager.js +1 -1
  98. package/dist/src/agent/tools/image-generate-tool.js +23 -7
  99. package/dist/src/agent-runtime/index.js +1 -1
  100. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  101. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  102. package/dist/src/capabilities/readiness/from-config.d.ts +10 -0
  103. package/dist/src/capabilities/readiness/from-config.js +128 -0
  104. package/dist/src/capabilities/readiness/index.d.ts +3 -0
  105. package/dist/src/capabilities/readiness/index.js +3 -0
  106. package/dist/src/capabilities/readiness/planner.d.ts +3 -0
  107. package/dist/src/capabilities/readiness/planner.js +56 -0
  108. package/dist/src/capabilities/readiness/types.d.ts +35 -0
  109. package/dist/src/capabilities/readiness/types.js +1 -0
  110. package/dist/src/cli/commands/agent.js +9 -0
  111. package/dist/src/cli/commands/auth.js +4 -3
  112. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  113. package/dist/src/cli/commands/models.js +2 -1
  114. package/dist/src/cli/commands/onboard/model.d.ts +3 -21
  115. package/dist/src/cli/commands/onboard/model.js +10 -86
  116. package/dist/src/cli/commands/tunnel.js +3 -3
  117. package/dist/src/cli/utils/oauth-login.d.ts +2 -0
  118. package/dist/src/cli/utils/oauth-login.js +9 -1
  119. package/dist/src/config/index.js +2 -2
  120. package/dist/src/config/paths-state.d.ts +2 -0
  121. package/dist/src/config/paths-state.js +5 -1
  122. package/dist/src/config/paths.d.ts +1 -1
  123. package/dist/src/config/paths.js +2 -2
  124. package/dist/src/config/schema.js +1 -1
  125. package/dist/src/connectors/composio-managed-client.d.ts +60 -0
  126. package/dist/src/connectors/composio-managed-client.js +135 -0
  127. package/dist/src/connectors/composio-managed-events.d.ts +41 -0
  128. package/dist/src/connectors/composio-managed-events.js +105 -0
  129. package/dist/src/connectors/composio-sessions.d.ts +3 -1
  130. package/dist/src/connectors/composio-sessions.js +15 -8
  131. package/dist/src/connectors/composio.js +10 -4
  132. package/dist/src/connectors/connected-source-cursor.d.ts +9 -0
  133. package/dist/src/connectors/connected-source-cursor.js +30 -0
  134. package/dist/src/connectors/connected-source-ingestion.js +128 -65
  135. package/dist/src/connectors/connected-source-normalizers.d.ts +1 -0
  136. package/dist/src/connectors/connected-source-normalizers.js +33 -2
  137. package/dist/src/connectors/connected-source-sanitization.d.ts +1 -0
  138. package/dist/src/connectors/connected-source-sanitization.js +21 -0
  139. package/dist/src/connectors/connector-identity.js +10 -2
  140. package/dist/src/connectors/content-enrichment.d.ts +29 -0
  141. package/dist/src/connectors/content-enrichment.js +273 -0
  142. package/dist/src/connectors/learning-coordinator.js +1 -2
  143. package/dist/src/connectors/learning-recipes.js +30 -33
  144. package/dist/src/connectors/runtime-adapter-registry.js +2 -2
  145. package/dist/src/discussions/live-worker.d.ts +1 -0
  146. package/dist/src/discussions/live-worker.js +7 -1
  147. package/dist/src/discussions/repository.js +11 -1
  148. package/dist/src/discussions/sealer.d.ts +1 -1
  149. package/dist/src/discussions/sealer.js +16 -7
  150. package/dist/src/discussions/service.js +6 -2
  151. package/dist/src/discussions/transcript.d.ts +2 -0
  152. package/dist/src/discussions/transcript.js +42 -3
  153. package/dist/src/discussions/types.d.ts +4 -0
  154. package/dist/src/extensions/install.d.ts +10 -0
  155. package/dist/src/extensions/install.js +111 -14
  156. package/dist/src/extensions/loader.js +22 -18
  157. package/dist/src/gateway/hono/app.js +8 -3
  158. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  159. package/dist/src/gateway/hono/middleware/auth.js +2 -2
  160. package/dist/src/gateway/hono/middleware/logger.js +1 -1
  161. package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
  162. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +9 -2
  163. package/dist/src/gateway/hono/oauth-async.d.ts +11 -5
  164. package/dist/src/gateway/hono/oauth-async.js +29 -16
  165. package/dist/src/gateway/hono/oauth.d.ts +1 -3
  166. package/dist/src/gateway/hono/oauth.js +22 -22
  167. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  168. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  169. package/dist/src/gateway/hono/routes/connectors.js +10 -3
  170. package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
  171. package/dist/src/gateway/hono/routes/discussions.js +2 -1
  172. package/dist/src/gateway/hono/routes/exposure.js +1 -1
  173. package/dist/src/gateway/hono/routes/home.d.ts +1 -1
  174. package/dist/src/gateway/hono/routes/home.js +2 -2
  175. package/dist/src/gateway/hono/routes/lazy-bundles.js +2 -1
  176. package/dist/src/gateway/hono/routes/models.js +59 -5
  177. package/dist/src/gateway/hono/routes/shares.js +1 -1
  178. package/dist/src/gateway/hono/routes/tunnel.js +3 -3
  179. package/dist/src/gateway/hono/routes/understanding-sources.js +29 -0
  180. package/dist/src/gateway/hono/routes/voice.d.ts +1 -2
  181. package/dist/src/gateway/hono/routes/voice.js +16 -35
  182. package/dist/src/gateway/hono/routes/workflows.js +69 -0
  183. package/dist/src/gateway/index.js +2 -2
  184. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  185. package/dist/src/gateway/rate-limit/buckets.js +12 -0
  186. package/dist/src/gateway/runtime-config.js +2 -2
  187. package/dist/src/gateway/security/audit.js +2 -2
  188. package/dist/src/gateway/service/config-coordinator.js +1 -1
  189. package/dist/src/gateway/service/session-input-coordinator.js +1 -2
  190. package/dist/src/gateway/service.d.ts +1 -0
  191. package/dist/src/gateway/service.js +37 -7
  192. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +1 -1
  193. package/dist/src/knowledge/connected-understanding-pipeline.js +74 -25
  194. package/dist/src/knowledge/ingestion-service.js +33 -15
  195. package/dist/src/knowledge/types.d.ts +2 -0
  196. package/dist/src/media-understanding/audio-transcription-runner.d.ts +2 -0
  197. package/dist/src/media-understanding/audio-transcription-runner.js +3 -1
  198. package/dist/src/media-understanding/runner.js +3 -1
  199. package/dist/src/media-understanding/types.d.ts +2 -0
  200. package/dist/src/notes/note-attachment-sync.js +1 -1
  201. package/dist/src/notes/service.d.ts +1 -0
  202. package/dist/src/notes/service.js +2 -1
  203. package/dist/src/notes/types.d.ts +2 -0
  204. package/dist/src/providers/model-catalog-persistence.d.ts +9 -0
  205. package/dist/src/providers/model-catalog-persistence.js +172 -0
  206. package/dist/src/providers/model-catalog-ranking.d.ts +2 -0
  207. package/dist/src/providers/model-catalog-ranking.js +17 -0
  208. package/dist/src/providers/model-catalog-store.d.ts +9 -57
  209. package/dist/src/providers/model-catalog-store.js +24 -5
  210. package/dist/src/providers/model-catalog-sync-service.d.ts +3 -3
  211. package/dist/src/providers/model-catalog-sync-service.js +12 -7
  212. package/dist/src/providers/model-catalog-types.d.ts +60 -0
  213. package/dist/src/providers/model-catalog-types.js +1 -0
  214. package/dist/src/providers/provider-auth-service.d.ts +1 -0
  215. package/dist/src/providers/provider-auth-service.js +3 -0
  216. package/dist/src/providers/provider-disconnect-core.d.ts +11 -0
  217. package/dist/src/providers/provider-disconnect-core.js +35 -0
  218. package/dist/src/providers/provider-disconnect.d.ts +3 -0
  219. package/dist/src/providers/provider-disconnect.js +11 -0
  220. package/dist/src/providers/xopc-cloud-catalog-coordinator.d.ts +56 -0
  221. package/dist/src/providers/xopc-cloud-catalog-coordinator.js +182 -0
  222. package/dist/src/providers/xopc-cloud-model-source.d.ts +6 -10
  223. package/dist/src/providers/xopc-cloud-model-source.js +49 -27
  224. package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
  225. package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
  226. package/dist/src/storage/sqlite/migrations/124_workflow_context_snapshots.sql +15 -0
  227. package/dist/src/storage/sqlite/migrations/125_project_workflow_presets.sql +12 -0
  228. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  229. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  230. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  231. package/dist/src/storage/sqlite/schema.js +1 -1
  232. package/dist/src/storage/sqlite/user-context-quality-repository.d.ts +8 -0
  233. package/dist/src/storage/sqlite/user-context-quality-repository.js +21 -1
  234. package/dist/src/tasks/home-query-service.d.ts +12 -127
  235. package/dist/src/tasks/home-query-service.js +73 -271
  236. package/dist/src/tasks/index.js +2 -2
  237. package/dist/src/tui/backends/embedded-backend.js +11 -3
  238. package/dist/src/tui/tui-oauth-login.js +5 -0
  239. package/dist/src/tui/xopc-tui-keybindings.d.ts +2 -2
  240. package/dist/src/tunnel/index.js +2 -2
  241. package/dist/src/user-context/sources/activity-clustering.js +30 -117
  242. package/dist/src/user-context/sources/index.d.ts +1 -0
  243. package/dist/src/user-context/sources/index.js +2 -1
  244. package/dist/src/user-context/sources/signal-clustering.d.ts +18 -0
  245. package/dist/src/user-context/sources/signal-clustering.js +131 -0
  246. package/dist/src/voice/audio/normalize.d.ts +18 -0
  247. package/dist/src/voice/audio/normalize.js +175 -0
  248. package/dist/src/voice/language-profile.d.ts +1 -4
  249. package/dist/src/voice/language-profile.js +2 -25
  250. package/dist/src/voice/local/runtime-client.d.ts +2 -0
  251. package/dist/src/voice/local/runtime-client.js +20 -1
  252. package/dist/src/voice/local/runtime-worker.js +7 -13
  253. package/dist/src/voice/local/wav.d.ts +3 -0
  254. package/dist/src/voice/local/wav.js +11 -5
  255. package/dist/src/voice/stt/availability.d.ts +1 -4
  256. package/dist/src/voice/stt/availability.js +3 -15
  257. package/dist/src/voice/stt/config.js +1 -0
  258. package/dist/src/voice/stt/factory.js +23 -0
  259. package/dist/src/voice/stt/index.d.ts +1 -0
  260. package/dist/src/voice/stt/index.js +2 -2
  261. package/dist/src/voice/stt/list-providers.js +1 -1
  262. package/dist/src/voice/stt/providers/local-transcription.js +7 -3
  263. package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +3 -1
  264. package/dist/src/voice/stt/transcribe-core.d.ts +5 -1
  265. package/dist/src/voice/stt/transcribe-core.js +13 -5
  266. package/dist/src/voice/stt/types.d.ts +2 -0
  267. package/dist/src/voice/tts/factory.d.ts +1 -1
  268. package/dist/src/voice/tts/factory.js +23 -1
  269. package/dist/src/voice/tts/merge-config.js +5 -3
  270. package/dist/src/voice/tts/providers/xopc-cloud-speech.js +3 -1
  271. package/dist/src/voice/tts/types.d.ts +2 -0
  272. package/dist/src/voice/tts/types.js +4 -2
  273. package/dist/src/work-discovery/evaluation.d.ts +23 -0
  274. package/dist/src/work-discovery/evaluation.js +18 -1
  275. package/dist/src/work-discovery/index.js +2 -2
  276. package/dist/src/work-discovery/service.js +6 -8
  277. package/dist/src/work-discovery/types.d.ts +2 -0
  278. package/dist/src/workflows/context/workflow-context-snapshot-repository.d.ts +21 -0
  279. package/dist/src/workflows/context/workflow-context-snapshot-repository.js +40 -0
  280. package/dist/src/workflows/context/workflow-context.d.ts +18 -0
  281. package/dist/src/workflows/context/workflow-context.js +159 -0
  282. package/dist/src/workflows/domain/run.d.ts +10 -1
  283. package/dist/src/workflows/engine/workflow-engine.d.ts +1 -0
  284. package/dist/src/workflows/engine/workflow-engine.js +2 -0
  285. package/dist/src/workflows/project-presets/project-workflow-preset-repository.d.ts +20 -0
  286. package/dist/src/workflows/project-presets/project-workflow-preset-repository.js +38 -0
  287. package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
  288. package/dist/src/workflows/service/workflow-run-service.js +107 -22
  289. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
  290. package/dist/src/workflows/service/workflow-writeback-service.d.ts +9 -0
  291. package/dist/src/workflows/service/workflow-writeback-service.js +106 -0
  292. package/package.json +9 -8
  293. package/dist/gateway/static/root/assets/agents-DqGMj3QJ.js +0 -68
  294. package/dist/gateway/static/root/assets/apps-page-BT7F4WBI.js +0 -1
  295. package/dist/gateway/static/root/assets/automations-page-CwOXGV9z.js +0 -6
  296. package/dist/gateway/static/root/assets/browser-settings-page-CyRLhCod.js +0 -8
  297. package/dist/gateway/static/root/assets/capabilities-settings-panel-jRKcS7lZ.js +0 -7
  298. package/dist/gateway/static/root/assets/capability-presets-settings-panel-B3bKdtwU.js +0 -3
  299. package/dist/gateway/static/root/assets/channels-settings-yZBWH02s.js +0 -1
  300. package/dist/gateway/static/root/assets/channels-status-swr-C3zlimZd.js +0 -1
  301. package/dist/gateway/static/root/assets/connectors-page-OX4KvUkA.js +0 -2
  302. package/dist/gateway/static/root/assets/directory-picker-path-field-OkqRFyRL.js +0 -1
  303. package/dist/gateway/static/root/assets/gateway-settings-V1XVxjHa.js +0 -1
  304. package/dist/gateway/static/root/assets/heartbeat-settings-CWUBAQrE.js +0 -1
  305. package/dist/gateway/static/root/assets/home-page-D57cYRd3.js +0 -1
  306. package/dist/gateway/static/root/assets/index-DJ7HSgKs.js +0 -85
  307. package/dist/gateway/static/root/assets/index-PNBFdxHb.css +0 -2
  308. package/dist/gateway/static/root/assets/local-app-workbench-page-BbAiMZE1.js +0 -2
  309. package/dist/gateway/static/root/assets/markdown-view-B12xeflb.css +0 -1
  310. package/dist/gateway/static/root/assets/messages-1qg_hOOd.js +0 -3
  311. package/dist/gateway/static/root/assets/notes-workbench-BYPoZeRw.js +0 -4
  312. package/dist/gateway/static/root/assets/project-detail-page-D27nOKbo.js +0 -1
  313. package/dist/gateway/static/root/assets/projects-page-CdB5cJJ-.js +0 -1
  314. package/dist/gateway/static/root/assets/remote-access-hub-DFoZ3UNS.js +0 -1
  315. package/dist/gateway/static/root/assets/sessions-page-C1cbIcJ7.js +0 -1
  316. package/dist/gateway/static/root/assets/settings-advanced-gate-DnXRlQXS.js +0 -1
  317. package/dist/gateway/static/root/assets/setup-status-panel-CwgMODfJ.js +0 -1
  318. package/dist/gateway/static/root/assets/shares-settings-hlUgIkrp.js +0 -1
  319. package/dist/gateway/static/root/assets/skill-reload-api-DR31B_Gz.js +0 -1
  320. package/dist/gateway/static/root/assets/task-detail-page-CTKDpxhf.js +0 -1
  321. package/dist/gateway/static/root/assets/user-context-page-keJJYpix.js +0 -1
  322. package/dist/gateway/static/root/assets/work-discovery-overlay-D5_MH3n3.js +0 -1
  323. package/dist/gateway/static/root/assets/work-discovery-page-BcvBiebt.js +0 -1
  324. package/dist/gateway/static/root/assets/workflows-page-Cz2VpWdj.js +0 -5
  325. package/dist/src/voice/local/runtime-dispatcher.d.ts +0 -9
  326. package/dist/src/voice/local/runtime-dispatcher.js +0 -20
@@ -1,68 +1,20 @@
1
- export interface CatalogModel {
2
- id: string;
3
- name: string;
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;
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
- };
41
- }
42
- export interface CatalogSource {
43
- providerId: string;
44
- baseUrl: string;
45
- api: 'openai-completions' | 'openai-responses';
46
- etag: string | null;
47
- recommendedModel: string | null;
48
- lastSuccessAt: number;
49
- models: CatalogModel[];
50
- }
51
- export interface ModelCatalogSnapshot {
52
- sources: Record<string, CatalogSource>;
53
- }
54
- export type AvailableCatalogModel = Omit<CatalogModel, 'availability'>;
1
+ import type { AvailableCatalogModel, CatalogSource, CatalogSourceOrigin, ModelCatalogSnapshot } from './model-catalog-types.js';
2
+ export type { AvailableCatalogModel, CatalogModel, CatalogSource, CatalogSourceOrigin, ModelCatalogSnapshot, } from './model-catalog-types.js';
55
3
  export declare class ModelCatalogStore {
56
4
  private sources;
5
+ private origins;
57
6
  load(): ModelCatalogSnapshot;
58
7
  getSource(sourceId: string): CatalogSource | undefined;
59
- saveSource(sourceId: string, source: CatalogSource): void;
8
+ getSourceOrigin(sourceId: string): CatalogSourceOrigin | undefined;
9
+ saveSource(sourceId: string, source: CatalogSource, origin?: CatalogSourceOrigin): void;
60
10
  removeSource(sourceId: string): boolean;
61
- replaceSourceModels(sourceId: string, source: Omit<CatalogSource, 'models'>, models: AvailableCatalogModel[]): {
11
+ replaceSourceModels(sourceId: string, source: Omit<CatalogSource, 'models'>, models: AvailableCatalogModel[], origin?: CatalogSourceOrigin): {
62
12
  addedCount: number;
63
13
  unavailableCount: number;
64
14
  };
65
15
  private cloneSource;
66
16
  }
67
17
  export declare function getModelCatalogStore(): ModelCatalogStore;
68
- export declare function resetModelCatalogStore(): void;
18
+ export declare function resetModelCatalogStore(options?: {
19
+ rehydrate?: boolean;
20
+ }): void;
@@ -1,16 +1,25 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
+ import { ModelCatalogPersistence, init_model_catalog_persistence } from "./model-catalog-persistence.js";
2
3
  //#region src/providers/model-catalog-store.ts
3
4
  function getModelCatalogStore() {
4
5
  globalModelCatalogStore ??= new ModelCatalogStore();
6
+ if (!globalCatalogHydrated) {
7
+ globalCatalogHydrated = true;
8
+ const source = new ModelCatalogPersistence().loadSync();
9
+ if (source) globalModelCatalogStore.saveSource("xopc-cloud", source, "disk");
10
+ }
5
11
  return globalModelCatalogStore;
6
12
  }
7
- function resetModelCatalogStore() {
13
+ function resetModelCatalogStore(options = {}) {
8
14
  globalModelCatalogStore = void 0;
15
+ if (options.rehydrate) globalCatalogHydrated = false;
9
16
  }
10
- var ModelCatalogStore, globalModelCatalogStore;
17
+ var ModelCatalogStore, globalModelCatalogStore, globalCatalogHydrated;
11
18
  var init_model_catalog_store = __esmMin((() => {
19
+ init_model_catalog_persistence();
12
20
  ModelCatalogStore = class {
13
21
  sources = {};
22
+ origins = {};
14
23
  load() {
15
24
  return { sources: Object.fromEntries(Object.entries(this.sources).map(([id, source]) => [id, this.cloneSource(source)])) };
16
25
  }
@@ -18,19 +27,28 @@ var init_model_catalog_store = __esmMin((() => {
18
27
  const source = this.sources[sourceId];
19
28
  return source ? this.cloneSource(source) : void 0;
20
29
  }
21
- saveSource(sourceId, source) {
30
+ getSourceOrigin(sourceId) {
31
+ return this.origins[sourceId];
32
+ }
33
+ saveSource(sourceId, source, origin = "memory") {
22
34
  this.sources = {
23
35
  ...this.sources,
24
36
  [sourceId]: this.cloneSource(source)
25
37
  };
38
+ this.origins = {
39
+ ...this.origins,
40
+ [sourceId]: origin
41
+ };
26
42
  }
27
43
  removeSource(sourceId) {
28
44
  if (!this.sources[sourceId]) return false;
29
45
  const { [sourceId]: _removed, ...sources } = this.sources;
46
+ const { [sourceId]: _removedOrigin, ...origins } = this.origins;
30
47
  this.sources = sources;
48
+ this.origins = origins;
31
49
  return true;
32
50
  }
33
- replaceSourceModels(sourceId, source, models) {
51
+ replaceSourceModels(sourceId, source, models, origin = "memory") {
34
52
  const previous = this.getSource(sourceId);
35
53
  const nextIds = new Set(models.map((model) => model.id));
36
54
  const previousAvailableIds = new Set((previous?.models ?? []).filter((model) => model.availability === "available").map((model) => model.id));
@@ -44,7 +62,7 @@ var init_model_catalog_store = __esmMin((() => {
44
62
  ...model,
45
63
  availability: "available"
46
64
  })), ...unavailable]
47
- });
65
+ }, origin);
48
66
  return {
49
67
  addedCount: models.filter((model) => !previousAvailableIds.has(model.id)).length,
50
68
  unavailableCount: unavailable.length
@@ -81,6 +99,7 @@ var init_model_catalog_store = __esmMin((() => {
81
99
  };
82
100
  }
83
101
  };
102
+ globalCatalogHydrated = false;
84
103
  }));
85
104
  //#endregion
86
105
  init_model_catalog_store();
@@ -2,7 +2,7 @@ import type { Config } from '../config/schema.js';
2
2
  import { type ModelsJsonConfig } from '../config/models-json.js';
3
3
  import { type ModelCatalogStore } from './model-catalog-store.js';
4
4
  import { discoverProviderModels } from './model-discovery.js';
5
- import { XopcCloudModelSource } from './xopc-cloud-model-source.js';
5
+ import { type CatalogReadiness, type XopcCloudCatalogCoordinator } from './xopc-cloud-catalog-coordinator.js';
6
6
  export interface ModelCatalogSyncStatus {
7
7
  running: boolean;
8
8
  refreshing: boolean;
@@ -21,7 +21,7 @@ export declare class ModelCatalogSyncService {
21
21
  constructor(options?: {
22
22
  intervalMs?: number;
23
23
  onUpdated?: (modelCount: number) => void;
24
- xopcCloud?: XopcCloudModelSource;
24
+ xopcCloud?: Pick<XopcCloudCatalogCoordinator, 'refresh'>;
25
25
  getConfig?: () => Config;
26
26
  catalogStore?: ModelCatalogStore;
27
27
  loadProviders?: () => ModelsJsonConfig['providers'];
@@ -32,7 +32,7 @@ export declare class ModelCatalogSyncService {
32
32
  start(): void;
33
33
  stop(): void;
34
34
  getStatus(): ModelCatalogSyncStatus;
35
- refreshNow(): Promise<Awaited<ReturnType<XopcCloudModelSource['refresh']>>>;
35
+ refreshNow(): Promise<CatalogReadiness>;
36
36
  refreshAll(): Promise<{
37
37
  updatedSources: string[];
38
38
  }>;
@@ -4,7 +4,7 @@ import { init_models_json, loadModelsJson } from "../config/models-json.js";
4
4
  import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
5
5
  import { getModelRegistry, init_model_registry } from "./model-registry.js";
6
6
  import { discoverProviderModels, isProviderApiDiscoverable } from "./model-discovery.js";
7
- import { XopcCloudModelSource } from "./xopc-cloud-model-source.js";
7
+ import { getXopcCloudCatalogCoordinator } from "./xopc-cloud-catalog-coordinator.js";
8
8
  //#region src/providers/model-catalog-sync-service.ts
9
9
  init_logger();
10
10
  init_models_json();
@@ -23,7 +23,7 @@ var ModelCatalogSyncService = class {
23
23
  };
24
24
  constructor(options = {}) {
25
25
  this.options = options;
26
- this.xopcCloud = options.xopcCloud ?? new XopcCloudModelSource();
26
+ this.xopcCloud = options.xopcCloud ?? getXopcCloudCatalogCoordinator();
27
27
  }
28
28
  start() {
29
29
  if (this.status.running) return;
@@ -47,12 +47,15 @@ var ModelCatalogSyncService = class {
47
47
  if (this.refreshPromise) return this.refreshPromise;
48
48
  this.status.refreshing = true;
49
49
  this.status.lastAttemptAt = Date.now();
50
- this.refreshPromise = this.xopcCloud.refresh().then((result) => {
51
- if (result.status === "updated") {
50
+ this.refreshPromise = this.xopcCloud.refresh("manual").then((result) => {
51
+ if (result.state === "not-authorized") {
52
+ this.status.lastError = result.error?.message;
53
+ this.options.onUpdated?.(0);
54
+ } else if (result.source === "network" && !result.error) {
52
55
  this.status.lastSuccessAt = Date.now();
53
56
  this.status.lastError = void 0;
54
- this.options.onUpdated?.(result.modelCount ?? 0);
55
- }
57
+ this.options.onUpdated?.(result.modelCount);
58
+ } else if (result.error) this.status.lastError = result.error.message;
56
59
  return result;
57
60
  }).catch((err) => {
58
61
  const errorMessage = err instanceof Error ? err.message : String(err);
@@ -81,7 +84,9 @@ var ModelCatalogSyncService = class {
81
84
  const updatedSources = [];
82
85
  const sourceErrors = {};
83
86
  try {
84
- if ((await this.refreshNow()).status === "updated") updatedSources.push("xopc-cloud");
87
+ const cloud = await this.refreshNow();
88
+ if (cloud.source === "network" && !cloud.error) updatedSources.push("xopc-cloud");
89
+ if (cloud.error) sourceErrors["xopc-cloud"] = cloud.error.message;
85
90
  } catch (err) {
86
91
  sourceErrors["xopc-cloud"] = err instanceof Error ? err.message : String(err);
87
92
  }
@@ -0,0 +1,60 @@
1
+ export interface CatalogModel {
2
+ id: string;
3
+ name: string;
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;
11
+ maxOutputTokens: number | null;
12
+ stability?: 'stable' | 'preview' | 'deprecated';
13
+ priority?: number;
14
+ tier?: string;
15
+ bestEffort?: boolean;
16
+ imageGeneration?: {
17
+ maxCount: number;
18
+ sizes: string[];
19
+ aspectRatios?: string[];
20
+ qualities: Array<'low' | 'medium' | 'high' | 'auto'>;
21
+ formats: Array<'png' | 'jpeg' | 'webp'>;
22
+ backgrounds: Array<'transparent' | 'opaque' | 'auto'>;
23
+ maxInputImages: number;
24
+ };
25
+ stt?: {
26
+ inputFormats: string[];
27
+ maxBytes: number;
28
+ maxDurationSeconds: number;
29
+ languages: string[];
30
+ languageHint: boolean;
31
+ prompt: boolean;
32
+ timestamps: Array<'segment' | 'word'>;
33
+ diarization: boolean;
34
+ };
35
+ tts?: {
36
+ maxCharacters: number;
37
+ languages: string[];
38
+ outputFormats: Array<'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'>;
39
+ streaming: boolean;
40
+ speed: boolean;
41
+ pitch: boolean;
42
+ instructions: boolean;
43
+ defaultVoice?: string;
44
+ };
45
+ }
46
+ export interface CatalogSource {
47
+ providerId: string;
48
+ baseUrl: string;
49
+ api: 'openai-completions' | 'openai-responses';
50
+ etag: string | null;
51
+ recommendedModel: string | null;
52
+ recommended?: Partial<Record<'vision' | 'image-generation' | 'stt' | 'tts', string>>;
53
+ lastSuccessAt: number;
54
+ models: CatalogModel[];
55
+ }
56
+ export interface ModelCatalogSnapshot {
57
+ sources: Record<string, CatalogSource>;
58
+ }
59
+ export type CatalogSourceOrigin = 'memory' | 'disk' | 'network';
60
+ export type AvailableCatalogModel = Omit<CatalogModel, 'availability'>;
@@ -0,0 +1 @@
1
+ export {};
@@ -15,6 +15,7 @@ export declare class ProviderAuthService {
15
15
  private runtime;
16
16
  constructor(options?: ProviderAuthServiceOptions);
17
17
  resolveApiKey(providerId: string, signal?: AbortSignal): Promise<string | null>;
18
+ invalidate(): void;
18
19
  private getRuntime;
19
20
  }
20
21
  export declare function getProviderAuthService(): ProviderAuthService;
@@ -55,6 +55,9 @@ var init_provider_auth_service = __esmMin((() => {
55
55
  }
56
56
  return await this.resolver.resolveApiKey(providerId);
57
57
  }
58
+ invalidate() {
59
+ this.runtime = void 0;
60
+ }
58
61
  getRuntime() {
59
62
  this.runtime ??= this.runtimeFactory(this.credentials).catch((error) => {
60
63
  this.runtime = void 0;
@@ -0,0 +1,11 @@
1
+ import { CredentialResolver } from '../auth/credentials.js';
2
+ export interface ProviderDisconnectOptions {
3
+ resolver?: Pick<CredentialResolver, 'deleteProviderCredential'>;
4
+ invalidateAuth?: () => void;
5
+ clearCloudCatalog?: () => Promise<void>;
6
+ refreshModels?: () => void;
7
+ evictRunners?: () => void;
8
+ withLock?: <T>(providerId: string, operation: () => Promise<T>) => Promise<T>;
9
+ }
10
+ /** Low-level disconnect operation. Cloud callers must inject catalog cleanup. */
11
+ export declare function disconnectProviderCore(providerId: string, options?: ProviderDisconnectOptions): Promise<void>;
@@ -0,0 +1,35 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { getModelRegistry, init_model_registry } from "./model-registry.js";
4
+ import { init_oauth_provider_lock, withOAuthProviderLock } from "../auth/oauth-provider-lock.js";
5
+ import { CredentialResolver, init_credentials } from "../auth/credentials.js";
6
+ import { getProviderAuthService, init_provider_auth_service } from "./provider-auth-service.js";
7
+ import { evictAllEmbeddedSessionRunners } from "../agent/embedded/session-runner.js";
8
+ //#region src/providers/provider-disconnect-core.ts
9
+ init_credentials();
10
+ init_oauth_provider_lock();
11
+ init_logger();
12
+ init_model_registry();
13
+ init_provider_auth_service();
14
+ const log = createLogger("ProviderDisconnect");
15
+ /** Low-level disconnect operation. Cloud callers must inject catalog cleanup. */
16
+ async function disconnectProviderCore(providerId, options = {}) {
17
+ const provider = providerId.trim().toLowerCase();
18
+ if (!provider) throw new Error("Provider id is required");
19
+ const resolver = options.resolver ?? new CredentialResolver();
20
+ await (options.withLock ?? ((id, operation) => withOAuthProviderLock(id, operation)))(provider, async () => {
21
+ await resolver.deleteProviderCredential(provider);
22
+ (options.invalidateAuth ?? (() => getProviderAuthService().invalidate()))();
23
+ if (provider === "xopc-cloud") {
24
+ if (!options.clearCloudCatalog) throw new Error("XOPC Cloud disconnect requires a catalog cleanup hook");
25
+ await options.clearCloudCatalog();
26
+ } else (options.refreshModels ?? (() => getModelRegistry().refresh()))();
27
+ (options.evictRunners ?? (() => evictAllEmbeddedSessionRunners("provider_disconnected")))();
28
+ });
29
+ log.info({
30
+ provider,
31
+ phase: "provider_revoked"
32
+ }, `Disconnected provider: ${provider}`);
33
+ }
34
+ //#endregion
35
+ export { disconnectProviderCore };
@@ -0,0 +1,3 @@
1
+ import { type ProviderDisconnectOptions } from './provider-disconnect-core.js';
2
+ export type { ProviderDisconnectOptions } from './provider-disconnect-core.js';
3
+ export declare function disconnectProvider(providerId: string, options?: ProviderDisconnectOptions): Promise<void>;
@@ -0,0 +1,11 @@
1
+ import { disconnectProviderCore } from "./provider-disconnect-core.js";
2
+ import { getXopcCloudCatalogCoordinator } from "./xopc-cloud-catalog-coordinator.js";
3
+ //#region src/providers/provider-disconnect.ts
4
+ async function disconnectProvider(providerId, options = {}) {
5
+ return disconnectProviderCore(providerId, {
6
+ ...options,
7
+ clearCloudCatalog: options.clearCloudCatalog ?? (() => getXopcCloudCatalogCoordinator().clear("revoke"))
8
+ });
9
+ }
10
+ //#endregion
11
+ export { disconnectProvider };
@@ -0,0 +1,56 @@
1
+ import { ModelCatalogPersistence } from './model-catalog-persistence.js';
2
+ import { type CatalogSourceOrigin, type ModelCatalogStore } from './model-catalog-store.js';
3
+ import { XopcCloudModelSource } from './xopc-cloud-model-source.js';
4
+ export type CatalogEnsureReason = 'startup' | 'oauth' | 'agent-run' | 'manual' | 'recovery';
5
+ export interface EnsureCatalogOptions {
6
+ reason: CatalogEnsureReason;
7
+ network: 'never' | 'if-empty' | 'always';
8
+ timeoutMs?: number;
9
+ }
10
+ export interface CatalogReadiness {
11
+ state: 'not-authorized' | 'ready' | 'stale' | 'refreshing' | 'unavailable';
12
+ source: CatalogSourceOrigin | 'none';
13
+ fetchedAt?: number;
14
+ catalogVersion?: string | null;
15
+ modelCount: number;
16
+ error?: {
17
+ code: string;
18
+ message: string;
19
+ retryable: boolean;
20
+ };
21
+ }
22
+ interface CatalogCoordinatorOptions {
23
+ source?: Pick<XopcCloudModelSource, 'fetch'>;
24
+ store?: ModelCatalogStore;
25
+ persistence?: Pick<ModelCatalogPersistence, 'loadSync' | 'save' | 'clear'>;
26
+ staleAfterMs?: number;
27
+ refreshModels?: () => void;
28
+ reloadImageProviders?: () => void;
29
+ withLock?: <T>(operation: () => Promise<T>) => Promise<T>;
30
+ onPermanentAuthFailure?: () => Promise<void>;
31
+ }
32
+ export declare class XopcCloudCatalogCoordinator {
33
+ private readonly source;
34
+ private readonly store;
35
+ private readonly persistence;
36
+ private readonly staleAfterMs;
37
+ private readonly refreshModels;
38
+ private readonly reloadImageProviders;
39
+ private readonly withLock;
40
+ private readonly onPermanentAuthFailure;
41
+ private refreshPromise;
42
+ private generation;
43
+ private lastError;
44
+ private notAuthorized;
45
+ constructor(options?: CatalogCoordinatorOptions);
46
+ hydrate(): Promise<CatalogReadiness>;
47
+ ensure(options: EnsureCatalogOptions): Promise<CatalogReadiness>;
48
+ refresh(reason: CatalogEnsureReason, timeoutMs?: number): Promise<CatalogReadiness>;
49
+ clear(reason: 'revoke' | 'invalid-grant'): Promise<void>;
50
+ snapshot(): CatalogReadiness;
51
+ private buildSnapshot;
52
+ private runRefresh;
53
+ }
54
+ export declare function getXopcCloudCatalogCoordinator(): XopcCloudCatalogCoordinator;
55
+ export declare function resetXopcCloudCatalogCoordinator(): void;
56
+ export {};
@@ -0,0 +1,182 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { ModelCatalogPersistence, init_model_catalog_persistence } from "./model-catalog-persistence.js";
4
+ import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
5
+ import { getModelRegistry, init_model_registry } from "./model-registry.js";
6
+ import { init_oauth_provider_lock, withOAuthProviderLock } from "../auth/oauth-provider-lock.js";
7
+ import { reloadImageGenerationProviders } from "../agent/image/generation/provider-registry.js";
8
+ import { disconnectProviderCore } from "./provider-disconnect-core.js";
9
+ import { XopcCloudModelSource } from "./xopc-cloud-model-source.js";
10
+ //#region src/providers/xopc-cloud-catalog-coordinator.ts
11
+ init_oauth_provider_lock();
12
+ init_logger();
13
+ init_model_catalog_persistence();
14
+ init_model_catalog_store();
15
+ init_model_registry();
16
+ const log = createLogger("XopcCloudCatalog");
17
+ const DEFAULT_STALE_AFTER_MS = 1440 * 6e4;
18
+ var XopcCloudCatalogCoordinator = class {
19
+ source;
20
+ store;
21
+ persistence;
22
+ staleAfterMs;
23
+ refreshModels;
24
+ reloadImageProviders;
25
+ withLock;
26
+ onPermanentAuthFailure;
27
+ refreshPromise = null;
28
+ generation = 0;
29
+ lastError;
30
+ notAuthorized = false;
31
+ constructor(options = {}) {
32
+ this.source = options.source ?? new XopcCloudModelSource();
33
+ this.store = options.store ?? getModelCatalogStore();
34
+ this.persistence = options.persistence ?? new ModelCatalogPersistence();
35
+ this.staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
36
+ this.refreshModels = options.refreshModels ?? (() => getModelRegistry().refresh());
37
+ this.reloadImageProviders = options.reloadImageProviders ?? reloadImageGenerationProviders;
38
+ this.withLock = options.withLock ?? ((operation) => withOAuthProviderLock("xopc-cloud", operation));
39
+ this.onPermanentAuthFailure = options.onPermanentAuthFailure ?? (async () => {
40
+ await disconnectProviderCore("xopc-cloud", { clearCloudCatalog: () => this.clear("invalid-grant") });
41
+ });
42
+ }
43
+ async hydrate() {
44
+ if (!this.store.getSource("xopc-cloud")) {
45
+ const source = this.persistence.loadSync();
46
+ if (source) this.store.saveSource("xopc-cloud", source, "disk");
47
+ }
48
+ return this.snapshot();
49
+ }
50
+ async ensure(options) {
51
+ await this.hydrate();
52
+ if (options.network === "never") return this.snapshot();
53
+ if (options.network === "if-empty" && this.store.getSource("xopc-cloud")) return this.snapshot();
54
+ return this.refresh(options.reason, options.timeoutMs);
55
+ }
56
+ refresh(reason, timeoutMs = 3e4) {
57
+ if (this.refreshPromise) return this.refreshPromise;
58
+ const generation = this.generation;
59
+ this.refreshPromise = this.runRefresh(reason, generation, timeoutMs).finally(() => {
60
+ this.refreshPromise = null;
61
+ });
62
+ return this.refreshPromise;
63
+ }
64
+ async clear(reason) {
65
+ this.generation += 1;
66
+ await this.withLock(async () => {
67
+ this.store.removeSource("xopc-cloud");
68
+ await this.persistence.clear();
69
+ this.lastError = void 0;
70
+ this.notAuthorized = reason === "revoke" || reason === "invalid-grant";
71
+ this.refreshModels();
72
+ this.reloadImageProviders();
73
+ log.info({
74
+ provider: "xopc-cloud",
75
+ reason,
76
+ phase: "catalog_commit"
77
+ }, "Cleared XOPC Cloud model catalog");
78
+ });
79
+ }
80
+ snapshot() {
81
+ return this.buildSnapshot(this.refreshPromise !== null);
82
+ }
83
+ buildSnapshot(refreshing) {
84
+ const source = this.store.getSource("xopc-cloud");
85
+ if (!source) return {
86
+ state: this.notAuthorized ? "not-authorized" : "unavailable",
87
+ source: "none",
88
+ modelCount: 0,
89
+ ...this.lastError ? { error: this.lastError } : {}
90
+ };
91
+ const stale = Date.now() - source.lastSuccessAt > this.staleAfterMs;
92
+ return {
93
+ state: refreshing ? "refreshing" : stale ? "stale" : "ready",
94
+ source: this.store.getSourceOrigin("xopc-cloud") ?? "memory",
95
+ fetchedAt: source.lastSuccessAt,
96
+ catalogVersion: source.etag,
97
+ modelCount: source.models.filter((model) => model.availability === "available").length,
98
+ ...this.lastError ? { error: this.lastError } : {}
99
+ };
100
+ }
101
+ async runRefresh(reason, generation, timeoutMs) {
102
+ const startedAt = Date.now();
103
+ try {
104
+ const readiness = await this.withLock(async () => {
105
+ const result = await this.source.fetch(AbortSignal.timeout(timeoutMs));
106
+ if (result.status === "skipped") {
107
+ await this.clear("revoke");
108
+ return this.buildSnapshot(false);
109
+ }
110
+ if (generation !== this.generation) return this.buildSnapshot(false);
111
+ const previous = this.store.getSource("xopc-cloud");
112
+ const previousOrigin = this.store.getSourceOrigin("xopc-cloud");
113
+ this.store.replaceSourceModels("xopc-cloud", result.source, result.models, "network");
114
+ const committed = this.store.getSource("xopc-cloud");
115
+ if (!committed) throw new Error("XOPC Cloud catalog commit failed");
116
+ try {
117
+ await this.persistence.save(committed);
118
+ } catch (error) {
119
+ if (previous) this.store.saveSource("xopc-cloud", previous, previousOrigin ?? "memory");
120
+ else this.store.removeSource("xopc-cloud");
121
+ throw error;
122
+ }
123
+ if (generation !== this.generation) {
124
+ this.store.removeSource("xopc-cloud");
125
+ await this.persistence.clear();
126
+ return this.buildSnapshot(false);
127
+ }
128
+ this.notAuthorized = false;
129
+ this.lastError = void 0;
130
+ this.refreshModels();
131
+ this.reloadImageProviders();
132
+ return this.buildSnapshot(false);
133
+ });
134
+ log.info({
135
+ provider: "xopc-cloud",
136
+ reason,
137
+ phase: "catalog_refresh",
138
+ durationMs: Date.now() - startedAt
139
+ }, `XOPC Cloud model catalog refresh completed with ${readiness.modelCount} models`);
140
+ return readiness;
141
+ } catch (err) {
142
+ const message = err instanceof Error ? err.message : String(err);
143
+ const modelError = asXopcCloudModelError(err);
144
+ if (modelError?.status === 401 && (modelError.code === "invalid_grant" || modelError.code === "invalid_token")) {
145
+ await this.onPermanentAuthFailure();
146
+ this.notAuthorized = true;
147
+ }
148
+ this.lastError = {
149
+ code: modelError ? modelError.code ?? `http_${modelError.status}` : "refresh_failed",
150
+ message,
151
+ retryable: !modelError || modelError.status === 429 || modelError.status >= 500
152
+ };
153
+ log.warn({
154
+ err,
155
+ provider: "xopc-cloud",
156
+ reason,
157
+ phase: "catalog_refresh",
158
+ durationMs: Date.now() - startedAt
159
+ }, `XOPC Cloud model catalog refresh failed: ${message}`);
160
+ return this.buildSnapshot(false);
161
+ }
162
+ }
163
+ };
164
+ function asXopcCloudModelError(error) {
165
+ if (!(error instanceof Error) || error.name !== "XopcCloudModelError") return void 0;
166
+ const candidate = error;
167
+ if (typeof candidate.status !== "number") return void 0;
168
+ return {
169
+ status: candidate.status,
170
+ ...typeof candidate.code === "string" ? { code: candidate.code } : {}
171
+ };
172
+ }
173
+ let globalCoordinator;
174
+ function getXopcCloudCatalogCoordinator() {
175
+ globalCoordinator ??= new XopcCloudCatalogCoordinator();
176
+ return globalCoordinator;
177
+ }
178
+ function resetXopcCloudCatalogCoordinator() {
179
+ globalCoordinator = void 0;
180
+ }
181
+ //#endregion
182
+ export { XopcCloudCatalogCoordinator, getXopcCloudCatalogCoordinator, resetXopcCloudCatalogCoordinator };
@@ -1,12 +1,12 @@
1
- import { type ModelCatalogStore } from './model-catalog-store.js';
1
+ import type { AvailableCatalogModel, CatalogSource } from './model-catalog-store.js';
2
2
  import { type ProviderAuthService } from './provider-auth-service.js';
3
- export type XopcCloudModelRefreshResult = {
3
+ export type XopcCloudCatalogFetchResult = {
4
4
  status: 'skipped';
5
5
  reason: 'not_configured';
6
6
  } | {
7
- status: 'updated';
8
- modelCount: number;
9
- models: string[];
7
+ status: 'fetched';
8
+ source: Omit<CatalogSource, 'models'>;
9
+ models: AvailableCatalogModel[];
10
10
  };
11
11
  export declare class XopcCloudModelError extends Error {
12
12
  readonly status: number;
@@ -17,14 +17,10 @@ export declare class XopcCloudModelSource {
17
17
  private readonly fetchImpl;
18
18
  private readonly routerUrl;
19
19
  private readonly credentials;
20
- private readonly catalogStore;
21
- private readonly refreshModels;
22
20
  constructor(options?: {
23
21
  fetchImpl?: typeof fetch;
24
22
  routerUrl?: string;
25
23
  credentials?: Pick<ProviderAuthService, 'resolveApiKey'>;
26
- catalogStore?: ModelCatalogStore;
27
- refreshModels?: () => void;
28
24
  });
29
- refresh(): Promise<XopcCloudModelRefreshResult>;
25
+ fetch(signal?: AbortSignal): Promise<XopcCloudCatalogFetchResult>;
30
26
  }