alita-sdk 0.3.201__py3-none-any.whl → 0.3.202__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.
@@ -1283,7 +1283,7 @@ class PostmanApiWrapper(BaseToolApiWrapper):
1283
1283
  self.analyzer.remove_item_ids(collection_data.get("item", []))
1284
1284
 
1285
1285
  response = self._make_request(
1286
- 'POST', '/collections', json={"collection": collection_data})
1286
+ 'POST', f'/collections?workspace={self.workspace_id}', json={"collection": collection_data})
1287
1287
  return json.dumps(response, indent=2)
1288
1288
  except Exception as e:
1289
1289
  stacktrace = format_exc()
@@ -25,6 +25,7 @@ def get_tools(tool):
25
25
 
26
26
  class SlackToolkit(BaseToolkit):
27
27
  tools: List[BaseTool] = []
28
+ toolkit_max_length: int = 0
28
29
 
29
30
  @staticmethod
30
31
  def toolkit_config_schema() -> BaseModel:
@@ -52,7 +53,7 @@ class SlackToolkit(BaseToolkit):
52
53
  'configuration_title': True})),
53
54
  slack_token=(SecretStr, Field(description="Slack Token like XOXB-*****-*****-*****-*****",
54
55
  json_schema_extra={'secret': True, 'configuration': True})),
55
- channel_id=(str, Field(description="Channel ID", json_schema_extra={'configuration': True})),
56
+ channel_id=(Optional[str], Field(default=None, description="Channel ID", json_schema_extra={'configuration': True})),
56
57
  selected_tools=(List[Literal[tuple(selected_tools)]],
57
58
  Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
58
59
  __config__={'json_schema_extra': {'metadata': {"label": "Slack", "icon_url": "slack-icon.svg"}}}
@@ -74,7 +75,7 @@ class SlackToolkit(BaseToolkit):
74
75
  tools.append(BaseAction(
75
76
  api_wrapper=slack_api_wrapper,
76
77
  name=prefix + tool["name"],
77
- description=tool["description"],
78
+ description=f"Slack Tool: {tool['description']}",
78
79
  args_schema=tool["args_schema"],
79
80
  ))
80
81
  return cls(tools=tools)
@@ -10,12 +10,14 @@ from alita_sdk.tools.elitea_base import BaseToolApiWrapper
10
10
  logger = logging.getLogger(__name__)
11
11
 
12
12
  SendMessageModel = create_model(
13
- "SendMessageModel",
13
+ "SendMessageModel",
14
+ channel_id=(Optional[str], Field(default=None,description="Channel ID, user ID, or conversation ID to send the message to. (like C12345678 for public channels, D12345678 for DMs)")),
14
15
  message=(str, Field(description="The message text to send."))
15
16
  )
16
17
 
17
18
  ReadMessagesModel = create_model(
18
- "ReadMessagesModel",
19
+ "ReadMessagesModel",
20
+ channel_id=(Optional[str], Field(default=None,description="Channel ID, user ID, or conversation ID to read messages from. (like C12345678 for public channels, D12345678 for DMs)")),
19
21
  limit=(int, Field(default=10, description="The number of messages to fetch (default is 10)."))
20
22
  )
21
23
 
@@ -25,11 +27,27 @@ CreateChannelModel = create_model(
25
27
  is_private=(bool, Field(default=False, description="Whether to make the channel private (default: False)."))
26
28
  )
27
29
 
28
- ListUsersModel = create_model(
29
- "ListUsersModel"
30
+ ListChannelUsersModel = create_model(
31
+ "ListChannelUsersModel",
32
+ channel_id=(Optional[str], Field(default=None,description="Channel ID, user ID, or conversation ID to read messages from. (like C12345678 for public channels, D12345678 for DMs)"))
33
+ )
34
+
35
+ ListWorkspaceUsersModel = create_model(
36
+ "ListWorkspaceUsersModel"
37
+ )
38
+
39
+ ListWorkspaceConversationsModel = create_model(
40
+ "ListWorkspaceConversationsModel"
41
+ )
42
+
43
+ InviteToConversationModel = create_model(
44
+ "InviteToConversationModel" ,
45
+ channel_id=(Optional[str], Field(default=None,description="Conversation ID of the channel.")),
46
+ user_ids=(list[str], Field(description="List of user IDs to invite."))
30
47
  )
31
48
 
32
49
 
50
+
33
51
  class SlackApiWrapper(BaseToolApiWrapper):
34
52
 
35
53
  """
@@ -46,28 +64,34 @@ class SlackApiWrapper(BaseToolApiWrapper):
46
64
  logger.error("Slack token is required for authentication.")
47
65
  raise ValueError("Slack token is required for authentication.")
48
66
  return values
67
+
68
+
49
69
  def _get_client(self):
50
70
  if not hasattr(self, "_client") or self._client is None:
51
71
  self._client = WebClient(token=self.slack_token.get_secret_value())
52
72
  return self._client
53
73
 
54
- def send_message(self, message: str):
74
+ def send_message(self, message: str, channel_id: Optional[str] = None):
55
75
  """
56
76
  Sends a message to a specified Slack channel, user, or conversation.
77
+ Uses the provided channel_id if given, otherwise falls back to the instance's channel_id.
57
78
  """
58
79
 
59
80
  try:
60
81
 
61
82
  client = self._get_client()
62
- response = client.chat_postMessage(channel=self.channel_id, text=message)
63
- logger.info(f"Message sent to {self.channel_id}: {message}")
64
- return f"Message sent successfully to {self.channel_id}."
83
+
84
+ # Use the passed channel_id if provided, else use self.channel_id
85
+ channel = channel_id if channel_id else self.channel_id
86
+ response = client.chat_postMessage(channel=channel, text=message)
87
+ logger.info(f"Message sent to {channel}: {message}")
88
+ return f"Message sent successfully to {channel}."
65
89
 
66
90
  except SlackApiError as e:
67
- logger.error(f"Failed to send message to {self.channel_id}: {e.response['error']}")
91
+ logger.error(f"Failed to send message to {channel}: {e.response['error']}")
68
92
  return f"Received the error : {e.response['error']}"
69
93
 
70
- def read_messages(self, limit=10):
94
+ def read_messages(self, limit=10, channel_id: Optional[str] = None):
71
95
  """
72
96
  Reads the latest messages from a Slack channel or conversation.
73
97
 
@@ -78,9 +102,11 @@ class SlackApiWrapper(BaseToolApiWrapper):
78
102
 
79
103
  client = self._get_client()
80
104
  logger.info(f"auth test: {client.auth_test()}")
105
+ # Use the passed channel_id if provided, else use self.channel_id
106
+ channel = channel_id if channel_id else self.channel_id
81
107
  # Fetch conversation history
82
108
  response = client.conversations_history(
83
- channel=self.channel_id,
109
+ channel=channel,
84
110
  limit=limit )
85
111
 
86
112
  # Extract messages from the response
@@ -90,7 +116,7 @@ class SlackApiWrapper(BaseToolApiWrapper):
90
116
 
91
117
  except SlackApiError as e:
92
118
  # Handle errors from the Slack API
93
- logger.error(f"Failed to read message from {self.channel_id}: {e.response['error']}")
119
+ logger.error(f"Failed to read message from {channel}: {e.response['error']}")
94
120
  return f"Received the error : {e.response['error']}"
95
121
 
96
122
  def create_slack_channel(self, channel_name: str, is_private=False):
@@ -116,25 +142,91 @@ class SlackApiWrapper(BaseToolApiWrapper):
116
142
  print(f"Failed to create channel '{channel_name}': {error_message}")
117
143
  return {"success": False, "error": error_message}
118
144
 
119
- def list_users(self):
145
+
146
+
147
+ def list_channel_users(self, channel_id: Optional[str] = None):
120
148
  """
121
- Lists all users in the Slack workspace.
149
+ Lists all users in the specified Slack channel.
122
150
 
123
- :return: list: List of users with their IDs and names.
151
+ :param channel_id: Optional[str]: The channel ID to list users from. If not provided, uses self.channel_id.
152
+ :return: list: List of user dictionaries with their IDs and names.
124
153
  """
125
-
126
-
127
154
  try:
128
155
  client = self._get_client()
129
- print(client.auth_test())
130
- response = client.users_list()
131
- users = response["members"]
132
- return [{"id": user["id"], "name": user["name"]} for user in users if not user["is_bot"]]
133
-
156
+ # Use the passed channel_id if provided, else use self.channel_id
157
+ channel = channel_id if channel_id else self.channel_id
158
+ logger.info
159
+ if not channel:
160
+ logger.error("No channel_id provided to list_channel_users.")
161
+ return "Error: channel_id must be provided either as an argument or set on the instance."
162
+
163
+ # Get user IDs in the channel
164
+ members_response = client.conversations_members(channel=channel)
165
+ user_ids = members_response.get("members", [])
166
+
167
+ # Fetch user info for each user ID
168
+ users = []
169
+ for user_id in user_ids:
170
+ user_info = client.users_info(user=user_id)
171
+ user = user_info.get("user", {})
172
+ users.append({"id": user.get("id"), "name": user.get("name")})
173
+
174
+ return users
175
+
134
176
  except SlackApiError as e:
135
- logger.error(f"Failed to list users: {e.response['error']}")
177
+ logger.error(f"Failed to list users in channel {channel}: {e.response['error']}")
136
178
  return f"Received the error : {e.response['error']}"
179
+
180
+ def list_workspace_users(self):
181
+ """
182
+ Fetches and returns a list of all users in the Slack workspace with selected user details.
183
+
184
+ :return: list: List of user dictionaries containing id, name, is_bot, email, and team.
185
+ """
186
+ try:
187
+ client = self._get_client()
188
+ response = client.users_list() # Fetch users
189
+ members = self.extract_required_user_fields(response.get('members', []))
190
+ print(f"Found {len(members)} users.")
191
+ return members # Return the list of users
192
+ except SlackApiError as e:
193
+ print(f"Error fetching users: {e.response['error']}")
194
+ return []
137
195
 
196
+ def list_workspace_conversations(self):
197
+ """
198
+ Retrieves and returns a list of all conversations (channels, groups, and direct messages) in the Slack workspace.
199
+
200
+ :return: list: List of conversation/channel dictionaries as returned by the Slack API.
201
+ """
202
+ try:
203
+ client = self._get_client()
204
+ response = client.conversations_list() # Fetch conversations
205
+ channels = response.get("channels", [])
206
+ print(f"Found {len(channels)} channels.")
207
+ return channels # Return the list of channels
208
+ except SlackApiError as e:
209
+ print(f"Error fetching conversations: {e.response['error']}")
210
+ return []
211
+
212
+ def invite_to_conversation(self, user_ids: list, channel_id: Optional[str] = None ):
213
+ """
214
+ Invite one or more users to a Slack channel.
215
+ :param client: Slack WebClient instance.
216
+ :param channel_id: Conversation ID of the channel.
217
+ :param user_ids: List of user IDs to invite.
218
+ """
219
+ try:
220
+ client = self._get_client()
221
+ # Use the passed channel_id if provided, else use self.channel_id
222
+ channel = channel_id if channel_id else self.channel_id
223
+ response = client.conversations_invite(channel=channel, users=",".join(user_ids))
224
+ print(f"Successfully invited users to {channel}.")
225
+ return response
226
+ except SlackApiError as e:
227
+ print(f"Error inviting users: {e.response['error']}")
228
+ return None
229
+
138
230
  def extract_slack_messages(self, data):
139
231
  extracted_info = []
140
232
 
@@ -150,7 +242,20 @@ class SlackApiWrapper(BaseToolApiWrapper):
150
242
  extracted_info.append({"user": user, "message": message, "app_name": app_name})
151
243
 
152
244
  return extracted_info
153
-
245
+
246
+ # Function to extract required user details
247
+ def extract_required_user_fields(self, user_details):
248
+ extracted_user_data = []
249
+ for entry in user_details:
250
+ extracted_entry = {
251
+ "id": entry.get("id", None),
252
+ "name": entry.get("name", None),
253
+ "is_bot": entry.get("is_bot", None),
254
+ "email": entry.get("profile", {}).get("email", None),
255
+ "team": entry.get("profile", {}).get("team", None)
256
+ }
257
+ extracted_user_data.append(extracted_entry)
258
+ return extracted_user_data
154
259
 
155
260
  def get_available_tools(self):
156
261
  return [
@@ -163,21 +268,34 @@ class SlackApiWrapper(BaseToolApiWrapper):
163
268
  },
164
269
  {
165
270
  "name": "read_messages",
166
- "description": self.read_messages.__doc__ or "Send a message to a Slack channel, user, or conversation.",
271
+ "description": self.read_messages.__doc__ or "Read a message from a Slack channel, user, or conversation.",
167
272
  "args_schema": ReadMessagesModel,
168
273
  "ref": self.read_messages
169
274
  },
170
275
  {
171
- "name": "create_channel",
172
- "description": self.create_slack_channel.__doc__ or "Send a message to a Slack channel, user, or conversation.",
276
+ "name": "create_slack_channel",
277
+ "description": self.create_slack_channel.__doc__ or "Create a Slack channel",
173
278
  "args_schema": CreateChannelModel,
174
279
  "ref": self.create_slack_channel
175
280
  },
176
281
  {
177
- "name": "list_users",
178
- "description": self.list_users.__doc__ or "List all users in the Slack workspace.",
179
- "args_schema": ListUsersModel,
180
- "ref": self.list_users
282
+ "name": "list_channel_users",
283
+ "description": self.list_channel_users.__doc__ or "List all users in the Slack channel.",
284
+ "args_schema": ListChannelUsersModel,
285
+ "ref": self.list_channel_users
286
+ },
287
+ {
288
+ "name": "list_workspace_users",
289
+ "description": self.list_workspace_users.__doc__ or "List all users in the Slack workspace.",
290
+ "args_schema": ListWorkspaceUsersModel,
291
+ "ref": self.list_workspace_users
292
+ }
293
+ ,
294
+ {
295
+ "name": "invite_to_conversation",
296
+ "description": self.invite_to_conversation.__doc__ or "Invite to a conversation in the Slack workspace.",
297
+ "args_schema": InviteToConversationModel,
298
+ "ref": self.invite_to_conversation
181
299
  }
182
300
 
183
301
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.201
3
+ Version: 0.3.202
4
4
  Summary: SDK for building langchain agents using resources from Alita
5
5
  Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedjik@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -248,7 +248,7 @@ alita_sdk/tools/pandas/statsmodels/descriptive.py,sha256=APdofBnEiRhMrn6tLKwH076
248
248
  alita_sdk/tools/pandas/statsmodels/hypothesis_testing.py,sha256=fdNAayMB3W7avMfKJCcbf2_P54vUXbq8KVebOB48348,10508
249
249
  alita_sdk/tools/pandas/statsmodels/regression.py,sha256=Y1pWK4u_qzrfA740K-FX0nZ5FREGGPk8mfvykPIYoiI,9164
250
250
  alita_sdk/tools/postman/__init__.py,sha256=FzVZvqbTrA08mdoHVs0GZH1HcXDTtiMMWmSK07Bdvlc,4766
251
- alita_sdk/tools/postman/api_wrapper.py,sha256=K7Vq06DX7uMeuhpnc3EQfYvc4szY0_ElrRf9P4FLlfk,93501
251
+ alita_sdk/tools/postman/api_wrapper.py,sha256=7IgbaKfk8Wtvo0-3Wl0DpbiQOU_h00lCEmNo4J3uG2g,93532
252
252
  alita_sdk/tools/postman/postman_analysis.py,sha256=2d-Oi2UORosIePIUyncSONw9hY7dw8Zc7BQvCd4aqpg,45115
253
253
  alita_sdk/tools/pptx/__init__.py,sha256=vVUrWnj7KWJgEk9oxGSsCAQ2SMSXrp_SFOdUHYQKcAo,3444
254
254
  alita_sdk/tools/pptx/pptx_wrapper.py,sha256=yyCYcTlIY976kJ4VfPo4dyxj4yeii9j9TWP6W8ZIpN8,29195
@@ -270,8 +270,8 @@ alita_sdk/tools/sharepoint/__init__.py,sha256=HqKQDFboab1AYh20uJvHxs9HFLJSqVfVTj
270
270
  alita_sdk/tools/sharepoint/api_wrapper.py,sha256=qCHCIH4FRDtgdpIK22ewFhZJeOaTv9hT9BVivslxxlE,7119
271
271
  alita_sdk/tools/sharepoint/authorization_helper.py,sha256=n-nL5dlBoLMK70nHu7P2RYCb8C6c9HMA_gEaw8LxuhE,2007
272
272
  alita_sdk/tools/sharepoint/utils.py,sha256=fZ1YzAu5CTjKSZeslowpOPH974902S8vCp1Wu7L44LM,446
273
- alita_sdk/tools/slack/__init__.py,sha256=bMuSoJYCkMzaZuMMktRtI7wPwrO5r07FN5PyR0nTys4,3821
274
- alita_sdk/tools/slack/api_wrapper.py,sha256=dkMcS3xozEhoJ-A1ycEn6OqbIftxmVHjyYttTy3D2JI,7343
273
+ alita_sdk/tools/slack/__init__.py,sha256=mbP2JiHybGSAH0ay8pxvPCqeU2eb9CK_NaCKG1uhPE4,3894
274
+ alita_sdk/tools/slack/api_wrapper.py,sha256=EsfxhQHFhfji7hanxbDzTMbEFQnBnipyCDuu_AZgGJ8,13291
275
275
  alita_sdk/tools/sql/__init__.py,sha256=9Lh8YHKO8zD5eeolpR4O9swTUsjpXj9LVDn8fM-T5IM,3506
276
276
  alita_sdk/tools/sql/api_wrapper.py,sha256=Rky0_CX9HWDQ2mClHGAgP3LHjYVX4iymPuilZMtaDlQ,3687
277
277
  alita_sdk/tools/sql/models.py,sha256=AKJgSl_kEEz4fZfw3kbvdGHXaRZ-yiaqfJOB6YOj3i0,641
@@ -297,8 +297,8 @@ alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=UHVQUVqcBc3SZvDfO78HSuBzwAsRw
297
297
  alita_sdk/tools/zephyr_squad/__init__.py,sha256=0AI_j27xVO5Gk5HQMFrqPTd4uvuVTpiZUicBrdfEpKg,2796
298
298
  alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=kmw_xol8YIYFplBLWTqP_VKPRhL_1ItDD0_vXTe_UuI,14906
299
299
  alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=R371waHsms4sllHCbijKYs90C-9Yu0sSR3N4SUfQOgU,5066
300
- alita_sdk-0.3.201.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
301
- alita_sdk-0.3.201.dist-info/METADATA,sha256=RFOFTi8B3D4RaQKwv-N029Joo0gLd406t0hXhe03dkI,18804
302
- alita_sdk-0.3.201.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
303
- alita_sdk-0.3.201.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
304
- alita_sdk-0.3.201.dist-info/RECORD,,
300
+ alita_sdk-0.3.202.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
301
+ alita_sdk-0.3.202.dist-info/METADATA,sha256=0c34jEtau84xdrHseyu4ZiBrj2u71UZDTV6mBSdms3Q,18804
302
+ alita_sdk-0.3.202.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
303
+ alita_sdk-0.3.202.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
304
+ alita_sdk-0.3.202.dist-info/RECORD,,