alita-sdk 0.3.351__py3-none-any.whl → 0.3.499__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 +1256 -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 +64 -8
- alita_sdk/community/inventory/__init__.py +224 -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/visualize.py +1370 -0
- alita_sdk/configurations/bitbucket.py +94 -2
- alita_sdk/configurations/confluence.py +96 -1
- alita_sdk/configurations/gitlab.py +79 -0
- alita_sdk/configurations/jira.py +103 -0
- alita_sdk/configurations/testrail.py +88 -0
- alita_sdk/configurations/xray.py +93 -0
- alita_sdk/configurations/zephyr_enterprise.py +93 -0
- alita_sdk/configurations/zephyr_essential.py +75 -0
- alita_sdk/runtime/clients/artifact.py +1 -1
- alita_sdk/runtime/clients/client.py +214 -42
- 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 +373 -0
- alita_sdk/runtime/langchain/assistant.py +118 -30
- alita_sdk/runtime/langchain/constants.py +8 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +4 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +41 -12
- alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +1 -1
- alita_sdk/runtime/langchain/document_loaders/constants.py +116 -99
- alita_sdk/runtime/langchain/interfaces/llm_processor.py +2 -2
- alita_sdk/runtime/langchain/langraph_agent.py +307 -71
- alita_sdk/runtime/langchain/utils.py +48 -8
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/models/mcp_models.py +61 -0
- alita_sdk/runtime/toolkits/__init__.py +26 -0
- alita_sdk/runtime/toolkits/application.py +9 -2
- alita_sdk/runtime/toolkits/artifact.py +18 -6
- 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/tools.py +205 -55
- alita_sdk/runtime/toolkits/vectorstore.py +9 -4
- alita_sdk/runtime/tools/__init__.py +11 -3
- alita_sdk/runtime/tools/application.py +7 -0
- alita_sdk/runtime/tools/artifact.py +225 -12
- alita_sdk/runtime/tools/function.py +95 -5
- alita_sdk/runtime/tools/graph.py +10 -4
- alita_sdk/runtime/tools/image_generation.py +212 -0
- alita_sdk/runtime/tools/llm.py +494 -102
- 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 +4 -4
- 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 +180 -79
- alita_sdk/runtime/tools/vectorstore.py +22 -21
- alita_sdk/runtime/tools/vectorstore_base.py +125 -52
- alita_sdk/runtime/utils/AlitaCallback.py +106 -20
- alita_sdk/runtime/utils/mcp_client.py +465 -0
- alita_sdk/runtime/utils/mcp_oauth.py +244 -0
- alita_sdk/runtime/utils/mcp_sse_client.py +405 -0
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/streamlit.py +40 -13
- alita_sdk/runtime/utils/toolkit_utils.py +28 -9
- alita_sdk/runtime/utils/utils.py +12 -0
- alita_sdk/tools/__init__.py +77 -33
- alita_sdk/tools/ado/repos/__init__.py +7 -6
- alita_sdk/tools/ado/repos/repos_wrapper.py +11 -11
- alita_sdk/tools/ado/test_plan/__init__.py +7 -7
- alita_sdk/tools/ado/wiki/__init__.py +7 -11
- alita_sdk/tools/ado/wiki/ado_wrapper.py +89 -15
- alita_sdk/tools/ado/work_item/__init__.py +7 -11
- alita_sdk/tools/ado/work_item/ado_wrapper.py +17 -8
- alita_sdk/tools/advanced_jira_mining/__init__.py +8 -7
- alita_sdk/tools/aws/delta_lake/__init__.py +11 -9
- alita_sdk/tools/azure_ai/search/__init__.py +7 -6
- alita_sdk/tools/base_indexer_toolkit.py +345 -70
- alita_sdk/tools/bitbucket/__init__.py +9 -8
- alita_sdk/tools/bitbucket/api_wrapper.py +50 -6
- alita_sdk/tools/browser/__init__.py +4 -4
- alita_sdk/tools/carrier/__init__.py +4 -6
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
- 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 +7 -6
- alita_sdk/tools/cloud/azure/__init__.py +7 -6
- alita_sdk/tools/cloud/gcp/__init__.py +7 -6
- alita_sdk/tools/cloud/k8s/__init__.py +7 -6
- alita_sdk/tools/code/linter/__init__.py +7 -7
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +8 -7
- alita_sdk/tools/code_indexer_toolkit.py +199 -0
- alita_sdk/tools/confluence/__init__.py +9 -8
- alita_sdk/tools/confluence/api_wrapper.py +171 -75
- alita_sdk/tools/confluence/loader.py +10 -0
- alita_sdk/tools/custom_open_api/__init__.py +9 -4
- alita_sdk/tools/elastic/__init__.py +8 -7
- alita_sdk/tools/elitea_base.py +492 -52
- alita_sdk/tools/figma/__init__.py +7 -7
- alita_sdk/tools/figma/api_wrapper.py +2 -1
- alita_sdk/tools/github/__init__.py +9 -9
- alita_sdk/tools/github/api_wrapper.py +9 -26
- alita_sdk/tools/github/github_client.py +62 -2
- alita_sdk/tools/gitlab/__init__.py +8 -8
- alita_sdk/tools/gitlab/api_wrapper.py +135 -33
- alita_sdk/tools/gitlab_org/__init__.py +7 -8
- alita_sdk/tools/google/bigquery/__init__.py +11 -12
- alita_sdk/tools/google_places/__init__.py +8 -7
- alita_sdk/tools/jira/__init__.py +9 -7
- alita_sdk/tools/jira/api_wrapper.py +100 -52
- alita_sdk/tools/keycloak/__init__.py +8 -7
- alita_sdk/tools/localgit/local_git.py +56 -54
- alita_sdk/tools/memory/__init__.py +1 -1
- alita_sdk/tools/non_code_indexer_toolkit.py +3 -2
- alita_sdk/tools/ocr/__init__.py +8 -7
- alita_sdk/tools/openapi/__init__.py +10 -1
- alita_sdk/tools/pandas/__init__.py +8 -7
- alita_sdk/tools/postman/__init__.py +7 -8
- alita_sdk/tools/postman/api_wrapper.py +19 -8
- alita_sdk/tools/postman/postman_analysis.py +8 -1
- alita_sdk/tools/pptx/__init__.py +8 -9
- alita_sdk/tools/qtest/__init__.py +16 -11
- alita_sdk/tools/qtest/api_wrapper.py +1784 -88
- alita_sdk/tools/rally/__init__.py +7 -8
- alita_sdk/tools/report_portal/__init__.py +9 -7
- alita_sdk/tools/salesforce/__init__.py +7 -7
- alita_sdk/tools/servicenow/__init__.py +10 -10
- alita_sdk/tools/sharepoint/__init__.py +7 -6
- alita_sdk/tools/sharepoint/api_wrapper.py +127 -36
- alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
- alita_sdk/tools/sharepoint/utils.py +8 -2
- alita_sdk/tools/slack/__init__.py +7 -6
- alita_sdk/tools/sql/__init__.py +8 -7
- alita_sdk/tools/sql/api_wrapper.py +71 -23
- alita_sdk/tools/testio/__init__.py +7 -6
- alita_sdk/tools/testrail/__init__.py +8 -9
- alita_sdk/tools/utils/__init__.py +26 -4
- alita_sdk/tools/utils/content_parser.py +88 -60
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +76 -26
- alita_sdk/tools/xray/__init__.py +9 -7
- alita_sdk/tools/zephyr/__init__.py +7 -6
- alita_sdk/tools/zephyr_enterprise/__init__.py +8 -6
- alita_sdk/tools/zephyr_essential/__init__.py +7 -6
- alita_sdk/tools/zephyr_essential/api_wrapper.py +12 -13
- alita_sdk/tools/zephyr_scale/__init__.py +7 -6
- alita_sdk/tools/zephyr_squad/__init__.py +7 -6
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/METADATA +147 -2
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/RECORD +206 -130
- alita_sdk-0.3.499.dist-info/entry_points.txt +2 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/top_level.txt +0 -0
alita_sdk/tools/ocr/__init__.py
CHANGED
|
@@ -5,7 +5,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
|
5
5
|
|
|
6
6
|
from .api_wrapper import OCRApiWrapper
|
|
7
7
|
from ..base.tool import BaseAction
|
|
8
|
-
from ..utils import clean_string,
|
|
8
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
9
9
|
|
|
10
10
|
name = "ocr"
|
|
11
11
|
|
|
@@ -23,15 +23,13 @@ def get_tools(tool):
|
|
|
23
23
|
|
|
24
24
|
class OCRToolkit(BaseToolkit):
|
|
25
25
|
tools: list[BaseTool] = []
|
|
26
|
-
toolkit_max_length: int = 0
|
|
27
26
|
|
|
28
27
|
@staticmethod
|
|
29
28
|
def toolkit_config_schema() -> BaseModel:
|
|
30
29
|
selected_tools = {x['name']: x['args_schema'].schema() for x in OCRApiWrapper.model_construct().get_available_tools()}
|
|
31
|
-
OCRToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
32
30
|
return create_model(
|
|
33
31
|
name,
|
|
34
|
-
artifacts_folder=(str, Field(description="Folder path containing artifacts to process", json_schema_extra={'toolkit_name': True
|
|
32
|
+
artifacts_folder=(str, Field(description="Folder path containing artifacts to process", json_schema_extra={'toolkit_name': True})),
|
|
35
33
|
tesseract_settings=(dict, Field(description="Settings for Tesseract OCR processing", default={})),
|
|
36
34
|
structured_output=(bool, Field(description="Whether to return structured JSON output", default=False)),
|
|
37
35
|
expected_fields=(dict, Field(description="Expected fields for structured output", default={})),
|
|
@@ -47,16 +45,19 @@ class OCRToolkit(BaseToolkit):
|
|
|
47
45
|
if selected_tools is None:
|
|
48
46
|
selected_tools = []
|
|
49
47
|
ocr_api_wrapper = OCRApiWrapper(**kwargs)
|
|
50
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
51
48
|
available_tools = ocr_api_wrapper.get_available_tools()
|
|
52
49
|
tools = []
|
|
53
50
|
for tool in available_tools:
|
|
54
51
|
if selected_tools and tool["name"] not in selected_tools:
|
|
55
52
|
continue
|
|
53
|
+
description = tool["description"]
|
|
54
|
+
if toolkit_name:
|
|
55
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
56
|
+
description = description[:1000]
|
|
56
57
|
tools.append(BaseAction(
|
|
57
58
|
api_wrapper=ocr_api_wrapper,
|
|
58
|
-
name=
|
|
59
|
-
description=
|
|
59
|
+
name=tool["name"],
|
|
60
|
+
description=description,
|
|
60
61
|
args_schema=tool["args_schema"]
|
|
61
62
|
))
|
|
62
63
|
return cls(tools=tools)
|
|
@@ -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
|
-
|
|
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:
|
|
@@ -5,7 +5,7 @@ from pydantic import BaseModel, ConfigDict, create_model, Field
|
|
|
5
5
|
|
|
6
6
|
from .api_wrapper import PandasWrapper
|
|
7
7
|
from ..base.tool import BaseAction
|
|
8
|
-
from ..utils import clean_string,
|
|
8
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
9
9
|
|
|
10
10
|
name = "pandas"
|
|
11
11
|
|
|
@@ -21,15 +21,13 @@ def get_tools(tool):
|
|
|
21
21
|
|
|
22
22
|
class PandasToolkit(BaseToolkit):
|
|
23
23
|
tools: List[BaseTool] = []
|
|
24
|
-
toolkit_max_length: int = 0
|
|
25
24
|
|
|
26
25
|
@staticmethod
|
|
27
26
|
def toolkit_config_schema() -> BaseModel:
|
|
28
27
|
selected_tools = {x['name']: x['args_schema'].schema() for x in PandasWrapper.model_construct().get_available_tools()}
|
|
29
|
-
PandasToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
30
28
|
return create_model(
|
|
31
29
|
name,
|
|
32
|
-
bucket_name=(str, Field(default=None, title="Bucket name", description="Bucket where the content file is stored"
|
|
30
|
+
bucket_name=(str, Field(default=None, title="Bucket name", description="Bucket where the content file is stored")),
|
|
33
31
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
34
32
|
__config__=ConfigDict(json_schema_extra={'metadata': {"label": "Pandas", "icon_url": "pandas-icon.svg",
|
|
35
33
|
"categories": ["analysis"],
|
|
@@ -41,16 +39,19 @@ class PandasToolkit(BaseToolkit):
|
|
|
41
39
|
if selected_tools is None:
|
|
42
40
|
selected_tools = []
|
|
43
41
|
csv_tool_api_wrapper = PandasWrapper(**kwargs)
|
|
44
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
45
42
|
available_tools = csv_tool_api_wrapper.get_available_tools()
|
|
46
43
|
tools = []
|
|
47
44
|
for tool in available_tools:
|
|
48
45
|
if selected_tools and tool["name"] not in selected_tools:
|
|
49
46
|
continue
|
|
47
|
+
description = tool["description"]
|
|
48
|
+
if toolkit_name:
|
|
49
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
50
|
+
description = description[:1000]
|
|
50
51
|
tools.append(BaseAction(
|
|
51
52
|
api_wrapper=csv_tool_api_wrapper,
|
|
52
|
-
name=
|
|
53
|
-
description=
|
|
53
|
+
name=tool["name"],
|
|
54
|
+
description=description,
|
|
54
55
|
args_schema=tool["args_schema"]
|
|
55
56
|
))
|
|
56
57
|
return cls(tools=tools)
|
|
@@ -6,7 +6,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field, field_validator
|
|
|
6
6
|
from ..base.tool import BaseAction
|
|
7
7
|
|
|
8
8
|
from .api_wrapper import PostmanApiWrapper
|
|
9
|
-
from ..utils import clean_string, get_max_toolkit_length,
|
|
9
|
+
from ..utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
10
10
|
from ...configurations.postman import PostmanConfiguration
|
|
11
11
|
|
|
12
12
|
name = "postman"
|
|
@@ -43,14 +43,11 @@ def get_tools(tool):
|
|
|
43
43
|
|
|
44
44
|
class PostmanToolkit(BaseToolkit):
|
|
45
45
|
tools: List[BaseTool] = []
|
|
46
|
-
toolkit_max_length: int = 0
|
|
47
46
|
|
|
48
47
|
@staticmethod
|
|
49
48
|
def toolkit_config_schema() -> BaseModel:
|
|
50
49
|
selected_tools = {x['name']: x['args_schema'].schema(
|
|
51
50
|
) for x in PostmanApiWrapper.model_construct().get_available_tools()}
|
|
52
|
-
PostmanToolkit.toolkit_max_length = get_max_toolkit_length(
|
|
53
|
-
selected_tools)
|
|
54
51
|
m = create_model(
|
|
55
52
|
name,
|
|
56
53
|
postman_configuration=(Optional[PostmanConfiguration], Field(description="Postman Configuration",
|
|
@@ -89,19 +86,21 @@ class PostmanToolkit(BaseToolkit):
|
|
|
89
86
|
**kwargs['postman_configuration'],
|
|
90
87
|
}
|
|
91
88
|
postman_api_wrapper = PostmanApiWrapper(**wrapper_payload)
|
|
92
|
-
prefix = clean_string(str(toolkit_name), cls.toolkit_max_length) + \
|
|
93
|
-
TOOLKIT_SPLITTER if toolkit_name else ''
|
|
94
89
|
available_tools = postman_api_wrapper.get_available_tools()
|
|
95
90
|
tools = []
|
|
96
91
|
for tool in available_tools:
|
|
97
92
|
if selected_tools:
|
|
98
93
|
if tool["name"] not in selected_tools:
|
|
99
94
|
continue
|
|
95
|
+
description = f"{tool['description']}\nAPI URL: {postman_api_wrapper.base_url}"
|
|
96
|
+
if toolkit_name:
|
|
97
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
98
|
+
description = description[:1000]
|
|
100
99
|
tools.append(PostmanAction(
|
|
101
100
|
api_wrapper=postman_api_wrapper,
|
|
102
|
-
name=
|
|
101
|
+
name=tool["name"],
|
|
103
102
|
mode=tool["mode"],
|
|
104
|
-
description=
|
|
103
|
+
description=description,
|
|
105
104
|
args_schema=tool["args_schema"]
|
|
106
105
|
))
|
|
107
106
|
return cls(tools=tools)
|
|
@@ -340,7 +340,7 @@ class PostmanApiWrapper(BaseToolApiWrapper):
|
|
|
340
340
|
raise ToolException(
|
|
341
341
|
f"Invalid JSON response from Postman API: {str(e)}")
|
|
342
342
|
|
|
343
|
-
def _apply_authentication(self, headers, params, all_variables, resolve_variables):
|
|
343
|
+
def _apply_authentication(self, headers, params, all_variables, native_auth, resolve_variables):
|
|
344
344
|
"""Apply authentication based on environment_config auth settings.
|
|
345
345
|
|
|
346
346
|
Supports multiple authentication types:
|
|
@@ -363,14 +363,15 @@ class PostmanApiWrapper(BaseToolApiWrapper):
|
|
|
363
363
|
import base64
|
|
364
364
|
|
|
365
365
|
# Handle structured auth configuration only - no backward compatibility
|
|
366
|
-
auth_config = self.environment_config.get('auth')
|
|
366
|
+
auth_config = self.environment_config.get('auth', native_auth)
|
|
367
367
|
if auth_config and isinstance(auth_config, dict):
|
|
368
368
|
auth_type = auth_config.get('type', '').lower()
|
|
369
369
|
auth_params = auth_config.get('params', {})
|
|
370
370
|
|
|
371
371
|
if auth_type == 'bearer':
|
|
372
372
|
# Bearer token authentication
|
|
373
|
-
|
|
373
|
+
tokent_raw = auth_config.get('bearer', [{}])[0].get('value', '')
|
|
374
|
+
token = resolve_variables(str(tokent_raw))
|
|
374
375
|
if token:
|
|
375
376
|
headers['Authorization'] = f'Bearer {token}'
|
|
376
377
|
|
|
@@ -739,7 +740,7 @@ class PostmanApiWrapper(BaseToolApiWrapper):
|
|
|
739
740
|
all_variables = {}
|
|
740
741
|
|
|
741
742
|
# 1. Start with environment_config variables (lowest priority)
|
|
742
|
-
all_variables.update(self.
|
|
743
|
+
all_variables.update(self._get_variables_from_env_config())
|
|
743
744
|
|
|
744
745
|
# 2. Add collection variables
|
|
745
746
|
collection_variables = collection_data.get('variable', [])
|
|
@@ -760,8 +761,9 @@ class PostmanApiWrapper(BaseToolApiWrapper):
|
|
|
760
761
|
import re
|
|
761
762
|
def replace_var(match):
|
|
762
763
|
var_name = match.group(1)
|
|
763
|
-
|
|
764
|
-
|
|
764
|
+
value = all_variables.get(var_name, None)
|
|
765
|
+
return resolve_variables(str(value)) if value else match.group(0)
|
|
766
|
+
|
|
765
767
|
return re.sub(r'\{\{([^}]+)\}\}', replace_var, text)
|
|
766
768
|
|
|
767
769
|
# Prepare the request
|
|
@@ -791,7 +793,7 @@ class PostmanApiWrapper(BaseToolApiWrapper):
|
|
|
791
793
|
headers = {}
|
|
792
794
|
|
|
793
795
|
# Handle authentication from environment_config
|
|
794
|
-
self._apply_authentication(headers, params, all_variables, resolve_variables)
|
|
796
|
+
self._apply_authentication(headers, params, all_variables, request_data.get('auth', None), resolve_variables)
|
|
795
797
|
|
|
796
798
|
# Add headers from request
|
|
797
799
|
request_headers = request_data.get('header', [])
|
|
@@ -1640,7 +1642,7 @@ class PostmanApiWrapper(BaseToolApiWrapper):
|
|
|
1640
1642
|
|
|
1641
1643
|
# Find the request
|
|
1642
1644
|
request_item = self.analyzer.find_request_by_path(
|
|
1643
|
-
collection_data["item"], request_path)
|
|
1645
|
+
collection_data["item"], request_path, collection_data.get("auth", None))
|
|
1644
1646
|
if not request_item:
|
|
1645
1647
|
raise ToolException(f"Request '{request_path}' not found")
|
|
1646
1648
|
|
|
@@ -2161,3 +2163,12 @@ class PostmanApiWrapper(BaseToolApiWrapper):
|
|
|
2161
2163
|
parse_items(items)
|
|
2162
2164
|
|
|
2163
2165
|
return result
|
|
2166
|
+
|
|
2167
|
+
def _get_variables_from_env_config(self):
|
|
2168
|
+
"""Extracts all enabled variables from the 'values' field in environment_config."""
|
|
2169
|
+
result = {}
|
|
2170
|
+
values = self.environment_config.get("values", [])
|
|
2171
|
+
for var in values:
|
|
2172
|
+
if var.get("enabled", True) and "key" in var and "value" in var:
|
|
2173
|
+
result[var["key"]] = var["value"]
|
|
2174
|
+
return result
|
|
@@ -1049,13 +1049,14 @@ class PostmanAnalyzer:
|
|
|
1049
1049
|
find_in_items(items, path_parts)
|
|
1050
1050
|
return results
|
|
1051
1051
|
|
|
1052
|
-
def find_request_by_path(self, items: List[Dict], request_path: str) -> Optional[Dict]:
|
|
1052
|
+
def find_request_by_path(self, items: List[Dict], request_path: str, auth = None) -> Optional[Dict]:
|
|
1053
1053
|
"""Find a request by its path."""
|
|
1054
1054
|
path_parts = [part.strip() for part in request_path.split('/') if part.strip()]
|
|
1055
1055
|
if not path_parts:
|
|
1056
1056
|
return None
|
|
1057
1057
|
|
|
1058
1058
|
current_items = items
|
|
1059
|
+
current_auth = auth
|
|
1059
1060
|
|
|
1060
1061
|
# Navigate through folders to the request
|
|
1061
1062
|
for i, part in enumerate(path_parts):
|
|
@@ -1065,6 +1066,9 @@ class PostmanAnalyzer:
|
|
|
1065
1066
|
if i == len(path_parts) - 1:
|
|
1066
1067
|
# This should be the request
|
|
1067
1068
|
if item.get('request'):
|
|
1069
|
+
# if request has no auth, inherit from parent
|
|
1070
|
+
if not item['request'].get('auth') and current_auth:
|
|
1071
|
+
item['request']['auth'] = current_auth
|
|
1068
1072
|
return item
|
|
1069
1073
|
else:
|
|
1070
1074
|
return None
|
|
@@ -1072,6 +1076,9 @@ class PostmanAnalyzer:
|
|
|
1072
1076
|
# This should be a folder
|
|
1073
1077
|
if item.get('item'):
|
|
1074
1078
|
current_items = item['item']
|
|
1079
|
+
# Update current_auth if folder has auth
|
|
1080
|
+
if item.get('auth'):
|
|
1081
|
+
current_auth = item['auth']
|
|
1075
1082
|
found = True
|
|
1076
1083
|
break
|
|
1077
1084
|
else:
|
alita_sdk/tools/pptx/__init__.py
CHANGED
|
@@ -7,7 +7,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
|
7
7
|
from .pptx_wrapper import PPTXWrapper
|
|
8
8
|
|
|
9
9
|
from ..base.tool import BaseAction
|
|
10
|
-
from ..utils import clean_string,
|
|
10
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
11
11
|
|
|
12
12
|
logger = logging.getLogger(__name__)
|
|
13
13
|
|
|
@@ -27,8 +27,6 @@ def get_tools(tool):
|
|
|
27
27
|
).get_tools()
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
TOOLKIT_MAX_LENGTH = 25
|
|
31
|
-
|
|
32
30
|
class PPTXToolkit(BaseToolkit):
|
|
33
31
|
"""
|
|
34
32
|
PowerPoint (PPTX) manipulation toolkit for Alita.
|
|
@@ -45,8 +43,7 @@ class PPTXToolkit(BaseToolkit):
|
|
|
45
43
|
|
|
46
44
|
return create_model(
|
|
47
45
|
name,
|
|
48
|
-
bucket_name=(str, Field(description="Bucket name where PPTX files are stored",
|
|
49
|
-
json_schema_extra={'toolkit_name': True, 'max_toolkit_length': TOOLKIT_MAX_LENGTH})),
|
|
46
|
+
bucket_name=(str, Field(description="Bucket name where PPTX files are stored")),
|
|
50
47
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
51
48
|
__config__=ConfigDict(json_schema_extra={
|
|
52
49
|
'metadata': {
|
|
@@ -75,18 +72,20 @@ class PPTXToolkit(BaseToolkit):
|
|
|
75
72
|
selected_tools = []
|
|
76
73
|
|
|
77
74
|
pptx_api_wrapper = PPTXWrapper(**kwargs)
|
|
78
|
-
prefix = clean_string(toolkit_name, TOOLKIT_MAX_LENGTH) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
79
75
|
available_tools = pptx_api_wrapper.get_available_tools()
|
|
80
76
|
tools = []
|
|
81
77
|
|
|
82
78
|
for tool in available_tools:
|
|
83
79
|
if selected_tools and tool["name"] not in selected_tools:
|
|
84
80
|
continue
|
|
85
|
-
|
|
81
|
+
description = tool["description"]
|
|
82
|
+
if toolkit_name:
|
|
83
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
84
|
+
description = description[:1000]
|
|
86
85
|
tools.append(BaseAction(
|
|
87
86
|
api_wrapper=pptx_api_wrapper,
|
|
88
|
-
name=
|
|
89
|
-
description=
|
|
87
|
+
name=tool["name"],
|
|
88
|
+
description=description,
|
|
90
89
|
args_schema=tool["args_schema"]
|
|
91
90
|
))
|
|
92
91
|
|
|
@@ -7,7 +7,7 @@ from pydantic import create_model, BaseModel, ConfigDict, Field, SecretStr
|
|
|
7
7
|
from .api_wrapper import QtestApiWrapper
|
|
8
8
|
from .tool import QtestAction
|
|
9
9
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
10
|
-
from ..utils import clean_string, get_max_toolkit_length,
|
|
10
|
+
from ..utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
11
11
|
from ...configurations.qtest import QtestConfiguration
|
|
12
12
|
|
|
13
13
|
name = "qtest"
|
|
@@ -17,27 +17,29 @@ def get_tools(tool):
|
|
|
17
17
|
toolkit = QtestToolkit.get_toolkit(
|
|
18
18
|
selected_tools=tool['settings'].get('selected_tools', []),
|
|
19
19
|
qtest_project_id=tool['settings'].get('qtest_project_id', tool['settings'].get('project_id', None)),
|
|
20
|
+
no_of_tests_shown_in_dql_search=tool['settings'].get('no_of_tests_shown_in_dql_search'),
|
|
20
21
|
qtest_configuration=tool['settings']['qtest_configuration'],
|
|
21
|
-
toolkit_name=tool.get('toolkit_name')
|
|
22
|
+
toolkit_name=tool.get('toolkit_name'),
|
|
23
|
+
llm=tool['settings'].get('llm', None)
|
|
22
24
|
)
|
|
23
25
|
return toolkit.tools
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
class QtestToolkit(BaseToolkit):
|
|
27
29
|
tools: List[BaseTool] = []
|
|
28
|
-
toolkit_max_length: int = 0
|
|
29
30
|
|
|
30
31
|
@staticmethod
|
|
31
32
|
def toolkit_config_schema() -> BaseModel:
|
|
32
33
|
selected_tools = {x['name']: x['args_schema'].schema() for x in QtestApiWrapper.model_construct().get_available_tools()}
|
|
33
|
-
QtestToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
34
34
|
m = create_model(
|
|
35
35
|
name,
|
|
36
36
|
qtest_configuration=(QtestConfiguration, Field(description="QTest API token", json_schema_extra={
|
|
37
37
|
'configuration_types': ['qtest']})),
|
|
38
|
-
qtest_project_id=(int, Field(
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
qtest_project_id=(int, Field(description="QTest project id")),
|
|
39
|
+
no_of_tests_shown_in_dql_search=(Optional[int], Field(description="Max number of items returned by dql search",
|
|
40
|
+
default=10)),
|
|
41
|
+
|
|
42
|
+
selected_tools=(List[Literal[tuple(selected_tools)]],
|
|
41
43
|
Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
42
44
|
__config__=ConfigDict(json_schema_extra={'metadata': {"label": "QTest", "icon_url": "qtest.svg",
|
|
43
45
|
"categories": ["test management"],
|
|
@@ -71,21 +73,24 @@ class QtestToolkit(BaseToolkit):
|
|
|
71
73
|
**kwargs['qtest_configuration'],
|
|
72
74
|
}
|
|
73
75
|
qtest_api_wrapper = QtestApiWrapper(**wrapper_payload)
|
|
74
|
-
prefix = clean_string(str(toolkit_name), cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
75
76
|
available_tools = qtest_api_wrapper.get_available_tools()
|
|
76
77
|
tools = []
|
|
77
78
|
for tool in available_tools:
|
|
78
79
|
if selected_tools:
|
|
79
80
|
if tool["name"] not in selected_tools:
|
|
80
81
|
continue
|
|
82
|
+
description = f"{tool['description']}\nUrl: {qtest_api_wrapper.base_url}. Project id: {qtest_api_wrapper.qtest_project_id}"
|
|
83
|
+
if toolkit_name:
|
|
84
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
85
|
+
description = description[:1000]
|
|
81
86
|
tools.append(QtestAction(
|
|
82
87
|
api_wrapper=qtest_api_wrapper,
|
|
83
|
-
name=
|
|
88
|
+
name=tool["name"],
|
|
84
89
|
mode=tool["mode"],
|
|
85
|
-
description=
|
|
90
|
+
description=description,
|
|
86
91
|
args_schema=tool["args_schema"]
|
|
87
92
|
))
|
|
88
93
|
return cls(tools=tools)
|
|
89
94
|
|
|
90
95
|
def get_tools(self):
|
|
91
|
-
return self.tools
|
|
96
|
+
return self.tools
|