Skip to content

feat: add composio components#9560

Merged
edwinjosechittilappilly merged 3 commits into
langflow-ai:mainfrom
ComposioHQ:feat/composio-v3-2-newcomponent-v1-addcompPr
Sep 16, 2025
Merged

feat: add composio components#9560
edwinjosechittilappilly merged 3 commits into
langflow-ai:mainfrom
ComposioHQ:feat/composio-v3-2-newcomponent-v1-addcompPr

Conversation

@Uday-sidagana
Copy link
Copy Markdown
Contributor

@Uday-sidagana Uday-sidagana commented Aug 26, 2025

Added new components: Airtable, Asana, Attio, Calendly, Contentful, Discord, Figma, Google Docs, Google Sheets, Klaviyo, Miro, Notion, OneDrive,Wrike

frontend: /src/frontend/src/icons and /src/frontend/src/icons/lazyIconImports.ts & /src/frontend/src/icons and /src/frontend/src/icons

backend: /src/backend/base/langflow/components/composio

Summary by CodeRabbit

  • New Features

    • Added Composio integrations for Airtable, Asana, Attio, Calendly, Contentful, Discord, Figma, Google Docs/Sheets, Klaviyo, Miro, Notion, OneDrive, and Wrike.
    • Components and icons now support on-demand loading for faster initial load.
  • UI

    • Introduced new SVG icons for all added services (with ref forwarding), improving visual consistency across the app.
    • Expanded lazy icon loading to include the new service icons.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Aug 26, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Expands Composio backend with new API component classes and updates init to expose and lazy-load them. Adds corresponding frontend SVG icons and forwardRef wrappers, and extends the lazy icon import map to include the new icons.

Changes

Cohort / File(s) Summary
Composio package surface
src/backend/base/langflow/components/composio/__init__.py
Extends TYPE_CHECKING imports, public __all__, and _dynamic_imports to include new Composio API components; enables lazy attribute-based imports.
New Composio API components
.../composio/airtable_composio.py, .../asana_composio.py, .../attio_composio.py, .../calendly_composio.py, .../contentful_composio.py, .../discord_composio.py, .../figma_composio.py, .../googledocs_composio.py, .../googlesheets_composio.py, .../klaviyo_composio.py, .../miro_composio.py, .../notion_composio.py, .../onedrive_composio.py, .../wrike_composio.py
Adds 14 subclasses of ComposioBaseComponent with metadata (display_name, icon, documentation, app_name) and stub set_default_tools(self) methods.
Frontend SVG icon components
src/frontend/src/icons/*/*.jsx for: airtable, asana, attio, calendly, contentful, discord, figma, googledocs, klaviyo, miro, one_drive, wrike
Introduces presentational SVG React components (default export Icon) for each new app icon.
Frontend icon forwardRef wrappers
src/frontend/src/icons/*/index.tsx for: airtable, asana, attio, calendly, contentful, discord, figma, googledocs, klaviyo, miro, one_drive, wrike
Adds named exports wrapping SVG components with forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>, passing through props and refs.
Lazy icon loader mapping
src/frontend/src/icons/lazyIconImports.ts
Adds lazy-load entries for the new icons (Airtable, Asana, Attio, Calendly, Contentful, Discord, Figma, Googledocs, Googlesheets, Klaviyo, Miro, One_Drive, Wrike); removes a duplicate/old Googlesheets entry at bottom.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Import Consumer
  participant ComposioPkg as composio.__init__
  participant Module as Specific Component Module

  Dev->>ComposioPkg: Access attribute (e.g., ComposioNotionAPIComponent)
  Note over ComposioPkg: __getattr__ consults _dynamic_imports
  ComposioPkg->>Module: Lazy import target module (e.g., notion_composio)
  Module-->>ComposioPkg: Return class symbol
  ComposioPkg-->>Dev: Provide requested component class
Loading
sequenceDiagram
  autonumber
  actor UI as UI Component
  participant LazyMap as lazyIconImports.ts
  participant IconMod as "@/icons/.../index"

  UI->>LazyMap: Request icon by key (e.g., "Figma")
  LazyMap->>IconMod: dynamic import()
  IconMod-->>LazyMap: { default: FigmaIcon }
  LazyMap-->>UI: Resolved component
  UI->>UI: Render <FigmaIcon .../>
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested labels

enhancement, size:XXL, lgtm

Suggested reviewers

  • edwinjosechittilappilly
  • lucaseduoli
  • Cristhianzl
  • ogabrielluiz
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Aug 26, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 22

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/components/composio/__init__.py (1)

1-116: Add missing Composio component icons to the frontend mapping

All backend Composio components declare an icon = "…” value, but your frontend’s lazyIconImports.ts only defines a handful of keys (e.g. Miro). The vast majority of backend icons aren’t mapped, so their icons won’t render in the UI. You need to update src/frontend/src/icons/lazyIconImports.ts to include entries for:

  • Airtable
  • Asana
  • Attio
  • Calendly
  • Composio
  • Contentful
  • Discord
  • Dropbox
  • Figma
  • Github
  • Google
  • GoogleTasks
  • Googlecalendar
  • Googledocs
  • Googlemeet
  • Googlesheets
  • Klaviyo
  • Linear
  • Notion
  • One_Drive
  • Outlook
  • Reddit
  • Slack
  • Supabase
  • Todoist
  • Wrike
  • Youtube

(Action items)

  • In src/frontend/src/icons/lazyIconImports.ts, add mapping lines for each of the above keys, matching the backend icon names exactly.
  • Verify you import the correct SVG/module for each service.
  • After updating, run:
    • Backend: make format_backend && make lint
    • Frontend: make format_frontend && make lint

This will ensure parity between backend components and their corresponding frontend icons, preventing missing‐icon gaps in the UI.

🧹 Nitpick comments (38)
src/frontend/src/icons/contentful/contentful.jsx (2)

12-35: React SVG attribute casing: prefer camelCase to avoid lint noise.

We commonly camelCase SVG attributes to keep ESLint/TSX happy. Hyphenated attributes like stroke-width should be strokeWidth. Functionally equivalent, but quieter for tooling.

-      stroke-width="0.25"
+      strokeWidth="0.25"
@@
-      stroke-width="0.25"
+      strokeWidth="0.25"
@@
-      stroke-width="0.25"
+      strokeWidth="0.25"
@@
-      stroke-width="0.25"
+      strokeWidth="0.25"
@@
-      stroke-width="0.25"
+      strokeWidth="0.25"

2-11: Optional: ensure unique/uniform ids and accessibility.

The hardcoded id="Contentful--Streamline-Svg-Logos" is globally scoped; consider prefixing with "lf-" to avoid collisions when multiple icons render on a page. Also consider adding role="img" and aria-hidden for decorative usage.

src/frontend/src/icons/one_drive/one_drive.jsx (2)

16-17: CamelCase SVG stop-color for cleaner JSX.

Update stop-color to stopColor to align with our JSX conventions and avoid lint warnings. No behavioral change.

-      <stop offset="0" stop-color="#0571bf" />
-      <stop offset="1" stop-color="#0268ba" />
+      <stop offset="0" stopColor="#0571bf" />
+      <stop offset="1" stopColor="#0268ba" />
@@
-      <stop offset="0" stop-color="#1684da" />
-      <stop offset="1" stop-color="#107cd4" />
+      <stop offset="0" stopColor="#1684da" />
+      <stop offset="1" stopColor="#107cd4" />
@@
-      <stop offset="0" stop-color="#138cdd" />
-      <stop offset="1" stop-color="#0c7dd4" />
+      <stop offset="0" stopColor="#138cdd" />
+      <stop offset="1" stopColor="#0c7dd4" />
@@
-      <stop offset="0" stop-color="#27a7ea" />
-      <stop offset="1" stop-color="#1c94e3" />
+      <stop offset="0" stopColor="#27a7ea" />
+      <stop offset="1" stopColor="#1c94e3" />

Also applies to: 31-32, 46-47, 61-62


8-21: Optional: avoid special characters in gradient IDs.

The "~" character is valid but makes CSS targeting/automation awkward. Consider simplifying ids to ascii alphanumerics.

src/frontend/src/icons/airtable/airtable.jsx (1)

1-37: Optional: expose accessibility semantics when decorative.

If this logo is purely decorative, consider aria-hidden="true" to keep it out of the accessibility tree. If meaningful, add role="img" and an aria-label.

src/frontend/src/icons/miro/miro.jsx (2)

11-28: CamelCase SVG attributes to satisfy React/ESLint.

Change stop-color, stroke-miterlimit, stroke-width, fill-rule/clip-rule to their camelCase forms. You already adjusted two above; update the remaining occurrences.

-      <stop offset="0" stop-color="#000000" fill="#000000" />
-      <stop offset="1" stop-color="#000000" fill="#000000" />
+      <stop offset="0" stopColor="#000000" fill="#000000" />
+      <stop offset="1" stopColor="#000000" fill="#000000" />
@@
-      stroke-miterlimit="10"
-      stroke-width="2"
+      strokeMiterlimit="10"
+      strokeWidth="2"

42-47: Attribute casing continued for inner glyph.

fill-rule/clip-rule on the inner path should be fillRule/clipRule.

-      fill-rule="evenodd"
+      fillRule="evenodd"
@@
-      clip-rule="evenodd"
+      clipRule="evenodd"
src/backend/base/langflow/components/composio/airtable_composio.py (1)

10-11: Clarify intentional fallback or set explicit defaults in set_default_tools.

Right now the method is a no-op (docstring only). That’s fine if you want the base class to fall back to the first N tools (default_tools_limit=5). If that’s intentional, add a brief note; otherwise, populate self._default_tools with explicit action keys.

Apply this diff to document the fallback and leave a TODO for explicit defaults:

-    def set_default_tools(self):
-        """Set the default tools for Airtable component."""
+    def set_default_tools(self):
+        """Set the default tools for Airtable component.
+        If left empty, enabled_tools will fall back to the first `default_tools_limit` actions.
+        """
+        # TODO: Populate with Airtable action keys when the preferred default set is decided.
+        # Example: self._default_tools = {"create_record", "update_record", "search_records"}
+        return None
src/backend/base/langflow/components/composio/googledocs_composio.py (2)

6-6: Icon casing likely needs alignment with frontend mapping.

The icon is set to "Googledocs". Frontend keys are typically TitleCase with internal capitals (e.g., "GoogleDocs"). Please verify the exact key in lazyIconImports.ts and align. If the frontend uses "GoogleDocs", apply the diff below; otherwise, consider renaming the frontend key to match the backend string.

-    icon = "Googledocs"
+    icon = "GoogleDocs"

To confirm and prevent regressions, run the icon mapping check script I posted on the Airtable comment.


10-11: Set defaults or document fallback behavior.

Same as other components: either populate self._default_tools or explicitly document that you’re relying on the base class fallback to the first N actions.

-    def set_default_tools(self):
-        """Set the default tools for Google Docs component."""
+    def set_default_tools(self):
+        """Set the default tools for Google Docs component.
+        Intentionally empty: fallback to first `default_tools_limit` actions.
+        """
+        return None
src/backend/base/langflow/components/composio/attio_composio.py (1)

10-11: Document fallback or set explicit defaults.

Same recommendation: add a brief note or set self._default_tools when you have the preferred defaults.

-    def set_default_tools(self):
-        """Set the default tools for Attio component."""
+    def set_default_tools(self):
+        """Set the default tools for Attio component. Currently relies on fallback to first N actions."""
+        return None
src/backend/base/langflow/components/composio/figma_composio.py (1)

10-11: Explicitly acknowledge fallback or choose defaults.

Same guidance as the others—either populate self._default_tools with a curated subset or document that you’re using the base fallback to the first N actions.

-    def set_default_tools(self):
-        """Set the default tools for Figma component."""
+    def set_default_tools(self):
+        """Set the default tools for Figma component. Intentionally left empty to use fallback."""
+        return None
src/backend/base/langflow/components/composio/contentful_composio.py (1)

10-11: Document fallback or set defaults.

Add a brief note or populate self._default_tools.

-    def set_default_tools(self):
-        """Set the default tools for Contentful component."""
+    def set_default_tools(self):
+        """Set the default tools for Contentful component. Using fallback to first N actions for now."""
+        return None
src/backend/base/langflow/components/composio/wrike_composio.py (1)

10-11: Consider implementing default tool selection or add explicit TODO.

set_default_tools is a no-op. If Wrike needs a subset of Composio tools by default, override here; otherwise add a brief comment noting intentional no-op to satisfy linters and future readers.

-    def set_default_tools(self):
-        """Set the default tools for Wrike component."""
+    def set_default_tools(self):
+        """Set the default tools for Wrike component.
+        Intentionally left blank if using Composio defaults."""
+        # TODO: populate if Wrike requires curated defaults
+        return
src/backend/base/langflow/components/composio/miro_composio.py (1)

10-11: Optional: make the no-op explicit or wire curated defaults.

Same note as Wrike: either document the intentional no-op or implement default tool selection.

-    def set_default_tools(self):
-        """Set the default tools for Miro component."""
+    def set_default_tools(self):
+        """Set the default tools for Miro component.
+        Intentionally left blank if using Composio defaults."""
+        return
src/frontend/src/icons/klaviyo/klaviyo.jsx (1)

1-6: Optional: prefer currentColor to inherit text color.

If brand colors aren’t required, using fill="currentColor" lets theme/styles control the color without explicit isDark logic.

-    <path
-      d="M100,100H0V0h100L78.8,50L100,100z"
-      fill={isDark ? "#ffffff" : "#000000"}
-    />
+    <path d="M100,100H0V0h100L78.8,50L100,100z" fill="currentColor" />
src/frontend/src/icons/airtable/index.tsx (1)

1-9: Add a displayName for better DevTools and lazy-load debugging.

Small quality-of-life improvement; no runtime impact.

Apply this diff:

 export const AirtableIcon = forwardRef<
   SVGSVGElement,
   React.PropsWithChildren<{}>
 >((props, ref) => {
   return <AirtableIconSVG ref={ref} {...props} />;
 });
+
+// Helps with debugging component names in React DevTools and lazy imports
+AirtableIcon.displayName = "AirtableIcon";
src/frontend/src/icons/asana/index.tsx (2)

1-8: Consider adding displayName for consistency with other wrappers.

Apply this diff:

 export const AsanaIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
   (props, ref) => {
     return <AsanaIconSVG ref={ref} {...props} />;
   },
 );
+
+AsanaIcon.displayName = "AsanaIcon";

1-8: Optional: strengthen typing to include isDark and standard SVG props.

If you plan to pass isDark directly from TSX call sites, consider typing it. I’m aware the repo commonly uses PropsWithChildren<{}>; treat this as optional alignment for future robustness.

Apply this diff if you choose to tighten types:

-import React, { forwardRef } from "react";
+import React, { forwardRef } from "react";
 
-export const AsanaIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
+type IconProps = React.SVGProps<SVGSVGElement> & { isDark?: boolean };
+export const AsanaIcon = forwardRef<SVGSVGElement, IconProps>(
   (props, ref) => {
     return <AsanaIconSVG ref={ref} {...props} />;
   },
 );
src/frontend/src/icons/klaviyo/index.tsx (1)

1-9: Add displayName for debug friendliness.

Apply this diff:

 export const KlaviyoIcon = forwardRef<
   SVGSVGElement,
   React.PropsWithChildren<{}>
 >((props, ref) => {
   return <KlaviyoIconSVG ref={ref} {...props} />;
 });
+
+KlaviyoIcon.displayName = "KlaviyoIcon";
src/frontend/src/icons/miro/index.tsx (1)

1-8: Add displayName for consistency with other icons.

Apply this diff:

 export const MiroIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
   (props, ref) => {
     return <MiroIconSVG ref={ref} {...props} />;
   },
 );
+
+MiroIcon.displayName = "MiroIcon";
src/frontend/src/icons/googledocs/index.tsx (2)

4-9: Potential casing mismatch: “Googledocs” vs “GoogleDocs”. Please verify end-to-end naming.

Frontend mapping keys and backend icon strings are case-sensitive per repo convention. Many Langflow icons use PascalCase without collapsing brand camel-case (e.g., GoogleDocs). If the backend uses icon="GoogleDocs" but the frontend key/export is “Googledocs”, the icon won’t load.

If you confirm the backend and lazyIconImports use “GoogleDocs”, consider this rename for consistency:

-import React, { forwardRef } from "react";
-import GoogledocsIconSVG from "./googledocs";
+import React, { forwardRef } from "react";
+import GoogleDocsIconSVG from "./googledocs";
 
-export const GoogledocsIcon = forwardRef<
+export const GoogleDocsIcon = forwardRef<
   SVGSVGElement,
   React.PropsWithChildren<{}>
 >((props, ref) => {
-  return <GoogledocsIconSVG ref={ref} {...props} />;
+  return <GoogleDocsIconSVG ref={ref} {...props} />;
 });
+
+GoogleDocsIcon.displayName = "GoogleDocsIcon";

Follow-ups if you adopt the rename:

  • Update src/frontend/src/icons/lazyIconImports.ts to map "GoogleDocs" -> { default: mod.GoogleDocsIcon }
  • Ensure all backend components use icon="GoogleDocs"
  • Adjust any story/tests/usages referring to GoogledocsIcon

1-9: Add displayName (even if you keep the current name).

Helps debugging either way.

Apply this diff if you keep current casing:

 export const GoogledocsIcon = forwardRef<
   SVGSVGElement,
   React.PropsWithChildren<{}>
 >((props, ref) => {
   return <GoogledocsIconSVG ref={ref} {...props} />;
 });
+
+GoogledocsIcon.displayName = "GoogledocsIcon";
src/frontend/src/icons/figma/figma.jsx (1)

1-27: Optional: migrate brand-icon .jsx to .tsx later.

Not required for this PR, but moving to .tsx will let you type the isDark prop and catch ref issues at compile time.

src/frontend/src/icons/wrike/wrike.jsx (1)

1-24: Optional: consider .tsx for icons going forward.

TypeScript would let you define IconProps = React.ComponentPropsWithoutRef<"svg"> & { isDark?: boolean } for stronger typing.

src/frontend/src/icons/attio/index.tsx (1)

1-2: Nit: tree-shakeable import optional.

You can import only forwardRef from react if desired, but current import is fine and consistent elsewhere.

src/frontend/src/icons/calendly/index.tsx (1)

1-9: Add a displayName for better DevTools/debuggability.

Helps React DevTools show a readable component name when lazy-loaded.

 import React, { forwardRef } from "react";
 import CalendlyIconSVG from "./calendly";

 export const CalendlyIcon = forwardRef<
   SVGSVGElement,
   React.PropsWithChildren<{}>
 >((props, ref) => {
   return <CalendlyIconSVG ref={ref} {...props} />;
 });
+
+CalendlyIcon.displayName = "CalendlyIcon";
src/backend/base/langflow/components/composio/klaviyo_composio.py (1)

10-11: Consider defining a minimal set_default_tools to improve initial UX.

Without defaults, enabled_tools will fall back to the first N actions which may feel arbitrary. If you have high-signal Klaviyo actions, set them here via a small curated set.

Example pattern (adjust tags to real action keys):

 def set_default_tools(self):
-    """Set the default tools for Klaviyo component."""
+    """Set the default tools for Klaviyo component."""
+    # e.g., choose the top few frequently-used actions
+    self._default_tools = {
+        # "create_campaign",
+        # "create_list",
+        # "add_profile_to_list",
+    }
src/backend/base/langflow/components/composio/calendly_composio.py (1)

10-11: Optionally seed default tools for Calendly.

Setting a few curated defaults helps the agent avoid low-signal actions on first use.

 def set_default_tools(self):
-    """Set the default tools for Calendly component."""
+    """Set the default tools for Calendly component."""
+    self._default_tools = {
+        # e.g.: "list_event_types", "list_scheduled_events", "create_invitee"
+    }
src/backend/base/langflow/components/composio/googlesheets_composio.py (1)

10-11: Optionally predefine default tools for Sheets.

Curating a few actions improves OOB experience.

 def set_default_tools(self):
-    """Set the default tools for Google Sheets component."""
+    """Set the default tools for Google Sheets component."""
+    self._default_tools = {
+        # e.g.: "create_spreadsheet", "append_values", "get_values"
+    }
src/backend/base/langflow/components/composio/asana_composio.py (1)

10-11: Optional: seed default tools for Asana.

Helps prevent surfacing low-value actions first.

 def set_default_tools(self):
-    """Set the default tools for Asana component."""
+    """Set the default tools for Asana component."""
+    self._default_tools = {
+        # e.g.: "create_task", "list_projects", "add_comment_to_task"
+    }
src/backend/base/langflow/components/composio/discord_composio.py (1)

10-11: Optionally set curated default tools to improve UX

Leaving set_default_tools empty falls back to the first N actions. If you already know the most useful Discord actions, consider populating self._default_tools to bias the default tools list.

I can open a follow-up PR to set sensible defaults once the available action slugs are confirmed.

src/backend/base/langflow/components/composio/notion_composio.py (1)

10-11: Consider defining default tools

As with other components, populating self._default_tools with commonly used Notion actions can make the component more helpful out-of-the-box.

src/backend/base/langflow/components/composio/onedrive_composio.py (1)

10-11: Optional: predefine _default_tools

If there are a couple of high-value OneDrive actions (e.g., list files, upload file), consider setting them as _default_tools.

src/frontend/src/icons/lazyIconImports.ts (1)

22-56: Keep new mappings alphabetized to reduce churn and ease discovery

The newly added keys are correct, but they break the otherwise mostly alphabetical organization of this object. Sorting these entries alphabetically (by key) reduces merge conflicts and makes future maintenance easier.

Apply this minimal reordering within the current block:

-  Googledocs: () =>
-    import("@/icons/googledocs").then((mod) => ({
-      default: mod.GoogledocsIcon,
-    })),
-  Googlesheets: () =>
-    import("@/icons/googlesheets").then((mod) => ({
-      default: mod.GooglesheetsIcon,
-    })),
-  Klaviyo: () =>
-    import("@/icons/klaviyo").then((mod) => ({ default: mod.KlaviyoIcon })),
-  One_Drive: () =>
-    import("@/icons/one_drive").then((mod) => ({ default: mod.One_DriveIcon })),
-  Wrike: () =>
-    import("@/icons/wrike").then((mod) => ({ default: mod.WrikeIcon })),
-  Miro: () => import("@/icons/miro").then((mod) => ({ default: mod.MiroIcon })),
-  Figma: () =>
-    import("@/icons/figma").then((mod) => ({ default: mod.FigmaIcon })),
-  Discord: () =>
-    import("@/icons/discord").then((mod) => ({
-      default: mod.DiscordIcon,
-    })),
-  Contentful: () =>
-    import("@/icons/contentful").then((mod) => ({
-      default: mod.ContentfulIcon,
-    })),
-  Calendly: () =>
-    import("@/icons/calendly").then((mod) => ({
-      default: mod.CalendlyIcon,
-    })),
-  Attio: () =>
-    import("@/icons/attio").then((mod) => ({ default: mod.AttioIcon })),
-  Asana: () =>
-    import("@/icons/asana").then((mod) => ({ default: mod.AsanaIcon })),
-  Airtable: () =>
-    import("@/icons/airtable").then((mod) => ({ default: mod.AirtableIcon })),
+  Airtable: () =>
+    import("@/icons/airtable").then((mod) => ({ default: mod.AirtableIcon })),
+  Asana: () =>
+    import("@/icons/asana").then((mod) => ({ default: mod.AsanaIcon })),
+  Attio: () =>
+    import("@/icons/attio").then((mod) => ({ default: mod.AttioIcon })),
+  Calendly: () =>
+    import("@/icons/calendly").then((mod) => ({
+      default: mod.CalendlyIcon,
+    })),
+  Contentful: () =>
+    import("@/icons/contentful").then((mod) => ({
+      default: mod.ContentfulIcon,
+    })),
+  Discord: () =>
+    import("@/icons/discord").then((mod) => ({
+      default: mod.DiscordIcon,
+    })),
+  Figma: () =>
+    import("@/icons/figma").then((mod) => ({ default: mod.FigmaIcon })),
+  Googledocs: () =>
+    import("@/icons/googledocs").then((mod) => ({
+      default: mod.GoogledocsIcon,
+    })),
+  Googlesheets: () =>
+    import("@/icons/googlesheets").then((mod) => ({
+      default: mod.GooglesheetsIcon,
+    })),
+  Klaviyo: () =>
+    import("@/icons/klaviyo").then((mod) => ({ default: mod.KlaviyoIcon })),
+  Miro: () => import("@/icons/miro").then((mod) => ({ default: mod.MiroIcon })),
+  One_Drive: () =>
+    import("@/icons/one_drive").then((mod) => ({ default: mod.One_DriveIcon })),
+  Wrike: () =>
+    import("@/icons/wrike").then((mod) => ({ default: mod.WrikeIcon })),
src/backend/base/langflow/components/composio/__init__.py (3)

7-35: Sort TYPE_CHECKING imports alphabetically for consistency

The newly added imports are correct but not strictly alphabetical. Sorting helps future diffs and quick scanning.

Apply this reordering within the TYPE_CHECKING block:

 if TYPE_CHECKING:
-    from .airtable_composio import ComposioAirtableAPIComponent
-    from .asana_composio import ComposioAsanaAPIComponent
-    from .attio_composio import ComposioAttioAPIComponent
-    from .calendly_composio import ComposioCalendlyAPIComponent
     from .composio_api import ComposioAPIComponent
-    from .contentful_composio import ComposioContentfulAPIComponent
-    from .discord_composio import ComposioDiscordAPIComponent
-    from .figma_composio import ComposioFigmaAPIComponent
+    from .airtable_composio import ComposioAirtableAPIComponent
+    from .asana_composio import ComposioAsanaAPIComponent
+    from .attio_composio import ComposioAttioAPIComponent
+    from .calendly_composio import ComposioCalendlyAPIComponent
+    from .contentful_composio import ComposioContentfulAPIComponent
+    from .discord_composio import ComposioDiscordAPIComponent
+    from .figma_composio import ComposioFigmaAPIComponent
     from .github_composio import ComposioGitHubAPIComponent
     from .gmail_composio import ComposioGmailAPIComponent
     from .googlecalendar_composio import ComposioGoogleCalendarAPIComponent
-    from .googledocs_composio import ComposioGoogleDocsAPIComponent
     from .googlemeet_composio import ComposioGooglemeetAPIComponent
-    from .googlesheets_composio import ComposioGoogleSheetsAPIComponent
+    from .googledocs_composio import ComposioGoogleDocsAPIComponent
+    from .googlesheets_composio import ComposioGoogleSheetsAPIComponent
     from .googletasks_composio import ComposioGoogleTasksAPIComponent
-    from .klaviyo_composio import ComposioKlaviyoAPIComponent
     from .linear_composio import ComposioLinearAPIComponent
-    from .miro_composio import ComposioMiroAPIComponent
-    from .notion_composio import ComposioNotionAPIComponent
-    from .onedrive_composio import ComposioOneDriveAPIComponent
+    from .klaviyo_composio import ComposioKlaviyoAPIComponent
+    from .miro_composio import ComposioMiroAPIComponent
+    from .notion_composio import ComposioNotionAPIComponent
+    from .onedrive_composio import ComposioOneDriveAPIComponent
     from .outlook_composio import ComposioOutlookAPIComponent
     from .reddit_composio import ComposioRedditAPIComponent
     from .slack_composio import ComposioSlackAPIComponent
     from .slackbot_composio import ComposioSlackbotAPIComponent
     from .supabase_composio import ComposioSupabaseAPIComponent
     from .todoist_composio import ComposioTodoistAPIComponent
-    from .wrike_composio import ComposioWrikeAPIComponent
     from .youtube_composio import ComposioYoutubeAPIComponent
+    from .wrike_composio import ComposioWrikeAPIComponent

52-66: Sort the new dynamic import mappings alphabetically by class name

No functional issue, but keeping this dict sorted makes it easier to spot missing/duplicate entries.

Apply this reordering for the newly added keys:

     "ComposioYoutubeAPIComponent": "youtube_composio",
-    "ComposioGoogleDocsAPIComponent": "googledocs_composio",
-    "ComposioGoogleSheetsAPIComponent": "googlesheets_composio",
-    "ComposioKlaviyoAPIComponent": "klaviyo_composio",
-    "ComposioNotionAPIComponent": "notion_composio",
-    "ComposioOneDriveAPIComponent": "onedrive_composio",
-    "ComposioAirtableAPIComponent": "airtable_composio",
-    "ComposioAsanaAPIComponent": "asana_composio",
-    "ComposioAttioAPIComponent": "attio_composio",
-    "ComposioCalendlyAPIComponent": "calendly_composio",
-    "ComposioContentfulAPIComponent": "contentful_composio",
-    "ComposioDiscordAPIComponent": "discord_composio",
-    "ComposioFigmaAPIComponent": "figma_composio",
-    "ComposioMiroAPIComponent": "miro_composio",
-    "ComposioWrikeAPIComponent": "wrike_composio",
+    "ComposioAirtableAPIComponent": "airtable_composio",
+    "ComposioAsanaAPIComponent": "asana_composio",
+    "ComposioAttioAPIComponent": "attio_composio",
+    "ComposioCalendlyAPIComponent": "calendly_composio",
+    "ComposioContentfulAPIComponent": "contentful_composio",
+    "ComposioDiscordAPIComponent": "discord_composio",
+    "ComposioFigmaAPIComponent": "figma_composio",
+    "ComposioGoogleDocsAPIComponent": "googledocs_composio",
+    "ComposioGoogleSheetsAPIComponent": "googlesheets_composio",
+    "ComposioKlaviyoAPIComponent": "klaviyo_composio",
+    "ComposioMiroAPIComponent": "miro_composio",
+    "ComposioNotionAPIComponent": "notion_composio",
+    "ComposioOneDriveAPIComponent": "onedrive_composio",
+    "ComposioWrikeAPIComponent": "wrike_composio",

68-97: Alphabetize all for stable diffs and discoverability

Alphabetizing __all__ reduces merge conflicts and makes it easier to ensure parity with _dynamic_imports.

 __all__ = [
-    "ComposioAPIComponent",
-    "ComposioAirtableAPIComponent",
-    "ComposioAsanaAPIComponent",
-    "ComposioAttioAPIComponent",
-    "ComposioCalendlyAPIComponent",
-    "ComposioContentfulAPIComponent",
-    "ComposioDiscordAPIComponent",
-    "ComposioFigmaAPIComponent",
-    "ComposioGitHubAPIComponent",
-    "ComposioGmailAPIComponent",
-    "ComposioGoogleCalendarAPIComponent",
-    "ComposioGoogleDocsAPIComponent",
-    "ComposioGoogleSheetsAPIComponent",
-    "ComposioGoogleTasksAPIComponent",
-    "ComposioGooglemeetAPIComponent",
-    "ComposioKlaviyoAPIComponent",
-    "ComposioLinearAPIComponent",
-    "ComposioMiroAPIComponent",
-    "ComposioNotionAPIComponent",
-    "ComposioOneDriveAPIComponent",
-    "ComposioOutlookAPIComponent",
-    "ComposioRedditAPIComponent",
-    "ComposioSlackAPIComponent",
-    "ComposioSlackbotAPIComponent",
-    "ComposioSupabaseAPIComponent",
-    "ComposioTodoistAPIComponent",
-    "ComposioWrikeAPIComponent",
-    "ComposioYoutubeAPIComponent",
+    "ComposioAPIComponent",
+    "ComposioAirtableAPIComponent",
+    "ComposioAsanaAPIComponent",
+    "ComposioAttioAPIComponent",
+    "ComposioCalendlyAPIComponent",
+    "ComposioContentfulAPIComponent",
+    "ComposioDiscordAPIComponent",
+    "ComposioFigmaAPIComponent",
+    "ComposioGitHubAPIComponent",
+    "ComposioGmailAPIComponent",
+    "ComposioGoogleCalendarAPIComponent",
+    "ComposioGoogleDocsAPIComponent",
+    "ComposioGoogleSheetsAPIComponent",
+    "ComposioGoogleTasksAPIComponent",
+    "ComposioGooglemeetAPIComponent",
+    "ComposioKlaviyoAPIComponent",
+    "ComposioLinearAPIComponent",
+    "ComposioMiroAPIComponent",
+    "ComposioNotionAPIComponent",
+    "ComposioOneDriveAPIComponent",
+    "ComposioOutlookAPIComponent",
+    "ComposioRedditAPIComponent",
+    "ComposioSlackAPIComponent",
+    "ComposioSlackbotAPIComponent",
+    "ComposioSupabaseAPIComponent",
+    "ComposioTodoistAPIComponent",
+    "ComposioWrikeAPIComponent",
+    "ComposioYoutubeAPIComponent",
 ]

Comment on lines +5 to +8
display_name: str = "Asana"
icon = "Asana"
documentation: str = "https://docs.composio.dev"
app_name = "asana"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify exports and dynamic import registration.

Ensure init.py exports ComposioAsanaAPIComponent, includes it in all, and adds a _dynamic_imports entry mapping "asana" -> "asana_composio".


🏁 Script executed:

#!/bin/bash
set -euo pipefail
INIT=src/backend/base/langflow/components/composio/__init__.py

rg -nP '\bComposioAsanaAPIComponent\b' "$INIT" || echo "ERROR: Missing class export in $INIT"
rg -nP "__all__\\s*=\\s*\\[[\\s\\S]*\\bComposioAsanaAPIComponent\\b" "$INIT" || echo "ERROR: Missing __all__ entry"
rg -nP "_dynamic_imports\\s*=\\s*\\{[\\s\\S]*['\"]asana['\"]\\s*:\\s*['\"][^'\"]*asana_composio['\"]" "$INIT" || echo "ERROR: Missing dynamic import mapping for 'asana' in $INIT"

Length of output: 924


Add missing exports and dynamic import mapping for Asana component

The Asana component class is imported, but it isn't exported in __all__ nor registered under "asana" in the dynamic imports table. Without these entries, the component won’t be discoverable via the public API or dynamic loader.

Please update src/backend/base/langflow/components/composio/__init__.py:

  • In the __all__ list, include "ComposioAsanaAPIComponent".
  • In the _dynamic_imports dict, add the key "asana" mapping to "asana_composio".

For example:

 __all__ = [
     # existing exports...
-    # missing ComposioAsanaAPIComponent
+    "ComposioAsanaAPIComponent",
 ]

 _dynamic_imports = {
     # existing mappings...
-    # missing Asana mapping
+    "asana": "asana_composio",
 }
📝 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
display_name: str = "Asana"
icon = "Asana"
documentation: str = "https://docs.composio.dev"
app_name = "asana"
++ b/src/backend/base/langflow/components/composio/__init__.py
@@
__all__ = [
# existing exports...
"ComposioAsanaAPIComponent",
]
_dynamic_imports = {
# existing mappings...
"asana": "asana_composio",
}
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/composio/__init__.py around the
top-level exports and dynamic-import mapping (update lines near the existing
__all__ and _dynamic_imports definitions), add "ComposioAsanaAPIComponent" to
the __all__ list and add a mapping "asana": "asana_composio" to the
_dynamic_imports dict so the Asana component is exported from the package and
discoverable by the dynamic loader; ensure string names match the class/file
names exactly and preserve existing ordering/formatting.

display_name: str = "Google Docs"
icon = "Googledocs"
documentation: str = "https://docs.composio.dev"
app_name = "googledocs"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

❓ Verification inconclusive

Confirm Composio app_name slug.

Please verify that "googledocs" matches Composio’s app slug; a mismatch here will result in no tools being discovered for this component at runtime.


🌐 Web query:

What is the correct Composio app slug for Google Docs (the string used to fetch actions/tools)?

Error during web search


Composio app_name slug mismatch

The Composio toolkit slug for Google Docs is defined as GOOGLEDOCS (uppercase) in the official registry; using "googledocs" (all lowercase) here will prevent this component’s tools from being discovered at runtime (docs.composio.dev, v3.docs.composio.dev).

• File: src/backend/base/langflow/components/composio/googledocs_composio.py, line 8
• Suggested change:

-    app_name = "googledocs"
+    app_name = "GOOGLEDOCS"
📝 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
app_name = "googledocs"
app_name = "GOOGLEDOCS"
🤖 Prompt for AI Agents
In src/backend/base/langflow/components/composio/googledocs_composio.py around
line 8, the Composio toolkit slug is set to "googledocs" but the official
registry expects "GOOGLEDOCS"; change the app_name value to "GOOGLEDOCS"
(uppercase) so the component's tools are discovered at runtime, and verify any
imports/tests or references use the updated slug for consistency.

Comment on lines +4 to +11
class ComposioGoogleSheetsAPIComponent(ComposioBaseComponent):
display_name: str = "Google Sheets"
icon = "Googlesheets"
documentation: str = "https://docs.composio.dev"
app_name = "googlesheets"

def set_default_tools(self):
"""Set the default tools for Google Sheets component."""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Potential case mismatch risk for icon "Googlesheets".

Double-check that the frontend lazy icon mapping uses the exact key "Googlesheets" (not "GoogleSheets"). Case mismatch will break icon rendering.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Search for Googlesheets vs GoogleSheets in lazy icon mapping:"
rg -nP '["'\''`](Googlesheets|GoogleSheets)["'\''`]\s*:' src/frontend/src/icons/lazyIconImports.ts || \
  echo "NOTE: No mapping found for either variant—ensure one is added."

echo "Verify a Google Sheets icon exists under icons/:"
fd -a -HI 'googlesheets|GoogleSheets' src/frontend/src/icons

Length of output: 758


Add lazy icon mapping for “Googlesheets” in lazyIconImports.ts

The frontend currently has the assets under src/frontend/src/icons/googlesheets/, but there is no corresponding entry in the lazy‐load mapping. Without this, the backend’s icon = "Googlesheets" will not resolve and the icon won’t render.

• File to update:
src/frontend/src/icons/lazyIconImports.ts

• Add an entry whose key exactly matches the backend string ("Googlesheets"), for example:

 export const lazyIconsMapping: Record<string, () => Promise<{ default: React.FC<SVGProps<SVGSVGElement>> }>> = {
   // … existing mappings
+  Googlesheets: () => import('./googlesheets/googlesheets'),
 };

This must match the backend icon attribute string exactly (case‐sensitive) to ensure the Google Sheets icon loads correctly.

📝 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
class ComposioGoogleSheetsAPIComponent(ComposioBaseComponent):
display_name: str = "Google Sheets"
icon = "Googlesheets"
documentation: str = "https://docs.composio.dev"
app_name = "googlesheets"
def set_default_tools(self):
"""Set the default tools for Google Sheets component."""
export const lazyIconsMapping: Record<string, () => Promise<{ default: React.FC<SVGProps<SVGSVGElement>> }>> = {
//existing mappings
Googlesheets: () => import('./googlesheets/googlesheets'),
};
🤖 Prompt for AI Agents
In src/frontend/src/icons/lazyIconImports.ts (add near other icon mappings),
there is no lazy-load mapping for the backend icon string "Googlesheets", so the
frontend cannot resolve the Google Sheets asset; add a new mapping with the key
exactly "Googlesheets" (case-sensitive) that returns a dynamic import of the
icon module under src/frontend/src/icons/googlesheets (matching the exported
component name), following the same pattern used by the other entries in this
file so the icon is lazy-loaded and resolves correctly.

Comment on lines +1 to +8
const Icon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="24px"
height="24px"
baseProfile="basic"
>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Forward props and add isDark hook-in.

This icon doesn’t spread props and lacks the isDark hook. Align with the rest for theme support and consumer overrides.

-const Icon = (props) => (
+const Icon = ({ isDark = false, ...props }) => (
   <svg
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 100 100"
     width="24px"
     height="24px"
     baseProfile="basic"
-  >
+    {...props}
+  >
📝 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 Icon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="24px"
height="24px"
baseProfile="basic"
>
const Icon = ({ isDark = false, ...props }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="24px"
height="24px"
baseProfile="basic"
{...props}
>
🤖 Prompt for AI Agents
In src/frontend/src/icons/airtable/airtable.jsx around lines 1-8, the SVG
component neither forwards incoming props nor integrates the app's isDark hook;
update the component to import and call the isDark hook, compute any
theme-dependent attributes (e.g. fill/stroke or className) using the hook, and
spread the incoming props onto the <svg> element so consumers can override
width/height/className/aria attributes; ensure existing static attributes remain
but allow props to override them, and keep accessibility attributes
(role/aria-hidden) consistent with project conventions.

Comment on lines +1 to +9
import React, { forwardRef } from "react";
import AirtableIconSVG from "./airtable";

export const AirtableIcon = forwardRef<
SVGSVGElement,
React.PropsWithChildren<{}>
>((props, ref) => {
return <AirtableIconSVG ref={ref} {...props} />;
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify icon mapping and backend icon string alignment (case-sensitive).

Ensure:

  • lazyIconImports.ts has key "Airtable" pointing to this module and re-exporting AirtableIcon
  • Backend Composio component sets icon="Airtable"

Run this repo-local check to confirm mappings for all new icons added in this PR and that SVGs reference isDark.


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python << 'PY'
import re, os, glob

icons = ["Airtable","Asana","Klaviyo","Miro","GoogleDocs"]

# Parse lazy icon mapping keys
mapping_path = "src/frontend/src/icons/lazyIconImports.ts"
keys = set()
if os.path.exists(mapping_path):
    txt = open(mapping_path, "r", encoding="utf-8").read()
    for m in re.finditer(r'["\']([A-Za-z0-9]+)["\']\s*:', txt):
        keys.add(m.group(1))

missing_map = [k for k in icons if k not in keys]

# Parse exported icon component names
exports = {}
for name in icons:
    dir_ = name.lower()
    idx = f"src/frontend/src/icons/{dir_}/index.tsx"
    comp = None
    if os.path.exists(idx):
        t = open(idx,"r",encoding="utf-8").read()
        m = re.search(r'export\s+const\s+(\w+)\s*=\s*forwardRef', t)
        if m: comp = m.group(1)
    exports[name] = comp

# Collect backend icon strings
backend = set()
for p in glob.glob("src/backend/**/components/**/**/*.py", recursive=True):
    try:
        t = open(p,"r",encoding="utf-8").read()
    except Exception:
        continue
    for m in re.finditer(r'\bicon\s*=\s*["\']([A-Za-z0-9]+)["\']', t):
        backend.add(m.group(1))

missing_backend = [k for k in icons if k not in backend]

# Check isDark usage in SVG JSX files
needs_isDark = []
for name in icons:
    dir_ = name.lower()
    used = False
    for j in glob.glob(f"src/frontend/src/icons/{dir_}/*.jsx"):
        try:
            if "isDark" in open(j,"r",encoding="utf-8").read():
                used = True
                break
        except Exception:
            pass
    if not used:
        needs_isDark.append(name)

print("lazyIconImports.ts keys (subset):", sorted(keys))
print("Missing mapping keys:", missing_map)
print("Exports (index.tsx):", exports)
print("Backend icon strings (subset):", sorted(list(backend))[:80])
print("Missing backend icon strings:", missing_backend)
print("SVGs not referencing isDark (verify styles/impl):", needs_isDark)
PY

Length of output: 1446


Add missing icon mappings, backend string, and isDark support

The repository currently lacks the necessary lazy‐load mappings and isDark prop usage for the new icons, and the backend is not setting the GoogleDocs icon string. Please address the following:

  • In src/frontend/src/icons/lazyIconImports.ts
    • Add entries for "Airtable", "Asana", "Klaviyo", "Miro", and "GoogleDocs" keyed exactly (case-sensitive) to import their respective modules (e.g.

    "Airtable": () => import("./airtable").then(m => m.AirtableIcon),
    // …and so on for Asana, Klaviyo, Miro, GoogleDocs

    )

  • In the backend Composio component definitions
    • Verify that each integration component sets icon="Airtable", icon="Asana", icon="Klaviyo", icon="Miro", and add icon="GoogleDocs" for the Google Docs connector (currently missing) missing_backend

  • In each SVG source under src/frontend/src/icons/{airtable, asana, klaviyo, miro, googledocs}/
    • Ensure the SVG implementation honors the isDark prop to switch colors/themes appropriately (currently none reference isDark) needs_isDark

🤖 Prompt for AI Agents
In src/frontend/src/icons/airtable/index.tsx lines 1-9 and related modules, add
missing lazy-load mappings, backend icon string, and isDark support: update
src/frontend/src/icons/lazyIconImports.ts to include exact case-sensitive keys
"Airtable", "Asana", "Klaviyo", "Miro", and "GoogleDocs" mapping to dynamic
imports that return the corresponding *Icon export (e.g. () =>
import("./airtable").then(m => m.AirtableIcon)); update the backend Composio
component definitions to set icon="Airtable"/"Asana"/"Klaviyo"/"Miro" where
appropriate and add icon="GoogleDocs" to the Google Docs connector; and modify
each SVG component under
src/frontend/src/icons/{airtable,asana,klaviyo,miro,googledocs}/ to accept an
isDark prop and use it to switch colors/theme (apply conditional fill/stroke or
className based on isDark) so the icons render correctly in dark mode.

Comment on lines +1 to +10
const Icon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 64 64"
width="24px"
height="24px"
fill-rule="evenodd"
clip-rule="evenodd"
baseProfile="basic"
>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Forward props and add isDark hook-in on the SVG.

Mirror the convention across icons for theme and sizing flexibility.

-const Icon = (props) => (
+const Icon = ({ isDark = false, ...props }) => (
   <svg
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 64 64"
     width="24px"
     height="24px"
-    fill-rule="evenodd"
-    clip-rule="evenodd"
+    {...props}
+    fillRule="evenodd"
+    clipRule="evenodd"
     baseProfile="basic"
   >

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +1 to +9
import React, { forwardRef } from "react";
import One_DriveIconSVG from "./one_drive";

export const One_DriveIcon = forwardRef<
SVGSVGElement,
React.PropsWithChildren<{}>
>((props, ref) => {
return <One_DriveIconSVG ref={ref} {...props} />;
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify naming consistency: OneDrive vs one_drive vs One_Drive.

Directory/component names here use underscores (one_drive, One_DriveIcon). Please ensure:

  • lazyIconImports.ts maps the exact backend icon string (likely "OneDrive") to "@/icons/one_drive".
  • No duplicate "OneDrive" icon directory already exists (capitalized variant).

Run this to confirm there’s a single OneDrive icon family and that lazy mapping aligns with backend icon strings:


🏁 Script executed:

#!/bin/bash
# Find potential duplicates for OneDrive icon directories/files
fd -H -t d -E node_modules -E dist -E build -E .git -g 'src/frontend/src/icons/*' | rg -nP '/(OneDrive|one_drive)\b'

# Show wrappers to confirm exported symbol names
rg -nP --type=ts -C2 'export\s+const\s+(OneDriveIcon|One_DriveIcon)\b' src/frontend/src/icons

# Check lazy icon mapping keys and targets
rg -nP -C2 '"OneDrive"|One_Drive|one_drive' src/frontend/src/icons/lazyIconImports.ts

# Check backend composio components' `icon` attribute for OneDrive key
rg -nP -C2 'icon\s*=\s*["\']OneDrive["\']' src/backend/base/langflow/components/composio

Length of output: 1427


🏁 Script executed:

#!/bin/bash
# Search for OneDrive usage in backend component definitions
rg -n 'OneDrive' -n src/backend/base/langflow/components/composio

Length of output: 767


🏁 Script executed:

#!/bin/bash
echo "=== lazyIconImports.ts ==="
sed -n '1,200p' src/frontend/src/icons/lazyIconImports.ts || echo "File not found"
echo
echo "=== Icon directories under src/frontend/src/icons ==="
fd -H -t d -E node_modules -E dist -E build -E .git -g src/frontend/src/icons/* | sed 's|src/frontend/src/icons/||' | sort

Length of output: 13475


Inconsistent OneDrive icon naming & duplicate directories detected

The codebase currently contains two separate icon folders and a mismatched mapping entry:

  • Icons directories:
    • src/frontend/src/icons/one_drive (exports One_DriveIcon)
    • src/frontend/src/icons/OneDrive (exports OneDriveIcon)
  • lazyIconsMapping.ts uses the key One_Drive@/icons/one_drive, but the backend component’s display name is "OneDrive", and there is no "OneDrive" key in the mapping.

To resolve:

• Consolidate into a single directory named OneDrive (to match the backend string exactly) and remove one_drive.
• Update src/frontend/src/icons/lazyIconImports.ts, replacing:

-  One_Drive: () =>
-    import("@/icons/one_drive").then((mod) => ({ default: mod.One_DriveIcon })),
+  OneDrive: () =>
+    import("@/icons/OneDrive").then((mod) => ({ default: mod.OneDriveIcon })),

• In src/frontend/src/icons/OneDrive/index.tsx, ensure the component is exported as:

export const OneDriveIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
  (props, ref) => <SvgOneDrive ref={ref} {...props} />
);

This will align the frontend mapping key with the backend’s display_name: "OneDrive" and eliminate the duplicate one_drive folder.

🤖 Prompt for AI Agents
In src/frontend/src/icons/one_drive/index.tsx lines 1-9: the project has
duplicate icon folders and mismatched naming between frontend mapping and
backend display_name; consolidate the icon into a single directory named
OneDrive, remove the one_drive folder, update
src/frontend/src/icons/OneDrive/index.tsx to export the component as
OneDriveIcon using forwardRef<SVGSVGElement, React.PropsWithChildren<{}>> and
render the SVG (SvgOneDrive) with ref and props, and finally update
src/frontend/src/icons/lazyIconImports.ts to replace the mapping key/path from
"@/icons/one_drive" to "@/icons/OneDrive" so the frontend mapping matches the
backend display_name "OneDrive".

Comment on lines +1 to +7
const Icon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48"
width="24px"
height="24px"
>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Forward props and add isDark hook-in for theme compatibility.

Same as other icons: destructure isDark and spread props onto the to allow sizing/styling overrides.

-const Icon = (props) => (
+const Icon = ({ isDark = false, ...props }) => (
   <svg
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 48 48"
     width="24px"
     height="24px"
-  >
+    {...props}
+  >
📝 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 Icon = (props) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48"
width="24px"
height="24px"
>
const Icon = ({ isDark = false, ...props }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 48 48"
width="24px"
height="24px"
{...props}
>
🤖 Prompt for AI Agents
In src/frontend/src/icons/one_drive/one_drive.jsx around lines 1-7, the Icon
component currently ignores passed props and theme state; update the component
signature to accept and destructure isDark from props (e.g. ({ isDark, ...props
})) and, if isDark is undefined, call the project's theme hook to derive it (use
the same useIsDark hook used by other icons), then spread the remaining props
onto the <svg> element so consumers can override width/height/className/styles;
keep existing default width/height only as fallbacks when not provided via
props.

Comment on lines +4 to +8
export const WrikeIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => {
return <WrikeIconSVG ref={ref} {...props} />;
},
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Forwarded ref won’t reach unless ./wrike uses forwardRef.

Same issue as Attio/Discord: update ./wrike to forwardRef so refs attach to the root . Also expose/use isDark for theming neutrals.

Apply this in src/frontend/src/icons/wrike/wrike.jsx (outside this hunk). A full fix tailored to Wrike (with neutral color theming) is below in that file’s review.

🤖 Prompt for AI Agents
In src/frontend/src/icons/wrike/index.tsx around lines 4 to 8, the forwarded ref
from WrikeIcon won't reach the root <svg> because ./wrike does not itself use
forwardRef; open src/frontend/src/icons/wrike/wrike.jsx and update the component
to accept (props, ref) and wrap it with React.forwardRef so the ref is attached
to the root <svg>, add an isDark boolean prop (default false) and use it to
select neutral theme colors for fills/strokes, ensure the exported component is
the forwardRef-wrapped version and the index file continues to forwardRef to
that component so refs and neutral theming propagate correctly.

Comment on lines +1 to +24
const Icon = (props) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
<path
fill="#73787F"
d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z"
/>
<path
fill="#73787F"
d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z"
/>
<path fill="#73787F" d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" />
<path
fill="#73787F"
d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z"
/>
<path
fill="#73787F"
d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z"
/>
<path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" />
<path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" />
</svg>
);
export default Icon;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ref-forwarding missing; add isDark-aware neutral fills.

Convert to forwardRef so the wrapper’s ref attaches. Also theme the neutral gray (#73787F) via isDark while preserving brand greens.

Apply:

+import React, { forwardRef } from "react";
-const Icon = (props) => (
-  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
-    <path
-      fill="#73787F"
-      d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z"
-    />
-    <path
-      fill="#73787F"
-      d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z"
-    />
-    <path fill="#73787F" d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" />
-    <path
-      fill="#73787F"
-      d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z"
-    />
-    <path
-      fill="#73787F"
-      d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z"
-    />
-    <path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" />
-    <path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" />
-  </svg>
-);
-export default Icon;
+const Icon = forwardRef(function WrikeIcon({ isDark = false, ...props }, ref) {
+  const neutral = isDark ? "#E5E7EB" : "#73787F";
+  return (
+    <svg ref={ref} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
+      <path fill={neutral} d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z" />
+      <path fill={neutral} d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z" />
+      <path fill={neutral} d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" />
+      <path fill={neutral} d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z" />
+      <path fill={neutral} d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z" />
+      <path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" />
+      <path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" />
+    </svg>
+  );
+});
+export default Icon;
📝 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 Icon = (props) => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
<path
fill="#73787F"
d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z"
/>
<path
fill="#73787F"
d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z"
/>
<path fill="#73787F" d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z" />
<path
fill="#73787F"
d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z"
/>
<path
fill="#73787F"
d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z"
/>
<path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" />
<path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" />
</svg>
);
export default Icon;
import React, { forwardRef } from "react";
const Icon = forwardRef(function WrikeIcon({ isDark = false, ...props }, ref) {
const neutral = isDark ? "#E5E7EB" : "#73787F";
return (
<svg ref={ref} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
<path
fill={neutral}
d="M19.8,40.6L14.3,56.8L9.4,40.6H3.9l8.1,24.2h4.4L25.7,48.8l5.3,16h4.4l8.1-24.2h-5.4l-4.9,16.2L25.7,40.6H19.8z"
/>
<path
fill={neutral}
d="M39.7,64.8V47.7h4.8v3.8c1.5-4.4,6.5-3.8,6.5-3.8v4.7c0,0-6.5-0.5-6.5,4.8v7.5H39.7z"
/>
<path
fill={neutral}
d="M53.3,64.8v-10.5l4.8-4.6v15.1H53.3z"
/>
<path
fill={neutral}
d="M62.2,64.8V45.9l4.8-4.8v12.8l5.9-6.2h5.9L71.7,55.4l8.6,9.4h-6.3l-6.8-7.4v7.4H62.2z"
/>
<path
fill={neutral}
d="M91.2,54.4c-0.1-1.9-1.4-3.4-3.6-3.4c-2.2,0-3.6,1.4-3.8,3.4H91.2z M81.8,62.6c-1.8-1.6-2.7-3.8-2.7-6.5c0-2.5,0.8-4.6,2.4-6.3c1.6-1.7,3.8-2.6,6.4-2.6c2.5,0,4.4,0.9,5.9,2.6c1.5,1.7,2.2,3.8,2.2,6.3v1.2h-12.1c0.5,2.3,2.7,3.5,5.7,3.5c1.9,0,3.7-0.5,5.4-1.5v3.8c-1.5,1.1-3.7,1.7-6.4,1.7C85.4,66.8,83.6,64.2,81.8,62.6L81.8,62.6z"
/>
<path fill="#00A551" d="M63.2,34.9l-10.8,10.8l3.2,3.2l14-14H63.2z" />
<path fill="#A5CD39" d="M53.6,40.6h-6.4l8.4,8.4l3.2-3.2L53.6,40.6z" />
</svg>
);
});
export default Icon;
🤖 Prompt for AI Agents
In src/frontend/src/icons/wrike/wrike.jsx lines 1-24, the component must be
converted to use React.forwardRef so the wrapper can attach a ref, and the
neutral gray fills should be theme-aware (isDark) while keeping the green brand
colors unchanged; update the component to: import React and use React.forwardRef
to accept (props, ref), pull isDark from props (or props.theme if you prefer)
and compute a neutral variable (dark vs light hex), replace the hard-coded
"#73787F" fills with that neutral variable, forward the ref to the <svg> element
and spread remaining props, and leave the green fills intact.

@Uday-sidagana Uday-sidagana force-pushed the feat/composio-v3-2-newcomponent-v1-addcompPr branch from f6a6d60 to a078a92 Compare September 6, 2025 16:50
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Sep 6, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Sep 14, 2025
Copy link
Copy Markdown
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly left a comment

Choose a reason for hiding this comment

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

code LGTM.

Testing ongoing

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

@edwinjosechittilappilly edwinjosechittilappilly added the fast-track Skip tests and sends PR into the merge queue label Sep 16, 2025
@edwinjosechittilappilly edwinjosechittilappilly added this pull request to the merge queue Sep 16, 2025
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Sep 16, 2025
@edwinjosechittilappilly edwinjosechittilappilly added this pull request to the merge queue Sep 16, 2025
Merged via the queue into langflow-ai:main with commit 5ba5519 Sep 16, 2025
32 of 33 checks passed
@edwinjosechittilappilly edwinjosechittilappilly deleted the feat/composio-v3-2-newcomponent-v1-addcompPr branch September 16, 2025 16:09
lucaseduoli pushed a commit that referenced this pull request Sep 17, 2025
feat: add more components

Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request fast-track Skip tests and sends PR into the merge queue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants