holographic-sdk 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,34 @@
1
+ # Rust
2
+ /target
3
+ Cargo.lock
4
+
5
+ # Node.js
6
+ /node_modules
7
+ package-lock.json
8
+ *.node
9
+ !index.js
10
+ index.d.ts
11
+
12
+ # OS
13
+ .DS_Store
14
+ Thumbs.db
15
+
16
+ # Databases (Local dev)
17
+ memory_db/
18
+ *.db
19
+ *.redb
20
+ vectors_data.bin/
21
+
22
+ # Environment / Private
23
+ .cargo_home/
24
+ GEMINI.md
25
+ todo.md
26
+ tasks/
27
+ devplan/
28
+
29
+ # Python
30
+ __pycache__/
31
+ .venv/
32
+
33
+ # Claude Code
34
+ .claude/
@@ -0,0 +1,61 @@
1
+ Metadata-Version: 2.5
2
+ Name: holographic-sdk
3
+ Version: 0.1.0
4
+ Summary: Zero-Trust FHE-Lite SDK for Holographic Memory System
5
+ Author-email: WritersLogic <david@writerslogic.com>
6
+ License: AGPL-3.0-or-later
7
+ Requires-Python: >=3.9
8
+ Requires-Dist: numpy>=1.24.0
9
+ Requires-Dist: requests>=2.31.0
10
+ Provides-Extra: all
11
+ Requires-Dist: dspy-ai>=2.4.0; extra == 'all'
12
+ Requires-Dist: haystack-ai>=2.0.0; extra == 'all'
13
+ Requires-Dist: langchain-core>=0.1.0; extra == 'all'
14
+ Requires-Dist: llama-index-core>=0.10.0; extra == 'all'
15
+ Requires-Dist: semantic-kernel>=1.0.0; extra == 'all'
16
+ Provides-Extra: dspy
17
+ Requires-Dist: dspy-ai>=2.4.0; extra == 'dspy'
18
+ Provides-Extra: haystack
19
+ Requires-Dist: haystack-ai>=2.0.0; extra == 'haystack'
20
+ Provides-Extra: langchain
21
+ Requires-Dist: langchain-core>=0.1.0; extra == 'langchain'
22
+ Provides-Extra: llamaindex
23
+ Requires-Dist: llama-index-core>=0.10.0; extra == 'llamaindex'
24
+ Provides-Extra: semantic-kernel
25
+ Requires-Dist: semantic-kernel>=1.0.0; extra == 'semantic-kernel'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # Holographic SDK
29
+
30
+ The official Python SDK for the Holographic Memory System, featuring Zero-Trust FHE-Lite cryptographic privacy.
31
+
32
+ ## Installation
33
+
34
+ Install the base SDK:
35
+ ```bash
36
+ pip install holographic-sdk
37
+ ```
38
+
39
+ Or install with specific framework integrations:
40
+ ```bash
41
+ pip install "holographic-sdk[all]"
42
+ ```
43
+
44
+ ## Supported Integrations
45
+
46
+ ```python
47
+ # LangChain
48
+ from holographic_sdk.langchain import HolographicVectorStore
49
+
50
+ # LlamaIndex
51
+ from holographic_sdk.llamaindex import HolographicVectorStore
52
+
53
+ # Haystack
54
+ from holographic_sdk.haystack import HolographicDocumentStore
55
+
56
+ # Microsoft Semantic Kernel
57
+ from holographic_sdk.semantic_kernel import HolographicMemoryStore
58
+
59
+ # DSPy
60
+ from holographic_sdk.dspy import HolographicRM
61
+ ```
@@ -0,0 +1,34 @@
1
+ # Holographic SDK
2
+
3
+ The official Python SDK for the Holographic Memory System, featuring Zero-Trust FHE-Lite cryptographic privacy.
4
+
5
+ ## Installation
6
+
7
+ Install the base SDK:
8
+ ```bash
9
+ pip install holographic-sdk
10
+ ```
11
+
12
+ Or install with specific framework integrations:
13
+ ```bash
14
+ pip install "holographic-sdk[all]"
15
+ ```
16
+
17
+ ## Supported Integrations
18
+
19
+ ```python
20
+ # LangChain
21
+ from holographic_sdk.langchain import HolographicVectorStore
22
+
23
+ # LlamaIndex
24
+ from holographic_sdk.llamaindex import HolographicVectorStore
25
+
26
+ # Haystack
27
+ from holographic_sdk.haystack import HolographicDocumentStore
28
+
29
+ # Microsoft Semantic Kernel
30
+ from holographic_sdk.semantic_kernel import HolographicMemoryStore
31
+
32
+ # DSPy
33
+ from holographic_sdk.dspy import HolographicRM
34
+ ```
File without changes
@@ -0,0 +1,2 @@
1
+ from .retriever import HolographicRM
2
+ __all__ = ["HolographicRM"]
@@ -0,0 +1,62 @@
1
+ from typing import Any, List, Optional, Union
2
+ import requests
3
+ import hashlib
4
+ import dspy
5
+
6
+ class HolographicRM(dspy.Retrieve):
7
+ def __init__(
8
+ self,
9
+ url: str = "http://localhost:8080",
10
+ zero_trust_key: str = "",
11
+ api_key: Optional[str] = None,
12
+ tenant_id: Optional[str] = None,
13
+ k: int = 3,
14
+ embedder: Any = None
15
+ ):
16
+ super().__init__(k=k)
17
+ self.url = url
18
+ self.zero_trust_key = zero_trust_key
19
+ self.api_key = api_key
20
+ self.tenant_id = tenant_id
21
+ self.embedder = embedder
22
+
23
+ def _encrypt_vector(self, embedding: List[float]) -> List[float]:
24
+ if not self.zero_trust_key or not embedding:
25
+ return embedding
26
+ seed = int(hashlib.sha256(self.zero_trust_key.encode()).hexdigest()[:8], 16)
27
+ import random
28
+ rng = random.Random(seed)
29
+ return [val * (1.0 if rng.random() > 0.5 else -1.0) for val in embedding]
30
+
31
+ def _get_headers(self) -> dict:
32
+ headers = {"Content-Type": "application/json"}
33
+ if self.api_key:
34
+ headers["Authorization"] = f"Bearer {self.api_key}"
35
+ if self.tenant_id:
36
+ headers["X-Tenant-ID"] = self.tenant_id
37
+ return headers
38
+
39
+ def forward(self, query_or_queries: Union[str, List[str]], k: Optional[int] = None) -> dspy.Prediction:
40
+ k = k if k is not None else self.k
41
+ queries = [query_or_queries] if isinstance(query_or_queries, str) else query_or_queries
42
+
43
+ passages = []
44
+ for query in queries:
45
+ if not self.embedder:
46
+ raise ValueError("An embedder must be provided to HolographicRM")
47
+
48
+ embedding = self.embedder(query)
49
+ encrypted_query = self._encrypt_vector(embedding)
50
+
51
+ headers = self._get_headers()
52
+ payload = {
53
+ "query_vector": encrypted_query,
54
+ "top_k": k
55
+ }
56
+ res = requests.post(f"{self.url}/api/v1/query", json=payload, headers=headers)
57
+ res.raise_for_status()
58
+
59
+ for doc in res.json().get("matches", []):
60
+ passages.append(doc.get("text", ""))
61
+
62
+ return dspy.Prediction(passages=passages)
@@ -0,0 +1,2 @@
1
+ from .document_store import HolographicDocumentStore
2
+ __all__ = ["HolographicDocumentStore"]
@@ -0,0 +1,62 @@
1
+ from typing import Any, Dict, List, Optional
2
+ import requests
3
+ import hashlib
4
+ from haystack import Document
5
+ from haystack.document_stores.types import DocumentStore
6
+
7
+ class HolographicDocumentStore:
8
+ def __init__(
9
+ self,
10
+ url: str = "http://localhost:8080",
11
+ zero_trust_key: str = "",
12
+ api_key: Optional[str] = None,
13
+ tenant_id: Optional[str] = None,
14
+ ):
15
+ self.url = url
16
+ self.zero_trust_key = zero_trust_key
17
+ self.api_key = api_key
18
+ self.tenant_id = tenant_id
19
+
20
+ def _encrypt_vector(self, embedding: List[float]) -> List[float]:
21
+ if not self.zero_trust_key:
22
+ return embedding
23
+ seed = int(hashlib.sha256(self.zero_trust_key.encode()).hexdigest()[:8], 16)
24
+ import random
25
+ rng = random.Random(seed)
26
+ return [val * (1.0 if rng.random() > 0.5 else -1.0) for val in embedding]
27
+
28
+ def _get_headers(self) -> dict:
29
+ headers = {"Content-Type": "application/json"}
30
+ if self.api_key:
31
+ headers["Authorization"] = f"Bearer {self.api_key}"
32
+ if self.tenant_id:
33
+ headers["X-Tenant-ID"] = self.tenant_id
34
+ return headers
35
+
36
+ def count_documents(self) -> int:
37
+ return 0 # To be implemented on the backend API
38
+
39
+ def filter_documents(self, filters: Optional[Dict[str, Any]] = None) -> List[Document]:
40
+ return []
41
+
42
+ def write_documents(self, documents: List[Document], policy: Any = None) -> int:
43
+ headers = self._get_headers()
44
+ count = 0
45
+ for doc in documents:
46
+ vector = self._encrypt_vector(doc.embedding) if doc.embedding else []
47
+ payload = {
48
+ "id": doc.id,
49
+ "text": doc.content,
50
+ "vector": vector,
51
+ "metadata": doc.meta
52
+ }
53
+ res = requests.post(f"{self.url}/api/v1/documents", json=payload, headers=headers)
54
+ res.raise_for_status()
55
+ count += 1
56
+ return count
57
+
58
+ def delete_documents(self, document_ids: List[str]) -> None:
59
+ headers = self._get_headers()
60
+ for doc_id in document_ids:
61
+ res = requests.delete(f"{self.url}/api/v1/documents/{doc_id}", headers=headers)
62
+ res.raise_for_status()
@@ -0,0 +1,2 @@
1
+ from .vectorstores import HolographicVectorStore
2
+ __all__ = ["HolographicVectorStore"]
@@ -0,0 +1,111 @@
1
+ from typing import Any, Iterable, List, Optional
2
+ from langchain_core.embeddings import Embeddings
3
+ from langchain_core.documents import Document
4
+ from langchain_core.vectorstores import VectorStore
5
+ import holographic_memory
6
+ import hashlib
7
+
8
+ class HolographicVectorStore(VectorStore):
9
+ """
10
+ A Zero-Trust Vector Store for LangChain using Holographic Memory System (HMS).
11
+
12
+ If `zero_trust_key` is provided, all embeddings are XOR-bound with a dense
13
+ deterministic cryptographic key before being sent to the HMS engine.
14
+ The database server only processes encrypted noise, ensuring perfect data privacy.
15
+ """
16
+
17
+ def __init__(
18
+ self,
19
+ embedding_function: Embeddings,
20
+ persist_directory: str = "./hms-store",
21
+ zero_trust_key: Optional[str] = None,
22
+ dimensions: int = 16384
23
+ ):
24
+ self.embedding_function = embedding_function
25
+ self.persist_directory = persist_directory
26
+ self.dimensions = dimensions
27
+ self.zero_trust_key = zero_trust_key
28
+
29
+ # Initialize the underlying Rust engine
30
+ self.hms = holographic_memory.HmsCore(
31
+ dimensions,
32
+ persist_directory
33
+ )
34
+
35
+ def _get_fhe_lite_key_vector(self) -> Any:
36
+ """
37
+ Generates the dense Master Key vector from the string seed.
38
+ In production, this relies on the Rust core's EntangledHVec::new_deterministic.
39
+ """
40
+ if not self.zero_trust_key:
41
+ return None
42
+ seed = int(hashlib.sha256(self.zero_trust_key.encode()).hexdigest()[:15], 16)
43
+
44
+ # Create a dense key by bundling multiple sparse seeds
45
+ key_vec = holographic_memory.EntangledHVec(self.dimensions, seed)
46
+ for i in range(1, 50):
47
+ key_vec = key_vec.bind(holographic_memory.EntangledHVec(self.dimensions, seed + i))
48
+ return key_vec
49
+
50
+ def add_texts(
51
+ self,
52
+ texts: Iterable[str],
53
+ metadatas: Optional[List[dict]] = None,
54
+ **kwargs: Any
55
+ ) -> List[str]:
56
+ embeddings = self.embedding_function.embed_documents(list(texts))
57
+ key_vec = self._get_fhe_lite_key_vector()
58
+
59
+ ids = []
60
+ for i, text in enumerate(texts):
61
+ doc_id = f"doc_{hash(text)}"
62
+
63
+ # Map standard embeddings to HMS Phase Space
64
+ plain_vec = holographic_memory.encode_text(text, self.dimensions)
65
+
66
+ if key_vec:
67
+ # Client-Side Zero-Trust Encryption
68
+ plain_vec = plain_vec.bind(key_vec)
69
+
70
+ self.hms.memorize(doc_id, plain_vec)
71
+ ids.append(doc_id)
72
+
73
+ return ids
74
+
75
+ def similarity_search(
76
+ self,
77
+ query: str,
78
+ k: int = 4,
79
+ **kwargs: Any
80
+ ) -> List[Document]:
81
+
82
+ plain_query_vec = holographic_memory.encode_text(query, self.dimensions)
83
+ key_vec = self._get_fhe_lite_key_vector()
84
+
85
+ if key_vec:
86
+ # Encrypt the query before passing to the engine
87
+ search_vec = plain_query_vec.bind(key_vec)
88
+ else:
89
+ search_vec = plain_query_vec
90
+
91
+ # The underlying Rust engine searches over the encrypted index
92
+ raw_results = self.hms.query(search_vec, k)
93
+
94
+ # In a full implementation, we fetch the decrypted text chunks here
95
+ docs = []
96
+ for res in raw_results:
97
+ docs.append(Document(page_content=f"Recovered content for {res.id}", metadata={"score": res.score}))
98
+
99
+ return docs
100
+
101
+ @classmethod
102
+ def from_texts(
103
+ cls,
104
+ texts: List[str],
105
+ embedding: Embeddings,
106
+ metadatas: Optional[List[dict]] = None,
107
+ **kwargs: Any
108
+ ) -> "HolographicVectorStore":
109
+ store = cls(embedding, **kwargs)
110
+ store.add_texts(texts, metadatas)
111
+ return store
@@ -0,0 +1,2 @@
1
+ from .vectorstores import HolographicVectorStore
2
+ __all__ = ["HolographicVectorStore"]
@@ -0,0 +1,104 @@
1
+ from typing import Any, List, Optional
2
+ import requests
3
+ import hashlib
4
+ from llama_index.core.vector_stores.types import (
5
+ BasePydanticVectorStore,
6
+ VectorStoreQuery,
7
+ VectorStoreQueryResult,
8
+ MetadataFilters,
9
+ )
10
+ from llama_index.core.schema import TextNode, BaseNode
11
+
12
+ class HolographicVectorStore(BasePydanticVectorStore):
13
+ stores_text: bool = True
14
+ is_embedding_query: bool = True
15
+
16
+ url: str
17
+ zero_trust_key: str
18
+ api_key: Optional[str] = None
19
+ tenant_id: Optional[str] = None
20
+
21
+ def __init__(
22
+ self,
23
+ url: str = "http://localhost:8080",
24
+ zero_trust_key: str = "",
25
+ api_key: Optional[str] = None,
26
+ tenant_id: Optional[str] = None,
27
+ **kwargs: Any,
28
+ ) -> None:
29
+ super().__init__(
30
+ url=url,
31
+ zero_trust_key=zero_trust_key,
32
+ api_key=api_key,
33
+ tenant_id=tenant_id,
34
+ **kwargs
35
+ )
36
+
37
+ def _encrypt_vector(self, embedding: List[float]) -> List[float]:
38
+ if not self.zero_trust_key:
39
+ return embedding
40
+ seed = int(hashlib.sha256(self.zero_trust_key.encode()).hexdigest()[:8], 16)
41
+ import random
42
+ rng = random.Random(seed)
43
+ return [val * (1.0 if rng.random() > 0.5 else -1.0) for val in embedding]
44
+
45
+ def _get_headers(self) -> dict:
46
+ headers = {"Content-Type": "application/json"}
47
+ if self.api_key:
48
+ headers["Authorization"] = f"Bearer {self.api_key}"
49
+ if self.tenant_id:
50
+ headers["X-Tenant-ID"] = self.tenant_id
51
+ return headers
52
+
53
+ @property
54
+ def client(self) -> Any:
55
+ return self
56
+
57
+ def add(self, nodes: List[BaseNode], **add_kwargs: Any) -> List[str]:
58
+ headers = self._get_headers()
59
+ ids = []
60
+ for node in nodes:
61
+ vector = self._encrypt_vector(node.embedding) if node.embedding else []
62
+ payload = {
63
+ "id": node.node_id,
64
+ "text": node.get_content(metadata_mode="all"),
65
+ "vector": vector,
66
+ "metadata": node.metadata
67
+ }
68
+ res = requests.post(f"{self.url}/api/v1/documents", json=payload, headers=headers)
69
+ res.raise_for_status()
70
+ ids.append(node.node_id)
71
+ return ids
72
+
73
+ def delete(self, ref_doc_id: str, **delete_kwargs: Any) -> None:
74
+ headers = self._get_headers()
75
+ res = requests.delete(f"{self.url}/api/v1/documents/{ref_doc_id}", headers=headers)
76
+ res.raise_for_status()
77
+
78
+ def query(self, query: VectorStoreQuery, **kwargs: Any) -> VectorStoreQueryResult:
79
+ headers = self._get_headers()
80
+ encrypted_query = self._encrypt_vector(query.query_embedding) if query.query_embedding else []
81
+
82
+ payload = {
83
+ "query_vector": encrypted_query,
84
+ "top_k": query.similarity_top_k
85
+ }
86
+ res = requests.post(f"{self.url}/api/v1/query", json=payload, headers=headers)
87
+ res.raise_for_status()
88
+
89
+ results = res.json()
90
+ nodes = []
91
+ similarities = []
92
+ ids = []
93
+
94
+ for doc in results.get("matches", []):
95
+ node = TextNode(
96
+ id_=doc.get("id"),
97
+ text=doc.get("text", ""),
98
+ metadata=doc.get("metadata", {})
99
+ )
100
+ nodes.append(node)
101
+ similarities.append(doc.get("score", 0.0))
102
+ ids.append(doc.get("id"))
103
+
104
+ return VectorStoreQueryResult(nodes=nodes, similarities=similarities, ids=ids)
@@ -0,0 +1,2 @@
1
+ from .memory_store import HolographicMemoryStore
2
+ __all__ = ["HolographicMemoryStore"]
@@ -0,0 +1,120 @@
1
+ from typing import Any, List, Optional, Tuple
2
+ import requests
3
+ import hashlib
4
+ from semantic_kernel.memory.memory_store_base import MemoryStoreBase
5
+ from semantic_kernel.memory.memory_record import MemoryRecord
6
+
7
+ class HolographicMemoryStore(MemoryStoreBase):
8
+ def __init__(
9
+ self,
10
+ url: str = "http://localhost:8080",
11
+ zero_trust_key: str = "",
12
+ api_key: Optional[str] = None,
13
+ tenant_id: Optional[str] = None,
14
+ ):
15
+ self.url = url
16
+ self.zero_trust_key = zero_trust_key
17
+ self.api_key = api_key
18
+ self.tenant_id = tenant_id
19
+
20
+ def _encrypt_vector(self, embedding: List[float]) -> List[float]:
21
+ if not self.zero_trust_key or not embedding:
22
+ return embedding
23
+ seed = int(hashlib.sha256(self.zero_trust_key.encode()).hexdigest()[:8], 16)
24
+ import random
25
+ rng = random.Random(seed)
26
+ return [val * (1.0 if rng.random() > 0.5 else -1.0) for val in embedding]
27
+
28
+ def _get_headers(self) -> dict:
29
+ headers = {"Content-Type": "application/json"}
30
+ if self.api_key:
31
+ headers["Authorization"] = f"Bearer {self.api_key}"
32
+ if self.tenant_id:
33
+ headers["X-Tenant-ID"] = self.tenant_id
34
+ return headers
35
+
36
+ async def create_collection_async(self, collection_name: str) -> None:
37
+ pass
38
+
39
+ async def get_collections_async(self) -> List[str]:
40
+ return ["default"]
41
+
42
+ async def delete_collection_async(self, collection_name: str) -> None:
43
+ pass
44
+
45
+ async def does_collection_exist_async(self, collection_name: str) -> bool:
46
+ return True
47
+
48
+ async def upsert_async(self, collection_name: str, record: MemoryRecord) -> str:
49
+ headers = self._get_headers()
50
+ vector = self._encrypt_vector(record.embedding.tolist() if record.embedding is not None else [])
51
+ payload = {
52
+ "id": record._id,
53
+ "text": record._text,
54
+ "vector": vector,
55
+ "metadata": {"collection": collection_name}
56
+ }
57
+ res = requests.post(f"{self.url}/api/v1/documents", json=payload, headers=headers)
58
+ res.raise_for_status()
59
+ return record._id
60
+
61
+ async def upsert_batch_async(self, collection_name: str, records: List[MemoryRecord]) -> List[str]:
62
+ return [await self.upsert_async(collection_name, r) for r in records]
63
+
64
+ async def get_async(self, collection_name: str, key: str, with_embedding: bool = False) -> MemoryRecord:
65
+ raise NotImplementedError
66
+
67
+ async def get_batch_async(self, collection_name: str, keys: List[str], with_embeddings: bool = False) -> List[MemoryRecord]:
68
+ raise NotImplementedError
69
+
70
+ async def remove_async(self, collection_name: str, key: str) -> None:
71
+ headers = self._get_headers()
72
+ res = requests.delete(f"{self.url}/api/v1/documents/{key}", headers=headers)
73
+ res.raise_for_status()
74
+
75
+ async def remove_batch_async(self, collection_name: str, keys: List[str]) -> None:
76
+ for k in keys:
77
+ await self.remove_async(collection_name, k)
78
+
79
+ async def get_nearest_matches_async(
80
+ self,
81
+ collection_name: str,
82
+ embedding: Any,
83
+ limit: int = 1,
84
+ min_relevance_score: float = 0.0,
85
+ with_embeddings: bool = False,
86
+ ) -> List[Tuple[MemoryRecord, float]]:
87
+ headers = self._get_headers()
88
+ encrypted_query = self._encrypt_vector(embedding.tolist())
89
+ payload = {
90
+ "query_vector": encrypted_query,
91
+ "top_k": limit
92
+ }
93
+ res = requests.post(f"{self.url}/api/v1/query", json=payload, headers=headers)
94
+ res.raise_for_status()
95
+
96
+ matches = []
97
+ for doc in res.json().get("matches", []):
98
+ if doc.get("score", 0.0) >= min_relevance_score:
99
+ record = MemoryRecord(
100
+ id=doc.get("id"),
101
+ text=doc.get("text", ""),
102
+ is_reference=False,
103
+ embedding=None,
104
+ description=None,
105
+ additional_metadata=None
106
+ )
107
+ matches.append((record, doc.get("score", 0.0)))
108
+ return matches
109
+
110
+ async def get_nearest_match_async(
111
+ self,
112
+ collection_name: str,
113
+ embedding: Any,
114
+ min_relevance_score: float = 0.0,
115
+ with_embedding: bool = False,
116
+ ) -> Tuple[MemoryRecord, float]:
117
+ matches = await self.get_nearest_matches_async(
118
+ collection_name, embedding, limit=1, min_relevance_score=min_relevance_score
119
+ )
120
+ return matches[0] if matches else (None, 0.0)
@@ -0,0 +1,32 @@
1
+ [project]
2
+ name = "holographic-sdk"
3
+ version = "0.1.0"
4
+ description = "Zero-Trust FHE-Lite SDK for Holographic Memory System"
5
+ authors = [
6
+ {name = "WritersLogic", email = "david@writerslogic.com"},
7
+ ]
8
+ dependencies = [
9
+ "numpy>=1.24.0",
10
+ "requests>=2.31.0"
11
+ ]
12
+ readme = "README.md"
13
+ requires-python = ">=3.9"
14
+ license = {text = "AGPL-3.0-or-later"}
15
+
16
+ [project.optional-dependencies]
17
+ langchain = ["langchain-core>=0.1.0"]
18
+ llamaindex = ["llama-index-core>=0.10.0"]
19
+ haystack = ["haystack-ai>=2.0.0"]
20
+ semantic-kernel = ["semantic-kernel>=1.0.0"]
21
+ dspy = ["dspy-ai>=2.4.0"]
22
+ all = [
23
+ "langchain-core>=0.1.0",
24
+ "llama-index-core>=0.10.0",
25
+ "haystack-ai>=2.0.0",
26
+ "semantic-kernel>=1.0.0",
27
+ "dspy-ai>=2.4.0"
28
+ ]
29
+
30
+ [build-system]
31
+ requires = ["hatchling"]
32
+ build-backend = "hatchling.build"