@xopcai/xopc 0.0.210 → 0.0.211

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 (263) 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-BzjFoSr0.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CI1zQfzY.js → agent-avatar-dicebear-DTfjhfVE.js} +1 -1
  5. package/dist/gateway/static/root/assets/agents-CjhgfuVJ.js +68 -0
  6. package/dist/gateway/static/root/assets/{api-C6MmWfcb.js → api-D269PnU9.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cd02GGpV.js → app-management-settings-panel-BFpfQDWc.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-Db-h2I3G.js → appearance-settings-DLxFdqhY.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-BT7F4WBI.js → apps-page-CjmlGB5V.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-CMHzJT2a.js → archive-plugin-DPlH4dnc.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-BzhI2LoH.js → attachment-load-xqfLLd0I.js} +1 -1
  12. package/dist/gateway/static/root/assets/automations-page-4m6Ey6wG.js +6 -0
  13. package/dist/gateway/static/root/assets/{binary-plugins-DsUeHvZO.js → binary-plugins-C0tuoPXk.js} +1 -1
  14. package/dist/gateway/static/root/assets/{block-editor-CFfsIeZ4.js → block-editor-Deyphj1o.js} +47 -47
  15. package/dist/gateway/static/root/assets/browser-settings-page-CAGCYx8U.js +8 -0
  16. package/dist/gateway/static/root/assets/{browser-workflow-inputs-BiWghvJ0.js → browser-workflow-inputs-CYEbXyRF.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-workflows-page-DPLdT6Zn.js → browser-workflows-page-Bf0tPbGi.js} +2 -2
  18. package/dist/gateway/static/root/assets/capabilities-settings-panel-CKfLsxTI.js +7 -0
  19. package/dist/gateway/static/root/assets/{capability-presets-api-CTxGFvsS.js → capability-presets-api-DPkFA_-R.js} +1 -1
  20. package/dist/gateway/static/root/assets/capability-presets-settings-panel-CpipKNqX.js +3 -0
  21. package/dist/gateway/static/root/assets/{channel-recipient-api-BklVUOxC.js → channel-recipient-api-DqKaAcnZ.js} +1 -1
  22. package/dist/gateway/static/root/assets/channels-settings-Bvq-O4pt.js +1 -0
  23. package/dist/gateway/static/root/assets/channels-status-swr-CrMld2l7.js +1 -0
  24. package/dist/gateway/static/root/assets/{chat-terminal-dock-0F4Jmma2.js → chat-terminal-dock-CTDRZa7e.js} +2 -2
  25. package/dist/gateway/static/root/assets/{connectors-api-BvIZ51ty.js → connectors-api-Buu8fif8.js} +1 -1
  26. package/dist/gateway/static/root/assets/connectors-page-CSQRzaVn.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-BHmwaMbO.js → cron-expression-DTLR82NB.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-fj_pPCv5.js → date-picker-DyNogHQH.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-DsWvwOv-.js → dependency-picker-BpnCuo7B.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-mjkF0Xxh.js → desktop-pet-CDKI4gVB.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-ClwUpRYu.js → desktop-pet-settings-DjT5C2a3.js} +1 -1
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-OkqRFyRL.js → directory-picker-path-field-DlJY90TM.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-DC69wplH.js → extension-debug-page-DWf2z7q5.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-DCtk6zdJ.js → extension-page-Dorx0kf9.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-Bkm4zzv-.js → extension-settings-page-B1wU9ZOB.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-Dr_NQt7v.js → gateway-config-api-B1lG4dNr.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-CEfv8N1J.js → gateway-config-swr-BIxuwPQi.js} +1 -1
  38. package/dist/gateway/static/root/assets/gateway-settings-DqIOqJjM.js +1 -0
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-B8hebJ7s.js → gateway-startup-retry-BpZgd4U-.js} +1 -1
  40. package/dist/gateway/static/root/assets/heartbeat-settings-DG4Kmgkc.js +1 -0
  41. package/dist/gateway/static/root/assets/home-page-BhqItS_s.js +1 -0
  42. package/dist/gateway/static/root/assets/image-generation-api-PkhYohDa.js +1 -0
  43. package/dist/gateway/static/root/assets/index-DLhvsU9B.css +2 -0
  44. package/dist/gateway/static/root/assets/{index-DJ7HSgKs.js → index-_cuTcWjB.js} +78 -56
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DCQvf05d.js → keyboard-shortcuts-settings-6OQT3gQF.js} +1 -1
  46. package/dist/gateway/static/root/assets/local-app-workbench-page-DWjTmzxw.js +2 -0
  47. package/dist/gateway/static/root/assets/{local-apps-page-B3Ugd0my.js → local-apps-page-DfruRAmE.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-hDBVeG3G.js → locale-store-C5MK9WcP.js} +1 -1
  49. package/dist/gateway/static/root/assets/logs-page-BA5efZ8B.js +2 -0
  50. package/dist/gateway/static/root/assets/{management-settings-C-S5Llq3.js → management-settings-L1VYkywO.js} +1 -1
  51. package/dist/gateway/static/root/assets/{markdown-split-DuVq37Uh.js → markdown-split-oqgHbqt-.js} +1 -1
  52. package/dist/gateway/static/root/assets/markdown-view-DD_PgVue.css +1 -0
  53. package/dist/gateway/static/root/assets/{markdown-view-D8eO_6h3.js → markdown-view-V4rcPPH0.js} +1 -1
  54. package/dist/gateway/static/root/assets/{media-plugins-C1V6pkX3.js → media-plugins-Bb6gSX2o.js} +1 -1
  55. package/dist/gateway/static/root/assets/messages-ctG2e-ix.js +3 -0
  56. package/dist/gateway/static/root/assets/{notes-page-Dn71ZV8c.js → notes-page-B1rOXjpT.js} +1 -1
  57. package/dist/gateway/static/root/assets/notes-workbench-CkHXVmKP.js +4 -0
  58. package/dist/gateway/static/root/assets/{page-tabs-B5a5aSoS.js → page-tabs-CBuCKeyy.js} +1 -1
  59. package/dist/gateway/static/root/assets/{preview-open-alternatives-5041AIBX.js → preview-open-alternatives-BQ0tLfPO.js} +1 -1
  60. package/dist/gateway/static/root/assets/{product-open-page-7UkouFQU.js → product-open-page-DPeFn7Hu.js} +1 -1
  61. package/dist/gateway/static/root/assets/project-detail-page-DCqet9-L.js +1 -0
  62. package/dist/gateway/static/root/assets/projects-page-D0t_AjzG.js +1 -0
  63. package/dist/gateway/static/root/assets/remote-access-hub-BUWPoBvw.js +1 -0
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DvaXzHYS.js → runtime-tools-settings-panel-BCfQNzjG.js} +2 -2
  65. package/dist/gateway/static/root/assets/{schema-form-Dlxl_5X0.js → schema-form-Bo7YbHYN.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-vLhrrM3m.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-OP1y0Y8M.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-CSaiuuer.js → settings-form-section-B9dnKr3M.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-H3mJwt3r.js → settings-loading-skeleton-CYDV2JtY.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-Cs7zA4BS.js → settings-page-DbrIYfS9.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-CwgMODfJ.js → setup-status-panel-Cxc-Ejl5.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-Bdpw5m7M.js → share-preview-page-olgr7LLN.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-ZOqC6-aA.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-DwvC3Iuf.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-Bup3Lg1Z.js → skills-page-PE16CNw5.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-D22ORR21.js → skills-page.utils-nXmBcBxt.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-GmtWsfjB.js → system-settings-panel-C3qPwAdY.js} +1 -1
  78. package/dist/gateway/static/root/assets/task-detail-page-DCRB-5q-.js +1 -0
  79. package/dist/gateway/static/root/assets/{theme-store-CtY8RwMX.js → theme-store-KR5Otp5w.js} +1 -1
  80. package/dist/gateway/static/root/assets/{typed-models-lib-C2aOdlEA.js → typed-models-lib-lMZodtDF.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-autosave-DOj5i8d_.js → use-autosave-CKpatP3S.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-context-page-CoiedRuA.js +1 -0
  83. package/dist/gateway/static/root/assets/{voice-api-key-field-5WfurWYa.js → voice-api-key-field-CDcv0Wbh.js} +1 -1
  84. package/dist/gateway/static/root/assets/{work-discovery-overlay-D5_MH3n3.js → work-discovery-overlay-CGdT22un.js} +1 -1
  85. package/dist/gateway/static/root/assets/work-discovery-page-BwaU1RqI.js +1 -0
  86. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-bBA8LinI.js → workflow-run-setup-panel-BAHYNlQt.js} +2 -2
  87. package/dist/gateway/static/root/assets/workflows-page-DHYmh9G7.js +5 -0
  88. package/dist/gateway/static/root/index.html +10 -10
  89. package/dist/package.js +1 -1
  90. package/dist/src/agent/agent-manager.js +1 -1
  91. package/dist/src/agent/image/generation/providers/xopc-cloud.js +2 -1
  92. package/dist/src/agent/image/tool-model-config.js +15 -9
  93. package/dist/src/agent/memory/builtin-provider.js +0 -1
  94. package/dist/src/agent/memory/create-memory-manager.js +1 -1
  95. package/dist/src/agent/tools/image-generate-tool.js +23 -7
  96. package/dist/src/agent-runtime/index.js +1 -1
  97. package/dist/src/agent-runtime/runtime-profile.js +1 -1
  98. package/dist/src/capabilities/readiness/from-config.d.ts +10 -0
  99. package/dist/src/capabilities/readiness/from-config.js +128 -0
  100. package/dist/src/capabilities/readiness/index.d.ts +3 -0
  101. package/dist/src/capabilities/readiness/index.js +3 -0
  102. package/dist/src/capabilities/readiness/planner.d.ts +3 -0
  103. package/dist/src/capabilities/readiness/planner.js +56 -0
  104. package/dist/src/capabilities/readiness/types.d.ts +35 -0
  105. package/dist/src/capabilities/readiness/types.js +1 -0
  106. package/dist/src/cli/commands/agent.js +9 -0
  107. package/dist/src/cli/commands/auth.js +4 -3
  108. package/dist/src/cli/commands/connectors.js +1 -1
  109. package/dist/src/cli/commands/models.js +2 -1
  110. package/dist/src/cli/commands/onboard/model.d.ts +3 -21
  111. package/dist/src/cli/commands/onboard/model.js +10 -86
  112. package/dist/src/cli/utils/oauth-login.d.ts +2 -0
  113. package/dist/src/cli/utils/oauth-login.js +9 -1
  114. package/dist/src/config/agent-profile.js +1 -1
  115. package/dist/src/config/index.js +2 -2
  116. package/dist/src/config/paths-state.d.ts +2 -0
  117. package/dist/src/config/paths-state.js +5 -1
  118. package/dist/src/config/paths.d.ts +1 -1
  119. package/dist/src/config/paths.js +2 -2
  120. package/dist/src/config/schema.js +1 -1
  121. package/dist/src/connectors/composio-sessions.d.ts +1 -0
  122. package/dist/src/connectors/composio-sessions.js +2 -1
  123. package/dist/src/connectors/composio.js +8 -3
  124. package/dist/src/connectors/connected-source-cursor.d.ts +9 -0
  125. package/dist/src/connectors/connected-source-cursor.js +30 -0
  126. package/dist/src/connectors/connected-source-ingestion.js +67 -46
  127. package/dist/src/connectors/connected-source-normalizers.d.ts +1 -0
  128. package/dist/src/connectors/connected-source-normalizers.js +33 -2
  129. package/dist/src/connectors/connected-source-sanitization.d.ts +1 -0
  130. package/dist/src/connectors/connected-source-sanitization.js +21 -0
  131. package/dist/src/connectors/connector-identity.js +10 -2
  132. package/dist/src/connectors/content-enrichment.d.ts +29 -0
  133. package/dist/src/connectors/content-enrichment.js +273 -0
  134. package/dist/src/connectors/health.js +1 -1
  135. package/dist/src/connectors/learning-coordinator.js +1 -2
  136. package/dist/src/connectors/learning-recipes.js +28 -33
  137. package/dist/src/discussions/live-worker.d.ts +1 -0
  138. package/dist/src/discussions/live-worker.js +7 -1
  139. package/dist/src/discussions/repository.js +11 -1
  140. package/dist/src/discussions/sealer.d.ts +1 -1
  141. package/dist/src/discussions/sealer.js +16 -7
  142. package/dist/src/discussions/transcript.js +27 -1
  143. package/dist/src/discussions/types.d.ts +4 -0
  144. package/dist/src/gateway/agents-admin.js +1 -1
  145. package/dist/src/gateway/heartbeat/service.js +1 -1
  146. package/dist/src/gateway/hono/app.js +8 -3
  147. package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
  148. package/dist/src/gateway/hono/middleware/strict-rate-limit.js +8 -1
  149. package/dist/src/gateway/hono/oauth-async.d.ts +11 -5
  150. package/dist/src/gateway/hono/oauth-async.js +29 -16
  151. package/dist/src/gateway/hono/oauth.d.ts +1 -3
  152. package/dist/src/gateway/hono/oauth.js +22 -22
  153. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  154. package/dist/src/gateway/hono/routes/connectors.js +1 -1
  155. package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
  156. package/dist/src/gateway/hono/routes/discussions.js +2 -1
  157. package/dist/src/gateway/hono/routes/lazy-bundles.js +2 -1
  158. package/dist/src/gateway/hono/routes/mcp.js +1 -1
  159. package/dist/src/gateway/hono/routes/models.js +59 -5
  160. package/dist/src/gateway/hono/routes/understanding-sources.js +29 -0
  161. package/dist/src/gateway/hono/routes/voice.d.ts +1 -2
  162. package/dist/src/gateway/hono/routes/voice.js +16 -35
  163. package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
  164. package/dist/src/gateway/rate-limit/buckets.js +12 -0
  165. package/dist/src/gateway/service/session-input-coordinator.js +1 -2
  166. package/dist/src/gateway/service.js +20 -5
  167. package/dist/src/heartbeat/index.js +1 -1
  168. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +1 -1
  169. package/dist/src/knowledge/connected-understanding-pipeline.js +74 -25
  170. package/dist/src/knowledge/ingestion-service.js +33 -15
  171. package/dist/src/knowledge/types.d.ts +2 -0
  172. package/dist/src/media-understanding/audio-transcription-runner.d.ts +2 -0
  173. package/dist/src/media-understanding/audio-transcription-runner.js +3 -1
  174. package/dist/src/media-understanding/runner.js +3 -1
  175. package/dist/src/media-understanding/types.d.ts +2 -0
  176. package/dist/src/providers/model-catalog-persistence.d.ts +9 -0
  177. package/dist/src/providers/model-catalog-persistence.js +172 -0
  178. package/dist/src/providers/model-catalog-ranking.d.ts +2 -0
  179. package/dist/src/providers/model-catalog-ranking.js +17 -0
  180. package/dist/src/providers/model-catalog-store.d.ts +13 -3
  181. package/dist/src/providers/model-catalog-store.js +24 -5
  182. package/dist/src/providers/model-catalog-sync-service.d.ts +3 -3
  183. package/dist/src/providers/model-catalog-sync-service.js +12 -7
  184. package/dist/src/providers/provider-auth-service.d.ts +1 -0
  185. package/dist/src/providers/provider-auth-service.js +3 -0
  186. package/dist/src/providers/provider-disconnect.d.ts +11 -0
  187. package/dist/src/providers/provider-disconnect.js +33 -0
  188. package/dist/src/providers/xopc-cloud-catalog-coordinator.d.ts +56 -0
  189. package/dist/src/providers/xopc-cloud-catalog-coordinator.js +182 -0
  190. package/dist/src/providers/xopc-cloud-model-source.d.ts +6 -10
  191. package/dist/src/providers/xopc-cloud-model-source.js +49 -27
  192. package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
  193. package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
  194. package/dist/src/storage/sqlite/user-context-quality-repository.d.ts +8 -0
  195. package/dist/src/storage/sqlite/user-context-quality-repository.js +21 -1
  196. package/dist/src/tui/backends/embedded-backend.js +11 -3
  197. package/dist/src/tui/tui-oauth-login.js +5 -0
  198. package/dist/src/tui/tui-startup-resources.js +1 -1
  199. package/dist/src/user-context/sources/activity-clustering.js +30 -117
  200. package/dist/src/user-context/sources/index.d.ts +1 -0
  201. package/dist/src/user-context/sources/index.js +2 -1
  202. package/dist/src/user-context/sources/signal-clustering.d.ts +18 -0
  203. package/dist/src/user-context/sources/signal-clustering.js +131 -0
  204. package/dist/src/voice/audio/normalize.d.ts +17 -0
  205. package/dist/src/voice/audio/normalize.js +155 -0
  206. package/dist/src/voice/language-profile.d.ts +1 -4
  207. package/dist/src/voice/language-profile.js +2 -25
  208. package/dist/src/voice/local/runtime-client.d.ts +2 -0
  209. package/dist/src/voice/local/runtime-client.js +20 -1
  210. package/dist/src/voice/local/runtime-worker.js +7 -13
  211. package/dist/src/voice/local/wav.js +1 -1
  212. package/dist/src/voice/stt/availability.d.ts +1 -4
  213. package/dist/src/voice/stt/availability.js +3 -15
  214. package/dist/src/voice/stt/config.js +1 -0
  215. package/dist/src/voice/stt/factory.js +23 -0
  216. package/dist/src/voice/stt/index.d.ts +1 -0
  217. package/dist/src/voice/stt/index.js +2 -2
  218. package/dist/src/voice/stt/list-providers.js +1 -1
  219. package/dist/src/voice/stt/providers/local-transcription.js +7 -3
  220. package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +3 -1
  221. package/dist/src/voice/stt/transcribe-core.d.ts +5 -1
  222. package/dist/src/voice/stt/transcribe-core.js +13 -5
  223. package/dist/src/voice/stt/types.d.ts +2 -0
  224. package/dist/src/voice/tts/factory.d.ts +1 -1
  225. package/dist/src/voice/tts/factory.js +23 -1
  226. package/dist/src/voice/tts/merge-config.js +5 -3
  227. package/dist/src/voice/tts/providers/xopc-cloud-speech.js +3 -1
  228. package/dist/src/voice/tts/types.d.ts +2 -0
  229. package/dist/src/voice/tts/types.js +4 -2
  230. package/dist/src/work-discovery/evaluation.d.ts +23 -0
  231. package/dist/src/work-discovery/evaluation.js +18 -1
  232. package/dist/src/work-discovery/index.js +2 -2
  233. package/package.json +4 -3
  234. package/dist/gateway/static/root/assets/agents-DqGMj3QJ.js +0 -68
  235. package/dist/gateway/static/root/assets/automations-page-CwOXGV9z.js +0 -6
  236. package/dist/gateway/static/root/assets/browser-settings-page-CyRLhCod.js +0 -8
  237. package/dist/gateway/static/root/assets/capabilities-settings-panel-jRKcS7lZ.js +0 -7
  238. package/dist/gateway/static/root/assets/capability-presets-settings-panel-B3bKdtwU.js +0 -3
  239. package/dist/gateway/static/root/assets/channels-settings-yZBWH02s.js +0 -1
  240. package/dist/gateway/static/root/assets/channels-status-swr-C3zlimZd.js +0 -1
  241. package/dist/gateway/static/root/assets/connectors-page-OX4KvUkA.js +0 -2
  242. package/dist/gateway/static/root/assets/gateway-settings-V1XVxjHa.js +0 -1
  243. package/dist/gateway/static/root/assets/heartbeat-settings-CWUBAQrE.js +0 -1
  244. package/dist/gateway/static/root/assets/home-page-D57cYRd3.js +0 -1
  245. package/dist/gateway/static/root/assets/index-PNBFdxHb.css +0 -2
  246. package/dist/gateway/static/root/assets/local-app-workbench-page-BbAiMZE1.js +0 -2
  247. package/dist/gateway/static/root/assets/logs-page-nXdF3wOT.js +0 -2
  248. package/dist/gateway/static/root/assets/markdown-view-B12xeflb.css +0 -1
  249. package/dist/gateway/static/root/assets/messages-1qg_hOOd.js +0 -3
  250. package/dist/gateway/static/root/assets/notes-workbench-BYPoZeRw.js +0 -4
  251. package/dist/gateway/static/root/assets/project-detail-page-D27nOKbo.js +0 -1
  252. package/dist/gateway/static/root/assets/projects-page-CdB5cJJ-.js +0 -1
  253. package/dist/gateway/static/root/assets/remote-access-hub-DFoZ3UNS.js +0 -1
  254. package/dist/gateway/static/root/assets/sessions-page-C1cbIcJ7.js +0 -1
  255. package/dist/gateway/static/root/assets/settings-advanced-gate-DnXRlQXS.js +0 -1
  256. package/dist/gateway/static/root/assets/shares-settings-hlUgIkrp.js +0 -1
  257. package/dist/gateway/static/root/assets/skill-reload-api-DR31B_Gz.js +0 -1
  258. package/dist/gateway/static/root/assets/task-detail-page-CTKDpxhf.js +0 -1
  259. package/dist/gateway/static/root/assets/user-context-page-keJJYpix.js +0 -1
  260. package/dist/gateway/static/root/assets/work-discovery-page-BcvBiebt.js +0 -1
  261. package/dist/gateway/static/root/assets/workflows-page-Cz2VpWdj.js +0 -5
  262. package/dist/src/voice/local/runtime-dispatcher.d.ts +0 -9
  263. package/dist/src/voice/local/runtime-dispatcher.js +0 -20
@@ -55,6 +55,11 @@ import { registerClarifyBridge } from "./clarify-runtime.js";
55
55
  import { ChannelManager } from "../channels/manager.js";
56
56
  import { getWorkspacePath } from "../config/workspace-path-helpers.js";
57
57
  import "../config/index.js";
58
+ import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
59
+ import "../knowledge/index.js";
60
+ import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
61
+ import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
62
+ import { startConnectorSupervisor } from "../connectors/supervisor.js";
58
63
  import { DiscussionService } from "../discussions/service.js";
59
64
  import { DiscussionOrganizer } from "../discussions/organizer.js";
60
65
  import { DiscussionLiveWorker } from "../discussions/live-worker.js";
@@ -63,11 +68,6 @@ import { DiscussionSealer } from "../discussions/sealer.js";
63
68
  import "../discussions/index.js";
64
69
  import { EndpointToolRuntime } from "../endpoint-tools/runtime.js";
65
70
  import "../endpoint-tools/index.js";
66
- import { startConnectedKnowledgeCoordinator } from "../knowledge/coordinator.js";
67
- import "../knowledge/index.js";
68
- import { startConnectorLearningCoordinator } from "../connectors/learning-coordinator.js";
69
- import { ConnectedSourceChangePublisher } from "../connectors/source-change-publisher.js";
70
- import { startConnectorSupervisor } from "../connectors/supervisor.js";
71
71
  import { assertGatewayAuthConfigured, extractToken, resolveGatewayAuth, validateToken } from "./auth.js";
72
72
  import { prepareAutomationAgentSession } from "./automation-agent-session.js";
73
73
  import { reconcileDreamingAutomations } from "./dreaming-automation-reconciler.js";
@@ -88,6 +88,7 @@ import { getExposureManager } from "../remote-access/exposure-manager.js";
88
88
  import { assertGatewayAuthNotKnownWeak } from "./security/known-weak-secrets.js";
89
89
  import { assertGatewayRuntimeConfig } from "./runtime-config.js";
90
90
  import { auditGatewayConfig } from "./security/audit.js";
91
+ import { getXopcCloudCatalogCoordinator } from "../providers/xopc-cloud-catalog-coordinator.js";
91
92
  import { ModelCatalogSyncService } from "../providers/model-catalog-sync-service.js";
92
93
  import { runBootstrapMigrationsSync } from "../migrations/runner.js";
93
94
  import { MobileNotificationService } from "../mobile/notification-service.js";
@@ -794,6 +795,20 @@ var GatewayService = class {
794
795
  this.startupTrace = createGatewayStartupTrace();
795
796
  this.readiness.markStarting(this.startTime);
796
797
  const trace = this.startupTrace;
798
+ const catalogCoordinator = getXopcCloudCatalogCoordinator();
799
+ const catalog = await trace.measure("model-catalog.hydrate", () => catalogCoordinator.hydrate());
800
+ if (getAgentDefaultModelRef(this.config)?.startsWith("xopc-cloud/") && catalog.source === "none") {
801
+ const readiness = await trace.measure("model-catalog.initial-refresh", () => catalogCoordinator.ensure({
802
+ reason: "startup",
803
+ network: "if-empty",
804
+ timeoutMs: 1e4
805
+ }));
806
+ if (readiness.error) log.warn({
807
+ provider: "xopc-cloud",
808
+ phase: "catalog_refresh",
809
+ errorMessage: readiness.error.message
810
+ }, `Initial XOPC Cloud catalog refresh failed: ${readiness.error.message}`);
811
+ }
797
812
  registerClarifyBridge(this.agentRunner.getClarifyBridge());
798
813
  this.ensureAgentService();
799
814
  this.agentRunner.recoverSessionInputs();
@@ -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";
3
2
  import { isWithinActiveHours } from "./active-hours.js";
4
3
  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 };
@@ -13,5 +13,5 @@ export declare function renderConnectedObservation(observation: ClaimObservation
13
13
  export declare class ConnectedUnderstandingPipeline {
14
14
  private readonly memoryManager;
15
15
  constructor(memoryManager: MemoryManager);
16
- process(sourceInstanceId: string, connectorId: string, agentId: string): Promise<UnderstandingReviewResult>;
16
+ process(agentId: string): Promise<UnderstandingReviewResult>;
17
17
  }
@@ -1,5 +1,6 @@
1
1
  import { listKnowledgeSourceItems } from "../storage/sqlite/knowledge-repository.js";
2
2
  import "../storage/sqlite/index.js";
3
+ import { clusterUnderstandingSignals } from "../user-context/sources/signal-clustering.js";
3
4
  //#region src/knowledge/connected-understanding-pipeline.ts
4
5
  function logicalEventKey(item) {
5
6
  const value = item.metadata.logicalEventKey;
@@ -10,6 +11,59 @@ function eventTime(item) {
10
11
  const value = Date.parse(item.occurredAt);
11
12
  return Number.isFinite(value) ? value : void 0;
12
13
  }
14
+ function normalizedRecord(item) {
15
+ if (!item.normalizedText) return {};
16
+ try {
17
+ const value = JSON.parse(item.normalizedText);
18
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
19
+ } catch {
20
+ return {};
21
+ }
22
+ }
23
+ function textField(record, ...fields) {
24
+ for (const field of fields) {
25
+ const value = record[field];
26
+ if (typeof value === "string" && value.trim()) return value.trim();
27
+ if (value && typeof value === "object" && !Array.isArray(value)) {
28
+ const nested = value;
29
+ for (const nestedField of [
30
+ "name",
31
+ "full_name",
32
+ "fullName",
33
+ "title"
34
+ ]) {
35
+ const nestedValue = nested[nestedField];
36
+ if (typeof nestedValue === "string" && nestedValue.trim()) return nestedValue.trim();
37
+ }
38
+ }
39
+ }
40
+ }
41
+ function normalizeConversationTitle(value) {
42
+ return value.replace(/^(?:(?:re|fwd?|回复|转发)\s*[::]\s*)+/i, "").trim();
43
+ }
44
+ function projectSignal(item) {
45
+ if (item.metadata.actorAttributed !== true) return void 0;
46
+ const observationKind = item.metadata.observationKind;
47
+ if (![
48
+ "activity",
49
+ "message",
50
+ "calendar_event",
51
+ "external_task",
52
+ "document_metadata"
53
+ ].includes(String(observationKind))) return;
54
+ const title = textField(normalizedRecord(item), "subject", "title", "repository", "project", "fullName", "full_name", "name");
55
+ const subjectKey = typeof item.metadata.subjectKey === "string" && item.metadata.subjectKey.trim() ? item.metadata.subjectKey.trim() : void 0;
56
+ const displayTitle = title ? normalizeConversationTitle(title) : subjectKey;
57
+ if (!displayTitle) return void 0;
58
+ return {
59
+ evidenceRef: item.id,
60
+ sourceId: item.sourceInstanceId,
61
+ title: displayTitle,
62
+ group: typeof item.metadata.toolkit === "string" ? item.metadata.toolkit : void 0,
63
+ subjectKey,
64
+ occurredAt: eventTime(item)
65
+ };
66
+ }
13
67
  function recent(items, days) {
14
68
  const now = Date.now();
15
69
  const cutoff = now - days * 864e5;
@@ -86,30 +140,24 @@ function routineObservations(items) {
86
140
  });
87
141
  }
88
142
  function projectObservations(items) {
89
- const grouped = /* @__PURE__ */ new Map();
90
- for (const item of recent(items, 60)) {
91
- if (item.metadata.observationKind !== "activity" || item.metadata.actorAttributed !== true) continue;
92
- const subject = typeof item.metadata.subjectKey === "string" ? item.metadata.subjectKey.trim() : "";
93
- if (!subject) continue;
94
- const entry = grouped.get(subject.toLowerCase()) ?? {
95
- label: subject,
96
- events: /* @__PURE__ */ new Map()
97
- };
98
- const events = entry.events;
99
- const eventKey = logicalEventKey(item);
100
- if (!events.has(eventKey)) events.set(eventKey, item);
101
- grouped.set(subject.toLowerCase(), entry);
102
- }
103
- return [...grouped.entries()].sort((left, right) => right[1].events.size - left[1].events.size).slice(0, 8).map(([, entry]) => {
104
- const { label: subject, events } = entry;
105
- return {
143
+ const recentItems = recent(items, 60);
144
+ const byId = new Map(recentItems.map((item) => [item.id, item]));
145
+ return clusterUnderstandingSignals(recentItems.map(projectSignal).filter((signal) => Boolean(signal))).flatMap((cluster) => {
146
+ const events = /* @__PURE__ */ new Map();
147
+ for (const signal of cluster.signals) {
148
+ const item = byId.get(signal.evidenceRef);
149
+ const eventKey = item && logicalEventKey(item);
150
+ if (item && eventKey && !events.has(eventKey)) events.set(eventKey, item);
151
+ }
152
+ if (![...events.values()].some((item) => item.itemType !== "calendar_event")) return [];
153
+ return [{
106
154
  class: "project",
107
- key: `project:${subject.toLocaleLowerCase()}`,
108
- value: { label: subject },
155
+ key: `project:${cluster.key}`,
156
+ value: { label: cluster.title },
109
157
  items: [...events.values()],
110
158
  windowDays: 60
111
- };
112
- });
159
+ }];
160
+ }).sort((left, right) => right.items.length - left.items.length).slice(0, 8);
113
161
  }
114
162
  function deriveConnectedClaimObservations(items) {
115
163
  const active = items.filter((item) => !item.deletedAt && item.synthesisPipeline === "connected_knowledge" && item.sensitivity !== "secret" && item.sensitivity !== "regulated" && item.metadata.observationKind !== "inventory");
@@ -178,9 +226,9 @@ var ConnectedUnderstandingPipeline = class {
178
226
  constructor(memoryManager) {
179
227
  this.memoryManager = memoryManager;
180
228
  }
181
- async process(sourceInstanceId, connectorId, agentId) {
229
+ async process(agentId) {
182
230
  const observations = deriveConnectedClaimObservations(listKnowledgeSourceItems({
183
- sourceInstanceId,
231
+ agentId,
184
232
  includeDeleted: false,
185
233
  limit: 500
186
234
  }));
@@ -193,6 +241,7 @@ var ConnectedUnderstandingPipeline = class {
193
241
  };
194
242
  for (const observation of observations) {
195
243
  if (!isDurableObservation(observation)) continue;
244
+ const sourceInstanceIds = [...new Set(observation.items.map((item) => item.sourceInstanceId))];
196
245
  const result = await this.memoryManager.applyUnderstandingCandidates([renderConnectedObservation(observation)], {
197
246
  sourceItemIds: observation.items.map((item) => item.id).slice(0, 20),
198
247
  sourceText: JSON.stringify({
@@ -201,8 +250,8 @@ var ConnectedUnderstandingPipeline = class {
201
250
  windowDays: observation.windowDays
202
251
  }),
203
252
  source: {
204
- provider: connectorId,
205
- sourceInstanceId
253
+ provider: "connected-sources",
254
+ ...sourceInstanceIds.length === 1 ? { sourceInstanceId: sourceInstanceIds[0] } : {}
206
255
  },
207
256
  reviewSource: "background"
208
257
  });
@@ -4,6 +4,7 @@ import { finishKnowledgeSyncRun, getKnowledgeSourceCursor, listKnowledgeSourceIt
4
4
  //#region src/knowledge/ingestion-service.ts
5
5
  init_logger();
6
6
  const log = createLogger("KnowledgeIngestion");
7
+ const MAX_PULL_PAGES = 20;
7
8
  function deletionInputs(instanceId, collectionScope, snapshotExternalIds) {
8
9
  if (!snapshotExternalIds) return [];
9
10
  const seen = new Set(snapshotExternalIds);
@@ -93,29 +94,46 @@ var KnowledgeIngestionService = class {
93
94
  const controller = params.signal ? null : new AbortController();
94
95
  const signal = params.signal ?? controller.signal;
95
96
  try {
96
- const pulled = await adapter.pull({
97
- instanceId: params.instanceId,
98
- collectionScope: params.collectionScope,
99
- cursor: cursorBefore,
100
- windowStart: params.windowStart,
101
- signal
102
- });
103
- const tombstones = deletionInputs(params.instanceId, params.collectionScope, pulled.snapshotExternalIds);
104
- const stored = upsertKnowledgeSourceItems([...pulled.items, ...tombstones]);
105
- this.state.setCursor(params.instanceId, params.collectionScope, pulled.nextCursor);
97
+ const items = [];
98
+ const warnings = [];
99
+ const snapshotExternalIds = [];
100
+ let snapshotComplete = true;
101
+ let pullCursor = cursorBefore;
102
+ let cursorAfter = cursorBefore;
103
+ for (let page = 0; page < MAX_PULL_PAGES; page += 1) {
104
+ const pulled = await adapter.pull({
105
+ instanceId: params.instanceId,
106
+ collectionScope: params.collectionScope,
107
+ cursor: pullCursor,
108
+ windowStart: params.windowStart,
109
+ signal
110
+ });
111
+ items.push(...pulled.items);
112
+ warnings.push(...pulled.warnings);
113
+ if (pulled.snapshotExternalIds) snapshotExternalIds.push(...pulled.snapshotExternalIds);
114
+ else snapshotComplete = false;
115
+ cursorAfter = pulled.nextCursor;
116
+ if (!pulled.hasMore) break;
117
+ if (!pulled.nextCursor || pulled.nextCursor === pullCursor) throw new Error("Knowledge source returned an invalid pagination cursor.");
118
+ if (page === MAX_PULL_PAGES - 1) throw new Error(`Knowledge source exceeded the ${MAX_PULL_PAGES}-page safety limit.`);
119
+ pullCursor = pulled.nextCursor;
120
+ }
121
+ const tombstones = deletionInputs(params.instanceId, params.collectionScope, snapshotComplete ? snapshotExternalIds : void 0);
122
+ const stored = upsertKnowledgeSourceItems([...items, ...tombstones]);
123
+ this.state.setCursor(params.instanceId, params.collectionScope, cursorAfter);
106
124
  const completed = finishKnowledgeSyncRun({
107
125
  runId: run.id,
108
- status: pulled.warnings.length > 0 ? "partial" : "succeeded",
109
- cursorAfter: pulled.nextCursor,
110
- itemsSeen: pulled.items.length,
126
+ status: warnings.length > 0 ? "partial" : "succeeded",
127
+ cursorAfter,
128
+ itemsSeen: items.length,
111
129
  itemsCreated: stored.created,
112
130
  itemsUpdated: stored.updated,
113
- warnings: pulled.warnings
131
+ warnings
114
132
  });
115
133
  log.info({
116
134
  runId: run.id,
117
135
  sourceInstanceId: params.instanceId,
118
- itemsSeen: pulled.items.length,
136
+ itemsSeen: items.length,
119
137
  itemsCreated: stored.created,
120
138
  itemsUpdated: stored.updated,
121
139
  itemsDeleted: tombstones.length
@@ -83,6 +83,8 @@ export interface KnowledgePullInput {
83
83
  export interface KnowledgePullResult {
84
84
  items: KnowledgeSourceItemInput[];
85
85
  nextCursor?: string;
86
+ /** True only when nextCursor is a required continuation page, not a committed checkpoint. */
87
+ hasMore?: boolean;
86
88
  warnings: string[];
87
89
  /** All active external ids observed during a complete source snapshot. Omit for partial/incremental-only pulls. */
88
90
  snapshotExternalIds?: string[];
@@ -41,6 +41,8 @@ export interface RunAudioTranscriptionResult {
41
41
  text: string;
42
42
  provider: string;
43
43
  model?: string;
44
+ language?: string;
45
+ durationSeconds?: number;
44
46
  }>;
45
47
  decision: MediaUnderstandingDecision;
46
48
  }
@@ -25,7 +25,9 @@ async function runAudioTranscription(options) {
25
25
  attachmentIndex: entry.attachmentIndex,
26
26
  text: entry.text,
27
27
  provider: entry.provider,
28
- ...entry.model ? { model: entry.model } : {}
28
+ ...entry.model ? { model: entry.model } : {},
29
+ ...entry.language ? { language: entry.language } : {},
30
+ ...entry.durationSeconds !== void 0 ? { durationSeconds: entry.durationSeconds } : {}
29
31
  }));
30
32
  return {
31
33
  transcript: outputs.length === 0 ? void 0 : outputs.slice().sort((a, b) => a.attachmentIndex - b.attachmentIndex).map((o) => o.text).join("\n").trim() || void 0,
@@ -116,7 +116,9 @@ async function runCapability(options) {
116
116
  attachmentIndex: attachment.attachmentIndex,
117
117
  text,
118
118
  provider: provider.id,
119
- model: callResult.model
119
+ model: callResult.model,
120
+ ...callResult.language ? { language: callResult.language } : {},
121
+ ...callResult.durationSeconds !== void 0 ? { durationSeconds: callResult.durationSeconds } : {}
120
122
  });
121
123
  break;
122
124
  } catch (error) {
@@ -63,6 +63,8 @@ export interface MediaUnderstandingOutput {
63
63
  text: string;
64
64
  provider: string;
65
65
  model?: string;
66
+ language?: string;
67
+ durationSeconds?: number;
66
68
  }
67
69
  export interface MediaUnderstandingModelDecision {
68
70
  provider?: string;
@@ -0,0 +1,9 @@
1
+ import type { CatalogSource } from './model-catalog-store.js';
2
+ export declare class ModelCatalogPersistence {
3
+ private readonly path;
4
+ constructor(path?: string);
5
+ loadSync(): CatalogSource | undefined;
6
+ save(source: CatalogSource): Promise<void>;
7
+ clear(): Promise<void>;
8
+ clearSync(): void;
9
+ }
@@ -0,0 +1,172 @@
1
+ import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
+ import { init_paths_state, resolveXopcCloudCatalogCachePath } from "../config/paths-state.js";
3
+ import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
4
+ import { readFileSync, rmSync } from "node:fs";
5
+ import { z } from "zod";
6
+ import { rm } from "node:fs/promises";
7
+ //#region src/providers/model-catalog-persistence.ts
8
+ var MAX_CATALOG_BYTES, imageGenerationSchema, sttSchema, ttsSchema, catalogModelSchema, persistedCatalogSchema, ModelCatalogPersistence;
9
+ var init_model_catalog_persistence = __esmMin((() => {
10
+ init_paths_state();
11
+ init_write_file_atomic();
12
+ MAX_CATALOG_BYTES = 4 * 1024 * 1024;
13
+ imageGenerationSchema = z.object({
14
+ maxCount: z.number().int().positive(),
15
+ sizes: z.array(z.string()),
16
+ aspectRatios: z.array(z.string()).optional(),
17
+ qualities: z.array(z.enum([
18
+ "low",
19
+ "medium",
20
+ "high",
21
+ "auto"
22
+ ])),
23
+ formats: z.array(z.enum([
24
+ "png",
25
+ "jpeg",
26
+ "webp"
27
+ ])),
28
+ backgrounds: z.array(z.enum([
29
+ "transparent",
30
+ "opaque",
31
+ "auto"
32
+ ])),
33
+ maxInputImages: z.number().int().nonnegative()
34
+ }).strict();
35
+ sttSchema = z.object({
36
+ inputFormats: z.array(z.string()),
37
+ maxBytes: z.number().int().nonnegative(),
38
+ maxDurationSeconds: z.number().int().nonnegative(),
39
+ languages: z.array(z.string()),
40
+ languageHint: z.boolean(),
41
+ prompt: z.boolean(),
42
+ timestamps: z.array(z.enum(["segment", "word"])),
43
+ diarization: z.boolean()
44
+ }).strict();
45
+ ttsSchema = z.object({
46
+ maxCharacters: z.number().int().nonnegative(),
47
+ languages: z.array(z.string()),
48
+ outputFormats: z.array(z.enum([
49
+ "mp3",
50
+ "opus",
51
+ "aac",
52
+ "flac",
53
+ "wav",
54
+ "pcm"
55
+ ])),
56
+ streaming: z.boolean(),
57
+ speed: z.boolean(),
58
+ pitch: z.boolean(),
59
+ instructions: z.boolean(),
60
+ defaultVoice: z.string().optional()
61
+ }).strict();
62
+ catalogModelSchema = z.object({
63
+ id: z.string().min(1),
64
+ name: z.string().min(1),
65
+ availability: z.enum(["available", "unavailable"]),
66
+ kind: z.enum([
67
+ "language",
68
+ "image",
69
+ "stt",
70
+ "tts"
71
+ ]),
72
+ input: z.array(z.enum([
73
+ "text",
74
+ "image",
75
+ "audio"
76
+ ])),
77
+ output: z.array(z.enum([
78
+ "text",
79
+ "image",
80
+ "audio"
81
+ ])),
82
+ operations: z.array(z.enum([
83
+ "chat.completions",
84
+ "responses",
85
+ "images.generate",
86
+ "images.edit",
87
+ "audio.transcription",
88
+ "audio.speech"
89
+ ])),
90
+ reasoning: z.boolean(),
91
+ contextWindow: z.number().int().positive(),
92
+ maxOutputTokens: z.number().int().positive().nullable(),
93
+ stability: z.enum([
94
+ "stable",
95
+ "preview",
96
+ "deprecated"
97
+ ]).optional(),
98
+ priority: z.number().optional(),
99
+ tier: z.string().optional(),
100
+ bestEffort: z.boolean().optional(),
101
+ imageGeneration: imageGenerationSchema.optional(),
102
+ stt: sttSchema.optional(),
103
+ tts: ttsSchema.optional()
104
+ }).strict();
105
+ persistedCatalogSchema = z.object({
106
+ schemaVersion: z.literal(1),
107
+ providerId: z.literal("xopc-cloud"),
108
+ catalogVersion: z.string().nullable(),
109
+ fetchedAt: z.number().int().nonnegative(),
110
+ baseUrl: z.string().url(),
111
+ api: z.enum(["openai-completions", "openai-responses"]),
112
+ recommendedModel: z.string().nullable(),
113
+ recommended: z.record(z.enum([
114
+ "vision",
115
+ "image-generation",
116
+ "stt",
117
+ "tts"
118
+ ]), z.string()).optional(),
119
+ models: z.array(catalogModelSchema)
120
+ }).strict();
121
+ ModelCatalogPersistence = class {
122
+ constructor(path = resolveXopcCloudCatalogCachePath()) {
123
+ this.path = path;
124
+ }
125
+ loadSync() {
126
+ try {
127
+ const raw = readFileSync(this.path, "utf8");
128
+ if (Buffer.byteLength(raw) > MAX_CATALOG_BYTES) return void 0;
129
+ const parsed = persistedCatalogSchema.safeParse(JSON.parse(raw));
130
+ if (!parsed.success) return void 0;
131
+ return {
132
+ providerId: parsed.data.providerId,
133
+ baseUrl: parsed.data.baseUrl,
134
+ api: parsed.data.api,
135
+ etag: parsed.data.catalogVersion,
136
+ recommendedModel: parsed.data.recommendedModel,
137
+ recommended: parsed.data.recommended,
138
+ lastSuccessAt: parsed.data.fetchedAt,
139
+ models: parsed.data.models
140
+ };
141
+ } catch {
142
+ return;
143
+ }
144
+ }
145
+ async save(source) {
146
+ if (source.providerId !== "xopc-cloud") throw new Error(`Cannot persist catalog for provider ${source.providerId}`);
147
+ const payload = persistedCatalogSchema.parse({
148
+ schemaVersion: 1,
149
+ providerId: source.providerId,
150
+ catalogVersion: source.etag,
151
+ fetchedAt: source.lastSuccessAt,
152
+ baseUrl: source.baseUrl,
153
+ api: source.api,
154
+ recommendedModel: source.recommendedModel,
155
+ recommended: source.recommended,
156
+ models: source.models
157
+ });
158
+ const serialized = `${JSON.stringify(payload, null, 2)}\n`;
159
+ if (Buffer.byteLength(serialized) > MAX_CATALOG_BYTES) throw new Error("XOPC Cloud model catalog exceeds the 4 MiB cache limit");
160
+ await writeTextAtomic(this.path, serialized, { mode: 384 });
161
+ }
162
+ async clear() {
163
+ await rm(this.path, { force: true });
164
+ }
165
+ clearSync() {
166
+ rmSync(this.path, { force: true });
167
+ }
168
+ };
169
+ }));
170
+ //#endregion
171
+ init_model_catalog_persistence();
172
+ export { ModelCatalogPersistence, init_model_catalog_persistence };
@@ -0,0 +1,2 @@
1
+ import type { CatalogModel } from './model-catalog-store.js';
2
+ export declare function compareCatalogModels(left: CatalogModel, right: CatalogModel, recommendedModel?: string): number;
@@ -0,0 +1,17 @@
1
+ //#region src/providers/model-catalog-ranking.ts
2
+ const STABILITY_ORDER = {
3
+ stable: 0,
4
+ preview: 1,
5
+ deprecated: 2
6
+ };
7
+ function compareCatalogModels(left, right, recommendedModel) {
8
+ if (left.id === recommendedModel) return -1;
9
+ if (right.id === recommendedModel) return 1;
10
+ const stability = STABILITY_ORDER[left.stability ?? "stable"] - STABILITY_ORDER[right.stability ?? "stable"];
11
+ if (stability !== 0) return stability;
12
+ if (left.bestEffort !== right.bestEffort) return left.bestEffort ? 1 : -1;
13
+ if ((left.priority ?? 0) !== (right.priority ?? 0)) return (right.priority ?? 0) - (left.priority ?? 0);
14
+ return left.id.localeCompare(right.id);
15
+ }
16
+ //#endregion
17
+ export { compareCatalogModels };
@@ -9,6 +9,10 @@ export interface CatalogModel {
9
9
  reasoning: boolean;
10
10
  contextWindow: number;
11
11
  maxOutputTokens: number | null;
12
+ stability?: 'stable' | 'preview' | 'deprecated';
13
+ priority?: number;
14
+ tier?: string;
15
+ bestEffort?: boolean;
12
16
  imageGeneration?: {
13
17
  maxCount: number;
14
18
  sizes: string[];
@@ -45,24 +49,30 @@ export interface CatalogSource {
45
49
  api: 'openai-completions' | 'openai-responses';
46
50
  etag: string | null;
47
51
  recommendedModel: string | null;
52
+ recommended?: Partial<Record<'vision' | 'image-generation' | 'stt' | 'tts', string>>;
48
53
  lastSuccessAt: number;
49
54
  models: CatalogModel[];
50
55
  }
51
56
  export interface ModelCatalogSnapshot {
52
57
  sources: Record<string, CatalogSource>;
53
58
  }
59
+ export type CatalogSourceOrigin = 'memory' | 'disk' | 'network';
54
60
  export type AvailableCatalogModel = Omit<CatalogModel, 'availability'>;
55
61
  export declare class ModelCatalogStore {
56
62
  private sources;
63
+ private origins;
57
64
  load(): ModelCatalogSnapshot;
58
65
  getSource(sourceId: string): CatalogSource | undefined;
59
- saveSource(sourceId: string, source: CatalogSource): void;
66
+ getSourceOrigin(sourceId: string): CatalogSourceOrigin | undefined;
67
+ saveSource(sourceId: string, source: CatalogSource, origin?: CatalogSourceOrigin): void;
60
68
  removeSource(sourceId: string): boolean;
61
- replaceSourceModels(sourceId: string, source: Omit<CatalogSource, 'models'>, models: AvailableCatalogModel[]): {
69
+ replaceSourceModels(sourceId: string, source: Omit<CatalogSource, 'models'>, models: AvailableCatalogModel[], origin?: CatalogSourceOrigin): {
62
70
  addedCount: number;
63
71
  unavailableCount: number;
64
72
  };
65
73
  private cloneSource;
66
74
  }
67
75
  export declare function getModelCatalogStore(): ModelCatalogStore;
68
- export declare function resetModelCatalogStore(): void;
76
+ export declare function resetModelCatalogStore(options?: {
77
+ rehydrate?: boolean;
78
+ }): 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();