From bd884d938fc1dae33eeed3a313f5208d4bc0bdd2 Mon Sep 17 00:00:00 2001 From: Daniel Eder Date: Sat, 27 Sep 2025 19:28:25 +0200 Subject: [PATCH] feat: bot now remembers communication history per person --- intelligent_agent.py | 49 +++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/intelligent_agent.py b/intelligent_agent.py index 6e2c734..c71167c 100644 --- a/intelligent_agent.py +++ b/intelligent_agent.py @@ -4,7 +4,7 @@ import re import sys from collections import deque from dataclasses import dataclass, field -from typing import Deque, Optional, Pattern, Tuple +from typing import Deque, Dict, Optional, Pattern, Tuple try: from litellm import completion @@ -33,7 +33,9 @@ class IntelligentCommunicationAgent(Agent): ) ) last_output: str = field(default="", init=False) + max_history_chars: int = 16_000 pending_replies: Deque[Tuple[str, str]] = field(default_factory=deque, init=False) + conversation_history: Dict[str, Deque[Tuple[str, str]]] = field(default_factory=dict, init=False) def observe(self, output: str) -> None: if not output: @@ -46,17 +48,19 @@ class IntelligentCommunicationAgent(Agent): continue self.pending_replies.append((player, message)) print(f"[Agent] Received message from {player}: {message}") + self._append_history(player, "user", message) def decide(self) -> Optional[str]: if not self.pending_replies: return None - player, message = self.pending_replies.popleft() - reply_text = self._generate_reply(player, message) + player, _ = self.pending_replies.popleft() + reply_text = self._generate_reply(player) + self._append_history(player, "assistant", reply_text) reply = f"teile {player} mit {reply_text}" print(f"[Agent] Replying to {player} with model output") return reply - def _generate_reply(self, player: str, message: str) -> str: + def _generate_reply(self, player: str) -> str: if completion is None: print( "[Agent] litellm is not installed; falling back to default reply", @@ -67,16 +71,7 @@ class IntelligentCommunicationAgent(Agent): try: response = completion( model=self.model, - messages=[ - {"role": "system", "content": self.system_prompt}, - { - "role": "user", - "content": ( - f"Spieler {player} schreibt: {message}\n" - "Formuliere eine kurze, freundliche Antwort." - ), - }, - ], + messages=self._build_messages(player), temperature=self.temperature, max_tokens=self.max_output_tokens, ) @@ -90,3 +85,29 @@ class IntelligentCommunicationAgent(Agent): return self.fallback_reply return content or self.fallback_reply + + def _build_messages(self, player: str) -> list[dict[str, str]]: + history = self.conversation_history.get(player) + messages: list[dict[str, str]] = [{"role": "system", "content": self.system_prompt}] + if not history: + return messages + for role, content in history: + messages.append({"role": role, "content": content}) + return messages + + def _append_history(self, player: str, role: str, content: str) -> None: + if not content: + return + history = self.conversation_history.setdefault(player, deque()) + history.append((role, content)) + self._trim_history(history) + + def _trim_history(self, history: Deque[Tuple[str, str]]) -> None: + total_chars = sum(len(content) for _, content in history) + while len(history) > 1 and total_chars > self.max_history_chars: + _, removed_content = history.popleft() + total_chars -= len(removed_content) + if history and total_chars > self.max_history_chars: + role, content = history.pop() + trimmed = content[-self.max_history_chars :] + history.append((role, trimmed))