IM.analyst / app.py
James MacQuillan
push
6b19354
raw
history blame
11.3 kB
from sentence_transformers import SentenceTransformer
import gradio as gr
import os
import json
from bs4 import BeautifulSoup
import requests
from huggingface_hub import InferenceClient
from langchain.vectorstores import Chroma
# Required imports
from sentence_transformers import SentenceTransformer
from langchain.embeddings import HuggingFaceEmbeddings # Use Hugging Face wrapper for SentenceTransformers
from langchain.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.schema import Document
from langchain.vectorstores import Chroma
import numpy as np
from sklearn.manifold import TSNE
import plotly.graph_objects as go
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.schema import Document
import chromadb.utils.embedding_functions as embedding_functions
from langchain_community.embeddings import HuggingFaceEmbeddings
hf_token = os.getenv('HF_TOKEN')
huggingface_ef = embedding_functions.HuggingFaceEmbeddingFunction(
api_key=hf_token,
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
embedding_model = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2')
# Define global variables
BOT_AVATAR = 'https://automatedstockmining.org/wp-content/uploads/2024/08/south-west-value-mining-logo.webp'
#for the search vector database
# Initialize Chroma vector store directory
db_name2 = "search_checkvector_db"
# Read in the text for processing
health_check_text = ''
with open('search_requirements.txt', 'r', encoding='utf-8') as search_text:
search_requirements_text = search_text.read()
# Split text into chunks
search_splitter = CharacterTextSplitter(chunk_size=20, chunk_overlap=2)
parts = search_splitter.split_text(search_requirements_text)
search_documents = [Document(page_content=chunk) for chunk in parts]
# Initialize Chroma with documents and embeddings
search_vectorstore = Chroma.from_documents(
documents=search_documents,
embedding=embedding_model,
persist_directory=db_name2
)
# Initialize Chroma vector store directory
db_name = "health_checkvector_db"
# Read in the text for processing
health_check_text = ''
with open('healthcheck.txt', 'r', encoding='utf-8') as file:
health_check_text = file.read()
# Split text into chunks
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = text_splitter.split_text(health_check_text)
# Convert chunks into Document objects
documents = [Document(page_content=chunk) for chunk in chunks]
# Initialize Chroma with documents and embeddings
vectorstore = Chroma.from_documents(
documents=documents,
embedding=embedding_model,
persist_directory=db_name
)
client = InferenceClient(token=hf_token)
custom_css = '''
.gradio-container {
font-family: 'Roboto', sans-serif;
}
.main-header {
text-align: center;
color: #4a4a4a;
margin-bottom: 2rem;
}
.tab-header {
font-size: 1.2rem;
font-weight: bold;
margin-bottom: 1rem;
}
.custom-chatbot {
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.custom-button {
background-color: #3498db;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.custom-button:hover {
background-color: #2980b9;
}
'''
def extract_text_from_webpage(html):
soup = BeautifulSoup(html, "html.parser")
for script in soup(["script", "style"]):
script.decompose()
visible_text = soup.get_text(separator=" ", strip=True)
return visible_text
def search(query):
term = query
max_chars_per_page = 8000
all_results = []
with requests.Session() as session:
try:
resp = session.get(
url="https://www.google.com/search",
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0"},
params={"q": term, "num": 7},
timeout=5
)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, "html.parser")
result_block = soup.find_all("div", attrs={"class": "g"})
for result in result_block:
link = result.find("a", href=True)
if link:
link = link["href"]
try:
webpage = session.get(link, headers={"User-Agent": "Mozilla/5.0"}, timeout=5)
webpage.raise_for_status()
visible_text = extract_text_from_webpage(webpage.text)
if len(visible_text) > max_chars_per_page:
visible_text = visible_text[:max_chars_per_page]
all_results.append({"link": link, "text": visible_text})
except requests.exceptions.RequestException as e:
print(f"Failed to retrieve {link}: {e}")
all_results.append({"link": link, "text": None})
except requests.exceptions.RequestException as e:
print(f"Google search failed: {e}")
return all_results
def process_query(user_input, history):
yield 'locating vectorstore 🛠️'
docs = vectorstore.similarity_search(user_input, k=5)
# Retrieve and concatenate results
retrieved_texts = " ".join([doc.page_content for doc in docs])
#similarity search on searches
searches = search_vectorstore.similarity_search(user_input, k=3)
# Retrieve and concatenate results
search_texts = " ".join([doc.page_content for doc in searches])
yield 'Preparing your request 🛠️'
# Step 1: Generate a search term based on the user query
stream_search = client.chat_completion(
model="Qwen/Qwen2.5-72B-Instruct",
messages=[{"role": "user", "content": f"Based on this chat history {history} the user's request '{user_input}', and this vector database {search_texts}, suggest a Google search term in a single line without specific dates; use 'this year', 'this month', etc. INCLUDE NOTHING IN YOUR RESPONSE EXCEPT THE RELEVANT SEARCH RESULT. EXAMPLE: USER: WHAT IS THE CURRENT PRICE OF COCA COLA STOCK. YOUR RESPONSE: WHAT IS THE CURRENT PRICE OF COCA COLA STOCK"}],
max_tokens=400,
stream=True
)
# Collect the search term
search_query = ""
for chunk in stream_search:
content = chunk.choices[0].delta.content or ''
search_query += content
# Step 2: Perform the web search with the generated term
yield 'Searching the web for relevant information 🌐'
search_results = search(search_query)
# Format results as a JSON string for model input
search_results_str = json.dumps(search_results)
yield 'thinking...'
# Step 3: Generate a response using the search results
response = client.chat_completion(
model="Qwen/Qwen2.5-72B-Instruct",
messages=[{"role": "user", "content": f"Using the search results: {search_results_str} and chat history {history}, this vector database on health checks {retrieved_texts} answer the user's query '{user_input}' in a concise, precise way, using numerical data if available. ONLY GIVE ONE RESPONSE BACK, CONCISE OR DETAILED BASED ON THE USERS INPUT"}],
max_tokens=3000,
stream=True
)
yield "Analyzing the data and getting ready to respond 📊"
# Stream final response
final_response = ""
for chunk in response:
content = chunk.choices[0].delta.content or ''
final_response += content
yield final_response
theme = gr.themes.Citrus(
primary_hue="blue",
neutral_hue="slate",
)
examples = [
["whats the trending social sentiment like for Nvidia"],
["What's the latest news on Cisco Systems stock"],
["Analyze technical indicators for Adobe, are they presenting buy or sell signals"],
["Write me a smart sheet on the trending social sentiment and technical indicators for Nvidia"],
["What are the best stocks to buy this month"],
["What companies report earnings this week"],
["write me a health check on adobe"],
["Analyze the technical indicators for Apple"],
["give me the current sentiment score for Apple"],
["Make a table of Apple's stock price for the last 3 days"],
["What is Apple's PE ratio and how does it compare to other companies in consumer electronics"],
["How did Salesforce perform in its last earnings?"],
["What is the average analyst price target for Nvidia"],
["What is the outlook for the stock market in 2025"],
["When does Nvidia next report earnings"],
["What are the latest products from Apple"],
["What is Tesla's current price-to-earnings ratio and how does it compare to other car manufacturers?"],
["List the top 5 performing stocks in the S&P 500 this month"],
["What is the dividend yield for Coca-Cola?"],
["Which companies in the tech sector are announcing dividends this month?"],
["Analyze the latest moving averages for Microsoft; are they indicating a trend reversal?"],
["What is the latest guidance on revenue for Meta?"],
["What is the current beta of Amazon stock and how does it compare to the industry average?"],
["What are the top-rated ETFs for technology exposure this quarter?"]
]
chatbot = gr.Chatbot(
label="IM.S",
avatar_images=[None, BOT_AVATAR],
show_copy_button=True,
layout="panel",
height=700
)
theme = gr.themes.Ocean()
with gr.Blocks(theme=theme) as demo:
with gr.Column():
gr.Markdown("## quantineuron.com: IM.analyst - Building the Future of Investing")
with gr.Column(scale=3, min_width=600):
chat_interface = gr.ChatInterface(
fn=process_query,
chatbot=chatbot,
examples=examples
)
with gr.Column():
gr.Markdown('''
**Disclaimer**: The information provided by IM.analyst is for educational and informational purposes only and does not constitute financial, investment, or professional advice. By using this service, you acknowledge and agree that all decisions you make based on the information provided are made at your own risk. Neither IM.analyst nor quantineuron.com is liable for any financial losses or damages resulting from reliance on information provided by this chatbot.
By using IM.analyst, you agree to be bound by quantineuron.com’s [Terms of Service](https://quantineuron.com/disclaimer-statement/), [Terms and Conditions](https://quantineuron.com/terms-and-conditions/), [Data Protection and Privacy Policy](https://quantineuron.com/data-protection-and-privacy-policy/), [our discalimer statement](https://quantineuron.com/disclaimer-statement/) and this Disclaimer Statement. We recommend reviewing these documents carefully. Your continued use of this service confirms your acceptance of these terms and conditions, and it is your responsibility to stay informed of any updates or changes.
**Important Note**: Investing in financial markets carries risk, and it is possible to lose some or all of the invested capital. Always consider seeking advice from a qualified financial advisor.
''')
demo.launch()