nomadweb/backend/app/services/ai_service.py
eric 48408d3079 feat: complete NomadCNA parity layer with platform APIs and pages
Add services, videos, AI assistant, map/weather, gigs post, notifications settings, static legal pages, Google OAuth, payment router, real-user matching, newsletter, and content submission — all using nomadweb UI patterns.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-30 10:13:17 -05:00

51 lines
1.5 KiB
Python

"""Rule-based nomad assistant (no LLM)."""
from __future__ import annotations
KEYWORD_CITIES = {
"便宜": ["chiangmai", "mexico", "bali"],
"budget": ["chiangmai", "mexico", "bali"],
"快": ["tokyo", "barcelona", "lisbon"],
"网速": ["tokyo", "barcelona", "lisbon"],
"internet": ["tokyo", "barcelona", "lisbon"],
"暖": ["bali", "chiangmai", "mexico"],
"warm": ["bali", "chiangmai", "mexico"],
"冷": ["lisbon", "barcelona"],
"cool": ["lisbon", "barcelona"],
"签证": ["lisbon", "mexico"],
"visa": ["lisbon", "mexico"],
"中文": ["chiangmai", "bali"],
"chinese": ["chiangmai", "bali"],
}
def assistant_reply(message: str, destinations: list[dict]) -> dict:
msg = message.lower()
picks: list[str] = []
for kw, slugs in KEYWORD_CITIES.items():
if kw in msg:
picks.extend(slugs)
if not picks:
picks = ["chiangmai", "lisbon", "bali"]
seen: set[str] = set()
items = []
for slug in picks:
if slug in seen:
continue
seen.add(slug)
dest = next((d for d in destinations if d.get("slug") == slug), None)
if dest:
items.append({
"slug": slug,
"name": dest.get("name", slug),
"emoji": dest.get("emoji", "🌍"),
"reason": f"匹配你的需求:{message[:40]}",
})
if len(items) >= 3:
break
reply = (
f"根据你的描述,我推荐看看 {', '.join(i['name'] for i in items)}。"
" 可以用「下一站决策」做更精细的筛选,或在社区问当地细节。"
)
return {"reply": reply, "cities": items}