alita-sdk 0.3.203__py3-none-any.whl → 0.3.205__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.
- alita_sdk/runtime/clients/client.py +3 -3
- alita_sdk/runtime/tools/vectorstore.py +143 -13
- alita_sdk/tools/__init__.py +2 -0
- alita_sdk/tools/aws/__init__.py +7 -0
- alita_sdk/tools/aws/delta_lake/__init__.py +136 -0
- alita_sdk/tools/aws/delta_lake/api_wrapper.py +220 -0
- alita_sdk/tools/aws/delta_lake/schemas.py +20 -0
- alita_sdk/tools/aws/delta_lake/tool.py +35 -0
- alita_sdk/tools/elitea_base.py +49 -4
- alita_sdk/tools/google/__init__.py +7 -0
- alita_sdk/tools/google/bigquery/__init__.py +154 -0
- alita_sdk/tools/google/bigquery/api_wrapper.py +502 -0
- alita_sdk/tools/google/bigquery/schemas.py +102 -0
- alita_sdk/tools/google/bigquery/tool.py +34 -0
- alita_sdk/tools/postman/api_wrapper.py +15 -8
- alita_sdk/tools/sharepoint/api_wrapper.py +60 -4
- alita_sdk/tools/testrail/__init__.py +9 -1
- alita_sdk/tools/testrail/api_wrapper.py +132 -6
- alita_sdk/tools/zephyr_scale/api_wrapper.py +271 -22
- {alita_sdk-0.3.203.dist-info → alita_sdk-0.3.205.dist-info}/METADATA +3 -1
- {alita_sdk-0.3.203.dist-info → alita_sdk-0.3.205.dist-info}/RECORD +24 -14
- {alita_sdk-0.3.203.dist-info → alita_sdk-0.3.205.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.203.dist-info → alita_sdk-0.3.205.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.203.dist-info → alita_sdk-0.3.205.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
import logging
|
3
|
+
import re
|
3
4
|
from typing import Any, Optional, List, Dict, Tuple, Union
|
4
5
|
|
5
6
|
from pydantic import model_validator, BaseModel, SecretStr
|
@@ -7,7 +8,12 @@ from langchain_core.tools import ToolException
|
|
7
8
|
from pydantic import create_model, PrivateAttr
|
8
9
|
from pydantic.fields import Field
|
9
10
|
|
10
|
-
from ..elitea_base import
|
11
|
+
from ..elitea_base import BaseVectorStoreToolApiWrapper, BaseIndexParams, extend_with_vector_tools
|
12
|
+
from langchain_core.documents import Document
|
13
|
+
try:
|
14
|
+
from alita_sdk.runtime.langchain.interfaces.llm_processor import get_embeddings
|
15
|
+
except ImportError:
|
16
|
+
from alita_sdk.langchain.interfaces.llm_processor import get_embeddings
|
11
17
|
|
12
18
|
logger = logging.getLogger(__name__)
|
13
19
|
|
@@ -164,7 +170,7 @@ ZephyrCreateTestScript = create_model(
|
|
164
170
|
|
165
171
|
ZephyrSearchTestCases = create_model(
|
166
172
|
"ZephyrSearchTestCases",
|
167
|
-
|
173
|
+
project_key=(str, Field(description="Jira project key filter")),
|
168
174
|
search_term=(Optional[str], Field(description="Optional search term to filter test cases", default=None)),
|
169
175
|
max_results=(Optional[int], Field(description="Maximum number of results to query from the API", default=1000)),
|
170
176
|
start_at=(Optional[int], Field(description="Zero-indexed starting position", default=0)),
|
@@ -242,8 +248,37 @@ ZephyrUpdateTestSteps = create_model(
|
|
242
248
|
steps_updates=(str, Field(description="JSON string representing the test steps to update. Format: [{\"index\": 0, \"description\": \"Updated step description\", \"testData\": \"Updated test data\", \"expectedResult\": \"Updated expected result\"}]"))
|
243
249
|
)
|
244
250
|
|
251
|
+
# Schema for indexing Zephyr scale data into vector store
|
252
|
+
indexData = create_model(
|
253
|
+
"indexData",
|
254
|
+
__base__=BaseIndexParams,
|
255
|
+
project_key=(str, Field(description="Jira project key filter")),
|
256
|
+
jql=(str, Field(description="""JQL-like query for searching test cases.
|
257
|
+
|
258
|
+
Supported fields:
|
259
|
+
- folder: exact folder name (e.g., folder = "Login Tests")
|
260
|
+
- folderPath: full folder path (e.g., folderPath = "Root/Subfolder")
|
261
|
+
- label: one or more labels (e.g., label in ("Smoke", "Critical"))
|
262
|
+
- text: full-text search in name/description (e.g., text ~ "login")
|
263
|
+
- customFields: JSON string with key-value pairs to filter by custom fields
|
264
|
+
- steps: search within test steps (e.g., steps ~ "click submit")
|
265
|
+
- orderBy: sort field (e.g., orderBy = "name")
|
266
|
+
- orderDirection: ASC or DESC (e.g., orderDirection = "DESC")
|
267
|
+
- limit: maximum number of results (e.g., limit = 100)
|
268
|
+
- includeSubfolders: whether to include subfolders (e.g., includeSubfolders = false)
|
269
|
+
- exactFolderMatch: match folder name exactly (e.g., exactFolderMatch = true)
|
270
|
+
|
271
|
+
Example:
|
272
|
+
'folder = "Authentication" AND label in ("Smoke", "Critical") AND text ~ "login" AND orderBy = "name" AND orderDirection = "ASC"'
|
273
|
+
""")),
|
274
|
+
progress_step=(Optional[int], Field(default=None, ge=0, le=100,
|
275
|
+
description="Optional step size for progress reporting during indexing")),
|
276
|
+
clean_index=(Optional[bool], Field(default=False,
|
277
|
+
description="Optional flag to enforce clean existing index before indexing new data")),
|
278
|
+
)
|
245
279
|
|
246
|
-
|
280
|
+
|
281
|
+
class ZephyrScaleApiWrapper(BaseVectorStoreToolApiWrapper):
|
247
282
|
# url for a Zephyr server
|
248
283
|
base_url: Optional[str] = ""
|
249
284
|
# auth with Jira token (cloud & server)
|
@@ -260,6 +295,14 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
260
295
|
_is_cloud: bool = False
|
261
296
|
_api: Any = PrivateAttr()
|
262
297
|
|
298
|
+
llm: Any = None
|
299
|
+
|
300
|
+
connection_string: Optional[SecretStr] = None
|
301
|
+
collection_name: Optional[str] = None
|
302
|
+
embedding_model: Optional[str] = "HuggingFaceEmbeddings"
|
303
|
+
embedding_model_params: Optional[Dict[str, Any]] = {"model_name": "sentence-transformers/all-MiniLM-L6-v2"}
|
304
|
+
vectorstore_type: Optional[str] = "PGVector"
|
305
|
+
|
263
306
|
class Config:
|
264
307
|
arbitrary_types_allowed = True
|
265
308
|
|
@@ -342,6 +385,8 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
342
385
|
try:
|
343
386
|
test_case_steps = self._api.test_cases.get_test_steps(test_case_key, **kwargs)
|
344
387
|
steps_list = [str(step) for step in test_case_steps]
|
388
|
+
if kwargs['return_list']:
|
389
|
+
return steps_list
|
345
390
|
all_steps_concatenated = '\n'.join(steps_list)
|
346
391
|
except Exception as e:
|
347
392
|
return ToolException(f"Unable to extract test case steps from test case with key: {test_case_key}:\n{str(e)}")
|
@@ -403,7 +448,8 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
403
448
|
maxResults: Optional[int] = 10,
|
404
449
|
startAt: Optional[int] = 0,
|
405
450
|
projectKey: Optional[str] = None,
|
406
|
-
folderType: Optional[str] = None
|
451
|
+
folderType: Optional[str] = None,
|
452
|
+
return_as_list: bool = False
|
407
453
|
):
|
408
454
|
"""Retrieves all folders. Query parameters can be used to filter the results: maxResults, startAt, projectKey, folderType"""
|
409
455
|
|
@@ -411,7 +457,7 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
411
457
|
for folder in self._api.folders.get_folders(maxResults=maxResults, startAt=startAt,
|
412
458
|
projectKey=projectKey, folderType=folderType):
|
413
459
|
folders_str.append(folder)
|
414
|
-
return f"Extracted folders: {folders_str}"
|
460
|
+
return folders_str if return_as_list else f"Extracted folders: {folders_str}"
|
415
461
|
|
416
462
|
def update_test_case(self, test_case_key: str, test_case_id: int, name: str, project_id: int, priority_id: int, status_id: int, **kwargs) -> str:
|
417
463
|
"""Updates an existing test case.
|
@@ -452,7 +498,7 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
452
498
|
except Exception as e:
|
453
499
|
return ToolException(f"Unable to update test case with key: {test_case_key}:\n{str(e)}")
|
454
500
|
|
455
|
-
def get_links(self, test_case_key: str) -> str:
|
501
|
+
def get_links(self, test_case_key: str, **kwargs) -> str:
|
456
502
|
"""Returns links for a test case with specified key
|
457
503
|
|
458
504
|
Args:
|
@@ -461,6 +507,8 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
461
507
|
|
462
508
|
try:
|
463
509
|
links = self._api.test_cases.get_links(test_case_key)
|
510
|
+
if kwargs['return_only_links']:
|
511
|
+
return links
|
464
512
|
return f"Links for test case `{test_case_key}`: {str(links)}"
|
465
513
|
except Exception as e:
|
466
514
|
return ToolException(f"Unable to get links for test case with key: {test_case_key}:\n{str(e)}")
|
@@ -495,8 +543,32 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
495
543
|
return f"Web link created for test case `{test_case_key}` with URL `{url}`: {str(web_link_response)}"
|
496
544
|
except Exception as e:
|
497
545
|
return ToolException(f"Unable to create web link for test case with key: {test_case_key}:\n{str(e)}")
|
498
|
-
|
499
|
-
def
|
546
|
+
|
547
|
+
def _get_last_version(self, test_case_key: str, step:int = 10):
|
548
|
+
max_iterations = 50
|
549
|
+
count = 0
|
550
|
+
start_at = 0
|
551
|
+
last_version = None
|
552
|
+
|
553
|
+
while count < max_iterations:
|
554
|
+
count+=1
|
555
|
+
last_versions = self.get_versions(test_case_key=test_case_key, maxResults=step, startAt=start_at, return_as_list=True)
|
556
|
+
last_versions_count = len(last_versions)
|
557
|
+
|
558
|
+
if last_versions_count == 0:
|
559
|
+
break
|
560
|
+
|
561
|
+
last_version = last_versions[-1]
|
562
|
+
start_at+=last_versions_count
|
563
|
+
|
564
|
+
if last_version:
|
565
|
+
match = re.search(r'/versions/(\d+)', last_version["self"])
|
566
|
+
version_number = match.group(1)
|
567
|
+
return self.get_version(test_case_key=test_case_key, version=version_number, return_as_object=True)
|
568
|
+
return None
|
569
|
+
|
570
|
+
|
571
|
+
def get_versions(self, test_case_key: str, maxResults: Optional[int] = 10, startAt: Optional[int] = 0, return_as_list: bool = False) -> str|list:
|
500
572
|
"""Returns all test case versions for a test case with specified key. Response is ordered by most recent first.
|
501
573
|
|
502
574
|
Args:
|
@@ -507,26 +579,30 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
507
579
|
|
508
580
|
try:
|
509
581
|
versions = self._api.test_cases.get_versions(test_case_key, maxResults=maxResults, startAt=startAt)
|
582
|
+
if return_as_list:
|
583
|
+
return [version for version in versions]
|
510
584
|
versions_list = [str(version) for version in versions]
|
511
585
|
all_versions = '\n'.join(versions_list)
|
512
586
|
return f"Versions for test case `{test_case_key}`: {all_versions}"
|
513
587
|
except Exception as e:
|
514
588
|
return ToolException(f"Unable to get versions for test case with key: {test_case_key}:\n{str(e)}")
|
515
589
|
|
516
|
-
def get_version(self, test_case_key: str, version: str) -> str:
|
590
|
+
def get_version(self, test_case_key: str, version: str, return_as_object: bool = False) -> str|dict:
|
517
591
|
"""Retrieves a specific version of a test case"""
|
518
592
|
|
519
593
|
try:
|
520
594
|
version_data = self._api.test_cases.get_version(test_case_key, version)
|
521
|
-
return f"Version {version} of test case `{test_case_key}`: {str(version_data)}"
|
595
|
+
return version_data if return_as_object else f"Version {version} of test case `{test_case_key}`: {str(version_data)}"
|
522
596
|
except Exception as e:
|
523
597
|
return ToolException(f"Unable to get version {version} for test case with key: {test_case_key}:\n{str(e)}")
|
524
598
|
|
525
|
-
def get_test_script(self, test_case_key: str) -> str:
|
599
|
+
def get_test_script(self, test_case_key: str, return_only_script:bool = False) -> str:
|
526
600
|
"""Returns the test script for the given test case"""
|
527
601
|
|
528
602
|
try:
|
529
603
|
test_script = self._api.test_cases.get_test_script(test_case_key)
|
604
|
+
if return_only_script:
|
605
|
+
return test_script
|
530
606
|
return f"Test script for test case `{test_case_key}`: {str(test_script)}"
|
531
607
|
except Exception as e:
|
532
608
|
return ToolException(f"Unable to get test script for test case with key: {test_case_key}:\n{str(e)}")
|
@@ -949,7 +1025,7 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
949
1025
|
|
950
1026
|
return result_cases, message
|
951
1027
|
|
952
|
-
def search_test_cases(self,
|
1028
|
+
def search_test_cases(self, project_key: str, search_term: Optional[str] = None,
|
953
1029
|
max_results: Optional[int] = 1000, start_at: Optional[int] = 0,
|
954
1030
|
order_by: Optional[str] = "name", order_direction: Optional[str] = "ASC",
|
955
1031
|
archived: Optional[bool] = False, fields: Optional[List[str]] = ["key", "name"],
|
@@ -957,7 +1033,8 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
957
1033
|
folder_name: Optional[str] = None, exact_folder_match: Optional[bool] = False,
|
958
1034
|
folder_path: Optional[str] = None, include_subfolders: Optional[bool] = True,
|
959
1035
|
labels: Optional[List[str]] = None, custom_fields: Optional[str] = None,
|
960
|
-
steps_search: Optional[str] = None, include_steps: Optional[bool] = False
|
1036
|
+
steps_search: Optional[str] = None, include_steps: Optional[bool] = False,
|
1037
|
+
return_raw: bool = False) -> Union[str, List[dict]]:
|
961
1038
|
"""Searches for test cases using custom search API.
|
962
1039
|
|
963
1040
|
Args:
|
@@ -987,7 +1064,7 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
987
1064
|
# If we have folder_name or folder_path, we need to get folders and build the folder hierarchy
|
988
1065
|
if folder_name or folder_path:
|
989
1066
|
# Get all folders in the project
|
990
|
-
all_folders = self._get_folders(
|
1067
|
+
all_folders = self._get_folders(project_key, "TEST_CASE", 1000)
|
991
1068
|
|
992
1069
|
# Build folder hierarchy
|
993
1070
|
folder_hierarchy = self._build_folder_hierarchy(all_folders)
|
@@ -1014,7 +1091,7 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
1014
1091
|
|
1015
1092
|
# Prepare parameters for the API call
|
1016
1093
|
params = {
|
1017
|
-
"projectKey":
|
1094
|
+
"projectKey": project_key,
|
1018
1095
|
"maxResults": max_results,
|
1019
1096
|
"startAt": start_at
|
1020
1097
|
}
|
@@ -1040,7 +1117,7 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
1040
1117
|
# If we have multiple target folder IDs, get test cases from each folder
|
1041
1118
|
if target_folder_ids and include_subfolders:
|
1042
1119
|
all_test_cases = self._get_test_cases_from_folders(
|
1043
|
-
|
1120
|
+
project_key, target_folder_ids, max_results, start_at, params
|
1044
1121
|
)
|
1045
1122
|
else:
|
1046
1123
|
# Just use the standard params (which might include a single folder_id)
|
@@ -1077,14 +1154,179 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
1077
1154
|
"custom fields": custom_fields,
|
1078
1155
|
"steps containing": steps_search
|
1079
1156
|
}
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
return
|
1084
|
-
|
1157
|
+
|
1158
|
+
if return_raw:
|
1159
|
+
return filtered_cases
|
1160
|
+
return self._finalize_test_case_results(filtered_cases, fields, search_criteria)
|
1161
|
+
|
1085
1162
|
except Exception as e:
|
1086
1163
|
return ToolException(f"Error searching test cases: {str(e)}")
|
1087
1164
|
|
1165
|
+
def _finalize_test_case_results(self, filtered_cases: List[dict], fields: List[str], search_criteria: dict) -> str:
|
1166
|
+
result_cases, message = self._format_test_case_results(filtered_cases, fields, search_criteria)
|
1167
|
+
return f"{message}: {json.dumps(result_cases, indent=2)}"
|
1168
|
+
|
1169
|
+
def _search_test_cases_by_jql(self, project_key: str, jql: str):
|
1170
|
+
try:
|
1171
|
+
parsed = self._parse_jql(jql)
|
1172
|
+
|
1173
|
+
return self.search_test_cases(
|
1174
|
+
project_key=project_key,
|
1175
|
+
search_term=parsed.get("text"),
|
1176
|
+
order_by=parsed.get("orderBy", "name"),
|
1177
|
+
order_direction=parsed.get("orderDirection", "ASC"),
|
1178
|
+
limit_results=parsed.get("limit"),
|
1179
|
+
folder_name=parsed.get("folder"),
|
1180
|
+
folder_path=parsed.get("folderPath"),
|
1181
|
+
exact_folder_match=parsed.get("exactFolderMatch", False),
|
1182
|
+
include_subfolders=parsed.get("includeSubfolders", True),
|
1183
|
+
labels=parsed.get("label"),
|
1184
|
+
custom_fields=parsed.get("customFields"),
|
1185
|
+
steps_search=parsed.get("steps"),
|
1186
|
+
include_steps=True,
|
1187
|
+
return_raw=True
|
1188
|
+
)
|
1189
|
+
except Exception as e:
|
1190
|
+
return ToolException(f"Error searching test cases by JQL: {str(e)}")
|
1191
|
+
|
1192
|
+
def _parse_jql(self, jql: str) -> dict:
|
1193
|
+
import re
|
1194
|
+
result = {}
|
1195
|
+
|
1196
|
+
# Match string equality: field = "value"
|
1197
|
+
for match in re.findall(r'(\w+)\s*=\s*"([^"]*)"', jql):
|
1198
|
+
result[match[0]] = match[1]
|
1199
|
+
|
1200
|
+
# Match text search: field ~ "value"
|
1201
|
+
for match in re.findall(r'(\w+)\s*~\s*"([^"]*)"', jql):
|
1202
|
+
result[match[0]] = match[1]
|
1203
|
+
|
1204
|
+
# Match list: field in ("a", "b", ...)
|
1205
|
+
for match in re.findall(r'(\w+)\s*in\s*\(\s*([^)]+?)\s*\)', jql):
|
1206
|
+
values = [v.strip().strip('"') for v in match[1].split(",")]
|
1207
|
+
result[match[0]] = values
|
1208
|
+
|
1209
|
+
# Match number/bool: field = 123 or field = true/false
|
1210
|
+
for match in re.findall(r'(\w+)\s*=\s*([^\s"()]+)', jql):
|
1211
|
+
key, raw_val = match
|
1212
|
+
if key in result:
|
1213
|
+
continue
|
1214
|
+
if raw_val.lower() == "true":
|
1215
|
+
result[key] = True
|
1216
|
+
elif raw_val.lower() == "false":
|
1217
|
+
result[key] = False
|
1218
|
+
elif raw_val.isdigit():
|
1219
|
+
result[key] = int(raw_val)
|
1220
|
+
else:
|
1221
|
+
try:
|
1222
|
+
result[key] = float(raw_val)
|
1223
|
+
except ValueError:
|
1224
|
+
result[key] = raw_val
|
1225
|
+
|
1226
|
+
return result
|
1227
|
+
|
1228
|
+
def index_data(self, project_key: str,
|
1229
|
+
jql: str,
|
1230
|
+
collection_suffix: str = '',
|
1231
|
+
progress_step: int = None,
|
1232
|
+
clean_index: bool = False) -> str:
|
1233
|
+
"""
|
1234
|
+
Search test cases using a JQL-like query with explicit project_key.
|
1235
|
+
|
1236
|
+
Example:
|
1237
|
+
jql = 'folder = "Authentication" AND label in ("Smoke", "Critical") AND text ~ "login"'
|
1238
|
+
"""
|
1239
|
+
docs = self._base_loader(project_key, jql)
|
1240
|
+
embedding = get_embeddings(self.embedding_model, self.embedding_model_params)
|
1241
|
+
vs = self._init_vector_store(collection_suffix, embeddings=embedding)
|
1242
|
+
return vs.index_documents(docs, progress_step=progress_step, clean_index=clean_index)
|
1243
|
+
|
1244
|
+
def _base_loader(self, project_key: str, jql: str):
|
1245
|
+
test_cases_docs = self._get_test_cases_docs(project_key, jql)
|
1246
|
+
folders_docs = self._get_folders_docs(project_key)
|
1247
|
+
return test_cases_docs + folders_docs
|
1248
|
+
|
1249
|
+
def _get_all_folders(self, project_key: str, folder_type:str, step: int = 10):
|
1250
|
+
max_iterations = 50
|
1251
|
+
count = 0
|
1252
|
+
all_folders = []
|
1253
|
+
start_at = 0
|
1254
|
+
while count < max_iterations:
|
1255
|
+
count+=1
|
1256
|
+
new_folders = self.get_folders(projectKey=project_key, folderType=folder_type, maxResults=step, startAt=start_at, return_as_list=True)
|
1257
|
+
|
1258
|
+
if new_folders and len(new_folders) > 0:
|
1259
|
+
all_folders.extend(new_folders)
|
1260
|
+
start_at+=step
|
1261
|
+
else:
|
1262
|
+
break
|
1263
|
+
return all_folders
|
1264
|
+
|
1265
|
+
def _get_folders_docs(self, project_key: str):
|
1266
|
+
folder_types = ['TEST_CASE', 'TEST_PLAN', 'TEST_CYCLE']
|
1267
|
+
folders = []
|
1268
|
+
for folder_type in folder_types:
|
1269
|
+
try:
|
1270
|
+
folders.extend(self._get_all_folders(project_key, folder_type=folder_type, step=100))
|
1271
|
+
except Exception as e:
|
1272
|
+
raise ToolException(f"Unable to extract folders for folder type '{folder_type}': {e}")
|
1273
|
+
page_content = {}
|
1274
|
+
docs: List[Document] = []
|
1275
|
+
for folder in folders:
|
1276
|
+
page_content['name'] = folder['name']
|
1277
|
+
metadata = {}
|
1278
|
+
for key, value in folder.items():
|
1279
|
+
if value is not None:
|
1280
|
+
metadata[key] = value
|
1281
|
+
page_content['type'] = "FOLDER"
|
1282
|
+
docs.append(Document(page_content=json.dumps(page_content), metadata=metadata))
|
1283
|
+
return docs
|
1284
|
+
|
1285
|
+
def _get_test_cases_docs(self, project_key: str, jql: str):
|
1286
|
+
try:
|
1287
|
+
test_cases = self._search_test_cases_by_jql(project_key, jql)
|
1288
|
+
except Exception as e:
|
1289
|
+
raise ToolException(f"Unable to extract test cases: {e}")
|
1290
|
+
|
1291
|
+
docs: List[Document] = []
|
1292
|
+
for case in test_cases:
|
1293
|
+
last_version = self._get_last_version(case['key'], step=100)
|
1294
|
+
metadata = {
|
1295
|
+
k: v for k, v in case.items()
|
1296
|
+
if isinstance(v, (str, int, float, bool, list, dict))
|
1297
|
+
}
|
1298
|
+
if last_version and isinstance(last_version, dict) and 'createdOn' in last_version:
|
1299
|
+
metadata['updated_at'] = last_version['createdOn']
|
1300
|
+
else:
|
1301
|
+
metadata['updated_at'] = case['createdOn']
|
1302
|
+
|
1303
|
+
case['type'] = "TEST_CASE"
|
1304
|
+
|
1305
|
+
docs.append(Document(page_content=json.dumps(case), metadata=metadata))
|
1306
|
+
return docs
|
1307
|
+
|
1308
|
+
def _process_document(self, document: Document) -> Document:
|
1309
|
+
try:
|
1310
|
+
base_data = json.loads(document.page_content)
|
1311
|
+
|
1312
|
+
if base_data['type'] and base_data['type'] == "TEST_CASE":
|
1313
|
+
additional_content = self._process_test_case(base_data)
|
1314
|
+
base_data['test_case_content'] = additional_content
|
1315
|
+
|
1316
|
+
document.page_content = json.dumps(base_data)
|
1317
|
+
return document
|
1318
|
+
except json.JSONDecodeError as e:
|
1319
|
+
raise ToolException(f"Failed to decode JSON from document: {e}")
|
1320
|
+
|
1321
|
+
def _process_test_case(self, case):
|
1322
|
+
steps = self.get_test_steps(case['key'], return_list=True)
|
1323
|
+
script = self.get_test_script(case['key'], return_only_script=True)
|
1324
|
+
additional_content = {
|
1325
|
+
"steps": "" if isinstance(steps, ToolException) else steps,
|
1326
|
+
"script": "" if isinstance(script, ToolException) else script,
|
1327
|
+
}
|
1328
|
+
return additional_content
|
1329
|
+
|
1088
1330
|
def get_tests_recursive(self, project_key: str = None, folder_id: str = None, maxResults: Optional[int] = 100, startAt: Optional[int] = 0):
|
1089
1331
|
"""Retrieves all test cases recursively from a folder and all its subfolders.
|
1090
1332
|
|
@@ -1341,7 +1583,8 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
1341
1583
|
return f"Test steps updated for test case `{test_case_key}`: {len(updates)} step(s) modified"
|
1342
1584
|
except Exception as e:
|
1343
1585
|
return ToolException(f"Error updating test steps for test case {test_case_key}: {str(e)}")
|
1344
|
-
|
1586
|
+
|
1587
|
+
@extend_with_vector_tools
|
1345
1588
|
def get_available_tools(self):
|
1346
1589
|
return [
|
1347
1590
|
{
|
@@ -1463,5 +1706,11 @@ class ZephyrScaleApiWrapper(BaseToolApiWrapper):
|
|
1463
1706
|
"description": self.get_tests_by_folder_path.__doc__,
|
1464
1707
|
"args_schema": ZephyrGetTestsByFolderPath,
|
1465
1708
|
"ref": self.get_tests_by_folder_path,
|
1709
|
+
},
|
1710
|
+
{
|
1711
|
+
"name": "index_data",
|
1712
|
+
"ref": self.index_data,
|
1713
|
+
"description": self.index_data.__doc__,
|
1714
|
+
"args_schema": indexData,
|
1466
1715
|
}
|
1467
1716
|
]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: alita_sdk
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.205
|
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
|
@@ -125,6 +125,8 @@ Requires-Dist: yarl==1.17.1; extra == "tools"
|
|
125
125
|
Requires-Dist: langmem==0.0.27; extra == "tools"
|
126
126
|
Requires-Dist: textract-py3==2.1.1; extra == "tools"
|
127
127
|
Requires-Dist: slack_sdk==3.35.0; extra == "tools"
|
128
|
+
Requires-Dist: deltalake==1.0.2; extra == "tools"
|
129
|
+
Requires-Dist: google_cloud_bigquery==3.34.0; extra == "tools"
|
128
130
|
Provides-Extra: community
|
129
131
|
Requires-Dist: retry-extended==0.2.3; extra == "community"
|
130
132
|
Requires-Dist: pyobjtojson==0.3; extra == "community"
|
@@ -13,7 +13,7 @@ alita_sdk/community/analysis/jira_analyse/api_wrapper.py,sha256=Ui1GBWizIFGFOi98
|
|
13
13
|
alita_sdk/runtime/__init__.py,sha256=4W0UF-nl3QF2bvET5lnah4o24CoTwSoKXhuN0YnwvEE,828
|
14
14
|
alita_sdk/runtime/clients/__init__.py,sha256=BdehU5GBztN1Qi1Wul0cqlU46FxUfMnI6Vq2Zd_oq1M,296
|
15
15
|
alita_sdk/runtime/clients/artifact.py,sha256=4N2t5x3GibyXLq3Fvrv2o_VA7Z000yNfc-UN4eGsHZg,2679
|
16
|
-
alita_sdk/runtime/clients/client.py,sha256=
|
16
|
+
alita_sdk/runtime/clients/client.py,sha256=t4KckYtjJo7JauxcCuQxOsjqPzhfqR4B8bJuVUorPiY,21674
|
17
17
|
alita_sdk/runtime/clients/datasource.py,sha256=HAZovoQN9jBg0_-lIlGBQzb4FJdczPhkHehAiVG3Wx0,1020
|
18
18
|
alita_sdk/runtime/clients/prompt.py,sha256=li1RG9eBwgNK_Qf0qUaZ8QNTmsncFrAL2pv3kbxZRZg,1447
|
19
19
|
alita_sdk/runtime/langchain/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -89,7 +89,7 @@ alita_sdk/runtime/tools/pgvector_search.py,sha256=NN2BGAnq4SsDHIhUcFZ8d_dbEOM8Qw
|
|
89
89
|
alita_sdk/runtime/tools/prompt.py,sha256=nJafb_e5aOM1Rr3qGFCR-SKziU9uCsiP2okIMs9PppM,741
|
90
90
|
alita_sdk/runtime/tools/router.py,sha256=wCvZjVkdXK9dMMeEerrgKf5M790RudH68pDortnHSz0,1517
|
91
91
|
alita_sdk/runtime/tools/tool.py,sha256=lE1hGi6qOAXG7qxtqxarD_XMQqTghdywf261DZawwno,5631
|
92
|
-
alita_sdk/runtime/tools/vectorstore.py,sha256=
|
92
|
+
alita_sdk/runtime/tools/vectorstore.py,sha256=yRx1hUyPhyLRPby-GWgOlWQ2zbY-zqYKw-an9-Jy6dQ,29743
|
93
93
|
alita_sdk/runtime/utils/AlitaCallback.py,sha256=E4LlSBuCHWiUq6W7IZExERHZY0qcmdjzc_rJlF2iQIw,7356
|
94
94
|
alita_sdk/runtime/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
95
95
|
alita_sdk/runtime/utils/constants.py,sha256=Xntx1b_uxUzT4clwqHA_U6K8y5bBqf_4lSQwXdcWrp4,13586
|
@@ -98,8 +98,8 @@ alita_sdk/runtime/utils/logging.py,sha256=svPyiW8ztDfhqHFITv5FBCj8UhLxz6hWcqGIY6
|
|
98
98
|
alita_sdk/runtime/utils/save_dataframe.py,sha256=i-E1wp-t4wb17Zq3nA3xYwgSILjoXNizaQAA9opWvxY,1576
|
99
99
|
alita_sdk/runtime/utils/streamlit.py,sha256=gRwsT4lv4kujQfNSQripMPe1ZbmjbHNLSraW3FmL-qA,85710
|
100
100
|
alita_sdk/runtime/utils/utils.py,sha256=dM8whOJAuFJFe19qJ69-FLzrUp6d2G-G6L7d4ss2XqM,346
|
101
|
-
alita_sdk/tools/__init__.py,sha256=
|
102
|
-
alita_sdk/tools/elitea_base.py,sha256=
|
101
|
+
alita_sdk/tools/__init__.py,sha256=R5KsF1aqKFsBY2SGTYvlhk7HZSNyBoos0JMgSV6QHys,10196
|
102
|
+
alita_sdk/tools/elitea_base.py,sha256=NILHGtsoWtOATGdQExtn6Svx0JwDVpmGUJsQZbGHEic,23142
|
103
103
|
alita_sdk/tools/ado/__init__.py,sha256=mD6GHcYMTtffPJkJvFPe2rzvye_IRmXmWfI7xYuZhO4,912
|
104
104
|
alita_sdk/tools/ado/utils.py,sha256=PTCludvaQmPLakF2EbCGy66Mro4-rjDtavVP-xcB2Wc,1252
|
105
105
|
alita_sdk/tools/ado/repos/__init__.py,sha256=guYY95Gtyb0S4Jj0V1qO0x2jlRoH0H1cKjHXNwmShow,6388
|
@@ -112,6 +112,11 @@ alita_sdk/tools/ado/work_item/__init__.py,sha256=k6gZ6pEE7gvNWvCDoDV05jltzbqxC_N
|
|
112
112
|
alita_sdk/tools/ado/work_item/ado_wrapper.py,sha256=aLB-aSNQST0FCwP7I01OXanCpZHKVarZZB1u9j2H1LA,26253
|
113
113
|
alita_sdk/tools/advanced_jira_mining/__init__.py,sha256=pUTzECqGvYaR5qWY3JPUhrImrZgc7pCXuqSe5eWIE80,4604
|
114
114
|
alita_sdk/tools/advanced_jira_mining/data_mining_wrapper.py,sha256=nZPtuwVWp8VeHw1B8q9kdwf-6ZvHnlXTOGdcIMDkKpw,44211
|
115
|
+
alita_sdk/tools/aws/__init__.py,sha256=tB6GCOg4XGSpR6qgbgAF4MUQ5-YmQCbWurWgrVKEKQ8,181
|
116
|
+
alita_sdk/tools/aws/delta_lake/__init__.py,sha256=aMAOw3EYV6CzIZSh3caAyLZQbKMRFg7w1X7gmAKNu60,5863
|
117
|
+
alita_sdk/tools/aws/delta_lake/api_wrapper.py,sha256=bo0MPnhIQ787RL-dIA-e2dDMzxHJ4mTpYChmkg0Z_0A,8929
|
118
|
+
alita_sdk/tools/aws/delta_lake/schemas.py,sha256=yl8yYSCY3OrapElCcDSpirM9P-H2Hi6zZyZATv6JWrc,967
|
119
|
+
alita_sdk/tools/aws/delta_lake/tool.py,sha256=xXaaKnTGdoXhvYn89TmzWaV_zn79uTibpxCsi5FS_eU,1104
|
115
120
|
alita_sdk/tools/azure_ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
116
121
|
alita_sdk/tools/azure_ai/search/__init__.py,sha256=RaaWHX9o2NMxRruQGQwsDfacvtEJ5E0brMd-8P4N__4,4682
|
117
122
|
alita_sdk/tools/azure_ai/search/api_wrapper.py,sha256=E4p6HPDlwgxfT_i6cvg9rN4Vn_47CVAyNBAKLIGq3mU,7265
|
@@ -211,6 +216,11 @@ alita_sdk/tools/gitlab_org/api_wrapper.py,sha256=WQr5HjxDV3Ry4vreIV67sHYesHmzreQ
|
|
211
216
|
alita_sdk/tools/gmail/__init__.py,sha256=RkVWqVT335tpSUEVZUWqqPYMOYnxjkPmkBKLYdkpKto,887
|
212
217
|
alita_sdk/tools/gmail/gmail_wrapper.py,sha256=t0IYM3zb77Ub8o9kv6HugNm_OoG5tN9T730hYmY8F-c,1312
|
213
218
|
alita_sdk/tools/gmail/utils.py,sha256=cu6pbSsyMIr1BQOSs9et1rbAkk-Z_u48PB9FtJwFhUs,448
|
219
|
+
alita_sdk/tools/google/__init__.py,sha256=YbDEXq3nBmWkXfqipqlPSc6kTAGTLckP8gswNfsA4jE,178
|
220
|
+
alita_sdk/tools/google/bigquery/__init__.py,sha256=yc4an81N4yab6clsCknwoncUCFg5SxQ6XUaWmAES1K0,4846
|
221
|
+
alita_sdk/tools/google/bigquery/api_wrapper.py,sha256=I8wETiA36w6odKZwb_4TA1g_5RgUr1LOZg4hOpBC5to,19683
|
222
|
+
alita_sdk/tools/google/bigquery/schemas.py,sha256=Gb8KQZSoRkmjXiz21dTC95c1MHEHFcnA0lPTqb8ZjCY,4455
|
223
|
+
alita_sdk/tools/google/bigquery/tool.py,sha256=Esf9Hsp8I0e7-5EdkFqQ-bid0cfrg-bfSoHoW_IIARo,1027
|
214
224
|
alita_sdk/tools/google_places/__init__.py,sha256=mHKc7u9P2gqGDzqqJNQC9qiZYEm5gncnM_1XjtrM17o,3152
|
215
225
|
alita_sdk/tools/google_places/api_wrapper.py,sha256=7nZly6nk4f4Tm7s2MVdnnwlb-1_WHRrDhyjDiqoyPjA,4674
|
216
226
|
alita_sdk/tools/jira/__init__.py,sha256=ZFDopVLZMw3ah2R-fRMw3fM3ImN3SL4bAc5r1kA6cCM,5894
|
@@ -248,7 +258,7 @@ alita_sdk/tools/pandas/statsmodels/descriptive.py,sha256=APdofBnEiRhMrn6tLKwH076
|
|
248
258
|
alita_sdk/tools/pandas/statsmodels/hypothesis_testing.py,sha256=fdNAayMB3W7avMfKJCcbf2_P54vUXbq8KVebOB48348,10508
|
249
259
|
alita_sdk/tools/pandas/statsmodels/regression.py,sha256=Y1pWK4u_qzrfA740K-FX0nZ5FREGGPk8mfvykPIYoiI,9164
|
250
260
|
alita_sdk/tools/postman/__init__.py,sha256=FzVZvqbTrA08mdoHVs0GZH1HcXDTtiMMWmSK07Bdvlc,4766
|
251
|
-
alita_sdk/tools/postman/api_wrapper.py,sha256=
|
261
|
+
alita_sdk/tools/postman/api_wrapper.py,sha256=oJLtOu0vHqVzRsXgJIW6kXqXyYq9jAs6QE9JG1ALmHY,94912
|
252
262
|
alita_sdk/tools/postman/postman_analysis.py,sha256=2d-Oi2UORosIePIUyncSONw9hY7dw8Zc7BQvCd4aqpg,45115
|
253
263
|
alita_sdk/tools/pptx/__init__.py,sha256=vVUrWnj7KWJgEk9oxGSsCAQ2SMSXrp_SFOdUHYQKcAo,3444
|
254
264
|
alita_sdk/tools/pptx/pptx_wrapper.py,sha256=yyCYcTlIY976kJ4VfPo4dyxj4yeii9j9TWP6W8ZIpN8,29195
|
@@ -267,7 +277,7 @@ alita_sdk/tools/servicenow/__init__.py,sha256=VHH3qpUbEJ0tdtrIiWakohCmbifUOPgCVX
|
|
267
277
|
alita_sdk/tools/servicenow/api_wrapper.py,sha256=WpH-bBLGFdhehs4g-K-WAkNuaD1CSrwsDpdgB3RG53s,6120
|
268
278
|
alita_sdk/tools/servicenow/servicenow_client.py,sha256=Rdqfu-ll-qbnclMzChLZBsfXRDzgoX_FdeI2WLApWxc,3269
|
269
279
|
alita_sdk/tools/sharepoint/__init__.py,sha256=HqKQDFboab1AYh20uJvHxs9HFLJSqVfVTjpX9sfOP-8,2995
|
270
|
-
alita_sdk/tools/sharepoint/api_wrapper.py,sha256=
|
280
|
+
alita_sdk/tools/sharepoint/api_wrapper.py,sha256=j5aArfEHqV3_M8JK_HZU_fzchjQXiAqkq83Osdx3Gls,9534
|
271
281
|
alita_sdk/tools/sharepoint/authorization_helper.py,sha256=n-nL5dlBoLMK70nHu7P2RYCb8C6c9HMA_gEaw8LxuhE,2007
|
272
282
|
alita_sdk/tools/sharepoint/utils.py,sha256=fZ1YzAu5CTjKSZeslowpOPH974902S8vCp1Wu7L44LM,446
|
273
283
|
alita_sdk/tools/slack/__init__.py,sha256=mbP2JiHybGSAH0ay8pxvPCqeU2eb9CK_NaCKG1uhPE4,3894
|
@@ -277,8 +287,8 @@ alita_sdk/tools/sql/api_wrapper.py,sha256=Rky0_CX9HWDQ2mClHGAgP3LHjYVX4iymPuilZM
|
|
277
287
|
alita_sdk/tools/sql/models.py,sha256=AKJgSl_kEEz4fZfw3kbvdGHXaRZ-yiaqfJOB6YOj3i0,641
|
278
288
|
alita_sdk/tools/testio/__init__.py,sha256=qi12wyJXN02hrUXg08CbijcCL5pi30JMbJfiXjn1Zr0,2646
|
279
289
|
alita_sdk/tools/testio/api_wrapper.py,sha256=BvmL5h634BzG6p7ajnQLmj-uoAw1gjWnd4FHHu1h--Q,21638
|
280
|
-
alita_sdk/tools/testrail/__init__.py,sha256=
|
281
|
-
alita_sdk/tools/testrail/api_wrapper.py,sha256=
|
290
|
+
alita_sdk/tools/testrail/__init__.py,sha256=YILz5ZjkHfBg1tQ-FKFBP_s0uo2WDY110Qgsg0kBntM,4157
|
291
|
+
alita_sdk/tools/testrail/api_wrapper.py,sha256=CE7oUREaLL0AXH-RF3PXORp1PrIPthR5_xnCgD6DBT4,30373
|
282
292
|
alita_sdk/tools/utils/__init__.py,sha256=155xepXPr4OEzs2Mz5YnjXcBpxSv1X2eznRUVoPtyK0,3268
|
283
293
|
alita_sdk/tools/utils/content_parser.py,sha256=cdAENBS2-KPBAVbUczsuT-YJEdouKQ0SxCU6bWFfgak,4736
|
284
294
|
alita_sdk/tools/xray/__init__.py,sha256=dn-Ine9mHF8c_yZ-pWkn-gvSvSmGwdrqxPJOz6Cmqc4,3297
|
@@ -293,12 +303,12 @@ alita_sdk/tools/zephyr_enterprise/__init__.py,sha256=y9KDJS3E3D22xc0l08AUuhmGSjS
|
|
293
303
|
alita_sdk/tools/zephyr_enterprise/api_wrapper.py,sha256=Ir3zHljhbZQJRJJQOBzS_GL5xvxb3-Vq5VF8XIMkxck,9348
|
294
304
|
alita_sdk/tools/zephyr_enterprise/zephyr_enterprise.py,sha256=hV9LIrYfJT6oYp-ZfQR0YHflqBFPsUw2Oc55HwK0H48,6809
|
295
305
|
alita_sdk/tools/zephyr_scale/__init__.py,sha256=2NTcdrfkx4GSegqyXhsPLsEpc4FlACuDy85b0fk6cAo,4572
|
296
|
-
alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=
|
306
|
+
alita_sdk/tools/zephyr_scale/api_wrapper.py,sha256=VDsSFUTnBne1mFNssX2eLFxThXAhXnXUG5W4pxD_EPI,79412
|
297
307
|
alita_sdk/tools/zephyr_squad/__init__.py,sha256=0AI_j27xVO5Gk5HQMFrqPTd4uvuVTpiZUicBrdfEpKg,2796
|
298
308
|
alita_sdk/tools/zephyr_squad/api_wrapper.py,sha256=kmw_xol8YIYFplBLWTqP_VKPRhL_1ItDD0_vXTe_UuI,14906
|
299
309
|
alita_sdk/tools/zephyr_squad/zephyr_squad_cloud_client.py,sha256=R371waHsms4sllHCbijKYs90C-9Yu0sSR3N4SUfQOgU,5066
|
300
|
-
alita_sdk-0.3.
|
301
|
-
alita_sdk-0.3.
|
302
|
-
alita_sdk-0.3.
|
303
|
-
alita_sdk-0.3.
|
304
|
-
alita_sdk-0.3.
|
310
|
+
alita_sdk-0.3.205.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
311
|
+
alita_sdk-0.3.205.dist-info/METADATA,sha256=yvmS329tNz5JkW-qID4aiG3vM2cIGDxy3loJE8u1ivM,18917
|
312
|
+
alita_sdk-0.3.205.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
313
|
+
alita_sdk-0.3.205.dist-info/top_level.txt,sha256=0vJYy5p_jK6AwVb1aqXr7Kgqgk3WDtQ6t5C-XI9zkmg,10
|
314
|
+
alita_sdk-0.3.205.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|