char-slop/berry
multipurpose self-modifiable agentic harness
git clone https://git.t4t.associates/char-slop/berry
032d2bf
main
1import type { ConversationView , InboxState , LiveState } from "@earendil-works/pi-durable" ; 2import type { Scope } from "./ui.ts" ; 3 4/** Acknowledge the settled messages actually drawn in a visible conversation pane. */ 5export function readWhenVisible ( 6scope :Scope , 7acknowledge :( entryId :number ) => Promise < unknown >, 8) :( view :ConversationView ) => void { 9let current = 0 ; 10let readThrough = 0 ; 11let sending = false ; 12let disposed = false ; 13const read = async () => { 14if ( disposed || document . visibilityState !== "visible" || sending || current <= readThrough ) { 15return ; 16} 17const entryId = current ; 18sending = true ; 19try { 20await acknowledge ( entryId ); 21readThrough = Math . max ( readThrough , entryId ); 22} catch ( error ) { 23console . error ( "[berry] read receipt:" , error ); 24} finally { 25sending = false ; 26if ( current !== entryId ) void read (); 27} 28}; 29const onVisibility = () => void read (); 30document . addEventListener ( "visibilitychange" , onVisibility ); 31scope . add (() => { 32disposed = true ; 33document . removeEventListener ( "visibilitychange" , onVisibility ); 34}); 35return ({ entries, docs}) => { 36const live = docs [ "pi.live" ] as LiveState | undefined ; 37const inbox = docs [ "pi.inbox" ] as InboxState | undefined ; 38current = live ?. run || inbox ?. items . length 39 ?0 40 :entries . findLast (( entry ) => entry . kind === "pi.assistant" || entry . kind === "pi.user" ) 41?. id ?? 0 ; 42void read (); 43}; 44}