Skip to content

feat: unify JSON/Table/Text operations into a single Operations component#13743

Open
erichare wants to merge 4 commits into
release-1.11.0from
feat/operations-component
Open

feat: unify JSON/Table/Text operations into a single Operations component#13743
erichare wants to merge 4 commits into
release-1.11.0from
feat/operations-component

Conversation

@erichare

@erichare erichare commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Combines the three data-type-specific operation components — JSON Operations, Table Operations, and Text Operations — into a single Operations component that exposes every operation across all three Langflow data types from one flat operation picker.

Selecting an operation reveals the matching input (JSON / Table / Text), its operation-specific fields, and sets the appropriate output type. Operation names don't collide across the three sets, so a single picker is unambiguous.

Supersedes the stale draft #11395, which added the component and the legacy flags but did not remove the Filter Values operation, regenerate the index/locales, add tests/docs, or fix the deprecation pointers. This PR is a complete, independent implementation. #11395 can be closed.

What's included

  • New Operations component (processing/operations.py) — flat Operation picker with all 30 operations; contextual inputs and dynamic outputs (as_data / as_dataframe / as_message / as_text), reusing the exact logic of the three originals.
  • Removes the Filter Values operation from JSON Operations (a leftover from the old Data List operations) — and does not carry it forward, per the request.
  • Marks JSON Operations, Table Operations, and Text Operations as legacy = True — they keep working for existing flows but are hidden from the default sidebar.
  • Repoints replacement pointers of 12 already-legacy processing components from the now-legacy DataOperations/DataFrameOperations to the live Operations successor, so deprecation guidance no longer leads to another legacy component.
  • Tests: 35 unit tests for Operations (one per data type + dynamic UI/output routing), updated JSON Operations tests for the removed operation, and two Playwright e2e specs retargeted to Operations.
  • Regenerated component_index.json (surgically — only the 16 processing components changed; no optional-dependency version drift) and backend locales/en.json.
  • Docs: new operations.mdx + sidebar entry, with legacy banners on the three superseded pages.

Design notes

  • One flat operation list rather than a data-type selector — most direct, fewest clicks, and names are unique so it's unambiguous.
  • The three main inputs are all shown on a fresh node (discoverable as multi-type); once an operation is chosen, only the relevant input remains and is marked required.
  • Operation logic was ported to preserve exact behavioral parity with the originals (verified by an adversarial parity review across JSON/Table/Text logic and UI/output routing).

Testing

  • 272 passed across src/backend/tests/unit/components/processing/
  • Backend + lfx component-index and upgrade-gate tests pass (test_build_component_index, test_component_index, test_cli_gate)
  • ruff check / ruff format clean; biome clean on the e2e specs
  • Locale --check and component-index sha integrity verified

Test plan

  • CI: full backend unit suite
  • CI: Playwright e2e (filterSidebar, loop-component) — retargeted to Operations; validate in CI
  • Manual: drag the Operations component, exercise one operation per data type, confirm input/output switching

Summary by CodeRabbit

  • New Features

    • Introduced a unified Operations component combining JSON, Table, and Text operations with dynamic input/output routing.
  • Documentation

    • Added Operations component documentation with usage examples and operation reference.
    • Marked JSON Operations, Table Operations, and Text Operations as legacy; users directed to the new unified Operations component.
  • Bug Fixes

    • Removed the "Filter Values" operation from Data Operations.
  • Tests

    • Added comprehensive test suite for the new Operations component.
    • Updated existing tests to reflect component naming and functionality changes.

…nent

Combine the three data-type-specific operation components — JSON Operations,
Table Operations, and Text Operations — into one Operations component that
exposes every operation across all three Langflow data types from a single
flat operation picker. Selecting an operation reveals the matching input
(JSON / Table / Text), its operation-specific fields, and the appropriate
output type.

- Remove the "Filter Values" operation from JSON Operations (a leftover from
  the old Data List operations); it is not carried over to Operations.
- Mark JSON Operations, Table Operations, and Text Operations as legacy. They
  keep working for existing flows but are hidden from the default sidebar.
- Repoint the replacement pointers of 12 already-legacy processing components
  from the now-legacy DataOperations/DataFrameOperations to the new Operations
  component, so deprecation guidance leads to a live successor.
- Add unit tests for Operations, update the JSON Operations tests for the
  removed operation, retarget two Playwright e2e tests, regenerate the
  component index and backend locales, and add docs.
@coderabbitai

coderabbitai Bot commented Jun 18, 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

Run ID: c1f46ed0-5e3a-40e1-b6cd-8c666ba51aee

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

Introduces a new unified OperationsComponent consolidating JSON, Table, and Text operations into a single component with dynamic input/output routing. Marks DataFrameOperationsComponent and TextOperations as legacy, removes the "Filter Values" operation from DataOperationsComponent, redirects replacement pointers across all legacy components to processing.Operations, and adds matching locale strings, unit tests, frontend E2E test selectors, and documentation.

Changes

Unified Operations Component

Layer / File(s) Summary
OperationsComponent: registries, metadata, inputs, and OPERATION_FIELDS
src/lfx/src/lfx/components/processing/operations.py
Defines JSON_OPERATIONS, TABLE_OPERATIONS, TEXT_OPERATIONS sets, OperationsComponent class with OPERATION_FIELDS reveal map, ALL_OPERATION_FIELDS reset list, field defaults, and the complete UI input schema for all three data type categories.
OperationsComponent: dynamic routing and execution logic
src/lfx/src/lfx/components/processing/operations.py
Implements update_build_config (field visibility, JSON path refresh), update_outputs (dynamic output port wiring), output executor methods (as_data, as_dataframe, as_message, as_text), and all JSON, Table, and Text operation handlers.
Module registration and replacement pointer updates
src/lfx/src/lfx/components/processing/__init__.py, src/lfx/src/lfx/components/processing/alter_metadata.py, src/lfx/src/lfx/components/processing/combine_text.py, src/lfx/src/lfx/components/processing/create_data.py, src/lfx/src/lfx/components/processing/data_to_dataframe.py, src/lfx/src/lfx/components/processing/extract_key.py, src/lfx/src/lfx/components/processing/filter_data.py, src/lfx/src/lfx/components/processing/filter_data_values.py, src/lfx/src/lfx/components/processing/merge_data.py, src/lfx/src/lfx/components/processing/parse_data.py, src/lfx/src/lfx/components/processing/parse_dataframe.py, src/lfx/src/lfx/components/processing/select_data.py, src/lfx/src/lfx/components/processing/update_data.py
Exports OperationsComponent from the processing package and updates replacement class attributes on all legacy components from processing.DataOperations (or processing.DataFrameOperations) to processing.Operations.
DataOperations Filter Values removal and legacy flags
src/lfx/src/lfx/components/processing/data_operations.py, src/lfx/src/lfx/components/processing/dataframe_operations.py, src/lfx/src/lfx/components/processing/text_operations.py
Removes "Filter Values" operation from DataOperationsComponent (config, inputs, defaults, methods, dispatch). Sets legacy = True on DataFrameOperationsComponent and TextOperations.
Locale strings
src/backend/base/langflow/locales/en.json
Removes filter/comparison-related keys from components.dataoperations.inputs and adds the full components.operations locale block covering all JSON, Table, and Text operation input labels and help text.
Backend unit tests
src/backend/tests/unit/components/processing/test_operations_component.py, src/backend/tests/unit/components/processing/test_data_operations_component.py
Adds test_operations_component.py with seven test classes covering operation catalog, JSON/Table/Text operations, dynamic inputs, and dynamic outputs. Updates test_data_operations_component.py to remove test_filter_values and revise the operation-cleared test for Rename Keys.
Frontend E2E test selector renames
src/frontend/tests/core/features/filterSidebar.spec.ts, src/frontend/tests/extended/features/loop-component.spec.ts
Updates selectors from processingJSON Operations / handle-dataoperations-* / title-JSON Operations to processingOperations / handle-operations-* / title-Operations.
Documentation: new Operations page and legacy callouts
docs/docs/Components/operations.mdx, docs/docs/Components/data-operations.mdx, docs/docs/Components/dataframe-operations.mdx, docs/docs/Components/text-operations.mdx, docs/sidebars.js
Adds the operations.mdx page with operation catalog and dynamic behavior description, inserts legacy warning callouts into existing operation doc pages, and registers Components/operations in the Processing sidebar.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • langflow-ai/langflow#13152: Directly adds or modifies the Text Operations documentation page (docs/docs/Components/text-operations.mdx), which this PR also modifies to add a legacy warning callout.

Suggested labels

refactor

Suggested reviewers

  • dkaushik94
  • Empreiteiro
  • viktoravelino
🚥 Pre-merge checks | ✅ 8 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.24% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: unifying three separate operation components (JSON/Table/Text operations) into a single Operations component. It is specific, directly related to the primary purpose of the changeset, and uses clear language without vague terms.
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 Coverage For New Implementations ✅ Passed PR includes comprehensive test coverage: new test_operations_component.py with 37 unit tests covering JSON/Table/Text operations and dynamic routing, updated data_operations tests (removed Filter V...
Test Quality And Coverage ✅ Passed 37 backend tests (71+ assertions) comprehensively cover main functionality: operation catalog, JSON/Table/Text operations, error handling, dynamic input/output routing. 2 frontend specs properly up...
Test File Naming And Structure ✅ Passed All test files follow correct naming patterns (test_*.py for backend, *.spec.ts for Playwright), proper pytest structure with fixtures, descriptive function names, logical organization by functiona...
Excessive Mock Usage Warning ✅ Passed New test file (37 methods) uses zero mocks; modified test file (12 methods) uses only 1 appropriate pytest.monkeypatch for cross-platform jq import testing; 48/49 tests instantiate real objects (Da...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/operations-component

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 enhancement New feature or request label Jun 18, 2026
@github-actions

github-actions Bot commented Jun 18, 2026

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 github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 18, 2026
@github-actions

This comment has been minimized.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 18, 2026
@github-actions

This comment has been minimized.

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 58.69%. Comparing base (2b7b113) to head (a3757ee).

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##           release-1.11.0   #13743      +/-   ##
==================================================
- Coverage           58.71%   58.69%   -0.02%     
==================================================
  Files                2309     2309              
  Lines              220388   220388              
  Branches            31204    33012    +1808     
==================================================
- Hits               129391   129358      -33     
- Misses              89528    89562      +34     
+ Partials             1469     1468       -1     
Flag Coverage Δ
backend 65.74% <ø> (-0.04%) ⬇️
frontend 57.88% <ø> (-0.02%) ⬇️
lfx 54.65% <ø> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 38 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.

@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: 4

🧹 Nitpick comments (1)
src/lfx/src/lfx/components/processing/operations.py (1)

926-931: 💤 Low value

Dead code: the len(self.data) == 1 check is unreachable.

data_is_list() returns True only when len(self.data) > 1. The early return at line 927 handles all cases where len <= 1, so the check at line 929 can never evaluate to True.

♻️ Suggested simplification
     def combine_data(self) -> Data:
         """Combine multiple data objects into one."""
         logger.info("combining data")
         if not self.data_is_list():
             return self.data[0] if self.data else Data(data={})

-        if len(self.data) == 1:
-            msg = "Combine operation requires multiple data inputs."
-            raise ValueError(msg)
-
         data_dicts = [data.model_dump().get("data", data.model_dump()) for data in self.data]
🤖 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/lfx/src/lfx/components/processing/operations.py` around lines 926 - 931,
The len(self.data) == 1 check is unreachable dead code because the early return
when not self.data_is_list() is true already handles all cases where
len(self.data) is 1 or less. Since data_is_list() only returns True when
len(self.data) > 1, after the first conditional return, the length is guaranteed
to be greater than 1. Remove the entire if block with the len(self.data) == 1
check and its associated ValueError to eliminate the unreachable code and
simplify the logic.
🤖 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 `@docs/docs/Components/operations.mdx`:
- Around line 35-36: The documentation contains inconsistencies between the
described behavior and the actual implementation of the Operation component.
Update line 35 to reflect that operations are presented in a flat picker rather
than grouped by data type. Update line 85 to accurately document the Text Join
operation's output types, and update line 95 to include Text as a valid output
option for the Operation component, ensuring all references to the as_text path
and Text output behavior are consistent across the documentation.

In `@src/lfx/src/lfx/components/processing/data_operations.py`:
- Line 35: The legacy operation handling in the data processing code currently
returns empty Data(data={}) when encountering removed legacy operations like
"Filter Values", which silently changes behavior instead of alerting users to
the broken flow. Instead of silently returning empty data when legacy is True at
line 35 and in the corresponding code block around lines 461-487, raise an
appropriate exception (such as a ValueError or NotImplementedError) with a clear
message indicating that the legacy operation is no longer supported and the flow
must be updated. This will fail fast and prevent silent data corruption in
downstream flow results.

In `@src/lfx/src/lfx/components/processing/filter_data_values.py`:
- Line 18: The replacement target for FilterDataValues in the replacement
variable is incorrect because it points to processing.Operations, which no
longer contains the value-based comparison operator functionality that
DataFilterComponent provides. Identify where the value-based comparison
operators that FilterDataValues depends on have been moved to or what component
now provides equivalent functionality, and update the replacement list to point
to the correct component that preserves the original behavior instead of
pointing to processing.Operations.

In `@src/lfx/src/lfx/components/processing/operations.py`:
- Around line 1352-1361: The _text_clean method has a logic issue where the
remove_extra_spaces operation processes before remove_empty_lines, causing
remove_empty_lines to become ineffective. The regex pattern \s+ in
remove_extra_spaces matches all whitespace including newlines and replaces them
with a single space, which removes the newline characters that
remove_empty_lines depends on for splitting and filtering empty lines. To fix
this, either reorder the operations to process remove_empty_lines before
remove_extra_spaces, or modify the regex pattern in the remove_extra_spaces
block from \s+ to [ ]+ to match only spaces and preserve newlines.

---

Nitpick comments:
In `@src/lfx/src/lfx/components/processing/operations.py`:
- Around line 926-931: The len(self.data) == 1 check is unreachable dead code
because the early return when not self.data_is_list() is true already handles
all cases where len(self.data) is 1 or less. Since data_is_list() only returns
True when len(self.data) > 1, after the first conditional return, the length is
guaranteed to be greater than 1. Remove the entire if block with the
len(self.data) == 1 check and its associated ValueError to eliminate the
unreachable code and simplify the logic.
🪄 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

Run ID: 18bb2a94-732d-4ed4-93d7-c1c78284c1e4

📥 Commits

Reviewing files that changed from the base of the PR and between 2b8f7f9 and 4e7399c.

📒 Files selected for processing (28)
  • docs/docs/Components/data-operations.mdx
  • docs/docs/Components/dataframe-operations.mdx
  • docs/docs/Components/operations.mdx
  • docs/docs/Components/text-operations.mdx
  • docs/sidebars.js
  • src/backend/base/langflow/locales/en.json
  • src/backend/tests/unit/components/processing/test_data_operations_component.py
  • src/backend/tests/unit/components/processing/test_operations_component.py
  • src/frontend/tests/core/features/filterSidebar.spec.ts
  • src/frontend/tests/extended/features/loop-component.spec.ts
  • src/lfx/src/lfx/_assets/component_index.json
  • src/lfx/src/lfx/components/processing/__init__.py
  • src/lfx/src/lfx/components/processing/alter_metadata.py
  • src/lfx/src/lfx/components/processing/combine_text.py
  • src/lfx/src/lfx/components/processing/create_data.py
  • src/lfx/src/lfx/components/processing/data_operations.py
  • src/lfx/src/lfx/components/processing/data_to_dataframe.py
  • src/lfx/src/lfx/components/processing/dataframe_operations.py
  • src/lfx/src/lfx/components/processing/extract_key.py
  • src/lfx/src/lfx/components/processing/filter_data.py
  • src/lfx/src/lfx/components/processing/filter_data_values.py
  • src/lfx/src/lfx/components/processing/merge_data.py
  • src/lfx/src/lfx/components/processing/operations.py
  • src/lfx/src/lfx/components/processing/parse_data.py
  • src/lfx/src/lfx/components/processing/parse_dataframe.py
  • src/lfx/src/lfx/components/processing/select_data.py
  • src/lfx/src/lfx/components/processing/text_operations.py
  • src/lfx/src/lfx/components/processing/update_data.py

Comment thread docs/docs/Components/operations.mdx Outdated
Comment thread src/lfx/src/lfx/components/processing/data_operations.py
Comment thread src/lfx/src/lfx/components/processing/filter_data_values.py Outdated
Comment thread src/lfx/src/lfx/components/processing/operations.py
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 43%
43.39% (57786/133158) 69.06% (7842/11355) 41.64% (1299/3119)

Unit Test Results

Tests Skipped Failures Errors Time
4945 0 💤 0 ❌ 0 🔥 10m 35s ⏱️

- Give the Operations component three default outputs (JSON/Table/Message) so
  base_classes is populated and it appears in connection-filtered sidebars.
  Fixes the filterSidebar Playwright test and restores the discoverability the
  legacy components had with their static outputs.
- Fix broken docs links: the legacy-component banners now use version-aware
  relative links (./operations.mdx) so they resolve within the unreleased docs
  version (the new page is not in the released 1.10.0 snapshot).
- JSON Operations raises a clear error for a removed operation (e.g. the old
  "Filter Values") instead of silently returning empty data.
- Text Clean's remove_extra_spaces preserves newlines so remove_empty_lines
  stays effective when both are enabled.
- Point FilterDataValues' replacement to [] (its capability was removed, not
  carried into Operations).
- Drop an unreachable branch in combine_data; clarify operations.mdx text.
- Regenerate component index and locales; add regression tests.
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 18, 2026
@github-actions

This comment has been minimized.

@Empreiteiro Empreiteiro self-requested a review June 22, 2026 19:08
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jun 22, 2026
@github-actions

github-actions Bot commented Jun 22, 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

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant