@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.
- package/README.md +21 -15
- package/database-schema.sql +178 -8
- package/dist/src/bootstrap/initializeServices.d.ts.map +1 -1
- package/dist/src/bootstrap/initializeServices.js +2 -0
- package/dist/src/bootstrap/initializeServices.js.map +1 -1
- package/dist/src/config/global.js +1 -1
- package/dist/src/config/global.js.map +1 -1
- package/dist/src/controllers/ChatController.d.ts +12 -1
- package/dist/src/controllers/ChatController.d.ts.map +1 -1
- package/dist/src/controllers/ChatController.js +274 -148
- package/dist/src/controllers/ChatController.js.map +1 -1
- package/dist/src/controllers/KnowledgeController.d.ts.map +1 -1
- package/dist/src/controllers/KnowledgeController.js +0 -4
- package/dist/src/controllers/KnowledgeController.js.map +1 -1
- package/dist/src/migrations/006_add_knowledge_chunks.d.ts +4 -0
- package/dist/src/migrations/006_add_knowledge_chunks.d.ts.map +1 -0
- package/dist/src/migrations/006_add_knowledge_chunks.js +245 -0
- package/dist/src/migrations/006_add_knowledge_chunks.js.map +1 -0
- package/dist/src/migrations/007_add_updated_at_to_feedback.d.ts +4 -0
- package/dist/src/migrations/007_add_updated_at_to_feedback.d.ts.map +1 -0
- package/dist/src/migrations/007_add_updated_at_to_feedback.js +22 -0
- package/dist/src/migrations/007_add_updated_at_to_feedback.js.map +1 -0
- package/dist/src/server.js +42 -8
- package/dist/src/server.js.map +1 -1
- package/dist/src/services/AIService.d.ts +9 -0
- package/dist/src/services/AIService.d.ts.map +1 -1
- package/dist/src/services/AIService.js +111 -3
- package/dist/src/services/AIService.js.map +1 -1
- package/dist/src/services/IntentService.d.ts +2 -1
- package/dist/src/services/IntentService.d.ts.map +1 -1
- package/dist/src/services/IntentService.js +23 -4
- package/dist/src/services/IntentService.js.map +1 -1
- package/dist/src/services/KnowledgeBaseService.d.ts +20 -5
- package/dist/src/services/KnowledgeBaseService.d.ts.map +1 -1
- package/dist/src/services/KnowledgeBaseService.js +203 -137
- package/dist/src/services/KnowledgeBaseService.js.map +1 -1
- package/dist/src/storage/FeedbackRepository.d.ts +1 -0
- package/dist/src/storage/FeedbackRepository.d.ts.map +1 -1
- package/dist/src/storage/FeedbackRepository.js +26 -0
- package/dist/src/storage/FeedbackRepository.js.map +1 -1
- package/dist/src/storage/UnifiedStorage.d.ts +1 -0
- package/dist/src/storage/UnifiedStorage.d.ts.map +1 -1
- package/dist/src/storage/UnifiedStorage.js +3 -0
- package/dist/src/storage/UnifiedStorage.js.map +1 -1
- package/package.json +2 -2
- 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);
|