ak0601 commited on
Commit
e386167
Β·
verified Β·
1 Parent(s): fcc4ed8

Upload 6 files

Browse files
src/chat.txt ADDED
The diff for this file is too large to render. See raw diff
 
src/extract_features.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import random
3
+ from collections import Counter, defaultdict
4
+
5
+ def parse_chat(file_path):
6
+ pattern = r"(\d{1,2}/\d{1,2}/\d{2,4}), (\d{1,2}:\d{2}) - ([^:]+): (.*)"
7
+ messages = []
8
+
9
+ with open(file_path, "r", encoding="utf-8") as f:
10
+ for line in f:
11
+ match = re.match(pattern, line)
12
+ if match:
13
+ date, time, sender, text = match.groups()
14
+
15
+ # Normalize names
16
+ if sender == "ak":
17
+ sender = "Aman"
18
+ elif sender == "Sarah con H":
19
+ sender = "Sarah"
20
+
21
+ messages.append({
22
+ "date": date,
23
+ "time": time,
24
+ "sender": sender,
25
+ "text": text.strip()
26
+ })
27
+ return messages
28
+
29
+
30
+ def extract_inside_jokes(messages):
31
+ funny_candidates = []
32
+ cute_candidates = []
33
+ memory_candidates = []
34
+ phrase_counter = Counter()
35
+
36
+ funny_keywords = ["lol", "πŸ˜‚", "🀣", "lmao", "funny", "haha", "hehe","hahaha"]
37
+ cute_keywords = ["miss", "thank", "sweet", "cute", "proud", "happy","aww","glad"]
38
+
39
+ for msg in messages:
40
+ text = msg["text"].lower()
41
+
42
+ # Funny moments
43
+ if any(k in text for k in funny_keywords):
44
+ funny_candidates.append(msg["text"])
45
+
46
+ # Cute/emotional moments
47
+ if any(k in text for k in cute_keywords):
48
+ cute_candidates.append(msg["text"])
49
+
50
+ # Memorable random moments
51
+ if len(msg["text"].split()) > 4: # skip too short
52
+ memory_candidates.append(msg["text"])
53
+
54
+ # Count repeated words
55
+ phrase_counter.update(text.split())
56
+
57
+ top_words = [w for w, c in phrase_counter.most_common(40)]
58
+
59
+ return {
60
+ "funny": funny_candidates,
61
+ "cute": cute_candidates,
62
+ "memories": memory_candidates,
63
+ "top_words": top_words
64
+ }
65
+
66
+
67
+ def random_memory(messages):
68
+ """Returns a random meaningful moment."""
69
+ long_messages = [m["text"] for m in messages if len(m["text"]) > 10]
70
+ if not long_messages:
71
+ return "One of your old conversations ❀️"
72
+ return random.choice(long_messages)
src/generate_jokes.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import random
3
+ from openai import OpenAI
4
+ import os
5
+ from dotenv import load_dotenv
6
+ from extract_features import parse_chat, extract_inside_jokes, random_memory
7
+
8
+ # Load environment variables
9
+ load_dotenv()
10
+
11
+ def generate_inside_jokes(count=3):
12
+ # Configure Groq API
13
+ client = OpenAI(
14
+ api_key=os.environ.get("GROQ_API_KEY"),
15
+ base_url="https://api.groq.com/openai/v1",
16
+ )
17
+
18
+ messages = parse_chat("chat.txt")
19
+ data = extract_inside_jokes(messages)
20
+
21
+ # meaningful memory for Sarah
22
+ random_real_memory = select_meaningful_memory(messages, client)
23
+
24
+ prompt = f"""
25
+ You are a comedian whoose task is to generate funny inside jokes for two best friends: Aman and Sarah.
26
+ They have a very close, playful, supportive and affectionate friendship.
27
+
28
+ Here is the context from their WhatsApp chats:
29
+
30
+ Funny lines they've said:
31
+ {json.dumps(data['funny'][:30], indent=2)}
32
+
33
+ Cute moments between them:
34
+ {json.dumps(data['cute'][:20], indent=2)}
35
+
36
+ Shared vocabulary & patterns:
37
+ {json.dumps(data['top_words'][:20], indent=2)}
38
+
39
+ One real memory to set the mood:
40
+ "{random_real_memory}"
41
+
42
+ Your Goal:
43
+ Generate {count} ORIGINAL inside jokes that sound exactly like something they would say to each other.
44
+ The jokes should be a mix of funny, teasing, and heartfelt(more of funny).
45
+
46
+ Guidelines:
47
+ 1. **Be Human**: Use casual language, slang (if fits their vibe), and natural phrasing. Avoid robotic or stiff sentence structures.
48
+ 2. **Show, Don't Tell**: Instead of saying "You are funny," say "Remember that time you tried to tell a joke and choked on water? Classic."
49
+ 3. **Mix Humor and Heart**: The best inside jokes often come from a place of love. "Fries before guys" is funny but also shows loyalty.
50
+ 4. **Use Context**: Reference their shared vocabulary or specific funny/cute moments provided above.
51
+ 5. **Be creative**: The best inside jokes often come from a place of love. "Fries before guys" is funny but also shows loyalty.
52
+ 6. Try to make atleast one line jokes
53
+
54
+
55
+ Output Format:
56
+
57
+ INSIDE JOKES:
58
+ 1. [Joke/Phrase]
59
+ 2. [Joke/Phrase]
60
+ ...
61
+
62
+ MEMORY FOR SARAH:
63
+ "{random_real_memory}"
64
+ """
65
+
66
+ response = client.chat.completions.create(
67
+ model="llama-3.3-70b-versatile",
68
+ messages=[
69
+ {"role": "user", "content": prompt}
70
+ ]
71
+ )
72
+
73
+ return response.choices[0].message.content
74
+
75
+
76
+ def select_meaningful_memory(messages, client):
77
+ """Selects a meaningful memory using LLM."""
78
+ # Filter for potentially interesting messages to save tokens
79
+ candidates = [m["text"] for m in messages if len(m["text"]) > 15]
80
+ if not candidates:
81
+ return "Remember that time we couldn't stop laughing? Good times."
82
+
83
+ # Sample if too many
84
+ if len(candidates) > 50:
85
+ candidates = random.sample(candidates, 50)
86
+
87
+ candidates_str = "\n".join([f"- {c}" for c in candidates])
88
+
89
+ prompt = f"""
90
+ Here are some excerpts from a chat history between two best friends, Aman and Sarah:
91
+
92
+ {candidates_str}
93
+
94
+ Your Task:
95
+ Select ONE specific message from this list that represents a "meaningful memory".
96
+ Criteria for "meaningful":
97
+ - A plan to meet (e.g., "Let's go to that movie", "Dinner tonight?")
98
+ - A sweet/emotional moment
99
+ - An inside joke or funny observation
100
+ - NOT just "Hello" or "Okay"
101
+
102
+ Return ONLY the exact text of the selected message. Nothing else.
103
+ """
104
+
105
+ try:
106
+ response = client.chat.completions.create(
107
+ model="llama-3.3-70b-versatile",
108
+ messages=[{"role": "user", "content": prompt}]
109
+ )
110
+ return response.choices[0].message.content.strip()
111
+ except Exception:
112
+ return random.choice(candidates)
113
+
114
+
115
+ def generate_motivation():
116
+ # Configure Groq API
117
+ client = OpenAI(
118
+ api_key=os.environ.get("GROQ_API_KEY"),
119
+ base_url="https://api.groq.com/openai/v1",
120
+ )
121
+
122
+ try:
123
+ with open("sarah_about.txt", "r", encoding="utf-8") as f:
124
+ about_sarah = f.read()
125
+ except FileNotFoundError:
126
+ return "You are stronger than you know. Keep shining! ✨"
127
+
128
+ prompt = f"""
129
+ You are a supportive, wise, and kind friend.
130
+ Read this context about Sarah:
131
+ "{about_sarah}"
132
+
133
+ Your Task:
134
+ Generate a short, powerful, and personalized motivational thought for Sarah.
135
+ It should directly address her struggles (past burdens, insecurity) but focus on her strengths (kindness, resilience, future in Air Force).
136
+ Make it sound like it's coming from a place of deep understanding and belief in her.
137
+ Keep it under 2 sentences.
138
+
139
+ Output ONLY the motivational message.
140
+ """
141
+
142
+ response = client.chat.completions.create(
143
+ model="llama-3.3-70b-versatile",
144
+ messages=[
145
+ {"role": "user", "content": prompt}
146
+ ]
147
+ )
148
+
149
+ return response.choices[0].message.content
150
+
151
+
152
+ if __name__ == "__main__":
153
+ print(generate_inside_jokes(5))
src/requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ openai==2.9.0
2
+ python-dotenv==1.2.1
3
+ streamlit==1.52.1
src/sarah_about.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Sarah is a kind hearted, mature and a beautiful person.
2
+ She went through a lot of hardships in her life but she never lost her smile.
3
+ She is a true inspiration to everyone around her in the past.
4
+ Like all her life she thinks that she did some mistakes which cannot be forgiven that's why
5
+ she always felt insecure with her relationship with her boyfriend.
6
+ She has a very pure heart and is very straightforward with her thoughts and actions.
7
+ She wants to join US air force and finish her education, currently she is doing bachelors in
8
+ pshycology.
9
+ Though her boyfriend had also made mistakes but he didn't accept that and puts all the
10
+ blame on her.
11
+ She is kind of carrying her past burden with her in the present.
12
+ She has a friend Aman who never judges her and will always stand by her in times of need as a friend.
13
+ She is one the most brave and courageous person I know.
14
+
src/streamlit_app.py CHANGED
@@ -1,40 +1,133 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
5
-
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import random
4
+ from generate_jokes import generate_inside_jokes, generate_motivation
5
+
6
+ # Page Config
7
+ st.set_page_config(
8
+ page_title="Memory Forever",
9
+ page_icon="πŸ’›",
10
+ layout="wide"
11
+ )
12
+
13
+ # Custom CSS
14
+ st.markdown("""
15
+ <style>
16
+ .main {
17
+ background-color: #f0f2f6;
18
+ }
19
+ .stButton>button {
20
+ width: 100%;
21
+ background-color: #ff4b4b;
22
+ color: white;
23
+ border-radius: 10px;
24
+ height: 50px;
25
+ font-size: 20px;
26
+ }
27
+ .joke-card {
28
+ background-color: white;
29
+ color: black;
30
+ padding: 20px;
31
+ border-radius: 10px;
32
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
33
+ margin-bottom: 15px;
34
+ border-left: 5px solid #ff4b4b;
35
+ }
36
+ .memory-card {
37
+ background-color: #fff3cd;
38
+ padding: 15px;
39
+ border-radius: 10px;
40
+ border: 1px solid #ffeeba;
41
+ color: #856404;
42
+ font-style: italic;
43
+ }
44
+ .motivation-card {
45
+ background-color: #d4edda;
46
+ color: #155724;
47
+ padding: 20px;
48
+ border-radius: 10px;
49
+ border-left: 5px solid #28a745;
50
+ margin-top: 20px;
51
+ font-weight: bold;
52
+ }
53
+ h1 {
54
+ color: #ff4b4b;
55
+ text-align: center;
56
+ font-family: 'Helvetica', sans-serif;
57
+ }
58
+ </style>
59
+ """, unsafe_allow_html=True)
60
+
61
+ # Header
62
+ st.title("πŸ’› Memory Forever πŸ‘©β€βœˆοΈ")
63
+ st.markdown("---")
64
+
65
+ # Layout: 2 Columns
66
+ col1, col2 = st.columns([1, 2])
67
+
68
+ with col1:
69
+ st.header("πŸ“Έ Past Gallery")
70
+
71
+ # Load images from 'sarah' directory
72
+ image_dir = "sarah"
73
+ if os.path.exists(image_dir):
74
+ images = [f for f in os.listdir(image_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif'))]
75
+
76
+ if images:
77
+ # Display a random image or a grid
78
+ selected_image = random.choice(images)
79
+ st.image(os.path.join(image_dir, selected_image), caption="Classic Sarah Moment", use_container_width=True)
80
+
81
+ # Optional: Show more images in an expander
82
+ with st.expander("See more photos"):
83
+ for img in images:
84
+ st.image(os.path.join(image_dir, img), use_container_width=True)
85
+ else:
86
+ st.info("No images found in 'sarah' folder. Add some photos to see them here!")
87
+ else:
88
+ st.warning("Folder 'sarah' not found. Please create it and add images.")
89
+
90
+ st.markdown("---")
91
+ st.subheader("βš™οΈ Settings")
92
+ count = st.slider("How many jokes?", 1, 10, 3)
93
+
94
+ st.markdown("---")
95
+ st.subheader("πŸ’ͺ Daily Boost")
96
+ if st.button("Need a quick motivation ✨"):
97
+ with st.spinner("Finding the right words..."):
98
+ motivation = generate_motivation()
99
+ st.markdown(f'<div class="motivation-card">{motivation}</div>', unsafe_allow_html=True)
100
+
101
+ with col2:
102
+ st.header("✨ Memory jokes fusion")
103
+
104
+ if st.button("Generate 🎲"):
105
+ with st.spinner("Cooking up some humor..."):
106
+ try:
107
+ jokes_text = generate_inside_jokes(count)
108
+
109
+ # Parse the output to separate jokes and memory
110
+ if "MEMORY FOR SARAH:" in jokes_text:
111
+ parts = jokes_text.split("MEMORY FOR SARAH:")
112
+ jokes_section = parts[0].replace("INSIDE JOKES:", "").strip()
113
+ memory_section = parts[1].strip().strip('"')
114
+ else:
115
+ jokes_section = jokes_text
116
+ memory_section = "Remember that time..."
117
+
118
+ # Display Jokes
119
+ st.markdown("### 🎭 Inside Jokes")
120
+ for line in jokes_section.split('\n'):
121
+ if line.strip():
122
+ st.markdown(f'<div class="joke-card">{line.strip()}</div>', unsafe_allow_html=True)
123
+
124
+ # Display Memory
125
+ st.markdown("### πŸ’Œ A Memory to Cherish")
126
+ st.markdown(f'<div class="memory-card">"{memory_section}"</div>', unsafe_allow_html=True)
127
+
128
+ except Exception as e:
129
+ st.error(f"Oof! Something went wrong: {e}")
130
+
131
+ # Footer
132
+ st.markdown("---")
133
+ st.markdown("<div style='text-align: center; color: gray;'>Made with πŸ’– by Aman</div>", unsafe_allow_html=True)