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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from langchain_core.tools import ToolException
|
|
4
5
|
from langgraph.store.base import BaseStore
|
|
@@ -8,13 +9,22 @@ from alita_sdk.tools import get_tools as alita_tools
|
|
|
8
9
|
from .application import ApplicationToolkit
|
|
9
10
|
from .artifact import ArtifactToolkit
|
|
10
11
|
from .datasource import DatasourcesToolkit
|
|
12
|
+
from .planning import PlanningToolkit
|
|
11
13
|
from .prompt import PromptToolkit
|
|
12
14
|
from .subgraph import SubgraphToolkit
|
|
13
15
|
from .vectorstore import VectorStoreToolkit
|
|
16
|
+
from .mcp import McpToolkit
|
|
17
|
+
from .skill_router import SkillRouterToolkit
|
|
14
18
|
from ..tools.mcp_server_tool import McpServerTool
|
|
19
|
+
from ..tools.sandbox import SandboxToolkit
|
|
20
|
+
from ..tools.image_generation import ImageGenerationToolkit
|
|
21
|
+
from ..tools.data_analysis import DataAnalysisToolkit
|
|
15
22
|
# Import community tools
|
|
16
23
|
from ...community import get_toolkits as community_toolkits, get_tools as community_tools
|
|
17
24
|
from ...tools.memory import MemoryToolkit
|
|
25
|
+
from ..utils.mcp_oauth import canonical_resource, McpAuthorizationRequired
|
|
26
|
+
from ...tools.utils import clean_string
|
|
27
|
+
from alita_sdk.tools import _inject_toolkit_id
|
|
18
28
|
|
|
19
29
|
logger = logging.getLogger(__name__)
|
|
20
30
|
|
|
@@ -23,78 +33,291 @@ def get_toolkits():
|
|
|
23
33
|
core_toolkits = [
|
|
24
34
|
ArtifactToolkit.toolkit_config_schema(),
|
|
25
35
|
MemoryToolkit.toolkit_config_schema(),
|
|
26
|
-
|
|
36
|
+
PlanningToolkit.toolkit_config_schema(),
|
|
37
|
+
VectorStoreToolkit.toolkit_config_schema(),
|
|
38
|
+
SandboxToolkit.toolkit_config_schema(),
|
|
39
|
+
ImageGenerationToolkit.toolkit_config_schema(),
|
|
40
|
+
DataAnalysisToolkit.toolkit_config_schema(),
|
|
41
|
+
McpToolkit.toolkit_config_schema(),
|
|
42
|
+
SkillRouterToolkit.toolkit_config_schema()
|
|
27
43
|
]
|
|
28
44
|
|
|
29
45
|
return core_toolkits + community_toolkits() + alita_toolkits()
|
|
30
46
|
|
|
31
47
|
|
|
32
|
-
def get_tools(tools_list: list, alita_client, llm, memory_store: BaseStore = None) -> list:
|
|
48
|
+
def get_tools(tools_list: list, alita_client=None, llm=None, memory_store: BaseStore = None, debug_mode: Optional[bool] = False, mcp_tokens: Optional[dict] = None, conversation_id: Optional[str] = None, ignored_mcp_servers: Optional[list] = None) -> list:
|
|
49
|
+
# Sanitize tools_list to handle corrupted tool configurations
|
|
50
|
+
sanitized_tools = []
|
|
51
|
+
for tool in tools_list:
|
|
52
|
+
if isinstance(tool, dict):
|
|
53
|
+
# Check for corrupted structure where 'type' and 'name' contain the full tool config
|
|
54
|
+
if 'type' in tool and isinstance(tool['type'], dict):
|
|
55
|
+
# This is a corrupted tool - use the inner dict instead
|
|
56
|
+
logger.warning(f"Detected corrupted tool configuration (type=dict), fixing: {tool}")
|
|
57
|
+
actual_tool = tool['type'] # or tool['name'], they should be the same
|
|
58
|
+
sanitized_tools.append(actual_tool)
|
|
59
|
+
elif 'name' in tool and isinstance(tool['name'], dict):
|
|
60
|
+
# Another corruption pattern where name contains the full config
|
|
61
|
+
logger.warning(f"Detected corrupted tool configuration (name=dict), fixing: {tool}")
|
|
62
|
+
actual_tool = tool['name']
|
|
63
|
+
sanitized_tools.append(actual_tool)
|
|
64
|
+
elif 'type' in tool and isinstance(tool['type'], str):
|
|
65
|
+
# Valid tool configuration
|
|
66
|
+
sanitized_tools.append(tool)
|
|
67
|
+
else:
|
|
68
|
+
# Skip invalid/corrupted tools that can't be fixed
|
|
69
|
+
logger.warning(f"Skipping invalid tool configuration: {tool}")
|
|
70
|
+
else:
|
|
71
|
+
logger.warning(f"Skipping non-dict tool: {tool}")
|
|
72
|
+
# Skip non-dict tools
|
|
73
|
+
|
|
33
74
|
prompts = []
|
|
34
75
|
tools = []
|
|
76
|
+
unhandled_tools = [] # Track tools not handled by main processing
|
|
77
|
+
|
|
78
|
+
for tool in sanitized_tools:
|
|
79
|
+
# Flag to track if this tool was processed by the main loop
|
|
80
|
+
# Used to prevent double processing by fallback systems
|
|
81
|
+
tool_handled = False
|
|
82
|
+
try:
|
|
83
|
+
if tool['type'] == 'datasource':
|
|
84
|
+
tool_handled = True
|
|
85
|
+
tools.extend(DatasourcesToolkit.get_toolkit(
|
|
86
|
+
alita_client,
|
|
87
|
+
datasource_ids=[int(tool['settings']['datasource_id'])],
|
|
88
|
+
selected_tools=tool['settings']['selected_tools'],
|
|
89
|
+
toolkit_name=tool.get('toolkit_name', '') or tool.get('name', '')
|
|
90
|
+
).get_tools())
|
|
91
|
+
elif tool['type'] == 'application':
|
|
92
|
+
tool_handled = True
|
|
93
|
+
tools.extend(ApplicationToolkit.get_toolkit(
|
|
94
|
+
alita_client,
|
|
95
|
+
application_id=int(tool['settings']['application_id']),
|
|
96
|
+
application_version_id=int(tool['settings']['application_version_id']),
|
|
97
|
+
selected_tools=[],
|
|
98
|
+
ignored_mcp_servers=ignored_mcp_servers
|
|
99
|
+
).get_tools())
|
|
100
|
+
# backward compatibility for pipeline application type as subgraph node
|
|
101
|
+
if tool.get('agent_type', '') == 'pipeline':
|
|
102
|
+
# static get_toolkit returns a list of CompiledStateGraph stubs
|
|
103
|
+
tools.extend(SubgraphToolkit.get_toolkit(
|
|
104
|
+
alita_client,
|
|
105
|
+
application_id=int(tool['settings']['application_id']),
|
|
106
|
+
application_version_id=int(tool['settings']['application_version_id']),
|
|
107
|
+
app_api_key=alita_client.auth_token,
|
|
108
|
+
selected_tools=[],
|
|
109
|
+
llm=llm
|
|
110
|
+
))
|
|
111
|
+
elif tool['type'] == 'memory':
|
|
112
|
+
tool_handled = True
|
|
113
|
+
tools += MemoryToolkit.get_toolkit(
|
|
114
|
+
namespace=tool['settings'].get('namespace', str(tool['id'])),
|
|
115
|
+
pgvector_configuration=tool['settings'].get('pgvector_configuration', {}),
|
|
116
|
+
store=memory_store,
|
|
117
|
+
).get_tools()
|
|
118
|
+
# TODO: update configuration of internal tools
|
|
119
|
+
elif tool['type'] == 'internal_tool':
|
|
120
|
+
tool_handled = True
|
|
121
|
+
if tool['name'] == 'pyodide':
|
|
122
|
+
tools += SandboxToolkit.get_toolkit(
|
|
123
|
+
stateful=False,
|
|
124
|
+
allow_net=True,
|
|
125
|
+
alita_client=alita_client,
|
|
126
|
+
).get_tools()
|
|
127
|
+
elif tool['name'] == 'image_generation':
|
|
128
|
+
if alita_client and alita_client.model_image_generation:
|
|
129
|
+
tools += ImageGenerationToolkit.get_toolkit(
|
|
130
|
+
client=alita_client,
|
|
131
|
+
).get_tools()
|
|
132
|
+
else:
|
|
133
|
+
logger.warning("Image generation internal tool requested "
|
|
134
|
+
"but no image generation model configured")
|
|
135
|
+
elif tool['name'] == 'planner':
|
|
136
|
+
tools += PlanningToolkit.get_toolkit(
|
|
137
|
+
pgvector_configuration=tool.get('settings', {}).get('pgvector_configuration'),
|
|
138
|
+
conversation_id=conversation_id,
|
|
139
|
+
).get_tools()
|
|
140
|
+
elif tool['name'] == 'data_analysis':
|
|
141
|
+
# Data Analysis internal tool - uses conversation attachment bucket
|
|
142
|
+
settings = tool.get('settings', {})
|
|
143
|
+
bucket_name = settings.get('bucket_name')
|
|
144
|
+
if bucket_name:
|
|
145
|
+
tools += DataAnalysisToolkit.get_toolkit(
|
|
146
|
+
alita_client=alita_client,
|
|
147
|
+
llm=llm,
|
|
148
|
+
bucket_name=bucket_name,
|
|
149
|
+
toolkit_name="Data Analyst",
|
|
150
|
+
).get_tools()
|
|
151
|
+
else:
|
|
152
|
+
logger.warning("Data Analysis internal tool requested "
|
|
153
|
+
"but no bucket_name provided in settings")
|
|
154
|
+
elif tool['type'] == 'artifact':
|
|
155
|
+
tool_handled = True
|
|
156
|
+
toolkit_tools = ArtifactToolkit.get_toolkit(
|
|
157
|
+
client=alita_client,
|
|
158
|
+
bucket=tool['settings']['bucket'],
|
|
159
|
+
toolkit_name=tool.get('toolkit_name', ''),
|
|
160
|
+
selected_tools=tool['settings'].get('selected_tools', []),
|
|
161
|
+
llm=llm,
|
|
162
|
+
# indexer settings
|
|
163
|
+
pgvector_configuration=tool['settings'].get('pgvector_configuration', {}),
|
|
164
|
+
embedding_model=tool['settings'].get('embedding_model'),
|
|
165
|
+
collection_name=f"{tool.get('toolkit_name')}",
|
|
166
|
+
collection_schema=str(tool['settings'].get('id', tool.get('id', ''))),
|
|
167
|
+
).get_tools()
|
|
168
|
+
# Inject toolkit_id for artifact tools as well
|
|
169
|
+
# Pass settings as the tool config since that's where the id field is
|
|
170
|
+
_inject_toolkit_id(tool['settings'], toolkit_tools)
|
|
171
|
+
tools.extend(toolkit_tools)
|
|
172
|
+
|
|
173
|
+
elif tool['type'] == 'vectorstore':
|
|
174
|
+
tool_handled = True
|
|
175
|
+
tools.extend(VectorStoreToolkit.get_toolkit(
|
|
176
|
+
llm=llm,
|
|
177
|
+
toolkit_name=tool.get('toolkit_name', ''),
|
|
178
|
+
**tool['settings']).get_tools())
|
|
179
|
+
elif tool['type'] == 'planning':
|
|
180
|
+
tool_handled = True
|
|
181
|
+
# Planning toolkit for multi-step task tracking
|
|
182
|
+
settings = tool.get('settings', {})
|
|
183
|
+
|
|
184
|
+
# Check if local mode is enabled (uses filesystem storage, ignores pgvector)
|
|
185
|
+
use_local = settings.get('local', False)
|
|
186
|
+
|
|
187
|
+
if use_local:
|
|
188
|
+
# Local mode - use filesystem storage
|
|
189
|
+
logger.info("Planning toolkit using local filesystem storage (local=true)")
|
|
190
|
+
pgvector_config = {}
|
|
191
|
+
else:
|
|
192
|
+
# Check if explicit connection_string is provided in pgvector_configuration
|
|
193
|
+
explicit_pgvector_config = settings.get('pgvector_configuration', {})
|
|
194
|
+
explicit_connstr = explicit_pgvector_config.get('connection_string') if explicit_pgvector_config else None
|
|
195
|
+
|
|
196
|
+
if explicit_connstr:
|
|
197
|
+
# Use explicitly provided connection string (overrides project secrets)
|
|
198
|
+
logger.info("Using explicit connection_string for planning toolkit")
|
|
199
|
+
pgvector_config = explicit_pgvector_config
|
|
200
|
+
else:
|
|
201
|
+
# Try to fetch pgvector_project_connstr from project secrets
|
|
202
|
+
pgvector_connstr = None
|
|
203
|
+
if alita_client:
|
|
204
|
+
try:
|
|
205
|
+
pgvector_connstr = alita_client.unsecret('pgvector_project_connstr')
|
|
206
|
+
if pgvector_connstr:
|
|
207
|
+
logger.info("Using pgvector_project_connstr for planning toolkit")
|
|
208
|
+
except Exception as e:
|
|
209
|
+
logger.debug(f"pgvector_project_connstr not available: {e}")
|
|
210
|
+
|
|
211
|
+
pgvector_config = {'connection_string': pgvector_connstr} if pgvector_connstr else {}
|
|
212
|
+
|
|
213
|
+
tools.extend(PlanningToolkit.get_toolkit(
|
|
214
|
+
toolkit_name=tool.get('toolkit_name', ''),
|
|
215
|
+
selected_tools=settings.get('selected_tools', []),
|
|
216
|
+
pgvector_configuration=pgvector_config,
|
|
217
|
+
conversation_id=conversation_id or settings.get('conversation_id'),
|
|
218
|
+
).get_tools())
|
|
219
|
+
elif tool['type'] == 'mcp':
|
|
220
|
+
tool_handled = True
|
|
221
|
+
# remote mcp tool initialization with token injection
|
|
222
|
+
settings = dict(tool['settings'])
|
|
223
|
+
url = settings.get('url')
|
|
224
|
+
|
|
225
|
+
# Check if this MCP server should be ignored (user chose to continue without auth)
|
|
226
|
+
if ignored_mcp_servers and url:
|
|
227
|
+
canonical_url = canonical_resource(url)
|
|
228
|
+
if canonical_url in ignored_mcp_servers or url in ignored_mcp_servers:
|
|
229
|
+
logger.info(f"[MCP Auth] Skipping ignored MCP server: {url}")
|
|
230
|
+
continue
|
|
231
|
+
|
|
232
|
+
headers = settings.get('headers')
|
|
233
|
+
token_data = None
|
|
234
|
+
session_id = None
|
|
235
|
+
if mcp_tokens and url:
|
|
236
|
+
canonical_url = canonical_resource(url)
|
|
237
|
+
logger.info(f"[MCP Auth] Looking for token for URL: {url}")
|
|
238
|
+
logger.info(f"[MCP Auth] Canonical URL: {canonical_url}")
|
|
239
|
+
logger.info(f"[MCP Auth] Available tokens: {list(mcp_tokens.keys())}")
|
|
240
|
+
token_data = mcp_tokens.get(canonical_url)
|
|
241
|
+
if token_data:
|
|
242
|
+
logger.info(f"[MCP Auth] Found token data for {canonical_url}")
|
|
243
|
+
# Handle both old format (string) and new format (dict with access_token and session_id)
|
|
244
|
+
if isinstance(token_data, dict):
|
|
245
|
+
access_token = token_data.get('access_token')
|
|
246
|
+
session_id = token_data.get('session_id')
|
|
247
|
+
logger.info(f"[MCP Auth] Token data: access_token={'present' if access_token else 'missing'}, session_id={session_id or 'none'}")
|
|
248
|
+
else:
|
|
249
|
+
# Backward compatibility: treat as plain token string
|
|
250
|
+
access_token = token_data
|
|
251
|
+
logger.info(f"[MCP Auth] Using legacy token format (string)")
|
|
252
|
+
else:
|
|
253
|
+
access_token = None
|
|
254
|
+
logger.warning(f"[MCP Auth] No token found for {canonical_url}")
|
|
255
|
+
else:
|
|
256
|
+
access_token = None
|
|
257
|
+
|
|
258
|
+
if access_token:
|
|
259
|
+
merged_headers = dict(headers) if headers else {}
|
|
260
|
+
merged_headers.setdefault('Authorization', f'Bearer {access_token}')
|
|
261
|
+
settings['headers'] = merged_headers
|
|
262
|
+
logger.info(f"[MCP Auth] Added Authorization header for {url}")
|
|
263
|
+
|
|
264
|
+
# Pass session_id to MCP toolkit if available
|
|
265
|
+
if session_id:
|
|
266
|
+
settings['session_id'] = session_id
|
|
267
|
+
logger.info(f"[MCP Auth] Passing session_id to toolkit: {session_id}")
|
|
268
|
+
tools.extend(McpToolkit.get_toolkit(
|
|
269
|
+
toolkit_name=tool.get('toolkit_name', ''),
|
|
270
|
+
client=alita_client,
|
|
271
|
+
**settings).get_tools())
|
|
272
|
+
elif tool['type'] == 'skill_router':
|
|
273
|
+
tool_handled = True
|
|
274
|
+
# Skills Registry Router Toolkit
|
|
275
|
+
logger.info(f"Processing skill_router toolkit: {tool}")
|
|
276
|
+
try:
|
|
277
|
+
settings = tool.get('settings', {})
|
|
278
|
+
toolkit_name = tool.get('toolkit_name', '')
|
|
279
|
+
selected_tools = settings.get('selected_tools', [])
|
|
280
|
+
|
|
281
|
+
toolkit_tools = SkillRouterToolkit.get_toolkit(
|
|
282
|
+
client=alita_client,
|
|
283
|
+
llm=llm,
|
|
284
|
+
toolkit_name=toolkit_name,
|
|
285
|
+
selected_tools=selected_tools,
|
|
286
|
+
**settings
|
|
287
|
+
).get_tools()
|
|
288
|
+
|
|
289
|
+
tools.extend(toolkit_tools)
|
|
290
|
+
logger.info(f"✅ Successfully added {len(toolkit_tools)} tools from SkillRouterToolkit")
|
|
291
|
+
except Exception as e:
|
|
292
|
+
logger.error(f"❌ Failed to initialize SkillRouterToolkit: {e}")
|
|
293
|
+
raise
|
|
294
|
+
except McpAuthorizationRequired:
|
|
295
|
+
# Re-raise auth required exceptions directly
|
|
296
|
+
raise
|
|
297
|
+
except Exception as e:
|
|
298
|
+
logger.error(f"Error initializing toolkit for tool '{tool.get('name', 'unknown')}': {e}", exc_info=True)
|
|
299
|
+
if debug_mode:
|
|
300
|
+
logger.info("Skipping tool initialization error due to debug mode.")
|
|
301
|
+
continue
|
|
302
|
+
else:
|
|
303
|
+
raise ToolException(f"Error initializing toolkit for tool '{tool.get('name', 'unknown')}': {e}")
|
|
304
|
+
|
|
305
|
+
# Track unhandled tools (make a copy to avoid reference issues)
|
|
306
|
+
if not tool_handled:
|
|
307
|
+
# Ensure we only add valid tool configurations to unhandled_tools
|
|
308
|
+
if isinstance(tool, dict) and 'type' in tool and isinstance(tool['type'], str):
|
|
309
|
+
unhandled_tools.append(dict(tool))
|
|
35
310
|
|
|
36
|
-
for tool in tools_list:
|
|
37
|
-
if tool['type'] == 'datasource':
|
|
38
|
-
tools.extend(DatasourcesToolkit.get_toolkit(
|
|
39
|
-
alita_client,
|
|
40
|
-
datasource_ids=[int(tool['settings']['datasource_id'])],
|
|
41
|
-
selected_tools=tool['settings']['selected_tools'],
|
|
42
|
-
toolkit_name=tool.get('toolkit_name', '') or tool.get('name', '')
|
|
43
|
-
).get_tools())
|
|
44
|
-
elif tool['type'] == 'application' and tool.get('agent_type', '') != 'pipeline' :
|
|
45
|
-
tools.extend(ApplicationToolkit.get_toolkit(
|
|
46
|
-
alita_client,
|
|
47
|
-
application_id=int(tool['settings']['application_id']),
|
|
48
|
-
application_version_id=int(tool['settings']['application_version_id']),
|
|
49
|
-
selected_tools=[]
|
|
50
|
-
).get_tools())
|
|
51
|
-
elif tool['type'] == 'application' and tool.get('agent_type', '') == 'pipeline':
|
|
52
|
-
# static get_toolkit returns a list of CompiledStateGraph stubs
|
|
53
|
-
tools.extend(SubgraphToolkit.get_toolkit(
|
|
54
|
-
alita_client,
|
|
55
|
-
application_id=int(tool['settings']['application_id']),
|
|
56
|
-
application_version_id=int(tool['settings']['application_version_id']),
|
|
57
|
-
app_api_key=alita_client.auth_token,
|
|
58
|
-
selected_tools=[],
|
|
59
|
-
llm=llm
|
|
60
|
-
))
|
|
61
|
-
elif tool['type'] == 'memory':
|
|
62
|
-
if memory_store is None:
|
|
63
|
-
raise ToolException(f"Memory store is not provided for memory tool: {tool.get('name', tool.get('toolkit_name', 'unknown'))}")
|
|
64
|
-
tools += MemoryToolkit.get_toolkit(
|
|
65
|
-
namespace=tool['settings'].get('namespace', str(tool['id'])),
|
|
66
|
-
store=memory_store,
|
|
67
|
-
toolkit_name=tool.get('toolkit_name', '')
|
|
68
|
-
).get_tools()
|
|
69
|
-
elif tool['type'] == 'artifact':
|
|
70
|
-
tools.extend(ArtifactToolkit.get_toolkit(
|
|
71
|
-
client=alita_client,
|
|
72
|
-
bucket=tool['settings']['bucket'],
|
|
73
|
-
toolkit_name=tool.get('toolkit_name', ''),
|
|
74
|
-
selected_tools=tool['settings'].get('selected_tools', []),
|
|
75
|
-
llm=tool['settings'].get('llm'),
|
|
76
|
-
# indexer settings
|
|
77
|
-
connection_string=tool['settings'].get('connection_string', None),
|
|
78
|
-
collection_name=tool.get('toolkit_name'),
|
|
79
|
-
embedding_model=tool['settings'].get('embedding_model'),
|
|
80
|
-
embedding_model_params=tool['settings'].get('embedding_model_params', None),
|
|
81
|
-
vectorstore_type="PGVector"
|
|
82
|
-
).get_tools())
|
|
83
|
-
elif tool['type'] == 'vectorstore':
|
|
84
|
-
tools.extend(VectorStoreToolkit.get_toolkit(
|
|
85
|
-
llm=llm,
|
|
86
|
-
toolkit_name=tool.get('toolkit_name', ''),
|
|
87
|
-
**tool['settings']).get_tools())
|
|
88
|
-
|
|
89
311
|
if len(prompts) > 0:
|
|
90
312
|
tools += PromptToolkit.get_toolkit(alita_client, prompts).get_tools()
|
|
91
|
-
|
|
92
|
-
# Add community tools
|
|
93
|
-
tools += community_tools(
|
|
94
|
-
# Add alita tools
|
|
95
|
-
tools += alita_tools(
|
|
96
|
-
# Add MCP tools
|
|
97
|
-
|
|
313
|
+
|
|
314
|
+
# Add community tools (only for unhandled tools)
|
|
315
|
+
tools += community_tools(unhandled_tools, alita_client, llm)
|
|
316
|
+
# Add alita tools (only for unhandled tools)
|
|
317
|
+
tools += alita_tools(unhandled_tools, alita_client, llm, memory_store)
|
|
318
|
+
# Add MCP tools registered via alita-mcp CLI (static registry)
|
|
319
|
+
# Note: Tools with type='mcp' are already handled in main loop above
|
|
320
|
+
tools += _mcp_tools(unhandled_tools, alita_client)
|
|
98
321
|
|
|
99
322
|
# Sanitize tool names to meet OpenAI's function naming requirements
|
|
100
323
|
# tools = _sanitize_tool_names(tools)
|
|
@@ -148,17 +371,26 @@ def _sanitize_tool_names(tools: list) -> list:
|
|
|
148
371
|
|
|
149
372
|
|
|
150
373
|
def _mcp_tools(tools_list, alita):
|
|
374
|
+
"""
|
|
375
|
+
Handle MCP tools registered via alita-mcp CLI (static registry).
|
|
376
|
+
Skips tools with type='mcp' as those are handled by dynamic discovery.
|
|
377
|
+
"""
|
|
151
378
|
try:
|
|
152
379
|
all_available_toolkits = alita.get_mcp_toolkits()
|
|
153
380
|
toolkit_lookup = {tk["name"]: tk for tk in all_available_toolkits}
|
|
154
381
|
tools = []
|
|
155
382
|
#
|
|
156
383
|
for selected_toolkit in tools_list:
|
|
157
|
-
|
|
158
|
-
|
|
384
|
+
server_toolkit_name = selected_toolkit['type']
|
|
385
|
+
|
|
386
|
+
# Skip tools with type='mcp' - they're handled by dynamic discovery
|
|
387
|
+
if server_toolkit_name == 'mcp':
|
|
388
|
+
continue
|
|
389
|
+
|
|
390
|
+
toolkit_conf = toolkit_lookup.get(server_toolkit_name)
|
|
159
391
|
#
|
|
160
392
|
if not toolkit_conf:
|
|
161
|
-
logger.debug(f"Toolkit '{
|
|
393
|
+
logger.debug(f"Toolkit '{server_toolkit_name}' not found in available MCP toolkits. Skipping...")
|
|
162
394
|
continue
|
|
163
395
|
#
|
|
164
396
|
available_tools = toolkit_conf.get("tools", [])
|
|
@@ -166,7 +398,11 @@ def _mcp_tools(tools_list, alita):
|
|
|
166
398
|
for available_tool in available_tools:
|
|
167
399
|
tool_name = available_tool.get("name", "").lower()
|
|
168
400
|
if not selected_tools or tool_name in selected_tools:
|
|
169
|
-
if server_tool := _init_single_mcp_tool(
|
|
401
|
+
if server_tool := _init_single_mcp_tool(server_toolkit_name,
|
|
402
|
+
# selected_toolkit["name"] is None for toolkit_test
|
|
403
|
+
selected_toolkit["toolkit_name"] if selected_toolkit.get("toolkit_name")
|
|
404
|
+
else server_toolkit_name,
|
|
405
|
+
available_tool, alita, selected_toolkit['settings']):
|
|
170
406
|
tools.append(server_tool)
|
|
171
407
|
return tools
|
|
172
408
|
except Exception:
|
|
@@ -174,19 +410,27 @@ def _mcp_tools(tools_list, alita):
|
|
|
174
410
|
return []
|
|
175
411
|
|
|
176
412
|
|
|
177
|
-
def _init_single_mcp_tool(toolkit_name, available_tool, alita, toolkit_settings):
|
|
413
|
+
def _init_single_mcp_tool(server_toolkit_name, toolkit_name, available_tool, alita, toolkit_settings):
|
|
178
414
|
try:
|
|
415
|
+
# Use clean tool name without prefix
|
|
179
416
|
tool_name = available_tool["name"]
|
|
417
|
+
# Add toolkit context to description (max 1000 chars)
|
|
418
|
+
toolkit_context = f" [Toolkit: {clean_string(toolkit_name)}]" if toolkit_name else ''
|
|
419
|
+
base_description = f"MCP for a tool '{tool_name}': {available_tool.get('description', '')}"
|
|
420
|
+
description = base_description
|
|
421
|
+
if toolkit_context and len(base_description + toolkit_context) <= 1000:
|
|
422
|
+
description = base_description + toolkit_context
|
|
423
|
+
|
|
180
424
|
return McpServerTool(
|
|
181
425
|
name=tool_name,
|
|
182
|
-
description=
|
|
426
|
+
description=description,
|
|
183
427
|
args_schema=McpServerTool.create_pydantic_model_from_schema(
|
|
184
428
|
available_tool.get("inputSchema", {})
|
|
185
429
|
),
|
|
186
430
|
client=alita,
|
|
187
|
-
server=
|
|
431
|
+
server=server_toolkit_name,
|
|
188
432
|
tool_timeout_sec=toolkit_settings.get("timeout", 90)
|
|
189
433
|
)
|
|
190
434
|
except Exception as e:
|
|
191
|
-
logger.error(f"Failed to create McpServerTool for '{toolkit_name}.{tool_name}': {e}")
|
|
435
|
+
logger.error(f"Failed to create McpServerTool ('{server_toolkit_name}') for '{toolkit_name}.{tool_name}': {e}")
|
|
192
436
|
return None
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from logging import getLogger
|
|
2
2
|
from typing import Any, List, Literal, Optional
|
|
3
3
|
|
|
4
|
-
from alita_sdk.tools.utils import clean_string
|
|
4
|
+
from alita_sdk.tools.utils import clean_string
|
|
5
5
|
from pydantic import BaseModel, create_model, Field, ConfigDict
|
|
6
6
|
from langchain_core.tools import BaseToolkit, BaseTool
|
|
7
7
|
from alita_sdk.tools.base.tool import BaseAction
|
|
@@ -31,7 +31,8 @@ class VectorStoreToolkit(BaseToolkit):
|
|
|
31
31
|
toolkit_name: Optional[str] = None,
|
|
32
32
|
selected_tools: list[str] = []):
|
|
33
33
|
logger.info("Selected tools: %s", selected_tools)
|
|
34
|
-
|
|
34
|
+
# Use clean toolkit name for context (max 1000 chars in description)
|
|
35
|
+
toolkit_context = f" [Toolkit: {clean_string(toolkit_name)}]" if toolkit_name else ''
|
|
35
36
|
if selected_tools is None:
|
|
36
37
|
selected_tools = []
|
|
37
38
|
tools = []
|
|
@@ -46,11 +47,16 @@ class VectorStoreToolkit(BaseToolkit):
|
|
|
46
47
|
# if selected_tools:
|
|
47
48
|
# if tool["name"] not in selected_tools:
|
|
48
49
|
# continue
|
|
50
|
+
# Add toolkit context to description with character limit
|
|
51
|
+
description = tool["description"]
|
|
52
|
+
if toolkit_context and len(description + toolkit_context) <= 1000:
|
|
53
|
+
description = description + toolkit_context
|
|
49
54
|
tools.append(BaseAction(
|
|
50
55
|
api_wrapper=vectorstore_wrapper,
|
|
51
|
-
name=
|
|
52
|
-
description=
|
|
53
|
-
args_schema=tool["args_schema"]
|
|
56
|
+
name=tool["name"],
|
|
57
|
+
description=description,
|
|
58
|
+
args_schema=tool["args_schema"],
|
|
59
|
+
metadata={"toolkit_name": toolkit_name, "toolkit_type": "vectorstore"} if toolkit_name else {}
|
|
54
60
|
))
|
|
55
61
|
return cls(tools=tools)
|
|
56
62
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime tools module for Alita SDK.
|
|
3
|
+
This module provides various tools that can be used within LangGraph agents.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .sandbox import PyodideSandboxTool, StatefulPyodideSandboxTool, create_sandbox_tool
|
|
7
|
+
from .echo import EchoTool
|
|
8
|
+
from .image_generation import (
|
|
9
|
+
ImageGenerationTool,
|
|
10
|
+
create_image_generation_tool,
|
|
11
|
+
ImageGenerationToolkit
|
|
12
|
+
)
|
|
13
|
+
from .skill_router import SkillRouterWrapper
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"PyodideSandboxTool",
|
|
17
|
+
"StatefulPyodideSandboxTool",
|
|
18
|
+
"create_sandbox_tool",
|
|
19
|
+
"EchoTool",
|
|
20
|
+
"ImageGenerationTool",
|
|
21
|
+
"ImageGenerationToolkit",
|
|
22
|
+
"create_image_generation_tool",
|
|
23
|
+
"SkillRouterWrapper"
|
|
24
|
+
]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import json
|
|
2
2
|
|
|
3
3
|
from ..utils.utils import clean_string
|
|
4
|
-
from langchain_core.tools import BaseTool
|
|
5
|
-
from langchain_core.messages import BaseMessage, AIMessage,
|
|
6
|
-
from typing import Any, Type, Optional
|
|
4
|
+
from langchain_core.tools import BaseTool, ToolException
|
|
5
|
+
from langchain_core.messages import BaseMessage, AIMessage, HumanMessage
|
|
6
|
+
from typing import Any, Type, Optional
|
|
7
7
|
from pydantic import create_model, field_validator, BaseModel
|
|
8
8
|
from pydantic.fields import FieldInfo
|
|
9
9
|
from ..langchain.mixedAgentRenderes import convert_message_to_json
|
|
@@ -31,7 +31,12 @@ def formulate_query(kwargs):
|
|
|
31
31
|
chat_history = []
|
|
32
32
|
for each in kwargs.get('chat_history')[:]:
|
|
33
33
|
chat_history.append(AIMessage(each))
|
|
34
|
-
|
|
34
|
+
user_task = kwargs.get('task')
|
|
35
|
+
if not user_task:
|
|
36
|
+
raise ToolException("Task is required to invoke the application. "
|
|
37
|
+
"Check the provided input (some errors may happen on previous steps).")
|
|
38
|
+
input_message = HumanMessage(content=user_task)
|
|
39
|
+
result = {"input": [input_message], "chat_history": chat_history}
|
|
35
40
|
for key, value in kwargs.items():
|
|
36
41
|
if key not in ("task", "chat_history"):
|
|
37
42
|
result[key] = value
|
|
@@ -45,6 +50,8 @@ class Application(BaseTool):
|
|
|
45
50
|
application: Any
|
|
46
51
|
args_schema: Type[BaseModel] = applicationToolSchema
|
|
47
52
|
return_type: str = "str"
|
|
53
|
+
client: Any
|
|
54
|
+
args_runnable: dict = {}
|
|
48
55
|
|
|
49
56
|
@field_validator('name', mode='before')
|
|
50
57
|
@classmethod
|
|
@@ -61,6 +68,11 @@ class Application(BaseTool):
|
|
|
61
68
|
return self._run(*config, **all_kwargs)
|
|
62
69
|
|
|
63
70
|
def _run(self, *args, **kwargs):
|
|
71
|
+
if self.client and self.args_runnable:
|
|
72
|
+
# Recreate new LanggraphAgentRunnable in order to reflect the current input_mapping (it can be dynamic for pipelines).
|
|
73
|
+
# Actually, for pipelines agent toolkits LanggraphAgentRunnable is created (for LLMNode) before pipeline's schema parsing.
|
|
74
|
+
application_variables = {k: {"name": k, "value": v} for k, v in kwargs.items()}
|
|
75
|
+
self.application = self.client.application(**self.args_runnable, application_variables=application_variables)
|
|
64
76
|
response = self.application.invoke(formulate_query(kwargs))
|
|
65
77
|
if self.return_type == "str":
|
|
66
78
|
return response["output"]
|