Skip to content

Conversation

@edwinjosechittilappilly
Copy link
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly commented Dec 18, 2025

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:

  • Added a new FastAPI router for agentic endpoints, including /prompt and /next_component, which execute flows using user-specific variables and OpenAI credentials (src/backend/base/langflow/agentic/api/router.py).
  • Exposed the agentic API router in the package’s __init__.py for easier imports (src/backend/base/langflow/agentic/api/__init__.py).
  • Registered the agentic router with the main API router, making agentic endpoints available under the /v2 prefix (src/backend/base/langflow/api/router.py). [1] [2]

Agentic Variable Management:

  • Refactored agentic variable initialization to dynamically use a list of variable names and a default value from new constants, and changed their type to CREDENTIAL_TYPE (src/backend/base/langflow/api/utils/mcp/agentic_mcp.py).
  • Added new agentic variable names and a default value constant (DEFAULT_AGENTIC_VARIABLE_VALUE) to the settings constants (src/lfx/src/lfx/services/settings/constants.py).

Configuration and Defaults:

  • Enabled the agentic experience by default in the settings, ensuring the agentic MCP server starts automatically (src/lfx/src/lfx/services/settings/base.py).

Testing and Utilities:

  • Added a standalone test script to run a flow using the new agentic API logic for development and debugging (src/backend/base/langflow/agentic/api/test.py).

Dependency and Import Cleanups:

  • Adjusted imports for pydantic and 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

    • Introduced Assistant Nudges feature enabling users to generate optimized prompts and discover recommended components via an interactive popover interface
    • Agentic assistant capabilities now enabled by default
  • Chores

    • Updated default configuration for agentic experience settings

✏️ Tip: You can customize this high-level summary in your review settings.

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.
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.
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 18, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 18, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 18, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 18, 2025
add nudge code and use new prompt endpoint
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 23, 2025
@Adam-Aghili Adam-Aghili marked this pull request as ready for review December 23, 2025 17:38
@Adam-Aghili Adam-Aghili added the lgtm This PR has been approved by a maintainer label Dec 23, 2025
@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 23, 2025
Copilot AI review requested due to automatic review settings December 23, 2025 17:42
Copy link
Contributor

Copilot AI left a 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.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 23, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 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_variables creates only 3 hardcoded variables (FLOW_ID, COMPONENT_ID, FIELD_NAME) using GENERIC_TYPE, while initialize_agentic_user_variables (lines 321-338) creates all 9 variables from AGENTIC_VARIABLES using CREDENTIAL_TYPE.

This inconsistency could lead to:

  1. Different variable sets depending on initialization path
  2. Different variable types for the same logical variables

Consider aligning both functions to use the same variable set from AGENTIC_VARIABLES and 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 any types. 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: Missing await on async logger calls.

Lines 325 and 330 call logger.adebug(...) without await, while other logger calls in this file correctly use await 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 useEffect for 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-point should be cursor-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 a key prop to the mapped Pill components.

React requires a unique key prop when rendering lists to optimize reconciliation. Using nudge.id if 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: nudegsLoading should be nudgesLoading.

🔎 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 the type prop instead of hardcoding "field".

The AssistantNudges component receives type="field" hardcoded, but AssistantButton receives type as 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 unique data-testid values 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 e

Also applies to: 132-134

src/backend/base/langflow/agentic/api/router.py-162-164 (1)

162-164: HTTPException is inappropriate in standalone script context.

HTTPException is 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 missing flow_description and tags fields.

The return dictionary now includes flow_description (line 85) and tags (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 than Object for params.

While changing from any to Object is an improvement, Object is still a weak type in TypeScript. Consider using Record<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 1000000000000 is unnecessarily extreme and can cause stacking context issues. Use a reasonable value like 1000 or 9999 that 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: popoverRef is unused since the click-outside handler is commented out.

The popoverRef is 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 session parameter lacks a type annotation. Adding AsyncSession improves 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_flow function 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

📥 Commits

Reviewing files that changed from the base of the PR and between 2d02456 and 275bdc5.

📒 Files selected for processing (19)
  • src/backend/base/langflow/agentic/api/__init__.py
  • src/backend/base/langflow/agentic/api/router.py
  • src/backend/base/langflow/agentic/api/test.py
  • src/backend/base/langflow/agentic/flows/PromptGeneration.json
  • src/backend/base/langflow/agentic/utils/flow_graph.py
  • src/backend/base/langflow/api/__init__.py
  • src/backend/base/langflow/api/router.py
  • src/backend/base/langflow/api/utils/mcp/agentic_mcp.py
  • src/backend/base/langflow/main.py
  • src/frontend/src/components/common/assistant/assistantButton.css
  • src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx
  • src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsx
  • src/frontend/src/components/common/assistant/index.tsx
  • src/frontend/src/controllers/API/helpers/constants.ts
  • src/frontend/src/controllers/API/queries/assistant/use-agentic-prompt.ts
  • src/frontend/src/controllers/API/queries/assistant/use-suggest-next-component.ts
  • src/lfx/src/lfx/_assets/component_index.json
  • src/lfx/src/lfx/services/settings/base.py
  • src/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 with await for async operations in component execution methods
Use asyncio.create_task() for background tasks and implement proper cleanup with try/except for asyncio.CancelledError
Use queue.put_nowait() for non-blocking queue operations and asyncio.wait_for() with timeouts for controlled get operations

Files:

  • src/backend/base/langflow/agentic/api/test.py
  • src/backend/base/langflow/agentic/api/__init__.py
  • src/backend/base/langflow/agentic/utils/flow_graph.py
  • src/backend/base/langflow/api/__init__.py
  • src/backend/base/langflow/agentic/api/router.py
  • src/backend/base/langflow/main.py
  • src/backend/base/langflow/api/router.py
  • src/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.ts
  • src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsx
  • src/frontend/src/controllers/API/queries/assistant/use-agentic-prompt.ts
  • src/frontend/src/controllers/API/helpers/constants.ts
  • src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx
  • src/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.css
  • src/frontend/src/components/common/assistant/assistantNudgeBar/pills.tsx
  • src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx
  • src/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.tsx
  • src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx
  • src/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.tsx
  • src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx
  • src/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__.py
  • src/backend/base/langflow/api/router.py
  • src/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.py
  • src/backend/base/langflow/agentic/flows/PromptGeneration.json
  • src/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.tsx
  • src/frontend/src/components/common/assistant/assistantNudgeBar/index.tsx
  • 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/**/*.{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.tsx
  • src/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.tsx
  • src/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.tsx
  • src/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__.py
  • src/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 False to True means existing deployments will automatically start the agentic MCP server on upgrade. Verify that:

  1. Existing deployments won't experience unexpected resource usage or side effects
  2. Users who don't need agentic features can easily opt-out via LANGFLOW_AGENTIC_EXPERIENCE=false
src/frontend/src/controllers/API/helpers/constants.ts (1)

38-38: LGTM!

The new AGENTIC_PROMPT endpoint 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 with stream: true in a query context.

The request sets stream: true but 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 if stream: false is 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_v1 is properly imported in main.py (line 517) and conditionally includes the agentic_router (lines 519-522) when agentic_experience is enabled before being included in the main router (line 525). The architectural split of router definitions in router.py and conditional assembly in main.py is 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_v1 is a module-level object, so calling create_app() multiple times would repeatedly include agentic_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 in main.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 names gpt-5.1, gpt-5, gpt-5-mini, and gpt-5-nano are valid OpenAI reasoning models properly defined in the codebase with the reasoning=True flag. 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_id may 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 BaseModel for request validation
  • FastAPI dependency injection for user authentication and database session
  • async/await for all async operations including run_flow and get_variable

Also applies to: 36-38, 98-100

)
global_vars["FIELD_VALUE"] = field_value.get("value", "")

logger.debug(f"GLOBAL VARIABLES: {global_vars}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

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.

Suggested change
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.

Comment on lines +114 to +117
# 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")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

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.

Comment on lines +148 to +149
openai_key = os.getenv("OPENAI_API_KEY")
print(f"OPENAI API KEY: {openai_key}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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.

Comment on lines +6 to +8
if __name__ == "__main__":
# Path to LFX_TEST3.json
flow_path = Path(__file__).parent.parent / "flows" / "LFX_TEST3.json"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 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.py

Repository: 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.

Comment on lines +15 to +18
global_variables={
"FLOW_ID": "LFX_TEST3",
"OPENAI_API_KEY": "sk-proj-1234567890",
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Comment on lines +1521 to +1538
"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"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

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, Output

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

Suggested change
"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;
Copy link
Contributor

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.

Suggested change
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.

Comment on lines +78 to +89
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);
});
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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();
}, []);

Comment on lines +11 to +14
interface PillProps {
nudge;
setNudgesOpen;
}
Copy link
Contributor

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.

Suggested change
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.

Comment on lines +29 to +41
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];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

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.

Suggested change
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).

@github-actions
Copy link
Contributor

github-actions bot commented Dec 23, 2025

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 17%
16.58% (4707/28383) 9.96% (2177/21851) 10.91% (679/6219)

Unit Test Results

Tests Skipped Failures Errors Time
1830 0 💤 0 ❌ 0 🔥 25.098s ⏱️

@codecov
Copy link

codecov bot commented Dec 23, 2025

Codecov Report

❌ Patch coverage is 1.31579% with 150 lines in your changes missing coverage. Please review.
✅ Project coverage is 33.18%. Comparing base (5211855) to head (36ea228).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...nents/common/assistant/assistantNudgeBar/index.tsx 0.00% 78 Missing ⚠️
...nents/common/assistant/assistantNudgeBar/pills.tsx 0.00% 35 Missing ⚠️
...PI/queries/assistant/use-suggest-next-component.ts 0.00% 15 Missing ⚠️
...ollers/API/queries/assistant/use-agentic-prompt.ts 0.00% 13 Missing ⚠️
...frontend/src/components/common/assistant/index.tsx 0.00% 8 Missing ⚠️
.../frontend/src/controllers/API/helpers/constants.ts 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            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     
Flag Coverage Δ
frontend 15.29% <0.00%> (-0.09%) ⬇️
lfx 39.54% <100.00%> (-0.01%) ⬇️

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

Files with missing lines Coverage Δ
.../backend/base/langflow/agentic/utils/flow_graph.py 18.86% <ø> (ø)
src/backend/base/langflow/api/router.py 100.00% <ø> (ø)
src/backend/base/langflow/main.py 66.02% <ø> (ø)
src/lfx/src/lfx/services/settings/base.py 71.02% <100.00%> (ø)
src/lfx/src/lfx/services/settings/constants.py 100.00% <100.00%> (ø)
.../frontend/src/controllers/API/helpers/constants.ts 60.00% <0.00%> (ø)
...frontend/src/components/common/assistant/index.tsx 0.00% <0.00%> (ø)
...ollers/API/queries/assistant/use-agentic-prompt.ts 0.00% <0.00%> (ø)
...PI/queries/assistant/use-suggest-next-component.ts 0.00% <0.00%> (ø)
...nents/common/assistant/assistantNudgeBar/pills.tsx 0.00% <0.00%> (ø)
... and 1 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot added enhancement New feature or request and removed enhancement New feature or request labels Dec 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants