94 lines
8.3 KiB
TypeScript
94 lines
8.3 KiB
TypeScript
/** Real dream triggers, message reports, and built-in receipts across a harness reopen. */
|
|
import { BACKGROUND_CONTEXT as context } from '@earendil-works/chord/context'
|
|
import { createModels } from '@earendil-works/pi-ai/models'
|
|
import { fauxProvider, fauxAssistantMessage, fauxToolCall } from '@earendil-works/pi-ai/providers/faux'
|
|
import { Harness, createRegistry, defineExtension, defineTool } from '@earendil-works/pi-durable'
|
|
import { obj } from '@earendil-works/pi-schema'
|
|
import { loadExtensions } from './extensions'
|
|
import { openStorage } from './sqlite'
|
|
const assert=(ok:any,message:string)=>{if(!ok) throw new Error(message)}
|
|
const until=async(test:()=>any)=>{const deadline=Date.now()+20000;while(!await test()){if(Date.now()>deadline)throw new Error(`Dream deadline: ${JSON.stringify((await entries()).filter((e:any)=>['pi.tool-result','board.reply'].includes(e.kind)))}`);await new Promise(r=>setTimeout(r,0))}}
|
|
const models=createModels(),faux=fauxProvider({tokensPerSecond:100000});models.setProvider(faux.provider)
|
|
const registry=createRegistry(),storage=await openStorage(globalThis.storagePath)
|
|
const harness=await Harness.open(storage,{models,registry,settings:{retry:{enabled:false},get extensions(){return registry.snapshot().installed()}}},context)
|
|
const root=await harness.root(context,{agent:{model:{provider:'faux',modelId:'faux-1'},cwd:'/src/demo'}})
|
|
const route=(transcript:any):any=>{
|
|
faux.appendResponses([route])
|
|
const last=transcript.messages.findLast((m:any)=>m.role!=='system')
|
|
const text=typeof last?.content==='string'?last.content:(last?.content??[]).filter((p:any)=>p.type==='text').map((p:any)=>p.text).join('')
|
|
if(last?.role==='user'&&text.startsWith('CALL ')){const call=JSON.parse(text.slice(5));return fauxAssistantMessage([fauxToolCall(call.name,call.args)],{stopReason:'toolUse'})}
|
|
if(last?.role==='user'&&text.includes('Dream journal pass')) return fauxAssistantMessage([fauxToolCall('subagent',{action:'start',agent:'dream-pass',task:'Review supplied evidence',background:true,isolate:'none'})],{stopReason:'toolUse'})
|
|
if(last?.role==='user'&&text==='Review supplied evidence') return fauxAssistantMessage('Evidence #1: keep the review read-only.')
|
|
if(last?.role==='user'&&/^(Reply|Message|Note) from/.test(text)) return fauxAssistantMessage('Received')
|
|
if(last?.role==='toolResult'||text.includes('Evidence #1')) return fauxAssistantMessage('Dream journal: keep the review read-only. Evidence #1.')
|
|
return fauxAssistantMessage('Received')
|
|
}
|
|
faux.setResponses([route])
|
|
// The role requires the normal host read/bash tools. The scripted pass does not invoke them.
|
|
const baseTools=defineExtension({name:'dream-test-tools',tools:['read','bash'].map(name=>defineTool({name,description:'Unused fixture tool',parameters:obj({}),execute:async()=>{throw new Error('Unexpected fixture tool invocation')}}))})
|
|
const loader=await loadExtensions(harness,registry,storage,models,context,[baseTools])
|
|
assert(!loader.state().error,`Extension load: ${loader.state().error}`)
|
|
const base=`file:///run/sausage/extensions/${loader.state().good}/extensions`
|
|
const {BuiltInDoc,PauseDoc,ensureAutomation,fired,AUTOMATION_NAME,PAUSE_NAME}=await import(`${base}/dream/built-ins.ts`)
|
|
const {Next}=await import(`${base}/dream/server.ts`)
|
|
const {Automations}=await import(`${base}/automations/server.ts`)
|
|
const {ContextUsageDoc}=await import(`${base}/automations/triggers.ts`)
|
|
const {Fired}=await import(`${base}/automations/refs.ts`)
|
|
const {Messages}=await import(`${base}/messages/api.ts`)
|
|
const primary=(await harness.conversation(await globalThis.dreamSubagents.mainAgent('mainAgent',context),context))!
|
|
const entries=async()=> (await primary.context(context)).entries
|
|
const ledger=async()=> (await harness.snapshot(Automations,context))?.automations??{}
|
|
const requested=async()=> (await entries()).filter((e:any)=>e.kind==='dream.requested')
|
|
const operation=(args:any)=>globalThis.dreamAutomations.operate(args)
|
|
harness.resume()
|
|
try {
|
|
if(globalThis.dreamMode==='reopen') {
|
|
await ensureAutomation(globalThis.dreamHost)
|
|
const all=Object.values(await ledger()) as any[]
|
|
assert(all.length===1&&all[0].name===PAUSE_NAME&&!all[0].enabled,'Reopen must preserve deletion and pause')
|
|
assert((await requested()).length===2,'Reopen duplicated dream requests')
|
|
assert((await harness.snapshot(Next,root.id,context)).prepared.handoff==='Replacement handoff','Prepared handoff must survive reopen')
|
|
assert((await harness.snapshot(Messages,root.id,context)).messages.filter((m:any)=>m.re!==undefined&&m.text.includes('Dream journal')).length===1,'Reopen duplicated the dream report')
|
|
} else {
|
|
await until(async()=>Object.keys(await ledger()).length===2)
|
|
await ensureAutomation(globalThis.dreamHost)
|
|
const id=(await harness.snapshot(BuiltInDoc,root.id,context)).id
|
|
const pause=(await harness.snapshot(PauseDoc,root.id,context)).id
|
|
assert(Object.keys(await ledger()).length===2,'Repeated ensure duplicated built-ins')
|
|
assert((await ledger())[id].name===AUTOMATION_NAME&&(await ledger())[id].condition.above===70,'Compaction trigger')
|
|
assert((await ledger())[pause].condition.idleFor===8*3600_000&&(await ledger())[pause].condition.above===50,'Pause trigger')
|
|
await harness.commit(async(tx:any)=>Object.assign(await tx.doc(ContextUsageDoc,primary.id),{percent:71,tokens:710,window:1000}),context)
|
|
await until(async()=> (await requested()).filter((e:any)=>e.data.automation?.id===id).length===1)
|
|
await harness.commit((tx:any)=>globalThis.dreamHost.emit(tx,Fired,{id,fire:1}),context)
|
|
await harness.commit((tx:any)=>fired(globalThis.dreamHost,tx,id,1),context)
|
|
await harness.waitForIdle(context)
|
|
const deliveries=await harness.commit((tx:any)=>tx.scanTasks({kind:'dream.deliver'},100),context)
|
|
for(const task of deliveries.items) await harness.waitForTask(task.id,context)
|
|
assert((await requested()).length===1,'One fire must add exactly one dream.requested entry')
|
|
const request=(await storage.scanSubmissions({conversationId:primary.id},100,undefined,context)).items.find((s:any)=>s.requestId===`dream.requested:${id}:1`)
|
|
assert(request?.type==='write','The fire adds a passive write')
|
|
await globalThis.dreamService.operate({action:'start'})
|
|
await until(async()=> (await requested()).length===2)
|
|
for(const args of [{learned:['one'],handoff:'x'},{learned:['a','b','c'],handoff:'x'.repeat(12001)}]) {
|
|
let failed=false;try{await globalThis.dreamService.operate({action:'prepare',...args})}catch{failed=true}assert(failed,'Invalid preparation must fail')
|
|
}
|
|
await globalThis.dreamService.operate({action:'prepare',learned:['I learned one.','I keep two.','I propose three.'],handoff:'First handoff'})
|
|
await globalThis.dreamService.operate({action:'prepare',learned:['a','b','c'],handoff:'Replacement handoff'})
|
|
await until(async()=> (await entries()).filter((e:any)=>e.kind==='dream.prepared').length===2)
|
|
await (await primary.submit({type:'input',content:`CALL ${JSON.stringify({name:'branch',args:{repo:'/src/demo',prompt:'Dream journal pass'}})}`},context)).wait(context)
|
|
await until(async()=> (await entries()).some((e:any)=>e.kind==='board.reply'&&e.data.text.includes('Dream journal')))
|
|
await harness.waitForIdle(context)
|
|
const report=(await entries()).find((e:any)=>e.kind==='board.reply'&&e.data.text.includes('Dream journal'))
|
|
const branch=(await harness.conversation(report.data.from,context))!
|
|
const reports=(await branch.context(context)).entries.filter((e:any)=>e.kind==='subagents.report')
|
|
assert(reports.length===1&&reports[0].data.agent==='dream-pass'&&JSON.stringify(reports).includes('Evidence #1'),`The dream-pass must report its evidence: ${JSON.stringify((await branch.context(context)).entries.filter((e:any)=>['pi.tool-result','subagents.report'].includes(e.kind)))}`)
|
|
await operation({action:'pause',id:pause})
|
|
await harness.commit(async(tx:any)=>{delete (await tx.doc(PauseDoc,root.id)).id},context)
|
|
await ensureAutomation(globalThis.dreamHost)
|
|
assert((await harness.snapshot(PauseDoc,root.id,context)).id===pause&&!(await ledger())[pause].enabled,'A lost receipt must adopt the paused automation')
|
|
await operation({action:'delete',id})
|
|
await ensureAutomation(globalThis.dreamHost)
|
|
assert((await harness.snapshot(BuiltInDoc,root.id,context)).deleted&&Object.keys(await ledger()).length===1,'Deletion must persist')
|
|
}
|
|
} finally {await loader.close();await harness.close(context)}
|