From 933198d8be0bcc2539b6ef4aeb235b62742f56b4 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Mon, 25 Aug 2025 20:32:44 -0300 Subject: [PATCH] feat: add static dependency analysis module and update metadata handling (#9192) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add dependency analysis utilities for custom components - Introduced `dependency_analyzer.py` to analyze and classify dependencies in Python code. - Implemented functions to extract import information and categorize dependencies as standard library, local, or external. - Enhanced `build_component_metadata` to include dependency analysis results in component metadata. - Added unit tests to validate the functionality of the dependency analysis features. * refactor: streamline dependency analysis by filtering out stdlib and local imports - Updated `dependency_analyzer.py` to focus on external dependencies only, removing standard library and local imports from analysis results. - Simplified the `DependencyInfo` class by eliminating unnecessary attributes and adjusting the deduplication logic. - Modified `build_component_metadata` to reflect changes in dependency structure, removing counts for stdlib and local dependencies. - Enhanced unit tests to validate the new filtering behavior and ensure no duplicates in external dependencies. * feat: update starter project metadata with dependency information - Added dependency sections to multiple starter project JSON files, specifying required packages and their versions. - Included `langflow` version `1.5.0.post1` and other relevant dependencies such as `orjson`, `fastapi`, and `pydantic` across various projects. - Enhanced project metadata to improve clarity on external dependencies for better maintainability and user guidance. * ⚡️ Speed up function `_classify_dependency` by 7,582% in PR #9192 (`add-deps-metadata`) (#9193) Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> * fix: ensure distribution version is returned correctly in `_get_distribution_version` - Updated `_get_distribution_version` function to return the distribution version after successfully retrieving it, addressing a potential issue where `None` could be returned prematurely. * fix: improve distribution version lookup in `_get_distribution_version` * fix: handle distribution version lookup exceptions more gracefully * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes * [autofix.ci] apply automated fixes (attempt 2/3) * fix(apply_tweaks): skip tweaks to code field and log warning (#9467) * fix: add security warning for overriding code field in tweaks * test: add tests for preventing code field overrides in tweaks * ref: Refactor vectorstore components structure (#9486) * Refactor vectorstore components structure Moved vectorstore components for Chroma, ClickHouse, Couchbase, DataStax, Elastic, Milvus, MongoDB, Pinecone, Qdrant, Supabase, Upstash, Vectara, and Weaviate into dedicated subfolders with __init__.py files for each. Updated Redis vectorstore implementation to reside in redis.py and removed the old vectorstores/redis.py. Adjusted starter project JSONs and frontend constants to reflect new module paths and sidebar entries for these vectorstores. * Refactor vectorstore components and add lazy imports Moved Datastax-related files from vectorstores to a dedicated datastax directory. Added lazy import logic to __init__.py files for chroma, clickhouse, couchbase, elastic, milvus, mongodb, pinecone, qdrant, supabase, upstash, vectara, and weaviate components. Cleaned up vectorstores/__init__.py to only include local and faiss components, improving modularity and import efficiency. * [autofix.ci] apply automated fixes * Refactor vectorstore components structure Moved FAISS, Cassandra, and pgvector components to dedicated subdirectories with lazy-loading __init__.py files. Updated imports and references throughout the backend and frontend to reflect new locations. Removed obsolete datastax Cassandra component. Added new sidebar bundle entries for FAISS, Cassandra, and pgvector in frontend constants and style utilities. * Add lazy imports and Redis chat memory component Refactored the Redis module to support lazy imports for RedisIndexChatMemory and RedisVectorStoreComponent, improving import efficiency. Added a new redis_chat.py file implementing RedisIndexChatMemory for chat message storage and retrieval using Redis. * Fix vector store astra imports * Revert package lock changes * More test fixes * Update test_vector_store_rag.py * Update test_dynamic_imports.py * Update vector_store_rag.py * Update test_dynamic_imports.py * Refactor the cassandra chat component * Fix frontend tests for bundle * Mark Local DB as legacy * Update inputComponent.spec.ts * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Eric Hare Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com> * feat: add dependencies metadata to starter projects * feat: add caching for packages_distributions to improve performance * refactor: update test descriptions and remove unused imports in metadata tests --------- Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Edwin Jose Co-authored-by: Eric Hare Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com> --- .../langflow/custom/dependency_analyzer.py | 165 ++++++++ src/backend/base/langflow/custom/utils.py | 50 ++- .../Basic Prompt Chaining.json | 26 ++ .../starter_projects/Basic Prompting.json | 26 ++ .../starter_projects/Blog Writer.json | 56 +++ .../Custom Component Generator.json | 35 ++ .../starter_projects/Document Q&A.json | 26 ++ .../Financial Report Parser.json | 43 ++ .../starter_projects/Hybrid Search RAG.json | 82 ++++ .../Image Sentiment Analysis.json | 43 ++ .../Instagram Copywriter.json | 48 +++ .../starter_projects/Invoice Summarizer.json | 39 ++ .../starter_projects/Knowledge Ingestion.json | 71 ++++ .../starter_projects/Knowledge Retrieval.json | 63 +++ .../starter_projects/Market Research.json | 56 +++ .../starter_projects/Meeting Summary.json | 95 +++++ .../starter_projects/Memory Chatbot.json | 35 ++ .../starter_projects/News Aggregator.json | 60 +++ .../starter_projects/Nvidia Remix.json | 65 +++ .../starter_projects/Pokédex Agent.json | 47 +++ .../Portfolio Website Code Generator.json | 43 ++ .../starter_projects/Price Deal Finder.json | 52 +++ .../starter_projects/Research Agent.json | 39 ++ .../Research Translation Loop.json | 66 ++++ .../SEO Keyword Generator.json | 17 + .../starter_projects/SaaS Pricing.json | 26 ++ .../starter_projects/Search agent.json | 39 ++ .../Sequential Tasks Agents.json | 69 ++++ .../starter_projects/Simple Agent.json | 56 +++ .../starter_projects/Social Media Agent.json | 76 ++++ .../Text Sentiment Analysis.json | 34 ++ .../Travel Planning Agents.json | 48 +++ .../Twitter Thread Generator.json | 80 ++++ .../starter_projects/Vector Store RAG.json | 107 +++++ .../starter_projects/Youtube Analysis.json | 81 ++++ .../tests/unit/custom/test_utils_metadata.py | 370 +++++++++++++++++- 36 files changed, 2311 insertions(+), 23 deletions(-) create mode 100644 src/backend/base/langflow/custom/dependency_analyzer.py diff --git a/src/backend/base/langflow/custom/dependency_analyzer.py b/src/backend/base/langflow/custom/dependency_analyzer.py new file mode 100644 index 000000000..1b418ecf5 --- /dev/null +++ b/src/backend/base/langflow/custom/dependency_analyzer.py @@ -0,0 +1,165 @@ +"""Dependency analysis utilities for custom components.""" + +from __future__ import annotations + +import ast +import importlib.metadata as md +import sys +from dataclasses import asdict, dataclass +from functools import lru_cache + +try: + STDLIB_MODULES: set[str] = set(sys.stdlib_module_names) # 3.10+ +except AttributeError: + # Fallback heuristic if running on <3.10 + STDLIB_MODULES = set(sys.builtin_module_names) + + +@dataclass(frozen=True) +class DependencyInfo: + """Information about a dependency imported in Python code.""" + + name: str # package name (e.g. "numpy", "requests") + version: str | None # package version if available + is_local: bool # True for relative imports (from .module import ...) + + +def _top_level(pkg: str) -> str: + """Extract top-level package name.""" + return pkg.split(".", 1)[0] + + +def _is_relative(module: str | None) -> bool: + """Check if module is a relative import.""" + return module is not None and module.startswith(".") + + +class _ImportVisitor(ast.NodeVisitor): + """AST visitor to extract import information.""" + + def __init__(self): + self.results: list[DependencyInfo] = [] + + def visit_Import(self, node: ast.Import): + for alias in node.names: + full = alias.name + dep = DependencyInfo( + name=_top_level(full), + version=None, + is_local=False, # Regular imports are not local + ) + self.results.append(dep) + + def visit_ImportFrom(self, node: ast.ImportFrom): + # Reconstruct full module name with proper relative import handling + if node.level > 0: + # Relative import: from .module import x or from ..parent import x + dots = "." * node.level + full_module = dots + (node.module or "") + else: + # Absolute import: from module import x + full_module = node.module or "" + for _alias in node.names: + dep = DependencyInfo( + name=_top_level(full_module.lstrip(".")) if full_module else "", + version=None, + is_local=_is_relative(full_module), # Check if it's a relative import + ) + self.results.append(dep) + + +def _classify_dependency(dep: DependencyInfo) -> DependencyInfo: + """Resolve version information for external dependencies.""" + version = None + if not dep.is_local and dep.name: + version = _get_distribution_version(dep.name) + + return DependencyInfo( + name=dep.name, + version=version, + is_local=dep.is_local, + ) + + +def analyze_dependencies(source: str, *, resolve_versions: bool = True) -> list[dict]: + """Return a list[dict] of dependencies imported by the given Python source code. + + Args: + source: Python source code string + resolve_versions: Whether to resolve version information + + Returns: + List of dependency dictionaries + """ + code = source + + # Parse the code and extract imports + tree = ast.parse(code) + visitor = _ImportVisitor() + visitor.visit(tree) + + # Process and deduplicate dependencies by package name only + unique_packages: dict[str, DependencyInfo] = {} + for raw_dep in visitor.results: + processed_dep = _classify_dependency(raw_dep) if resolve_versions else raw_dep + + # Skip stdlib imports and local imports - we only care about external dependencies + if processed_dep.name in STDLIB_MODULES or processed_dep.is_local: + continue + + # Deduplicate by package name only (not full_module) + if processed_dep.name not in unique_packages: + unique_packages[processed_dep.name] = processed_dep + + return [asdict(d) for d in unique_packages.values()] + + +def analyze_component_dependencies(component_code: str) -> dict: + """Analyze dependencies for a custom component. + + Args: + component_code: The component's source code + + Returns: + Dictionary with dependency analysis results + """ + try: + deps = analyze_dependencies(component_code, resolve_versions=True) + + return { + "total_dependencies": len(deps), + "dependencies": [{"name": d["name"], "version": d["version"]} for d in deps if d["name"]], + } + except (SyntaxError, TypeError, ValueError, ImportError): + # If analysis fails, return minimal info + return { + "total_dependencies": 0, + "dependencies": [], + } + + +# Cache the expensive packages_distributions() call globally +@lru_cache(maxsize=1) +def _get_packages_distributions(): + """Cache the expensive packages_distributions() call.""" + try: + return md.packages_distributions() + except (OSError, AttributeError, ValueError): + return {} + + +# Helper function to cache version lookups for installed distributions +@lru_cache(maxsize=128) +def _get_distribution_version(import_name: str): + try: + # Reverse-lookup: which distribution(s) provide this importable name? + reverse_map = _get_packages_distributions() + dist_names = reverse_map.get(import_name) + if not dist_names: + return None + + # Take the first matching distribution + dist_name = dist_names[0] + return md.distribution(dist_name).version + except (ImportError, AttributeError, OSError, ValueError): + return None diff --git a/src/backend/base/langflow/custom/utils.py b/src/backend/base/langflow/custom/utils.py index fe08726c4..5d7fcdc85 100644 --- a/src/backend/base/langflow/custom/utils.py +++ b/src/backend/base/langflow/custom/utils.py @@ -1,4 +1,6 @@ # mypy: ignore-errors +from __future__ import annotations + import ast import asyncio import contextlib @@ -7,14 +9,13 @@ import inspect import re import traceback from pathlib import Path -from typing import Any -from uuid import UUID +from typing import TYPE_CHECKING, Any from fastapi import HTTPException from pydantic import BaseModel from langflow.custom.custom_component.component import Component -from langflow.custom.custom_component.custom_component import CustomComponent +from langflow.custom.dependency_analyzer import analyze_component_dependencies from langflow.custom.directory_reader.utils import ( abuild_custom_component_list_from_path, build_custom_component_list_from_path, @@ -32,6 +33,11 @@ from langflow.type_extraction.type_extraction import extract_inner_type from langflow.utils import validate from langflow.utils.util import get_base_classes +if TYPE_CHECKING: + from uuid import UUID + + from langflow.custom.custom_component.custom_component import CustomComponent + def _generate_code_hash(source_code: str, modname: str) -> str: """Generate a hash of the component source code. @@ -488,6 +494,15 @@ def build_custom_component_template_from_inputs( # ! This should be removed when we have a better way to handle this frontend_node.set_base_classes_from_outputs() reorder_fields(frontend_node, cc_instance._get_field_order()) + frontend_node = build_component_metadata(frontend_node, cc_instance, module_name, ctype_name) + + return frontend_node.to_dict(keep_name=False), cc_instance + + +def build_component_metadata( + frontend_node: CustomComponentFrontendNode, custom_component: CustomComponent, module_name: str, ctype_name: str +): + """Build the metadata for a custom component.""" if module_name: frontend_node.metadata["module"] = module_name else: @@ -502,7 +517,19 @@ def build_custom_component_template_from_inputs( except Exception as exc: # noqa: BLE001 logger.debug(f"Error generating code hash for {custom_component.__class__.__name__}", exc_info=exc) - return frontend_node.to_dict(keep_name=False), cc_instance + # Analyze component dependencies + try: + dependency_info = analyze_component_dependencies(custom_component._code) + frontend_node.metadata["dependencies"] = dependency_info + except (SyntaxError, TypeError, ValueError, ImportError) as exc: + logger.warning(f"Failed to analyze dependencies for component {ctype_name}: {exc}") + # Set minimal dependency info on failure + frontend_node.metadata["dependencies"] = { + "total_dependencies": 0, + "dependencies": [], + } + + return frontend_node def build_custom_component_template( @@ -562,18 +589,9 @@ def build_custom_component_template( reorder_fields(frontend_node, custom_instance._get_field_order()) if module_name: - frontend_node.metadata["module"] = module_name - else: - module_name = get_module_name_from_display_name(frontend_node.display_name) - frontend_node.metadata["module"] = f"custom_components.{module_name}" - - # Generate code hash for cache invalidation and debugging - try: - code_hash = _generate_code_hash(custom_component._code, module_name) - if code_hash: - frontend_node.metadata["code_hash"] = code_hash - except Exception as exc: # noqa: BLE001 - logger.debug(f"Error generating code hash for {custom_component.__class__.__name__}", exc_info=exc) + frontend_node = build_component_metadata( + frontend_node, custom_component, module_name, custom_component.__class__.__name__ + ) return frontend_node.to_dict(keep_name=False), custom_instance except Exception as exc: diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json index 1b0332889..dc0761e36 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json @@ -363,6 +363,15 @@ "lf_version": "1.5.0", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -664,6 +673,23 @@ "lf_version": "1.5.0", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json index 1a7089acb..9c68a6283 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json @@ -118,6 +118,15 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -616,6 +625,23 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json index e2b67f1fa..019bf19aa 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json @@ -353,6 +353,15 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], @@ -469,6 +478,23 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], @@ -792,6 +818,15 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "556209520650", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.processing.parser.ParserComponent" }, "minimized": false, @@ -979,6 +1014,27 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "252132357639", + "dependencies": { + "dependencies": [ + { + "name": "requests", + "version": "2.32.4" + }, + { + "name": "bs4", + "version": "4.12.3" + }, + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.data.url.URLComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json index ce52b8b6b..01dcf6bf4 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Generator.json @@ -238,6 +238,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "464cc8b8fdd2", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.helpers.memory.MemoryComponent" }, "output_types": [], @@ -1926,6 +1935,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -2243,6 +2261,23 @@ "legacy": false, "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json b/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json index 3217d3503..0faca6e1a 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json @@ -148,6 +148,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -443,6 +452,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json index a62cbf4d6..e381dd63b 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json @@ -151,6 +151,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -466,6 +483,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -1294,6 +1320,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "ad2a6f4552c0", + "dependencies": { + "dependencies": [ + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "trustcall", + "version": "0.0.39" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.processing.structured_output.StructuredOutputComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json index ed7435015..fa5621569 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json @@ -206,6 +206,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -516,6 +525,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "556209520650", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.processing.parser.ParserComponent" }, "minimized": false, @@ -698,6 +716,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1003,6 +1038,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "556209520650", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.processing.parser.ParserComponent" }, "minimized": false, @@ -1199,6 +1243,27 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "23fbe9daca09", + "dependencies": { + "dependencies": [ + { + "name": "astrapy", + "version": "2.0.1" + }, + { + "name": "langchain_astradb", + "version": "0.6.0" + }, + { + "name": "langchain_core", + "version": "0.3.72" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.datastax.astradb.AstraDBVectorStoreComponent" }, "minimized": false, @@ -2583,6 +2648,23 @@ "legacy": false, "metadata": { "code_hash": "ad2a6f4552c0", + "dependencies": { + "dependencies": [ + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "trustcall", + "version": "0.0.39" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.processing.structured_output.StructuredOutputComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json index 1c7fe85df..82f9b703c 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json @@ -235,6 +235,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -543,6 +552,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], @@ -1010,6 +1036,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "ad2a6f4552c0", + "dependencies": { + "dependencies": [ + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "trustcall", + "version": "0.0.39" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.processing.structured_output.StructuredOutputComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json b/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json index 547a7868c..487a1b246 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json @@ -318,6 +318,15 @@ "lf_version": "1.1.1", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -790,6 +799,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], @@ -1065,6 +1083,23 @@ "legacy": false, "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], @@ -1588,6 +1623,19 @@ "legacy": false, "metadata": { "code_hash": "4c76fb76d395", + "dependencies": { + "dependencies": [ + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.tavily.tavily_search.TavilySearchComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json b/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json index c26627a8f..0ab3acd5d 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json @@ -306,6 +306,23 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -670,6 +687,19 @@ "legacy": false, "metadata": { "code_hash": "57d868cb067b", + "dependencies": { + "dependencies": [ + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.needle.needle.NeedleComponent" }, "minimized": false, @@ -878,6 +908,15 @@ "legacy": false, "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Ingestion.json b/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Ingestion.json index dc0bceffb..4f7194c90 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Ingestion.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Ingestion.json @@ -89,6 +89,19 @@ "lf_version": "1.5.0.post1", "metadata": { "code_hash": "dbf2e9d2319d", + "dependencies": { + "dependencies": [ + { + "name": "langchain_text_splitters", + "version": "0.3.8" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.processing.split_text.SplitTextComponent" }, "minimized": false, @@ -340,6 +353,27 @@ "lf_version": "1.5.0.post1", "metadata": { "code_hash": "252132357639", + "dependencies": { + "dependencies": [ + { + "name": "requests", + "version": "2.32.4" + }, + { + "name": "bs4", + "version": "4.12.3" + }, + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.data.url.URLComponent" }, "minimized": false, @@ -703,6 +737,43 @@ "legacy": false, "metadata": { "code_hash": "6c62063f2c09", + "dependencies": { + "dependencies": [ + { + "name": "pandas", + "version": "2.2.3" + }, + { + "name": "cryptography", + "version": "43.0.3" + }, + { + "name": "langchain_chroma", + "version": "0.1.4" + }, + { + "name": "loguru", + "version": "0.7.3" + }, + { + "name": "langflow", + "version": null + }, + { + "name": "langchain_openai", + "version": "0.3.23" + }, + { + "name": "langchain_huggingface", + "version": "0.3.1" + }, + { + "name": "langchain_cohere", + "version": "0.3.3" + } + ], + "total_dependencies": 8 + }, "module": "langflow.components.data.kb_ingest.KBIngestionComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Retrieval.json b/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Retrieval.json index c83495376..c27915b89 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Retrieval.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Knowledge Retrieval.json @@ -109,6 +109,15 @@ "lf_version": "1.5.0.post1", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "minimized": false, @@ -226,6 +235,23 @@ "lf_version": "1.5.0.post1", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -533,6 +559,43 @@ "legacy": false, "metadata": { "code_hash": "6fcf86be1aca", + "dependencies": { + "dependencies": [ + { + "name": "cryptography", + "version": "43.0.3" + }, + { + "name": "langchain_chroma", + "version": "0.1.4" + }, + { + "name": "loguru", + "version": "0.7.3" + }, + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "langflow", + "version": null + }, + { + "name": "langchain_openai", + "version": "0.3.23" + }, + { + "name": "langchain_huggingface", + "version": "0.3.1" + }, + { + "name": "langchain_cohere", + "version": "0.3.3" + } + ], + "total_dependencies": 8 + }, "module": "langflow.components.data.kb_retrieval.KBRetrievalComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json index ae1a66631..4198ea237 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json @@ -197,6 +197,15 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -498,6 +507,23 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], @@ -840,6 +866,23 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "ad2a6f4552c0", + "dependencies": { + "dependencies": [ + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "trustcall", + "version": "0.0.39" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.processing.structured_output.StructuredOutputComponent" }, "minimized": false, @@ -1191,6 +1234,19 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "4c76fb76d395", + "dependencies": { + "dependencies": [ + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.tavily.tavily_search.TavilySearchComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json b/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json index cdd8fabe3..070d30f80 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json @@ -315,6 +315,19 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "3e67a5940263", + "dependencies": { + "dependencies": [ + { + "name": "assemblyai", + "version": "0.35.1" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.assemblyai.assemblyai_poll_transcript.AssemblyAITranscriptionJobPoller" }, "minimized": false, @@ -627,6 +640,23 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -932,6 +962,23 @@ "lf_version": "1.1.1", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1237,6 +1284,23 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1719,6 +1783,15 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "464cc8b8fdd2", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.helpers.memory.MemoryComponent" }, "minimized": false, @@ -2049,6 +2122,15 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -2467,6 +2549,19 @@ "legacy": false, "metadata": { "code_hash": "03d20eaf49f4", + "dependencies": { + "dependencies": [ + { + "name": "assemblyai", + "version": "0.35.1" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.assemblyai.assemblyai_start_transcript.AssemblyAITranscriptionJobCreator" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json index aaa0b8f57..f78ddd28d 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json @@ -149,6 +149,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -458,6 +467,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], @@ -960,6 +986,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "464cc8b8fdd2", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.helpers.memory.MemoryComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json index 7eb6ef72c..aaf148e12 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json @@ -206,6 +206,19 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "ab828f4cdff2", + "dependencies": { + "dependencies": [ + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.agentql.agentql_api.AgentQL" }, "minimized": false, @@ -562,6 +575,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -904,6 +926,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1209,6 +1248,27 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "1bcc6faaaa62", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "pandas", + "version": "2.2.3" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.processing.save_file.SaveToFileComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json b/src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json index 6f9813090..36925b00e 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json @@ -233,6 +233,15 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -549,6 +558,23 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1890,6 +1916,19 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "93faf11517da", + "dependencies": { + "dependencies": [ + { + "name": "langchain_openai", + "version": "0.3.23" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.models.embedding_model.EmbeddingModelComponent" }, "minimized": false, @@ -2183,6 +2222,19 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "ed38680af3a6", + "dependencies": { + "dependencies": [ + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.FAISS.faiss.FaissVectorStoreComponent" }, "minimized": false, @@ -2519,6 +2571,19 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "bd0c4250c82c", + "dependencies": { + "dependencies": [ + { + "name": "langchain_core", + "version": "0.3.72" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.agents.mcp_component.MCPToolsComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json index 4b73fa372..dd67a71fb 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json @@ -113,6 +113,15 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -430,6 +439,23 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -832,6 +858,27 @@ "legacy": false, "metadata": { "code_hash": "a648ad26f226", + "dependencies": { + "dependencies": [ + { + "name": "aiofiles", + "version": "24.1.0" + }, + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "validators", + "version": "0.34.0" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.data.api_request.APIRequestComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json index 50b759233..5a3c3c4cb 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json @@ -193,6 +193,15 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "minimized": false, @@ -312,6 +321,23 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -767,6 +793,23 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "ad2a6f4552c0", + "dependencies": { + "dependencies": [ + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "trustcall", + "version": "0.0.39" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.processing.structured_output.StructuredOutputComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json b/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json index 5b9106bee..257316984 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json @@ -138,6 +138,15 @@ "lf_version": "1.3.2", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -454,6 +463,23 @@ "lf_version": "1.3.2", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -768,6 +794,19 @@ "lf_version": "1.3.2", "metadata": { "code_hash": "4c76fb76d395", + "dependencies": { + "dependencies": [ + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.tavily.tavily_search.TavilySearchComponent" }, "minimized": false, @@ -1169,6 +1208,19 @@ "lf_version": "1.3.2", "metadata": { "code_hash": "ab828f4cdff2", + "dependencies": { + "dependencies": [ + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.agentql.agentql_api.AgentQL" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json index 20b7fb904..0038bdca0 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json @@ -478,6 +478,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -1259,6 +1268,19 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "4c76fb76d395", + "dependencies": { + "dependencies": [ + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.tavily.tavily_search.TavilySearchComponent" }, "minimized": false, @@ -1660,6 +1682,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json b/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json index 235dda0ec..d26d7e146 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json @@ -229,6 +229,19 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "b61405ff011f", + "dependencies": { + "dependencies": [ + { + "name": "defusedxml", + "version": "0.7.1" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.arxiv.arxiv.ArXivComponent" }, "minimized": false, @@ -390,6 +403,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -701,6 +731,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -1038,6 +1077,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "556209520650", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.processing.parser.ParserComponent" }, "minimized": false, @@ -1213,6 +1261,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "5b234f78c942", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.logic.loop.LoopComponent" }, "minimized": false, @@ -1626,6 +1683,15 @@ "legacy": false, "metadata": { "code_hash": "38e56a852063", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.processing.converter.TypeConverterComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json index 3e4232e42..840652f0d 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json @@ -563,6 +563,23 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], diff --git a/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json b/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json index 21964516c..2212c9be8 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json @@ -371,6 +371,23 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -716,6 +733,15 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "3139fe9e04a5", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.helpers.calculator_core.CalculatorComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json index 1e8db8d87..545e15310 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json @@ -104,6 +104,19 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "99b8b89dc4ca", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + }, + { + "name": "scrapegraph_py", + "version": "1.12.0" + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.scrapegraph.scrapegraph_search_api.ScrapeGraphSearchApi" }, "minimized": false, @@ -278,6 +291,15 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -592,6 +614,23 @@ "lf_version": "1.1.5", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json b/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json index f8b5da348..3894ab506 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json @@ -1911,6 +1911,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -2801,6 +2810,27 @@ "legacy": false, "metadata": { "code_hash": "6e61ed5ad81b", + "dependencies": { + "dependencies": [ + { + "name": "yfinance", + "version": "0.2.50" + }, + { + "name": "langchain_core", + "version": "0.3.72" + }, + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.yahoosearch.yahoo.YfinanceComponent" }, "minimized": false, @@ -3015,6 +3045,15 @@ "legacy": false, "metadata": { "code_hash": "3139fe9e04a5", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.helpers.calculator_core.CalculatorComponent" }, "minimized": false, @@ -3172,6 +3211,19 @@ "legacy": false, "metadata": { "code_hash": "4c76fb76d395", + "dependencies": { + "dependencies": [ + { + "name": "httpx", + "version": "0.27.2" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.tavily.tavily_search.TavilySearchComponent" }, "minimized": false, @@ -3572,6 +3624,23 @@ "legacy": false, "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json index 270338d24..37a35708f 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json @@ -192,6 +192,15 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "3139fe9e04a5", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.helpers.calculator_core.CalculatorComponent" }, "minimized": false, @@ -350,6 +359,15 @@ "legacy": false, "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -668,6 +686,23 @@ "legacy": false, "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1526,6 +1561,27 @@ "legacy": false, "metadata": { "code_hash": "252132357639", + "dependencies": { + "dependencies": [ + { + "name": "requests", + "version": "2.32.4" + }, + { + "name": "bs4", + "version": "4.12.3" + }, + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.data.url.URLComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json index c032d24f6..98e8f5f36 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json @@ -145,6 +145,31 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "233d7ef687d5", + "dependencies": { + "dependencies": [ + { + "name": "apify_client", + "version": "1.11.0" + }, + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langchain_core", + "version": "0.3.72" + }, + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 5 + }, "module": "langflow.components.apify.apify_actor.ApifyActorsComponent" }, "minimized": false, @@ -351,6 +376,31 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "233d7ef687d5", + "dependencies": { + "dependencies": [ + { + "name": "apify_client", + "version": "1.11.0" + }, + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langchain_core", + "version": "0.3.72" + }, + { + "name": "pydantic", + "version": "2.10.6" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 5 + }, "module": "langflow.components.apify.apify_actor.ApifyActorsComponent" }, "minimized": false, @@ -644,6 +694,15 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -959,6 +1018,23 @@ "lf_version": "1.4.2", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json index cb31022ca..b9ba7aed0 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json @@ -714,6 +714,23 @@ "legacy": false, "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1025,6 +1042,23 @@ "legacy": false, "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json b/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json index e522f90df..a492b8d0d 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json @@ -229,6 +229,15 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -530,6 +539,23 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], @@ -1277,6 +1303,15 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "3139fe9e04a5", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.helpers.calculator_core.CalculatorComponent" }, "minimized": false, @@ -1435,6 +1470,19 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "c561e416205b", + "dependencies": { + "dependencies": [ + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.searchapi.search.SearchComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json index d96cc7871..d933f670f 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json @@ -284,6 +284,15 @@ "legacy": false, "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, @@ -596,6 +605,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], @@ -714,6 +732,23 @@ "legacy": false, "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1023,6 +1058,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], @@ -1131,6 +1175,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], @@ -1239,6 +1292,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], @@ -1347,6 +1409,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], @@ -1455,6 +1526,15 @@ "lf_version": "1.0.19.post2", "metadata": { "code_hash": "efdcba3771af", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.text.TextInputComponent" }, "output_types": [], diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index 45dddf829..5a33dbd79 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -321,6 +321,15 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "output_types": [], @@ -795,6 +804,19 @@ "lf_version": "1.1.1", "metadata": { "code_hash": "dbf2e9d2319d", + "dependencies": { + "dependencies": [ + { + "name": "langchain_text_splitters", + "version": "0.3.8" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.processing.split_text.SplitTextComponent" }, "output_types": [], @@ -1084,6 +1106,23 @@ "lf_version": "1.1.1", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "output_types": [], @@ -1401,6 +1440,19 @@ "lf_version": "1.2.0", "metadata": { "code_hash": "2691dee277c9", + "dependencies": { + "dependencies": [ + { + "name": "langchain_openai", + "version": "0.3.23" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.openai.openai.OpenAIEmbeddingsComponent" }, "output_types": [], @@ -1937,6 +1989,19 @@ "lf_version": "1.1.1", "metadata": { "code_hash": "2691dee277c9", + "dependencies": { + "dependencies": [ + { + "name": "langchain_openai", + "version": "0.3.23" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 2 + }, "module": "langflow.components.openai.openai.OpenAIEmbeddingsComponent" }, "output_types": [], @@ -2710,6 +2775,27 @@ "legacy": false, "metadata": { "code_hash": "23fbe9daca09", + "dependencies": { + "dependencies": [ + { + "name": "astrapy", + "version": "2.0.1" + }, + { + "name": "langchain_astradb", + "version": "0.6.0" + }, + { + "name": "langchain_core", + "version": "0.3.72" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.datastax.astradb.AstraDBVectorStoreComponent" }, "minimized": false, @@ -3486,6 +3572,27 @@ "legacy": false, "metadata": { "code_hash": "23fbe9daca09", + "dependencies": { + "dependencies": [ + { + "name": "astrapy", + "version": "2.0.1" + }, + { + "name": "langchain_astradb", + "version": "0.6.0" + }, + { + "name": "langchain_core", + "version": "0.3.72" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.datastax.astradb.AstraDBVectorStoreComponent" }, "minimized": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json index 3c3ede037..86ec392e5 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json @@ -286,6 +286,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "ee50d5005321", + "dependencies": { + "dependencies": [ + { + "name": "toml", + "version": "0.10.2" + }, + { + "name": "langflow", + "version": null + }, + { + "name": "langchain_core", + "version": "0.3.72" + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.processing.batch_run.BatchRunComponent" }, "minimized": false, @@ -504,6 +521,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "aeda2975f4aa", + "dependencies": { + "dependencies": [ + { + "name": "pandas", + "version": "2.2.3" + }, + { + "name": "googleapiclient", + "version": "2.154.0" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.youtube.comments.YouTubeCommentsComponent" }, "minimized": false, @@ -1440,6 +1474,23 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "6f74e04e39d5", + "dependencies": { + "dependencies": [ + { + "name": "orjson", + "version": "3.10.15" + }, + { + "name": "fastapi", + "version": "0.115.13" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 3 + }, "module": "langflow.components.input_output.chat_output.ChatOutput" }, "minimized": true, @@ -1751,6 +1802,27 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "c9f0262ff0b6", + "dependencies": { + "dependencies": [ + { + "name": "pandas", + "version": "2.2.3" + }, + { + "name": "youtube_transcript_api", + "version": "0.6.3" + }, + { + "name": "langchain_community", + "version": "0.3.21" + }, + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 4 + }, "module": "langflow.components.youtube.youtube_transcripts.YouTubeTranscriptsComponent" }, "minimized": false, @@ -2501,6 +2573,15 @@ "lf_version": "1.4.3", "metadata": { "code_hash": "192913db3453", + "dependencies": { + "dependencies": [ + { + "name": "langflow", + "version": null + } + ], + "total_dependencies": 1 + }, "module": "langflow.components.input_output.chat.ChatInput" }, "minimized": true, diff --git a/src/backend/tests/unit/custom/test_utils_metadata.py b/src/backend/tests/unit/custom/test_utils_metadata.py index 015e9b1b0..7812dc3eb 100644 --- a/src/backend/tests/unit/custom/test_utils_metadata.py +++ b/src/backend/tests/unit/custom/test_utils_metadata.py @@ -3,7 +3,11 @@ from unittest.mock import Mock, patch import pytest -from langflow.custom.utils import _generate_code_hash +from langflow.custom.utils import ( + _generate_code_hash, + build_component_metadata, + build_custom_component_template_from_inputs, +) class TestCodeHashGeneration: @@ -141,21 +145,373 @@ class TestMetadataInTemplateBuilders: assert len(result) == 12 assert all(c in "0123456789abcdef" for c in result) - @patch("langflow.custom.utils.ComponentFrontendNode") - def test_build_from_inputs_without_module_generates_default(self, mock_frontend_class): - """Test that build_custom_component_template_from_inputs generates default module when module_name is None.""" + +class TestDependencyAnalyzer: + """Test dependency analysis functionality.""" + + def test_top_level_basic(self): + """Test extracting top level package name.""" + from langflow.custom.dependency_analyzer import _top_level + + assert _top_level("numpy") == "numpy" + assert _top_level("numpy.array") == "numpy" + assert _top_level("requests.adapters.HTTPAdapter") == "requests" + + def test_is_relative(self): + """Test relative import detection.""" + from langflow.custom.dependency_analyzer import _is_relative + + assert _is_relative(".module") is True + assert _is_relative("..parent") is True + assert _is_relative("...grandparent") is True + assert _is_relative("module") is False + assert _is_relative(None) is False + + def test_analyze_dependencies_basic(self): + """Test basic dependency analysis.""" + from langflow.custom.dependency_analyzer import analyze_dependencies + + code = """ +import os +import sys +from typing import List +import numpy as np +from requests import get +""" + + deps = analyze_dependencies(code, resolve_versions=False) + + # Should find external dependencies only (stdlib imports filtered out) + assert len(deps) == 2 + + # Check external dependencies + dep_names = [d["name"] for d in deps] + assert "numpy" in dep_names + assert "requests" in dep_names + + # Stdlib imports should be filtered out + assert "os" not in dep_names + assert "sys" not in dep_names + assert "typing" not in dep_names + + def test_analyze_dependencies_optional_detection(self): + """Test that all dependencies are treated as required (no optional detection).""" + from langflow.custom.dependency_analyzer import analyze_dependencies + + code = """ +import os +try: + import optional_package + HAS_OPTIONAL = True +except ImportError: + HAS_OPTIONAL = False + +try: + from another_optional import something +except ImportError: + pass # This is now treated as a regular dependency +""" + + deps = analyze_dependencies(code, resolve_versions=False) + + # Should find external dependencies only (stdlib imports filtered out) + assert len(deps) == 2 # optional_package, another_optional + dep_names = [d["name"] for d in deps] + assert "optional_package" in dep_names + assert "another_optional" in dep_names + + # Stdlib imports should be filtered out + assert "os" not in dep_names + + def test_analyze_component_dependencies(self): + """Test component-specific dependency analysis.""" + from langflow.custom.dependency_analyzer import analyze_component_dependencies + + component_code = """ +import os +import sys +from typing import Dict, List +from langflow.custom import CustomComponent +import numpy as np + +class TestComponent(CustomComponent): + def build(self): + return {"test": "value"} +""" + + result = analyze_component_dependencies(component_code) + + # Check structure + assert "total_dependencies" in result + assert "dependencies" in result + + # Should have some dependencies (only external dependencies) + assert result["total_dependencies"] > 0 + + # Should have dependencies list + assert isinstance(result["dependencies"], list) + + # Verify no duplicate packages in dependencies + package_names = [pkg["name"] for pkg in result["dependencies"]] + assert len(package_names) == len(set(package_names)), "No duplicate packages should exist" + + def test_analyze_component_dependencies_error_handling(self): + """Test error handling in component dependency analysis.""" + from langflow.custom.dependency_analyzer import analyze_component_dependencies + + # Test with invalid Python code + invalid_code = "import os\nthis is not valid python syntax!!!" + + result = analyze_component_dependencies(invalid_code) + + # Should return minimal info on error + assert result["total_dependencies"] == 0 + assert result["dependencies"] == [] + + def test_dependency_info_dataclass(self): + """Test DependencyInfo dataclass creation.""" + from langflow.custom.dependency_analyzer import DependencyInfo + + dep = DependencyInfo( + name="numpy", + version="1.21.0", + is_local=False, + ) + + assert dep.name == "numpy" + assert dep.version == "1.21.0" + assert not dep.is_local + + def test_no_optional_dependency_classification(self): + """Test that the simplified analyzer doesn't classify any dependencies as optional.""" + from langflow.custom.dependency_analyzer import analyze_dependencies + + # Code with various import patterns that previously might have been considered optional + code = """ +import os +try: + import package_a + HAS_A = True +except ImportError: + HAS_A = False + +try: + import package_b +except ImportError: + pass + +try: + from package_c import something +except (ImportError, ModuleNotFoundError): + something = None +""" + deps = analyze_dependencies(code, resolve_versions=False) + + # Should find external dependencies only (stdlib filtered out) + dep_names = [d["name"] for d in deps] + assert "package_a" in dep_names + assert "package_b" in dep_names + assert "package_c" in dep_names + + # Stdlib imports should be filtered out + assert "os" not in dep_names + + # All found dependencies should be external (not local) + for dep in deps: + assert not dep["is_local"], f"Dependency {dep['name']} should not be local" + + +class TestMetadataWithDependencies: + """Test metadata functionality including dependencies.""" + + def test_build_component_metadata_includes_dependencies(self): + """Test that build_component_metadata includes dependency analysis.""" + + def test_build_from_inputs_without_module_generates_default(self): + """Test that build_component_metadata includes dependency analysis results.""" from langflow.custom.custom_component.component import Component - from langflow.custom.utils import build_custom_component_template_from_inputs # Setup mock frontend node mock_frontend = Mock() mock_frontend.metadata = {} + + # Create test component with real code + test_component = Mock(spec=Component) + test_component._code = """ +import os +import sys +from typing import List + +class TestComponent: + def build(self): + return {"test": "value"} +""" + + # Call the function + build_component_metadata(mock_frontend, test_component, "test.module", "TestComponent") + + # Verify metadata was added + assert "module" in mock_frontend.metadata + assert "code_hash" in mock_frontend.metadata + assert "dependencies" in mock_frontend.metadata + + # Verify dependency analysis results + dep_info = mock_frontend.metadata["dependencies"] + # Only external dependencies are tracked now (stdlib filtered out) + assert dep_info["total_dependencies"] == 0 # No external deps in this test code + assert "dependencies" in dep_info + assert isinstance(dep_info["dependencies"], list) + + def test_build_component_metadata_handles_analysis_error(self): + """Test that build_component_metadata handles dependency analysis errors gracefully.""" + from langflow.custom.custom_component.component import Component + + # Setup mock frontend node + mock_frontend = Mock() + mock_frontend.metadata = {} + + # Create test component with invalid Python code + test_component = Mock(spec=Component) + test_component._code = "import os\nthis is not valid python syntax!!!" + + # Call the function - should not raise exception + build_component_metadata(mock_frontend, test_component, "test.module", "TestComponent") + + # Should not raise exception and should set minimal dependency info + assert "dependencies" in mock_frontend.metadata + dep_info = mock_frontend.metadata["dependencies"] + assert dep_info["total_dependencies"] == 0 + assert dep_info["dependencies"] == [] + + def test_build_component_metadata_with_external_dependencies(self): + """Test dependency analysis with external packages.""" + from langflow.custom.custom_component.component import Component + + # Setup mock frontend node + mock_frontend = Mock() + mock_frontend.metadata = {} + + # Create test component with external dependencies + test_component = Mock(spec=Component) + test_component._code = """ +import os +from langflow.custom import CustomComponent + +class TestComponent(CustomComponent): + def build(self): + return {"test": "value"} +""" + + # Call the function + build_component_metadata(mock_frontend, test_component, "test.module", "TestComponent") + + # Verify dependency analysis results + dep_info = mock_frontend.metadata["dependencies"] + assert dep_info["total_dependencies"] == 1 # Only langflow (os is stdlib, filtered out) + + # Check for dependencies + package_names = [pkg["name"] for pkg in dep_info["dependencies"]] + assert "langflow" in package_names # langflow should be detected as external + assert "os" not in package_names # os is stdlib, should be filtered out + + def test_build_component_metadata_with_optional_dependencies(self): + """Test dependency analysis with optional dependencies.""" + from langflow.custom.custom_component.component import Component + + # Setup mock frontend node + mock_frontend = Mock() + mock_frontend.metadata = {} + + # Create test component with optional dependencies + test_component = Mock(spec=Component) + test_component._code = """ +import os +try: + import some_optional_package + HAS_OPTIONAL = True +except ImportError: + HAS_OPTIONAL = False + +class TestComponent: + def build(self): + return {"test": "value"} +""" + + # Call the function + build_component_metadata(mock_frontend, test_component, "test.module", "TestComponent") + + # Verify dependency analysis results + dep_info = mock_frontend.metadata["dependencies"] + assert dep_info["total_dependencies"] == 1 # Only some_optional_package (os is stdlib, filtered out) + + # Verify the dependencies are found + package_names = [pkg["name"] for pkg in dep_info["dependencies"]] + assert "some_optional_package" in package_names + assert "os" not in package_names # os is stdlib, should be filtered out + + def test_build_component_metadata_with_real_component(self): + """Test dependency analysis with a real component.""" + from langflow.custom.custom_component.component import Component + from langflow.custom.utils import build_component_metadata + + # Setup mock frontend node + mock_frontend = Mock() + mock_frontend.metadata = {} + + # Use real component code based on LMStudio component + real_component_code = """from typing import Any +from urllib.parse import urljoin + +import httpx +from langchain_openai import ChatOpenAI + +from langflow.base.models.model import LCModelComponent +from langflow.field_typing import LanguageModel + +class LMStudioModelComponent(LCModelComponent): + display_name = "LM Studio" + description = "Generate text using LM Studio Local LLMs." + icon = "LMStudio" + name = "LMStudioModel" + + def build(self): + return {"test": "value"} +""" + + # Create test component + test_component = Mock(spec=Component) + test_component._code = real_component_code + + # Call the function + build_component_metadata( + mock_frontend, test_component, "langflow.components.lmstudio", "LMStudioModelComponent" + ) + + # Verify metadata was added + assert "module" in mock_frontend.metadata + assert "code_hash" in mock_frontend.metadata + assert "dependencies" in mock_frontend.metadata + + # Verify dependency analysis results + dep_info = mock_frontend.metadata["dependencies"] + assert dep_info["total_dependencies"] > 0 + + # Check that external dependencies are found (stdlib filtered out) + package_names = [pkg["name"] for pkg in dep_info["dependencies"]] + + # External packages should be found + assert "httpx" in package_names # external + assert "langchain_openai" in package_names # external + assert "langflow" in package_names # project dependency + + # Stdlib imports should be filtered out + assert "typing" not in package_names + assert "urllib" not in package_names mock_frontend.outputs = [] mock_frontend.to_dict = Mock(return_value={"test": "data"}) mock_frontend.validate_component = Mock() mock_frontend.set_base_classes_from_outputs = Mock() mock_frontend.display_name = "My Test Component" - mock_frontend_class.from_inputs.return_value = mock_frontend # Create test component test_component = Mock(spec=Component) @@ -176,7 +532,7 @@ class TestMetadataInTemplateBuilders: patch("langflow.custom.utils.reorder_fields"), ): # Call the function without module_name - template, _ = build_custom_component_template_from_inputs(test_component, module_name=None) + _, _ = build_custom_component_template_from_inputs(test_component, module_name=None) # Verify metadata was added with generated module name assert "module" in mock_frontend.metadata