dsh-memu-memory 1.1.3 → 1.2.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/AGENTS.md +1 -1
- package/README.md +31 -2
- package/README.zh.md +30 -2
- package/docs/active-memory-ab.md +385 -0
- package/docs/binding-lifecycle.md +99 -0
- package/docs/contributing.md +1 -1
- package/docs/emotion-model-spec.md +281 -0
- package/docs/host-api.md +2 -2
- package/docs/memory-semantics.md +12 -10
- package/docs/recall-benchmark.md +238 -0
- package/docs/troubleshooting.md +395 -395
- package/lib/active-memory.js +165 -0
- package/lib/activity-log.js +1 -1
- package/lib/binding-diagnostics.js +8 -3
- package/lib/client.js +33 -11
- package/lib/consolidation-ledger.js +347 -0
- package/lib/consolidation-receipt.js +284 -0
- package/lib/consolidation-snapshot.js +274 -0
- package/lib/consolidation-worker.js +115 -0
- package/lib/cycle.js +40 -6
- package/lib/inject.js +104 -76
- package/lib/local-embedding-manager.js +24 -6
- package/lib/memory.js +221 -19
- package/lib/mood.js +268 -39
- package/lib/preset-scope.js +1 -1
- package/lib/private.js +335 -40
- package/lib/prompts/private-consolidation.coding.md +1 -0
- package/lib/prompts/private-consolidation.md +1 -0
- package/lib/prompts/private-consolidation.mixed.md +1 -0
- package/lib/prompts/private-consolidation.rp.md +1 -0
- package/lib/prompts.js +4 -4
- package/lib/remote-summary.js +51 -25
- package/lib/rpc.js +9 -1
- package/lib/state.js +29 -12
- package/lib/tools.js +49 -2
- package/lib/vector-profile.js +27 -0
- package/package.json +2 -1
- package/scripts/acceptance-local.mjs +2 -1
- package/scripts/active-memory-ab-live.mjs +655 -0
- package/scripts/active-memory-ab.mjs +1302 -0
- package/scripts/chain-matrix.mjs +11 -1
- package/scripts/check-all.mjs +10 -1
- package/tests/activation.test.mjs +89 -0
- package/tests/active-memory-ab.test.mjs +745 -0
- package/tests/active-memory.test.mjs +129 -0
- package/tests/activity-log.test.mjs +126 -0
- package/tests/activity-wiring.test.mjs +103 -0
- package/tests/appendix-b.test.mjs +212 -0
- package/tests/appendix-b2.test.mjs +166 -0
- package/tests/audit-regression.test.mjs +272 -0
- package/tests/audit-safety.test.mjs +227 -0
- package/tests/backend-compensation.test.mjs +272 -0
- package/tests/backup.test.mjs +793 -0
- package/tests/binding-diagnostics.test.mjs +720 -0
- package/tests/browser.test.mjs +366 -0
- package/tests/client-render.test.mjs +892 -0
- package/tests/coalesce.test.mjs +113 -0
- package/tests/config.test.mjs +159 -0
- package/tests/consolidation-credential.test.mjs +320 -0
- package/tests/consolidation-fork.test.mjs +357 -0
- package/tests/consolidation-ledger.test.mjs +298 -0
- package/tests/consolidation-snapshot.test.mjs +321 -0
- package/tests/consolidation-value.test.mjs +89 -0
- package/tests/context-scope.test.mjs +40 -0
- package/tests/cue.test.mjs +44 -0
- package/tests/curator-probe.test.mjs +433 -0
- package/tests/curator.test.mjs +150 -0
- package/tests/cycle.test.mjs +411 -0
- package/tests/disclosure.test.mjs +231 -0
- package/tests/doc-drift.test.mjs +222 -0
- package/tests/embedding-catalog.test.mjs +266 -0
- package/tests/embedding-download.test.mjs +391 -0
- package/tests/embedding-runtime.test.mjs +389 -0
- package/tests/emotion-chain.test.mjs +84 -0
- package/tests/emotion-contract.test.mjs +445 -0
- package/tests/engine.test.mjs +35 -0
- package/tests/fixtures/active-memory-ab/README.md +56 -0
- package/tests/fixtures/active-memory-ab/cases/01-clean-dense-turn.json +351 -0
- package/tests/fixtures/active-memory-ab/cases/02-clean-thin-turn.json +122 -0
- package/tests/fixtures/active-memory-ab/cases/03-clean-starved-small.json +125 -0
- package/tests/fixtures/active-memory-ab/cases/04-clean-large-thin.json +137 -0
- package/tests/fixtures/active-memory-ab/cases/05-clean-half-step.json +166 -0
- package/tests/fixtures/active-memory-ab/cases/06-clean-duplicate-reread.json +197 -0
- package/tests/fixtures/active-memory-ab/cases/07-clean-recent-recall.json +125 -0
- package/tests/fixtures/active-memory-ab/cases/08-global-relevant.json +111 -0
- package/tests/fixtures/active-memory-ab/cases/09-global-irrelevant-conflict.json +158 -0
- package/tests/fixtures/active-memory-ab/cases/10-no-human-turn.json +97 -0
- package/tests/fixtures/active-memory-ab/cases/11-clean-scale-100.json +137 -0
- package/tests/fixtures/active-memory-ab/cases/12-clean-scale-1000.json +137 -0
- package/tests/fixtures/active-memory-ab/cases/13-clean-scale-5000.json +137 -0
- package/tests/fixtures/active-memory-ab/cases/14-clean-scale-20000.json +137 -0
- package/tests/fixtures/active-memory-ab/lead-ai-reviewed-reference.json +191 -0
- package/tests/fixtures/active-memory-ab/manifest.json +199 -0
- package/tests/fixtures/recall-bench/01-paraphrase.json +184 -0
- package/tests/fixtures/recall-bench/02-exact.json +153 -0
- package/tests/fixtures/recall-bench/03-negation.json +173 -0
- package/tests/fixtures/recall-bench/04-no-answer.json +162 -0
- package/tests/fixtures/recall-bench/05-conflict.json +194 -0
- package/tests/fixtures/recall-bench/06-boundary.json +273 -0
- package/tests/fixtures/recall-bench/07-secret.json +191 -0
- package/tests/fixtures/recall-bench/08-coding.json +164 -0
- package/tests/fixtures/recall-bench-gold-candidates/01-paraphrase.json +193 -0
- package/tests/fixtures/recall-bench-gold-candidates/02-exact.json +197 -0
- package/tests/fixtures/recall-bench-gold-candidates/03-negation.json +244 -0
- package/tests/fixtures/recall-bench-gold-candidates/04-no-answer.json +189 -0
- package/tests/fixtures/recall-bench-gold-candidates/05-conflict.json +245 -0
- package/tests/fixtures/recall-bench-gold-candidates/06-boundary.json +279 -0
- package/tests/fixtures/recall-bench-gold-candidates/07-secret.json +224 -0
- package/tests/fixtures/recall-bench-gold-candidates/08-coding.json +218 -0
- package/tests/fixtures/repetition-eval/01-zh-rp.json +93 -0
- package/tests/fixtures/repetition-eval/02-en.json +97 -0
- package/tests/fixtures/repetition-eval/03-code.json +91 -0
- package/tests/fixtures/repetition-eval/04-names.json +116 -0
- package/tests/fixtures/repetition-eval/05-user-quote.json +96 -0
- package/tests/fixtures/repetition-eval/06-agreement.json +86 -0
- package/tests/graph-view.test.mjs +187 -0
- package/tests/graph.test.mjs +77 -0
- package/tests/hook-order.test.mjs +72 -0
- package/tests/humanlike.test.mjs +232 -0
- package/tests/hybrid-recall.test.mjs +92 -0
- package/tests/inbound.test.mjs +393 -0
- package/tests/inject-guide.test.mjs +364 -0
- package/tests/inject.test.mjs +222 -0
- package/tests/injection-budget-settings.test.mjs +35 -0
- package/tests/injection-budget.test.mjs +64 -0
- package/tests/injection-chain.test.mjs +191 -0
- package/tests/loader-register.mjs +3 -0
- package/tests/loader.mjs +12 -0
- package/tests/local-embedding-entry.test.mjs +95 -0
- package/tests/local-embedding-manager.test.mjs +476 -0
- package/tests/local-embedding-protocol.test.mjs +95 -0
- package/tests/local-embedding-worker.test.mjs +346 -0
- package/tests/managed-memory.test.mjs +536 -0
- package/tests/managed-runtime.test.mjs +40 -0
- package/tests/media.test.mjs +132 -0
- package/tests/migration-payload.test.mjs +42 -0
- package/tests/mood.test.mjs +109 -0
- package/tests/multiprocess.test.mjs +29 -0
- package/tests/new-session-gate.test.mjs +361 -0
- package/tests/package-shipping.test.mjs +84 -0
- package/tests/preset-scope.test.mjs +212 -0
- package/tests/prompts.test.mjs +250 -0
- package/tests/react-snapshot.test.mjs +23 -0
- package/tests/recall-bench.test.mjs +306 -0
- package/tests/remote.test.mjs +140 -0
- package/tests/rename.test.mjs +30 -0
- package/tests/repetition-detector-snapshot.test.mjs +231 -0
- package/tests/repetition-eval-live.test.mjs +177 -0
- package/tests/repetition-eval.test.mjs +373 -0
- package/tests/salient-date.test.mjs +142 -0
- package/tests/settings-beat.test.mjs +221 -0
- package/tests/short-term.test.mjs +166 -0
- package/tests/sidebar-beat.test.mjs +208 -0
- package/tests/sidebar-refresh.test.mjs +123 -0
- package/tests/sidebar.test.mjs +70 -0
- package/tests/snippet.test.mjs +47 -0
- package/tests/source-kind.test.mjs +52 -0
- package/tests/state.test.mjs +150 -0
- package/tests/stats.test.mjs +112 -0
- package/tests/storage.test.mjs +125 -0
- package/tests/stubs/dsh-llm.js +5 -0
- package/tests/stubs/dsh-session.js +7 -0
- package/tests/stubs/dsh-tools.js +101 -0
- package/tests/tool-schema.test.mjs +73 -0
- package/tests/tools.test.mjs +184 -0
- package/tests/ui-defaults.test.mjs +57 -0
- package/tests/update-fields.test.mjs +138 -0
- package/tests/vector-migration.test.mjs +733 -0
- package/tests/vector-profile.test.mjs +425 -0
- package/tests/visibility-migration.test.mjs +152 -0
- package/tests/webui-auth.test.mjs +454 -0
- package/tests/webui.test.mjs +164 -0
- package/tests/windows-env.test.mjs +89 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"kind": "active-memory-ab-case",
|
|
4
|
+
"id": "clean-dense-turn",
|
|
5
|
+
"draft": true,
|
|
6
|
+
"notGold": true,
|
|
7
|
+
"gold": false,
|
|
8
|
+
"review": "pending",
|
|
9
|
+
"annotationSource": "synthetic-proxy",
|
|
10
|
+
"interference": "off",
|
|
11
|
+
"title": "密集回合:分数达标就检查,不等空闲",
|
|
12
|
+
"annotationNotes": "合成代理标注:按 seq 指向“若由人来标也应记”的事件,未经过人工确认。",
|
|
13
|
+
"snapshot": {
|
|
14
|
+
"domain": "coding",
|
|
15
|
+
"idleAtSnapshotEndMinutes": 0.5,
|
|
16
|
+
"lastInjectedAt": null,
|
|
17
|
+
"events": [
|
|
18
|
+
{
|
|
19
|
+
"type": "turn/start",
|
|
20
|
+
"at": "2026-10-30T02:00:00.000Z"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "user/message",
|
|
24
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
25
|
+
"data": {
|
|
26
|
+
"source": {
|
|
27
|
+
"kind": "user"
|
|
28
|
+
},
|
|
29
|
+
"content": [
|
|
30
|
+
{
|
|
31
|
+
"type": "text",
|
|
32
|
+
"text": "我们决定把主动记忆改成快照 worker:主会话不再等整理跑完,worker 只处理固定前缀 (fromSeq, throughSeq]。根因是现在的 fork 每次都把整段转录重新种进去,5 个成功 fork 实测平均 9.4 万 input(含缓存读),长会话一次就接近 22 万。这条结论要留在记忆里,别再回头讨论窗口化 seed——宿主目前不支持,重编号会被拒。另外记一下约定:worker 只能写私有层,全局条目只读,不许把全局正文复制进私有条目;凭证必须带 fromSeq、throughSeq、snapshotSha256 和 scopeGeneration 四样,缺一样就不能前移游标。还有一条:检查结果为 no_value 必须来自 completed 凭证,空白输出、任务 idle、工具不可达都不算 no_value,要分别记成 failed 或 deferred,并且不能前移游标。这些口径以后都按这个来,不再重新讨论。"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "assistant/message",
|
|
39
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
40
|
+
"data": {
|
|
41
|
+
"message": {
|
|
42
|
+
"content": [
|
|
43
|
+
{
|
|
44
|
+
"type": "text",
|
|
45
|
+
"text": "记下了:检查走快照 worker,窗口化 seed 先不做。我把两处证据分别标出来:一是 fork 的 usage,二是宿主 seed 语义的实测边界。结论按四条落库:快照 worker、全局只读、凭证四要素、no_value 的口径。这样后面写测试就有明确断言点。"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"type": "tool-call",
|
|
49
|
+
"toolCallId": "c1",
|
|
50
|
+
"name": "read",
|
|
51
|
+
"arguments": {
|
|
52
|
+
"path": "docs/active-memory-construction.md"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"type": "tool/result",
|
|
61
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
62
|
+
"toolCallId": "c1",
|
|
63
|
+
"data": {
|
|
64
|
+
"message": {
|
|
65
|
+
"isError": false,
|
|
66
|
+
"content": [
|
|
67
|
+
{
|
|
68
|
+
"type": "text",
|
|
69
|
+
"text": "§13.11 每次 fork 实测(只看种子截止标记之后的 fork 自有回合,数据来自 assistant/message.data.usage):\n\n| fork | 源会话 | 事件数 | LLM 步数 | uncached input | cache read | output |\n| mvttm41k | 62056bff | 2327 | 5 | 161161 | 55680 | 2325 |\n| mvtyrh91 | 62056bff | 5956 | 3 | 83504 | 13696 | 1853 |\n| mvtqiitr | e38a0de0 | 105 | 2 | 21426 | 19584 | 769 |\n| mvu0wkex | edf7dc5c | 80 | 3 | 16979 | 35200 | 962 |\n| mvu1kbw4 | edf7dc5c | 104 | 3 | 19090 | 43008 | 3406 |\n\n平均每次约 9.4 万 input(含缓存读)+ 1.9k output;首请求约 2~4 万 input,之后随记忆工具步数增长,宿主会压缩上下文。宿主 seed 语义实证(@deepseek-ai/dsh-session):buildForkSeed(events, lastSeq) 加 inheritedEventCount = lastSeq + 1 会被接受;只种最近窗口(重编号 + inheritedEventCount: 0)被拒绝,报 sourceEventSeqs must reference earlier events: 4653 >= current seq 7;不重编号直接切片报 seq 4648 (expected 0); seed must be contiguous from 0。因此窗口化 seed 不是「改改 count」能做的,在宿主提供官方 windowed seed 之前不做。"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"type": "step/end",
|
|
77
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
78
|
+
"step": 1
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"type": "user/message",
|
|
82
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
83
|
+
"data": {
|
|
84
|
+
"source": {
|
|
85
|
+
"kind": "user"
|
|
86
|
+
},
|
|
87
|
+
"content": [
|
|
88
|
+
{
|
|
89
|
+
"type": "text",
|
|
90
|
+
"text": "还有一条硬约束:迁移脚本只允许在 engine/<version>/venv 里跑,不许碰系统解释器,也不许往用户 site-packages 里装东西。venv 里不留 pip,用基础 Python 的 pip --python 指进去装。这是安全底线,不是风格偏好,任何“为了快一点”的临时方案都不算数;如果某次真的要破例,必须先在记忆里留下一条待复核的条目说明原因,并且等我确认。升级引擎也只装声明版本,走新 venv + smoke + 切换 + 保留旧版,不自动追最新 MemU;备份目录只保留最新三份,破坏性操作前必须自动再备份一次,删库这种操作必须我显式确认。"
|
|
91
|
+
}
|
|
92
|
+
]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"type": "assistant/message",
|
|
97
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
98
|
+
"data": {
|
|
99
|
+
"message": {
|
|
100
|
+
"content": [
|
|
101
|
+
{
|
|
102
|
+
"type": "text",
|
|
103
|
+
"text": "明白,venv 是唯一允许的 Python 安装位置。我把这条记成硬约束,并在检查凭证里保留来源 seq,避免以后被“临时方案”悄悄覆盖。顺带把引擎升级与备份纪律一起记:只装声明版本、新 venv 切换、备份留三份、删库必须显式确认。"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"type": "tool-call",
|
|
107
|
+
"toolCallId": "c2",
|
|
108
|
+
"name": "grep",
|
|
109
|
+
"arguments": {
|
|
110
|
+
"pattern": "site-packages"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"type": "tool/result",
|
|
119
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
120
|
+
"toolCallId": "c2",
|
|
121
|
+
"data": {
|
|
122
|
+
"message": {
|
|
123
|
+
"isError": false,
|
|
124
|
+
"content": [
|
|
125
|
+
{
|
|
126
|
+
"type": "text",
|
|
127
|
+
"text": "lib/engine.js:112 只使用 engine/<version>/venv/bin/python 调用引擎;scripts/setup.mjs 用 --without-pip 建 venv,再用基础 Python 的 pip --python 装依赖,venv 里不留 pip;docs/env-and-commands.md §9 记录了引擎安装、smoke、切换、回滚顺序与 prune 白名单(current / recommended 不参与 prune);lib/backup.js 的备份只保留最新三份,破坏性操作前自动再备份一次;删库必须显式确认,删会话默认只解绑不删库。\n\n没有发现往系统解释器或用户 site-packages 写入的路径;唯一可疑的写法是把 pip install 放进 setup 的临时目录,但它已经在 venv 内执行。原会话里那次“直接 pip install 到系统”的记录来自上个月的旧脚本,已经删除。"
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"type": "step/end",
|
|
135
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
136
|
+
"step": 2
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"type": "user/message",
|
|
140
|
+
"at": "2026-10-30T02:02:00.000Z",
|
|
141
|
+
"data": {
|
|
142
|
+
"source": {
|
|
143
|
+
"kind": "user"
|
|
144
|
+
},
|
|
145
|
+
"content": [
|
|
146
|
+
{
|
|
147
|
+
"type": "text",
|
|
148
|
+
"text": "第三个决定:人审候选集和 gold gating 要分开。评审状态先保持 pending,合成代理标注永远不许标成 gold;真实模型调用必须我明确选择之后才能做,你不要自己去联网跑对照。评测结果先写 provisional,宁可说“调度/管线通过”,也不要把合成代理的数字说成真实模型的主功率提升。评测要报的口径我也定一下:应记事件覆盖率与延迟、检查 no_value 率、重复与 held 条数、每千有效步骤的检查次数、额外调用与 token 估算、主任务阻塞耗时,调度结果与模型效果必须分开写。"
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"type": "assistant/message",
|
|
155
|
+
"at": "2026-10-30T02:02:00.000Z",
|
|
156
|
+
"data": {
|
|
157
|
+
"message": {
|
|
158
|
+
"content": [
|
|
159
|
+
{
|
|
160
|
+
"type": "text",
|
|
161
|
+
"text": "接受这个口径。报告里我会把 goldGating 与 model 两块分开写:executed 固定为 false,标注来源标 synthetic-proxy,覆盖率先给上下界而不是点估计;指标按你列的那几项输出,调度与模型效果分栏。"
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
"type": "assistant/message",
|
|
169
|
+
"at": "2026-10-30T02:02:00.000Z",
|
|
170
|
+
"data": {
|
|
171
|
+
"message": {
|
|
172
|
+
"content": [
|
|
173
|
+
{
|
|
174
|
+
"type": "text",
|
|
175
|
+
"text": "先把指标口径核对一遍,避免报告里混着写。"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"type": "tool-call",
|
|
179
|
+
"toolCallId": "c3",
|
|
180
|
+
"name": "grep",
|
|
181
|
+
"arguments": {
|
|
182
|
+
"pattern": "per1000Steps"
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"type": "tool/call",
|
|
191
|
+
"at": "2026-10-30T02:02:00.000Z",
|
|
192
|
+
"toolCallId": "c3",
|
|
193
|
+
"name": "grep",
|
|
194
|
+
"arguments": {
|
|
195
|
+
"pattern": "per1000Steps"
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"type": "tool/result",
|
|
200
|
+
"at": "2026-10-30T02:02:00.000Z",
|
|
201
|
+
"toolCallId": "c3",
|
|
202
|
+
"data": {
|
|
203
|
+
"message": {
|
|
204
|
+
"isError": false,
|
|
205
|
+
"content": [
|
|
206
|
+
{
|
|
207
|
+
"type": "text",
|
|
208
|
+
"text": "scripts/recall-bench.mjs 里已有的口径是:候选 id 与最终注入 id 分别算 Recall@3、MRR@3、无答案误召回率、隔离违规、延迟统计、按子类分组;预算只报 estimate,字段名写明 estimateOnly,并注明「不是实际 token 用量」。同样的纪律搬到这里:覆盖率先给上下界(oracle 上界、no-value 下界),延迟用「人类回合数 / step-start 事件数」而不是毫秒,成本用 estTokens 估算并在报告里注明 estimateOnly=true,阻塞只报结构性口径(旧 fork 每个检查都让主会话等满整段前缀,快照 worker 不等)而不编造真实延迟。所有这些字段名必须与 doc 一致,否则读者会拿估算当实测。"
|
|
209
|
+
}
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"type": "assistant/message",
|
|
216
|
+
"at": "2026-10-30T02:02:30.000Z",
|
|
217
|
+
"data": {
|
|
218
|
+
"message": {
|
|
219
|
+
"content": [
|
|
220
|
+
{
|
|
221
|
+
"type": "text",
|
|
222
|
+
"text": "再确认一条:held 不能算覆盖。"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"type": "tool-call",
|
|
226
|
+
"toolCallId": "c4",
|
|
227
|
+
"name": "read",
|
|
228
|
+
"arguments": {
|
|
229
|
+
"path": "docs/active-memory-construction.md"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"type": "tool/call",
|
|
238
|
+
"at": "2026-10-30T02:02:30.000Z",
|
|
239
|
+
"toolCallId": "c4",
|
|
240
|
+
"name": "read",
|
|
241
|
+
"arguments": {
|
|
242
|
+
"path": "docs/active-memory-construction.md"
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"type": "tool/result",
|
|
247
|
+
"at": "2026-10-30T02:02:30.000Z",
|
|
248
|
+
"toolCallId": "c4",
|
|
249
|
+
"data": {
|
|
250
|
+
"message": {
|
|
251
|
+
"isError": false,
|
|
252
|
+
"content": [
|
|
253
|
+
{
|
|
254
|
+
"type": "text",
|
|
255
|
+
"text": "§13.6 正常输出与成功条件:检查结果至少有 checked range / snapshot identity / scope generation、status: completed | skipped | deferred | failed、outcome: created | updated | mixed | no_value、createdIds / updatedIds / heldIds、reasonCode / retryable。no_value 必须有明确正常结果,不等于空输出或任务 idle。工具动作的 id、正文版本和来源事件要能核验;重复写返回已有 id 不算新增。冲突 pending_review 单独计 held,不计可召回成功。§13.6 游标与恢复:只有完整覆盖范围且有凭证的 completed / no_value 才前移相应 checked 游标;失败、不支持工具、超时、半步、格式错误不能前移;分批时只确认实际覆盖前缀。"
|
|
256
|
+
}
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"type": "step/end",
|
|
263
|
+
"at": "2026-10-30T02:02:00.000Z",
|
|
264
|
+
"step": 3
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"type": "turn/end",
|
|
268
|
+
"at": "2026-10-30T02:03:00.000Z"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"type": "turn/start",
|
|
272
|
+
"at": "2026-10-30T02:04:00.000Z"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"type": "user/message",
|
|
276
|
+
"at": "2026-10-30T02:04:00.000Z",
|
|
277
|
+
"data": {
|
|
278
|
+
"source": {
|
|
279
|
+
"kind": "user"
|
|
280
|
+
},
|
|
281
|
+
"content": [
|
|
282
|
+
{
|
|
283
|
+
"type": "text",
|
|
284
|
+
"text": "继续,把剩下两个测试补上。"
|
|
285
|
+
}
|
|
286
|
+
]
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
"type": "assistant/message",
|
|
291
|
+
"at": "2026-10-30T02:04:00.000Z",
|
|
292
|
+
"data": {
|
|
293
|
+
"message": {
|
|
294
|
+
"content": [
|
|
295
|
+
{
|
|
296
|
+
"type": "text",
|
|
297
|
+
"text": "好的,先跑用例结构检查。"
|
|
298
|
+
}
|
|
299
|
+
]
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"type": "turn/end",
|
|
305
|
+
"at": "2026-10-30T02:05:00.000Z"
|
|
306
|
+
}
|
|
307
|
+
]
|
|
308
|
+
},
|
|
309
|
+
"labels": {
|
|
310
|
+
"expected": [
|
|
311
|
+
{
|
|
312
|
+
"id": "mem-ab-dense-worker-decision",
|
|
313
|
+
"class": "decision",
|
|
314
|
+
"sourceSeq": 1,
|
|
315
|
+
"note": "检查改用固定前缀快照 worker,主会话不等整理"
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"id": "mem-ab-dense-fork-root-cause",
|
|
319
|
+
"class": "root-cause",
|
|
320
|
+
"sourceSeq": 3,
|
|
321
|
+
"note": "fork 重复种整段转录,每次约 9.4 万 input"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"id": "mem-ab-dense-venv-constraint",
|
|
325
|
+
"class": "preference",
|
|
326
|
+
"sourceSeq": 5,
|
|
327
|
+
"note": "Python 只装 engine/<version>/venv,不碰系统解释器"
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
"id": "mem-ab-dense-gold-gating",
|
|
331
|
+
"class": "promise",
|
|
332
|
+
"sourceSeq": 9,
|
|
333
|
+
"note": "合成代理标注不标 gold;真实模型调用需用户明确选择"
|
|
334
|
+
}
|
|
335
|
+
],
|
|
336
|
+
"mainProactive": [],
|
|
337
|
+
"userReminders": []
|
|
338
|
+
},
|
|
339
|
+
"expect": {
|
|
340
|
+
"wakeReasons": [
|
|
341
|
+
"score"
|
|
342
|
+
],
|
|
343
|
+
"minBackgroundChecks": 1,
|
|
344
|
+
"coveredLabelIds": [
|
|
345
|
+
"mem-ab-dense-worker-decision",
|
|
346
|
+
"mem-ab-dense-fork-root-cause",
|
|
347
|
+
"mem-ab-dense-venv-constraint",
|
|
348
|
+
"mem-ab-dense-gold-gating"
|
|
349
|
+
]
|
|
350
|
+
}
|
|
351
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"kind": "active-memory-ab-case",
|
|
4
|
+
"id": "clean-thin-turn",
|
|
5
|
+
"draft": true,
|
|
6
|
+
"notGold": true,
|
|
7
|
+
"gold": false,
|
|
8
|
+
"review": "pending",
|
|
9
|
+
"annotationSource": "synthetic-proxy",
|
|
10
|
+
"interference": "off",
|
|
11
|
+
"title": "薄回合:没有空闲窗口,也不该唤醒",
|
|
12
|
+
"annotationNotes": "合成代理标注:薄回合本身没有应记事件;留一条标签是为了量“未被覆盖的区间”,不是假装覆盖。",
|
|
13
|
+
"snapshot": {
|
|
14
|
+
"domain": "coding",
|
|
15
|
+
"idleAtSnapshotEndMinutes": 0.5,
|
|
16
|
+
"lastInjectedAt": null,
|
|
17
|
+
"events": [
|
|
18
|
+
{
|
|
19
|
+
"type": "turn/start",
|
|
20
|
+
"at": "2026-10-30T02:00:00.000Z"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "user/message",
|
|
24
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
25
|
+
"data": {
|
|
26
|
+
"source": {
|
|
27
|
+
"kind": "user"
|
|
28
|
+
},
|
|
29
|
+
"content": [
|
|
30
|
+
{
|
|
31
|
+
"type": "text",
|
|
32
|
+
"text": "继续"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "assistant/message",
|
|
39
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
40
|
+
"data": {
|
|
41
|
+
"message": {
|
|
42
|
+
"content": [
|
|
43
|
+
{
|
|
44
|
+
"type": "text",
|
|
45
|
+
"text": "好,接着上次的进度。"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "step/end",
|
|
53
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
54
|
+
"step": 1
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"type": "turn/end",
|
|
58
|
+
"at": "2026-10-30T02:00:30.000Z"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "turn/start",
|
|
62
|
+
"at": "2026-10-30T02:01:00.000Z"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"type": "user/message",
|
|
66
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
67
|
+
"data": {
|
|
68
|
+
"source": {
|
|
69
|
+
"kind": "user"
|
|
70
|
+
},
|
|
71
|
+
"content": [
|
|
72
|
+
{
|
|
73
|
+
"type": "text",
|
|
74
|
+
"text": "嗯"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"type": "assistant/message",
|
|
81
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
82
|
+
"data": {
|
|
83
|
+
"message": {
|
|
84
|
+
"content": [
|
|
85
|
+
{
|
|
86
|
+
"type": "text",
|
|
87
|
+
"text": "需要我改哪一块?"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"type": "step/end",
|
|
95
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
96
|
+
"step": 2
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"type": "turn/end",
|
|
100
|
+
"at": "2026-10-30T02:01:30.000Z"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"labels": {
|
|
105
|
+
"expected": [
|
|
106
|
+
{
|
|
107
|
+
"id": "mem-ab-thin-uncovered-note",
|
|
108
|
+
"class": "decision",
|
|
109
|
+
"sourceSeq": 1,
|
|
110
|
+
"note": "薄回合里没有真实决定,这条标签用于标出未被检查覆盖的区间"
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"mainProactive": [],
|
|
114
|
+
"userReminders": []
|
|
115
|
+
},
|
|
116
|
+
"expect": {
|
|
117
|
+
"maxBackgroundChecks": 0,
|
|
118
|
+
"uncoveredLabelIds": [
|
|
119
|
+
"mem-ab-thin-uncovered-note"
|
|
120
|
+
]
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"kind": "active-memory-ab-case",
|
|
4
|
+
"id": "clean-starved-small",
|
|
5
|
+
"draft": true,
|
|
6
|
+
"notGold": true,
|
|
7
|
+
"gold": false,
|
|
8
|
+
"review": "pending",
|
|
9
|
+
"annotationSource": "synthetic-proxy",
|
|
10
|
+
"interference": "off",
|
|
11
|
+
"title": "小会话饥饿:空闲到阈值就无条件检查一次",
|
|
12
|
+
"annotationNotes": "合成代理标注:短关键口径(no_value 的语义)算应记事件,不能因为字符少就丢。",
|
|
13
|
+
"snapshot": {
|
|
14
|
+
"domain": "coding",
|
|
15
|
+
"idleAtSnapshotEndMinutes": 20,
|
|
16
|
+
"lastInjectedAt": null,
|
|
17
|
+
"events": [
|
|
18
|
+
{
|
|
19
|
+
"type": "turn/start",
|
|
20
|
+
"at": "2026-10-30T02:00:00.000Z"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"type": "user/message",
|
|
24
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
25
|
+
"data": {
|
|
26
|
+
"source": {
|
|
27
|
+
"kind": "user"
|
|
28
|
+
},
|
|
29
|
+
"content": [
|
|
30
|
+
{
|
|
31
|
+
"type": "text",
|
|
32
|
+
"text": "把刚才那个 no_value 的口径记一下:检查正常返回空结果才算 no_value,空白输出和 idle 都不算。"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "assistant/message",
|
|
39
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
40
|
+
"data": {
|
|
41
|
+
"message": {
|
|
42
|
+
"content": [
|
|
43
|
+
{
|
|
44
|
+
"type": "text",
|
|
45
|
+
"text": "收到,no_value 只在凭证 completed 且没有候选时成立。"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "step/end",
|
|
53
|
+
"at": "2026-10-30T02:00:00.000Z",
|
|
54
|
+
"step": 1
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"type": "turn/end",
|
|
58
|
+
"at": "2026-10-30T02:00:30.000Z"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "turn/start",
|
|
62
|
+
"at": "2026-10-30T02:01:00.000Z"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"type": "user/message",
|
|
66
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
67
|
+
"data": {
|
|
68
|
+
"source": {
|
|
69
|
+
"kind": "user"
|
|
70
|
+
},
|
|
71
|
+
"content": [
|
|
72
|
+
{
|
|
73
|
+
"type": "text",
|
|
74
|
+
"text": "对,就这个。"
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"type": "assistant/message",
|
|
81
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
82
|
+
"data": {
|
|
83
|
+
"message": {
|
|
84
|
+
"content": [
|
|
85
|
+
{
|
|
86
|
+
"type": "text",
|
|
87
|
+
"text": "已经按这个口径记好了。"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"type": "step/end",
|
|
95
|
+
"at": "2026-10-30T02:01:00.000Z",
|
|
96
|
+
"step": 2
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"type": "turn/end",
|
|
100
|
+
"at": "2026-10-30T02:01:30.000Z"
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"labels": {
|
|
105
|
+
"expected": [
|
|
106
|
+
{
|
|
107
|
+
"id": "mem-ab-starved-no-value-rule",
|
|
108
|
+
"class": "decision",
|
|
109
|
+
"sourceSeq": 1,
|
|
110
|
+
"note": "no_value 必须是正常空结果,空白输出与 idle 不算"
|
|
111
|
+
}
|
|
112
|
+
],
|
|
113
|
+
"mainProactive": [],
|
|
114
|
+
"userReminders": []
|
|
115
|
+
},
|
|
116
|
+
"expect": {
|
|
117
|
+
"wakeReasons": [
|
|
118
|
+
"starved"
|
|
119
|
+
],
|
|
120
|
+
"minBackgroundChecks": 1,
|
|
121
|
+
"coveredLabelIds": [
|
|
122
|
+
"mem-ab-starved-no-value-rule"
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
}
|