alita-sdk 0.3.462__py3-none-any.whl → 0.3.627__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/agent/__init__.py +5 -0
- alita_sdk/cli/agent/default.py +258 -0
- alita_sdk/cli/agent_executor.py +15 -3
- alita_sdk/cli/agent_loader.py +56 -8
- alita_sdk/cli/agent_ui.py +93 -31
- alita_sdk/cli/agents.py +2274 -230
- alita_sdk/cli/callbacks.py +96 -25
- alita_sdk/cli/cli.py +10 -1
- alita_sdk/cli/config.py +162 -9
- 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/input_handler.py +419 -0
- alita_sdk/cli/inventory.py +1073 -0
- alita_sdk/cli/testcases/__init__.py +94 -0
- alita_sdk/cli/testcases/data_generation.py +119 -0
- alita_sdk/cli/testcases/discovery.py +96 -0
- alita_sdk/cli/testcases/executor.py +84 -0
- alita_sdk/cli/testcases/logger.py +85 -0
- alita_sdk/cli/testcases/parser.py +172 -0
- alita_sdk/cli/testcases/prompts.py +91 -0
- alita_sdk/cli/testcases/reporting.py +125 -0
- alita_sdk/cli/testcases/setup.py +108 -0
- alita_sdk/cli/testcases/test_runner.py +282 -0
- alita_sdk/cli/testcases/utils.py +39 -0
- alita_sdk/cli/testcases/validation.py +90 -0
- alita_sdk/cli/testcases/workflow.py +196 -0
- alita_sdk/cli/toolkit.py +14 -17
- alita_sdk/cli/toolkit_loader.py +35 -5
- alita_sdk/cli/tools/__init__.py +36 -2
- alita_sdk/cli/tools/approval.py +224 -0
- alita_sdk/cli/tools/filesystem.py +910 -64
- 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 +1 -1
- alita_sdk/configurations/ado.py +141 -20
- alita_sdk/configurations/bitbucket.py +0 -3
- alita_sdk/configurations/confluence.py +76 -42
- alita_sdk/configurations/figma.py +76 -0
- alita_sdk/configurations/gitlab.py +17 -5
- alita_sdk/configurations/openapi.py +329 -0
- alita_sdk/configurations/qtest.py +72 -1
- alita_sdk/configurations/report_portal.py +96 -0
- alita_sdk/configurations/sharepoint.py +148 -0
- alita_sdk/configurations/testio.py +83 -0
- alita_sdk/runtime/clients/artifact.py +3 -3
- alita_sdk/runtime/clients/client.py +353 -48
- alita_sdk/runtime/clients/sandbox_client.py +0 -21
- alita_sdk/runtime/langchain/_constants_bkup.py +1318 -0
- alita_sdk/runtime/langchain/assistant.py +123 -26
- alita_sdk/runtime/langchain/constants.py +642 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +103 -60
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLinesLoader.py +77 -0
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +6 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +226 -7
- alita_sdk/runtime/langchain/document_loaders/AlitaTextLoader.py +5 -2
- alita_sdk/runtime/langchain/document_loaders/constants.py +12 -7
- alita_sdk/runtime/langchain/langraph_agent.py +279 -73
- alita_sdk/runtime/langchain/utils.py +82 -15
- alita_sdk/runtime/llms/preloaded.py +2 -6
- 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 +7 -0
- alita_sdk/runtime/toolkits/application.py +21 -9
- alita_sdk/runtime/toolkits/artifact.py +15 -5
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +139 -251
- alita_sdk/runtime/toolkits/mcp_config.py +1048 -0
- alita_sdk/runtime/toolkits/planning.py +178 -0
- alita_sdk/runtime/toolkits/skill_router.py +238 -0
- alita_sdk/runtime/toolkits/subgraph.py +251 -6
- alita_sdk/runtime/toolkits/tools.py +238 -32
- alita_sdk/runtime/toolkits/vectorstore.py +11 -5
- alita_sdk/runtime/tools/__init__.py +3 -1
- alita_sdk/runtime/tools/application.py +20 -6
- alita_sdk/runtime/tools/artifact.py +511 -28
- alita_sdk/runtime/tools/data_analysis.py +183 -0
- alita_sdk/runtime/tools/function.py +43 -15
- alita_sdk/runtime/tools/image_generation.py +50 -44
- alita_sdk/runtime/tools/llm.py +852 -67
- alita_sdk/runtime/tools/loop.py +3 -1
- alita_sdk/runtime/tools/loop_output.py +3 -1
- alita_sdk/runtime/tools/mcp_remote_tool.py +25 -10
- alita_sdk/runtime/tools/mcp_server_tool.py +7 -6
- 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 -4
- alita_sdk/runtime/tools/sandbox.py +9 -6
- alita_sdk/runtime/tools/skill_router.py +776 -0
- alita_sdk/runtime/tools/tool.py +3 -1
- alita_sdk/runtime/tools/vectorstore.py +7 -2
- alita_sdk/runtime/tools/vectorstore_base.py +51 -11
- alita_sdk/runtime/utils/AlitaCallback.py +137 -21
- alita_sdk/runtime/utils/constants.py +5 -1
- alita_sdk/runtime/utils/mcp_client.py +492 -0
- alita_sdk/runtime/utils/mcp_oauth.py +202 -5
- alita_sdk/runtime/utils/mcp_sse_client.py +36 -7
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/serialization.py +155 -0
- alita_sdk/runtime/utils/streamlit.py +6 -10
- alita_sdk/runtime/utils/toolkit_utils.py +16 -5
- alita_sdk/runtime/utils/utils.py +36 -0
- alita_sdk/tools/__init__.py +113 -29
- alita_sdk/tools/ado/repos/__init__.py +51 -33
- alita_sdk/tools/ado/repos/repos_wrapper.py +148 -89
- alita_sdk/tools/ado/test_plan/__init__.py +25 -9
- alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +23 -1
- alita_sdk/tools/ado/utils.py +1 -18
- alita_sdk/tools/ado/wiki/__init__.py +25 -8
- alita_sdk/tools/ado/wiki/ado_wrapper.py +291 -22
- alita_sdk/tools/ado/work_item/__init__.py +26 -9
- alita_sdk/tools/ado/work_item/ado_wrapper.py +56 -3
- alita_sdk/tools/advanced_jira_mining/__init__.py +11 -8
- alita_sdk/tools/aws/delta_lake/__init__.py +13 -9
- alita_sdk/tools/aws/delta_lake/tool.py +5 -1
- alita_sdk/tools/azure_ai/search/__init__.py +11 -8
- alita_sdk/tools/azure_ai/search/api_wrapper.py +1 -1
- alita_sdk/tools/base/tool.py +5 -1
- alita_sdk/tools/base_indexer_toolkit.py +170 -45
- alita_sdk/tools/bitbucket/__init__.py +17 -12
- alita_sdk/tools/bitbucket/api_wrapper.py +59 -11
- alita_sdk/tools/bitbucket/cloud_api_wrapper.py +49 -35
- alita_sdk/tools/browser/__init__.py +5 -4
- alita_sdk/tools/carrier/__init__.py +5 -6
- alita_sdk/tools/carrier/backend_reports_tool.py +6 -6
- alita_sdk/tools/carrier/run_ui_test_tool.py +6 -6
- alita_sdk/tools/carrier/ui_reports_tool.py +5 -5
- alita_sdk/tools/chunkers/__init__.py +3 -1
- alita_sdk/tools/chunkers/code/treesitter/treesitter.py +37 -13
- alita_sdk/tools/chunkers/sematic/json_chunker.py +1 -0
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
- alita_sdk/tools/chunkers/universal_chunker.py +270 -0
- alita_sdk/tools/cloud/aws/__init__.py +10 -7
- alita_sdk/tools/cloud/azure/__init__.py +10 -7
- alita_sdk/tools/cloud/gcp/__init__.py +10 -7
- alita_sdk/tools/cloud/k8s/__init__.py +10 -7
- alita_sdk/tools/code/linter/__init__.py +10 -8
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +10 -7
- alita_sdk/tools/code_indexer_toolkit.py +73 -23
- alita_sdk/tools/confluence/__init__.py +21 -15
- alita_sdk/tools/confluence/api_wrapper.py +78 -23
- alita_sdk/tools/confluence/loader.py +4 -2
- alita_sdk/tools/custom_open_api/__init__.py +12 -5
- alita_sdk/tools/elastic/__init__.py +11 -8
- alita_sdk/tools/elitea_base.py +493 -30
- alita_sdk/tools/figma/__init__.py +58 -11
- alita_sdk/tools/figma/api_wrapper.py +1235 -143
- alita_sdk/tools/figma/figma_client.py +73 -0
- alita_sdk/tools/figma/toon_tools.py +2748 -0
- alita_sdk/tools/github/__init__.py +13 -14
- alita_sdk/tools/github/github_client.py +224 -100
- alita_sdk/tools/github/graphql_client_wrapper.py +119 -33
- alita_sdk/tools/github/schemas.py +14 -5
- alita_sdk/tools/github/tool.py +5 -1
- alita_sdk/tools/github/tool_prompts.py +9 -22
- alita_sdk/tools/gitlab/__init__.py +15 -11
- alita_sdk/tools/gitlab/api_wrapper.py +207 -41
- alita_sdk/tools/gitlab_org/__init__.py +10 -8
- alita_sdk/tools/gitlab_org/api_wrapper.py +63 -64
- alita_sdk/tools/google/bigquery/__init__.py +13 -12
- alita_sdk/tools/google/bigquery/tool.py +5 -1
- alita_sdk/tools/google_places/__init__.py +10 -8
- alita_sdk/tools/google_places/api_wrapper.py +1 -1
- alita_sdk/tools/jira/__init__.py +17 -11
- alita_sdk/tools/jira/api_wrapper.py +91 -40
- alita_sdk/tools/keycloak/__init__.py +11 -8
- alita_sdk/tools/localgit/__init__.py +9 -3
- alita_sdk/tools/localgit/local_git.py +62 -54
- alita_sdk/tools/localgit/tool.py +5 -1
- alita_sdk/tools/memory/__init__.py +11 -3
- alita_sdk/tools/non_code_indexer_toolkit.py +1 -0
- alita_sdk/tools/ocr/__init__.py +11 -8
- alita_sdk/tools/openapi/__init__.py +490 -114
- alita_sdk/tools/openapi/api_wrapper.py +1368 -0
- alita_sdk/tools/openapi/tool.py +20 -0
- alita_sdk/tools/pandas/__init__.py +20 -12
- alita_sdk/tools/pandas/api_wrapper.py +38 -25
- alita_sdk/tools/pandas/dataframe/generator/base.py +3 -1
- alita_sdk/tools/postman/__init__.py +11 -11
- alita_sdk/tools/pptx/__init__.py +10 -9
- alita_sdk/tools/pptx/pptx_wrapper.py +1 -1
- alita_sdk/tools/qtest/__init__.py +30 -10
- alita_sdk/tools/qtest/api_wrapper.py +430 -13
- alita_sdk/tools/rally/__init__.py +10 -8
- alita_sdk/tools/rally/api_wrapper.py +1 -1
- alita_sdk/tools/report_portal/__init__.py +12 -9
- alita_sdk/tools/salesforce/__init__.py +10 -9
- alita_sdk/tools/servicenow/__init__.py +17 -14
- alita_sdk/tools/servicenow/api_wrapper.py +1 -1
- alita_sdk/tools/sharepoint/__init__.py +10 -8
- alita_sdk/tools/sharepoint/api_wrapper.py +4 -4
- alita_sdk/tools/slack/__init__.py +10 -8
- alita_sdk/tools/slack/api_wrapper.py +2 -2
- alita_sdk/tools/sql/__init__.py +11 -9
- alita_sdk/tools/testio/__init__.py +10 -8
- alita_sdk/tools/testrail/__init__.py +11 -8
- alita_sdk/tools/testrail/api_wrapper.py +1 -1
- alita_sdk/tools/utils/__init__.py +9 -4
- alita_sdk/tools/utils/content_parser.py +77 -3
- alita_sdk/tools/utils/text_operations.py +410 -0
- alita_sdk/tools/utils/tool_prompts.py +79 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +17 -13
- alita_sdk/tools/xray/__init__.py +12 -9
- alita_sdk/tools/yagmail/__init__.py +9 -3
- alita_sdk/tools/zephyr/__init__.py +9 -7
- alita_sdk/tools/zephyr_enterprise/__init__.py +11 -8
- alita_sdk/tools/zephyr_essential/__init__.py +10 -8
- alita_sdk/tools/zephyr_essential/api_wrapper.py +30 -13
- alita_sdk/tools/zephyr_essential/client.py +2 -2
- alita_sdk/tools/zephyr_scale/__init__.py +11 -9
- alita_sdk/tools/zephyr_scale/api_wrapper.py +2 -2
- alita_sdk/tools/zephyr_squad/__init__.py +10 -8
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/METADATA +147 -7
- alita_sdk-0.3.627.dist-info/RECORD +468 -0
- alita_sdk-0.3.627.dist-info/entry_points.txt +2 -0
- alita_sdk-0.3.462.dist-info/RECORD +0 -384
- alita_sdk-0.3.462.dist-info/entry_points.txt +0 -2
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.462.dist-info → alita_sdk-0.3.627.dist-info}/top_level.txt +0 -0
|
@@ -5,8 +5,9 @@ from ..base.tool import BaseAction
|
|
|
5
5
|
from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
6
6
|
|
|
7
7
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
8
|
-
from ..utils import clean_string,
|
|
8
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
9
9
|
from ...configurations.salesforce import SalesforceConfiguration
|
|
10
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
10
11
|
|
|
11
12
|
name = "salesforce"
|
|
12
13
|
|
|
@@ -19,11 +20,9 @@ def get_tools(tool):
|
|
|
19
20
|
|
|
20
21
|
class SalesforceToolkit(BaseToolkit):
|
|
21
22
|
tools: List[BaseTool] = []
|
|
22
|
-
toolkit_max_length: int = 0
|
|
23
23
|
@staticmethod
|
|
24
24
|
def toolkit_config_schema() -> BaseModel:
|
|
25
25
|
available_tools = {x['name']: x['args_schema'].schema() for x in SalesforceApiWrapper.model_construct().get_available_tools()}
|
|
26
|
-
SalesforceToolkit.toolkit_max_length = get_max_toolkit_length(available_tools)
|
|
27
26
|
return create_model(
|
|
28
27
|
name,
|
|
29
28
|
api_version=(str, Field(description="Salesforce API Version", default='v59.0')),
|
|
@@ -31,7 +30,6 @@ class SalesforceToolkit(BaseToolkit):
|
|
|
31
30
|
selected_tools=(List[Literal[tuple(available_tools)]], Field(default=[], json_schema_extra={'args_schemas': available_tools})),
|
|
32
31
|
__config__=ConfigDict(json_schema_extra={'metadata': {
|
|
33
32
|
"label": "Salesforce", "icon_url": "salesforce-icon.svg",
|
|
34
|
-
"max_length": SalesforceToolkit.toolkit_max_length,
|
|
35
33
|
"categories": ["other"],
|
|
36
34
|
"extra_categories": ["customer relationship management", "cloud computing", "marketing automation", "salesforce"]
|
|
37
35
|
}})
|
|
@@ -48,18 +46,21 @@ class SalesforceToolkit(BaseToolkit):
|
|
|
48
46
|
**kwargs.get('salesforce_configuration', {}),
|
|
49
47
|
}
|
|
50
48
|
api_wrapper = SalesforceApiWrapper(**wrapper_payload)
|
|
51
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
52
49
|
tools = []
|
|
53
50
|
|
|
54
51
|
for tool in api_wrapper.get_available_tools():
|
|
55
52
|
if selected_tools and tool["name"] not in selected_tools:
|
|
56
53
|
continue
|
|
57
|
-
|
|
54
|
+
description = f"Salesforce Tool: {tool['description']}"
|
|
55
|
+
if toolkit_name:
|
|
56
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
57
|
+
description = description[:1000]
|
|
58
58
|
tools.append(BaseAction(
|
|
59
59
|
api_wrapper=api_wrapper,
|
|
60
|
-
name=
|
|
61
|
-
description=
|
|
62
|
-
args_schema=tool["args_schema"]
|
|
60
|
+
name=tool["name"],
|
|
61
|
+
description=description,
|
|
62
|
+
args_schema=tool["args_schema"],
|
|
63
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
63
64
|
))
|
|
64
65
|
|
|
65
66
|
return cls(tools=tools)
|
|
@@ -7,35 +7,33 @@ from ..base.tool import BaseAction
|
|
|
7
7
|
from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
8
8
|
|
|
9
9
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
10
|
-
from ..utils import clean_string, TOOLKIT_SPLITTER, get_max_toolkit_length
|
|
11
10
|
from ...configurations.service_now import ServiceNowConfiguration
|
|
11
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
name = "service_now"
|
|
15
15
|
|
|
16
16
|
def get_tools(tool):
|
|
17
|
+
settings = tool.get('settings') or {}
|
|
18
|
+
|
|
17
19
|
return ServiceNowToolkit().get_toolkit(
|
|
18
|
-
selected_tools=
|
|
19
|
-
instance_alias=
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
response_fields=tool['settings'].get('response_fields', None),
|
|
20
|
+
selected_tools=settings.get('selected_tools', []),
|
|
21
|
+
instance_alias=settings.get('instance_alias', None),
|
|
22
|
+
servicenow_configuration=settings.get('servicenow_configuration', None),
|
|
23
|
+
response_fields=settings.get('response_fields', None),
|
|
23
24
|
toolkit_name=tool.get('toolkit_name')
|
|
24
25
|
).get_tools()
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
class ServiceNowToolkit(BaseToolkit):
|
|
28
29
|
tools: List[BaseTool] = []
|
|
29
|
-
toolkit_max_length: int = 0
|
|
30
30
|
|
|
31
31
|
@staticmethod
|
|
32
32
|
def toolkit_config_schema() -> BaseModel:
|
|
33
33
|
selected_tools = {x['name']: x['args_schema'].schema() for x in
|
|
34
34
|
ServiceNowAPIWrapper.model_construct().get_available_tools()}
|
|
35
|
-
ServiceNowToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
36
35
|
return create_model(
|
|
37
36
|
name,
|
|
38
|
-
name=(str, Field(description="Toolkit name")),
|
|
39
37
|
response_fields=(Optional[str], Field(description="Response fields", default=None)),
|
|
40
38
|
servicenow_configuration=(ServiceNowConfiguration, Field(description="ServiceNow Configuration",
|
|
41
39
|
json_schema_extra={
|
|
@@ -47,7 +45,6 @@ class ServiceNowToolkit(BaseToolkit):
|
|
|
47
45
|
'metadata': {
|
|
48
46
|
"label": "ServiceNow",
|
|
49
47
|
"icon_url": "service-now.svg",
|
|
50
|
-
"max_length": ServiceNowToolkit.toolkit_max_length,
|
|
51
48
|
"hidden": False,
|
|
52
49
|
"sections": {
|
|
53
50
|
"auth": {
|
|
@@ -79,18 +76,24 @@ class ServiceNowToolkit(BaseToolkit):
|
|
|
79
76
|
**kwargs['servicenow_configuration'],
|
|
80
77
|
}
|
|
81
78
|
servicenow_api_wrapper = ServiceNowAPIWrapper(**wrapper_payload)
|
|
82
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
83
79
|
available_tools = servicenow_api_wrapper.get_available_tools()
|
|
84
80
|
tools = []
|
|
85
81
|
for tool in available_tools:
|
|
86
82
|
if selected_tools:
|
|
87
83
|
if tool["name"] not in selected_tools:
|
|
88
84
|
continue
|
|
85
|
+
base_url = getattr(servicenow_api_wrapper, "base_url", "") or ""
|
|
86
|
+
description = tool.get("description", "") if isinstance(tool, dict) else ""
|
|
87
|
+
if toolkit_name:
|
|
88
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
89
|
+
description = f"ServiceNow: {base_url}\n{description}".strip()
|
|
90
|
+
description = description[:1000]
|
|
89
91
|
tools.append(BaseAction(
|
|
90
92
|
api_wrapper=servicenow_api_wrapper,
|
|
91
|
-
name=
|
|
92
|
-
description=
|
|
93
|
-
args_schema=tool["args_schema"]
|
|
93
|
+
name=tool["name"],
|
|
94
|
+
description=description,
|
|
95
|
+
args_schema=tool["args_schema"],
|
|
96
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
94
97
|
))
|
|
95
98
|
return cls(tools=tools)
|
|
96
99
|
|
|
@@ -58,7 +58,7 @@ class ServiceNowAPIWrapper(BaseToolApiWrapper):
|
|
|
58
58
|
password = SecretStr(values['password'])
|
|
59
59
|
username = values['username']
|
|
60
60
|
cls.fields = values.get('fields', ['sys_id', 'number', 'state', 'short_description', 'description', 'priority', 'category', 'urgency', 'impact', 'creation_date'])
|
|
61
|
-
cls.client = ServiceNowClient(base_url, (username, password.get_secret_value()))
|
|
61
|
+
cls.client = ServiceNowClient(instance=base_url, auth=(username, password.get_secret_value()))
|
|
62
62
|
return values
|
|
63
63
|
|
|
64
64
|
def get_incidents(self, data: Optional[Dict[str, Any]] = None) -> ToolException | str:
|
|
@@ -5,9 +5,10 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
|
5
5
|
from .api_wrapper import SharepointApiWrapper
|
|
6
6
|
from ..base.tool import BaseAction
|
|
7
7
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
8
|
-
from ..utils import clean_string,
|
|
8
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
9
9
|
from ...configurations.pgvector import PgVectorConfiguration
|
|
10
10
|
from ...configurations.sharepoint import SharepointConfiguration
|
|
11
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
11
12
|
|
|
12
13
|
name = "sharepoint"
|
|
13
14
|
|
|
@@ -29,12 +30,10 @@ def get_tools(tool):
|
|
|
29
30
|
|
|
30
31
|
class SharepointToolkit(BaseToolkit):
|
|
31
32
|
tools: List[BaseTool] = []
|
|
32
|
-
toolkit_max_length: int = 0
|
|
33
33
|
|
|
34
34
|
@staticmethod
|
|
35
35
|
def toolkit_config_schema() -> BaseModel:
|
|
36
36
|
selected_tools = {x['name']: x['args_schema'].schema() for x in SharepointApiWrapper.model_construct().get_available_tools()}
|
|
37
|
-
SharepointToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
38
37
|
return create_model(
|
|
39
38
|
name,
|
|
40
39
|
sharepoint_configuration=(SharepointConfiguration, Field(description="SharePoint Configuration", json_schema_extra={'configuration_types': ['sharepoint']})),
|
|
@@ -48,7 +47,6 @@ class SharepointToolkit(BaseToolkit):
|
|
|
48
47
|
__config__=ConfigDict(json_schema_extra={
|
|
49
48
|
'metadata': {
|
|
50
49
|
"label": "Sharepoint", "icon_url": "sharepoint.svg",
|
|
51
|
-
"max_length": SharepointToolkit.toolkit_max_length,
|
|
52
50
|
"categories": ["office"],
|
|
53
51
|
"extra_categories": ["microsoft", "cloud storage", "team collaboration", "content management"]
|
|
54
52
|
}})
|
|
@@ -65,18 +63,22 @@ class SharepointToolkit(BaseToolkit):
|
|
|
65
63
|
**(kwargs.get('pgvector_configuration') or {}),
|
|
66
64
|
}
|
|
67
65
|
sharepoint_api_wrapper = SharepointApiWrapper(**wrapper_payload)
|
|
68
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
69
66
|
available_tools = sharepoint_api_wrapper.get_available_tools()
|
|
70
67
|
tools = []
|
|
71
68
|
for tool in available_tools:
|
|
72
69
|
if selected_tools:
|
|
73
70
|
if tool["name"] not in selected_tools:
|
|
74
71
|
continue
|
|
72
|
+
description = f"Sharepoint {sharepoint_api_wrapper.site_url}\n{tool['description']}"
|
|
73
|
+
if toolkit_name:
|
|
74
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
75
|
+
description = description[:1000]
|
|
75
76
|
tools.append(BaseAction(
|
|
76
77
|
api_wrapper=sharepoint_api_wrapper,
|
|
77
|
-
name=
|
|
78
|
-
description=
|
|
79
|
-
args_schema=tool["args_schema"]
|
|
78
|
+
name=tool["name"],
|
|
79
|
+
description=description,
|
|
80
|
+
args_schema=tool["args_schema"],
|
|
81
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
80
82
|
))
|
|
81
83
|
return cls(tools=tools)
|
|
82
84
|
|
|
@@ -20,7 +20,7 @@ NoInput = create_model(
|
|
|
20
20
|
ReadList = create_model(
|
|
21
21
|
"ReadList",
|
|
22
22
|
list_title=(str, Field(description="Name of a Sharepoint list to be read.")),
|
|
23
|
-
limit=(Optional[int], Field(description="Limit (maximum number) of list items to be returned", default=1000))
|
|
23
|
+
limit=(Optional[int], Field(description="Limit (maximum number) of list items to be returned", default=1000, gt=0))
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
GetFiles = create_model(
|
|
@@ -30,7 +30,7 @@ GetFiles = create_model(
|
|
|
30
30
|
"Can be called with synonyms, such as First, Top, etc., "
|
|
31
31
|
"or can be reflected just by a number for example 'Top 10 files'. "
|
|
32
32
|
"Use default value if not specified in a query WITH NO EXTRA "
|
|
33
|
-
"CONFIRMATION FROM A USER", default=100)),
|
|
33
|
+
"CONFIRMATION FROM A USER", default=100, gt=0)),
|
|
34
34
|
)
|
|
35
35
|
|
|
36
36
|
ReadDocument = create_model(
|
|
@@ -271,13 +271,13 @@ class SharepointApiWrapper(NonCodeIndexerToolkit):
|
|
|
271
271
|
file_name = file.get('Name', '')
|
|
272
272
|
|
|
273
273
|
# Check if file should be skipped based on skip_extensions
|
|
274
|
-
if any(re.match(pattern.replace('
|
|
274
|
+
if any(re.match(re.escape(pattern).replace(r'\*', '.*') + '$', file_name, re.IGNORECASE)
|
|
275
275
|
for pattern in skip_extensions):
|
|
276
276
|
continue
|
|
277
277
|
|
|
278
278
|
# Check if file should be included based on include_extensions
|
|
279
279
|
# If include_extensions is empty, process all files (that weren't skipped)
|
|
280
|
-
if include_extensions and not (any(re.match(pattern.replace('
|
|
280
|
+
if include_extensions and not (any(re.match(re.escape(pattern).replace(r'\*', '.*') + '$', file_name, re.IGNORECASE)
|
|
281
281
|
for pattern in include_extensions)):
|
|
282
282
|
continue
|
|
283
283
|
|
|
@@ -12,9 +12,10 @@ from pydantic import create_model, BaseModel, Field
|
|
|
12
12
|
from ..base.tool import BaseAction
|
|
13
13
|
|
|
14
14
|
from .api_wrapper import SlackApiWrapper
|
|
15
|
-
from ..utils import
|
|
15
|
+
from ..utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
16
16
|
from slack_sdk.errors import SlackApiError
|
|
17
17
|
from slack_sdk import WebClient
|
|
18
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
18
19
|
|
|
19
20
|
name = "slack"
|
|
20
21
|
|
|
@@ -28,12 +29,10 @@ def get_tools(tool):
|
|
|
28
29
|
|
|
29
30
|
class SlackToolkit(BaseToolkit):
|
|
30
31
|
tools: List[BaseTool] = []
|
|
31
|
-
toolkit_max_length: int = 0
|
|
32
32
|
|
|
33
33
|
@staticmethod
|
|
34
34
|
def toolkit_config_schema() -> BaseModel:
|
|
35
35
|
selected_tools = {x['name']: x['args_schema'].schema() for x in SlackApiWrapper.model_construct().get_available_tools()}
|
|
36
|
-
SlackToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
37
36
|
|
|
38
37
|
@check_connection_response
|
|
39
38
|
def check_connection(self):
|
|
@@ -59,7 +58,6 @@ class SlackToolkit(BaseToolkit):
|
|
|
59
58
|
'metadata': {
|
|
60
59
|
"label": "Slack",
|
|
61
60
|
"icon_url": "slack-icon.svg",
|
|
62
|
-
"max_length": SlackToolkit.toolkit_max_length,
|
|
63
61
|
"categories": ["communication"],
|
|
64
62
|
"extra_categories": ["slack", "chat", "messaging", "collaboration"],
|
|
65
63
|
}
|
|
@@ -79,17 +77,21 @@ class SlackToolkit(BaseToolkit):
|
|
|
79
77
|
**kwargs['slack_configuration'],
|
|
80
78
|
}
|
|
81
79
|
slack_api_wrapper = SlackApiWrapper(**wrapper_payload)
|
|
82
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
83
80
|
available_tools = slack_api_wrapper.get_available_tools()
|
|
84
81
|
tools = []
|
|
85
82
|
for tool in available_tools:
|
|
86
83
|
if selected_tools and tool["name"] not in selected_tools:
|
|
87
84
|
continue
|
|
88
|
-
|
|
85
|
+
description = f"Slack Tool: {tool['description']}"
|
|
86
|
+
if toolkit_name:
|
|
87
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
88
|
+
description = description[:1000]
|
|
89
|
+
tools.append(BaseAction(
|
|
89
90
|
api_wrapper=slack_api_wrapper,
|
|
90
|
-
name=
|
|
91
|
-
description=
|
|
91
|
+
name=tool["name"],
|
|
92
|
+
description=description,
|
|
92
93
|
args_schema=tool["args_schema"],
|
|
94
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
93
95
|
))
|
|
94
96
|
return cls(tools=tools)
|
|
95
97
|
|
|
@@ -17,8 +17,8 @@ SendMessageModel = create_model(
|
|
|
17
17
|
|
|
18
18
|
ReadMessagesModel = create_model(
|
|
19
19
|
"ReadMessagesModel",
|
|
20
|
-
channel_id=(Optional[str], Field(default=None,description="Channel ID, user ID, or conversation ID to read messages from. (like C12345678 for public channels, D12345678 for DMs)")),
|
|
21
|
-
limit=(int, Field(default=10, description="The number of messages to fetch (default is 10)."))
|
|
20
|
+
channel_id=(Optional[str], Field(default=None,description="Channel ID, user ID, or conversation ID to read messages from. (like C12345678 for public channels, D12345678 for DMs)")),
|
|
21
|
+
limit=(int, Field(default=10, description="The number of messages to fetch (default is 10).", gt=0))
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
CreateChannelModel = create_model(
|
alita_sdk/tools/sql/__init__.py
CHANGED
|
@@ -7,8 +7,9 @@ from .api_wrapper import SQLApiWrapper
|
|
|
7
7
|
from ..base.tool import BaseAction
|
|
8
8
|
from .models import SQLDialect
|
|
9
9
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
10
|
-
from ..utils import
|
|
10
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
11
11
|
from ...configurations.sql import SqlConfiguration
|
|
12
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
12
13
|
|
|
13
14
|
name = "sql"
|
|
14
15
|
|
|
@@ -24,16 +25,14 @@ def get_tools(tool):
|
|
|
24
25
|
|
|
25
26
|
class SQLToolkit(BaseToolkit):
|
|
26
27
|
tools: list[BaseTool] = []
|
|
27
|
-
toolkit_max_length: int = 0
|
|
28
28
|
|
|
29
29
|
@staticmethod
|
|
30
30
|
def toolkit_config_schema() -> BaseModel:
|
|
31
31
|
selected_tools = {x['name']: x['args_schema'].schema() for x in SQLApiWrapper.model_construct().get_available_tools()}
|
|
32
|
-
SQLToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
33
32
|
supported_dialects = (d.value for d in SQLDialect)
|
|
34
33
|
return create_model(
|
|
35
34
|
name,
|
|
36
|
-
dialect=(Literal[tuple(supported_dialects)], Field(description="Database dialect (mysql or postgres)")),
|
|
35
|
+
dialect=(Literal[tuple(supported_dialects)], Field(default=SQLDialect.POSTGRES.value, description="Database dialect (mysql or postgres)")),
|
|
37
36
|
database_name=(str, Field(description="Database name")),
|
|
38
37
|
sql_configuration=(SqlConfiguration, Field(description="SQL Configuration", json_schema_extra={'configuration_types': ['sql']})),
|
|
39
38
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
@@ -42,7 +41,6 @@ class SQLToolkit(BaseToolkit):
|
|
|
42
41
|
'metadata':
|
|
43
42
|
{
|
|
44
43
|
"label": "SQL", "icon_url": "sql-icon.svg",
|
|
45
|
-
"max_length": SQLToolkit.toolkit_max_length,
|
|
46
44
|
"categories": ["development"],
|
|
47
45
|
"extra_categories": ["sql", "data management", "data analysis"]}})
|
|
48
46
|
)
|
|
@@ -57,17 +55,21 @@ class SQLToolkit(BaseToolkit):
|
|
|
57
55
|
**kwargs.get('sql_configuration', {}),
|
|
58
56
|
}
|
|
59
57
|
sql_api_wrapper = SQLApiWrapper(**wrapper_payload)
|
|
60
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
61
58
|
available_tools = sql_api_wrapper.get_available_tools()
|
|
62
59
|
tools = []
|
|
63
60
|
for tool in available_tools:
|
|
64
61
|
if selected_tools and tool["name"] not in selected_tools:
|
|
65
62
|
continue
|
|
63
|
+
description = f"{tool['description']}\nDatabase: {sql_api_wrapper.database_name}. Host: {sql_api_wrapper.host}"
|
|
64
|
+
if toolkit_name:
|
|
65
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
66
|
+
description = description[:1000]
|
|
66
67
|
tools.append(BaseAction(
|
|
67
68
|
api_wrapper=sql_api_wrapper,
|
|
68
|
-
name=
|
|
69
|
-
description=
|
|
70
|
-
args_schema=tool["args_schema"]
|
|
69
|
+
name=tool["name"],
|
|
70
|
+
description=description,
|
|
71
|
+
args_schema=tool["args_schema"],
|
|
72
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
71
73
|
))
|
|
72
74
|
return cls(tools=tools)
|
|
73
75
|
|
|
@@ -6,8 +6,9 @@ from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
|
6
6
|
from .api_wrapper import TestIOApiWrapper
|
|
7
7
|
from ..base.tool import BaseAction
|
|
8
8
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
9
|
-
from ..utils import clean_string,
|
|
9
|
+
from ..utils import clean_string, get_max_toolkit_length
|
|
10
10
|
from ...configurations.testio import TestIOConfiguration
|
|
11
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
11
12
|
|
|
12
13
|
name = "testio"
|
|
13
14
|
|
|
@@ -19,8 +20,6 @@ def get_tools(tool):
|
|
|
19
20
|
).get_tools()
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
TOOLKIT_MAX_LENGTH = 25
|
|
23
|
-
|
|
24
23
|
class TestIOToolkit(BaseToolkit):
|
|
25
24
|
tools: list[BaseTool] = []
|
|
26
25
|
|
|
@@ -33,7 +32,6 @@ class TestIOToolkit(BaseToolkit):
|
|
|
33
32
|
testio_configuration=(TestIOConfiguration, Field(description="TestIO Configuration", json_schema_extra={'configuration_types': ['testio']})),
|
|
34
33
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
35
34
|
__config__=ConfigDict(json_schema_extra={'metadata': {"label": "TestIO", "icon_url": "testio-icon.svg",
|
|
36
|
-
"max_length": TOOLKIT_MAX_LENGTH,
|
|
37
35
|
"categories": ["testing"],
|
|
38
36
|
"extra_categories": ["test automation", "test case management", "test planning"]}})
|
|
39
37
|
)
|
|
@@ -48,17 +46,21 @@ class TestIOToolkit(BaseToolkit):
|
|
|
48
46
|
**kwargs.get('testio_configuration', {}),
|
|
49
47
|
}
|
|
50
48
|
testio_api_wrapper = TestIOApiWrapper(**wrapper_payload)
|
|
51
|
-
prefix = clean_string(toolkit_name, TOOLKIT_MAX_LENGTH) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
52
49
|
available_tools = testio_api_wrapper.get_available_tools()
|
|
53
50
|
tools = []
|
|
54
51
|
for tool in available_tools:
|
|
55
52
|
if selected_tools and tool["name"] not in selected_tools:
|
|
56
53
|
continue
|
|
54
|
+
description = tool["description"]
|
|
55
|
+
if toolkit_name:
|
|
56
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
57
|
+
description = description[:1000]
|
|
57
58
|
tools.append(BaseAction(
|
|
58
59
|
api_wrapper=testio_api_wrapper,
|
|
59
|
-
name=
|
|
60
|
-
description=
|
|
61
|
-
args_schema=tool["args_schema"]
|
|
60
|
+
name=tool["name"],
|
|
61
|
+
description=description,
|
|
62
|
+
args_schema=tool["args_schema"],
|
|
63
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
62
64
|
))
|
|
63
65
|
return cls(tools=tools)
|
|
64
66
|
|
|
@@ -7,9 +7,10 @@ import requests
|
|
|
7
7
|
from .api_wrapper import TestrailAPIWrapper
|
|
8
8
|
from ..base.tool import BaseAction
|
|
9
9
|
from ..elitea_base import filter_missconfigured_index_tools
|
|
10
|
-
from ..utils import clean_string,
|
|
10
|
+
from ..utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
11
11
|
from ...configurations.testrail import TestRailConfiguration
|
|
12
12
|
from ...configurations.pgvector import PgVectorConfiguration
|
|
13
|
+
from ...runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
13
14
|
|
|
14
15
|
name = "testrail"
|
|
15
16
|
|
|
@@ -31,12 +32,10 @@ def get_tools(tool):
|
|
|
31
32
|
|
|
32
33
|
class TestrailToolkit(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 TestrailAPIWrapper.model_construct().get_available_tools()}
|
|
39
|
-
TestrailToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
40
39
|
m = create_model(
|
|
41
40
|
name,
|
|
42
41
|
testrail_configuration=(Optional[TestRailConfiguration], Field(description="TestRail Configuration", json_schema_extra={'configuration_types': ['testrail']})),
|
|
@@ -47,7 +46,6 @@ class TestrailToolkit(BaseToolkit):
|
|
|
47
46
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
48
47
|
__config__=ConfigDict(json_schema_extra={'metadata':
|
|
49
48
|
{"label": "Testrail", "icon_url": "testrail-icon.svg",
|
|
50
|
-
"max_length": TestrailToolkit.toolkit_max_length,
|
|
51
49
|
"categories": ["test management"],
|
|
52
50
|
"extra_categories": ["quality assurance", "test case management", "test planning"]
|
|
53
51
|
}})
|
|
@@ -77,18 +75,23 @@ class TestrailToolkit(BaseToolkit):
|
|
|
77
75
|
**(kwargs.get('pgvector_configuration') or {}),
|
|
78
76
|
}
|
|
79
77
|
testrail_api_wrapper = TestrailAPIWrapper(**wrapper_payload)
|
|
80
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
81
78
|
available_tools = testrail_api_wrapper.get_available_tools()
|
|
82
79
|
tools = []
|
|
83
80
|
for tool in available_tools:
|
|
84
81
|
if selected_tools:
|
|
85
82
|
if tool["name"] not in selected_tools:
|
|
86
83
|
continue
|
|
84
|
+
description = tool["description"]
|
|
85
|
+
if toolkit_name:
|
|
86
|
+
description = f"Toolkit: {toolkit_name}\n{description}"
|
|
87
|
+
description = description + "\nTestrail instance: " + testrail_api_wrapper.url
|
|
88
|
+
description = description[:1000]
|
|
87
89
|
tools.append(BaseAction(
|
|
88
90
|
api_wrapper=testrail_api_wrapper,
|
|
89
|
-
name=
|
|
90
|
-
description=
|
|
91
|
-
args_schema=tool["args_schema"]
|
|
91
|
+
name=tool["name"],
|
|
92
|
+
description=description,
|
|
93
|
+
args_schema=tool["args_schema"],
|
|
94
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
92
95
|
))
|
|
93
96
|
return cls(tools=tools)
|
|
94
97
|
|
|
@@ -697,7 +697,7 @@ class TestrailAPIWrapper(NonCodeIndexerToolkit):
|
|
|
697
697
|
'id': str(case.get('id', '')),
|
|
698
698
|
IndexerKeywords.UPDATED_ON.value: case.get('updated_on') or -1,
|
|
699
699
|
'labels': [lbl['title'] for lbl in case.get('labels', [])],
|
|
700
|
-
'type':
|
|
700
|
+
'type': "testrail_test_case",
|
|
701
701
|
'priority': case.get('priority_id') or -1,
|
|
702
702
|
'milestone': case.get('milestone_id') or -1,
|
|
703
703
|
'estimate': case.get('estimate') or '',
|
|
@@ -7,6 +7,8 @@ import requests
|
|
|
7
7
|
from pydantic import create_model, Field
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
# DEPRECATED: Tool names no longer use prefixes
|
|
11
|
+
# Kept for backward compatibility only
|
|
10
12
|
TOOLKIT_SPLITTER = "___"
|
|
11
13
|
TOOL_NAME_LIMIT = 64
|
|
12
14
|
|
|
@@ -22,10 +24,13 @@ def clean_string(s: str, max_length: int = 0):
|
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
def get_max_toolkit_length(selected_tools: Any):
|
|
25
|
-
"""Calculates the maximum length of the toolkit name
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
"""DEPRECATED: Calculates the maximum length of the toolkit name.
|
|
28
|
+
|
|
29
|
+
This function is deprecated as tool names no longer use prefixes.
|
|
30
|
+
Returns a fixed value for backward compatibility.
|
|
31
|
+
"""
|
|
32
|
+
# Return a reasonable default since we no longer use prefixes
|
|
33
|
+
return 50
|
|
29
34
|
|
|
30
35
|
|
|
31
36
|
def parse_list(list_str: str = None) -> List[str]:
|
|
@@ -109,7 +109,15 @@ def parse_file_content(file_name=None, file_content=None, is_capture_image: bool
|
|
|
109
109
|
loader_extra_config=loader_kwargs,
|
|
110
110
|
llm=llm)
|
|
111
111
|
except Exception as e:
|
|
112
|
-
|
|
112
|
+
# Surface full underlying error message (including nested causes) so that
|
|
113
|
+
# JSONDecodeError or other specific issues are not hidden behind
|
|
114
|
+
# generic RuntimeError messages from loaders.
|
|
115
|
+
root_msg = str(e)
|
|
116
|
+
if getattr(e, "__cause__", None):
|
|
117
|
+
root_msg = f"{root_msg} | Cause: {e.__cause__}"
|
|
118
|
+
return ToolException(
|
|
119
|
+
f"Error reading file ({file_name or file_path}) content. Make sure these types are supported: {root_msg}"
|
|
120
|
+
)
|
|
113
121
|
|
|
114
122
|
def load_file_docs(file_name=None, file_content=None, is_capture_image: bool = False, page_number: int = None,
|
|
115
123
|
sheet_name: str = None, llm=None, file_path: str = None, excel_by_sheets: bool = False) -> List[Document] | ToolException:
|
|
@@ -130,7 +138,38 @@ def load_file_docs(file_name=None, file_content=None, is_capture_image: bool = F
|
|
|
130
138
|
|
|
131
139
|
def get_loader_kwargs(loader_object, file_name=None, file_content=None, is_capture_image: bool = False, page_number: int = None,
|
|
132
140
|
sheet_name: str = None, llm=None, file_path: str = None, excel_by_sheets: bool = False, prompt=None):
|
|
133
|
-
|
|
141
|
+
"""Build loader kwargs safely without deepcopying non-picklable objects like LLMs.
|
|
142
|
+
|
|
143
|
+
We avoid copying keys that are going to be overridden by this function anyway
|
|
144
|
+
(file_path, file_content, file_name, extract_images, llm, page_number,
|
|
145
|
+
sheet_name, excel_by_sheets, prompt, row_content, json_documents) to
|
|
146
|
+
prevent errors such as `cannot pickle '_thread.RLock' object` when an LLM
|
|
147
|
+
or client with internal locks is stored in the original kwargs.
|
|
148
|
+
"""
|
|
149
|
+
if not loader_object:
|
|
150
|
+
raise ToolException("Loader configuration is missing.")
|
|
151
|
+
|
|
152
|
+
original_kwargs = loader_object.get("kwargs", {}) or {}
|
|
153
|
+
|
|
154
|
+
# Keys that will be overwritten below – skip them when copying
|
|
155
|
+
overridden_keys = {
|
|
156
|
+
"file_path",
|
|
157
|
+
"file_content",
|
|
158
|
+
"file_name",
|
|
159
|
+
"extract_images",
|
|
160
|
+
"llm",
|
|
161
|
+
"page_number",
|
|
162
|
+
"sheet_name",
|
|
163
|
+
"excel_by_sheets",
|
|
164
|
+
"prompt",
|
|
165
|
+
"row_content",
|
|
166
|
+
"json_documents",
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Build a safe shallow copy without overridden keys to avoid deepcopy
|
|
170
|
+
# of potentially non-picklable objects (e.g., llm with internal RLock).
|
|
171
|
+
loader_kwargs = {k: v for k, v in original_kwargs.items() if k not in overridden_keys}
|
|
172
|
+
|
|
134
173
|
loader_kwargs.update({
|
|
135
174
|
"file_path": file_path,
|
|
136
175
|
"file_content": file_content,
|
|
@@ -212,6 +251,41 @@ def load_content_from_bytes(file_content: bytes, extension: str = None, loader_e
|
|
|
212
251
|
if temp_file_path and os.path.exists(temp_file_path):
|
|
213
252
|
os.remove(temp_file_path)
|
|
214
253
|
|
|
254
|
+
|
|
255
|
+
def _load_content_from_bytes_with_prompt(file_content: bytes, extension: str = None, loader_extra_config: dict = None, llm = None, prompt: str = image_processing_prompt) -> str:
|
|
256
|
+
"""Internal helper that behaves like load_content_from_bytes but also propagates prompt.
|
|
257
|
+
|
|
258
|
+
This keeps the public load_content_from_bytes API unchanged while allowing newer
|
|
259
|
+
code paths to pass an explicit prompt through to the loader.
|
|
260
|
+
"""
|
|
261
|
+
temp_file_path = None
|
|
262
|
+
try:
|
|
263
|
+
with tempfile.NamedTemporaryFile(mode='w+b', delete=False, suffix=extension or '') as temp_file:
|
|
264
|
+
temp_file.write(file_content)
|
|
265
|
+
temp_file.flush()
|
|
266
|
+
temp_file_path = temp_file.name
|
|
267
|
+
|
|
268
|
+
# Use prepare_loader so that prompt and other kwargs are handled consistently
|
|
269
|
+
loader = prepare_loader(
|
|
270
|
+
file_name=None,
|
|
271
|
+
file_content=None,
|
|
272
|
+
is_capture_image=loader_extra_config.get('extract_images') if loader_extra_config else False,
|
|
273
|
+
page_number=loader_extra_config.get('page_number') if loader_extra_config else None,
|
|
274
|
+
sheet_name=loader_extra_config.get('sheet_name') if loader_extra_config else None,
|
|
275
|
+
llm=llm or (loader_extra_config.get('llm') if loader_extra_config else None),
|
|
276
|
+
file_path=temp_file_path,
|
|
277
|
+
excel_by_sheets=loader_extra_config.get('excel_by_sheets') if loader_extra_config else False,
|
|
278
|
+
prompt=prompt or (loader_extra_config.get('prompt') if loader_extra_config else image_processing_prompt),
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
documents = loader.load()
|
|
282
|
+
page_contents = [doc.page_content for doc in documents]
|
|
283
|
+
return "\n".join(page_contents)
|
|
284
|
+
finally:
|
|
285
|
+
if temp_file_path and os.path.exists(temp_file_path):
|
|
286
|
+
os.remove(temp_file_path)
|
|
287
|
+
|
|
288
|
+
|
|
215
289
|
def process_document_by_type(content, extension_source: str, document: Document = None, llm = None, chunking_config=None) \
|
|
216
290
|
-> Generator[Document, None, None]:
|
|
217
291
|
"""Process the content of a file based on its type using a configured loader cosidering the origin document."""
|
|
@@ -338,4 +412,4 @@ def file_extension_by_chunker(chunker_name: str) -> str | None:
|
|
|
338
412
|
return ".xml"
|
|
339
413
|
if name == "csv":
|
|
340
414
|
return ".csv"
|
|
341
|
-
return None
|
|
415
|
+
return None
|