alita-sdk 0.3.140b1__py3-none-any.whl → 0.3.140b3__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.
@@ -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
 
@@ -20,51 +20,72 @@ class McpServerTool(BaseTool):
20
20
 
21
21
  @staticmethod
22
22
  def create_pydantic_model_from_schema(schema: dict):
23
- fields = {}
24
- for field_name, field_info in schema['properties'].items():
25
- field_type = None
26
-
27
- if 'type' in field_info:
28
- field_type = field_info['type']
29
- elif 'allOf' in field_info or 'anyOf' in field_info:# ADO-MCP wit_update_work_item, testplan_add_test_cases_to_suite
30
- field_type = 'array'
31
-
32
- field_description = field_info.get('description', '')
33
- if field_type == 'string':
34
- if 'enum' in field_info:
35
- field_type = Literal[tuple(field_info['enum'])]
36
- else:
37
- field_type = str
38
- elif field_type == 'integer':
39
- field_type = int
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
- None
56
- )
57
- if item_type is None:
58
- raise ValueError(f"Unsupported array item type: {item_schema['type']}")
59
- field_type = list[item_type]
60
- else:
61
- raise ValueError(f"Unsupported field type: {field_type}")
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)
71
+ if t == "array":
72
+ items = field.get("items", {})
73
+ return List[parse_type(items, name + "Item")]
74
+ return Any
62
75
 
63
- if field_name in schema.get('required', []):
64
- fields[field_name] = (field_type, Field(..., description=field_description))
65
- else:
66
- fields[field_name] = (Optional[field_type], Field(None, description=field_description))
67
- return create_model('DynamicModel', **fields)
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("DynamicModel", **fields)
68
89
 
69
90
  def _run(self, *args, **kwargs):
70
91
  call_data = {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alita_sdk
3
- Version: 0.3.140b1
3
+ Version: 0.3.140b3
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=8RcYSV_6FAEwFSh4KNpdb8rO9oFQ-RR6ufXiZOTgsHA,3476
91
+ alita_sdk/tools/mcp_server_tool.py,sha256=SWuCGz6ZEYbB0jWElhHIWEGUzNekz3gViKQ99SurZrk,4109
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.140b1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
104
+ alita_sdk-0.3.140b3.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.140b1.dist-info/METADATA,sha256=mAGZFKCyqDPJoYal-kfCJV96nP9UYigBBybAWK8hxVI,7078
111
- alita_sdk-0.3.140b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
112
- alita_sdk-0.3.140b1.dist-info/top_level.txt,sha256=SWRhxB7Et3cOy3RkE5hR7OIRnHoo3K8EXzoiNlkfOmc,25
113
- alita_sdk-0.3.140b1.dist-info/RECORD,,
110
+ alita_sdk-0.3.140b3.dist-info/METADATA,sha256=9OBtknQ__fZR7o8DPh0QKuvcd2eMHY7R-TF5no3SZks,7078
111
+ alita_sdk-0.3.140b3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
112
+ alita_sdk-0.3.140b3.dist-info/top_level.txt,sha256=SWRhxB7Et3cOy3RkE5hR7OIRnHoo3K8EXzoiNlkfOmc,25
113
+ alita_sdk-0.3.140b3.dist-info/RECORD,,