aetherforge-platform 1.0.0__py3-none-any.whl

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 (55) hide show
  1. aetherforge_platform-1.0.0.dist-info/METADATA +86 -0
  2. aetherforge_platform-1.0.0.dist-info/RECORD +55 -0
  3. aetherforge_platform-1.0.0.dist-info/WHEEL +5 -0
  4. aetherforge_platform-1.0.0.dist-info/top_level.txt +4 -0
  5. ai-life-assistant-copy/ai_agent.py +145 -0
  6. ai-life-assistant-copy/avatar_manager.py +231 -0
  7. ai-life-assistant-copy/avatar_packer.py +261 -0
  8. ai-life-assistant-copy/backup_all.py +262 -0
  9. ai-life-assistant-copy/backups/backup_20260404_193836/ai_agent.py +145 -0
  10. ai-life-assistant-copy/backups/backup_20260404_193836/avatar_manager.py +231 -0
  11. ai-life-assistant-copy/backups/backup_20260404_193836/avatar_packer.py +261 -0
  12. ai-life-assistant-copy/backups/backup_20260404_193836/backup_all.py +262 -0
  13. ai-life-assistant-copy/backups/backup_20260404_193836/commands.py +210 -0
  14. ai-life-assistant-copy/backups/backup_20260404_193836/config.py +30 -0
  15. ai-life-assistant-copy/backups/backup_20260404_193836/daemon/__init__.py +3 -0
  16. ai-life-assistant-copy/backups/backup_20260404_193836/daemon/daemon.py +174 -0
  17. ai-life-assistant-copy/backups/backup_20260404_193836/database.py +292 -0
  18. ai-life-assistant-copy/backups/backup_20260404_193836/graph.py +531 -0
  19. ai-life-assistant-copy/backups/backup_20260404_193836/main.py +830 -0
  20. ai-life-assistant-copy/backups/backup_20260404_193836/mcp_tools.py +449 -0
  21. ai-life-assistant-copy/backups/backup_20260404_193836/memory.py +92 -0
  22. ai-life-assistant-copy/backups/backup_20260404_193836/memory_v2.py +333 -0
  23. ai-life-assistant-copy/backups/backup_20260404_193836/mock_shopping_data.py +172 -0
  24. ai-life-assistant-copy/backups/backup_20260404_193836/personality.py +159 -0
  25. ai-life-assistant-copy/backups/backup_20260404_193836/speech.py +41 -0
  26. ai-life-assistant-copy/backups/backup_20260404_193836/test_simple.py +127 -0
  27. ai-life-assistant-copy/backups/backup_20260404_193836/tools/__init__.py +15 -0
  28. ai-life-assistant-copy/backups/backup_20260404_193836/tools/amazon_tool.py +103 -0
  29. ai-life-assistant-copy/backups/backup_20260404_193836/tools/calendar_tool.py +92 -0
  30. ai-life-assistant-copy/backups/backup_20260404_193836/tools/reminder_tool.py +92 -0
  31. ai-life-assistant-copy/backups/backup_20260404_193836/tools/weather_tool.py +45 -0
  32. ai-life-assistant-copy/backups/backup_20260404_193836/tree_memory.py +340 -0
  33. ai-life-assistant-copy/commands.py +210 -0
  34. ai-life-assistant-copy/config.py +30 -0
  35. ai-life-assistant-copy/daemon/__init__.py +3 -0
  36. ai-life-assistant-copy/daemon/daemon.py +174 -0
  37. ai-life-assistant-copy/database.py +292 -0
  38. ai-life-assistant-copy/graph.py +531 -0
  39. ai-life-assistant-copy/main.py +830 -0
  40. ai-life-assistant-copy/mcp_tools.py +449 -0
  41. ai-life-assistant-copy/memory.py +92 -0
  42. ai-life-assistant-copy/memory_v2.py +333 -0
  43. ai-life-assistant-copy/mock_shopping_data.py +172 -0
  44. ai-life-assistant-copy/personality.py +159 -0
  45. ai-life-assistant-copy/speech.py +41 -0
  46. ai-life-assistant-copy/test_simple.py +127 -0
  47. ai-life-assistant-copy/tools/__init__.py +15 -0
  48. ai-life-assistant-copy/tools/amazon_tool.py +103 -0
  49. ai-life-assistant-copy/tools/calendar_tool.py +92 -0
  50. ai-life-assistant-copy/tools/reminder_tool.py +92 -0
  51. ai-life-assistant-copy/tools/weather_tool.py +45 -0
  52. ai-life-assistant-copy/tree_memory.py +340 -0
  53. ai_agent_runtime.py +447 -0
  54. main.py +6752 -0
  55. mcp_server.py +427 -0
@@ -0,0 +1,340 @@
1
+ import json
2
+ import os
3
+ from typing import List, Dict, Any, Optional
4
+ from datetime import datetime, timedelta
5
+ import uuid
6
+
7
+
8
+ class MemoryNode:
9
+ def __init__(
10
+ self,
11
+ content: str,
12
+ memory_id: Optional[str] = None,
13
+ min_age: int = 0,
14
+ max_age: int = 150,
15
+ clarity: int = 80,
16
+ emotional_tone: str = "neutral",
17
+ topic: Optional[str] = None,
18
+ parent_id: Optional[str] = None,
19
+ created_at: Optional[str] = None,
20
+ importance: float = 0.5,
21
+ access_count: int = 0
22
+ ):
23
+ self.memory_id = memory_id or str(uuid.uuid4())
24
+ self.content = content
25
+ self.min_age = min_age
26
+ self.max_age = max_age
27
+ self.clarity = clarity
28
+ self.emotional_tone = emotional_tone
29
+ self.topic = topic
30
+ self.parent_id = parent_id
31
+ self.created_at = created_at or datetime.now().isoformat()
32
+ self.importance = importance
33
+ self.access_count = access_count
34
+ self.children: List[str] = []
35
+
36
+ def get_age_in_days(self) -> float:
37
+ created = datetime.fromisoformat(self.created_at)
38
+ now = datetime.now()
39
+ return (now - created).total_seconds() / 86400
40
+
41
+ def get_recency_score(self) -> float:
42
+ age_days = self.get_age_in_days()
43
+ if age_days < 1:
44
+ return 1.0
45
+ elif age_days < 7:
46
+ return 0.8
47
+ elif age_days < 30:
48
+ return 0.5
49
+ elif age_days < 90:
50
+ return 0.2
51
+ else:
52
+ return 0.05
53
+
54
+ def get_relevance_score(self, query: str) -> float:
55
+ query_lower = query.lower()
56
+ content_lower = self.content.lower()
57
+ topic_lower = self.topic.lower() if self.topic else ""
58
+
59
+ score = 0.0
60
+ if query_lower in content_lower:
61
+ score += 0.6
62
+ if query_lower in topic_lower:
63
+ score += 0.3
64
+
65
+ score += self.importance * 0.3
66
+ score += (self.clarity / 100) * 0.2
67
+ score += self.get_recency_score() * 0.4
68
+
69
+ return min(1.0, score)
70
+
71
+ def to_dict(self) -> Dict[str, Any]:
72
+ return {
73
+ "memory_id": self.memory_id,
74
+ "content": self.content,
75
+ "min_age": self.min_age,
76
+ "max_age": self.max_age,
77
+ "clarity": self.clarity,
78
+ "emotional_tone": self.emotional_tone,
79
+ "topic": self.topic,
80
+ "parent_id": self.parent_id,
81
+ "created_at": self.created_at,
82
+ "importance": self.importance,
83
+ "access_count": self.access_count,
84
+ "children": self.children
85
+ }
86
+
87
+ @classmethod
88
+ def from_dict(cls, data: Dict[str, Any]) -> 'MemoryNode':
89
+ node = cls(
90
+ content=data["content"],
91
+ memory_id=data["memory_id"],
92
+ min_age=data["min_age"],
93
+ max_age=data["max_age"],
94
+ clarity=data["clarity"],
95
+ emotional_tone=data["emotional_tone"],
96
+ topic=data.get("topic"),
97
+ parent_id=data.get("parent_id"),
98
+ created_at=data.get("created_at"),
99
+ importance=data.get("importance", 0.5),
100
+ access_count=data.get("access_count", 0)
101
+ )
102
+ node.children = data.get("children", [])
103
+ return node
104
+
105
+
106
+ class InvertedTreeMemory:
107
+ def __init__(self, tree_id: str = "root"):
108
+ self.tree_id = tree_id
109
+ self.nodes: Dict[str, MemoryNode] = {}
110
+ self.trunk: List[str] = []
111
+ self.created_at = datetime.now().isoformat()
112
+
113
+ def add_node(self, node: MemoryNode):
114
+ self.nodes[node.memory_id] = node
115
+ if not node.parent_id:
116
+ self.trunk.append(node.memory_id)
117
+ elif node.parent_id in self.nodes:
118
+ self.nodes[node.parent_id].children.append(node.memory_id)
119
+
120
+ def get_node(self, memory_id: str) -> Optional[MemoryNode]:
121
+ return self.nodes.get(memory_id)
122
+
123
+ def filter_by_age(self, target_age: int) -> List[MemoryNode]:
124
+ filtered = []
125
+ for node in self.nodes.values():
126
+ if node.min_age <= target_age <= node.max_age:
127
+ filtered.append(node)
128
+ return filtered
129
+
130
+ def search_relevant(self, query: str, min_relevance: float = 0.3, max_results: int = 10) -> List[MemoryNode]:
131
+ scored_nodes = []
132
+ for node in self.nodes.values():
133
+ score = node.get_relevance_score(query)
134
+ if score >= min_relevance:
135
+ scored_nodes.append((score, node))
136
+
137
+ scored_nodes.sort(key=lambda x: x[0], reverse=True)
138
+ return [node for (score, node) in scored_nodes[:max_results]]
139
+
140
+ def get_related_memories(self, memory_id: str) -> List[MemoryNode]:
141
+ related = []
142
+ node = self.get_node(memory_id)
143
+ if not node:
144
+ return related
145
+
146
+ if node.parent_id:
147
+ parent = self.get_node(node.parent_id)
148
+ if parent:
149
+ related.append(parent)
150
+
151
+ for child_id in node.children:
152
+ child = self.get_node(child_id)
153
+ if child:
154
+ related.append(child)
155
+
156
+ return related
157
+
158
+ def to_dict(self) -> Dict[str, Any]:
159
+ return {
160
+ "tree_id": self.tree_id,
161
+ "nodes": {k: v.to_dict() for k, v in self.nodes.items()},
162
+ "trunk": self.trunk,
163
+ "created_at": self.created_at
164
+ }
165
+
166
+ @classmethod
167
+ def from_dict(cls, data: Dict[str, Any]) -> 'InvertedTreeMemory':
168
+ tree = cls(tree_id=data["tree_id"])
169
+ tree.created_at = data["created_at"]
170
+ tree.trunk = data.get("trunk", [])
171
+ for node_data in data.get("nodes", {}).values():
172
+ node = MemoryNode.from_dict(node_data)
173
+ tree.nodes[node.memory_id] = node
174
+ return tree
175
+
176
+
177
+ class TreeMemorySystem:
178
+ def __init__(self, storage_dir: str = "avatar_memory"):
179
+ self.storage_dir = storage_dir
180
+ if not os.path.exists(storage_dir):
181
+ os.makedirs(storage_dir)
182
+
183
+ def _get_tree_file(self, avatar_id: str) -> str:
184
+ return os.path.join(self.storage_dir, f"{avatar_id}_tree.json")
185
+
186
+ def load_tree(self, avatar_id: str) -> InvertedTreeMemory:
187
+ file_path = self._get_tree_file(avatar_id)
188
+ if os.path.exists(file_path):
189
+ with open(file_path, "r", encoding="utf-8") as f:
190
+ data = json.load(f)
191
+ return InvertedTreeMemory.from_dict(data)
192
+ return InvertedTreeMemory(tree_id=avatar_id)
193
+
194
+ def save_tree(self, avatar_id: str, tree: InvertedTreeMemory):
195
+ file_path = self._get_tree_file(avatar_id)
196
+ with open(file_path, "w", encoding="utf-8") as f:
197
+ json.dump(tree.to_dict(), f, ensure_ascii=False, indent=2)
198
+
199
+ def add_memory(
200
+ self,
201
+ avatar_id: str,
202
+ content: str,
203
+ min_age: int = 0,
204
+ max_age: int = 150,
205
+ clarity: int = 80,
206
+ emotional_tone: str = "neutral",
207
+ topic: Optional[str] = None,
208
+ parent_id: Optional[str] = None,
209
+ importance: float = 0.5
210
+ ) -> str:
211
+ tree = self.load_tree(avatar_id)
212
+ node = MemoryNode(
213
+ content=content,
214
+ min_age=min_age,
215
+ max_age=max_age,
216
+ clarity=clarity,
217
+ emotional_tone=emotional_tone,
218
+ topic=topic,
219
+ parent_id=parent_id,
220
+ importance=importance
221
+ )
222
+ tree.add_node(node)
223
+ self.save_tree(avatar_id, tree)
224
+ return node.memory_id
225
+
226
+ def get_memories_by_age(self, avatar_id: str, target_age: int) -> List[Dict[str, Any]]:
227
+ tree = self.load_tree(avatar_id)
228
+ nodes = tree.filter_by_age(target_age)
229
+ return [node.to_dict() for node in nodes]
230
+
231
+ def get_all_memories(self, avatar_id: str) -> List[Dict[str, Any]]:
232
+ tree = self.load_tree(avatar_id)
233
+ return [node.to_dict() for node in tree.nodes.values()]
234
+
235
+ def get_tree_structure(self, avatar_id: str) -> Dict[str, Any]:
236
+ tree = self.load_tree(avatar_id)
237
+ return tree.to_dict()
238
+
239
+ def delete_memory(self, avatar_id: str, memory_id: str) -> bool:
240
+ tree = self.load_tree(avatar_id)
241
+ if memory_id in tree.nodes:
242
+ del tree.nodes[memory_id]
243
+ tree.trunk = [mid for mid in tree.trunk if mid != memory_id]
244
+ for node in tree.nodes.values():
245
+ node.children = [mid for mid in node.children if mid != memory_id]
246
+ self.save_tree(avatar_id, tree)
247
+ return True
248
+ return False
249
+
250
+ def search_relevant_memories(
251
+ self,
252
+ avatar_id: str,
253
+ query: str,
254
+ min_relevance: float = 0.3,
255
+ max_results: int = 10
256
+ ) -> List[Dict[str, Any]]:
257
+ tree = self.load_tree(avatar_id)
258
+ nodes = tree.search_relevant(query, min_relevance, max_results)
259
+ results = []
260
+ for node in nodes:
261
+ node.access_count += 1
262
+ results.append(node.to_dict())
263
+ self.save_tree(avatar_id, tree)
264
+ return results
265
+
266
+ def get_related_memories(self, avatar_id: str, memory_id: str) -> List[Dict[str, Any]]:
267
+ tree = self.load_tree(avatar_id)
268
+ nodes = tree.get_related_memories(memory_id)
269
+ return [node.to_dict() for node in nodes]
270
+
271
+ def get_relevant_context(
272
+ self,
273
+ avatar_id: str,
274
+ current_message: str,
275
+ min_relevance: float = 0.3,
276
+ max_results: int = 5
277
+ ) -> str:
278
+ memories = self.search_relevant_memories(avatar_id, current_message, min_relevance, max_results)
279
+ if not memories:
280
+ return ""
281
+
282
+ context_parts = ["【用户背景信息 - 树状记忆系统】"]
283
+ for mem in memories:
284
+ age_info = ""
285
+ if mem["min_age"] != 0 or mem["max_age"] != 150:
286
+ if mem["min_age"] == mem["max_age"]:
287
+ age_info = f" [年龄: {mem['min_age']}]"
288
+ else:
289
+ age_info = f" [年龄: {mem['min_age']}-{mem['max_age']}]"
290
+
291
+ clarity_info = f" [清晰度: {mem['clarity']}%]"
292
+ emotion_info = f" [情感: {mem['emotional_tone']}]"
293
+ topic_info = f" [主题: {mem['topic']}]" if mem['topic'] else ""
294
+
295
+ context_parts.append(f"- {mem['content']}{age_info}{clarity_info}{emotion_info}{topic_info}")
296
+
297
+ return "\n".join(context_parts)
298
+
299
+ def extract_and_save_memory(
300
+ self,
301
+ avatar_id: str,
302
+ message: str,
303
+ response: str = "",
304
+ current_age: int = 25
305
+ ) -> Optional[str]:
306
+ message_lower = message.lower()
307
+
308
+ importance = 0.5
309
+ if "永远" in message_lower or "绝对" in message_lower or "绝不" in message_lower:
310
+ importance = 0.9
311
+ elif "非常" in message_lower or "特别" in message_lower:
312
+ importance = 0.75
313
+
314
+ emotional_tone = "neutral"
315
+ positive_words = ["开心", "快乐", "高兴", "喜欢", "爱", "好", "棒", "完美"]
316
+ negative_words = ["难过", "伤心", "讨厌", "恨", "不好", "糟糕", "生气", "愤怒"]
317
+
318
+ if any(word in message_lower for word in positive_words):
319
+ emotional_tone = "positive"
320
+ elif any(word in message_lower for word in negative_words):
321
+ emotional_tone = "negative"
322
+
323
+ user_keywords = ["我是", "我喜欢", "我偏好", "我不喜欢", "我讨厌", "我想要", "我爱吃", "我爱玩", "记得", "小时候", "曾经"]
324
+ should_save = any(keyword in message_lower for keyword in user_keywords) or len(message) > 20
325
+
326
+ if should_save:
327
+ return self.add_memory(
328
+ avatar_id=avatar_id,
329
+ content=message,
330
+ min_age=current_age,
331
+ max_age=current_age,
332
+ clarity=80,
333
+ emotional_tone=emotional_tone,
334
+ importance=importance
335
+ )
336
+
337
+ return None
338
+
339
+
340
+ tree_memory_system = TreeMemorySystem()
@@ -0,0 +1,210 @@
1
+ """命令系统"""
2
+
3
+ from typing import Dict, Any, List
4
+ import re
5
+
6
+ class CommandParser:
7
+ """命令解析器"""
8
+
9
+ def __init__(self):
10
+ self.commands = {
11
+ "weather": self._parse_weather,
12
+ "w": self._parse_weather,
13
+ "calendar": self._parse_calendar,
14
+ "cal": self._parse_calendar,
15
+ "reminder": self._parse_reminder,
16
+ "rem": self._parse_reminder,
17
+ "shopping": self._parse_shopping,
18
+ "buy": self._parse_shopping,
19
+ "food": self._parse_food,
20
+ "taxi": self._parse_taxi,
21
+ "flight": self._parse_flight,
22
+ "help": self._parse_help
23
+ }
24
+
25
+ def parse(self, message: str) -> Dict[str, Any]:
26
+ """解析命令
27
+
28
+ Args:
29
+ message: 用户输入
30
+
31
+ Returns:
32
+ 解析结果
33
+ """
34
+ if not message.startswith("/"):
35
+ return {"type": "normal", "message": message}
36
+
37
+ # 提取命令和参数
38
+ parts = message[1:].split(" ", 1)
39
+ command = parts[0].lower()
40
+ args = parts[1] if len(parts) > 1 else ""
41
+
42
+ if command in self.commands:
43
+ return self.commands[command](args)
44
+ else:
45
+ return {"type": "normal", "message": message}
46
+
47
+ def _parse_weather(self, args: str) -> Dict[str, Any]:
48
+ """解析天气命令"""
49
+ location = args.strip() or "北京"
50
+ return {
51
+ "type": "command",
52
+ "command": "weather",
53
+ "intent": "weather",
54
+ "requirements": {"location": location}
55
+ }
56
+
57
+ def _parse_calendar(self, args: str) -> Dict[str, Any]:
58
+ """解析日程命令"""
59
+ parts = args.split(" ")
60
+ if not parts:
61
+ return {
62
+ "type": "command",
63
+ "command": "calendar",
64
+ "intent": "calendar",
65
+ "requirements": {}
66
+ }
67
+
68
+ if parts[0] == "add":
69
+ # /calendar add 标题 时间 [日期]
70
+ if len(parts) >= 3:
71
+ title = " ".join(parts[1:-1])
72
+ time = parts[-1]
73
+ return {
74
+ "type": "command",
75
+ "command": "calendar",
76
+ "intent": "calendar",
77
+ "requirements": {
78
+ "action": "add",
79
+ "title": title,
80
+ "time": time
81
+ }
82
+ }
83
+
84
+ # 默认获取日程
85
+ date = args.strip()
86
+ return {
87
+ "type": "command",
88
+ "command": "calendar",
89
+ "intent": "calendar",
90
+ "requirements": {"date": date}
91
+ }
92
+
93
+ def _parse_reminder(self, args: str) -> Dict[str, Any]:
94
+ """解析提醒命令"""
95
+ parts = args.split(" ")
96
+ if not parts:
97
+ return {
98
+ "type": "command",
99
+ "command": "reminder",
100
+ "intent": "reminder",
101
+ "requirements": {}
102
+ }
103
+
104
+ if parts[0] == "set":
105
+ # /reminder set 标题 时间 [日期] [重复]
106
+ if len(parts) >= 3:
107
+ title = " ".join(parts[1:-1])
108
+ time = parts[-1]
109
+ return {
110
+ "type": "command",
111
+ "command": "reminder",
112
+ "intent": "reminder",
113
+ "requirements": {
114
+ "action": "set",
115
+ "title": title,
116
+ "time": time
117
+ }
118
+ }
119
+
120
+ # 默认获取提醒
121
+ date = args.strip()
122
+ return {
123
+ "type": "command",
124
+ "command": "reminder",
125
+ "intent": "reminder",
126
+ "requirements": {"date": date}
127
+ }
128
+
129
+ def _parse_shopping(self, args: str) -> Dict[str, Any]:
130
+ """解析购物命令"""
131
+ query = args.strip()
132
+ return {
133
+ "type": "command",
134
+ "command": "shopping",
135
+ "intent": "shopping",
136
+ "requirements": {"query": query}
137
+ }
138
+
139
+ def _parse_food(self, args: str) -> Dict[str, Any]:
140
+ """解析外卖命令"""
141
+ query = args.strip()
142
+ return {
143
+ "type": "command",
144
+ "command": "food",
145
+ "intent": "food",
146
+ "requirements": {"query": query}
147
+ }
148
+
149
+ def _parse_taxi(self, args: str) -> Dict[str, Any]:
150
+ """解析打车命令"""
151
+ destination = args.strip()
152
+ return {
153
+ "type": "command",
154
+ "command": "taxi",
155
+ "intent": "taxi",
156
+ "requirements": {"destination": destination}
157
+ }
158
+
159
+ def _parse_flight(self, args: str) -> Dict[str, Any]:
160
+ """解析机票命令"""
161
+ parts = args.split(" ")
162
+ if len(parts) >= 2:
163
+ from_city = parts[0]
164
+ to_city = parts[1]
165
+ return {
166
+ "type": "command",
167
+ "command": "flight",
168
+ "intent": "flight",
169
+ "requirements": {
170
+ "from": from_city,
171
+ "to": to_city
172
+ }
173
+ }
174
+ return {
175
+ "type": "command",
176
+ "command": "flight",
177
+ "intent": "flight",
178
+ "requirements": {}
179
+ }
180
+
181
+ def _parse_help(self, args: str) -> Dict[str, Any]:
182
+ """解析帮助命令"""
183
+ return {
184
+ "type": "command",
185
+ "command": "help",
186
+ "intent": "general",
187
+ "requirements": {}
188
+ }
189
+
190
+ def get_help(self) -> str:
191
+ """获取帮助信息"""
192
+ help_text = """可用命令:
193
+
194
+ /weather [城市] - 查看天气
195
+ /calendar [日期] - 查看日程
196
+ /calendar add [标题] [时间] - 添加日程
197
+ /reminder [日期] - 查看提醒
198
+ /reminder set [标题] [时间] - 设置提醒
199
+ /shopping [关键词] - 搜索商品
200
+ /food [关键词] - 点外卖
201
+ /taxi [目的地] - 打车
202
+ /flight [出发地] [目的地] - 查机票
203
+ /help - 查看帮助
204
+
205
+ 示例:
206
+ /weather 上海
207
+ /reminder set 吃药 08:00
208
+ /shopping 手机
209
+ """
210
+ return help_text
@@ -0,0 +1,30 @@
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ load_dotenv()
5
+
6
+ # API Keys
7
+ GROK_API_KEY = os.getenv("GROK_API_KEY", "")
8
+ SUPABASE_URL = os.getenv("SUPABASE_URL", "")
9
+ SUPABASE_KEY = os.getenv("SUPABASE_KEY", "")
10
+
11
+ # Amazon Affiliate
12
+ AMAZON_ASSOCIATE_TAG = os.getenv("AMAZON_ASSOCIATE_TAG", "")
13
+ AMAZON_ACCESS_KEY = os.getenv("AMAZON_ACCESS_KEY", "")
14
+ AMAZON_SECRET_KEY = os.getenv("AMAZON_SECRET_KEY", "")
15
+
16
+ # Uber Affiliate
17
+ UBER_CLIENT_ID = os.getenv("UBER_CLIENT_ID", "")
18
+ UBER_CLIENT_SECRET = os.getenv("UBER_CLIENT_SECRET", "")
19
+
20
+ # App Settings
21
+ APP_NAME = "AI Life Assistant"
22
+ APP_VERSION = "1.0.0"
23
+ DEBUG = os.getenv("DEBUG", "True").lower() == "true"
24
+
25
+ # API Settings
26
+ MAX_RETRIES = 3
27
+ REQUEST_TIMEOUT = 30
28
+
29
+ # Memory Settings
30
+ MEMORY_MAX_LENGTH = 50
@@ -0,0 +1,3 @@
1
+ """梦游功能(智能后台服务)"""
2
+
3
+ from .daemon import LifeAssistantDaemon