hippo-memory 1.61.0 → 1.63.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 +37 -53
- package/dist/agent-memories/apply.d.ts +3 -1
- package/dist/agent-memories/apply.js +23 -1
- package/dist/agent-memories/claude-code.d.ts +4 -1
- package/dist/agent-memories/claude-code.js +53 -9
- package/dist/agent-memories/report.d.ts +1 -0
- package/dist/agent-memories/report.js +2 -2
- package/dist/agent-memories/sync.d.ts +3 -3
- package/dist/agent-memories/sync.js +46 -24
- package/dist/agent-memories/types.d.ts +0 -2
- package/dist/ambient-store.d.ts +4 -4
- package/dist/ambient-store.js +4 -3
- package/dist/api/assemble.d.ts +7 -10
- package/dist/api/assemble.js +62 -66
- package/dist/api/audit.d.ts +2 -2
- package/dist/api/audit.js +2 -2
- package/dist/api/auth.d.ts +6 -6
- package/dist/api/auth.js +5 -7
- package/dist/api/context-select.d.ts +50 -0
- package/dist/api/context-select.js +342 -0
- package/dist/api/context-types.d.ts +12 -17
- package/dist/api/context.d.ts +5 -4
- package/dist/api/context.js +208 -535
- package/dist/api/dormant.js +1 -1
- package/dist/api/drill-down.d.ts +4 -4
- package/dist/api/drill-down.js +56 -41
- package/dist/api/outcome.d.ts +8 -13
- package/dist/api/outcome.js +13 -17
- package/dist/api/promote.d.ts +5 -8
- package/dist/api/promote.js +55 -66
- package/dist/api/quarantine.js +3 -2
- package/dist/api/recall-types.d.ts +43 -55
- package/dist/api/recall.d.ts +3 -3
- package/dist/api/recall.js +310 -456
- package/dist/api/remember.d.ts +2 -2
- package/dist/api/sleep.d.ts +7 -35
- package/dist/api/sleep.js +206 -220
- package/dist/api/tokens.d.ts +2 -2
- package/dist/api/tokens.js +2 -2
- package/dist/api/types.d.ts +6 -10
- package/dist/api/types.js +2 -4
- package/dist/audit-prune.d.ts +4 -6
- package/dist/audit-prune.js +3 -5
- package/dist/audit.js +11 -33
- package/dist/auth.d.ts +8 -9
- package/dist/auth.js +5 -7
- package/dist/autolearn.d.ts +1 -1
- package/dist/autolearn.js +1 -1
- package/dist/availability.js +3 -5
- package/dist/capture/command.d.ts +5 -4
- package/dist/capture/command.js +8 -22
- package/dist/capture/compact.d.ts +2 -2
- package/dist/capture/compact.js +11 -15
- package/dist/capture/extract.js +37 -115
- package/dist/capture-error.d.ts +1 -1
- package/dist/capture-error.js +1 -1
- package/dist/churn-git.d.ts +1 -1
- package/dist/churn-git.js +1 -1
- package/dist/cli/audit.js +3 -4
- package/dist/cli/auth.js +3 -6
- package/dist/cli/briefs.js +324 -306
- package/dist/cli/context.js +44 -34
- package/dist/cli/continuity.js +283 -271
- package/dist/cli/curate.d.ts +1 -1
- package/dist/cli/curate.js +43 -58
- package/dist/cli/dag.js +5 -9
- package/dist/cli/decisions.js +334 -345
- package/dist/cli/explain.js +68 -61
- package/dist/cli/goals.js +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/maintenance.js +62 -51
- package/dist/cli/playbooks.js +391 -379
- package/dist/cli/projects.js +11 -6
- package/dist/cli/recall.js +30 -44
- package/dist/cli/remember.js +118 -87
- package/dist/cli/session-hooks.js +106 -115
- package/dist/cli/setup.d.ts +1 -1
- package/dist/cli/setup.js +267 -250
- package/dist/cli/shared.js +3 -3
- package/dist/cli/slack.js +1 -1
- package/dist/cli/sleep.js +27 -1
- package/dist/cli/status.d.ts +4 -4
- package/dist/cli/status.js +80 -76
- package/dist/cli/transfer.js +88 -107
- package/dist/cli/usage.js +9 -6
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +4 -9
- package/dist/compaction-record.d.ts +2 -2
- package/dist/compaction-record.js +89 -68
- package/dist/compare.d.ts +11 -16
- package/dist/compare.js +11 -16
- package/dist/config.d.ts +19 -18
- package/dist/config.js +90 -67
- package/dist/connectors/github/backfill.d.ts +2 -2
- package/dist/connectors/github/backfill.js +8 -15
- package/dist/connectors/github/cli-impl.js +3 -8
- package/dist/connectors/github/deletion.d.ts +5 -12
- package/dist/connectors/github/deletion.js +5 -12
- package/dist/connectors/github/dlq.d.ts +6 -9
- package/dist/connectors/github/dlq.js +2 -3
- package/dist/connectors/github/ingest.d.ts +5 -7
- package/dist/connectors/github/ingest.js +8 -12
- package/dist/connectors/github/octokit-client.d.ts +3 -5
- package/dist/connectors/github/octokit-client.js +5 -6
- package/dist/connectors/github/signature.d.ts +9 -39
- package/dist/connectors/github/signature.js +9 -39
- package/dist/connectors/github/tenant-routing.d.ts +1 -1
- package/dist/connectors/github/tenant-routing.js +1 -1
- package/dist/connectors/github/transform.js +2 -2
- package/dist/connectors/github/types.d.ts +2 -10
- package/dist/connectors/github/types.js +1 -3
- package/dist/connectors/slack/deletion.d.ts +3 -8
- package/dist/connectors/slack/deletion.js +3 -8
- package/dist/connectors/slack/dlq.d.ts +1 -1
- package/dist/connectors/slack/ingest.d.ts +1 -1
- package/dist/connectors/slack/ingest.js +7 -16
- package/dist/connectors/slack/signature.d.ts +1 -1
- package/dist/connectors/slack/tenant-routing.d.ts +3 -5
- package/dist/connectors/slack/tenant-routing.js +3 -5
- package/dist/connectors/slack/transform.d.ts +5 -6
- package/dist/connectors/slack/transform.js +5 -6
- package/dist/connectors/slack/types.d.ts +2 -6
- package/dist/connectors/slack/types.js +1 -3
- package/dist/connectors/slack/web-client.js +10 -3
- package/dist/connectors/slack/workspaces.d.ts +3 -5
- package/dist/connectors/slack/workspaces.js +3 -5
- package/dist/consolidate/conflicts.js +3 -14
- package/dist/consolidate/decay.js +9 -29
- package/dist/consolidate/llm-passes.js +4 -5
- package/dist/consolidate/merge.js +8 -23
- package/dist/consolidate/run.d.ts +1 -8
- package/dist/consolidate/run.js +3 -25
- package/dist/consolidate/sleep.js +5 -17
- package/dist/consolidate/traces.js +9 -21
- package/dist/customer-notes.d.ts +5 -7
- package/dist/customer-notes.js +82 -76
- package/dist/dag.d.ts +10 -21
- package/dist/dag.js +189 -203
- package/dist/db/continuity.js +2 -2
- package/dist/db/migrations/v14.js +1 -1
- package/dist/db/migrations/v15.js +1 -2
- package/dist/db/migrations/v16.js +3 -4
- package/dist/db/migrations/v17.js +2 -3
- package/dist/db/migrations/v19.js +1 -1
- package/dist/db/migrations/v20.js +1 -1
- package/dist/db/migrations/v21.js +2 -6
- package/dist/db/migrations/v22.js +2 -4
- package/dist/db/migrations/v23.js +1 -1
- package/dist/db/migrations/v24.js +4 -6
- package/dist/db/migrations/v25.js +2 -3
- package/dist/db/migrations/v26.js +3 -3
- package/dist/db/migrations/v27.js +2 -10
- package/dist/db/migrations/v28.js +5 -8
- package/dist/db/migrations/v29.js +3 -4
- package/dist/db/migrations/v30.js +2 -2
- package/dist/db/migrations/v31.js +1 -1
- package/dist/db/migrations/v32.js +1 -1
- package/dist/db/migrations/v33.js +3 -3
- package/dist/db/migrations/v34.js +1 -1
- package/dist/db/migrations/v35.js +3 -4
- package/dist/db/migrations/v36.js +3 -4
- package/dist/db/migrations/v37.js +5 -5
- package/dist/db/migrations/v38.js +7 -8
- package/dist/db/migrations/v39.js +1 -1
- package/dist/db/migrations/v40.js +4 -16
- package/dist/db/migrations/v41.js +3 -4
- package/dist/db/migrations/v42.js +3 -4
- package/dist/db/migrations/v45.js +1 -1
- package/dist/db/migrations/v46.js +1 -1
- package/dist/db/migrations/v47.js +1 -1
- package/dist/db/migrations/v48.js +1 -1
- package/dist/decisions.d.ts +2 -2
- package/dist/decisions.js +97 -80
- package/dist/dedupe.js +86 -61
- package/dist/delivery-recorder.js +154 -135
- package/dist/doctor.js +129 -110
- package/dist/dormant.js +1 -4
- package/dist/embedding-provider.d.ts +4 -8
- package/dist/embedding-provider.js +4 -8
- package/dist/embeddings.js +55 -47
- package/dist/env.d.ts +1 -1
- package/dist/env.js +12 -12
- package/dist/escape.d.ts +5 -0
- package/dist/escape.js +10 -0
- package/dist/eval-stats.d.ts +1 -2
- package/dist/eval-stats.js +1 -2
- package/dist/eval-suite.js +27 -21
- package/dist/extract.js +4 -9
- package/dist/failure-log.d.ts +3 -3
- package/dist/failure-log.js +1 -1
- package/dist/forward-claim-detector.d.ts +2 -4
- package/dist/forward-claim-detector.js +6 -11
- package/dist/goals.d.ts +3 -3
- package/dist/goals.js +103 -91
- package/dist/graph/read.d.ts +2 -2
- package/dist/graph/read.js +5 -6
- package/dist/graph/types.d.ts +8 -8
- package/dist/graph/write.d.ts +7 -14
- package/dist/graph/write.js +16 -23
- package/dist/graph-extract.d.ts +7 -8
- package/dist/graph-extract.js +62 -72
- package/dist/graph-recall.d.ts +2 -2
- package/dist/graph-recall.js +55 -49
- package/dist/graph-stream.d.ts +5 -6
- package/dist/graph-stream.js +66 -57
- package/dist/graph-view.d.ts +2 -2
- package/dist/graph-view.js +7 -7
- package/dist/half-life-migration.d.ts +1 -2
- package/dist/half-life-migration.js +2 -3
- package/dist/hooks/codex-session.js +1 -1
- package/dist/hooks/codex-wrapper.d.ts +1 -1
- package/dist/hooks/codex-wrapper.js +3 -2
- package/dist/hooks/json-hooks.d.ts +2 -2
- package/dist/hooks/json-hooks.js +5 -4
- package/dist/hooks/opencode.d.ts +1 -1
- package/dist/hooks/opencode.js +5 -4
- package/dist/hooks/shared.d.ts +3 -7
- package/dist/hooks/shared.js +1 -8
- package/dist/http-util.d.ts +2 -3
- package/dist/http-util.js +3 -0
- package/dist/importers/core.d.ts +2 -9
- package/dist/importers/core.js +15 -30
- package/dist/importers/sources.js +2 -1
- package/dist/importers/vault.js +2 -20
- package/dist/incidents.d.ts +1 -1
- package/dist/incidents.js +46 -39
- package/dist/instruction-detect.d.ts +1 -1
- package/dist/instruction-detect.js +1 -1
- package/dist/invalidation.d.ts +3 -0
- package/dist/invalidation.js +160 -114
- package/dist/json.d.ts +5 -0
- package/dist/json.js +4 -0
- package/dist/judgment.js +1 -2
- package/dist/local-embedding.js +1 -1
- package/dist/mcp/admin-tools.js +7 -17
- package/dist/mcp/format.js +1 -1
- package/dist/mcp/framing.js +3 -6
- package/dist/mcp/protocol.d.ts +2 -5
- package/dist/mcp/protocol.js +1 -3
- package/dist/mcp/recall-tools.js +12 -15
- package/dist/mcp/request.js +4 -3
- package/dist/mcp/session-state.js +2 -3
- package/dist/mcp/stdio.js +2 -1
- package/dist/mcp/tools.js +9 -6
- package/dist/memory-value-weights.d.ts +5 -8
- package/dist/memory-value-weights.js +5 -8
- package/dist/memory-value.d.ts +13 -13
- package/dist/memory-value.js +26 -37
- package/dist/memory.d.ts +20 -22
- package/dist/memory.js +24 -48
- package/dist/multihop.d.ts +1 -1
- package/dist/multihop.js +3 -2
- package/dist/owner-validation.d.ts +4 -5
- package/dist/owner-validation.js +4 -5
- package/dist/physics.d.ts +4 -4
- package/dist/physics.js +7 -9
- package/dist/policies.d.ts +9 -10
- package/dist/policies.js +96 -81
- package/dist/postinstall.js +3 -6
- package/dist/predictions/planning-fallacy.d.ts +9 -14
- package/dist/predictions/planning-fallacy.js +10 -16
- package/dist/predictions/store.d.ts +15 -23
- package/dist/predictions/store.js +36 -33
- package/dist/processes.d.ts +2 -7
- package/dist/processes.js +88 -72
- package/dist/project-briefs.d.ts +2 -3
- package/dist/project-briefs.js +141 -118
- package/dist/project-identity.d.ts +22 -9
- package/dist/project-identity.js +47 -12
- package/dist/project-merge.d.ts +28 -5
- package/dist/project-merge.js +213 -46
- package/dist/project-remote.d.ts +12 -0
- package/dist/project-remote.js +138 -0
- package/dist/prompt-recall.js +1 -2
- package/dist/rate-limit.d.ts +1 -1
- package/dist/rate-limit.js +1 -1
- package/dist/raw-archive.d.ts +9 -0
- package/dist/raw-archive.js +70 -53
- package/dist/recall-history.d.ts +19 -20
- package/dist/recall-history.js +24 -42
- package/dist/recall-pipeline.js +4 -28
- package/dist/recall-scope.d.ts +7 -8
- package/dist/recall-scope.js +7 -8
- package/dist/recall-trace.d.ts +5 -9
- package/dist/recall-trace.js +6 -10
- package/dist/refine-llm.d.ts +1 -1
- package/dist/refine-llm.js +2 -2
- package/dist/reject-flow.d.ts +3 -4
- package/dist/reject-flow.js +122 -117
- package/dist/rejection.d.ts +5 -6
- package/dist/rejection.js +7 -15
- package/dist/rerankers/clef.d.ts +1 -1
- package/dist/rerankers/jev.d.ts +1 -2
- package/dist/rerankers/jev.js +4 -5
- package/dist/rerankers/llm.d.ts +1 -2
- package/dist/rerankers/llm.js +1 -2
- package/dist/rerankers/types.d.ts +1 -2
- package/dist/rrf.d.ts +2 -2
- package/dist/rrf.js +2 -2
- package/dist/search/bm25-search.d.ts +1 -1
- package/dist/search/bm25-search.js +2 -1
- package/dist/search/boosts.js +2 -1
- package/dist/search/hybrid.d.ts +1 -1
- package/dist/search/hybrid.js +2 -1
- package/dist/search/physics-search.d.ts +1 -1
- package/dist/search/physics-search.js +2 -1
- package/dist/search/types.d.ts +2 -0
- package/dist/search/types.js +3 -1
- package/dist/secret-detect.d.ts +4 -5
- package/dist/secret-detect.js +6 -10
- package/dist/server/auth.js +5 -5
- package/dist/server/client-ip.js +1 -1
- package/dist/server/cursor.js +2 -1
- package/dist/server/mcp-http.js +4 -4
- package/dist/server/request.d.ts +3 -6
- package/dist/server/request.js +6 -7
- package/dist/server/routes/admin.js +5 -4
- package/dist/server/routes/customer-notes.js +6 -5
- package/dist/server/routes/decisions.js +4 -3
- package/dist/server/routes/incidents.js +7 -5
- package/dist/server/routes/memories.js +7 -7
- package/dist/server/routes/policies.js +3 -2
- package/dist/server/routes/predictions.js +12 -15
- package/dist/server/routes/processes.js +3 -2
- package/dist/server/routes/project-briefs.js +8 -7
- package/dist/server/routes/recall.js +95 -93
- package/dist/server/routes/skills.js +6 -5
- package/dist/server/types.d.ts +1 -1
- package/dist/server/validation.d.ts +1 -2
- package/dist/server/validation.js +7 -14
- package/dist/server-detect.js +72 -58
- package/dist/server.d.ts +2 -2
- package/dist/server.js +131 -117
- package/dist/shared.d.ts +26 -17
- package/dist/shared.js +102 -104
- package/dist/skills.d.ts +3 -3
- package/dist/skills.js +88 -72
- package/dist/store/audit-event.d.ts +2 -2
- package/dist/store/audit-event.js +1 -1
- package/dist/store/candidates.d.ts +2 -2
- package/dist/store/candidates.js +4 -3
- package/dist/store/conflicts.js +30 -22
- package/dist/store/delete-and-batch.d.ts +11 -14
- package/dist/store/delete-and-batch.js +40 -91
- package/dist/store/entry-reads.d.ts +17 -25
- package/dist/store/entry-reads.js +59 -40
- package/dist/store/entry-row.d.ts +6 -24
- package/dist/store/entry-row.js +6 -24
- package/dist/store/entry-writes.d.ts +6 -7
- package/dist/store/entry-writes.js +13 -11
- package/dist/store/handoffs.d.ts +1 -1
- package/dist/store/handoffs.js +7 -10
- package/dist/store/index-and-stats.d.ts +2 -6
- package/dist/store/index-and-stats.js +4 -10
- package/dist/store/mirrors.d.ts +6 -19
- package/dist/store/mirrors.js +14 -39
- package/dist/store/open.js +9 -31
- package/dist/store/rows.d.ts +5 -11
- package/dist/store/rows.js +6 -11
- package/dist/store/search-rows.d.ts +17 -34
- package/dist/store/search-rows.js +34 -56
- package/dist/store/sessions.d.ts +4 -5
- package/dist/store/sessions.js +5 -6
- package/dist/store/summaries.d.ts +13 -17
- package/dist/store/summaries.js +26 -70
- package/dist/support-bundle.js +4 -8
- package/dist/tenant.d.ts +1 -5
- package/dist/token-ledger.d.ts +1 -1
- package/dist/token-ledger.js +3 -5
- package/dist/trace.js +1 -3
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/working-memory.d.ts +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/store/summaries.js
CHANGED
|
@@ -7,17 +7,12 @@ import { audit } from './audit-event.js';
|
|
|
7
7
|
import { syncFtsRow } from './entry-row.js';
|
|
8
8
|
import { openStore } from './open.js';
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
// Used by E2 (child-write propagation in invalidation.ts / writeEntry /
|
|
14
|
-
// forgetMemory / archiveRawMemory) to mark a summary dirty when one of its
|
|
15
|
-
// children changes, and by E3's sleep-cycle rebuildDirtySummaries phase to
|
|
16
|
-
// enumerate candidates without scanning every memory row.
|
|
10
|
+
// Dirty-flag helpers for DAG summaries: child writes mark a summary dirty, and the
|
|
11
|
+
// sleep-cycle rebuild enumerates candidates without scanning every memory row.
|
|
17
12
|
// ---------------------------------------------------------------------------
|
|
18
13
|
/**
|
|
19
14
|
* Load summaries flagged dirty for the given tenant. Sorted by latest_at
|
|
20
|
-
* DESC (NULLS LAST) so
|
|
15
|
+
* DESC (NULLS LAST) so the rebuild cap (HIPPO_DAG_REBUILD_CAP, default 20)
|
|
21
16
|
* takes the most-recently-changed summaries first.
|
|
22
17
|
*
|
|
23
18
|
* Returns full MemoryEntry shape via MEMORY_SELECT_COLUMNS + rowToEntry
|
|
@@ -46,13 +41,12 @@ export function loadDirtySummaries(hippoRoot, tenantId) {
|
|
|
46
41
|
/**
|
|
47
42
|
* Mark a summary as dirty. Idempotent (re-marking dirty is a no-op + no
|
|
48
43
|
* second audit row). Tenant-scoped to prevent cross-tenant writes via
|
|
49
|
-
* parent-lookup. Called
|
|
44
|
+
* parent-lookup. Called from invalidation.ts / writeEntry /
|
|
50
45
|
* forgetMemory / archiveRawMemory whenever a child is invalidated,
|
|
51
46
|
* superseded, forgotten, or archived.
|
|
52
47
|
*
|
|
53
|
-
* Quietly no-ops if the target row doesn't exist or isn't a level-2
|
|
54
|
-
* summary
|
|
55
|
-
* build path lands). Emits a 'summary_marked_dirty' audit row on actual
|
|
48
|
+
* Quietly no-ops if the target row doesn't exist or isn't a level-2/3
|
|
49
|
+
* summary. Emits a 'summary_marked_dirty' audit row on actual
|
|
56
50
|
* state transitions (0 -> 1) via the audit() helper, which try/catches
|
|
57
51
|
* for missing audit_log (the v27 self-heal scenario).
|
|
58
52
|
*/
|
|
@@ -60,8 +54,7 @@ export function markSummaryDirty(hippoRoot, summaryId, tenantId, actor = 'cli')
|
|
|
60
54
|
assertTenantId('markSummaryDirty', tenantId);
|
|
61
55
|
const db = openStore(hippoRoot);
|
|
62
56
|
try {
|
|
63
|
-
//
|
|
64
|
-
// actual level in same round trip.
|
|
57
|
+
// RETURNING dag_level reads the actual level in the same round trip.
|
|
65
58
|
// SAFETY: result's shape matches the single `dag_level` column returned
|
|
66
59
|
// above.
|
|
67
60
|
const result = db.prepare(`
|
|
@@ -76,8 +69,7 @@ export function markSummaryDirty(hippoRoot, summaryId, tenantId, actor = 'cli')
|
|
|
76
69
|
`).get(summaryId, tenantId);
|
|
77
70
|
if (result) {
|
|
78
71
|
// audit() wraps appendAuditEvent in try/catch (v27 heal scenario).
|
|
79
|
-
// metadata.source
|
|
80
|
-
// distinguish dirty-marks across the arc's wiring layers.
|
|
72
|
+
// metadata.source tells this dirty-mark apart from the other wiring layers' marks.
|
|
81
73
|
audit(db, 'summary_marked_dirty', summaryId, { dag_level: result.dag_level, source: 'E1' }, actor, tenantId);
|
|
82
74
|
}
|
|
83
75
|
}
|
|
@@ -86,7 +78,7 @@ export function markSummaryDirty(hippoRoot, summaryId, tenantId, actor = 'cli')
|
|
|
86
78
|
}
|
|
87
79
|
}
|
|
88
80
|
// ---------------------------------------------------------------------------
|
|
89
|
-
//
|
|
81
|
+
// Sleep-cycle rebuild surface.
|
|
90
82
|
//
|
|
91
83
|
// loadAllDirtySummaries / loadChildrenOfSummary / applyRebuildResult /
|
|
92
84
|
// clearSummaryDirtyAfterBuild live HERE (not in dag.ts) because they need
|
|
@@ -95,9 +87,9 @@ export function markSummaryDirty(hippoRoot, summaryId, tenantId, actor = 'cli')
|
|
|
95
87
|
// rebuildDirtySummaries() that calls into these.
|
|
96
88
|
// ---------------------------------------------------------------------------
|
|
97
89
|
/**
|
|
98
|
-
*
|
|
90
|
+
* Host-wide loader for L2 topic summaries without an L3 parent.
|
|
99
91
|
* Used by consolidate phase 1.9 (buildEntityProfiles) to cluster L2s into
|
|
100
|
-
* L3 entity profiles. Mirrors loadAllDirtySummaries
|
|
92
|
+
* L3 entity profiles. Mirrors loadAllDirtySummaries: SQL-level
|
|
101
93
|
* filter is cheaper than reusing in-memory `survivors` (which doesn't
|
|
102
94
|
* contain L2s freshly created by phase 1.7 buildDag).
|
|
103
95
|
*
|
|
@@ -125,7 +117,7 @@ export function loadAllL2Summaries(hippoRoot) {
|
|
|
125
117
|
}
|
|
126
118
|
}
|
|
127
119
|
/**
|
|
128
|
-
*
|
|
120
|
+
* Host-wide variant of loadDirtySummaries. Iterates all tenants
|
|
129
121
|
* in one query so consolidate.ts (host-wide per L106-109) does not need a
|
|
130
122
|
* per-tenant loop. Each returned MemoryEntry carries its own tenantId (via
|
|
131
123
|
* rowToEntry), so per-summary children + rebuild UPDATE stay tenant-scoped.
|
|
@@ -152,7 +144,7 @@ export function loadAllDirtySummaries(hippoRoot) {
|
|
|
152
144
|
}
|
|
153
145
|
}
|
|
154
146
|
/**
|
|
155
|
-
*
|
|
147
|
+
* Load live children of a DAG summary. Used by
|
|
156
148
|
* rebuildDirtySummaries to regenerate content from the CURRENT child set
|
|
157
149
|
* (not the children at create-time). Skips archived. Tenant-scoped
|
|
158
150
|
* (defence in depth — dag_parent_id is unique-ish but tenant guard is
|
|
@@ -180,7 +172,7 @@ export function loadChildrenOfSummary(hippoRoot, summaryId, tenantId) {
|
|
|
180
172
|
}
|
|
181
173
|
}
|
|
182
174
|
/**
|
|
183
|
-
*
|
|
175
|
+
* Apply a rebuild result to a dirty summary. Atomic: one
|
|
184
176
|
* prepared UPDATE statement plus syncFtsRow inside one SAVEPOINT.
|
|
185
177
|
* WHERE includes `AND summary_dirty = 1` so concurrent sleep's race-loser
|
|
186
178
|
* becomes a no-op (no rebuild_count bump, no audit row).
|
|
@@ -217,7 +209,6 @@ export function applyRebuildResult(hippoRoot, summary, patch) {
|
|
|
217
209
|
}
|
|
218
210
|
}
|
|
219
211
|
// ONE prepared UPDATE per branch. Test #8 inspects the SQL string.
|
|
220
|
-
// v0.30 / E5: widened dag_level=2 -> IN (2, 3) on both branches.
|
|
221
212
|
const REBUILD_CONTENT_SQL = `UPDATE memories
|
|
222
213
|
SET content = ?,
|
|
223
214
|
descendant_count = ?,
|
|
@@ -243,17 +234,8 @@ const REBUILD_METADATA_SQL = `UPDATE memories
|
|
|
243
234
|
AND kind != 'archived'`;
|
|
244
235
|
function applyRebuildInSavepoint(db, summary, patch) {
|
|
245
236
|
const nowIso = new Date().toISOString();
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
// a direct UPDATE, bypassing the rejection guard entirely (the guard
|
|
249
|
-
// lives in upsertEntryRow's INSERT path, which this function never
|
|
250
|
-
// calls). A rebuild that regenerates byte-identical content to an
|
|
251
|
-
// already-rejected value (e.g. deterministic summarization of an
|
|
252
|
-
// unchanged child set) would silently re-assert it every sleep cycle.
|
|
253
|
-
// Check BEFORE choosing which UPDATE to run — only the
|
|
254
|
-
// bumpRebuildCount branch ever writes content, so a miss or a
|
|
255
|
-
// zero-child call is a no-op here (one indexed point query, guarded
|
|
256
|
-
// path only).
|
|
237
|
+
// Check tombstones before choosing the UPDATE: this direct UPDATE bypasses upsertEntryRow's guard, and
|
|
238
|
+
// a deterministic rebuild would otherwise re-assert a rejected value every sleep cycle.
|
|
257
239
|
const tombstone = patch.bumpRebuildCount
|
|
258
240
|
? findRejectedValue(db, summary.tenantId, rejectionDigest(patch.content))
|
|
259
241
|
: null;
|
|
@@ -268,23 +250,8 @@ function applyRebuildInSavepoint(db, summary, patch) {
|
|
|
268
250
|
const result = applyContentWrite
|
|
269
251
|
? db.prepare(REBUILD_CONTENT_SQL).run(patch.content, patch.descendant_count, patch.earliest_at, patch.latest_at, nowIso, summary.id, summary.tenantId)
|
|
270
252
|
: db.prepare(REBUILD_METADATA_SQL).run(patch.descendant_count, patch.earliest_at, patch.latest_at, summary.id, summary.tenantId);
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
// whether patch.content specifically landed. On a refusal, metadata
|
|
274
|
-
// still applies, so changed=true even though content did not change.
|
|
275
|
-
// This preserves the pre-T4 no-infinite-retry choice: the caller
|
|
276
|
-
// (dag.ts rebuildDirtySummaries) treats changed=false as "race lost,
|
|
277
|
-
// silently retry next cycle" — returning false on a refusal would
|
|
278
|
-
// retry the same doomed LLM rebuild forever, so changed=true settles
|
|
279
|
-
// this cycle (dirty cleared) regardless of refusal.
|
|
280
|
-
// `refused` is the T4 addition: true only when a tombstone hit AND
|
|
281
|
-
// the metadata UPDATE landed (changed=true) — a refusal that loses
|
|
282
|
-
// the race to a concurrent writer reports refused=false too, since
|
|
283
|
-
// nothing from this call took effect. Before T4, a refusal also
|
|
284
|
-
// counted toward the caller's `rebuilt` stat because `changed` alone
|
|
285
|
-
// could not distinguish it; the caller now increments `refused`
|
|
286
|
-
// instead of `rebuilt` when this is true, so the stat reflects what
|
|
287
|
-
// happened without changing dirty-clearing or retry behavior.
|
|
253
|
+
// `changed` means THIS call's UPDATE hit a row, so a refusal still settles the cycle (false would retry
|
|
254
|
+
// the doomed rebuild forever); `refused` lets the caller count it as refused rather than rebuilt.
|
|
288
255
|
const changed = (result.changes ?? 0) > 0;
|
|
289
256
|
const refused = Boolean(tombstone) && changed;
|
|
290
257
|
if (tombstone && changed)
|
|
@@ -307,13 +274,8 @@ function auditRefusedRebuild(db, summary, patch, tombstone) {
|
|
|
307
274
|
`(digest ${tombstone.digest.slice(0, 12)}...); metadata updated, content unchanged`);
|
|
308
275
|
}
|
|
309
276
|
function syncRebuiltSummary(db, summary, patch, applyContentWrite, nowIso) {
|
|
310
|
-
//
|
|
311
|
-
//
|
|
312
|
-
// memory and reuse the existing syncFtsRow helper (delete-then-insert).
|
|
313
|
-
// earliest_at/latest_at preserve null semantics (R2 must-fix).
|
|
314
|
-
// AT1: content stays summary.content (unchanged) when the write was
|
|
315
|
-
// refused — applyContentWrite is false, so patch.content was never
|
|
316
|
-
// written to the row FTS must mirror.
|
|
277
|
+
// A bare UPDATE on memories does NOT update memories_fts, so resync from the patched entry;
|
|
278
|
+
// content stays summary.content when the write was refused, since FTS must mirror the row.
|
|
317
279
|
const patchedEntry = {
|
|
318
280
|
...summary,
|
|
319
281
|
content: applyContentWrite ? patch.content : summary.content,
|
|
@@ -328,8 +290,7 @@ function syncRebuiltSummary(db, summary, patch, applyContentWrite, nowIso) {
|
|
|
328
290
|
};
|
|
329
291
|
syncFtsRow(db, patchedEntry);
|
|
330
292
|
audit(db, 'summary_rebuilt', summary.id, {
|
|
331
|
-
//
|
|
332
|
-
// (NOT hardcoded 2). L2 -> 2, L3 -> 3.
|
|
293
|
+
// Actual level from the summary in scope, never hardcoded: L2 -> 2, L3 -> 3.
|
|
333
294
|
dag_level: summary.dag_level,
|
|
334
295
|
source: 'E3-rebuild',
|
|
335
296
|
zero_children: patch.zeroChildren,
|
|
@@ -337,21 +298,17 @@ function syncRebuiltSummary(db, summary, patch, applyContentWrite, nowIso) {
|
|
|
337
298
|
}, patch.actor, summary.tenantId);
|
|
338
299
|
}
|
|
339
300
|
/**
|
|
340
|
-
*
|
|
341
|
-
*
|
|
342
|
-
* each member's writeEntry call fires markSummaryDirtyInTx on the just-
|
|
343
|
-
* created parent (E2 hook at store.ts:1214), and the same sleep cycle's
|
|
344
|
-
* E3 rebuild phase would re-rebuild every new summary (2x LLM cost).
|
|
301
|
+
* Clear summary_dirty on a freshly-built summary. Called by buildDag right after the child-link loop:
|
|
302
|
+
* each member's writeEntry marks the new parent dirty, so the same cycle's rebuild would redo every new summary.
|
|
345
303
|
*
|
|
346
304
|
* Idempotent: no-op + no audit if summary isn't dirty. Audit
|
|
347
|
-
* source='buildDag-clean' distinguishes from
|
|
305
|
+
* source='buildDag-clean' distinguishes it from the rebuild's source.
|
|
348
306
|
*/
|
|
349
307
|
export function clearSummaryDirtyAfterBuild(hippoRoot, summaryId, tenantId, actor = 'cli', source = 'buildDag-clean') {
|
|
350
308
|
assertTenantId('clearSummaryDirtyAfterBuild', tenantId);
|
|
351
309
|
const db = openStore(hippoRoot);
|
|
352
310
|
try {
|
|
353
|
-
//
|
|
354
|
-
// actual level so audit metadata stays accurate without an extra SELECT.
|
|
311
|
+
// RETURNING dag_level reads the actual level so audit metadata stays accurate without an extra SELECT.
|
|
355
312
|
// SAFETY: result's shape matches the single `dag_level` column returned
|
|
356
313
|
// below.
|
|
357
314
|
const result = db.prepare(`
|
|
@@ -365,8 +322,7 @@ export function clearSummaryDirtyAfterBuild(hippoRoot, summaryId, tenantId, acto
|
|
|
365
322
|
RETURNING dag_level
|
|
366
323
|
`).get(summaryId, tenantId);
|
|
367
324
|
if (result) {
|
|
368
|
-
//
|
|
369
|
-
// buildEntityProfiles-clean (L3) and any future build path.
|
|
325
|
+
// source tells buildDag-clean (L2) from buildEntityProfiles-clean (L3) and any future build path.
|
|
370
326
|
audit(db, 'summary_marked_clean', summaryId, { dag_level: result.dag_level, source }, actor, tenantId);
|
|
371
327
|
}
|
|
372
328
|
}
|
package/dist/support-bundle.js
CHANGED
|
@@ -11,6 +11,8 @@ import { openHippoDbReadOnly, closeHippoDb, getSchemaVersion, getMeta, countTabl
|
|
|
11
11
|
import { runDoctor } from './doctor.js';
|
|
12
12
|
import { loadConfig } from './config.js';
|
|
13
13
|
import { redactSecretsStrict } from './secret-detect.js';
|
|
14
|
+
import { isJsonString } from './json.js';
|
|
15
|
+
import { escapeRegex } from './escape.js';
|
|
14
16
|
const TAIL_MAX_BYTES = 256 * 1024;
|
|
15
17
|
export const TAIL_MAX_LINES = 200;
|
|
16
18
|
const TAIL_MAX_LINE_CHARS = 2000;
|
|
@@ -28,9 +30,6 @@ const CONFIG_SECRET_KEY_RE = /key|token|secret|passw|credential|auth|cookie|bear
|
|
|
28
30
|
function isJsonObject(v) {
|
|
29
31
|
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
30
32
|
}
|
|
31
|
-
function isJsonString(v) {
|
|
32
|
-
return typeof v === 'string';
|
|
33
|
-
}
|
|
34
33
|
function buildRuntime() {
|
|
35
34
|
return {
|
|
36
35
|
node: process.versions.node,
|
|
@@ -177,9 +176,6 @@ function buildLogsSection(opts) {
|
|
|
177
176
|
}
|
|
178
177
|
return logs;
|
|
179
178
|
}
|
|
180
|
-
function escapeRegExp(s) {
|
|
181
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
182
|
-
}
|
|
183
179
|
// The native realpath is the only form that exposes a short-name (8.3) or symlinked alias for what it is.
|
|
184
180
|
function nativeRealPathKey(p) {
|
|
185
181
|
try {
|
|
@@ -232,12 +228,12 @@ function mountedDrive(letter) {
|
|
|
232
228
|
/** Regex source for one spelling of the home, or null when too little of it is left to swap safely. */
|
|
233
229
|
function spellingPattern(spelling, deep) {
|
|
234
230
|
if (process.platform !== 'win32')
|
|
235
|
-
return spelling.length >= 3 ?
|
|
231
|
+
return spelling.length >= 3 ? escapeRegex(spelling) : null;
|
|
236
232
|
// Each tool that mounts a drive writes it its own way, so a home two or more folders below its drive (\Users\<name>)
|
|
237
233
|
// matches after any prefix, with \, / or JSON's \\ between folders. A drive written a known way goes into the swap with it.
|
|
238
234
|
const drive = /^([A-Za-z])[:-]/.exec(spelling);
|
|
239
235
|
const below = drive === null ? spelling : spelling.slice(2);
|
|
240
|
-
const body = below.split(/[\\/]+/).map(
|
|
236
|
+
const body = below.split(/[\\/]+/).map(escapeRegex).join('[\\\\/]+');
|
|
241
237
|
if (drive === null) {
|
|
242
238
|
if (spelling.length < 3)
|
|
243
239
|
return null;
|
package/dist/tenant.d.ts
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import type { DatabaseSyncLike } from './db.js';
|
|
2
|
+
import type { JsonValue } from './json.js';
|
|
2
3
|
export interface ResolveOpts {
|
|
3
4
|
db?: DatabaseSyncLike;
|
|
4
5
|
apiKey?: string;
|
|
5
6
|
}
|
|
6
7
|
export declare function resolveTenantId(opts: ResolveOpts): string;
|
|
7
|
-
/** A value that round-trips through JSON.stringify/JSON.parse unchanged. */
|
|
8
|
-
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
9
|
-
[key: string]: JsonValue;
|
|
10
|
-
};
|
|
11
8
|
/**
|
|
12
9
|
* Defensive runtime guard for tenant id arguments.
|
|
13
10
|
*
|
|
@@ -25,5 +22,4 @@ type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
|
25
22
|
* Acceptable tradeoff for catching the silent-leak class.
|
|
26
23
|
*/
|
|
27
24
|
export declare function assertTenantId(fnName: string, value: JsonValue): asserts value is string;
|
|
28
|
-
export {};
|
|
29
25
|
//# sourceMappingURL=tenant.d.ts.map
|
package/dist/token-ledger.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { DatabaseSyncLike } from './db.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Where a block of memory text was sent.
|
|
4
4
|
* - `hook`: the per-prompt `UserPromptSubmit` hook (`hippo context --pinned-only`).
|
|
5
|
-
* - `hook_recall`: the same hook's
|
|
5
|
+
* - `hook_recall`: the same hook's prompt-recall section.
|
|
6
6
|
* - `compact_resume`: the snapshot the SessionStart(compact) hook prints (`hippo compact-resume`).
|
|
7
7
|
* - `context`, `recall`: the CLI commands.
|
|
8
8
|
* - `mcp_recall`, `mcp_context`: the MCP tools.
|
package/dist/token-ledger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Token ledger
|
|
2
|
+
* Token ledger: what memory text hippo hands agents,
|
|
3
3
|
* and how many tokens it costs.
|
|
4
4
|
*
|
|
5
5
|
* One row per block of memory text sent to an agent, on every surface: the
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Every later model call re-reads a sent block until the host compacts; at session end the worker counts
|
|
12
12
|
* those calls from the transcript as `reread` rows for the {@link REREAD_SURFACES} blocks, dated by call day.
|
|
13
13
|
*
|
|
14
|
-
* It also backs
|
|
14
|
+
* It also backs inject-only-on-change: the per-prompt hook compares the
|
|
15
15
|
* hash of the block it is about to send with the last block it sent in the
|
|
16
16
|
* same session and records a `skip` instead of sending it again.
|
|
17
17
|
*
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { createHash } from 'node:crypto';
|
|
27
27
|
import { open } from 'node:fs/promises';
|
|
28
|
+
import { isJsonString } from './json.js';
|
|
28
29
|
/** All surfaces, in report order. */
|
|
29
30
|
export const TOKEN_SURFACES = [
|
|
30
31
|
'hook', 'hook_recall', 'compact_resume', 'context', 'recall', 'mcp_recall', 'mcp_context',
|
|
@@ -144,9 +145,6 @@ export function summarizeTokenUse(db, tenantId, sinceIso) {
|
|
|
144
145
|
export function isSyntheticMessage(message) {
|
|
145
146
|
return message.model === '<synthetic>';
|
|
146
147
|
}
|
|
147
|
-
function isJsonString(value) {
|
|
148
|
-
return value !== undefined && value !== null && value.constructor === String;
|
|
149
|
-
}
|
|
150
148
|
/** JSON-value plain-object check (excludes arrays and null). */
|
|
151
149
|
function isJsonObject(value) {
|
|
152
150
|
return value !== undefined && value !== null && !Array.isArray(value) && value.constructor === Object;
|
package/dist/trace.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* sequence of agent actions and their final outcome. v1 stores steps as
|
|
6
6
|
* markdown in `content`; `renderTraceContent` is the canonical formatter.
|
|
7
7
|
*/
|
|
8
|
+
import { isJsonString } from './json.js';
|
|
8
9
|
/**
|
|
9
10
|
* Render a trace record as agent-readable markdown.
|
|
10
11
|
*
|
|
@@ -32,9 +33,6 @@ export function renderTraceContent(rec) {
|
|
|
32
33
|
function isJsonRecord(value) {
|
|
33
34
|
return value !== null && !Array.isArray(value) && typeof value === 'object';
|
|
34
35
|
}
|
|
35
|
-
function isJsonString(value) {
|
|
36
|
-
return typeof value === 'string';
|
|
37
|
-
}
|
|
38
36
|
/**
|
|
39
37
|
* Parse a JSON string into an array of TraceStep. Throws on invalid shape.
|
|
40
38
|
*/
|
package/dist/version.d.ts
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* an ESM `import` can resolve cleanly, and a hardcoded constant survives
|
|
17
17
|
* any packager that drops .json files.
|
|
18
18
|
*/
|
|
19
|
-
export declare const PACKAGE_VERSION = "1.
|
|
19
|
+
export declare const PACKAGE_VERSION = "1.63.0";
|
|
20
20
|
/** Compares plain x.y.z versions, positive if a > b; tags throw so the rollback guard never misfires silently. */
|
|
21
21
|
export declare function compareSemver(a: string, b: string): number;
|
|
22
22
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* an ESM `import` can resolve cleanly, and a hardcoded constant survives
|
|
17
17
|
* any packager that drops .json files.
|
|
18
18
|
*/
|
|
19
|
-
export const PACKAGE_VERSION = '1.
|
|
19
|
+
export const PACKAGE_VERSION = '1.63.0';
|
|
20
20
|
/** Compares plain x.y.z versions, positive if a > b; tags throw so the rollback guard never misfires silently. */
|
|
21
21
|
export function compareSemver(a, b) {
|
|
22
22
|
const parse = (v) => {
|
package/dist/working-memory.d.ts
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* importance-ranked, and automatically evicted when the buffer
|
|
6
6
|
* exceeds WM_MAX_ENTRIES per scope.
|
|
7
7
|
*/
|
|
8
|
+
import type { JsonValue } from './json.js';
|
|
8
9
|
export declare const WM_MAX_ENTRIES = 20;
|
|
9
|
-
export type JsonValue = string | number | boolean | null | JsonValue[] | JsonObject;
|
|
10
10
|
export type JsonObject = {
|
|
11
11
|
[key: string]: JsonValue;
|
|
12
12
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "hippo-memory",
|
|
3
3
|
"name": "Hippo Memory",
|
|
4
4
|
"description": "Memory for AI agents that learns what is wrong and ranks it down. Injects context at session start and captures errors.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.63.0",
|
|
6
6
|
|
|
7
7
|
"configSchema": {
|
|
8
8
|
"type": "object",
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "hippo-memory",
|
|
3
3
|
"name": "Hippo Memory",
|
|
4
4
|
"description": "Memory for AI agents that learns what is wrong and ranks it down. Injects context at session start and captures errors.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.63.0",
|
|
6
6
|
"configSchema": {
|
|
7
7
|
"type": "object",
|
|
8
8
|
"additionalProperties": false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hippo-memory",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.63.0",
|
|
4
4
|
"description": "Memory for AI agents that learns what is wrong and ranks it down. MCP server, hooks for Claude Code, OpenCode and Codex, AGENTS.md instructions for Codex, Cursor, OpenClaw and Pi. SQLite, zero runtime deps.",
|
|
5
5
|
"mcpName": "io.github.kitfunso/hippo-memory",
|
|
6
6
|
"type": "module",
|