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.

Files changed (67) hide show
  1. lfx/_assets/component_index.json +1 -1
  2. lfx/base/agents/agent.py +17 -1
  3. lfx/base/agents/utils.py +15 -2
  4. lfx/base/composio/composio_base.py +24 -9
  5. lfx/base/datastax/__init__.py +5 -0
  6. lfx/{components/vectorstores/astradb.py → base/datastax/astradb_base.py} +84 -473
  7. lfx/base/io/chat.py +5 -4
  8. lfx/base/mcp/util.py +101 -15
  9. lfx/cli/commands.py +1 -1
  10. lfx/components/agents/agent.py +1 -1
  11. lfx/components/agents/cuga_agent.py +1 -1
  12. lfx/components/agents/mcp_component.py +16 -0
  13. lfx/components/amazon/amazon_bedrock_converse.py +1 -1
  14. lfx/components/apify/apify_actor.py +3 -3
  15. lfx/components/datastax/__init__.py +12 -6
  16. lfx/components/datastax/{astra_assistant_manager.py → astradb_assistant_manager.py} +1 -0
  17. lfx/components/datastax/astradb_chatmemory.py +40 -0
  18. lfx/components/datastax/astradb_cql.py +5 -31
  19. lfx/components/datastax/astradb_graph.py +9 -123
  20. lfx/components/datastax/astradb_tool.py +12 -52
  21. lfx/components/datastax/astradb_vectorstore.py +133 -976
  22. lfx/components/datastax/create_assistant.py +1 -0
  23. lfx/components/datastax/create_thread.py +1 -0
  24. lfx/components/datastax/dotenv.py +1 -0
  25. lfx/components/datastax/get_assistant.py +1 -0
  26. lfx/components/datastax/getenvvar.py +1 -0
  27. lfx/components/datastax/graph_rag.py +1 -1
  28. lfx/components/datastax/list_assistants.py +1 -0
  29. lfx/components/datastax/run.py +1 -0
  30. lfx/components/knowledge_bases/ingestion.py +17 -9
  31. lfx/components/knowledge_bases/retrieval.py +16 -8
  32. lfx/components/mistral/mistral_embeddings.py +1 -1
  33. lfx/components/openrouter/openrouter.py +49 -147
  34. lfx/components/vectorstores/__init__.py +0 -6
  35. lfx/custom/custom_component/component.py +3 -2
  36. lfx/graph/edge/base.py +2 -2
  37. lfx/graph/graph/base.py +1 -1
  38. lfx/graph/graph/schema.py +3 -2
  39. lfx/graph/vertex/vertex_types.py +1 -1
  40. {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev4.dist-info}/METADATA +1 -1
  41. {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev4.dist-info}/RECORD +44 -65
  42. lfx/components/datastax/astra_db.py +0 -77
  43. lfx/components/datastax/cassandra.py +0 -92
  44. lfx/components/vectorstores/astradb_graph.py +0 -326
  45. lfx/components/vectorstores/cassandra.py +0 -264
  46. lfx/components/vectorstores/cassandra_graph.py +0 -238
  47. lfx/components/vectorstores/chroma.py +0 -167
  48. lfx/components/vectorstores/clickhouse.py +0 -135
  49. lfx/components/vectorstores/couchbase.py +0 -102
  50. lfx/components/vectorstores/elasticsearch.py +0 -267
  51. lfx/components/vectorstores/faiss.py +0 -111
  52. lfx/components/vectorstores/graph_rag.py +0 -141
  53. lfx/components/vectorstores/hcd.py +0 -314
  54. lfx/components/vectorstores/milvus.py +0 -115
  55. lfx/components/vectorstores/mongodb_atlas.py +0 -213
  56. lfx/components/vectorstores/opensearch.py +0 -243
  57. lfx/components/vectorstores/pgvector.py +0 -72
  58. lfx/components/vectorstores/pinecone.py +0 -134
  59. lfx/components/vectorstores/qdrant.py +0 -109
  60. lfx/components/vectorstores/supabase.py +0 -76
  61. lfx/components/vectorstores/upstash.py +0 -124
  62. lfx/components/vectorstores/vectara.py +0 -97
  63. lfx/components/vectorstores/vectara_rag.py +0 -164
  64. lfx/components/vectorstores/weaviate.py +0 -89
  65. /lfx/components/datastax/{astra_vectorize.py → astradb_vectorize.py} +0 -0
  66. {lfx_nightly-0.1.13.dev2.dist-info → lfx_nightly-0.1.13.dev4.dist-info}/WHEEL +0 -0
  67. {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
- lc_message.content = [item for item in lc_message.content if item.get("type") != "image"]
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
- return [value.to_lc_message() for value in data]
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__._actions_cache:
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__._actions_cache[toolkit_slug])
410
- self._action_schemas = copy.deepcopy(self.__class__._action_schema_cache.get(toolkit_slug, {}))
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__._actions_cache[toolkit_slug] = copy.deepcopy(self._actions_data)
634
- self.__class__._action_schema_cache[toolkit_slug] = copy.deepcopy(self._action_schemas)
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__._all_auth_field_names.add(name)
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__._all_auth_field_names.add(name)
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__._actions_cache
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__._all_auth_field_names)
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:
@@ -0,0 +1,5 @@
1
+ from .astradb_base import AstraDBBaseComponent
2
+
3
+ __all__ = [
4
+ "AstraDBBaseComponent",
5
+ ]