alita-sdk 0.3.257__py3-none-any.whl → 0.3.584__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.
Potentially problematic release.
This version of alita-sdk might be problematic. Click here for more details.
- 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 +3794 -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 +323 -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 +493 -105
- alita_sdk/runtime/langchain/utils.py +118 -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 +25 -9
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +782 -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 +1032 -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/constants.py +5 -1
- 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 +16 -19
- alita_sdk/tools/ado/repos/repos_wrapper.py +12 -20
- alita_sdk/tools/ado/test_plan/__init__.py +27 -8
- alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +56 -28
- alita_sdk/tools/ado/wiki/__init__.py +28 -12
- alita_sdk/tools/ado/wiki/ado_wrapper.py +114 -40
- alita_sdk/tools/ado/work_item/__init__.py +28 -12
- alita_sdk/tools/ado/work_item/ado_wrapper.py +95 -11
- alita_sdk/tools/advanced_jira_mining/__init__.py +13 -8
- alita_sdk/tools/aws/delta_lake/__init__.py +15 -11
- alita_sdk/tools/aws/delta_lake/tool.py +5 -1
- alita_sdk/tools/azure_ai/search/__init__.py +14 -8
- alita_sdk/tools/base/tool.py +5 -1
- alita_sdk/tools/base_indexer_toolkit.py +454 -110
- alita_sdk/tools/bitbucket/__init__.py +28 -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 +12 -7
- alita_sdk/tools/cloud/azure/__init__.py +12 -7
- alita_sdk/tools/cloud/gcp/__init__.py +12 -7
- alita_sdk/tools/cloud/k8s/__init__.py +12 -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 +21 -13
- alita_sdk/tools/code_indexer_toolkit.py +199 -0
- alita_sdk/tools/confluence/__init__.py +22 -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 +12 -5
- alita_sdk/tools/elastic/__init__.py +11 -8
- alita_sdk/tools/elitea_base.py +546 -64
- alita_sdk/tools/figma/__init__.py +60 -11
- alita_sdk/tools/figma/api_wrapper.py +1400 -167
- alita_sdk/tools/figma/figma_client.py +73 -0
- alita_sdk/tools/figma/toon_tools.py +2748 -0
- alita_sdk/tools/github/__init__.py +18 -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 +19 -13
- alita_sdk/tools/gitlab/api_wrapper.py +256 -80
- alita_sdk/tools/gitlab_org/__init__.py +14 -10
- alita_sdk/tools/google/bigquery/__init__.py +14 -13
- alita_sdk/tools/google/bigquery/tool.py +5 -1
- alita_sdk/tools/google_places/__init__.py +21 -11
- alita_sdk/tools/jira/__init__.py +22 -11
- alita_sdk/tools/jira/api_wrapper.py +315 -168
- 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 +38 -14
- alita_sdk/tools/non_code_indexer_toolkit.py +7 -2
- alita_sdk/tools/ocr/__init__.py +11 -8
- alita_sdk/tools/openapi/__init__.py +491 -106
- alita_sdk/tools/openapi/api_wrapper.py +1357 -0
- alita_sdk/tools/openapi/tool.py +20 -0
- alita_sdk/tools/pandas/__init__.py +20 -12
- 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 +11 -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 +11 -10
- alita_sdk/tools/qtest/__init__.py +22 -14
- alita_sdk/tools/qtest/api_wrapper.py +1784 -88
- alita_sdk/tools/rally/__init__.py +13 -10
- alita_sdk/tools/report_portal/__init__.py +23 -16
- alita_sdk/tools/salesforce/__init__.py +22 -16
- alita_sdk/tools/servicenow/__init__.py +21 -16
- alita_sdk/tools/servicenow/api_wrapper.py +1 -1
- alita_sdk/tools/sharepoint/__init__.py +17 -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 +13 -8
- alita_sdk/tools/sql/__init__.py +22 -19
- alita_sdk/tools/sql/api_wrapper.py +71 -23
- alita_sdk/tools/testio/__init__.py +21 -13
- alita_sdk/tools/testrail/__init__.py +13 -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 +241 -55
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +83 -27
- alita_sdk/tools/xray/__init__.py +18 -14
- alita_sdk/tools/xray/api_wrapper.py +58 -113
- alita_sdk/tools/yagmail/__init__.py +9 -3
- alita_sdk/tools/zephyr/__init__.py +12 -7
- alita_sdk/tools/zephyr_enterprise/__init__.py +16 -9
- alita_sdk/tools/zephyr_enterprise/api_wrapper.py +30 -15
- alita_sdk/tools/zephyr_essential/__init__.py +16 -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 +13 -8
- alita_sdk/tools/zephyr_scale/api_wrapper.py +39 -31
- alita_sdk/tools/zephyr_squad/__init__.py +12 -7
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/METADATA +184 -37
- alita_sdk-0.3.584.dist-info/RECORD +452 -0
- alita_sdk-0.3.584.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.584.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.257.dist-info → alita_sdk-0.3.584.dist-info}/top_level.txt +0 -0
|
@@ -12,7 +12,9 @@ logger = logging.getLogger(__name__)
|
|
|
12
12
|
|
|
13
13
|
def instantiate_toolkit_with_client(toolkit_config: Dict[str, Any],
|
|
14
14
|
llm_client: Any,
|
|
15
|
-
alita_client: Optional[Any] = None
|
|
15
|
+
alita_client: Optional[Any] = None,
|
|
16
|
+
mcp_tokens: Optional[Dict[str, Any]] = None,
|
|
17
|
+
use_prefix: bool = False) -> List[Any]:
|
|
16
18
|
"""
|
|
17
19
|
Instantiate a toolkit with LLM client support.
|
|
18
20
|
|
|
@@ -22,20 +24,25 @@ def instantiate_toolkit_with_client(toolkit_config: Dict[str, Any],
|
|
|
22
24
|
Args:
|
|
23
25
|
toolkit_config: Configuration dictionary for the toolkit
|
|
24
26
|
llm_client: LLM client instance for tools that need LLM capabilities
|
|
25
|
-
|
|
27
|
+
alita_client: Optional additional client instance
|
|
28
|
+
mcp_tokens: Optional dictionary of MCP OAuth tokens by server URL
|
|
29
|
+
use_prefix: If True, tools get prefixed with toolkit_name to prevent collisions
|
|
30
|
+
(for agent use). If False, tools use base names only (for testing interface).
|
|
31
|
+
Default False for backward compatibility with testing.
|
|
26
32
|
|
|
27
33
|
Returns:
|
|
28
34
|
List of instantiated tools from the toolkit
|
|
29
35
|
|
|
30
36
|
Raises:
|
|
31
37
|
ValueError: If required configuration or client is missing
|
|
38
|
+
McpAuthorizationRequired: If MCP server requires OAuth authorization
|
|
32
39
|
Exception: If toolkit instantiation fails
|
|
33
40
|
"""
|
|
41
|
+
toolkit_name = toolkit_config.get('toolkit_name', 'unknown')
|
|
34
42
|
try:
|
|
35
43
|
from ..toolkits.tools import get_tools
|
|
36
44
|
|
|
37
|
-
toolkit_name
|
|
38
|
-
if not toolkit_name:
|
|
45
|
+
if not toolkit_name or toolkit_name == 'unknown':
|
|
39
46
|
raise ValueError("toolkit_name is required in configuration")
|
|
40
47
|
|
|
41
48
|
if not llm_client:
|
|
@@ -46,18 +53,22 @@ def instantiate_toolkit_with_client(toolkit_config: Dict[str, Any],
|
|
|
46
53
|
# Log the configuration being used
|
|
47
54
|
logger.info(f"Instantiating toolkit {toolkit_name} with LLM client")
|
|
48
55
|
logger.debug(f"Toolkit {toolkit_name} configuration: {toolkit_config}")
|
|
49
|
-
|
|
56
|
+
|
|
57
|
+
# Use toolkit type from config, or fall back to lowercase toolkit name
|
|
58
|
+
toolkit_type = toolkit_config.get('type', toolkit_name.lower())
|
|
59
|
+
|
|
50
60
|
# Create a tool configuration dict with required fields
|
|
61
|
+
# Note: MCP toolkit always requires toolkit_name, other toolkits respect use_prefix flag
|
|
51
62
|
tool_config = {
|
|
52
63
|
'id': toolkit_config.get('id', random.randint(1, 1000000)),
|
|
53
|
-
'type': toolkit_config.get('type',
|
|
64
|
+
'type': toolkit_config.get('type', toolkit_type),
|
|
54
65
|
'settings': settings,
|
|
55
|
-
'toolkit_name': toolkit_name
|
|
66
|
+
'toolkit_name': toolkit_name if (use_prefix or toolkit_type == 'mcp') else None
|
|
56
67
|
}
|
|
57
68
|
|
|
58
69
|
# Get tools using the toolkit configuration with clients
|
|
59
|
-
# Parameter order: get_tools(tools_list, alita_client, llm, memory_store)
|
|
60
|
-
tools = get_tools([tool_config], alita_client, llm_client)
|
|
70
|
+
# Parameter order: get_tools(tools_list, alita_client, llm, memory_store, debug_mode, mcp_tokens)
|
|
71
|
+
tools = get_tools([tool_config], alita_client, llm_client, mcp_tokens=mcp_tokens)
|
|
61
72
|
|
|
62
73
|
if not tools:
|
|
63
74
|
logger.warning(f"No tools returned for toolkit {toolkit_name}")
|
|
@@ -67,6 +78,14 @@ def instantiate_toolkit_with_client(toolkit_config: Dict[str, Any],
|
|
|
67
78
|
return tools
|
|
68
79
|
|
|
69
80
|
except Exception as e:
|
|
81
|
+
# Re-raise McpAuthorizationRequired without logging as error
|
|
82
|
+
from ..utils.mcp_oauth import McpAuthorizationRequired
|
|
83
|
+
|
|
84
|
+
if isinstance(e, McpAuthorizationRequired):
|
|
85
|
+
logger.info(f"Toolkit {toolkit_name} requires MCP OAuth authorization")
|
|
86
|
+
raise
|
|
87
|
+
|
|
88
|
+
# Log and re-raise other errors
|
|
70
89
|
logger.error(f"Error instantiating toolkit {toolkit_name} with client: {str(e)}")
|
|
71
90
|
raise
|
|
72
91
|
|
alita_sdk/runtime/utils/utils.py
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import logging
|
|
1
3
|
import re
|
|
2
4
|
from enum import Enum
|
|
5
|
+
from typing import Any
|
|
3
6
|
|
|
7
|
+
# DEPRECATED: Tool names no longer use prefixes
|
|
8
|
+
# Kept for backward compatibility only
|
|
4
9
|
TOOLKIT_SPLITTER = "___"
|
|
5
10
|
|
|
6
11
|
class IndexerKeywords(Enum):
|
|
@@ -9,6 +14,12 @@ class IndexerKeywords(Enum):
|
|
|
9
14
|
PARENT = 'parent_id'
|
|
10
15
|
# DEPENDENCY_ID = 'dependency_id'
|
|
11
16
|
UPDATED_ON = 'updated_on'
|
|
17
|
+
CONTENT_IN_BYTES = 'loader_content'
|
|
18
|
+
CONTENT_FILE_NAME = 'loader_content_type'
|
|
19
|
+
INDEX_META_TYPE = 'index_meta'
|
|
20
|
+
INDEX_META_IN_PROGRESS = 'in_progress'
|
|
21
|
+
INDEX_META_COMPLETED = 'completed'
|
|
22
|
+
INDEX_META_FAILED = 'failed'
|
|
12
23
|
|
|
13
24
|
# This pattern matches characters that are NOT alphanumeric, underscores, or hyphens
|
|
14
25
|
clean_string_pattern = re.compile(r'[^a-zA-Z0-9_.-]')
|
|
@@ -18,3 +29,40 @@ def clean_string(s: str) -> str:
|
|
|
18
29
|
# Replace these characters with an empty string
|
|
19
30
|
cleaned_string = re.sub(clean_string_pattern, '', s)
|
|
20
31
|
return cleaned_string
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def clean_node_str(s: str) -> str:
|
|
35
|
+
"""Cleans a node string by removing all non-alphanumeric characters except underscores and spaces."""
|
|
36
|
+
cleaned_string = re.sub(r'[^\w\s]', '', s)
|
|
37
|
+
return cleaned_string
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def resolve_image_from_cache(client: Any, cached_image_id: str) -> bytes:
|
|
41
|
+
"""
|
|
42
|
+
Resolve cached_image_id from client's image cache and return decoded binary data.
|
|
43
|
+
|
|
44
|
+
Args:
|
|
45
|
+
client: AlitaClient instance with _generated_images_cache attribute
|
|
46
|
+
cached_image_id: The cached image ID to resolve
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
bytes: Decoded binary image data
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: If cached_image_id not found or decoding fails
|
|
53
|
+
"""
|
|
54
|
+
cache = getattr(client, '_generated_images_cache', {})
|
|
55
|
+
|
|
56
|
+
if cached_image_id not in cache:
|
|
57
|
+
raise ValueError(f"Image reference '{cached_image_id}' not found. The image may have expired.")
|
|
58
|
+
|
|
59
|
+
cached_data = cache[cached_image_id]
|
|
60
|
+
base64_data = cached_data.get('base64_data', '')
|
|
61
|
+
logging.debug(f"Resolved cached_image_id '{cached_image_id}' from cache (length: {len(base64_data)} chars)")
|
|
62
|
+
# Decode base64 to binary data for image files
|
|
63
|
+
try:
|
|
64
|
+
binary_data = base64.b64decode(base64_data)
|
|
65
|
+
logging.debug(f"Decoded base64 to binary data ({len(binary_data)} bytes)")
|
|
66
|
+
return binary_data
|
|
67
|
+
except Exception as e:
|
|
68
|
+
raise ValueError(f"Failed to decode image data for '{cached_image_id}': {e}")
|
alita_sdk/tools/__init__.py
CHANGED
|
@@ -13,6 +13,30 @@ AVAILABLE_TOOLS = {}
|
|
|
13
13
|
AVAILABLE_TOOLKITS = {}
|
|
14
14
|
FAILED_IMPORTS = {}
|
|
15
15
|
|
|
16
|
+
|
|
17
|
+
def _inject_toolkit_id(tool_conf: dict, toolkit_tools) -> None:
|
|
18
|
+
"""Inject `toolkit_id` into tools that expose `api_wrapper.toolkit_id`.
|
|
19
|
+
|
|
20
|
+
This reads 'id' from the tool configuration and, if it is an integer,
|
|
21
|
+
assigns it to the 'toolkit_id' attribute of the 'api_wrapper' for each
|
|
22
|
+
tool in 'toolkit_tools' that supports it.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
tool_conf: Raw tool configuration item from 'tools_list'.
|
|
26
|
+
toolkit_tools: List of instantiated tools produced by a toolkit.
|
|
27
|
+
"""
|
|
28
|
+
toolkit_id = tool_conf.get('id')
|
|
29
|
+
if isinstance(toolkit_id, int):
|
|
30
|
+
for t in toolkit_tools:
|
|
31
|
+
if hasattr(t, 'api_wrapper') and hasattr(t.api_wrapper, 'toolkit_id'):
|
|
32
|
+
t.api_wrapper.toolkit_id = toolkit_id
|
|
33
|
+
else:
|
|
34
|
+
logger.error(
|
|
35
|
+
f"Toolkit ID is missing or not an integer for tool "
|
|
36
|
+
f"`{tool_conf.get('type', '')}` with name `{tool_conf.get('name', '')}`"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
16
40
|
def _safe_import_tool(tool_name, module_path, get_tools_name=None, toolkit_class_name=None):
|
|
17
41
|
"""Safely import a tool module and register available functions/classes."""
|
|
18
42
|
try:
|
|
@@ -21,6 +45,12 @@ def _safe_import_tool(tool_name, module_path, get_tools_name=None, toolkit_class
|
|
|
21
45
|
imported = {}
|
|
22
46
|
if get_tools_name and hasattr(module, get_tools_name):
|
|
23
47
|
imported['get_tools'] = getattr(module, get_tools_name)
|
|
48
|
+
|
|
49
|
+
if hasattr(module, 'get_toolkit'):
|
|
50
|
+
imported['get_toolkit'] = getattr(module, 'get_toolkit')
|
|
51
|
+
|
|
52
|
+
if hasattr(module, 'get_toolkit_available_tools'):
|
|
53
|
+
imported['get_toolkit_available_tools'] = getattr(module, 'get_toolkit_available_tools')
|
|
24
54
|
|
|
25
55
|
if toolkit_class_name and hasattr(module, toolkit_class_name):
|
|
26
56
|
imported['toolkit_class'] = getattr(module, toolkit_class_name)
|
|
@@ -34,9 +64,10 @@ def _safe_import_tool(tool_name, module_path, get_tools_name=None, toolkit_class
|
|
|
34
64
|
FAILED_IMPORTS[tool_name] = str(e)
|
|
35
65
|
logger.debug(f"Failed to import {tool_name}: {e}")
|
|
36
66
|
|
|
67
|
+
|
|
37
68
|
# Safe imports for all tools
|
|
38
69
|
_safe_import_tool('github', 'github', 'get_tools', 'AlitaGitHubToolkit')
|
|
39
|
-
_safe_import_tool('openapi', 'openapi', 'get_tools')
|
|
70
|
+
_safe_import_tool('openapi', 'openapi', 'get_tools', 'AlitaOpenAPIToolkit')
|
|
40
71
|
_safe_import_tool('jira', 'jira', 'get_tools', 'JiraToolkit')
|
|
41
72
|
_safe_import_tool('confluence', 'confluence', 'get_tools', 'ConfluenceToolkit')
|
|
42
73
|
_safe_import_tool('service_now', 'servicenow', 'get_tools', 'ServiceNowToolkit')
|
|
@@ -67,11 +98,11 @@ _safe_import_tool('aws', 'cloud.aws', None, 'AWSToolkit')
|
|
|
67
98
|
_safe_import_tool('azure', 'cloud.azure', None, 'AzureToolkit')
|
|
68
99
|
_safe_import_tool('gcp', 'cloud.gcp', None, 'GCPToolkit')
|
|
69
100
|
_safe_import_tool('k8s', 'cloud.k8s', None, 'KubernetesToolkit')
|
|
70
|
-
_safe_import_tool('custom_open_api', 'custom_open_api', None, 'OpenApiToolkit')
|
|
101
|
+
# _safe_import_tool('custom_open_api', 'custom_open_api', None, 'OpenApiToolkit')
|
|
71
102
|
_safe_import_tool('elastic', 'elastic', None, 'ElasticToolkit')
|
|
72
103
|
_safe_import_tool('keycloak', 'keycloak', None, 'KeycloakToolkit')
|
|
73
104
|
_safe_import_tool('localgit', 'localgit', None, 'AlitaLocalGitToolkit')
|
|
74
|
-
|
|
105
|
+
# pandas toolkit removed - use Data Analysis internal tool instead
|
|
75
106
|
_safe_import_tool('azure_search', 'azure_ai.search', 'get_tools', 'AzureSearchToolkit')
|
|
76
107
|
_safe_import_tool('figma', 'figma', 'get_tools', 'FigmaToolkit')
|
|
77
108
|
_safe_import_tool('salesforce', 'salesforce', 'get_tools', 'SalesforceToolkit')
|
|
@@ -79,7 +110,6 @@ _safe_import_tool('carrier', 'carrier', 'get_tools', 'AlitaCarrierToolkit')
|
|
|
79
110
|
_safe_import_tool('ocr', 'ocr', 'get_tools', 'OCRToolkit')
|
|
80
111
|
_safe_import_tool('pptx', 'pptx', 'get_tools', 'PPTXToolkit')
|
|
81
112
|
_safe_import_tool('postman', 'postman', 'get_tools', 'PostmanToolkit')
|
|
82
|
-
_safe_import_tool('memory', 'memory', 'get_tools', 'MemoryToolkit')
|
|
83
113
|
_safe_import_tool('zephyr_squad', 'zephyr_squad', 'get_tools', 'ZephyrSquadToolkit')
|
|
84
114
|
_safe_import_tool('zephyr_essential', 'zephyr_essential', 'get_tools', 'ZephyrEssentialToolkit')
|
|
85
115
|
_safe_import_tool('slack', 'slack', 'get_tools', 'SlackToolkit')
|
|
@@ -91,62 +121,81 @@ available_count = len(AVAILABLE_TOOLS)
|
|
|
91
121
|
total_attempted = len(AVAILABLE_TOOLS) + len(FAILED_IMPORTS)
|
|
92
122
|
logger.info(f"Tool imports completed: {available_count}/{total_attempted} successful")
|
|
93
123
|
|
|
124
|
+
# Import community module to trigger community toolkit registration
|
|
125
|
+
try:
|
|
126
|
+
from alita_sdk import community # noqa: F401
|
|
127
|
+
logger.debug("Community toolkits registered successfully")
|
|
128
|
+
except ImportError as e:
|
|
129
|
+
logger.debug(f"Community module not available: {e}")
|
|
130
|
+
|
|
131
|
+
|
|
94
132
|
def get_tools(tools_list, alita, llm, store: Optional[BaseStore] = None, *args, **kwargs):
|
|
95
133
|
tools = []
|
|
134
|
+
|
|
96
135
|
for tool in tools_list:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if isinstance(tool_name, str) and tool_name.startswith('_'):
|
|
100
|
-
raise ValueError(f"Tool name '{tool_name}' from toolkit '{tool.get('type', '')}' cannot start with '_'")
|
|
101
|
-
|
|
102
|
-
tool['settings']['alita'] = alita
|
|
103
|
-
tool['settings']['llm'] = llm
|
|
104
|
-
tool['settings']['store'] = store
|
|
105
|
-
tool_type = tool['type']
|
|
136
|
+
toolkit_tools = []
|
|
137
|
+
settings = tool.get('settings')
|
|
106
138
|
|
|
107
|
-
#
|
|
108
|
-
if
|
|
109
|
-
|
|
139
|
+
# Skip tools without settings early
|
|
140
|
+
if not settings:
|
|
141
|
+
logger.warning(f"Tool '{tool.get('type', '')}' has no settings, skipping...")
|
|
142
|
+
continue
|
|
110
143
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
144
|
+
# Validate tool names once
|
|
145
|
+
selected_tools = settings.get('selected_tools', [])
|
|
146
|
+
invalid_tools = [name for name in selected_tools if isinstance(name, str) and name.startswith('_')]
|
|
147
|
+
if invalid_tools:
|
|
148
|
+
raise ValueError(f"Tool names {invalid_tools} from toolkit '{tool.get('type', '')}' cannot start with '_'")
|
|
116
149
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
150
|
+
# Cache tool type and add common settings
|
|
151
|
+
tool_type = tool['type']
|
|
152
|
+
settings['alita'] = alita
|
|
153
|
+
settings['llm'] = llm
|
|
154
|
+
settings['store'] = store
|
|
155
|
+
|
|
156
|
+
# Set pgvector collection schema if present
|
|
157
|
+
if settings.get('pgvector_configuration'):
|
|
158
|
+
# Use tool id if available, otherwise use toolkit_name or type as fallback
|
|
159
|
+
collection_id = tool.get('id') or tool.get('toolkit_name') or tool_type
|
|
160
|
+
settings['pgvector_configuration']['collection_schema'] = str(collection_id)
|
|
120
161
|
|
|
121
|
-
# Handle ADO
|
|
162
|
+
# Handle ADO special cases
|
|
163
|
+
if tool_type in ['ado_boards', 'ado_wiki', 'ado_plans']:
|
|
164
|
+
toolkit_tools.extend(AVAILABLE_TOOLS['ado']['get_tools'](tool_type, tool))
|
|
122
165
|
elif tool_type in ['ado_repos', 'azure_devops_repos'] and 'ado_repos' in AVAILABLE_TOOLS:
|
|
123
166
|
try:
|
|
124
|
-
|
|
125
|
-
tools.extend(get_tools_func(tool))
|
|
167
|
+
toolkit_tools.extend(AVAILABLE_TOOLS['ado_repos']['get_tools'](tool))
|
|
126
168
|
except Exception as e:
|
|
127
169
|
logger.error(f"Error getting ADO repos tools: {e}")
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
elif
|
|
170
|
+
elif tool_type == 'mcp':
|
|
171
|
+
logger.debug(f"Skipping MCP toolkit '{tool.get('toolkit_name')}' - handled by runtime toolkit system")
|
|
172
|
+
elif tool_type == 'planning':
|
|
173
|
+
logger.debug(f"Skipping planning toolkit '{tool.get('toolkit_name')}' - handled by runtime toolkit system")
|
|
174
|
+
elif tool_type in AVAILABLE_TOOLS and 'get_tools' in AVAILABLE_TOOLS[tool_type]:
|
|
175
|
+
try:
|
|
176
|
+
toolkit_tools.extend(AVAILABLE_TOOLS[tool_type]['get_tools'](tool))
|
|
177
|
+
except Exception as e:
|
|
178
|
+
logger.error(f"Error getting tools for {tool_type}: {e}")
|
|
179
|
+
raise ToolException(f"Error getting tools for {tool_type}: {e}")
|
|
180
|
+
elif settings.get("module"):
|
|
131
181
|
try:
|
|
132
|
-
settings = tool.get("settings", {})
|
|
133
182
|
mod = import_module(settings.pop("module"))
|
|
134
183
|
tkitclass = getattr(mod, settings.pop("class"))
|
|
135
|
-
|
|
136
|
-
get_toolkit_params = tool["settings"].copy()
|
|
184
|
+
get_toolkit_params = settings.copy()
|
|
137
185
|
get_toolkit_params["name"] = tool.get("name")
|
|
138
|
-
#
|
|
139
186
|
toolkit = tkitclass.get_toolkit(**get_toolkit_params)
|
|
140
|
-
|
|
187
|
+
toolkit_tools.extend(toolkit.get_tools())
|
|
141
188
|
except Exception as e:
|
|
142
189
|
logger.error(f"Error in getting custom toolkit: {e}")
|
|
143
|
-
|
|
144
190
|
else:
|
|
145
|
-
# Tool not available or not found
|
|
146
191
|
if tool_type in FAILED_IMPORTS:
|
|
147
192
|
logger.warning(f"Tool '{tool_type}' is not available: {FAILED_IMPORTS[tool_type]}")
|
|
148
193
|
else:
|
|
149
194
|
logger.warning(f"Unknown tool type: {tool_type}")
|
|
195
|
+
#
|
|
196
|
+
# Always inject toolkit_id to each tool
|
|
197
|
+
_inject_toolkit_id(tool, toolkit_tools)
|
|
198
|
+
tools.extend(toolkit_tools)
|
|
150
199
|
|
|
151
200
|
return tools
|
|
152
201
|
|
|
@@ -166,6 +215,18 @@ def get_toolkits():
|
|
|
166
215
|
logger.info(f"Successfully loaded {len(toolkit_configs)} toolkit configurations")
|
|
167
216
|
return toolkit_configs
|
|
168
217
|
|
|
218
|
+
def instantiate_toolkit(tool_config):
|
|
219
|
+
"""Instantiate a toolkit from its configuration."""
|
|
220
|
+
tool_type = tool_config.get('type')
|
|
221
|
+
|
|
222
|
+
if tool_type in AVAILABLE_TOOLS:
|
|
223
|
+
tool_module = AVAILABLE_TOOLS[tool_type]
|
|
224
|
+
|
|
225
|
+
if 'get_toolkit' in tool_module:
|
|
226
|
+
return tool_module['get_toolkit'](tool_config)
|
|
227
|
+
|
|
228
|
+
raise ValueError(f"Toolkit type '{tool_type}' does not support direct instantiation or is not available.")
|
|
229
|
+
|
|
169
230
|
def get_available_tools():
|
|
170
231
|
"""Return list of available tool types."""
|
|
171
232
|
return list(AVAILABLE_TOOLS.keys())
|
|
@@ -182,6 +243,42 @@ def get_available_toolkit_models():
|
|
|
182
243
|
"""Return dict with available toolkit classes."""
|
|
183
244
|
return deepcopy(AVAILABLE_TOOLS)
|
|
184
245
|
|
|
246
|
+
|
|
247
|
+
def get_toolkit_available_tools(toolkit_type: str, settings: dict) -> dict:
|
|
248
|
+
"""Return dynamic available tools + per-tool JSON schemas for a toolkit instance.
|
|
249
|
+
|
|
250
|
+
This is the single SDK entrypoint used by backend services (e.g. indexer_worker)
|
|
251
|
+
when the UI needs spec/instance-dependent tool enumeration. Toolkits that don't
|
|
252
|
+
support dynamic enumeration should return an empty payload.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
toolkit_type: toolkit type string (e.g. 'openapi')
|
|
256
|
+
settings: persisted toolkit settings
|
|
257
|
+
|
|
258
|
+
Returns:
|
|
259
|
+
{
|
|
260
|
+
"tools": [{"name": str, "description": str}],
|
|
261
|
+
"args_schemas": {"tool_name": <json schema dict>}
|
|
262
|
+
}
|
|
263
|
+
"""
|
|
264
|
+
toolkit_type = (toolkit_type or '').strip().lower()
|
|
265
|
+
if not isinstance(settings, dict):
|
|
266
|
+
settings = {}
|
|
267
|
+
|
|
268
|
+
tool_module = AVAILABLE_TOOLS.get(toolkit_type) or {}
|
|
269
|
+
enumerator = tool_module.get('get_toolkit_available_tools')
|
|
270
|
+
if not callable(enumerator):
|
|
271
|
+
return {"tools": [], "args_schemas": {}}
|
|
272
|
+
|
|
273
|
+
try:
|
|
274
|
+
result = enumerator(settings)
|
|
275
|
+
if not isinstance(result, dict):
|
|
276
|
+
return {"tools": [], "args_schemas": {}, "error": "Invalid response from toolkit enumerator"}
|
|
277
|
+
return result
|
|
278
|
+
except Exception as e: # pylint: disable=W0718
|
|
279
|
+
logger.exception("Failed to compute available tools for toolkit_type=%s", toolkit_type)
|
|
280
|
+
return {"tools": [], "args_schemas": {}, "error": str(e)}
|
|
281
|
+
|
|
185
282
|
def diagnose_imports():
|
|
186
283
|
"""Print diagnostic information about tool imports."""
|
|
187
284
|
available_count = len(AVAILABLE_TOOLS)
|
|
@@ -218,6 +315,7 @@ def diagnose_imports():
|
|
|
218
315
|
__all__ = [
|
|
219
316
|
'get_tools',
|
|
220
317
|
'get_toolkits',
|
|
318
|
+
'get_toolkit_available_tools',
|
|
221
319
|
'get_available_tools',
|
|
222
320
|
'get_failed_imports',
|
|
223
321
|
'get_available_toolkits',
|
alita_sdk/tools/ado/__init__.py
CHANGED
|
@@ -9,16 +9,16 @@ def get_tools(tool_type, tool):
|
|
|
9
9
|
config_dict = {
|
|
10
10
|
# common
|
|
11
11
|
"selected_tools": tool['settings'].get('selected_tools', []),
|
|
12
|
-
"organization_url": tool['settings']['organization_url'],
|
|
13
12
|
"ado_configuration": tool['settings']['ado_configuration'],
|
|
14
13
|
"limit": tool['settings'].get('limit', 5),
|
|
15
14
|
"toolkit_name": tool.get('toolkit_name', ''),
|
|
16
15
|
# indexer settings
|
|
16
|
+
"alita": tool['settings'].get('alita', None),
|
|
17
17
|
"llm": tool['settings'].get('llm', None),
|
|
18
18
|
"pgvector_configuration": tool['settings'].get('pgvector_configuration', {}),
|
|
19
19
|
"collection_name": tool['toolkit_name'],
|
|
20
20
|
"doctype": 'doc',
|
|
21
|
-
"embedding_model": tool['settings'].get('
|
|
21
|
+
"embedding_model": tool['settings'].get('embedding_model'),
|
|
22
22
|
"vectorstore_type": "PGVector"
|
|
23
23
|
}
|
|
24
24
|
if tool_type == 'ado_plans':
|
|
@@ -5,16 +5,18 @@ from pydantic import BaseModel, Field, create_model
|
|
|
5
5
|
|
|
6
6
|
import requests
|
|
7
7
|
|
|
8
|
+
from ...elitea_base import filter_missconfigured_index_tools
|
|
8
9
|
from ....configurations.ado import AdoReposConfiguration
|
|
9
10
|
from ....configurations.pgvector import PgVectorConfiguration
|
|
10
11
|
from ...base.tool import BaseAction
|
|
11
12
|
from .repos_wrapper import ReposApiWrapper
|
|
12
|
-
from ...utils import clean_string,
|
|
13
|
+
from ...utils import clean_string, get_max_toolkit_length, check_connection_response
|
|
14
|
+
from ....runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
13
15
|
|
|
14
16
|
name = "ado_repos"
|
|
15
17
|
|
|
16
18
|
|
|
17
|
-
def
|
|
19
|
+
def get_toolkit(tool) -> BaseToolkit:
|
|
18
20
|
return AzureDevOpsReposToolkit().get_toolkit(
|
|
19
21
|
selected_tools=tool['settings'].get('selected_tools', []),
|
|
20
22
|
ado_repos_configuration=tool['settings']['ado_repos_configuration'],
|
|
@@ -23,26 +25,21 @@ def _get_toolkit(tool) -> BaseToolkit:
|
|
|
23
25
|
active_branch=tool['settings'].get('active_branch', ""),
|
|
24
26
|
toolkit_name=tool['settings'].get('toolkit_name', ""),
|
|
25
27
|
pgvector_configuration=tool['settings'].get('pgvector_configuration', {}),
|
|
26
|
-
collection_name=tool['toolkit_name'],
|
|
27
|
-
doctype='code',
|
|
28
28
|
embedding_model=tool['settings'].get('embedding_model'),
|
|
29
|
-
|
|
29
|
+
collection_name=tool['toolkit_name'],
|
|
30
|
+
alita=tool['settings'].get('alita', None),
|
|
31
|
+
llm=tool['settings'].get('llm', None),
|
|
30
32
|
)
|
|
31
33
|
|
|
32
|
-
def get_toolkit():
|
|
33
|
-
return AzureDevOpsReposToolkit.toolkit_config_schema()
|
|
34
|
-
|
|
35
34
|
def get_tools(tool):
|
|
36
|
-
return
|
|
35
|
+
return get_toolkit(tool).get_tools()
|
|
37
36
|
|
|
38
37
|
class AzureDevOpsReposToolkit(BaseToolkit):
|
|
39
38
|
tools: List[BaseTool] = []
|
|
40
|
-
toolkit_max_length: int = 0
|
|
41
39
|
|
|
42
40
|
@staticmethod
|
|
43
41
|
def toolkit_config_schema() -> BaseModel:
|
|
44
42
|
selected_tools = {x['name']: x['args_schema'].schema() for x in ReposApiWrapper.model_construct().get_available_tools()}
|
|
45
|
-
AzureDevOpsReposToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
46
43
|
m = create_model(
|
|
47
44
|
name,
|
|
48
45
|
ado_repos_configuration=(AdoReposConfiguration, Field(description="Ado Repos configuration", default=None,
|
|
@@ -62,11 +59,6 @@ class AzureDevOpsReposToolkit(BaseToolkit):
|
|
|
62
59
|
"icon_url": "ado-repos-icon.svg",
|
|
63
60
|
"categories": ["code repositories"],
|
|
64
61
|
"extra_categories": ["code", "repository", "version control"],
|
|
65
|
-
# "configuration_group": {
|
|
66
|
-
# "name": "ado_repos",
|
|
67
|
-
# "label": "Azure DevOps Repositories",
|
|
68
|
-
# "icon_url": "ado-repos-icon.svg",
|
|
69
|
-
# }
|
|
70
62
|
}}}
|
|
71
63
|
)
|
|
72
64
|
|
|
@@ -83,6 +75,7 @@ class AzureDevOpsReposToolkit(BaseToolkit):
|
|
|
83
75
|
return m
|
|
84
76
|
|
|
85
77
|
@classmethod
|
|
78
|
+
@filter_missconfigured_index_tools
|
|
86
79
|
def get_toolkit(cls, selected_tools: list[str] | None = None, toolkit_name: Optional[str] = None, **kwargs):
|
|
87
80
|
from os import environ
|
|
88
81
|
|
|
@@ -101,17 +94,21 @@ class AzureDevOpsReposToolkit(BaseToolkit):
|
|
|
101
94
|
azure_devops_repos_wrapper = ReposApiWrapper(**wrapper_payload)
|
|
102
95
|
available_tools = azure_devops_repos_wrapper.get_available_tools()
|
|
103
96
|
tools = []
|
|
104
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
105
97
|
for tool in available_tools:
|
|
106
98
|
if selected_tools:
|
|
107
99
|
if tool["name"] not in selected_tools:
|
|
108
100
|
continue
|
|
101
|
+
description = tool["description"] + f"\nADO instance: {azure_devops_repos_wrapper.organization_url}/{azure_devops_repos_wrapper.project}"
|
|
102
|
+
if toolkit_name:
|
|
103
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
104
|
+
description = description[:1000]
|
|
109
105
|
tools.append(
|
|
110
106
|
BaseAction(
|
|
111
107
|
api_wrapper=azure_devops_repos_wrapper,
|
|
112
|
-
name=
|
|
113
|
-
description=
|
|
108
|
+
name=tool["name"],
|
|
109
|
+
description=description,
|
|
114
110
|
args_schema=tool["args_schema"],
|
|
111
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
115
112
|
)
|
|
116
113
|
)
|
|
117
114
|
return cls(tools=tools)
|
|
@@ -24,7 +24,8 @@ from msrest.authentication import BasicAuthentication
|
|
|
24
24
|
from pydantic import Field, PrivateAttr, create_model, model_validator, SecretStr
|
|
25
25
|
|
|
26
26
|
from ..utils import extract_old_new_pairs, generate_diff, get_content_from_generator
|
|
27
|
-
from ...
|
|
27
|
+
from ...code_indexer_toolkit import CodeIndexerToolkit
|
|
28
|
+
from ...utils.available_tools_decorator import extend_with_parent_available_tools
|
|
28
29
|
|
|
29
30
|
logger = logging.getLogger(__name__)
|
|
30
31
|
|
|
@@ -110,8 +111,7 @@ class ArgsSchema(Enum):
|
|
|
110
111
|
Field(
|
|
111
112
|
description=(
|
|
112
113
|
"Branch to be used for read file operation."
|
|
113
|
-
)
|
|
114
|
-
default=None
|
|
114
|
+
)
|
|
115
115
|
),
|
|
116
116
|
)
|
|
117
117
|
)
|
|
@@ -159,6 +159,7 @@ class ArgsSchema(Enum):
|
|
|
159
159
|
Field(
|
|
160
160
|
description="""List of comments, where each comment is a dictionary specifying details about the comment,
|
|
161
161
|
e.g. [{'file_path': 'src/main.py', 'comment_text': 'Logic needs improvement', 'right_line': 20}]""",
|
|
162
|
+
default=None,
|
|
162
163
|
examples=[
|
|
163
164
|
{
|
|
164
165
|
"file_path": "src/main.py",
|
|
@@ -241,7 +242,7 @@ class ArgsSchema(Enum):
|
|
|
241
242
|
)
|
|
242
243
|
|
|
243
244
|
|
|
244
|
-
class ReposApiWrapper(
|
|
245
|
+
class ReposApiWrapper(CodeIndexerToolkit):
|
|
245
246
|
# TODO use ado_repos_configuration fields
|
|
246
247
|
organization_url: Optional[str]
|
|
247
248
|
project: Optional[str]
|
|
@@ -251,15 +252,6 @@ class ReposApiWrapper(BaseCodeToolApiWrapper):
|
|
|
251
252
|
token: Optional[SecretStr]
|
|
252
253
|
_client: Optional[GitClient] = PrivateAttr()
|
|
253
254
|
|
|
254
|
-
llm: Optional[Any] = None
|
|
255
|
-
# Vector store configuration
|
|
256
|
-
connection_string: Optional[SecretStr] = None
|
|
257
|
-
collection_name: Optional[str] = None
|
|
258
|
-
doctype: Optional[str] = 'code'
|
|
259
|
-
embedding_model: Optional[str] = "HuggingFaceEmbeddings"
|
|
260
|
-
embedding_model_params: Optional[dict] = {"model_name": "sentence-transformers/all-MiniLM-L6-v2"}
|
|
261
|
-
vectorstore_type: Optional[str] = "PGVector"
|
|
262
|
-
|
|
263
255
|
class Config:
|
|
264
256
|
arbitrary_types_allowed = True
|
|
265
257
|
|
|
@@ -301,7 +293,7 @@ class ReposApiWrapper(BaseCodeToolApiWrapper):
|
|
|
301
293
|
if not branch_exists(active_branch):
|
|
302
294
|
raise ToolException(f"The active branch '{active_branch}' does not exist.")
|
|
303
295
|
|
|
304
|
-
return values
|
|
296
|
+
return super().validate_toolkit(values)
|
|
305
297
|
|
|
306
298
|
def _get_commits(self, file_path: str, branch: str, top: int = None) -> List[GitCommitRef]:
|
|
307
299
|
"""
|
|
@@ -652,6 +644,9 @@ class ReposApiWrapper(BaseCodeToolApiWrapper):
|
|
|
652
644
|
|
|
653
645
|
return dumps(data)
|
|
654
646
|
|
|
647
|
+
def download_file(self, path):
|
|
648
|
+
return b"".join(self._client.get_item_content(self.repository_id, path=path, project=self.project, download=True))
|
|
649
|
+
|
|
655
650
|
def get_file_content(self, commit_id, path):
|
|
656
651
|
version_descriptor = GitVersionDescriptor(
|
|
657
652
|
version=commit_id, version_type="commit"
|
|
@@ -1179,9 +1174,10 @@ class ReposApiWrapper(BaseCodeToolApiWrapper):
|
|
|
1179
1174
|
except Exception as e:
|
|
1180
1175
|
return ToolException(f"Unable to retrieve commits due to error:\n{str(e)}")
|
|
1181
1176
|
|
|
1177
|
+
@extend_with_parent_available_tools
|
|
1182
1178
|
def get_available_tools(self):
|
|
1183
1179
|
"""Return a list of available tools."""
|
|
1184
|
-
|
|
1180
|
+
return [
|
|
1185
1181
|
{
|
|
1186
1182
|
"ref": self.list_branches_in_repo,
|
|
1187
1183
|
"name": "list_branches_in_repo",
|
|
@@ -1272,8 +1268,4 @@ class ReposApiWrapper(BaseCodeToolApiWrapper):
|
|
|
1272
1268
|
"description": self.get_commits.__doc__,
|
|
1273
1269
|
"args_schema": ArgsSchema.GetCommits.value,
|
|
1274
1270
|
},
|
|
1275
|
-
]
|
|
1276
|
-
vector_search_tools = self._get_vector_search_tools()
|
|
1277
|
-
tools.extend(vector_search_tools)
|
|
1278
|
-
|
|
1279
|
-
return tools
|
|
1271
|
+
]
|