lfx-nightly 0.1.13.dev2__py3-none-any.whl → 0.1.13.dev3__py3-none-any.whl
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.
Potentially problematic release.
This version of lfx-nightly might be problematic. Click here for more details.
- lfx/_assets/component_index.json +1 -1
- lfx/base/agents/agent.py +17 -1
- lfx/base/agents/utils.py +15 -2
- lfx/base/datastax/__init__.py +5 -0
- lfx/{components/vectorstores/astradb.py → base/datastax/astradb_base.py} +81 -471
- lfx/base/mcp/util.py +30 -10
- lfx/components/datastax/__init__.py +12 -6
- lfx/components/datastax/{astra_assistant_manager.py → astradb_assistant_manager.py} +1 -0
- lfx/components/datastax/astradb_chatmemory.py +40 -0
- lfx/components/datastax/astradb_cql.py +5 -31
- lfx/components/datastax/astradb_graph.py +9 -123
- lfx/components/datastax/astradb_tool.py +12 -52
- lfx/components/datastax/astradb_vectorstore.py +133 -976
- lfx/components/datastax/create_assistant.py +1 -0
- lfx/components/datastax/create_thread.py +1 -0
- lfx/components/datastax/dotenv.py +1 -0
- lfx/components/datastax/get_assistant.py +1 -0
- lfx/components/datastax/getenvvar.py +1 -0
- lfx/components/datastax/graph_rag.py +1 -1
- lfx/components/datastax/list_assistants.py +1 -0
- lfx/components/datastax/run.py +1 -0
- lfx/components/knowledge_bases/ingestion.py +17 -9
- lfx/components/knowledge_bases/retrieval.py +16 -8
- lfx/components/vectorstores/__init__.py +0 -6
- lfx/graph/edge/base.py +2 -2
- {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev3.dist-info}/METADATA +1 -1
- {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev3.dist-info}/RECORD +30 -51
- lfx/components/datastax/astra_db.py +0 -77
- lfx/components/datastax/cassandra.py +0 -92
- lfx/components/vectorstores/astradb_graph.py +0 -326
- lfx/components/vectorstores/cassandra.py +0 -264
- lfx/components/vectorstores/cassandra_graph.py +0 -238
- lfx/components/vectorstores/chroma.py +0 -167
- lfx/components/vectorstores/clickhouse.py +0 -135
- lfx/components/vectorstores/couchbase.py +0 -102
- lfx/components/vectorstores/elasticsearch.py +0 -267
- lfx/components/vectorstores/faiss.py +0 -111
- lfx/components/vectorstores/graph_rag.py +0 -141
- lfx/components/vectorstores/hcd.py +0 -314
- lfx/components/vectorstores/milvus.py +0 -115
- lfx/components/vectorstores/mongodb_atlas.py +0 -213
- lfx/components/vectorstores/opensearch.py +0 -243
- lfx/components/vectorstores/pgvector.py +0 -72
- lfx/components/vectorstores/pinecone.py +0 -134
- lfx/components/vectorstores/qdrant.py +0 -109
- lfx/components/vectorstores/supabase.py +0 -76
- lfx/components/vectorstores/upstash.py +0 -124
- lfx/components/vectorstores/vectara.py +0 -97
- lfx/components/vectorstores/vectara_rag.py +0 -164
- lfx/components/vectorstores/weaviate.py +0 -89
- /lfx/components/datastax/{astra_vectorize.py → astradb_vectorize.py} +0 -0
- {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev3.dist-info}/WHEEL +0 -0
- {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev3.dist-info}/entry_points.txt +0 -0
lfx/base/mcp/util.py
CHANGED
|
@@ -35,13 +35,33 @@ HTTP_INTERNAL_SERVER_ERROR = 500
|
|
|
35
35
|
HTTP_UNAUTHORIZED = 401
|
|
36
36
|
HTTP_FORBIDDEN = 403
|
|
37
37
|
|
|
38
|
-
# MCP Session Manager constants
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
# MCP Session Manager constants - lazy loaded
|
|
39
|
+
_mcp_settings_cache: dict[str, Any] = {}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _get_mcp_setting(key: str, default: Any = None) -> Any:
|
|
43
|
+
"""Lazy load MCP settings from settings service."""
|
|
44
|
+
if key not in _mcp_settings_cache:
|
|
45
|
+
settings = get_settings_service().settings
|
|
46
|
+
_mcp_settings_cache[key] = getattr(settings, key, default)
|
|
47
|
+
return _mcp_settings_cache[key]
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def get_max_sessions_per_server() -> int:
|
|
51
|
+
"""Get maximum number of sessions per server to prevent resource exhaustion."""
|
|
52
|
+
return _get_mcp_setting("mcp_max_sessions_per_server")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def get_session_idle_timeout() -> int:
|
|
56
|
+
"""Get 5 minutes idle timeout for sessions."""
|
|
57
|
+
return _get_mcp_setting("mcp_session_idle_timeout")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_session_cleanup_interval() -> int:
|
|
61
|
+
"""Get cleanup interval in seconds."""
|
|
62
|
+
return _get_mcp_setting("mcp_session_cleanup_interval")
|
|
63
|
+
|
|
64
|
+
|
|
45
65
|
# RFC 7230 compliant header name pattern: token = 1*tchar
|
|
46
66
|
# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
|
|
47
67
|
# "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
|
|
@@ -432,7 +452,7 @@ class MCPSessionManager:
|
|
|
432
452
|
"""Periodically clean up idle sessions."""
|
|
433
453
|
while True:
|
|
434
454
|
try:
|
|
435
|
-
await asyncio.sleep(
|
|
455
|
+
await asyncio.sleep(get_session_cleanup_interval())
|
|
436
456
|
await self._cleanup_idle_sessions()
|
|
437
457
|
except asyncio.CancelledError:
|
|
438
458
|
break
|
|
@@ -450,7 +470,7 @@ class MCPSessionManager:
|
|
|
450
470
|
sessions_to_remove = []
|
|
451
471
|
|
|
452
472
|
for session_id, session_info in list(sessions.items()):
|
|
453
|
-
if current_time - session_info["last_used"] >
|
|
473
|
+
if current_time - session_info["last_used"] > get_session_idle_timeout():
|
|
454
474
|
sessions_to_remove.append(session_id)
|
|
455
475
|
|
|
456
476
|
# Clean up idle sessions
|
|
@@ -573,7 +593,7 @@ class MCPSessionManager:
|
|
|
573
593
|
await self._cleanup_session_by_id(server_key, session_id)
|
|
574
594
|
|
|
575
595
|
# Check if we've reached the maximum number of sessions for this server
|
|
576
|
-
if len(sessions) >=
|
|
596
|
+
if len(sessions) >= get_max_sessions_per_server():
|
|
577
597
|
# Remove the oldest session
|
|
578
598
|
oldest_session_id = min(sessions.keys(), key=lambda x: sessions[x]["last_used"])
|
|
579
599
|
await logger.ainfo(
|
|
@@ -5,17 +5,19 @@ from typing import TYPE_CHECKING, Any
|
|
|
5
5
|
from lfx.components._importing import import_mod
|
|
6
6
|
|
|
7
7
|
if TYPE_CHECKING:
|
|
8
|
-
from .
|
|
9
|
-
from .
|
|
10
|
-
from .astra_vectorize import AstraVectorizeComponent
|
|
8
|
+
from .astradb_assistant_manager import AstraAssistantManager
|
|
9
|
+
from .astradb_chatmemory import AstraDBChatMemory
|
|
11
10
|
from .astradb_cql import AstraDBCQLToolComponent
|
|
11
|
+
from .astradb_graph import AstraDBGraphVectorStoreComponent
|
|
12
12
|
from .astradb_tool import AstraDBToolComponent
|
|
13
|
+
from .astradb_vectorize import AstraVectorizeComponent
|
|
13
14
|
from .astradb_vectorstore import AstraDBVectorStoreComponent
|
|
14
15
|
from .create_assistant import AssistantsCreateAssistant
|
|
15
16
|
from .create_thread import AssistantsCreateThread
|
|
16
17
|
from .dotenv import Dotenv
|
|
17
18
|
from .get_assistant import AssistantsGetAssistantName
|
|
18
19
|
from .getenvvar import GetEnvVar
|
|
20
|
+
from .graph_rag import GraphRAGComponent
|
|
19
21
|
from .list_assistants import AssistantsListAssistants
|
|
20
22
|
from .run import AssistantsRun
|
|
21
23
|
|
|
@@ -25,14 +27,16 @@ _dynamic_imports = {
|
|
|
25
27
|
"AssistantsGetAssistantName": "get_assistant",
|
|
26
28
|
"AssistantsListAssistants": "list_assistants",
|
|
27
29
|
"AssistantsRun": "run",
|
|
28
|
-
"AstraAssistantManager": "
|
|
30
|
+
"AstraAssistantManager": "astradb_assistant_manager",
|
|
29
31
|
"AstraDBCQLToolComponent": "astradb_cql",
|
|
30
|
-
"AstraDBChatMemory": "
|
|
32
|
+
"AstraDBChatMemory": "astradb_chatmemory",
|
|
33
|
+
"AstraDBGraphVectorStoreComponent": "astradb_graph",
|
|
31
34
|
"AstraDBToolComponent": "astradb_tool",
|
|
32
35
|
"AstraDBVectorStoreComponent": "astradb_vectorstore",
|
|
33
|
-
"AstraVectorizeComponent": "
|
|
36
|
+
"AstraVectorizeComponent": "astradb_vectorize",
|
|
34
37
|
"Dotenv": "dotenv",
|
|
35
38
|
"GetEnvVar": "getenvvar",
|
|
39
|
+
"GraphRAGComponent": "graph_rag",
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
__all__ = [
|
|
@@ -44,11 +48,13 @@ __all__ = [
|
|
|
44
48
|
"AstraAssistantManager",
|
|
45
49
|
"AstraDBCQLToolComponent",
|
|
46
50
|
"AstraDBChatMemory",
|
|
51
|
+
"AstraDBGraphVectorStoreComponent",
|
|
47
52
|
"AstraDBToolComponent",
|
|
48
53
|
"AstraDBVectorStoreComponent",
|
|
49
54
|
"AstraVectorizeComponent",
|
|
50
55
|
"Dotenv",
|
|
51
56
|
"GetEnvVar",
|
|
57
|
+
"GraphRAGComponent",
|
|
52
58
|
]
|
|
53
59
|
|
|
54
60
|
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from lfx.base.datastax.astradb_base import AstraDBBaseComponent
|
|
2
|
+
from lfx.base.memory.model import LCChatMemoryComponent
|
|
3
|
+
from lfx.field_typing.constants import Memory
|
|
4
|
+
from lfx.inputs.inputs import MessageTextInput
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AstraDBChatMemory(AstraDBBaseComponent, LCChatMemoryComponent):
|
|
8
|
+
display_name = "Astra DB Chat Memory"
|
|
9
|
+
description = "Retrieves and stores chat messages from Astra DB."
|
|
10
|
+
name = "AstraDBChatMemory"
|
|
11
|
+
icon: str = "AstraDB"
|
|
12
|
+
|
|
13
|
+
inputs = [
|
|
14
|
+
*AstraDBBaseComponent.inputs,
|
|
15
|
+
MessageTextInput(
|
|
16
|
+
name="session_id",
|
|
17
|
+
display_name="Session ID",
|
|
18
|
+
info="The session ID of the chat. If empty, the current session ID parameter will be used.",
|
|
19
|
+
advanced=True,
|
|
20
|
+
),
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
def build_message_history(self) -> Memory:
|
|
24
|
+
try:
|
|
25
|
+
from langchain_astradb.chat_message_histories import AstraDBChatMessageHistory
|
|
26
|
+
except ImportError as e:
|
|
27
|
+
msg = (
|
|
28
|
+
"Could not import langchain Astra DB integration package. "
|
|
29
|
+
"Please install it with `uv pip install langchain-astradb`."
|
|
30
|
+
)
|
|
31
|
+
raise ImportError(msg) from e
|
|
32
|
+
|
|
33
|
+
return AstraDBChatMessageHistory(
|
|
34
|
+
session_id=self.session_id,
|
|
35
|
+
collection_name=self.collection_name,
|
|
36
|
+
token=self.token,
|
|
37
|
+
api_endpoint=self.get_api_endpoint(),
|
|
38
|
+
namespace=self.get_keyspace(),
|
|
39
|
+
environment=self.environment,
|
|
40
|
+
)
|
|
@@ -8,20 +8,22 @@ import requests
|
|
|
8
8
|
from langchain_core.tools import StructuredTool, Tool
|
|
9
9
|
from pydantic import BaseModel, Field, create_model
|
|
10
10
|
|
|
11
|
+
from lfx.base.datastax.astradb_base import AstraDBBaseComponent
|
|
11
12
|
from lfx.base.langchain_utilities.model import LCToolComponent
|
|
12
|
-
from lfx.io import DictInput, IntInput,
|
|
13
|
+
from lfx.io import DictInput, IntInput, StrInput, TableInput
|
|
13
14
|
from lfx.log.logger import logger
|
|
14
15
|
from lfx.schema.data import Data
|
|
15
16
|
from lfx.schema.table import EditMode
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
class AstraDBCQLToolComponent(LCToolComponent):
|
|
19
|
+
class AstraDBCQLToolComponent(AstraDBBaseComponent, LCToolComponent):
|
|
19
20
|
display_name: str = "Astra DB CQL"
|
|
20
21
|
description: str = "Create a tool to get transactional data from DataStax Astra DB CQL Table"
|
|
21
22
|
documentation: str = "https://docs.langflow.org/bundles-datastax#astra-db-cql"
|
|
22
23
|
icon: str = "AstraDB"
|
|
23
24
|
|
|
24
25
|
inputs = [
|
|
26
|
+
*AstraDBBaseComponent.inputs,
|
|
25
27
|
StrInput(name="tool_name", display_name="Tool Name", info="The name of the tool.", required=True),
|
|
26
28
|
StrInput(
|
|
27
29
|
name="tool_description",
|
|
@@ -29,34 +31,6 @@ class AstraDBCQLToolComponent(LCToolComponent):
|
|
|
29
31
|
info="The tool description to be passed to the model.",
|
|
30
32
|
required=True,
|
|
31
33
|
),
|
|
32
|
-
StrInput(
|
|
33
|
-
name="keyspace",
|
|
34
|
-
display_name="Keyspace",
|
|
35
|
-
value="default_keyspace",
|
|
36
|
-
info="The keyspace name within Astra DB where the data is stored.",
|
|
37
|
-
required=True,
|
|
38
|
-
advanced=True,
|
|
39
|
-
),
|
|
40
|
-
StrInput(
|
|
41
|
-
name="table_name",
|
|
42
|
-
display_name="Table Name",
|
|
43
|
-
info="The name of the table within Astra DB where the data is stored.",
|
|
44
|
-
required=True,
|
|
45
|
-
),
|
|
46
|
-
SecretStrInput(
|
|
47
|
-
name="token",
|
|
48
|
-
display_name="Astra DB Application Token",
|
|
49
|
-
info="Authentication token for accessing Astra DB.",
|
|
50
|
-
value="ASTRA_DB_APPLICATION_TOKEN",
|
|
51
|
-
required=True,
|
|
52
|
-
),
|
|
53
|
-
StrInput(
|
|
54
|
-
name="api_endpoint",
|
|
55
|
-
display_name="API Endpoint",
|
|
56
|
-
info="API endpoint URL for the Astra DB service.",
|
|
57
|
-
value="ASTRA_DB_API_ENDPOINT",
|
|
58
|
-
required=True,
|
|
59
|
-
),
|
|
60
34
|
StrInput(
|
|
61
35
|
name="projection_fields",
|
|
62
36
|
display_name="Projection fields",
|
|
@@ -204,7 +178,7 @@ class AstraDBCQLToolComponent(LCToolComponent):
|
|
|
204
178
|
|
|
205
179
|
def astra_rest(self, args):
|
|
206
180
|
headers = {"Accept": "application/json", "X-Cassandra-Token": f"{self.token}"}
|
|
207
|
-
astra_url = f"{self.
|
|
181
|
+
astra_url = f"{self.get_api_endpoint()}/api/rest/v2/keyspaces/{self.get_keyspace()}/{self.collection_name}/"
|
|
208
182
|
where = {}
|
|
209
183
|
|
|
210
184
|
for param in self.tools_params:
|
|
@@ -1,138 +1,36 @@
|
|
|
1
|
-
import os
|
|
2
|
-
|
|
3
1
|
import orjson
|
|
4
2
|
|
|
3
|
+
from lfx.base.datastax.astradb_base import AstraDBBaseComponent
|
|
5
4
|
from lfx.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store
|
|
6
5
|
from lfx.helpers.data import docs_to_data
|
|
7
6
|
from lfx.inputs.inputs import (
|
|
8
|
-
BoolInput,
|
|
9
7
|
DictInput,
|
|
10
8
|
DropdownInput,
|
|
11
9
|
FloatInput,
|
|
12
|
-
HandleInput,
|
|
13
10
|
IntInput,
|
|
14
|
-
SecretStrInput,
|
|
15
11
|
StrInput,
|
|
16
12
|
)
|
|
17
13
|
from lfx.schema.data import Data
|
|
18
14
|
|
|
19
15
|
|
|
20
|
-
class AstraDBGraphVectorStoreComponent(LCVectorStoreComponent):
|
|
16
|
+
class AstraDBGraphVectorStoreComponent(AstraDBBaseComponent, LCVectorStoreComponent):
|
|
21
17
|
display_name: str = "Astra DB Graph"
|
|
22
18
|
description: str = "Implementation of Graph Vector Store using Astra DB"
|
|
23
19
|
name = "AstraDBGraph"
|
|
24
20
|
documentation: str = "https://docs.langflow.org/bundles-datastax#astra-db-graph"
|
|
25
21
|
icon: str = "AstraDB"
|
|
22
|
+
legacy: bool = True
|
|
23
|
+
replacement = ["datastax.GraphRAG"]
|
|
26
24
|
|
|
27
25
|
inputs = [
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
display_name="Astra DB Application Token",
|
|
31
|
-
info="Authentication token for accessing Astra DB.",
|
|
32
|
-
value="ASTRA_DB_APPLICATION_TOKEN",
|
|
33
|
-
required=True,
|
|
34
|
-
advanced=os.getenv("ASTRA_ENHANCED", "false").lower() == "true",
|
|
35
|
-
),
|
|
36
|
-
SecretStrInput(
|
|
37
|
-
name="api_endpoint",
|
|
38
|
-
display_name="Database" if os.getenv("ASTRA_ENHANCED", "false").lower() == "true" else "API Endpoint",
|
|
39
|
-
info="API endpoint URL for the Astra DB service.",
|
|
40
|
-
value="ASTRA_DB_API_ENDPOINT",
|
|
41
|
-
required=True,
|
|
42
|
-
),
|
|
43
|
-
StrInput(
|
|
44
|
-
name="collection_name",
|
|
45
|
-
display_name="Collection Name",
|
|
46
|
-
info="The name of the collection within Astra DB where the vectors will be stored.",
|
|
47
|
-
required=True,
|
|
48
|
-
),
|
|
26
|
+
*AstraDBBaseComponent.inputs,
|
|
27
|
+
*LCVectorStoreComponent.inputs,
|
|
49
28
|
StrInput(
|
|
50
29
|
name="metadata_incoming_links_key",
|
|
51
30
|
display_name="Metadata incoming links key",
|
|
52
31
|
info="Metadata key used for incoming links.",
|
|
53
32
|
advanced=True,
|
|
54
33
|
),
|
|
55
|
-
*LCVectorStoreComponent.inputs,
|
|
56
|
-
StrInput(
|
|
57
|
-
name="keyspace",
|
|
58
|
-
display_name="Keyspace",
|
|
59
|
-
info="Optional keyspace within Astra DB to use for the collection.",
|
|
60
|
-
advanced=True,
|
|
61
|
-
),
|
|
62
|
-
HandleInput(
|
|
63
|
-
name="embedding_model",
|
|
64
|
-
display_name="Embedding Model",
|
|
65
|
-
input_types=["Embeddings"],
|
|
66
|
-
info="Allows an embedding model configuration.",
|
|
67
|
-
),
|
|
68
|
-
DropdownInput(
|
|
69
|
-
name="metric",
|
|
70
|
-
display_name="Metric",
|
|
71
|
-
info="Optional distance metric for vector comparisons in the vector store.",
|
|
72
|
-
options=["cosine", "dot_product", "euclidean"],
|
|
73
|
-
value="cosine",
|
|
74
|
-
advanced=True,
|
|
75
|
-
),
|
|
76
|
-
IntInput(
|
|
77
|
-
name="batch_size",
|
|
78
|
-
display_name="Batch Size",
|
|
79
|
-
info="Optional number of data to process in a single batch.",
|
|
80
|
-
advanced=True,
|
|
81
|
-
),
|
|
82
|
-
IntInput(
|
|
83
|
-
name="bulk_insert_batch_concurrency",
|
|
84
|
-
display_name="Bulk Insert Batch Concurrency",
|
|
85
|
-
info="Optional concurrency level for bulk insert operations.",
|
|
86
|
-
advanced=True,
|
|
87
|
-
),
|
|
88
|
-
IntInput(
|
|
89
|
-
name="bulk_insert_overwrite_concurrency",
|
|
90
|
-
display_name="Bulk Insert Overwrite Concurrency",
|
|
91
|
-
info="Optional concurrency level for bulk insert operations that overwrite existing data.",
|
|
92
|
-
advanced=True,
|
|
93
|
-
),
|
|
94
|
-
IntInput(
|
|
95
|
-
name="bulk_delete_concurrency",
|
|
96
|
-
display_name="Bulk Delete Concurrency",
|
|
97
|
-
info="Optional concurrency level for bulk delete operations.",
|
|
98
|
-
advanced=True,
|
|
99
|
-
),
|
|
100
|
-
DropdownInput(
|
|
101
|
-
name="setup_mode",
|
|
102
|
-
display_name="Setup Mode",
|
|
103
|
-
info="Configuration mode for setting up the vector store, with options like 'Sync', or 'Off'.",
|
|
104
|
-
options=["Sync", "Off"],
|
|
105
|
-
advanced=True,
|
|
106
|
-
value="Sync",
|
|
107
|
-
),
|
|
108
|
-
BoolInput(
|
|
109
|
-
name="pre_delete_collection",
|
|
110
|
-
display_name="Pre Delete Collection",
|
|
111
|
-
info="Boolean flag to determine whether to delete the collection before creating a new one.",
|
|
112
|
-
advanced=True,
|
|
113
|
-
value=False,
|
|
114
|
-
),
|
|
115
|
-
StrInput(
|
|
116
|
-
name="metadata_indexing_include",
|
|
117
|
-
display_name="Metadata Indexing Include",
|
|
118
|
-
info="Optional list of metadata fields to include in the indexing.",
|
|
119
|
-
advanced=True,
|
|
120
|
-
list=True,
|
|
121
|
-
),
|
|
122
|
-
StrInput(
|
|
123
|
-
name="metadata_indexing_exclude",
|
|
124
|
-
display_name="Metadata Indexing Exclude",
|
|
125
|
-
info="Optional list of metadata fields to exclude from the indexing.",
|
|
126
|
-
advanced=True,
|
|
127
|
-
list=True,
|
|
128
|
-
),
|
|
129
|
-
StrInput(
|
|
130
|
-
name="collection_indexing_policy",
|
|
131
|
-
display_name="Collection Indexing Policy",
|
|
132
|
-
info='Optional JSON string for the "indexing" field of the collection. '
|
|
133
|
-
"See https://docs.datastax.com/en/astra-db-serverless/api-reference/collections.html#the-indexing-option",
|
|
134
|
-
advanced=True,
|
|
135
|
-
),
|
|
136
34
|
IntInput(
|
|
137
35
|
name="number_of_results",
|
|
138
36
|
display_name="Number of Results",
|
|
@@ -174,7 +72,6 @@ class AstraDBGraphVectorStoreComponent(LCVectorStoreComponent):
|
|
|
174
72
|
@check_cached_vector_store
|
|
175
73
|
def build_vector_store(self):
|
|
176
74
|
try:
|
|
177
|
-
from astrapy.admin import parse_api_endpoint
|
|
178
75
|
from langchain_astradb import AstraDBGraphVectorStore
|
|
179
76
|
from langchain_astradb.utils.astradb import SetupMode
|
|
180
77
|
except ImportError as e:
|
|
@@ -196,25 +93,14 @@ class AstraDBGraphVectorStoreComponent(LCVectorStoreComponent):
|
|
|
196
93
|
try:
|
|
197
94
|
self.log(f"Initializing Graph Vector Store {self.collection_name}")
|
|
198
95
|
|
|
199
|
-
# Handle environment parsing with try-except to avoid circular import
|
|
200
|
-
environment = None
|
|
201
|
-
if self.api_endpoint:
|
|
202
|
-
try:
|
|
203
|
-
from astrapy.admin import parse_api_endpoint
|
|
204
|
-
|
|
205
|
-
environment = parse_api_endpoint(self.api_endpoint).environment
|
|
206
|
-
except ImportError:
|
|
207
|
-
self.log("Warning: Could not import parse_api_endpoint, using None for environment")
|
|
208
|
-
environment = None
|
|
209
|
-
|
|
210
96
|
vector_store = AstraDBGraphVectorStore(
|
|
211
97
|
embedding=self.embedding_model,
|
|
212
98
|
collection_name=self.collection_name,
|
|
213
99
|
metadata_incoming_links_key=self.metadata_incoming_links_key or "incoming_links",
|
|
214
100
|
token=self.token,
|
|
215
|
-
api_endpoint=self.
|
|
216
|
-
namespace=self.
|
|
217
|
-
environment=environment,
|
|
101
|
+
api_endpoint=self.get_api_endpoint(),
|
|
102
|
+
namespace=self.get_keyspace(),
|
|
103
|
+
environment=self.environment,
|
|
218
104
|
metric=self.metric or None,
|
|
219
105
|
batch_size=self.batch_size or None,
|
|
220
106
|
bulk_insert_batch_concurrency=self.bulk_insert_batch_concurrency or None,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import os
|
|
2
1
|
from datetime import datetime, timezone
|
|
3
2
|
from typing import Any
|
|
4
3
|
|
|
@@ -6,20 +5,25 @@ from astrapy import Collection, DataAPIClient, Database
|
|
|
6
5
|
from langchain_core.tools import StructuredTool, Tool
|
|
7
6
|
from pydantic import BaseModel, Field, create_model
|
|
8
7
|
|
|
8
|
+
from lfx.base.datastax.astradb_base import AstraDBBaseComponent
|
|
9
9
|
from lfx.base.langchain_utilities.model import LCToolComponent
|
|
10
|
-
from lfx.io import BoolInput, DictInput,
|
|
10
|
+
from lfx.io import BoolInput, DictInput, IntInput, StrInput, TableInput
|
|
11
11
|
from lfx.log.logger import logger
|
|
12
12
|
from lfx.schema.data import Data
|
|
13
13
|
from lfx.schema.table import EditMode
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
class AstraDBToolComponent(LCToolComponent):
|
|
16
|
+
class AstraDBToolComponent(AstraDBBaseComponent, LCToolComponent):
|
|
17
17
|
display_name: str = "Astra DB Tool"
|
|
18
18
|
description: str = "Tool to run hybrid vector and metadata search on DataStax Astra DB Collection"
|
|
19
19
|
documentation: str = "https://docs.langflow.org/bundles-datastax#astra-db-tool"
|
|
20
20
|
icon: str = "AstraDB"
|
|
21
|
+
legacy: bool = True
|
|
22
|
+
name = "AstraDBTool"
|
|
23
|
+
replacement = ["datastax.AstraDB"]
|
|
21
24
|
|
|
22
25
|
inputs = [
|
|
26
|
+
*AstraDBBaseComponent.inputs,
|
|
23
27
|
StrInput(
|
|
24
28
|
name="tool_name",
|
|
25
29
|
display_name="Tool Name",
|
|
@@ -32,33 +36,6 @@ class AstraDBToolComponent(LCToolComponent):
|
|
|
32
36
|
info="Describe the tool to LLM. Add any information that can help the LLM to use the tool.",
|
|
33
37
|
required=True,
|
|
34
38
|
),
|
|
35
|
-
StrInput(
|
|
36
|
-
name="keyspace",
|
|
37
|
-
display_name="Keyspace Name",
|
|
38
|
-
info="The name of the keyspace within Astra where the collection is stored.",
|
|
39
|
-
value="default_keyspace",
|
|
40
|
-
advanced=True,
|
|
41
|
-
),
|
|
42
|
-
StrInput(
|
|
43
|
-
name="collection_name",
|
|
44
|
-
display_name="Collection Name",
|
|
45
|
-
info="The name of the collection within Astra DB where the vectors will be stored.",
|
|
46
|
-
required=True,
|
|
47
|
-
),
|
|
48
|
-
SecretStrInput(
|
|
49
|
-
name="token",
|
|
50
|
-
display_name="Astra DB Application Token",
|
|
51
|
-
info="Authentication token for accessing Astra DB.",
|
|
52
|
-
value="ASTRA_DB_APPLICATION_TOKEN",
|
|
53
|
-
required=True,
|
|
54
|
-
),
|
|
55
|
-
SecretStrInput(
|
|
56
|
-
name="api_endpoint",
|
|
57
|
-
display_name="Database" if os.getenv("ASTRA_ENHANCED", "false").lower() == "true" else "API Endpoint",
|
|
58
|
-
info="API endpoint URL for the Astra DB service.",
|
|
59
|
-
value="ASTRA_DB_API_ENDPOINT",
|
|
60
|
-
required=True,
|
|
61
|
-
),
|
|
62
39
|
StrInput(
|
|
63
40
|
name="projection_attributes",
|
|
64
41
|
display_name="Projection Attributes",
|
|
@@ -175,7 +152,6 @@ class AstraDBToolComponent(LCToolComponent):
|
|
|
175
152
|
advanced=False,
|
|
176
153
|
value=False,
|
|
177
154
|
),
|
|
178
|
-
HandleInput(name="embedding", display_name="Embedding Model", input_types=["Embeddings"]),
|
|
179
155
|
StrInput(
|
|
180
156
|
name="semantic_search_instruction",
|
|
181
157
|
display_name="Semantic Search Instruction",
|
|
@@ -190,26 +166,6 @@ class AstraDBToolComponent(LCToolComponent):
|
|
|
190
166
|
_cached_db: Database | None = None
|
|
191
167
|
_cached_collection: Collection | None = None
|
|
192
168
|
|
|
193
|
-
def _build_collection(self):
|
|
194
|
-
try:
|
|
195
|
-
from astrapy.admin import parse_api_endpoint
|
|
196
|
-
except ImportError as e:
|
|
197
|
-
msg = "Could not import Astra DB integration package. Please install it with `uv pip install astrapy`."
|
|
198
|
-
raise ImportError(msg) from e
|
|
199
|
-
if self._cached_collection:
|
|
200
|
-
return self._cached_collection
|
|
201
|
-
|
|
202
|
-
try:
|
|
203
|
-
environment = parse_api_endpoint(self.api_endpoint).environment
|
|
204
|
-
cached_client = DataAPIClient(self.token, environment=environment)
|
|
205
|
-
cached_db = cached_client.get_database(self.api_endpoint, keyspace=self.keyspace)
|
|
206
|
-
self._cached_collection = cached_db.get_collection(self.collection_name)
|
|
207
|
-
except Exception as e:
|
|
208
|
-
msg = f"Error building collection: {e}"
|
|
209
|
-
raise ValueError(msg) from e
|
|
210
|
-
else:
|
|
211
|
-
return self._cached_collection
|
|
212
|
-
|
|
213
169
|
def create_args_schema(self) -> dict[str, BaseModel]:
|
|
214
170
|
"""DEPRECATED: This method is deprecated. Please use create_args_schema_v2 instead.
|
|
215
171
|
|
|
@@ -375,7 +331,6 @@ class AstraDBToolComponent(LCToolComponent):
|
|
|
375
331
|
|
|
376
332
|
def run_model(self, **args) -> Data | list[Data]:
|
|
377
333
|
"""Run the query to get the data from the Astra DB collection."""
|
|
378
|
-
collection = self._build_collection()
|
|
379
334
|
sort = {}
|
|
380
335
|
|
|
381
336
|
# Build filters using the new method
|
|
@@ -405,6 +360,11 @@ class AstraDBToolComponent(LCToolComponent):
|
|
|
405
360
|
find_options["projection"] = projection
|
|
406
361
|
|
|
407
362
|
try:
|
|
363
|
+
database = self.get_database_object(api_endpoint=self.get_api_endpoint())
|
|
364
|
+
collection = database.get_collection(
|
|
365
|
+
name=self.collection_name,
|
|
366
|
+
keyspace=self.get_keyspace(),
|
|
367
|
+
)
|
|
408
368
|
results = collection.find(**find_options)
|
|
409
369
|
except Exception as e:
|
|
410
370
|
msg = f"Error on Astra DB Tool {self.tool_name} request: {e}"
|