@xopcai/xopc 0.0.162 → 0.0.164
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/README.md +4 -2
- package/README.zh-CN.md +4 -2
- 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-hpcNv9MZ.js → activity-store-DkALQFJT.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Zf9UQEmQ.js → agent-avatar-dicebear-RpxkQtQ3.js} +1 -1
- package/dist/gateway/static/root/assets/agents-CxpwxMPE.js +2 -0
- package/dist/gateway/static/root/assets/{api-Dnatri09.js → api-DPIXEcIq.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-BBTR9wJP.js → app-management-settings-panel-DLdjfMXB.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-C2zpLCHD.js → appearance-settings-C89-uxkq.js} +1 -1
- package/dist/gateway/static/root/assets/apps-page-k-tZbaRB.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-9eR_ODY1.js → archive-plugin-CqbH5geE.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-DPuWYUeX.js → attachment-load-CeU4Qiot.js} +1 -1
- package/dist/gateway/static/root/assets/{automation-suggestion-card-Dw49OJRl.js → automation-suggestion-card-WiOuqXq9.js} +1 -1
- package/dist/gateway/static/root/assets/automations-page-Bdn3dgC_.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-BdkJpDFm.js → binary-plugins-C5TdzrhJ.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-CAi7SXYU.js → block-editor-BjvWhphG.js} +39 -39
- package/dist/gateway/static/root/assets/browser-settings-page-GsVTGfGs.js +8 -0
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-Dx6wkGz1.js → browser-workflow-inputs-DXmzQ3nk.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-Skertc-A.js → browser-workflows-page-C1-ptRe4.js} +2 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-6d4kVjzl.js +2 -0
- package/dist/gateway/static/root/assets/{capability-presets-api-CNFl7dM3.js → capability-presets-api-C0pVlUyc.js} +1 -1
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DCxy5Ls_.js +2 -0
- package/dist/gateway/static/root/assets/{channel-recipient-api-DYQyGDw4.js → channel-recipient-api-B5rLegwk.js} +1 -1
- package/dist/gateway/static/root/assets/channels-settings-Bg3P8k0f.js +1 -0
- package/dist/gateway/static/root/assets/channels-status-swr-DZZq0upi.js +1 -0
- package/dist/gateway/static/root/assets/{connector-logo-Bng6kxYF.js → connector-logo-CuI5w4qM.js} +1 -1
- package/dist/gateway/static/root/assets/connectors-page-6UR7yhIZ.js +2 -0
- package/dist/gateway/static/root/assets/{desktop-pet-Bpf6oegd.js → desktop-pet-BvG8vDXZ.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BVUyefSd.js → desktop-pet-settings-CR__kZ8C.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-DjSZAPz_.js → directory-picker-path-field-BblWMz3e.js} +1 -1
- package/dist/gateway/static/root/assets/{dreaming-settings-CAZk2AM4.js → dreaming-settings-DHMPugDE.js} +3 -3
- package/dist/gateway/static/root/assets/{extension-debug-page-C2F6vTTd.js → extension-debug-page-ByVY1gZg.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-AnIt4bn4.js → extension-page-DLCKKtbK.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-M-rhlFBC.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-config-api-DLFyZv33.js → gateway-config-api-DZHqhbXH.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-DnQAA-qq.js → gateway-settings-CZswIehx.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-DbzLyJ3R.js → gateway-startup-retry-ulwTJovP.js} +1 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-TbyRfDas.js +1 -0
- package/dist/gateway/static/root/assets/goal-detail-page-B-QBVOf2.js +4 -0
- package/dist/gateway/static/root/assets/{goals-config-api-REmr3QCr.js → goals-config-api-DMxG6f0N.js} +1 -1
- package/dist/gateway/static/root/assets/goals-page-BGxki8BR.js +2 -0
- package/dist/gateway/static/root/assets/{goals-settings-Dz0F3uRO.js → goals-settings-G-w1gCYD.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-CQFY5gYs.js → heartbeat-settings-Csb90R59.js} +1 -1
- package/dist/gateway/static/root/assets/index-BXtJvaQl.css +1 -0
- package/dist/gateway/static/root/assets/{index-C8JkTS6d.js → index-CGwuxvzr.js} +70 -70
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BnOQXU5k.js → keyboard-shortcuts-settings-C_Bl3YOr.js} +1 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-BR2tBhO3.js +2 -0
- package/dist/gateway/static/root/assets/{local-apps-page-KsOtWOyM.js → local-apps-page-_8Rv-tSk.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-0lpYdNDr.js → locale-store-C_ax27uc.js} +1 -1
- package/dist/gateway/static/root/assets/logs-page-CwF0C_Z2.js +7 -0
- package/dist/gateway/static/root/assets/{markdown-split-D5GRg10r.js → markdown-split-CZnZS6gq.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C1ryULGs.js → media-plugins-C2XLYC6G.js} +1 -1
- package/dist/gateway/static/root/assets/messages-C96Zjb0V.js +5 -0
- package/dist/gateway/static/root/assets/{notes-page-CIeZ1_DT.js → notes-page-BkuZxTFo.js} +1 -1
- package/dist/gateway/static/root/assets/notes-workbench-CD4FADi7.js +4 -0
- package/dist/gateway/static/root/assets/{page-tabs-Caj1-E_X.js → page-tabs-DR2FGC4E.js} +1 -1
- package/dist/gateway/static/root/assets/{preview-open-alternatives-DKwEce-9.js → preview-open-alternatives-B65O8wBL.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-B90ZskkN.js → product-open-page-Cag-utLH.js} +1 -1
- package/dist/gateway/static/root/assets/project-detail-page-COKtUblD.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-QYmqanBN.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-BU_gBU0f.js +1 -0
- package/dist/gateway/static/root/assets/{save-bar-controls-BDYt53uQ.js → save-bar-controls-DCWpFnPc.js} +1 -1
- package/dist/gateway/static/root/assets/schedule-field-ClacZdvE.js +1 -0
- package/dist/gateway/static/root/assets/{schema-form-D7oCARF7.js → schema-form-BVlbEipU.js} +1 -1
- package/dist/gateway/static/root/assets/sessions-page-u-Pjbzfm.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-1Yck1PKq.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CARTHCxH.js → settings-form-section-GSNlQWSW.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-DEwYqESe.js → settings-loading-skeleton-08Ae5sB_.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-B6vVdHeQ.js → settings-page-BseJD4I-.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-layout-D3srt5Bi.js → settings-page-layout-bSliH-Y3.js} +1 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CGRhJVlt.js +1 -0
- package/dist/gateway/static/root/assets/{share-preview-page-Ck9SxiXw.js → share-preview-page-C114OpTx.js} +1 -1
- package/dist/gateway/static/root/assets/shares-settings-BRFpWFgI.js +1 -0
- package/dist/gateway/static/root/assets/skill-reload-api-cVjU2GnN.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-CoMTjtRT.js +2 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-DLBUQSk2.js → system-settings-panel-El8cDcTY.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-C1oaqeD2.js → theme-store-D37XLD_C.js} +1 -1
- package/dist/gateway/static/root/assets/time-picker-CU7hhD8T.js +1 -0
- package/dist/gateway/static/root/assets/{typed-models-lib-Divbg_C4.js → typed-models-lib-kToxD7Rc.js} +1 -1
- package/dist/gateway/static/root/assets/{use-channel-catalog-CP9a_rAf.js → use-channel-catalog-DBh0dOC9.js} +1 -1
- package/dist/gateway/static/root/assets/user-context-page-C0xYCSXB.js +1 -0
- package/dist/gateway/static/root/assets/voice-api-key-field-DzEpwYaU.js +1 -0
- package/dist/gateway/static/root/assets/work-discovery-page-DakZqR85.js +1 -0
- package/dist/gateway/static/root/assets/work-item-detail-page-CswqPbTT.js +1 -0
- package/dist/gateway/static/root/assets/work-page-DYRXEk8m.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DbDPYQwB.js → workflow-run-setup-panel-BwSxyVMM.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-CiLSYGuN.js +11 -0
- package/dist/gateway/static/root/index.html +7 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/client-error-format.d.ts +1 -1
- package/dist/src/agent/client-error-format.js +6 -2
- package/dist/src/agent/embedded/model-runtime.d.ts +4 -0
- package/dist/src/agent/embedded/model-runtime.js +49 -0
- package/dist/src/agent/embedded/run-for-session.js +38 -31
- package/dist/src/agent/embedded/session-runner.d.ts +1 -0
- package/dist/src/agent/embedded/session-runner.js +13 -5
- package/dist/src/agent/failover-error.d.ts +1 -1
- package/dist/src/agent/image/generation/openai-compatible-image-provider.d.ts +2 -6
- package/dist/src/agent/image/generation/openai-compatible-image-provider.js +1 -3
- package/dist/src/agent/image/generation/provider-registry.d.ts +5 -46
- package/dist/src/agent/image/generation/provider-registry.js +24 -73
- package/dist/{extensions/dashscope/src/image-generation-provider.d.ts → src/agent/image/generation/providers/dashscope.d.ts} +3 -6
- package/dist/{extensions/dashscope/src/image-generation-provider.js → src/agent/image/generation/providers/dashscope.js} +36 -59
- package/dist/{extensions/fal/src/image-generation-provider.d.ts → src/agent/image/generation/providers/fal.d.ts} +1 -1
- package/dist/{extensions/fal/src/image-generation-provider.js → src/agent/image/generation/providers/fal.js} +19 -29
- package/dist/{extensions/google/src/image-generation-provider.d.ts → src/agent/image/generation/providers/google.d.ts} +2 -2
- package/dist/{extensions/google/src/image-generation-provider.js → src/agent/image/generation/providers/google.js} +23 -30
- package/dist/{extensions/minimax/src/image-generation-provider.d.ts → src/agent/image/generation/providers/minimax.d.ts} +2 -5
- package/dist/{extensions/minimax/src/image-generation-provider.js → src/agent/image/generation/providers/minimax.js} +35 -51
- package/dist/{extensions/openai/src/image-generation-provider.d.ts → src/agent/image/generation/providers/openai.d.ts} +2 -2
- package/dist/{extensions/openai/src/image-generation-provider.js → src/agent/image/generation/providers/openai.js} +13 -38
- package/dist/src/agent/image/generation/runtime-types.d.ts +1 -0
- package/dist/src/agent/image/generation/runtime.d.ts +1 -3
- package/dist/src/agent/image/generation/runtime.js +6 -6
- package/dist/src/agent/image/generation/types.d.ts +23 -3
- package/dist/src/agent/image/index.d.ts +1 -1
- package/dist/src/agent/image/index.js +2 -2
- package/dist/src/agent/media-generation/runtime-shared.d.ts +2 -0
- package/dist/src/agent/media-generation/runtime-shared.js +1 -0
- package/dist/src/agent/tools/factory.js +4 -1
- package/dist/src/agent/tools/image-generate-tool.d.ts +2 -0
- package/dist/src/agent/tools/image-generate-tool.js +14 -7
- package/dist/src/auth/credentials.js +45 -2
- package/dist/src/auth/index.js +2 -1
- package/dist/src/auth/oauth/anthropic.js +27 -24
- package/dist/src/auth/oauth/github-copilot.js +20 -15
- package/dist/src/auth/oauth/google-antigravity.js +9 -2
- package/dist/src/auth/oauth/google-gemini-cli.js +9 -2
- package/dist/src/auth/oauth/google-oauth/google-antigravity.js +47 -40
- package/dist/src/auth/oauth/google-oauth/google-gemini-cli.js +48 -41
- package/dist/src/auth/oauth/google-oauth/oauth-page.js +7 -2
- package/dist/src/auth/oauth/google-oauth/pkce.js +4 -1
- package/dist/src/auth/oauth/index.d.ts +2 -0
- package/dist/src/auth/oauth/index.js +24 -10
- package/dist/src/auth/oauth/kimi-coding.js +76 -71
- package/dist/src/auth/oauth/minimax-cn.js +78 -73
- package/dist/src/auth/oauth/minimax.js +78 -73
- package/dist/src/auth/oauth/openai-codex.js +31 -25
- package/dist/src/auth/oauth/pkce.js +4 -1
- package/dist/src/auth/oauth/registry.d.ts +13 -0
- package/dist/src/auth/oauth/registry.js +65 -0
- package/dist/src/auth/oauth/xopc-cloud.d.ts +2 -0
- package/dist/src/auth/oauth/xopc-cloud.js +101 -0
- package/dist/src/auth/sync-provider-auth.d.ts +3 -0
- package/dist/src/auth/sync-provider-auth.js +17 -1
- package/dist/src/cli/commands/models.js +2 -5
- package/dist/src/cli/commands/onboard/model.js +3 -2
- package/dist/src/cli/commands/setup-shared/types.d.ts +1 -1
- package/dist/src/cli/utils/oauth-providers.d.ts +3 -26
- package/dist/src/cli/utils/oauth-providers.js +6 -80
- package/dist/src/config/index.js +2 -2
- package/dist/src/config/models-json.d.ts +6 -0
- package/dist/src/config/models-json.js +10 -6
- package/dist/src/config/schema.d.ts +26 -15
- package/dist/src/config/schema.js +23 -12
- package/dist/src/gateway/heartbeat/service.js +1 -1
- package/dist/src/gateway/hono/app.js +12 -6
- package/dist/src/gateway/hono/lib/safe-providers-config.d.ts +0 -3
- package/dist/src/gateway/hono/lib/safe-providers-config.js +1 -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.js +3 -19
- package/dist/src/gateway/hono/oauth.js +3 -19
- package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -11
- package/dist/src/gateway/hono/routes/deps.d.ts +1 -0
- package/dist/src/gateway/hono/routes/lazy-bundles.js +9 -2
- package/dist/src/gateway/hono/routes/models.js +96 -128
- package/dist/src/gateway/image-generation-setup.d.ts +40 -0
- package/dist/src/gateway/image-generation-setup.js +130 -0
- 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.d.ts +3 -0
- package/dist/src/gateway/service.js +10 -0
- package/dist/src/heartbeat/index.js +1 -1
- package/dist/src/media-shared/http/private-network.d.ts +1 -1
- package/dist/src/media-shared/http/private-network.js +1 -1
- package/dist/src/providers/auth-runtime/resolve-api-key.d.ts +2 -4
- package/dist/src/providers/auth-runtime/resolve-api-key.js +2 -4
- package/dist/src/providers/auth-runtime/resolve-auth.d.ts +3 -4
- package/dist/src/providers/auth-runtime/resolve-auth.js +18 -18
- package/dist/src/providers/domestic-presets.d.ts +2 -0
- package/dist/src/providers/index.js +9 -0
- package/dist/src/providers/model-catalog-store.d.ts +33 -0
- package/dist/src/providers/model-catalog-store.js +63 -0
- package/dist/src/providers/model-catalog-sync-service.d.ts +40 -0
- package/dist/src/providers/model-catalog-sync-service.js +132 -0
- package/dist/src/providers/model-reference-auditor.d.ts +14 -0
- package/dist/src/providers/model-reference-auditor.js +71 -0
- package/dist/src/providers/model-registry.d.ts +4 -1
- package/dist/src/providers/model-registry.js +33 -2
- package/dist/src/providers/presentation.js +2 -0
- package/dist/src/providers/xopc-cloud-model-source.d.ts +30 -0
- package/dist/src/providers/xopc-cloud-model-source.js +68 -0
- package/dist/src/session/index.d.ts +1 -1
- package/dist/src/session/index.js +2 -2
- package/dist/src/session/session-title.d.ts +2 -0
- package/dist/src/session/session-title.js +24 -3
- package/dist/src/work-discovery/analyzer.js +27 -14
- package/package.json +5 -7
- package/dist/extensions/dashscope/src/index.d.ts +0 -4
- package/dist/extensions/dashscope/src/index.js +0 -2
- package/dist/extensions/dashscope/xopc.extension.json +0 -15
- package/dist/extensions/fal/src/index.d.ts +0 -4
- package/dist/extensions/fal/src/index.js +0 -2
- package/dist/extensions/fal/xopc.extension.json +0 -14
- package/dist/extensions/google/src/index.d.ts +0 -4
- package/dist/extensions/google/src/index.js +0 -2
- package/dist/extensions/google/xopc.extension.json +0 -14
- package/dist/extensions/minimax/src/index.d.ts +0 -4
- package/dist/extensions/minimax/src/index.js +0 -2
- package/dist/extensions/minimax/xopc.extension.json +0 -15
- package/dist/extensions/openai/src/index.d.ts +0 -4
- package/dist/extensions/openai/src/index.js +0 -2
- package/dist/extensions/openai/xopc.extension.json +0 -14
- package/dist/gateway/static/root/assets/agents-DfVkZlHc.js +0 -2
- package/dist/gateway/static/root/assets/apps-page-BMtAa4Ra.js +0 -1
- package/dist/gateway/static/root/assets/automations-page-BiSAMYTr.js +0 -6
- package/dist/gateway/static/root/assets/browser-settings-page-DHmaEJS2.js +0 -8
- package/dist/gateway/static/root/assets/capabilities-settings-panel-B5wSgf4f.js +0 -2
- package/dist/gateway/static/root/assets/capability-presets-settings-panel-DyvFZwBj.js +0 -2
- package/dist/gateway/static/root/assets/channels-settings-BBKEqDZn.js +0 -1
- package/dist/gateway/static/root/assets/channels-status-swr-Drk110ve.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-HpgaUDQ1.js +0 -2
- package/dist/gateway/static/root/assets/extension-settings-page-CLSc6682.js +0 -1
- package/dist/gateway/static/root/assets/goal-create-dialog-DrnKFC6M.js +0 -1
- package/dist/gateway/static/root/assets/goal-detail-page-Cw1hpJkZ.js +0 -4
- package/dist/gateway/static/root/assets/goals-page-BDGkTVma.js +0 -2
- package/dist/gateway/static/root/assets/index-hmrG55qg.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-Bdef1b7F.js +0 -2
- package/dist/gateway/static/root/assets/logs-page-CwLPgrWh.js +0 -7
- package/dist/gateway/static/root/assets/messages-BwQ3WssU.js +0 -5
- package/dist/gateway/static/root/assets/notes-workbench-Cf06q19x.js +0 -4
- package/dist/gateway/static/root/assets/project-detail-page-SHTurM4t.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-BcC2qUAw.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-6vGefBHv.js +0 -1
- package/dist/gateway/static/root/assets/schedule-field-Bcdni4Pj.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-C5014a53.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CDY3ZI1K.js +0 -1
- package/dist/gateway/static/root/assets/settings-collapsible-section-6eNF8Jey.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-z-rF0Hdg.js +0 -1
- package/dist/gateway/static/root/assets/shares-settings-CHZFXE_d.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-B7p2QNXt.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-ncw3tX9P.js +0 -2
- package/dist/gateway/static/root/assets/user-context-page-iYfeSLKI.js +0 -1
- package/dist/gateway/static/root/assets/voice-api-key-field-CrwkicvT.js +0 -1
- package/dist/gateway/static/root/assets/work-discovery-page-BQWxyPg8.js +0 -1
- package/dist/gateway/static/root/assets/work-item-detail-page-50ZzGay5.js +0 -1
- package/dist/gateway/static/root/assets/work-page-DPqEahx7.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-C3eIC5HZ.js +0 -11
- package/dist/src/agent/embedded/xopc-auth-storage.d.ts +0 -19
- package/dist/src/agent/embedded/xopc-auth-storage.js +0 -40
- package/dist/src/agent/image/generation/bundled-registry.d.ts +0 -18
- package/dist/src/agent/image/generation/bundled-registry.js +0 -35
- package/dist/src/agent/image/generation/bundled.d.ts +0 -10
- package/dist/src/agent/image/generation/bundled.js +0 -15
- package/dist/src/agent/image/generation/image-provider-ui.d.ts +0 -20
- package/dist/src/agent/image/generation/image-provider-ui.js +0 -1
- package/dist/src/gateway/image-capabilities.d.ts +0 -28
- package/dist/src/gateway/image-capabilities.js +0 -78
- package/dist/src/generated/bundled-image-generation-providers.d.ts +0 -14
- package/dist/src/generated/bundled-image-generation-providers.js +0 -17
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Resolution order matches `resolveApiKeyForProvider`:
|
|
8
8
|
* 1. AuthProfileStore (per-agent profile — may be OAuth)
|
|
9
|
-
* 2.
|
|
10
|
-
* 3. PROVIDER_ENV_MAP[providerId] env vars
|
|
9
|
+
* 2. Environment variables
|
|
11
10
|
*
|
|
12
11
|
* Returns:
|
|
13
12
|
* - `mode: 'oauth' | 'azure-key' | 'api-key'`
|
|
@@ -19,8 +18,8 @@ export interface ProviderAuthResolution {
|
|
|
19
18
|
apiKey?: string;
|
|
20
19
|
mode: ProviderAuthMode;
|
|
21
20
|
profileId?: string;
|
|
22
|
-
/** Source bucket
|
|
23
|
-
source: 'store' | '
|
|
21
|
+
/** Source bucket. */
|
|
22
|
+
source: 'store' | 'env' | 'none';
|
|
24
23
|
/** Vendor metadata copied from the matched profile (azure resource etc.). */
|
|
25
24
|
meta?: Record<string, unknown>;
|
|
26
25
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { init_sync_provider_auth, resolveProviderApiKeyForAgentSync } from "../../auth/sync-provider-auth.js";
|
|
1
2
|
import { getApiKeyFromEnv, init_env_keys } from "../env-keys.js";
|
|
2
3
|
import { getDefaultAuthProfileStore } from "./auth-profile-store.js";
|
|
3
4
|
//#region src/providers/auth-runtime/resolve-auth.ts
|
|
4
5
|
init_env_keys();
|
|
6
|
+
init_sync_provider_auth();
|
|
5
7
|
function resolveAuthProfileForProvider(options) {
|
|
6
8
|
const { providerId } = options;
|
|
7
9
|
if (!providerId) return {
|
|
@@ -20,22 +22,28 @@ function resolveAuthProfileForProvider(options) {
|
|
|
20
22
|
meta: profile.meta
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
if (!options.store && !options.envReader) {
|
|
26
|
+
const storedKey = resolveProviderApiKeyForAgentSync(providerId, options.agentId, options.cfg);
|
|
27
|
+
if (storedKey) {
|
|
28
|
+
const azure = readCfgAzureMeta(options.cfg, providerId);
|
|
29
|
+
return {
|
|
30
|
+
apiKey: storedKey,
|
|
31
|
+
mode: azure ? "azure-key" : "api-key",
|
|
32
|
+
source: "store",
|
|
33
|
+
meta: azure
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const envKey = options.envReader ? readFromCustomEnv(options.envReader, providerId) : getApiKeyFromEnv(providerId);
|
|
38
|
+
if (envKey) {
|
|
25
39
|
const azure = readCfgAzureMeta(options.cfg, providerId);
|
|
26
40
|
return {
|
|
27
|
-
apiKey:
|
|
41
|
+
apiKey: envKey,
|
|
28
42
|
mode: azure ? "azure-key" : "api-key",
|
|
29
|
-
source: "
|
|
43
|
+
source: "env",
|
|
30
44
|
meta: azure
|
|
31
45
|
};
|
|
32
46
|
}
|
|
33
|
-
const envKey = options.envReader ? readFromCustomEnv(options.envReader, providerId) : getApiKeyFromEnv(providerId);
|
|
34
|
-
if (envKey) return {
|
|
35
|
-
apiKey: envKey,
|
|
36
|
-
mode: "api-key",
|
|
37
|
-
source: "env"
|
|
38
|
-
};
|
|
39
47
|
return {
|
|
40
48
|
apiKey: void 0,
|
|
41
49
|
mode: "api-key",
|
|
@@ -49,14 +57,6 @@ function pickProfile(store, providerId, profileName) {
|
|
|
49
57
|
return;
|
|
50
58
|
}
|
|
51
59
|
}
|
|
52
|
-
function readCfgApiKey(cfg, providerId) {
|
|
53
|
-
const providers = cfg?.providers;
|
|
54
|
-
if (!providers || typeof providers !== "object") return void 0;
|
|
55
|
-
const entry = providers[providerId];
|
|
56
|
-
if (!entry || typeof entry !== "object") return void 0;
|
|
57
|
-
const apiKey = entry.apiKey;
|
|
58
|
-
return typeof apiKey === "string" && apiKey.length > 0 ? apiKey : void 0;
|
|
59
|
-
}
|
|
60
60
|
function readCfgAzureMeta(cfg, providerId) {
|
|
61
61
|
const providers = cfg?.providers;
|
|
62
62
|
if (!providers || typeof providers !== "object") return void 0;
|
|
@@ -30,6 +30,8 @@ export interface DomesticProviderPreset {
|
|
|
30
30
|
models: DomesticProviderModelPreset[];
|
|
31
31
|
aliases: string[];
|
|
32
32
|
quirks?: string[];
|
|
33
|
+
onboardingIcon?: string;
|
|
34
|
+
requiresModelDiscovery?: boolean;
|
|
33
35
|
}
|
|
34
36
|
export declare const DOMESTIC_PROVIDER_PRESETS: readonly [{
|
|
35
37
|
readonly id: "dashscope-cn";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { __esmMin, __exportAll } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
|
|
3
|
+
import { getOAuthProviderIds, init_registry } from "../auth/oauth/registry.js";
|
|
3
4
|
import { hasProviderAuthOnDiskSync, init_sync_provider_auth } from "../auth/sync-provider-auth.js";
|
|
4
5
|
import { PROVIDER_ENV_MAP, getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
5
6
|
import { ModelRegistry, getModelRegistry, init_model_registry, prewarmModelRegistry, resetModelRegistry } from "./model-registry.js";
|
|
@@ -136,6 +137,7 @@ function getAllProviders() {
|
|
|
136
137
|
for (const p of getProviders()) providers.add(p);
|
|
137
138
|
for (const m of registry.getAll()) providers.add(m.provider);
|
|
138
139
|
for (const plugin of getProviderRegistry().listAll()) providers.add(plugin.id);
|
|
140
|
+
for (const provider of getOAuthProviderIds()) providers.add(provider);
|
|
139
141
|
return Array.from(providers);
|
|
140
142
|
}
|
|
141
143
|
async function getApiKey(provider, credentialOptions) {
|
|
@@ -310,12 +312,19 @@ var init_providers = __esmMin((() => {
|
|
|
310
312
|
init_model_registry();
|
|
311
313
|
init_credentials();
|
|
312
314
|
init_sync_provider_auth();
|
|
315
|
+
init_registry();
|
|
313
316
|
init_env_keys();
|
|
314
317
|
init_constants();
|
|
315
318
|
init_model_supplements();
|
|
316
319
|
init_plugin_registry();
|
|
317
320
|
OPENAI_CODEX_CANONICAL_BASE_URL = "https://chatgpt.com/backend-api/codex";
|
|
318
321
|
PROVIDER_META = {
|
|
322
|
+
"xopc-cloud": {
|
|
323
|
+
name: "XOPC Model Service",
|
|
324
|
+
category: "oauth",
|
|
325
|
+
supportsOAuth: true,
|
|
326
|
+
supportsApiKey: false
|
|
327
|
+
},
|
|
319
328
|
"openai": {
|
|
320
329
|
name: "OpenAI",
|
|
321
330
|
category: "common",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface CatalogModel {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
availability: 'available' | 'unavailable';
|
|
5
|
+
maxOutputTokens: number | null;
|
|
6
|
+
}
|
|
7
|
+
export interface CatalogSource {
|
|
8
|
+
providerId: string;
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
api: 'openai-completions' | 'openai-responses';
|
|
11
|
+
etag: string | null;
|
|
12
|
+
recommendedModel: string | null;
|
|
13
|
+
lastSuccessAt: number;
|
|
14
|
+
models: CatalogModel[];
|
|
15
|
+
}
|
|
16
|
+
export interface ModelCatalogSnapshot {
|
|
17
|
+
sources: Record<string, CatalogSource>;
|
|
18
|
+
}
|
|
19
|
+
export type AvailableCatalogModel = Omit<CatalogModel, 'availability'>;
|
|
20
|
+
export declare class ModelCatalogStore {
|
|
21
|
+
private sources;
|
|
22
|
+
load(): ModelCatalogSnapshot;
|
|
23
|
+
getSource(sourceId: string): CatalogSource | undefined;
|
|
24
|
+
saveSource(sourceId: string, source: CatalogSource): void;
|
|
25
|
+
removeSource(sourceId: string): boolean;
|
|
26
|
+
replaceSourceModels(sourceId: string, source: Omit<CatalogSource, 'models'>, models: AvailableCatalogModel[]): {
|
|
27
|
+
addedCount: number;
|
|
28
|
+
unavailableCount: number;
|
|
29
|
+
};
|
|
30
|
+
private cloneSource;
|
|
31
|
+
}
|
|
32
|
+
export declare function getModelCatalogStore(): ModelCatalogStore;
|
|
33
|
+
export declare function resetModelCatalogStore(): void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
+
//#region src/providers/model-catalog-store.ts
|
|
3
|
+
function getModelCatalogStore() {
|
|
4
|
+
globalModelCatalogStore ??= new ModelCatalogStore();
|
|
5
|
+
return globalModelCatalogStore;
|
|
6
|
+
}
|
|
7
|
+
function resetModelCatalogStore() {
|
|
8
|
+
globalModelCatalogStore = void 0;
|
|
9
|
+
}
|
|
10
|
+
var ModelCatalogStore, globalModelCatalogStore;
|
|
11
|
+
var init_model_catalog_store = __esmMin((() => {
|
|
12
|
+
ModelCatalogStore = class {
|
|
13
|
+
sources = {};
|
|
14
|
+
load() {
|
|
15
|
+
return { sources: Object.fromEntries(Object.entries(this.sources).map(([id, source]) => [id, this.cloneSource(source)])) };
|
|
16
|
+
}
|
|
17
|
+
getSource(sourceId) {
|
|
18
|
+
const source = this.sources[sourceId];
|
|
19
|
+
return source ? this.cloneSource(source) : void 0;
|
|
20
|
+
}
|
|
21
|
+
saveSource(sourceId, source) {
|
|
22
|
+
this.sources = {
|
|
23
|
+
...this.sources,
|
|
24
|
+
[sourceId]: this.cloneSource(source)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
removeSource(sourceId) {
|
|
28
|
+
if (!this.sources[sourceId]) return false;
|
|
29
|
+
const { [sourceId]: _removed, ...sources } = this.sources;
|
|
30
|
+
this.sources = sources;
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
replaceSourceModels(sourceId, source, models) {
|
|
34
|
+
const previous = this.getSource(sourceId);
|
|
35
|
+
const nextIds = new Set(models.map((model) => model.id));
|
|
36
|
+
const previousAvailableIds = new Set((previous?.models ?? []).filter((model) => model.availability === "available").map((model) => model.id));
|
|
37
|
+
const unavailable = (previous?.models ?? []).filter((model) => !nextIds.has(model.id)).map((model) => ({
|
|
38
|
+
...model,
|
|
39
|
+
availability: "unavailable"
|
|
40
|
+
}));
|
|
41
|
+
this.saveSource(sourceId, {
|
|
42
|
+
...source,
|
|
43
|
+
models: [...models.map((model) => ({
|
|
44
|
+
...model,
|
|
45
|
+
availability: "available"
|
|
46
|
+
})), ...unavailable]
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
addedCount: models.filter((model) => !previousAvailableIds.has(model.id)).length,
|
|
50
|
+
unavailableCount: unavailable.length
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
cloneSource(source) {
|
|
54
|
+
return {
|
|
55
|
+
...source,
|
|
56
|
+
models: source.models.map((model) => ({ ...model }))
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}));
|
|
61
|
+
//#endregion
|
|
62
|
+
init_model_catalog_store();
|
|
63
|
+
export { ModelCatalogStore, getModelCatalogStore, init_model_catalog_store, resetModelCatalogStore };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Config } from '../config/schema.js';
|
|
2
|
+
import { type ModelsJsonConfig } from '../config/models-json.js';
|
|
3
|
+
import { type ModelCatalogStore } from './model-catalog-store.js';
|
|
4
|
+
import { discoverProviderModels } from './model-discovery.js';
|
|
5
|
+
import { XopcCloudModelSource } from './xopc-cloud-model-source.js';
|
|
6
|
+
export interface ModelCatalogSyncStatus {
|
|
7
|
+
running: boolean;
|
|
8
|
+
refreshing: boolean;
|
|
9
|
+
lastAttemptAt?: number;
|
|
10
|
+
lastSuccessAt?: number;
|
|
11
|
+
lastError?: string;
|
|
12
|
+
sourceErrors?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export declare class ModelCatalogSyncService {
|
|
15
|
+
private readonly options;
|
|
16
|
+
private readonly xopcCloud;
|
|
17
|
+
private timer;
|
|
18
|
+
private refreshPromise;
|
|
19
|
+
private refreshAllPromise;
|
|
20
|
+
private status;
|
|
21
|
+
constructor(options?: {
|
|
22
|
+
intervalMs?: number;
|
|
23
|
+
onUpdated?: (modelCount: number) => void;
|
|
24
|
+
xopcCloud?: XopcCloudModelSource;
|
|
25
|
+
getConfig?: () => Config;
|
|
26
|
+
catalogStore?: ModelCatalogStore;
|
|
27
|
+
loadProviders?: () => ModelsJsonConfig['providers'];
|
|
28
|
+
discoverModels?: typeof discoverProviderModels;
|
|
29
|
+
refreshModels?: () => void;
|
|
30
|
+
getModelCount?: () => number;
|
|
31
|
+
});
|
|
32
|
+
start(): void;
|
|
33
|
+
stop(): void;
|
|
34
|
+
getStatus(): ModelCatalogSyncStatus;
|
|
35
|
+
refreshNow(): Promise<Awaited<ReturnType<XopcCloudModelSource['refresh']>>>;
|
|
36
|
+
refreshAll(): Promise<{
|
|
37
|
+
updatedSources: string[];
|
|
38
|
+
}>;
|
|
39
|
+
private refreshAllSources;
|
|
40
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { init_models_json, loadModelsJson } from "../config/models-json.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 { discoverProviderModels, isProviderApiDiscoverable } from "./model-discovery.js";
|
|
7
|
+
import { XopcCloudModelSource } from "./xopc-cloud-model-source.js";
|
|
8
|
+
//#region src/providers/model-catalog-sync-service.ts
|
|
9
|
+
init_logger();
|
|
10
|
+
init_models_json();
|
|
11
|
+
init_model_catalog_store();
|
|
12
|
+
init_model_registry();
|
|
13
|
+
const log = createLogger("ModelCatalogSync");
|
|
14
|
+
const DEFAULT_INTERVAL_MS = 360 * 6e4;
|
|
15
|
+
var ModelCatalogSyncService = class {
|
|
16
|
+
xopcCloud;
|
|
17
|
+
timer = null;
|
|
18
|
+
refreshPromise = null;
|
|
19
|
+
refreshAllPromise = null;
|
|
20
|
+
status = {
|
|
21
|
+
running: false,
|
|
22
|
+
refreshing: false
|
|
23
|
+
};
|
|
24
|
+
constructor(options = {}) {
|
|
25
|
+
this.options = options;
|
|
26
|
+
this.xopcCloud = options.xopcCloud ?? new XopcCloudModelSource();
|
|
27
|
+
}
|
|
28
|
+
start() {
|
|
29
|
+
if (this.status.running) return;
|
|
30
|
+
const settings = this.options.getConfig?.().modelCatalog;
|
|
31
|
+
if (settings?.enabled === false) return;
|
|
32
|
+
this.status.running = true;
|
|
33
|
+
if (settings?.refreshOnStartup !== false) queueMicrotask(() => void this.refreshAll().catch(() => {}));
|
|
34
|
+
const intervalMs = this.options.intervalMs ?? (settings?.intervalHours ?? 6) * 60 * 6e4;
|
|
35
|
+
this.timer = setInterval(() => void this.refreshAll().catch(() => {}), intervalMs || DEFAULT_INTERVAL_MS);
|
|
36
|
+
this.timer.unref();
|
|
37
|
+
}
|
|
38
|
+
stop() {
|
|
39
|
+
if (this.timer) clearInterval(this.timer);
|
|
40
|
+
this.timer = null;
|
|
41
|
+
this.status.running = false;
|
|
42
|
+
}
|
|
43
|
+
getStatus() {
|
|
44
|
+
return { ...this.status };
|
|
45
|
+
}
|
|
46
|
+
refreshNow() {
|
|
47
|
+
if (this.refreshPromise) return this.refreshPromise;
|
|
48
|
+
this.status.refreshing = true;
|
|
49
|
+
this.status.lastAttemptAt = Date.now();
|
|
50
|
+
this.refreshPromise = this.xopcCloud.refresh().then((result) => {
|
|
51
|
+
if (result.status === "updated") {
|
|
52
|
+
this.status.lastSuccessAt = Date.now();
|
|
53
|
+
this.status.lastError = void 0;
|
|
54
|
+
this.options.onUpdated?.(result.modelCount ?? 0);
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}).catch((err) => {
|
|
58
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
59
|
+
this.status.lastError = errorMessage;
|
|
60
|
+
log.warn({
|
|
61
|
+
err,
|
|
62
|
+
errorMessage
|
|
63
|
+
}, `Model catalog refresh failed: ${errorMessage}`);
|
|
64
|
+
throw err;
|
|
65
|
+
}).finally(() => {
|
|
66
|
+
this.status.refreshing = false;
|
|
67
|
+
this.refreshPromise = null;
|
|
68
|
+
});
|
|
69
|
+
return this.refreshPromise;
|
|
70
|
+
}
|
|
71
|
+
refreshAll() {
|
|
72
|
+
if (this.refreshAllPromise) return this.refreshAllPromise;
|
|
73
|
+
this.status.refreshing = true;
|
|
74
|
+
this.refreshAllPromise = this.refreshAllSources().finally(() => {
|
|
75
|
+
this.status.refreshing = false;
|
|
76
|
+
this.refreshAllPromise = null;
|
|
77
|
+
});
|
|
78
|
+
return this.refreshAllPromise;
|
|
79
|
+
}
|
|
80
|
+
async refreshAllSources() {
|
|
81
|
+
const updatedSources = [];
|
|
82
|
+
const sourceErrors = {};
|
|
83
|
+
try {
|
|
84
|
+
if ((await this.refreshNow()).status === "updated") updatedSources.push("xopc-cloud");
|
|
85
|
+
} catch (err) {
|
|
86
|
+
sourceErrors["xopc-cloud"] = err instanceof Error ? err.message : String(err);
|
|
87
|
+
}
|
|
88
|
+
this.status.refreshing = true;
|
|
89
|
+
const providers = this.options.loadProviders?.() ?? loadModelsJson().config.providers;
|
|
90
|
+
const discoverable = Object.entries(providers).filter(([, provider]) => provider.modelDiscovery?.enabled === true && typeof provider.baseUrl === "string" && isProviderApiDiscoverable(provider.api));
|
|
91
|
+
const catalogStore = this.options.catalogStore ?? getModelCatalogStore();
|
|
92
|
+
const enabledSourceIds = new Set(discoverable.map(([providerId]) => `provider:${providerId}`));
|
|
93
|
+
const removedSource = Object.keys(catalogStore.load().sources).filter((sourceId) => sourceId.startsWith("provider:") && !enabledSourceIds.has(sourceId)).map((sourceId) => catalogStore.removeSource(sourceId)).some(Boolean);
|
|
94
|
+
const results = await Promise.all(discoverable.map(async ([providerId, provider]) => {
|
|
95
|
+
try {
|
|
96
|
+
const models = await (this.options.discoverModels ?? discoverProviderModels)({
|
|
97
|
+
providerId,
|
|
98
|
+
baseUrl: provider.baseUrl,
|
|
99
|
+
apiKey: provider.apiKey,
|
|
100
|
+
api: provider.api,
|
|
101
|
+
headers: provider.headers
|
|
102
|
+
});
|
|
103
|
+
catalogStore.replaceSourceModels(`provider:${providerId}`, {
|
|
104
|
+
providerId,
|
|
105
|
+
baseUrl: provider.baseUrl,
|
|
106
|
+
api: provider.api === "openai-responses" ? "openai-responses" : "openai-completions",
|
|
107
|
+
etag: null,
|
|
108
|
+
recommendedModel: null,
|
|
109
|
+
lastSuccessAt: Date.now()
|
|
110
|
+
}, models.map((model) => ({
|
|
111
|
+
id: model.id,
|
|
112
|
+
name: model.name ?? model.id,
|
|
113
|
+
maxOutputTokens: null
|
|
114
|
+
})));
|
|
115
|
+
return providerId;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
sourceErrors[providerId] = err instanceof Error ? err.message : String(err);
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}));
|
|
121
|
+
for (const providerId of results) if (providerId) updatedSources.push(providerId);
|
|
122
|
+
if (results.some(Boolean) || removedSource) {
|
|
123
|
+
(this.options.refreshModels ?? (() => getModelRegistry().refresh()))();
|
|
124
|
+
this.status.lastSuccessAt = Date.now();
|
|
125
|
+
this.options.onUpdated?.(this.options.getModelCount?.() ?? getModelRegistry().getAll().length);
|
|
126
|
+
}
|
|
127
|
+
this.status.sourceErrors = Object.keys(sourceErrors).length > 0 ? sourceErrors : void 0;
|
|
128
|
+
return { updatedSources };
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
//#endregion
|
|
132
|
+
export { ModelCatalogSyncService };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Config } from '../config/schema.js';
|
|
2
|
+
import type { SessionAgentConfig } from '../session/config-types.js';
|
|
3
|
+
import { type ModelCatalogSnapshot } from './model-catalog-store.js';
|
|
4
|
+
import { type ModelRegistry } from './model-registry.js';
|
|
5
|
+
export interface ModelReferenceHealth {
|
|
6
|
+
ref: string;
|
|
7
|
+
availability: 'available' | 'unavailable';
|
|
8
|
+
locations: string[];
|
|
9
|
+
suggestedRef?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function auditModelReferences(config: Config, sessionConfigs?: ReadonlyMap<string, SessionAgentConfig>, deps?: {
|
|
12
|
+
registry?: ModelRegistry;
|
|
13
|
+
catalog?: ModelCatalogSnapshot;
|
|
14
|
+
}): ModelReferenceHealth[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
|
|
2
|
+
import { getModelRegistry, init_model_registry } from "./model-registry.js";
|
|
3
|
+
//#region src/providers/model-reference-auditor.ts
|
|
4
|
+
init_model_catalog_store();
|
|
5
|
+
init_model_registry();
|
|
6
|
+
function asRecord(value) {
|
|
7
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
8
|
+
}
|
|
9
|
+
function addRef(out, value, location) {
|
|
10
|
+
if (typeof value === "string" && value.trim()) out.push({
|
|
11
|
+
ref: value.trim(),
|
|
12
|
+
location
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function collectToolModel(out, value, location) {
|
|
16
|
+
const model = asRecord(value);
|
|
17
|
+
if (!model) return;
|
|
18
|
+
addRef(out, model.primary, `${location}.primary`);
|
|
19
|
+
if (Array.isArray(model.fallbacks)) model.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.fallbacks[${index}]`));
|
|
20
|
+
}
|
|
21
|
+
function collectModelPolicy(out, value, location) {
|
|
22
|
+
const policy = asRecord(value);
|
|
23
|
+
if (!policy) return;
|
|
24
|
+
const roles = asRecord(policy.roles);
|
|
25
|
+
for (const [roleId, roleValue] of Object.entries(roles ?? {})) {
|
|
26
|
+
const role = asRecord(roleValue);
|
|
27
|
+
if (!role) continue;
|
|
28
|
+
addRef(out, role.model, `${location}.roles.${roleId}.model`);
|
|
29
|
+
if (Array.isArray(role.fallbacks)) role.fallbacks.forEach((ref, index) => addRef(out, ref, `${location}.roles.${roleId}.fallbacks[${index}]`));
|
|
30
|
+
}
|
|
31
|
+
collectToolModel(out, policy.imageModel, `${location}.imageModel`);
|
|
32
|
+
collectToolModel(out, policy.imageGenerationModel, `${location}.imageGenerationModel`);
|
|
33
|
+
}
|
|
34
|
+
function collectReferences(config, sessionConfigs) {
|
|
35
|
+
const out = [];
|
|
36
|
+
for (const [presetId, preset] of Object.entries(config.agents.capabilityPresets)) collectModelPolicy(out, preset.models, `agents.capabilityPresets.${presetId}.models`);
|
|
37
|
+
for (const agent of config.agents.list) collectModelPolicy(out, agent.models, `agents.list.${agent.id}.models`);
|
|
38
|
+
for (const [sessionKey, sessionConfig] of sessionConfigs) addRef(out, sessionConfig.modelOverride, `sessions.${sessionKey}.modelOverride`);
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
function suggestedRef(ref, catalog) {
|
|
42
|
+
const providerId = ref.split("/")[0];
|
|
43
|
+
const source = Object.values(catalog.sources).find((entry) => entry.providerId === providerId);
|
|
44
|
+
if (!source) return void 0;
|
|
45
|
+
const available = new Set(source.models.filter((model) => model.availability === "available").map((model) => model.id));
|
|
46
|
+
if (source.recommendedModel && available.has(source.recommendedModel)) return `${providerId}/${source.recommendedModel}`;
|
|
47
|
+
const first = source.models.find((model) => model.availability === "available");
|
|
48
|
+
return first ? `${providerId}/${first.id}` : void 0;
|
|
49
|
+
}
|
|
50
|
+
function auditModelReferences(config, sessionConfigs = /* @__PURE__ */ new Map(), deps = {}) {
|
|
51
|
+
const registry = deps.registry ?? getModelRegistry();
|
|
52
|
+
const catalog = deps.catalog ?? getModelCatalogStore().load();
|
|
53
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
54
|
+
for (const reference of collectReferences(config, sessionConfigs)) {
|
|
55
|
+
const locations = grouped.get(reference.ref) ?? [];
|
|
56
|
+
locations.push(reference.location);
|
|
57
|
+
grouped.set(reference.ref, locations);
|
|
58
|
+
}
|
|
59
|
+
return [...grouped.entries()].map(([ref, locations]) => {
|
|
60
|
+
const availability = registry.resolve(ref) ? "available" : "unavailable";
|
|
61
|
+
const suggestion = availability === "unavailable" ? suggestedRef(ref, catalog) : void 0;
|
|
62
|
+
return {
|
|
63
|
+
ref,
|
|
64
|
+
availability,
|
|
65
|
+
locations,
|
|
66
|
+
...suggestion ? { suggestedRef: suggestion } : {}
|
|
67
|
+
};
|
|
68
|
+
}).sort((a, b) => a.ref.localeCompare(b.ref));
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { auditModelReferences };
|
|
@@ -10,11 +10,13 @@
|
|
|
10
10
|
* - Hot reload support
|
|
11
11
|
*/
|
|
12
12
|
import { type Api, type Model } from '@earendil-works/pi-ai/compat';
|
|
13
|
+
import { type ModelCatalogStore } from './model-catalog-store.js';
|
|
13
14
|
/**
|
|
14
15
|
* Model Registry - manages all models (built-in + custom)
|
|
15
16
|
*/
|
|
16
17
|
export declare class ModelRegistry {
|
|
17
18
|
private modelsJsonPath;
|
|
19
|
+
private catalogStore;
|
|
18
20
|
private models;
|
|
19
21
|
private customProviderApiKeys;
|
|
20
22
|
private loadError;
|
|
@@ -22,7 +24,7 @@ export declare class ModelRegistry {
|
|
|
22
24
|
private prewarmPromise;
|
|
23
25
|
private _availableModelsCache;
|
|
24
26
|
private _authStatusCache;
|
|
25
|
-
constructor(modelsJsonPath?: string);
|
|
27
|
+
constructor(modelsJsonPath?: string, catalogStore?: ModelCatalogStore);
|
|
26
28
|
isLoaded(): boolean;
|
|
27
29
|
/** Synchronously materialize the catalog (idempotent). */
|
|
28
30
|
ensureLoaded(): void;
|
|
@@ -69,6 +71,7 @@ export declare class ModelRegistry {
|
|
|
69
71
|
* Clears caches to ensure fresh data
|
|
70
72
|
*/
|
|
71
73
|
private loadModels;
|
|
74
|
+
private loadRemoteModels;
|
|
72
75
|
/**
|
|
73
76
|
* Load built-in models and apply provider/model overrides
|
|
74
77
|
*/
|
|
@@ -5,6 +5,7 @@ import { resolveModelsJsonPath } from "../config/paths.js";
|
|
|
5
5
|
import { init_resolve_config_value, resolveConfigValue, resolveHeaders } from "../config/resolve-config-value.js";
|
|
6
6
|
import { getDefaultModelValues, init_models_json, validateModelsConfig } from "../config/models-json.js";
|
|
7
7
|
import { getApiKeyFromEnv, init_env_keys } from "./env-keys.js";
|
|
8
|
+
import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
|
|
8
9
|
import { existsSync, readFileSync } from "fs";
|
|
9
10
|
import { getModels, getProviders } from "@earendil-works/pi-ai/compat";
|
|
10
11
|
//#region src/providers/model-registry.ts
|
|
@@ -94,6 +95,7 @@ var init_model_registry = __esmMin((() => {
|
|
|
94
95
|
init_models_json();
|
|
95
96
|
init_logger();
|
|
96
97
|
init_env_keys();
|
|
98
|
+
init_model_catalog_store();
|
|
97
99
|
log = createLogger("ModelRegistry");
|
|
98
100
|
ModelRegistry = class {
|
|
99
101
|
models = [];
|
|
@@ -103,8 +105,9 @@ var init_model_registry = __esmMin((() => {
|
|
|
103
105
|
prewarmPromise = null;
|
|
104
106
|
_availableModelsCache;
|
|
105
107
|
_authStatusCache = /* @__PURE__ */ new Map();
|
|
106
|
-
constructor(modelsJsonPath = resolveModelsJsonPath()) {
|
|
108
|
+
constructor(modelsJsonPath = resolveModelsJsonPath(), catalogStore = getModelCatalogStore()) {
|
|
107
109
|
this.modelsJsonPath = modelsJsonPath;
|
|
110
|
+
this.catalogStore = catalogStore;
|
|
108
111
|
}
|
|
109
112
|
isLoaded() {
|
|
110
113
|
return this.loaded;
|
|
@@ -213,13 +216,41 @@ var init_model_registry = __esmMin((() => {
|
|
|
213
216
|
}
|
|
214
217
|
this.customProviderApiKeys = apiKeyConfigs;
|
|
215
218
|
const builtInModels = this.loadBuiltInModels(overrides, modelOverrides);
|
|
216
|
-
|
|
219
|
+
const remoteModels = this.loadRemoteModels();
|
|
220
|
+
this.models = this.mergeCustomModels(this.mergeCustomModels(builtInModels, remoteModels), customModels);
|
|
217
221
|
log.debug({
|
|
218
222
|
builtIn: builtInModels.length,
|
|
223
|
+
remote: remoteModels.length,
|
|
219
224
|
custom: customModels.length,
|
|
220
225
|
total: this.models.length
|
|
221
226
|
}, "Models loaded");
|
|
222
227
|
}
|
|
228
|
+
loadRemoteModels() {
|
|
229
|
+
let sources;
|
|
230
|
+
try {
|
|
231
|
+
sources = this.catalogStore.load().sources;
|
|
232
|
+
} catch (err) {
|
|
233
|
+
log.warn({ err }, "Failed to load remote model catalog");
|
|
234
|
+
return [];
|
|
235
|
+
}
|
|
236
|
+
return Object.values(sources).flatMap((source) => source.models.filter((model) => model.availability === "available").map((model) => ({
|
|
237
|
+
id: model.id,
|
|
238
|
+
name: model.name,
|
|
239
|
+
api: source.api,
|
|
240
|
+
provider: source.providerId,
|
|
241
|
+
baseUrl: source.baseUrl,
|
|
242
|
+
reasoning: false,
|
|
243
|
+
input: ["text"],
|
|
244
|
+
cost: {
|
|
245
|
+
input: 0,
|
|
246
|
+
output: 0,
|
|
247
|
+
cacheRead: 0,
|
|
248
|
+
cacheWrite: 0
|
|
249
|
+
},
|
|
250
|
+
contextWindow: 128e3,
|
|
251
|
+
maxTokens: model.maxOutputTokens ?? 16384
|
|
252
|
+
})));
|
|
253
|
+
}
|
|
223
254
|
/**
|
|
224
255
|
* Load built-in models and apply provider/model overrides
|
|
225
256
|
*/
|
|
@@ -5,6 +5,7 @@ import { getDomesticProviderPreset, getDomesticProviderPresetIds } from "./domes
|
|
|
5
5
|
init_providers();
|
|
6
6
|
init_plugin_registry();
|
|
7
7
|
const FEATURED_PROVIDER_ORDER = [
|
|
8
|
+
"xopc-cloud",
|
|
8
9
|
"deepseek",
|
|
9
10
|
"openai",
|
|
10
11
|
"anthropic",
|
|
@@ -34,6 +35,7 @@ const FEATURED_PROVIDER_ORDER = [
|
|
|
34
35
|
"minimax-cn"
|
|
35
36
|
];
|
|
36
37
|
const PROVIDER_HINTS = {
|
|
38
|
+
"xopc-cloud": "Official XOPC model service with models discovered from your account.",
|
|
37
39
|
openai: "Frontier OpenAI models from the official API.",
|
|
38
40
|
anthropic: "Claude models for coding, long context, and reasoning.",
|
|
39
41
|
xai: "Grok models from xAI.",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type CredentialResolver } from '../auth/credentials.js';
|
|
2
|
+
import { type ModelCatalogStore } from './model-catalog-store.js';
|
|
3
|
+
export type XopcCloudModelRefreshResult = {
|
|
4
|
+
status: 'skipped';
|
|
5
|
+
reason: 'not_configured';
|
|
6
|
+
} | {
|
|
7
|
+
status: 'updated';
|
|
8
|
+
modelCount: number;
|
|
9
|
+
models: string[];
|
|
10
|
+
};
|
|
11
|
+
export declare class XopcCloudModelError extends Error {
|
|
12
|
+
readonly status: number;
|
|
13
|
+
readonly code?: string;
|
|
14
|
+
constructor(message: string, status: number, code?: string);
|
|
15
|
+
}
|
|
16
|
+
export declare class XopcCloudModelSource {
|
|
17
|
+
private readonly fetchImpl;
|
|
18
|
+
private readonly routerUrl;
|
|
19
|
+
private readonly credentials;
|
|
20
|
+
private readonly catalogStore;
|
|
21
|
+
private readonly refreshModels;
|
|
22
|
+
constructor(options?: {
|
|
23
|
+
fetchImpl?: typeof fetch;
|
|
24
|
+
routerUrl?: string;
|
|
25
|
+
credentials?: Pick<CredentialResolver, 'resolveApiKey'>;
|
|
26
|
+
catalogStore?: ModelCatalogStore;
|
|
27
|
+
refreshModels?: () => void;
|
|
28
|
+
});
|
|
29
|
+
refresh(): Promise<XopcCloudModelRefreshResult>;
|
|
30
|
+
}
|