/** Two ordinary context automations, with durable creation and deletion receipts. */ import { BACKGROUND_CONTEXT as context } from '@earendil-works/chord/context' import { defineDoc, ROOT_CONVERSATION_ID as ROOT } from '@earendil-works/pi-durable' import { Automations, AutomationsApi } from '../automations/server.ts' import { Standing } from '../subagents/api.ts' import { deliver } from './delivery.ts' export const AUTOMATION_NAME='Dream before compaction' export const PAUSE_NAME='Dream after a pause' export const BuiltInDoc=defineDoc<{id?:string;deleted?:true}>({kind:'dream.after-compaction',version:1,scope:'conversation',history:'latest',fork:'initial',checkpointWhen:()=>false,initial:()=>({})}) export const PauseDoc=defineDoc<{id?:string;deleted?:true}>({kind:'dream.after-pause',version:1,scope:'conversation',history:'latest',fork:'initial',checkpointWhen:()=>false,initial:()=>({})}) const builtIns=[ {doc:BuiltInDoc,name:AUTOMATION_NAME,condition:{metric:'context',of:'@ultimate',above:70}}, {doc:PauseDoc,name:PAUSE_NAME,condition:{metric:'context',of:'@ultimate',above:50,idleFor:8*3600_000}}, ] export const DREAM_ASK='Dream now: follow "For @ultimate" in /src/sausage/extensions/dream/DREAM.md. Write your handoff into the dream branch prompt in this turn, while your context still holds everything. If a dream branch is already active, say so and do not start another.' export async function ensureAutomation(host:any) { const service=host.want(AutomationsApi) if(!service || (await host.harness().snapshot(Standing,ROOT,context))?.ultimate===undefined) return for(const {doc,name,condition} of builtIns) { const state=await host.harness().snapshot(doc,ROOT,context) if(state?.deleted) continue if(state?.id) { const list=await service.operate({action:'list'}) if(!list.some((a:any)=>a.id===state.id)) await host.harness().commit(async(tx:any)=>{(await tx.doc(doc,ROOT)).deleted=true},context) } else { const made=await service.operate({action:'create',name,condition,subscribers:['@ultimate'],key:`dream:${doc.definition.kind}`}) await host.harness().commit(async(tx:any)=>{(await tx.doc(doc,ROOT)).id=made.id},context) } } } export async function fired(host:any,tx:any,id:string,fire:number) { const builtIn=await Promise.all(builtIns.map(async(item)=>({item,id:(await tx.doc(item.doc,ROOT)).id}))) const found=builtIn.find(item=>item.id===id)?.item const ultimate=(await tx.doc(Standing,ROOT)).ultimate if(!found || ultimate===undefined) return const automation=(await tx.doc(Automations)).automations[id] const pause=found.doc===PauseDoc && automation ? Date.now()-(automation.condition?.inputAt??automation.createdAt) : undefined const data={automation:{id,name:automation?.name??found.name,...(pause===undefined?{}:{pause})}} await deliver(host,tx,ultimate,{type:'write',requestId:`dream.requested:${id}:${fire}`,kind:'dream.requested',data,content:`Automation ${id} "${data.automation.name}" fired${pause===undefined?'':` after ${Math.round(pause/3600_000)} h away`}. ${DREAM_ASK}`}) }