dsh-loadout 0.12.1 → 0.12.2
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 +4 -0
- package/index.js +12 -1
- package/package.json +1 -1
- package/scripts/selftest.mjs +18 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
「装备栏」是一个 DeepSeek Harness 插件:给每个对话选一套工具(套装),只把用得上的工具投给模型。
|
|
4
4
|
|
|
5
|
+
## 0.12.2
|
|
6
|
+
|
|
7
|
+
- **修「绑定到已不存在的套装」**:如果某个对话绑的套装在应用关着的时候被删掉(旧版本、手改 loadout.json、或别的机器同步过来的文件),启动后它会被当成「空套装」套用——等于把这对话的工具连同内置工具一起裁光,只剩 kit_*。现在这种绑定在第一次被读到时回退到「全部」,并把 ssignments 里那个失效名字改成
|
|
8
|
+
ull,日志里留一行说明。回归断言: binding to a deleted kit falls back to 全部(用第二个模块实例模拟重启)。
|
|
5
9
|
## 0.12.1
|
|
6
10
|
|
|
7
11
|
- **修卡死**:编辑(覆盖保存)、重命名或删除一个正在被对话使用的套装时,宿主会遍历「正在用它的对话」并逐个重新套用工具;这个遍历边改边往 `Map` 里重写条目,迭代器被塞回一个已经走过的键,于是永远走不完——表现是界面点下去没有任何反应、进程占满一个核。现在遍历快照(`[...state]`),编辑与删除都会立刻返回。
|
package/index.js
CHANGED
|
@@ -1132,8 +1132,19 @@ export function apply(ctx, config = {}) {
|
|
|
1132
1132
|
*/
|
|
1133
1133
|
function ensureBindingApplied(agent) {
|
|
1134
1134
|
if (agent === undefined || agent === null) return
|
|
1135
|
-
|
|
1135
|
+
let value = ensureBinding(agent)
|
|
1136
1136
|
if (value === undefined) return
|
|
1137
|
+
// A stored binding can name a kit that no longer exists — an older build, a
|
|
1138
|
+
// hand-edited store, or a kit deleted while the app was closed. Applying it
|
|
1139
|
+
// would compute an empty allow list and strip the conversation down to the
|
|
1140
|
+
// kit_* tools, so such a conversation falls back to 全部 and the dangling
|
|
1141
|
+
// name is rewritten to stop it resurfacing on every read.
|
|
1142
|
+
if (value !== null && value !== DEFAULT_DSH && resolveKit(lastAgent, value) === undefined) {
|
|
1143
|
+
book.assignments[sessionIdOf(agent)] = null
|
|
1144
|
+
save()
|
|
1145
|
+
ctx.logger?.warn(`dsh-loadout: 套装「${value}」已不存在,这个对话回到「全部」`)
|
|
1146
|
+
value = null
|
|
1147
|
+
}
|
|
1137
1148
|
const selection = selectionForBinding(value)
|
|
1138
1149
|
const current = state.get(agent)?.selection
|
|
1139
1150
|
if (current !== undefined && sameSelection(current, selection)) return
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-loadout",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "Loadout for DeepSeek Harness: group tools into kits, keep only the current kit's tools visible in each conversation, and manage everything from a settings panel.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
package/scripts/selftest.mjs
CHANGED
|
@@ -846,6 +846,24 @@ try {
|
|
|
846
846
|
check('a preset name cannot be taken by a user kit',
|
|
847
847
|
/预置/u.test(presetClashError ?? ''), presetClashError)
|
|
848
848
|
|
|
849
|
+
// T22: a binding that names a kit removed outside the app falls back to 全部.
|
|
850
|
+
// Simulated the way it really happens: the kit is gone from the store file when
|
|
851
|
+
// the app starts again, so a fresh module instance has to cope with it.
|
|
852
|
+
await ctxV2.registered.get('kit_create').execute(
|
|
853
|
+
{ name: 'ghost-kit', title: '已删除的', builtins: ['read'], plugins: [] }, exec(agentB))
|
|
854
|
+
await ctxV2.registered.get('kit_assign').execute({ sessionId: 'session-ghost', kit: 'ghost-kit' }, exec(agentB))
|
|
855
|
+
const storeWithGhost = storeOf()
|
|
856
|
+
storeWithGhost.kits = storeWithGhost.kits.filter((kit) => kit.name !== 'ghost-kit')
|
|
857
|
+
writeFileSync(join(v2Home, '.dsh', 'loadout.json'), JSON.stringify(storeWithGhost), 'utf8')
|
|
858
|
+
const v2b = await import('../index.js?v2=2')
|
|
859
|
+
const ctxV2b = makeCtx()
|
|
860
|
+
v2b.apply(ctxV2b, { defaultKit: '', kits: config.kits })
|
|
861
|
+
const agentGhost = makeAgent(undefined, { id: 'session-ghost' })
|
|
862
|
+
for (const handler of ctxV2b.handlers.get('agent/created') ?? []) handler(agentGhost)
|
|
863
|
+
check('a binding to a deleted kit falls back to 全部',
|
|
864
|
+
storeOf().assignments['session-ghost'] === null && keptOf(agentGhost).includes('web_search'),
|
|
865
|
+
JSON.stringify({ assignments: storeOf().assignments, kept: keptOf(agentGhost) }))
|
|
866
|
+
|
|
849
867
|
// T03/T05: the default changes again; conversations that already answered keep theirs.
|
|
850
868
|
const agentC = makeAgent(undefined, { id: 'session-c' })
|
|
851
869
|
await ctxV2.registered.get('kit_set_default').execute({ name: 'chat' }, exec(agentB))
|