@undefineds.co/xpod 0.3.70 → 0.3.71-rc.13

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 (172) hide show
  1. package/config/cloud.json +3 -0
  2. package/config/local.json +3 -0
  3. package/config/resolver.json +7 -0
  4. package/config/xpod.base.json +20 -0
  5. package/dist/agents/ClaudeExecutor.js +1 -1
  6. package/dist/agents/ClaudeExecutor.js.map +1 -1
  7. package/dist/agents/types.d.ts +5 -5
  8. package/dist/agents/types.js.map +1 -1
  9. package/dist/api/ai-gateway/AiGatewayService.d.ts +5 -16
  10. package/dist/api/ai-gateway/AiGatewayService.js +13 -35
  11. package/dist/api/ai-gateway/AiGatewayService.js.map +1 -1
  12. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.d.ts +3 -2
  13. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js +37 -12
  14. package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js.map +1 -1
  15. package/dist/api/ai-gateway/auth/GatewayPrincipal.d.ts +2 -16
  16. package/dist/api/ai-gateway/auth/GatewayPrincipal.js +3 -33
  17. package/dist/api/ai-gateway/auth/GatewayPrincipal.js.map +1 -1
  18. package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.d.ts +23 -0
  19. package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.js +81 -0
  20. package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.js.map +1 -0
  21. package/dist/api/ai-gateway/auth/InvocationTokenCodec.d.ts +7 -4
  22. package/dist/api/ai-gateway/auth/InvocationTokenCodec.js.map +1 -1
  23. package/dist/api/ai-gateway/connect/index.d.ts +7 -26
  24. package/dist/api/ai-gateway/connect/index.js +40 -67
  25. package/dist/api/ai-gateway/connect/index.js.map +1 -1
  26. package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.d.ts +17 -0
  27. package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.js +65 -0
  28. package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.js.map +1 -0
  29. package/dist/api/ai-gateway/pod/HostedPodDataAccess.d.ts +24 -0
  30. package/dist/api/ai-gateway/pod/HostedPodDataAccess.js +149 -0
  31. package/dist/api/ai-gateway/pod/HostedPodDataAccess.js.map +1 -0
  32. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.d.ts +13 -5
  33. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +16 -19
  34. package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js.map +1 -1
  35. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.d.ts +1 -1
  36. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js +0 -2
  37. package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js.map +1 -1
  38. package/dist/api/auth/AuthContext.d.ts +1 -12
  39. package/dist/api/auth/AuthContext.js +0 -11
  40. package/dist/api/auth/AuthContext.js.map +1 -1
  41. package/dist/api/auth/ClientCredentialsAuthenticator.js +4 -11
  42. package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
  43. package/dist/api/chatkit/default-agent.d.ts +2 -2
  44. package/dist/api/chatkit/default-agent.js +4 -4
  45. package/dist/api/chatkit/default-agent.js.map +1 -1
  46. package/dist/api/chatkit/runtime/AcpAgentRuntime.js +1 -1
  47. package/dist/api/chatkit/runtime/AcpAgentRuntime.js.map +1 -1
  48. package/dist/api/container/common.js +28 -69
  49. package/dist/api/container/common.js.map +1 -1
  50. package/dist/api/container/index.js +5 -6
  51. package/dist/api/container/index.js.map +1 -1
  52. package/dist/api/container/routes.js +2 -5
  53. package/dist/api/container/routes.js.map +1 -1
  54. package/dist/api/container/types.d.ts +8 -10
  55. package/dist/api/container/types.js.map +1 -1
  56. package/dist/api/handlers/AiClientConfigurationHandler.js +3 -3
  57. package/dist/api/handlers/AiClientConfigurationHandler.js.map +1 -1
  58. package/dist/api/handlers/AiGatewayHandler.js +2 -2
  59. package/dist/api/handlers/AiGatewayHandler.js.map +1 -1
  60. package/dist/api/handlers/AiGatewayManagementHandler.d.ts +2 -10
  61. package/dist/api/handlers/AiGatewayManagementHandler.js +4 -154
  62. package/dist/api/handlers/AiGatewayManagementHandler.js.map +1 -1
  63. package/dist/api/handlers/NetworkSettingsHandler.js +0 -3
  64. package/dist/api/handlers/NetworkSettingsHandler.js.map +1 -1
  65. package/dist/api/handlers/PodSettingsHandler.d.ts +5 -2
  66. package/dist/api/handlers/PodSettingsHandler.js +3 -3
  67. package/dist/api/handlers/PodSettingsHandler.js.map +1 -1
  68. package/dist/api/runs/AgentRuntimeTypes.d.ts +3 -3
  69. package/dist/api/runs/AgentRuntimeTypes.js +10 -10
  70. package/dist/api/runs/AgentRuntimeTypes.js.map +1 -1
  71. package/dist/api/runs/InngestRunExecutionBackend.d.ts +15 -9
  72. package/dist/api/runs/InngestRunExecutionBackend.js +25 -10
  73. package/dist/api/runs/InngestRunExecutionBackend.js.map +1 -1
  74. package/dist/api/runs/PiAgentRuntimeDriver.js +2 -2
  75. package/dist/api/runs/PiAgentRuntimeDriver.js.map +1 -1
  76. package/dist/api/runs/RunStateCenter.js +1 -1
  77. package/dist/api/runs/RunStateCenter.js.map +1 -1
  78. package/dist/api/service/AiClientConfigurationService.d.ts +2 -2
  79. package/dist/api/service/AiClientConfigurationService.js +11 -11
  80. package/dist/api/service/AiClientConfigurationService.js.map +1 -1
  81. package/dist/api/tasks/InngestTaskScheduler.d.ts +16 -10
  82. package/dist/api/tasks/InngestTaskScheduler.js +24 -12
  83. package/dist/api/tasks/InngestTaskScheduler.js.map +1 -1
  84. package/dist/cli/commands/start.js +7 -7
  85. package/dist/cli/commands/start.js.map +1 -1
  86. package/dist/components/components.jsonld +1 -0
  87. package/dist/components/context.jsonld +36 -0
  88. package/dist/http/InternalPodDataHttpHandler.d.ts +32 -0
  89. package/dist/http/InternalPodDataHttpHandler.js +258 -0
  90. package/dist/http/InternalPodDataHttpHandler.js.map +1 -0
  91. package/dist/http/InternalPodDataHttpHandler.jsonld +201 -0
  92. package/dist/index.d.ts +2 -1
  93. package/dist/index.js +4 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/main.js +13 -13
  96. package/dist/main.js.map +1 -1
  97. package/dist/runtime/GatewayAdminProxyAuth.d.ts +15 -1
  98. package/dist/runtime/GatewayAdminProxyAuth.js +57 -2
  99. package/dist/runtime/GatewayAdminProxyAuth.js.map +1 -1
  100. package/dist/runtime/bootstrap.js +3 -0
  101. package/dist/runtime/bootstrap.js.map +1 -1
  102. package/dist/runtime/css-process.d.ts +1 -1
  103. package/dist/runtime/css-process.js +4 -1
  104. package/dist/runtime/css-process.js.map +1 -1
  105. package/dist/runtime/runner/node/CommunitySolidServerCssRunner.d.ts +2 -0
  106. package/dist/runtime/runner/node/CommunitySolidServerCssRunner.js +50 -0
  107. package/dist/runtime/runner/node/CommunitySolidServerCssRunner.js.map +1 -1
  108. package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.d.ts +5 -5
  109. package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.js +7 -7
  110. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionMain.js +1 -1
  111. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.d.ts +3 -1
  112. package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.js +74 -60
  113. package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.d.ts +0 -21
  114. package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.js +0 -41
  115. package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.d.ts +1 -0
  116. package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.js +7 -2
  117. package/node_modules/@undefineds.co/ai-connection/dist/client-config/codex.js +3 -3
  118. package/node_modules/@undefineds.co/ai-connection/dist/client-config/index.cjs +15 -9
  119. package/node_modules/@undefineds.co/ai-connection/dist/client-config/json-env-adapter.js +4 -4
  120. package/node_modules/@undefineds.co/ai-connection/dist/client-config/pi.js +3 -3
  121. package/node_modules/@undefineds.co/ai-connection/dist/client-config/types.d.ts +1 -1
  122. package/node_modules/@undefineds.co/ai-connection/dist/controller.d.ts +2 -1
  123. package/node_modules/@undefineds.co/ai-connection/dist/controller.js +1 -0
  124. package/node_modules/@undefineds.co/ai-connection/dist/service-access.js +0 -1
  125. package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +22 -1
  126. package/package.json +3 -3
  127. package/static/app/assets/main.js +7 -7
  128. package/static/dashboard/assets/NetworkPage-CXjiUMR1.js +2 -0
  129. package/static/dashboard/assets/{PaneListHeader-57nvMwH6.js → PaneListHeader-BSipfl0W.js} +1 -1
  130. package/static/dashboard/assets/PodPage-Bd3Xhmp-.js +2 -0
  131. package/static/dashboard/assets/ServicesPage-CI3jWZGe.js +1 -0
  132. package/static/dashboard/assets/{card-B9Zjf_2p.js → card-z5BV5hTo.js} +1 -1
  133. package/static/dashboard/assets/{dashboard-8C6o666W.js → dashboard-CSrqAv2L.js} +2 -2
  134. package/static/dashboard/assets/{database-DPh9wDY9.js → database-Ct5ZPe6L.js} +1 -1
  135. package/static/dashboard/assets/{external-link-VbMQvVMz.js → external-link-B7wD1hkm.js} +1 -1
  136. package/static/dashboard/assets/index-tOBaUnM1.js +44 -0
  137. package/static/dashboard/assets/{refresh-cw-BxVxNxNr.js → refresh-cw-CFDZPaE8.js} +1 -1
  138. package/static/dashboard/assets/{services-status-context-DKmJ7ISr.js → services-status-context-DN1Icg4A.js} +1 -1
  139. package/static/dashboard/dashboard.html +1 -1
  140. package/static/settings/assets/ModelsPage-03NPWzoX.js +1 -0
  141. package/static/settings/assets/{PaneListHeader-Bgaze006.js → PaneListHeader-DMD8OJef.js} +1 -1
  142. package/static/settings/assets/PodPage-DT4EMYhL.js +2 -0
  143. package/static/settings/assets/ServicesPage-CJ0ub6IH.js +1 -0
  144. package/static/settings/assets/SettingsPage-BkR7ZK18.js +41 -0
  145. package/static/settings/assets/{card-B_bXSIn-.js → card-Cjsia0_V.js} +1 -1
  146. package/static/settings/assets/{services-status-context-DiX-AbrP.js → services-status-context-CkuKmH5h.js} +1 -1
  147. package/static/settings/assets/{settings-B30oMfZq.js → settings-Cyyv6-SD.js} +2 -2
  148. package/static/settings/assets/{workspace-layout-Dv1Yn9Ci.js → workspace-layout-B47luv6r.js} +1 -1
  149. package/static/settings/settings.html +1 -1
  150. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.d.ts +0 -25
  151. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js +0 -91
  152. package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js.map +0 -1
  153. package/dist/api/ai-gateway/auth/GatewayApiKey.d.ts +0 -28
  154. package/dist/api/ai-gateway/auth/GatewayApiKey.js +0 -162
  155. package/dist/api/ai-gateway/auth/GatewayApiKey.js.map +0 -1
  156. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +0 -56
  157. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +0 -143
  158. package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js.map +0 -1
  159. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.d.ts +0 -26
  160. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js +0 -97
  161. package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js.map +0 -1
  162. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +0 -54
  163. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +0 -152
  164. package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js.map +0 -1
  165. package/static/dashboard/assets/NetworkPage-Brt79fuQ.js +0 -2
  166. package/static/dashboard/assets/PodPage-CM6do1vB.js +0 -2
  167. package/static/dashboard/assets/ServicesPage-BUNxGJRz.js +0 -1
  168. package/static/dashboard/assets/index-RfiFckzb.js +0 -51
  169. package/static/settings/assets/ModelsPage-D_IH7AH3.js +0 -1
  170. package/static/settings/assets/PodPage-Cy1VNObw.js +0 -2
  171. package/static/settings/assets/ServicesPage-BsFaxVWC.js +0 -1
  172. package/static/settings/assets/SettingsPage-UafNWE_p.js +0 -48
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/api/container/routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 路由注册\n *\n * 根据容器中的服务注册 API 路由\n */\n\nimport type { AwilixContainer } from 'awilix';\nimport type { ApiContainerCradle, ApiContainerConfig } from './types';\nimport type { ApiServer } from '../ApiServer';\n\nimport { registerEdgeNodeSignalRoutes } from '../handlers/EdgeNodeSignalHandler';\nimport { registerReachabilityRoutes } from '../handlers/ReachabilityHandler';\nimport { registerNodeRoutes } from '../handlers/NodeHandler';\nimport { registerChatRoutes } from '../handlers/ChatHandler';\nimport { registerSubdomainRoutes } from '../handlers/SubdomainHandler';\nimport { registerSubdomainClientRoutes } from '../handlers/SubdomainClientHandler';\nimport { registerDdnsRoutes } from '../handlers/DdnsHandler';\nimport { registerChatKitRoutes } from '../handlers/ChatKitHandler';\nimport { registerChatKitV1Routes } from '../handlers/ChatKitV1Handler';\nimport { registerInngestRoutes } from '../handlers/InngestHandler';\nimport { registerRunRoutes } from '../handlers/RunHandler';\nimport { registerMatrixRoutes } from '../handlers/MatrixHandler';\nimport { registerCoordinationRoutes } from '../handlers/CoordinationHandler';\nimport { registerDashboardRoutes } from '../handlers/DashboardHandler';\nimport { registerSettingsRoutes } from '../handlers/SettingsHandler';\nimport { registerAdminRoutes } from '../handlers/AdminHandler';\nimport { registerAdminDdnsRoutes } from '../handlers/AdminDdnsHandler';\nimport { registerLinxCapabilitiesRoutes } from '../handlers/LinxCapabilitiesHandler';\nimport { createLocalSetupProvisionStateWriter, registerProvisionRoutes, registerProvisionStatusRoute } from '../handlers/ProvisionHandler';\nimport { registerPodManagementRoutes } from '../handlers/PodManagementHandler';\nimport { DrizzlePodAiConnectionStatusReader, registerPodSettingsRoutes } from '../handlers/PodSettingsHandler';\nimport {\n createAddressReaders,\n createCertificateCapability,\n createDeploymentNetworkSettingsAuthorizer,\n createDnsStatusReader,\n createPublicAddressReader,\n createTunnelStatusReader,\n registerNetworkSettingsRoutes,\n} from '../handlers/NetworkSettingsHandler';\nimport { registerQuotaRoutes } from '../handlers/QuotaHandler';\nimport { registerUsageRoutes } from '../handlers/UsageHandler';\nimport { registerRdfStatsRoutes } from '../handlers/RdfStatsHandler';\nimport { registerAiGatewayManagementRoutes } from '../handlers/AiGatewayManagementHandler';\nimport { registerAiClientConfigurationRoutes } from '../handlers/AiClientConfigurationHandler';\nimport { registerDeviceNotificationRuntime, type DeviceNotificationRuntimeOptions } from '../handlers/DeviceNotificationRuntime';\nimport { AiClientConfigurationService } from '../service/AiClientConfigurationService';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport { UsageRepository } from '../../storage/quota/UsageRepository';\nimport { DrizzleQuotaService } from '../../quota/DrizzleQuotaService';\nimport { LocalPodProvisioningService } from '../../provision/LocalPodProvisioningService';\nimport { verifyServiceAccessToken } from '../../provision/ServiceAccessTokenCodec';\nimport {\n findEdgeNodeCertificateCapabilityBridge,\n resolveEdgeNodeCertificateCapabilityBridgeId,\n} from '../../edge/EdgeNodeCertificateCapabilityBridge';\nimport * as path from 'node:path';\nimport { PACKAGE_ROOT } from '../../runtime';\n\n/**\n * 注册所有 API 路由\n */\nexport function registerRoutes(container: AwilixContainer<ApiContainerCradle>): void {\n const server = container.resolve('apiServer') as ApiServer;\n const config = container.resolve('config') as ApiContainerConfig;\n\n // 公共健康检查端点\n registerHealthRoutes(server);\n\n // 共享路由\n registerSharedRoutes(container, server);\n\n // 根据 edition 注册专属路由\n if (config.edition === 'cloud') {\n registerCloudRoutes(container, server);\n } else {\n registerLocalRoutes(container, server);\n }\n}\n\n/**\n * 健康检查路由\n */\nfunction registerHealthRoutes(server: ApiServer): void {\n server.get('/health', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ok' }));\n }, { public: true });\n\n server.get('/ready', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ready' }));\n }, { public: true });\n\n // Dashboard 静态资源\n const staticDir = path.resolve(PACKAGE_ROOT, 'static/dashboard');\n registerDashboardRoutes(server, { staticDir });\n const settingsStaticDir = path.resolve(PACKAGE_ROOT, 'static/settings');\n registerSettingsRoutes(server, { staticDir: settingsStaticDir });\n}\n\n/**\n * 共享路由 (cloud 和 local 都有)\n */\nfunction registerSharedRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const chatService = container.resolve('chatService');\n const chatKitService = container.resolve('chatKitService');\n const chatKitStore = container.resolve('chatKitStore');\n const runExecutionBackend = container.resolve('runExecutionBackend');\n const matrixStore = container.resolve('matrixStore');\n const clientReconcilerCoordinator = container.resolve('clientReconcilerCoordinator');\n const inngestTaskScheduler = container.resolve('inngestTaskScheduler');\n const inngestRuntimeConfig = container.resolve('inngestRuntimeConfig');\n const rdfStorageStatsService = container.resolve('rdfStorageStatsService');\n const gatewayAccessKeyRepository = container.resolve('gatewayAccessKeyRepository');\n const gatewayInternalPodAccess = container.resolve('gatewayInternalPodAccess');\n const aiConnectionInvocationKeyIssuer = container.resolve('aiConnectionInvocationKeyIssuer');\n const providerConnectService = container.resolve('providerConnectService');\n const providerQuotaService = container.resolve('providerQuotaService', { allowUnregistered: true });\n const config = container.resolve('config') as ApiContainerConfig;\n const aiClientConfigurationService = resolveAiClientConfigurationService(container, config);\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true });\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true });\n const dnsCoordinator = container.resolve('dnsCoordinator', { allowUnregistered: true });\n const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true });\n const cloudTunnelProvider = container.resolve('tunnelProvider', { allowUnregistered: true });\n const tunnelProvider = localTunnelProvider ?? cloudTunnelProvider;\n const edgeCertificateBridge = createDynamicEdgeCertificateBridge(config);\n const certificateCapability = createCertificateCapability(\n container.resolve('certificateManager', { allowUnregistered: true }),\n container.resolve('acmeCertificateManager', { allowUnregistered: true }),\n container.resolve('clusterCertificateManager', { allowUnregistered: true }),\n edgeCertificateBridge,\n );\n const podLookupRepository = container.resolve('podLookupRepo');\n const accountRoleRepository = container.resolve('accountRoleRepo', { allowUnregistered: true });\n if (!podLookupRepository) {\n throw new Error('Pod settings route requires podLookupRepo');\n }\n\n registerEdgeNodeSignalRoutes(server, {\n repository: nodeRepo,\n dnsCoordinator: container.resolve('dnsCoordinator', { allowUnregistered: true }) as any,\n healthProbeService: container.resolve('healthProbeService', { allowUnregistered: true }) as any,\n });\n registerReachabilityRoutes(server, {\n repository: nodeRepo,\n baseStorageDomain: config.subdomain?.baseStorageDomain,\n apiBaseUrl: config.cloudApiEndpoint ?? process.env.XPOD_CLOUD_API_ENDPOINT ?? process.env.CSS_BASE_URL,\n });\n registerNodeRoutes(server, { repository: nodeRepo });\n const aiGatewayService = container.resolve('aiGatewayService');\n registerChatRoutes(server, {\n chatService,\n aiGatewayService,\n acceptanceEndpointsEnabled: process.env.XPOD_ACCEPTANCE_ENDPOINTS_ENABLED === 'true',\n });\n registerChatKitRoutes(server, { chatKitService });\n registerChatKitV1Routes(server, { store: chatKitStore });\n registerRunRoutes(server, { runStore: chatKitStore });\n registerMatrixRoutes(server, { store: matrixStore });\n registerCoordinationRoutes(server, { clientReconcilerCoordinator });\n registerInngestRoutes(server, {\n backend: runExecutionBackend,\n taskScheduler: inngestTaskScheduler,\n runtimeConfig: inngestRuntimeConfig,\n });\n registerRdfStatsRoutes(server, {\n rdfStorageStatsService,\n });\n registerAiGatewayManagementRoutes(server, {\n repository: gatewayAccessKeyRepository,\n deployment: config.edition,\n connectService: providerConnectService,\n quotaService: providerQuotaService,\n servicePrincipal: gatewayInternalPodAccess,\n aiClientConfiguration: aiClientConfigurationService?.capability(),\n aiConnectionInvocationKeyIssuer,\n });\n registerAiClientConfigurationRoutes(server, {\n service: aiClientConfigurationService,\n });\n const notificationOrigin = config.publicUrl ?? config.solidBaseUrl ?? process.env.CSS_BASE_URL ?? `http://${config.host === '0.0.0.0' ? '127.0.0.1' : config.host}:${config.port}`;\n registerDeviceNotificationRuntime(server, {\n origin: notificationOrigin,\n authorizeTopic: createOwnerOnlyNotificationTopicAuthorizer(notificationOrigin),\n });\n registerPodSettingsRoutes(server, {\n podLookupRepository,\n usageRepo: new UsageRepository(container.resolve('db')),\n aiConnectionStatusReader: new DrizzlePodAiConnectionStatusReader(gatewayInternalPodAccess),\n });\n registerNetworkSettingsRoutes(server, {\n endpoint: () => resolveNetworkEndpoint(config),\n ...createAddressReaders({\n endpoint: () => resolveNetworkEndpoint(config),\n port: config.port,\n publicUrls: [\n config.publicUrl,\n config.activeTunnelProfile?.publicUrl,\n ],\n }),\n publicAddresses: createPublicAddressReader({\n configuredUrls: [\n config.publicUrl,\n config.activeTunnelProfile?.publicUrl,\n ],\n ddnsManager,\n tunnelProvider,\n }),\n dnsStatusReader: createDnsStatusReader({ ddnsManager, dnsProvider, dnsCoordinator }),\n tunnelStatusReader: createTunnelStatusReader(tunnelProvider),\n tlsStatusReader: certificateCapability?.tlsStatusReader,\n certificateRenewer: certificateCapability?.certificateRenewer,\n authorizer: createDeploymentNetworkSettingsAuthorizer({\n deployment: config.edition,\n accountRoleRepository,\n }),\n });\n\n // Quota & Usage API (Business 对接)\n try {\n const quotaService = new DrizzleQuotaService({ identityDbUrl: config.databaseUrl });\n const usageRepo = new UsageRepository(container.resolve('db'));\n registerQuotaRoutes(server, { quotaService, usageRepo });\n registerUsageRoutes(server, { usageRepo });\n console.log('[Shared] Quota & Usage routes registered');\n } catch (error) {\n console.log(`[Shared] Quota & Usage routes not registered: ${error}`);\n }\n}\n\ntype DeviceNotificationTopicAuthorizer = NonNullable<DeviceNotificationRuntimeOptions['authorizeTopic']>;\n\nfunction createOwnerOnlyNotificationTopicAuthorizer(origin: string): DeviceNotificationTopicAuthorizer {\n return async ({ identity, topic }) => {\n // Owner-only fallback until a shared Solid Read permission reader is available for runtime injection.\n // This is not a full WebACL/ACP authorization decision.\n return topic.startsWith(new URL(`/${identity.localPart}/`, origin).toString());\n };\n}\n\nfunction resolveAiClientConfigurationService(\n container: AwilixContainer<ApiContainerCradle>,\n config: ApiContainerConfig,\n): AiClientConfigurationService | undefined {\n const injected = container.resolve('aiClientConfigurationService', { allowUnregistered: true });\n if (injected) return injected;\n const capability = config.aiClientConfiguration;\n if (!capability?.enabled || capability.authority !== 'local-filesystem') {\n return undefined;\n }\n return new AiClientConfigurationService({\n homeDir: capability.homeDir,\n backupRoot: capability.backupRoot,\n });\n}\n\nfunction createDynamicEdgeCertificateBridge(config: ApiContainerConfig): unknown {\n const bridgeId = resolveEdgeNodeCertificateCapabilityBridgeId({\n nodeId: config.nodeId,\n baseUrl: config.solidBaseUrl ?? config.publicUrl,\n });\n if (!bridgeId) {\n return undefined;\n }\n return {\n readCertificateStatus: async () => {\n return await findEdgeNodeCertificateCapabilityBridge(bridgeId)?.readCertificateStatus()\n ?? { supported: false, status: 'unsupported' };\n },\n renewCertificate: async () => {\n const bridge = findEdgeNodeCertificateCapabilityBridge(bridgeId);\n if (!bridge) {\n throw Object.assign(new Error('Certificate runtime is not available.'), {\n statusCode: 503,\n code: 'certificate_renewal_unavailable',\n });\n }\n return await bridge.renewCertificate();\n },\n isAvailable: async () => {\n return Boolean(await findEdgeNodeCertificateCapabilityBridge(bridgeId)?.isAvailable());\n },\n };\n}\n\n/**\n * Cloud 模式专属路由\n */\nfunction registerCloudRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n // 子域名管理 API (需要 SubdomainService)\n try {\n const subdomainService = container.resolve('subdomainService') as ApiContainerCradle['subdomainService'];\n if (subdomainService) {\n registerSubdomainRoutes(server, { subdomainService });\n console.log('[Cloud] Subdomain routes registered');\n }\n } catch {\n console.log('[Cloud] Subdomain routes not registered (service not available)');\n }\n\n // DDNS 服务\n try {\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true });\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true });\n const config = container.resolve('config') as ApiContainerConfig;\n\n if (ddnsRepo) {\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n if (baseStorageDomain) {\n registerDdnsRoutes(server, {\n ddnsRepo: ddnsRepo as any,\n dnsProvider: dnsProvider as any,\n defaultDomain: baseStorageDomain,\n });\n console.log(`[Cloud] DDNS routes registered (domain: ${baseStorageDomain})`);\n } else {\n console.log('[Cloud] DDNS routes not registered (no CSS_BASE_STORAGE_DOMAIN)');\n }\n }\n } catch {\n console.log('[Cloud] DDNS routes not registered (repo not available)');\n }\n\n // SP Provision API (SP 注册)\n try {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const config = container.resolve('config') as ApiContainerConfig;\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true }) as any;\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true }) as any;\n const tunnelProvider = container.resolve('tunnelProvider', { allowUnregistered: true }) as any;\n registerProvisionRoutes(server, {\n repository: nodeRepo,\n ddnsRepo,\n dnsProvider,\n tunnelProvider,\n baseUrl,\n baseStorageDomain,\n });\n console.log(`[Cloud] Provision routes registered${baseStorageDomain ? ` (baseStorageDomain: ${baseStorageDomain})` : ''}`);\n } catch {\n console.log('[Cloud] Provision routes not registered (dependencies not available)');\n }\n}\n\n/**\n * Local 模式专属路由\n */\nfunction registerLocalRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n const config = container.resolve('config') as ApiContainerConfig;\n registerLinxCapabilitiesRoutes(server);\n\n // Admin API (配置管理、重启)\n registerAdminRoutes(server, {\n internalAdminAuthSecret: config.gatewayAdminProxyAuthSecret,\n });\n // DDNS status (托管式 Local 模式)\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n registerAdminDdnsRoutes(server, { ddnsManager });\n } catch {\n // ignore\n }\n\n // 子域名客户端 API (通过 SubdomainClient 调用 Cloud)\n try {\n const subdomainClient = container.resolve('subdomainClient') as ApiContainerCradle['subdomainClient'];\n if (subdomainClient) {\n registerSubdomainClientRoutes(server, { subdomainClient });\n console.log('[Local] Subdomain client routes registered');\n }\n } catch {\n console.log('[Local] Subdomain client routes not registered (client not available)');\n }\n\n // Pod Provision API (SP 端,供 Cloud 回调创建 Pod)\n try {\n const config = container.resolve('config') as ApiContainerConfig;\n // rootDir: CSS 数据目录,默认 ./data\n const rootDir = process.env.CSS_ROOT_FILE_PATH || './data';\n // serviceToken 验证:从 SP 配置中读取\n const expectedServiceToken = config.serviceToken;\n\n if (expectedServiceToken) {\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const sparqlEndpoint = process.env.CSS_SPARQL_ENDPOINT || process.env.SPARQL_ENDPOINT;\n const identityDbUrl = process.env.CSS_IDENTITY_DB_URL || process.env.DATABASE_URL;\n const provisioningService = sparqlEndpoint && identityDbUrl\n ? new LocalPodProvisioningService({\n baseUrl,\n rootDir,\n sparqlEndpoint,\n identityDbUrl,\n rdfIndexPath: config.rdfIndexPath,\n oidcIssuer: process.env.oidcIssuer ?? config.oidcIssuer,\n authMode: config.authMode,\n })\n : undefined;\n\n registerPodManagementRoutes(server, {\n rootDir,\n verifyServiceToken: async (token: string) => (\n token === expectedServiceToken\n || verifyServiceAccessToken(token, { serviceToken: expectedServiceToken }).valid\n ),\n provisioningService,\n podLookupRepository: container.resolve('podLookupRepo', { allowUnregistered: true }),\n storageProviderBaseUrl: baseUrl,\n });\n console.log(`[Local] Pod provision routes registered (/provision/pods, /provision/webids, ${provisioningService ? 'css-compatible' : 'directory-only'})`);\n } else {\n console.log('[Local] Pod provision routes not registered (serviceToken not configured)');\n }\n } catch (error) {\n console.log(`[Local] Pod provision routes not registered: ${error}`);\n }\n\n // SP 状态查询 (供 Linx 查询 SP 配置状态)\n try {\n const config = container.resolve('config') as ApiContainerConfig;\n registerProvisionStatusRoute(server, {\n cloudUrl: config.cloudApiEndpoint,\n nodeId: config.nodeId,\n nodeToken: config.nodeToken,\n serviceToken: config.serviceToken,\n publicUrl: process.env.XPOD_PUBLIC_URL ?? config.publicUrl ?? process.env.CSS_BASE_URL,\n spDomain: process.env.XPOD_SP_DOMAIN ?? config.spDomain,\n localPort: readPositiveInteger(process.env.CSS_PORT ?? process.env.XPOD_PORT ?? process.env.PORT),\n tunnelToken: process.env.CLOUDFLARE_TUNNEL_TOKEN ?? process.env.SAKURA_TUNNEL_TOKEN ?? process.env.SAKURA_TOKEN,\n cloudBaseUrl: config.oidcIssuer || config.cloudApiEndpoint,\n provisionCode: process.env.XPOD_PROVISION_CODE ?? config.provisionCode,\n persistState: createLocalSetupProvisionStateWriter(\n config.localSetupPath,\n config.localSetupProviderId,\n ),\n });\n console.log('[Local] Provision status route registered (/provision/status)');\n } catch (error) {\n console.log(`[Local] Provision status route not registered: ${error}`);\n }\n}\n\nfunction readPositiveInteger(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const parsed = Number.parseInt(value, 10);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction resolveNetworkEndpoint(config: ApiContainerConfig): string {\n const configured = config.publicUrl\n ?? config.activeTunnelProfile?.publicUrl\n ?? config.solidBaseUrl\n ?? `http://${config.host === '0.0.0.0' ? '127.0.0.1' : config.host}:${config.port}/`;\n try {\n return new URL(configured).toString().replace(/\\/+$/u, '') + '/';\n } catch {\n return `http://127.0.0.1:${config.port}/`;\n }\n}\n"]}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../src/api/container/routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 路由注册\n *\n * 根据容器中的服务注册 API 路由\n */\n\nimport type { AwilixContainer } from 'awilix';\nimport type { ApiContainerCradle, ApiContainerConfig } from './types';\nimport type { ApiServer } from '../ApiServer';\n\nimport { registerEdgeNodeSignalRoutes } from '../handlers/EdgeNodeSignalHandler';\nimport { registerReachabilityRoutes } from '../handlers/ReachabilityHandler';\nimport { registerNodeRoutes } from '../handlers/NodeHandler';\nimport { registerChatRoutes } from '../handlers/ChatHandler';\nimport { registerSubdomainRoutes } from '../handlers/SubdomainHandler';\nimport { registerSubdomainClientRoutes } from '../handlers/SubdomainClientHandler';\nimport { registerDdnsRoutes } from '../handlers/DdnsHandler';\nimport { registerChatKitRoutes } from '../handlers/ChatKitHandler';\nimport { registerChatKitV1Routes } from '../handlers/ChatKitV1Handler';\nimport { registerInngestRoutes } from '../handlers/InngestHandler';\nimport { registerRunRoutes } from '../handlers/RunHandler';\nimport { registerMatrixRoutes } from '../handlers/MatrixHandler';\nimport { registerCoordinationRoutes } from '../handlers/CoordinationHandler';\nimport { registerDashboardRoutes } from '../handlers/DashboardHandler';\nimport { registerSettingsRoutes } from '../handlers/SettingsHandler';\nimport { registerAdminRoutes } from '../handlers/AdminHandler';\nimport { registerAdminDdnsRoutes } from '../handlers/AdminDdnsHandler';\nimport { registerLinxCapabilitiesRoutes } from '../handlers/LinxCapabilitiesHandler';\nimport { createLocalSetupProvisionStateWriter, registerProvisionRoutes, registerProvisionStatusRoute } from '../handlers/ProvisionHandler';\nimport { registerPodManagementRoutes } from '../handlers/PodManagementHandler';\nimport { DrizzlePodAiConnectionStatusReader, registerPodSettingsRoutes } from '../handlers/PodSettingsHandler';\nimport {\n createAddressReaders,\n createCertificateCapability,\n createDeploymentNetworkSettingsAuthorizer,\n createDnsStatusReader,\n createPublicAddressReader,\n createTunnelStatusReader,\n registerNetworkSettingsRoutes,\n} from '../handlers/NetworkSettingsHandler';\nimport { registerQuotaRoutes } from '../handlers/QuotaHandler';\nimport { registerUsageRoutes } from '../handlers/UsageHandler';\nimport { registerRdfStatsRoutes } from '../handlers/RdfStatsHandler';\nimport { registerAiGatewayManagementRoutes } from '../handlers/AiGatewayManagementHandler';\nimport { registerAiClientConfigurationRoutes } from '../handlers/AiClientConfigurationHandler';\nimport { registerDeviceNotificationRuntime, type DeviceNotificationRuntimeOptions } from '../handlers/DeviceNotificationRuntime';\nimport { AiClientConfigurationService } from '../service/AiClientConfigurationService';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport { UsageRepository } from '../../storage/quota/UsageRepository';\nimport { DrizzleQuotaService } from '../../quota/DrizzleQuotaService';\nimport { LocalPodProvisioningService } from '../../provision/LocalPodProvisioningService';\nimport { verifyServiceAccessToken } from '../../provision/ServiceAccessTokenCodec';\nimport {\n findEdgeNodeCertificateCapabilityBridge,\n resolveEdgeNodeCertificateCapabilityBridgeId,\n} from '../../edge/EdgeNodeCertificateCapabilityBridge';\nimport * as path from 'node:path';\nimport { PACKAGE_ROOT } from '../../runtime';\n\n/**\n * 注册所有 API 路由\n */\nexport function registerRoutes(container: AwilixContainer<ApiContainerCradle>): void {\n const server = container.resolve('apiServer') as ApiServer;\n const config = container.resolve('config') as ApiContainerConfig;\n\n // 公共健康检查端点\n registerHealthRoutes(server);\n\n // 共享路由\n registerSharedRoutes(container, server);\n\n // 根据 edition 注册专属路由\n if (config.edition === 'cloud') {\n registerCloudRoutes(container, server);\n } else {\n registerLocalRoutes(container, server);\n }\n}\n\n/**\n * 健康检查路由\n */\nfunction registerHealthRoutes(server: ApiServer): void {\n server.get('/health', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ok' }));\n }, { public: true });\n\n server.get('/ready', async (_req, res) => {\n res.statusCode = 200;\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ status: 'ready' }));\n }, { public: true });\n\n // Dashboard 静态资源\n const staticDir = path.resolve(PACKAGE_ROOT, 'static/dashboard');\n registerDashboardRoutes(server, { staticDir });\n const settingsStaticDir = path.resolve(PACKAGE_ROOT, 'static/settings');\n registerSettingsRoutes(server, { staticDir: settingsStaticDir });\n}\n\n/**\n * 共享路由 (cloud 和 local 都有)\n */\nfunction registerSharedRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const chatService = container.resolve('chatService');\n const chatKitService = container.resolve('chatKitService');\n const chatKitStore = container.resolve('chatKitStore');\n const runExecutionBackend = container.resolve('runExecutionBackend');\n const matrixStore = container.resolve('matrixStore');\n const clientReconcilerCoordinator = container.resolve('clientReconcilerCoordinator');\n const inngestTaskScheduler = container.resolve('inngestTaskScheduler');\n const inngestRuntimeConfig = container.resolve('inngestRuntimeConfig');\n const rdfStorageStatsService = container.resolve('rdfStorageStatsService');\n const hostedPodDataAccess = container.resolve('hostedPodDataAccess');\n const aiConnectionInvocationKeyIssuer = container.resolve('aiConnectionInvocationKeyIssuer');\n const providerConnectService = container.resolve('providerConnectService');\n const providerQuotaService = container.resolve('providerQuotaService', { allowUnregistered: true });\n const config = container.resolve('config') as ApiContainerConfig;\n const aiClientConfigurationService = resolveAiClientConfigurationService(container, config);\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true });\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true });\n const dnsCoordinator = container.resolve('dnsCoordinator', { allowUnregistered: true });\n const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true });\n const cloudTunnelProvider = container.resolve('tunnelProvider', { allowUnregistered: true });\n const tunnelProvider = localTunnelProvider ?? cloudTunnelProvider;\n const edgeCertificateBridge = createDynamicEdgeCertificateBridge(config);\n const certificateCapability = createCertificateCapability(\n container.resolve('certificateManager', { allowUnregistered: true }),\n container.resolve('acmeCertificateManager', { allowUnregistered: true }),\n container.resolve('clusterCertificateManager', { allowUnregistered: true }),\n edgeCertificateBridge,\n );\n const podLookupRepository = container.resolve('podLookupRepo');\n const accountRoleRepository = container.resolve('accountRoleRepo', { allowUnregistered: true });\n if (!podLookupRepository) {\n throw new Error('Pod settings route requires podLookupRepo');\n }\n\n registerEdgeNodeSignalRoutes(server, {\n repository: nodeRepo,\n dnsCoordinator: container.resolve('dnsCoordinator', { allowUnregistered: true }) as any,\n healthProbeService: container.resolve('healthProbeService', { allowUnregistered: true }) as any,\n });\n registerReachabilityRoutes(server, {\n repository: nodeRepo,\n baseStorageDomain: config.subdomain?.baseStorageDomain,\n apiBaseUrl: config.cloudApiEndpoint ?? process.env.XPOD_CLOUD_API_ENDPOINT ?? process.env.CSS_BASE_URL,\n });\n registerNodeRoutes(server, { repository: nodeRepo });\n const aiGatewayService = container.resolve('aiGatewayService');\n registerChatRoutes(server, {\n chatService,\n aiGatewayService,\n acceptanceEndpointsEnabled: process.env.XPOD_ACCEPTANCE_ENDPOINTS_ENABLED === 'true',\n });\n registerChatKitRoutes(server, { chatKitService });\n registerChatKitV1Routes(server, { store: chatKitStore });\n registerRunRoutes(server, { runStore: chatKitStore });\n registerMatrixRoutes(server, { store: matrixStore });\n registerCoordinationRoutes(server, { clientReconcilerCoordinator });\n registerInngestRoutes(server, {\n backend: runExecutionBackend,\n taskScheduler: inngestTaskScheduler,\n runtimeConfig: inngestRuntimeConfig,\n });\n registerRdfStatsRoutes(server, {\n rdfStorageStatsService,\n });\n registerAiGatewayManagementRoutes(server, {\n deployment: config.edition,\n connectService: providerConnectService,\n quotaService: providerQuotaService,\n aiClientConfiguration: aiClientConfigurationService?.capability(),\n aiConnectionInvocationKeyIssuer,\n });\n registerAiClientConfigurationRoutes(server, {\n service: aiClientConfigurationService,\n });\n const notificationOrigin = config.publicUrl ?? config.solidBaseUrl ?? process.env.CSS_BASE_URL ?? `http://${config.host === '0.0.0.0' ? '127.0.0.1' : config.host}:${config.port}`;\n registerDeviceNotificationRuntime(server, {\n origin: notificationOrigin,\n authorizeTopic: createOwnerOnlyNotificationTopicAuthorizer(notificationOrigin),\n });\n registerPodSettingsRoutes(server, {\n podLookupRepository,\n usageRepo: new UsageRepository(container.resolve('db')),\n aiConnectionStatusReader: new DrizzlePodAiConnectionStatusReader(hostedPodDataAccess),\n });\n registerNetworkSettingsRoutes(server, {\n endpoint: () => resolveNetworkEndpoint(config),\n ...createAddressReaders({\n endpoint: () => resolveNetworkEndpoint(config),\n port: config.port,\n publicUrls: [\n config.publicUrl,\n config.activeTunnelProfile?.publicUrl,\n ],\n }),\n publicAddresses: createPublicAddressReader({\n configuredUrls: [\n config.publicUrl,\n config.activeTunnelProfile?.publicUrl,\n ],\n ddnsManager,\n tunnelProvider,\n }),\n dnsStatusReader: createDnsStatusReader({ ddnsManager, dnsProvider, dnsCoordinator }),\n tunnelStatusReader: createTunnelStatusReader(tunnelProvider),\n tlsStatusReader: certificateCapability?.tlsStatusReader,\n certificateRenewer: certificateCapability?.certificateRenewer,\n authorizer: createDeploymentNetworkSettingsAuthorizer({\n deployment: config.edition,\n accountRoleRepository,\n }),\n });\n\n // Quota & Usage API (Business 对接)\n try {\n const quotaService = new DrizzleQuotaService({ identityDbUrl: config.databaseUrl });\n const usageRepo = new UsageRepository(container.resolve('db'));\n registerQuotaRoutes(server, { quotaService, usageRepo });\n registerUsageRoutes(server, { usageRepo });\n console.log('[Shared] Quota & Usage routes registered');\n } catch (error) {\n console.log(`[Shared] Quota & Usage routes not registered: ${error}`);\n }\n}\n\ntype DeviceNotificationTopicAuthorizer = NonNullable<DeviceNotificationRuntimeOptions['authorizeTopic']>;\n\nfunction createOwnerOnlyNotificationTopicAuthorizer(origin: string): DeviceNotificationTopicAuthorizer {\n return async ({ identity, topic }) => {\n // Owner-only fallback until a shared Solid Read permission reader is available for runtime injection.\n // This is not a full WebACL/ACP authorization decision.\n return topic.startsWith(new URL(`/${identity.localPart}/`, origin).toString());\n };\n}\n\nfunction resolveAiClientConfigurationService(\n container: AwilixContainer<ApiContainerCradle>,\n config: ApiContainerConfig,\n): AiClientConfigurationService | undefined {\n const injected = container.resolve('aiClientConfigurationService', { allowUnregistered: true });\n if (injected) return injected;\n const capability = config.aiClientConfiguration;\n if (!capability?.enabled || capability.authority !== 'local-filesystem') {\n return undefined;\n }\n return new AiClientConfigurationService({\n homeDir: capability.homeDir,\n backupRoot: capability.backupRoot,\n });\n}\n\nfunction createDynamicEdgeCertificateBridge(config: ApiContainerConfig): unknown {\n const bridgeId = resolveEdgeNodeCertificateCapabilityBridgeId({\n nodeId: config.nodeId,\n baseUrl: config.solidBaseUrl ?? config.publicUrl,\n });\n if (!bridgeId) {\n return undefined;\n }\n return {\n readCertificateStatus: async () => {\n return await findEdgeNodeCertificateCapabilityBridge(bridgeId)?.readCertificateStatus()\n ?? { supported: false, status: 'unsupported' };\n },\n renewCertificate: async () => {\n const bridge = findEdgeNodeCertificateCapabilityBridge(bridgeId);\n if (!bridge) {\n throw Object.assign(new Error('Certificate runtime is not available.'), {\n statusCode: 503,\n code: 'certificate_renewal_unavailable',\n });\n }\n return await bridge.renewCertificate();\n },\n isAvailable: async () => {\n return Boolean(await findEdgeNodeCertificateCapabilityBridge(bridgeId)?.isAvailable());\n },\n };\n}\n\n/**\n * Cloud 模式专属路由\n */\nfunction registerCloudRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n // 子域名管理 API (需要 SubdomainService)\n try {\n const subdomainService = container.resolve('subdomainService') as ApiContainerCradle['subdomainService'];\n if (subdomainService) {\n registerSubdomainRoutes(server, { subdomainService });\n console.log('[Cloud] Subdomain routes registered');\n }\n } catch {\n console.log('[Cloud] Subdomain routes not registered (service not available)');\n }\n\n // DDNS 服务\n try {\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true });\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true });\n const config = container.resolve('config') as ApiContainerConfig;\n\n if (ddnsRepo) {\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n if (baseStorageDomain) {\n registerDdnsRoutes(server, {\n ddnsRepo: ddnsRepo as any,\n dnsProvider: dnsProvider as any,\n defaultDomain: baseStorageDomain,\n });\n console.log(`[Cloud] DDNS routes registered (domain: ${baseStorageDomain})`);\n } else {\n console.log('[Cloud] DDNS routes not registered (no CSS_BASE_STORAGE_DOMAIN)');\n }\n }\n } catch {\n console.log('[Cloud] DDNS routes not registered (repo not available)');\n }\n\n // SP Provision API (SP 注册)\n try {\n const nodeRepo = container.resolve('nodeRepo') as EdgeNodeRepository;\n const config = container.resolve('config') as ApiContainerConfig;\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const baseStorageDomain = config.subdomain?.baseStorageDomain;\n const ddnsRepo = container.resolve('ddnsRepo', { allowUnregistered: true }) as any;\n const dnsProvider = container.resolve('dnsProvider', { allowUnregistered: true }) as any;\n const tunnelProvider = container.resolve('tunnelProvider', { allowUnregistered: true }) as any;\n registerProvisionRoutes(server, {\n repository: nodeRepo,\n ddnsRepo,\n dnsProvider,\n tunnelProvider,\n baseUrl,\n baseStorageDomain,\n });\n console.log(`[Cloud] Provision routes registered${baseStorageDomain ? ` (baseStorageDomain: ${baseStorageDomain})` : ''}`);\n } catch {\n console.log('[Cloud] Provision routes not registered (dependencies not available)');\n }\n}\n\n/**\n * Local 模式专属路由\n */\nfunction registerLocalRoutes(\n container: AwilixContainer<ApiContainerCradle>,\n server: ApiServer,\n): void {\n const config = container.resolve('config') as ApiContainerConfig;\n registerLinxCapabilitiesRoutes(server);\n\n // Admin API (配置管理、重启)\n registerAdminRoutes(server, {\n internalAdminAuthSecret: config.gatewayAdminProxyAuthSecret,\n });\n // DDNS status (托管式 Local 模式)\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n registerAdminDdnsRoutes(server, { ddnsManager });\n } catch {\n // ignore\n }\n\n // 子域名客户端 API (通过 SubdomainClient 调用 Cloud)\n try {\n const subdomainClient = container.resolve('subdomainClient') as ApiContainerCradle['subdomainClient'];\n if (subdomainClient) {\n registerSubdomainClientRoutes(server, { subdomainClient });\n console.log('[Local] Subdomain client routes registered');\n }\n } catch {\n console.log('[Local] Subdomain client routes not registered (client not available)');\n }\n\n // Pod Provision API (SP 端,供 Cloud 回调创建 Pod)\n try {\n const config = container.resolve('config') as ApiContainerConfig;\n // rootDir: CSS 数据目录,默认 ./data\n const rootDir = process.env.CSS_ROOT_FILE_PATH || './data';\n // serviceToken 验证:从 SP 配置中读取\n const expectedServiceToken = config.serviceToken;\n\n if (expectedServiceToken) {\n const baseUrl = process.env.CSS_BASE_URL || 'http://localhost:3000/';\n const sparqlEndpoint = process.env.CSS_SPARQL_ENDPOINT || process.env.SPARQL_ENDPOINT;\n const identityDbUrl = process.env.CSS_IDENTITY_DB_URL || process.env.DATABASE_URL;\n const provisioningService = sparqlEndpoint && identityDbUrl\n ? new LocalPodProvisioningService({\n baseUrl,\n rootDir,\n sparqlEndpoint,\n identityDbUrl,\n rdfIndexPath: config.rdfIndexPath,\n oidcIssuer: process.env.oidcIssuer ?? config.oidcIssuer,\n authMode: config.authMode,\n })\n : undefined;\n\n registerPodManagementRoutes(server, {\n rootDir,\n verifyServiceToken: async (token: string) => (\n token === expectedServiceToken\n || verifyServiceAccessToken(token, { serviceToken: expectedServiceToken }).valid\n ),\n provisioningService,\n podLookupRepository: container.resolve('podLookupRepo', { allowUnregistered: true }),\n storageProviderBaseUrl: baseUrl,\n });\n console.log(`[Local] Pod provision routes registered (/provision/pods, /provision/webids, ${provisioningService ? 'css-compatible' : 'directory-only'})`);\n } else {\n console.log('[Local] Pod provision routes not registered (serviceToken not configured)');\n }\n } catch (error) {\n console.log(`[Local] Pod provision routes not registered: ${error}`);\n }\n\n // SP 状态查询 (供 Linx 查询 SP 配置状态)\n try {\n const config = container.resolve('config') as ApiContainerConfig;\n registerProvisionStatusRoute(server, {\n cloudUrl: config.cloudApiEndpoint,\n nodeId: config.nodeId,\n nodeToken: config.nodeToken,\n serviceToken: config.serviceToken,\n publicUrl: process.env.XPOD_PUBLIC_URL ?? config.publicUrl ?? process.env.CSS_BASE_URL,\n spDomain: process.env.XPOD_SP_DOMAIN ?? config.spDomain,\n localPort: readPositiveInteger(process.env.CSS_PORT ?? process.env.XPOD_PORT ?? process.env.PORT),\n tunnelToken: process.env.CLOUDFLARE_TUNNEL_TOKEN ?? process.env.SAKURA_TUNNEL_TOKEN ?? process.env.SAKURA_TOKEN,\n cloudBaseUrl: config.oidcIssuer || config.cloudApiEndpoint,\n provisionCode: process.env.XPOD_PROVISION_CODE ?? config.provisionCode,\n persistState: createLocalSetupProvisionStateWriter(\n config.localSetupPath,\n config.localSetupProviderId,\n ),\n });\n console.log('[Local] Provision status route registered (/provision/status)');\n } catch (error) {\n console.log(`[Local] Provision status route not registered: ${error}`);\n }\n}\n\nfunction readPositiveInteger(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const parsed = Number.parseInt(value, 10);\n return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;\n}\n\nfunction resolveNetworkEndpoint(config: ApiContainerConfig): string {\n const configured = config.publicUrl\n ?? config.activeTunnelProfile?.publicUrl\n ?? config.solidBaseUrl\n ?? `http://${config.host === '0.0.0.0' ? '127.0.0.1' : config.host}:${config.port}/`;\n try {\n return new URL(configured).toString().replace(/\\/+$/u, '') + '/';\n } catch {\n return `http://127.0.0.1:${config.port}/`;\n }\n}\n"]}
@@ -6,7 +6,6 @@
6
6
  import type { ApiServer } from '../ApiServer';
7
7
  import type { AuthMiddleware } from '../middleware/AuthMiddleware';
8
8
  import type { Authenticator } from '../auth/Authenticator';
9
- import type { GatewayAccessKeyRepository } from '../ai-gateway/auth/GatewayApiKeyAuthenticator';
10
9
  import type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';
11
10
  import type { ServiceTokenRepositoryPort } from '../../identity/drizzle/ServiceTokenRepository';
12
11
  import type { VercelChatService } from '../service/VercelChatService';
@@ -48,7 +47,7 @@ import type { ProviderRegistry as GatewayProviderRegistry } from '../ai-gateway/
48
47
  import type { SessionAffinityStore } from '../ai-gateway/routing/SessionAffinityStore';
49
48
  import type { AiConnectionInvocationKeyIssuer } from '../ai-gateway/auth/AiConnectionInvocationKeyIssuer';
50
49
  import type { InvocationTokenCodec } from '../ai-gateway/auth/InvocationTokenCodec';
51
- import type { ClientCredentialsInternalPodAccessTokenProvider } from '../ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider';
50
+ import type { HostedPodDataAccess } from '../ai-gateway/pod/HostedPodDataAccess';
52
51
  import type { AiClientConfigurationService } from '../service/AiClientConfigurationService';
53
52
  /**
54
53
  * 容器配置
@@ -95,16 +94,16 @@ export interface ApiContainerConfig {
95
94
  /** CSS Token 端点 */
96
95
  cssTokenEndpoint: string;
97
96
  solidBaseUrl?: string;
98
- /** Gateway locator encryption secret. Internal platform secret; not a user/provider AI credential. */
99
- gatewayLocatorSecret?: string;
100
- gatewayLocatorKeyId?: string;
101
- gatewayPreviousLocatorSecrets?: Array<{
97
+ /** Independent short-lived AI Connection invocation token key. Falls back to process-ephemeral when omitted. */
98
+ aiConnectionInvocationSecret?: string;
99
+ aiConnectionInvocationKeyId?: string;
100
+ aiConnectionPreviousInvocationSecrets?: Array<{
102
101
  kid: string;
103
102
  secret: string;
104
103
  }>;
104
+ /** Independent session-affinity hashing secret. Falls back to process-ephemeral when omitted. */
105
+ aiGatewaySessionAffinitySecret?: string;
105
106
  /** Internal service client used to read user-owned private Pod gateway-key hashes. */
106
- gatewayInternalClientId?: string;
107
- gatewayInternalClientSecret?: string;
108
107
  /** Runtime-generated secret used only between GatewayProxy and the internal API server for admin ingress evidence. */
109
108
  gatewayAdminProxyAuthSecret?: string;
110
109
  /** AI Provider Connect is disabled by default for backwards-compatible startup. */
@@ -190,8 +189,7 @@ export interface ApiContainerCradle {
190
189
  authenticator: Authenticator;
191
190
  nodeRepo: EdgeNodeRepository;
192
191
  serviceTokenRepo: ServiceTokenRepositoryPort;
193
- gatewayInternalPodAccess?: ClientCredentialsInternalPodAccessTokenProvider;
194
- gatewayAccessKeyRepository: GatewayAccessKeyRepository;
192
+ hostedPodDataAccess: HostedPodDataAccess;
195
193
  invocationTokenCodec: InvocationTokenCodec;
196
194
  aiConnectionInvocationKeyIssuer: AiConnectionInvocationKeyIssuer;
197
195
  aiClientConfigurationService?: AiClientConfigurationService;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/container/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG","sourcesContent":["/**\n * API Container 依赖类型定义\n *\n * 定义容器中注册的所有服务接口\n */\n\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthMiddleware } from '../middleware/AuthMiddleware';\nimport type { Authenticator } from '../auth/Authenticator';\nimport type { GatewayAccessKeyRepository } from '../ai-gateway/auth/GatewayApiKeyAuthenticator';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport type { ServiceTokenRepositoryPort } from '../../identity/drizzle/ServiceTokenRepository';\nimport type { VercelChatService } from '../service/VercelChatService';\nimport type { SubdomainService } from '../../subdomain/SubdomainService';\nimport type { SubdomainClient } from '../../subdomain/SubdomainClient';\nimport type { DnsProvider } from '../../dns/DnsProvider';\nimport type { TunnelProvider } from '../../tunnel/TunnelProvider';\nimport type { ActiveTunnelProvider, TunnelProfile } from '../../tunnel/TunnelProfiles';\nimport type { AcmeCertificateManager } from '../../edge/acme/AcmeCertificateManager';\nimport type { ClusterCertificateManager } from '../../edge/acme/ClusterCertificateManager';\nimport type { EdgeNodeCertificateCapabilityBridge } from '../../edge/EdgeNodeCertificateCapabilityBridge';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport type { DdnsRepository } from '../../identity/drizzle/DdnsRepository';\nimport type { PodLookupRepository } from '../../identity/drizzle/PodLookupRepository';\nimport type { AccountRoleRepository } from '../../identity/drizzle/AccountRoleRepository';\nimport type { ChatKitService, AiProvider } from '../chatkit';\nimport type { StoreContext } from '../chatkit/store';\nimport type { PodChatKitStore } from '../chatkit/pod-store';\nimport type { RuntimeHost } from '../../runtime/host/types';\nimport type { ProviderRegistry, EmbeddingService } from '../../ai/service';\nimport type { VectorService } from '../service/VectorService';\nimport type { RdfSearchIndexingService } from '../service/RdfSearchIndexingService';\nimport type { RdfStorageStatsService } from '../service/RdfStorageStatsService';\nimport type { InngestRunExecutionBackend } from '../runs/InngestRunExecutionBackend';\nimport type { RunContextRetriever } from '../runs/RunExecutionBackend';\nimport type { EmbeddedInngestRuntimeConfig } from '../runs/EmbeddedInngestService';\nimport type { RunAuthContextRegistry } from '../runs/RunAuthContextRegistry';\nimport type { TaskAuthBindingService, TaskService, InngestTaskScheduler } from '../tasks';\nimport type { PodMatrixStore } from '../matrix';\nimport type { ClientReconcilerCoordinator, ServerGroupReconcilerService } from '../reconciler';\nimport type { AuthMode } from '../../authorization/AuthMode';\nimport type { RdfEngineLike } from '../../storage/rdf';\nimport type { CredentialVault } from '../ai-gateway/credentials/CredentialVault';\nimport type { ProviderConnectService } from '../ai-gateway/connect';\nimport type { ProviderQuotaService } from '../ai-gateway/quota';\nimport type { AiGatewayService, GatewayCredentialStore } from '../ai-gateway/AiGatewayService';\nimport type { ProviderRuntimeRegistry } from '../ai-gateway/providers/ProviderRuntimeRegistry';\nimport type { ProviderRegistry as GatewayProviderRegistry } from '../ai-gateway/providers/ProviderRegistry';\nimport type { SessionAffinityStore } from '../ai-gateway/routing/SessionAffinityStore';\nimport type { AiConnectionInvocationKeyIssuer } from '../ai-gateway/auth/AiConnectionInvocationKeyIssuer';\nimport type { InvocationTokenCodec } from '../ai-gateway/auth/InvocationTokenCodec';\nimport type { ClientCredentialsInternalPodAccessTokenProvider } from '../ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider';\nimport type { AiClientConfigurationService } from '../service/AiClientConfigurationService';\n\n/**\n * 容器配置\n */\nexport interface ApiContainerConfig {\n /** 运行模式: cloud 持有密钥, local 调用远程 */\n edition: 'cloud' | 'local';\n\n /** API Server 端口 */\n port: number;\n\n /** API Server 主机 */\n host: string;\n\n /** API Server Unix socket 路径 */\n socketPath?: string;\n\n /** Runtime host implementation */\n runtimeHost?: RuntimeHost;\n\n /** Solid authorization mode used by CSS and SP-local Pod provisioning. */\n authMode: AuthMode;\n\n /** RDF term-id index used by CSS LDP structured reads. */\n rdfIndexPath?: string;\n\n /** 数据库连接 URL */\n databaseUrl: string;\n\n /** RDF/SPARQL facts database connection URL. */\n sparqlEndpoint?: string;\n\n /** Route SPARQL reads through an installed native SPARQL provider. */\n rdfNativeSparqlEnabled?: boolean;\n\n /** Redis connection URL, used by embedded infrastructure such as Inngest in cloud mode. */\n redisUrl?: string;\n\n /** Embedded Inngest runtime configuration. */\n inngest?: {\n enabled: boolean;\n mode?: 'managed' | 'spawn';\n port?: number;\n host?: string;\n baseUrl?: string;\n eventKey?: string;\n signingKey?: string;\n binaryPath?: string;\n sqliteDir?: string;\n };\n\n /** Resolved runtime config passed from API bootstrap after starting/locating Inngest. */\n inngestRuntimeConfig?: EmbeddedInngestRuntimeConfig;\n\n /** CORS 允许的源 */\n corsOrigins: string[];\n\n /** CSS Token 端点 */\n cssTokenEndpoint: string;\n solidBaseUrl?: string;\n\n /** Gateway locator encryption secret. Internal platform secret; not a user/provider AI credential. */\n gatewayLocatorSecret?: string;\n gatewayLocatorKeyId?: string;\n gatewayPreviousLocatorSecrets?: Array<{ kid: string; secret: string }>;\n\n /** Internal service client used to read user-owned private Pod gateway-key hashes. */\n gatewayInternalClientId?: string;\n gatewayInternalClientSecret?: string;\n\n /** Runtime-generated secret used only between GatewayProxy and the internal API server for admin ingress evidence. */\n gatewayAdminProxyAuthSecret?: string;\n\n /** AI Provider Connect is disabled by default for backwards-compatible startup. */\n aiGatewayConnectEnabled?: boolean;\n /** Local filesystem host capability for AI coding-client configuration. Disabled unless explicitly injected. */\n aiClientConfiguration?: {\n enabled: boolean;\n homeDir: string;\n backupRoot?: string;\n authority: 'local-filesystem';\n };\n /** Platform signing secret for short-lived provider Connect attempts. */\n aiGatewayConnectSigningSecret?: string;\n /** Xpod/Moonshot-issued Kimi device-code OAuth client id. Never reuse official CLI ids. */\n aiGatewayKimiClientId?: string;\n /** Generic Pod SecretCell credential vault factory, configured by Xpod operations. */\n secretCellCredentialVaultFactory?: () => CredentialVault;\n /** Explicit provider endpoint overrides for controlled deployments and local E2E fixtures. */\n aiGatewayProviderBaseUrls?: Partial<Record<'openai', string>>;\n\n /** 子域名功能配置 (cloud 模式) */\n subdomain?: {\n /** 节点域名根域名 (如 undefineds.site),有值即启用子域名功能 */\n baseStorageDomain?: string;\n cloudflareAccountId?: string;\n cloudflareApiToken?: string;\n tencentDnsSecretId?: string;\n tencentDnsSecretKey?: string;\n };\n\n /** Cloud API 端点 (local 托管式,调用 cloud 的子域名 API) */\n cloudApiEndpoint?: string;\n\n /** 节点 ID (local 托管式) */\n nodeId?: string;\n\n /** 节点 Token (local 托管式,调用 Cloud API 的认证) */\n nodeToken?: string;\n\n /** Local SP service token(Cloud 回调 Local、Local 服务级 API 的唯一服务凭据) */\n serviceToken?: string;\n\n /** 已签发的 provisionCode(Local 首次注册/刷新后持久化恢复) */\n provisionCode?: string;\n\n /** Local canonical public URL(通常来自 CSS_BASE_URL,也可从 setup 恢复) */\n publicUrl?: string;\n\n /** Cloud 分配或用户指定的 SP 域名 */\n spDomain?: string;\n\n /** Local setup/provision 状态文件路径 */\n localSetupPath?: string;\n\n /** Local setup/provision 状态文件中的 provider key */\n localSetupProviderId?: string;\n\n /** OIDC Issuer URL (local 托管式,使用 Cloud IdP) */\n oidcIssuer?: string;\n\n /** Active tunnel provider after resolving profile selection. */\n tunnelProvider?: ActiveTunnelProvider;\n\n /** Recorded tunnel profiles. Only tunnelActiveProfileId/activeTunnelProfile takes effect at runtime. */\n tunnelProfiles?: TunnelProfile[];\n\n /** Selected tunnel profile id. */\n tunnelActiveProfileId?: string;\n\n /** Selected tunnel profile. */\n activeTunnelProfile?: TunnelProfile;\n\n /** Cloudflare Tunnel Token (local 托管式/自管式,启动 cloudflared) */\n cloudflareTunnelToken?: string;\n\n /** SakuraFRP Tunnel Token (SAKURA_TUNNEL_TOKEN;local 托管式/自管式,启动 frpc) */\n sakuraTunnelToken?: string;\n\n /** ngrok authtoken (local only; not sent to Cloud). */\n ngrokAuthToken?: string;\n\n /** Fixed ngrok endpoint/custom domain, e.g. https://example.ngrok-free.dev. */\n ngrokUrl?: string;\n\n /** ngrok executable path. */\n ngrokPath?: string;\n\n /** 是否接受 Edge 节点注册 (cloud 模式) */\n edgeNodesEnabled?: boolean;\n}\n\nimport { EdgeNodeDnsCoordinator } from '../../edge/EdgeNodeDnsCoordinator';\nimport { EdgeNodeHealthProbeService } from '../../edge/EdgeNodeHealthProbeService';\nimport { EdgeNodeCapabilityDetector } from '../../edge/EdgeNodeCapabilityDetector';\nimport { LocalNetworkManager } from '../../edge/LocalNetworkManager';\nimport { DdnsManager } from '../../edge/DdnsManager';\n\n/**\n * 容器中注册的所有服务\n */\nexport interface ApiContainerCradle {\n // 配置\n config: ApiContainerConfig;\n\n // 核心服务\n db: IdentityDatabase;\n apiServer: ApiServer;\n authMiddleware: AuthMiddleware;\n authenticator: Authenticator;\n\n // 仓库\n nodeRepo: EdgeNodeRepository;\n serviceTokenRepo: ServiceTokenRepositoryPort;\n gatewayInternalPodAccess?: ClientCredentialsInternalPodAccessTokenProvider;\n gatewayAccessKeyRepository: GatewayAccessKeyRepository;\n invocationTokenCodec: InvocationTokenCodec;\n aiConnectionInvocationKeyIssuer: AiConnectionInvocationKeyIssuer;\n aiClientConfigurationService?: AiClientConfigurationService;\n providerConnectService: ProviderConnectService;\n providerQuotaService?: ProviderQuotaService;\n gatewayProviderRegistry: GatewayProviderRegistry;\n gatewayCredentialStore: GatewayCredentialStore;\n gatewayRuntimeRegistry: ProviderRuntimeRegistry;\n gatewaySessionAffinityStore: SessionAffinityStore;\n aiGatewayService: AiGatewayService;\n\n // 业务服务\n chatService: VercelChatService;\n\n // ChatKit 服务 (OpenAI ChatKit 协议)\n chatKitStore: PodChatKitStore;\n chatKitAiProvider: AiProvider;\n inngestRuntimeConfig: EmbeddedInngestRuntimeConfig | undefined;\n runAuthContextRegistry: RunAuthContextRegistry;\n rdfEngine: RdfEngineLike | undefined;\n runContextRetriever: RunContextRetriever<StoreContext> | undefined;\n rdfSearchIndexingService: RdfSearchIndexingService | undefined;\n runExecutionBackend: InngestRunExecutionBackend;\n taskAuthBindingService: TaskAuthBindingService<StoreContext>;\n taskService: TaskService<StoreContext>;\n inngestTaskScheduler: InngestTaskScheduler<StoreContext>;\n chatKitService: ChatKitService<StoreContext>;\n matrixStore: PodMatrixStore;\n clientReconcilerCoordinator: ClientReconcilerCoordinator;\n serverGroupReconcilerService: ServerGroupReconcilerService;\n providerRegistry: ProviderRegistry;\n embeddingService: EmbeddingService;\n vectorService: VectorService;\n rdfStorageStatsService: RdfStorageStatsService;\n\n // Cloud 模式: 身份服务\n ddnsRepo?: DdnsRepository;\n podLookupRepo?: PodLookupRepository;\n accountRoleRepo?: AccountRoleRepository;\n\n // 子域名相关 (可选,按 edition 注册)\n // Cloud 模式 或 Local 自管模式\n dnsProvider?: DnsProvider;\n dnsCoordinator?: EdgeNodeDnsCoordinator;\n healthProbeService?: EdgeNodeHealthProbeService;\n capabilityDetector?: EdgeNodeCapabilityDetector;\n localNetworkManager?: LocalNetworkManager;\n\n tunnelProvider?: TunnelProvider;\n subdomainService?: SubdomainService;\n // Local 托管式\n subdomainClient?: SubdomainClient;\n // Local 托管式 DDNS 管理\n ddnsManager?: DdnsManager;\n // Local 托管式/自管式 (启动 cloudflared)\n localTunnelProvider?: TunnelProvider;\n\n // Optional runtime certificate managers. Routes only enable TLS status/renewal\n // when one of these services is explicitly registered by the active profile.\n edgeNodeCertificateCapabilityBridge?: EdgeNodeCertificateCapabilityBridge;\n certificateManager?: unknown;\n acmeCertificateManager?: AcmeCertificateManager;\n clusterCertificateManager?: ClusterCertificateManager;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/container/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG","sourcesContent":["/**\n * API Container 依赖类型定义\n *\n * 定义容器中注册的所有服务接口\n */\n\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthMiddleware } from '../middleware/AuthMiddleware';\nimport type { Authenticator } from '../auth/Authenticator';\nimport type { EdgeNodeRepository } from '../../identity/drizzle/EdgeNodeRepository';\nimport type { ServiceTokenRepositoryPort } from '../../identity/drizzle/ServiceTokenRepository';\nimport type { VercelChatService } from '../service/VercelChatService';\nimport type { SubdomainService } from '../../subdomain/SubdomainService';\nimport type { SubdomainClient } from '../../subdomain/SubdomainClient';\nimport type { DnsProvider } from '../../dns/DnsProvider';\nimport type { TunnelProvider } from '../../tunnel/TunnelProvider';\nimport type { ActiveTunnelProvider, TunnelProfile } from '../../tunnel/TunnelProfiles';\nimport type { AcmeCertificateManager } from '../../edge/acme/AcmeCertificateManager';\nimport type { ClusterCertificateManager } from '../../edge/acme/ClusterCertificateManager';\nimport type { EdgeNodeCertificateCapabilityBridge } from '../../edge/EdgeNodeCertificateCapabilityBridge';\nimport type { IdentityDatabase } from '../../identity/drizzle/db';\nimport type { DdnsRepository } from '../../identity/drizzle/DdnsRepository';\nimport type { PodLookupRepository } from '../../identity/drizzle/PodLookupRepository';\nimport type { AccountRoleRepository } from '../../identity/drizzle/AccountRoleRepository';\nimport type { ChatKitService, AiProvider } from '../chatkit';\nimport type { StoreContext } from '../chatkit/store';\nimport type { PodChatKitStore } from '../chatkit/pod-store';\nimport type { RuntimeHost } from '../../runtime/host/types';\nimport type { ProviderRegistry, EmbeddingService } from '../../ai/service';\nimport type { VectorService } from '../service/VectorService';\nimport type { RdfSearchIndexingService } from '../service/RdfSearchIndexingService';\nimport type { RdfStorageStatsService } from '../service/RdfStorageStatsService';\nimport type { InngestRunExecutionBackend } from '../runs/InngestRunExecutionBackend';\nimport type { RunContextRetriever } from '../runs/RunExecutionBackend';\nimport type { EmbeddedInngestRuntimeConfig } from '../runs/EmbeddedInngestService';\nimport type { RunAuthContextRegistry } from '../runs/RunAuthContextRegistry';\nimport type { TaskAuthBindingService, TaskService, InngestTaskScheduler } from '../tasks';\nimport type { PodMatrixStore } from '../matrix';\nimport type { ClientReconcilerCoordinator, ServerGroupReconcilerService } from '../reconciler';\nimport type { AuthMode } from '../../authorization/AuthMode';\nimport type { RdfEngineLike } from '../../storage/rdf';\nimport type { CredentialVault } from '../ai-gateway/credentials/CredentialVault';\nimport type { ProviderConnectService } from '../ai-gateway/connect';\nimport type { ProviderQuotaService } from '../ai-gateway/quota';\nimport type { AiGatewayService, GatewayCredentialStore } from '../ai-gateway/AiGatewayService';\nimport type { ProviderRuntimeRegistry } from '../ai-gateway/providers/ProviderRuntimeRegistry';\nimport type { ProviderRegistry as GatewayProviderRegistry } from '../ai-gateway/providers/ProviderRegistry';\nimport type { SessionAffinityStore } from '../ai-gateway/routing/SessionAffinityStore';\nimport type { AiConnectionInvocationKeyIssuer } from '../ai-gateway/auth/AiConnectionInvocationKeyIssuer';\nimport type { InvocationTokenCodec } from '../ai-gateway/auth/InvocationTokenCodec';\nimport type { HostedPodDataAccess } from '../ai-gateway/pod/HostedPodDataAccess';\nimport type { AiClientConfigurationService } from '../service/AiClientConfigurationService';\n\n/**\n * 容器配置\n */\nexport interface ApiContainerConfig {\n /** 运行模式: cloud 持有密钥, local 调用远程 */\n edition: 'cloud' | 'local';\n\n /** API Server 端口 */\n port: number;\n\n /** API Server 主机 */\n host: string;\n\n /** API Server Unix socket 路径 */\n socketPath?: string;\n\n /** Runtime host implementation */\n runtimeHost?: RuntimeHost;\n\n /** Solid authorization mode used by CSS and SP-local Pod provisioning. */\n authMode: AuthMode;\n\n /** RDF term-id index used by CSS LDP structured reads. */\n rdfIndexPath?: string;\n\n /** 数据库连接 URL */\n databaseUrl: string;\n\n /** RDF/SPARQL facts database connection URL. */\n sparqlEndpoint?: string;\n\n /** Route SPARQL reads through an installed native SPARQL provider. */\n rdfNativeSparqlEnabled?: boolean;\n\n /** Redis connection URL, used by embedded infrastructure such as Inngest in cloud mode. */\n redisUrl?: string;\n\n /** Embedded Inngest runtime configuration. */\n inngest?: {\n enabled: boolean;\n mode?: 'managed' | 'spawn';\n port?: number;\n host?: string;\n baseUrl?: string;\n eventKey?: string;\n signingKey?: string;\n binaryPath?: string;\n sqliteDir?: string;\n };\n\n /** Resolved runtime config passed from API bootstrap after starting/locating Inngest. */\n inngestRuntimeConfig?: EmbeddedInngestRuntimeConfig;\n\n /** CORS 允许的源 */\n corsOrigins: string[];\n\n /** CSS Token 端点 */\n cssTokenEndpoint: string;\n solidBaseUrl?: string;\n\n /** Independent short-lived AI Connection invocation token key. Falls back to process-ephemeral when omitted. */\n aiConnectionInvocationSecret?: string;\n aiConnectionInvocationKeyId?: string;\n aiConnectionPreviousInvocationSecrets?: Array<{ kid: string; secret: string }>;\n\n /** Independent session-affinity hashing secret. Falls back to process-ephemeral when omitted. */\n aiGatewaySessionAffinitySecret?: string;\n\n /** Internal service client used to read user-owned private Pod gateway-key hashes. */\n\n /** Runtime-generated secret used only between GatewayProxy and the internal API server for admin ingress evidence. */\n gatewayAdminProxyAuthSecret?: string;\n\n /** AI Provider Connect is disabled by default for backwards-compatible startup. */\n aiGatewayConnectEnabled?: boolean;\n /** Local filesystem host capability for AI coding-client configuration. Disabled unless explicitly injected. */\n aiClientConfiguration?: {\n enabled: boolean;\n homeDir: string;\n backupRoot?: string;\n authority: 'local-filesystem';\n };\n /** Platform signing secret for short-lived provider Connect attempts. */\n aiGatewayConnectSigningSecret?: string;\n /** Xpod/Moonshot-issued Kimi device-code OAuth client id. Never reuse official CLI ids. */\n aiGatewayKimiClientId?: string;\n /** Generic Pod SecretCell credential vault factory, configured by Xpod operations. */\n secretCellCredentialVaultFactory?: () => CredentialVault;\n /** Explicit provider endpoint overrides for controlled deployments and local E2E fixtures. */\n aiGatewayProviderBaseUrls?: Partial<Record<'openai', string>>;\n\n /** 子域名功能配置 (cloud 模式) */\n subdomain?: {\n /** 节点域名根域名 (如 undefineds.site),有值即启用子域名功能 */\n baseStorageDomain?: string;\n cloudflareAccountId?: string;\n cloudflareApiToken?: string;\n tencentDnsSecretId?: string;\n tencentDnsSecretKey?: string;\n };\n\n /** Cloud API 端点 (local 托管式,调用 cloud 的子域名 API) */\n cloudApiEndpoint?: string;\n\n /** 节点 ID (local 托管式) */\n nodeId?: string;\n\n /** 节点 Token (local 托管式,调用 Cloud API 的认证) */\n nodeToken?: string;\n\n /** Local SP service token(Cloud 回调 Local、Local 服务级 API 的唯一服务凭据) */\n serviceToken?: string;\n\n /** 已签发的 provisionCode(Local 首次注册/刷新后持久化恢复) */\n provisionCode?: string;\n\n /** Local canonical public URL(通常来自 CSS_BASE_URL,也可从 setup 恢复) */\n publicUrl?: string;\n\n /** Cloud 分配或用户指定的 SP 域名 */\n spDomain?: string;\n\n /** Local setup/provision 状态文件路径 */\n localSetupPath?: string;\n\n /** Local setup/provision 状态文件中的 provider key */\n localSetupProviderId?: string;\n\n /** OIDC Issuer URL (local 托管式,使用 Cloud IdP) */\n oidcIssuer?: string;\n\n /** Active tunnel provider after resolving profile selection. */\n tunnelProvider?: ActiveTunnelProvider;\n\n /** Recorded tunnel profiles. Only tunnelActiveProfileId/activeTunnelProfile takes effect at runtime. */\n tunnelProfiles?: TunnelProfile[];\n\n /** Selected tunnel profile id. */\n tunnelActiveProfileId?: string;\n\n /** Selected tunnel profile. */\n activeTunnelProfile?: TunnelProfile;\n\n /** Cloudflare Tunnel Token (local 托管式/自管式,启动 cloudflared) */\n cloudflareTunnelToken?: string;\n\n /** SakuraFRP Tunnel Token (SAKURA_TUNNEL_TOKEN;local 托管式/自管式,启动 frpc) */\n sakuraTunnelToken?: string;\n\n /** ngrok authtoken (local only; not sent to Cloud). */\n ngrokAuthToken?: string;\n\n /** Fixed ngrok endpoint/custom domain, e.g. https://example.ngrok-free.dev. */\n ngrokUrl?: string;\n\n /** ngrok executable path. */\n ngrokPath?: string;\n\n /** 是否接受 Edge 节点注册 (cloud 模式) */\n edgeNodesEnabled?: boolean;\n}\n\nimport { EdgeNodeDnsCoordinator } from '../../edge/EdgeNodeDnsCoordinator';\nimport { EdgeNodeHealthProbeService } from '../../edge/EdgeNodeHealthProbeService';\nimport { EdgeNodeCapabilityDetector } from '../../edge/EdgeNodeCapabilityDetector';\nimport { LocalNetworkManager } from '../../edge/LocalNetworkManager';\nimport { DdnsManager } from '../../edge/DdnsManager';\n\n/**\n * 容器中注册的所有服务\n */\nexport interface ApiContainerCradle {\n // 配置\n config: ApiContainerConfig;\n\n // 核心服务\n db: IdentityDatabase;\n apiServer: ApiServer;\n authMiddleware: AuthMiddleware;\n authenticator: Authenticator;\n\n // 仓库\n nodeRepo: EdgeNodeRepository;\n serviceTokenRepo: ServiceTokenRepositoryPort;\n hostedPodDataAccess: HostedPodDataAccess;\n invocationTokenCodec: InvocationTokenCodec;\n aiConnectionInvocationKeyIssuer: AiConnectionInvocationKeyIssuer;\n aiClientConfigurationService?: AiClientConfigurationService;\n providerConnectService: ProviderConnectService;\n providerQuotaService?: ProviderQuotaService;\n gatewayProviderRegistry: GatewayProviderRegistry;\n gatewayCredentialStore: GatewayCredentialStore;\n gatewayRuntimeRegistry: ProviderRuntimeRegistry;\n gatewaySessionAffinityStore: SessionAffinityStore;\n aiGatewayService: AiGatewayService;\n\n // 业务服务\n chatService: VercelChatService;\n\n // ChatKit 服务 (OpenAI ChatKit 协议)\n chatKitStore: PodChatKitStore;\n chatKitAiProvider: AiProvider;\n inngestRuntimeConfig: EmbeddedInngestRuntimeConfig | undefined;\n runAuthContextRegistry: RunAuthContextRegistry;\n rdfEngine: RdfEngineLike | undefined;\n runContextRetriever: RunContextRetriever<StoreContext> | undefined;\n rdfSearchIndexingService: RdfSearchIndexingService | undefined;\n runExecutionBackend: InngestRunExecutionBackend;\n taskAuthBindingService: TaskAuthBindingService<StoreContext>;\n taskService: TaskService<StoreContext>;\n inngestTaskScheduler: InngestTaskScheduler<StoreContext>;\n chatKitService: ChatKitService<StoreContext>;\n matrixStore: PodMatrixStore;\n clientReconcilerCoordinator: ClientReconcilerCoordinator;\n serverGroupReconcilerService: ServerGroupReconcilerService;\n providerRegistry: ProviderRegistry;\n embeddingService: EmbeddingService;\n vectorService: VectorService;\n rdfStorageStatsService: RdfStorageStatsService;\n\n // Cloud 模式: 身份服务\n ddnsRepo?: DdnsRepository;\n podLookupRepo?: PodLookupRepository;\n accountRoleRepo?: AccountRoleRepository;\n\n // 子域名相关 (可选,按 edition 注册)\n // Cloud 模式 或 Local 自管模式\n dnsProvider?: DnsProvider;\n dnsCoordinator?: EdgeNodeDnsCoordinator;\n healthProbeService?: EdgeNodeHealthProbeService;\n capabilityDetector?: EdgeNodeCapabilityDetector;\n localNetworkManager?: LocalNetworkManager;\n\n tunnelProvider?: TunnelProvider;\n subdomainService?: SubdomainService;\n // Local 托管式\n subdomainClient?: SubdomainClient;\n // Local 托管式 DDNS 管理\n ddnsManager?: DdnsManager;\n // Local 托管式/自管式 (启动 cloudflared)\n localTunnelProvider?: TunnelProvider;\n\n // Optional runtime certificate managers. Routes only enable TLS status/renewal\n // when one of these services is explicitly registered by the active profile.\n edgeNodeCertificateCapabilityBridge?: EdgeNodeCertificateCapabilityBridge;\n certificateManager?: unknown;\n acmeCertificateManager?: AcmeCertificateManager;\n clusterCertificateManager?: ClusterCertificateManager;\n}\n"]}
@@ -49,7 +49,7 @@ function registerAiClientConfigurationRoutes(server, options) {
49
49
  await sendServiceResult(response, () => options.service.apply({
50
50
  client: requireClient(params.client),
51
51
  planId: requireString(body.planId, 'planId'),
52
- gatewayKey: requireString(body.gatewayKey, 'gatewayKey'),
52
+ apiKey: requireString(body.apiKey, 'apiKey'),
53
53
  confirmation: optionalConfirmation(body.confirmation),
54
54
  webId: request.auth?.type === 'solid' ? request.auth.webId : optionalString(body.webId),
55
55
  }));
@@ -111,13 +111,13 @@ function hasClientConfigScope(auth, scope) {
111
111
  if (auth.type === 'service') {
112
112
  return true;
113
113
  }
114
- return auth.type === 'solid' && auth.viaGatewayApiKey === true && auth.internalInvocation === true;
114
+ return auth.type === 'solid' && auth.internalInvocation === true;
115
115
  }
116
116
  function readScopes(auth) {
117
117
  if (auth.type === 'service') {
118
118
  return auth.scopes;
119
119
  }
120
- if (auth.type === 'solid' && auth.viaGatewayApiKey === true) {
120
+ if (auth.type === 'solid' && auth.internalInvocation === true) {
121
121
  return auth.scopes ?? [];
122
122
  }
123
123
  return [];
@@ -1 +1 @@
1
- {"version":3,"file":"AiClientConfigurationHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/AiClientConfigurationHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServerResponse } from 'node:http';\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport { readBoundedJsonBody } from '../http/readBoundedJsonBody';\nimport type { AuthContext } from '../auth/AuthContext';\nimport {\n AiClientConfigurationError,\n type AiClientConfigurationService,\n type AiClientId,\n redactSecretText,\n unavailableAiClientConfigurationCapability,\n} from '../service/AiClientConfigurationService';\n\nexport interface AiClientConfigurationHandlerOptions {\n service?: AiClientConfigurationService;\n jsonBodyLimitBytes?: number;\n}\n\nexport function registerAiClientConfigurationRoutes(\n server: ApiServer,\n options: AiClientConfigurationHandlerOptions,\n): void {\n const jsonBodyLimitBytes = options.jsonBodyLimitBytes ?? 16 * 1024;\n\n server.get('/api/ai/client-configuration/capability', async (request, response) => {\n if (!authorizeCapability(request, response)) {\n return;\n }\n sendJson(response, 200, options.service?.capability() ?? unavailableAiClientConfigurationCapability());\n });\n\n server.get('/api/ai/client-configuration/:client', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:read')) {\n return;\n }\n await sendServiceResult(response, () => options.service!.inspect(requireClient(params.client)));\n });\n\n server.post('/api/ai/client-configuration/:client/plan', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:write')) {\n return;\n }\n const body = await readJsonObject(request, response, jsonBodyLimitBytes);\n if (!body) {\n return;\n }\n await sendServiceResult(response, () => options.service!.plan({\n client: requireClient(params.client),\n endpoint: requireString(body.endpoint, 'endpoint'),\n model: optionalString(body.model),\n webId: request.auth?.type === 'solid' ? request.auth.webId : optionalString(body.webId),\n }));\n });\n\n server.post('/api/ai/client-configuration/:client/apply', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:write')) {\n return;\n }\n const body = await readJsonObject(request, response, jsonBodyLimitBytes);\n if (!body) {\n return;\n }\n await sendServiceResult(response, () => options.service!.apply({\n client: requireClient(params.client),\n planId: requireString(body.planId, 'planId'),\n gatewayKey: requireString(body.gatewayKey, 'gatewayKey'),\n confirmation: optionalConfirmation(body.confirmation),\n webId: request.auth?.type === 'solid' ? request.auth.webId : optionalString(body.webId),\n }));\n });\n\n server.post('/api/ai/client-configuration/:client/verify', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:read')) {\n return;\n }\n const body = await readJsonObject(request, response, jsonBodyLimitBytes);\n if (!body) {\n return;\n }\n await sendServiceResult(response, () => options.service!.verify({\n client: requireClient(params.client),\n planId: optionalString(body.planId),\n }));\n });\n\n server.post('/api/ai/client-configuration/:client/restore', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:write')) {\n return;\n }\n await sendServiceResult(response, () => options.service!.restore(\n requireClient(params.client),\n request.auth?.type === 'solid' ? request.auth.webId : undefined,\n ));\n });\n}\n\nfunction requireService(options: AiClientConfigurationHandlerOptions, response: ServerResponse): boolean {\n if (options.service) return true;\n sendJson(response, 503, safeErrorPayload(new AiClientConfigurationError(\n 'client_configuration_unavailable',\n 'Local AI client configuration is unavailable on this host.',\n 503,\n { aiClientConfiguration: unavailableAiClientConfigurationCapability() },\n )));\n return false;\n}\n\nfunction authorizeCapability(request: AuthenticatedRequest, response: ServerResponse): boolean {\n if (request.auth?.type === 'solid' || request.auth?.type === 'service') {\n return true;\n }\n sendJson(response, 401, safeErrorPayload(new AiClientConfigurationError(\n 'authentication_required',\n 'Authentication required.',\n 401,\n )));\n return false;\n}\n\nfunction authorizeClientConfig(\n request: AuthenticatedRequest,\n response: ServerResponse,\n scope: 'client-config:read' | 'client-config:write',\n): boolean {\n const auth = request.auth;\n if (!auth) {\n sendJson(response, 401, safeErrorPayload(new AiClientConfigurationError('authentication_required', 'Authentication required.', 401)));\n return false;\n }\n if (hasClientConfigScope(auth, scope)) {\n return true;\n }\n sendJson(response, 403, safeErrorPayload(new AiClientConfigurationError('insufficient_permissions', 'Insufficient permissions.', 403)));\n return false;\n}\n\nfunction hasClientConfigScope(auth: AuthContext, scope: 'client-config:read' | 'client-config:write'): boolean {\n const scopes = readScopes(auth);\n if (!scopes.includes(scope)) {\n return false;\n }\n if (auth.type === 'service') {\n return true;\n }\n return auth.type === 'solid' && auth.viaGatewayApiKey === true && auth.internalInvocation === true;\n}\n\nfunction readScopes(auth: AuthContext): string[] {\n if (auth.type === 'service') {\n return auth.scopes;\n }\n if (auth.type === 'solid' && auth.viaGatewayApiKey === true) {\n return auth.scopes ?? [];\n }\n return [];\n}\n\nasync function readJsonObject(\n request: AuthenticatedRequest,\n response: ServerResponse,\n limitBytes: number,\n): Promise<Record<string, unknown> | undefined> {\n const bodyResult = await readBoundedJsonBody(request, { limitBytes });\n if (!bodyResult.ok) {\n sendJson(response, bodyResult.status, { error: bodyResult.error });\n return undefined;\n }\n if (!bodyResult.value || typeof bodyResult.value !== 'object' || Array.isArray(bodyResult.value)) {\n sendJson(response, 400, { error: 'Request body must be a JSON object' });\n return undefined;\n }\n return bodyResult.value as Record<string, unknown>;\n}\n\nasync function sendServiceResult(response: ServerResponse, action: () => Promise<unknown>): Promise<void> {\n try {\n sendJson(response, 200, await action());\n } catch (error) {\n if (error instanceof AiClientConfigurationError) {\n sendJson(response, error.statusCode, safeErrorPayload(error));\n return;\n }\n sendJson(response, 500, safeErrorPayload(new AiClientConfigurationError(\n 'client_configuration_failed',\n redactSecretText(error instanceof Error ? error.message : 'Unknown error'),\n 500,\n )));\n }\n}\n\nfunction requireClient(value: string | undefined): AiClientId {\n if (value === 'codex' || value === 'claude-code' || value === 'pi' || value === 'codebuddy') {\n return value;\n }\n throw new AiClientConfigurationError('unsupported_client', 'Unsupported AI client.', 404);\n}\n\nfunction requireString(value: unknown, field: string): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new AiClientConfigurationError('invalid_request', `${field} must be a non-empty string.`, 400);\n }\n return value.trim();\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction optionalConfirmation(value: unknown): { token: string; targetHash: string } | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n const token = optionalString(record.token);\n const targetHash = optionalString(record.targetHash);\n return token && targetHash ? { token, targetHash } : undefined;\n}\n\nfunction safeErrorPayload(error: AiClientConfigurationError): { code: string; message: string; details?: unknown } {\n return {\n code: error.code,\n message: redactSecretText(error.message),\n ...(error.details ? { details: redactDetails(error.details) } : {}),\n };\n}\n\nfunction redactDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') {\n return typeof value === 'string' ? redactSecretText(value) : value;\n }\n if (Array.isArray(value)) {\n return value.map(redactDetails);\n }\n const output: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (/path|secret|token|key/iu.test(key)) {\n output[key] = '[redacted]';\n } else {\n output[key] = redactDetails(entry);\n }\n }\n return output;\n}\n\nfunction sendJson(response: ServerResponse, statusCode: number, payload: unknown): void {\n response.statusCode = statusCode;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(payload));\n}\n"]}
1
+ {"version":3,"file":"AiClientConfigurationHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/AiClientConfigurationHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServerResponse } from 'node:http';\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport { readBoundedJsonBody } from '../http/readBoundedJsonBody';\nimport type { AuthContext } from '../auth/AuthContext';\nimport {\n AiClientConfigurationError,\n type AiClientConfigurationService,\n type AiClientId,\n redactSecretText,\n unavailableAiClientConfigurationCapability,\n} from '../service/AiClientConfigurationService';\n\nexport interface AiClientConfigurationHandlerOptions {\n service?: AiClientConfigurationService;\n jsonBodyLimitBytes?: number;\n}\n\nexport function registerAiClientConfigurationRoutes(\n server: ApiServer,\n options: AiClientConfigurationHandlerOptions,\n): void {\n const jsonBodyLimitBytes = options.jsonBodyLimitBytes ?? 16 * 1024;\n\n server.get('/api/ai/client-configuration/capability', async (request, response) => {\n if (!authorizeCapability(request, response)) {\n return;\n }\n sendJson(response, 200, options.service?.capability() ?? unavailableAiClientConfigurationCapability());\n });\n\n server.get('/api/ai/client-configuration/:client', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:read')) {\n return;\n }\n await sendServiceResult(response, () => options.service!.inspect(requireClient(params.client)));\n });\n\n server.post('/api/ai/client-configuration/:client/plan', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:write')) {\n return;\n }\n const body = await readJsonObject(request, response, jsonBodyLimitBytes);\n if (!body) {\n return;\n }\n await sendServiceResult(response, () => options.service!.plan({\n client: requireClient(params.client),\n endpoint: requireString(body.endpoint, 'endpoint'),\n model: optionalString(body.model),\n webId: request.auth?.type === 'solid' ? request.auth.webId : optionalString(body.webId),\n }));\n });\n\n server.post('/api/ai/client-configuration/:client/apply', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:write')) {\n return;\n }\n const body = await readJsonObject(request, response, jsonBodyLimitBytes);\n if (!body) {\n return;\n }\n await sendServiceResult(response, () => options.service!.apply({\n client: requireClient(params.client),\n planId: requireString(body.planId, 'planId'),\n apiKey: requireString(body.apiKey, 'apiKey'),\n confirmation: optionalConfirmation(body.confirmation),\n webId: request.auth?.type === 'solid' ? request.auth.webId : optionalString(body.webId),\n }));\n });\n\n server.post('/api/ai/client-configuration/:client/verify', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:read')) {\n return;\n }\n const body = await readJsonObject(request, response, jsonBodyLimitBytes);\n if (!body) {\n return;\n }\n await sendServiceResult(response, () => options.service!.verify({\n client: requireClient(params.client),\n planId: optionalString(body.planId),\n }));\n });\n\n server.post('/api/ai/client-configuration/:client/restore', async (request, response, params) => {\n if (!requireService(options, response)) return;\n if (!authorizeClientConfig(request, response, 'client-config:write')) {\n return;\n }\n await sendServiceResult(response, () => options.service!.restore(\n requireClient(params.client),\n request.auth?.type === 'solid' ? request.auth.webId : undefined,\n ));\n });\n}\n\nfunction requireService(options: AiClientConfigurationHandlerOptions, response: ServerResponse): boolean {\n if (options.service) return true;\n sendJson(response, 503, safeErrorPayload(new AiClientConfigurationError(\n 'client_configuration_unavailable',\n 'Local AI client configuration is unavailable on this host.',\n 503,\n { aiClientConfiguration: unavailableAiClientConfigurationCapability() },\n )));\n return false;\n}\n\nfunction authorizeCapability(request: AuthenticatedRequest, response: ServerResponse): boolean {\n if (request.auth?.type === 'solid' || request.auth?.type === 'service') {\n return true;\n }\n sendJson(response, 401, safeErrorPayload(new AiClientConfigurationError(\n 'authentication_required',\n 'Authentication required.',\n 401,\n )));\n return false;\n}\n\nfunction authorizeClientConfig(\n request: AuthenticatedRequest,\n response: ServerResponse,\n scope: 'client-config:read' | 'client-config:write',\n): boolean {\n const auth = request.auth;\n if (!auth) {\n sendJson(response, 401, safeErrorPayload(new AiClientConfigurationError('authentication_required', 'Authentication required.', 401)));\n return false;\n }\n if (hasClientConfigScope(auth, scope)) {\n return true;\n }\n sendJson(response, 403, safeErrorPayload(new AiClientConfigurationError('insufficient_permissions', 'Insufficient permissions.', 403)));\n return false;\n}\n\nfunction hasClientConfigScope(auth: AuthContext, scope: 'client-config:read' | 'client-config:write'): boolean {\n const scopes = readScopes(auth);\n if (!scopes.includes(scope)) {\n return false;\n }\n if (auth.type === 'service') {\n return true;\n }\n return auth.type === 'solid' && auth.internalInvocation === true;\n}\n\nfunction readScopes(auth: AuthContext): string[] {\n if (auth.type === 'service') {\n return auth.scopes;\n }\n if (auth.type === 'solid' && auth.internalInvocation === true) {\n return auth.scopes ?? [];\n }\n return [];\n}\n\nasync function readJsonObject(\n request: AuthenticatedRequest,\n response: ServerResponse,\n limitBytes: number,\n): Promise<Record<string, unknown> | undefined> {\n const bodyResult = await readBoundedJsonBody(request, { limitBytes });\n if (!bodyResult.ok) {\n sendJson(response, bodyResult.status, { error: bodyResult.error });\n return undefined;\n }\n if (!bodyResult.value || typeof bodyResult.value !== 'object' || Array.isArray(bodyResult.value)) {\n sendJson(response, 400, { error: 'Request body must be a JSON object' });\n return undefined;\n }\n return bodyResult.value as Record<string, unknown>;\n}\n\nasync function sendServiceResult(response: ServerResponse, action: () => Promise<unknown>): Promise<void> {\n try {\n sendJson(response, 200, await action());\n } catch (error) {\n if (error instanceof AiClientConfigurationError) {\n sendJson(response, error.statusCode, safeErrorPayload(error));\n return;\n }\n sendJson(response, 500, safeErrorPayload(new AiClientConfigurationError(\n 'client_configuration_failed',\n redactSecretText(error instanceof Error ? error.message : 'Unknown error'),\n 500,\n )));\n }\n}\n\nfunction requireClient(value: string | undefined): AiClientId {\n if (value === 'codex' || value === 'claude-code' || value === 'pi' || value === 'codebuddy') {\n return value;\n }\n throw new AiClientConfigurationError('unsupported_client', 'Unsupported AI client.', 404);\n}\n\nfunction requireString(value: unknown, field: string): string {\n if (typeof value !== 'string' || !value.trim()) {\n throw new AiClientConfigurationError('invalid_request', `${field} must be a non-empty string.`, 400);\n }\n return value.trim();\n}\n\nfunction optionalString(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction optionalConfirmation(value: unknown): { token: string; targetHash: string } | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return undefined;\n const record = value as Record<string, unknown>;\n const token = optionalString(record.token);\n const targetHash = optionalString(record.targetHash);\n return token && targetHash ? { token, targetHash } : undefined;\n}\n\nfunction safeErrorPayload(error: AiClientConfigurationError): { code: string; message: string; details?: unknown } {\n return {\n code: error.code,\n message: redactSecretText(error.message),\n ...(error.details ? { details: redactDetails(error.details) } : {}),\n };\n}\n\nfunction redactDetails(value: unknown): unknown {\n if (!value || typeof value !== 'object') {\n return typeof value === 'string' ? redactSecretText(value) : value;\n }\n if (Array.isArray(value)) {\n return value.map(redactDetails);\n }\n const output: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n if (/path|secret|token|key/iu.test(key)) {\n output[key] = '[redacted]';\n } else {\n output[key] = redactDetails(entry);\n }\n }\n return output;\n}\n\nfunction sendJson(response: ServerResponse, statusCode: number, payload: unknown): void {\n response.statusCode = statusCode;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(payload));\n}\n"]}
@@ -82,8 +82,8 @@ class AiGatewayHandler {
82
82
  }
83
83
  async handleAcceptanceProvenance(request, response) {
84
84
  try {
85
- if (request.auth?.type !== 'solid' || request.auth.viaGatewayApiKey !== true) {
86
- throw new errors_1.GatewayProtocolError('Acceptance provenance requires a Gateway API key principal', {
85
+ if (request.auth?.type !== 'solid') {
86
+ throw new errors_1.GatewayProtocolError('Acceptance provenance requires a Solid user principal', {
87
87
  code: 'invalid_request',
88
88
  status: 403,
89
89
  });
@@ -1 +1 @@
1
- {"version":3,"file":"AiGatewayHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/AiGatewayHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServerResponse } from 'node:http';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport { readBoundedJsonBody } from '../http/readBoundedJsonBody';\nimport { GatewayProtocolError, normalizeGatewayError } from '../ai-gateway/errors';\nimport type { AiGatewayService } from '../ai-gateway/AiGatewayService';\nimport type { GatewayEvent, GatewayProtocol, GatewayProtocolFrontend } from '../ai-gateway/types';\n\nexport interface AiGatewayHandlerOptions {\n service: AiGatewayService;\n jsonBodyLimitBytes?: number;\n acceptanceEndpointsEnabled?: boolean;\n}\n\nconst DEFAULT_JSON_BODY_LIMIT_BYTES = 2 * 1024 * 1024;\n\nexport function registerAiGatewayRoutes(\n server: ApiServer,\n options: AiGatewayHandlerOptions,\n): void {\n const handler = new AiGatewayHandler(options);\n server.post('/v1/responses', (request, response) => handler.handleInference(request, response, 'responses'));\n server.post('/v1/messages', (request, response) => handler.handleInference(request, response, 'anthropic'));\n server.post('/v1/chat/completions', (request, response) => handler.handleInference(request, response, 'chatCompletions'));\n server.get('/v1/models', (request, response) => handler.handleModels(request, response));\n if (options.acceptanceEndpointsEnabled === true) {\n server.get('/v1/xpod/acceptance/provenance', (request, response) => handler.handleAcceptanceProvenance(request, response));\n }\n}\n\nexport class AiGatewayHandler {\n private readonly logger = getLoggerFor(this);\n private readonly service: AiGatewayService;\n private readonly jsonBodyLimitBytes: number;\n\n public constructor(options: AiGatewayHandlerOptions) {\n this.service = options.service;\n this.jsonBodyLimitBytes = options.jsonBodyLimitBytes ?? DEFAULT_JSON_BODY_LIMIT_BYTES;\n }\n\n public async handleInference(\n request: AuthenticatedRequest,\n response: ServerResponse,\n protocol: GatewayProtocol,\n ): Promise<void> {\n const bodyResult = await readBoundedJsonBody(request, { limitBytes: this.jsonBodyLimitBytes });\n if (!bodyResult.ok) {\n this.sendGatewayError(response, new GatewayProtocolError(bodyResult.error, {\n code: 'invalid_request',\n status: bodyResult.status,\n }));\n return;\n }\n\n const controller = new AbortController();\n const abort = (): void => controller.abort();\n response.once('close', abort);\n\n try {\n const stream = isStreamRequest(bodyResult.value);\n if (!stream) {\n const result = await this.service.complete({\n auth: request.auth!,\n protocol,\n body: bodyResult.value,\n signal: controller.signal,\n });\n sendJson(response, 200, result);\n return;\n }\n\n const execution = await this.service.execute({\n auth: request.auth!,\n protocol,\n body: bodyResult.value,\n signal: controller.signal,\n });\n await this.sendEventStream(response, execution.frontend, execution.events);\n } catch (error) {\n if (controller.signal.aborted || response.destroyed) {\n return;\n }\n if (response.headersSent) {\n await this.writeTerminalStreamError(response, error);\n return;\n }\n this.sendGatewayError(response, error);\n } finally {\n response.off('close', abort);\n }\n }\n\n public async handleModels(\n request: AuthenticatedRequest,\n response: ServerResponse,\n ): Promise<void> {\n try {\n const models = await this.service.listModels(request.auth!);\n sendJson(response, 200, {\n object: 'list',\n data: models,\n });\n } catch (error) {\n this.sendGatewayError(response, error);\n }\n }\n\n public async handleAcceptanceProvenance(\n request: AuthenticatedRequest,\n response: ServerResponse,\n ): Promise<void> {\n try {\n if (request.auth?.type !== 'solid' || request.auth.viaGatewayApiKey !== true) {\n throw new GatewayProtocolError('Acceptance provenance requires a Gateway API key principal', {\n code: 'invalid_request',\n status: 403,\n });\n }\n const url = new URL(request.url ?? '/', `http://${request.headers.host ?? 'localhost'}`);\n const model = url.searchParams.get('model')?.trim();\n if (!model) {\n throw new GatewayProtocolError('model is required', {\n code: 'invalid_request',\n status: 400,\n });\n }\n sendJson(response, 200, await this.service.acceptanceProvenance({\n auth: request.auth,\n model,\n xpodBaseUrl: `${headerString(request.headers['x-forwarded-proto']) || url.protocol.replace(':', '')}://${url.host}`,\n }));\n } catch (error) {\n this.sendGatewayError(response, error);\n }\n }\n\n private async sendEventStream(\n response: ServerResponse,\n frontend: GatewayProtocolFrontend,\n events: AsyncIterable<GatewayEvent>,\n ): Promise<void> {\n const iterator = events[Symbol.asyncIterator]();\n let disconnected = false;\n let iteratorReturned = false;\n const returnIterator = async(): Promise<void> => {\n if (!iteratorReturned) {\n iteratorReturned = true;\n await iterator.return?.();\n }\n };\n const onClose = (): void => {\n disconnected = true;\n void returnIterator();\n };\n response.once('close', onClose);\n let first: IteratorResult<GatewayEvent>;\n try {\n first = await iterator.next();\n } catch (error) {\n await returnIterator();\n response.off('close', onClose);\n throw error;\n }\n if (first.done) {\n await returnIterator();\n response.off('close', onClose);\n throw new GatewayProtocolError('Provider stream ended before emitting any gateway event', {\n code: 'provider_error',\n status: 502,\n });\n }\n\n response.statusCode = 200;\n response.setHeader('Content-Type', 'text/event-stream; charset=utf-8');\n response.setHeader('Cache-Control', 'no-cache, no-transform');\n response.setHeader('Connection', 'keep-alive');\n const serializer = frontend.createEventSerializer();\n try {\n await writeSerializedEvents(response, serializer.serializeEvent(first.value));\n for (;;) {\n const next = await iterator.next();\n if (next.done) {\n break;\n }\n await writeSerializedEvents(response, serializer.serializeEvent(next.value));\n }\n await writeWithBackpressure(response, 'data: [DONE]\\n\\n');\n } catch (error) {\n await returnIterator();\n if (!disconnected) {\n await this.writeTerminalStreamError(response, error);\n }\n } finally {\n response.off('close', onClose);\n if (!disconnected && !response.writableEnded) {\n response.end();\n }\n }\n }\n\n private async writeTerminalStreamError(response: ServerResponse, error: unknown): Promise<void> {\n const payload = normalizeGatewayError(error);\n await writeWithBackpressure(response, `data: ${JSON.stringify({ error: payload.error })}\\n\\n`);\n await writeWithBackpressure(response, 'data: [DONE]\\n\\n');\n if (!response.writableEnded) {\n response.end();\n }\n }\n\n private sendGatewayError(response: ServerResponse, error: unknown): void {\n const payload = normalizeGatewayError(error);\n this.logger.warn(`AI Gateway request failed: ${payload.error.code}`);\n sendJson(response, payload.error.status, {\n error: {\n code: payload.error.code,\n message: payload.error.message,\n ...(payload.error.details ? { details: payload.error.details } : {}),\n },\n });\n }\n}\n\nasync function writeSerializedEvents(\n response: ServerResponse,\n serialized: Record<string, unknown> | Record<string, unknown>[],\n): Promise<void> {\n for (const event of Array.isArray(serialized) ? serialized : [serialized]) {\n await writeWithBackpressure(response, `data: ${JSON.stringify(event)}\\n\\n`);\n }\n}\n\nasync function writeWithBackpressure(response: ServerResponse, chunk: string): Promise<void> {\n if (response.destroyed || response.writableEnded) {\n throw new Error('Response stream closed');\n }\n if (response.write(chunk)) {\n return;\n }\n await new Promise<void>((resolve, reject) => {\n const onDrain = (): void => {\n cleanup();\n resolve();\n };\n const onClose = (): void => {\n cleanup();\n reject(new Error('Response stream closed'));\n };\n const cleanup = (): void => {\n response.off('drain', onDrain);\n response.off('close', onClose);\n };\n response.once('drain', onDrain);\n response.once('close', onClose);\n });\n}\n\nfunction isStreamRequest(body: unknown): boolean {\n return Boolean(body && typeof body === 'object' && !Array.isArray(body) && (body as { stream?: unknown }).stream === true);\n}\n\nfunction headerString(value: string | string[] | undefined): string {\n return Array.isArray(value) ? value[0] ?? '' : value ?? '';\n}\n\nfunction sendJson(response: ServerResponse, status: number, data: unknown): void {\n response.statusCode = status;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(data));\n}\n"]}
1
+ {"version":3,"file":"AiGatewayHandler.js","sourceRoot":"","sources":["../../../src/api/handlers/AiGatewayHandler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ServerResponse } from 'node:http';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { ApiServer } from '../ApiServer';\nimport type { AuthenticatedRequest } from '../middleware/AuthMiddleware';\nimport { readBoundedJsonBody } from '../http/readBoundedJsonBody';\nimport { GatewayProtocolError, normalizeGatewayError } from '../ai-gateway/errors';\nimport type { AiGatewayService } from '../ai-gateway/AiGatewayService';\nimport type { GatewayEvent, GatewayProtocol, GatewayProtocolFrontend } from '../ai-gateway/types';\n\nexport interface AiGatewayHandlerOptions {\n service: AiGatewayService;\n jsonBodyLimitBytes?: number;\n acceptanceEndpointsEnabled?: boolean;\n}\n\nconst DEFAULT_JSON_BODY_LIMIT_BYTES = 2 * 1024 * 1024;\n\nexport function registerAiGatewayRoutes(\n server: ApiServer,\n options: AiGatewayHandlerOptions,\n): void {\n const handler = new AiGatewayHandler(options);\n server.post('/v1/responses', (request, response) => handler.handleInference(request, response, 'responses'));\n server.post('/v1/messages', (request, response) => handler.handleInference(request, response, 'anthropic'));\n server.post('/v1/chat/completions', (request, response) => handler.handleInference(request, response, 'chatCompletions'));\n server.get('/v1/models', (request, response) => handler.handleModels(request, response));\n if (options.acceptanceEndpointsEnabled === true) {\n server.get('/v1/xpod/acceptance/provenance', (request, response) => handler.handleAcceptanceProvenance(request, response));\n }\n}\n\nexport class AiGatewayHandler {\n private readonly logger = getLoggerFor(this);\n private readonly service: AiGatewayService;\n private readonly jsonBodyLimitBytes: number;\n\n public constructor(options: AiGatewayHandlerOptions) {\n this.service = options.service;\n this.jsonBodyLimitBytes = options.jsonBodyLimitBytes ?? DEFAULT_JSON_BODY_LIMIT_BYTES;\n }\n\n public async handleInference(\n request: AuthenticatedRequest,\n response: ServerResponse,\n protocol: GatewayProtocol,\n ): Promise<void> {\n const bodyResult = await readBoundedJsonBody(request, { limitBytes: this.jsonBodyLimitBytes });\n if (!bodyResult.ok) {\n this.sendGatewayError(response, new GatewayProtocolError(bodyResult.error, {\n code: 'invalid_request',\n status: bodyResult.status,\n }));\n return;\n }\n\n const controller = new AbortController();\n const abort = (): void => controller.abort();\n response.once('close', abort);\n\n try {\n const stream = isStreamRequest(bodyResult.value);\n if (!stream) {\n const result = await this.service.complete({\n auth: request.auth!,\n protocol,\n body: bodyResult.value,\n signal: controller.signal,\n });\n sendJson(response, 200, result);\n return;\n }\n\n const execution = await this.service.execute({\n auth: request.auth!,\n protocol,\n body: bodyResult.value,\n signal: controller.signal,\n });\n await this.sendEventStream(response, execution.frontend, execution.events);\n } catch (error) {\n if (controller.signal.aborted || response.destroyed) {\n return;\n }\n if (response.headersSent) {\n await this.writeTerminalStreamError(response, error);\n return;\n }\n this.sendGatewayError(response, error);\n } finally {\n response.off('close', abort);\n }\n }\n\n public async handleModels(\n request: AuthenticatedRequest,\n response: ServerResponse,\n ): Promise<void> {\n try {\n const models = await this.service.listModels(request.auth!);\n sendJson(response, 200, {\n object: 'list',\n data: models,\n });\n } catch (error) {\n this.sendGatewayError(response, error);\n }\n }\n\n public async handleAcceptanceProvenance(\n request: AuthenticatedRequest,\n response: ServerResponse,\n ): Promise<void> {\n try {\n if (request.auth?.type !== 'solid') {\n throw new GatewayProtocolError('Acceptance provenance requires a Solid user principal', {\n code: 'invalid_request',\n status: 403,\n });\n }\n const url = new URL(request.url ?? '/', `http://${request.headers.host ?? 'localhost'}`);\n const model = url.searchParams.get('model')?.trim();\n if (!model) {\n throw new GatewayProtocolError('model is required', {\n code: 'invalid_request',\n status: 400,\n });\n }\n sendJson(response, 200, await this.service.acceptanceProvenance({\n auth: request.auth,\n model,\n xpodBaseUrl: `${headerString(request.headers['x-forwarded-proto']) || url.protocol.replace(':', '')}://${url.host}`,\n }));\n } catch (error) {\n this.sendGatewayError(response, error);\n }\n }\n\n private async sendEventStream(\n response: ServerResponse,\n frontend: GatewayProtocolFrontend,\n events: AsyncIterable<GatewayEvent>,\n ): Promise<void> {\n const iterator = events[Symbol.asyncIterator]();\n let disconnected = false;\n let iteratorReturned = false;\n const returnIterator = async(): Promise<void> => {\n if (!iteratorReturned) {\n iteratorReturned = true;\n await iterator.return?.();\n }\n };\n const onClose = (): void => {\n disconnected = true;\n void returnIterator();\n };\n response.once('close', onClose);\n let first: IteratorResult<GatewayEvent>;\n try {\n first = await iterator.next();\n } catch (error) {\n await returnIterator();\n response.off('close', onClose);\n throw error;\n }\n if (first.done) {\n await returnIterator();\n response.off('close', onClose);\n throw new GatewayProtocolError('Provider stream ended before emitting any gateway event', {\n code: 'provider_error',\n status: 502,\n });\n }\n\n response.statusCode = 200;\n response.setHeader('Content-Type', 'text/event-stream; charset=utf-8');\n response.setHeader('Cache-Control', 'no-cache, no-transform');\n response.setHeader('Connection', 'keep-alive');\n const serializer = frontend.createEventSerializer();\n try {\n await writeSerializedEvents(response, serializer.serializeEvent(first.value));\n for (;;) {\n const next = await iterator.next();\n if (next.done) {\n break;\n }\n await writeSerializedEvents(response, serializer.serializeEvent(next.value));\n }\n await writeWithBackpressure(response, 'data: [DONE]\\n\\n');\n } catch (error) {\n await returnIterator();\n if (!disconnected) {\n await this.writeTerminalStreamError(response, error);\n }\n } finally {\n response.off('close', onClose);\n if (!disconnected && !response.writableEnded) {\n response.end();\n }\n }\n }\n\n private async writeTerminalStreamError(response: ServerResponse, error: unknown): Promise<void> {\n const payload = normalizeGatewayError(error);\n await writeWithBackpressure(response, `data: ${JSON.stringify({ error: payload.error })}\\n\\n`);\n await writeWithBackpressure(response, 'data: [DONE]\\n\\n');\n if (!response.writableEnded) {\n response.end();\n }\n }\n\n private sendGatewayError(response: ServerResponse, error: unknown): void {\n const payload = normalizeGatewayError(error);\n this.logger.warn(`AI Gateway request failed: ${payload.error.code}`);\n sendJson(response, payload.error.status, {\n error: {\n code: payload.error.code,\n message: payload.error.message,\n ...(payload.error.details ? { details: payload.error.details } : {}),\n },\n });\n }\n}\n\nasync function writeSerializedEvents(\n response: ServerResponse,\n serialized: Record<string, unknown> | Record<string, unknown>[],\n): Promise<void> {\n for (const event of Array.isArray(serialized) ? serialized : [serialized]) {\n await writeWithBackpressure(response, `data: ${JSON.stringify(event)}\\n\\n`);\n }\n}\n\nasync function writeWithBackpressure(response: ServerResponse, chunk: string): Promise<void> {\n if (response.destroyed || response.writableEnded) {\n throw new Error('Response stream closed');\n }\n if (response.write(chunk)) {\n return;\n }\n await new Promise<void>((resolve, reject) => {\n const onDrain = (): void => {\n cleanup();\n resolve();\n };\n const onClose = (): void => {\n cleanup();\n reject(new Error('Response stream closed'));\n };\n const cleanup = (): void => {\n response.off('drain', onDrain);\n response.off('close', onClose);\n };\n response.once('drain', onDrain);\n response.once('close', onClose);\n });\n}\n\nfunction isStreamRequest(body: unknown): boolean {\n return Boolean(body && typeof body === 'object' && !Array.isArray(body) && (body as { stream?: unknown }).stream === true);\n}\n\nfunction headerString(value: string | string[] | undefined): string {\n return Array.isArray(value) ? value[0] ?? '' : value ?? '';\n}\n\nfunction sendJson(response: ServerResponse, status: number, data: unknown): void {\n response.statusCode = status;\n response.setHeader('Content-Type', 'application/json');\n response.end(JSON.stringify(data));\n}\n"]}
@@ -1,24 +1,16 @@
1
1
  import type { ApiServer } from '../ApiServer';
2
- import { type GatewayDeployment } from '../ai-gateway/auth/GatewayApiKey';
3
- import type { GatewayAccessKeyRepository } from '../ai-gateway/auth/GatewayApiKeyAuthenticator';
2
+ import type { GatewayDeployment } from '../ai-gateway/auth/InvocationTokenCodec';
4
3
  import type { ProviderConnectService } from '../ai-gateway/connect';
5
4
  import type { ProviderQuotaService } from '../ai-gateway/quota';
6
5
  import type { AiConnectionInvocationKeyIssuer } from '../ai-gateway/auth/AiConnectionInvocationKeyIssuer';
7
6
  import { type AiClientConfigurationCapabilityDescriptor } from '../service/AiClientConfigurationService';
8
7
  export interface AiGatewayManagementHandlerOptions {
9
- repository: GatewayAccessKeyRepository;
10
8
  deployment: GatewayDeployment;
11
9
  connectService?: ProviderConnectService;
12
10
  quotaService?: ProviderQuotaService;
13
- servicePrincipal?: {
14
- getServicePrincipal(): Promise<{
15
- webId: string;
16
- }>;
17
- };
18
11
  aiClientConfiguration?: AiClientConfigurationCapabilityDescriptor;
19
- aiConnectionInvocationKeyIssuer?: Pick<AiConnectionInvocationKeyIssuer, 'issue'>;
12
+ aiConnectionInvocationKeyIssuer?: Pick<AiConnectionInvocationKeyIssuer, 'issueClientConfiguration'>;
20
13
  now?: () => Date;
21
- keyId?: (owner: string) => string;
22
14
  jsonBodyLimitBytes?: number;
23
15
  }
24
16
  export declare function registerAiGatewayManagementRoutes(server: ApiServer, options: AiGatewayManagementHandlerOptions): void;