Spaces:
Sleeping
Sleeping
File size: 17,267 Bytes
9b5b26a c19d193 6aae614 8fe992b 9b5b26a 5df72d6 9b5b26a ca69d52 9b5b26a ca69d52 9b5b26a ca69d52 9b5b26a ca69d52 9b5b26a ca69d52 8c01ffb 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 7199aa9 ca69d52 8c01ffb ca69d52 ae7a494 ca69d52 ae7a494 ca69d52 e121372 ca69d52 13d500a 8c01ffb ca69d52 9b5b26a 8c01ffb 861422e 9b5b26a 8c01ffb 8fe992b ca69d52 8c01ffb ca69d52 861422e 8fe992b 8c01ffb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 |
from smolagents import CodeAgent,DuckDuckGoSearchTool, HfApiModel,load_tool,tool
import datetime
import requests
import pytz
import yaml
from tools.final_answer import FinalAnswerTool
from Gradio_UI import GradioUI
# Below is an example of a tool that does nothing. Amaze us with your creativity !
@tool
def get_current_time_in_timezone(timezone: str) -> str:
"""Get the current time in a specified timezone.
Args:
timezone: A valid timezone string (e.g., 'America/New_York', 'Asia/Tokyo').
"""
try:
# Validate timezone
if timezone not in pytz.all_timezones:
return json.dumps({
"status": "error",
"message": f"Invalid timezone: '{timezone}'. Please provide a valid timezone like 'America/New_York'.",
"data_source": "none"
})
# Create timezone object
tz = pytz.timezone(timezone)
# Get current time in that timezone
local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S")
return json.dumps({
"status": "success",
"message": f"The current time in {timezone} is: {local_time}",
"data": {
"timezone": timezone,
"current_time": local_time
},
"data_source": "system_time"
})
except Exception as e:
return json.dumps({
"status": "error",
"message": f"Error fetching time for timezone '{timezone}': {str(e)}",
"data_source": "none"
})
@tool
def get_sunrise_time(location: str, date: str = "today") -> str:
"""Get sunrise time and photography tips for a specified location.
Args:
location: Location name or coordinates (e.g., "London" or "51.5074,-0.1278")
date: Date string (e.g., "2023-12-25" or "today" for current date)
"""
try:
# Validate date format if not "today"
if date != "today":
try:
datetime.datetime.strptime(date, "%Y-%m-%d")
date_param = f"&date={date}"
except ValueError:
return json.dumps({
"status": "error",
"message": f"Invalid date format: '{date}'. Please use YYYY-MM-DD format or 'today'.",
"data_source": "none"
})
else:
date_param = ""
# Check if location is in coordinate format
if "," in location and all(part.replace('.', '', 1).replace('-', '', 1).isdigit() for part in location.split(',')):
lat, lng = location.split(',')
location_source = "user_coordinates"
else:
# Use Nominatim API for geocoding (convert location name to coordinates)
try:
geo_response = requests.get(
f"https://nominatim.openstreetmap.org/search?q={location}&format=json&limit=1",
headers={"User-Agent": "SunrisePhotographyAssistant/1.0"}
)
geo_data = geo_response.json()
if not geo_data:
return json.dumps({
"status": "error",
"message": f"Could not find location: {location}. Please try using coordinates or check the spelling.",
"data_source": "none"
})
lat = geo_data[0]['lat']
lng = geo_data[0]['lon']
location_source = "openstreetmap_geocoding"
# Get the properly formatted name from OSM
location_name = geo_data[0].get('display_name', location)
except Exception as e:
return json.dumps({
"status": "error",
"message": f"Error geocoding location '{location}': {str(e)}",
"data_source": "none"
})
# Use coordinates to get sunrise data
try:
response = requests.get(f"https://api.sunrise-sunset.org/json?lat={lat}&lng={lng}{date_param}&formatted=0")
data = response.json()
if data.get('status') != 'OK':
return json.dumps({
"status": "error",
"message": f"Error getting sunrise data: {data.get('status', 'Unknown error')}",
"data_source": "none"
})
# Validate required fields
required_fields = ['sunrise', 'civil_twilight_begin']
for field in required_fields:
if field not in data.get('results', {}):
return json.dumps({
"status": "error",
"message": f"Missing required data field: {field}",
"data_source": "none"
})
except Exception as e:
return json.dumps({
"status": "error",
"message": f"Error fetching sunrise data: {str(e)}",
"data_source": "none"
})
# Process sunrise times (convert from UTC to local time)
sunrise_utc = datetime.datetime.fromisoformat(data['results']['sunrise'].replace('Z', '+00:00'))
civil_twilight_utc = datetime.datetime.fromisoformat(data['results']['civil_twilight_begin'].replace('Z', '+00:00'))
# Get timezone for the location (using timezonefinder library)
try:
from timezonefinder import TimezoneFinder
tf = TimezoneFinder()
timezone_str = tf.certain_timezone_at(lat=float(lat), lng=float(lng))
if not timezone_str:
timezone = pytz.UTC
timezone_name = "UTC"
timezone_confidence = "low"
timezone_note = "(Note: Could not determine exact local timezone, using UTC instead)"
else:
timezone = pytz.timezone(timezone_str)
timezone_name = timezone_str
timezone_confidence = "high"
timezone_note = ""
except Exception as e:
# Fallback to UTC if timezone lookup fails
timezone = pytz.UTC
timezone_name = "UTC"
timezone_confidence = "fallback"
timezone_note = f"(Note: Error determining timezone: {str(e)}. Using UTC instead)"
# Convert to local time
sunrise_local = sunrise_utc.astimezone(timezone)
civil_twilight_local = civil_twilight_utc.astimezone(timezone)
# Calculate golden hour (about 30 minutes after sunrise)
golden_hour_end = sunrise_local + datetime.timedelta(minutes=30)
# Format times
sunrise_time = sunrise_local.strftime("%H:%M:%S")
civil_twilight_time = civil_twilight_local.strftime("%H:%M:%S")
golden_hour_end_time = golden_hour_end.strftime("%H:%M:%S")
# Provide season-specific advice
month = sunrise_local.month
season = ""
season_tip = ""
if 3 <= month <= 5: # Spring
season = "Spring"
season_tip = "Spring sunrises often feature mist and soft light. Try to capture flowers in the foreground."
elif 6 <= month <= 8: # Summer
season = "Summer"
season_tip = "Summer sunrise comes early and temperatures rise quickly. Bring insect repellent and watch for lens fog due to humidity."
elif 9 <= month <= 11: # Fall/Autumn
season = "Fall/Autumn"
season_tip = "Fall sunrises often have fog and interesting cloud formations. Try using fallen leaves as foreground elements."
else: # Winter
season = "Winter"
season_tip = "Winter sunrises come later with cooler light. Stay warm and bring extra batteries as cold temperatures drain them faster."
# Generate factual data section
factual_data = [
f"Sunrise time: {sunrise_time} {timezone_note}",
f"Civil twilight begins: {civil_twilight_time}",
f"Golden light ends approximately: {golden_hour_end_time}",
f"Current season: {season}"
]
# Generate photography recommendations
photography_recommendations = [
f"Recommended arrival time: Civil twilight ({civil_twilight_time})",
f"{season} photography consideration: {season_tip}",
"Suggested gear: Tripod (essential), Variable ND filter, Remote shutter, Extra batteries",
"Composition tip: Look for interesting foreground elements, don't just focus on the sky",
"For best exposure, consider bracketing (HDR) or graduated filters"
]
# Add a humorous tip
humor_tips = [
"Remember to bring coffee, because your eyes might still be dreaming at dawn!",
"If you see other photographers, don't stand in front of them... unless you want to be the 'silhouette art' in their photos.",
"If your memory card fills up before the sunrise begins, that's why you should always bring two!",
"First rule of sunrise photography: Don't oversleep. Second rule: Seriously, don't oversleep!",
"Remember, the best tripod is the one you forgot at home...",
"The ultimate test for your sunrise photo: If your mom says 'Wow!' instead of just politely nodding, you've succeeded.",
"While waiting for sunrise in the frigid morning, remember that your bed misses you too.",
"If your photos come out blurry, just tell everyone it's an 'artistic style'.",
"The secret formula for the perfect sunrise shot: Weather forecast accuracy + Luck × Preparation ÷ Snooze button index"
]
# Build final output
result = f"== Sunrise Photography Guide for {location} ==\n\n"
result += "FACTUAL DATA (from sunrise-sunset.org):\n"
result += "\n".join([f"• {item}" for item in factual_data])
result += "\n\n"
result += "PHOTOGRAPHY RECOMMENDATIONS:\n"
result += "\n".join([f"• {item}" for item in photography_recommendations])
result += "\n\n"
result += "HUMOR TIP:\n"
result += f"• {random.choice(humor_tips)}\n\n"
result += "NOTE: Weather conditions can significantly affect photography opportunities and are not predicted by this tool."
# Prepare data for structured output
output_data = {
"status": "success",
"message": result,
"data": {
"location": location,
"date": date if date != "today" else datetime.datetime.now().strftime("%Y-%m-%d"),
"sunrise_time": sunrise_time,
"civil_twilight_time": civil_twilight_time,
"golden_hour_end_time": golden_hour_end_time,
"timezone": timezone_name,
"season": season
},
"data_sources": {
"location": location_source,
"astronomy": "sunrise-sunset.org",
"timezone": f"timezonefinder ({timezone_confidence} confidence)"
}
}
return json.dumps(output_data)
except Exception as e:
return json.dumps({
"status": "error",
"message": f"Error processing request: {str(e)}",
"data_source": "none"
})
@tool
def get_photography_tip() -> str:
"""Get a random sunrise photography tip."""
tips = [
"Arrive 45 minutes before sunrise to set up your equipment and have time to adjust your composition.",
"Don't just shoot at the moment of sunrise - the light changes before and after are equally worth capturing.",
"Use a tripod and remote shutter for sharp photos in low light conditions.",
"Try using foreground elements (trees, rocks, lake reflections) to add depth to your photo.",
"Use smartphone apps to predict the sunrise direction at your location and plan your composition in advance.",
"Cloudy days can produce spectacular sunrise photos - don't abandon your shoot just because there's no clear sky.",
"Light changes rapidly during sunrise - use exposure bracketing (HDR) to ensure you capture enough dynamic range.",
"Consider using a telephoto lens for sunrise shots to magnify the sun and highlight atmospheric effects near the horizon.",
"Bring graduated ND filters to balance the bright sky with a darker foreground.",
"Research your location before traveling, understanding the sun's direction and terrain to find the best shooting spots.",
"Try shooting panoramas to capture the full range of colors in the sky during sunrise.",
"Shoot in RAW format to preserve more possibilities for post-processing.",
"When shooting sunrise at the beach, check tide schedules to plan your best shooting position.",
"Winter sunrises often have the most dramatic colors and longest golden hour periods.",
"City sunrises can be spectacular - look for elevated positions that show the city skyline.",
"In windy weather, add weight to your tripod to prevent camera shake during sunrise shoots.",
"Use interval shooting (time-lapse) to document the entire sunrise process.",
"Having the sky occupy 2/3 of your composition often creates more dramatic sunrise photos.",
"During sunrise, sunlight has a reddish-yellow tone. Try setting your white balance to 'cloudy' to preserve these colors.",
"If you want to capture star trails and sunrise in one composition, you'll need a star tracker and multiple exposure techniques."
]
# Add some humorous "rescue" tips
rescue_tips = [
"If you overslept and missed the sunrise, don't worry! Claim you're practicing 'minimalist photography' - not shooting is the ultimate art form.",
"Lens fogged up? Tell everyone you invented the 'dream filter effect' - it might be trending next week.",
"If you took 100 photos and none are satisfactory, convert them to black and white - photographers call this 'artistic redemption'.",
"Forgot your memory card? Congratulations on experiencing 'mindful photography' - recording the moment with your eyes and heart.",
"Sun hiding behind clouds and not coming out? Claim you were actually there to shoot 'cloud portraits' all along.",
"Forgot to adjust ISO and got noisy photos? No problem, call it 'digital grain' and claim it's your signature style.",
"If your sunrise photos look bland, try this pro tip: Add filters until it looks like an alien sunset, then post on social media with #NoFilter.",
"Tripod collapsed? That's the universe telling you it's time to try 'stream of consciousness photography'."
]
# 20% chance to return a "rescue" tip
if random.random() < 0.2:
tip = random.choice(rescue_tips)
tip_type = "humorous_rescue"
else:
tip = random.choice(tips)
tip_type = "practical"
return json.dumps({
"status": "success",
"message": tip,
"data": {
"tip": tip,
"tip_type": tip_type
},
"data_source": "curated_collection"
})
@tool
def parse_response(response_json: str) -> str:
"""Helper tool to parse JSON responses and format them for user display.
Args:
response_json: JSON string from one of the other tools
"""
try:
data = json.loads(response_json)
# Simply return the message for successful responses
if data.get("status") == "success":
return data.get("message", "Operation completed successfully, but no message was provided.")
else:
# For error responses, provide a clear error message
return f"ERROR: {data.get('message', 'An unknown error occurred.')}"
except Exception as e:
return f"Error parsing response: {str(e)}"
final_answer = FinalAnswerTool()
# Model setup
model = HfApiModel(
max_tokens=2096,
temperature=0.5,
model_id='Qwen/Qwen2.5-Coder-32B-Instruct',
custom_role_conversions=None,
)
# Import image generation tool from Hub
image_generation_tool = load_tool("agents-course/text-to-image", trust_remote_code=True)
with open("prompts.yaml", 'r') as stream:
prompt_templates = yaml.safe_load(stream)
agent = CodeAgent(
model=model,
tools=[
get_current_time_in_timezone,
get_sunrise_time,
get_photography_tip,
parse_response, # Add helper tool for parsing
image_generation_tool,
final_answer
],
max_steps=6,
verbosity_level=1,
grammar=None,
planning_interval=None,
name="Sunrise Photography Assistant",
description="An intelligent assistant that helps photographers find the best times for sunrise photography and provides professional advice",
prompt_templates=prompt_templates
)
GradioUI(agent).launch() |