/** Core extensions run through the real snapshot loader with a faux model. */ import { BACKGROUND_CONTEXT as context } from '@earendil-works/chord/context' import { createModels } from '@earendil-works/pi-ai/models' import { fauxProvider, fauxAssistantMessage } from '@earendil-works/pi-ai/providers/faux' import { Harness, AgentDoc, createRegistry } from '@earendil-works/pi-durable' import { openStorage } from './sqlite' import { loadExtensions, fs } from './extensions' import {readTestConfig,writeTestConfig} from './roster-fixture' const assert = (ok:any,message:string)=>{if(!ok)throw new Error(message);Deno.core.ops.op_output(`ok - ${message}\n`)} const models=createModels(), faux=fauxProvider({tokensPerSecond:100000});models.setProvider(faux.provider) const storage=await openStorage(globalThis.storagePath), registry=createRegistry() const harness=await Harness.open(storage,{models,registry,settings:{retry:{enabled:false},get extensions(){return registry.snapshot().installed()}}},context) await harness.root(context,{agent:{model:{provider:'faux',modelId:'faux-1'}}}) const loader=await loadExtensions(harness,registry,storage,models,context) try { assert(!loader.state().error,`loader: ${loader.state().error ?? 'loaded'}`) const {selection,conversations,State,metadata}=globalThis.core const config = await readTestConfig(fs) config.main_agent_name='worker' config.roster=[{name:'worker',description:'Worker',model:'faux/faux-1',thinking:'low',tools:['read','write'],prompt:'Worker body'}] const save = ()=>writeTestConfig(fs,config) await save() const worker=await selection.start({agent:'worker',cwd:'/project/sub'},context) let agent=await worker.agent(context) assert(agent.model.modelId==='faux-1' && agent.thinkingLevel==='low','worker roster model and thinking') assert(agent.tools.map(t=>t.name).join(',')==='read,write','worker roster tools') assert(agent.instructions.indexOf('## Sausage and the world') < agent.instructions.indexOf('Worker body'),'global prompt precedes role prompt') const sections:any={} for(const section of agent.sections) sections[section.key]=await section.render({conversationId:worker.id,agent},context) assert(sections.project_context.includes('Root instructions') && sections.project_context.includes('Nested instructions'),'cwd and parent AGENTS.md') assert(!sections.project_context.includes('Outside instructions'),'instructions stop at repo root') assert(sections.skills.includes('builtin-skill') && sections.skills.includes('project-skill'),'builtin and project skills') assert(sections.cwd==='/project/sub' && sections.tools.includes('read'),'cwd and tools sections') const checkPrompt = (ctx: any, expected: string) => { const prompt=JSON.stringify(ctx.messages.filter((message: any)=>message.role==='system')) for (const route of ['whoami','conversations/ID/entries?after=N','events?after=N','models','extensions','credential-requests','/proc/processes','/proc/extensions','jaq']) assert(prompt.includes(route),`fresh system prompt includes ${route}`) assert(prompt.includes(expected),'system prompt uses current global prompt') assert(prompt.indexOf(expected){checkPrompt(ctx,'## Sausage and the world');return fauxAssistantMessage('fresh')}]) harness.resume() await (await worker.submit({type:'input',content:'fresh'},context)).wait(context) config.prompt='Edited global prompt\\n'+config.prompt await save() faux.setResponses([(ctx)=>{checkPrompt(ctx,'Edited global prompt');return fauxAssistantMessage('edited')}]) await (await worker.submit({type:'input',content:'edited'},context)).wait(context) const seed=await harness.commit(tx=>tx.appendEntry(worker.id,{kind:'test.seed'}),context) const child=await worker.fork(seed.id,{ownership:{kind:'ownerless'}},context) const unrelated=await harness.createConversation({ownership:{kind:'ownerless'}},context) await harness.commit(async tx=>{ await conversations.concludeIn(tx,[worker.id,child.id,unrelated.id]) await conversations.setAutomaticSummaries(tx,worker.id,false) ;(await tx.doc(metadata,worker.id)).title='Generated' await conversations.generatedTitle(tx,worker.id,'Generated') },context) assert((await harness.snapshot(State,worker.id,context)).automaticSummaries===false,'automatic summary seam') assert((await harness.snapshot(State,worker.id,context)).generatedTitle==='Generated','generated title') await child.submit({type:'write',entry:{kind:'test.note'}},context) assert((await conversations.concluded(context)).size===3,'write does not resume') faux.setResponses([fauxAssistantMessage('done')]) const receipt=await child.submit({type:'input',content:'resume'},context) assert(JSON.stringify([...await conversations.concluded(context)])===JSON.stringify([unrelated.id]),'input placement atomically resumes ancestors') harness.resume();await receipt.wait(context) config.roster[0].thinking='high';await save() faux.setResponses([fauxAssistantMessage('next')]) await (await worker.submit({type:'input',content:'next'},context)).wait(context) agent=await worker.agent(context) assert(agent.thinkingLevel==='high','model config edit applies next turn') // A second faux model proves selection changes, not only the thinking level. const provider=models.getProvider('faux'), template=models.getModels('faux')[0] models.setProvider({...provider,getModels:()=>[template,{...template,id:'second'}]}) config.roster[0].model='faux/second';await save() faux.setResponses([fauxAssistantMessage('second')]) await (await worker.submit({type:'input',content:'second'},context)).wait(context) assert((await harness.snapshot(AgentDoc,worker.id,context)).model.modelId==='second','edited roster changes next model without restart') globalThis.modelPin={provider:'faux',modelId:'faux-1'} faux.setResponses([fauxAssistantMessage('pin')]) await (await worker.submit({type:'input',content:'pin'},context)).wait(context) assert((await worker.agent(context)).model.provider==='faux','models.pin overrides roster selection') await harness.commit(tx=>conversations.setMainAgent(tx,worker.id,true),context) let refused=false;try{await harness.commit(tx=>conversations.concludeIn(tx,[worker.id]),context)}catch{refused=true} assert(refused,'mainAgent conversation cannot conclude') } finally {await loader.close();await harness.close(context)}