File size: 7,261 Bytes
140fcff
356ab4e
 
 
 
 
e0823ce
c148ed0
 
e0823ce
 
 
 
f379bec
c148ed0
 
721f63f
c148ed0
8c537bd
 
 
 
721f63f
e0823ce
 
c148ed0
 
 
 
e0823ce
c148ed0
e0823ce
 
 
 
f379bec
c148ed0
356ab4e
c148ed0
356ab4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c148ed0
356ab4e
 
c148ed0
 
356ab4e
 
c148ed0
 
356ab4e
c148ed0
 
 
 
356ab4e
c148ed0
356ab4e
c148ed0
 
356ab4e
c148ed0
356ab4e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c148ed0
356ab4e
 
 
c148ed0
356ab4e
c148ed0
356ab4e
 
c148ed0
 
356ab4e
e0823ce
356ab4e
 
c148ed0
 
721f63f
356ab4e
8c537bd
 
 
356ab4e
721f63f
e0823ce
 
 
c148ed0
e0823ce
 
 
f379bec
c148ed0
 
721f63f
 
8c537bd
 
 
 
721f63f
e0823ce
 
 
 
c148ed0
e0823ce
c148ed0
 
 
 
 
 
 
 
 
 
e0823ce
 
 
25e0e45
8c537bd
 
 
356ab4e
 
8c537bd
 
 
 
356ab4e
8c537bd
 
356ab4e
 
8c537bd
356ab4e
8c537bd
 
 
 
 
e0823ce
356ab4e
8c537bd
e0823ce
8c537bd
 
356ab4e
8c537bd
25e0e45
69aae5c
e0823ce
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
import gradio as gr
import requests
from bs4 import BeautifulSoup
import json
from urllib.parse import quote_plus
import time
import logging
import re  # Added missing import
from smolagents.tools import tool  # Added for tool decorators

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

@tool(name="knowledge_base")
def search_knowledge_base(issue: str) -> str:
    """
    Search the knowledge base for solutions related to the provided technical issue.
    Args:
        issue (str): The technical issue to search for
    Returns:
        str: Solution steps or message if no solution found
    """
    try:
        issue = issue.lower()
        if "wifi" in issue or "internet" in issue or "network" in issue:
            return "πŸ”§ WiFi Troubleshooting:\n1. Check if your router is powered on\n2. Restart your router\n3. Try connecting again\n4. If problem persists, contact your ISP"
        elif "screen" in issue or "display" in issue:
            return "πŸ–₯️ Display Issues:\n1. Adjust display cable connections\n2. Update graphics drivers\n3. Restart the system\n4. Try a different monitor if available"
        elif "sound" in issue or "audio" in issue:
            return "πŸ”Š Audio Problems:\n1. Check volume settings\n2. Verify audio output device selection\n3. Update audio drivers\n4. Test with headphones"
        return "No predefined solution found in the knowledge base. Please try our web search tool for more information."
    except Exception as e:
        logger.error(f"Error in knowledge base search: {str(e)}")
        return f"Error searching knowledge base: {str(e)}"

def search_web_duckduckgo(query: str) -> str:
    """
    Perform web search using DuckDuckGo API.
    Args:
        query (str): The search query
    Returns:
        str: Formatted search results
    """
    try:
        url = f"https://api.duckduckgo.com/?q={quote_plus(query)}&format=json&no_html=1&skip_disambig=1"
        
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        
        data = response.json()
        results = []
        
        if data.get('AbstractText'):
            results.append(f"πŸ“Œ {data['AbstractText']}")
        
        if data.get('RelatedTopics'):
            results.append("\nπŸ” Related Topics:")
            for i, topic in enumerate(data['RelatedTopics'][:5], 1):
                if isinstance(topic, dict) and topic.get('Text'):
                    results.append(f"{i}. {topic['Text']}")
                elif hasattr(topic, 'FirstURL'):
                    results.append(f"{i}. {getattr(topic, 'Text', 'No description')} - {topic.FirstURL}")
        
        if data.get('Results'):
            results.append("\n🌐 Web Results:")
            for i, result in enumerate(data['Results'][:3], 1):
                results.append(f"{i}. {result.get('Text', 'No title')} - {result.get('FirstURL', 'No URL')}")
        
        return "\n".join(results) if results else search_web_scraper(query)
    except Exception as e:
        logger.error(f"DuckDuckGo API error: {str(e)}")
        return search_web_scraper(query)

def search_web_scraper(query: str) -> str:
    """
    Alternative web search using web scraping (backup method).
    Args:
        query (str): The search query
    Returns:
        str: Formatted search results
    """
    try:
        search_url = f"https://duckduckgo.com/html/?q={quote_plus(query)}"
        
        headers = {
            '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'
        }
        
        response = requests.get(search_url, headers=headers, timeout=10)
        response.raise_for_status()
        
        soup = BeautifulSoup(response.content, 'html.parser')
        results = []
        result_links = soup.find_all('a', class_='result__a')[:5]
        
        for i, link in enumerate(result_links, 1):
            title = link.get_text(strip=True)
            url = link['href'] if 'href' in link.attrs else '#'
            if title:
                results.append(f"{i}. {title} - {url}")
        
        if results:
            return f"πŸ”Ž Search Results for '{query}':\n" + "\n".join(results)
        return f"No results found for '{query}'. Try different keywords."
    except Exception as e:
        logger.error(f"Web scraping error: {str(e)}")
        return f"Error in backup search: {str(e)}"

@tool(name="web_search")
def search_web(query: str) -> str:
    """
    Main web search function that tries multiple methods.
    Args:
        query (str): The search query
    Returns:
        str: Formatted search results
    """
    try:
        if not query.strip():
            return "Please enter a search query."
        return search_web_duckduckgo(query)
    except Exception as e:
        logger.error(f"Error in main web search: {str(e)}")
        return f"Error processing your search: {str(e)}"

@tool(name="formatter")
def format_response(raw_steps: str) -> str:
    """
    Format the raw steps into a numbered list.
    Args:
        raw_steps (str): Raw text steps separated by periods
    Returns:
        str: Formatted numbered list of steps
    """
    try:
        if not raw_steps.strip():
            return "Please enter some text to format."
        
        steps = re.split(r'[.,;]\s+|\n', raw_steps)
        steps = [step.strip() for step in steps if step.strip()]
        
        formatted_steps = []
        for i, step in enumerate(steps, 1):
            if step:
                formatted_step = f"{i}. {step[0].upper()}{step[1:]}" 
                if not step.endswith('.'):
                    formatted_step += '.'
                formatted_steps.append(formatted_step)
        
        return "\n".join(formatted_steps)
    except Exception as e:
        logger.error(f"Error formatting steps: {str(e)}")
        return f"Error formatting your steps: {str(e)}"

# Knowledge Base Search Interface
demo1 = gr.Interface(
    fn=search_knowledge_base,
    inputs=[gr.Textbox(label="Technical Issue", placeholder="Enter your technical problem (e.g., wifi connection problem)")],
    outputs=[gr.Textbox(label="Solution")],
    title="Knowledge Base Search",
    description="Enter a technical issue to search for solutions in the knowledge base."
)

# Web Search Interface
demo2 = gr.Interface(
    fn=search_web,
    inputs=[gr.Textbox(label="Search Query", placeholder="Enter your search query (e.g., latest tech news)")],
    outputs=[gr.Textbox(label="Search Results")],
    title="Web Search",
    description="Enter a search query to get real web search results from DuckDuckGo."
)

# Response Formatter Interface
demo3 = gr.Interface(
    fn=format_response,
    inputs=[gr.Textbox(label="Raw Steps", placeholder="Enter steps separated by periods or semicolons")],
    outputs=[gr.Textbox(label="Formatted Steps")],
    title="Response Formatter",
    description="Enter raw steps separated by periods or semicolons to format them as a numbered list."
)

# Combine all interfaces using Tabs
demo = gr.TabbedInterface([demo1, demo2, demo3], ["Knowledge Base", "Web Search", "Formatter"])

if __name__ == "__main__":
    demo.launch()