dsh-lite-memory 0.18.26 → 0.18.27
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/docs/CONVENTIONS.md +3 -2
- package/docs/RELEASE-0.18.27.md +5 -0
- package/package.json +1 -1
- package/test/contract.test.mjs +4 -0
- package/test/control.test.mjs +2 -0
- package/test/recall.test.mjs +6 -4
- package/test/runtime-context.test.mjs +2 -0
- package/test/view.test.mjs +5 -1
- package/view.js +11 -1
package/docs/CONVENTIONS.md
CHANGED
|
@@ -83,9 +83,10 @@
|
|
|
83
83
|
**范围路由**:模型给的 `scope` 是提案,不是命令。
|
|
84
84
|
|
|
85
85
|
- 显式 `scope="global"` 表示「用户在这一次对话里要求存全局」,只有用户确实这么说才传;模型自己觉得通用不是理由。显式全局不再因为缺少 `evidenceRef` 被降级。
|
|
86
|
-
- 仍然会拦住的两类:设备事实没有条件(`machine` / `targetOs` / `runtime` / `shell`
|
|
86
|
+
- 仍然会拦住的两类:设备事实没有条件(`machine` / `targetOs` / `runtime` / `shell` 至少一个),以及正文或依据里写死本机路径、回环地址、端口却没声明适用环境的「通用流程」——后者换台机器/换个项目就不成立,留在项目层。
|
|
87
|
+
- 声明了上述环境条件的本机流程(例如本机特有的命令包装)可以进全局层:条件不成立的机器上不会拿出来用;命令名/工具名本身不算本机痕迹。
|
|
87
88
|
- `memoryClass="project_fact"` 不因写了 `global` 就变全局:项目事实换个项目本来就不成立。
|
|
88
|
-
- 按类别推导(没有显式 `scope`)保持更严:`portable_procedure` 没有 `evidenceRef
|
|
89
|
+
- 按类别推导(没有显式 `scope`)保持更严:`portable_procedure` 没有 `evidenceRef`、也没有环境条件时落项目层。
|
|
89
90
|
- 每次降级都要能解释:只在降级时返回 `scopeNote` 一行,说明为什么没进全局、怎么改才进得去;正常落全局或落项目不带这行。
|
|
90
91
|
|
|
91
92
|
**限额与腾位**:每层活跃条目软上限 200、硬上限 1000;单条正文 4096 字节;单层总字节 1 MiB。到硬上限时把最久没被读的活跃条目移进归档,并在结果里写明「已归档「标题」腾位」,不拒绝新记忆;单条正文超限只报错、不截断。
|
package/package.json
CHANGED
package/test/contract.test.mjs
CHANGED
|
@@ -460,6 +460,8 @@ const pass = (text, id) => async () => ({
|
|
|
460
460
|
messages: [{ role: 'user', id, source: { kind: 'user' }, content: [{ type: 'text', text }] }],
|
|
461
461
|
});
|
|
462
462
|
const recall = promptContexts.find((entry) => entry.name === 'lite-memory:recall');
|
|
463
|
+
/* CI 冷启动偶尔超过召回耗时上限,逻辑断言不该被「这轮先不注入」判失败。 */
|
|
464
|
+
globalThis.__liteMemoryRecall?.setDeadlineMs?.(5000);
|
|
463
465
|
assert.ok(recall, 'recall context registered');
|
|
464
466
|
assert.equal(recall.order, 60);
|
|
465
467
|
assert.equal(recall.interpolate, false);
|
|
@@ -545,6 +547,8 @@ const evoEnter = async () => ({
|
|
|
545
547
|
});
|
|
546
548
|
await preStep({ agent: evoAgent, signal: evoSig, turn: '21' }, evoEnter);
|
|
547
549
|
const evoRecall = promptContexts.find((entry) => entry.name === 'lite-memory:recall');
|
|
550
|
+
/* CI 冷启动偶尔超过召回耗时上限,逻辑断言不该被「这轮先不注入」判失败。 */
|
|
551
|
+
globalThis.__liteMemoryRecall?.setDeadlineMs?.(5000);
|
|
548
552
|
assert.match(evoRecall.text({ agent: evoAgent, signal: evoSig }), /开场三句内给结论/);
|
|
549
553
|
assert.equal(evoRecall.text({ agent: evoAgent, signal: evoSig }).includes('README'), false);
|
|
550
554
|
|
package/test/control.test.mjs
CHANGED
|
@@ -33,6 +33,8 @@ function boot() {
|
|
|
33
33
|
};
|
|
34
34
|
apply(ctx, { mode: 'adaptive' });
|
|
35
35
|
const provider = promptContexts.find((entry) => entry.name === 'lite-memory:recall');
|
|
36
|
+
/* CI 冷启动偶尔超过召回耗时上限,逻辑断言不该被「这轮先不注入」判失败。 */
|
|
37
|
+
globalThis.__liteMemoryRecall?.setDeadlineMs?.(5000);
|
|
36
38
|
const exec = (name, args, agent) => defs.get(name).execute(args, { agent });
|
|
37
39
|
const preStep = (payload, decision) => handlers.get('agent/pre-step').at(-1)(payload, async () => decision);
|
|
38
40
|
return { exec, preStep, text: (agent, signal) => provider.text({ agent, signal }), debug: globalThis.__liteMemoryRecall };
|
package/test/recall.test.mjs
CHANGED
|
@@ -39,6 +39,8 @@ function boot(mode = 'adaptive') {
|
|
|
39
39
|
apply(ctx, { mode });
|
|
40
40
|
const debug = globalThis.__liteMemoryRecall;
|
|
41
41
|
const provider = promptContexts.find((entry) => entry.name === 'lite-memory:recall');
|
|
42
|
+
/* CI 冷启动偶尔超过召回耗时上限,逻辑断言不该被「这轮先不注入」判失败。 */
|
|
43
|
+
globalThis.__liteMemoryRecall?.setDeadlineMs?.(5000);
|
|
42
44
|
assert.ok(provider, 'recall provider registered');
|
|
43
45
|
assert.equal(provider.order, 60);
|
|
44
46
|
assert.equal(provider.interpolate, false);
|
|
@@ -111,8 +113,8 @@ const linuxOnly = save(scopeA, {
|
|
|
111
113
|
tags: ['插件', '构建'],
|
|
112
114
|
when: '',
|
|
113
115
|
applicability: 'conditional',
|
|
114
|
-
conditions: [{ key: '
|
|
115
|
-
summary: '
|
|
116
|
+
conditions: [{ key: 'machine', value: '别的机器' }],
|
|
117
|
+
summary: '只在另一台机器上跑构建检查',
|
|
116
118
|
});
|
|
117
119
|
const unresolved = save(scopeA, { title: '发布前要检查什么', tags: ['发布', '检查'], when: '发布前', applicability: 'unresolved' });
|
|
118
120
|
const globalHot = save(global, { title: '插件改动后先热刷新', tags: ['插件', '热刷新'], summary: '全局规矩:先热刷新再谈重启' });
|
|
@@ -266,10 +268,10 @@ assert.notEqual(bootA.provider.text({ agent: agentB, signal: signalB }), prepare
|
|
|
266
268
|
const cwdC = mkdir('c');
|
|
267
269
|
const scopeC = store.scopeOf(cwdC);
|
|
268
270
|
save(scopeC, {
|
|
269
|
-
title: '
|
|
271
|
+
title: '只在另一台机器上跑构建检查',
|
|
270
272
|
tags: ['构建'],
|
|
271
273
|
applicability: 'conditional',
|
|
272
|
-
conditions: [{ key: '
|
|
274
|
+
conditions: [{ key: 'machine', value: '别的机器' }],
|
|
273
275
|
});
|
|
274
276
|
save(scopeC, { title: '发布前检查清单', tags: ['发布'], when: '发布前', applicability: 'unresolved' });
|
|
275
277
|
const agent = makeAgent('agent-cond', cwdC);
|
|
@@ -33,6 +33,8 @@ function boot(mode = 'adaptive') {
|
|
|
33
33
|
};
|
|
34
34
|
apply(ctx, { mode });
|
|
35
35
|
const provider = promptContexts.find((entry) => entry.name === 'lite-memory:recall');
|
|
36
|
+
/* CI 冷启动偶尔超过召回耗时上限,逻辑断言不该被「这轮先不注入」判失败。 */
|
|
37
|
+
globalThis.__liteMemoryRecall?.setDeadlineMs?.(5000);
|
|
36
38
|
assert.ok(provider, 'recall provider registered');
|
|
37
39
|
const exec = (name, args, agent) => defs.get(name).execute(args, { agent });
|
|
38
40
|
const preStep = (payload, decision) => handlers.get('agent/pre-step').at(-1)(payload, async () => decision);
|
package/test/view.test.mjs
CHANGED
|
@@ -70,7 +70,11 @@ test('条件裁决:不把不知道当不存在,也不把未解决当普遍
|
|
|
70
70
|
const record = { id: 'mem_000000000001', applicability: 'conditional', conditions: [{ key: 'targetOs', value: 'macOS' }], when: '' };
|
|
71
71
|
assert.equal(view.evaluate(record, ctxOf(null, { targetOs: 'macos' })).state, 'match');
|
|
72
72
|
assert.equal(view.evaluate(record, ctxOf(null, { targetOs: 'linux' })).state, 'mismatch');
|
|
73
|
-
assert.equal(
|
|
73
|
+
assert.equal(ctxOf(null, {}).targetOs, view.hostTargetOs());
|
|
74
|
+
const hostRecord = { ...record, conditions: [{ key: 'targetOs', value: view.hostTargetOs() || 'macos' }] };
|
|
75
|
+
assert.equal(view.evaluate(hostRecord, ctxOf(null, {})).state, 'match');
|
|
76
|
+
const machineOnly = { ...record, conditions: [{ key: 'machine', value: '这台机器' }] };
|
|
77
|
+
assert.equal(view.evaluate(machineOnly, ctxOf(null, {})).state, 'unknown');
|
|
74
78
|
const unresolved = { ...record, applicability: 'unresolved', conditions: [] };
|
|
75
79
|
assert.equal(view.statusOf(unresolved, ctxOf(null, {})), 'needs_context');
|
|
76
80
|
assert.equal(view.canAutoRecall(unresolved, ctxOf(null, {})), false);
|
package/view.js
CHANGED
|
@@ -152,7 +152,8 @@ export function validateApplicability(applicability, conditions, selection, when
|
|
|
152
152
|
export function trustedContext(scope, options = {}) {
|
|
153
153
|
const cwd = typeof options.cwd === 'string' && options.cwd ? options.cwd : (scope && scope.cwd) || '';
|
|
154
154
|
return {
|
|
155
|
-
targetOs
|
|
155
|
+
/** 宿主的真实平台是可信上下文:条件里写 targetOs 的规则本职就是按平台生效。 */
|
|
156
|
+
targetOs: options.targetOs === undefined ? hostTargetOs() : options.targetOs,
|
|
156
157
|
shell: options.shell,
|
|
157
158
|
runtime: options.runtime,
|
|
158
159
|
machine: options.machine,
|
|
@@ -166,6 +167,15 @@ export function trustedContext(scope, options = {}) {
|
|
|
166
167
|
};
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
/** 只报归一化后的平台名;未知平台不硬猜,留给条件判 unknown。 */
|
|
171
|
+
export function hostTargetOs() {
|
|
172
|
+
const platform = typeof process !== 'undefined' && process ? process.platform : '';
|
|
173
|
+
if (platform === 'darwin') return 'macos';
|
|
174
|
+
if (platform === 'win32') return 'windows';
|
|
175
|
+
if (platform === 'linux') return 'linux';
|
|
176
|
+
return '';
|
|
177
|
+
}
|
|
178
|
+
|
|
169
179
|
function sameText(left, right) {
|
|
170
180
|
return plain(left, PATH_CHARS).toLowerCase() === plain(right, PATH_CHARS).toLowerCase();
|
|
171
181
|
}
|