@modusensus/dsh-mneme 0.8.2 → 0.8.4
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/LICENSE +21 -21
- package/README.md +718 -633
- package/bin/cli.mjs +0 -0
- package/bin/dsh-mneme-mcp.mjs +502 -0
- package/cordis.patch.yml +21 -21
- package/lib/api-standalone.js +495 -316
- package/lib/api.js +1382 -1316
- package/lib/bootstrap.js +211 -0
- package/lib/client.js +4475 -4362
- package/lib/commands.js +95 -95
- package/lib/config.js +533 -500
- package/lib/dream/clustering.js +118 -118
- package/lib/dream/decisions.js +658 -658
- package/lib/dream/narratives.js +44 -0
- package/lib/dream/sleep.js +700 -700
- package/lib/dream.js +1319 -1216
- package/lib/embedding.js +177 -177
- package/lib/entities/extractor.js +249 -249
- package/lib/heat.js +142 -136
- package/lib/hot-memory.js +46 -46
- package/lib/index.js +515 -513
- package/lib/inject.js +299 -253
- package/lib/lang.js +202 -179
- package/lib/local-embedder.js +320 -308
- package/lib/mirror.js +198 -198
- package/lib/quality-filter.js +126 -126
- package/lib/recall-stats.js +103 -0
- package/lib/reranker.js +269 -260
- package/lib/runtime/adopt.js +176 -176
- package/lib/runtime/closure.js +172 -172
- package/lib/runtime/download.js +247 -247
- package/lib/runtime/layout.js +235 -235
- package/lib/runtime/loader.js +249 -249
- package/lib/runtime/model-fetch.js +361 -0
- package/lib/runtime/provision.js +237 -237
- package/lib/runtime/tarball.js +130 -130
- package/lib/runtime/verify.js +191 -191
- package/lib/scope.js +118 -118
- package/lib/search/adaptive.js +22 -22
- package/lib/search/bm25.js +96 -96
- package/lib/service.js +2171 -2071
- package/lib/settings.js +430 -419
- package/lib/store.js +2448 -2367
- package/lib/summarize.js +575 -449
- package/lib/tools.js +574 -574
- package/lib/vector-index.js +110 -110
- package/lib/version-check.js +122 -122
- package/package.json +109 -108
- package/runtime-manifest.json +596 -596
- package/scripts/benchmark-embed.js +201 -201
- package/scripts/benchmark-recall.js +199 -199
- package/scripts/benchmark-rerank.js +166 -166
- package/scripts/build-runtime-manifest.mjs +217 -217
- package/scripts/check-sync.js +42 -42
- package/scripts/e2e-dsh.js +220 -220
- package/scripts/mneme-runtime.mjs +277 -277
- package/scripts/stress-dsh.js +255 -255
- package/scripts/sync-lib.js +47 -47
- package/scripts/sync-test-badge.mjs +61 -61
- package/src/api-standalone.js +495 -316
- package/src/api.js +1382 -1316
- package/src/bootstrap.js +211 -0
- package/src/commands.js +95 -95
- package/src/config.js +533 -500
- package/src/dream/clustering.js +118 -118
- package/src/dream/decisions.js +658 -658
- package/src/dream/narratives.js +44 -0
- package/src/dream/sleep.js +700 -700
- package/src/dream.js +1319 -1216
- package/src/embedding.js +177 -177
- package/src/entities/extractor.js +249 -249
- package/src/heat.js +142 -136
- package/src/hot-memory.js +46 -46
- package/src/index.js +515 -513
- package/src/inject.js +299 -253
- package/src/lang.js +202 -179
- package/src/local-embedder.js +320 -308
- package/src/mirror.js +198 -198
- package/src/quality-filter.js +126 -126
- package/src/recall-stats.js +103 -0
- package/src/reranker.js +269 -260
- package/src/runtime/adopt.js +176 -176
- package/src/runtime/closure.js +172 -172
- package/src/runtime/download.js +247 -247
- package/src/runtime/layout.js +235 -235
- package/src/runtime/loader.js +249 -249
- package/src/runtime/model-fetch.js +361 -0
- package/src/runtime/provision.js +237 -237
- package/src/runtime/tarball.js +130 -130
- package/src/runtime/verify.js +191 -191
- package/src/scope.js +118 -118
- package/src/search/adaptive.js +22 -22
- package/src/search/bm25.js +96 -96
- package/src/service.js +2171 -2071
- package/src/settings.js +430 -419
- package/src/store.js +2448 -2367
- package/src/summarize.js +575 -449
- package/src/tools.js +574 -574
- package/src/vector-index.js +110 -110
- package/src/version-check.js +122 -122
- package/test/api-routes-gaps.test.js +218 -218
- package/test/api.test.js +1578 -1481
- package/test/audit.test.js +448 -448
- package/test/benchmark.test.js +94 -94
- package/test/bootstrap.test.js +220 -0
- package/test/client.test.js +799 -736
- package/test/clustering.test.js +100 -100
- package/test/commands.test.js +106 -106
- package/test/config.test.js +66 -66
- package/test/conflict-freeze.test.js +300 -300
- package/test/dream-archive-guardrail.test.js +116 -116
- package/test/dream-candidate-hybrid.test.js +281 -281
- package/test/dream-coverage-degrade.test.js +86 -86
- package/test/dream.test.js +1257 -1254
- package/test/embedding-ready.test.js +196 -196
- package/test/entities.test.js +547 -547
- package/test/entity-recall.test.js +179 -0
- package/test/epistemic.test.js +298 -298
- package/test/fnew-0112.test.js +311 -311
- package/test/fnew-03.test.js +422 -422
- package/test/graph-api.test.js +175 -175
- package/test/heat.test.js +175 -148
- package/test/helpers/dream-mock.js +82 -82
- package/test/helpers/peer-worker.mjs +25 -25
- package/test/helpers/runtime-source.js +60 -60
- package/test/helpers/tar-builder.js +80 -80
- package/test/hot-memory.test.js +145 -145
- package/test/inject-content-cap.test.js +89 -0
- package/test/inject-first-round-bm25.test.js +89 -89
- package/test/inject-heat.test.js +61 -0
- package/test/inject-rotation.test.js +161 -0
- package/test/inject.test.js +249 -249
- package/test/lang.test.js +87 -87
- package/test/lib-smoke.test.js +96 -96
- package/test/llm-audit.test.js +309 -309
- package/test/llm-message-source.test.js +177 -177
- package/test/local-embedder.test.js +249 -229
- package/test/mcp-stdio.test.js +385 -0
- package/test/mirror-dirty.test.js +424 -424
- package/test/mirror-edit-digest.test.js +187 -187
- package/test/mirror-generation.test.js +499 -499
- package/test/mirror.test.js +249 -249
- package/test/narrative-bars.test.js +162 -0
- package/test/peer-blockers.test.js +193 -193
- package/test/policy-epoch.test.js +259 -259
- package/test/quality-filter.test.js +186 -186
- package/test/reasoning-effort.test.js +746 -746
- package/test/recall-evals.test.js +235 -235
- package/test/recall-layer.test.js +326 -326
- package/test/recall-stats.test.js +117 -0
- package/test/receipt-chain.test.js +451 -451
- package/test/reflection.test.js +226 -226
- package/test/reindex-backfill.test.js +62 -62
- package/test/reranker-single-logit.test.js +73 -73
- package/test/reranker.test.js +197 -197
- package/test/resident-status.test.js +83 -0
- package/test/runtime-adopt.test.js +206 -206
- package/test/runtime-cli.test.js +89 -89
- package/test/runtime-closure.test.js +193 -193
- package/test/runtime-download.test.js +302 -302
- package/test/runtime-layout.test.js +163 -163
- package/test/runtime-loader.test.js +237 -237
- package/test/runtime-manifest.test.js +158 -158
- package/test/runtime-model-fetch.test.js +348 -0
- package/test/runtime-provision.test.js +101 -101
- package/test/runtime-tarball.test.js +81 -81
- package/test/runtime-verify.test.js +214 -214
- package/test/scope-candidates.test.js +239 -239
- package/test/scope-explicit.test.js +452 -452
- package/test/scope-retrieval.test.js +197 -197
- package/test/scope-storage.test.js +255 -255
- package/test/scope-strict.test.js +231 -231
- package/test/search-fusion.test.js +90 -90
- package/test/semantic.test.js +124 -124
- package/test/service-search.test.js +174 -174
- package/test/service.test.js +405 -405
- package/test/settings.test.js +261 -261
- package/test/skip-invalid-restore.test.js +262 -262
- package/test/sleep-action-set.test.js +422 -422
- package/test/sleep-heat.test.js +126 -125
- package/test/sleep-scheduler-rearm.test.js +89 -89
- package/test/sleep.test.js +373 -373
- package/test/standalone-api.test.js +544 -359
- package/test/store-vector-cache.test.js +98 -98
- package/test/store.test.js +383 -383
- package/test/stress.test.js +209 -209
- package/test/summarize.test.js +884 -575
- package/test/tools-memory-get-schema.test.js +65 -65
- package/test/tools.test.js +341 -341
- package/test/updated-at-semantics.test.js +113 -113
- package/test/vector-index.test.js +221 -221
- package/test/version-check.test.js +152 -152
- package/test/webServer-optional.test.js +82 -82
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
import test from "node:test";
|
|
2
|
-
import assert from "node:assert/strict";
|
|
3
|
-
import { createStore } from "../src/store.js";
|
|
4
|
-
import { createService } from "../src/service.js";
|
|
5
|
-
import { createDreamScheduler, validateDecisions } from "../src/dream.js";
|
|
6
|
-
import { mockCtx } from "./helpers/dream-mock.js";
|
|
7
|
-
|
|
8
|
-
// 回归(issue #104 方向 1):dreamMinExplicitCoverage 覆盖率护栏误伤「挑重点」
|
|
9
|
-
// 型输出。提示词明文要求「无问题的条目无需输出」(lang.js 硬性规则),模型
|
|
10
|
-
// 只显式决策少数条目是提示词要求的行为;但护栏把显式覆盖率 < 下限判成
|
|
11
|
-
// 「截断 → 隐式 keep 洗白」整单拒绝——heptaspirit 实测官方路由 + 强模型也
|
|
12
|
-
// 天天命中(81 轮 failed 全是 coverage,applied=0,LLM 调用本身已成功)。
|
|
13
|
-
// 修复:coverage 不足降级为 degraded(合法子集照常应用 + 未提及条目隐式
|
|
14
|
-
// keep),降级理由落库 outcome.degradations;护栏以状态暴露而非一票否决。
|
|
15
|
-
// 明确异常信号(create 上限等)保持整单拒绝不变;dreamImplicitKeep=false 的
|
|
16
|
-
// 严格模式不受影响。
|
|
17
|
-
|
|
18
|
-
function snapshot(ids, type = "project") {
|
|
19
|
-
return new Map(ids.map((id, i) => [id, { id, type, title: `t${i}`, content: `c${i}`, importance: 3, archived: false, forgotten: false }]));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// ---------------------------------------------------------- validateDecisions
|
|
23
|
-
|
|
24
|
-
test("#104-1: coverage shortfall degrades — ok:true + reason surfaced, implicit keeps fill", () => {
|
|
25
|
-
const snap = snapshot(["a", "b", "c", "d"]);
|
|
26
|
-
const decisions = [{ action: "update", ids: ["a"], title: "t-new", content: "c-new" }];
|
|
27
|
-
const { ok, errors, coverageShortfall } = validateDecisions(decisions, snap, {
|
|
28
|
-
dreamImplicitKeep: true,
|
|
29
|
-
dreamMinExplicitCoverage: 0.5,
|
|
30
|
-
skipInvalid: true
|
|
31
|
-
});
|
|
32
|
-
assert.equal(ok, true, "valid subset is applied instead of whole-order rejection");
|
|
33
|
-
assert.deepEqual(errors, [], "coverage shortfall is not a per-decision error");
|
|
34
|
-
assert.match(String(coverageShortfall), /coverage/, "degradation reason surfaced for audit");
|
|
35
|
-
assert.equal(decisions.length, 4, "unclaimed ids filled with implicit keeps");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("#104-1: sufficient coverage carries no shortfall marker", () => {
|
|
39
|
-
const snap = snapshot(["a", "b"]);
|
|
40
|
-
const decisions = [{ action: "archive", ids: ["a"], reason: "stale" }, { action: "keep", ids: ["b"] }];
|
|
41
|
-
const { ok, coverageShortfall } = validateDecisions(decisions, snap, {
|
|
42
|
-
dreamImplicitKeep: true,
|
|
43
|
-
dreamMinExplicitCoverage: 0.5
|
|
44
|
-
});
|
|
45
|
-
assert.equal(ok, true);
|
|
46
|
-
assert.equal(coverageShortfall ?? null, null);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("#104-1: strict mode (implicitKeep=false) unchanged — missing ids still reject", () => {
|
|
50
|
-
const snap = snapshot(["a", "b"]);
|
|
51
|
-
const decisions = [{ action: "keep", ids: ["a"] }];
|
|
52
|
-
const { ok } = validateDecisions(decisions, snap, { dreamImplicitKeep: false });
|
|
53
|
-
assert.equal(ok, false, "strict mode keeps whole-order rejection");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// ---------------------------------------------------------- runDream 端到端
|
|
57
|
-
|
|
58
|
-
test("#104-1: runDream records degraded (not failed) with the coverage reason in the run row", async () => {
|
|
59
|
-
const store = createStore(":memory:");
|
|
60
|
-
const service = createService({ store, mirror: null, config: {} });
|
|
61
|
-
for (let i = 0; i < 20; i++) {
|
|
62
|
-
service.saveWithDedupe({ type: "project", title: `主题${i}`, content: `内容${i}`, importance: 3 });
|
|
63
|
-
}
|
|
64
|
-
// 只显式决策 1/20 = 5%(< 默认下限 50%)——提示词要求的「挑重点」形态
|
|
65
|
-
const ctx = mockCtx({
|
|
66
|
-
onConsolidation: (listText) => {
|
|
67
|
-
const ids = [...listText.matchAll(/id=([^\s|]+)\s*\|\s*type=(\w+)/g)].map((m) => m[1]);
|
|
68
|
-
return JSON.stringify([{ action: "archive", ids: [ids[0]], reason: "stale variant" }]);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
const dream = createDreamScheduler({ thresholdCount: 1, thresholdChars: 0, delayMs: 0 });
|
|
72
|
-
const result = await dream.runDream(ctx, service, {
|
|
73
|
-
dreamProvider: "deepseek",
|
|
74
|
-
dreamModel: "deepseek-chat",
|
|
75
|
-
dreamMinExplicitCoverage: 0.5
|
|
76
|
-
});
|
|
77
|
-
assert.equal(result.status, "degraded", "coverage shortfall degrades the run, not rejects it");
|
|
78
|
-
assert.equal(result.ok, true, "valid subset absorbed — scheduler baseline advances");
|
|
79
|
-
assert.ok(result.applied >= 1, "the explicit decision was applied");
|
|
80
|
-
|
|
81
|
-
const run = store.listDreamRuns()[0];
|
|
82
|
-
assert.equal(run.status, "degraded");
|
|
83
|
-
const degradations = run.outcome?.degradations ?? [];
|
|
84
|
-
assert.ok(degradations.some((s) => String(s).includes("coverage")), "coverage reason persisted in outcome.degradations");
|
|
85
|
-
store.close();
|
|
86
|
-
});
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { createStore } from "../src/store.js";
|
|
4
|
+
import { createService } from "../src/service.js";
|
|
5
|
+
import { createDreamScheduler, validateDecisions } from "../src/dream.js";
|
|
6
|
+
import { mockCtx } from "./helpers/dream-mock.js";
|
|
7
|
+
|
|
8
|
+
// 回归(issue #104 方向 1):dreamMinExplicitCoverage 覆盖率护栏误伤「挑重点」
|
|
9
|
+
// 型输出。提示词明文要求「无问题的条目无需输出」(lang.js 硬性规则),模型
|
|
10
|
+
// 只显式决策少数条目是提示词要求的行为;但护栏把显式覆盖率 < 下限判成
|
|
11
|
+
// 「截断 → 隐式 keep 洗白」整单拒绝——heptaspirit 实测官方路由 + 强模型也
|
|
12
|
+
// 天天命中(81 轮 failed 全是 coverage,applied=0,LLM 调用本身已成功)。
|
|
13
|
+
// 修复:coverage 不足降级为 degraded(合法子集照常应用 + 未提及条目隐式
|
|
14
|
+
// keep),降级理由落库 outcome.degradations;护栏以状态暴露而非一票否决。
|
|
15
|
+
// 明确异常信号(create 上限等)保持整单拒绝不变;dreamImplicitKeep=false 的
|
|
16
|
+
// 严格模式不受影响。
|
|
17
|
+
|
|
18
|
+
function snapshot(ids, type = "project") {
|
|
19
|
+
return new Map(ids.map((id, i) => [id, { id, type, title: `t${i}`, content: `c${i}`, importance: 3, archived: false, forgotten: false }]));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// ---------------------------------------------------------- validateDecisions
|
|
23
|
+
|
|
24
|
+
test("#104-1: coverage shortfall degrades — ok:true + reason surfaced, implicit keeps fill", () => {
|
|
25
|
+
const snap = snapshot(["a", "b", "c", "d"]);
|
|
26
|
+
const decisions = [{ action: "update", ids: ["a"], title: "t-new", content: "c-new" }];
|
|
27
|
+
const { ok, errors, coverageShortfall } = validateDecisions(decisions, snap, {
|
|
28
|
+
dreamImplicitKeep: true,
|
|
29
|
+
dreamMinExplicitCoverage: 0.5,
|
|
30
|
+
skipInvalid: true
|
|
31
|
+
});
|
|
32
|
+
assert.equal(ok, true, "valid subset is applied instead of whole-order rejection");
|
|
33
|
+
assert.deepEqual(errors, [], "coverage shortfall is not a per-decision error");
|
|
34
|
+
assert.match(String(coverageShortfall), /coverage/, "degradation reason surfaced for audit");
|
|
35
|
+
assert.equal(decisions.length, 4, "unclaimed ids filled with implicit keeps");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test("#104-1: sufficient coverage carries no shortfall marker", () => {
|
|
39
|
+
const snap = snapshot(["a", "b"]);
|
|
40
|
+
const decisions = [{ action: "archive", ids: ["a"], reason: "stale" }, { action: "keep", ids: ["b"] }];
|
|
41
|
+
const { ok, coverageShortfall } = validateDecisions(decisions, snap, {
|
|
42
|
+
dreamImplicitKeep: true,
|
|
43
|
+
dreamMinExplicitCoverage: 0.5
|
|
44
|
+
});
|
|
45
|
+
assert.equal(ok, true);
|
|
46
|
+
assert.equal(coverageShortfall ?? null, null);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test("#104-1: strict mode (implicitKeep=false) unchanged — missing ids still reject", () => {
|
|
50
|
+
const snap = snapshot(["a", "b"]);
|
|
51
|
+
const decisions = [{ action: "keep", ids: ["a"] }];
|
|
52
|
+
const { ok } = validateDecisions(decisions, snap, { dreamImplicitKeep: false });
|
|
53
|
+
assert.equal(ok, false, "strict mode keeps whole-order rejection");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// ---------------------------------------------------------- runDream 端到端
|
|
57
|
+
|
|
58
|
+
test("#104-1: runDream records degraded (not failed) with the coverage reason in the run row", async () => {
|
|
59
|
+
const store = createStore(":memory:");
|
|
60
|
+
const service = createService({ store, mirror: null, config: {} });
|
|
61
|
+
for (let i = 0; i < 20; i++) {
|
|
62
|
+
service.saveWithDedupe({ type: "project", title: `主题${i}`, content: `内容${i}`, importance: 3 });
|
|
63
|
+
}
|
|
64
|
+
// 只显式决策 1/20 = 5%(< 默认下限 50%)——提示词要求的「挑重点」形态
|
|
65
|
+
const ctx = mockCtx({
|
|
66
|
+
onConsolidation: (listText) => {
|
|
67
|
+
const ids = [...listText.matchAll(/id=([^\s|]+)\s*\|\s*type=(\w+)/g)].map((m) => m[1]);
|
|
68
|
+
return JSON.stringify([{ action: "archive", ids: [ids[0]], reason: "stale variant" }]);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const dream = createDreamScheduler({ thresholdCount: 1, thresholdChars: 0, delayMs: 0 });
|
|
72
|
+
const result = await dream.runDream(ctx, service, {
|
|
73
|
+
dreamProvider: "deepseek",
|
|
74
|
+
dreamModel: "deepseek-chat",
|
|
75
|
+
dreamMinExplicitCoverage: 0.5
|
|
76
|
+
});
|
|
77
|
+
assert.equal(result.status, "degraded", "coverage shortfall degrades the run, not rejects it");
|
|
78
|
+
assert.equal(result.ok, true, "valid subset absorbed — scheduler baseline advances");
|
|
79
|
+
assert.ok(result.applied >= 1, "the explicit decision was applied");
|
|
80
|
+
|
|
81
|
+
const run = store.listDreamRuns()[0];
|
|
82
|
+
assert.equal(run.status, "degraded");
|
|
83
|
+
const degradations = run.outcome?.degradations ?? [];
|
|
84
|
+
assert.ok(degradations.some((s) => String(s).includes("coverage")), "coverage reason persisted in outcome.degradations");
|
|
85
|
+
store.close();
|
|
86
|
+
});
|