sravan837 commited on
Commit
51dee27
·
verified ·
1 Parent(s): 86be3b6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -82
app.py CHANGED
@@ -2,60 +2,75 @@ import gradio as gr
2
  import json
3
  import asyncio
4
  import edge_tts
 
5
  import os
6
  from huggingface_hub import InferenceClient
7
 
8
- # --- CONFIGURATION ---
9
- # We use Llama-3 for BOTH tasks now as it is the most reliable on the free tier
10
  EXTRACTOR_MODEL = "meta-llama/Meta-Llama-3-8B-Instruct"
11
  PERSONALITY_MODEL = "meta-llama/Meta-Llama-3-8B-Instruct"
12
 
13
- # Default Data
14
  DEFAULT_LOGS = """
15
- 1. User: I feel completely drained after large social gatherings.
16
- 2. User: I enjoy abstract theories more than practical details.
17
- 3. User: My desk is always messy, but I know where everything is.
18
- 4. User: I often worry that I said the wrong thing in conversations.
19
- 5. User: I prefer planning everything weeks in advance. Spontaneity stresses me out.
20
- 6. User: I find it hard to sympathize with people who are overly emotional.
21
- 7. User: I love exploring new ideas and hobbies, even if I don't finish them.
22
- 8. User: Criticism hits me really hard, even if it's constructive.
23
- 9. User: I tend to take charge in group projects because I want things done right.
24
- 10. User: I value logic and truth over sparing someone's feelings.
25
- 11. User: I often get lost in my own thoughts and forget my surroundings.
26
- 12. User: I hate conflict. I will do anything to keep the peace.
27
- 13. User: I feel a strong need to help others, sometimes at my own expense.
28
- 14. User: I get bored easily with routine tasks.
29
- 15. User: I am very skeptical until I see concrete evidence.
30
- 16. User: I love meeting new people and being the center of attention.
31
- 17. User: I struggle to express my emotions verbally.
32
- 18. User: I often procrastinate until the very last minute.
33
- 19. User: I feel deeply moved by art and music.
34
- 20. User: I prefer a few close friends over a large group of acquaintances.
35
- 21. User: I have a hard time saying "no" to people.
36
- 22. User: I am constantly analyzing why people do what they do.
37
- 23. User: I value tradition and established rules.
38
- 24. User: I am often described as "intense" or "serious."
39
- 25. User: I feel energetic when I'm debating intellectual topics.
40
- 26. User: I worry a lot about the future.
41
- 27. User: I trust my gut instincts more than data sometimes.
42
- 28. User: I prefer to work alone rather than in a team.
43
- 29. User: I am very competitive and hate losing.
44
- 30. User: I want to understand my true purpose in life.
45
  """
46
 
47
- # --- LOGIC: MEMORY EXTRACTION ---
 
 
 
 
 
 
 
 
 
48
  def extract_memory(chat_logs, hf_token):
49
  if not hf_token:
50
- return json.dumps({"error": "Missing HF Token"}, indent=2)
51
 
52
  client = InferenceClient(token=hf_token)
53
 
 
54
  system_prompt = """
55
- You are a Psychological Analyst. Analyze the chat logs.
56
- Extract a profile with these JSON KEYS:
57
- "traits" (Big Five/MBTI), "values" (Logic, Harmony, etc), "struggles" (Anxiety, Procrastination).
58
- OUTPUT: Valid JSON only. Do not add markdown blocks like ```json.
 
 
 
 
59
  """
60
 
61
  messages = [
@@ -67,48 +82,47 @@ def extract_memory(chat_logs, hf_token):
67
  response = client.chat_completion(
68
  model=EXTRACTOR_MODEL,
69
  messages=messages,
70
- max_tokens=600,
71
  temperature=0.1
72
  )
73
 
74
- # Parse JSON
75
  text = response.choices[0].message.content.strip()
76
-
77
- # Cleaning potential markdown formatting from LLM response
78
- if "```json" in text:
79
  text = text.replace("```json", "").replace("```", "")
80
-
81
  start = text.find("{")
82
  end = text.rfind("}") + 1
83
  return json.dumps(json.loads(text[start:end]), indent=2)
84
  except Exception as e:
85
  return json.dumps({"error": str(e)}, indent=2)
86
 
87
- # --- LOGIC: PERSONALITY RESPONSE ---
88
  async def generate_response_and_audio(message, memory_json, persona, hf_token):
89
  if not hf_token:
90
- return "Please enter HF Token.", None
91
 
92
  client = InferenceClient(token=hf_token)
93
 
 
94
  try:
95
  memory = json.loads(memory_json)
96
  except:
97
  memory = {}
98
 
99
- # 1. Define Persona Prompts
100
  prompts = {
101
- "Calm Mentor": "Role: Mentor. Tone: Calm, wise, patient. Focus: Growth, long-term perspective. Voice: Deep & Slow.",
102
- "Witty Friend": "Role: Friend. Tone: Witty, casual, sarcastic, fun. Focus: Relatability, humor. Voice: Fast & Energetic.",
103
- "Therapist-style": "Role: Therapist. Tone: Empathetic, soft, validating. Focus: Emotions, safety. Voice: Soft & Warm."
104
  }
105
 
106
- # 2. Context Injection
107
  context = f"""
108
- USER PROFILE:
109
- - Traits: {memory.get('traits', 'Unknown')}
110
  - Values: {memory.get('values', 'Unknown')}
111
- - Struggles: {memory.get('struggles', 'Unknown')}
112
  """
113
 
114
  messages = [
@@ -117,7 +131,7 @@ async def generate_response_and_audio(message, memory_json, persona, hf_token):
117
  ]
118
 
119
  try:
120
- # 3. Generate Text
121
  res = client.chat_completion(
122
  model=PERSONALITY_MODEL,
123
  messages=messages,
@@ -126,57 +140,60 @@ async def generate_response_and_audio(message, memory_json, persona, hf_token):
126
  )
127
  text_reply = res.choices[0].message.content
128
 
129
- # 4. Generate Audio (Edge-TTS)
 
 
 
130
  voice_map = {
131
- "Calm Mentor": "en-US-ChristopherNeural",
132
- "Witty Friend": "en-US-EricNeural",
133
- "Therapist-style": "en-US-AvaNeural"
134
  }
135
 
 
136
  output_file = "response.mp3"
137
- communicate = edge_tts.Communicate(text_reply, voice_map.get(persona, "en-US-AriaNeural"))
138
  await communicate.save(output_file)
139
 
140
  return text_reply, output_file
141
 
142
  except Exception as e:
143
- return f"API Error: {str(e)}", None
144
 
145
- # Wrapper for Gradio
146
  def process_interaction(message, memory_json, persona, hf_token):
147
  return asyncio.run(generate_response_and_audio(message, memory_json, persona, hf_token))
148
 
149
- # --- GRADIO UI ---
150
  with gr.Blocks(title="Personality Engine") as demo:
151
- gr.Markdown("# Personality Engine: Memory & Tones")
152
 
153
  with gr.Row():
154
- token_input = gr.Textbox(label="Hugging Face Token", type="password", placeholder="Paste HF Token here...")
155
 
156
  with gr.Row():
157
- # Left Column: Memory
158
- with gr.Column(scale=1):
159
- gr.Markdown("### 1. Memory Extraction")
160
- logs_input = gr.Textbox(label="Chat Logs (Input)", value=DEFAULT_LOGS, lines=10)
161
- extract_btn = gr.Button("Analyze Profile")
162
- memory_output = gr.Code(label="Extracted Memory (JSON)", language="json")
163
 
164
  extract_btn.click(extract_memory, inputs=[logs_input, token_input], outputs=memory_output)
165
 
166
- # Right Column: Interaction
167
- with gr.Column(scale=1):
168
- gr.Markdown("### 2. Personality Interaction")
169
- user_msg = gr.Textbox(label="Your Message", value="I'm feeling overwhelmed by the future.")
170
  persona_select = gr.Radio(
171
- ["Calm Mentor", "Witty Friend", "Therapist-style"],
172
- label="Select Tone",
173
  value="Calm Mentor"
174
  )
175
- generate_btn = gr.Button("Generate Response")
176
 
177
- with gr.Group():
178
- text_output = gr.Markdown(label="Response Text")
179
- audio_output = gr.Audio(label="Voice Response")
180
 
181
  generate_btn.click(
182
  process_interaction,
 
2
  import json
3
  import asyncio
4
  import edge_tts
5
+ import re
6
  import os
7
  from huggingface_hub import InferenceClient
8
 
9
+ # --- SETTINGS ---
10
+ # We use the Llama-3 model for everything because it is smart and free.
11
  EXTRACTOR_MODEL = "meta-llama/Meta-Llama-3-8B-Instruct"
12
  PERSONALITY_MODEL = "meta-llama/Meta-Llama-3-8B-Instruct"
13
 
14
+ # Default Chat History (30 messages showing different personality traits)
15
  DEFAULT_LOGS = """
16
+ 1. User: I feel tired after big parties. I need to be alone to recharge.
17
+ 2. User: I like ideas more than real-world details.
18
+ 3. User: My desk is messy, but I know where my stuff is.
19
+ 4. User: I worry that I said the wrong thing.
20
+ 5. User: I like to plan ahead. Surprises stress me out.
21
+ 6. User: It is hard for me to understand why people cry over small things.
22
+ 7. User: I start many hobbies but do not finish them.
23
+ 8. User: I feel bad when someone criticizes me.
24
+ 9. User: I take charge in groups to make sure work is done right.
25
+ 10. User: Logic is more important than feelings.
26
+ 11. User: I daydream a lot.
27
+ 12. User: I hate fighting. I want everyone to get along.
28
+ 13. User: I help others even if it hurts me.
29
+ 14. User: Boring tasks make me sleepy.
30
+ 15. User: I need proof before I believe something.
31
+ 16. User: I love being the center of attention.
32
+ 17. User: I am bad at talking about my feelings.
33
+ 18. User: I wait until the last minute to do work.
34
+ 19. User: Music makes me feel strong emotions.
35
+ 20. User: I prefer 2 close friends over 20 acquaintances.
36
+ 21. User: I cannot say "no" to people.
37
+ 22. User: I always analyze why people act the way they do.
38
+ 23. User: I like following rules and traditions.
39
+ 24. User: People say I am too serious.
40
+ 25. User: I have lots of energy when debating.
41
+ 26. User: I am scared of the future.
42
+ 27. User: I trust my gut feeling more than numbers.
43
+ 28. User: I work better alone.
44
+ 29. User: I hate losing games.
45
+ 30. User: I want to know my purpose in life.
46
  """
47
 
48
+ # --- HELPER FUNCTION ---
49
+ def clean_text_for_audio(text):
50
+ """
51
+ This removes text in brackets like (sighs) or *laughs*.
52
+ We do this so the voice robot does not read them out loud.
53
+ """
54
+ clean = re.sub(r'[\(\[\*].*?[\)\]\*]', '', text)
55
+ return clean.strip()
56
+
57
+ # --- PART 1: MEMORY EXTRACTOR ---
58
  def extract_memory(chat_logs, hf_token):
59
  if not hf_token:
60
+ return "Error: Please paste your Hugging Face Token."
61
 
62
  client = InferenceClient(token=hf_token)
63
 
64
+ # Instructions for the AI to find personality traits
65
  system_prompt = """
66
+ Read the chat logs. Create a simple User Profile in JSON format.
67
+
68
+ Find these 3 things:
69
+ 1. "traits": Is the user Introverted? Organized? Anxious?
70
+ 2. "values": Do they care about Logic? Peace? Winning?
71
+ 3. "struggles": Do they procrastinate? Have social anxiety?
72
+
73
+ Return ONLY valid JSON.
74
  """
75
 
76
  messages = [
 
82
  response = client.chat_completion(
83
  model=EXTRACTOR_MODEL,
84
  messages=messages,
85
+ max_tokens=500,
86
  temperature=0.1
87
  )
88
 
89
+ # Clean up the answer to get just the JSON data
90
  text = response.choices[0].message.content.strip()
91
+ if "```" in text:
 
 
92
  text = text.replace("```json", "").replace("```", "")
93
+
94
  start = text.find("{")
95
  end = text.rfind("}") + 1
96
  return json.dumps(json.loads(text[start:end]), indent=2)
97
  except Exception as e:
98
  return json.dumps({"error": str(e)}, indent=2)
99
 
100
+ # --- PART 2: PERSONALITY & VOICE ---
101
  async def generate_response_and_audio(message, memory_json, persona, hf_token):
102
  if not hf_token:
103
+ return "Error: Please paste your Hugging Face Token.", None
104
 
105
  client = InferenceClient(token=hf_token)
106
 
107
+ # Load the user's memory profile
108
  try:
109
  memory = json.loads(memory_json)
110
  except:
111
  memory = {}
112
 
113
+ # Define the 3 Personalities
114
  prompts = {
115
+ "Calm Mentor": "Role: Wise Teacher. Tone: Calm, slow, patient. Advice: Focus on long-term growth.",
116
+ "Witty Friend": "Role: Best Friend. Tone: Funny, fast, sarcastic. Advice: Make jokes and be relatable.",
117
+ "Therapist": "Role: Counselor. Tone: Soft, kind, gentle. Advice: Validate their feelings and ask how they feel."
118
  }
119
 
120
+ # Add User Memory to the AI's brain
121
  context = f"""
122
+ ABOUT THE USER:
123
+ - Personality: {memory.get('traits', 'Unknown')}
124
  - Values: {memory.get('values', 'Unknown')}
125
+ - Problems: {memory.get('struggles', 'Unknown')}
126
  """
127
 
128
  messages = [
 
131
  ]
132
 
133
  try:
134
+ # Step A: Write the text response
135
  res = client.chat_completion(
136
  model=PERSONALITY_MODEL,
137
  messages=messages,
 
140
  )
141
  text_reply = res.choices[0].message.content
142
 
143
+ # Step B: Clean text for the voice engine
144
+ spoken_text = clean_text_for_audio(text_reply)
145
+
146
+ # Step C: Pick a voice based on the persona
147
  voice_map = {
148
+ "Calm Mentor": "en-US-ChristopherNeural", # Deep Male Voice
149
+ "Witty Friend": "en-US-EricNeural", # Fast Male Voice
150
+ "Therapist": "en-US-AvaNeural" # Soft Female Voice
151
  }
152
 
153
+ # Step D: Create the audio file
154
  output_file = "response.mp3"
155
+ communicate = edge_tts.Communicate(spoken_text, voice_map.get(persona, "en-US-AriaNeural"))
156
  await communicate.save(output_file)
157
 
158
  return text_reply, output_file
159
 
160
  except Exception as e:
161
+ return f"Error: {str(e)}", None
162
 
163
+ # Wrapper to make the async code work with Gradio
164
  def process_interaction(message, memory_json, persona, hf_token):
165
  return asyncio.run(generate_response_and_audio(message, memory_json, persona, hf_token))
166
 
167
+ # --- PART 3: THE USER INTERFACE ---
168
  with gr.Blocks(title="Personality Engine") as demo:
169
+ gr.Markdown("See how Memory + Tone changes the AI response.")
170
 
171
  with gr.Row():
172
+ token_input = gr.Textbox(label="Hugging Face Token (Required)", type="password")
173
 
174
  with gr.Row():
175
+ # Column 1: Analyze the User
176
+ with gr.Column():
177
+ gr.Markdown("### 1. Analyze User History")
178
+ logs_input = gr.Textbox(label="Chat History", value=DEFAULT_LOGS, lines=10)
179
+ extract_btn = gr.Button("Create Profile")
180
+ memory_output = gr.Code(label="Result (JSON)", language="json")
181
 
182
  extract_btn.click(extract_memory, inputs=[logs_input, token_input], outputs=memory_output)
183
 
184
+ # Column 2: Chat with Persona
185
+ with gr.Column():
186
+ gr.Markdown("### 2. Chat with Agent")
187
+ user_msg = gr.Textbox(label="Your Message", value="I am scared about the future.")
188
  persona_select = gr.Radio(
189
+ ["Calm Mentor", "Witty Friend", "Therapist"],
190
+ label="Choose Personality",
191
  value="Calm Mentor"
192
  )
193
+ generate_btn = gr.Button("Get Answer")
194
 
195
+ text_output = gr.Markdown(label="Text Answer")
196
+ audio_output = gr.Audio(label="Voice Answer")
 
197
 
198
  generate_btn.click(
199
  process_interaction,