dsh-vibe-math 0.3.4 → 0.3.6
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/README.md +23 -113
- package/installer.js +127 -29
- package/package.json +1 -1
- package/vibe-math-v2/vibe-math-v2.js +17 -5
package/README.md
CHANGED
|
@@ -15,6 +15,24 @@
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
+
## 🧩 架构图(v1 + v2)
|
|
19
|
+
|
|
20
|
+
> 静态架构图;完整流程说明见 [docs/架构图.md](docs/架构图.md);可编辑生成脚本:[v1](docs/generate_framework_diagram.py) / [v2](docs/generate_framework_diagram_v2.py)。
|
|
21
|
+
|
|
22
|
+
### Vibe Math V1(经典流水线)
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
**一句话流水线**:`qs.csv` → Brainstorm 拆方向 → 每方向一个 Solver 多轮迭代(卡死则 Derive 派生新方向)→ 输出拆成最小验证单元 → ≥3 个 Verifier 独立审查 → 辩论 → 裁决 → 通过晋升 `Verified/` → Decider 回写 `qs.csv`;全程状态落盘 `VibeMath_State/`,`resume` 断点续跑,`manual` 模式在派发/裁决/晋升处挂起人工决策。
|
|
27
|
+
|
|
28
|
+
### Vibe Math V2(新架构 · 概率驱动)
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
**一句话流水线**:`qs.json` 按优先级取问题 → Explorer 拆方向(全死路则重派生)→ 每方向一个 Solver 多轮迭代(引理进 `Propos/`、解法回 `qs.json`,概率均 <1)→ 调度器选 r(命题 / 命题+证明·证伪 / 问题+解法)派 ≥3 验证器独立审查→辩论→裁决 → 概率=1 自动收口(问题 solved、命题 1/0,优先级置 `never`);全程状态落盘,`resume` 断点续跑,`reportMode` 可 file/push/both 汇报。
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
18
36
|
## ✨ 功能特色
|
|
19
37
|
|
|
20
38
|
- **多代理自动求解**:主代理把问题交给调度器,调度器派发 brainstorm / solver / verifier / decider(v1)或 explorer / solver / verifier(v2)等子代理协同求解,**你无需逐节点手操**。
|
|
@@ -43,6 +61,7 @@ dsh plugin --profile <你的 profile> add github:ChongCyrus/Vibe-Mathematics
|
|
|
43
61
|
|
|
44
62
|
安装时插件会自动把两个 preset 写入 `~/.dsh/.agent-presets/`:`vibe-math-v1/` 与 `vibe-math-v2/`。
|
|
45
63
|
之后新建会话,预设选择器里选择 **Vibe Math**(v1)或 **Vibe Math V2**(v2)即可。
|
|
64
|
+
**升级包版本后重启 DSH,未手动改过的 preset 文件会自动更新到新版本**(细节见文末「v2」安装器说明)。
|
|
46
65
|
|
|
47
66
|
### 方式 B:作为 agent preset 手动安装
|
|
48
67
|
|
|
@@ -92,116 +111,6 @@ dsh plugin --profile <你的 profile> add github:ChongCyrus/Vibe-Mathematics
|
|
|
92
111
|
|
|
93
112
|
---
|
|
94
113
|
|
|
95
|
-
## 🧩 架构图 · v1(经典)
|
|
96
|
-
|
|
97
|
-
> 静态 PNG 预览 + 可编辑 Mermaid 图源(GitHub 原生渲染);完整流程说明见 [docs/架构图.md](docs/架构图.md)。
|
|
98
|
-
|
|
99
|
-

|
|
100
|
-
|
|
101
|
-
```mermaid
|
|
102
|
-
flowchart TB
|
|
103
|
-
subgraph L1["👤 交互层"]
|
|
104
|
-
U["😀 用户(自然语言)"]
|
|
105
|
-
M["🤖 主代理(助手 + 汇报者)<br/>翻译需求 · 汇报进度 · 问答配置<br/>不求解 · 不调度"]
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
subgraph L2["⚙️ 调度层(插件代码)"]
|
|
109
|
-
SCHED["调度器 Scheduler<br/>唯一文件写者<br/>读 qs.csv · 派发子代理 · 推进状态机"]
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
subgraph L3["🧠 子代理层(continuable 持久会话)"]
|
|
113
|
-
BRAIN["🧭 Brainstorm<br/>拆解多个求解方向"]
|
|
114
|
-
SOLV["✍️ Solver × N<br/>逐方向多轮迭代"]
|
|
115
|
-
DERI["🔀 Derive<br/>死路时派生新方向"]
|
|
116
|
-
VERI["🔬 Verifier × ≥3<br/>独立审查 → 辩论 → 裁决"]
|
|
117
|
-
DECI["⚖️ Decider<br/>判定是否解决"]
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
subgraph L4["💾 数据层 · VibeMath/Projects/<项目>/"]
|
|
121
|
-
QS["📋 qs.csv"]
|
|
122
|
-
PEND["📥 Pending_Verification/"]
|
|
123
|
-
UNDR["📂 Under_Verification/"]
|
|
124
|
-
TVAL["✅ Temp_Validated/"]
|
|
125
|
-
KNOW["📚 Verified/ 可信知识库"]
|
|
126
|
-
STATE["🗄️ Progress_Logs/ · VibeMath_State/"]
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
U -->|"求解 XX / 查进度 / 干预"| M
|
|
130
|
-
M -->|"vibe_math_* 工具"| SCHED
|
|
131
|
-
|
|
132
|
-
SCHED -->|"① 派发"| BRAIN
|
|
133
|
-
BRAIN -->|"多个大相径庭的方向"| SCHED
|
|
134
|
-
SCHED -->|"② 每方向一个"| SOLV
|
|
135
|
-
SOLV -->|"结构化结果 JSON"| SCHED
|
|
136
|
-
SOLV -.->|"迭代至卡死"| DERI
|
|
137
|
-
DERI -->|"派生 1~3 个新方向"| SCHED
|
|
138
|
-
SCHED -->|"③ 写盘"| PEND
|
|
139
|
-
SCHED -->|"④ 拆解为最小验证单元"| UNDR
|
|
140
|
-
SCHED -->|"⑤ 派发 ≥3 个"| VERI
|
|
141
|
-
VERI -->|"裁决 JSON"| SCHED
|
|
142
|
-
SCHED -->|"⑥ 通过"| TVAL
|
|
143
|
-
SCHED -->|"⑦ 晋升"| KNOW
|
|
144
|
-
SCHED -->|"⑧ 派发"| DECI
|
|
145
|
-
DECI -->|"⑨ 已解决 → 回写"| QS
|
|
146
|
-
SCHED <-->|"读取问题"| QS
|
|
147
|
-
SCHED <-->|"状态落盘 / 断点恢复"| STATE
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**一句话流水线**:`qs.csv` → Brainstorm 拆方向 → 每方向一个 Solver 多轮迭代(卡死则 Derive 派生新方向)→ 输出拆成最小验证单元 → ≥3 个 Verifier 独立审查 → 辩论 → 裁决 → 通过晋升 `Verified/` → Decider 回写 `qs.csv`;全程状态落盘 `VibeMath_State/`,`resume` 断点续跑,`manual` 模式在派发/裁决/晋升处挂起人工决策。
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## 🧩 架构图 · v2(新架构 · 概率驱动)
|
|
155
|
-
|
|
156
|
-
> 静态 PNG 预览 + 可编辑 Mermaid 图源(GitHub 原生渲染);生成脚本见 [docs/generate_framework_diagram_v2.py](docs/generate_framework_diagram_v2.py)。
|
|
157
|
-
|
|
158
|
-

|
|
159
|
-
|
|
160
|
-
```mermaid
|
|
161
|
-
flowchart TB
|
|
162
|
-
subgraph L1["👤 交互层"]
|
|
163
|
-
U["😀 用户(自然语言)"]
|
|
164
|
-
M["🤖 主代理(助手 + 汇报者)<br/>翻译需求 · 汇报进度 · 问答配置<br/>不求解 · 不调度"]
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
subgraph L2["⚙️ 调度层(插件代码 · 概率驱动)"]
|
|
168
|
-
SCHED["调度器 Scheduler<br/>唯一文件写者 · 按优先级调度<br/>explorer → 逐方向 solver → 验证器 → 收口<br/>断点持久化 · 人工决策门"]
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
subgraph L3["🧠 子代理层(continuable 持久会话)"]
|
|
172
|
-
EXP["🧭 Explorer<br/>拆方向 / 全死路时重派生(去死路 · 并集)"]
|
|
173
|
-
SOLV["✍️ Solver × N<br/>agent_self_iteration<br/>逐方向多轮迭代"]
|
|
174
|
-
VERI["🔬 Verifier × ≥3<br/>独立审查 → 辩论 → 裁决"]
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
subgraph L4["💾 数据层 · VibeMath/Projects/<项目>/"]
|
|
178
|
-
QS["📋 qs/qs.json<br/>问题 + 解法(正确概率)"]
|
|
179
|
-
PRP["📚 Propos/<分类>_Propos.json<br/>命题(布尔估计 · 证明/证伪列表)"]
|
|
180
|
-
VERD["✅ Verified/<br/>定论事实(0/1)"]
|
|
181
|
-
LOGS["🗄️ Verification_logs/ · Progress_Logs/<br/>· Reliable/ · VibeMath_State/"]
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
U -->|"求解 / 查进度 / 干预"| M
|
|
185
|
-
M -->|"vibe_math_* 工具"| SCHED
|
|
186
|
-
|
|
187
|
-
SCHED -->|"① 按优先级取问题"| QS
|
|
188
|
-
SCHED -->|"② 派 Explorer"| EXP
|
|
189
|
-
EXP -->|"方向集 M_q"| SCHED
|
|
190
|
-
SCHED -->|"③ 每方向一个"| SOLV
|
|
191
|
-
SOLV -->|"引理 → Propos(概率<1)"| PRP
|
|
192
|
-
SOLV -->|"解法 → qs(概率<1)"| QS
|
|
193
|
-
SOLV -.->|"卡死 → 重派生"| EXP
|
|
194
|
-
SCHED -->|"④ 选 r 派 ≥3 验证器"| VERI
|
|
195
|
-
VERI -->|"⑤ 裁决 0/1/中间"| SCHED
|
|
196
|
-
SCHED -->|"⑥ 概率=1 → 收口/晋升"| PRP
|
|
197
|
-
SCHED -->|"已解决 / 优先级 never"| QS
|
|
198
|
-
SCHED -->|"晋升定论"| VERD
|
|
199
|
-
SCHED <-->|"辩论记录 / 状态落盘"| LOGS
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
**一句话流水线**:`qs.json` 按优先级取问题 → Explorer 拆方向(全死路则重派生)→ 每方向一个 Solver 多轮迭代(引理进 `Propos/`、解法回 `qs.json`,概率均 <1)→ 调度器选 r(命题 / 命题+证明·证伪 / 问题+解法)派 ≥3 验证器独立审查→辩论→裁决 → 概率=1 自动收口(问题 solved、命题 1/0,优先级置 `never`);全程状态落盘,`resume` 断点续跑,`reportMode` 可 file/push/both 汇报。
|
|
203
|
-
|
|
204
|
-
---
|
|
205
114
|
|
|
206
115
|
## 📁 目录结构
|
|
207
116
|
|
|
@@ -278,9 +187,9 @@ flowchart TB
|
|
|
278
187
|
| `vibe_math_setup` | 返回参数 schema(交互式配置用) |
|
|
279
188
|
| `vibe_math_save_settings` | 把当前参数存成新默认 |
|
|
280
189
|
| `vibe_math_template` | 生成默认参数模板文件 |
|
|
281
|
-
| `vibe_math_new_project` / `
|
|
190
|
+
| `vibe_math_new_project` / `vibe_math_set_project` / `vibe_math_list_projects` | 项目管理 |
|
|
282
191
|
| `vibe_math_list_decisions` / `decide` | 查看 / 裁决人工决策 |
|
|
283
|
-
| `vibe_math_list_agents` / `
|
|
192
|
+
| `vibe_math_list_agents` / `vibe_math_message_agent` / `vibe_math_interrupt_agent` | 查看 / 发消息 / 中断子代理 |
|
|
284
193
|
|
|
285
194
|
斜杠命令(与工具等价):`/vibe start|resume|pause|abort|status|report|mode <auto|manual>|setup|save|template [global|project]|add <id> <desc>|add-proposition <id> <概述>|list-propositions|project [list|new <name>|<name>]|decisions|agents`
|
|
286
195
|
|
|
@@ -414,6 +323,7 @@ flowchart TB
|
|
|
414
323
|
| `mode` | `auto` | `auto` / `manual` |
|
|
415
324
|
| `maxParallelThreshold` | 4 | 全局最大并发子代理轮数(新派发前须 active < 阈值) |
|
|
416
325
|
| `solverMaxRounds` | 3 | 每个求解方向最大迭代轮数(agent_self_iteration 上限) |
|
|
326
|
+
| `directionsPerSolver` | 1 | 每个 solver 提示词附带的方向数量(1 = 只看自己方向、互不干扰;>1 = 附带其他活跃方向摘要用于协调) |
|
|
417
327
|
| `verifierCount` | 3 | 每个验证对象的独立验证器数量 |
|
|
418
328
|
| `debateMaxRounds` | 5 | 验证辩论(交流群)最大轮数 |
|
|
419
329
|
| `verdictMode` | `flat` | `flat` = 均衡机制(不一致判 0.5)/ `forced` = 强制裁决(历史准确率+严谨性加权) |
|
|
@@ -456,7 +366,7 @@ flowchart TB
|
|
|
456
366
|
- manual 模式在第一个未决关键节点暂停整条主循环。
|
|
457
367
|
|
|
458
368
|
**v2**:
|
|
459
|
-
-
|
|
369
|
+
- 安装器带**版本化自动更新**:每次 DSH 启动时对比包版本与 `<presetRoot>/.vibe-math-installed.json` 记录——版本升级会自动替换**未被手动修改**的 preset 文件(哈希一致才覆盖);你改过的文件会被保留并在日志中提示。无记录的老安装首次会一次性刷新到当前版本。想强制全量重装:删除 `~/.dsh/.agent-presets/vibe-math-v1` 与 `vibe-math-v2` 目录后重启 DSH。
|
|
460
370
|
- `flat` 裁决在辩论不一致时直接判 `0.5`;`forced` 按历史准确率+置信度加权。
|
|
461
371
|
- `never` 优先级的问题/命题**永不调度**,且不阻塞严格终止(视为主动弃权)。
|
|
462
372
|
- 两个 preset 文件互相独立、可共存;同一会话同时只能选一个预设。
|
package/installer.js
CHANGED
|
@@ -1,51 +1,149 @@
|
|
|
1
|
-
// dsh-vibe-math merged bundle installer.
|
|
1
|
+
// dsh-vibe-math merged bundle installer — VERSIONED AUTO-UPDATE.
|
|
2
2
|
// When this bundle is installed (e.g. `dsh plugin add dsh-vibe-math` or from the
|
|
3
3
|
// dsh-market), this plugin copies BOTH agent presets out of the package into the
|
|
4
4
|
// DSH preset root, so the user immediately gets two presets in the picker:
|
|
5
5
|
// vibe-math-v1/ (classic pipeline architecture)
|
|
6
6
|
// vibe-math-v2/ (new probability-driven architecture)
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
7
|
+
//
|
|
8
|
+
// UPDATE POLICY (state recorded in <presetRoot>/.vibe-math-installed.json):
|
|
9
|
+
// - baseline (no state file — e.g. upgrading from an installer that predates
|
|
10
|
+
// this mechanism): every existing owned file is refreshed to the current
|
|
11
|
+
// package version and recorded as package-owned (user policy: auto-update
|
|
12
|
+
// old installs; any manual edits made before this baseline are overwritten
|
|
13
|
+
// once — from then on edits are protected).
|
|
14
|
+
// - upgrade (recorded version != current package.json version): every owned
|
|
15
|
+
// file that is byte-identical to the previously installed copy (i.e. NOT
|
|
16
|
+
// user-edited since) is overwritten with the new version; user-edited files
|
|
17
|
+
// are preserved and reported via the logger.
|
|
18
|
+
// - same version: no-op (idempotent). Missing files are ALWAYS restored.
|
|
19
|
+
// - force a full refresh at any time: delete the preset dirs and restart DSH.
|
|
20
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs'
|
|
21
|
+
import { createHash } from 'node:crypto'
|
|
10
22
|
import { homedir } from 'node:os'
|
|
11
23
|
import { dirname, join } from 'node:path'
|
|
12
24
|
import { fileURLToPath } from 'node:url'
|
|
13
25
|
|
|
14
26
|
export const name = 'vibe-math-preset-installer'
|
|
15
27
|
|
|
28
|
+
const PRESETS = [
|
|
29
|
+
{
|
|
30
|
+
src: 'vibe-math-v1',
|
|
31
|
+
dst: 'vibe-math-v1',
|
|
32
|
+
files: ['agent.cordis.yml', 'preset.yml', 'vibe-math.js', '实现方案-多代理数学问题求解与验证框架.md'],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
src: 'vibe-math-v2',
|
|
36
|
+
dst: 'vibe-math-v2',
|
|
37
|
+
files: ['agent.cordis.yml', 'preset.yml', 'vibe-math-v2.js', '实现方案.md'],
|
|
38
|
+
},
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
const STATE_FILE = '.vibe-math-installed.json'
|
|
42
|
+
|
|
43
|
+
function sha256(buf) { return createHash('sha256').update(buf).digest('hex') }
|
|
44
|
+
|
|
45
|
+
function readState(path) {
|
|
46
|
+
try {
|
|
47
|
+
const raw = readFileSync(path, 'utf8')
|
|
48
|
+
const obj = JSON.parse(raw)
|
|
49
|
+
if (obj && typeof obj === 'object' && obj.files && typeof obj.files === 'object') return obj
|
|
50
|
+
} catch (e) { /* missing or corrupt — treat as no state (baseline) */ }
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function writeState(path, state) {
|
|
55
|
+
try {
|
|
56
|
+
const tmp = path + '.tmp'
|
|
57
|
+
writeFileSync(tmp, JSON.stringify(state, null, 2) + '\n', 'utf8')
|
|
58
|
+
renameSync(tmp, path)
|
|
59
|
+
} catch (e) {
|
|
60
|
+
// best-effort: state persistence failure must not break the copy step
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
16
64
|
export function apply(ctx) {
|
|
17
65
|
const logger = ctx && ctx.logger
|
|
18
66
|
try {
|
|
19
67
|
const dshHome = process.env.DSH_HOME || join(homedir(), '.dsh')
|
|
20
68
|
const here = dirname(fileURLToPath(import.meta.url))
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
69
|
+
const presetRoot = join(dshHome, '.agent-presets')
|
|
70
|
+
const stateFile = join(presetRoot, STATE_FILE)
|
|
71
|
+
|
|
72
|
+
// current package version (the source of truth for "is this an upgrade?")
|
|
73
|
+
let pkgVersion = ''
|
|
74
|
+
try { pkgVersion = String((JSON.parse(readFileSync(join(here, 'package.json'), 'utf8')).version) || '') } catch (e) { pkgVersion = '' }
|
|
75
|
+
|
|
76
|
+
const state = readState(stateFile)
|
|
77
|
+
const prevFiles = (state && state.files) || {}
|
|
78
|
+
const isUpgrade = state !== null && pkgVersion !== '' && state.version !== pkgVersion
|
|
79
|
+
const isBaseline = state === null // no recorded history → refresh everything (user policy: auto-update old installs)
|
|
80
|
+
|
|
81
|
+
const nextFiles = {}
|
|
82
|
+
let installed = 0, updated = 0, kept = 0
|
|
83
|
+
const keptList = []
|
|
84
|
+
|
|
85
|
+
for (const p of PRESETS) {
|
|
86
|
+
const srcDir = join(here, p.src)
|
|
87
|
+
const dstDir = join(presetRoot, p.dst)
|
|
88
|
+
if (!existsSync(srcDir)) continue
|
|
89
|
+
mkdirSync(dstDir, { recursive: true })
|
|
90
|
+
for (const f of p.files) {
|
|
91
|
+
const s = join(srcDir, f)
|
|
92
|
+
const d = join(dstDir, f)
|
|
93
|
+
if (!existsSync(s)) continue
|
|
94
|
+
const key = p.src + '/' + f
|
|
95
|
+
const cur = readFileSync(s)
|
|
96
|
+
const curHash = sha256(cur)
|
|
97
|
+
if (!existsSync(d)) {
|
|
98
|
+
// missing file: always restore, whatever the version
|
|
99
|
+
writeFileSync(d, cur)
|
|
100
|
+
installed += 1
|
|
101
|
+
nextFiles[key] = { hash: curHash, provenance: 'package' }
|
|
102
|
+
continue
|
|
103
|
+
}
|
|
104
|
+
const destHash = sha256(readFileSync(d))
|
|
105
|
+
if (isBaseline) {
|
|
106
|
+
// no recorded history: refresh to the current package (one-time; edits
|
|
107
|
+
// made before this mechanism are overwritten, later edits are protected)
|
|
108
|
+
if (destHash === curHash) { nextFiles[key] = { hash: curHash, provenance: 'package' } }
|
|
109
|
+
else { writeFileSync(d, cur); updated += 1; nextFiles[key] = { hash: curHash, provenance: 'package' } }
|
|
110
|
+
continue
|
|
111
|
+
}
|
|
112
|
+
const prev = prevFiles[key]
|
|
113
|
+
const prevRec = (prev && typeof prev === 'object') ? prev : { hash: prev, provenance: 'package' }
|
|
114
|
+
const prevProv = (prevRec.provenance === 'user') ? 'user' : 'package' // 未知来源按包文件处理
|
|
115
|
+
if (prevProv === 'package' && destHash === prevRec.hash) {
|
|
116
|
+
// 包文件且未被改动 → 可安全升级(内容相同则跳过写入)
|
|
117
|
+
if (destHash !== curHash) { writeFileSync(d, cur); updated += 1 }
|
|
118
|
+
nextFiles[key] = { hash: curHash, provenance: 'package' }
|
|
119
|
+
} else if (prevProv === 'user') {
|
|
120
|
+
// 用户持有 → 永不覆盖
|
|
121
|
+
kept += 1
|
|
122
|
+
if (isUpgrade) keptList.push(key + ' (用户持有)')
|
|
123
|
+
nextFiles[key] = { hash: destHash, provenance: 'user' }
|
|
124
|
+
} else {
|
|
125
|
+
// 包文件但自上次安装后已被用户改动
|
|
126
|
+
kept += 1
|
|
127
|
+
if (isUpgrade) keptList.push(key + ' (已修改)')
|
|
128
|
+
nextFiles[key] = { hash: destHash, provenance: 'user' }
|
|
129
|
+
}
|
|
43
130
|
}
|
|
44
131
|
}
|
|
45
|
-
|
|
46
|
-
|
|
132
|
+
|
|
133
|
+
writeState(stateFile, { version: pkgVersion, files: nextFiles, updatedAt: Date.now() })
|
|
134
|
+
|
|
135
|
+
if (isUpgrade) {
|
|
136
|
+
logger?.info?.('[dsh-vibe-math] preset auto-update: version ' + (state.version || '(none)') + ' → ' + pkgVersion +
|
|
137
|
+
' — 新增 ' + installed + ' 个文件,更新 ' + updated + ' 个文件' +
|
|
138
|
+
(kept > 0 ? ',保留 ' + kept + ' 个未覆盖文件(' + keptList.join('; ') + ')' : '') +
|
|
139
|
+
'。新版本 preset 将在新会话生效。')
|
|
140
|
+
} else if (isBaseline) {
|
|
141
|
+
logger?.info?.('[dsh-vibe-math] preset baseline: refreshed ' + (installed + updated) + ' file(s) to v' + pkgVersion +
|
|
142
|
+
' — 已启用自动更新(后续版本升级将自动替换未被手动修改的 preset 文件)。')
|
|
143
|
+
} else if (installed > 0) {
|
|
144
|
+
logger?.info?.('[dsh-vibe-math] restored ' + installed + ' missing preset file(s)')
|
|
47
145
|
}
|
|
48
146
|
} catch (err) {
|
|
49
|
-
logger?.warn?.('[dsh-vibe-math] preset install failed: %s', String((err && err.message) || err))
|
|
147
|
+
logger?.warn?.('[dsh-vibe-math] preset install/update failed: %s', String((err && err.message) || err))
|
|
50
148
|
}
|
|
51
149
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-vibe-math",
|
|
3
3
|
"description": "Multi-agent mathematical problem-solving & verification frameworks for DeepSeek Harness — TWO agent presets in one install: vibe-math-v1 (classic pipeline: brainstorm → solver iteration → multi-verifier debate → Verified) and vibe-math-v2 (new probability-driven architecture: qs.json + Propos knowledge base + explorer→solver→review/debate verdict). Installing this bundle auto-installs both presets into the DSH preset root.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.6",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "installer.js",
|
|
7
7
|
"exports": {
|
|
@@ -34,6 +34,7 @@ export function apply(ctx) {
|
|
|
34
34
|
mode: 'auto', // auto | manual
|
|
35
35
|
maxParallelThreshold: 4, // concurrency gate: active turns < this
|
|
36
36
|
solverMaxRounds: 3, // per-direction iteration cap (spec example)
|
|
37
|
+
directionsPerSolver: 1, // 每个 solver 提示词附带的方向数量(1 = 只看自己方向)
|
|
37
38
|
verifierCount: 3, // independent reviewers per verification
|
|
38
39
|
debateMaxRounds: 5, // debate round cap (spec example)
|
|
39
40
|
verdictMode: 'flat', // flat = 均衡机制(0.5) | forced = 强制裁决(weighted)
|
|
@@ -119,6 +120,7 @@ export function apply(ctx) {
|
|
|
119
120
|
{ name: 'mode', type: 'enum', options: ['auto', 'manual'], description: 'auto = 无人值守自动通过关键节点;manual = 关键节点挂起人工决策', suggestion: 'auto' },
|
|
120
121
|
{ name: 'maxParallelThreshold', type: 'integer', description: '全局最大并发子代理轮数(新派发前须满足 active < 阈值)', suggestion: 4 },
|
|
121
122
|
{ name: 'solverMaxRounds', type: 'integer', description: '每个求解方向的最大迭代轮数(agent_self_iteration 上限)', suggestion: 3 },
|
|
123
|
+
{ name: 'directionsPerSolver', type: 'integer', description: '每个 solver 提示词附带的方向数量:1 = 只看自己方向(互不干扰);>1 = 额外附带其他活跃方向摘要用于协调', suggestion: 1 },
|
|
122
124
|
{ name: 'verifierCount', type: 'integer', description: '每个验证对象的独立验证器数量', suggestion: 3 },
|
|
123
125
|
{ name: 'debateMaxRounds', type: 'integer', description: '验证辩论(交流群)最大轮数', suggestion: 5 },
|
|
124
126
|
{ name: 'verdictMode', type: 'enum', options: ['flat', 'forced'], description: 'flat = 均衡机制(不一致直接判 0.5);forced = 强制裁决(按历史准确率+严谨性加权)', suggestion: 'flat' },
|
|
@@ -164,7 +166,7 @@ export function apply(ctx) {
|
|
|
164
166
|
// ================= settings =================
|
|
165
167
|
function sanitizeParams(obj) {
|
|
166
168
|
const out = {}
|
|
167
|
-
const intFields = ['maxParallelThreshold', 'solverMaxRounds', 'verifierCount', 'debateMaxRounds', 'solverMaxToolCalls', 'verifierMaxToolCalls', 'reportIntervalMs', 'tickIntervalMs', 'activityLogCap', 'maxExplorerRetries']
|
|
169
|
+
const intFields = ['maxParallelThreshold', 'solverMaxRounds', 'directionsPerSolver', 'verifierCount', 'debateMaxRounds', 'solverMaxToolCalls', 'verifierMaxToolCalls', 'reportIntervalMs', 'tickIntervalMs', 'activityLogCap', 'maxExplorerRetries']
|
|
168
170
|
const numFields = ['promoteValueThreshold']
|
|
169
171
|
const arrayFields = ['solverToolAllow', 'solverToolDeny', 'verifierToolAllow', 'verifierToolDeny']
|
|
170
172
|
for (const k of Object.keys(DEFAULT_PARAMS)) {
|
|
@@ -397,6 +399,16 @@ export function apply(ctx) {
|
|
|
397
399
|
(d.lessons && d.lessons.length ? ' | lessons: ' + d.lessons.join('; ') : '') +
|
|
398
400
|
(d.blockers && d.blockers.length ? ' | blockers: ' + d.blockers.join('; ') : '')
|
|
399
401
|
}
|
|
402
|
+
// 每个 solver 默认只看自己方向(互不干扰):round>1 时带上自己的历史进度,
|
|
403
|
+
// directionsPerSolver>1 时再附带其他活跃方向摘要用于协调(总数不超过该参数)。
|
|
404
|
+
function buildSolverContext(all, own, round, perSolver) {
|
|
405
|
+
const out = []
|
|
406
|
+
const n = Math.max(1, Number(perSolver) || 1)
|
|
407
|
+
if (round > 1) out.push(own)
|
|
408
|
+
const others = all.filter(function (d) { return d.id !== own.id && d.status === 'active' })
|
|
409
|
+
for (let i = 0; i < others.length && out.length < n; i++) out.push(others[i])
|
|
410
|
+
return out.map(directionSummary).join('\n')
|
|
411
|
+
}
|
|
400
412
|
function solverPrompt(q, dir, round, progressText) {
|
|
401
413
|
let head = solverPersonaText() + 'You are a dedicated solver agent working ONE solution direction of a math problem (agent_self_iteration).\n\n'
|
|
402
414
|
head += 'PROBLEM (id: ' + q.id + '): ' + q.概述 + '\nDIRECTION: ' + dir.title + ' (method: ' + dir.method + '; core assumption: ' + dir.core_assumption + ')\nROUND: ' + round + ' of ' + params.solverMaxRounds + '\n'
|
|
@@ -688,7 +700,7 @@ export function apply(ctx) {
|
|
|
688
700
|
if (dir.status === 'success' || dir.status === 'dead-end') continue
|
|
689
701
|
const running = Object.keys(agentRegistry).some(function (cid) { const m = agentRegistry[cid]; return m && m.qid === q.id && m.direction === dir.id && m.role === 'solver' })
|
|
690
702
|
if (running) continue
|
|
691
|
-
const progressText = prog.directions.
|
|
703
|
+
const progressText = buildSolverContext(prog.directions, dir, 1, params.directionsPerSolver)
|
|
692
704
|
const promptText = solverPrompt(q, dir, 1, progressText)
|
|
693
705
|
const r = await maybeGate('spawn', 'solver for problem ' + q.id + ' direction ' + dir.id, { label: 'solver:' + q.id + ':' + dir.id, promptText: promptText, meta: { role: 'solver', qid: q.id, direction: dir.id, round: 1, description: q.概述 } }, async function (d) { await spawnChild(d.label, d.promptText, d.meta); return { spawned: true } })
|
|
694
706
|
if (r && r.gated) return
|
|
@@ -743,7 +755,7 @@ export function apply(ctx) {
|
|
|
743
755
|
delete agentRegistry[childId]
|
|
744
756
|
logActivity('solver', qid + '/' + dirId + ' dead-end (success without solution)')
|
|
745
757
|
} else {
|
|
746
|
-
const progressText = prog.directions.
|
|
758
|
+
const progressText = buildSolverContext(prog.directions, dir, meta.round + 1, params.directionsPerSolver)
|
|
747
759
|
await followupChild(childId, solverPrompt(q, dir, meta.round + 1, progressText))
|
|
748
760
|
agentRegistry[childId].round = meta.round + 1
|
|
749
761
|
dir.round = meta.round + 1
|
|
@@ -755,7 +767,7 @@ export function apply(ctx) {
|
|
|
755
767
|
delete agentRegistry[childId]
|
|
756
768
|
logActivity('solver', qid + '/' + dirId + ' dead-end: ' + dir.dead_end_reason)
|
|
757
769
|
} else {
|
|
758
|
-
const progressText = prog.directions.
|
|
770
|
+
const progressText = buildSolverContext(prog.directions, dir, meta.round + 1, params.directionsPerSolver)
|
|
759
771
|
if (!scheduler.running) {
|
|
760
772
|
// paused/aborted: stop the follow-up chain; keep the direction active for resume
|
|
761
773
|
delete agentRegistry[childId]
|
|
@@ -1095,7 +1107,7 @@ export function apply(ctx) {
|
|
|
1095
1107
|
registerTool('vibe_math_status', 'Show scheduler status, params, active agents, projects, and recent activity.', objParams({}), async function () { return await getStatus() })
|
|
1096
1108
|
registerTool('vibe_math_report', 'Return the full progress report and write it to Progress_Logs/report.json.', objParams({}), async function () { await maybeWriteReport(true); return await buildReport() })
|
|
1097
1109
|
registerTool('vibe_math_set_mode', 'Switch between manual and auto (preset) mode. Switching to auto auto-resolves any pending manual decisions.', objParams({ mode: { type: 'string', enum: ['manual', 'auto'] } }, ['mode']), async function (args) { params.mode = args.mode; await saveAll(); if (params.mode === 'auto') await autoResolvePending(); return { ok: true, mode: params.mode } })
|
|
1098
|
-
registerTool('vibe_math_set_params', 'Update scheduler parameters (partial).', objParams({ maxParallelThreshold: { type: 'integer' }, solverMaxRounds: { type: 'integer' }, verifierCount: { type: 'integer' }, debateMaxRounds: { type: 'integer' }, verdictMode: { type: 'string', enum: ['flat', 'forced'] }, reportMode: { type: 'string', enum: ['file', 'push', 'both'] }, promoteValueThreshold: { type: 'number' }, priorityAdjust: { type: 'string', enum: ['none', 'deadend-deprioritize', 'survival-map'] }, proposPriorityAdjust: { type: 'string', enum: ['none', 'progress-graded'] }, provider: { type: 'string' }, model: { type: 'string' }, solverPersona: { type: 'string' }, verifierPersona: { type: 'string' }, solverToolAllow: { type: 'array', items: { type: 'string' } }, solverToolDeny: { type: 'array', items: { type: 'string' } }, verifierToolAllow: { type: 'array', items: { type: 'string' } }, verifierToolDeny: { type: 'array', items: { type: 'string' } }, solverMaxToolCalls: { type: 'integer' }, verifierMaxToolCalls: { type: 'integer' }, reportIntervalMs: { type: 'integer' }, tickIntervalMs: { type: 'integer' }, activityLogCap: { type: 'integer' }, maxExplorerRetries: { type: 'integer' } }), async function (args) { params = Object.assign({}, params, sanitizeParams(args)); await saveAll(); return { ok: true, params: params } })
|
|
1110
|
+
registerTool('vibe_math_set_params', 'Update scheduler parameters (partial).', objParams({ maxParallelThreshold: { type: 'integer' }, solverMaxRounds: { type: 'integer' }, verifierCount: { type: 'integer' }, debateMaxRounds: { type: 'integer' }, verdictMode: { type: 'string', enum: ['flat', 'forced'] }, reportMode: { type: 'string', enum: ['file', 'push', 'both'] }, promoteValueThreshold: { type: 'number' }, priorityAdjust: { type: 'string', enum: ['none', 'deadend-deprioritize', 'survival-map'] }, proposPriorityAdjust: { type: 'string', enum: ['none', 'progress-graded'] }, provider: { type: 'string' }, model: { type: 'string' }, solverPersona: { type: 'string' }, verifierPersona: { type: 'string' }, solverToolAllow: { type: 'array', items: { type: 'string' } }, solverToolDeny: { type: 'array', items: { type: 'string' } }, verifierToolAllow: { type: 'array', items: { type: 'string' } }, verifierToolDeny: { type: 'array', items: { type: 'string' } }, solverMaxToolCalls: { type: 'integer' }, verifierMaxToolCalls: { type: 'integer' }, reportIntervalMs: { type: 'integer' }, tickIntervalMs: { type: 'integer' }, activityLogCap: { type: 'integer' }, maxExplorerRetries: { type: 'integer' }, directionsPerSolver: { type: 'integer' } }), async function (args) { params = Object.assign({}, params, sanitizeParams(args)); await saveAll(); return { ok: true, params: params } })
|
|
1099
1111
|
registerTool('vibe_math_setup', 'Return the interactive parameter schema for guided configuration.', objParams({}), async function () { const list = PARAM_SCHEMA.map(function (p) { const out = Object.assign({}, p); out.current = params[p.name]; out.default = DEFAULT_PARAMS[p.name]; return out }); return { ok: true, parameters: list, saveTo: frameworkRoot() + '/vibe_math_setting.json' } })
|
|
1100
1112
|
registerTool('vibe_math_save_settings', 'Write the current params to vibe_math_setting.json (JSON with comments) as new defaults.', objParams({}), async function () { return await saveSettings() })
|
|
1101
1113
|
registerTool('vibe_math_template', 'Create a fresh vibe_math_setting.json template (with defaults + comments) in the workspace (global) or current project folder.', objParams({ where: { type: 'string', enum: ['global', 'project'] } }), async function (args) { return await createTemplate((args && args.where) || 'global') })
|