dsh-vibe-math 0.3.0 → 0.3.1
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/package.json +1 -1
- package/vibe-math-v2/vibe-math-v2.js +42 -18
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.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "installer.js",
|
|
7
7
|
"exports": {
|
|
@@ -64,6 +64,10 @@ export function apply(ctx) {
|
|
|
64
64
|
let reportDirty = false
|
|
65
65
|
let tickInFlight = false
|
|
66
66
|
let explorerRetries = {}
|
|
67
|
+
// Process epoch: written to state at init; a DIFFERENT persisted epoch means a
|
|
68
|
+
// previous DSH process wrote this state (in-flight children are gone), while an
|
|
69
|
+
// equal epoch means same-process pause→resume (children may still be alive).
|
|
70
|
+
const processEpoch = String(Date.now()) + '-' + Math.random().toString(36).slice(2, 8)
|
|
67
71
|
|
|
68
72
|
// ================= helpers =================
|
|
69
73
|
function textBlock(t) { return { type: 'text', text: String(t) } }
|
|
@@ -374,6 +378,7 @@ export function apply(ctx) {
|
|
|
374
378
|
return 'id ' + d.id + '「' + d.title + '」method=' + d.method + ' | round=' + d.round + ' status=' + d.status +
|
|
375
379
|
' survival=' + d.survival +
|
|
376
380
|
(d.routes && d.routes.length ? ' | routes: ' + d.routes.map(function (r) { return r.title + '[' + (r.feasibility_signal || '') + ']' }).join('; ') : '') +
|
|
381
|
+
(d.lessons && d.lessons.length ? ' | lessons: ' + d.lessons.join('; ') : '') +
|
|
377
382
|
(d.blockers && d.blockers.length ? ' | blockers: ' + d.blockers.join('; ') : '')
|
|
378
383
|
}
|
|
379
384
|
function solverPrompt(q, dir, round, progressText) {
|
|
@@ -384,11 +389,12 @@ export function apply(ctx) {
|
|
|
384
389
|
head += '\nStart from the last recorded node of direction ' + dir.id + ' (inherit progress, or branch a sub-route under it). Each round you MUST produce, even if incomplete:\n' +
|
|
385
390
|
'- new lemmas / intermediate conclusions WITH full proofs (these go to the Propos/ knowledge base);\n' +
|
|
386
391
|
'- each concrete sub-route tried, its progress overview, an EXPLICIT feasibility signal (e.g. "unremovable singularity", "conflicts with known theorem X"), and any blocker;\n' +
|
|
392
|
+
'- lessons learned from failed attempts (what to avoid, what did not work and why);\n' +
|
|
387
393
|
'- an updated survival probability for this direction.\n'
|
|
388
394
|
head += '\nIf you encounter an EXTREMELY complex auxiliary conjecture/sub-problem q_sub: list it in "sub_questions", TEMPORARILY ASSUME it holds, and continue the main line — every later proposition MUST then be stated as "若 <q_sub 标题> 成立,则:..." so the dependency is explicit.\n'
|
|
389
395
|
head += '\nIf you obtain a COMPLETE solution: adversarially self-check (construct counterexamples, test boundary conditions) BEFORE declaring success; put the full solution text in "solution".\n'
|
|
390
396
|
head += '\nRespond with ONLY a single JSON object wrapped in a ```json code fence — no prose and no braces { } outside the JSON:\n' +
|
|
391
|
-
'{"status":"continue|success|dead-end","solution":"complete solution text, or null","solution_probability":0.85,"lemmas":[{"title":"...","statement":"...","proof":"...","细类型":{"分类名":{}},"布尔估计":0.6,"价值/关键性":0.5,"优先级":1}],"routes":[{"title":"...","progress":"...","feasibility_signal":"...","blocker":"..."}],"survival_probability":0.5,"dead_end_reason":"... or null","sub_questions":[{"title":"...","statement":"..."}]}'
|
|
397
|
+
'{"status":"continue|success|dead-end","solution":"complete solution text, or null","solution_probability":0.85,"lemmas":[{"title":"...","statement":"...","proof":"...","细类型":{"分类名":{}},"布尔估计":0.6,"价值/关键性":0.5,"优先级":1}],"routes":[{"title":"...","progress":"...","feasibility_signal":"...","blocker":"..."}],"lessons":["..."],"survival_probability":0.5,"dead_end_reason":"... or null","sub_questions":[{"title":"...","statement":"..."}]}'
|
|
392
398
|
return head
|
|
393
399
|
}
|
|
394
400
|
function verifierReviewPrompt(r) {
|
|
@@ -595,7 +601,12 @@ export function apply(ctx) {
|
|
|
595
601
|
const ids = Object.keys(tasks)
|
|
596
602
|
for (let i = 0; i < ids.length; i++) {
|
|
597
603
|
const t = tasks[ids[i]]
|
|
598
|
-
if (t.type !== 'verify'
|
|
604
|
+
if (t.type !== 'verify') continue
|
|
605
|
+
if (t.status === 'paused') {
|
|
606
|
+
const allReported = t.children.length > 0 && t.children.every(function (cid) { const r = t.childResults[cid]; return r && r.round === t.round })
|
|
607
|
+
if (allReported) { t.status = 'debating'; await advanceVerification(t, t.round); continue }
|
|
608
|
+
}
|
|
609
|
+
if (t.status !== 'spawning') continue
|
|
599
610
|
if (scheduler.activeCount >= params.maxParallelThreshold) break
|
|
600
611
|
await backfillVerifiers(t)
|
|
601
612
|
}
|
|
@@ -665,6 +676,7 @@ export function apply(ctx) {
|
|
|
665
676
|
dir.round = meta.round
|
|
666
677
|
if (parsed) {
|
|
667
678
|
if (parsed.routes) dir.routes = (dir.routes || []).concat(parsed.routes)
|
|
679
|
+
if (parsed.lessons) dir.lessons = (dir.lessons || []).concat(parsed.lessons)
|
|
668
680
|
if (parsed.dead_end_reason) dir.dead_end_reason = parsed.dead_end_reason
|
|
669
681
|
if (typeof parsed.survival_probability === 'number') dir.survival = clamp01(parsed.survival_probability)
|
|
670
682
|
if (parsed.lemmas && parsed.lemmas.length) { for (let i = 0; i < parsed.lemmas.length; i++) await addLemmaAsProposition(qid, parsed.lemmas[i]) }
|
|
@@ -696,14 +708,19 @@ export function apply(ctx) {
|
|
|
696
708
|
logActivity('solver', qid + '/' + dirId + ' dead-end: ' + dir.dead_end_reason)
|
|
697
709
|
} else {
|
|
698
710
|
const progressText = prog.directions.map(directionSummary).join('\n')
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
agentRegistry[childId].round = meta.round + 1
|
|
702
|
-
dir.round = meta.round + 1
|
|
703
|
-
} catch (e) {
|
|
704
|
-
console.error('vibe-math-v2: solver followup failed: ' + String((e && e.message) || e))
|
|
705
|
-
dir.status = 'dead-end'; dir.dead_end_reason = dir.dead_end_reason || '求解器续轮失败(followup 异常)'
|
|
711
|
+
if (!scheduler.running) {
|
|
712
|
+
// paused/aborted: stop the follow-up chain; keep the direction active for resume
|
|
706
713
|
delete agentRegistry[childId]
|
|
714
|
+
} else {
|
|
715
|
+
try {
|
|
716
|
+
await followupChild(childId, solverPrompt(q, dir, meta.round + 1, progressText))
|
|
717
|
+
agentRegistry[childId].round = meta.round + 1
|
|
718
|
+
dir.round = meta.round + 1
|
|
719
|
+
} catch (e) {
|
|
720
|
+
console.error('vibe-math-v2: solver followup failed: ' + String((e && e.message) || e))
|
|
721
|
+
dir.status = 'dead-end'; dir.dead_end_reason = dir.dead_end_reason || '求解器续轮失败(followup 异常)'
|
|
722
|
+
delete agentRegistry[childId]
|
|
723
|
+
}
|
|
707
724
|
}
|
|
708
725
|
}
|
|
709
726
|
await saveProgress(qid, prog)
|
|
@@ -764,6 +781,7 @@ export function apply(ctx) {
|
|
|
764
781
|
}
|
|
765
782
|
async function advanceVerification(t, round) {
|
|
766
783
|
if (round < params.debateMaxRounds && !consensus(t) && t.children.length > 0) {
|
|
784
|
+
if (!scheduler.running) { t.status = 'paused'; return } // resume will re-advance this task
|
|
767
785
|
t.round = round + 1
|
|
768
786
|
const transcript = buildTranscript(t)
|
|
769
787
|
const nextChildren = []
|
|
@@ -922,23 +940,29 @@ export function apply(ctx) {
|
|
|
922
940
|
|
|
923
941
|
// ================= init / control =================
|
|
924
942
|
async function resolveRootAgent(agent) { if (rootAgent) return rootAgent; if (agent) { rootAgent = agent; return rootAgent } try { const roots = agents.roots ? agents.roots() : []; if (roots && roots.length > 0) { rootAgent = roots[0]; return rootAgent } } catch (e) {} return rootAgent }
|
|
925
|
-
async function init(agent) {
|
|
943
|
+
async function init(agent, fresh) {
|
|
926
944
|
await resolveRootAgent(agent); if (!rootAgent) return { ok: false, message: 'no root agent available' }
|
|
927
945
|
currentProject = await readCurrentProject(); await ensureDirs()
|
|
928
946
|
if ((await readJson('qs/qs.json')) === undefined) await writeJson('qs/qs.json', [])
|
|
929
947
|
params = Object.assign({}, DEFAULT_PARAMS); await loadSettings(); await loadState()
|
|
930
|
-
//
|
|
931
|
-
//
|
|
932
|
-
//
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
948
|
+
// Distinguish same-process continue from cross-process restart via processEpoch:
|
|
949
|
+
// equal epoch = same process (pause→resume; children may still be alive), different
|
|
950
|
+
// epoch = previous process wrote this state (in-flight children are gone).
|
|
951
|
+
const prevEpoch = await readJson('VibeMath_State/process_epoch.json')
|
|
952
|
+
const stale = typeof prevEpoch === 'string' && prevEpoch !== processEpoch
|
|
953
|
+
if (fresh || stale) {
|
|
954
|
+
if (fresh) { const ids = Object.keys(agentRegistry); for (let i = 0; i < ids.length; i++) await interruptChild(ids[i]) }
|
|
955
|
+
if (Object.keys(agentRegistry).length > 0 || Object.keys(tasks).length > 0) {
|
|
956
|
+
logActivity(fresh ? 'start' : 'resume', 'cleared ' + Object.keys(agentRegistry).length + ' agent(s) and ' + Object.keys(tasks).length + ' task(s) (' + (fresh ? 'restart' : 'stale from previous process') + ')')
|
|
957
|
+
agentRegistry = {}; tasks = {}
|
|
958
|
+
}
|
|
936
959
|
}
|
|
960
|
+
await writeJson('VibeMath_State/process_epoch.json', processEpoch)
|
|
937
961
|
scheduler.activeCount = 0; await saveAll()
|
|
938
962
|
return { ok: true }
|
|
939
963
|
}
|
|
940
|
-
async function startScheduler(agent) { const r = await init(agent); if (!r.ok) return r; scheduler.running = true; scheduler.startedAt = now(); scheduler.gate = null; logActivity('start', 'scheduler started for project ' + currentProject); await saveAll(); await maybeWriteReport(true); scheduleTick(); return { ok: true, message: 'scheduler started', project: currentProject, frameworkRoot: frameworkRoot() } }
|
|
941
|
-
async function resumeScheduler(agent) { const r = await init(agent); if (!r.ok) return r; scheduler.running = true; scheduler.gate = null; logActivity('resume', 'scheduler resumed'); await saveAll(); await maybeWriteReport(true); scheduleTick(); return { ok: true, message: 'scheduler resumed', project: currentProject, frameworkRoot: frameworkRoot() } }
|
|
964
|
+
async function startScheduler(agent) { const r = await init(agent, true); if (!r.ok) return r; scheduler.running = true; scheduler.startedAt = now(); scheduler.gate = null; logActivity('start', 'scheduler started for project ' + currentProject); await saveAll(); await maybeWriteReport(true); scheduleTick(); return { ok: true, message: 'scheduler started', project: currentProject, frameworkRoot: frameworkRoot() } }
|
|
965
|
+
async function resumeScheduler(agent) { const r = await init(agent, false); if (!r.ok) return r; scheduler.running = true; scheduler.gate = null; logActivity('resume', 'scheduler resumed'); await saveAll(); await maybeWriteReport(true); scheduleTick(); return { ok: true, message: 'scheduler resumed', project: currentProject, frameworkRoot: frameworkRoot() } }
|
|
942
966
|
async function pauseScheduler() { scheduler.running = false; logActivity('pause', 'scheduler paused'); await saveAll(); return { ok: true, message: 'scheduler paused' } }
|
|
943
967
|
async function abortScheduler() { scheduler.running = false; const ids = Object.keys(agentRegistry); for (let i = 0; i < ids.length; i++) await interruptChild(ids[i]); scheduler.activeCount = 0; logActivity('abort', 'scheduler aborted, ' + ids.length + ' child(ren) interrupted'); await saveAll(); return { ok: true, message: 'scheduler aborted', interrupted: ids.length } }
|
|
944
968
|
async function getStatus() {
|