dsh-experience 1.1.1 → 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/CHANGELOG.md +14 -0
- package/README.md +2 -0
- package/index.js +4 -2
- package/lib/recall.js +23 -0
- package/package.json +1 -1
- package/tools/selftest.mjs +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [1.2.0] — 2026-11-09 — 计划任务召回与已知问题清单
|
|
5
|
+
|
|
6
|
+
### 修复
|
|
7
|
+
- **计划任务的轮次召回为空**:这类会话的第一条消息是 `[SCHEDULE REMINDER] … reminder_prompt_json: "…"`,
|
|
8
|
+
整段被当成查询词,搜到的是 "schedule"。新增 `stripReminder()`,从包装里取出真实 prompt 再分词;
|
|
9
|
+
原文保留在 `trace.queryRaw`。测试 T84。
|
|
10
|
+
|
|
11
|
+
### 新增
|
|
12
|
+
- `docs/KNOWN-ISSUES.md`:八条已知问题,按"会不会让经验变错"排序,每条写症状/影响/现状/绕法
|
|
13
|
+
(含 shell 落盘不算写、`set_bundle` 不重载、召回只在第 1 步、纯词面检索、单机单用户等)。
|
|
14
|
+
|
|
15
|
+
### 测试
|
|
16
|
+
- `selftest 94 pass / 0 fail`、`e2e 23 pass / 0 fail`。
|
|
17
|
+
|
|
4
18
|
## [1.1.1] — 2026-11-09 — 构建标识修正
|
|
5
19
|
|
|
6
20
|
- `BUILD` 从 `r20-scope-tools` 改为 `r21-platform`。1.1.0 的代码已含平台隔离,但包内构建标识还是上一个版本号,
|
package/README.md
CHANGED
package/index.js
CHANGED
|
@@ -35,7 +35,7 @@ const PROBE_FILE = path.join(STORE_DIR, 'probe.json')
|
|
|
35
35
|
const THRESHOLD = 0.15
|
|
36
36
|
const MAX_EXPERIENCES = 2
|
|
37
37
|
const MAX_CHARS = 1600
|
|
38
|
-
const BUILD = '
|
|
38
|
+
const BUILD = 'r22-reminder'
|
|
39
39
|
|
|
40
40
|
let CONFIG = { ...C.DEFAULT_CONFIG }
|
|
41
41
|
|
|
@@ -286,7 +286,8 @@ export function apply(ctx) {
|
|
|
286
286
|
const step = payload.step
|
|
287
287
|
if (!id || step !== 1) return
|
|
288
288
|
|
|
289
|
-
const
|
|
289
|
+
const rawQuery = (payload.messages || []).map(textOfMessage).join('\n')
|
|
290
|
+
const queryText = R.stripReminder(rawQuery)
|
|
290
291
|
const queryTokens = tokens(queryText)
|
|
291
292
|
const index = R.corpus(store.experiences)
|
|
292
293
|
const scored = store.experiences
|
|
@@ -310,6 +311,7 @@ export function apply(ctx) {
|
|
|
310
311
|
endedAt: null,
|
|
311
312
|
steps: 0,
|
|
312
313
|
query: queryText.slice(0, 400),
|
|
314
|
+
queryRaw: rawQuery === queryText ? undefined : rawQuery.slice(0, 400),
|
|
313
315
|
queryTokens: [...queryTokens].slice(0, 40),
|
|
314
316
|
candidates,
|
|
315
317
|
threshold: threshold(),
|
package/lib/recall.js
CHANGED
|
@@ -87,6 +87,29 @@ export function expand(text) {
|
|
|
87
87
|
return out
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
/**
|
|
91
|
+
* A scheduled turn starts with its delivery wrapper ("[SCHEDULE REMINDER] ...
|
|
92
|
+
* reminder_prompt_json: \"...\""). Searching that text finds the word
|
|
93
|
+
* "schedule" and nothing else, so recall reads the wrapped prompt instead.
|
|
94
|
+
*/
|
|
95
|
+
export function stripReminder(text) {
|
|
96
|
+
const raw = String(text || '')
|
|
97
|
+
if (!raw.includes('[SCHEDULE REMINDER]')) return raw
|
|
98
|
+
const spoiled = /reminder_prompt_json:\s*("(?:[^"\\]|\\.)*")/s.exec(raw)
|
|
99
|
+
if (spoiled) {
|
|
100
|
+
try {
|
|
101
|
+
const prompt = JSON.parse(spoiled[1])
|
|
102
|
+
if (prompt) return String(prompt)
|
|
103
|
+
} catch {
|
|
104
|
+
/* keep the raw text when the JSON is not what we expect */
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return raw
|
|
108
|
+
.split('\n')
|
|
109
|
+
.filter((line) => !/^\s*\[SCHEDULE REMINDER\]/.test(line) && !/^\s*(schedule_id_json|occurrence_at|reminder_prompt_json)\s*:/.test(line))
|
|
110
|
+
.join('\n')
|
|
111
|
+
}
|
|
112
|
+
|
|
90
113
|
/** The searchable profile of a stored experience. */
|
|
91
114
|
export function profileText(experience) {
|
|
92
115
|
if (!experience) return ''
|
package/package.json
CHANGED
package/tools/selftest.mjs
CHANGED
|
@@ -1198,6 +1198,16 @@ test('T83 a recipe from another OS is never merged and never recalled', () => {
|
|
|
1198
1198
|
assert.equal(C.platformConflicts({}), false)
|
|
1199
1199
|
})
|
|
1200
1200
|
|
|
1201
|
+
test('T84 a scheduled wrapper yields the task, not the wrapper', () => {
|
|
1202
|
+
const wrapped = '[SCHEDULE REMINDER]\nThis is a scheduled message from the user\nschedule_id_json: "schedule-1"\noccurrence_at: 2026-11-09T02:57:00.000Z\nreminder_prompt_json: "在 D:\\\\work\\\\platgate 下创建 platgate.js 并运行"'
|
|
1203
|
+
const task = R.stripReminder(wrapped)
|
|
1204
|
+
assert.equal(task, '在 D:\\work\\platgate 下创建 platgate.js 并运行')
|
|
1205
|
+
const tokens = R.expand(task)
|
|
1206
|
+
assert.ok(tokens.has('platgate'))
|
|
1207
|
+
assert.ok(!tokens.has('schedule'))
|
|
1208
|
+
assert.equal(R.stripReminder('普通任务'), '普通任务')
|
|
1209
|
+
})
|
|
1210
|
+
|
|
1201
1211
|
// ---------------------------------------------------------------- summary
|
|
1202
1212
|
|
|
1203
1213
|
const total = pass + failures.length
|