dsh-vibe-math 2.0.11 → 2.0.13
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
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 — THREE agent presets in one install: vibe-math-v2 (probability-driven: qs.json + Propos knowledge base + explorer→solver→review/debate verdict), vibe-math-v3 (THIRD-generation, recommended: paper-style Markdown knowledge base with Problems/Progress/Propos/Methods/Verified + planner-agent scheduling that decides the next N actions + universal theory/method invention library + agents write their own Markdown directly via a per-file write lock), and vibe-math-v4 (FOURTH-generation: persistent self-organizing resident subagents that message & meet to decide all tasks, verify only by unanimous consensus, /compact at a context threshold, and stop only when all agree the problem is solved). Installing this bundle auto-installs all three presets (v1 was removed at v2.0.0).",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.13",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^22.19.0 || >=24.0.0"
|
|
@@ -253,7 +253,7 @@ export function apply(ctx) {
|
|
|
253
253
|
residents.set(r.rId,r); await saveAll(); logActivity('spawn',r.rId+' ('+(r.direction||'brainstorm')+')')
|
|
254
254
|
}
|
|
255
255
|
async function wakeResident(r, promptText, kind){
|
|
256
|
-
if(!r.childId) return false
|
|
256
|
+
if(!r || !r.childId) return false // a removed resident must never be woken (rune: crash on r.childId)
|
|
257
257
|
clearHeartbeat()
|
|
258
258
|
busy.add(r.rId); wakeKind.set(r.rId,kind||'normal'); currentResident=r.rId
|
|
259
259
|
r.lastActiveAt=now(); r.rounds+=1; r.roundsSinceCompact+=1
|
|
@@ -305,7 +305,7 @@ export function apply(ctx) {
|
|
|
305
305
|
async function recordMethod(rId,o){ const id=o.id||('m-'+shortId()); const lines=['# 方法|'+(o.title||id),'- 标题: '+(o.title||id),'- ID: '+id,'- 类型: '+(o.type||'方法'),'- 状态: 经验','- 可信断言: []','- 价值程度: '+cl(o.value!=null?o.value:0.5),'- 动机用途计划: '+(o.motivation||''),'','## 核心内容',String(o.content||''),'','## 定义与记号',String(o.notation||''),'','## 应用记录','## 改进历史','']; await writeText('Methods/'+rId+'/'+id+'.md',lines.join('\n')); logActivity('record',rId+' 方法 '+id); bumpArtifacts(); return {ok:true,id,file:'Methods/'+rId+'/'+id+'.md'} }
|
|
306
306
|
async function recordSubproblem(rId,o){ const id=o.id||('s-'+shortId()); const lines=['# 子问题|'+(o.title||id),'- 标题: '+(o.title||id),'- ID: '+id,'- 状态: 求解中','- 价值程度: '+cl(o.value!=null?o.value:0.5),'- 动机用途计划: '+(o.motivation||''),'- 依赖: []','','## 陈述',String(o.statement||''),'','## 进度','']; await writeText('Subproblems/'+rId+'/'+id+'.md',lines.join('\n')); logActivity('record',rId+' 子问题 '+id); bumpArtifacts(); return {ok:true,id,file:'Subproblems/'+rId+'/'+id+'.md'} }
|
|
307
307
|
// auto-sync meeting: every meetingKeepEvery new artifacts, convene a general coordination meeting
|
|
308
|
-
function bumpArtifacts(){ artifactCount+=1; markProgress(); if(!meetingState && !verifyState && Number(params.meetingKeepEvery)>0 && artifactCount % Number(params.meetingKeepEvery)===0){ startMeeting('定期同步:分工/进展/是否需要验证','general',null).catch(()=>{}) } }
|
|
308
|
+
function bumpArtifacts(){ artifactCount+=1; markProgress(); if(!meetingState && !verifyState && !pendingMeeting && Number(params.meetingKeepEvery)>0 && artifactCount % Number(params.meetingKeepEvery)===0){ startMeeting('定期同步:分工/进展/是否需要验证','general',null).catch(()=>{}) } }
|
|
309
309
|
function listResidents(){ return Array.from(residents.values()).map(r=>({id:r.rId,direction:r.direction,status:r.status,rounds:r.rounds,contextPct:r.contextPct,insight:r.insight?r.insight.slice(0,80):''})) }
|
|
310
310
|
// identify WHICH resident is calling a resident-facing tool: match the caller's
|
|
311
311
|
// subagent id to a resident's childId. Fall back to the last-woken resident when
|
|
@@ -370,7 +370,11 @@ export function apply(ctx) {
|
|
|
370
370
|
// A meeting must NOT preempt an active or pending verification (unanimous-consensus is the
|
|
371
371
|
// group's truth-making step; preempting it would let every round resurface the same conflict).
|
|
372
372
|
// Wait instead of stealing the floor: park the request and resume it after the verify settles.
|
|
373
|
-
if(verifyState || pendingVerify){
|
|
373
|
+
if(verifyState || pendingVerify){
|
|
374
|
+
// Keep the FIRST deferred request (never overwrite an earlier one with a later agenda).
|
|
375
|
+
if(!pendingMeeting) pendingMeeting = { agenda, type:type||'general', targetId:targetId||null }
|
|
376
|
+
return {ok:true,deferred:true,during:'verify'}
|
|
377
|
+
}
|
|
374
378
|
clearHeartbeat()
|
|
375
379
|
const ids=Array.from(residents.keys())
|
|
376
380
|
// Rotate the per-meeting speaking order so the SAME resident isn't always the "first speaker
|
|
@@ -723,10 +727,19 @@ export function apply(ctx) {
|
|
|
723
727
|
// disk and re-seed the resumed run). Same-process pause→resume keeps continuable ids.
|
|
724
728
|
const crossProcess = persistedEpoch !== processEpoch
|
|
725
729
|
if(crossProcess){ for(const [,r] of residents){ r.childId=''; r.status='brainstorm'; r.roundsSinceCompact=0 } }
|
|
730
|
+
// ANY re-spawn (cross-process OR a same-process abort that already cleared childIds) must get a FRESH
|
|
731
|
+
// coordination/concurrency state and a brainstorm phase. Otherwise: re-spawned brainstorm residents run
|
|
732
|
+
// under phase='active' (brainstorm summary never written), and a LATE subagent/end from an interrupted
|
|
733
|
+
// OLD resident (same rId) deletes the NEW resident's busy mark → A-fill can wake it mid-brainstorm.
|
|
734
|
+
const needRespawn = Array.from(residents.values()).some(r=>!r.childId)
|
|
735
|
+
if(needRespawn){
|
|
736
|
+
for(const [,r] of residents){ r.childId=''; r.status='brainstorm'; r.insight=''; r.roundsSinceCompact=0 }
|
|
737
|
+
busy=new Set(); wakeKind=new Map(); currentResident=''; pendingMeeting=null; pendingVerify=null; verifyState=null; meetingState=null
|
|
738
|
+
}
|
|
726
739
|
for(const [,r] of residents){ if(!r.childId){ await spawnResident(r) } }
|
|
727
740
|
if(!running){ running=true; autoDone=false; if(phase==='idle') phase='active' }
|
|
728
|
-
if(
|
|
729
|
-
logActivity('resume','restarted'+(crossProcess?' (cross-process: re-spawned)':'')); await saveAll(); await scheduleNext(); return {ok:true,message:'resumed',project:currentProject}
|
|
741
|
+
if(needRespawn && phase!=='brainstorm') phase='brainstorm' // let re-spawned residents re-bootstrap together
|
|
742
|
+
logActivity('resume','restarted'+(crossProcess?' (cross-process: re-spawned)':needRespawn?' (re-spawned)':'')); await saveAll(); await scheduleNext(); return {ok:true,message:'resumed',project:currentProject}
|
|
730
743
|
}
|
|
731
744
|
function status(){ return { ok:true, running, phase, autoDone, project:currentProject, residentCount:residents.size,
|
|
732
745
|
residents:listResidents(), busy:[...busy], taskboard:taskboard.length,
|
|
@@ -739,7 +752,14 @@ export function apply(ctx) {
|
|
|
739
752
|
pendingVerify: pendingVerify?pendingVerify.targetId:null,
|
|
740
753
|
meetings:meetings.length, recentActivity: activityLog.slice(-8) } }
|
|
741
754
|
async function addMember(direction){ const r=newResident(direction||''); await spawnResident(r); return {ok:true,id:r.rId,direction:r.direction} }
|
|
742
|
-
async function removeMember(id){ const r=residents.get(id); if(!r) return {ok:false}; if(r.childId){ try{ subagents.interrupt(r.childId,{kind:'ancestor',agent:rootAgent}) }catch(e){} } residents.delete(id); busy.delete(id); mailboxes.delete(id);
|
|
755
|
+
async function removeMember(id){ const r=residents.get(id); if(!r) return {ok:false}; if(r.childId){ try{ subagents.interrupt(r.childId,{kind:'ancestor',agent:rootAgent}) }catch(e){} } residents.delete(id); busy.delete(id); mailboxes.delete(id); wakeKind.delete(id)
|
|
756
|
+
// Reconcile in-progress coordination so a removed member cannot hang consensus or crash a round:
|
|
757
|
+
// drop its meeting speech / verify verdict / deferred-meeting / pending-verify if it owned them, and
|
|
758
|
+
// prune it from the meeting's speaking order so the find() there never selects a ghost.
|
|
759
|
+
if(meetingState){ delete meetingState.inputs[id]; meetingState.order=(meetingState.order||[]).filter(x=>x!==id) }
|
|
760
|
+
if(verifyState){ delete verifyState.verdicts[id] }
|
|
761
|
+
if(pendingVerify && pendingVerify.proposer===id) pendingVerify=null
|
|
762
|
+
await saveAll(); return {ok:true} }
|
|
743
763
|
// Normalize one parameter value to its intended type so a string from /v4 set or configure
|
|
744
764
|
// becomes the right number/array. Keeps settings.json clean regardless of how it was set.
|
|
745
765
|
function normalizeParam(k, v){
|
|
@@ -367,6 +367,7 @@ VibeMath/Projects/<project>/
|
|
|
367
367
|
| **非全票验证不写回平均概率** | `finalizeVerify` 算出 `avg` 只写进辩论录,源卡 `- 概率:` 保持原值,未兑现设计 §8"留库附概率"。 | 新增 `findSourceRel`/`rewriteSourceProb`,非全票时把 `avg` 写回源卡 `- 概率:`(状态仍 `未定论`)。 |
|
|
368
368
|
| **方法型验证被误标为"命题"** | `writeVerifiedCard` 把方法目标写进 `Verified/命题/` 且类型=命题。 | 按 `targetType` 标 `类型: 方法`(子问题→问题,方法→方法,其余→命题),来源卡标 `已验证·真/假`。 |
|
|
369
369
|
| **同进程 abort→resume 不重建常驻** | `processEpoch` 进程级,同进程 abort(interrupt 杀掉常驻)后 resume 判非跨进程→保留死 childId;且 `phase=idle && !running` 时 resume 直接拒绝。 | `initAbort` 清空 `childId` 并 `saveAll()`;`resume` 守卫改为 `phase==='idle' && !running && residents.size===0`(有常驻即可 重建)。 |
|
|
370
|
+
| **abort→resume 重种化不彻底(牵连修复)** | 同进程 abort 后 `phase='idle'`、childId 已清空,但旧居民 `status='active'` 且旧 `insight` 仍在;resume 走"非跨进程"分支不清状态,直接 re-spawn 后落入 `phase='active'`——重种化居民在第一轮 brainstorm 期间就被当作 active 处理(brainstorm 汇总不写);且被 interrupt 的**旧**居民迟到的 `subagent/end`(同名 rId)会删除**新**居民的 busy 标记。 | `resume()` 用 `needRespawn`(任一 childId 为空)统一判定:**任何 re-spawn(跨进程或同进程 abort)** 都清空 busy/wakeKind/currentResident/pendingMeeting/pendingVerify/verifyState/meetingState,并把居民 `status='brainstorm'`、`insight=''`、`phase='brainstorm'`——让重种化居民真正重新头脑风暴、汇总正常写出、旧居民的迟到 end 不会污染新居民的 busy。 |
|
|
370
371
|
| **自动同步会议计数不一致** | `bumpArtifacts` 只在记录方法/子问题时调用,`recordProposition`/`publish_progress` 不计;`artifactCount` 未持久化。 | `recordProposition` 也 `bumpArtifacts()`;`artifactCount` 持久化到 `session.json` 并在 `start()` 时清零。 |
|
|
371
372
|
| **唤醒信号硬编码 60s** | `spawnResident`/`wakeResident` 用 `makeSignal(60000)`,比 `activityTimeoutMs`(120s) 短。 | 改用 `makeSignal(params.activityTimeoutMs||60000)`。 |
|
|
372
373
|
| **`verdictMaxRounds`/`meetingKeepEvery` 不可调/不展示** | `verdictMaxRounds` 不在 `vibe_v4_set` schema;两者都不在 `status()` 参数串。 | `vibe_v4_set` 增加 `verdictMaxRounds`;`status()` 参数串补 `meetingKeepEvery` 与 `verdictMaxRounds`。 |
|
|
@@ -553,7 +554,8 @@ VibeMath/Projects/<project>/
|
|
|
553
554
|
- 分级保活 B 增加 `busy.size===0` 守卫:任何常驻正在工作时不触发,避免预抢占在途轮次。
|
|
554
555
|
|
|
555
556
|
### 会议与验证互斥(不抢占)
|
|
556
|
-
- 并行填充常驻后,一个常驻可能"提议验证(propose_verify)"而另一个同时"提议开会(propose_meeting)"。**会议不得抢占验证**:`startMeeting` 在 `verifyState || pendingVerify` 时改为把会议请求**暂存**(`pendingMeeting`,仅记录 agenda/type/target)并返回 `{deferred:true}`;`scheduleNext` 在所有 meeting/verify/pending 都清空后才恢复该暂存会议。这样统一共识验证(全真/全假)作为"求真"
|
|
557
|
+
- 并行填充常驻后,一个常驻可能"提议验证(propose_verify)"而另一个同时"提议开会(propose_meeting)"。**会议不得抢占验证**:`startMeeting` 在 `verifyState || pendingVerify` 时改为把会议请求**暂存**(`pendingMeeting`,仅记录 agenda/type/target)并返回 `{deferred:true}`;`scheduleNext` 在所有 meeting/verify/pending 都清空后才恢复该暂存会议。这样统一共识验证(全真/全假)作为"求真"环节不会被会议的协调讨论打断,验证做完后再开会开会协调下一步——两者互斥但都不丢失(暂存会议之后补开)。**暂存只保留第一条**(`!pendingMeeting` 才写入),避免后到的请求覆盖先到的。
|
|
558
|
+
- **进行中增删常驻的一致性**:在会议/验证进行中 `removeMember` 会**同步清理**该常驻的会议发言(`delete meetingState.inputs[id]`)、验证投票(`delete verifyState.verdicts[id]`)、若它是待验证的提出者则清 `pendingVerify`,并从会议发言顺序 `st.order` 里剔除它;`wakeResident` 对已经不存在的常驻**防御性返回 false**(不再因 `r.childId` 抛 TypeError)。这样移除一个常驻不会让共识**卡在幽灵身上**,也不会让会议/验证循环去唤醒一个已删除的常驻而导致崩溃。
|
|
557
559
|
|
|
558
560
|
> 效果:一个卡死/坏掉的会议或验证最多阻塞 `activityTimeoutMs`×2 后自动释放,团队重新回到 A/B 分级保活,**不会永久停死**。仍符合"框架只促成、从不指派任务"(放弃只是终止一个无法推进的会议,把控制权交还团队的自组织循环)。
|
|
559
561
|
>
|