@undefineds.co/xpod 0.3.69 → 0.3.71-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/cloud.json +3 -28
- package/config/local.json +3 -0
- package/config/resolver.json +7 -0
- package/config/xpod.base.json +20 -0
- package/dist/agents/ClaudeExecutor.js +1 -1
- package/dist/agents/ClaudeExecutor.js.map +1 -1
- package/dist/agents/types.d.ts +5 -5
- package/dist/agents/types.js.map +1 -1
- package/dist/api/ai-gateway/AiGatewayService.d.ts +5 -16
- package/dist/api/ai-gateway/AiGatewayService.js +13 -35
- package/dist/api/ai-gateway/AiGatewayService.js.map +1 -1
- package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.d.ts +3 -2
- package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js +37 -12
- package/dist/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.js.map +1 -1
- package/dist/api/ai-gateway/auth/GatewayPrincipal.d.ts +2 -16
- package/dist/api/ai-gateway/auth/GatewayPrincipal.js +3 -33
- package/dist/api/ai-gateway/auth/GatewayPrincipal.js.map +1 -1
- package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.d.ts +23 -0
- package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.js +81 -0
- package/dist/api/ai-gateway/auth/InvocationTokenAuthenticator.js.map +1 -0
- package/dist/api/ai-gateway/auth/InvocationTokenCodec.d.ts +7 -4
- package/dist/api/ai-gateway/auth/InvocationTokenCodec.js.map +1 -1
- package/dist/api/ai-gateway/connect/index.d.ts +7 -26
- package/dist/api/ai-gateway/connect/index.js +40 -67
- package/dist/api/ai-gateway/connect/index.js.map +1 -1
- package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.d.ts +17 -0
- package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.js +65 -0
- package/dist/api/ai-gateway/credentials/PlaintextCredentialPayload.js.map +1 -0
- package/dist/api/ai-gateway/pod/HostedPodDataAccess.d.ts +24 -0
- package/dist/api/ai-gateway/pod/HostedPodDataAccess.js +149 -0
- package/dist/api/ai-gateway/pod/HostedPodDataAccess.js.map +1 -0
- package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.d.ts +13 -5
- package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js +16 -19
- package/dist/api/ai-gateway/quota/ProviderQuotaAdapter.js.map +1 -1
- package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.d.ts +1 -1
- package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js +0 -2
- package/dist/api/ai-gateway/service-access/AiConnectionServiceAccess.js.map +1 -1
- package/dist/api/auth/AuthContext.d.ts +1 -12
- package/dist/api/auth/AuthContext.js +0 -11
- package/dist/api/auth/AuthContext.js.map +1 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.js +4 -11
- package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
- package/dist/api/chatkit/default-agent.d.ts +2 -2
- package/dist/api/chatkit/default-agent.js +4 -4
- package/dist/api/chatkit/default-agent.js.map +1 -1
- package/dist/api/chatkit/runtime/AcpAgentRuntime.js +1 -1
- package/dist/api/chatkit/runtime/AcpAgentRuntime.js.map +1 -1
- package/dist/api/container/common.js +28 -69
- package/dist/api/container/common.js.map +1 -1
- package/dist/api/container/index.js +5 -6
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/routes.js +2 -5
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +8 -10
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/AiClientConfigurationHandler.js +3 -3
- package/dist/api/handlers/AiClientConfigurationHandler.js.map +1 -1
- package/dist/api/handlers/AiGatewayHandler.js +2 -2
- package/dist/api/handlers/AiGatewayHandler.js.map +1 -1
- package/dist/api/handlers/AiGatewayManagementHandler.d.ts +2 -10
- package/dist/api/handlers/AiGatewayManagementHandler.js +4 -154
- package/dist/api/handlers/AiGatewayManagementHandler.js.map +1 -1
- package/dist/api/handlers/NetworkSettingsHandler.js +0 -3
- package/dist/api/handlers/NetworkSettingsHandler.js.map +1 -1
- package/dist/api/handlers/PodSettingsHandler.d.ts +5 -2
- package/dist/api/handlers/PodSettingsHandler.js +3 -3
- package/dist/api/handlers/PodSettingsHandler.js.map +1 -1
- package/dist/api/runs/AgentRuntimeTypes.d.ts +3 -3
- package/dist/api/runs/AgentRuntimeTypes.js +10 -10
- package/dist/api/runs/AgentRuntimeTypes.js.map +1 -1
- package/dist/api/runs/InngestRunExecutionBackend.d.ts +15 -9
- package/dist/api/runs/InngestRunExecutionBackend.js +25 -10
- package/dist/api/runs/InngestRunExecutionBackend.js.map +1 -1
- package/dist/api/runs/PiAgentRuntimeDriver.js +2 -2
- package/dist/api/runs/PiAgentRuntimeDriver.js.map +1 -1
- package/dist/api/runs/RunStateCenter.js +1 -1
- package/dist/api/runs/RunStateCenter.js.map +1 -1
- package/dist/api/service/AiClientConfigurationService.d.ts +2 -2
- package/dist/api/service/AiClientConfigurationService.js +11 -11
- package/dist/api/service/AiClientConfigurationService.js.map +1 -1
- package/dist/api/tasks/InngestTaskScheduler.d.ts +16 -10
- package/dist/api/tasks/InngestTaskScheduler.js +24 -12
- package/dist/api/tasks/InngestTaskScheduler.js.map +1 -1
- package/dist/cli/commands/start.js +7 -7
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/components/components.jsonld +1 -0
- package/dist/components/context.jsonld +42 -0
- package/dist/http/InternalPodDataHttpHandler.d.ts +32 -0
- package/dist/http/InternalPodDataHttpHandler.js +258 -0
- package/dist/http/InternalPodDataHttpHandler.js.map +1 -0
- package/dist/http/InternalPodDataHttpHandler.jsonld +201 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/main.js +13 -13
- package/dist/main.js.map +1 -1
- package/dist/runtime/GatewayAdminProxyAuth.d.ts +15 -1
- package/dist/runtime/GatewayAdminProxyAuth.js +57 -2
- package/dist/runtime/GatewayAdminProxyAuth.js.map +1 -1
- package/dist/runtime/bootstrap.js +3 -0
- package/dist/runtime/bootstrap.js.map +1 -1
- package/dist/runtime/css-process.d.ts +1 -1
- package/dist/runtime/css-process.js +4 -1
- package/dist/runtime/css-process.js.map +1 -1
- package/dist/runtime/runner/node/CommunitySolidServerCssRunner.d.ts +2 -0
- package/dist/runtime/runner/node/CommunitySolidServerCssRunner.js +50 -0
- package/dist/runtime/runner/node/CommunitySolidServerCssRunner.js.map +1 -1
- package/dist/storage/rdf/PostgresRdfEngine.js +2 -0
- package/dist/storage/rdf/PostgresRdfEngine.js.map +1 -1
- package/dist/storage/rdf/PostgresRdfVectorIndex.d.ts +1 -0
- package/dist/storage/rdf/PostgresRdfVectorIndex.js +1 -1
- package/dist/storage/rdf/PostgresRdfVectorIndex.js.map +1 -1
- package/dist/storage/rdf/PostgresRdfVectorIndex.jsonld +29 -0
- package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.d.ts +5 -5
- package/node_modules/@undefineds.co/ai-connection/dist/AiClientConfigurationSection.js +7 -7
- package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionMain.js +1 -1
- package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.d.ts +3 -1
- package/node_modules/@undefineds.co/ai-connection/dist/AiConnectionPanel.js +74 -60
- package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.d.ts +0 -21
- package/node_modules/@undefineds.co/ai-connection/dist/ai-connection-client.js +0 -41
- package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.d.ts +1 -0
- package/node_modules/@undefineds.co/ai-connection/dist/client-config/base-adapter.js +7 -2
- package/node_modules/@undefineds.co/ai-connection/dist/client-config/codex.js +3 -3
- package/node_modules/@undefineds.co/ai-connection/dist/client-config/index.cjs +15 -9
- package/node_modules/@undefineds.co/ai-connection/dist/client-config/json-env-adapter.js +4 -4
- package/node_modules/@undefineds.co/ai-connection/dist/client-config/pi.js +3 -3
- package/node_modules/@undefineds.co/ai-connection/dist/client-config/types.d.ts +1 -1
- package/node_modules/@undefineds.co/ai-connection/dist/controller.d.ts +2 -1
- package/node_modules/@undefineds.co/ai-connection/dist/controller.js +1 -0
- package/node_modules/@undefineds.co/ai-connection/dist/service-access.js +0 -1
- package/node_modules/@undefineds.co/extension-sdk/dist/web.d.ts +22 -1
- package/package.json +3 -3
- package/static/app/assets/main.js +7 -7
- package/static/dashboard/assets/NetworkPage-CXjiUMR1.js +2 -0
- package/static/dashboard/assets/{PaneListHeader-57nvMwH6.js → PaneListHeader-BSipfl0W.js} +1 -1
- package/static/dashboard/assets/PodPage-Bd3Xhmp-.js +2 -0
- package/static/dashboard/assets/ServicesPage-CI3jWZGe.js +1 -0
- package/static/dashboard/assets/{card-B9Zjf_2p.js → card-z5BV5hTo.js} +1 -1
- package/static/dashboard/assets/{dashboard-8C6o666W.js → dashboard-CSrqAv2L.js} +2 -2
- package/static/dashboard/assets/{database-DPh9wDY9.js → database-Ct5ZPe6L.js} +1 -1
- package/static/dashboard/assets/{external-link-VbMQvVMz.js → external-link-B7wD1hkm.js} +1 -1
- package/static/dashboard/assets/index-tOBaUnM1.js +44 -0
- package/static/dashboard/assets/{refresh-cw-BxVxNxNr.js → refresh-cw-CFDZPaE8.js} +1 -1
- package/static/dashboard/assets/{services-status-context-DKmJ7ISr.js → services-status-context-DN1Icg4A.js} +1 -1
- package/static/dashboard/dashboard.html +1 -1
- package/static/settings/assets/ModelsPage-D87RrLB0.js +1 -0
- package/static/settings/assets/{PaneListHeader-Bgaze006.js → PaneListHeader-BtON8Z5Q.js} +1 -1
- package/static/settings/assets/PodPage-9LGuOloQ.js +2 -0
- package/static/settings/assets/ServicesPage-ZoT9-B_0.js +1 -0
- package/static/settings/assets/SettingsPage-Bj4lB3mq.js +41 -0
- package/static/settings/assets/{card-B_bXSIn-.js → card-CCGngjas.js} +1 -1
- package/static/settings/assets/{services-status-context-DiX-AbrP.js → services-status-context-CBfImxL_.js} +1 -1
- package/static/settings/assets/{settings-B30oMfZq.js → settings-yUyFIJxi.js} +2 -2
- package/static/settings/assets/{workspace-layout-Dv1Yn9Ci.js → workspace-layout-B0wJpPze.js} +1 -1
- package/static/settings/settings.html +1 -1
- package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.d.ts +0 -25
- package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js +0 -91
- package/dist/api/ai-gateway/auth/ClientCredentialsInternalPodAccessTokenProvider.js.map +0 -1
- package/dist/api/ai-gateway/auth/GatewayApiKey.d.ts +0 -28
- package/dist/api/ai-gateway/auth/GatewayApiKey.js +0 -162
- package/dist/api/ai-gateway/auth/GatewayApiKey.js.map +0 -1
- package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.d.ts +0 -56
- package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js +0 -143
- package/dist/api/ai-gateway/auth/GatewayApiKeyAuthenticator.js.map +0 -1
- package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.d.ts +0 -26
- package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js +0 -97
- package/dist/api/ai-gateway/auth/GatewayKeyLocatorCodec.js.map +0 -1
- package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.d.ts +0 -54
- package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js +0 -152
- package/dist/api/ai-gateway/auth/PodGatewayAccessKeyRepository.js.map +0 -1
- package/static/dashboard/assets/NetworkPage-Brt79fuQ.js +0 -2
- package/static/dashboard/assets/PodPage-CM6do1vB.js +0 -2
- package/static/dashboard/assets/ServicesPage-BUNxGJRz.js +0 -1
- package/static/dashboard/assets/index-RfiFckzb.js +0 -51
- package/static/settings/assets/ModelsPage-D_IH7AH3.js +0 -1
- package/static/settings/assets/PodPage-Cy1VNObw.js +0 -2
- package/static/settings/assets/ServicesPage-BsFaxVWC.js +0 -1
- package/static/settings/assets/SettingsPage-UafNWE_p.js +0 -48
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiGatewayService.js","sourceRoot":"","sources":["../../../src/api/ai-gateway/AiGatewayService.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport { GatewayProtocolError, normalizeGatewayError } from './errors';\nimport type { AuthContext } from '../auth/AuthContext';\nimport { getWebId, hasGatewayScope } from '../auth/AuthContext';\nimport type { CredentialVault } from './credentials/CredentialVault';\nimport type { EncryptedCredentialSecret } from './credentials/KeyWrapper';\nimport { ChatCompletionsFrontend, MessagesFrontend, ResponsesFrontend } from './protocol';\nimport type { ProviderRuntimeCredential } from './providers/ProviderRuntimeAdapter';\nimport type { ProviderCapabilities, ProviderRegistry } from './providers/ProviderRegistry';\nimport { normalizeProviderId } from './providers/ProviderRegistry';\nimport type { ProviderRuntimeRegistry } from './providers/ProviderRuntimeRegistry';\nimport type { GatewayCredentialCandidate, ModelRouter, ModelRouteResult } from './routing/ModelRouter';\nimport type {\n GatewayEvent,\n GatewayProtocol,\n GatewayProtocolFrontend,\n GatewayRequest,\n GatewayUsage,\n} from './types';\n\nexport interface StoredGatewayCredential extends GatewayCredentialCandidate {\n encryptedSecret: EncryptedCredentialSecret;\n version?: number;\n runtimeCredential?: ProviderRuntimeCredential;\n}\n\nexport interface GatewayCredentialStore {\n listCredentials(input: {\n webId: string;\n deployment: string;\n auth?: AuthContext;\n }): Promise<StoredGatewayCredential[]>;\n recordSuccess?(input: GatewayCredentialHealthRecord): Promise<void>;\n recordFailure?(input: GatewayCredentialHealthRecord): Promise<void>;\n rewrapCredential?(input: {\n webId: string;\n deployment: string;\n credentialId: string;\n expectedVersion?: number;\n encryptedSecret: EncryptedCredentialSecret;\n }): Promise<boolean>;\n}\n\nexport interface GatewayCredentialHealthRecord {\n webId: string;\n deployment: string;\n provider: string;\n credentialId: string;\n credentialIri: string;\n status?: number;\n errorCode?: string;\n}\n\nexport interface AiGatewayServiceOptions {\n deployment: string;\n registry: ProviderRegistry;\n router: ModelRouter;\n credentials: GatewayCredentialStore;\n vault: CredentialVault;\n runtimes: ProviderRuntimeRegistry;\n frontends?: GatewayProtocolFrontend[];\n now?: () => Date;\n}\n\nexport interface GatewayExecutionInput {\n auth: AuthContext;\n protocol: GatewayProtocol;\n body: unknown;\n signal?: AbortSignal;\n}\n\nexport interface GatewayExecution {\n protocol: GatewayProtocol;\n frontend: GatewayProtocolFrontend;\n request: GatewayRequest;\n route: ModelRouteResult;\n events: AsyncIterable<GatewayEvent>;\n}\n\nexport interface GatewayModelListItem {\n id: string;\n object: 'model';\n owned_by: string;\n context_window?: number;\n capabilities?: ProviderCapabilities;\n protocols?: GatewayProtocol[];\n}\n\nexport interface GatewayAcceptanceProvenance {\n webId: string;\n gatewayKeyId: string;\n gatewayKeyFingerprint: string;\n credentialIriHash: string;\n secretCellRefHash: string;\n providerId: string;\n providerRouteSource: 'pod-credential';\n xpodBaseUrl: string;\n generatedAt: string;\n}\n\nexport class AiGatewayService {\n private readonly deployment: string;\n private readonly registry: ProviderRegistry;\n private readonly router: ModelRouter;\n private readonly credentials: GatewayCredentialStore;\n private readonly vault: CredentialVault;\n private readonly runtimes: ProviderRuntimeRegistry;\n private readonly frontends = new Map<GatewayProtocol, GatewayProtocolFrontend>();\n private readonly now: () => Date;\n\n public constructor(options: AiGatewayServiceOptions) {\n this.deployment = options.deployment;\n this.registry = options.registry;\n this.router = options.router;\n this.credentials = options.credentials;\n this.vault = options.vault;\n this.runtimes = options.runtimes;\n this.now = options.now ?? (() => new Date());\n for (const frontend of options.frontends ?? [\n new ResponsesFrontend(),\n new MessagesFrontend(),\n new ChatCompletionsFrontend(),\n ]) {\n this.frontends.set(frontend.protocol, frontend);\n }\n }\n\n public frontend(protocol: GatewayProtocol): GatewayProtocolFrontend {\n const frontend = this.frontends.get(protocol);\n if (!frontend) {\n throw new GatewayProtocolError('Unsupported gateway protocol', {\n code: 'invalid_request',\n status: 400,\n details: { protocol },\n });\n }\n return frontend;\n }\n\n public async execute(input: GatewayExecutionInput): Promise<GatewayExecution> {\n this.requireScope(input.auth, 'inference:write');\n const principal = this.requirePrincipal(input.auth);\n const frontend = this.frontend(input.protocol);\n const request = frontend.parseRequest(input.body);\n validateGatewayRequest(request, input.protocol);\n const route = await this.router.route({\n webId: principal.webId,\n deployment: this.deployment,\n auth: input.auth,\n model: request.model,\n conversationId: conversationIdFor(request),\n explicitCredentialId: explicitCredentialIdFor(request),\n });\n request.model = route.model;\n const events = this.executeWithCredentialFailover({\n principal,\n request,\n route,\n signal: input.signal,\n });\n\n return {\n protocol: input.protocol,\n frontend,\n request,\n route,\n events,\n };\n }\n\n public async complete(input: GatewayExecutionInput): Promise<Record<string, unknown>> {\n const execution = await this.execute(input);\n const events: GatewayEvent[] = [];\n for await (const event of execution.events) {\n events.push(event);\n }\n return aggregateEvents(execution.protocol, execution.request.model, events, this.now());\n }\n\n public async listModels(auth: AuthContext): Promise<GatewayModelListItem[]> {\n this.requireScope(auth, 'models:read');\n const principal = this.requirePrincipal(auth);\n const credentials = await this.credentials.listCredentials({\n webId: principal.webId,\n deployment: this.deployment,\n auth,\n });\n const activeCredentialModels = new Map<string, Set<string> | undefined>();\n for (const credential of credentials) {\n if (!isCredentialModelVisible(credential, this.now())) {\n continue;\n }\n const providerId = normalizeProviderId(credential.provider);\n const allowedModels = credential.models ?? [];\n if (allowedModels.length === 0) {\n activeCredentialModels.set(providerId, undefined);\n continue;\n }\n const existing = activeCredentialModels.get(providerId);\n if (existing === undefined && activeCredentialModels.has(providerId)) {\n continue;\n }\n const models = existing ?? new Set<string>();\n for (const model of allowedModels) {\n models.add(model);\n }\n activeCredentialModels.set(providerId, models);\n }\n const seen = new Set<string>();\n const models: GatewayModelListItem[] = [];\n for (const provider of this.registry.listProviders()) {\n const providerId = normalizeProviderId(provider.id);\n if (!activeCredentialModels.has(providerId)) {\n continue;\n }\n const allowedModels = activeCredentialModels.get(providerId);\n const providerModelItems = provider.models\n .filter((model) => allowedModels === undefined || allowedModels.has(model.id))\n .map((model) => ({\n id: model.id,\n object: 'model' as const,\n owned_by: provider.id,\n ...(model.contextWindow !== undefined ? { context_window: model.contextWindow } : {}),\n ...(model.capabilities ? { capabilities: model.capabilities } : {}),\n ...(model.protocols ? { protocols: model.protocols } : {}),\n }));\n const registryModelIds = new Set(provider.models.map((model) => model.id));\n const credentialOnlyModelItems = allowedModels === undefined\n ? []\n : Array.from(allowedModels)\n .filter((model) => !registryModelIds.has(model))\n .map((model) => ({\n id: model,\n object: 'model' as const,\n owned_by: provider.id,\n }));\n for (const model of [ ...providerModelItems, ...credentialOnlyModelItems ]) {\n if (seen.has(model.id)) {\n continue;\n }\n seen.add(model.id);\n models.push(model);\n }\n }\n return models;\n }\n\n public async acceptanceProvenance(input: {\n auth: AuthContext;\n model: string;\n xpodBaseUrl: string;\n }): Promise<GatewayAcceptanceProvenance> {\n this.requireScope(input.auth, 'acceptance:read');\n const principal = this.requirePrincipal(input.auth);\n if (input.auth.type !== 'solid' || input.auth.viaGatewayApiKey !== true || !input.auth.gatewayKeyFingerprint) {\n throw new GatewayProtocolError('Acceptance provenance requires a Gateway API key principal', {\n code: 'invalid_request',\n status: 403,\n });\n }\n let route: ModelRouteResult;\n try {\n route = await this.router.route({\n webId: principal.webId,\n deployment: this.deployment,\n auth: input.auth,\n model: input.model,\n });\n } catch (error) {\n if (error instanceof GatewayProtocolError && error.code === 'credential_unavailable') {\n throw new GatewayProtocolError('Acceptance provenance credential route was not resolved', {\n code: 'credential_unavailable',\n status: 404,\n details: error.details,\n });\n }\n throw error;\n }\n if (route.model !== requestedRouteModel(input.model)) {\n throw new GatewayProtocolError('Acceptance provenance credential route was not resolved', {\n code: 'credential_unavailable',\n status: 404,\n details: { model: input.model },\n });\n }\n const credential = route.credential as StoredGatewayCredential;\n return {\n webId: principal.webId,\n gatewayKeyId: input.auth.type === 'solid' ? input.auth.gatewayKeyId ?? 'unknown' : 'unknown',\n gatewayKeyFingerprint: input.auth.gatewayKeyFingerprint,\n credentialIriHash: hashProvenanceValue(credential.credentialIri),\n secretCellRefHash: hashProvenanceValue(credential.encryptedSecret.credentialIri),\n providerId: route.provider.id,\n providerRouteSource: 'pod-credential',\n xpodBaseUrl: input.xpodBaseUrl,\n generatedAt: this.now().toISOString(),\n };\n }\n\n private async *executeWithCredentialFailover(input: {\n principal: { webId: string };\n request: GatewayRequest;\n route: ModelRouteResult;\n signal?: AbortSignal;\n }): AsyncIterable<GatewayEvent> {\n let route = input.route;\n let firstClientEventEmitted = false;\n const attempted = new Set<string>();\n\n for (;;) {\n attempted.add(route.credential.id);\n const credential = route.credential as StoredGatewayCredential;\n try {\n const apiKey = await this.openApiKey(input.principal, route, credential);\n const adapter = this.runtimes.get(route.provider.id);\n const upstream = adapter.execute({\n request: input.request,\n apiKey,\n credential: credential.runtimeCredential ?? runtimeCredentialFromMetadata(credential.metadata),\n signal: input.signal,\n });\n for await (const event of upstream) {\n if (!firstClientEventEmitted) {\n firstClientEventEmitted = true;\n this.router.markClientEventEmitted(route);\n }\n yield event;\n }\n await this.credentials.recordSuccess?.(healthRecord(input.principal.webId, this.deployment, route));\n return;\n } catch (error) {\n await this.recordRouteFailure(input.principal.webId, route, error);\n if (!firstClientEventEmitted && this.router.canFailOver(route)) {\n const nextRoute = await this.findFailoverRoute(input.principal.webId, input.request, route, attempted);\n if (nextRoute) {\n route = nextRoute;\n continue;\n }\n }\n throw error;\n }\n }\n }\n\n private async findFailoverRoute(\n webId: string,\n request: GatewayRequest,\n failedRoute: ModelRouteResult,\n attempted: Set<string>,\n ): Promise<ModelRouteResult | undefined> {\n try {\n return await this.router.route({\n webId,\n deployment: this.deployment,\n model: `${failedRoute.provider.id}/${failedRoute.model}`,\n conversationId: conversationIdFor(request),\n }, attempted);\n } catch (error) {\n if (error instanceof GatewayProtocolError && error.code === 'credential_unavailable') {\n return undefined;\n }\n throw error;\n }\n }\n\n private async openApiKey(\n principal: { webId: string },\n route: ModelRouteResult,\n credential: StoredGatewayCredential,\n ): Promise<string> {\n const secret = await this.vault.open(\n principal,\n credential.credentialIri,\n route.provider.id,\n credential.encryptedSecret,\n );\n if (this.vault.needsRewrap?.(credential.encryptedSecret) && this.credentials.rewrapCredential) {\n const rewrapped = await this.vault.rewrap(principal, credential.encryptedSecret);\n await this.credentials.rewrapCredential({\n webId: principal.webId,\n deployment: this.deployment,\n credentialId: credential.id,\n expectedVersion: credential.version,\n encryptedSecret: rewrapped,\n });\n }\n const apiKey = secret.apiKey ?? secret.accessToken ?? secret.token;\n if (typeof apiKey !== 'string' || !apiKey) {\n throw new GatewayProtocolError('Credential secret does not contain a usable provider token', {\n code: 'credential_unavailable',\n status: 403,\n details: { provider: route.provider.id, credentialId: credential.id },\n });\n }\n return apiKey;\n }\n\n private async recordRouteFailure(webId: string, route: ModelRouteResult, error: unknown): Promise<void> {\n const status = typeof (error as { status?: unknown })?.status === 'number'\n ? (error as { status: number }).status\n : error instanceof GatewayProtocolError\n ? error.status\n : undefined;\n if (status === 429) {\n await this.router.recordCooldown({\n webId,\n deployment: this.deployment,\n credentialId: route.credential.id,\n until: new Date(this.now().getTime() + 60_000),\n });\n }\n const normalized = normalizeGatewayError(error);\n await this.credentials.recordFailure?.({\n ...healthRecord(webId, this.deployment, route),\n status,\n errorCode: normalized.error.code,\n });\n }\n\n private requirePrincipal(auth: AuthContext): { webId: string } {\n const webId = getWebId(auth);\n if (!webId) {\n throw new GatewayProtocolError('Gateway requests require a Solid WebID principal', {\n code: 'invalid_request',\n status: 401,\n });\n }\n return { webId };\n }\n\n private requireScope(auth: AuthContext, scope: string): void {\n if (!hasGatewayScope(auth, scope)) {\n throw new GatewayProtocolError(`Missing required scope: ${scope}`, {\n code: 'invalid_request',\n status: 403,\n details: { scope },\n });\n }\n }\n}\n\nfunction hashProvenanceValue(value: string): string {\n return `sha256:${createHash('sha256').update(value).digest('hex')}`;\n}\n\nfunction requestedRouteModel(model: string): string {\n const slash = model.indexOf('/');\n return slash > 0 && slash < model.length - 1 ? model.slice(slash + 1) : model;\n}\n\nfunction isCredentialModelVisible(credential: StoredGatewayCredential, now: Date): boolean {\n return credential.enabled\n && (!credential.health || credential.health === 'healthy')\n && credential.quota?.status !== 'exhausted'\n && (!credential.cooldownUntil || credential.cooldownUntil.getTime() <= now.getTime());\n}\n\nfunction validateGatewayRequest(request: GatewayRequest, protocol: GatewayProtocol): void {\n if (!request.model) {\n throw new GatewayProtocolError('model is required', {\n code: 'invalid_request',\n status: 400,\n details: { protocol, field: 'model' },\n });\n }\n if (request.messages.length === 0) {\n throw new GatewayProtocolError('messages or input are required', {\n code: 'invalid_request',\n status: 400,\n details: { protocol, field: protocol === 'responses' ? 'input' : 'messages' },\n });\n }\n}\n\nfunction conversationIdFor(request: GatewayRequest): string | undefined {\n const extensions = request.protocolExtensions.responses ?? request.protocolExtensions.chatCompletions ?? request.protocolExtensions.anthropic;\n return request.previousResponseId\n ?? stringExtension(extensions, 'conversation')\n ?? stringExtension(extensions, 'conversation_id')\n ?? stringExtension(extensions, 'thread_id');\n}\n\nfunction explicitCredentialIdFor(request: GatewayRequest): string | undefined {\n const extensions = request.protocolExtensions.responses ?? request.protocolExtensions.chatCompletions ?? request.protocolExtensions.anthropic;\n return stringExtension(extensions, 'credential')\n ?? stringExtension(extensions, 'credential_id')\n ?? stringExtension(extensions, 'xpod_credential_id');\n}\n\nfunction stringExtension(extensions: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = extensions?.[key];\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction runtimeCredentialFromMetadata(metadata: Record<string, unknown> | undefined): ProviderRuntimeCredential | undefined {\n const runtime = metadata?.runtimeCredential;\n return runtime && typeof runtime === 'object' && !Array.isArray(runtime)\n ? runtime as ProviderRuntimeCredential\n : undefined;\n}\n\nfunction healthRecord(webId: string, deployment: string, route: ModelRouteResult): GatewayCredentialHealthRecord {\n return {\n webId,\n deployment,\n provider: route.provider.id,\n credentialId: route.credential.id,\n credentialIri: route.credential.credentialIri,\n };\n}\n\nfunction aggregateEvents(\n protocol: GatewayProtocol,\n model: string,\n events: GatewayEvent[],\n now: Date,\n): Record<string, unknown> {\n const state = collectEventState(events);\n if (protocol === 'responses') {\n return {\n id: state.id ?? `resp_${now.getTime()}`,\n object: 'response',\n created_at: Math.floor(now.getTime() / 1000),\n status: 'completed',\n model,\n output: [\n ...(state.reasoning ? [{\n type: 'reasoning',\n summary: [{ type: 'summary_text', text: state.reasoning }],\n ...(state.reasoningSignatures[0] ? { encrypted_content: state.reasoningSignatures[0].signature } : {}),\n }] : []),\n {\n type: 'message',\n role: 'assistant',\n content: state.text ? [{ type: 'output_text', text: state.text }] : [],\n },\n ...state.tools.map((tool) => ({\n type: 'function_call',\n call_id: tool.id,\n name: tool.name,\n arguments: tool.arguments,\n })),\n ],\n usage: openAiUsage(state.usage),\n };\n }\n if (protocol === 'anthropic') {\n return {\n id: state.id ?? `msg_${now.getTime()}`,\n type: 'message',\n role: 'assistant',\n model,\n content: [\n ...(state.reasoning ? [{\n type: 'thinking',\n thinking: state.reasoning,\n ...(state.reasoningSignatures[0] ? { signature: state.reasoningSignatures[0].signature } : {}),\n }] : []),\n ...(state.text ? [{ type: 'text', text: state.text }] : []),\n ...state.tools.map((tool) => ({\n type: 'tool_use',\n id: tool.id,\n name: tool.name,\n input: parseJsonOrString(tool.arguments),\n })),\n ],\n stop_reason: state.finishReason ?? 'end_turn',\n usage: anthropicUsage(state.usage),\n };\n }\n return {\n id: state.id ?? `chatcmpl_${now.getTime()}`,\n object: 'chat.completion',\n created: Math.floor(now.getTime() / 1000),\n model,\n choices: [{\n index: 0,\n message: {\n role: 'assistant',\n content: state.text || null,\n ...(state.reasoning ? { reasoning_content: state.reasoning } : {}),\n ...(state.reasoningSignatures[0] ? { reasoning_signature: state.reasoningSignatures[0].signature } : {}),\n ...(state.tools.length > 0 ? {\n tool_calls: state.tools.map((tool) => ({\n id: tool.id,\n type: 'function',\n function: {\n name: tool.name,\n arguments: tool.arguments,\n },\n })),\n } : {}),\n },\n finish_reason: state.finishReason ?? 'stop',\n }],\n usage: chatUsage(state.usage),\n };\n}\n\nfunction collectEventState(events: GatewayEvent[]): {\n id?: string;\n text: string;\n usage?: GatewayUsage;\n finishReason?: string;\n tools: Array<{ id: string; name: string; arguments: string }>;\n reasoning: string;\n reasoningSignatures: Array<{ provider: string; signature: string }>;\n} {\n const tools = new Map<string, { id: string; name: string; arguments: string }>();\n let id: string | undefined;\n let text = '';\n let reasoning = '';\n const reasoningSignatures: Array<{ provider: string; signature: string }> = [];\n let usage: GatewayUsage | undefined;\n let finishReason: string | undefined;\n for (const event of events) {\n if (event.type === 'response.started') {\n id = event.id;\n } else if (event.type === 'text.delta') {\n text += event.text;\n } else if (event.type === 'reasoning.delta') {\n reasoning += event.text;\n } else if (event.type === 'reasoning.signature') {\n reasoningSignatures.push({ provider: event.provider, signature: event.signature });\n } else if (event.type === 'tool.started') {\n tools.set(event.callId, { id: event.callId, name: event.name, arguments: '' });\n } else if (event.type === 'tool.arguments.delta') {\n const tool = tools.get(event.callId);\n if (tool) {\n tool.arguments += event.delta;\n }\n } else if (event.type === 'usage') {\n usage = event.usage;\n } else if (event.type === 'response.completed') {\n finishReason = event.finishReason;\n }\n }\n return {\n id,\n text,\n usage,\n finishReason,\n tools: Array.from(tools.values()),\n reasoning,\n reasoningSignatures,\n };\n}\n\nfunction chatUsage(usage: GatewayUsage | undefined): Record<string, number> {\n return {\n prompt_tokens: usage?.inputTokens ?? 0,\n completion_tokens: usage?.outputTokens ?? 0,\n total_tokens: usage?.totalTokens ?? ((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)),\n };\n}\n\nfunction openAiUsage(usage: GatewayUsage | undefined): Record<string, number> {\n return {\n input_tokens: usage?.inputTokens ?? 0,\n output_tokens: usage?.outputTokens ?? 0,\n total_tokens: usage?.totalTokens ?? ((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)),\n };\n}\n\nfunction anthropicUsage(usage: GatewayUsage | undefined): Record<string, number> {\n return {\n input_tokens: usage?.inputTokens ?? 0,\n output_tokens: usage?.outputTokens ?? 0,\n };\n}\n\nfunction parseJsonOrString(value: string): unknown {\n try {\n return JSON.parse(value || '{}');\n } catch {\n return value;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AiGatewayService.js","sourceRoot":"","sources":["../../../src/api/ai-gateway/AiGatewayService.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport { GatewayProtocolError, normalizeGatewayError } from './errors';\nimport type { AuthContext } from '../auth/AuthContext';\nimport { getWebId } from '../auth/AuthContext';\nimport { decodePlaintextCredential } from './credentials/PlaintextCredentialPayload';\nimport { ChatCompletionsFrontend, MessagesFrontend, ResponsesFrontend } from './protocol';\nimport type { ProviderRuntimeCredential } from './providers/ProviderRuntimeAdapter';\nimport type { ProviderCapabilities, ProviderRegistry } from './providers/ProviderRegistry';\nimport { normalizeProviderId } from './providers/ProviderRegistry';\nimport type { ProviderRuntimeRegistry } from './providers/ProviderRuntimeRegistry';\nimport type { GatewayCredentialCandidate, ModelRouter, ModelRouteResult } from './routing/ModelRouter';\nimport type {\n GatewayEvent,\n GatewayProtocol,\n GatewayProtocolFrontend,\n GatewayRequest,\n GatewayUsage,\n} from './types';\n\nexport interface StoredGatewayCredential extends GatewayCredentialCandidate {\n storageMode: 'plaintext-v1';\n secretPayload: string;\n version?: number;\n runtimeCredential?: ProviderRuntimeCredential;\n}\n\nexport interface GatewayCredentialStore {\n listCredentials(input: {\n webId: string;\n deployment: string;\n auth?: AuthContext;\n }): Promise<StoredGatewayCredential[]>;\n recordSuccess?(input: GatewayCredentialHealthRecord): Promise<void>;\n recordFailure?(input: GatewayCredentialHealthRecord): Promise<void>;\n}\n\nexport interface GatewayCredentialHealthRecord {\n webId: string;\n deployment: string;\n provider: string;\n credentialId: string;\n credentialIri: string;\n status?: number;\n errorCode?: string;\n}\n\nexport interface AiGatewayServiceOptions {\n deployment: string;\n registry: ProviderRegistry;\n router: ModelRouter;\n credentials: GatewayCredentialStore;\n runtimes: ProviderRuntimeRegistry;\n frontends?: GatewayProtocolFrontend[];\n now?: () => Date;\n}\n\nexport interface GatewayExecutionInput {\n auth: AuthContext;\n protocol: GatewayProtocol;\n body: unknown;\n signal?: AbortSignal;\n}\n\nexport interface GatewayExecution {\n protocol: GatewayProtocol;\n frontend: GatewayProtocolFrontend;\n request: GatewayRequest;\n route: ModelRouteResult;\n events: AsyncIterable<GatewayEvent>;\n}\n\nexport interface GatewayModelListItem {\n id: string;\n object: 'model';\n owned_by: string;\n context_window?: number;\n capabilities?: ProviderCapabilities;\n protocols?: GatewayProtocol[];\n}\n\nexport interface GatewayAcceptanceProvenance {\n webId: string;\n authType: 'solid-oidc' | 'client-credentials';\n clientIdHash?: string;\n credentialIriHash: string;\n credentialPayloadRefHash: string;\n providerId: string;\n providerRouteSource: 'pod-credential';\n xpodBaseUrl: string;\n generatedAt: string;\n}\n\nexport class AiGatewayService {\n private readonly deployment: string;\n private readonly registry: ProviderRegistry;\n private readonly router: ModelRouter;\n private readonly credentials: GatewayCredentialStore;\n private readonly runtimes: ProviderRuntimeRegistry;\n private readonly frontends = new Map<GatewayProtocol, GatewayProtocolFrontend>();\n private readonly now: () => Date;\n\n public constructor(options: AiGatewayServiceOptions) {\n this.deployment = options.deployment;\n this.registry = options.registry;\n this.router = options.router;\n this.credentials = options.credentials;\n this.runtimes = options.runtimes;\n this.now = options.now ?? (() => new Date());\n for (const frontend of options.frontends ?? [\n new ResponsesFrontend(),\n new MessagesFrontend(),\n new ChatCompletionsFrontend(),\n ]) {\n this.frontends.set(frontend.protocol, frontend);\n }\n }\n\n public frontend(protocol: GatewayProtocol): GatewayProtocolFrontend {\n const frontend = this.frontends.get(protocol);\n if (!frontend) {\n throw new GatewayProtocolError('Unsupported gateway protocol', {\n code: 'invalid_request',\n status: 400,\n details: { protocol },\n });\n }\n return frontend;\n }\n\n public async execute(input: GatewayExecutionInput): Promise<GatewayExecution> {\n const principal = this.requirePrincipal(input.auth);\n const frontend = this.frontend(input.protocol);\n const request = frontend.parseRequest(input.body);\n validateGatewayRequest(request, input.protocol);\n const route = await this.router.route({\n webId: principal.webId,\n deployment: this.deployment,\n auth: input.auth,\n model: request.model,\n conversationId: conversationIdFor(request),\n explicitCredentialId: explicitCredentialIdFor(request),\n });\n request.model = route.model;\n const events = this.executeWithCredentialFailover({\n auth: input.auth,\n principal,\n request,\n route,\n signal: input.signal,\n });\n\n return {\n protocol: input.protocol,\n frontend,\n request,\n route,\n events,\n };\n }\n\n public async complete(input: GatewayExecutionInput): Promise<Record<string, unknown>> {\n const execution = await this.execute(input);\n const events: GatewayEvent[] = [];\n for await (const event of execution.events) {\n events.push(event);\n }\n return aggregateEvents(execution.protocol, execution.request.model, events, this.now());\n }\n\n public async listModels(auth: AuthContext): Promise<GatewayModelListItem[]> {\n const principal = this.requirePrincipal(auth);\n const credentials = await this.credentials.listCredentials({\n webId: principal.webId,\n deployment: this.deployment,\n auth,\n });\n const activeCredentialModels = new Map<string, Set<string> | undefined>();\n for (const credential of credentials) {\n if (!isCredentialModelVisible(credential, this.now())) {\n continue;\n }\n const providerId = normalizeProviderId(credential.provider);\n const allowedModels = credential.models ?? [];\n if (allowedModels.length === 0) {\n activeCredentialModels.set(providerId, undefined);\n continue;\n }\n const existing = activeCredentialModels.get(providerId);\n if (existing === undefined && activeCredentialModels.has(providerId)) {\n continue;\n }\n const models = existing ?? new Set<string>();\n for (const model of allowedModels) {\n models.add(model);\n }\n activeCredentialModels.set(providerId, models);\n }\n const seen = new Set<string>();\n const models: GatewayModelListItem[] = [];\n for (const provider of this.registry.listProviders()) {\n const providerId = normalizeProviderId(provider.id);\n if (!activeCredentialModels.has(providerId)) {\n continue;\n }\n const allowedModels = activeCredentialModels.get(providerId);\n const providerModelItems = provider.models\n .filter((model) => allowedModels === undefined || allowedModels.has(model.id))\n .map((model) => ({\n id: model.id,\n object: 'model' as const,\n owned_by: provider.id,\n ...(model.contextWindow !== undefined ? { context_window: model.contextWindow } : {}),\n ...(model.capabilities ? { capabilities: model.capabilities } : {}),\n ...(model.protocols ? { protocols: model.protocols } : {}),\n }));\n const registryModelIds = new Set(provider.models.map((model) => model.id));\n const credentialOnlyModelItems = allowedModels === undefined\n ? []\n : Array.from(allowedModels)\n .filter((model) => !registryModelIds.has(model))\n .map((model) => ({\n id: model,\n object: 'model' as const,\n owned_by: provider.id,\n }));\n for (const model of [ ...providerModelItems, ...credentialOnlyModelItems ]) {\n if (seen.has(model.id)) {\n continue;\n }\n seen.add(model.id);\n models.push(model);\n }\n }\n return models;\n }\n\n public async acceptanceProvenance(input: {\n auth: AuthContext;\n model: string;\n xpodBaseUrl: string;\n }): Promise<GatewayAcceptanceProvenance> {\n const principal = this.requirePrincipal(input.auth);\n let route: ModelRouteResult;\n try {\n route = await this.router.route({\n webId: principal.webId,\n deployment: this.deployment,\n auth: input.auth,\n model: input.model,\n });\n } catch (error) {\n if (error instanceof GatewayProtocolError && error.code === 'credential_unavailable') {\n throw new GatewayProtocolError('Acceptance provenance credential route was not resolved', {\n code: 'credential_unavailable',\n status: 404,\n details: error.details,\n });\n }\n throw error;\n }\n if (route.model !== requestedRouteModel(input.model)) {\n throw new GatewayProtocolError('Acceptance provenance credential route was not resolved', {\n code: 'credential_unavailable',\n status: 404,\n details: { model: input.model },\n });\n }\n const credential = route.credential as StoredGatewayCredential;\n return {\n webId: principal.webId,\n authType: input.auth.type === 'solid' && input.auth.viaApiKey === true\n ? 'client-credentials'\n : 'solid-oidc',\n ...(input.auth.type === 'solid' && input.auth.clientId\n ? { clientIdHash: hashProvenanceValue(input.auth.clientId) }\n : {}),\n credentialIriHash: hashProvenanceValue(credential.credentialIri),\n credentialPayloadRefHash: hashProvenanceValue(credential.credentialIri),\n providerId: route.provider.id,\n providerRouteSource: 'pod-credential',\n xpodBaseUrl: input.xpodBaseUrl,\n generatedAt: this.now().toISOString(),\n };\n }\n\n private async *executeWithCredentialFailover(input: {\n auth: AuthContext;\n principal: { webId: string };\n request: GatewayRequest;\n route: ModelRouteResult;\n signal?: AbortSignal;\n }): AsyncIterable<GatewayEvent> {\n let route = input.route;\n let firstClientEventEmitted = false;\n const attempted = new Set<string>();\n\n for (;;) {\n attempted.add(route.credential.id);\n const credential = route.credential as StoredGatewayCredential;\n try {\n const apiKey = await this.openApiKey(input.principal, route, credential);\n const adapter = this.runtimes.get(route.provider.id);\n const upstream = adapter.execute({\n request: input.request,\n apiKey,\n credential: credential.runtimeCredential ?? runtimeCredentialFromMetadata(credential.metadata),\n signal: input.signal,\n });\n for await (const event of upstream) {\n if (!firstClientEventEmitted) {\n firstClientEventEmitted = true;\n this.router.markClientEventEmitted(route);\n }\n yield event;\n }\n await this.credentials.recordSuccess?.(healthRecord(input.principal.webId, this.deployment, route));\n return;\n } catch (error) {\n await this.recordRouteFailure(input.principal.webId, route, error);\n if (!firstClientEventEmitted && this.router.canFailOver(route)) {\n const nextRoute = await this.findFailoverRoute(input.auth, input.principal.webId, input.request, route, attempted);\n if (nextRoute) {\n route = nextRoute;\n continue;\n }\n }\n throw error;\n }\n }\n }\n\n private async findFailoverRoute(\n auth: AuthContext,\n webId: string,\n request: GatewayRequest,\n failedRoute: ModelRouteResult,\n attempted: Set<string>,\n ): Promise<ModelRouteResult | undefined> {\n try {\n return await this.router.route({\n webId,\n deployment: this.deployment,\n auth,\n model: `${failedRoute.provider.id}/${failedRoute.model}`,\n conversationId: conversationIdFor(request),\n }, attempted);\n } catch (error) {\n if (error instanceof GatewayProtocolError && error.code === 'credential_unavailable') {\n return undefined;\n }\n throw error;\n }\n }\n\n private async openApiKey(\n principal: { webId: string },\n route: ModelRouteResult,\n credential: StoredGatewayCredential,\n ): Promise<string> {\n const secret = decodePlaintextCredential(credential);\n const apiKey = secret.apiKey ?? secret.accessToken ?? secret.token;\n if (typeof apiKey !== 'string' || !apiKey) {\n throw new GatewayProtocolError('Credential secret does not contain a usable provider token', {\n code: 'credential_unavailable',\n status: 403,\n details: { provider: route.provider.id, credentialId: credential.id },\n });\n }\n return apiKey;\n }\n\n private async recordRouteFailure(webId: string, route: ModelRouteResult, error: unknown): Promise<void> {\n const status = typeof (error as { status?: unknown })?.status === 'number'\n ? (error as { status: number }).status\n : error instanceof GatewayProtocolError\n ? error.status\n : undefined;\n if (status === 429) {\n await this.router.recordCooldown({\n webId,\n deployment: this.deployment,\n credentialId: route.credential.id,\n until: new Date(this.now().getTime() + 60_000),\n });\n }\n const normalized = normalizeGatewayError(error);\n await this.credentials.recordFailure?.({\n ...healthRecord(webId, this.deployment, route),\n status,\n errorCode: normalized.error.code,\n });\n }\n\n private requirePrincipal(auth: AuthContext): { webId: string } {\n const webId = getWebId(auth);\n if (!webId) {\n throw new GatewayProtocolError('Gateway requests require a Solid WebID principal', {\n code: 'invalid_request',\n status: 401,\n });\n }\n return { webId };\n }\n\n}\n\nfunction hashProvenanceValue(value: string): string {\n return `sha256:${createHash('sha256').update(value).digest('hex')}`;\n}\n\nfunction requestedRouteModel(model: string): string {\n const slash = model.indexOf('/');\n return slash > 0 && slash < model.length - 1 ? model.slice(slash + 1) : model;\n}\n\nfunction isCredentialModelVisible(credential: StoredGatewayCredential, now: Date): boolean {\n return credential.enabled\n && (!credential.health || credential.health === 'healthy')\n && credential.quota?.status !== 'exhausted'\n && (!credential.cooldownUntil || credential.cooldownUntil.getTime() <= now.getTime());\n}\n\nfunction validateGatewayRequest(request: GatewayRequest, protocol: GatewayProtocol): void {\n if (!request.model) {\n throw new GatewayProtocolError('model is required', {\n code: 'invalid_request',\n status: 400,\n details: { protocol, field: 'model' },\n });\n }\n if (request.messages.length === 0) {\n throw new GatewayProtocolError('messages or input are required', {\n code: 'invalid_request',\n status: 400,\n details: { protocol, field: protocol === 'responses' ? 'input' : 'messages' },\n });\n }\n}\n\nfunction conversationIdFor(request: GatewayRequest): string | undefined {\n const extensions = request.protocolExtensions.responses ?? request.protocolExtensions.chatCompletions ?? request.protocolExtensions.anthropic;\n return request.previousResponseId\n ?? stringExtension(extensions, 'conversation')\n ?? stringExtension(extensions, 'conversation_id')\n ?? stringExtension(extensions, 'thread_id');\n}\n\nfunction explicitCredentialIdFor(request: GatewayRequest): string | undefined {\n const extensions = request.protocolExtensions.responses ?? request.protocolExtensions.chatCompletions ?? request.protocolExtensions.anthropic;\n return stringExtension(extensions, 'credential')\n ?? stringExtension(extensions, 'credential_id')\n ?? stringExtension(extensions, 'xpod_credential_id');\n}\n\nfunction stringExtension(extensions: Record<string, unknown> | undefined, key: string): string | undefined {\n const value = extensions?.[key];\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction runtimeCredentialFromMetadata(metadata: Record<string, unknown> | undefined): ProviderRuntimeCredential | undefined {\n const runtime = metadata?.runtimeCredential;\n return runtime && typeof runtime === 'object' && !Array.isArray(runtime)\n ? runtime as ProviderRuntimeCredential\n : undefined;\n}\n\nfunction healthRecord(webId: string, deployment: string, route: ModelRouteResult): GatewayCredentialHealthRecord {\n return {\n webId,\n deployment,\n provider: route.provider.id,\n credentialId: route.credential.id,\n credentialIri: route.credential.credentialIri,\n };\n}\n\nfunction aggregateEvents(\n protocol: GatewayProtocol,\n model: string,\n events: GatewayEvent[],\n now: Date,\n): Record<string, unknown> {\n const state = collectEventState(events);\n if (protocol === 'responses') {\n return {\n id: state.id ?? `resp_${now.getTime()}`,\n object: 'response',\n created_at: Math.floor(now.getTime() / 1000),\n status: 'completed',\n model,\n output: [\n ...(state.reasoning ? [{\n type: 'reasoning',\n summary: [{ type: 'summary_text', text: state.reasoning }],\n ...(state.reasoningSignatures[0] ? { encrypted_content: state.reasoningSignatures[0].signature } : {}),\n }] : []),\n {\n type: 'message',\n role: 'assistant',\n content: state.text ? [{ type: 'output_text', text: state.text }] : [],\n },\n ...state.tools.map((tool) => ({\n type: 'function_call',\n call_id: tool.id,\n name: tool.name,\n arguments: tool.arguments,\n })),\n ],\n usage: openAiUsage(state.usage),\n };\n }\n if (protocol === 'anthropic') {\n return {\n id: state.id ?? `msg_${now.getTime()}`,\n type: 'message',\n role: 'assistant',\n model,\n content: [\n ...(state.reasoning ? [{\n type: 'thinking',\n thinking: state.reasoning,\n ...(state.reasoningSignatures[0] ? { signature: state.reasoningSignatures[0].signature } : {}),\n }] : []),\n ...(state.text ? [{ type: 'text', text: state.text }] : []),\n ...state.tools.map((tool) => ({\n type: 'tool_use',\n id: tool.id,\n name: tool.name,\n input: parseJsonOrString(tool.arguments),\n })),\n ],\n stop_reason: state.finishReason ?? 'end_turn',\n usage: anthropicUsage(state.usage),\n };\n }\n return {\n id: state.id ?? `chatcmpl_${now.getTime()}`,\n object: 'chat.completion',\n created: Math.floor(now.getTime() / 1000),\n model,\n choices: [{\n index: 0,\n message: {\n role: 'assistant',\n content: state.text || null,\n ...(state.reasoning ? { reasoning_content: state.reasoning } : {}),\n ...(state.reasoningSignatures[0] ? { reasoning_signature: state.reasoningSignatures[0].signature } : {}),\n ...(state.tools.length > 0 ? {\n tool_calls: state.tools.map((tool) => ({\n id: tool.id,\n type: 'function',\n function: {\n name: tool.name,\n arguments: tool.arguments,\n },\n })),\n } : {}),\n },\n finish_reason: state.finishReason ?? 'stop',\n }],\n usage: chatUsage(state.usage),\n };\n}\n\nfunction collectEventState(events: GatewayEvent[]): {\n id?: string;\n text: string;\n usage?: GatewayUsage;\n finishReason?: string;\n tools: Array<{ id: string; name: string; arguments: string }>;\n reasoning: string;\n reasoningSignatures: Array<{ provider: string; signature: string }>;\n} {\n const tools = new Map<string, { id: string; name: string; arguments: string }>();\n let id: string | undefined;\n let text = '';\n let reasoning = '';\n const reasoningSignatures: Array<{ provider: string; signature: string }> = [];\n let usage: GatewayUsage | undefined;\n let finishReason: string | undefined;\n for (const event of events) {\n if (event.type === 'response.started') {\n id = event.id;\n } else if (event.type === 'text.delta') {\n text += event.text;\n } else if (event.type === 'reasoning.delta') {\n reasoning += event.text;\n } else if (event.type === 'reasoning.signature') {\n reasoningSignatures.push({ provider: event.provider, signature: event.signature });\n } else if (event.type === 'tool.started') {\n tools.set(event.callId, { id: event.callId, name: event.name, arguments: '' });\n } else if (event.type === 'tool.arguments.delta') {\n const tool = tools.get(event.callId);\n if (tool) {\n tool.arguments += event.delta;\n }\n } else if (event.type === 'usage') {\n usage = event.usage;\n } else if (event.type === 'response.completed') {\n finishReason = event.finishReason;\n }\n }\n return {\n id,\n text,\n usage,\n finishReason,\n tools: Array.from(tools.values()),\n reasoning,\n reasoningSignatures,\n };\n}\n\nfunction chatUsage(usage: GatewayUsage | undefined): Record<string, number> {\n return {\n prompt_tokens: usage?.inputTokens ?? 0,\n completion_tokens: usage?.outputTokens ?? 0,\n total_tokens: usage?.totalTokens ?? ((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)),\n };\n}\n\nfunction openAiUsage(usage: GatewayUsage | undefined): Record<string, number> {\n return {\n input_tokens: usage?.inputTokens ?? 0,\n output_tokens: usage?.outputTokens ?? 0,\n total_tokens: usage?.totalTokens ?? ((usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0)),\n };\n}\n\nfunction anthropicUsage(usage: GatewayUsage | undefined): Record<string, number> {\n return {\n input_tokens: usage?.inputTokens ?? 0,\n output_tokens: usage?.outputTokens ?? 0,\n };\n}\n\nfunction parseJsonOrString(value: string): unknown {\n try {\n return JSON.parse(value || '{}');\n } catch {\n return value;\n }\n}\n"]}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { StoreContext } from '../../chatkit/store';
|
|
2
2
|
import type { AIConnectionInvocationConfig } from '../../../agents/types';
|
|
3
|
-
import type
|
|
4
|
-
import { type InvocationTokenCodec } from './InvocationTokenCodec';
|
|
3
|
+
import { type GatewayDeployment, type InvocationTokenCodec } from './InvocationTokenCodec';
|
|
5
4
|
export interface AiConnectionInvocationKeyIssuerOptions {
|
|
6
5
|
codec: InvocationTokenCodec;
|
|
7
6
|
deployment: GatewayDeployment;
|
|
@@ -32,6 +31,8 @@ export declare class AiConnectionInvocationKeyIssuer {
|
|
|
32
31
|
private readonly pending;
|
|
33
32
|
constructor(options: AiConnectionInvocationKeyIssuerOptions);
|
|
34
33
|
issue(context: StoreContext): Promise<AIConnectionInvocationConfig>;
|
|
34
|
+
issueClientConfiguration(context: StoreContext): Promise<AIConnectionInvocationConfig>;
|
|
35
|
+
private issueScoped;
|
|
35
36
|
private createInvocation;
|
|
36
37
|
private toInvocationConfig;
|
|
37
38
|
private pruneCache;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AiConnectionInvocationKeyIssuer = void 0;
|
|
4
|
-
const GatewayApiKeyAuthenticator_1 = require("./GatewayApiKeyAuthenticator");
|
|
5
4
|
const InvocationTokenCodec_1 = require("./InvocationTokenCodec");
|
|
6
5
|
// ACP can remain in an interactive authentication wait for five minutes.
|
|
7
6
|
// Ten minutes covers that boundary plus the resumed turn while retaining a
|
|
@@ -29,19 +28,33 @@ class AiConnectionInvocationKeyIssuer {
|
|
|
29
28
|
}
|
|
30
29
|
async issue(context) {
|
|
31
30
|
const auth = requireTrustedSolidAuth(context.auth);
|
|
31
|
+
if (auth.viaApiKey === true && auth.clientId && auth.clientSecret) {
|
|
32
|
+
return {
|
|
33
|
+
baseUrl: this.baseUrl,
|
|
34
|
+
apiKey: encodeClientCredentialsApiKey(auth.clientId, auth.clientSecret),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
throw new Error('AI Connection runtime execution requires delegated Solid client credentials');
|
|
38
|
+
}
|
|
39
|
+
async issueClientConfiguration(context) {
|
|
40
|
+
const auth = requireInteractiveSolidAuth(context.auth);
|
|
41
|
+
return this.issueScoped(auth, ['client-config:read', 'client-config:write']);
|
|
42
|
+
}
|
|
43
|
+
async issueScoped(auth, scopes) {
|
|
32
44
|
const webId = (0, InvocationTokenCodec_1.requireCanonicalWebId)(auth.webId);
|
|
45
|
+
const cacheKey = `${webId}\n${scopes.join(' ')}`;
|
|
33
46
|
const now = this.now();
|
|
34
|
-
const cached = this.cache.get(
|
|
47
|
+
const cached = this.cache.get(cacheKey);
|
|
35
48
|
if (cached && cached.expiresAt.getTime() - now.getTime() >= this.reuseSafetyMarginMs) {
|
|
36
49
|
return this.toInvocationConfig(cached);
|
|
37
50
|
}
|
|
38
|
-
let pending = this.pending.get(
|
|
51
|
+
let pending = this.pending.get(cacheKey);
|
|
39
52
|
if (!pending) {
|
|
40
|
-
pending = Promise.resolve().then(() => this.createInvocation(webId, now));
|
|
41
|
-
this.pending.set(
|
|
53
|
+
pending = Promise.resolve().then(() => this.createInvocation(cacheKey, webId, scopes, now));
|
|
54
|
+
this.pending.set(cacheKey, pending);
|
|
42
55
|
const clearPending = () => {
|
|
43
|
-
if (this.pending.get(
|
|
44
|
-
this.pending.delete(
|
|
56
|
+
if (this.pending.get(cacheKey) === pending) {
|
|
57
|
+
this.pending.delete(cacheKey);
|
|
45
58
|
}
|
|
46
59
|
};
|
|
47
60
|
void pending.then(clearPending, clearPending);
|
|
@@ -49,7 +62,7 @@ class AiConnectionInvocationKeyIssuer {
|
|
|
49
62
|
const issued = await pending;
|
|
50
63
|
return this.toInvocationConfig(issued);
|
|
51
64
|
}
|
|
52
|
-
createInvocation(webId, createdAt) {
|
|
65
|
+
createInvocation(cacheKey, webId, scopes, createdAt) {
|
|
53
66
|
this.pruneCache(createdAt);
|
|
54
67
|
const expiresAt = new Date(createdAt.getTime() + this.ttlMs);
|
|
55
68
|
const plaintext = this.codec.encode({
|
|
@@ -57,18 +70,18 @@ class AiConnectionInvocationKeyIssuer {
|
|
|
57
70
|
audience: this.audience,
|
|
58
71
|
issuer: this.issuer,
|
|
59
72
|
webId,
|
|
60
|
-
scopes
|
|
73
|
+
scopes,
|
|
61
74
|
issuedAt: createdAt,
|
|
62
75
|
expiresAt,
|
|
63
76
|
});
|
|
64
77
|
const cached = { plaintext, expiresAt };
|
|
65
|
-
this.cache.set(
|
|
78
|
+
this.cache.set(cacheKey, cached);
|
|
66
79
|
return cached;
|
|
67
80
|
}
|
|
68
81
|
toInvocationConfig(invocation) {
|
|
69
82
|
return {
|
|
70
83
|
baseUrl: this.baseUrl,
|
|
71
|
-
|
|
84
|
+
apiKey: invocation.plaintext,
|
|
72
85
|
expiresAt: invocation.expiresAt.toISOString(),
|
|
73
86
|
};
|
|
74
87
|
}
|
|
@@ -92,11 +105,23 @@ function requireTrustedSolidAuth(auth) {
|
|
|
92
105
|
if (auth?.type !== 'solid'
|
|
93
106
|
|| typeof auth.webId !== 'string'
|
|
94
107
|
|| auth.webId.trim().length === 0
|
|
95
|
-
|| auth.
|
|
108
|
+
|| (auth.viaApiKey === true && (!auth.clientId || !auth.clientSecret))) {
|
|
96
109
|
throw new Error('AI Connection invocation key requires an authenticated Solid WebID');
|
|
97
110
|
}
|
|
98
111
|
return auth;
|
|
99
112
|
}
|
|
113
|
+
function requireInteractiveSolidAuth(auth) {
|
|
114
|
+
if (auth?.type !== 'solid'
|
|
115
|
+
|| typeof auth.webId !== 'string'
|
|
116
|
+
|| auth.webId.trim().length === 0
|
|
117
|
+
|| auth.viaApiKey === true) {
|
|
118
|
+
throw new Error('AI Connection client configuration requires an authenticated interactive Solid WebID');
|
|
119
|
+
}
|
|
120
|
+
return auth;
|
|
121
|
+
}
|
|
122
|
+
function encodeClientCredentialsApiKey(clientId, clientSecret) {
|
|
123
|
+
return `sk-${Buffer.from(`${clientId}:${clientSecret}`, 'utf8').toString('base64')}`;
|
|
124
|
+
}
|
|
100
125
|
function requireBaseUrl(value) {
|
|
101
126
|
const normalized = value.trim().replace(/\/+$/u, '');
|
|
102
127
|
if (!normalized) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiConnectionInvocationKeyIssuer.js","sourceRoot":"","sources":["../../../../src/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthContext, SolidAuthContext } from '../../auth/AuthContext';\nimport type { StoreContext } from '../../chatkit/store';\nimport type { AIConnectionInvocationConfig } from '../../../agents/types';\nimport type { GatewayDeployment } from './GatewayApiKey';\nimport { DEFAULT_GATEWAY_API_KEY_SCOPES } from './GatewayApiKeyAuthenticator';\nimport { requireCanonicalOrigin, requireCanonicalWebId, type InvocationTokenCodec } from './InvocationTokenCodec';\n\n// ACP can remain in an interactive authentication wait for five minutes.\n// Ten minutes covers that boundary plus the resumed turn while retaining a\n// hard fifteen-minute ceiling for every stateless invocation token.\nconst DEFAULT_INVOCATION_KEY_TTL_MS = 10 * 60_000;\nconst MAX_INVOCATION_KEY_TTL_MS = 15 * 60_000;\n\nexport interface AiConnectionInvocationKeyIssuerOptions {\n codec: InvocationTokenCodec;\n deployment: GatewayDeployment;\n baseUrl: string;\n audience?: string;\n issuer?: string;\n ttlMs?: number;\n reuseSafetyMarginMs?: number;\n maxCacheEntries?: number;\n now?: () => Date;\n}\n\n/**\n * Produces a short-lived stateless Gateway token at the trusted execution\n * boundary. Nothing is persisted; plaintext exists solely in process memory\n * and the returned invocation context.\n */\nexport class AiConnectionInvocationKeyIssuer {\n private readonly codec: InvocationTokenCodec;\n private readonly deployment: GatewayDeployment;\n private readonly baseUrl: string;\n private readonly audience: string;\n private readonly issuer: string;\n private readonly ttlMs: number;\n private readonly reuseSafetyMarginMs: number;\n private readonly maxCacheEntries: number;\n private readonly now: () => Date;\n private readonly cache = new Map<string, CachedInvocation>();\n private readonly pending = new Map<string, Promise<CachedInvocation>>();\n\n public constructor(options: AiConnectionInvocationKeyIssuerOptions) {\n this.codec = options.codec;\n this.deployment = options.deployment;\n this.baseUrl = requireBaseUrl(options.baseUrl);\n this.audience = requireCanonicalOrigin(options.audience ?? new URL(this.baseUrl).origin, 'audience');\n this.issuer = requireCanonicalOrigin(options.issuer ?? this.audience, 'issuer');\n this.ttlMs = normalizeTtl(options.ttlMs);\n this.reuseSafetyMarginMs = normalizeSafetyMargin(options.reuseSafetyMarginMs, this.ttlMs);\n this.maxCacheEntries = normalizeMaxCacheEntries(options.maxCacheEntries);\n this.now = options.now ?? (() => new Date());\n }\n\n public async issue(context: StoreContext): Promise<AIConnectionInvocationConfig> {\n const auth = requireTrustedSolidAuth(context.auth as AuthContext | undefined);\n const webId = requireCanonicalWebId(auth.webId);\n const now = this.now();\n const cached = this.cache.get(webId);\n if (cached && cached.expiresAt.getTime() - now.getTime() >= this.reuseSafetyMarginMs) {\n return this.toInvocationConfig(cached);\n }\n let pending = this.pending.get(webId);\n if (!pending) {\n pending = Promise.resolve().then(() => this.createInvocation(webId, now));\n this.pending.set(webId, pending);\n const clearPending = (): void => {\n if (this.pending.get(webId) === pending) {\n this.pending.delete(webId);\n }\n };\n void pending.then(clearPending, clearPending);\n }\n const issued = await pending;\n\n return this.toInvocationConfig(issued);\n }\n\n private createInvocation(webId: string, createdAt: Date): CachedInvocation {\n this.pruneCache(createdAt);\n const expiresAt = new Date(createdAt.getTime() + this.ttlMs);\n const plaintext = this.codec.encode({\n deployment: this.deployment,\n audience: this.audience,\n issuer: this.issuer,\n webId,\n scopes: [...DEFAULT_GATEWAY_API_KEY_SCOPES, 'client-config:read', 'client-config:write'],\n issuedAt: createdAt,\n expiresAt,\n });\n const cached = { plaintext, expiresAt };\n this.cache.set(webId, cached);\n return cached;\n }\n\n private toInvocationConfig(invocation: CachedInvocation): AIConnectionInvocationConfig {\n return {\n baseUrl: this.baseUrl,\n gatewayKey: invocation.plaintext,\n expiresAt: invocation.expiresAt.toISOString(),\n };\n }\n\n private pruneCache(now: Date): void {\n for (const [webId, cached] of this.cache) {\n if (cached.expiresAt.getTime() <= now.getTime()) {\n this.cache.delete(webId);\n }\n }\n while (this.cache.size >= this.maxCacheEntries) {\n const oldest = this.cache.keys().next().value as string | undefined;\n if (!oldest) {\n break;\n }\n this.cache.delete(oldest);\n }\n }\n}\n\ninterface CachedInvocation {\n plaintext: string;\n expiresAt: Date;\n}\n\nfunction requireTrustedSolidAuth(auth: AuthContext | undefined): SolidAuthContext {\n if (\n auth?.type !== 'solid'\n || typeof auth.webId !== 'string'\n || auth.webId.trim().length === 0\n || auth.viaGatewayApiKey === true\n ) {\n throw new Error('AI Connection invocation key requires an authenticated Solid WebID');\n }\n return auth;\n}\n\nfunction requireBaseUrl(value: string): string {\n const normalized = value.trim().replace(/\\/+$/u, '');\n if (!normalized) {\n throw new Error('AI Connection invocation baseUrl is required');\n }\n return normalized;\n}\n\nfunction normalizeTtl(value: number | undefined): number {\n const ttlMs = value ?? DEFAULT_INVOCATION_KEY_TTL_MS;\n if (!Number.isFinite(ttlMs) || ttlMs <= 0 || ttlMs > MAX_INVOCATION_KEY_TTL_MS) {\n throw new Error(`AI Connection invocation key TTL must be between 1 and ${MAX_INVOCATION_KEY_TTL_MS} milliseconds`);\n }\n return ttlMs;\n}\n\nfunction normalizeSafetyMargin(value: number | undefined, ttlMs: number): number {\n const margin = value ?? 30_000;\n if (!Number.isFinite(margin) || margin < 0 || margin >= ttlMs) {\n throw new Error('AI Connection invocation key reuse safety margin must be non-negative and less than its TTL');\n }\n return margin;\n}\n\nfunction normalizeMaxCacheEntries(value: number | undefined): number {\n const entries = value ?? 1_024;\n if (!Number.isSafeInteger(entries) || entries <= 0 || entries > 100_000) {\n throw new Error('AI Connection invocation key cache size must be between 1 and 100000');\n }\n return entries;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AiConnectionInvocationKeyIssuer.js","sourceRoot":"","sources":["../../../../src/api/ai-gateway/auth/AiConnectionInvocationKeyIssuer.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AuthContext, SolidAuthContext } from '../../auth/AuthContext';\nimport type { StoreContext } from '../../chatkit/store';\nimport type { AIConnectionInvocationConfig } from '../../../agents/types';\nimport { requireCanonicalOrigin, requireCanonicalWebId, type GatewayDeployment, type InvocationTokenCodec } from './InvocationTokenCodec';\n\n// ACP can remain in an interactive authentication wait for five minutes.\n// Ten minutes covers that boundary plus the resumed turn while retaining a\n// hard fifteen-minute ceiling for every stateless invocation token.\nconst DEFAULT_INVOCATION_KEY_TTL_MS = 10 * 60_000;\nconst MAX_INVOCATION_KEY_TTL_MS = 15 * 60_000;\n\nexport interface AiConnectionInvocationKeyIssuerOptions {\n codec: InvocationTokenCodec;\n deployment: GatewayDeployment;\n baseUrl: string;\n audience?: string;\n issuer?: string;\n ttlMs?: number;\n reuseSafetyMarginMs?: number;\n maxCacheEntries?: number;\n now?: () => Date;\n}\n\n/**\n * Produces a short-lived stateless Gateway token at the trusted execution\n * boundary. Nothing is persisted; plaintext exists solely in process memory\n * and the returned invocation context.\n */\nexport class AiConnectionInvocationKeyIssuer {\n private readonly codec: InvocationTokenCodec;\n private readonly deployment: GatewayDeployment;\n private readonly baseUrl: string;\n private readonly audience: string;\n private readonly issuer: string;\n private readonly ttlMs: number;\n private readonly reuseSafetyMarginMs: number;\n private readonly maxCacheEntries: number;\n private readonly now: () => Date;\n private readonly cache = new Map<string, CachedInvocation>();\n private readonly pending = new Map<string, Promise<CachedInvocation>>();\n\n public constructor(options: AiConnectionInvocationKeyIssuerOptions) {\n this.codec = options.codec;\n this.deployment = options.deployment;\n this.baseUrl = requireBaseUrl(options.baseUrl);\n this.audience = requireCanonicalOrigin(options.audience ?? new URL(this.baseUrl).origin, 'audience');\n this.issuer = requireCanonicalOrigin(options.issuer ?? this.audience, 'issuer');\n this.ttlMs = normalizeTtl(options.ttlMs);\n this.reuseSafetyMarginMs = normalizeSafetyMargin(options.reuseSafetyMarginMs, this.ttlMs);\n this.maxCacheEntries = normalizeMaxCacheEntries(options.maxCacheEntries);\n this.now = options.now ?? (() => new Date());\n }\n\n public async issue(context: StoreContext): Promise<AIConnectionInvocationConfig> {\n const auth = requireTrustedSolidAuth(context.auth as AuthContext | undefined);\n if (auth.viaApiKey === true && auth.clientId && auth.clientSecret) {\n return {\n baseUrl: this.baseUrl,\n apiKey: encodeClientCredentialsApiKey(auth.clientId, auth.clientSecret),\n };\n }\n throw new Error('AI Connection runtime execution requires delegated Solid client credentials');\n }\n\n public async issueClientConfiguration(context: StoreContext): Promise<AIConnectionInvocationConfig> {\n const auth = requireInteractiveSolidAuth(context.auth as AuthContext | undefined);\n return this.issueScoped(auth, ['client-config:read', 'client-config:write']);\n }\n\n private async issueScoped(auth: SolidAuthContext, scopes: string[]): Promise<AIConnectionInvocationConfig> {\n const webId = requireCanonicalWebId(auth.webId);\n const cacheKey = `${webId}\\n${scopes.join(' ')}`;\n const now = this.now();\n const cached = this.cache.get(cacheKey);\n if (cached && cached.expiresAt.getTime() - now.getTime() >= this.reuseSafetyMarginMs) {\n return this.toInvocationConfig(cached);\n }\n let pending = this.pending.get(cacheKey);\n if (!pending) {\n pending = Promise.resolve().then(() => this.createInvocation(cacheKey, webId, scopes, now));\n this.pending.set(cacheKey, pending);\n const clearPending = (): void => {\n if (this.pending.get(cacheKey) === pending) {\n this.pending.delete(cacheKey);\n }\n };\n void pending.then(clearPending, clearPending);\n }\n const issued = await pending;\n\n return this.toInvocationConfig(issued);\n }\n\n private createInvocation(cacheKey: string, webId: string, scopes: string[], createdAt: Date): CachedInvocation {\n this.pruneCache(createdAt);\n const expiresAt = new Date(createdAt.getTime() + this.ttlMs);\n const plaintext = this.codec.encode({\n deployment: this.deployment,\n audience: this.audience,\n issuer: this.issuer,\n webId,\n scopes,\n issuedAt: createdAt,\n expiresAt,\n });\n const cached = { plaintext, expiresAt };\n this.cache.set(cacheKey, cached);\n return cached;\n }\n\n private toInvocationConfig(invocation: CachedInvocation): AIConnectionInvocationConfig {\n return {\n baseUrl: this.baseUrl,\n apiKey: invocation.plaintext,\n expiresAt: invocation.expiresAt.toISOString(),\n };\n }\n\n private pruneCache(now: Date): void {\n for (const [webId, cached] of this.cache) {\n if (cached.expiresAt.getTime() <= now.getTime()) {\n this.cache.delete(webId);\n }\n }\n while (this.cache.size >= this.maxCacheEntries) {\n const oldest = this.cache.keys().next().value as string | undefined;\n if (!oldest) {\n break;\n }\n this.cache.delete(oldest);\n }\n }\n}\n\ninterface CachedInvocation {\n plaintext: string;\n expiresAt: Date;\n}\n\nfunction requireTrustedSolidAuth(auth: AuthContext | undefined): SolidAuthContext {\n if (\n auth?.type !== 'solid'\n || typeof auth.webId !== 'string'\n || auth.webId.trim().length === 0\n || (auth.viaApiKey === true && (!auth.clientId || !auth.clientSecret))\n ) {\n throw new Error('AI Connection invocation key requires an authenticated Solid WebID');\n }\n return auth;\n}\n\nfunction requireInteractiveSolidAuth(auth: AuthContext | undefined): SolidAuthContext {\n if (\n auth?.type !== 'solid'\n || typeof auth.webId !== 'string'\n || auth.webId.trim().length === 0\n || auth.viaApiKey === true\n ) {\n throw new Error('AI Connection client configuration requires an authenticated interactive Solid WebID');\n }\n return auth;\n}\n\nfunction encodeClientCredentialsApiKey(clientId: string, clientSecret: string): string {\n return `sk-${Buffer.from(`${clientId}:${clientSecret}`, 'utf8').toString('base64')}`;\n}\n\nfunction requireBaseUrl(value: string): string {\n const normalized = value.trim().replace(/\\/+$/u, '');\n if (!normalized) {\n throw new Error('AI Connection invocation baseUrl is required');\n }\n return normalized;\n}\n\nfunction normalizeTtl(value: number | undefined): number {\n const ttlMs = value ?? DEFAULT_INVOCATION_KEY_TTL_MS;\n if (!Number.isFinite(ttlMs) || ttlMs <= 0 || ttlMs > MAX_INVOCATION_KEY_TTL_MS) {\n throw new Error(`AI Connection invocation key TTL must be between 1 and ${MAX_INVOCATION_KEY_TTL_MS} milliseconds`);\n }\n return ttlMs;\n}\n\nfunction normalizeSafetyMargin(value: number | undefined, ttlMs: number): number {\n const margin = value ?? 30_000;\n if (!Number.isFinite(margin) || margin < 0 || margin >= ttlMs) {\n throw new Error('AI Connection invocation key reuse safety margin must be non-negative and less than its TTL');\n }\n return margin;\n}\n\nfunction normalizeMaxCacheEntries(value: number | undefined): number {\n const entries = value ?? 1_024;\n if (!Number.isSafeInteger(entries) || entries <= 0 || entries > 100_000) {\n throw new Error('AI Connection invocation key cache size must be between 1 and 100000');\n }\n return entries;\n}\n"]}
|
|
@@ -1,20 +1,6 @@
|
|
|
1
1
|
import type { AuthContext, SolidAuthContext } from '../../auth/AuthContext';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
accountId?: string;
|
|
5
|
-
scopes: string[];
|
|
6
|
-
keyId: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function isGatewayApiKeyPrincipal(auth: AuthContext | undefined): auth is SolidAuthContext & {
|
|
9
|
-
viaGatewayApiKey: true;
|
|
10
|
-
gatewayKeyId: string;
|
|
11
|
-
scopes: string[];
|
|
12
|
-
};
|
|
13
|
-
export declare function isInternalGatewayInvocationPrincipal(auth: AuthContext | undefined): auth is SolidAuthContext & {
|
|
14
|
-
viaGatewayApiKey: true;
|
|
2
|
+
export declare function isInternalInvocationPrincipal(auth: AuthContext | undefined): auth is SolidAuthContext & {
|
|
3
|
+
viaApiKey: true;
|
|
15
4
|
internalInvocation: true;
|
|
16
|
-
gatewayKeyId: string;
|
|
17
5
|
scopes: string[];
|
|
18
6
|
};
|
|
19
|
-
export declare function canManageGatewayKeys(auth: AuthContext | undefined): boolean;
|
|
20
|
-
export declare function ownerWebIdForGatewayKeyManagement(auth: AuthContext, requestedOwner: unknown): string | undefined;
|
|
@@ -1,37 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.ownerWebIdForGatewayKeyManagement = ownerWebIdForGatewayKeyManagement;
|
|
7
|
-
function isGatewayApiKeyPrincipal(auth) {
|
|
8
|
-
return auth?.type === 'solid' && auth.viaGatewayApiKey === true;
|
|
9
|
-
}
|
|
10
|
-
function isInternalGatewayInvocationPrincipal(auth) {
|
|
11
|
-
return isGatewayApiKeyPrincipal(auth) && auth.internalInvocation === true;
|
|
12
|
-
}
|
|
13
|
-
function canManageGatewayKeys(auth) {
|
|
14
|
-
if (!auth) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
if (isGatewayApiKeyPrincipal(auth)) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
if (auth.type === 'solid') {
|
|
21
|
-
return Boolean(auth.webId);
|
|
22
|
-
}
|
|
23
|
-
return hasGatewayKeyManagementScope(auth);
|
|
24
|
-
}
|
|
25
|
-
function ownerWebIdForGatewayKeyManagement(auth, requestedOwner) {
|
|
26
|
-
if (auth.type === 'solid') {
|
|
27
|
-
return auth.webId;
|
|
28
|
-
}
|
|
29
|
-
if (hasGatewayKeyManagementScope(auth) && typeof requestedOwner === 'string' && requestedOwner.trim()) {
|
|
30
|
-
return requestedOwner.trim();
|
|
31
|
-
}
|
|
32
|
-
return undefined;
|
|
33
|
-
}
|
|
34
|
-
function hasGatewayKeyManagementScope(auth) {
|
|
35
|
-
return auth.type === 'service' && auth.scopes.includes('gateway:keys:write');
|
|
3
|
+
exports.isInternalInvocationPrincipal = isInternalInvocationPrincipal;
|
|
4
|
+
function isInternalInvocationPrincipal(auth) {
|
|
5
|
+
return auth?.type === 'solid' && auth.viaApiKey === true && auth.internalInvocation === true;
|
|
36
6
|
}
|
|
37
7
|
//# sourceMappingURL=GatewayPrincipal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GatewayPrincipal.js","sourceRoot":"","sources":["../../../../src/api/ai-gateway/auth/GatewayPrincipal.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"GatewayPrincipal.js","sourceRoot":"","sources":["../../../../src/api/ai-gateway/auth/GatewayPrincipal.ts"],"names":[],"mappings":";;AAEA,sEAMC;AAND,SAAgB,6BAA6B,CAAC,IAA6B;IAKzE,OAAO,IAAI,EAAE,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,kBAAkB,KAAK,IAAI,CAAC;AAC/F,CAAC","sourcesContent":["import type { AuthContext, SolidAuthContext } from '../../auth/AuthContext';\n\nexport function isInternalInvocationPrincipal(auth: AuthContext | undefined): auth is SolidAuthContext & {\n viaApiKey: true;\n internalInvocation: true;\n scopes: string[];\n} {\n return auth?.type === 'solid' && auth.viaApiKey === true && auth.internalInvocation === true;\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IncomingMessage } from 'node:http';
|
|
2
|
+
import type { Authenticator, AuthResult } from '../../auth/Authenticator';
|
|
3
|
+
import type { GatewayDeployment, InvocationTokenCodec } from './InvocationTokenCodec';
|
|
4
|
+
export interface InvocationTokenAuthenticatorOptions {
|
|
5
|
+
codec: InvocationTokenCodec;
|
|
6
|
+
deployment: GatewayDeployment;
|
|
7
|
+
audience?: string;
|
|
8
|
+
issuer?: string;
|
|
9
|
+
now?: () => Date;
|
|
10
|
+
maxClockSkewMs?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class InvocationTokenAuthenticator implements Authenticator {
|
|
13
|
+
private readonly codec;
|
|
14
|
+
private readonly deployment;
|
|
15
|
+
private readonly audience?;
|
|
16
|
+
private readonly issuer?;
|
|
17
|
+
private readonly now;
|
|
18
|
+
private readonly maxClockSkewMs;
|
|
19
|
+
constructor(options: InvocationTokenAuthenticatorOptions);
|
|
20
|
+
canAuthenticate(request: IncomingMessage): boolean;
|
|
21
|
+
authenticate(request: IncomingMessage): Promise<AuthResult>;
|
|
22
|
+
private validClaims;
|
|
23
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InvocationTokenAuthenticator = void 0;
|
|
4
|
+
const InvocationTokenCodec_1 = require("./InvocationTokenCodec");
|
|
5
|
+
const INVALID_INVOCATION_TOKEN = 'Invalid invocation token';
|
|
6
|
+
const CLIENT_CONFIG_PREFIX = '/api/ai/client-configuration/';
|
|
7
|
+
const CLIENT_CONFIG_CAPABILITY = '/api/ai/client-configuration/capability';
|
|
8
|
+
const ALLOWED_INVOCATION_SCOPES = new Set([
|
|
9
|
+
'client-config:read',
|
|
10
|
+
'client-config:write',
|
|
11
|
+
]);
|
|
12
|
+
class InvocationTokenAuthenticator {
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.codec = options.codec;
|
|
15
|
+
this.deployment = options.deployment;
|
|
16
|
+
this.audience = options.audience ? (0, InvocationTokenCodec_1.requireCanonicalOrigin)(options.audience, 'audience') : undefined;
|
|
17
|
+
this.issuer = options.issuer ? (0, InvocationTokenCodec_1.requireCanonicalOrigin)(options.issuer, 'issuer') : this.audience;
|
|
18
|
+
this.now = options.now ?? (() => new Date());
|
|
19
|
+
this.maxClockSkewMs = options.maxClockSkewMs ?? 5_000;
|
|
20
|
+
if (!Number.isSafeInteger(this.maxClockSkewMs) || this.maxClockSkewMs < 0 || this.maxClockSkewMs > 30_000) {
|
|
21
|
+
throw new Error('Invocation token clock skew must be between 0 and 30000 milliseconds');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
canAuthenticate(request) {
|
|
25
|
+
const bearer = readBearer(request);
|
|
26
|
+
return Boolean(bearer?.startsWith('xpod_inv_v1.') && requiredScope(request));
|
|
27
|
+
}
|
|
28
|
+
async authenticate(request) {
|
|
29
|
+
const bearer = readBearer(request);
|
|
30
|
+
const claims = bearer?.startsWith('xpod_inv_v1.') ? this.codec.decode(bearer) : undefined;
|
|
31
|
+
if (!bearer || !claims || !this.validClaims(claims, request)) {
|
|
32
|
+
return invalidInvocationToken();
|
|
33
|
+
}
|
|
34
|
+
const context = {
|
|
35
|
+
type: 'solid',
|
|
36
|
+
webId: claims.webId,
|
|
37
|
+
accountId: claims.webId,
|
|
38
|
+
internalInvocation: true,
|
|
39
|
+
scopes: claims.scopes,
|
|
40
|
+
tokenType: 'Bearer',
|
|
41
|
+
};
|
|
42
|
+
return { success: true, context };
|
|
43
|
+
}
|
|
44
|
+
validClaims(claims, request) {
|
|
45
|
+
const now = this.now().getTime();
|
|
46
|
+
const scope = requiredScope(request);
|
|
47
|
+
return (Boolean(scope)
|
|
48
|
+
&& claims.deployment === this.deployment
|
|
49
|
+
&& (!this.audience || claims.audience === this.audience)
|
|
50
|
+
&& (!this.issuer || claims.issuer === this.issuer)
|
|
51
|
+
&& claims.issuedAt.getTime() <= now + this.maxClockSkewMs
|
|
52
|
+
&& claims.expiresAt.getTime() > now
|
|
53
|
+
&& claims.scopes.length > 0
|
|
54
|
+
&& claims.scopes.every((scope) => ALLOWED_INVOCATION_SCOPES.has(scope))
|
|
55
|
+
&& claims.scopes.includes(scope));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.InvocationTokenAuthenticator = InvocationTokenAuthenticator;
|
|
59
|
+
function requiredScope(request) {
|
|
60
|
+
const pathname = new URL(request.url ?? '/', 'http://localhost').pathname;
|
|
61
|
+
if (pathname === CLIENT_CONFIG_CAPABILITY || pathname.startsWith(CLIENT_CONFIG_PREFIX)) {
|
|
62
|
+
return request.method === 'GET' ? 'client-config:read' : 'client-config:write';
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
function readBearer(request) {
|
|
67
|
+
const authorization = request.headers.authorization;
|
|
68
|
+
if (!authorization?.startsWith('Bearer ')) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
return authorization.slice(7).trim();
|
|
72
|
+
}
|
|
73
|
+
function invalidInvocationToken() {
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: INVALID_INVOCATION_TOKEN,
|
|
77
|
+
category: 'invalid_credentials',
|
|
78
|
+
statusCode: 401,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=InvocationTokenAuthenticator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InvocationTokenAuthenticator.js","sourceRoot":"","sources":["../../../../src/api/ai-gateway/auth/InvocationTokenAuthenticator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IncomingMessage } from 'node:http';\nimport type { Authenticator, AuthResult } from '../../auth/Authenticator';\nimport type { SolidAuthContext } from '../../auth/AuthContext';\nimport type { GatewayDeployment, InvocationTokenClaims, InvocationTokenCodec } from './InvocationTokenCodec';\nimport { requireCanonicalOrigin } from './InvocationTokenCodec';\n\nexport interface InvocationTokenAuthenticatorOptions {\n codec: InvocationTokenCodec;\n deployment: GatewayDeployment;\n audience?: string;\n issuer?: string;\n now?: () => Date;\n maxClockSkewMs?: number;\n}\n\nconst INVALID_INVOCATION_TOKEN = 'Invalid invocation token';\nconst CLIENT_CONFIG_PREFIX = '/api/ai/client-configuration/';\nconst CLIENT_CONFIG_CAPABILITY = '/api/ai/client-configuration/capability';\nconst ALLOWED_INVOCATION_SCOPES = new Set([\n 'client-config:read',\n 'client-config:write',\n]);\n\nexport class InvocationTokenAuthenticator implements Authenticator {\n private readonly codec: InvocationTokenCodec;\n private readonly deployment: GatewayDeployment;\n private readonly audience?: string;\n private readonly issuer?: string;\n private readonly now: () => Date;\n private readonly maxClockSkewMs: number;\n\n public constructor(options: InvocationTokenAuthenticatorOptions) {\n this.codec = options.codec;\n this.deployment = options.deployment;\n this.audience = options.audience ? requireCanonicalOrigin(options.audience, 'audience') : undefined;\n this.issuer = options.issuer ? requireCanonicalOrigin(options.issuer, 'issuer') : this.audience;\n this.now = options.now ?? (() => new Date());\n this.maxClockSkewMs = options.maxClockSkewMs ?? 5_000;\n if (!Number.isSafeInteger(this.maxClockSkewMs) || this.maxClockSkewMs < 0 || this.maxClockSkewMs > 30_000) {\n throw new Error('Invocation token clock skew must be between 0 and 30000 milliseconds');\n }\n }\n\n public canAuthenticate(request: IncomingMessage): boolean {\n const bearer = readBearer(request);\n return Boolean(bearer?.startsWith('xpod_inv_v1.') && requiredScope(request));\n }\n\n public async authenticate(request: IncomingMessage): Promise<AuthResult> {\n const bearer = readBearer(request);\n const claims = bearer?.startsWith('xpod_inv_v1.') ? this.codec.decode(bearer) : undefined;\n if (!bearer || !claims || !this.validClaims(claims, request)) {\n return invalidInvocationToken();\n }\n const context: SolidAuthContext = {\n type: 'solid',\n webId: claims.webId,\n accountId: claims.webId,\n internalInvocation: true,\n scopes: claims.scopes,\n tokenType: 'Bearer',\n };\n return { success: true, context };\n }\n\n private validClaims(claims: InvocationTokenClaims, request: IncomingMessage): boolean {\n const now = this.now().getTime();\n const scope = requiredScope(request);\n return (\n Boolean(scope)\n && claims.deployment === this.deployment\n && (!this.audience || claims.audience === this.audience)\n && (!this.issuer || claims.issuer === this.issuer)\n && claims.issuedAt.getTime() <= now + this.maxClockSkewMs\n && claims.expiresAt.getTime() > now\n && claims.scopes.length > 0\n && claims.scopes.every((scope) => ALLOWED_INVOCATION_SCOPES.has(scope))\n && claims.scopes.includes(scope!)\n );\n }\n}\n\nfunction requiredScope(request: IncomingMessage): string | undefined {\n const pathname = new URL(request.url ?? '/', 'http://localhost').pathname;\n if (pathname === CLIENT_CONFIG_CAPABILITY || pathname.startsWith(CLIENT_CONFIG_PREFIX)) {\n return request.method === 'GET' ? 'client-config:read' : 'client-config:write';\n }\n return undefined;\n}\n\nfunction readBearer(request: IncomingMessage): string | undefined {\n const authorization = request.headers.authorization;\n if (!authorization?.startsWith('Bearer ')) {\n return undefined;\n }\n return authorization.slice(7).trim();\n}\n\nfunction invalidInvocationToken(): AuthResult {\n return {\n success: false,\n error: INVALID_INVOCATION_TOKEN,\n category: 'invalid_credentials',\n statusCode: 401,\n };\n}\n"]}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import type { GatewayDeployment } from './GatewayApiKey';
|
|
2
|
-
import type { GatewayKeyLocatorSecret } from './GatewayKeyLocatorCodec';
|
|
3
1
|
export interface InvocationTokenClaims {
|
|
4
2
|
version: 1;
|
|
5
3
|
kid: string;
|
|
@@ -12,6 +10,11 @@ export interface InvocationTokenClaims {
|
|
|
12
10
|
expiresAt: Date;
|
|
13
11
|
jti: string;
|
|
14
12
|
}
|
|
13
|
+
export type GatewayDeployment = 'cloud' | 'local';
|
|
14
|
+
export interface InvocationTokenSecret {
|
|
15
|
+
kid: string;
|
|
16
|
+
secret: string;
|
|
17
|
+
}
|
|
15
18
|
export interface InvocationTokenInput {
|
|
16
19
|
deployment: GatewayDeployment;
|
|
17
20
|
audience: string;
|
|
@@ -27,8 +30,8 @@ export interface InvocationTokenCodec {
|
|
|
27
30
|
decode(token: string): InvocationTokenClaims | undefined;
|
|
28
31
|
}
|
|
29
32
|
export interface AesInvocationTokenCodecOptions {
|
|
30
|
-
active:
|
|
31
|
-
previous?:
|
|
33
|
+
active: InvocationTokenSecret;
|
|
34
|
+
previous?: InvocationTokenSecret[];
|
|
32
35
|
}
|
|
33
36
|
export declare class AesInvocationTokenCodec implements InvocationTokenCodec {
|
|
34
37
|
private readonly active;
|