@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
|
@@ -70,6 +70,13 @@ function createChatRateLimitMiddleware(deps) {
|
|
|
70
70
|
reason: "chat_rate_limit_exceeded"
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
+
function createMediaRateLimitMiddleware(deps) {
|
|
74
|
+
return createClientRateLimitMiddleware(deps, {
|
|
75
|
+
limiter: () => buckets.mediaApi(),
|
|
76
|
+
exceededMessage: "Media API rate limit exceeded",
|
|
77
|
+
reason: "media_rate_limit_exceeded"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
73
80
|
function createTaskRateLimitMiddleware(deps) {
|
|
74
81
|
return createClientRateLimitMiddleware(deps, {
|
|
75
82
|
limiter: () => buckets.taskApi(),
|
|
@@ -92,4 +99,4 @@ function createChannelRateLimitMiddleware(deps) {
|
|
|
92
99
|
});
|
|
93
100
|
}
|
|
94
101
|
//#endregion
|
|
95
|
-
export { createChannelRateLimitMiddleware, createChatRateLimitMiddleware, createStrictRateLimitMiddleware, createTaskRateLimitMiddleware, createXopcCloudPollRateLimitMiddleware };
|
|
102
|
+
export { createChannelRateLimitMiddleware, createChatRateLimitMiddleware, createMediaRateLimitMiddleware, createStrictRateLimitMiddleware, createTaskRateLimitMiddleware, createXopcCloudPollRateLimitMiddleware };
|
|
@@ -7,8 +7,17 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { Hono } from 'hono';
|
|
9
9
|
import type { GatewayService } from '../service.js';
|
|
10
|
-
import {
|
|
11
|
-
|
|
10
|
+
import type { Config } from '../../config/schema.js';
|
|
11
|
+
import { type CapabilityId } from '../../capabilities/readiness/index.js';
|
|
12
|
+
import type { CatalogReadiness } from '../../providers/xopc-cloud-catalog-coordinator.js';
|
|
13
|
+
export interface OAuthCompletionReadiness {
|
|
14
|
+
authorized: true;
|
|
15
|
+
state: 'connected' | 'connected-degraded';
|
|
16
|
+
catalog: CatalogReadiness;
|
|
17
|
+
capabilities: Record<CapabilityId, 'ready' | 'unavailable' | 'disabled'>;
|
|
18
|
+
}
|
|
19
|
+
export declare function buildOAuthCompletionReadiness(config: Config, catalog: CatalogReadiness): OAuthCompletionReadiness;
|
|
20
|
+
export declare function refreshModelCatalogAfterOAuth(provider: string, service: Pick<GatewayService, 'getModelCatalogSync'>): Promise<CatalogReadiness | undefined>;
|
|
12
21
|
export declare function normalizeDesktopOAuthReturnPath(value: unknown): string | undefined;
|
|
13
22
|
export declare function resolveOAuthLoginMethodPreference(params: {
|
|
14
23
|
requestedMethod?: unknown;
|
|
@@ -16,6 +25,3 @@ export declare function resolveOAuthLoginMethodPreference(params: {
|
|
|
16
25
|
remote: boolean;
|
|
17
26
|
}): string | undefined;
|
|
18
27
|
export declare function createOAuthAsyncHandler(service: GatewayService): Hono<import("hono/dist/types/types.js").BlankEnv, import("hono/dist/types/types.js").BlankSchema, "/">;
|
|
19
|
-
export declare function getOAuthCredentialsFromCache(provider: string): OAuthCredentials | undefined;
|
|
20
|
-
export declare function setOAuthCredentialsToCache(provider: string, creds: OAuthCredentials): void;
|
|
21
|
-
export declare function deleteOAuthCredentialsFromCache(provider: string): void;
|
|
@@ -4,6 +4,8 @@ import { getOAuthProviderInterfaces, init_registry } from "../../auth/oauth/regi
|
|
|
4
4
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
5
5
|
import { isLoopbackHost } from "../host.js";
|
|
6
6
|
import { resolveReverseProxyPublicUrl } from "../public-url.js";
|
|
7
|
+
import { buildCapabilityPlansForConfig } from "../../capabilities/readiness/from-config.js";
|
|
8
|
+
import "../../capabilities/readiness/index.js";
|
|
7
9
|
import { Hono } from "hono";
|
|
8
10
|
//#region src/gateway/hono/oauth-async.ts
|
|
9
11
|
/**
|
|
@@ -17,10 +19,20 @@ init_registry();
|
|
|
17
19
|
init_credentials();
|
|
18
20
|
init_logger();
|
|
19
21
|
const log = createLogger("OAuthAsync");
|
|
22
|
+
function buildOAuthCompletionReadiness(config, catalog) {
|
|
23
|
+
const plans = buildCapabilityPlansForConfig(config);
|
|
24
|
+
const capabilities = Object.fromEntries(Object.entries(plans).map(([capability, plan]) => [capability, plan.status === "disabled" ? "disabled" : plan.status === "unavailable" ? "unavailable" : "ready"]));
|
|
25
|
+
return {
|
|
26
|
+
authorized: true,
|
|
27
|
+
state: Boolean(catalog.error) || Object.values(capabilities).some((status) => status === "unavailable") ? "connected-degraded" : "connected",
|
|
28
|
+
catalog,
|
|
29
|
+
capabilities
|
|
30
|
+
};
|
|
31
|
+
}
|
|
20
32
|
async function refreshModelCatalogAfterOAuth(provider, service) {
|
|
21
|
-
if (provider !== "xopc-cloud") return;
|
|
33
|
+
if (provider !== "xopc-cloud") return void 0;
|
|
22
34
|
try {
|
|
23
|
-
await service.getModelCatalogSync().refreshNow();
|
|
35
|
+
return await service.getModelCatalogSync().refreshNow();
|
|
24
36
|
} catch (err) {
|
|
25
37
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
26
38
|
log.warn({
|
|
@@ -28,6 +40,16 @@ async function refreshModelCatalogAfterOAuth(provider, service) {
|
|
|
28
40
|
provider,
|
|
29
41
|
errorMessage
|
|
30
42
|
}, `OAuth completed, but the model catalog could not be refreshed: ${errorMessage}`);
|
|
43
|
+
return {
|
|
44
|
+
state: "unavailable",
|
|
45
|
+
source: "none",
|
|
46
|
+
modelCount: 0,
|
|
47
|
+
error: {
|
|
48
|
+
code: "refresh_failed",
|
|
49
|
+
message: errorMessage,
|
|
50
|
+
retryable: true
|
|
51
|
+
}
|
|
52
|
+
};
|
|
31
53
|
}
|
|
32
54
|
}
|
|
33
55
|
/** User-facing message when undici/fetch fails (often DNS, firewall, or wrong machine for localhost callback). */
|
|
@@ -172,6 +194,7 @@ function createOAuthAsyncHandler(service) {
|
|
|
172
194
|
verificationUri: session.verificationUri,
|
|
173
195
|
message: session.message,
|
|
174
196
|
error: session.error,
|
|
197
|
+
readiness: session.readiness,
|
|
175
198
|
expiresAt: session.expiresAt
|
|
176
199
|
}
|
|
177
200
|
});
|
|
@@ -301,13 +324,13 @@ async function runOAuthFlow(session, oauthProvider, service) {
|
|
|
301
324
|
};
|
|
302
325
|
try {
|
|
303
326
|
const credentials = await oauthProvider.login(callbacks);
|
|
304
|
-
setOAuthCredentialsToCache(session.provider, credentials);
|
|
305
327
|
await new CredentialResolver().saveOAuthCredentials(session.provider, credentials);
|
|
306
328
|
session.message = session.provider === "xopc-cloud" ? "OAuth login successful. Syncing available models..." : "OAuth login successful";
|
|
307
|
-
await refreshModelCatalogAfterOAuth(session.provider, service);
|
|
329
|
+
const catalog = await refreshModelCatalogAfterOAuth(session.provider, service);
|
|
330
|
+
if (catalog && session.provider === "xopc-cloud") session.readiness = buildOAuthCompletionReadiness(service.currentConfig, catalog);
|
|
308
331
|
session.status = "completed";
|
|
309
332
|
session.credentials = credentials;
|
|
310
|
-
session.message = "OAuth login successful";
|
|
333
|
+
session.message = session.readiness?.state === "connected-degraded" ? `OAuth login successful, but capability setup is degraded${catalog?.error ? `: ${catalog.error.message}` : ""}` : "OAuth login successful";
|
|
311
334
|
log.info({
|
|
312
335
|
sessionId: session.id,
|
|
313
336
|
provider: session.provider
|
|
@@ -331,15 +354,5 @@ async function runOAuthFlow(session, oauthProvider, service) {
|
|
|
331
354
|
session.manualCodeReject = void 0;
|
|
332
355
|
}
|
|
333
356
|
}
|
|
334
|
-
const oauthCredentialsCache = /* @__PURE__ */ new Map();
|
|
335
|
-
function getOAuthCredentialsFromCache(provider) {
|
|
336
|
-
return oauthCredentialsCache.get(provider);
|
|
337
|
-
}
|
|
338
|
-
function setOAuthCredentialsToCache(provider, creds) {
|
|
339
|
-
oauthCredentialsCache.set(provider, creds);
|
|
340
|
-
}
|
|
341
|
-
function deleteOAuthCredentialsFromCache(provider) {
|
|
342
|
-
oauthCredentialsCache.delete(provider);
|
|
343
|
-
}
|
|
344
357
|
//#endregion
|
|
345
|
-
export {
|
|
358
|
+
export { buildOAuthCompletionReadiness, createOAuthAsyncHandler, normalizeDesktopOAuthReturnPath, refreshModelCatalogAfterOAuth, resolveOAuthLoginMethodPreference };
|
|
@@ -5,6 +5,4 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Hono } from 'hono';
|
|
7
7
|
import type { GatewayService } from '../service.js';
|
|
8
|
-
|
|
9
|
-
export declare function loadOAuthCredentialsToCache(_service: GatewayService): void;
|
|
10
|
-
export declare function createOAuthHandler(_service: GatewayService): Hono<import("hono/dist/types/types.js").BlankEnv, import("hono/dist/types/types.js").BlankSchema, "/">;
|
|
8
|
+
export declare function createOAuthHandler(service: GatewayService): Hono<import("hono/dist/types/types.js").BlankEnv, import("hono/dist/types/types.js").BlankSchema, "/">;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { getOAuthProviderInterfaces, init_registry } from "../../auth/oauth/registry.js";
|
|
2
2
|
import { CredentialResolver, init_credentials } from "../../auth/credentials.js";
|
|
3
3
|
import { getProviderAuthState, init_providers, isProviderConfigured } from "../../providers/index.js";
|
|
4
|
+
import { disconnectProvider } from "../../providers/provider-disconnect.js";
|
|
5
|
+
import { buildOAuthCompletionReadiness, refreshModelCatalogAfterOAuth } from "./oauth-async.js";
|
|
4
6
|
import { Hono } from "hono";
|
|
5
7
|
//#region src/gateway/hono/oauth.ts
|
|
6
8
|
/**
|
|
@@ -12,19 +14,7 @@ init_registry();
|
|
|
12
14
|
init_credentials();
|
|
13
15
|
init_providers();
|
|
14
16
|
const OAUTH_PROVIDERS = getOAuthProviderInterfaces();
|
|
15
|
-
|
|
16
|
-
function getOAuthCredentialsFromCache(provider) {
|
|
17
|
-
return oauthCredentialsCache.get(provider);
|
|
18
|
-
}
|
|
19
|
-
function setOAuthCredentialsToCache(provider, creds) {
|
|
20
|
-
oauthCredentialsCache.set(provider, creds);
|
|
21
|
-
}
|
|
22
|
-
function deleteOAuthCredentialsFromCache(provider) {
|
|
23
|
-
oauthCredentialsCache.delete(provider);
|
|
24
|
-
}
|
|
25
|
-
/** No-op: OAuth tokens live on disk under auth paths; cache is populated during login. */
|
|
26
|
-
function loadOAuthCredentialsToCache(_service) {}
|
|
27
|
-
function createOAuthHandler(_service) {
|
|
17
|
+
function createOAuthHandler(service) {
|
|
28
18
|
const oauth = new Hono();
|
|
29
19
|
/**
|
|
30
20
|
* POST /api/auth/oauth/start
|
|
@@ -73,21 +63,28 @@ function createOAuthHandler(_service) {
|
|
|
73
63
|
return prompt.options.find((option) => option.id === "browser")?.id ?? prompt.options[0]?.id;
|
|
74
64
|
}
|
|
75
65
|
});
|
|
76
|
-
setOAuthCredentialsToCache(provider, credentials);
|
|
77
66
|
await new CredentialResolver().saveOAuthCredentials(provider, credentials);
|
|
67
|
+
const catalog = await refreshModelCatalogAfterOAuth(provider, service);
|
|
68
|
+
const readiness = catalog ? buildOAuthCompletionReadiness(service.currentConfig, catalog) : void 0;
|
|
69
|
+
service.emit("provider.auth.changed", {
|
|
70
|
+
provider,
|
|
71
|
+
connected: true
|
|
72
|
+
});
|
|
78
73
|
return c.json({
|
|
79
74
|
ok: true,
|
|
80
75
|
payload: {
|
|
81
76
|
success: true,
|
|
82
77
|
provider,
|
|
83
|
-
message: "OAuth login successful",
|
|
78
|
+
message: readiness?.state === "connected-degraded" ? "OAuth login successful, but capability setup is degraded" : "OAuth login successful",
|
|
84
79
|
expires: credentials.expires,
|
|
85
80
|
authUrl: authResult?.url,
|
|
86
81
|
deviceCode: authResult?.deviceCode,
|
|
87
82
|
verificationUri: authResult?.verificationUri,
|
|
88
83
|
instructions: authResult?.instructions,
|
|
89
84
|
usesCallbackServer: oauthProvider.usesCallbackServer ?? false,
|
|
90
|
-
manualCodeRequested
|
|
85
|
+
manualCodeRequested,
|
|
86
|
+
catalog,
|
|
87
|
+
readiness
|
|
91
88
|
}
|
|
92
89
|
});
|
|
93
90
|
} catch (err) {
|
|
@@ -101,16 +98,15 @@ function createOAuthHandler(_service) {
|
|
|
101
98
|
*/
|
|
102
99
|
oauth.get("/:provider", async (c) => {
|
|
103
100
|
const provider = c.req.param("provider");
|
|
104
|
-
const credentials = getOAuthCredentialsFromCache(provider);
|
|
105
101
|
const authState = await getProviderAuthState(provider);
|
|
106
102
|
const configured = await isProviderConfigured(provider);
|
|
107
103
|
return c.json({
|
|
108
104
|
ok: true,
|
|
109
105
|
payload: {
|
|
110
|
-
configured
|
|
106
|
+
configured,
|
|
111
107
|
authMode: authState.authMode,
|
|
112
108
|
authStatus: authState.authStatus,
|
|
113
|
-
expiresAt: authState.expiresAt
|
|
109
|
+
expiresAt: authState.expiresAt
|
|
114
110
|
}
|
|
115
111
|
});
|
|
116
112
|
});
|
|
@@ -120,8 +116,12 @@ function createOAuthHandler(_service) {
|
|
|
120
116
|
*/
|
|
121
117
|
oauth.delete("/:provider", async (c) => {
|
|
122
118
|
const provider = c.req.param("provider");
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
await disconnectProvider(provider);
|
|
120
|
+
service.emit("provider.auth.changed", {
|
|
121
|
+
provider,
|
|
122
|
+
connected: false
|
|
123
|
+
});
|
|
124
|
+
if (provider === "xopc-cloud") service.emit("model-catalog.updated", { modelCount: 0 });
|
|
125
125
|
return c.json({
|
|
126
126
|
ok: true,
|
|
127
127
|
payload: { disconnected: provider }
|
|
@@ -144,4 +144,4 @@ function createOAuthHandler(_service) {
|
|
|
144
144
|
return oauth;
|
|
145
145
|
}
|
|
146
146
|
//#endregion
|
|
147
|
-
export { createOAuthHandler
|
|
147
|
+
export { createOAuthHandler };
|
|
@@ -3,8 +3,8 @@ import { ActivationPlanner } from "../../../extensions/activation-planner.js";
|
|
|
3
3
|
import { mergeActivationContext } from "../../../extensions/activation-context.js";
|
|
4
4
|
import { fetchRegistry, listExtensions, searchExtensions } from "../../../extensions/marketplace.js";
|
|
5
5
|
import { buildWhenContextSnapshot } from "../../../extensions/when-context.js";
|
|
6
|
-
import { createOAuthHandler } from "../oauth.js";
|
|
7
6
|
import { createOAuthAsyncHandler } from "../oauth-async.js";
|
|
7
|
+
import { createOAuthHandler } from "../oauth.js";
|
|
8
8
|
import { extensionAssetMimeType } from "../lib/extension-assets.js";
|
|
9
9
|
import { loadExtensionStore, saveExtensionStore } from "../lib/extension-store.js";
|
|
10
10
|
import { relative, resolve } from "node:path";
|
|
@@ -14,7 +14,6 @@ import { getConnectorDefinition, listConnectorCatalog } from "../../../connector
|
|
|
14
14
|
import { listUnderstandingSourceGrants, revokeUnderstandingSourceGrant } from "../../../user-context/sources/repository.js";
|
|
15
15
|
import { recordConnectorHealthUsage } from "../../../connectors/usage.js";
|
|
16
16
|
import { getConnectorInstance, listConnectorInstances } from "../../../connectors/instances.js";
|
|
17
|
-
import { installConnector, installConnectorDefinition, uninstallConnector, updateConnectorConfig } from "../../../connectors/install.js";
|
|
18
17
|
import { startConnectorAuthorization } from "../../../connectors/auth-provider-registry.js";
|
|
19
18
|
import { composioLogoResponse } from "../../../connectors/composio-logo.js";
|
|
20
19
|
import { appendComposioTriggerEvent, listComposioTriggerEvents } from "../../../connectors/composio-triggers.js";
|
|
@@ -22,6 +21,7 @@ import { buildConnectedPeopleGraph } from "../../../knowledge/people-graph.js";
|
|
|
22
21
|
import "../../../knowledge/index.js";
|
|
23
22
|
import { ingestLocalFolderSource } from "../../../connectors/connected-source-ingestion.js";
|
|
24
23
|
import { previewConnectorDefinition, testConnectorInstance } from "../../../connectors/health.js";
|
|
24
|
+
import { installConnector, installConnectorDefinition, uninstallConnector, updateConnectorConfig } from "../../../connectors/install.js";
|
|
25
25
|
import { setConnectorEnabled } from "../../../connectors/lifecycle.js";
|
|
26
26
|
import { projectComposioConnectionStatus } from "../../../connectors/runtime-status.js";
|
|
27
27
|
//#region src/gateway/hono/routes/connectors.ts
|
|
@@ -4,6 +4,7 @@ export interface AuthenticatedRouteDeps {
|
|
|
4
4
|
service: GatewayService;
|
|
5
5
|
strictRateLimitMiddleware: MiddlewareHandler;
|
|
6
6
|
chatRateLimitMiddleware: MiddlewareHandler;
|
|
7
|
+
mediaRateLimitMiddleware?: MiddlewareHandler;
|
|
7
8
|
taskRateLimitMiddleware?: MiddlewareHandler;
|
|
8
9
|
xopcCloudPollRateLimitMiddleware: MiddlewareHandler;
|
|
9
10
|
channelRateLimitMiddleware?: MiddlewareHandler;
|
|
@@ -22,6 +22,7 @@ async function multipart(c) {
|
|
|
22
22
|
}
|
|
23
23
|
function registerDiscussionRoutes(authenticated, deps) {
|
|
24
24
|
const { service, strictRateLimitMiddleware } = deps;
|
|
25
|
+
const mediaRateLimitMiddleware = deps.mediaRateLimitMiddleware ?? deps.chatRateLimitMiddleware ?? strictRateLimitMiddleware;
|
|
25
26
|
authenticated.get("/api/discussion-capture/settings", (c) => c.json(service.discussions.settings()));
|
|
26
27
|
authenticated.put("/api/discussion-capture/settings", strictRateLimitMiddleware, async (c) => {
|
|
27
28
|
const body = await c.req.json().catch(() => ({}));
|
|
@@ -76,7 +77,7 @@ function registerDiscussionRoutes(authenticated, deps) {
|
|
|
76
77
|
const transcript = service.discussions.transcript(c.req.param("id"));
|
|
77
78
|
return transcript ? c.json(transcript) : c.json({ error: "Discussion not found" }, 404);
|
|
78
79
|
});
|
|
79
|
-
authenticated.put("/api/discussions/:id/segments/:sequence",
|
|
80
|
+
authenticated.put("/api/discussions/:id/segments/:sequence", mediaRateLimitMiddleware, async (c) => {
|
|
80
81
|
const body = await multipart(c);
|
|
81
82
|
if (!body) return c.json({ error: "Invalid multipart body" }, 400);
|
|
82
83
|
const file = body.file;
|
|
@@ -139,7 +139,8 @@ const AUTHENTICATED_LAZY_ROUTE_BUNDLES = [
|
|
|
139
139
|
match: (path) => startsWithAny(path, [
|
|
140
140
|
"/api/models",
|
|
141
141
|
"/api/models-json",
|
|
142
|
-
"/api/providers"
|
|
142
|
+
"/api/providers",
|
|
143
|
+
"/api/capabilities/readiness"
|
|
143
144
|
]),
|
|
144
145
|
load: async () => {
|
|
145
146
|
const { registerModelsRoutes } = await import("./models.js");
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { canonicalizeConfiguredMcpServer, normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
|
|
2
2
|
import { loadMergedBundleMcpConfig } from "../../../agent/mcp/bundle-mcp-config.js";
|
|
3
|
-
import { isManagedConnectorServer } from "../../../connectors/materialize.js";
|
|
4
3
|
import { getWorkspacePath } from "../../../config/workspace-path-helpers.js";
|
|
4
|
+
import { isManagedConnectorServer } from "../../../connectors/materialize.js";
|
|
5
5
|
import { listBundleMcpServerCapabilitiesForGateway, listBundleMcpServerToolsForGateway } from "../../../agent/mcp/bundle-mcp-gateway.js";
|
|
6
6
|
//#region src/gateway/hono/routes/mcp.ts
|
|
7
7
|
function registerMcpRoutes(authenticated, deps) {
|
|
@@ -6,7 +6,9 @@ import { getModelRegistry } from "../../../providers/model-registry.js";
|
|
|
6
6
|
import { CredentialResolver, init_credentials } from "../../../auth/credentials.js";
|
|
7
7
|
import "../../../providers/constants.js";
|
|
8
8
|
import { getProviderRegistry, init_plugin_registry } from "../../../providers/plugin-registry.js";
|
|
9
|
-
import { PROVIDER_META, getAllModels, getAllProviders, getAvailableModels, getProviderAuthState, init_providers, isProviderConfigured } from "../../../providers/index.js";
|
|
9
|
+
import { PROVIDER_META, getAllModels, getAllProviders, getAvailableModels, getProviderAuthState, init_providers, isProviderConfigured, isProviderConfiguredSync } from "../../../providers/index.js";
|
|
10
|
+
import { buildCapabilityPlansForConfig } from "../../../capabilities/readiness/from-config.js";
|
|
11
|
+
import "../../../capabilities/readiness/index.js";
|
|
10
12
|
import { getImageGenerationProvider, reloadImageGenerationProviders, resolveImageGenerationCredentialMode } from "../../../agent/image/generation/provider-registry.js";
|
|
11
13
|
import { SessionConfigStore } from "../../../session/config-store.js";
|
|
12
14
|
import { deleteCustomImageProvider, listCustomImageProviders, upsertCustomImageProvider } from "../../custom-image-providers.js";
|
|
@@ -14,6 +16,7 @@ import { getDomesticProviderPreset, getDomesticProviderPresetIds } from "../../.
|
|
|
14
16
|
import { getOnboardingFeaturedProviders, getProviderHint, getRecommendedModelsForProvider, isRecommendedModel, sortModelsForPicker, sortProvidersForPicker } from "../../../providers/presentation.js";
|
|
15
17
|
import { getAgentImageGenerationConfig, getImageGenerationCatalog, prepareImageGenerationSetup, verifyImageGenerationCredential } from "../../image-generation-setup.js";
|
|
16
18
|
import { discoverProviderModels, isProviderApiDiscoverable } from "../../../providers/model-discovery.js";
|
|
19
|
+
import { getXopcCloudCatalogCoordinator } from "../../../providers/xopc-cloud-catalog-coordinator.js";
|
|
17
20
|
import { respondStartupUnavailable } from "../lib/startup-unavailable.js";
|
|
18
21
|
import { auditModelReferences } from "../../../providers/model-reference-auditor.js";
|
|
19
22
|
import { XopcCloudAccountError, XopcCloudAccountService } from "../../../providers/xopc-cloud-account-service.js";
|
|
@@ -68,10 +71,61 @@ function registerModelsRoutes(authenticated, deps) {
|
|
|
68
71
|
const { service, strictRateLimitMiddleware } = deps;
|
|
69
72
|
const catalogSync = service.getModelCatalogSync();
|
|
70
73
|
const xopcCloudAccount = new XopcCloudAccountService();
|
|
71
|
-
authenticated.get("/api/models/catalog/status", (c) =>
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
authenticated.get("/api/models/catalog/status", (c) => {
|
|
75
|
+
const readiness = getXopcCloudCatalogCoordinator().snapshot();
|
|
76
|
+
return c.json({
|
|
77
|
+
ok: true,
|
|
78
|
+
payload: {
|
|
79
|
+
...catalogSync.getStatus(),
|
|
80
|
+
hydratedFromDisk: readiness.source === "disk",
|
|
81
|
+
stale: readiness.state === "stale",
|
|
82
|
+
fetchedAt: readiness.fetchedAt,
|
|
83
|
+
catalogVersion: readiness.catalogVersion,
|
|
84
|
+
lastRefreshError: readiness.error
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
authenticated.get("/api/capabilities/readiness", async (c) => {
|
|
89
|
+
const auth = await getProviderAuthState("xopc-cloud");
|
|
90
|
+
const catalog = getXopcCloudCatalogCoordinator().snapshot();
|
|
91
|
+
const authorized = auth.authStatus === "connected";
|
|
92
|
+
const capabilities = buildCapabilityPlansForConfig(service.currentConfig, { providerReady: (providerId) => providerId === "xopc-cloud" ? authorized : isProviderConfiguredSync(providerId) });
|
|
93
|
+
const issues = [
|
|
94
|
+
...auth.authStatus === "not_connected" ? [{
|
|
95
|
+
code: "oauth_not_connected",
|
|
96
|
+
capability: null
|
|
97
|
+
}] : [],
|
|
98
|
+
...auth.authStatus === "expired" ? [{
|
|
99
|
+
code: "oauth_expired_refresh_failed",
|
|
100
|
+
capability: null
|
|
101
|
+
}] : [],
|
|
102
|
+
...catalog.state === "unavailable" ? [{
|
|
103
|
+
code: "catalog_never_loaded",
|
|
104
|
+
capability: null
|
|
105
|
+
}] : [],
|
|
106
|
+
...catalog.state === "stale" ? [{
|
|
107
|
+
code: "catalog_stale",
|
|
108
|
+
capability: null
|
|
109
|
+
}] : [],
|
|
110
|
+
...Object.values(capabilities).filter((plan) => authorized && catalog.modelCount > 0 && plan.status === "unavailable").map((plan) => ({
|
|
111
|
+
code: "capability_not_published",
|
|
112
|
+
capability: plan.capability
|
|
113
|
+
}))
|
|
114
|
+
];
|
|
115
|
+
return c.json({
|
|
116
|
+
ok: true,
|
|
117
|
+
payload: {
|
|
118
|
+
provider: {
|
|
119
|
+
id: "xopc-cloud",
|
|
120
|
+
authorized,
|
|
121
|
+
authStatus: auth.authStatus,
|
|
122
|
+
catalog
|
|
123
|
+
},
|
|
124
|
+
capabilities,
|
|
125
|
+
issues
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
75
129
|
authenticated.get("/api/models/catalog", async (c) => {
|
|
76
130
|
const catalog = getModelCatalogStore().load();
|
|
77
131
|
const sessionConfigs = await new SessionConfigStore("").getAll();
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { deleteUnderstanding, listUnderstandingEvidence, listUnderstandings } from "../../../storage/sqlite/user-context-repository.js";
|
|
2
2
|
import { getConnectorAccount } from "../../../storage/sqlite/connector-account-repository.js";
|
|
3
3
|
import "../../../storage/sqlite/index.js";
|
|
4
|
+
import { init_agent_scope, resolveDefaultAgentId } from "../../../agent/agent-scope.js";
|
|
4
5
|
import { deleteUserFocus, getUnderstandingSourceGrant, listUnderstandingSourceGrants, listUserFocuses, revokeUnderstandingSourceGrant, setUserFocusStatus } from "../../../user-context/sources/repository.js";
|
|
6
|
+
import { listConnectedContentCandidates, readConnectedContent } from "../../../connectors/content-enrichment.js";
|
|
5
7
|
import { getWorkDiscoveryService } from "./work-discovery.js";
|
|
6
8
|
import { listUnderstandingSourceDefinitions } from "../../../user-context/sources/catalog.js";
|
|
7
9
|
//#region src/gateway/hono/routes/understanding-sources.ts
|
|
10
|
+
init_agent_scope();
|
|
8
11
|
function stringField(body, field) {
|
|
9
12
|
if (!body || typeof body !== "object") return "";
|
|
10
13
|
const value = body[field];
|
|
@@ -39,6 +42,32 @@ function registerUnderstandingSourceRoutes(authenticated, deps) {
|
|
|
39
42
|
ok: true,
|
|
40
43
|
grants: listUnderstandingSourceGrants({ includeRevoked: c.req.query("includeRevoked") === "true" })
|
|
41
44
|
}));
|
|
45
|
+
authenticated.get("/api/understanding/sources/content-candidates", (c) => {
|
|
46
|
+
const agentId = resolveDefaultAgentId(deps.service.currentConfig);
|
|
47
|
+
return c.json({
|
|
48
|
+
ok: true,
|
|
49
|
+
candidates: listConnectedContentCandidates({ agentId })
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
authenticated.post("/api/understanding/sources/content-reads", limited, async (c) => {
|
|
53
|
+
const body = await c.req.json().catch(() => null);
|
|
54
|
+
const sourceItemIds = body && typeof body === "object" && Array.isArray(body.sourceItemIds) ? body.sourceItemIds.filter((value) => typeof value === "string") : [];
|
|
55
|
+
try {
|
|
56
|
+
const agentId = resolveDefaultAgentId(deps.service.currentConfig);
|
|
57
|
+
return c.json({
|
|
58
|
+
ok: true,
|
|
59
|
+
result: await readConnectedContent({
|
|
60
|
+
sourceItemIds,
|
|
61
|
+
agentId
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return c.json({
|
|
66
|
+
ok: false,
|
|
67
|
+
error: error instanceof Error ? error.message : String(error)
|
|
68
|
+
}, 400);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
42
71
|
authenticated.delete("/api/understanding/sources/grants/:grantId", limited, (c) => {
|
|
43
72
|
const current = getUnderstandingSourceGrant(c.req.param("grantId"));
|
|
44
73
|
const accountId = typeof current?.config.accountId === "string" ? current.config.accountId : void 0;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Voice routes — POST /api/voice/transcriptions (multipart)
|
|
3
|
-
* POST /api/voice/transcribe (JSON/base64).
|
|
2
|
+
* Voice routes — POST /api/voice/transcriptions (multipart).
|
|
4
3
|
*
|
|
5
4
|
* The endpoints share one execution path that:
|
|
6
5
|
* 1. Runs the configured STT provider and fallback chain
|
|
@@ -6,7 +6,7 @@ import { speak } from "../../../voice/tts/speak-core.js";
|
|
|
6
6
|
import { mergeTtsConfigFromAppConfig } from "../../../voice/tts/merge-config.js";
|
|
7
7
|
import { getLocalVoiceRuntimeClient } from "../../../voice/local/runtime-client.js";
|
|
8
8
|
import { resolveSttProviderConfigSlice } from "../../../voice/stt/config-slice.js";
|
|
9
|
-
import { transcribe } from "../../../voice/stt/transcribe-core.js";
|
|
9
|
+
import { STTTranscriptionError, transcribe } from "../../../voice/stt/transcribe-core.js";
|
|
10
10
|
import { isSTTAvailable } from "../../../voice/stt/availability.js";
|
|
11
11
|
import { mergeSttConfigFromAppConfig } from "../../../voice/stt/config.js";
|
|
12
12
|
import "../../../voice/stt/index.js";
|
|
@@ -497,6 +497,7 @@ function registerVoiceRoutes(authenticated, deps) {
|
|
|
497
497
|
...detectedLanguage ? { language: detectedLanguage } : {},
|
|
498
498
|
provider: result.provider,
|
|
499
499
|
attempts: result.attempts,
|
|
500
|
+
...result.duration !== void 0 ? { durationSeconds: result.duration } : {},
|
|
500
501
|
latencyMs: Date.now() - startedAt
|
|
501
502
|
}
|
|
502
503
|
});
|
|
@@ -507,9 +508,22 @@ function registerVoiceRoutes(authenticated, deps) {
|
|
|
507
508
|
mimeType: input.mimeType,
|
|
508
509
|
fileName: input.fileName
|
|
509
510
|
}, `Voice transcription failed: ${msg}`);
|
|
511
|
+
if (error instanceof STTTranscriptionError) {
|
|
512
|
+
const status = error.reasonCode === "unsupported_format" ? 415 : error.reasonCode === "timeout" ? 504 : 502;
|
|
513
|
+
return c.json({
|
|
514
|
+
ok: false,
|
|
515
|
+
error: {
|
|
516
|
+
code: error.reasonCode,
|
|
517
|
+
message: `Transcription failed: ${msg}`
|
|
518
|
+
}
|
|
519
|
+
}, status);
|
|
520
|
+
}
|
|
510
521
|
return c.json({
|
|
511
522
|
ok: false,
|
|
512
|
-
error: {
|
|
523
|
+
error: {
|
|
524
|
+
code: "provider_error",
|
|
525
|
+
message: `Transcription failed: ${msg}`
|
|
526
|
+
}
|
|
513
527
|
}, 502);
|
|
514
528
|
}
|
|
515
529
|
};
|
|
@@ -544,39 +558,6 @@ function registerVoiceRoutes(authenticated, deps) {
|
|
|
544
558
|
...language ? { language } : {}
|
|
545
559
|
});
|
|
546
560
|
});
|
|
547
|
-
/** Legacy JSON/base64 endpoint retained for mobile and external clients. */
|
|
548
|
-
authenticated.post("/api/voice/transcribe", strictRateLimitMiddleware, async (c) => {
|
|
549
|
-
let body = {};
|
|
550
|
-
try {
|
|
551
|
-
body = await c.req.json();
|
|
552
|
-
} catch {
|
|
553
|
-
return c.json({
|
|
554
|
-
ok: false,
|
|
555
|
-
error: { message: "Invalid JSON body" }
|
|
556
|
-
}, 400);
|
|
557
|
-
}
|
|
558
|
-
if (typeof body.audio !== "string" || !body.audio.trim()) return c.json({
|
|
559
|
-
ok: false,
|
|
560
|
-
error: { message: "Missing required field: audio (base64)" }
|
|
561
|
-
}, 400);
|
|
562
|
-
if (typeof body.mimeType !== "string" || !body.mimeType.trim()) return c.json({
|
|
563
|
-
ok: false,
|
|
564
|
-
error: { message: "Missing required field: mimeType" }
|
|
565
|
-
}, 400);
|
|
566
|
-
const encoded = body.audio.replace(/\s/g, "");
|
|
567
|
-
if (encoded.length % 4 === 1 || !/^[A-Za-z0-9+/]*={0,2}$/.test(encoded)) return c.json({
|
|
568
|
-
ok: false,
|
|
569
|
-
error: { message: "Invalid base64 audio data" }
|
|
570
|
-
}, 400);
|
|
571
|
-
const language = typeof body.language === "string" && body.language.trim() ? body.language.trim() : void 0;
|
|
572
|
-
const fileName = typeof body.fileName === "string" && body.fileName.trim() ? body.fileName.trim() : `audio-${Date.now()}`;
|
|
573
|
-
return runTranscription(c, {
|
|
574
|
-
audioBuffer: Buffer.from(encoded, "base64"),
|
|
575
|
-
mimeType: body.mimeType.trim(),
|
|
576
|
-
fileName,
|
|
577
|
-
...language ? { language } : {}
|
|
578
|
-
});
|
|
579
|
-
});
|
|
580
561
|
}
|
|
581
562
|
//#endregion
|
|
582
563
|
export { registerVoiceRoutes };
|
|
@@ -36,6 +36,7 @@ declare class BucketRegistry {
|
|
|
36
36
|
private authFailureSignature?;
|
|
37
37
|
private strictApiLimiter?;
|
|
38
38
|
private chatApiLimiter?;
|
|
39
|
+
private mediaApiLimiter?;
|
|
39
40
|
private taskApiLimiter?;
|
|
40
41
|
private xopcCloudPollLimiter?;
|
|
41
42
|
private channelApiLimiter?;
|
|
@@ -53,6 +54,8 @@ declare class BucketRegistry {
|
|
|
53
54
|
strictApi(): RateLimiter;
|
|
54
55
|
/** Interactive chat actions — 180 req / 60 s per client IP. */
|
|
55
56
|
chatApi(): RateLimiter;
|
|
57
|
+
/** Durable media chunk uploads — 300 req / 60 s per client IP. */
|
|
58
|
+
mediaApi(): RateLimiter;
|
|
56
59
|
/** Interactive task and board mutations — 300 req / 60 s per client IP. */
|
|
57
60
|
taskApi(): RateLimiter;
|
|
58
61
|
/** XOPC Cloud authorization polling — 60 req / 60 s per client IP. */
|
|
@@ -48,6 +48,7 @@ var BucketRegistry = class {
|
|
|
48
48
|
authFailureSignature;
|
|
49
49
|
strictApiLimiter;
|
|
50
50
|
chatApiLimiter;
|
|
51
|
+
mediaApiLimiter;
|
|
51
52
|
taskApiLimiter;
|
|
52
53
|
xopcCloudPollLimiter;
|
|
53
54
|
channelApiLimiter;
|
|
@@ -90,6 +91,14 @@ var BucketRegistry = class {
|
|
|
90
91
|
});
|
|
91
92
|
return this.chatApiLimiter;
|
|
92
93
|
}
|
|
94
|
+
/** Durable media chunk uploads — 300 req / 60 s per client IP. */
|
|
95
|
+
mediaApi() {
|
|
96
|
+
if (!this.mediaApiLimiter) this.mediaApiLimiter = new RateLimiter({
|
|
97
|
+
maxRequests: 300,
|
|
98
|
+
windowMs: 6e4
|
|
99
|
+
});
|
|
100
|
+
return this.mediaApiLimiter;
|
|
101
|
+
}
|
|
93
102
|
/** Interactive task and board mutations — 300 req / 60 s per client IP. */
|
|
94
103
|
taskApi() {
|
|
95
104
|
if (!this.taskApiLimiter) this.taskApiLimiter = new RateLimiter({
|
|
@@ -151,6 +160,7 @@ var BucketRegistry = class {
|
|
|
151
160
|
this.authFailureLimiter?.destroy();
|
|
152
161
|
this.strictApiLimiter?.destroy();
|
|
153
162
|
this.chatApiLimiter?.destroy();
|
|
163
|
+
this.mediaApiLimiter?.destroy();
|
|
154
164
|
this.taskApiLimiter?.destroy();
|
|
155
165
|
this.xopcCloudPollLimiter?.destroy();
|
|
156
166
|
this.channelApiLimiter?.destroy();
|
|
@@ -161,6 +171,7 @@ var BucketRegistry = class {
|
|
|
161
171
|
this.authFailureLimiter = void 0;
|
|
162
172
|
this.strictApiLimiter = void 0;
|
|
163
173
|
this.chatApiLimiter = void 0;
|
|
174
|
+
this.mediaApiLimiter = void 0;
|
|
164
175
|
this.taskApiLimiter = void 0;
|
|
165
176
|
this.xopcCloudPollLimiter = void 0;
|
|
166
177
|
this.channelApiLimiter = void 0;
|
|
@@ -175,6 +186,7 @@ var BucketRegistry = class {
|
|
|
175
186
|
this.authFailureLimiter?.resetForTests();
|
|
176
187
|
this.strictApiLimiter?.resetForTests();
|
|
177
188
|
this.chatApiLimiter?.resetForTests();
|
|
189
|
+
this.mediaApiLimiter?.resetForTests();
|
|
178
190
|
this.taskApiLimiter?.resetForTests();
|
|
179
191
|
this.xopcCloudPollLimiter?.resetForTests();
|
|
180
192
|
this.channelApiLimiter?.resetForTests();
|
|
@@ -90,12 +90,11 @@ var SessionInputCoordinator = class {
|
|
|
90
90
|
remaining: [...result.remainingMessages, replacement]
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
|
-
const state = this.publish(sessionKey);
|
|
94
93
|
this.drain(sessionKey);
|
|
95
94
|
return {
|
|
96
95
|
ok: true,
|
|
97
96
|
effectiveDelivery: "next",
|
|
98
|
-
state
|
|
97
|
+
state: this.publish(sessionKey)
|
|
99
98
|
};
|
|
100
99
|
});
|
|
101
100
|
}
|