The Ruby client the agentic search calls into on the backend, and the React handler that enriches a selected place with full address details on the frontend.

# app/services/google_places/client.rb

# lines 120–163 (text_search_near)

def text_search_near(query:, lat:, lng:, radius_metres: 8047, type: nil, max_results: 10)
  q = query.to_s.strip
  return [] if q.blank?

  uri = URI(TEXT_SEARCH_URL)
  params = {
    key:      @api_key,
    query:    q,
    location: "#{lat},#{lng}",
    radius:   radius_metres.to_i,
    type:     type.presence
  }.compact
  uri.query = URI.encode_www_form(params)

  json = get_json_hash(uri, context: "textsearch_near")

  google_status = json["status"].to_s
  if google_status != "OK" && google_status != "ZERO_RESULTS"
    msg = json["error_message"].presence || "Google Places text search failed"
    raise Error.new(msg, http_code: 502, google_status: google_status)
  end

  results = Array(json["results"]).first(max_results.to_i)

  results.map do |place|
    next unless place.is_a?(Hash)

    geometry = place["geometry"].is_a?(Hash) ? place["geometry"] : {}
    location = geometry["location"].is_a?(Hash) ? geometry["location"] : {}
    photo0   = Array(place["photos"]).first
    primary_ref = photo0.is_a?(Hash) ? photo0["photo_reference"] : nil

    {
      place_id:                place["place_id"],
      name:                    place["name"],
      formatted_address:       place["formatted_address"],
      lat:                     location["lat"],
      lng:                     location["lng"],
      types:                   Array(place["types"]),
      rating:                  place["rating"],
      primary_photo_reference: primary_ref
    }
  end.compact
end

 Text Search (not Nearby Search) gives better semantic matching for intent-based criteria like "jazz cafe with indoor seating."

# src/components/forms/events/EventForm.tsx

# lines 718–782 (handleSelectSuggestion)

const handleSelectSuggestion = useCallback(
  (suggestion: LocationSuggestion) => {
    setSelectedSuggestion(suggestion);
    setPlacePhotos([]);
    setSearchError(null);
    setPhotoIndex(0);

    // Google Places Nearby Search returns addresses like:
    //   "123 Main St, Denver, CO 80203, USA"
    const addr = parseFormattedAddress(suggestion.formatted_address);

    // Auto-populate Step 6 location fields from the selected place, falling
    // back to what the user typed in Step 3 if parsing comes up short.
    setLocation((prev) => ({
      ...prev,
      name:          suggestion.name,
      type:          inferLocationType(suggestion.types) ?? prev.type,
      placeId:       suggestion.place_id,
      streetNumber:  addr.streetNumber,
      streetName:    addr.streetName,
      city:          addr.city          || locationCity          || prev.city,
      stateProvince: addr.stateProvince || locationStateProvince || prev.stateProvince,
      country:       addr.country       || locationCountry       || prev.country,
    }));

    // ── Address enrichment via Places Details API ──────────────────────
    // Nearby Search's "vicinity" field is abbreviated and typically omits
    // postal_code, short-form state/country. Fetch full address_components
    // for the selected place_id and merge in anything missing.
    fetchPlaceAddress(suggestion.place_id)
      .then((placeAddr: PlaceAddress) => {
        setLocation((prev) => ({
          ...prev,
          streetNumber:  placeAddr.street_number       || prev.streetNumber,
          stateProvince: placeAddr.state_province_short || placeAddr.state_province || prev.stateProvince,
          country:       placeAddr.country_short        || placeAddr.country        || prev.country,
          postalCode:    placeAddr.postal_code          || prev.postalCode,
        }));
      })
      .catch(() => {
        // Address enrichment is best-effort — silently ignore failures.
      });

    setCurrentStep(5);
  },
  [locationCity, locationStateProvince, locationCountry]
);
Optimistic fill first from the abbreviated search result, then a background Places Details call backfills the fields the abbreviated form leaves out.