agent-working-memory 0.14.1 → 0.14.6

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 (76) hide show
  1. package/README.md +240 -653
  2. package/dist/adapters/claude-code.d.ts.map +1 -1
  3. package/dist/adapters/claude-code.js +234 -131
  4. package/dist/adapters/claude-code.js.map +1 -1
  5. package/dist/adapters/common.d.ts +44 -5
  6. package/dist/adapters/common.d.ts.map +1 -1
  7. package/dist/adapters/common.js +111 -41
  8. package/dist/adapters/common.js.map +1 -1
  9. package/dist/adapters/hook-scripts.d.ts +54 -0
  10. package/dist/adapters/hook-scripts.d.ts.map +1 -0
  11. package/dist/adapters/hook-scripts.js +340 -0
  12. package/dist/adapters/hook-scripts.js.map +1 -0
  13. package/dist/adapters/types.d.ts +13 -3
  14. package/dist/adapters/types.d.ts.map +1 -1
  15. package/dist/cli.js +21 -5
  16. package/dist/cli.js.map +1 -1
  17. package/dist/core/agent-id.d.ts +19 -0
  18. package/dist/core/agent-id.d.ts.map +1 -0
  19. package/dist/core/agent-id.js +28 -0
  20. package/dist/core/agent-id.js.map +1 -0
  21. package/dist/core/whoami.d.ts +9 -1
  22. package/dist/core/whoami.d.ts.map +1 -1
  23. package/dist/core/whoami.js +12 -2
  24. package/dist/core/whoami.js.map +1 -1
  25. package/dist/engine/activation.d.ts +2 -0
  26. package/dist/engine/activation.d.ts.map +1 -1
  27. package/dist/engine/activation.js +18 -3
  28. package/dist/engine/activation.js.map +1 -1
  29. package/dist/engine/eval.d.ts +15 -0
  30. package/dist/engine/eval.d.ts.map +1 -1
  31. package/dist/engine/eval.js +23 -0
  32. package/dist/engine/eval.js.map +1 -1
  33. package/dist/hooks/prime.d.ts +10 -4
  34. package/dist/hooks/prime.d.ts.map +1 -1
  35. package/dist/hooks/prime.js +16 -6
  36. package/dist/hooks/prime.js.map +1 -1
  37. package/dist/hooks/sidecar.d.ts +18 -2
  38. package/dist/hooks/sidecar.d.ts.map +1 -1
  39. package/dist/hooks/sidecar.js +30 -4
  40. package/dist/hooks/sidecar.js.map +1 -1
  41. package/dist/mcp.js +48 -19
  42. package/dist/mcp.js.map +1 -1
  43. package/dist/storage/pglite.d.ts +7 -0
  44. package/dist/storage/pglite.d.ts.map +1 -1
  45. package/dist/storage/pglite.js +17 -3
  46. package/dist/storage/pglite.js.map +1 -1
  47. package/dist/storage/postgres.d.ts +7 -0
  48. package/dist/storage/postgres.d.ts.map +1 -1
  49. package/dist/storage/postgres.js +17 -3
  50. package/dist/storage/postgres.js.map +1 -1
  51. package/dist/storage/sqlite.d.ts +12 -0
  52. package/dist/storage/sqlite.d.ts.map +1 -1
  53. package/dist/storage/sqlite.js +24 -3
  54. package/dist/storage/sqlite.js.map +1 -1
  55. package/dist/types/engram.d.ts +16 -0
  56. package/dist/types/engram.d.ts.map +1 -1
  57. package/dist/types/eval.d.ts +2 -0
  58. package/dist/types/eval.d.ts.map +1 -1
  59. package/package.json +94 -72
  60. package/src/adapters/claude-code.ts +223 -125
  61. package/src/adapters/common.ts +117 -42
  62. package/src/adapters/hook-scripts.ts +370 -0
  63. package/src/adapters/types.ts +14 -3
  64. package/src/cli.ts +19 -5
  65. package/src/core/agent-id.ts +28 -0
  66. package/src/core/whoami.ts +11 -1
  67. package/src/engine/activation.ts +18 -3
  68. package/src/engine/eval.ts +34 -0
  69. package/src/hooks/prime.ts +22 -7
  70. package/src/hooks/sidecar.ts +50 -6
  71. package/src/mcp.ts +50 -18
  72. package/src/storage/pglite.ts +22 -4
  73. package/src/storage/postgres.ts +22 -4
  74. package/src/storage/sqlite.ts +26 -4
  75. package/src/types/engram.ts +16 -0
  76. package/src/types/eval.ts +3 -1
@@ -1348,7 +1348,7 @@ export class EngramStore {
1348
1348
  }
1349
1349
 
1350
1350
  getActivationStats(agentId: string, windowHours: number = 24): {
1351
- count: number; avgLatencyMs: number; p95LatencyMs: number;
1351
+ count: number; avgLatencyMs: number; p50LatencyMs: number; p90LatencyMs: number; p95LatencyMs: number;
1352
1352
  } {
1353
1353
  const since = new Date(Date.now() - windowHours * 3600_000).toISOString();
1354
1354
  const rows = this.db.prepare(`
@@ -1357,17 +1357,39 @@ export class EngramStore {
1357
1357
  ORDER BY latency_ms ASC
1358
1358
  `).all(agentId, since) as { latency_ms: number }[];
1359
1359
 
1360
- if (rows.length === 0) return { count: 0, avgLatencyMs: 0, p95LatencyMs: 0 };
1360
+ if (rows.length === 0) return { count: 0, avgLatencyMs: 0, p50LatencyMs: 0, p90LatencyMs: 0, p95LatencyMs: 0 };
1361
1361
 
1362
+ // 0.14.3: p50/p90 added. The column mixes warm recalls with cold model loads
1363
+ // and stalls (live store: mean 20 s, median 1.6 s, max 38 min), so the mean
1364
+ // is not a usable number; percentiles are. Rows are already sorted ASC.
1365
+ const pct = (q: number) => rows[Math.min(Math.floor(rows.length * q), rows.length - 1)].latency_ms;
1362
1366
  const total = rows.reduce((s, r) => s + r.latency_ms, 0);
1363
- const p95Index = Math.min(Math.floor(rows.length * 0.95), rows.length - 1);
1364
1367
  return {
1365
1368
  count: rows.length,
1366
1369
  avgLatencyMs: total / rows.length,
1367
- p95LatencyMs: rows[p95Index].latency_ms,
1370
+ p50LatencyMs: pct(0.5),
1371
+ p90LatencyMs: pct(0.9),
1372
+ p95LatencyMs: pct(0.95),
1368
1373
  };
1369
1374
  }
1370
1375
 
1376
+ /**
1377
+ * 0.14.3: feedback rows in the window that are JOINED to an activation event.
1378
+ * Unlinked rows (activation_event_id IS NULL — all 872 rows written before
1379
+ * 0.14.3) are excluded on purpose: this is the recall→use signal, and a row
1380
+ * that cannot be traced to a recall does not measure it.
1381
+ */
1382
+ getLinkedFeedbackStats(agentId: string, windowHours: number = 24 * 7): { total: number; useful: number } {
1383
+ const since = new Date(Date.now() - windowHours * 3600_000).toISOString();
1384
+ const row = this.db.prepare(`
1385
+ SELECT COUNT(*) AS total, COUNT(CASE WHEN rf.useful = 1 THEN 1 END) AS useful
1386
+ FROM retrieval_feedback rf
1387
+ JOIN activation_events ae ON ae.id = rf.activation_event_id
1388
+ WHERE ae.agent_id = ? AND rf.timestamp > ?
1389
+ `).get(agentId, since) as { total: number; useful: number };
1390
+ return { total: row.total, useful: row.useful };
1391
+ }
1392
+
1371
1393
  getConsolidatedCount(agentId: string): number {
1372
1394
  const row = this.db.prepare(
1373
1395
  `SELECT COUNT(*) as cnt FROM engrams WHERE agent_id = ? AND stage = 'consolidated'`
@@ -219,6 +219,13 @@ export interface ActivationResult {
219
219
  * See `src/engine/confidence.ts` for the formula.
220
220
  */
221
221
  confidence?: number;
222
+ /**
223
+ * Id of the activation_events row this recall logged (0.14.3). Same value on
224
+ * every result in the same recall. Hand it back on memory_feedback so the
225
+ * feedback joins to the recall that produced it — before this, the id was
226
+ * generated and dropped, and every retrieval_feedback row was orphaned.
227
+ */
228
+ activationEventId?: string;
222
229
  /**
223
230
  * Confidence-adaptive content preview (Paper 3: cognitive teaming).
224
231
  * Set when the query opts in via `granularity: 'compact' | 'auto'`.
@@ -310,6 +317,15 @@ export interface ActivationQuery {
310
317
  * something different on every run.
311
318
  */
312
319
  asOf?: number;
320
+ /**
321
+ * 0.14.4: clock for ACT-R decay. Defaults to Date.now(). `asOf` pinned the
322
+ * temporal PARSER but decay still read the wall clock, so a "frozen" eval
323
+ * snapshot scored differently every day — a 300-query benchmark read 70.0%
324
+ * s@1 one evening and 67.0% the next afternoon on byte-identical data and
325
+ * code. Evals must pass the snapshot's own timestamp here. Production leaves
326
+ * it unset.
327
+ */
328
+ now?: number;
313
329
  bm25Only?: boolean; // Skip embedding — fast text-only retrieval for bulk/benchmark scenarios
314
330
  /**
315
331
  * Output granularity (Paper 3: cognitive teaming, Brill 2018 ACT-R collaboration).
package/src/types/eval.ts CHANGED
@@ -54,7 +54,9 @@ export interface EvalMetrics {
54
54
  // Retrieval quality
55
55
  activationCount: number;
56
56
  avgPrecisionAtK: number; // Of returned results, % judged useful
57
- avgLatencyMs: number;
57
+ avgLatencyMs: number; // kept for callers; misleading on the live store (mixes cold loads) — prefer p50/p90
58
+ p50LatencyMs: number; // 0.14.3
59
+ p90LatencyMs: number; // 0.14.3
58
60
  p95LatencyMs: number;
59
61
 
60
62
  // Connection quality