+46
-16
bsky.py
+46
-16
bsky.py
···
97
97
message_counters = defaultdict(int)
98
98
start_time = time.time()
99
99
100
+
# Synthesis cycle configuration (normal mode uses cycles, synthesis-only uses time interval)
101
+
SYNTHESIS_CYCLES = 10 # trigger synthesis after this many successful mentions
102
+
MENTIONS_SINCE_LAST_SYNTHESIS = 0
103
+
SYNTHESIS_MODE = "mentions" # normal mode synthesis trigger: "mentions" or "time"
104
+
100
105
# Testing mode flag
101
106
TESTING_MODE = False
102
107
···
1220
1225
success = process_mention(void_agent, atproto_client, notif_data, queue_filepath=filepath, testing_mode=testing_mode)
1221
1226
if success:
1222
1227
message_counters['mentions'] += 1
1228
+
# Increment synthesis cycle counter and trigger if threshold reached
1229
+
global MENTIONS_SINCE_LAST_SYNTHESIS, SYNTHESIS_CYCLES, last_synthesis_time, SYNTHESIS_MODE
1230
+
if SYNTHESIS_MODE == 'mentions' and SYNTHESIS_CYCLES > 0:
1231
+
MENTIONS_SINCE_LAST_SYNTHESIS += 1
1232
+
logger.debug(f"Mentions since last synthesis: {MENTIONS_SINCE_LAST_SYNTHESIS}/{SYNTHESIS_CYCLES}")
1233
+
if MENTIONS_SINCE_LAST_SYNTHESIS >= SYNTHESIS_CYCLES:
1234
+
logger.info(
1235
+
f"🧠 Synthesis threshold reached: {MENTIONS_SINCE_LAST_SYNTHESIS}/{SYNTHESIS_CYCLES} mentions. Triggering synthesis."
1236
+
)
1237
+
try:
1238
+
send_synthesis_message(CLIENT, void_agent.id, void_agent.name, atproto_client)
1239
+
last_synthesis_time = time.time()
1240
+
except Exception as e:
1241
+
logger.error(f"Error during synthesis trigger: {e}")
1242
+
finally:
1243
+
MENTIONS_SINCE_LAST_SYNTHESIS = 0
1223
1244
elif notif_data['reason'] == "reply":
1224
1245
success = process_mention(void_agent, atproto_client, notif_data, queue_filepath=filepath, testing_mode=testing_mode)
1225
1246
if success:
···
1478
1499
1479
1500
def send_synthesis_message(client: Letta, agent_id: str, agent_name: str = "void", atproto_client=None) -> None:
1480
1501
"""
1481
-
Send a synthesis message to the agent every 10 minutes.
1482
-
This prompts the agent to synthesize its recent experiences.
1502
+
Send a synthesis message to the agent.
1503
+
This is typically triggered periodically based on the configured schedule
1504
+
(time-based or mention-based) and prompts the agent to synthesize recent experiences.
1483
1505
1484
1506
Args:
1485
1507
client: Letta client
···
1846
1868
# --rich option removed as we now use simple text formatting
1847
1869
parser.add_argument('--reasoning', action='store_true', help='Display reasoning in panels and set reasoning log level to INFO')
1848
1870
parser.add_argument('--cleanup-interval', type=int, default=10, help='Run user block cleanup every N cycles (default: 10, 0 to disable)')
1849
-
parser.add_argument('--synthesis-interval', type=int, default=600, help='Send synthesis message every N seconds (default: 600 = 10 minutes, 0 to disable)')
1871
+
parser.add_argument('--synthesis-interval', type=int, default=600, help='Synthesis-only mode: send synthesis every N seconds (default: 600 = 10 minutes); used in normal mode when --synthesis-mode=time')
1872
+
parser.add_argument('--synthesis-cycles', type=int, default=10, help='Normal mode: trigger synthesis after N successful mentions (default: 10, 0 to disable)')
1873
+
parser.add_argument('--synthesis-mode', choices=['mentions', 'time'], default='mentions', help='Normal mode: choose synthesis trigger mechanism: mentions (after N successful mentions) or time (every N seconds). Default: mentions')
1850
1874
parser.add_argument('--synthesis-only', action='store_true', help='Run in synthesis-only mode (only send synthesis messages, no notification processing)')
1851
1875
parser.add_argument('--debug', action='store_true', help='Enable debug logging')
1852
1876
args = parser.parse_args()
···
1921
1945
1922
1946
# Create handler with custom formatter
1923
1947
handler = logging.StreamHandler()
1924
-
if not args.simple_logs:
1925
-
handler.setFormatter(SymbolFormatter(bot_name))
1926
-
else:
1927
-
handler.setFormatter(logging.Formatter(log_format))
1948
+
handler.setFormatter(SymbolFormatter(bot_name))
1928
1949
1929
1950
# Configure root logger
1930
1951
logging.root.setLevel(logging.INFO)
···
2033
2054
atproto_client = None
2034
2055
logger.info("Skipping Bluesky connection (test mode)")
2035
2056
2036
-
# Configure intervals
2057
+
# Configure intervals / counters
2037
2058
CLEANUP_INTERVAL = args.cleanup_interval
2038
-
SYNTHESIS_INTERVAL = args.synthesis_interval
2059
+
SYNTHESIS_INTERVAL = args.synthesis_interval # used in synthesis-only mode and in normal mode if synthesis-mode=time
2060
+
global SYNTHESIS_CYCLES, MENTIONS_SINCE_LAST_SYNTHESIS, SYNTHESIS_MODE
2061
+
SYNTHESIS_CYCLES = args.synthesis_cycles
2062
+
SYNTHESIS_MODE = args.synthesis_mode
2039
2063
2040
2064
# Synthesis-only mode
2041
2065
if SYNTHESIS_ONLY:
···
2073
2097
else:
2074
2098
logger.info("User block cleanup disabled")
2075
2099
2076
-
if SYNTHESIS_INTERVAL > 0:
2077
-
logger.info(f"Synthesis messages enabled every {SYNTHESIS_INTERVAL} seconds ({SYNTHESIS_INTERVAL/60:.1f} minutes)")
2078
-
else:
2079
-
logger.info("Synthesis messages disabled")
2100
+
if SYNTHESIS_MODE == 'mentions':
2101
+
if SYNTHESIS_CYCLES > 0:
2102
+
logger.info(f"Synthesis enabled (mode=mentions): every {SYNTHESIS_CYCLES} successful mentions")
2103
+
else:
2104
+
logger.info("Synthesis disabled in normal mode (mode=mentions, cycles=0)")
2105
+
else: # time-based in normal mode
2106
+
if SYNTHESIS_INTERVAL > 0:
2107
+
logger.info(f"Synthesis enabled (mode=time): every {SYNTHESIS_INTERVAL} seconds ({SYNTHESIS_INTERVAL/60:.1f} minutes)")
2108
+
else:
2109
+
logger.info("Synthesis disabled in normal mode (mode=time, interval=0)")
2080
2110
2081
2111
while True:
2082
2112
try:
2083
2113
cycle_count += 1
2084
2114
process_notifications(void_agent, atproto_client, TESTING_MODE)
2085
2115
2086
-
# Check if synthesis interval has passed
2087
-
if SYNTHESIS_INTERVAL > 0:
2116
+
# If using time-based synthesis in normal mode, check timer
2117
+
if SYNTHESIS_MODE == 'time' and SYNTHESIS_INTERVAL > 0:
2088
2118
current_time = time.time()
2089
2119
global last_synthesis_time
2090
2120
if current_time - last_synthesis_time >= SYNTHESIS_INTERVAL:
2091
2121
logger.info(f"⏰ {SYNTHESIS_INTERVAL/60:.1f} minutes have passed, triggering synthesis")
2092
2122
send_synthesis_message(CLIENT, void_agent.id, void_agent.name, atproto_client)
2093
2123
last_synthesis_time = current_time
2094
-
2124
+
2095
2125
# Run periodic cleanup every N cycles
2096
2126
if CLEANUP_INTERVAL > 0 and cycle_count % CLEANUP_INTERVAL == 0:
2097
2127
logger.debug(f"Running periodic user block cleanup (cycle {cycle_count})")