lfx-nightly 0.1.12.dev33__py3-none-any.whl → 0.1.12.dev35__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.

@@ -1548,7 +1548,16 @@ class Component(CustomComponent):
1548
1548
  if not message.sender_name:
1549
1549
  message.sender_name = MESSAGE_SENDER_NAME_AI
1550
1550
 
1551
- async def send_message(self, message: Message, id_: str | None = None):
1551
+ async def send_message(self, message: Message, id_: str | None = None, *, skip_db_update: bool = False):
1552
+ """Send a message with optional database update control.
1553
+
1554
+ Args:
1555
+ message: The message to send
1556
+ id_: Optional message ID
1557
+ skip_db_update: If True, only update in-memory and send event, skip DB write.
1558
+ Useful during streaming to avoid excessive DB round-trips.
1559
+ Note: This assumes the message already exists in the database with message.id set.
1560
+ """
1552
1561
  if self._should_skip_message(message):
1553
1562
  return message
1554
1563
 
@@ -1558,26 +1567,37 @@ class Component(CustomComponent):
1558
1567
  # Ensure required fields for message storage are set
1559
1568
  self._ensure_message_required_fields(message)
1560
1569
 
1561
- stored_message = await self._store_message(message)
1570
+ # If skip_db_update is True and message already has an ID, skip the DB write
1571
+ # This path is used during agent streaming to avoid excessive DB round-trips
1572
+ if skip_db_update and message.id:
1573
+ # Create a fresh Message instance for consistency with normal flow
1574
+ stored_message = await Message.create(**message.model_dump())
1575
+ self._stored_message_id = stored_message.id
1576
+ # Still send the event to update the client in real-time
1577
+ # Note: If this fails, we don't need DB cleanup since we didn't write to DB
1578
+ await self._send_message_event(stored_message, id_=id_)
1579
+ else:
1580
+ # Normal flow: store/update in database
1581
+ stored_message = await self._store_message(message)
1562
1582
 
1563
- self._stored_message_id = stored_message.id
1564
- try:
1565
- complete_message = ""
1566
- if (
1567
- self._should_stream_message(stored_message, message)
1568
- and message is not None
1569
- and isinstance(message.text, AsyncIterator | Iterator)
1570
- ):
1571
- complete_message = await self._stream_message(message.text, stored_message)
1572
- stored_message.text = complete_message
1573
- stored_message = await self._update_stored_message(stored_message)
1574
- else:
1575
- # Only send message event for non-streaming messages
1576
- await self._send_message_event(stored_message, id_=id_)
1577
- except Exception:
1578
- # remove the message from the database
1579
- await delete_message(stored_message.id)
1580
- raise
1583
+ self._stored_message_id = stored_message.id
1584
+ try:
1585
+ complete_message = ""
1586
+ if (
1587
+ self._should_stream_message(stored_message, message)
1588
+ and message is not None
1589
+ and isinstance(message.text, AsyncIterator | Iterator)
1590
+ ):
1591
+ complete_message = await self._stream_message(message.text, stored_message)
1592
+ stored_message.text = complete_message
1593
+ stored_message = await self._update_stored_message(stored_message)
1594
+ else:
1595
+ # Only send message event for non-streaming messages
1596
+ await self._send_message_event(stored_message, id_=id_)
1597
+ except Exception:
1598
+ # remove the message from the database
1599
+ await delete_message(stored_message.id)
1600
+ raise
1581
1601
  self.status = stored_message
1582
1602
  return stored_message
1583
1603
 
@@ -12,7 +12,7 @@ from pydantic import BaseModel
12
12
 
13
13
  from lfx.custom import validate
14
14
  from lfx.custom.custom_component.base_component import BaseComponent
15
- from lfx.helpers.flow import list_flows, load_flow, run_flow
15
+ from lfx.helpers import list_flows, load_flow, run_flow
16
16
  from lfx.log.logger import logger
17
17
  from lfx.schema.data import Data
18
18
  from lfx.services.deps import get_storage_service, get_variable_service, session_scope
@@ -161,7 +161,7 @@ class ParameterHandler:
161
161
  elif field.get("required"):
162
162
  field_display_name = field.get("display_name")
163
163
  logger.warning(
164
- "File path not found for {} in component {}. Setting to None.",
164
+ "File path not found for %s in component %s. Setting to None.",
165
165
  field_display_name,
166
166
  self.vertex.display_name,
167
167
  )
@@ -255,7 +255,7 @@ class ParameterHandler:
255
255
  else:
256
256
  params[field_name] = ast.literal_eval(val) if val else None
257
257
  except Exception: # noqa: BLE001
258
- logger.debug("Error evaluating code for {}", field_name)
258
+ logger.debug("Error evaluating code for %s", field_name)
259
259
  params[field_name] = val
260
260
  return params
261
261
 
lfx/helpers/__init__.py CHANGED
@@ -1 +1,129 @@
1
- """Helpers module for lfx package."""
1
+ """Helpers module for the lfx package.
2
+
3
+ This module automatically chooses between the full langflow implementation
4
+ (when available) and the lfx implementation (when standalone).
5
+ """
6
+
7
+ from lfx.utils.langflow_utils import has_langflow_memory
8
+
9
+ # Import the appropriate implementation
10
+ if has_langflow_memory():
11
+ try:
12
+ # Import full langflow implementation
13
+ # Base Model
14
+ from langflow.helpers.base_model import (
15
+ BaseModel,
16
+ SchemaField,
17
+ build_model_from_schema,
18
+ coalesce_bool,
19
+ )
20
+
21
+ # Custom
22
+ from langflow.helpers.custom import (
23
+ format_type,
24
+ )
25
+
26
+ # Data
27
+ from langflow.helpers.data import (
28
+ clean_string,
29
+ data_to_text,
30
+ data_to_text_list,
31
+ docs_to_data,
32
+ safe_convert,
33
+ )
34
+
35
+ # Flow
36
+ from langflow.helpers.flow import (
37
+ build_schema_from_inputs,
38
+ get_arg_names,
39
+ get_flow_inputs,
40
+ list_flows,
41
+ load_flow,
42
+ run_flow,
43
+ )
44
+ except ImportError:
45
+ # Fallback to lfx implementation if langflow import fails
46
+ # Base Model
47
+ from lfx.helpers.base_model import (
48
+ BaseModel,
49
+ SchemaField,
50
+ build_model_from_schema,
51
+ coalesce_bool,
52
+ )
53
+
54
+ # Custom
55
+ from lfx.helpers.custom import (
56
+ format_type,
57
+ )
58
+
59
+ # Data
60
+ from lfx.helpers.data import (
61
+ clean_string,
62
+ data_to_text,
63
+ data_to_text_list,
64
+ docs_to_data,
65
+ safe_convert,
66
+ )
67
+
68
+ # Flow
69
+ from lfx.helpers.flow import (
70
+ build_schema_from_inputs,
71
+ get_arg_names,
72
+ get_flow_inputs,
73
+ list_flows,
74
+ load_flow,
75
+ run_flow,
76
+ )
77
+ else:
78
+ # Use lfx implementation
79
+ # Base Model
80
+ from lfx.helpers.base_model import (
81
+ BaseModel,
82
+ SchemaField,
83
+ build_model_from_schema,
84
+ coalesce_bool,
85
+ )
86
+
87
+ # Custom
88
+ from lfx.helpers.custom import (
89
+ format_type,
90
+ )
91
+
92
+ # Data
93
+ from lfx.helpers.data import (
94
+ clean_string,
95
+ data_to_text,
96
+ data_to_text_list,
97
+ docs_to_data,
98
+ safe_convert,
99
+ )
100
+
101
+ # Flow
102
+ from lfx.helpers.flow import (
103
+ build_schema_from_inputs,
104
+ get_arg_names,
105
+ get_flow_inputs,
106
+ list_flows,
107
+ load_flow,
108
+ run_flow,
109
+ )
110
+
111
+ # Export the available functions
112
+ __all__ = [
113
+ "BaseModel",
114
+ "SchemaField",
115
+ "build_model_from_schema",
116
+ "build_schema_from_inputs",
117
+ "clean_string",
118
+ "coalesce_bool",
119
+ "data_to_text",
120
+ "data_to_text_list",
121
+ "docs_to_data",
122
+ "format_type",
123
+ "get_arg_names",
124
+ "get_flow_inputs",
125
+ "list_flows",
126
+ "load_flow",
127
+ "run_flow",
128
+ "safe_convert",
129
+ ]
lfx/helpers/flow.py CHANGED
@@ -189,6 +189,3 @@ async def run_flow(
189
189
  types=types,
190
190
  fallback_to_env_vars=fallback_to_env_vars,
191
191
  )
192
-
193
-
194
- __all__ = ["build_schema_from_inputs", "get_arg_names", "get_flow_inputs", "list_flows", "load_flow", "run_flow"]
lfx/inputs/input_mixin.py CHANGED
@@ -12,6 +12,7 @@ from pydantic import (
12
12
 
13
13
  from lfx.field_typing.range_spec import RangeSpec
14
14
  from lfx.inputs.validators import CoalesceBool
15
+ from lfx.schema.cross_module import CrossModuleModel
15
16
 
16
17
 
17
18
  class FieldTypes(str, Enum):
@@ -42,7 +43,7 @@ SerializableFieldTypes = Annotated[FieldTypes, PlainSerializer(lambda v: v.value
42
43
 
43
44
 
44
45
  # Base mixin for common input field attributes and methods
45
- class BaseInputMixin(BaseModel, validate_assignment=True): # type: ignore[call-arg]
46
+ class BaseInputMixin(CrossModuleModel, validate_assignment=True): # type: ignore[call-arg]
46
47
  model_config = ConfigDict(
47
48
  arbitrary_types_allowed=True,
48
49
  extra="forbid",
lfx/inputs/inputs.py CHANGED
@@ -190,24 +190,15 @@ class MessageInput(StrInput, InputTraceMixin):
190
190
  # If v is a instance of Message, then its fine
191
191
  if isinstance(v, dict):
192
192
  return Message(**v)
193
+ # Duck-typed Message check - works across module boundaries
193
194
  if isinstance(v, Message):
195
+ # If it's from a different module (e.g., langflow.schema.Message),
196
+ # convert it to ensure we have the right type
197
+ if type(v).__module__ != Message.__module__:
198
+ return Message(**v.model_dump())
194
199
  return v
195
- # Check for Message-like objects by examining their fields
196
- # This handles both langflow and lfx Message instances
197
- if hasattr(v, "text") and hasattr(v, "model_dump") and callable(v.model_dump):
198
- # Check if it has other Message-specific attributes
199
- message_fields = {"text", "data", "sender", "session_id", "properties"}
200
- obj_attrs = set(dir(v))
201
- min_message_fields = 3
202
- if len(message_fields.intersection(obj_attrs)) >= min_message_fields:
203
- try:
204
- return Message(**v.model_dump())
205
- except (TypeError, ValueError):
206
- # Fallback to text only if model_dump fails
207
- return Message(text=v.text)
208
200
  if isinstance(v, str | AsyncIterator | Iterator):
209
201
  return Message(text=v)
210
- # For simplified implementation, we'll skip MessageBase handling
211
202
  msg = f"Invalid value type {type(v)}"
212
203
  raise ValueError(msg)
213
204
 
@@ -95,8 +95,10 @@ def _process_single_module(modname: str) -> tuple[str, dict] | None:
95
95
  """
96
96
  try:
97
97
  module = importlib.import_module(modname)
98
- except (ImportError, AttributeError) as e:
99
- logger.error(f"Error importing module {modname}: {e}", exc_info=True)
98
+ except Exception as e: # noqa: BLE001
99
+ # Catch all exceptions during import to prevent component failures from crashing startup
100
+ # TODO: Surface these errors to the UI in a friendly manner
101
+ logger.error(f"Failed to import module {modname}: {e}", exc_info=True)
100
102
  return None
101
103
  # Extract the top-level subpackage name after "langflow.components."
102
104
  # e.g., "langflow.components.Notion.add_content_to_page" -> "Notion"
lfx/log/logger.py CHANGED
@@ -209,6 +209,7 @@ def configure(
209
209
  log_format: str | None = None,
210
210
  log_rotation: str | None = None,
211
211
  cache: bool | None = None,
212
+ output_file=None,
212
213
  ) -> None:
213
214
  """Configure the logger."""
214
215
  # Early-exit only if structlog is configured AND current min level matches the requested one.
@@ -297,11 +298,14 @@ def configure(
297
298
  wrapper_class.min_level = numeric_level
298
299
 
299
300
  # Configure structlog
301
+ # Default to stdout for backward compatibility, unless output_file is specified
302
+ log_output_file = output_file if output_file is not None else sys.stdout
303
+
300
304
  structlog.configure(
301
305
  processors=processors,
302
306
  wrapper_class=wrapper_class,
303
307
  context_class=dict,
304
- logger_factory=structlog.PrintLoggerFactory(file=sys.stdout)
308
+ logger_factory=structlog.PrintLoggerFactory(file=log_output_file)
305
309
  if not log_file
306
310
  else structlog.stdlib.LoggerFactory(),
307
311
  cache_logger_on_first_use=cache if cache is not None else True,
lfx/memory/__init__.py CHANGED
@@ -1,35 +1,15 @@
1
1
  """Memory management for lfx with dynamic loading.
2
2
 
3
- This module automatically chooses between full langflow implementations
4
- (when available) and lfx stub implementations (when standalone).
3
+ This module automatically chooses between the full langflow implementation
4
+ (when available) and the lfx implementation (when standalone).
5
5
  """
6
6
 
7
- import importlib.util
7
+ from lfx.utils.langflow_utils import has_langflow_memory
8
8
 
9
- from lfx.log.logger import logger
10
-
11
-
12
- def _has_langflow_memory():
13
- """Check if langflow.memory with database support is available."""
14
- try:
15
- # Check if langflow.memory and MessageTable are available
16
- return importlib.util.find_spec("langflow") is not None
17
- except (ImportError, ModuleNotFoundError):
18
- pass
19
- except Exception as e: # noqa: BLE001
20
- logger.error(f"Error checking for langflow.memory: {e}")
21
- return False
22
-
23
-
24
- #### TODO: This _LANGFLOW_AVAILABLE implementation should be changed later ####
25
- # Consider refactoring to lazy loading or a more robust service discovery mechanism
26
- # that can handle runtime availability changes.
27
- _LANGFLOW_AVAILABLE = _has_langflow_memory()
28
-
29
- # Import the appropriate implementations
30
- if _LANGFLOW_AVAILABLE:
9
+ # Import the appropriate implementation
10
+ if has_langflow_memory():
31
11
  try:
32
- # Import from full langflow implementation
12
+ # Import full langflow implementation
33
13
  from langflow.memory import (
34
14
  aadd_messages,
35
15
  aadd_messagetables,
@@ -43,8 +23,8 @@ if _LANGFLOW_AVAILABLE:
43
23
  get_messages,
44
24
  store_message,
45
25
  )
46
- except (ImportError, ModuleNotFoundError):
47
- # Fall back to stubs if langflow import fails
26
+ except ImportError:
27
+ # Fallback to lfx implementation if langflow import fails
48
28
  from lfx.memory.stubs import (
49
29
  aadd_messages,
50
30
  aadd_messagetables,
@@ -59,7 +39,7 @@ if _LANGFLOW_AVAILABLE:
59
39
  store_message,
60
40
  )
61
41
  else:
62
- # Use lfx stub implementations
42
+ # Use lfx implementation
63
43
  from lfx.memory.stubs import (
64
44
  aadd_messages,
65
45
  aadd_messagetables,
@@ -74,7 +54,7 @@ else:
74
54
  store_message,
75
55
  )
76
56
 
77
- # Export the available functions and classes
57
+ # Export the available functions
78
58
  __all__ = [
79
59
  "aadd_messages",
80
60
  "aadd_messagetables",
@@ -0,0 +1,80 @@
1
+ """Cross-module BaseModel for handling re-exported classes.
2
+
3
+ This module provides a metaclass and base model that enable isinstance checks
4
+ to work across module boundaries for Pydantic models. This is particularly useful
5
+ when the same class is re-exported from different modules (e.g., lfx.Message vs
6
+ langflow.schema.Message) but Python's isinstance() checks fail due to different
7
+ module paths.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from typing import Any
13
+
14
+ from pydantic import BaseModel
15
+
16
+
17
+ class CrossModuleMeta(type(BaseModel)): # type: ignore[misc]
18
+ """Metaclass that enables cross-module isinstance checks for Pydantic models.
19
+
20
+ This metaclass overrides __instancecheck__ to perform structural type checking
21
+ based on the model's fields rather than strict class identity. This allows
22
+ instances of the same model from different module paths to be recognized as
23
+ compatible.
24
+ """
25
+
26
+ def __instancecheck__(cls, instance: Any) -> bool:
27
+ """Check if instance is compatible with this class across module boundaries.
28
+
29
+ First performs a standard isinstance check. If that fails, falls back to
30
+ checking if the instance has all required Pydantic model attributes and
31
+ a compatible set of model fields.
32
+
33
+ Args:
34
+ instance: The object to check.
35
+
36
+ Returns:
37
+ bool: True if instance is compatible with this class.
38
+ """
39
+ # First try standard isinstance check
40
+ if type.__instancecheck__(cls, instance):
41
+ return True
42
+
43
+ # If that fails, check for cross-module compatibility
44
+ # An object is cross-module compatible if it:
45
+ # 1. Has model_fields attribute (is a Pydantic model)
46
+ # 2. Has the same __class__.__name__
47
+ # 3. Has compatible model fields
48
+ if not hasattr(instance, "model_fields"):
49
+ return False
50
+
51
+ # Check if class names match
52
+ if instance.__class__.__name__ != cls.__name__:
53
+ return False
54
+
55
+ # Check if the instance has all required fields from cls
56
+ cls_fields = set(cls.model_fields.keys()) if hasattr(cls, "model_fields") else set()
57
+ instance_fields = set(instance.model_fields.keys())
58
+
59
+ # The instance must have at least the same fields as the class
60
+ # (it can have more, but not fewer required fields)
61
+ return cls_fields.issubset(instance_fields)
62
+
63
+
64
+ class CrossModuleModel(BaseModel, metaclass=CrossModuleMeta):
65
+ """Base Pydantic model with cross-module isinstance support.
66
+
67
+ This class should be used as the base for models that may be re-exported
68
+ from different modules. It enables isinstance() checks to work across
69
+ module boundaries by using structural type checking.
70
+
71
+ Example:
72
+ >>> class Message(CrossModuleModel):
73
+ ... text: str
74
+ ...
75
+ >>> # Even if Message is imported from different paths:
76
+ >>> from lfx.schema.message import Message as LfxMessage
77
+ >>> from langflow.schema import Message as LangflowMessage
78
+ >>> msg = LfxMessage(text="hello")
79
+ >>> isinstance(msg, LangflowMessage) # True (with cross-module support)
80
+ """
lfx/schema/data.py CHANGED
@@ -14,6 +14,7 @@ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
14
14
  from pydantic import BaseModel, ConfigDict, model_serializer, model_validator
15
15
 
16
16
  from lfx.log.logger import logger
17
+ from lfx.schema.cross_module import CrossModuleModel
17
18
  from lfx.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER
18
19
  from lfx.utils.image import create_image_content_dict
19
20
 
@@ -22,7 +23,7 @@ if TYPE_CHECKING:
22
23
  from lfx.schema.message import Message
23
24
 
24
25
 
25
- class Data(BaseModel):
26
+ class Data(CrossModuleModel):
26
27
  """Represents a record with text and optional data.
27
28
 
28
29
  Attributes:
lfx/schema/log.py CHANGED
@@ -34,6 +34,7 @@ class SendMessageFunctionType(Protocol):
34
34
  id_: str | None = None,
35
35
  *,
36
36
  allow_markdown: bool = True,
37
+ skip_db_update: bool = False,
37
38
  ) -> Message: ...
38
39
 
39
40
 
lfx/schema/message.py CHANGED
@@ -121,9 +121,13 @@ class Message(Data):
121
121
 
122
122
  def to_lc_message(
123
123
  self,
124
+ model_name: str | None = None,
124
125
  ) -> BaseMessage:
125
126
  """Converts the Data to a BaseMessage.
126
127
 
128
+ Args:
129
+ model_name: The model name to use for conversion. Optional.
130
+
127
131
  Returns:
128
132
  BaseMessage: The converted BaseMessage.
129
133
  """
@@ -139,7 +143,7 @@ class Message(Data):
139
143
  if self.sender == MESSAGE_SENDER_USER or not self.sender:
140
144
  if self.files:
141
145
  contents = [{"type": "text", "text": text}]
142
- file_contents = self.get_file_content_dicts()
146
+ file_contents = self.get_file_content_dicts(model_name)
143
147
  contents.extend(file_contents)
144
148
  human_message = HumanMessage(content=contents)
145
149
  else:
@@ -197,7 +201,7 @@ class Message(Data):
197
201
  return value
198
202
 
199
203
  # Keep this async method for backwards compatibility
200
- def get_file_content_dicts(self):
204
+ def get_file_content_dicts(self, model_name: str | None = None):
201
205
  content_dicts = []
202
206
  try:
203
207
  files = get_file_paths(self.files)
@@ -209,7 +213,7 @@ class Message(Data):
209
213
  if isinstance(file, Image):
210
214
  content_dicts.append(file.to_content_dict())
211
215
  else:
212
- content_dicts.append(create_image_content_dict(file))
216
+ content_dicts.append(create_image_content_dict(file, None, model_name))
213
217
  return content_dicts
214
218
 
215
219
  def load_lc_prompt(self):
lfx/utils/image.py CHANGED
@@ -56,12 +56,15 @@ def create_data_url(image_path: str | Path, mime_type: str | None = None) -> str
56
56
 
57
57
 
58
58
  @lru_cache(maxsize=50)
59
- def create_image_content_dict(image_path: str | Path, mime_type: str | None = None) -> dict:
59
+ def create_image_content_dict(
60
+ image_path: str | Path, mime_type: str | None = None, model_name: str | None = None
61
+ ) -> dict:
60
62
  """Create a content dictionary for multimodal inputs from an image file.
61
63
 
62
64
  Args:
63
65
  image_path: Path to the image file
64
66
  mime_type: MIME type of the image. If None, will be auto-detected
67
+ model_name: Optional model parameter to determine content dict structure
65
68
 
66
69
  Returns:
67
70
  Content dictionary with type and image_url fields
@@ -70,4 +73,7 @@ def create_image_content_dict(image_path: str | Path, mime_type: str | None = No
70
73
  FileNotFoundError: If the image file doesn't exist
71
74
  """
72
75
  data_url = create_data_url(image_path, mime_type)
76
+
77
+ if model_name == "OllamaModel":
78
+ return {"type": "image_url", "source_type": "url", "image_url": data_url}
73
79
  return {"type": "image", "source_type": "url", "url": data_url}
@@ -0,0 +1,52 @@
1
+ """Langflow environment utility functions."""
2
+
3
+ import importlib.util
4
+
5
+ from lfx.log.logger import logger
6
+
7
+
8
+ class _LangflowModule:
9
+ # Static variable
10
+ # Tri-state:
11
+ # - None: Langflow check not performed yet
12
+ # - True: Langflow is available
13
+ # - False: Langflow is not available
14
+ _available = None
15
+
16
+ @classmethod
17
+ def is_available(cls):
18
+ return cls._available
19
+
20
+ @classmethod
21
+ def set_available(cls, value):
22
+ cls._available = value
23
+
24
+
25
+ def has_langflow_memory():
26
+ """Check if langflow.memory (with database support) and MessageTable are available."""
27
+ # TODO: REVISIT: Optimize this implementation later
28
+ # - Consider refactoring to use lazy loading or a more robust service discovery mechanism
29
+ # that can handle runtime availability changes.
30
+
31
+ # Use cached check from previous invocation (if applicable)
32
+
33
+ is_langflow_available = _LangflowModule.is_available()
34
+
35
+ if is_langflow_available is not None:
36
+ return is_langflow_available
37
+
38
+ # First check (lazy load and cache check)
39
+
40
+ module_spec = None
41
+
42
+ try:
43
+ module_spec = importlib.util.find_spec("langflow")
44
+ except ImportError:
45
+ pass
46
+ except (TypeError, ValueError) as e:
47
+ logger.error(f"Error encountered checking for langflow.memory: {e}")
48
+
49
+ is_langflow_available = module_spec is not None
50
+ _LangflowModule.set_available(is_langflow_available)
51
+
52
+ return is_langflow_available
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lfx-nightly
3
- Version: 0.1.12.dev33
3
+ Version: 0.1.12.dev35
4
4
  Summary: Langflow Executor - A lightweight CLI tool for executing and serving Langflow AI flows
5
5
  Author-email: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
6
6
  Requires-Python: <3.14,>=3.10