ChitiN7 commited on
Commit
fe53a0d
·
verified ·
1 Parent(s): 04133cb

Update planner_agent_centralized.py

Browse files
Files changed (1) hide show
  1. planner_agent_centralized.py +36 -10
planner_agent_centralized.py CHANGED
@@ -2,22 +2,33 @@ import os
2
  from datetime import datetime, timedelta
3
  from typing import Dict, Any, List
4
  from urllib.parse import urlencode
 
5
 
6
  from tavily import TavilyClient
7
 
8
 
9
  GENERIC_KEYWORDS = [
10
  "best", "top", "guide", "things", "visit", "attractions",
11
- "all you must know", "the 10 best", "the best"
12
  ]
13
  BLOCKED_SOURCES = [
14
- "reddit", "quora", "tripadvisor", "yelp", "forum", "forums", "community"
 
15
  ]
 
 
 
16
 
17
 
18
  def is_generic_title(title: str) -> bool:
19
  t = title.lower()
20
- return any(k in t for k in GENERIC_KEYWORDS) or any(s in t for s in BLOCKED_SOURCES) or t.startswith("r/")
 
 
 
 
 
 
21
 
22
 
23
  def normalize_title(title: str) -> str:
@@ -28,6 +39,18 @@ def normalize_title(title: str) -> str:
28
  return cleaned if cleaned else title
29
 
30
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  class PlannerAgentCentralized:
32
  def __init__(self, tavily_api_key: str | None = None):
33
  api_key = tavily_api_key or os.environ.get("TAVILY_API_KEY")
@@ -40,6 +63,7 @@ class PlannerAgentCentralized:
40
  departure_date = request.get("departure_date", "")
41
  return_date = request.get("return_date", "")
42
  preferences = request.get("preferences", [])
 
43
  total_budget = float(request.get("budget", 0) or 0)
44
  hotel_budget = float(request.get("hotel_budget", 0) or 0)
45
  activity_budget = float(request.get("activity_budget", 0) or 0)
@@ -49,7 +73,7 @@ class PlannerAgentCentralized:
49
  activity_budget = round(total_budget * 0.4, 2)
50
 
51
  hotel_names, hotel_reason = self._search_hotel_names(destination)
52
- poi_items, poi_reason = self._search_pois(destination, preferences)
53
 
54
  if not poi_items:
55
  poi_items = self._default_activities(destination)
@@ -97,7 +121,7 @@ class PlannerAgentCentralized:
97
  except Exception as e:
98
  return [], f"Hotel search failed: {e}"
99
 
100
- def _search_pois(self, destination: str, preferences: List[str]) -> tuple[List[Dict[str, Any]], str]:
101
  pref_part = (", ".join(preferences)) if preferences else "attractions"
102
  query = f"{pref_part} in {destination}"
103
  try:
@@ -111,6 +135,8 @@ class PlannerAgentCentralized:
111
  if is_generic_title(raw):
112
  continue
113
  name = normalize_title(raw)
 
 
114
  if name and not any(x.get("name") == name for x in items):
115
  items.append({"name": name, "url": url})
116
  reason = f"Collected {len(items)} itinerary items via Tavily for {pref_part}."
@@ -120,11 +146,11 @@ class PlannerAgentCentralized:
120
 
121
  def _default_activities(self, destination: str) -> List[Dict[str, Any]]:
122
  return [
123
- {"name": f"City walking tour of {destination}"},
124
- {"name": f"Local market & food tasting in {destination}"},
125
- {"name": f"Museum or cultural site in {destination}"},
126
- {"name": f"Scenic viewpoint / park in {destination}"},
127
- {"name": f"Evening dining in {destination} city center"}
128
  ]
129
 
130
  def _build_daily_schedule(self, start_date: datetime, num_days: int, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
 
2
  from datetime import datetime, timedelta
3
  from typing import Dict, Any, List
4
  from urllib.parse import urlencode
5
+ import re
6
 
7
  from tavily import TavilyClient
8
 
9
 
10
  GENERIC_KEYWORDS = [
11
  "best", "top", "guide", "things", "visit", "attractions",
12
+ "all you must know", "the 10 best", "the best", "how to", "tips"
13
  ]
14
  BLOCKED_SOURCES = [
15
+ "reddit", "quora", "tripadvisor", "yelp", "forum", "forums", "community",
16
+ "wikipedia.org", "wikivoyage.org", "blog", "list of"
17
  ]
18
+ ARTICLE_PATTERNS = [r"^list of ", r"^how to ", r"^why ", r"^what "]
19
+
20
+ PROPER_NOUN_RE = re.compile(r"\b([A-Z][a-z]+(?:\s+[A-Z][a-z]+)*)\b")
21
 
22
 
23
  def is_generic_title(title: str) -> bool:
24
  t = title.lower()
25
+ if any(k in t for k in GENERIC_KEYWORDS):
26
+ return True
27
+ if any(s in t for s in BLOCKED_SOURCES):
28
+ return True
29
+ if any(re.match(p, t) for p in ARTICLE_PATTERNS):
30
+ return True
31
+ return t.startswith("r/")
32
 
33
 
34
  def normalize_title(title: str) -> str:
 
39
  return cleaned if cleaned else title
40
 
41
 
42
+ def actionize(name: str, fallback_category: str | None = None) -> str:
43
+ # Convert generic/statement titles into imperative activity suggestions
44
+ n = name.strip().rstrip(".,! ")
45
+ # If contains a proper noun (probable place), keep it as is
46
+ if PROPER_NOUN_RE.search(n):
47
+ return n
48
+ # If looks like a topic, make it actionable
49
+ if fallback_category:
50
+ return f"Explore {fallback_category.lower()} – {n}" if len(n) < 40 else f"Explore {fallback_category.lower()} in the area"
51
+ return f"Explore: {n}" if len(n) < 40 else "Explore local highlights"
52
+
53
+
54
  class PlannerAgentCentralized:
55
  def __init__(self, tavily_api_key: str | None = None):
56
  api_key = tavily_api_key or os.environ.get("TAVILY_API_KEY")
 
63
  departure_date = request.get("departure_date", "")
64
  return_date = request.get("return_date", "")
65
  preferences = request.get("preferences", [])
66
+ pref_hint = preferences[0] if preferences else None
67
  total_budget = float(request.get("budget", 0) or 0)
68
  hotel_budget = float(request.get("hotel_budget", 0) or 0)
69
  activity_budget = float(request.get("activity_budget", 0) or 0)
 
73
  activity_budget = round(total_budget * 0.4, 2)
74
 
75
  hotel_names, hotel_reason = self._search_hotel_names(destination)
76
+ poi_items, poi_reason = self._search_pois(destination, preferences, pref_hint)
77
 
78
  if not poi_items:
79
  poi_items = self._default_activities(destination)
 
121
  except Exception as e:
122
  return [], f"Hotel search failed: {e}"
123
 
124
+ def _search_pois(self, destination: str, preferences: List[str], pref_hint: str | None) -> tuple[List[Dict[str, Any]], str]:
125
  pref_part = (", ".join(preferences)) if preferences else "attractions"
126
  query = f"{pref_part} in {destination}"
127
  try:
 
135
  if is_generic_title(raw):
136
  continue
137
  name = normalize_title(raw)
138
+ # Make action-friendly
139
+ name = actionize(name, pref_hint)
140
  if name and not any(x.get("name") == name for x in items):
141
  items.append({"name": name, "url": url})
142
  reason = f"Collected {len(items)} itinerary items via Tavily for {pref_part}."
 
146
 
147
  def _default_activities(self, destination: str) -> List[Dict[str, Any]]:
148
  return [
149
+ {"name": f"Morning walking tour of {destination}"},
150
+ {"name": f"Lunch at a local market in {destination}"},
151
+ {"name": f"Afternoon museum visit in {destination}"},
152
+ {"name": f"Sunset viewpoint in {destination}"},
153
+ {"name": f"Dinner in {destination} city center"}
154
  ]
155
 
156
  def _build_daily_schedule(self, start_date: datetime, num_days: int, items: List[Dict[str, Any]]) -> List[Dict[str, Any]]: