@shadowforge0/aquifer-memory 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/core/aquifer.js +49 -1
  2. package/package.json +1 -1
package/core/aquifer.js CHANGED
@@ -259,6 +259,10 @@ function createAquifer(config) {
259
259
  const customSummaryFn = opts.summaryFn || null; // async (messages) => { summaryText, structuredSummary, entityRaw?, extra? }
260
260
  const customEntityParseFn = opts.entityParseFn || null; // (text) => [{ name, normalizedName, aliases, type }]
261
261
 
262
+ // Post-commit hook: runs after tx commit + client release. Best-effort, at-most-once.
263
+ const postProcess = opts.postProcess || null; // async (ctx) => void
264
+ const optModel = 'model' in opts ? opts.model : undefined; // undefined = no override
265
+
262
266
  // 1. Optimistic lock: claim session for processing
263
267
  const claimResult = await pool.query(
264
268
  `UPDATE ${qi(schema)}.sessions
@@ -361,7 +365,7 @@ function createAquifer(config) {
361
365
  schema, tenantId, agentId, sessionId,
362
366
  summaryText: summaryResult.summaryText,
363
367
  structuredSummary: summaryResult.structuredSummary,
364
- model: session.model || null, sourceHash: null,
368
+ model: (optModel !== undefined ? optModel : session.model) || null, sourceHash: null,
365
369
  msgCount: normalized.length,
366
370
  userCount: turns.length,
367
371
  assistantCount: normalized.filter(m => m.role === 'assistant').length,
@@ -453,6 +457,41 @@ function createAquifer(config) {
453
457
  client.release();
454
458
  }
455
459
 
460
+ // Post-commit hook: best-effort, at-most-once, no retry.
461
+ // Runs after tx commit + client release. Failure does not affect session status.
462
+ const effectiveModel = (optModel !== undefined ? optModel : session.model) || null;
463
+ let postProcessError = null;
464
+ if (postProcess) {
465
+ try {
466
+ await postProcess({
467
+ session: {
468
+ id: session.id,
469
+ sessionId,
470
+ agentId,
471
+ model: session.model || null,
472
+ source: session.source || null,
473
+ startedAt: session.started_at || null,
474
+ endedAt: session.ended_at || null,
475
+ },
476
+ effectiveModel,
477
+ summary: summaryResult
478
+ ? { summaryText: summaryResult.summaryText, structuredSummary: summaryResult.structuredSummary }
479
+ : null,
480
+ embedding: summaryEmbedding,
481
+ turnVectors,
482
+ extra,
483
+ normalized,
484
+ parsedEntities,
485
+ skipped: { summary: skipSummary, entities: skipEntities, turns: skipTurnEmbed },
486
+ turnsEmbedded,
487
+ entitiesFound,
488
+ warnings: [...warnings], // defensive copy — caller cannot mutate enrich warnings
489
+ });
490
+ } catch (e) {
491
+ postProcessError = e;
492
+ }
493
+ }
494
+
456
495
  return {
457
496
  summary: summaryResult ? summaryResult.summaryText : null,
458
497
  structuredSummary: summaryResult ? summaryResult.structuredSummary : null,
@@ -460,6 +499,15 @@ function createAquifer(config) {
460
499
  entitiesFound,
461
500
  warnings,
462
501
  extra,
502
+ session: {
503
+ id: session.id,
504
+ sessionId,
505
+ agentId,
506
+ model: session.model || null,
507
+ source: session.source || null,
508
+ },
509
+ effectiveModel,
510
+ postProcessError,
463
511
  };
464
512
  },
465
513
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shadowforge0/aquifer-memory",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "PG-native long-term memory for AI agents. Turn-level embedding, hybrid RRF ranking, optional knowledge graph. Includes CLI, MCP server, and OpenClaw plugin.",
5
5
  "main": "index.js",
6
6
  "files": [