langflow-base-nightly 0.5.0.dev33__py3-none-any.whl → 0.5.0.dev35__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.
Files changed (171) hide show
  1. langflow/alembic/versions/1cb603706752_modify_uniqueness_constraint_on_file_.py +279 -0
  2. langflow/api/v1/endpoints.py +1 -1
  3. langflow/base/composio/composio_base.py +1092 -126
  4. langflow/components/agents/mcp_component.py +21 -4
  5. langflow/components/composio/__init__.py +24 -0
  6. langflow/components/composio/composio_api.py +116 -136
  7. langflow/components/composio/dropbox_compnent.py +11 -0
  8. langflow/components/composio/github_composio.py +1 -639
  9. langflow/components/composio/gmail_composio.py +26 -394
  10. langflow/components/composio/googlecalendar_composio.py +2 -778
  11. langflow/components/composio/googlemeet_composio.py +11 -0
  12. langflow/components/composio/googletasks_composio.py +8 -0
  13. langflow/components/composio/linear_composio.py +11 -0
  14. langflow/components/composio/outlook_composio.py +1 -755
  15. langflow/components/composio/reddit_composio.py +11 -0
  16. langflow/components/composio/slack_composio.py +1 -576
  17. langflow/components/composio/slackbot_composio.py +11 -0
  18. langflow/components/composio/supabase_composio.py +11 -0
  19. langflow/components/composio/todoist_composio.py +11 -0
  20. langflow/components/composio/youtube_composio.py +11 -0
  21. langflow/components/data/kb_ingest.py +15 -16
  22. langflow/components/processing/save_file.py +31 -4
  23. langflow/custom/utils.py +30 -7
  24. langflow/frontend/assets/{SlackIcon-Bikuxo8x.js → SlackIcon-B260Qg_R.js} +1 -1
  25. langflow/frontend/assets/{Wikipedia-B6aCFf5-.js → Wikipedia-BB2mbgyd.js} +1 -1
  26. langflow/frontend/assets/{Wolfram-CekL_M-a.js → Wolfram-DytXC9hF.js} +1 -1
  27. langflow/frontend/assets/{index-D1RgjMON.js → index-3TJWUdmx.js} +1 -1
  28. langflow/frontend/assets/{index-B4xLpgbM.js → index-3qMh9x6K.js} +1 -1
  29. langflow/frontend/assets/{index-DEuXrfXH.js → index-3uOAA_XX.js} +1 -1
  30. langflow/frontend/assets/{index-DTJX3yQa.js → index-4eRtaV45.js} +1 -1
  31. langflow/frontend/assets/index-7xXgqu09.js +1 -0
  32. langflow/frontend/assets/{index-BRNhftot.js → index-AY5Dm2mG.js} +1 -1
  33. langflow/frontend/assets/{index-4Tl3Nxdo.js → index-AlJ7td-D.js} +1 -1
  34. langflow/frontend/assets/{index-D2nHdRne.js → index-B-c82Fnu.js} +1 -1
  35. langflow/frontend/assets/{index-C3RZz8WE.js → index-B2ggrBuR.js} +1 -1
  36. langflow/frontend/assets/{index-in188l0A.js → index-B536IPXH.js} +1 -1
  37. langflow/frontend/assets/{index-CP0tFKwN.js → index-B5ed-sAv.js} +1 -1
  38. langflow/frontend/assets/{index-CAzSTGAM.js → index-B8TlNgn-.js} +1 -1
  39. langflow/frontend/assets/{index-09CVJwsY.js → index-B8y58M9b.js} +1 -1
  40. langflow/frontend/assets/{index-B9uOBe6Y.js → index-B9Mo3ndZ.js} +1 -1
  41. langflow/frontend/assets/{index-DAJafn16.js → index-BCK-ZyIh.js} +1 -1
  42. langflow/frontend/assets/{index-Cy-ZEfWh.js → index-BEDxAk3N.js} +1 -1
  43. langflow/frontend/assets/{index-DbmqjLy6.js → index-BEKoRwsX.js} +1 -1
  44. langflow/frontend/assets/{index-BcqeL_f4.js → index-BIkqesA-.js} +1 -1
  45. langflow/frontend/assets/{index-7x3wNZ-4.js → index-BJrY2Fiu.js} +1 -1
  46. langflow/frontend/assets/{index-Iamzh9ZT.js → index-BKvKC-12.js} +1 -1
  47. langflow/frontend/assets/{index-COqjpsdy.js → index-BLROcaSz.js} +1 -1
  48. langflow/frontend/assets/{index-BRwkzs92.js → index-BNbWMmAV.js} +1 -1
  49. langflow/frontend/assets/{index-C_UkF-RJ.js → index-BOEf7-ty.js} +1 -1
  50. langflow/frontend/assets/index-BOYTBrh9.js +1 -0
  51. langflow/frontend/assets/{index-DDcpxWU4.js → index-BQB-iDYl.js} +1 -1
  52. langflow/frontend/assets/{index-Crq_yhkG.js → index-BRWNIt9F.js} +1 -1
  53. langflow/frontend/assets/{index-DmaQAn3K.js → index-BVHvIhT5.js} +1 -1
  54. langflow/frontend/assets/{index-Cs_jt3dj.js → index-BVtf6m9S.js} +1 -1
  55. langflow/frontend/assets/{index-T2jJOG85.js → index-BWq9GTzt.js} +1 -1
  56. langflow/frontend/assets/{index-Dz0r9Idb.js → index-BXMhmvTj.js} +1 -1
  57. langflow/frontend/assets/{index-eJwu5YEi.js → index-Ba3RTMXI.js} +1 -1
  58. langflow/frontend/assets/{index-xVx59Op-.js → index-Baka5dKE.js} +1 -1
  59. langflow/frontend/assets/{index-DnusMCK1.js → index-BbsND1Qg.js} +1 -1
  60. langflow/frontend/assets/index-BcgB3rXH.js +1 -0
  61. langflow/frontend/assets/{index-CmiRgF_-.js → index-BdIWbCEL.js} +1 -1
  62. langflow/frontend/assets/{index-BllNr21U.js → index-BdYgKk1d.js} +1 -1
  63. langflow/frontend/assets/{index-BIKbxmIh.js → index-BeNby7qF.js} +1 -1
  64. langflow/frontend/assets/{index-CUe1ivTn.js → index-BejHxU5W.js} +1 -1
  65. langflow/frontend/assets/{index-CVphnxXi.js → index-Bisa4IQF.js} +1 -1
  66. langflow/frontend/assets/{index-Cr2oy5K2.js → index-BjENqyKe.js} +1 -1
  67. langflow/frontend/assets/{index-CEn_71Wk.js → index-BlBl2tvQ.js} +1 -1
  68. langflow/frontend/assets/{index-DOb9c2bf.js → index-BnLT29qW.js} +1 -1
  69. langflow/frontend/assets/{index-BRizlHaN.js → index-BqUeOc7Y.js} +1 -1
  70. langflow/frontend/assets/{index-D7nFs6oq.js → index-BsBWP-Dh.js} +1 -1
  71. langflow/frontend/assets/{index-BlRTHXW5.js → index-BtJ2o21k.js} +1 -1
  72. langflow/frontend/assets/{index-AOX7bbjJ.js → index-BxWXWRmZ.js} +1 -1
  73. langflow/frontend/assets/{index-B20KmxhS.js → index-BxkZkBgQ.js} +1 -1
  74. langflow/frontend/assets/{index-DoFlaGDx.js → index-Bxml6wXu.js} +1 -1
  75. langflow/frontend/assets/{index-B9KRIJFi.js → index-ByFXr9Iq.js} +1 -1
  76. langflow/frontend/assets/{index-CY6LUi4V.js → index-C2Xd7UkR.js} +1 -1
  77. langflow/frontend/assets/index-C76aBV_h.js +1 -0
  78. langflow/frontend/assets/{index-9gkURvG2.js → index-C7V5U9yH.js} +1 -1
  79. langflow/frontend/assets/{index-BDmbsLY2.js → index-C7x9R_Yo.js} +1 -1
  80. langflow/frontend/assets/{index-DI0zAExi.js → index-C8KD3LPb.js} +1 -1
  81. langflow/frontend/assets/{index-DzDNhMMW.js → index-C9N80hP8.js} +1 -1
  82. langflow/frontend/assets/{index-6GWpsedd.js → index-CDFLVFB4.js} +1 -1
  83. langflow/frontend/assets/{index-pkOi9P45.js → index-CF4dtI6S.js} +1 -1
  84. langflow/frontend/assets/{index-CdwjD4IX.js → index-CG7cp0nD.js} +1 -1
  85. langflow/frontend/assets/{index-J0pvFqLk.js → index-CHFO5O4g.js} +1 -1
  86. langflow/frontend/assets/{index-5G402gB8.js → index-CJwYfDBz.js} +1 -1
  87. langflow/frontend/assets/{index-BzCjyHto.js → index-CMGZGIx_.js} +1 -1
  88. langflow/frontend/assets/{index-Bm7a2vMS.js → index-COL0eiWI.js} +1 -1
  89. langflow/frontend/assets/{index-JHCxbvlW.js → index-CWWo2zOA.js} +1 -1
  90. langflow/frontend/assets/{index-C7wDSVVH.js → index-C_1RBTul.js} +1 -1
  91. langflow/frontend/assets/{index-BIjUtp6d.js → index-Ccb5B8zG.js} +1 -1
  92. langflow/frontend/assets/{index-yIh6-LZT.js → index-Cd5zuUUK.js} +1 -1
  93. langflow/frontend/assets/{index-CPIdMJkX.js → index-CkQ-bJ4G.js} +1 -1
  94. langflow/frontend/assets/{index-TRyDa01A.js → index-CkSzjCqM.js} +1 -1
  95. langflow/frontend/assets/{index-CSRizl2S.js → index-CoUlHbtg.js} +1 -1
  96. langflow/frontend/assets/index-Cpgkb0Q3.js +1 -0
  97. langflow/frontend/assets/{index-Cp7Pmn03.js → index-CqDUqHfd.js} +1 -1
  98. langflow/frontend/assets/{index-CGVDXKtN.js → index-Ct9_T9ox.js} +1 -1
  99. langflow/frontend/assets/{index-BwlYjc56.js → index-CvQ0w8Pj.js} +1 -1
  100. langflow/frontend/assets/{index-DkJCCraf.js → index-CwIxqYlT.js} +1 -1
  101. langflow/frontend/assets/{index-Bgd7yLoW.js → index-Cx__T92e.js} +1 -1
  102. langflow/frontend/assets/{index-RveG4dl9.js → index-D-zkHcob.js} +1 -1
  103. langflow/frontend/assets/{index-DVV_etfW.js → index-D0HmkH0H.js} +1 -1
  104. langflow/frontend/assets/{index-CglSqvB5.js → index-D0s9f6Re.js} +1 -1
  105. langflow/frontend/assets/{index-J98sU-1p.js → index-D5PeCofu.js} +1 -1
  106. langflow/frontend/assets/{index-BJIsQS8D.js → index-D87Zw62M.js} +1 -1
  107. langflow/frontend/assets/{index-FYcoJPMP.js → index-D9eflZfP.js} +1 -1
  108. langflow/frontend/assets/{index-DJs6FoYC.js → index-DDNNv4C0.js} +1 -1
  109. langflow/frontend/assets/index-DHlEwAxb.js +1 -0
  110. langflow/frontend/assets/{index-DqDQk0Cu.js → index-DIqSyDVO.js} +1 -1
  111. langflow/frontend/assets/{index-DOI0ceS-.js → index-DK8vNpXK.js} +1 -1
  112. langflow/frontend/assets/{index-D29n5mus.js → index-DKEXZFUO.js} +1 -1
  113. langflow/frontend/assets/{index-dfaj9-hY.js → index-DPX6X_bw.js} +1 -1
  114. langflow/frontend/assets/{index-CgbINWS8.js → index-DS1EgA10.js} +1 -1
  115. langflow/frontend/assets/{index-C69gdJqw.js → index-DS9I4y48.js} +1 -1
  116. langflow/frontend/assets/{index-B2EmwqKj.js → index-DWkMJnbd.js} +1 -1
  117. langflow/frontend/assets/{index-CIYzjH2y.js → index-DWr_zPkx.js} +1 -1
  118. langflow/frontend/assets/{index-D-HTZ68O.js → index-DX7XsAcx.js} +1 -1
  119. langflow/frontend/assets/{index-Cq30cQcP.js → index-DZzbmg3J.js} +1 -1
  120. langflow/frontend/assets/{index-BZCt_UnJ.js → index-DasrI03Y.js} +1 -1
  121. langflow/frontend/assets/index-DdzVmJHE.js +1 -0
  122. langflow/frontend/assets/{index-DmvjdU1N.js → index-DhzEUXfr.js} +1 -1
  123. langflow/frontend/assets/{index-B_ytx_iA.js → index-DpJiH-Rk.js} +1 -1
  124. langflow/frontend/assets/{index-Cyk3aCmP.js → index-DpQKtcXu.js} +1 -1
  125. langflow/frontend/assets/{index-DrvRK4_i.js → index-Dpz3oBf5.js} +1 -1
  126. langflow/frontend/assets/{index-DF0oWRdd.js → index-DqSH4x-R.js} +1 -1
  127. langflow/frontend/assets/{index-DX_InNVT.js → index-DtJyCbzF.js} +1 -1
  128. langflow/frontend/assets/{index-B4AtFbkN.js → index-Du9aJK7m.js} +1 -1
  129. langflow/frontend/assets/{index-qXcoVIRo.js → index-DuAeoC-H.js} +1 -1
  130. langflow/frontend/assets/{index-D7Vx6mgS.js → index-DxIs8VSp.js} +1 -1
  131. langflow/frontend/assets/{index-U7J1YiWE.js → index-DyJDHm2D.js} +1 -1
  132. langflow/frontend/assets/{index-1MEYR1La.js → index-DzeIsaBm.js} +1 -1
  133. langflow/frontend/assets/{index-Cbwk3f-p.js → index-DztLFiip.js} +1 -1
  134. langflow/frontend/assets/{index-C_2G2ZqJ.js → index-GODbXlHC.js} +1 -1
  135. langflow/frontend/assets/{index-2vQdFIK_.js → index-G_U_kPAd.js} +1 -1
  136. langflow/frontend/assets/{index-DS4F_Phe.js → index-IFGgPiye.js} +1 -1
  137. langflow/frontend/assets/{index-5hW8VleF.js → index-LrMzDsq9.js} +1 -1
  138. langflow/frontend/assets/{index-L7FKc9QN.js → index-R7q8cAek.js} +1 -1
  139. langflow/frontend/assets/{index-BRE8A4Q_.js → index-Uq2ij_SS.js} +1 -1
  140. langflow/frontend/assets/{index-Bn4HAVDG.js → index-VHmUHUUU.js} +1 -1
  141. langflow/frontend/assets/{index-VO-pk-Hg.js → index-VZnN0P6C.js} +1 -1
  142. langflow/frontend/assets/{index-Dy7ehgeV.js → index-VcXZzovW.js} +1 -1
  143. langflow/frontend/assets/{index-DNS4La1f.js → index-Ym6gz0T6.js} +1 -1
  144. langflow/frontend/assets/{index-UI2ws3qp.js → index-ci4XHjbJ.js} +176 -176
  145. langflow/frontend/assets/{index-DlMAYATX.js → index-dkS0ek2S.js} +1 -1
  146. langflow/frontend/assets/{index-Dc0p1Oxl.js → index-hOkEW3JP.js} +1 -1
  147. langflow/frontend/assets/{index-KnS52ylc.js → index-js8ceOaP.js} +1 -1
  148. langflow/frontend/assets/{index-DtCsjX48.js → index-lKEJpUsF.js} +1 -1
  149. langflow/frontend/assets/{index-BO4fl1uU.js → index-mBjJYD9q.js} +1 -1
  150. langflow/frontend/assets/{index-C_K6Tof7.js → index-r1LZg-PY.js} +1 -1
  151. langflow/frontend/assets/index-rcdQpNcU.js +1 -0
  152. langflow/frontend/assets/{index-_3qag0I4.js → index-sS6XLk3j.js} +1 -1
  153. langflow/frontend/assets/{index-C6P0vvSP.js → index-tOy_uloT.js} +1 -1
  154. langflow/frontend/assets/lazyIconImports-Bh1TFfvH.js +2 -0
  155. langflow/frontend/assets/{use-post-add-user-Bt6vZvvT.js → use-post-add-user-HN0rRnhv.js} +1 -1
  156. langflow/frontend/index.html +1 -1
  157. langflow/initial_setup/starter_projects/Knowledge Ingestion.json +2 -2
  158. langflow/initial_setup/starter_projects/News Aggregator.json +19 -2
  159. langflow/initial_setup/starter_projects/Nvidia Remix.json +19 -2
  160. langflow/interface/initialize/loading.py +3 -1
  161. langflow/main.py +19 -2
  162. langflow/services/database/models/file/model.py +4 -2
  163. langflow/services/database/service.py +3 -1
  164. langflow/services/telemetry/schema.py +7 -0
  165. langflow/services/telemetry/service.py +25 -0
  166. langflow/services/tracing/service.py +14 -4
  167. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/METADATA +1 -1
  168. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/RECORD +170 -152
  169. langflow/frontend/assets/lazyIconImports-kvf_Kak2.js +0 -2
  170. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/WHEEL +0 -0
  171. {langflow_base_nightly-0.5.0.dev33.dist-info → langflow_base_nightly-0.5.0.dev35.dist-info}/entry_points.txt +0 -0
@@ -1,406 +1,38 @@
1
- import json
2
- from typing import Any
3
-
4
- from composio import Action
5
-
6
1
  from langflow.base.composio.composio_base import ComposioBaseComponent
7
- from langflow.inputs.inputs import (
8
- BoolInput,
9
- FileInput,
10
- IntInput,
11
- MessageTextInput,
12
- )
13
- from langflow.logging import logger
14
2
 
15
3
 
16
4
  class ComposioGmailAPIComponent(ComposioBaseComponent):
17
- """Gmail API component for interacting with Gmail services."""
18
-
19
5
  display_name: str = "Gmail"
20
- name = "GmailAPI"
21
6
  icon = "Google"
22
7
  documentation: str = "https://docs.composio.dev"
23
8
  app_name = "gmail"
24
9
 
25
- # Gmail-specific actions
26
- _actions_data: dict = {
27
- "GMAIL_SEND_EMAIL": {
28
- "display_name": "Send Email",
29
- "action_fields": [
30
- "recipient_email",
31
- "subject",
32
- "body",
33
- "cc",
34
- "bcc",
35
- "is_html",
36
- "gmail_user_id",
37
- "attachment",
38
- ],
39
- },
40
- "GMAIL_FETCH_EMAILS": {
41
- "display_name": "Fetch Emails",
42
- "action_fields": [
43
- "gmail_user_id",
44
- "max_results",
45
- "query",
46
- "page_token",
47
- "label_ids",
48
- "include_spam_trash",
49
- ],
50
- "get_result_field": True,
51
- "result_field": "messages",
52
- },
53
- "GMAIL_GET_PROFILE": {
54
- "display_name": "Get User Profile",
55
- "action_fields": ["gmail_user_id"],
56
- },
57
- "GMAIL_FETCH_MESSAGE_BY_MESSAGE_ID": {
58
- "display_name": "Get Email By ID",
59
- "action_fields": ["message_id", "gmail_user_id", "format"],
60
- "get_result_field": False,
61
- },
62
- "GMAIL_CREATE_EMAIL_DRAFT": {
63
- "display_name": "Create Draft Email",
64
- "action_fields": [
65
- "recipient_email",
66
- "subject",
67
- "body",
68
- "cc",
69
- "bcc",
70
- "is_html",
71
- "attachment",
72
- "gmail_user_id",
73
- ],
74
- },
75
- "GMAIL_FETCH_MESSAGE_BY_THREAD_ID": {
76
- "display_name": "Get Message By Thread ID",
77
- "action_fields": ["thread_id", "page_token", "gmail_user_id"],
78
- "get_result_field": False,
79
- },
80
- "GMAIL_LIST_THREADS": {
81
- "display_name": "List Email Threads",
82
- "action_fields": ["max_results", "query", "gmail_user_id", "page_token"],
83
- "get_result_field": True,
84
- "result_field": "threads",
85
- },
86
- "GMAIL_REPLY_TO_THREAD": {
87
- "display_name": "Reply To Thread",
88
- "action_fields": ["thread_id", "message_body", "recipient_email", "gmail_user_id", "cc", "bcc", "is_html"],
89
- },
90
- "GMAIL_LIST_LABELS": {
91
- "display_name": "List Email Labels",
92
- "action_fields": ["gmail_user_id"],
93
- "get_result_field": True,
94
- "result_field": "labels",
95
- },
96
- "GMAIL_CREATE_LABEL": {
97
- "display_name": "Create Email Label",
98
- "action_fields": ["label_name", "label_list_visibility", "message_list_visibility", "gmail_user_id"],
99
- },
100
- "GMAIL_GET_PEOPLE": {
101
- "display_name": "Get Contacts",
102
- "action_fields": ["resource_name", "person_fields"],
103
- "get_result_field": True,
104
- "result_field": "people_data",
105
- },
106
- "GMAIL_REMOVE_LABEL": {
107
- "display_name": "Delete Email Label",
108
- "action_fields": ["label_id", "gmail_user_id"],
109
- "get_result_field": False,
110
- },
111
- "GMAIL_GET_ATTACHMENT": {
112
- "display_name": "Get Attachment",
113
- "action_fields": ["message_id", "attachment_id", "file_name", "gmail_user_id"],
114
- },
115
- }
116
- _all_fields = {field for action_data in _actions_data.values() for field in action_data["action_fields"]}
117
- _bool_variables = {"is_html", "include_spam_trash"}
118
-
119
- # Combine base inputs with Gmail-specific inputs
120
- inputs = [
121
- *ComposioBaseComponent._base_inputs,
122
- # Email composition fields
123
- MessageTextInput(
124
- name="recipient_email",
125
- display_name="Recipient Email",
126
- info="Email address of the recipient",
127
- show=False,
128
- required=True,
129
- advanced=False,
130
- ),
131
- MessageTextInput(
132
- name="subject",
133
- display_name="Subject",
134
- info="Subject of the email",
135
- show=False,
136
- required=True,
137
- advanced=False,
138
- ),
139
- MessageTextInput(
140
- name="body",
141
- display_name="Body",
142
- required=True,
143
- info="Content of the email",
144
- show=False,
145
- advanced=False,
146
- ),
147
- MessageTextInput(
148
- name="cc",
149
- display_name="CC",
150
- info="Email addresses to CC (Carbon Copy) in the email, separated by commas",
151
- show=False,
152
- advanced=True,
153
- ),
154
- MessageTextInput(
155
- name="bcc",
156
- display_name="BCC",
157
- info="Email addresses to BCC (Blind Carbon Copy) in the email, separated by commas",
158
- show=False,
159
- advanced=True,
160
- ),
161
- BoolInput(
162
- name="is_html",
163
- display_name="Is HTML",
164
- info="Specify whether the email body contains HTML content (true/false)",
165
- show=False,
166
- value=False,
167
- advanced=True,
168
- ),
169
- # Email retrieval and management fields
170
- MessageTextInput(
171
- name="gmail_user_id",
172
- display_name="User ID",
173
- info="The user's email address or 'me' for the authenticated user",
174
- show=False,
175
- advanced=True,
176
- ),
177
- IntInput(
178
- name="max_results",
179
- display_name="Max Results",
180
- required=True,
181
- info="Maximum number of emails to be returned",
182
- show=False,
183
- advanced=False,
184
- ),
185
- MessageTextInput(
186
- name="message_id",
187
- display_name="Message ID",
188
- info="The ID of the specific email message",
189
- show=False,
190
- required=True,
191
- advanced=False,
192
- ),
193
- MessageTextInput(
194
- name="thread_id",
195
- display_name="Thread ID",
196
- info="The ID of the email thread",
197
- show=False,
198
- required=True,
199
- advanced=False,
200
- ),
201
- MessageTextInput(
202
- name="query",
203
- display_name="Query",
204
- info="Search query to filter emails (e.g., 'from:someone@email.com' or 'subject:hello')",
205
- show=False,
206
- advanced=False,
207
- ),
208
- MessageTextInput(
209
- name="message_body",
210
- display_name="Message Body",
211
- info="The body content of the message to be sent",
212
- show=False,
213
- advanced=True,
214
- ),
215
- # Label management fields
216
- MessageTextInput(
217
- name="label_name",
218
- display_name="Label Name",
219
- info="Name of the Gmail label to create, modify, or filter by",
220
- show=False,
221
- required=True,
222
- advanced=False,
223
- ),
224
- MessageTextInput(
225
- name="label_id",
226
- display_name="Label ID",
227
- info="The ID of the Gmail label",
228
- show=False,
229
- advanced=False,
230
- ),
231
- MessageTextInput(
232
- name="label_ids",
233
- display_name="Label Ids",
234
- info="Comma-separated list of label IDs to filter messages",
235
- show=False,
236
- advanced=True,
237
- ),
238
- MessageTextInput(
239
- name="label_list_visibility",
240
- display_name="Label List Visibility",
241
- info="The visibility of the label in the label list in the Gmail web interface",
242
- show=False,
243
- advanced=True,
244
- ),
245
- MessageTextInput(
246
- name="message_list_visibility",
247
- display_name="Message List Visibility",
248
- info="The visibility of the label in the message list in the Gmail web interface",
249
- show=False,
250
- advanced=True,
251
- ),
252
- # Pagination and filtering
253
- MessageTextInput(
254
- name="page_token",
255
- display_name="Page Token",
256
- info="Token for retrieving the next page of results",
257
- show=False,
258
- advanced=True,
259
- ),
260
- BoolInput(
261
- name="include_spam_trash",
262
- display_name="Include messages from Spam/Trash",
263
- info="Include messages from SPAM and TRASH in the results",
264
- show=False,
265
- value=False,
266
- advanced=True,
267
- ),
268
- MessageTextInput(
269
- name="format",
270
- display_name="Format",
271
- info="The format to return the message in. Possible values: minimal, full, raw, metadata",
272
- show=False,
273
- advanced=True,
274
- ),
275
- # Contact management fields
276
- MessageTextInput(
277
- name="resource_name",
278
- display_name="Resource Name",
279
- info="The resource name of the person to provide information about",
280
- show=False,
281
- advanced=True,
282
- ),
283
- MessageTextInput(
284
- name="person_fields",
285
- display_name="Person fields",
286
- info="Fields to return for the person. Multiple fields can be specified by separating them with commas",
287
- show=False,
288
- advanced=True,
289
- ),
290
- # Attachment handling
291
- MessageTextInput(
292
- name="attachment_id",
293
- display_name="Attachment ID",
294
- info="Id of the attachment",
295
- show=False,
296
- required=True,
297
- advanced=False,
298
- ),
299
- MessageTextInput(
300
- name="file_name",
301
- display_name="File name",
302
- info="File name of the attachment file",
303
- show=False,
304
- required=True,
305
- advanced=False,
306
- ),
307
- FileInput(
308
- name="attachment",
309
- display_name="Add Attachment",
310
- file_types=[
311
- "csv",
312
- "txt",
313
- "doc",
314
- "docx",
315
- "xls",
316
- "xlsx",
317
- "pdf",
318
- "png",
319
- "jpg",
320
- "jpeg",
321
- "gif",
322
- "zip",
323
- "rar",
324
- "ppt",
325
- "pptx",
326
- ],
327
- info="Add an attachment",
328
- show=False,
329
- ),
330
- ]
331
-
332
- def execute_action(self):
333
- """Execute action and return response as Message."""
334
- toolset = self._build_wrapper()
335
-
336
- try:
337
- self._build_action_maps()
338
- # Get the display name from the action list
339
- display_name = self.action[0]["name"] if isinstance(self.action, list) and self.action else self.action
340
- # Use the display_to_key_map to get the action key
341
- action_key = self._display_to_key_map.get(display_name)
342
- if not action_key:
343
- msg = f"Invalid action: {display_name}"
344
- raise ValueError(msg)
345
-
346
- enum_name = getattr(Action, action_key)
347
- params = {}
348
- if action_key in self._actions_data:
349
- for field in self._actions_data[action_key]["action_fields"]:
350
- value = getattr(self, field)
351
-
352
- if value is None or value == "":
353
- continue
354
-
355
- if field in ["cc", "bcc", "label_ids"] and value:
356
- value = [item.strip() for item in value.split(",")]
357
-
358
- if field in self._bool_variables:
359
- value = bool(value)
360
-
361
- params[field] = value
362
-
363
- if params.get("gmail_user_id"):
364
- params["user_id"] = params.pop("gmail_user_id")
365
-
366
- result = toolset.execute_action(
367
- action=enum_name,
368
- params=params,
369
- )
370
- if not result.get("successful"):
371
- message_str = result.get("data", {}).get("message", "{}")
372
- try:
373
- error_data = json.loads(message_str).get("error", {})
374
- except json.JSONDecodeError:
375
- error_data = {"error": "Failed to get exact error details"}
376
- return {
377
- "code": error_data.get("code"),
378
- "message": error_data.get("message"),
379
- "errors": error_data.get("errors", []),
380
- "status": error_data.get("status"),
381
- }
382
-
383
- result_data = result.get("data", {})
384
- actions_data = self._actions_data.get(action_key, {})
385
- # If 'get_result_field' is True and 'result_field' is specified, extract the data
386
- # using 'result_field'. Otherwise, fall back to the entire 'data' field in the response.
387
- if actions_data.get("get_result_field") and actions_data.get("result_field"):
388
- result_data = result_data.get(actions_data.get("result_field"), result.get("data", []))
389
- if len(result_data) != 1 and not actions_data.get("result_field") and actions_data.get("get_result_field"):
390
- msg = f"Expected a dict with a single key, got {len(result_data)} keys: {result_data.keys()}"
391
- raise ValueError(msg)
392
- return result_data # noqa: TRY300
393
- except Exception as e:
394
- logger.error(f"Error executing action: {e}")
395
- display_name = self.action[0]["name"] if isinstance(self.action, list) and self.action else str(self.action)
396
- msg = f"Failed to execute {display_name}: {e!s}"
397
- raise ValueError(msg) from e
10
+ def __init__(self, **kwargs):
11
+ super().__init__(**kwargs)
12
+ self.post_processors = {
13
+ "GMAIL_SEND_EMAIL": self._process_send_email_response,
14
+ "GMAIL_FETCH_EMAILS": self._process_fetch_emails_response,
15
+ }
398
16
 
399
- def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None) -> dict:
400
- return super().update_build_config(build_config, field_value, field_name)
17
+ def _process_send_email_response(self, raw_data):
18
+ """Post-processor for GMAIL_SEND_EMAIL action."""
19
+ if isinstance(raw_data, dict):
20
+ response_data = raw_data.get("response_data", raw_data)
21
+
22
+ return {
23
+ "message_id": response_data.get("id"),
24
+ "thread_id": response_data.get("threadId"),
25
+ "label_ids": response_data.get("labelIds", []),
26
+ }
27
+ return raw_data
28
+
29
+ def _process_fetch_emails_response(self, raw_data):
30
+ """Post-processor for GMAIL_FETCH_EMAILS action."""
31
+ if isinstance(raw_data, dict):
32
+ messages = raw_data.get("messages", [])
33
+ if messages:
34
+ return messages
35
+ return raw_data
401
36
 
402
37
  def set_default_tools(self):
403
- self._default_tools = {
404
- "GMAIL_SEND_EMAIL",
405
- "GMAIL_FETCH_EMAILS",
406
- }
38
+ """Set the default tools for Gmail component."""