juanmaguitar commited on
Commit
a33f19e
·
1 Parent(s): c2fb256

better image getter

Browse files
Files changed (2) hide show
  1. app.py +29 -25
  2. tools/image_handler.py +147 -0
app.py CHANGED
@@ -12,6 +12,7 @@ from tools.visit_webpage import VisitWebpageTool
12
  from tools.web_search import DuckDuckGoSearchTool
13
  from tools.html_to_wp_blocks import HTMLToWPBlocksTool
14
  from tools.wordpress_media import WordPressMediaTool
 
15
 
16
  from Gradio_UI import GradioUI
17
 
@@ -62,8 +63,8 @@ def quick_research(query: str, max_results: int = 3) -> str:
62
  try:
63
  # Add travel-specific terms to the query
64
  travel_query = f"{query} travel guide tourist attractions things to do"
65
- search_results = search_tool.search(
66
- travel_query, max_results=max_results)
67
 
68
  if not search_results:
69
  return "No travel information found for the given destination."
@@ -152,6 +153,17 @@ model = HfApiModel(
152
  image_generation_tool = load_tool(
153
  "agents-course/text-to-image", trust_remote_code=True)
154
 
 
 
 
 
 
 
 
 
 
 
 
155
  with open("prompts.yaml", 'r') as stream:
156
  prompt_templates = yaml.safe_load(stream)
157
 
@@ -166,7 +178,7 @@ agent = CodeAgent(
166
  tools=[
167
  final_answer,
168
  # get_current_time_in_timezone,
169
- image_generation_tool,
170
  quick_research,
171
  # get_weather,
172
  wordpress_post,
@@ -185,32 +197,24 @@ agent = CodeAgent(
185
  prompt_templates=prompt_templates
186
  )
187
 
188
- # Update system prompt to include WordPress capabilities
189
  prompt_templates["system_prompt"] += """
 
 
 
 
190
 
191
- You are also capable of managing a WordPress blog through the following tools:
192
- - wordpress_post: Publishes posts to WordPress
193
- - wordpress_media: Uploads media files to WordPress and returns attachment URLs
194
- - blog_generator: Generates AI-written blog posts
195
- - html_to_blocks: Converts HTML content to WordPress Gutenberg blocks format
196
-
197
- Always check credentials before attempting to post content.
198
-
199
- Example WordPress workflow:
200
- 1. Set credentials (first time only)
201
- 2. Generate blog content
202
- 3. Generate or prepare media files
203
- 4. Upload media files to WordPress using wordpress_media tool
204
- 5. Convert HTML content to WordPress blocks format, including media blocks
205
- 6. Publish blocks-formatted content to WordPress
206
 
207
  Remember to:
208
- - ALWAYS convert HTML content to WordPress blocks format before publishing
209
- - Upload any media files before referencing them in posts
210
- - Validate WordPress credentials before posting
211
- - Generate high-quality, relevant content
212
- - Handle errors gracefully
213
- - Provide clear status updates to the user
214
  """
215
 
216
  GradioUI(agent).launch()
 
12
  from tools.web_search import DuckDuckGoSearchTool
13
  from tools.html_to_wp_blocks import HTMLToWPBlocksTool
14
  from tools.wordpress_media import WordPressMediaTool
15
+ from tools.image_handler import ImageHandlerTool
16
 
17
  from Gradio_UI import GradioUI
18
 
 
63
  try:
64
  # Add travel-specific terms to the query
65
  travel_query = f"{query} travel guide tourist attractions things to do"
66
+ search_results = search_tool.forward(
67
+ query=travel_query, max_results=max_results)
68
 
69
  if not search_results:
70
  return "No travel information found for the given destination."
 
153
  image_generation_tool = load_tool(
154
  "agents-course/text-to-image", trust_remote_code=True)
155
 
156
+ # Create temp directory for images
157
+ image_temp_dir = os.path.join(os.getcwd(), 'temp_images')
158
+ os.makedirs(image_temp_dir, exist_ok=True)
159
+
160
+ # Initialize tools
161
+ image_handler = ImageHandlerTool(
162
+ web_search_tool=web_search,
163
+ image_gen_tool=image_generation_tool,
164
+ temp_dir=image_temp_dir
165
+ )
166
+
167
  with open("prompts.yaml", 'r') as stream:
168
  prompt_templates = yaml.safe_load(stream)
169
 
 
178
  tools=[
179
  final_answer,
180
  # get_current_time_in_timezone,
181
+ image_handler,
182
  quick_research,
183
  # get_weather,
184
  wordpress_post,
 
197
  prompt_templates=prompt_templates
198
  )
199
 
200
+ # Update system prompt to include image handling capabilities
201
  prompt_templates["system_prompt"] += """
202
+ You can now handle images in blog posts more effectively:
203
+ - image_handler: Gets images from web search or generates them if needed
204
+ - wordpress_media: Uploads media files to WordPress
205
+ - html_to_blocks: Converts HTML content to WordPress blocks, including image blocks
206
 
207
+ When creating posts with images:
208
+ 1. Use image_handler to get images (it will try web search first, then generation)
209
+ 2. Upload obtained images using wordpress_media
210
+ 3. Include the WordPress media URLs in your HTML content
211
+ 4. Convert to blocks and publish
 
 
 
 
 
 
 
 
 
 
212
 
213
  Remember to:
214
+ - Handle image search/generation errors gracefully
215
+ - Provide appropriate alt text and titles for images
216
+ - Include image attribution if using web images
217
+ - Generate images as a fallback when web search fails
 
 
218
  """
219
 
220
  GradioUI(agent).launch()
tools/image_handler.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import tempfile
3
+ import requests
4
+ from typing import Dict, List, Optional
5
+ from smolagents.tools import Tool
6
+ import time
7
+
8
+
9
+ class ImageHandlerTool(Tool):
10
+ name = "image_handler"
11
+ description = "Gets or generates images for a given topic, with fallback options"
12
+ inputs = {
13
+ 'query': {'type': 'string', 'description': 'The topic to get images for'},
14
+ 'num_images': {
15
+ 'type': 'integer',
16
+ 'description': 'Number of images to get/generate',
17
+ 'nullable': True
18
+ },
19
+ 'style': {
20
+ 'type': 'string',
21
+ 'description': 'Style for generated images (e.g., "photo", "artistic")',
22
+ 'nullable': True
23
+ }
24
+ }
25
+ output_type = "object"
26
+
27
+ def __init__(self, web_search_tool, image_gen_tool, temp_dir=None):
28
+ super().__init__()
29
+ self.web_search = web_search_tool
30
+ self.image_gen = image_gen_tool
31
+ self.temp_dir = temp_dir or tempfile.gettempdir()
32
+
33
+ def _download_image(self, url: str, filename: str) -> Optional[str]:
34
+ """Downloads an image from a URL and saves it to a temporary file"""
35
+ try:
36
+ response = requests.get(url, timeout=10)
37
+ response.raise_for_status()
38
+
39
+ # Ensure temp directory exists
40
+ os.makedirs(self.temp_dir, exist_ok=True)
41
+
42
+ # Save the image
43
+ file_path = os.path.join(self.temp_dir, filename)
44
+ with open(file_path, 'wb') as f:
45
+ f.write(response.content)
46
+ return file_path
47
+ except Exception as e:
48
+ print(f"Failed to download image from {url}: {str(e)}")
49
+ return None
50
+
51
+ def _try_web_search(self, query: str, num_images: int) -> List[Dict]:
52
+ """Attempts to find images via web search"""
53
+ results = []
54
+ try:
55
+ # Try different search queries
56
+ search_queries = [
57
+ f"{query} high quality photo",
58
+ f"{query} professional photograph",
59
+ f"{query} travel photo"
60
+ ]
61
+
62
+ for search_query in search_queries:
63
+ if len(results) >= num_images:
64
+ break
65
+
66
+ time.sleep(2) # Rate limiting
67
+ search_results = self.web_search.forward(
68
+ query=search_query, max_results=num_images)
69
+
70
+ for idx, result in enumerate(search_results):
71
+ if len(results) >= num_images:
72
+ break
73
+
74
+ if 'image_url' in result:
75
+ filename = f"{query.replace(' ', '_')}_{idx}.jpg"
76
+ file_path = self._download_image(
77
+ result['image_url'], filename)
78
+ if file_path:
79
+ results.append({
80
+ 'file_path': file_path,
81
+ 'source': 'web',
82
+ 'url': result['image_url']
83
+ })
84
+
85
+ except Exception as e:
86
+ print(f"Web search failed: {str(e)}")
87
+
88
+ return results
89
+
90
+ def _generate_images(self, query: str, num_images: int, style: str = "photo") -> List[Dict]:
91
+ """Generates images using the image generation tool"""
92
+ results = []
93
+ try:
94
+ for idx in range(num_images):
95
+ prompt = f"Generate a {style} of {query}"
96
+ response = self.image_gen.forward(prompt=prompt)
97
+
98
+ if isinstance(response, dict) and 'image_path' in response:
99
+ results.append({
100
+ 'file_path': response['image_path'],
101
+ 'source': 'generated',
102
+ 'prompt': prompt
103
+ })
104
+ elif isinstance(response, str) and os.path.exists(response):
105
+ results.append({
106
+ 'file_path': response,
107
+ 'source': 'generated',
108
+ 'prompt': prompt
109
+ })
110
+
111
+ except Exception as e:
112
+ print(f"Image generation failed: {str(e)}")
113
+
114
+ return results
115
+
116
+ def forward(self, query: str, num_images: int = 2, style: str = "photo") -> Dict:
117
+ """Gets or generates images for the query
118
+ Args:
119
+ query: What to get images of
120
+ num_images: How many images to get
121
+ style: Style for generated images
122
+ Returns:
123
+ Dict containing results and status
124
+ """
125
+ all_results = []
126
+
127
+ # First try web search
128
+ web_results = self._try_web_search(query, num_images)
129
+ all_results.extend(web_results)
130
+
131
+ # If we don't have enough images, try generation
132
+ if len(all_results) < num_images:
133
+ remaining = num_images - len(all_results)
134
+ generated = self._generate_images(query, remaining, style)
135
+ all_results.extend(generated)
136
+
137
+ if not all_results:
138
+ return {
139
+ "status": "error",
140
+ "message": "Failed to get any images"
141
+ }
142
+
143
+ return {
144
+ "status": "success",
145
+ "images": all_results,
146
+ "total": len(all_results)
147
+ }