travel-agent-cli 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/bin/cli.js +6 -6
  2. package/package.json +2 -2
  3. package/python/agents/__init__.py +19 -0
  4. package/python/agents/analysis_agent.py +234 -0
  5. package/python/agents/base.py +377 -0
  6. package/python/agents/collector_agent.py +304 -0
  7. package/python/agents/manager_agent.py +251 -0
  8. package/python/agents/planning_agent.py +161 -0
  9. package/python/agents/product_agent.py +672 -0
  10. package/python/agents/report_agent.py +172 -0
  11. package/python/analyzers/__init__.py +10 -0
  12. package/python/analyzers/hot_score.py +123 -0
  13. package/python/analyzers/ranker.py +225 -0
  14. package/python/analyzers/route_planner.py +86 -0
  15. package/python/cli/commands.py +254 -0
  16. package/python/collectors/__init__.py +14 -0
  17. package/python/collectors/ota/ctrip.py +120 -0
  18. package/python/collectors/ota/fliggy.py +152 -0
  19. package/python/collectors/weibo.py +235 -0
  20. package/python/collectors/wenlv.py +155 -0
  21. package/python/collectors/xiaohongshu.py +170 -0
  22. package/python/config/__init__.py +30 -0
  23. package/python/config/models.py +119 -0
  24. package/python/config/prompts.py +105 -0
  25. package/python/config/settings.py +172 -0
  26. package/python/export/__init__.py +6 -0
  27. package/python/export/report.py +192 -0
  28. package/python/main.py +632 -0
  29. package/python/pyproject.toml +51 -0
  30. package/python/scheduler/tasks.py +77 -0
  31. package/python/tools/fliggy_mcp.py +553 -0
  32. package/python/tools/flyai_tools.py +251 -0
  33. package/python/tools/mcp_tools.py +412 -0
  34. package/python/utils/__init__.py +9 -0
  35. package/python/utils/http.py +73 -0
  36. package/python/utils/storage.py +288 -0
@@ -0,0 +1,161 @@
1
+ """规划 Agent - 负责旅行路线规划"""
2
+ from typing import Dict, Any, List, Optional
3
+ import json
4
+ from agents.base import BaseAgent
5
+
6
+
7
+ class PlanningAgent(BaseAgent):
8
+ """规划 Agent
9
+
10
+ 职责:
11
+ - 为目的地生成详细行程
12
+ - 估算预算
13
+ - 提供旅行建议
14
+ """
15
+
16
+ name = "planning_agent"
17
+ role = "资深旅行规划师"
18
+ goal = "为推荐目的地设计详细、实用、高性价比的旅行路线"
19
+
20
+ def __init__(
21
+ self,
22
+ provider: Optional[str] = None,
23
+ model: Optional[str] = None,
24
+ use_tools: bool = False,
25
+ ):
26
+ super().__init__(provider, model, use_tools)
27
+
28
+ async def execute_local(self, task: str, context: Dict[str, Any]) -> str:
29
+ """本地执行路线规划"""
30
+ destination = context.get("destination", "目的地")
31
+ days = context.get("days", 3)
32
+
33
+ result = {
34
+ "destination": destination,
35
+ "duration_days": days,
36
+ "daily_plan": [
37
+ {
38
+ "day": i + 1,
39
+ "theme": f"第{i + 1}天探索",
40
+ "activities": [
41
+ {"time": "上午", "item": "景点游览", "duration": "3 小时"},
42
+ {"time": "下午", "item": "深度体验", "duration": "4 小时"},
43
+ {"time": "晚上", "item": "美食探索", "duration": "2 小时"},
44
+ ]
45
+ }
46
+ for i in range(days)
47
+ ],
48
+ "budget_estimate": {
49
+ "accommodation": "¥300-500/晚",
50
+ "food": "¥100-200/天",
51
+ "transport": "¥50-100/天",
52
+ "activities": "¥100-300/天",
53
+ "total": f"¥{(300 + 100 + 50 + 100) * days}-{(500 + 200 + 100 + 300) * days}"
54
+ }
55
+ }
56
+
57
+ return json.dumps(result, ensure_ascii=False, indent=2)
58
+
59
+ async def plan_route(
60
+ self,
61
+ destination: Dict[str, Any],
62
+ days: int = None
63
+ ) -> Dict[str, Any]:
64
+ """为单个目的地规划路线
65
+
66
+ Args:
67
+ destination: 目的地信息(包含 name, suggested_days 等)
68
+ days: 游玩天数,如不传则从 destination 中获取
69
+
70
+ Returns:
71
+ 路线规划结果
72
+ """
73
+ dest_name = destination.get("name", "未知目的地")
74
+ travel_days = days or destination.get("suggested_days", 3)
75
+
76
+ task = f"""请为以下目的地设计详细的 {travel_days} 天旅行路线:
77
+
78
+ 目的地信息:
79
+ - 名称:{dest_name}
80
+ - 建议天数:{travel_days}天
81
+ - 推荐理由:{destination.get("reason", "")}
82
+ - 亮点:{", ".join(destination.get("highlights", []))}
83
+
84
+ 请设计包含以下内容的路线:
85
+ 1. 每日详细行程(上午/下午/晚上的活动)
86
+ 2. 每个景点的建议游玩时长
87
+ 3. 用餐推荐(当地特色美食)
88
+ 4. 住宿区域建议
89
+ 5. 交通建议
90
+ 6. 预算估算(住宿、餐饮、交通、活动、总计)
91
+
92
+ 请输出 JSON 格式:
93
+ {{
94
+ "destination": "{dest_name}",
95
+ "duration_days": {travel_days},
96
+ "daily_plan": [
97
+ {{
98
+ "day": 1,
99
+ "theme": "今日主题",
100
+ "activities": [
101
+ {{"time": "上午", "item": "景点/活动", "duration": "时长", "description": "描述"}},
102
+ {{"time": "下午", "item": "景点/活动", "duration": "时长", "description": "描述"}},
103
+ {{"time": "晚上", "item": "景点/活动", "duration": "时长", "description": "描述"}}
104
+ ],
105
+ "food_recommendation": "用餐建议",
106
+ "accommodation_area": "住宿区域建议",
107
+ "transport_tips": "交通建议"
108
+ }}
109
+ ],
110
+ "budget_estimate": {{
111
+ "accommodation": "住宿预算",
112
+ "food": "餐饮预算",
113
+ "transport": "交通预算",
114
+ "activities": "活动预算",
115
+ "tips": "省钱技巧",
116
+ "total": "总计"
117
+ }},
118
+ "travel_tips": ["出行提示 1", "出行提示 2"]
119
+ }}
120
+ """
121
+
122
+ result_str = await self.execute(task, {"destination": destination})
123
+
124
+ # 尝试解析 JSON
125
+ try:
126
+ # 清理可能的 markdown 格式
127
+ clean_result = result_str.strip()
128
+ if clean_result.startswith("```json"):
129
+ clean_result = clean_result[7:]
130
+ if clean_result.endswith("```"):
131
+ clean_result = clean_result[:-3]
132
+ return json.loads(clean_result.strip())
133
+ except json.JSONDecodeError:
134
+ # 解析失败,返回本地规划结果
135
+ return json.loads(await self.execute_local(task, {
136
+ "destination": dest_name,
137
+ "days": travel_days
138
+ }))
139
+
140
+ async def plan_top_destinations(
141
+ self,
142
+ destinations: List[Dict[str, Any]],
143
+ top_n: int = 3
144
+ ) -> List[Dict[str, Any]]:
145
+ """为 TOP 目的地规划路线
146
+
147
+ Args:
148
+ destinations: 目的地列表
149
+ top_n: 规划前 N 个目的地
150
+
151
+ Returns:
152
+ 路线规划列表
153
+ """
154
+ routes = []
155
+
156
+ for dest in destinations[:top_n]:
157
+ print(f"[{self.name}] 规划路线:{dest.get('name')}")
158
+ route = await self.plan_route(dest)
159
+ routes.append(route)
160
+
161
+ return routes