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()