Threatthriver commited on
Commit
ccbd1ae
1 Parent(s): a9dcc32

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +61 -113
app.py CHANGED
@@ -5,79 +5,60 @@ import requests
5
  import os
6
  from typing import List, Tuple, Optional
7
 
8
- # Retrieve API key from environment variable
9
- api_key = os.getenv('HF_TOKEN')
10
- if not api_key:
11
- raise ValueError("API key not found. Please set the HFTOKEN environment variable.")
12
-
13
- # Initialize the InferenceClient with the specified model and API key
14
- client = InferenceClient(
15
- model="meta-llama/Meta-Llama-3.1-405B-Instruct",
16
- token=api_key
17
- )
18
 
19
- def scrape_yahoo_search(query: str, num_results: int = 3) -> Tuple[str, str]:
20
- """
21
- Scrapes Yahoo search results for the given query and returns detailed snippets and URLs for the top results.
22
-
23
- Args:
24
- query (str): The search query.
25
- num_results (int): Number of results to retrieve.
26
-
27
- Returns:
28
- Tuple[str, str]: The formatted snippets and URLs of the top search results.
29
- """
30
  search_url = f"https://search.yahoo.com/search?p={query}"
31
- headers = {
32
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
33
- }
34
-
35
  try:
36
  response = requests.get(search_url, headers=headers)
37
- response.raise_for_status()
 
38
  soup = BeautifulSoup(response.content, 'html.parser')
39
-
40
- results = []
41
  result_elements = soup.find_all('div', {'class': 'dd algo algo-sr Sr'}, limit=num_results)
42
-
43
  if result_elements:
44
- for result in result_elements:
45
- title = result.find('h3').get_text(strip=True) if result.find('h3') else "No title"
46
- snippet = result.find('div', {'class': 'compText aAbs'}).get_text(strip=True) if result.find('div', {'class': 'compText aAbs'}) else "No snippet"
47
- url = result.find('a')['href'] if result.find('a') else "No URL"
48
- results.append((title, snippet, url))
49
-
50
- formatted_results = "\n\n".join(
51
- f"Title: {title}\nSnippet: {snippet}\nURL: {url}" for title, snippet, url in results
52
- )
53
- return formatted_results, search_url
54
  else:
55
- return "No results found.", search_url
56
-
57
  except requests.RequestException as e:
58
- return f"Request error: {str(e)}", search_url
59
  except Exception as e:
60
- return f"Processing error: {str(e)}", search_url
61
 
62
- def extract_search_query(message: str, trigger_word: str) -> Optional[str]:
63
- """
64
- Extracts the search query from the message based on the trigger word.
65
-
66
- Args:
67
- message (str): The user's input message.
68
- trigger_word (str): The word that activates the search feature.
69
-
70
- Returns:
71
- Optional[str]: The extracted search query if found, otherwise None.
72
- """
73
  lower_message = message.lower()
74
  if trigger_word in lower_message:
75
- parts = lower_message.split(trigger_word, 1)
76
- if len(parts) > 1:
77
- query = parts[1].strip()
78
- return query if query else None
79
  return None
80
 
 
 
 
 
81
  def respond(
82
  message: str,
83
  history: List[Tuple[str, str]],
@@ -86,48 +67,22 @@ def respond(
86
  temperature: float,
87
  top_p: float,
88
  ) -> str:
89
- """
90
- Generates a response from the AI model based on the user's message, chat history, and optional Yahoo search results.
91
-
92
- Args:
93
- message (str): The user's input message.
94
- history (List[Tuple[str, str]]): A list of tuples representing the conversation history (user, assistant).
95
- system_message (str): A system-level message guiding the AI's behavior.
96
- max_tokens (int): The maximum number of tokens for the output.
97
- temperature (float): Sampling temperature for controlling the randomness.
98
- top_p (float): Top-p (nucleus sampling) for controlling diversity.
99
-
100
- Returns:
101
- str: The AI's response as it is generated, including the source URL if applicable.
102
- """
103
-
104
- # Check for trigger word and activate search feature if present
105
- trigger_word = "search"
106
- query = extract_search_query(message, trigger_word)
107
-
108
- if query:
109
- snippet, url = scrape_yahoo_search(query, num_results=3)
110
- message += f"\n\nWeb Content:\n{snippet}\nSource: {url}"
111
- elif query is None:
112
- message = "Please provide a search query after the trigger word."
113
 
114
- # Prepare the conversation history for the API call
115
- messages = [{"role": "system", "content": system_message}]
 
 
 
 
116
 
117
- for user_input, assistant_response in history:
118
- if user_input:
119
- messages.append({"role": "user", "content": user_input})
120
- if assistant_response:
121
- messages.append({"role": "assistant", "content": assistant_response})
122
 
123
- # Add the latest user message to the conversation
124
- messages.append({"role": "user", "content": message})
125
-
126
- # Initialize an empty response
127
  response = ""
128
-
129
  try:
130
- # Generate a response from the model with streaming
131
  for response_chunk in client.chat_completion(
132
  messages=messages,
133
  max_tokens=max_tokens,
@@ -135,32 +90,25 @@ def respond(
135
  temperature=temperature,
136
  top_p=top_p,
137
  ):
138
- token = response_chunk.choices[0].delta.content
139
- response += token
140
  except Exception as e:
141
- return f"AI model error: {str(e)}"
142
 
143
  return response
144
 
145
- # Define the ChatInterface with additional input components for user customization
146
  demo = gr.ChatInterface(
147
  fn=respond,
148
  additional_inputs=[
149
- gr.Textbox(value="You are a friendly Chatbot.", label="System message"),
150
- gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
151
- gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
152
- gr.Slider(
153
- minimum=0.1,
154
- maximum=1.0,
155
- value=0.95,
156
- step=0.05,
157
- label="Top-p (nucleus sampling)",
158
- ),
159
  ],
160
- title="Chatbot Interface",
161
- description="A customizable chatbot interface using Hugging Face's Inference API with Yahoo search scraping capabilities.",
162
  )
163
 
164
- # Launch the Gradio interface
165
  if __name__ == "__main__":
166
- demo.launch()
 
5
  import os
6
  from typing import List, Tuple, Optional
7
 
8
+ # --- Configuration ---
9
+ MODEL_NAME = "meta-llama/Meta-Llama-3.1-405B-Instruct"
10
+ API_KEY_ENV_VAR = "HF_TOKEN"
11
+ SEARCH_TRIGGER_WORD = "search"
12
+ DEFAULT_NUM_RESULTS = 3
 
 
 
 
 
13
 
14
+ # --- Utility Functions ---
15
+
16
+ def get_api_key() -> str:
17
+ """Retrieves the API key from an environment variable."""
18
+ api_key = os.getenv(API_KEY_ENV_VAR)
19
+ if not api_key:
20
+ raise ValueError(f"API key not found. Please set the {API_KEY_ENV_VAR} environment variable.")
21
+ return api_key
22
+
23
+ def scrape_yahoo_search(query: str, num_results: int = DEFAULT_NUM_RESULTS) -> Tuple[Optional[str], Optional[str]]:
24
+ """Scrapes Yahoo search results and returns formatted snippets and the search URL."""
25
  search_url = f"https://search.yahoo.com/search?p={query}"
26
+ headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'}
27
+
 
 
28
  try:
29
  response = requests.get(search_url, headers=headers)
30
+ response.raise_for_status()
31
+
32
  soup = BeautifulSoup(response.content, 'html.parser')
 
 
33
  result_elements = soup.find_all('div', {'class': 'dd algo algo-sr Sr'}, limit=num_results)
34
+
35
  if result_elements:
36
+ results = [
37
+ f"**Title:** {res.find('h3').get_text(strip=True)}\n**Snippet:** {res.find('div', {'class': 'compText aAbs'}).get_text(strip=True)}\n**URL:** {res.find('a')['href']}"
38
+ for res in result_elements
39
+ if res.find('h3') and res.find('div', {'class': 'compText aAbs'}) and res.find('a')
40
+ ]
41
+ return "\n\n".join(results), search_url
 
 
 
 
42
  else:
43
+ return None, search_url
44
+
45
  except requests.RequestException as e:
46
+ return f"Request error: {str(e)}", None
47
  except Exception as e:
48
+ return f"Processing error: {str(e)}", None
49
 
50
+ def extract_search_query(message: str, trigger_word: str = SEARCH_TRIGGER_WORD) -> Optional[str]:
51
+ """Extracts the search query from the message if the trigger word is present."""
 
 
 
 
 
 
 
 
 
52
  lower_message = message.lower()
53
  if trigger_word in lower_message:
54
+ query = lower_message.split(trigger_word, 1)[1].strip()
55
+ return query if query else None
 
 
56
  return None
57
 
58
+ # --- Initialize Inference Client ---
59
+ client = InferenceClient(model=MODEL_NAME, token=get_api_key())
60
+
61
+ # --- Chatbot Logic ---
62
  def respond(
63
  message: str,
64
  history: List[Tuple[str, str]],
 
67
  temperature: float,
68
  top_p: float,
69
  ) -> str:
70
+ """Generates a response from the AI model, incorporating search results if requested."""
71
+ query = extract_search_query(message)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
+ if query:
74
+ search_results, search_url = scrape_yahoo_search(query)
75
+ if search_results:
76
+ message += f"\n\n## Web Search Results:\n{search_results}\n**Source:** {search_url}"
77
+ else:
78
+ message += "\n\nI couldn't find any relevant web results for your query."
79
 
80
+ messages = [{"role": "system", "content": system_message}] + \
81
+ [{"role": role, "content": content} for role, content in history] + \
82
+ [{"role": "user", "content": message}]
 
 
83
 
 
 
 
 
84
  response = ""
 
85
  try:
 
86
  for response_chunk in client.chat_completion(
87
  messages=messages,
88
  max_tokens=max_tokens,
 
90
  temperature=temperature,
91
  top_p=top_p,
92
  ):
93
+ response += response_chunk.choices[0].delta.content
 
94
  except Exception as e:
95
+ return f"AI model error: {str(e)}"
96
 
97
  return response
98
 
99
+ # --- Gradio Interface ---
100
  demo = gr.ChatInterface(
101
  fn=respond,
102
  additional_inputs=[
103
+ gr.Textbox(value="You are a helpful and informative AI assistant.", label="System Message"),
104
+ gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max New Tokens"),
105
+ gr.Slider(minimum=0.1, maximum=1.0, value=0.7, step=0.1, label="Temperature"),
106
+ gr.Slider(minimum=0.1, maximum=1.0, value=0.95, step=0.05, label="Top-p (Nucleus Sampling)"),
 
 
 
 
 
 
107
  ],
108
+ title="Chatbot with Search",
109
+ description="Chat and search the web using the power of Meta-Llama!",
110
  )
111
 
112
+ # --- Launch the App ---
113
  if __name__ == "__main__":
114
+ demo.launch()