@undefineds.co/xpod 0.4.3 → 0.4.5
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/config/cloud.json +1 -1
- package/config/main.json +36 -2
- package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +3 -0
- package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +1 -1
- package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +2 -1
- package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +101 -32
- package/dist/api/ai-gateway/connect/DeviceCodeProtocol.d.ts +80 -0
- package/dist/api/ai-gateway/connect/DeviceCodeProtocol.js +3 -0
- package/dist/api/ai-gateway/connect/FileSessionImportAdapter.d.ts +38 -0
- package/dist/api/ai-gateway/connect/FileSessionImportAdapter.js +63 -0
- package/dist/api/ai-gateway/connect/LoopbackAuthorizationCallbackReceiver.d.ts +24 -0
- package/dist/api/ai-gateway/connect/LoopbackAuthorizationCallbackReceiver.js +136 -0
- package/dist/api/ai-gateway/connect/OAuthConnectAdapter.d.ts +2 -0
- package/dist/api/ai-gateway/connect/OAuthConnectAdapter.js +2 -1
- package/dist/api/ai-gateway/connect/OAuthIntegrationRegistry.d.ts +17 -13
- package/dist/api/ai-gateway/connect/OAuthIntegrationRegistry.js +52 -19
- package/dist/api/ai-gateway/connect/OpenAiSubscriptionSessionImportAdapter.d.ts +4 -28
- package/dist/api/ai-gateway/connect/OpenAiSubscriptionSessionImportAdapter.js +7 -58
- package/dist/api/ai-gateway/connect/ProviderAuthorizationProfiles.d.ts +4 -0
- package/dist/api/ai-gateway/connect/ProviderAuthorizationProfiles.js +116 -0
- package/dist/api/ai-gateway/connect/SessionImportProfiles.d.ts +10 -0
- package/dist/api/ai-gateway/connect/SessionImportProfiles.js +112 -0
- package/dist/api/ai-gateway/connect/index.d.ts +125 -23
- package/dist/api/ai-gateway/connect/index.js +1277 -260
- package/dist/api/ai-gateway/models/PodModelSelectionRepository.d.ts +4 -1
- package/dist/api/ai-gateway/models/PodModelSelectionRepository.js +154 -19
- package/dist/api/ai-gateway/providers/DeepSeekRuntimeAdapter.js +10 -6
- package/dist/api/ai-gateway/providers/ModelsDevCatalog.d.ts +7 -0
- package/dist/api/ai-gateway/providers/ModelsDevCatalog.js +25 -1
- package/dist/api/ai-gateway/providers/OfferingAuthorization.d.ts +24 -0
- package/dist/api/ai-gateway/providers/OfferingAuthorization.js +37 -0
- package/dist/api/ai-gateway/providers/OpenAiRuntimeAdapter.d.ts +1 -1
- package/dist/api/ai-gateway/providers/OpenAiRuntimeAdapter.js +5 -3
- package/dist/api/ai-gateway/providers/ProviderRegistry.d.ts +6 -3
- package/dist/api/ai-gateway/providers/ProviderRegistry.js +55 -16
- package/dist/api/ai-gateway/providers/ProviderRuntimeAdapter.d.ts +2 -0
- package/dist/api/ai-gateway/providers/ProviderRuntimeAdapter.js +37 -4
- package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.js +7 -0
- package/dist/api/ai-gateway/quota/SubscriptionQuotaAdapters.js +2 -1
- package/dist/api/ai-gateway/routing/ModelRouter.js +3 -1
- package/dist/api/container/common.js +30 -40
- package/dist/api/container/index.js +6 -2
- package/dist/api/container/routes.js +5 -22
- package/dist/api/handlers/AiClientConfigurationHandler.js +39 -1
- package/dist/api/handlers/AiGatewayManagementHandler.d.ts +3 -0
- package/dist/api/handlers/AiGatewayManagementHandler.js +173 -58
- package/dist/api/service/AiClientConfigurationService.d.ts +4 -15
- package/dist/api/service/AiClientConfigurationService.js +17 -64
- package/dist/cli/commands/start.js +2 -0
- package/dist/components/components.jsonld +1 -0
- package/dist/components/context.jsonld +80 -0
- package/dist/http/InternalPodDataHttpHandler.d.ts +3 -0
- package/dist/http/InternalPodDataHttpHandler.js +13 -2
- package/dist/http/InternalPodDataHttpHandler.jsonld +12 -0
- package/dist/identity/oidc/RememberedClientPromptFactory.d.ts +1 -1
- package/dist/identity/oidc/RememberedClientPromptFactory.js +5 -2
- package/dist/identity/oidc/RememberedConsentHandler.js +1 -1
- package/dist/identity/oidc/ScopedPickWebIdHandler.d.ts +1 -0
- package/dist/identity/oidc/ScopedPickWebIdHandler.js +26 -0
- package/dist/identity/oidc/ScopedPickWebIdHandler.jsonld +4 -0
- package/dist/identity/oidc/SessionBoundIdentityProviderFactory.d.ts +10 -0
- package/dist/identity/oidc/SessionBoundIdentityProviderFactory.js +21 -0
- package/dist/identity/oidc/SessionBoundIdentityProviderFactory.jsonld +172 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -2
- package/dist/runtime/component-parameter-keys.js +18 -2
- package/dist/storage/accessors/MixDataAccessor.js +6 -2
- package/dist/storage/rdf/PostgresRdfEngine.js +10 -2
- package/dist/storage/rdf/RdfContentTypes.js +4 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.d.ts +3 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.js +13 -16
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsList.js +1 -3
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.d.ts +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.js +2 -2
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.d.ts +4 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.js +127 -57
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.d.ts +6 -4
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.js +436 -83
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.d.ts +3 -2
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.js +212 -76
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.d.ts +6 -4
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.js +58 -41
- package/node_modules/@undefineds.co/ai-connections/dist/AiQuotaCard.d.ts +4 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiQuotaCard.js +63 -4
- package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.d.ts +46 -6
- package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.js +143 -14
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.d.ts +19 -3
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.js +45 -7
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/codex.d.ts +7 -1
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/codex.js +305 -40
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/index.cjs +383 -50
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/json-env-adapter.js +3 -2
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/pi.js +12 -3
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/transaction.d.ts +2 -0
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/transaction.js +39 -4
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/types.d.ts +8 -1
- package/node_modules/@undefineds.co/ai-connections/dist/client-visuals.d.ts +2 -0
- package/node_modules/@undefineds.co/ai-connections/dist/client-visuals.js +14 -0
- package/node_modules/@undefineds.co/ai-connections/dist/controller.d.ts +2 -2
- package/node_modules/@undefineds.co/ai-connections/dist/controller.js +216 -57
- package/node_modules/@undefineds.co/ai-connections/dist/index.d.ts +3 -1
- package/node_modules/@undefineds.co/ai-connections/dist/index.js +16 -2
- package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.js +6 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/execution/ldp-executor.js +27 -6
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/pod-database.js +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/query-builders/select-query-builder.js +2 -2
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/sparql/builder/update-builder.js +12 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/triple/builder.js +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/triple/handlers/array.js +8 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/triple/handlers/default.js +9 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/core/triple/handlers/inline.js +3 -3
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/execution/ldp-executor.js +27 -6
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/pod-database.js +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/query-builders/select-query-builder.js +2 -2
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/sparql/builder/update-builder.js +12 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/triple/builder.js +1 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/triple/handlers/array.js +8 -0
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/triple/handlers/default.js +9 -1
- package/node_modules/@undefineds.co/drizzle-solid/dist/esm/core/triple/handlers/inline.js +3 -3
- package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +31 -0
- package/package.json +2 -2
- package/static/app/assets/{index-BikOyGPu.js → index-BCZVzMpj.js} +44 -44
- package/static/app/assets/inrupt-smoke.js +2 -2
- package/static/app/assets/main.css +1 -1
- package/static/app/assets/main.js +10 -10
- package/static/auth-callback/assets/{AiConfigContext-DrCH6ckh.js → AiConfigContext-DVkh8Kg2.js} +1 -1
- package/static/auth-callback/assets/{AiConfigPage-DVrlSSdA.js → AiConfigPage-HWVWpe-P.js} +1 -1
- package/static/auth-callback/assets/{DocumentProcessingPanel-_Md-v2R2.js → DocumentProcessingPanel-DDq-mH17.js} +1 -1
- package/static/auth-callback/assets/{IndexLifecyclePanel-BbWwe23H.js → IndexLifecyclePanel-Cx4cjrdP.js} +1 -1
- package/static/auth-callback/assets/{IndexSubjectPanel-upH9MjU-.js → IndexSubjectPanel-DzSw8M9j.js} +1 -1
- package/static/auth-callback/assets/{ModelAssignmentsPanel-CVGH4t4g.js → ModelAssignmentsPanel-BsRxGc2p.js} +1 -1
- package/static/auth-callback/assets/ModelsPage-DEe1lo6Q.js +10 -0
- package/static/auth-callback/assets/{NetworkPage-Dcbrb1fd.js → NetworkPage-DBiEh1Oz.js} +1 -1
- package/static/auth-callback/assets/{PaneListHeader-DrY-1wBq.js → PaneListHeader-lEEgjyN9.js} +1 -1
- package/static/auth-callback/assets/{SearchIndexingPanel-Dw25y53v.js → SearchIndexingPanel-CZCUUGt6.js} +1 -1
- package/static/auth-callback/assets/{StatusSubjectPanel-BHlz9rNF.js → StatusSubjectPanel-21qdueMr.js} +1 -1
- package/static/auth-callback/assets/{StatusWorkspace-BH7exQP5.js → StatusWorkspace-R8RKsqVz.js} +1 -1
- package/static/auth-callback/assets/{SystemSettingsPage-BYLKnM9f.js → SystemSettingsPage-BQ4e-4Wy.js} +1 -1
- package/static/auth-callback/assets/{SystemSettingsSubjectPanel-DT34LKku.js → SystemSettingsSubjectPanel-BopXD7SE.js} +1 -1
- package/static/auth-callback/assets/{activity-DdULRcSI.js → activity-DSfmTGfY.js} +1 -1
- package/static/auth-callback/assets/ai-connections-C03UWyPh.js +1 -0
- package/static/auth-callback/assets/{auth-callback-D7l2P25I.js → auth-callback-DleaitAS.js} +91 -91
- package/static/auth-callback/assets/auth-callback-vPSC2d2F.css +1 -0
- package/static/auth-callback/assets/{badge-j4zjFnmg.js → badge-B0aLu1sl.js} +1 -1
- package/static/auth-callback/assets/{download-DGXoks01.js → download-D_bFwdYJ.js} +1 -1
- package/static/auth-callback/assets/{external-link-CvbgXXaI.js → external-link-DRfjTaQu.js} +1 -1
- package/static/auth-callback/assets/{index-LRWvKJ2i.js → index-CG23cLYQ.js} +1 -1
- package/static/auth-callback/assets/{index-BOK3j1dz.js → index-CyV9ejwx.js} +1 -1
- package/static/auth-callback/assets/{index-browser-C1Qpe0g4.js → index-browser-D70paxIg.js} +1 -1
- package/static/auth-callback/assets/{key-round-CmgS5UdQ.js → key-round-BjV_mVYH.js} +1 -1
- package/static/auth-callback/assets/{rotate-ccw-c4CSG6Rq.js → rotate-ccw-CKoOAfse.js} +1 -1
- package/static/auth-callback/assets/{skeleton-ZPMTiRSM.js → skeleton-BZNjZaHx.js} +1 -1
- package/static/auth-callback/assets/{waypoints-xjyBflU5.js → waypoints-DoaJVzZv.js} +1 -1
- package/static/auth-callback/assets/{workspace-layout-B9nj6F5J.js → workspace-layout-CaP46_ZR.js} +1 -1
- package/static/auth-callback/auth-callback.html +2 -2
- package/static/dashboard/assets/{AiConfigContext-BWOOSYNr.js → AiConfigContext-BSrR27yD.js} +1 -1
- package/static/dashboard/assets/{AiConfigPage-CG2kQ9Wy.js → AiConfigPage-D65Z2LET.js} +1 -1
- package/static/dashboard/assets/{DocumentProcessingPanel-B4VXajfj.js → DocumentProcessingPanel-DyTe7Nei.js} +1 -1
- package/static/dashboard/assets/{IndexLifecyclePanel-CWCy0CC8.js → IndexLifecyclePanel-fK8ZGlrL.js} +1 -1
- package/static/dashboard/assets/{IndexSubjectPanel-CSgyQnG_.js → IndexSubjectPanel-CZPGor7v.js} +1 -1
- package/static/dashboard/assets/{ModelAssignmentsPanel-CdGIGidT.js → ModelAssignmentsPanel-CfYn5LMQ.js} +1 -1
- package/static/dashboard/assets/ModelsPage-djlJsghe.js +25 -0
- package/static/dashboard/assets/{NetworkPage-COia9NCH.js → NetworkPage-Coj6GnPl.js} +1 -1
- package/static/dashboard/assets/{PaneListHeader-SZWyr602.js → PaneListHeader-CUuFNSsZ.js} +1 -1
- package/static/dashboard/assets/{SearchIndexingPanel-D6PZtG6k.js → SearchIndexingPanel-CyJLioXS.js} +1 -1
- package/static/dashboard/assets/{StatusSubjectPanel-CxRD4kv0.js → StatusSubjectPanel-Cv26GSVC.js} +1 -1
- package/static/dashboard/assets/{StatusWorkspace-D3PfmY9-.js → StatusWorkspace-CDjFrsmB.js} +1 -1
- package/static/dashboard/assets/{SystemSettingsPage-COg1MmMj.js → SystemSettingsPage-BuNOyNoa.js} +1 -1
- package/static/dashboard/assets/{SystemSettingsSubjectPanel-BSVVB9Ol.js → SystemSettingsSubjectPanel-B2dasdez.js} +1 -1
- package/static/dashboard/assets/{activity-BJJx5cN-.js → activity-D1d2j_4Z.js} +1 -1
- package/static/dashboard/assets/ai-connections-C03UWyPh.js +1 -0
- package/static/dashboard/assets/{badge-elmrFSCj.js → badge-BeAAv6sp.js} +1 -1
- package/static/dashboard/assets/{dashboard-IvQrNmru.js → dashboard-BnGrUGv8.js} +68 -68
- package/static/dashboard/assets/dashboard-vPSC2d2F.css +1 -0
- package/static/dashboard/assets/{download-C3FH2KzG.js → download-DfFGiZRn.js} +1 -1
- package/static/dashboard/assets/{external-link-Bx7F0uKb.js → external-link-IsjU_LC9.js} +1 -1
- package/static/dashboard/assets/{index-liRoRIP1.js → index-BWQTucPe.js} +1 -1
- package/static/dashboard/assets/{index-M4-kWiGz.js → index-Dj75OjnW.js} +1 -1
- package/static/dashboard/assets/{key-round-CXg0bKAj.js → key-round-BJ_9wmQ_.js} +1 -1
- package/static/dashboard/assets/{rotate-ccw-yxJKOBrX.js → rotate-ccw-D3JGiFbR.js} +1 -1
- package/static/dashboard/assets/{skeleton-x9jNGrQT.js → skeleton-CC4nc-z-.js} +1 -1
- package/static/dashboard/assets/{waypoints-CTKeRsGp.js → waypoints-h7sqFqiG.js} +1 -1
- package/static/dashboard/assets/{workspace-layout--YkgkS38.js → workspace-layout-ZAPTOHhs.js} +1 -1
- package/static/dashboard/dashboard.html +2 -2
- package/static/settings/assets/{AiConfigContext-CelxXFcQ.js → AiConfigContext-lGkWpvKP.js} +1 -1
- package/static/settings/assets/{AiConfigPage-BaP-EovM.js → AiConfigPage-BbZWIBZq.js} +1 -1
- package/static/settings/assets/{DocumentProcessingPanel-DzLZluFv.js → DocumentProcessingPanel-DvYdjT-V.js} +1 -1
- package/static/settings/assets/{IndexLifecyclePanel-Bzj1-_oI.js → IndexLifecyclePanel-W5OGQZj7.js} +1 -1
- package/static/settings/assets/{IndexSubjectPanel-B263QLUh.js → IndexSubjectPanel-g_Aa5soq.js} +1 -1
- package/static/settings/assets/{ModelAssignmentsPanel-BAdT4UR0.js → ModelAssignmentsPanel-COlMBKXj.js} +1 -1
- package/static/settings/assets/ModelsPage-mApKi-aw.js +10 -0
- package/static/settings/assets/{NetworkPage-BK6a7l4g.js → NetworkPage-BDT05JUq.js} +1 -1
- package/static/settings/assets/{PaneListHeader-BAS2ICPq.js → PaneListHeader-CByhNpMG.js} +1 -1
- package/static/settings/assets/{SearchIndexingPanel-Cb_p-NgW.js → SearchIndexingPanel-BFAyzXls.js} +1 -1
- package/static/settings/assets/{StatusSubjectPanel-CcjqUua6.js → StatusSubjectPanel-Bz_XZ3VU.js} +1 -1
- package/static/settings/assets/{StatusWorkspace-7Ibty3_k.js → StatusWorkspace-CeVypHcW.js} +1 -1
- package/static/settings/assets/{SystemSettingsPage-DPSz4dg4.js → SystemSettingsPage-Dh7cQIfx.js} +1 -1
- package/static/settings/assets/{SystemSettingsSubjectPanel-Cb4HkKT5.js → SystemSettingsSubjectPanel-CSnpciO0.js} +1 -1
- package/static/settings/assets/{activity-Qhsr5Pxu.js → activity-DXz3EfFN.js} +1 -1
- package/static/settings/assets/ai-connections-C03UWyPh.js +1 -0
- package/static/settings/assets/{badge-B1vf2qCl.js → badge-1ZA144i4.js} +1 -1
- package/static/settings/assets/{download-CYNt0aZ-.js → download-CUHimlYa.js} +1 -1
- package/static/settings/assets/{external-link-ClKb39NT.js → external-link-BYHSVj2Z.js} +1 -1
- package/static/settings/assets/{index-y8ew3MLM.js → index-DKPDMdW5.js} +1 -1
- package/static/settings/assets/{index-browser-DJhvgpNI.js → index-browser-BaEFz0e0.js} +1 -1
- package/static/settings/assets/{index-BgiIDSch.js → index-viSgSvbO.js} +1 -1
- package/static/settings/assets/{key-round-5d-DrJz-.js → key-round-COByPOg8.js} +1 -1
- package/static/settings/assets/{rotate-ccw-CHZY7kS5.js → rotate-ccw-BC2EN6cE.js} +1 -1
- package/static/settings/assets/{settings-D5VRWyx6.js → settings-DLH9XUoT.js} +86 -86
- package/static/settings/assets/settings-vPSC2d2F.css +1 -0
- package/static/settings/assets/{skeleton-FNabNxNE.js → skeleton-B0-FOhKL.js} +1 -1
- package/static/settings/assets/{waypoints-BnL_8ljo.js → waypoints-DGMsvqWo.js} +1 -1
- package/static/settings/assets/{workspace-layout-D5q3F59S.js → workspace-layout-B0SVrJIu.js} +1 -1
- package/static/settings/settings.html +2 -2
- package/static/auth-callback/assets/ModelsPage-BpkVFKbf.js +0 -10
- package/static/auth-callback/assets/ai-connections-Bm52UO7Y.js +0 -1
- package/static/auth-callback/assets/auth-callback-01yz-UDU.css +0 -1
- package/static/dashboard/assets/ModelsPage-Chd5UK0D.js +0 -25
- package/static/dashboard/assets/ai-connections-Bm52UO7Y.js +0 -1
- package/static/dashboard/assets/dashboard-01yz-UDU.css +0 -1
- package/static/settings/assets/ModelsPage-C0NFa1zq.js +0 -10
- package/static/settings/assets/ai-connections-Bm52UO7Y.js +0 -1
- package/static/settings/assets/settings-01yz-UDU.css +0 -1
|
@@ -2847,7 +2847,7 @@ class PostgresRdfEngine {
|
|
|
2847
2847
|
}
|
|
2848
2848
|
async scanNative(pattern, options, sourceScope) {
|
|
2849
2849
|
const start = Date.now();
|
|
2850
|
-
const resolved = await this.resolvePattern(pattern);
|
|
2850
|
+
const resolved = await this.resolvePattern(pattern, sourceScope);
|
|
2851
2851
|
if (resolved.unresolved) {
|
|
2852
2852
|
return {
|
|
2853
2853
|
quads: [],
|
|
@@ -5703,7 +5703,7 @@ class PostgresRdfEngine {
|
|
|
5703
5703
|
|| filter.operator === '$datatype'
|
|
5704
5704
|
|| filter.operator === '$notDatatype';
|
|
5705
5705
|
}
|
|
5706
|
-
async resolvePattern(pattern) {
|
|
5706
|
+
async resolvePattern(pattern, explicitSourceScope) {
|
|
5707
5707
|
const ids = {};
|
|
5708
5708
|
const idSets = {};
|
|
5709
5709
|
const excludedIdSets = {};
|
|
@@ -5716,6 +5716,14 @@ class PostgresRdfEngine {
|
|
|
5716
5716
|
continue;
|
|
5717
5717
|
}
|
|
5718
5718
|
if ((0, types_1.isTerm)(value)) {
|
|
5719
|
+
// An access-scoped DefaultGraph represents the logical union of Pod
|
|
5720
|
+
// source documents. Their physical facts retain named graph IDs, so
|
|
5721
|
+
// constraining graph_id to the RDF default-graph term incorrectly
|
|
5722
|
+
// turns every normal SPARQL query into an empty result.
|
|
5723
|
+
const sourceScope = explicitSourceScope ?? pattern.sourceScope;
|
|
5724
|
+
if (key === 'graph' && value.termType === 'DefaultGraph' && sourceScopeHasFilters(sourceScope)) {
|
|
5725
|
+
continue;
|
|
5726
|
+
}
|
|
5719
5727
|
const id = await this.requireDictionary().find(value);
|
|
5720
5728
|
if (id === undefined) {
|
|
5721
5729
|
return { ids, idSets, excludedIdSets, termFilters, unresolved: key };
|
|
@@ -10,6 +10,10 @@ exports.isRdfDocumentPath = isRdfDocumentPath;
|
|
|
10
10
|
exports.isRdfDocument = isRdfDocument;
|
|
11
11
|
exports.isSafeRdfDocumentContentType = isSafeRdfDocumentContentType;
|
|
12
12
|
const CONTENT_TYPE_BY_EXTENSION = {
|
|
13
|
+
// Solid ACP access-control resources use the `.acr` suffix while their
|
|
14
|
+
// representation is Turtle. Treat them as line-addressable RDF so native
|
|
15
|
+
// prepared updates can safely persist universalAccess mutations.
|
|
16
|
+
'.acr': 'text/turtle',
|
|
13
17
|
'.ttl': 'text/turtle',
|
|
14
18
|
'.jsonld': 'application/ld+json',
|
|
15
19
|
'.nt': 'application/n-triples',
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { AiClientConfigurationModel } from '@undefineds.co/extension-sdk/web';
|
|
1
2
|
export declare const AI_CONNECTIONS_CLIENTS: readonly ["codex", "claude-code", "pi", "codebuddy"];
|
|
2
3
|
export type AiConnectionsClientId = (typeof AI_CONNECTIONS_CLIENTS)[number];
|
|
3
4
|
export interface AiClientConfigurationStatus {
|
|
4
5
|
status: 'notConfigured' | 'configured' | 'drifted' | 'unavailable' | 'unverifiable' | 'failedAndRestored';
|
|
5
6
|
message?: string;
|
|
7
|
+
appliedKeyFingerprint?: string;
|
|
6
8
|
}
|
|
7
9
|
export interface AiClientConfigurationConfirmation {
|
|
8
10
|
required: boolean;
|
|
@@ -25,6 +27,7 @@ export interface AiClientConfigurationBridge {
|
|
|
25
27
|
plan(input: {
|
|
26
28
|
client: AiConnectionsClientId;
|
|
27
29
|
endpoint: string;
|
|
30
|
+
activeModels?: AiClientConfigurationModel[];
|
|
28
31
|
}): Promise<AiClientConfigurationDryRun>;
|
|
29
32
|
apply(input: {
|
|
30
33
|
client: AiConnectionsClientId;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef, useState } from 'react';
|
|
3
3
|
import { Badge, Button, Input, } from '@undefineds.co/shared-ui';
|
|
4
|
-
import {
|
|
4
|
+
import { Copy, RotateCcw, SquareTerminal } from 'lucide-react';
|
|
5
5
|
import { normalizeAiConnectionsThrownError } from './ai-connections-client.js';
|
|
6
|
+
import { getClientAvatar } from './client-visuals.js';
|
|
6
7
|
export const AI_CONNECTIONS_CLIENTS = ['codex', 'claude-code', 'pi', 'codebuddy'];
|
|
7
8
|
export const AI_CLIENT_LABELS = {
|
|
8
9
|
codex: 'Codex',
|
|
@@ -11,12 +12,11 @@ export const AI_CLIENT_LABELS = {
|
|
|
11
12
|
codebuddy: 'CodeBuddy',
|
|
12
13
|
};
|
|
13
14
|
export function AiClientIcon({ client, className = 'h-4 w-4' }) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
case 'codebuddy': return _jsx(Code2, { className: className, "aria-hidden": "true" });
|
|
18
|
-
default: return _jsx(SquareTerminal, { className: className, "aria-hidden": "true" });
|
|
15
|
+
const avatar = getClientAvatar(client);
|
|
16
|
+
if (avatar) {
|
|
17
|
+
return _jsx("img", { src: avatar, alt: "", "aria-hidden": "true", className: `${className} shrink-0 rounded-[3px] object-cover` });
|
|
19
18
|
}
|
|
19
|
+
return _jsx(SquareTerminal, { className: className, "aria-hidden": "true" });
|
|
20
20
|
}
|
|
21
21
|
export function AiClientConfigurationSection({ bridge, endpoint, client, createClientCredential, manualApiKey, autoApply = false, compact = false, onComplete, }) {
|
|
22
22
|
const [status, setStatus] = useState({ status: 'notConfigured' });
|
|
@@ -71,12 +71,9 @@ export function AiClientConfigurationSection({ bridge, endpoint, client, createC
|
|
|
71
71
|
} : {}),
|
|
72
72
|
});
|
|
73
73
|
applied = true;
|
|
74
|
-
|
|
75
|
-
setStatus(nextStatus);
|
|
74
|
+
setStatus({ status: 'configured' });
|
|
76
75
|
setDryRun(undefined);
|
|
77
|
-
|
|
78
|
-
onComplete?.();
|
|
79
|
-
}
|
|
76
|
+
onComplete?.();
|
|
80
77
|
}
|
|
81
78
|
catch (error) {
|
|
82
79
|
let recoveryMessage = errorMessage(error);
|
|
@@ -92,7 +89,7 @@ export function AiClientConfigurationSection({ bridge, endpoint, client, createC
|
|
|
92
89
|
}
|
|
93
90
|
}
|
|
94
91
|
setStatus(failedAndRestoredError(error)
|
|
95
|
-
? { status: 'failedAndRestored', message: '
|
|
92
|
+
? { status: 'failedAndRestored', message: '配置写入失败,已自动恢复原配置。' }
|
|
96
93
|
: { status: 'unavailable', message: recoveryMessage });
|
|
97
94
|
}
|
|
98
95
|
finally {
|
|
@@ -191,16 +188,16 @@ export function manualConfigurationText(client, endpoint, apiKey) {
|
|
|
191
188
|
case 'codex':
|
|
192
189
|
return [
|
|
193
190
|
'# ~/.codex/config.toml',
|
|
191
|
+
'# 将 model_provider 放在第一个配置节之前;已有同名顶层字段时替换',
|
|
194
192
|
'model_provider = "xpod"',
|
|
195
193
|
'',
|
|
196
194
|
'[model_providers.xpod]',
|
|
197
195
|
'name = "Xpod AI Connection"',
|
|
198
196
|
`base_url = ${JSON.stringify(v1Url)}`,
|
|
199
197
|
'wire_api = "responses"',
|
|
200
|
-
'requires_openai_auth =
|
|
201
|
-
|
|
202
|
-
'#
|
|
203
|
-
JSON.stringify({ OPENAI_API_KEY: secret }, null, 2),
|
|
198
|
+
'requires_openai_auth = false',
|
|
199
|
+
`experimental_bearer_token = ${JSON.stringify(secret)}`,
|
|
200
|
+
'# 保留现有订阅登录,Xpod 单独使用此 provider 的 Key',
|
|
204
201
|
].join('\n');
|
|
205
202
|
case 'claude-code':
|
|
206
203
|
return [
|
|
@@ -18,9 +18,7 @@ export function AiConnectionsList({ controller }) {
|
|
|
18
18
|
if (provider.id !== 'custom')
|
|
19
19
|
return [...items, { ...provider }];
|
|
20
20
|
const credentials = providerProducts.custom?.credentials ?? [];
|
|
21
|
-
return [...items, ...
|
|
22
|
-
? credentials.map((credential) => ({ ...provider, name: credential.label || provider.name, credentialId: credential.id }))
|
|
23
|
-
: [{ ...provider }])];
|
|
21
|
+
return [...items, ...credentials.map((credential) => ({ ...provider, name: credential.label || provider.name, credentialId: credential.id }))];
|
|
24
22
|
}, []);
|
|
25
23
|
const providers = searchQuery
|
|
26
24
|
? providerItems.filter((provider) => providerDisplayName(provider, providerProducts).toLocaleLowerCase().includes(searchQuery))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type AiConnectionsController } from './controller';
|
|
2
|
-
export declare function AiConnectionsMain({ controller }: {
|
|
2
|
+
export declare function AiConnectionsMain({ controller, renderToaster }: {
|
|
3
3
|
controller: AiConnectionsController;
|
|
4
|
+
renderToaster?: boolean;
|
|
4
5
|
}): import("react").JSX.Element;
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { AI_CONNECTIONS_PINNED_SECTIONS, PROVIDERS, useProviderLoadError, useProviderProducts, useProviderSummaries, useSelectedCredentialId, useSelectedProvider, useSelectedSection, } from './controller.js';
|
|
3
3
|
import { AiConnectionsPanel } from './AiConnectionsPanel.js';
|
|
4
4
|
import { useEffect } from 'react';
|
|
5
|
-
export function AiConnectionsMain({ controller }) {
|
|
5
|
+
export function AiConnectionsMain({ controller, renderToaster = true }) {
|
|
6
6
|
const selectedSection = useSelectedSection(controller);
|
|
7
7
|
const selectedProvider = useSelectedProvider(controller);
|
|
8
8
|
const selectedCredentialId = useSelectedCredentialId(controller);
|
|
@@ -35,7 +35,7 @@ export function AiConnectionsMain({ controller }) {
|
|
|
35
35
|
if (!controller.client) {
|
|
36
36
|
return (_jsxs("section", { role: "alert", "aria-label": "AI Connections unavailable", children: [_jsx("h2", { children: "AI Connections \u5C1A\u672A\u5C31\u7EEA" }), _jsx("p", { children: "\u5BBF\u4E3B\u9700\u8981\u5148\u63D0\u4F9B\u5DF2\u767B\u5F55\u7684 WebID \u548C\u53EF\u7528\u7684 Pod\u3002" })] }));
|
|
37
37
|
}
|
|
38
|
-
return (_jsx("section", { role: "region", "aria-label": regionLabel, children: _jsx(AiConnectionsPanel, { client: controller.client, clientConfigurationBridge: controller.clientConfigurationBridge, selectedSection: selectedSection, selectedProvider: selectedProvider, selectedCredentialId: selectedCredentialId, openExternal: controller.openExternal, providerSummaries: providerSummaries, providerProducts: scopedProducts, providerLoadError: providerLoadError, onProviderStateChange: controller.setProviderState }) }));
|
|
38
|
+
return (_jsx("section", { role: "region", "aria-label": regionLabel, children: _jsx(AiConnectionsPanel, { client: controller.client, renderToaster: renderToaster, clientConfigurationBridge: controller.clientConfigurationBridge, selectedSection: selectedSection, selectedProvider: selectedProvider, selectedCredentialId: selectedCredentialId, openExternal: controller.openExternal, providerSummaries: providerSummaries, providerProducts: scopedProducts, providerLoadError: providerLoadError, providerLoading: !providerProducts[selectedProvider] && !providerLoadError, onProviderStateChange: controller.setProviderState }) }));
|
|
39
39
|
}
|
|
40
40
|
function scopedCustomOfferings(product, credential) {
|
|
41
41
|
if (!credential)
|
|
@@ -3,6 +3,8 @@ import { type AiConnectionsWorkspaceSection, type ProviderProductState } from '.
|
|
|
3
3
|
import type { AiClientConfigurationBridge } from './AiClientConfigurationSection';
|
|
4
4
|
export interface AiConnectionsPanelProps {
|
|
5
5
|
client: AiConnectionsClient;
|
|
6
|
+
/** Disable when the embedding application already renders shared-ui Toaster. */
|
|
7
|
+
renderToaster?: boolean;
|
|
6
8
|
openExternal?: (url: string) => void | Promise<void>;
|
|
7
9
|
clientConfigurationBridge?: AiClientConfigurationBridge;
|
|
8
10
|
selectedSection?: AiConnectionsWorkspaceSection;
|
|
@@ -11,7 +13,8 @@ export interface AiConnectionsPanelProps {
|
|
|
11
13
|
providerSummaries?: Partial<Record<AiConnectionsProvider, AiProviderConnectionSummary>>;
|
|
12
14
|
providerProducts?: Partial<Record<AiConnectionsProvider, AiProviderSummary>>;
|
|
13
15
|
providerLoadError?: string;
|
|
16
|
+
providerLoading?: boolean;
|
|
14
17
|
onProviderStateChange?: (provider: AiConnectionsProvider, state: ProviderProductState) => void;
|
|
15
18
|
onModelSelectionChange?: (provider: AiConnectionsProvider, modelIds: string[]) => void;
|
|
16
19
|
}
|
|
17
|
-
export declare function AiConnectionsPanel({ client, openExternal, clientConfigurationBridge, selectedSection, selectedProvider, selectedCredentialId, providerSummaries: providerSummariesInput, providerProducts, providerLoadError, onProviderStateChange, onModelSelectionChange, }: AiConnectionsPanelProps): import("react").JSX.Element;
|
|
20
|
+
export declare function AiConnectionsPanel({ client, renderToaster, openExternal, clientConfigurationBridge, selectedSection, selectedProvider, selectedCredentialId, providerSummaries: providerSummariesInput, providerProducts, providerLoadError, providerLoading, onProviderStateChange, onModelSelectionChange, }: AiConnectionsPanelProps): import("react").JSX.Element;
|
|
@@ -3,14 +3,18 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|
|
3
3
|
import { Toaster, toast, } from '@undefineds.co/shared-ui';
|
|
4
4
|
import { normalizeAiConnectionsThrownError, } from './ai-connections-client.js';
|
|
5
5
|
import { PROVIDERS, } from './controller.js';
|
|
6
|
+
import { offeringTitle } from './offering-label.js';
|
|
6
7
|
import { AiProviderCard, } from './AiProviderCard.js';
|
|
7
8
|
import { AiModelEditorDialog, } from './AiModelEditorDialog.js';
|
|
8
9
|
import { AiGatewayKeysSection } from './AiGatewayKeysSection.js';
|
|
9
10
|
const EMPTY_PROVIDER_SUMMARIES = {};
|
|
10
|
-
export function AiConnectionsPanel({ client, openExternal = openExternalUrl, clientConfigurationBridge, selectedSection = 'provider', selectedProvider, selectedCredentialId, providerSummaries: providerSummariesInput = EMPTY_PROVIDER_SUMMARIES, providerProducts = {}, providerLoadError, onProviderStateChange, onModelSelectionChange, }) {
|
|
11
|
+
export function AiConnectionsPanel({ client, renderToaster = true, openExternal = openExternalUrl, clientConfigurationBridge, selectedSection = 'provider', selectedProvider, selectedCredentialId, providerSummaries: providerSummariesInput = EMPTY_PROVIDER_SUMMARIES, providerProducts = {}, providerLoadError, providerLoading = false, onProviderStateChange, onModelSelectionChange, }) {
|
|
11
12
|
const [connectionStates, setConnectionStates] = useState({});
|
|
12
13
|
const [models, setModels] = useState([]);
|
|
14
|
+
const [gatewayModels, setGatewayModels] = useState();
|
|
15
|
+
const [gatewayCatalogVersion, setGatewayCatalogVersion] = useState(0);
|
|
13
16
|
const [selectedModelIds, setSelectedModelIds] = useState({});
|
|
17
|
+
const [modelSelectionStatus, setModelSelectionStatus] = useState({});
|
|
14
18
|
const [attempts, setAttempts] = useState({});
|
|
15
19
|
const [attemptOfferingIds, setAttemptOfferingIds] = useState({});
|
|
16
20
|
const [apiKeyInputs, setApiKeyInputs] = useState({});
|
|
@@ -77,13 +81,23 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
77
81
|
pollingGeneration.current += 1;
|
|
78
82
|
};
|
|
79
83
|
}, [client]);
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
let active = true;
|
|
86
|
+
setGatewayModels(undefined);
|
|
87
|
+
// Load the routing projection independently: the host's listModels may be a Pod catalog.
|
|
88
|
+
void client.listGatewayModels?.()
|
|
89
|
+
.then((availableModels) => { if (active)
|
|
90
|
+
setGatewayModels(availableModels); })
|
|
91
|
+
.catch(() => undefined);
|
|
92
|
+
return () => { active = false; };
|
|
93
|
+
}, [client, gatewayCatalogVersion]);
|
|
80
94
|
const setBusy = (provider, value) => {
|
|
81
95
|
setBusyProviders((current) => ({ ...current, [provider]: value }));
|
|
82
96
|
};
|
|
83
|
-
const setProviderError = (provider, value, offeringId) => {
|
|
97
|
+
const setProviderError = (provider, value, offeringId, authorization) => {
|
|
84
98
|
setProviderErrors((current) => ({
|
|
85
99
|
...current,
|
|
86
|
-
[provider]: value ? { message: value, offeringId } : undefined,
|
|
100
|
+
[provider]: value ? { message: value, offeringId, authorization } : undefined,
|
|
87
101
|
}));
|
|
88
102
|
};
|
|
89
103
|
const openAttemptUrl = useCallback(async (attempt) => {
|
|
@@ -125,14 +139,14 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
125
139
|
}
|
|
126
140
|
await beginConnectMode(definition.id, definition.browserMode);
|
|
127
141
|
};
|
|
128
|
-
const beginOfferingConnect = async (provider, offering, mode) => {
|
|
142
|
+
const beginOfferingConnect = async (provider, offering, mode, method) => {
|
|
129
143
|
if (mode === 'browserAssistedApiKey') {
|
|
130
144
|
await beginApiKey(provider);
|
|
131
145
|
return;
|
|
132
146
|
}
|
|
133
|
-
await beginConnectMode(provider, mode, offering.id);
|
|
147
|
+
await beginConnectMode(provider, mode, offering.id, method?.id);
|
|
134
148
|
};
|
|
135
|
-
const beginConnectMode = async (provider, mode, offeringId) => {
|
|
149
|
+
const beginConnectMode = async (provider, mode, offeringId, authorizationMethodId) => {
|
|
136
150
|
if (mode === 'connectUnsupported')
|
|
137
151
|
return;
|
|
138
152
|
setBusy(provider, true);
|
|
@@ -141,15 +155,18 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
141
155
|
const generation = pollingGeneration.current + 1;
|
|
142
156
|
pollingGeneration.current = generation;
|
|
143
157
|
try {
|
|
144
|
-
const attempt = await client.beginConnect(provider, mode);
|
|
158
|
+
const attempt = await client.beginConnect(provider, mode, { offeringId, authorizationMethodId });
|
|
145
159
|
setAttempts((current) => ({ ...current, [provider]: attempt }));
|
|
146
160
|
if (!isPendingAttempt(attempt.status)) {
|
|
147
161
|
const connected = attempt.status === 'completed';
|
|
148
|
-
|
|
162
|
+
if (connected)
|
|
163
|
+
await completeOAuthConnect(provider);
|
|
164
|
+
else
|
|
165
|
+
updateConnectionState(provider, 'failed');
|
|
149
166
|
if (!connected) {
|
|
150
167
|
setProviderError(provider, attempt.status === 'unsupported'
|
|
151
168
|
? '当前部署未启用账号授权'
|
|
152
|
-
: attempt.message ?? connectFailureMessage(attempt.status), offeringId);
|
|
169
|
+
: attempt.message ?? connectFailureMessage(attempt.status), offeringId, { mode, authorizationMethodId });
|
|
153
170
|
}
|
|
154
171
|
setBusy(provider, false);
|
|
155
172
|
return;
|
|
@@ -158,20 +175,47 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
158
175
|
await openAttemptUrl(attempt);
|
|
159
176
|
void pollDeviceConnect(client, provider, attempt, generation, pollingGeneration, {
|
|
160
177
|
onAttempt: (next) => setAttempts((current) => ({ ...current, [provider]: next })),
|
|
161
|
-
onConnected: () =>
|
|
178
|
+
onConnected: () => completeOAuthConnect(provider),
|
|
162
179
|
onFailed: (message) => {
|
|
163
180
|
updateConnectionState(provider, 'failed');
|
|
164
|
-
setProviderError(provider, message, offeringId);
|
|
181
|
+
setProviderError(provider, message, offeringId, { mode, authorizationMethodId });
|
|
165
182
|
},
|
|
166
183
|
onFinished: () => setBusy(provider, false),
|
|
167
184
|
});
|
|
168
185
|
}
|
|
169
186
|
catch (error) {
|
|
170
187
|
updateConnectionState(provider, 'failed');
|
|
171
|
-
setProviderError(provider, errorMessage(error), offeringId);
|
|
188
|
+
setProviderError(provider, errorMessage(error), offeringId, { mode, authorizationMethodId });
|
|
172
189
|
setBusy(provider, false);
|
|
173
190
|
}
|
|
174
191
|
};
|
|
192
|
+
const completeOAuthConnect = async (provider) => {
|
|
193
|
+
// Poll completion has already persisted the OAuth credential in the Pod.
|
|
194
|
+
updateConnectionState(provider, 'connected');
|
|
195
|
+
try {
|
|
196
|
+
const product = (await client.listProviders()).find((item) => item.id === provider);
|
|
197
|
+
if (product) {
|
|
198
|
+
setProviderProductOverrides((current) => ({ ...current, [provider]: product }));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
setProviderError(provider, `账号已连接,连接信息刷新失败:${errorMessage(error)}`);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const cancelConnect = async (provider, attempt) => {
|
|
206
|
+
pollingGeneration.current += 1;
|
|
207
|
+
setBusy(provider, false);
|
|
208
|
+
setAttempts((current) => ({ ...current, [provider]: undefined }));
|
|
209
|
+
setAttemptOfferingIds((current) => ({ ...current, [provider]: undefined }));
|
|
210
|
+
updateConnectionState(provider, 'failed');
|
|
211
|
+
try {
|
|
212
|
+
await client.cancelConnect?.(provider, attempt);
|
|
213
|
+
setProviderError(provider, '连接已取消');
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
setProviderError(provider, errorMessage(error));
|
|
217
|
+
}
|
|
218
|
+
};
|
|
175
219
|
const saveApiKey = async (definition) => {
|
|
176
220
|
const apiKey = apiKeyInputs[definition.id]?.trim();
|
|
177
221
|
const baseUrl = baseUrlInputs[definition.id]
|
|
@@ -241,15 +285,19 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
241
285
|
? 'configured'
|
|
242
286
|
: 'connected');
|
|
243
287
|
};
|
|
244
|
-
const syncProviderModels = async (provider, input, announceSuccess = false) => {
|
|
288
|
+
const syncProviderModels = async (provider, input, announceSuccess = false, failurePrefix = '') => {
|
|
245
289
|
setVerifyingProviders((current) => ({ ...current, [provider]: true }));
|
|
246
290
|
setProviderError(provider);
|
|
247
291
|
try {
|
|
248
292
|
const discovery = input
|
|
249
293
|
? await client.discoverModels(provider, input)
|
|
250
294
|
: await client.discoverModels(provider);
|
|
295
|
+
setGatewayCatalogVersion((version) => version + 1);
|
|
251
296
|
const selectedModels = effectiveProviderProducts[provider]?.selectedModels ?? [];
|
|
252
|
-
const mergeScope =
|
|
297
|
+
const mergeScope = {
|
|
298
|
+
...modelDiscoveryMergeScope(provider, input),
|
|
299
|
+
...(discovery.complete === false ? { markMissing: false } : {}),
|
|
300
|
+
};
|
|
253
301
|
try {
|
|
254
302
|
const persisted = await client.listModels();
|
|
255
303
|
const persistedForProvider = persisted
|
|
@@ -277,7 +325,10 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
277
325
|
// The model catalog already reflects the discovery result; provider
|
|
278
326
|
// summaries will refresh on the next host/provider reload.
|
|
279
327
|
}
|
|
280
|
-
if (
|
|
328
|
+
if (discovery.complete === false) {
|
|
329
|
+
setProviderError(provider, '部分连接同步失败,已保留原有模型目录,可稍后重试。', input?.offeringId);
|
|
330
|
+
}
|
|
331
|
+
else if (announceSuccess) {
|
|
281
332
|
toast({
|
|
282
333
|
variant: discovery.models.length > 0 ? 'success' : 'default',
|
|
283
334
|
description: discovery.models.length > 0
|
|
@@ -289,7 +340,7 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
289
340
|
}
|
|
290
341
|
catch (error) {
|
|
291
342
|
const message = errorMessage(error);
|
|
292
|
-
setProviderError(provider, message
|
|
343
|
+
setProviderError(provider, `${failurePrefix}${message}`, input?.offeringId);
|
|
293
344
|
return false;
|
|
294
345
|
}
|
|
295
346
|
finally {
|
|
@@ -324,24 +375,25 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
324
375
|
setBusy(provider, false);
|
|
325
376
|
}
|
|
326
377
|
};
|
|
327
|
-
const createLocalCredential = async (provider, offering) => {
|
|
378
|
+
const createLocalCredential = async (provider, offering, method) => {
|
|
328
379
|
setBusy(provider, true);
|
|
329
380
|
setProviderError(provider);
|
|
330
381
|
try {
|
|
331
|
-
const
|
|
382
|
+
const localService = offering.kind === 'local';
|
|
332
383
|
const credential = await client.createLocalCredential(provider, {
|
|
333
384
|
offeringId: offering.id,
|
|
334
|
-
|
|
335
|
-
|
|
385
|
+
authorizationMethodId: method?.id,
|
|
386
|
+
label: offering.label ?? offeringTitle(offering),
|
|
387
|
+
...(localService ? { baseUrl: offering.endpoints?.[0]?.baseUrl } : {}),
|
|
336
388
|
priority: 10,
|
|
337
389
|
});
|
|
338
390
|
mergeProviderCredential(provider, credential);
|
|
339
|
-
toast({ description:
|
|
391
|
+
toast({ description: `${offeringTitle(offering)} 已连接` });
|
|
340
392
|
if (offering.modelDiscovery?.strategy !== 'unsupported') {
|
|
341
393
|
await syncProviderModels(provider, {
|
|
342
394
|
offeringId: credential.offeringId,
|
|
343
395
|
credentialId: credential.id,
|
|
344
|
-
});
|
|
396
|
+
}, false, localService ? '本地服务已连接,模型获取失败:' : '订阅已读取,模型获取失败:');
|
|
345
397
|
}
|
|
346
398
|
}
|
|
347
399
|
catch (error) {
|
|
@@ -380,14 +432,25 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
380
432
|
}
|
|
381
433
|
};
|
|
382
434
|
const deleteProviderCredential = async (provider, credential) => {
|
|
435
|
+
// Legacy connection summaries use a synthetic id, not a Pod credential id.
|
|
436
|
+
if (credential.id === `${provider}:current` && credential.version === 0) {
|
|
437
|
+
if (effectiveProviderProducts[provider]?.credentials.some((item) => item.id !== credential.id)) {
|
|
438
|
+
setProviderError(provider, '请重新加载连接后再移除旧连接。', credential.offeringId);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
await disconnect(provider);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
383
444
|
setBusy(provider, true);
|
|
384
445
|
setProviderError(provider);
|
|
385
446
|
try {
|
|
386
447
|
await client.deleteProviderCredential(provider, credential.id);
|
|
448
|
+
const product = providerProductWithoutCredential(effectiveProviderProducts[provider], provider, credential.id);
|
|
387
449
|
setProviderProductOverrides((current) => ({
|
|
388
450
|
...current,
|
|
389
|
-
[provider]:
|
|
451
|
+
[provider]: product,
|
|
390
452
|
}));
|
|
453
|
+
updateConnectionState(provider, connectionStateFromProduct(product));
|
|
391
454
|
toast({ description: '凭证已删除' });
|
|
392
455
|
}
|
|
393
456
|
catch (error) {
|
|
@@ -460,34 +523,36 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
460
523
|
setBusy(provider, false);
|
|
461
524
|
}
|
|
462
525
|
};
|
|
526
|
+
const quotaRequests = useRef(new Set());
|
|
463
527
|
const refreshQuota = async (provider, offering, credential) => {
|
|
464
|
-
const
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
},
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
528
|
+
const credentials = credential ? [credential] : (effectiveProviderProducts[provider]?.credentials ?? []).filter((item) => item.enabled && item.offeringId === offering.id);
|
|
529
|
+
await Promise.all(credentials.map(async (item) => {
|
|
530
|
+
const requestKey = `${provider}\0${item.id}`;
|
|
531
|
+
if (quotaRequests.current.has(requestKey))
|
|
532
|
+
return;
|
|
533
|
+
quotaRequests.current.add(requestKey);
|
|
534
|
+
const setQuotaState = (patch) => {
|
|
535
|
+
setQuotas((current) => ({
|
|
536
|
+
...current,
|
|
537
|
+
[provider]: { ...current[provider], [item.id]: patch },
|
|
538
|
+
}));
|
|
539
|
+
};
|
|
540
|
+
setQuotaState({ busy: true, credentialId: item.id });
|
|
541
|
+
try {
|
|
542
|
+
const quota = await client.quota(provider, true, {
|
|
543
|
+
offeringId: offering.id,
|
|
544
|
+
credentialId: item.id,
|
|
545
|
+
credentialIri: item.id,
|
|
546
|
+
});
|
|
547
|
+
setQuotaState({ quota, busy: false, credentialId: item.id });
|
|
548
|
+
}
|
|
549
|
+
catch (error) {
|
|
550
|
+
setQuotaState({ busy: false, error: errorMessage(error), credentialId: item.id });
|
|
551
|
+
}
|
|
552
|
+
finally {
|
|
553
|
+
quotaRequests.current.delete(requestKey);
|
|
554
|
+
}
|
|
555
|
+
}));
|
|
491
556
|
};
|
|
492
557
|
const verifyProvider = async (provider) => {
|
|
493
558
|
await syncProviderModels(provider, provider === 'custom' && selectedCredentialId
|
|
@@ -495,6 +560,7 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
495
560
|
: undefined, true);
|
|
496
561
|
};
|
|
497
562
|
const reloadModels = useCallback(async () => {
|
|
563
|
+
setGatewayCatalogVersion((version) => version + 1);
|
|
498
564
|
try {
|
|
499
565
|
setModels(await client.listModels());
|
|
500
566
|
}
|
|
@@ -550,6 +616,7 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
550
616
|
const generation = (modelSelectionGeneration.current[provider] ?? 0) + 1;
|
|
551
617
|
modelSelectionGeneration.current[provider] = generation;
|
|
552
618
|
setSelectedModelIds((current) => ({ ...current, [provider]: ids }));
|
|
619
|
+
setModelSelectionStatus((current) => ({ ...current, [provider]: 'saving' }));
|
|
553
620
|
void (async () => {
|
|
554
621
|
try {
|
|
555
622
|
const candidates = [
|
|
@@ -569,12 +636,15 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
569
636
|
await client.saveModelSelection?.(provider, selections);
|
|
570
637
|
}
|
|
571
638
|
if (modelSelectionGeneration.current[provider] === generation) {
|
|
639
|
+
setGatewayCatalogVersion((version) => version + 1);
|
|
640
|
+
setModelSelectionStatus((current) => ({ ...current, [provider]: 'saved' }));
|
|
572
641
|
onModelSelectionChange?.(provider, ids);
|
|
573
642
|
}
|
|
574
643
|
}
|
|
575
644
|
catch (error) {
|
|
576
645
|
if (modelSelectionGeneration.current[provider] !== generation)
|
|
577
646
|
return;
|
|
647
|
+
setModelSelectionStatus((current) => ({ ...current, [provider]: 'error' }));
|
|
578
648
|
setSelectedModelIds((current) => ({ ...current, [provider]: previousIds }));
|
|
579
649
|
onModelSelectionChange?.(provider, previousIds);
|
|
580
650
|
toast({ variant: 'destructive', description: errorMessage(error) });
|
|
@@ -588,16 +658,16 @@ export function AiConnectionsPanel({ client, openExternal = openExternalUrl, cli
|
|
|
588
658
|
const providerSelectedModelIds = selectedModelIds[definition.id]
|
|
589
659
|
?? providerProduct?.selectedModels.map(modelSelectionId)
|
|
590
660
|
?? [];
|
|
591
|
-
return (_jsx(AiProviderCard, { definition: definition, product: providerProduct, status: resolvedConnectionState(connectionStates[definition.id], providerProduct), accountLabel: providerSummariesInput[definition.id]?.accountLabel, attempt: attempts[definition.id], attemptOfferingId: attemptOfferingIds[definition.id], apiKey: apiKeyInputs[definition.id] ?? '', baseUrl: baseUrlInputs[definition.id] ?? providerSummariesInput[definition.id]?.baseUrl ?? '', busy: Boolean(busyProviders[definition.id]), error: providerErrors[definition.id], quotas: quotas[definition.id], models: providerModels, selectedModelIds: providerSelectedModelIds, onApiKeyChange: (value) => setApiKeyInputs((current) => ({
|
|
661
|
+
return (_jsx(AiProviderCard, { definition: definition, product: providerProduct, status: resolvedConnectionState(connectionStates[definition.id], providerProduct), accountLabel: providerSummariesInput[definition.id]?.accountLabel, attempt: attempts[definition.id], attemptOfferingId: attemptOfferingIds[definition.id], apiKey: apiKeyInputs[definition.id] ?? '', baseUrl: baseUrlInputs[definition.id] ?? providerSummariesInput[definition.id]?.baseUrl ?? '', busy: Boolean(busyProviders[definition.id] || verifyingProviders[definition.id]), disabled: providerLoading, error: providerErrors[definition.id], quotas: quotas[definition.id], models: providerModels, selectedModelIds: providerSelectedModelIds, modelSelectionStatus: modelSelectionStatus[definition.id], onApiKeyChange: (value) => setApiKeyInputs((current) => ({
|
|
592
662
|
...current,
|
|
593
663
|
[definition.id]: value,
|
|
594
664
|
})), onBaseUrlChange: (value) => setBaseUrlInputs((current) => ({
|
|
595
665
|
...current,
|
|
596
666
|
[definition.id]: value,
|
|
597
|
-
})), onBeginApiKey: () => void beginApiKey(definition.id), onBeginOffering: (offering, mode) => void beginOfferingConnect(definition.id, offering, mode), onBeginBrowser: () => void beginBrowserConnect(definition), onSaveApiKey: () => void saveApiKey(definition), onDisconnect: (credential) => void disconnect(definition.id, credential?.id), onCreateApiKeyCredential: (offering, input) => createApiKeyCredential(definition.id, offering, input), onCreateLocalCredential: (offering) => createLocalCredential(definition.id, offering), onUpdateCredential: (credential, patch) => updateProviderCredential(definition.id, credential, patch), onDeleteCredential: (credential) => void deleteProviderCredential(definition.id, credential), onTestCredential: (credential) => void testProviderCredential(definition.id, credential), onReorderCredentials: (offering, credentials, fromIndex, toIndex) => void reorderProviderCredentials(definition.id, offering, credentials, fromIndex, toIndex), onRefreshQuota: (offering, credential) => void refreshQuota(definition.id, offering, credential), verifyPending: Boolean(verifyingProviders[definition.id]), onVerify: () => void verifyProvider(definition.id), onAddModel: () => openModelEditor(definition.id), onEditModel: (model) => openModelEditor(definition.id, model), onDeleteModel: (model) => void deleteProviderModel(definition.id, model), onModelSelectionChange: handleModelSelectionChange, onDismissError: () => setProviderError(definition.id) }, definition.id));
|
|
667
|
+
})), onBeginApiKey: () => void beginApiKey(definition.id), onBeginOffering: (offering, mode, method) => void beginOfferingConnect(definition.id, offering, mode, method), onCancelConnect: (attempt) => void cancelConnect(definition.id, attempt), onBeginBrowser: () => void beginBrowserConnect(definition), onSaveApiKey: () => void saveApiKey(definition), onDisconnect: (credential) => void disconnect(definition.id, credential?.id), onCreateApiKeyCredential: (offering, input) => createApiKeyCredential(definition.id, offering, input), onCreateLocalCredential: (offering, method) => createLocalCredential(definition.id, offering, method), onUpdateCredential: (credential, patch) => updateProviderCredential(definition.id, credential, patch), onDeleteCredential: (credential) => void deleteProviderCredential(definition.id, credential), onTestCredential: (credential) => void testProviderCredential(definition.id, credential), onReorderCredentials: (offering, credentials, fromIndex, toIndex) => void reorderProviderCredentials(definition.id, offering, credentials, fromIndex, toIndex), onRefreshQuota: (offering, credential) => void refreshQuota(definition.id, offering, credential), verifyPending: Boolean(verifyingProviders[definition.id]), onVerify: () => void verifyProvider(definition.id), onAddModel: () => openModelEditor(definition.id), onEditModel: (model) => openModelEditor(definition.id, model), onDeleteModel: (model) => void deleteProviderModel(definition.id, model), onModelSelectionChange: handleModelSelectionChange, onDismissError: () => setProviderError(definition.id) }, definition.id));
|
|
598
668
|
})] }));
|
|
599
|
-
const keyContent = (_jsx(AiGatewayKeysSection, { client: client, clientConfigurationBridge: clientConfigurationBridge }));
|
|
600
|
-
return (_jsxs("div", { "data-testid": "ai-connections-panel", className: "mx-auto w-full max-w-5xl space-y-10 px-4 py-6 sm:px-8 sm:py-8", children: [_jsx(Toaster, {}), selectedSection === 'keys' ? keyContent : null, selectedSection === 'provider' ? providerContent : null, selectedSection === 'provider' && modelEditor ? (_jsx(AiModelEditorDialog, { open: true, providerName: PROVIDERS.find((definition) => definition.id === modelEditor.provider)?.name ?? modelEditor.provider, initialValue: modelEditor.model
|
|
669
|
+
const keyContent = (_jsx(AiGatewayKeysSection, { client: client, clientConfigurationBridge: clientConfigurationBridge, gatewayModels: gatewayModels }));
|
|
670
|
+
return (_jsxs("div", { "data-testid": "ai-connections-panel", className: "mx-auto w-full max-w-5xl space-y-10 px-4 py-6 sm:px-8 sm:py-8", children: [renderToaster ? _jsx(Toaster, {}) : null, selectedSection === 'keys' ? keyContent : null, selectedSection === 'provider' ? providerContent : null, selectedSection === 'provider' && modelEditor ? (_jsx(AiModelEditorDialog, { open: true, providerName: PROVIDERS.find((definition) => definition.id === modelEditor.provider)?.name ?? modelEditor.provider, initialValue: modelEditor.model
|
|
601
671
|
? {
|
|
602
672
|
id: modelEditor.model.id,
|
|
603
673
|
name: modelEditor.model.displayName ?? '',
|
|
@@ -635,11 +705,11 @@ async function pollDeviceConnect(client, provider, initial, generation, generati
|
|
|
635
705
|
await delay(Math.max(1, attempt.intervalSeconds ?? 2) * 1000);
|
|
636
706
|
if (generationRef.current !== generation)
|
|
637
707
|
return;
|
|
638
|
-
attempt = await client.pollDevice(provider, attempt);
|
|
708
|
+
attempt = { ...attempt, ...await client.pollDevice(provider, attempt) };
|
|
639
709
|
callbacks.onAttempt(attempt);
|
|
640
710
|
}
|
|
641
711
|
if (attempt.status === 'completed') {
|
|
642
|
-
callbacks.onConnected();
|
|
712
|
+
await callbacks.onConnected();
|
|
643
713
|
}
|
|
644
714
|
else if (generationRef.current === generation) {
|
|
645
715
|
callbacks.onFailed(attempt.message || `连接${attempt.status === 'expired' ? '已过期' : '失败'}`);
|
|
@@ -741,7 +811,7 @@ function providerProductWithCredentialList(product, provider, offering, updatedC
|
|
|
741
811
|
? base.offerings
|
|
742
812
|
: [...base.offerings, offering],
|
|
743
813
|
credentials: sortCredentialsByPriority([
|
|
744
|
-
...base.credentials.filter((credential) =>
|
|
814
|
+
...base.credentials.filter((credential) => !updatedIds.has(credential.id)),
|
|
745
815
|
...updatedCredentials,
|
|
746
816
|
]),
|
|
747
817
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { AiConnectAttempt, AiConnectionsMode, AiProviderCredentialSummary, AiProviderOffering, AiProviderSummary, AiQuotaSnapshot } from './ai-connections-client';
|
|
1
|
+
import type { AiConnectAttempt, AiConnectionsMode, AiProviderAuthorizationMethod, AiProviderCredentialSummary, AiProviderOffering, AiProviderSummary, AiQuotaSnapshot } from './ai-connections-client';
|
|
2
2
|
import type { AiProviderDefinition } from './controller';
|
|
3
3
|
import type { ProviderConnectionState } from './AiProviderCard';
|
|
4
4
|
export interface AiOfferingActionError {
|
|
5
5
|
message: string;
|
|
6
6
|
offeringId?: string;
|
|
7
|
+
authorization?: Pick<AiConnectAttempt, 'mode' | 'authorizationMethodId'>;
|
|
7
8
|
}
|
|
8
9
|
export interface AiOfferingQuotaState {
|
|
9
10
|
quota?: AiQuotaSnapshot;
|
|
@@ -11,7 +12,7 @@ export interface AiOfferingQuotaState {
|
|
|
11
12
|
error?: string;
|
|
12
13
|
credentialId?: string;
|
|
13
14
|
}
|
|
14
|
-
export declare function AiCredentialPoolSection({ definition, product, status, accountLabel, attempt, attemptOfferingId, apiKey, baseUrl, busy, disabled, error, suppressError, quotas, onApiKeyChange, onBaseUrlChange, onBeginApiKey, onBeginOffering, onBeginBrowser, onSaveApiKey, onDisconnect, onCreateApiKeyCredential, onCreateLocalCredential, onUpdateCredential, onDeleteCredential, onTestCredential, onReorderCredentials, onRefreshQuota, onDismissError, }: {
|
|
15
|
+
export declare function AiCredentialPoolSection({ definition, product, status, accountLabel, attempt, attemptOfferingId, apiKey, baseUrl, busy, disabled, error, suppressError, quotas, onApiKeyChange, onBaseUrlChange, onBeginApiKey, onBeginOffering, onCancelConnect, onBeginBrowser, onSaveApiKey, onDisconnect, onCreateApiKeyCredential, onCreateLocalCredential, onUpdateCredential, onDeleteCredential, onTestCredential, onReorderCredentials, onRefreshQuota, onDismissError, }: {
|
|
15
16
|
definition: AiProviderDefinition;
|
|
16
17
|
product?: AiProviderSummary;
|
|
17
18
|
status: ProviderConnectionState;
|
|
@@ -28,7 +29,8 @@ export declare function AiCredentialPoolSection({ definition, product, status, a
|
|
|
28
29
|
onApiKeyChange: (value: string) => void;
|
|
29
30
|
onBaseUrlChange?: (value: string) => void;
|
|
30
31
|
onBeginApiKey: () => void;
|
|
31
|
-
onBeginOffering?: (offering: AiProviderOffering, mode: AiConnectionsMode) => void;
|
|
32
|
+
onBeginOffering?: (offering: AiProviderOffering, mode: AiConnectionsMode, method?: AiProviderAuthorizationMethod) => void;
|
|
33
|
+
onCancelConnect?: (attempt: Pick<AiConnectAttempt, 'attemptId' | 'state' | 'signature' | 'offeringId'> & Partial<Pick<AiConnectAttempt, 'mode'>>) => void;
|
|
32
34
|
onBeginBrowser: () => void;
|
|
33
35
|
onSaveApiKey: () => void;
|
|
34
36
|
onDisconnect: (credential?: AiProviderCredentialSummary) => void;
|
|
@@ -39,7 +41,7 @@ export declare function AiCredentialPoolSection({ definition, product, status, a
|
|
|
39
41
|
proxyUrl?: string;
|
|
40
42
|
priority: number;
|
|
41
43
|
}) => Promise<void>;
|
|
42
|
-
onCreateLocalCredential?: (offering: AiProviderOffering) => Promise<void>;
|
|
44
|
+
onCreateLocalCredential?: (offering: AiProviderOffering, method?: AiProviderAuthorizationMethod) => Promise<void>;
|
|
43
45
|
onUpdateCredential?: (credential: AiProviderCredentialSummary, patch: {
|
|
44
46
|
label?: string;
|
|
45
47
|
enabled?: boolean;
|