diff --git a/apps/server/package.json b/apps/server/package.json index cb32657a7..3e5ae9592 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -66,6 +66,7 @@ "@nestjs/websockets": "11.1.28", "@node-saml/passport-saml": "5.1.0", "@socket.io/redis-adapter": "8.3.0", + "@turbopuffer/turbopuffer": "^2.8.0", "ai": "6.0.134", "ai-sdk-ollama": "3.8.1", "bcrypt": "6.0.0", diff --git a/apps/server/src/ee b/apps/server/src/ee index 22a5f200d..662335793 160000 --- a/apps/server/src/ee +++ b/apps/server/src/ee @@ -1 +1 @@ -Subproject commit 22a5f200dfb7d042e88c6a1397568da5bdf9477b +Subproject commit 6623357936f70af833f283a59caebe9e7f393ecc diff --git a/apps/server/src/integrations/environment/environment.service.ts b/apps/server/src/integrations/environment/environment.service.ts index 5667bf5a6..c483df626 100644 --- a/apps/server/src/integrations/environment/environment.service.ts +++ b/apps/server/src/integrations/environment/environment.service.ts @@ -310,6 +310,31 @@ export class EnvironmentService { return val === 'true'; } + getAiVectorDriver(): string { + return this.configService + .get('AI_VECTOR_DRIVER', 'pgvector') + .toLowerCase(); + } + + getTurbopufferApiKey(): string { + return this.configService.get('TURBOPUFFER_API_KEY'); + } + + getTurbopufferRegion(): string { + return this.configService.get('TURBOPUFFER_REGION'); + } + + getTurbopufferBaseUrl(): string { + return this.configService.get('TURBOPUFFER_BASE_URL'); + } + + getTurbopufferNamespacePrefix(): string { + return this.configService.get( + 'TURBOPUFFER_NAMESPACE_PREFIX', + 'docmost', + ); + } + getOpenAiApiKey(): string { return this.configService.get('OPENAI_API_KEY'); } diff --git a/apps/server/src/integrations/environment/environment.validation.ts b/apps/server/src/integrations/environment/environment.validation.ts index ef3c420cf..e584e8125 100644 --- a/apps/server/src/integrations/environment/environment.validation.ts +++ b/apps/server/src/integrations/environment/environment.validation.ts @@ -108,6 +108,37 @@ export class EnvironmentVariables { @IsString() AI_DRIVER: string; + @IsOptional() + @ValidateIf((obj) => obj.AI_VECTOR_DRIVER) + @IsIn(['pgvector', 'turbopuffer']) + @IsString() + AI_VECTOR_DRIVER: string; + + @ValidateIf((obj) => obj.AI_VECTOR_DRIVER === 'turbopuffer') + @IsNotEmpty() + @IsString() + TURBOPUFFER_API_KEY: string; + + @ValidateIf( + (obj) => + obj.AI_VECTOR_DRIVER === 'turbopuffer' && !obj.TURBOPUFFER_BASE_URL, + ) + @IsNotEmpty({ + message: + 'TURBOPUFFER_REGION is required when AI_VECTOR_DRIVER is turbopuffer, unless TURBOPUFFER_BASE_URL is set', + }) + @IsString() + TURBOPUFFER_REGION: string; + + @IsOptional() + @ValidateIf((obj) => obj.TURBOPUFFER_BASE_URL != '' && obj.TURBOPUFFER_BASE_URL != null) + @IsUrl({ protocols: ['http', 'https'], require_tld: false }) + TURBOPUFFER_BASE_URL: string; + + @IsOptional() + @IsString() + TURBOPUFFER_NAMESPACE_PREFIX: string; + @IsOptional() @IsString() AI_EMBEDDING_MODEL: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e26d0a45d..3a6ca01a7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -593,6 +593,9 @@ importers: '@socket.io/redis-adapter': specifier: 8.3.0 version: 8.3.0(socket.io-adapter@2.5.4(supports-color@10.2.2))(supports-color@10.2.2) + '@turbopuffer/turbopuffer': + specifier: ^2.8.0 + version: 2.8.0 ai: specifier: 6.0.134 version: 6.0.134(zod@4.3.6) @@ -4382,6 +4385,9 @@ packages: '@tsconfig/node16@1.0.4': resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + '@turbopuffer/turbopuffer@2.8.0': + resolution: {integrity: sha512-lurmVByLynuWtPtVl7SBEJ0bNakb8bs4KsafKzeLWnXA6BsQiGS9obT/7ExQVb9/yecyRn/grj8VgwUzi2xMyg==} + '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} @@ -5698,6 +5704,7 @@ packages: cron-parser@4.9.0: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} + deprecated: v4 is no longer maintained, upgrade to v5 cron@4.4.0: resolution: {integrity: sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==} @@ -8168,6 +8175,9 @@ packages: pako@2.0.3: resolution: {integrity: sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw==} + pako@2.2.0: + resolution: {integrity: sha512-zJq6RP/5q+TO2OpFV3FHzlPnFjmkb7Nc99a5SNjJE+uu/PkpChs+NIZSSzbBoD+6kjiISXjfYdwj1ZRQ81dz/w==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -14341,6 +14351,11 @@ snapshots: '@tsconfig/node16@1.0.4': {} + '@turbopuffer/turbopuffer@2.8.0': + dependencies: + pako: 2.2.0 + undici: 7.29.0 + '@tybys/wasm-util@0.10.2': dependencies: tslib: 2.8.1 @@ -18749,6 +18764,8 @@ snapshots: pako@2.0.3: {} + pako@2.2.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0