Add beli_category (RES/DES/BAR/BAK) to restaurant records

Store Beli's category code on each ranking so the agent can filter by type
(restaurant/bar/cafe/bakery). Category label shown in tool output.

Requires migration for beli_category column + updated unique constraint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-17 22:09:09 -04:00
parent aa61ec54b9
commit c682d2b320
3 changed files with 54 additions and 11 deletions
+2
View File
@@ -86,6 +86,7 @@ async def _refresh_friend_sample(profile: BeliProfile, access_token: str) -> int
beli_business_id=biz["beli_business_id"],
status=BeliStatus.BEEN,
friend_beli_user_id=friend_id,
beli_category=category,
defaults={
"friend_name": friend_name,
"name": biz["name"],
@@ -136,6 +137,7 @@ async def refresh_profile(profile_id: str) -> dict:
profile=profile,
beli_business_id=biz["beli_business_id"],
status=BeliStatus.BEEN,
beli_category=category,
defaults={
"name": biz["name"],
"city": biz["city"],
+9 -1
View File
@@ -38,6 +38,8 @@ class BeliRestaurant(Model):
# Empty string = profile owner's own ranking; UUID string = a followed user's ranking
friend_beli_user_id = fields.CharField(max_length=255, default="")
friend_name = fields.CharField(max_length=255, null=True)
# Beli category code: RES / DES / BAR / BAK; empty for bookmarks
beli_category = fields.CharField(max_length=10, default="")
name = fields.CharField(max_length=500)
city = fields.CharField(max_length=255, null=True)
neighborhood = fields.CharField(max_length=255, null=True)
@@ -54,5 +56,11 @@ class BeliRestaurant(Model):
class Meta:
table = "beli_restaurants"
unique_together = (
("profile", "beli_business_id", "status", "friend_beli_user_id"),
(
"profile",
"beli_business_id",
"status",
"friend_beli_user_id",
"beli_category",
),
)
+43 -10
View File
@@ -1288,31 +1288,57 @@ if google_gmail_enabled:
tools.extend([gmail_search_emails, gmail_get_email])
_BELI_CATEGORY_CODES = {
"restaurant": "RES",
"restaurants": "RES",
"food": "RES",
"dessert": "DES",
"desserts": "DES",
"cafe": "DES",
"cafes": "DES",
"coffee": "DES",
"bar": "BAR",
"bars": "BAR",
"drinks": "BAR",
"bakery": "BAK",
"bakeries": "BAK",
}
_BELI_CATEGORY_LABELS = {
"RES": "Restaurant",
"DES": "Cafe/Dessert",
"BAR": "Bar",
"BAK": "Bakery",
}
@tool
async def beli_search_restaurants(
status: str = "",
city: str = "",
cuisine: str = "",
name: str = "",
category: str = "",
include_friends: bool = True,
) -> str:
"""Search restaurant recommendations from Beli profiles.
"""Search restaurant, bar, cafe, and bakery recommendations from Beli profiles.
Use this tool when the user asks about:
- Restaurant recommendations or suggestions
- Restaurant, bar, cafe, or bakery recommendations
- Places they've been to or want to try
- Dining recommendations in a specific city or cuisine
- What restaurants their friends have rated on Beli
- Dining or drinks recommendations in a specific city or cuisine
- What places their friends have rated on Beli
Args:
status: Filter by status — 'been' (ranked places) or 'want_to_try' (bookmarks). Leave blank for all.
city: Filter by city name (partial match). Leave blank for all cities.
cuisine: Filter by cuisine type (partial match). Leave blank for all cuisines.
name: Filter by restaurant name (partial match). Leave blank for all.
name: Filter by place name (partial match). Leave blank for all.
category: Filter by type — 'restaurant', 'bar', 'cafe', 'bakery', 'dessert'. Leave blank for all.
include_friends: Include friends' rankings (default True). Set False for own lists only.
Returns:
Formatted list of matching restaurants with ratings, cuisine, location, and attribution.
Formatted list of matching places with ratings, type, location, and attribution.
"""
from blueprints.beli.models import BeliRestaurant, BeliStatus
@@ -1328,6 +1354,11 @@ async def beli_search_restaurants(
except ValueError:
return f"Invalid status '{status}'. Valid values: been, want_to_try."
if category:
code = _BELI_CATEGORY_CODES.get(category.lower().strip())
if code:
qs = qs.filter(beli_category=code)
if city:
qs = qs.filter(city__icontains=city)
if name:
@@ -1346,7 +1377,7 @@ async def beli_search_restaurants(
]
if not restaurants:
return "No matching restaurants found in your Beli lists."
return "No matching places found in your Beli lists."
lines = []
for r in restaurants:
@@ -1356,12 +1387,14 @@ async def beli_search_restaurants(
cuisines = ", ".join(r.cuisine) if r.cuisine else ""
price = f" ({r.price_range})" if r.price_range else ""
status_label = r.status.value.replace("_", " ").title()
cat_label = _BELI_CATEGORY_LABELS.get(r.beli_category, "")
cat = f" [{cat_label}]" if cat_label else ""
attribution = (
f" [via {r.friend_name or r.friend_beli_user_id}]"
if r.friend_beli_user_id
else ""
)
line = f"• {r.name}{price}{rank}{score} [{status_label}]{attribution}"
line = f"• {r.name}{price}{rank}{score}{cat} [{status_label}]{attribution}"
if location:
line += f" — {location}"
if cuisines:
@@ -1370,10 +1403,10 @@ async def beli_search_restaurants(
line += f"\n Note: {r.notes}"
lines.append(line)
return f"Found {len(lines)} restaurant(s):\n\n" + "\n".join(lines)
return f"Found {len(lines)} place(s):\n\n" + "\n".join(lines)
except Exception as e:
return f"Error searching Beli restaurants: {e}"
return f"Error searching Beli places: {e}"
tools.append(beli_search_restaurants)