alita-sdk 0.3.417__py3-none-any.whl → 0.3.419__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.
@@ -143,6 +143,7 @@ class SandboxClient:
143
143
  self.configurations_url = f'{self.base_url}{self.api_path}/integrations/integrations/default/{self.project_id}?section=configurations&unsecret=true'
144
144
  self.ai_section_url = f'{self.base_url}{self.api_path}/integrations/integrations/default/{self.project_id}?section=ai'
145
145
  self.image_generation_url = f'{self.base_url}{self.llm_path}/images/generations'
146
+ self.auth_user_url = f'{self.base_url}{self.api_path}/auth/user'
146
147
  self.configurations: list = configurations or []
147
148
  self.model_timeout = kwargs.get('model_timeout', 120)
148
149
  self.model_image_generation = kwargs.get('model_image_generation')
@@ -363,3 +364,10 @@ class SandboxClient:
363
364
  url = f'{self.artifact_url}/{bucket_name}'
364
365
  data = requests.delete(url, headers=self.headers, verify=False, params={'filename': quote(artifact_name)})
365
366
  return self._process_requst(data)
367
+
368
+ def get_user_data(self) -> Dict[str, Any]:
369
+ resp = requests.get(self.auth_user_url, headers=self.headers, verify=False)
370
+ if resp.ok:
371
+ return resp.json()
372
+ logger.error(f'Failed to fetch user data: {resp.status_code} - {resp.text}')
373
+ raise ApiDetailsRequestError(f'Failed to fetch user data with status code {resp.status_code}.')
@@ -48,23 +48,24 @@ def get_tools(tools_list: list, alita_client, llm, memory_store: BaseStore = Non
48
48
  selected_tools=tool['settings']['selected_tools'],
49
49
  toolkit_name=tool.get('toolkit_name', '') or tool.get('name', '')
50
50
  ).get_tools())
51
- elif tool['type'] == 'application' and tool.get('agent_type', '') != 'pipeline' :
51
+ elif tool['type'] == 'application':
52
52
  tools.extend(ApplicationToolkit.get_toolkit(
53
53
  alita_client,
54
54
  application_id=int(tool['settings']['application_id']),
55
55
  application_version_id=int(tool['settings']['application_version_id']),
56
56
  selected_tools=[]
57
57
  ).get_tools())
58
- elif tool['type'] == 'application' and tool.get('agent_type', '') == 'pipeline':
59
- # static get_toolkit returns a list of CompiledStateGraph stubs
60
- tools.extend(SubgraphToolkit.get_toolkit(
61
- alita_client,
62
- application_id=int(tool['settings']['application_id']),
63
- application_version_id=int(tool['settings']['application_version_id']),
64
- app_api_key=alita_client.auth_token,
65
- selected_tools=[],
66
- llm=llm
67
- ))
58
+ # backward compatibility for pipeline application type as subgraph node
59
+ if tool.get('agent_type', '') == 'pipeline':
60
+ # static get_toolkit returns a list of CompiledStateGraph stubs
61
+ tools.extend(SubgraphToolkit.get_toolkit(
62
+ alita_client,
63
+ application_id=int(tool['settings']['application_id']),
64
+ application_version_id=int(tool['settings']['application_version_id']),
65
+ app_api_key=alita_client.auth_token,
66
+ selected_tools=[],
67
+ llm=llm
68
+ ))
68
69
  elif tool['type'] == 'memory':
69
70
  tools += MemoryToolkit.get_toolkit(
70
71
  namespace=tool['settings'].get('namespace', str(tool['id'])),
@@ -329,11 +329,14 @@ class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
329
329
  parsed_item.update(fields_data)
330
330
 
331
331
  # extract relations if any
332
- relations_data = work_item.relations
332
+ relations_data = None
333
+ if expand and str(expand).lower() in ("relations", "all"):
334
+ try:
335
+ relations_data = getattr(work_item, 'relations', None)
336
+ except KeyError:
337
+ relations_data = None
333
338
  if relations_data:
334
- parsed_item['relations'] = []
335
- for relation in relations_data:
336
- parsed_item['relations'].append(relation.as_dict())
339
+ parsed_item['relations'] = [relation.as_dict() for relation in relations_data]
337
340
 
338
341
  if parse_attachments:
339
342
  # describe images in work item fields if present
@@ -344,13 +347,19 @@ class AzureDevOpsApiWrapper(NonCodeIndexerToolkit):
344
347
  for img in images:
345
348
  src = img.get('src')
346
349
  if src:
347
- description = self.parse_attachment_by_url(src, image_description_prompt)
350
+ description = self.parse_attachment_by_url(src, image_description_prompt=image_description_prompt)
348
351
  img['image-description'] = description
349
352
  parsed_item[field_name] = str(soup)
350
353
  # parse attached documents if present
351
- if parsed_item['relations']:
352
- for attachment in parsed_item['relations']:
353
- attachment['content'] = self.parse_attachment_by_url(attachment['url'], attachment['attributes']['name'], image_description_prompt)
354
+ for relation in parsed_item.get('relations', []):
355
+ # Only process actual file attachments
356
+ if relation.get('rel') == 'AttachedFile':
357
+ file_name = relation.get('attributes', {}).get('name')
358
+ if file_name:
359
+ try:
360
+ relation['content'] = self.parse_attachment_by_url(relation['url'], file_name, image_description_prompt=image_description_prompt)
361
+ except Exception as att_e:
362
+ logger.warning(f"Failed to parse attachment {file_name}: {att_e}")
354
363
 
355
364
 
356
365
  return parsed_item
@@ -1,6 +1,7 @@
1
1
  import json
2
2
  import re
3
3
  import logging
4
+ import yaml
4
5
  from typing import List, Any, Optional, Dict
5
6
  from langchain_core.tools import BaseTool, BaseToolkit, ToolException
6
7
  from requests_openapi import Operation, Client, Server
@@ -101,7 +102,15 @@ class AlitaOpenAPIToolkit(BaseToolkit):
101
102
  else:
102
103
  tools_set = {}
103
104
  if isinstance(openapi_spec, str):
104
- openapi_spec = json.loads(openapi_spec)
105
+ # Try to detect if it's YAML or JSON by attempting to parse as JSON first
106
+ try:
107
+ openapi_spec = json.loads(openapi_spec)
108
+ except json.JSONDecodeError:
109
+ # If JSON parsing fails, try YAML
110
+ try:
111
+ openapi_spec = yaml.safe_load(openapi_spec)
112
+ except yaml.YAMLError as e:
113
+ raise ToolException(f"Failed to parse OpenAPI spec as JSON or YAML: {e}")
105
114
  c = Client()
106
115
  c.load_spec(openapi_spec)
107
116
  if headers:
@@ -92,15 +92,33 @@ class SharepointApiWrapper(NonCodeIndexerToolkit):
92
92
  target_list = self._client.web.lists.get_by_title(list_title)
93
93
  self._client.load(target_list)
94
94
  self._client.execute_query()
95
- items = target_list.items.get().top(limit).execute_query()
96
- logging.info("{0} items from sharepoint loaded successfully.".format(len(items)))
95
+ items = target_list.items.top(limit).get().execute_query()
96
+ logging.info("{0} items from sharepoint loaded successfully via SharePoint REST API.".format(len(items)))
97
97
  result = []
98
98
  for item in items:
99
99
  result.append(item.properties)
100
100
  return result
101
- except Exception as e:
102
- logging.error(f"Failed to load items from sharepoint: {e}")
103
- return ToolException("Can not list items. Please, double check List name and read permissions.")
101
+ except Exception as base_e:
102
+ logging.warning(f"Primary SharePoint REST list read failed: {base_e}. Attempting Graph API fallback.")
103
+ # Attempt Graph API fallback
104
+ try:
105
+ from .authorization_helper import SharepointAuthorizationHelper
106
+ auth_helper = SharepointAuthorizationHelper(
107
+ client_id=self.client_id,
108
+ client_secret=self.client_secret.get_secret_value() if self.client_secret else None,
109
+ tenant="", # optional for graph api (derived inside helper)
110
+ scope="", # optional for graph api
111
+ token_json="", # not needed for client credentials flow here
112
+ )
113
+ graph_items = auth_helper.get_list_items(self.site_url, list_title, limit)
114
+ if graph_items:
115
+ logging.info(f"{len(graph_items)} items from sharepoint loaded successfully via Graph API fallback.")
116
+ return graph_items
117
+ else:
118
+ return ToolException("List appears empty or inaccessible via both REST and Graph APIs.")
119
+ except Exception as graph_e:
120
+ logging.error(f"Graph API fallback failed: {graph_e}")
121
+ return ToolException(f"Cannot read list '{list_title}'. Check list name and permissions: {base_e} | {graph_e}")
104
122
 
105
123
 
106
124
  def get_files_list(self, folder_name: str = None, limit_files: int = 100):
@@ -185,3 +185,47 @@ class SharepointAuthorizationHelper:
185
185
  raise RuntimeError(f"File '{path}' not found in any private or shared documents.")
186
186
  except Exception as e:
187
187
  raise RuntimeError(f"Error in get_file_content: {e}")
188
+
189
+ def get_list_items(self, site_url: str, list_title: str, limit: int = 1000):
190
+ """Fallback Graph API method to read SharePoint list items by list title.
191
+
192
+ Returns a list of dictionaries representing list item fields.
193
+ """
194
+ if not site_url or not site_url.startswith("https://"):
195
+ raise ValueError(f"Invalid site_url format: {site_url}")
196
+ try:
197
+ access_token, site_id = self.generate_token_and_site_id(site_url)
198
+ headers = {"Authorization": f"Bearer {access_token}"}
199
+ lists_url = f"https://graph.microsoft.com/v1.0/sites/{site_id}/lists"
200
+ response = requests.get(lists_url, headers=headers)
201
+ if response.status_code != 200:
202
+ raise RuntimeError(f"Lists request failed: {response.status_code} {response.text}")
203
+ lists_json = response.json()
204
+ lists = lists_json.get("value", [])
205
+ target_list = None
206
+ normalized_title = list_title.strip().lower()
207
+ for lst in lists:
208
+ # displayName is the user-visible title. name can differ (internal name)
209
+ display_name = (lst.get("displayName") or lst.get("name") or '').strip().lower()
210
+ if display_name == normalized_title:
211
+ target_list = lst
212
+ break
213
+ if not target_list:
214
+ raise RuntimeError(f"List '{list_title}' not found via Graph API.")
215
+ list_id = target_list.get('id')
216
+ if not list_id:
217
+ raise RuntimeError(f"List '{list_title}' missing id field.")
218
+ items_url = f"https://graph.microsoft.com/v1.0/sites/{site_id}/lists/{list_id}/items?expand=fields&$top={limit}"
219
+ items_response = requests.get(items_url, headers=headers)
220
+ if items_response.status_code != 200:
221
+ raise RuntimeError(f"List items request failed: {items_response.status_code} {items_response.text}")
222
+ items_json = items_response.json()
223
+ values = items_json.get('value', [])
224
+ result = []
225
+ for item in values:
226
+ fields = item.get('fields', {})
227
+ if fields:
228
+ result.append(fields)
229
+ return result
230
+ except Exception as e:
231
+ raise RuntimeError(f"Error in get_list_items: {e}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.417
3
+ Version: 0.3.419
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 <lifedj27@gmail.com>, Artem Dubrovskiy <ad13box@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -39,7 +39,7 @@ alita_sdk/runtime/clients/artifact.py,sha256=b7hVuGRROt6qUcT11uAZqzJqslzmlgW-Y6o
39
39
  alita_sdk/runtime/clients/client.py,sha256=ElJdZHYLpuXLQadoHMcuhiHzs8HVUiiv5rZE7UU-iNg,45896
40
40
  alita_sdk/runtime/clients/datasource.py,sha256=HAZovoQN9jBg0_-lIlGBQzb4FJdczPhkHehAiVG3Wx0,1020
41
41
  alita_sdk/runtime/clients/prompt.py,sha256=li1RG9eBwgNK_Qf0qUaZ8QNTmsncFrAL2pv3kbxZRZg,1447
42
- alita_sdk/runtime/clients/sandbox_client.py,sha256=OhEasE0MxBBDw4o76xkxVCpNpr3xJ8spQsrsVxMrjUA,16192
42
+ alita_sdk/runtime/clients/sandbox_client.py,sha256=kGOGfm3OAFmYeTM4bIuKbhRsOiOhF0M1q8takBe-sWY,16637
43
43
  alita_sdk/runtime/langchain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
44
  alita_sdk/runtime/langchain/assistant.py,sha256=qKoEjbGuUnX-OZDHmSaK3plb1jON9unzEwAjxBT9DY8,16044
45
45
  alita_sdk/runtime/langchain/chat_message_template.py,sha256=kPz8W2BG6IMyITFDA5oeb5BxVRkHEVZhuiGl4MBZKdc,2176
@@ -102,7 +102,7 @@ alita_sdk/runtime/toolkits/configurations.py,sha256=kIDAlnryPQfbZyFxV-9SzN2-Vefz
102
102
  alita_sdk/runtime/toolkits/datasource.py,sha256=qk78OdPoReYPCWwahfkKLbKc4pfsu-061oXRryFLP6I,2498
103
103
  alita_sdk/runtime/toolkits/prompt.py,sha256=WIpTkkVYWqIqOWR_LlSWz3ug8uO9tm5jJ7aZYdiGRn0,1192
104
104
  alita_sdk/runtime/toolkits/subgraph.py,sha256=wwUK8JjPXkGzyVZ3tAukmvST6eGbqx_U11rpnmbrvtg,2105
105
- alita_sdk/runtime/toolkits/tools.py,sha256=XBbbEZOTbzt1cogu7b9mg-nluZgD5EEUuaZp5QvE9b8,10122
105
+ alita_sdk/runtime/toolkits/tools.py,sha256=vJGZtXAP-EMT6HXTeDzKd_BuH3fx3Ht_8Skp_BvI9O8,10168
106
106
  alita_sdk/runtime/toolkits/vectorstore.py,sha256=BGppQADa1ZiLO17fC0uCACTTEvPHlodEDYEzUcBRbAA,2901
107
107
  alita_sdk/runtime/tools/__init__.py,sha256=Fx7iHqkzA90-KfjdcUUzMUI_7kDarjuTsSpSzOW2pN0,568
108
108
  alita_sdk/runtime/tools/agent.py,sha256=m98QxOHwnCRTT9j18Olbb5UPS8-ZGeQaGiUyZJSyFck,3162
@@ -149,7 +149,7 @@ alita_sdk/tools/ado/test_plan/test_plan_wrapper.py,sha256=MHM1WJUUWIgOUxGPjQUhNU
149
149
  alita_sdk/tools/ado/wiki/__init__.py,sha256=ela6FOuT1fqN3FvHGBflzAh16HS1SSPsJYS2SldRX7A,5272
150
150
  alita_sdk/tools/ado/wiki/ado_wrapper.py,sha256=qqKJw755X-kgB2KkcwFECa464xLKmlKrhqKfZ5Da5Gs,18188
151
151
  alita_sdk/tools/ado/work_item/__init__.py,sha256=jml_zSkdC7gdGIoX2ZqRgDb45nhT3ZWzNsZ0II0iVJI,5474
152
- alita_sdk/tools/ado/work_item/ado_wrapper.py,sha256=LTZl9yiqjsoKdy-6zD4as3NCZg1NY1Ogp9LQbiV-IZw,30851
152
+ alita_sdk/tools/ado/work_item/ado_wrapper.py,sha256=uURYPFEj2kVa-mxgaa6duQ0RRwUQTi4yBopdmHeiMPQ,31420
153
153
  alita_sdk/tools/advanced_jira_mining/__init__.py,sha256=GdrFVsyG8h43BnQwBKUtZ_ca_0atP1rQ_0adkd9mssc,4703
154
154
  alita_sdk/tools/advanced_jira_mining/data_mining_wrapper.py,sha256=nZPtuwVWp8VeHw1B8q9kdwf-6ZvHnlXTOGdcIMDkKpw,44211
155
155
  alita_sdk/tools/aws/__init__.py,sha256=tB6GCOg4XGSpR6qgbgAF4MUQ5-YmQCbWurWgrVKEKQ8,181
@@ -277,7 +277,7 @@ alita_sdk/tools/memory/__init__.py,sha256=aOF0-PAAqBZS3rI2IOezyLhZpn-WpV--ABy4J_
277
277
  alita_sdk/tools/ocr/__init__.py,sha256=pvslKVXyJmK0q23FFDNieuc7RBIuzNXTjTNj-GqhGb0,3335
278
278
  alita_sdk/tools/ocr/api_wrapper.py,sha256=08UF8wj1sR8DcW0z16pw19bgLatLkBF8dySW-Ds8iRk,29649
279
279
  alita_sdk/tools/ocr/text_detection.py,sha256=1DBxt54r3_HdEi93QynSIVta3rH3UpIvy799TPtDTtk,23825
280
- alita_sdk/tools/openapi/__init__.py,sha256=x1U4SGApL6MmNFz9SSsQCv352wMAIdGv0z4eMmYnjCw,4984
280
+ alita_sdk/tools/openapi/__init__.py,sha256=a3eE1zL2InB_bnngKhFoQlR-B4voywqs3s9mEbWypCE,5417
281
281
  alita_sdk/tools/pandas/__init__.py,sha256=rGenKJH5b9__qM4GerpyLT5YEhNk7W1gA7gn6Zpew04,2748
282
282
  alita_sdk/tools/pandas/api_wrapper.py,sha256=wn0bagB45Tz_kN0FoKUCIxKcYklMMWTqQP5NOM8_Kwc,11100
283
283
  alita_sdk/tools/pandas/dataframe/__init__.py,sha256=iOZRlYDEtwqg2MaYFFxETjN8yHAkUqSNe86cm6ao4LA,108
@@ -317,8 +317,8 @@ alita_sdk/tools/servicenow/__init__.py,sha256=ziEt2juPrGFyB98ZXbGf25v6gZo4UJTHsz
317
317
  alita_sdk/tools/servicenow/api_wrapper.py,sha256=WpH-bBLGFdhehs4g-K-WAkNuaD1CSrwsDpdgB3RG53s,6120
318
318
  alita_sdk/tools/servicenow/servicenow_client.py,sha256=Rdqfu-ll-qbnclMzChLZBsfXRDzgoX_FdeI2WLApWxc,3269
319
319
  alita_sdk/tools/sharepoint/__init__.py,sha256=5z2iSmm-0kbHKf70wN6OOgS4Px7tOzwkIpHXz0Vrbj4,4045
320
- alita_sdk/tools/sharepoint/api_wrapper.py,sha256=QcOtgc8L10YLdSK8LwACV_vRBF7T-u7T9-W05TbuAQI,15409
321
- alita_sdk/tools/sharepoint/authorization_helper.py,sha256=QvxWFBjYZfhI1h_KkSrDbRh8D5BlFX8xWDLmlIoO4mo,9569
320
+ alita_sdk/tools/sharepoint/api_wrapper.py,sha256=yOAZfa9-GcjohTak-TqcFL8f7s18hIA89FNO0qXjb_s,16614
321
+ alita_sdk/tools/sharepoint/authorization_helper.py,sha256=GN_UkI_HOn9b5UFlxqck7sm6HuB_Kh4wCIGBYFPe2dg,11924
322
322
  alita_sdk/tools/sharepoint/utils.py,sha256=CO1PNRC5CpQaVo2Gdenj_jqm2bReSqUT92Bk5s37d8M,573
323
323
  alita_sdk/tools/slack/__init__.py,sha256=YiPAoRc6y6uVpfHl0K1Qi-flcyPlWFIMVcVbhicGWXY,3990
324
324
  alita_sdk/tools/slack/api_wrapper.py,sha256=5VrV7iSGno8ZcDzEHdGPNhInhtODGPPvAzoZ9W9iQWE,14009
@@ -353,8 +353,8 @@ alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=kT0TbmMvuKhDUZc0i7KO18O38JM9S
353
353
  alita_sdk/tools/zephyr_squad/__init__.py,sha256=0ne8XLJEQSLOWfzd2HdnqOYmQlUliKHbBED5kW_Vias,2895
354
354
  alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=kmw_xol8YIYFplBLWTqP_VKPRhL_1ItDD0_vXTe_UuI,14906
355
355
  alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=R371waHsms4sllHCbijKYs90C-9Yu0sSR3N4SUfQOgU,5066
356
- alita_sdk-0.3.417.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
357
- alita_sdk-0.3.417.dist-info/METADATA,sha256=nKqrQw7YB1U0nQcSa1ewAQZSWDGzSxeiYBZ7CpRFuIA,19071
358
- alita_sdk-0.3.417.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
359
- alita_sdk-0.3.417.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
360
- alita_sdk-0.3.417.dist-info/RECORD,,
356
+ alita_sdk-0.3.419.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
357
+ alita_sdk-0.3.419.dist-info/METADATA,sha256=Uqn7Qo3w7QK8Jntv7H1pTLRf3ZHjndnY1NADGUnPlV4,19071
358
+ alita_sdk-0.3.419.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
359
+ alita_sdk-0.3.419.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
360
+ alita_sdk-0.3.419.dist-info/RECORD,,