hippo-memory 1.52.8 → 1.53.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 +185 -101
- package/dist/agent-memories/apply.d.ts +47 -0
- package/dist/agent-memories/apply.js +253 -0
- package/dist/agent-memories/claude-code.d.ts +11 -0
- package/dist/agent-memories/claude-code.js +113 -0
- package/dist/agent-memories/codex.d.ts +3 -0
- package/dist/agent-memories/codex.js +47 -0
- package/dist/agent-memories/copilot.d.ts +3 -0
- package/dist/agent-memories/copilot.js +125 -0
- package/dist/agent-memories/files.d.ts +37 -0
- package/dist/agent-memories/files.js +77 -0
- package/dist/agent-memories/folder-store.d.ts +17 -0
- package/dist/agent-memories/folder-store.js +44 -0
- package/dist/agent-memories/gemini.d.ts +3 -0
- package/dist/agent-memories/gemini.js +103 -0
- package/dist/agent-memories/git.d.ts +8 -0
- package/dist/agent-memories/git.js +11 -0
- package/dist/agent-memories/keys.d.ts +9 -0
- package/dist/agent-memories/keys.js +20 -0
- package/dist/agent-memories/legacy.d.ts +17 -0
- package/dist/agent-memories/legacy.js +45 -0
- package/dist/agent-memories/markdown.d.ts +13 -0
- package/dist/agent-memories/markdown.js +123 -0
- package/dist/agent-memories/openclaw.d.ts +3 -0
- package/dist/agent-memories/openclaw.js +42 -0
- package/dist/agent-memories/plan.d.ts +78 -0
- package/dist/agent-memories/plan.js +123 -0
- package/dist/agent-memories/qwen-code.d.ts +5 -0
- package/dist/agent-memories/qwen-code.js +50 -0
- package/dist/agent-memories/report.d.ts +52 -0
- package/dist/agent-memories/report.js +88 -0
- package/dist/agent-memories/source.d.ts +16 -0
- package/dist/agent-memories/source.js +32 -0
- package/dist/agent-memories/sync.d.ts +33 -0
- package/dist/agent-memories/sync.js +336 -0
- package/dist/agent-memories/tools.d.ts +33 -0
- package/dist/agent-memories/tools.js +19 -0
- package/dist/agent-memories/types.d.ts +42 -0
- package/dist/agent-memories/types.js +2 -0
- package/dist/api.d.ts +53 -20
- package/dist/api.js +141 -97
- package/dist/audit.d.ts +2 -1
- package/dist/audit.js +68 -2
- package/dist/capture.d.ts +48 -22
- package/dist/capture.js +186 -161
- package/dist/cli.d.ts +0 -2
- package/dist/cli.js +750 -797
- package/dist/codex-patch.d.ts +12 -0
- package/dist/codex-patch.js +71 -0
- package/dist/compaction-items.d.ts +18 -0
- package/dist/compaction-items.js +60 -0
- package/dist/compaction-record.d.ts +94 -0
- package/dist/compaction-record.js +546 -0
- package/dist/config.d.ts +4 -1
- package/dist/config.js +13 -4
- package/dist/connectors/slack/types.d.ts +0 -1
- package/dist/consolidate.js +87 -34
- package/dist/context-render.d.ts +36 -0
- package/dist/context-render.js +154 -0
- package/dist/dag.js +3 -2
- package/dist/db.d.ts +5 -1
- package/dist/db.js +46 -14
- package/dist/dedupe.d.ts +6 -6
- package/dist/dedupe.js +10 -9
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +69 -4
- package/dist/dormant.d.ts +9 -3
- package/dist/dormant.js +26 -2
- package/dist/embedding-provider.d.ts +2 -1
- package/dist/embedding-provider.js +2 -1
- package/dist/embeddings.js +23 -3
- package/dist/extract.js +5 -1
- package/dist/forward-claim-detector.d.ts +1 -1
- package/dist/forward-claim-detector.js +1 -1
- package/dist/gated-write.d.ts +9 -0
- package/dist/gated-write.js +24 -0
- package/dist/graph-recall.d.ts +3 -1
- package/dist/graph-recall.js +5 -3
- package/dist/hooks.d.ts +18 -2
- package/dist/hooks.js +128 -32
- package/dist/importers.js +5 -12
- package/dist/judgment.d.ts +30 -0
- package/dist/judgment.js +122 -0
- package/dist/mcp/server.js +171 -210
- package/dist/memory.d.ts +19 -2
- package/dist/memory.js +35 -3
- package/dist/merged-row.d.ts +6 -0
- package/dist/merged-row.js +35 -0
- package/dist/multihop.d.ts +2 -1
- package/dist/multihop.js +7 -4
- package/dist/physics-state.d.ts +0 -4
- package/dist/physics-state.js +0 -6
- package/dist/predictions.d.ts +2 -17
- package/dist/predictions.js +2 -15
- package/dist/reject-flow.d.ts +7 -5
- package/dist/reject-flow.js +41 -12
- package/dist/salience.js +12 -5
- package/dist/same-text.d.ts +17 -0
- package/dist/same-text.js +38 -0
- package/dist/scheduler.d.ts +4 -0
- package/dist/scheduler.js +8 -0
- package/dist/search.d.ts +7 -0
- package/dist/search.js +16 -32
- package/dist/secret-detect.d.ts +2 -0
- package/dist/secret-detect.js +6 -0
- package/dist/server-detect.js +9 -33
- package/dist/server.js +6 -62
- package/dist/session-digest.d.ts +79 -0
- package/dist/session-digest.js +528 -0
- package/dist/shared.d.ts +10 -2
- package/dist/shared.js +44 -36
- package/dist/store.d.ts +9 -2
- package/dist/store.js +25 -2
- package/dist/token-ledger.d.ts +46 -8
- package/dist/token-ledger.js +140 -21
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/extensions/openclaw-plugin/README.md +4 -4
- package/extensions/openclaw-plugin/openclaw.plugin.json +2 -2
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +2 -2
- package/package.json +2 -2
package/dist/server.js
CHANGED
|
@@ -2,12 +2,13 @@ import { createServer } from 'node:http';
|
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
3
|
import { dirname, resolve } from 'node:path';
|
|
4
4
|
import { resolveProjectIdentity } from './project-identity.js';
|
|
5
|
+
import { assembleCost, contextCost, drillCost } from './context-render.js';
|
|
5
6
|
import { detectServer, writePidfile, removePidfileIfOwned } from './server-detect.js';
|
|
6
7
|
import { resolveTenantId } from './tenant.js';
|
|
7
8
|
import { openHippoDb, closeHippoDb } from './db.js';
|
|
8
9
|
import { updateStats } from './store.js';
|
|
9
10
|
import { buildSessionKey, getOrCreateRing, appendRecall, snapshotRing, hashQueryText, } from './recall-history.js';
|
|
10
|
-
import { appendAuditEvent } from './audit.js';
|
|
11
|
+
import { appendAuditEvent, AUDIT_OPS } from './audit.js';
|
|
11
12
|
// v0.33 / J1 — Module-level per-(tenant, session) recall-history ring map
|
|
12
13
|
// for the HTTP pipeline. Separate from CLI/MCP rings per plan v3 (per-
|
|
13
14
|
// pipeline rings; no IPC). HTTP is the only caller that threads its
|
|
@@ -63,65 +64,7 @@ const PUBLIC_ROUTES = new Set([
|
|
|
63
64
|
function isPublicRoute(method, path) {
|
|
64
65
|
return PUBLIC_ROUTES.has(`${method} ${path}`);
|
|
65
66
|
}
|
|
66
|
-
const VALID_AUDIT_OPS = new Set(
|
|
67
|
-
'remember',
|
|
68
|
-
'recall',
|
|
69
|
-
'promote',
|
|
70
|
-
'supersede',
|
|
71
|
-
'forget',
|
|
72
|
-
'archive_raw',
|
|
73
|
-
'auth_revoke',
|
|
74
|
-
'auth_create', // v1.12.4: emitted by api.authCreate
|
|
75
|
-
'outcome', // v1.11.5: pre-existing drift — emitted today but rejected by old Set
|
|
76
|
-
'consolidate', // v1.11.5: emitted by api.sleep / POST /v1/sleep
|
|
77
|
-
'audit_prune', // v1.12.9: emitted by pruneAuditLog
|
|
78
|
-
'summary_marked_dirty', // v0.30 / E1 — lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS (v1.11.5 CRIT A institutional rule)
|
|
79
|
-
'summary_marked_clean', // v0.30 / E3 — buildDag post-link clean op; lockstep
|
|
80
|
-
'summary_rebuilt', // v0.30 / E3 — sleep-cycle rebuild op; lockstep
|
|
81
|
-
'predict_create', // v0.31 / E2 prediction first-class object — emitted by savePrediction
|
|
82
|
-
'predict_close', // v0.31 / E2 — emitted by closePrediction
|
|
83
|
-
'predict_baserate', // v0.31 / J3 — emitted by computePredictionBaserate
|
|
84
|
-
'recall_autodebias_hint', // v0.32 / J3.2 — emitted by computePlanningFallacyHint on success
|
|
85
|
-
'recall_autodebias_hint_no_class_match', // v0.32 / J3.2 — telemetry: forward-claim, no class scored
|
|
86
|
-
'recall_autodebias_hint_tiebreak', // v0.32 / J3.2 — telemetry: forward-claim, >=2 classes tied
|
|
87
|
-
'recall_anchor_detected_query_repeat', // v0.33 / J1 — emitted by detector on R1 fire
|
|
88
|
-
'recall_anchor_detected_memory_dominance', // v0.33 / J1 — emitted by detector on R2 fire
|
|
89
|
-
'recall_anchor_skipped_no_session', // v0.33 / J1 — telemetry: no sessionId, ring skipped
|
|
90
|
-
'recall_availability_detected', // v1.13.x / J2 - emitted when availability/recency-bias hint fires
|
|
91
|
-
'decision_create', // E2 decision first-class object — emitted by saveDecision
|
|
92
|
-
'decision_supersede', // E2 — emitted by saveDecision when --supersedes resolves to an active decision row
|
|
93
|
-
'decision_close', // E2 — emitted by closeDecision
|
|
94
|
-
'incident_open', // E2 incident first-class object — emitted by saveIncident
|
|
95
|
-
'incident_resolve', // E2 — emitted by resolveIncident (open -> resolved)
|
|
96
|
-
'incident_close', // E2 — emitted by closeIncident (open|resolved -> closed)
|
|
97
|
-
'process_create', // E2 process first-class object — emitted by saveProcess
|
|
98
|
-
'process_supersede', // E2 — emitted by saveProcess on a supersession
|
|
99
|
-
'process_close', // E2 — emitted by closeProcess
|
|
100
|
-
'policy_create', // E2 policy first-class object — emitted by savePolicy
|
|
101
|
-
'policy_supersede', // E2 — emitted by savePolicy on a supersession
|
|
102
|
-
'policy_close', // E2 — emitted by closePolicy
|
|
103
|
-
'skill_create', // E2 skill first-class object — emitted by saveSkill
|
|
104
|
-
'skill_supersede', // E2 — emitted by saveSkill on a supersession
|
|
105
|
-
'skill_close', // E2 — emitted by closeSkill
|
|
106
|
-
'project_brief_create', // E2 project_brief first-class object — emitted by saveProjectBrief
|
|
107
|
-
'project_brief_supersede', // E2 — emitted by saveProjectBrief on a supersession (incl. refresh)
|
|
108
|
-
'project_brief_close', // E2 — emitted by closeProjectBrief
|
|
109
|
-
'customer_note_create', // E2 customer_note first-class object — emitted by saveCustomerNote
|
|
110
|
-
'customer_note_supersede', // E2 — emitted by saveCustomerNote on a supersession
|
|
111
|
-
'customer_note_close', // E2 — emitted by closeCustomerNote
|
|
112
|
-
'mv_rescue', // LC2-E3 — emitted by consolidate() per rescue; lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS
|
|
113
|
-
'reject_value', // AT1 — emitted by `hippo reject`; lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS
|
|
114
|
-
'reject_refusal', // AT1 — emitted when the rejection guard refuses a write; lockstep
|
|
115
|
-
'unreject_value', // AT1 — emitted by `hippo unreject`; lockstep
|
|
116
|
-
'conflict_resolve', // AT1 — emitted by resolveConflict on every resolution path; lockstep
|
|
117
|
-
'half_life_migrate', // Decay default change — emitted by migrateDefaultHalfLife; lockstep with AuditOp union
|
|
118
|
-
'dormant_restore', // Dormant memories — emitted by api.restoreDormant; lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS
|
|
119
|
-
'auth_grant', // EI2: emitted by api.authGrant; lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS
|
|
120
|
-
'auth_ungrant', // EI2: emitted by api.authUngrant; lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS
|
|
121
|
-
'quarantine', // CD5: emitted by recordQuarantine; lockstep with AuditOp union + cli.ts VALID_AUDIT_OPS
|
|
122
|
-
'quarantine_approve', // CD5: emitted by api.quarantineApprove; lockstep
|
|
123
|
-
'quarantine_reject', // CD5: emitted by api.quarantineReject; lockstep
|
|
124
|
-
]);
|
|
67
|
+
const VALID_AUDIT_OPS = new Set(AUDIT_OPS);
|
|
125
68
|
// Cap on GET /v1/audit?limit=. Matches docs/api.md (when written) and is large
|
|
126
69
|
// enough to dump a small deployment's full audit log without paginating, but
|
|
127
70
|
// small enough that a malicious client can't ask for the world.
|
|
@@ -853,7 +796,7 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
853
796
|
assembleExtra.summarizeOlder = summarizeOlder;
|
|
854
797
|
if (scope !== undefined)
|
|
855
798
|
assembleExtra.scope = scope;
|
|
856
|
-
const result = assemble(ctx, assembleMatch.id, assembleExtra);
|
|
799
|
+
const result = assemble(ctx, assembleMatch.id, { ...assembleExtra, cost: assembleCost(assembleMatch.id) });
|
|
857
800
|
recordTokens(ctx, 'http_assemble', { items: result.items.length, tokens: result.tokens, sessionId: assembleMatch.id });
|
|
858
801
|
sendJson(res, 200, result);
|
|
859
802
|
return;
|
|
@@ -896,7 +839,7 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
896
839
|
drillExtra.budget = budget;
|
|
897
840
|
if (depth !== undefined)
|
|
898
841
|
drillExtra.depth = depth;
|
|
899
|
-
const result = drillDown(ctx, drillMatch.id, drillExtra);
|
|
842
|
+
const result = drillDown(ctx, drillMatch.id, { ...drillExtra, cost: drillCost });
|
|
900
843
|
if ('failure' in result) {
|
|
901
844
|
// v1.6.4: leaf id maps to 422 (caller-actionable). Other cases stay
|
|
902
845
|
// as 404 to avoid leaking cross-tenant existence or scope grants.
|
|
@@ -1054,6 +997,7 @@ async function handleRequest(req, res, opts, startedAt, limiter) {
|
|
|
1054
997
|
includeRecent,
|
|
1055
998
|
crossProject,
|
|
1056
999
|
currentProject: resolveProjectIdentity(dirname(resolve(opts.hippoRoot))).name,
|
|
1000
|
+
cost: contextCost('markdown', 'observe'), // clients render; the budget prices the block `hippo context` would print
|
|
1057
1001
|
});
|
|
1058
1002
|
recordTokens(ctx, 'http_context', { items: result.entries.length, tokens: result.tokens });
|
|
1059
1003
|
sendJson(res, 200, result);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { type SessionTurn } from './capture.js';
|
|
2
|
+
import { type MemoryEntry } from './memory.js';
|
|
3
|
+
export declare const SESSION_DIGEST_TAG = "session-digest";
|
|
4
|
+
/** Five-word runs are stock phrases; six in a row is a copied clause. */
|
|
5
|
+
export declare const ECHO_WINDOW = 6;
|
|
6
|
+
/** Five sentences of about 150 chars leave room for the Changed line inside the total cap. */
|
|
7
|
+
export declare const MAX_SENTENCES = 5;
|
|
8
|
+
/** A longer "sentence" in agent text is an unsplit list or pasted output. */
|
|
9
|
+
export declare const MAX_SENTENCE_CHARS = 300;
|
|
10
|
+
/** At about 20 chars per repo path this keeps the Changed line near 50 tokens. */
|
|
11
|
+
export declare const MAX_FILES = 10;
|
|
12
|
+
/** 300 tokens at 4 chars each: 20% of the 1500-token default budget of both context surfaces. */
|
|
13
|
+
export declare const MAX_DIGEST_CHARS = 1200;
|
|
14
|
+
/** Bounds a detached worker's memory; the final message sits at the end, so a tail read loses nothing. */
|
|
15
|
+
export declare const READ_CAP_BYTES: number;
|
|
16
|
+
export interface DigestEdit {
|
|
17
|
+
filePath: string;
|
|
18
|
+
/** Working directory in effect at the call, for relative paths. */
|
|
19
|
+
base: string | null;
|
|
20
|
+
}
|
|
21
|
+
export interface SessionScan {
|
|
22
|
+
turns: SessionTurn[];
|
|
23
|
+
finalText: string;
|
|
24
|
+
/** The first working directory the transcript names: where the session ran. */
|
|
25
|
+
cwd: string | null;
|
|
26
|
+
/** Edits that landed, in call order. */
|
|
27
|
+
edits: DigestEdit[];
|
|
28
|
+
}
|
|
29
|
+
/** One pass over a Claude Code or Codex transcript: the turns capture reads, the closing message, and the edits that landed. */
|
|
30
|
+
export declare function scanSessionTranscript(jsonl: string): SessionScan;
|
|
31
|
+
export declare function readSessionTranscript(transcriptPath: string, log: (message: string) => void): string;
|
|
32
|
+
/** The transcript, read once and scanned, or null with the reason logged. */
|
|
33
|
+
export declare function readSessionScan(transcriptPath: string, log: (message: string) => void): SessionScan | null;
|
|
34
|
+
/** Test-only seam, the scheduler's pattern: lets a test prove a network path never reaches the probe. Null restores it. */
|
|
35
|
+
export declare function __setDigestExistsProbe(probe: ((p: string) => boolean) | null): void;
|
|
36
|
+
/** The store root is realpath'd; transcript paths are not, and a deleted file has no realpath of its own. Null for a network path. */
|
|
37
|
+
export declare function realFsPath(p: string): string | null;
|
|
38
|
+
/** Repo-relative with forward slashes, '' for the root itself, null outside the repo or when the path cannot be resolved. */
|
|
39
|
+
export declare function repoRelative(p: string, repoRoot: string): string | null;
|
|
40
|
+
export declare const USER_SEGMENT: readonly RegExp[];
|
|
41
|
+
/** Sentences of the reply; code spans and "e.g." are held out of the split so their dots never end a sentence. */
|
|
42
|
+
export declare function digestSentences(text: string): string[];
|
|
43
|
+
export declare function sentenceScore(sentence: string): number;
|
|
44
|
+
export interface DigestSources {
|
|
45
|
+
finalText: string;
|
|
46
|
+
/** Text the session already holds: its own prompts, and what hippo injected into it. */
|
|
47
|
+
echoTexts: readonly string[];
|
|
48
|
+
edits: readonly DigestEdit[];
|
|
49
|
+
repoRoot: string;
|
|
50
|
+
}
|
|
51
|
+
export interface DigestDraft {
|
|
52
|
+
content: string;
|
|
53
|
+
sentences: number;
|
|
54
|
+
files: number;
|
|
55
|
+
}
|
|
56
|
+
/** The digest text, or null when nothing survives the filters. Sentences print in reply order. */
|
|
57
|
+
export declare function buildSessionDigest(sources: DigestSources): DigestDraft | null;
|
|
58
|
+
/** Facts extracted from a digest and DAG summaries over one inherit its tag, but they are not the digest itself. */
|
|
59
|
+
export declare function isSessionDigestRow(entry: Pick<MemoryEntry, 'source' | 'tags' | 'extracted_from'>): boolean;
|
|
60
|
+
/** Same session, same row: a second worker for one session updates the digest instead of adding one. */
|
|
61
|
+
export declare function sessionDigestId(tenantId: string, key: string): string;
|
|
62
|
+
export interface SessionDigestOptions {
|
|
63
|
+
/** Session id, or the transcript's basename when the host gives none. */
|
|
64
|
+
key: string;
|
|
65
|
+
tenantId: string;
|
|
66
|
+
}
|
|
67
|
+
export interface DigestOutcome {
|
|
68
|
+
written: boolean;
|
|
69
|
+
reason: string;
|
|
70
|
+
sentences: number;
|
|
71
|
+
files: number;
|
|
72
|
+
}
|
|
73
|
+
export declare function writeSessionDigest(hippoRoot: string, scan: SessionScan, opts: SessionDigestOptions): DigestOutcome;
|
|
74
|
+
export interface DigestRunOptions extends SessionDigestOptions {
|
|
75
|
+
log: (message: string) => void;
|
|
76
|
+
}
|
|
77
|
+
/** Never throws: a digest failure must not block the handoff or the snapshot close. Logs carry no digest text. */
|
|
78
|
+
export declare function recordSessionDigest(hippoRoot: string, scan: SessionScan | null, opts: DigestRunOptions): void;
|
|
79
|
+
//# sourceMappingURL=session-digest.d.ts.map
|