suchith83 commited on
Commit
860c2fc
·
1 Parent(s): d07654f

force push to update remote with working files

Browse files
.env ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ GOOGLE_API_KEY="AIzaSyDeMN75nrEsda5UbgPJBzkf75tK1YKsS8k"
2
+ GOOGLE_CSE_ID="b11df941e76874d3f"
3
+ CEREBRAS_API_KEY="csk-8ee89j8w8kcxdj3v62er4r3jjw3ctpff88p5whfdrvkccmrf"
4
+ FIRECRAWL_API_KEY="fc-ca91b1bc71e14c6281c4fe0e1f90ed4e"
.gitignore CHANGED
@@ -1,3 +1,2 @@
1
  venv/
2
  tools/__pycache__
3
- .env
 
1
  venv/
2
  tools/__pycache__
 
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: Deepsearch
3
  emoji: 😻
4
  colorFrom: yellow
5
  colorTo: blue
@@ -7,7 +7,7 @@ sdk: gradio
7
  sdk_version: 5.32.1
8
  app_file: app.py
9
  pinned: false
10
- short_description: Searchs through web and return detailed summary on the query
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: Search
3
  emoji: 😻
4
  colorFrom: yellow
5
  colorTo: blue
 
7
  sdk_version: 5.32.1
8
  app_file: app.py
9
  pinned: false
10
+ short_description: Searchs through web and returns related links
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
__pycache__/research.cpython-312.pyc ADDED
Binary file (8.19 kB). View file
 
app.py CHANGED
@@ -1,44 +1,47 @@
1
  import gradio as gr
2
- from research import research
3
- from textblob import TextBlob
 
4
 
5
- def research_query(query):
6
- """
7
- Function to handle research queries through Gradio interface
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- Args:
10
- text (str): The query to perform websearch and provide summary.
11
- Returns:
12
- text (str): A detailed summary on the query asked by perfoming web search.
13
- """
14
- if not query.strip():
15
- return "Please enter a valid query"
16
-
17
  try:
18
- result = research(query)
19
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  except Exception as e:
21
- return f"Error processing query: {str(e)}"
22
-
23
- # Create Gradio interface
24
- demo = gr.Interface(
25
- fn=research_query,
26
- inputs=gr.Textbox(
27
- lines=3,
28
- placeholder="Enter your research query here...",
29
- label="Research Query"
30
- ),
31
- outputs=gr.Textbox(
32
- lines=10,
33
- label="Research Results"
34
- ),
35
- title="Research Assistant",
36
- description="Enter a query to get detailed research results using ReAct agent.",
37
- examples=[
38
- ["What are the latest developments in quantum computing?"],
39
- ["Explain the impact of artificial intelligence on healthcare"],
40
- ]
41
- )
42
 
43
- if __name__ == "__main__":
44
- demo.launch(mcp_server=True)
 
 
 
 
 
 
 
1
  import gradio as gr
2
+ import os
3
+ import requests
4
+ from dotenv import load_dotenv
5
 
6
+ load_dotenv(".env")
7
+
8
+ API_KEY = os.getenv("GOOGLE_API_KEY")
9
+ CSE_ID = os.getenv("GOOGLE_CSE_ID")
10
+
11
+ def search_web(query):
12
+ if not API_KEY or not CSE_ID:
13
+ return "Missing API key or Search Engine ID in .env"
14
+
15
+ params = {
16
+ "q": query,
17
+ "key": API_KEY,
18
+ "cx": CSE_ID
19
+ }
20
 
 
 
 
 
 
 
 
 
21
  try:
22
+ response = requests.get("https://www.googleapis.com/customsearch/v1", params=params)
23
+ response.raise_for_status()
24
+ data = response.json()
25
+ results = data.get("items", [])
26
+ if not results:
27
+ return "No results found."
28
+
29
+ formatted = ""
30
+ for i, result in enumerate(results[:3], 1):
31
+ title = result.get("title", "No Title")
32
+ link = result.get("link", "No Link")
33
+ snippet = result.get("snippet", "No Snippet")
34
+ formatted += f"**Result {i}**\n[{title}]({link})\n\n{snippet}\n\n---\n"
35
+ return formatted
36
+
37
  except Exception as e:
38
+ return f"Error: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
+ # Gradio UI
41
+ gr.Interface(
42
+ fn=search_web,
43
+ inputs=gr.Textbox(label="Search Query", placeholder="e.g. IPL 2025 predictions"),
44
+ outputs=gr.Markdown(label="Results"),
45
+ title="Google Search Tool",
46
+ description="Uses Google Custom Search API to fetch top 3 web results"
47
+ ).launch()
research.py DELETED
@@ -1,178 +0,0 @@
1
- import os
2
- from typing import List, Dict, Any, Optional
3
- from openai import OpenAI
4
- import json
5
- from tools import SearchTool, FetchTool, SummarizeTool
6
- from dotenv import load_dotenv
7
- import httpx
8
- from mcp.server.fastmcp import FastMCP
9
- from openai.types.chat import ChatCompletionMessage
10
- from openai.types.chat.chat_completion import ChatCompletion
11
-
12
- # mcp = FastMCP("researcher")
13
-
14
- load_dotenv()
15
-
16
- class ReActAgent:
17
- def __init__(self, client):
18
- self.client = client
19
- self.model = "qwen-3-32b"
20
- self.conversation_history: List[Dict[str, str]] = []
21
- self.max_history_length = 10 # Limit conversation history
22
- self.tools = [
23
- SearchTool(),
24
- FetchTool(),
25
- SummarizeTool()
26
- ]
27
-
28
- self.tools_json = [
29
- {
30
- "type": "function",
31
- "function": tool.to_json()
32
- }
33
- for tool in self.tools
34
- ]
35
- self.tools_map = {tool.name: tool for tool in self.tools}
36
- self.process_log = [] # Store the intermediate process
37
-
38
- def _execute_tool(self, tool_call: Dict[str, Any]) -> str:
39
- """Execute the called tool and return the result."""
40
- try:
41
- tool_name = tool_call.function.name
42
- arguments = json.loads(tool_call.function.arguments)
43
-
44
- if tool_name not in self.tools_map:
45
- return f"Error: Unknown tool: {tool_name}"
46
-
47
- tool = self.tools_map[tool_name]
48
- result = tool(**arguments)
49
-
50
- # Log the tool execution
51
- self.process_log.append({
52
- "tool": tool_name,
53
- "arguments": arguments,
54
- "result": result
55
- })
56
-
57
- return result
58
- except json.JSONDecodeError:
59
- error_msg = "Error: Invalid tool arguments format"
60
- self.process_log.append({
61
- "tool": tool_call.function.name,
62
- "arguments": tool_call.function.arguments,
63
- "result": error_msg
64
- })
65
- return error_msg
66
- except Exception as e:
67
- error_msg = f"Error executing tool: {str(e)}"
68
- self.process_log.append({
69
- "tool": tool_call.function.name,
70
- "arguments": tool_call.function.arguments,
71
- "result": error_msg
72
- })
73
- return error_msg
74
-
75
- def _truncate_history(self):
76
- """Keep only the most recent messages to prevent context overflow."""
77
- if len(self.conversation_history) > self.max_history_length:
78
- self.conversation_history = self.conversation_history[-self.max_history_length:]
79
-
80
- def _format_process_log(self) -> str:
81
- """Format the process log into a readable string."""
82
- if not self.process_log:
83
- return "No intermediate steps were taken."
84
-
85
- formatted_log = ["<intermediate_steps>"]
86
- for i, step in enumerate(self.process_log, 1):
87
- formatted_log.append(f"\nStep {i}:")
88
- formatted_log.append(f"Tool: {step['tool']}")
89
- formatted_log.append(f"Arguments: {json.dumps(step['arguments'], indent=2)}")
90
- formatted_log.append(f"Result: {step['result']}")
91
- formatted_log.append("</intermediate_steps>")
92
- return "\n".join(formatted_log)
93
-
94
- def run(self, user_input: str) -> str:
95
- """Run the ReAct loop for a single user input."""
96
- if not user_input or not isinstance(user_input, str):
97
- return "Error: Invalid input. Please provide a valid string query."
98
-
99
- try:
100
- # Reset process log for new query
101
- self.process_log = []
102
-
103
- # Add user input to conversation history
104
- self.conversation_history.append({"role": "user", "content": user_input})
105
- print(f"\n\nUser input: {user_input}\n--------------------------------\n")
106
-
107
- while True:
108
- try:
109
- # Get response from the model
110
- response: ChatCompletion = self.client.chat.completions.create(
111
- model=self.model,
112
- messages=self.conversation_history,
113
- tools=self.tools_json,
114
- )
115
-
116
- message: ChatCompletionMessage = response.choices[0].message
117
-
118
- # Add assistant's response to conversation history
119
- self.conversation_history.append({
120
- "role": "assistant",
121
- "content": message.content if message.content else "",
122
- "tool_calls": message.tool_calls
123
- })
124
-
125
- # If no tool calls, return the response with process log
126
- if not message.tool_calls:
127
- print("No tool calls\nExiting loop\n--------------------------------")
128
- final_response = message.content or "No response generated"
129
- process_log = self._format_process_log()
130
- return f"{process_log}\n\n{final_response}"
131
-
132
- # Execute the tool calls
133
- tool_results = []
134
- for tool_call in message.tool_calls:
135
- print(f"Tool call: {tool_call.function.name}\nTool arguments: {tool_call.function.arguments}")
136
- tool_result = self._execute_tool(tool_call)
137
- print(f"Tool result: {tool_result}\n--------------------------------\n")
138
- tool_results.append({
139
- "tool_call_id": tool_call.id,
140
- "role": "tool",
141
- "name": tool_call.function.name,
142
- "content": tool_result
143
- })
144
-
145
- # Add tool results to conversation history
146
- self.conversation_history.extend(tool_results)
147
- self._truncate_history()
148
-
149
- except Exception as e:
150
- error_msg = f"Error during model interaction: {str(e)}"
151
- process_log = self._format_process_log()
152
- return f"{error_msg}\n\n{process_log}"
153
-
154
- except Exception as e:
155
- error_msg = f"Error in research process: {str(e)}"
156
- process_log = self._format_process_log()
157
- return f"{error_msg}\n\n{process_log}"
158
-
159
- # @mcp.tool()
160
- def research(query: str) -> str:
161
- """Get final answer on the query after detailed research"""
162
- try:
163
- api_key = os.environ.get("CEREBRAS_API_KEY")
164
- if not api_key:
165
- return "Error: Please set CEREBRAS_API_KEY environment variable"
166
-
167
- client = OpenAI(
168
- base_url="https://api.cerebras.ai/v1",
169
- api_key=api_key
170
- )
171
-
172
- agent = ReActAgent(client)
173
- return agent.run(query)
174
- except Exception as e:
175
- return f"Error in research function: {str(e)}"
176
-
177
- # if __name__ == "__main__":
178
- # mcp.run()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_search.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv(".env")
6
+
7
+ API_KEY = os.getenv("GOOGLE_API_KEY")
8
+ CSE_ID = os.getenv("GOOGLE_CSE_ID")
9
+ # QUERY = "OpenAI GPT-4"
10
+ QUERY = "IPL 2025 final points table predictions team performance analysis"
11
+
12
+ if not API_KEY or not CSE_ID:
13
+ print("Missing API key or Search Engine ID")
14
+ exit(1)
15
+
16
+ params = {
17
+ "q": QUERY,
18
+ "key": API_KEY,
19
+ "cx": CSE_ID
20
+ }
21
+
22
+ response = requests.get("https://www.googleapis.com/customsearch/v1", params=params)
23
+
24
+ if response.status_code != 200:
25
+ print("Error:", response.status_code, response.text)
26
+ else:
27
+ data = response.json()
28
+ results = data.get("items", [])
29
+ if not results:
30
+ print("API is working, but no search results found.")
31
+ else:
32
+ for i, result in enumerate(results[:3], 1):
33
+ print(f"\nResult {i}:")
34
+ print("Title:", result.get("title"))
35
+ print("Link:", result.get("link"))
36
+ print("Snippet:", result.get("snippet"))
tools/__init__.py DELETED
@@ -1,6 +0,0 @@
1
- from .search import SearchTool
2
- from .fetch import FetchTool
3
- from .summarize import SummarizeTool
4
- from .tool import Tool
5
-
6
- __all__ = ["SearchTool", "FetchTool", "SummarizeTool", "Tool"]
 
 
 
 
 
 
 
tools/fetch.py DELETED
@@ -1,31 +0,0 @@
1
- from .tool import Tool
2
- from markdownify import markdownify
3
- import requests
4
-
5
- class FetchTool(Tool):
6
- def __init__(self):
7
- super().__init__(
8
- name="fetch",
9
- description="Fetch the content of a URL and return the markdownified version of the content",
10
- inputSchema={
11
- "type": "object",
12
- "properties": {
13
- "url": {"type": "string", "description": "The URL to fetch"}
14
- }
15
- }
16
- )
17
-
18
- def __call__(self, url: str):
19
- try:
20
- if not url:
21
- return "Error: URL parameter is required"
22
-
23
- resp = requests.get(url)
24
- resp.raise_for_status() # Raise an exception for bad status codes
25
-
26
- return markdownify(resp.text)
27
-
28
- except requests.exceptions.RequestException as e:
29
- return f"Error fetching URL: {str(e)}"
30
- except Exception as e:
31
- return f"Unexpected error while processing URL: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/search.py DELETED
@@ -1,65 +0,0 @@
1
- import requests
2
- from dotenv import load_dotenv
3
- import os
4
- from .tool import Tool
5
-
6
- load_dotenv("./.env")
7
-
8
- class SearchTool(Tool):
9
- def __init__(self):
10
- super().__init__(
11
- name="search",
12
- description="Search the web for information",
13
- inputSchema={
14
- "type": "object",
15
- "properties": {
16
- "query": {"type": "string", "description": "The search query"}
17
- }
18
- }
19
- )
20
-
21
- self.api_key = os.environ.get("GOOGLE_API_KEY")
22
- self.search_engine_id = os.environ.get("GOOGLE_CSE_ID")
23
-
24
- if not self.api_key:
25
- raise ValueError("Please set GOOGLE_API_KEY environment variable")
26
- if not self.search_engine_id:
27
- raise ValueError("Please set GOOGLE_CSE_ID environment variable")
28
-
29
- def __call__(self, query: str):
30
- try:
31
- if not query:
32
- return "Error: Query parameter is required"
33
-
34
- params = {
35
- "q": query,
36
- "key": self.api_key,
37
- "cx": self.search_engine_id
38
- }
39
-
40
- resp = requests.get("https://www.googleapis.com/customsearch/v1", params=params)
41
- resp.raise_for_status() # Raise an exception for bad status codes
42
-
43
- _results = resp.json().get("items", [])
44
- results = []
45
- for result in _results[:3]:
46
- results.append({
47
- "title": result.get("title", "No title"),
48
- "link": result.get("link", "No link"),
49
- "snippet": result.get("snippet", "No snippet")
50
- })
51
-
52
- if not results:
53
- return "No results found for the given query."
54
-
55
- # Format results as a string
56
- formatted_results = []
57
- for i, result in enumerate(results, 1):
58
- formatted_results.append(f"Result {i}:\nTitle: {result['title']}\nLink: {result['link']}\nSnippet: {result['snippet']}\n")
59
-
60
- return "\n".join(formatted_results)
61
-
62
- except requests.exceptions.RequestException as e:
63
- return f"Error during search: {str(e)}"
64
- except Exception as e:
65
- return f"Unexpected error during search: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/summarize.py DELETED
@@ -1,42 +0,0 @@
1
- from .tool import Tool
2
- from openai import OpenAI
3
- from dotenv import load_dotenv
4
- import os
5
-
6
- load_dotenv("./.env")
7
-
8
- class SummarizeTool(Tool):
9
- def __init__(self):
10
- super().__init__(
11
- name="summarize",
12
- description="Summarize the content of a URL",
13
- inputSchema={
14
- "type": "object",
15
- "properties": {
16
- "content": {"type": "string", "description": "The content to summarize"}
17
- }
18
- }
19
- )
20
-
21
- api_key = os.environ.get("CEREBRAS_API_KEY")
22
- if not api_key:
23
- raise ValueError("Please set CEREBRAS_API_KEY environment variable")
24
-
25
- self.client = OpenAI(base_url="https://api.cerebras.ai/v1", api_key=api_key)
26
-
27
- def __call__(self, **kwargs):
28
- try:
29
- content = kwargs.get("content")
30
- if not content:
31
- return "Error: Content parameter is required"
32
-
33
- response = self.client.chat.completions.create(
34
- model="qwen-3-32b",
35
- messages=[
36
- {"role": "system", "content": "You are a helpful assistant that summarizes content while keeping the all important information."},
37
- {"role": "user", "content": content}
38
- ]
39
- )
40
- return response.choices[0].message.content
41
- except Exception as e:
42
- return f"Error during summarization: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
tools/tool.py DELETED
@@ -1,15 +0,0 @@
1
- class Tool:
2
- def __init__(self, name: str, description: str, inputSchema: dict):
3
- self.name = name
4
- self.description = description
5
- self.inputSchema = inputSchema
6
-
7
- def __repr__(self):
8
- return f"Tool(name={self.name}, description={self.description}, inputSchema={self.inputSchema})"
9
-
10
- def to_json(self):
11
- return {
12
- "name": self.name,
13
- "description": self.description,
14
- "parameters": self.inputSchema
15
- }