from faker import Faker from mistralai import Mistral import os fake = Faker() api_key = os.environ["MISTRAL_API_KEY"] if api_key is None: raise ValueError("MISTRAL_API_KEY environment variable not set") basic_instruction = ( "Du nimmst an einer Debatte teil. Dir wird ein Thema vorgegeben, und du musst entweder dafür oder " "dagegen argumentieren. Verhalte dich wie ein typischer Schweizer Politiker in einer öffentlich ausgestrahlten " "Debatte. Gehe auf die Argumente deines Gegners ein, analysiere sie und antworte darauf. Deine Antwort sollte " "maximal 100 Wörter umfassen und keine Aufzählungen enthalten. Wenn derselbe Aspekt diskutiert wird, versuche ein " "neues Argument zu finden. Sei Kreativ und halte die Diskussion lebendig. Das Thema der Debatte ist die " "Legalisierung von Cannabis. Wenn du als Erster sprichst, wähle einen spezifischen " "Aspekt des Themas aus und beginne damit." ) class Participant: def __init__(self, name, role_description): self.name = f"""{name} {fake.name()}""" self.client = Mistral(api_key=api_key) self.role_description = role_description try: os.remove(f"log/{self.__class__.__name__}.md") except FileNotFoundError: pass self.messages = [ {"role": "system", "content": basic_instruction}, {"role": "system", "content": self.role_description}, ] def truncate_to_word_limit(self, text, word_limit=100): """Truncate text to specified word limit, ensuring to complete the last sentence.""" words = text.split() if len(words) <= word_limit: return text # Get the first 100 words truncated = words[:word_limit] truncated_text = " ".join(truncated) # Find the last sentence end (., !, or ?) last_sentence_end = max( truncated_text.rfind("."), truncated_text.rfind("!"), truncated_text.rfind("?") ) # If we found a sentence end, cut there, otherwise use the full 100 words if last_sentence_end != -1: return truncated_text[:last_sentence_end + 1] return truncated_text def answer(self, question): self.messages.append({"role": "user", "content": question}) response = self.client.chat.complete( temperature=0.7, model="mistral-large-latest", messages=self.messages ) answer = response.choices[0].message.content # Enforce 100-word limit while maintaining complete sentences answer = self.truncate_to_word_limit(answer) self.messages.append({"role": "assistant", "content": answer}) self.write_to_file(self.__class__.__name__, self.messages) return answer def write_to_file(self, filename, messages): with open(f"log/{filename}.md", "w") as file: for message in messages: role = "unknown" match message["role"]: case "system": role = "System Prompt" case "user": role = "Gegnerische Antwort" case "assistant": role = "Meine Antwort" file.write(f"## {role}\n") file.write(f"{message['content']}\n\n") class ProParticipant(Participant): def __init__(self, name): role_description = ( "Du bist ein Befürworter der Legalisierung von Cannabis. Du argumentierst dafür, dass " "Cannabis legalisiert werden sollte. Du hast eine starke Meinung zu dieser Frage und bist bereit, dich " "dafür einzusetzen." ) super().__init__(name, role_description) class ContraParticipant(Participant): def __init__(self, name): role_description = ( "Du lehnst die Legalisierung von Cannabis vehement ab. Du argumentierst dagegen, dass " "Cannabis legalisiert werden sollte. Du hast eine extreme Meinung zu dieser Frage und bist bereit, dich " "dafür einzusetzen, und weichst nicht von deiner Meinung ab." ) super().__init__(name, role_description)