Skip to content

feat: Add multiple handles support for list inputs#10117

Closed
rodrigosnader wants to merge 2 commits into
mainfrom
feat/multiple-handles-for-list-inputs
Closed

feat: Add multiple handles support for list inputs#10117
rodrigosnader wants to merge 2 commits into
mainfrom
feat/multiple-handles-for-list-inputs

Conversation

@rodrigosnader
Copy link
Copy Markdown
Contributor

@rodrigosnader rodrigosnader commented Oct 4, 2025

Summary

  • Enable multiple handles for list inputs with input_types defined
  • Each list item gets its own connection handle for granular input control
  • Maintain backward compatibility with existing single-handle behavior

Key Changes

  1. URL Component: Added input_types=["Message"] to enable multiple handles
  2. NodeInputField: Added detection and rendering logic for multiple handles
  3. Handle Positioning: Implemented precise positioning with 55px base + 45.8px spacing
  4. Unique Handle IDs: Generate unique IDs using ${id.id}_${i} pattern
  5. Dynamic Container Height: Adjust container height based on number of handles

Technical Details

  • Only applies to inputs with both is_list=True AND input_types defined
  • Maintains compatibility with existing validation logic
  • Uses absolute positioning with transform for precise handle placement
  • Added constants for maintainable positioning values

Test Plan

  • Verify URL component shows multiple handles for each URL input
  • Test connections from different Message sources to each handle
  • Confirm existing single-handle inputs remain unchanged
  • Validate no frontend crashes or console errors
  • Check that handle tooltips show correct input types
  • Check possible impact in every other component handles

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Multi-handle support for list inputs in the node editor, enabling multiple connections per field with auto-adjusted node sizing for clarity.
  • Bug Fixes

    • Standardized URL input behavior across starter projects, enforcing the correct input type for URL fields to improve validation, compatibility, and stability.

Adds support for rendering individual handles for each item in list inputs that have input_types defined, enabling users to connect different sources to each list item independently.

## Changes Made

### Backend
- **URL Component**: Added `input_types=["Message"]` to enable multiple handles for the URLs list input

### Frontend
- **NodeInputField**: Added logic to detect list inputs with input_types and render multiple handles
- **Handle Positioning**: Implemented precise positioning (55px base + 45.8px spacing) for multiple handles
- **Unique Handle IDs**: Each handle gets a unique ID by appending index to prevent conflicts
- **Dynamic Height**: Container height adjusts based on number of handles

## Features
- ✅ **Individual Connections**: Connect different sources to each URL input independently
- ✅ **Proper Validation**: Connections work correctly without "invalid connection" errors
- ✅ **Correct Tooltips**: Shows proper input types without index suffixes
- ✅ **Responsive Design**: Handles scale with list length dynamically

## Technical Details
- Only applies to list inputs with `is_list=True` AND `input_types` defined
- Uses constants for maintainable positioning values
- Preserves existing single handle behavior for non-list inputs
- Falls back gracefully for list inputs without input_types

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Oct 4, 2025

Walkthrough

Updates tighten URLComponent input types to ["Message"] across starter projects and lfx implementation, update embedded code/code_hash, and add multi-handle support for list inputs in the frontend NodeInputField with dynamic layout adjustments.

Changes

Cohort / File(s) Summary of changes
Starter projects: URLComponent input_types and code metadata
src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json, src/backend/base/langflow/initial_setup/starter_projects/Knowledge Ingestion.json, src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json
For URLComponent, set urls.input_types from [] to ["Message"]; updated embedded code/value and metadata.code_hash accordingly.
Frontend multi-handle for list inputs
src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx
Replaced single-handle rendering with logic that renders multiple handles when isList with input types; computes listLength from template value; positions handles vertically; adjusts container min-height; preserves single-handle fallback.
LFX URL component input constraint
src/lfx/src/lfx/components/data/url.py
Changed MessageTextInput "urls" input_types from [] to ["Message"] in URLComponent.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant N as NodeInputField
  participant T as Template Data
  participant H as HandleRenderComponent

  U->>N: Open node with list input
  N->>T: Read template[name].value
  T-->>N: value (array or scalar)
  Note over N: Determine listLength (>=1)
  alt listLength > 1
    loop For each index i
      N->>H: Render handle i with id suffix "_i"
      Note right of H: Position with base offset + i*spacing
    end
  else Single handle
    N->>H: Render single handle
  end
  Note over N: Adjust container min-height based on listLength
Loading
sequenceDiagram
  autonumber
  participant UI as UI Connector
  participant B as Backend
  participant URL as URLComponent

  UI->>B: Provide urls input (type: Message)
  B->>URL: Invoke with urls: Message
  URL-->>B: Accepts due to input_types=["Message"]
  B-->>UI: Continue pipeline
  Note over URL: Non-Message inputs are rejected earlier by type checks
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

size:M, lgtm

Suggested reviewers

  • ogabrielluiz
  • mendonk
  • erichare

Pre-merge checks and finishing touches

❌ Failed checks (1 error, 3 warnings)
Check name Status Explanation Resolution
Test Coverage For New Implementations ❌ Error The PR updates multiple starter project JSONs, the reusable URLComponent backend implementation, and the frontend NodeInputField to support multiple handles, but no new or modified test files appear in the diff. Given the breadth of new behavior—especially the frontend rendering logic and backend input-type changes—regression or feature tests would normally be expected, yet none are provided, failing the coverage requirement for new implementations. Please add appropriate automated tests covering the new multi-handle rendering logic and the updated URL component behavior, ensuring they follow the project’s naming conventions, and then rerun this check.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Test Quality And Coverage ⚠️ Warning I reviewed the PR and found no new or updated automated tests (unit, integration, or end-to-end) covering the multiple-handle rendering logic in NodeInputField or the tighter input_types=["Message"] validation across the updated URL components. Given the substantial UI behavior change and backend configuration adjustments, the absence of tests leaves the feature unvalidated and fails to meet the stated testing expectations. Please add targeted tests that verify multiple handles render correctly for list inputs with defined input_types, and include coverage ensuring the new Message-only constraint on URL inputs behaves as intended.
Test File Naming And Structure ⚠️ Warning I inspected the repository for relevant test coverage around the updated URL component and the NodeInputField multi-handle logic, but found no backend test_*.py files or frontend *.test.ts/tsx exercises touching these changes, and no integration tests covering the new behavior. Consequently there are no descriptive test functions, setup/teardown, nor positive and negative scenario validations for the affected functionality, leaving the new multiple-handle feature and stricter input types without automated verification. Add or update automated tests following the required naming conventions to cover the new multiple-handle list input behavior and the URL component changes, ensuring meaningful test names, proper organization, and inclusion of both success and failure scenarios before re-running this check.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title concisely and accurately describes the primary feature introduced: adding support for multiple handles on list inputs. It focuses on the main implementation change without extraneous details, aligning with the changes in NodeInputField and associated updates. The title is clear, specific, and easily understood by reviewers scanning the history.
Excessive Mock Usage Warning ✅ Passed No test files were modified in this pull request, so there are no new or altered tests employing mocks; therefore the concern about excessive mock usage does not apply here.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/multiple-handles-for-list-inputs

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 and usage tips.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 4, 2025
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Oct 4, 2025

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 11%
10.94% (2889/26392) 4.56% (926/20300) 6.51% (372/5712)

Unit Test Results

Tests Skipped Failures Errors Time
1200 0 💤 0 ❌ 0 🔥 14.241s ⏱️

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 4, 2025
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Oct 4, 2025

@codecov
Copy link
Copy Markdown

codecov Bot commented Oct 4, 2025

Codecov Report

❌ Patch coverage is 0% with 24 lines in your changes missing coverage. Please review.
✅ Project coverage is 24.15%. Comparing base (662f069) to head (99780b9).
⚠️ Report is 483 commits behind head on main.

Files with missing lines Patch % Lines
...es/GenericNode/components/NodeInputField/index.tsx 0.00% 24 Missing ⚠️

❌ Your patch status has failed because the patch coverage (0.00%) is below the target coverage (40.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project status has failed because the head coverage (47.08%) is below the target coverage (55.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #10117      +/-   ##
==========================================
- Coverage   24.17%   24.15%   -0.02%     
==========================================
  Files        1086     1086              
  Lines       40044    40088      +44     
  Branches     5541     5556      +15     
==========================================
+ Hits         9679     9682       +3     
- Misses      30194    30235      +41     
  Partials      171      171              
Flag Coverage Δ
backend 47.08% <ø> (ø)
frontend 10.09% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...es/GenericNode/components/NodeInputField/index.tsx 0.00% <0.00%> (ø)

... and 7 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.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Oct 4, 2025
Copy link
Copy Markdown
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: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa96d74 and 99780b9.

📒 Files selected for processing (5)
  • src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json (3 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Knowledge Ingestion.json (3 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json (3 hunks)
  • src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx (3 hunks)
  • src/lfx/src/lfx/components/data/url.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/frontend/src/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

src/frontend/src/**/*.{ts,tsx,js,jsx}: All frontend TypeScript and JavaScript code should be located under src/frontend/src/ and organized into components, pages, icons, stores, types, utils, hooks, services, and assets directories as per the specified directory layout.
Use React 18 with TypeScript for all UI components in the frontend.
Format all TypeScript and JavaScript code using the make format_frontend command.
Lint all TypeScript and JavaScript code using the make lint command.

Files:

  • src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx
🧠 Learnings (1)
📚 Learning: 2025-06-23T12:46:42.048Z
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-06-23T12:46:42.048Z
Learning: Custom React Flow node types should be implemented as memoized components, using Handle components for connection points and supporting optional icons and labels.

Applied to files:

  • src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx
🪛 GitHub Actions: autofix.ci
src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx

[error] 1-1: Autofix CI step reported as error: 'Autofix task started.' Artifact 'autofix.ci.zip' uploaded and finalized. Exit status indicates failure.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Frontend Unit Tests / Frontend Jest Unit Tests
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Test Starter Templates
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Frontend Tests / Determine Test Suites and Shard Distribution
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Starter Projects
  • GitHub Check: test-starter-projects
🔇 Additional comments (1)
src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json (1)

1256-1258: Typed handles enable multi-handle support.

Restricting urls to ["Message"] matches the MessageTextInput semantics and activates the new per-item handle behavior without breaking existing connections. Nicely aligned with the frontend changes.

Comment on lines +212 to 214
shouldRenderMultipleHandles &&
`min-h-[${CONTAINER_BASE_HEIGHT + listLength * CONTAINER_HEIGHT_PER_HANDLE + CONTAINER_HEIGHT_PADDING}px]`, // Adjust height for multiple handles
)}
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.

⚠️ Potential issue | 🟠 Major

Computed Tailwind class never materializes

min-h-[${…}] is built at runtime, so Tailwind never emits the corresponding utility. The container keeps the default min-height and the stacked handles end up overlapping/overflowing for lists with more than one item. Move the sizing logic to an inline style (React will append px for numeric values) so the container reliably grows with listLength.

Apply this diff:

     <div
       ref={ref}
       className={cn(
         "relative flex min-h-10 w-full flex-wrap items-center justify-between px-5 py-2",
         lastInput ? "rounded-b-[0.69rem] pb-5" : "",
         isToolMode && "bg-primary/10",
         (name === "code" && type === "code") || (name.includes("code") && proxy)
           ? "hidden"
           : ""
-        shouldRenderMultipleHandles && 
-          `min-h-[${CONTAINER_BASE_HEIGHT + listLength * CONTAINER_HEIGHT_PER_HANDLE + CONTAINER_HEIGHT_PADDING}px]`,
       )}
+      style={
+        shouldRenderMultipleHandles
+          ? {
+              minHeight:
+                CONTAINER_BASE_HEIGHT +
+                listLength * CONTAINER_HEIGHT_PER_HANDLE +
+                CONTAINER_HEIGHT_PADDING,
+            }
+          : undefined
+      }
     >
📝 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.

Suggested change
shouldRenderMultipleHandles &&
`min-h-[${CONTAINER_BASE_HEIGHT + listLength * CONTAINER_HEIGHT_PER_HANDLE + CONTAINER_HEIGHT_PADDING}px]`, // Adjust height for multiple handles
)}
<div
ref={ref}
className={cn(
"relative flex min-h-10 w-full flex-wrap items-center justify-between px-5 py-2",
lastInput ? "rounded-b-[0.69rem] pb-5" : "",
isToolMode && "bg-primary/10",
(name === "code" && type === "code") || (name.includes("code") && proxy)
? "hidden"
: ""
)}
style={
shouldRenderMultipleHandles
? {
minHeight:
CONTAINER_BASE_HEIGHT +
listLength * CONTAINER_HEIGHT_PER_HANDLE +
CONTAINER_HEIGHT_PADDING,
}
: undefined
}
>
🤖 Prompt for AI Agents
In src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx
around lines 212 to 214, the runtime-built Tailwind class `min-h-[${...}]` never
gets emitted so the container doesn't grow for multiple handles; replace that
dynamic class with an inline style: compute the desired height as
CONTAINER_BASE_HEIGHT + listLength * CONTAINER_HEIGHT_PER_HANDLE +
CONTAINER_HEIGHT_PADDING and, when shouldRenderMultipleHandles is true, set
style={{ minHeight: computedHeight }} (use a numeric value so React appends px);
remove the runtime `min-h-[...]` class and keep the existing classes otherwise
so the container reliably expands for varying listLength.

@rodrigosnader
Copy link
Copy Markdown
Contributor Author

Closing - no longer needed

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