Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -74,114 +74,91 @@ def indent_code(code: str, indent: str = " ") -> str:
|
|
74 |
return "\n".join(indent + line for line in code.splitlines())
|
75 |
|
76 |
# --- Tool Definitions ---
|
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 |
-
# The exec function is used carefully here. In a production environment,
|
151 |
-
# consider a more robust and secure sandbox (e.g., Docker, dedicated service).
|
152 |
-
exec(f"def __exec_fn__():\n{indent_code(code)}\n_result_value = __exec_fn__()", globals(), env)
|
153 |
-
return str(env.get('_result_value', 'No explicit result assigned to "_result_value" variable.'))
|
154 |
-
except Exception as e:
|
155 |
-
return f"Python execution error: {str(e)}"
|
156 |
|
157 |
class VideoTranscriptionTool(BaseTool):
|
158 |
name: str = "transcript_video"
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
video_id = url_or_id.split("v=")[1].split("&")[0]
|
168 |
-
elif "youtu.be/" in url_or_id:
|
169 |
-
video_id = url_or_id.split("youtu.be/")[1].split("?")[0]
|
170 |
-
elif len(url_or_id.strip()) == 11 and not ("http://" in url_or_id or "https://" in url_or_id):
|
171 |
-
video_id = url_or_id.strip() # Assume it's just the ID
|
172 |
-
|
173 |
-
if not video_id:
|
174 |
-
return f"Invalid or unsupported YouTube URL/ID: {url_or_id}. Please provide a valid YouTube URL or 11-character ID."
|
175 |
-
|
176 |
-
try:
|
177 |
-
transcription = YouTubeTranscriptApi.get_transcript(video_id)
|
178 |
-
return " ".join([part['text'] for part in transcription])
|
179 |
-
|
180 |
-
except Exception as e:
|
181 |
-
return f"Error fetching transcript for video ID '{video_id}': {str(e)}. It might not have an English transcript, or the video is unavailable."
|
182 |
|
183 |
-
def _arun(self, *args, **kwargs):
|
184 |
-
raise NotImplementedError("Async not supported for this tool.")
|
185 |
|
186 |
# --- Agent State Definition ---
|
187 |
# --- Agent State ---
|
|
|
74 |
return "\n".join(indent + line for line in code.splitlines())
|
75 |
|
76 |
# --- Tool Definitions ---
|
77 |
+
import wikipedia # <--- Make sure you have this installed: pip install wikipedia
|
78 |
+
|
79 |
+
# --- Dummy Tools (replace with actual, robust implementations for full functionality) ---
|
80 |
+
class DuckDuckGoSearchTool(BaseTool):
|
81 |
+
name: str = "duckduckgo_search"
|
82 |
+
description: str = "Performs a DuckDuckGo web search for current events, general facts, or quick lookups."
|
83 |
+
def _run(self, query: str) -> str:
|
84 |
+
print(f"DEBUG: Executing duckduckgo_search with query: {query}")
|
85 |
+
if "current year" in query.lower():
|
86 |
+
# Current time is Saturday, June 7, 2025 at 12:21:08 PM NZST.
|
87 |
+
return "The current year is 2025."
|
88 |
+
if "capital of france" in query.lower():
|
89 |
+
return "The capital of France is Paris."
|
90 |
+
if "python creator" in query.lower():
|
91 |
+
return "Python was created by Guido van Rossum."
|
92 |
+
return f"Search result for '{query}': Information about {query}."
|
93 |
+
async def _arun(self, query: str) -> str:
|
94 |
+
raise NotImplementedError("Asynchronous execution not supported for now.")
|
95 |
+
|
96 |
+
class WikipediaSearchTool(BaseTool):
|
97 |
+
name: str = "wikipedia_search"
|
98 |
+
description: str = "Performs a Wikipedia search for encyclopedic information, historical context, or detailed topics. Returns the first 3 sentences of the summary."
|
99 |
+
def _run(self, query: str) -> str:
|
100 |
+
print(f"DEBUG: wikipedia_search called with: {query}")
|
101 |
+
try:
|
102 |
+
return wikipedia.summary(query, sentences=3)
|
103 |
+
except wikipedia.DisambiguationError as e:
|
104 |
+
return f"Disambiguation options: {', '.join(e.options[:3])}. Please refine your query."
|
105 |
+
except wikipedia.PageError:
|
106 |
+
return "Wikipedia page not found for your query."
|
107 |
+
except Exception as e:
|
108 |
+
return f"Error performing Wikipedia search: {str(e)}"
|
109 |
+
async def _arun(self, query: str) -> str:
|
110 |
+
raise NotImplementedError("Asynchronous execution not supported for now.")
|
111 |
+
|
112 |
+
class ArxivSearchTool(BaseTool):
|
113 |
+
name: str = "arxiv_search"
|
114 |
+
description: str = "Searches ArXiv for scientific papers, research, or cutting-edge technical information."
|
115 |
+
def _run(self, query: str) -> str:
|
116 |
+
print(f"DEBUG: Executing arxiv_search with query: {query}")
|
117 |
+
return f"ArXiv result for '{query}': Scientific papers related to {query}."
|
118 |
+
async def _arun(self, query: str) -> str:
|
119 |
+
raise NotImplementedError("Asynchronous execution not supported for now.")
|
120 |
+
|
121 |
+
class DocumentQATool(BaseTool):
|
122 |
+
name: str = "document_qa"
|
123 |
+
description: str = "Answers questions based on provided document text. Input format: 'document_text||question'."
|
124 |
+
def _run(self, input_str: str) -> str:
|
125 |
+
print(f"DEBUG: Executing document_qa with input: {input_str}")
|
126 |
+
if "||" not in input_str:
|
127 |
+
return "[Error] Invalid input for document_qa. Expected 'document_text||question'."
|
128 |
+
doc_text, question = input_str.split("||", 1)
|
129 |
+
if "Paris" in doc_text and "capital" in question:
|
130 |
+
return "The capital of France is Paris."
|
131 |
+
return f"Answer to '{question}' from document: '{doc_text[:50]}...' is not directly found."
|
132 |
+
async def _arun(self, query: str) -> str:
|
133 |
+
raise NotImplementedError("Asynchronous execution not supported for now.")
|
134 |
+
|
135 |
+
class PythonExecutionTool(BaseTool):
|
136 |
+
name: str = "python_execution"
|
137 |
+
description: "Executes Python code for complex calculations, data manipulation, or logical operations. Always assign the final result to a variable named '_result_value'."
|
138 |
+
def _run(self, code: str) -> str:
|
139 |
+
print(f"DEBUG: Executing python_execution with code: {code}")
|
140 |
+
try:
|
141 |
+
local_vars = {}
|
142 |
+
exec(code, globals(), local_vars)
|
143 |
+
if '_result_value' in local_vars:
|
144 |
+
return str(local_vars['_result_value'])
|
145 |
+
return "Python code executed successfully, but no _result_value was assigned."
|
146 |
+
except Exception as e:
|
147 |
+
return f"[Python Error] {str(e)}"
|
148 |
+
async def _arun(self, query: str) -> str:
|
149 |
+
raise NotImplementedError("Asynchronous execution not supported for now.")
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
class VideoTranscriptionTool(BaseTool):
|
152 |
name: str = "transcript_video"
|
153 |
+
description: str = "Transcribes video content from a given YouTube URL or video ID."
|
154 |
+
def _run(self, query: str) -> str:
|
155 |
+
print(f"DEBUG: Executing transcript_video with query: {query}")
|
156 |
+
if "youtube.com" in query or "youtu.be" in query:
|
157 |
+
return f"Transcription of YouTube video '{query}': This is a sample transcription of the video content."
|
158 |
+
return "[Error] Invalid input for transcript_video. Please provide a valid YouTube URL or video ID."
|
159 |
+
async def _arun(self, query: str) -> str:
|
160 |
+
raise NotImplementedError("Asynchronous execution not supported for now.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
|
|
|
|
|
162 |
|
163 |
# --- Agent State Definition ---
|
164 |
# --- Agent State ---
|