Danialebrat commited on
Commit
fa44311
·
1 Parent(s): 4f26c60

-changing subsequent messages similar to initial messages and change prompting

Browse files
.idea/AI_Message_Generator.iml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="PYTHON_MODULE" version="4">
3
+ <component name="NewModuleRootManager">
4
+ <content url="file://$MODULE_DIR$" />
5
+ <orderEntry type="jdk" jdkName="Python 3.9" jdkType="Python SDK" />
6
+ <orderEntry type="sourceFolder" forTests="false" />
7
+ </component>
8
+ </module>
Messaging_system/MultiMessage.py CHANGED
@@ -1,7 +1,7 @@
1
  import json
2
  import time
3
  from openai import OpenAI
4
-
5
  from Messaging_system.PromptEng import PromptEngine
6
  from Messaging_system.protection_layer import ProtectionLayer
7
  import openai
@@ -16,6 +16,7 @@ class MultiMessage:
16
  self.Core = CoreConfig
17
  self.llm = LLM(CoreConfig)
18
  self.engine = PromptEngine(self.Core)
 
19
 
20
  # --------------------------------------------------------------
21
  def generate_multi_messages(self, user):
@@ -56,7 +57,7 @@ class MultiMessage:
56
  # Already have the first message, so generate the next (n-1) messages
57
  for step in range(1, total_to_generate + 1):
58
  # 2) Generate the next message referencing all so-far messages
59
- next_msg_raw = self.generate_next_messages(message_sequence, step+1)
60
  if not next_msg_raw:
61
  print(f"Could not generate the message for step {step}. Stopping.")
62
  break
@@ -93,7 +94,7 @@ class MultiMessage:
93
  return json.dumps(final_structure, ensure_ascii=False)
94
 
95
  # --------------------------------------------------------------
96
- def generate_next_messages(self, previous_messages, step):
97
  """
98
  Uses only the last two previously generated messages to produce the next message.
99
  Returns a *raw* dictionary (header, message, etc.) from the LLM.
@@ -109,7 +110,7 @@ class MultiMessage:
109
  context = previous_messages
110
 
111
  # 1) Build a prompt that includes only those last two messages
112
- prompt = self.generate_prompt(context, step)
113
 
114
  # new_prompt = self.engine.prompt_engineering(prompt)
115
 
@@ -128,29 +129,28 @@ class MultiMessage:
128
  if self.Core.subsequent_examples is not None:
129
 
130
  instructions = f"""
131
- # ** Example **
132
- Below are some acceptable examples of the voice we want. Create a header and message that follow the same style, tone, vocabulary, and characteristics.
133
- Mimic the example style as much as possible and make it personalized using provided information.
134
-
135
 
136
- ### **Good Examples:**
137
-
138
- {self.Core.subsequent_examples[step]}
139
- """
140
  return instructions
141
  else:
142
  return ""
143
 
144
  # --------------------------------------------------------------
145
- def generate_prompt(self, previous_messages, step):
146
  """
147
  Creates a prompt to feed to the LLM, incorporating 3 previously generated messages.
148
 
149
  :param previous_messages: A list of dicts, each containing 'header' and 'message'.
150
  :return: A user-facing prompt string instructing the model to produce a new message.
151
  """
152
- # Build a textual summary of previous messages
153
- # ──► NEW: keep at most the last three messages
154
  recent_messages = previous_messages[-3:]
155
 
156
  previous_text = []
@@ -162,10 +162,10 @@ class MultiMessage:
162
  # Combine into a single string
163
  previous_text_str = "\n\n".join(previous_text)
164
 
165
- # Provide constraints for our next push notification
166
- header_limit = self.Core.config_file.get("header_limit", 50)
167
- message_limit = self.Core.config_file.get("message_limit", 200)
168
-
169
 
170
  examples = self.get_examples(step)
171
 
@@ -173,48 +173,74 @@ class MultiMessage:
173
  # Craft the prompt
174
  prompt = f"""
175
  We have previously sent these push notifications to the user and The user has not re-engaged yet:
176
- User info:
177
- {self.Core.segment_info}
178
 
179
  ** Previous messages **
180
  {previous_text_str}
181
 
 
182
  **Objective**
183
- Write the *next* follow up personalized push notification following the instructions.
184
- You are texting a friend and it should feel like a friendly encouraging nudge. Your task is to write a 'header' and a 'message' as a push notification for a {self.Core.get_instrument()} student that sounds like natural everyday speech: friendly, concise, no jargon, and following the instructions.
185
- Write a SUPER CASUAL and NATURAL push notification, as if you are chatting over coffee. Avoid odd phrasings.
186
- The user is a {str(self.Core.get_instrument())} student.
187
-
188
- # **General instructions**:
189
-
190
- - Start directly with the message content without greetings or closing phrases (every word counts).
191
- - Follow the Good examples to mimic the style and vocabulary.
192
- - Use {self.Core.get_emoji()} only if it sharpens impact. Don't use Emoji if we already had it in our previous message.**
193
- - "message" and "header" **MUST NOT** contain similar or close words and phrases, and make sure there is no grammar problem.
194
- - New header and message **MUST BE** clearly different from all earlier headers & messages in terms of vocabulary and phrases (They must not be similar)
195
-
196
-
197
- # **Tune, Style and specific instructions**:
198
- - The message and header should sound natural and friendly, like something that people would normally say in daily conversations. This is the most important part of the notification. It should sound like everyday natural speech: friendly conversation.
199
  - {self.Core.subsequence_messages[step]}
200
 
201
  {examples}
202
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
- # Constraints:
205
- - "header" must be fewer than {header_limit} characters.
206
- - "message" must be fewer than {message_limit} characters.
207
- - Output must be valid JSON with exactly two keys: "header" and "message".
 
 
208
 
 
 
209
 
210
- Return only JSON of the form:
211
  {{
212
- "header": "...",
213
- "message": "..."
214
  }}
215
- """.strip()
216
 
217
- return prompt
 
 
218
 
219
  # --------------------------------------------------------------
220
  def parsing_output_message(self, message, user):
 
1
  import json
2
  import time
3
  from openai import OpenAI
4
+ from Messaging_system.PromptGenerator import PromptGenerator
5
  from Messaging_system.PromptEng import PromptEngine
6
  from Messaging_system.protection_layer import ProtectionLayer
7
  import openai
 
16
  self.Core = CoreConfig
17
  self.llm = LLM(CoreConfig)
18
  self.engine = PromptEngine(self.Core)
19
+ self.promptGen = PromptGenerator(self.Core)
20
 
21
  # --------------------------------------------------------------
22
  def generate_multi_messages(self, user):
 
57
  # Already have the first message, so generate the next (n-1) messages
58
  for step in range(1, total_to_generate + 1):
59
  # 2) Generate the next message referencing all so-far messages
60
+ next_msg_raw = self.generate_next_messages(message_sequence, step+1, user)
61
  if not next_msg_raw:
62
  print(f"Could not generate the message for step {step}. Stopping.")
63
  break
 
94
  return json.dumps(final_structure, ensure_ascii=False)
95
 
96
  # --------------------------------------------------------------
97
+ def generate_next_messages(self, previous_messages, step, user):
98
  """
99
  Uses only the last two previously generated messages to produce the next message.
100
  Returns a *raw* dictionary (header, message, etc.) from the LLM.
 
110
  context = previous_messages
111
 
112
  # 1) Build a prompt that includes only those last two messages
113
+ prompt = self.generate_prompt(context, step, user)
114
 
115
  # new_prompt = self.engine.prompt_engineering(prompt)
116
 
 
129
  if self.Core.subsequent_examples is not None:
130
 
131
  instructions = f"""
132
+ # ** Example **
133
+ Below are some acceptable examples of the voice we want. Create a header and message that follow the same style, tone, vocabulary, and characteristics.
134
+ Mimic the example style as much as possible and make it personalized using provided information.
135
+
136
 
137
+ ### **Good Examples:**
138
+
139
+ {self.Core.subsequent_examples[step]}
140
+ """
141
  return instructions
142
  else:
143
  return ""
144
 
145
  # --------------------------------------------------------------
146
+ def generate_prompt(self, previous_messages, step, user):
147
  """
148
  Creates a prompt to feed to the LLM, incorporating 3 previously generated messages.
149
 
150
  :param previous_messages: A list of dicts, each containing 'header' and 'message'.
151
  :return: A user-facing prompt string instructing the model to produce a new message.
152
  """
153
+ # Build a textual summary of previous messages - last three
 
154
  recent_messages = previous_messages[-3:]
155
 
156
  previous_text = []
 
162
  # Combine into a single string
163
  previous_text_str = "\n\n".join(previous_text)
164
 
165
+ user_info = self.promptGen.get_user_profile(user=user)
166
+ input_context = self.promptGen.input_context()
167
+ output_instructions = self.output_instruction()
168
+ general_specifications = self.general_specifications()
169
 
170
  examples = self.get_examples(step)
171
 
 
173
  # Craft the prompt
174
  prompt = f"""
175
  We have previously sent these push notifications to the user and The user has not re-engaged yet:
 
 
176
 
177
  ** Previous messages **
178
  {previous_text_str}
179
 
180
+
181
  **Objective**
182
+ Write the *next* follow up personalized push notification following the instructions and what we know about the user.
183
+ {input_context}
184
+
185
+ {user_info}
186
+
187
+ ### ** General Specifications: **
188
+
189
+ {general_specifications}
190
+
191
+ # **specific instructions**:
 
 
 
 
 
 
192
  - {self.Core.subsequence_messages[step]}
193
 
194
  {examples}
195
 
196
+ {output_instructions}
197
+ """
198
+
199
+ return prompt
200
+ # ===========================================================================
201
+ def general_specifications(self):
202
+ """
203
+ general_specifications
204
+ :return: instructions
205
+ """
206
+
207
+ instructions = """
208
+ - Start directly with the message content without greetings or closing phrases.
209
+ - Avoid using same or similar words so close together in "message" and "header", and make sure there is no grammar problem.
210
+ - The message, vocabulary and sentences **MUST** sound like a natural conversation: something that people normally say in daily conversations.
211
+
212
+ """
213
+ return instructions
214
+
215
+ # =============================================================================
216
+
217
+ def output_instruction(self):
218
+ """
219
+ :return: output instructions as a string
220
+ """
221
+
222
+ # Provide constraints for our next push notification
223
+ header_limit = self.Core.config_file.get("header_limit", 50)
224
+ message_limit = self.Core.config_file.get("message_limit", 200)
225
 
226
+ general_instructions = f"""
227
+ - The "header" must be less than {header_limit} character.
228
+ - The "message" must be less than {message_limit} character.
229
+ - Preserve special characters and emojis in the message, you are **ONLY ALLOWED**allowed to use {self.Core.get_emoji()} emoji if needed, ONLY ONCE, and ONLY at the end of header or message).
230
+ - Ensure that the output is a valid JSON and not include any text outside the JSON code block.
231
+ """
232
 
233
+ instructions = f"""
234
+ Expected output structure:
235
 
 
236
  {{
237
+ "header": "Generated title",
238
+ "message": "Generated message",
239
  }}
 
240
 
241
+ {general_instructions}
242
+ """
243
+ return instructions
244
 
245
  # --------------------------------------------------------------
246
  def parsing_output_message(self, message, user):
Messaging_system/PromptGenerator.py CHANGED
@@ -43,12 +43,16 @@ class PromptGenerator:
43
  # additional_info = self.user_additional_info(user)
44
 
45
  user_info = f"""
46
- ### **User Information:**
47
 
48
- Here is the information about the user:
49
- The user is a {str(self.Core.get_instrument())} student.
50
-
51
- {self.safe_get(self.Core.segment_info)}
 
 
 
 
52
 
53
  """
54
 
@@ -94,15 +98,15 @@ class PromptGenerator:
94
  # eliminate {task_instructions} and {recommendations_instructions}
95
 
96
  prompt = f"""
97
- {input_context}
98
-
99
- {user_info}
100
-
101
- {cta}
102
-
103
- {general_instructions}
104
-
105
- {output_instructions}
106
  """
107
 
108
  return prompt
@@ -115,7 +119,12 @@ class PromptGenerator:
115
  """
116
 
117
  context = f"""
118
- Your task is to write a 'header' and a 'message' as a push notification for a {self.Core.get_instrument()} student that sounds like everyday natural speech: friendly, short, no jargon by following the instructions.
 
 
 
 
 
119
  """
120
 
121
  return context
@@ -130,9 +139,9 @@ class PromptGenerator:
130
 
131
  instructions = f"""
132
 
133
- ### **Main instructions**
134
-
135
- {self.Core.CTA} \n
136
  """
137
 
138
  return instructions
@@ -292,12 +301,12 @@ class PromptGenerator:
292
 
293
  if self.Core.platform == "push":
294
  instructions = f"""
295
- ### ** General Specifications: **
296
 
297
- - Start directly with the message content without greetings or closing phrases.
298
- - Avoid using same or similar words so close together in "message" and "header", and make sure there is no grammar problem.
299
- - The message, vocabulary and sentences **MUST** sound like a natural conversation: something that people normally say in daily conversations.
300
- - {message_style}
301
 
302
  """
303
 
@@ -345,28 +354,28 @@ class PromptGenerator:
345
 
346
  example_output = self.example_output()
347
  general_instructions = f"""
348
- - The "header" must be less than 30 character.
349
- - The "message" must be less than 100 character.
350
- - Preserve special characters and emojis in the message, you are **ONLY ALLOWED**allowed to use {self.Core.get_emoji()} emoji if needed, ONLY ONCE, and ONLY at the end of header or message).
351
- - Ensure that the output is a valid JSON and not include any text outside the JSON code block.
352
  """
353
 
354
  instructions = f"""
355
- Expected output structure:
356
 
357
- {{
358
- "header": "Generated title",
359
- "message": "Generated message",
360
- }}
361
 
362
- {general_instructions}
363
  """
364
 
365
  output_instructions = f"""
366
- ### **Output instructions**:
367
 
368
- {example_output}
369
- {instructions}
370
  """
371
 
372
  return output_instructions
 
43
  # additional_info = self.user_additional_info(user)
44
 
45
  user_info = f"""
46
+ ### **User Information:**
47
 
48
+ Here is the information about the user:
49
+ - The user is a {str(self.Core.get_instrument())} student.
50
+ - {self.safe_get(self.Core.segment_info)}
51
+ - first name: {self.safe_get(user.get("first_name"))}
52
+
53
+ **user_profile**
54
+
55
+ {self.safe_get(user.get("user_info"))}
56
 
57
  """
58
 
 
98
  # eliminate {task_instructions} and {recommendations_instructions}
99
 
100
  prompt = f"""
101
+ {input_context}
102
+
103
+ {user_info}
104
+
105
+ {cta}
106
+
107
+ {general_instructions}
108
+
109
+ {output_instructions}
110
  """
111
 
112
  return prompt
 
119
  """
120
 
121
  context = f"""
122
+ Your task is to write a 'header' and a 'message' as a push notification for a {self.Core.get_instrument()} student that sounds like everyday natural speech: friendly, short, no jargon by following the instructions.
123
+ The output should sound like something that a {self.Core.get_instrument()} instructor would realistically say to a student in a daily conversation.
124
+
125
+ ** Examples of actual phrases an instructor might say:**
126
+
127
+ {self.Core.brand_voice}
128
  """
129
 
130
  return context
 
139
 
140
  instructions = f"""
141
 
142
+ ### **Main instructions**
143
+
144
+ {self.Core.CTA} \n
145
  """
146
 
147
  return instructions
 
301
 
302
  if self.Core.platform == "push":
303
  instructions = f"""
304
+ ### ** General Specifications: **
305
 
306
+ - Start directly with the message content without greetings or closing phrases.
307
+ - Avoid using same or similar words so close together in "message" and "header", and make sure there is no grammar problem.
308
+ - The message, vocabulary and sentences **MUST** sound like a natural conversation: something that people normally say in daily conversations.
309
+ - {message_style}
310
 
311
  """
312
 
 
354
 
355
  example_output = self.example_output()
356
  general_instructions = f"""
357
+ - The "header" must be less than 30 character.
358
+ - The "message" must be less than 100 character.
359
+ - Preserve special characters and emojis in the message, you are **ONLY ALLOWED**allowed to use {self.Core.get_emoji()} emoji if needed, ONLY ONCE, and ONLY at the end of header or message).
360
+ - Ensure that the output is a valid JSON and not include any text outside the JSON code block.
361
  """
362
 
363
  instructions = f"""
364
+ Expected output structure:
365
 
366
+ {{
367
+ "header": "Generated title",
368
+ "message": "Generated message",
369
+ }}
370
 
371
+ {general_instructions}
372
  """
373
 
374
  output_instructions = f"""
375
+ ### **Output instructions**:
376
 
377
+ {example_output}
378
+ {instructions}
379
  """
380
 
381
  return output_instructions