James MacQuillan commited on
Commit
380991e
·
1 Parent(s): 1824405
Files changed (1) hide show
  1. app.py +183 -58
app.py CHANGED
@@ -1,64 +1,189 @@
 
 
1
  import gradio as gr
 
 
 
 
2
  from huggingface_hub import InferenceClient
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
 
4
- """
5
- For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
6
- """
7
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
8
-
9
-
10
- def respond(
11
- message,
12
- history: list[tuple[str, str]],
13
- system_message,
14
- max_tokens,
15
- temperature,
16
- top_p,
17
- ):
18
- messages = [{"role": "system", "content": system_message}]
19
-
20
- for val in history:
21
- if val[0]:
22
- messages.append({"role": "user", "content": val[0]})
23
- if val[1]:
24
- messages.append({"role": "assistant", "content": val[1]})
25
-
26
- messages.append({"role": "user", "content": message})
27
-
28
- response = ""
29
-
30
- for message in client.chat_completion(
31
- messages,
32
- max_tokens=max_tokens,
33
- stream=True,
34
- temperature=temperature,
35
- top_p=top_p,
36
- ):
37
- token = message.choices[0].delta.content
38
-
39
- response += token
40
- yield response
41
-
42
-
43
- """
44
- For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
45
- """
46
- demo = gr.ChatInterface(
47
- respond,
48
- additional_inputs=[
49
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
50
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
51
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
52
- gr.Slider(
53
- minimum=0.1,
54
- maximum=1.0,
55
- value=0.95,
56
- step=0.05,
57
- label="Top-p (nucleus sampling)",
58
- ),
59
- ],
60
  )
61
 
62
 
63
- if __name__ == "__main__":
64
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from typing import final
3
  import gradio as gr
4
+ import os
5
+ import json
6
+ from bs4 import BeautifulSoup
7
+ import requests
8
  from huggingface_hub import InferenceClient
9
+ from datetime import datetime, timedelta
10
+ import json
11
+
12
+
13
+ # Define global variables
14
+ BOT_AVATAR = 'https://automatedstockmining.org/wp-content/uploads/2024/08/south-west-value-mining-logo.webp'
15
+ client = InferenceClient(token=os.getenv("HF_TOKEN"))
16
+ custom_css = '''
17
+ .gradio-container {
18
+ font-family: 'Roboto', sans-serif;
19
+ }
20
+
21
+ .main-header {
22
+ text-align: center;
23
+ color: #4a4a4a;
24
+ margin-bottom: 2rem;
25
+ }
26
+
27
+ .tab-header {
28
+ font-size: 1.2rem;
29
+ font-weight: bold;
30
+ margin-bottom: 1rem;
31
+ }
32
+
33
+ .custom-chatbot {
34
+ border-radius: 10px;
35
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
36
+ }
37
+
38
+ .custom-button {
39
+ background-color: #3498db;
40
+ color: white;
41
+ border: none;
42
+ padding: 10px 20px;
43
+ border-radius: 5px;
44
+ cursor: pointer;
45
+ transition: background-color 0.3s ease;
46
+ }
47
+
48
+ .custom-button:hover {
49
+ background-color: #2980b9;
50
+ }
51
+ '''
52
+
53
+
54
+ def extract_text_from_webpage(html):
55
+ soup = BeautifulSoup(html, "html.parser")
56
+ # Extract visible text, removing unnecessary elements (e.g., scripts, styles)
57
+ for script in soup(["script", "style"]):
58
+ script.decompose()
59
+ visible_text = soup.get_text(separator=" ", strip=True)
60
+ return visible_text
61
+
62
+ def search(query):
63
+ term = query
64
+ max_chars_per_page = 8000
65
+ all_results = []
66
+
67
+ with requests.Session() as session:
68
+ try:
69
+ # Send a search request to Google
70
+ resp = session.get(
71
+ url="https://www.google.com/search",
72
+ headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0"},
73
+ params={"q": term, "num": 4},
74
+ timeout=5
75
+ )
76
+ resp.raise_for_status() # Ensure the request was successful
77
+
78
+ soup = BeautifulSoup(resp.text, "html.parser")
79
+ result_block = soup.find_all("div", attrs={"class": "g"})
80
+
81
+ for result in result_block:
82
+ link = result.find("a", href=True)
83
+ if link:
84
+ link = link["href"]
85
+ try:
86
+ # Fetch the webpage at the found link
87
+ webpage = session.get(link, headers={"User-Agent": "Mozilla/5.0"}, timeout=5)
88
+ webpage.raise_for_status()
89
+
90
+ # Extract visible text from the webpage
91
+ visible_text = extract_text_from_webpage(webpage.text)
92
+ if len(visible_text) > max_chars_per_page:
93
+ visible_text = visible_text[:max_chars_per_page]
94
+
95
+ all_results.append({"link": link, "text": visible_text})
96
+
97
+ except requests.exceptions.RequestException as e:
98
+ print(f"Failed to retrieve {link}: {e}")
99
+ all_results.append({"link": link, "text": None})
100
+ except requests.exceptions.RequestException as e:
101
+ print(f"Google search failed: {e}")
102
+
103
+ return all_results
104
+ def process_query(user_input, history):
105
+ if len(history) > 0 and history[-1]['role'] == 'user' and history[-1]['content'].lower() == user_input.lower():
106
+ gr.Info('Searching the web for the latest data...', duration=4)
107
+ else:
108
+ # Append new user message to the history
109
+ history.append({"role": "user", "content": user_input})
110
+
111
+ search_results = search(user_input)
112
+ search_results_str = json.dumps(search_results)
113
+ response = client.chat_completion(
114
+ model="Qwen/Qwen2.5-72B-Instruct",
115
+ messages=[{"role": "user", "content": f"YOU ARE IM.X, AN INVESTMENT CHATBOT BUILT BY automatedstockmining.org. Answer the user's request '{user_input}' using the following information: {search_results_str} and the chat history{history}. Provide a concise, direct answer in no more than 2-3 sentences. use the appropriate emojis for some of your responses"}],
116
+ max_tokens=400,
117
+ stream=False
118
+ )
119
+ final_response = response.choices[0].message['content']
120
+ history.append({"role": "assistant", "content": final_response})
121
 
122
+ return history, "" # Clear the input box after sending the response
123
+
124
+
125
+ def clear_history():
126
+ return [], "" # Return empty history and clear the input box
127
+
128
+ # Function to undo the last user-bot message pair
129
+ def undo_last(history):
130
+ if len(history) >= 2: # Ensure that there's at least one user-bot message pair
131
+ history.pop() # Remove the bot's response
132
+ history.pop() # Remove the user's input
133
+ return history, "" # Return updated history and clear the input box
134
+
135
+ # Gradio UI setup
136
+
137
+
138
+ theme = gr.themes.Citrus(
139
+ primary_hue="blue",
140
+ neutral_hue="slate",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  )
142
 
143
 
144
+ with gr.Blocks(theme = theme,css = custom_css) as demo:
145
+ gr.Markdown("<h1 style='text-align: center;'>IM.B - Intelligent Investing with automatedstockmining.org</h1>")
146
+
147
+ with gr.Column():
148
+ chatbot_display = gr.Chatbot(label="IM.B chat", avatar_images=[None, BOT_AVATAR], height=600, type="messages", layout="panel")
149
+
150
+ # User input and send button
151
+ with gr.Row():
152
+ user_input = gr.Textbox(placeholder="Type your message here...", label=None, show_label=False)
153
+ send_button = gr.Button("Send")
154
+
155
+ example_inputs = [
156
+ ["What's the current price of bitcoin"],
157
+ ["What's the latest news on Cisco Systems stock"],
158
+ ["Analyze technical indicators for Adobe, are they presenting buy or sell signals"],
159
+ ["What's the current price of Apple stock"],
160
+ ["What are the best stocks to buy this month"],
161
+ ['what companies report earnings this week'],
162
+ ["whats apple's current market cap"]
163
+ ]
164
+
165
+ # Add examples to the UI
166
+ gr.Examples(examples=example_inputs, inputs=user_input)
167
+
168
+ # Buttons for Clear and Undo
169
+ with gr.Row():
170
+ clear_button = gr.Button("Clear Chat")
171
+ undo_button = gr.Button("Undo Last")
172
+
173
+ # History is now handled as part of the chatbot_display
174
+ send_button.click(process_query, inputs=[user_input, chatbot_display], outputs=[chatbot_display, user_input])
175
+
176
+ # Allow pressing Enter to submit the input
177
+ user_input.submit(process_query, inputs=[user_input, chatbot_display], outputs=[chatbot_display, user_input])
178
+
179
+ # Action for Clear Button
180
+ clear_button.click(clear_history, outputs=[chatbot_display, user_input])
181
+
182
+ # Action for Undo Button
183
+ undo_button.click(undo_last, inputs=[chatbot_display], outputs=[chatbot_display, user_input])
184
+
185
+ # Launch the Gradio app
186
+ demo.launch()
187
+
188
+
189
+