dsh-team-model-policy 0.10.2 → 0.10.3

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.
Files changed (3) hide show
  1. package/README.md +12 -4
  2. package/index.mjs +21 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,19 +4,21 @@
4
4
 
5
5
  ## 安装
6
6
 
7
- 本版仅支持 **DSH 0.2.2-rc.1**。先升级 DSH,再在“插件”页面通过以下公开地址安装:
7
+ 本版仅支持 **DSH 0.2.2-rc.1**。先升级 DSH,再在“插件”页面输入以下 npm 包名安装:
8
8
 
9
9
  ```text
10
- https://github.com/kogekiplay/dsh-team-model-policy/archive/refs/tags/v0.10.2.tar.gz
10
+ dsh-team-model-policy
11
11
  ```
12
12
 
13
+ 通过 npm 注册表安装后,可在插件详情页使用原生“检查更新”。需要固定版本时使用 `dsh-team-model-policy@版本号`。GitHub 标签归档仍可作为备用来源,但从归档安装不会启用原生更新区域。
14
+
13
15
  安装包已包含构建好的界面资源,不需要安装脚本或本地编译。升级后重新打开插件详情;如果已打开的界面仍显示旧内容,刷新当前 DSH 窗口即可。
14
16
 
15
17
  ## 原生检查更新
16
18
 
17
19
  DSH 的原生“检查更新”只适用于**通过 npm 注册表、以插件自身名称安装的第三方包**。从 GitHub 归档、Git 地址或本地目录安装时,不显示该更新区域;设置 `repository` 或发布 Git 标签不会自动启用它。
18
20
 
19
- 本插件已准备公开 npm 发布配置。首次发布并在 DSH 中把安装来源切换为 `dsh-team-model-policy@版本号` 后,后续版本会出现在插件详情页的 **版本 → 检查更新** 中。请以 npm 注册表实际可查询到的版本为准;仅有 Git 标签不代表 npm 已发布。
21
+ 本插件已在 npm 公开发布。从 npm 安装后,后续版本会出现在插件详情页的 **版本 → 检查更新** 中。请以 npm 注册表实际可查询到的版本为准;仅有 Git 标签不代表 npm 已发布。
20
22
 
21
23
  原生更新先检查目标版本与当前 DSH 的兼容性,不兼容的版本会被标出。插件不会自行轮询、自动下载安装或绕过 DSH 的版本检查。
22
24
 
@@ -131,6 +133,12 @@ v0.10 系列已适配新的模型选择接口、会话投影句柄和模型目
131
133
 
132
134
  模型选择在步骤准备前通过原生 `agent.model.select()` 记录。已经为某一步捕获的选择保持不变,稍后的更新用于下一步,不再通过旧的 `agent/request` 钩子修改模型。
133
135
 
136
+ ## 大历史会话与内存
137
+
138
+ v0.10.3 起,补充离线队员模型信息的历史读取在整个插件内最多同时进行一次,前一个句柄关闭后才开始下一个;同时按新版存储句柄提供的继承边界读取,避免把父会话模型误当成成员自己的模型。取消和卸载会等待已开始的读取关闭,排队的已取消请求不会再打开历史。
139
+
140
+ DSH 0.2.2-rc.1 的 JSONL 后端即使只请求事件切片,也可能完整解码一份历史。因此,该修复消除多份历史并行解码造成的峰值叠加,但不保证单份超长历史在低内存环境中可以加载,也不代表全部 Host OOM 已被归因或解决。长期任务宜保留进度摘要并在新会话中继续,减少同时保留的超长历史会话;无需删除原始历史。
141
+
134
142
  ## 禁用与重启
135
143
 
136
144
  禁用插件前会等待插件已接收的操作收敛,然后释放相关监听、工具和界面入口。已移除的子会话仍保持归档,但原生历史名册和子智能体目录会重新显示;再次启用插件后恢复过滤。
@@ -157,7 +165,7 @@ v0.10 系列已适配新的模型选择接口、会话投影句柄和模型目
157
165
 
158
166
  ## 验证与开发
159
167
 
160
- v0.10.0 适配已通过 **74 项单元/组件测试和 28 个目标运行时场景**,覆盖模型选择、动态授权、切换、普通与 PTC 权限同步、任务移除、名额复用、子智能体清理和冷恢复。v0.10.1 补齐中文说明。v0.10.2 区分授权组件未加载与用户关闭模型选择,并补齐 npm 公开发布配置;本次通过 19 项针对性单元测试和 12 个目标运行时场景,客户端构建产物保持一致。
168
+ v0.10.0 适配已通过 **74 项单元/组件测试和 28 个目标运行时场景**,覆盖模型选择、动态授权、切换、普通与 PTC 权限同步、任务移除、名额复用、子智能体清理和冷恢复。v0.10.1 补齐中文说明。v0.10.2 区分授权组件未加载与用户关闭模型选择,并补齐 npm 公开发布配置;本次通过 19 项针对性单元测试和 12 个目标运行时场景,客户端构建产物保持一致。v0.10.3 限制冷历史读取的全局并发,修正存储句柄继承边界的读取位置,通过 79 项单元/组件测试和 12 个目标运行时场景;该验证不等于全部 Host OOM 已被解决。
161
169
 
162
170
  测试使用隔离环境和专用团队。只有模型输出采用脚本,其余 Loader、工具、团队生命周期和持久化使用真实目标实现。迁移测试使用官方 V3→V4 转换器,并检查旧缓存重建和已移除对象的恢复阻止。桌面截图与实际点击验证会单独记录,不与自动测试混为一谈。
163
171
 
package/index.mjs CHANGED
@@ -125,6 +125,26 @@ export function apply(ctx, config) {
125
125
  }
126
126
  return undefined;
127
127
  };
128
+ // One persisted history at a time across all rosters. JSONL backends may decode
129
+ // the complete log even for a slice, so parallel cold reads multiply peak memory.
130
+ let coldReadTail = Promise.resolve();
131
+ const readColdModel = (id, signal) => {
132
+ const operation = coldReadTail.then(async () => {
133
+ signal.throwIfAborted();
134
+ const handle = await ctx.sessionPersistence.open(id, 'read', { signal });
135
+ try {
136
+ const offset = handle.inheritedEventCount;
137
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new TeamModelPolicyError('The stored teammate handle has no valid inherited event count.', 'UNSUPPORTED_RUNTIME');
138
+ const stored = await handle.read(offset, undefined, { signal });
139
+ signal.throwIfAborted();
140
+ return lastRequest(stored.events);
141
+ } finally {
142
+ await handle.close();
143
+ }
144
+ });
145
+ coldReadTail = operation.then(() => undefined, () => undefined);
146
+ return operation;
147
+ };
128
148
  const fixMember = async (row, members, signal) => {
129
149
  const member = members.find(candidate => candidate.name === row.target);
130
150
  if (member === undefined || member.status === 'failed' || member.status === 'provisioning') return row;
@@ -133,14 +153,7 @@ export function apply(ctx, config) {
133
153
  if (live !== undefined) {
134
154
  actual = lastRequest(live.session.snapshotEvents(live.session.inheritedEventCount));
135
155
  } else {
136
- const handle = await ctx.sessionPersistence.open(member.id, 'read', { signal });
137
- try {
138
- const stored = await handle.read();
139
- signal.throwIfAborted();
140
- actual = lastRequest(stored.events.slice(stored.inheritedEventCount));
141
- } finally {
142
- await handle.close();
143
- }
156
+ actual = await readColdModel(member.id, signal);
144
157
  }
145
158
  const { model: _oldModel, ...rest } = row;
146
159
  const planned = member.role === 'teammate' ? await configuredRoute(members.caller, member, false) : live?.model?.current() ?? live?.options;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-team-model-policy",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "Configure teammate models and manually retire ordinary subagents or Team members while retaining conversation history.",
5
5
  "type": "module",
6
6
  "main": "./ui.mjs",