agentic-qe 2.8.0 → 2.8.1
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/CHANGELOG.md +105 -0
- package/README.md +1 -1
- package/dist/agents/BaseAgent.d.ts +128 -0
- package/dist/agents/BaseAgent.d.ts.map +1 -1
- package/dist/agents/BaseAgent.js +256 -0
- package/dist/agents/BaseAgent.js.map +1 -1
- package/dist/cli/commands/supabase/index.d.ts +20 -0
- package/dist/cli/commands/supabase/index.d.ts.map +1 -0
- package/dist/cli/commands/supabase/index.js +632 -0
- package/dist/cli/commands/supabase/index.js.map +1 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/memory/HNSWVectorMemory.js +1 -1
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts +8 -8
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts.map +1 -1
- package/dist/mcp/handlers/NewDomainToolsHandler.js.map +1 -1
- package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts +54 -0
- package/dist/mcp/handlers/ruvector/RuVectorHandler.d.ts.map +1 -0
- package/dist/mcp/handlers/ruvector/RuVectorHandler.js +325 -0
- package/dist/mcp/handlers/ruvector/RuVectorHandler.js.map +1 -0
- package/dist/mcp/handlers/ruvector/index.d.ts +5 -0
- package/dist/mcp/handlers/ruvector/index.d.ts.map +1 -0
- package/dist/mcp/handlers/ruvector/index.js +9 -0
- package/dist/mcp/handlers/ruvector/index.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/server-instructions.js +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +100 -22
- package/dist/mcp/server.js.map +1 -1
- package/dist/nervous-system/adapters/BTSPAdapter.d.ts +342 -0
- package/dist/nervous-system/adapters/BTSPAdapter.d.ts.map +1 -0
- package/dist/nervous-system/adapters/BTSPAdapter.js +494 -0
- package/dist/nervous-system/adapters/BTSPAdapter.js.map +1 -0
- package/dist/nervous-system/adapters/CircadianController.d.ts +560 -0
- package/dist/nervous-system/adapters/CircadianController.d.ts.map +1 -0
- package/dist/nervous-system/adapters/CircadianController.js +882 -0
- package/dist/nervous-system/adapters/CircadianController.js.map +1 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts +337 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.d.ts.map +1 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js +532 -0
- package/dist/nervous-system/adapters/GlobalWorkspaceAdapter.js.map +1 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts +444 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.d.ts.map +1 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.js +715 -0
- package/dist/nervous-system/adapters/HdcMemoryAdapter.js.map +1 -0
- package/dist/nervous-system/adapters/ReflexLayer.d.ts +231 -0
- package/dist/nervous-system/adapters/ReflexLayer.d.ts.map +1 -0
- package/dist/nervous-system/adapters/ReflexLayer.js +309 -0
- package/dist/nervous-system/adapters/ReflexLayer.js.map +1 -0
- package/dist/nervous-system/index.d.ts +25 -0
- package/dist/nervous-system/index.d.ts.map +1 -0
- package/dist/nervous-system/index.js +80 -0
- package/dist/nervous-system/index.js.map +1 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.d.ts +266 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.d.ts.map +1 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.js +587 -0
- package/dist/nervous-system/integration/BTSPLearningEngine.js.map +1 -0
- package/dist/nervous-system/integration/CircadianAgent.d.ts +389 -0
- package/dist/nervous-system/integration/CircadianAgent.d.ts.map +1 -0
- package/dist/nervous-system/integration/CircadianAgent.js +696 -0
- package/dist/nervous-system/integration/CircadianAgent.js.map +1 -0
- package/dist/nervous-system/integration/HybridPatternStore.d.ts +244 -0
- package/dist/nervous-system/integration/HybridPatternStore.d.ts.map +1 -0
- package/dist/nervous-system/integration/HybridPatternStore.js +622 -0
- package/dist/nervous-system/integration/HybridPatternStore.js.map +1 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts +459 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.d.ts.map +1 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.js +921 -0
- package/dist/nervous-system/integration/NervousSystemEnhancement.js.map +1 -0
- package/dist/nervous-system/integration/WorkspaceAgent.d.ts +398 -0
- package/dist/nervous-system/integration/WorkspaceAgent.d.ts.map +1 -0
- package/dist/nervous-system/integration/WorkspaceAgent.js +722 -0
- package/dist/nervous-system/integration/WorkspaceAgent.js.map +1 -0
- package/dist/nervous-system/integration/index.d.ts +22 -0
- package/dist/nervous-system/integration/index.d.ts.map +1 -0
- package/dist/nervous-system/integration/index.js +44 -0
- package/dist/nervous-system/integration/index.js.map +1 -0
- package/dist/nervous-system/persistence/BTSPSerializer.d.ts +96 -0
- package/dist/nervous-system/persistence/BTSPSerializer.d.ts.map +1 -0
- package/dist/nervous-system/persistence/BTSPSerializer.js +223 -0
- package/dist/nervous-system/persistence/BTSPSerializer.js.map +1 -0
- package/dist/nervous-system/persistence/CircadianSerializer.d.ts +90 -0
- package/dist/nervous-system/persistence/CircadianSerializer.d.ts.map +1 -0
- package/dist/nervous-system/persistence/CircadianSerializer.js +239 -0
- package/dist/nervous-system/persistence/CircadianSerializer.js.map +1 -0
- package/dist/nervous-system/persistence/HdcSerializer.d.ts +100 -0
- package/dist/nervous-system/persistence/HdcSerializer.d.ts.map +1 -0
- package/dist/nervous-system/persistence/HdcSerializer.js +259 -0
- package/dist/nervous-system/persistence/HdcSerializer.js.map +1 -0
- package/dist/nervous-system/persistence/INervousSystemStore.d.ts +208 -0
- package/dist/nervous-system/persistence/INervousSystemStore.d.ts.map +1 -0
- package/dist/nervous-system/persistence/INervousSystemStore.js +11 -0
- package/dist/nervous-system/persistence/INervousSystemStore.js.map +1 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts +187 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.d.ts.map +1 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js +411 -0
- package/dist/nervous-system/persistence/NervousSystemPersistenceManager.js.map +1 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts +98 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.d.ts.map +1 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js +510 -0
- package/dist/nervous-system/persistence/SQLiteNervousSystemStore.js.map +1 -0
- package/dist/nervous-system/persistence/index.d.ts +22 -0
- package/dist/nervous-system/persistence/index.d.ts.map +1 -0
- package/dist/nervous-system/persistence/index.js +45 -0
- package/dist/nervous-system/persistence/index.js.map +1 -0
- package/dist/nervous-system/wasm-loader.d.ts +52 -0
- package/dist/nervous-system/wasm-loader.d.ts.map +1 -0
- package/dist/nervous-system/wasm-loader.js +188 -0
- package/dist/nervous-system/wasm-loader.js.map +1 -0
- package/dist/persistence/HybridPersistenceProvider.d.ts +184 -0
- package/dist/persistence/HybridPersistenceProvider.d.ts.map +1 -0
- package/dist/persistence/HybridPersistenceProvider.js +1086 -0
- package/dist/persistence/HybridPersistenceProvider.js.map +1 -0
- package/dist/persistence/IPersistenceProvider.d.ts +657 -0
- package/dist/persistence/IPersistenceProvider.d.ts.map +1 -0
- package/dist/persistence/IPersistenceProvider.js +11 -0
- package/dist/persistence/IPersistenceProvider.js.map +1 -0
- package/dist/persistence/SupabaseConfig.d.ts +176 -0
- package/dist/persistence/SupabaseConfig.d.ts.map +1 -0
- package/dist/persistence/SupabaseConfig.js +277 -0
- package/dist/persistence/SupabaseConfig.js.map +1 -0
- package/dist/persistence/SupabasePersistenceProvider.d.ts +143 -0
- package/dist/persistence/SupabasePersistenceProvider.d.ts.map +1 -0
- package/dist/persistence/SupabasePersistenceProvider.js +955 -0
- package/dist/persistence/SupabasePersistenceProvider.js.map +1 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts +213 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.d.ts.map +1 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js +468 -0
- package/dist/persistence/adapters/CodeIntelligenceSyncAdapter.js.map +1 -0
- package/dist/persistence/adapters/MemorySyncAdapter.d.ts +115 -0
- package/dist/persistence/adapters/MemorySyncAdapter.d.ts.map +1 -0
- package/dist/persistence/adapters/MemorySyncAdapter.js +291 -0
- package/dist/persistence/adapters/MemorySyncAdapter.js.map +1 -0
- package/dist/persistence/adapters/index.d.ts +11 -0
- package/dist/persistence/adapters/index.d.ts.map +1 -0
- package/dist/persistence/adapters/index.js +20 -0
- package/dist/persistence/adapters/index.js.map +1 -0
- package/dist/persistence/index.d.ts +14 -0
- package/dist/persistence/index.d.ts.map +1 -1
- package/dist/persistence/index.js +36 -1
- package/dist/persistence/index.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,955 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Supabase Persistence Provider
|
|
4
|
+
*
|
|
5
|
+
* Cloud persistence provider using Supabase PostgreSQL with RuVector extension.
|
|
6
|
+
* Supports multi-tenant data isolation via Row-Level Security and
|
|
7
|
+
* vector similarity search for intelligent experience/pattern matching.
|
|
8
|
+
*
|
|
9
|
+
* @module persistence/SupabasePersistenceProvider
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SupabasePersistenceProvider = void 0;
|
|
13
|
+
exports.createSupabasePersistenceProvider = createSupabasePersistenceProvider;
|
|
14
|
+
const supabase_js_1 = require("@supabase/supabase-js");
|
|
15
|
+
const SupabaseConfig_js_1 = require("./SupabaseConfig.js");
|
|
16
|
+
// ============================================
|
|
17
|
+
// Provider Implementation
|
|
18
|
+
// ============================================
|
|
19
|
+
/**
|
|
20
|
+
* Supabase cloud persistence provider
|
|
21
|
+
*
|
|
22
|
+
* Implements IPersistenceProvider using Supabase PostgreSQL backend.
|
|
23
|
+
* Features:
|
|
24
|
+
* - Multi-tenant data isolation via RLS
|
|
25
|
+
* - Vector similarity search via RuVector
|
|
26
|
+
* - Automatic embedding generation (optional)
|
|
27
|
+
* - Sharing between users/teams
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const provider = new SupabasePersistenceProvider({
|
|
32
|
+
* connection: {
|
|
33
|
+
* url: 'https://xxx.supabase.co',
|
|
34
|
+
* anonKey: 'xxx',
|
|
35
|
+
* },
|
|
36
|
+
* project: { projectId: 'my-project' },
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* await provider.initialize();
|
|
40
|
+
*
|
|
41
|
+
* // Store an experience
|
|
42
|
+
* await provider.storeExperience({
|
|
43
|
+
* id: 'exp-1',
|
|
44
|
+
* agentId: 'test-gen',
|
|
45
|
+
* agentType: 'test-generator',
|
|
46
|
+
* taskType: 'unit-test-generation',
|
|
47
|
+
* context: { sourceFile: 'UserService.ts' },
|
|
48
|
+
* outcome: { result: 'success', confidence: 0.95 },
|
|
49
|
+
* privacyLevel: 'team',
|
|
50
|
+
* isAnonymized: false,
|
|
51
|
+
* shareCount: 0,
|
|
52
|
+
* createdAt: new Date(),
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* // Search for similar experiences
|
|
56
|
+
* const similar = await provider.searchSimilarExperiences(embedding, 10);
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
class SupabasePersistenceProvider {
|
|
60
|
+
/**
|
|
61
|
+
* Create a new Supabase persistence provider
|
|
62
|
+
*
|
|
63
|
+
* @param configOverrides Configuration overrides
|
|
64
|
+
*/
|
|
65
|
+
constructor(configOverrides = {}) {
|
|
66
|
+
this.client = null;
|
|
67
|
+
this.projectId = null;
|
|
68
|
+
this.initialized = false;
|
|
69
|
+
this.config = (0, SupabaseConfig_js_1.buildSupabaseConfig)(configOverrides);
|
|
70
|
+
}
|
|
71
|
+
// ============================================
|
|
72
|
+
// Lifecycle
|
|
73
|
+
// ============================================
|
|
74
|
+
async initialize() {
|
|
75
|
+
if (this.initialized) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Create Supabase client
|
|
79
|
+
this.client = (0, supabase_js_1.createClient)(this.config.connection.url, this.config.connection.anonKey);
|
|
80
|
+
// Get or create project
|
|
81
|
+
this.projectId = await this.ensureProject();
|
|
82
|
+
this.initialized = true;
|
|
83
|
+
}
|
|
84
|
+
async shutdown() {
|
|
85
|
+
// Supabase client doesn't need explicit cleanup
|
|
86
|
+
this.client = null;
|
|
87
|
+
this.initialized = false;
|
|
88
|
+
}
|
|
89
|
+
// ============================================
|
|
90
|
+
// Learning Experiences
|
|
91
|
+
// ============================================
|
|
92
|
+
async storeExperience(experience) {
|
|
93
|
+
this.ensureInitialized();
|
|
94
|
+
const row = {
|
|
95
|
+
id: experience.id,
|
|
96
|
+
project_id: this.projectId,
|
|
97
|
+
agent_id: experience.agentId,
|
|
98
|
+
agent_type: experience.agentType,
|
|
99
|
+
task_type: experience.taskType,
|
|
100
|
+
context: experience.context,
|
|
101
|
+
outcome: experience.outcome,
|
|
102
|
+
embedding: experience.embedding ?? null,
|
|
103
|
+
privacy_level: experience.privacyLevel,
|
|
104
|
+
is_anonymized: experience.isAnonymized,
|
|
105
|
+
share_count: experience.shareCount,
|
|
106
|
+
confidence: experience.outcome.confidence,
|
|
107
|
+
created_at: experience.createdAt.toISOString(),
|
|
108
|
+
created_by: experience.createdBy ?? null,
|
|
109
|
+
};
|
|
110
|
+
const { error } = await this.client
|
|
111
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
|
|
112
|
+
.upsert(row, { onConflict: 'id' });
|
|
113
|
+
if (error) {
|
|
114
|
+
throw new Error(`Failed to store experience: ${error.message}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async queryExperiences(query) {
|
|
118
|
+
this.ensureInitialized();
|
|
119
|
+
let queryBuilder = this.client
|
|
120
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
|
|
121
|
+
.select('*')
|
|
122
|
+
.eq('project_id', this.projectId);
|
|
123
|
+
// Apply filters
|
|
124
|
+
if (query.agentId) {
|
|
125
|
+
queryBuilder = queryBuilder.eq('agent_id', query.agentId);
|
|
126
|
+
}
|
|
127
|
+
if (query.agentType) {
|
|
128
|
+
queryBuilder = queryBuilder.eq('agent_type', query.agentType);
|
|
129
|
+
}
|
|
130
|
+
if (query.taskType) {
|
|
131
|
+
queryBuilder = queryBuilder.eq('task_type', query.taskType);
|
|
132
|
+
}
|
|
133
|
+
if (query.outcome) {
|
|
134
|
+
queryBuilder = queryBuilder.eq('outcome->result', query.outcome);
|
|
135
|
+
}
|
|
136
|
+
if (query.privacyLevel) {
|
|
137
|
+
queryBuilder = queryBuilder.eq('privacy_level', query.privacyLevel);
|
|
138
|
+
}
|
|
139
|
+
if (query.minConfidence !== undefined) {
|
|
140
|
+
queryBuilder = queryBuilder.gte('confidence', query.minConfidence);
|
|
141
|
+
}
|
|
142
|
+
if (query.startDate) {
|
|
143
|
+
queryBuilder = queryBuilder.gte('created_at', query.startDate.toISOString());
|
|
144
|
+
}
|
|
145
|
+
if (query.endDate) {
|
|
146
|
+
queryBuilder = queryBuilder.lte('created_at', query.endDate.toISOString());
|
|
147
|
+
}
|
|
148
|
+
// Apply pagination
|
|
149
|
+
if (query.offset) {
|
|
150
|
+
queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 50) - 1);
|
|
151
|
+
}
|
|
152
|
+
else if (query.limit) {
|
|
153
|
+
queryBuilder = queryBuilder.limit(query.limit);
|
|
154
|
+
}
|
|
155
|
+
// Order by created_at descending
|
|
156
|
+
queryBuilder = queryBuilder.order('created_at', { ascending: false });
|
|
157
|
+
const { data, error } = await queryBuilder;
|
|
158
|
+
if (error) {
|
|
159
|
+
throw new Error(`Failed to query experiences: ${error.message}`);
|
|
160
|
+
}
|
|
161
|
+
return data.map(this.rowToExperience);
|
|
162
|
+
}
|
|
163
|
+
async searchSimilarExperiences(embedding, limit) {
|
|
164
|
+
this.ensureInitialized();
|
|
165
|
+
// Use RPC function for vector similarity search
|
|
166
|
+
const { data, error } = await this.client.rpc('search_similar_experiences', {
|
|
167
|
+
query_embedding: embedding,
|
|
168
|
+
match_threshold: 0.7,
|
|
169
|
+
match_count: limit,
|
|
170
|
+
});
|
|
171
|
+
if (error) {
|
|
172
|
+
throw new Error(`Failed to search experiences: ${error.message}`);
|
|
173
|
+
}
|
|
174
|
+
// The RPC returns a different shape, map it
|
|
175
|
+
return data.map((row) => ({
|
|
176
|
+
...this.rowToExperience(row),
|
|
177
|
+
// Could add similarity score to metadata if needed
|
|
178
|
+
}));
|
|
179
|
+
}
|
|
180
|
+
// ============================================
|
|
181
|
+
// Patterns
|
|
182
|
+
// ============================================
|
|
183
|
+
async storePattern(pattern) {
|
|
184
|
+
this.ensureInitialized();
|
|
185
|
+
const row = {
|
|
186
|
+
id: pattern.id,
|
|
187
|
+
project_id: this.projectId,
|
|
188
|
+
type: pattern.type,
|
|
189
|
+
domain: pattern.domain ?? 'general',
|
|
190
|
+
framework: pattern.framework ?? null,
|
|
191
|
+
content: pattern.content ?? '',
|
|
192
|
+
embedding: pattern.embedding ?? null,
|
|
193
|
+
confidence: pattern.confidence,
|
|
194
|
+
usage_count: pattern.usageCount,
|
|
195
|
+
last_used: pattern.lastUsed?.toISOString() ?? null,
|
|
196
|
+
verdict: pattern.verdict ?? null,
|
|
197
|
+
privacy_level: pattern.privacyLevel,
|
|
198
|
+
is_anonymized: pattern.isAnonymized,
|
|
199
|
+
source_hash: pattern.sourceHash ?? null,
|
|
200
|
+
metadata: pattern.metadata,
|
|
201
|
+
created_at: pattern.createdAt.toISOString(),
|
|
202
|
+
};
|
|
203
|
+
const { error } = await this.client
|
|
204
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
|
|
205
|
+
.upsert(row, { onConflict: 'id' });
|
|
206
|
+
if (error) {
|
|
207
|
+
throw new Error(`Failed to store pattern: ${error.message}`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
async queryPatterns(query) {
|
|
211
|
+
this.ensureInitialized();
|
|
212
|
+
let queryBuilder = this.client
|
|
213
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
|
|
214
|
+
.select('*')
|
|
215
|
+
.eq('project_id', this.projectId);
|
|
216
|
+
// Apply filters
|
|
217
|
+
if (query.type) {
|
|
218
|
+
queryBuilder = queryBuilder.eq('type', query.type);
|
|
219
|
+
}
|
|
220
|
+
if (query.domain) {
|
|
221
|
+
queryBuilder = queryBuilder.eq('domain', query.domain);
|
|
222
|
+
}
|
|
223
|
+
if (query.framework) {
|
|
224
|
+
queryBuilder = queryBuilder.eq('framework', query.framework);
|
|
225
|
+
}
|
|
226
|
+
if (query.privacyLevel) {
|
|
227
|
+
queryBuilder = queryBuilder.eq('privacy_level', query.privacyLevel);
|
|
228
|
+
}
|
|
229
|
+
if (query.minConfidence !== undefined) {
|
|
230
|
+
queryBuilder = queryBuilder.gte('confidence', query.minConfidence);
|
|
231
|
+
}
|
|
232
|
+
// Apply pagination
|
|
233
|
+
if (query.offset) {
|
|
234
|
+
queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 50) - 1);
|
|
235
|
+
}
|
|
236
|
+
else if (query.limit) {
|
|
237
|
+
queryBuilder = queryBuilder.limit(query.limit);
|
|
238
|
+
}
|
|
239
|
+
// Order by usage_count descending (most used first)
|
|
240
|
+
queryBuilder = queryBuilder.order('usage_count', { ascending: false });
|
|
241
|
+
const { data, error } = await queryBuilder;
|
|
242
|
+
if (error) {
|
|
243
|
+
throw new Error(`Failed to query patterns: ${error.message}`);
|
|
244
|
+
}
|
|
245
|
+
return data.map(this.rowToPattern);
|
|
246
|
+
}
|
|
247
|
+
async searchSimilarPatterns(embedding, limit) {
|
|
248
|
+
this.ensureInitialized();
|
|
249
|
+
// Use RPC function for vector similarity search
|
|
250
|
+
const { data, error } = await this.client.rpc('search_similar_patterns', {
|
|
251
|
+
query_embedding: embedding,
|
|
252
|
+
match_threshold: 0.7,
|
|
253
|
+
match_count: limit,
|
|
254
|
+
});
|
|
255
|
+
if (error) {
|
|
256
|
+
throw new Error(`Failed to search patterns: ${error.message}`);
|
|
257
|
+
}
|
|
258
|
+
// Map RPC result to StoredPattern
|
|
259
|
+
return data.map(this.rowToPattern);
|
|
260
|
+
}
|
|
261
|
+
// ============================================
|
|
262
|
+
// Nervous System State
|
|
263
|
+
// ============================================
|
|
264
|
+
async saveNervousSystemState(agentId, component, state) {
|
|
265
|
+
this.ensureInitialized();
|
|
266
|
+
const isBinary = state instanceof Uint8Array;
|
|
267
|
+
const row = {
|
|
268
|
+
project_id: this.projectId,
|
|
269
|
+
agent_id: agentId,
|
|
270
|
+
component,
|
|
271
|
+
state_data: isBinary ? this.uint8ArrayToBase64(state) : null,
|
|
272
|
+
state_json: isBinary ? null : state,
|
|
273
|
+
version: 1,
|
|
274
|
+
updated_at: new Date().toISOString(),
|
|
275
|
+
};
|
|
276
|
+
const { error } = await this.client
|
|
277
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
|
|
278
|
+
.upsert(row, {
|
|
279
|
+
onConflict: 'project_id,agent_id,component',
|
|
280
|
+
});
|
|
281
|
+
if (error) {
|
|
282
|
+
throw new Error(`Failed to save nervous system state: ${error.message}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async loadNervousSystemState(agentId, component) {
|
|
286
|
+
this.ensureInitialized();
|
|
287
|
+
const { data, error } = await this.client
|
|
288
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
|
|
289
|
+
.select('*')
|
|
290
|
+
.eq('project_id', this.projectId)
|
|
291
|
+
.eq('agent_id', agentId)
|
|
292
|
+
.eq('component', component)
|
|
293
|
+
.single();
|
|
294
|
+
if (error) {
|
|
295
|
+
if (error.code === 'PGRST116') {
|
|
296
|
+
// No rows returned
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
throw new Error(`Failed to load nervous system state: ${error.message}`);
|
|
300
|
+
}
|
|
301
|
+
const row = data;
|
|
302
|
+
if (row.state_data) {
|
|
303
|
+
return this.base64ToUint8Array(row.state_data);
|
|
304
|
+
}
|
|
305
|
+
return row.state_json;
|
|
306
|
+
}
|
|
307
|
+
async deleteNervousSystemState(agentId) {
|
|
308
|
+
this.ensureInitialized();
|
|
309
|
+
const { error } = await this.client
|
|
310
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
|
|
311
|
+
.delete()
|
|
312
|
+
.eq('project_id', this.projectId)
|
|
313
|
+
.eq('agent_id', agentId);
|
|
314
|
+
if (error) {
|
|
315
|
+
throw new Error(`Failed to delete nervous system state: ${error.message}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async listAgentsWithState() {
|
|
319
|
+
this.ensureInitialized();
|
|
320
|
+
const { data, error } = await this.client
|
|
321
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.NERVOUS_SYSTEM)
|
|
322
|
+
.select('agent_id')
|
|
323
|
+
.eq('project_id', this.projectId);
|
|
324
|
+
if (error) {
|
|
325
|
+
throw new Error(`Failed to list agents: ${error.message}`);
|
|
326
|
+
}
|
|
327
|
+
// Get unique agent IDs
|
|
328
|
+
const agentIds = new Set(data.map((r) => r.agent_id));
|
|
329
|
+
return Array.from(agentIds);
|
|
330
|
+
}
|
|
331
|
+
// ============================================
|
|
332
|
+
// Sharing (Cloud-specific)
|
|
333
|
+
// ============================================
|
|
334
|
+
async shareExperience(experienceId, privacyLevel) {
|
|
335
|
+
this.ensureInitialized();
|
|
336
|
+
const { error } = await this.client
|
|
337
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
|
|
338
|
+
.update({
|
|
339
|
+
privacy_level: privacyLevel,
|
|
340
|
+
share_count: this.client.rpc('increment_share_count'),
|
|
341
|
+
})
|
|
342
|
+
.eq('id', experienceId)
|
|
343
|
+
.eq('project_id', this.projectId);
|
|
344
|
+
if (error) {
|
|
345
|
+
throw new Error(`Failed to share experience: ${error.message}`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
async importSharedExperiences(query) {
|
|
349
|
+
this.ensureInitialized();
|
|
350
|
+
let queryBuilder = this.client
|
|
351
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EXPERIENCES)
|
|
352
|
+
.select('*');
|
|
353
|
+
// Build privacy filter
|
|
354
|
+
const privacyFilters = [];
|
|
355
|
+
if (query.includePublic) {
|
|
356
|
+
privacyFilters.push('public');
|
|
357
|
+
}
|
|
358
|
+
if (query.includeTeam) {
|
|
359
|
+
privacyFilters.push('team');
|
|
360
|
+
}
|
|
361
|
+
if (privacyFilters.length > 0) {
|
|
362
|
+
queryBuilder = queryBuilder.in('privacy_level', privacyFilters);
|
|
363
|
+
}
|
|
364
|
+
// Exclude own project's experiences
|
|
365
|
+
queryBuilder = queryBuilder.neq('project_id', this.projectId);
|
|
366
|
+
// Apply other filters
|
|
367
|
+
if (query.agentType) {
|
|
368
|
+
queryBuilder = queryBuilder.eq('agent_type', query.agentType);
|
|
369
|
+
}
|
|
370
|
+
if (query.taskType) {
|
|
371
|
+
queryBuilder = queryBuilder.eq('task_type', query.taskType);
|
|
372
|
+
}
|
|
373
|
+
if (query.minQuality !== undefined) {
|
|
374
|
+
queryBuilder = queryBuilder.gte('confidence', query.minQuality);
|
|
375
|
+
}
|
|
376
|
+
// Apply pagination
|
|
377
|
+
if (query.limit) {
|
|
378
|
+
queryBuilder = queryBuilder.limit(query.limit);
|
|
379
|
+
}
|
|
380
|
+
const { data, error } = await queryBuilder;
|
|
381
|
+
if (error) {
|
|
382
|
+
throw new Error(`Failed to import shared experiences: ${error.message}`);
|
|
383
|
+
}
|
|
384
|
+
return data.map(this.rowToExperience);
|
|
385
|
+
}
|
|
386
|
+
async sharePattern(patternId, privacyLevel) {
|
|
387
|
+
this.ensureInitialized();
|
|
388
|
+
const { error } = await this.client
|
|
389
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
|
|
390
|
+
.update({ privacy_level: privacyLevel })
|
|
391
|
+
.eq('id', patternId)
|
|
392
|
+
.eq('project_id', this.projectId);
|
|
393
|
+
if (error) {
|
|
394
|
+
throw new Error(`Failed to share pattern: ${error.message}`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
async importSharedPatterns(query) {
|
|
398
|
+
this.ensureInitialized();
|
|
399
|
+
let queryBuilder = this.client
|
|
400
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.PATTERNS)
|
|
401
|
+
.select('*');
|
|
402
|
+
// Only public patterns for import
|
|
403
|
+
if (query.includePublic) {
|
|
404
|
+
queryBuilder = queryBuilder.eq('privacy_level', 'public');
|
|
405
|
+
}
|
|
406
|
+
// Exclude own project
|
|
407
|
+
queryBuilder = queryBuilder.neq('project_id', this.projectId);
|
|
408
|
+
// Apply filters
|
|
409
|
+
if (query.type) {
|
|
410
|
+
queryBuilder = queryBuilder.eq('type', query.type);
|
|
411
|
+
}
|
|
412
|
+
if (query.domain) {
|
|
413
|
+
queryBuilder = queryBuilder.eq('domain', query.domain);
|
|
414
|
+
}
|
|
415
|
+
if (query.framework) {
|
|
416
|
+
queryBuilder = queryBuilder.eq('framework', query.framework);
|
|
417
|
+
}
|
|
418
|
+
if (query.minConfidence !== undefined) {
|
|
419
|
+
queryBuilder = queryBuilder.gte('confidence', query.minConfidence);
|
|
420
|
+
}
|
|
421
|
+
// Apply pagination
|
|
422
|
+
if (query.limit) {
|
|
423
|
+
queryBuilder = queryBuilder.limit(query.limit);
|
|
424
|
+
}
|
|
425
|
+
const { data, error } = await queryBuilder;
|
|
426
|
+
if (error) {
|
|
427
|
+
throw new Error(`Failed to import shared patterns: ${error.message}`);
|
|
428
|
+
}
|
|
429
|
+
return data.map(this.rowToPattern);
|
|
430
|
+
}
|
|
431
|
+
// ============================================
|
|
432
|
+
// Memory Entries
|
|
433
|
+
// ============================================
|
|
434
|
+
async storeMemoryEntry(entry) {
|
|
435
|
+
this.ensureInitialized();
|
|
436
|
+
const row = {
|
|
437
|
+
project_id: this.projectId,
|
|
438
|
+
key: entry.key,
|
|
439
|
+
partition: entry.partition,
|
|
440
|
+
value: entry.value,
|
|
441
|
+
owner: entry.owner,
|
|
442
|
+
access_level: entry.accessLevel,
|
|
443
|
+
team_id: entry.teamId ?? null,
|
|
444
|
+
swarm_id: entry.swarmId ?? null,
|
|
445
|
+
metadata: entry.metadata ?? null,
|
|
446
|
+
created_at: entry.createdAt.toISOString(),
|
|
447
|
+
expires_at: entry.expiresAt?.toISOString() ?? null,
|
|
448
|
+
};
|
|
449
|
+
const { error } = await this.client
|
|
450
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
|
|
451
|
+
.upsert(row, { onConflict: 'project_id,partition,key' });
|
|
452
|
+
if (error) {
|
|
453
|
+
throw new Error(`Failed to store memory entry: ${error.message}`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
async storeMemoryEntries(entries) {
|
|
457
|
+
if (entries.length === 0)
|
|
458
|
+
return;
|
|
459
|
+
this.ensureInitialized();
|
|
460
|
+
const rows = entries.map((entry) => ({
|
|
461
|
+
project_id: this.projectId,
|
|
462
|
+
key: entry.key,
|
|
463
|
+
partition: entry.partition,
|
|
464
|
+
value: entry.value,
|
|
465
|
+
owner: entry.owner,
|
|
466
|
+
access_level: entry.accessLevel,
|
|
467
|
+
team_id: entry.teamId ?? null,
|
|
468
|
+
swarm_id: entry.swarmId ?? null,
|
|
469
|
+
metadata: entry.metadata ?? null,
|
|
470
|
+
created_at: entry.createdAt.toISOString(),
|
|
471
|
+
expires_at: entry.expiresAt?.toISOString() ?? null,
|
|
472
|
+
}));
|
|
473
|
+
const { error } = await this.client
|
|
474
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
|
|
475
|
+
.upsert(rows, { onConflict: 'project_id,partition,key' });
|
|
476
|
+
if (error) {
|
|
477
|
+
throw new Error(`Failed to store memory entries: ${error.message}`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
async getMemoryEntry(key, partition = 'default') {
|
|
481
|
+
this.ensureInitialized();
|
|
482
|
+
const { data, error } = await this.client
|
|
483
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
|
|
484
|
+
.select('*')
|
|
485
|
+
.eq('project_id', this.projectId)
|
|
486
|
+
.eq('partition', partition)
|
|
487
|
+
.eq('key', key)
|
|
488
|
+
.single();
|
|
489
|
+
if (error) {
|
|
490
|
+
if (error.code === 'PGRST116') {
|
|
491
|
+
return null;
|
|
492
|
+
}
|
|
493
|
+
throw new Error(`Failed to get memory entry: ${error.message}`);
|
|
494
|
+
}
|
|
495
|
+
return this.rowToMemoryEntry(data);
|
|
496
|
+
}
|
|
497
|
+
async queryMemoryEntries(query) {
|
|
498
|
+
this.ensureInitialized();
|
|
499
|
+
let queryBuilder = this.client
|
|
500
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
|
|
501
|
+
.select('*')
|
|
502
|
+
.eq('project_id', this.projectId);
|
|
503
|
+
if (query.partition) {
|
|
504
|
+
queryBuilder = queryBuilder.eq('partition', query.partition);
|
|
505
|
+
}
|
|
506
|
+
if (query.owner) {
|
|
507
|
+
queryBuilder = queryBuilder.eq('owner', query.owner);
|
|
508
|
+
}
|
|
509
|
+
if (query.keyPattern) {
|
|
510
|
+
queryBuilder = queryBuilder.ilike('key', query.keyPattern.replace('*', '%'));
|
|
511
|
+
}
|
|
512
|
+
if (query.accessLevel) {
|
|
513
|
+
queryBuilder = queryBuilder.eq('access_level', query.accessLevel);
|
|
514
|
+
}
|
|
515
|
+
if (!query.includeExpired) {
|
|
516
|
+
queryBuilder = queryBuilder.or('expires_at.is.null,expires_at.gt.now()');
|
|
517
|
+
}
|
|
518
|
+
if (query.offset) {
|
|
519
|
+
queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 100) - 1);
|
|
520
|
+
}
|
|
521
|
+
else if (query.limit) {
|
|
522
|
+
queryBuilder = queryBuilder.limit(query.limit);
|
|
523
|
+
}
|
|
524
|
+
const { data, error } = await queryBuilder;
|
|
525
|
+
if (error) {
|
|
526
|
+
throw new Error(`Failed to query memory entries: ${error.message}`);
|
|
527
|
+
}
|
|
528
|
+
return data.map(this.rowToMemoryEntry);
|
|
529
|
+
}
|
|
530
|
+
async deleteMemoryEntries(keyPattern, partition) {
|
|
531
|
+
this.ensureInitialized();
|
|
532
|
+
let queryBuilder = this.client
|
|
533
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.MEMORY_ENTRIES)
|
|
534
|
+
.delete()
|
|
535
|
+
.eq('project_id', this.projectId)
|
|
536
|
+
.ilike('key', keyPattern.replace('*', '%'));
|
|
537
|
+
if (partition) {
|
|
538
|
+
queryBuilder = queryBuilder.eq('partition', partition);
|
|
539
|
+
}
|
|
540
|
+
const { data, error } = await queryBuilder.select('id');
|
|
541
|
+
if (error) {
|
|
542
|
+
throw new Error(`Failed to delete memory entries: ${error.message}`);
|
|
543
|
+
}
|
|
544
|
+
return data.length;
|
|
545
|
+
}
|
|
546
|
+
// ============================================
|
|
547
|
+
// Events
|
|
548
|
+
// ============================================
|
|
549
|
+
async storeEvent(event) {
|
|
550
|
+
this.ensureInitialized();
|
|
551
|
+
const row = {
|
|
552
|
+
id: event.id,
|
|
553
|
+
project_id: this.projectId,
|
|
554
|
+
type: event.type,
|
|
555
|
+
payload: event.payload,
|
|
556
|
+
source: event.source,
|
|
557
|
+
timestamp: event.timestamp.toISOString(),
|
|
558
|
+
ttl: event.ttl,
|
|
559
|
+
};
|
|
560
|
+
const { error } = await this.client
|
|
561
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
|
|
562
|
+
.insert(row);
|
|
563
|
+
if (error) {
|
|
564
|
+
throw new Error(`Failed to store event: ${error.message}`);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
async storeEvents(events) {
|
|
568
|
+
if (events.length === 0)
|
|
569
|
+
return;
|
|
570
|
+
this.ensureInitialized();
|
|
571
|
+
const rows = events.map((event) => ({
|
|
572
|
+
id: event.id,
|
|
573
|
+
project_id: this.projectId,
|
|
574
|
+
type: event.type,
|
|
575
|
+
payload: event.payload,
|
|
576
|
+
source: event.source,
|
|
577
|
+
timestamp: event.timestamp.toISOString(),
|
|
578
|
+
ttl: event.ttl,
|
|
579
|
+
}));
|
|
580
|
+
const { error } = await this.client
|
|
581
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
|
|
582
|
+
.insert(rows);
|
|
583
|
+
if (error) {
|
|
584
|
+
throw new Error(`Failed to store events: ${error.message}`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
async queryEvents(query) {
|
|
588
|
+
this.ensureInitialized();
|
|
589
|
+
let queryBuilder = this.client
|
|
590
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
|
|
591
|
+
.select('*')
|
|
592
|
+
.eq('project_id', this.projectId);
|
|
593
|
+
if (query.type) {
|
|
594
|
+
queryBuilder = queryBuilder.eq('type', query.type);
|
|
595
|
+
}
|
|
596
|
+
if (query.source) {
|
|
597
|
+
queryBuilder = queryBuilder.eq('source', query.source);
|
|
598
|
+
}
|
|
599
|
+
if (query.startTime) {
|
|
600
|
+
queryBuilder = queryBuilder.gte('timestamp', query.startTime.toISOString());
|
|
601
|
+
}
|
|
602
|
+
if (query.endTime) {
|
|
603
|
+
queryBuilder = queryBuilder.lte('timestamp', query.endTime.toISOString());
|
|
604
|
+
}
|
|
605
|
+
queryBuilder = queryBuilder.order('timestamp', { ascending: false });
|
|
606
|
+
if (query.offset) {
|
|
607
|
+
queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 100) - 1);
|
|
608
|
+
}
|
|
609
|
+
else if (query.limit) {
|
|
610
|
+
queryBuilder = queryBuilder.limit(query.limit);
|
|
611
|
+
}
|
|
612
|
+
const { data, error } = await queryBuilder;
|
|
613
|
+
if (error) {
|
|
614
|
+
throw new Error(`Failed to query events: ${error.message}`);
|
|
615
|
+
}
|
|
616
|
+
return data.map(this.rowToEvent);
|
|
617
|
+
}
|
|
618
|
+
async deleteOldEvents(olderThan) {
|
|
619
|
+
this.ensureInitialized();
|
|
620
|
+
const { data, error } = await this.client
|
|
621
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.EVENTS)
|
|
622
|
+
.delete()
|
|
623
|
+
.eq('project_id', this.projectId)
|
|
624
|
+
.lt('timestamp', olderThan.toISOString())
|
|
625
|
+
.select('id');
|
|
626
|
+
if (error) {
|
|
627
|
+
throw new Error(`Failed to delete old events: ${error.message}`);
|
|
628
|
+
}
|
|
629
|
+
return data.length;
|
|
630
|
+
}
|
|
631
|
+
// ============================================
|
|
632
|
+
// Code Chunks
|
|
633
|
+
// ============================================
|
|
634
|
+
async storeCodeChunk(chunk) {
|
|
635
|
+
this.ensureInitialized();
|
|
636
|
+
const row = {
|
|
637
|
+
id: chunk.id,
|
|
638
|
+
project_id: this.projectId,
|
|
639
|
+
file_path: chunk.filePath,
|
|
640
|
+
start_line: chunk.startLine,
|
|
641
|
+
end_line: chunk.endLine,
|
|
642
|
+
chunk_type: chunk.chunkType,
|
|
643
|
+
name: chunk.name ?? null,
|
|
644
|
+
language: chunk.language,
|
|
645
|
+
content: chunk.content,
|
|
646
|
+
embedding: chunk.embedding ?? null,
|
|
647
|
+
metadata: chunk.metadata ?? null,
|
|
648
|
+
commit_sha: chunk.commitSha ?? null,
|
|
649
|
+
indexed_at: chunk.indexedAt.toISOString(),
|
|
650
|
+
};
|
|
651
|
+
const { error } = await this.client
|
|
652
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
|
|
653
|
+
.upsert(row, { onConflict: 'project_id,file_path,start_line,end_line' });
|
|
654
|
+
if (error) {
|
|
655
|
+
throw new Error(`Failed to store code chunk: ${error.message}`);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
async storeCodeChunks(chunks) {
|
|
659
|
+
if (chunks.length === 0)
|
|
660
|
+
return;
|
|
661
|
+
this.ensureInitialized();
|
|
662
|
+
const rows = chunks.map((chunk) => ({
|
|
663
|
+
id: chunk.id,
|
|
664
|
+
project_id: this.projectId,
|
|
665
|
+
file_path: chunk.filePath,
|
|
666
|
+
start_line: chunk.startLine,
|
|
667
|
+
end_line: chunk.endLine,
|
|
668
|
+
chunk_type: chunk.chunkType,
|
|
669
|
+
name: chunk.name ?? null,
|
|
670
|
+
language: chunk.language,
|
|
671
|
+
content: chunk.content,
|
|
672
|
+
embedding: chunk.embedding ?? null,
|
|
673
|
+
metadata: chunk.metadata ?? null,
|
|
674
|
+
commit_sha: chunk.commitSha ?? null,
|
|
675
|
+
indexed_at: chunk.indexedAt.toISOString(),
|
|
676
|
+
}));
|
|
677
|
+
const { error } = await this.client
|
|
678
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
|
|
679
|
+
.upsert(rows, { onConflict: 'project_id,file_path,start_line,end_line' });
|
|
680
|
+
if (error) {
|
|
681
|
+
throw new Error(`Failed to store code chunks: ${error.message}`);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
async queryCodeChunks(query) {
|
|
685
|
+
this.ensureInitialized();
|
|
686
|
+
let queryBuilder = this.client
|
|
687
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
|
|
688
|
+
.select('*')
|
|
689
|
+
.eq('project_id', query.projectId ?? this.projectId);
|
|
690
|
+
if (query.filePattern) {
|
|
691
|
+
queryBuilder = queryBuilder.ilike('file_path', query.filePattern.replace('*', '%'));
|
|
692
|
+
}
|
|
693
|
+
if (query.chunkType) {
|
|
694
|
+
queryBuilder = queryBuilder.eq('chunk_type', query.chunkType);
|
|
695
|
+
}
|
|
696
|
+
if (query.language) {
|
|
697
|
+
queryBuilder = queryBuilder.eq('language', query.language);
|
|
698
|
+
}
|
|
699
|
+
if (query.namePattern) {
|
|
700
|
+
queryBuilder = queryBuilder.ilike('name', query.namePattern.replace('*', '%'));
|
|
701
|
+
}
|
|
702
|
+
if (query.offset) {
|
|
703
|
+
queryBuilder = queryBuilder.range(query.offset, query.offset + (query.limit ?? 100) - 1);
|
|
704
|
+
}
|
|
705
|
+
else if (query.limit) {
|
|
706
|
+
queryBuilder = queryBuilder.limit(query.limit);
|
|
707
|
+
}
|
|
708
|
+
const { data, error } = await queryBuilder;
|
|
709
|
+
if (error) {
|
|
710
|
+
throw new Error(`Failed to query code chunks: ${error.message}`);
|
|
711
|
+
}
|
|
712
|
+
return data.map(this.rowToCodeChunk);
|
|
713
|
+
}
|
|
714
|
+
async searchSimilarCode(embedding, options) {
|
|
715
|
+
this.ensureInitialized();
|
|
716
|
+
const { data, error } = await this.client.rpc('search_similar_code', {
|
|
717
|
+
query_embedding: embedding,
|
|
718
|
+
match_threshold: options?.minScore ?? 0.7,
|
|
719
|
+
match_count: options?.limit ?? 10,
|
|
720
|
+
filter_project_id: options?.projectId ?? this.projectId,
|
|
721
|
+
filter_language: options?.language ?? null,
|
|
722
|
+
});
|
|
723
|
+
if (error) {
|
|
724
|
+
throw new Error(`Failed to search similar code: ${error.message}`);
|
|
725
|
+
}
|
|
726
|
+
return data.map((row) => ({
|
|
727
|
+
chunk: this.rowToCodeChunk(row),
|
|
728
|
+
score: row.similarity,
|
|
729
|
+
}));
|
|
730
|
+
}
|
|
731
|
+
async deleteCodeChunksForFile(projectId, filePath) {
|
|
732
|
+
this.ensureInitialized();
|
|
733
|
+
const { data, error } = await this.client
|
|
734
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
|
|
735
|
+
.delete()
|
|
736
|
+
.eq('project_id', projectId)
|
|
737
|
+
.eq('file_path', filePath)
|
|
738
|
+
.select('id');
|
|
739
|
+
if (error) {
|
|
740
|
+
throw new Error(`Failed to delete code chunks for file: ${error.message}`);
|
|
741
|
+
}
|
|
742
|
+
return data.length;
|
|
743
|
+
}
|
|
744
|
+
async deleteCodeChunksForProject(projectId) {
|
|
745
|
+
this.ensureInitialized();
|
|
746
|
+
const { data, error } = await this.client
|
|
747
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.CODE_CHUNKS)
|
|
748
|
+
.delete()
|
|
749
|
+
.eq('project_id', projectId)
|
|
750
|
+
.select('id');
|
|
751
|
+
if (error) {
|
|
752
|
+
throw new Error(`Failed to delete code chunks for project: ${error.message}`);
|
|
753
|
+
}
|
|
754
|
+
return data.length;
|
|
755
|
+
}
|
|
756
|
+
// ============================================
|
|
757
|
+
// Info
|
|
758
|
+
// ============================================
|
|
759
|
+
getProviderInfo() {
|
|
760
|
+
return {
|
|
761
|
+
type: 'supabase',
|
|
762
|
+
features: [
|
|
763
|
+
'cloud-persistence',
|
|
764
|
+
'vector-search',
|
|
765
|
+
'multi-tenant',
|
|
766
|
+
'rls-security',
|
|
767
|
+
'experience-sharing',
|
|
768
|
+
'pattern-sharing',
|
|
769
|
+
'real-time-sync',
|
|
770
|
+
'memory-sync',
|
|
771
|
+
'event-sync',
|
|
772
|
+
'code-intelligence-sync',
|
|
773
|
+
],
|
|
774
|
+
initialized: this.initialized,
|
|
775
|
+
location: this.config.connection.url,
|
|
776
|
+
};
|
|
777
|
+
}
|
|
778
|
+
// ============================================
|
|
779
|
+
// Private Methods
|
|
780
|
+
// ============================================
|
|
781
|
+
ensureInitialized() {
|
|
782
|
+
if (!this.initialized || !this.client) {
|
|
783
|
+
throw new Error('SupabasePersistenceProvider not initialized. Call initialize() first.');
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Get or create the project for this provider
|
|
788
|
+
*/
|
|
789
|
+
async ensureProject() {
|
|
790
|
+
// If project ID is configured, use it
|
|
791
|
+
if (this.config.project.projectId) {
|
|
792
|
+
return this.config.project.projectId;
|
|
793
|
+
}
|
|
794
|
+
// Try to get current user's default project
|
|
795
|
+
const { data: user } = await this.client.auth.getUser();
|
|
796
|
+
if (user?.user) {
|
|
797
|
+
const { data: projects } = await this.client
|
|
798
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.PROJECTS)
|
|
799
|
+
.select('id')
|
|
800
|
+
.eq('owner_id', user.user.id)
|
|
801
|
+
.limit(1);
|
|
802
|
+
if (projects && projects.length > 0) {
|
|
803
|
+
return projects[0].id;
|
|
804
|
+
}
|
|
805
|
+
// Create a default project
|
|
806
|
+
const { data: newProject, error } = await this.client
|
|
807
|
+
.from(SupabaseConfig_js_1.SUPABASE_TABLES.PROJECTS)
|
|
808
|
+
.insert({
|
|
809
|
+
name: 'Default Project',
|
|
810
|
+
owner_id: user.user.id,
|
|
811
|
+
settings: this.config.sharing,
|
|
812
|
+
})
|
|
813
|
+
.select('id')
|
|
814
|
+
.single();
|
|
815
|
+
if (error) {
|
|
816
|
+
throw new Error(`Failed to create project: ${error.message}`);
|
|
817
|
+
}
|
|
818
|
+
return newProject.id;
|
|
819
|
+
}
|
|
820
|
+
// For anonymous usage, generate a local project ID
|
|
821
|
+
return `local-${Date.now()}`;
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Convert database row to LearningExperience
|
|
825
|
+
*/
|
|
826
|
+
rowToExperience(row) {
|
|
827
|
+
return {
|
|
828
|
+
id: row.id,
|
|
829
|
+
agentId: row.agent_id,
|
|
830
|
+
agentType: row.agent_type,
|
|
831
|
+
taskType: row.task_type,
|
|
832
|
+
context: row.context,
|
|
833
|
+
outcome: row.outcome,
|
|
834
|
+
embedding: row.embedding ?? undefined,
|
|
835
|
+
privacyLevel: row.privacy_level,
|
|
836
|
+
isAnonymized: row.is_anonymized,
|
|
837
|
+
shareCount: row.share_count,
|
|
838
|
+
createdAt: new Date(row.created_at),
|
|
839
|
+
createdBy: row.created_by ?? undefined,
|
|
840
|
+
};
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Convert database row to StoredPattern
|
|
844
|
+
*/
|
|
845
|
+
rowToPattern(row) {
|
|
846
|
+
return {
|
|
847
|
+
id: row.id,
|
|
848
|
+
projectId: row.project_id,
|
|
849
|
+
type: row.type,
|
|
850
|
+
domain: row.domain,
|
|
851
|
+
framework: row.framework ?? undefined,
|
|
852
|
+
content: row.content,
|
|
853
|
+
embedding: row.embedding ?? undefined,
|
|
854
|
+
confidence: row.confidence,
|
|
855
|
+
usageCount: row.usage_count,
|
|
856
|
+
lastUsed: row.last_used ? new Date(row.last_used) : undefined,
|
|
857
|
+
verdict: row.verdict ?? undefined,
|
|
858
|
+
privacyLevel: row.privacy_level,
|
|
859
|
+
isAnonymized: row.is_anonymized,
|
|
860
|
+
sourceHash: row.source_hash ?? undefined,
|
|
861
|
+
metadata: row.metadata,
|
|
862
|
+
createdAt: new Date(row.created_at),
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Convert database row to MemoryEntry
|
|
867
|
+
*/
|
|
868
|
+
rowToMemoryEntry(row) {
|
|
869
|
+
return {
|
|
870
|
+
key: row.key,
|
|
871
|
+
value: row.value,
|
|
872
|
+
partition: row.partition,
|
|
873
|
+
owner: row.owner,
|
|
874
|
+
accessLevel: row.access_level,
|
|
875
|
+
teamId: row.team_id ?? undefined,
|
|
876
|
+
swarmId: row.swarm_id ?? undefined,
|
|
877
|
+
metadata: row.metadata ?? undefined,
|
|
878
|
+
createdAt: new Date(row.created_at),
|
|
879
|
+
expiresAt: row.expires_at ? new Date(row.expires_at) : null,
|
|
880
|
+
};
|
|
881
|
+
}
|
|
882
|
+
/**
|
|
883
|
+
* Convert database row to EventRecord
|
|
884
|
+
*/
|
|
885
|
+
rowToEvent(row) {
|
|
886
|
+
return {
|
|
887
|
+
id: row.id,
|
|
888
|
+
type: row.type,
|
|
889
|
+
payload: row.payload,
|
|
890
|
+
source: row.source,
|
|
891
|
+
timestamp: new Date(row.timestamp),
|
|
892
|
+
ttl: row.ttl,
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
/**
|
|
896
|
+
* Convert database row to CodeChunk
|
|
897
|
+
*/
|
|
898
|
+
rowToCodeChunk(row) {
|
|
899
|
+
return {
|
|
900
|
+
id: row.id,
|
|
901
|
+
projectId: row.project_id,
|
|
902
|
+
filePath: row.file_path,
|
|
903
|
+
startLine: row.start_line,
|
|
904
|
+
endLine: row.end_line,
|
|
905
|
+
chunkType: row.chunk_type,
|
|
906
|
+
name: row.name ?? undefined,
|
|
907
|
+
language: row.language,
|
|
908
|
+
content: row.content,
|
|
909
|
+
embedding: row.embedding ?? undefined,
|
|
910
|
+
metadata: row.metadata ?? undefined,
|
|
911
|
+
commitSha: row.commit_sha ?? undefined,
|
|
912
|
+
indexedAt: new Date(row.indexed_at),
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Convert Uint8Array to base64 string for storage
|
|
917
|
+
*/
|
|
918
|
+
uint8ArrayToBase64(data) {
|
|
919
|
+
if (typeof Buffer !== 'undefined') {
|
|
920
|
+
return Buffer.from(data).toString('base64');
|
|
921
|
+
}
|
|
922
|
+
// Browser fallback
|
|
923
|
+
let binary = '';
|
|
924
|
+
for (let i = 0; i < data.length; i++) {
|
|
925
|
+
binary += String.fromCharCode(data[i]);
|
|
926
|
+
}
|
|
927
|
+
return btoa(binary);
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Convert base64 string back to Uint8Array
|
|
931
|
+
*/
|
|
932
|
+
base64ToUint8Array(base64) {
|
|
933
|
+
if (typeof Buffer !== 'undefined') {
|
|
934
|
+
return new Uint8Array(Buffer.from(base64, 'base64'));
|
|
935
|
+
}
|
|
936
|
+
// Browser fallback
|
|
937
|
+
const binary = atob(base64);
|
|
938
|
+
const bytes = new Uint8Array(binary.length);
|
|
939
|
+
for (let i = 0; i < binary.length; i++) {
|
|
940
|
+
bytes[i] = binary.charCodeAt(i);
|
|
941
|
+
}
|
|
942
|
+
return bytes;
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
exports.SupabasePersistenceProvider = SupabasePersistenceProvider;
|
|
946
|
+
/**
|
|
947
|
+
* Factory function to create a Supabase persistence provider
|
|
948
|
+
*
|
|
949
|
+
* @param config Configuration overrides
|
|
950
|
+
* @returns Configured provider instance
|
|
951
|
+
*/
|
|
952
|
+
function createSupabasePersistenceProvider(config = {}) {
|
|
953
|
+
return new SupabasePersistenceProvider(config);
|
|
954
|
+
}
|
|
955
|
+
//# sourceMappingURL=SupabasePersistenceProvider.js.map
|