lfx-nightly 0.1.13.dev2__py3-none-any.whl → 0.1.13.dev4__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/composio/composio_base.py +24 -9
- lfx/base/datastax/__init__.py +5 -0
- lfx/{components/vectorstores/astradb.py → base/datastax/astradb_base.py} +84 -473
- lfx/base/io/chat.py +5 -4
- lfx/base/mcp/util.py +101 -15
- lfx/cli/commands.py +1 -1
- lfx/components/agents/agent.py +1 -1
- lfx/components/agents/cuga_agent.py +1 -1
- lfx/components/agents/mcp_component.py +16 -0
- lfx/components/amazon/amazon_bedrock_converse.py +1 -1
- lfx/components/apify/apify_actor.py +3 -3
- 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/mistral/mistral_embeddings.py +1 -1
- lfx/components/openrouter/openrouter.py +49 -147
- lfx/components/vectorstores/__init__.py +0 -6
- lfx/custom/custom_component/component.py +3 -2
- lfx/graph/edge/base.py +2 -2
- lfx/graph/graph/base.py +1 -1
- lfx/graph/graph/schema.py +3 -2
- lfx/graph/vertex/vertex_types.py +1 -1
- {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev4.dist-info}/METADATA +1 -1
- {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev4.dist-info}/RECORD +44 -65
- 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.dev4.dist-info}/WHEEL +0 -0
- {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev4.dist-info}/entry_points.txt +0 -0
lfx/base/agents/agent.py
CHANGED
|
@@ -164,7 +164,16 @@ class LCAgentComponent(Component):
|
|
|
164
164
|
# ! Because the input has to be a string, we must pass the images in the chat_history
|
|
165
165
|
|
|
166
166
|
image_dicts = [item for item in lc_message.content if item.get("type") == "image"]
|
|
167
|
-
|
|
167
|
+
text_items = [item for item in lc_message.content if item.get("type") != "image"]
|
|
168
|
+
|
|
169
|
+
# Extract text content from remaining items
|
|
170
|
+
if text_items:
|
|
171
|
+
# If there are text items, extract their text content
|
|
172
|
+
input_text = " ".join(item.get("text", "") for item in text_items if item.get("type") == "text").strip()
|
|
173
|
+
|
|
174
|
+
# If input_text is still a list or empty, provide a default
|
|
175
|
+
if isinstance(input_text, list) or not input_text:
|
|
176
|
+
input_text = "Process the provided images."
|
|
168
177
|
|
|
169
178
|
if "chat_history" not in input_dict:
|
|
170
179
|
input_dict["chat_history"] = []
|
|
@@ -172,6 +181,13 @@ class LCAgentComponent(Component):
|
|
|
172
181
|
input_dict["chat_history"].extend(HumanMessage(content=[image_dict]) for image_dict in image_dicts)
|
|
173
182
|
else:
|
|
174
183
|
input_dict["chat_history"] = [HumanMessage(content=[image_dict]) for image_dict in image_dicts]
|
|
184
|
+
|
|
185
|
+
# Final safety check: ensure input_text is never empty (prevents Anthropic API errors)
|
|
186
|
+
if not input_text or (isinstance(input_text, (list, str)) and not str(input_text).strip()):
|
|
187
|
+
input_text = "Continue the conversation."
|
|
188
|
+
# Ensure the agent input is a string
|
|
189
|
+
if not isinstance(input_text, str):
|
|
190
|
+
input_text = " ".join(map(str, input_text)) if isinstance(input_text, list) else str(input_text)
|
|
175
191
|
input_dict["input"] = input_text
|
|
176
192
|
if hasattr(self, "graph"):
|
|
177
193
|
session_id = self.graph.session_id
|
lfx/base/agents/utils.py
CHANGED
|
@@ -47,9 +47,22 @@ def data_to_messages(data: list[Data | Message]) -> list[BaseMessage]:
|
|
|
47
47
|
data (List[Data | Message]): The data to convert.
|
|
48
48
|
|
|
49
49
|
Returns:
|
|
50
|
-
List[BaseMessage]: The data as messages.
|
|
50
|
+
List[BaseMessage]: The data as messages, filtering out any with empty content.
|
|
51
51
|
"""
|
|
52
|
-
|
|
52
|
+
messages = []
|
|
53
|
+
for value in data:
|
|
54
|
+
try:
|
|
55
|
+
lc_message = value.to_lc_message()
|
|
56
|
+
# Only add messages with non-empty content (prevents Anthropic API errors)
|
|
57
|
+
content = lc_message.content
|
|
58
|
+
if content and ((isinstance(content, str) and content.strip()) or (isinstance(content, list) and content)):
|
|
59
|
+
messages.append(lc_message)
|
|
60
|
+
else:
|
|
61
|
+
logger.warning("Skipping message with empty content in chat history")
|
|
62
|
+
except (ValueError, AttributeError) as e:
|
|
63
|
+
logger.warning(f"Failed to convert message to BaseMessage: {e}")
|
|
64
|
+
continue
|
|
65
|
+
return messages
|
|
53
66
|
|
|
54
67
|
|
|
55
68
|
def validate_and_create_xml_agent(
|
|
@@ -284,6 +284,21 @@ class ComposioBaseComponent(Component):
|
|
|
284
284
|
# Track all auth field names discovered across all toolkits
|
|
285
285
|
_all_auth_field_names: set[str] = set()
|
|
286
286
|
|
|
287
|
+
@classmethod
|
|
288
|
+
def get_actions_cache(cls) -> dict[str, dict[str, Any]]:
|
|
289
|
+
"""Get the class-level actions cache."""
|
|
290
|
+
return cls._actions_cache
|
|
291
|
+
|
|
292
|
+
@classmethod
|
|
293
|
+
def get_action_schema_cache(cls) -> dict[str, dict[str, Any]]:
|
|
294
|
+
"""Get the class-level action schema cache."""
|
|
295
|
+
return cls._action_schema_cache
|
|
296
|
+
|
|
297
|
+
@classmethod
|
|
298
|
+
def get_all_auth_field_names(cls) -> set[str]:
|
|
299
|
+
"""Get all auth field names discovered across toolkits."""
|
|
300
|
+
return cls._all_auth_field_names
|
|
301
|
+
|
|
287
302
|
outputs = [
|
|
288
303
|
Output(name="dataFrame", display_name="DataFrame", method="as_dataframe"),
|
|
289
304
|
]
|
|
@@ -403,11 +418,11 @@ class ComposioBaseComponent(Component):
|
|
|
403
418
|
|
|
404
419
|
# Try to load from the class-level cache
|
|
405
420
|
toolkit_slug = self.app_name.lower()
|
|
406
|
-
if toolkit_slug in self.__class__.
|
|
421
|
+
if toolkit_slug in self.__class__.get_actions_cache():
|
|
407
422
|
# Deep-copy so that any mutation on this instance does not affect the
|
|
408
423
|
# cached master copy.
|
|
409
|
-
self._actions_data = copy.deepcopy(self.__class__.
|
|
410
|
-
self._action_schemas = copy.deepcopy(self.__class__.
|
|
424
|
+
self._actions_data = copy.deepcopy(self.__class__.get_actions_cache()[toolkit_slug])
|
|
425
|
+
self._action_schemas = copy.deepcopy(self.__class__.get_action_schema_cache().get(toolkit_slug, {}))
|
|
411
426
|
logger.debug(f"Loaded actions for {toolkit_slug} from in-process cache")
|
|
412
427
|
return
|
|
413
428
|
|
|
@@ -630,8 +645,8 @@ class ComposioBaseComponent(Component):
|
|
|
630
645
|
|
|
631
646
|
# Cache actions for this toolkit so subsequent component instances
|
|
632
647
|
# can reuse them without hitting the Composio API again.
|
|
633
|
-
self.__class__.
|
|
634
|
-
self.__class__.
|
|
648
|
+
self.__class__.get_actions_cache()[toolkit_slug] = copy.deepcopy(self._actions_data)
|
|
649
|
+
self.__class__.get_action_schema_cache()[toolkit_slug] = copy.deepcopy(self._action_schemas)
|
|
635
650
|
|
|
636
651
|
except ValueError as e:
|
|
637
652
|
logger.debug(f"Could not populate Composio actions for {self.app_name}: {e}")
|
|
@@ -1313,7 +1328,7 @@ class ComposioBaseComponent(Component):
|
|
|
1313
1328
|
|
|
1314
1329
|
self._auth_dynamic_fields.add(name)
|
|
1315
1330
|
# Also add to class-level cache for better tracking
|
|
1316
|
-
self.__class__.
|
|
1331
|
+
self.__class__.get_all_auth_field_names().add(name)
|
|
1317
1332
|
|
|
1318
1333
|
def _render_custom_auth_fields(self, build_config: dict, schema: dict[str, Any], mode: str) -> None:
|
|
1319
1334
|
"""Render fields for custom auth based on schema auth_config_details sections."""
|
|
@@ -1378,7 +1393,7 @@ class ComposioBaseComponent(Component):
|
|
|
1378
1393
|
if name:
|
|
1379
1394
|
names.add(name)
|
|
1380
1395
|
# Add to class-level cache for tracking all discovered auth fields
|
|
1381
|
-
self.__class__.
|
|
1396
|
+
self.__class__.get_all_auth_field_names().add(name)
|
|
1382
1397
|
# Only use names discovered from the toolkit schema; do not add aliases
|
|
1383
1398
|
return names
|
|
1384
1399
|
|
|
@@ -1443,7 +1458,7 @@ class ComposioBaseComponent(Component):
|
|
|
1443
1458
|
# Check if we need to populate actions - but also check cache availability
|
|
1444
1459
|
actions_available = bool(self._actions_data)
|
|
1445
1460
|
toolkit_slug = getattr(self, "app_name", "").lower()
|
|
1446
|
-
cached_actions_available = toolkit_slug in self.__class__.
|
|
1461
|
+
cached_actions_available = toolkit_slug in self.__class__.get_actions_cache()
|
|
1447
1462
|
|
|
1448
1463
|
should_populate = False
|
|
1449
1464
|
|
|
@@ -2623,7 +2638,7 @@ class ComposioBaseComponent(Component):
|
|
|
2623
2638
|
# Add all dynamic auth fields to protected set
|
|
2624
2639
|
protected.update(self._auth_dynamic_fields)
|
|
2625
2640
|
# Also protect any auth fields discovered across all instances
|
|
2626
|
-
protected.update(self.__class__.
|
|
2641
|
+
protected.update(self.__class__.get_all_auth_field_names())
|
|
2627
2642
|
|
|
2628
2643
|
for key, cfg in list(build_config.items()):
|
|
2629
2644
|
if key in protected:
|