Queer European MD passionate about IT

Mission903Solutions.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. from openai import OpenAI
  2. import tiktoken
  3. import json
  4. from datetime import datetime
  5. import os
  6. import streamlit as st
  7. DEFAULT_API_KEY = os.environ.get("TOGETHER_API_KEY")
  8. DEFAULT_BASE_URL = "https://api.together.xyz/v1"
  9. DEFAULT_MODEL = "meta-llama/Llama-3-8b-chat-hf"
  10. DEFAULT_TEMPERATURE = 0.7
  11. DEFAULT_MAX_TOKENS = 512
  12. DEFAULT_TOKEN_BUDGET = 4096
  13. class ConversationManager:
  14. def __init__(self, api_key=None, base_url=None, model=None, history_file=None, temperature=None, max_tokens=None, token_budget=None):
  15. if not api_key:
  16. api_key = DEFAULT_API_KEY
  17. if not base_url:
  18. base_url = DEFAULT_BASE_URL
  19. self.client = OpenAI(
  20. api_key=api_key,
  21. base_url=base_url
  22. )
  23. if history_file is None:
  24. timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
  25. self.history_file = f"conversation_history_{timestamp}.json"
  26. else:
  27. self.history_file = history_file
  28. self.model = model if model else DEFAULT_MODEL
  29. self.temperature = temperature if temperature else DEFAULT_TEMPERATURE
  30. self.max_tokens = max_tokens if max_tokens else DEFAULT_MAX_TOKENS
  31. self.token_budget = token_budget if token_budget else DEFAULT_TOKEN_BUDGET
  32. self.system_messages = {
  33. "sassy_assistant": "You are a sassy assistant that is fed up with answering questions.",
  34. "angry_assistant": "You are an angry assistant that likes yelling in all caps.",
  35. "thoughtful_assistant": "You are a thoughtful assistant, always ready to dig deeper. You ask clarifying questions to ensure understanding and approach problems with a step-by-step methodology.",
  36. "custom": "Enter your custom system message here."
  37. }
  38. self.system_message = self.system_messages["sassy_assistant"] # Default persona
  39. self.load_conversation_history()
  40. def count_tokens(self, text):
  41. try:
  42. encoding = tiktoken.encoding_for_model(self.model)
  43. except KeyError:
  44. encoding = tiktoken.get_encoding("cl100k_base")
  45. tokens = encoding.encode(text)
  46. return len(tokens)
  47. def total_tokens_used(self):
  48. try:
  49. return sum(self.count_tokens(message['content']) for message in self.conversation_history)
  50. except Exception as e:
  51. print(f"An unexpected error occurred while calculating the total tokens used: {e}")
  52. return None
  53. def enforce_token_budget(self):
  54. try:
  55. while self.total_tokens_used() > self.token_budget:
  56. if len(self.conversation_history) <= 1:
  57. break
  58. self.conversation_history.pop(1)
  59. except Exception as e:
  60. print(f"An unexpected error occurred while enforcing the token budget: {e}")
  61. def set_persona(self, persona):
  62. if persona in self.system_messages:
  63. self.system_message = self.system_messages[persona]
  64. self.update_system_message_in_history()
  65. else:
  66. raise ValueError(f"Unknown persona: {persona}. Available personas are: {list(self.system_messages.keys())}")
  67. def set_custom_system_message(self, custom_message):
  68. if not custom_message:
  69. raise ValueError("Custom message cannot be empty.")
  70. self.system_messages['custom'] = custom_message
  71. self.set_persona('custom')
  72. def update_system_message_in_history(self):
  73. try:
  74. if self.conversation_history and self.conversation_history[0]["role"] == "system":
  75. self.conversation_history[0]["content"] = self.system_message
  76. else:
  77. self.conversation_history.insert(0, {"role": "system", "content": self.system_message})
  78. except Exception as e:
  79. print(f"An unexpected error occurred while updating the system message in the conversation history: {e}")
  80. def chat_completion(self, prompt, temperature=None, max_tokens=None, model=None):
  81. temperature = temperature if temperature is not None else self.temperature
  82. max_tokens = max_tokens if max_tokens is not None else self.max_tokens
  83. model = model if model is not None else self.model
  84. self.conversation_history.append({"role": "user", "content": prompt})
  85. self.enforce_token_budget()
  86. try:
  87. response = self.client.chat.completions.create(
  88. model=model,
  89. messages=self.conversation_history,
  90. temperature=temperature,
  91. max_tokens=max_tokens,
  92. )
  93. except Exception as e:
  94. print(f"An error occurred while generating a response: {e}")
  95. return None
  96. ai_response = response.choices[0].message.content
  97. self.conversation_history.append({"role": "assistant", "content": ai_response})
  98. self.save_conversation_history()
  99. return ai_response
  100. def load_conversation_history(self):
  101. try:
  102. with open(self.history_file, "r") as file:
  103. self.conversation_history = json.load(file)
  104. except FileNotFoundError:
  105. self.conversation_history = [{"role": "system", "content": self.system_message}]
  106. except json.JSONDecodeError:
  107. print("Error reading the conversation history file. Starting with an empty history.")
  108. self.conversation_history = [{"role": "system", "content": self.system_message}]
  109. def save_conversation_history(self):
  110. try:
  111. with open(self.history_file, "w") as file:
  112. json.dump(self.conversation_history, file, indent=4)
  113. except IOError as e:
  114. print(f"An I/O error occurred while saving the conversation history: {e}")
  115. except Exception as e:
  116. print(f"An unexpected error occurred while saving the conversation history: {e}")
  117. def reset_conversation_history(self):
  118. self.conversation_history = [{"role": "system", "content": self.system_message}]
  119. try:
  120. self.save_conversation_history() # Attempt to save the reset history to the file
  121. except Exception as e:
  122. print(f"An unexpected error occurred while resetting the conversation history: {e}")
  123. ### Streamlit code ###
  124. st.title("Sassy Chatbot :face_with_rolling_eyes:")
  125. # Sidebar
  126. st.sidebar.header("Options")
  127. # Initialize the ConversationManager object
  128. if 'chat_manager' not in st.session_state:
  129. st.session_state['chat_manager'] = ConversationManager()
  130. chat_manager = st.session_state['chat_manager']
  131. # Set the token budget, max tokens per message, and temperature with sliders
  132. max_tokens_per_message = st.sidebar.slider("Max Tokens Per Message", min_value=10, max_value=500, value=50)
  133. temperature = st.sidebar.slider("Temperature", min_value=0.0, max_value=1.0, value=0.7, step=0.01)
  134. # Select and set system message with a selectbox
  135. system_message = st.sidebar.selectbox("System message", ['Sassy', 'Angry', 'Thoughtful', 'Custom'])
  136. if system_message == 'Sassy':
  137. chat_manager.set_persona('sassy_assistant')
  138. elif system_message == 'Angry':
  139. chat_manager.set_persona('angry_assistant')
  140. elif system_message == 'Thoughtful':
  141. chat_manager.set_persona('thoughtful_assistant')
  142. # Open text area for custom system message if "Custom" is selected
  143. elif system_message == 'Custom':
  144. custom_message = st.sidebar.text_area("Custom system message")
  145. if st.sidebar.button("Set custom system message"):
  146. chat_manager.set_custom_system_message(custom_message)
  147. if st.sidebar.button("Reset conversation history", on_click=chat_manager.reset_conversation_history):
  148. st.session_state['conversation_history'] = chat_manager.conversation_history
  149. if 'conversation_history' not in st.session_state:
  150. st.session_state['conversation_history'] = chat_manager.conversation_history
  151. conversation_history = st.session_state['conversation_history']
  152. # Chat input from the user
  153. user_input = st.chat_input("Write a message")
  154. # Call the chat manager to get a response from the AI. Uses settings from the sidebar.
  155. if user_input:
  156. response = chat_manager.chat_completion(user_input, temperature=temperature, max_tokens=max_tokens_per_message)
  157. # Display the conversation history
  158. for message in conversation_history:
  159. if message["role"] != "system":
  160. with st.chat_message(message["role"]):
  161. st.write(message["content"])