@undefineds.co/xpod 0.4.10 → 0.4.12
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/components-ignore.json +5 -1
- package/config/notifications.json +68 -0
- package/config/xpod.base.json +9 -11
- package/dist/ai/service/AiCredentialSecret.d.ts +30 -0
- package/dist/ai/service/AiCredentialSecret.js +120 -0
- package/dist/ai/service/CredentialReaderImpl.d.ts +18 -0
- package/dist/ai/service/CredentialReaderImpl.js +81 -5
- package/dist/ai/service/CredentialReaderImpl.jsonld +42 -2
- package/dist/ai/service/EmbeddingModelPolicy.d.ts +79 -0
- package/dist/ai/service/EmbeddingModelPolicy.js +134 -0
- package/dist/ai/service/EmbeddingProviderError.js +6 -0
- package/dist/ai/service/EmbeddingServiceImpl.d.ts +13 -1
- package/dist/ai/service/EmbeddingServiceImpl.js +18 -5
- package/dist/ai/service/EmbeddingServiceImpl.jsonld +35 -0
- package/dist/ai/service/index.d.ts +2 -0
- package/dist/ai/service/index.js +2 -0
- package/dist/api/ai-gateway/connect/index.d.ts +20 -2
- package/dist/api/ai-gateway/connect/index.js +162 -16
- package/dist/api/ai-gateway/credentials/AiCredentialSecretDecoder.d.ts +12 -0
- package/dist/api/ai-gateway/credentials/AiCredentialSecretDecoder.js +30 -0
- package/dist/api/ai-gateway/errors.d.ts +1 -1
- package/dist/api/ai-gateway/models/GatewayEmbeddingModelCatalog.d.ts +11 -0
- package/dist/api/ai-gateway/models/GatewayEmbeddingModelCatalog.js +31 -0
- package/dist/api/ai-gateway/models/PodModelSelectionRepository.js +7 -3
- package/dist/api/ai-gateway/models/ProviderCustomModelsService.d.ts +18 -0
- package/dist/api/ai-gateway/models/ProviderCustomModelsService.js +23 -0
- package/dist/api/ai-gateway/models/ProviderModelDiscoveryAdapters.d.ts +3 -1
- package/dist/api/ai-gateway/models/ProviderModelDiscoveryAdapters.js +2 -45
- package/dist/api/ai-gateway/models/ProviderModelSelectionService.d.ts +10 -0
- package/dist/api/ai-gateway/models/ProviderModelSelectionService.js +57 -20
- package/dist/api/ai-gateway/models/ProviderModelType.d.ts +28 -0
- package/dist/api/ai-gateway/models/ProviderModelType.js +34 -0
- package/dist/api/ai-gateway/models/ProviderModelsAdapter.d.ts +10 -0
- package/dist/api/ai-gateway/models/ProviderModelsAdapter.js +3 -4
- package/dist/api/ai-gateway/models/index.d.ts +1 -0
- package/dist/api/ai-gateway/models/index.js +3 -1
- package/dist/api/ai-gateway/providers/CustomRuntimeAdapter.d.ts +7 -0
- package/dist/api/ai-gateway/providers/CustomRuntimeAdapter.js +9 -2
- package/dist/api/ai-gateway/providers/ModelsDevCatalog.d.ts +7 -1
- package/dist/api/ai-gateway/providers/ModelsDevCatalog.js +4 -10
- package/dist/api/ai-gateway/providers/ProviderRegistry.d.ts +107 -0
- package/dist/api/ai-gateway/providers/ProviderRegistry.js +244 -21
- package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.d.ts +5 -0
- package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.js +5 -1
- package/dist/api/ai-gateway/quota/SubscriptionQuotaAdapters.d.ts +12 -4
- package/dist/api/ai-gateway/quota/SubscriptionQuotaAdapters.js +11 -11
- package/dist/api/ai-gateway/routing/ModelRouter.d.ts +14 -0
- package/dist/api/ai-gateway/routing/ModelRouter.js +43 -4
- package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.d.ts +9 -1
- package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.js +3 -27
- package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +0 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.js +0 -3
- package/dist/api/auth/index.d.ts +1 -0
- package/dist/api/auth/index.js +1 -1
- package/dist/api/chatkit/pod-store.d.ts +31 -0
- package/dist/api/chatkit/pod-store.js +132 -8
- package/dist/api/container/common.js +24 -4
- package/dist/api/container/routes.js +17 -2
- package/dist/api/container/types.d.ts +3 -1
- package/dist/api/handlers/AdminHandler.d.ts +13 -0
- package/dist/api/handlers/AdminHandler.js +47 -18
- package/dist/api/handlers/AiConfigHandler.d.ts +6 -0
- package/dist/api/handlers/AiConfigHandler.js +28 -0
- package/dist/api/handlers/AiGatewayManagementHandler.js +36 -0
- package/dist/api/runs/RdfRunContextRetriever.d.ts +14 -0
- package/dist/api/runs/RdfRunContextRetriever.js +41 -5
- package/dist/api/runtime.js +2 -1
- package/dist/cli/commands/secret.d.ts +1 -0
- package/dist/cli/commands/secret.js +25 -7
- package/dist/components/components.jsonld +3 -1
- package/dist/components/context.jsonld +53 -1
- package/dist/http/SubgraphSparqlHttpHandler.d.ts +59 -2
- package/dist/http/SubgraphSparqlHttpHandler.js +145 -13
- package/dist/http/SubgraphSparqlHttpHandler.jsonld +37 -0
- package/dist/identity/drizzle/AccountRoleRepository.d.ts +30 -2
- package/dist/identity/drizzle/AccountRoleRepository.js +163 -15
- package/dist/identity/drizzle/EdgeNodeRepository.d.ts +0 -12
- package/dist/identity/drizzle/EdgeNodeRepository.js +5 -13
- package/dist/identity/drizzle/PodLookupRepository.d.ts +58 -4
- package/dist/identity/drizzle/PodLookupRepository.js +248 -105
- package/dist/identity/drizzle/db.d.ts +19 -0
- package/dist/identity/drizzle/db.js +39 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +7 -3
- package/dist/logging/log-file.d.ts +17 -0
- package/dist/logging/log-file.js +69 -0
- package/dist/main.js +2 -1
- package/dist/notifications/NotificationChannelSweeper.d.ts +50 -0
- package/dist/notifications/NotificationChannelSweeper.js +131 -0
- package/dist/notifications/NotificationChannelSweeper.jsonld +136 -0
- package/dist/notifications/ReclaimingWebSocket2023Storer.d.ts +25 -0
- package/dist/notifications/ReclaimingWebSocket2023Storer.js +56 -0
- package/dist/notifications/ReclaimingWebSocket2023Storer.jsonld +77 -0
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.js +2 -0
- package/dist/runtime/Proxy.d.ts +37 -0
- package/dist/runtime/Proxy.js +88 -16
- package/dist/runtime/bootstrap.js +2 -1
- package/dist/runtime/upgrade/BunNativeUpgradeRelay.d.ts +116 -0
- package/dist/runtime/upgrade/BunNativeUpgradeRelay.js +423 -0
- package/dist/runtime/upgrade/UpgradeHandshake.d.ts +63 -0
- package/dist/runtime/upgrade/UpgradeHandshake.js +199 -0
- package/dist/runtime/upgrade/WebSocketFrames.d.ts +67 -0
- package/dist/runtime/upgrade/WebSocketFrames.js +224 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.js +8 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.d.ts +11 -2
- package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.js +27 -10
- package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.d.ts +7 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.js +13 -11
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectDialog.js +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsList.js +10 -6
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.d.ts +15 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.js +29 -3
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMainHeader.js +18 -3
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.d.ts +16 -1
- package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.js +92 -20
- package/node_modules/@undefineds.co/ai-connections/dist/AiCopyButton.d.ts +35 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiCopyButton.js +45 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.js +71 -11
- package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialRow.js +9 -7
- package/node_modules/@undefineds.co/ai-connections/dist/AiEndpointList.d.ts +23 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiEndpointList.js +24 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.d.ts +13 -4
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.js +35 -38
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.d.ts +21 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.js +51 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiInfoTooltip.d.ts +15 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiInfoTooltip.js +16 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiModelCatalog.d.ts +175 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiModelCatalog.js +133 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiOfferingDetails.js +2 -2
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.js +13 -64
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderHeader.d.ts +21 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiProviderHeader.js +12 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiRowAction.d.ts +15 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiRowAction.js +12 -0
- package/node_modules/@undefineds.co/ai-connections/dist/AiSortableCredentialList.js +2 -1
- package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.d.ts +7 -0
- package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.js +6 -0
- package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.d.ts +36 -5
- package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.js +52 -9
- package/node_modules/@undefineds.co/ai-connections/dist/client/normalize.js +30 -3
- package/node_modules/@undefineds.co/ai-connections/dist/client/types.d.ts +21 -1
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.d.ts +1 -3
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.js +3 -7
- package/node_modules/@undefineds.co/ai-connections/dist/client-config/index.cjs +9 -7
- package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.d.ts +46 -0
- package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.js +231 -0
- package/node_modules/@undefineds.co/ai-connections/dist/collections.d.ts +119 -0
- package/node_modules/@undefineds.co/ai-connections/dist/collections.js +173 -0
- package/node_modules/@undefineds.co/ai-connections/dist/controller.d.ts +71 -5
- package/node_modules/@undefineds.co/ai-connections/dist/controller.js +285 -16
- package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.d.ts +5 -0
- package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.js +8 -3
- package/node_modules/@undefineds.co/ai-connections/dist/credential-storage.d.ts +59 -0
- package/node_modules/@undefineds.co/ai-connections/dist/credential-storage.js +131 -0
- package/node_modules/@undefineds.co/ai-connections/dist/endpoint-urls.d.ts +15 -0
- package/node_modules/@undefineds.co/ai-connections/dist/endpoint-urls.js +20 -0
- package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.d.ts +14 -0
- package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.js +20 -0
- package/node_modules/@undefineds.co/ai-connections/dist/index.d.ts +8 -0
- package/node_modules/@undefineds.co/ai-connections/dist/index.js +8 -0
- package/node_modules/@undefineds.co/ai-connections/dist/manifest.js +1 -1
- package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.d.ts +14 -0
- package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.js +17 -0
- package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.cjs +68 -1
- package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.d.ts +75 -1
- package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.js +119 -0
- package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.d.ts +5 -0
- package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.js +5 -0
- package/node_modules/@undefineds.co/ai-connections/dist/service-access.js +2 -27
- package/node_modules/@undefineds.co/ai-connections/package.json +1 -0
- package/node_modules/@undefineds.co/extension-sdk/dist/manifest.d.ts +1 -1
- package/node_modules/@undefineds.co/extension-sdk/dist/manifest.js +2 -0
- package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +150 -0
- package/node_modules/@undefineds.co/extension-sdk/package.json +2 -1
- package/node_modules/@undefineds.co/models/README.md +1 -1
- package/node_modules/@undefineds.co/models/dist/ai-config/index.d.ts +3 -3
- package/node_modules/@undefineds.co/models/dist/ai-gateway.schema.d.ts +5 -0
- package/node_modules/@undefineds.co/models/dist/ai-gateway.schema.js +9 -0
- package/node_modules/@undefineds.co/models/dist/ai-runtime.repository.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/approval.repository.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/audit.presentation.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/capture.repository.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/chat-project.repository.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/chat.repository.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/control-request.repository.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/conversation-share.repository.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/credential.schema.d.ts +12 -0
- package/node_modules/@undefineds.co/models/dist/credential.schema.js +15 -1
- package/node_modules/@undefineds.co/models/dist/discovery/index.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/discovery/providers.json +248 -7
- package/node_modules/@undefineds.co/models/dist/discovery/types.d.ts +31 -0
- package/node_modules/@undefineds.co/models/dist/extension/index.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/favorite/index.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/fixtures/contracts-chat-contact.d.ts +5 -5
- package/node_modules/@undefineds.co/models/dist/import/index.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/index.d.ts +73 -73
- package/node_modules/@undefineds.co/models/dist/index.js +1 -1
- package/node_modules/@undefineds.co/models/dist/input-request.repository.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/knowledge/index.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/message.repository.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/namespaces.js +5 -0
- package/node_modules/@undefineds.co/models/dist/pod-storage-descriptor.d.ts +4815 -26
- package/node_modules/@undefineds.co/models/dist/pod-storage-descriptor.js +482 -132
- package/node_modules/@undefineds.co/models/dist/schema.d.ts +4 -0
- package/node_modules/@undefineds.co/models/dist/session/index.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/settings/index.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/sidecar/persistence-mapping.d.ts +5 -5
- package/node_modules/@undefineds.co/models/dist/thread.repository.d.ts +2 -2
- package/node_modules/@undefineds.co/models/dist/types/message-block.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/vocab/_namespaces.d.ts +1 -1
- package/node_modules/@undefineds.co/models/dist/vocab/index.d.ts +10 -10
- package/node_modules/@undefineds.co/models/dist/vocab/sidecar.vocab.d.ts +1 -0
- package/node_modules/@undefineds.co/models/dist/vocab/sidecar.vocab.js +1 -0
- package/node_modules/@undefineds.co/models/package.json +4 -2
- package/node_modules/@undefineds.co/pod-collections/README.md +71 -0
- package/node_modules/@undefineds.co/pod-collections/dist/diff.d.ts +85 -0
- package/node_modules/@undefineds.co/pod-collections/dist/diff.js +166 -0
- package/node_modules/@undefineds.co/pod-collections/dist/feed.d.ts +17 -0
- package/node_modules/@undefineds.co/pod-collections/dist/feed.js +27 -0
- package/node_modules/@undefineds.co/pod-collections/dist/index.cjs +1042 -0
- package/node_modules/@undefineds.co/pod-collections/dist/index.d.ts +37 -0
- package/node_modules/@undefineds.co/pod-collections/dist/index.js +89 -0
- package/node_modules/@undefineds.co/pod-collections/dist/layout.d.ts +75 -0
- package/node_modules/@undefineds.co/pod-collections/dist/layout.js +173 -0
- package/node_modules/@undefineds.co/pod-collections/dist/mapping.d.ts +78 -0
- package/node_modules/@undefineds.co/pod-collections/dist/mapping.js +287 -0
- package/node_modules/@undefineds.co/pod-collections/dist/mutations.d.ts +83 -0
- package/node_modules/@undefineds.co/pod-collections/dist/mutations.js +273 -0
- package/node_modules/@undefineds.co/pod-collections/dist/react.d.ts +21 -0
- package/node_modules/@undefineds.co/pod-collections/dist/react.js +22 -0
- package/node_modules/@undefineds.co/pod-collections/dist/read.d.ts +65 -0
- package/node_modules/@undefineds.co/pod-collections/dist/read.js +31 -0
- package/node_modules/@undefineds.co/pod-collections/dist/sync.d.ts +66 -0
- package/node_modules/@undefineds.co/pod-collections/dist/sync.js +260 -0
- package/node_modules/@undefineds.co/pod-collections/dist/types.d.ts +155 -0
- package/node_modules/@undefineds.co/pod-collections/dist/types.js +9 -0
- package/node_modules/@undefineds.co/pod-collections/package.json +42 -0
- package/node_modules/@undefineds.co/shared-ui/dist/index.d.ts +0 -1
- package/node_modules/@undefineds.co/shared-ui/dist/index.js +0 -1
- package/package.json +15 -7
- package/static/app/assets/main.css +1 -1
- package/static/app/assets/main.js +12 -13
- package/static/auth-callback/assets/AiConfigContext-DnQs1ZpW.js +1 -0
- package/static/auth-callback/assets/AiConfigPage-DOtvlxH0.js +1 -0
- package/static/auth-callback/assets/DocumentProcessingPanel-BS2voQgL.js +1 -0
- package/static/auth-callback/assets/IndexLifecyclePanel-Cvt0cJtN.js +1 -0
- package/static/auth-callback/assets/{IndexSubjectPanel-C4YG0whI.js → IndexSubjectPanel-Dhf01GqF.js} +1 -1
- package/static/auth-callback/assets/ModelAssignmentsPanel-BJutWaAF.js +1 -0
- package/static/auth-callback/assets/ModelsPage-BRS0sje3.js +11 -0
- package/static/auth-callback/assets/{NetworkPage-Cbdn_P1e.js → NetworkPage-B3qBfANA.js} +2 -2
- package/static/auth-callback/assets/{PaneListHeader-jy70Q00L.js → PaneListHeader-QQeJGTp4.js} +1 -1
- package/static/auth-callback/assets/SearchIndexingPanel-MyNUSEwT.js +1 -0
- package/static/auth-callback/assets/{StatusSubjectPanel-hfjoB5aS.js → StatusSubjectPanel-DQkEVsFs.js} +1 -1
- package/static/{settings/assets/StatusWorkspace-CKD_Rzdr.js → auth-callback/assets/StatusWorkspace-Dkv63Uwk.js} +1 -1
- package/static/auth-callback/assets/SystemSettingsPage-TIsUfX5d.js +1 -0
- package/static/auth-callback/assets/SystemSettingsSubjectPanel-BJWEt2-7.js +33 -0
- package/static/auth-callback/assets/XpodAiConnectionsPodStore-BJiXm-PF.js +3 -0
- package/static/auth-callback/assets/{activity-BcsZZxxw.js → activity-5hNeNKnL.js} +1 -1
- package/static/auth-callback/assets/admin-C6qCRFiY.js +1 -0
- package/static/auth-callback/assets/ai-connections-CryuHGKW.js +1 -0
- package/static/auth-callback/assets/{auth-callback-atKg_oig.js → auth-callback-CAFZ3R0B.js} +80 -84
- package/static/auth-callback/assets/auth-callback-rk080mvG.css +1 -0
- package/static/auth-callback/assets/{badge-BWbRHThQ.js → badge-CAIPI0CB.js} +1 -1
- package/static/auth-callback/assets/collection-runtime-D9s7h9YA.js +1 -0
- package/static/auth-callback/assets/dialog-BjA109aX.js +1 -0
- package/static/auth-callback/assets/{download-BmvG1Vya.js → download-B3Up5W2G.js} +1 -1
- package/static/auth-callback/assets/{external-link-DZ34d3g3.js → external-link-BTXgSPzB.js} +1 -1
- package/static/auth-callback/assets/index-BppXlxcp.js +41 -0
- package/static/auth-callback/assets/index-CirW4CJf.js +1 -0
- package/static/auth-callback/assets/index-DlLYWOhw.js +4 -0
- package/static/auth-callback/assets/{index-browser-B9Z7GU-T.js → index-browser-DtU38ni3.js} +1 -1
- package/static/auth-callback/assets/{key-round-tjP76Se-.js → key-round-CQCOrZ7x.js} +1 -1
- package/static/auth-callback/assets/layout-DB3pMyTl.js +1 -0
- package/static/auth-callback/assets/pod-collections-host-KnnGFZHL.js +8 -0
- package/static/auth-callback/assets/{rotate-ccw-C_L5ZLx1.js → rotate-ccw-C1zM2KtS.js} +1 -1
- package/static/auth-callback/assets/settings-projection-CUkyprDQ.js +1 -0
- package/static/auth-callback/assets/{skeleton-C7tGDQIs.js → skeleton-Cqp7_M9-.js} +1 -1
- package/static/auth-callback/assets/{waypoints-VMNQlWdU.js → waypoints-Bj6gAUSQ.js} +1 -1
- package/static/auth-callback/assets/{workspace-layout-SAp6BtYK.js → workspace-layout-DK8mDzrY.js} +1 -1
- package/static/auth-callback/auth-callback.html +2 -2
- package/static/dashboard/assets/AiConfigContext-BsE7MqX8.js +1 -0
- package/static/dashboard/assets/AiConfigPage-DvM-lRXa.js +1 -0
- package/static/dashboard/assets/DocumentProcessingPanel-BPfdlfuf.js +1 -0
- package/static/dashboard/assets/IndexLifecyclePanel--m0AGxvh.js +1 -0
- package/static/dashboard/assets/{IndexSubjectPanel-DQFPP6-p.js → IndexSubjectPanel-Bb7m1k3d.js} +1 -1
- package/static/dashboard/assets/ModelAssignmentsPanel-BLi_zbMa.js +1 -0
- package/static/dashboard/assets/ModelsPage-CxdpgnfR.js +11 -0
- package/static/dashboard/assets/{NetworkPage-CHQ3YxIB.js → NetworkPage-BAIPw-D_.js} +2 -2
- package/static/dashboard/assets/{PaneListHeader-DsXemAdR.js → PaneListHeader-BBCMei0r.js} +1 -1
- package/static/dashboard/assets/SearchIndexingPanel-Ck4Y-xjR.js +1 -0
- package/static/dashboard/assets/{StatusSubjectPanel-D3PGEYT4.js → StatusSubjectPanel-D1KWfAXE.js} +1 -1
- package/static/dashboard/assets/{StatusWorkspace-BcpePYUW.js → StatusWorkspace-JbA5gzXx.js} +1 -1
- package/static/dashboard/assets/SystemSettingsPage-BbwQWsSR.js +1 -0
- package/static/dashboard/assets/SystemSettingsSubjectPanel-N117nMt5.js +33 -0
- package/static/dashboard/assets/XpodAiConnectionsPodStore-CdDOb4SV.js +18 -0
- package/static/dashboard/assets/{activity-j5zrznu-.js → activity-DX1I96o_.js} +1 -1
- package/static/dashboard/assets/admin-C6qCRFiY.js +1 -0
- package/static/dashboard/assets/ai-connections-DwCRqOQa.js +1 -0
- package/static/dashboard/assets/{badge-CzeBdG7h.js → badge-k2vhtDqH.js} +1 -1
- package/static/dashboard/assets/collection-runtime-BFQ8teQJ.js +1 -0
- package/static/dashboard/assets/{dashboard-D-xANHk1.js → dashboard-DWZ-fmCT.js} +105 -109
- package/static/dashboard/assets/dashboard-rk080mvG.css +1 -0
- package/static/dashboard/assets/dialog-1CCw-iHT.js +1 -0
- package/static/dashboard/assets/{download-IcNdEZWi.js → download-C6-SNY1q.js} +1 -1
- package/static/dashboard/assets/{external-link-DxBxK8Vu.js → external-link-BgPcZ_j2.js} +1 -1
- package/static/dashboard/assets/index-6LcIUIYO.js +1 -0
- package/static/dashboard/assets/index-D7A8U6Pt.js +41 -0
- package/static/dashboard/assets/index-UD6QOE7H.js +4 -0
- package/static/dashboard/assets/{key-round-D1K7warM.js → key-round-BOd7Jo0Q.js} +1 -1
- package/static/dashboard/assets/layout-DB3pMyTl.js +1 -0
- package/static/dashboard/assets/pod-collections-host-KnnGFZHL.js +8 -0
- package/static/dashboard/assets/{rotate-ccw-CcN1N6p9.js → rotate-ccw-CCgJqsvx.js} +1 -1
- package/static/dashboard/assets/settings-projection-CUkyprDQ.js +1 -0
- package/static/dashboard/assets/{skeleton-CKnmJMUH.js → skeleton-Bc7abAn5.js} +1 -1
- package/static/dashboard/assets/{waypoints-DuZPO_wu.js → waypoints-s-opmJxx.js} +1 -1
- package/static/dashboard/assets/{workspace-layout-BUj3wZ_m.js → workspace-layout-DqIQeTBV.js} +1 -1
- package/static/dashboard/dashboard.html +2 -2
- package/static/settings/assets/AiConfigContext-BB9KZySa.js +1 -0
- package/static/settings/assets/AiConfigPage-DGSXUkLs.js +1 -0
- package/static/settings/assets/DocumentProcessingPanel-Da2Re6Rg.js +1 -0
- package/static/settings/assets/IndexLifecyclePanel-BSZuIzgr.js +1 -0
- package/static/settings/assets/{IndexSubjectPanel-73sM16Ma.js → IndexSubjectPanel-CFd0ay-r.js} +1 -1
- package/static/settings/assets/ModelAssignmentsPanel-CSAryvWJ.js +1 -0
- package/static/settings/assets/ModelsPage-BQwCwLHU.js +11 -0
- package/static/settings/assets/{NetworkPage-i6j-M2RY.js → NetworkPage-BKymvsQc.js} +2 -2
- package/static/settings/assets/{PaneListHeader-DpqC0jd5.js → PaneListHeader-Bjh3hRdQ.js} +1 -1
- package/static/settings/assets/SearchIndexingPanel-MjKL5QLU.js +1 -0
- package/static/settings/assets/{StatusSubjectPanel-Dv4q3PGh.js → StatusSubjectPanel-Bvl6K4mx.js} +1 -1
- package/static/settings/assets/StatusWorkspace-B0NzrP--.js +1 -0
- package/static/settings/assets/SystemSettingsPage-D2z6Z4FE.js +1 -0
- package/static/settings/assets/SystemSettingsSubjectPanel-4sxma4X4.js +33 -0
- package/static/settings/assets/XpodAiConnectionsPodStore-BkNQ8fZx.js +3 -0
- package/static/settings/assets/{activity-DaFkk8f3.js → activity-CgJJGpjx.js} +1 -1
- package/static/settings/assets/admin-C6qCRFiY.js +1 -0
- package/static/settings/assets/ai-connections-CryuHGKW.js +1 -0
- package/static/settings/assets/{badge-d5SHdc-x.js → badge-C4NypVyT.js} +1 -1
- package/static/settings/assets/collection-runtime-CTLCDxAi.js +1 -0
- package/static/settings/assets/dialog-Csq0vWUi.js +1 -0
- package/static/settings/assets/{download-CpkwomDr.js → download-DaLJJ-Wp.js} +1 -1
- package/static/settings/assets/{external-link-_4YT42Mf.js → external-link--w_iW5Au.js} +1 -1
- package/static/settings/assets/index-B0mQa59b.js +4 -0
- package/static/settings/assets/index-BukHiu4y.js +1 -0
- package/static/settings/assets/index-COmVnZi2.js +41 -0
- package/static/settings/assets/{index-browser-B06xjBdZ.js → index-browser-BGpvHwD0.js} +1 -1
- package/static/settings/assets/{key-round-Dlqmp1Kq.js → key-round-Bk4YRjBu.js} +1 -1
- package/static/settings/assets/layout-DB3pMyTl.js +1 -0
- package/static/settings/assets/pod-collections-host-KnnGFZHL.js +8 -0
- package/static/settings/assets/{rotate-ccw-TAY65xWT.js → rotate-ccw-TCabbqsr.js} +1 -1
- package/static/settings/assets/{settings-ExBXGgbj.js → settings-CJWpdbNC.js} +105 -109
- package/static/settings/assets/settings-projection-CUkyprDQ.js +1 -0
- package/static/settings/assets/settings-rk080mvG.css +1 -0
- package/static/settings/assets/{skeleton-DKIWjNr9.js → skeleton-JDHYVe7t.js} +1 -1
- package/static/settings/assets/{waypoints-9erLIxyR.js → waypoints-DDvEl-MU.js} +1 -1
- package/static/settings/assets/{workspace-layout-CYXfYIa3.js → workspace-layout-DV5QU30U.js} +1 -1
- package/static/settings/settings.html +2 -2
- package/node_modules/@undefineds.co/shared-ui/dist/oidc-consent.d.ts +0 -54
- package/node_modules/@undefineds.co/shared-ui/dist/oidc-consent.js +0 -21
- package/static/auth-callback/assets/AiConfigContext-C81deMM9.js +0 -1
- package/static/auth-callback/assets/AiConfigPage-evWI8T56.js +0 -1
- package/static/auth-callback/assets/DocumentProcessingPanel-B9GrDEMe.js +0 -1
- package/static/auth-callback/assets/IndexLifecyclePanel-qCo8ABQZ.js +0 -1
- package/static/auth-callback/assets/ModelAssignmentsPanel-DG7Lxh3t.js +0 -1
- package/static/auth-callback/assets/ModelsPage-CgEuqE6p.js +0 -10
- package/static/auth-callback/assets/SearchIndexingPanel-ByU3u7kp.js +0 -1
- package/static/auth-callback/assets/StatusWorkspace-BZd617sV.js +0 -1
- package/static/auth-callback/assets/SystemSettingsPage-BirzWAQM.js +0 -1
- package/static/auth-callback/assets/SystemSettingsSubjectPanel-CmsVWNCx.js +0 -31
- package/static/auth-callback/assets/admin-BU4m6Ko2.js +0 -1
- package/static/auth-callback/assets/ai-connections-CHNTKemd.js +0 -1
- package/static/auth-callback/assets/auth-callback-C_7MUXJb.css +0 -1
- package/static/auth-callback/assets/index-BpV1hsqs.js +0 -4
- package/static/auth-callback/assets/index-D9oE6FXK.js +0 -41
- package/static/dashboard/assets/AiConfigContext-De-OtAWo.js +0 -1
- package/static/dashboard/assets/AiConfigPage-macP4Mop.js +0 -1
- package/static/dashboard/assets/DocumentProcessingPanel-C5ObvCCl.js +0 -1
- package/static/dashboard/assets/IndexLifecyclePanel-xVNa2l40.js +0 -1
- package/static/dashboard/assets/ModelAssignmentsPanel-DMOATFpQ.js +0 -1
- package/static/dashboard/assets/ModelsPage-91UbnETA.js +0 -25
- package/static/dashboard/assets/SearchIndexingPanel-Dh70PNFZ.js +0 -1
- package/static/dashboard/assets/SystemSettingsPage-BiN5GcKx.js +0 -1
- package/static/dashboard/assets/SystemSettingsSubjectPanel-B9QrSiFp.js +0 -31
- package/static/dashboard/assets/admin-BU4m6Ko2.js +0 -1
- package/static/dashboard/assets/ai-connections-CHNTKemd.js +0 -1
- package/static/dashboard/assets/dashboard-C_7MUXJb.css +0 -1
- package/static/dashboard/assets/index-FWZ-s52O.js +0 -41
- package/static/dashboard/assets/index-ZiQZ96oC.js +0 -4
- package/static/settings/assets/AiConfigContext-C0cQMPfG.js +0 -1
- package/static/settings/assets/AiConfigPage-CPhB4iFb.js +0 -1
- package/static/settings/assets/DocumentProcessingPanel-sYI7OpuH.js +0 -1
- package/static/settings/assets/IndexLifecyclePanel-yj8iyiT8.js +0 -1
- package/static/settings/assets/ModelAssignmentsPanel-BFIgUX5v.js +0 -1
- package/static/settings/assets/ModelsPage-BdppXl7E.js +0 -10
- package/static/settings/assets/SearchIndexingPanel-BlPnrkT3.js +0 -1
- package/static/settings/assets/SystemSettingsPage-CiOm2NzV.js +0 -1
- package/static/settings/assets/SystemSettingsSubjectPanel-Cd-GECon.js +0 -31
- package/static/settings/assets/admin-BU4m6Ko2.js +0 -1
- package/static/settings/assets/ai-connections-CHNTKemd.js +0 -1
- package/static/settings/assets/index-BFi9yn7_.js +0 -41
- package/static/settings/assets/index-BGgEhIUy.js +0 -4
- package/static/settings/assets/settings-C_7MUXJb.css +0 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal RFC 6455 frame codec used by the gateway's native (Bun) WebSocket
|
|
3
|
+
* upgrade relay.
|
|
4
|
+
*
|
|
5
|
+
* The gateway only needs it on runtimes whose HTTP server cannot hand the raw
|
|
6
|
+
* upgraded socket back to JavaScript (see `BunNativeUpgradeRelay`): there the
|
|
7
|
+
* client side is a native WebSocket (message level), while the upstream side is
|
|
8
|
+
* a raw socket, so frames have to be decoded/encoded in between.
|
|
9
|
+
*
|
|
10
|
+
* The codec deliberately implements a single, predictable flavour of the
|
|
11
|
+
* protocol: no extensions (the relay never offers `permessage-deflate`), no
|
|
12
|
+
* fragmentation on the outbound path (one frame per message) and a bounded
|
|
13
|
+
* inbound message size.
|
|
14
|
+
*/
|
|
15
|
+
export declare const WS_OPCODE: {
|
|
16
|
+
readonly continuation: 0;
|
|
17
|
+
readonly text: 1;
|
|
18
|
+
readonly binary: 2;
|
|
19
|
+
readonly close: 8;
|
|
20
|
+
readonly ping: 9;
|
|
21
|
+
readonly pong: 10;
|
|
22
|
+
};
|
|
23
|
+
export type WebSocketFrameOpcode = typeof WS_OPCODE[keyof typeof WS_OPCODE];
|
|
24
|
+
/** Close code used when the peer violates the protocol. */
|
|
25
|
+
export declare const WS_CLOSE_PROTOCOL_ERROR = 1002;
|
|
26
|
+
/** Close code used when a message exceeds the configured size limit. */
|
|
27
|
+
export declare const WS_CLOSE_MESSAGE_TOO_BIG = 1009;
|
|
28
|
+
export interface EncodeWebSocketFrameOptions {
|
|
29
|
+
opcode: WebSocketFrameOpcode;
|
|
30
|
+
/** Client-to-server frames must be masked; server-to-client frames must not. */
|
|
31
|
+
mask: boolean;
|
|
32
|
+
/** Deterministic mask key, for tests only. */
|
|
33
|
+
maskKey?: Buffer;
|
|
34
|
+
}
|
|
35
|
+
export declare function encodeWebSocketFrame(payload: Buffer, options: EncodeWebSocketFrameOptions): Buffer;
|
|
36
|
+
/** Encodes a close frame body (`code` + UTF-8 reason). */
|
|
37
|
+
export declare function encodeWebSocketClosePayload(code: number, reason: string): Buffer;
|
|
38
|
+
export interface WebSocketFrameSink {
|
|
39
|
+
/** A complete (possibly reassembled) data message. */
|
|
40
|
+
onMessage(payload: Buffer, isBinary: boolean): void;
|
|
41
|
+
onPing(payload: Buffer): void;
|
|
42
|
+
onPong(payload: Buffer): void;
|
|
43
|
+
onClose(code: number, reason: string): void;
|
|
44
|
+
/** The peer sent something that violates the protocol; the connection should be closed with 1002. */
|
|
45
|
+
onProtocolError(reason: string): void;
|
|
46
|
+
}
|
|
47
|
+
export interface WebSocketFrameParserOptions {
|
|
48
|
+
/** Upper bound for a single (reassembled) message; oversized messages raise a protocol error. */
|
|
49
|
+
maxMessageBytes?: number;
|
|
50
|
+
}
|
|
51
|
+
export declare class WebSocketFrameParser {
|
|
52
|
+
private readonly sink;
|
|
53
|
+
private buffer;
|
|
54
|
+
private fragmentOpcode;
|
|
55
|
+
private fragments;
|
|
56
|
+
private fragmentBytes;
|
|
57
|
+
private failed;
|
|
58
|
+
private readonly maxMessageBytes;
|
|
59
|
+
constructor(sink: WebSocketFrameSink, options?: WebSocketFrameParserOptions);
|
|
60
|
+
push(chunk: Buffer): void;
|
|
61
|
+
private fail;
|
|
62
|
+
/** @returns whether a complete frame was consumed. */
|
|
63
|
+
private parseFrame;
|
|
64
|
+
private handleFrame;
|
|
65
|
+
private appendFragment;
|
|
66
|
+
private completeMessage;
|
|
67
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebSocketFrameParser = exports.WS_CLOSE_MESSAGE_TOO_BIG = exports.WS_CLOSE_PROTOCOL_ERROR = exports.WS_OPCODE = void 0;
|
|
4
|
+
exports.encodeWebSocketFrame = encodeWebSocketFrame;
|
|
5
|
+
exports.encodeWebSocketClosePayload = encodeWebSocketClosePayload;
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
/**
|
|
8
|
+
* Minimal RFC 6455 frame codec used by the gateway's native (Bun) WebSocket
|
|
9
|
+
* upgrade relay.
|
|
10
|
+
*
|
|
11
|
+
* The gateway only needs it on runtimes whose HTTP server cannot hand the raw
|
|
12
|
+
* upgraded socket back to JavaScript (see `BunNativeUpgradeRelay`): there the
|
|
13
|
+
* client side is a native WebSocket (message level), while the upstream side is
|
|
14
|
+
* a raw socket, so frames have to be decoded/encoded in between.
|
|
15
|
+
*
|
|
16
|
+
* The codec deliberately implements a single, predictable flavour of the
|
|
17
|
+
* protocol: no extensions (the relay never offers `permessage-deflate`), no
|
|
18
|
+
* fragmentation on the outbound path (one frame per message) and a bounded
|
|
19
|
+
* inbound message size.
|
|
20
|
+
*/
|
|
21
|
+
exports.WS_OPCODE = {
|
|
22
|
+
continuation: 0x0,
|
|
23
|
+
text: 0x1,
|
|
24
|
+
binary: 0x2,
|
|
25
|
+
close: 0x8,
|
|
26
|
+
ping: 0x9,
|
|
27
|
+
pong: 0xa,
|
|
28
|
+
};
|
|
29
|
+
/** Close code used when the peer violates the protocol. */
|
|
30
|
+
exports.WS_CLOSE_PROTOCOL_ERROR = 1002;
|
|
31
|
+
/** Close code used when a message exceeds the configured size limit. */
|
|
32
|
+
exports.WS_CLOSE_MESSAGE_TOO_BIG = 1009;
|
|
33
|
+
function encodeWebSocketFrame(payload, options) {
|
|
34
|
+
const { opcode, mask } = options;
|
|
35
|
+
const length = payload.length;
|
|
36
|
+
const lengthBytes = length < 126 ? 1 : length <= 0xffff ? 3 : 9;
|
|
37
|
+
const maskBytes = mask ? 4 : 0;
|
|
38
|
+
const frame = Buffer.allocUnsafe(1 + lengthBytes + maskBytes + length);
|
|
39
|
+
frame[0] = 0x80 | opcode;
|
|
40
|
+
let offset;
|
|
41
|
+
if (length < 126) {
|
|
42
|
+
frame[1] = (mask ? 0x80 : 0) | length;
|
|
43
|
+
offset = 2;
|
|
44
|
+
}
|
|
45
|
+
else if (length <= 0xffff) {
|
|
46
|
+
frame[1] = (mask ? 0x80 : 0) | 126;
|
|
47
|
+
frame.writeUInt16BE(length, 2);
|
|
48
|
+
offset = 4;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
frame[1] = (mask ? 0x80 : 0) | 127;
|
|
52
|
+
frame.writeBigUInt64BE(BigInt(length), 2);
|
|
53
|
+
offset = 10;
|
|
54
|
+
}
|
|
55
|
+
if (!mask) {
|
|
56
|
+
payload.copy(frame, offset);
|
|
57
|
+
return frame;
|
|
58
|
+
}
|
|
59
|
+
const maskKey = options.maskKey ?? (0, node_crypto_1.randomBytes)(4);
|
|
60
|
+
maskKey.copy(frame, offset);
|
|
61
|
+
for (let index = 0; index < length; index++) {
|
|
62
|
+
frame[offset + 4 + index] = payload[index] ^ maskKey[index % 4];
|
|
63
|
+
}
|
|
64
|
+
return frame;
|
|
65
|
+
}
|
|
66
|
+
/** Encodes a close frame body (`code` + UTF-8 reason). */
|
|
67
|
+
function encodeWebSocketClosePayload(code, reason) {
|
|
68
|
+
const reasonBytes = Buffer.from(reason, 'utf8');
|
|
69
|
+
const payload = Buffer.allocUnsafe(2 + reasonBytes.length);
|
|
70
|
+
payload.writeUInt16BE(code, 0);
|
|
71
|
+
reasonBytes.copy(payload, 2);
|
|
72
|
+
return payload;
|
|
73
|
+
}
|
|
74
|
+
const DEFAULT_MAX_MESSAGE_BYTES = 64 * 1024 * 1024;
|
|
75
|
+
class WebSocketFrameParser {
|
|
76
|
+
constructor(sink, options = {}) {
|
|
77
|
+
this.sink = sink;
|
|
78
|
+
this.buffer = Buffer.alloc(0);
|
|
79
|
+
this.fragments = [];
|
|
80
|
+
this.fragmentBytes = 0;
|
|
81
|
+
this.failed = false;
|
|
82
|
+
this.maxMessageBytes = options.maxMessageBytes ?? DEFAULT_MAX_MESSAGE_BYTES;
|
|
83
|
+
}
|
|
84
|
+
push(chunk) {
|
|
85
|
+
if (this.failed || chunk.length === 0) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);
|
|
89
|
+
while (!this.failed && this.parseFrame()) {
|
|
90
|
+
// Keep consuming buffered frames.
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
fail(reason) {
|
|
94
|
+
this.failed = true;
|
|
95
|
+
this.buffer = Buffer.alloc(0);
|
|
96
|
+
this.fragments = [];
|
|
97
|
+
this.fragmentOpcode = undefined;
|
|
98
|
+
this.sink.onProtocolError(reason);
|
|
99
|
+
}
|
|
100
|
+
/** @returns whether a complete frame was consumed. */
|
|
101
|
+
parseFrame() {
|
|
102
|
+
const buffer = this.buffer;
|
|
103
|
+
if (buffer.length < 2) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const fin = (buffer[0] & 0x80) !== 0;
|
|
107
|
+
const reserved = buffer[0] & 0x70;
|
|
108
|
+
const opcode = (buffer[0] & 0x0f);
|
|
109
|
+
const masked = (buffer[1] & 0x80) !== 0;
|
|
110
|
+
let payloadLength = buffer[1] & 0x7f;
|
|
111
|
+
let offset = 2;
|
|
112
|
+
if (reserved !== 0) {
|
|
113
|
+
this.fail('reserved frame bits set without a negotiated extension');
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
if (payloadLength === 126) {
|
|
117
|
+
if (buffer.length < offset + 2) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
payloadLength = buffer.readUInt16BE(offset);
|
|
121
|
+
offset += 2;
|
|
122
|
+
}
|
|
123
|
+
else if (payloadLength === 127) {
|
|
124
|
+
if (buffer.length < offset + 8) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
const big = buffer.readBigUInt64BE(offset);
|
|
128
|
+
if (big > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
129
|
+
this.fail('frame payload length is out of range');
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
payloadLength = Number(big);
|
|
133
|
+
offset += 8;
|
|
134
|
+
}
|
|
135
|
+
const isControl = (opcode & 0x8) !== 0;
|
|
136
|
+
if (isControl && (!fin || payloadLength > 125)) {
|
|
137
|
+
this.fail('invalid control frame');
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
const maskBytes = masked ? 4 : 0;
|
|
141
|
+
if (payloadLength > this.maxMessageBytes || this.fragmentBytes + payloadLength > this.maxMessageBytes) {
|
|
142
|
+
this.fail('message exceeds the configured size limit');
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
if (buffer.length < offset + maskBytes + payloadLength) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const maskKey = masked ? buffer.subarray(offset, offset + 4) : undefined;
|
|
149
|
+
offset += maskBytes;
|
|
150
|
+
const payload = Buffer.from(buffer.subarray(offset, offset + payloadLength));
|
|
151
|
+
this.buffer = buffer.subarray(offset + payloadLength);
|
|
152
|
+
if (maskKey) {
|
|
153
|
+
for (let index = 0; index < payload.length; index++) {
|
|
154
|
+
payload[index] = payload[index] ^ maskKey[index % 4];
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
this.handleFrame(fin, opcode, payload);
|
|
158
|
+
return !this.failed;
|
|
159
|
+
}
|
|
160
|
+
handleFrame(fin, opcode, payload) {
|
|
161
|
+
switch (opcode) {
|
|
162
|
+
case exports.WS_OPCODE.continuation:
|
|
163
|
+
if (this.fragmentOpcode === undefined) {
|
|
164
|
+
this.fail('continuation frame without a started message');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
this.appendFragment(payload);
|
|
168
|
+
if (fin) {
|
|
169
|
+
this.completeMessage();
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
case exports.WS_OPCODE.text:
|
|
173
|
+
case exports.WS_OPCODE.binary:
|
|
174
|
+
if (this.fragmentOpcode !== undefined) {
|
|
175
|
+
this.fail('new data frame while a fragmented message is in progress');
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
this.fragmentOpcode = opcode;
|
|
179
|
+
this.appendFragment(payload);
|
|
180
|
+
if (fin) {
|
|
181
|
+
this.completeMessage();
|
|
182
|
+
}
|
|
183
|
+
return;
|
|
184
|
+
case exports.WS_OPCODE.close: {
|
|
185
|
+
if (payload.length === 1) {
|
|
186
|
+
this.fail('close frame with a 1 byte payload');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
// The close frame ends the data stream: nothing after it is dispatched.
|
|
190
|
+
this.failed = true;
|
|
191
|
+
this.buffer = Buffer.alloc(0);
|
|
192
|
+
this.sink.onClose(payload.length === 0 ? 1005 : payload.readUInt16BE(0), payload.subarray(2).toString('utf8'));
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
case exports.WS_OPCODE.ping:
|
|
196
|
+
this.sink.onPing(payload);
|
|
197
|
+
return;
|
|
198
|
+
case exports.WS_OPCODE.pong:
|
|
199
|
+
this.sink.onPong(payload);
|
|
200
|
+
return;
|
|
201
|
+
default:
|
|
202
|
+
this.fail(`unsupported opcode ${opcode}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
appendFragment(payload) {
|
|
206
|
+
this.fragmentBytes += payload.length;
|
|
207
|
+
if (this.fragmentBytes > this.maxMessageBytes) {
|
|
208
|
+
this.fail('message exceeds the configured size limit');
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
this.fragments.push(payload);
|
|
212
|
+
}
|
|
213
|
+
completeMessage() {
|
|
214
|
+
const opcode = this.fragmentOpcode;
|
|
215
|
+
const fragments = this.fragments;
|
|
216
|
+
this.fragmentOpcode = undefined;
|
|
217
|
+
this.fragments = [];
|
|
218
|
+
this.fragmentBytes = 0;
|
|
219
|
+
const payload = fragments.length === 1 ? fragments[0] : Buffer.concat(fragments);
|
|
220
|
+
this.sink.onMessage(payload, opcode === exports.WS_OPCODE.binary);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
exports.WebSocketFrameParser = WebSocketFrameParser;
|
|
224
|
+
//# sourceMappingURL=WebSocketFrames.js.map
|
|
@@ -4,6 +4,7 @@ import { Button, Input, cn } from '@undefineds.co/shared-ui';
|
|
|
4
4
|
import { ExternalLink, Eye, EyeOff, KeyRound, Loader2, LogOut, Plus, RotateCw } from 'lucide-react';
|
|
5
5
|
import { normalizeProxyUrl } from './ai-connections-client.js';
|
|
6
6
|
import { offeringTitle } from './offering-label.js';
|
|
7
|
+
import { authorizationMethodsForOffering, isApiKeyMethod } from './authorization-methods.js';
|
|
7
8
|
import { nextCredentialPriority } from './credential-labels.js';
|
|
8
9
|
import { offeringEndpoint } from './offering-endpoints.js';
|
|
9
10
|
export function AiApiKeyPool({ definition, offering, createOfferings, status, credentials, attempt, apiKey, baseUrl, busy, disabled, error, onApiKeyChange, onBaseUrlChange, onBeginApiKey, onBeginBrowser, onSaveApiKey, onDisconnect, onCreateApiKeyCredential, onUpdateCredential, initialEditing, initialCreate = false, onSavingChange, onCloseEdit, }) {
|
|
@@ -11,6 +12,12 @@ export function AiApiKeyPool({ definition, offering, createOfferings, status, cr
|
|
|
11
12
|
const isConfigured = status === 'configured';
|
|
12
13
|
const isConnected = status === 'connected';
|
|
13
14
|
const hasPoolActions = Boolean(onCreateApiKeyCredential);
|
|
15
|
+
/**
|
|
16
|
+
* The legacy no-pool toolbar names its browser entry from the offering's own
|
|
17
|
+
* methods, like every other connect action. An api-key-only offering declares
|
|
18
|
+
* none, so that toolbar shows no browser button at all.
|
|
19
|
+
*/
|
|
20
|
+
const browserMethod = authorizationMethodsForOffering(offering).find((method) => !isApiKeyMethod(method));
|
|
14
21
|
const [createOfferingId, setCreateOfferingId] = useState(offering.id);
|
|
15
22
|
const formOffering = createOfferings.find((item) => item.id === createOfferingId) ?? offering;
|
|
16
23
|
const [showKey, setShowKey] = useState(false);
|
|
@@ -115,7 +122,7 @@ export function AiApiKeyPool({ definition, offering, createOfferings, status, cr
|
|
|
115
122
|
}
|
|
116
123
|
}
|
|
117
124
|
};
|
|
118
|
-
return (_jsxs("div", { className: cn('space-y-3', formMode && 'w-full'), children: [attempt?.userCode ? (_jsxs("div", { className: "border-l-2 border-primary bg-muted/30 px-3 py-2 text-sm", children: ["\u9A8C\u8BC1\u7801\uFF1A", _jsx("strong", { className: "font-mono", children: attempt.userCode })] })) : null, !initialCreate && !initialEditing ? _jsxs("div", { className: "flex flex-wrap gap-2", children: [onCreateApiKeyCredential && createOfferings.length > 0 ? (_jsxs(Button, { variant: "outline", size: "sm", disabled: busy || disabled || saving, onClick: openCreateForm, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "\u6DFB\u52A0 API Key"] })) : null, hasPoolActions ? null : isConnected ? (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "outline", size: "sm", disabled: busy || disabled || saving, onClick: onBeginBrowser, children: [busy ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(RotateCw, { className: "mr-2 h-4 w-4" }), "\u91CD\u65B0\u8FDE\u63A5"] }), _jsxs(Button, { variant: "ghost", size: "sm", disabled: busy || disabled || saving, onClick: onDisconnect, children: [_jsx(LogOut, { className: "mr-2 h-4 w-4" }), "\u65AD\u5F00\u8FDE\u63A5"] })] })) : isConfigured ? (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "outline", size: "sm", "aria-label": "\u66F4\u65B0 API Key", disabled: busy || disabled || saving, onClick: onBeginApiKey, children: [_jsx(KeyRound, { className: "mr-2 h-4 w-4" }), "\u66F4\u65B0 API Key"] }), _jsx(Button, { variant: "ghost", size: "sm", disabled: busy || disabled || saving, onClick: onDisconnect, children: "\u79FB\u9664\u914D\u7F6E" })] })) : (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "outline", size: "sm", disabled: busy || disabled || saving ||
|
|
125
|
+
return (_jsxs("div", { className: cn('space-y-3', formMode && 'w-full'), children: [attempt?.userCode ? (_jsxs("div", { className: "border-l-2 border-primary bg-muted/30 px-3 py-2 text-sm", children: ["\u9A8C\u8BC1\u7801\uFF1A", _jsx("strong", { className: "font-mono", children: attempt.userCode })] })) : null, !initialCreate && !initialEditing ? _jsxs("div", { className: "flex flex-wrap gap-2", children: [onCreateApiKeyCredential && createOfferings.length > 0 ? (_jsxs(Button, { variant: "outline", size: "sm", disabled: busy || disabled || saving, onClick: openCreateForm, children: [_jsx(Plus, { className: "mr-2 h-4 w-4" }), "\u6DFB\u52A0 API Key"] })) : null, hasPoolActions ? null : isConnected ? (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "outline", size: "sm", disabled: busy || disabled || saving, onClick: onBeginBrowser, children: [busy ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(RotateCw, { className: "mr-2 h-4 w-4" }), "\u91CD\u65B0\u8FDE\u63A5"] }), _jsxs(Button, { variant: "ghost", size: "sm", disabled: busy || disabled || saving, onClick: onDisconnect, children: [_jsx(LogOut, { className: "mr-2 h-4 w-4" }), "\u65AD\u5F00\u8FDE\u63A5"] })] })) : isConfigured ? (_jsxs(_Fragment, { children: [_jsxs(Button, { variant: "outline", size: "sm", "aria-label": "\u66F4\u65B0 API Key", disabled: busy || disabled || saving, onClick: onBeginApiKey, children: [_jsx(KeyRound, { className: "mr-2 h-4 w-4" }), "\u66F4\u65B0 API Key"] }), _jsx(Button, { variant: "ghost", size: "sm", disabled: busy || disabled || saving, onClick: onDisconnect, children: "\u79FB\u9664\u914D\u7F6E" })] })) : (_jsxs(_Fragment, { children: [browserMethod ? (_jsxs(Button, { variant: "outline", size: "sm", title: browserMethod.lifecycle === 'unavailable' ? browserMethod.reason : undefined, disabled: busy || disabled || saving || browserMethod.lifecycle === 'unavailable', onClick: onBeginBrowser, children: [busy ? _jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }) : _jsx(ExternalLink, { className: "mr-2 h-4 w-4" }), browserMethod.label] })) : null, _jsxs(Button, { variant: "outline", size: "sm", "aria-label": `${definition.name} API Key`, disabled: busy || disabled || saving, onClick: onBeginApiKey, children: [_jsx(KeyRound, { className: "mr-2 h-4 w-4" }), "\u914D\u7F6E API Key"] })] }))] }) : null, formMode ? (_jsxs("div", { className: "space-y-2 rounded-lg border border-border/50 bg-muted/10 p-3", children: [formMode === 'create' && createOfferings.length > 1 ? (_jsxs("label", { className: "block space-y-1 text-xs text-muted-foreground", children: [_jsx("span", { children: "\u5957\u9910 / \u533A\u57DF" }), _jsx("select", { "aria-label": `${definition.name} 套餐 / 区域`, value: createOfferingId, disabled: busy || disabled || saving, onChange: (event) => { setCreateOfferingId(event.target.value); setPoolFormError(undefined); }, className: "h-9 w-full rounded-md border border-input bg-background px-3 text-sm text-foreground", children: createOfferings.map((item) => _jsx("option", { value: item.id, children: offeringTitle(item) }, item.id)) })] })) : null, formMode === 'edit' ? (_jsx(Input, { disabled: busy || disabled || saving, autoComplete: "off", "aria-label": `${definition.name} API Key 标签`, placeholder: "\u540D\u79F0\uFF0C\u4F8B\u5982 Work key", value: poolLabel, onChange: (event) => setPoolLabel(event.target.value) })) : null, formMode === 'create' ? (_jsx(Input, { disabled: busy || disabled || saving, type: showKey ? 'text' : 'password', autoComplete: "new-password", "data-lpignore": "true", "data-1p-ignore": true, "aria-label": `${definition.name} API Key 输入`, placeholder: definition.apiKeyPlaceholder || '从官方控制台复制 API Key', value: poolApiKey, onChange: (event) => setPoolApiKey(event.target.value), className: "font-mono" })) : null, formMode === 'edit' || showAdvanced ? (_jsxs(_Fragment, { children: [_jsx(Input, { disabled: busy || disabled || saving, autoComplete: "off", "data-lpignore": "true", "data-1p-ignore": true, "aria-label": `${definition.name} Base URL 输入`, placeholder: offeringEndpoint(formMode === 'edit' ? offering : formOffering) || definition.defaultBaseUrl || '默认服务地址', value: poolBaseUrl, onChange: (event) => setPoolBaseUrl(event.target.value), className: "font-mono text-xs" }), _jsx(Input, { disabled: busy || disabled || saving, autoComplete: "off", "data-lpignore": "true", "data-1p-ignore": true, "aria-label": `${definition.name} Proxy URL 输入`, placeholder: "http://127.0.0.1:7890", value: poolProxyUrl, onChange: (event) => setPoolProxyUrl(event.target.value), className: "font-mono text-xs" })] })) : null, poolFormError ? _jsx("p", { className: "text-xs text-destructive", children: poolFormError }) : null, _jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx(Button, { size: "sm", "aria-label": formMode === 'create' ? `保存 ${definition.name} API Key` : '保存凭证', disabled: busy || disabled || saving || (formMode === 'create' && !poolApiKey.trim()), onClick: savePoolForm, children: formMode === 'create' ? '保存 API Key' : '保存凭证' }), _jsx(Button, { variant: "ghost", size: "sm", disabled: saving, onClick: closePoolForm, children: "\u53D6\u6D88" }), formMode === 'create' ? (_jsx(Button, { variant: "ghost", size: "sm", disabled: saving, onClick: () => setShowAdvanced((current) => !current), children: showAdvanced ? '收起高级设置' : '高级设置' })) : null] })] })) : null, apiKeyAttempt && !formMode ? (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-sm font-medium", children: "API Key" }), definition.apiKeyUrl ? (_jsx("a", { href: definition.apiKeyUrl, target: "_blank", rel: "noreferrer", className: "text-xs text-primary hover:underline", children: "\u83B7\u53D6 API Key" })) : null] }), _jsxs("div", { className: "group relative", children: [_jsx(Input, { disabled: busy || disabled || saving, type: showKey ? 'text' : 'password', autoComplete: "new-password", "data-lpignore": "true", "data-1p-ignore": true, "aria-label": `${definition.name} API Key 输入`, placeholder: definition.apiKeyPlaceholder || '从官方控制台复制 API Key', value: apiKey, onChange: (event) => onApiKeyChange(event.target.value), className: "border-border/60 bg-muted/20 pr-10 font-mono transition-colors focus:border-primary/50 focus:bg-background" }), _jsx("div", { className: "absolute bottom-1 right-1 top-1 flex items-center", children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-full w-8 rounded hover:bg-muted", onClick: () => setShowKey((current) => !current), "aria-label": showKey ? '隐藏 API Key' : '显示 API Key', children: showKey
|
|
119
126
|
? _jsx(EyeOff, { className: "h-4 w-4 text-muted-foreground" })
|
|
120
127
|
: _jsx(Eye, { className: "h-4 w-4 text-muted-foreground" }) }) })] }), onBaseUrlChange ? (_jsxs("div", { className: "space-y-1.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Base URL\uFF08\u9009\u586B\uFF09" }), _jsx(Input, { disabled: busy || disabled || saving, autoComplete: "off", "data-lpignore": "true", "data-1p-ignore": true, "aria-label": `${definition.name} Base URL 输入`, placeholder: definition.defaultBaseUrl || '默认服务地址', value: baseUrl, onChange: (event) => onBaseUrlChange(event.target.value), className: "border-border/60 bg-muted/20 font-mono text-xs transition-colors focus:border-primary/50 focus:bg-background" }), _jsxs("p", { className: "break-all font-mono text-[11px] text-muted-foreground opacity-80", children: [_jsx("span", { className: "mr-1 select-none opacity-50", children: "\u9884\u89C8:" }), (baseUrl.trim() || definition.defaultBaseUrl || '').replace(/\/+$/, ''), "/chat/completions"] })] })) : null, _jsx(Button, { size: "sm", "aria-label": `保存 ${definition.name} API Key`, disabled: !apiKey.trim() || busy || disabled, onClick: onSaveApiKey, children: "\u4FDD\u5B58 API Key" })] })) : null, error ? _jsx("p", { className: "text-sm text-destructive", children: error }) : null] }));
|
|
121
128
|
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import type { AiConnectionsMode, AiProviderAuthorizationMethod, AiProviderOffering } from './ai-connections-client';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* The offering's own entries, one button per declared `authorizationMethod`.
|
|
4
|
+
*
|
|
5
|
+
* A method that is implemented but unavailable in this deployment still gets its
|
|
6
|
+
* button, greyed at the same spec as its neighbours so the row keeps one line,
|
|
7
|
+
* with the reason as its tooltip. Nothing explains itself in a second row: the
|
|
8
|
+
* entry's own state is the message, and a list of internal reasons underneath
|
|
9
|
+
* the row reflows the buttons around it. Methods this build has not implemented
|
|
10
|
+
* never reach here - the server omits them.
|
|
11
|
+
*/
|
|
12
|
+
export declare function AiAuthorizationActions({ methods, offering, busy, disabled, onBeginOffering, onCreateLocalCredential, }: {
|
|
3
13
|
methods: AiProviderAuthorizationMethod[];
|
|
4
14
|
offering: AiProviderOffering;
|
|
5
|
-
hasCredentials: boolean;
|
|
6
15
|
busy: boolean;
|
|
7
16
|
disabled: boolean;
|
|
8
17
|
onBeginOffering?: (offering: AiProviderOffering, mode: AiConnectionsMode, method?: AiProviderAuthorizationMethod) => void;
|
|
@@ -2,17 +2,34 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Button } from '@undefineds.co/shared-ui';
|
|
3
3
|
import { ExternalLink, Loader2, Plus } from 'lucide-react';
|
|
4
4
|
import { connectModeForMethod, isLocalMethod, isOAuthMode } from './authorization-methods.js';
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* The offering's own entries, one button per declared `authorizationMethod`.
|
|
7
|
+
*
|
|
8
|
+
* A method that is implemented but unavailable in this deployment still gets its
|
|
9
|
+
* button, greyed at the same spec as its neighbours so the row keeps one line,
|
|
10
|
+
* with the reason as its tooltip. Nothing explains itself in a second row: the
|
|
11
|
+
* entry's own state is the message, and a list of internal reasons underneath
|
|
12
|
+
* the row reflows the buttons around it. Methods this build has not implemented
|
|
13
|
+
* never reach here - the server omits them.
|
|
14
|
+
*/
|
|
15
|
+
export function AiAuthorizationActions({ methods, offering, busy, disabled, onBeginOffering, onCreateLocalCredential, }) {
|
|
6
16
|
if (methods.length === 0)
|
|
7
17
|
return null;
|
|
8
|
-
return (_jsx("div", { className: "
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return (_jsxs(Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", title: "\u5BFC\u5165\u5F53\u524D\u8BBE\u5907\u5DF2\u6709\u767B\u5F55\u6001\uFF0C\u4E0D\u4F1A\u53D1\u8D77\u65B0\u7684\u6D4F\u89C8\u5668\u6388\u6743\u3002", disabled: busy || disabled || !onCreateLocalCredential, onClick: () => void onCreateLocalCredential?.(offering, method), children: [busy ? _jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : _jsx(Plus, { className: "h-3.5 w-3.5" }), method.label || '已有登录态'] }, method.id));
|
|
15
|
-
}
|
|
18
|
+
return (_jsx("div", { className: "flex flex-wrap gap-2", children: methods.map((method) => {
|
|
19
|
+
const connectMode = connectModeForMethod(method);
|
|
20
|
+
const unavailable = method.lifecycle === 'unavailable';
|
|
21
|
+
// An entry without a label is not one the offering asked for; the
|
|
22
|
+
// button is named by the method itself, never by a provider default.
|
|
23
|
+
if (!method.label)
|
|
16
24
|
return null;
|
|
17
|
-
|
|
25
|
+
if (isOAuthMode(connectMode)) {
|
|
26
|
+
return (_jsxs(Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", title: unavailable ? method.reason : undefined, disabled: busy || disabled || unavailable || !onBeginOffering, onClick: () => onBeginOffering?.(offering, connectMode, method), children: [busy ? _jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : _jsx(ExternalLink, { className: "h-3.5 w-3.5" }), method.label] }, method.id));
|
|
27
|
+
}
|
|
28
|
+
if (isLocalMethod(method)) {
|
|
29
|
+
return (_jsxs(Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", title: unavailable
|
|
30
|
+
? method.reason
|
|
31
|
+
: '导入当前设备已有登录态,不会发起新的浏览器授权。', disabled: busy || disabled || unavailable || !onCreateLocalCredential, onClick: () => void onCreateLocalCredential?.(offering, method), children: [busy ? _jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" }) : _jsx(Plus, { className: "h-3.5 w-3.5" }), method.label] }, method.id));
|
|
32
|
+
}
|
|
33
|
+
return null;
|
|
34
|
+
}) }));
|
|
18
35
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AiClientConfigurationModel } from '@undefineds.co/extension-sdk/web';
|
|
2
|
+
import { normalizeV1Endpoint } from './endpoint-urls';
|
|
2
3
|
export declare const AI_CONNECTIONS_CLIENTS: readonly ["codex", "claude-code", "pi", "codebuddy"];
|
|
3
4
|
export type AiConnectionsClientId = (typeof AI_CONNECTIONS_CLIENTS)[number];
|
|
4
5
|
export interface AiClientConfigurationStatus {
|
|
@@ -68,4 +69,10 @@ export declare function AiClientConfigurationSection({ bridge, endpoint, client,
|
|
|
68
69
|
compact?: boolean;
|
|
69
70
|
onComplete?: () => void;
|
|
70
71
|
}): import("react").JSX.Element;
|
|
72
|
+
/**
|
|
73
|
+
* The OpenAI-compatible base a client is pointed at, derived from the Xpod URL.
|
|
74
|
+
* The rule itself is shared with the client-config adapters, so what a copied
|
|
75
|
+
* config claims and what the adapters write cannot drift apart.
|
|
76
|
+
*/
|
|
77
|
+
export declare const openAiCompatibleBaseUrl: typeof normalizeV1Endpoint;
|
|
71
78
|
export declare function manualConfigurationText(client: AiConnectionsClientId, endpoint: string, apiKey?: string): string;
|
|
@@ -1,9 +1,11 @@
|
|
|
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 { RotateCcw, SquareTerminal } from 'lucide-react';
|
|
5
5
|
import { normalizeAiConnectionsThrownError } from './ai-connections-client.js';
|
|
6
6
|
import { getClientAvatar } from './client-visuals.js';
|
|
7
|
+
import { normalizeMessagesEndpoint, normalizeV1Endpoint } from './endpoint-urls.js';
|
|
8
|
+
import { AiCopyButton } from './AiCopyButton.js';
|
|
7
9
|
export const AI_CONNECTIONS_CLIENTS = ['codex', 'claude-code', 'pi', 'codebuddy'];
|
|
8
10
|
export const AI_CLIENT_LABELS = {
|
|
9
11
|
codex: 'Codex',
|
|
@@ -23,12 +25,10 @@ export function AiClientConfigurationSection({ bridge, endpoint, client, createC
|
|
|
23
25
|
const [dryRun, setDryRun] = useState();
|
|
24
26
|
const [confirmationValue, setConfirmationValue] = useState('');
|
|
25
27
|
const [busy, setBusy] = useState(false);
|
|
26
|
-
const [copiedManualConfig, setCopiedManualConfig] = useState(false);
|
|
27
28
|
const autoApplyStarted = useRef(false);
|
|
28
29
|
useEffect(() => {
|
|
29
30
|
setDryRun(undefined);
|
|
30
31
|
setConfirmationValue('');
|
|
31
|
-
setCopiedManualConfig(false);
|
|
32
32
|
if (!bridge) {
|
|
33
33
|
setStatus({ status: 'unavailable' });
|
|
34
34
|
return;
|
|
@@ -149,13 +149,10 @@ export function AiClientConfigurationSection({ bridge, endpoint, client, createC
|
|
|
149
149
|
const confirmationSatisfied = !confirmation?.required || confirmationValue === confirmation.token;
|
|
150
150
|
const clientLabel = AI_CLIENT_LABELS[client];
|
|
151
151
|
const manual = !bridge;
|
|
152
|
-
const
|
|
153
|
-
await navigator.clipboard?.writeText(manualConfigurationText(client, endpoint, manualApiKey));
|
|
154
|
-
setCopiedManualConfig(true);
|
|
155
|
-
};
|
|
152
|
+
const manualConfig = manualConfigurationText(client, endpoint, manualApiKey);
|
|
156
153
|
return (_jsxs("div", { className: compact ? '' : 'overflow-hidden rounded-md border border-border/60', children: [!compact ? _jsxs("div", { className: "flex flex-wrap items-center gap-2 px-3 py-2", children: [_jsx("span", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground", children: _jsx(AiClientIcon, { client: client }) }), _jsxs("div", { className: "min-w-[10rem] flex-1", children: [_jsx("div", { className: "text-sm font-medium", children: clientLabel }), !manual ? _jsx("div", { className: "mt-0.5 text-xs text-muted-foreground", children: status.message ?? (status.status === 'configured'
|
|
157
154
|
? `${clientLabel} 正在使用 Xpod。`
|
|
158
|
-
: '可自动写入本机配置。') }) : null] }), !manual ? _jsx(Badge, { variant: "secondary", children: statusLabel(status.status) }) : null, manual ? (
|
|
155
|
+
: '可自动写入本机配置。') }) : null] }), !manual ? _jsx(Badge, { variant: "secondary", children: statusLabel(status.status) }) : null, manual ? (_jsx(AiCopyButton, { value: manualConfig, label: `${clientLabel} 配置`, variant: "ghost", size: "icon", iconClassName: "h-4 w-4" })) : (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Button, { variant: "outline", size: "sm", "aria-label": `配置 ${clientLabel}`, disabled: busy, onClick: () => void plan(), children: "\u914D\u7F6E" }), _jsx(Button, { variant: "ghost", size: "icon", "aria-label": `恢复 ${clientLabel} 配置`, disabled: status.status === 'notConfigured' || busy, onClick: () => void restore(), children: _jsx(RotateCcw, { className: "h-4 w-4" }) })] }))] }) : null, compact && busy ? (_jsxs("div", { className: "py-1 text-xs text-muted-foreground", children: ["\u6B63\u5728\u5E94\u7528 ", clientLabel, " \u914D\u7F6E\u2026"] })) : null, compact && !busy && status.message ? (_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2 py-1 text-xs text-destructive", children: [_jsx("span", { children: status.message }), _jsx(Button, { variant: "outline", size: "sm", onClick: () => void plan(), children: "\u91CD\u8BD5\u5E94\u7528\u914D\u7F6E" })] })) : null, dryRun ? (_jsxs("div", { className: "space-y-3 border-t border-border/60 bg-muted/20 px-4 py-3", children: [_jsx("div", { className: "text-xs font-medium", children: "\u5C06\u6267\u884C\u4EE5\u4E0B\u66F4\u6539" }), dryRun.changes.map((change) => (_jsxs("div", { className: "text-xs text-muted-foreground", children: [_jsx("span", { className: "font-mono", children: change.target }), ' · ', changeActionLabel(change.action), change.backup ? ' · 创建备份' : ''] }, `${change.target}:${change.action}`))), confirmation?.required ? (_jsxs("div", { className: "space-y-2", children: [confirmation.message ? _jsx("div", { className: "text-xs text-muted-foreground", children: confirmation.message }) : null, _jsxs("div", { className: "text-xs text-muted-foreground", children: ["\u786E\u8BA4\u7801\uFF1A", _jsx("code", { className: "font-mono text-foreground", children: confirmation.token })] }), _jsx(Input, { "aria-label": `输入确认码以应用 ${clientLabel} 配置`, value: confirmationValue, onChange: (event) => setConfirmationValue(event.target.value) })] })) : null, _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { size: "sm", "aria-label": confirmation?.required
|
|
159
156
|
? `确认并应用 ${clientLabel} 配置`
|
|
160
157
|
: `应用 ${clientLabel} 配置`, disabled: !createClientCredential || busy || !confirmationSatisfied, onClick: () => void apply(), children: confirmation?.required ? '确认并应用' : '应用配置' }), _jsx(Button, { variant: "ghost", size: "sm", disabled: busy, onClick: () => {
|
|
161
158
|
setDryRun(undefined);
|
|
@@ -179,11 +176,16 @@ function statusLabel(status) {
|
|
|
179
176
|
default: return '未配置';
|
|
180
177
|
}
|
|
181
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* The OpenAI-compatible base a client is pointed at, derived from the Xpod URL.
|
|
181
|
+
* The rule itself is shared with the client-config adapters, so what a copied
|
|
182
|
+
* config claims and what the adapters write cannot drift apart.
|
|
183
|
+
*/
|
|
184
|
+
export const openAiCompatibleBaseUrl = normalizeV1Endpoint;
|
|
182
185
|
export function manualConfigurationText(client, endpoint, apiKey) {
|
|
183
186
|
const secret = apiKey ?? '<粘贴 Xpod API Key>';
|
|
184
|
-
const
|
|
185
|
-
const
|
|
186
|
-
const messagesUrl = baseUrl.replace(/\/v1$/, '');
|
|
187
|
+
const v1Url = normalizeV1Endpoint(endpoint);
|
|
188
|
+
const messagesUrl = normalizeMessagesEndpoint(endpoint);
|
|
187
189
|
switch (client) {
|
|
188
190
|
case 'codex':
|
|
189
191
|
return [
|
|
@@ -33,7 +33,7 @@ export function AiConnectDialog({ controller, definition, offerings, apiOffering
|
|
|
33
33
|
const authorizationError = error?.offeringId === offering.id ? error.authorization : undefined;
|
|
34
34
|
const attemptedMethod = methods.find((method) => method.id === (authorizationError?.authorizationMethodId ?? offeringAttempt?.authorizationMethodId))
|
|
35
35
|
?? activeMethods.find(isOAuthMethod);
|
|
36
|
-
const attemptedMode = authorizationError?.mode ?? offeringAttempt?.mode ?? (attemptedMethod ? connectModeForMethod(attemptedMethod) : modeForOffering(offering
|
|
36
|
+
const attemptedMode = authorizationError?.mode ?? offeringAttempt?.mode ?? (attemptedMethod ? connectModeForMethod(attemptedMethod) : modeForOffering(offering));
|
|
37
37
|
const offeringError = error?.offeringId === offering.id ? error.message : undefined;
|
|
38
38
|
if (offering.lifecycle === 'unavailable' && activeMethods.length === 0) {
|
|
39
39
|
return _jsxs("fieldset", { "data-create-offering": offering.id, className: "space-y-2 border-t border-border/50 pt-3 first:border-t-0 first:pt-0", children: [_jsx("legend", { className: "px-1 text-sm font-medium", children: offeringTitle(offering) }), _jsx("p", { className: "text-xs text-muted-foreground", children: offering.kind === 'oauth-subscription'
|
|
@@ -2,9 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useContext, useRef } from 'react';
|
|
3
3
|
import { Avatar, AvatarFallback, AvatarImage, cn } from '@undefineds.co/shared-ui';
|
|
4
4
|
import { WorkspaceLayoutContext } from '@undefineds.co/extension-sdk/react';
|
|
5
|
-
import { getProviderAvatar, getProviderAvatarBackground } from './provider-visuals.js';
|
|
6
|
-
import { AI_CONNECTIONS_PINNED_SECTIONS, PROVIDERS, useProviderLoadError, useProviderProducts, useProviderSearch, useProviderStates, useSelectedCredentialId, useSelectedProvider, useSelectedSection, } from './controller.js';
|
|
5
|
+
import { XPOD_AVATAR, getProviderAvatar, getProviderAvatarBackground } from './provider-visuals.js';
|
|
6
|
+
import { AI_CONNECTIONS_PINNED_SECTIONS, PROVIDERS, useAvailableProviders, useProviderLoadError, useProviderProducts, useProviderSearch, useProviderStates, useSelectedCredentialId, useSelectedProvider, useSelectedSection, } from './controller.js';
|
|
7
7
|
export function AiConnectionsList({ controller }) {
|
|
8
|
+
const availableProviders = useAvailableProviders(controller);
|
|
8
9
|
const workspace = useContext(WorkspaceLayoutContext);
|
|
9
10
|
const selectedSection = useSelectedSection(controller);
|
|
10
11
|
const selectedProvider = useSelectedProvider(controller);
|
|
@@ -13,7 +14,10 @@ export function AiConnectionsList({ controller }) {
|
|
|
13
14
|
const providerStates = useProviderStates(controller);
|
|
14
15
|
const providerProducts = useProviderProducts(controller);
|
|
15
16
|
const providerLoadError = useProviderLoadError(controller);
|
|
16
|
-
const
|
|
17
|
+
const visibleProviders = availableProviders
|
|
18
|
+
? PROVIDERS.filter((provider) => availableProviders.includes(provider.id))
|
|
19
|
+
: PROVIDERS;
|
|
20
|
+
const providerItems = visibleProviders.reduce((items, provider) => {
|
|
17
21
|
if (provider.id !== 'custom')
|
|
18
22
|
return [...items, { ...provider }];
|
|
19
23
|
const credentials = providerProducts.custom?.credentials ?? [];
|
|
@@ -86,11 +90,11 @@ function moveSelection(items, requestedIndex, controller, optionRefs) {
|
|
|
86
90
|
}
|
|
87
91
|
/**
|
|
88
92
|
* The pinned section is an issued-credential surface, i.e. another provider from
|
|
89
|
-
* the client's point of view, so it
|
|
90
|
-
*
|
|
93
|
+
* the client's point of view, so it carries the Xpod provider mark and falls
|
|
94
|
+
* back to its initials only while that mark is unavailable.
|
|
91
95
|
*/
|
|
92
96
|
function PinnedMark({ section: _section }) {
|
|
93
|
-
return (
|
|
97
|
+
return (_jsxs(Avatar, { className: "h-9 w-9 shrink-0 rounded-md border border-border/20", children: [_jsx(AvatarImage, { src: XPOD_AVATAR, className: "object-cover" }), _jsx(AvatarFallback, { className: "rounded-md bg-muted text-[10px] font-bold uppercase text-muted-foreground", children: "XP" })] }));
|
|
94
98
|
}
|
|
95
99
|
function ProviderStateIndicator({ state, statusId, }) {
|
|
96
100
|
const active = state === 'configured' || state === 'connected';
|
|
@@ -1,4 +1,19 @@
|
|
|
1
1
|
import { type AiConnectionsController } from './controller';
|
|
2
|
+
/**
|
|
3
|
+
* The page's live credentials table.
|
|
4
|
+
*
|
|
5
|
+
* `useCredentialRows` subscribes to the controller's snapshot of the collection:
|
|
6
|
+
* the rows it returns already include optimistic writes, so a create/update/
|
|
7
|
+
* delete shows before the Pod has confirmed it, and the projection diff keeps
|
|
8
|
+
* unchanged rows identical. Both the table and the layer that reads it are
|
|
9
|
+
* loaded lazily, so this hook is a plain `useSyncExternalStore` over whatever the
|
|
10
|
+
* controller has - which is nothing until the collection's first read lands.
|
|
11
|
+
*
|
|
12
|
+
* Until then - while the layer is still loading, after a failed first read, or
|
|
13
|
+
* when the host offers no collection at all - `credentialRows` stays undefined
|
|
14
|
+
* and the page keeps rendering what the store reported, so a table that cannot
|
|
15
|
+
* load is never shown as an empty table.
|
|
16
|
+
*/
|
|
2
17
|
export declare function AiConnectionsMain({ controller, renderToaster }: {
|
|
3
18
|
controller: AiConnectionsController;
|
|
4
19
|
renderToaster?: boolean;
|