Manavraj commited on
Commit
69e7e0f
·
verified ·
1 Parent(s): ab7850a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -197
app.py CHANGED
@@ -1,219 +1,86 @@
1
  import gradio as gr
2
  import requests
3
- from bs4 import BeautifulSoup
4
  import json
5
- from urllib.parse import quote_plus
6
- import time
7
  import logging
8
- import re
9
- from smolagents.tools import tool
10
- from fastapi import FastAPI
11
- import uvicorn
12
 
13
  # Configure logging
14
  logging.basicConfig(level=logging.INFO)
15
  logger = logging.getLogger(__name__)
16
 
17
- app = FastAPI()
18
 
19
- @tool
20
- def search_knowledge_base(issue: str) -> str:
21
- """
22
- Search the knowledge base for solutions related to the provided issue.
23
- Args:
24
- issue (str): The technical issue to search for
25
- Returns:
26
- str: Solution steps or message if no solution found
27
- """
28
  try:
29
- issue = issue.lower()
30
- if "wifi" in issue:
31
- return "1. Check if your router is powered on\n2. Restart your router\n3. Try connecting again\n4. If problem persists, contact your ISP"
32
- elif "screen" in issue:
33
- return "1. Adjust display cable connections\n2. Update graphics drivers\n3. Restart the system\n4. Try a different monitor if available"
34
- elif "sound" in issue or "audio" in issue:
35
- return "1. Check volume settings\n2. Verify audio output device selection\n3. Update audio drivers\n4. Test with headphones"
36
- return "No predefined solution found in the knowledge base. Please try our web search tool for more information."
37
- except Exception as e:
38
- logger.error(f"Error in knowledge base search: {str(e)}")
39
- return f"Error searching knowledge base: {str(e)}"
40
-
41
- def search_web_duckduckgo(query: str) -> str:
42
- """
43
- Perform actual web search using DuckDuckGo API.
44
- Args:
45
- query (str): The search query
46
- Returns:
47
- str: Formatted search results
48
- """
49
- try:
50
- url = f"https://api.duckduckgo.com/?q={quote_plus(query)}&format=json&no_html=1&skip_disambig=1"
51
-
52
- response = requests.get(url, timeout=10)
53
  response.raise_for_status()
54
 
55
- data = response.json()
56
- results = []
57
-
58
- if data.get('AbstractText'):
59
- results.append(f"Summary: {data['AbstractText']}")
60
-
61
- if data.get('RelatedTopics'):
62
- results.append("\nRelated Topics:")
63
- for i, topic in enumerate(data['RelatedTopics'][:3], 1):
64
- if isinstance(topic, dict) and topic.get('Text'):
65
- results.append(f"{i}. {topic['Text']}")
66
- elif hasattr(topic, 'Topics'):
67
- for subtopic in topic['Topics'][:3]:
68
- if subtopic.get('Text'):
69
- results.append(f"{i}. {subtopic['Text']}")
70
-
71
- if data.get('Definition'):
72
- results.append(f"\nDefinition: {data['Definition']}")
73
-
74
- if not results or len(''.join(results).strip()) < 20:
75
- return search_web_scraper(query)
76
- return "\n".join(results)
77
  except Exception as e:
78
- logger.error(f"Web search API error: {str(e)}")
79
- return search_web_scraper(query)
80
 
81
- def search_web_scraper(query: str) -> str:
82
- """
83
- Alternative web search using web scraping (backup method).
84
- Args:
85
- query (str): The search query
86
- Returns:
87
- str: Formatted search results
88
- """
89
- try:
90
- search_url = f"https://duckduckgo.com/html/?q={quote_plus(query)}"
91
-
92
- headers = {
93
- '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'
94
- }
95
-
96
- response = requests.get(search_url, headers=headers, timeout=10)
97
- response.raise_for_status()
98
-
99
- soup = BeautifulSoup(response.content, 'html.parser')
100
- results = []
101
- result_links = soup.find_all('a', class_='result__a')[:5]
102
-
103
- for i, link in enumerate(result_links, 1):
104
- title = link.get_text(strip=True)
105
- if title:
106
- results.append(f"{i}. {title} (https://{link['href']})" if link.get('href') else f"{i}. {title}")
107
-
108
- if results:
109
- return f"Search Results for '{query}':\n" + "\n".join(results)
110
- return f"No results found for '{query}'. Try different keywords."
111
- except Exception as e:
112
- logger.error(f"Web scraping error: {str(e)}")
113
- return f"Error in backup search: {str(e)}"
114
-
115
- @tool
116
- def search_web(query: str) -> str:
117
- """
118
- Main web search function that tries multiple methods.
119
- Args:
120
- query (str): The search query
121
- Returns:
122
- str: Formatted search results
123
- """
124
- try:
125
- if not query.strip():
126
- return "Please enter a search query."
127
- return search_web_duckduckgo(query)
128
- except Exception as e:
129
- logger.error(f"Error in main web search: {str(e)}")
130
- return f"Error processing your search: {str(e)}"
131
 
132
- @tool
133
- def format_response(raw_steps: str) -> str:
134
- """
135
- Format the raw steps into a numbered list.
136
- Args:
137
- raw_steps (str): Raw text steps separated by periods
138
- Returns:
139
- str: Formatted numbered list of steps
140
- """
141
  try:
142
- if not raw_steps.strip():
143
- return "Please enter some text to format."
144
-
145
- steps = re.split(r'[.,;]\s*', raw_steps)
146
- steps = [step.strip() for step in steps if step.strip()]
147
- steps = [f"{i+1}. {step}" for i, step in enumerate(steps)]
148
- return "\n".join(steps)
149
  except Exception as e:
150
- logger.error(f"Error formatting steps: {str(e)}")
151
- return f"Error formatting your steps: {str(e)}"
152
-
153
- # Create interfaces
154
- demo1 = gr.Interface(
155
- fn=search_knowledge_base,
156
- inputs=[gr.Textbox(label="Technical Issue", placeholder="Enter your technical problem")],
157
- outputs=[gr.Textbox(label="Solution")],
158
- title="Knowledge Base Search"
159
- )
160
 
161
- demo2 = gr.Interface(
162
- fn=search_web,
163
- inputs=[gr.Textbox(label="Search Query", placeholder="Enter your search query")],
164
- outputs=[gr.Textbox(label="Search Results")],
165
- title="Web Search"
166
  )
167
 
168
- demo3 = gr.Interface(
169
- fn=format_response,
170
- inputs=[gr.Textbox(label="Raw Steps", placeholder="Enter steps separated by periods")],
171
- outputs=[gr.Textbox(label="Formatted Steps")],
172
- title="Response Formatter"
173
- )
174
-
175
- demo = gr.TabbedInterface([demo1, demo2, demo3], ["Knowledge Base", "Web Search", "Formatter"])
176
-
177
- # Add MCP schema endpoint
178
- @app.get("/gradio_api/mcp/schema")
179
- async def mcp_schema():
180
- return {
181
- "tools": [
182
- {
183
- "name": "search_knowledge_base",
184
- "description": "Search knowledge base for technical solutions",
185
- "parameters": {
186
- "type": "object",
187
- "properties": {
188
- "issue": {"type": "string"}
189
- }
190
- }
191
- },
192
- {
193
- "name": "search_web",
194
- "description": "Perform web search",
195
- "parameters": {
196
- "type": "object",
197
- "properties": {
198
- "query": {"type": "string"}
199
- }
200
- }
201
- },
202
- {
203
- "name": "format_response",
204
- "description": "Format steps into numbered list",
205
- "parameters": {
206
- "type": "object",
207
- "properties": {
208
- "raw_steps": {"type": "string"}
209
- }
210
- }
211
- }
212
- ]
213
- }
214
-
215
- # Mount Gradio app
216
- app = gr.mount_gradio_app(app, demo, path="/")
217
-
218
  if __name__ == "__main__":
219
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
1
  import gradio as gr
2
  import requests
 
3
  import json
4
+ from smolagents import CodeAgent
 
5
  import logging
6
+ from tenacity import retry, stop_after_attempt, wait_exponential
 
 
 
7
 
8
  # Configure logging
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
12
+ HF_SPACE_URL = "https://manavraj-troubleshoot-mcp.hf.space"
13
 
14
+ @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
15
+ def call_mcp_server(message: str, tool_type: str = "knowledge_base") -> str:
16
+ """Call MCP server endpoint"""
 
 
 
 
 
 
17
  try:
18
+ endpoint = f"{HF_SPACE_URL}/gradio_api/mcp/sse"
19
+ response = requests.post(
20
+ endpoint,
21
+ json={
22
+ "tool": tool_type,
23
+ "input": message
24
+ },
25
+ stream=True,
26
+ timeout=30
27
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  response.raise_for_status()
29
 
30
+ for line in response.iter_lines():
31
+ if line.startswith(b'data:'):
32
+ return json.loads(line[5:])["output"]
33
+
34
+ return "No response received from MCP server"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  except Exception as e:
36
+ logger.error(f"API call failed: {str(e)}")
37
+ return f"Error: {str(e)}"
38
 
39
+ agent = CodeAgent(
40
+ tools=[],
41
+ model="microsoft/DialoGPT-medium",
42
+ system_prompt="""{{authorized_imports}}
43
+ - requests for API calls
44
+ - standard Python libraries
45
+ {{managed_agents_descriptions}}
46
+ You are a Technical Support Assistant with these capabilities:
47
+ 1. Troubleshooting technical issues
48
+ 2. Finding information via web search
49
+ 3. Formatting instructions
50
+ Access tools through MCP server:
51
+ - knowledge_base: For technical issues
52
+ - web_search: For information lookup
53
+ - formatter: To organize steps
54
+ Response workflow:
55
+ 1. Analyze user request
56
+ 2. Choose appropriate tool
57
+ 3. Return clear response
58
+ Example:
59
+ USER: My wifi disconnected
60
+ THOUGHT: Should use knowledge_base
61
+ ACTION: knowledge_base("wifi disconnection")
62
+ RESPONSE: Try these steps: [solution steps]
63
+ Never show internal workflow to user."""
64
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
+ def chat_interface(message: str, history: list) -> str:
67
+ """Handle chat interaction"""
 
 
 
 
 
 
 
68
  try:
69
+ response = agent.run(message)
70
+ if "ACTION:" in response:
71
+ tool_call = response.split("ACTION:")[1].split("(")[0].strip()
72
+ input_text = response.split("(")[1].split(")")[0].strip('"')
73
+ return call_mcp_server(input_text, tool_call)
74
+ return response
 
75
  except Exception as e:
76
+ logger.error(f"Chat error: {str(e)}")
77
+ return f"Error: {str(e)}"
 
 
 
 
 
 
 
 
78
 
79
+ demo = gr.ChatInterface(
80
+ fn=chat_interface,
81
+ title="🔧 Technical Support",
82
+ examples=["Wifi not working", "Find Windows 11 specs", "Format: Turn off. Wait. Restart"]
 
83
  )
84
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  if __name__ == "__main__":
86
+ demo.launch()