Spaces:
Runtime error
Runtime error
import gradio as gr | |
from swarm import Swarm, Agent | |
from openai import OpenAI | |
from exa_py import Exa | |
import os | |
from dotenv import load_dotenv | |
import tweepy | |
import json | |
load_dotenv() | |
openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) | |
client = Swarm(client=openai_client) | |
exa_client = Exa(api_key=os.getenv("EXA_API_KEY")) | |
# Twitter API setup | |
bearer_token = os.getenv('bearer_token') | |
twitter_client = tweepy.Client(bearer_token=bearer_token) | |
def search_prop_firm_info(query, num_results=5): | |
results = exa_client.search_and_contents( | |
query, | |
type="keyword", | |
num_results=int(num_results), | |
text=True, | |
start_published_date="2023-01-01", | |
category="company", | |
include_domains=["propfirmmatch.com"], | |
summary=True | |
) | |
formatted_results = [] | |
for result in results.results: | |
formatted_results.append(f"Title: {result.title}\nURL: {result.url}\nSummary: {result.summary}\n") | |
return "\n".join(formatted_results) | |
def search_trustpilot_reviews(company_name, num_results=3): | |
query = f"site:trustpilot.com {company_name} reviews" | |
results = exa_client.search_and_contents( | |
query, | |
type="keyword", | |
num_results=int(num_results), | |
text=True, | |
start_published_date="2023-01-01", | |
summary=True | |
) | |
formatted_results = [] | |
for result in results.results: | |
formatted_results.append(f"Title: {result.title}\nURL: {result.url}\nSummary: {result.summary}\n") | |
return "\n".join(formatted_results) | |
def search_tweets(query, max_results=100): | |
try: | |
formatted_query = query.replace('"', '').strip() | |
tweets = twitter_client.search_recent_tweets(query=formatted_query, max_results=max_results) | |
return tweets.data if tweets.data else [] | |
except tweepy.errors.BadRequest as e: | |
print(f"BadRequest error: {e}") | |
return [] | |
except tweepy.errors.TweepyException as e: | |
print(f"Tweepy error: {e}") | |
return [] | |
except Exception as e: | |
print(f"Unexpected error in search_tweets: {e}") | |
return [] | |
twitter_sentiment_agent = Agent( | |
name="Twitter Sentiment Analyzer", | |
instructions="""You are an agent that analyzes Twitter sentiment for proprietary trading firms. | |
Given a list of tweets about a specific firm, analyze the overall sentiment and provide a summary. | |
Consider the following: | |
1. Overall sentiment (positive, negative, or neutral) | |
2. Common themes or topics mentioned | |
3. Any notable praise or complaints | |
4. Level of engagement (replies, retweets, likes) | |
Provide a concise summary of your findings.""", | |
functions=[search_tweets], | |
) | |
trustpilot_review_agent = Agent( | |
name="TrustPilot Review Analyzer", | |
instructions="""You are an agent that searches for and analyzes TrustPilot reviews for proprietary trading firms. | |
Use the search_trustpilot_reviews function to find reviews for a given company. | |
Your tasks are to: | |
1. Search for TrustPilot reviews using the provided company name. | |
2. Analyze the overall sentiment of the reviews (positive, negative, or mixed). | |
3. Identify common themes or recurring points in the reviews. | |
4. Note any standout positive or negative comments. | |
5. If available, mention the overall TrustPilot rating for the company. | |
6. Provide a concise summary of your findings, highlighting the most important aspects for a potential trader. | |
Your summary should be informative and balanced, presenting both positives and negatives if they exist.""", | |
functions=[search_trustpilot_reviews], | |
) | |
prop_firm_search_agent = Agent( | |
name="Prop Firm Search", | |
instructions="""You are an agent that searches for proprietary trading firm information on propfirmmatch.com. Use the search_prop_firm_info function to find information based on the user's query. The function takes two parameters: query (string) and num_results (integer, default 5). | |
If the user names a specific firm: | |
1. Use the firm's name as the search query. | |
2. Call the search_prop_firm_info function with the firm's name. | |
3. Provide a detailed summary of the information found about the firm from propfirmmatch.com. | |
Always include relevant details such as leverage, accepted countries, and any unique features of the firms.""", | |
functions=[search_prop_firm_info], | |
) | |
score_agent = Agent( | |
name="Score Generator", | |
instructions="""You are an agent that generates an overall score for proprietary trading firms based on the information provided. | |
Consider the following factors: | |
1. Information from propfirmmatch.com | |
2. TrustPilot reviews | |
3. Twitter sentiment | |
4. Any unique features or advantages of the firm | |
Generate a score out of 100, where: | |
90-100: Excellent | |
80-89: Very Good | |
70-79: Good | |
60-69: Fair | |
Below 60: Poor | |
Provide a brief explanation for the score. | |
Format your response as follows: | |
**Score:** (your score here) | |
**Twitter:** (Highlights of twitter analysis here) | |
**TrustPilot:** (Highlights / notable reviews here) | |
**PropFirmMatch:** (Summary of firm from search_propfirm_info / propfirmmatch agent)""", | |
functions=[], | |
) | |
def fetch_twitter_sentiment(company_name, num_tweets=100): | |
query = f"{company_name} -is:retweet" | |
tweets = search_tweets(query, max_results=num_tweets) | |
if not tweets: | |
return "No tweets found." | |
tweet_texts = [tweet.text for tweet in tweets] | |
tweet_data = "\n\n".join(tweet_texts) | |
analysis_prompt = f"Analyze the sentiment of the following tweets about {company_name}:\n\n{tweet_data}" | |
sentiment_response = client.run(twitter_sentiment_agent, messages=[{"role": "user", "content": analysis_prompt}]) | |
sentiment_analysis = sentiment_response.messages[-1]["content"] if sentiment_response.messages else "No sentiment analysis available." | |
return sentiment_analysis | |
def search_prop_firms(query): | |
search_response = client.run(prop_firm_search_agent, messages=[{"role": "user", "content": query}]) | |
search_results = search_response.messages[-1]["content"] if search_response.messages else "No search results." | |
trustpilot_analysis = get_trustpilot_analysis(query) | |
twitter_sentiment = fetch_twitter_sentiment(query) | |
combined_results = f"{search_results}\n\nTrustPilot Analysis:\n{trustpilot_analysis}\n\nTwitter Sentiment Analysis:\n{twitter_sentiment}" | |
score_prompt = f"Generate a score for {query} based on the following information:\n\n{combined_results}" | |
score_response = client.run(score_agent, messages=[{"role": "user", "content": score_prompt}]) | |
score_result = score_response.messages[-1]["content"] if score_response.messages else "No score available." | |
return query, search_results, trustpilot_analysis, twitter_sentiment, score_result | |
def get_trustpilot_analysis(firm_name): | |
trustpilot_prompt = f"Find and analyze TrustPilot reviews for {firm_name}" | |
trustpilot_response = client.run(trustpilot_review_agent, messages=[{"role": "user", "content": trustpilot_prompt}]) | |
return trustpilot_response.messages[-1]["content"] if trustpilot_response.messages else "No TrustPilot analysis available." | |
def format_report_card(query): | |
firm_name, search_results, trustpilot_analysis, twitter_sentiment, score_result = search_prop_firms(query) | |
report_card = { | |
"firm_name": firm_name, | |
"overall_score": score_result, | |
"firm_info": search_results, | |
"trustpilot_analysis": trustpilot_analysis, | |
"twitter_sentiment": twitter_sentiment | |
} | |
return json.dumps(report_card) | |
def run_gradio_interface(): | |
with gr.Blocks(theme=gr.themes.Soft()) as demo: | |
gr.Markdown("# Proprietary Trading Firm Analysis") | |
with gr.Row(): | |
with gr.Column(scale=2): | |
query_input = gr.Textbox(label="Enter firm name", lines=2) | |
search_button = gr.Button("Generate Report", variant="primary") | |
with gr.Column(scale=1): | |
gr.Markdown("### Example Queries") | |
gr.Examples( | |
examples=["FTMO", "MyForexFunds", "The5ers"], | |
inputs=query_input | |
) | |
output = gr.JSON(label="Report Card") | |
search_button.click(format_report_card, inputs=[query_input], outputs=[output]) | |
demo.launch(share=True) | |
if __name__ == "__main__": | |
run_gradio_interface() | |