tarujain8's picture
feat: implement backend analysis agents and frontend utility helpers for relationship evaluation
6377526
Raw
History Blame Contribute Delete
11.6 kB
import re
import requests
API_URL = "http://127.0.0.1:8000/analyze"
MAX_FILES = 5
def parse_score_value(raw_score):
match = re.search(r"\d+(?:\.\d+)?", str(raw_score))
return float(match.group()) if match else None
def clean_text(value, fallback="Not available yet."):
text = str(value).strip() if value is not None else ""
return text if text else fallback
def clean_list(value):
if isinstance(value, list):
return [str(item).strip() for item in value if str(item).strip()]
if value is None:
return []
text = str(value).strip()
return [text] if text else []
def count_files(uploaded_files):
return len(uploaded_files) if uploaded_files else 0
def normalize_files(uploaded_files):
if not uploaded_files:
return []
return list(uploaded_files[:MAX_FILES])
def interest_to_percent(value):
text = str(value or "").lower()
mapping = {
"very high": 92,
"high": 82,
"medium": 58,
"mixed": 46,
"low": 28,
"very low": 14,
}
for key, score in mapping.items():
if key in text:
return score
return 50
def get_emotional_signal(score_value):
if score_value is None:
return (
"AI signal",
"The emotional pattern is still forming."
)
if score_value >= 80:
return (
"Deep resonance",
"The connection reads warm, mutual, and emotionally available."
)
if score_value >= 60:
return (
"Promising energy",
"There is meaningful interest here, but clarity still matters."
)
if score_value >= 40:
return (
"Mixed signals",
"The attraction may be real, but the emotional consistency is uneven."
)
return (
"Guarded connection",
"Protect your energy and look for stronger reciprocity before investing more."
)
def analyze_payload(
chat,
feelings,
uploaded_files,
user_perspective="",
emotional_goal="",
conversation_consistency=""
):
selected_files = normalize_files(uploaded_files)
files_payload = []
for file in selected_files:
try:
file.seek(0)
files_payload.append(
(
"files",
(
file.name,
file.read(),
file.type or "image/png"
)
)
)
except Exception as e:
print("FILE ERROR:", e)
response = requests.post(
API_URL,
data={
"chat": chat,
"feelings": feelings,
"user_perspective": user_perspective,
"emotional_goal": emotional_goal,
"conversation_consistency": conversation_consistency,
},
files=files_payload,
timeout=300,
)
print("STATUS CODE:", response.status_code)
print("RESPONSE:", response.text)
response.raise_for_status()
return response.json()
def detect_perspective_payload(
chat,
feelings,
uploaded_files
):
selected_files = normalize_files(uploaded_files)
files_payload = []
for file in selected_files:
try:
file.seek(0)
files_payload.append(
(
"files",
(
file.name,
file.read(),
file.type or "image/png"
)
)
)
except Exception as e:
print("PERSPECTIVE FILE ERROR:", e)
url = "http://127.0.0.1:8000/detect_perspective"
response = requests.post(
url,
data={
"chat": chat,
"feelings": feelings,
},
files=files_payload,
timeout=300,
)
print("PERSPECTIVE STATUS:", response.status_code)
print("PERSPECTIVE RESPONSE:", response.text)
response.raise_for_status()
return response.json()
def build_people_cards(analysis, feelings):
analyst = analysis.get("analyst", {})
psychology = analysis.get("psychology", {})
interest_level = clean_text(
analyst.get("interest_level"),
"Unclear"
)
emotional_tone = clean_text(
analyst.get("emotional_tone"),
"Unreadable"
)
partner_intent = clean_text(
psychology.get("partner_intent"),
"Unclear intent"
)
user_intent = clean_text(
psychology.get("user_intent"),
"Clarifying feelings"
)
feelings_text = f"{feelings} {user_intent}".lower()
partner_text = (
f"{interest_level} "
f"{emotional_tone} "
f"{partner_intent}"
).lower()
if any(word in feelings_text for word in [
"break up",
"breakup",
"leave",
"dont love",
"don't love",
"end it",
"distance"
]):
you = {
"label": "You",
"emoji": "πŸ’”",
"title": "Ready to step back",
"description": (
"Your side reads emotionally detached "
"and focused on ending this respectfully."
),
"percent": 90,
"meter_label": "Clarity",
}
elif any(word in feelings_text for word in [
"confused",
"unsure",
"mixed",
"idk"
]):
you = {
"label": "You",
"emoji": "🫧",
"title": "Still sorting feelings",
"description": (
"You sound uncertain and are looking "
"for emotional clarity before acting."
),
"percent": 58,
"meter_label": "Certainty",
}
else:
you = {
"label": "You",
"emoji": "🩷",
"title": clean_text(
user_intent,
"Emotionally engaged"
),
"description": (
"Your side still sounds invested in "
"understanding what this connection means."
),
"percent": 72,
"meter_label": "Investment",
}
if any(word in partner_text for word in [
"cold",
"dry",
"avoidant",
"disinterest",
"ignoring",
"distance",
"very low",
"low"
]):
partner = {
"label": "Them",
"emoji": "🧊",
"title": "Emotionally cold",
"description": (
"Their side reads short, guarded, "
"and low-effort rather than warm or reassuring."
),
"percent": 24,
"meter_label": "Warmth",
}
elif any(word in partner_text for word in [
"mixed",
"unclear"
]):
partner = {
"label": "Them",
"emoji": "🀍",
"title": "Mixed energy",
"description": (
"They are giving some signal, but not enough "
"consistency to feel fully safe or clear."
),
"percent": 48,
"meter_label": "Warmth",
}
else:
partner = {
"label": "Them",
"emoji": "😍",
"title": clean_text(
interest_level,
"Interested"
),
"description": (
"Their tone and effort look more emotionally "
"open and invested."
),
"percent": interest_to_percent(
interest_level
),
"meter_label": "Warmth",
}
return [you, partner]
def build_story_cards(analysis):
analyst = analysis.get("analyst", {})
psychology = analysis.get("psychology", {})
strategy = analysis.get("strategy", {})
cards = [
{
"emoji": "πŸ”Ž",
"title": "Truth",
"body": clean_text(strategy.get("truth")),
"tone": "pink",
},
{
"emoji": "⚠️",
"title": "Risk",
"body": clean_text(strategy.get("warning")),
"tone": "amber",
},
{
"emoji": "🧭",
"title": "Best next move",
"body": clean_text(strategy.get("action_advice")),
"tone": "violet",
},
{
"emoji": "🫠",
"title": "Hidden meaning",
"body": clean_text(
analyst.get("hidden_meaning")
),
"tone": "rose",
},
{
"emoji": "🧠",
"title": "Psych dynamic",
"body": clean_text(
psychology.get("psychological_dynamic")
),
"tone": "indigo",
},
{
"emoji": "βš–οΈ",
"title": "Leverage",
"body": clean_text(strategy.get("leverage_assessment")),
"tone": "slate",
},
{
"emoji": "πŸ“ˆ",
"title": "Trajectory",
"body": clean_text(strategy.get("trajectory")),
"tone": "amber",
},
]
for reply in clean_list(
strategy.get("suggested_replies")
)[:3]:
cards.append(
{
"emoji": "πŸ’¬",
"title": "Suggested reply",
"body": reply,
"tone": "slate",
}
)
return cards
def build_key_insight_cards(analysis):
analyst = analysis.get("analyst", {})
strategy = analysis.get("strategy", {})
return [
{
"emoji": "⚠️",
"title": "Risk",
"body": clean_text(strategy.get("warning")),
"tone": "amber",
},
{
"emoji": "🫠",
"title": "Hidden meaning",
"body": clean_text(
analyst.get("hidden_meaning")
),
"tone": "rose",
},
{
"emoji": "🧭",
"title": "Best next step",
"body": clean_text(
strategy.get("action_advice")
),
"tone": "violet",
},
]
def default_swipe_profiles():
return [
{
"name": "Aarav",
"age": 26,
"bio": (
"Warm texter, quick replies, "
"values direct communication "
"and emotional consistency."
),
"compatibility": 72,
"emotional_availability": "Open but cautious",
"red_flags": (
"Can pull back if conversations "
"become unclear."
),
"communication_style": (
"Clear, affectionate, reassurance-seeking"
),
"theme": "rose",
"emoji": "😊",
},
{
"name": "Maya",
"age": 24,
"bio": (
"Playful energy, strong chemistry, "
"but can be inconsistent when overwhelmed."
),
"compatibility": 64,
"emotional_availability": "Mixed signals",
"red_flags": (
"Hot-cold rhythm and unclear follow-through."
),
"communication_style": (
"Flirty, reactive, emotionally uneven"
),
"theme": "violet",
"emoji": "πŸ₯°",
},
]