Skip to content

fix: include Google as a default partner bundle - #14220

Merged
erichare merged 9 commits into
release-1.12.0from
fix/le-1974-google-partner-bundle
Jul 23, 2026
Merged

fix: include Google as a default partner bundle#14220
erichare merged 9 commits into
release-1.12.0from
fix/le-1974-google-partner-bundle

Conversation

@erichare

@erichare erichare commented Jul 23, 2026

Copy link
Copy Markdown
Member

Summary

  • graduate the Google components from the opt-in lfx-bundles[google] extra to the standalone lfx-google partner bundle
  • include lfx-google in the default Langflow distribution so Gemini always installs langchain-google-genai
  • preserve the existing google bundle name and compatibility shim so saved component IDs remain stable
  • update release inventories, the enterprise bundle profile, documentation, and the lfx-bundles patch release metadata

Validation

  • focused release, bundle, and Google component suite: 96 passed, 8 skipped
  • Ruff check and format check
  • extension manifest validation
  • release-plan and bundle-profile validation
  • built lfx-google, lfx-bundles, and default langflow wheels; verified default wheel metadata requires lfx-google>=0.1.0,<1.0.0
  • all pre-commit hooks passed, including secret scanning and extension migration checks

Jira

Summary by CodeRabbit

  • New Features
    • Introduced the standalone Google (Gemini/BigQuery) bundle with Gmail, Google Drive (load/search), OAuth token generation, Google Search (Core/Serper), plus Gemini model + embeddings support.
  • Documentation
    • Updated Google bundle docs for Langflow 1.12.0 and clarified standalone installation.
  • Bug Fixes
    • Improved Google/Gemini model selection behavior and enhanced input/error handling across Google components (including OAuth flow).
  • Tests
    • Added and updated unit/regression coverage for the new Google bundle and compatibility behaviors.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6be43e45-f4ac-4fd8-ac30-83d4df283307

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

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Google components are graduated into a standalone lfx-google extension bundle. Packaging, workspace registration, compatibility imports, release profiles, component localization, tests, dependency metadata, and documentation are updated accordingly.

Changes

Google bundle graduation

Layer / File(s) Summary
Google integrations and component contracts
src/bundles/google/src/lfx_google/components/google/*, src/backend/base/langflow/locales/en.json
Adds BigQuery, Drive, Google Search, Serper, and related Google component contracts, API integrations, outputs, validation, and localized metadata.
Gemini and OAuth behavior
src/bundles/google/src/lfx_google/components/google/google_generative_ai*.py, src/bundles/google/src/lfx_google/components/google/google_oauth_token.py
Updates Gemini model discovery and tool filtering, adds embeddings, and changes OAuth scope validation and installed-app authorization handling.
Extension packaging and exports
src/bundles/google/pyproject.toml, src/bundles/google/src/lfx_google/*, src/bundles/google/README.md
Defines the standalone package, extension manifest, entry point, exports, and development documentation.
Workspace and compatibility migration
pyproject.toml, src/bundles/lfx-bundles/*, src/lfx/src/lfx/components/google/*, scripts/migrate/consolidate_bundles.py, docs/docs/*
Adds lfx-google to the workspace, preserves the Google compatibility extra, repoints legacy imports, updates aggregate extras, and changes installation documentation.
Release profiles and validation
scripts/ci/*, src/lfx/src/lfx/_assets/component_index.json, src/backend/base/langflow/initial_setup/starter_projects/*
Adds lfx-google to profiles and release contracts, updates lock data and inventory checks, and pins Google-related dependency metadata.
Regression and migration tests
src/backend/tests/unit/components/bundles/google/*, src/bundles/google/tests/*, src/backend/tests/unit/test_lfx_bundles_extras.py
Updates imports and patch targets, and adds coverage for Google component errors, Gemini compatibility, OAuth behavior, and compatibility extras.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: enhancement, documentation

Suggested reviewers: jordanrfrazier


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error Existing tests cover most new Google features, but GoogleDriveComponent and GoogleGenerativeAIEmbeddingsComponent have no corresponding tests, so coverage is incomplete. Add tests for the missing components (success and failure cases) in a test_*.py file.
Docstring Coverage ⚠️ Warning Docstring coverage is 10.42% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Quality And Coverage ⚠️ Warning Most new Google code has pytest+mock coverage, but GoogleDriveComponent and GoogleGenerativeAIEmbeddingsComponent have no test references, and one async test is smoke-only. Add focused pytest tests for the uncovered bundle components and exercise success/error paths for Gmail/Drive Search; replace the async smoke test with behavior assertions.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: Google is being promoted to a default partner bundle.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Test File Naming And Structure ✅ Passed All added test files use test_*.py naming, pytest fixtures/mocks, descriptive test names, and include positive and negative coverage; no frontend tests were added.
Excessive Mock Usage Warning ✅ Passed Mocks are targeted at external Google/OAuth APIs; 6/11 regression tests use minimal fakes/patches, with several direct behavior tests and no over-mocked core logic.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/le-1974-google-partner-bundle

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

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the bug Something isn't working label Jul 23, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Test Coverage Advisor

No source changes detected without accompanying tests. Thanks for keeping coverage up! 🎉

Advisory check only — never blocks merge.

@github-actions

This comment has been minimized.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/bundles/lfx-bundles/pyproject.toml (1)

53-54: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep google as a deprecated compatibility extra.

Removing this extra means existing pip install "lfx-bundles[google]" installations no longer install lfx-google; the updated lfx.components.google shim will then fail for those users. Retain google = ["lfx-google>=0.1.0,<1.0.0"] as a compatibility alias while keeping it excluded from all and all-no-torch.

Suggested compatibility extra
 [project.optional-dependencies]
+google = ["lfx-google>=0.1.0,<1.0.0"]

This follows from the shim’s new lfx-google requirement and the removed documented installation extra.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/lfx-bundles/pyproject.toml` around lines 53 - 54, Restore the
deprecated google extra in pyproject.toml with lfx-google>=0.1.0,<1.0.0 as its
dependency. Keep google as a compatibility alias, but do not include it in the
all or all-no-torch aggregate extras.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/bundles/google/src/lfx_google/components/google/gmail.py`:
- Around line 165-192: Update the max_results conversion in the component method
containing the JSON parsing and loader setup to catch invalid numeric input and
raise a friendly ValueError with a descriptive message, consistent with the
existing JSONDecodeError and document-loading error handling; preserve the
default of 100 when max_results is unset.

In `@src/bundles/google/src/lfx_google/components/google/google_drive_search.py`:
- Around line 105-140: Update search_files to catch JSONDecodeError around
json.loads(self.token_string) and raise ValueError("Invalid JSON string"),
matching the sibling loaders. Import RefreshError from google.auth.exceptions
and wrap the Google Drive service setup/search execution in the same error
handling pattern used by those loaders, converting RefreshError and other API
exceptions into the bundle’s consistent ValueError messages.

In `@src/bundles/google/src/lfx_google/components/google/google_generative_ai.py`:
- Around line 111-124: Update the tool-support filtering in the model-selection
method to instantiate ChatGoogleGenerativeAI with the loop variable model, not
self.model_name. Avoid mutating model_ids during iteration by building a
filtered collection or iterating over a copy, and ensure the no-supported-model
case returns an empty result or otherwise follows the existing validation path
without causing a later IndexError-to-ValueError failure in update_build_config.
- Around line 97-110: Update get_models and the related update_build_config
tool-model validation to use a client-scoped Google Gen AI SDK/API initialized
with self.api_key, removing the process-wide genai.configure() call. Pass the
client explicitly through both model listing and validation paths so concurrent
requests using different API keys remain isolated, while preserving the existing
supported-generation filtering, sorting, and fallback behavior.

In `@src/bundles/google/src/lfx_google/components/google/google_oauth_token.py`:
- Around line 40-54: Update validate_scopes so every repeated scope alternative
requires the same comma-and-optional-whitespace separator, preventing
unseparated values such as mail.google.com/ or calendar feeds from being
concatenated and accepted. Preserve validation of single scopes and properly
comma-separated scopes.
- Around line 55-88: Update build_output to stop using the process-wide
token.json and the blocking InstalledAppFlow.run_local_server flow. Use an
isolated, caller-owned credential store keyed to the current flow or request,
and implement OAuth through a redirect/callback exchange with an explicit
timeout and failure handling before returning the credentials in Data.

---

Outside diff comments:
In `@src/bundles/lfx-bundles/pyproject.toml`:
- Around line 53-54: Restore the deprecated google extra in pyproject.toml with
lfx-google>=0.1.0,<1.0.0 as its dependency. Keep google as a compatibility
alias, but do not include it in the all or all-no-torch aggregate extras.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2206ccff-cdd0-4412-8f20-f3dab7094951

📥 Commits

Reviewing files that changed from the base of the PR and between 2e677bf and 5c1203b.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (31)
  • docs/docs/Components/bundles-google.mdx
  • docs/docs/Lfx/extensions-bundle-list.mdx
  • pyproject.toml
  • scripts/ci/bundle_profile_locks/enterprise-hardened.lock.json
  • scripts/ci/bundle_profiles.json
  • scripts/ci/release_inventory_contract.json
  • scripts/ci/test_release_inventory.py
  • scripts/migrate/consolidate_bundles.py
  • src/backend/base/langflow/locales/en.json
  • src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py
  • src/backend/tests/unit/components/bundles/google/test_google_search_api.py
  • src/backend/tests/unit/components/bundles/google/test_google_serper_api_core.py
  • src/bundles/google/README.md
  • src/bundles/google/pyproject.toml
  • src/bundles/google/src/lfx_google/__init__.py
  • src/bundles/google/src/lfx_google/components/__init__.py
  • src/bundles/google/src/lfx_google/components/google/__init__.py
  • src/bundles/google/src/lfx_google/components/google/gmail.py
  • src/bundles/google/src/lfx_google/components/google/google_bq_sql_executor.py
  • src/bundles/google/src/lfx_google/components/google/google_drive.py
  • src/bundles/google/src/lfx_google/components/google/google_drive_search.py
  • src/bundles/google/src/lfx_google/components/google/google_generative_ai.py
  • src/bundles/google/src/lfx_google/components/google/google_generative_ai_embeddings.py
  • src/bundles/google/src/lfx_google/components/google/google_oauth_token.py
  • src/bundles/google/src/lfx_google/components/google/google_search_api_core.py
  • src/bundles/google/src/lfx_google/components/google/google_serper_api_core.py
  • src/bundles/google/src/lfx_google/extension.json
  • src/bundles/google/tests/test_google_generative_ai_model.py
  • src/bundles/lfx-bundles/README.md
  • src/bundles/lfx-bundles/pyproject.toml
  • src/lfx/src/lfx/components/google/__init__.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/bundles/lfx-bundles/pyproject.toml (1)

53-54: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep google as a deprecated compatibility extra.

Removing this extra means existing pip install "lfx-bundles[google]" installations no longer install lfx-google; the updated lfx.components.google shim will then fail for those users. Retain google = ["lfx-google>=0.1.0,<1.0.0"] as a compatibility alias while keeping it excluded from all and all-no-torch.

Suggested compatibility extra
 [project.optional-dependencies]
+google = ["lfx-google>=0.1.0,<1.0.0"]

This follows from the shim’s new lfx-google requirement and the removed documented installation extra.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/lfx-bundles/pyproject.toml` around lines 53 - 54, Restore the
deprecated google extra in pyproject.toml with lfx-google>=0.1.0,<1.0.0 as its
dependency. Keep google as a compatibility alias, but do not include it in the
all or all-no-torch aggregate extras.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/bundles/google/src/lfx_google/components/google/gmail.py`:
- Around line 165-192: Update the max_results conversion in the component method
containing the JSON parsing and loader setup to catch invalid numeric input and
raise a friendly ValueError with a descriptive message, consistent with the
existing JSONDecodeError and document-loading error handling; preserve the
default of 100 when max_results is unset.

In `@src/bundles/google/src/lfx_google/components/google/google_drive_search.py`:
- Around line 105-140: Update search_files to catch JSONDecodeError around
json.loads(self.token_string) and raise ValueError("Invalid JSON string"),
matching the sibling loaders. Import RefreshError from google.auth.exceptions
and wrap the Google Drive service setup/search execution in the same error
handling pattern used by those loaders, converting RefreshError and other API
exceptions into the bundle’s consistent ValueError messages.

In `@src/bundles/google/src/lfx_google/components/google/google_generative_ai.py`:
- Around line 111-124: Update the tool-support filtering in the model-selection
method to instantiate ChatGoogleGenerativeAI with the loop variable model, not
self.model_name. Avoid mutating model_ids during iteration by building a
filtered collection or iterating over a copy, and ensure the no-supported-model
case returns an empty result or otherwise follows the existing validation path
without causing a later IndexError-to-ValueError failure in update_build_config.
- Around line 97-110: Update get_models and the related update_build_config
tool-model validation to use a client-scoped Google Gen AI SDK/API initialized
with self.api_key, removing the process-wide genai.configure() call. Pass the
client explicitly through both model listing and validation paths so concurrent
requests using different API keys remain isolated, while preserving the existing
supported-generation filtering, sorting, and fallback behavior.

In `@src/bundles/google/src/lfx_google/components/google/google_oauth_token.py`:
- Around line 40-54: Update validate_scopes so every repeated scope alternative
requires the same comma-and-optional-whitespace separator, preventing
unseparated values such as mail.google.com/ or calendar feeds from being
concatenated and accepted. Preserve validation of single scopes and properly
comma-separated scopes.
- Around line 55-88: Update build_output to stop using the process-wide
token.json and the blocking InstalledAppFlow.run_local_server flow. Use an
isolated, caller-owned credential store keyed to the current flow or request,
and implement OAuth through a redirect/callback exchange with an explicit
timeout and failure handling before returning the credentials in Data.

---

Outside diff comments:
In `@src/bundles/lfx-bundles/pyproject.toml`:
- Around line 53-54: Restore the deprecated google extra in pyproject.toml with
lfx-google>=0.1.0,<1.0.0 as its dependency. Keep google as a compatibility
alias, but do not include it in the all or all-no-torch aggregate extras.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2206ccff-cdd0-4412-8f20-f3dab7094951

📥 Commits

Reviewing files that changed from the base of the PR and between 2e677bf and 5c1203b.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (31)
  • docs/docs/Components/bundles-google.mdx
  • docs/docs/Lfx/extensions-bundle-list.mdx
  • pyproject.toml
  • scripts/ci/bundle_profile_locks/enterprise-hardened.lock.json
  • scripts/ci/bundle_profiles.json
  • scripts/ci/release_inventory_contract.json
  • scripts/ci/test_release_inventory.py
  • scripts/migrate/consolidate_bundles.py
  • src/backend/base/langflow/locales/en.json
  • src/backend/tests/unit/components/bundles/google/test_google_bq_sql_executor_component.py
  • src/backend/tests/unit/components/bundles/google/test_google_search_api.py
  • src/backend/tests/unit/components/bundles/google/test_google_serper_api_core.py
  • src/bundles/google/README.md
  • src/bundles/google/pyproject.toml
  • src/bundles/google/src/lfx_google/__init__.py
  • src/bundles/google/src/lfx_google/components/__init__.py
  • src/bundles/google/src/lfx_google/components/google/__init__.py
  • src/bundles/google/src/lfx_google/components/google/gmail.py
  • src/bundles/google/src/lfx_google/components/google/google_bq_sql_executor.py
  • src/bundles/google/src/lfx_google/components/google/google_drive.py
  • src/bundles/google/src/lfx_google/components/google/google_drive_search.py
  • src/bundles/google/src/lfx_google/components/google/google_generative_ai.py
  • src/bundles/google/src/lfx_google/components/google/google_generative_ai_embeddings.py
  • src/bundles/google/src/lfx_google/components/google/google_oauth_token.py
  • src/bundles/google/src/lfx_google/components/google/google_search_api_core.py
  • src/bundles/google/src/lfx_google/components/google/google_serper_api_core.py
  • src/bundles/google/src/lfx_google/extension.json
  • src/bundles/google/tests/test_google_generative_ai_model.py
  • src/bundles/lfx-bundles/README.md
  • src/bundles/lfx-bundles/pyproject.toml
  • src/lfx/src/lfx/components/google/__init__.py
🛑 Comments failed to post (6)
src/bundles/google/src/lfx_google/components/google/gmail.py (1)

165-192: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Unguarded int() conversion produces an unclear error.

int(self.max_results) (Line 167) isn't wrapped in a try/except like the adjacent JSON parsing, Refresh, and generic load-error paths. A non-numeric max_results value raises a raw ValueError from int() instead of the same friendly ValueError(msg) pattern used elsewhere in this method.

🐛 Proposed fix
-        max_results = int(self.max_results) if self.max_results else 100
+        try:
+            max_results = int(self.max_results) if self.max_results else 100
+        except ValueError as e:
+            msg = f"Invalid max_results value: {self.max_results}"
+            raise ValueError(msg) from e
📝 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.

        json_string = self.json_string
        label_ids = self.label_ids.split(",") if self.label_ids else ["INBOX"]
        try:
            max_results = int(self.max_results) if self.max_results else 100
        except ValueError as e:
            msg = f"Invalid max_results value: {self.max_results}"
            raise ValueError(msg) from e

        # Load the token information from the JSON string
        try:
            token_info = json.loads(json_string)
        except JSONDecodeError as e:
            msg = "Invalid JSON string"
            raise ValueError(msg) from e

        creds = Credentials.from_authorized_user_info(token_info)

        # Initialize the custom loader with the provided credentials
        loader = CustomGMailLoader(creds=creds, n=max_results, label_ids=label_ids)

        try:
            docs = loader.load()
        except RefreshError as e:
            msg = "Authentication error: Unable to refresh authentication token. Please try to reauthenticate."
            raise ValueError(msg) from e
        except Exception as e:
            msg = f"Error loading documents: {e}"
            raise ValueError(msg) from e

        # Return the loaded documents
        self.status = docs
        return Data(data={"text": docs})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/google/src/lfx_google/components/google/gmail.py` around lines
165 - 192, Update the max_results conversion in the component method containing
the JSON parsing and loader setup to catch invalid numeric input and raise a
friendly ValueError with a descriptive message, consistent with the existing
JSONDecodeError and document-loading error handling; preserve the default of 100
when max_results is unset.
src/bundles/google/src/lfx_google/components/google/google_drive_search.py (1)

105-140: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Missing JSON-decode and API-error handling, unlike sibling loaders.

json.loads(self.token_string) (Line 107) isn't wrapped, unlike the identical parsing in gmail.py and google_drive.py, which catch JSONDecodeError and raise a clear ValueError("Invalid JSON string"). Similarly, service.files().list(...).execute() has no RefreshError/generic exception handling, unlike the sibling loaders' loader.load() calls. Malformed tokens or API failures here will surface as raw, unfriendly exceptions instead of the consistent ValueError messages used elsewhere in this bundle.

🐛 Proposed fix
     def search_files(self) -> dict:
         # Load the token information from the JSON string
-        token_info = json.loads(self.token_string)
+        try:
+            token_info = json.loads(self.token_string)
+        except json.JSONDecodeError as e:
+            msg = "Invalid JSON string"
+            raise ValueError(msg) from e
         creds = Credentials.from_authorized_user_info(token_info)

         # Use the query string from the input (which might have been edited by the user)
         query = self.query_string or self.generate_query_string()

         # Initialize the Google Drive API service
         service = build("drive", "v3", credentials=creds)

         # Perform the search
-        results = service.files().list(q=query, pageSize=5, fields="nextPageToken, files(id, name, mimeType)").execute()
+        try:
+            results = (
+                service.files().list(q=query, pageSize=5, fields="nextPageToken, files(id, name, mimeType)").execute()
+            )
+        except RefreshError as e:
+            msg = "Authentication error: Unable to refresh authentication token. Please try to reauthenticate."
+            raise ValueError(msg) from e
+        except Exception as e:
+            msg = f"Error searching Google Drive: {e}"
+            raise ValueError(msg) from e

(remember to import RefreshError from google.auth.exceptions)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/google/src/lfx_google/components/google/google_drive_search.py`
around lines 105 - 140, Update search_files to catch JSONDecodeError around
json.loads(self.token_string) and raise ValueError("Invalid JSON string"),
matching the sibling loaders. Import RefreshError from google.auth.exceptions
and wrap the Google Drive service setup/search execution in the same error
handling pattern used by those loaders, converting RefreshError and other API
exceptions into the bundle’s consistent ValueError messages.
src/bundles/google/src/lfx_google/components/google/google_generative_ai.py (2)

97-110: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🌐 Web query:

Does the google-generativeai Python SDK support listing models with a per-call API key instead of global genai.configure()?

💡 Result:

The legacy google-generativeai SDK (which uses genai.configure) does not support passing a per-call API key, as it relies on a global configuration to manage authentication [1][2]. To use different API keys in that SDK, developers typically avoid genai.configure and instead manage authentication via environment variables or low-level client configuration [2]. However, the new, recommended Google Gen AI SDK (google-genai) utilizes a client-based architecture that explicitly supports per-client (and effectively per-instance) API key management [3][4][5]. Instead of global configuration, you instantiate a client with a specific API key, allowing for multiple, independent clients within the same application [3][6][7]: from google import genai # Create a client with a specific API key client = genai.Client(api_key='YOUR_API_KEY') # Use this client to list models or perform other operations models = client.models.list This design resolves the limitations of the legacy SDK by allowing developers to maintain isolated instances with their own credentials [6][7][5]. It is recommended to migrate from google-generativeai to google-genai to benefit from this improved architecture [6][7].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file location =="
git ls-files | rg 'google_generative_ai.py|pyproject.toml|requirements|Pipfile|poetry|uv.lock|lock' || true

echo
echo "== target file excerpt =="
fd -a google_generative_ai.py . | while read -r f; do
  echo "--- $f"
  wc -l "$f"
  sed -n '1,180p' "$f"
done

echo
echo "== dependenc references to google generative =="
rg -n "google-(generativeai|genai)|generativeai|genai|Gemini|GenerativeModel" -S . --glob '!*.lock' --glob '!node_modules/**' --glob '!dist/**' || true

echo
echo "== call sites / class methods =="
rg -n "get_models|update_build_config|api_key|google_generative_ai|Genai|google\.generativeai" -S src || true

Repository: langflow-ai/langflow

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== inspect package metadata/version constraints if present =="
for f in pyproject.toml requirements.txt requirements*.txt Pipfile poetry.lock uv.lock poetry.lock.backup; do
  if [ -f "$f" ]; then
    echo "--- $f"
    rg -n "google-(genai|generativeai)|generativeai|genai" "$f" || true
  fi
done

echo
echo "== git diff around modified/deleted dependencies if available =="
git diff --name-only --diff-filter=M || true
git diff --stat || true

Repository: langflow-ai/langflow

Length of output: 2754


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate exact google_generative_ai.py =="
git ls-files | grep 'src/bundles/google/src/lfx_google/components/google/google_generative_ai.py$' || true

echo
echo "== target file =="
f="$(git ls-files | grep 'src/bundles/google/src/lfx_google/components/google/google_generative_ai.py$' || true)"
if [ -n "$f" ]; then
  wc -l "$f"
  sed -n '1,220p' "$f"
fi

echo
echo "== dependency constraints in pyproject/uv.lock =="
if [ -f uv.lock ]; then
  rg -n -C 2 "^name = \"google-(genai|generativeai)\"|google-genai|google-generativeai|langchain-google-genai" uv.lock | head -n 120
fi
rg -n -C 2 "google-(genai|generativeai)|google_genai|google-generativeai|langchain-google-genai" pyproject.toml pyproject.* uv.lock 2>/dev/null | head -n 160 || true

echo
echo "== runtime availability and module symbols =="
python3 - <<'PY'
import importlib.util
for name in ["google.generativeai", "google.genai"]:
    spec = importlib.util.find_spec(name)
    print(f"{name}: {spec.origin if spec else 'not installed'}")
try:
    import google.generativeai as genai
    print("google.generativeai.configure:", getattr(genai, "configure", None))
    print("google.generativeai.list_models:", getattr(genai, "list_models", None))
except Exception as e:
    print("google.generativeai import error:", type(e).__name__, e)
try:
    import google.genai
    print("google.genai.available:", True)
    print("google.genai modules:", tuple(dir(google.genai)))
except Exception as e:
    print("google.genai import error:", type(e).__name__, e)
PY

Repository: langflow-ai/langflow

Length of output: 13123


Use per-client Google Gen AI auth and avoid calling genai.configure() during UI refresh.

google.generativeai.configure() and list_models() share the process-wide Gen AI module state, so concurrent get_models() / update_build_config() calls from different Google API keys can execute against the wrong keys. Switch to a client-scoped SDK/API and pass credentials through the client in both model listing and tool-model validation, so refresh/background config refresh cannot leak credentials between flows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/google/src/lfx_google/components/google/google_generative_ai.py`
around lines 97 - 110, Update get_models and the related update_build_config
tool-model validation to use a client-scoped Google Gen AI SDK/API initialized
with self.api_key, removing the process-wide genai.configure() call. Pass the
client explicitly through both model listing and validation paths so concurrent
requests using different API keys remain isolated, while preserving the existing
supported-generation filtering, sorting, and fallback behavior.

111-124: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tool-support filtering is broken: wrong model probed, and list mutated during iteration.

The probe always builds ChatGoogleGenerativeAI(model=self.model_name, ...) instead of the loop variable model, so every candidate is judged by the single currently-selected model's tool support, not its own. Separately, model_ids.remove(model) while iterating model_ids skips the element following each removal. Together, tool_model_enabled filtering produces incorrect/incomplete results, and an all-removed edge case surfaces later as an opaque IndexErrorValueError in update_build_config (Line 139).

🐛 Proposed fix
         if tool_model_enabled:
             try:
                 from langchain_google_genai.chat_models import ChatGoogleGenerativeAI
             except ImportError as e:
                 msg = "langchain_google_genai is not installed."
                 raise ImportError(msg) from e
-            for model in model_ids:
-                model_with_tool = ChatGoogleGenerativeAI(
-                    model=self.model_name,
-                    google_api_key=self.api_key,
-                )
-                if not self.supports_tool_calling(model_with_tool):
-                    model_ids.remove(model)
+            model_ids = [
+                model
+                for model in model_ids
+                if self.supports_tool_calling(
+                    ChatGoogleGenerativeAI(model=model, google_api_key=self.api_key)
+                )
+            ]
         return model_ids
📝 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.

        if tool_model_enabled:
            try:
                from langchain_google_genai.chat_models import ChatGoogleGenerativeAI
            except ImportError as e:
                msg = "langchain_google_genai is not installed."
                raise ImportError(msg) from e
            model_ids = [
                model
                for model in model_ids
                if self.supports_tool_calling(
                    ChatGoogleGenerativeAI(model=model, google_api_key=self.api_key)
                )
            ]
        return model_ids
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/google/src/lfx_google/components/google/google_generative_ai.py`
around lines 111 - 124, Update the tool-support filtering in the model-selection
method to instantiate ChatGoogleGenerativeAI with the loop variable model, not
self.model_name. Avoid mutating model_ids during iteration by building a
filtered collection or iterating over a copy, and ensure the no-supported-model
case returns an empty result or otherwise follows the existing validation path
without causing a later IndexError-to-ValueError failure in update_build_config.
src/bundles/google/src/lfx_google/components/google/google_oauth_token.py (2)

40-54: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Scope-validation regex allows missing comma separators.

Only the first alternative in the repeating group carries the ,\s* prefix; mail.google.com/, www.google.com/calendar/feeds, and www.google.com/m8/feeds can match without a preceding comma, so multiple scopes can be concatenated without a separator and still pass validation.

🐛 Proposed fix
     def validate_scopes(self, scopes):
         pattern = (
             r"^(https://www\.googleapis\.com/auth/[\w\.\-]+"
             r"|mail\.google\.com/"
             r"|www\.google\.com/calendar/feeds"
             r"|www\.google\.com/m8/feeds)"
-            r"(,\s*https://www\.googleapis\.com/auth/[\w\.\-]+"
-            r"|mail\.google\.com/"
-            r"|www\.google\.com/calendar/feeds"
-            r"|www\.google\.com/m8/feeds)*$"
+            r"(,\s*(https://www\.googleapis\.com/auth/[\w\.\-]+"
+            r"|mail\.google\.com/"
+            r"|www\.google\.com/calendar/feeds"
+            r"|www\.google\.com/m8/feeds))*$"
         )
📝 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 validate_scopes(self, scopes):
        pattern = (
            r"^(https://www\.googleapis\.com/auth/[\w\.\-]+"
            r"|mail\.google\.com/"
            r"|www\.google\.com/calendar/feeds"
            r"|www\.google\.com/m8/feeds)"
            r"(,\s*(https://www\.googleapis\.com/auth/[\w\.\-]+"
            r"|mail\.google\.com/"
            r"|www\.google\.com/calendar/feeds"
            r"|www\.google\.com/m8/feeds))*$"
        )
        if not re.match(pattern, scopes):
            error_message = "Invalid scope format."
            raise ValueError(error_message)
🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 50-50: Regex pattern passed to re is built from a non-literal (variable, call, concatenation, or f-string) value. If that value is attacker-controlled it can introduce a malicious pattern with catastrophic backtracking (ReDoS). Use a hardcoded literal pattern, or validate/escape untrusted input with re.escape() and bound the regex complexity before compiling.
Context: re.match(pattern, scopes)
Note: [CWE-1333] Inefficient Regular Expression Complexity.

(redos-non-literal-regex-python)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/google/src/lfx_google/components/google/google_oauth_token.py`
around lines 40 - 54, Update validate_scopes so every repeated scope alternative
requires the same comma-and-optional-whitespace separator, preventing
unseparated values such as mail.google.com/ or calendar feeds from being
concatenated and accepted. Preserve validation of single scopes and properly
comma-separated scopes.

55-88: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file exists and outline/size =="
fd -a 'google_oauth_token.py' . || true
if [ -f src/bundles/google/src/lfx_google/components/google/google_oauth_token.py ]; then
  wc -l src/bundles/google/src/lfx_google/components/google/google_oauth_token.py
  ast-grep outline src/bundles/google/src/lfx_google/components/google/google_oauth_token.py || true
  echo "== relevant lines =="
  sed -n '1,140p' src/bundles/google/src/lfx_google/components/google/google_oauth_token.py | cat -n
fi

echo "== usages/imports/config for google_oauth_token =="
rg -n "google_oauth_token|OAuthToken|token\.json|run_local_server|from_authorized_user_file|to_json" . || true

echo "== dependency hints for google oauth library =="
rg -n "google-auth|google-api-python-client|google-auth-oauthlib" -S . -g '!node_modules' || true
fd . . -e py | xargs -r rg -n "from google.auth|import google|Credentials|InstalledAppFlow" | head -100

Repository: langflow-ai/langflow

Length of output: 50377


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== google oauth token file =="
cat -n src/bundles/google/src/lfx_google/components/google/google_oauth_token.py

echo "== component wiring/usages =="
rg -n "GoogleOAuthToken|google_oauth_token|Google OAuth Token|InstalledAppFlow|run_local_server|token\.json|oauth_credentials" src/bundles/google src -g '!**/Content Aggregator.json' || true

echo "== package dependency/source snippets =="
fd . src -e py | xargs -r rg -n "InstalledAppFlow|run_local_server|Credentials\.from_authorized_user|to_json" | head -80 || true

Repository: langflow-ai/langflow

Length of output: 20756


🌐 Web query:

Google Auth Python InstalledAppFlow run_local_server timeout port=0 blocks browser behavior documentation

💡 Result:

In the Google Auth library for Python (google-auth-oauthlib), the InstalledAppFlow.run_local_server method is designed to facilitate the OAuth 2.0 flow for installed applications by spinning up a short-lived local web server to capture the authorization code [1][2][3]. Behavior of port=0 When you set port=0 in the run_local_server method, the underlying wsgiref.simple_server library automatically assigns an available ephemeral port [3]. This is a common practice to avoid "Address already in use" errors that can occur when a hardcoded port is already occupied by another process [4][5]. Behavior of Timeout By default, run_local_server blocks indefinitely while waiting for the user to complete the authentication in their browser [6][7][8]. If the user closes the browser or does not complete the flow, the application will remain blocked [8]. Recent updates have introduced a timeout_seconds parameter to address this [9][8]. When this parameter is used, the server will wait for the specified duration for the authorization callback. If no request is received within that time: 1. Historically, this often resulted in an AttributeError: 'NoneType' object has no attribute 'replace' because the code attempted to access the callback URI which was never set [6][9][8]. 2. More recent versions (e.g., following updates like PR #363 in 2026) have been designed to raise a more meaningful exception instead, allowing developers to handle the timeout gracefully [9]. Implementation Recommendations To avoid blocking indefinitely, you should pass the timeout_seconds parameter [8] and wrap the call in a try-except block to handle the potential timeout exception [8]. Example usage: from google_auth_oauthlib.flow import InstalledAppFlow flow = InstalledAppFlow.from_client_secrets_file('client_secrets.json', scopes=[...]) try: # Using port=0 for an ephemeral port and timeout_seconds to prevent indefinite blocking creds = flow.run_local_server(port=0, timeout_seconds=60) except Exception as e: print(f"Authentication timed out or failed: {e}")

Citations:


🌐 Web query:

google-auth-oauthlib InstalledAppFlow run_local_server source wsgiref timeout_seconds

💡 Result:

In the google-auth-oauthlib library, the InstalledAppFlow.run_local_server method includes a timeout_seconds parameter [1]. This parameter allows you to specify a timeout duration for the local web server created to handle the OAuth 2.0 authorization response [2][3]. The timeout_seconds argument was introduced to address issues where the server would otherwise block indefinitely while waiting for an authorization response [2][3]. When provided, this value is passed to the underlying socket server's timeout mechanism [2]. If no value is provided, it defaults to None, meaning the server will continue to block until a request is received or an error occurs [2]. Key implementation details include: - The parameter is explicitly named timeout_seconds [1]. - It is used to prevent the local server from blocking indefinitely during the OAuth flow [2][3]. - The library uses wsgiref.simple_server.make_server to create the local redirect server [4]. If you are encountering issues with run_local_server blocking or failing to bind to a port, ensure you are using a recent version of the library, as enhancements such as the timeout_seconds parameter and bind_addr (for container environments) have been added to resolve these common behaviors [5][3][6].

Citations:


Avoid using global token.json and run_local_server() in the backend.

Path("token.json") is a single shared credential file across all flows, so concurrent requests can race or read tokens belonging to another user/token set. flow.run_local_server(port=0) also blocks waiting for the browser callback with no configured timeout, which can hang indefinitely in a server context. Use an isolated, caller-owned store and handle OAuth via a redirect/callback model with explicit timeout/error handling.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/bundles/google/src/lfx_google/components/google/google_oauth_token.py`
around lines 55 - 88, Update build_output to stop using the process-wide
token.json and the blocking InstalledAppFlow.run_local_server flow. Use an
isolated, caller-owned credential store keyed to the current flow or request,
and implement OAuth through a redirect/callback exchange with an explicit
timeout and failure handling before returning the credentials in Data.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@github-actions

This comment has been minimized.

@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 53.61%. Comparing base (597d05f) to head (afe4fad).
⚠️ Report is 26 commits behind head on release-1.12.0.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##           release-1.12.0   #14220      +/-   ##
==================================================
- Coverage           61.47%   53.61%   -7.86%     
==================================================
  Files                2339     2299      -40     
  Lines              237145   228084    -9061     
  Branches            35410    17626   -17784     
==================================================
- Hits               145787   122292   -23495     
- Misses              89561   103982   +14421     
- Partials             1797     1810      +13     
Flag Coverage Δ
backend 69.10% <ø> (+0.15%) ⬆️
frontend 47.01% <ø> (-12.73%) ⬇️
lfx 60.37% <ø> (+0.16%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 953 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@erichare

Copy link
Copy Markdown
Member Author

@coderabbitai review

Addressed the review findings in 0efa677:

  • retained lfx-bundles[google] as a deprecated compatibility alias without adding it back to aggregate extras
  • added friendly Gmail and Drive Search validation/API errors
  • switched Gemini model discovery to an API-key-scoped google.genai.Client, fixed per-model tool filtering, and handled an empty supported-model list
  • tightened OAuth scope parsing, removed the shared token.json credential store, and added a bounded callback timeout with explicit failures
  • added focused regressions for each changed path

The full server-native OAuth redirect UI would require a separate API/frontend design; this commit removes the cross-user state and indefinite-wait risks without widening this release PR.

Validation: 110 passed, 8 skipped; Ruff, release-plan/profile checks, lock validation, wheel builds, and pre-commit hooks all pass.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Commit and changed files =='
git show --no-ext-diff --format=fuller --name-status 0efa677d4a

echo
echo '== Targeted change summary =='
git show --no-ext-diff --stat 0efa677d4a

echo
echo '== Relevant modified source/test files =='
git diff-tree --no-commit-id --name-only -r 0efa677d4a |
  rg '(^src/bundles/google/|^src/bundles/lfx-bundles/|^src/lfx/src/lfx/components/google/|test_google|pyproject\.toml$)' || true

echo
echo '== Packaging and compatibility diff =='
git show --no-ext-diff --format= -- \
  src/bundles/lfx-bundles/pyproject.toml \
  src/bundles/lfx-bundles/README.md \
  src/bundles/google/pyproject.toml \
  pyproject.toml \
  src/lfx/src/lfx/components/google/__init__.py 0efa677d4a || true

echo
echo '== OAuth/model-discovery/component diff =='
git show --no-ext-diff --format= 0efa677d4a -- \
  src/bundles/google/src/lfx_google/components/google \
  src/bundles/google/tests || true

Length of output: 23418


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Commit and changed files =='
git show --no-ext-diff --format=fuller --name-status 0efa677d4a

echo
echo '== Targeted change summary =='
git show --no-ext-diff --stat 0efa677d4a

echo
echo '== Relevant modified source/test files =='
git diff-tree --no-commit-id --name-only -r 0efa677d4a |
  rg '(^src/bundles/google/|^src/bundles/lfx-bundles/|^src/lfx/src/lfx/components/google/|test_google|pyproject\.toml$)' || true

echo
echo '== Packaging and compatibility diff =='
git show --no-ext-diff --format= 0efa677d4a -- \
  src/bundles/lfx-bundles/pyproject.toml \
  src/bundles/lfx-bundles/README.md \
  src/bundles/google/pyproject.toml \
  pyproject.toml \
  src/lfx/src/lfx/components/google/__init__.py || true

echo
echo '== OAuth/model-discovery/component diff =='
git show --no-ext-diff --format= 0efa677d4a -- \
  src/bundles/google/src/lfx_google/components/google \
  src/bundles/google/tests || true

Length of output: 23418


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '== Relevant symbol map =='
ast-grep outline src/bundles/google/src/lfx_google/components/google/google_generative_ai.py --items all --type class,function --view expanded
ast-grep outline src/bundles/google/src/lfx_google/components/google/google_oauth_token.py --items all --type class,function --view expanded
ast-grep outline scripts/migrate/consolidate_bundles.py --items all --type function --view expanded
ast-grep outline src/backend/tests/unit/test_lfx_bundles_extras.py --items all --type function --view expanded

echo
echo '== Aggregate-extra generation and compatibility assertions =='
rg -n -C 5 'all-no-torch|optional-dependencies|PROVIDER_DEPS|google|lfx-google' \
  scripts/migrate/consolidate_bundles.py \
  src/bundles/lfx-bundles/pyproject.toml \
  src/backend/tests/unit/test_lfx_bundles_extras.py

echo
echo '== Current implementation and focused regression test =='
sed -n '80,155p' src/bundles/google/src/lfx_google/components/google/google_generative_ai.py
sed -n '1,130p' src/bundles/google/src/lfx_google/components/google/google_oauth_token.py
sed -n '1,245p' src/bundles/google/tests/test_google_component_regressions.py

echo
echo '== Locked google-genai dependency metadata =='
rg -n -A18 -B3 '^name = "google-genai"$' uv.lock

Length of output: 44992


🤖 web_search executed:

google-genai Python 1.75.0 Client context manager __enter__ close models.list supported_actions API documentation

Length of output: 9324


@erichare Verified the follow-up in 0efa677d4a. The compatibility alias is preserved while excluded from aggregate extras; the aggregate-generation logic and regression test enforce that invariant.

The Gemini client usage matches the google-genai 1.75.0 API, including scoped client construction, context-manager cleanup, model listing, and supported_actions filtering. The per-model tool filtering, empty-model handling, OAuth credential isolation/callback timeout, and user-facing validation errors are all covered by focused regressions.

No new issues found in the follow-up changes. 🐇


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@github-actions

This comment has been minimized.

@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 47%
47.01% (67374/143289) 70.15% (9505/13548) 45.58% (1554/3409)

Unit Test Results

Tests Skipped Failures Errors Time
5375 0 💤 0 ❌ 0 🔥 18m 5s ⏱️

…-google-partner-bundle

# Conflicts:
#	src/lfx/src/lfx/_assets/component_index.json
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 23, 2026
@erichare
erichare merged commit dc79b9f into release-1.12.0 Jul 23, 2026
95 checks passed
@erichare
erichare deleted the fix/le-1974-google-partner-bundle branch July 23, 2026 03:13
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Build successful! ✅
Deploying docs draft.
Deploy successful! View draft

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

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant