alita-sdk 0.3.351__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/bitbucket.py +94 -2
- alita_sdk/configurations/confluence.py +96 -1
- alita_sdk/configurations/gitlab.py +79 -0
- alita_sdk/configurations/jira.py +103 -0
- alita_sdk/configurations/testrail.py +88 -0
- alita_sdk/configurations/xray.py +93 -0
- alita_sdk/configurations/zephyr_enterprise.py +93 -0
- alita_sdk/configurations/zephyr_essential.py +75 -0
- alita_sdk/runtime/clients/artifact.py +1 -1
- alita_sdk/runtime/clients/client.py +214 -42
- 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 +118 -30
- 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 +103 -60
- alita_sdk/runtime/langchain/document_loaders/AlitaJSONLoader.py +4 -1
- alita_sdk/runtime/langchain/document_loaders/AlitaPowerPointLoader.py +41 -12
- alita_sdk/runtime/langchain/document_loaders/AlitaTableLoader.py +1 -1
- alita_sdk/runtime/langchain/document_loaders/constants.py +116 -99
- alita_sdk/runtime/langchain/interfaces/llm_processor.py +2 -2
- alita_sdk/runtime/langchain/langraph_agent.py +307 -71
- alita_sdk/runtime/langchain/utils.py +48 -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 +18 -6
- 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/tools.py +205 -55
- alita_sdk/runtime/toolkits/vectorstore.py +9 -4
- alita_sdk/runtime/tools/__init__.py +11 -3
- alita_sdk/runtime/tools/application.py +7 -0
- alita_sdk/runtime/tools/artifact.py +225 -12
- alita_sdk/runtime/tools/function.py +95 -5
- alita_sdk/runtime/tools/graph.py +10 -4
- alita_sdk/runtime/tools/image_generation.py +212 -0
- alita_sdk/runtime/tools/llm.py +494 -102
- 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 +4 -4
- 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 +180 -79
- alita_sdk/runtime/tools/vectorstore.py +22 -21
- alita_sdk/runtime/tools/vectorstore_base.py +125 -52
- 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 +40 -13
- alita_sdk/runtime/utils/toolkit_utils.py +28 -9
- alita_sdk/runtime/utils/utils.py +12 -0
- alita_sdk/tools/__init__.py +77 -33
- alita_sdk/tools/ado/repos/__init__.py +7 -6
- alita_sdk/tools/ado/repos/repos_wrapper.py +11 -11
- alita_sdk/tools/ado/test_plan/__init__.py +7 -7
- alita_sdk/tools/ado/wiki/__init__.py +7 -11
- alita_sdk/tools/ado/wiki/ado_wrapper.py +89 -15
- alita_sdk/tools/ado/work_item/__init__.py +7 -11
- alita_sdk/tools/ado/work_item/ado_wrapper.py +17 -8
- alita_sdk/tools/advanced_jira_mining/__init__.py +8 -7
- alita_sdk/tools/aws/delta_lake/__init__.py +11 -9
- alita_sdk/tools/azure_ai/search/__init__.py +7 -6
- alita_sdk/tools/base_indexer_toolkit.py +345 -70
- alita_sdk/tools/bitbucket/__init__.py +9 -8
- alita_sdk/tools/bitbucket/api_wrapper.py +50 -6
- alita_sdk/tools/browser/__init__.py +4 -4
- alita_sdk/tools/carrier/__init__.py +4 -6
- alita_sdk/tools/chunkers/__init__.py +3 -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 +7 -6
- alita_sdk/tools/cloud/azure/__init__.py +7 -6
- alita_sdk/tools/cloud/gcp/__init__.py +7 -6
- alita_sdk/tools/cloud/k8s/__init__.py +7 -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 +8 -7
- alita_sdk/tools/code_indexer_toolkit.py +199 -0
- alita_sdk/tools/confluence/__init__.py +9 -8
- alita_sdk/tools/confluence/api_wrapper.py +171 -75
- 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 +492 -52
- alita_sdk/tools/figma/__init__.py +7 -7
- alita_sdk/tools/figma/api_wrapper.py +2 -1
- alita_sdk/tools/github/__init__.py +9 -9
- alita_sdk/tools/github/api_wrapper.py +9 -26
- alita_sdk/tools/github/github_client.py +62 -2
- alita_sdk/tools/gitlab/__init__.py +8 -8
- alita_sdk/tools/gitlab/api_wrapper.py +135 -33
- alita_sdk/tools/gitlab_org/__init__.py +7 -8
- alita_sdk/tools/google/bigquery/__init__.py +11 -12
- alita_sdk/tools/google_places/__init__.py +8 -7
- alita_sdk/tools/jira/__init__.py +9 -7
- alita_sdk/tools/jira/api_wrapper.py +100 -52
- alita_sdk/tools/keycloak/__init__.py +8 -7
- alita_sdk/tools/localgit/local_git.py +56 -54
- alita_sdk/tools/memory/__init__.py +1 -1
- alita_sdk/tools/non_code_indexer_toolkit.py +3 -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/postman/__init__.py +7 -8
- 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 +16 -11
- alita_sdk/tools/qtest/api_wrapper.py +1784 -88
- alita_sdk/tools/rally/__init__.py +7 -8
- alita_sdk/tools/report_portal/__init__.py +9 -7
- alita_sdk/tools/salesforce/__init__.py +7 -7
- alita_sdk/tools/servicenow/__init__.py +10 -10
- alita_sdk/tools/sharepoint/__init__.py +7 -6
- alita_sdk/tools/sharepoint/api_wrapper.py +127 -36
- alita_sdk/tools/sharepoint/authorization_helper.py +191 -1
- alita_sdk/tools/sharepoint/utils.py +8 -2
- alita_sdk/tools/slack/__init__.py +7 -6
- alita_sdk/tools/sql/__init__.py +8 -7
- alita_sdk/tools/sql/api_wrapper.py +71 -23
- alita_sdk/tools/testio/__init__.py +7 -6
- alita_sdk/tools/testrail/__init__.py +8 -9
- alita_sdk/tools/utils/__init__.py +26 -4
- alita_sdk/tools/utils/content_parser.py +88 -60
- alita_sdk/tools/utils/text_operations.py +254 -0
- alita_sdk/tools/vector_adapters/VectorStoreAdapter.py +76 -26
- alita_sdk/tools/xray/__init__.py +9 -7
- alita_sdk/tools/zephyr/__init__.py +7 -6
- alita_sdk/tools/zephyr_enterprise/__init__.py +8 -6
- alita_sdk/tools/zephyr_essential/__init__.py +7 -6
- alita_sdk/tools/zephyr_essential/api_wrapper.py +12 -13
- alita_sdk/tools/zephyr_scale/__init__.py +7 -6
- alita_sdk/tools/zephyr_squad/__init__.py +7 -6
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/METADATA +147 -2
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/RECORD +206 -130
- alita_sdk-0.3.499.dist-info/entry_points.txt +2 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.351.dist-info → alita_sdk-0.3.499.dist-info}/top_level.txt +0 -0
|
@@ -2,11 +2,12 @@ import builtins
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
-
from pydantic import create_model, Field
|
|
5
|
+
from pydantic import create_model, Field, Json
|
|
6
6
|
from typing import Tuple, TypedDict, Any, Optional, Annotated
|
|
7
7
|
from langchain_core.messages import AnyMessage
|
|
8
|
-
from
|
|
9
|
-
|
|
8
|
+
from langgraph.graph import add_messages
|
|
9
|
+
|
|
10
|
+
from ...runtime.langchain.constants import ELITEA_RS, PRINTER_NODE_RS
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger(__name__)
|
|
12
13
|
|
|
@@ -130,16 +131,22 @@ def parse_type(type_str):
|
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
def create_state(data: Optional[dict] = None):
|
|
133
|
-
state_dict = {'input': str, '
|
|
134
|
+
state_dict = {'input': str, 'messages': 'list[str]', 'router_output': str,
|
|
135
|
+
ELITEA_RS: str, PRINTER_NODE_RS: str} # Always include router_output
|
|
136
|
+
types_dict = {}
|
|
134
137
|
if not data:
|
|
135
138
|
data = {'messages': 'list[str]'}
|
|
136
139
|
for key, value in data.items():
|
|
137
140
|
# support of old & new UI
|
|
138
141
|
value = value['type'] if isinstance(value, dict) else value
|
|
142
|
+
value = 'str' if value == 'string' else value # normalize string type (old state support)
|
|
139
143
|
if key == 'messages':
|
|
140
144
|
state_dict[key] = Annotated[list[AnyMessage], add_messages]
|
|
141
|
-
elif value in ['str', 'int', 'float', 'bool', 'list', 'dict', 'number']:
|
|
145
|
+
elif value in ['str', 'int', 'float', 'bool', 'list', 'dict', 'number', 'dict']:
|
|
142
146
|
state_dict[key] = parse_type(value)
|
|
147
|
+
|
|
148
|
+
state_dict["state_types"] = types_dict # Default value for state_types
|
|
149
|
+
types_dict["state_types"] = dict
|
|
143
150
|
logger.debug(f"Created state: {state_dict}")
|
|
144
151
|
return TypedDict('State', state_dict)
|
|
145
152
|
|
|
@@ -173,16 +180,49 @@ def propagate_the_input_mapping(input_mapping: dict[str, dict], input_variables:
|
|
|
173
180
|
var_dict = create_params(input_variables, source)
|
|
174
181
|
|
|
175
182
|
if value['type'] == 'fstring':
|
|
176
|
-
|
|
183
|
+
try:
|
|
184
|
+
input_data[key] = value['value'].format(**var_dict)
|
|
185
|
+
except KeyError as e:
|
|
186
|
+
logger.error(f"KeyError in fstring formatting for key '{key}'. Attempt to find proper data in state.\n{e}")
|
|
187
|
+
try:
|
|
188
|
+
# search for variables in state if not found in var_dict
|
|
189
|
+
input_data[key] = safe_format(value['value'], state)
|
|
190
|
+
except KeyError as no_var_exception:
|
|
191
|
+
logger.error(f"KeyError in fstring formatting for key '{key}' with state data.\n{no_var_exception}")
|
|
192
|
+
# leave value as is if still not found (could be a constant string marked as fstring by mistake)
|
|
193
|
+
input_data[key] = value['value']
|
|
177
194
|
elif value['type'] == 'fixed':
|
|
178
195
|
input_data[key] = value['value']
|
|
179
196
|
else:
|
|
180
197
|
input_data[key] = source.get(value['value'], "")
|
|
181
198
|
return input_data
|
|
182
199
|
|
|
200
|
+
def safe_format(template, mapping):
|
|
201
|
+
"""Format a template string using a mapping, leaving placeholders unchanged if keys are missing."""
|
|
202
|
+
|
|
203
|
+
def replacer(match):
|
|
204
|
+
key = match.group(1)
|
|
205
|
+
return str(mapping.get(key, f'{{{key}}}'))
|
|
206
|
+
return re.sub(r'\{(\w+)\}', replacer, template)
|
|
183
207
|
|
|
184
208
|
def create_pydantic_model(model_name: str, variables: dict[str, dict]):
|
|
185
209
|
fields = {}
|
|
186
210
|
for var_name, var_data in variables.items():
|
|
187
|
-
fields[var_name] = (
|
|
188
|
-
return create_model(model_name, **fields)
|
|
211
|
+
fields[var_name] = (parse_pydantic_type(var_data['type']), Field(description=var_data.get('description', None)))
|
|
212
|
+
return create_model(model_name, **fields)
|
|
213
|
+
|
|
214
|
+
def parse_pydantic_type(type_name: str):
|
|
215
|
+
"""
|
|
216
|
+
Helper function to parse type names into Python types.
|
|
217
|
+
Extend this function to handle custom types like 'dict' -> Json[Any].
|
|
218
|
+
"""
|
|
219
|
+
type_mapping = {
|
|
220
|
+
'str': str,
|
|
221
|
+
'int': int,
|
|
222
|
+
'float': float,
|
|
223
|
+
'bool': bool,
|
|
224
|
+
'dict': Json[Any], # Map 'dict' to Pydantic's Json type
|
|
225
|
+
'list': list,
|
|
226
|
+
'any': Any
|
|
227
|
+
}
|
|
228
|
+
return type_mapping.get(type_name, Any)
|
|
@@ -105,8 +105,7 @@ class PreloadedChatModel(BaseChatModel): # pylint: disable=R0903
|
|
|
105
105
|
model_name: str = ""
|
|
106
106
|
max_tokens: Optional[int] = 256
|
|
107
107
|
temperature: Optional[float] = 0.9
|
|
108
|
-
|
|
109
|
-
top_k: Optional[int] = 20
|
|
108
|
+
reasoning_effort: Optional[str] = None
|
|
110
109
|
token_limit: Optional[int] = 1024
|
|
111
110
|
|
|
112
111
|
_local_streams: Any = PrivateAttr()
|
|
@@ -252,8 +251,7 @@ class PreloadedChatModel(BaseChatModel): # pylint: disable=R0903
|
|
|
252
251
|
"return_full_text": False,
|
|
253
252
|
"temperature": self.temperature,
|
|
254
253
|
"do_sample": True,
|
|
255
|
-
"
|
|
256
|
-
"top_p": self.top_p,
|
|
254
|
+
"reasoning_effort": self.reasoning_effort
|
|
257
255
|
}
|
|
258
256
|
#
|
|
259
257
|
try:
|
|
@@ -302,8 +300,6 @@ class PreloadedChatModel(BaseChatModel): # pylint: disable=R0903
|
|
|
302
300
|
"return_full_text": False,
|
|
303
301
|
"temperature": self.temperature,
|
|
304
302
|
"do_sample": True,
|
|
305
|
-
"top_k": self.top_k,
|
|
306
|
-
"top_p": self.top_p,
|
|
307
303
|
}
|
|
308
304
|
#
|
|
309
305
|
while True:
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Models for MCP (Model Context Protocol) configuration.
|
|
3
|
+
Following MCP specification for remote HTTP servers only.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Optional, List, Dict, Any
|
|
7
|
+
from pydantic import BaseModel, Field, validator
|
|
8
|
+
from urllib.parse import urlparse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class McpConnectionConfig(BaseModel):
|
|
12
|
+
"""
|
|
13
|
+
MCP connection configuration for remote HTTP servers.
|
|
14
|
+
Based on https://modelcontextprotocol.io/specification/2025-06-18
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
url: str = Field(description="MCP server HTTP URL (http:// or https://)")
|
|
18
|
+
headers: Optional[Dict[str, str]] = Field(
|
|
19
|
+
default=None,
|
|
20
|
+
description="HTTP headers for the connection (JSON object)"
|
|
21
|
+
)
|
|
22
|
+
session_id: Optional[str] = Field(
|
|
23
|
+
default=None,
|
|
24
|
+
description="MCP session ID for stateful SSE servers (managed by client)"
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
@validator('url')
|
|
28
|
+
def validate_url(cls, v):
|
|
29
|
+
"""Validate URL is HTTP/HTTPS."""
|
|
30
|
+
if not v:
|
|
31
|
+
raise ValueError("URL cannot be empty")
|
|
32
|
+
|
|
33
|
+
parsed = urlparse(v)
|
|
34
|
+
if parsed.scheme not in ['http', 'https']:
|
|
35
|
+
raise ValueError("URL must use http:// or https:// scheme for remote MCP servers")
|
|
36
|
+
|
|
37
|
+
if not parsed.netloc:
|
|
38
|
+
raise ValueError("URL must include host and port")
|
|
39
|
+
|
|
40
|
+
return v
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class McpToolkitConfig(BaseModel):
|
|
44
|
+
"""Configuration for a single remote MCP server toolkit."""
|
|
45
|
+
|
|
46
|
+
server_name: str = Field(description="MCP server name/identifier")
|
|
47
|
+
connection: McpConnectionConfig = Field(description="MCP connection configuration")
|
|
48
|
+
timeout: int = Field(default=60, description="Request timeout in seconds", ge=1, le=3600)
|
|
49
|
+
selected_tools: List[str] = Field(default_factory=list, description="Specific tools to enable (empty = all)")
|
|
50
|
+
enable_caching: bool = Field(default=True, description="Enable tool schema caching")
|
|
51
|
+
cache_ttl: int = Field(default=300, description="Cache TTL in seconds", ge=60, le=3600)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class McpToolMetadata(BaseModel):
|
|
55
|
+
"""Metadata about an MCP tool."""
|
|
56
|
+
|
|
57
|
+
name: str = Field(description="Tool name")
|
|
58
|
+
description: str = Field(description="Tool description")
|
|
59
|
+
server: str = Field(description="Source server name")
|
|
60
|
+
input_schema: Dict[str, Any] = Field(description="Tool input schema")
|
|
61
|
+
enabled: bool = Field(default=True, description="Whether tool is enabled")
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Runtime toolkits module for Alita SDK.
|
|
3
|
+
This module provides various toolkit implementations for LangGraph agents.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .application import ApplicationToolkit
|
|
7
|
+
from .artifact import ArtifactToolkit
|
|
8
|
+
from .datasource import DatasourcesToolkit
|
|
9
|
+
from .planning import PlanningToolkit
|
|
10
|
+
from .prompt import PromptToolkit
|
|
11
|
+
from .subgraph import SubgraphToolkit
|
|
12
|
+
from .vectorstore import VectorStoreToolkit
|
|
13
|
+
from .mcp import McpToolkit
|
|
14
|
+
from ...tools.memory import MemoryToolkit
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"ApplicationToolkit",
|
|
18
|
+
"ArtifactToolkit",
|
|
19
|
+
"DatasourcesToolkit",
|
|
20
|
+
"PlanningToolkit",
|
|
21
|
+
"PromptToolkit",
|
|
22
|
+
"SubgraphToolkit",
|
|
23
|
+
"VectorStoreToolkit",
|
|
24
|
+
"McpToolkit",
|
|
25
|
+
"MemoryToolkit"
|
|
26
|
+
]
|
|
@@ -28,7 +28,7 @@ class ApplicationToolkit(BaseToolkit):
|
|
|
28
28
|
version_details = client.get_app_version_details(application_id, application_version_id)
|
|
29
29
|
model_settings = {
|
|
30
30
|
"max_tokens": version_details['llm_settings']['max_tokens'],
|
|
31
|
-
"
|
|
31
|
+
"reasoning_effort": version_details['llm_settings'].get('reasoning_effort'),
|
|
32
32
|
"temperature": version_details['llm_settings']['temperature'],
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -39,7 +39,14 @@ class ApplicationToolkit(BaseToolkit):
|
|
|
39
39
|
description=app_details.get("description"),
|
|
40
40
|
application=app,
|
|
41
41
|
args_schema=applicationToolSchema,
|
|
42
|
-
return_type='str'
|
|
42
|
+
return_type='str',
|
|
43
|
+
client=client,
|
|
44
|
+
args_runnable={
|
|
45
|
+
"application_id": application_id,
|
|
46
|
+
"application_version_id": application_version_id,
|
|
47
|
+
"store": store,
|
|
48
|
+
"llm": client.get_llm(version_details['llm_settings']['model_name'], model_settings),
|
|
49
|
+
})])
|
|
43
50
|
|
|
44
51
|
def get_tools(self):
|
|
45
52
|
return self.tools
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from typing import List, Any, Literal, Optional
|
|
2
2
|
|
|
3
|
-
from alita_sdk.tools.utils import clean_string,
|
|
3
|
+
from alita_sdk.tools.utils import clean_string, get_max_toolkit_length
|
|
4
4
|
from langchain_community.agent_toolkits.base import BaseToolkit
|
|
5
5
|
from langchain_core.tools import BaseTool
|
|
6
6
|
from pydantic import create_model, BaseModel, ConfigDict, Field
|
|
@@ -21,7 +21,10 @@ class ArtifactToolkit(BaseToolkit):
|
|
|
21
21
|
return create_model(
|
|
22
22
|
"artifact",
|
|
23
23
|
# client = (Any, FieldInfo(description="Client object", required=True, autopopulate=True)),
|
|
24
|
-
bucket
|
|
24
|
+
bucket=(str, FieldInfo(
|
|
25
|
+
description="Bucket name",
|
|
26
|
+
pattern=r'^[a-z][a-z0-9-]*$'
|
|
27
|
+
)),
|
|
25
28
|
selected_tools=(List[Literal[tuple(selected_tools)]], Field(default=[], json_schema_extra={'args_schemas': selected_tools})),
|
|
26
29
|
# indexer settings
|
|
27
30
|
pgvector_configuration=(Optional[PgVectorConfiguration], Field(default=None, description="PgVector Configuration", json_schema_extra={'configuration_types': ['pgvector']})),
|
|
@@ -30,29 +33,38 @@ class ArtifactToolkit(BaseToolkit):
|
|
|
30
33
|
embedding_model=(Optional[str], Field(default=None, description="Embedding configuration.",
|
|
31
34
|
json_schema_extra={'configuration_model': 'embedding'})),
|
|
32
35
|
|
|
33
|
-
__config__=ConfigDict(json_schema_extra={'metadata': {"label": "Artifact",
|
|
36
|
+
__config__=ConfigDict(json_schema_extra={'metadata': {"label": "Artifact",
|
|
37
|
+
"icon_url": None,
|
|
38
|
+
"max_length": ArtifactToolkit.toolkit_max_length
|
|
39
|
+
}})
|
|
34
40
|
)
|
|
35
41
|
|
|
36
42
|
@classmethod
|
|
37
43
|
def get_toolkit(cls, client: Any, bucket: str, toolkit_name: Optional[str] = None, selected_tools: list[str] = [], **kwargs):
|
|
38
44
|
if selected_tools is None:
|
|
39
45
|
selected_tools = []
|
|
46
|
+
|
|
40
47
|
tools = []
|
|
41
48
|
wrapper_payload = {
|
|
42
49
|
**kwargs,
|
|
43
50
|
**(kwargs.get('pgvector_configuration') or {}),
|
|
44
51
|
}
|
|
45
52
|
artifact_wrapper = ArtifactWrapper(alita=client, bucket=bucket, **wrapper_payload)
|
|
46
|
-
|
|
53
|
+
# Use clean toolkit name for context (max 1000 chars in description)
|
|
54
|
+
toolkit_context = f" [Toolkit: {clean_string(toolkit_name, 0)}]" if toolkit_name else ''
|
|
47
55
|
available_tools = artifact_wrapper.get_available_tools()
|
|
48
56
|
for tool in available_tools:
|
|
49
57
|
if selected_tools:
|
|
50
58
|
if tool["name"] not in selected_tools:
|
|
51
59
|
continue
|
|
60
|
+
# Add toolkit context to description with character limit
|
|
61
|
+
description = tool["description"]
|
|
62
|
+
if toolkit_context and len(description + toolkit_context) <= 1000:
|
|
63
|
+
description = description + toolkit_context
|
|
52
64
|
tools.append(BaseAction(
|
|
53
65
|
api_wrapper=artifact_wrapper,
|
|
54
|
-
name=
|
|
55
|
-
description=
|
|
66
|
+
name=tool["name"],
|
|
67
|
+
description=description,
|
|
56
68
|
args_schema=tool["args_schema"]
|
|
57
69
|
))
|
|
58
70
|
return cls(tools=tools)
|
|
@@ -3,7 +3,7 @@ from pydantic import create_model, BaseModel, Field
|
|
|
3
3
|
from langchain_community.agent_toolkits.base import BaseToolkit
|
|
4
4
|
from langchain_core.tools import BaseTool, ToolException
|
|
5
5
|
from ..tools.datasource import DatasourcePredict, DatasourceSearch, datasourceToolSchema
|
|
6
|
-
from alita_sdk.tools.utils import clean_string
|
|
6
|
+
from alita_sdk.tools.utils import clean_string
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class DatasourcesToolkit(BaseToolkit):
|
|
@@ -21,21 +21,28 @@ class DatasourcesToolkit(BaseToolkit):
|
|
|
21
21
|
@classmethod
|
|
22
22
|
def get_toolkit(cls, client: Any, datasource_ids: list[int], toolkit_name: Optional[str] = None, selected_tools: list[str] = []):
|
|
23
23
|
tools = []
|
|
24
|
-
|
|
24
|
+
# Use clean toolkit name for context (max 1000 chars in description)
|
|
25
|
+
toolkit_context = f" [Toolkit: {clean_string(toolkit_name)}]" if toolkit_name else ''
|
|
25
26
|
for datasource_id in datasource_ids:
|
|
26
27
|
datasource = client.datasource(datasource_id)
|
|
27
28
|
ds_name = clean_string(datasource.name)
|
|
28
29
|
if len(ds_name) == 0:
|
|
29
30
|
raise ToolException(f'Datasource with id {datasource_id} has incorrect name (i.e. special characters, etc.)')
|
|
30
31
|
if len(selected_tools) == 0 or 'chat' in selected_tools:
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
description = f'Search and summarize. {datasource.description}'
|
|
33
|
+
if toolkit_context and len(description + toolkit_context) <= 1000:
|
|
34
|
+
description = description + toolkit_context
|
|
35
|
+
tools.append(DatasourcePredict(name=f'chat',
|
|
36
|
+
description=description,
|
|
33
37
|
datasource=datasource,
|
|
34
38
|
args_schema=datasourceToolSchema,
|
|
35
39
|
return_type='str'))
|
|
36
40
|
if len(selected_tools) == 0 or 'search' in selected_tools:
|
|
37
|
-
|
|
38
|
-
|
|
41
|
+
description = f'Search return results. {datasource.description}'
|
|
42
|
+
if toolkit_context and len(description + toolkit_context) <= 1000:
|
|
43
|
+
description = description + toolkit_context
|
|
44
|
+
tools.append(DatasourceSearch(name=f'search',
|
|
45
|
+
description=description,
|
|
39
46
|
datasource=datasource,
|
|
40
47
|
args_schema=datasourceToolSchema,
|
|
41
48
|
return_type='str'))
|