hippo-memory 1.56.0 → 1.58.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 +11 -0
- package/dist/agent-memories/claude-code.js +1 -1
- package/dist/agent-memories/gemini.js +1 -1
- package/dist/api-errors.d.ts +27 -0
- package/dist/api-errors.js +37 -0
- package/dist/api.d.ts +21 -14
- package/dist/api.js +97 -71
- package/dist/audit.d.ts +4 -0
- package/dist/audit.js +11 -0
- package/dist/autolearn.d.ts +1 -1
- package/dist/autolearn.js +7 -5
- package/dist/capture-contract.d.ts +47 -0
- package/dist/capture-contract.js +49 -0
- package/dist/capture-error.js +2 -1
- package/dist/capture.d.ts +0 -13
- package/dist/capture.js +5 -66
- package/dist/card-detail.d.ts +1 -1
- package/dist/card-detail.js +1 -1
- package/dist/cli/shared.d.ts +137 -0
- package/dist/cli/shared.js +834 -0
- package/dist/cli/sleep.d.ts +10 -0
- package/dist/cli/sleep.js +171 -0
- package/dist/cli.d.ts +0 -7
- package/dist/cli.js +322 -1827
- package/dist/client.js +9 -0
- package/dist/codex-patch.js +1 -1
- package/dist/compaction-record.d.ts +1 -1
- package/dist/compaction-record.js +3 -2
- package/dist/config.d.ts +5 -0
- package/dist/config.js +17 -0
- package/dist/connectors/github/dlq.js +5 -2
- package/dist/connectors/github/octokit-client.js +4 -2
- package/dist/connectors/github/webhook.d.ts +19 -0
- package/dist/connectors/github/webhook.js +313 -0
- package/dist/connectors/slack/dlq.js +6 -2
- package/dist/connectors/slack/web-client.js +7 -5
- package/dist/connectors/slack/webhook.d.ts +22 -0
- package/dist/connectors/slack/webhook.js +203 -0
- package/dist/consolidate.d.ts +10 -0
- package/dist/consolidate.js +38 -35
- package/dist/context-auto.d.ts +3 -0
- package/dist/context-auto.js +34 -0
- package/dist/customer-notes.js +16 -14
- package/dist/dag.js +3 -2
- package/dist/dashboard.js +3 -2
- package/dist/db.d.ts +12 -0
- package/dist/db.js +62 -1
- package/dist/decisions.js +11 -9
- package/dist/doctor.js +5 -0
- package/dist/embedding-provider.js +3 -3
- package/dist/embeddings.d.ts +4 -4
- package/dist/embeddings.js +72 -16
- package/dist/eval-stats.d.ts +58 -0
- package/dist/eval-stats.js +111 -0
- package/dist/extract.js +3 -2
- package/dist/goals.d.ts +49 -25
- package/dist/goals.js +39 -22
- package/dist/graph-extract.js +1 -1
- package/dist/graph-recall.d.ts +1 -1
- package/dist/graph-recall.js +1 -1
- package/dist/graph.js +1 -1
- package/dist/hooks.d.ts +1 -3
- package/dist/hooks.js +2 -4
- package/dist/http-retry.d.ts +21 -0
- package/dist/http-retry.js +50 -0
- package/dist/http-util.d.ts +39 -0
- package/dist/http-util.js +56 -0
- package/dist/importers.d.ts +2 -0
- package/dist/importers.js +16 -5
- package/dist/incidents.js +13 -11
- package/dist/index.d.ts +5 -2
- package/dist/index.js +5 -2
- package/dist/judgment.js +10 -17
- package/dist/log.d.ts +25 -0
- package/dist/log.js +48 -0
- package/dist/mcp/server.js +224 -308
- package/dist/mcp/tool-args.d.ts +21 -0
- package/dist/mcp/tool-args.js +80 -0
- package/dist/memory.d.ts +19 -0
- package/dist/memory.js +41 -2
- package/dist/overlap-index.d.ts +7 -0
- package/dist/overlap-index.js +38 -0
- package/dist/pilot-arm.d.ts +9 -0
- package/dist/pilot-arm.js +47 -0
- package/dist/policies.js +14 -12
- package/dist/predictions.js +11 -9
- package/dist/processes.js +16 -14
- package/dist/project-briefs.js +19 -16
- package/dist/project-identity.d.ts +1 -1
- package/dist/project-identity.js +25 -1
- package/dist/prompt-recall.js +1 -1
- package/dist/raw-archive.js +7 -6
- package/dist/recall-history.d.ts +5 -0
- package/dist/recall-history.js +9 -0
- package/dist/recall-pipeline.d.ts +101 -0
- package/dist/recall-pipeline.js +313 -0
- package/dist/recall-scope.d.ts +24 -1
- package/dist/recall-scope.js +29 -2
- package/dist/refine-llm.js +3 -2
- package/dist/reject-flow.js +6 -9
- package/dist/rejection.d.ts +2 -1
- package/dist/rejection.js +2 -1
- package/dist/search.d.ts +0 -20
- package/dist/search.js +16 -51
- package/dist/secret-detect.d.ts +13 -1
- package/dist/secret-detect.js +33 -1
- package/dist/server.d.ts +3 -1
- package/dist/server.js +1854 -2566
- package/dist/session-digest.js +2 -1
- package/dist/shared.js +7 -6
- package/dist/skills.js +17 -15
- package/dist/store-cards.d.ts +53 -0
- package/dist/store-cards.js +512 -0
- package/dist/store.d.ts +2 -89
- package/dist/store.js +10 -566
- package/dist/tenant.d.ts +22 -0
- package/dist/tenant.js +26 -0
- package/dist/token-ledger.d.ts +4 -2
- package/dist/token-ledger.js +2 -2
- package/dist/tokenize.d.ts +2 -0
- package/dist/tokenize.js +8 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +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/connectors/slack/ratelimit.d.ts +0 -9
- package/dist/connectors/slack/ratelimit.js +0 -18
package/README.md
CHANGED
|
@@ -559,6 +559,17 @@ are not recorded yet. It holds ids, hashes, counts and reasons only, never promp
|
|
|
559
559
|
text; the prompt hash is unsalted, so a very short prompt can be guessed. A ledger failure prints one stderr line and never changes what the hook prints. Rows
|
|
560
560
|
older than 90 days are pruned; at a heavy 300 prompts a day that is about 190 MB per store.
|
|
561
561
|
|
|
562
|
+
**Run a pilot with a holdout group.** Set `{"pilot":{"holdoutRateBp":2000}}` in `.hippo/config.json`
|
|
563
|
+
to hold back memories from about 20% of sessions. The rate is in basis points, 0 to 10000, and 0
|
|
564
|
+
is off (the default). The setting is read from the store the token ledger writes to. A session
|
|
565
|
+
lands in its arm by a hash of its id, and the first hook call writes one row to the token ledger.
|
|
566
|
+
A holdout session gets no memories from the per-prompt hook, the SessionStart hook or compact-resume.
|
|
567
|
+
The agent's own `hippo context` pull is gated in Claude Code only, so a Codex holdout session still
|
|
568
|
+
gets memories from it. Capture still runs. `hippo recall`, the HTTP API and the MCP tools are not gated
|
|
569
|
+
and write no arm row. Agents are told to call the MCP context tool at session start, and those calls
|
|
570
|
+
are not recorded. Set the rate to 0 only after the pilot window closes, because 0 ends every holdout at once.
|
|
571
|
+
`hippo doctor` shows the pilot when it is on.
|
|
572
|
+
|
|
562
573
|
---
|
|
563
574
|
|
|
564
575
|
### Outcome feedback
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { realpathOrResolve } from '../project-identity.js';
|
|
5
|
-
import { isStringValue } from '../capture.js';
|
|
5
|
+
import { isStringValue } from '../capture-contract.js';
|
|
6
6
|
import { isJsonObject } from '../hooks.js';
|
|
7
7
|
import { expandHome, frontmatterField, itemTime, readTextFile, splitFrontmatter } from './files.js';
|
|
8
8
|
import { markdownNotes, readFolderStore, uniqueFolders } from './folder-store.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Gemini CLI: the "Gemini Added Memories" section of GEMINI.md, and the auto-memory folder that projects.json names.
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { isStringValue } from '../capture.js';
|
|
4
|
+
import { isStringValue } from '../capture-contract.js';
|
|
5
5
|
import { isJsonObject } from '../hooks.js';
|
|
6
6
|
import { readTextFile, splitFrontmatter } from './files.js';
|
|
7
7
|
import { markdownNotes, readFolderStore } from './folder-store.js';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Errors whose HTTP status is part of the API contract; the server maps by class, so message text can change freely. */
|
|
2
|
+
export type ApiErrorStatus = 400 | 403 | 404 | 409;
|
|
3
|
+
/** Base class: an error the caller caused, carrying the status the HTTP layer answers with. */
|
|
4
|
+
export declare abstract class ApiError extends Error {
|
|
5
|
+
abstract readonly status: ApiErrorStatus;
|
|
6
|
+
}
|
|
7
|
+
/** The request cannot be applied as given: bad input, or a state this route reports as 400. */
|
|
8
|
+
export declare class BadRequestError extends ApiError {
|
|
9
|
+
readonly status = 400;
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
12
|
+
/** The actor's role or identity does not allow the operation. */
|
|
13
|
+
export declare class ForbiddenError extends ApiError {
|
|
14
|
+
readonly status = 403;
|
|
15
|
+
constructor(message: string);
|
|
16
|
+
}
|
|
17
|
+
/** The named row does not exist for this tenant. */
|
|
18
|
+
export declare class NotFoundError extends ApiError {
|
|
19
|
+
readonly status = 404;
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
/** The row exists but its current state forbids the change (already superseded, closed, or decided). */
|
|
23
|
+
export declare class ConflictError extends ApiError {
|
|
24
|
+
readonly status = 409;
|
|
25
|
+
constructor(message: string);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=api-errors.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Errors whose HTTP status is part of the API contract; the server maps by class, so message text can change freely. */
|
|
2
|
+
/** Base class: an error the caller caused, carrying the status the HTTP layer answers with. */
|
|
3
|
+
export class ApiError extends Error {
|
|
4
|
+
}
|
|
5
|
+
/** The request cannot be applied as given: bad input, or a state this route reports as 400. */
|
|
6
|
+
export class BadRequestError extends ApiError {
|
|
7
|
+
status = 400;
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = 'BadRequestError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** The actor's role or identity does not allow the operation. */
|
|
14
|
+
export class ForbiddenError extends ApiError {
|
|
15
|
+
status = 403;
|
|
16
|
+
constructor(message) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = 'ForbiddenError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/** The named row does not exist for this tenant. */
|
|
22
|
+
export class NotFoundError extends ApiError {
|
|
23
|
+
status = 404;
|
|
24
|
+
constructor(message) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = 'NotFoundError';
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** The row exists but its current state forbids the change (already superseded, closed, or decided). */
|
|
30
|
+
export class ConflictError extends ApiError {
|
|
31
|
+
status = 409;
|
|
32
|
+
constructor(message) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = 'ConflictError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=api-errors.js.map
|
package/dist/api.d.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* in exactly one place.
|
|
8
8
|
*/
|
|
9
9
|
import { type DatabaseSyncLike } from './db.js';
|
|
10
|
+
import { BadRequestError } from './api-errors.js';
|
|
11
|
+
export { ApiError, BadRequestError, ConflictError, ForbiddenError, NotFoundError } from './api-errors.js';
|
|
10
12
|
import { deleteEntry, loadAllEntries, type TaskSnapshot, type SessionEvent } from './store.js';
|
|
11
13
|
import { type RejectedValueRow } from './rejection.js';
|
|
12
14
|
import { type DormantMemory, type ListDormantOpts } from './dormant.js';
|
|
@@ -19,7 +21,7 @@ import { auditMemories, type AuditEvent, type AuditOp } from './audit.js';
|
|
|
19
21
|
import { autoShare } from './shared.js';
|
|
20
22
|
import type { DeliveryObserver } from './delivery-recorder.js';
|
|
21
23
|
import { type ApiKeyListItem } from './auth.js';
|
|
22
|
-
import { type RerankStep } from './search.js';
|
|
24
|
+
import { type RerankStep, type SearchResult } from './search.js';
|
|
23
25
|
import { consolidate } from './consolidate.js';
|
|
24
26
|
import { loadConfig } from './config.js';
|
|
25
27
|
import { deduplicateStore } from './dedupe.js';
|
|
@@ -77,14 +79,10 @@ export declare function adminActor(subject: string): Actor;
|
|
|
77
79
|
* full-store fallback (codex v1.7.0 diff-pass P1). Validated upfront
|
|
78
80
|
* so the contract holds.
|
|
79
81
|
*/
|
|
80
|
-
export declare class RecallContractError extends
|
|
82
|
+
export declare class RecallContractError extends BadRequestError {
|
|
81
83
|
readonly code: 'fresh_tail_requires_session_id' | 'invalid_scorer_window';
|
|
82
84
|
constructor(code: 'fresh_tail_requires_session_id' | 'invalid_scorer_window', message: string);
|
|
83
85
|
}
|
|
84
|
-
/** The actor's role or identity does not allow the operation. HTTP maps it to 403. */
|
|
85
|
-
export declare class ForbiddenError extends Error {
|
|
86
|
-
constructor(message: string);
|
|
87
|
-
}
|
|
88
86
|
import { isPrivateScope, passesScopeFilterForRecall } from './recall-scope.js';
|
|
89
87
|
export { isPrivateScope, passesScopeFilterForRecall };
|
|
90
88
|
export { passesCliRecallScopeFilter, ScopeForbiddenError } from './recall-scope.js';
|
|
@@ -92,9 +90,8 @@ export type { TokenSummary, TokenSurface, TokenSurfaceSummary } from './token-le
|
|
|
92
90
|
export type { FailureSummary } from './failure-log.js';
|
|
93
91
|
export { classifyOriginProject } from './project-identity.js';
|
|
94
92
|
/**
|
|
95
|
-
* v39 S4: the secret half of the ambient policy on its own, for
|
|
96
|
-
*
|
|
97
|
-
* exact-match). A flagged row is only admitted inside its owning project;
|
|
93
|
+
* v39 S4: the secret half of the ambient policy on its own, for callers
|
|
94
|
+
* that apply their own scope rule. A flagged row is only admitted inside its owning project;
|
|
98
95
|
* flagged rows with no project origin never ambient-inject.
|
|
99
96
|
*/
|
|
100
97
|
export declare function ambientSecretAdmit(e: MemoryEntry, currentProjectName: string): boolean;
|
|
@@ -126,6 +123,8 @@ export interface RememberResult {
|
|
|
126
123
|
quarantined?: {
|
|
127
124
|
reason: string;
|
|
128
125
|
};
|
|
126
|
+
/** Set only when the content held secret material: untrusted text had it redacted, typed text was stored as sent. */
|
|
127
|
+
warnings?: string[];
|
|
129
128
|
}
|
|
130
129
|
export declare function remember(ctx: Context, opts: RememberOpts): RememberResult;
|
|
131
130
|
export interface RecallOpts {
|
|
@@ -270,16 +269,22 @@ export interface RecallOpts {
|
|
|
270
269
|
* Mirrors `suppressAvailabilityHint`'s pattern: callers that run their OWN
|
|
271
270
|
* tracing over a DIFFERENT result set must suppress api.recall's copy so
|
|
272
271
|
* the training corpus doesn't get a trace mislabeled as 'api' pipeline
|
|
273
|
-
* when the caller's actual user-visible results came from elsewhere.
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
* tracing is the reserved 'mcp' pipeline, a follow-up). HTTP / direct SDK
|
|
277
|
-
* callers leave this unset and get the trace.
|
|
272
|
+
* when the caller's actual user-visible results came from elsewhere. Under
|
|
273
|
+
* `showRanked` it also drops the 'mcp' trace of the shown list. HTTP /
|
|
274
|
+
* direct SDK callers leave this unset and get the trace.
|
|
278
275
|
*/
|
|
279
276
|
suppressRecallTrace?: boolean;
|
|
280
277
|
/** Set only by the MCP recall tool, which ranks with its own scorer and drops copies from its own final list: this call
|
|
281
278
|
* then keeps a memory that a merged row in the same result holds word for word. Other callers leave it unset. */
|
|
282
279
|
keepHeldCopies?: boolean;
|
|
280
|
+
/** MCP recall only: `retrieve` ranks the whole scoped store and strengthens and traces (pipeline 'mcp') just the ids this returns; `results` stays the window band. */
|
|
281
|
+
showRanked?: (ranking: StoreRanking, result: RecallResult) => readonly string[];
|
|
282
|
+
}
|
|
283
|
+
/** `ranked`: every scored row, best first, goal boost applied, entries as loaded; `pool`: the store after the scope filter. */
|
|
284
|
+
export interface StoreRanking {
|
|
285
|
+
ranked: SearchResult[];
|
|
286
|
+
pool: MemoryEntry[];
|
|
287
|
+
droppedByScope: number;
|
|
283
288
|
}
|
|
284
289
|
export interface ContinuityBlock {
|
|
285
290
|
activeSnapshot: TaskSnapshot | null;
|
|
@@ -946,6 +951,8 @@ export interface ContextOpts {
|
|
|
946
951
|
limit?: number;
|
|
947
952
|
pinnedOnly?: boolean;
|
|
948
953
|
scope?: string;
|
|
954
|
+
/** Envelope scope to match exactly, as in `recall`: admits that scope even when private, after the actor's scope check. */
|
|
955
|
+
exactScope?: string;
|
|
949
956
|
/** With `pinnedOnly`, also inject the N most recent writes that pass the
|
|
950
957
|
* quality floor (`isContentWorthStoring`, DF3). Filtering happens BEFORE
|
|
951
958
|
* the take-N, so a caller asking for 5 gets 5 qualifying entries rather
|