Files
sausage/host/js/core-ext-test.ts
T

71 lines
5.8 KiB
TypeScript

/** 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'
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 proxyTemplate={...models.getModels('faux')[0],provider:'openai',baseUrl:'https://proxy.invalid/v1'}
models.setProvider({...faux.provider,id:'openai',getModels:()=>[proxyTemplate]})
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 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 fast family and thinking')
assert(agent.tools.map(t=>t.name).join(',')==='read,write','worker tools and project overlay')
assert(agent.instructions.includes('Worker body') && agent.instructions.includes('Project body'),'definition body and overlay')
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 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)
await fs.write('/src/sausage/agents/models.json',JSON.stringify({default:{model:'faux/faux-1'},fast:{model:'faux/faux-1',thinking:'high'}}))
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'}]})
await fs.write('/src/sausage/agents/models.json',JSON.stringify({default:{model:'faux/faux-1'},fast:{model:'faux/second'}}))
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 family changes next model without restart')
await fs.write('/src/sausage/agents/models.json',JSON.stringify({default:{model:'faux/faux-1'},fast:{model:'logical/new'}}))
faux.setResponses([fauxAssistantMessage('proxy')])
await (await worker.submit({type:'input',content:'proxy'},context)).wait(context)
assert(models.getModel('logical','new').baseUrl===proxyTemplate.baseUrl && models.getProvider('logical').auth===models.getProvider('openai').auth,'new model retains proxy transport and auth')
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 family selection')
await harness.commit(tx=>conversations.setStanding(tx,worker.id,true),context)
let refused=false;try{await harness.commit(tx=>conversations.concludeIn(tx,[worker.id]),context)}catch{refused=true}
assert(refused,'standing conversation cannot conclude')
} finally {await loader.close();await harness.close(context)}