-
Notifications
You must be signed in to change notification settings - Fork 8.2k
feat: Add Prompt generation Agentic Experience #11097
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
base: main
Are you sure you want to change the base?
Conversation
The run CLI command now accepts --env-var KEY=VALUE options to inject global variables into the graph context. Includes validation for variable format and unit tests to verify correct injection and error handling. Also improves script loading to register modules by script name for better inspection.
Updated environment variable loading logic to prioritize CLI-provided variables (request_variables in context) over OS environment variables for load_from_db fields. Added unit tests to verify correct precedence and fallback behavior.
…ngflow-ai/langflow into feat-variable-passthrough-lfx
Refactors the run CLI command to delegate execution logic to a new lfx.run.base module, improving separation of concerns and maintainability. Moves core run logic and error handling into lfx.run.base, introduces a RunError exception, and updates tests to target the new structure. Removes the --env-var option from the CLI and migrates related tests to the run module.
Co-authored-by: Gabriel Luiz Freitas Almeida <[email protected]>
Co-authored-by: Gabriel Luiz Freitas Almeida <[email protected]>
add nudge code and use new prompt endpoint
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.
Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.
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.
Actionable comments posted: 10
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/backend/base/langflow/api/utils/mcp/agentic_mcp.py (1)
217-244: Inconsistency between global and user variable initialization.
initialize_agentic_global_variablescreates only 3 hardcoded variables (FLOW_ID,COMPONENT_ID,FIELD_NAME) usingGENERIC_TYPE, whileinitialize_agentic_user_variables(lines 321-338) creates all 9 variables fromAGENTIC_VARIABLESusingCREDENTIAL_TYPE.This inconsistency could lead to:
- Different variable sets depending on initialization path
- Different variable types for the same logical variables
Consider aligning both functions to use the same variable set from
AGENTIC_VARIABLESand the same type.🔎 Suggested alignment
+ from lfx.services.settings.constants import AGENTIC_VARIABLES, DEFAULT_AGENTIC_VARIABLE_VALUE + # Define agentic variables with default values - agentic_variables = { - "FLOW_ID": "", - "COMPONENT_ID": "", - "FIELD_NAME": "", - } + agentic_variables = dict.fromkeys(AGENTIC_VARIABLES, DEFAULT_AGENTIC_VARIABLE_VALUE) # ... later in the loop ... await variable_service.create_variable( user_id=user.id, name=var_name, value=default_value, default_fields=[], - type_=GENERIC_TYPE, + type_=CREDENTIAL_TYPE, session=session, )
🟡 Minor comments (12)
src/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.ts-7-10 (1)
7-10: Missing type annotations for query parameters.The type definition uses shorthand property syntax without specifying types, which will result in implicit
anytypes. Explicitly define types for better type safety.🔎 Suggested fix
export const useGetNextSuggestedComponentQuery: useQueryFunctionType< - { compId; flowId; fieldName; inputValue }, + { compId: string; flowId: string; fieldName: string; inputValue: string }, {} > = ({ compId, flowId, fieldName, inputValue }, options) => {src/frontend/src/controllers/API/queries/assistant/use-agentic-prompt.ts-7-10 (1)
7-10: Missing type annotations for query parameters.Same issue as in
use-suggest-next-component.ts- the type definition uses shorthand property syntax without specifying types.🔎 Suggested fix
export const useAgenticPromptQuery: useQueryFunctionType< - { compId; flowId; fieldName; inputValue }, + { compId: string; flowId: string; fieldName: string; inputValue: string }, {} > = ({ compId, flowId, fieldName, inputValue }, options) => {src/backend/base/langflow/api/utils/mcp/agentic_mcp.py-325-330 (1)
325-330: Missingawaiton async logger calls.Lines 325 and 330 call
logger.adebug(...)withoutawait, while other logger calls in this file correctly useawait logger.adebug(...). This inconsistency could cause the log messages to not be properly awaited.🔎 Suggested fix
agentic_variables = dict.fromkeys(AGENTIC_VARIABLES, DEFAULT_AGENTIC_VARIABLE_VALUE) - logger.adebug(f"Agentic variables: {agentic_variables}") + await logger.adebug(f"Agentic variables: {agentic_variables}") existing_vars = await variable_service.list_variables(user_id, session) for var_name, default_value in agentic_variables.items(): - logger.adebug(f"Checking if agentic variable {var_name} exists for user {user_id}") + await logger.adebug(f"Checking if agentic variable {var_name} exists for user {user_id}")src/frontend/src/components/common/assistant/assistantButton.css-14-14 (1)
14-14: Verify this background color is intentional.The
rgb(132, 90, 90)produces a brownish-red color that appears inconsistent with the typical UI palette. This looks like a placeholder or debug value.src/frontend/src/components/common/assistant/index.tsx-48-64 (1)
48-64: Complete or remove the outside-click handler.The commented-out
useEffectfor handling clicks outside the popover leaves the UI without a way to dismiss the popover by clicking elsewhere. This is a common UX expectation for popovers. Either implement the handler or use an existing popover component from the UI library that handles this automatically.Do you want me to help implement the outside-click handler or suggest an alternative approach using existing UI components?
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsx-89-89 (1)
89-89: Fix typo:cursor-pointshould becursor-pointer.🔎 Proposed fix
- className="flex cursor-point items-center gap-2 rounded-md p-1 px-2 bg-accent text-placeholder-foreground h-8" + className="flex cursor-pointer items-center gap-2 rounded-md p-1 px-2 bg-accent text-placeholder-foreground h-8"src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx-182-185 (1)
182-185: Add akeyprop to the mappedPillcomponents.React requires a unique
keyprop when rendering lists to optimize reconciliation. Usingnudge.idif available would be appropriate.🔎 Proposed fix
{!nudegsLoading && componentNudges?.nudges.map((nudge) => { return ( - <Pill nudge={nudge} setNudgesOpen={setNudgesOpen}></Pill> + <Pill key={nudge.id} nudge={nudge} setNudgesOpen={setNudgesOpen} /> ); })}src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx-34-34 (1)
34-34: Fix typo:nudegsLoadingshould benudgesLoading.🔎 Proposed fix
- const [nudegsLoading, setNudgesLoading] = useState(true); + const [nudgesLoading, setNudgesLoading] = useState(true);Also update the usage on line 181:
- {!nudegsLoading && + {!nudgesLoading &&src/frontend/src/components/common/assistant/index.tsx-194-195 (1)
194-195: Pass thetypeprop instead of hardcoding"field".The
AssistantNudgescomponent receivestype="field"hardcoded, butAssistantButtonreceivestypeas a prop. This means the nudges won't behave correctly for other button types.🔎 Proposed fix
<AssistantNudges - type="field" + type={type} handleOnNewValue={handleOnNewValue} setNudgesOpen={setNudgesOpen} ></AssistantNudges>src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx-147-147 (1)
147-147: Use uniquedata-testidvalues for different inputs.Both textareas have
data-testid="prompt-user-input", which will cause issues with automated testing. The second textarea should have a distinct identifier.🔎 Proposed fix
<Textarea value={promptOutput} - data-testid="prompt-user-input" + data-testid="prompt-output" onChange={(e) => setPromptOutput(e.target.value)}src/backend/base/langflow/agentic/api/router.py-90-92 (1)
90-92: Avoid exposing internal exception details in API responses.The exception messages (e.g.,
f"Error executing flow: {e}") are returned directly to clients, which may expose internal implementation details. Consider using generic error messages for client responses while logging the full details.🔎 Proposed fix
except Exception as e: logger.error(f"Error executing flow: {e}") - raise HTTPException(status_code=500, detail=f"Error executing flow: {e}") from e + raise HTTPException(status_code=500, detail="An error occurred while executing the flow") from eAlso applies to: 132-134
src/backend/base/langflow/agentic/api/router.py-162-164 (1)
162-164: HTTPException is inappropriate in standalone script context.
HTTPExceptionis a FastAPI construct for returning HTTP error responses. In the__main__block running as a standalone script, this exception won't be caught by FastAPI's exception handler and will just raise as a regular exception.🔎 Proposed fix
except Exception as e: logger.error(f"Error executing flow: {e}") - raise HTTPException(status_code=500, detail=f"Error executing flow: {e}") from e + raise
🧹 Nitpick comments (10)
src/backend/base/langflow/agentic/utils/flow_graph.py (1)
82-91: Docstring is missingflow_descriptionandtagsfields.The return dictionary now includes
flow_description(line 85) andtags(line 90), but the docstring at lines 27-34 doesn't document these fields. Consider updating the docstring for completeness.🔎 Suggested docstring update
Returns: Dictionary containing: - flow_id: The flow ID - flow_name: The flow name + - flow_description: The flow description (empty string if none) - ascii_graph: ASCII art representation of the graph - text_repr: Text representation with vertices and edges - vertex_count: Number of vertices in the graph - edge_count: Number of edges in the graph + - tags: Flow tags - error: Error message if any (only if operation fails)src/frontend/src/controllers/API/helpers/constants.ts (1)
44-54: Consider using a more specific type thanObjectforparams.While changing from
anytoObjectis an improvement,Objectis still a weak type in TypeScript. Consider usingRecord<string, string | number>for better type safety, since the values are used in URL path construction.🔎 Suggested type improvement
export function getURL( key: keyof typeof URLs, - params: Object = {}, + params: Record<string, string | number> = {}, v2: boolean = false, ) {src/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.ts (1)
13-17: Add type annotations to function parameters.The inner function parameters lack type annotations, relying on implicit
any. This reduces type safety and IDE support.🔎 Suggested fix
const getNextSuggestedComponentFn = async ( - compId, - flowId, - fieldName, - inputValue, + compId: string, + flowId: string, + fieldName: string, + inputValue: string, ) => {src/frontend/src/controllers/API/queries/assistant/use-agentic-prompt.ts (1)
13-26: Add type annotations and consider removing empty headers.The function parameters lack type annotations. Additionally, the empty
headers: {}object on lines 22-24 is unnecessary and can be removed.🔎 Suggested improvements
- const getAgenticPromptFn = async (compId, flowId, fieldName, inputValue) => { + const getAgenticPromptFn = async ( + compId: string, + flowId: string, + fieldName: string, + inputValue: string, + ) => { return await api.post( getURL("AGENTIC_PROMPT"), { flow_id: flowId, component_id: compId, field_name: fieldName, input_value: inputValue, }, - { - headers: {}, - }, ); };src/frontend/src/components/common/assistant/assistantButton.css (2)
19-19: Reduce the excessive z-index value.A z-index of
1000000000000is unnecessarily extreme and can cause stacking context issues. Use a reasonable value like1000or9999that still ensures the popover appears above other content.🔎 Proposed fix
- z-index: 1000000000000; + z-index: 1000;
1-33: Consider using Tailwind CSS for styling consistency.Per coding guidelines, Tailwind CSS should be used for styling in frontend components. This raw CSS file may not integrate well with the existing design system and lacks dark mode support. Consider converting these styles to Tailwind utility classes or using CSS variables that respect the theme.
src/frontend/src/components/common/assistant/index.tsx (1)
33-35:popoverRefis unused since the click-outside handler is commented out.The
popoverRefis created but only referenced in the commented-out code. Either implement the click-outside functionality or remove the unused ref to avoid confusion.src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx (1)
134-134: Address TODO placeholder text before release.The UI contains TODO placeholder labels that should be replaced with actual helper text before the feature is released to users.
Do you want me to open an issue to track these TODO items?
Also applies to: 142-143, 173-173
src/backend/base/langflow/agentic/api/router.py (2)
27-33: Add type annotation for session parameter.The
sessionparameter lacks a type annotation. AddingAsyncSessionimproves code clarity and enables better IDE/type-checker support.🔎 Proposed fix
+from sqlmodel.ext.asyncio.session import AsyncSession + -async def get_openai_api_key(variable_service: DatabaseVariableService, user_id: UUID | str, session) -> str: +async def get_openai_api_key(variable_service: DatabaseVariableService, user_id: UUID | str, session: AsyncSession) -> str:
48-48: Move import to module level.The import is currently inside the
run_prompt_flowfunction with no circular dependency preventing a module-level import. Moving it to the top of the file improves readability and catches import errors at startup rather than at function invocation.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
src/backend/base/langflow/agentic/api/__init__.pysrc/backend/base/langflow/agentic/api/router.pysrc/backend/base/langflow/agentic/api/test.pysrc/backend/base/langflow/agentic/flows/PromptGeneration.jsonsrc/backend/base/langflow/agentic/utils/flow_graph.pysrc/backend/base/langflow/api/__init__.pysrc/backend/base/langflow/api/router.pysrc/backend/base/langflow/api/utils/mcp/agentic_mcp.pysrc/backend/base/langflow/main.pysrc/frontend/src/components/common/assistant/assistantButton.csssrc/frontend/src/components/common/assistant/assistantNudgeBar/index.tsxsrc/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/index.tsxsrc/frontend/src/controllers/API/helpers/constants.tssrc/frontend/src/controllers/API/queries/assistant/use-agentic-prompt.tssrc/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.tssrc/lfx/src/lfx/_assets/component_index.jsonsrc/lfx/src/lfx/services/settings/base.pysrc/lfx/src/lfx/services/settings/constants.py
🧰 Additional context used
📓 Path-based instructions (6)
src/backend/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
src/backend/**/*.py: Use FastAPI async patterns withawaitfor async operations in component execution methods
Useasyncio.create_task()for background tasks and implement proper cleanup with try/except forasyncio.CancelledError
Usequeue.put_nowait()for non-blocking queue operations andasyncio.wait_for()with timeouts for controlled get operations
Files:
src/backend/base/langflow/agentic/api/test.pysrc/backend/base/langflow/agentic/api/__init__.pysrc/backend/base/langflow/agentic/utils/flow_graph.pysrc/backend/base/langflow/api/__init__.pysrc/backend/base/langflow/agentic/api/router.pysrc/backend/base/langflow/main.pysrc/backend/base/langflow/api/router.pysrc/backend/base/langflow/api/utils/mcp/agentic_mcp.py
src/frontend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
src/frontend/src/**/*.{ts,tsx}: Use React 18 with TypeScript for frontend development
Use Zustand for state management
Files:
src/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.tssrc/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/controllers/API/queries/assistant/use-agentic-prompt.tssrc/frontend/src/controllers/API/helpers/constants.tssrc/frontend/src/components/common/assistant/assistantNudgeBar/index.tsxsrc/frontend/src/components/common/assistant/index.tsx
src/frontend/src/**/*.{tsx,jsx,css,scss}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
Use Tailwind CSS for styling
Files:
src/frontend/src/components/common/assistant/assistantButton.csssrc/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/assistantNudgeBar/index.tsxsrc/frontend/src/components/common/assistant/index.tsx
src/frontend/src/components/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
src/frontend/src/components/**/*.{tsx,jsx}: Use React Flow for flow graph visualization with Node, Edge, Controls, and Background components
Use the cn() utility function for combining Tailwind CSS classes in components
Use TypeScript interfaces for defining component props in React components
Files:
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/assistantNudgeBar/index.tsxsrc/frontend/src/components/common/assistant/index.tsx
src/frontend/src/**/*.{tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)
src/frontend/src/**/*.{tsx,jsx}: Implement dark mode support using the useDarkMode hook and dark store
Use Lucide React for icon components in the application
Files:
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/assistantNudgeBar/index.tsxsrc/frontend/src/components/common/assistant/index.tsx
src/backend/base/langflow/api/**/*.py
📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)
Backend API endpoints should be organized by version (v1/, v2/) under
src/backend/base/langflow/api/with specific modules for features (chat.py, flows.py, users.py, etc.)
Files:
src/backend/base/langflow/api/__init__.pysrc/backend/base/langflow/api/router.pysrc/backend/base/langflow/api/utils/mcp/agentic_mcp.py
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new components to the appropriate subdirectory under `src/backend/base/langflow/components/` (agents/, data/, embeddings/, input_output/, models/, processing/, prompts/, tools/, or vectorstores/)
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use `aiofiles` and `anyio.Path` for async file operations in tests; create temporary test files using `tmp_path` fixture and verify file existence and content
Applied to files:
src/backend/base/langflow/agentic/api/test.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test Langflow REST API endpoints using the `client` fixture with appropriate HTTP methods (GET, POST, etc.), headers (logged_in_headers), and payload validation
Applied to files:
src/backend/base/langflow/agentic/api/test.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Use predefined JSON flows and utility functions from `tests.unit.build_utils` (create_flow, build_flow, get_build_events, consume_and_assert_stream) for flow execution testing
Applied to files:
src/backend/base/langflow/agentic/api/test.py
📚 Learning: 2025-12-19T18:04:08.938Z
Learnt from: Jkavia
Repo: langflow-ai/langflow PR: 11111
File: src/backend/tests/unit/api/v2/test_workflow.py:10-11
Timestamp: 2025-12-19T18:04:08.938Z
Learning: In the langflow-ai/langflow project, pyproject.toml configures pytest-asyncio with `asyncio_mode = "auto"`, so pytest.mark.asyncio decorators are not needed on test classes or test methods. Async tests are automatically detected and run by pytest-asyncio's auto mode.
Applied to files:
src/backend/base/langflow/agentic/api/test.py
📚 Learning: 2025-11-24T19:47:28.997Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.997Z
Learning: Applies to src/backend/tests/**/*.py : Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration
Applied to files:
src/backend/base/langflow/agentic/api/test.py
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new components to the appropriate subdirectory under `src/backend/base/langflow/components/` (agents/, data/, embeddings/, input_output/, models/, processing/, prompts/, tools/, or vectorstores/)
Applied to files:
src/backend/base/langflow/agentic/api/test.pysrc/backend/base/langflow/agentic/flows/PromptGeneration.jsonsrc/backend/base/langflow/agentic/api/router.py
📚 Learning: 2025-11-24T19:46:57.920Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/icons.mdc:0-0
Timestamp: 2025-11-24T19:46:57.920Z
Learning: Applies to src/frontend/src/icons/*/index.tsx : Create an `index.tsx` for each icon that exports the icon using `forwardRef` and properly types it as `React.ForwardRefExoticComponent<React.PropsWithChildren<{}> & React.RefAttributes<SVGSVGElement>>`.
Applied to files:
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsx
📚 Learning: 2025-06-23T12:46:42.048Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 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/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/assistantNudgeBar/index.tsxsrc/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/components/**/*.{tsx,jsx} : Use React Flow for flow graph visualization with Node, Edge, Controls, and Background components
Applied to files:
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-06-16T11:14:04.200Z
Learnt from: dolfim-ibm
Repo: langflow-ai/langflow PR: 8394
File: src/frontend/src/icons/Docling/index.tsx:4-6
Timestamp: 2025-06-16T11:14:04.200Z
Learning: The Langflow codebase consistently uses `React.PropsWithChildren<{}>` as the prop type for all icon components using forwardRef, rather than `React.SVGProps<SVGSVGElement>`. This is an established pattern across hundreds of icon files in src/frontend/src/icons/.
Applied to files:
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-06-23T12:46:52.420Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/icons.mdc:0-0
Timestamp: 2025-06-23T12:46:52.420Z
Learning: Export custom icon components in React using React.forwardRef to ensure proper ref forwarding and compatibility with parent components.
Applied to files:
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsxsrc/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-11-24T19:46:09.104Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.104Z
Learning: Applies to src/backend/base/langflow/api/**/*.py : Backend API endpoints should be organized by version (v1/, v2/) under `src/backend/base/langflow/api/` with specific modules for features (chat.py, flows.py, users.py, etc.)
Applied to files:
src/backend/base/langflow/api/__init__.pysrc/backend/base/langflow/api/router.py
📚 Learning: 2025-06-23T12:46:42.048Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-06-23T12:46:42.048Z
Learning: React Flow should be used for flow graph visualization, with nodes and edges passed as props, and changes handled via onNodesChange and onEdgesChange callbacks.
Applied to files:
src/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/components/nodes/**/*.{tsx,jsx} : Memoize custom React Flow node components using memo() to prevent unnecessary re-renders
Applied to files:
src/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-06-23T12:46:42.048Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-06-23T12:46:42.048Z
Learning: Use Zustand for state management in React components within the frontend; stores should expose both state and setter functions, and be imported via hooks (e.g., useMyStore).
Applied to files:
src/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/**/*.{ts,tsx} : Use React 18 with TypeScript for frontend development
Applied to files:
src/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/**/*.{tsx,jsx} : Use Lucide React for icon components in the application
Applied to files:
src/frontend/src/components/common/assistant/index.tsx
📚 Learning: 2025-11-24T19:46:45.790Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/frontend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:45.790Z
Learning: Applies to src/frontend/src/**/*.{ts,tsx} : Use Zustand for state management
Applied to files:
src/frontend/src/components/common/assistant/index.tsx
🧬 Code graph analysis (7)
src/backend/base/langflow/agentic/api/test.py (3)
src/lfx/src/lfx/custom/custom_component/custom_component.py (1)
run_flow(536-552)src/backend/base/langflow/agentic/api/router.py (1)
main(143-164)src/backend/base/langflow/services/task/backends/anyio.py (1)
result(36-37)
src/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.ts (4)
src/frontend/src/types/api/index.ts (1)
useQueryFunctionType(266-277)src/frontend/src/controllers/API/services/request-processor.ts (1)
UseRequestProcessor(14-54)src/frontend/src/controllers/API/api.tsx (1)
api(377-377)src/frontend/src/controllers/API/helpers/constants.ts (1)
getURL(44-54)
src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsx (3)
src/frontend/src/hooks/use-add-component.ts (1)
useAddComponent(11-80)src/frontend/src/utils/reactflowUtils.ts (2)
scapedJSONStringfy(1140-1142)getHandleId(1217-1226)src/frontend/src/components/common/genericIconComponent/index.tsx (1)
ForwardedIconComponent(15-146)
src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx (4)
src/frontend/src/CustomNodes/hooks/use-handle-new-value.ts (1)
handleOnNewValueType(16-22)src/frontend/src/stores/foldersStore.tsx (1)
useFolderStore(4-29)src/frontend/src/controllers/API/queries/assistant/use-agentic-prompt.ts (1)
useAgenticPromptQuery(7-44)src/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.ts (1)
useGetNextSuggestedComponentQuery(7-63)
src/backend/base/langflow/agentic/api/router.py (2)
src/backend/base/langflow/services/variable/service.py (1)
DatabaseVariableService(24-321)src/backend/base/langflow/agentic/mcp/server.py (2)
get_flow_component_field_value(491-521)visualize_flow_graph(332-362)
src/backend/base/langflow/main.py (1)
src/lfx/src/lfx/services/interfaces.py (1)
settings(55-57)
src/frontend/src/components/common/assistant/index.tsx (1)
src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx (1)
AssistantNudges(22-193)
🔇 Additional comments (13)
src/lfx/src/lfx/services/settings/constants.py (2)
49-50: Consider using an empty string instead of "Empty Value" as the default.The literal string
"Empty Value"might cause confusion when checking if a variable is set. Downstream code would need to check for this specific string rather than using standard falsy checks. An empty string""is more idiomatic for representing unset values.Is
"Empty Value"intentional for display purposes, or would""be more appropriate for programmatic checks?
38-48: LGTM!The new agentic variable names are descriptive and align with the flow/component context functionality being introduced.
src/lfx/src/lfx/services/settings/base.py (1)
311-314: Breaking behavior change: agentic experience now enabled by default.Changing the default from
FalsetoTruemeans existing deployments will automatically start the agentic MCP server on upgrade. Verify that:
- Existing deployments won't experience unexpected resource usage or side effects
- Users who don't need agentic features can easily opt-out via
LANGFLOW_AGENTIC_EXPERIENCE=falsesrc/frontend/src/controllers/API/helpers/constants.ts (1)
38-38: LGTM!The new
AGENTIC_PROMPTendpoint key correctly references the agentic prompt API path.src/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.ts (1)
23-28: Verify streaming behavior withstream: truein a query context.The request sets
stream: truebut uses a standard query pattern that expects a complete response. If the endpoint returns a stream, this query won't handle it correctly. Confirm whether streaming is actually needed here, or ifstream: falseis more appropriate.src/backend/base/langflow/api/router.py (1)
64-68: Router configuration correctly implements conditional agentic router inclusion.The verification confirms that
router_v1is properly imported inmain.py(line 517) and conditionally includes theagentic_router(lines 519-522) whenagentic_experienceis enabled before being included in the main router (line 525). The architectural split of router definitions inrouter.pyand conditional assembly inmain.pyis correctly implemented and documented.src/backend/base/langflow/agentic/api/__init__.py (1)
1-3: LGTM!Clean re-export following the established pattern in the codebase for exposing package-level imports.
src/backend/base/langflow/main.py (1)
516-526: Conditional agentic router inclusion looks good.The runtime composition pattern correctly adds agentic endpoints only when enabled. However, note that
router_v1is a module-level object, so callingcreate_app()multiple times would repeatedly includeagentic_router. This is fine for typical single-app usage but could cause duplicate route registration in test scenarios that create multiple app instances.src/backend/base/langflow/api/__init__.py (1)
3-5: LGTM!Clean extension of the public API surface to expose
router_v1, enabling the modular router composition pattern used inmain.py.src/backend/base/langflow/agentic/flows/PromptGeneration.json (2)
1-10: Flow structure and metadata look reasonable.The flow graph structure with edges connecting ChatInput → Prompt Template → LanguageModel → ChatOutput, along with two TextInput nodes feeding into the Prompt Template, is well-organized. The flow description and endpoint naming are appropriate.
Also applies to: 1710-1718
1185-1315: No action needed. The model namesgpt-5.1,gpt-5,gpt-5-mini, andgpt-5-nanoare valid OpenAI reasoning models properly defined in the codebase with thereasoning=Trueflag. They are correctly configured in the flow and will not cause API failures.Likely an incorrect or invalid review comment.
src/backend/base/langflow/agentic/api/router.py (2)
43-43: Consider if logging user_id aligns with privacy requirements.Logging
user_idmay be acceptable for debugging, but depending on your privacy/compliance requirements (GDPR, etc.), user identifiers in logs might need to be reviewed.
17-24: Good use of FastAPI patterns and async handling.The router properly uses:
- Pydantic
BaseModelfor request validation- FastAPI dependency injection for user authentication and database session
async/awaitfor all async operations includingrun_flowandget_variableAlso applies to: 36-38, 98-100
| ) | ||
| global_vars["FIELD_VALUE"] = field_value.get("value", "") | ||
|
|
||
| logger.debug(f"GLOBAL VARIABLES: {global_vars}") |
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.
Critical: API key logged in debug output.
Logging global_vars at line 71 exposes the OPENAI_API_KEY in application logs, which is a security risk. Credentials should never be logged.
🔎 Proposed fix: Redact sensitive values before logging
- logger.debug(f"GLOBAL VARIABLES: {global_vars}")
+ # Log global vars without sensitive keys
+ safe_vars = {k: v if k != "OPENAI_API_KEY" else "[REDACTED]" for k, v in global_vars.items()}
+ logger.debug(f"GLOBAL VARIABLES: {safe_vars}")📝 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.
| logger.debug(f"GLOBAL VARIABLES: {global_vars}") | |
| # Log global vars without sensitive keys | |
| safe_vars = {k: v if k != "OPENAI_API_KEY" else "[REDACTED]" for k, v in global_vars.items()} | |
| logger.debug(f"GLOBAL VARIABLES: {safe_vars}") |
🤖 Prompt for AI Agents
In src/backend/base/langflow/agentic/api/router.py around line 71, the current
debug log prints the entire global_vars dict which can expose OPENAI_API_KEY;
instead sanitize the data before logging by cloning global_vars and replacing
any sensitive entries (e.g., keys matching /api(|_)?key|secret|token/i or
specifically OPENAI_API_KEY) with a placeholder like "[REDACTED]" and then log
the sanitized copy, or remove the log entirely if not necessary.
| # Path to the flow file | ||
| flow_path = Path(__file__).parent.parent / "flows" / f"{request.flow_id}.json" | ||
| if not flow_path.exists(): | ||
| raise HTTPException(status_code=404, detail=f"Flow {request.flow_id} not found") |
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.
Critical: Path traversal vulnerability in flow_id.
The request.flow_id is used directly in path construction without sanitization. An attacker could use values like ../../../sensitive_file to potentially access files outside the intended directory.
🔎 Proposed fix: Validate and sanitize flow_id
+import re
+
+def validate_flow_id(flow_id: str) -> str:
+ """Validate flow_id to prevent path traversal."""
+ # Only allow alphanumeric, hyphens, and underscores
+ if not re.match(r'^[a-zA-Z0-9_-]+$', flow_id):
+ raise HTTPException(status_code=400, detail="Invalid flow_id format")
+ return flow_id
+
@router.post("/next_component")
async def run_next_component_flow(request: FlowRequest, current_user: CurrentActiveUser, session: DbSession) -> dict:
"""Execute the next component flow with provided parameters."""
+ validated_flow_id = validate_flow_id(request.flow_id)
# ...
# Path to the flow file
- flow_path = Path(__file__).parent.parent / "flows" / f"{request.flow_id}.json"
+ flow_path = Path(__file__).parent.parent / "flows" / f"{validated_flow_id}.json"
+ # Ensure resolved path is within the flows directory
+ flows_dir = (Path(__file__).parent.parent / "flows").resolve()
+ if not flow_path.resolve().is_relative_to(flows_dir):
+ raise HTTPException(status_code=400, detail="Invalid flow path")Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/backend/base/langflow/agentic/api/router.py around lines 114 to 117,
request.flow_id is used directly to build a Path which allows path traversal;
validate and sanitize flow_id before using it: reject any flow_id containing
path separators or traversal components, enforce a strict regex (e.g. only
alphanumeric, hyphen, underscore), ensure the user does not supply an extension
(always append ".json" server-side), and after building the path use resolve()
and check that the resolved path is inside the intended flows directory (compare
with flows_dir.resolve()) — return HTTP 400 for invalid flow_id and 404 if the
file does not exist.
| openai_key = os.getenv("OPENAI_API_KEY") | ||
| print(f"OPENAI API KEY: {openai_key}") |
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.
Remove credential printing from test code.
Even in development/test code, printing the API key to stdout risks credential exposure in logs or terminal history.
🔎 Proposed fix
openai_key = os.getenv("OPENAI_API_KEY")
- print(f"OPENAI API KEY: {openai_key}")
+ print(f"OPENAI API KEY: {'[SET]' if openai_key else '[NOT SET]'}")📝 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.
| openai_key = os.getenv("OPENAI_API_KEY") | |
| print(f"OPENAI API KEY: {openai_key}") | |
| openai_key = os.getenv("OPENAI_API_KEY") | |
| print(f"OPENAI API KEY: {'[SET]' if openai_key else '[NOT SET]'}") |
🤖 Prompt for AI Agents
In src/backend/base/langflow/agentic/api/router.py around lines 148-149, the
code prints the OPENAI_API_KEY to stdout which risks credential exposure; remove
the print statement that outputs the key and, if you need to confirm presence,
replace it with a non-sensitive check (e.g., log that the key is present/absent
or raise a controlled error) without including the key value or any partial
secrets.
| if __name__ == "__main__": | ||
| # Path to LFX_TEST3.json | ||
| flow_path = Path(__file__).parent.parent / "flows" / "LFX_TEST3.json" |
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:
#!/bin/bash
# Check if the referenced flow file exists
fd -t f "LFX_TEST3.json" src/backend/base/langflow/agentic/flows/
# List available flow files
echo "=== Available flow files in agentic/flows: ==="
fd -t f ".json" src/backend/base/langflow/agentic/flows/
# Check if PromptGeneration.json exists anywhere
echo "=== Searching for PromptGeneration.json: ==="
fd -t f "PromptGeneration.json"
# Check the content of the test script
echo "=== Content of test.py: ==="
cat -n src/backend/base/langflow/agentic/api/test.pyRepository: langflow-ai/langflow
Length of output: 1304
Use an existing flow file and relocate this test to the standard test directory with proper test utilities.
The script references LFX_TEST3.json which does not exist. Available flows are PromptGeneration.json, SystemMessageGen.json, and TemplateAssistant.json. Additionally, this test is located in src/backend/base/langflow/agentic/api/ rather than src/backend/tests/. Per learnings, tests should use predefined utility functions from tests.unit.build_utils (such as create_flow, build_flow, get_build_events, consume_and_assert_stream) for flow execution testing.
🤖 Prompt for AI Agents
In src/backend/base/langflow/agentic/api/test.py around lines 6 to 8, the test
uses a nonexistent LFX_TEST3.json and is placed in the wrong directory; move
this test into src/backend/tests/ (e.g.,
src/backend/tests/agentic/test_agentic_api.py), replace the flow path with one
of the existing flows (PromptGeneration.json, SystemMessageGen.json, or
TemplateAssistant.json), remove the __main__ script style and convert to a
pytest test function, and use the shared utilities from tests.unit.build_utils
(import and call create_flow, build_flow, get_build_events and
consume_and_assert_stream) to create, build and assert the flow execution stream
accordingly, ensuring imports and relative paths match the new test location.
| global_variables={ | ||
| "FLOW_ID": "LFX_TEST3", | ||
| "OPENAI_API_KEY": "sk-proj-1234567890", | ||
| }, |
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.
Remove hardcoded API key and use environment variables.
Hardcoding API keys (even placeholder values) in source files is a security anti-pattern and can lead to accidental credential exposure. Use environment variables instead.
🔎 Proposed fix
+import os
+
async def main():
# Call run_flow with the flow path (minimal test, add parameters as needed)
result = await run_flow(
script_path=flow_path,
input_value=None, # or provide string if required
global_variables={
"FLOW_ID": "LFX_TEST3",
- "OPENAI_API_KEY": "sk-proj-1234567890",
+ "OPENAI_API_KEY": os.getenv("OPENAI_API_KEY", ""),
},
verbose=True,
check_variables=False,
)🤖 Prompt for AI Agents
In src/backend/base/langflow/agentic/api/test.py around lines 15 to 18, remove
the hardcoded "OPENAI_API_KEY" value and replace it with a call to read the key
from an environment variable (e.g., os.environ["OPENAI_API_KEY"] or os.getenv
with a sensible fallback/explicit test-time assertion); update the test setup to
inject or mock the environment variable instead of embedding credentials in
source, and ensure the code raises a clear error if the env var is missing so
tests fail fast.
| "code": { | ||
| "advanced": true, | ||
| "dynamic": true, | ||
| "fileTypes": [], | ||
| "file_path": "", | ||
| "info": "", | ||
| "list": false, | ||
| "load_from_db": false, | ||
| "multiline": true, | ||
| "name": "code", | ||
| "password": false, | ||
| "placeholder": "", | ||
| "required": true, | ||
| "show": true, | ||
| "title_case": false, | ||
| "type": "code", | ||
| "value": "from lfx.base.io.text import TextComponent\nfrom lfx.io import MultilineInput, Output\nfrom lfx.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get user text inputs.\"\n documentation: str = \"https://docs.langflow.org/text-input-and-output\"\n icon = \"type\"\n name = \"TextInput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Output Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n return Message(\n text=self.input_value,\n )\n" | ||
| }, |
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.
Import mismatch in embedded TextInput component code.
The embedded code imports MultilineInput but uses MessageTextInput in the inputs list (line 1537 embedded code). This would cause a NameError at runtime.
🔎 Proposed fix
Update the embedded code to import MessageTextInput:
-from lfx.io import MultilineInput, Output
+from lfx.io import MessageTextInput, OutputOr change the input to use MultilineInput instead of MessageTextInput.
📝 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.
| "code": { | |
| "advanced": true, | |
| "dynamic": true, | |
| "fileTypes": [], | |
| "file_path": "", | |
| "info": "", | |
| "list": false, | |
| "load_from_db": false, | |
| "multiline": true, | |
| "name": "code", | |
| "password": false, | |
| "placeholder": "", | |
| "required": true, | |
| "show": true, | |
| "title_case": false, | |
| "type": "code", | |
| "value": "from lfx.base.io.text import TextComponent\nfrom lfx.io import MultilineInput, Output\nfrom lfx.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get user text inputs.\"\n documentation: str = \"https://docs.langflow.org/text-input-and-output\"\n icon = \"type\"\n name = \"TextInput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Output Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n return Message(\n text=self.input_value,\n )\n" | |
| }, | |
| "code": { | |
| "advanced": true, | |
| "dynamic": true, | |
| "fileTypes": [], | |
| "file_path": "", | |
| "info": "", | |
| "list": false, | |
| "load_from_db": false, | |
| "multiline": true, | |
| "name": "code", | |
| "password": false, | |
| "placeholder": "", | |
| "required": true, | |
| "show": true, | |
| "title_case": false, | |
| "type": "code", | |
| "value": "from lfx.base.io.text import TextComponent\nfrom lfx.io import MessageTextInput, Output\nfrom lfx.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get user text inputs.\"\n documentation: str = \"https://docs.langflow.org/text-input-and-output\"\n icon = \"type\"\n name = \"TextInput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Output Text\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n return Message(\n text=self.input_value,\n )\n" | |
| }, |
🤖 Prompt for AI Agents
In src/backend/base/langflow/agentic/flows/PromptGeneration.json around lines
1521 to 1538, the embedded component code imports MultilineInput but the inputs
list uses MessageTextInput causing a NameError; fix it by either changing the
import to import MessageTextInput (preferred) or by changing the inputs entry to
use MultilineInput so the import and usage match, and ensure any corresponding
documentation or references are updated accordingly.
|
|
||
| interface AssistantNudgesProps { | ||
| type: "field" | "flow" | "project" | "header"; | ||
| setNudgesOpen; |
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.
🛠️ Refactor suggestion | 🟠 Major
Add TypeScript type for setNudgesOpen prop.
Per coding guidelines, TypeScript interfaces should fully type component props.
🔎 Proposed fix
interface AssistantNudgesProps {
type: "field" | "flow" | "project" | "header";
- setNudgesOpen;
+ setNudgesOpen: (open: boolean) => void;
handleOnNewValue: handleOnNewValueType;
}📝 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.
| setNudgesOpen; | |
| interface AssistantNudgesProps { | |
| type: "field" | "flow" | "project" | "header"; | |
| setNudgesOpen: (open: boolean) => void; | |
| handleOnNewValue: handleOnNewValueType; | |
| } |
🤖 Prompt for AI Agents
In src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx
around line 18, the prop declaration currently lists "setNudgesOpen" without a
TypeScript type; update the component's props interface to declare setNudgesOpen
with an appropriate type (e.g., React.Dispatch<React.SetStateAction<boolean>> if
it's the state setter from useState, or (open: boolean) => void if it's a
callback) and ensure React is imported for the type or use the global Function
type alias; then replace the untyped prop with the newly typed interface so the
component props are fully typed.
| useEffect(() => { | ||
| const result = async () => { | ||
| setNudgesLoading(true); | ||
| return await suggestedComponents(); | ||
| }; | ||
| result().then((nudges) => { | ||
| setComponentNudges( | ||
| JSON.parse(nudges.data.data.outputs[0].outputs[0].messages[0].message), | ||
| ); | ||
| setNudgesLoading(false); | ||
| }); | ||
| }, []); |
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.
Add error handling for the async data fetch.
The suggestedComponents() call can fail, and the deeply nested property access (nudges.data.data.outputs[0].outputs[0].messages[0].message) will throw if the response structure differs. Add try-catch and null checks.
🔎 Proposed fix
useEffect(() => {
- const result = async () => {
+ const fetchNudges = async () => {
setNudgesLoading(true);
- return await suggestedComponents();
+ try {
+ const result = await suggestedComponents();
+ const message = result?.data?.data?.outputs?.[0]?.outputs?.[0]?.messages?.[0]?.message;
+ if (message) {
+ setComponentNudges(JSON.parse(message));
+ }
+ } catch (error) {
+ console.error("Failed to fetch suggested components:", error);
+ } finally {
+ setNudgesLoading(false);
+ }
};
- result().then((nudges) => {
- setComponentNudges(
- JSON.parse(nudges.data.data.outputs[0].outputs[0].messages[0].message),
- );
- setNudgesLoading(false);
- });
+ fetchNudges();
}, []);📝 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.
| useEffect(() => { | |
| const result = async () => { | |
| setNudgesLoading(true); | |
| return await suggestedComponents(); | |
| }; | |
| result().then((nudges) => { | |
| setComponentNudges( | |
| JSON.parse(nudges.data.data.outputs[0].outputs[0].messages[0].message), | |
| ); | |
| setNudgesLoading(false); | |
| }); | |
| }, []); | |
| useEffect(() => { | |
| const fetchNudges = async () => { | |
| setNudgesLoading(true); | |
| try { | |
| const result = await suggestedComponents(); | |
| const message = result?.data?.data?.outputs?.[0]?.outputs?.[0]?.messages?.[0]?.message; | |
| if (message) { | |
| setComponentNudges(JSON.parse(message)); | |
| } | |
| } catch (error) { | |
| console.error("Failed to fetch suggested components:", error); | |
| } finally { | |
| setNudgesLoading(false); | |
| } | |
| }; | |
| fetchNudges(); | |
| }, []); |
| interface PillProps { | ||
| nudge; | ||
| setNudgesOpen; | ||
| } |
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.
🛠️ Refactor suggestion | 🟠 Major
Add TypeScript types for PillProps interface.
Per coding guidelines, TypeScript interfaces should be used for defining component props. The nudge and setNudgesOpen properties are untyped, which reduces type safety and IDE support.
🔎 Proposed fix
+interface NudgeTrigger {
+ componentId: string;
+}
+
+interface NudgeUI {
+ icon: string;
+}
+
+interface Nudge {
+ id: string;
+ type: "connect_component" | "route" | string;
+ trigger: NudgeTrigger;
+ ui: NudgeUI;
+ display_text: string;
+ description: string;
+}
+
interface PillProps {
- nudge;
- setNudgesOpen;
+ nudge: Nudge;
+ setNudgesOpen: (open: boolean) => void;
}📝 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.
| interface PillProps { | |
| nudge; | |
| setNudgesOpen; | |
| } | |
| interface NudgeTrigger { | |
| componentId: string; | |
| } | |
| interface NudgeUI { | |
| icon: string; | |
| } | |
| interface Nudge { | |
| id: string; | |
| type: "connect_component" | "route" | string; | |
| trigger: NudgeTrigger; | |
| ui: NudgeUI; | |
| display_text: string; | |
| description: string; | |
| } | |
| interface PillProps { | |
| nudge: Nudge; | |
| setNudgesOpen: (open: boolean) => void; | |
| } |
🤖 Prompt for AI Agents
In src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsx
around lines 11–14, the PillProps interface leaves nudge and setNudgesOpen
untyped; update it to use explicit TypeScript types (e.g. define or import a
Nudge type/interface representing the nudge object shape and use it for nudge,
and type setNudgesOpen as React.Dispatch<React.SetStateAction<boolean>> or
(open: boolean) => void), export or reuse existing types if available, and
update any component usage to match the new types.
| const nodes = useFlowStore.getState().nodes; | ||
| const sourceNode = nodes[nodes.length - 1]; | ||
| const sourceNodeId = sourceNode.id; | ||
| const sourceHandleObject = { | ||
| dataType: sourceNode.data.type, | ||
| id: sourceNode.id, | ||
| name: sourceNode.data.node.outputs[0].name, | ||
| output_types: sourceNode.data.node.outputs[0].types, | ||
| }; | ||
|
|
||
| const targetNode = nodes.find((n) => n.id === selectedCompData.id); | ||
| const targetField = | ||
| targetNode.data.node.template[selectedCompData?.fieldName]; |
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.
Add null checks to prevent runtime errors.
The code assumes the nodes array is non-empty, that the last node is the source, and that targetNode and targetField exist. These assumptions can cause runtime errors if the state is unexpected.
🔎 Proposed fix
const nodes = useFlowStore.getState().nodes;
+ if (nodes.length === 0) {
+ console.error("No nodes available");
+ return;
+ }
const sourceNode = nodes[nodes.length - 1];
+ if (!sourceNode?.data?.node?.outputs?.[0]) {
+ console.error("Source node output not found");
+ return;
+ }
const sourceNodeId = sourceNode.id;
const sourceHandleObject = {
dataType: sourceNode.data.type,
id: sourceNode.id,
name: sourceNode.data.node.outputs[0].name,
output_types: sourceNode.data.node.outputs[0].types,
};
const targetNode = nodes.find((n) => n.id === selectedCompData.id);
+ if (!targetNode) {
+ console.error("Target node not found");
+ return;
+ }
const targetField =
targetNode.data.node.template[selectedCompData?.fieldName];
+ if (!targetField) {
+ console.error("Target field not found");
+ return;
+ }📝 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.
| const nodes = useFlowStore.getState().nodes; | |
| const sourceNode = nodes[nodes.length - 1]; | |
| const sourceNodeId = sourceNode.id; | |
| const sourceHandleObject = { | |
| dataType: sourceNode.data.type, | |
| id: sourceNode.id, | |
| name: sourceNode.data.node.outputs[0].name, | |
| output_types: sourceNode.data.node.outputs[0].types, | |
| }; | |
| const targetNode = nodes.find((n) => n.id === selectedCompData.id); | |
| const targetField = | |
| targetNode.data.node.template[selectedCompData?.fieldName]; | |
| const nodes = useFlowStore.getState().nodes; | |
| if (nodes.length === 0) { | |
| console.error("No nodes available"); | |
| return; | |
| } | |
| const sourceNode = nodes[nodes.length - 1]; | |
| if (!sourceNode?.data?.node?.outputs?.[0]) { | |
| console.error("Source node output not found"); | |
| return; | |
| } | |
| const sourceNodeId = sourceNode.id; | |
| const sourceHandleObject = { | |
| dataType: sourceNode.data.type, | |
| id: sourceNode.id, | |
| name: sourceNode.data.node.outputs[0].name, | |
| output_types: sourceNode.data.node.outputs[0].types, | |
| }; | |
| const targetNode = nodes.find((n) => n.id === selectedCompData.id); | |
| if (!targetNode) { | |
| console.error("Target node not found"); | |
| return; | |
| } | |
| const targetField = | |
| targetNode.data.node.template[selectedCompData?.fieldName]; | |
| if (!targetField) { | |
| console.error("Target field not found"); | |
| return; | |
| } |
🤖 Prompt for AI Agents
In src/frontend/src/components common/assistant/assistantNudgeBar/pills.tsx
around lines 29 to 41, add defensive null/length checks before using
nodes[nodes.length - 1], accessing sourceNode.data/node outputs, and before
using targetNode and targetField: verify nodes is an array and non-empty, return
or bail early if not; verify sourceNode.data and sourceNode.data.node.outputs[0]
exist before reading name/types (or use optional chaining and sensible
defaults); find targetNode and if missing handle gracefully (early return) and
guard access to targetNode.data.node.template[selectedCompData?.fieldName] with
optional chaining and a fallback. Ensure any early exits do not break calling
code (e.g., return null/empty JSX or no-op).
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #11097 +/- ##
==========================================
- Coverage 33.25% 33.18% -0.08%
==========================================
Files 1394 1398 +4
Lines 66015 66156 +141
Branches 9771 9792 +21
==========================================
- Hits 21955 21953 -2
- Misses 42934 43076 +142
- Partials 1126 1127 +1
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
This pull request introduces a new Agentic API to the backend and improves the management and initialization of agentic variables. It also enables the agentic experience by default and adds supporting constants and test scripts. The most important changes are grouped below.
Agentic API Integration:
/promptand/next_component, which execute flows using user-specific variables and OpenAI credentials (src/backend/base/langflow/agentic/api/router.py).__init__.pyfor easier imports (src/backend/base/langflow/agentic/api/__init__.py)./v2prefix (src/backend/base/langflow/api/router.py). [1] [2]Agentic Variable Management:
CREDENTIAL_TYPE(src/backend/base/langflow/api/utils/mcp/agentic_mcp.py).DEFAULT_AGENTIC_VARIABLE_VALUE) to the settings constants (src/lfx/src/lfx/services/settings/constants.py).Configuration and Defaults:
src/lfx/src/lfx/services/settings/base.py).Testing and Utilities:
src/backend/base/langflow/agentic/api/test.py).Dependency and Import Cleanups:
pydanticand related dependencies for clarity and correctness in several files (src/lfx/src/lfx/custom/custom_component/custom_component.py,src/lfx/src/lfx/services/settings/base.py). [1] [2] [3] [4]These changes collectively add agentic capabilities to the API, streamline agentic variable handling, and ensure the agentic server is enabled by default.
Summary by CodeRabbit
Release Notes
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.