mohammedelfeky-ai commited on
Commit
f12b87d
·
verified ·
1 Parent(s): 057daa4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +86 -76
app.py CHANGED
@@ -8,56 +8,36 @@ 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 tools.web_search import DuckDuckGoSearchTool
11
- from smolagents import GradioUI
12
  import gradio as gr
13
  import json # Not used directly in the provided snippet, but can be common
14
- import os # os is imported twice, which is fine.
15
  from typing import Dict, List, Optional, Union, Any
16
  import re # Added for regex in Gradio UI if not already globally available
17
 
18
- '''
19
- # Below is an example of a tool that does nothing. Amaze us with your creativity !
20
- @tool
21
- def my_custom_tool(x:str, y:int)-> int: #it's import to specify the return type
22
- #Keep this format for the description / args / args description but feel free to modify the tool
23
- """A tool that does nothing yet
24
- Args:
25
- arg1: the first argument
26
- arg2: the second argument
27
- """
28
- return "What magic will you build ?"
29
- @tool
30
- def get_current_time_in_timezone(timezone: str) -> str:
31
- """A tool that fetches the current local time in a specified timezone.
32
- Args:
33
- timezone: A string representing a valid timezone (e.g., 'America/New_York').
34
- """
35
- try:
36
- # Create timezone object
37
- tz = pytz.timezone(timezone)
38
- # Get current time in that timezone
39
- local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
40
- return f"The current local time in {timezone} is: {local_time}"
41
- except Exception as e:
42
- return f"Error fetching time for timezone '{timezone}': {str(e)}"
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', 'pdf', or 'txt'.
51
  """
52
  try:
53
- # Create a temp directory to store files
54
  temp_dir = tempfile.mkdtemp()
 
55
 
56
  if format.lower() == "txt":
57
- txt_path = os.path.join(temp_dir, "generated_document.txt")
58
- with open(txt_path, "w", encoding="utf-8") as f:
59
  f.write(text)
60
- return txt_path
 
61
 
62
  elif format.lower() in ["docx", "pdf"]:
63
  try:
@@ -68,7 +48,6 @@ def create_document(text: str, format: str = "docx") -> str:
68
  f"Please install it (e.g., 'pip install python-docx'). "
69
  f"You can try creating a 'txt' file instead by specifying format='txt'.")
70
 
71
- # Create a new document
72
  doc = docx.Document()
73
  doc.add_heading('Generated Document', 0)
74
  style = doc.styles['Normal']
@@ -77,25 +56,30 @@ def create_document(text: str, format: str = "docx") -> str:
77
  font.size = Pt(11)
78
 
79
  for paragraph in text.split('\n'):
80
- if paragraph.strip(): # Skip empty paragraphs
81
  doc.add_paragraph(paragraph)
82
 
83
- docx_path = os.path.join(temp_dir, "generated_document.docx")
84
  doc.save(docx_path)
85
-
 
86
  if format.lower() == "pdf":
87
  try:
88
  from docx2pdf import convert
89
- pdf_path = os.path.join(temp_dir, "generated_document.pdf")
90
  convert(docx_path, pdf_path)
91
- # Optional: os.remove(docx_path) # If PDF is main target and DOCX is intermediate
92
  return pdf_path
93
  except ImportError:
94
- return (f"ERROR: PDF conversion requires the 'docx2pdf' package. "
95
- f"Please install it (e.g., 'pip install docx2pdf'). "
96
- f"Document saved as DOCX instead at: {docx_path}")
 
 
97
  except Exception as e_pdf:
98
- return f"Error converting DOCX to PDF: {str(e_pdf)}. Document saved as DOCX at: {docx_path}"
 
 
99
 
100
  return docx_path
101
 
@@ -103,68 +87,94 @@ def create_document(text: str, format: str = "docx") -> str:
103
  return f"Error: Unsupported format '{format}'. Supported formats are 'docx', 'pdf', 'txt'."
104
 
105
  except Exception as e:
106
- # Catch-all for other unexpected errors during file operations, etc.
107
  return f"Error creating document: {str(e)}"
108
 
109
- # Custom file download tool to help with file handling
110
  @tool
111
  def get_file_download_link(file_path: str) -> str:
112
- """Creates a download link for a file.
113
-
114
  Args:
115
- file_path: Path to the file that should be made available for download
116
  """
117
  if not os.path.exists(file_path):
 
118
  return f"Error: File not found at {file_path}"
119
 
120
- # Get file extension and set up appropriate mime type
121
  _, file_extension = os.path.splitext(file_path)
122
  mime_types = {
123
  '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
124
  '.pdf': 'application/pdf',
125
- '.txt': 'text/plain', # Added for .txt files
126
  }
127
  mime_type = mime_types.get(file_extension.lower(), 'application/octet-stream')
128
-
129
- # Return information that can be used by the agent to instruct the user
130
- return f"File ready for download: {os.path.basename(file_path)} ({mime_type})"
131
 
132
-
133
  final_answer = FinalAnswerTool()
134
- web_search=DuckDuckGoSearchTool() # This was commented out in original, keeping it so
135
  visit_webpage=VisitWebpageTool()
136
 
137
- # 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:
138
- # model_id='https://pflgm2locj2t89co.us-east-1.aws.endpoints.huggingface.cloud'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
 
140
  model = LiteLLMModel(
141
- model_id="gemini/gemini-2.0-flash", # As per original, though gemini-1.5-flash-latest might be more common
142
  api_key=os.getenv("GEMINI_KEY"),
143
- max_tokens=8192,
144
- temperature=0.7
145
  )
146
 
 
 
 
 
 
 
 
 
147
 
148
- # Import tool from Hub
149
- # image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True) # This tool is loaded but not added to the agent
150
-
151
- with open("prompts.yaml", 'r') as stream:
152
- prompt_templates = yaml.safe_load(stream)
 
 
 
153
 
154
- #,web_search
 
 
 
155
 
156
  agent = CodeAgent(
157
  model=model,
158
- tools=[final_answer,visit_webpage,create_document,get_file_download_link,web_search], ## add your tools here (don't remove final answer)
159
- max_steps=10,
160
- verbosity_level=1,
161
  prompt_templates=prompt_templates
162
  )
163
 
164
-
165
-
166
- # Ensure this conditional execution if the script can also be imported
167
  if __name__ == "__main__":
168
- # Note: The original script had GradioUI(agent).launch() directly.
169
- # Using the custom UI:
170
- GradioUI(agent).launch()
 
 
 
 
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 tools.web_search import DuckDuckGoSearchTool
11
+
12
  import gradio as gr
13
  import json # Not used directly in the provided snippet, but can be common
14
+
15
  from typing import Dict, List, Optional, Union, Any
16
  import re # Added for regex in Gradio UI if not already globally available
17
 
18
+ from smolagents.tools import Tool as SmolToolBase # Renamed to avoid conflict with @tool decorator
19
+ from smolagents.agent_types import AgentAudio, AgentImage, AgentText # For GradioUI output handling
20
+
21
+ from Gradio_UI import GradioUI # This will import the class from your modified file
22
+
23
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  @tool
25
  def create_document(text: str, format: str = "docx") -> str:
26
  """Creates a document with the provided text and allows download.
 
27
  Args:
28
  text: The text content to write to the document.
29
+ format: The output format, either 'docx', 'pdf', or 'txt'. Default is 'docx'.
30
  """
31
  try:
 
32
  temp_dir = tempfile.mkdtemp()
33
+ file_name = "generated_document" # Consistent filename
34
 
35
  if format.lower() == "txt":
36
+ path = os.path.join(temp_dir, f"{file_name}.txt")
37
+ with open(path, "w", encoding="utf-8") as f:
38
  f.write(text)
39
+ print(f"Document created (txt): {path}")
40
+ return path
41
 
42
  elif format.lower() in ["docx", "pdf"]:
43
  try:
 
48
  f"Please install it (e.g., 'pip install python-docx'). "
49
  f"You can try creating a 'txt' file instead by specifying format='txt'.")
50
 
 
51
  doc = docx.Document()
52
  doc.add_heading('Generated Document', 0)
53
  style = doc.styles['Normal']
 
56
  font.size = Pt(11)
57
 
58
  for paragraph in text.split('\n'):
59
+ if paragraph.strip():
60
  doc.add_paragraph(paragraph)
61
 
62
+ docx_path = os.path.join(temp_dir, f"{file_name}.docx")
63
  doc.save(docx_path)
64
+ print(f"Document created (docx): {docx_path}")
65
+
66
  if format.lower() == "pdf":
67
  try:
68
  from docx2pdf import convert
69
+ pdf_path = os.path.join(temp_dir, f"{file_name}.pdf")
70
  convert(docx_path, pdf_path)
71
+ print(f"Document converted to PDF: {pdf_path}")
72
  return pdf_path
73
  except ImportError:
74
+ err_msg = (f"ERROR: PDF conversion requires the 'docx2pdf' package. "
75
+ f"Please install it (e.g., 'pip install docx2pdf'). "
76
+ f"Document saved as DOCX instead at: {docx_path}")
77
+ print(err_msg)
78
+ return err_msg # Or return docx_path with a note
79
  except Exception as e_pdf:
80
+ err_msg = f"Error converting DOCX to PDF: {str(e_pdf)}. Document saved as DOCX at: {docx_path}"
81
+ print(err_msg)
82
+ return err_msg # Or return docx_path
83
 
84
  return docx_path
85
 
 
87
  return f"Error: Unsupported format '{format}'. Supported formats are 'docx', 'pdf', 'txt'."
88
 
89
  except Exception as e:
90
+ print(f"General error in create_document: {str(e)}")
91
  return f"Error creating document: {str(e)}"
92
 
 
93
  @tool
94
  def get_file_download_link(file_path: str) -> str:
95
+ """Informs that a file is ready for download and its type. (Used by agent to tell user).
 
96
  Args:
97
+ file_path: Path to the file that should be made available for download.
98
  """
99
  if not os.path.exists(file_path):
100
+ print(f"get_file_download_link: File not found at {file_path}")
101
  return f"Error: File not found at {file_path}"
102
 
 
103
  _, file_extension = os.path.splitext(file_path)
104
  mime_types = {
105
  '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
106
  '.pdf': 'application/pdf',
107
+ '.txt': 'text/plain',
108
  }
109
  mime_type = mime_types.get(file_extension.lower(), 'application/octet-stream')
110
+ msg = f"File '{os.path.basename(file_path)}' is ready for download (type: {mime_type})."
111
+ print(f"get_file_download_link: {msg}")
112
+ return msg
113
 
 
114
  final_answer = FinalAnswerTool()
115
+ web_search=DuckDuckGoSearchTool()
116
  visit_webpage=VisitWebpageTool()
117
 
118
+ # Load image generation tool from Hub
119
+ try:
120
+ image_generation_tool = load_tool("stabilityai/stable-diffusion-xl-base-1.0", trust_remote_code=True)
121
+ # Common alternative: "agents-course/text-to-image" (uses a smaller SD model)
122
+ # image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
123
+ print(f"Successfully loaded image generation tool. Name: {getattr(image_generation_tool, 'name', 'N/A')}")
124
+ except Exception as e:
125
+ print(f"Error loading image generation tool: {e}")
126
+ print("Image generation will not be available.")
127
+ image_generation_tool = None # Set to None if loading fails
128
+
129
+ # --- Configure LLM Model ---
130
+ # Ensure GEMINI_KEY is set in your environment variables
131
+ if not os.getenv("GEMINI_KEY"):
132
+ print("CRITICAL: GEMINI_KEY environment variable not set. The LLM will not work.")
133
+ # exit(1) # Or handle gracefully
134
 
135
  model = LiteLLMModel(
136
+ model_id="gemini/gemini-1.5-flash-latest", # Using a common and capable Gemini model
137
  api_key=os.getenv("GEMINI_KEY"),
138
+ max_tokens=4096, # Max output tokens for the LLM
139
+ temperature=0.6 # Slightly lower temperature for more factual tool use
140
  )
141
 
142
+ # --- Load Prompts ---
143
+ prompts_file = "prompts.yaml"
144
+ if not os.path.exists(prompts_file):
145
+ print(f"Warning: '{prompts_file}' not found. Using default agent prompts.")
146
+ prompt_templates = None # Agent will use its defaults
147
+ else:
148
+ with open(prompts_file, 'r') as stream:
149
+ prompt_templates = yaml.safe_load(stream)
150
 
151
+ # --- Initialize Agent ---
152
+ agent_tools = [
153
+ final_answer_tool,
154
+ web_search_tool,
155
+ visit_webpage_tool,
156
+ create_document, # This is a @tool decorated function, so it's directly usable
157
+ get_file_download_link, # Also a @tool decorated function
158
+ ]
159
 
160
+ if image_generation_tool:
161
+ agent_tools.append(image_generation_tool)
162
+ else:
163
+ print("Note: Image generation tool was not loaded, so it's not added to the agent.")
164
 
165
  agent = CodeAgent(
166
  model=model,
167
+ tools=agent_tools,
168
+ max_steps=10, # Max iterations for the agent
169
+ verbosity_level=1, # Set to 1 or higher to populate interaction_logs for GradioUI
170
  prompt_templates=prompt_templates
171
  )
172
 
173
+ # --- Main Application Entry Point ---
 
 
174
  if __name__ == "__main__":
175
+ print("Starting Gradio UI...")
176
+ # Initialize GradioUI with the agent
177
+ # The GradioUI class should be imported from your modified Gradio_UI.py
178
+ # Ensure Gradio_UI.py is in the same directory or python path
179
+ ui = GradioUI(agent, file_upload_folder="uploaded_files") # Enable file uploads
180
+ ui.launch() # share=False is default and safer for Spaces