@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.
Files changed (402) hide show
  1. package/config/components-ignore.json +5 -1
  2. package/config/notifications.json +68 -0
  3. package/config/xpod.base.json +9 -11
  4. package/dist/ai/service/AiCredentialSecret.d.ts +30 -0
  5. package/dist/ai/service/AiCredentialSecret.js +120 -0
  6. package/dist/ai/service/CredentialReaderImpl.d.ts +18 -0
  7. package/dist/ai/service/CredentialReaderImpl.js +81 -5
  8. package/dist/ai/service/CredentialReaderImpl.jsonld +42 -2
  9. package/dist/ai/service/EmbeddingModelPolicy.d.ts +79 -0
  10. package/dist/ai/service/EmbeddingModelPolicy.js +134 -0
  11. package/dist/ai/service/EmbeddingProviderError.js +6 -0
  12. package/dist/ai/service/EmbeddingServiceImpl.d.ts +13 -1
  13. package/dist/ai/service/EmbeddingServiceImpl.js +18 -5
  14. package/dist/ai/service/EmbeddingServiceImpl.jsonld +35 -0
  15. package/dist/ai/service/index.d.ts +2 -0
  16. package/dist/ai/service/index.js +2 -0
  17. package/dist/api/ai-gateway/connect/index.d.ts +20 -2
  18. package/dist/api/ai-gateway/connect/index.js +162 -16
  19. package/dist/api/ai-gateway/credentials/AiCredentialSecretDecoder.d.ts +12 -0
  20. package/dist/api/ai-gateway/credentials/AiCredentialSecretDecoder.js +30 -0
  21. package/dist/api/ai-gateway/errors.d.ts +1 -1
  22. package/dist/api/ai-gateway/models/GatewayEmbeddingModelCatalog.d.ts +11 -0
  23. package/dist/api/ai-gateway/models/GatewayEmbeddingModelCatalog.js +31 -0
  24. package/dist/api/ai-gateway/models/PodModelSelectionRepository.js +7 -3
  25. package/dist/api/ai-gateway/models/ProviderCustomModelsService.d.ts +18 -0
  26. package/dist/api/ai-gateway/models/ProviderCustomModelsService.js +23 -0
  27. package/dist/api/ai-gateway/models/ProviderModelDiscoveryAdapters.d.ts +3 -1
  28. package/dist/api/ai-gateway/models/ProviderModelDiscoveryAdapters.js +2 -45
  29. package/dist/api/ai-gateway/models/ProviderModelSelectionService.d.ts +10 -0
  30. package/dist/api/ai-gateway/models/ProviderModelSelectionService.js +57 -20
  31. package/dist/api/ai-gateway/models/ProviderModelType.d.ts +28 -0
  32. package/dist/api/ai-gateway/models/ProviderModelType.js +34 -0
  33. package/dist/api/ai-gateway/models/ProviderModelsAdapter.d.ts +10 -0
  34. package/dist/api/ai-gateway/models/ProviderModelsAdapter.js +3 -4
  35. package/dist/api/ai-gateway/models/index.d.ts +1 -0
  36. package/dist/api/ai-gateway/models/index.js +3 -1
  37. package/dist/api/ai-gateway/providers/CustomRuntimeAdapter.d.ts +7 -0
  38. package/dist/api/ai-gateway/providers/CustomRuntimeAdapter.js +9 -2
  39. package/dist/api/ai-gateway/providers/ModelsDevCatalog.d.ts +7 -1
  40. package/dist/api/ai-gateway/providers/ModelsDevCatalog.js +4 -10
  41. package/dist/api/ai-gateway/providers/ProviderRegistry.d.ts +107 -0
  42. package/dist/api/ai-gateway/providers/ProviderRegistry.js +244 -21
  43. package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.d.ts +5 -0
  44. package/dist/api/ai-gateway/providers/ProviderRuntimeRegistry.js +5 -1
  45. package/dist/api/ai-gateway/quota/SubscriptionQuotaAdapters.d.ts +12 -4
  46. package/dist/api/ai-gateway/quota/SubscriptionQuotaAdapters.js +11 -11
  47. package/dist/api/ai-gateway/routing/ModelRouter.d.ts +14 -0
  48. package/dist/api/ai-gateway/routing/ModelRouter.js +43 -4
  49. package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.d.ts +9 -1
  50. package/dist/api/ai-gateway/service-access/AiConnectionsServiceAccess.js +3 -27
  51. package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +0 -1
  52. package/dist/api/auth/ClientCredentialsAuthenticator.js +0 -3
  53. package/dist/api/auth/index.d.ts +1 -0
  54. package/dist/api/auth/index.js +1 -1
  55. package/dist/api/chatkit/pod-store.d.ts +31 -0
  56. package/dist/api/chatkit/pod-store.js +132 -8
  57. package/dist/api/container/common.js +24 -4
  58. package/dist/api/container/routes.js +17 -2
  59. package/dist/api/container/types.d.ts +3 -1
  60. package/dist/api/handlers/AdminHandler.d.ts +13 -0
  61. package/dist/api/handlers/AdminHandler.js +47 -18
  62. package/dist/api/handlers/AiConfigHandler.d.ts +6 -0
  63. package/dist/api/handlers/AiConfigHandler.js +28 -0
  64. package/dist/api/handlers/AiGatewayManagementHandler.js +36 -0
  65. package/dist/api/runs/RdfRunContextRetriever.d.ts +14 -0
  66. package/dist/api/runs/RdfRunContextRetriever.js +41 -5
  67. package/dist/api/runtime.js +2 -1
  68. package/dist/cli/commands/secret.d.ts +1 -0
  69. package/dist/cli/commands/secret.js +25 -7
  70. package/dist/components/components.jsonld +3 -1
  71. package/dist/components/context.jsonld +53 -1
  72. package/dist/http/SubgraphSparqlHttpHandler.d.ts +59 -2
  73. package/dist/http/SubgraphSparqlHttpHandler.js +145 -13
  74. package/dist/http/SubgraphSparqlHttpHandler.jsonld +37 -0
  75. package/dist/identity/drizzle/AccountRoleRepository.d.ts +30 -2
  76. package/dist/identity/drizzle/AccountRoleRepository.js +163 -15
  77. package/dist/identity/drizzle/EdgeNodeRepository.d.ts +0 -12
  78. package/dist/identity/drizzle/EdgeNodeRepository.js +5 -13
  79. package/dist/identity/drizzle/PodLookupRepository.d.ts +58 -4
  80. package/dist/identity/drizzle/PodLookupRepository.js +248 -105
  81. package/dist/identity/drizzle/db.d.ts +19 -0
  82. package/dist/identity/drizzle/db.js +39 -4
  83. package/dist/index.d.ts +2 -1
  84. package/dist/index.js +7 -3
  85. package/dist/logging/log-file.d.ts +17 -0
  86. package/dist/logging/log-file.js +69 -0
  87. package/dist/main.js +2 -1
  88. package/dist/notifications/NotificationChannelSweeper.d.ts +50 -0
  89. package/dist/notifications/NotificationChannelSweeper.js +131 -0
  90. package/dist/notifications/NotificationChannelSweeper.jsonld +136 -0
  91. package/dist/notifications/ReclaimingWebSocket2023Storer.d.ts +25 -0
  92. package/dist/notifications/ReclaimingWebSocket2023Storer.js +56 -0
  93. package/dist/notifications/ReclaimingWebSocket2023Storer.jsonld +77 -0
  94. package/dist/notifications/index.d.ts +2 -0
  95. package/dist/notifications/index.js +2 -0
  96. package/dist/runtime/Proxy.d.ts +37 -0
  97. package/dist/runtime/Proxy.js +88 -16
  98. package/dist/runtime/bootstrap.js +2 -1
  99. package/dist/runtime/upgrade/BunNativeUpgradeRelay.d.ts +116 -0
  100. package/dist/runtime/upgrade/BunNativeUpgradeRelay.js +423 -0
  101. package/dist/runtime/upgrade/UpgradeHandshake.d.ts +63 -0
  102. package/dist/runtime/upgrade/UpgradeHandshake.js +199 -0
  103. package/dist/runtime/upgrade/WebSocketFrames.d.ts +67 -0
  104. package/dist/runtime/upgrade/WebSocketFrames.js +224 -0
  105. package/node_modules/@undefineds.co/ai-connections/dist/AiApiKeyPool.js +8 -1
  106. package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.d.ts +11 -2
  107. package/node_modules/@undefineds.co/ai-connections/dist/AiAuthorizationActions.js +27 -10
  108. package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.d.ts +7 -0
  109. package/node_modules/@undefineds.co/ai-connections/dist/AiClientConfigurationSection.js +13 -11
  110. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectDialog.js +1 -1
  111. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsList.js +10 -6
  112. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.d.ts +15 -0
  113. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMain.js +29 -3
  114. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsMainHeader.js +18 -3
  115. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.d.ts +16 -1
  116. package/node_modules/@undefineds.co/ai-connections/dist/AiConnectionsPanel.js +92 -20
  117. package/node_modules/@undefineds.co/ai-connections/dist/AiCopyButton.d.ts +35 -0
  118. package/node_modules/@undefineds.co/ai-connections/dist/AiCopyButton.js +45 -0
  119. package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialPoolSection.js +71 -11
  120. package/node_modules/@undefineds.co/ai-connections/dist/AiCredentialRow.js +9 -7
  121. package/node_modules/@undefineds.co/ai-connections/dist/AiEndpointList.d.ts +23 -0
  122. package/node_modules/@undefineds.co/ai-connections/dist/AiEndpointList.js +24 -0
  123. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.d.ts +13 -4
  124. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayKeysSection.js +35 -38
  125. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.d.ts +21 -0
  126. package/node_modules/@undefineds.co/ai-connections/dist/AiGatewayModelsSection.js +51 -0
  127. package/node_modules/@undefineds.co/ai-connections/dist/AiInfoTooltip.d.ts +15 -0
  128. package/node_modules/@undefineds.co/ai-connections/dist/AiInfoTooltip.js +16 -0
  129. package/node_modules/@undefineds.co/ai-connections/dist/AiModelCatalog.d.ts +175 -0
  130. package/node_modules/@undefineds.co/ai-connections/dist/AiModelCatalog.js +133 -0
  131. package/node_modules/@undefineds.co/ai-connections/dist/AiOfferingDetails.js +2 -2
  132. package/node_modules/@undefineds.co/ai-connections/dist/AiProviderCard.js +13 -64
  133. package/node_modules/@undefineds.co/ai-connections/dist/AiProviderHeader.d.ts +21 -0
  134. package/node_modules/@undefineds.co/ai-connections/dist/AiProviderHeader.js +12 -0
  135. package/node_modules/@undefineds.co/ai-connections/dist/AiRowAction.d.ts +15 -0
  136. package/node_modules/@undefineds.co/ai-connections/dist/AiRowAction.js +12 -0
  137. package/node_modules/@undefineds.co/ai-connections/dist/AiSortableCredentialList.js +2 -1
  138. package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.d.ts +7 -0
  139. package/node_modules/@undefineds.co/ai-connections/dist/ai-connections-client.js +6 -0
  140. package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.d.ts +36 -5
  141. package/node_modules/@undefineds.co/ai-connections/dist/authorization-methods.js +52 -9
  142. package/node_modules/@undefineds.co/ai-connections/dist/client/normalize.js +30 -3
  143. package/node_modules/@undefineds.co/ai-connections/dist/client/types.d.ts +21 -1
  144. package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.d.ts +1 -3
  145. package/node_modules/@undefineds.co/ai-connections/dist/client-config/base-adapter.js +3 -7
  146. package/node_modules/@undefineds.co/ai-connections/dist/client-config/index.cjs +9 -7
  147. package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.d.ts +46 -0
  148. package/node_modules/@undefineds.co/ai-connections/dist/collection-runtime.js +231 -0
  149. package/node_modules/@undefineds.co/ai-connections/dist/collections.d.ts +119 -0
  150. package/node_modules/@undefineds.co/ai-connections/dist/collections.js +173 -0
  151. package/node_modules/@undefineds.co/ai-connections/dist/controller.d.ts +71 -5
  152. package/node_modules/@undefineds.co/ai-connections/dist/controller.js +285 -16
  153. package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.d.ts +5 -0
  154. package/node_modules/@undefineds.co/ai-connections/dist/credential-labels.js +8 -3
  155. package/node_modules/@undefineds.co/ai-connections/dist/credential-storage.d.ts +59 -0
  156. package/node_modules/@undefineds.co/ai-connections/dist/credential-storage.js +131 -0
  157. package/node_modules/@undefineds.co/ai-connections/dist/endpoint-urls.d.ts +15 -0
  158. package/node_modules/@undefineds.co/ai-connections/dist/endpoint-urls.js +20 -0
  159. package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.d.ts +14 -0
  160. package/node_modules/@undefineds.co/ai-connections/dist/gateway-endpoints.js +20 -0
  161. package/node_modules/@undefineds.co/ai-connections/dist/index.d.ts +8 -0
  162. package/node_modules/@undefineds.co/ai-connections/dist/index.js +8 -0
  163. package/node_modules/@undefineds.co/ai-connections/dist/manifest.js +1 -1
  164. package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.d.ts +14 -0
  165. package/node_modules/@undefineds.co/ai-connections/dist/offering-endpoints.js +17 -0
  166. package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.cjs +68 -1
  167. package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.d.ts +75 -1
  168. package/node_modules/@undefineds.co/ai-connections/dist/provider-catalog.js +119 -0
  169. package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.d.ts +5 -0
  170. package/node_modules/@undefineds.co/ai-connections/dist/provider-visuals.js +5 -0
  171. package/node_modules/@undefineds.co/ai-connections/dist/service-access.js +2 -27
  172. package/node_modules/@undefineds.co/ai-connections/package.json +1 -0
  173. package/node_modules/@undefineds.co/extension-sdk/dist/manifest.d.ts +1 -1
  174. package/node_modules/@undefineds.co/extension-sdk/dist/manifest.js +2 -0
  175. package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +150 -0
  176. package/node_modules/@undefineds.co/extension-sdk/package.json +2 -1
  177. package/node_modules/@undefineds.co/models/README.md +1 -1
  178. package/node_modules/@undefineds.co/models/dist/ai-config/index.d.ts +3 -3
  179. package/node_modules/@undefineds.co/models/dist/ai-gateway.schema.d.ts +5 -0
  180. package/node_modules/@undefineds.co/models/dist/ai-gateway.schema.js +9 -0
  181. package/node_modules/@undefineds.co/models/dist/ai-runtime.repository.d.ts +1 -1
  182. package/node_modules/@undefineds.co/models/dist/approval.repository.d.ts +2 -2
  183. package/node_modules/@undefineds.co/models/dist/audit.presentation.d.ts +2 -2
  184. package/node_modules/@undefineds.co/models/dist/capture.repository.d.ts +1 -1
  185. package/node_modules/@undefineds.co/models/dist/chat-project.repository.d.ts +1 -1
  186. package/node_modules/@undefineds.co/models/dist/chat.repository.d.ts +2 -2
  187. package/node_modules/@undefineds.co/models/dist/control-request.repository.d.ts +2 -2
  188. package/node_modules/@undefineds.co/models/dist/conversation-share.repository.d.ts +1 -1
  189. package/node_modules/@undefineds.co/models/dist/credential.schema.d.ts +12 -0
  190. package/node_modules/@undefineds.co/models/dist/credential.schema.js +15 -1
  191. package/node_modules/@undefineds.co/models/dist/discovery/index.d.ts +2 -2
  192. package/node_modules/@undefineds.co/models/dist/discovery/providers.json +248 -7
  193. package/node_modules/@undefineds.co/models/dist/discovery/types.d.ts +31 -0
  194. package/node_modules/@undefineds.co/models/dist/extension/index.d.ts +1 -1
  195. package/node_modules/@undefineds.co/models/dist/favorite/index.d.ts +2 -2
  196. package/node_modules/@undefineds.co/models/dist/fixtures/contracts-chat-contact.d.ts +5 -5
  197. package/node_modules/@undefineds.co/models/dist/import/index.d.ts +1 -1
  198. package/node_modules/@undefineds.co/models/dist/index.d.ts +73 -73
  199. package/node_modules/@undefineds.co/models/dist/index.js +1 -1
  200. package/node_modules/@undefineds.co/models/dist/input-request.repository.d.ts +2 -2
  201. package/node_modules/@undefineds.co/models/dist/knowledge/index.d.ts +1 -1
  202. package/node_modules/@undefineds.co/models/dist/message.repository.d.ts +1 -1
  203. package/node_modules/@undefineds.co/models/dist/namespaces.js +5 -0
  204. package/node_modules/@undefineds.co/models/dist/pod-storage-descriptor.d.ts +4815 -26
  205. package/node_modules/@undefineds.co/models/dist/pod-storage-descriptor.js +482 -132
  206. package/node_modules/@undefineds.co/models/dist/schema.d.ts +4 -0
  207. package/node_modules/@undefineds.co/models/dist/session/index.d.ts +1 -1
  208. package/node_modules/@undefineds.co/models/dist/settings/index.d.ts +1 -1
  209. package/node_modules/@undefineds.co/models/dist/sidecar/persistence-mapping.d.ts +5 -5
  210. package/node_modules/@undefineds.co/models/dist/thread.repository.d.ts +2 -2
  211. package/node_modules/@undefineds.co/models/dist/types/message-block.d.ts +1 -1
  212. package/node_modules/@undefineds.co/models/dist/vocab/_namespaces.d.ts +1 -1
  213. package/node_modules/@undefineds.co/models/dist/vocab/index.d.ts +10 -10
  214. package/node_modules/@undefineds.co/models/dist/vocab/sidecar.vocab.d.ts +1 -0
  215. package/node_modules/@undefineds.co/models/dist/vocab/sidecar.vocab.js +1 -0
  216. package/node_modules/@undefineds.co/models/package.json +4 -2
  217. package/node_modules/@undefineds.co/pod-collections/README.md +71 -0
  218. package/node_modules/@undefineds.co/pod-collections/dist/diff.d.ts +85 -0
  219. package/node_modules/@undefineds.co/pod-collections/dist/diff.js +166 -0
  220. package/node_modules/@undefineds.co/pod-collections/dist/feed.d.ts +17 -0
  221. package/node_modules/@undefineds.co/pod-collections/dist/feed.js +27 -0
  222. package/node_modules/@undefineds.co/pod-collections/dist/index.cjs +1042 -0
  223. package/node_modules/@undefineds.co/pod-collections/dist/index.d.ts +37 -0
  224. package/node_modules/@undefineds.co/pod-collections/dist/index.js +89 -0
  225. package/node_modules/@undefineds.co/pod-collections/dist/layout.d.ts +75 -0
  226. package/node_modules/@undefineds.co/pod-collections/dist/layout.js +173 -0
  227. package/node_modules/@undefineds.co/pod-collections/dist/mapping.d.ts +78 -0
  228. package/node_modules/@undefineds.co/pod-collections/dist/mapping.js +287 -0
  229. package/node_modules/@undefineds.co/pod-collections/dist/mutations.d.ts +83 -0
  230. package/node_modules/@undefineds.co/pod-collections/dist/mutations.js +273 -0
  231. package/node_modules/@undefineds.co/pod-collections/dist/react.d.ts +21 -0
  232. package/node_modules/@undefineds.co/pod-collections/dist/react.js +22 -0
  233. package/node_modules/@undefineds.co/pod-collections/dist/read.d.ts +65 -0
  234. package/node_modules/@undefineds.co/pod-collections/dist/read.js +31 -0
  235. package/node_modules/@undefineds.co/pod-collections/dist/sync.d.ts +66 -0
  236. package/node_modules/@undefineds.co/pod-collections/dist/sync.js +260 -0
  237. package/node_modules/@undefineds.co/pod-collections/dist/types.d.ts +155 -0
  238. package/node_modules/@undefineds.co/pod-collections/dist/types.js +9 -0
  239. package/node_modules/@undefineds.co/pod-collections/package.json +42 -0
  240. package/node_modules/@undefineds.co/shared-ui/dist/index.d.ts +0 -1
  241. package/node_modules/@undefineds.co/shared-ui/dist/index.js +0 -1
  242. package/package.json +15 -7
  243. package/static/app/assets/main.css +1 -1
  244. package/static/app/assets/main.js +12 -13
  245. package/static/auth-callback/assets/AiConfigContext-DnQs1ZpW.js +1 -0
  246. package/static/auth-callback/assets/AiConfigPage-DOtvlxH0.js +1 -0
  247. package/static/auth-callback/assets/DocumentProcessingPanel-BS2voQgL.js +1 -0
  248. package/static/auth-callback/assets/IndexLifecyclePanel-Cvt0cJtN.js +1 -0
  249. package/static/auth-callback/assets/{IndexSubjectPanel-C4YG0whI.js → IndexSubjectPanel-Dhf01GqF.js} +1 -1
  250. package/static/auth-callback/assets/ModelAssignmentsPanel-BJutWaAF.js +1 -0
  251. package/static/auth-callback/assets/ModelsPage-BRS0sje3.js +11 -0
  252. package/static/auth-callback/assets/{NetworkPage-Cbdn_P1e.js → NetworkPage-B3qBfANA.js} +2 -2
  253. package/static/auth-callback/assets/{PaneListHeader-jy70Q00L.js → PaneListHeader-QQeJGTp4.js} +1 -1
  254. package/static/auth-callback/assets/SearchIndexingPanel-MyNUSEwT.js +1 -0
  255. package/static/auth-callback/assets/{StatusSubjectPanel-hfjoB5aS.js → StatusSubjectPanel-DQkEVsFs.js} +1 -1
  256. package/static/{settings/assets/StatusWorkspace-CKD_Rzdr.js → auth-callback/assets/StatusWorkspace-Dkv63Uwk.js} +1 -1
  257. package/static/auth-callback/assets/SystemSettingsPage-TIsUfX5d.js +1 -0
  258. package/static/auth-callback/assets/SystemSettingsSubjectPanel-BJWEt2-7.js +33 -0
  259. package/static/auth-callback/assets/XpodAiConnectionsPodStore-BJiXm-PF.js +3 -0
  260. package/static/auth-callback/assets/{activity-BcsZZxxw.js → activity-5hNeNKnL.js} +1 -1
  261. package/static/auth-callback/assets/admin-C6qCRFiY.js +1 -0
  262. package/static/auth-callback/assets/ai-connections-CryuHGKW.js +1 -0
  263. package/static/auth-callback/assets/{auth-callback-atKg_oig.js → auth-callback-CAFZ3R0B.js} +80 -84
  264. package/static/auth-callback/assets/auth-callback-rk080mvG.css +1 -0
  265. package/static/auth-callback/assets/{badge-BWbRHThQ.js → badge-CAIPI0CB.js} +1 -1
  266. package/static/auth-callback/assets/collection-runtime-D9s7h9YA.js +1 -0
  267. package/static/auth-callback/assets/dialog-BjA109aX.js +1 -0
  268. package/static/auth-callback/assets/{download-BmvG1Vya.js → download-B3Up5W2G.js} +1 -1
  269. package/static/auth-callback/assets/{external-link-DZ34d3g3.js → external-link-BTXgSPzB.js} +1 -1
  270. package/static/auth-callback/assets/index-BppXlxcp.js +41 -0
  271. package/static/auth-callback/assets/index-CirW4CJf.js +1 -0
  272. package/static/auth-callback/assets/index-DlLYWOhw.js +4 -0
  273. package/static/auth-callback/assets/{index-browser-B9Z7GU-T.js → index-browser-DtU38ni3.js} +1 -1
  274. package/static/auth-callback/assets/{key-round-tjP76Se-.js → key-round-CQCOrZ7x.js} +1 -1
  275. package/static/auth-callback/assets/layout-DB3pMyTl.js +1 -0
  276. package/static/auth-callback/assets/pod-collections-host-KnnGFZHL.js +8 -0
  277. package/static/auth-callback/assets/{rotate-ccw-C_L5ZLx1.js → rotate-ccw-C1zM2KtS.js} +1 -1
  278. package/static/auth-callback/assets/settings-projection-CUkyprDQ.js +1 -0
  279. package/static/auth-callback/assets/{skeleton-C7tGDQIs.js → skeleton-Cqp7_M9-.js} +1 -1
  280. package/static/auth-callback/assets/{waypoints-VMNQlWdU.js → waypoints-Bj6gAUSQ.js} +1 -1
  281. package/static/auth-callback/assets/{workspace-layout-SAp6BtYK.js → workspace-layout-DK8mDzrY.js} +1 -1
  282. package/static/auth-callback/auth-callback.html +2 -2
  283. package/static/dashboard/assets/AiConfigContext-BsE7MqX8.js +1 -0
  284. package/static/dashboard/assets/AiConfigPage-DvM-lRXa.js +1 -0
  285. package/static/dashboard/assets/DocumentProcessingPanel-BPfdlfuf.js +1 -0
  286. package/static/dashboard/assets/IndexLifecyclePanel--m0AGxvh.js +1 -0
  287. package/static/dashboard/assets/{IndexSubjectPanel-DQFPP6-p.js → IndexSubjectPanel-Bb7m1k3d.js} +1 -1
  288. package/static/dashboard/assets/ModelAssignmentsPanel-BLi_zbMa.js +1 -0
  289. package/static/dashboard/assets/ModelsPage-CxdpgnfR.js +11 -0
  290. package/static/dashboard/assets/{NetworkPage-CHQ3YxIB.js → NetworkPage-BAIPw-D_.js} +2 -2
  291. package/static/dashboard/assets/{PaneListHeader-DsXemAdR.js → PaneListHeader-BBCMei0r.js} +1 -1
  292. package/static/dashboard/assets/SearchIndexingPanel-Ck4Y-xjR.js +1 -0
  293. package/static/dashboard/assets/{StatusSubjectPanel-D3PGEYT4.js → StatusSubjectPanel-D1KWfAXE.js} +1 -1
  294. package/static/dashboard/assets/{StatusWorkspace-BcpePYUW.js → StatusWorkspace-JbA5gzXx.js} +1 -1
  295. package/static/dashboard/assets/SystemSettingsPage-BbwQWsSR.js +1 -0
  296. package/static/dashboard/assets/SystemSettingsSubjectPanel-N117nMt5.js +33 -0
  297. package/static/dashboard/assets/XpodAiConnectionsPodStore-CdDOb4SV.js +18 -0
  298. package/static/dashboard/assets/{activity-j5zrznu-.js → activity-DX1I96o_.js} +1 -1
  299. package/static/dashboard/assets/admin-C6qCRFiY.js +1 -0
  300. package/static/dashboard/assets/ai-connections-DwCRqOQa.js +1 -0
  301. package/static/dashboard/assets/{badge-CzeBdG7h.js → badge-k2vhtDqH.js} +1 -1
  302. package/static/dashboard/assets/collection-runtime-BFQ8teQJ.js +1 -0
  303. package/static/dashboard/assets/{dashboard-D-xANHk1.js → dashboard-DWZ-fmCT.js} +105 -109
  304. package/static/dashboard/assets/dashboard-rk080mvG.css +1 -0
  305. package/static/dashboard/assets/dialog-1CCw-iHT.js +1 -0
  306. package/static/dashboard/assets/{download-IcNdEZWi.js → download-C6-SNY1q.js} +1 -1
  307. package/static/dashboard/assets/{external-link-DxBxK8Vu.js → external-link-BgPcZ_j2.js} +1 -1
  308. package/static/dashboard/assets/index-6LcIUIYO.js +1 -0
  309. package/static/dashboard/assets/index-D7A8U6Pt.js +41 -0
  310. package/static/dashboard/assets/index-UD6QOE7H.js +4 -0
  311. package/static/dashboard/assets/{key-round-D1K7warM.js → key-round-BOd7Jo0Q.js} +1 -1
  312. package/static/dashboard/assets/layout-DB3pMyTl.js +1 -0
  313. package/static/dashboard/assets/pod-collections-host-KnnGFZHL.js +8 -0
  314. package/static/dashboard/assets/{rotate-ccw-CcN1N6p9.js → rotate-ccw-CCgJqsvx.js} +1 -1
  315. package/static/dashboard/assets/settings-projection-CUkyprDQ.js +1 -0
  316. package/static/dashboard/assets/{skeleton-CKnmJMUH.js → skeleton-Bc7abAn5.js} +1 -1
  317. package/static/dashboard/assets/{waypoints-DuZPO_wu.js → waypoints-s-opmJxx.js} +1 -1
  318. package/static/dashboard/assets/{workspace-layout-BUj3wZ_m.js → workspace-layout-DqIQeTBV.js} +1 -1
  319. package/static/dashboard/dashboard.html +2 -2
  320. package/static/settings/assets/AiConfigContext-BB9KZySa.js +1 -0
  321. package/static/settings/assets/AiConfigPage-DGSXUkLs.js +1 -0
  322. package/static/settings/assets/DocumentProcessingPanel-Da2Re6Rg.js +1 -0
  323. package/static/settings/assets/IndexLifecyclePanel-BSZuIzgr.js +1 -0
  324. package/static/settings/assets/{IndexSubjectPanel-73sM16Ma.js → IndexSubjectPanel-CFd0ay-r.js} +1 -1
  325. package/static/settings/assets/ModelAssignmentsPanel-CSAryvWJ.js +1 -0
  326. package/static/settings/assets/ModelsPage-BQwCwLHU.js +11 -0
  327. package/static/settings/assets/{NetworkPage-i6j-M2RY.js → NetworkPage-BKymvsQc.js} +2 -2
  328. package/static/settings/assets/{PaneListHeader-DpqC0jd5.js → PaneListHeader-Bjh3hRdQ.js} +1 -1
  329. package/static/settings/assets/SearchIndexingPanel-MjKL5QLU.js +1 -0
  330. package/static/settings/assets/{StatusSubjectPanel-Dv4q3PGh.js → StatusSubjectPanel-Bvl6K4mx.js} +1 -1
  331. package/static/settings/assets/StatusWorkspace-B0NzrP--.js +1 -0
  332. package/static/settings/assets/SystemSettingsPage-D2z6Z4FE.js +1 -0
  333. package/static/settings/assets/SystemSettingsSubjectPanel-4sxma4X4.js +33 -0
  334. package/static/settings/assets/XpodAiConnectionsPodStore-BkNQ8fZx.js +3 -0
  335. package/static/settings/assets/{activity-DaFkk8f3.js → activity-CgJJGpjx.js} +1 -1
  336. package/static/settings/assets/admin-C6qCRFiY.js +1 -0
  337. package/static/settings/assets/ai-connections-CryuHGKW.js +1 -0
  338. package/static/settings/assets/{badge-d5SHdc-x.js → badge-C4NypVyT.js} +1 -1
  339. package/static/settings/assets/collection-runtime-CTLCDxAi.js +1 -0
  340. package/static/settings/assets/dialog-Csq0vWUi.js +1 -0
  341. package/static/settings/assets/{download-CpkwomDr.js → download-DaLJJ-Wp.js} +1 -1
  342. package/static/settings/assets/{external-link-_4YT42Mf.js → external-link--w_iW5Au.js} +1 -1
  343. package/static/settings/assets/index-B0mQa59b.js +4 -0
  344. package/static/settings/assets/index-BukHiu4y.js +1 -0
  345. package/static/settings/assets/index-COmVnZi2.js +41 -0
  346. package/static/settings/assets/{index-browser-B06xjBdZ.js → index-browser-BGpvHwD0.js} +1 -1
  347. package/static/settings/assets/{key-round-Dlqmp1Kq.js → key-round-Bk4YRjBu.js} +1 -1
  348. package/static/settings/assets/layout-DB3pMyTl.js +1 -0
  349. package/static/settings/assets/pod-collections-host-KnnGFZHL.js +8 -0
  350. package/static/settings/assets/{rotate-ccw-TAY65xWT.js → rotate-ccw-TCabbqsr.js} +1 -1
  351. package/static/settings/assets/{settings-ExBXGgbj.js → settings-CJWpdbNC.js} +105 -109
  352. package/static/settings/assets/settings-projection-CUkyprDQ.js +1 -0
  353. package/static/settings/assets/settings-rk080mvG.css +1 -0
  354. package/static/settings/assets/{skeleton-DKIWjNr9.js → skeleton-JDHYVe7t.js} +1 -1
  355. package/static/settings/assets/{waypoints-9erLIxyR.js → waypoints-DDvEl-MU.js} +1 -1
  356. package/static/settings/assets/{workspace-layout-CYXfYIa3.js → workspace-layout-DV5QU30U.js} +1 -1
  357. package/static/settings/settings.html +2 -2
  358. package/node_modules/@undefineds.co/shared-ui/dist/oidc-consent.d.ts +0 -54
  359. package/node_modules/@undefineds.co/shared-ui/dist/oidc-consent.js +0 -21
  360. package/static/auth-callback/assets/AiConfigContext-C81deMM9.js +0 -1
  361. package/static/auth-callback/assets/AiConfigPage-evWI8T56.js +0 -1
  362. package/static/auth-callback/assets/DocumentProcessingPanel-B9GrDEMe.js +0 -1
  363. package/static/auth-callback/assets/IndexLifecyclePanel-qCo8ABQZ.js +0 -1
  364. package/static/auth-callback/assets/ModelAssignmentsPanel-DG7Lxh3t.js +0 -1
  365. package/static/auth-callback/assets/ModelsPage-CgEuqE6p.js +0 -10
  366. package/static/auth-callback/assets/SearchIndexingPanel-ByU3u7kp.js +0 -1
  367. package/static/auth-callback/assets/StatusWorkspace-BZd617sV.js +0 -1
  368. package/static/auth-callback/assets/SystemSettingsPage-BirzWAQM.js +0 -1
  369. package/static/auth-callback/assets/SystemSettingsSubjectPanel-CmsVWNCx.js +0 -31
  370. package/static/auth-callback/assets/admin-BU4m6Ko2.js +0 -1
  371. package/static/auth-callback/assets/ai-connections-CHNTKemd.js +0 -1
  372. package/static/auth-callback/assets/auth-callback-C_7MUXJb.css +0 -1
  373. package/static/auth-callback/assets/index-BpV1hsqs.js +0 -4
  374. package/static/auth-callback/assets/index-D9oE6FXK.js +0 -41
  375. package/static/dashboard/assets/AiConfigContext-De-OtAWo.js +0 -1
  376. package/static/dashboard/assets/AiConfigPage-macP4Mop.js +0 -1
  377. package/static/dashboard/assets/DocumentProcessingPanel-C5ObvCCl.js +0 -1
  378. package/static/dashboard/assets/IndexLifecyclePanel-xVNa2l40.js +0 -1
  379. package/static/dashboard/assets/ModelAssignmentsPanel-DMOATFpQ.js +0 -1
  380. package/static/dashboard/assets/ModelsPage-91UbnETA.js +0 -25
  381. package/static/dashboard/assets/SearchIndexingPanel-Dh70PNFZ.js +0 -1
  382. package/static/dashboard/assets/SystemSettingsPage-BiN5GcKx.js +0 -1
  383. package/static/dashboard/assets/SystemSettingsSubjectPanel-B9QrSiFp.js +0 -31
  384. package/static/dashboard/assets/admin-BU4m6Ko2.js +0 -1
  385. package/static/dashboard/assets/ai-connections-CHNTKemd.js +0 -1
  386. package/static/dashboard/assets/dashboard-C_7MUXJb.css +0 -1
  387. package/static/dashboard/assets/index-FWZ-s52O.js +0 -41
  388. package/static/dashboard/assets/index-ZiQZ96oC.js +0 -4
  389. package/static/settings/assets/AiConfigContext-C0cQMPfG.js +0 -1
  390. package/static/settings/assets/AiConfigPage-CPhB4iFb.js +0 -1
  391. package/static/settings/assets/DocumentProcessingPanel-sYI7OpuH.js +0 -1
  392. package/static/settings/assets/IndexLifecyclePanel-yj8iyiT8.js +0 -1
  393. package/static/settings/assets/ModelAssignmentsPanel-BFIgUX5v.js +0 -1
  394. package/static/settings/assets/ModelsPage-BdppXl7E.js +0 -10
  395. package/static/settings/assets/SearchIndexingPanel-BlPnrkT3.js +0 -1
  396. package/static/settings/assets/SystemSettingsPage-CiOm2NzV.js +0 -1
  397. package/static/settings/assets/SystemSettingsSubjectPanel-Cd-GECon.js +0 -31
  398. package/static/settings/assets/admin-BU4m6Ko2.js +0 -1
  399. package/static/settings/assets/ai-connections-CHNTKemd.js +0 -1
  400. package/static/settings/assets/index-BFi9yn7_.js +0 -41
  401. package/static/settings/assets/index-BGgEhIUy.js +0 -4
  402. package/static/settings/assets/settings-C_7MUXJb.css +0 -1
@@ -386,10 +386,21 @@ function modelCapabilitiesFromWire(value) {
386
386
  const capabilities = [];
387
387
  if (value.capabilities.imageInput === true)
388
388
  capabilities.push('image');
389
+ // Only what a model can do for the caller earns a mark. `parallelToolCalls`
390
+ // refines tool calling and `promptCaching` is a transport optimisation, so
391
+ // neither becomes a marker of its own.
389
392
  if (value.capabilities.toolCalls === true)
390
393
  capabilities.push('tool_call');
391
394
  if (value.capabilities.reasoningEffort === true)
392
395
  capabilities.push('reasoning');
396
+ // A curated tier marker, not a measurement: the catalog has no latency data,
397
+ // so a model is only "fast" because the catalog says so.
398
+ if (value.capabilities.fast === true)
399
+ capabilities.push('fast');
400
+ // Catalog-provided embedding models carry the capability as an object flag, the
401
+ // same way the AI Config embedding assignment reads them.
402
+ if (value.capabilities.embedding === true)
403
+ capabilities.push('embedding');
393
404
  return capabilities.length > 0 ? capabilities : undefined;
394
405
  }
395
406
  function isPlatformModelId(modelId) {
@@ -835,12 +846,18 @@ export function parseModelDiscovery(value, expectedProvider) {
835
846
  .map((item) => {
836
847
  if (!isRecord(item) || typeof item.id !== 'string' || !item.id)
837
848
  return undefined;
849
+ const capabilities = Array.isArray(item.capabilities)
850
+ ? item.capabilities.filter((cap) => typeof cap === 'string')
851
+ : undefined;
852
+ const modelType = discoveredModelType(item.modelType);
838
853
  return compactObject({
839
854
  id: item.id,
840
855
  displayName: stringValue(item.displayName),
841
- capabilities: Array.isArray(item.capabilities)
842
- ? item.capabilities.filter((cap) => typeof cap === 'string')
843
- : undefined,
856
+ // A provider that declares capabilities sends them; otherwise the type
857
+ // is the only evidence a row has, and an embedding model without it is
858
+ // listed as if it were a chat model.
859
+ capabilities: capabilities ?? (modelType === 'embedding' ? ['embedding'] : undefined),
860
+ modelType,
844
861
  });
845
862
  })
846
863
  .filter(isDefined);
@@ -855,6 +872,16 @@ export function parseModelDiscovery(value, expectedProvider) {
855
872
  export function compactObject(value) {
856
873
  return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
857
874
  }
875
+ /**
876
+ * Only the two classes the Pod stores survive the wire.
877
+ *
878
+ * A server that sends anything else (an older release, a provider's own
879
+ * vocabulary) leaves the row untyped, which reads as a chat model - never as a
880
+ * value the AI config write would reject.
881
+ */
882
+ function discoveredModelType(value) {
883
+ return value === 'chat' || value === 'embedding' ? value : undefined;
884
+ }
858
885
  function stringValue(value) {
859
886
  return typeof value === 'string' ? value : undefined;
860
887
  }
@@ -85,6 +85,13 @@ export interface CreatedGatewayKey {
85
85
  }
86
86
  export interface AiGatewayModel extends AiConnectionsModelSelection {
87
87
  provider: AiConnectionsProvider;
88
+ /**
89
+ * What kind of model this row is, when the Pod or the provider catalog knows.
90
+ *
91
+ * Rows read from the Pod carry it as their own column; the settings list shows
92
+ * it as the same capability mark the Gateway projection uses.
93
+ */
94
+ modelType?: DiscoveredProviderModelType;
88
95
  /** Owning credential for providers that allow multiple independent custom endpoints. */
89
96
  credentialId?: string;
90
97
  displayName?: string;
@@ -96,10 +103,21 @@ export interface AiGatewayModel extends AiConnectionsModelSelection {
96
103
  outputModalities?: string[];
97
104
  capabilities?: string[];
98
105
  }
106
+ /**
107
+ * What the provider's own model list said a model is.
108
+ *
109
+ * Two values only, because that is the distinction the product acts on and the
110
+ * only one the Pod can store: the server infers it
111
+ * (`ProviderModelType.inferProviderModelType`) and the Pod row keeps it, so an
112
+ * embedding model stays selectable for embedding instead of being stored as an
113
+ * ordinary chat model.
114
+ */
115
+ export type DiscoveredProviderModelType = 'chat' | 'embedding';
99
116
  export interface DiscoveredProviderModel {
100
117
  id: string;
101
118
  displayName?: string;
102
119
  capabilities?: string[];
120
+ modelType?: DiscoveredProviderModelType;
103
121
  }
104
122
  export interface CustomProviderModel {
105
123
  id: string;
@@ -117,7 +135,9 @@ export interface ProviderModelDiscovery {
117
135
  observedAt: string;
118
136
  source: string;
119
137
  }
120
- export type AiProviderAuthorizationMethodId = 'device-code' | 'local-session-import' | 'api-key' | 'local-service' | string;
138
+ export type AiProviderAuthorizationMethodId = 'device-code' | 'local-session-import' | 'api-key' | 'local-service'
139
+ /** Opens the provider console to sign in and mint the key the entry then stores. */
140
+ | 'browser-login' | string;
121
141
  export interface AiProviderAuthorizationMethod {
122
142
  id: AiProviderAuthorizationMethodId;
123
143
  authMode: 'oauth' | 'deviceCode' | 'local' | 'apiKey';
@@ -20,8 +20,7 @@ interface OwnershipState {
20
20
  export declare function hashWebId(webId: string): string;
21
21
  declare function contentHash(value: string): string;
22
22
  export declare const contentFingerprint: typeof contentHash;
23
- export declare function normalizeV1Endpoint(endpoint: string): string;
24
- export declare function normalizeMessagesEndpoint(endpoint: string): string;
23
+ export { normalizeMessagesEndpoint, normalizeV1Endpoint } from '../endpoint-urls';
25
24
  export declare function parseJsonObject(content: string | undefined, label: string): Record<string, unknown>;
26
25
  export declare function stringifyJson(value: unknown): string;
27
26
  export declare function looksLikePreviousXpodValue(value: unknown): boolean;
@@ -68,4 +67,3 @@ export declare abstract class BaseAiClientConfigAdapter implements AiClientConfi
68
67
  private exists;
69
68
  private isExecutableOnPath;
70
69
  }
71
- export {};
@@ -17,13 +17,9 @@ function contentHash(value) {
17
17
  return crypto.createHash('sha256').update(value, 'utf8').digest('hex');
18
18
  }
19
19
  export const contentFingerprint = contentHash;
20
- export function normalizeV1Endpoint(endpoint) {
21
- const normalized = endpoint.trim().replace(/\/+$/, '');
22
- return normalized.endsWith('/v1') ? normalized : `${normalized}/v1`;
23
- }
24
- export function normalizeMessagesEndpoint(endpoint) {
25
- return endpoint.trim().replace(/\/+$/, '').replace(/\/v1$/, '');
26
- }
20
+ // The base-URL rules are shared with the UI (see src/endpoint-urls.ts); they are
21
+ // re-exported here so adapters keep importing them from one place.
22
+ export { normalizeMessagesEndpoint, normalizeV1Endpoint } from '../endpoint-urls.js';
27
23
  export function parseJsonObject(content, label) {
28
24
  if (!content?.trim())
29
25
  return {};
@@ -269,6 +269,15 @@ class AiClientConfigTransaction {
269
269
  }
270
270
  }
271
271
 
272
+ // src/endpoint-urls.ts
273
+ function normalizeV1Endpoint(endpoint) {
274
+ const normalized = endpoint.trim().replace(/\/+$/, "");
275
+ return normalized.endsWith("/v1") ? normalized : `${normalized}/v1`;
276
+ }
277
+ function normalizeMessagesEndpoint(endpoint) {
278
+ return endpoint.trim().replace(/\/+$/, "").replace(/\/v1$/, "");
279
+ }
280
+
272
281
  // src/client-config/base-adapter.ts
273
282
  class AiClientConfigError extends Error {
274
283
  code;
@@ -285,13 +294,6 @@ function contentHash(value) {
285
294
  return crypto2.createHash("sha256").update(value, "utf8").digest("hex");
286
295
  }
287
296
  var contentFingerprint = contentHash;
288
- function normalizeV1Endpoint(endpoint) {
289
- const normalized = endpoint.trim().replace(/\/+$/, "");
290
- return normalized.endsWith("/v1") ? normalized : `${normalized}/v1`;
291
- }
292
- function normalizeMessagesEndpoint(endpoint) {
293
- return endpoint.trim().replace(/\/+$/, "").replace(/\/v1$/, "");
294
- }
295
297
  function parseJsonObject(content, label) {
296
298
  if (!content?.trim())
297
299
  return {};
@@ -0,0 +1,46 @@
1
+ import type { AiConnectionsPodStore, WebExtensionHost } from '@undefineds.co/extension-sdk/web';
2
+ import type { AiConnectionsClient } from './ai-connections-client';
3
+ import { type CredentialCollection } from './collections';
4
+ /**
5
+ * The half of the credentials table that needs the collection layer at runtime.
6
+ *
7
+ * This module is reached **only** through `collections.credentialCollectionRuntime()`
8
+ * (a dynamic import): it is the single place in the applet that pulls
9
+ * `@undefineds.co/pod-collections` - and with it the TanStack DB engine - so the
10
+ * settings entry and every page that renders the applet without live rows do not
11
+ * carry that weight (`docs/pod-collections.md` §9-9).
12
+ *
13
+ * Everything here is behind an `await`: defining the table (the host may still be
14
+ * fetching the engine), reading rows and writing rows. The page keeps rendering
15
+ * the store's own summary until it lands, which is exactly how it behaves when
16
+ * the host offers no `podCollections` capability at all.
17
+ */
18
+ /**
19
+ * The host's live credentials collection, or `undefined` when the host offers no
20
+ * `podCollections` capability (or cannot lay the table out).
21
+ *
22
+ * A missing capability is a degradation, not an error: the page keeps reading
23
+ * through the store exactly as before. `layout_document_required` cannot happen
24
+ * for this descriptor (its document is derived from `storage.base`) but is
25
+ * handled the same way rather than taking the page down with it.
26
+ *
27
+ * `load()` is the host accessor that works whether the collection engine is
28
+ * already in the host or still arriving; `define()` is the eager host's
29
+ * synchronous path and stays the fallback for a host that does not implement it.
30
+ */
31
+ export declare function openCredentialCollection(host: WebExtensionHost): Promise<CredentialCollection | undefined>;
32
+ /** Inverse of {@link credentialIdOfRow}: collection key for a credential resource id. */
33
+ export declare function credentialRowKey(id: string): string | undefined;
34
+ /**
35
+ * The credential mutations of `AiConnectionsClient`, backed by the collection.
36
+ *
37
+ * Everything the descriptor declares is written through `insert` / `update` /
38
+ * `delete`, so it is optimistic, rolls back on rejection and reconciles with the
39
+ * document instead of being overwritten by the next read. Everything it cannot
40
+ * express - the secret envelope, `offeringId`, `metadata`, base URLs,
41
+ * `compatibility` - is written by the store within the same user action; if that
42
+ * completion fails, the row the collection created is deleted again and a
43
+ * partially applied update is put back, so a failed write leaves no
44
+ * half-written credential behind.
45
+ */
46
+ export declare function collectionCredentialMutations(credentials: CredentialCollection, store: AiConnectionsPodStore): Pick<AiConnectionsClient, 'createApiKeyCredential' | 'createLocalCredential' | 'updateProviderCredential' | 'deleteProviderCredential'>;
@@ -0,0 +1,231 @@
1
+ import { credentialDescriptor, credentialResource } from '@undefineds.co/models';
2
+ import { rowKeyOf } from '@undefineds.co/pod-collections';
3
+ import { credentialProviderRelation, credentialRowKeyFor, customCredentialProviderRelation, } from './credential-storage.js';
4
+ import { credentialSummaryFromRow } from './collections.js';
5
+ import { normalizeProxyUrl } from './client/normalize.js';
6
+ import { credentialOfferingMetadata, defaultOfferingFor, offeringBaseUrl, storedOfferingIdFor, } from './provider-catalog.js';
7
+ /**
8
+ * The half of the credentials table that needs the collection layer at runtime.
9
+ *
10
+ * This module is reached **only** through `collections.credentialCollectionRuntime()`
11
+ * (a dynamic import): it is the single place in the applet that pulls
12
+ * `@undefineds.co/pod-collections` - and with it the TanStack DB engine - so the
13
+ * settings entry and every page that renders the applet without live rows do not
14
+ * carry that weight (`docs/pod-collections.md` §9-9).
15
+ *
16
+ * Everything here is behind an `await`: defining the table (the host may still be
17
+ * fetching the engine), reading rows and writing rows. The page keeps rendering
18
+ * the store's own summary until it lands, which is exactly how it behaves when
19
+ * the host offers no `podCollections` capability at all.
20
+ */
21
+ /**
22
+ * The host's live credentials collection, or `undefined` when the host offers no
23
+ * `podCollections` capability (or cannot lay the table out).
24
+ *
25
+ * A missing capability is a degradation, not an error: the page keeps reading
26
+ * through the store exactly as before. `layout_document_required` cannot happen
27
+ * for this descriptor (its document is derived from `storage.base`) but is
28
+ * handled the same way rather than taking the page down with it.
29
+ *
30
+ * `load()` is the host accessor that works whether the collection engine is
31
+ * already in the host or still arriving; `define()` is the eager host's
32
+ * synchronous path and stays the fallback for a host that does not implement it.
33
+ */
34
+ export async function openCredentialCollection(host) {
35
+ const capability = host.capabilities.podCollections;
36
+ if (!capability)
37
+ return undefined;
38
+ try {
39
+ if (capability.load) {
40
+ return { collection: await capability.load(credentialDescriptor, { table: credentialResource }) };
41
+ }
42
+ return { collection: capability.define(credentialDescriptor, { table: credentialResource }) };
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
48
+ /** Inverse of {@link credentialIdOfRow}: collection key for a credential resource id. */
49
+ export function credentialRowKey(id) {
50
+ if (!id.includes('#'))
51
+ return id;
52
+ return rowKeyOf(credentialDescriptor, { id });
53
+ }
54
+ /** Writes a row the descriptor declares; confirmation is the collection's own protocol. */
55
+ async function insertCredentialRow(collection, row) {
56
+ await collection.insert(row).isPersisted.promise;
57
+ }
58
+ /** Patches the descriptor-declared fields of one row (label, status, …). */
59
+ async function updateCredentialRow(collection, key, patch) {
60
+ await collection.update(key, (draft) => {
61
+ Object.assign(draft, patch);
62
+ }).isPersisted.promise;
63
+ }
64
+ async function deleteCredentialRow(collection, key) {
65
+ await collection.delete(key).isPersisted.promise;
66
+ }
67
+ /**
68
+ * The row a create writes through the collection: exactly the columns the
69
+ * models descriptor declares.
70
+ *
71
+ * The secret envelope is deliberately absent, and not because the confirmation
72
+ * protocol could not handle it any more (that defect is fixed: a write intent
73
+ * carrying a `secret: true` field now confirms, §9-7). It is absent because the
74
+ * store owns it: `encryptedSecret` is built by the store's encryption path.
75
+ *
76
+ * `offeringId` / `metadata` / `baseUrl` / `proxyUrl` are a different case: models
77
+ * 0.2.57 **does** declare them, so a read projects them back and this row has to
78
+ * carry the same values the store writes or our own echo looks like a change and
79
+ * replaces the row (see `credentials collection` in
80
+ * `packages/ai-connections/test/pod-collections.test.tsx`). Their derivation
81
+ * currently lives in the store adapter, which is why this row still omits them;
82
+ * reconciling that is the open item, not a decision this comment can settle.
83
+ */
84
+ function newCredentialRow(key, input) {
85
+ const { provider } = input;
86
+ // The offering columns are derived here exactly as the store derives them, so
87
+ // the row the collection writes is already the row the store will confirm.
88
+ const offeringId = storedOfferingIdFor(provider, input.offeringId ?? defaultOfferingFor(provider, input.authMode));
89
+ const baseUrl = input.baseUrl ?? offeringBaseUrl(provider, offeringId);
90
+ const proxyUrl = normalizeProxyUrl(input.proxyUrl);
91
+ return {
92
+ id: key,
93
+ service: 'ai',
94
+ // The credential descriptor's provider relation (models 0.2.57 names the
95
+ // field `provider`; the retired `providerId` still compiles because `RowOf`
96
+ // carries an index signature, and read back `undefined` at runtime).
97
+ provider: provider === 'custom'
98
+ ? customCredentialProviderRelation(key)
99
+ : credentialProviderRelation(provider),
100
+ authMode: input.authMode,
101
+ status: 'active',
102
+ accountLabel: input.accountLabel,
103
+ label: input.accountLabel,
104
+ keyVersion: '1',
105
+ reauthRequired: false,
106
+ encryptionAlgorithm: 'PLAINTEXT',
107
+ offeringId,
108
+ ...(baseUrl ? { baseUrl } : {}),
109
+ ...(proxyUrl ? { proxyUrl } : {}),
110
+ metadata: credentialOfferingMetadata({ offeringId, baseUrl }),
111
+ };
112
+ }
113
+ /**
114
+ * The credential mutations of `AiConnectionsClient`, backed by the collection.
115
+ *
116
+ * Everything the descriptor declares is written through `insert` / `update` /
117
+ * `delete`, so it is optimistic, rolls back on rejection and reconciles with the
118
+ * document instead of being overwritten by the next read. Everything it cannot
119
+ * express - the secret envelope, `offeringId`, `metadata`, base URLs,
120
+ * `compatibility` - is written by the store within the same user action; if that
121
+ * completion fails, the row the collection created is deleted again and a
122
+ * partially applied update is put back, so a failed write leaves no
123
+ * half-written credential behind.
124
+ */
125
+ export function collectionCredentialMutations(credentials, store) {
126
+ const { collection } = credentials;
127
+ const discard = async (key) => {
128
+ await deleteCredentialRow(collection, key).catch(() => undefined);
129
+ };
130
+ const summaryOf = (key, provider) => {
131
+ const row = collection.get(key);
132
+ return row ? credentialSummaryFromRow(row, provider) : undefined;
133
+ };
134
+ const create = async (provider, key, row, complete) => {
135
+ await insertCredentialRow(collection, row);
136
+ try {
137
+ const completed = await complete(credentialResource.buildId({ id: key }));
138
+ const summary = completed ?? summaryOf(key, provider);
139
+ if (!summary)
140
+ throw new Error('credential_create_failed');
141
+ return summary;
142
+ }
143
+ catch (error) {
144
+ await discard(key);
145
+ throw error;
146
+ }
147
+ };
148
+ return {
149
+ async createApiKeyCredential(provider, input) {
150
+ if (!store.createApiKeyCredential)
151
+ throw new Error('credential_store_unavailable');
152
+ const key = credentialRowKeyFor(provider, 'apiKey');
153
+ const label = input.label ?? provider;
154
+ return await create(provider, key, newCredentialRow(key, {
155
+ provider,
156
+ authMode: 'apiKey',
157
+ accountLabel: label,
158
+ offeringId: input.offeringId,
159
+ baseUrl: input.baseUrl,
160
+ proxyUrl: input.proxyUrl,
161
+ }), (id) => store.createApiKeyCredential(provider, { ...input, label, id }));
162
+ },
163
+ async createLocalCredential(provider, input) {
164
+ if (!store.createLocalCredential)
165
+ throw new Error('credential_store_unavailable');
166
+ const key = credentialRowKeyFor(provider, 'local');
167
+ const label = input.label ?? 'Local';
168
+ return await create(provider, key, newCredentialRow(key, {
169
+ provider,
170
+ authMode: 'local',
171
+ accountLabel: label,
172
+ offeringId: input.offeringId,
173
+ baseUrl: input.baseUrl,
174
+ }), (id) => store.createLocalCredential(provider, { ...input, label, id }));
175
+ },
176
+ async updateProviderCredential(provider, credentialId, input) {
177
+ const key = credentialRowKey(credentialId);
178
+ if (!key)
179
+ throw new Error('credential_not_found');
180
+ // `label` and `enabled` are descriptor fields: they land optimistically
181
+ // through the collection. Priority and base URLs are not, so they go to
182
+ // the store within the same call. Built as a literal because models 0.2.59
183
+ // declares these row fields readonly.
184
+ const patch = {
185
+ ...(input.label === undefined ? {} : { label: input.label, accountLabel: input.label }),
186
+ ...(input.enabled === undefined ? {} : { status: input.enabled ? 'active' : 'disabled' }),
187
+ };
188
+ const before = collection.get(key);
189
+ if (Object.keys(patch).length > 0)
190
+ await updateCredentialRow(collection, key, patch);
191
+ const attributes = {
192
+ ...(input.priority === undefined ? {} : { priority: input.priority }),
193
+ ...(input.baseUrl === undefined ? {} : { baseUrl: input.baseUrl }),
194
+ ...(input.proxyUrl === undefined ? {} : { proxyUrl: input.proxyUrl }),
195
+ };
196
+ if (Object.keys(attributes).length === 0)
197
+ return summaryOf(key, provider);
198
+ if (!store.updateProviderCredential)
199
+ throw new Error('credential_store_unavailable');
200
+ try {
201
+ const completed = await store.updateProviderCredential(provider, credentialId, {
202
+ expectedVersion: input.expectedVersion,
203
+ ...attributes,
204
+ });
205
+ return completed ?? summaryOf(key, provider);
206
+ }
207
+ catch (error) {
208
+ // The optimistic part must not survive a rejected completion: put the
209
+ // row's own fields back, then report the failure.
210
+ if (before && Object.keys(patch).length > 0) {
211
+ await updateCredentialRow(collection, key, {
212
+ ...(patch.label === undefined ? {} : {
213
+ label: before.label,
214
+ accountLabel: before.accountLabel,
215
+ }),
216
+ ...(patch.status === undefined ? {} : { status: before.status }),
217
+ }).catch(() => undefined);
218
+ }
219
+ throw error;
220
+ }
221
+ },
222
+ async deleteProviderCredential(provider, credentialId) {
223
+ const key = credentialRowKey(credentialId);
224
+ if (!key)
225
+ return undefined;
226
+ const before = summaryOf(key, provider);
227
+ await deleteCredentialRow(collection, key);
228
+ return before;
229
+ },
230
+ };
231
+ }
@@ -0,0 +1,119 @@
1
+ import { credentialDescriptor } from '@undefineds.co/models';
2
+ import type { PodCollection, RowOf } from '@undefineds.co/pod-collections';
3
+ import type { AiConnectionsProvider, AiProviderCredentialSummary, AiProviderSummary } from './ai-connections-client';
4
+ /**
5
+ * The credentials table, declared once (`docs/pod-collections.md` §6.4-2).
6
+ *
7
+ * This module is the *shape* of the table and everything that can be computed
8
+ * from a row without the collection layer: the row type, the projection of a row
9
+ * into the summary the page renders, and the enrichment carriers. Nothing here
10
+ * imports `@undefineds.co/pod-collections` at runtime - the row type is a type,
11
+ * and the two things that do need the layer (declaring the table, reading and
12
+ * writing its rows) live in `./collection-runtime`, which is reached through the
13
+ * dynamic import below. That is what keeps the engine out of the settings
14
+ * entry's chunk and out of any page that renders without live rows (§9-9).
15
+ *
16
+ * The one read the page does here, `useCredentialRows`, is a `useSyncExternalStore`
17
+ * subscription to a rows source (the controller's live snapshot of the
18
+ * collection). It is deliberately not `@tanstack/react-db`'s `useLiveQuery`: the
19
+ * page needs "all rows of one table, once its first read landed", which the
20
+ * collection's own change feed answers, and loading a hook lazily would force
21
+ * the whole panel to remount when the chunk arrived. The design doc names this
22
+ * exit explicitly (§7.4-4, §8.7-5: engine only, no react hook).
23
+ *
24
+ * ## What the collection can carry, and what it cannot (yet)
25
+ *
26
+ * Rows are the descriptor's projection: `id`, `service`, `provider`, `label`,
27
+ * `accountLabel`, `authMode`, `status`, `keyVersion`, `expiresAt`,
28
+ * `reauthRequired`, … The known schema drift (locked by
29
+ * `packages/pod-collections/test/guards.test.ts`) means `offeringId`,
30
+ * `metadata`, `baseUrl` and `proxyUrl` are **not** projectable, and `secret`
31
+ * fields are not projected however they are written. So
32
+ *
33
+ * - reading carries the undeclared attributes over from the store's own summary
34
+ * of the same row (`credentialCarriers`), and
35
+ * - writing hands them to the store (`AiConnectionsPodStore`), which owns those
36
+ * columns and the secret envelope.
37
+ *
38
+ * Both are migration-window behaviour. models 0.2.57 now declares all four, so
39
+ * their delete condition is formally met, but they stay until the descriptor
40
+ * projection work (P4) retires the carrier path as a whole - removing them one
41
+ * at a time would leave reads and writes disagreeing in between.
42
+ */
43
+ /** A credentials-table row as the collection projects it. */
44
+ export type CredentialRow = RowOf<typeof credentialDescriptor>;
45
+ /** The collection's `syncState` is the page's availability signal. */
46
+ export interface CredentialCollection {
47
+ readonly collection: PodCollection<CredentialRow>;
48
+ }
49
+ /**
50
+ * A live rows source: the controller's snapshot of the credentials collection.
51
+ *
52
+ * `credentialRows` is `undefined` until the collection's first read lands - and
53
+ * stays `undefined` while the collection layer is still loading, when the host
54
+ * offers no `podCollections` capability, or after a failed first read. The page
55
+ * keeps its store-backed rendering in every one of those states.
56
+ */
57
+ export interface CredentialRowsSource {
58
+ subscribe(listener: () => void): () => void;
59
+ readonly credentialRows?: readonly CredentialRow[];
60
+ }
61
+ /**
62
+ * Live rows for the credentials table. Re-renders on sync and on optimistic
63
+ * writes, because the source is the collection's own change feed.
64
+ */
65
+ export declare function useCredentialRows(source: CredentialRowsSource): readonly CredentialRow[] | undefined;
66
+ /** The lazy half of this module's subject: everything that needs the engine. */
67
+ export type CredentialCollectionRuntime = typeof import('./collection-runtime');
68
+ /**
69
+ * The collection layer at the point of use, fetched once.
70
+ *
71
+ * This is the applet's only dynamic import of it: the settings entry and the
72
+ * applet's own chunk contain no part of the engine, and a page that never
73
+ * reaches the credentials list never fetches it.
74
+ */
75
+ export declare function credentialCollectionRuntime(): Promise<CredentialCollectionRuntime>;
76
+ /**
77
+ * The row's resource id in the shape the rest of the applet uses for
78
+ * credentials: `credentials.ttl#<key>`. The collection's key is only the
79
+ * `resourceIdPattern` slot (`#{id}` → `openai-<uuid>`), so the document segment
80
+ * comes from the same models builder the store writes with.
81
+ */
82
+ export declare function credentialIdOfRow(row: CredentialRow): string;
83
+ /**
84
+ * Which provider a row belongs to, from the row's own `provider` relation.
85
+ *
86
+ * Rows have to be attributable without the store's help: a credential another
87
+ * device just wrote reaches this page as a live row, before any summary read
88
+ * has seen it.
89
+ */
90
+ export declare function providerOfCredentialRow(row: CredentialRow): AiConnectionsProvider | undefined;
91
+ /**
92
+ * A row as the page's credential summary.
93
+ *
94
+ * The row wins for everything the descriptor declares; `carrier` - the store's
95
+ * summary of the same credential - supplies the attributes the descriptor cannot
96
+ * project and the secret-derived hint. A row the store has not read yet (an
97
+ * optimistic insert) falls back to the descriptor's own defaults.
98
+ */
99
+ export declare function credentialSummaryFromRow(row: CredentialRow, provider: AiConnectionsProvider, carrier?: AiProviderCredentialSummary): AiProviderCredentialSummary;
100
+ /** The provider's credential list, rebuilt from the live rows of one table document. */
101
+ export declare function credentialSummariesForProvider(provider: AiConnectionsProvider, rows: readonly CredentialRow[], carrier?: readonly AiProviderCredentialSummary[]): AiProviderCredentialSummary[];
102
+ /**
103
+ * The enrichment carrier per provider: the store's own summary of every
104
+ * credential, plus any credential a mutation of this session added and the store
105
+ * has not read back yet.
106
+ *
107
+ * The store's entries win where both know the same credential - it is the
108
+ * independent read - and the session's overlay only fills the gap, so a
109
+ * just-created row keeps its offering and base URL while it is still optimistic.
110
+ */
111
+ export declare function credentialCarriers(storeProducts: Partial<Record<AiConnectionsProvider, AiProviderSummary>>, overlayProducts: Partial<Record<AiConnectionsProvider, AiProviderSummary>>): Partial<Record<AiConnectionsProvider, readonly AiProviderCredentialSummary[]>>;
112
+ /**
113
+ * The provider products the page renders, with every credential list rebuilt
114
+ * from the live rows.
115
+ *
116
+ * `carriers` only enriches: which credentials exist, and every field the
117
+ * descriptor declares, come from the rows.
118
+ */
119
+ export declare function withLiveCredentials(products: Partial<Record<AiConnectionsProvider, AiProviderSummary>>, carriers: Partial<Record<AiConnectionsProvider, readonly AiProviderCredentialSummary[]>>, rows: readonly CredentialRow[] | undefined): Partial<Record<AiConnectionsProvider, AiProviderSummary>>;