dsh-memory-gate 0.9.0 → 0.10.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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.10.0 - 2026-08-16
4
+
5
+ - Relax the live auto-extractor: memory cues ("记住…", "我偏好…", "always",
6
+ …) now match mid-sentence, not just at the start. The claim is taken from
7
+ the cue to the sentence end, so leading context is dropped. Still the same
8
+ conservative cue phrases and heuristic low-confidence origin.
9
+
3
10
  ## 0.9.0 - 2026-08-16
4
11
 
5
12
  - Similarity dedup (supersede): on write, a claim whose terms overlap an
package/README.md CHANGED
@@ -24,7 +24,7 @@ over time — all auditable, bounded (≤3 claims / 1200 chars by default),
24
24
  no extra model call. (Local SQLite + FTS5 storage; no embeddings, no
25
25
  external memory API.)
26
26
 
27
- 当前版本:`0.3.2`。目标 Harness:`0.1.0-rc.6`,Node.js `>=22.5`。
27
+ 当前版本:`0.9.0`。目标 Harness:`0.1.0-rc.6`,Node.js `>=22.5`。
28
28
 
29
29
  ## v1 能力
30
30
 
@@ -35,6 +35,9 @@ external memory API.)
35
35
  - **使用后学习**:`/memory ok`(或 `feedback <#n> helped`)把当次查询的
36
36
  区分性词项学进触发词(只存词项、不存查询原文),harmful/stale 降低
37
37
  置信度并触发隔离——越用越准,`/memory explain` 全程可审计。
38
+ - **近重复合并**:写入时新记忆与同作用域已有词项重叠 ≥ 60% 时,旧条目
39
+ 自动标 `superseded`、新记忆记录取代关系;`/memory consolidate` 可手动
40
+ 全库合并,避免"相近表达"堆成重复记忆。
38
41
  - **三种运行模式**:`shadow`(只审计零注入)、`assist`(默认,注入 use +
39
42
  标出 verify)、`enforce`(只注入高置信)——按场景切换"怎么用"。
40
43
  - 双通道召回:少量可信全局偏好/约束组成记忆胶囊,其余记忆经词项触发。
@@ -69,7 +72,7 @@ dsh web
69
72
  也可以用 Git 地址安装并锁定版本:
70
73
 
71
74
  ```bash
72
- dsh plugin --profile web add git+https://github.com/GIT121995/dsh-memory-gate.git#v0.3.2
75
+ dsh plugin --profile web add git+https://github.com/GIT121995/dsh-memory-gate.git#v0.9.0
73
76
  ```
74
77
 
75
78
  卸载:
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AAgBD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAUnE"}
1
+ {"version":3,"file":"extractor.d.ts","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,SAAS,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;CACf;AA4BD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CAYnE"}
package/lib/extractor.js CHANGED
@@ -1,30 +1,43 @@
1
1
  import { normalizeContent } from './repository.js';
2
+ /**
3
+ * 记忆 cue 短语:不再锚定句首(句中「下次记得…」「对了,记住…」也能触发),
4
+ * 但仍是保守的固定短语——不做任意「记住」匹配,避免乱存。
5
+ */
2
6
  const MEMORY_CUES = [
3
- /^(?:请)?记住[:,:,\s]*/u,
4
- /^以后(?:请)?[:,:,\s]*/u,
5
- /^请始终[:,:,\s]*/u,
6
- /^我(?:的)?偏好是[:,:,\s]*/u,
7
- /^我喜欢[:,:,\s]*/u,
8
- /^不要再[:,:,\s]*/u,
9
- /^(?:please\s+)?remember(?:\s+that)?[,:\s]*/iu,
10
- /^from now on[,:\s]*/iu,
11
- /^i prefer[,:\s]*/iu,
12
- /^(?:please\s+)?always[,:\s]*/iu,
13
- /^(?:please\s+)?(?:do not|don't|never)[,:\s]*/iu,
7
+ /(?:请)?记住[::,,\s]*/u,
8
+ /以后(?:请)?[::,,\s]*/u,
9
+ /请始终[::,,\s]*/u,
10
+ /我(?:的)?偏好是?[::,,\s]*/u,
11
+ /我喜欢[::,,\s]*/u,
12
+ /不要再[::,,\s]*/u,
13
+ /(?:please\s+)?remember(?:\s+that)?[,:\s]*/iu,
14
+ /from now on[,:\s]*/iu,
15
+ /i prefer[,:\s]*/iu,
16
+ /(?:please\s+)?always[,:\s]*/iu,
17
+ /(?:please\s+)?(?:do not|don't|never)[,:\s]*/iu,
14
18
  ];
19
+ /** 取 cue 之后到句末(或 500 字符)作为 claim 正文,丢弃 cue 之前的前缀。 */
20
+ function takeClaim(afterCue) {
21
+ const end = afterCue.search(/[。!?!?;;.\n]/u);
22
+ const sliced = end === -1 ? afterCue : afterCue.slice(0, end);
23
+ const trimmed = normalizeContent(sliced);
24
+ return trimmed.length > 500 ? trimmed.slice(0, 500) : trimmed;
25
+ }
15
26
  export function extractDurableClaims(text) {
16
27
  const normalized = normalizeContent(text);
17
28
  if (normalized.length < 4 || normalized.length > 1000 || looksLikeQuestion(normalized))
18
29
  return [];
19
- const cue = MEMORY_CUES.find((pattern) => pattern.test(normalized));
20
- if (!cue)
21
- return [];
22
- const stripped = normalizeContent(normalized.replace(cue, ''));
23
- if (stripped.length < 2)
24
- return [];
25
- const content = stripped.length > 500 ? stripped.slice(0, 500) : stripped;
26
- const kind = classify(content, normalized);
27
- return [{ content, kind, tags: ['auto-extracted'] }];
30
+ for (const cue of MEMORY_CUES) {
31
+ const match = cue.exec(normalized);
32
+ if (!match || match.index === undefined)
33
+ continue;
34
+ const content = takeClaim(normalized.slice(match.index + match[0].length));
35
+ if (content.length < 2)
36
+ continue;
37
+ const kind = classify(content, normalized);
38
+ return [{ content, kind, tags: ['auto-extracted'] }];
39
+ }
40
+ return [];
28
41
  }
29
42
  function looksLikeQuestion(value) {
30
43
  return /[??]\s*$/u.test(value);
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAQlD,MAAM,WAAW,GAAG;IAClB,qBAAqB;IACrB,qBAAqB;IACrB,gBAAgB;IAChB,uBAAuB;IACvB,gBAAgB;IAChB,gBAAgB;IAChB,8CAA8C;IAC9C,uBAAuB;IACvB,oBAAoB;IACpB,gCAAgC;IAChC,gDAAgD;CACjD,CAAA;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACzC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,IAAI,IAAI,iBAAiB,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAA;IACjG,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAA;IACnE,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAA;IACnB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAA;IAC9D,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;IACzE,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IAC1C,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAA;AACtD,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,QAAgB;IACjD,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,OAAO,EAAE,CAAC,iBAAiB,EAAE,CAAA;IAC7D,IAAI,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,YAAY,CAAA;IAC/D,IAAI,+CAA+C,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,YAAY,CAAA;IACvF,IAAI,kCAAkC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,WAAW,CAAA;IACzE,IAAI,0BAA0B,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IAC/D,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../src/extractor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAQlD;;;GAGG;AACH,MAAM,WAAW,GAAG;IAClB,oBAAoB;IACpB,oBAAoB;IACpB,eAAe;IACf,uBAAuB;IACvB,eAAe;IACf,eAAe;IACf,6CAA6C;IAC7C,sBAAsB;IACtB,mBAAmB;IACnB,+BAA+B;IAC/B,+CAA+C;CAChD,CAAA;AAED,qDAAqD;AACrD,SAAS,SAAS,CAAC,QAAgB;IACjC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;IAC5C,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IAC7D,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IACxC,OAAO,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AAC/D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACzC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,IAAI,IAAI,iBAAiB,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAA;IACjG,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QAClC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,SAAQ;QACjD,MAAM,OAAO,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;QAC1E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,SAAQ;QAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;QAC1C,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;AAChC,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,QAAgB;IACjD,MAAM,QAAQ,GAAG,GAAG,QAAQ,IAAI,OAAO,EAAE,CAAC,iBAAiB,EAAE,CAAA;IAC7D,IAAI,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,YAAY,CAAA;IAC/D,IAAI,+CAA+C,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,YAAY,CAAA;IACvF,IAAI,kCAAkC,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,WAAW,CAAA;IACzE,IAAI,0BAA0B,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAA;IAC/D,OAAO,MAAM,CAAA;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-memory-gate",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Retrieved ≠ injected: CBDC-gated memory for DeepSeek Harness — decides how memory is USED (use/verify/ignore decisions, feedback learning, full audit); local SQLite + FTS5, bounded, no extra model call",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -45,7 +45,7 @@
45
45
  "build": "tsc -p tsconfig.build.json",
46
46
  "typecheck": "tsc -p tsconfig.json --noEmit",
47
47
  "check": "npm run typecheck && npm run build",
48
- "test": "npm run build && node --test tests/text.test.mjs tests/repository.test.mjs tests/service.test.mjs tests/mine.test.mjs backtest/measure.test.mjs backtest/trajectory.test.mjs",
48
+ "test": "npm run build && node --test tests/text.test.mjs tests/repository.test.mjs tests/service.test.mjs tests/mine.test.mjs tests/extractor.test.mjs backtest/measure.test.mjs backtest/trajectory.test.mjs",
49
49
  "backtest": "npm run build && node backtest/run.mjs",
50
50
  "result": "npm run build && node backtest/result.mjs",
51
51
  "observe": "npm run build && node backtest/observe.mjs",