alpha-avatar-plugins-memory 0.6.2__tar.gz → 0.6.4__tar.gz
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.
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/.gitignore +0 -1
- alpha_avatar_plugins_memory-0.6.4/PKG-INFO +242 -0
- alpha_avatar_plugins_memory-0.6.4/README.md +220 -0
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/alphaavatar/plugins/memory/__init__.py +5 -3
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/graph/__init__.py +24 -0
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/graph/graph_alias.py +144 -0
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/graph/graph_builder.py +230 -0
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/graph/graph_lookup.py +232 -0
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/graph/graph_store.py +362 -0
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/memory_delta_extractor.py +456 -0
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/alphaavatar/plugins/memory/memory_markdown.py +47 -17
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/alphaavatar/plugins/memory/memory_op.py +45 -12
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/memory_prompts.py +1003 -0
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/memory_runtime.py +886 -0
- alpha_avatar_plugins_memory-0.6.4/alphaavatar/plugins/memory/runner/lancedb_runner.py +663 -0
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/alphaavatar/plugins/memory/version.py +1 -1
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/pyproject.toml +0 -6
- alpha_avatar_plugins_memory-0.6.2/PKG-INFO +0 -176
- alpha_avatar_plugins_memory-0.6.2/README.md +0 -149
- alpha_avatar_plugins_memory-0.6.2/alphaavatar/plugins/memory/memory_prompts.py +0 -560
- alpha_avatar_plugins_memory-0.6.2/alphaavatar/plugins/memory/memory_runtime.py +0 -755
- alpha_avatar_plugins_memory-0.6.2/alphaavatar/plugins/memory/runner/lancedb_runner.py +0 -240
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/alphaavatar/plugins/memory/log.py +0 -0
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/alphaavatar/plugins/memory/runner/__init__.py +0 -0
- {alpha_avatar_plugins_memory-0.6.2 → alpha_avatar_plugins_memory-0.6.4}/alphaavatar/plugins/memory/runner/qdrant_runner.py +0 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: alpha-avatar-plugins-memory
|
|
3
|
+
Version: 0.6.4
|
|
4
|
+
Summary: AlphaAvatar Framework plugin for memory service
|
|
5
|
+
Project-URL: Source, https://github.com/AlphaAvatar/AlphaAvatar
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Keywords: AI,agents,langchain,llm,memory
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
17
|
+
Classifier: Topic :: Multimedia :: Video
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: <3.12,>=3.11
|
|
20
|
+
Requires-Dist: torchaudio>=0.10.1
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# 🧠 Memory Plugin for AlphaAvatar
|
|
24
|
+
|
|
25
|
+
> Give AlphaAvatar the ability to **remember you, its tools, and its environment** — across conversations, sessions, and time.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 🤔 What is the Memory Plugin?
|
|
30
|
+
|
|
31
|
+
Imagine talking to an assistant that forgets everything the moment you close the app. Frustrating, right?
|
|
32
|
+
|
|
33
|
+
The **Memory Plugin** gives AlphaAvatar a persistent memory layer. It can:
|
|
34
|
+
|
|
35
|
+
- Remember your **preferences, goals, and important facts**
|
|
36
|
+
- Recall **past conversations** and previous decisions
|
|
37
|
+
- Learn from **tool usage**, research, and retrieved documents
|
|
38
|
+
- Build **environment memories** from live visual observations
|
|
39
|
+
- Retrieve related memories through **semantic and graph-aware search**
|
|
40
|
+
|
|
41
|
+
Think of it as AlphaAvatar's long-term notebook — important information is extracted, organized, stored, and brought back when it becomes useful.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 💡 How Does it Work? (Simple Flow)
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
Conversation / Tool Result / Visual Observation
|
|
49
|
+
↓
|
|
50
|
+
AlphaAvatar extracts useful memory updates
|
|
51
|
+
↓
|
|
52
|
+
Runtime adds identity, session, graph, and evidence metadata
|
|
53
|
+
↓
|
|
54
|
+
Memories are stored in local or remote vector storage
|
|
55
|
+
↓
|
|
56
|
+
Relevant memories are retrieved in future turns
|
|
57
|
+
↓
|
|
58
|
+
AlphaAvatar responds with better continuity and grounding
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Conversation and tool memory work automatically in the background.
|
|
62
|
+
Online ENV memory is enabled when a multimodal `env_delta_task` is configured.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## ✨ Features
|
|
67
|
+
|
|
68
|
+
### 🌍 Persistent Memory
|
|
69
|
+
|
|
70
|
+
AlphaAvatar maintains memories beyond a single chat session.
|
|
71
|
+
|
|
72
|
+
This includes:
|
|
73
|
+
|
|
74
|
+
- Things **you** told it
|
|
75
|
+
- Important **conversation decisions**
|
|
76
|
+
- Results from **MCP, RAG, and DeepResearch**
|
|
77
|
+
- Useful observations from the **camera, screen, or surrounding environment**
|
|
78
|
+
- Links between people, objects, sessions, tools, and events
|
|
79
|
+
|
|
80
|
+
### ⚡ Runtime Memory Updates
|
|
81
|
+
|
|
82
|
+
Memory can update while a session is active instead of waiting until the conversation ends.
|
|
83
|
+
|
|
84
|
+
Conversation, tool, and ENV memory use separate extraction paths, while the runtime controls timestamps, ownership, evidence, graph structure, and session metadata.
|
|
85
|
+
|
|
86
|
+
### 👁️ Online ENV Memory
|
|
87
|
+
|
|
88
|
+
The Memory plugin can consume ordered observation windows from `PerceptionRuntime`.
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
Video / Screen Observations
|
|
92
|
+
↓
|
|
93
|
+
PerceptionRuntime Window
|
|
94
|
+
↓
|
|
95
|
+
Multimodal ENV Extraction Task
|
|
96
|
+
↓
|
|
97
|
+
EnvMemoryDelta
|
|
98
|
+
↓
|
|
99
|
+
MemoryType.ENV
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
ENV memory prefers annotated visual evidence when available and falls back to raw frames. Heavy runtime payloads such as video frames are never written directly into memory storage.
|
|
103
|
+
|
|
104
|
+
### 🕸️ Graph-aware Retrieval
|
|
105
|
+
|
|
106
|
+
Memories can include graph nodes and links for entities such as:
|
|
107
|
+
|
|
108
|
+
- users
|
|
109
|
+
- faces and speakers
|
|
110
|
+
- objects
|
|
111
|
+
- sessions
|
|
112
|
+
- tools
|
|
113
|
+
- locations
|
|
114
|
+
- events
|
|
115
|
+
|
|
116
|
+
Graph nodes act as retrieval anchors, while memory text remains the source of truth.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## 📦 What Kind of Things Does AlphaAvatar Remember?
|
|
121
|
+
|
|
122
|
+
| Type | Example |
|
|
123
|
+
|------|---------|
|
|
124
|
+
| 👤 Personal facts | “My name is Alex and I live in New York.” |
|
|
125
|
+
| ❤️ Preferences | “I prefer short, direct answers.” |
|
|
126
|
+
| 🗓️ Conversation memory | A decision or topic from an earlier session |
|
|
127
|
+
| 🔍 Research results | Findings from a DeepResearch task |
|
|
128
|
+
| 📄 Document knowledge | Useful information retrieved through RAG |
|
|
129
|
+
| 🛠️ Tool interactions | Results from MCP tools such as Gmail or Notion |
|
|
130
|
+
| 👁️ ENV memory | “A person placed a red cup on the desk.” |
|
|
131
|
+
| 🕸️ Graph associations | A user, object, tool, and event linked across memories |
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 🔧 Installation
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
pip install alpha-avatar-plugins-memory
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The plugin is then loaded through the AlphaAvatar configuration.
|
|
142
|
+
|
|
143
|
+
To enable online ENV memory, configure a multimodal provider task such as:
|
|
144
|
+
|
|
145
|
+
```yaml
|
|
146
|
+
env_delta_task: memory.env_delta
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
If no ENV extraction task is configured, the rest of the Memory plugin continues to work normally.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## 🗄️ How Memories are Stored
|
|
154
|
+
|
|
155
|
+
AlphaAvatar stores memories as structured records with searchable embeddings and runtime-owned metadata.
|
|
156
|
+
|
|
157
|
+
Memory records can include:
|
|
158
|
+
|
|
159
|
+
- memory text
|
|
160
|
+
- memory type
|
|
161
|
+
- object ownership
|
|
162
|
+
- timestamps and session IDs
|
|
163
|
+
- evidence references
|
|
164
|
+
- graph nodes and links
|
|
165
|
+
- additional runtime metadata
|
|
166
|
+
|
|
167
|
+
### Supported Backends
|
|
168
|
+
|
|
169
|
+
| Backend | What it Does |
|
|
170
|
+
|---------|--------------|
|
|
171
|
+
| **LanceDB** | Local vector storage and graph-aware retrieval (default) |
|
|
172
|
+
| **Qdrant** | Remote or self-hosted vector storage |
|
|
173
|
+
| **Provider Gateway** | Routes extraction tasks to configured LLM or VLM providers |
|
|
174
|
+
|
|
175
|
+
By default, AlphaAvatar can run with local LanceDB storage. Raw camera frames, audio buffers, and other heavy runtime payloads are not persisted as memory items.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## 🔗 How Memory Connects to Other Modules
|
|
180
|
+
|
|
181
|
+
```text
|
|
182
|
+
PerceptionRuntime
|
|
183
|
+
└── → ENV Memory (visual and future audio observations)
|
|
184
|
+
|
|
185
|
+
Persona Plugin
|
|
186
|
+
└── → Identity Aliases (face / speaker / user relationships)
|
|
187
|
+
|
|
188
|
+
RAG / DeepResearch / MCP
|
|
189
|
+
└── → Tool Memory (documents, research, and actions)
|
|
190
|
+
|
|
191
|
+
Memory Plugin
|
|
192
|
+
├── → Avatar Runtime (dynamic per-turn context)
|
|
193
|
+
├── → Graph Retrieval (entity and relationship lookup)
|
|
194
|
+
├── → Reflection* (behavior improvement)
|
|
195
|
+
└── → Planning* (goals and reminders)
|
|
196
|
+
|
|
197
|
+
* Planned
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 🙋 Common Questions
|
|
203
|
+
|
|
204
|
+
**Q: Does memory work across sessions?**
|
|
205
|
+
Yes. Stored memories can be retrieved in later sessions.
|
|
206
|
+
|
|
207
|
+
**Q: Does ENV memory save my raw camera stream?**
|
|
208
|
+
No. Raw runtime frames are not stored as memory records. The configured multimodal model extracts useful environment memories from selected observation windows.
|
|
209
|
+
|
|
210
|
+
**Q: Is ENV memory always enabled?**
|
|
211
|
+
No. It is optional and only runs when `env_delta_task` is configured.
|
|
212
|
+
|
|
213
|
+
**Q: Can memory distinguish different users?**
|
|
214
|
+
Memory supports multi-object ownership and graph aliases. Persona can resolve temporary face or speaker identities to stable users.
|
|
215
|
+
|
|
216
|
+
**Q: Can I see or delete individual memories?**
|
|
217
|
+
Fine-grained inspection, correction, export, and deletion controls are still being developed.
|
|
218
|
+
|
|
219
|
+
**Q: Is my data private?**
|
|
220
|
+
Local LanceDB storage keeps memory data on your own machine unless you configure a remote backend or external model provider.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 🚀 Coming Soon
|
|
225
|
+
|
|
226
|
+
| Feature | Description |
|
|
227
|
+
|---------|-------------|
|
|
228
|
+
| 🎤 Audio ENV Memory | Extract useful events and context from continuous audio streams |
|
|
229
|
+
| 🔍 Rich Visual-history Search | Search by objects, events, identities, and time ranges |
|
|
230
|
+
| 🧩 Multi-annotation Fusion | Combine face, speaker, object, action, and scene annotations |
|
|
231
|
+
| 🔒 Memory Privacy Controls | Inspect, edit, export, and delete memories |
|
|
232
|
+
| 👥 Stronger Multi-user Memory | Better separation and merging across shared sessions |
|
|
233
|
+
| 🧠 Reflection & Planning | Use memory for longer-term behavior improvement and goals |
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## 📚 Related Links
|
|
238
|
+
|
|
239
|
+
- [AlphaAvatar ROADMAP — Memory Section](https://github.com/AlphaAvatar/AlphaAvatar/blob/main/ROADMAP.md#-memory)
|
|
240
|
+
- [Persona Plugin](https://github.com/AlphaAvatar/AlphaAvatar/blob/main/avatar-plugins/avatar-plugins-persona/README.md)
|
|
241
|
+
- [LanceDB Documentation](https://lancedb.com/docs/)
|
|
242
|
+
- [Qdrant Documentation](https://qdrant.tech/documentation/)
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# 🧠 Memory Plugin for AlphaAvatar
|
|
2
|
+
|
|
3
|
+
> Give AlphaAvatar the ability to **remember you, its tools, and its environment** — across conversations, sessions, and time.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🤔 What is the Memory Plugin?
|
|
8
|
+
|
|
9
|
+
Imagine talking to an assistant that forgets everything the moment you close the app. Frustrating, right?
|
|
10
|
+
|
|
11
|
+
The **Memory Plugin** gives AlphaAvatar a persistent memory layer. It can:
|
|
12
|
+
|
|
13
|
+
- Remember your **preferences, goals, and important facts**
|
|
14
|
+
- Recall **past conversations** and previous decisions
|
|
15
|
+
- Learn from **tool usage**, research, and retrieved documents
|
|
16
|
+
- Build **environment memories** from live visual observations
|
|
17
|
+
- Retrieve related memories through **semantic and graph-aware search**
|
|
18
|
+
|
|
19
|
+
Think of it as AlphaAvatar's long-term notebook — important information is extracted, organized, stored, and brought back when it becomes useful.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 💡 How Does it Work? (Simple Flow)
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
Conversation / Tool Result / Visual Observation
|
|
27
|
+
↓
|
|
28
|
+
AlphaAvatar extracts useful memory updates
|
|
29
|
+
↓
|
|
30
|
+
Runtime adds identity, session, graph, and evidence metadata
|
|
31
|
+
↓
|
|
32
|
+
Memories are stored in local or remote vector storage
|
|
33
|
+
↓
|
|
34
|
+
Relevant memories are retrieved in future turns
|
|
35
|
+
↓
|
|
36
|
+
AlphaAvatar responds with better continuity and grounding
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Conversation and tool memory work automatically in the background.
|
|
40
|
+
Online ENV memory is enabled when a multimodal `env_delta_task` is configured.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## ✨ Features
|
|
45
|
+
|
|
46
|
+
### 🌍 Persistent Memory
|
|
47
|
+
|
|
48
|
+
AlphaAvatar maintains memories beyond a single chat session.
|
|
49
|
+
|
|
50
|
+
This includes:
|
|
51
|
+
|
|
52
|
+
- Things **you** told it
|
|
53
|
+
- Important **conversation decisions**
|
|
54
|
+
- Results from **MCP, RAG, and DeepResearch**
|
|
55
|
+
- Useful observations from the **camera, screen, or surrounding environment**
|
|
56
|
+
- Links between people, objects, sessions, tools, and events
|
|
57
|
+
|
|
58
|
+
### ⚡ Runtime Memory Updates
|
|
59
|
+
|
|
60
|
+
Memory can update while a session is active instead of waiting until the conversation ends.
|
|
61
|
+
|
|
62
|
+
Conversation, tool, and ENV memory use separate extraction paths, while the runtime controls timestamps, ownership, evidence, graph structure, and session metadata.
|
|
63
|
+
|
|
64
|
+
### 👁️ Online ENV Memory
|
|
65
|
+
|
|
66
|
+
The Memory plugin can consume ordered observation windows from `PerceptionRuntime`.
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
Video / Screen Observations
|
|
70
|
+
↓
|
|
71
|
+
PerceptionRuntime Window
|
|
72
|
+
↓
|
|
73
|
+
Multimodal ENV Extraction Task
|
|
74
|
+
↓
|
|
75
|
+
EnvMemoryDelta
|
|
76
|
+
↓
|
|
77
|
+
MemoryType.ENV
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
ENV memory prefers annotated visual evidence when available and falls back to raw frames. Heavy runtime payloads such as video frames are never written directly into memory storage.
|
|
81
|
+
|
|
82
|
+
### 🕸️ Graph-aware Retrieval
|
|
83
|
+
|
|
84
|
+
Memories can include graph nodes and links for entities such as:
|
|
85
|
+
|
|
86
|
+
- users
|
|
87
|
+
- faces and speakers
|
|
88
|
+
- objects
|
|
89
|
+
- sessions
|
|
90
|
+
- tools
|
|
91
|
+
- locations
|
|
92
|
+
- events
|
|
93
|
+
|
|
94
|
+
Graph nodes act as retrieval anchors, while memory text remains the source of truth.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## 📦 What Kind of Things Does AlphaAvatar Remember?
|
|
99
|
+
|
|
100
|
+
| Type | Example |
|
|
101
|
+
|------|---------|
|
|
102
|
+
| 👤 Personal facts | “My name is Alex and I live in New York.” |
|
|
103
|
+
| ❤️ Preferences | “I prefer short, direct answers.” |
|
|
104
|
+
| 🗓️ Conversation memory | A decision or topic from an earlier session |
|
|
105
|
+
| 🔍 Research results | Findings from a DeepResearch task |
|
|
106
|
+
| 📄 Document knowledge | Useful information retrieved through RAG |
|
|
107
|
+
| 🛠️ Tool interactions | Results from MCP tools such as Gmail or Notion |
|
|
108
|
+
| 👁️ ENV memory | “A person placed a red cup on the desk.” |
|
|
109
|
+
| 🕸️ Graph associations | A user, object, tool, and event linked across memories |
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 🔧 Installation
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pip install alpha-avatar-plugins-memory
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
The plugin is then loaded through the AlphaAvatar configuration.
|
|
120
|
+
|
|
121
|
+
To enable online ENV memory, configure a multimodal provider task such as:
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
env_delta_task: memory.env_delta
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If no ENV extraction task is configured, the rest of the Memory plugin continues to work normally.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## 🗄️ How Memories are Stored
|
|
132
|
+
|
|
133
|
+
AlphaAvatar stores memories as structured records with searchable embeddings and runtime-owned metadata.
|
|
134
|
+
|
|
135
|
+
Memory records can include:
|
|
136
|
+
|
|
137
|
+
- memory text
|
|
138
|
+
- memory type
|
|
139
|
+
- object ownership
|
|
140
|
+
- timestamps and session IDs
|
|
141
|
+
- evidence references
|
|
142
|
+
- graph nodes and links
|
|
143
|
+
- additional runtime metadata
|
|
144
|
+
|
|
145
|
+
### Supported Backends
|
|
146
|
+
|
|
147
|
+
| Backend | What it Does |
|
|
148
|
+
|---------|--------------|
|
|
149
|
+
| **LanceDB** | Local vector storage and graph-aware retrieval (default) |
|
|
150
|
+
| **Qdrant** | Remote or self-hosted vector storage |
|
|
151
|
+
| **Provider Gateway** | Routes extraction tasks to configured LLM or VLM providers |
|
|
152
|
+
|
|
153
|
+
By default, AlphaAvatar can run with local LanceDB storage. Raw camera frames, audio buffers, and other heavy runtime payloads are not persisted as memory items.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## 🔗 How Memory Connects to Other Modules
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
PerceptionRuntime
|
|
161
|
+
└── → ENV Memory (visual and future audio observations)
|
|
162
|
+
|
|
163
|
+
Persona Plugin
|
|
164
|
+
└── → Identity Aliases (face / speaker / user relationships)
|
|
165
|
+
|
|
166
|
+
RAG / DeepResearch / MCP
|
|
167
|
+
└── → Tool Memory (documents, research, and actions)
|
|
168
|
+
|
|
169
|
+
Memory Plugin
|
|
170
|
+
├── → Avatar Runtime (dynamic per-turn context)
|
|
171
|
+
├── → Graph Retrieval (entity and relationship lookup)
|
|
172
|
+
├── → Reflection* (behavior improvement)
|
|
173
|
+
└── → Planning* (goals and reminders)
|
|
174
|
+
|
|
175
|
+
* Planned
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 🙋 Common Questions
|
|
181
|
+
|
|
182
|
+
**Q: Does memory work across sessions?**
|
|
183
|
+
Yes. Stored memories can be retrieved in later sessions.
|
|
184
|
+
|
|
185
|
+
**Q: Does ENV memory save my raw camera stream?**
|
|
186
|
+
No. Raw runtime frames are not stored as memory records. The configured multimodal model extracts useful environment memories from selected observation windows.
|
|
187
|
+
|
|
188
|
+
**Q: Is ENV memory always enabled?**
|
|
189
|
+
No. It is optional and only runs when `env_delta_task` is configured.
|
|
190
|
+
|
|
191
|
+
**Q: Can memory distinguish different users?**
|
|
192
|
+
Memory supports multi-object ownership and graph aliases. Persona can resolve temporary face or speaker identities to stable users.
|
|
193
|
+
|
|
194
|
+
**Q: Can I see or delete individual memories?**
|
|
195
|
+
Fine-grained inspection, correction, export, and deletion controls are still being developed.
|
|
196
|
+
|
|
197
|
+
**Q: Is my data private?**
|
|
198
|
+
Local LanceDB storage keeps memory data on your own machine unless you configure a remote backend or external model provider.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 🚀 Coming Soon
|
|
203
|
+
|
|
204
|
+
| Feature | Description |
|
|
205
|
+
|---------|-------------|
|
|
206
|
+
| 🎤 Audio ENV Memory | Extract useful events and context from continuous audio streams |
|
|
207
|
+
| 🔍 Rich Visual-history Search | Search by objects, events, identities, and time ranges |
|
|
208
|
+
| 🧩 Multi-annotation Fusion | Combine face, speaker, object, action, and scene annotations |
|
|
209
|
+
| 🔒 Memory Privacy Controls | Inspect, edit, export, and delete memories |
|
|
210
|
+
| 👥 Stronger Multi-user Memory | Better separation and merging across shared sessions |
|
|
211
|
+
| 🧠 Reflection & Planning | Use memory for longer-term behavior improvement and goals |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 📚 Related Links
|
|
216
|
+
|
|
217
|
+
- [AlphaAvatar ROADMAP — Memory Section](https://github.com/AlphaAvatar/AlphaAvatar/blob/main/ROADMAP.md#-memory)
|
|
218
|
+
- [Persona Plugin](https://github.com/AlphaAvatar/AlphaAvatar/blob/main/avatar-plugins/avatar-plugins-persona/README.md)
|
|
219
|
+
- [LanceDB Documentation](https://lancedb.com/docs/)
|
|
220
|
+
- [Qdrant Documentation](https://qdrant.tech/documentation/)
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import os
|
|
15
15
|
|
|
16
16
|
from alphaavatar.agents import AvatarModule, AvatarPlugin
|
|
17
|
-
from alphaavatar.agents.runtime import
|
|
17
|
+
from alphaavatar.agents.runtime import AvatarRuntime
|
|
18
18
|
|
|
19
19
|
from .log import logger
|
|
20
20
|
from .memory_runtime import MemoryRuntime
|
|
@@ -33,7 +33,8 @@ class MemoryPlugin(AvatarPlugin):
|
|
|
33
33
|
|
|
34
34
|
def get_plugin(
|
|
35
35
|
self,
|
|
36
|
-
|
|
36
|
+
runtime: AvatarRuntime,
|
|
37
|
+
avatar_id: str,
|
|
37
38
|
memory_search_context: int,
|
|
38
39
|
memory_recall_num: int,
|
|
39
40
|
maximum_memory_num: int,
|
|
@@ -43,7 +44,8 @@ class MemoryPlugin(AvatarPlugin):
|
|
|
43
44
|
) -> MemoryRuntime:
|
|
44
45
|
try:
|
|
45
46
|
return MemoryRuntime(
|
|
46
|
-
|
|
47
|
+
runtime=runtime,
|
|
48
|
+
avatar_id=avatar_id,
|
|
47
49
|
memory_search_context=memory_search_context,
|
|
48
50
|
memory_recall_num=memory_recall_num,
|
|
49
51
|
maximum_memory_num=maximum_memory_num,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
from .graph_alias import save_graph_aliases
|
|
15
|
+
from .graph_builder import build_graph_from_mentions
|
|
16
|
+
from .graph_lookup import GraphLookup
|
|
17
|
+
from .graph_store import save_memory_graph_stubs
|
|
18
|
+
|
|
19
|
+
__all__ = [
|
|
20
|
+
"save_graph_aliases",
|
|
21
|
+
"build_graph_from_mentions",
|
|
22
|
+
"GraphLookup",
|
|
23
|
+
"save_memory_graph_stubs",
|
|
24
|
+
]
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Copyright 2026 AlphaAvatar project
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
import json
|
|
15
|
+
import pathlib
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _json_dumps(value: Any) -> str:
|
|
20
|
+
return json.dumps(value, ensure_ascii=False, default=str)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _json_loads(line: str) -> dict[str, Any] | None:
|
|
24
|
+
try:
|
|
25
|
+
data = json.loads(line)
|
|
26
|
+
return data if isinstance(data, dict) else None
|
|
27
|
+
except Exception:
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _read_alias_map(path: pathlib.Path) -> dict[str, dict[str, Any]]:
|
|
32
|
+
if not path.exists():
|
|
33
|
+
return {}
|
|
34
|
+
|
|
35
|
+
out: dict[str, dict[str, Any]] = {}
|
|
36
|
+
|
|
37
|
+
for line in path.read_text(encoding="utf-8").splitlines():
|
|
38
|
+
line = line.strip()
|
|
39
|
+
if not line:
|
|
40
|
+
continue
|
|
41
|
+
|
|
42
|
+
row = _json_loads(line)
|
|
43
|
+
if not row:
|
|
44
|
+
continue
|
|
45
|
+
|
|
46
|
+
alias_key = str(row.get("alias_key", "")).strip()
|
|
47
|
+
canonical_key = str(row.get("canonical_key", "")).strip()
|
|
48
|
+
|
|
49
|
+
if not alias_key or not canonical_key:
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
out[alias_key] = row
|
|
53
|
+
|
|
54
|
+
return out
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def _write_aliases(path: pathlib.Path, aliases: dict[str, dict[str, Any]]) -> None:
|
|
58
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
|
|
60
|
+
rows = sorted(
|
|
61
|
+
aliases.values(),
|
|
62
|
+
key=lambda x: (
|
|
63
|
+
str(x.get("canonical_key", "")),
|
|
64
|
+
str(x.get("alias_key", "")),
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
text = "\n".join(_json_dumps(row) for row in rows)
|
|
69
|
+
path.write_text(text + ("\n" if text else ""), encoding="utf-8")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def save_graph_aliases(
|
|
73
|
+
*,
|
|
74
|
+
graph_path: str | pathlib.Path,
|
|
75
|
+
aliases: list[dict[str, Any]],
|
|
76
|
+
) -> dict[str, Any]:
|
|
77
|
+
graph_path = pathlib.Path(graph_path)
|
|
78
|
+
aliases_path = graph_path / "aliases.jsonl"
|
|
79
|
+
|
|
80
|
+
alias_map = _read_alias_map(aliases_path)
|
|
81
|
+
|
|
82
|
+
updated = 0
|
|
83
|
+
skipped = 0
|
|
84
|
+
conflicts: list[dict[str, Any]] = []
|
|
85
|
+
|
|
86
|
+
for alias in aliases:
|
|
87
|
+
alias_key = str(alias.get("alias_key", "")).strip()
|
|
88
|
+
canonical_key = str(alias.get("canonical_key", "")).strip()
|
|
89
|
+
|
|
90
|
+
if not alias_key or not canonical_key or alias_key == canonical_key:
|
|
91
|
+
skipped += 1
|
|
92
|
+
continue
|
|
93
|
+
|
|
94
|
+
# local detector keys must already be scoped before aliasing
|
|
95
|
+
if alias_key.startswith(("face:", "voice:", "object:")) and ":local:" not in alias_key:
|
|
96
|
+
skipped += 1
|
|
97
|
+
conflicts.append(
|
|
98
|
+
{
|
|
99
|
+
"alias_key": alias_key,
|
|
100
|
+
"canonical_key": canonical_key,
|
|
101
|
+
"reason": "unscoped_local_key",
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
continue
|
|
105
|
+
|
|
106
|
+
old = alias_map.get(alias_key)
|
|
107
|
+
|
|
108
|
+
if old:
|
|
109
|
+
old_canonical = str(old.get("canonical_key", "")).strip()
|
|
110
|
+
old_weight = float(old.get("weight", 0.0))
|
|
111
|
+
new_weight = float(alias.get("weight", 0.0))
|
|
112
|
+
|
|
113
|
+
# If conflict, only replace when new confidence is higher.
|
|
114
|
+
if old_canonical and old_canonical != canonical_key and new_weight < old_weight:
|
|
115
|
+
conflicts.append(
|
|
116
|
+
{
|
|
117
|
+
"alias_key": alias_key,
|
|
118
|
+
"old_canonical_key": old_canonical,
|
|
119
|
+
"new_canonical_key": canonical_key,
|
|
120
|
+
"old_weight": old_weight,
|
|
121
|
+
"new_weight": new_weight,
|
|
122
|
+
"reason": "lower_confidence_conflict",
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
skipped += 1
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
merged = dict(old)
|
|
129
|
+
merged.update(alias)
|
|
130
|
+
alias_map[alias_key] = merged
|
|
131
|
+
else:
|
|
132
|
+
alias_map[alias_key] = alias
|
|
133
|
+
|
|
134
|
+
updated += 1
|
|
135
|
+
|
|
136
|
+
_write_aliases(aliases_path, alias_map)
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
"aliases_file": str(aliases_path),
|
|
140
|
+
"aliases": len(alias_map),
|
|
141
|
+
"updated": updated,
|
|
142
|
+
"skipped": skipped,
|
|
143
|
+
"conflicts": conflicts,
|
|
144
|
+
}
|