langchain-cyborgdb 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.
@@ -0,0 +1,7 @@
1
+ Copyright 2025, Cyborg Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: langchain-cyborgdb
3
+ Version: 0.1.0
4
+ Summary: LangChain integration for CyborgDB: The Confidential Vector Database
5
+ Author: Cyborg Inc.
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://www.cyborg.co
8
+ Project-URL: Documentation, https://docs.cyborg.co/versions/latest/integrations/langchain/introduction
9
+ Project-URL: Repository, https://github.com/cyborginc/langchain-cyborgdb
10
+ Keywords: langchain,vectorstore,cyborgdb,encrypted,vector database
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Database
20
+ Classifier: Topic :: Security :: Cryptography
21
+ Classifier: Topic :: Software Development :: Libraries
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: cyborgdb-core[langchain]>=0.18.0
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest; extra == "test"
28
+ Dynamic: license-file
29
+
30
+ # langchain-cyborgdb
31
+
32
+ LangChain integration for [CyborgDB](https://www.cyborg.co), the Confidential Vector Database. Provides `CyborgVectorStore`, a [LangChain](https://www.langchain.com/) `VectorStore` backed by CyborgDB's encrypted vector indexes.
33
+
34
+ This package is a thin wrapper around the integration that ships in [`cyborgdb-core`](https://pypi.org/project/cyborgdb-core/) — it re-exports `CyborgVectorStore`, `CyborgEmbeddings`, and `StorageConfig` under the standalone package name that LangChain's integration directory expects.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install langchain-cyborgdb
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ The example below uses OpenAI embeddings (`pip install langchain-openai`), but any LangChain `Embeddings` implementation works. You'll need a CyborgDB API key from [cyborg.co](https://www.cyborg.co).
45
+
46
+ ```python
47
+ from langchain_cyborgdb import CyborgVectorStore, StorageConfig
48
+ from langchain_openai import OpenAIEmbeddings
49
+
50
+ store = CyborgVectorStore.from_texts(
51
+ texts=["hello world", "goodbye world"],
52
+ embedding=OpenAIEmbeddings(),
53
+ index_key=CyborgVectorStore.generate_key(),
54
+ api_key="your-api-key",
55
+ storage_config=StorageConfig.disk("/tmp/cyborgdb-langchain"),
56
+ metric="cosine"
57
+ )
58
+
59
+ docs = store.similarity_search("hello")
60
+ ```
61
+
62
+ ## Key Features
63
+
64
+ - Full VectorStore API compatibility (`add_texts`, `similarity_search`, etc.)
65
+ - Async operations support
66
+ - Configurable distance metrics (`cosine`, `euclidean`, `squared_euclidean`)
67
+ - Document ID tracking and management
68
+ - Max marginal relevance search
69
+ - Factory methods (`from_texts`, `from_documents`) for quick setup
70
+
71
+ ## Key Classes
72
+
73
+ ### `CyborgVectorStore`
74
+
75
+ Implements the LangChain-compatible vector store interface. Supports:
76
+
77
+ - `.add_texts()` / `.add_documents()`
78
+ - `.similarity_search()` / `.similarity_search_with_score()`
79
+ - `.max_marginal_relevance_search()`
80
+ - `.get()` / `.list_ids()` / `.delete()`
81
+ - `.as_retriever()` for use in LangChain chains
82
+ - Async variants (`.aadd_texts()`, `.asimilarity_search()`, etc.)
83
+
84
+ ### `StorageConfig`
85
+
86
+ Configuration object for defining where index data is stored, built with `StorageConfig.disk(path)` or `StorageConfig.s3(bucket, ...)`.
87
+
88
+ ## Documentation
89
+
90
+ Full documentation, including metadata filtering and hybrid (BM25) search, lives at [docs.cyborg.co](https://docs.cyborg.co/versions/latest/integrations/langchain/introduction).
91
+
92
+ Using the CyborgDB client/server deployment instead of the embedded engine? The same integration is available via `pip install cyborgdb[langchain]` — see the [Deployment Models Guide](https://docs.cyborg.co/versions/latest/intro/deployment-models).
93
+
94
+ ## License
95
+
96
+ This wrapper is MIT licensed. It depends on `cyborgdb-core`, which is distributed under its own [proprietary license](https://www.cyborg.co).
@@ -0,0 +1,67 @@
1
+ # langchain-cyborgdb
2
+
3
+ LangChain integration for [CyborgDB](https://www.cyborg.co), the Confidential Vector Database. Provides `CyborgVectorStore`, a [LangChain](https://www.langchain.com/) `VectorStore` backed by CyborgDB's encrypted vector indexes.
4
+
5
+ This package is a thin wrapper around the integration that ships in [`cyborgdb-core`](https://pypi.org/project/cyborgdb-core/) — it re-exports `CyborgVectorStore`, `CyborgEmbeddings`, and `StorageConfig` under the standalone package name that LangChain's integration directory expects.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install langchain-cyborgdb
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ The example below uses OpenAI embeddings (`pip install langchain-openai`), but any LangChain `Embeddings` implementation works. You'll need a CyborgDB API key from [cyborg.co](https://www.cyborg.co).
16
+
17
+ ```python
18
+ from langchain_cyborgdb import CyborgVectorStore, StorageConfig
19
+ from langchain_openai import OpenAIEmbeddings
20
+
21
+ store = CyborgVectorStore.from_texts(
22
+ texts=["hello world", "goodbye world"],
23
+ embedding=OpenAIEmbeddings(),
24
+ index_key=CyborgVectorStore.generate_key(),
25
+ api_key="your-api-key",
26
+ storage_config=StorageConfig.disk("/tmp/cyborgdb-langchain"),
27
+ metric="cosine"
28
+ )
29
+
30
+ docs = store.similarity_search("hello")
31
+ ```
32
+
33
+ ## Key Features
34
+
35
+ - Full VectorStore API compatibility (`add_texts`, `similarity_search`, etc.)
36
+ - Async operations support
37
+ - Configurable distance metrics (`cosine`, `euclidean`, `squared_euclidean`)
38
+ - Document ID tracking and management
39
+ - Max marginal relevance search
40
+ - Factory methods (`from_texts`, `from_documents`) for quick setup
41
+
42
+ ## Key Classes
43
+
44
+ ### `CyborgVectorStore`
45
+
46
+ Implements the LangChain-compatible vector store interface. Supports:
47
+
48
+ - `.add_texts()` / `.add_documents()`
49
+ - `.similarity_search()` / `.similarity_search_with_score()`
50
+ - `.max_marginal_relevance_search()`
51
+ - `.get()` / `.list_ids()` / `.delete()`
52
+ - `.as_retriever()` for use in LangChain chains
53
+ - Async variants (`.aadd_texts()`, `.asimilarity_search()`, etc.)
54
+
55
+ ### `StorageConfig`
56
+
57
+ Configuration object for defining where index data is stored, built with `StorageConfig.disk(path)` or `StorageConfig.s3(bucket, ...)`.
58
+
59
+ ## Documentation
60
+
61
+ Full documentation, including metadata filtering and hybrid (BM25) search, lives at [docs.cyborg.co](https://docs.cyborg.co/versions/latest/integrations/langchain/introduction).
62
+
63
+ Using the CyborgDB client/server deployment instead of the embedded engine? The same integration is available via `pip install cyborgdb[langchain]` — see the [Deployment Models Guide](https://docs.cyborg.co/versions/latest/intro/deployment-models).
64
+
65
+ ## License
66
+
67
+ This wrapper is MIT licensed. It depends on `cyborgdb-core`, which is distributed under its own [proprietary license](https://www.cyborg.co).
@@ -0,0 +1,16 @@
1
+ """LangChain integration for CyborgDB.
2
+
3
+ This package is a thin wrapper around ``cyborgdb_core.integrations.langchain``,
4
+ published under the standalone name LangChain's integration directory expects.
5
+ All functionality lives in ``cyborgdb-core[langchain]``.
6
+ """
7
+
8
+ from cyborgdb_core.integrations.langchain import (
9
+ CyborgEmbeddings,
10
+ CyborgVectorStore,
11
+ StorageConfig,
12
+ )
13
+
14
+ __version__ = "0.1.0"
15
+
16
+ __all__ = ["CyborgVectorStore", "CyborgEmbeddings", "StorageConfig"]
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: langchain-cyborgdb
3
+ Version: 0.1.0
4
+ Summary: LangChain integration for CyborgDB: The Confidential Vector Database
5
+ Author: Cyborg Inc.
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://www.cyborg.co
8
+ Project-URL: Documentation, https://docs.cyborg.co/versions/latest/integrations/langchain/introduction
9
+ Project-URL: Repository, https://github.com/cyborginc/langchain-cyborgdb
10
+ Keywords: langchain,vectorstore,cyborgdb,encrypted,vector database
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Information Technology
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Database
20
+ Classifier: Topic :: Security :: Cryptography
21
+ Classifier: Topic :: Software Development :: Libraries
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: cyborgdb-core[langchain]>=0.18.0
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest; extra == "test"
28
+ Dynamic: license-file
29
+
30
+ # langchain-cyborgdb
31
+
32
+ LangChain integration for [CyborgDB](https://www.cyborg.co), the Confidential Vector Database. Provides `CyborgVectorStore`, a [LangChain](https://www.langchain.com/) `VectorStore` backed by CyborgDB's encrypted vector indexes.
33
+
34
+ This package is a thin wrapper around the integration that ships in [`cyborgdb-core`](https://pypi.org/project/cyborgdb-core/) — it re-exports `CyborgVectorStore`, `CyborgEmbeddings`, and `StorageConfig` under the standalone package name that LangChain's integration directory expects.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install langchain-cyborgdb
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ The example below uses OpenAI embeddings (`pip install langchain-openai`), but any LangChain `Embeddings` implementation works. You'll need a CyborgDB API key from [cyborg.co](https://www.cyborg.co).
45
+
46
+ ```python
47
+ from langchain_cyborgdb import CyborgVectorStore, StorageConfig
48
+ from langchain_openai import OpenAIEmbeddings
49
+
50
+ store = CyborgVectorStore.from_texts(
51
+ texts=["hello world", "goodbye world"],
52
+ embedding=OpenAIEmbeddings(),
53
+ index_key=CyborgVectorStore.generate_key(),
54
+ api_key="your-api-key",
55
+ storage_config=StorageConfig.disk("/tmp/cyborgdb-langchain"),
56
+ metric="cosine"
57
+ )
58
+
59
+ docs = store.similarity_search("hello")
60
+ ```
61
+
62
+ ## Key Features
63
+
64
+ - Full VectorStore API compatibility (`add_texts`, `similarity_search`, etc.)
65
+ - Async operations support
66
+ - Configurable distance metrics (`cosine`, `euclidean`, `squared_euclidean`)
67
+ - Document ID tracking and management
68
+ - Max marginal relevance search
69
+ - Factory methods (`from_texts`, `from_documents`) for quick setup
70
+
71
+ ## Key Classes
72
+
73
+ ### `CyborgVectorStore`
74
+
75
+ Implements the LangChain-compatible vector store interface. Supports:
76
+
77
+ - `.add_texts()` / `.add_documents()`
78
+ - `.similarity_search()` / `.similarity_search_with_score()`
79
+ - `.max_marginal_relevance_search()`
80
+ - `.get()` / `.list_ids()` / `.delete()`
81
+ - `.as_retriever()` for use in LangChain chains
82
+ - Async variants (`.aadd_texts()`, `.asimilarity_search()`, etc.)
83
+
84
+ ### `StorageConfig`
85
+
86
+ Configuration object for defining where index data is stored, built with `StorageConfig.disk(path)` or `StorageConfig.s3(bucket, ...)`.
87
+
88
+ ## Documentation
89
+
90
+ Full documentation, including metadata filtering and hybrid (BM25) search, lives at [docs.cyborg.co](https://docs.cyborg.co/versions/latest/integrations/langchain/introduction).
91
+
92
+ Using the CyborgDB client/server deployment instead of the embedded engine? The same integration is available via `pip install cyborgdb[langchain]` — see the [Deployment Models Guide](https://docs.cyborg.co/versions/latest/intro/deployment-models).
93
+
94
+ ## License
95
+
96
+ This wrapper is MIT licensed. It depends on `cyborgdb-core`, which is distributed under its own [proprietary license](https://www.cyborg.co).
@@ -0,0 +1,11 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ langchain_cyborgdb/__init__.py
5
+ langchain_cyborgdb.egg-info/PKG-INFO
6
+ langchain_cyborgdb.egg-info/SOURCES.txt
7
+ langchain_cyborgdb.egg-info/dependency_links.txt
8
+ langchain_cyborgdb.egg-info/requires.txt
9
+ langchain_cyborgdb.egg-info/top_level.txt
10
+ tests/test_functional.py
11
+ tests/test_imports.py
@@ -0,0 +1,4 @@
1
+ cyborgdb-core[langchain]>=0.18.0
2
+
3
+ [test]
4
+ pytest
@@ -0,0 +1 @@
1
+ langchain_cyborgdb
@@ -0,0 +1,38 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "langchain-cyborgdb"
7
+ version = "0.1.0"
8
+ description = "LangChain integration for CyborgDB: The Confidential Vector Database"
9
+ readme = "README.md"
10
+ requires-python = ">= 3.10"
11
+ license = "MIT"
12
+ authors = [{ name = "Cyborg Inc." }]
13
+ keywords = ["langchain", "vectorstore", "cyborgdb", "encrypted", "vector database"]
14
+ dependencies = ["cyborgdb-core[langchain] >= 0.18.0"]
15
+ classifiers = [
16
+ "Intended Audience :: Developers",
17
+ "Intended Audience :: Information Technology",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Topic :: Database",
25
+ "Topic :: Security :: Cryptography",
26
+ "Topic :: Software Development :: Libraries",
27
+ ]
28
+
29
+ [project.urls]
30
+ "Homepage" = "https://www.cyborg.co"
31
+ "Documentation" = "https://docs.cyborg.co/versions/latest/integrations/langchain/introduction"
32
+ "Repository" = "https://github.com/cyborginc/langchain-cyborgdb"
33
+
34
+ [project.optional-dependencies]
35
+ test = ["pytest"]
36
+
37
+ [tool.setuptools.packages.find]
38
+ include = ["langchain_cyborgdb*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,189 @@
1
+ """Functional tests: the re-exported integration works end-to-end.
2
+
3
+ Adapted from cyborgdb-core's py_langchain_test.py, but importing everything
4
+ through ``langchain_cyborgdb`` — proving the wrapper exposes a working
5
+ integration, not just importable names.
6
+
7
+ Uses DeterministicFakeEmbedding (identical text -> identical vector), so
8
+ exact-text queries must return that text as the top hit and no embedding
9
+ model download or OpenAI key is needed. Semantic-quality tests (synonym /
10
+ paraphrase search) stay in cyborgdb-core where the real models live.
11
+
12
+ cyborgdb-core validates the CyborgDB API key against Cyborg's backend, so
13
+ the whole module is skipped unless CYBORGDB_API_KEY is set.
14
+ """
15
+
16
+ import os
17
+ import uuid
18
+
19
+ import pytest
20
+ from langchain_core.documents import Document
21
+ from langchain_core.embeddings import DeterministicFakeEmbedding
22
+
23
+ from langchain_cyborgdb import CyborgVectorStore, StorageConfig
24
+
25
+ pytestmark = pytest.mark.skipif(
26
+ not os.environ.get("CYBORGDB_API_KEY"),
27
+ reason="CYBORGDB_API_KEY not set; functional tests need a real key",
28
+ )
29
+
30
+ EMBEDDING = DeterministicFakeEmbedding(size=128)
31
+
32
+
33
+ @pytest.fixture
34
+ def make_store(tmp_path):
35
+ """Build stores with unique index names; delete their indexes afterward."""
36
+ stores = []
37
+
38
+ def _make(texts=None, metadatas=None, ids=None, documents=None, **overrides):
39
+ kwargs = dict(
40
+ embedding=EMBEDDING,
41
+ index_name=f"lc_wrapper_{uuid.uuid4().hex[:12]}",
42
+ index_key=CyborgVectorStore.generate_key(),
43
+ api_key=os.environ["CYBORGDB_API_KEY"],
44
+ storage_config=StorageConfig.disk(str(tmp_path)),
45
+ metric="cosine",
46
+ )
47
+ kwargs.update(overrides)
48
+ if documents is not None:
49
+ store = CyborgVectorStore.from_documents(documents=documents, **kwargs)
50
+ elif texts is not None:
51
+ store = CyborgVectorStore.from_texts(
52
+ texts=texts, metadatas=metadatas, ids=ids, **kwargs
53
+ )
54
+ else:
55
+ store = CyborgVectorStore(**kwargs)
56
+ stores.append(store)
57
+ return store
58
+
59
+ yield _make
60
+
61
+ for store in stores:
62
+ try:
63
+ store.delete(delete_index=True)
64
+ except Exception:
65
+ pass
66
+
67
+
68
+ def test_quickstart_flow(make_store):
69
+ """The docs quickstart shape: from_texts -> similarity_search."""
70
+ store = make_store(texts=["hello world", "goodbye world"])
71
+
72
+ docs = store.similarity_search("hello world", k=2)
73
+
74
+ assert len(docs) == 2
75
+ assert docs[0].page_content == "hello world"
76
+ assert {doc.page_content for doc in docs} == {"hello world", "goodbye world"}
77
+
78
+
79
+ def test_search_methods_return_contents_and_metadata(make_store):
80
+ texts = ["cat on a mat", "dog in a fog", "bird on a wire", "fish in a dish"]
81
+ metadatas = [{"animal": text.split()[0], "idx": i} for i, text in enumerate(texts)]
82
+ expected = dict(zip(texts, metadatas))
83
+ store = make_store(texts=texts, metadatas=metadatas)
84
+
85
+ query = "cat on a mat"
86
+ searches = {
87
+ "similarity_search": store.similarity_search(query, k=4),
88
+ "similarity_search_with_score": [
89
+ doc for doc, _ in store.similarity_search_with_score(query, k=4)
90
+ ],
91
+ "similarity_search_by_vector": store.similarity_search_by_vector(
92
+ EMBEDDING.embed_query(query), k=4
93
+ ),
94
+ }
95
+ for name, docs in searches.items():
96
+ assert len(docs) == len(texts), name
97
+ for doc in docs:
98
+ assert doc.page_content in expected, name
99
+ assert doc.metadata == expected[doc.page_content], name
100
+
101
+
102
+ def test_metadata_filtering(make_store):
103
+ texts = [f"Doc {i}" for i in range(10)]
104
+ metadatas = [
105
+ {"owner": {"name": "Jane" if i % 2 == 0 else "John"}} for i in range(10)
106
+ ]
107
+ store = make_store(texts=texts, metadatas=metadatas)
108
+
109
+ results = store.similarity_search(
110
+ "Doc 0", k=10, filter={"owner.name": {"$eq": "Jane"}}
111
+ )
112
+
113
+ assert results
114
+ assert all(doc.metadata["owner"]["name"] == "Jane" for doc in results)
115
+
116
+
117
+ def test_delete_documents(make_store):
118
+ texts = [f"Delete Me {i}" for i in range(5)]
119
+ store = make_store()
120
+ ids = store.add_texts(texts, metadatas=[{"n": i} for i in range(5)])
121
+ assert len(ids) == 5
122
+
123
+ store.delete(ids=[ids[1], ids[3]])
124
+
125
+ remaining = store.similarity_search("Delete Me 0", k=5)
126
+ remaining_ns = {doc.metadata["n"] for doc in remaining}
127
+ assert remaining_ns == {0, 2, 4}
128
+
129
+
130
+ def test_mmr_search(make_store):
131
+ texts = [f"topic {i} foxes and dogs" for i in range(10)]
132
+ store = make_store(
133
+ texts=texts, metadatas=[{"category": f"group_{i % 3}"} for i in range(10)]
134
+ )
135
+
136
+ results = store.max_marginal_relevance_search(
137
+ "topic 1 foxes and dogs", k=3, fetch_k=6, lambda_mult=0.5
138
+ )
139
+
140
+ assert len(results) == 3
141
+
142
+
143
+ def test_from_documents(make_store):
144
+ documents = [
145
+ Document(page_content=f"LangChain doc {i}", metadata={"category": "test"})
146
+ for i in range(10)
147
+ ]
148
+ store = make_store(documents=documents)
149
+
150
+ results = store.similarity_search("LangChain doc 5", k=2)
151
+
152
+ assert results
153
+ assert results[0].page_content == "LangChain doc 5"
154
+ assert results[0].metadata == {"category": "test"}
155
+
156
+
157
+ def test_list_ids_get_and_upsert(make_store):
158
+ texts = ["alpha text", "beta text", "gamma text"]
159
+ ids = ["doc_001", "doc_002", "doc_003"]
160
+ store = make_store()
161
+ store.add_texts(texts, [{"pos": i} for i in range(3)], ids=ids)
162
+
163
+ assert sorted(store.list_ids()) == ids
164
+
165
+ doc = store.get_document("doc_002")
166
+ assert doc is not None
167
+ assert doc.page_content == "beta text"
168
+ assert doc.metadata == {"pos": 1}
169
+
170
+ docs = store.get_documents(["doc_001", "doc_003", "doc_999"])
171
+ assert len(docs) == 3
172
+ assert docs[0] is not None and docs[1] is not None
173
+ assert docs[2] is None
174
+
175
+ # Re-adding an existing ID upserts rather than duplicating.
176
+ store.add_texts(["alpha text updated"], ids=["doc_001"])
177
+ assert len(store.list_ids()) == 3
178
+ assert store.get_document("doc_001").page_content == "alpha text updated"
179
+
180
+
181
+ def test_as_retriever(make_store):
182
+ texts = ["red apple", "green pear", "blue sky"]
183
+ store = make_store(texts=texts)
184
+
185
+ retriever = store.as_retriever(search_kwargs={"k": 2})
186
+ docs = retriever.invoke("red apple")
187
+
188
+ assert len(docs) == 2
189
+ assert docs[0].page_content == "red apple"
@@ -0,0 +1,26 @@
1
+ """Smoke tests: the package installs and the public API is importable.
2
+
3
+ These mirror the acceptance criteria on cyborginc/cyborgdb-core#2719 —
4
+ `from langchain_cyborgdb import CyborgVectorStore, StorageConfig` must work
5
+ in a clean environment against cyborgdb-core 0.18.x.
6
+ """
7
+
8
+ from langchain_core.vectorstores import VectorStore
9
+
10
+ import langchain_cyborgdb
11
+ from langchain_cyborgdb import CyborgEmbeddings, CyborgVectorStore, StorageConfig
12
+
13
+
14
+ def test_cyborg_vector_store_is_a_langchain_vectorstore():
15
+ assert issubclass(CyborgVectorStore, VectorStore)
16
+
17
+
18
+ def test_storage_config_factories_exist():
19
+ assert callable(StorageConfig.disk)
20
+ assert callable(StorageConfig.s3)
21
+
22
+
23
+ def test_public_api_matches_all():
24
+ for name in langchain_cyborgdb.__all__:
25
+ assert getattr(langchain_cyborgdb, name) is not None
26
+ assert CyborgEmbeddings is not None