9month-revision-update2 #22

Merged
AllfatherHatt merged 2 commits from 9month-revision-update2 into master 2026-03-16 13:22:17 +01:00

View File

@ -25,7 +25,6 @@ CALLABLE_FUNCTIONS = {
DEFAULT_MODEL = "gpt-5-mini-2025-08-07" DEFAULT_MODEL = "gpt-5-mini-2025-08-07"
DEFAULT_MAX_COMPLETION_TOKENS = 2000 DEFAULT_MAX_COMPLETION_TOKENS = 2000
TYPING_HEARTBEAT_INTERVAL_SECONDS = 8
STATUS_UPDATE_MIN_INTERVAL_SECONDS = 1.5 STATUS_UPDATE_MIN_INTERVAL_SECONDS = 1.5
@ -100,12 +99,6 @@ class ReginaldCog(PermissionsMixin, BlacklistMixin, MemoryMixin, commands.Cog):
} }
return tool_statuses.get(tool_name, "Reginald is consulting an external source...") return tool_statuses.get(tool_name, "Reginald is consulting an external source...")
async def typing_heartbeat(self, channel: discord.TextChannel):
while True:
with suppress(discord.HTTPException):
await channel.trigger_typing()
await asyncio.sleep(TYPING_HEARTBEAT_INTERVAL_SECONDS)
def make_status_updater( def make_status_updater(
self, status_message: discord.Message self, status_message: discord.Message
) -> Callable[[str, bool], Awaitable[None]]: ) -> Callable[[str, bool], Awaitable[None]]:
@ -215,46 +208,62 @@ class ReginaldCog(PermissionsMixin, BlacklistMixin, MemoryMixin, commands.Cog):
status_message = await message.channel.send(self.get_thinking_status_message()) status_message = await message.channel.send(self.get_thinking_status_message())
status_update = self.make_status_updater(status_message) status_update = self.make_status_updater(status_message)
typing_task = asyncio.create_task(self.typing_heartbeat(message.channel)) response_text = None
try: if hasattr(message.channel, "typing"):
try:
async with message.channel.typing():
response_text = await self.generate_response(
api_key,
formatted_messages,
status_update=status_update,
)
except (discord.HTTPException, AttributeError):
# Fall back to normal processing if typing indicator isn't available.
response_text = await self.generate_response(
api_key,
formatted_messages,
status_update=status_update,
)
else:
response_text = await self.generate_response( response_text = await self.generate_response(
api_key, api_key,
formatted_messages, formatted_messages,
status_update=status_update, status_update=status_update,
) )
try:
await self.send_split_message(message.channel, response_text)
finally: finally:
typing_task.cancel() if status_message is not None:
with suppress(asyncio.CancelledError): with suppress(discord.HTTPException):
await typing_task await status_message.delete()
memory.append({"user": user_name, "content": prompt}) try:
memory.append({"user": "Reginald", "content": response_text}) memory.append({"user": user_name, "content": prompt})
memory.append({"user": "Reginald", "content": response_text})
if len(memory) > self.short_term_memory_limit: if len(memory) > self.short_term_memory_limit:
summary_batch_size = int(self.short_term_memory_limit * self.summary_retention_ratio) summary_batch_size = int(self.short_term_memory_limit * self.summary_retention_ratio)
summary = await self.summarize_memory(message, memory[:summary_batch_size]) summary = await self.summarize_memory(message, memory[:summary_batch_size])
mid_term_summaries.append( mid_term_summaries.append(
{ {
"timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M"), "timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M"),
"topics": self.extract_topics_from_summary(summary), "topics": self.extract_topics_from_summary(summary),
"summary": summary, "summary": summary,
} }
) )
retained_count = max(1, self.short_term_memory_limit - summary_batch_size) retained_count = max(1, self.short_term_memory_limit - summary_batch_size)
memory = memory[-retained_count:] memory = memory[-retained_count:]
async with self.config.guild(guild).short_term_memory() as short_memory, self.config.guild( async with self.config.guild(guild).short_term_memory() as short_memory, self.config.guild(
guild guild
).mid_term_memory() as mid_memory: ).mid_term_memory() as mid_memory:
short_memory[channel_id] = memory short_memory[channel_id] = memory
mid_memory[channel_id] = mid_term_summaries[-self.summary_retention_limit :] mid_memory[channel_id] = mid_term_summaries[-self.summary_retention_limit :]
except Exception as error:
await self.send_split_message(message.channel, response_text) print(f"DEBUG: Memory persistence failed after response delivery: {error}")
if status_message is not None:
with suppress(discord.HTTPException):
await status_message.delete()
def should_reginald_interject(self, message_content: str) -> bool: def should_reginald_interject(self, message_content: str) -> bool:
direct_invocation = {"reginald,"} direct_invocation = {"reginald,"}