- search_places: detect HTTP 429 and mark retryable=False to stop the
retry loop immediately instead of spiraling until MAX_ITERATIONS
- get_weather: extract collection coordinates (lat/lng from first
location with coords) and retry when LLM omits required params;
uses sync_to_async for the DB query in the async view
- AITravelChat: deduplicate context-only tools (get_trip_details,
get_weather) in the render pipeline to prevent duplicate place cards
from appearing when the retry loop causes multiple get_trip_details calls
- Tests: 5 new tests covering 429 non-retryable path and weather
coord fallback; all 39 chat tests pass