wotann 0.5.42 → 0.5.43
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.
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* `store.search()`.
|
|
31
31
|
*/
|
|
32
32
|
import type { MemoryEntry, MemoryStore } from "./store.js";
|
|
33
|
+
import { type InjectionMatch } from "./injection-scanner.js";
|
|
33
34
|
export interface WorkingTurn {
|
|
34
35
|
readonly id: string;
|
|
35
36
|
readonly role: "user" | "assistant" | "system";
|
|
@@ -62,6 +63,17 @@ export interface MultiTierMemoryOptions {
|
|
|
62
63
|
/** Working buffer size (default 50, mem0 default). */
|
|
63
64
|
readonly workingCapacity?: number;
|
|
64
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Thrown by `recordTurn` when the input content matches a prompt-injection
|
|
68
|
+
* pattern. The caller decides whether to log, alert, or re-prompt the user.
|
|
69
|
+
* Carries the list of matched patterns so a higher layer can show "which
|
|
70
|
+
* rule fired" — silent rejection would be the worse failure mode (QB#6).
|
|
71
|
+
*/
|
|
72
|
+
export declare class MemoryInjectionRejectedError extends Error {
|
|
73
|
+
readonly turnId: string;
|
|
74
|
+
readonly matches: readonly InjectionMatch[];
|
|
75
|
+
constructor(turnId: string, matches: readonly InjectionMatch[]);
|
|
76
|
+
}
|
|
65
77
|
/**
|
|
66
78
|
* Multi-tier memory for ONE session. Keeps a per-instance working
|
|
67
79
|
* buffer; episodic + semantic queries delegate to the underlying
|
|
@@ -74,7 +86,20 @@ export declare class MultiTierMemory {
|
|
|
74
86
|
/** Internal mutable buffer; never exposed by reference. */
|
|
75
87
|
private working;
|
|
76
88
|
constructor(store: MemoryStore, sessionId: string, options?: MultiTierMemoryOptions);
|
|
77
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Add a turn to the working window. Evicts oldest when capacity exceeded.
|
|
91
|
+
*
|
|
92
|
+
* Runs `scanForInjection` over the turn's content before admitting it
|
|
93
|
+
* into memory. Working memory is replayed on every prompt, so a
|
|
94
|
+
* compromised entry would re-inject the malicious instructions every
|
|
95
|
+
* session — gate the write boundary, not the read boundary. On a hit,
|
|
96
|
+
* the turn is REJECTED (not silently dropped): the caller learns the
|
|
97
|
+
* pattern that fired so a higher layer can surface the gap.
|
|
98
|
+
*
|
|
99
|
+
* This closes the V9-injection-scanner zombie wire flagged in the
|
|
100
|
+
* 2026-05-15 audit (commit e26286c claimed wire; only limits.ts was
|
|
101
|
+
* actually wired).
|
|
102
|
+
*/
|
|
78
103
|
recordTurn(turn: WorkingTurn): void;
|
|
79
104
|
/** Snapshot of the working window (newest last). Always a fresh array. */
|
|
80
105
|
getWorking(): readonly WorkingTurn[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-tier.d.ts","sourceRoot":"","sources":["../../src/memory/multi-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"multi-tier.d.ts","sourceRoot":"","sources":["../../src/memory/multi-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI/E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IACpC,sDAAsD;IACtD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,6BAA6B;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,sDAAsD;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED;;;;;GAKG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;IACrD,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,OAAO,EAAE,SAAS,cAAc,EAAE,CAAC;gBACvC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,cAAc,EAAE;CAS/D;AAOD;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,2DAA2D;IAC3D,OAAO,CAAC,OAAO,CAAgB;gBAEnB,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B;IAUvF;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAYnC,0EAA0E;IAC1E,UAAU,IAAI,SAAS,WAAW,EAAE;IAIpC;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,oBAAoB;CAqC/E"}
|
|
@@ -29,6 +29,24 @@
|
|
|
29
29
|
* - Bar #11 / #14: no duplicate FTS — semantic search delegates to
|
|
30
30
|
* `store.search()`.
|
|
31
31
|
*/
|
|
32
|
+
import { scanForInjection } from "./injection-scanner.js";
|
|
33
|
+
/**
|
|
34
|
+
* Thrown by `recordTurn` when the input content matches a prompt-injection
|
|
35
|
+
* pattern. The caller decides whether to log, alert, or re-prompt the user.
|
|
36
|
+
* Carries the list of matched patterns so a higher layer can show "which
|
|
37
|
+
* rule fired" — silent rejection would be the worse failure mode (QB#6).
|
|
38
|
+
*/
|
|
39
|
+
export class MemoryInjectionRejectedError extends Error {
|
|
40
|
+
turnId;
|
|
41
|
+
matches;
|
|
42
|
+
constructor(turnId, matches) {
|
|
43
|
+
const ids = matches.map((m) => m.id);
|
|
44
|
+
super(`Memory write rejected for turn ${turnId}: matched ${matches.length} injection pattern(s) (${ids.slice(0, 3).join(", ")}${ids.length > 3 ? ", …" : ""}). The turn is NOT stored.`);
|
|
45
|
+
this.name = "MemoryInjectionRejectedError";
|
|
46
|
+
this.turnId = turnId;
|
|
47
|
+
this.matches = matches;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
32
50
|
// ── Implementation ────────────────────────────────────────────
|
|
33
51
|
const DEFAULT_WORKING_CAPACITY = 50;
|
|
34
52
|
const DEFAULT_PER_LAYER = 5;
|
|
@@ -52,8 +70,25 @@ export class MultiTierMemory {
|
|
|
52
70
|
this.capacity = Math.max(1, options.workingCapacity ?? DEFAULT_WORKING_CAPACITY);
|
|
53
71
|
this.working = [];
|
|
54
72
|
}
|
|
55
|
-
/**
|
|
73
|
+
/**
|
|
74
|
+
* Add a turn to the working window. Evicts oldest when capacity exceeded.
|
|
75
|
+
*
|
|
76
|
+
* Runs `scanForInjection` over the turn's content before admitting it
|
|
77
|
+
* into memory. Working memory is replayed on every prompt, so a
|
|
78
|
+
* compromised entry would re-inject the malicious instructions every
|
|
79
|
+
* session — gate the write boundary, not the read boundary. On a hit,
|
|
80
|
+
* the turn is REJECTED (not silently dropped): the caller learns the
|
|
81
|
+
* pattern that fired so a higher layer can surface the gap.
|
|
82
|
+
*
|
|
83
|
+
* This closes the V9-injection-scanner zombie wire flagged in the
|
|
84
|
+
* 2026-05-15 audit (commit e26286c claimed wire; only limits.ts was
|
|
85
|
+
* actually wired).
|
|
86
|
+
*/
|
|
56
87
|
recordTurn(turn) {
|
|
88
|
+
const scan = scanForInjection(turn.content);
|
|
89
|
+
if (!scan.ok) {
|
|
90
|
+
throw new MemoryInjectionRejectedError(turn.id, scan.matches);
|
|
91
|
+
}
|
|
57
92
|
// Push then trim — single allocation when within capacity.
|
|
58
93
|
this.working.push(turn);
|
|
59
94
|
if (this.working.length > this.capacity) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multi-tier.js","sourceRoot":"","sources":["../../src/memory/multi-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;
|
|
1
|
+
{"version":3,"file":"multi-tier.js","sourceRoot":"","sources":["../../src/memory/multi-tier.ts"],"names":[],"mappings":"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"}
|