alita-sdk 0.3.257__py3-none-any.whl → 0.3.562__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/cli/__init__.py +10 -0
- alita_sdk/cli/__main__.py +17 -0
- alita_sdk/cli/agent/__init__.py +5 -0
- alita_sdk/cli/agent/default.py +258 -0
- alita_sdk/cli/agent_executor.py +155 -0
- alita_sdk/cli/agent_loader.py +215 -0
- alita_sdk/cli/agent_ui.py +228 -0
- alita_sdk/cli/agents.py +3601 -0
- alita_sdk/cli/callbacks.py +647 -0
- alita_sdk/cli/cli.py +168 -0
- alita_sdk/cli/config.py +306 -0
- alita_sdk/cli/context/__init__.py +30 -0
- alita_sdk/cli/context/cleanup.py +198 -0
- alita_sdk/cli/context/manager.py +731 -0
- alita_sdk/cli/context/message.py +285 -0
- alita_sdk/cli/context/strategies.py +289 -0
- alita_sdk/cli/context/token_estimation.py +127 -0
- alita_sdk/cli/formatting.py +182 -0
- alita_sdk/cli/input_handler.py +419 -0
- alita_sdk/cli/inventory.py +1073 -0
- alita_sdk/cli/mcp_loader.py +315 -0
- alita_sdk/cli/toolkit.py +327 -0
- alita_sdk/cli/toolkit_loader.py +85 -0
- alita_sdk/cli/tools/__init__.py +43 -0
- alita_sdk/cli/tools/approval.py +224 -0
- alita_sdk/cli/tools/filesystem.py +1751 -0
- alita_sdk/cli/tools/planning.py +389 -0
- alita_sdk/cli/tools/terminal.py +414 -0
- alita_sdk/community/__init__.py +72 -12
- alita_sdk/community/inventory/__init__.py +236 -0
- alita_sdk/community/inventory/config.py +257 -0
- alita_sdk/community/inventory/enrichment.py +2137 -0
- alita_sdk/community/inventory/extractors.py +1469 -0
- alita_sdk/community/inventory/ingestion.py +3172 -0
- alita_sdk/community/inventory/knowledge_graph.py +1457 -0
- alita_sdk/community/inventory/parsers/__init__.py +218 -0
- alita_sdk/community/inventory/parsers/base.py +295 -0
- alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
- alita_sdk/community/inventory/parsers/go_parser.py +851 -0
- alita_sdk/community/inventory/parsers/html_parser.py +389 -0
- alita_sdk/community/inventory/parsers/java_parser.py +593 -0
- alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
- alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
- alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
- alita_sdk/community/inventory/parsers/python_parser.py +604 -0
- alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
- alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
- alita_sdk/community/inventory/parsers/text_parser.py +322 -0
- alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
- alita_sdk/community/inventory/patterns/__init__.py +61 -0
- alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
- alita_sdk/community/inventory/patterns/loader.py +348 -0
- alita_sdk/community/inventory/patterns/registry.py +198 -0
- alita_sdk/community/inventory/presets.py +535 -0
- alita_sdk/community/inventory/retrieval.py +1403 -0
- alita_sdk/community/inventory/toolkit.py +173 -0
- alita_sdk/community/inventory/toolkit_utils.py +176 -0
- alita_sdk/community/inventory/visualize.py +1370 -0
- alita_sdk/configurations/__init__.py +11 -0
- alita_sdk/configurations/ado.py +148 -2
- alita_sdk/configurations/azure_search.py +1 -1
- alita_sdk/configurations/bigquery.py +1 -1
- alita_sdk/configurations/bitbucket.py +94 -2
- alita_sdk/configurations/browser.py +18 -0
- alita_sdk/configurations/carrier.py +19 -0
- alita_sdk/configurations/confluence.py +130 -1
- alita_sdk/configurations/delta_lake.py +1 -1
- alita_sdk/configurations/figma.py +76 -5
- alita_sdk/configurations/github.py +65 -1
- alita_sdk/configurations/gitlab.py +81 -0
- alita_sdk/configurations/google_places.py +17 -0
- alita_sdk/configurations/jira.py +103 -0
- alita_sdk/configurations/openapi.py +111 -0
- alita_sdk/configurations/postman.py +1 -1
- alita_sdk/configurations/qtest.py +72 -3
- alita_sdk/configurations/report_portal.py +115 -0
- alita_sdk/configurations/salesforce.py +19 -0
- alita_sdk/configurations/service_now.py +1 -12
- alita_sdk/configurations/sharepoint.py +167 -0
- alita_sdk/configurations/sonar.py +18 -0
- alita_sdk/configurations/sql.py +20 -0
- alita_sdk/configurations/testio.py +101 -0
- alita_sdk/configurations/testrail.py +88 -0
- alita_sdk/configurations/xray.py +94 -1
- alita_sdk/configurations/zephyr_enterprise.py +94 -1
- alita_sdk/configurations/zephyr_essential.py +95 -0
- alita_sdk/runtime/clients/artifact.py +21 -4
- alita_sdk/runtime/clients/client.py +458 -67
- alita_sdk/runtime/clients/mcp_discovery.py +342 -0
- alita_sdk/runtime/clients/mcp_manager.py +262 -0
- alita_sdk/runtime/clients/sandbox_client.py +352 -0
- alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
- alita_sdk/runtime/langchain/assistant.py +183 -43
- alita_sdk/runtime/langchain/constants.py +647 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +209 -31
- alita_sdk/runtime/langchain/document_loaders/AlitaImageLoader.py +1 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +10 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaMarkdownLoader.py +66 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaPDFLoader.py +79 -10
- alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +52 -15
- alita_sdk/runtime/langchain/document_loaders/AlitaPythonLoader.py +9 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +1 -4
- alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +15 -2
- alita_sdk/runtime/langchain/document_loaders/ImageParser.py +30 -0
- alita_sdk/runtime/langchain/document_loaders/constants.py +189 -41
- alita_sdk/runtime/langchain/interfaces/llm_processor.py +4 -2
- alita_sdk/runtime/langchain/langraph_agent.py +407 -92
- alita_sdk/runtime/langchain/utils.py +102 -8
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/models/mcp_models.py +61 -0
- alita_sdk/runtime/skills/__init__.py +91 -0
- alita_sdk/runtime/skills/callbacks.py +498 -0
- alita_sdk/runtime/skills/discovery.py +540 -0
- alita_sdk/runtime/skills/executor.py +610 -0
- alita_sdk/runtime/skills/input_builder.py +371 -0
- alita_sdk/runtime/skills/models.py +330 -0
- alita_sdk/runtime/skills/registry.py +355 -0
- alita_sdk/runtime/skills/skill_runner.py +330 -0
- alita_sdk/runtime/toolkits/__init__.py +28 -0
- alita_sdk/runtime/toolkits/application.py +14 -4
- alita_sdk/runtime/toolkits/artifact.py +24 -9
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +780 -0
- alita_sdk/runtime/toolkits/planning.py +178 -0
- alita_sdk/runtime/toolkits/skill_router.py +238 -0
- alita_sdk/runtime/toolkits/subgraph.py +11 -6
- alita_sdk/runtime/toolkits/tools.py +314 -70
- alita_sdk/runtime/toolkits/vectorstore.py +11 -5
- alita_sdk/runtime/tools/__init__.py +24 -0
- alita_sdk/runtime/tools/application.py +16 -4
- alita_sdk/runtime/tools/artifact.py +367 -33
- alita_sdk/runtime/tools/data_analysis.py +183 -0
- alita_sdk/runtime/tools/function.py +100 -4
- alita_sdk/runtime/tools/graph.py +81 -0
- alita_sdk/runtime/tools/image_generation.py +218 -0
- alita_sdk/runtime/tools/llm.py +1013 -177
- alita_sdk/runtime/tools/loop.py +3 -1
- alita_sdk/runtime/tools/loop_output.py +3 -1
- alita_sdk/runtime/tools/mcp_inspect_tool.py +284 -0
- alita_sdk/runtime/tools/mcp_remote_tool.py +181 -0
- alita_sdk/runtime/tools/mcp_server_tool.py +3 -1
- alita_sdk/runtime/tools/planning/__init__.py +36 -0
- alita_sdk/runtime/tools/planning/models.py +246 -0
- alita_sdk/runtime/tools/planning/wrapper.py +607 -0
- alita_sdk/runtime/tools/router.py +2 -1
- alita_sdk/runtime/tools/sandbox.py +375 -0
- alita_sdk/runtime/tools/skill_router.py +776 -0
- alita_sdk/runtime/tools/tool.py +3 -1
- alita_sdk/runtime/tools/vectorstore.py +69 -65
- alita_sdk/runtime/tools/vectorstore_base.py +163 -90
- alita_sdk/runtime/utils/AlitaCallback.py +137 -21
- alita_sdk/runtime/utils/mcp_client.py +492 -0
- alita_sdk/runtime/utils/mcp_oauth.py +361 -0
- alita_sdk/runtime/utils/mcp_sse_client.py +434 -0
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/streamlit.py +41 -14
- alita_sdk/runtime/utils/toolkit_utils.py +28 -9
- alita_sdk/runtime/utils/utils.py +48 -0
- alita_sdk/tools/__init__.py +135 -37
- alita_sdk/tools/ado/__init__.py +2 -2
- alita_sdk/tools/ado/repos/__init__.py +15 -19
- alita_sdk/tools/ado/repos/repos_wrapper.py +12 -20
- alita_sdk/tools/ado/test_plan/__init__.py +26 -8
- alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +56 -28
- alita_sdk/tools/ado/wiki/__init__.py +27 -12
- alita_sdk/tools/ado/wiki/ado_wrapper.py +114 -40
- alita_sdk/tools/ado/work_item/__init__.py +27 -12
- alita_sdk/tools/ado/work_item/ado_wrapper.py +95 -11
- alita_sdk/tools/advanced_jira_mining/__init__.py +12 -8
- alita_sdk/tools/aws/delta_lake/__init__.py +14 -11
- alita_sdk/tools/aws/delta_lake/tool.py +5 -1
- alita_sdk/tools/azure_ai/search/__init__.py +13 -8
- alita_sdk/tools/base/tool.py +5 -1
- alita_sdk/tools/base_indexer_toolkit.py +454 -110
- alita_sdk/tools/bitbucket/__init__.py +27 -19
- alita_sdk/tools/bitbucket/api_wrapper.py +285 -27
- alita_sdk/tools/bitbucket/cloud_api_wrapper.py +5 -5
- alita_sdk/tools/browser/__init__.py +41 -16
- alita_sdk/tools/browser/crawler.py +3 -1
- alita_sdk/tools/browser/utils.py +15 -6
- alita_sdk/tools/carrier/__init__.py +18 -17
- alita_sdk/tools/carrier/backend_reports_tool.py +8 -4
- alita_sdk/tools/carrier/excel_reporter.py +8 -4
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/code/codeparser.py +1 -1
- alita_sdk/tools/chunkers/sematic/json_chunker.py +2 -1
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
- alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
- alita_sdk/tools/chunkers/universal_chunker.py +270 -0
- alita_sdk/tools/cloud/aws/__init__.py +11 -7
- alita_sdk/tools/cloud/azure/__init__.py +11 -7
- alita_sdk/tools/cloud/gcp/__init__.py +11 -7
- alita_sdk/tools/cloud/k8s/__init__.py +11 -7
- alita_sdk/tools/code/linter/__init__.py +9 -8
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +20 -13
- alita_sdk/tools/code_indexer_toolkit.py +199 -0
- alita_sdk/tools/confluence/__init__.py +21 -14
- alita_sdk/tools/confluence/api_wrapper.py +197 -58
- alita_sdk/tools/confluence/loader.py +14 -2
- alita_sdk/tools/custom_open_api/__init__.py +11 -5
- alita_sdk/tools/elastic/__init__.py +10 -8
- alita_sdk/tools/elitea_base.py +546 -64
- alita_sdk/tools/figma/__init__.py +11 -8
- alita_sdk/tools/figma/api_wrapper.py +352 -153
- alita_sdk/tools/github/__init__.py +17 -17
- alita_sdk/tools/github/api_wrapper.py +9 -26
- alita_sdk/tools/github/github_client.py +81 -12
- alita_sdk/tools/github/schemas.py +2 -1
- alita_sdk/tools/github/tool.py +5 -1
- alita_sdk/tools/gitlab/__init__.py +18 -13
- alita_sdk/tools/gitlab/api_wrapper.py +224 -80
- alita_sdk/tools/gitlab_org/__init__.py +13 -10
- alita_sdk/tools/google/bigquery/__init__.py +13 -13
- alita_sdk/tools/google/bigquery/tool.py +5 -1
- alita_sdk/tools/google_places/__init__.py +20 -11
- alita_sdk/tools/jira/__init__.py +21 -11
- alita_sdk/tools/jira/api_wrapper.py +315 -168
- alita_sdk/tools/keycloak/__init__.py +10 -8
- alita_sdk/tools/localgit/__init__.py +8 -3
- alita_sdk/tools/localgit/local_git.py +62 -54
- alita_sdk/tools/localgit/tool.py +5 -1
- alita_sdk/tools/memory/__init__.py +38 -14
- alita_sdk/tools/non_code_indexer_toolkit.py +7 -2
- alita_sdk/tools/ocr/__init__.py +10 -8
- alita_sdk/tools/openapi/__init__.py +281 -108
- alita_sdk/tools/openapi/api_wrapper.py +883 -0
- alita_sdk/tools/openapi/tool.py +20 -0
- alita_sdk/tools/pandas/__init__.py +18 -11
- alita_sdk/tools/pandas/api_wrapper.py +40 -45
- alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
- alita_sdk/tools/postman/__init__.py +10 -11
- alita_sdk/tools/postman/api_wrapper.py +19 -8
- alita_sdk/tools/postman/postman_analysis.py +8 -1
- alita_sdk/tools/pptx/__init__.py +10 -10
- alita_sdk/tools/qtest/__init__.py +21 -14
- alita_sdk/tools/qtest/api_wrapper.py +1784 -88
- alita_sdk/tools/rally/__init__.py +12 -10
- alita_sdk/tools/report_portal/__init__.py +22 -16
- alita_sdk/tools/salesforce/__init__.py +21 -16
- alita_sdk/tools/servicenow/__init__.py +20 -16
- alita_sdk/tools/servicenow/api_wrapper.py +1 -1
- alita_sdk/tools/sharepoint/__init__.py +16 -14
- alita_sdk/tools/sharepoint/api_wrapper.py +179 -39
- alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
- alita_sdk/tools/sharepoint/utils.py +8 -2
- alita_sdk/tools/slack/__init__.py +11 -7
- alita_sdk/tools/sql/__init__.py +21 -19
- alita_sdk/tools/sql/api_wrapper.py +71 -23
- alita_sdk/tools/testio/__init__.py +20 -13
- alita_sdk/tools/testrail/__init__.py +12 -11
- alita_sdk/tools/testrail/api_wrapper.py +214 -46
- alita_sdk/tools/utils/__init__.py +28 -4
- alita_sdk/tools/utils/content_parser.py +182 -62
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +83 -27
- alita_sdk/tools/xray/__init__.py +17 -14
- alita_sdk/tools/xray/api_wrapper.py +58 -113
- alita_sdk/tools/yagmail/__init__.py +8 -3
- alita_sdk/tools/zephyr/__init__.py +11 -7
- alita_sdk/tools/zephyr_enterprise/__init__.py +15 -9
- alita_sdk/tools/zephyr_enterprise/api_wrapper.py +30 -15
- alita_sdk/tools/zephyr_essential/__init__.py +15 -10
- alita_sdk/tools/zephyr_essential/api_wrapper.py +297 -54
- alita_sdk/tools/zephyr_essential/client.py +6 -4
- alita_sdk/tools/zephyr_scale/__init__.py +12 -8
- alita_sdk/tools/zephyr_scale/api_wrapper.py +39 -31
- alita_sdk/tools/zephyr_squad/__init__.py +11 -7
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/METADATA +184 -37
- alita_sdk-0.3.562.dist-info/RECORD +450 -0
- alita_sdk-0.3.562.dist-info/entry_points.txt +2 -0
- alita_sdk/tools/bitbucket/tools.py +0 -304
- alita_sdk-0.3.257.dist-info/RECORD +0 -343
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.562.dist-info}/top_level.txt +0 -0
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import hashlib
|
|
1
2
|
import json
|
|
2
3
|
import logging
|
|
3
4
|
from typing import Optional, Generator, Literal
|
|
4
5
|
from pydantic import model_validator, create_model, Field, SecretStr, PrivateAttr
|
|
5
6
|
|
|
6
7
|
from .client import ZephyrEssentialAPI
|
|
7
|
-
from ..elitea_base import extend_with_vector_tools, BaseVectorStoreToolApiWrapper
|
|
8
8
|
from langchain_core.documents import Document
|
|
9
9
|
from langchain_core.tools import ToolException
|
|
10
10
|
|
|
11
11
|
from ..non_code_indexer_toolkit import NonCodeIndexerToolkit
|
|
12
12
|
from ..utils.available_tools_decorator import extend_with_parent_available_tools
|
|
13
|
+
from ..utils.content_parser import file_extension_by_chunker
|
|
14
|
+
from ...runtime.utils.utils import IndexerKeywords
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
class ZephyrEssentialApiWrapper(NonCodeIndexerToolkit):
|
|
@@ -180,12 +182,43 @@ class ZephyrEssentialApiWrapper(NonCodeIndexerToolkit):
|
|
|
180
182
|
def create_folder(self, json: str):
|
|
181
183
|
"""Create a new folder."""
|
|
182
184
|
folder_data = self._parse_json(json)
|
|
185
|
+
if 'parentId' not in folder_data:
|
|
186
|
+
if 'parentName' in folder_data:
|
|
187
|
+
parent_folder_name = folder_data['parentName']
|
|
188
|
+
|
|
189
|
+
parent_folder = self.find_folder_by_name(parent_folder_name)
|
|
190
|
+
|
|
191
|
+
if isinstance(parent_folder, ToolException):
|
|
192
|
+
return ToolException(f"Folder with name '{parent_folder_name}' not found.")
|
|
193
|
+
else:
|
|
194
|
+
folder_data['parentId'] = parent_folder['id']
|
|
195
|
+
|
|
183
196
|
return self._client.create_folder(folder_data)
|
|
184
197
|
|
|
185
198
|
def get_folder(self, folder_id: str):
|
|
186
199
|
"""Retrieve details of a specific folder."""
|
|
187
200
|
return self._client.get_folder(folder_id)
|
|
188
201
|
|
|
202
|
+
def find_folder_by_name(self, name: str, project_key: Optional[str] = None, folder_type: Optional[str] = None):
|
|
203
|
+
"""
|
|
204
|
+
Find a folder by its name, ignoring case.
|
|
205
|
+
|
|
206
|
+
:param name: The name of the folder to search for.
|
|
207
|
+
:param project_key: Optional filter by project key.
|
|
208
|
+
:param folder_type: Optional filter by folder type.
|
|
209
|
+
:return: The folder details if found, otherwise None.
|
|
210
|
+
"""
|
|
211
|
+
# Fetch all folders with optional filters
|
|
212
|
+
folders = self.list_folders(project_key=project_key, folder_type=folder_type)
|
|
213
|
+
|
|
214
|
+
# Iterate through the folders and search for the matching name
|
|
215
|
+
for folder in folders['values']:
|
|
216
|
+
if folder.get('name', '').lower() == name.lower():
|
|
217
|
+
return folder
|
|
218
|
+
|
|
219
|
+
# Return None if no folder is found
|
|
220
|
+
return ToolException(f"Folder with name {name} was not found")
|
|
221
|
+
|
|
189
222
|
def delete_link(self, link_id: str):
|
|
190
223
|
"""Delete a specific link."""
|
|
191
224
|
return self._client.delete_link(link_id)
|
|
@@ -236,11 +269,11 @@ class ZephyrEssentialApiWrapper(NonCodeIndexerToolkit):
|
|
|
236
269
|
|
|
237
270
|
def _index_tool_params(self):
|
|
238
271
|
return {
|
|
239
|
-
'chunking_tool':(Literal[
|
|
240
|
-
Field(description="Name of chunking tool", default='json'))
|
|
272
|
+
'chunking_tool':(Literal['json', ''], Field(description="Name of chunking tool", default='json'))
|
|
241
273
|
}
|
|
242
274
|
|
|
243
275
|
def _base_loader(self, **kwargs) -> Generator[Document, None, None]:
|
|
276
|
+
self._chunking_tool = kwargs.get('chunking_tool', None)
|
|
244
277
|
try:
|
|
245
278
|
test_cases = self.list_test_cases()
|
|
246
279
|
except Exception as e:
|
|
@@ -252,27 +285,29 @@ class ZephyrEssentialApiWrapper(NonCodeIndexerToolkit):
|
|
|
252
285
|
if isinstance(v, (str, int, float, bool, list, dict))
|
|
253
286
|
}
|
|
254
287
|
metadata['type'] = "TEST_CASE"
|
|
255
|
-
|
|
288
|
+
#
|
|
289
|
+
try:
|
|
290
|
+
additional_content = self._process_test_case(metadata['key'])
|
|
291
|
+
for steps_type, content in additional_content.items():
|
|
292
|
+
if content:
|
|
293
|
+
page_content = json.dumps(content)
|
|
294
|
+
content_hash = hashlib.sha256(page_content.encode('utf-8')).hexdigest()
|
|
295
|
+
metadata[IndexerKeywords.UPDATED_ON.value] = content_hash
|
|
296
|
+
metadata[IndexerKeywords.CONTENT_IN_BYTES.value] = page_content.encode('utf-8')
|
|
297
|
+
metadata["steps_type"] = steps_type
|
|
298
|
+
except Exception as e:
|
|
299
|
+
logging.error(f"Failed to process document: {e}")
|
|
300
|
+
#
|
|
256
301
|
yield Document(page_content="", metadata=metadata)
|
|
257
302
|
|
|
258
|
-
def
|
|
259
|
-
for document in documents:
|
|
260
|
-
try:
|
|
261
|
-
if document.metadata['type'] and document.metadata['type'] == "TEST_CASE":
|
|
262
|
-
additional_content = self._process_test_case(document.metadata['key'])
|
|
263
|
-
document.page_content = json.dumps(additional_content)
|
|
264
|
-
except json.JSONDecodeError as e:
|
|
265
|
-
logging.error(f"Failed to decode JSON from document: {e}")
|
|
266
|
-
yield document
|
|
267
|
-
|
|
268
|
-
def _process_test_case(self, key):
|
|
303
|
+
def _process_test_case(self, key) -> dict:
|
|
269
304
|
steps = self.get_test_case_test_steps(key)
|
|
305
|
+
if steps and not isinstance(steps, ToolException):
|
|
306
|
+
return {"steps": steps}
|
|
270
307
|
script = self.get_test_case_test_script(key)
|
|
271
|
-
|
|
272
|
-
"
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
return additional_content
|
|
308
|
+
if script and not isinstance(script, ToolException):
|
|
309
|
+
return {"script": script}
|
|
310
|
+
return {"empty": ""}
|
|
276
311
|
|
|
277
312
|
@extend_with_parent_available_tools
|
|
278
313
|
def get_available_tools(self):
|
|
@@ -481,6 +516,12 @@ class ZephyrEssentialApiWrapper(NonCodeIndexerToolkit):
|
|
|
481
516
|
"args_schema": GetFolder,
|
|
482
517
|
"ref": self.get_folder,
|
|
483
518
|
},
|
|
519
|
+
{
|
|
520
|
+
"name": "find_folder_by_name",
|
|
521
|
+
"description": self.find_folder_by_name.__doc__,
|
|
522
|
+
"args_schema": FindFolderByName,
|
|
523
|
+
"ref": self.find_folder_by_name,
|
|
524
|
+
},
|
|
484
525
|
{
|
|
485
526
|
"name": "delete_link",
|
|
486
527
|
"description": self.delete_link.__doc__,
|
|
@@ -576,8 +617,74 @@ UpdateTestCase = create_model(
|
|
|
576
617
|
json=(str, Field(description=("""
|
|
577
618
|
JSON body to update a test case. Example:
|
|
578
619
|
{
|
|
579
|
-
"
|
|
580
|
-
"
|
|
620
|
+
"id": 1,
|
|
621
|
+
"key": "SA-T10",
|
|
622
|
+
"name": "Check axial pump",
|
|
623
|
+
"project": {
|
|
624
|
+
"id": 10005,
|
|
625
|
+
"self": "https://<api-base-url>/projects/10005"
|
|
626
|
+
},
|
|
627
|
+
"createdOn": "2018-05-15T13:15:13Z",
|
|
628
|
+
"objective": "To ensure the axial pump can be enabled",
|
|
629
|
+
"precondition": "Latest version of the axial pump available",
|
|
630
|
+
"estimatedTime": 138000,
|
|
631
|
+
"labels": [
|
|
632
|
+
"Regression",
|
|
633
|
+
"Performance",
|
|
634
|
+
"Automated"
|
|
635
|
+
],
|
|
636
|
+
"component": {
|
|
637
|
+
"id": 10001,
|
|
638
|
+
"self": "https://<jira-instance>.atlassian.net/rest/api/2/component/10001"
|
|
639
|
+
},
|
|
640
|
+
"priority": {
|
|
641
|
+
"id": 10002,
|
|
642
|
+
"self": "https://<api-base-url>/priorities/10002"
|
|
643
|
+
},
|
|
644
|
+
"status": {
|
|
645
|
+
"id": 10000,
|
|
646
|
+
"self": "https://<api-base-url>/statuses/10000"
|
|
647
|
+
},
|
|
648
|
+
"folder": {
|
|
649
|
+
"id": 100006,
|
|
650
|
+
"self": "https://<api-base-url>/folders/10006"
|
|
651
|
+
},
|
|
652
|
+
"owner": {
|
|
653
|
+
"self": "https://<jira-instance>.atlassian.net/rest/api/2/user?accountId=5b10a2844c20165700ede21g",
|
|
654
|
+
"accountId": "5b10a2844c20165700ede21g"
|
|
655
|
+
},
|
|
656
|
+
"testScript": {
|
|
657
|
+
"self": "https://<api-base-url>/testCases/PROJ-T1/testscript"
|
|
658
|
+
},
|
|
659
|
+
"customFields": {
|
|
660
|
+
"Build Number": 20,
|
|
661
|
+
"Release Date": "2020-01-01",
|
|
662
|
+
"Pre-Condition(s)": "User should have logged in. <br> User should have navigated to the administration panel.",
|
|
663
|
+
"Implemented": false,
|
|
664
|
+
"Category": [
|
|
665
|
+
"Performance",
|
|
666
|
+
"Regression"
|
|
667
|
+
],
|
|
668
|
+
"Tester": "fa2e582e-5e15-521e-92e3-47e6ca2e7256"
|
|
669
|
+
},
|
|
670
|
+
"links": {
|
|
671
|
+
"self": "string",
|
|
672
|
+
"issues": [
|
|
673
|
+
{
|
|
674
|
+
"self": "string",
|
|
675
|
+
"issueId": 10100,
|
|
676
|
+
"id": 1,
|
|
677
|
+
"target": "https://<jira-instance>.atlassian.net/rest/api/2/issue/10000",
|
|
678
|
+
"type": "COVERAGE"
|
|
679
|
+
}
|
|
680
|
+
],
|
|
681
|
+
"webLinks": [
|
|
682
|
+
{
|
|
683
|
+
"self": "string",
|
|
684
|
+
"description": "A link to atlassian.com",
|
|
685
|
+
"url": "https://atlassian.com",
|
|
686
|
+
"id": 1,
|
|
687
|
+
"type": "COVERAGE"
|
|
581
688
|
}
|
|
582
689
|
"""
|
|
583
690
|
)))
|
|
@@ -594,9 +701,9 @@ CreateTestCaseIssueLink = create_model(
|
|
|
594
701
|
json=(str, Field(description=("""
|
|
595
702
|
JSON body to create an issue link. Example:
|
|
596
703
|
{
|
|
597
|
-
"
|
|
598
|
-
"description": "Link Description"
|
|
704
|
+
"issueId": 10100
|
|
599
705
|
}
|
|
706
|
+
where issueId - Jira issue id
|
|
600
707
|
"""
|
|
601
708
|
)))
|
|
602
709
|
)
|
|
@@ -638,8 +745,10 @@ CreateTestCaseTestScript = create_model(
|
|
|
638
745
|
json=(str, Field(description=("""
|
|
639
746
|
JSON body to create a test script. Example:
|
|
640
747
|
{
|
|
641
|
-
"
|
|
748
|
+
"type": "bdd",
|
|
749
|
+
"text": "Attempt to login to the application"
|
|
642
750
|
}
|
|
751
|
+
Where type - Test script type. Allowed: plain, bdd
|
|
643
752
|
"""
|
|
644
753
|
)))
|
|
645
754
|
)
|
|
@@ -656,13 +765,43 @@ CreateTestCaseTestSteps = create_model(
|
|
|
656
765
|
test_case_key=(str, Field(description="Key of the test case to create test steps for.")),
|
|
657
766
|
json=(str, Field(description=("""
|
|
658
767
|
JSON body to create test steps. Example:
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
768
|
+
{
|
|
769
|
+
"mode": "APPEND",
|
|
770
|
+
"items": [
|
|
771
|
+
{
|
|
772
|
+
"inline": {
|
|
773
|
+
"description": "Attempt to login to the application",
|
|
774
|
+
"testData": "Username = SmartBear Password = weLoveAtlassian",
|
|
775
|
+
"expectedResult": "Login succeeds, web-app redirects to the dashboard view",
|
|
776
|
+
"customFields": {
|
|
777
|
+
"Build Number": 20,
|
|
778
|
+
"Release Date": "2020-01-01",
|
|
779
|
+
"Pre-Condition(s)": "User should have logged in. <br> User should have navigated to the administration panel.",
|
|
780
|
+
"Implemented": false,
|
|
781
|
+
"Category": [
|
|
782
|
+
"Performance",
|
|
783
|
+
"Regression"
|
|
784
|
+
],
|
|
785
|
+
"Tester": "fa2e582e-5e15-521e-92e3-47e6ca2e7256"
|
|
786
|
+
}
|
|
787
|
+
},
|
|
788
|
+
"testCase": {
|
|
789
|
+
"self": "string",
|
|
790
|
+
"testCaseKey": "PROJ-T123",
|
|
791
|
+
"parameters": [
|
|
792
|
+
{
|
|
793
|
+
"name": "username",
|
|
794
|
+
"type": "DEFAULT_VALUE",
|
|
795
|
+
"value": "admin"
|
|
796
|
+
}
|
|
797
|
+
]
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
]
|
|
801
|
+
}
|
|
802
|
+
Where:
|
|
803
|
+
mode: str - required - Valid values: "APPEND", "OVERWRITE",
|
|
804
|
+
items - The list of test steps. Each step should be an object containing inline or testCase. They should only include one of these fields at a time.
|
|
666
805
|
"""
|
|
667
806
|
)))
|
|
668
807
|
)
|
|
@@ -700,9 +839,71 @@ UpdateTestCycle = create_model(
|
|
|
700
839
|
json=(str, Field(description=("""
|
|
701
840
|
JSON body to update a test cycle. Example:
|
|
702
841
|
{
|
|
703
|
-
"
|
|
704
|
-
"
|
|
705
|
-
|
|
842
|
+
"id": 1,
|
|
843
|
+
"key": "SA-R40",
|
|
844
|
+
"name": "Sprint 1 Regression Test Cycle",
|
|
845
|
+
"project": {
|
|
846
|
+
"id": 10005,
|
|
847
|
+
"self": "https://<api-base-url>/projects/10005"
|
|
848
|
+
},
|
|
849
|
+
"jiraProjectVersion": {
|
|
850
|
+
"id": 10000,
|
|
851
|
+
"self": "https://<jira-instance>.atlassian.net/rest/api/2/version/10000"
|
|
852
|
+
},
|
|
853
|
+
"status": {
|
|
854
|
+
"id": 10000,
|
|
855
|
+
"self": "https://<api-base-url>/statuses/10000"
|
|
856
|
+
},
|
|
857
|
+
"folder": {
|
|
858
|
+
"id": 100006,
|
|
859
|
+
"self": "https://<api-base-url>/folders/10006"
|
|
860
|
+
},
|
|
861
|
+
"description": "Regression test cycle 1 to ensure no breaking changes",
|
|
862
|
+
"plannedStartDate": "2018-05-19T13:15:13Z",
|
|
863
|
+
"plannedEndDate": "2018-05-20T13:15:13Z",
|
|
864
|
+
"owner": {
|
|
865
|
+
"self": "https://<jira-instance>.atlassian.net/rest/api/2/user?accountId=5b10a2844c20165700ede21g",
|
|
866
|
+
"accountId": "5b10a2844c20165700ede21g"
|
|
867
|
+
},
|
|
868
|
+
"customFields": {
|
|
869
|
+
"Build Number": 20,
|
|
870
|
+
"Release Date": "2020-01-01",
|
|
871
|
+
"Pre-Condition(s)": "User should have logged in. <br> User should have navigated to the administration panel.",
|
|
872
|
+
"Implemented": false,
|
|
873
|
+
"Category": [
|
|
874
|
+
"Performance",
|
|
875
|
+
"Regression"
|
|
876
|
+
],
|
|
877
|
+
"Tester": "fa2e582e-5e15-521e-92e3-47e6ca2e7256"
|
|
878
|
+
},
|
|
879
|
+
"links": {
|
|
880
|
+
"self": "string",
|
|
881
|
+
"issues": [
|
|
882
|
+
{
|
|
883
|
+
"self": "string",
|
|
884
|
+
"issueId": 10100,
|
|
885
|
+
"id": 1,
|
|
886
|
+
"target": "https://<jira-instance>.atlassian.net/rest/api/2/issue/10000",
|
|
887
|
+
"type": "COVERAGE"
|
|
888
|
+
}
|
|
889
|
+
],
|
|
890
|
+
"webLinks": [
|
|
891
|
+
{
|
|
892
|
+
"self": "string",
|
|
893
|
+
"description": "A link to atlassian.com",
|
|
894
|
+
"url": "https://atlassian.com",
|
|
895
|
+
"id": 1,
|
|
896
|
+
"type": "COVERAGE"
|
|
897
|
+
}
|
|
898
|
+
],
|
|
899
|
+
"testPlans": [
|
|
900
|
+
{
|
|
901
|
+
"id": 1,
|
|
902
|
+
"self": "https://<api-base-url>/links/1",
|
|
903
|
+
"type": "RELATED",
|
|
904
|
+
"testPlanId": 2,
|
|
905
|
+
"target": "https://<jira-instance>.atlassian.net/rest/api/2/testplan/123"
|
|
906
|
+
}
|
|
706
907
|
"""
|
|
707
908
|
)))
|
|
708
909
|
)
|
|
@@ -718,9 +919,9 @@ CreateTestCycleIssueLink = create_model(
|
|
|
718
919
|
json=(str, Field(description=("""
|
|
719
920
|
JSON body to create an issue link. Example:
|
|
720
921
|
{
|
|
721
|
-
"
|
|
722
|
-
"description": "Link Description"
|
|
922
|
+
"issueId": 10100
|
|
723
923
|
}
|
|
924
|
+
where issueId - Jira issue id
|
|
724
925
|
"""
|
|
725
926
|
)))
|
|
726
927
|
)
|
|
@@ -752,10 +953,34 @@ CreateTestExecution = create_model(
|
|
|
752
953
|
json=(str, Field(description=("""
|
|
753
954
|
JSON body to create a test execution. Example:
|
|
754
955
|
{
|
|
755
|
-
"
|
|
756
|
-
"
|
|
757
|
-
"
|
|
758
|
-
|
|
956
|
+
"projectKey": "TIS",
|
|
957
|
+
"testCaseKey": "SA-T10",
|
|
958
|
+
"testCycleKey": "SA-R10",
|
|
959
|
+
"statusName": "In Progress",
|
|
960
|
+
"testScriptResults": [
|
|
961
|
+
{
|
|
962
|
+
"statusName": "In Progress",
|
|
963
|
+
"actualEndDate": "2018-05-20T13:15:13Z",
|
|
964
|
+
"actualResult": "User logged in successfully"
|
|
965
|
+
}
|
|
966
|
+
],
|
|
967
|
+
"environmentName": "Chrome Latest Version",
|
|
968
|
+
"actualEndDate": "2018-05-20T13:15:13Z",
|
|
969
|
+
"executionTime": 120000,
|
|
970
|
+
"executedById": "5b10a2844c20165700ede21g",
|
|
971
|
+
"assignedToId": "5b10a2844c20165700ede21g",
|
|
972
|
+
"comment": "Test failed user could not login",
|
|
973
|
+
"customFields": {
|
|
974
|
+
"Build Number": 20,
|
|
975
|
+
"Release Date": "2020-01-01",
|
|
976
|
+
"Pre-Condition(s)": "User should have logged in. <br> User should have navigated to the administration panel.",
|
|
977
|
+
"Implemented": false,
|
|
978
|
+
"Category": [
|
|
979
|
+
"Performance",
|
|
980
|
+
"Regression"
|
|
981
|
+
],
|
|
982
|
+
"Tester": "fa2e582e-5e15-521e-92e3-47e6ca2e7256"
|
|
983
|
+
}
|
|
759
984
|
"""
|
|
760
985
|
)))
|
|
761
986
|
)
|
|
@@ -771,8 +996,13 @@ UpdateTestExecution = create_model(
|
|
|
771
996
|
json=(str, Field(description=("""
|
|
772
997
|
JSON body to update a test execution. Example:
|
|
773
998
|
{
|
|
774
|
-
"
|
|
775
|
-
"
|
|
999
|
+
"statusName": "In Progress",
|
|
1000
|
+
"environmentName": "Chrome Latest Version",
|
|
1001
|
+
"actualEndDate": "2018-05-20T13:15:13Z",
|
|
1002
|
+
"executionTime": 120000,
|
|
1003
|
+
"executedById": "5b10a2844c20165700ede21g",
|
|
1004
|
+
"assignedToId": "5b10a2844c20165700ede21g",
|
|
1005
|
+
"comment": "Test failed user could not login"
|
|
776
1006
|
}
|
|
777
1007
|
"""
|
|
778
1008
|
)))
|
|
@@ -790,12 +1020,14 @@ UpdateTestExecutionTestSteps = create_model(
|
|
|
790
1020
|
test_execution_id_or_key=(str, Field(description="ID or key of the test execution to update test steps for.")),
|
|
791
1021
|
json=(str, Field(description=("""
|
|
792
1022
|
"JSON body to update test steps. Example:
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1023
|
+
{
|
|
1024
|
+
"steps": [
|
|
1025
|
+
{
|
|
1026
|
+
"actualResult": "User logged in successfully",
|
|
1027
|
+
"statusName": "In Progress"
|
|
1028
|
+
}
|
|
1029
|
+
]
|
|
1030
|
+
}
|
|
799
1031
|
"""
|
|
800
1032
|
)))
|
|
801
1033
|
)
|
|
@@ -816,9 +1048,9 @@ CreateTestExecutionIssueLink = create_model(
|
|
|
816
1048
|
json=(str, Field(description=("""
|
|
817
1049
|
JSON body to create an issue link. Example:
|
|
818
1050
|
{
|
|
819
|
-
"
|
|
820
|
-
"description": "Link Description"
|
|
1051
|
+
"issueId": 10100
|
|
821
1052
|
}
|
|
1053
|
+
where issueId - Jira issue id
|
|
822
1054
|
"""
|
|
823
1055
|
)))
|
|
824
1056
|
)
|
|
@@ -847,10 +1079,13 @@ CreateFolder = create_model(
|
|
|
847
1079
|
json=(str, Field(description=("""
|
|
848
1080
|
JSON body to create a folder. Example:
|
|
849
1081
|
{
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
1082
|
+
"parentId": 123456,
|
|
1083
|
+
"parentName": "parentFolder",
|
|
1084
|
+
"name": "ZephyrEssential_test",
|
|
1085
|
+
"projectKey": "PRJ",
|
|
1086
|
+
"folderType": "TEST_CASE"
|
|
853
1087
|
}
|
|
1088
|
+
Possible folder types: "TEST_CASE", "TEST_PLAN", "TEST_CYCLE",
|
|
854
1089
|
"""
|
|
855
1090
|
)))
|
|
856
1091
|
)
|
|
@@ -860,6 +1095,14 @@ GetFolder = create_model(
|
|
|
860
1095
|
folder_id=(str, Field(description="ID of the folder to retrieve."))
|
|
861
1096
|
)
|
|
862
1097
|
|
|
1098
|
+
FindFolderByName = create_model(
|
|
1099
|
+
"GetFolder",
|
|
1100
|
+
name=(str, Field(description="Name of the folder to retrieve.")),
|
|
1101
|
+
project_key=(Optional[str], Field(description="Project key", default=None)),
|
|
1102
|
+
folder_type=(Optional[str], Field(description="""Folder type. Possible values: "TEST_CASE", "TEST_PLAN", "TEST_CYCLE" """,
|
|
1103
|
+
default=None)),
|
|
1104
|
+
)
|
|
1105
|
+
|
|
863
1106
|
DeleteLink = create_model(
|
|
864
1107
|
"DeleteLink",
|
|
865
1108
|
link_id=(str, Field(description="ID of the link to delete."))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import requests
|
|
2
|
+
from langchain_core.tools import ToolException
|
|
2
3
|
|
|
3
4
|
class ZephyrEssentialAPI:
|
|
4
5
|
def __init__(self, base_url: str, token: str):
|
|
@@ -14,10 +15,11 @@ class ZephyrEssentialAPI:
|
|
|
14
15
|
})
|
|
15
16
|
try:
|
|
16
17
|
resp = requests.request(method=method, url=url, headers=headers, json=json, params=params, files=files)
|
|
17
|
-
resp.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
if resp.status_code < 300:
|
|
19
|
+
if resp.headers.get("Content-Type", "").startswith("application/json"):
|
|
20
|
+
return resp.json()
|
|
21
|
+
return resp.text
|
|
22
|
+
return ToolException(f"Error performing request {method} {api_path}: {resp.content}")
|
|
21
23
|
except requests.RequestException as e:
|
|
22
24
|
raise Exception(f"Error performing request {method} {api_path}: {str(e)}")
|
|
23
25
|
|
|
@@ -6,7 +6,8 @@ from pydantic import create_model, BaseModel, Field
|
|
|
6
6
|
|
|
7
7
|
from .api_wrapper import ZephyrScaleApiWrapper
|
|
8
8
|
from ..base.tool import BaseAction
|
|
9
|
-
from ..
|
|
9
|
+
from ..elitea_base import filter_missconfigured_index_tools
|
|
10
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
10
11
|
from ...configurations.pgvector import PgVectorConfiguration
|
|
11
12
|
from ...configurations.zephyr import ZephyrConfiguration
|
|
12
13
|
|
|
@@ -31,16 +32,14 @@ def get_tools(tool):
|
|
|
31
32
|
|
|
32
33
|
class ZephyrScaleToolkit(BaseToolkit):
|
|
33
34
|
tools: List[BaseTool] = []
|
|
34
|
-
toolkit_max_length: int = 0
|
|
35
35
|
|
|
36
36
|
@staticmethod
|
|
37
37
|
def toolkit_config_schema() -> BaseModel:
|
|
38
38
|
selected_tools = {x['name']: x['args_schema'].schema() for x in ZephyrScaleApiWrapper.model_construct().get_available_tools()}
|
|
39
|
-
ZephyrScaleToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
40
39
|
return create_model(
|
|
41
40
|
name,
|
|
42
41
|
max_results=(int, Field(default=100, description="Results count to show")),
|
|
43
|
-
zephyr_configuration=(
|
|
42
|
+
zephyr_configuration=(ZephyrConfiguration, Field(description="Zephyr Configuration",
|
|
44
43
|
json_schema_extra={'configuration_types': ['zephyr']})),
|
|
45
44
|
pgvector_configuration=(Optional[PgVectorConfiguration], Field(default=None, description="PgVector Configuration",
|
|
46
45
|
json_schema_extra={
|
|
@@ -63,6 +62,7 @@ class ZephyrScaleToolkit(BaseToolkit):
|
|
|
63
62
|
)
|
|
64
63
|
|
|
65
64
|
@classmethod
|
|
65
|
+
@filter_missconfigured_index_tools
|
|
66
66
|
def get_toolkit(cls, selected_tools: list[str] | None = None, toolkit_name: Optional[str] = None, **kwargs):
|
|
67
67
|
if selected_tools is None:
|
|
68
68
|
selected_tools = []
|
|
@@ -73,18 +73,22 @@ class ZephyrScaleToolkit(BaseToolkit):
|
|
|
73
73
|
**(kwargs.get('pgvector_configuration') or {}),
|
|
74
74
|
}
|
|
75
75
|
zephyr_wrapper = ZephyrScaleApiWrapper(**wrapper_payload)
|
|
76
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
77
76
|
available_tools = zephyr_wrapper.get_available_tools()
|
|
78
77
|
tools = []
|
|
79
78
|
for tool in available_tools:
|
|
80
79
|
if selected_tools:
|
|
81
80
|
if tool["name"] not in selected_tools:
|
|
82
81
|
continue
|
|
82
|
+
description = tool["description"]
|
|
83
|
+
if toolkit_name:
|
|
84
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
85
|
+
description = description[:1000]
|
|
83
86
|
tools.append(BaseAction(
|
|
84
87
|
api_wrapper=zephyr_wrapper,
|
|
85
|
-
name=
|
|
86
|
-
description=
|
|
87
|
-
args_schema=tool["args_schema"]
|
|
88
|
+
name=tool["name"],
|
|
89
|
+
description=description,
|
|
90
|
+
args_schema=tool["args_schema"],
|
|
91
|
+
metadata={"toolkit_name": toolkit_name} if toolkit_name else {}
|
|
88
92
|
))
|
|
89
93
|
return cls(tools=tools)
|
|
90
94
|
|