@undefineds.co/xpod 0.2.0-preview.2 → 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.
Files changed (64) hide show
  1. package/README.md +24 -2
  2. package/dist/agents/AgentExecutorFactory.js +1 -1
  3. package/dist/agents/AgentExecutorFactory.js.map +1 -1
  4. package/dist/agents/AgentManager.js +1 -1
  5. package/dist/agents/AgentManager.js.map +1 -1
  6. package/dist/agents/config/agent-meta-schema.d.ts +7 -7
  7. package/dist/agents/config/agent-meta-schema.js +1 -1
  8. package/dist/agents/config/agent-meta-schema.js.map +1 -1
  9. package/dist/agents/config/resolve.js +1 -1
  10. package/dist/agents/config/resolve.js.map +1 -1
  11. package/dist/agents/schema/agent-config.d.ts +18 -18
  12. package/dist/agents/schema/agent-config.js +1 -1
  13. package/dist/agents/schema/agent-config.js.map +1 -1
  14. package/dist/agents/schema/tables.d.ts +8 -8
  15. package/dist/agents/schema/tables.js +1 -1
  16. package/dist/agents/schema/tables.js.map +1 -1
  17. package/dist/ai/schema/config.d.ts +7 -7
  18. package/dist/ai/schema/config.js +1 -1
  19. package/dist/ai/schema/config.js.map +1 -1
  20. package/dist/ai/schema/model.d.ts +13 -13
  21. package/dist/ai/schema/model.js +1 -1
  22. package/dist/ai/schema/model.js.map +1 -1
  23. package/dist/ai/schema/provider.d.ts +7 -7
  24. package/dist/ai/schema/provider.js +1 -1
  25. package/dist/ai/schema/provider.js.map +1 -1
  26. package/dist/ai/schema/vector-store.d.ts +17 -17
  27. package/dist/ai/schema/vector-store.js +1 -1
  28. package/dist/ai/schema/vector-store.js.map +1 -1
  29. package/dist/ai/service/CredentialReaderImpl.js +1 -1
  30. package/dist/ai/service/CredentialReaderImpl.js.map +1 -1
  31. package/dist/ai/service/DefaultAiConfigService.js.map +1 -1
  32. package/dist/api/ApiServer.d.ts +3 -1
  33. package/dist/api/ApiServer.js +14 -1
  34. package/dist/api/ApiServer.js.map +1 -1
  35. package/dist/api/chatkit/pod-store.d.ts +6 -0
  36. package/dist/api/chatkit/pod-store.js +86 -35
  37. package/dist/api/chatkit/pod-store.js.map +1 -1
  38. package/dist/api/chatkit/schema.d.ts +29 -29
  39. package/dist/api/chatkit/schema.js +4 -4
  40. package/dist/api/chatkit/schema.js.map +1 -1
  41. package/dist/api/container/common.js +1 -0
  42. package/dist/api/container/common.js.map +1 -1
  43. package/dist/api/runtime.js +21 -0
  44. package/dist/api/runtime.js.map +1 -1
  45. package/dist/api/service/VectorStoreService.js +1 -1
  46. package/dist/api/service/VectorStoreService.js.map +1 -1
  47. package/dist/cli/lib/pod-thread-store.js +1 -1
  48. package/dist/cli/lib/pod-thread-store.js.map +1 -1
  49. package/dist/credential/schema/tables.d.ts +14 -14
  50. package/dist/credential/schema/tables.js +1 -1
  51. package/dist/credential/schema/tables.js.map +1 -1
  52. package/dist/identity/drizzle/ServiceTokenRepository.js +9 -10
  53. package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -1
  54. package/dist/identity/drizzle/db.js +27 -2
  55. package/dist/identity/drizzle/db.js.map +1 -1
  56. package/dist/identity/drizzle/schema.pg.js +16 -16
  57. package/dist/identity/drizzle/schema.pg.js.map +1 -1
  58. package/dist/task/DrizzleTaskQueue.d.ts +1 -1
  59. package/dist/task/DrizzleTaskQueue.js +1 -1
  60. package/dist/task/DrizzleTaskQueue.js.map +1 -1
  61. package/dist/task/schema.d.ts +10 -10
  62. package/dist/task/schema.js +1 -1
  63. package/dist/task/schema.js.map +1 -1
  64. package/package.json +20 -10
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/api/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { asValue, type AwilixContainer } from 'awilix';\nimport { setGlobalLoggerFactory, getLoggerFor } from 'global-logger-factory';\nimport { ConfigurableLoggerFactory } from '../logging/ConfigurableLoggerFactory';\nimport { createApiContainer, loadConfigFromEnv, type ApiContainerConfig, type ApiContainerCradle } from './container';\nimport { registerRoutes } from './container/routes';\nimport type { AuthContext } from './auth/AuthContext';\nimport { OpenAuthMiddleware } from './middleware/OpenAuthMiddleware';\n\nexport interface StartApiServiceOptions {\n config?: ApiContainerConfig;\n open?: boolean;\n authContext?: AuthContext;\n initializeLogger?: boolean;\n}\n\nexport interface ApiServiceHandle {\n config: ApiContainerConfig;\n container: AwilixContainer<ApiContainerCradle>;\n stop: () => Promise<void>;\n}\n\nfunction initApiLogger(): void {\n const loggerFactory = new ConfigurableLoggerFactory(process.env.CSS_LOGGING_LEVEL || 'info', {\n fileName: './logs/xpod-%DATE%.log',\n showLocation: true,\n });\n setGlobalLoggerFactory(loggerFactory);\n}\n\nasync function startBackgroundServices(\n container: AwilixContainer<ApiContainerCradle>,\n logger: ReturnType<typeof getLoggerFor>,\n): Promise<void> {\n try {\n const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true }) as any;\n if (localNetworkManager) {\n localNetworkManager.start();\n }\n } catch (error) {\n logger.error(`Failed to initialize LocalNetworkManager: ${error}`);\n }\n\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n if (ddnsManager) {\n await ddnsManager.start();\n logger.info('DDNS Manager started');\n }\n } catch (error) {\n logger.error(`Failed to initialize DdnsManager: ${error}`);\n }\n\n try {\n const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true });\n const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true }) as any;\n\n if (!localNetworkManager && localTunnelProvider) {\n logger.info('Starting Cloudflare Tunnel (standalone mode)...');\n await localTunnelProvider.start();\n logger.info('Cloudflare Tunnel started');\n }\n } catch (error) {\n logger.error(`Failed to start Cloudflare Tunnel: ${error}`);\n }\n}\n\nasync function stopBackgroundServices(container: AwilixContainer<ApiContainerCradle>): Promise<void> {\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n ddnsManager?.stop();\n } catch {\n // ignore shutdown errors\n }\n\n try {\n const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true });\n await localNetworkManager?.stop();\n } catch {\n // ignore shutdown errors\n }\n\n try {\n const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true }) as any;\n await localTunnelProvider?.stop();\n } catch {\n // ignore shutdown errors\n }\n}\n\nexport async function startApiService(options: StartApiServiceOptions = {}): Promise<ApiServiceHandle> {\n if (options.initializeLogger !== false) {\n initApiLogger();\n }\n\n const config = options.config ?? loadConfigFromEnv();\n const logger = getLoggerFor('ApiRuntime');\n\n if (!config.databaseUrl) {\n throw new Error('CSS_IDENTITY_DB_URL or DATABASE_URL environment variable is required');\n }\n\n logger.info(`Starting API Service (edition: ${config.edition})...`);\n\n const container = createApiContainer(config);\n\n if (options.open) {\n container.register({\n authMiddleware: asValue(new OpenAuthMiddleware({ context: options.authContext })),\n });\n }\n\n registerRoutes(container);\n await startBackgroundServices(container, logger);\n\n const server = container.resolve('apiServer');\n await server.start();\n logger.info(`API Service active on ${config.socketPath ? `unix://${config.socketPath}` : `${config.host}:${config.port}`}`);\n\n return {\n config,\n container,\n stop: async(): Promise<void> => {\n logger.info('Stopping API Service...');\n await stopBackgroundServices(container);\n await server.stop();\n },\n };\n}\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/api/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { asValue, type AwilixContainer } from 'awilix';\nimport { setGlobalLoggerFactory, getLoggerFor } from 'global-logger-factory';\nimport { ConfigurableLoggerFactory } from '../logging/ConfigurableLoggerFactory';\nimport { createApiContainer, loadConfigFromEnv, type ApiContainerConfig, type ApiContainerCradle } from './container';\nimport { registerRoutes } from './container/routes';\nimport type { AuthContext } from './auth/AuthContext';\nimport { OpenAuthMiddleware } from './middleware/OpenAuthMiddleware';\n\nexport interface StartApiServiceOptions {\n config?: ApiContainerConfig;\n open?: boolean;\n authContext?: AuthContext;\n initializeLogger?: boolean;\n}\n\nexport interface ApiServiceHandle {\n config: ApiContainerConfig;\n container: AwilixContainer<ApiContainerCradle>;\n stop: () => Promise<void>;\n}\n\nfunction initApiLogger(): void {\n const loggerFactory = new ConfigurableLoggerFactory(process.env.CSS_LOGGING_LEVEL || 'info', {\n fileName: './logs/xpod-%DATE%.log',\n showLocation: true,\n });\n setGlobalLoggerFactory(loggerFactory);\n}\n\nasync function registerPrimaryServiceToken(\n container: AwilixContainer<ApiContainerCradle>,\n config: ApiContainerConfig,\n logger: ReturnType<typeof getLoggerFor>,\n): Promise<void> {\n try {\n const serviceToken = process.env.XPOD_SERVICE_TOKEN;\n if (!serviceToken) {\n return;\n }\n\n const serviceTokenRepo = container.resolve('serviceTokenRepo') as any;\n const serviceType = config.edition === 'cloud' ? 'cloud' : 'local';\n const serviceId = process.env.XPOD_NODE_ID || (config.edition === 'cloud' ? 'cloud-1' : 'local-1');\n\n await serviceTokenRepo.registerToken(serviceToken, {\n serviceType,\n serviceId,\n scopes: ['quota:write', 'usage:read', 'account:manage'],\n });\n\n logger.info(`Registered service token for ${serviceType}:${serviceId}`);\n } catch (error) {\n logger.error(`Failed to register service token: ${error}`);\n }\n}\n\nasync function startBackgroundServices(\n container: AwilixContainer<ApiContainerCradle>,\n logger: ReturnType<typeof getLoggerFor>,\n): Promise<void> {\n try {\n const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true }) as any;\n if (localNetworkManager) {\n localNetworkManager.start();\n }\n } catch (error) {\n logger.error(`Failed to initialize LocalNetworkManager: ${error}`);\n }\n\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n if (ddnsManager) {\n await ddnsManager.start();\n logger.info('DDNS Manager started');\n }\n } catch (error) {\n logger.error(`Failed to initialize DdnsManager: ${error}`);\n }\n\n try {\n const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true });\n const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true }) as any;\n\n if (!localNetworkManager && localTunnelProvider) {\n logger.info('Starting Cloudflare Tunnel (standalone mode)...');\n await localTunnelProvider.start();\n logger.info('Cloudflare Tunnel started');\n }\n } catch (error) {\n logger.error(`Failed to start Cloudflare Tunnel: ${error}`);\n }\n}\n\nasync function stopBackgroundServices(container: AwilixContainer<ApiContainerCradle>): Promise<void> {\n try {\n const ddnsManager = container.resolve('ddnsManager', { allowUnregistered: true }) as any;\n ddnsManager?.stop();\n } catch {\n // ignore shutdown errors\n }\n\n try {\n const localNetworkManager = container.resolve('localNetworkManager', { allowUnregistered: true });\n await localNetworkManager?.stop();\n } catch {\n // ignore shutdown errors\n }\n\n try {\n const localTunnelProvider = container.resolve('localTunnelProvider', { allowUnregistered: true }) as any;\n await localTunnelProvider?.stop();\n } catch {\n // ignore shutdown errors\n }\n}\n\nexport async function startApiService(options: StartApiServiceOptions = {}): Promise<ApiServiceHandle> {\n if (options.initializeLogger !== false) {\n initApiLogger();\n }\n\n const config = options.config ?? loadConfigFromEnv();\n const logger = getLoggerFor('ApiRuntime');\n\n if (!config.databaseUrl) {\n throw new Error('CSS_IDENTITY_DB_URL or DATABASE_URL environment variable is required');\n }\n\n logger.info(`Starting API Service (edition: ${config.edition})...`);\n\n const container = createApiContainer(config);\n\n if (options.open) {\n container.register({\n authMiddleware: asValue(new OpenAuthMiddleware({ context: options.authContext })),\n });\n }\n\n registerRoutes(container);\n await registerPrimaryServiceToken(container, config, logger);\n await startBackgroundServices(container, logger);\n\n const server = container.resolve('apiServer');\n await server.start();\n logger.info(`API Service active on ${config.socketPath ? `unix://${config.socketPath}` : `${config.host}:${config.port}`}`);\n\n return {\n config,\n container,\n stop: async(): Promise<void> => {\n logger.info('Stopping API Service...');\n await stopBackgroundServices(container);\n await server.stop();\n },\n };\n}\n"]}
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VectorStoreService = void 0;
4
4
  const global_logger_factory_1 = require("global-logger-factory");
5
- const drizzle_solid_1 = require("drizzle-solid");
5
+ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
6
6
  const crypto_1 = require("crypto");
7
7
  const AuthContext_1 = require("../auth/AuthContext");
8
8
  const solid_client_authn_node_1 = require("@inrupt/solid-client-authn-node");
@@ -1 +1 @@
1
- {"version":3,"file":"VectorStoreService.js","sourceRoot":"","sources":["../../../src/api/service/VectorStoreService.ts"],"names":[],"mappings":"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","sourcesContent":["import { getLoggerFor } from 'global-logger-factory';\nimport { drizzle, eq } from 'drizzle-solid';\nimport { randomBytes } from 'crypto';\nimport type { AuthContext } from '../auth/AuthContext';\nimport { getWebId, getAccountId, isSolidAuth } from '../auth/AuthContext';\nimport type { EmbeddingService } from '../../ai/service/EmbeddingService';\nimport type { AiCredential } from '../../ai/service/types';\nimport { Session } from '@inrupt/solid-client-authn-node';\n\nimport {\n AIConfig,\n VectorStore,\n IndexedFile,\n Model,\n Provider,\n VectorStoreStatus,\n ChunkingStrategy,\n FileIndexStatus,\n MigrationStatus,\n} from '../../ai/schema';\nimport { Credential } from '../../credential/schema/tables';\nimport { ServiceType, CredentialStatus } from '../../credential/schema/types';\n\nconst schema = {\n aiConfig: AIConfig,\n vectorStore: VectorStore,\n indexedFile: IndexedFile,\n model: Model,\n provider: Provider,\n credential: Credential,\n};\n\n// ============================================\n// Types - OpenAI Compatible\n// ============================================\n\n/**\n * 创建 Vector Store 请求\n */\nexport interface CreateVectorStoreRequest {\n /** 知识库名称 */\n name?: string;\n /** Container URL */\n url: string;\n /** Chunking 策略 */\n chunking_strategy?: 'auto' | 'static';\n /** 元数据 */\n metadata?: Record<string, string>;\n}\n\n/**\n * 修改 Vector Store 请求\n */\nexport interface ModifyVectorStoreRequest {\n name?: string;\n chunking_strategy?: 'auto' | 'static';\n metadata?: Record<string, string>;\n}\n\n/**\n * Vector Store 对象(OpenAI 兼容格式)\n */\nexport interface VectorStoreObject {\n id: string;\n object: 'vector_store';\n created_at: number;\n name: string;\n status: 'in_progress' | 'completed' | 'expired';\n usage_bytes: number;\n file_counts: {\n in_progress: number;\n completed: number;\n failed: number;\n cancelled: number;\n total: number;\n };\n last_active_at: number | null;\n metadata: Record<string, string>;\n // Xpod 扩展字段\n url: string;\n chunking_strategy: string;\n}\n\n/**\n * Pod AI 配置\n */\nexport interface PodAIConfig {\n embeddingModel: string;\n migrationStatus: 'idle' | 'in_progress' | 'completed' | 'failed';\n previousModel?: string;\n migrationProgress?: number;\n}\n\n/**\n * 搜索请求\n */\nexport interface SearchRequest {\n query: string | string[];\n max_num_results?: number;\n filters?: Record<string, any>;\n ranking_options?: {\n ranker?: string;\n score_threshold?: number;\n };\n rewrite_query?: boolean;\n}\n\n/**\n * 搜索结果\n */\nexport interface SearchResult {\n file_id: string;\n file_url: string;\n filename: string;\n score: number;\n attributes: Record<string, any>;\n content: Array<{ type: 'text'; text: string }>;\n}\n\nexport interface VectorStoreServiceOptions {\n /** CSS base URL */\n cssBaseUrl: string;\n /** Token endpoint for login */\n tokenEndpoint: string;\n /** Embedding service */\n embeddingService: EmbeddingService;\n /** Webhook URL for receiving notifications (optional) */\n webhookUrl?: string;\n}\n\n/**\n * VectorStoreService - 知识库管理服务\n *\n * 提供 OpenAI 兼容的 Vector Store API\n */\nexport class VectorStoreService {\n private readonly logger = getLoggerFor(this);\n private readonly cssBaseUrl: string;\n private readonly tokenEndpoint: string;\n private readonly embeddingService: EmbeddingService;\n private readonly webhookUrl?: string;\n\n public constructor(options: VectorStoreServiceOptions) {\n this.cssBaseUrl = options.cssBaseUrl.replace(/\\/$/, '');\n this.tokenEndpoint = options.tokenEndpoint;\n this.embeddingService = options.embeddingService;\n this.webhookUrl = options.webhookUrl;\n }\n\n // ============================================\n // Vector Store CRUD\n // ============================================\n\n /**\n * 创建 Vector Store(配置文件夹为知识库)\n */\n public async createVectorStore(\n request: CreateVectorStoreRequest,\n auth: AuthContext,\n accessToken?: string,\n ): Promise<VectorStoreObject> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 生成 ID\n const id = this.generateId();\n const now = new Date();\n const containerUri = request.url;\n\n // 插入记录(不再存储 model,model 从全局配置获取)\n await db.insert(VectorStore).values({\n id,\n name: request.name || this.extractContainerName(containerUri),\n container: containerUri,\n chunkingStrategy: request.chunking_strategy || ChunkingStrategy.AUTO,\n status: VectorStoreStatus.COMPLETED,\n createdAt: now,\n lastActiveAt: now,\n });\n\n this.logger.info(`Created vector store ${id} for container ${containerUri}`);\n\n // 尝试注册 webhook 订阅(如果配置了 webhookUrl)\n if (this.webhookUrl && accessToken) {\n try {\n await this.subscribeToContainer(containerUri, accessToken);\n this.logger.info(`Subscribed to container ${containerUri} for webhook notifications`);\n } catch (error) {\n // 订阅失败不影响 VectorStore 创建,只记录警告\n this.logger.warn(`Failed to subscribe to container ${containerUri}: ${error}`);\n }\n }\n\n return this.buildVectorStoreObject(id, {\n name: request.name || this.extractContainerName(containerUri),\n containerUrl: containerUri,\n chunkingStrategy: request.chunking_strategy || 'auto',\n status: 'completed',\n createdAt: now,\n lastActiveAt: now,\n });\n }\n\n /**\n * 列出所有 Vector Store\n */\n public async listVectorStores(\n auth: AuthContext,\n options?: { limit?: number; order?: 'asc' | 'desc'; after?: string; before?: string },\n ): Promise<{ object: 'list'; data: VectorStoreObject[]; has_more: boolean }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n const stores = await db.select().from(VectorStore);\n\n // 排序\n const order = options?.order || 'desc';\n stores.sort((a, b) => {\n const aTime = a.createdAt?.getTime() || 0;\n const bTime = b.createdAt?.getTime() || 0;\n return order === 'desc' ? bTime - aTime : aTime - bTime;\n });\n\n // 分页\n const limit = options?.limit || 20;\n const data = stores.slice(0, limit).map(store => this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n }));\n\n return {\n object: 'list',\n data,\n has_more: stores.length > limit,\n };\n }\n\n /**\n * 获取单个 Vector Store\n */\n public async getVectorStore(id: string, auth: AuthContext): Promise<VectorStoreObject> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n const stores = await db.select().from(VectorStore).where(eq(VectorStore.id, id));\n if (stores.length === 0) {\n throw new Error(`Vector store ${id} not found`);\n }\n\n const store = stores[0];\n\n // 获取 file_counts(基于 Container 前缀匹配)\n const fileCounts = await this.getFileCounts(store.container || '', auth);\n\n return this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n fileCounts,\n });\n }\n\n /**\n * 修改 Vector Store\n */\n public async modifyVectorStore(\n id: string,\n request: ModifyVectorStoreRequest,\n auth: AuthContext,\n ): Promise<VectorStoreObject> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 构建更新数据(不再支持修改 model,model 是全局配置)\n const updates: Partial<typeof VectorStore.$inferInsert> = {};\n if (request.name !== undefined) updates.name = request.name;\n if (request.chunking_strategy !== undefined) updates.chunkingStrategy = request.chunking_strategy;\n\n await db.update(VectorStore).set(updates).where(eq(VectorStore.id, id));\n\n return this.getVectorStore(id, auth);\n }\n\n /**\n * 删除 Vector Store\n */\n public async deleteVectorStore(\n id: string,\n auth: AuthContext,\n ): Promise<{ id: string; object: 'vector_store.deleted'; deleted: boolean }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n await db.delete(VectorStore).where(eq(VectorStore.id, id));\n\n this.logger.info(`Deleted vector store ${id}`);\n\n return {\n id,\n object: 'vector_store.deleted',\n deleted: true,\n };\n }\n\n // ============================================\n // File Index Management (for webhook)\n // ============================================\n\n /**\n * 索引文件(由 webhook 调用)\n *\n * @param vectorStoreId Vector Store ID\n * @param fileUrl 文件 URL\n * @param auth 认证上下文\n * @param accessToken 访问令牌\n */\n public async indexFile(\n fileUrl: string,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ id: string; status: string; vectorId: number }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 获取全局 AI 配置(embedding model)\n const aiConfig = await this.getAIConfig(auth);\n if (!aiConfig) {\n throw new Error('No AI configuration found. Please configure an embedding model first.');\n }\n\n // 查找最近的父级 VectorStore 获取分块策略\n const chunkingStrategy = await this.getChunkingStrategyForFile(fileUrl, auth);\n\n // 检查文件是否已索引\n const existingFiles = await db.select().from(IndexedFile).where(\n eq(IndexedFile.fileUrl, fileUrl),\n );\n\n const vectorId = this.hashSubjectAspect(fileUrl, 'content');\n let fileIndexId: string;\n\n if (existingFiles.length > 0) {\n // 文件已存在,更新状态\n fileIndexId = existingFiles[0].id;\n await db.update(IndexedFile).set({\n status: FileIndexStatus.IN_PROGRESS,\n chunkingStrategy,\n indexedAt: new Date(),\n }).where(eq(IndexedFile.id, fileIndexId));\n } else {\n // 创建新的索引记录\n fileIndexId = `idx_${randomBytes(8).toString('hex')}`;\n await db.insert(IndexedFile).values({\n id: fileIndexId,\n fileUrl,\n vectorId,\n chunkingStrategy,\n status: FileIndexStatus.IN_PROGRESS,\n usageBytes: 0,\n indexedAt: new Date(),\n });\n }\n\n try {\n // 获取 AI credential\n const credential = await this.getAiCredential(auth);\n if (!credential) {\n throw new Error('No AI credential found');\n }\n\n // 读取文件内容\n const content = await this.fetchResourceContent(fileUrl, accessToken);\n if (!content || content.trim().length === 0) {\n throw new Error(`File ${fileUrl} has no indexable content`);\n }\n\n // 生成 embedding(使用全局 model)\n const embedding = await this.embeddingService.embed(content, credential, aiConfig.embeddingModel);\n\n // 存储向量\n await this.upsertVector(aiConfig.embeddingModel, vectorId, embedding, accessToken);\n\n // 更新索引记录为 completed\n await db.update(IndexedFile).set({\n status: FileIndexStatus.COMPLETED,\n usageBytes: content.length,\n lastError: null,\n }).where(eq(IndexedFile.id, fileIndexId));\n\n this.logger.info(`Indexed file ${fileUrl} with model ${aiConfig.embeddingModel}`);\n\n return { id: fileIndexId, status: 'completed', vectorId };\n } catch (error) {\n // 更新索引记录为 failed\n const errorMsg = error instanceof Error ? error.message : String(error);\n await db.update(IndexedFile).set({\n status: FileIndexStatus.FAILED,\n lastError: errorMsg,\n }).where(eq(IndexedFile.id, fileIndexId));\n\n this.logger.error(`Failed to index file ${fileUrl}: ${errorMsg}`);\n throw error;\n }\n }\n\n /**\n * 获取文件应使用的分块策略(查找最近的父级 VectorStore)\n */\n private async getChunkingStrategyForFile(fileUrl: string, auth: AuthContext): Promise<string> {\n const db = await this.getPodDb(auth);\n if (!db) return ChunkingStrategy.AUTO;\n\n // 获取所有 VectorStore\n const allStores = await db.select().from(VectorStore);\n\n // 找到所有是 fileUrl 前缀的 VectorStore\n const matchedStores = allStores.filter(store => {\n if (!store.container) return false;\n const containerUrl = store.container.endsWith('/') ? store.container : store.container + '/';\n return fileUrl.startsWith(containerUrl);\n });\n\n if (matchedStores.length === 0) {\n return ChunkingStrategy.AUTO;\n }\n\n // 找最长前缀(最近的父级)\n matchedStores.sort((a, b) => (b.container?.length || 0) - (a.container?.length || 0));\n return matchedStores[0].chunkingStrategy || ChunkingStrategy.AUTO;\n }\n\n /**\n * 删除文件索引(由 webhook 调用)\n */\n public async removeFileIndex(\n fileUrl: string,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ deleted: boolean }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 获取全局 AI 配置\n const aiConfig = await this.getAIConfig(auth);\n if (!aiConfig) {\n this.logger.warn(`No AI config found, cannot delete vector for ${fileUrl}`);\n return { deleted: false };\n }\n\n // 查找文件索引记录\n const files = await db.select().from(IndexedFile).where(\n eq(IndexedFile.fileUrl, fileUrl),\n );\n\n if (files.length === 0) {\n this.logger.warn(`File index record not found for ${fileUrl}`);\n return { deleted: false };\n }\n\n const fileRecord = files[0];\n\n // 从向量存储中删除\n if (fileRecord.vectorId) {\n await this.deleteVector(aiConfig.embeddingModel, fileRecord.vectorId, accessToken);\n }\n\n // 删除索引记录\n await db.delete(IndexedFile).where(eq(IndexedFile.id, fileRecord.id));\n\n this.logger.info(`Removed file index ${fileUrl}`);\n return { deleted: true };\n }\n\n /**\n * 获取 Container 下的 file_counts 统计(基于 fileUrl 前缀匹配)\n */\n public async getFileCounts(\n containerUrl: string,\n auth: AuthContext,\n ): Promise<{ in_progress: number; completed: number; failed: number; cancelled: number; total: number }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n return { in_progress: 0, completed: 0, failed: 0, cancelled: 0, total: 0 };\n }\n\n // 获取所有索引文件,过滤属于该 Container 的\n const allFiles = await db.select().from(IndexedFile);\n const containerPrefix = containerUrl.endsWith('/') ? containerUrl : containerUrl + '/';\n const files = allFiles.filter(f => f.fileUrl?.startsWith(containerPrefix));\n\n const counts = {\n in_progress: 0,\n completed: 0,\n failed: 0,\n cancelled: 0,\n total: files.length,\n };\n\n for (const file of files) {\n switch (file.status) {\n case FileIndexStatus.IN_PROGRESS:\n counts.in_progress++;\n break;\n case FileIndexStatus.COMPLETED:\n counts.completed++;\n break;\n case FileIndexStatus.FAILED:\n counts.failed++;\n break;\n case FileIndexStatus.CANCELLED:\n counts.cancelled++;\n break;\n }\n }\n\n return counts;\n }\n\n /**\n * 通过 vectorId 查找文件 URL(供 search 使用)\n * 注意:文件只索引一份,用 vectorId 即可查找\n */\n public async getFileUrlByVectorId(\n vectorId: number,\n auth: AuthContext,\n ): Promise<string | null> {\n const db = await this.getPodDb(auth);\n if (!db) return null;\n\n const files = await db.select().from(IndexedFile).where(\n eq(IndexedFile.vectorId, vectorId),\n );\n\n return files.length > 0 ? files[0].fileUrl : null;\n }\n\n /**\n * 根据 Container URL 查找 VectorStore\n */\n public async findVectorStoreByContainer(\n containerUrl: string,\n auth: AuthContext,\n ): Promise<VectorStoreObject | null> {\n const db = await this.getPodDb(auth);\n if (!db) return null;\n\n const stores = await db.select().from(VectorStore).where(\n eq(VectorStore.container, containerUrl),\n );\n\n if (stores.length === 0) return null;\n\n const store = stores[0];\n return this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n });\n }\n\n /**\n * 根据文件 URL 查找所有匹配的 VectorStore(包括父级容器)\n *\n * 例如:文件 https://alice.pod/A/B/c.txt 会匹配:\n * - https://alice.pod/A/B/ (直接父级)\n * - https://alice.pod/A/ (祖先级)\n * - https://alice.pod/ (Pod 根)\n *\n * 这样文件可以被索引到多个知识库中\n */\n public async findVectorStoresByFileUrl(\n fileUrl: string,\n auth: AuthContext,\n ): Promise<VectorStoreObject[]> {\n const db = await this.getPodDb(auth);\n if (!db) return [];\n\n // 获取所有 VectorStore\n const allStores = await db.select().from(VectorStore);\n\n // 过滤出 container 是 fileUrl 前缀的 VectorStore\n const matchedStores = allStores.filter(store => {\n if (!store.container) return false;\n // 确保 container URL 以 / 结尾\n const containerUrl = store.container.endsWith('/') ? store.container : store.container + '/';\n return fileUrl.startsWith(containerUrl);\n });\n\n // 转换为 VectorStoreObject\n return matchedStores.map(store => this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n }));\n }\n\n // ============================================\n // Search\n // ============================================\n\n /**\n * 搜索 Vector Store\n */\n public async search(\n vectorStoreId: string,\n request: SearchRequest,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ object: 'vector_store.search_results.page'; search_query: string; data: SearchResult[]; has_more: boolean }> {\n const store = await this.getVectorStore(vectorStoreId, auth);\n\n // 获取 AI credential\n const credential = await this.getAiCredential(auth);\n if (!credential) {\n throw new Error('No AI credential found');\n }\n\n // 获取全局 AI 配置中的 embedding model\n const aiConfig = await this.getAIConfig(auth);\n if (!aiConfig?.embeddingModel) {\n throw new Error('No embedding model configured. Please set up AI configuration first.');\n }\n\n const queryText = Array.isArray(request.query) ? request.query.join(' ') : request.query;\n\n // 生成 query embedding(使用全局模型)\n const queryEmbedding = await this.embeddingService.embed(queryText, credential, aiConfig.embeddingModel);\n\n // 调用 CSS vector search,使用 subjectPrefix 过滤只搜索该 VectorStore 的文件\n const limit = request.max_num_results || 10;\n const results = await this.searchVectors(aiConfig.embeddingModel, queryEmbedding, limit, accessToken, {\n subjectPrefix: store.url, // Container URL 作为 subject 前缀\n });\n\n // 构建搜索结果,使用 vectorId -> fileUrl 映射\n const searchResults: SearchResult[] = [];\n for (const r of results) {\n const vectorId = typeof r.id === 'number' ? r.id : parseInt(String(r.id), 10);\n const fileUrl = await this.getFileUrlByVectorId(vectorId, auth);\n\n searchResults.push({\n file_id: String(r.id),\n file_url: fileUrl || '',\n filename: fileUrl ? this.extractFilename(fileUrl) : '',\n score: r.score,\n attributes: {},\n content: [], // TODO: 可选返回内容片段\n });\n }\n\n return {\n object: 'vector_store.search_results.page',\n search_query: queryText,\n data: searchResults,\n has_more: false,\n };\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private generateId(): string {\n return `vs_${randomBytes(12).toString('hex')}`;\n }\n\n /**\n * Hash subject + aspect 为向量 ID(供 webhook 索引使用)\n */\n public hashSubjectAspect(subject: string, aspect: string): number {\n const str = `${subject}|${aspect}`;\n let hash = 2166136261;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return Math.abs(hash);\n }\n\n private extractContainerName(url: string): string {\n const parts = url.replace(/\\/$/, '').split('/');\n return parts[parts.length - 1] || 'Unnamed';\n }\n\n private extractFilename(url: string): string {\n const parts = url.split('/');\n return parts[parts.length - 1] || '';\n }\n\n private extractModelId(uri: string): string {\n const hashIndex = uri.lastIndexOf('#');\n if (hashIndex !== -1) {\n return uri.slice(hashIndex + 1);\n }\n return uri;\n }\n\n private getPodBaseUrl(webId: string): string {\n const url = new URL(webId);\n url.hash = '';\n let path = url.pathname;\n if (path.endsWith('/profile/card')) {\n path = path.slice(0, -'/profile/card'.length);\n }\n if (!path.endsWith('/')) {\n path = path + '/';\n }\n return `${url.origin}${path}`;\n }\n\n private buildVectorStoreObject(\n id: string,\n data: {\n name: string;\n containerUrl: string;\n chunkingStrategy: string;\n status: 'in_progress' | 'completed' | 'expired';\n createdAt: Date;\n lastActiveAt: Date | null;\n fileCounts?: { in_progress: number; completed: number; failed: number; cancelled: number; total: number };\n usageBytes?: number;\n },\n ): VectorStoreObject {\n return {\n id,\n object: 'vector_store',\n created_at: Math.floor(data.createdAt.getTime() / 1000),\n name: data.name,\n status: data.status,\n usage_bytes: data.usageBytes || 0,\n file_counts: data.fileCounts || {\n in_progress: 0,\n completed: 0,\n failed: 0,\n cancelled: 0,\n total: 0,\n },\n last_active_at: data.lastActiveAt ? Math.floor(data.lastActiveAt.getTime() / 1000) : null,\n metadata: {},\n url: data.containerUrl,\n chunking_strategy: data.chunkingStrategy,\n };\n }\n\n private async getPodDb(auth: AuthContext) {\n if (!isSolidAuth(auth) || !auth.clientId || !auth.clientSecret) {\n this.logger.debug('No clientId or clientSecret in auth context');\n return null;\n }\n\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 });\n\n if (!session.info.isLoggedIn || !session.info.webId) {\n throw new Error('Login failed');\n }\n\n return drizzle({ fetch: session.fetch, info: { webId: session.info.webId, isLoggedIn: true } } as any, { schema });\n } catch (error) {\n this.logger.error(`Failed to login: ${error}`);\n return null;\n }\n }\n\n private async getAiCredential(auth: AuthContext): Promise<AiCredential | undefined> {\n const db = await this.getPodDb(auth);\n if (!db) return undefined;\n\n try {\n const credentials = await db.select().from(Credential).where(\n eq(Credential.service, ServiceType.AI),\n );\n\n const activeCred = credentials.find(c => c.status === CredentialStatus.ACTIVE);\n if (!activeCred || !activeCred.apiKey) return undefined;\n\n // 获取 provider 信息\n let baseUrl: string | undefined;\n let proxyUrl: string | undefined;\n\n if (activeCred.provider) {\n const providers = await db.select().from(Provider);\n const provider = providers.find(p => activeCred.provider?.includes(p.id));\n if (provider) {\n baseUrl = provider.baseUrl || undefined;\n proxyUrl = provider.proxyUrl || undefined;\n }\n }\n\n return {\n provider: activeCred.id,\n apiKey: activeCred.apiKey,\n baseUrl: activeCred.baseUrl || baseUrl,\n proxyUrl,\n };\n } catch (error) {\n this.logger.error(`Failed to get AI credential: ${error}`);\n return undefined;\n }\n }\n\n /**\n * 获取 Pod 级别的 AI 配置(全局 embedding model)\n */\n public async getAIConfig(auth: AuthContext): Promise<PodAIConfig | null> {\n const db = await this.getPodDb(auth);\n if (!db) return null;\n\n try {\n const configs = await db.select().from(AIConfig);\n const config = configs.find(c => c.id === 'config');\n\n if (!config || !config.embeddingModel) {\n // 如果没有配置,尝试使用默认模型\n const models = await db.select().from(Model);\n const defaultModel = models.find(m => m.modelType === 'embedding') || models[0];\n if (defaultModel) {\n return {\n embeddingModel: defaultModel.id,\n migrationStatus: 'idle',\n };\n }\n return null;\n }\n\n return {\n embeddingModel: this.extractModelId(config.embeddingModel),\n migrationStatus: (config.migrationStatus as any) || 'idle',\n previousModel: config.previousModel ? this.extractModelId(config.previousModel) : undefined,\n migrationProgress: config.migrationProgress || undefined,\n };\n } catch (error) {\n this.logger.error(`Failed to get AI config: ${error}`);\n return null;\n }\n }\n\n /**\n * 设置全局 embedding model\n * 如果更换了模型,自动触发迁移(后台重新索引所有文件)\n */\n public async setEmbeddingModel(\n newModel: string,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ success: boolean; migrationTriggered: boolean; message: string }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n const currentConfig = await this.getAIConfig(auth);\n const currentModel = currentConfig?.embeddingModel;\n\n // 检查模型是否有变化\n const modelChanged = currentModel && currentModel !== newModel;\n\n const webId = getWebId(auth) ?? getAccountId(auth) ?? '';\n const podBaseUrl = this.getPodBaseUrl(webId);\n const modelUri = `${podBaseUrl}settings/ai/models.ttl#${newModel}`;\n\n try {\n // 检查配置是否已存在\n const configs = await db.select().from(AIConfig);\n const existingConfig = configs.find(c => c.id === 'config');\n\n if (existingConfig) {\n // 更新现有配置\n await db.update(AIConfig).set({\n embeddingModel: modelUri,\n previousModel: modelChanged ? `${podBaseUrl}settings/ai/models.ttl#${currentModel}` : existingConfig.previousModel,\n migrationStatus: modelChanged ? MigrationStatus.IN_PROGRESS : existingConfig.migrationStatus,\n migrationProgress: modelChanged ? 0 : existingConfig.migrationProgress,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n } else {\n // 创建新配置\n await db.insert(AIConfig).values({\n id: 'config',\n embeddingModel: modelUri,\n migrationStatus: MigrationStatus.IDLE,\n migrationProgress: 0,\n updatedAt: new Date(),\n });\n }\n\n this.logger.info(`Set embedding model to ${newModel}`);\n\n // 如果模型变化,在后台启动迁移\n if (modelChanged) {\n this.logger.info(`Model changed from ${currentModel} to ${newModel}, triggering migration`);\n // 异步执行迁移,不阻塞响应\n this.startMigration(auth, accessToken).catch(error => {\n this.logger.error(`Migration failed: ${error}`);\n });\n }\n\n return {\n success: true,\n migrationTriggered: modelChanged === true,\n message: modelChanged\n ? `Model updated to ${newModel}. Migration started to re-index all files.`\n : `Model set to ${newModel}.`,\n };\n } catch (error) {\n this.logger.error(`Failed to set embedding model: ${error}`);\n throw error;\n }\n }\n\n /**\n * 开始迁移:重新索引所有文件\n */\n private async startMigration(auth: AuthContext, accessToken: string): Promise<void> {\n const db = await this.getPodDb(auth);\n if (!db) return;\n\n try {\n // 获取所有已索引的文件\n const allFiles = await db.select().from(IndexedFile);\n const totalFiles = allFiles.length;\n\n if (totalFiles === 0) {\n // 无文件需要迁移\n await db.update(AIConfig).set({\n migrationStatus: MigrationStatus.COMPLETED,\n migrationProgress: 100,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n return;\n }\n\n this.logger.info(`Starting migration for ${totalFiles} files`);\n\n let completedFiles = 0;\n let failedFiles = 0;\n\n for (const file of allFiles) {\n try {\n // 重新索引每个文件\n await this.indexFile(file.fileUrl, auth, accessToken);\n completedFiles++;\n } catch (error) {\n failedFiles++;\n this.logger.error(`Failed to re-index ${file.fileUrl}: ${error}`);\n }\n\n // 更新迁移进度\n const progress = Math.round(((completedFiles + failedFiles) / totalFiles) * 100);\n await db.update(AIConfig).set({\n migrationProgress: progress,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n }\n\n // 标记迁移完成\n const finalStatus = failedFiles === 0 ? MigrationStatus.COMPLETED : MigrationStatus.FAILED;\n await db.update(AIConfig).set({\n migrationStatus: finalStatus,\n migrationProgress: 100,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n\n this.logger.info(`Migration completed: ${completedFiles} success, ${failedFiles} failed`);\n } catch (error) {\n this.logger.error(`Migration error: ${error}`);\n await db.update(AIConfig).set({\n migrationStatus: MigrationStatus.FAILED,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n }\n }\n\n /**\n * 获取资源内容(供 webhook 索引使用)\n */\n public async fetchResourceContent(url: string, accessToken: string): Promise<string> {\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'text/turtle, application/ld+json, text/plain, text/markdown, text/html, */*',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}: ${response.status}`);\n }\n\n const contentType = response.headers.get('Content-Type') || '';\n const body = await response.text();\n return this.extractText(body, contentType);\n }\n\n private extractText(body: string, contentType: string): string {\n const ct = contentType.toLowerCase();\n\n if (ct.includes('text/turtle') || ct.includes('application/n-triples')) {\n return this.extractTextFromTurtle(body);\n }\n if (ct.includes('application/ld+json') || ct.includes('application/json')) {\n return this.extractTextFromJsonLd(body);\n }\n if (ct.includes('text/html')) {\n return this.extractTextFromHtml(body);\n }\n return body;\n }\n\n private extractTextFromTurtle(turtle: string): string {\n const literals: string[] = [];\n const tripleQuoteRegex = /\"\"\"([^]*?)\"\"\"/g;\n const singleQuoteRegex = /\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"/g;\n\n let match;\n while ((match = tripleQuoteRegex.exec(turtle)) !== null) {\n if (match[1].trim().length > 0) literals.push(match[1].trim());\n }\n\n const withoutTriple = turtle.replace(/\"\"\"[^]*?\"\"\"/g, '');\n while ((match = singleQuoteRegex.exec(withoutTriple)) !== null) {\n const value = match[1].trim();\n if (value.length > 3 && !value.startsWith('http') && !value.startsWith('urn:')) {\n literals.push(value);\n }\n }\n return literals.join('\\n');\n }\n\n private extractTextFromJsonLd(jsonStr: string): string {\n try {\n const json = JSON.parse(jsonStr);\n const texts: string[] = [];\n const extract = (obj: any): void => {\n if (typeof obj === 'string' && obj.length > 3 && !obj.startsWith('http')) {\n texts.push(obj);\n } else if (Array.isArray(obj)) {\n obj.forEach(extract);\n } else if (obj && typeof obj === 'object') {\n for (const [key, value] of Object.entries(obj)) {\n if (!key.startsWith('@')) extract(value);\n }\n }\n };\n extract(json);\n return texts.join('\\n');\n } catch {\n return jsonStr;\n }\n }\n\n private extractTextFromHtml(html: string): string {\n let text = html.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '');\n text = text.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '');\n text = text.replace(/<[^>]+>/g, ' ');\n text = text.replace(/\\s+/g, ' ').trim();\n return text;\n }\n\n /**\n * Upsert 向量到 CSS(供 webhook 索引使用)\n */\n public async upsertVector(model: string, id: number, vector: number[], accessToken: string): Promise<void> {\n const url = `${this.cssBaseUrl}/-/vector/upsert`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({ model, vectors: [{ id, vector }] }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Vector upsert failed: ${response.status} ${errorText}`);\n }\n }\n\n /**\n * 删除向量(供 webhook 索引使用)\n */\n public async deleteVector(model: string, id: number, accessToken: string): Promise<void> {\n const url = `${this.cssBaseUrl}/-/vector/delete`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({ model, ids: [id] }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Vector delete failed: ${response.status} ${errorText}`);\n }\n }\n\n private async searchVectors(\n model: string,\n vector: number[],\n limit: number,\n accessToken: string,\n options?: { subjectPrefix?: string },\n ): Promise<any[]> {\n const url = `${this.cssBaseUrl}/-/vector/search`;\n \n const body: Record<string, any> = { model, vector, limit };\n \n // 添加 subject 前缀过滤(限定搜索范围到特定 Container)\n if (options?.subjectPrefix) {\n body.filter = {\n subject: { $startsWith: options.subjectPrefix },\n };\n }\n \n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Vector search failed: ${response.status}`);\n }\n\n const data = await response.json() as { results?: any[] };\n return data.results || [];\n }\n\n // ============================================\n // Webhook Subscription\n // ============================================\n\n /**\n * 订阅 Container 的变更通知(WebhookChannel2023)\n *\n * @param containerUrl Container URL\n * @param accessToken 访问令牌\n */\n private async subscribeToContainer(containerUrl: string, accessToken: string): Promise<void> {\n if (!this.webhookUrl) {\n throw new Error('Webhook URL not configured');\n }\n\n // 1. 发现订阅端点\n const subscriptionEndpoint = await this.discoverNotificationEndpoint(containerUrl, accessToken);\n if (!subscriptionEndpoint) {\n throw new Error(`No notification endpoint found for ${containerUrl}`);\n }\n\n // 2. 创建 webhook 订阅\n const subscriptionRequest = {\n '@context': ['https://www.w3.org/ns/solid/notification/v1'],\n type: 'WebhookChannel2023',\n topic: containerUrl,\n sendTo: this.webhookUrl,\n };\n\n const response = await fetch(subscriptionEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/ld+json',\n Accept: 'application/ld+json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(subscriptionRequest),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Subscription failed: ${response.status} ${errorText}`);\n }\n\n const result = await response.json();\n this.logger.info(`Created webhook subscription: ${JSON.stringify(result)}`);\n }\n\n /**\n * 发现 Solid Notification 端点\n *\n * 通过 HEAD 请求获取 Link header 中的 describedby,然后获取订阅端点\n */\n private async discoverNotificationEndpoint(resourceUrl: string, accessToken: string): Promise<string | null> {\n // 方法 1:直接使用已知的 CSS 端点格式\n // CSS 的 webhook 订阅端点通常是 /.notifications/WebhookChannel2023/\n const url = new URL(resourceUrl);\n const webhookEndpoint = `${url.origin}/.notifications/WebhookChannel2023/`;\n\n // 验证端点是否存在\n try {\n const response = await fetch(webhookEndpoint, {\n method: 'GET',\n headers: {\n Accept: 'application/ld+json',\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (response.ok) {\n return webhookEndpoint;\n }\n } catch {\n // 忽略错误,尝试其他方法\n }\n\n // 方法 2:通过 describedby Link header 发现\n try {\n const headResponse = await fetch(resourceUrl, {\n method: 'HEAD',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n const linkHeader = headResponse.headers.get('Link');\n if (linkHeader) {\n // 解析 Link header 找 describedby\n const describedBy = this.parseLinkHeader(linkHeader, 'describedby');\n if (describedBy) {\n // 获取 describedby 资源,解析通知端点\n const descResponse = await fetch(describedBy, {\n headers: {\n Accept: 'application/ld+json',\n Authorization: `Bearer ${accessToken}`,\n },\n });\n if (descResponse.ok) {\n const desc = await descResponse.json() as any;\n // 查找 notify:subscription 或类似属性\n const subscription = desc['notify:subscription'] || desc['subscription'];\n if (subscription) {\n return typeof subscription === 'string' ? subscription : subscription['@id'];\n }\n }\n }\n }\n } catch {\n // 忽略错误\n }\n\n return null;\n }\n\n /**\n * 解析 Link header\n */\n private parseLinkHeader(linkHeader: string, rel: string): string | null {\n const links = linkHeader.split(',');\n for (const link of links) {\n const match = link.match(/<([^>]+)>.*rel=\"?([^\";]+)\"?/);\n if (match && match[2] === rel) {\n return match[1];\n }\n }\n return null;\n }\n}\n"]}
1
+ {"version":3,"file":"VectorStoreService.js","sourceRoot":"","sources":["../../../src/api/service/VectorStoreService.ts"],"names":[],"mappings":"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","sourcesContent":["import { getLoggerFor } from 'global-logger-factory';\nimport { drizzle, eq } from '@undefineds.co/drizzle-solid';\nimport { randomBytes } from 'crypto';\nimport type { AuthContext } from '../auth/AuthContext';\nimport { getWebId, getAccountId, isSolidAuth } from '../auth/AuthContext';\nimport type { EmbeddingService } from '../../ai/service/EmbeddingService';\nimport type { AiCredential } from '../../ai/service/types';\nimport { Session } from '@inrupt/solid-client-authn-node';\n\nimport {\n AIConfig,\n VectorStore,\n IndexedFile,\n Model,\n Provider,\n VectorStoreStatus,\n ChunkingStrategy,\n FileIndexStatus,\n MigrationStatus,\n} from '../../ai/schema';\nimport { Credential } from '../../credential/schema/tables';\nimport { ServiceType, CredentialStatus } from '../../credential/schema/types';\n\nconst schema = {\n aiConfig: AIConfig,\n vectorStore: VectorStore,\n indexedFile: IndexedFile,\n model: Model,\n provider: Provider,\n credential: Credential,\n};\n\n// ============================================\n// Types - OpenAI Compatible\n// ============================================\n\n/**\n * 创建 Vector Store 请求\n */\nexport interface CreateVectorStoreRequest {\n /** 知识库名称 */\n name?: string;\n /** Container URL */\n url: string;\n /** Chunking 策略 */\n chunking_strategy?: 'auto' | 'static';\n /** 元数据 */\n metadata?: Record<string, string>;\n}\n\n/**\n * 修改 Vector Store 请求\n */\nexport interface ModifyVectorStoreRequest {\n name?: string;\n chunking_strategy?: 'auto' | 'static';\n metadata?: Record<string, string>;\n}\n\n/**\n * Vector Store 对象(OpenAI 兼容格式)\n */\nexport interface VectorStoreObject {\n id: string;\n object: 'vector_store';\n created_at: number;\n name: string;\n status: 'in_progress' | 'completed' | 'expired';\n usage_bytes: number;\n file_counts: {\n in_progress: number;\n completed: number;\n failed: number;\n cancelled: number;\n total: number;\n };\n last_active_at: number | null;\n metadata: Record<string, string>;\n // Xpod 扩展字段\n url: string;\n chunking_strategy: string;\n}\n\n/**\n * Pod AI 配置\n */\nexport interface PodAIConfig {\n embeddingModel: string;\n migrationStatus: 'idle' | 'in_progress' | 'completed' | 'failed';\n previousModel?: string;\n migrationProgress?: number;\n}\n\n/**\n * 搜索请求\n */\nexport interface SearchRequest {\n query: string | string[];\n max_num_results?: number;\n filters?: Record<string, any>;\n ranking_options?: {\n ranker?: string;\n score_threshold?: number;\n };\n rewrite_query?: boolean;\n}\n\n/**\n * 搜索结果\n */\nexport interface SearchResult {\n file_id: string;\n file_url: string;\n filename: string;\n score: number;\n attributes: Record<string, any>;\n content: Array<{ type: 'text'; text: string }>;\n}\n\nexport interface VectorStoreServiceOptions {\n /** CSS base URL */\n cssBaseUrl: string;\n /** Token endpoint for login */\n tokenEndpoint: string;\n /** Embedding service */\n embeddingService: EmbeddingService;\n /** Webhook URL for receiving notifications (optional) */\n webhookUrl?: string;\n}\n\n/**\n * VectorStoreService - 知识库管理服务\n *\n * 提供 OpenAI 兼容的 Vector Store API\n */\nexport class VectorStoreService {\n private readonly logger = getLoggerFor(this);\n private readonly cssBaseUrl: string;\n private readonly tokenEndpoint: string;\n private readonly embeddingService: EmbeddingService;\n private readonly webhookUrl?: string;\n\n public constructor(options: VectorStoreServiceOptions) {\n this.cssBaseUrl = options.cssBaseUrl.replace(/\\/$/, '');\n this.tokenEndpoint = options.tokenEndpoint;\n this.embeddingService = options.embeddingService;\n this.webhookUrl = options.webhookUrl;\n }\n\n // ============================================\n // Vector Store CRUD\n // ============================================\n\n /**\n * 创建 Vector Store(配置文件夹为知识库)\n */\n public async createVectorStore(\n request: CreateVectorStoreRequest,\n auth: AuthContext,\n accessToken?: string,\n ): Promise<VectorStoreObject> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 生成 ID\n const id = this.generateId();\n const now = new Date();\n const containerUri = request.url;\n\n // 插入记录(不再存储 model,model 从全局配置获取)\n await db.insert(VectorStore).values({\n id,\n name: request.name || this.extractContainerName(containerUri),\n container: containerUri,\n chunkingStrategy: request.chunking_strategy || ChunkingStrategy.AUTO,\n status: VectorStoreStatus.COMPLETED,\n createdAt: now,\n lastActiveAt: now,\n });\n\n this.logger.info(`Created vector store ${id} for container ${containerUri}`);\n\n // 尝试注册 webhook 订阅(如果配置了 webhookUrl)\n if (this.webhookUrl && accessToken) {\n try {\n await this.subscribeToContainer(containerUri, accessToken);\n this.logger.info(`Subscribed to container ${containerUri} for webhook notifications`);\n } catch (error) {\n // 订阅失败不影响 VectorStore 创建,只记录警告\n this.logger.warn(`Failed to subscribe to container ${containerUri}: ${error}`);\n }\n }\n\n return this.buildVectorStoreObject(id, {\n name: request.name || this.extractContainerName(containerUri),\n containerUrl: containerUri,\n chunkingStrategy: request.chunking_strategy || 'auto',\n status: 'completed',\n createdAt: now,\n lastActiveAt: now,\n });\n }\n\n /**\n * 列出所有 Vector Store\n */\n public async listVectorStores(\n auth: AuthContext,\n options?: { limit?: number; order?: 'asc' | 'desc'; after?: string; before?: string },\n ): Promise<{ object: 'list'; data: VectorStoreObject[]; has_more: boolean }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n const stores = await db.select().from(VectorStore);\n\n // 排序\n const order = options?.order || 'desc';\n stores.sort((a, b) => {\n const aTime = a.createdAt?.getTime() || 0;\n const bTime = b.createdAt?.getTime() || 0;\n return order === 'desc' ? bTime - aTime : aTime - bTime;\n });\n\n // 分页\n const limit = options?.limit || 20;\n const data = stores.slice(0, limit).map(store => this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n }));\n\n return {\n object: 'list',\n data,\n has_more: stores.length > limit,\n };\n }\n\n /**\n * 获取单个 Vector Store\n */\n public async getVectorStore(id: string, auth: AuthContext): Promise<VectorStoreObject> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n const stores = await db.select().from(VectorStore).where(eq(VectorStore.id, id));\n if (stores.length === 0) {\n throw new Error(`Vector store ${id} not found`);\n }\n\n const store = stores[0];\n\n // 获取 file_counts(基于 Container 前缀匹配)\n const fileCounts = await this.getFileCounts(store.container || '', auth);\n\n return this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n fileCounts,\n });\n }\n\n /**\n * 修改 Vector Store\n */\n public async modifyVectorStore(\n id: string,\n request: ModifyVectorStoreRequest,\n auth: AuthContext,\n ): Promise<VectorStoreObject> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 构建更新数据(不再支持修改 model,model 是全局配置)\n const updates: Partial<typeof VectorStore.$inferInsert> = {};\n if (request.name !== undefined) updates.name = request.name;\n if (request.chunking_strategy !== undefined) updates.chunkingStrategy = request.chunking_strategy;\n\n await db.update(VectorStore).set(updates).where(eq(VectorStore.id, id));\n\n return this.getVectorStore(id, auth);\n }\n\n /**\n * 删除 Vector Store\n */\n public async deleteVectorStore(\n id: string,\n auth: AuthContext,\n ): Promise<{ id: string; object: 'vector_store.deleted'; deleted: boolean }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n await db.delete(VectorStore).where(eq(VectorStore.id, id));\n\n this.logger.info(`Deleted vector store ${id}`);\n\n return {\n id,\n object: 'vector_store.deleted',\n deleted: true,\n };\n }\n\n // ============================================\n // File Index Management (for webhook)\n // ============================================\n\n /**\n * 索引文件(由 webhook 调用)\n *\n * @param vectorStoreId Vector Store ID\n * @param fileUrl 文件 URL\n * @param auth 认证上下文\n * @param accessToken 访问令牌\n */\n public async indexFile(\n fileUrl: string,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ id: string; status: string; vectorId: number }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 获取全局 AI 配置(embedding model)\n const aiConfig = await this.getAIConfig(auth);\n if (!aiConfig) {\n throw new Error('No AI configuration found. Please configure an embedding model first.');\n }\n\n // 查找最近的父级 VectorStore 获取分块策略\n const chunkingStrategy = await this.getChunkingStrategyForFile(fileUrl, auth);\n\n // 检查文件是否已索引\n const existingFiles = await db.select().from(IndexedFile).where(\n eq(IndexedFile.fileUrl, fileUrl),\n );\n\n const vectorId = this.hashSubjectAspect(fileUrl, 'content');\n let fileIndexId: string;\n\n if (existingFiles.length > 0) {\n // 文件已存在,更新状态\n fileIndexId = existingFiles[0].id;\n await db.update(IndexedFile).set({\n status: FileIndexStatus.IN_PROGRESS,\n chunkingStrategy,\n indexedAt: new Date(),\n }).where(eq(IndexedFile.id, fileIndexId));\n } else {\n // 创建新的索引记录\n fileIndexId = `idx_${randomBytes(8).toString('hex')}`;\n await db.insert(IndexedFile).values({\n id: fileIndexId,\n fileUrl,\n vectorId,\n chunkingStrategy,\n status: FileIndexStatus.IN_PROGRESS,\n usageBytes: 0,\n indexedAt: new Date(),\n });\n }\n\n try {\n // 获取 AI credential\n const credential = await this.getAiCredential(auth);\n if (!credential) {\n throw new Error('No AI credential found');\n }\n\n // 读取文件内容\n const content = await this.fetchResourceContent(fileUrl, accessToken);\n if (!content || content.trim().length === 0) {\n throw new Error(`File ${fileUrl} has no indexable content`);\n }\n\n // 生成 embedding(使用全局 model)\n const embedding = await this.embeddingService.embed(content, credential, aiConfig.embeddingModel);\n\n // 存储向量\n await this.upsertVector(aiConfig.embeddingModel, vectorId, embedding, accessToken);\n\n // 更新索引记录为 completed\n await db.update(IndexedFile).set({\n status: FileIndexStatus.COMPLETED,\n usageBytes: content.length,\n lastError: null,\n }).where(eq(IndexedFile.id, fileIndexId));\n\n this.logger.info(`Indexed file ${fileUrl} with model ${aiConfig.embeddingModel}`);\n\n return { id: fileIndexId, status: 'completed', vectorId };\n } catch (error) {\n // 更新索引记录为 failed\n const errorMsg = error instanceof Error ? error.message : String(error);\n await db.update(IndexedFile).set({\n status: FileIndexStatus.FAILED,\n lastError: errorMsg,\n }).where(eq(IndexedFile.id, fileIndexId));\n\n this.logger.error(`Failed to index file ${fileUrl}: ${errorMsg}`);\n throw error;\n }\n }\n\n /**\n * 获取文件应使用的分块策略(查找最近的父级 VectorStore)\n */\n private async getChunkingStrategyForFile(fileUrl: string, auth: AuthContext): Promise<string> {\n const db = await this.getPodDb(auth);\n if (!db) return ChunkingStrategy.AUTO;\n\n // 获取所有 VectorStore\n const allStores = await db.select().from(VectorStore);\n\n // 找到所有是 fileUrl 前缀的 VectorStore\n const matchedStores = allStores.filter(store => {\n if (!store.container) return false;\n const containerUrl = store.container.endsWith('/') ? store.container : store.container + '/';\n return fileUrl.startsWith(containerUrl);\n });\n\n if (matchedStores.length === 0) {\n return ChunkingStrategy.AUTO;\n }\n\n // 找最长前缀(最近的父级)\n matchedStores.sort((a, b) => (b.container?.length || 0) - (a.container?.length || 0));\n return matchedStores[0].chunkingStrategy || ChunkingStrategy.AUTO;\n }\n\n /**\n * 删除文件索引(由 webhook 调用)\n */\n public async removeFileIndex(\n fileUrl: string,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ deleted: boolean }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n // 获取全局 AI 配置\n const aiConfig = await this.getAIConfig(auth);\n if (!aiConfig) {\n this.logger.warn(`No AI config found, cannot delete vector for ${fileUrl}`);\n return { deleted: false };\n }\n\n // 查找文件索引记录\n const files = await db.select().from(IndexedFile).where(\n eq(IndexedFile.fileUrl, fileUrl),\n );\n\n if (files.length === 0) {\n this.logger.warn(`File index record not found for ${fileUrl}`);\n return { deleted: false };\n }\n\n const fileRecord = files[0];\n\n // 从向量存储中删除\n if (fileRecord.vectorId) {\n await this.deleteVector(aiConfig.embeddingModel, fileRecord.vectorId, accessToken);\n }\n\n // 删除索引记录\n await db.delete(IndexedFile).where(eq(IndexedFile.id, fileRecord.id));\n\n this.logger.info(`Removed file index ${fileUrl}`);\n return { deleted: true };\n }\n\n /**\n * 获取 Container 下的 file_counts 统计(基于 fileUrl 前缀匹配)\n */\n public async getFileCounts(\n containerUrl: string,\n auth: AuthContext,\n ): Promise<{ in_progress: number; completed: number; failed: number; cancelled: number; total: number }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n return { in_progress: 0, completed: 0, failed: 0, cancelled: 0, total: 0 };\n }\n\n // 获取所有索引文件,过滤属于该 Container 的\n const allFiles = await db.select().from(IndexedFile);\n const containerPrefix = containerUrl.endsWith('/') ? containerUrl : containerUrl + '/';\n const files = allFiles.filter(f => f.fileUrl?.startsWith(containerPrefix));\n\n const counts = {\n in_progress: 0,\n completed: 0,\n failed: 0,\n cancelled: 0,\n total: files.length,\n };\n\n for (const file of files) {\n switch (file.status) {\n case FileIndexStatus.IN_PROGRESS:\n counts.in_progress++;\n break;\n case FileIndexStatus.COMPLETED:\n counts.completed++;\n break;\n case FileIndexStatus.FAILED:\n counts.failed++;\n break;\n case FileIndexStatus.CANCELLED:\n counts.cancelled++;\n break;\n }\n }\n\n return counts;\n }\n\n /**\n * 通过 vectorId 查找文件 URL(供 search 使用)\n * 注意:文件只索引一份,用 vectorId 即可查找\n */\n public async getFileUrlByVectorId(\n vectorId: number,\n auth: AuthContext,\n ): Promise<string | null> {\n const db = await this.getPodDb(auth);\n if (!db) return null;\n\n const files = await db.select().from(IndexedFile).where(\n eq(IndexedFile.vectorId, vectorId),\n );\n\n return files.length > 0 ? files[0].fileUrl : null;\n }\n\n /**\n * 根据 Container URL 查找 VectorStore\n */\n public async findVectorStoreByContainer(\n containerUrl: string,\n auth: AuthContext,\n ): Promise<VectorStoreObject | null> {\n const db = await this.getPodDb(auth);\n if (!db) return null;\n\n const stores = await db.select().from(VectorStore).where(\n eq(VectorStore.container, containerUrl),\n );\n\n if (stores.length === 0) return null;\n\n const store = stores[0];\n return this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n });\n }\n\n /**\n * 根据文件 URL 查找所有匹配的 VectorStore(包括父级容器)\n *\n * 例如:文件 https://alice.pod/A/B/c.txt 会匹配:\n * - https://alice.pod/A/B/ (直接父级)\n * - https://alice.pod/A/ (祖先级)\n * - https://alice.pod/ (Pod 根)\n *\n * 这样文件可以被索引到多个知识库中\n */\n public async findVectorStoresByFileUrl(\n fileUrl: string,\n auth: AuthContext,\n ): Promise<VectorStoreObject[]> {\n const db = await this.getPodDb(auth);\n if (!db) return [];\n\n // 获取所有 VectorStore\n const allStores = await db.select().from(VectorStore);\n\n // 过滤出 container 是 fileUrl 前缀的 VectorStore\n const matchedStores = allStores.filter(store => {\n if (!store.container) return false;\n // 确保 container URL 以 / 结尾\n const containerUrl = store.container.endsWith('/') ? store.container : store.container + '/';\n return fileUrl.startsWith(containerUrl);\n });\n\n // 转换为 VectorStoreObject\n return matchedStores.map(store => this.buildVectorStoreObject(store.id, {\n name: store.name || '',\n containerUrl: store.container || '',\n chunkingStrategy: store.chunkingStrategy || 'auto',\n status: (store.status as any) || 'completed',\n createdAt: store.createdAt || new Date(),\n lastActiveAt: store.lastActiveAt || null,\n }));\n }\n\n // ============================================\n // Search\n // ============================================\n\n /**\n * 搜索 Vector Store\n */\n public async search(\n vectorStoreId: string,\n request: SearchRequest,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ object: 'vector_store.search_results.page'; search_query: string; data: SearchResult[]; has_more: boolean }> {\n const store = await this.getVectorStore(vectorStoreId, auth);\n\n // 获取 AI credential\n const credential = await this.getAiCredential(auth);\n if (!credential) {\n throw new Error('No AI credential found');\n }\n\n // 获取全局 AI 配置中的 embedding model\n const aiConfig = await this.getAIConfig(auth);\n if (!aiConfig?.embeddingModel) {\n throw new Error('No embedding model configured. Please set up AI configuration first.');\n }\n\n const queryText = Array.isArray(request.query) ? request.query.join(' ') : request.query;\n\n // 生成 query embedding(使用全局模型)\n const queryEmbedding = await this.embeddingService.embed(queryText, credential, aiConfig.embeddingModel);\n\n // 调用 CSS vector search,使用 subjectPrefix 过滤只搜索该 VectorStore 的文件\n const limit = request.max_num_results || 10;\n const results = await this.searchVectors(aiConfig.embeddingModel, queryEmbedding, limit, accessToken, {\n subjectPrefix: store.url, // Container URL 作为 subject 前缀\n });\n\n // 构建搜索结果,使用 vectorId -> fileUrl 映射\n const searchResults: SearchResult[] = [];\n for (const r of results) {\n const vectorId = typeof r.id === 'number' ? r.id : parseInt(String(r.id), 10);\n const fileUrl = await this.getFileUrlByVectorId(vectorId, auth);\n\n searchResults.push({\n file_id: String(r.id),\n file_url: fileUrl || '',\n filename: fileUrl ? this.extractFilename(fileUrl) : '',\n score: r.score,\n attributes: {},\n content: [], // TODO: 可选返回内容片段\n });\n }\n\n return {\n object: 'vector_store.search_results.page',\n search_query: queryText,\n data: searchResults,\n has_more: false,\n };\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private generateId(): string {\n return `vs_${randomBytes(12).toString('hex')}`;\n }\n\n /**\n * Hash subject + aspect 为向量 ID(供 webhook 索引使用)\n */\n public hashSubjectAspect(subject: string, aspect: string): number {\n const str = `${subject}|${aspect}`;\n let hash = 2166136261;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return Math.abs(hash);\n }\n\n private extractContainerName(url: string): string {\n const parts = url.replace(/\\/$/, '').split('/');\n return parts[parts.length - 1] || 'Unnamed';\n }\n\n private extractFilename(url: string): string {\n const parts = url.split('/');\n return parts[parts.length - 1] || '';\n }\n\n private extractModelId(uri: string): string {\n const hashIndex = uri.lastIndexOf('#');\n if (hashIndex !== -1) {\n return uri.slice(hashIndex + 1);\n }\n return uri;\n }\n\n private getPodBaseUrl(webId: string): string {\n const url = new URL(webId);\n url.hash = '';\n let path = url.pathname;\n if (path.endsWith('/profile/card')) {\n path = path.slice(0, -'/profile/card'.length);\n }\n if (!path.endsWith('/')) {\n path = path + '/';\n }\n return `${url.origin}${path}`;\n }\n\n private buildVectorStoreObject(\n id: string,\n data: {\n name: string;\n containerUrl: string;\n chunkingStrategy: string;\n status: 'in_progress' | 'completed' | 'expired';\n createdAt: Date;\n lastActiveAt: Date | null;\n fileCounts?: { in_progress: number; completed: number; failed: number; cancelled: number; total: number };\n usageBytes?: number;\n },\n ): VectorStoreObject {\n return {\n id,\n object: 'vector_store',\n created_at: Math.floor(data.createdAt.getTime() / 1000),\n name: data.name,\n status: data.status,\n usage_bytes: data.usageBytes || 0,\n file_counts: data.fileCounts || {\n in_progress: 0,\n completed: 0,\n failed: 0,\n cancelled: 0,\n total: 0,\n },\n last_active_at: data.lastActiveAt ? Math.floor(data.lastActiveAt.getTime() / 1000) : null,\n metadata: {},\n url: data.containerUrl,\n chunking_strategy: data.chunkingStrategy,\n };\n }\n\n private async getPodDb(auth: AuthContext) {\n if (!isSolidAuth(auth) || !auth.clientId || !auth.clientSecret) {\n this.logger.debug('No clientId or clientSecret in auth context');\n return null;\n }\n\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 });\n\n if (!session.info.isLoggedIn || !session.info.webId) {\n throw new Error('Login failed');\n }\n\n return drizzle({ fetch: session.fetch, info: { webId: session.info.webId, isLoggedIn: true } } as any, { schema });\n } catch (error) {\n this.logger.error(`Failed to login: ${error}`);\n return null;\n }\n }\n\n private async getAiCredential(auth: AuthContext): Promise<AiCredential | undefined> {\n const db = await this.getPodDb(auth);\n if (!db) return undefined;\n\n try {\n const credentials = await db.select().from(Credential).where(\n eq(Credential.service, ServiceType.AI),\n );\n\n const activeCred = credentials.find(c => c.status === CredentialStatus.ACTIVE);\n if (!activeCred || !activeCred.apiKey) return undefined;\n\n // 获取 provider 信息\n let baseUrl: string | undefined;\n let proxyUrl: string | undefined;\n\n if (activeCred.provider) {\n const providers = await db.select().from(Provider);\n const provider = providers.find(p => activeCred.provider?.includes(p.id));\n if (provider) {\n baseUrl = provider.baseUrl || undefined;\n proxyUrl = provider.proxyUrl || undefined;\n }\n }\n\n return {\n provider: activeCred.id,\n apiKey: activeCred.apiKey,\n baseUrl: activeCred.baseUrl || baseUrl,\n proxyUrl,\n };\n } catch (error) {\n this.logger.error(`Failed to get AI credential: ${error}`);\n return undefined;\n }\n }\n\n /**\n * 获取 Pod 级别的 AI 配置(全局 embedding model)\n */\n public async getAIConfig(auth: AuthContext): Promise<PodAIConfig | null> {\n const db = await this.getPodDb(auth);\n if (!db) return null;\n\n try {\n const configs = await db.select().from(AIConfig);\n const config = configs.find(c => c.id === 'config');\n\n if (!config || !config.embeddingModel) {\n // 如果没有配置,尝试使用默认模型\n const models = await db.select().from(Model);\n const defaultModel = models.find(m => m.modelType === 'embedding') || models[0];\n if (defaultModel) {\n return {\n embeddingModel: defaultModel.id,\n migrationStatus: 'idle',\n };\n }\n return null;\n }\n\n return {\n embeddingModel: this.extractModelId(config.embeddingModel),\n migrationStatus: (config.migrationStatus as any) || 'idle',\n previousModel: config.previousModel ? this.extractModelId(config.previousModel) : undefined,\n migrationProgress: config.migrationProgress || undefined,\n };\n } catch (error) {\n this.logger.error(`Failed to get AI config: ${error}`);\n return null;\n }\n }\n\n /**\n * 设置全局 embedding model\n * 如果更换了模型,自动触发迁移(后台重新索引所有文件)\n */\n public async setEmbeddingModel(\n newModel: string,\n auth: AuthContext,\n accessToken: string,\n ): Promise<{ success: boolean; migrationTriggered: boolean; message: string }> {\n const db = await this.getPodDb(auth);\n if (!db) {\n throw new Error('Failed to authenticate with Pod');\n }\n\n const currentConfig = await this.getAIConfig(auth);\n const currentModel = currentConfig?.embeddingModel;\n\n // 检查模型是否有变化\n const modelChanged = currentModel && currentModel !== newModel;\n\n const webId = getWebId(auth) ?? getAccountId(auth) ?? '';\n const podBaseUrl = this.getPodBaseUrl(webId);\n const modelUri = `${podBaseUrl}settings/ai/models.ttl#${newModel}`;\n\n try {\n // 检查配置是否已存在\n const configs = await db.select().from(AIConfig);\n const existingConfig = configs.find(c => c.id === 'config');\n\n if (existingConfig) {\n // 更新现有配置\n await db.update(AIConfig).set({\n embeddingModel: modelUri,\n previousModel: modelChanged ? `${podBaseUrl}settings/ai/models.ttl#${currentModel}` : existingConfig.previousModel,\n migrationStatus: modelChanged ? MigrationStatus.IN_PROGRESS : existingConfig.migrationStatus,\n migrationProgress: modelChanged ? 0 : existingConfig.migrationProgress,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n } else {\n // 创建新配置\n await db.insert(AIConfig).values({\n id: 'config',\n embeddingModel: modelUri,\n migrationStatus: MigrationStatus.IDLE,\n migrationProgress: 0,\n updatedAt: new Date(),\n });\n }\n\n this.logger.info(`Set embedding model to ${newModel}`);\n\n // 如果模型变化,在后台启动迁移\n if (modelChanged) {\n this.logger.info(`Model changed from ${currentModel} to ${newModel}, triggering migration`);\n // 异步执行迁移,不阻塞响应\n this.startMigration(auth, accessToken).catch(error => {\n this.logger.error(`Migration failed: ${error}`);\n });\n }\n\n return {\n success: true,\n migrationTriggered: modelChanged === true,\n message: modelChanged\n ? `Model updated to ${newModel}. Migration started to re-index all files.`\n : `Model set to ${newModel}.`,\n };\n } catch (error) {\n this.logger.error(`Failed to set embedding model: ${error}`);\n throw error;\n }\n }\n\n /**\n * 开始迁移:重新索引所有文件\n */\n private async startMigration(auth: AuthContext, accessToken: string): Promise<void> {\n const db = await this.getPodDb(auth);\n if (!db) return;\n\n try {\n // 获取所有已索引的文件\n const allFiles = await db.select().from(IndexedFile);\n const totalFiles = allFiles.length;\n\n if (totalFiles === 0) {\n // 无文件需要迁移\n await db.update(AIConfig).set({\n migrationStatus: MigrationStatus.COMPLETED,\n migrationProgress: 100,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n return;\n }\n\n this.logger.info(`Starting migration for ${totalFiles} files`);\n\n let completedFiles = 0;\n let failedFiles = 0;\n\n for (const file of allFiles) {\n try {\n // 重新索引每个文件\n await this.indexFile(file.fileUrl, auth, accessToken);\n completedFiles++;\n } catch (error) {\n failedFiles++;\n this.logger.error(`Failed to re-index ${file.fileUrl}: ${error}`);\n }\n\n // 更新迁移进度\n const progress = Math.round(((completedFiles + failedFiles) / totalFiles) * 100);\n await db.update(AIConfig).set({\n migrationProgress: progress,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n }\n\n // 标记迁移完成\n const finalStatus = failedFiles === 0 ? MigrationStatus.COMPLETED : MigrationStatus.FAILED;\n await db.update(AIConfig).set({\n migrationStatus: finalStatus,\n migrationProgress: 100,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n\n this.logger.info(`Migration completed: ${completedFiles} success, ${failedFiles} failed`);\n } catch (error) {\n this.logger.error(`Migration error: ${error}`);\n await db.update(AIConfig).set({\n migrationStatus: MigrationStatus.FAILED,\n updatedAt: new Date(),\n }).where(eq(AIConfig.id, 'config'));\n }\n }\n\n /**\n * 获取资源内容(供 webhook 索引使用)\n */\n public async fetchResourceContent(url: string, accessToken: string): Promise<string> {\n const response = await fetch(url, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: 'text/turtle, application/ld+json, text/plain, text/markdown, text/html, */*',\n },\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch ${url}: ${response.status}`);\n }\n\n const contentType = response.headers.get('Content-Type') || '';\n const body = await response.text();\n return this.extractText(body, contentType);\n }\n\n private extractText(body: string, contentType: string): string {\n const ct = contentType.toLowerCase();\n\n if (ct.includes('text/turtle') || ct.includes('application/n-triples')) {\n return this.extractTextFromTurtle(body);\n }\n if (ct.includes('application/ld+json') || ct.includes('application/json')) {\n return this.extractTextFromJsonLd(body);\n }\n if (ct.includes('text/html')) {\n return this.extractTextFromHtml(body);\n }\n return body;\n }\n\n private extractTextFromTurtle(turtle: string): string {\n const literals: string[] = [];\n const tripleQuoteRegex = /\"\"\"([^]*?)\"\"\"/g;\n const singleQuoteRegex = /\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"/g;\n\n let match;\n while ((match = tripleQuoteRegex.exec(turtle)) !== null) {\n if (match[1].trim().length > 0) literals.push(match[1].trim());\n }\n\n const withoutTriple = turtle.replace(/\"\"\"[^]*?\"\"\"/g, '');\n while ((match = singleQuoteRegex.exec(withoutTriple)) !== null) {\n const value = match[1].trim();\n if (value.length > 3 && !value.startsWith('http') && !value.startsWith('urn:')) {\n literals.push(value);\n }\n }\n return literals.join('\\n');\n }\n\n private extractTextFromJsonLd(jsonStr: string): string {\n try {\n const json = JSON.parse(jsonStr);\n const texts: string[] = [];\n const extract = (obj: any): void => {\n if (typeof obj === 'string' && obj.length > 3 && !obj.startsWith('http')) {\n texts.push(obj);\n } else if (Array.isArray(obj)) {\n obj.forEach(extract);\n } else if (obj && typeof obj === 'object') {\n for (const [key, value] of Object.entries(obj)) {\n if (!key.startsWith('@')) extract(value);\n }\n }\n };\n extract(json);\n return texts.join('\\n');\n } catch {\n return jsonStr;\n }\n }\n\n private extractTextFromHtml(html: string): string {\n let text = html.replace(/<script[^>]*>[\\s\\S]*?<\\/script>/gi, '');\n text = text.replace(/<style[^>]*>[\\s\\S]*?<\\/style>/gi, '');\n text = text.replace(/<[^>]+>/g, ' ');\n text = text.replace(/\\s+/g, ' ').trim();\n return text;\n }\n\n /**\n * Upsert 向量到 CSS(供 webhook 索引使用)\n */\n public async upsertVector(model: string, id: number, vector: number[], accessToken: string): Promise<void> {\n const url = `${this.cssBaseUrl}/-/vector/upsert`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({ model, vectors: [{ id, vector }] }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Vector upsert failed: ${response.status} ${errorText}`);\n }\n }\n\n /**\n * 删除向量(供 webhook 索引使用)\n */\n public async deleteVector(model: string, id: number, accessToken: string): Promise<void> {\n const url = `${this.cssBaseUrl}/-/vector/delete`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify({ model, ids: [id] }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Vector delete failed: ${response.status} ${errorText}`);\n }\n }\n\n private async searchVectors(\n model: string,\n vector: number[],\n limit: number,\n accessToken: string,\n options?: { subjectPrefix?: string },\n ): Promise<any[]> {\n const url = `${this.cssBaseUrl}/-/vector/search`;\n \n const body: Record<string, any> = { model, vector, limit };\n \n // 添加 subject 前缀过滤(限定搜索范围到特定 Container)\n if (options?.subjectPrefix) {\n body.filter = {\n subject: { $startsWith: options.subjectPrefix },\n };\n }\n \n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw new Error(`Vector search failed: ${response.status}`);\n }\n\n const data = await response.json() as { results?: any[] };\n return data.results || [];\n }\n\n // ============================================\n // Webhook Subscription\n // ============================================\n\n /**\n * 订阅 Container 的变更通知(WebhookChannel2023)\n *\n * @param containerUrl Container URL\n * @param accessToken 访问令牌\n */\n private async subscribeToContainer(containerUrl: string, accessToken: string): Promise<void> {\n if (!this.webhookUrl) {\n throw new Error('Webhook URL not configured');\n }\n\n // 1. 发现订阅端点\n const subscriptionEndpoint = await this.discoverNotificationEndpoint(containerUrl, accessToken);\n if (!subscriptionEndpoint) {\n throw new Error(`No notification endpoint found for ${containerUrl}`);\n }\n\n // 2. 创建 webhook 订阅\n const subscriptionRequest = {\n '@context': ['https://www.w3.org/ns/solid/notification/v1'],\n type: 'WebhookChannel2023',\n topic: containerUrl,\n sendTo: this.webhookUrl,\n };\n\n const response = await fetch(subscriptionEndpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/ld+json',\n Accept: 'application/ld+json',\n Authorization: `Bearer ${accessToken}`,\n },\n body: JSON.stringify(subscriptionRequest),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Subscription failed: ${response.status} ${errorText}`);\n }\n\n const result = await response.json();\n this.logger.info(`Created webhook subscription: ${JSON.stringify(result)}`);\n }\n\n /**\n * 发现 Solid Notification 端点\n *\n * 通过 HEAD 请求获取 Link header 中的 describedby,然后获取订阅端点\n */\n private async discoverNotificationEndpoint(resourceUrl: string, accessToken: string): Promise<string | null> {\n // 方法 1:直接使用已知的 CSS 端点格式\n // CSS 的 webhook 订阅端点通常是 /.notifications/WebhookChannel2023/\n const url = new URL(resourceUrl);\n const webhookEndpoint = `${url.origin}/.notifications/WebhookChannel2023/`;\n\n // 验证端点是否存在\n try {\n const response = await fetch(webhookEndpoint, {\n method: 'GET',\n headers: {\n Accept: 'application/ld+json',\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (response.ok) {\n return webhookEndpoint;\n }\n } catch {\n // 忽略错误,尝试其他方法\n }\n\n // 方法 2:通过 describedby Link header 发现\n try {\n const headResponse = await fetch(resourceUrl, {\n method: 'HEAD',\n headers: {\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n const linkHeader = headResponse.headers.get('Link');\n if (linkHeader) {\n // 解析 Link header 找 describedby\n const describedBy = this.parseLinkHeader(linkHeader, 'describedby');\n if (describedBy) {\n // 获取 describedby 资源,解析通知端点\n const descResponse = await fetch(describedBy, {\n headers: {\n Accept: 'application/ld+json',\n Authorization: `Bearer ${accessToken}`,\n },\n });\n if (descResponse.ok) {\n const desc = await descResponse.json() as any;\n // 查找 notify:subscription 或类似属性\n const subscription = desc['notify:subscription'] || desc['subscription'];\n if (subscription) {\n return typeof subscription === 'string' ? subscription : subscription['@id'];\n }\n }\n }\n }\n } catch {\n // 忽略错误\n }\n\n return null;\n }\n\n /**\n * 解析 Link header\n */\n private parseLinkHeader(linkHeader: string, rel: string): string | null {\n const links = linkHeader.split(',');\n for (const link of links) {\n const match = link.match(/<([^>]+)>.*rel=\"?([^\";]+)\"?/);\n if (match && match[2] === rel) {\n return match[1];\n }\n }\n return null;\n }\n}\n"]}
@@ -16,7 +16,7 @@ exports.loadThread = loadThread;
16
16
  exports.saveMessage = saveMessage;
17
17
  exports.saveToolCall = saveToolCall;
18
18
  exports.createThread = createThread;
19
- const drizzle_solid_1 = require("drizzle-solid");
19
+ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
20
20
  const schema_1 = require("../../api/chatkit/schema");
21
21
  /** Default Chat ID for CLI 1v1 conversations with SecretaryAI */
22
22
  const DEFAULT_CLI_CHAT_ID = 'cli-default';
@@ -1 +1 @@
1
- {"version":3,"file":"pod-thread-store.js","sourceRoot":"","sources":["../../../src/cli/lib/pod-thread-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Conversation thread storage backed by the user's Solid Pod.\n *\n * Uses drizzle-solid to operate on Chat + Thread + Message tables,\n * following the same protocol as API/ChatKit.\n *\n * Data model:\n * - Chat = 通讯录(跟谁聊):由 participants 决定,不再由 cwd hash 生成\n * - Thread = 对话实例(聊什么、在哪聊):workspace 是一级字段\n */\n\nimport { drizzle, eq } from 'drizzle-solid';\nimport { Chat, Thread, Message } from '../../api/chatkit/schema';\nimport type { Session } from '@inrupt/solid-client-authn-node';\n\n/** Default Chat ID for CLI 1v1 conversations with SecretaryAI */\nconst DEFAULT_CLI_CHAT_ID = 'cli-default';\n\nexport interface ThreadMessage {\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: string;\n}\n\nexport interface ThreadData {\n id: string;\n title?: string;\n workspace?: string;\n createdAt: string;\n updatedAt: string;\n messages: ThreadMessage[];\n}\n\n/**\n * Create a drizzle-solid database instance from an authenticated Session.\n */\nfunction createDb(session: Session) {\n return drizzle({\n fetch: session.fetch,\n info: session.info,\n } as any);\n}\n\n/**\n * Get or create the default 1v1 Chat for CLI (user ↔ SecretaryAI).\n * Returns the chatId (bare ID, not URI).\n */\nexport async function getOrCreateDefaultChat(session: Session): Promise<string> {\n const chatId = DEFAULT_CLI_CHAT_ID;\n try {\n const db = createDb(session);\n await ensureChat(db, chatId, session.info.webId!);\n } catch (error) {\n console.error('Failed to ensure default chat:', error);\n }\n return chatId;\n}\n\n/**\n * List thread IDs (most-recent first) for a given chatId.\n * Uses direct SPARQL because eq() on optional uri() fields still has issues.\n */\nexport async function listThreads(session: Session, chatId: string): Promise<string[]> {\n try {\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;\n const chatSubject = `<${podBaseUrl}/.data/chat/${chatId}/index.ttl#this>`;\n\n // Note: Removed OPTIONAL to avoid filtering out threads without createdAt\n // OPTIONAL in GRAPH ?g context can cause incomplete results (40 vs 57 threads)\n const query = `\n PREFIX sioc: <http://rdfs.org/sioc/ns#>\n PREFIX udfs: <https://undefineds.co/ns#>\n SELECT ?thread ?createdAt\n WHERE {\n ?thread a sioc:Thread ;\n sioc:has_parent ${chatSubject} ;\n udfs:createdAt ?createdAt .\n }\n ORDER BY DESC(?createdAt)\n `;\n\n const res = await session.fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/sparql-query',\n 'Accept': 'application/sparql-results+json',\n },\n body: query,\n });\n\n if (!res.ok) return [];\n\n const json = await res.json();\n const bindings = json.results?.bindings || [];\n\n // Extract thread ID from URI fragment: ...index.ttl#thread-xxx → thread-xxx\n return bindings\n .map((b: any) => {\n const uri = b.thread?.value || '';\n const hash = uri.lastIndexOf('#');\n return hash >= 0 ? uri.slice(hash + 1) : '';\n })\n .filter((id: string) => id.length > 0);\n } catch (error) {\n console.error('Failed to list threads:', error);\n return [];\n }\n}\n\n/**\n * Load a thread by ID with all its messages.\n */\nexport async function loadThread(\n session: Session,\n chatId: string,\n threadId: string,\n): Promise<ThreadData | null> {\n try {\n const db = createDb(session);\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Query thread by full URI\n const thread = await db.findByIri(Thread, threadUri);\n if (!thread) return null;\n\n // Query messages using direct SPARQL\n // Note: OPTIONAL works correctly with date-grouped files (messages.ttl)\n const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;\n const threadSubject = `<${threadUri}>`;\n\n const messagesQuery = `\n PREFIX meeting: <http://www.w3.org/ns/pim/meeting#>\n PREFIX sioc: <http://rdfs.org/sioc/ns#>\n PREFIX udfs: <https://undefineds.co/ns#>\n SELECT ?role ?content ?createdAt\n WHERE {\n ?msg a meeting:Message ;\n sioc:has_container ${threadSubject} .\n OPTIONAL { ?msg udfs:role ?role . }\n OPTIONAL { ?msg sioc:content ?content . }\n OPTIONAL { ?msg udfs:createdAt ?createdAt . }\n }\n ORDER BY ?createdAt\n `;\n\n const messagesRes = await session.fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/sparql-query',\n 'Accept': 'application/sparql-results+json',\n },\n body: messagesQuery,\n });\n\n const messagesJson = messagesRes.ok ? await messagesRes.json() : { results: { bindings: [] } };\n const messageBindings = messagesJson.results?.bindings || [];\n\n // Extract bare ID from thread.id\n const bareId = typeof thread.id === 'string' && thread.id.includes('#')\n ? thread.id.split('#').pop() || threadId\n : thread.id;\n\n return {\n id: bareId,\n title: thread.title || undefined,\n workspace: thread.workspace || undefined,\n createdAt: thread.createdAt?.toISOString() || new Date().toISOString(),\n updatedAt: thread.updatedAt?.toISOString() || new Date().toISOString(),\n messages: messageBindings.map((m: any) => ({\n role: m.role?.value || 'user',\n content: m.content?.value || '',\n timestamp: m.createdAt?.value || new Date().toISOString(),\n })),\n };\n } catch (error) {\n console.error('Failed to load thread:', error);\n return null;\n }\n}\n\n/**\n * Save a message to a thread.\n */\nexport async function saveMessage(\n session: Session,\n chatId: string,\n threadId: string,\n message: ThreadMessage,\n): Promise<boolean> {\n try {\n const db = createDb(session);\n\n // Ensure chat exists\n await ensureChat(db, chatId, session.info.webId!);\n\n // Ensure thread exists\n await ensureThread(db, chatId, threadId, session.info.webId!);\n\n // 构建完整的 Thread URI(用于 RDF 引用)\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Insert message\n // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid\n const messageId = `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n await db.insert(Message).values({\n id: messageId,\n chatId,\n threadId: threadUri, // 传入完整 URI\n maker: session.info.webId!,\n role: message.role,\n content: message.content,\n status: 'completed',\n createdAt: new Date(message.timestamp),\n });\n\n return true;\n } catch (error) {\n console.error('Failed to save message:', error);\n return false;\n }\n}\n\n/**\n * Save a tool call as a message with metadata.\n */\nexport async function saveToolCall(\n session: Session,\n chatId: string,\n threadId: string,\n toolCall: {\n toolName: string;\n toolCallId: string;\n arguments: any;\n output?: string;\n status: 'pending' | 'completed' | 'failed';\n },\n): Promise<boolean> {\n try {\n const db = createDb(session);\n\n // Ensure chat and thread exist\n await ensureChat(db, chatId, session.info.webId!);\n await ensureThread(db, chatId, threadId, session.info.webId!);\n\n // 构建完整的 Thread URI(用于 RDF 引用)\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Insert tool call message\n // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid\n const messageId = `tool-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n await db.insert(Message).values({\n id: messageId,\n chatId,\n threadId: threadUri, // 传入完整 URI\n maker: session.info.webId!,\n role: 'tool_call',\n content: `Executed ${toolCall.toolName}`,\n status: toolCall.status,\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n metadata: JSON.stringify({\n type: 'tool_call',\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n arguments: toolCall.arguments,\n output: toolCall.output,\n status: toolCall.status,\n }),\n createdAt: new Date(),\n });\n\n return true;\n } catch (error) {\n console.error('Failed to save tool call:', error);\n return false;\n }\n}\n\n/**\n * Create a fresh thread.\n * workspace is stored as a first-class field on Thread.\n */\nexport async function createThread(\n session: Session,\n chatId: string,\n workspace?: string,\n title?: string,\n): Promise<string> {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n try {\n const db = createDb(session);\n\n // Ensure chat exists\n await ensureChat(db, chatId, session.info.webId!);\n\n // Create thread with workspace as first-class field\n const now = new Date();\n await db.insert(Thread).values({\n id: threadId,\n chatId,\n title: title || 'CLI Conversation',\n workspace: workspace || null,\n status: 'active',\n metadata: JSON.stringify({ source: 'cli' }),\n createdAt: now,\n updatedAt: now,\n });\n\n return threadId;\n } catch (error) {\n console.error('Failed to create thread:', error);\n return threadId; // Return ID anyway, will be created on first message\n }\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\nasync function ensureChat(db: any, chatId: string, webId: string): Promise<void> {\n try {\n // Use findByIri to avoid OPTIONAL bug in SPARQL queries\n const podBaseUrl = webId.replace('/profile/card#me', '');\n const chatUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#this`;\n const chat = await db.findByIri(Chat, chatUri);\n\n if (!chat) {\n const now = new Date();\n await db.insert(Chat).values({\n id: chatId,\n title: 'CLI Chat',\n author: webId,\n participants: [],\n status: 'active',\n createdAt: now,\n updatedAt: now,\n });\n }\n } catch (error) {\n // Ignore if already exists\n }\n}\n\nasync function ensureThread(db: any, chatId: string, threadId: string, webId: string): Promise<void> {\n try {\n // Use findByIri to avoid OPTIONAL bug in SPARQL queries\n const podBaseUrl = webId.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n const thread = await db.findByIri(Thread, threadUri);\n\n if (!thread) {\n const now = new Date();\n await db.insert(Thread).values({\n id: threadId,\n chatId,\n title: 'CLI Conversation',\n status: 'active',\n metadata: JSON.stringify({ source: 'cli' }),\n createdAt: now,\n updatedAt: now,\n });\n }\n } catch (error) {\n // Ignore if already exists\n }\n}\n"]}
1
+ {"version":3,"file":"pod-thread-store.js","sourceRoot":"","sources":["../../../src/cli/lib/pod-thread-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Conversation thread storage backed by the user's Solid Pod.\n *\n * Uses drizzle-solid to operate on Chat + Thread + Message tables,\n * following the same protocol as API/ChatKit.\n *\n * Data model:\n * - Chat = 通讯录(跟谁聊):由 participants 决定,不再由 cwd hash 生成\n * - Thread = 对话实例(聊什么、在哪聊):workspace 是一级字段\n */\n\nimport { drizzle, eq } from '@undefineds.co/drizzle-solid';\nimport { Chat, Thread, Message } from '../../api/chatkit/schema';\nimport type { Session } from '@inrupt/solid-client-authn-node';\n\n/** Default Chat ID for CLI 1v1 conversations with SecretaryAI */\nconst DEFAULT_CLI_CHAT_ID = 'cli-default';\n\nexport interface ThreadMessage {\n role: 'user' | 'assistant' | 'system';\n content: string;\n timestamp: string;\n}\n\nexport interface ThreadData {\n id: string;\n title?: string;\n workspace?: string;\n createdAt: string;\n updatedAt: string;\n messages: ThreadMessage[];\n}\n\n/**\n * Create a drizzle-solid database instance from an authenticated Session.\n */\nfunction createDb(session: Session) {\n return drizzle({\n fetch: session.fetch,\n info: session.info,\n } as any);\n}\n\n/**\n * Get or create the default 1v1 Chat for CLI (user ↔ SecretaryAI).\n * Returns the chatId (bare ID, not URI).\n */\nexport async function getOrCreateDefaultChat(session: Session): Promise<string> {\n const chatId = DEFAULT_CLI_CHAT_ID;\n try {\n const db = createDb(session);\n await ensureChat(db, chatId, session.info.webId!);\n } catch (error) {\n console.error('Failed to ensure default chat:', error);\n }\n return chatId;\n}\n\n/**\n * List thread IDs (most-recent first) for a given chatId.\n * Uses direct SPARQL because eq() on optional uri() fields still has issues.\n */\nexport async function listThreads(session: Session, chatId: string): Promise<string[]> {\n try {\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;\n const chatSubject = `<${podBaseUrl}/.data/chat/${chatId}/index.ttl#this>`;\n\n // Note: Removed OPTIONAL to avoid filtering out threads without createdAt\n // OPTIONAL in GRAPH ?g context can cause incomplete results (40 vs 57 threads)\n const query = `\n PREFIX sioc: <http://rdfs.org/sioc/ns#>\n PREFIX udfs: <https://undefineds.co/ns#>\n SELECT ?thread ?createdAt\n WHERE {\n ?thread a sioc:Thread ;\n sioc:has_parent ${chatSubject} ;\n udfs:createdAt ?createdAt .\n }\n ORDER BY DESC(?createdAt)\n `;\n\n const res = await session.fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/sparql-query',\n 'Accept': 'application/sparql-results+json',\n },\n body: query,\n });\n\n if (!res.ok) return [];\n\n const json = await res.json();\n const bindings = json.results?.bindings || [];\n\n // Extract thread ID from URI fragment: ...index.ttl#thread-xxx → thread-xxx\n return bindings\n .map((b: any) => {\n const uri = b.thread?.value || '';\n const hash = uri.lastIndexOf('#');\n return hash >= 0 ? uri.slice(hash + 1) : '';\n })\n .filter((id: string) => id.length > 0);\n } catch (error) {\n console.error('Failed to list threads:', error);\n return [];\n }\n}\n\n/**\n * Load a thread by ID with all its messages.\n */\nexport async function loadThread(\n session: Session,\n chatId: string,\n threadId: string,\n): Promise<ThreadData | null> {\n try {\n const db = createDb(session);\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Query thread by full URI\n const thread = await db.findByIri(Thread, threadUri);\n if (!thread) return null;\n\n // Query messages using direct SPARQL\n // Note: OPTIONAL works correctly with date-grouped files (messages.ttl)\n const endpoint = `${podBaseUrl}/.data/chat/-/sparql`;\n const threadSubject = `<${threadUri}>`;\n\n const messagesQuery = `\n PREFIX meeting: <http://www.w3.org/ns/pim/meeting#>\n PREFIX sioc: <http://rdfs.org/sioc/ns#>\n PREFIX udfs: <https://undefineds.co/ns#>\n SELECT ?role ?content ?createdAt\n WHERE {\n ?msg a meeting:Message ;\n sioc:has_container ${threadSubject} .\n OPTIONAL { ?msg udfs:role ?role . }\n OPTIONAL { ?msg sioc:content ?content . }\n OPTIONAL { ?msg udfs:createdAt ?createdAt . }\n }\n ORDER BY ?createdAt\n `;\n\n const messagesRes = await session.fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/sparql-query',\n 'Accept': 'application/sparql-results+json',\n },\n body: messagesQuery,\n });\n\n const messagesJson = messagesRes.ok ? await messagesRes.json() : { results: { bindings: [] } };\n const messageBindings = messagesJson.results?.bindings || [];\n\n // Extract bare ID from thread.id\n const bareId = typeof thread.id === 'string' && thread.id.includes('#')\n ? thread.id.split('#').pop() || threadId\n : thread.id;\n\n return {\n id: bareId,\n title: thread.title || undefined,\n workspace: thread.workspace || undefined,\n createdAt: thread.createdAt?.toISOString() || new Date().toISOString(),\n updatedAt: thread.updatedAt?.toISOString() || new Date().toISOString(),\n messages: messageBindings.map((m: any) => ({\n role: m.role?.value || 'user',\n content: m.content?.value || '',\n timestamp: m.createdAt?.value || new Date().toISOString(),\n })),\n };\n } catch (error) {\n console.error('Failed to load thread:', error);\n return null;\n }\n}\n\n/**\n * Save a message to a thread.\n */\nexport async function saveMessage(\n session: Session,\n chatId: string,\n threadId: string,\n message: ThreadMessage,\n): Promise<boolean> {\n try {\n const db = createDb(session);\n\n // Ensure chat exists\n await ensureChat(db, chatId, session.info.webId!);\n\n // Ensure thread exists\n await ensureThread(db, chatId, threadId, session.info.webId!);\n\n // 构建完整的 Thread URI(用于 RDF 引用)\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Insert message\n // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid\n const messageId = `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n await db.insert(Message).values({\n id: messageId,\n chatId,\n threadId: threadUri, // 传入完整 URI\n maker: session.info.webId!,\n role: message.role,\n content: message.content,\n status: 'completed',\n createdAt: new Date(message.timestamp),\n });\n\n return true;\n } catch (error) {\n console.error('Failed to save message:', error);\n return false;\n }\n}\n\n/**\n * Save a tool call as a message with metadata.\n */\nexport async function saveToolCall(\n session: Session,\n chatId: string,\n threadId: string,\n toolCall: {\n toolName: string;\n toolCallId: string;\n arguments: any;\n output?: string;\n status: 'pending' | 'completed' | 'failed';\n },\n): Promise<boolean> {\n try {\n const db = createDb(session);\n\n // Ensure chat and thread exist\n await ensureChat(db, chatId, session.info.webId!);\n await ensureThread(db, chatId, threadId, session.info.webId!);\n\n // 构建完整的 Thread URI(用于 RDF 引用)\n const podBaseUrl = session.info.webId!.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n\n // Insert tool call message\n // Note: yyyy/MM/dd are automatically extracted from createdAt by drizzle-solid\n const messageId = `tool-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n await db.insert(Message).values({\n id: messageId,\n chatId,\n threadId: threadUri, // 传入完整 URI\n maker: session.info.webId!,\n role: 'tool_call',\n content: `Executed ${toolCall.toolName}`,\n status: toolCall.status,\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n metadata: JSON.stringify({\n type: 'tool_call',\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n arguments: toolCall.arguments,\n output: toolCall.output,\n status: toolCall.status,\n }),\n createdAt: new Date(),\n });\n\n return true;\n } catch (error) {\n console.error('Failed to save tool call:', error);\n return false;\n }\n}\n\n/**\n * Create a fresh thread.\n * workspace is stored as a first-class field on Thread.\n */\nexport async function createThread(\n session: Session,\n chatId: string,\n workspace?: string,\n title?: string,\n): Promise<string> {\n const threadId = `thread-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n try {\n const db = createDb(session);\n\n // Ensure chat exists\n await ensureChat(db, chatId, session.info.webId!);\n\n // Create thread with workspace as first-class field\n const now = new Date();\n await db.insert(Thread).values({\n id: threadId,\n chatId,\n title: title || 'CLI Conversation',\n workspace: workspace || null,\n status: 'active',\n metadata: JSON.stringify({ source: 'cli' }),\n createdAt: now,\n updatedAt: now,\n });\n\n return threadId;\n } catch (error) {\n console.error('Failed to create thread:', error);\n return threadId; // Return ID anyway, will be created on first message\n }\n}\n\n// ============================================================================\n// Internal Helpers\n// ============================================================================\n\nasync function ensureChat(db: any, chatId: string, webId: string): Promise<void> {\n try {\n // Use findByIri to avoid OPTIONAL bug in SPARQL queries\n const podBaseUrl = webId.replace('/profile/card#me', '');\n const chatUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#this`;\n const chat = await db.findByIri(Chat, chatUri);\n\n if (!chat) {\n const now = new Date();\n await db.insert(Chat).values({\n id: chatId,\n title: 'CLI Chat',\n author: webId,\n participants: [],\n status: 'active',\n createdAt: now,\n updatedAt: now,\n });\n }\n } catch (error) {\n // Ignore if already exists\n }\n}\n\nasync function ensureThread(db: any, chatId: string, threadId: string, webId: string): Promise<void> {\n try {\n // Use findByIri to avoid OPTIONAL bug in SPARQL queries\n const podBaseUrl = webId.replace('/profile/card#me', '');\n const threadUri = `${podBaseUrl}/.data/chat/${chatId}/index.ttl#${threadId}`;\n const thread = await db.findByIri(Thread, threadUri);\n\n if (!thread) {\n const now = new Date();\n await db.insert(Thread).values({\n id: threadId,\n chatId,\n title: 'CLI Conversation',\n status: 'active',\n metadata: JSON.stringify({ source: 'cli' }),\n createdAt: now,\n updatedAt: now,\n });\n }\n } catch (error) {\n // Ignore if already exists\n }\n}\n"]}
@@ -14,18 +14,18 @@
14
14
  * udfs:apiKey "sk-xxx" ;
15
15
  * udfs:label "Google AI" .
16
16
  */
17
- export declare const Credential: import("drizzle-solid/dist/core/schema").PodTableWithColumns<import("drizzle-solid/dist/core/schema").ResolvedColumns<{
18
- id: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
19
- provider: import("drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
20
- service: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
21
- status: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
22
- apiKey: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
23
- baseUrl: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
24
- proxyUrl: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
25
- projectId: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
26
- organizationId: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
27
- label: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
28
- lastUsedAt: import("drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
29
- failCount: import("drizzle-solid/dist/core/schema").ColumnBuilder<"integer", null, false, false>;
30
- rateLimitResetAt: import("drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
17
+ export declare const Credential: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
18
+ id: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
19
+ provider: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"uri", null, false, false>;
20
+ service: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
21
+ status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
22
+ apiKey: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
23
+ baseUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
24
+ proxyUrl: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
25
+ projectId: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
26
+ organizationId: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
27
+ label: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
28
+ lastUsedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
29
+ failCount: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"integer", null, false, false>;
30
+ rateLimitResetAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
31
31
  }>>;
@@ -4,7 +4,7 @@
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Credential = void 0;
7
- const drizzle_solid_1 = require("drizzle-solid");
7
+ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
8
8
  const vocab_1 = require("../../vocab");
9
9
  /**
10
10
  * Credential - 凭据存储
@@ -1 +1 @@
1
- {"version":3,"file":"tables.js","sourceRoot":"","sources":["../../../src/credential/schema/tables.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,iDAAqE;AACrE,uCAAmD;AAEnD;;;;;;;;;;;;GAYG;AACU,QAAA,UAAU,GAAG,IAAA,wBAAQ,EAChC,YAAY,EACZ;IACE,EAAE,EAAE,IAAA,sBAAM,EAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAC7B,QAAQ,EAAE,IAAA,mBAAG,EAAC,UAAU,CAAC;IACzB,OAAO,EAAE,IAAA,sBAAM,EAAC,SAAS,CAAC;IAC1B,MAAM,EAAE,IAAA,sBAAM,EAAC,QAAQ,CAAC;IACxB,MAAM,EAAE,IAAA,sBAAM,EAAC,QAAQ,CAAC;IACxB,OAAO,EAAE,IAAA,sBAAM,EAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,IAAA,sBAAM,EAAC,UAAU,CAAC;IAC5B,SAAS,EAAE,IAAA,sBAAM,EAAC,WAAW,CAAC;IAC9B,cAAc,EAAE,IAAA,sBAAM,EAAC,gBAAgB,CAAC;IACxC,KAAK,EAAE,IAAA,sBAAM,EAAC,OAAO,CAAC;IACtB,UAAU,EAAE,IAAA,wBAAQ,EAAC,YAAY,CAAC;IAClC,SAAS,EAAE,IAAA,mBAAG,EAAC,WAAW,CAAC;IAC3B,gBAAgB,EAAE,IAAA,wBAAQ,EAAC,kBAAkB,CAAC;CAC/C,EACD;IACE,IAAI,EAAE,2BAA2B;IACjC,IAAI,EAAE,YAAI,CAAC,UAAU;IACrB,SAAS,EAAE,sBAAc;IACzB,eAAe,EAAE,OAAO;CACzB,CACF,CAAC","sourcesContent":["/**\n * Credential Schema - Pod RDF 表定义\n */\n\nimport { podTable, string, int, datetime, uri } from 'drizzle-solid';\nimport { UDFS, UDFS_NAMESPACE } from '../../vocab';\n\n/**\n * Credential - 凭据存储\n *\n * 存储位置: /settings/credentials.ttl\n *\n * RDF 示例:\n * <#cred-001> a udfs:Credential ;\n * udfs:provider </settings/ai/providers.ttl#google> ;\n * udfs:service \"ai\" ;\n * udfs:status \"active\" ;\n * udfs:apiKey \"sk-xxx\" ;\n * udfs:label \"Google AI\" .\n */\nexport const Credential = podTable(\n 'Credential',\n {\n id: string('id').primaryKey(),\n provider: uri('provider'),\n service: string('service'),\n status: string('status'),\n apiKey: string('apiKey'),\n baseUrl: string('baseUrl'),\n proxyUrl: string('proxyUrl'),\n projectId: string('projectId'),\n organizationId: string('organizationId'),\n label: string('label'),\n lastUsedAt: datetime('lastUsedAt'),\n failCount: int('failCount'),\n rateLimitResetAt: datetime('rateLimitResetAt'),\n },\n {\n base: '/settings/credentials.ttl',\n type: UDFS.Credential,\n namespace: UDFS_NAMESPACE,\n subjectTemplate: '#{id}',\n },\n);\n\n"]}
1
+ {"version":3,"file":"tables.js","sourceRoot":"","sources":["../../../src/credential/schema/tables.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,gEAAoF;AACpF,uCAAmD;AAEnD;;;;;;;;;;;;GAYG;AACU,QAAA,UAAU,GAAG,IAAA,wBAAQ,EAChC,YAAY,EACZ;IACE,EAAE,EAAE,IAAA,sBAAM,EAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAC7B,QAAQ,EAAE,IAAA,mBAAG,EAAC,UAAU,CAAC;IACzB,OAAO,EAAE,IAAA,sBAAM,EAAC,SAAS,CAAC;IAC1B,MAAM,EAAE,IAAA,sBAAM,EAAC,QAAQ,CAAC;IACxB,MAAM,EAAE,IAAA,sBAAM,EAAC,QAAQ,CAAC;IACxB,OAAO,EAAE,IAAA,sBAAM,EAAC,SAAS,CAAC;IAC1B,QAAQ,EAAE,IAAA,sBAAM,EAAC,UAAU,CAAC;IAC5B,SAAS,EAAE,IAAA,sBAAM,EAAC,WAAW,CAAC;IAC9B,cAAc,EAAE,IAAA,sBAAM,EAAC,gBAAgB,CAAC;IACxC,KAAK,EAAE,IAAA,sBAAM,EAAC,OAAO,CAAC;IACtB,UAAU,EAAE,IAAA,wBAAQ,EAAC,YAAY,CAAC;IAClC,SAAS,EAAE,IAAA,mBAAG,EAAC,WAAW,CAAC;IAC3B,gBAAgB,EAAE,IAAA,wBAAQ,EAAC,kBAAkB,CAAC;CAC/C,EACD;IACE,IAAI,EAAE,2BAA2B;IACjC,IAAI,EAAE,YAAI,CAAC,UAAU;IACrB,SAAS,EAAE,sBAAc;IACzB,eAAe,EAAE,OAAO;CACzB,CACF,CAAC","sourcesContent":["/**\n * Credential Schema - Pod RDF 表定义\n */\n\nimport { podTable, string, int, datetime, uri } from '@undefineds.co/drizzle-solid';\nimport { UDFS, UDFS_NAMESPACE } from '../../vocab';\n\n/**\n * Credential - 凭据存储\n *\n * 存储位置: /settings/credentials.ttl\n *\n * RDF 示例:\n * <#cred-001> a udfs:Credential ;\n * udfs:provider </settings/ai/providers.ttl#google> ;\n * udfs:service \"ai\" ;\n * udfs:status \"active\" ;\n * udfs:apiKey \"sk-xxx\" ;\n * udfs:label \"Google AI\" .\n */\nexport const Credential = podTable(\n 'Credential',\n {\n id: string('id').primaryKey(),\n provider: uri('provider'),\n service: string('service'),\n status: string('status'),\n apiKey: string('apiKey'),\n baseUrl: string('baseUrl'),\n proxyUrl: string('proxyUrl'),\n projectId: string('projectId'),\n organizationId: string('organizationId'),\n label: string('label'),\n lastUsedAt: datetime('lastUsedAt'),\n failCount: int('failCount'),\n rateLimitResetAt: datetime('rateLimitResetAt'),\n },\n {\n base: '/settings/credentials.ttl',\n type: UDFS.Credential,\n namespace: UDFS_NAMESPACE,\n subjectTemplate: '#{id}',\n },\n);\n\n"]}