vecmindb 1.0.0b0__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.
- vecmindb-1.0.0b0/PKG-INFO +143 -0
- vecmindb-1.0.0b0/README.md +112 -0
- vecmindb-1.0.0b0/pyproject.toml +46 -0
- vecmindb-1.0.0b0/setup.cfg +4 -0
- vecmindb-1.0.0b0/tests/test_agent_memory.py +224 -0
- vecmindb-1.0.0b0/tests/test_client.py +250 -0
- vecmindb-1.0.0b0/tests/test_integrations.py +21 -0
- vecmindb-1.0.0b0/vecmindb/__init__.py +163 -0
- vecmindb-1.0.0b0/vecmindb/async_client.py +1074 -0
- vecmindb-1.0.0b0/vecmindb/auth.py +188 -0
- vecmindb-1.0.0b0/vecmindb/client.py +748 -0
- vecmindb-1.0.0b0/vecmindb/exceptions.py +135 -0
- vecmindb-1.0.0b0/vecmindb/integrations/__init__.py +1 -0
- vecmindb-1.0.0b0/vecmindb/integrations/langchain.py +172 -0
- vecmindb-1.0.0b0/vecmindb/integrations/llamaindex.py +156 -0
- vecmindb-1.0.0b0/vecmindb/mcp.py +515 -0
- vecmindb-1.0.0b0/vecmindb/mcp_server.py +138 -0
- vecmindb-1.0.0b0/vecmindb/memory.py +329 -0
- vecmindb-1.0.0b0/vecmindb/memory_plugin.py +254 -0
- vecmindb-1.0.0b0/vecmindb/models.py +469 -0
- vecmindb-1.0.0b0/vecmindb/py.typed +1 -0
- vecmindb-1.0.0b0/vecmindb/retry.py +179 -0
- vecmindb-1.0.0b0/vecmindb.egg-info/PKG-INFO +143 -0
- vecmindb-1.0.0b0/vecmindb.egg-info/SOURCES.txt +25 -0
- vecmindb-1.0.0b0/vecmindb.egg-info/dependency_links.txt +1 -0
- vecmindb-1.0.0b0/vecmindb.egg-info/requires.txt +5 -0
- vecmindb-1.0.0b0/vecmindb.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vecmindb
|
|
3
|
+
Version: 1.0.0b0
|
|
4
|
+
Summary: Python SDK for VecminDB - High-performance vector database HTTP client
|
|
5
|
+
Author-email: VecminDB Team <sulingqi@hotmail.com>
|
|
6
|
+
License: MIT OR Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://lingxinmind.com
|
|
8
|
+
Project-URL: Repository, https://github.com/lingxinmind/vecminDB
|
|
9
|
+
Project-URL: Documentation, https://lingxinmind.com/docs/index.html
|
|
10
|
+
Project-URL: Changelog, https://github.com/lingxinmind/vecminDB/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: vector-database,similarity-search,embedding,sdk,rag
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Database
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
25
|
+
Requires-Python: >=3.8
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
Requires-Dist: requests>=2.28.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
31
|
+
|
|
32
|
+
# VecminDB SDK
|
|
33
|
+
|
|
34
|
+
The official SDK for [VecminDB](https://lingxinmind.com) — The Sovereign Memory OS for AI Agents.
|
|
35
|
+
|
|
36
|
+
> Stop letting your AI Agents hallucinate from memory rot. VecminDB naturally decays outdated memories, distills knowledge via PCA, and provides 100% Air-Gapped cryptographic data sovereignty.
|
|
37
|
+
|
|
38
|
+
⚠️ **License Note**: VecminDB is a commercial Cognitive Vector Database. The Free Tier supports up to 5 agents and 100K vectors/agent forever. For enterprise scale-out or clusters, please visit our official website to register and obtain a license key: [https://lingxinmind.com](https://lingxinmind.com).
|
|
39
|
+
|
|
40
|
+
## Deployment & Installation
|
|
41
|
+
|
|
42
|
+
VecminDB can be run via Docker or as optimized, standalone pre-compiled native binary packages. No local compilers, dependencies, or Python runtimes are needed.
|
|
43
|
+
|
|
44
|
+
### Method A: Docker Deployment (All Platforms - Windows, macOS, Linux)
|
|
45
|
+
The fastest way to spin up VecminDB with automatic in-database bilingual embedding support.
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# For Global / Overseas users:
|
|
49
|
+
docker run -d --name vecmindb-trial -p 5520:5520 ghcr.io/lingxinmind/vecmindb:latest
|
|
50
|
+
|
|
51
|
+
# For Domestic users (China Aliyun Mirror):
|
|
52
|
+
# docker run -d --name vecmindb-trial -p 5520:5520 crpi-ngtfnt7d3tsnwk7l.cn-shanghai.personal.cr.aliyuncs.com/vecmindb/vecmindb:latest
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### Method B: Pre-Compiled Native Binary Bundles (Zero-Docker / Zero-Python)
|
|
58
|
+
Ideal for high-performance, air-gapped on-premise or private cloud servers. Download the appropriate package from our official website [Downloads](https://lingxinmind.com) portal:
|
|
59
|
+
|
|
60
|
+
* **Windows (AMD64)**:
|
|
61
|
+
Download `vecmindb-1.0.0-beta-x86_64-pc-windows-msvc.zip`. Extract the ZIP archive, open Command Prompt or PowerShell in the directory, and run:
|
|
62
|
+
```cmd
|
|
63
|
+
.\vecmindb-server.exe
|
|
64
|
+
```
|
|
65
|
+
* **macOS (Apple Silicon M1/M2/M3)**:
|
|
66
|
+
Download `vecmindb-1.0.0-beta-aarch64-apple-darwin.tar.gz`. Open Terminal, extract and run:
|
|
67
|
+
```bash
|
|
68
|
+
tar -xzf vecmindb-1.0.0-beta-aarch64-apple-darwin.tar.gz
|
|
69
|
+
cd vecmindb-1.0.0-beta-aarch64-apple-darwin
|
|
70
|
+
./vecmindb-server
|
|
71
|
+
```
|
|
72
|
+
* **Linux (AMD64)**:
|
|
73
|
+
Download `vecmindb-offline-linux-amd64.tar.gz`. Extract and run:
|
|
74
|
+
```bash
|
|
75
|
+
tar -xzf vecmindb-offline-linux-amd64.tar.gz
|
|
76
|
+
cd vecmindb-offline-linux-amd64
|
|
77
|
+
./vecmindb-server
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## SDK Quickstart
|
|
83
|
+
|
|
84
|
+
First, install the target client SDK:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Install core client
|
|
88
|
+
pip install vecmindb
|
|
89
|
+
|
|
90
|
+
# Install with LangChain integration
|
|
91
|
+
pip install vecmindb[langchain]
|
|
92
|
+
|
|
93
|
+
# Install with CrewAI integration
|
|
94
|
+
pip install vecmindb[crewai]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Using with LangChain
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from vecmindb.memory_plugin import VecminDBMemoryPlugin
|
|
101
|
+
from langchain_openai import ChatOpenAI
|
|
102
|
+
from langchain.chains import ConversationChain
|
|
103
|
+
|
|
104
|
+
# Initialize Sovereign Agent Memory
|
|
105
|
+
memory = VecminDBMemoryPlugin.for_langchain(agent_id="support_agent_01", base_url="http://localhost:5520")
|
|
106
|
+
|
|
107
|
+
llm = ChatOpenAI(temperature=0)
|
|
108
|
+
conversation = ConversationChain(llm=llm, memory=memory)
|
|
109
|
+
|
|
110
|
+
conversation.predict(input="Hi, I need help with my billing.")
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Using with CrewAI
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from vecmindb.memory_plugin import VecminDBMemoryPlugin
|
|
117
|
+
from crewai import Agent, Crew
|
|
118
|
+
|
|
119
|
+
# Initialize Sovereign Agent Memory
|
|
120
|
+
memory_storage = VecminDBMemoryPlugin.for_crewai(agent_id="finance_agent_01", base_url="http://localhost:5520")
|
|
121
|
+
|
|
122
|
+
agent = Agent(
|
|
123
|
+
role='Financial Analyst',
|
|
124
|
+
goal='Analyze billing data',
|
|
125
|
+
backstory='An expert in financial data.',
|
|
126
|
+
memory=True,
|
|
127
|
+
memory_config={"storage": memory_storage} # Inject VecminDB memory
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Why VecminDB?
|
|
132
|
+
|
|
133
|
+
Unlike generic vector databases that act as static drives, VecminDB acts as a cognitive memory operating system with native lifecycle management and cryptographic isolation:
|
|
134
|
+
|
|
135
|
+
* **Biological Forgetting (LTSM)**: Episodic memories decay dynamically following $W(t) = \exp(-\lambda \times \Delta t)$ with automatic 90-day semantic pruning (`let semantic_prune_threshold_secs = 90 * 86400;` on disk). Frequently accessed memories persist; transient noise is permanently retired.
|
|
136
|
+
* **Welford & PCA Memory Distillation**: Fuses decaying memory clusters into stable Abstract Centroids using real-time Welford online variance and DP-Federated PCA. Storage converges and scales logarithmically, locking in long-term TCO budgets.
|
|
137
|
+
* **3-Sigma Sentinel Guard**: Performs real-time anomaly detection and adversarial injection pruning. Evaluates cosine outlier distance with dynamic cutoffs: $\text{Threshold} = \max(\text{Mean}_s - 3 \times \text{Std}_s, 0.7)$.
|
|
138
|
+
* **Sovereign Federation**: Shares collective intelligence across multiple agent domains or VPCs without raw data leak. Fuses PCA Candidate Centroids with differential privacy and a 10% principal bias: $\vec{v}_{\text{centroid}} = \text{Mean}_{\text{global}} + P_0 \times 0.1$.
|
|
139
|
+
* **Raft Consensus & 1024-Bucket Anti-Entropy**: Combines strong consensus replication with self-healing topology. Employs monotonic lock validation (`pub fencing_token: u64`) and an adaptive sync cap: `(resolution * 2).min(1024)`.
|
|
140
|
+
* **100% Air-Gapped Single-Binary**: Built-in BGE-M3 ONNX runtime. No Python, PyTorch, or external embedding API keys needed. Bounded tightly to machine-level HAI hardware fingerprints.
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
**Enterprise Licensing**: For multi-node SOC-2 compliant deployments, please purchase subscriptions or contact us at `sulingqi@hotmail.com`.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# VecminDB SDK
|
|
2
|
+
|
|
3
|
+
The official SDK for [VecminDB](https://lingxinmind.com) — The Sovereign Memory OS for AI Agents.
|
|
4
|
+
|
|
5
|
+
> Stop letting your AI Agents hallucinate from memory rot. VecminDB naturally decays outdated memories, distills knowledge via PCA, and provides 100% Air-Gapped cryptographic data sovereignty.
|
|
6
|
+
|
|
7
|
+
⚠️ **License Note**: VecminDB is a commercial Cognitive Vector Database. The Free Tier supports up to 5 agents and 100K vectors/agent forever. For enterprise scale-out or clusters, please visit our official website to register and obtain a license key: [https://lingxinmind.com](https://lingxinmind.com).
|
|
8
|
+
|
|
9
|
+
## Deployment & Installation
|
|
10
|
+
|
|
11
|
+
VecminDB can be run via Docker or as optimized, standalone pre-compiled native binary packages. No local compilers, dependencies, or Python runtimes are needed.
|
|
12
|
+
|
|
13
|
+
### Method A: Docker Deployment (All Platforms - Windows, macOS, Linux)
|
|
14
|
+
The fastest way to spin up VecminDB with automatic in-database bilingual embedding support.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# For Global / Overseas users:
|
|
18
|
+
docker run -d --name vecmindb-trial -p 5520:5520 ghcr.io/lingxinmind/vecmindb:latest
|
|
19
|
+
|
|
20
|
+
# For Domestic users (China Aliyun Mirror):
|
|
21
|
+
# docker run -d --name vecmindb-trial -p 5520:5520 crpi-ngtfnt7d3tsnwk7l.cn-shanghai.personal.cr.aliyuncs.com/vecmindb/vecmindb:latest
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
### Method B: Pre-Compiled Native Binary Bundles (Zero-Docker / Zero-Python)
|
|
27
|
+
Ideal for high-performance, air-gapped on-premise or private cloud servers. Download the appropriate package from our official website [Downloads](https://lingxinmind.com) portal:
|
|
28
|
+
|
|
29
|
+
* **Windows (AMD64)**:
|
|
30
|
+
Download `vecmindb-1.0.0-beta-x86_64-pc-windows-msvc.zip`. Extract the ZIP archive, open Command Prompt or PowerShell in the directory, and run:
|
|
31
|
+
```cmd
|
|
32
|
+
.\vecmindb-server.exe
|
|
33
|
+
```
|
|
34
|
+
* **macOS (Apple Silicon M1/M2/M3)**:
|
|
35
|
+
Download `vecmindb-1.0.0-beta-aarch64-apple-darwin.tar.gz`. Open Terminal, extract and run:
|
|
36
|
+
```bash
|
|
37
|
+
tar -xzf vecmindb-1.0.0-beta-aarch64-apple-darwin.tar.gz
|
|
38
|
+
cd vecmindb-1.0.0-beta-aarch64-apple-darwin
|
|
39
|
+
./vecmindb-server
|
|
40
|
+
```
|
|
41
|
+
* **Linux (AMD64)**:
|
|
42
|
+
Download `vecmindb-offline-linux-amd64.tar.gz`. Extract and run:
|
|
43
|
+
```bash
|
|
44
|
+
tar -xzf vecmindb-offline-linux-amd64.tar.gz
|
|
45
|
+
cd vecmindb-offline-linux-amd64
|
|
46
|
+
./vecmindb-server
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## SDK Quickstart
|
|
52
|
+
|
|
53
|
+
First, install the target client SDK:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Install core client
|
|
57
|
+
pip install vecmindb
|
|
58
|
+
|
|
59
|
+
# Install with LangChain integration
|
|
60
|
+
pip install vecmindb[langchain]
|
|
61
|
+
|
|
62
|
+
# Install with CrewAI integration
|
|
63
|
+
pip install vecmindb[crewai]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Using with LangChain
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from vecmindb.memory_plugin import VecminDBMemoryPlugin
|
|
70
|
+
from langchain_openai import ChatOpenAI
|
|
71
|
+
from langchain.chains import ConversationChain
|
|
72
|
+
|
|
73
|
+
# Initialize Sovereign Agent Memory
|
|
74
|
+
memory = VecminDBMemoryPlugin.for_langchain(agent_id="support_agent_01", base_url="http://localhost:5520")
|
|
75
|
+
|
|
76
|
+
llm = ChatOpenAI(temperature=0)
|
|
77
|
+
conversation = ConversationChain(llm=llm, memory=memory)
|
|
78
|
+
|
|
79
|
+
conversation.predict(input="Hi, I need help with my billing.")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Using with CrewAI
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from vecmindb.memory_plugin import VecminDBMemoryPlugin
|
|
86
|
+
from crewai import Agent, Crew
|
|
87
|
+
|
|
88
|
+
# Initialize Sovereign Agent Memory
|
|
89
|
+
memory_storage = VecminDBMemoryPlugin.for_crewai(agent_id="finance_agent_01", base_url="http://localhost:5520")
|
|
90
|
+
|
|
91
|
+
agent = Agent(
|
|
92
|
+
role='Financial Analyst',
|
|
93
|
+
goal='Analyze billing data',
|
|
94
|
+
backstory='An expert in financial data.',
|
|
95
|
+
memory=True,
|
|
96
|
+
memory_config={"storage": memory_storage} # Inject VecminDB memory
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Why VecminDB?
|
|
101
|
+
|
|
102
|
+
Unlike generic vector databases that act as static drives, VecminDB acts as a cognitive memory operating system with native lifecycle management and cryptographic isolation:
|
|
103
|
+
|
|
104
|
+
* **Biological Forgetting (LTSM)**: Episodic memories decay dynamically following $W(t) = \exp(-\lambda \times \Delta t)$ with automatic 90-day semantic pruning (`let semantic_prune_threshold_secs = 90 * 86400;` on disk). Frequently accessed memories persist; transient noise is permanently retired.
|
|
105
|
+
* **Welford & PCA Memory Distillation**: Fuses decaying memory clusters into stable Abstract Centroids using real-time Welford online variance and DP-Federated PCA. Storage converges and scales logarithmically, locking in long-term TCO budgets.
|
|
106
|
+
* **3-Sigma Sentinel Guard**: Performs real-time anomaly detection and adversarial injection pruning. Evaluates cosine outlier distance with dynamic cutoffs: $\text{Threshold} = \max(\text{Mean}_s - 3 \times \text{Std}_s, 0.7)$.
|
|
107
|
+
* **Sovereign Federation**: Shares collective intelligence across multiple agent domains or VPCs without raw data leak. Fuses PCA Candidate Centroids with differential privacy and a 10% principal bias: $\vec{v}_{\text{centroid}} = \text{Mean}_{\text{global}} + P_0 \times 0.1$.
|
|
108
|
+
* **Raft Consensus & 1024-Bucket Anti-Entropy**: Combines strong consensus replication with self-healing topology. Employs monotonic lock validation (`pub fencing_token: u64`) and an adaptive sync cap: `(resolution * 2).min(1024)`.
|
|
109
|
+
* **100% Air-Gapped Single-Binary**: Built-in BGE-M3 ONNX runtime. No Python, PyTorch, or external embedding API keys needed. Bounded tightly to machine-level HAI hardware fingerprints.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
**Enterprise Licensing**: For multi-node SOC-2 compliant deployments, please purchase subscriptions or contact us at `sulingqi@hotmail.com`.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "vecmindb"
|
|
7
|
+
version = "1.0.0-beta"
|
|
8
|
+
description = "Python SDK for VecminDB - High-performance vector database HTTP client"
|
|
9
|
+
authors = [{email = "sulingqi@hotmail.com", name = "VecminDB Team"}]
|
|
10
|
+
license = {text = "MIT OR Apache-2.0"}
|
|
11
|
+
readme = "README.md"
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
|
+
keywords = ["vector-database", "similarity-search", "embedding", "sdk", "rag"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 5 - Production/Stable",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"License :: OSI Approved :: Apache Software License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
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 :: Database",
|
|
27
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"requests>=2.28.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=7.0",
|
|
36
|
+
"pytest-cov>=4.0",
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://lingxinmind.com"
|
|
41
|
+
Repository = "https://github.com/lingxinmind/vecminDB"
|
|
42
|
+
Documentation = "https://lingxinmind.com/docs/index.html"
|
|
43
|
+
Changelog = "https://github.com/lingxinmind/vecminDB/blob/main/CHANGELOG.md"
|
|
44
|
+
|
|
45
|
+
[tool.setuptools.packages.find]
|
|
46
|
+
include = ["vecmindb*"]
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""Unit tests for the VecminDB Agent OS Memory abstraction."""
|
|
2
|
+
|
|
3
|
+
import unittest
|
|
4
|
+
from unittest.mock import MagicMock, AsyncMock, patch
|
|
5
|
+
from vecmindb import (
|
|
6
|
+
VecminClient,
|
|
7
|
+
AsyncVecminClient,
|
|
8
|
+
connect,
|
|
9
|
+
AgentMemoryManager,
|
|
10
|
+
AsyncAgentMemoryManager,
|
|
11
|
+
VecminMemorySpace,
|
|
12
|
+
AsyncVecminMemorySpace,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestAgentMemory(unittest.IsolatedAsyncioTestCase):
|
|
17
|
+
"""Verify sovereignty agent isolation and cognitive memory space lifecycle."""
|
|
18
|
+
|
|
19
|
+
def test_client_init(self) -> None:
|
|
20
|
+
"""Verify constructor handles agent_id and sovereignty_token correctly."""
|
|
21
|
+
client = VecminClient(
|
|
22
|
+
"http://localhost:5520",
|
|
23
|
+
agent_id="my_agent",
|
|
24
|
+
sovereignty_token="my_token",
|
|
25
|
+
)
|
|
26
|
+
self.assertEqual(client.agent_id, "my_agent")
|
|
27
|
+
self.assertEqual(client.sovereignty_token, "my_token")
|
|
28
|
+
|
|
29
|
+
# default values
|
|
30
|
+
client_default = VecminClient("http://localhost:5520")
|
|
31
|
+
self.assertEqual(client_default.agent_id, "default_agent")
|
|
32
|
+
self.assertEqual(client_default.sovereignty_token, "system")
|
|
33
|
+
|
|
34
|
+
def test_connect_shortcut(self) -> None:
|
|
35
|
+
"""Verify package-level connect() sets agent parameters correctly."""
|
|
36
|
+
client = connect(
|
|
37
|
+
"http://localhost:5520",
|
|
38
|
+
agent_id="agent_123",
|
|
39
|
+
sovereignty_token="sovereign_abc",
|
|
40
|
+
)
|
|
41
|
+
self.assertIsInstance(client, VecminClient)
|
|
42
|
+
self.assertEqual(client.agent_id, "agent_123")
|
|
43
|
+
self.assertEqual(client.sovereignty_token, "sovereign_abc")
|
|
44
|
+
|
|
45
|
+
@patch("vecmindb.client.VecminClient._api_post")
|
|
46
|
+
def test_mcp_store_search_sync(self, mock_post: MagicMock) -> None:
|
|
47
|
+
"""Verify MCP parameters propagate sovereignty values correctly."""
|
|
48
|
+
mock_post.return_value = {"data": {"content": "Stored successfully"}}
|
|
49
|
+
client = VecminClient(
|
|
50
|
+
"http://localhost:5520",
|
|
51
|
+
agent_id="a1",
|
|
52
|
+
sovereignty_token="t1",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
res = client.mcp_store_memory("my memory content")
|
|
56
|
+
self.assertEqual(res, "Stored successfully")
|
|
57
|
+
|
|
58
|
+
# Verify extra headers and arguments propagation
|
|
59
|
+
mock_post.assert_called_once()
|
|
60
|
+
args = mock_post.call_args[0]
|
|
61
|
+
kwargs = mock_post.call_args[1]
|
|
62
|
+
self.assertEqual(args[0], "/mcp/message")
|
|
63
|
+
self.assertEqual(args[1]["params"]["arguments"]["agent_id"], "a1")
|
|
64
|
+
self.assertEqual(args[1]["params"]["arguments"]["sovereignty_token"], "t1")
|
|
65
|
+
self.assertEqual(args[1]["params"]["arguments"]["model_id"], "t1")
|
|
66
|
+
self.assertEqual(kwargs.get("agent_id"), "a1")
|
|
67
|
+
self.assertEqual(kwargs.get("model_id"), "t1")
|
|
68
|
+
|
|
69
|
+
@patch("vecmindb.client.VecminClient._api_post")
|
|
70
|
+
@patch("vecmindb.client.VecminClient.ensure_collection")
|
|
71
|
+
@patch("vecmindb.client.VecminClient._api_get")
|
|
72
|
+
def test_memory_space_lifecycle_sync(
|
|
73
|
+
self,
|
|
74
|
+
mock_get: MagicMock,
|
|
75
|
+
mock_ensure: MagicMock,
|
|
76
|
+
mock_post: MagicMock,
|
|
77
|
+
) -> None:
|
|
78
|
+
"""Verify full memory space mounting, storage, search, evolve, and centroids lifecycle."""
|
|
79
|
+
client = VecminClient(
|
|
80
|
+
"http://localhost:5520",
|
|
81
|
+
agent_id="agent_alice",
|
|
82
|
+
sovereignty_token="sovereign_wonderland",
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Mount memory space
|
|
86
|
+
space = client.mount_memory(domain="my_domain")
|
|
87
|
+
self.assertIsInstance(space, VecminMemorySpace)
|
|
88
|
+
mock_ensure.assert_called_once_with(
|
|
89
|
+
"my_domain",
|
|
90
|
+
dimension=1536,
|
|
91
|
+
metric_type="Cosine",
|
|
92
|
+
index_type="HNSW",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
# Store memory
|
|
96
|
+
mock_post.return_value = {"data": {"content": "anchored"}}
|
|
97
|
+
store_res = space.store_memory("test memory")
|
|
98
|
+
self.assertEqual(store_res, "anchored")
|
|
99
|
+
|
|
100
|
+
# Search memory
|
|
101
|
+
mock_post.return_value = {
|
|
102
|
+
"data": {
|
|
103
|
+
"content": '[{"text": "test memory", "score": 0.9}]',
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
search_res = space.search_memory("test query")
|
|
107
|
+
self.assertEqual(len(search_res), 1)
|
|
108
|
+
self.assertEqual(search_res[0]["text"], "test memory")
|
|
109
|
+
|
|
110
|
+
# Evolve memory
|
|
111
|
+
mock_get.return_value = {"data": {"candidates": [{"id": "cand_1"}]}}
|
|
112
|
+
# Mock decide & optimize
|
|
113
|
+
mock_post.side_effect = [
|
|
114
|
+
{"data": {"decision": "approved"}}, # decide
|
|
115
|
+
{"data": {"status": "optimized"}}, # optimize
|
|
116
|
+
]
|
|
117
|
+
evolve_res = space.evolve()
|
|
118
|
+
self.assertEqual(evolve_res["status"], "success")
|
|
119
|
+
self.assertEqual(evolve_res["candidates_evaluated"], 1)
|
|
120
|
+
self.assertEqual(evolve_res["decisions"][0]["decision"], "approved")
|
|
121
|
+
|
|
122
|
+
# Get centroids
|
|
123
|
+
mock_get.return_value = {
|
|
124
|
+
"data": {
|
|
125
|
+
"centroids": [
|
|
126
|
+
{
|
|
127
|
+
"id": "c_1",
|
|
128
|
+
"vector": [0.1],
|
|
129
|
+
"weight": 1.0,
|
|
130
|
+
"source_count": 5,
|
|
131
|
+
"created_at": "now",
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
}
|
|
136
|
+
centroids = space.get_centroids()
|
|
137
|
+
self.assertEqual(len(centroids), 1)
|
|
138
|
+
self.assertEqual(centroids[0]["id"], "c_1")
|
|
139
|
+
|
|
140
|
+
async def test_async_lifecycle(self) -> None:
|
|
141
|
+
"""Verify full asynchronous memory space lifecycle."""
|
|
142
|
+
client = AsyncVecminClient(
|
|
143
|
+
"http://localhost:5520",
|
|
144
|
+
agent_id="agent_bob",
|
|
145
|
+
sovereignty_token="sovereign_builder",
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Mocking async client internal calls
|
|
149
|
+
client.ensure_collection = AsyncMock() # type: ignore[method-assign]
|
|
150
|
+
client._api_post = AsyncMock(return_value={"data": {"content": "anchored"}}) # type: ignore[method-assign]
|
|
151
|
+
client._api_get = AsyncMock() # type: ignore[method-assign]
|
|
152
|
+
|
|
153
|
+
space = await client.mount_memory(domain="async_domain")
|
|
154
|
+
self.assertIsInstance(space, AsyncVecminMemorySpace)
|
|
155
|
+
client.ensure_collection.assert_called_once()
|
|
156
|
+
|
|
157
|
+
# Store memory
|
|
158
|
+
store_res = await space.store_memory("async test memory")
|
|
159
|
+
self.assertEqual(store_res, "anchored")
|
|
160
|
+
|
|
161
|
+
# Search memory
|
|
162
|
+
client._api_post.return_value = {
|
|
163
|
+
"data": {
|
|
164
|
+
"content": '[{"text": "async search result"}]',
|
|
165
|
+
},
|
|
166
|
+
}
|
|
167
|
+
search_res = await space.search_memory("async query")
|
|
168
|
+
self.assertEqual(search_res[0]["text"], "async search result")
|
|
169
|
+
|
|
170
|
+
# Evolve memory
|
|
171
|
+
client._api_get.return_value = {
|
|
172
|
+
"data": {"candidates": [{"id": "cand_async_1"}]},
|
|
173
|
+
}
|
|
174
|
+
client._api_post.side_effect = [
|
|
175
|
+
{"data": {"decision": "deferred"}},
|
|
176
|
+
{"data": {"status": "optimized"}},
|
|
177
|
+
]
|
|
178
|
+
evolve_res = await space.evolve()
|
|
179
|
+
self.assertEqual(evolve_res["status"], "success")
|
|
180
|
+
self.assertEqual(evolve_res["decisions"][0]["decision"], "deferred")
|
|
181
|
+
|
|
182
|
+
# Get centroids
|
|
183
|
+
client._api_get.return_value = {
|
|
184
|
+
"data": {"centroids": [{"id": "c_async_1"}]},
|
|
185
|
+
}
|
|
186
|
+
centroids = await space.get_centroids()
|
|
187
|
+
self.assertEqual(centroids[0]["id"], "c_async_1")
|
|
188
|
+
|
|
189
|
+
@patch("vecmindb.client.VecminClient._api_post")
|
|
190
|
+
def test_sovereignty_violation_sync(self, mock_post: MagicMock) -> None:
|
|
191
|
+
"""Verify sovereignty violation raises AuthenticationError or PermissionError."""
|
|
192
|
+
from vecmindb.exceptions import AuthenticationError, PermissionError
|
|
193
|
+
|
|
194
|
+
# Simulate sovereignty_token rejection with 401 Unauthorized
|
|
195
|
+
mock_post.side_effect = AuthenticationError("Sovereignty token validation failed", code=401)
|
|
196
|
+
client = VecminClient("http://localhost:5520", agent_id="hacker", sovereignty_token="invalid_token")
|
|
197
|
+
|
|
198
|
+
with self.assertRaises(AuthenticationError):
|
|
199
|
+
client.mcp_store_memory("unauthorized write")
|
|
200
|
+
|
|
201
|
+
# Simulate sovereignty_token access restriction with 403 Forbidden
|
|
202
|
+
mock_post.side_effect = PermissionError("Access to sovereign domain denied", code=403)
|
|
203
|
+
with self.assertRaises(PermissionError):
|
|
204
|
+
client.mcp_store_memory("forbidden write")
|
|
205
|
+
|
|
206
|
+
async def test_sovereignty_violation_async(self) -> None:
|
|
207
|
+
"""Verify sovereignty violation in async client raises AuthenticationError or PermissionError."""
|
|
208
|
+
from vecmindb.exceptions import AuthenticationError, PermissionError
|
|
209
|
+
|
|
210
|
+
client = AsyncVecminClient("http://localhost:5520", agent_id="hacker_async", sovereignty_token="invalid_token")
|
|
211
|
+
|
|
212
|
+
# Simulate 401 Unauthorized
|
|
213
|
+
client._api_post = AsyncMock(side_effect=AuthenticationError("Sovereignty token validation failed", code=401)) # type: ignore[method-assign]
|
|
214
|
+
with self.assertRaises(AuthenticationError):
|
|
215
|
+
await client.mcp_store_memory("unauthorized write")
|
|
216
|
+
|
|
217
|
+
# Simulate 403 Forbidden
|
|
218
|
+
client._api_post = AsyncMock(side_effect=PermissionError("Access to sovereign domain denied", code=403)) # type: ignore[method-assign]
|
|
219
|
+
with self.assertRaises(PermissionError):
|
|
220
|
+
await client.mcp_store_memory("forbidden write")
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
if __name__ == "__main__":
|
|
224
|
+
unittest.main()
|