-
Notifications
You must be signed in to change notification settings - Fork 8.7k
feat: adds inspection panel to show node inputs #11263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
cce966a
5429a4b
ebe8886
b6bb0d4
2369db5
deedd21
bc12b15
63eca6c
dc6c424
7355fb4
830beb9
a50cee2
3673b68
e51e4ee
f541e1c
d2fbfdf
61d1b6e
a4ab8ff
12407f9
1dd1bb6
f494cc4
29ce8d5
d0c6831
745760c
eca1e53
dca90a5
28cc19f
725e3ee
8d3bf63
504f4b3
d005c4e
1331af6
bee5509
8c81ffe
e5ebd57
27fa9ad
8b30f2a
ae227b5
e0c1f69
5b1d13a
1a27d8b
9b9f6d7
f6dc533
5030b8c
7ee16b4
004259d
c80f9f7
e0dd8e9
9fa1457
cc58b05
7eb1204
2ff9c28
6931607
4935cf7
dc99e57
42b900c
7cd9b72
25462a2
003c8d7
853397e
dd688be
3b0c6d5
acf2190
a9b5f2e
17e14ed
fe3d7ee
033dab6
e5c4918
46926f3
5d5b0a9
f2213f6
5a11d5b
b10742e
76f5f51
faa62a1
0673a22
16ae4d1
367b001
c09828e
bd004b8
d91435a
d431b81
679666e
e5c3215
df7a616
2eda317
38181c0
a8f8cc3
6af30eb
5de486e
c446323
fdd4345
4fb186f
9e905aa
9b32822
85b4715
5f27e35
ac05916
a232854
e8ac894
4cee0bc
ac3a479
a8db935
9c5c16e
7e47e6a
2e4e78b
2d0295a
75fabc0
093da5d
e6825d1
e05d63d
efa86ac
7df3f80
c187f35
6bed58e
2ab8326
780ec33
ba49307
cac19ad
1eddc36
4b3ff13
13fa51c
5d04d36
b8e1a29
7e1807f
3bb44c4
324eeeb
adc987a
a0207c5
7dbd0a6
f05be04
58772a8
a50dd4e
1d6119e
7668741
247da1b
eb0d19f
3991d9e
66af60f
7802a65
e4a8842
4ddd510
dc5b072
f196e53
af3f23c
1fd3d97
349319f
a4a3eb3
011d4e5
f08726f
d63e727
3973118
547b497
ea68fb3
caf5e02
98e624a
ba078c3
c33ca06
160cbe7
2ba7677
f167242
d817d8f
4493e8f
3ec91fc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,191 @@ | ||
| import { useMemo } from "react"; | ||
| import { AssistantButton } from "@/components/common/assistant"; | ||
| import IconComponent from "@/components/common/genericIconComponent"; | ||
| import ShadTooltip from "@/components/common/shadTooltipComponent"; | ||
| import { | ||
| CustomParameterComponent, | ||
| CustomParameterLabel, | ||
| getCustomParameterTitle, | ||
| } from "@/customization/components/custom-parameter"; | ||
| import { LANGFLOW_AGENTIC_EXPERIENCE } from "@/customization/feature-flags"; | ||
| import { useIsAutoLogin } from "@/hooks/use-is-auto-login"; | ||
| import useAuthStore from "@/stores/authStore"; | ||
| import useFlowStore from "@/stores/flowStore"; | ||
| import { useTypesStore } from "@/stores/typesStore"; | ||
| import type { NodeInputFieldComponentType } from "@/types/components"; | ||
| import { cn } from "@/utils/utils"; | ||
| import { | ||
| DEFAULT_TOOLSET_PLACEHOLDER, | ||
| FLEX_VIEW_TYPES, | ||
| ICON_STROKE_WIDTH, | ||
| } from "@/constants/constants"; | ||
| import useHandleNodeClass from "@/CustomNodes/hooks/use-handle-node-class"; | ||
| import { usePostTemplateValue } from "@/controllers/API/queries/nodes/use-post-template-value"; | ||
| import useFetchDataOnMount from "@/CustomNodes/hooks/use-fetch-data-on-mount"; | ||
| import useHandleOnNewValue from "@/CustomNodes/hooks/use-handle-new-value"; | ||
| import NodeInputInfo from "@/CustomNodes/GenericNode/components/NodeInputInfo"; | ||
|
|
||
| export default function InspectionPanelField({ | ||
| id, | ||
| data, | ||
| title, | ||
| name = "", | ||
| required = false, | ||
| info = "", | ||
| showNode, | ||
| isToolMode = false, | ||
| proxy, | ||
| }: Omit< | ||
| NodeInputFieldComponentType, | ||
| | "colors" | ||
| | "tooltipTitle" | ||
| | "type" | ||
| | "optionalHandle" | ||
| | "colorName" | ||
| | "lastInput" | ||
| >) { | ||
| const isAuthenticated = useAuthStore((state) => state.isAuthenticated); | ||
| const isAutoLogin = useIsAutoLogin(); | ||
| const shouldDisplayApiKey = isAuthenticated && !isAutoLogin; | ||
|
|
||
| const { currentFlowId, currentFlowName } = useFlowStore((state) => ({ | ||
| currentFlowId: state.currentFlow?.id, | ||
| currentFlowName: state.currentFlow?.name, | ||
| })); | ||
|
|
||
| const myData = useTypesStore((state) => state.data); | ||
| const postTemplateValue = usePostTemplateValue({ | ||
| node: data.node!, | ||
| nodeId: data.id, | ||
| parameterId: name, | ||
| }); | ||
|
|
||
| const { handleNodeClass } = useHandleNodeClass(data.id); | ||
|
|
||
| const { handleOnNewValue } = useHandleOnNewValue({ | ||
| node: data.node!, | ||
| nodeId: data.id, | ||
| name, | ||
| }); | ||
|
|
||
| const nodeInformationMetadata = useMemo(() => { | ||
| return { | ||
| flowId: currentFlowId ?? "", | ||
| nodeType: data?.type?.toLowerCase() ?? "", | ||
| flowName: currentFlowName ?? "", | ||
| isAuth: shouldDisplayApiKey!, | ||
| variableName: name, | ||
| }; | ||
| }, [data?.node?.id, shouldDisplayApiKey, name]); | ||
|
|
||
|
Comment on lines
+67
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix
Proposed fix const nodeInformationMetadata = useMemo(() => {
return {
flowId: currentFlowId ?? "",
nodeType: data?.type?.toLowerCase() ?? "",
flowName: currentFlowName ?? "",
isAuth: shouldDisplayApiKey!,
variableName: name,
};
- }, [data?.node?.id, shouldDisplayApiKey, name]);
+ }, [currentFlowId, currentFlowName, data?.type, shouldDisplayApiKey, name]);🤖 Prompt for AI Agents |
||
| useFetchDataOnMount( | ||
| data.node!, | ||
| data.id, | ||
| handleNodeClass, | ||
| name, | ||
| postTemplateValue, | ||
| ); | ||
|
|
||
| const template = data.node?.template[name]; | ||
| const type = template?.type; | ||
| const isFlexView = FLEX_VIEW_TYPES.includes(type ?? ""); | ||
|
|
||
| return ( | ||
| <div | ||
| className={cn( | ||
| "relative flex min-h-10 w-full flex-wrap items-center justify-between px-3 py-1.5", | ||
| isToolMode && "bg-primary/10", | ||
| (name === "code" && type === "code") || (name.includes("code") && proxy) | ||
| ? "hidden" | ||
| : "", | ||
| )} | ||
|
Comment on lines
+87
to
+94
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # First, let's read the file to understand the full context
cat -n "src/frontend/src/pages/FlowPage/components/InspectionPanel/components/InspectionPanelField.tsx" | head -120 | tail -40Repository: langflow-ai/langflow Length of output: 1500 🏁 Script executed: # Get more context around lines 94-101
wc -l "src/frontend/src/pages/FlowPage/components/InspectionPanel/components/InspectionPanelField.tsx"Repository: langflow-ai/langflow Length of output: 162 🏁 Script executed: # Read the entire file to understand the component structure
cat -n "src/frontend/src/pages/FlowPage/components/InspectionPanel/components/InspectionPanelField.tsx"Repository: langflow-ai/langflow Length of output: 7409 🏁 Script executed: # Search for where this component is used and what name values are passed
rg "InspectionPanelField" --type tsx -A 3 -B 1 | head -100Repository: langflow-ai/langflow Length of output: 91 🏁 Script executed: # Look for field names that might contain "code"
rg "name.*code|code.*name" --type tsx -i | head -50Repository: langflow-ai/langflow Length of output: 91 🏁 Script executed: # Search for InspectionPanelField usage with name parameters
rg "InspectionPanelField" -A 5 -B 2 | head -150Repository: langflow-ai/langflow Length of output: 5862 🏁 Script executed: # Search for field definitions that might contain "code" in their names
rg "name.*=.*code|code.*name" --type ts --type tsx -i -A 2 -B 2 | head -100Repository: langflow-ai/langflow Length of output: 91 🏁 Script executed: # Look for template fields that might be passed as name prop
rg "template\[.*code" --type ts --type tsx -A 2 -B 2 | head -50Repository: langflow-ai/langflow Length of output: 91 🏁 Script executed: # Search for what proxy fields might be and their naming patterns
rg "proxy" --type tsx -B 3 -A 3 "InspectionPanel" | head -80Repository: langflow-ai/langflow Length of output: 91 🏁 Script executed: # Find all usages of name.includes pattern in codebase
rg 'name\.includes.*code' --type ts --type tsxRepository: langflow-ai/langflow Length of output: 91 🏁 Script executed: # Look for InspectionPanelFields.tsx to see how fields are iterated
cat -n "src/frontend/src/pages/FlowPage/components/InspectionPanel/components/InspectionPanelFields.tsx"Repository: langflow-ai/langflow Length of output: 2970 🏁 Script executed: # Search for name.includes pattern anywhere in the codebase
rg 'name\.includes' -A 2 -B 2 | head -80Repository: langflow-ai/langflow Length of output: 5103 🏁 Script executed: # Look for proxy-related field names in templates
rg '"code"' src/frontend --max-count 50 | grep -i nameRepository: langflow-ai/langflow Length of output: 4997 🏁 Script executed: # Search for field definitions/templates that contain "code" in various files
rg '"[^"]*code[^"]*":\s*{' -A 3 src/frontend --max-count 30Repository: langflow-ai/langflow Length of output: 169 🏁 Script executed: # Look for proxy field definitions with "code" in their names
rg 'proxy.*true' src/backend -A 2 -B 2 | grep -i code | head -50Repository: langflow-ai/langflow Length of output: 50376 🏁 Script executed: # Check NodeInputField to see if it has similar logic
cat -n "src/frontend/src/CustomNodes/GenericNode/components/NodeInputField/index.tsx" | grep -A 10 -B 10 'name.includes.*code'Repository: langflow-ai/langflow Length of output: 772 🏁 Script executed: # Search for proxy field definitions with any field names
rg '"proxy".*"field"' -A 2 -B 2 | head -80Repository: langflow-ai/langflow Length of output: 50377 🏁 Script executed: # Look for any fields that might be code-related with proxy
rg 'includes.*code|encode|decode' src/frontend --type ts -A 3 -B 3 | head -100Repository: langflow-ai/langflow Length of output: 6939 🏁 Script executed: # Check the actual backend to understand what fields exist
find src/backend -name "*.py" -type f | head -20 | xargs rg 'proxy.*=.*True' -A 2 -B 2 | head -80Repository: langflow-ai/langflow Length of output: 46 🏁 Script executed: # Search for actual proxy field patterns and names more carefully
rg '"field"\s*:\s*"[^"]*code' src/backend src/frontend -A 1 -B 1 | head -50Repository: langflow-ai/langflow Length of output: 1330 🏁 Script executed: # Check if there are any Python definitions of fields with "code" in name and proxy=True
find src/backend -name "*.py" -type f -exec grep -l "proxy.*True" {} \; | head -5 | xargs grep -B 5 -A 5 'name.*=.*' | grep -i codeRepository: langflow-ai/langflow Length of output: 46 🏁 Script executed: # Let's verify the filtering is indeed redundant by checking if any fields pass both filters
python3 << 'EOF'
# Simulate the logic from InspectionPanelFields
test_fields = [
("code", {"show": True, "type": "code"}),
("model_kwargs", {"show": True, "type": "code", "proxy": {"id": "x", "field": "y"}}),
("my_code_field", {"show": True, "type": "str", "proxy": {"id": "x", "field": "z"}}),
("code_handler", {"show": True, "type": "str", "proxy": {"id": "x", "field": "w"}}),
("llm", {"show": True, "type": "BaseLanguageModel", "proxy": {"id": "x", "field": "llm"}}),
]
print("Fields that would be filtered (redundantly hidden in InspectionPanelField):")
for field_name, template in test_fields:
if (field_name == "code" and template.get("type") == "code") or (field_name.includes("code") and template.get("proxy")):
print(f" - {field_name}: includes('code')={field_name.includes('code')}, proxy={bool(template.get('proxy'))}")
EOFRepository: langflow-ai/langflow Length of output: 150 🏁 Script executed: # Better approach - check actual field data from real flows
rg -A 15 '"template"\s*:' src/backend/tests/data/grouped_chat.json 2>/dev/null | grep -E '"name"|"type"|"proxy"' | head -40Repository: langflow-ai/langflow Length of output: 20337 🏁 Script executed: # Check if fields filtered in InspectionPanelFields ever reach InspectionPanelField
cat -n "src/frontend/src/pages/FlowPage/components/InspectionPanel/components/InspectionPanelFields.tsx" | head -50Repository: langflow-ai/langflow Length of output: 1946 Tighten the field name matching to avoid unintentionally hiding unrelated fields. The condition Suggested fix- (name === "code" && type === "code") || (name.includes("code") && proxy)
+ (name === "code" && type === "code") ||
+ (proxy && /(^|_)code($|_)/.test(name))
? "hidden"
: "",🤖 Prompt for AI Agents |
||
| > | ||
| <div | ||
| className={cn( | ||
| "flex w-full flex-col gap-2", | ||
| isFlexView ? "flex-row" : "flex-col", | ||
| )} | ||
| > | ||
| <div className="flex w-full items-center justify-between text-sm"> | ||
| <div className="flex w-full items-center truncate"> | ||
| {proxy ? ( | ||
| <ShadTooltip content={<span>{proxy.id}</span>}> | ||
| <span> | ||
| {getCustomParameterTitle({ | ||
| title, | ||
| nodeId: data.id, | ||
| isFlexView, | ||
| required, | ||
| })} | ||
| </span> | ||
| </ShadTooltip> | ||
| ) : ( | ||
| <div className="flex gap-2"> | ||
| <span className="text-sm font-medium"> | ||
| {getCustomParameterTitle({ | ||
| title, | ||
| nodeId: data.id, | ||
| isFlexView, | ||
| required, | ||
| })} | ||
| </span> | ||
| </div> | ||
| )} | ||
| <div> | ||
| {info !== "" && ( | ||
| <ShadTooltip content={<NodeInputInfo info={info} />}> | ||
| <div className="cursor-help"> | ||
| <IconComponent | ||
| name="Info" | ||
| strokeWidth={ICON_STROKE_WIDTH} | ||
| className="relative ml-1 h-3 w-3 text-placeholder" | ||
| /> | ||
| </div> | ||
| </ShadTooltip> | ||
| )} | ||
| </div> | ||
| {LANGFLOW_AGENTIC_EXPERIENCE && | ||
| data.node?.template[name]?.ai_enabled && ( | ||
| <AssistantButton | ||
| compData={id} | ||
| handleOnNewValue={handleOnNewValue} | ||
| inputValue={data.node?.template[name]?.value} | ||
| type="field" | ||
| /> | ||
| )} | ||
| </div> | ||
| <CustomParameterLabel | ||
| name={name} | ||
| nodeId={data.id} | ||
| templateValue={data.node?.template[name]} | ||
| nodeClass={data.node!} | ||
| /> | ||
| </div> | ||
|
|
||
| {data.node?.template[name] !== undefined && ( | ||
| <CustomParameterComponent | ||
| handleOnNewValue={handleOnNewValue} | ||
| name={name} | ||
| nodeId={data.id} | ||
| inputId={id} | ||
| templateData={data.node?.template[name]!} | ||
| templateValue={data.node?.template[name].value ?? ""} | ||
| editNode={false} | ||
| handleNodeClass={handleNodeClass} | ||
| nodeClass={data.node!} | ||
| placeholder={ | ||
| isToolMode | ||
| ? DEFAULT_TOOLSET_PLACEHOLDER | ||
| : data.node?.template[name].placeholder | ||
| } | ||
| isToolMode={isToolMode} | ||
| nodeInformationMetadata={nodeInformationMetadata} | ||
| proxy={proxy} | ||
| /> | ||
| )} | ||
| </div> | ||
| </div> | ||
| ); | ||
| } | ||
|
|
||
| // Made with Bob | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,81 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useMemo } from "react"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { sortToolModeFields } from "@/CustomNodes/helpers/sort-tool-mode-field"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import getFieldTitle from "@/CustomNodes/utils/get-field-title"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import type { NodeDataType } from "@/types/flow"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { LANGFLOW_SUPPORTED_TYPES } from "@/constants/constants"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import InspectionPanelField from "./InspectionPanelField"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| interface InspectionPanelFieldsProps { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data: NodeDataType; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default function InspectionPanelFields({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }: InspectionPanelFieldsProps) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Get all fields in one list - show ALL fields in Inspection Panel | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const allFields = useMemo(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return Object.keys(data.node?.template || {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter((templateField) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const template = data.node?.template[templateField]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Filter out fields that shouldn't be shown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| templateField.charAt(0) === "_" || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| !template?.show || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (templateField === "code" && template.type === "code") || | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (templateField.includes("code") && template.proxy) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .sort((a, b) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sortToolModeFields( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| a, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| b, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data.node!.template, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data.node?.field_order ?? [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, [data.node?.template, data.node?.field_order]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (allFields.length === 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center justify-center p-8 text-sm text-muted-foreground"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| No fields available | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="space-y-2 p-3"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {allFields.map((templateField: string) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const template = data.node?.template[templateField]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <InspectionPanelField | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| key={`${data.id}-${templateField}`} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data={data} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title={getFieldTitle(data.node?.template!, templateField)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| info={template.info!} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name={templateField} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| required={template.required} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id={{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputTypes: template.input_types, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: template.type, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: data.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fieldName: templateField, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| proxy={template.proxy} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| showNode={true} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isToolMode={false} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+141
to
+146
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a defensive guard for missing template entries to avoid runtime crashes. If Proposed fix return (
<div className="space-y-2 p-3">
{allFields.map((templateField: string) => {
- const template = data.node?.template[templateField];
+ const template = data.node?.template?.[templateField];
+ if (!template) return null;
return (
<InspectionPanelField
key={`${data.id}-${templateField}`}
data={data}
title={getFieldTitle(data.node?.template!, templateField)}
- info={template.info!}
+ info={template.info ?? ""}
name={templateField}
- required={template.required}
+ required={!!template.required}
id={{
inputTypes: template.input_types,
type: template.type,
id: data.id,
fieldName: templateField,
}}
proxy={template.proxy}
showNode={true}
isToolMode={false}
/>
);
})}
</div>
);📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Made with Bob | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 91
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 234
🏁 Script executed:
# Look at the actual RenderInputParameters file to see the full context wc -l src/frontend/src/CustomNodes/GenericNode/components/RenderInputParameters/index.tsxRepository: langflow-ai/langflow
Length of output: 151
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 2926
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 91
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 2549
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 294
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 2664
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 46
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 5769
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 6099
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 2347
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 404
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 46
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 2371
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 46
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 268
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 1859
🏁 Script executed:
Repository: langflow-ai/langflow
Length of output: 788
Address the "blank row" risk where fields have input_types + refresh_button but no visible editor or handle.
The filter passes any field with
input_types, but NodeInputField hides its editor whenoptionalHandleis present (line 230). If such a field also hasrefresh_button: trueand is not a model type, the condition(!hasRefreshButton || isModelInput)becomes false, hiding the handle as well. This leaves an empty row with neither editor nor connection point.Verify that no field template combines
refresh_button: true, non-emptyinput_types, andtype ≠ "model", or if such fields exist, confirm this blank-row rendering is intentional.Additionally, harden the
input_typescheck to useArray.isArray()for defensive programming, matching the pattern already used elsewhere in NodeInputField (line 109):Proposed change
📝 Committable suggestion
🤖 Prompt for AI Agents