Skip to content

Conversation

@ogabrielluiz
Copy link
Contributor

@ogabrielluiz ogabrielluiz commented Jun 3, 2025

The main goal here is to not require a db connection for a flow to run. It does feel a bit hacky (because we are checking for the existence of a table) but it works. The best solution could involve a new config but there are edge cases that would make it not work as well.

Database Enhancements:

  • Added _is_database_available method and _database_available property to DatabaseService to check if the database is operational by verifying the presence of a "message" table. This ensures components can adapt to database availability dynamically. [1] [2]
  • Updated the teardown method in DatabaseService to safely dispose of the database engine and reset it to None during cleanup.

Component Updates:

  • Introduced _is_database_available method in Component to integrate database availability checks into the _should_skip_message logic, ensuring messages are only processed when the database is accessible.
  • Added _database_available attribute in the Component class to store the database state.

Testing Improvements:

  • Added new tests for AgentComponent to validate its behavior with OpenAI and Anthropic models, including scenarios using the CalculatorToolComponent. These tests ensure compatibility and correctness across different models.
  • Renamed TestAgentComponent to TestAgentComponentWithoutClient for clarity in distinguishing test classes.

Miscellaneous:

  • Updated the blockbuster function in conftest.py to include additional modules and functions for blocking

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 3, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update introduces database availability checks into the Component class, leveraging new logic in the DatabaseService to track the presence of a required table. The changes also add new asynchronous tests for agent components with calculator tools and various LLMs, and extend test configuration to block additional functions during testing.

Changes

File(s) Change Summary
src/backend/base/langflow/custom/custom_component/component.py Added _is_database_available method, _database_available attribute, and database check in _should_skip_message.
src/backend/base/langflow/services/database/service.py Added engine and _database_available attributes, async _is_database_available method, and database_available property; updated run_migrations and teardown to manage availability and engine state.
src/backend/tests/conftest.py Extended blockbuster fixture to allow blocking in additional Alembic and dotenv-related functions during tests.
src/backend/tests/unit/components/agents/test_agent_component.py Renamed TestAgentComponent to TestAgentComponentWithoutClient; added three async test methods for agent/calculator/LLM integration.

Sequence Diagram(s)

sequenceDiagram
    participant Component
    participant DatabaseService

    Component->>DatabaseService: get_db_service().database_available
    DatabaseService-->>Component: Return True if "message" table exists, else False

    Component->>Component: _should_skip_message(message)
    alt Database not available
        Component-->>Component: Return True (skip message)
    else Database available
        Component-->>Component: Continue normal processing
    end
Loading

Possibly related PRs

Suggested labels

size:L, lgtm

Suggested reviewers

  • jordanrfrazier
  • edwinjosechittilappilly
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch deactivate-db-in-agent

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 3, 2025
@ogabrielluiz ogabrielluiz marked this pull request as ready for review July 1, 2025 11:50
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 1, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 1, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/backend/base/langflow/services/database/service.py (2)

73-73: Consider state refresh mechanisms beyond migrations.

The initialization to False is appropriately conservative. However, consider implementing mechanisms to refresh this state when database connectivity changes outside of the migration process.


75-84: Consider more comprehensive database health checks.

The implementation correctly checks table existence, but using only the "message" table as a database availability indicator may be insufficient. Consider:

  1. Comprehensive health check: Check for multiple critical tables or perform a simple query
  2. Error handling: Add exception handling for database connectivity issues
  3. Efficiency: Consider caching the connection or using the existing session

Example improvement:

 async def _is_database_available(self) -> bool:
-    async with self.with_session() as session, session.bind.connect() as conn:
-        # Use run_sync to inspect the connection
-        def check_tables(conn):
-            inspector = inspect(conn)
-            return "message" in inspector.get_table_names()
-
-        self._database_available = await conn.run_sync(check_tables)
+    try:
+        async with self.with_session() as session, session.bind.connect() as conn:
+            def check_tables(conn):
+                inspector = inspect(conn)
+                required_tables = ["message", "user", "flow"]
+                return all(table in inspector.get_table_names() for table in required_tables)
+            
+            self._database_available = await conn.run_sync(check_tables)
+    except Exception:
+        self._database_available = False
     return self._database_available
src/backend/tests/unit/components/agents/test_agent_component.py (1)

155-189: LGTM: Robust Anthropic model testing with proper error handling.

The test provides comprehensive coverage of Anthropic models with excellent error handling and detailed failure reporting. The try/catch pattern appropriately handles potential API failures.

Consider reducing code duplication between test classes.

The test methods in TestAgentComponentWithoutClient are nearly identical to those in TestAgentComponentWithClient. Consider extracting common test logic into a shared base method or mixin to improve maintainability.

class AgentTestMixin:
    async def _test_agent_with_calculator(self, api_key_env_var: str, llm_type: str):
        # Common test logic here
        pass
    
    async def _test_agent_with_all_models(self, models: list, api_key_env_var: str, llm_type: str):
        # Common test logic here
        pass
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f835a6b and 9743632.

📒 Files selected for processing (4)
  • src/backend/base/langflow/custom/custom_component/component.py (3 hunks)
  • src/backend/base/langflow/services/database/service.py (5 hunks)
  • src/backend/tests/conftest.py (1 hunks)
  • src/backend/tests/unit/components/agents/test_agent_component.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
`src/backend/**/*.py`: Run make format_backend to format Python code early and often Run make lint to check for linting issues in backend Python code

src/backend/**/*.py: Run make format_backend to format Python code early and often
Run make lint to check for linting issues in backend Python code

📄 Source: CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

List of files the instruction was applied to:

  • src/backend/tests/conftest.py
  • src/backend/base/langflow/custom/custom_component/component.py
  • src/backend/base/langflow/services/database/service.py
  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/tests/**/*.py`: Unit tests for backend code should be located in 's...

src/backend/tests/**/*.py: Unit tests for backend code should be located in 'src/backend/tests/' and organized by component subdirectory for component tests.
Test files should use the same filename as the component with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Skip client creation in tests by marking them with '@pytest.mark.noclient' when the 'client' fixture is not needed.
Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/conftest.py
  • src/backend/tests/unit/components/agents/test_agent_component.py
`{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/...

{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py}: Each test should have a clear docstring explaining its purpose.
Complex test setups should be commented, and mock usage should be documented within the test code.
Expected behaviors should be explicitly stated in test docstrings or comments.
Create comprehensive unit tests for all new components.
Test both sync and async code paths in components.
Mock external dependencies appropriately in tests.
Test error handling and edge cases in components.
Validate input/output behavior in tests.
Test component initialization and configuration.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/conftest.py
  • src/backend/tests/unit/components/agents/test_agent_component.py
`{src/backend/tests/**/*.py,tests/**/*.py}`: Use '@pytest.mark.asyncio' for asyn...

{src/backend/tests/**/*.py,tests/**/*.py}: Use '@pytest.mark.asyncio' for async test functions.
Test queue operations in async tests using 'asyncio.Queue' and non-blocking put/get methods.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests.
Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Each test should ensure proper resource cleanup, especially in async fixtures using 'try/finally' and cleanup methods.
Test that operations respect timeout constraints and assert elapsed time is within tolerance.
Test Langflow's 'Message' objects and chat functionality by asserting correct properties and structure.
Use predefined JSON flows and utility functions for flow testing (e.g., 'create_flow', 'build_flow', 'get_build_events', 'consume_and_assert_stream').
Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Use 'MockLanguageModel' for testing language model components without external API calls.
Use 'anyio' and 'aiofiles' for async file operations in tests.
Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Test component configuration updates by asserting changes in build config dictionaries.
Test real-time event streaming endpoints by consuming NDJSON event streams and validating event structure.
Test backward compatibility across Langflow versions by mapping component files to supported versions using 'VersionComponentMapping'.
Test webhook endpoints by posting payloads and asserting correct processing and status codes.
Test error handling by monkeypatching internal functions to raise exceptions and asserting correct error responses.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/conftest.py
  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/**/*component*.py`: In your Python component class, set the `icon` attribute to a string matching the frontend icon mapping exactly (case-sensitive).

src/backend/**/*component*.py: In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

📄 Source: CodeRabbit Inference Engine (.cursor/rules/icons.mdc)

List of files the instruction was applied to:

  • src/backend/base/langflow/custom/custom_component/component.py
  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/tests/unit/components/**/*.py`: Mirror the component directory stru...

src/backend/tests/unit/components/**/*.py: Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Provide file_names_mapping in tests for backward compatibility version testing
Create comprehensive unit tests for all new components
Use the client fixture from conftest.py for FastAPI API endpoint tests
Test authenticated FastAPI endpoints using logged_in_headers in tests

📄 Source: CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/tests/unit/**/*.py`: Use in-memory SQLite for database tests Test c...

src/backend/tests/unit/**/*.py: Use in-memory SQLite for database tests
Test component integration within flows using create_flow, build_flow, and get_build_events utilities
Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs

📄 Source: CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/**/components/**/*.py`: In your Python component class, set the `icon` attribute to a string matching the frontend icon mapping exactly (case-sensitive).

src/backend/**/components/**/*.py: In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

📄 Source: CodeRabbit Inference Engine (.cursor/rules/icons.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test component configuration updates by asserting changes in build config dictionaries.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: After backend restart, old components will show 'Updates Available' in the UI
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Create comprehensive unit tests for all new components
src/backend/tests/conftest.py (10)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/**/*.py : Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use 'anyio' and 'aiofiles' for async file operations in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Mock external dependencies appropriately in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test error handling by monkeypatching internal functions to raise exceptions and asserting correct error responses.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use '@pytest.mark.asyncio' for async test functions.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use the client fixture from conftest.py for FastAPI API endpoint tests
src/backend/base/langflow/custom/custom_component/component.py (5)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update __init__.py with alphabetical imports when adding new components
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Implement async component methods using async def and await for asynchronous operations
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
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-06-30T14:39:17.428Z
Learning: Applies to src/backend/base/langflow/services/database/models/**/*.py : Place database models in src/backend/base/langflow/services/database/models/ and its subdirectories
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's 'Message' objects and chat functionality by asserting correct properties and structure.
src/backend/tests/unit/components/agents/test_agent_component.py (15)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Create comprehensive unit tests for all new components
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/**/*.py : Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test component configuration updates by asserting changes in build config dictionaries.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test backward compatibility across Langflow versions by mapping component files to supported versions using 'VersionComponentMapping'.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Test files should use the same filename as the component with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test both sync and async code paths in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use the client fixture from conftest.py for FastAPI API endpoint tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test component initialization and configuration.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Test authenticated FastAPI endpoints using logged_in_headers in tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/**/*.py : Test component integration within flows using create_flow, build_flow, and get_build_events utilities
🧬 Code Graph Analysis (2)
src/backend/base/langflow/custom/custom_component/component.py (4)
src/backend/base/langflow/services/deps.py (1)
  • get_db_service (133-142)
src/backend/base/langflow/schema/message.py (2)
  • Message (38-288)
  • ErrorMessage (381-467)
src/backend/base/langflow/graph/utils.py (1)
  • has_chat_output (209-212)
src/backend/base/langflow/graph/graph/base.py (1)
  • get_vertex_neighbors (1790-1808)
src/backend/tests/unit/components/agents/test_agent_component.py (4)
src/backend/tests/base.py (1)
  • ComponentTestBaseWithoutClient (163-164)
src/backend/base/langflow/components/tools/calculator.py (1)
  • CalculatorToolComponent (15-103)
src/backend/base/langflow/components/agents/agent.py (1)
  • message_response (69-115)
src/backend/base/langflow/base/agents/agent.py (1)
  • message_response (81-87)
🔇 Additional comments (12)
src/backend/base/langflow/services/database/service.py (4)

42-42: LGTM: Explicit initialization improves clarity.

The explicit initialization of engine to None provides better defensive programming, ensuring the attribute always exists even if engine creation fails.


86-88: LGTM: Clean property implementation.

The read-only property correctly encapsulates the private _database_available attribute following standard Python patterns.


502-504: LGTM: Improved error handling in teardown.

The null check prevents errors when disposing an already-disposed engine, and resetting to None ensures clean state for potential reinitialization.


394-394: Database availability integration confirmed for components

Verified that custom components correctly use the refreshed state after migrations:

  • src/backend/base/langflow/custom/custom_component/component.py
    _is_database_available() returns get_db_service().database_available
    _should_skip_message() uses this method to gate message handling

No further changes required.

src/backend/tests/conftest.py (1)

77-80: LGTM: Appropriate test isolation for database functionality.

The additional blocking rules for Alembic migration internals and dotenv functions are well-justified given the new database availability checks and migration handling. These rules help isolate tests from file system operations during database migrations.

src/backend/base/langflow/custom/custom_component/component.py (4)

35-35: LGTM: Clean service dependency import.

The import follows the established dependency injection pattern and is correctly placed for use in the database availability check.


163-163: LGTM: Proper attribute initialization.

The database availability attribute is correctly typed and follows the established pattern for private attributes in the Component class.


1341-1343: LGTM: Clean delegation pattern.

The method properly delegates database availability checking to the service layer and follows the established private method conventions.


1352-1352: LGTM: Correct integration of database availability check.

The addition of the database availability condition properly ensures message processing is skipped when the database is unavailable, aligning with the PR's goal of making components responsive to database state.

src/backend/tests/unit/components/agents/test_agent_component.py (3)

23-23: LGTM: Clear class rename following established patterns.

The rename to TestAgentComponentWithoutClient properly follows the base class pattern and clearly distinguishes the test context from the client-based tests.


104-126: LGTM: Well-structured agent integration test.

The test properly uses pytest markers for external API testing, follows established patterns for component testing, and validates the core agent-calculator integration functionality.


128-153: LGTM: Comprehensive model compatibility testing.

The test thoroughly validates agent functionality across all OpenAI models with proper test isolation, error collection, and detailed failure reporting.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 1, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 1, 2025
@ogabrielluiz ogabrielluiz force-pushed the deactivate-db-in-agent branch from 2f5c623 to 75ce509 Compare July 1, 2025 12:05
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 1, 2025
and not self.is_connected_to_chat_output()
and not isinstance(message, ErrorMessage)
)
) or not self._is_database_available()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not having the database available necessarily mean the message should be skipped? e.g. this would also now skip sending the message to the event manager

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Not having access to the database means there's no API.

Ideally we would have an interface that could be replaced by some storage using a config

else:
self.alembic_log_path = Path(langflow_dir) / alembic_log_file

self._database_available = False
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Perhaps this is in a follow up PR)

Do you anticipate adding a new config to indicate "No database", or does not setting DATABASE_URL imply no database? Either way, we'll need some changes in the init here to account for that, especially around the create_ methods.

Copy link
Contributor Author

@ogabrielluiz ogabrielluiz Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be easier for sure. My solution is a hacky one. Perhaps checking for the var first, then checking for the message table would be better.

I'll try to refactor the settings soon and then we can have settings specifically for the initialization, allowing us to skip steps if we so desire

logger.debug("Alembic not initialized")
should_initialize_alembic = True
await asyncio.to_thread(self._run_migrations, should_initialize_alembic, fix)
self._database_available = await self._is_database_available()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this is checked here rather than in init?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function checks if the message table exists, so in init it would not exist the first time Langflow runs.

@github-actions github-actions bot removed the enhancement New feature or request label Jul 9, 2025
…ponent_config parameter in flow build functions for enhanced customization
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@ogabrielluiz ogabrielluiz changed the title feat: Skip message creation if database is not available feat: add option to skip message persistence in Component Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 14, 2025
stored_message = await self._store_message(message)
if self._is_database_available():
stored_message = await self._store_message(message)
self._stored_message_id = stored_message.id
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe this is being used anymore

stored_message.text = complete_message
stored_message = await self._update_stored_message(stored_message)
if self._is_database_available():
stored_message = await self._update_stored_message(stored_message)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this mutate the stored_message variable? I assume it does based on the context, but what consequences does that have downstream?

First time looking at this area, so I'm a bit confused to the message assignment -- we've got message, stored_message, complete_message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants