a tool to help your Letta AI agents navigate bluesky
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 11fd3ef23ea4f26690a8fad6348e80c22b013fd0 154 lines 4.6 kB view raw
1import { agentContext } from "./agentContext.ts"; 2import { Temporal } from "@js-temporal/polyfill"; 3 4/** 5 * Convert time units to milliseconds 6 */ 7export const msFrom = { 8 /** 9 * Convert seconds to milliseconds 10 * @param s - number of seconds 11 */ 12 seconds: (seconds: number): number => seconds * 1000, 13 /** 14 * Convert minutes to milliseconds 15 * @param m - number of minutes 16 */ 17 minutes: (minutes: number): number => minutes * 60 * 1000, 18 /** 19 * Convert hours to milliseconds 20 * @param h - number of hours 21 */ 22 hours: (hours: number): number => hours * 60 * 60 * 1000, 23}; 24 25/** 26 * Generate a random time interval in milliseconds within a defined range 27 * 28 * @param minimum - the minimum duration in milliseconds (default: 5 minutes) 29 * @param maximum - the maximum duration in milliseconds (default: 15 minutes) 30 * @returns A random time interval in milliseconds between the min and max range 31 */ 32 33export const msRandomOffset = ( 34 minimum: number = msFrom.minutes(5), 35 maximum: number = msFrom.minutes(15), 36): number => { 37 if (maximum <= minimum) { 38 throw new Error("Maximum time must be larger than minimum time"); 39 } 40 41 if (minimum < 0 || maximum < 0) { 42 throw new Error("Time values must be non-negative"); 43 } 44 45 if (Math.max(minimum, maximum) > msFrom.hours(24)) { 46 throw new Error( 47 `time values must not exceed ${ 48 msFrom.hours(24) 49 } (24 hours). you entered: [min: ${minimum}ms, max: ${maximum}ms]`, 50 ); 51 } 52 53 const min = Math.ceil(minimum); 54 const max = Math.floor(maximum); 55 56 return Math.floor(Math.random() * (max - min) + min); 57}; 58 59/** 60 * finds the time in milliseconds until the next wake window 61 * 62 * @param minimumOffset - the minimum duration in milliseconds to offset from the window 63 * @param maximumOffset - the maximum duration in milliseconds to offset from the window 64 * @returns time until next wake window plus random offset, in milliseconds 65 */ 66export const msUntilNextWakeWindow = ( 67 minimumOffset: number, 68 maximumOffset: number, 69): number => { 70 const current = Temporal.Now.zonedDateTimeISO(agentContext.timeZone); 71 72 if (!agentContext.sleepEnabled) { 73 return 0; 74 } 75 76 if ( 77 current.hour >= agentContext.wakeTime && 78 current.hour < agentContext.sleepTime 79 ) { 80 return 0; 81 } else { 82 let newTime; 83 84 if (current.hour < agentContext.wakeTime) { 85 newTime = current.with({ hour: agentContext.wakeTime }); 86 } else { 87 newTime = current.add({ days: 1 }).with({ hour: agentContext.wakeTime }); 88 } 89 90 return newTime.toInstant().epochMilliseconds + 91 msRandomOffset(minimumOffset, maximumOffset) - 92 current.toInstant().epochMilliseconds; 93 } 94}; 95 96/** 97 * Calculate the time until next configurable window, plus a random offset. 98 * @param window - the hour of the day to wake up at 99 * @param minimumOffset - the minimum duration in milliseconds to offset from the window 100 * @param maximumOffset - the maximum duration in milliseconds to offset from the window 101 * @returns time until next daily window plus random offset, in milliseconds 102 */ 103export const msUntilDailyWindow = ( 104 window: number, 105 minimumOffset: number, 106 maximumOffset: number, 107): number => { 108 const current = Temporal.Now.zonedDateTimeISO(agentContext.timeZone); 109 110 if (window > 23) { 111 throw Error("window hour cannot exceed 23 (11pm)"); 112 } 113 114 let msToWindow; 115 if (current.hour < window) { 116 msToWindow = current.with({ hour: window }).toInstant().epochMilliseconds; 117 } else { 118 msToWindow = current.add({ days: 1 }).with({ hour: window }).toInstant() 119 .epochMilliseconds; 120 } 121 122 return msToWindow + 123 msRandomOffset(minimumOffset, maximumOffset) - 124 current.toInstant().epochMilliseconds; 125}; 126 127export const getNow = () => { 128 return Temporal.Now.zonedDateTimeISO(agentContext.timeZone); 129}; 130 131/** 132 * Format uptime from milliseconds into a human-readable string 133 * @param ms - uptime in milliseconds 134 * @returns Formatted string like "2 days, 3 hours, 15 minutes" or "3 hours, 15 minutes" 135 */ 136export const formatUptime = (ms: number): string => { 137 const days = Math.floor(ms / (1000 * 60 * 60 * 24)); 138 const hours = Math.floor((ms % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 139 const minutes = Math.floor((ms % (1000 * 60 * 60)) / (1000 * 60)); 140 141 const parts: string[] = []; 142 143 if (days > 0) { 144 parts.push(`${days} ${days === 1 ? "day" : "days"}`); 145 } 146 if (hours > 0) { 147 parts.push(`${hours} ${hours === 1 ? "hour" : "hours"}`); 148 } 149 if (minutes > 0 || parts.length === 0) { 150 parts.push(`${minutes} ${minutes === 1 ? "minute" : "minutes"}`); 151 } 152 153 return parts.join(", "); 154};