ws-bom-robot-app 0.0.39__tar.gz → 0.0.40__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.
- {ws_bom_robot_app-0.0.39/ws_bom_robot_app.egg-info → ws_bom_robot_app-0.0.40}/PKG-INFO +1 -1
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/setup.py +1 -1
- ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/db/base.py +143 -0
- ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/db/chroma.py +77 -0
- ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/db/faiss.py +64 -0
- ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/db/manager.py +15 -0
- ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/db/qdrant.py +58 -0
- ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/loader/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40/ws_bom_robot_app.egg-info}/PKG-INFO +1 -1
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app.egg-info/SOURCES.txt +6 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/MANIFEST.in +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/README.md +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/pyproject.toml +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/requirements.txt +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/setup.cfg +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/auth.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/config.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/cron_manager.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/agent_description.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/agent_handler.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/agent_lcel.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/api.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/defaut_prompt.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/main.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/models/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/models/api.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/models/base.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/models/kb.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/providers/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/providers/llm_manager.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/settings.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/models/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/models/main.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/tool_builder.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/tool_manager.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/utils.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/agent.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/chunker.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/download.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/kb.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/print.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/secrets.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/utils/webhooks.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39/ws_bom_robot_app/llm/vector_store/integration → ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/db}/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/generator.py +0 -0
- {ws_bom_robot_app-0.0.39/ws_bom_robot_app/llm/vector_store/loader → ws_bom_robot_app-0.0.40/ws_bom_robot_app/llm/vector_store/integration}/__init__.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/azure.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/base.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/confluence.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/dropbox.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/gcs.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/github.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/googledrive.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/jira.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/manager.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/s3.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/sftp.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/sharepoint.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/sitemap.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/integration/slack.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/loader/base.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/loader/docling.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/loader/json_loader.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/main.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/task_manager.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/util.py +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app.egg-info/dependency_links.txt +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app.egg-info/requires.txt +0 -0
- {ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ _requirements = [line.split('#')[0].strip() for line in open("requirements.txt")
|
|
|
4
4
|
|
|
5
5
|
setup(
|
|
6
6
|
name="ws_bom_robot_app",
|
|
7
|
-
version="0.0.
|
|
7
|
+
version="0.0.40",
|
|
8
8
|
description="A FastAPI application serving ws bom/robot/llm platform ai.",
|
|
9
9
|
long_description=open("README.md", encoding='utf-8').read(),
|
|
10
10
|
long_description_content_type="text/markdown",
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, Optional, List, Dict
|
|
3
|
+
import asyncio
|
|
4
|
+
from langchain_core.documents import Document
|
|
5
|
+
from langchain_core.embeddings import Embeddings
|
|
6
|
+
from langchain_core.language_models import BaseChatModel
|
|
7
|
+
from langchain_core.vectorstores.base import VectorStoreRetriever, VectorStore
|
|
8
|
+
from langchain.retrievers import SelfQueryRetriever
|
|
9
|
+
from langchain.chains.query_constructor.schema import AttributeInfo
|
|
10
|
+
|
|
11
|
+
class VectorDBStrategy(ABC):
|
|
12
|
+
class VectorDBStrategy:
|
|
13
|
+
"""
|
|
14
|
+
A strategy interface for managing vector databases. It caches and retrieves vector
|
|
15
|
+
stores, providing mechanisms for creating them, retrieving them, and invoking
|
|
16
|
+
document searches.
|
|
17
|
+
Attributes:
|
|
18
|
+
_CACHE (dict[str, VectorStore]):
|
|
19
|
+
A dictionary that caches loaded VectoreStore(e.g. Faiss,Chroma,qDrant) indexes keyed by their storage IDs.
|
|
20
|
+
Methods:
|
|
21
|
+
create(embeddings, documents, storage_id, **kwargs):
|
|
22
|
+
Asynchronously create a vector store using the provided embeddings,
|
|
23
|
+
documents, and a unique storage identifier. Returns the created
|
|
24
|
+
store's ID or None if creation fails.
|
|
25
|
+
get_loader(embeddings, storage_id, **kwargs):
|
|
26
|
+
Retrieve a vector store loader based on the provided embeddings
|
|
27
|
+
and storage identifier. This loader can be used to perform
|
|
28
|
+
further operations like retrieving documents.
|
|
29
|
+
get_retriever(embeddings, storage_id, search_type, search_kwargs, **kwargs):
|
|
30
|
+
Retrieve a VectorStoreRetriever for searching documents. Supports
|
|
31
|
+
different search methods (e.g., similarity, mmr) and employs the
|
|
32
|
+
appropriate strategy based on the search_type argument.
|
|
33
|
+
supports_self_query():
|
|
34
|
+
Indicates whether this strategy supports self-querying functionality.
|
|
35
|
+
By default, returns True.
|
|
36
|
+
_get_self_query_retriever(llm, store, description, metadata):
|
|
37
|
+
Creates a SelfQueryRetriever using the specified language model,
|
|
38
|
+
vector store, document description, and metadata. Used internally
|
|
39
|
+
for self-querying when supported.
|
|
40
|
+
invoke(embeddings, storage_id, query, search_type, search_kwargs, **kwargs):
|
|
41
|
+
Asynchronously searches for documents based on a query. Depending
|
|
42
|
+
on arguments and available metadata, either uses a self-query
|
|
43
|
+
retriever or falls back to other retrieval methods (e.g., mixed
|
|
44
|
+
similarity and mmr).
|
|
45
|
+
_remove_duplicates(docs):
|
|
46
|
+
Removes duplicate documents by checking their page content,
|
|
47
|
+
returning a list with unique results.
|
|
48
|
+
_combine_search(retrievers, query):
|
|
49
|
+
Asynchronously invokes multiple retrievers in parallel, then merges
|
|
50
|
+
their results while removing duplicates.
|
|
51
|
+
"""
|
|
52
|
+
_CACHE: dict[str, VectorStore] = {}
|
|
53
|
+
def _clear_cache(self, key: str):
|
|
54
|
+
if key in self._CACHE:
|
|
55
|
+
del self._CACHE[key]
|
|
56
|
+
|
|
57
|
+
@abstractmethod
|
|
58
|
+
async def create(
|
|
59
|
+
self,
|
|
60
|
+
embeddings: Embeddings,
|
|
61
|
+
documents: List[Document],
|
|
62
|
+
storage_id: str,
|
|
63
|
+
**kwargs
|
|
64
|
+
) -> Optional[str]:
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
@abstractmethod
|
|
68
|
+
def get_loader(
|
|
69
|
+
self,
|
|
70
|
+
embeddings: Embeddings,
|
|
71
|
+
storage_id: str,
|
|
72
|
+
**kwargs
|
|
73
|
+
) -> VectorStore:
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
def get_retriever(
|
|
77
|
+
self,
|
|
78
|
+
embeddings: Embeddings,
|
|
79
|
+
storage_id: str,
|
|
80
|
+
search_type: str,
|
|
81
|
+
search_kwargs: Dict[str, Any],
|
|
82
|
+
**kwargs
|
|
83
|
+
) -> VectorStoreRetriever:
|
|
84
|
+
return self.get_loader(embeddings, storage_id).as_retriever(
|
|
85
|
+
search_type=search_type,
|
|
86
|
+
search_kwargs=search_kwargs
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def supports_self_query(self) -> bool:
|
|
90
|
+
return True
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def _get_self_query_retriever(llm:BaseChatModel,store:VectorStore,description:str, metadata: list[AttributeInfo]) -> SelfQueryRetriever:
|
|
94
|
+
return SelfQueryRetriever.from_llm(
|
|
95
|
+
llm=llm,
|
|
96
|
+
vectorstore=store,
|
|
97
|
+
document_contents=description,
|
|
98
|
+
metadata_field_info=metadata,
|
|
99
|
+
enable_limit=True,
|
|
100
|
+
verbose=True
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
async def invoke(
|
|
104
|
+
self,
|
|
105
|
+
embeddings: Embeddings,
|
|
106
|
+
storage_id: str,
|
|
107
|
+
query: str,
|
|
108
|
+
search_type: str,
|
|
109
|
+
search_kwargs: Dict[str, Any],
|
|
110
|
+
**kwargs
|
|
111
|
+
) -> List[Document]:
|
|
112
|
+
if self.supports_self_query():
|
|
113
|
+
if "app_tool" in kwargs and "llm" in kwargs:
|
|
114
|
+
from ws_bom_robot_app.llm.tools.tool_manager import LlmAppTool
|
|
115
|
+
app_tool: LlmAppTool = kwargs["app_tool"]
|
|
116
|
+
_description,_metadata=app_tool.get_vector_filtering()
|
|
117
|
+
if _description and _metadata:
|
|
118
|
+
llm: BaseChatModel = kwargs["llm"]
|
|
119
|
+
retriever = VectorDBStrategy._get_self_query_retriever(llm,self.get_loader(embeddings, storage_id),_description,_metadata)
|
|
120
|
+
return await retriever.ainvoke(query)
|
|
121
|
+
if search_type == "mixed":
|
|
122
|
+
similarity_retriever = self.get_retriever(embeddings, storage_id, "similarity", search_kwargs)
|
|
123
|
+
mmr_kwargs = {
|
|
124
|
+
"k": search_kwargs.get("k", 4),
|
|
125
|
+
"fetch_k": search_kwargs.get("fetch_k", 20),
|
|
126
|
+
"lambda_mult": search_kwargs.get("lambda_mult", 0.2),
|
|
127
|
+
}
|
|
128
|
+
mmr_retriever = self.get_retriever(embeddings, storage_id, "mmr", mmr_kwargs)
|
|
129
|
+
return await VectorDBStrategy._combine_search([similarity_retriever, mmr_retriever], query)
|
|
130
|
+
retriever = self.get_retriever(embeddings, storage_id, search_type, search_kwargs)
|
|
131
|
+
return await retriever.ainvoke(query)
|
|
132
|
+
|
|
133
|
+
@staticmethod
|
|
134
|
+
def _remove_duplicates(docs: List[Document]) -> List[Document]:
|
|
135
|
+
seen = set()
|
|
136
|
+
return [doc for doc in docs if not (doc.page_content in seen or seen.add(doc.page_content))]
|
|
137
|
+
@staticmethod
|
|
138
|
+
async def _combine_search(
|
|
139
|
+
retrievers: List[VectorStoreRetriever],
|
|
140
|
+
query: str
|
|
141
|
+
) -> List[Document]:
|
|
142
|
+
tasks = [retriever.ainvoke(query) for retriever in retrievers]
|
|
143
|
+
return VectorDBStrategy._remove_duplicates([doc for res in await asyncio.gather(*tasks) for doc in res])
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from langchain_chroma import Chroma as CHROMA
|
|
2
|
+
from langchain_core.documents import Document
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
import asyncio, gc, logging
|
|
5
|
+
from langchain_core.embeddings import Embeddings
|
|
6
|
+
from ws_bom_robot_app.llm.utils.chunker import DocumentChunker
|
|
7
|
+
from ws_bom_robot_app.llm.vector_store.db.base import VectorDBStrategy
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Chroma(VectorDBStrategy):
|
|
11
|
+
"""
|
|
12
|
+
A strategy class for interacting with a Chroma-based vector store implementation.
|
|
13
|
+
This class provides methods to create a Chroma vector store from a list of documents
|
|
14
|
+
and retrieve an existing Chroma instance. The vector store can be used to perform
|
|
15
|
+
operations such as embedding documents, persisting them to a storage directory, and
|
|
16
|
+
later loading them for retrieval tasks.
|
|
17
|
+
Attributes:
|
|
18
|
+
_CACHE (dict[str, CHROMA]): A cache to store and reuse Chroma instances.
|
|
19
|
+
Methods:
|
|
20
|
+
create(embeddings, documents, storage_id, **kwargs):
|
|
21
|
+
Creates a new Chroma instance after chunking the provided documents
|
|
22
|
+
and embedding them. Persists the vector store in the given storage directory.
|
|
23
|
+
If any error occurs during creation, logs the error and returns None.
|
|
24
|
+
Args:
|
|
25
|
+
embeddings (Embeddings): The embeddings strategy used to embed documents.
|
|
26
|
+
documents (list[Document]): The list of documents to be chunked and embedded.
|
|
27
|
+
storage_id (str): The directory where the Chroma vector store should be persisted.
|
|
28
|
+
**kwargs: Additional keyword arguments.
|
|
29
|
+
Returns:
|
|
30
|
+
Optional[str]: The storage ID if creation is successful; otherwise, None.
|
|
31
|
+
get_loader(embeddings, storage_id, **kwargs):
|
|
32
|
+
Retrieves a Chroma instance from the cache if it exists;
|
|
33
|
+
otherwise, creates and caches a new instance using the given embeddings and storage ID.
|
|
34
|
+
Args:
|
|
35
|
+
embeddings (Embeddings): The embeddings strategy used to create or load the Chroma instance.
|
|
36
|
+
storage_id (str): The directory where the Chroma vector store is persisted.
|
|
37
|
+
**kwargs: Additional keyword arguments.
|
|
38
|
+
Returns:
|
|
39
|
+
CHROMA: The retrieved or newly created Chroma instance.
|
|
40
|
+
"""
|
|
41
|
+
async def create(
|
|
42
|
+
self,
|
|
43
|
+
embeddings: Embeddings,
|
|
44
|
+
documents: list[Document],
|
|
45
|
+
storage_id: str,
|
|
46
|
+
**kwargs
|
|
47
|
+
) -> Optional[str]:
|
|
48
|
+
try:
|
|
49
|
+
chunked_docs = DocumentChunker.chunk(documents)
|
|
50
|
+
await asyncio.to_thread(
|
|
51
|
+
CHROMA.from_documents,
|
|
52
|
+
documents=chunked_docs,
|
|
53
|
+
embedding=embeddings,
|
|
54
|
+
persist_directory=storage_id
|
|
55
|
+
)
|
|
56
|
+
self._clear_cache(storage_id)
|
|
57
|
+
return storage_id
|
|
58
|
+
except Exception as e:
|
|
59
|
+
logging.error(f"{Chroma.__name__} create error: {e}")
|
|
60
|
+
raise e
|
|
61
|
+
finally:
|
|
62
|
+
del documents
|
|
63
|
+
gc.collect()
|
|
64
|
+
|
|
65
|
+
def get_loader(
|
|
66
|
+
self,
|
|
67
|
+
embeddings: Embeddings,
|
|
68
|
+
storage_id: str,
|
|
69
|
+
**kwargs
|
|
70
|
+
) -> CHROMA:
|
|
71
|
+
if storage_id not in self._CACHE:
|
|
72
|
+
self._CACHE[storage_id] = CHROMA(
|
|
73
|
+
collection_name="default",
|
|
74
|
+
embedding_function=embeddings,
|
|
75
|
+
persist_directory=storage_id
|
|
76
|
+
)
|
|
77
|
+
return self._CACHE[storage_id]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from langchain_community.vectorstores.faiss import FAISS
|
|
2
|
+
from langchain_core.documents import Document
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
import asyncio, gc, logging
|
|
5
|
+
from langchain_core.embeddings import Embeddings
|
|
6
|
+
from ws_bom_robot_app.llm.utils.chunker import DocumentChunker
|
|
7
|
+
from ws_bom_robot_app.llm.vector_store.db.base import VectorDBStrategy
|
|
8
|
+
|
|
9
|
+
class Faiss(VectorDBStrategy):
|
|
10
|
+
"""
|
|
11
|
+
Faiss is a vector database strategy that leverages a FAISS index to store and retrieve
|
|
12
|
+
vectorized documents. It provides methods for creating a new FAISS index and for
|
|
13
|
+
loading an existing index from a local directory, with an internal caching mechanism
|
|
14
|
+
to optimize repeated retrievals.
|
|
15
|
+
Methods:
|
|
16
|
+
create(
|
|
17
|
+
Asynchronously creates a FAISS index from the given documents, using the
|
|
18
|
+
provided embeddings, then saves it locally under the specified storage ID.
|
|
19
|
+
Returns the storage ID if successful, or None otherwise.
|
|
20
|
+
get_loader(
|
|
21
|
+
Retrieves a FAISS index associated with a given storage ID. If this index
|
|
22
|
+
was previously loaded and cached, it returns the cached instance; otherwise,
|
|
23
|
+
it loads the index from local storage and caches it for subsequent use.
|
|
24
|
+
"""
|
|
25
|
+
async def create(
|
|
26
|
+
self,
|
|
27
|
+
embeddings: Embeddings,
|
|
28
|
+
documents: list[Document],
|
|
29
|
+
storage_id: str,
|
|
30
|
+
**kwargs
|
|
31
|
+
) -> Optional[str]:
|
|
32
|
+
try:
|
|
33
|
+
chunked_docs = DocumentChunker.chunk(documents)
|
|
34
|
+
_instance = await asyncio.to_thread(
|
|
35
|
+
FAISS.from_documents,
|
|
36
|
+
chunked_docs,
|
|
37
|
+
embeddings
|
|
38
|
+
)
|
|
39
|
+
await asyncio.to_thread(_instance.save_local, storage_id)
|
|
40
|
+
self._clear_cache(storage_id)
|
|
41
|
+
return storage_id
|
|
42
|
+
except Exception as e:
|
|
43
|
+
logging.error(f"{Faiss.__name__} create error: {e}")
|
|
44
|
+
raise e
|
|
45
|
+
finally:
|
|
46
|
+
del documents, _instance
|
|
47
|
+
gc.collect()
|
|
48
|
+
|
|
49
|
+
def get_loader(
|
|
50
|
+
self,
|
|
51
|
+
embeddings: Embeddings,
|
|
52
|
+
storage_id: str,
|
|
53
|
+
**kwargs
|
|
54
|
+
) -> FAISS:
|
|
55
|
+
if storage_id not in self._CACHE:
|
|
56
|
+
self._CACHE[storage_id] = FAISS.load_local(
|
|
57
|
+
folder_path=storage_id,
|
|
58
|
+
embeddings=embeddings,
|
|
59
|
+
allow_dangerous_deserialization=True
|
|
60
|
+
)
|
|
61
|
+
return self._CACHE[storage_id]
|
|
62
|
+
|
|
63
|
+
def supports_self_query(self) -> bool:
|
|
64
|
+
return False
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from ws_bom_robot_app.llm.vector_store.db.base import VectorDBStrategy
|
|
2
|
+
from ws_bom_robot_app.llm.vector_store.db.chroma import Chroma
|
|
3
|
+
from ws_bom_robot_app.llm.vector_store.db.faiss import Faiss
|
|
4
|
+
from ws_bom_robot_app.llm.vector_store.db.qdrant import Qdrant
|
|
5
|
+
|
|
6
|
+
class VectorDbManager:
|
|
7
|
+
_list: dict[str, VectorDBStrategy] = {
|
|
8
|
+
"chroma": Chroma(),
|
|
9
|
+
"faiss": Faiss(),
|
|
10
|
+
"qdrant": Qdrant()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@classmethod
|
|
14
|
+
def get_strategy(cls, name: str) -> VectorDBStrategy:
|
|
15
|
+
return cls._list.get(name.lower(), Faiss())
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from langchain_qdrant import QdrantVectorStore as QDRANT, FastEmbedSparse, RetrievalMode
|
|
2
|
+
from qdrant_client import QdrantClient
|
|
3
|
+
from langchain_core.documents import Document
|
|
4
|
+
from typing import Any, Optional
|
|
5
|
+
import asyncio, gc, logging, os
|
|
6
|
+
from langchain_core.embeddings import Embeddings
|
|
7
|
+
from ws_bom_robot_app.llm.utils.chunker import DocumentChunker
|
|
8
|
+
from ws_bom_robot_app.llm.vector_store.db.base import VectorDBStrategy
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Qdrant(VectorDBStrategy):
|
|
12
|
+
async def create(
|
|
13
|
+
self,
|
|
14
|
+
embeddings: Embeddings,
|
|
15
|
+
documents: list[Document],
|
|
16
|
+
storage_id: str,
|
|
17
|
+
**kwargs
|
|
18
|
+
) -> Optional[str]:
|
|
19
|
+
try:
|
|
20
|
+
chunked_docs = DocumentChunker.chunk(documents)
|
|
21
|
+
if not os.path.exists(storage_id):
|
|
22
|
+
os.makedirs(storage_id)
|
|
23
|
+
|
|
24
|
+
def _create():
|
|
25
|
+
QDRANT.from_documents(
|
|
26
|
+
documents=chunked_docs,
|
|
27
|
+
embedding=embeddings,
|
|
28
|
+
sparse_embedding=kwargs['sparse_embedding'] if 'sparse_embedding' in kwargs else FastEmbedSparse(),
|
|
29
|
+
collection_name="default",
|
|
30
|
+
path=storage_id,
|
|
31
|
+
retrieval_mode=RetrievalMode.HYBRID
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
await asyncio.to_thread(_create)
|
|
35
|
+
self._clear_cache(storage_id)
|
|
36
|
+
return storage_id
|
|
37
|
+
except Exception as e:
|
|
38
|
+
logging.error(f"{Qdrant.__name__} create error: {e}")
|
|
39
|
+
raise e
|
|
40
|
+
finally:
|
|
41
|
+
del documents
|
|
42
|
+
gc.collect()
|
|
43
|
+
|
|
44
|
+
def get_loader(
|
|
45
|
+
self,
|
|
46
|
+
embeddings: Embeddings,
|
|
47
|
+
storage_id: str,
|
|
48
|
+
**kwargs
|
|
49
|
+
) -> QDRANT:
|
|
50
|
+
if storage_id not in self._CACHE:
|
|
51
|
+
self._CACHE[storage_id] = QDRANT(
|
|
52
|
+
client=QdrantClient(path=storage_id),
|
|
53
|
+
collection_name="default",
|
|
54
|
+
embedding=embeddings,
|
|
55
|
+
sparse_embedding=FastEmbedSparse(),
|
|
56
|
+
retrieval_mode=RetrievalMode.HYBRID,
|
|
57
|
+
)
|
|
58
|
+
return self._CACHE[storage_id]
|
|
File without changes
|
|
@@ -45,6 +45,12 @@ ws_bom_robot_app/llm/utils/secrets.py
|
|
|
45
45
|
ws_bom_robot_app/llm/utils/webhooks.py
|
|
46
46
|
ws_bom_robot_app/llm/vector_store/__init__.py
|
|
47
47
|
ws_bom_robot_app/llm/vector_store/generator.py
|
|
48
|
+
ws_bom_robot_app/llm/vector_store/db/__init__.py
|
|
49
|
+
ws_bom_robot_app/llm/vector_store/db/base.py
|
|
50
|
+
ws_bom_robot_app/llm/vector_store/db/chroma.py
|
|
51
|
+
ws_bom_robot_app/llm/vector_store/db/faiss.py
|
|
52
|
+
ws_bom_robot_app/llm/vector_store/db/manager.py
|
|
53
|
+
ws_bom_robot_app/llm/vector_store/db/qdrant.py
|
|
48
54
|
ws_bom_robot_app/llm/vector_store/integration/__init__.py
|
|
49
55
|
ws_bom_robot_app/llm/vector_store/integration/azure.py
|
|
50
56
|
ws_bom_robot_app/llm/vector_store/integration/base.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/agent_description.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/providers/__init__.py
RENAMED
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/providers/llm_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/models/__init__.py
RENAMED
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/models/main.py
RENAMED
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/tool_builder.py
RENAMED
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/tools/tool_manager.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app/llm/vector_store/loader/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ws_bom_robot_app-0.0.39 → ws_bom_robot_app-0.0.40}/ws_bom_robot_app.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|