alita-sdk 0.3.140b2__py3-none-any.whl → 0.3.140b4__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/tools/mcp_server_tool.py +76 -47
- {alita_sdk-0.3.140b2.dist-info → alita_sdk-0.3.140b4.dist-info}/METADATA +1 -1
- {alita_sdk-0.3.140b2.dist-info → alita_sdk-0.3.140b4.dist-info}/RECORD +6 -6
- {alita_sdk-0.3.140b2.dist-info → alita_sdk-0.3.140b4.dist-info}/WHEEL +0 -0
- {alita_sdk-0.3.140b2.dist-info → alita_sdk-0.3.140b4.dist-info}/licenses/LICENSE +0 -0
- {alita_sdk-0.3.140b2.dist-info → alita_sdk-0.3.140b4.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,9 @@
|
|
1
1
|
import uuid
|
2
2
|
from logging import getLogger
|
3
|
-
from typing import Any, Type, Literal, Optional
|
3
|
+
from typing import Any, Type, Literal, Optional, Union, List
|
4
4
|
|
5
5
|
from langchain_core.tools import BaseTool
|
6
|
-
from pydantic import BaseModel, Field, create_model
|
6
|
+
from pydantic import BaseModel, Field, create_model, EmailStr, constr
|
7
7
|
|
8
8
|
logger = getLogger(__name__)
|
9
9
|
|
@@ -19,53 +19,82 @@ class McpServerTool(BaseTool):
|
|
19
19
|
|
20
20
|
|
21
21
|
@staticmethod
|
22
|
-
def create_pydantic_model_from_schema(schema: dict):
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
def create_pydantic_model_from_schema(schema: dict, model_name: str = "ArgsSchema"):
|
23
|
+
def parse_type(field: dict, name: str = "Field") -> Any:
|
24
|
+
if "allOf" in field:
|
25
|
+
merged = {}
|
26
|
+
required = set()
|
27
|
+
for idx, subschema in enumerate(field["allOf"]):
|
28
|
+
sub_type = parse_type(subschema, f"{name}AllOf{idx}")
|
29
|
+
if hasattr(sub_type, "__fields__"):
|
30
|
+
merged.update({k: (v.outer_type_, v.default) for k, v in sub_type.__fields__.items()})
|
31
|
+
required.update({k for k, v in sub_type.__fields__.items() if v.required})
|
32
|
+
if merged:
|
33
|
+
return create_model(f"{name}AllOf", **merged)
|
34
|
+
return Any
|
35
|
+
if "anyOf" in field or "oneOf" in field:
|
36
|
+
key = "anyOf" if "anyOf" in field else "oneOf"
|
37
|
+
types = [parse_type(sub, f"{name}{key.capitalize()}{i}") for i, sub in enumerate(field[key])]
|
38
|
+
# Check for null type
|
39
|
+
if any(sub.get("type") == "null" for sub in field[key]):
|
40
|
+
non_null_types = [parse_type(sub, f"{name}{key.capitalize()}{i}")
|
41
|
+
for i, sub in enumerate(field[key]) if sub.get("type") != "null"]
|
42
|
+
if len(non_null_types) == 1:
|
43
|
+
return Optional[non_null_types[0]]
|
44
|
+
return Union[tuple(types)]
|
45
|
+
t = field.get("type")
|
46
|
+
if isinstance(t, list):
|
47
|
+
if "null" in t:
|
48
|
+
non_null = [x for x in t if x != "null"]
|
49
|
+
if len(non_null) == 1:
|
50
|
+
field = dict(field)
|
51
|
+
field["type"] = non_null[0]
|
52
|
+
return Optional[parse_type(field, name)]
|
53
|
+
return Any
|
54
|
+
return Any
|
55
|
+
if t == "string":
|
56
|
+
if "enum" in field:
|
57
|
+
return Literal[tuple(field["enum"])]
|
58
|
+
if field.get("format") == "email":
|
59
|
+
return EmailStr
|
60
|
+
if "pattern" in field:
|
61
|
+
return constr(regex=field["pattern"])
|
62
|
+
return str
|
63
|
+
if t == "integer":
|
64
|
+
return int
|
65
|
+
if t == "number":
|
66
|
+
return float
|
67
|
+
if t == "boolean":
|
68
|
+
return bool
|
69
|
+
if t == "object":
|
70
|
+
return McpServerTool.create_pydantic_model_from_schema(field, name.capitalize())
|
71
|
+
if t == "array":
|
72
|
+
items = field.get("items", {})
|
73
|
+
return List[parse_type(items, name + "Item")]
|
74
|
+
return Any
|
26
75
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
elif field_type == 'number':
|
41
|
-
field_type = float
|
42
|
-
elif field_type == 'boolean':
|
43
|
-
field_type = bool
|
44
|
-
elif field_type == 'object':#Dict[str, Any] - for tool start_browser in selenium mcp
|
45
|
-
nested_model = McpServerTool.create_pydantic_model_from_schema(field_info) if 'properties' in field_info else dict# for tool build_run_build in ADO-MCP
|
46
|
-
field_type = nested_model
|
47
|
-
elif field_type == 'array':
|
48
|
-
item_schema = field_info['items'] if 'items' in field_info else (field_info.get('allOf', field_info.get('anyOf', [{'type': None}]))[-1])# ADO-MCP wit_update_work_item, testplan_add_test_cases_to_suite
|
49
|
-
item_type = McpServerTool.create_pydantic_model_from_schema(item_schema) if item_schema['type'] == 'object' else (
|
50
|
-
str if item_schema['type'] == 'string' else # support enum
|
51
|
-
int if item_schema['type'] == 'integer' else
|
52
|
-
float if item_schema['type'] == 'number' else
|
53
|
-
bool if item_schema['type'] == 'boolean' else
|
54
|
-
list if item_schema['type'] == 'array' else# ADO-MCP testplan_add_test_cases_to_suite
|
55
|
-
str if item_schema['type'] == 'null' else#for mcp-atlassian
|
56
|
-
None
|
57
|
-
)
|
58
|
-
if item_type is None:
|
59
|
-
raise ValueError(f"Unsupported array item type: {item_schema['type']}")
|
60
|
-
field_type = list[item_type]
|
61
|
-
else:
|
62
|
-
raise ValueError(f"Unsupported field type: {field_type}")
|
76
|
+
properties = schema.get("properties", {})
|
77
|
+
required = set(schema.get("required", []))
|
78
|
+
fields = {}
|
79
|
+
for name, prop in properties.items():
|
80
|
+
typ = parse_type(prop, name.capitalize())
|
81
|
+
default = prop.get("default", ... if name in required else None)
|
82
|
+
field_args = {}
|
83
|
+
if "description" in prop:
|
84
|
+
field_args["description"] = prop["description"]
|
85
|
+
if "format" in prop:
|
86
|
+
field_args["format"] = prop["format"]
|
87
|
+
fields[name] = (typ, Field(default, **field_args))
|
88
|
+
return create_model(model_name, **fields)
|
63
89
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
90
|
+
def _to_args_and_kwargs(
|
91
|
+
self, tool_input: Union[str, dict], tool_call_id: Optional[str]
|
92
|
+
) -> tuple[tuple, dict]:
|
93
|
+
# just return input as is without any transformation to/from pydentic model
|
94
|
+
if isinstance(tool_input, str):
|
95
|
+
return (tool_input,), {}
|
96
|
+
else:
|
97
|
+
return (), tool_input
|
69
98
|
|
70
99
|
def _run(self, *args, **kwargs):
|
71
100
|
call_data = {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: alita_sdk
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.140b4
|
4
4
|
Summary: SDK for building langchain agents using resources from Alita
|
5
5
|
Author-email: Artem Rozumenko <artyom.rozumenko@gmail.com>, Mikalai Biazruchka <mikalai_biazruchka@epam.com>, Roman Mitusov <roman_mitusov@epam.com>, Ivan Krakhmaliuk <lifedjik@gmail.com>
|
6
6
|
Project-URL: Homepage, https://projectalita.ai
|
@@ -88,7 +88,7 @@ alita_sdk/tools/indexer_tool.py,sha256=P9S_omk5TZkizb6UXyxMO87Pzj4UCaye0CuXBgCnh
|
|
88
88
|
alita_sdk/tools/llm.py,sha256=UUd4U4CuCNImHxVJAF5daYbew-7X9H8k21bUWy2PDvg,3502
|
89
89
|
alita_sdk/tools/loop.py,sha256=uds0WhZvwMxDVFI6MZHrcmMle637cQfBNg682iLxoJA,8335
|
90
90
|
alita_sdk/tools/loop_output.py,sha256=U4hO9PCQgWlXwOq6jdmCGbegtAxGAPXObSxZQ3z38uk,8069
|
91
|
-
alita_sdk/tools/mcp_server_tool.py,sha256=
|
91
|
+
alita_sdk/tools/mcp_server_tool.py,sha256=WIDh8i6pJX-ZbC3uHGSHS5gD9FUPFgvrY1epNzqntV0,4496
|
92
92
|
alita_sdk/tools/pgvector_search.py,sha256=NN2BGAnq4SsDHIhUcFZ8d_dbEOM8QwB0UwpsWCYruXU,11692
|
93
93
|
alita_sdk/tools/prompt.py,sha256=nJafb_e5aOM1Rr3qGFCR-SKziU9uCsiP2okIMs9PppM,741
|
94
94
|
alita_sdk/tools/router.py,sha256=wCvZjVkdXK9dMMeEerrgKf5M790RudH68pDortnHSz0,1517
|
@@ -101,13 +101,13 @@ alita_sdk/utils/logging.py,sha256=hBE3qAzmcLMdamMp2YRXwOOK9P4lmNaNhM76kntVljs,31
|
|
101
101
|
alita_sdk/utils/save_dataframe.py,sha256=tNwnaVCvN4_B0oi3F4Y3Z13elbIRtwKmdKHsMcj658g,1465
|
102
102
|
alita_sdk/utils/streamlit.py,sha256=zp8owZwHI3HZplhcExJf6R3-APtWx-z6s5jznT2hY_k,29124
|
103
103
|
alita_sdk/utils/utils.py,sha256=dM8whOJAuFJFe19qJ69-FLzrUp6d2G-G6L7d4ss2XqM,346
|
104
|
-
alita_sdk-0.3.
|
104
|
+
alita_sdk-0.3.140b4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
105
105
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
106
106
|
tests/test_ado_analysis.py,sha256=wsxB4B2Ycxoiykthh6YbPQ9hqsDbPFie8D9ZK1i_6kg,3311
|
107
107
|
tests/test_github_analysis.py,sha256=ulR4CEGmiMRPydJuX7aQcglzvhC7kFOAtZRLLBB9F_M,3148
|
108
108
|
tests/test_gitlab_analysis.py,sha256=J7Y2mNi5Sj8-rH2PMRmVbT3uwZ17YeR9pcs0MDIyNW4,3352
|
109
109
|
tests/test_jira_analysis.py,sha256=6F3Elikt02L28N6sS_AKDy9lgqgD81_hr979NcdZeg4,3359
|
110
|
-
alita_sdk-0.3.
|
111
|
-
alita_sdk-0.3.
|
112
|
-
alita_sdk-0.3.
|
113
|
-
alita_sdk-0.3.
|
110
|
+
alita_sdk-0.3.140b4.dist-info/METADATA,sha256=kPo52ujJYFCH8RFmRn2d8PW3fBsSfewCbqOwjFBhsqI,7078
|
111
|
+
alita_sdk-0.3.140b4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
112
|
+
alita_sdk-0.3.140b4.dist-info/top_level.txt,sha256=SWRhxB7Et3cOy3RkE5hR7OIRnHoo3K8EXzoiNlkfOmc,25
|
113
|
+
alita_sdk-0.3.140b4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|