ibrhmyi commited on
Commit
493e7b4
·
verified ·
1 Parent(s): 17c68d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -104
app.py CHANGED
@@ -1,30 +1,14 @@
1
  import gradio as gr
2
  import google.generativeai as genai
3
- import os
4
  import json
 
5
 
6
  # 🔐 Configure Gemini API
7
  genai.configure(api_key="AIzaSyBzxuqigEr7TXXADHFxZ3hDKPGs1ENi92E")
8
 
9
  model = genai.GenerativeModel("gemini-2.0-flash")
10
 
11
- # 🎯 Function to generate challenge
12
- def generate_challenge(spiceLevel, timesPerDay, keywords, longDistanceMode, priorTitles, priorDescs):
13
- prior_challenges = [
14
- {"title": t, "description": d}
15
- for t, d in zip(priorTitles.split(";"), priorDescs.split(";"))
16
- if t.strip() and d.strip()
17
- ]
18
-
19
- payload = {
20
- "spiceLevel": int(spiceLevel),
21
- "timesPerDay": int(timesPerDay),
22
- "keywords": [k.strip() for k in keywords.split(",") if k.strip()],
23
- "longDistanceMode": bool(longDistanceMode),
24
- "priorChallenges": prior_challenges
25
- }
26
-
27
- # Full system prompt
28
  SYSTEM_PROMPT = """
29
  [Task Background]
30
  You are the AI challenge generator for the relationship app “Spicer.”
@@ -41,62 +25,41 @@ You will receive a JSON request containing:
41
  {"title": string, "description": string}
42
  ]
43
  }
44
- Use this information to understand the users’ preferences, avoid repetition, and generate one new, original challenge idea. Each challenge must feel creative, context-aware, and match the couple’s kinkiness level and relationship mode (physical or long-distance). Challenges can be bold but always have a sense of randomness and unexpectancy, so even when the previous challange was something hard and extreme like public sex for example the next chalange can be something very easy and unexpectedly boring like play clahroyale together, You may sometimes choose to be inspired by the keywords and always be creative and dont be afraid to be absurd like "make out while watching Gordon Ramsay cook" stuff like this makes it fun.
45
-
46
- [Challenge Design Rules]
47
- 1. **Tone by Spice Level**
48
- - Level 1 (Soft): Romantic, playful, trust-building, or creative, usually for new couples (e.g., “Pocky game,” “draw each other,” “truth or dare with body contact”, "lick the same ice cream together" ).
49
- - Level 2 (Flirty): Physical teasing, affectionate dares, or sensual moments (e.g., “give each other a hickey”, “slap each other”,"say 3 places you want to fuck your partner", "kiss passionately for 10 minutes").
50
- - Level 3 (Extreme): Bold, adventurous, or risqué challenges designed for couples who enjoy intense intimacy (e.g., “public sex,” “roleplay,” “sexual photo tasks”).
51
-
52
- 2. **Long-Distance Mode**
53
- - If `"longDistanceMode": true`, all ideas must work over video, voice, or messaging.
54
- - Examples: video dares, creative roleplay through calls, shared sexual experiences online like phone sex and watching porn together.
55
-
56
- 3. **Frequency & Timing**
57
- - `"timesPerDay"` determines how often new challenges appear:
58
- - 1 → once every 24h
59
- - 2 → every 12h
60
- - 3 → every 8h
61
- The challenge text should implicitly reflect the intensity suitable for this pacing.
62
-
63
- 4. **History Filtering**
64
- - Do NOT repeat or closely resemble any challenge in `"priorChallenges"`.
65
- - You may use similar concepts if a challenge was previously *missed*, but the description must be fresh and distinct.
66
-
67
- 5. **Keyword Influence**
68
- - The provided `"keywords"` should flavor the challenge 50% of the time.
69
- Example: “art” → creative drawing or photography task.
70
- “outdoors” → challenge outside or in nature.
71
- “food” → sensory, taste-based, or cooking tasks.
72
- "Minecraft" → sensual actions while playing Minecraft
73
- "skirts" → challenges involving lifting skirts
74
 
75
  [Output Format]
76
- Return a single, valid JSON object strictly in this format:
77
  {
78
- "title": "short creative name for the challenge like the name of an episode of a TV series",
79
- "description": "one-sentence challenge instruction clearly explaining what to do"
80
  }
81
  """
82
 
 
83
  def generate_challenge(spice_level, times_per_day, keywords, long_distance, prior_challenges):
84
  try:
85
- # Create input JSON
 
 
 
 
 
 
86
  user_json = {
87
- "spiceLevel": spice_level,
88
- "timesPerDay": times_per_day,
89
  "keywords": [k.strip() for k in keywords.split(",") if k.strip()],
90
- "longDistanceMode": long_distance,
91
- "priorChallenges": [{"title": t, "description": d} for t, d in prior_challenges if t or d]
92
  }
93
 
94
- response = client.models.generate_content(
95
- model="gemini-2.5-flash",
96
- contents=f"{SYSTEM_PROMPT}\n\nInput:\n{json.dumps(user_json, indent=2)}"
97
  )
98
-
99
  text = response.text.strip()
 
 
100
  try:
101
  data = json.loads(text[text.find("{"):text.rfind("}") + 1])
102
  title = data.get("title", "Untitled Challenge")
@@ -108,14 +71,21 @@ def generate_challenge(spice_level, times_per_day, keywords, long_distance, prio
108
  except Exception as e:
109
  return f"❌ Error: {str(e)}"
110
 
111
- # Define sexy theme
112
- theme = gr.themes.Soft(
113
- primary_hue="pink",
114
- secondary_hue="rose",
115
- neutral_hue="gray"
116
- )
117
 
118
- # Gradio UI Layout
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  with gr.Blocks(theme=theme) as demo:
120
  gr.Markdown(
121
  """
@@ -126,38 +96,18 @@ with gr.Blocks(theme=theme) as demo:
126
  )
127
 
128
  with gr.Row():
129
- spice_level = gr.Radio(
130
- [1, 2, 3],
131
- label="🔥 Spice Level",
132
- info="1 = Soft, 2 = Flirty, 3 = Extreme",
133
- value=1,
134
- interactive=True
135
- )
136
- times_per_day = gr.Radio(
137
- [1, 2, 3],
138
- label="⏰ Times Per Day",
139
- info="How often you want new challenges",
140
- value=1,
141
- interactive=True
142
- )
143
 
144
  with gr.Row():
145
- keywords = gr.Textbox(
146
- placeholder="art, food, outdoors...",
147
- label="🎯 Keywords",
148
- info="Add themes or vibes that inspire your challenges"
149
- )
150
- long_distance = gr.Checkbox(
151
- label="💌 Long-Distance Mode",
152
- info="Enable for couples not physically together"
153
- )
154
 
155
  prior_challenges = gr.Dataframe(
156
  headers=["title", "description"],
157
- label="🕓 Previous Challenges (Optional)",
158
  row_count=2,
159
- col_count=2,
160
- wrap=True
161
  )
162
 
163
  with gr.Row():
@@ -166,11 +116,6 @@ with gr.Blocks(theme=theme) as demo:
166
 
167
  output = gr.Markdown("")
168
 
169
- def random_inputs():
170
- return random.choice([1, 2, 3]), random.choice([1, 2, 3]), random.choice([
171
- "art, dance, roleplay", "food, cooking, sensual", "outdoors, park, sunset", "gaming, minecraft, fun"
172
- ]), random.choice([True, False]), [["", ""]]
173
-
174
  generate_btn.click(
175
  fn=generate_challenge,
176
  inputs=[spice_level, times_per_day, keywords, long_distance, prior_challenges],
@@ -183,12 +128,7 @@ with gr.Blocks(theme=theme) as demo:
183
  outputs=output
184
  )
185
 
186
- gr.Markdown(
187
- """
188
- <hr>
189
- <p style='text-align:center; font-size:14px; color:#999;'>Made with ❤️ by Spicer</p>
190
- """
191
- )
192
 
193
  if __name__ == "__main__":
194
  demo.launch()
 
1
  import gradio as gr
2
  import google.generativeai as genai
 
3
  import json
4
+ import random
5
 
6
  # 🔐 Configure Gemini API
7
  genai.configure(api_key="AIzaSyBzxuqigEr7TXXADHFxZ3hDKPGs1ENi92E")
8
 
9
  model = genai.GenerativeModel("gemini-2.0-flash")
10
 
11
+ # 🎯 System prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  SYSTEM_PROMPT = """
13
  [Task Background]
14
  You are the AI challenge generator for the relationship app “Spicer.”
 
25
  {"title": string, "description": string}
26
  ]
27
  }
28
+ Use this information to understand the users’ preferences, avoid repetition, and generate one new, original challenge idea. Each challenge must feel creative, context-aware, and match the couple’s kinkiness level and relationship mode (physical or long-distance).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  [Output Format]
31
+ Return JSON like:
32
  {
33
+ "title": "short creative name",
34
+ "description": "one-sentence challenge instruction"
35
  }
36
  """
37
 
38
+ # 🎨 Generator function
39
  def generate_challenge(spice_level, times_per_day, keywords, long_distance, prior_challenges):
40
  try:
41
+ # Safely build prior challenges list
42
+ prior_list = []
43
+ for row in prior_challenges:
44
+ if isinstance(row, list) and len(row) >= 2 and (row[0] or row[1]):
45
+ prior_list.append({"title": row[0], "description": row[1]})
46
+
47
+ # Create payload
48
  user_json = {
49
+ "spiceLevel": int(spice_level),
50
+ "timesPerDay": int(times_per_day),
51
  "keywords": [k.strip() for k in keywords.split(",") if k.strip()],
52
+ "longDistanceMode": bool(long_distance),
53
+ "priorChallenges": prior_list
54
  }
55
 
56
+ # Generate content
57
+ response = model.generate_content(
58
+ f"{SYSTEM_PROMPT}\n\nInput:\n{json.dumps(user_json, indent=2)}"
59
  )
 
60
  text = response.text.strip()
61
+
62
+ # Try to extract JSON
63
  try:
64
  data = json.loads(text[text.find("{"):text.rfind("}") + 1])
65
  title = data.get("title", "Untitled Challenge")
 
71
  except Exception as e:
72
  return f"❌ Error: {str(e)}"
73
 
 
 
 
 
 
 
74
 
75
+ # 💅 Gradio theme
76
+ theme = gr.themes.Soft(primary_hue="pink", secondary_hue="rose", neutral_hue="gray")
77
+
78
+ # 🧠 Random input generator for “Surprise Me”
79
+ def random_inputs():
80
+ return (
81
+ random.choice([1, 2, 3]),
82
+ random.choice([1, 2, 3]),
83
+ random.choice(["art, dance", "food, cooking", "outdoors, sunset", "gaming, minecraft"]),
84
+ random.choice([True, False]),
85
+ [["", ""]]
86
+ )
87
+
88
+ # 🖼️ Gradio UI
89
  with gr.Blocks(theme=theme) as demo:
90
  gr.Markdown(
91
  """
 
96
  )
97
 
98
  with gr.Row():
99
+ spice_level = gr.Radio([1, 2, 3], label="🔥 Spice Level", value=1)
100
+ times_per_day = gr.Radio([1, 2, 3], label="⏰ Times per Day", value=1)
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  with gr.Row():
103
+ keywords = gr.Textbox(placeholder="art, food, outdoors...", label="🎯 Keywords")
104
+ long_distance = gr.Checkbox(label="💌 Long Distance Mode")
 
 
 
 
 
 
 
105
 
106
  prior_challenges = gr.Dataframe(
107
  headers=["title", "description"],
108
+ label="🕓 Previous Challenges (optional)",
109
  row_count=2,
110
+ col_count=2
 
111
  )
112
 
113
  with gr.Row():
 
116
 
117
  output = gr.Markdown("")
118
 
 
 
 
 
 
119
  generate_btn.click(
120
  fn=generate_challenge,
121
  inputs=[spice_level, times_per_day, keywords, long_distance, prior_challenges],
 
128
  outputs=output
129
  )
130
 
131
+ gr.Markdown("<hr><p style='text-align:center; color:#aaa;'>Made with ❤️ by Spicer</p>")
 
 
 
 
 
132
 
133
  if __name__ == "__main__":
134
  demo.launch()