@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
@@ -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
  }
@@ -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
+ 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
+ export declare function disconnectProvider(providerId: string, options?: ProviderDisconnectOptions): Promise<void>;
11
+ export {};
@@ -0,0 +1,33 @@
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
+ import { getXopcCloudCatalogCoordinator } from "./xopc-cloud-catalog-coordinator.js";
9
+ //#region src/providers/provider-disconnect.ts
10
+ init_credentials();
11
+ init_oauth_provider_lock();
12
+ init_logger();
13
+ init_model_registry();
14
+ init_provider_auth_service();
15
+ const log = createLogger("ProviderDisconnect");
16
+ async function disconnectProvider(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") await (options.clearCloudCatalog ?? (() => getXopcCloudCatalogCoordinator().clear("revoke")))();
24
+ else (options.refreshModels ?? (() => getModelRegistry().refresh()))();
25
+ (options.evictRunners ?? (() => evictAllEmbeddedSessionRunners("provider_disconnected")))();
26
+ });
27
+ log.info({
28
+ provider,
29
+ phase: "provider_revoked"
30
+ }, `Disconnected provider: ${provider}`);
31
+ }
32
+ //#endregion
33
+ 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 { XopcCloudModelSource } from "./xopc-cloud-model-source.js";
9
+ //#region src/providers/xopc-cloud-catalog-coordinator.ts
10
+ init_oauth_provider_lock();
11
+ init_logger();
12
+ init_model_catalog_persistence();
13
+ init_model_catalog_store();
14
+ init_model_registry();
15
+ const log = createLogger("XopcCloudCatalog");
16
+ const DEFAULT_STALE_AFTER_MS = 1440 * 6e4;
17
+ var XopcCloudCatalogCoordinator = class {
18
+ source;
19
+ store;
20
+ persistence;
21
+ staleAfterMs;
22
+ refreshModels;
23
+ reloadImageProviders;
24
+ withLock;
25
+ onPermanentAuthFailure;
26
+ refreshPromise = null;
27
+ generation = 0;
28
+ lastError;
29
+ notAuthorized = false;
30
+ constructor(options = {}) {
31
+ this.source = options.source ?? new XopcCloudModelSource();
32
+ this.store = options.store ?? getModelCatalogStore();
33
+ this.persistence = options.persistence ?? new ModelCatalogPersistence();
34
+ this.staleAfterMs = options.staleAfterMs ?? DEFAULT_STALE_AFTER_MS;
35
+ this.refreshModels = options.refreshModels ?? (() => getModelRegistry().refresh());
36
+ this.reloadImageProviders = options.reloadImageProviders ?? reloadImageGenerationProviders;
37
+ this.withLock = options.withLock ?? ((operation) => withOAuthProviderLock("xopc-cloud", operation));
38
+ this.onPermanentAuthFailure = options.onPermanentAuthFailure ?? (async () => {
39
+ const { disconnectProvider } = await import("./provider-disconnect.js");
40
+ await disconnectProvider("xopc-cloud");
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
  }
@@ -1,11 +1,6 @@
1
- import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
2
- import { getModelRegistry, init_model_registry } from "./model-registry.js";
3
1
  import { init_xopc_cloud_config, resolveXopcModelRouterUrl } from "./xopc-cloud-config.js";
4
2
  import { getProviderAuthService, init_provider_auth_service } from "./provider-auth-service.js";
5
- import { reloadImageGenerationProviders } from "../agent/image/generation/provider-registry.js";
6
3
  //#region src/providers/xopc-cloud-model-source.ts
7
- init_model_catalog_store();
8
- init_model_registry();
9
4
  init_provider_auth_service();
10
5
  init_xopc_cloud_config();
11
6
  var XopcCloudModelError = class extends Error {
@@ -20,17 +15,14 @@ var XopcCloudModelSource = class {
20
15
  fetchImpl;
21
16
  routerUrl;
22
17
  credentials;
23
- catalogStore;
24
- refreshModels;
25
18
  constructor(options = {}) {
26
19
  this.fetchImpl = options.fetchImpl ?? fetch;
27
20
  this.routerUrl = resolveXopcModelRouterUrl(options.routerUrl);
28
21
  this.credentials = options.credentials ?? getProviderAuthService();
29
- this.catalogStore = options.catalogStore ?? getModelCatalogStore();
30
- this.refreshModels = options.refreshModels ?? (() => getModelRegistry().refresh());
31
22
  }
32
- async refresh() {
33
- const accessToken = await this.credentials.resolveApiKey("xopc-cloud");
23
+ async fetch(signal) {
24
+ const requestSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(3e4)]) : AbortSignal.timeout(3e4);
25
+ const accessToken = await this.credentials.resolveApiKey("xopc-cloud", requestSignal);
34
26
  if (!accessToken) return {
35
27
  status: "skipped",
36
28
  reason: "not_configured"
@@ -40,7 +32,7 @@ var XopcCloudModelSource = class {
40
32
  authorization: `Bearer ${accessToken}`,
41
33
  accept: "application/json"
42
34
  },
43
- signal: AbortSignal.timeout(3e4)
35
+ signal: requestSignal
44
36
  });
45
37
  const body = await response.json().catch(() => null);
46
38
  if (!response.ok) throw new XopcCloudModelError(typeof body?.error?.message === "string" ? body.error.message : `XOPC model discovery failed (${response.status})`, response.status, typeof body?.error?.code === "string" ? body.error.code : void 0);
@@ -58,7 +50,7 @@ var XopcCloudModelSource = class {
58
50
  const generation = parseImageGenerationCapabilities(model.xopc?.capabilities?.imageGeneration);
59
51
  const stt = kind === "stt" ? parseSttCapabilities(model.xopc?.capabilities) : void 0;
60
52
  const tts = kind === "tts" ? parseTtsCapabilities(model.xopc?.capabilities, model.xopc?.defaultVoice) : void 0;
61
- return [model.id, {
53
+ const catalogModel = {
62
54
  id: model.id,
63
55
  name: model.id,
64
56
  kind,
@@ -68,28 +60,58 @@ var XopcCloudModelSource = class {
68
60
  reasoning: model.xopc?.capabilities?.reasoning === true,
69
61
  contextWindow: 128e3,
70
62
  maxOutputTokens: typeof maxOutputTokens === "number" && Number.isSafeInteger(maxOutputTokens) ? maxOutputTokens : null,
63
+ ...model.xopc?.stability === "stable" || model.xopc?.stability === "preview" || model.xopc?.stability === "deprecated" ? { stability: model.xopc.stability } : {},
64
+ ...typeof model.xopc?.priority === "number" && Number.isFinite(model.xopc.priority) ? { priority: model.xopc.priority } : {},
65
+ ...typeof model.xopc?.tier === "string" && model.xopc.tier ? { tier: model.xopc.tier } : {},
66
+ ...typeof model.xopc?.bestEffort === "boolean" ? { bestEffort: model.xopc.bestEffort } : {},
71
67
  ...generation ? { imageGeneration: generation } : {},
72
68
  ...stt ? { stt } : {},
73
69
  ...tts ? { tts } : {}
74
- }];
70
+ };
71
+ return [model.id, catalogModel];
75
72
  })).values()];
76
- this.catalogStore.replaceSourceModels("xopc-cloud", {
77
- providerId: "xopc-cloud",
78
- baseUrl: this.routerUrl,
79
- api: "openai-completions",
80
- etag: response.headers.get("x-xopc-model-catalog-version"),
81
- recommendedModel: models[0]?.id ?? null,
82
- lastSuccessAt: Date.now()
83
- }, models);
84
- this.refreshModels();
85
- reloadImageGenerationProviders();
73
+ const recommended = parseRecommendations(body.xopc?.defaults, models);
86
74
  return {
87
- status: "updated",
88
- modelCount: models.length,
89
- models: models.map((model) => model.id)
75
+ status: "fetched",
76
+ source: {
77
+ providerId: "xopc-cloud",
78
+ baseUrl: this.routerUrl,
79
+ api: "openai-completions",
80
+ etag: response.headers.get("x-xopc-model-catalog-version"),
81
+ recommendedModel: models[0]?.id ?? null,
82
+ ...Object.keys(recommended).length > 0 ? { recommended } : {},
83
+ lastSuccessAt: Date.now()
84
+ },
85
+ models
90
86
  };
91
87
  }
92
88
  };
89
+ function parseRecommendations(value, models) {
90
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
91
+ const raw = value;
92
+ const capabilities = [
93
+ "vision",
94
+ "image-generation",
95
+ "stt",
96
+ "tts"
97
+ ];
98
+ const recommended = {};
99
+ for (const capability of capabilities) {
100
+ const modelId = raw[capability];
101
+ if (typeof modelId !== "string") continue;
102
+ const model = models.find((entry) => entry.id === modelId);
103
+ if (model && modelMatchesRecommendation(model, capability)) recommended[capability] = modelId;
104
+ }
105
+ return recommended;
106
+ }
107
+ function modelMatchesRecommendation(model, capability) {
108
+ switch (capability) {
109
+ case "vision": return model.kind === "language" && model.input.includes("image");
110
+ case "image-generation": return model.kind === "image" && model.operations.includes("images.generate");
111
+ case "stt": return model.kind === "stt" && model.operations.includes("audio.transcription");
112
+ case "tts": return model.kind === "tts" && model.operations.includes("audio.speech");
113
+ }
114
+ }
93
115
  function parseSttCapabilities(value) {
94
116
  if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
95
117
  const raw = value;
@@ -40,6 +40,7 @@ export declare function getKnowledgeConsumerWatermark(consumerId: string, source
40
40
  export declare function setKnowledgeConsumerWatermark(consumerId: string, sourceInstanceId: string, sequence: number, nowMs?: number): void;
41
41
  export declare function listKnowledgeSourceItems(options?: {
42
42
  sourceInstanceId?: string;
43
+ agentId?: string;
43
44
  collectionScope?: string;
44
45
  itemType?: string;
45
46
  synthesisStatus?: KnowledgeSynthesisStatus;
@@ -240,6 +240,10 @@ function listKnowledgeSourceItems(options = {}) {
240
240
  where.push("source_instance_id = ?");
241
241
  params.push(options.sourceInstanceId);
242
242
  }
243
+ if (options.agentId) {
244
+ where.push("json_extract(metadata_json, '$.agentId') = ?");
245
+ params.push(options.agentId);
246
+ }
243
247
  if (options.collectionScope) {
244
248
  where.push("collection_scope = ?");
245
249
  params.push(options.collectionScope);
@@ -26,6 +26,14 @@ export type UserUnderstandingQualityMetrics = {
26
26
  irrelevant: number;
27
27
  helpfulRate: number | null;
28
28
  };
29
+ quickUnderstanding: {
30
+ sourcesAuthorized: number;
31
+ sourcesCollected: number;
32
+ sourceCoverage: number | null;
33
+ bootstrapJobs: number;
34
+ successfulBootstrapRate: number | null;
35
+ medianBootstrapDurationMs: number | null;
36
+ };
29
37
  };
30
38
  export type UnderstandingFeedbackSummary = {
31
39
  understandingId: string;
@@ -28,6 +28,12 @@ function summarizeUnderstandingFeedback(understandingIds) {
28
28
  function rate(numerator, denominator) {
29
29
  return denominator > 0 ? Math.round(numerator / denominator * 1e4) / 1e4 : null;
30
30
  }
31
+ function median(values) {
32
+ if (!values.length) return null;
33
+ const sorted = values.toSorted((left, right) => left - right);
34
+ const middle = Math.floor(sorted.length / 2);
35
+ return sorted.length % 2 ? sorted[middle] : Math.round((sorted[middle - 1] + sorted[middle]) / 2);
36
+ }
31
37
  function summarizeUserUnderstandingQuality(options = {}) {
32
38
  const nowMs = options.nowMs ?? Date.now();
33
39
  const windowDays = Math.max(1, Math.min(365, Math.floor(options.windowDays ?? 30)));
@@ -83,6 +89,12 @@ function summarizeUserUnderstandingQuality(options = {}) {
83
89
  helpfulRate: null
84
90
  };
85
91
  recall.helpfulRate = rate(recall.helpful, recall.total);
92
+ const sourceRows = db.prepare(`SELECT last_collected_at
93
+ FROM understanding_source_grants WHERE status = 'active'`).all();
94
+ const bootstrapRows = db.prepare(`SELECT status, started_at, finished_at
95
+ FROM connector_learning_jobs WHERE mode = 'bootstrap' AND created_at >= ?`).all(sinceMs);
96
+ const completedBootstraps = bootstrapRows.filter((row) => row.status === "completed");
97
+ const bootstrapDurations = completedBootstraps.flatMap((row) => row.started_at !== null && row.finished_at !== null && row.finished_at >= row.started_at ? [row.finished_at - row.started_at] : []);
86
98
  return {
87
99
  windowDays,
88
100
  since: new Date(sinceMs).toISOString(),
@@ -91,7 +103,15 @@ function summarizeUserUnderstandingQuality(options = {}) {
91
103
  total: recentDecisions.length,
92
104
  acceptanceRate: rate(accepted, recentDecisions.length)
93
105
  },
94
- recall
106
+ recall,
107
+ quickUnderstanding: {
108
+ sourcesAuthorized: sourceRows.length,
109
+ sourcesCollected: sourceRows.filter((row) => row.last_collected_at !== null).length,
110
+ sourceCoverage: rate(sourceRows.filter((row) => row.last_collected_at !== null).length, sourceRows.length),
111
+ bootstrapJobs: bootstrapRows.length,
112
+ successfulBootstrapRate: rate(completedBootstraps.length, bootstrapRows.length),
113
+ medianBootstrapDurationMs: median(bootstrapDurations)
114
+ }
95
115
  };
96
116
  }
97
117
  //#endregion
@@ -30,6 +30,7 @@ import { buildWorkflowChildTools } from "../../agent/workflow/workflow-child-too
30
30
  import { WorkflowRunService } from "../../workflows/service/workflow-run-service.js";
31
31
  import { WorkflowSessionBridge } from "../../workflows/service/workflow-session-bridge.js";
32
32
  import { ChatStreamMapper } from "../../gateway/chat-stream/mapper.js";
33
+ import { getXopcCloudCatalogCoordinator } from "../../providers/xopc-cloud-catalog-coordinator.js";
33
34
  import { fuzzySearchWorkspaceFiles } from "../../gateway/workspace-file-search.js";
34
35
  import { sessionMetadataToTuiItem } from "../tui-session-format.js";
35
36
  import { buildTuiTranscriptTree, transcriptTreeEntryIdToRowNumber } from "../tui-transcript-tree.js";
@@ -148,9 +149,16 @@ var EmbeddedBackend = class {
148
149
  }
149
150
  async refreshXopcCloudModels() {
150
151
  try {
151
- const { XopcCloudModelSource } = await import("../../providers/xopc-cloud-model-source.js");
152
- const result = await new XopcCloudModelSource().refresh();
153
- if (result.status === "updated") log.info({ modelCount: result.modelCount }, `XOPC Cloud model catalog refreshed: ${result.modelCount} models`);
152
+ const readiness = await getXopcCloudCatalogCoordinator().ensure({
153
+ reason: "agent-run",
154
+ network: "if-empty",
155
+ timeoutMs: 1e4
156
+ });
157
+ if (!readiness.error) return;
158
+ log.warn({
159
+ errorMessage: readiness.error.message,
160
+ phase: "model_catalog_refresh"
161
+ }, `XOPC Cloud model catalog refresh failed: ${readiness.error.message}`);
154
162
  } catch (err) {
155
163
  const errorMessage = err instanceof Error ? err.message : String(err);
156
164
  log.warn({