refactor(vector_store): make obvec and zvec vector stores optional dependencies (#273)

* refactor(vector_store): make obvec and zvec vector stores optional dependencies

- Removed direct imports of ObVecVectorStore and ZvecVectorStore from init file
- Added try-except blocks for conditional importing of optional vector stores
- Updated error handling to check for both pyobvector and sqlalchemy in ObVecVectorStore
- Renamed _OBVECTOR_IMPORT_ERROR to _OBVEC_IMPORT_ERROR for consistency
- Moved pyobvector and related dependencies to optional 'obvec' extra
- Added separate 'zvec' optional dependency group
- Updated package configuration to exclude reme4 module patterns
- Removed reme4 entry point from console scripts
- Bumped version from 0.3.1.9 to 0.3.1.10

* refactor(dependencies): reorganize project dependencies and add optional seekdb support

- Move sqlite-vec, prompt_toolkit, and rich to earlier in dependencies list
- Remove pyseekdb from main dependencies and create separate seekdb optional dependency group
- Reorder pyyaml to later in the dependencies list
- Maintain all existing dependency versions while improving organization

* chore(deps): remove faiss-cpu dependency from pyproject.toml

- Removed faiss-cpu>=1.7.4 from the faiss dependency group
- Cleaned up unused faiss dependency configuration
- Updated project dependencies to exclude faiss-cpu package
This commit is contained in:
jinliyl 2026-06-03 17:28:30 +08:00 • committed by GitHub
parent d8086039dc
commit 36a5512fc8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 41 deletions

View file

@ -33,33 +33,23 @@ classifiers = [
keywords = ["llm", "memory", "experience", "memoryscope", "ai", "mcp", "http", "reme", "personal"]
dependencies = [
"aiofiles>=24.1.0",
"sqlite-vec>=0.1.6",
"prompt_toolkit>=3.0.52",
"rich>=14.2.0",
"asyncpg>=0.31.0",
"chromadb>=1.3.5",
# pyseekdb 1.2+ requires Python >=3.11 (no wheels on 3.10)
"pyseekdb>=1.2.0; python_version >= '3.11'",
"dashscope>=1.25.1",
"elasticsearch>=9.2.0",
"fastapi>=0.121.3",
"fastmcp>=2.14.1",
"httpx>=0.28.1",
"jieba>=0.42.1",
"rjieba>=0.1.11",
"loguru>=0.7.3",
"mcp>=1.25.0",
"networkx>=3.4",
"numpy>=2.2.6",
"openai>=2.8.1",
"pandas>=2.3.3",
"prompt_toolkit>=3.0.52",
"pydantic>=2.12.4",
"pyobvector>=0.1.20",
"pyyaml>=6.0.3",
"qdrant-client>=1.16.0",
"rich>=14.2.0",
"sqlite-vec>=0.1.6",
# pyobvector imports Expression from sqlglot; removed from sqlglot 30+ top-level API
"sqlglot>=25,<30",
"tavily-python>=0.7.13",
"tiktoken>=0.12.0",
"tqdm>=4.67.1",
@ -67,17 +57,27 @@ dependencies = [
"uvicorn>=0.40.0",
"watchfiles>=1.1.1",
"pyyaml>=6.0.3",
"mistletoe",
"neo4j",
]
[project.optional-dependencies]
ray = [
"ray",
obvec = [
"pyobvector>=0.1.20",
"sqlalchemy>=2.0",
# pyobvector imports Expression from sqlglot; removed from sqlglot 30+ top-level API
"sqlglot>=25,<30",
]
faiss = [
"faiss-cpu>=1.7.4",
seekdb = [
# pyseekdb 1.2+ requires Python >=3.11 (no wheels on 3.10)
"pyseekdb>=1.2.0; python_version >= '3.11'",
]
zvec = [
"zvec",
]
ray = [
"ray",
]
dev = [
@ -111,7 +111,7 @@ core = [
[tool.setuptools.packages.find]
where = ["."]
include = ["reme_ai*", "reme*", "reme4*"]
include = ["reme_ai*", "reme*"]
exclude = ["test*", "cookbook*", "doc*", "library*", "dist*"]
[tool.setuptools.package-data]
@ -127,12 +127,6 @@ reme = [
"**/*.json",
]
reme4 = [
"**/*.yaml",
"**/*.py",
"**/*.json",
]
[tool.setuptools.dynamic]
version = { attr = "reme.__version__" }
@ -145,7 +139,6 @@ Repository = "https://github.com/agentscope-ai/ReMe"
reme = "reme_ai.main:main"
reme2 = "reme.reme:main"
remecli = "reme.reme_cli:main"
reme4 = "reme4.reme:main"
[tool.pytest.ini_options]
asyncio_default_fixture_loop_scope = "function"

View file

@ -6,7 +6,7 @@ from . import extension
from . import memory
from .reme import ReMe
__version__ = "0.3.1.9"
__version__ = "0.3.1.10"
__all__ = [
"config",

View file

@ -5,10 +5,8 @@ from .chroma_vector_store import ChromaVectorStore
from .es_vector_store import ESVectorStore
from .hologres_store import HologresVectorStore
from .local_vector_store import LocalVectorStore
from .obvec_vector_store import ObVecVectorStore
from .pgvector_store import PGVectorStore
from .qdrant_vector_store import QdrantVectorStore
from .zvec_vector_store import ZvecVectorStore
from ..registry_factory import R
__all__ = [
@ -17,20 +15,32 @@ __all__ = [
"ESVectorStore",
"HologresVectorStore",
"LocalVectorStore",
"ObVecVectorStore",
"PGVectorStore",
"QdrantVectorStore",
"ZvecVectorStore",
]
R.vector_stores.register("chroma")(ChromaVectorStore)
R.vector_stores.register("es")(ESVectorStore)
R.vector_stores.register("hologres")(HologresVectorStore)
R.vector_stores.register("local")(LocalVectorStore)
R.vector_stores.register("obvec")(ObVecVectorStore)
R.vector_stores.register("pgvector")(PGVectorStore)
R.vector_stores.register("qdrant")(QdrantVectorStore)
R.vector_stores.register("zvec")(ZvecVectorStore)
try:
from .obvec_vector_store import ObVecVectorStore
R.vector_stores.register("obvec")(ObVecVectorStore)
__all__.append("ObVecVectorStore")
except ImportError:
pass
try:
from .zvec_vector_store import ZvecVectorStore
R.vector_stores.register("zvec")(ZvecVectorStore)
__all__.append("ZvecVectorStore")
except ImportError:
pass
try:
from .seekdb_vector_store import SeekdbVectorStore

View file

@ -7,24 +7,31 @@ from pathlib import Path
from typing import Any
from loguru import logger
from sqlalchemy import Column, JSON, String, text as sa_text
from sqlalchemy.dialects.mysql import LONGTEXT
from .base_vector_store import BaseVectorStore
from ..embedding import BaseEmbeddingModel
from ..schema import VectorNode
_OBVECTOR_IMPORT_ERROR: Exception | None = None
_OBVEC_IMPORT_ERROR: Exception | None = None
try:
from sqlalchemy import Column, JSON, String, text as sa_text
from sqlalchemy.dialects.mysql import LONGTEXT
from pyobvector import IndexParams, ObVecClient, VecIndexType, VECTOR
from pyobvector import cosine_distance, inner_product
except Exception as e:
_OBVECTOR_IMPORT_ERROR = e
_OBVEC_IMPORT_ERROR = e
Column = None # type: ignore[misc, assignment]
JSON = None # type: ignore[misc, assignment]
String = None # type: ignore[misc, assignment]
sa_text = None # type: ignore[misc, assignment]
LONGTEXT = None # type: ignore[misc, assignment]
IndexParams = None # type: ignore[misc, assignment]
ObVecClient = None # type: ignore[misc, assignment]
VecIndexType = None # type: ignore[misc, assignment]
VECTOR = None # type: ignore[misc, assignment]
cosine_distance = None # type: ignore[misc, assignment]
inner_product = None # type: ignore[misc, assignment]
_COL_SELECT = "id, content, vector, metadata"
@ -139,10 +146,11 @@ class ObVecVectorStore(BaseVectorStore):
index_ef_search: int = 100,
**kwargs,
):
if _OBVECTOR_IMPORT_ERROR is not None:
if _OBVEC_IMPORT_ERROR is not None:
raise ImportError(
"ObVecVectorStore requires pyobvector. Install with `pip install pyobvector`",
) from _OBVECTOR_IMPORT_ERROR
"ObVecVectorStore requires pyobvector and sqlalchemy. "
"Install with `pip install pyobvector sqlalchemy`",
) from _OBVEC_IMPORT_ERROR
super().__init__(
collection_name=collection_name,