Danialebrat commited on
Commit
83d1ea1
·
1 Parent(s): fba48d8

- adding Claude 3.5 haiku

Browse files
Config_files/message_system_config.json CHANGED
@@ -21,10 +21,11 @@
21
  "AI_phrases_singeo": ["your voice deserves more"],
22
  "header_limit": 30,
23
  "message_limit": 110,
24
- "LLM_models": ["gpt-4o-mini", "gpt-4o", "gpt-4.1-mini", "gpt-3.5-turbo", "o1", "o4-mini", "o1-mini", "o3-mini"],
25
  "openai_models": ["gpt-4o-mini", "gpt-4o", "gpt-4.1-nano", "gpt-3.5-turbo", "gpt-4.1-mini"],
26
  "reasoning": ["o1", "o4-mini", "o1-mini", "o3-mini"],
27
- "ollama_models": ["deepseek-r1:1.5b", "gemma3:4b", "deepseek-r1:7b", "gemma3:4b"]
 
28
  }
29
 
30
 
 
21
  "AI_phrases_singeo": ["your voice deserves more"],
22
  "header_limit": 30,
23
  "message_limit": 110,
24
+ "LLM_models": ["gpt-4o-mini", "gpt-4o", "gpt-4.1-mini", "gpt-3.5-turbo", "o1", "o4-mini", "o1-mini", "o3-mini", "claude-3-5-haiku-latest"],
25
  "openai_models": ["gpt-4o-mini", "gpt-4o", "gpt-4.1-nano", "gpt-3.5-turbo", "gpt-4.1-mini"],
26
  "reasoning": ["o1", "o4-mini", "o1-mini", "o3-mini"],
27
+ "ollama_models": ["deepseek-r1:1.5b", "gemma3:4b", "deepseek-r1:7b", "gemma3:4b"],
28
+ "claude_models": ["claude-3-5-haiku-latest"]
29
  }
30
 
31
 
Messaging_system/LLM.py CHANGED
@@ -9,6 +9,9 @@ import openai
9
  import ollama
10
  import torch
11
  import re
 
 
 
12
 
13
 
14
 
@@ -20,12 +23,17 @@ class LLM:
20
  self.client = None
21
  self.connect_to_llm()
22
 
 
 
23
 
24
  def get_response(self, prompt, instructions):
25
  if self.model_type == "openai":
26
  response = self.get_message_openai(prompt, instructions)
27
  elif self.model_type == "ollama":
28
  response = self.get_message_ollama(prompt, instructions)
 
 
 
29
  else:
30
  raise f"Invalid model type : {self.model_type}"
31
 
@@ -40,78 +48,17 @@ class LLM:
40
  if self.Core.model in self.Core.config_file["openai_models"]:
41
  self.model_type = "openai"
42
 
43
- if self.Core.model in self.Core.config_file["ollama_models"]:
44
  self.model_type = "ollama"
45
  self.client = ollama.Client()
46
 
47
- self.model = self.Core.model
48
-
49
-
50
- # def get_message_openai(self, prompt, instructions, max_retries=4):
51
- #
52
- #
53
- # openai.api_key = self.Core.api_key
54
- # client = OpenAI(api_key=self.Core.api_key)
55
- #
56
- # for attempt in range(max_retries):
57
- # try:
58
- # response = client.chat.completions.create(
59
- # model=self.Core.model,
60
- # messages= [{"role": "system", "content": instructions},{"role": "user", "content": prompt}],
61
- # response_format={"type": "json_object"},
62
- # reasoning_effort=self.reasoning,
63
- # max_tokens=1000,
64
- # temperature=self.Core.temperature,
65
- # tools=[]
66
- # )
67
- #
68
- # tokens = {
69
- # 'prompt_tokens': response.usage.prompt_tokens,
70
- # 'completion_tokens': response.usage.completion_tokens,
71
- # 'total_tokens': response.usage.total_tokens
72
- # }
73
- #
74
- # try:
75
- # content = response.choices[0].message.content
76
- #
77
- # # Extract JSON code block
78
- #
79
- # output = json.loads(content)
80
- #
81
- # if 'message' not in output or 'header' not in output:
82
- # print(f"'message' or 'header' is missing in response on attempt {attempt + 1}. Retrying...")
83
- # continue # Continue to next attempt
84
- #
85
- # else:
86
- # if len(output["header"].strip()) > self.Core.config_file["header_limit"] or len(
87
- # output["message"].strip()) > self.Core.config_file["message_limit"]:
88
- # print(
89
- # f"'header' or 'message' is more than specified characters in response on attempt {attempt + 1}. Retrying...")
90
- # continue
91
- #
92
- # # validating the JSON
93
- # self.Core.total_tokens['prompt_tokens'] += tokens['prompt_tokens']
94
- # self.Core.total_tokens['completion_tokens'] += tokens['completion_tokens']
95
- # self.Core.temp_token_counter += tokens['total_tokens']
96
- # return output
97
- #
98
- # except json.JSONDecodeError:
99
- # print(f"Invalid JSON from LLM on attempt {attempt + 1}. Retrying...")
100
- #
101
- # except openai.APIConnectionError as e:
102
- # print("The server could not be reached")
103
- # print(e.__cause__) # an underlying Exception, likely raised within httpx.
104
- # except openai.RateLimitError as e:
105
- # print("A 429 status code was received; we should back off a bit.")
106
- # except openai.APIStatusError as e:
107
- # print("Another non-200-range status code was received")
108
- # print(e.status_code)
109
- # print(e.response)
110
- #
111
- # print("Max retries exceeded. Returning empty response.")
112
- # return None
113
-
114
 
 
115
 
116
  def get_message_openai(self, prompt, instructions, max_retries=4):
117
  """
@@ -251,6 +198,62 @@ class LLM:
251
  print("Max retries exceeded. Returning empty response.")
252
  return [], {}
253
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  # ======================================================================
255
 
256
  def preprocess_and_parse_json(self, response: str):
@@ -280,6 +283,18 @@ class LLM:
280
  # print("Offending text:", json_text)
281
  return None
282
 
 
 
 
 
 
 
 
 
 
 
 
 
283
 
284
 
285
 
 
9
  import ollama
10
  import torch
11
  import re
12
+ import anthropic
13
+ import os
14
+ import streamlit as st
15
 
16
 
17
 
 
23
  self.client = None
24
  self.connect_to_llm()
25
 
26
+ def get_credential(self, key):
27
+ return os.getenv(key) or st.secrets.get(key)
28
 
29
  def get_response(self, prompt, instructions):
30
  if self.model_type == "openai":
31
  response = self.get_message_openai(prompt, instructions)
32
  elif self.model_type == "ollama":
33
  response = self.get_message_ollama(prompt, instructions)
34
+
35
+ elif self.model_type == "claude":
36
+ response = self.get_message_claude(prompt, instructions)
37
  else:
38
  raise f"Invalid model type : {self.model_type}"
39
 
 
48
  if self.Core.model in self.Core.config_file["openai_models"]:
49
  self.model_type = "openai"
50
 
51
+ elif self.Core.model in self.Core.config_file["ollama_models"]:
52
  self.model_type = "ollama"
53
  self.client = ollama.Client()
54
 
55
+ elif self.Core.model in self.Core.config_file["claude_models"]:
56
+ self.model_type = "claude"
57
+ self.client = anthropic.Anthropic(
58
+ api_key=self.get_credential('claude_api_key'),
59
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ self.model = self.Core.model
62
 
63
  def get_message_openai(self, prompt, instructions, max_retries=4):
64
  """
 
198
  print("Max retries exceeded. Returning empty response.")
199
  return [], {}
200
 
201
+ def get_message_claude(self, prompt, instructions, max_retries=4):
202
+ """
203
+ send prompt to claude LLM and get back the response
204
+ :param prompt:
205
+ :param instructions:
206
+ :return:
207
+ """
208
+
209
+
210
+ for attempt in range(max_retries):
211
+ try:
212
+
213
+ message = self.client.messages.create(
214
+ model=self.model,
215
+ max_tokens=4096,
216
+ system = instructions,
217
+ messages=[
218
+ {"role": "user", "content": prompt + "\nHere is the JSON requested:\n"}
219
+ ],
220
+ temperature=self.Core.temperature
221
+ )
222
+ # Try generating the response
223
+ response = message.content[0].text
224
+
225
+ tokens = {
226
+ 'prompt_tokens': 0,
227
+ 'completion_tokens': 0,
228
+ 'total_tokens': 0
229
+ }
230
+
231
+ try:
232
+ output = self.preprocess_and_parse_json_claude(response)
233
+ if output is None:
234
+ continue
235
+
236
+ if 'message' not in output or 'header' not in output:
237
+ print(f"'message' or 'header' is missing in response on attempt {attempt + 1}. Retrying...")
238
+ continue # Continue to next attempt
239
+
240
+ else:
241
+ if len(output["header"].strip()) > self.Core.config_file["header_limit"] or len(
242
+ output["message"].strip()) > self.Core.config_file["message_limit"]:
243
+ print(
244
+ f"'header' or 'message' is more than specified characters in response on attempt {attempt + 1}. Retrying...")
245
+ continue
246
+ else:
247
+ return output
248
+
249
+ except json.JSONDecodeError:
250
+ print(f"Invalid JSON from LLM on attempt {attempt + 1}. Retrying...")
251
+ except Exception as parse_error:
252
+ print("Error processing output:", parse_error)
253
+
254
+ print("Max retries exceeded. Returning empty response.")
255
+ return [], {}
256
+
257
  # ======================================================================
258
 
259
  def preprocess_and_parse_json(self, response: str):
 
283
  # print("Offending text:", json_text)
284
  return None
285
 
286
+ # ===============================================================
287
+ def preprocess_and_parse_json_claude(self, response: str):
288
+ """
289
+ process claude response and extract JSON
290
+ :param response:
291
+ :return:
292
+ """
293
+ json_start = response.index("{")
294
+ json_end = response.rfind("}")
295
+ parsed_response = json.loads(response[json_start:json_end + 1])
296
+ return parsed_response
297
+
298
 
299
 
300
 
Messaging_system/PromptEng.py CHANGED
@@ -4,12 +4,13 @@ This is the prompt engineering layer to modifty the prompt for better perfromanc
4
  import openai
5
  from fontTools.ttLib.tables.ttProgram import instructions
6
  from openai import OpenAI
7
-
8
 
9
  class PromptEngine:
10
 
11
  def __init__(self, coreconfig):
12
  self.Core=coreconfig
 
13
 
14
  # =============================================================
15
  def prompt_engineering(self, prompt):
@@ -36,8 +37,18 @@ output the new prompt as text without any additional information.
36
 
37
  """
38
 
39
- final_prompt = self.get_llm_response(new_prompt)
40
  return final_prompt
 
 
 
 
 
 
 
 
 
 
41
 
42
  # ============================================================
43
  def llm_instructions(self):
@@ -50,7 +61,7 @@ output the new prompt as text without any additional information.
50
 
51
  # =============================================================
52
 
53
- def get_llm_response(self, prompt, max_retries=4):
54
  """
55
  sending the prompt to openai LLM and get back the response
56
  """
@@ -115,3 +126,35 @@ output the new prompt as text without any additional information.
115
  return prompt # returns original prompt if needed
116
 
117
  # ==========================================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  import openai
5
  from fontTools.ttLib.tables.ttProgram import instructions
6
  from openai import OpenAI
7
+ from Messaging_system.LLM import LLM
8
 
9
  class PromptEngine:
10
 
11
  def __init__(self, coreconfig):
12
  self.Core=coreconfig
13
+ self.llm=LLM(self.Core)
14
 
15
  # =============================================================
16
  def prompt_engineering(self, prompt):
 
37
 
38
  """
39
 
40
+ final_prompt = self.get_final_prompt(new_prompt)
41
  return final_prompt
42
+ # ===========================================================
43
+ def get_final_prompt(self, prompt):
44
+
45
+ if self.Core.model in self.Core.config_file["openai_models"]:
46
+ final_prompt = self.get_openai_response(prompt)
47
+ return final_prompt
48
+
49
+ elif self.Core.model in self.Core.config_file["claude_models"]:
50
+ final_prompt = self.get_claude_response(prompt, self.llm_instructions())
51
+ return final_prompt
52
 
53
  # ============================================================
54
  def llm_instructions(self):
 
61
 
62
  # =============================================================
63
 
64
+ def get_openai_response(self, prompt, max_retries=4):
65
  """
66
  sending the prompt to openai LLM and get back the response
67
  """
 
126
  return prompt # returns original prompt if needed
127
 
128
  # ==========================================================================
129
+
130
+
131
+ def get_claude_response(self, prompt, instructions, max_retries=4):
132
+ """
133
+ send prompt to claude LLM and get back the response
134
+ :param prompt:
135
+ :param instructions:
136
+ :return:
137
+ """
138
+
139
+ for attempt in range(max_retries):
140
+ try:
141
+
142
+ message = self.llm.client.messages.create(
143
+ model=self.Core.model,
144
+ max_tokens=4096,
145
+ system = instructions,
146
+ messages=[
147
+ {"role": "user", "content": prompt}
148
+ ],
149
+ temperature=self.Core.temperature
150
+ )
151
+ # Try generating the response
152
+ response = message.content[0].text
153
+ return response
154
+ except Exception as e:
155
+ print(f"Error: {e}")
156
+
157
+
158
+ print("Max retries exceeded. Returning empty response.")
159
+ return prompt # returns original prompt if needed
160
+
messaging_main_test.py CHANGED
@@ -136,18 +136,14 @@ if __name__ == "__main__":
136
  # number of messages to generate
137
  number_of_messages = 3
138
  instructionset = {
139
- 1: "Talk like a singing coach motivating your student. Don't say things a singer wouldn't say. Make the message quick, concise, and in casual language. Tell them to practice, take a lesson, or warm up today. ",
140
  2: "Talk like a singing coach motivating your student. Don't say things a singer wouldn't say. Make the message quick, concise, and in casual language. Tell them to practice, take a lesson, or warm up today. ",
141
- 3: "Talk like a singing coach motivating your student. Don't say things a singer wouldn't say. Make the message quick, concise, and in casual language. Tell them to practice, take a lesson, or warm up today. ",
142
- }
143
 
144
  subsequent_examples = {
145
- 1: "Header: Sing Your Heart Out!"
146
  "Message: It’s been a few days. Take a lesson today and start practicing!",
147
- 2: "header: Here Comes The Sun"
148
- "message: A quick practice session will light up your day. Let’s get right back at it. ",
149
- 3: "header: Ain’t No Mountain High Enough"
150
- "message: Daily practice makes you unstoppable. Time to build your skills!"
151
  }
152
 
153
  involve_recsys_result = True
@@ -167,7 +163,7 @@ if __name__ == "__main__":
167
  # o3-mini o1-mini o4-mini o1
168
 
169
  users_message = permes.create_personalize_messages(session=session,
170
- model="o4-mini",
171
  users=users,
172
  brand=brand,
173
  config_file=config_file,
 
136
  # number of messages to generate
137
  number_of_messages = 3
138
  instructionset = {
 
139
  2: "Talk like a singing coach motivating your student. Don't say things a singer wouldn't say. Make the message quick, concise, and in casual language. Tell them to practice, take a lesson, or warm up today. ",
140
+ 3: "Talk like a singing coach motivating your student. Don't say things a singer wouldn't say. Make the message quick, concise, and in casual language. Tell them to practice, take a lesson, or warm up today. "}
 
141
 
142
  subsequent_examples = {
143
+ 2: "Header: Sing Your Heart Out!"
144
  "Message: It’s been a few days. Take a lesson today and start practicing!",
145
+ 3: "header: Here Comes The Sun"
146
+ "message: A quick practice session will light up your day. Let’s get right back at it. "
 
 
147
  }
148
 
149
  involve_recsys_result = True
 
163
  # o3-mini o1-mini o4-mini o1
164
 
165
  users_message = permes.create_personalize_messages(session=session,
166
+ model="claude-3-5-haiku-latest",
167
  users=users,
168
  brand=brand,
169
  config_file=config_file,
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ