dsh-vibe-math 1.4.0 → 2.0.0
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 +54 -102
- package/cordis.patch.yml +3 -3
- package/installer.js +25 -14
- package/package.json +5 -9
- package/vibe-math-v3//345/256/236/347/216/260/346/226/271/346/241/210.md +2 -2
- package/vibe-math-v4/agent.cordis.yml +8 -1
- package/vibe-math-v4/vibe-math-v4.js +80 -15
- package/vibe-math-v4//345/256/236/347/216/260/346/226/271/346/241/210.md +35 -0
- package/vibe-math-v1/agent.cordis.yml +0 -198
- package/vibe-math-v1/preset.yml +0 -2
- package/vibe-math-v1/vibe-math.js +0 -692
- package/vibe-math-v1//345/256/236/347/216/260/346/226/271/346/241/210-/345/244/232/344/273/243/347/220/206/346/225/260/345/255/246/351/227/256/351/242/230/346/261/202/350/247/243/344/270/216/351/252/214/350/257/201/346/241/206/346/236/266.md +0 -161
|
@@ -32,7 +32,13 @@ export function apply(ctx) {
|
|
|
32
32
|
residentCount: 4, compactThreshold: 66, compactAfterRounds: 8,
|
|
33
33
|
maxParallel: 3, activityTimeoutMs: 120000, verdictMaxRounds: 3,
|
|
34
34
|
meetingKeepEvery: 5, // 每积累 N 个新产物自动触发一次同步会议
|
|
35
|
+
// model/provider inheritance: '' = the resident inherits the parent (main assistant)
|
|
36
|
+
// route (provider + model). Set them to override the resident's LLM backend/model.
|
|
35
37
|
provider: '', model: '', residentPersona: '',
|
|
38
|
+
// tool permissions: an allow/deny list of tool names applied via startContinuable's
|
|
39
|
+
// toolFilter (scoped tools.restrict() in the child). Empty = inherit all tools.
|
|
40
|
+
// CAUTION: only set one of these; an empty allow:[] would deny EVERY tool.
|
|
41
|
+
toolAllow: [], toolDeny: [],
|
|
36
42
|
}
|
|
37
43
|
let params = Object.assign({}, DEFAULT_PARAMS)
|
|
38
44
|
let running = false, autoDone = false, phase = 'idle'
|
|
@@ -59,6 +65,19 @@ export function apply(ctx) {
|
|
|
59
65
|
function logActivity(event,detail){ activityLog.push({at:now(),event,detail:String(detail||'')}); if(activityLog.length>activityLogCap) activityLog.shift() }
|
|
60
66
|
function logDecision(kind,detail){ decisions.push({at:now(),kind,detail:String(detail||'')}) }
|
|
61
67
|
function pickProvider(){ try { const n=subagents.list?subagents.list():[]; if(n.indexOf('spawn')!==-1) return 'spawn'; if(n.indexOf('fork')!==-1) return 'fork' } catch(e){} return 'spawn' }
|
|
68
|
+
// Per-resident model/provider inheritance: when params.provider / params.model are set,
|
|
69
|
+
// the resident uses that exact route; when left '' the resident inherits the parent's
|
|
70
|
+
// (main assistant) route — the documented DSH default (resolveChildAgentOptions merges
|
|
71
|
+
// requested over parent). No override is applied for empty values.
|
|
72
|
+
function residentAgentOptions(){ const ao={}; if(params.provider) ao.provider=params.provider; if(params.model) ao.model=params.model; return ao }
|
|
73
|
+
// Tool permission (scoped toolFilter). Only emit a filter when allow or deny has entries;
|
|
74
|
+
// an empty object is rejected by DSH ("must declare allow and/or deny").
|
|
75
|
+
function residentToolFilter(){
|
|
76
|
+
const allow=Array.isArray(params.toolAllow)?params.toolAllow.filter(x=>String(x).trim()):[]
|
|
77
|
+
const deny=Array.isArray(params.toolDeny)?params.toolDeny.filter(x=>String(x).trim()):[]
|
|
78
|
+
if(allow.length===0 && deny.length===0) return undefined
|
|
79
|
+
const f={}; if(allow.length) f.allow=allow; if(deny.length) f.deny=deny; return f
|
|
80
|
+
}
|
|
62
81
|
function makeSignal(ms){ return AbortSignal.timeout(ms||30000) }
|
|
63
82
|
function workspaceRoot(){ try { if(rootAgent&&rootAgent.session&&rootAgent.session.header&&rootAgent.session.header.cwd) return rootAgent.session.header.cwd } catch(e){} if(sandboxPolicy&&sandboxPolicy.workspaceRoot) return sandboxPolicy.workspaceRoot; return '.' }
|
|
64
83
|
function vibeRoot(){ return (workspaceRoot()+'/VibeMath').replace(/\\/g,'/') }
|
|
@@ -150,6 +169,12 @@ export function apply(ctx) {
|
|
|
150
169
|
s.push('### 可用工具')
|
|
151
170
|
s.push(toolList())
|
|
152
171
|
s.push('')
|
|
172
|
+
if(level==='full'){
|
|
173
|
+
s.push('### 可自主发明理论/工具(鼓励,但不强迫)')
|
|
174
|
+
s.push('请注意:你可以(但**不强迫**,完全视实际需要而定)尝试自主构建新的理论框架或工具——例如对某种系统做抽象化、一般化,抽离/推广出更一般的结构或理论框架;然后不断完善这个理论框架,在该框架下推得各种定理、性质、结论,以利于该框架下问题的解决。这就像为解决方程问题发明了群论、为分析需要建立了泛函分析框架——它比单纯解决当前问题更有学术价值,因为你直接得到了一类更普遍的方法/理论体系。')
|
|
175
|
+
s.push('若你发明了这样的理论/工具,请**阐明它对原问题的用处、价值**;后续可根据需要不断**完善、一般化、推广**它。把这类成果记入你的 Methods/<你>/ 库。')
|
|
176
|
+
s.push('')
|
|
177
|
+
}
|
|
153
178
|
s.push('### 规则')
|
|
154
179
|
s.push('- 只有 Verified/(或卡片标"已验证·真/假")算已确立;其余都是你的实验性工作,请区分"猜想/已知"。')
|
|
155
180
|
s.push('- 验证必须**全组一致**(全真或全假);你只信全票结果。未全票的对象留在库里带概率。')
|
|
@@ -210,7 +235,8 @@ export function apply(ctx) {
|
|
|
210
235
|
let residentSeq = 0
|
|
211
236
|
function newResident(dir){ const rId='r-'+(++residentSeq); return {rId,childId:'',direction:dir||'',status:'brainstorm',rounds:0,roundsSinceCompact:0,lastActiveAt:now(),insight:'',contextPct:0,contextSeed:'',needCompact:false} }
|
|
212
237
|
async function spawnResident(r){
|
|
213
|
-
const
|
|
238
|
+
const ao=residentAgentOptions(); const tf=residentToolFilter()
|
|
239
|
+
const started=await subagents.startContinuable({provider:pickProvider(),label:r.rId,request:{prompt:[textBlock(brainstormPrompt(r))],parent:rootAgent,agentOptions:ao,...(tf?{toolFilter:tf}:{})},signal:makeSignal(params.activityTimeoutMs||60000)})
|
|
214
240
|
r.childId=started.childId; r.status='brainstorm'; r.lastActiveAt=now()
|
|
215
241
|
childOwner.set(started.childId,sessionId); busy.add(r.rId); wakeKind.set(r.rId,'normal'); currentResident=r.rId
|
|
216
242
|
residents.set(r.rId,r); await saveAll(); logActivity('spawn',r.rId+' ('+(r.direction||'brainstorm')+')')
|
|
@@ -220,16 +246,28 @@ export function apply(ctx) {
|
|
|
220
246
|
clearHeartbeat()
|
|
221
247
|
busy.add(r.rId); wakeKind.set(r.rId,kind||'normal'); currentResident=r.rId
|
|
222
248
|
r.lastActiveAt=now(); r.rounds+=1; r.roundsSinceCompact+=1
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
//
|
|
249
|
+
// Context compaction has TWO distinct needs. Confusing them is the bug that made
|
|
250
|
+
// '[核心规则重申]+[CONTEXT COMPACT]' repeat at the start of nearly every prompt:
|
|
251
|
+
// (a) r.needCompact (set by a REAL /compact) => the resident's rules may be blurred, so
|
|
252
|
+
// re-anchor the short core rules on the next wake of ANY kind, then CLEAR the flag.
|
|
253
|
+
// (Short recap only; no self-summary directive — the real compact already condensed.)
|
|
254
|
+
// (b) soft-compact trigger (contextPct>=threshold OR roundsSinceCompact>=afterRounds) =>
|
|
255
|
+
// the resident's context genuinely grew; ask it to self-summary. ONLY on a normal
|
|
256
|
+
// research round (kind==='normal'): a meeting/verify reply has no contextPct/compacted
|
|
257
|
+
// fields, so a directive injected there is never acknowledged and would repeat forever.
|
|
226
258
|
let prompt = promptText
|
|
227
|
-
|
|
259
|
+
const isNormal = (kind||'normal')==='normal'
|
|
260
|
+
const wantSoft = isNormal && (Number(r.contextPct)>=Number(params.compactThreshold) || Number(r.roundsSinceCompact)>=Number(params.compactAfterRounds))
|
|
261
|
+
const wantReanchor = r.needCompact
|
|
262
|
+
if(wantSoft){
|
|
228
263
|
prompt = coreRulesBrief() + '\n' +
|
|
229
264
|
'[CONTEXT COMPACT — your conversation is at/near the limit. Do NOT re-derive history.\n' +
|
|
230
265
|
'Condense your current working state into ONE tight self-summary (findings so far, active direction, key artifacts you recorded, next concrete steps, open questions), then answer this round in the normal JSON format as usual.\n' +
|
|
231
266
|
'Set "contextPct": 15 (your post-compact usage) and "compacted": true in the reply so the framework records the condensed seed.]\n\n' + promptText
|
|
232
267
|
r.needCompact = true
|
|
268
|
+
} else if(wantReanchor){
|
|
269
|
+
prompt = coreRulesBrief() + '\n' + prompt
|
|
270
|
+
r.needCompact = false
|
|
233
271
|
}
|
|
234
272
|
try { await subagents.followup(rootAgent,r.childId,[textBlock(prompt)],{source:{kind:'user'},signal:makeSignal(params.activityTimeoutMs||60000)}); return true }
|
|
235
273
|
catch(e){ console.error('vibe-v4 wake '+r.rId+' failed: '+String((e&&e.message)||e)); busy.delete(r.rId); return false }
|
|
@@ -261,6 +299,18 @@ export function apply(ctx) {
|
|
|
261
299
|
async function saveTaskboard(){ await writeJson('State/taskboard.json',taskboard); await writeTaskboard() }
|
|
262
300
|
function listTasks(){ return taskboard.filter(t=>t.status!=='done') }
|
|
263
301
|
async function reportContext(rId,pct){ const r=residents.get(rId); if(r){ r.contextPct=clPct(pct); if(Number(pct)<30) r.needCompact=false; } return {ok:true} }
|
|
302
|
+
// Apply context/compact bookkeeping from a resident's reply, so the flag can clear even when
|
|
303
|
+
// the reply came through a meeting/verify branch (defensive) as well as the normal branch.
|
|
304
|
+
function postmark(r, parsed){
|
|
305
|
+
if(typeof parsed.contextPct==='number') r.contextPct=clPct(parsed.contextPct)
|
|
306
|
+
if(parsed.compacted===true || (r.needCompact && parsed.summary)){
|
|
307
|
+
r.contextSeed=String(parsed.summary||r.contextSeed||'')
|
|
308
|
+
r.contextPct=Math.min(r.contextPct||15,25)
|
|
309
|
+
r.roundsSinceCompact=0
|
|
310
|
+
r.needCompact=false
|
|
311
|
+
logActivity('compact', r.rId+' consolidated context')
|
|
312
|
+
}
|
|
313
|
+
}
|
|
264
314
|
|
|
265
315
|
// ---- messaging ----
|
|
266
316
|
async function postMessage(from,to,content){
|
|
@@ -293,15 +343,21 @@ export function apply(ctx) {
|
|
|
293
343
|
async function startMeeting(agenda,type,targetId){
|
|
294
344
|
if(meetingState) return {ok:false,message:'meeting already in progress'}
|
|
295
345
|
clearHeartbeat()
|
|
296
|
-
|
|
346
|
+
const ids=Array.from(residents.keys())
|
|
347
|
+
// Rotate the per-meeting speaking order so the SAME resident isn't always the "first speaker
|
|
348
|
+
// who sees no one else's contribution"; a real discussion lets each member lead sometimes.
|
|
349
|
+
const rot=Math.floor(Math.random()*Math.max(1,ids.length))
|
|
350
|
+
const order=ids.slice(rot).concat(ids.slice(0,rot))
|
|
351
|
+
meetingState={id:'mt-'+shortId(),agenda,type:type||'general',targetId:targetId||null,round:0,asked:[],inputs:{},transcript:[],order}
|
|
297
352
|
logActivity('meeting','start: '+agenda); await saveAll(); await scheduleNext(); return {ok:true,id:meetingState.id}
|
|
298
353
|
}
|
|
299
354
|
async function continueMeetingRound(){
|
|
300
355
|
if(!meetingState) return
|
|
301
356
|
const ids=Array.from(residents.keys()); const allSpoke=ids.every(id=>meetingState.inputs[id]!==undefined)
|
|
302
357
|
if(allSpoke){ await finalizeMeeting(); return }
|
|
303
|
-
// only wake IDLE un-spoken residents; in-flight ones re-trigger this on end.
|
|
304
|
-
const
|
|
358
|
+
// only wake IDLE un-spoken residents (rotated order); in-flight ones re-trigger this on end.
|
|
359
|
+
const order=meetingState.order||ids
|
|
360
|
+
const id=order.find(x=>meetingState.inputs[x]===undefined && !busy.has(x)); if(!id) return
|
|
305
361
|
const r=residents.get(id)
|
|
306
362
|
await wakeResident(r, meetingPrompt(r,meetingState), 'meeting'); await saveAll()
|
|
307
363
|
}
|
|
@@ -490,6 +546,7 @@ export function apply(ctx) {
|
|
|
490
546
|
realCompact(r).catch(()=>{}) // best-effort real DSH /compact of this resident while idle
|
|
491
547
|
const output=blocksToText(info&&info.lastAssistantMessage)
|
|
492
548
|
const parsed=parseReply(output)
|
|
549
|
+
postmark(r, parsed) // context/compact bookkeeping, regardless of wake kind (clears any leak)
|
|
493
550
|
const kind=wakeKind.get(r.rId)||'normal'
|
|
494
551
|
if(kind==='meeting' && meetingState){
|
|
495
552
|
meetingState.inputs[r.rId]={input:parsed.input||parsed.summary||'',voteSolved:typeof parsed.voteSolved==='boolean'?parsed.voteSolved:null,propose_verify:parsed.propose_verify||null,propose_task:parsed.propose_task||null,task_desc:parsed.task_desc||'',claim_task:parsed.claim_task||null}
|
|
@@ -512,9 +569,6 @@ export function apply(ctx) {
|
|
|
512
569
|
// normal turn
|
|
513
570
|
if(r.status==='brainstorm'){ r.insight=parsed.summary||output; r.status='active' }
|
|
514
571
|
if(typeof parsed.solved==='boolean') reports.push({rId:r.rId,solved:parsed.solved,summary:parsed.summary||'',at:now()})
|
|
515
|
-
// context / compact: record the condensed seed + post-compact usage, clear the flag
|
|
516
|
-
if(typeof parsed.contextPct==='number'){ r.contextPct=clPct(parsed.contextPct) }
|
|
517
|
-
if(parsed.compacted===true || (r.needCompact && parsed.summary)){ r.contextSeed=String(parsed.summary||''); r.contextPct=Math.min(r.contextPct||15,25); r.roundsSinceCompact=0; r.needCompact=false; logActivity('compact',r.rId+' consolidated context') }
|
|
518
572
|
if(parsed.propose_verify) pendingVerify={targetId:parsed.propose_verify,targetType:guessTargetType(parsed.propose_verify),proposer:r.rId,at:now()}
|
|
519
573
|
// group-conversation relay: the resident may choose to speak to the whole team (input) —
|
|
520
574
|
// forward it to the others so this is a real discussion group, not private monologues.
|
|
@@ -559,14 +613,22 @@ export function apply(ctx) {
|
|
|
559
613
|
}
|
|
560
614
|
function status(){ return { ok:true, running, phase, autoDone, project:currentProject, residentCount:residents.size,
|
|
561
615
|
residents:listResidents(), busy:[...busy], taskboard:taskboard.length,
|
|
562
|
-
params:['residentCount','compactAfterRounds','compactThreshold','maxParallel','activityTimeoutMs','meetingKeepEvery','verdictMaxRounds'].map(k=>k+'='+params[k]).join(', ') } }
|
|
616
|
+
params:['residentCount','compactAfterRounds','compactThreshold','maxParallel','activityTimeoutMs','meetingKeepEvery','verdictMaxRounds','provider','model','residentPersona','toolAllow','toolDeny'].map(k=>k+'='+(Array.isArray(params[k])?params[k].join(','):params[k])).join(', ') } }
|
|
563
617
|
function report(){ return { ok:true, running, phase, autoDone, project:currentProject, problem:problemText,
|
|
564
618
|
residents:listResidents(), taskboard:taskboard.filter(t=>t.status!=='done'),
|
|
565
619
|
verify: verifyState?{target:verifyState.targetId,stage:verifyState.stage}:null, meetings:meetings.length,
|
|
566
620
|
recentActivity: activityLog.slice(-8) } }
|
|
567
621
|
async function addMember(direction){ const r=newResident(direction||''); await spawnResident(r); return {ok:true,id:r.rId,direction:r.direction} }
|
|
568
622
|
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); await saveAll(); return {ok:true} }
|
|
569
|
-
|
|
623
|
+
// Normalize one parameter value to its intended type so a string from /v4 set or configure
|
|
624
|
+
// becomes the right number/array. Keeps settings.json clean regardless of how it was set.
|
|
625
|
+
function normalizeParam(k, v){
|
|
626
|
+
const INT_KEYS=['residentCount','compactThreshold','compactAfterRounds','maxParallel','activityTimeoutMs','verdictMaxRounds','meetingKeepEvery']
|
|
627
|
+
if(INT_KEYS.includes(k)){ const n=Number(v); return Number.isFinite(n)?n:v }
|
|
628
|
+
if(k==='toolAllow'||k==='toolDeny'){ if(Array.isArray(v)) return v.map(x=>String(x).trim()).filter(Boolean); if(typeof v==='string') return v.split(',').map(x=>x.trim()).filter(Boolean); return [] }
|
|
629
|
+
return v
|
|
630
|
+
}
|
|
631
|
+
function setParams(upd){ for(const k of Object.keys(upd||{})){ if(k in params) params[k]=normalizeParam(k, upd[k]) } saveSettings().catch(()=>{}); return {ok:true} }
|
|
570
632
|
// ---- create / configure (no auto-start) + settings-file persistence ----
|
|
571
633
|
async function loadSettings(){ const s=await readJson('State/settings.json'); if(s&&typeof s==='object'){ for(const k of Object.keys(s)){ if(k in params) params[k]=s[k] } } }
|
|
572
634
|
async function saveSettings(){ await writeJson('State/settings.json', params) }
|
|
@@ -575,7 +637,7 @@ export function apply(ctx) {
|
|
|
575
637
|
async function configure(cfg){
|
|
576
638
|
if(cfg && cfg.project && String(cfg.project).trim()) currentProject=String(cfg.project).trim()
|
|
577
639
|
if(cfg && cfg.problem) problemText=String(cfg.problem)
|
|
578
|
-
if(cfg && cfg.params && typeof cfg.params==='object')
|
|
640
|
+
if(cfg && cfg.params && typeof cfg.params==='object') setParams(cfg.params)
|
|
579
641
|
await writeCurrentProject(); await ensureDirs(); await saveSettings()
|
|
580
642
|
// create the problem card so the project is complete BEFORE the run starts
|
|
581
643
|
if(problemText){ const pid=slugify(problemText.slice(0,40))||'problem'; await writeText('Problems/'+pid+'.md','# 问题|'+pid+'\n- ID: '+pid+'\n- 类型: 问题\n- 状态: 求解中\n- 优先级: 1\n- 依赖: []\n\n## 陈述\n'+problemText+'\n') }
|
|
@@ -624,7 +686,10 @@ export function apply(ctx) {
|
|
|
624
686
|
registerTool('vibe_v4_list_members','List residents.',objParams({}),(s)=>({ok:true,residents:s.listResidents()}))
|
|
625
687
|
registerTool('vibe_v4_add_member','Add a resident.',objParams({direction:{type:'string'}}),(s,a)=>s.addMember(a.direction))
|
|
626
688
|
registerTool('vibe_v4_remove_member','Close a resident.',objParams({id:{type:'string'}},['id']),(s,a)=>s.removeMember(a.id))
|
|
627
|
-
|
|
689
|
+
// model/provider inheritance: set model/provider to override the residents' LLM route (''=inherit
|
|
690
|
+
// the main assistant's route). toolAllow/toolDeny are per-resident tool permissions (scoped
|
|
691
|
+
// restrict). residentPersona prepends a persona line to every resident prompt.
|
|
692
|
+
registerTool('vibe_v4_set','Set V4 parameters. model/provider override resident LLM route (empty=inherit main); toolAllow/toolDeny restrict resident tools (arrays of tool names); residentPersona adds a persona line.',objParams({residentCount:{type:'integer'},compactAfterRounds:{type:'integer'},compactThreshold:{type:'integer'},meetingKeepEvery:{type:'integer'},maxParallel:{type:'integer'},activityTimeoutMs:{type:'integer'},verdictMaxRounds:{type:'integer'},provider:{type:'string'},model:{type:'string'},residentPersona:{type:'string'},toolAllow:{type:'array',items:{type:'string'}},toolDeny:{type:'array',items:{type:'string'}}}),(s,a)=>{ s.setParams(a); return {ok:true} })
|
|
628
693
|
// resident-facing tools: route to the CALLING resident (exec.agent.id === childId);
|
|
629
694
|
// fall back to the last-woken resident when called by the host/assistant.
|
|
630
695
|
registerTool('vibe_v4_send_message','(resident) Send a message to another resident.',objParams({to:{type:'string'},content:{type:'string'}},['to','content']),(s,a,x)=>s.postMessage(s.residentIdOf(x),a.to,a.content))
|
|
@@ -480,6 +480,41 @@ VibeMath/Projects/<project>/
|
|
|
480
480
|
- **补上缺失的 `/v4 set` 分支**:此前 usage 列了 `set` 但命令处理器没实现,`/v4 set` 会掉到 usage;现支持 `key=value` 解析并 `setParams`(也持久化到 settings)。
|
|
481
481
|
- **真实 `/compact` 后重申规则**:`realCompact` 成功压缩常驻真实会话后,置 `needCompact=true`,使下一次唤醒**重申核心规则**(与软压缩一致),避免真实压缩后常驻淡忘规则。
|
|
482
482
|
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## 24. 自主发明理论 / 模型与工具权限 / 压缩重申泄漏修复(v1.4.1)
|
|
486
|
+
|
|
487
|
+
针对一次真实 3 常驻 run(HRT 4 猜想)的深入审计 + 用户三条新增要求:
|
|
488
|
+
|
|
489
|
+
### 1. 初始提示告知"可自主构建新的理论框架/工具"(v1.4.1-①)
|
|
490
|
+
在 `contextBrief(r,'full')`(**仅首轮 brainstorm**,符合"背景只讲一次")新增一节 **"可自主发明理论/工具(鼓励,但不强迫)"**:
|
|
491
|
+
- 常驻可(但**不强迫**、完全视实际需要)**自主尝试构建新的理论框架或工具**——对某种系统做**抽象化、一般化**,抽离/推广出更一般的结构或理论框架;然后**不断完善**它,在该框架下推得各种**定理、性质、结论**,以利于该框架下问题的解决。
|
|
492
|
+
- 类比:为解决方程问题发明了**群论**、为分析需要建立了**泛函分析**框架——这比单纯解决当前问题更有价值,因为直接得到了一类**更普遍的方法/理论体系**。
|
|
493
|
+
- 若发明了这样的理论/工具,请**阐明它对原问题的用处、价值**;后续可**不断完善、一般化、推广**它,并把这类成果记入 `Methods/<你>/` 库。
|
|
494
|
+
- 这是**鼓励,不是指派**;不写固定模板、不强制"每轮必须发明"。
|
|
495
|
+
|
|
496
|
+
### 2. 补齐"模型继承关系 + 工具权限"参数(v1.4.1-②)
|
|
497
|
+
此前 `provider`/`model` 参数在 `DEFAULT_PARAMS` 里**声明但从未被使用**(死参数),且**没有任何工具权限参数**。现补齐并真正落地:
|
|
498
|
+
- **模型继承**:默认**常驻继承主代理(main assistant)的 provider/model 路由**(DSH `resolveChildAgentOptions` 把请求项并到父路由之上)。通过 `params.provider`/`params.model` 可**覆盖**常驻的 LLM 后端/模型(空=继承)。
|
|
499
|
+
- **工具权限**:新增 `params.toolAllow` / `params.toolDeny`,经 `startContinuable` 的 `toolFilter` 做**作用域 `tools.restrict()`**(被点名的工具从常驻提示里消失且拒绝执行)。默认两者为空 → **常驻继承全部工具**(含 fs 与各 `vibe_v4_*`);只有显式配置才收权。⚠️ 注意"deny-all 陷阱":**空 `allow:[]` 会拒绝一切工具**,因此只有当 allow 或 deny 至少有一项时才会发出 filter。
|
|
500
|
+
- **接线**:`spawnResident` 现把 `residentAgentOptions()`(provider/model)与 `residentToolFilter()`(toolAllow/toolDeny)传入 `startContinuable`;`setParams` 做类型归一(整数 / 逗号分隔的数组);`vibe_v4_set` schema 与 `status()` 参数串也已加这些新参数。
|
|
501
|
+
|
|
502
|
+
### 3. 修复"[核心规则重申]+[CONTEXT COMPACT]"在提示开头重复泄漏(v1.4.1-③)
|
|
503
|
+
这是真实 run 的核心 bug。**根因**(从 `State/residents.json` 证实):r-1 的 `needCompact:true` 常年不释放、`roundsSinceCompact:10`(>8)——框架在**所有**唤醒(含 meeting/verify)里都根据"`needCompact || contextPct>=阈值 || rounds>=afterRounds`"注入压缩指令;而 meeting/verify 分支收到回复后**提前 return,从不处理 `contextPct/compacted/needCompact`**,于是 `needCompact` 卡死为 true,**每个后续提示都在开头重复"核心规则重申 + CONTEXT COMPACT"**。修复:
|
|
504
|
+
- **只对 normal 研究轮注入完整压缩指令**;meeting/verify/CHECKPOINT 不再注入(它们的回复没有 `compacted/contextPct` 字段,注入了也永远无法被确认 → 无限重复)。
|
|
505
|
+
- **`needCompact`(真实 `/compact` 后)只重申一次短规则并立即清位**(下次任一唤醒即可,清位后不再重复),不再要求再做一次自述。
|
|
506
|
+
- 新增 `postmark(r, parsed)`,在 `onResidentEnd` **所有分支**(含 meeting/verify)开头统一处理 context/compact 记账,杜绝任何情况下的标志泄漏。
|
|
507
|
+
- 这样"规则重申/压缩指令"只出现在**真正发生了压缩的那次唤醒**(软压缩每 `compactAfterRounds` 轮一次、真实 `/compact` 后一次),不再"每轮都重复"。
|
|
508
|
+
|
|
509
|
+
### 4. 会议发言顺序轮换(v1.4.1-④,改善"第一位发言者看不到别人")
|
|
510
|
+
真实 run 里 r-1 几乎总是在会议里 **第一个发言**(因 `residents` 按插入序 r-1,r-2,r-3,`continueMeetingRound` 取第一个未发言者),于是它本次会议内**看不到** r-2/r-3 的后续发言。现改为**每次会议随机轮换发言顺序**(`meetingState.order`),让不同常驻轮流先发言,讨论更公平、各成员都能看到别人。
|
|
511
|
+
|
|
512
|
+
### 5. 关于 HRT run 收敛与"第7轮后看不到别人消息"的解释(审计结论,非代码 bug)
|
|
513
|
+
- **收敛合理且符合哲学**:三名常驻经约 18/24/29 轮与 6 次会议,**独立且一致**地给出诚实结论——"HRT-4 一般形式很可能为假(0.8+,未确立)+ 完整必要筛 + 统一机制 + 判定方程(♯) + 明确标注未决点(显式反例=外部无全文阻塞、generic 证明=HRT 核心困难未证)";**无任何 Verified/ 对象**;**无人 declare solved**(每会 `voteSolved` 均非全 true)。框架没有强行收口(`autoDone=false`),run 是被**外部暂停**(`running:false, phase:active`)。这正是哲学要求的诚实:常驻不编造"已解决",框架也不强加结论。
|
|
514
|
+
- **"第7轮后看不到别人消息/群聊"合理且有两点成因**:① run 后期以**会议为主**(r-1 的后续唤醒几乎都是 Meeting 提示,而非"第 N 轮"研究轮);② **`[群聊]` 群聊转发在会议主导期被积压**——`scheduleNext` 让会议/验证优先于邮箱投递,会议期间 `[群聊]` 只排队不投递,r-1 邮箱里积压了大量未投递的群聊消息(`State/mailboxes.json` 可见)。会议提示里虽会把"他人已发言"转给常驻,但 r-1 作为最常的先发言者,本次会议内看不到后续发言。这是**自组织在"深度协作+会议主导"下的自然表现**;已通过 §24.4 的发言顺序轮换改善,`[群聊]` 积压会在恢复 normal 阶段被正常投递。
|
|
515
|
+
|
|
516
|
+
> 测试:`selfdrive-v4.mjs` 21/21;`e2e-v4-fixes.test.mjs` 36/36(新增 T10 模型/工具权限接线、T11 默认继承、T12 自主发明理论提示、T13 压缩指令不泄漏进 meetings);v3 E2E 100/100、v2 regression 14/14、v2 business 24/24、multisession 25/25 全绿。
|
|
517
|
+
|
|
483
518
|
|
|
484
519
|
|
|
485
520
|
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
# The `vibe-math` agent preset: the full coding agent (`standard`), plus the
|
|
2
|
-
# multi-agent mathematical problem-solving & verification framework.
|
|
3
|
-
#
|
|
4
|
-
# The vibe-math plugin row consumes the HOST subagents/agents/fs/tools services
|
|
5
|
-
# and publishes nothing, so it needs no isolate realm (like tool-fs / tool-web).
|
|
6
|
-
|
|
7
|
-
# ── identity ────────────────────────────────────────────────────────────────
|
|
8
|
-
|
|
9
|
-
- id: persona
|
|
10
|
-
name: '@deepseek-ai/dsh-persona'
|
|
11
|
-
config:
|
|
12
|
-
text: |-
|
|
13
|
-
You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.
|
|
14
|
-
|
|
15
|
-
## Vibe Math toolkit (available in this preset)
|
|
16
|
-
|
|
17
|
-
This session includes the "Vibe Math" multi-agent mathematical problem-solving and
|
|
18
|
-
verification framework. It is driven by a background scheduler (code), NOT by the model:
|
|
19
|
-
you only issue the control tools below and read status; the scheduler then automatically
|
|
20
|
-
runs brainstorm → solver iteration → multi-verifier debate → promotion to Verified →
|
|
21
|
-
triage back to the problem list (priority 2 > 3 > 1, concurrency-gated).
|
|
22
|
-
|
|
23
|
-
- vibe_math_add_problem {id, description, priority} — add a problem to qs.csv.
|
|
24
|
-
- vibe_math_start / vibe_math_resume — start / resume the scheduler (resume = continue after a checkpoint or restart).
|
|
25
|
-
- vibe_math_status / vibe_math_report — read scheduler status / full progress report (report also writes Progress_Logs/report.json).
|
|
26
|
-
- vibe_math_pause / vibe_math_abort — pause / abort (abort interrupts all children).
|
|
27
|
-
- vibe_math_set_mode {mode: manual|auto} — switch manual / auto control.
|
|
28
|
-
- vibe_math_set_params {...} — tune any parameter (see vibe_math_setup for the full schema).
|
|
29
|
-
- vibe_math_setup — return the parameter schema (name, type, current, default, description, options, suggestion) for guided configuration.
|
|
30
|
-
- vibe_math_save_settings — write current params to <project>/vibe_math_setting.json (JSON-with-comments) as new defaults.
|
|
31
|
-
- vibe_math_new_project / vibe_math_set_project / vibe_math_list_projects — manage per-project folders.
|
|
32
|
-
- vibe_math_list_decisions / vibe_math_decide {id, action: approve|reject|override, verdict?} — resolve manual decisions.
|
|
33
|
-
- vibe_math_list_agents / vibe_math_message_agent / vibe_math_interrupt_agent — inspect / steer / interrupt subagents.
|
|
34
|
-
|
|
35
|
-
A /vibe slash command mirrors these: /vibe start|resume|pause|abort|status|report|mode <auto|manual>|setup|save|add <id> <description>|project [list|new <name>|<name>]|decisions|agents.
|
|
36
|
-
|
|
37
|
-
Configurable subagent permissions (via vibe_math_set_params or the settings file): solverToolAllow/solverToolDeny and verifierToolAllow/verifierToolDeny restrict which tools a child sees (hard toolFilter); solverMaxToolCalls/verifierMaxToolCalls cap external tool calls per round (soft). Each child is also told it may read Verified/ and, for solvers, Progress_Logs/{qid}_progress.csv.
|
|
38
|
-
|
|
39
|
-
Interactive configuration: when the user wants to configure or adjust Vibe Math parameters, call vibe_math_setup to get the schema (each item has description, options, and a suggestion), then use ask_user_question to ask the user for the choices, apply them with vibe_math_set_params, and finally ask whether to persist them to vibe_math_setting.json via vibe_math_save_settings.
|
|
40
|
-
|
|
41
|
-
When the user asks to solve or verify a math problem with Vibe Math: add the problem (or ask for it first), then vibe_math_start, then report vibe_math_status. In manual mode, poll vibe_math_list_decisions and resolve each with vibe_math_decide. Data lives under {{cwd}}/VibeMath/Projects/<project>/ and survives restarts via vibe_math_resume.
|
|
42
|
-
|
|
43
|
-
- id: agent-instructions
|
|
44
|
-
name: '@deepseek-ai/dsh-agent-instructions'
|
|
45
|
-
config:
|
|
46
|
-
maxBytes: 65536
|
|
47
|
-
|
|
48
|
-
# ── shell ───────────────────────────────────────────────────────────────────
|
|
49
|
-
|
|
50
|
-
- id: tool-bash
|
|
51
|
-
name: '@deepseek-ai/dsh-tool-bash'
|
|
52
|
-
disabled: !!js process.platform === 'win32'
|
|
53
|
-
|
|
54
|
-
- id: tool-pwsh
|
|
55
|
-
name: '@deepseek-ai/dsh-tool-pwsh'
|
|
56
|
-
disabled: !!js process.platform !== 'win32'
|
|
57
|
-
|
|
58
|
-
# ── filesystem ──────────────────────────────────────────────────────────────
|
|
59
|
-
|
|
60
|
-
- id: tool-fs
|
|
61
|
-
name: '@deepseek-ai/dsh-tool-fs'
|
|
62
|
-
|
|
63
|
-
- id: tool-fs-search
|
|
64
|
-
name: '@deepseek-ai/dsh-tool-fs-search'
|
|
65
|
-
config:
|
|
66
|
-
sampleOverCapGlobResults: false
|
|
67
|
-
|
|
68
|
-
# ── background jobs ────────────────────────────────────────────────────────
|
|
69
|
-
|
|
70
|
-
- id: tool-jobs
|
|
71
|
-
name: '@deepseek-ai/dsh-tool-jobs'
|
|
72
|
-
|
|
73
|
-
# ── skills ──────────────────────────────────────────────────────────────────
|
|
74
|
-
|
|
75
|
-
- id: skill-filesystem
|
|
76
|
-
name: '@deepseek-ai/dsh-skill-filesystem'
|
|
77
|
-
|
|
78
|
-
- id: tool-skill
|
|
79
|
-
name: '@deepseek-ai/dsh-tool-skill'
|
|
80
|
-
|
|
81
|
-
# ── goals ───────────────────────────────────────────────────────────────────
|
|
82
|
-
|
|
83
|
-
- id: tool-goal
|
|
84
|
-
name: '@deepseek-ai/dsh-tool-goal'
|
|
85
|
-
|
|
86
|
-
# ── plan mode ───────────────────────────────────────────────────────────────
|
|
87
|
-
|
|
88
|
-
- id: planning
|
|
89
|
-
name: cordis:group
|
|
90
|
-
group: true
|
|
91
|
-
isolate:
|
|
92
|
-
planMode: true
|
|
93
|
-
config:
|
|
94
|
-
- id: plan-mode
|
|
95
|
-
name: '@deepseek-ai/dsh-plan-mode'
|
|
96
|
-
config:
|
|
97
|
-
section: |
|
|
98
|
-
You are in plan mode. Stay in plan mode until exit_plan_mode succeeds or the user switches the session mode. Imperative language to implement changes means plan the implementation, not execute it. A user's conversational agreement — including an answer confirming something you asked — approves nothing and does not end plan mode; fold the confirmed decision into the plan and submit it through exit_plan_mode.
|
|
99
|
-
|
|
100
|
-
Explore first. Use non-mutating reads, searches, static analysis, and checks to ground the plan in the actual repository. Do not edit or write files, change configuration, run formatters or code generation that rewrites tracked files, commit, or otherwise carry out the plan. Prefer existing functions and patterns over new machinery.
|
|
101
|
-
|
|
102
|
-
The tool catalog stays the same across modes for request-cache stability. These plan-mode rules override any later tool description or guidance that suggests using mutation tools; those tools remain listed to keep the tool catalog unchanged. Do not use todo_write to track this planning phase: it tracks implementation after an approved plan, while the plan itself belongs in exit_plan_mode.
|
|
103
|
-
|
|
104
|
-
Resolve discoverable facts by inspection. Use ask_user_question only for user-owned choices or material ambiguity that inspection cannot answer. Do not ask the user where code lives or how current behavior works when you can find out.
|
|
105
|
-
|
|
106
|
-
Make the plan decision-complete: state the goal and success criteria; group implementation changes by subsystem; identify public API, schema, and data-flow changes; cover edge cases, failure modes, tests, acceptance criteria, and explicit assumptions. Keep it concise enough to review but detailed enough that another engineer can implement it without making design decisions.
|
|
107
|
-
|
|
108
|
-
When ready, call exit_plan_mode with the complete plan markdown, starting with a # title. Make exit_plan_mode the only and final tool call in that assistant response: it presents the plan for approval, and implementation begins only in a later step after approval. Do not paste the final plan as a plain reply or ask "should I proceed?" through prose or ask_user_question. If review rejects it, incorporate the feedback and present again. If the review channel is unavailable or aborted, stay in plan mode and ask the user to switch modes manually; do not proceed with implementation.
|
|
109
|
-
|
|
110
|
-
# ── compaction ──────────────────────────────────────────────────────────────
|
|
111
|
-
|
|
112
|
-
- id: compaction
|
|
113
|
-
name: cordis:group
|
|
114
|
-
group: true
|
|
115
|
-
isolate:
|
|
116
|
-
compaction: true
|
|
117
|
-
toolResultPruner: true
|
|
118
|
-
config:
|
|
119
|
-
- id: compaction-basic
|
|
120
|
-
name: '@deepseek-ai/dsh-compaction-basic'
|
|
121
|
-
|
|
122
|
-
- id: command-compact
|
|
123
|
-
name: '@deepseek-ai/dsh-command-compact'
|
|
124
|
-
|
|
125
|
-
- id: tool-result-pruner
|
|
126
|
-
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
127
|
-
config:
|
|
128
|
-
thresholdChars: 8192
|
|
129
|
-
headChars: 4096
|
|
130
|
-
tailChars: 1024
|
|
131
|
-
|
|
132
|
-
# ── delegation and workflows ────────────────────────────────────────────────
|
|
133
|
-
|
|
134
|
-
- id: delegation
|
|
135
|
-
name: cordis:group
|
|
136
|
-
group: true
|
|
137
|
-
isolate:
|
|
138
|
-
workflowEngine: true
|
|
139
|
-
config:
|
|
140
|
-
- id: tool-subagent-control
|
|
141
|
-
name: '@deepseek-ai/dsh-tool-subagent-control'
|
|
142
|
-
|
|
143
|
-
- id: tool-subagent-list-agents
|
|
144
|
-
name: '@deepseek-ai/dsh-tool-subagent-control/list-agents'
|
|
145
|
-
|
|
146
|
-
- id: tool-subagent
|
|
147
|
-
name: '@deepseek-ai/dsh-tool-subagent'
|
|
148
|
-
config:
|
|
149
|
-
provider: spawn
|
|
150
|
-
toolName: subagent
|
|
151
|
-
backgroundMode: continuable
|
|
152
|
-
|
|
153
|
-
- id: tool-subagent-fork
|
|
154
|
-
name: '@deepseek-ai/dsh-tool-subagent'
|
|
155
|
-
config:
|
|
156
|
-
provider: fork
|
|
157
|
-
toolName: subagent_fork
|
|
158
|
-
backgroundMode: continuable
|
|
159
|
-
|
|
160
|
-
- id: workflow-worker-thread
|
|
161
|
-
name: '@deepseek-ai/dsh-workflow-worker-thread'
|
|
162
|
-
config:
|
|
163
|
-
provider: spawn
|
|
164
|
-
|
|
165
|
-
- id: tool-workflow
|
|
166
|
-
name: '@deepseek-ai/dsh-tool-workflow'
|
|
167
|
-
|
|
168
|
-
- id: tool-ralph
|
|
169
|
-
name: '@deepseek-ai/dsh-tool-ralph'
|
|
170
|
-
config:
|
|
171
|
-
subagentProvider: spawn
|
|
172
|
-
maxRounds: 64
|
|
173
|
-
|
|
174
|
-
# ── remaining model-facing rows ─────────────────────────────────────────────
|
|
175
|
-
|
|
176
|
-
- id: tool-ask-user
|
|
177
|
-
name: '@deepseek-ai/dsh-tool-ask-user'
|
|
178
|
-
|
|
179
|
-
- id: tool-todo
|
|
180
|
-
name: '@deepseek-ai/dsh-tool-todo'
|
|
181
|
-
config:
|
|
182
|
-
allowParallelInProgress: true
|
|
183
|
-
|
|
184
|
-
- id: tool-web
|
|
185
|
-
name: '@deepseek-ai/dsh-tool-web'
|
|
186
|
-
config:
|
|
187
|
-
fetch: false
|
|
188
|
-
searchTimeoutMs: 60000
|
|
189
|
-
|
|
190
|
-
# ── Vibe Math ───────────────────────────────────────────────────────────────
|
|
191
|
-
|
|
192
|
-
# The multi-agent math solver + verification framework: a preset-local plugin
|
|
193
|
-
# (./vibe-math.js) that registers 16 model tools (vibe_math_*), a /vibe slash
|
|
194
|
-
# command, and a background scheduler. It consumes the HOST
|
|
195
|
-
# subagents/agents/fs/tools/commands services and provides nothing, so it sits
|
|
196
|
-
# loose (no isolate realm).
|
|
197
|
-
- id: vibe-math
|
|
198
|
-
name: './vibe-math.js'
|
package/vibe-math-v1/preset.yml
DELETED