pi-shadow-mind 0.1.19 → 0.1.20
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/DESIGN-Evolution.md +18 -0
- package/DESIGN.md +13 -7
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/index.js +354 -33
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/DESIGN-Evolution.md
CHANGED
|
@@ -37,3 +37,21 @@
|
|
|
37
37
|
- 发生:早期讨论包含产品隐喻、内置编辑体验和可观测性扩展等非运行时主线内容。
|
|
38
38
|
- 分析:“多核”“章鱼”等隐喻适合产品表达但不拥有架构语义;Markdown 编辑器和日志轮转需要先由真实使用证明价值。
|
|
39
39
|
- 改变:`DESIGN.md` 只保留当前运行时契约;隐喻退出技术定义,编辑体验、日志轮转及其他尚未验证的扩展保留在本变更历史中。
|
|
40
|
+
|
|
41
|
+
## 2026-09-07 · 对齐 ACP 持久压缩视图
|
|
42
|
+
|
|
43
|
+
- 发生:PR #6 报告 ACP 已压缩的 Main 会话仍向 Shadow 提供原始历史,触发上下文超限;审查进一步复现多工具调用、自定义报告漏压缩和 `null` 状态文件异常。
|
|
44
|
+
- 分析:ACP 将状态写入独立文件,多工具调用使用 `entryId#toolCallId`;仅按原始会话 entry ID 替换会漏掉覆盖内容,并可能在非当前分支或原生 compaction 之前消耗摘要锚点。Pi 原生摘要使用 `summary` 字段,旧序列化器只读取 `content` 也会丢失摘要正文。
|
|
45
|
+
- 改变:将状态校验与上下文投影分离,在当前原生上下文上折叠 ACP 覆盖内容,保留部分工具调用并清理孤立工具对;补齐分支、解压、嵌套块、异常文件及原生摘要回归。实现参考 billion-context-pi `55afd556` 的消息 ID 映射和 acp-kernel `4216937a` 的首条用户消息保护及工具配对规则。当前适配不执行 ACP 的动态 nudge、紧急截断或其他扩展 hooks,也不承诺复现任意扩展的最终请求载荷。
|
|
46
|
+
|
|
47
|
+
## 2026-09-07 · 在配置刷新后执行 heartbeat 工具过滤
|
|
48
|
+
|
|
49
|
+
- 发生:PR #7 增加全局 `heartbeat_tools` 和单个 Shadow 的 `activation_tools`,用于减少不相关工具轮次上的唤醒。
|
|
50
|
+
- 分析:初版先按内存中的旧过滤器判断,再刷新配置;放宽限制时可能持续被旧配置拦截,收紧限制时则会多进入一次抽选。管理工具只写入配置文件,同样受此顺序影响。
|
|
51
|
+
- 改变:事件入口只跳过无工具活动的轮次,heartbeat 编排刷新一次配置后统一执行工具过滤和概率判断。新增真实配置文件回归,覆盖放宽、收紧、清空、连续过滤、无工具轮次和无效配置回退;确认 final-response 资格保持独立。
|
|
52
|
+
|
|
53
|
+
## 2026-09-07 · 分离报告历史与常驻状态面板
|
|
54
|
+
|
|
55
|
+
- 发生:PR #9 将报告正文挂到最近运行下;审计复现报告被后续沉默运行挤出视图、长报告生成超高常驻组件,以及面板关闭时显示命令只提示成功。
|
|
56
|
+
- 分析:最近运行与最近交付报告是不同的保留口径;常驻摘要面板也不适合承载完整正文。继续在 Runtime 中叠加可见性状态、命令解析和正文排版会扩大入口职责。
|
|
57
|
+
- 改变:ReportHistory 独立按交付保留 5 份报告,ReportBrowser 管理命令与会话生命周期,ReportViewer 提供限高滚动快照。定向回归经过实际交付、命令和组件渲染,验证 200 行正文完整可达、终端缩放、关闭重开、会话重置及非 TUI 模式。
|
package/DESIGN.md
CHANGED
|
@@ -65,7 +65,7 @@ Shadow 定义统一从全局目录加载:
|
|
|
65
65
|
|
|
66
66
|
该目录属于用户数据,不放入插件安装目录,也不随当前项目切换。插件级配置保存在 `config.json`;registry 只扫描目录顶层的 `.md` 文件,不读取 `config.json`,也不递归读取 `logs/`。
|
|
67
67
|
|
|
68
|
-
`config.json` 保存默认 Shadow 模型、`default_thinking_level`、`heartbeat_probability`、`max_parallel_shadows`、`default_shadow_timeout_seconds`、`headless_drain_timeout_seconds`、`result_batch_window_ms` 和可选的 `random_seed` 等全局调度配置。`default_shadow_model` 省略时,插件使用激活时的当前 Main 模型;用户也可以配置一个固定默认模型。`default_thinking_level` 的内置默认值为 `low`。
|
|
68
|
+
`config.json` 保存默认 Shadow 模型、`default_thinking_level`、`heartbeat_probability`、`heartbeat_tools`、`max_parallel_shadows`、`default_shadow_timeout_seconds`、`headless_drain_timeout_seconds`、`result_batch_window_ms` 和可选的 `random_seed` 等全局调度配置。`default_shadow_model` 省略时,插件使用激活时的当前 Main 模型;用户也可以配置一个固定默认模型。`default_thinking_level` 的内置默认值为 `low`。
|
|
69
69
|
|
|
70
70
|
每次 heartbeat 判断或 final-response 调度前,插件检查并重新加载发生变化的 `config.json`。纯文本轮次不会进入 heartbeat,但 Main 的最终文字可以触发 final-response 检查。新配置只影响后续调度和新建实例;已经运行的 Shadow 继续使用启动时取得的配置快照。
|
|
71
71
|
|
|
@@ -109,6 +109,7 @@ frontmatter 包含以下运行字段:
|
|
|
109
109
|
| `debug` | 是否保存完整 Shadow Session 日志;默认 `false` |
|
|
110
110
|
| `activation_probability` | 每次 heartbeat 时独立激活的概率,范围为 `0` 到 `1`;默认 `0.3`,不影响 final_response |
|
|
111
111
|
| `trigger` | 激活方式,可包含 `heartbeat`、`final_response` 或两者;默认 `[heartbeat]` |
|
|
112
|
+
| `activation_tools` | heartbeat 候选工具过滤;该 Main 轮次命中任意指定工具名即可,默认 `[]` 表示不限制;final_response 独立于此过滤 |
|
|
112
113
|
| `active_for_models` | 适用于哪些 Main 模型;`"*"` 表示全部模型,省略时默认 `["*"]` |
|
|
113
114
|
| `run_with_model` | Shadow 自己使用的模型;省略时使用插件默认模型 |
|
|
114
115
|
| `thinking_level` | Shadow 使用的 thinking level;省略时使用插件默认值,再回退到 Main 会话当前生效等级 |
|
|
@@ -241,6 +242,8 @@ Main system prompt
|
|
|
241
242
|
|
|
242
243
|
这里的“全部历史”以 Main 激活时实际可见的上下文为准。Main 已发生 compaction 时,Shadow 继承压缩后的上下文,不绕过 compaction 读取已被替换的原始消息。
|
|
243
244
|
|
|
245
|
+
ACP(Active Context Pruning,billion-context-pi)的持久压缩由独立上下文适配器处理:先解析当前分支及原生 compaction,再读取当前会话 `.acp.json` 中的有效压缩块,将可见范围内的覆盖内容替换为摘要。适配范围包含普通消息、自定义消息和单条消息中的部分工具调用,并保留 ACP 的首条用户消息保护。每次激活重新读取状态,以反映后续压缩和解压;无可用状态时沿用 Pi 原生上下文。该适配器的职责是投影持久压缩历史,Main 的其他扩展上下文变换仍由对应扩展负责。
|
|
246
|
+
|
|
244
247
|
Shadow 直接使用 Main 上下文的完整净化子集。如果某个 Shadow 配置的 `run_with_model` 上下文窗口更小而无法容纳轨迹,则该次激活失败并记录原因,不生成介入消息。
|
|
245
248
|
|
|
246
249
|
以下内容不进入 Shadow 上下文:
|
|
@@ -286,7 +289,7 @@ shell({ command: "npm test" }) · 失败,12 项通过、2 项失败
|
|
|
286
289
|
|
|
287
290
|
### 5.1 Heartbeat
|
|
288
291
|
|
|
289
|
-
Heartbeat 使用“工具轮次 + 随机概率”作为调度信号。Main model call
|
|
292
|
+
Heartbeat 使用“工具轮次 + 工具过滤 + 随机概率”作为调度信号。Main model call 完成后,该 `turn_end` 至少包含一个已完成的工具调用时,先刷新配置和 registry,再按同一份配置判断 `heartbeat_tools` 与 `heartbeat_probability`。`heartbeat_tools` 默认 `[]`,表示任意工具;非空时,该轮命中列表中任意一个精确工具名即可参与概率抽选。未通过工具过滤的轮次记录 `tool-filtered` 并跳过随机抽样。默认概率为 `1/3`:
|
|
290
293
|
|
|
291
294
|
```text
|
|
292
295
|
P(heartbeat after eligible tool-bearing turn) = heartbeat_probability
|
|
@@ -306,9 +309,10 @@ heartbeat 发生时:
|
|
|
306
309
|
1. 读取当前 Main 模型。
|
|
307
310
|
2. 筛选 `enabled: true` 且 `active_for_models` 匹配的 Shadow。
|
|
308
311
|
3. 排除当前正在运行的同一 Shadow。
|
|
309
|
-
4.
|
|
310
|
-
5.
|
|
311
|
-
6.
|
|
312
|
+
4. 根据各 Shadow 的 `activation_tools` 筛选候选:默认 `[]` 不限制,非空时要求该轮命中任意指定工具名;未匹配项记录在 `toolFiltered`。
|
|
313
|
+
5. 每个剩余 Shadow 按自己的 `activation_probability` 独立判断是否激活。
|
|
314
|
+
6. 如果命中项超过 `max_parallel_shadows`,从中随机选择允许的数量。
|
|
315
|
+
7. 并行创建运行实例并传入各自的净化轨迹。
|
|
312
316
|
|
|
313
317
|
一次 heartbeat 可能不激活任何 Shadow,也可能激活一个或多个。一次 heartbeat 不等待 Shadow 完成,Main 继续工作。
|
|
314
318
|
|
|
@@ -322,7 +326,7 @@ available_slots = max_parallel_shadows - running_shadow_count
|
|
|
322
326
|
|
|
323
327
|
命中数量超过剩余槽位时,未被随机选中的 Shadow 直接跳过,不进入等待队列,也不保留本次轨迹快照。后续 heartbeat 会基于届时的最新上下文重新判断。
|
|
324
328
|
|
|
325
|
-
`activation_probability` 表示 heartbeat 已经发生之后,该 Shadow 被选中的基础概率。因此某个 Shadow
|
|
329
|
+
`activation_probability` 表示 heartbeat 已经发生之后,该 Shadow 被选中的基础概率。因此某个 Shadow 在单次通过全局与自身工具过滤的 Main 工具轮次后获得激活机会的基础概率为:
|
|
326
330
|
|
|
327
331
|
```text
|
|
328
332
|
P(activation) = heartbeat_probability × activation_probability
|
|
@@ -336,7 +340,7 @@ Main 在会话中切换模型后,后续 heartbeat 直接依据新模型重新
|
|
|
336
340
|
|
|
337
341
|
### 5.2 Final response
|
|
338
342
|
|
|
339
|
-
配置了 `final_response` 的 Shadow 在 Main 发出非空最终文字,并进入 `agent_settled` 状态后参与调度。该模式仍应用 `enabled` 和 `active_for_models
|
|
343
|
+
配置了 `final_response` 的 Shadow 在 Main 发出非空最终文字,并进入 `agent_settled` 状态后参与调度。该模式仍应用 `enabled` 和 `active_for_models`,其候选资格独立于 `heartbeat_tools`、`activation_tools`、`heartbeat_probability` 与 `activation_probability`,所有匹配项都必须获得一次运行机会。
|
|
340
344
|
|
|
341
345
|
最终回复检查使用当时的完整净化轨迹快照。`max_parallel_shadows` 仍是硬并发上限;没有空闲槽位或同一 Shadow 正在运行时,检查进入专用队列,槽位释放后继续执行。旧 epoch 的运行释放槽位时同样继续泵送当前队列,避免跨 epoch 的异步收尾把检查永久卡住。
|
|
342
346
|
|
|
@@ -434,6 +438,8 @@ Shadow 的临时 AgentSession 不跨激活复用,也不写回记忆。
|
|
|
434
438
|
|
|
435
439
|
插件提供 `Alt+S` 快捷键以及 `/shadow toggle`、`/shadow pause`、`/shadow resume` 命令,控制当前 Main Session 是否继续产生 heartbeat 或 final-response 检查,不修改全局 Shadow Markdown。执行 pause 时立即中止当前 Session 已运行的 Shadow、清空排队检查和尚未发送的聚合结果并释放并发槽位;resume 后恢复后续调度。暂停时底部状态固定显示 `🐙 Paused`,不展示恒为零的运行数量。
|
|
436
440
|
|
|
441
|
+
报告查看由独立的 ReportBrowser 拥有命令、查看器生命周期与最近交付历史,Runtime 只转发交付结果、命令和会话重置。历史按交付顺序保留最近 5 份报告及其交付时间,与最近运行列表独立。TUI 中 `/shadow reports` 直接打开完整正文快照,查看器按终端尺寸限高并支持逐行、翻页及首尾滚动;Escape 或 `/shadow reports hide` 关闭。状态面板继续展示紧凑运行摘要。报告查看只使用当前 Session 的内存历史,切换会话或 reload 时关闭查看器并清空历史;持久化报告由原有会话记录承载。
|
|
442
|
+
|
|
437
443
|
同一个 Shadow 在前一次实例仍运行时不重复激活;不同 Shadow 可以并行运行。
|
|
438
444
|
|
|
439
445
|
前一次实例结束后,同一个 Shadow 可以在同一用户 epoch 内被后续 heartbeat 再次激活,不设置每 epoch 次数上限。每次仍创建全新的临时 AgentSession,并取得激活时刻的最新完整净化轨迹。
|
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ This Shadow is read-only. It reviews the implementation in parallel and reports
|
|
|
70
70
|
|
|
71
71
|
## How it works
|
|
72
72
|
|
|
73
|
-
Each Shadow chooses one or both activation triggers with `trigger`. The default is `[heartbeat]`: after a main-agent `turn_end` that completed at least one tool call, the extension evaluates the global heartbeat probability, then eligible Shadows roll independently using `activation_probability`. Pure text-only conversation turns are skipped.
|
|
73
|
+
Each Shadow chooses one or both activation triggers with `trigger`. The default is `[heartbeat]`: after a main-agent `turn_end` that completed at least one tool call, the extension evaluates the global heartbeat probability, then eligible Shadows roll independently using `activation_probability`. Pure text-only conversation turns are skipped. The global configuration `heartbeat_tools` restricts which Main tools can trigger a heartbeat evaluation; individual Shadows can use `activation_tools` to restrict their own heartbeat eligibility. Both default to `[]` (no filtering) and match any listed tool by exact name, e.g. `[edit, write]`. Config is refreshed before filtering each tool-bearing turn. These filters apply only to heartbeat, not `final_response`, and are separate from `tools`, which grants tools to the Shadow itself.
|
|
74
74
|
|
|
75
75
|
Use `trigger: [final_response]` for completion review. It activates after the main agent has emitted its final text and bypasses both heartbeat and activation probability. All checks for that final response finish before their findings are sent together through one `shadow-report` follow-up, so a slow sibling cannot leak into a revised answer. `trigger: [heartbeat, final_response]` enables both modes. `max_parallel_shadows` remains the concurrency limit; excess final-response checks are queued rather than skipped.
|
|
76
76
|
|
|
@@ -97,7 +97,7 @@ On the first session start, the extension creates:
|
|
|
97
97
|
|
|
98
98
|
No default Shadow Mind is created. The global runtime timeout defaults to 300 seconds, and individual Shadows may override it with `timeout_seconds`.
|
|
99
99
|
|
|
100
|
-
Press `F6` or `Alt+S` to pause or resume Shadow Mind for the current session. On macOS, you may need `Fn+F6`; `Alt+S` corresponds to `Option+S` and depends on the terminal's Option key mapping. The paused footer reads `🐙 Paused` without a redundant zero count. Use `/shadow` to toggle the status panel, `/shadow status` for a summary, or `/shadow toggle`, `/shadow pause`, and `/shadow resume` for command-based control. Management tools can list, create, update, enable, disable, and delete Shadow Minds, as well as read or update the global configuration. Every write requires user confirmation.
|
|
100
|
+
Press `F6` or `Alt+S` to pause or resume Shadow Mind for the current session. On macOS, you may need `Fn+F6`; `Alt+S` corresponds to `Option+S` and depends on the terminal's Option key mapping. The paused footer reads `🐙 Paused` without a redundant zero count. Use `/shadow` to toggle the status panel, `/shadow status` for a summary, or `/shadow toggle`, `/shadow pause`, and `/shadow resume` for command-based control. In TUI mode, `/shadow reports` opens a bounded, scrollable viewer for the five most recently delivered reports, independent of the recent-run list. Use ↑/↓, PageUp/PageDown, or Home/End to scroll; Escape or `/shadow reports hide` closes it. The viewer shows a snapshot; reopen to see new deliveries. Report history is session-local and clears on session replacement or reload; persisted reports remain in the conversation. The status panel keeps its compact summary. Management tools can list, create, update, enable, disable, and delete Shadow Minds, as well as read or update the global configuration. Every write requires user confirmation.
|
|
101
101
|
|
|
102
102
|
## Using with DSH
|
|
103
103
|
|
package/README.zh-CN.md
CHANGED
|
@@ -67,7 +67,7 @@ tools: [read, grep]
|
|
|
67
67
|
|
|
68
68
|
## 工作方式
|
|
69
69
|
|
|
70
|
-
每个 Shadow 可以通过 `trigger` 选择一种或两种激活方式。默认值是 `[heartbeat]`:主 Agent 的一次 `turn_end` 只有在该轮至少完成过一个工具调用时,扩展才进行全局 heartbeat 概率判断,符合条件的 Shadow 再按照各自的 `activation_probability` 独立抽选。纯文本对话轮次不会触发 heartbeat
|
|
70
|
+
每个 Shadow 可以通过 `trigger` 选择一种或两种激活方式。默认值是 `[heartbeat]`:主 Agent 的一次 `turn_end` 只有在该轮至少完成过一个工具调用时,扩展才进行全局 heartbeat 概率判断,符合条件的 Shadow 再按照各自的 `activation_probability` 独立抽选。纯文本对话轮次不会触发 heartbeat。全局配置 `heartbeat_tools` 限定哪些 Main 工具可以触发心跳判断;单个 Shadow 的 `activation_tools` 限定它自己的 heartbeat 候选资格。两者默认 `[]`(不限制),按工具名精确匹配,命中列表中任意一个即可,例如 `[edit, write]`。每个工具轮次先刷新配置再过滤。这两个过滤项只影响 heartbeat,不影响 `final_response`,也不同于授权 Shadow 自己使用工具的 `tools`。
|
|
71
71
|
|
|
72
72
|
使用 `trigger: [final_response]` 可以进行完成后审查。它在主 Agent 发出最终文字并完全 settled 后激活,不受 heartbeat 和 `activation_probability` 影响。同一最终回复的全部检查结束后,发现会合并为一次 `shadow-report` follow-up,较慢的同批检查不会介入已经修订的回复。`trigger: [heartbeat, final_response]` 会同时启用两种模式。`max_parallel_shadows` 仍然限制并发数;超出并发槽位的最终回复检查会排队,而不会被跳过。
|
|
73
73
|
|
|
@@ -94,7 +94,7 @@ pi install npm:pi-shadow-mind
|
|
|
94
94
|
|
|
95
95
|
扩展不会默认创建 Shadow Mind。全局默认运行超时为 300 秒,单个 Shadow 可以通过 `timeout_seconds` 覆盖。
|
|
96
96
|
|
|
97
|
-
按 `F6` 或 `Alt+S` 可以暂停或恢复当前 Session 的 Shadow Mind。macOS 上可能需要按 `Fn+F6`;`Alt+S` 对应 `Option+S`,是否生效取决于终端的 Option 键映射。暂停时底部状态显示为 `🐙 Paused`,不再显示没有信息量的零计数。使用 `/shadow` 显示或隐藏状态面板,`/shadow status` 查看摘要,也可以通过 `/shadow toggle`、`/shadow pause` 和 `/shadow resume`
|
|
97
|
+
按 `F6` 或 `Alt+S` 可以暂停或恢复当前 Session 的 Shadow Mind。macOS 上可能需要按 `Fn+F6`;`Alt+S` 对应 `Option+S`,是否生效取决于终端的 Option 键映射。暂停时底部状态显示为 `🐙 Paused`,不再显示没有信息量的零计数。使用 `/shadow` 显示或隐藏状态面板,`/shadow status` 查看摘要,也可以通过 `/shadow toggle`、`/shadow pause` 和 `/shadow resume` 控制状态。TUI 模式下,`/shadow reports` 直接打开限高、可滚动的查看器,展示最近交付的 5 份报告,独立于最近运行列表。使用 ↑/↓、PageUp/PageDown 或 Home/End 滚动,Escape 或 `/shadow reports hide` 关闭。查看器显示打开时的快照,重新打开可查看新报告。报告历史仅保留在当前 Session 内存中,切换会话或 reload 时清空;已持久化的报告仍可在对话记录中查看。状态面板保持简短摘要。管理工具可以查询、创建、更新、启用、禁用和删除 Shadow Mind,以及读取或修改全局配置。所有写操作都需要用户确认。
|
|
98
98
|
|
|
99
99
|
## 在 DSH 中使用
|
|
100
100
|
|