agent-working-memory 0.9.0 → 0.9.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.
@@ -184,7 +184,7 @@ export class PGliteEngramStore {
184
184
  params.push(e.id, e.agentId, e.timestamp.toISOString(), e.context, e.resultsReturned, e.topScore, e.latencyMs, JSON.stringify(e.engramIds));
185
185
  }
186
186
  try {
187
- await this.db.query(`INSERT INTO activation_events (id, agent_id, timestamp, context, results_returned, top_score, latency_ms, engram_ids)
187
+ await this.db.query(`INSERT INTO activation_events (id, agent_id, timestamp, context, results_returned, top_score, latency_ms, engram_ids)
188
188
  VALUES ${values.join(',')}`, params);
189
189
  }
190
190
  catch {
@@ -222,18 +222,18 @@ export class PGliteEngramStore {
222
222
  await this.readyPromise;
223
223
  const id = input.id ?? randomUUID();
224
224
  const now = new Date().toISOString();
225
- await this.db.query(`INSERT INTO engrams (
226
- id, agent_id, concept, content, embedding, embedding_model,
227
- confidence, salience, access_count, last_accessed, created_at,
228
- salience_features, reason_codes, stage, ttl, retracted,
229
- tags, memory_type, memory_class, supersedes, episode_id,
230
- task_status, task_priority, blocked_by, sequence, references_json
231
- ) VALUES (
232
- $1, $2, $3, $4, $5::vector, $6,
233
- $7, $8, 0, $9, $10,
234
- $11, $12, 'active', $13, FALSE,
235
- $14, $15, $16, $17, $18,
236
- $19, $20, $21, $22, $23
225
+ await this.db.query(`INSERT INTO engrams (
226
+ id, agent_id, concept, content, embedding, embedding_model,
227
+ confidence, salience, access_count, last_accessed, created_at,
228
+ salience_features, reason_codes, stage, ttl, retracted,
229
+ tags, memory_type, memory_class, supersedes, episode_id,
230
+ task_status, task_priority, blocked_by, sequence, references_json
231
+ ) VALUES (
232
+ $1, $2, $3, $4, $5::vector, $6,
233
+ $7, $8, 0, $9, $10,
234
+ $11, $12, 'active', $13, FALSE,
235
+ $14, $15, $16, $17, $18,
236
+ $19, $20, $21, $22, $23
237
237
  )`, [
238
238
  id,
239
239
  input.agentId,
@@ -362,10 +362,10 @@ export class PGliteEngramStore {
362
362
  }
363
363
  async touchEngram(id) {
364
364
  await this.readyPromise;
365
- await this.db.query(`UPDATE engrams
366
- SET access_count = access_count + 1,
367
- last_accessed = $1,
368
- confidence = LEAST(0.85, confidence + 0.02 / (1.0 + sqrt(access_count::float)))
365
+ await this.db.query(`UPDATE engrams
366
+ SET access_count = access_count + 1,
367
+ last_accessed = $1,
368
+ confidence = LEAST(0.85, confidence + 0.02 / (1.0 + sqrt(access_count::float)))
369
369
  WHERE id = $2`, [new Date().toISOString(), id]);
370
370
  }
371
371
  async updateStage(id, stage) {
@@ -411,9 +411,9 @@ export class PGliteEngramStore {
411
411
  async timeWarp(agentId, ms) {
412
412
  await this.readyPromise;
413
413
  const seconds = Math.round(ms / 1000);
414
- const r1 = await this.db.query(`UPDATE engrams SET
415
- created_at = to_char(($1::timestamptz - interval '1 second' * $2), 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
416
- last_accessed = to_char(($3::timestamptz - interval '1 second' * $2), 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
414
+ const r1 = await this.db.query(`UPDATE engrams SET
415
+ created_at = to_char(($1::timestamptz - interval '1 second' * $2), 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"'),
416
+ last_accessed = to_char(($3::timestamptz - interval '1 second' * $2), 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')
417
417
  WHERE agent_id = $4`, ['now', seconds, 'now', agentId]);
418
418
  // Simpler: just update with relative arithmetic on stored ISO strings.
419
419
  // PGlite doesn't support all date ops cleanly; fall through to JS-side calculation.
@@ -439,13 +439,13 @@ export class PGliteEngramStore {
439
439
  // Restrict to active + fading. Faded engrams (Paper 1: storage degradation)
440
440
  // retain their embedding so they still participate in semantic recall, even
441
441
  // though their content has been trimmed. Excludes staging/consolidated/archived.
442
- const result = await this.db.query(`SELECT *, (embedding <=> $2::vector) AS distance
443
- FROM engrams
444
- WHERE agent_id = $1
445
- AND embedding IS NOT NULL
446
- AND retracted = FALSE
447
- AND stage IN ('active', 'fading')
448
- ORDER BY distance ASC
442
+ const result = await this.db.query(`SELECT *, (embedding <=> $2::vector) AS distance
443
+ FROM engrams
444
+ WHERE agent_id = $1
445
+ AND embedding IS NOT NULL
446
+ AND retracted = FALSE
447
+ AND stage IN ('active', 'fading')
448
+ ORDER BY distance ASC
449
449
  LIMIT $3`, [agentId, vectorToLiteral(vec), limit]);
450
450
  return result.rows.map((r) => ({ engram: rowToEngram(r), distance: r.distance }));
451
451
  }
@@ -464,11 +464,11 @@ export class PGliteEngramStore {
464
464
  if (tokens.length === 0)
465
465
  return [];
466
466
  const websearchQuery = tokens.join(' OR ');
467
- const result = await this.db.query(`SELECT *, ts_rank_cd(fts, websearch_to_tsquery('english', $2)) AS rank
468
- FROM engrams
469
- WHERE agent_id = $1 AND retracted = FALSE
470
- AND fts @@ websearch_to_tsquery('english', $2)
471
- ORDER BY rank DESC
467
+ const result = await this.db.query(`SELECT *, ts_rank_cd(fts, websearch_to_tsquery('english', $2)) AS rank
468
+ FROM engrams
469
+ WHERE agent_id = $1 AND retracted = FALSE
470
+ AND fts @@ websearch_to_tsquery('english', $2)
471
+ ORDER BY rank DESC
472
472
  LIMIT $3`, [agentId, websearchQuery, limit]);
473
473
  return result.rows.map((r) => ({ engram: rowToEngram(r), bm25Score: calibrateBm25(Number(r.rank)) }));
474
474
  }
@@ -482,11 +482,11 @@ export class PGliteEngramStore {
482
482
  if (tokens.length === 0)
483
483
  return [];
484
484
  const websearchQuery = tokens.join(' OR ');
485
- const result = await this.db.query(`SELECT *, ts_rank_cd(fts, websearch_to_tsquery('english', $2)) AS rank
486
- FROM engrams
487
- WHERE agent_id = ANY($1::text[]) AND retracted = FALSE
488
- AND fts @@ websearch_to_tsquery('english', $2)
489
- ORDER BY rank DESC
485
+ const result = await this.db.query(`SELECT *, ts_rank_cd(fts, websearch_to_tsquery('english', $2)) AS rank
486
+ FROM engrams
487
+ WHERE agent_id = ANY($1::text[]) AND retracted = FALSE
488
+ AND fts @@ websearch_to_tsquery('english', $2)
489
+ ORDER BY rank DESC
490
490
  LIMIT $3`, [agentIds, websearchQuery, limit]);
491
491
  return result.rows.map((r) => ({ engram: rowToEngram(r), bm25Score: calibrateBm25(Number(r.rank)) }));
492
492
  }
@@ -567,32 +567,32 @@ export class PGliteEngramStore {
567
567
  sql += ` AND task_status = $${params.length + 1}`;
568
568
  params.push(status);
569
569
  }
570
- sql += ` ORDER BY
571
- CASE task_priority
572
- WHEN 'urgent' THEN 0
573
- WHEN 'high' THEN 1
574
- WHEN 'medium' THEN 2
575
- WHEN 'low' THEN 3
576
- ELSE 4
577
- END,
570
+ sql += ` ORDER BY
571
+ CASE task_priority
572
+ WHEN 'urgent' THEN 0
573
+ WHEN 'high' THEN 1
574
+ WHEN 'medium' THEN 2
575
+ WHEN 'low' THEN 3
576
+ ELSE 4
577
+ END,
578
578
  created_at DESC`;
579
579
  const result = await this.db.query(sql, params);
580
580
  return result.rows.map(rowToEngram);
581
581
  }
582
582
  async getNextTask(agentId) {
583
583
  await this.readyPromise;
584
- const result = await this.db.query(`SELECT * FROM engrams
585
- WHERE agent_id = $1 AND task_status IN ('open', 'in_progress') AND retracted = FALSE
586
- ORDER BY
587
- CASE task_status WHEN 'in_progress' THEN 0 ELSE 1 END,
588
- CASE task_priority
589
- WHEN 'urgent' THEN 0
590
- WHEN 'high' THEN 1
591
- WHEN 'medium' THEN 2
592
- WHEN 'low' THEN 3
593
- ELSE 4
594
- END,
595
- created_at ASC
584
+ const result = await this.db.query(`SELECT * FROM engrams
585
+ WHERE agent_id = $1 AND task_status IN ('open', 'in_progress') AND retracted = FALSE
586
+ ORDER BY
587
+ CASE task_status WHEN 'in_progress' THEN 0 ELSE 1 END,
588
+ CASE task_priority
589
+ WHEN 'urgent' THEN 0
590
+ WHEN 'high' THEN 1
591
+ WHEN 'medium' THEN 2
592
+ WHEN 'low' THEN 3
593
+ ELSE 4
594
+ END,
595
+ created_at ASC
596
596
  LIMIT 1`, [agentId]);
597
597
  return result.rows.length > 0 ? rowToEngram(result.rows[0]) : null;
598
598
  }
@@ -606,11 +606,11 @@ export class PGliteEngramStore {
606
606
  }
607
607
  async findActiveMatchByConcept(agentId, concept, requiredTags) {
608
608
  await this.readyPromise;
609
- let sql = `SELECT * FROM engrams
610
- WHERE agent_id = $1
611
- AND LOWER(TRIM(concept)) = LOWER(TRIM($2))
612
- AND stage = 'active'
613
- AND retracted = FALSE
609
+ let sql = `SELECT * FROM engrams
610
+ WHERE agent_id = $1
611
+ AND LOWER(TRIM(concept)) = LOWER(TRIM($2))
612
+ AND stage = 'active'
613
+ AND retracted = FALSE
614
614
  AND superseded_by IS NULL`;
615
615
  const params = [agentId, concept];
616
616
  if (requiredTags && requiredTags.length > 0) {
@@ -643,12 +643,12 @@ export class PGliteEngramStore {
643
643
  await this.readyPromise;
644
644
  const id = randomUUID();
645
645
  const now = new Date().toISOString();
646
- await this.db.query(`INSERT INTO associations (id, from_engram_id, to_engram_id, weight, confidence, type, activation_count, created_at, last_activated)
647
- VALUES ($1, $2, $3, $4, $5, $6, 0, $7, $7)
648
- ON CONFLICT (from_engram_id, to_engram_id) DO UPDATE SET
649
- weight = EXCLUDED.weight,
650
- confidence = EXCLUDED.confidence,
651
- last_activated = EXCLUDED.last_activated,
646
+ await this.db.query(`INSERT INTO associations (id, from_engram_id, to_engram_id, weight, confidence, type, activation_count, created_at, last_activated)
647
+ VALUES ($1, $2, $3, $4, $5, $6, 0, $7, $7)
648
+ ON CONFLICT (from_engram_id, to_engram_id) DO UPDATE SET
649
+ weight = EXCLUDED.weight,
650
+ confidence = EXCLUDED.confidence,
651
+ last_activated = EXCLUDED.last_activated,
652
652
  activation_count = associations.activation_count + 1`, [id, fromId, toId, weight, confidence, type, now]);
653
653
  const assoc = await this.getAssociation(fromId, toId);
654
654
  if (!assoc)
@@ -670,12 +670,12 @@ export class PGliteEngramStore {
670
670
  if (engramIds.length === 0)
671
671
  return result;
672
672
  await this.readyPromise;
673
- const r = await this.db.query(`SELECT id, SUM(cnt) AS count, SUM(sw) AS sum_weight FROM (
674
- SELECT from_engram_id AS id, 1 AS cnt, weight AS sw FROM associations WHERE from_engram_id = ANY($1::text[])
675
- UNION ALL
676
- SELECT to_engram_id AS id, 1 AS cnt, weight AS sw FROM associations WHERE to_engram_id = ANY($1::text[])
677
- ) t
678
- WHERE id = ANY($1::text[])
673
+ const r = await this.db.query(`SELECT id, SUM(cnt) AS count, SUM(sw) AS sum_weight FROM (
674
+ SELECT from_engram_id AS id, 1 AS cnt, weight AS sw FROM associations WHERE from_engram_id = ANY($1::text[])
675
+ UNION ALL
676
+ SELECT to_engram_id AS id, 1 AS cnt, weight AS sw FROM associations WHERE to_engram_id = ANY($1::text[])
677
+ ) t
678
+ WHERE id = ANY($1::text[])
679
679
  GROUP BY id`, [engramIds]);
680
680
  for (const row of r.rows) {
681
681
  result.set(row.id, { count: Number(row.count), sumWeight: Number(row.sum_weight) });
@@ -691,7 +691,7 @@ export class PGliteEngramStore {
691
691
  if (engramIds.length === 0)
692
692
  return result;
693
693
  await this.readyPromise;
694
- const r = await this.db.query(`SELECT * FROM associations
694
+ const r = await this.db.query(`SELECT * FROM associations
695
695
  WHERE from_engram_id = ANY($1::text[]) OR to_engram_id = ANY($1::text[])`, [engramIds]);
696
696
  for (const row of r.rows) {
697
697
  const a = rowToAssociation(row);
@@ -731,8 +731,8 @@ export class PGliteEngramStore {
731
731
  }
732
732
  async getAllAssociations(agentId) {
733
733
  await this.readyPromise;
734
- const result = await this.db.query(`SELECT a.* FROM associations a
735
- JOIN engrams e ON a.from_engram_id = e.id
734
+ const result = await this.db.query(`SELECT a.* FROM associations a
735
+ JOIN engrams e ON a.from_engram_id = e.id
736
736
  WHERE e.agent_id = $1`, [agentId]);
737
737
  return result.rows.map(rowToAssociation);
738
738
  }
@@ -741,11 +741,11 @@ export class PGliteEngramStore {
741
741
  // ============================================================
742
742
  async getEvictionCandidates(agentId, limit) {
743
743
  await this.readyPromise;
744
- const result = await this.db.query(`SELECT * FROM engrams
745
- WHERE agent_id = $1 AND stage = 'active' AND retracted = FALSE
746
- ORDER BY (salience * 0.3 + confidence * 0.3
747
- + (access_count::float / (access_count + 5)) * 0.2
748
- + (1.0 / (1.0 + EXTRACT(EPOCH FROM (now() - last_accessed::timestamptz)) / 86400.0)) * 0.2) ASC
744
+ const result = await this.db.query(`SELECT * FROM engrams
745
+ WHERE agent_id = $1 AND stage = 'active' AND retracted = FALSE
746
+ ORDER BY (salience * 0.3 + confidence * 0.3
747
+ + (access_count::float / (access_count + 5)) * 0.2
748
+ + (1.0 / (1.0 + EXTRACT(EPOCH FROM (now() - last_accessed::timestamptz)) / 86400.0)) * 0.2) ASC
749
749
  LIMIT $2`, [agentId, limit]);
750
750
  return result.rows.map(rowToEngram);
751
751
  }
@@ -780,7 +780,7 @@ export class PGliteEngramStore {
780
780
  }
781
781
  async logStagingEvent(event) {
782
782
  await this.readyPromise;
783
- await this.db.query(`INSERT INTO staging_events (engram_id, agent_id, action, resonance_score, timestamp, age_ms)
783
+ await this.db.query(`INSERT INTO staging_events (engram_id, agent_id, action, resonance_score, timestamp, age_ms)
784
784
  VALUES ($1, $2, $3, $4, $5, $6)`, [
785
785
  event.engramId, event.agentId, event.action,
786
786
  event.resonanceScore, event.timestamp.toISOString(), event.ageMs,
@@ -788,18 +788,18 @@ export class PGliteEngramStore {
788
788
  }
789
789
  async logRetrievalFeedback(activationEventId, engramId, useful, context) {
790
790
  await this.readyPromise;
791
- await this.db.query(`INSERT INTO retrieval_feedback (id, activation_event_id, engram_id, useful, context, timestamp)
791
+ await this.db.query(`INSERT INTO retrieval_feedback (id, activation_event_id, engram_id, useful, context, timestamp)
792
792
  VALUES ($1, $2, $3, $4, $5, $6)`, [randomUUID(), activationEventId, engramId, useful, context, new Date().toISOString()]);
793
793
  }
794
794
  async getRetrievalPrecision(agentId, windowHours = 24) {
795
795
  await this.readyPromise;
796
796
  const since = new Date(Date.now() - windowHours * 3600_000).toISOString();
797
- const result = await this.db.query(`SELECT
798
- COUNT(CASE WHEN useful = TRUE THEN 1 END) AS useful_count,
799
- COUNT(*) AS total_count
800
- FROM retrieval_feedback rf
801
- LEFT JOIN activation_events ae ON rf.activation_event_id = ae.id
802
- JOIN engrams e ON rf.engram_id = e.id
797
+ const result = await this.db.query(`SELECT
798
+ COUNT(CASE WHEN useful = TRUE THEN 1 END) AS useful_count,
799
+ COUNT(*) AS total_count
800
+ FROM retrieval_feedback rf
801
+ LEFT JOIN activation_events ae ON rf.activation_event_id = ae.id
802
+ JOIN engrams e ON rf.engram_id = e.id
803
803
  WHERE e.agent_id = $1 AND rf.timestamp > $2`, [agentId, since]);
804
804
  const row = result.rows[0];
805
805
  const total = Number(row?.total_count ?? 0);
@@ -808,10 +808,10 @@ export class PGliteEngramStore {
808
808
  }
809
809
  async getStagingMetrics(agentId) {
810
810
  await this.readyPromise;
811
- const result = await this.db.query(`SELECT
812
- COUNT(CASE WHEN action = 'promoted' THEN 1 END) AS promoted,
813
- COUNT(CASE WHEN action = 'discarded' THEN 1 END) AS discarded,
814
- COUNT(CASE WHEN action = 'expired' THEN 1 END) AS expired
811
+ const result = await this.db.query(`SELECT
812
+ COUNT(CASE WHEN action = 'promoted' THEN 1 END) AS promoted,
813
+ COUNT(CASE WHEN action = 'discarded' THEN 1 END) AS discarded,
814
+ COUNT(CASE WHEN action = 'expired' THEN 1 END) AS expired
815
815
  FROM staging_events WHERE agent_id = $1`, [agentId]);
816
816
  const row = result.rows[0] ?? { promoted: 0, discarded: 0, expired: 0 };
817
817
  return {
@@ -825,8 +825,8 @@ export class PGliteEngramStore {
825
825
  // Flush any buffered activation events so stats reflect the latest writes.
826
826
  await this.flushActivationEvents();
827
827
  const since = new Date(Date.now() - windowHours * 3600_000).toISOString();
828
- const result = await this.db.query(`SELECT latency_ms FROM activation_events
829
- WHERE agent_id = $1 AND timestamp > $2
828
+ const result = await this.db.query(`SELECT latency_ms FROM activation_events
829
+ WHERE agent_id = $1 AND timestamp > $2
830
830
  ORDER BY latency_ms ASC`, [agentId, since]);
831
831
  if (result.rows.length === 0)
832
832
  return { count: 0, avgLatencyMs: 0, p95LatencyMs: 0 };
@@ -851,7 +851,7 @@ export class PGliteEngramStore {
851
851
  await this.readyPromise;
852
852
  const id = randomUUID();
853
853
  const now = new Date().toISOString();
854
- await this.db.query(`INSERT INTO episodes (id, agent_id, label, embedding, engram_count, start_time, end_time, created_at)
854
+ await this.db.query(`INSERT INTO episodes (id, agent_id, label, embedding, engram_count, start_time, end_time, created_at)
855
855
  VALUES ($1, $2, $3, $4::vector, 0, $5, $5, $5)`, [id, input.agentId, input.label, vectorToLiteral(input.embedding ?? null), now]);
856
856
  const ep = await this.getEpisode(id);
857
857
  if (!ep)
@@ -877,9 +877,9 @@ export class PGliteEngramStore {
877
877
  async addEngramToEpisode(engramId, episodeId) {
878
878
  await this.readyPromise;
879
879
  await this.db.query(`UPDATE engrams SET episode_id = $1 WHERE id = $2`, [episodeId, engramId]);
880
- await this.db.query(`UPDATE episodes SET
881
- engram_count = engram_count + 1,
882
- end_time = GREATEST(end_time, $1)
880
+ await this.db.query(`UPDATE episodes SET
881
+ engram_count = engram_count + 1,
882
+ end_time = GREATEST(end_time, $1)
883
883
  WHERE id = $2`, [new Date().toISOString(), episodeId]);
884
884
  }
885
885
  async getEngramsByEpisode(episodeId) {
@@ -918,44 +918,44 @@ export class PGliteEngramStore {
918
918
  async updateAutoCheckpointWrite(agentId, engramId) {
919
919
  await this.readyPromise;
920
920
  const now = new Date().toISOString();
921
- await this.db.query(`INSERT INTO conscious_state (agent_id, last_write_id, last_activity_at, write_count_since_consolidation, updated_at)
922
- VALUES ($1, $2, $3, 1, $3)
923
- ON CONFLICT(agent_id) DO UPDATE SET
924
- last_write_id = EXCLUDED.last_write_id,
925
- last_activity_at = EXCLUDED.last_activity_at,
926
- write_count_since_consolidation = conscious_state.write_count_since_consolidation + 1,
921
+ await this.db.query(`INSERT INTO conscious_state (agent_id, last_write_id, last_activity_at, write_count_since_consolidation, updated_at)
922
+ VALUES ($1, $2, $3, 1, $3)
923
+ ON CONFLICT(agent_id) DO UPDATE SET
924
+ last_write_id = EXCLUDED.last_write_id,
925
+ last_activity_at = EXCLUDED.last_activity_at,
926
+ write_count_since_consolidation = conscious_state.write_count_since_consolidation + 1,
927
927
  updated_at = EXCLUDED.updated_at`, [agentId, engramId, now]);
928
928
  }
929
929
  async updateAutoCheckpointRecall(agentId, context, engramIds) {
930
930
  await this.readyPromise;
931
931
  const now = new Date().toISOString();
932
- await this.db.query(`INSERT INTO conscious_state (agent_id, last_recall_context, last_recall_ids, last_activity_at, recall_count_since_consolidation, updated_at)
933
- VALUES ($1, $2, $3, $4, 1, $4)
934
- ON CONFLICT(agent_id) DO UPDATE SET
935
- last_recall_context = EXCLUDED.last_recall_context,
936
- last_recall_ids = EXCLUDED.last_recall_ids,
937
- last_activity_at = EXCLUDED.last_activity_at,
938
- recall_count_since_consolidation = conscious_state.recall_count_since_consolidation + 1,
932
+ await this.db.query(`INSERT INTO conscious_state (agent_id, last_recall_context, last_recall_ids, last_activity_at, recall_count_since_consolidation, updated_at)
933
+ VALUES ($1, $2, $3, $4, 1, $4)
934
+ ON CONFLICT(agent_id) DO UPDATE SET
935
+ last_recall_context = EXCLUDED.last_recall_context,
936
+ last_recall_ids = EXCLUDED.last_recall_ids,
937
+ last_activity_at = EXCLUDED.last_activity_at,
938
+ recall_count_since_consolidation = conscious_state.recall_count_since_consolidation + 1,
939
939
  updated_at = EXCLUDED.updated_at`, [agentId, context, JSON.stringify(engramIds), now]);
940
940
  }
941
941
  async touchActivity(agentId) {
942
942
  await this.readyPromise;
943
943
  const now = new Date().toISOString();
944
- await this.db.query(`INSERT INTO conscious_state (agent_id, last_activity_at, updated_at)
945
- VALUES ($1, $2, $2)
946
- ON CONFLICT(agent_id) DO UPDATE SET
947
- last_activity_at = EXCLUDED.last_activity_at,
944
+ await this.db.query(`INSERT INTO conscious_state (agent_id, last_activity_at, updated_at)
945
+ VALUES ($1, $2, $2)
946
+ ON CONFLICT(agent_id) DO UPDATE SET
947
+ last_activity_at = EXCLUDED.last_activity_at,
948
948
  updated_at = EXCLUDED.updated_at`, [agentId, now]);
949
949
  }
950
950
  async saveCheckpoint(agentId, state) {
951
951
  await this.readyPromise;
952
952
  const now = new Date().toISOString();
953
- await this.db.query(`INSERT INTO conscious_state (agent_id, execution_state, checkpoint_at, last_activity_at, updated_at)
954
- VALUES ($1, $2, $3, $3, $3)
955
- ON CONFLICT(agent_id) DO UPDATE SET
956
- execution_state = EXCLUDED.execution_state,
957
- checkpoint_at = EXCLUDED.checkpoint_at,
958
- last_activity_at = EXCLUDED.last_activity_at,
953
+ await this.db.query(`INSERT INTO conscious_state (agent_id, execution_state, checkpoint_at, last_activity_at, updated_at)
954
+ VALUES ($1, $2, $3, $3, $3)
955
+ ON CONFLICT(agent_id) DO UPDATE SET
956
+ execution_state = EXCLUDED.execution_state,
957
+ checkpoint_at = EXCLUDED.checkpoint_at,
958
+ last_activity_at = EXCLUDED.last_activity_at,
959
959
  updated_at = EXCLUDED.updated_at`, [agentId, JSON.stringify(state), now]);
960
960
  }
961
961
  async getCheckpoint(agentId) {
@@ -988,13 +988,13 @@ export class PGliteEngramStore {
988
988
  await this.db.query(`UPDATE conscious_state SET last_mini_consolidation_at = $1, updated_at = $1 WHERE agent_id = $2`, [now, agentId]);
989
989
  }
990
990
  else {
991
- await this.db.query(`UPDATE conscious_state SET
992
- last_consolidation_at = $1,
993
- last_mini_consolidation_at = $1,
994
- write_count_since_consolidation = 0,
995
- recall_count_since_consolidation = 0,
996
- consolidation_cycle_count = consolidation_cycle_count + 1,
997
- updated_at = $1
991
+ await this.db.query(`UPDATE conscious_state SET
992
+ last_consolidation_at = $1,
993
+ last_mini_consolidation_at = $1,
994
+ write_count_since_consolidation = 0,
995
+ recall_count_since_consolidation = 0,
996
+ consolidation_cycle_count = consolidation_cycle_count + 1,
997
+ updated_at = $1
998
998
  WHERE agent_id = $2`, [now, agentId]);
999
999
  }
1000
1000
  }
@@ -1019,10 +1019,10 @@ export class PGliteEngramStore {
1019
1019
  // ============================================================
1020
1020
  async getLatestByTag(opts) {
1021
1021
  await this.readyPromise;
1022
- let sql = `SELECT * FROM engrams
1023
- WHERE agent_id = $1
1024
- AND retracted = $2
1025
- AND stage = 'active'
1022
+ let sql = `SELECT * FROM engrams
1023
+ WHERE agent_id = $1
1024
+ AND retracted = $2
1025
+ AND stage = 'active'
1026
1026
  AND tags LIKE $3`;
1027
1027
  const params = [opts.agentId, opts.retracted ?? false, `%"${opts.tagKeyPrefix}%`];
1028
1028
  if (opts.scopeTagsAll && opts.scopeTagsAll.length > 0) {
@@ -1049,10 +1049,10 @@ export class PGliteEngramStore {
1049
1049
  }
1050
1050
  async getTopBy(opts) {
1051
1051
  await this.readyPromise;
1052
- let sql = `SELECT * FROM engrams
1053
- WHERE agent_id = $1
1054
- AND retracted = $2
1055
- AND stage = 'active'
1052
+ let sql = `SELECT * FROM engrams
1053
+ WHERE agent_id = $1
1054
+ AND retracted = $2
1055
+ AND stage = 'active'
1056
1056
  AND tags LIKE $3`;
1057
1057
  const params = [opts.agentId, opts.retracted ?? false, `%"${opts.sortField}%`];
1058
1058
  if (opts.filterTagsAll && opts.filterTagsAll.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-working-memory",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Cognitive memory layer for AI agents — activation-based retrieval, salience filtering, associative connections",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/api/index.ts CHANGED
@@ -1,3 +1,3 @@
1
- // Copyright 2026 Robert Winter / Complete Ideas
2
- // SPDX-License-Identifier: Apache-2.0
3
- export * from './routes.js';
1
+ // Copyright 2026 Robert Winter / Complete Ideas
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ export * from './routes.js';