lfx-nightly 0.1.12.dev39__py3-none-any.whl → 0.1.12.dev41__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of lfx-nightly might be problematic. Click here for more details.

Files changed (41) hide show
  1. lfx/_assets/component_index.json +1 -1
  2. lfx/base/composio/composio_base.py +383 -42
  3. lfx/base/models/google_generative_ai_model.py +38 -0
  4. lfx/components/agents/__init__.py +3 -1
  5. lfx/components/agents/cuga_agent.py +995 -0
  6. lfx/components/arxiv/arxiv.py +8 -2
  7. lfx/components/composio/__init__.py +71 -17
  8. lfx/components/composio/agentql_composio.py +11 -0
  9. lfx/components/composio/agiled_composio.py +11 -0
  10. lfx/components/composio/bolna_composio.py +11 -0
  11. lfx/components/composio/brightdata_composio.py +11 -0
  12. lfx/components/composio/canvas_composio.py +11 -0
  13. lfx/components/composio/digicert_composio.py +11 -0
  14. lfx/components/composio/finage_composio.py +11 -0
  15. lfx/components/composio/fixer_composio.py +11 -0
  16. lfx/components/composio/flexisign_composio.py +11 -0
  17. lfx/components/composio/freshdesk_composio.py +11 -0
  18. lfx/components/composio/googleclassroom_composio.py +11 -0
  19. lfx/components/composio/instagram_composio.py +11 -0
  20. lfx/components/composio/jira_composio.py +11 -0
  21. lfx/components/composio/jotform_composio.py +11 -0
  22. lfx/components/composio/listennotes_composio.py +11 -0
  23. lfx/components/composio/missive_composio.py +11 -0
  24. lfx/components/composio/pandadoc_composio.py +11 -0
  25. lfx/components/composio/slack_composio.py +573 -2
  26. lfx/components/composio/timelinesai_composio.py +11 -0
  27. lfx/components/datastax/astra_db.py +1 -0
  28. lfx/components/datastax/astradb_cql.py +1 -1
  29. lfx/components/datastax/astradb_graph.py +1 -0
  30. lfx/components/datastax/astradb_tool.py +1 -1
  31. lfx/components/datastax/astradb_vectorstore.py +1 -1
  32. lfx/components/datastax/hcd.py +1 -0
  33. lfx/components/google/google_generative_ai.py +4 -7
  34. lfx/components/logic/__init__.py +3 -0
  35. lfx/components/logic/llm_conditional_router.py +65 -21
  36. lfx/components/models/language_model.py +2 -2
  37. lfx/components/processing/lambda_filter.py +82 -18
  38. {lfx_nightly-0.1.12.dev39.dist-info → lfx_nightly-0.1.12.dev41.dist-info}/METADATA +1 -1
  39. {lfx_nightly-0.1.12.dev39.dist-info → lfx_nightly-0.1.12.dev41.dist-info}/RECORD +41 -21
  40. {lfx_nightly-0.1.12.dev39.dist-info → lfx_nightly-0.1.12.dev41.dist-info}/WHEEL +0 -0
  41. {lfx_nightly-0.1.12.dev39.dist-info → lfx_nightly-0.1.12.dev41.dist-info}/entry_points.txt +0 -0
@@ -67,22 +67,24 @@ class ComposioBaseComponent(Component):
67
67
  auth_tooltip="Please insert a valid Composio API Key.",
68
68
  show=False,
69
69
  ),
70
- # Pre-defined placeholder fields for dynamic auth - will be updated dynamically
71
- StrInput(
70
+ # Pre-defined placeholder fields for dynamic auth - hidden by default
71
+ SecretStrInput(
72
72
  name="client_id",
73
- display_name="Client id",
73
+ display_name="Client ID",
74
74
  info="",
75
75
  show=False,
76
76
  value="",
77
77
  required=False,
78
+ real_time_refresh=True,
78
79
  ),
79
- StrInput(
80
+ SecretStrInput(
80
81
  name="client_secret",
81
- display_name="Client secret",
82
+ display_name="Client Secret",
82
83
  info="",
83
84
  show=False,
84
85
  value="",
85
86
  required=False,
87
+ real_time_refresh=True,
86
88
  ),
87
89
  StrInput(
88
90
  name="verification_token",
@@ -91,40 +93,82 @@ class ComposioBaseComponent(Component):
91
93
  show=False,
92
94
  value="",
93
95
  required=False,
96
+ real_time_refresh=True,
97
+ ),
98
+ StrInput(
99
+ name="redirect_uri",
100
+ display_name="Redirect URI",
101
+ info="",
102
+ show=False,
103
+ value="",
104
+ required=False,
105
+ real_time_refresh=True,
106
+ ),
107
+ StrInput(
108
+ name="authorization_url",
109
+ display_name="Authorization URL",
110
+ info="",
111
+ show=False,
112
+ value="",
113
+ required=False,
114
+ real_time_refresh=True,
94
115
  ),
95
116
  StrInput(
117
+ name="token_url",
118
+ display_name="Token URL",
119
+ info="",
120
+ show=False,
121
+ value="",
122
+ required=False,
123
+ real_time_refresh=True,
124
+ ),
125
+ # API Key auth fields
126
+ SecretStrInput(
96
127
  name="api_key_field",
97
128
  display_name="API Key",
98
129
  info="",
99
130
  show=False,
100
131
  value="",
101
132
  required=False,
133
+ real_time_refresh=True,
102
134
  ),
103
- StrInput(
135
+ SecretStrInput(
136
+ name="generic_api_key",
137
+ display_name="API Key",
138
+ info="",
139
+ show=False,
140
+ value="",
141
+ required=False,
142
+ real_time_refresh=True,
143
+ ),
144
+ SecretStrInput(
104
145
  name="token",
105
146
  display_name="Token",
106
147
  info="",
107
148
  show=False,
108
149
  value="",
109
150
  required=False,
151
+ real_time_refresh=True,
110
152
  ),
111
- # Additional common auth fields
112
- StrInput(
153
+ SecretStrInput(
113
154
  name="access_token",
114
155
  display_name="Access Token",
115
156
  info="",
116
157
  show=False,
117
158
  value="",
118
159
  required=False,
160
+ real_time_refresh=True,
119
161
  ),
120
- StrInput(
162
+ SecretStrInput(
121
163
  name="refresh_token",
122
164
  display_name="Refresh Token",
123
165
  info="",
124
166
  show=False,
125
167
  value="",
126
168
  required=False,
169
+ real_time_refresh=True,
127
170
  ),
171
+ # Basic Auth fields
128
172
  StrInput(
129
173
  name="username",
130
174
  display_name="Username",
@@ -132,15 +176,18 @@ class ComposioBaseComponent(Component):
132
176
  show=False,
133
177
  value="",
134
178
  required=False,
179
+ real_time_refresh=True,
135
180
  ),
136
- StrInput(
181
+ SecretStrInput(
137
182
  name="password",
138
183
  display_name="Password",
139
184
  info="",
140
185
  show=False,
141
186
  value="",
142
187
  required=False,
188
+ real_time_refresh=True,
143
189
  ),
190
+ # Other common auth fields
144
191
  StrInput(
145
192
  name="domain",
146
193
  display_name="Domain",
@@ -148,6 +195,7 @@ class ComposioBaseComponent(Component):
148
195
  show=False,
149
196
  value="",
150
197
  required=False,
198
+ real_time_refresh=True,
151
199
  ),
152
200
  StrInput(
153
201
  name="base_url",
@@ -156,6 +204,62 @@ class ComposioBaseComponent(Component):
156
204
  show=False,
157
205
  value="",
158
206
  required=False,
207
+ real_time_refresh=True,
208
+ ),
209
+ SecretStrInput(
210
+ name="bearer_token",
211
+ display_name="Bearer Token",
212
+ info="",
213
+ show=False,
214
+ value="",
215
+ required=False,
216
+ real_time_refresh=True,
217
+ ),
218
+ SecretStrInput(
219
+ name="authorization_code",
220
+ display_name="Authorization Code",
221
+ info="",
222
+ show=False,
223
+ value="",
224
+ required=False,
225
+ real_time_refresh=True,
226
+ ),
227
+ StrInput(
228
+ name="scopes",
229
+ display_name="Scopes",
230
+ info="",
231
+ show=False,
232
+ value="",
233
+ required=False,
234
+ real_time_refresh=True,
235
+ ),
236
+ # Add more common auth fields
237
+ StrInput(
238
+ name="subdomain",
239
+ display_name="Subdomain",
240
+ info="",
241
+ show=False,
242
+ value="",
243
+ required=False,
244
+ real_time_refresh=True,
245
+ ),
246
+ StrInput(
247
+ name="instance_url",
248
+ display_name="Instance URL",
249
+ info="",
250
+ show=False,
251
+ value="",
252
+ required=False,
253
+ real_time_refresh=True,
254
+ ),
255
+ StrInput(
256
+ name="tenant_id",
257
+ display_name="Tenant ID",
258
+ info="",
259
+ show=False,
260
+ value="",
261
+ required=False,
262
+ real_time_refresh=True,
159
263
  ),
160
264
  SortableListInput(
161
265
  name="action_button",
@@ -177,6 +281,8 @@ class ComposioBaseComponent(Component):
177
281
  # Class-level caches
178
282
  _actions_cache: dict[str, dict[str, Any]] = {}
179
283
  _action_schema_cache: dict[str, dict[str, Any]] = {}
284
+ # Track all auth field names discovered across all toolkits
285
+ _all_auth_field_names: set[str] = set()
180
286
 
181
287
  outputs = [
182
288
  Output(name="dataFrame", display_name="DataFrame", method="as_dataframe"),
@@ -851,6 +957,9 @@ class ComposioBaseComponent(Component):
851
957
  for inp in lf_inputs:
852
958
  if inp.name is not None:
853
959
  inp_dict = inp.to_dict() if hasattr(inp, "to_dict") else inp.__dict__.copy()
960
+
961
+ # Do not mutate input_types here; keep original configuration
962
+
854
963
  inp_dict.setdefault("show", True) # visible once action selected
855
964
  # Preserve previously entered value if user already filled something
856
965
  if inp.name in build_config:
@@ -1015,11 +1124,8 @@ class ComposioBaseComponent(Component):
1015
1124
  app_slug = getattr(self, "app_name", "").lower()
1016
1125
  if not app_slug:
1017
1126
  return None
1018
- try:
1019
- schema = composio.toolkits.get(slug=app_slug)
1020
- except (AttributeError, ValueError, ConnectionError, TypeError) as e:
1021
- logger.debug(f"Could not get toolkit schema for {app_slug}: {e}")
1022
- return None
1127
+ # Use the correct Composio SDK method
1128
+ schema = composio.toolkits.get(slug=app_slug)
1023
1129
  self._toolkit_schema = self._to_plain_dict(schema)
1024
1130
  except (AttributeError, ValueError, ConnectionError, TypeError) as e:
1025
1131
  logger.debug(f"Could not retrieve toolkit schema for {getattr(self, 'app_name', '')}: {e}")
@@ -1036,9 +1142,9 @@ class ComposioBaseComponent(Component):
1036
1142
  managed = schema.get("composio_managed_auth_schemes") or schema.get("composioManagedAuthSchemes") or []
1037
1143
  has_managed_schemes = isinstance(managed, list) and len(managed) > 0
1038
1144
 
1039
- # Add "Composio managed" as first option if there are managed schemes
1145
+ # Add "Composio_Managed" as first option if there are managed schemes
1040
1146
  if has_managed_schemes:
1041
- modes.append("Composio managed")
1147
+ modes.append("Composio_Managed")
1042
1148
 
1043
1149
  # auth_config_details: list with entries containing mode
1044
1150
  details = schema.get("auth_config_details") or schema.get("authConfigDetails") or []
@@ -1091,6 +1197,49 @@ class ComposioBaseComponent(Component):
1091
1197
  except (TypeError, ValueError, AttributeError) as e:
1092
1198
  logger.debug(f"Failed to render auth_mode dropdown: {e}")
1093
1199
 
1200
+ def _insert_field_before_action_button(self, build_config: dict, field_name: str, field_data: dict) -> None:
1201
+ """Insert a field in the correct position (before action_button) in build_config."""
1202
+ # If field already exists, don't add it again
1203
+ if field_name in build_config:
1204
+ return
1205
+
1206
+ # If action_button doesn't exist, just add the field normally
1207
+ if "action_button" not in build_config:
1208
+ build_config[field_name] = field_data
1209
+ return
1210
+
1211
+ # Find all the keys we need to preserve order for
1212
+ keys_before_action = []
1213
+ keys_after_action = []
1214
+ found_action = False
1215
+
1216
+ for key in list(build_config.keys()):
1217
+ if key == "action_button":
1218
+ found_action = True
1219
+ keys_after_action.append(key)
1220
+ elif found_action:
1221
+ keys_after_action.append(key)
1222
+ else:
1223
+ keys_before_action.append(key)
1224
+
1225
+ # Create new ordered dict
1226
+ new_config = {}
1227
+
1228
+ # Add all fields before action_button
1229
+ for key in keys_before_action:
1230
+ new_config[key] = build_config[key]
1231
+
1232
+ # Add the new field
1233
+ new_config[field_name] = field_data
1234
+
1235
+ # Add action_button and all fields after it
1236
+ for key in keys_after_action:
1237
+ new_config[key] = build_config[key]
1238
+
1239
+ # Clear and update build_config to maintain reference
1240
+ build_config.clear()
1241
+ build_config.update(new_config)
1242
+
1094
1243
  def _clear_auth_dynamic_fields(self, build_config: dict) -> None:
1095
1244
  for fname in list(self._auth_dynamic_fields):
1096
1245
  if fname in build_config and isinstance(build_config[fname], dict):
@@ -1121,19 +1270,50 @@ class ComposioBaseComponent(Component):
1121
1270
  if default_value is not None and default_value != "":
1122
1271
  build_config[name]["value"] = default_value
1123
1272
  else:
1124
- # Create new field if not pre-defined
1125
- field = StrInput(
1126
- name=name,
1127
- display_name=display_name or name.replace("_", " ").title(),
1128
- info=info or "",
1129
- required=required,
1130
- real_time_refresh=True,
1131
- show=True,
1132
- ).to_dict()
1273
+ # Create new field if it doesn't exist
1274
+ # Use SecretStrInput for sensitive fields
1275
+ sensitive_fields = {
1276
+ "client_id",
1277
+ "client_secret",
1278
+ "api_key",
1279
+ "api_key_field",
1280
+ "generic_api_key",
1281
+ "token",
1282
+ "access_token",
1283
+ "refresh_token",
1284
+ "password",
1285
+ "bearer_token",
1286
+ "authorization_code",
1287
+ }
1288
+
1289
+ if name in sensitive_fields:
1290
+ field = SecretStrInput(
1291
+ name=name,
1292
+ display_name=display_name or name.replace("_", " ").title(),
1293
+ info=info or "",
1294
+ required=required,
1295
+ real_time_refresh=True,
1296
+ show=True,
1297
+ ).to_dict()
1298
+ else:
1299
+ field = StrInput(
1300
+ name=name,
1301
+ display_name=display_name or name.replace("_", " ").title(),
1302
+ info=info or "",
1303
+ required=required,
1304
+ real_time_refresh=True,
1305
+ show=True,
1306
+ ).to_dict()
1307
+
1133
1308
  if default_value is not None and default_value != "":
1134
1309
  field["value"] = default_value
1135
- build_config[name] = field
1310
+
1311
+ # Insert the field in the correct position (before action_button)
1312
+ self._insert_field_before_action_button(build_config, name, field)
1313
+
1136
1314
  self._auth_dynamic_fields.add(name)
1315
+ # Also add to class-level cache for better tracking
1316
+ self.__class__._all_auth_field_names.add(name)
1137
1317
 
1138
1318
  def _render_custom_auth_fields(self, build_config: dict, schema: dict[str, Any], mode: str) -> None:
1139
1319
  """Render fields for custom auth based on schema auth_config_details sections."""
@@ -1197,6 +1377,8 @@ class ComposioBaseComponent(Component):
1197
1377
  name = entry.get("name") if isinstance(entry, dict) else None
1198
1378
  if name:
1199
1379
  names.add(name)
1380
+ # Add to class-level cache for tracking all discovered auth fields
1381
+ self.__class__._all_auth_field_names.add(name)
1200
1382
  # Only use names discovered from the toolkit schema; do not add aliases
1201
1383
  return names
1202
1384
 
@@ -1226,6 +1408,8 @@ class ComposioBaseComponent(Component):
1226
1408
 
1227
1409
  def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:
1228
1410
  """Update build config for auth and action selection."""
1411
+ # Avoid normalizing legacy input_types here; rely on upstream fixes
1412
+
1229
1413
  # BULLETPROOF tool_mode checking - check all possible places where tool_mode could be stored
1230
1414
  instance_tool_mode = getattr(self, "tool_mode", False) if hasattr(self, "tool_mode") else False
1231
1415
 
@@ -1282,10 +1466,11 @@ class ComposioBaseComponent(Component):
1282
1466
  try:
1283
1467
  selected_mode = (build_config.get("auth_mode") or {}).get("value")
1284
1468
  managed = (schema or {}).get("composio_managed_auth_schemes") or []
1285
- # Don't render custom fields if "Composio managed" is selected
1286
- if selected_mode and selected_mode != "Composio managed":
1469
+ # Don't render custom fields if "Composio_Managed" is selected
1470
+ if selected_mode and selected_mode != "Composio_Managed":
1287
1471
  self._clear_auth_dynamic_fields(build_config)
1288
1472
  self._render_custom_auth_fields(build_config, schema or {}, selected_mode)
1473
+ # Already reordered in _render_custom_auth_fields
1289
1474
  except (TypeError, ValueError, AttributeError):
1290
1475
  pass
1291
1476
 
@@ -1429,16 +1614,18 @@ class ComposioBaseComponent(Component):
1429
1614
  build_config["create_auth_config"]["value"] = ""
1430
1615
  build_config["create_auth_config"]["helper_text"] = ""
1431
1616
  build_config["create_auth_config"]["options"] = ["create"]
1432
- if mode == "Composio managed":
1433
- # Composio managed → no extra fields needed
1617
+ if mode == "Composio_Managed":
1618
+ # Composio_Managed → no extra fields needed
1434
1619
  pass
1435
1620
  elif isinstance(managed, list) and mode in managed:
1436
1621
  # This is a specific managed auth scheme (e.g., OAUTH2) but user can still choose custom
1437
1622
  # So we should render custom fields for this mode
1438
1623
  self._render_custom_auth_fields(build_config, schema, mode)
1624
+ # Already reordered in _render_custom_auth_fields
1439
1625
  else:
1440
1626
  # Custom → render only required fields based on the toolkit schema
1441
1627
  self._render_custom_auth_fields(build_config, schema, mode)
1628
+ # Already reordered in _render_custom_auth_fields
1442
1629
  return self.update_input_types(build_config)
1443
1630
 
1444
1631
  # Handle connection initiation when tool mode is enabled
@@ -1455,6 +1642,37 @@ class ComposioBaseComponent(Component):
1455
1642
  build_config["auth_link"]["connection_id"] = connection_id
1456
1643
  build_config["action_button"]["helper_text"] = ""
1457
1644
  build_config["action_button"]["helper_text_metadata"] = {}
1645
+
1646
+ # Clear auth fields when connected
1647
+ schema = self._get_toolkit_schema()
1648
+ self._clear_auth_fields_from_schema(build_config, schema)
1649
+
1650
+ # Convert auth_mode to pill for connected state
1651
+ scheme, _ = self._get_connection_auth_info(connection_id)
1652
+ if scheme:
1653
+ build_config.setdefault("auth_mode", {})
1654
+ build_config["auth_mode"]["value"] = scheme
1655
+ build_config["auth_mode"]["options"] = [scheme]
1656
+ build_config["auth_mode"]["show"] = False
1657
+ try:
1658
+ pill = TabInput(
1659
+ name="auth_mode",
1660
+ display_name="Auth Mode",
1661
+ options=[scheme],
1662
+ value=scheme,
1663
+ ).to_dict()
1664
+ pill["show"] = True
1665
+ build_config["auth_mode"] = pill
1666
+ except (TypeError, ValueError, AttributeError):
1667
+ build_config["auth_mode"] = {
1668
+ "name": "auth_mode",
1669
+ "display_name": "Auth Mode",
1670
+ "type": "tab",
1671
+ "options": [scheme],
1672
+ "value": scheme,
1673
+ "show": True,
1674
+ }
1675
+
1458
1676
  logger.info(f"Using existing ACTIVE connection {connection_id} for {toolkit_slug}")
1459
1677
  return self.update_input_types(build_config)
1460
1678
 
@@ -1472,13 +1690,14 @@ class ComposioBaseComponent(Component):
1472
1690
  # If no managed default exists (400 Default auth config), require mode selection
1473
1691
  managed = (schema or {}).get("composio_managed_auth_schemes") or []
1474
1692
 
1475
- # Handle "Composio managed" mode explicitly
1476
- if mode == "Composio managed":
1477
- # Use Composio managed auth flow
1693
+ # Handle "Composio_Managed" mode explicitly
1694
+ if mode == "Composio_Managed":
1695
+ # Use Composio_Managed auth flow
1478
1696
  redirect_url, connection_id = self._initiate_connection(toolkit_slug)
1479
1697
  build_config["auth_link"]["value"] = redirect_url
1480
1698
  logger.info(f"New OAuth URL created for {toolkit_slug}: {redirect_url}")
1481
1699
  return self.update_input_types(build_config)
1700
+
1482
1701
  if not mode:
1483
1702
  build_config["auth_link"]["value"] = "connect"
1484
1703
  build_config["auth_link"]["auth_tooltip"] = "Select Auth Mode"
@@ -1686,6 +1905,33 @@ class ComposioBaseComponent(Component):
1686
1905
  self._clear_auth_fields_from_schema(build_config, schema)
1687
1906
  build_config["action_button"]["helper_text"] = ""
1688
1907
  build_config["action_button"]["helper_text_metadata"] = {}
1908
+
1909
+ # Convert auth_mode to pill for connected state
1910
+ if not redirect_url and mode: # API_KEY or similar direct connection
1911
+ build_config["auth_link"]["connection_id"] = connection_id
1912
+ build_config.setdefault("auth_mode", {})
1913
+ build_config["auth_mode"]["value"] = mode
1914
+ build_config["auth_mode"]["options"] = [mode]
1915
+ build_config["auth_mode"]["show"] = False
1916
+ try:
1917
+ pill = TabInput(
1918
+ name="auth_mode",
1919
+ display_name="Auth Mode",
1920
+ options=[mode],
1921
+ value=mode,
1922
+ ).to_dict()
1923
+ pill["show"] = True
1924
+ build_config["auth_mode"] = pill
1925
+ except (TypeError, ValueError, AttributeError):
1926
+ build_config["auth_mode"] = {
1927
+ "name": "auth_mode",
1928
+ "display_name": "Auth Mode",
1929
+ "type": "tab",
1930
+ "options": [mode],
1931
+ "value": mode,
1932
+ "show": True,
1933
+ }
1934
+
1689
1935
  return self.update_input_types(build_config)
1690
1936
  # Generic custom auth flow for any other mode (treat like API_KEY)
1691
1937
  ac = composio.auth_configs.create(
@@ -1720,6 +1966,36 @@ class ComposioBaseComponent(Component):
1720
1966
  else:
1721
1967
  build_config["auth_link"]["value"] = "validated"
1722
1968
  build_config["auth_link"]["auth_tooltip"] = "Disconnect"
1969
+ build_config["auth_link"]["connection_id"] = connection_id
1970
+
1971
+ # Clear auth fields when connected
1972
+ schema = self._get_toolkit_schema()
1973
+ self._clear_auth_fields_from_schema(build_config, schema)
1974
+
1975
+ # Convert auth_mode to pill for connected state
1976
+ if mode:
1977
+ build_config.setdefault("auth_mode", {})
1978
+ build_config["auth_mode"]["value"] = mode
1979
+ build_config["auth_mode"]["options"] = [mode]
1980
+ build_config["auth_mode"]["show"] = False
1981
+ try:
1982
+ pill = TabInput(
1983
+ name="auth_mode",
1984
+ display_name="Auth Mode",
1985
+ options=[mode],
1986
+ value=mode,
1987
+ ).to_dict()
1988
+ pill["show"] = True
1989
+ build_config["auth_mode"] = pill
1990
+ except (TypeError, ValueError, AttributeError):
1991
+ build_config["auth_mode"] = {
1992
+ "name": "auth_mode",
1993
+ "display_name": "Auth Mode",
1994
+ "type": "tab",
1995
+ "options": [mode],
1996
+ "value": mode,
1997
+ "show": True,
1998
+ }
1723
1999
  return self.update_input_types(build_config)
1724
2000
  except (ValueError, ConnectionError, TypeError) as e:
1725
2001
  logger.error(f"Error creating connection: {e}")
@@ -1845,14 +2121,22 @@ class ComposioBaseComponent(Component):
1845
2121
  build_config.setdefault("auth_link", {})
1846
2122
  build_config["auth_link"]["show"] = False
1847
2123
  build_config["auth_link"]["display_name"] = ""
1848
- try:
1849
- schema = self._get_toolkit_schema()
1850
- mode = (build_config.get("auth_mode") or {}).get("value")
1851
- managed = (schema or {}).get("composio_managed_auth_schemes") or []
1852
- if mode and mode != "Composio managed" and not getattr(self, "_auth_dynamic_fields", set()):
1853
- self._render_custom_auth_fields(build_config, schema or {}, mode)
1854
- except (TypeError, ValueError, AttributeError):
1855
- pass
2124
+
2125
+ # Only render auth fields if NOT already connected
2126
+ active_connection = self._find_active_connection_for_app(self.app_name)
2127
+ if not active_connection:
2128
+ try:
2129
+ schema = self._get_toolkit_schema()
2130
+ mode = (build_config.get("auth_mode") or {}).get("value")
2131
+ managed = (schema or {}).get("composio_managed_auth_schemes") or []
2132
+ if mode and mode != "Composio_Managed" and not getattr(self, "_auth_dynamic_fields", set()):
2133
+ self._render_custom_auth_fields(build_config, schema or {}, mode)
2134
+ # Already reordered in _render_custom_auth_fields
2135
+ except (TypeError, ValueError, AttributeError):
2136
+ pass
2137
+ else:
2138
+ # If connected, clear any auth fields that might be showing
2139
+ self._clear_auth_dynamic_fields(build_config)
1856
2140
  # Do NOT return here; allow auth flow to run in Tool Mode
1857
2141
 
1858
2142
  if field_name == "tool_mode":
@@ -2039,6 +2323,36 @@ class ComposioBaseComponent(Component):
2039
2323
  build_config["auth_link"]["auth_tooltip"] = "Disconnect"
2040
2324
  build_config["action_button"]["helper_text"] = ""
2041
2325
  build_config["action_button"]["helper_text_metadata"] = {}
2326
+
2327
+ # Clear auth fields when connected
2328
+ schema = self._get_toolkit_schema()
2329
+ self._clear_auth_fields_from_schema(build_config, schema)
2330
+
2331
+ # Convert auth_mode to pill for connected state
2332
+ scheme, _ = self._get_connection_auth_info(active_connection_id)
2333
+ if scheme:
2334
+ build_config.setdefault("auth_mode", {})
2335
+ build_config["auth_mode"]["value"] = scheme
2336
+ build_config["auth_mode"]["options"] = [scheme]
2337
+ build_config["auth_mode"]["show"] = False
2338
+ try:
2339
+ pill = TabInput(
2340
+ name="auth_mode",
2341
+ display_name="Auth Mode",
2342
+ options=[scheme],
2343
+ value=scheme,
2344
+ ).to_dict()
2345
+ pill["show"] = True
2346
+ build_config["auth_mode"] = pill
2347
+ except (TypeError, ValueError, AttributeError):
2348
+ build_config["auth_mode"] = {
2349
+ "name": "auth_mode",
2350
+ "display_name": "Auth Mode",
2351
+ "type": "tab",
2352
+ "options": [scheme],
2353
+ "value": scheme,
2354
+ "show": True,
2355
+ }
2042
2356
  elif stored_connection_id:
2043
2357
  status = self._check_connection_status_by_id(stored_connection_id)
2044
2358
  if status == "INITIATED":
@@ -2283,7 +2597,34 @@ class ComposioBaseComponent(Component):
2283
2597
  "auth_mode",
2284
2598
  "auth_mode_pill",
2285
2599
  "create_auth_config",
2600
+ # Pre-defined auth fields
2601
+ "client_id",
2602
+ "client_secret",
2603
+ "verification_token",
2604
+ "redirect_uri",
2605
+ "authorization_url",
2606
+ "token_url",
2607
+ "api_key_field",
2608
+ "generic_api_key",
2609
+ "token",
2610
+ "access_token",
2611
+ "refresh_token",
2612
+ "username",
2613
+ "password",
2614
+ "domain",
2615
+ "base_url",
2616
+ "bearer_token",
2617
+ "authorization_code",
2618
+ "scopes",
2619
+ "subdomain",
2620
+ "instance_url",
2621
+ "tenant_id",
2286
2622
  }
2623
+ # Add all dynamic auth fields to protected set
2624
+ protected.update(self._auth_dynamic_fields)
2625
+ # Also protect any auth fields discovered across all instances
2626
+ protected.update(self.__class__._all_auth_field_names)
2627
+
2287
2628
  for key, cfg in list(build_config.items()):
2288
2629
  if key in protected:
2289
2630
  continue
@@ -0,0 +1,38 @@
1
+ from langchain_google_genai import ChatGoogleGenerativeAI
2
+
3
+
4
+ class ChatGoogleGenerativeAIFixed(ChatGoogleGenerativeAI):
5
+ """Custom ChatGoogleGenerativeAI that fixes function response name issues for Gemini."""
6
+
7
+ def __init__(self, *args, **kwargs):
8
+ """Initialize with fix for empty function response names in ToolMessage and FunctionMessage."""
9
+ if ChatGoogleGenerativeAI is None:
10
+ msg = "The 'langchain_google_genai' package is required to use the Google Generative AI model."
11
+ raise ImportError(msg)
12
+
13
+ # Initialize the parent class
14
+ super().__init__(*args, **kwargs)
15
+
16
+ def _prepare_request(self, messages, **kwargs):
17
+ """Override request preparation to fix empty function response names."""
18
+ from langchain_core.messages import FunctionMessage, ToolMessage
19
+
20
+ # Pre-process messages to ensure tool/function messages have names
21
+ fixed_messages = []
22
+ for message in messages:
23
+ fixed_message = message
24
+ if isinstance(message, ToolMessage) and not message.name:
25
+ # Create a new ToolMessage with a default name
26
+ fixed_message = ToolMessage(
27
+ content=message.content,
28
+ name="tool_response",
29
+ tool_call_id=getattr(message, "tool_call_id", None),
30
+ artifact=getattr(message, "artifact", None),
31
+ )
32
+ elif isinstance(message, FunctionMessage) and not message.name:
33
+ # Create a new FunctionMessage with a default name
34
+ fixed_message = FunctionMessage(content=message.content, name="function_response")
35
+ fixed_messages.append(fixed_message)
36
+
37
+ # Call the parent's method with fixed messages
38
+ return super()._prepare_request(fixed_messages, **kwargs)