@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.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-JLmEb1p0.js → activity-store-BzjFoSr0.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-CI1zQfzY.js → agent-avatar-dicebear-DTfjhfVE.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CjhgfuVJ.js +68 -0
- package/dist/gateway/static/root/assets/{api-C6MmWfcb.js → api-D269PnU9.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-Cd02GGpV.js → app-management-settings-panel-BFpfQDWc.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-Db-h2I3G.js → appearance-settings-DLxFdqhY.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-BT7F4WBI.js → apps-page-CjmlGB5V.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-CMHzJT2a.js → archive-plugin-DPlH4dnc.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-BzhI2LoH.js → attachment-load-xqfLLd0I.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-4m6Ey6wG.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DsUeHvZO.js → binary-plugins-C0tuoPXk.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CFfsIeZ4.js → block-editor-Deyphj1o.js} +47 -47
- package/dist/gateway/static/root/assets/browser-settings-page-CAGCYx8U.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-BiWghvJ0.js → browser-workflow-inputs-CYEbXyRF.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-DPLdT6Zn.js → browser-workflows-page-Bf0tPbGi.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-CKfLsxTI.js +7 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-CTxGFvsS.js → capability-presets-api-DPkFA_-R.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-CpipKNqX.js +3 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-BklVUOxC.js → channel-recipient-api-DqKaAcnZ.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-Bvq-O4pt.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-CrMld2l7.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-0F4Jmma2.js → chat-terminal-dock-CTDRZa7e.js} +2 -2
- package/dist/gateway/static/root/assets/{connectors-api-BvIZ51ty.js → connectors-api-Buu8fif8.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-CSQRzaVn.js +2 -0
- package/dist/gateway/static/root/assets/{cron-expression-BHmwaMbO.js → cron-expression-DTLR82NB.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-fj_pPCv5.js → date-picker-DyNogHQH.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-DsWvwOv-.js → dependency-picker-BpnCuo7B.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-mjkF0Xxh.js → desktop-pet-CDKI4gVB.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-ClwUpRYu.js → desktop-pet-settings-DjT5C2a3.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-OkqRFyRL.js → directory-picker-path-field-DlJY90TM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-DC69wplH.js → extension-debug-page-DWf2z7q5.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-DCtk6zdJ.js → extension-page-Dorx0kf9.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-Bkm4zzv-.js → extension-settings-page-B1wU9ZOB.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-Dr_NQt7v.js → gateway-config-api-B1lG4dNr.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-CEfv8N1J.js → gateway-config-swr-BIxuwPQi.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-settings-DqIOqJjM.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-startup-retry-B8hebJ7s.js → gateway-startup-retry-BpZgd4U-.js} +1 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-DG4Kmgkc.js +1 -0
- package/dist/gateway/static/root/assets/home-page-BhqItS_s.js +1 -0
- package/dist/gateway/static/root/assets/image-generation-api-PkhYohDa.js +1 -0
- package/dist/gateway/static/root/assets/index-DLhvsU9B.css +2 -0
- package/dist/gateway/static/root/assets/{index-DJ7HSgKs.js → index-_cuTcWjB.js} +78 -56
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DCQvf05d.js → keyboard-shortcuts-settings-6OQT3gQF.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-DWjTmzxw.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-B3Ugd0my.js → local-apps-page-DfruRAmE.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-hDBVeG3G.js → locale-store-C5MK9WcP.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-BA5efZ8B.js +2 -0
- package/dist/gateway/static/root/assets/{management-settings-C-S5Llq3.js → management-settings-L1VYkywO.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-DuVq37Uh.js → markdown-split-oqgHbqt-.js} +1 -1
- package/dist/gateway/static/root/assets/markdown-view-DD_PgVue.css +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-D8eO_6h3.js → markdown-view-V4rcPPH0.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C1V6pkX3.js → media-plugins-Bb6gSX2o.js} +1 -1
- package/dist/gateway/static/root/assets/messages-ctG2e-ix.js +3 -0
- package/dist/gateway/static/root/assets/{notes-page-Dn71ZV8c.js → notes-page-B1rOXjpT.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-CkHXVmKP.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-B5a5aSoS.js → page-tabs-CBuCKeyy.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-5041AIBX.js → preview-open-alternatives-BQ0tLfPO.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-7UkouFQU.js → product-open-page-DPeFn7Hu.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-DCqet9-L.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-D0t_AjzG.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BUWPoBvw.js +1 -0
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DvaXzHYS.js → runtime-tools-settings-panel-BCfQNzjG.js} +2 -2
- package/dist/gateway/static/root/assets/{schema-form-Dlxl_5X0.js → schema-form-Bo7YbHYN.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-vLhrrM3m.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-OP1y0Y8M.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CSaiuuer.js → settings-form-section-B9dnKr3M.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-H3mJwt3r.js → settings-loading-skeleton-CYDV2JtY.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-Cs7zA4BS.js → settings-page-DbrIYfS9.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-CwgMODfJ.js → setup-status-panel-Cxc-Ejl5.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-Bdpw5m7M.js → share-preview-page-olgr7LLN.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-ZOqC6-aA.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-DwvC3Iuf.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-Bup3Lg1Z.js → skills-page-PE16CNw5.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-D22ORR21.js → skills-page.utils-nXmBcBxt.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-GmtWsfjB.js → system-settings-panel-C3qPwAdY.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-DCRB-5q-.js +1 -0
- package/dist/gateway/static/root/assets/{theme-store-CtY8RwMX.js → theme-store-KR5Otp5w.js} +1 -1
- package/dist/gateway/static/root/assets/{typed-models-lib-C2aOdlEA.js → typed-models-lib-lMZodtDF.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DOj5i8d_.js → use-autosave-CKpatP3S.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-CoiedRuA.js +1 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-5WfurWYa.js → voice-api-key-field-CDcv0Wbh.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-D5_MH3n3.js → work-discovery-overlay-CGdT22un.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BwaU1RqI.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-bBA8LinI.js → workflow-run-setup-panel-BAHYNlQt.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-DHYmh9G7.js +5 -0
- package/dist/gateway/static/root/index.html +10 -10
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +1 -1
- package/dist/src/agent/image/generation/providers/xopc-cloud.js +2 -1
- package/dist/src/agent/image/tool-model-config.js +15 -9
- package/dist/src/agent/memory/builtin-provider.js +0 -1
- package/dist/src/agent/memory/create-memory-manager.js +1 -1
- package/dist/src/agent/tools/image-generate-tool.js +23 -7
- package/dist/src/agent-runtime/index.js +1 -1
- package/dist/src/agent-runtime/runtime-profile.js +1 -1
- package/dist/src/capabilities/readiness/from-config.d.ts +10 -0
- package/dist/src/capabilities/readiness/from-config.js +128 -0
- package/dist/src/capabilities/readiness/index.d.ts +3 -0
- package/dist/src/capabilities/readiness/index.js +3 -0
- package/dist/src/capabilities/readiness/planner.d.ts +3 -0
- package/dist/src/capabilities/readiness/planner.js +56 -0
- package/dist/src/capabilities/readiness/types.d.ts +35 -0
- package/dist/src/capabilities/readiness/types.js +1 -0
- package/dist/src/cli/commands/agent.js +9 -0
- package/dist/src/cli/commands/auth.js +4 -3
- package/dist/src/cli/commands/connectors.js +1 -1
- package/dist/src/cli/commands/models.js +2 -1
- package/dist/src/cli/commands/onboard/model.d.ts +3 -21
- package/dist/src/cli/commands/onboard/model.js +10 -86
- package/dist/src/cli/utils/oauth-login.d.ts +2 -0
- package/dist/src/cli/utils/oauth-login.js +9 -1
- package/dist/src/config/agent-profile.js +1 -1
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/paths-state.d.ts +2 -0
- package/dist/src/config/paths-state.js +5 -1
- package/dist/src/config/paths.d.ts +1 -1
- package/dist/src/config/paths.js +2 -2
- package/dist/src/config/schema.js +1 -1
- package/dist/src/connectors/composio-sessions.d.ts +1 -0
- package/dist/src/connectors/composio-sessions.js +2 -1
- package/dist/src/connectors/composio.js +8 -3
- package/dist/src/connectors/connected-source-cursor.d.ts +9 -0
- package/dist/src/connectors/connected-source-cursor.js +30 -0
- package/dist/src/connectors/connected-source-ingestion.js +67 -46
- package/dist/src/connectors/connected-source-normalizers.d.ts +1 -0
- package/dist/src/connectors/connected-source-normalizers.js +33 -2
- package/dist/src/connectors/connected-source-sanitization.d.ts +1 -0
- package/dist/src/connectors/connected-source-sanitization.js +21 -0
- package/dist/src/connectors/connector-identity.js +10 -2
- package/dist/src/connectors/content-enrichment.d.ts +29 -0
- package/dist/src/connectors/content-enrichment.js +273 -0
- package/dist/src/connectors/health.js +1 -1
- package/dist/src/connectors/learning-coordinator.js +1 -2
- package/dist/src/connectors/learning-recipes.js +28 -33
- package/dist/src/discussions/live-worker.d.ts +1 -0
- package/dist/src/discussions/live-worker.js +7 -1
- package/dist/src/discussions/repository.js +11 -1
- package/dist/src/discussions/sealer.d.ts +1 -1
- package/dist/src/discussions/sealer.js +16 -7
- package/dist/src/discussions/transcript.js +27 -1
- package/dist/src/discussions/types.d.ts +4 -0
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +8 -3
- package/dist/src/gateway/hono/middleware/strict-rate-limit.d.ts +4 -0
- package/dist/src/gateway/hono/middleware/strict-rate-limit.js +8 -1
- package/dist/src/gateway/hono/oauth-async.d.ts +11 -5
- package/dist/src/gateway/hono/oauth-async.js +29 -16
- package/dist/src/gateway/hono/oauth.d.ts +1 -3
- package/dist/src/gateway/hono/oauth.js +22 -22
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/connectors.js +1 -1
- package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
- package/dist/src/gateway/hono/routes/discussions.js +2 -1
- package/dist/src/gateway/hono/routes/lazy-bundles.js +2 -1
- package/dist/src/gateway/hono/routes/mcp.js +1 -1
- package/dist/src/gateway/hono/routes/models.js +59 -5
- package/dist/src/gateway/hono/routes/understanding-sources.js +29 -0
- package/dist/src/gateway/hono/routes/voice.d.ts +1 -2
- package/dist/src/gateway/hono/routes/voice.js +16 -35
- package/dist/src/gateway/rate-limit/buckets.d.ts +3 -0
- package/dist/src/gateway/rate-limit/buckets.js +12 -0
- package/dist/src/gateway/service/session-input-coordinator.js +1 -2
- package/dist/src/gateway/service.js +20 -5
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/knowledge/connected-understanding-pipeline.d.ts +1 -1
- package/dist/src/knowledge/connected-understanding-pipeline.js +74 -25
- package/dist/src/knowledge/ingestion-service.js +33 -15
- package/dist/src/knowledge/types.d.ts +2 -0
- package/dist/src/media-understanding/audio-transcription-runner.d.ts +2 -0
- package/dist/src/media-understanding/audio-transcription-runner.js +3 -1
- package/dist/src/media-understanding/runner.js +3 -1
- package/dist/src/media-understanding/types.d.ts +2 -0
- package/dist/src/providers/model-catalog-persistence.d.ts +9 -0
- package/dist/src/providers/model-catalog-persistence.js +172 -0
- package/dist/src/providers/model-catalog-ranking.d.ts +2 -0
- package/dist/src/providers/model-catalog-ranking.js +17 -0
- package/dist/src/providers/model-catalog-store.d.ts +13 -3
- package/dist/src/providers/model-catalog-store.js +24 -5
- package/dist/src/providers/model-catalog-sync-service.d.ts +3 -3
- package/dist/src/providers/model-catalog-sync-service.js +12 -7
- package/dist/src/providers/provider-auth-service.d.ts +1 -0
- package/dist/src/providers/provider-auth-service.js +3 -0
- package/dist/src/providers/provider-disconnect.d.ts +11 -0
- package/dist/src/providers/provider-disconnect.js +33 -0
- package/dist/src/providers/xopc-cloud-catalog-coordinator.d.ts +56 -0
- package/dist/src/providers/xopc-cloud-catalog-coordinator.js +182 -0
- package/dist/src/providers/xopc-cloud-model-source.d.ts +6 -10
- package/dist/src/providers/xopc-cloud-model-source.js +49 -27
- package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
- package/dist/src/storage/sqlite/user-context-quality-repository.d.ts +8 -0
- package/dist/src/storage/sqlite/user-context-quality-repository.js +21 -1
- package/dist/src/tui/backends/embedded-backend.js +11 -3
- package/dist/src/tui/tui-oauth-login.js +5 -0
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/user-context/sources/activity-clustering.js +30 -117
- package/dist/src/user-context/sources/index.d.ts +1 -0
- package/dist/src/user-context/sources/index.js +2 -1
- package/dist/src/user-context/sources/signal-clustering.d.ts +18 -0
- package/dist/src/user-context/sources/signal-clustering.js +131 -0
- package/dist/src/voice/audio/normalize.d.ts +17 -0
- package/dist/src/voice/audio/normalize.js +155 -0
- package/dist/src/voice/language-profile.d.ts +1 -4
- package/dist/src/voice/language-profile.js +2 -25
- package/dist/src/voice/local/runtime-client.d.ts +2 -0
- package/dist/src/voice/local/runtime-client.js +20 -1
- package/dist/src/voice/local/runtime-worker.js +7 -13
- package/dist/src/voice/local/wav.js +1 -1
- package/dist/src/voice/stt/availability.d.ts +1 -4
- package/dist/src/voice/stt/availability.js +3 -15
- package/dist/src/voice/stt/config.js +1 -0
- package/dist/src/voice/stt/factory.js +23 -0
- package/dist/src/voice/stt/index.d.ts +1 -0
- package/dist/src/voice/stt/index.js +2 -2
- package/dist/src/voice/stt/list-providers.js +1 -1
- package/dist/src/voice/stt/providers/local-transcription.js +7 -3
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +3 -1
- package/dist/src/voice/stt/transcribe-core.d.ts +5 -1
- package/dist/src/voice/stt/transcribe-core.js +13 -5
- package/dist/src/voice/stt/types.d.ts +2 -0
- package/dist/src/voice/tts/factory.d.ts +1 -1
- package/dist/src/voice/tts/factory.js +23 -1
- package/dist/src/voice/tts/merge-config.js +5 -3
- package/dist/src/voice/tts/providers/xopc-cloud-speech.js +3 -1
- package/dist/src/voice/tts/types.d.ts +2 -0
- package/dist/src/voice/tts/types.js +4 -2
- package/dist/src/work-discovery/evaluation.d.ts +23 -0
- package/dist/src/work-discovery/evaluation.js +18 -1
- package/dist/src/work-discovery/index.js +2 -2
- package/package.json +4 -3
- package/dist/gateway/static/root/assets/agents-DqGMj3QJ.js +0 -68
- package/dist/gateway/static/root/assets/automations-page-CwOXGV9z.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-CyRLhCod.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-jRKcS7lZ.js +0 -7
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-B3bKdtwU.js +0 -3
- package/dist/gateway/static/root/assets/channels-settings-yZBWH02s.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-C3zlimZd.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-OX4KvUkA.js +0 -2
- package/dist/gateway/static/root/assets/gateway-settings-V1XVxjHa.js +0 -1
- package/dist/gateway/static/root/assets/heartbeat-settings-CWUBAQrE.js +0 -1
- package/dist/gateway/static/root/assets/home-page-D57cYRd3.js +0 -1
- package/dist/gateway/static/root/assets/index-PNBFdxHb.css +0 -2
- package/dist/gateway/static/root/assets/local-app-workbench-page-BbAiMZE1.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-nXdF3wOT.js +0 -2
- package/dist/gateway/static/root/assets/markdown-view-B12xeflb.css +0 -1
- package/dist/gateway/static/root/assets/messages-1qg_hOOd.js +0 -3
- package/dist/gateway/static/root/assets/notes-workbench-BYPoZeRw.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-D27nOKbo.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-CdB5cJJ-.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-DFoZ3UNS.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-C1cbIcJ7.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DnXRlQXS.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-hlUgIkrp.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DR31B_Gz.js +0 -1
- package/dist/gateway/static/root/assets/task-detail-page-CTKDpxhf.js +0 -1
- package/dist/gateway/static/root/assets/user-context-page-keJJYpix.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BcvBiebt.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-Cz2VpWdj.js +0 -5
- package/dist/src/voice/local/runtime-dispatcher.d.ts +0 -9
- 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 {
|
|
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?:
|
|
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<
|
|
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 {
|
|
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 ??
|
|
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.
|
|
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
|
|
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
|
-
|
|
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 {
|
|
1
|
+
import type { AvailableCatalogModel, CatalogSource } from './model-catalog-store.js';
|
|
2
2
|
import { type ProviderAuthService } from './provider-auth-service.js';
|
|
3
|
-
export type
|
|
3
|
+
export type XopcCloudCatalogFetchResult = {
|
|
4
4
|
status: 'skipped';
|
|
5
5
|
reason: 'not_configured';
|
|
6
6
|
} | {
|
|
7
|
-
status: '
|
|
8
|
-
|
|
9
|
-
models:
|
|
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
|
-
|
|
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
|
|
33
|
-
const
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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: "
|
|
88
|
-
|
|
89
|
-
|
|
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
|
|
152
|
-
|
|
153
|
-
|
|
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({
|