ref: Refactor vectorstore components structure#9486
Conversation
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.
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughIntroduces lazy-loading initializers for many vector-store components, restructures Redis components (adds vector store in components/redis, adds separate chat memory, removes old vectorstores/redis), removes CassandraChatMemory, narrows vectorstores package to only LocalDBComponent, updates starter project component paths, and extends frontend sidebar constants with additional bundles. Changes
Sequence Diagram(s)sequenceDiagram
participant UserCode as User code
participant Package as components.<store>.__init__
participant Importer as import_mod
participant Submod as components.<store>.<module>
UserCode->>Package: from components.<store> import <Component>
activate Package
Package->>Package: __getattr__("<Component>")
alt name in _dynamic_imports
Package->>Importer: import_mod("<Component>", "<module>", __spec__.parent)
Importer->>Submod: import
Submod-->>Importer: <Component>
Importer-->>Package: <Component>
Package->>Package: cache in globals()
Package-->>UserCode: <Component>
else unknown name
Package-->>UserCode: AttributeError
end
deactivate Package
sequenceDiagram
participant UI as UI / Flow
participant RedisComp as RedisVectorStoreComponent
participant Embed as Embeddings
participant VStore as Redis Vector Store
UI->>RedisComp: build_vector_store()
activate RedisComp
RedisComp->>RedisComp: _prepare_ingest_data()
alt documents provided
RedisComp->>RedisComp: chunk documents
RedisComp->>VStore: Redis.from_documents(docs, embedding, redis_url, index_name)
else no documents
RedisComp->>VStore: Redis.from_existing_index(embedding, index_name, schema, redis_url)
end
RedisComp-->>UI: VStore
deactivate RedisComp
UI->>RedisComp: search_documents(query, k)
RedisComp->>VStore: similarity_search(query, k)
VStore-->>RedisComp: [docs]
RedisComp->>RedisComp: docs_to_data()
RedisComp-->>UI: [Data]
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
|
init needs to be updated. |
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.
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.
…langflow into split-vector-stores
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.
There was a problem hiding this comment.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (1)
2789-2793: Typo in user-facing info: “Supercedes” → “Supersedes”.Fix the spelling in the API Endpoint info text shown in the UI.
- "info": "The API Endpoint for the Astra DB instance. Supercedes database selection.", + "info": "The API Endpoint for the Astra DB instance. Supersedes database selection.",Apply the same replacement in both AstraDB nodes’ api_endpoint template blocks.
Also applies to: 3561-3571
src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (1)
2211-2228: Defaulting “Allow Dangerous Deserialization” to true is unsafeAllowing untrusted pickle loading by default can lead to RCE if users point to a malicious index. This starter should err on the safe side and require an explicit opt-in.
Apply this minimal change:
- "value": true + "value": false
🧹 Nitpick comments (22)
src/backend/base/langflow/components/chroma/__init__.py (1)
19-35: Minor resilience and introspection nitpicks: guard spec and sort dir.Guard against rare None spec to avoid AttributeError in import contexts, and return a sorted list from dir for stable introspection.
Apply:
def __getattr__(attr_name: str) -> Any: """Lazily import Chroma components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + parent_pkg = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], parent_pkg) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result def __dir__() -> list[str]: - return list(__all__) + return sorted(__all__)src/backend/base/langflow/components/pgvector/__init__.py (1)
19-35: Nit: add spec fallback and sorted dir; optional docstring casing.Same minor improvements as other modules; also consider capitalizing “PGVector” in the docstring for consistency.
def __getattr__(attr_name: str) -> Any: - """Lazily import pgvector components on attribute access.""" + """Lazily import PGVector components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + parent_pkg = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], parent_pkg) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result def __dir__() -> list[str]: - return list(__all__) + return sorted(__all__)src/backend/base/langflow/components/milvus/__init__.py (1)
19-35: Nit: add spec fallback and sorted dir.Mirrors the tiny hardening and introspection tweaks suggested elsewhere.
def __getattr__(attr_name: str) -> Any: """Lazily import Milvus components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + parent_pkg = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], parent_pkg) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result def __dir__() -> list[str]: - return list(__all__) + return sorted(__all__)src/backend/base/langflow/components/clickhouse/__init__.py (2)
19-21: Casing consistency nit: Clickhouse vs ClickHouse.Docstring says “ClickHouse” while public class is ClickhouseVectorStoreComponent. Recommend keeping casing consistent across docstrings, icons, and class names to avoid confusion (no change required if this matches existing naming elsewhere).
19-35: Nit: add spec fallback and sorted dir.Same tiny hardening as other modules.
def __getattr__(attr_name: str) -> Any: - """Lazily import ClickHouse components on attribute access.""" + """Lazily import Clickhouse components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + parent_pkg = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], parent_pkg) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result def __dir__() -> list[str]: - return list(__all__) + return sorted(__all__)src/backend/base/langflow/components/supabase/__init__.py (1)
11-14: Keep dynamic import map entries alphabetized for consistencyMinor readability nit to match our guideline about alphabetical ordering in init.py files. Keys first by public symbol: SupabaseComposioComponent, then SupabaseVectorStoreComponent.
-_dynamic_imports = { - "SupabaseVectorStoreComponent": "supabase", - "SupabaseComposioComponent": "supabase_composio", -} +_dynamic_imports = { + "SupabaseComposioComponent": "supabase_composio", + "SupabaseVectorStoreComponent": "supabase", +}src/backend/base/langflow/components/vectara/__init__.py (2)
11-14: Alphabetize dynamic imports for consistencyNit: keep the map ordered by public symbol name.
-_dynamic_imports = { - "VectaraVectorStoreComponent": "vectara", - "VectaraRagComponent": "vectara_rag", -} +_dynamic_imports = { + "VectaraRagComponent": "vectara_rag", + "VectaraVectorStoreComponent": "vectara", +}
22-34: Consider centralizing the lazy-loader to avoid future driftThis pattern appears across many component packages. A helper in langflow.components._importing (e.g., setup_lazy_loader(module_name: str, dynamic_map: dict[str,str], g: dict)) could assign all, getattr, and dir for a module in a single call, reducing copy/paste errors like the package argument bug.
Example (outside this hunk):
# in langflow/components/_importing.py from types import ModuleType from typing import Any def setup_lazy_loader(module: ModuleType, dynamic_imports: dict[str, str]) -> None: module.__all__ = list(sorted(dynamic_imports.keys())) def __getattr__(attr_name: str) -> Any: if attr_name not in dynamic_imports: raise AttributeError(f"module '{module.__name__}' has no attribute '{attr_name}'") result = import_mod(attr_name, dynamic_imports[attr_name], module.__name__) module.__dict__[attr_name] = result return result def __dir__() -> list[str]: return list(module.__all__) module.__getattr__ = __getattr__ # type: ignore[attr-defined] module.__dir__ = __dir__ # type: ignore[assignment]Then in each init.py:
from langflow.components._importing import setup_lazy_loader _dynamic_imports = {...} setup_lazy_loader(sys.modules[__name__], _dynamic_imports)src/backend/base/langflow/components/pinecone/__init__.py (2)
19-31: Harden lazy import against rare cases where spec may be None.In unusual execution contexts, spec can be None. Use a safe fallback for the package argument passed to import_mod to avoid AttributeError.
-def __getattr__(attr_name: str) -> Any: +def __getattr__(attr_name: str) -> Any: """Lazily import Pinecone components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package = (__spec__.parent if (__spec__ and __spec__.parent) else __name__.rpartition(".")[0] or __name__) + result = import_mod(attr_name, _dynamic_imports[attr_name], package) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result
10-16: Public API is clear; keep entries alphabetized as components grow.all and _dynamic_imports look good for a single symbol. Per house style, when more Pinecone components are added, keep keys and all sorted alphabetically for discoverability.
src/backend/base/langflow/components/cassandra/__init__.py (1)
16-19: Keep public exports alphabetical in all to align with guidelinesThe coding guideline for components/init.py asks for alphabetical imports/exports. Swap the order in all so "CassandraVectorStoreComponent" comes before "CassandraGraphVectorStoreComponent".
__all__ = [ - "CassandraGraphVectorStoreComponent", - "CassandraVectorStoreComponent", + "CassandraVectorStoreComponent", + "CassandraGraphVectorStoreComponent", ]src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (1)
2184-2187: Consider normalizing package casing for componentsUsing an uppercase package directory (components/FAISS) is unconventional in Python and can introduce platform-dependent import issues. If possible, prefer lowercase (components/faiss) and expose the PascalCase “FAISS” only in UI-facing display_name/icon.
src/frontend/src/utils/styleUtils.ts (1)
301-304: Use a recognizable Postgres icon for pgvector (consistency with icon naming guidelines)Icon "cpu" is generic and inconsistent with our icon naming preference (e.g., "AstraDB", "Postgres"). We already use "Postgres" elsewhere (e.g., PostgresChatMessageHistory).
Apply this diff:
- { display_name: "pgvector", name: "pgvector", icon: "cpu" }, + { display_name: "pgvector", name: "pgvector", icon: "Postgres" },src/backend/base/langflow/components/redis/__init__.py (1)
11-14: Minor: add typing to the dynamic imports map for clarityAdd a dict[str, str] annotation to _dynamic_imports; improves readability and static checking.
Apply this diff:
-_dynamic_imports = { +_dynamic_imports: dict[str, str] = { "RedisVectorStoreComponent": "redis", "RedisIndexChatMemory": "redis_chat", }Also applies to: 22-33
src/backend/base/langflow/components/redis/redis_chat.py (2)
11-14: Fix grammar in descriptionChange “Retrieves and store” to “Retrieves and stores”.
- description = "Retrieves and store chat messages from Redis." + description = "Retrieves and stores chat messages in Redis."
16-32: Prefer StrInput for username; consider IntInput for database
- Username should be a plain string, not a MessageTextInput.
- Database index is numeric; IntInput provides validation (it can still be interpolated into the URL).
- MessageTextInput( - name="username", display_name="Username", value="", info="The Redis user name.", advanced=True - ), + StrInput( + name="username", display_name="Username", value="", info="The Redis user name.", advanced=True + ), - StrInput(name="database", display_name="database", required=True, value="0", info="Redis database."), + IntInput(name="database", display_name="database", required=True, value=0, info="Redis database."),src/backend/base/langflow/components/FAISS/__init__.py (1)
10-12: Minor: add typing to import map and standardize docstring phrasingType the map and keep docstring phrasing consistent across packages.
-_dynamic_imports = { +_dynamic_imports: dict[str, str] = { "FaissVectorStoreComponent": "faiss", } def __getattr__(attr_name: str) -> Any: - """Lazily import FAISS components on attribute access.""" + """Lazily import FAISS components on first attribute access."""Also applies to: 19-31
src/backend/base/langflow/components/redis/redis.py (5)
67-68: Prefer RecursiveCharacterTextSplitter for better semantic chunking.
RecursiveCharacterTextSplittergenerally yields higher-quality chunks than the basic character splitter.Apply these diffs:
-from langchain.text_splitter import CharacterTextSplitter +from langchain.text_splitter import RecursiveCharacterTextSplitter- text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) + text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)Also applies to: 3-3
77-89: Minor: align no-query behavior with base component status handling.Set
statusto empty when no query to mirror base behavior and make downstream UI consistent.Apply this diff:
- return [] + self.status = "" + return []
42-46: Avoid mutating self.ingest_data during build; use a local.Using a local variable reduces side effects if other outputs/methods read
self.ingest_data.Apply this diff:
- self.ingest_data = self._prepare_ingest_data() + ingest_data = self._prepare_ingest_data() @@ - for _input in self.ingest_data or []: + for _input in ingest_data:Also applies to: 48-52
26-26: Unused input 'code'.
codeis not referenced in this component. Remove it or document its purpose to avoid confusing users.Apply this diff if unused:
- StrInput(name="code", display_name="Code", advanced=True),
59-66: Simplify Redis.from_existing_index callThe
Redis.from_existing_indexsignature is:
- embedding
- index_name (required)
- schema (required)
- key_prefix (optional, defaults to
None)- redis_url
Since
key_prefix=Noneis the default, you can safely omit it to reduce verbosity:redis_vs = Redis.from_existing_index( embedding=self.embedding, index_name=self.redis_index_name, schema=self.schema, - key_prefix=None, redis_url=self.redis_server_url, )
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (26)
src/backend/base/langflow/components/FAISS/__init__.py(1 hunks)src/backend/base/langflow/components/cassandra/__init__.py(1 hunks)src/backend/base/langflow/components/chroma/__init__.py(1 hunks)src/backend/base/langflow/components/clickhouse/__init__.py(1 hunks)src/backend/base/langflow/components/couchbase/__init__.py(1 hunks)src/backend/base/langflow/components/datastax/cassandra.py(0 hunks)src/backend/base/langflow/components/elastic/__init__.py(1 hunks)src/backend/base/langflow/components/milvus/__init__.py(1 hunks)src/backend/base/langflow/components/mongodb/__init__.py(1 hunks)src/backend/base/langflow/components/pgvector/__init__.py(1 hunks)src/backend/base/langflow/components/pinecone/__init__.py(1 hunks)src/backend/base/langflow/components/qdrant/__init__.py(1 hunks)src/backend/base/langflow/components/redis/__init__.py(1 hunks)src/backend/base/langflow/components/redis/redis.py(1 hunks)src/backend/base/langflow/components/redis/redis_chat.py(1 hunks)src/backend/base/langflow/components/supabase/__init__.py(1 hunks)src/backend/base/langflow/components/upstash/__init__.py(1 hunks)src/backend/base/langflow/components/vectara/__init__.py(1 hunks)src/backend/base/langflow/components/vectorstores/__init__.py(0 hunks)src/backend/base/langflow/components/vectorstores/redis.py(0 hunks)src/backend/base/langflow/components/weaviate/__init__.py(1 hunks)src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json(1 hunks)src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json(1 hunks)src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json(2 hunks)src/frontend/src/constants/constants.ts(1 hunks)src/frontend/src/utils/styleUtils.ts(3 hunks)
💤 Files with no reviewable changes (3)
- src/backend/base/langflow/components/vectorstores/redis.py
- src/backend/base/langflow/components/datastax/cassandra.py
- src/backend/base/langflow/components/vectorstores/init.py
🧰 Additional context used
📓 Path-based instructions (6)
src/backend/base/langflow/components/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
src/backend/base/langflow/components/**/*.py: Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/
Implement async component methods using async def and await for asynchronous operations
Use asyncio.create_task for background work in async components and ensure proper cleanup on cancellation
Use asyncio.Queue for non-blocking queue operations in async components and handle timeouts appropriately
Files:
src/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/redis/redis_chat.pysrc/backend/base/langflow/components/redis/redis.py
src/backend/base/langflow/components/**/__init__.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
Update init.py with alphabetical imports when adding new components
Files:
src/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/chroma/__init__.py
{src/backend/**/*.py,tests/**/*.py,Makefile}
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code
Files:
src/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/redis/redis_chat.pysrc/backend/base/langflow/components/redis/redis.py
src/backend/**/components/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/icons.mdc)
In your Python component class, set the
iconattribute to a string matching the frontend icon mapping exactly (case-sensitive).
Files:
src/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/redis/redis_chat.pysrc/backend/base/langflow/components/redis/redis.py
src/frontend/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
src/frontend/src/**/*.{ts,tsx,js,jsx}: All frontend TypeScript and JavaScript code should be located under src/frontend/src/ and organized into components, pages, icons, stores, types, utils, hooks, services, and assets directories as per the specified directory layout.
Use React 18 with TypeScript for all UI components in the frontend.
Format all TypeScript and JavaScript code using the make format_frontend command.
Lint all TypeScript and JavaScript code using the make lint command.
Files:
src/frontend/src/constants/constants.tssrc/frontend/src/utils/styleUtils.ts
src/frontend/src/utils/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
All utility functions should be placed in the utils directory.
Files:
src/frontend/src/utils/styleUtils.ts
🧠 Learnings (2)
📚 Learning: 2025-07-18T18:25:54.486Z
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-07-18T18:25:54.486Z
Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new components
Applied to files:
src/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/chroma/__init__.py
📚 Learning: 2025-07-28T15:56:47.865Z
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/icons.mdc:0-0
Timestamp: 2025-07-28T15:56:47.865Z
Learning: Always use clear, recognizable, and consistent icon names for both backend and frontend (e.g., "AstraDB", "Postgres", "OpenAI").
Applied to files:
src/frontend/src/utils/styleUtils.ts
🧬 Code graph analysis (18)
src/backend/base/langflow/components/weaviate/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/weaviate/weaviate.py (1)
WeaviateVectorStoreComponent(10-89)
src/backend/base/langflow/components/supabase/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/supabase/supabase.py (1)
SupabaseVectorStoreComponent(10-76)
src/backend/base/langflow/components/mongodb/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/mongodb/mongodb_atlas.py (1)
MongoVectorStoreComponent(15-213)
src/backend/base/langflow/components/vectara/__init__.py (3)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/vectara/vectara.py (1)
VectaraVectorStoreComponent(14-97)src/backend/base/langflow/components/vectara/vectara_rag.py (1)
VectaraRagComponent(7-164)
src/backend/base/langflow/components/upstash/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/upstash/upstash.py (1)
UpstashVectorStoreComponent(15-124)
src/backend/base/langflow/components/pgvector/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/pgvector/pgvector.py (1)
PGVectorStoreComponent(10-72)
src/backend/base/langflow/components/milvus/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/milvus/milvus.py (1)
MilvusVectorStoreComponent(16-115)
src/backend/base/langflow/components/clickhouse/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/clickhouse/clickhouse.py (1)
ClickhouseVectorStoreComponent(17-135)
src/backend/base/langflow/components/qdrant/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/qdrant/qdrant.py (1)
QdrantVectorStoreComponent(16-109)
src/backend/base/langflow/components/pinecone/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/pinecone/pinecone.py (1)
PineconeVectorStoreComponent(10-111)
src/backend/base/langflow/components/elastic/__init__.py (3)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/elastic/elasticsearch.py (1)
ElasticsearchVectorStoreComponent(20-267)src/backend/base/langflow/components/elastic/opensearch.py (1)
OpenSearchVectorStoreComponent(22-243)
src/backend/base/langflow/components/cassandra/__init__.py (3)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/cassandra/cassandra.py (1)
CassandraVectorStoreComponent(16-264)src/backend/base/langflow/components/cassandra/cassandra_graph.py (1)
CassandraGraphVectorStoreComponent(18-238)
src/backend/base/langflow/components/couchbase/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/couchbase/couchbase.py (1)
CouchbaseVectorStoreComponent(11-102)
src/backend/base/langflow/components/redis/__init__.py (3)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/redis/redis.py (1)
RedisVectorStoreComponent(12-89)src/backend/base/langflow/components/redis/redis_chat.py (1)
RedisIndexChatMemory(10-43)
src/backend/base/langflow/components/FAISS/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/FAISS/faiss.py (1)
FaissVectorStoreComponent(11-111)
src/backend/base/langflow/components/chroma/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/chroma/chroma.py (1)
ChromaVectorStoreComponent(17-167)
src/backend/base/langflow/components/redis/redis_chat.py (2)
src/backend/base/langflow/base/memory/model.py (1)
LCChatMemoryComponent(11-38)src/backend/base/langflow/inputs/inputs.py (4)
IntInput(343-375)MessageTextInput(205-256)SecretStrInput(285-340)StrInput(128-184)
src/backend/base/langflow/components/redis/redis.py (4)
src/backend/base/langflow/base/vectorstores/model.py (3)
LCVectorStoreComponent(41-193)check_cached_vector_store(17-38)_prepare_ingest_data(107-123)src/backend/base/langflow/helpers/data.py (1)
docs_to_data(14-23)src/backend/base/langflow/inputs/inputs.py (1)
HandleInput(76-87)src/backend/base/langflow/schema/data.py (2)
Data(23-277)to_lc_document(139-149)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: test-starter-projects
🔇 Additional comments (24)
src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (1)
1201-1203: AstraDB migration complete — no stale references detectedAll searches for the old
langflow.components.vectorstores.astradbpath returned no hits, confirming there are no lingering references in the starter projects or elsewhere in the backend. The newAstraDBVectorStoreComponentclass is correctly declared in
•src/backend/base/langflow/components/datastax/astradb.py(lines 29–33).
Frontend icon mappings and store lookups for “AstraDB” have also been updated appropriately. No further changes are needed.src/backend/base/langflow/components/chroma/__init__.py (1)
1-35: Lazy importer for Chroma is clean and consistent with the new pattern.
Solid use of TYPE_CHECKING, all, caching in globals(), and clear error messaging.src/backend/base/langflow/components/pgvector/__init__.py (1)
1-35: PGVector lazy importer looks good.
Matches the shared pattern; clear all and robust error handling.src/backend/base/langflow/components/milvus/__init__.py (1)
1-35: Milvus lazy importer is consistent and correct.
Good error propagation and symbol caching.src/backend/base/langflow/components/clickhouse/__init__.py (1)
1-35: Clickhouse lazy importer follows the shared pattern — nice.
TYPE_CHECKING import, all, caching, and error messages all look good.src/backend/base/langflow/components/upstash/__init__.py (2)
19-31: Nice lazy loader and clear error messagesThe lazy getattr with caching and descriptive AttributeError is solid and consistent with the shared import_mod utility.
1-35: Ignore incorrect flag:__spec__.parentusage is intentional and correctThe
import_modhelper is defined to accept apackageparameter, and using__spec__.parentensures that each component’s submodule is imported relative to its own package. This pattern is consistently applied across allsrc/backend/base/langflow/components/*/__init__.pyfiles and matches the intended design—no changes are needed.Likely an incorrect or invalid review comment.
src/backend/base/langflow/components/mongodb/__init__.py (2)
14-16: Exports look goodall correctly exposes MongoVectorStoreComponent and matches the dynamic map.
25-30: Correct import package: use nameUsing spec.parent here would import the package module ("langflow.components.mongodb") instead of the intended submodule ("langflow.components.mongodb.mongodb_atlas"). Switch to name.
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)Likely an incorrect or invalid review comment.
src/backend/base/langflow/components/vectara/__init__.py (1)
16-19: Export order is already alphabeticalall is in alphabetical order (Rag, then VectorStore). No changes needed.
src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (1)
2713-2714: AstraDB path refactor complete—no remaining stale imports detected
- No occurrences of the old
langflow.components.vectorstores.astradbpath were found anywhere in the repo (tests or otherwise).- Starter project JSONs only reference
langflow.components.datastax.astradb.AstraDBVectorStoreComponent(e.g., in Hybrid Search RAG.json and Vector Store RAG.json), as intended.- Other
langflow.components.vectorstores.*imports (GraphRAG, MongoDB Atlas, Chroma, LocalDB) are valid and unrelated to the AstraDB refactor.All checks pass; the refactor is fully consistent.
src/backend/base/langflow/components/pinecone/__init__.py (1)
7-9: TYPE_CHECKING import is correct and avoids runtime cost.Importing PineconeVectorStoreComponent only under TYPE_CHECKING plays well with static analyzers and the lazy loader.
src/backend/base/langflow/components/elastic/__init__.py (1)
16-19: API surface looks clean and explicitExplicit all with lazy loading for Elasticsearch and OpenSearch matches the refactor goals and keeps imports light.
src/backend/base/langflow/components/couchbase/__init__.py (1)
14-16: Good: public export list is minimal and clearSingle-symbol all and lazy import pattern are consistent with the refactor.
src/backend/base/langflow/components/weaviate/__init__.py (1)
14-16: LGTM: clear, consistent lazy exportMatches the pattern used across other vector store components.
src/backend/base/langflow/components/qdrant/__init__.py (1)
14-16: API exposure is tight and appropriateSingle export with lazy loading is appropriate for Qdrant.
src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (2)
2413-2441: No changes required: FAISS component inherits as_dataframeThe
LCVectorStoreComponentbase class (insrc/backend/base/langflow/base/vectorstores/model.py) defines anas_dataframemethod that simply wrapssearch_documentsin a DataFrame and is automatically inherited by all subclasses. SinceFaissVectorStoreComponentextendsLCVectorStoreComponentand does not overrideas_dataframe, the JSON entry for “as_dataframe” will correctly resolve at runtime. You can safely leave the tool metadata as is.Likely an incorrect or invalid review comment.
2184-2187: FAISS import path verified and correctAll checks confirm the new FAISS module path is accurate and no stale references remain:
- Component file and class exist
src/backend/base/langflow/components/FAISS/faiss.py definesclass FaissVectorStoreComponentin the expected location.- Starter JSON metadata matches
The starter project’smodulefield points to"langflow.components.FAISS.faiss.FaissVectorStoreComponent", matching the file path and class name.- Lazy loader setup is correct
src/backend/base/langflow/components/FAISS/__init__.pyuses_dynamic_importsand__getattr__to exposeFaissVectorStoreComponentfromfaiss.pywithout altering the import path.- No old-path references found
A repository-wide search yields no occurrences oflangflow.components.vectorstores.faiss.FaissVectorStoreComponent.With these confirmations, no further changes are needed here.
src/frontend/src/constants/constants.ts (1)
766-781: No changes needed in BUNDLES_SIDEBAR_FOLDER_NAMES—this list holds folder identifiers, not display names
- BUNDLES_SIDEBAR_FOLDER_NAMES is intentionally a list of folder keys (all lowercase, except “FAISS”) that map to on-disk bundle directories.
- Cased display variants (“Pinecone” vs. “pinecone”) belong in the
display_namefield withinSIDEBAR_BUNDLES(instyleUtils.ts), not in this constants array.The suggestion to add capitalized entries here conflates display text with folder IDs; please ignore it.
Likely an incorrect or invalid review comment.
src/frontend/src/utils/styleUtils.ts (1)
250-253: All custom icon mappings are present and correctly cased
- Verified that every icon string used in styleUtils.ts (“Cassandra”, “Chroma”, “Clickhouse”, “Couchbase”, “ElasticsearchStore”, “FAISS”, “Milvus”, “MongoDB”, “Postgres”, “Pinecone”, “Qdrant”, “Supabase”, “Upstash”, “Weaviate”) resolves to an entry in your lazyIconsMapping/exported icon modules.
- The “Clickhouse” icon casing matches the existing mapping (mapping uses “Clickhouse” rather than “ClickHouse”).
- No lucide “cpu” fallback was found in node_modules—which is acceptable if you’ve moved to using the Postgres icon.
All checks pass; no further action needed here.
src/backend/base/langflow/components/redis/__init__.py (1)
16-19: Public exports look good and alphabetizedThe all surface is minimal and alphabetized ("RedisIndexChatMemory", "RedisVectorStoreComponent"). Good alignment with our packaging guidelines.
src/backend/base/langflow/components/FAISS/__init__.py (1)
14-16: Public surface is minimal and clearall correctly exposes only FaissVectorStoreComponent and matches the lazy import map.
src/backend/base/langflow/components/redis/redis.py (2)
12-19: Class metadata looks good; ensure export path matches the new structure.
display_name,name, andiconlook consistent. Please ensuresrc/backend/base/langflow/components/redis/__init__.pyre-exportsRedisVectorStoreComponent(andRedisIndexChatMemoryif applicable) to satisfy the updated import paths and the sidebar mapping mentioned in the PR.
42-45: Nice use of @check_cached_vector_store to avoid duplicate builds.This aligns with LCVectorStoreComponent’s contract and prevents redundant connections/indexing per run.
Also applies to: 75-75
| if TYPE_CHECKING: | ||
| from .cassandra import CassandraVectorStoreComponent | ||
| from .cassandra_graph import CassandraGraphVectorStoreComponent | ||
|
|
||
| _dynamic_imports = { | ||
| "CassandraVectorStoreComponent": "cassandra", | ||
| "CassandraGraphVectorStoreComponent": "cassandra_graph", | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Double-check symbol paths and a potential option-string mismatch in CassandraGraph
- TYPE_CHECKING targets and _dynamic_imports look correct for this package.
- Separate issue to verify in cassandra_graph.py: inputs list includes "MMR traversal" but _map_search_type checks "MMR Traversal" (capital T). That condition may never match.
Run these to confirm and fix in the graph component:
🏁 Script executed:
#!/bin/bash
# 1) Ensure no remaining __spec__.parent usages in component __init__.py files
rg -nP --glob 'src/backend/**/components/**/__init__.py' 'import_mod\([^)]*,\s*__spec__\.parent\)'
# 2) Check for search-type casing mismatch in Cassandra graph component
rg -n -C2 --type=py '\bMMR traversal\b|\bMMR Traversal\b' src/backendLength of output: 10980
Critical fixes required: remove __spec__.parent in dynamic imports & correct “MMR traversal” casing
-
The dynamic‐import calls in all component
__init__.pyfiles still pass__spec__.parent(e.g.src/backend/base/langflow/components/cassandra/__init__.py:28), even though the import helper no longer needs it. These should be updated to omit the__spec__.parentargument:- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + result = import_mod(attr_name, _dynamic_imports[attr_name])
-
In
cassandra_graph.py, theoptionslist uses"MMR traversal"(lowercase “t”), but_map_search_typechecks for"MMR Traversal"(capital “T”), so choosing the “MMR traversal” option falls through to the default. Align these strings. For example, change the option to"MMR Traversal":--- a/src/backend/base/langflow/components/cassandra/cassandra_graph.py +++ b/src/backend/base/langflow/components/cassandra/cassandra_graph.py class CassandraGraphVectorStoreComponent(...): ... options=[ "Traversal", - "MMR traversal", + "MMR Traversal", "Similarity", "Similarity with score threshold", ] ... def _map_search_type(self): if self.search_type == "MMR (Max Marginal Relevance)": return "mmr" - if self.search_type == "MMR Traversal": + if self.search_type == "MMR traversal": return "mmr_traversal" return "traversal"
Please address both issues before merging.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/cassandra/__init__.py around lines 7 to
14, the dynamic import mapping still uses the helper that expects a parent arg;
remove any usage of __spec__.parent from the dynamic_imports calls so the import
helper is called with only module names (no __spec__.parent). Also in
src/backend/base/langflow/components/cassandra/cassandra_graph.py (where the
options list is defined), change the "MMR traversal" option to "MMR Traversal"
to match the _map_search_type check so the selection no longer falls through to
the default.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Fix dynamic import base: using spec.parent breaks relative imports and can recurse
Passing spec.parent points one level up (e.g., langflow.components), so ".cassandra" resolves to langflow.components.cassandra (the package), and getattr then re-enters this same getattr, risking infinite recursion. It also fails for sibling modules like ".cassandra_graph" that only exist under the current package. Use the current package name instead.
Apply this diff:
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ # Use this package as the base for relative imports (avoid importing from the parent package)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| # Use this package as the base for relative imports (avoid importing from the parent package) | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/cassandra/__init__.py around lines 28 to
33, the code calls import_mod(attr_name, _dynamic_imports[attr_name],
__spec__.parent) which uses __spec__.parent (one level up) and causes relative
imports like ".cassandra" to resolve to the package parent and re-enter this
module (risking recursion) and fail for sibling modules; change the import call
to use the current package name (use __name__ or __spec__.name) so relative
imports resolve against this package rather than its parent, preventing
recursion and correctly locating sibling modules.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Fix lazy import base package to avoid ModuleNotFoundError
Passing spec.parent will try langflow.components.couchbase (package) and re-enter getattr. Use name so ".couchbase" resolves to langflow.components.couchbase.couchbase.
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/couchbase/__init__.py around lines 25 to
30, the lazy import passes __spec__.parent which causes re-entry into
__getattr__ and a ModuleNotFoundError; change the third argument of import_mod
from __spec__.parent to __name__ so that a relative name like ".couchbase"
resolves to langflow.components.couchbase.couchbase and avoid re-entering the
package __getattr__ during import.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Correct package argument for import_mod; spec.parent targets the wrong package
Using spec.parent makes ".elasticsearch" resolve to langflow.components.elasticsearch instead of langflow.components.elastic.elasticsearch. Replace with name so imports are relative to the current package.
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
src/backend/base/langflow/components/elastic/__init__.py around lines 28-33: the
call to import_mod currently passes __spec__.parent which makes relative imports
resolve against the parent package (producing langflow.components.elasticsearch)
instead of the current package; change the package argument to __name__ so
import_mod resolves relative to langflow.components.elastic (i.e., pass __name__
as the third argument), leaving the existing error handling intact.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Fix incorrect package anchor in dynamic imports
Using spec.parent attempts to import from the parent package hierarchy and can fail. Use name.
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/qdrant/__init__.py around lines 25 to
30, the dynamic import call uses __spec__.parent as the package anchor which can
fail; change the third argument of import_mod from __spec__.parent to __name__
so the import is anchored to this module's package name (i.e.,
import_mod(attr_name, _dynamic_imports[attr_name], __name__)); update that call,
keep the surrounding exception handling intact, and run tests to verify imports
resolve correctly.
| else: | ||
| documents.append(_input) | ||
| Path("docuemnts.txt").write_text(str(documents), encoding="utf-8") | ||
|
|
There was a problem hiding this comment.
Remove debug file write; it's a PII leak and will bloat disks.
Writing all ingested documents to a local file is unsafe and likely accidental. Also note the typo in the filename.
Apply these diffs:
-from pathlib import Path- Path("docuemnts.txt").write_text(str(documents), encoding="utf-8")Also applies to: 1-1
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/redis/redis.py at line 53, remove the
debug Path("docuemnts.txt").write_text(...) call (it leaks PII, will bloat
disks, and has a filename typo); delete the line and any equivalent temporary
file writes elsewhere (the "Also applies to: 1-1" locations) and, if you need
visibility for debugging, replace with safe in-memory or sanitized logging
(avoid writing full document contents to disk and ensure any logs redact PII).
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Fix package scope for dynamic import
Same issue as other modules: pass name so ".supabase" resolves to "langflow.components.supabase.supabase" and not the package itself.
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| def __getattr__(attr_name: str) -> Any: | |
| try: | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/supabase/__init__.py around lines 28 to
33, the dynamic import call uses __spec__.parent which causes relative names
like ".supabase" to resolve to the package rather than
"langflow.components.supabase.supabase"; change the third argument passed to
import_mod from __spec__.parent to __name__ so import_mod(attr_name,
_dynamic_imports[attr_name], __name__) to ensure correct package scope for
dynamic imports and leave the existing error handling intact.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Use name instead of spec.parent in import_mod to avoid self-import/recursion
Passing spec.parent points to the parent package (e.g., "langflow.components"), so importing ".upstash" targets the package module ("langflow.components.upstash") rather than the submodule ("langflow.components.upstash.upstash"). This can trigger recursive lookups via this same getattr and fail to resolve the class. Using name correctly scopes the relative import to the current package.
Apply this diff:
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/upstash/__init__.py around lines 25 to
30, the call to import_mod passes __spec__.parent which can cause
self-import/recursion and resolve the package module instead of the submodule;
update the import_mod invocation to use __name__ so relative imports are scoped
to the current package module (e.g., ".upstash" resolves under this package) to
avoid recursive lookups and ensure the correct submodule/class is imported,
keeping the existing error handling unchanged.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Fix dynamic import scope to prevent infinite recursion
Pass name so that ".vectara" resolves to "langflow.components.vectara.vectara". The current spec.parent leads to importing the package module and can recurse back into this getattr.
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/vectara/__init__.py around lines 28 to
33, the dynamic import uses __spec__.parent which causes package-relative names
like ".vectara" to resolve to the package module and trigger recursion; change
the import_mod call to pass __name__ as the parent scope so relative imports
resolve to "langflow.components.vectara.vectara" instead of the package parent,
preventing the infinite recursion and ensuring the attribute is imported
correctly.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result |
There was a problem hiding this comment.
Use name for correct relative import context
spec.parent points to the parent package; this will not resolve weaviate submodule correctly. Switch to name.
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/weaviate/__init__.py around lines 25 to
30, the dynamic import uses __spec__.parent which points to the parent package
and can misresolve relative imports for the weaviate submodule; change the call
to use __name__ as the package context when calling import_mod (i.e., pass
__name__ instead of __spec__.parent) so relative imports resolve correctly, and
keep the rest of the exception handling and global assignment unchanged.
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/backend/base/langflow/components/elastic/__init__.py (1)
1-38: Update outdated vectorstores imports
We’ve found multiple lingering imports from the oldlangflow.components.vectorstorespath that need to be updated to the new subpackage structure. Please replace each occurrence with the correct new module path for that component.Affected locations:
- src/backend/base/langflow/initial_setup/starter_projects/vector_store_rag.py: line 9
- src/backend/base/langflow/components/init.py: line 90
- src/backend/tests/integration/test_dynamic_import_integration.py: line 104
- src/backend/tests/unit/components/vectorstores/test_graph_rag_component.py: line 8
- src/backend/tests/unit/components/vectorstores/test_local_db_component.py: line 7 and 373
- src/backend/tests/unit/components/vectorstores/test_mongodb_atlas.py: line 7
- src/backend/tests/integration/components/astra/test_astra_component.py: line 8
- src/backend/tests/unit/base/tools/test_vector_store_decorator.py: line 4
- src/backend/tests/unit/initial_setup/starter_projects/test_vector_store_rag.py: line 12
- src/backend/tests/unit/components/vectorstores/test_chroma_vector_store_component.py: line 6
Ensure each import now points to its new dedicated subpackage (for example,
langflow.components.elastic.elasticsearch.ElasticsearchVectorStoreComponent,langflow.components.elastic.opensearch.OpenSearchVectorStoreComponent,langflow.components.vectorstores.<component_name>, etc.) so that there are no broken references.
🧹 Nitpick comments (33)
src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (1)
1599-1609: Align database options metadata schema with runtime expectations.The saved starter contains "api_endpoint" (singular, str), but the component code expects "api_endpoints" (plural, list[str]) when handling selections. While the UI likely refreshes from live data, keeping the starter JSON consistent avoids edge-case errors and reduces confusion.
Apply this minimal change to reflect the expected shape:
- "api_endpoint": "https://5b8bb22c-4a38-4f0a-865c-a18ed7590bd1-us-east-2.apps.astra.datastax.com", + "api_endpoints": ["https://5b8bb22c-4a38-4f0a-865c-a18ed7590bd1-us-east-2.apps.astra.datastax.com"],src/backend/base/langflow/components/mongodb/__init__.py (1)
33-35: Minor: stable listing from dir.Return a sorted list for deterministic introspection; harmless and conventional.
-def __dir__() -> list[str]: - return list(__all__) +def __dir__() -> list[str]: + return sorted(__all__)src/backend/base/langflow/components/pinecone/__init__.py (2)
24-30: Harden against rare missing spec (fallback to module name)In unusual runtimes (embedded interpreters, custom loaders),
__spec__can beNone. Add a small fallback to avoid surprising import failures.Apply this diff:
def __getattr__(attr_name: str) -> Any: """Lazily import Pinecone components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], package) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result
14-16: Prefer immutable allMinor: using a tuple for
__all__prevents accidental mutation.-__all__ = [ - "PineconeVectorStoreComponent", -] +__all__ = ( + "PineconeVectorStoreComponent", +)src/backend/base/langflow/components/couchbase/__init__.py (2)
24-30: Add spec fallback for resilienceMirror the minor hardening suggested in other wrappers to guard against
__spec__being None.- try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + try: + package = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], package)
14-16: Optional: make all immutable-__all__ = [ - "CouchbaseVectorStoreComponent", -] +__all__ = ( + "CouchbaseVectorStoreComponent", +)src/backend/base/langflow/components/cassandra/__init__.py (3)
11-14: Keep dynamic import map keys in alphabetical order to match exportsFor consistency with the guideline about alphabetical ordering in init.py, place Graph before Vector in
_dynamic_importsto mirror__all__._dynamic_imports = { - "CassandraVectorStoreComponent": "cassandra", "CassandraGraphVectorStoreComponent": "cassandra_graph", + "CassandraVectorStoreComponent": "cassandra", }
22-33: Add spec fallback as in other modulesAligns behavior across packages and avoids edge-case failures.
- try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + try: + package = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], package)
16-19: Optional: make all a tuple-__all__ = [ - "CassandraGraphVectorStoreComponent", - "CassandraVectorStoreComponent", -] +__all__ = ( + "CassandraGraphVectorStoreComponent", + "CassandraVectorStoreComponent", +)src/backend/base/langflow/components/clickhouse/__init__.py (2)
20-20: Unify casing: Clickhouse vs ClickHouse in docstringDocstring says “ClickHouse” while the class/component uses “Clickhouse”. Pick one casing consistently across docs; code uses “Clickhouse”.
- """Lazily import ClickHouse components on attribute access.""" + """Lazily import Clickhouse components on attribute access."""
24-30: Add spec fallback as in other wrappersConsistency and resilience.
- try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + try: + package = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], package)src/backend/base/langflow/components/vectara/__init__.py (2)
28-33: Add spec fallback to align with other modulesKeeps behavior consistent and robust.
- try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + try: + package = __spec__.parent if __spec__ else __name__ + result = import_mod(attr_name, _dynamic_imports[attr_name], package)
16-19: Optional: all as tuple-__all__ = [ - "VectaraRagComponent", - "VectaraVectorStoreComponent", -] +__all__ = ( + "VectaraRagComponent", + "VectaraVectorStoreComponent", +)src/backend/base/langflow/components/upstash/__init__.py (1)
19-30: Harden getattr for environments where spec can be NoneIn some tooling/REPL/reloader contexts, spec may be None. Provide a safe fallback to derive the package string to avoid AttributeError during import.
Apply this diff:
def __getattr__(attr_name: str) -> Any: """Lazily import Upstash components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package_name = __spec__.parent if __spec__ is not None else (__name__.rpartition(".")[0] or None) + result = import_mod(attr_name, _dynamic_imports[attr_name], package_name) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return resultsrc/backend/base/langflow/components/pgvector/__init__.py (1)
19-30: Add a safe fallback for package resolution in getattrGuard against spec being None to prevent failures under certain loaders.
try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package_name = __spec__.parent if __spec__ is not None else (__name__.rpartition(".")[0] or None) + result = import_mod(attr_name, _dynamic_imports[attr_name], package_name) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from esrc/backend/base/langflow/components/qdrant/__init__.py (1)
19-30: Defensive fallback for spec in getattrMirror the small safety improvement to avoid failures when spec is None.
try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package_name = __spec__.parent if __spec__ is not None else (__name__.rpartition(".")[0] or None) + result = import_mod(attr_name, _dynamic_imports[attr_name], package_name) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from esrc/backend/base/langflow/components/elastic/__init__.py (1)
22-33: Make package resolution robust in getattrSame optional hardening as suggested for other bundles.
try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package_name = __spec__.parent if __spec__ is not None else (__name__.rpartition(".")[0] or None) + result = import_mod(attr_name, _dynamic_imports[attr_name], package_name) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from esrc/backend/base/langflow/components/weaviate/__init__.py (1)
19-30: Optional: guard spec access to improve resilienceAdopt the same fallback to avoid edge-case loader issues.
try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package_name = __spec__.parent if __spec__ is not None else (__name__.rpartition(".")[0] or None) + result = import_mod(attr_name, _dynamic_imports[attr_name], package_name) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from esrc/backend/base/langflow/components/supabase/__init__.py (2)
22-33: Harden lazy import for environments where spec may be NoneSome tooling/reload contexts can present spec as None, which would break the import path resolution. Use a robust fallback to package.
Apply this diff:
def __getattr__(attr_name: str) -> Any: """Lazily import Supabase components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) - try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + # Be robust when __spec__ is None (e.g., certain tooling or reload contexts) + package = __spec__.parent if __spec__ is not None else __package__ + try: + result = import_mod(attr_name, _dynamic_imports[attr_name], package) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result
36-37: Optional: return a sorted view for discoverabilityReturning sorted(all) can make interactive discovery a bit nicer; functionally equivalent.
-def __dir__() -> list[str]: - return list(__all__) +def __dir__() -> list[str]: + return sorted(__all__)src/backend/base/langflow/components/chroma/__init__.py (2)
19-30: Use a safe fallback when spec is NoneMirror the defensive pattern to avoid failures under certain loaders/reloaders.
def __getattr__(attr_name: str) -> Any: """Lazily import Chroma components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) - try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package = __spec__.parent if __spec__ is not None else __package__ + try: + result = import_mod(attr_name, _dynamic_imports[attr_name], package) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result
33-34: Nit: sorted listing for dirMinor discoverability improvement.
-def __dir__() -> list[str]: - return list(__all__) +def __dir__() -> list[str]: + return sorted(__all__)src/backend/base/langflow/components/milvus/__init__.py (2)
19-30: Defensive import: guard against spec being NoneAlign with the suggested robust pattern.
def __getattr__(attr_name: str) -> Any: """Lazily import Milvus components on attribute access.""" if attr_name not in _dynamic_imports: msg = f"module '{__name__}' has no attribute '{attr_name}'" raise AttributeError(msg) - try: - result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) + package = __spec__.parent if __spec__ is not None else __package__ + try: + result = import_mod(attr_name, _dynamic_imports[attr_name], package) except (ModuleNotFoundError, ImportError, AttributeError) as e: msg = f"Could not import '{attr_name}' from '{__name__}': {e}" raise AttributeError(msg) from e globals()[attr_name] = result return result
14-16: Typo in Milvus component UI label (cross-file)In src/backend/base/langflow/components/milvus/milvus.py, the DropdownInput display_name reads "Consistencey Level" (see provided snippet). Fix to "Consistency Level" to avoid user-facing typo.
Outside current file (for maintainers' convenience):
- DropdownInput( - name="consistency_level", - display_name="Consistencey Level", + DropdownInput( + name="consistency_level", + display_name="Consistency Level",src/backend/base/langflow/components/redis/redis_chat.py (3)
12-12: Grammar: description should be plural "stores"Tiny UX polish on the component description.
- description = "Retrieves and store chat messages from Redis." + description = "Retrieves and stores chat messages from Redis."
22-31: Prefer StrInput for username and session_idMessageTextInput allows Message/Data/iterators, which can lead to accidental non-string values bleeding into the URL and session id. These fields are inherently scalar strings; use StrInput to constrain types.
- MessageTextInput( - name="username", display_name="Username", value="", info="The Redis user name.", advanced=True - ), + StrInput( + name="username", display_name="Username", value="", info="The Redis user name.", advanced=True + ), @@ - MessageTextInput( - name="session_id", display_name="Session ID", info="Session ID for the message.", advanced=True - ), + StrInput( + name="session_id", display_name="Session ID", info="Session ID for the message.", advanced=True + ),
21-21: Optional: use IntInput for database indexThe Redis DB index is numeric; consider IntInput for "database" to catch invalid values earlier. If you prefer keeping it flexible, ensure downstream parsing tolerates strings.
src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (2)
2211-2228: Defaulting to “Allow Dangerous Deserialization” = True is risky; recommend default False.For FAISS load_local, enabling dangerous deserialization by default increases supply-chain risk if users point at untrusted indexes. Suggest flipping the default to False and requiring opt-in via the UI.
Proposed minimal change inside this node’s template:
- BoolInput( - name="allow_dangerous_deserialization", - display_name="Allow Dangerous Deserialization", - info="Set to True to allow loading pickle files from untrusted sources. " - "Only enable this if you trust the source of the data.", - advanced=True, - value=True, - ), + BoolInput( + name="allow_dangerous_deserialization", + display_name="Allow Dangerous Deserialization", + info="If True, allows loading pickled indices. Keep disabled unless you fully trust the source.", + advanced=True, + value=False, + ),If the project depends on True for a demo path, consider setting it per-project via the saved JSON, but keep the component’s default as False.
2166-2173: Add documentation link for FAISS component (minor UX polish).The FAISS node’s documentation field is empty. Adding a docs URL improves discoverability in the Playground.
- "documentation": "", + "documentation": "https://docs.langflow.org/components-vector-stores#faiss",If the docs URL changed with the refactor, update accordingly.
src/backend/base/langflow/components/FAISS/__init__.py (1)
1-35: LGTM: Lazy import shim follows the project pattern correctly.
- all, TYPE_CHECKING, getattr, and dir are implemented cleanly.
- Error messages are explicit and cache assignment via globals() avoids repeat imports.
Minor nit: if you later add more exports, keep all sorted alphabetically for consistency with other components.
src/backend/base/langflow/components/redis/redis.py (3)
77-89: Delegate to base search_documents to keep behavior consistent (search_type, logging, caching).The base LCVectorStoreComponent.search_documents already handles:
- honoring search_type (e.g., similarity, mmr),
- consistent logging,
- vector store caching.
Overriding here bypasses that logic. Prefer delegating to the base implementation.
Apply this diff:
- def search_documents(self) -> list[Data]: - vector_store = self.build_vector_store() - - if self.search_query and isinstance(self.search_query, str) and self.search_query.strip(): - docs = vector_store.similarity_search( - query=self.search_query, - k=self.number_of_results, - ) - - data = docs_to_data(docs) - self.status = data - return data - return [] + def search_documents(self) -> list[Data]: + # Delegate to base to leverage standardized behavior. + return super().search_documents()
55-66: Harden schema validation when reusing an existing index.Checking only for None misses empty-string/whitespace cases and produces confusing errors later. Validate string content.
Apply this diff:
- if not documents: - if self.schema is None: + if not documents: + if not isinstance(self.schema, str) or not self.schema.strip(): msg = "If no documents are provided, a schema must be provided." raise ValueError(msg) redis_vs = Redis.from_existing_index( embedding=self.embedding, index_name=self.redis_index_name, schema=self.schema, key_prefix=None, redis_url=self.redis_server_url, )
20-40: Consider marking embedding as required to fail fast if missing.Most vector stores need an embedding; leaving it optional defers failure to runtime. Making it required improves UX. If you prefer optional for tool-mode wiring, ignore.
Apply this diff to require the embedding handle:
- HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), + HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"], required=True),
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (26)
src/backend/base/langflow/components/FAISS/__init__.py(1 hunks)src/backend/base/langflow/components/cassandra/__init__.py(1 hunks)src/backend/base/langflow/components/chroma/__init__.py(1 hunks)src/backend/base/langflow/components/clickhouse/__init__.py(1 hunks)src/backend/base/langflow/components/couchbase/__init__.py(1 hunks)src/backend/base/langflow/components/datastax/cassandra.py(0 hunks)src/backend/base/langflow/components/elastic/__init__.py(1 hunks)src/backend/base/langflow/components/milvus/__init__.py(1 hunks)src/backend/base/langflow/components/mongodb/__init__.py(1 hunks)src/backend/base/langflow/components/pgvector/__init__.py(1 hunks)src/backend/base/langflow/components/pinecone/__init__.py(1 hunks)src/backend/base/langflow/components/qdrant/__init__.py(1 hunks)src/backend/base/langflow/components/redis/__init__.py(1 hunks)src/backend/base/langflow/components/redis/redis.py(1 hunks)src/backend/base/langflow/components/redis/redis_chat.py(1 hunks)src/backend/base/langflow/components/supabase/__init__.py(1 hunks)src/backend/base/langflow/components/upstash/__init__.py(1 hunks)src/backend/base/langflow/components/vectara/__init__.py(1 hunks)src/backend/base/langflow/components/vectorstores/__init__.py(0 hunks)src/backend/base/langflow/components/vectorstores/redis.py(0 hunks)src/backend/base/langflow/components/weaviate/__init__.py(1 hunks)src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json(1 hunks)src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json(1 hunks)src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json(2 hunks)src/frontend/src/constants/constants.ts(1 hunks)src/frontend/src/utils/styleUtils.ts(3 hunks)
💤 Files with no reviewable changes (3)
- src/backend/base/langflow/components/vectorstores/redis.py
- src/backend/base/langflow/components/datastax/cassandra.py
- src/backend/base/langflow/components/vectorstores/init.py
🧰 Additional context used
📓 Path-based instructions (6)
src/backend/base/langflow/components/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
src/backend/base/langflow/components/**/*.py: Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/
Implement async component methods using async def and await for asynchronous operations
Use asyncio.create_task for background work in async components and ensure proper cleanup on cancellation
Use asyncio.Queue for non-blocking queue operations in async components and handle timeouts appropriately
Files:
src/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/redis/redis_chat.pysrc/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/redis/redis.py
src/backend/base/langflow/components/**/__init__.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
Update init.py with alphabetical imports when adding new components
Files:
src/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/supabase/__init__.py
{src/backend/**/*.py,tests/**/*.py,Makefile}
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
{src/backend/**/*.py,tests/**/*.py,Makefile}: Run make format_backend to format Python code before linting or committing changes
Run make lint to perform linting checks on backend Python code
Files:
src/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/redis/redis_chat.pysrc/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/redis/redis.py
src/backend/**/components/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/icons.mdc)
In your Python component class, set the
iconattribute to a string matching the frontend icon mapping exactly (case-sensitive).
Files:
src/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/mongodb/__init__.pysrc/backend/base/langflow/components/elastic/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/pgvector/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/redis/redis_chat.pysrc/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/supabase/__init__.pysrc/backend/base/langflow/components/redis/redis.py
src/frontend/src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
src/frontend/src/**/*.{ts,tsx,js,jsx}: All frontend TypeScript and JavaScript code should be located under src/frontend/src/ and organized into components, pages, icons, stores, types, utils, hooks, services, and assets directories as per the specified directory layout.
Use React 18 with TypeScript for all UI components in the frontend.
Format all TypeScript and JavaScript code using the make format_frontend command.
Lint all TypeScript and JavaScript code using the make lint command.
Files:
src/frontend/src/constants/constants.tssrc/frontend/src/utils/styleUtils.ts
src/frontend/src/utils/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
All utility functions should be placed in the utils directory.
Files:
src/frontend/src/utils/styleUtils.ts
🧠 Learnings (2)
📚 Learning: 2025-07-18T18:25:54.486Z
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-07-18T18:25:54.486Z
Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new components
Applied to files:
src/backend/base/langflow/components/couchbase/__init__.pysrc/backend/base/langflow/components/clickhouse/__init__.pysrc/backend/base/langflow/components/FAISS/__init__.pysrc/backend/base/langflow/components/milvus/__init__.pysrc/backend/base/langflow/components/qdrant/__init__.pysrc/backend/base/langflow/components/vectara/__init__.pysrc/backend/base/langflow/components/redis/__init__.pysrc/backend/base/langflow/components/pinecone/__init__.pysrc/backend/base/langflow/components/cassandra/__init__.pysrc/backend/base/langflow/components/chroma/__init__.pysrc/backend/base/langflow/components/weaviate/__init__.pysrc/backend/base/langflow/components/upstash/__init__.pysrc/backend/base/langflow/components/supabase/__init__.py
📚 Learning: 2025-07-28T15:56:47.865Z
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/icons.mdc:0-0
Timestamp: 2025-07-28T15:56:47.865Z
Learning: Always use clear, recognizable, and consistent icon names for both backend and frontend (e.g., "AstraDB", "Postgres", "OpenAI").
Applied to files:
src/frontend/src/utils/styleUtils.ts
🧬 Code graph analysis (18)
src/backend/base/langflow/components/couchbase/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/couchbase/couchbase.py (1)
CouchbaseVectorStoreComponent(11-102)
src/backend/base/langflow/components/clickhouse/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/clickhouse/clickhouse.py (1)
ClickhouseVectorStoreComponent(17-135)
src/backend/base/langflow/components/mongodb/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/mongodb/mongodb_atlas.py (1)
MongoVectorStoreComponent(15-213)
src/backend/base/langflow/components/elastic/__init__.py (1)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)
src/backend/base/langflow/components/FAISS/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/FAISS/faiss.py (1)
FaissVectorStoreComponent(11-111)
src/backend/base/langflow/components/milvus/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/milvus/milvus.py (1)
MilvusVectorStoreComponent(16-115)
src/backend/base/langflow/components/qdrant/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/qdrant/qdrant.py (1)
QdrantVectorStoreComponent(16-109)
src/backend/base/langflow/components/pgvector/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/pgvector/pgvector.py (1)
PGVectorStoreComponent(10-72)
src/backend/base/langflow/components/vectara/__init__.py (3)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/vectara/vectara.py (1)
VectaraVectorStoreComponent(14-97)src/backend/base/langflow/components/vectara/vectara_rag.py (1)
VectaraRagComponent(7-164)
src/backend/base/langflow/components/redis/__init__.py (3)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/redis/redis.py (1)
RedisVectorStoreComponent(12-89)src/backend/base/langflow/components/redis/redis_chat.py (1)
RedisIndexChatMemory(10-43)
src/backend/base/langflow/components/pinecone/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/pinecone/pinecone.py (1)
PineconeVectorStoreComponent(10-111)
src/backend/base/langflow/components/cassandra/__init__.py (3)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/cassandra/cassandra.py (1)
CassandraVectorStoreComponent(16-264)src/backend/base/langflow/components/cassandra/cassandra_graph.py (1)
CassandraGraphVectorStoreComponent(18-238)
src/backend/base/langflow/components/chroma/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/chroma/chroma.py (1)
ChromaVectorStoreComponent(17-167)
src/backend/base/langflow/components/redis/redis_chat.py (2)
src/backend/base/langflow/base/memory/model.py (1)
LCChatMemoryComponent(11-38)src/backend/base/langflow/inputs/inputs.py (3)
MessageTextInput(205-256)SecretStrInput(285-340)StrInput(128-184)
src/backend/base/langflow/components/weaviate/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/weaviate/weaviate.py (1)
WeaviateVectorStoreComponent(10-89)
src/backend/base/langflow/components/upstash/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/upstash/upstash.py (1)
UpstashVectorStoreComponent(15-124)
src/backend/base/langflow/components/supabase/__init__.py (2)
src/backend/base/langflow/components/_importing.py (1)
import_mod(8-37)src/backend/base/langflow/components/supabase/supabase.py (1)
SupabaseVectorStoreComponent(10-76)
src/backend/base/langflow/components/redis/redis.py (4)
src/backend/base/langflow/base/vectorstores/model.py (3)
LCVectorStoreComponent(41-193)check_cached_vector_store(17-38)_prepare_ingest_data(107-123)src/backend/base/langflow/helpers/data.py (1)
docs_to_data(14-23)src/backend/base/langflow/inputs/inputs.py (4)
HandleInput(76-87)IntInput(343-375)SecretStrInput(285-340)StrInput(128-184)src/backend/base/langflow/schema/data.py (2)
Data(23-277)to_lc_document(139-149)
🔇 Additional comments (23)
src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json (1)
1201-1203: Module path verification completed — ready to approve
- Confirmed
astradb.pyexists atsrc/backend/base/langflow/components/datastax/astradb.py- Verified
class AstraDBVectorStoreComponentis declared (line 31)- No remaining references to the old
langflow.components.vectorstores.astradb.AstraDBVectorStoreComponentpath foundAll checks pass; changes look good.
src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json (1)
2713-2714: Module path migration verified – no stale references foundVerified that the module path
langflow.components.datastax.astradb.AstraDBVectorStoreComponentis declared insrc/backend/base/langflow/components/datastax/astradb.py(line 31) and that there are no remaining legacy references to the oldvectorstores.astradbpackage in the starter projects or elsewhere. Approving these changes.src/backend/base/langflow/components/pinecone/__init__.py (2)
19-30: LGTM: clean lazy-loader with cachingThe lazy import pattern is sound, errors are surfaced clearly, and imported symbols are cached in globals to avoid repeated imports.
1-35: Import path refactor verified – no stale Pinecone imports foundI ran a comprehensive search for both the old (
langflow.components.vectorstores.pinecone) and new (langflow.components.pinecone) import patterns across the entire codebase and found zero occurrences of the outdated path. All references now correctly point to the new subpackage. No further changes are needed.src/backend/base/langflow/components/couchbase/__init__.py (1)
19-30: LGTM: lazy import wrapper is consistent and robustThe pattern matches other components, with clear error messages and proper caching.
src/backend/base/langflow/components/cassandra/__init__.py (1)
1-35: No action needed: Backend and frontend icon keys for Cassandra components alignBoth Python component classes explicitly set
icon = "Cassandra", matching the only available icon mapping in the frontend. There is currently no separate “CassandraGraph” icon defined, so using"Cassandra"for both is correct.• src/backend/base/langflow/components/cassandra/cassandra.py (line 21):
icon = "Cassandra"
• src/backend/base/langflow/components/cassandra/cassandra_graph.py (line 22):icon = "Cassandra"
• src/frontend/src/utils/styleUtils.ts: icon key"Cassandra"
• src/frontend/src/icons/lazyIconImports.ts: mapping forCassandra→CassandraIcon
• src/frontend/src/icons/eagerIconImports.ts: mapping forCassandra→CassandraIconNo changes required.
src/backend/base/langflow/components/clickhouse/__init__.py (2)
1-35: LGTM: wrapper matches project patternDynamic map, caching, and public API exposure are correct.
1-35: Icon key consistency verified—no changes requiredThe backend component defines
icon = "Clickhouse"and the frontend mappings (in styleUtils, lazyIconImports, and eagerIconImports) all use the identical string
"Clickhouse". The casing and spelling match exactly, so icon rendering will work as expected.src/backend/base/langflow/components/vectara/__init__.py (2)
22-33: LGTM: dual-component lazy loader with clear APIExports both VectaraRagComponent and VectaraVectorStoreComponent; ordering and behavior look good.
1-35: Stalelangflow.components.vectorstoresImports Detected – Update to New Subpackage PathsSeveral backend tests and the starter‐project script continue importing from the old
langflow.components.vectorstoresnamespace. These will break now that each vector store lives in its own subpackage (e.g.pinecone,cassandra,clickhouse,vectara, etc.). Please update them to the new import paths. Icon mappings have been verified and require no changes.Affected locations:
- Tests under
src/backend/tests/unit/initial_setup/starter_projects/*andsrc/backend/base/langflow/initial_setup/starter_projects/vector_store_rag.pystill use:from langflow.components.vectorstores import AstraDBVectorStoreComponent- Tests in
src/backend/tests/unit/base/tools/test_vector_store_decorator.pyandsrc/backend/tests/integration/components/astra/test_astra_component.pyalso import:from langflow.components.vectorstores import AstraDBVectorStoreComponent- Unit tests in
src/backend/tests/unit/components/vectorstores/(e.g.test_chroma_vector_store_component.py,test_local_db_component.py,test_mongodb_atlas.py,test_graph_rag_component.py) import from:from langflow.components.vectorstores.<driver> import <Driver>VectorStoreComponent- Integration test
src/backend/tests/integration/test_dynamic_import_integration.pyrefers to"langflow.components.vectorstores"when cleaning modules.- The starter‐project Python script
src/backend/base/langflow/initial_setup/starter_projects/vector_store_rag.pyline 9 uses the old import.Recommended fixes:
- Replace each old import with its new subpackage path. For example:
(Adjust for Cassandra, ClickHouse, Chroma, LocalDB, MongoDB Atlas, Vectara, etc.)- from langflow.components.vectorstores import AstraDBVectorStoreComponent + from langflow.components.pinecone.pinecone import PineconeVectorStoreComponent- Update dynamic‐import cleanup in
test_dynamic_import_integration.pyto reference the new module names, or remove if no longer needed.- Confirm that all test fixtures and starter scripts reference the correct component classes under
langflow.components.<driver>.- No changes are required to frontend icon mappings for Pinecone, Couchbase, Clickhouse, Cassandra, or Vectara—they already match exactly.
⛔ Skipped due to learnings
Learnt from: CR PR: langflow-ai/langflow#0 File: .cursor/rules/testing.mdc:0-0 Timestamp: 2025-07-21T14:16:14.125Z Learning: Applies to src/backend/tests/**/*.py : Test backward compatibility across Langflow versions in backend Python tests by mapping component files to supported versions using 'VersionComponentMapping'.Learnt from: edwinjosechittilappilly PR: langflow-ai/langflow#0 File: :0-0 Timestamp: 2025-08-07T20:23:23.569Z Learning: Some Langflow starter project files and components still use `from loguru import logger` instead of the centralized structlog logger from `langflow.logging.logger`. These should be updated to ensure consistent structured logging across the entire codebase.Learnt from: CR PR: langflow-ai/langflow#0 File: .cursor/rules/backend_development.mdc:0-0 Timestamp: 2025-07-18T18:25:54.486Z Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/Learnt from: CR PR: langflow-ai/langflow#0 File: .cursor/rules/backend_development.mdc:0-0 Timestamp: 2025-07-18T18:25:54.486Z Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new componentssrc/backend/base/langflow/components/upstash/__init__.py (1)
1-16: LGTM: clean lazy-loader with clear public surfaceThe initializer follows the established pattern (future annotations, TYPE_CHECKING import, all, lazy getattr). Looks consistent with sibling components.
src/backend/base/langflow/components/pgvector/__init__.py (2)
1-16: LGTM: matches the shared lazy-import patternStructure and names are aligned with the rest of the components.
1-16: Verify icon mapping for PGVector componentUnrelated to this file but within this bundle: PGVectorStoreComponent sets icon = "cpu" (see pgvector/pgvector.py). Confirm this matches the exact frontend icon mapping; otherwise the node may render without an icon.
Would you like me to open a follow-up to sync the icon with the frontend mapping if needed?
src/backend/base/langflow/components/qdrant/__init__.py (1)
1-16: LGTM: lazy init and exports look correctPublic name and module mapping are accurate; mirrors other stores.
src/backend/base/langflow/components/elastic/__init__.py (1)
16-19: Alphabetical public exports: goodall order is alphabetical and matches coding guidelines; keep this consistent across new bundles.
src/backend/base/langflow/components/weaviate/__init__.py (1)
1-16: LGTM: consistent lazy-loader and API exposureMatches the pattern used elsewhere; TYPE_CHECKING and all are correct.
src/backend/base/langflow/components/supabase/__init__.py (2)
16-19: Lazy exports and naming look goodall is alphabetized as per guidelines, and the export surface matches the components provided in this package. Dynamic map keys also align with the module filenames.
16-19: Fix alphabetical ordering of_dynamic_importskeys in the root components__init__.pyThe automated check detected that the
_dynamic_importsdictionary in
src/backend/base/langflow/components/__init__.pyis not alphabetized. Please reorder its keys so that they appear in sorted order, for example:_dynamic_imports = { - "agents": AgentsComponent, - "data": DataComponent, - "processing": ProcessingComponent, - // … - "youtube": YouTubeComponent, - "zep": ZepComponent, - "wolframalpha": WolframAlphaComponent, + "aiml": AIMLComponent, + "agentql": AgentQLComponent, + "agents": AgentsComponent, + "amazon": AmazonComponent, + "anthropic": AnthropicComponent, + "apify": ApifyComponent, + "arxiv": ArXivComponent, + "azure": AzureComponent, + "baidu": BaiduComponent, + "bing": BingComponent, + "cloudflare": CloudflareComponent, + "composio": ComposioComponent, + "confluence": ConfluenceComponent, + "crewai": CrewaiComponent, + "custom_component": CustomComponent, + "data": DataComponent, + "datastax": DataStaxComponent, + "deepseek": DeepSeekComponent, + "docling": DoclingComponent, + "duckduckgo": DuckDuckGoComponent, + "elastic": ElasticComponent, + "exa": ExaComponent, + "firecrawl": FirecrawlComponent, + "git": GitComponent, + "glean": GleanComponent, + "google": GoogleComponent, + "groq": GroqComponent, + "helpers": HelpersComponent, + "homeassistant": HomeAssistantComponent, + "huggingface": HuggingFaceComponent, + "ibm": IBMComponent, + "icosacomputing": IcosaComputingComponent, + "input_output": InputOutputComponent, + "langchain_utilities": LangChainUtilitiesComponent, + "langwatch": LangWatchComponent, + "lmstudio": LMStudioComponent, + "maritalk": MaritalkComponent, + "mem0": Mem0Component, + "models": ModelsComponent, + "mistral": MistralComponent, + "mongodb": MongoDBComponent, + "needle": NeedleComponent, + "notdiamond": NotDiamondComponent, + "novita": NovitaComponent, + "nvidia": NVIDIAComponent, + "openai": OpenAIComponent, + "openrouter": OpenRouterComponent, + "ollama": OllamaComponent, + "perplexity": PerplexityComponent, + "pinecone": PineconeComponent, + "processing": ProcessingComponent, + "prototypes": PrototypesComponent, + "pgvector": PGVectorComponent, + "qdrant": QdrantComponent, + "redis": RedisComponent, + "sambanova": SambaNovaComponent, + "scrapegraph": ScrapeGraphComponent, + "searchapi": SearchAPIComponent, + "serpapi": SerpAPIComponent, + "serper": SerperComponent, + "supabase": SupabaseComponent, + "tavily": TavilyComponent, + "textsplitters": TextSplittersComponent, + "toolkits": ToolkitsComponent, + "tools": ToolsComponent, + "twelvelabs": TwelveLabsComponent, + "unstructured": UnstructuredComponent, + "vectorstores": VectorStoresComponent, + "vertexai": VertexAIComponent, + "vectara": VectaraComponent, + "weaviate": WeaviateComponent, + "wikipedia": WikipediaComponent, + "wolframalpha": WolframAlphaComponent, + "yahoosearch": YahooSearchComponent, + "youtube": YouTubeComponent, + "zep": ZepComponent, }• File to update:
src/backend/base/langflow/components/__init__.py([script report])
• No other__init__.pyexports failed the alphabetical check.Once keys are sorted, the provided shell script will pass without errors and ensure consistent ordering across components.
⛔ Skipped due to learnings
Learnt from: CR PR: langflow-ai/langflow#0 File: .cursor/rules/backend_development.mdc:0-0 Timestamp: 2025-07-18T18:25:54.486Z Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new componentsLearnt from: CR PR: langflow-ai/langflow#0 File: .cursor/rules/backend_development.mdc:0-0 Timestamp: 2025-07-18T18:25:54.486Z Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/src/backend/base/langflow/components/chroma/__init__.py (1)
14-16: Pattern matches the repo’s lazy import approachExport list is minimal and accurate, and the dynamic import mapping lines up with chroma.py.
src/backend/base/langflow/components/milvus/__init__.py (1)
14-16: LGTM on export surface and dynamic mappingPublic API is minimal and correct.
src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json (1)
2184-2187: FAISS component path update verified – ready to mergeAll checks passed successfully:
- No remaining references to the old
langflow.components.vectorstores.faiss.FaissVectorStoreComponentin the starter projects.- New metadata.module entry confirmed in
src/backend/base/langflow/initial_setup/starter_projects/Nvidia Remix.json(line 2186).FaissVectorStoreComponentclass defined insrc/backend/base/langflow/components/FAISS/faiss.py.src/backend/base/langflow/components/FAISS/__init__.pycorrectly imports and exposesFaissVectorStoreComponentvia__all__.src/frontend/src/constants/constants.ts (1)
766-781: No changes needed: “FAISS” casing matches existing component folderThe constants array must align exactly with the backend component directory names, which are case-sensitive. We’ve confirmed that there is a single folder named
FAISS(uppercase) and no lowercasefaissdirectory. Adding"faiss"to the list without a corresponding folder would break the bundler import logic.• All other entries (pinecone, weaviate, qdrant, etc.) match their folder names exactly
• TheFAISSentry correctly matchessrc/backend/base/langflow/components/FAISSIf you require case-insensitive matching in the future, consider introducing a canonicalization layer or aliases in your import logic rather than duplicating literal entries here.
src/backend/base/langflow/components/redis/__init__.py (1)
1-38: LGTM: Redis package lazy-loading is consistent with the new component structure.
- Exposes both RedisIndexChatMemory and RedisVectorStoreComponent via a clear dynamic map.
- Good use of TYPE_CHECKING to avoid import-time side effects.
- all ordering is already alphabetical.
No changes requested.
| def __getattr__(attr_name: str) -> Any: | ||
| """Lazily import MongoDB components on attribute access.""" | ||
| if attr_name not in _dynamic_imports: | ||
| msg = f"module '{__name__}' has no attribute '{attr_name}'" | ||
| raise AttributeError(msg) | ||
| try: | ||
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | ||
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | ||
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | ||
| raise AttributeError(msg) from e | ||
| globals()[attr_name] = result | ||
| return result | ||
|
|
There was a problem hiding this comment.
Fix broken lazy import: wrong package passed to import_mod (use name/package, not spec.parent).
Using spec.parent resolves to 'langflow.components', so import_mod attempts to import 'langflow.components.mongodb_atlas', which doesn't exist. The module is 'langflow.components.mongodb.mongodb_atlas'. This will raise and mask the real error behind an AttributeError at runtime.
Apply this diff to import from the correct package and keep the cached result:
- try:
- result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent)
+ try:
+ # Use the current package ('langflow.components.mongodb') as the import base
+ result = import_mod(attr_name, _dynamic_imports[attr_name], __name__)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def __getattr__(attr_name: str) -> Any: | |
| """Lazily import MongoDB components on attribute access.""" | |
| if attr_name not in _dynamic_imports: | |
| msg = f"module '{__name__}' has no attribute '{attr_name}'" | |
| raise AttributeError(msg) | |
| try: | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __spec__.parent) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result | |
| def __getattr__(attr_name: str) -> Any: | |
| """Lazily import MongoDB components on attribute access.""" | |
| if attr_name not in _dynamic_imports: | |
| msg = f"module '{__name__}' has no attribute '{attr_name}'" | |
| raise AttributeError(msg) | |
| try: | |
| # Use the current package ('langflow.components.mongodb') as the import base | |
| result = import_mod(attr_name, _dynamic_imports[attr_name], __name__) | |
| except (ModuleNotFoundError, ImportError, AttributeError) as e: | |
| msg = f"Could not import '{attr_name}' from '{__name__}': {e}" | |
| raise AttributeError(msg) from e | |
| globals()[attr_name] = result | |
| return result |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/mongodb/__init__.py around lines 19 to
31, the lazy importer is passing __spec__.parent to import_mod which resolves to
'langflow.components' and causes wrong module paths like
'langflow.components.mongodb_atlas'; change the parent arg to __name__ (or
__package__) so import_mod imports 'langflow.components.mongodb.mongodb_atlas'
correctly, ensure you still cache the imported result by assigning it into
globals()[attr_name] after a successful import, and keep the existing exception
handling but raise an AttributeError from the original exception.
| def build_message_history(self) -> Memory: | ||
| kwargs = {} | ||
| password: str | None = self.password | ||
| if self.key_prefix: | ||
| kwargs["key_prefix"] = self.key_prefix | ||
| if password: | ||
| password = parse.quote_plus(password) | ||
|
|
||
| url = f"redis://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}" | ||
| return RedisChatMessageHistory(session_id=self.session_id, url=url, **kwargs) |
There was a problem hiding this comment.
Fix URL construction: percent-encode credentials and build auth segment correctly
Currently, password is percent-encoded into a local variable but not used; raw credentials are inserted into the URL, and empty username/password produce an invalid ":@" segment. Build the auth segment conditionally and encode credentials safely.
Apply this diff:
def build_message_history(self) -> Memory:
- kwargs = {}
- password: str | None = self.password
- if self.key_prefix:
- kwargs["key_prefix"] = self.key_prefix
- if password:
- password = parse.quote_plus(password)
-
- url = f"redis://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
- return RedisChatMessageHistory(session_id=self.session_id, url=url, **kwargs)
+ kwargs = {}
+ if self.key_prefix:
+ kwargs["key_prefix"] = self.key_prefix
+
+ # Percent-encode credentials for safe URL embedding
+ username = str(self.username) if self.username else ""
+ password = str(self.password) if self.password else ""
+ enc_user = parse.quote(username, safe="") if username else ""
+ enc_pass = parse.quote(password, safe="") if password else ""
+
+ if enc_user and enc_pass:
+ auth = f"{enc_user}:{enc_pass}@"
+ elif enc_user:
+ auth = f"{enc_user}@"
+ elif enc_pass:
+ auth = f":{enc_pass}@"
+ else:
+ auth = ""
+
+ db = str(self.database).lstrip("/")
+ url = f"redis://{auth}{self.host}:{self.port}/{db}"
+ return RedisChatMessageHistory(session_id=str(self.session_id or ""), url=url, **kwargs)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def build_message_history(self) -> Memory: | |
| kwargs = {} | |
| password: str | None = self.password | |
| if self.key_prefix: | |
| kwargs["key_prefix"] = self.key_prefix | |
| if password: | |
| password = parse.quote_plus(password) | |
| url = f"redis://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}" | |
| return RedisChatMessageHistory(session_id=self.session_id, url=url, **kwargs) | |
| def build_message_history(self) -> Memory: | |
| kwargs = {} | |
| if self.key_prefix: | |
| kwargs["key_prefix"] = self.key_prefix | |
| # Percent-encode credentials for safe URL embedding | |
| username = str(self.username) if self.username else "" | |
| password = str(self.password) if self.password else "" | |
| enc_user = parse.quote(username, safe="") if username else "" | |
| enc_pass = parse.quote(password, safe="") if password else "" | |
| if enc_user and enc_pass: | |
| auth = f"{enc_user}:{enc_pass}@" | |
| elif enc_user: | |
| auth = f"{enc_user}@" | |
| elif enc_pass: | |
| auth = f":{enc_pass}@" | |
| else: | |
| auth = "" | |
| db = str(self.database).lstrip("/") | |
| url = f"redis://{auth}{self.host}:{self.port}/{db}" | |
| return RedisChatMessageHistory(session_id=str(self.session_id or ""), url=url, **kwargs) |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/redis/redis_chat.py around lines 34 to
43, the URL is built with raw credentials and leaves an invalid ":@" when
username/password are empty; the percent-encoded password stored in the local
variable is never used. Fix by percent-encoding both username and password (if
present) using urllib.parse.quote_plus, build an auth segment only when either
encoded username or encoded password exists (e.g. "user:pass@" or "user@" or
":pass@" as appropriate), and then construct the URL using that auth segment
instead of inserting raw self.username/self.password; keep key_prefix handling
and other kwargs unchanged. Ensure no stray ":@" appears when credentials are
absent.
💡 Verification agent
🧩 Analysis chain
Quick self-check script for URL construction logic
Verify there are no remaining quote_plus usages and sanity-check the URL building across typical credential combinations.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Ensure the old patterns are gone
rg -n "quote_plus" src/backend/base/langflow/components/redis/redis_chat.py || echo "OK: no quote_plus"
rg -nP 'redis://\{self\.username\}:\{self\.password\}@' src/backend/base/langflow/components/redis/redis_chat.py && { echo "Found raw credential f-string; please update."; exit 1; } || echo "OK: raw f-string not found"
# Sanity-check the encoding logic with representative cases (standalone snippet)
python - <<'PY'
from urllib import parse
def build_url(username, password, host="localhost", port=6379, db="0"):
enc_user = parse.quote(username, safe="") if username else ""
enc_pass = parse.quote(password, safe="") if password else ""
if enc_user and enc_pass:
auth = f"{enc_user}:{enc_pass}@"
elif enc_user:
auth = f"{enc_user}@"
elif enc_pass:
auth = f":{enc_pass}@"
else:
auth = ""
return f"redis://{auth}{host}:{port}/{str(db).lstrip('/')}"
cases = [
("", "", "redis://localhost:6379/0"),
("user", "", "redis://user@localhost:6379/0"),
("", "p@/w:rd", "redis://:%70%40%2Fw%3Ard@localhost:6379/0"),
("us@er", "p@ss", "redis://us%40er:p%40ss@localhost:6379/0"),
]
for u,p,exp in cases:
url = build_url(u,p)
print(u, p, "->", url, "OK" if url==exp else f"Mismatch (expected {exp})")
PYLength of output: 473
Update Redis URL construction to properly encode credentials
The verification script identified two remaining issues in redis_chat.py that must be addressed:
- The code still uses
parse.quote_plus, which isn’t consistent with how Redis URIs handle special characters, and - The f-string at line 42 interpolates raw
self.username/self.password, allowing invalid or insecure URLs when credentials contain characters like@,:, or/.
Locations needing fixes (src/backend/base/langflow/components/redis/redis_chat.py):
- Line 40:
password = parse.quote_plus(password) - Line 42:
url = f"redis://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
Suggested patch:
--- a/src/backend/base/langflow/components/redis/redis_chat.py
+++ b/src/backend/base/langflow/components/redis/redis_chat.py
@@ def build_message_history(self) -> Memory:
- kwargs = {}
- password: str | None = self.password
- if self.key_prefix:
- kwargs["key_prefix"] = self.key_prefix
- if password:
- password = parse.quote_plus(password)
-
- url = f"redis://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}"
- return RedisChatMessageHistory(session_id=self.session_id, url=url, **kwargs)
+ from urllib import parse
+
+ # Prepare kwargs
+ kwargs: dict[str, str] = {}
+ if self.key_prefix:
+ kwargs["key_prefix"] = self.key_prefix
+
+ # URL-encode credentials to handle special characters
+ user_enc = parse.quote(self.username or "", safe="") # empty if no username
+ pass_enc = parse.quote(self.password or "", safe="") # empty if no password
+ auth = ""
+ if user_enc or pass_enc:
+ auth = f"{user_enc}:{pass_enc}@"
+
+ url = f"redis://{auth}{self.host}:{self.port}/{self.database}"
+ return RedisChatMessageHistory(session_id=self.session_id, url=url, **kwargs)These changes remove all quote_plus calls, ensure both username and password are percent-encoded per RFC 3986 (using parse.quote with safe=""), and eliminate raw credential interpolation.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| def build_message_history(self) -> Memory: | |
| kwargs = {} | |
| password: str | None = self.password | |
| if self.key_prefix: | |
| kwargs["key_prefix"] = self.key_prefix | |
| if password: | |
| password = parse.quote_plus(password) | |
| url = f"redis://{self.username}:{self.password}@{self.host}:{self.port}/{self.database}" | |
| return RedisChatMessageHistory(session_id=self.session_id, url=url, **kwargs) | |
| def build_message_history(self) -> Memory: | |
| from urllib import parse | |
| # Prepare kwargs | |
| kwargs: dict[str, str] = {} | |
| if self.key_prefix: | |
| kwargs["key_prefix"] = self.key_prefix | |
| # URL-encode credentials to handle special characters | |
| user_enc = parse.quote(self.username or "", safe="") # empty if no username | |
| pass_enc = parse.quote(self.password or "", safe="") # empty if no password | |
| auth = "" | |
| if user_enc or pass_enc: | |
| auth = f"{user_enc}:{pass_enc}@" | |
| url = f"redis://{auth}{self.host}:{self.port}/{self.database}" | |
| return RedisChatMessageHistory(session_id=self.session_id, url=url, **kwargs) |
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/redis/redis_chat.py around lines 34 to
43, the code currently uses parse.quote_plus and interpolates raw
self.username/self.password into the Redis URL; replace the quote_plus call with
urllib.parse.quote(..., safe="") and percent-encode both username and password
into local variables (e.g., user_enc and pass_enc), then build the url using
those encoded variables (e.g.,
f"redis://{user_enc}:{pass_enc}@{self.host}:{self.port}/{self.database}"),
ensuring you handle None/empty username or password appropriately (omit
credentials if missing).
| Path("docuemnts.txt").write_text(str(documents), encoding="utf-8") | ||
|
|
There was a problem hiding this comment.
Remove debug file write; it leaks data and breaks sandboxed environments.
Writing every ingested document set to a local file ("docuemnts.txt") is a security/PII risk, creates side effects, and the filename is misspelled. Also, Path is only imported for this. Remove both.
Apply this diff:
-from pathlib import Path
@@
- Path("docuemnts.txt").write_text(str(documents), encoding="utf-8")Also applies to: 1-1
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/redis/redis.py around lines 53-54,
remove the debug file write Path("docuemnts.txt").write_text(str(documents),
encoding="utf-8") (note the misspelled filename) and also remove the unused Path
import since it is only present for that debug write; ensure no other code
depends on the file or Path, and run linters to remove any leftover
unused-import warnings.
| { display_name: "Cassandra", name: "cassandra", icon: "Cassandra" }, | ||
| { display_name: "Chroma", name: "chroma", icon: "Chroma" }, | ||
| { display_name: "ClickHouse", name: "clickhouse", icon: "Clickhouse" }, |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Verify icon names exist and match the actual exported icon identifiers.
Added bundles look right. Two checks to prevent runtime "missing icon" fallbacks:
- "ClickHouse" uses icon "Clickhouse". Please confirm the actual icon component/export is "Clickhouse" (same casing). If the asset is "ClickHouse" instead, the icon won't load.
- "pgvector" uses a generic "cpu" Lucide icon. That's fine but confirm we intend a generic icon here (branding may warrant a dedicated icon later).
Run this script to validate icons exist via any of: eager map, lazy icon imports, font-awesome set, or Lucide:
Also applies to: 258-258, 264-266, 288-288, 290-291, 301-304, 310-310, 314-315, 317-317
🏁 Script executed:
#!/bin/bash
# Validates that each SIDEBAR_BUNDLES icon resolves via one of our icon sources.
set -euo pipefail
icons=(Cassandra Chroma Clickhouse Couchbase ElasticsearchStore FAISS Milvus MongoDB cpu Pinecone Qdrant Supabase Upstash Weaviate)
echo "Checking icons in frontend icon sources..."
for icon in "${icons[@]}"; do
found=0
# Eager map
rg -nP "export const eagerLoadedIconsMap\s*=\s*{(?s).*?\b$icon\b" -g "src/frontend/src/utils/styleUtils.ts" >/dev/null && found=1
# Lazy icon imports mapping
rg -nP "\b$icon\b" src/frontend/src/icons/lazyIconImports.ts >/dev/null 2>&1 && found=1
# FontAwesome registry
rg -nP "\b$icon\b" src/frontend/src/icons/fontAwesomeIcons.ts >/dev/null 2>&1 && found=1
# Node icon to display map alternative names
rg -nP "nodeIconToDisplayIconMap\s*:\s*Record<.*?{(?s).*?\b$icon\b" src/frontend/src/utils/styleUtils.ts >/dev/null && found=1
# Lucide dynamic map (converted to kebab-case)
kebab=$(python - <<'PY'
name = "$icon"
name = name.replace("Icon","")
import re
kebab = re.sub(r'([a-z])([A-Z])', r'\1-\2', name)
kebab = re.sub(r'(\d)', r'-\1', kebab)
kebab = re.sub(r'\s+', '-', kebab).lower()
print(kebab)
PY
)
rg -nP "\b$kebab\b" node_modules/lucide-react/dynamicIconImports.d.ts >/dev/null 2>&1 && found=1 || true
if [[ $found -eq 1 ]]; then
echo "OK: $icon"
else
echo "MISSING ICON: $icon" >&2
fi
doneLength of output: 8092
Missing or mismatched icons in SIDEBAR_BUNDLES
The validation script shows that several icons aren’t resolving in any of our icon sources (eager map, lazy imports, FontAwesome registry, nodeIconToDisplayIconMap, or Lucide dynamic imports):
-
FAISS
No entry found—add a FAISS icon toeagerLoadedIconsMap,lazyIconImports.ts, orfontAwesomeIcons.ts, or confirm a Lucide icon (faiss) exists and include it in our dynamic imports. -
cpu
Intended as a generic Lucide icon. The current kebab-case conversion in the script is broken, but you must still verify/import the Lucide ‘cpu’ icon (kebab-casecpu) intolazyIconImports.tsor another registry so it resolves. -
Qdrant
Missing from all sources—provide a Qdrant icon or choose an appropriate fallback.
The ClickHouse entry (icon: "Clickhouse") was found in lazyIconImports.ts and matches the export name, so no change needed there.
Please address these missing icons to prevent runtime fallback errors.
Also applies to bundles defined at lines 258, 264–266, 288, 290–291, 301–304, 310, 314–315, 317 in src/frontend/src/utils/styleUtils.ts.
🤖 Prompt for AI Agents
In src/frontend/src/utils/styleUtils.ts around lines 250–252 (and also check
bundles at 258, 264–266, 288, 290–291, 301–304, 310, 314–315, 317), several
sidebar bundle icons are missing or mismatched: add a FAISS icon entry by
exporting/importing it in eagerLoadedIconsMap or lazyIconImports.ts or
registering it in fontAwesomeIcons.ts (or confirm a Lucide export and include it
in dynamic imports); ensure the generic Lucide 'cpu' icon is available under the
kebab-case name 'cpu' by adding an import/export in lazyIconImports.ts or the
Lucide dynamic import map; and provide a Qdrant icon entry similarly (or choose
a suitable fallback) so these icons resolve at runtime; keep the existing
ClickHouse mapping as-is.
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project status has failed because the head coverage (3.80%) is below the target coverage (10.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #9486 +/- ##
=======================================
Coverage 33.80% 33.80%
=======================================
Files 1196 1196
Lines 56386 56386
Branches 5335 5335
=======================================
+ Hits 19063 19064 +1
+ Misses 37253 37252 -1
Partials 70 70
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
* 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 <ericrhare@gmail.com> Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com>
…ing (#9192) * 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 <ericrhare@gmail.com> 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 <edwin.jose@datastax.com> Co-authored-by: Eric Hare <ericrhare@gmail.com> Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com>


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.
Summary by CodeRabbit
New Features
UI
Starter Projects
Refactor