fix: clean ||| from chat history and handle afterthoughts in reaction replies
- Extract _split_afterthought helper method - Store cleaned content (no |||) in chat history to prevent LLM reinforcement - Handle afterthought splitting in reaction-reply path too - Log main_reply instead of raw response Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+30
-16
@@ -73,6 +73,19 @@ def _format_relative_time(dt: datetime) -> str:
|
|||||||
|
|
||||||
|
|
||||||
class ChatCog(commands.Cog):
|
class ChatCog(commands.Cog):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _split_afterthought(response: str) -> tuple[str, str | None]:
|
||||||
|
"""Split a response on ||| into (main_reply, afterthought)."""
|
||||||
|
if "|||" not in response:
|
||||||
|
return response, None
|
||||||
|
parts = response.split("|||", 1)
|
||||||
|
main = parts[0].strip()
|
||||||
|
after = parts[1].strip() or None
|
||||||
|
if not main:
|
||||||
|
return response, None
|
||||||
|
return main, after
|
||||||
|
|
||||||
def __init__(self, bot: commands.Bot):
|
def __init__(self, bot: commands.Bot):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
# Per-channel conversation history for the bot: {channel_id: deque of {role, content}}
|
# Per-channel conversation history for the bot: {channel_id: deque of {role, content}}
|
||||||
@@ -395,9 +408,14 @@ class ChatCog(commands.Cog):
|
|||||||
logger.warning("LLM returned no response for %s in #%s", message.author, message.channel.name)
|
logger.warning("LLM returned no response for %s in #%s", message.author, message.channel.name)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Split afterthoughts (triple-pipe delimiter)
|
||||||
|
main_reply, afterthought = self._split_afterthought(response)
|
||||||
|
|
||||||
|
# Store cleaned content in history (no ||| delimiter)
|
||||||
if not image_attachment:
|
if not image_attachment:
|
||||||
|
clean_for_history = f"{main_reply}\n{afterthought}" if afterthought else main_reply
|
||||||
self._chat_history[ch_id].append(
|
self._chat_history[ch_id].append(
|
||||||
{"role": "assistant", "content": response}
|
{"role": "assistant", "content": clean_for_history}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Reset proactive cooldown counter for this channel
|
# Reset proactive cooldown counter for this channel
|
||||||
@@ -415,17 +433,6 @@ class ChatCog(commands.Cog):
|
|||||||
except (asyncio.TimeoutError, asyncio.CancelledError):
|
except (asyncio.TimeoutError, asyncio.CancelledError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Split afterthoughts (triple-pipe delimiter)
|
|
||||||
main_reply = response
|
|
||||||
afterthought = None
|
|
||||||
if "|||" in response:
|
|
||||||
parts = response.split("|||", 1)
|
|
||||||
main_reply = parts[0].strip()
|
|
||||||
afterthought = parts[1].strip() if len(parts) > 1 else None
|
|
||||||
if not main_reply:
|
|
||||||
main_reply = response
|
|
||||||
afterthought = None
|
|
||||||
|
|
||||||
await message.reply(main_reply, mention_author=False)
|
await message.reply(main_reply, mention_author=False)
|
||||||
|
|
||||||
if afterthought:
|
if afterthought:
|
||||||
@@ -446,7 +453,7 @@ class ChatCog(commands.Cog):
|
|||||||
reply_type.capitalize(),
|
reply_type.capitalize(),
|
||||||
message.channel.name,
|
message.channel.name,
|
||||||
message.author.display_name,
|
message.author.display_name,
|
||||||
response[:100],
|
main_reply[:100],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -518,15 +525,22 @@ class ChatCog(commands.Cog):
|
|||||||
if not response:
|
if not response:
|
||||||
return
|
return
|
||||||
|
|
||||||
self._chat_history[ch_id].append({"role": "assistant", "content": response})
|
main_reply, afterthought = self._split_afterthought(response)
|
||||||
|
clean_for_history = f"{main_reply}\n{afterthought}" if afterthought else main_reply
|
||||||
|
self._chat_history[ch_id].append({"role": "assistant", "content": clean_for_history})
|
||||||
|
|
||||||
|
await channel.send(main_reply)
|
||||||
|
|
||||||
|
if afterthought:
|
||||||
|
await asyncio.sleep(random.uniform(2.0, 5.0))
|
||||||
|
await channel.send(afterthought)
|
||||||
|
|
||||||
await channel.send(response)
|
|
||||||
logger.info(
|
logger.info(
|
||||||
"Reaction reply in #%s to %s (%s): %s",
|
"Reaction reply in #%s to %s (%s): %s",
|
||||||
channel.name,
|
channel.name,
|
||||||
member.display_name,
|
member.display_name,
|
||||||
emoji,
|
emoji,
|
||||||
response[:100],
|
main_reply[:100],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user