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
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):
|
|
@@ -30,3 +35,34 @@ def clean_node_str(s: str) -> str:
|
|
|
30
35
|
"""Cleans a node string by removing all non-alphanumeric characters except underscores and spaces."""
|
|
31
36
|
cleaned_string = re.sub(r'[^\w\s]', '', s)
|
|
32
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')
|
|
@@ -71,7 +102,7 @@ _safe_import_tool('k8s', 'cloud.k8s', None, 'KubernetesToolkit')
|
|
|
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')
|
|
@@ -90,11 +121,19 @@ available_count = len(AVAILABLE_TOOLS)
|
|
|
90
121
|
total_attempted = len(AVAILABLE_TOOLS) + len(FAILED_IMPORTS)
|
|
91
122
|
logger.info(f"Tool imports completed: {available_count}/{total_attempted} successful")
|
|
92
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
|
+
|
|
93
131
|
|
|
94
132
|
def get_tools(tools_list, alita, llm, store: Optional[BaseStore] = None, *args, **kwargs):
|
|
95
133
|
tools = []
|
|
96
134
|
|
|
97
135
|
for tool in tools_list:
|
|
136
|
+
toolkit_tools = []
|
|
98
137
|
settings = tool.get('settings')
|
|
99
138
|
|
|
100
139
|
# Skip tools without settings early
|
|
@@ -116,53 +155,49 @@ def get_tools(tools_list, alita, llm, store: Optional[BaseStore] = None, *args,
|
|
|
116
155
|
|
|
117
156
|
# Set pgvector collection schema if present
|
|
118
157
|
if settings.get('pgvector_configuration'):
|
|
119
|
-
|
|
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
162
|
# Handle ADO special cases
|
|
122
163
|
if tool_type in ['ado_boards', 'ado_wiki', 'ado_plans']:
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
# Handle ADO repos aliases
|
|
127
|
-
if tool_type in ['ado_repos', 'azure_devops_repos'] and 'ado_repos' in AVAILABLE_TOOLS:
|
|
164
|
+
toolkit_tools.extend(AVAILABLE_TOOLS['ado']['get_tools'](tool_type, tool))
|
|
165
|
+
elif tool_type in ['ado_repos', 'azure_devops_repos'] and 'ado_repos' in AVAILABLE_TOOLS:
|
|
128
166
|
try:
|
|
129
|
-
|
|
167
|
+
toolkit_tools.extend(AVAILABLE_TOOLS['ado_repos']['get_tools'](tool))
|
|
130
168
|
except Exception as e:
|
|
131
169
|
logger.error(f"Error getting ADO repos tools: {e}")
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
# Skip MCP toolkit - it's handled by runtime/toolkits/tools.py to avoid duplicate loading
|
|
135
|
-
if tool_type == 'mcp':
|
|
170
|
+
elif tool_type == 'mcp':
|
|
136
171
|
logger.debug(f"Skipping MCP toolkit '{tool.get('toolkit_name')}' - handled by runtime toolkit system")
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if tool_type in AVAILABLE_TOOLS and 'get_tools' in AVAILABLE_TOOLS[tool_type]:
|
|
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]:
|
|
141
175
|
try:
|
|
142
|
-
|
|
176
|
+
toolkit_tools.extend(AVAILABLE_TOOLS[tool_type]['get_tools'](tool))
|
|
143
177
|
except Exception as e:
|
|
144
178
|
logger.error(f"Error getting tools for {tool_type}: {e}")
|
|
145
179
|
raise ToolException(f"Error getting tools for {tool_type}: {e}")
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
# Handle custom modules
|
|
149
|
-
if settings.get("module"):
|
|
180
|
+
elif settings.get("module"):
|
|
150
181
|
try:
|
|
151
182
|
mod = import_module(settings.pop("module"))
|
|
152
183
|
tkitclass = getattr(mod, settings.pop("class"))
|
|
153
184
|
get_toolkit_params = settings.copy()
|
|
154
185
|
get_toolkit_params["name"] = tool.get("name")
|
|
155
186
|
toolkit = tkitclass.get_toolkit(**get_toolkit_params)
|
|
156
|
-
|
|
187
|
+
toolkit_tools.extend(toolkit.get_tools())
|
|
157
188
|
except Exception as e:
|
|
189
|
+
import traceback
|
|
158
190
|
logger.error(f"Error in getting custom toolkit: {e}")
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
# Tool not available
|
|
162
|
-
if tool_type in FAILED_IMPORTS:
|
|
163
|
-
logger.warning(f"Tool '{tool_type}' is not available: {FAILED_IMPORTS[tool_type]}")
|
|
191
|
+
logger.error(f"Traceback:\n{traceback.format_exc()}")
|
|
164
192
|
else:
|
|
165
|
-
|
|
193
|
+
if tool_type in FAILED_IMPORTS:
|
|
194
|
+
logger.warning(f"Tool '{tool_type}' is not available: {FAILED_IMPORTS[tool_type]}")
|
|
195
|
+
else:
|
|
196
|
+
logger.warning(f"Unknown tool type: {tool_type}")
|
|
197
|
+
#
|
|
198
|
+
# Always inject toolkit_id to each tool
|
|
199
|
+
_inject_toolkit_id(tool, toolkit_tools)
|
|
200
|
+
tools.extend(toolkit_tools)
|
|
166
201
|
|
|
167
202
|
return tools
|
|
168
203
|
|
|
@@ -182,6 +217,18 @@ def get_toolkits():
|
|
|
182
217
|
logger.info(f"Successfully loaded {len(toolkit_configs)} toolkit configurations")
|
|
183
218
|
return toolkit_configs
|
|
184
219
|
|
|
220
|
+
def instantiate_toolkit(tool_config):
|
|
221
|
+
"""Instantiate a toolkit from its configuration."""
|
|
222
|
+
tool_type = tool_config.get('type')
|
|
223
|
+
|
|
224
|
+
if tool_type in AVAILABLE_TOOLS:
|
|
225
|
+
tool_module = AVAILABLE_TOOLS[tool_type]
|
|
226
|
+
|
|
227
|
+
if 'get_toolkit' in tool_module:
|
|
228
|
+
return tool_module['get_toolkit'](tool_config)
|
|
229
|
+
|
|
230
|
+
raise ValueError(f"Toolkit type '{tool_type}' does not support direct instantiation or is not available.")
|
|
231
|
+
|
|
185
232
|
def get_available_tools():
|
|
186
233
|
"""Return list of available tool types."""
|
|
187
234
|
return list(AVAILABLE_TOOLS.keys())
|
|
@@ -198,6 +245,42 @@ def get_available_toolkit_models():
|
|
|
198
245
|
"""Return dict with available toolkit classes."""
|
|
199
246
|
return deepcopy(AVAILABLE_TOOLS)
|
|
200
247
|
|
|
248
|
+
|
|
249
|
+
def get_toolkit_available_tools(toolkit_type: str, settings: dict) -> dict:
|
|
250
|
+
"""Return dynamic available tools + per-tool JSON schemas for a toolkit instance.
|
|
251
|
+
|
|
252
|
+
This is the single SDK entrypoint used by backend services (e.g. indexer_worker)
|
|
253
|
+
when the UI needs spec/instance-dependent tool enumeration. Toolkits that don't
|
|
254
|
+
support dynamic enumeration should return an empty payload.
|
|
255
|
+
|
|
256
|
+
Args:
|
|
257
|
+
toolkit_type: toolkit type string (e.g. 'openapi')
|
|
258
|
+
settings: persisted toolkit settings
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
{
|
|
262
|
+
"tools": [{"name": str, "description": str}],
|
|
263
|
+
"args_schemas": {"tool_name": <json schema dict>}
|
|
264
|
+
}
|
|
265
|
+
"""
|
|
266
|
+
toolkit_type = (toolkit_type or '').strip().lower()
|
|
267
|
+
if not isinstance(settings, dict):
|
|
268
|
+
settings = {}
|
|
269
|
+
|
|
270
|
+
tool_module = AVAILABLE_TOOLS.get(toolkit_type) or {}
|
|
271
|
+
enumerator = tool_module.get('get_toolkit_available_tools')
|
|
272
|
+
if not callable(enumerator):
|
|
273
|
+
return {"tools": [], "args_schemas": {}}
|
|
274
|
+
|
|
275
|
+
try:
|
|
276
|
+
result = enumerator(settings)
|
|
277
|
+
if not isinstance(result, dict):
|
|
278
|
+
return {"tools": [], "args_schemas": {}, "error": "Invalid response from toolkit enumerator"}
|
|
279
|
+
return result
|
|
280
|
+
except Exception as e: # pylint: disable=W0718
|
|
281
|
+
logger.exception("Failed to compute available tools for toolkit_type=%s", toolkit_type)
|
|
282
|
+
return {"tools": [], "args_schemas": {}, "error": str(e)}
|
|
283
|
+
|
|
201
284
|
def diagnose_imports():
|
|
202
285
|
"""Print diagnostic information about tool imports."""
|
|
203
286
|
available_count = len(AVAILABLE_TOOLS)
|
|
@@ -234,6 +317,7 @@ def diagnose_imports():
|
|
|
234
317
|
__all__ = [
|
|
235
318
|
'get_tools',
|
|
236
319
|
'get_toolkits',
|
|
320
|
+
'get_toolkit_available_tools',
|
|
237
321
|
'get_available_tools',
|
|
238
322
|
'get_failed_imports',
|
|
239
323
|
'get_available_toolkits',
|
|
@@ -6,23 +6,25 @@ from pydantic import BaseModel, Field, create_model
|
|
|
6
6
|
import requests
|
|
7
7
|
|
|
8
8
|
from ...elitea_base import filter_missconfigured_index_tools
|
|
9
|
-
from ....configurations.ado import
|
|
9
|
+
from ....configurations.ado import AdoConfiguration
|
|
10
10
|
from ....configurations.pgvector import PgVectorConfiguration
|
|
11
11
|
from ...base.tool import BaseAction
|
|
12
12
|
from .repos_wrapper import ReposApiWrapper
|
|
13
|
-
from ...utils import
|
|
13
|
+
from ...utils import check_connection_response
|
|
14
|
+
from ....runtime.utils.constants import TOOLKIT_NAME_META, TOOL_NAME_META, TOOLKIT_TYPE_META
|
|
14
15
|
|
|
15
16
|
name = "ado_repos"
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
def
|
|
19
|
+
def get_toolkit(tool) -> BaseToolkit:
|
|
19
20
|
return AzureDevOpsReposToolkit().get_toolkit(
|
|
20
21
|
selected_tools=tool['settings'].get('selected_tools', []),
|
|
21
|
-
|
|
22
|
+
ado_configuration=tool['settings']['ado_configuration'],
|
|
23
|
+
repository_id=tool['settings']['repository_id'],
|
|
22
24
|
limit=tool['settings'].get('limit', 5),
|
|
23
|
-
base_branch=tool['settings'].get('base_branch', ""),
|
|
24
|
-
active_branch=tool['settings'].get('active_branch', ""),
|
|
25
|
-
toolkit_name=tool
|
|
25
|
+
base_branch=tool['settings'].get('base_branch', "main"),
|
|
26
|
+
active_branch=tool['settings'].get('active_branch', "main"),
|
|
27
|
+
toolkit_name=tool.get('toolkit_name', ''),
|
|
26
28
|
pgvector_configuration=tool['settings'].get('pgvector_configuration', {}),
|
|
27
29
|
embedding_model=tool['settings'].get('embedding_model'),
|
|
28
30
|
collection_name=tool['toolkit_name'],
|
|
@@ -30,26 +32,22 @@ def _get_toolkit(tool) -> BaseToolkit:
|
|
|
30
32
|
llm=tool['settings'].get('llm', None),
|
|
31
33
|
)
|
|
32
34
|
|
|
33
|
-
def get_toolkit():
|
|
34
|
-
return AzureDevOpsReposToolkit.toolkit_config_schema()
|
|
35
|
-
|
|
36
35
|
def get_tools(tool):
|
|
37
|
-
return
|
|
36
|
+
return get_toolkit(tool).get_tools()
|
|
38
37
|
|
|
39
38
|
class AzureDevOpsReposToolkit(BaseToolkit):
|
|
40
39
|
tools: List[BaseTool] = []
|
|
41
|
-
toolkit_max_length: int = 0
|
|
42
40
|
|
|
43
41
|
@staticmethod
|
|
44
42
|
def toolkit_config_schema() -> BaseModel:
|
|
45
43
|
selected_tools = {x['name']: x['args_schema'].schema() for x in ReposApiWrapper.model_construct().get_available_tools()}
|
|
46
|
-
AzureDevOpsReposToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
47
44
|
m = create_model(
|
|
48
45
|
name,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
46
|
+
ado_configuration=(AdoConfiguration, Field(description="ADO configuration", default=None,
|
|
47
|
+
json_schema_extra={'configuration_types': ['ado']})),
|
|
48
|
+
repository_id=(str, Field(description="ADO repository ID or name")),
|
|
49
|
+
base_branch=(Optional[str], Field(default="main", title="Base branch", description="ADO base branch (e.g., main)")),
|
|
50
|
+
active_branch=(Optional[str], Field(default="main", title="Active branch", description="ADO active branch (e.g., main)")),
|
|
53
51
|
|
|
54
52
|
# indexer settings
|
|
55
53
|
pgvector_configuration=(Optional[PgVectorConfiguration], Field(default=None, description="PgVector Configuration", json_schema_extra={'configuration_types': ['pgvector']})),
|
|
@@ -57,21 +55,38 @@ class AzureDevOpsReposToolkit(BaseToolkit):
|
|
|
57
55
|
embedding_model=(Optional[str], Field(default=None, description="Embedding configuration.", json_schema_extra={'configuration_model': 'embedding'})),
|
|
58
56
|
|
|
59
57
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
60
|
-
__config__={
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
58
|
+
__config__={
|
|
59
|
+
'json_schema_extra': {
|
|
60
|
+
'metadata': {
|
|
61
|
+
"label": "ADO repos",
|
|
62
|
+
"icon_url": "ado-repos-icon.svg",
|
|
63
|
+
"categories": ["code repositories"],
|
|
64
|
+
"extra_categories": ["code", "repository", "version control"],
|
|
65
|
+
"sections": {
|
|
66
|
+
"auth": {
|
|
67
|
+
"required": True,
|
|
68
|
+
"subsections": [
|
|
69
|
+
{
|
|
70
|
+
"name": "Token",
|
|
71
|
+
"fields": ["token"]
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"configuration_group": {
|
|
77
|
+
"name": "ado",
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
68
82
|
)
|
|
69
83
|
|
|
70
84
|
@check_connection_response
|
|
71
85
|
def check_connection(self):
|
|
86
|
+
ado_config = self.ado_configuration
|
|
72
87
|
response = requests.get(
|
|
73
|
-
f'{
|
|
74
|
-
headers = {'Authorization': f'Bearer {
|
|
88
|
+
f'{ado_config.organization_url}/{ado_config.project}/_apis/git/repositories/{self.repository_id}?api-version=7.0',
|
|
89
|
+
headers = {'Authorization': f'Bearer {ado_config.token.get_secret_value() if ado_config.token else ""}'},
|
|
75
90
|
timeout=5
|
|
76
91
|
)
|
|
77
92
|
return response
|
|
@@ -91,25 +106,28 @@ class AzureDevOpsReposToolkit(BaseToolkit):
|
|
|
91
106
|
|
|
92
107
|
wrapper_payload = {
|
|
93
108
|
**kwargs,
|
|
94
|
-
#
|
|
95
|
-
**kwargs['
|
|
96
|
-
**kwargs['ado_repos_configuration']['ado_configuration'],
|
|
109
|
+
# Extract ADO configuration fields
|
|
110
|
+
**kwargs['ado_configuration'],
|
|
97
111
|
**(kwargs.get('pgvector_configuration') or {}),
|
|
98
112
|
}
|
|
99
113
|
azure_devops_repos_wrapper = ReposApiWrapper(**wrapper_payload)
|
|
100
114
|
available_tools = azure_devops_repos_wrapper.get_available_tools()
|
|
101
115
|
tools = []
|
|
102
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
103
116
|
for tool in available_tools:
|
|
104
117
|
if selected_tools:
|
|
105
118
|
if tool["name"] not in selected_tools:
|
|
106
119
|
continue
|
|
120
|
+
description = tool["description"] + f"\nADO instance: {azure_devops_repos_wrapper.organization_url}/{azure_devops_repos_wrapper.project}"
|
|
121
|
+
if toolkit_name:
|
|
122
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
123
|
+
description = description[:1000]
|
|
107
124
|
tools.append(
|
|
108
125
|
BaseAction(
|
|
109
126
|
api_wrapper=azure_devops_repos_wrapper,
|
|
110
|
-
name=
|
|
111
|
-
description=
|
|
127
|
+
name=tool["name"],
|
|
128
|
+
description=description,
|
|
112
129
|
args_schema=tool["args_schema"],
|
|
130
|
+
metadata={TOOLKIT_NAME_META: toolkit_name, TOOLKIT_TYPE_META: name, TOOL_NAME_META: tool["name"]} if toolkit_name else {TOOL_NAME_META: tool["name"]}
|
|
113
131
|
)
|
|
114
132
|
)
|
|
115
133
|
return cls(tools=tools)
|