alita-sdk 0.3.263__py3-none-any.whl → 0.3.499__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- alita_sdk/cli/__init__.py +10 -0
- alita_sdk/cli/__main__.py +17 -0
- alita_sdk/cli/agent/__init__.py +5 -0
- alita_sdk/cli/agent/default.py +258 -0
- alita_sdk/cli/agent_executor.py +155 -0
- alita_sdk/cli/agent_loader.py +215 -0
- alita_sdk/cli/agent_ui.py +228 -0
- alita_sdk/cli/agents.py +3601 -0
- alita_sdk/cli/callbacks.py +647 -0
- alita_sdk/cli/cli.py +168 -0
- alita_sdk/cli/config.py +306 -0
- alita_sdk/cli/context/__init__.py +30 -0
- alita_sdk/cli/context/cleanup.py +198 -0
- alita_sdk/cli/context/manager.py +731 -0
- alita_sdk/cli/context/message.py +285 -0
- alita_sdk/cli/context/strategies.py +289 -0
- alita_sdk/cli/context/token_estimation.py +127 -0
- alita_sdk/cli/formatting.py +182 -0
- alita_sdk/cli/input_handler.py +419 -0
- alita_sdk/cli/inventory.py +1256 -0
- alita_sdk/cli/mcp_loader.py +315 -0
- alita_sdk/cli/toolkit.py +327 -0
- alita_sdk/cli/toolkit_loader.py +85 -0
- alita_sdk/cli/tools/__init__.py +43 -0
- alita_sdk/cli/tools/approval.py +224 -0
- alita_sdk/cli/tools/filesystem.py +1751 -0
- alita_sdk/cli/tools/planning.py +389 -0
- alita_sdk/cli/tools/terminal.py +414 -0
- alita_sdk/community/__init__.py +64 -8
- alita_sdk/community/inventory/__init__.py +224 -0
- alita_sdk/community/inventory/config.py +257 -0
- alita_sdk/community/inventory/enrichment.py +2137 -0
- alita_sdk/community/inventory/extractors.py +1469 -0
- alita_sdk/community/inventory/ingestion.py +3172 -0
- alita_sdk/community/inventory/knowledge_graph.py +1457 -0
- alita_sdk/community/inventory/parsers/__init__.py +218 -0
- alita_sdk/community/inventory/parsers/base.py +295 -0
- alita_sdk/community/inventory/parsers/csharp_parser.py +907 -0
- alita_sdk/community/inventory/parsers/go_parser.py +851 -0
- alita_sdk/community/inventory/parsers/html_parser.py +389 -0
- alita_sdk/community/inventory/parsers/java_parser.py +593 -0
- alita_sdk/community/inventory/parsers/javascript_parser.py +629 -0
- alita_sdk/community/inventory/parsers/kotlin_parser.py +768 -0
- alita_sdk/community/inventory/parsers/markdown_parser.py +362 -0
- alita_sdk/community/inventory/parsers/python_parser.py +604 -0
- alita_sdk/community/inventory/parsers/rust_parser.py +858 -0
- alita_sdk/community/inventory/parsers/swift_parser.py +832 -0
- alita_sdk/community/inventory/parsers/text_parser.py +322 -0
- alita_sdk/community/inventory/parsers/yaml_parser.py +370 -0
- alita_sdk/community/inventory/patterns/__init__.py +61 -0
- alita_sdk/community/inventory/patterns/ast_adapter.py +380 -0
- alita_sdk/community/inventory/patterns/loader.py +348 -0
- alita_sdk/community/inventory/patterns/registry.py +198 -0
- alita_sdk/community/inventory/presets.py +535 -0
- alita_sdk/community/inventory/retrieval.py +1403 -0
- alita_sdk/community/inventory/toolkit.py +173 -0
- alita_sdk/community/inventory/visualize.py +1370 -0
- alita_sdk/configurations/__init__.py +10 -0
- alita_sdk/configurations/ado.py +4 -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 +96 -1
- alita_sdk/configurations/delta_lake.py +1 -1
- alita_sdk/configurations/figma.py +0 -5
- alita_sdk/configurations/github.py +65 -1
- alita_sdk/configurations/gitlab.py +79 -0
- alita_sdk/configurations/google_places.py +17 -0
- alita_sdk/configurations/jira.py +103 -0
- alita_sdk/configurations/postman.py +1 -1
- alita_sdk/configurations/qtest.py +1 -3
- alita_sdk/configurations/report_portal.py +19 -0
- alita_sdk/configurations/salesforce.py +19 -0
- alita_sdk/configurations/service_now.py +1 -12
- alita_sdk/configurations/sharepoint.py +19 -0
- alita_sdk/configurations/sonar.py +18 -0
- alita_sdk/configurations/sql.py +20 -0
- alita_sdk/configurations/testio.py +18 -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 +12 -2
- alita_sdk/runtime/clients/client.py +235 -66
- alita_sdk/runtime/clients/mcp_discovery.py +342 -0
- alita_sdk/runtime/clients/mcp_manager.py +262 -0
- alita_sdk/runtime/clients/sandbox_client.py +373 -0
- alita_sdk/runtime/langchain/assistant.py +123 -17
- alita_sdk/runtime/langchain/constants.py +8 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaDocxMammothLoader.py +315 -3
- alita_sdk/runtime/langchain/document_loaders/AlitaExcelLoader.py +209 -31
- alita_sdk/runtime/langchain/document_loaders/AlitaImageLoader.py +1 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +8 -2
- 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 +187 -40
- alita_sdk/runtime/langchain/interfaces/llm_processor.py +4 -2
- alita_sdk/runtime/langchain/langraph_agent.py +406 -91
- alita_sdk/runtime/langchain/utils.py +51 -8
- alita_sdk/runtime/llms/preloaded.py +2 -6
- alita_sdk/runtime/models/mcp_models.py +61 -0
- alita_sdk/runtime/toolkits/__init__.py +26 -0
- alita_sdk/runtime/toolkits/application.py +9 -2
- alita_sdk/runtime/toolkits/artifact.py +19 -7
- alita_sdk/runtime/toolkits/datasource.py +13 -6
- alita_sdk/runtime/toolkits/mcp.py +780 -0
- alita_sdk/runtime/toolkits/planning.py +178 -0
- alita_sdk/runtime/toolkits/subgraph.py +11 -6
- alita_sdk/runtime/toolkits/tools.py +214 -60
- alita_sdk/runtime/toolkits/vectorstore.py +9 -4
- alita_sdk/runtime/tools/__init__.py +22 -0
- alita_sdk/runtime/tools/application.py +16 -4
- alita_sdk/runtime/tools/artifact.py +312 -19
- alita_sdk/runtime/tools/function.py +100 -4
- alita_sdk/runtime/tools/graph.py +81 -0
- alita_sdk/runtime/tools/image_generation.py +212 -0
- alita_sdk/runtime/tools/llm.py +539 -180
- 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/vectorstore.py +62 -63
- alita_sdk/runtime/tools/vectorstore_base.py +156 -85
- alita_sdk/runtime/utils/AlitaCallback.py +106 -20
- alita_sdk/runtime/utils/mcp_client.py +465 -0
- alita_sdk/runtime/utils/mcp_oauth.py +244 -0
- alita_sdk/runtime/utils/mcp_sse_client.py +405 -0
- alita_sdk/runtime/utils/mcp_tools_discovery.py +124 -0
- alita_sdk/runtime/utils/streamlit.py +41 -14
- alita_sdk/runtime/utils/toolkit_utils.py +28 -9
- alita_sdk/runtime/utils/utils.py +14 -0
- alita_sdk/tools/__init__.py +78 -35
- alita_sdk/tools/ado/__init__.py +0 -1
- alita_sdk/tools/ado/repos/__init__.py +10 -6
- alita_sdk/tools/ado/repos/repos_wrapper.py +12 -11
- alita_sdk/tools/ado/test_plan/__init__.py +10 -7
- alita_sdk/tools/ado/test_plan/test_plan_wrapper.py +56 -23
- alita_sdk/tools/ado/wiki/__init__.py +10 -11
- alita_sdk/tools/ado/wiki/ado_wrapper.py +114 -28
- alita_sdk/tools/ado/work_item/__init__.py +10 -11
- alita_sdk/tools/ado/work_item/ado_wrapper.py +63 -10
- alita_sdk/tools/advanced_jira_mining/__init__.py +10 -7
- alita_sdk/tools/aws/delta_lake/__init__.py +13 -11
- alita_sdk/tools/azure_ai/search/__init__.py +11 -7
- alita_sdk/tools/base_indexer_toolkit.py +392 -86
- alita_sdk/tools/bitbucket/__init__.py +18 -11
- alita_sdk/tools/bitbucket/api_wrapper.py +52 -9
- alita_sdk/tools/bitbucket/cloud_api_wrapper.py +5 -5
- alita_sdk/tools/browser/__init__.py +40 -16
- alita_sdk/tools/browser/crawler.py +3 -1
- alita_sdk/tools/browser/utils.py +15 -6
- alita_sdk/tools/carrier/__init__.py +17 -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 +1 -0
- alita_sdk/tools/chunkers/sematic/markdown_chunker.py +97 -6
- alita_sdk/tools/chunkers/sematic/proposal_chunker.py +1 -1
- alita_sdk/tools/chunkers/universal_chunker.py +270 -0
- alita_sdk/tools/cloud/aws/__init__.py +9 -6
- alita_sdk/tools/cloud/azure/__init__.py +9 -6
- alita_sdk/tools/cloud/gcp/__init__.py +9 -6
- alita_sdk/tools/cloud/k8s/__init__.py +9 -6
- alita_sdk/tools/code/linter/__init__.py +7 -7
- alita_sdk/tools/code/loaders/codesearcher.py +3 -2
- alita_sdk/tools/code/sonar/__init__.py +18 -12
- alita_sdk/tools/code_indexer_toolkit.py +199 -0
- alita_sdk/tools/confluence/__init__.py +14 -11
- alita_sdk/tools/confluence/api_wrapper.py +198 -58
- alita_sdk/tools/confluence/loader.py +10 -0
- alita_sdk/tools/custom_open_api/__init__.py +9 -4
- alita_sdk/tools/elastic/__init__.py +8 -7
- alita_sdk/tools/elitea_base.py +543 -64
- alita_sdk/tools/figma/__init__.py +10 -8
- alita_sdk/tools/figma/api_wrapper.py +352 -153
- alita_sdk/tools/github/__init__.py +13 -11
- alita_sdk/tools/github/api_wrapper.py +9 -26
- alita_sdk/tools/github/github_client.py +75 -12
- alita_sdk/tools/github/schemas.py +2 -1
- alita_sdk/tools/gitlab/__init__.py +11 -10
- alita_sdk/tools/gitlab/api_wrapper.py +135 -45
- alita_sdk/tools/gitlab_org/__init__.py +11 -9
- alita_sdk/tools/google/bigquery/__init__.py +12 -13
- alita_sdk/tools/google_places/__init__.py +18 -10
- alita_sdk/tools/jira/__init__.py +14 -8
- alita_sdk/tools/jira/api_wrapper.py +315 -168
- alita_sdk/tools/keycloak/__init__.py +8 -7
- alita_sdk/tools/localgit/local_git.py +56 -54
- alita_sdk/tools/memory/__init__.py +27 -11
- alita_sdk/tools/non_code_indexer_toolkit.py +7 -2
- alita_sdk/tools/ocr/__init__.py +8 -7
- alita_sdk/tools/openapi/__init__.py +10 -1
- alita_sdk/tools/pandas/__init__.py +8 -7
- alita_sdk/tools/pandas/api_wrapper.py +7 -25
- alita_sdk/tools/postman/__init__.py +8 -10
- alita_sdk/tools/postman/api_wrapper.py +19 -8
- alita_sdk/tools/postman/postman_analysis.py +8 -1
- alita_sdk/tools/pptx/__init__.py +8 -9
- alita_sdk/tools/qtest/__init__.py +19 -13
- alita_sdk/tools/qtest/api_wrapper.py +1784 -88
- alita_sdk/tools/rally/__init__.py +10 -9
- alita_sdk/tools/report_portal/__init__.py +20 -15
- alita_sdk/tools/salesforce/__init__.py +19 -15
- alita_sdk/tools/servicenow/__init__.py +14 -11
- alita_sdk/tools/sharepoint/__init__.py +14 -13
- 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 +10 -7
- alita_sdk/tools/sql/__init__.py +19 -18
- alita_sdk/tools/sql/api_wrapper.py +71 -23
- alita_sdk/tools/testio/__init__.py +18 -12
- alita_sdk/tools/testrail/__init__.py +10 -10
- alita_sdk/tools/testrail/api_wrapper.py +213 -45
- alita_sdk/tools/utils/__init__.py +28 -4
- alita_sdk/tools/utils/content_parser.py +181 -61
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +83 -27
- alita_sdk/tools/xray/__init__.py +12 -7
- alita_sdk/tools/xray/api_wrapper.py +58 -113
- alita_sdk/tools/zephyr/__init__.py +9 -6
- alita_sdk/tools/zephyr_enterprise/__init__.py +13 -8
- alita_sdk/tools/zephyr_enterprise/api_wrapper.py +17 -7
- alita_sdk/tools/zephyr_essential/__init__.py +13 -9
- alita_sdk/tools/zephyr_essential/api_wrapper.py +289 -47
- alita_sdk/tools/zephyr_essential/client.py +6 -4
- alita_sdk/tools/zephyr_scale/__init__.py +10 -7
- alita_sdk/tools/zephyr_scale/api_wrapper.py +6 -2
- alita_sdk/tools/zephyr_squad/__init__.py +9 -6
- {alita_sdk-0.3.263.dist-info → alita_sdk-0.3.499.dist-info}/METADATA +180 -33
- alita_sdk-0.3.499.dist-info/RECORD +433 -0
- alita_sdk-0.3.499.dist-info/entry_points.txt +2 -0
- alita_sdk-0.3.263.dist-info/RECORD +0 -342
- {alita_sdk-0.3.263.dist-info → alita_sdk-0.3.499.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.263.dist-info → alita_sdk-0.3.499.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.263.dist-info → alita_sdk-0.3.499.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
MCP Tools Discovery Utility.
|
|
3
|
+
Provides a standalone function to discover tools from remote MCP servers.
|
|
4
|
+
Supports both SSE (Server-Sent Events) and Streamable HTTP transports with auto-detection.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import asyncio
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
10
|
+
|
|
11
|
+
from .mcp_oauth import McpAuthorizationRequired
|
|
12
|
+
from .mcp_client import McpClient
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def discover_mcp_tools(
|
|
18
|
+
url: str,
|
|
19
|
+
headers: Optional[Dict[str, str]] = None,
|
|
20
|
+
timeout: int = 60,
|
|
21
|
+
session_id: Optional[str] = None,
|
|
22
|
+
) -> List[Dict[str, Any]]:
|
|
23
|
+
"""
|
|
24
|
+
Discover available tools from a remote MCP server.
|
|
25
|
+
|
|
26
|
+
This function connects to a remote MCP server and retrieves the list of
|
|
27
|
+
available tools using the MCP protocol. Automatically detects and uses
|
|
28
|
+
the appropriate transport (SSE or Streamable HTTP).
|
|
29
|
+
|
|
30
|
+
Args:
|
|
31
|
+
url: MCP server HTTP URL (http:// or https://)
|
|
32
|
+
headers: Optional HTTP headers for authentication
|
|
33
|
+
timeout: Request timeout in seconds (default: 60)
|
|
34
|
+
session_id: Optional session ID for stateful connections
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
List of tool definitions, each containing:
|
|
38
|
+
- name: Tool name
|
|
39
|
+
- description: Tool description
|
|
40
|
+
- inputSchema: JSON schema for tool input parameters
|
|
41
|
+
|
|
42
|
+
Raises:
|
|
43
|
+
McpAuthorizationRequired: If the server requires OAuth authorization (401)
|
|
44
|
+
Exception: For other connection or protocol errors
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
>>> tools = discover_mcp_tools(
|
|
48
|
+
... url="https://mcp.example.com/sse",
|
|
49
|
+
... headers={"Authorization": "Bearer token123"}
|
|
50
|
+
... )
|
|
51
|
+
>>> print(f"Found {len(tools)} tools")
|
|
52
|
+
"""
|
|
53
|
+
logger.info(f"[MCP Discovery] Starting tool discovery from {url}")
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
# Run the async discovery in a new event loop
|
|
57
|
+
tools_list = asyncio.run(
|
|
58
|
+
_discover_tools_async(url, headers, timeout, session_id)
|
|
59
|
+
)
|
|
60
|
+
logger.info(f"[MCP Discovery] Successfully discovered {len(tools_list)} tools from {url}")
|
|
61
|
+
return tools_list
|
|
62
|
+
|
|
63
|
+
except McpAuthorizationRequired:
|
|
64
|
+
# Re-raise auth exceptions directly
|
|
65
|
+
logger.info(f"[MCP Discovery] Authorization required for {url}")
|
|
66
|
+
raise
|
|
67
|
+
|
|
68
|
+
except Exception as e:
|
|
69
|
+
logger.error(f"[MCP Discovery] Failed to discover tools from {url}: {e}")
|
|
70
|
+
raise
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
async def _discover_tools_async(
|
|
74
|
+
url: str,
|
|
75
|
+
headers: Optional[Dict[str, str]],
|
|
76
|
+
timeout: int,
|
|
77
|
+
session_id: Optional[str],
|
|
78
|
+
) -> List[Dict[str, Any]]:
|
|
79
|
+
"""
|
|
80
|
+
Async implementation of tool discovery using unified MCP client.
|
|
81
|
+
"""
|
|
82
|
+
all_tools = []
|
|
83
|
+
|
|
84
|
+
# Create unified MCP client (auto-detects transport)
|
|
85
|
+
client = McpClient(
|
|
86
|
+
url=url,
|
|
87
|
+
session_id=session_id,
|
|
88
|
+
headers=headers,
|
|
89
|
+
timeout=timeout
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
async with client:
|
|
93
|
+
# Initialize MCP session
|
|
94
|
+
await client.initialize()
|
|
95
|
+
logger.debug(f"[MCP Discovery] Session initialized (transport={client.detected_transport})")
|
|
96
|
+
|
|
97
|
+
# Get tools list
|
|
98
|
+
tools = await client.list_tools()
|
|
99
|
+
logger.debug(f"[MCP Discovery] Received {len(tools)} tools")
|
|
100
|
+
|
|
101
|
+
# Convert tools to standard format
|
|
102
|
+
for tool in tools:
|
|
103
|
+
tool_def = {
|
|
104
|
+
'name': tool.get('name'),
|
|
105
|
+
'description': tool.get('description', ''),
|
|
106
|
+
'inputSchema': tool.get('inputSchema', {}),
|
|
107
|
+
}
|
|
108
|
+
all_tools.append(tool_def)
|
|
109
|
+
|
|
110
|
+
return all_tools
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
async def discover_mcp_tools_async(
|
|
114
|
+
url: str,
|
|
115
|
+
headers: Optional[Dict[str, str]] = None,
|
|
116
|
+
timeout: int = 60,
|
|
117
|
+
session_id: Optional[str] = None,
|
|
118
|
+
) -> List[Dict[str, Any]]:
|
|
119
|
+
"""
|
|
120
|
+
Async version of discover_mcp_tools.
|
|
121
|
+
|
|
122
|
+
See discover_mcp_tools for full documentation.
|
|
123
|
+
"""
|
|
124
|
+
return await _discover_tools_async(url, headers, timeout, session_id)
|
|
@@ -287,7 +287,6 @@ def run_streamlit(st, ai_icon=None, user_icon=None):
|
|
|
287
287
|
model_config={
|
|
288
288
|
"temperature": 0.1,
|
|
289
289
|
"max_tokens": 1000,
|
|
290
|
-
"top_p": 1.0
|
|
291
290
|
}
|
|
292
291
|
)
|
|
293
292
|
except Exception as e:
|
|
@@ -868,10 +867,24 @@ def run_streamlit(st, ai_icon=None, user_icon=None):
|
|
|
868
867
|
label = f"{'🔒 ' if is_secret else ''}{'*' if is_required else ''}{field_name.replace('_', ' ').title()}"
|
|
869
868
|
|
|
870
869
|
if field_type == 'string':
|
|
871
|
-
if
|
|
870
|
+
# Check if this is an enum field
|
|
871
|
+
if field_schema.get('enum'):
|
|
872
|
+
# Dropdown for enum values
|
|
873
|
+
options = field_schema['enum']
|
|
874
|
+
default_index = 0
|
|
875
|
+
if default_value and str(default_value) in options:
|
|
876
|
+
default_index = options.index(str(default_value))
|
|
877
|
+
toolkit_config_values[field_name] = st.selectbox(
|
|
878
|
+
label,
|
|
879
|
+
options=options,
|
|
880
|
+
index=default_index,
|
|
881
|
+
help=field_description,
|
|
882
|
+
key=f"config_{field_name}_{selected_toolkit_idx}"
|
|
883
|
+
)
|
|
884
|
+
elif is_secret:
|
|
872
885
|
toolkit_config_values[field_name] = st.text_input(
|
|
873
886
|
label,
|
|
874
|
-
value=str(default_value) if default_value else '',
|
|
887
|
+
value=str(default_value) if default_value else '',
|
|
875
888
|
help=field_description,
|
|
876
889
|
type="password",
|
|
877
890
|
key=f"config_{field_name}_{selected_toolkit_idx}"
|
|
@@ -879,7 +892,7 @@ def run_streamlit(st, ai_icon=None, user_icon=None):
|
|
|
879
892
|
else:
|
|
880
893
|
toolkit_config_values[field_name] = st.text_input(
|
|
881
894
|
label,
|
|
882
|
-
value=str(default_value) if default_value else '',
|
|
895
|
+
value=str(default_value) if default_value else '',
|
|
883
896
|
help=field_description,
|
|
884
897
|
key=f"config_{field_name}_{selected_toolkit_idx}"
|
|
885
898
|
)
|
|
@@ -971,6 +984,23 @@ def run_streamlit(st, ai_icon=None, user_icon=None):
|
|
|
971
984
|
key=f"config_{field_name}_{selected_toolkit_idx}"
|
|
972
985
|
)
|
|
973
986
|
toolkit_config_values[field_name] = [line.strip() for line in array_input.split('\n') if line.strip()]
|
|
987
|
+
elif field_type == 'object':
|
|
988
|
+
# Handle object/dict types (like headers)
|
|
989
|
+
obj_input = st.text_area(
|
|
990
|
+
f"{label} (JSON object)",
|
|
991
|
+
value=json.dumps(default_value) if isinstance(default_value, dict) else str(default_value) if default_value else '',
|
|
992
|
+
help=f"{field_description} - Enter as JSON object, e.g. {{\"Authorization\": \"Bearer token\"}}",
|
|
993
|
+
placeholder='{"key": "value"}',
|
|
994
|
+
key=f"config_{field_name}_{selected_toolkit_idx}"
|
|
995
|
+
)
|
|
996
|
+
try:
|
|
997
|
+
if obj_input.strip():
|
|
998
|
+
toolkit_config_values[field_name] = json.loads(obj_input)
|
|
999
|
+
else:
|
|
1000
|
+
toolkit_config_values[field_name] = None
|
|
1001
|
+
except json.JSONDecodeError as e:
|
|
1002
|
+
st.error(f"Invalid JSON format for {field_name}: {e}")
|
|
1003
|
+
toolkit_config_values[field_name] = None
|
|
974
1004
|
else:
|
|
975
1005
|
st.info("This toolkit doesn't require additional configuration.")
|
|
976
1006
|
|
|
@@ -1102,7 +1132,7 @@ def run_streamlit(st, ai_icon=None, user_icon=None):
|
|
|
1102
1132
|
st_cb = AlitaStreamlitCallback(st)
|
|
1103
1133
|
logger.info(st.session_state.messages)
|
|
1104
1134
|
response = st.session_state.agent_executor.invoke(
|
|
1105
|
-
{"input": prompt, "chat_history": st.session_state.messages[:-1]},
|
|
1135
|
+
{"input": [prompt], "chat_history": st.session_state.messages[:-1]},
|
|
1106
1136
|
{ 'callbacks': [st_cb], 'configurable': {"thread_id": st.session_state.thread_id}}
|
|
1107
1137
|
)
|
|
1108
1138
|
st.write(response["output"])
|
|
@@ -1225,7 +1255,6 @@ def run_streamlit(st, ai_icon=None, user_icon=None):
|
|
|
1225
1255
|
model_config={
|
|
1226
1256
|
"temperature": 0.1,
|
|
1227
1257
|
"max_tokens": 1000,
|
|
1228
|
-
"top_p": 1.0
|
|
1229
1258
|
}
|
|
1230
1259
|
)
|
|
1231
1260
|
except Exception as e:
|
|
@@ -1356,20 +1385,18 @@ def run_streamlit(st, ai_icon=None, user_icon=None):
|
|
|
1356
1385
|
help="Maximum number of tokens in the AI response"
|
|
1357
1386
|
)
|
|
1358
1387
|
|
|
1359
|
-
|
|
1360
|
-
"
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
step=0.1,
|
|
1365
|
-
help="Controls diversity via nucleus sampling"
|
|
1388
|
+
reasoning_effort = st.selectbox(
|
|
1389
|
+
"Reasoning effort:",
|
|
1390
|
+
options=['null', 'low', 'medium', 'high'],
|
|
1391
|
+
index=0,
|
|
1392
|
+
help="Higher effort better reasoning, slower response"
|
|
1366
1393
|
)
|
|
1367
1394
|
|
|
1368
1395
|
# Create LLM config
|
|
1369
1396
|
llm_config = {
|
|
1370
1397
|
'max_tokens': max_tokens,
|
|
1371
1398
|
'temperature': temperature,
|
|
1372
|
-
'
|
|
1399
|
+
'reasoning_effort': reasoning_effort
|
|
1373
1400
|
}
|
|
1374
1401
|
|
|
1375
1402
|
col1, col2 = st.columns([3, 1])
|
|
@@ -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,8 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from enum import Enum
|
|
3
3
|
|
|
4
|
+
# DEPRECATED: Tool names no longer use prefixes
|
|
5
|
+
# Kept for backward compatibility only
|
|
4
6
|
TOOLKIT_SPLITTER = "___"
|
|
5
7
|
|
|
6
8
|
class IndexerKeywords(Enum):
|
|
@@ -9,6 +11,12 @@ class IndexerKeywords(Enum):
|
|
|
9
11
|
PARENT = 'parent_id'
|
|
10
12
|
# DEPENDENCY_ID = 'dependency_id'
|
|
11
13
|
UPDATED_ON = 'updated_on'
|
|
14
|
+
CONTENT_IN_BYTES = 'loader_content'
|
|
15
|
+
CONTENT_FILE_NAME = 'loader_content_type'
|
|
16
|
+
INDEX_META_TYPE = 'index_meta'
|
|
17
|
+
INDEX_META_IN_PROGRESS = 'in_progress'
|
|
18
|
+
INDEX_META_COMPLETED = 'completed'
|
|
19
|
+
INDEX_META_FAILED = 'failed'
|
|
12
20
|
|
|
13
21
|
# This pattern matches characters that are NOT alphanumeric, underscores, or hyphens
|
|
14
22
|
clean_string_pattern = re.compile(r'[^a-zA-Z0-9_.-]')
|
|
@@ -18,3 +26,9 @@ def clean_string(s: str) -> str:
|
|
|
18
26
|
# Replace these characters with an empty string
|
|
19
27
|
cleaned_string = re.sub(clean_string_pattern, '', s)
|
|
20
28
|
return cleaned_string
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def clean_node_str(s: str) -> str:
|
|
32
|
+
"""Cleans a node string by removing all non-alphanumeric characters except underscores and spaces."""
|
|
33
|
+
cleaned_string = re.sub(r'[^\w\s]', '', s)
|
|
34
|
+
return cleaned_string
|
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:
|
|
@@ -34,6 +58,7 @@ def _safe_import_tool(tool_name, module_path, get_tools_name=None, toolkit_class
|
|
|
34
58
|
FAILED_IMPORTS[tool_name] = str(e)
|
|
35
59
|
logger.debug(f"Failed to import {tool_name}: {e}")
|
|
36
60
|
|
|
61
|
+
|
|
37
62
|
# Safe imports for all tools
|
|
38
63
|
_safe_import_tool('github', 'github', 'get_tools', 'AlitaGitHubToolkit')
|
|
39
64
|
_safe_import_tool('openapi', 'openapi', 'get_tools')
|
|
@@ -67,7 +92,7 @@ _safe_import_tool('aws', 'cloud.aws', None, 'AWSToolkit')
|
|
|
67
92
|
_safe_import_tool('azure', 'cloud.azure', None, 'AzureToolkit')
|
|
68
93
|
_safe_import_tool('gcp', 'cloud.gcp', None, 'GCPToolkit')
|
|
69
94
|
_safe_import_tool('k8s', 'cloud.k8s', None, 'KubernetesToolkit')
|
|
70
|
-
_safe_import_tool('custom_open_api', 'custom_open_api', None, 'OpenApiToolkit')
|
|
95
|
+
# _safe_import_tool('custom_open_api', 'custom_open_api', None, 'OpenApiToolkit')
|
|
71
96
|
_safe_import_tool('elastic', 'elastic', None, 'ElasticToolkit')
|
|
72
97
|
_safe_import_tool('keycloak', 'keycloak', None, 'KeycloakToolkit')
|
|
73
98
|
_safe_import_tool('localgit', 'localgit', None, 'AlitaLocalGitToolkit')
|
|
@@ -79,7 +104,6 @@ _safe_import_tool('carrier', 'carrier', 'get_tools', 'AlitaCarrierToolkit')
|
|
|
79
104
|
_safe_import_tool('ocr', 'ocr', 'get_tools', 'OCRToolkit')
|
|
80
105
|
_safe_import_tool('pptx', 'pptx', 'get_tools', 'PPTXToolkit')
|
|
81
106
|
_safe_import_tool('postman', 'postman', 'get_tools', 'PostmanToolkit')
|
|
82
|
-
_safe_import_tool('memory', 'memory', 'get_tools', 'MemoryToolkit')
|
|
83
107
|
_safe_import_tool('zephyr_squad', 'zephyr_squad', 'get_tools', 'ZephyrSquadToolkit')
|
|
84
108
|
_safe_import_tool('zephyr_essential', 'zephyr_essential', 'get_tools', 'ZephyrEssentialToolkit')
|
|
85
109
|
_safe_import_tool('slack', 'slack', 'get_tools', 'SlackToolkit')
|
|
@@ -91,62 +115,81 @@ available_count = len(AVAILABLE_TOOLS)
|
|
|
91
115
|
total_attempted = len(AVAILABLE_TOOLS) + len(FAILED_IMPORTS)
|
|
92
116
|
logger.info(f"Tool imports completed: {available_count}/{total_attempted} successful")
|
|
93
117
|
|
|
118
|
+
# Import community module to trigger community toolkit registration
|
|
119
|
+
try:
|
|
120
|
+
from alita_sdk import community # noqa: F401
|
|
121
|
+
logger.debug("Community toolkits registered successfully")
|
|
122
|
+
except ImportError as e:
|
|
123
|
+
logger.debug(f"Community module not available: {e}")
|
|
124
|
+
|
|
125
|
+
|
|
94
126
|
def get_tools(tools_list, alita, llm, store: Optional[BaseStore] = None, *args, **kwargs):
|
|
95
127
|
tools = []
|
|
128
|
+
|
|
96
129
|
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']
|
|
130
|
+
toolkit_tools = []
|
|
131
|
+
settings = tool.get('settings')
|
|
106
132
|
|
|
107
|
-
#
|
|
108
|
-
if
|
|
109
|
-
|
|
133
|
+
# Skip tools without settings early
|
|
134
|
+
if not settings:
|
|
135
|
+
logger.warning(f"Tool '{tool.get('type', '')}' has no settings, skipping...")
|
|
136
|
+
continue
|
|
110
137
|
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
138
|
+
# Validate tool names once
|
|
139
|
+
selected_tools = settings.get('selected_tools', [])
|
|
140
|
+
invalid_tools = [name for name in selected_tools if isinstance(name, str) and name.startswith('_')]
|
|
141
|
+
if invalid_tools:
|
|
142
|
+
raise ValueError(f"Tool names {invalid_tools} from toolkit '{tool.get('type', '')}' cannot start with '_'")
|
|
116
143
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
# Cache tool type and add common settings
|
|
145
|
+
tool_type = tool['type']
|
|
146
|
+
settings['alita'] = alita
|
|
147
|
+
settings['llm'] = llm
|
|
148
|
+
settings['store'] = store
|
|
120
149
|
|
|
121
|
-
#
|
|
150
|
+
# Set pgvector collection schema if present
|
|
151
|
+
if settings.get('pgvector_configuration'):
|
|
152
|
+
# Use tool id if available, otherwise use toolkit_name or type as fallback
|
|
153
|
+
collection_id = tool.get('id') or tool.get('toolkit_name') or tool_type
|
|
154
|
+
settings['pgvector_configuration']['collection_schema'] = str(collection_id)
|
|
155
|
+
|
|
156
|
+
# Handle ADO special cases
|
|
157
|
+
if tool_type in ['ado_boards', 'ado_wiki', 'ado_plans']:
|
|
158
|
+
toolkit_tools.extend(AVAILABLE_TOOLS['ado']['get_tools'](tool_type, tool))
|
|
122
159
|
elif tool_type in ['ado_repos', 'azure_devops_repos'] and 'ado_repos' in AVAILABLE_TOOLS:
|
|
123
160
|
try:
|
|
124
|
-
|
|
125
|
-
tools.extend(get_tools_func(tool))
|
|
161
|
+
toolkit_tools.extend(AVAILABLE_TOOLS['ado_repos']['get_tools'](tool))
|
|
126
162
|
except Exception as e:
|
|
127
163
|
logger.error(f"Error getting ADO repos tools: {e}")
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
elif
|
|
164
|
+
elif tool_type == 'mcp':
|
|
165
|
+
logger.debug(f"Skipping MCP toolkit '{tool.get('toolkit_name')}' - handled by runtime toolkit system")
|
|
166
|
+
elif tool_type == 'planning':
|
|
167
|
+
logger.debug(f"Skipping planning toolkit '{tool.get('toolkit_name')}' - handled by runtime toolkit system")
|
|
168
|
+
elif tool_type in AVAILABLE_TOOLS and 'get_tools' in AVAILABLE_TOOLS[tool_type]:
|
|
169
|
+
try:
|
|
170
|
+
toolkit_tools.extend(AVAILABLE_TOOLS[tool_type]['get_tools'](tool))
|
|
171
|
+
except Exception as e:
|
|
172
|
+
logger.error(f"Error getting tools for {tool_type}: {e}")
|
|
173
|
+
raise ToolException(f"Error getting tools for {tool_type}: {e}")
|
|
174
|
+
elif settings.get("module"):
|
|
131
175
|
try:
|
|
132
|
-
settings = tool.get("settings", {})
|
|
133
176
|
mod = import_module(settings.pop("module"))
|
|
134
177
|
tkitclass = getattr(mod, settings.pop("class"))
|
|
135
|
-
|
|
136
|
-
get_toolkit_params = tool["settings"].copy()
|
|
178
|
+
get_toolkit_params = settings.copy()
|
|
137
179
|
get_toolkit_params["name"] = tool.get("name")
|
|
138
|
-
#
|
|
139
180
|
toolkit = tkitclass.get_toolkit(**get_toolkit_params)
|
|
140
|
-
|
|
181
|
+
toolkit_tools.extend(toolkit.get_tools())
|
|
141
182
|
except Exception as e:
|
|
142
183
|
logger.error(f"Error in getting custom toolkit: {e}")
|
|
143
|
-
|
|
144
184
|
else:
|
|
145
|
-
# Tool not available or not found
|
|
146
185
|
if tool_type in FAILED_IMPORTS:
|
|
147
186
|
logger.warning(f"Tool '{tool_type}' is not available: {FAILED_IMPORTS[tool_type]}")
|
|
148
187
|
else:
|
|
149
188
|
logger.warning(f"Unknown tool type: {tool_type}")
|
|
189
|
+
#
|
|
190
|
+
# Always inject toolkit_id to each tool
|
|
191
|
+
_inject_toolkit_id(tool, toolkit_tools)
|
|
192
|
+
tools.extend(toolkit_tools)
|
|
150
193
|
|
|
151
194
|
return tools
|
|
152
195
|
|
alita_sdk/tools/ado/__init__.py
CHANGED
|
@@ -9,7 +9,6 @@ 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', ''),
|
|
@@ -5,11 +5,12 @@ 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
|
|
13
14
|
|
|
14
15
|
name = "ado_repos"
|
|
15
16
|
|
|
@@ -26,6 +27,7 @@ def _get_toolkit(tool) -> BaseToolkit:
|
|
|
26
27
|
embedding_model=tool['settings'].get('embedding_model'),
|
|
27
28
|
collection_name=tool['toolkit_name'],
|
|
28
29
|
alita=tool['settings'].get('alita', None),
|
|
30
|
+
llm=tool['settings'].get('llm', None),
|
|
29
31
|
)
|
|
30
32
|
|
|
31
33
|
def get_toolkit():
|
|
@@ -36,12 +38,10 @@ def get_tools(tool):
|
|
|
36
38
|
|
|
37
39
|
class AzureDevOpsReposToolkit(BaseToolkit):
|
|
38
40
|
tools: List[BaseTool] = []
|
|
39
|
-
toolkit_max_length: int = 0
|
|
40
41
|
|
|
41
42
|
@staticmethod
|
|
42
43
|
def toolkit_config_schema() -> BaseModel:
|
|
43
44
|
selected_tools = {x['name']: x['args_schema'].schema() for x in ReposApiWrapper.model_construct().get_available_tools()}
|
|
44
|
-
AzureDevOpsReposToolkit.toolkit_max_length = get_max_toolkit_length(selected_tools)
|
|
45
45
|
m = create_model(
|
|
46
46
|
name,
|
|
47
47
|
ado_repos_configuration=(AdoReposConfiguration, Field(description="Ado Repos configuration", default=None,
|
|
@@ -77,6 +77,7 @@ class AzureDevOpsReposToolkit(BaseToolkit):
|
|
|
77
77
|
return m
|
|
78
78
|
|
|
79
79
|
@classmethod
|
|
80
|
+
@filter_missconfigured_index_tools
|
|
80
81
|
def get_toolkit(cls, selected_tools: list[str] | None = None, toolkit_name: Optional[str] = None, **kwargs):
|
|
81
82
|
from os import environ
|
|
82
83
|
|
|
@@ -95,16 +96,19 @@ class AzureDevOpsReposToolkit(BaseToolkit):
|
|
|
95
96
|
azure_devops_repos_wrapper = ReposApiWrapper(**wrapper_payload)
|
|
96
97
|
available_tools = azure_devops_repos_wrapper.get_available_tools()
|
|
97
98
|
tools = []
|
|
98
|
-
prefix = clean_string(toolkit_name, cls.toolkit_max_length) + TOOLKIT_SPLITTER if toolkit_name else ''
|
|
99
99
|
for tool in available_tools:
|
|
100
100
|
if selected_tools:
|
|
101
101
|
if tool["name"] not in selected_tools:
|
|
102
102
|
continue
|
|
103
|
+
description = tool["description"] + f"\nADO instance: {azure_devops_repos_wrapper.organization_url}/{azure_devops_repos_wrapper.project}"
|
|
104
|
+
if toolkit_name:
|
|
105
|
+
description = f"{description}\nToolkit: {toolkit_name}"
|
|
106
|
+
description = description[:1000]
|
|
103
107
|
tools.append(
|
|
104
108
|
BaseAction(
|
|
105
109
|
api_wrapper=azure_devops_repos_wrapper,
|
|
106
|
-
name=
|
|
107
|
-
description=
|
|
110
|
+
name=tool["name"],
|
|
111
|
+
description=description,
|
|
108
112
|
args_schema=tool["args_schema"],
|
|
109
113
|
)
|
|
110
114
|
)
|