|
from flask import Flask, request, jsonify |
|
from flask_cors import CORS |
|
import logging |
|
from typing import List |
|
import math |
|
import faiss |
|
from langchain_openai import ChatOpenAI, OpenAIEmbeddings |
|
from langchain_experimental.generative_agents import GenerativeAgent, GenerativeAgentMemory |
|
from langchain.retrievers import TimeWeightedVectorStoreRetriever |
|
from langchain_community.vectorstores import FAISS |
|
from langchain_community.docstore.in_memory import InMemoryDocstore |
|
from datetime import datetime |
|
import os |
|
|
|
app = Flask(__name__) |
|
CORS(app) |
|
|
|
|
|
logging.basicConfig(level=logging.ERROR) |
|
LLM = ChatOpenAI(max_tokens=1500) |
|
|
|
def relevance_score_fn(score: float) -> float: |
|
return 1.0 - score / math.sqrt(2) |
|
|
|
def create_new_memory_retriever(): |
|
embeddings_model = OpenAIEmbeddings() |
|
embedding_size = 1536 |
|
index = faiss.IndexFlatL2(embedding_size) |
|
vectorstore = FAISS( |
|
embeddings_model.embed_query, |
|
index, |
|
InMemoryDocstore({}), |
|
{}, |
|
relevance_score_fn=relevance_score_fn, |
|
) |
|
return TimeWeightedVectorStoreRetriever( |
|
vectorstore=vectorstore, other_score_keys=["importance"], k=15 |
|
) |
|
|
|
PERSONALITY_TYPES = { |
|
"Romantic Idealist": "Seeks deep emotional connections and believes in soulmates", |
|
"Adventure Seeker": "Thrives on new experiences and loves to explore", |
|
"Intellectual Companion": "Values deep conversations and mental stimulation", |
|
"Social Butterfly": "Energized by social interactions and meeting new people", |
|
"Nurturing Partner": "Caring, supportive, and focused on emotional well-being", |
|
"Ambitious Go-Getter": "Driven by goals and seeks a partner with similar ambitions", |
|
"Creative Spirit": "Expresses themselves through art and values originality", |
|
"Steady Reliable": "Consistent, dependable, and values stability in relationships" |
|
} |
|
|
|
QUESTION_TEMPLATES = [ |
|
"What's your idea of a perfect date?", |
|
"How do you handle conflicts in a relationship?", |
|
"What's the most spontaneous thing you've ever done?", |
|
"How important is personal space to you in a relationship?", |
|
"What's a deal-breaker for you in a potential partner?", |
|
"How do you show affection to someone you care about?", |
|
"What role does humor play in your relationships?", |
|
"How do you balance your personal goals with a romantic relationship?", |
|
"What's the most important quality you look for in a partner?", |
|
"How do you envision your ideal future with a partner?" |
|
] |
|
|
|
class QuestionGeneratorAgent(GenerativeAgent): |
|
def __init__(self, name: str, age: int, traits: str): |
|
memory = GenerativeAgentMemory( |
|
llm=LLM, |
|
memory_retriever=create_new_memory_retriever(), |
|
verbose=False, |
|
reflection_threshold=5 |
|
) |
|
super().__init__(name=name, age=age, traits=traits, status="active", memory=memory, llm=LLM) |
|
|
|
def generate_question(self, previous_questions: List[str], previous_answers: List[str]) -> str: |
|
context = "\n".join([f"Q: {q}\nA: {a}" for q, a in zip(previous_questions, previous_answers)]) |
|
templates = "\n".join([f"- {template}" for template in QUESTION_TEMPLATES]) |
|
prompt = f"""As a dating app personality quiz, generate a new, interesting question based on the following context and question templates: |
|
|
|
Previous Questions and Answers: |
|
{context} |
|
|
|
Question Templates: |
|
{templates} |
|
|
|
Create a unique question inspired by these templates, but don't repeat them exactly. The question should be engaging, thought-provoking, and reveal aspects of the person's dating personality. Ensure it's different from the previous questions. |
|
|
|
Generate only the question, nothing else.""" |
|
|
|
response = self.generate_dialogue_response(prompt) |
|
return response[1].strip('"') |
|
|
|
class PersonalityClassifierAgent(GenerativeAgent): |
|
def __init__(self, name: str, age: int, traits: str): |
|
memory = GenerativeAgentMemory( |
|
llm=LLM, |
|
memory_retriever=create_new_memory_retriever(), |
|
verbose=False, |
|
reflection_threshold=5 |
|
) |
|
super().__init__(name=name, age=age, traits=traits, status="active", memory=memory, llm=LLM) |
|
|
|
def classify_personality(self, questions: List[str], answers: List[str]) -> dict: |
|
context = "\n".join([f"Q: {q}\nA: {a}" for q, a in zip(questions, answers)]) |
|
personality_types = "\n".join([f"- {type}: {desc}" for type, desc in PERSONALITY_TYPES.items()]) |
|
prompt = f"""As a dating app personality classifier, categorize the person's dating personality based on these questions and answers: |
|
|
|
{personality_types} |
|
|
|
Questions and Answers: |
|
{context} |
|
|
|
Provide the personality type and a brief explanation for your choice. Also, suggest potential compatible personality types for dating. Format your response as: |
|
Personality Type: [chosen type] |
|
Explanation: [your explanation] |
|
Compatible Types: [list of compatible types] |
|
Dating Advice: [brief advice based on their personality type] |
|
""" |
|
response = self.generate_dialogue_response(prompt) |
|
personality_summary = response[1] |
|
|
|
|
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") |
|
filename = f"personality_summary_{timestamp}.txt" |
|
with open(filename, "w") as f: |
|
f.write("Capybara Dating App - Personality Summary\n") |
|
f.write("=========================================\n\n") |
|
f.write("Questions and Answers:\n") |
|
for q, a in zip(questions, answers): |
|
f.write(f"Q: {q}\n") |
|
f.write(f"A: {a}\n\n") |
|
f.write("Personality Classification:\n") |
|
f.write(personality_summary) |
|
|
|
return {"personality": personality_summary, "summary_file": filename} |
|
|
|
question_agent = QuestionGeneratorAgent("CapybaraQuestionBot", 25, "curious, romantic, empathetic") |
|
classifier_agent = PersonalityClassifierAgent("CapybaraMatchBot", 30, "insightful, compassionate, intuitive") |
|
|
|
@app.route('/generate_question', methods=['POST']) |
|
def generate_question(): |
|
data = request.json |
|
previous_questions = data.get('previous_questions', []) |
|
previous_answers = data.get('previous_answers', []) |
|
question = question_agent.generate_question(previous_questions, previous_answers) |
|
return jsonify({'question': question}) |
|
|
|
@app.route('/classify_personality', methods=['POST']) |
|
def classify_personality(): |
|
data = request.json |
|
questions = data.get('questions', []) |
|
answers = data.get('answers', []) |
|
result = classifier_agent.classify_personality(questions, answers) |
|
return jsonify(result) |
|
|
|
if __name__ == '__main__': |
|
app.run(debug=True) |
|
|