dsh-vibe-math 0.3.6 → 0.3.8
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 +8 -0
- package/installer.js +30 -0
- package/package.json +5 -2
- package/vibe-math-v1/vibe-math.js +8 -2
package/README.md
CHANGED
|
@@ -77,6 +77,14 @@ dsh plugin --profile <你的 profile> add github:ChongCyrus/Vibe-Mathematics
|
|
|
77
77
|
|
|
78
78
|
> 修改 preset 文件后需**重启 DSH 进程**再开新会话(preset 的 standing mount 会缓存到进程退出)。
|
|
79
79
|
|
|
80
|
+
### DSH 版本适配与依赖
|
|
81
|
+
|
|
82
|
+
- **形态依赖**:两个 preset 依赖 DSH 的标准 **agent-preset 机制**(`~/.dsh/.agent-presets/<id>/` + preset picker)与 **bundle patch 机制**(`cordis.patch.yml` 注入安装器)。
|
|
83
|
+
- **宿主插件行**:`agent.cordis.yml` 引用宿主提供的 `@deepseek-ai/dsh-*` 插件行(persona、agent-instructions、tool-bash/pwsh、tool-fs/fs-search、tool-jobs、skill-filesystem、tool-skill、tool-goal、plan-mode、compaction、subagent/workflow、ask-user、todo、web 等,约 21 个唯一包名)。宿主缺行会导致 preset 挂载失败(会话启动时报错)。
|
|
84
|
+
- **宿主服务 API**:预设插件消费 `subagents`(startContinuable / followup / interrupt)、`agents`(roots)、`tools`(register)、`commands`(register)、`fs`(resolve/stat/readText/writeText/listDir),可选 `subprocess` / `sandboxPolicy`。这些 API 形状随 DSH 版本演进,**低于 `package.json` 中 `dsh.minVersion`(实测基线 `0.1.0-rc.5`)的版本未验证**,可能无法挂载。
|
|
85
|
+
- **运行时自检**:安装器(bundle 插件)每次启动时对上述服务与关键 API 做**能力自检**(DSH 不暴露版本号,故按能力而非版本检测);不满足时打 warning 并提示升级 DSH。preset 挂载失败时先看 DSH 日志里的自检 warning。
|
|
86
|
+
- **升级路径**:DSH 升级后无需重装本包;升级本包用 `dsh plugin update dsh-vibe-math`,重启 DSH 后安装器会自动把 preset 更新到新版本(见上文「安装」说明)。
|
|
87
|
+
|
|
80
88
|
---
|
|
81
89
|
|
|
82
90
|
## 🧭 两个预设怎么选
|
package/installer.js
CHANGED
|
@@ -61,6 +61,35 @@ function writeState(path, state) {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
// DSH 适配性自检(能力检测,而非版本号——DSH 不向插件暴露版本)。
|
|
65
|
+
// 检查两个 preset 运行时需要的宿主服务与关键 API 形状是否可用,
|
|
66
|
+
// 缺失时打 warning 提示宿主版本可能过旧 / 缺少对应插件行。
|
|
67
|
+
function checkHostCapabilities(ctx, logger) {
|
|
68
|
+
const problems = []
|
|
69
|
+
const checks = [
|
|
70
|
+
['subagents', ['startContinuable', 'followup', 'interrupt']],
|
|
71
|
+
['agents', ['roots']],
|
|
72
|
+
['tools', ['register']],
|
|
73
|
+
['commands', ['register']],
|
|
74
|
+
['fs', ['resolve', 'stat', 'readText', 'writeText', 'listDir']],
|
|
75
|
+
]
|
|
76
|
+
for (let i = 0; i < checks.length; i++) {
|
|
77
|
+
const svc = checks[i][0]
|
|
78
|
+
const methods = checks[i][1]
|
|
79
|
+
let s
|
|
80
|
+
try { s = (ctx && ctx.get) ? ctx.get(svc) : undefined } catch (e) { s = undefined }
|
|
81
|
+
if (s === undefined) { problems.push('宿主缺少服务 ' + svc); continue }
|
|
82
|
+
for (let j = 0; j < methods.length; j++) {
|
|
83
|
+
if (typeof s[methods[j]] !== 'function') problems.push(svc + '.' + methods[j] + ' 不可用(宿主版本可能过旧)')
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (problems.length > 0) {
|
|
87
|
+
logger?.warn?.('[dsh-vibe-math] 宿主能力自检:' + problems.length + ' 项不满足(' + problems.join(';') + ')。两个 preset 依赖这些宿主服务/API,旧版 DSH 可能无法挂载,建议升级 DSH(本项目实测基线版本 0.1.0-rc.5,见 package.json 的 dsh.minVersion)。')
|
|
88
|
+
} else {
|
|
89
|
+
logger?.info?.('[dsh-vibe-math] 宿主能力自检通过:subagents / agents / tools / commands / fs 服务及关键 API 均可用(实测基线 DSH 0.1.0-rc.5)。')
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
64
93
|
export function apply(ctx) {
|
|
65
94
|
const logger = ctx && ctx.logger
|
|
66
95
|
try {
|
|
@@ -143,6 +172,7 @@ export function apply(ctx) {
|
|
|
143
172
|
} else if (installed > 0) {
|
|
144
173
|
logger?.info?.('[dsh-vibe-math] restored ' + installed + ' missing preset file(s)')
|
|
145
174
|
}
|
|
175
|
+
checkHostCapabilities(ctx, logger)
|
|
146
176
|
} catch (err) {
|
|
147
177
|
logger?.warn?.('[dsh-vibe-math] preset install/update failed: %s', String((err && err.message) || err))
|
|
148
178
|
}
|
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.8",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "installer.js",
|
|
7
7
|
"exports": {
|
|
@@ -46,6 +46,9 @@
|
|
|
46
46
|
"dsh": {
|
|
47
47
|
"bundle": {
|
|
48
48
|
"patch": "./cordis.patch.yml"
|
|
49
|
-
}
|
|
49
|
+
},
|
|
50
|
+
"minVersion": "0.1.0-rc.5",
|
|
51
|
+
"testedVersion": "0.1.0-rc.5",
|
|
52
|
+
"compatNote": "依赖宿主提供的 subagents/agents/tools/commands/fs 服务与 @deepseek-ai/dsh-* 插件行;低于 minVersion 的 DSH 未验证,可能无法挂载 preset(安装器启动时会做能力自检并告警)"
|
|
50
53
|
}
|
|
51
54
|
}
|
|
@@ -357,7 +357,7 @@ export function apply(ctx) {
|
|
|
357
357
|
async function onChildEnd(info) { const meta = agentRegistry[info.id]; if (meta === undefined) return; scheduler.activeCount = Math.max(0, scheduler.activeCount - 1); const output = blocksToText(info.lastAssistantMessage); try { if (meta.role === 'brainstorm') await handleBrainstorm(info.id, meta, output); else if (meta.role === 'solver') await handleSolver(info.id, meta, output, info.stopReason); else if (meta.role === 'verifier') await handleVerifier(info.id, meta, output, info.stopReason); else if (meta.role === 'decider') await handleDecider(info.id, meta, output); else if (meta.role === 'derive') await handleDerive(info.id, meta, output) } catch (e) { console.error('vibe-math onChildEnd error: ' + String((e && e.stack) || e)) } await saveAll(); scheduleTick() }
|
|
358
358
|
async function handleBrainstorm(childId, meta, output) { delete agentRegistry[childId]; const parsed = parseJson(output); const dirs = (parsed && parsed.directions) || []; if (dirs.length === 0) { logActivity('brainstorm', 'problem ' + meta.qid + ' brainstorm returned no directions'); await saveAll(); return } brainstormRetries[meta.qid] = 0; const prog = []; for (let i = 0; i < dirs.length; i++) { const d = dirs[i]; prog.push({ direction_id: 'd_' + shortId(), title: d.title || '', method: d.method || '', core_assumption: d.core_assumption || '', round: 0, status: 'active', survival_probability: (typeof d.feasibility === 'number') ? d.feasibility : 0.5, dead_end_reason: '', lemmas: [], sub_routes: [], aux_hypotheses: [], updated_at: String(now()) }) } logActivity('brainstorm', 'problem ' + meta.qid + ' → ' + prog.length + ' directions'); await writeProgress(meta.qid, prog) }
|
|
359
359
|
async function handleDerive(childId, meta, output) { delete agentRegistry[childId]; const parsed = parseJson(output); const dirs = (parsed && parsed.directions) || []; if (dirs.length === 0) { logActivity('derive', 'problem ' + meta.qid + ' derived no new directions'); await saveAll(); return } const prog = await readProgress(meta.qid); for (let i = 0; i < dirs.length; i++) { const d = dirs[i]; prog.push({ direction_id: 'd_' + shortId(), title: d.title || '', method: d.method || '', core_assumption: d.core_assumption || (d.motivation || ''), round: 0, status: 'active', survival_probability: (typeof d.feasibility === 'number') ? d.feasibility : 0.5, dead_end_reason: '', lemmas: [], sub_routes: [], aux_hypotheses: [], updated_at: String(now()) }) } logActivity('derive', 'problem ' + meta.qid + ' derived ' + dirs.length + ' new directions'); await writeProgress(meta.qid, prog) }
|
|
360
|
-
async function handleSolver(childId, meta, output, stopReason) { const qid = meta.qid; const direction = meta.direction; const parsed = parseJson(output); const prog = await readProgress(qid); const dir = prog.find(function (d) { return d.direction_id === direction }); if (!dir) { delete agentRegistry[childId]; return } if (!parsed && !scheduler.running) { delete agentRegistry[childId]; return } const status = (parsed && parsed.status) || statusFromStop(stopReason); dir.round = meta.round; dir.status = status; if (parsed) { if (parsed.lemmas) dir.lemmas = parsed.lemmas; if (parsed.sub_routes) dir.sub_routes = parsed.sub_routes; if (parsed.aux_hypotheses) dir.aux_hypotheses = parsed.aux_hypotheses; if (typeof parsed.survival_probability === 'number') dir.survival_probability = parsed.survival_probability; if (parsed.dead_end_reason) dir.dead_end_reason = parsed.dead_end_reason } if (status === 'success') { dir.status = 'success'; delete agentRegistry[childId]; logActivity('solver', qid + '/' + direction + ' success at round ' + meta.round); await writePending(qid, dir, parsed) } else if (status === 'dead-end' || meta.round >= params.solverMaxRounds) { dir.status = 'dead-end'; if (!dir.dead_end_reason) dir.dead_end_reason = (status === 'dead-end' && !parsed) ? 'solver ended abnormally (' + stopReason + ')' : 'iteration cap reached'; delete agentRegistry[childId]; logActivity('solver', qid + '/' + direction + ' dead-end: ' + dir.dead_end_reason) } else { const q = { id: qid, description: meta.description || '' }; await followupChild(childId, solverPrompt(q, dir, meta.round + 1)); agentRegistry[childId].round = meta.round + 1; dir.round = meta.round + 1 } if (parsed && parsed.aux_hypotheses && parsed.aux_hypotheses.length > 0) await handleAuxHypotheses(qid, parsed.aux_hypotheses); dir.updated_at = String(now()); await writeProgress(qid, prog) }
|
|
360
|
+
async function handleSolver(childId, meta, output, stopReason) { const qid = meta.qid; const direction = meta.direction; const parsed = parseJson(output); const prog = await readProgress(qid); const dir = prog.find(function (d) { return d.direction_id === direction }); if (!dir) { delete agentRegistry[childId]; return } if (!parsed && !scheduler.running) { delete agentRegistry[childId]; return } const status = (parsed && parsed.status) || statusFromStop(stopReason); dir.round = meta.round; dir.status = status; if (parsed) { if (parsed.lemmas) dir.lemmas = parsed.lemmas; if (parsed.sub_routes) dir.sub_routes = parsed.sub_routes; if (parsed.aux_hypotheses) dir.aux_hypotheses = parsed.aux_hypotheses; if (typeof parsed.survival_probability === 'number') dir.survival_probability = parsed.survival_probability; if (parsed.dead_end_reason) dir.dead_end_reason = parsed.dead_end_reason } if (status === 'success') { dir.status = 'success'; delete agentRegistry[childId]; logActivity('solver', qid + '/' + direction + ' success at round ' + meta.round); await writePending(qid, dir, parsed) } else if (status === 'dead-end' || meta.round >= params.solverMaxRounds) { dir.status = 'dead-end'; if (!dir.dead_end_reason) dir.dead_end_reason = (status === 'dead-end' && !parsed) ? 'solver ended abnormally (' + stopReason + ')' : 'iteration cap reached'; delete agentRegistry[childId]; logActivity('solver', qid + '/' + direction + ' dead-end: ' + dir.dead_end_reason) } else if (!scheduler.running) { delete agentRegistry[childId] } else { const q = { id: qid, description: meta.description || '' }; await followupChild(childId, solverPrompt(q, dir, meta.round + 1)); agentRegistry[childId].round = meta.round + 1; dir.round = meta.round + 1 } if (parsed && parsed.aux_hypotheses && parsed.aux_hypotheses.length > 0) await handleAuxHypotheses(qid, parsed.aux_hypotheses); dir.updated_at = String(now()); await writeProgress(qid, prog) }
|
|
361
361
|
async function handleAuxHypotheses(qid, hyps) { const qs = await getQs(); for (let i = 0; i < hyps.length; i++) { const h = hyps[i]; if (!h || !h.title) continue; const subId = qid + '_sub_' + shortId(); qs.push({ id: subId, description: h.title + (h.statement ? ' - ' + h.statement : ''), priority: 1, status: 'unsolved', deps: [] }); dependencies[qid] = dependencies[qid] || []; dependencies[qid].push(subId); await writeQs(qs); logActivity('subquestion', qid + ' spawned sub-question ' + subId + ' (Aux_Hypothesis)') } }
|
|
362
362
|
async function writePending(qid, dir, parsed) { const doc = { qid: qid, direction: dir.direction_id, solution: solutionText(parsed, dir), lemmas: (parsed && parsed.lemmas) || [], findings: (parsed && parsed.findings) || [], sub_routes: (parsed && parsed.sub_routes) || [], aux_hypotheses: (parsed && parsed.aux_hypotheses) || [], survival_probability: dir.survival_probability, created_at: String(now()) }; const id = uuid(); await writeText('Pending_Verification/' + id + '.csv', 'qid,direction,content_json,created_at\n' + csvRow([qid, dir.direction_id, JSON.stringify(doc), String(now())]) + '\n') }
|
|
363
363
|
|
|
@@ -442,6 +442,7 @@ export function apply(ctx) {
|
|
|
442
442
|
function finalVerdict(t) { const rs = Object.keys(t.childResults).map(function (cid) { return t.childResults[cid] }); const falses = rs.filter(function (r) { return r.verdict === 'false' }); const trues = rs.filter(function (r) { return r.verdict === 'true' }); const uncerts = rs.filter(function (r) { return r.verdict === 'uncertain' }); if (params.verdictMode === 'weighted-vote') { if (falses.length > 0) return 'false'; if (trues.length > 0 && uncerts.length === 0) return 'true'; return 'false' } if (falses.length > 0) return 'false'; if (trues.length === rs.length && rs.length > 0) return 'true'; return 'false' }
|
|
443
443
|
async function advanceVerification(t, round) {
|
|
444
444
|
if (round < params.debateMaxRounds && !consensus(t)) {
|
|
445
|
+
if (!scheduler.running || scheduler.activeCount >= params.maxParallelThreshold) { t.status = 'paused'; return } // 暂停/并发门:辩论挂起,resume 由 reconcileTasks 重推进
|
|
445
446
|
t.round = round + 1
|
|
446
447
|
const transcript = buildTranscript(t)
|
|
447
448
|
for (let i = 0; i < t.children.length; i++) {
|
|
@@ -465,7 +466,12 @@ export function apply(ctx) {
|
|
|
465
466
|
const ids = Object.keys(tasks)
|
|
466
467
|
for (let i = 0; i < ids.length; i++) {
|
|
467
468
|
const t = tasks[ids[i]]
|
|
468
|
-
if (t.type !== 'verify'
|
|
469
|
+
if (t.type !== 'verify') continue
|
|
470
|
+
if (t.status === 'paused') {
|
|
471
|
+
const allReported = t.children.length > 0 && t.children.every(function (cid) { const r = t.childResults[cid]; return r && r.round === t.round })
|
|
472
|
+
if (allReported) { t.status = 'debating'; await advanceVerification(t, t.round); continue }
|
|
473
|
+
}
|
|
474
|
+
if (t.status !== 'debating') continue
|
|
469
475
|
const allReported = t.children.length > 0 && t.children.every(function (cid) { const r = t.childResults[cid]; return r && r.round === t.round })
|
|
470
476
|
if (!allReported) continue
|
|
471
477
|
await advanceVerification(t, t.round)
|