import os from openai import OpenAI import logging from typing import List, Dict, Any import json import time from pydantic import BaseModel import time from qdrant_client import QdrantClient, models from qdrant_client import QdrantClient from qdrant_client.models import Filter, FieldCondition, MatchValue, Range, MatchAny qdrant_client = QdrantClient( url="https://00e40cf4-6976-43c1-aa08-be895735804b.europe-west3-0.gcp.cloud.qdrant.io:6333", api_key="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOiJtIn0.lfvuJEBzsmB7vez0nhv7HBbUlW77eUAT8raSazqYXHA", ) qdrant_client.set_model("sentence-transformers/all-MiniLM-L6-v2") qdrant_client.set_sparse_model("prithivida/Splade_PP_en_v1") def recommend_talent_tool(search_query: str, verticals=None, min_age=None, max_age=None, gender=None, min_followers=None, max_followers=None, min_overall_engagement=None, max_overall_engagement=None): conditions = [] if verticals: if isinstance(verticals, str): verticals = [verticals] conditions.append( FieldCondition( key="verticals", match=MatchAny(any=verticals) ) ) if min_age is not None or max_age is not None: range_params = {} if min_age is not None: range_params["gte"] = int(min_age) # Ensure it's an integer if max_age is not None: range_params["lte"] = int(max_age) conditions.append( FieldCondition( key="age", range=Range(**range_params) ) ) if gender: conditions.append( FieldCondition( key="gender", match=MatchValue(value=gender) ) ) if min_followers is not None or max_followers is not None: range_params = {} if min_followers is not None: range_params["gte"] = int(min_followers) # Convert to int if max_followers is not None: range_params["lte"] = int(max_followers) conditions.append( FieldCondition( key="follower_count", range=Range(**range_params) ) ) if min_overall_engagement is not None or max_overall_engagement is not None: range_params = {} if min_overall_engagement is not None: range_params["gte"] = float(min_overall_engagement) # Convert to float if max_overall_engagement is not None: range_params["lte"] = float(max_overall_engagement) conditions.append( FieldCondition( key="overall_engagement", range=Range(**range_params) ) ) query_filter = Filter(must=conditions) if conditions else None search_result = qdrant_client.query( collection_name="social_media_profiles", query_text=search_query, query_filter=query_filter, limit=10 ) # Extract metadata and scores results = [] max_followers = max((hit.metadata.get("follower_count", 1) for hit in search_result), default=1) max_engagement = max((hit.metadata.get("overall_engagement", 1) for hit in search_result), default=1) W1, W2, W3 = 0.5, 2.5, 0.25 for hit in search_result: metadata = hit.metadata vector_similarity = hit.score # Qdrant should return a similarity score follower_count = metadata.get("follower_count", 0) overall_engagement = metadata.get("overall_engagement", 0) # Normalize follower count and engagement score normalized_followers = follower_count / max_followers if max_followers > 0 else 0 normalized_engagement = overall_engagement / max_engagement if max_engagement > 0 else 0 # Calculate the matching score matching_score = ( W1 * vector_similarity + W2 * normalized_followers + W3 * normalized_engagement ) results.append({"metadata": metadata, "matching_score": matching_score}) # Sort by matching score in descending order sorted_results = sorted(results, key=lambda x: x["matching_score"], reverse=True) return [item["metadata"] for item in sorted_results]