@pga-ai/adapters-storage-postgres 0.8.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 ADDED
@@ -0,0 +1,150 @@
1
+ # @pga-ai/adapters-storage-postgres
2
+
3
+ > PostgreSQL storage adapter for GSEP (Genomic Self-Evolving Prompts)
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @pga-ai/core @pga-ai/adapters-storage-postgres
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { PGA } from '@pga-ai/core';
15
+ import { ClaudeAdapter } from '@pga-ai/adapters-llm-anthropic';
16
+ import { PostgresAdapter } from '@pga-ai/adapters-storage-postgres';
17
+
18
+ const pga = new PGA({
19
+ llm: new ClaudeAdapter({
20
+ apiKey: process.env.ANTHROPIC_API_KEY,
21
+ }),
22
+ storage: new PostgresAdapter({
23
+ connectionString: process.env.DATABASE_URL,
24
+ autoInitialize: true, // Creates tables automatically
25
+ }),
26
+ });
27
+
28
+ await pga.initialize();
29
+
30
+ const genome = await pga.createGenome({ name: 'my-assistant' });
31
+ const response = await genome.chat('Hello!', { userId: 'user123' });
32
+
33
+ console.log(response);
34
+ ```
35
+
36
+ ## Configuration
37
+
38
+ ### `PostgresAdapter(config)`
39
+
40
+ | Option | Type | Default | Description |
41
+ |--------|------|---------|-------------|
42
+ | `connectionString` | `string` | required | PostgreSQL connection string |
43
+ | `maxConnections` | `number` | `20` | Maximum pool size |
44
+ | `autoInitialize` | `boolean` | `true` | Auto-create database schema |
45
+
46
+ ### Connection String Format
47
+
48
+ ```
49
+ postgresql://user:password@host:port/database
50
+ ```
51
+
52
+ **Example:**
53
+ ```
54
+ postgresql://postgres:secret@localhost:5432/pga
55
+ ```
56
+
57
+ ## Database Schema
58
+
59
+ The adapter automatically creates the following tables:
60
+
61
+ - `pga_genomes` - Genome metadata
62
+ - `pga_alleles` - Gene alleles (Layer 0, 1, 2)
63
+ - `pga_user_dna` - User cognitive profiles
64
+ - `pga_interactions` - Interaction logs
65
+ - `pga_mutations` - Mutation history
66
+ - `pga_feedback` - User feedback signals
67
+ - `pga_analytics` - Pre-aggregated stats
68
+
69
+ See [`sql/schema.sql`](./sql/schema.sql) for full schema.
70
+
71
+ ## Manual Schema Setup
72
+
73
+ If you prefer to manage migrations yourself:
74
+
75
+ ```typescript
76
+ const adapter = new PostgresAdapter({
77
+ connectionString: process.env.DATABASE_URL,
78
+ autoInitialize: false, // Don't auto-create tables
79
+ });
80
+
81
+ // Run your own migrations
82
+ await runMigrations();
83
+
84
+ // Then initialize GSEP (will skip schema creation)
85
+ await pga.initialize();
86
+ ```
87
+
88
+ ## Performance
89
+
90
+ ### Connection Pooling
91
+
92
+ The adapter uses `pg` connection pooling by default:
93
+
94
+ ```typescript
95
+ const adapter = new PostgresAdapter({
96
+ connectionString: process.env.DATABASE_URL,
97
+ maxConnections: 50, // Increase for high load
98
+ });
99
+ ```
100
+
101
+ ### Indexes
102
+
103
+ All critical queries are indexed:
104
+ - Genome lookups: `pga_genomes(id)`
105
+ - Allele selection: `pga_alleles(genome_id, layer, gene, status)`
106
+ - User DNA: `pga_user_dna(user_id, genome_id)`
107
+ - Analytics queries: All have composite indexes
108
+
109
+ ## Production Checklist
110
+
111
+ ✅ Use connection pooling (`maxConnections: 20+`)
112
+ ✅ Enable SSL for remote databases
113
+ ✅ Set up database backups
114
+ ✅ Monitor connection pool usage
115
+ ✅ Use read replicas for analytics queries
116
+ ✅ Consider partitioning `pga_interactions` table for high volume
117
+
118
+ ## Troubleshooting
119
+
120
+ ### "relation does not exist" error
121
+
122
+ ```typescript
123
+ // Ensure autoInitialize is true
124
+ const adapter = new PostgresAdapter({
125
+ connectionString: process.env.DATABASE_URL,
126
+ autoInitialize: true, // ← This creates tables
127
+ });
128
+
129
+ await pga.initialize();
130
+ ```
131
+
132
+ ### Connection timeout
133
+
134
+ ```typescript
135
+ // Increase max connections
136
+ const adapter = new PostgresAdapter({
137
+ connectionString: process.env.DATABASE_URL,
138
+ maxConnections: 50, // Default is 20
139
+ });
140
+ ```
141
+
142
+ ### SSL connection required
143
+
144
+ ```
145
+ postgresql://user:pass@host:5432/db?sslmode=require
146
+ ```
147
+
148
+ ## License
149
+
150
+ MIT © Luis Alfredo Velasquez Duran
@@ -0,0 +1,65 @@
1
+ import type { StorageAdapter, Genome, UserDNA, Interaction, MutationLog, SemanticFact, GeneRegistryEntry } from '@pga-ai/core';
2
+ export interface PostgresAdapterConfig {
3
+ connectionString: string;
4
+ maxConnections?: number;
5
+ autoInitialize?: boolean;
6
+ }
7
+ export declare class PostgresAdapter implements StorageAdapter {
8
+ private pool;
9
+ private config;
10
+ constructor(config: PostgresAdapterConfig);
11
+ initialize(): Promise<void>;
12
+ saveGenome(genome: Genome): Promise<void>;
13
+ loadGenome(genomeId: string): Promise<Genome | null>;
14
+ listGenomes(): Promise<Genome[]>;
15
+ deleteGenome(genomeId: string): Promise<void>;
16
+ saveDNA(userId: string, genomeId: string, dna: UserDNA): Promise<void>;
17
+ loadDNA(userId: string, genomeId: string): Promise<UserDNA | null>;
18
+ recordInteraction(interaction: Interaction): Promise<void>;
19
+ logMutation(mutation: MutationLog): Promise<void>;
20
+ getMutationHistory(genomeId: string, limit?: number): Promise<MutationLog[]>;
21
+ getGeneMutationHistory(genomeId: string, gene: string, limit?: number): Promise<MutationLog[]>;
22
+ getRecentInteractions(genomeId: string, userId: string, limit?: number): Promise<unknown[]>;
23
+ recordFeedback(feedback: {
24
+ genomeId: string;
25
+ userId: string;
26
+ gene: string;
27
+ sentiment: 'positive' | 'negative' | 'neutral';
28
+ timestamp: Date;
29
+ }): Promise<void>;
30
+ getAnalytics(genomeId: string): Promise<{
31
+ totalMutations: number;
32
+ totalInteractions: number;
33
+ avgFitnessImprovement: number;
34
+ userSatisfaction: number;
35
+ topGenes: Array<{
36
+ gene: string;
37
+ fitness: number;
38
+ }>;
39
+ }>;
40
+ saveFact(fact: SemanticFact, userId: string, genomeId: string): Promise<void>;
41
+ getFacts(userId: string, genomeId: string, includeExpired?: boolean): Promise<SemanticFact[]>;
42
+ getFact(factId: string): Promise<SemanticFact | null>;
43
+ updateFact(factId: string, updates: Partial<SemanticFact>): Promise<void>;
44
+ deleteFact(factId: string): Promise<void>;
45
+ deleteUserFacts(userId: string, genomeId: string): Promise<void>;
46
+ cleanExpiredFacts(userId: string, genomeId: string): Promise<number>;
47
+ saveToGeneRegistry(entry: {
48
+ id: string;
49
+ familyId: string;
50
+ gene: string;
51
+ variant: string;
52
+ content: string;
53
+ layer: 0 | 1 | 2;
54
+ fitness: number;
55
+ sampleCount: number;
56
+ successRate: number;
57
+ metadata: Record<string, unknown>;
58
+ createdAt: Date;
59
+ }): Promise<void>;
60
+ queryGeneRegistry(familyId: string, gene?: string, minFitness?: number): Promise<GeneRegistryEntry[]>;
61
+ getBestRegistryGene(familyId: string, gene: string): Promise<GeneRegistryEntry | null>;
62
+ private mapRowToGeneRegistryEntry;
63
+ close(): Promise<void>;
64
+ }
65
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,501 @@
1
+ import { Pool } from 'pg';
2
+ import { readFileSync } from 'fs';
3
+ import { join, dirname } from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ export class PostgresAdapter {
8
+ pool;
9
+ config;
10
+ constructor(config) {
11
+ this.config = {
12
+ connectionString: config.connectionString,
13
+ maxConnections: config.maxConnections ?? 20,
14
+ autoInitialize: config.autoInitialize ?? true,
15
+ };
16
+ const poolConfig = {
17
+ connectionString: this.config.connectionString,
18
+ max: this.config.maxConnections,
19
+ };
20
+ this.pool = new Pool(poolConfig);
21
+ }
22
+ async initialize() {
23
+ if (!this.config.autoInitialize) {
24
+ return;
25
+ }
26
+ try {
27
+ const schemaPath = join(__dirname, '../sql/schema.sql');
28
+ const schema = readFileSync(schemaPath, 'utf-8');
29
+ await this.pool.query(schema);
30
+ console.log('[GSEP] PostgreSQL schema initialized');
31
+ }
32
+ catch (error) {
33
+ throw new Error(`Failed to initialize PostgreSQL schema: ${error instanceof Error ? error.message : 'Unknown error'}`);
34
+ }
35
+ }
36
+ async saveGenome(genome) {
37
+ const client = await this.pool.connect();
38
+ try {
39
+ await client.query('BEGIN');
40
+ await client.query(`INSERT INTO pga_genomes (id, name, config, created_at, updated_at)
41
+ VALUES ($1, $2, $3, $4, $5)
42
+ ON CONFLICT (id) DO UPDATE SET
43
+ name = $2,
44
+ config = $3,
45
+ updated_at = $5`, [
46
+ genome.id,
47
+ genome.name,
48
+ JSON.stringify(genome.config),
49
+ genome.createdAt,
50
+ genome.updatedAt,
51
+ ]);
52
+ await client.query('DELETE FROM pga_alleles WHERE genome_id = $1', [genome.id]);
53
+ for (const layer of [0, 1, 2]) {
54
+ const layerKey = `layer${layer}`;
55
+ const alleles = genome.layers[layerKey];
56
+ for (const allele of alleles) {
57
+ await client.query(`INSERT INTO pga_alleles (
58
+ genome_id, layer, gene, variant, content, fitness,
59
+ sample_count, parent_variant, generation, status,
60
+ sandbox_tested, sandbox_score, recent_scores,
61
+ created_at, updated_at
62
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15)`, [
63
+ genome.id,
64
+ layer,
65
+ allele.gene,
66
+ allele.variant,
67
+ allele.content,
68
+ allele.fitness,
69
+ allele.sampleCount || 0,
70
+ allele.parentVariant,
71
+ allele.generation || 0,
72
+ allele.status,
73
+ allele.sandboxTested || false,
74
+ allele.sandboxScore,
75
+ JSON.stringify(allele.recentScores || []),
76
+ allele.createdAt,
77
+ new Date(),
78
+ ]);
79
+ }
80
+ }
81
+ await client.query('COMMIT');
82
+ }
83
+ catch (error) {
84
+ await client.query('ROLLBACK');
85
+ throw error;
86
+ }
87
+ finally {
88
+ client.release();
89
+ }
90
+ }
91
+ async loadGenome(genomeId) {
92
+ const result = await this.pool.query('SELECT * FROM pga_genomes WHERE id = $1', [genomeId]);
93
+ if (result.rows.length === 0) {
94
+ return null;
95
+ }
96
+ const row = result.rows[0];
97
+ const allelesResult = await this.pool.query('SELECT * FROM pga_alleles WHERE genome_id = $1 ORDER BY layer, gene, fitness DESC', [genomeId]);
98
+ const layer0 = [];
99
+ const layer1 = [];
100
+ const layer2 = [];
101
+ for (const alleleRow of allelesResult.rows) {
102
+ const allele = {
103
+ gene: alleleRow.gene,
104
+ variant: alleleRow.variant,
105
+ content: alleleRow.content,
106
+ fitness: parseFloat(alleleRow.fitness),
107
+ sampleCount: alleleRow.sample_count,
108
+ parentVariant: alleleRow.parent_variant,
109
+ generation: alleleRow.generation,
110
+ status: alleleRow.status,
111
+ sandboxTested: alleleRow.sandbox_tested,
112
+ sandboxScore: alleleRow.sandbox_score ? parseFloat(alleleRow.sandbox_score) : undefined,
113
+ recentScores: alleleRow.recent_scores || [],
114
+ createdAt: alleleRow.created_at,
115
+ };
116
+ if (alleleRow.layer === 0)
117
+ layer0.push(allele);
118
+ else if (alleleRow.layer === 1)
119
+ layer1.push(allele);
120
+ else if (alleleRow.layer === 2)
121
+ layer2.push(allele);
122
+ }
123
+ return {
124
+ id: row.id,
125
+ name: row.name,
126
+ config: row.config,
127
+ layers: {
128
+ layer0,
129
+ layer1,
130
+ layer2,
131
+ },
132
+ createdAt: row.created_at,
133
+ updatedAt: row.updated_at,
134
+ };
135
+ }
136
+ async listGenomes() {
137
+ const result = await this.pool.query('SELECT id FROM pga_genomes ORDER BY created_at DESC');
138
+ const genomes = [];
139
+ for (const row of result.rows) {
140
+ const genome = await this.loadGenome(row.id);
141
+ if (genome) {
142
+ genomes.push(genome);
143
+ }
144
+ }
145
+ return genomes;
146
+ }
147
+ async deleteGenome(genomeId) {
148
+ await this.pool.query('DELETE FROM pga_genomes WHERE id = $1', [genomeId]);
149
+ }
150
+ async saveDNA(userId, genomeId, dna) {
151
+ await this.pool.query(`INSERT INTO pga_user_dna (
152
+ user_id, genome_id, traits, confidence, generation, last_evolved, updated_at
153
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7)
154
+ ON CONFLICT (user_id, genome_id) DO UPDATE SET
155
+ traits = $3,
156
+ confidence = $4,
157
+ generation = $5,
158
+ last_evolved = $6,
159
+ updated_at = $7`, [
160
+ userId,
161
+ genomeId,
162
+ JSON.stringify(dna.traits),
163
+ JSON.stringify(dna.confidence),
164
+ dna.generation,
165
+ dna.lastEvolved,
166
+ new Date(),
167
+ ]);
168
+ }
169
+ async loadDNA(userId, genomeId) {
170
+ const result = await this.pool.query('SELECT * FROM pga_user_dna WHERE user_id = $1 AND genome_id = $2', [userId, genomeId]);
171
+ if (result.rows.length === 0) {
172
+ return null;
173
+ }
174
+ const row = result.rows[0];
175
+ return {
176
+ userId: row.user_id,
177
+ genomeId: row.genome_id,
178
+ traits: row.traits,
179
+ confidence: row.confidence,
180
+ generation: row.generation,
181
+ lastEvolved: row.last_evolved,
182
+ };
183
+ }
184
+ async recordInteraction(interaction) {
185
+ await this.pool.query(`INSERT INTO pga_interactions (
186
+ genome_id, user_id, user_message, assistant_response,
187
+ tool_calls, score, task_type, timestamp
188
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, [
189
+ interaction.genomeId,
190
+ interaction.userId,
191
+ interaction.userMessage,
192
+ interaction.assistantResponse,
193
+ JSON.stringify(interaction.toolCalls),
194
+ interaction.score,
195
+ interaction.taskType,
196
+ interaction.timestamp,
197
+ ]);
198
+ }
199
+ async logMutation(mutation) {
200
+ await this.pool.query(`INSERT INTO pga_mutations (
201
+ genome_id, layer, gene, variant, mutation_type,
202
+ parent_variant, trigger_reason, fitness_delta,
203
+ deployed, details, timestamp
204
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`, [
205
+ mutation.genomeId,
206
+ mutation.layer,
207
+ mutation.gene,
208
+ mutation.variant,
209
+ mutation.mutationType,
210
+ mutation.parentVariant,
211
+ mutation.triggerReason,
212
+ mutation.fitnessDelta,
213
+ mutation.deployed,
214
+ JSON.stringify(mutation.details || {}),
215
+ mutation.timestamp,
216
+ ]);
217
+ }
218
+ async getMutationHistory(genomeId, limit = 100) {
219
+ const result = await this.pool.query(`SELECT * FROM pga_mutations
220
+ WHERE genome_id = $1
221
+ ORDER BY timestamp DESC
222
+ LIMIT $2`, [genomeId, limit]);
223
+ return result.rows.map((row) => ({
224
+ genomeId: row.genome_id,
225
+ layer: row.layer,
226
+ gene: row.gene,
227
+ variant: row.variant,
228
+ mutationType: row.mutation_type,
229
+ parentVariant: row.parent_variant,
230
+ triggerReason: row.trigger_reason,
231
+ fitnessDelta: parseFloat(row.fitness_delta),
232
+ deployed: row.deployed,
233
+ details: row.details,
234
+ createdAt: row.timestamp,
235
+ timestamp: row.timestamp,
236
+ }));
237
+ }
238
+ async getGeneMutationHistory(genomeId, gene, limit = 50) {
239
+ const result = await this.pool.query(`SELECT * FROM pga_mutations
240
+ WHERE genome_id = $1 AND gene = $2
241
+ ORDER BY timestamp DESC
242
+ LIMIT $3`, [genomeId, gene, limit]);
243
+ return result.rows.map((row) => ({
244
+ genomeId: row.genome_id,
245
+ layer: row.layer,
246
+ gene: row.gene,
247
+ variant: row.variant,
248
+ mutationType: row.mutation_type,
249
+ parentVariant: row.parent_variant,
250
+ triggerReason: row.trigger_reason,
251
+ fitnessDelta: parseFloat(row.fitness_delta),
252
+ deployed: row.deployed,
253
+ details: row.details,
254
+ createdAt: row.timestamp,
255
+ timestamp: row.timestamp,
256
+ }));
257
+ }
258
+ async getRecentInteractions(genomeId, userId, limit = 20) {
259
+ const result = await this.pool.query(`SELECT * FROM pga_interactions
260
+ WHERE genome_id = $1 AND user_id = $2
261
+ ORDER BY timestamp DESC
262
+ LIMIT $3`, [genomeId, userId, limit]);
263
+ return result.rows.map((row) => ({
264
+ genomeId: row.genome_id,
265
+ userId: row.user_id,
266
+ userMessage: row.user_message,
267
+ assistantResponse: row.assistant_response,
268
+ toolCalls: row.tool_calls,
269
+ score: row.score ? parseFloat(row.score) : undefined,
270
+ timestamp: row.timestamp,
271
+ }));
272
+ }
273
+ async recordFeedback(feedback) {
274
+ await this.pool.query(`INSERT INTO pga_feedback (
275
+ genome_id, user_id, gene, sentiment, timestamp
276
+ ) VALUES ($1, $2, $3, $4, $5)`, [
277
+ feedback.genomeId,
278
+ feedback.userId,
279
+ feedback.gene,
280
+ feedback.sentiment,
281
+ feedback.timestamp,
282
+ ]);
283
+ }
284
+ async getAnalytics(genomeId) {
285
+ const [interactionsResult, mutationsResult, feedbackResult, topGenesResult,] = await Promise.all([
286
+ this.pool.query('SELECT COUNT(*) as count FROM pga_interactions WHERE genome_id = $1', [genomeId]),
287
+ this.pool.query('SELECT COUNT(*) as count, AVG(fitness_improvement) as avg_improvement FROM pga_mutations WHERE genome_id = $1 AND deployed = true', [genomeId]),
288
+ this.pool.query(`SELECT
289
+ COUNT(*) FILTER (WHERE sentiment = 'positive') as positive,
290
+ COUNT(*) as total
291
+ FROM pga_feedback WHERE genome_id = $1`, [genomeId]),
292
+ this.pool.query(`SELECT gene, AVG(sandbox_score) as fitness
293
+ FROM pga_mutations
294
+ WHERE genome_id = $1 AND deployed = true
295
+ GROUP BY gene
296
+ ORDER BY fitness DESC
297
+ LIMIT 5`, [genomeId]),
298
+ ]);
299
+ const totalFeedback = parseInt(feedbackResult.rows[0]?.total || '0');
300
+ const positiveFeedback = parseInt(feedbackResult.rows[0]?.positive || '0');
301
+ return {
302
+ totalMutations: parseInt(mutationsResult.rows[0]?.count || '0'),
303
+ totalInteractions: parseInt(interactionsResult.rows[0]?.count || '0'),
304
+ avgFitnessImprovement: parseFloat(mutationsResult.rows[0]?.avg_improvement || '0'),
305
+ userSatisfaction: totalFeedback > 0 ? positiveFeedback / totalFeedback : 0,
306
+ topGenes: topGenesResult.rows.map((row) => ({
307
+ gene: row.gene,
308
+ fitness: parseFloat(row.fitness || '0'),
309
+ })),
310
+ };
311
+ }
312
+ async saveFact(fact, userId, genomeId) {
313
+ await this.pool.query(`INSERT INTO semantic_facts (
314
+ id, user_id, genome_id, fact, category, confidence,
315
+ source_turn, source_interaction_id, extracted_at,
316
+ expiry, verified
317
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
318
+ ON CONFLICT (id) DO UPDATE SET
319
+ fact = $4,
320
+ category = $5,
321
+ confidence = $6,
322
+ verified = $11,
323
+ expiry = $10,
324
+ updated_at = NOW()`, [
325
+ fact.id,
326
+ userId,
327
+ genomeId,
328
+ fact.fact,
329
+ fact.category,
330
+ fact.confidence,
331
+ fact.sourceTurn,
332
+ fact.sourceInteractionId,
333
+ fact.extractedAt,
334
+ fact.expiry,
335
+ fact.verified,
336
+ ]);
337
+ }
338
+ async getFacts(userId, genomeId, includeExpired = false) {
339
+ const query = includeExpired
340
+ ? `SELECT * FROM semantic_facts
341
+ WHERE user_id = $1 AND genome_id = $2
342
+ ORDER BY verified DESC, confidence DESC, extracted_at DESC`
343
+ : `SELECT * FROM semantic_facts
344
+ WHERE user_id = $1 AND genome_id = $2
345
+ AND (expiry IS NULL OR expiry > NOW())
346
+ ORDER BY verified DESC, confidence DESC, extracted_at DESC`;
347
+ const result = await this.pool.query(query, [userId, genomeId]);
348
+ return result.rows.map((row) => ({
349
+ id: row.id,
350
+ fact: row.fact,
351
+ category: row.category,
352
+ confidence: parseFloat(row.confidence),
353
+ sourceTurn: row.source_turn,
354
+ sourceInteractionId: row.source_interaction_id,
355
+ extractedAt: row.extracted_at,
356
+ expiry: row.expiry,
357
+ verified: row.verified,
358
+ createdAt: row.created_at,
359
+ updatedAt: row.updated_at,
360
+ }));
361
+ }
362
+ async getFact(factId) {
363
+ const result = await this.pool.query('SELECT * FROM semantic_facts WHERE id = $1', [factId]);
364
+ if (result.rows.length === 0) {
365
+ return null;
366
+ }
367
+ const row = result.rows[0];
368
+ return {
369
+ id: row.id,
370
+ fact: row.fact,
371
+ category: row.category,
372
+ confidence: parseFloat(row.confidence),
373
+ sourceTurn: row.source_turn,
374
+ sourceInteractionId: row.source_interaction_id,
375
+ extractedAt: row.extracted_at,
376
+ expiry: row.expiry,
377
+ verified: row.verified,
378
+ createdAt: row.created_at,
379
+ updatedAt: row.updated_at,
380
+ };
381
+ }
382
+ async updateFact(factId, updates) {
383
+ const setClauses = [];
384
+ const values = [];
385
+ let paramIndex = 1;
386
+ if (updates.fact !== undefined) {
387
+ setClauses.push(`fact = $${paramIndex++}`);
388
+ values.push(updates.fact);
389
+ }
390
+ if (updates.category !== undefined) {
391
+ setClauses.push(`category = $${paramIndex++}`);
392
+ values.push(updates.category);
393
+ }
394
+ if (updates.confidence !== undefined) {
395
+ setClauses.push(`confidence = $${paramIndex++}`);
396
+ values.push(updates.confidence);
397
+ }
398
+ if (updates.verified !== undefined) {
399
+ setClauses.push(`verified = $${paramIndex++}`);
400
+ values.push(updates.verified);
401
+ }
402
+ if (updates.expiry !== undefined) {
403
+ setClauses.push(`expiry = $${paramIndex++}`);
404
+ values.push(updates.expiry);
405
+ }
406
+ if (setClauses.length === 0) {
407
+ return;
408
+ }
409
+ setClauses.push(`updated_at = NOW()`);
410
+ values.push(factId);
411
+ const query = `UPDATE semantic_facts SET ${setClauses.join(', ')} WHERE id = $${paramIndex}`;
412
+ await this.pool.query(query, values);
413
+ }
414
+ async deleteFact(factId) {
415
+ await this.pool.query('DELETE FROM semantic_facts WHERE id = $1', [factId]);
416
+ }
417
+ async deleteUserFacts(userId, genomeId) {
418
+ await this.pool.query('DELETE FROM semantic_facts WHERE user_id = $1 AND genome_id = $2', [userId, genomeId]);
419
+ }
420
+ async cleanExpiredFacts(userId, genomeId) {
421
+ const result = await this.pool.query(`DELETE FROM semantic_facts
422
+ WHERE user_id = $1 AND genome_id = $2
423
+ AND expiry IS NOT NULL AND expiry <= NOW()
424
+ RETURNING id`, [userId, genomeId]);
425
+ return result.rowCount || 0;
426
+ }
427
+ async saveToGeneRegistry(entry) {
428
+ await this.pool.query(`INSERT INTO pga_gene_registry (id, family_id, gene, variant, content, layer, fitness, sample_count, success_rate, metadata, created_at)
429
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
430
+ ON CONFLICT (id) DO UPDATE SET
431
+ fitness = EXCLUDED.fitness,
432
+ sample_count = EXCLUDED.sample_count,
433
+ success_rate = EXCLUDED.success_rate,
434
+ metadata = EXCLUDED.metadata`, [
435
+ entry.id,
436
+ entry.familyId,
437
+ entry.gene,
438
+ entry.variant,
439
+ entry.content,
440
+ entry.layer,
441
+ entry.fitness,
442
+ entry.sampleCount,
443
+ entry.successRate,
444
+ JSON.stringify(entry.metadata),
445
+ entry.createdAt,
446
+ ]);
447
+ }
448
+ async queryGeneRegistry(familyId, gene, minFitness) {
449
+ let query = 'SELECT * FROM pga_gene_registry WHERE family_id = $1';
450
+ const params = [familyId];
451
+ let paramIndex = 2;
452
+ if (gene) {
453
+ query += ` AND gene = $${paramIndex++}`;
454
+ params.push(gene);
455
+ }
456
+ if (minFitness !== undefined) {
457
+ query += ` AND fitness >= $${paramIndex++}`;
458
+ params.push(minFitness);
459
+ }
460
+ query += ' ORDER BY fitness DESC';
461
+ const result = await this.pool.query(query, params);
462
+ return result.rows.map((row) => this.mapRowToGeneRegistryEntry(row));
463
+ }
464
+ async getBestRegistryGene(familyId, gene) {
465
+ const result = await this.pool.query(`SELECT * FROM pga_gene_registry
466
+ WHERE family_id = $1 AND gene = $2
467
+ ORDER BY fitness DESC
468
+ LIMIT 1`, [familyId, gene]);
469
+ if (result.rows.length === 0)
470
+ return null;
471
+ return this.mapRowToGeneRegistryEntry(result.rows[0]);
472
+ }
473
+ mapRowToGeneRegistryEntry(row) {
474
+ const rawMetadata = typeof row.metadata === 'string'
475
+ ? JSON.parse(row.metadata)
476
+ : row.metadata || {};
477
+ return {
478
+ id: row.id,
479
+ familyId: row.family_id,
480
+ gene: row.gene,
481
+ variant: row.variant,
482
+ content: row.content,
483
+ layer: row.layer,
484
+ fitness: parseFloat(row.fitness),
485
+ sampleCount: row.sample_count,
486
+ successRate: parseFloat(row.success_rate),
487
+ metadata: {
488
+ sourceGenomeId: rawMetadata.sourceGenomeId || '',
489
+ sourceVersion: rawMetadata.sourceVersion || 0,
490
+ publishedBy: rawMetadata.publishedBy || '',
491
+ description: rawMetadata.description,
492
+ tags: rawMetadata.tags,
493
+ },
494
+ createdAt: new Date(row.created_at),
495
+ };
496
+ }
497
+ async close() {
498
+ await this.pool.end();
499
+ }
500
+ }
501
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@pga-ai/adapters-storage-postgres",
3
+ "version": "0.8.0",
4
+ "description": "PostgreSQL storage adapter for GSEP",
5
+ "author": "Luis Alfredo Velasquez Duran <contact@gsepcore.com>",
6
+ "license": "MIT",
7
+ "homepage": "https://gsepcore.com",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/LuisvelMarketer/pga-platform",
11
+ "directory": "packages/adapters-storage/postgres"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/LuisvelMarketer/pga-platform/issues"
15
+ },
16
+ "type": "module",
17
+ "main": "./dist/index.js",
18
+ "types": "./dist/index.d.ts",
19
+ "exports": {
20
+ ".": {
21
+ "import": "./dist/index.js",
22
+ "types": "./dist/index.d.ts"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "sql"
28
+ ],
29
+ "scripts": {
30
+ "build": "tsc --build",
31
+ "clean": "rm -rf dist",
32
+ "dev": "tsc --watch"
33
+ },
34
+ "dependencies": {
35
+ "pg": "^8.13.1",
36
+ "@pga-ai/core": "*"
37
+ },
38
+ "devDependencies": {
39
+ "@types/pg": "^8.11.10",
40
+ "typescript": "^5.6.0"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public"
44
+ }
45
+ }
package/sql/schema.sql ADDED
@@ -0,0 +1,251 @@
1
+ -- PGA PostgreSQL Schema
2
+ -- Created by Luis Alfredo Velasquez Duran (Germany, 2025)
3
+
4
+ -- ═══════════════════════════════════════════════════════════
5
+ -- GENOMES
6
+ -- ═══════════════════════════════════════════════════════════
7
+
8
+ CREATE TABLE IF NOT EXISTS pga_genomes (
9
+ id TEXT PRIMARY KEY,
10
+ name TEXT NOT NULL,
11
+ config JSONB NOT NULL DEFAULT '{}',
12
+ -- Living OS v1.0: Lineage tracking
13
+ family_id TEXT,
14
+ version INTEGER DEFAULT 1,
15
+ lineage JSONB DEFAULT '{}',
16
+ c0_hash TEXT,
17
+ created_at TIMESTAMPTZ DEFAULT NOW(),
18
+ updated_at TIMESTAMPTZ DEFAULT NOW()
19
+ );
20
+
21
+ CREATE INDEX IF NOT EXISTS idx_genomes_name ON pga_genomes(name);
22
+ CREATE INDEX IF NOT EXISTS idx_genomes_family ON pga_genomes(family_id, version DESC);
23
+
24
+ -- ═══════════════════════════════════════════════════════════
25
+ -- LAYERS (Three-Layer Architecture)
26
+ -- ═══════════════════════════════════════════════════════════
27
+
28
+ CREATE TABLE IF NOT EXISTS pga_alleles (
29
+ id BIGSERIAL PRIMARY KEY,
30
+ genome_id TEXT NOT NULL REFERENCES pga_genomes(id) ON DELETE CASCADE,
31
+ layer INTEGER NOT NULL CHECK (layer IN (0, 1, 2)),
32
+ gene TEXT NOT NULL,
33
+ variant TEXT NOT NULL,
34
+ content TEXT NOT NULL,
35
+ fitness NUMERIC(5,4) DEFAULT 0.5000,
36
+ sample_count INTEGER DEFAULT 0,
37
+ parent_variant TEXT,
38
+ generation INTEGER DEFAULT 0,
39
+ status TEXT DEFAULT 'active' CHECK (status IN ('active', 'retired')),
40
+ sandbox_tested BOOLEAN DEFAULT FALSE,
41
+ sandbox_score NUMERIC(5,4),
42
+ recent_scores JSONB DEFAULT '[]',
43
+ created_at TIMESTAMPTZ DEFAULT NOW(),
44
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
45
+ UNIQUE(genome_id, layer, gene, variant)
46
+ );
47
+
48
+ CREATE INDEX IF NOT EXISTS idx_alleles_genome ON pga_alleles(genome_id);
49
+ CREATE INDEX IF NOT EXISTS idx_alleles_active ON pga_alleles(genome_id, layer, gene, status) WHERE status = 'active';
50
+ CREATE INDEX IF NOT EXISTS idx_alleles_fitness ON pga_alleles(genome_id, layer, gene, fitness DESC);
51
+
52
+ -- ═══════════════════════════════════════════════════════════
53
+ -- USER DNA (Cognitive Profiles)
54
+ -- ═══════════════════════════════════════════════════════════
55
+
56
+ CREATE TABLE IF NOT EXISTS pga_user_dna (
57
+ user_id TEXT NOT NULL,
58
+ genome_id TEXT NOT NULL REFERENCES pga_genomes(id) ON DELETE CASCADE,
59
+ traits JSONB NOT NULL DEFAULT '{}',
60
+ confidence JSONB NOT NULL DEFAULT '{}',
61
+ generation INTEGER DEFAULT 0,
62
+ last_evolved TIMESTAMPTZ DEFAULT NOW(),
63
+ created_at TIMESTAMPTZ DEFAULT NOW(),
64
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
65
+ PRIMARY KEY (user_id, genome_id)
66
+ );
67
+
68
+ CREATE INDEX IF NOT EXISTS idx_user_dna_genome ON pga_user_dna(genome_id);
69
+ CREATE INDEX IF NOT EXISTS idx_user_dna_evolved ON pga_user_dna(genome_id, last_evolved DESC);
70
+
71
+ -- ═══════════════════════════════════════════════════════════
72
+ -- INTERACTIONS (Learning Data)
73
+ -- ═══════════════════════════════════════════════════════════
74
+
75
+ CREATE TABLE IF NOT EXISTS pga_interactions (
76
+ id BIGSERIAL PRIMARY KEY,
77
+ genome_id TEXT NOT NULL REFERENCES pga_genomes(id) ON DELETE CASCADE,
78
+ user_id TEXT NOT NULL,
79
+ user_message TEXT NOT NULL,
80
+ assistant_response TEXT NOT NULL,
81
+ tool_calls JSONB DEFAULT '[]',
82
+ score NUMERIC(5,4),
83
+ user_satisfied BOOLEAN,
84
+ task_type TEXT,
85
+ timestamp TIMESTAMPTZ DEFAULT NOW()
86
+ );
87
+
88
+ CREATE INDEX IF NOT EXISTS idx_interactions_genome ON pga_interactions(genome_id, timestamp DESC);
89
+ CREATE INDEX IF NOT EXISTS idx_interactions_user ON pga_interactions(genome_id, user_id, timestamp DESC);
90
+
91
+ -- ═══════════════════════════════════════════════════════════
92
+ -- MUTATIONS (Evolution Log)
93
+ -- ═══════════════════════════════════════════════════════════
94
+
95
+ CREATE TABLE IF NOT EXISTS pga_mutations (
96
+ id BIGSERIAL PRIMARY KEY,
97
+ genome_id TEXT NOT NULL REFERENCES pga_genomes(id) ON DELETE CASCADE,
98
+ layer INTEGER NOT NULL,
99
+ gene TEXT NOT NULL,
100
+ variant TEXT NOT NULL,
101
+ mutation_type TEXT NOT NULL,
102
+ parent_variant TEXT,
103
+ trigger_reason TEXT,
104
+ fitness_delta NUMERIC(5,4),
105
+ deployed BOOLEAN DEFAULT FALSE,
106
+ details JSONB DEFAULT '{}',
107
+ timestamp TIMESTAMPTZ DEFAULT NOW()
108
+ );
109
+
110
+ CREATE INDEX IF NOT EXISTS idx_mutations_genome ON pga_mutations(genome_id, timestamp DESC);
111
+ CREATE INDEX IF NOT EXISTS idx_mutations_gene ON pga_mutations(genome_id, gene, timestamp DESC);
112
+ CREATE INDEX IF NOT EXISTS idx_mutations_deployed ON pga_mutations(genome_id, deployed, timestamp DESC);
113
+
114
+ -- ═══════════════════════════════════════════════════════════
115
+ -- FEEDBACK (User Feedback Signals)
116
+ -- ═══════════════════════════════════════════════════════════
117
+
118
+ CREATE TABLE IF NOT EXISTS pga_feedback (
119
+ id BIGSERIAL PRIMARY KEY,
120
+ genome_id TEXT NOT NULL REFERENCES pga_genomes(id) ON DELETE CASCADE,
121
+ user_id TEXT NOT NULL,
122
+ gene TEXT,
123
+ sentiment TEXT NOT NULL CHECK (sentiment IN ('positive', 'negative', 'neutral')),
124
+ timestamp TIMESTAMPTZ DEFAULT NOW()
125
+ );
126
+
127
+ CREATE INDEX IF NOT EXISTS idx_feedback_genome ON pga_feedback(genome_id, timestamp DESC);
128
+ CREATE INDEX IF NOT EXISTS idx_feedback_user ON pga_feedback(genome_id, user_id, timestamp DESC);
129
+
130
+ -- ═══════════════════════════════════════════════════════════
131
+ -- ANALYTICS (Pre-aggregated Stats)
132
+ -- ═══════════════════════════════════════════════════════════
133
+
134
+ CREATE TABLE IF NOT EXISTS pga_analytics (
135
+ genome_id TEXT NOT NULL REFERENCES pga_genomes(id) ON DELETE CASCADE,
136
+ metric TEXT NOT NULL,
137
+ value JSONB NOT NULL,
138
+ snapshot_at TIMESTAMPTZ DEFAULT NOW(),
139
+ PRIMARY KEY (genome_id, metric, snapshot_at)
140
+ );
141
+
142
+ CREATE INDEX IF NOT EXISTS idx_analytics_genome ON pga_analytics(genome_id, snapshot_at DESC);
143
+
144
+ -- ═══════════════════════════════════════════════════════════
145
+ -- GENE REGISTRY (Cross-Genome Knowledge Inheritance)
146
+ -- ═══════════════════════════════════════════════════════════
147
+
148
+ CREATE TABLE IF NOT EXISTS pga_gene_registry (
149
+ id TEXT PRIMARY KEY,
150
+ family_id TEXT NOT NULL,
151
+ gene TEXT NOT NULL,
152
+ variant TEXT NOT NULL,
153
+ content TEXT NOT NULL,
154
+ layer INTEGER NOT NULL CHECK (layer IN (0, 1, 2)),
155
+ fitness NUMERIC(5,4) NOT NULL,
156
+ sample_count INTEGER NOT NULL,
157
+ success_rate NUMERIC(5,4) NOT NULL,
158
+ metadata JSONB NOT NULL DEFAULT '{}',
159
+ created_at TIMESTAMPTZ DEFAULT NOW(),
160
+ UNIQUE(family_id, gene, variant)
161
+ );
162
+
163
+ CREATE INDEX IF NOT EXISTS idx_gene_registry_family ON pga_gene_registry(family_id, fitness DESC);
164
+ CREATE INDEX IF NOT EXISTS idx_gene_registry_gene ON pga_gene_registry(family_id, gene, fitness DESC);
165
+
166
+ -- ═══════════════════════════════════════════════════════════
167
+ -- CALIBRATION HISTORY (Dynamic Threshold Tuning)
168
+ -- Living OS v1.0 Final 10/10
169
+ -- ═══════════════════════════════════════════════════════════
170
+
171
+ CREATE TABLE IF NOT EXISTS pga_calibration_history (
172
+ id BIGSERIAL PRIMARY KEY,
173
+ context_key TEXT NOT NULL,
174
+ layer INTEGER CHECK (layer IN (0, 1, 2)),
175
+ operator TEXT,
176
+ task_type TEXT,
177
+ threshold NUMERIC(5,4) NOT NULL,
178
+ total_candidates INTEGER NOT NULL,
179
+ passed_sandbox INTEGER NOT NULL,
180
+ deployed_successfully INTEGER NOT NULL,
181
+ rolled_back INTEGER NOT NULL,
182
+ false_positive_rate NUMERIC(5,4) NOT NULL,
183
+ false_negative_rate NUMERIC(5,4) NOT NULL,
184
+ optimal_threshold NUMERIC(5,4) NOT NULL,
185
+ timestamp TIMESTAMPTZ DEFAULT NOW()
186
+ );
187
+
188
+ CREATE INDEX IF NOT EXISTS idx_calibration_context ON pga_calibration_history(context_key, timestamp DESC);
189
+ CREATE INDEX IF NOT EXISTS idx_calibration_layer ON pga_calibration_history(layer, timestamp DESC);
190
+
191
+ -- ═══════════════════════════════════════════════════════════
192
+ -- SEMANTIC FACTS (Layered Memory - Long Term Storage)
193
+ -- v0.3.0 - Production-Ready Persistence
194
+ -- ═══════════════════════════════════════════════════════════
195
+
196
+ CREATE TABLE IF NOT EXISTS semantic_facts (
197
+ id TEXT PRIMARY KEY,
198
+ user_id TEXT NOT NULL,
199
+ genome_id TEXT NOT NULL REFERENCES pga_genomes(id) ON DELETE CASCADE,
200
+
201
+ -- Fact content
202
+ fact TEXT NOT NULL,
203
+ category TEXT NOT NULL CHECK (category IN ('profile', 'preference', 'constraint', 'knowledge')),
204
+
205
+ -- Metadata
206
+ confidence NUMERIC(5,4) NOT NULL CHECK (confidence >= 0.0 AND confidence <= 1.0),
207
+ source_turn INTEGER NOT NULL,
208
+ source_interaction_id TEXT,
209
+
210
+ -- Lifecycle
211
+ extracted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
212
+ expiry TIMESTAMPTZ, -- NULL = never expires
213
+ verified BOOLEAN NOT NULL DEFAULT FALSE,
214
+
215
+ -- Timestamps
216
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
217
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
218
+ );
219
+
220
+ -- Indexes for performance
221
+ CREATE INDEX IF NOT EXISTS idx_semantic_facts_user_genome
222
+ ON semantic_facts(user_id, genome_id);
223
+
224
+ CREATE INDEX IF NOT EXISTS idx_semantic_facts_expiry
225
+ ON semantic_facts(expiry)
226
+ WHERE expiry IS NOT NULL;
227
+
228
+ CREATE INDEX IF NOT EXISTS idx_semantic_facts_category
229
+ ON semantic_facts(genome_id, category);
230
+
231
+ CREATE INDEX IF NOT EXISTS idx_semantic_facts_verified
232
+ ON semantic_facts(genome_id, verified)
233
+ WHERE verified = TRUE;
234
+
235
+ CREATE INDEX IF NOT EXISTS idx_semantic_facts_active
236
+ ON semantic_facts(user_id, genome_id, expiry)
237
+ WHERE expiry IS NULL OR expiry > NOW();
238
+
239
+ -- Auto-update updated_at trigger
240
+ CREATE OR REPLACE FUNCTION update_semantic_facts_updated_at()
241
+ RETURNS TRIGGER AS $$
242
+ BEGIN
243
+ NEW.updated_at = NOW();
244
+ RETURN NEW;
245
+ END;
246
+ $$ LANGUAGE plpgsql;
247
+
248
+ CREATE TRIGGER trigger_semantic_facts_updated_at
249
+ BEFORE UPDATE ON semantic_facts
250
+ FOR EACH ROW
251
+ EXECUTE FUNCTION update_semantic_facts_updated_at();