memorycore-ai 0.4.0__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.
- memorycore_ai-0.4.0/PKG-INFO +92 -0
- memorycore_ai-0.4.0/README.md +61 -0
- memorycore_ai-0.4.0/memory_core/__init__.py +16 -0
- memorycore_ai-0.4.0/memory_core/client.py +355 -0
- memorycore_ai-0.4.0/memorycore_ai.egg-info/PKG-INFO +92 -0
- memorycore_ai-0.4.0/memorycore_ai.egg-info/SOURCES.txt +9 -0
- memorycore_ai-0.4.0/memorycore_ai.egg-info/dependency_links.txt +1 -0
- memorycore_ai-0.4.0/memorycore_ai.egg-info/requires.txt +8 -0
- memorycore_ai-0.4.0/memorycore_ai.egg-info/top_level.txt +1 -0
- memorycore_ai-0.4.0/pyproject.toml +45 -0
- memorycore_ai-0.4.0/setup.cfg +4 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memorycore-ai
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Universal memory engine for AI bots. 3 layers: Redis (Hot) + Qdrant (Warm) + Neo4j (Cold). FZ-152 compliant.
|
|
5
|
+
Author-email: Otel Group <info@otelgroup.ru>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://memorycore.ru
|
|
8
|
+
Project-URL: Documentation, https://api.memorycore.ru/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/aleksandrboss3090-code/memory-core-sdk
|
|
10
|
+
Project-URL: Dashboard, https://memorycore.ru/dashboard
|
|
11
|
+
Keywords: ai,memory,bots,telegram,qdrant,redis,neo4j,embeddings,semantic-search
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Requires-Dist: requests>=2.28.0
|
|
26
|
+
Provides-Extra: async
|
|
27
|
+
Requires-Dist: httpx>=0.24.0; extra == "async"
|
|
28
|
+
Provides-Extra: all
|
|
29
|
+
Requires-Dist: requests>=2.28.0; extra == "all"
|
|
30
|
+
Requires-Dist: httpx>=0.24.0; extra == "all"
|
|
31
|
+
|
|
32
|
+
# Memory Core SDK
|
|
33
|
+
|
|
34
|
+
Universal memory engine for AI bots. 3 layers: Redis (Hot) + Qdrant (Warm) + Neo4j (Cold).
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install memory-core
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from memory_core import MemoryClient
|
|
44
|
+
|
|
45
|
+
memory = MemoryClient("mc_live_...")
|
|
46
|
+
|
|
47
|
+
# Bot remembers
|
|
48
|
+
memory.upsert(user_id="user_42", content="Люблю итальянскую кухню")
|
|
49
|
+
|
|
50
|
+
# Bot recalls
|
|
51
|
+
ctx = memory.context(user_id="user_42", query="что заказать на ужин?")
|
|
52
|
+
# → Hot: fresh messages
|
|
53
|
+
# → Warm: "итальянская кухня" (score: 0.82)
|
|
54
|
+
# → Cold: user knowledge graph
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Async (for aiogram, FastAPI)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install memory-core[async]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from memory_core import AsyncMemoryClient
|
|
65
|
+
|
|
66
|
+
memory = AsyncMemoryClient("mc_live_...", bot_id="my_bot")
|
|
67
|
+
|
|
68
|
+
await memory.upsert(user_id="user_42", content="Предпочитает SPA")
|
|
69
|
+
ctx = await memory.context(user_id="user_42", query="что предложить?")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API
|
|
73
|
+
|
|
74
|
+
| Method | Description |
|
|
75
|
+
|--------|-------------|
|
|
76
|
+
| `upsert(user_id, content)` | Save to memory (Hot+Warm+Cold) |
|
|
77
|
+
| `context(user_id, query)` | Retrieve relevant context |
|
|
78
|
+
| `remember(user_id, fact)` | Shortcut: save a fact |
|
|
79
|
+
| `recall(user_id, query)` | Shortcut: semantic search |
|
|
80
|
+
| `summarize(user_id)` | Summarize session into episode |
|
|
81
|
+
| `profile(user_id)` | Full user profile |
|
|
82
|
+
| `health()` | API health check |
|
|
83
|
+
|
|
84
|
+
## Links
|
|
85
|
+
|
|
86
|
+
- **Landing**: https://memorycore.ru
|
|
87
|
+
- **API Docs**: https://api.memorycore.ru/docs
|
|
88
|
+
- **Dashboard**: https://memorycore.ru/dashboard
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT - (c) 2025-2026 Otel Group
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Memory Core SDK
|
|
2
|
+
|
|
3
|
+
Universal memory engine for AI bots. 3 layers: Redis (Hot) + Qdrant (Warm) + Neo4j (Cold).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install memory-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
from memory_core import MemoryClient
|
|
13
|
+
|
|
14
|
+
memory = MemoryClient("mc_live_...")
|
|
15
|
+
|
|
16
|
+
# Bot remembers
|
|
17
|
+
memory.upsert(user_id="user_42", content="Люблю итальянскую кухню")
|
|
18
|
+
|
|
19
|
+
# Bot recalls
|
|
20
|
+
ctx = memory.context(user_id="user_42", query="что заказать на ужин?")
|
|
21
|
+
# → Hot: fresh messages
|
|
22
|
+
# → Warm: "итальянская кухня" (score: 0.82)
|
|
23
|
+
# → Cold: user knowledge graph
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Async (for aiogram, FastAPI)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install memory-core[async]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from memory_core import AsyncMemoryClient
|
|
34
|
+
|
|
35
|
+
memory = AsyncMemoryClient("mc_live_...", bot_id="my_bot")
|
|
36
|
+
|
|
37
|
+
await memory.upsert(user_id="user_42", content="Предпочитает SPA")
|
|
38
|
+
ctx = await memory.context(user_id="user_42", query="что предложить?")
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## API
|
|
42
|
+
|
|
43
|
+
| Method | Description |
|
|
44
|
+
|--------|-------------|
|
|
45
|
+
| `upsert(user_id, content)` | Save to memory (Hot+Warm+Cold) |
|
|
46
|
+
| `context(user_id, query)` | Retrieve relevant context |
|
|
47
|
+
| `remember(user_id, fact)` | Shortcut: save a fact |
|
|
48
|
+
| `recall(user_id, query)` | Shortcut: semantic search |
|
|
49
|
+
| `summarize(user_id)` | Summarize session into episode |
|
|
50
|
+
| `profile(user_id)` | Full user profile |
|
|
51
|
+
| `health()` | API health check |
|
|
52
|
+
|
|
53
|
+
## Links
|
|
54
|
+
|
|
55
|
+
- **Landing**: https://memorycore.ru
|
|
56
|
+
- **API Docs**: https://api.memorycore.ru/docs
|
|
57
|
+
- **Dashboard**: https://memorycore.ru/dashboard
|
|
58
|
+
|
|
59
|
+
## License
|
|
60
|
+
|
|
61
|
+
MIT - (c) 2025-2026 Otel Group
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Memory Core SDK — Универсальный движок памяти для AI-ботов.
|
|
3
|
+
|
|
4
|
+
Подключите за 3 строки:
|
|
5
|
+
from memory_core import MemoryClient
|
|
6
|
+
memory = MemoryClient("mc_live_...")
|
|
7
|
+
memory.upsert(user_id="user_42", content="Люблю итальянскую кухню")
|
|
8
|
+
|
|
9
|
+
Docs: https://api.memorycore.ru/docs
|
|
10
|
+
Site: https://memorycore.ru
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from memory_core.client import MemoryClient, AsyncMemoryClient
|
|
14
|
+
|
|
15
|
+
__version__ = "0.3.3"
|
|
16
|
+
__all__ = ["MemoryClient", "AsyncMemoryClient"]
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Memory Core SDK — Python Client
|
|
3
|
+
Sync (requests) + Async (httpx) клиенты для Memory Core API.
|
|
4
|
+
|
|
5
|
+
Автор: Алита (Claude) для семьи Науменко
|
|
6
|
+
Продукт: ООО «Отель Групп»
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Optional, Any
|
|
10
|
+
import json
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# === SYNC CLIENT (requests) ===
|
|
14
|
+
|
|
15
|
+
class MemoryClient:
|
|
16
|
+
"""
|
|
17
|
+
Синхронный клиент Memory Core API.
|
|
18
|
+
|
|
19
|
+
Использование:
|
|
20
|
+
from memory_core import MemoryClient
|
|
21
|
+
|
|
22
|
+
memory = MemoryClient("mc_live_...")
|
|
23
|
+
|
|
24
|
+
# Сохранить
|
|
25
|
+
memory.upsert(user_id="user_42", content="Люблю итальянскую кухню")
|
|
26
|
+
|
|
27
|
+
# Вспомнить
|
|
28
|
+
ctx = memory.context(user_id="user_42", query="что заказать на ужин?")
|
|
29
|
+
print(ctx["warm_episodes"])
|
|
30
|
+
|
|
31
|
+
# Профиль
|
|
32
|
+
profile = memory.profile("user_42")
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
DEFAULT_URL = "https://api.memorycore.ru/api/v1"
|
|
36
|
+
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
api_key: str,
|
|
40
|
+
base_url: str = None,
|
|
41
|
+
bot_id: str = "default",
|
|
42
|
+
timeout: float = 15.0,
|
|
43
|
+
):
|
|
44
|
+
"""
|
|
45
|
+
Args:
|
|
46
|
+
api_key: API-ключ (получите на memorycore.ru)
|
|
47
|
+
base_url: URL API (по умолчанию https://api.memorycore.ru/api/v1)
|
|
48
|
+
bot_id: ID вашего бота (для разделения контекстов)
|
|
49
|
+
timeout: таймаут запросов в секундах
|
|
50
|
+
"""
|
|
51
|
+
try:
|
|
52
|
+
import requests
|
|
53
|
+
except ImportError:
|
|
54
|
+
raise ImportError(
|
|
55
|
+
"Для MemoryClient нужен пакет requests: pip install requests"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
self._api_key = api_key
|
|
59
|
+
self._base_url = (base_url or self.DEFAULT_URL).rstrip("/")
|
|
60
|
+
self._bot_id = bot_id
|
|
61
|
+
self._timeout = timeout
|
|
62
|
+
self._session = requests.Session()
|
|
63
|
+
self._session.headers.update({
|
|
64
|
+
"X-API-Key": api_key,
|
|
65
|
+
"Content-Type": "application/json",
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
def _post(self, path: str, data: dict) -> dict:
|
|
69
|
+
"""POST запрос к API."""
|
|
70
|
+
resp = self._session.post(
|
|
71
|
+
f"{self._base_url}{path}",
|
|
72
|
+
json=data,
|
|
73
|
+
timeout=self._timeout,
|
|
74
|
+
)
|
|
75
|
+
resp.raise_for_status()
|
|
76
|
+
return resp.json()
|
|
77
|
+
|
|
78
|
+
def _get(self, path: str) -> dict:
|
|
79
|
+
"""GET запрос к API."""
|
|
80
|
+
resp = self._session.get(
|
|
81
|
+
f"{self._base_url}{path}",
|
|
82
|
+
timeout=self._timeout,
|
|
83
|
+
)
|
|
84
|
+
resp.raise_for_status()
|
|
85
|
+
return resp.json()
|
|
86
|
+
|
|
87
|
+
# === ОСНОВНЫЕ МЕТОДЫ ===
|
|
88
|
+
|
|
89
|
+
def upsert(
|
|
90
|
+
self,
|
|
91
|
+
user_id: str,
|
|
92
|
+
content: str,
|
|
93
|
+
bot_id: str = None,
|
|
94
|
+
memory_type: str = "message",
|
|
95
|
+
session_id: str = None,
|
|
96
|
+
metadata: dict = None,
|
|
97
|
+
importance: float = 0.5,
|
|
98
|
+
) -> dict:
|
|
99
|
+
"""
|
|
100
|
+
Сохранить запись в память.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
user_id: ID пользователя (telegram_id, email, etc.)
|
|
104
|
+
content: Текст для запоминания
|
|
105
|
+
bot_id: ID бота (по умолчанию self.bot_id)
|
|
106
|
+
memory_type: Тип записи (message, fact, episode, preference, entity)
|
|
107
|
+
session_id: ID сессии (для группировки)
|
|
108
|
+
metadata: Дополнительные данные
|
|
109
|
+
importance: Важность 0-1
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
{"status": "ok", "id": "uuid", "drums": {...}, "stored_in": [...]}
|
|
113
|
+
"""
|
|
114
|
+
return self._post("/memory/upsert", {
|
|
115
|
+
"user_id": user_id,
|
|
116
|
+
"bot_id": bot_id or self._bot_id,
|
|
117
|
+
"content": content,
|
|
118
|
+
"memory_type": memory_type,
|
|
119
|
+
"session_id": session_id,
|
|
120
|
+
"metadata": metadata or {},
|
|
121
|
+
"importance": importance,
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
def context(
|
|
125
|
+
self,
|
|
126
|
+
user_id: str,
|
|
127
|
+
query: str,
|
|
128
|
+
bot_id: str = None,
|
|
129
|
+
max_items: int = 10,
|
|
130
|
+
include_hot: bool = True,
|
|
131
|
+
include_warm: bool = True,
|
|
132
|
+
include_cold: bool = False,
|
|
133
|
+
min_similarity: float = 0.40,
|
|
134
|
+
) -> dict:
|
|
135
|
+
"""
|
|
136
|
+
Получить контекст — релевантные воспоминания для бота.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
user_id: ID пользователя
|
|
140
|
+
query: Текущий запрос пользователя
|
|
141
|
+
bot_id: ID бота
|
|
142
|
+
max_items: Максимум результатов
|
|
143
|
+
include_hot: Включить HOT (Redis, текущая сессия)
|
|
144
|
+
include_warm: Включить WARM (Qdrant, семантический поиск)
|
|
145
|
+
include_cold: Включить COLD (Neo4j, граф знаний)
|
|
146
|
+
min_similarity: Минимальный score для WARM
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
{
|
|
150
|
+
"user_id": "...",
|
|
151
|
+
"hot_messages": [...],
|
|
152
|
+
"warm_episodes": [...],
|
|
153
|
+
"cold_graph": {...},
|
|
154
|
+
"drums": {...},
|
|
155
|
+
"total_items": N
|
|
156
|
+
}
|
|
157
|
+
"""
|
|
158
|
+
return self._post("/memory/context", {
|
|
159
|
+
"user_id": user_id,
|
|
160
|
+
"bot_id": bot_id or self._bot_id,
|
|
161
|
+
"query": query,
|
|
162
|
+
"max_items": max_items,
|
|
163
|
+
"include_hot": include_hot,
|
|
164
|
+
"include_warm": include_warm,
|
|
165
|
+
"include_cold": include_cold,
|
|
166
|
+
"min_similarity": min_similarity,
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
def summarize(
|
|
170
|
+
self,
|
|
171
|
+
user_id: str,
|
|
172
|
+
bot_id: str = None,
|
|
173
|
+
session_id: str = "default",
|
|
174
|
+
) -> dict:
|
|
175
|
+
"""
|
|
176
|
+
Суммаризировать сессию — создать эпизод из сообщений.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
user_id: ID пользователя
|
|
180
|
+
bot_id: ID бота
|
|
181
|
+
session_id: ID сессии для суммаризации
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
{"status": "summarized", "episode_id": "...", "messages_count": N}
|
|
185
|
+
"""
|
|
186
|
+
return self._post("/memory/summarize", {
|
|
187
|
+
"user_id": user_id,
|
|
188
|
+
"bot_id": bot_id or self._bot_id,
|
|
189
|
+
"session_id": session_id,
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
def profile(self, user_id: str) -> dict:
|
|
193
|
+
"""
|
|
194
|
+
Профиль пользователя — агрегация всех знаний.
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
{"user_id": "...", "facts": [...], "preferences": [...], "graph_summary": "..."}
|
|
198
|
+
"""
|
|
199
|
+
return self._get(f"/memory/profile/{user_id}")
|
|
200
|
+
|
|
201
|
+
def stats(self, user_id: str) -> dict:
|
|
202
|
+
"""Статистика по пользователю."""
|
|
203
|
+
return self._get(f"/memory/stats/{user_id}")
|
|
204
|
+
|
|
205
|
+
def health(self) -> dict:
|
|
206
|
+
"""Проверка здоровья API."""
|
|
207
|
+
return self._get("/health")
|
|
208
|
+
|
|
209
|
+
# === УДОБНЫЕ МЕТОДЫ ===
|
|
210
|
+
|
|
211
|
+
def remember(self, user_id: str, fact: str, **kwargs) -> dict:
|
|
212
|
+
"""Короткий метод — запомнить факт."""
|
|
213
|
+
return self.upsert(user_id=user_id, content=fact, memory_type="fact", **kwargs)
|
|
214
|
+
|
|
215
|
+
def recall(self, user_id: str, query: str, **kwargs) -> list:
|
|
216
|
+
"""Короткий метод — вспомнить (только WARM результаты)."""
|
|
217
|
+
ctx = self.context(user_id=user_id, query=query, **kwargs)
|
|
218
|
+
return ctx.get("warm_episodes", [])
|
|
219
|
+
|
|
220
|
+
def __repr__(self):
|
|
221
|
+
masked_key = self._api_key[:12] + "..." if len(self._api_key) > 12 else "***"
|
|
222
|
+
return f"MemoryClient(api_key='{masked_key}', bot_id='{self._bot_id}')"
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
# === ASYNC CLIENT (httpx) ===
|
|
226
|
+
|
|
227
|
+
class AsyncMemoryClient:
|
|
228
|
+
"""
|
|
229
|
+
Асинхронный клиент Memory Core API (для aiogram, FastAPI, asyncio).
|
|
230
|
+
|
|
231
|
+
Использование:
|
|
232
|
+
from memory_core import AsyncMemoryClient
|
|
233
|
+
|
|
234
|
+
memory = AsyncMemoryClient("mc_live_...")
|
|
235
|
+
|
|
236
|
+
# В async функции:
|
|
237
|
+
await memory.upsert(user_id="user_42", content="Люблю SPA")
|
|
238
|
+
ctx = await memory.context(user_id="user_42", query="что предложить?")
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
DEFAULT_URL = "https://api.memorycore.ru/api/v1"
|
|
242
|
+
|
|
243
|
+
def __init__(
|
|
244
|
+
self,
|
|
245
|
+
api_key: str,
|
|
246
|
+
base_url: str = None,
|
|
247
|
+
bot_id: str = "default",
|
|
248
|
+
timeout: float = 15.0,
|
|
249
|
+
):
|
|
250
|
+
try:
|
|
251
|
+
import httpx
|
|
252
|
+
except ImportError:
|
|
253
|
+
raise ImportError(
|
|
254
|
+
"Для AsyncMemoryClient нужен пакет httpx: pip install httpx"
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
self._api_key = api_key
|
|
258
|
+
self._base_url = (base_url or self.DEFAULT_URL).rstrip("/")
|
|
259
|
+
self._bot_id = bot_id
|
|
260
|
+
self._timeout = timeout
|
|
261
|
+
self._client = None
|
|
262
|
+
|
|
263
|
+
async def _get_client(self):
|
|
264
|
+
if self._client is None:
|
|
265
|
+
import httpx
|
|
266
|
+
self._client = httpx.AsyncClient(
|
|
267
|
+
headers={
|
|
268
|
+
"X-API-Key": self._api_key,
|
|
269
|
+
"Content-Type": "application/json",
|
|
270
|
+
},
|
|
271
|
+
timeout=self._timeout,
|
|
272
|
+
)
|
|
273
|
+
return self._client
|
|
274
|
+
|
|
275
|
+
async def _post(self, path: str, data: dict) -> dict:
|
|
276
|
+
client = await self._get_client()
|
|
277
|
+
resp = await client.post(f"{self._base_url}{path}", json=data)
|
|
278
|
+
resp.raise_for_status()
|
|
279
|
+
return resp.json()
|
|
280
|
+
|
|
281
|
+
async def _get(self, path: str) -> dict:
|
|
282
|
+
client = await self._get_client()
|
|
283
|
+
resp = await client.get(f"{self._base_url}{path}")
|
|
284
|
+
resp.raise_for_status()
|
|
285
|
+
return resp.json()
|
|
286
|
+
|
|
287
|
+
async def upsert(self, user_id: str, content: str, bot_id: str = None,
|
|
288
|
+
memory_type: str = "message", session_id: str = None,
|
|
289
|
+
metadata: dict = None, importance: float = 0.5) -> dict:
|
|
290
|
+
"""Сохранить запись в память (async)."""
|
|
291
|
+
return await self._post("/memory/upsert", {
|
|
292
|
+
"user_id": user_id,
|
|
293
|
+
"bot_id": bot_id or self._bot_id,
|
|
294
|
+
"content": content,
|
|
295
|
+
"memory_type": memory_type,
|
|
296
|
+
"session_id": session_id,
|
|
297
|
+
"metadata": metadata or {},
|
|
298
|
+
"importance": importance,
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
async def context(self, user_id: str, query: str, bot_id: str = None,
|
|
302
|
+
max_items: int = 10, include_hot: bool = True,
|
|
303
|
+
include_warm: bool = True, include_cold: bool = False,
|
|
304
|
+
min_similarity: float = 0.40) -> dict:
|
|
305
|
+
"""Получить контекст (async)."""
|
|
306
|
+
return await self._post("/memory/context", {
|
|
307
|
+
"user_id": user_id,
|
|
308
|
+
"bot_id": bot_id or self._bot_id,
|
|
309
|
+
"query": query,
|
|
310
|
+
"max_items": max_items,
|
|
311
|
+
"include_hot": include_hot,
|
|
312
|
+
"include_warm": include_warm,
|
|
313
|
+
"include_cold": include_cold,
|
|
314
|
+
"min_similarity": min_similarity,
|
|
315
|
+
})
|
|
316
|
+
|
|
317
|
+
async def summarize(self, user_id: str, bot_id: str = None,
|
|
318
|
+
session_id: str = "default") -> dict:
|
|
319
|
+
"""Суммаризировать сессию (async)."""
|
|
320
|
+
return await self._post("/memory/summarize", {
|
|
321
|
+
"user_id": user_id,
|
|
322
|
+
"bot_id": bot_id or self._bot_id,
|
|
323
|
+
"session_id": session_id,
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
async def profile(self, user_id: str) -> dict:
|
|
327
|
+
"""Профиль пользователя (async)."""
|
|
328
|
+
return await self._get(f"/memory/profile/{user_id}")
|
|
329
|
+
|
|
330
|
+
async def stats(self, user_id: str) -> dict:
|
|
331
|
+
"""Статистика (async)."""
|
|
332
|
+
return await self._get(f"/memory/stats/{user_id}")
|
|
333
|
+
|
|
334
|
+
async def health(self) -> dict:
|
|
335
|
+
"""Health check (async)."""
|
|
336
|
+
return await self._get("/health")
|
|
337
|
+
|
|
338
|
+
async def remember(self, user_id: str, fact: str, **kwargs) -> dict:
|
|
339
|
+
"""Запомнить факт (async)."""
|
|
340
|
+
return await self.upsert(user_id=user_id, content=fact, memory_type="fact", **kwargs)
|
|
341
|
+
|
|
342
|
+
async def recall(self, user_id: str, query: str, **kwargs) -> list:
|
|
343
|
+
"""Вспомнить (async)."""
|
|
344
|
+
ctx = await self.context(user_id=user_id, query=query, **kwargs)
|
|
345
|
+
return ctx.get("warm_episodes", [])
|
|
346
|
+
|
|
347
|
+
async def close(self):
|
|
348
|
+
"""Закрыть HTTP клиент."""
|
|
349
|
+
if self._client:
|
|
350
|
+
await self._client.aclose()
|
|
351
|
+
self._client = None
|
|
352
|
+
|
|
353
|
+
def __repr__(self):
|
|
354
|
+
masked_key = self._api_key[:12] + "..." if len(self._api_key) > 12 else "***"
|
|
355
|
+
return f"AsyncMemoryClient(api_key='{masked_key}', bot_id='{self._bot_id}')"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: memorycore-ai
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: Universal memory engine for AI bots. 3 layers: Redis (Hot) + Qdrant (Warm) + Neo4j (Cold). FZ-152 compliant.
|
|
5
|
+
Author-email: Otel Group <info@otelgroup.ru>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://memorycore.ru
|
|
8
|
+
Project-URL: Documentation, https://api.memorycore.ru/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/aleksandrboss3090-code/memory-core-sdk
|
|
10
|
+
Project-URL: Dashboard, https://memorycore.ru/dashboard
|
|
11
|
+
Keywords: ai,memory,bots,telegram,qdrant,redis,neo4j,embeddings,semantic-search
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
Requires-Dist: requests>=2.28.0
|
|
26
|
+
Provides-Extra: async
|
|
27
|
+
Requires-Dist: httpx>=0.24.0; extra == "async"
|
|
28
|
+
Provides-Extra: all
|
|
29
|
+
Requires-Dist: requests>=2.28.0; extra == "all"
|
|
30
|
+
Requires-Dist: httpx>=0.24.0; extra == "all"
|
|
31
|
+
|
|
32
|
+
# Memory Core SDK
|
|
33
|
+
|
|
34
|
+
Universal memory engine for AI bots. 3 layers: Redis (Hot) + Qdrant (Warm) + Neo4j (Cold).
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
pip install memory-core
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
from memory_core import MemoryClient
|
|
44
|
+
|
|
45
|
+
memory = MemoryClient("mc_live_...")
|
|
46
|
+
|
|
47
|
+
# Bot remembers
|
|
48
|
+
memory.upsert(user_id="user_42", content="Люблю итальянскую кухню")
|
|
49
|
+
|
|
50
|
+
# Bot recalls
|
|
51
|
+
ctx = memory.context(user_id="user_42", query="что заказать на ужин?")
|
|
52
|
+
# → Hot: fresh messages
|
|
53
|
+
# → Warm: "итальянская кухня" (score: 0.82)
|
|
54
|
+
# → Cold: user knowledge graph
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Async (for aiogram, FastAPI)
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install memory-core[async]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from memory_core import AsyncMemoryClient
|
|
65
|
+
|
|
66
|
+
memory = AsyncMemoryClient("mc_live_...", bot_id="my_bot")
|
|
67
|
+
|
|
68
|
+
await memory.upsert(user_id="user_42", content="Предпочитает SPA")
|
|
69
|
+
ctx = await memory.context(user_id="user_42", query="что предложить?")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## API
|
|
73
|
+
|
|
74
|
+
| Method | Description |
|
|
75
|
+
|--------|-------------|
|
|
76
|
+
| `upsert(user_id, content)` | Save to memory (Hot+Warm+Cold) |
|
|
77
|
+
| `context(user_id, query)` | Retrieve relevant context |
|
|
78
|
+
| `remember(user_id, fact)` | Shortcut: save a fact |
|
|
79
|
+
| `recall(user_id, query)` | Shortcut: semantic search |
|
|
80
|
+
| `summarize(user_id)` | Summarize session into episode |
|
|
81
|
+
| `profile(user_id)` | Full user profile |
|
|
82
|
+
| `health()` | API health check |
|
|
83
|
+
|
|
84
|
+
## Links
|
|
85
|
+
|
|
86
|
+
- **Landing**: https://memorycore.ru
|
|
87
|
+
- **API Docs**: https://api.memorycore.ru/docs
|
|
88
|
+
- **Dashboard**: https://memorycore.ru/dashboard
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT - (c) 2025-2026 Otel Group
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
memory_core/__init__.py
|
|
4
|
+
memory_core/client.py
|
|
5
|
+
memorycore_ai.egg-info/PKG-INFO
|
|
6
|
+
memorycore_ai.egg-info/SOURCES.txt
|
|
7
|
+
memorycore_ai.egg-info/dependency_links.txt
|
|
8
|
+
memorycore_ai.egg-info/requires.txt
|
|
9
|
+
memorycore_ai.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
memory_core
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "memorycore-ai"
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "Universal memory engine for AI bots. 3 layers: Redis (Hot) + Qdrant (Warm) + Neo4j (Cold). FZ-152 compliant."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Otel Group", email = "info@otelgroup.ru"},
|
|
14
|
+
]
|
|
15
|
+
keywords = ["ai", "memory", "bots", "telegram", "qdrant", "redis", "neo4j", "embeddings", "semantic-search"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.8",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
dependencies = [
|
|
31
|
+
"requests>=2.28.0",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.optional-dependencies]
|
|
35
|
+
async = ["httpx>=0.24.0"]
|
|
36
|
+
all = ["requests>=2.28.0", "httpx>=0.24.0"]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://memorycore.ru"
|
|
40
|
+
Documentation = "https://api.memorycore.ru/docs"
|
|
41
|
+
Repository = "https://github.com/aleksandrboss3090-code/memory-core-sdk"
|
|
42
|
+
Dashboard = "https://memorycore.ru/dashboard"
|
|
43
|
+
|
|
44
|
+
[tool.setuptools.packages.find]
|
|
45
|
+
include = ["memory_core*"]
|