memio 0.1.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.
Files changed (60) hide show
  1. memio-0.1.0/.github/workflows/docs.yml +20 -0
  2. memio-0.1.0/.github/workflows/publish.yml +22 -0
  3. memio-0.1.0/.gitignore +9 -0
  4. memio-0.1.0/LICENSE +21 -0
  5. memio-0.1.0/PKG-INFO +24 -0
  6. memio-0.1.0/README.md +228 -0
  7. memio-0.1.0/docs/api/client.md +5 -0
  8. memio-0.1.0/docs/api/exceptions.md +5 -0
  9. memio-0.1.0/docs/api/models.md +13 -0
  10. memio-0.1.0/docs/api/protocols.md +11 -0
  11. memio-0.1.0/docs/concepts/architecture.md +168 -0
  12. memio-0.1.0/docs/contributing/adding-providers.md +232 -0
  13. memio-0.1.0/docs/contributing/development.md +113 -0
  14. memio-0.1.0/docs/getting-started/installation.md +88 -0
  15. memio-0.1.0/docs/getting-started/quickstart.md +248 -0
  16. memio-0.1.0/docs/guides/custom-providers.md +272 -0
  17. memio-0.1.0/docs/index.md +85 -0
  18. memio-0.1.0/docs/providers/chroma.md +171 -0
  19. memio-0.1.0/docs/providers/mem0.md +139 -0
  20. memio-0.1.0/docs/providers/zep.md +212 -0
  21. memio-0.1.0/memio/__init__.py +19 -0
  22. memio-0.1.0/memio/client.py +55 -0
  23. memio-0.1.0/memio/exceptions.py +19 -0
  24. memio-0.1.0/memio/models.py +101 -0
  25. memio-0.1.0/memio/protocols.py +87 -0
  26. memio-0.1.0/memio/providers/__init__.py +0 -0
  27. memio-0.1.0/memio/providers/chroma/__init__.py +3 -0
  28. memio-0.1.0/memio/providers/chroma/document.py +107 -0
  29. memio-0.1.0/memio/providers/mem0/__init__.py +5 -0
  30. memio-0.1.0/memio/providers/mem0/fact.py +162 -0
  31. memio-0.1.0/memio/providers/mem0/graph.py +130 -0
  32. memio-0.1.0/memio/providers/zep/__init__.py +5 -0
  33. memio-0.1.0/memio/providers/zep/fact.py +183 -0
  34. memio-0.1.0/memio/providers/zep/graph.py +159 -0
  35. memio-0.1.0/memio/providers/zep/history.py +158 -0
  36. memio-0.1.0/memio/py.typed +0 -0
  37. memio-0.1.0/mkdocs.yml +71 -0
  38. memio-0.1.0/pyproject.toml +27 -0
  39. memio-0.1.0/tests/__init__.py +0 -0
  40. memio-0.1.0/tests/conformance/__init__.py +0 -0
  41. memio-0.1.0/tests/conformance/document_store.py +36 -0
  42. memio-0.1.0/tests/conformance/fact_store.py +43 -0
  43. memio-0.1.0/tests/conformance/graph_store.py +19 -0
  44. memio-0.1.0/tests/conformance/history_store.py +31 -0
  45. memio-0.1.0/tests/conftest.py +0 -0
  46. memio-0.1.0/tests/integration/__init__.py +0 -0
  47. memio-0.1.0/tests/integration/test_chroma.py +17 -0
  48. memio-0.1.0/tests/integration/test_mem0.py +20 -0
  49. memio-0.1.0/tests/integration/test_zep.py +78 -0
  50. memio-0.1.0/tests/providers/__init__.py +0 -0
  51. memio-0.1.0/tests/providers/test_chroma_doc.py +114 -0
  52. memio-0.1.0/tests/providers/test_mem0_fact.py +119 -0
  53. memio-0.1.0/tests/providers/test_mem0_graph.py +90 -0
  54. memio-0.1.0/tests/providers/test_zep_fact.py +132 -0
  55. memio-0.1.0/tests/providers/test_zep_graph.py +104 -0
  56. memio-0.1.0/tests/providers/test_zep_history.py +162 -0
  57. memio-0.1.0/tests/test_client.py +131 -0
  58. memio-0.1.0/tests/test_exceptions.py +35 -0
  59. memio-0.1.0/tests/test_models.py +81 -0
  60. memio-0.1.0/tests/test_protocols.py +80 -0
@@ -0,0 +1,20 @@
1
+ name: Deploy docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ deploy:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: '3.12'
19
+ - run: pip install mkdocs-material "mkdocstrings[python]"
20
+ - run: mkdocs gh-deploy --force
@@ -0,0 +1,22 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+ id-token: write
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ environment: pypi
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: '3.12'
20
+ - run: pip install build
21
+ - run: python -m build
22
+ - uses: pypa/gh-action-pypi-publish@release/v1
memio-0.1.0/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ .superpowers/
5
+ .reference/
6
+ site/
7
+ docs/superpowers/
8
+ docs/specs/
9
+ dist/
memio-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 y3zai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
memio-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: memio
3
+ Version: 0.1.0
4
+ Summary: Unified memory gateway for AI agents
5
+ License-Expression: MIT
6
+ License-File: LICENSE
7
+ Requires-Python: >=3.10
8
+ Provides-Extra: all
9
+ Requires-Dist: chromadb; extra == 'all'
10
+ Requires-Dist: mem0ai; extra == 'all'
11
+ Requires-Dist: zep-cloud; extra == 'all'
12
+ Provides-Extra: chroma
13
+ Requires-Dist: chromadb; extra == 'chroma'
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
16
+ Requires-Dist: pytest-mock>=3.12; extra == 'dev'
17
+ Requires-Dist: pytest>=8.0; extra == 'dev'
18
+ Provides-Extra: docs
19
+ Requires-Dist: mkdocs-material; extra == 'docs'
20
+ Requires-Dist: mkdocstrings[python]; extra == 'docs'
21
+ Provides-Extra: mem0
22
+ Requires-Dist: mem0ai; extra == 'mem0'
23
+ Provides-Extra: zep
24
+ Requires-Dist: zep-cloud; extra == 'zep'
memio-0.1.0/README.md ADDED
@@ -0,0 +1,228 @@
1
+ # memio
2
+
3
+ Unified memory gateway for AI agents. One interface, multiple memory providers.
4
+
5
+ memio lets you swap between memory backends (Mem0, Zep, Chroma) without changing your application code. Define what memory capabilities you need — facts, conversation history, documents, knowledge graphs — and plug in any supported provider.
6
+
7
+ ## Features
8
+
9
+ - **Protocol-based architecture** — providers implement Python protocols, so you can mix and match or bring your own
10
+ - **Async-first** — all operations are `async`/`await`
11
+ - **Zero production dependencies** — install only the providers you need
12
+ - **Composable** — use Mem0 for facts, Zep for history, and Chroma for documents in the same client
13
+ - **Multi-tenant** — scope data by `user_id` or `agent_id`
14
+ - **Consistent error handling** — all provider errors wrapped in `ProviderError` with context
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ pip install memio
20
+ ```
21
+
22
+ Install with providers:
23
+
24
+ ```bash
25
+ pip install memio[mem0] # Mem0 provider
26
+ pip install memio[zep] # Zep provider
27
+ pip install memio[chroma] # Chroma provider
28
+ pip install memio[all] # All providers
29
+ ```
30
+
31
+ ## Quick start
32
+
33
+ ```python
34
+ from memio import Memio
35
+ from memio.providers.mem0 import Mem0FactAdapter
36
+ from memio.providers.zep import ZepHistoryAdapter
37
+ from memio.providers.chroma import ChromaDocumentAdapter
38
+ import chromadb
39
+
40
+ client = Memio(
41
+ facts=Mem0FactAdapter(api_key="your-mem0-key"),
42
+ history=ZepHistoryAdapter(api_key="your-zep-key"),
43
+ documents=ChromaDocumentAdapter(
44
+ client=chromadb.EphemeralClient(),
45
+ collection_name="my-docs",
46
+ ),
47
+ )
48
+
49
+ # Store and retrieve facts
50
+ fact = await client.facts.add(content="likes coffee", user_id="alice")
51
+ results = await client.facts.search(query="coffee", user_id="alice")
52
+
53
+ # Manage conversation history
54
+ from memio import Message
55
+
56
+ await client.history.add(
57
+ session_id="session-1",
58
+ messages=[
59
+ Message(role="user", content="hello"),
60
+ Message(role="assistant", content="hi there"),
61
+ ],
62
+ )
63
+ messages = await client.history.get(session_id="session-1")
64
+
65
+ # Store and search documents
66
+ doc = await client.documents.add(content="memio is a memory gateway")
67
+ results = await client.documents.search(query="memory")
68
+ ```
69
+
70
+ ## Memory stores
71
+
72
+ memio defines four memory store protocols. Each provider implements one or more:
73
+
74
+ | Store | Purpose | Mem0 | Zep | Chroma |
75
+ |-------|---------|------|-----|--------|
76
+ | `FactStore` | Structured facts about users/agents | yes | yes | - |
77
+ | `HistoryStore` | Conversation message history | - | yes | - |
78
+ | `DocumentStore` | Document storage with semantic search | - | - | yes |
79
+ | `GraphStore` | Knowledge graph triples | yes | yes | - |
80
+
81
+ ### FactStore
82
+
83
+ ```python
84
+ fact = await store.add(content="prefers dark mode", user_id="alice")
85
+ fact = await store.get(fact_id=fact.id)
86
+ results = await store.search(query="preferences", user_id="alice")
87
+ updated = await store.update(fact_id=fact.id, content="prefers light mode")
88
+ all_facts = await store.get_all(user_id="alice")
89
+ await store.delete(fact_id=fact.id)
90
+ await store.delete_all(user_id="alice")
91
+ ```
92
+
93
+ ### HistoryStore
94
+
95
+ ```python
96
+ await store.add(session_id="s1", messages=[Message(role="user", content="hello")])
97
+ messages = await store.get(session_id="s1", limit=50)
98
+ results = await store.search(session_id="s1", query="hello")
99
+ sessions = await store.get_all(user_id="alice")
100
+ await store.delete(session_id="s1")
101
+ await store.delete_all(user_id="alice")
102
+ ```
103
+
104
+ ### DocumentStore
105
+
106
+ ```python
107
+ doc = await store.add(content="some text", metadata={"source": "wiki"})
108
+ doc = await store.get(doc_id=doc.id)
109
+ results = await store.search(query="text", limit=10)
110
+ all_docs = await store.get_all(limit=100)
111
+ updated = await store.update(doc_id=doc.id, content="updated text")
112
+ await store.delete(doc_id=doc.id)
113
+ await store.delete_all()
114
+ ```
115
+
116
+ ### GraphStore
117
+
118
+ ```python
119
+ from memio import Triple
120
+
121
+ await store.add(
122
+ triples=[Triple(subject="Alice", predicate="likes", object="coffee")],
123
+ user_id="alice",
124
+ )
125
+ result = await store.get(entity="Alice", user_id="alice")
126
+ result = await store.search(query="coffee", user_id="alice")
127
+ await store.delete_all(user_id="alice")
128
+ ```
129
+
130
+ ## Data models
131
+
132
+ ```python
133
+ from memio import Fact, Message, Document, Triple, GraphResult
134
+
135
+ # Fact — a stored piece of knowledge
136
+ Fact(id, content, user_id, agent_id, metadata, score, created_at, updated_at)
137
+
138
+ # Message — a conversation message
139
+ Message(role, content, metadata, timestamp, name)
140
+
141
+ # Document — a stored document
142
+ Document(id, content, metadata, score, created_at, updated_at)
143
+
144
+ # Triple — a knowledge graph triple
145
+ Triple(subject, predicate, object, metadata)
146
+
147
+ # GraphResult — result from graph queries
148
+ GraphResult(triples, nodes, scores)
149
+ ```
150
+
151
+ ## Custom providers
152
+
153
+ Implement any protocol to create your own provider:
154
+
155
+ ```python
156
+ from memio import Memio, DocumentStore, Document
157
+
158
+ class MyDocumentStore:
159
+ async def add(self, *, content, doc_id=None, metadata=None):
160
+ # your implementation
161
+ return Document(id="...", content=content, metadata=metadata)
162
+
163
+ async def get(self, *, doc_id):
164
+ ...
165
+
166
+ async def search(self, *, query, limit=10, filters=None):
167
+ ...
168
+
169
+ async def update(self, *, doc_id, content, metadata=None):
170
+ ...
171
+
172
+ async def delete(self, *, doc_id):
173
+ ...
174
+
175
+ async def get_all(self, *, limit=100, filters=None):
176
+ ...
177
+
178
+ async def delete_all(self):
179
+ ...
180
+
181
+ # memio validates the protocol at runtime
182
+ client = Memio(documents=MyDocumentStore())
183
+ ```
184
+
185
+ ## Error handling
186
+
187
+ All provider errors are wrapped in `ProviderError`:
188
+
189
+ ```python
190
+ from memio import ProviderError, MemioError
191
+
192
+ try:
193
+ await client.facts.search(query="test", user_id="alice")
194
+ except ProviderError as e:
195
+ print(e.provider) # "mem0", "zep", etc.
196
+ print(e.operation) # "search", "add", etc.
197
+ print(e.cause) # original exception
198
+ except MemioError:
199
+ # base class for all memio errors
200
+ ...
201
+ ```
202
+
203
+ ## Provider notes
204
+
205
+ **Mem0** — content may be rephrased by Mem0's LLM. Duplicate content is deduplicated automatically.
206
+
207
+ **Zep** — graph operations are eventually consistent. `graph.add` sends text to an LLM for asynchronous fact extraction. Individual fact/triple deletion is not supported; use `delete_all` instead.
208
+
209
+ **Chroma** — uses a local client you provide. No API key required for ephemeral or persistent local usage.
210
+
211
+ ## Development
212
+
213
+ ```bash
214
+ git clone https://github.com/y3zai/memio.git
215
+ cd memio
216
+ python -m venv .venv && source .venv/bin/activate
217
+ pip install -e ".[all,dev]"
218
+
219
+ # Run unit tests
220
+ pytest
221
+
222
+ # Run integration tests (requires API keys)
223
+ MEM0_API_KEY=... ZEP_API_KEY=... pytest -m integration -v
224
+ ```
225
+
226
+ ## License
227
+
228
+ MIT
@@ -0,0 +1,5 @@
1
+ # Client
2
+
3
+ The `Memio` class is the main entry point for using memio.
4
+
5
+ ::: memio.client.Memio
@@ -0,0 +1,5 @@
1
+ # Exceptions
2
+
3
+ ::: memio.exceptions.MemioError
4
+
5
+ ::: memio.exceptions.ProviderError
@@ -0,0 +1,13 @@
1
+ # Models
2
+
3
+ Data models used across all providers.
4
+
5
+ ::: memio.models.Fact
6
+
7
+ ::: memio.models.Message
8
+
9
+ ::: memio.models.Document
10
+
11
+ ::: memio.models.Triple
12
+
13
+ ::: memio.models.GraphResult
@@ -0,0 +1,11 @@
1
+ # Protocols
2
+
3
+ Store protocols that providers must implement.
4
+
5
+ ::: memio.protocols.FactStore
6
+
7
+ ::: memio.protocols.HistoryStore
8
+
9
+ ::: memio.protocols.DocumentStore
10
+
11
+ ::: memio.protocols.GraphStore
@@ -0,0 +1,168 @@
1
+ # Architecture
2
+
3
+ memio is a unified memory gateway for AI agents. It lets you connect any
4
+ combination of memory providers behind a single client, so your agent code
5
+ never depends on a specific vendor SDK.
6
+
7
+ This page explains the design decisions that make that possible.
8
+
9
+ ## Protocol-based design
10
+
11
+ memio defines four store **protocols** using Python's `@runtime_checkable`
12
+ `Protocol` from the `typing` module:
13
+
14
+ | Protocol | Purpose |
15
+ |---|---|
16
+ | `FactStore` | Structured facts scoped to a user or agent |
17
+ | `HistoryStore` | Conversation message history grouped by session |
18
+ | `DocumentStore` | Documents with semantic search and metadata filtering |
19
+ | `GraphStore` | Knowledge graph triples (subject-predicate-object) |
20
+
21
+ Because these are protocols -- not base classes -- any class that provides the
22
+ right async methods satisfies the contract. No inheritance is required. The
23
+ `Memio` client validates each store with `isinstance()` at init time and raises
24
+ `TypeError` if the check fails.
25
+
26
+ ```python
27
+ from memio import Memio
28
+ from memio.providers.mem0 import Mem0FactAdapter
29
+
30
+ # Mem0FactAdapter has no base class -- it just implements
31
+ # the same async methods that FactStore declares.
32
+ client = Memio(facts=Mem0FactAdapter(api_key="..."))
33
+ ```
34
+
35
+ ## The adapter pattern
36
+
37
+ Each provider ships one or more **adapter** classes. An adapter translates
38
+ memio's protocol methods into the provider's own SDK calls and normalizes
39
+ responses into memio's data models:
40
+
41
+ | Model | Fields |
42
+ |---|---|
43
+ | `Fact` | id, content, user_id, agent_id, metadata, score, created_at, updated_at |
44
+ | `Message` | role, content, metadata, timestamp, name |
45
+ | `Document` | id, content, metadata, score, created_at, updated_at |
46
+ | `Triple` | subject, predicate, object, metadata |
47
+ | `GraphResult` | triples, nodes, scores |
48
+
49
+ Your agent code works exclusively with these models. If you swap providers,
50
+ you change one import and one constructor call -- the rest of your code stays
51
+ the same.
52
+
53
+ ## Architecture diagram
54
+
55
+ ```
56
+ Your AI Agent
57
+ |
58
+ v
59
+ Memio Client
60
+ |
61
+ |-- facts -> Mem0FactAdapter -> Mem0 Cloud API
62
+ |-- history -> ZepHistoryAdapter -> Zep Cloud API
63
+ |-- documents -> ChromaDocumentAdapter -> Local Chroma
64
+ |-- graph -> ZepGraphAdapter -> Zep Cloud API
65
+ ```
66
+
67
+ ## Composability
68
+
69
+ You can mix providers freely. The `Memio` client accepts any combination of
70
+ stores -- use whichever provider is strongest for each memory type:
71
+
72
+ ```python
73
+ from memio import Memio
74
+ from memio.providers.mem0 import Mem0FactAdapter
75
+ from memio.providers.zep import ZepHistoryAdapter
76
+ from memio.providers.chroma import ChromaDocumentAdapter
77
+
78
+ import chromadb
79
+
80
+ client = Memio(
81
+ facts=Mem0FactAdapter(api_key="mem0-key"),
82
+ history=ZepHistoryAdapter(api_key="zep-key"),
83
+ documents=ChromaDocumentAdapter(
84
+ client=chromadb.PersistentClient(path="./chroma_data"),
85
+ collection_name="docs",
86
+ ),
87
+ )
88
+ ```
89
+
90
+ At least one store must be provided. Stores you do not need can be omitted --
91
+ accessing an omitted store attribute returns `None`.
92
+
93
+ ### Provider support matrix
94
+
95
+ | Store | Mem0 | Zep | Chroma |
96
+ |---|---|---|---|
97
+ | FactStore | Mem0FactAdapter | ZepFactAdapter | -- |
98
+ | HistoryStore | -- | ZepHistoryAdapter | -- |
99
+ | DocumentStore | -- | -- | ChromaDocumentAdapter |
100
+ | GraphStore | Mem0GraphAdapter | ZepGraphAdapter | -- |
101
+
102
+ ## Error handling
103
+
104
+ Every adapter wraps provider SDK exceptions in a single error type:
105
+
106
+ ```python
107
+ from memio.exceptions import ProviderError
108
+
109
+ try:
110
+ fact = await client.facts.add(content="likes coffee", user_id="alice")
111
+ except ProviderError as e:
112
+ print(e.provider) # "mem0"
113
+ print(e.operation) # "add"
114
+ print(e.cause) # the original SDK exception
115
+ ```
116
+
117
+ `ProviderError` always carries three attributes:
118
+
119
+ - **`provider`** -- the name of the provider (`"mem0"`, `"zep"`, `"chroma"`).
120
+ - **`operation`** -- the protocol method that failed (`"add"`, `"search"`, etc.).
121
+ - **`cause`** -- the original exception from the provider SDK.
122
+
123
+ This means your error-handling code never needs to import provider-specific
124
+ exception types.
125
+
126
+ ## Async-first
127
+
128
+ All store operations are `async`/`await`. Every method on every protocol is
129
+ declared `async def`, and every adapter implements them as coroutines:
130
+
131
+ ```python
132
+ # Every call goes through await
133
+ fact = await client.facts.add(content="likes coffee", user_id="alice")
134
+ results = await client.facts.search(query="coffee", user_id="alice")
135
+ await client.facts.delete(fact_id=fact.id)
136
+ ```
137
+
138
+ This makes memio a natural fit for async frameworks, LLM tool-calling loops,
139
+ and any agent runtime that uses `asyncio`.
140
+
141
+ ## Multi-tenancy
142
+
143
+ `FactStore` and `GraphStore` support **`user_id`** and **`agent_id`**
144
+ parameters for scoped data access. This lets a single memio deployment serve
145
+ multiple users or agents without data leaking across boundaries:
146
+
147
+ ```python
148
+ # Facts scoped to a specific user
149
+ await client.facts.add(
150
+ content="prefers dark mode",
151
+ user_id="alice",
152
+ )
153
+
154
+ # Search only returns facts for this user
155
+ results = await client.facts.search(
156
+ query="UI preferences",
157
+ user_id="alice",
158
+ )
159
+
160
+ # Graph triples scoped to a user
161
+ await client.graph.add(
162
+ triples=[Triple(subject="Alice", predicate="works_at", object="Acme")],
163
+ user_id="alice",
164
+ )
165
+ ```
166
+
167
+ `HistoryStore` scopes data by **`session_id`**, with `get_all` accepting a
168
+ `user_id` to list all sessions for a given user.