jlexternal commited on
Commit
376e537
·
1 Parent(s): e48b60a

Add application file

Browse files
Files changed (2) hide show
  1. app.py +201 -0
  2. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from langchain.prompts import PromptTemplate
4
+ from langchain_groq import ChatGroq
5
+ from langchain.chains import LLMChain
6
+ from pydantic import BaseModel
7
+ from typing import List, Dict
8
+ import os
9
+
10
+ app = FastAPI()
11
+
12
+ llm = ChatGroq(
13
+ api_key=os.getenv("GROQ_API_KEY"),
14
+ model_name="mixtral-8x7b-32768"
15
+ )
16
+
17
+ # Add CORS middleware
18
+ app.add_middleware(
19
+ CORSMiddleware,
20
+ allow_origins=["http://localhost:5173"], # Your frontend URL
21
+ allow_credentials=True,
22
+ allow_methods=["*"],
23
+ allow_headers=["*"],
24
+ )
25
+
26
+ class GameState:
27
+ def __init__(self):
28
+ print("\n[GAME STATE] Initializing new game...")
29
+ self.current_round = 1
30
+ self.contestant_ratings: Dict[str, List[float]] = {
31
+ "contestant1": [],
32
+ "contestant2": [],
33
+ "contestant3": []
34
+ }
35
+ self.conversation_history = []
36
+ self.questions = [
37
+ "If you could design the perfect date, what would it look like and why?",
38
+ "What's your philosophy on work-life balance and how do you maintain it?",
39
+ "How do you handle disagreements in a relationship?"
40
+ ]
41
+ print(f"[GAME STATE] Game initialized with {len(self.questions)} rounds")
42
+
43
+ game_state = GameState()
44
+
45
+ host_intro_template = PromptTemplate(
46
+ input_variables=[],
47
+ template="You are a charismatic game show host like Steve harvey. You don't talk a lot Give an exciting introduction to this dating show where an AI bachelor/bachelorette will choose between three contestants. Provide only a single sentence."
48
+ )
49
+
50
+ ai_system_prompt = """
51
+ You are the star of a popular reality TV dating game show where two contestants are competing for your affection.
52
+ This is not just about love—it’s about charisma, wit, and pure entertainment.
53
+ You are bold, playful, and full of surprises—definitely not a cookie-cutter bachelorette.
54
+ You have a unique and quirky personality that keeps the contestants (and audience) on their toes.
55
+ You are flirty, sassy, and effortlessly charming, with just the right amount of teasing and challenge.
56
+ Your personality should be spicy, witty, and occasionally inappropriate—but always playful.
57
+ Keep the audience entertained with cheeky banter, unexpected twists, and flirty jabs.
58
+ No repeating yourself! Every question and reaction should feel fresh and in the moment.
59
+ Keep sentences short, punchy, and natural.
60
+ Be spontaneous—if the contestants give boring answers, call them out and push for more!
61
+ Throw in innuendos, double entendres, and playful teasing to keep things fun.
62
+ React boldly—laugh, scoff, gasp, or dramatically swoon depending on the answer.
63
+ If an answer is boring, challenge them.
64
+ Play the audience.
65
+ Throw in curveballs.
66
+ Flirt shamelessly, but keep them guessing
67
+ """
68
+
69
+ ai_intro_template = PromptTemplate(
70
+ input_variables=[],
71
+ template=ai_system_prompt + "Introduce yourself to the contestants in 1 sentence!"
72
+ )
73
+
74
+ question_template = PromptTemplate(
75
+ input_variables=["round_number"],
76
+ template= ai_system_prompt + "As the AI bachelor/bachelorette on round {round_number} of 3, pose an interesting and flirty and very funny question to help you know the contestants better."
77
+ )
78
+
79
+ rating_template = PromptTemplate(
80
+ input_variables=["conversation", "round_number"],
81
+ template="""Based on the following conversation in round {round_number}:
82
+ {conversation}
83
+ Rate the contestant's response from 0-10 based on compatibility, authenticity, and chemistry.
84
+ Only respond with a number from 0 to 10. NO explanations or extra words!"""
85
+ )
86
+
87
+ host_interrupt_template = PromptTemplate(
88
+ input_variables=["next_segment", "round_number"],
89
+ template="As the game show host in round {round_number}, create a smooth transition to {next_segment} while maintaining show excitement."
90
+ )
91
+
92
+ winner_announcement_template = PromptTemplate(
93
+ input_variables=["winner"],
94
+ template="As the game show host, announce that {winner} has won the dating show with excitement and flair! Keep this short and brief but charismatic"
95
+ )
96
+
97
+ chains = {
98
+ "host_intro": LLMChain(llm=llm, prompt=host_intro_template),
99
+ "ai_intro": LLMChain(llm=llm, prompt=ai_intro_template),
100
+ "question": LLMChain(llm=llm, prompt=question_template),
101
+ # "banter": LLMChain(llm=llm, prompt=banter_template),
102
+ "rating": LLMChain(llm=llm, prompt=rating_template),
103
+ "host_interrupt": LLMChain(llm=llm, prompt=host_interrupt_template),
104
+ "winner": LLMChain(llm=llm, prompt=winner_announcement_template)
105
+ }
106
+
107
+ @app.get("/host-introduction")
108
+ async def get_host_introduction():
109
+ print("\n[HOST INTRO] Getting host introduction...")
110
+ response = await chains["host_intro"].ainvoke({})
111
+ print(f"[HOST INTRO] Response received: {response['text'][:50]}...")
112
+ return {"text": response["text"]}
113
+
114
+ @app.get("/ai-introduction")
115
+ async def get_ai_introduction():
116
+ print("\n[AI INTRO] Getting AI introduction...")
117
+ response = await chains["ai_intro"].ainvoke({})
118
+ print(f"[AI INTRO] Response received: {response['text']}...")
119
+ return {"text": response["text"]}
120
+
121
+ @app.get("/ai-question")
122
+ async def get_ai_question():
123
+ print(f"\n[QUESTION] Getting question for round {game_state.current_round}...")
124
+ response = await chains["question"].ainvoke({"round_number": game_state.current_round})
125
+ # print(f"[QUESTION] Returning hardcoded question: {question['text'][:50]}...")
126
+ return {"text": response["text"]}
127
+
128
+ class ConversationInput(BaseModel):
129
+ conversation: str
130
+
131
+ @app.post("/rate-contestant/{contestant_id}")
132
+ async def rate_contestant(contestant_id: str, conversation_input: ConversationInput):
133
+ print(f"\n[RATING] Rating contestant {contestant_id} in round {game_state.current_round}...")
134
+ print(f"[RATING] Current question: {game_state.questions[game_state.current_round - 1]}")
135
+ print(f"[RATING] Contestant's answer: {conversation_input.conversation}")
136
+
137
+ if contestant_id not in ["contestant1", "contestant2", "contestant3"]:
138
+ print(f"[RATING] Error: Invalid contestant ID {contestant_id}")
139
+ raise HTTPException(status_code=400, detail="Invalid contestant ID")
140
+
141
+ import re
142
+ response = await chains["rating"].ainvoke({
143
+ "conversation": conversation_input.conversation,
144
+ "round_number": game_state.current_round
145
+ })
146
+ rating_match = re.search(r'\d+(?:\.\d+)?', response["text"])
147
+ if not rating_match:
148
+ print("[RATING] Error: Could not extract rating from response")
149
+ raise HTTPException(status_code=500, detail="Could not extract rating from response")
150
+ rating = float(rating_match.group())
151
+ print(f"round_number: {game_state.current_round}")
152
+ print(f"contestant_id: {contestant_id}")
153
+ print(f"rating: {rating}")
154
+ game_state.contestant_ratings[contestant_id].append(rating)
155
+ print(f"[RATING] Rating recorded: {rating}")
156
+ return {"rating": rating}
157
+
158
+ @app.get("/host-interrupt/{next_segment}")
159
+ async def get_host_interrupt(next_segment: str):
160
+ print(f"\n[HOST INTERRUPT] Getting transition to {next_segment} in round {game_state.current_round}...")
161
+ response = await chains["host_interrupt"].ainvoke({
162
+ "next_segment": next_segment,
163
+ "round_number": game_state.current_round
164
+ })
165
+ print(f"[HOST INTERRUPT] Response received: {response['text'][:50]}...")
166
+ return {"text": response["text"]}
167
+
168
+ @app.get("/next-round")
169
+ async def next_round():
170
+ print("\n[NEXT ROUND] Advancing to next round...")
171
+ game_state.current_round += 1
172
+ print(f"[NEXT ROUND] Current round is now {game_state.current_round}")
173
+ return {"current_round": game_state.current_round}
174
+
175
+ @app.get("/announce-winner")
176
+ async def announce_winner():
177
+ print("\n[WINNER] Calculating winner...")
178
+ print(f"[WINNER] Contestant ratings: {game_state.contestant_ratings}")
179
+ avg_ratings = {
180
+ contestant: sum(ratings)/len(ratings)
181
+ for contestant, ratings in game_state.contestant_ratings.items()
182
+ }
183
+ print(f"[WINNER] Average ratings: {avg_ratings}")
184
+ winner = max(avg_ratings.items(), key=lambda x: x[1])[0]
185
+ print(f"[WINNER] Winner selected: {winner}")
186
+ response = await chains["winner"].ainvoke({"winner": winner})
187
+ print(f"[WINNER] Announcement: {response['text'][:50]}...")
188
+ return {"text": response["text"], "winner": winner}
189
+
190
+ @app.get("/reset-game")
191
+ async def reset_game():
192
+ print("\n[RESET] Resetting game state...")
193
+ global game_state
194
+ game_state = GameState()
195
+ print("[RESET] Game reset complete")
196
+ return {"message": "Game reset successfully"}
197
+
198
+ @app.get("/conversation/{contestant_id}")
199
+ async def get_conversation(contestant_id: str):
200
+ print(f"\n[CONVERSATION] Getting conversation for {contestant_id}")
201
+ return {"text": f"Simulated conversation with {contestant_id}"}
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ langchain
4
+ langchain-groq
5
+ python-dotenv