diff --git a/src/backend/base/langflow/components/composio/googlemeet_composio.py b/src/backend/base/langflow/components/composio/googlemeet_composio.py index 6c14fce898e6..cd11db72b6f0 100644 --- a/src/backend/base/langflow/components/composio/googlemeet_composio.py +++ b/src/backend/base/langflow/components/composio/googlemeet_composio.py @@ -1,3 +1,4 @@ +# flake8: noqa: TRY300 from typing import Any from composio import Action @@ -18,7 +19,6 @@ class ComposioGooglemeetAPIComponent(ComposioBaseComponent): documentation: str = "https://docs.composio.dev" app_name: str = "googlemeet" - # Google Meet specific actions _actions_data: dict = { "GOOGLEMEET_GET_TRANSCRIPTS_BY_CONFERENCE_RECORD_ID": { "display_name": "Get Transcripts By Conference Record ID", @@ -40,10 +40,14 @@ class ComposioGooglemeetAPIComponent(ComposioBaseComponent): "GOOGLEMEET_CREATE_MEET": { "display_name": "Create Meet", "action_fields": ["GOOGLEMEET_CREATE_MEET_access_type", "GOOGLEMEET_CREATE_MEET_entry_point_access"], + "get_result_field": True, + "result_field": "response_data", }, "GOOGLEMEET_GET_MEET": { "display_name": "Get Meet Details", "action_fields": ["GOOGLEMEET_GET_MEET_space_name"], + "get_result_field": True, + "result_field": "response_data", }, } @@ -146,22 +150,20 @@ def execute_action(self): params=params, ) if not result.get("successful"): - return {"error": result.get("error", "No response")} - - result_data = result.get("data", []) - if ( - len(result_data) != 1 - and not self._actions_data.get(action_key, {}).get("result_field") - and self._actions_data.get(action_key, {}).get("get_result_field") - ): - msg = f"Expected a dict with a single key, got {len(result_data)} keys: {result_data.keys()}" - raise ValueError(msg) - if result_data: - get_result_field = self._actions_data.get(action_key, {}).get("get_result_field", True) - if get_result_field: - key = self._actions_data.get(action_key, {}).get("result_field", next(iter(result_data))) - return result_data.get(key) + # Return the 'data' part of the response if unsuccessful + return result.get("data", {}) + + result_data = result.get("data", {}) + action_data = self._actions_data.get(action_key, {}) + get_result_field = action_data.get("get_result_field", False) + result_field = action_data.get("result_field") + + if get_result_field: + if result_field is not None: + return result_data.get(result_field) + # If get_result_field is True but no result_field is specified, return the whole data return result_data + return result_data except Exception as e: logger.error(f"Error executing action: {e}") display_name = self.action[0]["name"] if isinstance(self.action, list) and self.action else str(self.action) diff --git a/src/backend/tests/unit/components/bundles/composio/test_googlemeet.py b/src/backend/tests/unit/components/bundles/composio/test_googlemeet.py index c8e89b58ff42..2a0a72474f30 100644 --- a/src/backend/tests/unit/components/bundles/composio/test_googlemeet.py +++ b/src/backend/tests/unit/components/bundles/composio/test_googlemeet.py @@ -59,20 +59,20 @@ def test_execute_action_create_meet(self, component_class, default_kwargs, monke component = component_class(**default_kwargs) component.api_key = "test_key" component.action = [{"name": "Create Meet"}] - setattr(component, "GOOGLEMEET_CREATE_MEET-access_type", "OPEN") - setattr(component, "GOOGLEMEET_CREATE_MEET-entry_point_access", "ALL") + component.GOOGLEMEET_CREATE_MEET_access_type = "OPEN" + component.GOOGLEMEET_CREATE_MEET_entry_point_access = "ALL" # For this specific test, customize the _actions_data to not use get_result_field component._actions_data = { "GOOGLEMEET_CREATE_MEET": { "display_name": "Create Meet", - "action_fields": ["GOOGLEMEET_CREATE_MEET-access_type", "GOOGLEMEET_CREATE_MEET-entry_point_access"], + "action_fields": ["GOOGLEMEET_CREATE_MEET_access_type", "GOOGLEMEET_CREATE_MEET_entry_point_access"], }, } # Execute action result = component.execute_action() - assert result == "mocked response" + assert result == {"result": "mocked response"} def test_execute_action_get_meet(self, component_class, default_kwargs, monkeypatch): # Mock Action enum @@ -82,13 +82,13 @@ def test_execute_action_get_meet(self, component_class, default_kwargs, monkeypa component = component_class(**default_kwargs) component.api_key = "test_key" component.action = [{"name": "Get Meet Details"}] - setattr(component, "GOOGLEMEET_GET_MEET-space_name", "test space") + component.GOOGLEMEET_GET_MEET_space_name = "test space" # For this specific test, we need to customize the action_data to handle results field component._actions_data = { "GOOGLEMEET_GET_MEET": { "display_name": "Get Meet Details", - "action_fields": ["GOOGLEMEET_GET_MEET-space_name"], + "action_fields": ["GOOGLEMEET_GET_MEET_space_name"], }, } @@ -100,7 +100,7 @@ def test_execute_action_get_meet(self, component_class, default_kwargs, monkeypa with patch.object(component, "_build_wrapper", return_value=mock_toolset): result = component.execute_action() # Based on the component's actual behavior, it returns the entire data dict - assert result == "mocked response" + assert result == {"messages": "mocked response"} def test_execute_action_invalid_action(self, component_class, default_kwargs): # Setup component @@ -120,7 +120,7 @@ def test_as_dataframe(self, component_class, default_kwargs, monkeypatch): component = component_class(**default_kwargs) component.api_key = "test_key" component.action = [{"name": "Get Meet"}] - setattr(component, "GOOGLEMEET_GET_MEET-space_name", "test space") + component.GOOGLEMEET_GET_MEET_space_name = "test space" # Create mock email data that would be returned by execute_action mock_meet_details = [ diff --git a/src/frontend/src/icons/googlemeet/googlemeet.jsx b/src/frontend/src/icons/googlemeet/googlemeet.jsx index 15d1ac27479d..d1c92a65c54f 100644 --- a/src/frontend/src/icons/googlemeet/googlemeet.jsx +++ b/src/frontend/src/icons/googlemeet/googlemeet.jsx @@ -1,4 +1,4 @@ -const Icon = (props) => ( +const GooglemeetIcon = (props) => ( ( /> ); -export default Icon; +export default GooglemeetIcon; diff --git a/src/frontend/src/icons/lazyIconImports.ts b/src/frontend/src/icons/lazyIconImports.ts index 5247cbea1abb..0e39b86382b0 100644 --- a/src/frontend/src/icons/lazyIconImports.ts +++ b/src/frontend/src/icons/lazyIconImports.ts @@ -111,7 +111,7 @@ export const lazyIconsMapping = { import("@/icons/googlecalendar").then((mod) => ({ default: mod.GooglecalendarIcon, })), - GoogleMeet: () => + Googlemeet: () => import("@/icons/googlemeet").then((mod) => ({ default: mod.GooglemeetIcon, })), diff --git a/src/frontend/src/utils/styleUtils.ts b/src/frontend/src/utils/styleUtils.ts index 97935b8a9af6..10ff99e16963 100644 --- a/src/frontend/src/utils/styleUtils.ts +++ b/src/frontend/src/utils/styleUtils.ts @@ -5,6 +5,7 @@ import { TwitterLogoIcon } from "@radix-ui/react-icons"; import dynamicIconImports from "lucide-react/dynamicIconImports"; import { lazy } from "react"; import { FaApple, FaDiscord, FaGithub } from "react-icons/fa"; +import { GooglemeetIcon } from "../icons/googlemeet"; const iconCache = new Map(); @@ -371,6 +372,7 @@ export const nodeIconToDisplayIconMap: Record = { GoogleSearchResults: "Google", GoogleSearchRun: "Google", GoogleSerperAPI: "Google", + Googlemeet: "Googlemeet", group_components: "GradientUngroup", HNLoader: "HackerNews", HuggingFaceEmbeddings: "HuggingFace",