feat: Add multiple handles support for list inputs#10117
Conversation
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>
WalkthroughUpdates 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
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
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 error, 3 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
|
Codecov Report❌ Patch coverage is
❌ 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. Additional details and impacted files@@ 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
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 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
urlsto["Message"]matches theMessageTextInputsemantics and activates the new per-item handle behavior without breaking existing connections. Nicely aligned with the frontend changes.
| shouldRenderMultipleHandles && | ||
| `min-h-[${CONTAINER_BASE_HEIGHT + listLength * CONTAINER_HEIGHT_PER_HANDLE + CONTAINER_HEIGHT_PADDING}px]`, // Adjust height for multiple handles | ||
| )} |
There was a problem hiding this comment.
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.
| 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.
|
Closing - no longer needed |



Summary
Key Changes
input_types=["Message"]to enable multiple handles${id.id}_${i}patternTechnical Details
is_list=TrueANDinput_typesdefinedTest Plan
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes