11// server/services/qdrant.ts
2- import { QdrantClient } from ' @qdrant/js-client-rest' ;
3- import OpenAI from ' openai' ;
2+ import { QdrantClient } from " @qdrant/js-client-rest" ;
3+ import OpenAI from " openai" ;
44
55const qdrantUrl =
6- process . env . QDRANT_URL ||
7- process . env . QDRANT_HOST ||
8- 'http://localhost:6333' ;
6+ process . env . QDRANT_URL || process . env . QDRANT_HOST || "http://localhost:6333" ;
97
108const qdrantClient = new QdrantClient ( {
119 url : qdrantUrl ,
@@ -17,62 +15,57 @@ const openai = new OpenAI({
1715 apiKey : process . env . OPENAI_API_KEY ! ,
1816} ) ;
1917
20- console . log ( 'Testing Qdrant connection...' ) ;
21-
2218async function testQdrantConnection ( ) {
23- try {
24- console . log ( 'Testing Qdrant connection Again...' ) ;
25- // Test connection by listing collections
26- const collections = await qdrantClient . getCollections ( ) ;
27- console . log ( '✅ Qdrant connection OK' ) ;
28- } catch ( error : any ) {
29- console . error ( '❌ Failed to connect to Qdrant' ) ;
30- console . error ( 'Error message:' , error . message ) ;
31- if ( error . cause ) console . error ( 'Cause:' , error . cause ) ;
32- }
19+ try {
20+ console . log ( "Testing Qdrant connection Again..." ) ;
21+ // Test connection by listing collections
22+ const collections = await qdrantClient . getCollections ( ) ;
23+ console . log ( "✅ Qdrant connection OK" ) ;
24+ } catch ( error : any ) {
25+ console . error ( "❌ Failed to connect to Qdrant" ) ;
26+ console . error ( "Error message:" , error . message ) ;
27+ if ( error . cause ) console . error ( "Cause:" , error . cause ) ;
3328 }
34-
35- // Run connection test
36- await testQdrantConnection ( ) ;
29+ }
3730
3831export class QdrantService {
39- private collectionName = ' kb_pages' ;
32+ private collectionName = " kb_pages" ;
4033 private vectorSize = 1536 ; // OpenAI text-embedding-3-small dimension
4134
4235 // Initialize Qdrant collection
4336 async initializeCollection ( ) {
4437 try {
4538 // Check if collection exists
46- console . log ( ' Checking if collection exists ...' ) ;
39+ console . log ( " Checking if collection exists ..." ) ;
4740 const collections = await qdrantClient . getCollections ( ) ;
48- console . log ( ' collections' , collections ) ;
41+ console . log ( " collections" , collections ) ;
4942 const collectionExists = collections . collections . some (
50- col => col . name === this . collectionName
43+ ( col ) => col . name === this . collectionName ,
5144 ) ;
52- console . log ( ' collectionExists' , collectionExists ) ;
45+ console . log ( " collectionExists" , collectionExists ) ;
5346
5447 if ( ! collectionExists ) {
5548 console . log ( `Creating Qdrant collection: ${ this . collectionName } ` ) ;
56-
49+
5750 await qdrantClient . createCollection ( this . collectionName , {
5851 vectors : {
5952 size : this . vectorSize ,
60- distance : ' Cosine' , // Use cosine similarity
53+ distance : " Cosine" , // Use cosine similarity
6154 } ,
6255 optimizers_config : {
6356 default_segment_number : 2 ,
6457 } ,
6558 replication_factor : 1 ,
6659 } ) ;
6760
68- console . log ( ' Collection created successfully' ) ;
61+ console . log ( " Collection created successfully" ) ;
6962 } else {
70- console . log ( ' Collection already exists' ) ;
63+ console . log ( " Collection already exists" ) ;
7164 }
7265
7366 return true ;
7467 } catch ( error ) {
75- console . error ( ' Error initializing Qdrant collection:' , error ) ;
68+ console . error ( " Error initializing Qdrant collection:" , error ) ;
7669 throw error ;
7770 }
7871 }
@@ -82,18 +75,18 @@ export class QdrantService {
8275 try {
8376 // Clean HTML content to plain text
8477 const cleanText = text
85- . replace ( / < [ ^ > ] * > / g, ' ' )
86- . replace ( / \s + / g, ' ' )
78+ . replace ( / < [ ^ > ] * > / g, " " )
79+ . replace ( / \s + / g, " " )
8780 . trim ( ) ;
8881
8982 const response = await openai . embeddings . create ( {
90- model : ' text-embedding-3-small' ,
83+ model : " text-embedding-3-small" ,
9184 input : cleanText ,
9285 } ) ;
9386
9487 return response . data [ 0 ] . embedding ;
9588 } catch ( error ) {
96- console . error ( ' Error generating embeddings:' , error ) ;
89+ console . error ( " Error generating embeddings:" , error ) ;
9790 throw error ;
9891 }
9992 }
@@ -118,7 +111,10 @@ export class QdrantService {
118111 createdAt : kbPage . createdAt ,
119112 updatedAt : kbPage . updatedAt ,
120113 // Store clean text for better search
121- cleanText : kbPage . body . replace ( / < [ ^ > ] * > / g, ' ' ) . replace ( / \s + / g, ' ' ) . trim ( ) ,
114+ cleanText : kbPage . body
115+ . replace ( / < [ ^ > ] * > / g, " " )
116+ . replace ( / \s + / g, " " )
117+ . trim ( ) ,
122118 } ,
123119 } ;
124120
@@ -130,36 +126,42 @@ export class QdrantService {
130126 return { success : true , uuid : kbPage . uuid } ;
131127 } catch ( error ) {
132128 console . error ( `Error upserting KB page ${ kbPage . uuid } :` , error ) ;
133- return { success : false , uuid : kbPage . uuid , error : ( error as Error ) . message } ;
129+ return {
130+ success : false ,
131+ uuid : kbPage . uuid ,
132+ error : ( error as Error ) . message ,
133+ } ;
134134 }
135135 }
136136
137137 // Batch upsert multiple KB pages
138138 async batchUpsertKBPages ( kbPages : any [ ] , batchSize : number = 10 ) {
139139 const results : any [ ] = [ ] ;
140-
140+
141141 for ( let i = 0 ; i < kbPages . length ; i += batchSize ) {
142142 const batch = kbPages . slice ( i , i + batchSize ) ;
143- console . log ( `Processing batch ${ Math . floor ( i / batchSize ) + 1 } /${ Math . ceil ( kbPages . length / batchSize ) } ` ) ;
143+ console . log (
144+ `Processing batch ${ Math . floor ( i / batchSize ) + 1 } /${ Math . ceil ( kbPages . length / batchSize ) } ` ,
145+ ) ;
144146
145- const batchPromises = batch . map ( page => this . upsertKBPage ( page ) ) ;
147+ const batchPromises = batch . map ( ( page ) => this . upsertKBPage ( page ) ) ;
146148 const batchResults = await Promise . allSettled ( batchPromises ) ;
147-
149+
148150 batchResults . forEach ( ( result , index ) => {
149- if ( result . status === ' fulfilled' ) {
151+ if ( result . status === " fulfilled" ) {
150152 results . push ( result . value ) ;
151153 } else {
152154 results . push ( {
153155 success : false ,
154156 uuid : batch [ index ] . uuid ,
155- error : result . reason ?. message || ' Unknown error'
157+ error : result . reason ?. message || " Unknown error" ,
156158 } ) ;
157159 }
158160 } ) ;
159161
160162 // Add delay to avoid rate limiting
161163 if ( i + batchSize < kbPages . length ) {
162- await new Promise ( resolve => setTimeout ( resolve , 1000 ) ) ;
164+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
163165 }
164166 }
165167
@@ -178,14 +180,14 @@ export class QdrantService {
178180 filter : filter || {
179181 must : [
180182 {
181- key : ' status' ,
182- match : { value : ' published' }
183- }
184- ]
183+ key : " status" ,
184+ match : { value : " published" } ,
185+ } ,
186+ ] ,
185187 } ,
186188 } ) ;
187189
188- return searchResult . map ( point => ( {
190+ return searchResult . map ( ( point ) => ( {
189191 uuid : point . payload ?. uuid ,
190192 title : point . payload ?. title ,
191193 description : point . payload ?. description ,
@@ -195,7 +197,7 @@ export class QdrantService {
195197 cleanText : point . payload ?. cleanText ,
196198 } ) ) ;
197199 } catch ( error ) {
198- console . error ( ' Error searching Qdrant:' , error ) ;
200+ console . error ( " Error searching Qdrant:" , error ) ;
199201 throw error ;
200202 }
201203 }
@@ -206,7 +208,7 @@ export class QdrantService {
206208 const info = await qdrantClient . getCollection ( this . collectionName ) ;
207209 return info ;
208210 } catch ( error ) {
209- console . error ( ' Error getting collection info:' , error ) ;
211+ console . error ( " Error getting collection info:" , error ) ;
210212 throw error ;
211213 }
212214 }
@@ -226,4 +228,4 @@ export class QdrantService {
226228 }
227229}
228230
229- export const qdrantService = new QdrantService ( ) ;
231+ export const qdrantService = new QdrantService ( ) ;
0 commit comments