dsh-vibe-math 2.0.13 → 2.0.15

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.13",
4
+ "version": "2.0.15",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": "^22.19.0 || >=24.0.0"
@@ -230,14 +230,18 @@ export function apply(ctx) {
230
230
  +'{"input":"<your real contribution to this discussion>","propose_task":"<task title or null>","task_desc":"...","claim_task":"<task id or null>","propose_verify":"<id or null>","voteSolved":true}'
231
231
  }
232
232
  function verifyPrompt(r, vs){
233
- const others=Object.entries(vs.verdicts).map(([k,v])=>'- '+k+': 正确概率 '+String(v.prob!=null?Number(v.prob).toFixed(2):0.5)+' '+v.reason).join('\n')
233
+ // In a DEBATE round, show the PREVIOUS round's opinions (kept in vs.history) so the resident can
234
+ // see others' stances and give a fresh independent judgement; in the first (independent) round no
235
+ // others' opinions exist yet. vs.verdicts only ever holds the CURRENT round's votes.
236
+ const src = (vs.stage==='debate' && vs.history && Object.keys(vs.history).length>0) ? vs.history : (vs.stage==='debate' ? vs.verdicts : {})
237
+ const others=Object.entries(src).map(([k,v])=>'- '+k+': 正确概率 '+String(v.prob!=null?Number(v.prob).toFixed(2):0.5)+' → '+v.reason).join('\n')
234
238
  return (params.residentPersona?params.residentPersona+'\n':'')
235
239
  +'Resident '+r.rId+' — 团队验证。 The group is verifying object '+vs.targetId+'('+vs.targetType+',提出者 '+vs.targetOwner+')。\n'
236
240
  +'请给出你对「该对象为真」的**正确概率 `verdict`**,仅一个 0–1 数值:**1 = 绝对为真,0 = 绝对为假,0.5 = 完全不确定,其余为介于其间的程度**(不要给 TRUE/FALSE,就给一个数值)。\n'
237
241
  +'判定规则:仅当**全体常驻一致给 1(都认为是真)或一致给 0(都认为是假)**,才按「真/假」写入 Verified/;否则**只作为概率数值(一种程度)保留在库中**,附全组平均正确概率,不写成真/假。\n'
238
242
  +'请给出你**诚实独立的判断**'
239
243
  +(vs.stage==='debate'?',并参考他人意见:\n':'。\n')
240
- +(vs.stage==='debate'&&others?('### 他人意见(已转发给你)\n'+others+'\n'):'')
244
+ +(vs.stage==='debate'&&others?('### 他人上一轮意见(已转发给你)\n'+others+'\n'):'')
241
245
  +'\nReply with ONLY a JSON object:\n'
242
246
  +'{"vote":{"verdict":0.9,"reason":"<your logic>"}}'
243
247
  }
@@ -253,7 +257,7 @@ export function apply(ctx) {
253
257
  residents.set(r.rId,r); await saveAll(); logActivity('spawn',r.rId+' ('+(r.direction||'brainstorm')+')')
254
258
  }
255
259
  async function wakeResident(r, promptText, kind){
256
- if(!r || !r.childId) return false // a removed resident must never be woken (rune: crash on r.childId)
260
+ if(!r || !r.childId) return false // a removed resident must never be woken (else r.childId would crash)
257
261
  clearHeartbeat()
258
262
  busy.add(r.rId); wakeKind.set(r.rId,kind||'normal'); currentResident=r.rId
259
263
  r.lastActiveAt=now(); r.rounds+=1; r.roundsSinceCompact+=1
@@ -431,7 +435,7 @@ export function apply(ctx) {
431
435
  async function beginVerify(pv){
432
436
  clearHeartbeat()
433
437
  pendingVerify=null
434
- verifyState={targetId:pv.targetId,targetType:pv.targetType,targetOwner:pv.proposer||'',stage:'independent',round:0,asked:[],verdicts:{},transcript:[],at:now(),lastVerdictAt:now()}
438
+ verifyState={targetId:pv.targetId,targetType:pv.targetType,targetOwner:pv.proposer||'',stage:'independent',round:0,asked:[],verdicts:{},history:{},transcript:[],at:now(),lastVerdictAt:now()}
435
439
  markProgress();
436
440
  logActivity('verify','debate begin: '+pv.targetId+' ('+pv.targetType+')'); await saveAll(); await scheduleNext()
437
441
  }
@@ -462,7 +466,15 @@ export function apply(ctx) {
462
466
  const allTrue = allVoted && vals.every(x=>Number(x.prob)===1)
463
467
  const allFalse = allVoted && vals.every(x=>Number(x.prob)===0)
464
468
  if(allTrue||allFalse){ await closeVerify(vs,allTrue); return }
465
- if(vs.round+1<params.verdictMaxRounds){ vs.stage='debate'; vs.round+=1; vs.asked=[]; logActivity('verify',vs.targetId+' round '+vs.round+' → debate'); await saveAll(); await scheduleNext(); return }
469
+ if(vs.round+1<params.verdictMaxRounds){
470
+ // Move to a REAL debate round: snapshot the current votes into history (so the next round's
471
+ // prompt can show others' previous stances), then CLEAR verdicts so every resident is asked to
472
+ // give a fresh independent judgement after seeing the debate. Without the clear, allVoted stays
473
+ // true and the debate rounds burn through with NOBODY being re-asked (a silent no-op).
474
+ vs.history=Object.assign({}, vs.verdicts); vs.verdicts={}
475
+ vs.lastVerdictAt=now() // fresh deadlock window for the re-vote round
476
+ vs.stage='debate'; vs.round+=1; vs.asked=[]; logActivity('verify',vs.targetId+' round '+vs.round+' → debate (re-vote after seeing others)'); await saveAll(); await scheduleNext(); return
477
+ }
466
478
  const avg=vals.length? vals.reduce((a,x)=>a+(x.prob!=null?x.prob:0.5),0)/vals.length : 0.5
467
479
  await writeDebateDoc(vs,false,avg); await rewriteSourceProb(vs.targetId, avg, vs.targetOwner); logActivity('verify',vs.targetId+' NOT unanimous → kept unverified (avg '+avg.toFixed(2)+')')
468
480
  verifyState=null; wakeKind.clear(); await saveAll(); await scheduleNext()
@@ -720,6 +732,10 @@ export function apply(ctx) {
720
732
  }
721
733
  async function resume(){
722
734
  currentProject=await readCurrentProject(); await ensureDirs(); await loadAll(); await loadSettings()
735
+ // After loadAll the residentSeq counter is still whatever THIS process had (0 on a fresh process),
736
+ // but persisted residents may already be r-1..r-N. Sync it to the max existing id so a later
737
+ // addMember never collides with an existing resident (it would silently overwrite it).
738
+ for(const key of residents.keys()){ const mm=/^r-(\d+)$/.exec(String(key)); if(mm) residentSeq=Math.max(residentSeq, Number(mm[1])) }
723
739
  lastActivityAt=now(); lastProgressAt=now() // pause must not count as stall time; a resumed run gets a fresh clock
724
740
  if(phase==='idle' && !running && residents.size===0) return {ok:false,message:'nothing to resume'}
725
741
  // If the persisted State came from a DIFFERENT process (crash/restart), the saved
@@ -230,6 +230,8 @@ VibeMath/Projects/<project>/
230
230
  (问题类 target 同理:Verified/问题/<id>.md)
231
231
  4. 否则【公开辩论】:把初评意见+理由写入辩论录,广播全体;各常驻看他人意见后重评
232
232
  (可引用/反驳/修改),直至:全票同向,或不再出现理性新分歧。
233
+ (实现要点:进入 debate 轮时框架把上一轮投票快照进 `vs.history` 并**清空 `vs.verdicts`**,让每个常驻
234
+ 都被重新询问一次——若不清理,`allVoted` 恒真,debate 轮会静默烧掉且**无人被重新询问**。)
233
235
  5. 未全票 → 保留在来源库,概率取各常驻最后估计的平均,附"未达成全体一致"的辩论记录。
234
236
  【要点】不设 v3 的 forced/flat/近共识自动收口——必须真实全体一致,防止强分歧被强行判真。
235
237
  ```