@vezlo/assistant-server 2.2.2 → 2.4.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 (46) hide show
  1. package/README.md +21 -15
  2. package/database-schema.sql +178 -8
  3. package/dist/src/bootstrap/initializeServices.d.ts.map +1 -1
  4. package/dist/src/bootstrap/initializeServices.js +2 -0
  5. package/dist/src/bootstrap/initializeServices.js.map +1 -1
  6. package/dist/src/config/global.js +1 -1
  7. package/dist/src/config/global.js.map +1 -1
  8. package/dist/src/controllers/ChatController.d.ts +12 -1
  9. package/dist/src/controllers/ChatController.d.ts.map +1 -1
  10. package/dist/src/controllers/ChatController.js +274 -148
  11. package/dist/src/controllers/ChatController.js.map +1 -1
  12. package/dist/src/controllers/KnowledgeController.d.ts.map +1 -1
  13. package/dist/src/controllers/KnowledgeController.js +0 -4
  14. package/dist/src/controllers/KnowledgeController.js.map +1 -1
  15. package/dist/src/migrations/006_add_knowledge_chunks.d.ts +4 -0
  16. package/dist/src/migrations/006_add_knowledge_chunks.d.ts.map +1 -0
  17. package/dist/src/migrations/006_add_knowledge_chunks.js +245 -0
  18. package/dist/src/migrations/006_add_knowledge_chunks.js.map +1 -0
  19. package/dist/src/migrations/007_add_updated_at_to_feedback.d.ts +4 -0
  20. package/dist/src/migrations/007_add_updated_at_to_feedback.d.ts.map +1 -0
  21. package/dist/src/migrations/007_add_updated_at_to_feedback.js +22 -0
  22. package/dist/src/migrations/007_add_updated_at_to_feedback.js.map +1 -0
  23. package/dist/src/server.js +42 -8
  24. package/dist/src/server.js.map +1 -1
  25. package/dist/src/services/AIService.d.ts +9 -0
  26. package/dist/src/services/AIService.d.ts.map +1 -1
  27. package/dist/src/services/AIService.js +111 -3
  28. package/dist/src/services/AIService.js.map +1 -1
  29. package/dist/src/services/IntentService.d.ts +2 -1
  30. package/dist/src/services/IntentService.d.ts.map +1 -1
  31. package/dist/src/services/IntentService.js +23 -4
  32. package/dist/src/services/IntentService.js.map +1 -1
  33. package/dist/src/services/KnowledgeBaseService.d.ts +20 -5
  34. package/dist/src/services/KnowledgeBaseService.d.ts.map +1 -1
  35. package/dist/src/services/KnowledgeBaseService.js +203 -137
  36. package/dist/src/services/KnowledgeBaseService.js.map +1 -1
  37. package/dist/src/storage/FeedbackRepository.d.ts +1 -0
  38. package/dist/src/storage/FeedbackRepository.d.ts.map +1 -1
  39. package/dist/src/storage/FeedbackRepository.js +26 -0
  40. package/dist/src/storage/FeedbackRepository.js.map +1 -1
  41. package/dist/src/storage/UnifiedStorage.d.ts +1 -0
  42. package/dist/src/storage/UnifiedStorage.d.ts.map +1 -1
  43. package/dist/src/storage/UnifiedStorage.js +3 -0
  44. package/dist/src/storage/UnifiedStorage.js.map +1 -1
  45. package/package.json +2 -2
  46. package/scripts/test-chunks-embeddings.js +190 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Diagnostic script to check chunks, embeddings, and test search
3
+ * Run with: node scripts/test-chunks-embeddings.js
4
+ */
5
+
6
+ require('dotenv').config();
7
+ const { createClient } = require('@supabase/supabase-js');
8
+
9
+ const supabaseUrl = process.env.SUPABASE_URL;
10
+ const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY || process.env.SUPABASE_ANON_KEY;
11
+
12
+ if (!supabaseUrl || !supabaseKey) {
13
+ console.error('❌ Missing SUPABASE_URL or SUPABASE_KEY in environment');
14
+ process.exit(1);
15
+ }
16
+
17
+ const supabase = createClient(supabaseUrl, supabaseKey);
18
+
19
+ async function generateEmbedding(text) {
20
+ if (!process.env.OPENAI_API_KEY) {
21
+ console.error('❌ OPENAI_API_KEY not set');
22
+ return null;
23
+ }
24
+
25
+ try {
26
+ const response = await fetch('https://api.openai.com/v1/embeddings', {
27
+ method: 'POST',
28
+ headers: {
29
+ 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
30
+ 'Content-Type': 'application/json'
31
+ },
32
+ body: JSON.stringify({
33
+ model: 'text-embedding-3-large',
34
+ input: text.substring(0, 8000)
35
+ })
36
+ });
37
+
38
+ if (!response.ok) {
39
+ const errorText = await response.text();
40
+ throw new Error(`OpenAI API error: ${response.status} - ${errorText}`);
41
+ }
42
+
43
+ const data = await response.json();
44
+ return data.data[0].embedding;
45
+ } catch (error) {
46
+ console.error('Failed to generate embedding:', error);
47
+ return null;
48
+ }
49
+ }
50
+
51
+ async function testChunks() {
52
+ console.log('🔍 Testing chunks, embeddings, and search...\n');
53
+
54
+ // 1. Find the Python files
55
+ console.log('1️⃣ Finding Python files...');
56
+ const { data: items, error: itemsError } = await supabase
57
+ .from('vezlo_knowledge_items')
58
+ .select('id, uuid, title, type')
59
+ .in('title', ['setup_company_credentials.py', 'setup_partnership_system.py']);
60
+
61
+ if (itemsError) {
62
+ console.error('❌ Error fetching items:', itemsError);
63
+ return;
64
+ }
65
+
66
+ if (!items || items.length === 0) {
67
+ console.log('⚠️ No matching files found');
68
+ return;
69
+ }
70
+
71
+ console.log(`✅ Found ${items.length} file(s)\n`);
72
+
73
+ for (const item of items) {
74
+ console.log(`\n${'='.repeat(70)}`);
75
+ console.log(`📄 File: ${item.title} (ID: ${item.id})`);
76
+ console.log('='.repeat(70));
77
+
78
+ // 2. Get all chunks
79
+ const { data: chunks, error: chunksError } = await supabase
80
+ .from('vezlo_knowledge_chunks')
81
+ .select('id, chunk_index, chunk_text, embedding, processed_at')
82
+ .eq('document_id', item.id)
83
+ .order('chunk_index', { ascending: true });
84
+
85
+ if (chunksError) {
86
+ console.error(`❌ Error fetching chunks:`, chunksError);
87
+ continue;
88
+ }
89
+
90
+ if (!chunks || chunks.length === 0) {
91
+ console.log('⚠️ No chunks found');
92
+ continue;
93
+ }
94
+
95
+ console.log(`\n📦 Found ${chunks.length} chunk(s):\n`);
96
+
97
+ // Show chunk details
98
+ chunks.forEach((chunk) => {
99
+ console.log(`Chunk ${chunk.chunk_index}:`);
100
+ console.log(` Text (first 150 chars): ${chunk.chunk_text.substring(0, 150)}...`);
101
+ console.log(` Text length: ${chunk.chunk_text.length} chars`);
102
+ console.log(` Has embedding: ${chunk.embedding ? 'Yes' : 'No'}`);
103
+ if (chunk.embedding) {
104
+ const embeddingArray = Array.isArray(chunk.embedding) ? chunk.embedding :
105
+ (typeof chunk.embedding === 'string' ? JSON.parse(chunk.embedding) : null);
106
+ console.log(` Embedding dimensions: ${embeddingArray ? embeddingArray.length : 'N/A'}`);
107
+ }
108
+ console.log('');
109
+ });
110
+
111
+ // 3. Test search queries
112
+ console.log(`\n🔎 Testing search queries for ${item.title}...\n`);
113
+
114
+ const testQueries = [
115
+ 'run function',
116
+ 'what does run function do',
117
+ 'run()',
118
+ 'run_migration function',
119
+ 'verify_perplexity_api_key',
120
+ 'setup_env'
121
+ ];
122
+
123
+ for (const query of testQueries) {
124
+ console.log(`\nQuery: "${query}"`);
125
+ console.log('─'.repeat(60));
126
+
127
+ // Generate query embedding
128
+ console.log(' Generating query embedding...');
129
+ const queryEmbedding = await generateEmbedding(query);
130
+
131
+ if (!queryEmbedding) {
132
+ console.log(' ❌ Failed to generate embedding');
133
+ continue;
134
+ }
135
+
136
+ console.log(` ✅ Embedding generated (${queryEmbedding.length} dimensions)`);
137
+
138
+ // Test RPC function
139
+ console.log(' Calling vezlo_match_knowledge_chunks RPC...');
140
+ const { data: results, error: rpcError } = await supabase.rpc('vezlo_match_knowledge_chunks', {
141
+ query_embedding: JSON.stringify(queryEmbedding),
142
+ match_threshold: 0.20,
143
+ match_count: 5,
144
+ filter_company_id: null
145
+ });
146
+
147
+ if (rpcError) {
148
+ console.log(` ❌ RPC error:`, rpcError);
149
+ continue;
150
+ }
151
+
152
+ if (!results || results.length === 0) {
153
+ console.log(` ⚠️ No results found (threshold: 0.20)`);
154
+
155
+ // Try with lower threshold
156
+ const { data: lowThresholdResults } = await supabase.rpc('vezlo_match_knowledge_chunks', {
157
+ query_embedding: JSON.stringify(queryEmbedding),
158
+ match_threshold: 0.10,
159
+ match_count: 5,
160
+ filter_company_id: null
161
+ });
162
+
163
+ if (lowThresholdResults && lowThresholdResults.length > 0) {
164
+ console.log(` ℹ️ Found ${lowThresholdResults.length} result(s) with threshold 0.10:`);
165
+ lowThresholdResults.forEach((r, idx) => {
166
+ if (r.document_title === item.title) {
167
+ console.log(` ${idx + 1}. Chunk ${r.chunk_index}: similarity=${r.similarity.toFixed(3)}`);
168
+ console.log(` Text: "${r.chunk_text.substring(0, 100)}..."`);
169
+ }
170
+ });
171
+ }
172
+ } else {
173
+ console.log(` ✅ Found ${results.length} result(s):`);
174
+ results.forEach((r, idx) => {
175
+ if (r.document_title === item.title) {
176
+ console.log(` ${idx + 1}. Chunk ${r.chunk_index}: similarity=${r.similarity.toFixed(3)}`);
177
+ console.log(` Text: "${r.chunk_text.substring(0, 100)}..."`);
178
+ console.log(` Contains function name: ${r.chunk_text.toLowerCase().includes(query.toLowerCase().replace(/[()]/g, '')) ? 'Yes' : 'No'}`);
179
+ }
180
+ });
181
+ }
182
+ }
183
+ }
184
+
185
+ console.log('\n\n' + '='.repeat(70));
186
+ console.log('✅ Diagnostic complete');
187
+ console.log('='.repeat(70));
188
+ }
189
+
190
+ testChunks().catch(console.error);