@undefineds.co/xpod 0.1.7 → 0.2.0
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/README.md +164 -3
- package/config/cli.json +9 -71
- package/config/cloud.json +34 -7
- package/config/local.json +6 -2
- package/config/resolver.json +11 -49
- package/config/runtime-open.json +22 -0
- package/config/xpod.base.json +32 -0
- package/config/xpod.cluster.json +2 -44
- package/config/xpod.json +5 -2
- package/dist/agents/AgentExecutorFactory.js +1 -1
- package/dist/agents/AgentExecutorFactory.js.map +1 -1
- package/dist/agents/AgentManager.js +1 -1
- package/dist/agents/AgentManager.js.map +1 -1
- package/dist/agents/config/agent-meta-schema.d.ts +7 -7
- package/dist/agents/config/agent-meta-schema.js +1 -1
- package/dist/agents/config/agent-meta-schema.js.map +1 -1
- package/dist/agents/config/resolve.js +1 -1
- package/dist/agents/config/resolve.js.map +1 -1
- package/dist/agents/schema/agent-config.d.ts +18 -18
- package/dist/agents/schema/agent-config.js +1 -1
- package/dist/agents/schema/agent-config.js.map +1 -1
- package/dist/agents/schema/tables.d.ts +8 -8
- package/dist/agents/schema/tables.js +1 -1
- package/dist/agents/schema/tables.js.map +1 -1
- package/dist/ai/schema/config.d.ts +7 -7
- package/dist/ai/schema/config.js +1 -1
- package/dist/ai/schema/config.js.map +1 -1
- package/dist/ai/schema/model.d.ts +13 -13
- package/dist/ai/schema/model.js +1 -1
- package/dist/ai/schema/model.js.map +1 -1
- package/dist/ai/schema/provider.d.ts +7 -7
- package/dist/ai/schema/provider.js +1 -1
- package/dist/ai/schema/provider.js.map +1 -1
- package/dist/ai/schema/vector-store.d.ts +17 -17
- package/dist/ai/schema/vector-store.js +1 -1
- package/dist/ai/schema/vector-store.js.map +1 -1
- package/dist/ai/service/CredentialReaderImpl.js +1 -1
- package/dist/ai/service/CredentialReaderImpl.js.map +1 -1
- package/dist/ai/service/DefaultAiConfigService.js.map +1 -1
- package/dist/api/ApiServer.d.ts +3 -1
- package/dist/api/ApiServer.js +14 -1
- package/dist/api/ApiServer.js.map +1 -1
- package/dist/api/auth/AuthContext.d.ts +12 -1
- package/dist/api/auth/AuthContext.js +18 -1
- package/dist/api/auth/AuthContext.js.map +1 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +0 -1
- package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
- package/dist/api/auth/ServiceTokenAuthenticator.d.ts +18 -0
- package/dist/api/auth/ServiceTokenAuthenticator.js +50 -0
- package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -0
- package/dist/api/auth/index.d.ts +1 -0
- package/dist/api/auth/index.js +1 -0
- package/dist/api/auth/index.js.map +1 -1
- package/dist/api/chatkit/ai-provider.d.ts +0 -10
- package/dist/api/chatkit/ai-provider.js +11 -120
- package/dist/api/chatkit/ai-provider.js.map +1 -1
- package/dist/api/chatkit/default-agent.js +11 -8
- package/dist/api/chatkit/default-agent.js.map +1 -1
- package/dist/api/chatkit/pod-store.d.ts +6 -0
- package/dist/api/chatkit/pod-store.js +103 -36
- package/dist/api/chatkit/pod-store.js.map +1 -1
- package/dist/api/chatkit/schema.d.ts +32 -26
- package/dist/api/chatkit/schema.js +16 -8
- package/dist/api/chatkit/schema.js.map +1 -1
- package/dist/api/container/business-token.d.ts +9 -0
- package/dist/api/container/business-token.js +32 -0
- package/dist/api/container/business-token.js.map +1 -0
- package/dist/api/container/cloud.js +36 -12
- package/dist/api/container/cloud.js.map +1 -1
- package/dist/api/container/common.js +13 -5
- package/dist/api/container/common.js.map +1 -1
- package/dist/api/container/index.js +94 -14
- package/dist/api/container/index.js.map +1 -1
- package/dist/api/container/local.js +2 -1
- package/dist/api/container/local.js.map +1 -1
- package/dist/api/container/routes.js +81 -9
- package/dist/api/container/routes.js.map +1 -1
- package/dist/api/container/types.d.ts +8 -6
- package/dist/api/container/types.js.map +1 -1
- package/dist/api/handlers/AdminHandler.js +9 -9
- package/dist/api/handlers/AdminHandler.js.map +1 -1
- package/dist/api/handlers/ApiKeyHandler.js +0 -6
- package/dist/api/handlers/ApiKeyHandler.js.map +1 -1
- package/dist/api/handlers/EdgeNodeSignalHandler.d.ts +17 -0
- package/dist/api/handlers/EdgeNodeSignalHandler.js +171 -0
- package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -0
- package/dist/api/handlers/PodManagementHandler.d.ts +5 -4
- package/dist/api/handlers/PodManagementHandler.js +11 -10
- package/dist/api/handlers/PodManagementHandler.js.map +1 -1
- package/dist/api/handlers/ProvisionHandler.d.ts +42 -0
- package/dist/api/handlers/ProvisionHandler.js +161 -0
- package/dist/api/handlers/ProvisionHandler.js.map +1 -0
- package/dist/api/handlers/QuotaHandler.d.ts +7 -7
- package/dist/api/handlers/QuotaHandler.js +143 -73
- package/dist/api/handlers/QuotaHandler.js.map +1 -1
- package/dist/api/handlers/SubdomainClientHandler.js +2 -2
- package/dist/api/handlers/SubdomainClientHandler.js.map +1 -1
- package/dist/api/handlers/SubdomainHandler.js +13 -8
- package/dist/api/handlers/SubdomainHandler.js.map +1 -1
- package/dist/api/handlers/UsageHandler.d.ts +14 -0
- package/dist/api/handlers/UsageHandler.js +123 -0
- package/dist/api/handlers/UsageHandler.js.map +1 -0
- package/dist/api/handlers/index.d.ts +3 -1
- package/dist/api/handlers/index.js +3 -1
- package/dist/api/handlers/index.js.map +1 -1
- package/dist/api/main.js +18 -0
- package/dist/api/main.js.map +1 -1
- package/dist/api/middleware/OpenAuthMiddleware.d.ts +12 -0
- package/dist/api/middleware/OpenAuthMiddleware.js +27 -0
- package/dist/api/middleware/OpenAuthMiddleware.js.map +1 -0
- package/dist/api/runtime.d.ts +15 -0
- package/dist/api/runtime.js +125 -0
- package/dist/api/runtime.js.map +1 -0
- package/dist/api/service/VectorStoreService.js +1 -1
- package/dist/api/service/VectorStoreService.js.map +1 -1
- package/dist/api/service/VercelChatService.d.ts +16 -7
- package/dist/api/service/VercelChatService.js +98 -178
- package/dist/api/service/VercelChatService.js.map +1 -1
- package/dist/api/store/DrizzleClientCredentialsStore.d.ts +6 -11
- package/dist/api/store/DrizzleClientCredentialsStore.js +9 -39
- package/dist/api/store/DrizzleClientCredentialsStore.js.map +1 -1
- package/dist/authorization/AuthModeSelector.d.ts +10 -0
- package/dist/authorization/AuthModeSelector.js +27 -0
- package/dist/authorization/AuthModeSelector.js.map +1 -0
- package/dist/authorization/AuthModeSelector.jsonld +81 -0
- package/dist/cli/commands/account.d.ts +6 -0
- package/dist/cli/commands/account.js +119 -0
- package/dist/cli/commands/account.js.map +1 -0
- package/dist/cli/commands/auth.js +20 -29
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/backup.d.ts +15 -0
- package/dist/cli/commands/backup.js +286 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/config.d.ts +34 -3
- package/dist/cli/commands/config.js +195 -258
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +6 -0
- package/dist/cli/commands/doctor.js +94 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/pod.d.ts +6 -0
- package/dist/cli/commands/pod.js +124 -0
- package/dist/cli/commands/pod.js.map +1 -0
- package/dist/cli/commands/start.js +28 -5
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/index.js +9 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/lib/credentials-store.d.ts +17 -0
- package/dist/cli/lib/credentials-store.js +73 -0
- package/dist/cli/lib/credentials-store.js.map +1 -0
- package/dist/cli/lib/css-account.d.ts +17 -0
- package/dist/cli/lib/css-account.js +56 -0
- package/dist/cli/lib/css-account.js.map +1 -1
- package/dist/cli/lib/pod-thread-store.d.ts +57 -0
- package/dist/cli/lib/pod-thread-store.js +310 -0
- package/dist/cli/lib/pod-thread-store.js.map +1 -0
- package/dist/cli/lib/solid-auth.d.ts +20 -0
- package/dist/cli/lib/solid-auth.js +70 -0
- package/dist/cli/lib/solid-auth.js.map +1 -0
- package/dist/components/components.jsonld +5 -8
- package/dist/components/context.jsonld +114 -244
- package/dist/credential/schema/tables.d.ts +14 -14
- package/dist/credential/schema/tables.js +1 -1
- package/dist/credential/schema/tables.js.map +1 -1
- package/dist/edge/EdgeNodeAgent.js +2 -2
- package/dist/edge/EdgeNodeAgent.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -7
- package/dist/edge/EdgeNodeDnsCoordinator.js +31 -41
- package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
- package/dist/edge/EdgeNodeDnsCoordinator.jsonld +1 -27
- package/dist/edge/EdgeNodeModeDetector.d.ts +1 -1
- package/dist/edge/EdgeNodeModeDetector.js +9 -11
- package/dist/edge/EdgeNodeModeDetector.js.map +1 -1
- package/dist/http/ClusterIngressRouter.js +3 -3
- package/dist/http/ClusterIngressRouter.js.map +1 -1
- package/dist/http/ClusterWebSocketConfigurator.js +2 -2
- package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
- package/dist/http/PodRoutingHttpHandler.js +2 -2
- package/dist/http/PodRoutingHttpHandler.js.map +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.d.ts +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.js +1 -1
- package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
- package/dist/identity/drizzle/EdgeNodeRepository.d.ts +37 -4
- package/dist/identity/drizzle/EdgeNodeRepository.js +120 -128
- package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
- package/dist/identity/drizzle/ServiceTokenRepository.d.ts +52 -0
- package/dist/identity/drizzle/ServiceTokenRepository.js +142 -0
- package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -0
- package/dist/identity/drizzle/db.d.ts +9 -0
- package/dist/identity/drizzle/db.js +235 -3
- package/dist/identity/drizzle/db.js.map +1 -1
- package/dist/identity/drizzle/schema.pg.d.ts +5 -0
- package/dist/identity/drizzle/schema.pg.js +49 -20
- package/dist/identity/drizzle/schema.pg.js.map +1 -1
- package/dist/identity/drizzle/schema.sqlite.d.ts +332 -57
- package/dist/identity/drizzle/schema.sqlite.js +48 -18
- package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +6 -4
- package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
- package/dist/index.d.ts +6 -9
- package/dist/index.js +12 -14
- package/dist/index.js.map +1 -1
- package/dist/main.js +25 -8
- package/dist/main.js.map +1 -1
- package/dist/provision/ProvisionCodeCodec.d.ts +39 -0
- package/dist/provision/ProvisionCodeCodec.js +65 -0
- package/dist/provision/ProvisionCodeCodec.js.map +1 -0
- package/dist/provision/ProvisionCodeCodec.jsonld +47 -0
- package/dist/provision/ProvisionPodCreator.d.ts +20 -0
- package/dist/provision/ProvisionPodCreator.js +84 -0
- package/dist/provision/ProvisionPodCreator.js.map +1 -0
- package/dist/provision/ProvisionPodCreator.jsonld +118 -0
- package/dist/quota/DrizzleQuotaService.d.ts +17 -3
- package/dist/quota/DrizzleQuotaService.js +108 -8
- package/dist/quota/DrizzleQuotaService.js.map +1 -1
- package/dist/quota/DrizzleQuotaService.jsonld +33 -22
- package/dist/quota/NoopQuotaService.d.ts +7 -1
- package/dist/quota/NoopQuotaService.js +12 -0
- package/dist/quota/NoopQuotaService.js.map +1 -1
- package/dist/quota/NoopQuotaService.jsonld +24 -0
- package/dist/quota/QuotaService.d.ts +17 -0
- package/dist/quota/QuotaService.js +5 -0
- package/dist/quota/QuotaService.js.map +1 -1
- package/dist/quota/QuotaService.jsonld +50 -0
- package/dist/runtime/Proxy.d.ts +22 -4
- package/dist/runtime/Proxy.js +154 -35
- package/dist/runtime/Proxy.js.map +1 -1
- package/dist/runtime/XpodRuntime.d.ts +49 -0
- package/dist/runtime/XpodRuntime.js +374 -0
- package/dist/runtime/XpodRuntime.js.map +1 -0
- package/dist/runtime/env-utils.d.ts +2 -0
- package/dist/runtime/env-utils.js +55 -0
- package/dist/runtime/env-utils.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.js +8 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/socket-fetch.d.ts +1 -0
- package/dist/runtime/socket-fetch.js +72 -0
- package/dist/runtime/socket-fetch.js.map +1 -0
- package/dist/runtime/socket-http.d.ts +1 -0
- package/dist/runtime/socket-http.js +142 -0
- package/dist/runtime/socket-http.js.map +1 -0
- package/dist/runtime/socket-utils.d.ts +2 -0
- package/dist/runtime/socket-utils.js +34 -0
- package/dist/runtime/socket-utils.js.map +1 -0
- package/dist/service/{EdgeNodeHeartbeatService.d.ts → EdgeNodeSignalClient.d.ts} +3 -3
- package/dist/service/{EdgeNodeHeartbeatService.js → EdgeNodeSignalClient.js} +4 -4
- package/dist/service/EdgeNodeSignalClient.js.map +1 -0
- package/dist/service/PodMigrationService.d.ts +1 -2
- package/dist/service/PodMigrationService.js +1 -2
- package/dist/service/PodMigrationService.js.map +1 -1
- package/dist/storage/SparqlUpdateResourceStore.js +1 -1
- package/dist/storage/SparqlUpdateResourceStore.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.d.ts +6 -0
- package/dist/storage/accessors/MinioDataAccessor.js +10 -0
- package/dist/storage/accessors/MinioDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MinioDataAccessor.jsonld +4 -0
- package/dist/storage/accessors/MixDataAccessor.d.ts +2 -1
- package/dist/storage/accessors/MixDataAccessor.js +12 -1
- package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
- package/dist/storage/accessors/MixDataAccessor.jsonld +19 -0
- package/dist/storage/locking/UrlAwareRedisLocker.d.ts +18 -0
- package/dist/storage/locking/UrlAwareRedisLocker.js +60 -0
- package/dist/storage/locking/UrlAwareRedisLocker.js.map +1 -0
- package/dist/storage/locking/UrlAwareRedisLocker.jsonld +123 -0
- package/dist/storage/quota/UsageRepository.d.ts +41 -8
- package/dist/storage/quota/UsageRepository.js +252 -50
- package/dist/storage/quota/UsageRepository.js.map +1 -1
- package/dist/storage/sparql/ComunicaQuintEngine.d.ts +9 -0
- package/dist/storage/sparql/ComunicaQuintEngine.js +50 -9
- package/dist/storage/sparql/ComunicaQuintEngine.js.map +1 -1
- package/dist/storage/sparql/QueryOptimizer.js +13 -1
- package/dist/storage/sparql/QueryOptimizer.js.map +1 -1
- package/dist/storage/sparql/QuintQuerySource.d.ts +14 -0
- package/dist/storage/sparql/QuintQuerySource.js +152 -1
- package/dist/storage/sparql/QuintQuerySource.js.map +1 -1
- package/dist/storage/sparql/SubgraphQueryEngine.d.ts +1 -0
- package/dist/storage/sparql/SubgraphQueryEngine.js +6 -2
- package/dist/storage/sparql/SubgraphQueryEngine.js.map +1 -1
- package/dist/storage/sparql/SubgraphQueryEngine.jsonld +4 -0
- package/dist/subdomain/SubdomainClient.d.ts +3 -3
- package/dist/subdomain/SubdomainClient.js +1 -1
- package/dist/subdomain/SubdomainClient.js.map +1 -1
- package/dist/subdomain/SubdomainService.d.ts +15 -16
- package/dist/subdomain/SubdomainService.js +80 -54
- package/dist/subdomain/SubdomainService.js.map +1 -1
- package/dist/subdomain/SubdomainService.jsonld +22 -26
- package/dist/supervisor/Supervisor.d.ts +7 -2
- package/dist/supervisor/Supervisor.js +33 -1
- package/dist/supervisor/Supervisor.js.map +1 -1
- package/dist/task/DrizzleTaskQueue.d.ts +1 -1
- package/dist/task/DrizzleTaskQueue.js +1 -1
- package/dist/task/DrizzleTaskQueue.js.map +1 -1
- package/dist/task/schema.d.ts +10 -10
- package/dist/task/schema.js +1 -1
- package/dist/task/schema.js.map +1 -1
- package/dist/test-utils/index.d.ts +4 -0
- package/dist/test-utils/index.js +8 -0
- package/dist/test-utils/index.js.map +1 -0
- package/dist/test-utils/no-auth-xpod.d.ts +11 -0
- package/dist/test-utils/no-auth-xpod.js +25 -0
- package/dist/test-utils/no-auth-xpod.js.map +1 -0
- package/dist/test-utils/seed-pod.d.ts +5 -0
- package/dist/test-utils/seed-pod.js +61 -0
- package/dist/test-utils/seed-pod.js.map +1 -0
- package/package.json +38 -10
- package/templates/identity/account/create-pod.html.ejs +110 -0
- package/templates/main.html.ejs +10 -0
- package/dist/api/handlers/DevHandler.d.ts +0 -18
- package/dist/api/handlers/DevHandler.js +0 -276
- package/dist/api/handlers/DevHandler.js.map +0 -1
- package/dist/api/handlers/SignalHandler.d.ts +0 -13
- package/dist/api/handlers/SignalHandler.js +0 -122
- package/dist/api/handlers/SignalHandler.js.map +0 -1
- package/dist/gateway/Proxy.d.ts +0 -24
- package/dist/gateway/Proxy.js +0 -209
- package/dist/gateway/Proxy.js.map +0 -1
- package/dist/gateway/Supervisor.d.ts +0 -2
- package/dist/gateway/Supervisor.js +0 -7
- package/dist/gateway/Supervisor.js.map +0 -1
- package/dist/gateway/port-finder.d.ts +0 -4
- package/dist/gateway/port-finder.js +0 -15
- package/dist/gateway/port-finder.js.map +0 -1
- package/dist/gateway/types.d.ts +0 -1
- package/dist/gateway/types.js +0 -3
- package/dist/gateway/types.js.map +0 -1
- package/dist/http/SignalInterceptHttpHandler.d.ts +0 -24
- package/dist/http/SignalInterceptHttpHandler.js +0 -47
- package/dist/http/SignalInterceptHttpHandler.js.map +0 -1
- package/dist/http/SignalInterceptHttpHandler.jsonld +0 -103
- package/dist/http/admin/EdgeNodeSignalHttpHandler.d.ts +0 -71
- package/dist/http/admin/EdgeNodeSignalHttpHandler.js +0 -674
- package/dist/http/admin/EdgeNodeSignalHttpHandler.js.map +0 -1
- package/dist/http/admin/EdgeNodeSignalHttpHandler.jsonld +0 -406
- package/dist/http/cluster/PodMigrationHttpHandler.jsonld +0 -169
- package/dist/quota/DefaultQuotaService.d.ts +0 -16
- package/dist/quota/DefaultQuotaService.js +0 -37
- package/dist/quota/DefaultQuotaService.js.map +0 -1
- package/dist/quota/DefaultQuotaService.jsonld +0 -85
- package/dist/service/EdgeNodeHeartbeatService.js.map +0 -1
- package/dist/service/PodMigrationService.jsonld +0 -76
- package/dist/storage/MigratableDataAccessor.d.ts +0 -63
- package/dist/storage/MigratableDataAccessor.js +0 -11
- package/dist/storage/MigratableDataAccessor.js.map +0 -1
- package/dist/storage/MigratableDataAccessor.jsonld +0 -60
- package/dist/storage/accessors/TieredMinioDataAccessor.d.ts +0 -150
- package/dist/storage/accessors/TieredMinioDataAccessor.js +0 -582
- package/dist/storage/accessors/TieredMinioDataAccessor.js.map +0 -1
- package/dist/storage/accessors/TieredMinioDataAccessor.jsonld +0 -333
- package/static/app/assets/index.css +0 -1
- package/static/app/assets/main.js +0 -11
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.PodChatKitStore = void 0;
|
|
16
|
-
const
|
|
17
|
-
const drizzle_solid_1 = require("drizzle-solid");
|
|
16
|
+
const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
|
|
18
17
|
const global_logger_factory_1 = require("global-logger-factory");
|
|
19
18
|
const types_1 = require("./types");
|
|
20
19
|
const schema_1 = require("./schema");
|
|
@@ -55,6 +54,7 @@ class PodChatKitStore {
|
|
|
55
54
|
async getDb(context) {
|
|
56
55
|
// Check if we already have a cached db in context
|
|
57
56
|
if (context._cachedDb) {
|
|
57
|
+
this.logger.debug('Using cached db from context');
|
|
58
58
|
return context._cachedDb;
|
|
59
59
|
}
|
|
60
60
|
const auth = context.auth;
|
|
@@ -68,6 +68,7 @@ class PodChatKitStore {
|
|
|
68
68
|
if (auth.tokenType === 'DPoP') {
|
|
69
69
|
this.logger.warn('Using DPoP access token without proof key; Pod access may fail if issuer enforces DPoP proof');
|
|
70
70
|
}
|
|
71
|
+
this.logger.info(`[getDb] Using access token path for webId: ${auth.webId}`);
|
|
71
72
|
const authFetch = this.createAccessTokenFetch(auth.accessToken, auth.tokenType);
|
|
72
73
|
const db = (0, drizzle_solid_1.drizzle)({ fetch: authFetch, info: { webId: auth.webId, isLoggedIn: true } }, { schema });
|
|
73
74
|
this.logger.info(`Initializing tables for Pod (access token): ${auth.webId}`);
|
|
@@ -92,34 +93,30 @@ class PodChatKitStore {
|
|
|
92
93
|
this.logger.warn('No accessToken and no valid client credentials in context, cannot access Pod');
|
|
93
94
|
return null;
|
|
94
95
|
}
|
|
95
|
-
// Fallback path:
|
|
96
|
-
|
|
96
|
+
// Fallback path: exchange client credentials for an access token directly.
|
|
97
|
+
this.logger.info(`[getDb] Using client credentials path for clientId: ${auth.clientId}`);
|
|
97
98
|
try {
|
|
98
|
-
await
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
tokenType: 'DPoP',
|
|
103
|
-
});
|
|
104
|
-
if (!session.info.isLoggedIn || !session.info.webId) {
|
|
105
|
-
throw new Error('Login failed');
|
|
99
|
+
const token = await this.getClientCredentialsAccessToken(auth.clientId, auth.clientSecret);
|
|
100
|
+
const webId = auth.webId ?? this.getWebId(context);
|
|
101
|
+
if (!webId) {
|
|
102
|
+
throw new Error('Missing webId for client credentials auth');
|
|
106
103
|
}
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
this.logger.info(`Initializing tables for Pod: ${
|
|
104
|
+
this.logger.info(`[getDb] Client credentials token acquired, webId: ${webId}`);
|
|
105
|
+
const authFetch = this.createAccessTokenFetch(token.accessToken, token.tokenType);
|
|
106
|
+
const db = (0, drizzle_solid_1.drizzle)({ fetch: authFetch, info: { webId, isLoggedIn: true } }, { schema });
|
|
107
|
+
this.logger.info(`Initializing tables for Pod: ${webId}`);
|
|
111
108
|
try {
|
|
112
109
|
await db.init([schema_1.Chat, schema_1.Thread, schema_1.Message]);
|
|
113
110
|
this.logger.info('Tables initialized successfully');
|
|
114
111
|
}
|
|
115
112
|
catch (initError) {
|
|
116
113
|
this.logger.error(`Failed to init tables: ${initError}`);
|
|
117
|
-
// 继续执行,可能容器已存在
|
|
118
114
|
}
|
|
119
|
-
// Cache both db and session.fetch in context for reuse
|
|
120
115
|
context._cachedDb = db;
|
|
121
116
|
context._cachedFetch = authFetch;
|
|
122
|
-
context._cachedWebId =
|
|
117
|
+
context._cachedWebId = webId;
|
|
118
|
+
context._cachedAccessToken = token.accessToken;
|
|
119
|
+
context._cachedTokenType = token.tokenType;
|
|
123
120
|
return db;
|
|
124
121
|
}
|
|
125
122
|
catch (error) {
|
|
@@ -127,6 +124,30 @@ class PodChatKitStore {
|
|
|
127
124
|
return null;
|
|
128
125
|
}
|
|
129
126
|
}
|
|
127
|
+
async getClientCredentialsAccessToken(clientId, clientSecret) {
|
|
128
|
+
const response = await fetch(this.tokenEndpoint, {
|
|
129
|
+
method: 'POST',
|
|
130
|
+
headers: {
|
|
131
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
132
|
+
},
|
|
133
|
+
body: new URLSearchParams({
|
|
134
|
+
grant_type: 'client_credentials',
|
|
135
|
+
client_id: clientId,
|
|
136
|
+
client_secret: clientSecret,
|
|
137
|
+
}),
|
|
138
|
+
});
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
throw new Error(`Client credentials token request failed: ${response.status} ${await response.text().catch(() => '')}`);
|
|
141
|
+
}
|
|
142
|
+
const token = await response.json();
|
|
143
|
+
if (!token.access_token) {
|
|
144
|
+
throw new Error(`Client credentials token response missing access_token: ${JSON.stringify(token)}`);
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
accessToken: token.access_token,
|
|
148
|
+
tokenType: token.token_type?.toUpperCase() === 'DPOP' ? 'DPoP' : 'Bearer',
|
|
149
|
+
};
|
|
150
|
+
}
|
|
130
151
|
createAccessTokenFetch(accessToken, tokenType) {
|
|
131
152
|
const scheme = tokenType ?? 'Bearer';
|
|
132
153
|
return async (input, init) => {
|
|
@@ -273,6 +294,42 @@ class PodChatKitStore {
|
|
|
273
294
|
}
|
|
274
295
|
return chatIdOrUri;
|
|
275
296
|
}
|
|
297
|
+
extractThreadId(threadIdOrUri) {
|
|
298
|
+
if (!threadIdOrUri)
|
|
299
|
+
return undefined;
|
|
300
|
+
if (threadIdOrUri.includes('#')) {
|
|
301
|
+
return threadIdOrUri.split('#').pop() || undefined;
|
|
302
|
+
}
|
|
303
|
+
return threadIdOrUri;
|
|
304
|
+
}
|
|
305
|
+
getPodBaseUrl(context) {
|
|
306
|
+
const cachedWebId = context._cachedWebId;
|
|
307
|
+
const webId = cachedWebId ?? this.getWebId(context);
|
|
308
|
+
if (!webId) {
|
|
309
|
+
throw new Error('Missing webId for Pod URI resolution');
|
|
310
|
+
}
|
|
311
|
+
return webId.replace('/profile/card#me', '').replace(/\/$/, '');
|
|
312
|
+
}
|
|
313
|
+
buildThreadUri(chatId, threadId, context) {
|
|
314
|
+
return `${this.getPodBaseUrl(context)}/.data/chat/${chatId}/index.ttl#${threadId}`;
|
|
315
|
+
}
|
|
316
|
+
async selectMessagesForThread(threadId, context) {
|
|
317
|
+
const db = await this.getDb(context);
|
|
318
|
+
if (!db) {
|
|
319
|
+
throw new Error('Cannot access Pod: invalid credentials');
|
|
320
|
+
}
|
|
321
|
+
const chatId = await this.getThreadChatId(threadId, context);
|
|
322
|
+
const messages = await db.select().from(schema_1.Message);
|
|
323
|
+
return messages.filter((message) => this.extractChatId(message.chatId) === chatId && this.extractThreadId(message.threadId) === threadId);
|
|
324
|
+
}
|
|
325
|
+
async deleteMessageRecord(db, message) {
|
|
326
|
+
const messageIri = message['@id'];
|
|
327
|
+
if (messageIri) {
|
|
328
|
+
await db.delete(schema_1.Message).whereByIri(messageIri);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
await db.delete(schema_1.Message).where((0, drizzle_solid_1.and)((0, drizzle_solid_1.eq)(schema_1.Message.id, message.id), (0, drizzle_solid_1.eq)(schema_1.Message.chatId, this.extractChatId(message.chatId)), (0, drizzle_solid_1.eq)(schema_1.Message.createdAt, message.createdAt)));
|
|
332
|
+
}
|
|
276
333
|
/**
|
|
277
334
|
* 获取 Thread 的 chatId
|
|
278
335
|
* 先从缓存获取,如果没有再查询数据库
|
|
@@ -471,7 +528,10 @@ class PodChatKitStore {
|
|
|
471
528
|
}
|
|
472
529
|
// 删除关联到此 Thread 的消息
|
|
473
530
|
try {
|
|
474
|
-
await
|
|
531
|
+
const messages = await this.selectMessagesForThread(threadId, context);
|
|
532
|
+
for (const message of messages) {
|
|
533
|
+
await this.deleteMessageRecord(db, message);
|
|
534
|
+
}
|
|
475
535
|
}
|
|
476
536
|
catch (err) {
|
|
477
537
|
if (!err.message?.includes('404') && !err.message?.includes('Could not retrieve') && !err.message?.includes('Parse error')) {
|
|
@@ -481,7 +541,13 @@ class PodChatKitStore {
|
|
|
481
541
|
}
|
|
482
542
|
// 删除 Thread
|
|
483
543
|
try {
|
|
484
|
-
|
|
544
|
+
if (chatId) {
|
|
545
|
+
await db.delete(schema_1.Thread).where((0, drizzle_solid_1.and)((0, drizzle_solid_1.eq)(schema_1.Thread.id, threadId), (0, drizzle_solid_1.eq)(schema_1.Thread.chatId, chatId)));
|
|
546
|
+
}
|
|
547
|
+
else {
|
|
548
|
+
// 如果没有 chatId,尝试只用 id 删除(可能失败)
|
|
549
|
+
await db.delete(schema_1.Thread).where((0, drizzle_solid_1.eq)(schema_1.Thread.id, threadId));
|
|
550
|
+
}
|
|
485
551
|
}
|
|
486
552
|
catch (err) {
|
|
487
553
|
if (!err.message?.includes('404') && !err.message?.includes('Could not retrieve') && !err.message?.includes('Parse error')) {
|
|
@@ -499,13 +565,8 @@ class PodChatKitStore {
|
|
|
499
565
|
// Thread Item Operations (ChatKit items = our Messages)
|
|
500
566
|
// =========================================================================
|
|
501
567
|
async loadThreadItems(threadId, after, limit, order, context) {
|
|
502
|
-
const db = await this.getDb(context);
|
|
503
|
-
if (!db) {
|
|
504
|
-
return { data: [], has_more: false };
|
|
505
|
-
}
|
|
506
568
|
try {
|
|
507
|
-
|
|
508
|
-
const messages = await db.select().from(schema_1.Message).where((0, drizzle_solid_1.eq)(schema_1.Message.threadId, threadId));
|
|
569
|
+
const messages = await this.selectMessagesForThread(threadId, context);
|
|
509
570
|
// 排序
|
|
510
571
|
messages.sort((a, b) => {
|
|
511
572
|
const aTime = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
@@ -569,7 +630,7 @@ class PodChatKitStore {
|
|
|
569
630
|
const messageRecord = {
|
|
570
631
|
id: item.id,
|
|
571
632
|
chatId, // 用于路径构建
|
|
572
|
-
threadId, // 关联到 Thread
|
|
633
|
+
threadId: this.buildThreadUri(chatId, threadId, context), // 关联到 Thread
|
|
573
634
|
maker: role === schema_1.MessageRole.USER ? webId : null,
|
|
574
635
|
role,
|
|
575
636
|
content,
|
|
@@ -641,9 +702,14 @@ class PodChatKitStore {
|
|
|
641
702
|
throw new Error('No cached session for direct PATCH - call getDb first');
|
|
642
703
|
}
|
|
643
704
|
// 构建资源 URL 和 subject URI
|
|
644
|
-
// Template: {chatId}/{
|
|
705
|
+
// Template: {chatId}/{yyyy}/{MM}/{dd}/messages.ttl#{id}
|
|
706
|
+
// 使用 createdAt 时间来计算日期,与 drizzle-solid 的模板填充逻辑保持一致
|
|
707
|
+
const dateForPath = createdAt ? new Date(createdAt) : new Date();
|
|
708
|
+
const yyyy = dateForPath.getUTCFullYear();
|
|
709
|
+
const mm = String(dateForPath.getUTCMonth() + 1).padStart(2, '0');
|
|
710
|
+
const dd = String(dateForPath.getUTCDate()).padStart(2, '0');
|
|
645
711
|
const podBaseUrl = cachedWebId.replace('/profile/card#me', '');
|
|
646
|
-
const resourceUrl = `${podBaseUrl}/.data/chat/${chatId}/${
|
|
712
|
+
const resourceUrl = `${podBaseUrl}/.data/chat/${chatId}/${yyyy}/${mm}/${dd}/messages.ttl`;
|
|
647
713
|
const subjectUri = `${resourceUrl}#${messageId}`;
|
|
648
714
|
// 构建 SPARQL UPDATE:删除旧值,插入新值
|
|
649
715
|
const deletePatterns = [];
|
|
@@ -691,11 +757,7 @@ WHERE { ${deletePatterns.join(' ')} }
|
|
|
691
757
|
}
|
|
692
758
|
}
|
|
693
759
|
async loadItem(threadId, itemId, context) {
|
|
694
|
-
const
|
|
695
|
-
if (!db) {
|
|
696
|
-
throw new Error('Cannot access Pod: invalid credentials');
|
|
697
|
-
}
|
|
698
|
-
const messages = await db.select().from(schema_1.Message).where((0, drizzle_solid_1.and)((0, drizzle_solid_1.eq)(schema_1.Message.id, itemId), (0, drizzle_solid_1.eq)(schema_1.Message.threadId, threadId)));
|
|
760
|
+
const messages = (await this.selectMessagesForThread(threadId, context)).filter((message) => message.id === itemId);
|
|
699
761
|
if (messages.length === 0) {
|
|
700
762
|
throw new Error(`Item not found: ${itemId}`);
|
|
701
763
|
}
|
|
@@ -706,7 +768,12 @@ WHERE { ${deletePatterns.join(' ')} }
|
|
|
706
768
|
if (!db) {
|
|
707
769
|
throw new Error('Cannot access Pod: invalid credentials');
|
|
708
770
|
}
|
|
709
|
-
|
|
771
|
+
const messages = await this.selectMessagesForThread(threadId, context);
|
|
772
|
+
const target = messages.find((message) => message.id === itemId);
|
|
773
|
+
if (!target) {
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
await this.deleteMessageRecord(db, target);
|
|
710
777
|
}
|
|
711
778
|
// =========================================================================
|
|
712
779
|
// Attachment Operations (存 Pod 文件)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pod-store.js","sourceRoot":"","sources":["../../../src/api/chatkit/pod-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pod-based ChatKit Store\n *\n * 将 ChatKit 数据存储到 Solid Pod。\n *\n * 存储结构:\n * /.data/chat/{chatId}/\n * index.ttl\n * #this # Chat (meeting:LongChat)\n * #{threadId} # Thread (sioc:Thread)\n * {yyyy}/{MM}/{dd}/messages.ttl # Messages (meeting:Message)\n */\n\nimport { Session } from '@inrupt/solid-client-authn-node';\nimport { drizzle, eq, and } from 'drizzle-solid';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { ChatKitStore, StoreContext } from './store';\nimport type {\n ThreadMetadata,\n ThreadItem,\n Attachment,\n Page,\n StoreItemType,\n UserMessageItem,\n AssistantMessageItem,\n ThreadStatus,\n} from './types';\nimport { generateId, nowTimestamp } from './types';\nimport {\n Chat,\n Thread,\n Message,\n MessageRole,\n MessageStatus,\n type ChatRecord,\n type ThreadRecord,\n type MessageRecord,\n} from './schema';\nimport type { AuthContext } from '../auth/AuthContext';\nimport { isSolidAuth } from '../auth/AuthContext';\nimport { Provider } from '../../ai/schema/provider';\nimport { Credential } from '../../credential/schema/tables';\nimport { ServiceType, CredentialStatus } from '../../credential/schema/types';\n\nconst schema = {\n chat: Chat,\n thread: Thread,\n message: Message,\n provider: Provider,\n credential: Credential,\n};\n\nexport interface PodChatKitStoreOptions {\n tokenEndpoint: string;\n}\n\n/**\n * Pod-based ChatKit Store implementation\n *\n * 数据模型映射:\n * - ChatKit thread = Thread (sioc:Thread)\n * - ChatKit thread item = Message (meeting:Message)\n * - Chat (meeting:LongChat) 是容器/Agent,通过 metadata.chat_id 暴露\n *\n * 每个 Thread 属于一个 Chat 容器。默认使用 'default' Chat。\n */\nexport class PodChatKitStore implements ChatKitStore<StoreContext> {\n private readonly logger = getLoggerFor(this);\n private readonly tokenEndpoint: string;\n\n /** 默认 Chat 容器 ID */\n private static readonly DEFAULT_CHAT_ID = 'default';\n\n public constructor(options: PodChatKitStoreOptions) {\n this.tokenEndpoint = options.tokenEndpoint;\n }\n\n // =========================================================================\n // Private Helpers\n // =========================================================================\n\n /**\n * 获取认证后的 drizzle 实例 (缓存到 context 中)\n */\n private async getDb(context: StoreContext) {\n // Check if we already have a cached db in context\n if ((context as any)._cachedDb) {\n return (context as any)._cachedDb;\n }\n\n const auth = context.auth as AuthContext | undefined;\n\n if (!auth || !isSolidAuth(auth)) {\n this.logger.warn('No valid solid auth in context, cannot access Pod');\n return null;\n }\n\n // Preferred path: directly use caller's Solid access token.\n if (auth.accessToken && auth.webId) {\n try {\n if (auth.tokenType === 'DPoP') {\n this.logger.warn('Using DPoP access token without proof key; Pod access may fail if issuer enforces DPoP proof');\n }\n\n const authFetch = this.createAccessTokenFetch(auth.accessToken, auth.tokenType);\n const db = drizzle(\n { fetch: authFetch, info: { webId: auth.webId, isLoggedIn: true } } as any,\n { schema },\n );\n\n this.logger.info(`Initializing tables for Pod (access token): ${auth.webId}`);\n try {\n await db.init([Chat, Thread, Message]);\n this.logger.info('Tables initialized successfully');\n } catch (initError) {\n this.logger.error(`Failed to init tables: ${initError}`);\n }\n\n (context as any)._cachedDb = db;\n (context as any)._cachedFetch = authFetch;\n (context as any)._cachedWebId = auth.webId;\n return db;\n } catch (error) {\n this.logger.error(`Failed to get Pod db with access token: ${error}`);\n return null;\n }\n }\n\n if (!auth.clientId || !auth.clientSecret) {\n this.logger.warn('No accessToken and no valid client credentials in context, cannot access Pod');\n return null;\n }\n\n // Fallback path: login with client credentials to obtain a Pod session.\n const session = new Session();\n try {\n await session.login({\n oidcIssuer: new URL(this.tokenEndpoint).origin,\n clientId: auth.clientId,\n clientSecret: auth.clientSecret,\n tokenType: 'DPoP',\n });\n\n if (!session.info.isLoggedIn || !session.info.webId) {\n throw new Error('Login failed');\n }\n\n const authFetch = session.fetch.bind(session) as typeof fetch;\n const db = drizzle(\n { fetch: authFetch, info: { webId: session.info.webId, isLoggedIn: true } } as any,\n { schema },\n );\n\n\n // 初始化表(创建容器、资源)\n this.logger.info(`Initializing tables for Pod: ${session.info.webId}`);\n try {\n await db.init([Chat, Thread, Message]);\n this.logger.info('Tables initialized successfully');\n } catch (initError) {\n this.logger.error(`Failed to init tables: ${initError}`);\n // 继续执行,可能容器已存在\n }\n\n // Cache both db and session.fetch in context for reuse\n (context as any)._cachedDb = db;\n (context as any)._cachedFetch = authFetch;\n (context as any)._cachedWebId = session.info.webId;\n\n return db;\n } catch (error) {\n this.logger.error(`Failed to get Pod db: ${error}`);\n return null;\n }\n }\n\n private createAccessTokenFetch(accessToken: string, tokenType?: 'Bearer' | 'DPoP'): typeof fetch {\n const scheme = tokenType ?? 'Bearer';\n return async (\n input: Parameters<typeof fetch>[0],\n init?: Parameters<typeof fetch>[1],\n ): Promise<Response> => {\n const headers = new Headers(init?.headers);\n if (!headers.has('Authorization')) {\n headers.set('Authorization', `${scheme} ${accessToken}`);\n }\n return fetch(input, {\n ...init,\n headers,\n });\n };\n }\n\n /**\n * 从 context 获取 webId\n */\n private getWebId(context: StoreContext): string | undefined {\n const auth = context.auth as AuthContext | undefined;\n if (auth && isSolidAuth(auth)) {\n return auth.webId;\n }\n return undefined;\n }\n\n /**\n * 将 ThreadStatus 对象转为字符串\n */\n private statusToString(status: ThreadStatus): string {\n return status.type;\n }\n\n /**\n * 将字符串转为 ThreadStatus 对象\n */\n private stringToStatus(status: string | null | undefined): ThreadStatus {\n switch (status) {\n case 'locked':\n return { type: 'locked' };\n case 'closed':\n return { type: 'closed' };\n default:\n return { type: 'active' };\n }\n }\n\n /**\n * 从 ThreadMetadata.metadata 中获取 chat_id,如果没有则返回默认值\n */\n private getChatIdFromMetadata(metadata?: Record<string, unknown>): string {\n if (metadata && typeof metadata.chat_id === 'string') {\n return metadata.chat_id;\n }\n return PodChatKitStore.DEFAULT_CHAT_ID;\n }\n\n /**\n * 确保 Chat 容器存在,如果不存在则创建\n */\n private async ensureChat(chatId: string, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const webId = this.getWebId(context);\n\n // 检查是否存在\n const existing = await db.query.chat.findFirst({\n where: eq(Chat.id, chatId),\n });\n\n if (!existing) {\n // 创建 Chat 容器\n const now = new Date().toISOString();\n await db.insert(Chat).values({\n id: chatId,\n title: chatId === PodChatKitStore.DEFAULT_CHAT_ID ? 'Default Chat' : chatId,\n author: webId || null,\n status: 'active',\n createdAt: now,\n updatedAt: now,\n });\n this.logger.info(`Created Chat container: ${chatId}`);\n }\n }\n\n /**\n * 将 ThreadRecord 转为 ThreadMetadata\n * 包含 metadata.chat_id 暴露 Chat 容器 ID\n */\n private threadRecordToMetadata(record: ThreadRecord): ThreadMetadata {\n const chatId = this.extractChatId(record.chatId);\n let extra: Record<string, unknown> | undefined;\n if (record.metadata) {\n try {\n extra = JSON.parse(record.metadata) as Record<string, unknown>;\n } catch {\n // ignore invalid metadata\n }\n }\n\n return {\n id: record.id,\n title: record.title || undefined,\n status: this.stringToStatus(record.status),\n created_at: record.createdAt ? Math.floor(new Date(record.createdAt).getTime() / 1000) : nowTimestamp(),\n updated_at: record.updatedAt ? Math.floor(new Date(record.updatedAt).getTime() / 1000) : nowTimestamp(),\n metadata: {\n chat_id: chatId,\n ...(extra ?? {}),\n },\n };\n }\n\n /**\n * 将 MessageRecord 转为 ThreadItem\n * thread_id 返回 Message 所属的 Thread ID\n */\n private messageRecordToItem(record: MessageRecord, threadId: string): ThreadItem {\n const createdAt = record.createdAt ? Math.floor(new Date(record.createdAt).getTime() / 1000) : nowTimestamp();\n\n if (record.role === MessageRole.USER) {\n return {\n id: record.id,\n thread_id: threadId,\n type: 'user_message',\n content: [{ type: 'input_text', text: record.content || '' }],\n created_at: createdAt,\n } as UserMessageItem;\n } else {\n return {\n id: record.id,\n thread_id: threadId,\n type: 'assistant_message',\n content: [{ type: 'output_text', text: record.content || '' }],\n status: (record.status as 'in_progress' | 'completed' | 'incomplete') || 'completed',\n created_at: createdAt,\n } as AssistantMessageItem;\n }\n }\n\n /**\n * 从 Thread 获取 chatId(提取纯 ID)\n */\n private extractChatId(chatIdOrUri: string | null | undefined): string {\n if (!chatIdOrUri) return PodChatKitStore.DEFAULT_CHAT_ID;\n\n if (chatIdOrUri.includes('#')) {\n // 从 URI 中提取,如 http://.../.data/chat/default/index.ttl#this -> default\n const match = chatIdOrUri.match(/\\.data\\/chat\\/([^/]+)\\/index\\.ttl#this/);\n if (match) {\n return match[1];\n }\n }\n return chatIdOrUri;\n }\n\n /**\n * 获取 Thread 的 chatId\n * 先从缓存获取,如果没有再查询数据库\n */\n private async getThreadChatId(threadId: string, context: StoreContext): Promise<string> {\n // 先检查缓存\n const cached = this.getCachedThreadChatId(context, threadId);\n if (cached) {\n return cached;\n }\n\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const thread = await db.query.thread.findFirst({\n where: eq(Thread.id, threadId),\n });\n\n if (!thread) {\n // 如果找不到 Thread,返回默认 chatId\n this.logger.warn(`Thread not found in DB, using default chatId: ${threadId}`);\n return PodChatKitStore.DEFAULT_CHAT_ID;\n }\n\n const chatId = this.extractChatId(thread.chatId);\n // 缓存结果\n this.cacheThreadChatId(context, threadId, chatId);\n return chatId;\n }\n\n /**\n * 缓存 Thread -> chatId 映射\n */\n private cacheThreadChatId(context: StoreContext, threadId: string, chatId: string): void {\n if (!(context as any)._threadChatIdCache) {\n (context as any)._threadChatIdCache = new Map<string, string>();\n }\n (context as any)._threadChatIdCache.set(threadId, chatId);\n }\n\n /**\n * 从缓存获取 Thread 的 chatId\n */\n private getCachedThreadChatId(context: StoreContext, threadId: string): string | undefined {\n const cache = (context as any)._threadChatIdCache as Map<string, string> | undefined;\n return cache?.get(threadId);\n }\n\n /**\n * 缓存完整的 Thread metadata\n */\n private cacheThreadMetadata(context: StoreContext, thread: ThreadMetadata): void {\n if (!(context as any)._threadMetadataCache) {\n (context as any)._threadMetadataCache = new Map<string, ThreadMetadata>();\n }\n (context as any)._threadMetadataCache.set(thread.id, thread);\n }\n\n /**\n * 从缓存获取 Thread metadata\n */\n private getCachedThreadMetadata(context: StoreContext, threadId: string): ThreadMetadata | undefined {\n const cache = (context as any)._threadMetadataCache as Map<string, ThreadMetadata> | undefined;\n return cache?.get(threadId);\n }\n\n // =========================================================================\n // ID Generation\n // =========================================================================\n\n generateThreadId(_context: StoreContext): string {\n return generateId('thread');\n }\n\n generateItemId(itemType: StoreItemType, _thread: ThreadMetadata, _context: StoreContext): string {\n return generateId(itemType.replace('_', '-'));\n }\n\n // =========================================================================\n // Thread Operations (ChatKit thread = our Thread)\n // =========================================================================\n\n async loadThread(threadId: string, context: StoreContext): Promise<ThreadMetadata> {\n // 先从缓存获取\n const cached = this.getCachedThreadMetadata(context, threadId);\n if (cached) {\n return cached;\n }\n\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const thread = await db.query.thread.findFirst({\n where: eq(Thread.id, threadId),\n });\n\n if (!thread) {\n throw new Error(`Thread not found: ${threadId}`);\n }\n\n const metadata = this.threadRecordToMetadata(thread);\n // 缓存结果\n this.cacheThreadMetadata(context, metadata);\n return metadata;\n }\n\n async saveThread(thread: ThreadMetadata, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const now = new Date().toISOString();\n\n // 从 metadata 获取 chat_id\n const chatId = this.getChatIdFromMetadata(thread.metadata);\n // Persist all metadata except chat_id (which is derived from storage location).\n const metadataToPersist = { ...(thread.metadata ?? {}) } as Record<string, unknown>;\n delete (metadataToPersist as any).chat_id;\n const metadataJson = Object.keys(metadataToPersist).length > 0 ? JSON.stringify(metadataToPersist) : null;\n\n // 确保 Chat 容器存在\n await this.ensureChat(chatId, context);\n\n // 缓存 Thread -> chatId 映射,避免后续查询\n this.cacheThreadChatId(context, thread.id, chatId);\n\n // 检查 Thread 是否存在\n const existing = await db.query.thread.findFirst({\n where: eq(Thread.id, thread.id),\n });\n\n if (existing) {\n // Update\n await db.update(Thread).set({\n title: thread.title || null,\n status: this.statusToString(thread.status),\n metadata: metadataJson,\n updatedAt: now,\n }).where(eq(Thread.id, thread.id));\n } else {\n // Insert\n await db.insert(Thread).values({\n id: thread.id,\n chatId, // 关联到 Chat 容器\n title: thread.title || null,\n status: this.statusToString(thread.status),\n metadata: metadataJson,\n createdAt: new Date(thread.created_at * 1000).toISOString(),\n updatedAt: now,\n });\n }\n\n // 缓存完整的 Thread metadata,确保 metadata.chat_id 包含正确的值\n const threadMetadata: ThreadMetadata = {\n ...thread,\n metadata: { ...(thread.metadata ?? {}), chat_id: chatId },\n };\n this.cacheThreadMetadata(context, threadMetadata);\n }\n\n async loadThreads(\n limit: number,\n after: string | undefined,\n order: string,\n context: StoreContext,\n ): Promise<Page<ThreadMetadata>> {\n const db = await this.getDb(context);\n if (!db) {\n return { data: [], has_more: false };\n }\n\n try {\n const threads = await db.select().from(Thread) as ThreadRecord[];\n\n // 排序\n threads.sort((a: ThreadRecord, b: ThreadRecord) => {\n const aTime = a.createdAt ? new Date(a.createdAt).getTime() : 0;\n const bTime = b.createdAt ? new Date(b.createdAt).getTime() : 0;\n return order === 'desc' ? bTime - aTime : aTime - bTime;\n });\n\n // 分页\n let startIndex = 0;\n if (after) {\n const afterIndex = threads.findIndex((t: ThreadRecord) => t.id === after);\n if (afterIndex !== -1) {\n startIndex = afterIndex + 1;\n }\n }\n\n const slice = threads.slice(startIndex, startIndex + limit);\n const hasMore = startIndex + limit < threads.length;\n\n return {\n data: slice.map((t: ThreadRecord) => this.threadRecordToMetadata(t)),\n has_more: hasMore,\n after: slice.length > 0 ? slice[slice.length - 1].id : undefined,\n };\n } catch (error) {\n this.logger.error(`Failed to load threads: ${error}`);\n return { data: [], has_more: false };\n }\n }\n\n async deleteThread(threadId: string, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n // 尝试从缓存获取 chatId\n let chatId = this.getCachedThreadChatId(context, threadId);\n\n // 如果缓存没有,尝试从数据库查询\n if (!chatId) {\n try {\n const thread = await db.query.thread.findFirst({\n where: eq(Thread.id, threadId),\n });\n if (thread) {\n chatId = this.extractChatId(thread.chatId);\n }\n } catch (err: any) {\n // 忽略查询错误,继续尝试删除\n this.logger.debug(`Ignoring thread query error during delete: ${err.message}`);\n }\n }\n\n // 删除关联到此 Thread 的消息\n try {\n await db.delete(Message).where(eq(Message.threadId, threadId));\n } catch (err: any) {\n if (!err.message?.includes('404') && !err.message?.includes('Could not retrieve') && !err.message?.includes('Parse error')) {\n throw err;\n }\n this.logger.debug(`Ignoring delete message error: ${err.message}`);\n }\n\n // 删除 Thread\n try {\n await db.delete(Thread).where(eq(Thread.id, threadId));\n } catch (err: any) {\n if (!err.message?.includes('404') && !err.message?.includes('Could not retrieve') && !err.message?.includes('Parse error')) {\n throw err;\n }\n this.logger.debug(`Ignoring delete thread error: ${err.message}`);\n }\n\n // 清除缓存\n const metadataCache = (context as any)._threadMetadataCache as Map<string, ThreadMetadata> | undefined;\n const chatIdCache = (context as any)._threadChatIdCache as Map<string, string> | undefined;\n metadataCache?.delete(threadId);\n chatIdCache?.delete(threadId);\n }\n\n // =========================================================================\n // Thread Item Operations (ChatKit items = our Messages)\n // =========================================================================\n\n async loadThreadItems(\n threadId: string,\n after: string | undefined,\n limit: number,\n order: string,\n context: StoreContext,\n ): Promise<Page<ThreadItem>> {\n const db = await this.getDb(context);\n if (!db) {\n return { data: [], has_more: false };\n }\n\n try {\n // 按 threadId 查询 Message\n const messages = await db.select().from(Message).where(\n eq(Message.threadId, threadId),\n ) as MessageRecord[];\n\n // 排序\n messages.sort((a: MessageRecord, b: MessageRecord) => {\n const aTime = a.createdAt ? new Date(a.createdAt).getTime() : 0;\n const bTime = b.createdAt ? new Date(b.createdAt).getTime() : 0;\n return order === 'desc' ? bTime - aTime : aTime - bTime;\n });\n\n // 分页\n let startIndex = 0;\n if (after) {\n const afterIndex = messages.findIndex((m: MessageRecord) => m.id === after);\n if (afterIndex !== -1) {\n startIndex = afterIndex + 1;\n }\n }\n\n const slice = messages.slice(startIndex, startIndex + limit);\n const hasMore = startIndex + limit < messages.length;\n\n return {\n data: slice.map((m: MessageRecord) => this.messageRecordToItem(m, threadId)),\n has_more: hasMore,\n after: slice.length > 0 ? slice[slice.length - 1].id : undefined,\n };\n } catch (error) {\n this.logger.error(`Failed to load thread items: ${error}`);\n return { data: [], has_more: false };\n }\n }\n\n async addThreadItem(threadId: string, item: ThreadItem, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n // 从 Thread 获取 chatId\n const chatId = await this.getThreadChatId(threadId, context);\n\n const webId = this.getWebId(context);\n let content = '';\n let role: string = MessageRole.USER;\n let status: string | null = null;\n\n if (item.type === 'user_message') {\n const userItem = item as UserMessageItem;\n content = userItem.content\n .filter((c) => c.type === 'input_text')\n .map((c) => (c as any).text)\n .join('\\n');\n role = MessageRole.USER;\n } else if (item.type === 'assistant_message') {\n const assistantItem = item as AssistantMessageItem;\n content = assistantItem.content\n .filter((c) => c.type === 'output_text')\n .map((c) => c.text)\n .join('\\n');\n role = MessageRole.ASSISTANT;\n status = assistantItem.status || MessageStatus.COMPLETED;\n } else {\n // 其他类型暂时存储为 JSON\n content = JSON.stringify(item);\n role = MessageRole.SYSTEM;\n }\n\n const messageRecord = {\n id: item.id,\n chatId, // 用于路径构建\n threadId, // 关联到 Thread\n maker: role === MessageRole.USER ? webId : null,\n role,\n content,\n status,\n createdAt: new Date(item.created_at * 1000).toISOString(),\n };\n\n await db.insert(Message).values(messageRecord);\n\n // Track this ID to avoid cache timing issues in saveItem\n this.recentlyCreatedIds.add(messageRecord.id);\n }\n\n // Track recently created message IDs to avoid SELECT cache timing issues\n private recentlyCreatedIds = new Set<string>();\n\n async saveItem(threadId: string, item: ThreadItem, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n // 从 Thread 获取 chatId(用于构建资源路径)\n const chatId = await this.getThreadChatId(threadId, context);\n\n // 准备更新数据\n let content = '';\n let status: string | null = null;\n\n if (item.type === 'user_message') {\n const userItem = item as UserMessageItem;\n content = userItem.content\n .filter((c) => c.type === 'input_text')\n .map((c) => (c as any).text)\n .join('\\n');\n } else if (item.type === 'assistant_message') {\n const assistantItem = item as AssistantMessageItem;\n content = assistantItem.content\n .filter((c) => c.type === 'output_text')\n .map((c) => c.text)\n .join('\\n');\n status = assistantItem.status || MessageStatus.COMPLETED;\n }\n\n // 获取 createdAt 用于计算资源路径(与 drizzle-solid 模板填充保持一致)\n const createdAt = item.created_at ? new Date(item.created_at * 1000).toISOString() : undefined;\n\n // 如果是最近创建的消息,使用直接 PATCH 更新(避免 drizzle-solid UPDATE 的 bug)\n const wasRecentlyCreated = this.recentlyCreatedIds.has(item.id);\n if (wasRecentlyCreated) {\n this.recentlyCreatedIds.delete(item.id);\n await this.directPatchMessage(context, chatId, item.id, content, status, createdAt);\n return;\n }\n\n // 对于非最近创建的消息,使用普通流程\n const existingItems = await db.select().from(Message).where(\n eq(Message.id, item.id),\n ) as MessageRecord[];\n const existing = existingItems.length > 0 ? existingItems[0] : null;\n\n if (existing) {\n // 使用直接 PATCH 更新\n const existingCreatedAt = existing.createdAt\n ? (existing.createdAt instanceof Date ? existing.createdAt.toISOString() : String(existing.createdAt))\n : undefined;\n await this.directPatchMessage(context, chatId, item.id, content, status, existingCreatedAt);\n } else {\n // Create new record\n await this.addThreadItem(threadId, item, context);\n }\n }\n\n /**\n * 直接使用 SPARQL UPDATE PATCH 更新消息内容\n * 避免 drizzle-solid UPDATE 的 bug\n */\n private async directPatchMessage(\n context: StoreContext,\n chatId: string,\n messageId: string,\n content: string,\n status: string | null,\n createdAt?: string\n ): Promise<void> {\n // 使用缓存的 fetch 和 webId(由 getDb 时创建的 session)\n const cachedFetch = (context as any)._cachedFetch as typeof fetch | undefined;\n const cachedWebId = (context as any)._cachedWebId as string | undefined;\n\n if (!cachedFetch || !cachedWebId) {\n throw new Error('No cached session for direct PATCH - call getDb first');\n }\n\n // 构建资源 URL 和 subject URI\n // Template: {chatId}/{id}.ttl#{id}\n const podBaseUrl = cachedWebId.replace('/profile/card#me', '');\n const resourceUrl = `${podBaseUrl}/.data/chat/${chatId}/${messageId}.ttl`;\n const subjectUri = `${resourceUrl}#${messageId}`;\n\n // 构建 SPARQL UPDATE:删除旧值,插入新值\n const deletePatterns: string[] = [];\n const insertTriples: string[] = [];\n\n // 转义特殊字符\n const escapeForSparql = (value: string): string => {\n const hasQuotes = value.includes('\"');\n const hasNewlines = value.includes('\\n') || value.includes('\\r');\n\n if (hasQuotes || hasNewlines) {\n // 使用三引号\n let escaped = value;\n escaped = escaped.replace(/\"\"\"/g, '\"\\\\\"\\\\\"\"');\n if (escaped.endsWith('\"')) {\n const match = escaped.match(/\"*$/);\n const trailingQuotes = match ? match[0].length : 0;\n if (trailingQuotes > 0) {\n escaped = escaped.slice(0, -trailingQuotes) + '\\\\\"'.repeat(trailingQuotes);\n }\n }\n return `\"\"\"${escaped}\"\"\"`;\n }\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n };\n\n // Content 更新\n deletePatterns.push(`<${subjectUri}> <http://rdfs.org/sioc/ns#content> ?oldContent .`);\n insertTriples.push(`<${subjectUri}> <http://rdfs.org/sioc/ns#content> ${escapeForSparql(content)} .`);\n\n // Status 更新\n if (status) {\n deletePatterns.push(`<${subjectUri}> <https://undefineds.co/ns#status> ?oldStatus .`);\n insertTriples.push(`<${subjectUri}> <https://undefineds.co/ns#status> \"${status}\" .`);\n }\n\n const sparql = `\nDELETE { ${deletePatterns.join(' ')} }\nINSERT { ${insertTriples.join(' ')} }\nWHERE { ${deletePatterns.join(' ')} }\n `.trim();\n\n const response = await cachedFetch(resourceUrl, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/sparql-update' },\n body: sparql,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`Direct PATCH failed: ${response.status} ${response.statusText} - ${text}`);\n }\n }\n\n async loadItem(threadId: string, itemId: string, context: StoreContext): Promise<ThreadItem> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const messages = await db.select().from(Message).where(\n and(\n eq(Message.id, itemId),\n eq(Message.threadId, threadId),\n ),\n ) as MessageRecord[];\n\n if (messages.length === 0) {\n throw new Error(`Item not found: ${itemId}`);\n }\n\n return this.messageRecordToItem(messages[0], threadId);\n }\n\n async deleteThreadItem(threadId: string, itemId: string, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n await db.delete(Message).where(\n and(\n eq(Message.id, itemId),\n eq(Message.threadId, threadId),\n ),\n );\n }\n\n // =========================================================================\n // Attachment Operations (存 Pod 文件)\n // =========================================================================\n\n async saveAttachment(attachment: Attachment, _context: StoreContext): Promise<void> {\n this.logger.info(`Attachment saved: ${attachment.id} (${attachment.name})`);\n }\n\n async loadAttachment(attachmentId: string, _context: StoreContext): Promise<Attachment> {\n throw new Error(`Attachment not found: ${attachmentId}`);\n }\n\n async deleteAttachment(attachmentId: string, _context: StoreContext): Promise<void> {\n this.logger.info(`Attachment deleted: ${attachmentId}`);\n }\n\n // =========================================================================\n // AI Config Operations (复用 Session 缓存)\n // =========================================================================\n\n /**\n * AI 配置结果\n */\n public static readonly AiConfigResult = class {\n providerId!: string;\n baseUrl!: string;\n proxyUrl?: string;\n apiKey!: string;\n credentialId!: string;\n };\n\n /**\n * 从 Pod 获取 AI 配置(Provider + Credential)\n * 复用已缓存的 Session,避免重复登录\n */\n async getAiConfig(context: StoreContext): Promise<{\n providerId: string;\n baseUrl: string;\n proxyUrl?: string;\n apiKey: string;\n credentialId: string;\n } | undefined> {\n const db = await this.getDb(context);\n if (!db) {\n return undefined;\n }\n\n try {\n // 查询活跃的 AI 凭据\n const credentials = await db.select()\n .from(Credential)\n .where(and(\n eq(Credential.service, ServiceType.AI),\n eq(Credential.status, CredentialStatus.ACTIVE),\n ));\n\n if (credentials.length === 0) {\n return undefined;\n }\n\n // 遍历凭据,找到有效的 Provider\n for (const cred of credentials) {\n if (!cred.provider) continue;\n\n // 从 URI 提取 provider ID\n const providerId = this.extractProviderId(cred.provider);\n\n // 查询 Provider\n const providers = await db.select()\n .from(Provider)\n .where(eq(Provider.id, providerId));\n\n const provider = providers[0];\n if (!provider) continue;\n\n const baseUrl = cred.baseUrl || provider.baseUrl;\n if (!baseUrl) continue;\n\n this.logger.debug(`Using credential ${cred.id} with provider ${provider.id}`);\n\n return {\n providerId: provider.id,\n baseUrl,\n proxyUrl: cred.proxyUrl || provider.proxyUrl || undefined,\n apiKey: cred.apiKey!,\n credentialId: cred.id,\n };\n }\n\n return undefined;\n } catch (error) {\n this.logger.warn(`Failed to read AI config from Pod: ${error}`);\n return undefined;\n }\n }\n\n /**\n * 更新凭据状态(如 429 限流)\n * 复用已缓存的 Session\n */\n async updateCredentialStatus(\n context: StoreContext,\n credentialId: string,\n status: CredentialStatus,\n options?: { rateLimitResetAt?: Date; incrementFailCount?: boolean },\n ): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n this.logger.debug('Cannot update credential status: no db available');\n return;\n }\n\n try {\n const updateData: Record<string, any> = { status };\n\n if (options?.rateLimitResetAt) {\n updateData.rateLimitResetAt = options.rateLimitResetAt;\n }\n\n // 如果需要递增 failCount,先查询当前值\n if (options?.incrementFailCount) {\n const credentials = await db.select()\n .from(Credential)\n .where(eq(Credential.id, credentialId));\n\n const currentCred = credentials[0];\n if (currentCred) {\n updateData.failCount = (currentCred.failCount ?? 0) + 1;\n }\n }\n\n await db.update(Credential)\n .set(updateData)\n .where(eq(Credential.id, credentialId));\n\n this.logger.info(`Credential ${credentialId} status updated to ${status}`);\n } catch (error) {\n this.logger.error(`Failed to update credential ${credentialId}: ${error}`);\n }\n }\n\n /**\n * 记录凭据使用成功(重置 failCount,更新 lastUsedAt)\n */\n async recordCredentialSuccess(context: StoreContext, credentialId: string): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n return;\n }\n\n try {\n await db.update(Credential)\n .set({\n lastUsedAt: new Date(),\n failCount: 0,\n status: CredentialStatus.ACTIVE,\n rateLimitResetAt: undefined,\n })\n .where(eq(Credential.id, credentialId));\n } catch (error) {\n this.logger.debug(`Failed to record credential success: ${error}`);\n }\n }\n\n /**\n * 从 provider URI 提取 ID\n * e.g., \"http://localhost:3000/test/settings/ai/providers.ttl#google\" -> \"google\"\n */\n private extractProviderId(providerUri: string): string {\n const hash = providerUri.lastIndexOf('#');\n if (hash >= 0) {\n return providerUri.slice(hash + 1);\n }\n return providerUri;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"pod-store.js","sourceRoot":"","sources":["../../../src/api/chatkit/pod-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pod-based ChatKit Store\n *\n * 将 ChatKit 数据存储到 Solid Pod。\n *\n * 存储结构:\n * /.data/chat/{chatId}/\n * index.ttl\n * #this # Chat (meeting:LongChat)\n * #{threadId} # Thread (sioc:Thread)\n * {yyyy}/{MM}/{dd}/messages.ttl # Messages (meeting:Message)\n */\n\nimport { drizzle, eq, and } from '@undefineds.co/drizzle-solid';\nimport { getLoggerFor } from 'global-logger-factory';\nimport type { ChatKitStore, StoreContext } from './store';\nimport type {\n ThreadMetadata,\n ThreadItem,\n Attachment,\n Page,\n StoreItemType,\n UserMessageItem,\n AssistantMessageItem,\n ThreadStatus,\n} from './types';\nimport { generateId, nowTimestamp } from './types';\nimport {\n Chat,\n Thread,\n Message,\n MessageRole,\n MessageStatus,\n type ChatRecord,\n type ThreadRecord,\n type MessageRecord,\n} from './schema';\nimport type { AuthContext } from '../auth/AuthContext';\nimport { isSolidAuth } from '../auth/AuthContext';\nimport { Provider } from '../../ai/schema/provider';\nimport { Credential } from '../../credential/schema/tables';\nimport { ServiceType, CredentialStatus } from '../../credential/schema/types';\n\nconst schema = {\n chat: Chat,\n thread: Thread,\n message: Message,\n provider: Provider,\n credential: Credential,\n};\n\nexport interface PodChatKitStoreOptions {\n tokenEndpoint: string;\n}\n\n/**\n * Pod-based ChatKit Store implementation\n *\n * 数据模型映射:\n * - ChatKit thread = Thread (sioc:Thread)\n * - ChatKit thread item = Message (meeting:Message)\n * - Chat (meeting:LongChat) 是容器/Agent,通过 metadata.chat_id 暴露\n *\n * 每个 Thread 属于一个 Chat 容器。默认使用 'default' Chat。\n */\nexport class PodChatKitStore implements ChatKitStore<StoreContext> {\n private readonly logger = getLoggerFor(this);\n private readonly tokenEndpoint: string;\n\n /** 默认 Chat 容器 ID */\n private static readonly DEFAULT_CHAT_ID = 'default';\n\n public constructor(options: PodChatKitStoreOptions) {\n this.tokenEndpoint = options.tokenEndpoint;\n }\n\n // =========================================================================\n // Private Helpers\n // =========================================================================\n\n /**\n * 获取认证后的 drizzle 实例 (缓存到 context 中)\n */\n private async getDb(context: StoreContext) {\n // Check if we already have a cached db in context\n if ((context as any)._cachedDb) {\n this.logger.debug('Using cached db from context');\n return (context as any)._cachedDb;\n }\n\n const auth = context.auth as AuthContext | undefined;\n\n if (!auth || !isSolidAuth(auth)) {\n this.logger.warn('No valid solid auth in context, cannot access Pod');\n return null;\n }\n\n // Preferred path: directly use caller's Solid access token.\n if (auth.accessToken && auth.webId) {\n try {\n if (auth.tokenType === 'DPoP') {\n this.logger.warn('Using DPoP access token without proof key; Pod access may fail if issuer enforces DPoP proof');\n }\n\n this.logger.info(`[getDb] Using access token path for webId: ${auth.webId}`);\n const authFetch = this.createAccessTokenFetch(auth.accessToken, auth.tokenType);\n const db = drizzle(\n { fetch: authFetch, info: { webId: auth.webId, isLoggedIn: true } } as any,\n { schema },\n );\n\n this.logger.info(`Initializing tables for Pod (access token): ${auth.webId}`);\n try {\n await db.init([Chat, Thread, Message]);\n this.logger.info('Tables initialized successfully');\n } catch (initError) {\n this.logger.error(`Failed to init tables: ${initError}`);\n }\n\n (context as any)._cachedDb = db;\n (context as any)._cachedFetch = authFetch;\n (context as any)._cachedWebId = auth.webId;\n return db;\n } catch (error) {\n this.logger.error(`Failed to get Pod db with access token: ${error}`);\n return null;\n }\n }\n\n if (!auth.clientId || !auth.clientSecret) {\n this.logger.warn('No accessToken and no valid client credentials in context, cannot access Pod');\n return null;\n }\n\n // Fallback path: exchange client credentials for an access token directly.\n this.logger.info(`[getDb] Using client credentials path for clientId: ${auth.clientId}`);\n try {\n const token = await this.getClientCredentialsAccessToken(auth.clientId, auth.clientSecret);\n const webId = auth.webId ?? this.getWebId(context);\n if (!webId) {\n throw new Error('Missing webId for client credentials auth');\n }\n\n this.logger.info(`[getDb] Client credentials token acquired, webId: ${webId}`);\n const authFetch = this.createAccessTokenFetch(token.accessToken, token.tokenType);\n const db = drizzle(\n { fetch: authFetch, info: { webId, isLoggedIn: true } } as any,\n { schema },\n );\n\n this.logger.info(`Initializing tables for Pod: ${webId}`);\n try {\n await db.init([Chat, Thread, Message]);\n this.logger.info('Tables initialized successfully');\n } catch (initError) {\n this.logger.error(`Failed to init tables: ${initError}`);\n }\n\n (context as any)._cachedDb = db;\n (context as any)._cachedFetch = authFetch;\n (context as any)._cachedWebId = webId;\n (context as any)._cachedAccessToken = token.accessToken;\n (context as any)._cachedTokenType = token.tokenType;\n\n return db;\n } catch (error) {\n this.logger.error(`Failed to get Pod db: ${error}`);\n return null;\n }\n }\n\n private async getClientCredentialsAccessToken(clientId: string, clientSecret: string): Promise<{\n accessToken: string;\n tokenType: 'Bearer' | 'DPoP';\n }> {\n const response = await fetch(this.tokenEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: clientId,\n client_secret: clientSecret,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Client credentials token request failed: ${response.status} ${await response.text().catch(() => '')}`);\n }\n\n const token = await response.json() as { access_token?: string; token_type?: string };\n if (!token.access_token) {\n throw new Error(`Client credentials token response missing access_token: ${JSON.stringify(token)}`);\n }\n\n return {\n accessToken: token.access_token,\n tokenType: token.token_type?.toUpperCase() === 'DPOP' ? 'DPoP' : 'Bearer',\n };\n }\n\n private createAccessTokenFetch(accessToken: string, tokenType?: 'Bearer' | 'DPoP'): typeof fetch {\n const scheme = tokenType ?? 'Bearer';\n return async (\n input: Parameters<typeof fetch>[0],\n init?: Parameters<typeof fetch>[1],\n ): Promise<Response> => {\n const headers = new Headers(init?.headers);\n if (!headers.has('Authorization')) {\n headers.set('Authorization', `${scheme} ${accessToken}`);\n }\n return fetch(input, {\n ...init,\n headers,\n });\n };\n }\n\n /**\n * 从 context 获取 webId\n */\n private getWebId(context: StoreContext): string | undefined {\n const auth = context.auth as AuthContext | undefined;\n if (auth && isSolidAuth(auth)) {\n return auth.webId;\n }\n return undefined;\n }\n\n /**\n * 将 ThreadStatus 对象转为字符串\n */\n private statusToString(status: ThreadStatus): string {\n return status.type;\n }\n\n /**\n * 将字符串转为 ThreadStatus 对象\n */\n private stringToStatus(status: string | null | undefined): ThreadStatus {\n switch (status) {\n case 'locked':\n return { type: 'locked' };\n case 'closed':\n return { type: 'closed' };\n default:\n return { type: 'active' };\n }\n }\n\n /**\n * 从 ThreadMetadata.metadata 中获取 chat_id,如果没有则返回默认值\n */\n private getChatIdFromMetadata(metadata?: Record<string, unknown>): string {\n if (metadata && typeof metadata.chat_id === 'string') {\n return metadata.chat_id;\n }\n return PodChatKitStore.DEFAULT_CHAT_ID;\n }\n\n /**\n * 确保 Chat 容器存在,如果不存在则创建\n */\n private async ensureChat(chatId: string, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const webId = this.getWebId(context);\n\n // 检查是否存在\n const existing = await db.query.chat.findFirst({\n where: eq(Chat.id, chatId),\n });\n\n if (!existing) {\n // 创建 Chat 容器\n const now = new Date().toISOString();\n await db.insert(Chat).values({\n id: chatId,\n title: chatId === PodChatKitStore.DEFAULT_CHAT_ID ? 'Default Chat' : chatId,\n author: webId || null,\n status: 'active',\n createdAt: now,\n updatedAt: now,\n });\n this.logger.info(`Created Chat container: ${chatId}`);\n }\n }\n\n /**\n * 将 ThreadRecord 转为 ThreadMetadata\n * 包含 metadata.chat_id 暴露 Chat 容器 ID\n */\n private threadRecordToMetadata(record: ThreadRecord): ThreadMetadata {\n const chatId = this.extractChatId(record.chatId);\n let extra: Record<string, unknown> | undefined;\n if (record.metadata) {\n try {\n extra = JSON.parse(record.metadata) as Record<string, unknown>;\n } catch {\n // ignore invalid metadata\n }\n }\n\n return {\n id: record.id,\n title: record.title || undefined,\n status: this.stringToStatus(record.status),\n created_at: record.createdAt ? Math.floor(new Date(record.createdAt).getTime() / 1000) : nowTimestamp(),\n updated_at: record.updatedAt ? Math.floor(new Date(record.updatedAt).getTime() / 1000) : nowTimestamp(),\n metadata: {\n chat_id: chatId,\n ...(extra ?? {}),\n },\n };\n }\n\n /**\n * 将 MessageRecord 转为 ThreadItem\n * thread_id 返回 Message 所属的 Thread ID\n */\n private messageRecordToItem(record: MessageRecord, threadId: string): ThreadItem {\n const createdAt = record.createdAt ? Math.floor(new Date(record.createdAt).getTime() / 1000) : nowTimestamp();\n\n if (record.role === MessageRole.USER) {\n return {\n id: record.id,\n thread_id: threadId,\n type: 'user_message',\n content: [{ type: 'input_text', text: record.content || '' }],\n created_at: createdAt,\n } as UserMessageItem;\n } else {\n return {\n id: record.id,\n thread_id: threadId,\n type: 'assistant_message',\n content: [{ type: 'output_text', text: record.content || '' }],\n status: (record.status as 'in_progress' | 'completed' | 'incomplete') || 'completed',\n created_at: createdAt,\n } as AssistantMessageItem;\n }\n }\n\n /**\n * 从 Thread 获取 chatId(提取纯 ID)\n */\n private extractChatId(chatIdOrUri: string | null | undefined): string {\n if (!chatIdOrUri) return PodChatKitStore.DEFAULT_CHAT_ID;\n\n if (chatIdOrUri.includes('#')) {\n // 从 URI 中提取,如 http://.../.data/chat/default/index.ttl#this -> default\n const match = chatIdOrUri.match(/\\.data\\/chat\\/([^/]+)\\/index\\.ttl#this/);\n if (match) {\n return match[1];\n }\n }\n return chatIdOrUri;\n }\n\n private extractThreadId(threadIdOrUri: string | null | undefined): string | undefined {\n if (!threadIdOrUri) return undefined;\n\n if (threadIdOrUri.includes('#')) {\n return threadIdOrUri.split('#').pop() || undefined;\n }\n\n return threadIdOrUri;\n }\n\n private getPodBaseUrl(context: StoreContext): string {\n const cachedWebId = (context as any)._cachedWebId as string | undefined;\n const webId = cachedWebId ?? this.getWebId(context);\n if (!webId) {\n throw new Error('Missing webId for Pod URI resolution');\n }\n\n return webId.replace('/profile/card#me', '').replace(/\\/$/, '');\n }\n\n private buildThreadUri(chatId: string, threadId: string, context: StoreContext): string {\n return `${this.getPodBaseUrl(context)}/.data/chat/${chatId}/index.ttl#${threadId}`;\n }\n\n private async selectMessagesForThread(threadId: string, context: StoreContext): Promise<MessageRecord[]> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const chatId = await this.getThreadChatId(threadId, context);\n const messages = await db.select().from(Message) as MessageRecord[];\n return messages.filter(\n (message) => this.extractChatId(message.chatId) === chatId && this.extractThreadId(message.threadId) === threadId,\n );\n }\n\n private async deleteMessageRecord(db: NonNullable<Awaited<ReturnType<PodChatKitStore['getDb']>>>, message: MessageRecord): Promise<void> {\n const messageIri = (message as MessageRecord & { '@id'?: string })['@id'];\n if (messageIri) {\n await db.delete(Message).whereByIri(messageIri);\n return;\n }\n\n await db.delete(Message).where(and(\n eq(Message.id, message.id),\n eq(Message.chatId, this.extractChatId(message.chatId)),\n eq(Message.createdAt, message.createdAt as any),\n ));\n }\n\n /**\n * 获取 Thread 的 chatId\n * 先从缓存获取,如果没有再查询数据库\n */\n private async getThreadChatId(threadId: string, context: StoreContext): Promise<string> {\n // 先检查缓存\n const cached = this.getCachedThreadChatId(context, threadId);\n if (cached) {\n return cached;\n }\n\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const thread = await db.query.thread.findFirst({\n where: eq(Thread.id, threadId),\n });\n\n if (!thread) {\n // 如果找不到 Thread,返回默认 chatId\n this.logger.warn(`Thread not found in DB, using default chatId: ${threadId}`);\n return PodChatKitStore.DEFAULT_CHAT_ID;\n }\n\n const chatId = this.extractChatId(thread.chatId);\n // 缓存结果\n this.cacheThreadChatId(context, threadId, chatId);\n return chatId;\n }\n\n /**\n * 缓存 Thread -> chatId 映射\n */\n private cacheThreadChatId(context: StoreContext, threadId: string, chatId: string): void {\n if (!(context as any)._threadChatIdCache) {\n (context as any)._threadChatIdCache = new Map<string, string>();\n }\n (context as any)._threadChatIdCache.set(threadId, chatId);\n }\n\n /**\n * 从缓存获取 Thread 的 chatId\n */\n private getCachedThreadChatId(context: StoreContext, threadId: string): string | undefined {\n const cache = (context as any)._threadChatIdCache as Map<string, string> | undefined;\n return cache?.get(threadId);\n }\n\n /**\n * 缓存完整的 Thread metadata\n */\n private cacheThreadMetadata(context: StoreContext, thread: ThreadMetadata): void {\n if (!(context as any)._threadMetadataCache) {\n (context as any)._threadMetadataCache = new Map<string, ThreadMetadata>();\n }\n (context as any)._threadMetadataCache.set(thread.id, thread);\n }\n\n /**\n * 从缓存获取 Thread metadata\n */\n private getCachedThreadMetadata(context: StoreContext, threadId: string): ThreadMetadata | undefined {\n const cache = (context as any)._threadMetadataCache as Map<string, ThreadMetadata> | undefined;\n return cache?.get(threadId);\n }\n\n // =========================================================================\n // ID Generation\n // =========================================================================\n\n generateThreadId(_context: StoreContext): string {\n return generateId('thread');\n }\n\n generateItemId(itemType: StoreItemType, _thread: ThreadMetadata, _context: StoreContext): string {\n return generateId(itemType.replace('_', '-'));\n }\n\n // =========================================================================\n // Thread Operations (ChatKit thread = our Thread)\n // =========================================================================\n\n async loadThread(threadId: string, context: StoreContext): Promise<ThreadMetadata> {\n // 先从缓存获取\n const cached = this.getCachedThreadMetadata(context, threadId);\n if (cached) {\n return cached;\n }\n\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const thread = await db.query.thread.findFirst({\n where: eq(Thread.id, threadId),\n });\n\n if (!thread) {\n throw new Error(`Thread not found: ${threadId}`);\n }\n\n const metadata = this.threadRecordToMetadata(thread);\n // 缓存结果\n this.cacheThreadMetadata(context, metadata);\n return metadata;\n }\n\n async saveThread(thread: ThreadMetadata, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const now = new Date().toISOString();\n\n // 从 metadata 获取 chat_id\n const chatId = this.getChatIdFromMetadata(thread.metadata);\n // Persist all metadata except chat_id (which is derived from storage location).\n const metadataToPersist = { ...(thread.metadata ?? {}) } as Record<string, unknown>;\n delete (metadataToPersist as any).chat_id;\n const metadataJson = Object.keys(metadataToPersist).length > 0 ? JSON.stringify(metadataToPersist) : null;\n\n // 确保 Chat 容器存在\n await this.ensureChat(chatId, context);\n\n // 缓存 Thread -> chatId 映射,避免后续查询\n this.cacheThreadChatId(context, thread.id, chatId);\n\n // 检查 Thread 是否存在\n const existing = await db.query.thread.findFirst({\n where: eq(Thread.id, thread.id),\n });\n\n if (existing) {\n // Update\n await db.update(Thread).set({\n title: thread.title || null,\n status: this.statusToString(thread.status),\n metadata: metadataJson,\n updatedAt: now,\n }).where(eq(Thread.id, thread.id));\n } else {\n // Insert\n await db.insert(Thread).values({\n id: thread.id,\n chatId, // 关联到 Chat 容器\n title: thread.title || null,\n status: this.statusToString(thread.status),\n metadata: metadataJson,\n createdAt: new Date(thread.created_at * 1000).toISOString(),\n updatedAt: now,\n });\n }\n\n // 缓存完整的 Thread metadata,确保 metadata.chat_id 包含正确的值\n const threadMetadata: ThreadMetadata = {\n ...thread,\n metadata: { ...(thread.metadata ?? {}), chat_id: chatId },\n };\n this.cacheThreadMetadata(context, threadMetadata);\n }\n\n async loadThreads(\n limit: number,\n after: string | undefined,\n order: string,\n context: StoreContext,\n ): Promise<Page<ThreadMetadata>> {\n const db = await this.getDb(context);\n if (!db) {\n return { data: [], has_more: false };\n }\n\n try {\n const threads = await db.select().from(Thread) as ThreadRecord[];\n\n // 排序\n threads.sort((a: ThreadRecord, b: ThreadRecord) => {\n const aTime = a.createdAt ? new Date(a.createdAt).getTime() : 0;\n const bTime = b.createdAt ? new Date(b.createdAt).getTime() : 0;\n return order === 'desc' ? bTime - aTime : aTime - bTime;\n });\n\n // 分页\n let startIndex = 0;\n if (after) {\n const afterIndex = threads.findIndex((t: ThreadRecord) => t.id === after);\n if (afterIndex !== -1) {\n startIndex = afterIndex + 1;\n }\n }\n\n const slice = threads.slice(startIndex, startIndex + limit);\n const hasMore = startIndex + limit < threads.length;\n\n return {\n data: slice.map((t: ThreadRecord) => this.threadRecordToMetadata(t)),\n has_more: hasMore,\n after: slice.length > 0 ? slice[slice.length - 1].id : undefined,\n };\n } catch (error) {\n this.logger.error(`Failed to load threads: ${error}`);\n return { data: [], has_more: false };\n }\n }\n\n async deleteThread(threadId: string, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n // 尝试从缓存获取 chatId\n let chatId = this.getCachedThreadChatId(context, threadId);\n\n // 如果缓存没有,尝试从数据库查询\n if (!chatId) {\n try {\n const thread = await db.query.thread.findFirst({\n where: eq(Thread.id, threadId),\n });\n if (thread) {\n chatId = this.extractChatId(thread.chatId);\n }\n } catch (err: any) {\n // 忽略查询错误,继续尝试删除\n this.logger.debug(`Ignoring thread query error during delete: ${err.message}`);\n }\n }\n\n // 删除关联到此 Thread 的消息\n try {\n const messages = await this.selectMessagesForThread(threadId, context);\n for (const message of messages) {\n await this.deleteMessageRecord(db, message);\n }\n } catch (err: any) {\n if (!err.message?.includes('404') && !err.message?.includes('Could not retrieve') && !err.message?.includes('Parse error')) {\n throw err;\n }\n this.logger.debug(`Ignoring delete message error: ${err.message}`);\n }\n\n // 删除 Thread\n try {\n if (chatId) {\n await db.delete(Thread).where(and(eq(Thread.id, threadId), eq(Thread.chatId, chatId)));\n } else {\n // 如果没有 chatId,尝试只用 id 删除(可能失败)\n await db.delete(Thread).where(eq(Thread.id, threadId));\n }\n } catch (err: any) {\n if (!err.message?.includes('404') && !err.message?.includes('Could not retrieve') && !err.message?.includes('Parse error')) {\n throw err;\n }\n this.logger.debug(`Ignoring delete thread error: ${err.message}`);\n }\n\n // 清除缓存\n const metadataCache = (context as any)._threadMetadataCache as Map<string, ThreadMetadata> | undefined;\n const chatIdCache = (context as any)._threadChatIdCache as Map<string, string> | undefined;\n metadataCache?.delete(threadId);\n chatIdCache?.delete(threadId);\n }\n\n // =========================================================================\n // Thread Item Operations (ChatKit items = our Messages)\n // =========================================================================\n\n async loadThreadItems(\n threadId: string,\n after: string | undefined,\n limit: number,\n order: string,\n context: StoreContext,\n ): Promise<Page<ThreadItem>> {\n try {\n const messages = await this.selectMessagesForThread(threadId, context);\n\n // 排序\n messages.sort((a: MessageRecord, b: MessageRecord) => {\n const aTime = a.createdAt ? new Date(a.createdAt).getTime() : 0;\n const bTime = b.createdAt ? new Date(b.createdAt).getTime() : 0;\n return order === 'desc' ? bTime - aTime : aTime - bTime;\n });\n\n // 分页\n let startIndex = 0;\n if (after) {\n const afterIndex = messages.findIndex((m: MessageRecord) => m.id === after);\n if (afterIndex !== -1) {\n startIndex = afterIndex + 1;\n }\n }\n\n const slice = messages.slice(startIndex, startIndex + limit);\n const hasMore = startIndex + limit < messages.length;\n\n return {\n data: slice.map((m: MessageRecord) => this.messageRecordToItem(m, threadId)),\n has_more: hasMore,\n after: slice.length > 0 ? slice[slice.length - 1].id : undefined,\n };\n } catch (error) {\n this.logger.error(`Failed to load thread items: ${error}`);\n return { data: [], has_more: false };\n }\n }\n\n async addThreadItem(threadId: string, item: ThreadItem, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n // 从 Thread 获取 chatId\n const chatId = await this.getThreadChatId(threadId, context);\n\n const webId = this.getWebId(context);\n let content = '';\n let role: string = MessageRole.USER;\n let status: string | null = null;\n\n if (item.type === 'user_message') {\n const userItem = item as UserMessageItem;\n content = userItem.content\n .filter((c) => c.type === 'input_text')\n .map((c) => (c as any).text)\n .join('\\n');\n role = MessageRole.USER;\n } else if (item.type === 'assistant_message') {\n const assistantItem = item as AssistantMessageItem;\n content = assistantItem.content\n .filter((c) => c.type === 'output_text')\n .map((c) => c.text)\n .join('\\n');\n role = MessageRole.ASSISTANT;\n status = assistantItem.status || MessageStatus.COMPLETED;\n } else {\n // 其他类型暂时存储为 JSON\n content = JSON.stringify(item);\n role = MessageRole.SYSTEM;\n }\n\n const messageRecord = {\n id: item.id,\n chatId, // 用于路径构建\n threadId: this.buildThreadUri(chatId, threadId, context), // 关联到 Thread\n maker: role === MessageRole.USER ? webId : null,\n role,\n content,\n status,\n createdAt: new Date(item.created_at * 1000).toISOString(),\n };\n\n await db.insert(Message).values(messageRecord);\n\n // Track this ID to avoid cache timing issues in saveItem\n this.recentlyCreatedIds.add(messageRecord.id);\n }\n\n // Track recently created message IDs to avoid SELECT cache timing issues\n private recentlyCreatedIds = new Set<string>();\n\n async saveItem(threadId: string, item: ThreadItem, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n // 从 Thread 获取 chatId(用于构建资源路径)\n const chatId = await this.getThreadChatId(threadId, context);\n\n // 准备更新数据\n let content = '';\n let status: string | null = null;\n\n if (item.type === 'user_message') {\n const userItem = item as UserMessageItem;\n content = userItem.content\n .filter((c) => c.type === 'input_text')\n .map((c) => (c as any).text)\n .join('\\n');\n } else if (item.type === 'assistant_message') {\n const assistantItem = item as AssistantMessageItem;\n content = assistantItem.content\n .filter((c) => c.type === 'output_text')\n .map((c) => c.text)\n .join('\\n');\n status = assistantItem.status || MessageStatus.COMPLETED;\n }\n\n // 获取 createdAt 用于计算资源路径(与 drizzle-solid 模板填充保持一致)\n const createdAt = item.created_at ? new Date(item.created_at * 1000).toISOString() : undefined;\n\n // 如果是最近创建的消息,使用直接 PATCH 更新(避免 drizzle-solid UPDATE 的 bug)\n const wasRecentlyCreated = this.recentlyCreatedIds.has(item.id);\n if (wasRecentlyCreated) {\n this.recentlyCreatedIds.delete(item.id);\n await this.directPatchMessage(context, chatId, item.id, content, status, createdAt);\n return;\n }\n\n // 对于非最近创建的消息,使用普通流程\n const existingItems = await db.select().from(Message).where(\n eq(Message.id, item.id),\n ) as MessageRecord[];\n const existing = existingItems.length > 0 ? existingItems[0] : null;\n\n if (existing) {\n // 使用直接 PATCH 更新\n const existingCreatedAt = existing.createdAt\n ? (existing.createdAt instanceof Date ? existing.createdAt.toISOString() : String(existing.createdAt))\n : undefined;\n await this.directPatchMessage(context, chatId, item.id, content, status, existingCreatedAt);\n } else {\n // Create new record\n await this.addThreadItem(threadId, item, context);\n }\n }\n\n /**\n * 直接使用 SPARQL UPDATE PATCH 更新消息内容\n * 避免 drizzle-solid UPDATE 的 bug\n */\n private async directPatchMessage(\n context: StoreContext,\n chatId: string,\n messageId: string,\n content: string,\n status: string | null,\n createdAt?: string\n ): Promise<void> {\n // 使用缓存的 fetch 和 webId(由 getDb 时创建的 session)\n const cachedFetch = (context as any)._cachedFetch as typeof fetch | undefined;\n const cachedWebId = (context as any)._cachedWebId as string | undefined;\n\n if (!cachedFetch || !cachedWebId) {\n throw new Error('No cached session for direct PATCH - call getDb first');\n }\n\n // 构建资源 URL 和 subject URI\n // Template: {chatId}/{yyyy}/{MM}/{dd}/messages.ttl#{id}\n // 使用 createdAt 时间来计算日期,与 drizzle-solid 的模板填充逻辑保持一致\n const dateForPath = createdAt ? new Date(createdAt) : new Date();\n const yyyy = dateForPath.getUTCFullYear();\n const mm = String(dateForPath.getUTCMonth() + 1).padStart(2, '0');\n const dd = String(dateForPath.getUTCDate()).padStart(2, '0');\n\n const podBaseUrl = cachedWebId.replace('/profile/card#me', '');\n const resourceUrl = `${podBaseUrl}/.data/chat/${chatId}/${yyyy}/${mm}/${dd}/messages.ttl`;\n const subjectUri = `${resourceUrl}#${messageId}`;\n\n // 构建 SPARQL UPDATE:删除旧值,插入新值\n const deletePatterns: string[] = [];\n const insertTriples: string[] = [];\n\n // 转义特殊字符\n const escapeForSparql = (value: string): string => {\n const hasQuotes = value.includes('\"');\n const hasNewlines = value.includes('\\n') || value.includes('\\r');\n\n if (hasQuotes || hasNewlines) {\n // 使用三引号\n let escaped = value;\n escaped = escaped.replace(/\"\"\"/g, '\"\\\\\"\\\\\"\"');\n if (escaped.endsWith('\"')) {\n const match = escaped.match(/\"*$/);\n const trailingQuotes = match ? match[0].length : 0;\n if (trailingQuotes > 0) {\n escaped = escaped.slice(0, -trailingQuotes) + '\\\\\"'.repeat(trailingQuotes);\n }\n }\n return `\"\"\"${escaped}\"\"\"`;\n }\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n };\n\n // Content 更新\n deletePatterns.push(`<${subjectUri}> <http://rdfs.org/sioc/ns#content> ?oldContent .`);\n insertTriples.push(`<${subjectUri}> <http://rdfs.org/sioc/ns#content> ${escapeForSparql(content)} .`);\n\n // Status 更新\n if (status) {\n deletePatterns.push(`<${subjectUri}> <https://undefineds.co/ns#status> ?oldStatus .`);\n insertTriples.push(`<${subjectUri}> <https://undefineds.co/ns#status> \"${status}\" .`);\n }\n\n const sparql = `\nDELETE { ${deletePatterns.join(' ')} }\nINSERT { ${insertTriples.join(' ')} }\nWHERE { ${deletePatterns.join(' ')} }\n `.trim();\n\n const response = await cachedFetch(resourceUrl, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/sparql-update' },\n body: sparql,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`Direct PATCH failed: ${response.status} ${response.statusText} - ${text}`);\n }\n }\n\n async loadItem(threadId: string, itemId: string, context: StoreContext): Promise<ThreadItem> {\n const messages = (await this.selectMessagesForThread(threadId, context)).filter(\n (message) => message.id === itemId,\n );\n\n if (messages.length === 0) {\n throw new Error(`Item not found: ${itemId}`);\n }\n\n return this.messageRecordToItem(messages[0], threadId);\n }\n\n async deleteThreadItem(threadId: string, itemId: string, context: StoreContext): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n throw new Error('Cannot access Pod: invalid credentials');\n }\n\n const messages = await this.selectMessagesForThread(threadId, context);\n const target = messages.find((message) => message.id === itemId);\n if (!target) {\n return;\n }\n\n await this.deleteMessageRecord(db, target);\n }\n\n // =========================================================================\n // Attachment Operations (存 Pod 文件)\n // =========================================================================\n\n async saveAttachment(attachment: Attachment, _context: StoreContext): Promise<void> {\n this.logger.info(`Attachment saved: ${attachment.id} (${attachment.name})`);\n }\n\n async loadAttachment(attachmentId: string, _context: StoreContext): Promise<Attachment> {\n throw new Error(`Attachment not found: ${attachmentId}`);\n }\n\n async deleteAttachment(attachmentId: string, _context: StoreContext): Promise<void> {\n this.logger.info(`Attachment deleted: ${attachmentId}`);\n }\n\n // =========================================================================\n // AI Config Operations (复用 Session 缓存)\n // =========================================================================\n\n /**\n * AI 配置结果\n */\n public static readonly AiConfigResult = class {\n providerId!: string;\n baseUrl!: string;\n proxyUrl?: string;\n apiKey!: string;\n credentialId!: string;\n };\n\n /**\n * 从 Pod 获取 AI 配置(Provider + Credential)\n * 复用已缓存的 Session,避免重复登录\n */\n async getAiConfig(context: StoreContext): Promise<{\n providerId: string;\n baseUrl: string;\n proxyUrl?: string;\n apiKey: string;\n credentialId: string;\n } | undefined> {\n const db = await this.getDb(context);\n if (!db) {\n return undefined;\n }\n\n try {\n // 查询活跃的 AI 凭据\n const credentials = await db.select()\n .from(Credential)\n .where(and(\n eq(Credential.service, ServiceType.AI),\n eq(Credential.status, CredentialStatus.ACTIVE),\n ));\n\n if (credentials.length === 0) {\n return undefined;\n }\n\n // 遍历凭据,找到有效的 Provider\n for (const cred of credentials) {\n if (!cred.provider) continue;\n\n // 从 URI 提取 provider ID\n const providerId = this.extractProviderId(cred.provider);\n\n // 查询 Provider\n const providers = await db.select()\n .from(Provider)\n .where(eq(Provider.id, providerId));\n\n const provider = providers[0];\n if (!provider) continue;\n\n const baseUrl = cred.baseUrl || provider.baseUrl;\n if (!baseUrl) continue;\n\n this.logger.debug(`Using credential ${cred.id} with provider ${provider.id}`);\n\n return {\n providerId: provider.id,\n baseUrl,\n proxyUrl: cred.proxyUrl || provider.proxyUrl || undefined,\n apiKey: cred.apiKey!,\n credentialId: cred.id,\n };\n }\n\n return undefined;\n } catch (error) {\n this.logger.warn(`Failed to read AI config from Pod: ${error}`);\n return undefined;\n }\n }\n\n /**\n * 更新凭据状态(如 429 限流)\n * 复用已缓存的 Session\n */\n async updateCredentialStatus(\n context: StoreContext,\n credentialId: string,\n status: CredentialStatus,\n options?: { rateLimitResetAt?: Date; incrementFailCount?: boolean },\n ): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n this.logger.debug('Cannot update credential status: no db available');\n return;\n }\n\n try {\n const updateData: Record<string, any> = { status };\n\n if (options?.rateLimitResetAt) {\n updateData.rateLimitResetAt = options.rateLimitResetAt;\n }\n\n // 如果需要递增 failCount,先查询当前值\n if (options?.incrementFailCount) {\n const credentials = await db.select()\n .from(Credential)\n .where(eq(Credential.id, credentialId));\n\n const currentCred = credentials[0];\n if (currentCred) {\n updateData.failCount = (currentCred.failCount ?? 0) + 1;\n }\n }\n\n await db.update(Credential)\n .set(updateData)\n .where(eq(Credential.id, credentialId));\n\n this.logger.info(`Credential ${credentialId} status updated to ${status}`);\n } catch (error) {\n this.logger.error(`Failed to update credential ${credentialId}: ${error}`);\n }\n }\n\n /**\n * 记录凭据使用成功(重置 failCount,更新 lastUsedAt)\n */\n async recordCredentialSuccess(context: StoreContext, credentialId: string): Promise<void> {\n const db = await this.getDb(context);\n if (!db) {\n return;\n }\n\n try {\n await db.update(Credential)\n .set({\n lastUsedAt: new Date(),\n failCount: 0,\n status: CredentialStatus.ACTIVE,\n rateLimitResetAt: undefined,\n })\n .where(eq(Credential.id, credentialId));\n } catch (error) {\n this.logger.debug(`Failed to record credential success: ${error}`);\n }\n }\n\n /**\n * 从 provider URI 提取 ID\n * e.g., \"http://localhost:3000/test/settings/ai/providers.ttl#google\" -> \"google\"\n */\n private extractProviderId(providerUri: string): string {\n const hash = providerUri.lastIndexOf('#');\n if (hash >= 0) {\n return providerUri.slice(hash + 1);\n }\n return providerUri;\n }\n}\n"]}
|