mohammedelfeky-ai commited on
Commit
0aecc76
·
verified ·
1 Parent(s): 4a343f3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +81 -61
app.py CHANGED
@@ -1,17 +1,18 @@
1
  from smolagents import CodeAgent, DuckDuckGoSearchTool, load_tool, tool, LiteLLMModel
2
  import datetime
3
- import requests
4
- import pytz
5
  import yaml
6
  import os
7
  import tempfile
8
- from tools.final_answer import FinalAnswerTool
9
- from tools.visit_webpage import VisitWebpageTool
10
  from smolagents import GradioUI
11
  import gradio as gr
12
- import json
13
- import os
14
  from typing import Dict, List, Optional, Union, Any
 
15
 
16
  '''
17
  # Below is an example of a tool that does nothing. Amaze us with your creativity !
@@ -24,7 +25,6 @@ def my_custom_tool(x:str, y:int)-> int: #it's import to specify the return type
24
  arg2: the second argument
25
  """
26
  return "What magic will you build ?"
27
-
28
  @tool
29
  def get_current_time_in_timezone(timezone: str) -> str:
30
  """A tool that fetches the current local time in a specified timezone.
@@ -39,58 +39,70 @@ def get_current_time_in_timezone(timezone: str) -> str:
39
  return f"The current local time in {timezone} is: {local_time}"
40
  except Exception as e:
41
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
42
-
43
  '''
44
  @tool
45
  def create_document(text: str, format: str = "docx") -> str:
46
  """Creates a document with the provided text and allows download.
47
 
48
  Args:
49
- text: The text content to write to the document
50
- format: The output format, either 'docx' or 'pdf'
51
  """
52
  try:
53
- import docx
54
- from docx.shared import Pt
55
-
56
  # Create a temp directory to store files
57
  temp_dir = tempfile.mkdtemp()
58
 
59
- # Create a new document
60
- doc = docx.Document()
61
-
62
- # Add a heading
63
- doc.add_heading('Generated Document', 0)
64
-
65
- # Set font style for regular text
66
- style = doc.styles['Normal']
67
- font = style.font
68
- font.name = 'Calibri'
69
- font.size = Pt(11)
70
-
71
- # Add paragraphs from the input text
72
- # Split by newlines to maintain paragraph structure
73
- for paragraph in text.split('\n'):
74
- if paragraph.strip(): # Skip empty paragraphs
75
- doc.add_paragraph(paragraph)
76
-
77
- # Save the document
78
- docx_path = os.path.join(temp_dir, "generated_document.docx")
79
- doc.save(docx_path)
80
-
81
- # Convert to PDF if requested
82
- if format.lower() == "pdf":
83
  try:
84
- from docx2pdf import convert
85
- pdf_path = os.path.join(temp_dir, "generated_document.pdf")
86
- convert(docx_path, pdf_path)
87
- return pdf_path
88
  except ImportError:
89
- return f"PDF conversion requires docx2pdf package. Document saved as DOCX instead at: {docx_path}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
- return docx_path
92
-
 
93
  except Exception as e:
 
94
  return f"Error creating document: {str(e)}"
95
 
96
  # Custom file download tool to help with file handling
@@ -109,6 +121,7 @@ def get_file_download_link(file_path: str) -> str:
109
  mime_types = {
110
  '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
111
  '.pdf': 'application/pdf',
 
112
  }
113
  mime_type = mime_types.get(file_extension.lower(), 'application/octet-stream')
114
 
@@ -117,14 +130,14 @@ def get_file_download_link(file_path: str) -> str:
117
 
118
 
119
  final_answer = FinalAnswerTool()
120
- #web_search=DuckDuckGoSearchTool()
121
  visit_webpage=VisitWebpageTool()
122
 
123
  # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
124
  # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
125
 
126
  model = LiteLLMModel(
127
- model_id="gemini/gemini-2.0-flash",
128
  api_key=os.getenv("GEMINI_KEY"),
129
  max_tokens=8192,
130
  temperature=0.7
@@ -132,7 +145,7 @@ model = LiteLLMModel(
132
 
133
 
134
  # Import tool from Hub
135
- image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
136
 
137
  with open("prompts.yaml", 'r') as stream:
138
  prompt_templates = yaml.safe_load(stream)
@@ -167,38 +180,45 @@ class CustomGradioUI(GradioUI):
167
  file_output = gr.File(label="Generated Document", visible=False)
168
 
169
  # Store the latest file path
170
- self._latest_file_path = None
171
 
172
  def respond(message, chat_history):
173
  agent_response = self.agent.run(message)
174
  chat_history.append((message, agent_response))
175
 
176
- # Check if response contains a file path
177
- import re
178
- file_paths = re.findall(r'File ready for download: .+ \((application/[\w.+-]+)\)', agent_response)
179
-
180
  show_download = False
181
- self._latest_file_path = None
182
-
183
- # Look for generated file paths in the response
184
- paths = re.findall(r'/tmp/\w+/generated_document\.(docx|pdf)', agent_response)
 
 
 
185
  if paths:
186
- self._latest_file_path = paths[0]
187
  show_download = True
 
 
188
 
189
- return chat_history, gr.Button.update(visible=show_download), gr.File.update(visible=False)
190
 
191
  def prepare_download():
192
- if self._latest_file_path:
193
  return gr.File.update(value=self._latest_file_path, visible=True)
 
 
194
  return gr.File.update(visible=False)
195
 
196
  # Connect the components
197
  msg.submit(respond, [msg, chatbot], [chatbot, download_btn, file_output])
198
  download_btn.click(prepare_download, [], [file_output])
199
 
200
- gr.Markdown("Powered by smolagents and Qwen")
201
 
202
  return interface
203
 
204
- GradioUI(agent).launch()
 
 
 
 
 
1
  from smolagents import CodeAgent, DuckDuckGoSearchTool, load_tool, tool, LiteLLMModel
2
  import datetime
3
+ import requests # Not used in the provided snippet directly, but often a common import
4
+ import pytz # Used in the commented-out example tool
5
  import yaml
6
  import os
7
  import tempfile
8
+ from tools.final_answer import FinalAnswerTool # Assuming this exists in ./tools/final_answer.py
9
+ from tools.visit_webpage import VisitWebpageTool # Assuming this exists in ./tools/visit_webpage.py
10
  from smolagents import GradioUI
11
  import gradio as gr
12
+ import json # Not used directly in the provided snippet, but can be common
13
+ import os # os is imported twice, which is fine.
14
  from typing import Dict, List, Optional, Union, Any
15
+ import re # Added for regex in Gradio UI if not already globally available
16
 
17
  '''
18
  # Below is an example of a tool that does nothing. Amaze us with your creativity !
 
25
  arg2: the second argument
26
  """
27
  return "What magic will you build ?"
 
28
  @tool
29
  def get_current_time_in_timezone(timezone: str) -> str:
30
  """A tool that fetches the current local time in a specified timezone.
 
39
  return f"The current local time in {timezone} is: {local_time}"
40
  except Exception as e:
41
  return f"Error fetching time for timezone '{timezone}': {str(e)}"
 
42
  '''
43
  @tool
44
  def create_document(text: str, format: str = "docx") -> str:
45
  """Creates a document with the provided text and allows download.
46
 
47
  Args:
48
+ text: The text content to write to the document.
49
+ format: The output format, either 'docx', 'pdf', or 'txt'.
50
  """
51
  try:
 
 
 
52
  # Create a temp directory to store files
53
  temp_dir = tempfile.mkdtemp()
54
 
55
+ if format.lower() == "txt":
56
+ txt_path = os.path.join(temp_dir, "generated_document.txt")
57
+ with open(txt_path, "w", encoding="utf-8") as f:
58
+ f.write(text)
59
+ return txt_path
60
+
61
+ elif format.lower() in ["docx", "pdf"]:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  try:
63
+ import docx
64
+ from docx.shared import Pt
 
 
65
  except ImportError:
66
+ return (f"ERROR: To create DOCX or PDF files, the 'python-docx' package is required. "
67
+ f"Please install it (e.g., 'pip install python-docx'). "
68
+ f"You can try creating a 'txt' file instead by specifying format='txt'.")
69
+
70
+ # Create a new document
71
+ doc = docx.Document()
72
+ doc.add_heading('Generated Document', 0)
73
+ style = doc.styles['Normal']
74
+ font = style.font
75
+ font.name = 'Calibri'
76
+ font.size = Pt(11)
77
+
78
+ for paragraph in text.split('\n'):
79
+ if paragraph.strip(): # Skip empty paragraphs
80
+ doc.add_paragraph(paragraph)
81
+
82
+ docx_path = os.path.join(temp_dir, "generated_document.docx")
83
+ doc.save(docx_path)
84
+
85
+ if format.lower() == "pdf":
86
+ try:
87
+ from docx2pdf import convert
88
+ pdf_path = os.path.join(temp_dir, "generated_document.pdf")
89
+ convert(docx_path, pdf_path)
90
+ # Optional: os.remove(docx_path) # If PDF is main target and DOCX is intermediate
91
+ return pdf_path
92
+ except ImportError:
93
+ return (f"ERROR: PDF conversion requires the 'docx2pdf' package. "
94
+ f"Please install it (e.g., 'pip install docx2pdf'). "
95
+ f"Document saved as DOCX instead at: {docx_path}")
96
+ except Exception as e_pdf:
97
+ return f"Error converting DOCX to PDF: {str(e_pdf)}. Document saved as DOCX at: {docx_path}"
98
+
99
+ return docx_path
100
 
101
+ else:
102
+ return f"Error: Unsupported format '{format}'. Supported formats are 'docx', 'pdf', 'txt'."
103
+
104
  except Exception as e:
105
+ # Catch-all for other unexpected errors during file operations, etc.
106
  return f"Error creating document: {str(e)}"
107
 
108
  # Custom file download tool to help with file handling
 
121
  mime_types = {
122
  '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
123
  '.pdf': 'application/pdf',
124
+ '.txt': 'text/plain', # Added for .txt files
125
  }
126
  mime_type = mime_types.get(file_extension.lower(), 'application/octet-stream')
127
 
 
130
 
131
 
132
  final_answer = FinalAnswerTool()
133
+ #web_search=DuckDuckGoSearchTool() # This was commented out in original, keeping it so
134
  visit_webpage=VisitWebpageTool()
135
 
136
  # If the agent does not answer, the model is overloaded, please use another model or the following Hugging Face Endpoint that also contains qwen2.5 coder:
137
  # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
138
 
139
  model = LiteLLMModel(
140
+ model_id="gemini/gemini-2.0-flash", # As per original, though gemini-1.5-flash-latest might be more common
141
  api_key=os.getenv("GEMINI_KEY"),
142
  max_tokens=8192,
143
  temperature=0.7
 
145
 
146
 
147
  # Import tool from Hub
148
+ # image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True) # This tool is loaded but not added to the agent
149
 
150
  with open("prompts.yaml", 'r') as stream:
151
  prompt_templates = yaml.safe_load(stream)
 
180
  file_output = gr.File(label="Generated Document", visible=False)
181
 
182
  # Store the latest file path
183
+ self._latest_file_path = None # Instance variable to store path between calls
184
 
185
  def respond(message, chat_history):
186
  agent_response = self.agent.run(message)
187
  chat_history.append((message, agent_response))
188
 
 
 
 
 
189
  show_download = False
190
+ # Reset latest_file_path to ensure it's fresh for each response
191
+ # self._latest_file_path = None # Actually, should be set if file is found
192
+
193
+ # Look for generated file paths in the agent's response.
194
+ # tempfile.mkdtemp() usually creates paths like /tmp/some_random_string/
195
+ # The tool consistently names files "generated_document.ext"
196
+ paths = re.findall(r'/tmp/[^/]+/generated_document\.(docx|pdf|txt)', agent_response)
197
  if paths:
198
+ self._latest_file_path = paths[0] # Store the full path
199
  show_download = True
200
+ else:
201
+ self._latest_file_path = None # Clear if no path found in this response
202
 
203
+ return chat_history, gr.Button.update(visible=show_download), gr.File.update(visible=False) # Keep file output hidden until download clicked
204
 
205
  def prepare_download():
206
+ if self._latest_file_path and os.path.exists(self._latest_file_path):
207
  return gr.File.update(value=self._latest_file_path, visible=True)
208
+ # Handle case where file might have been cleaned up or path is stale
209
+ gr.Warning("File not available for download. It might have been temporary or an error occurred.")
210
  return gr.File.update(visible=False)
211
 
212
  # Connect the components
213
  msg.submit(respond, [msg, chatbot], [chatbot, download_btn, file_output])
214
  download_btn.click(prepare_download, [], [file_output])
215
 
216
+ gr.Markdown("Powered by smolagents and Qwen") # Qwen is mentioned, perhaps the HF endpoint uses it.
217
 
218
  return interface
219
 
220
+ # Ensure this conditional execution if the script can also be imported
221
+ if __name__ == "__main__":
222
+ # Note: The original script had GradioUI(agent).launch() directly.
223
+ # Using the custom UI:
224
+ CustomGradioUI(agent).launch()