universal-mcp-agents 0.1.3__py3-none-any.whl → 0.1.5__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.
- universal_mcp/agents/__init__.py +19 -0
- universal_mcp/agents/autoagent/__init__.py +1 -1
- universal_mcp/agents/autoagent/__main__.py +1 -1
- universal_mcp/agents/autoagent/graph.py +32 -13
- universal_mcp/agents/autoagent/studio.py +3 -8
- universal_mcp/agents/base.py +80 -22
- universal_mcp/agents/bigtool/__init__.py +13 -9
- universal_mcp/agents/bigtool/__main__.py +6 -7
- universal_mcp/agents/bigtool/graph.py +84 -40
- universal_mcp/agents/bigtool/prompts.py +3 -3
- universal_mcp/agents/bigtool2/__init__.py +16 -6
- universal_mcp/agents/bigtool2/__main__.py +7 -6
- universal_mcp/agents/bigtool2/agent.py +4 -2
- universal_mcp/agents/bigtool2/graph.py +78 -36
- universal_mcp/agents/bigtool2/prompts.py +1 -1
- universal_mcp/agents/bigtoolcache/__init__.py +8 -4
- universal_mcp/agents/bigtoolcache/__main__.py +1 -1
- universal_mcp/agents/bigtoolcache/agent.py +5 -3
- universal_mcp/agents/bigtoolcache/context.py +0 -1
- universal_mcp/agents/bigtoolcache/graph.py +99 -69
- universal_mcp/agents/bigtoolcache/prompts.py +28 -0
- universal_mcp/agents/bigtoolcache/tools_all.txt +956 -0
- universal_mcp/agents/bigtoolcache/tools_important.txt +474 -0
- universal_mcp/agents/builder.py +62 -20
- universal_mcp/agents/cli.py +19 -5
- universal_mcp/agents/codeact/__init__.py +16 -4
- universal_mcp/agents/codeact/test.py +2 -1
- universal_mcp/agents/hil.py +16 -4
- universal_mcp/agents/llm.py +12 -4
- universal_mcp/agents/planner/__init__.py +14 -4
- universal_mcp/agents/planner/__main__.py +10 -6
- universal_mcp/agents/planner/graph.py +9 -3
- universal_mcp/agents/planner/prompts.py +14 -1
- universal_mcp/agents/planner/state.py +0 -1
- universal_mcp/agents/react.py +36 -22
- universal_mcp/agents/shared/tool_node.py +26 -11
- universal_mcp/agents/simple.py +27 -4
- universal_mcp/agents/tools.py +9 -4
- universal_mcp/agents/ui_tools.py +305 -0
- universal_mcp/agents/utils.py +55 -17
- {universal_mcp_agents-0.1.3.dist-info → universal_mcp_agents-0.1.5.dist-info}/METADATA +3 -2
- universal_mcp_agents-0.1.5.dist-info/RECORD +52 -0
- universal_mcp/agents/bigtool/context.py +0 -24
- universal_mcp/agents/bigtool2/context.py +0 -33
- universal_mcp_agents-0.1.3.dist-info/RECORD +0 -51
- {universal_mcp_agents-0.1.3.dist-info → universal_mcp_agents-0.1.5.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Literal, TypedDict
|
|
3
|
+
|
|
4
|
+
import httpx
|
|
5
|
+
from loguru import logger
|
|
6
|
+
from markitdown import MarkItDown
|
|
7
|
+
from universal_mcp.applications.application import BaseApplication
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class SeriesItem(TypedDict):
|
|
11
|
+
seriesName: str
|
|
12
|
+
value: float
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ChartDataItem(TypedDict):
|
|
16
|
+
xAxisLabel: str
|
|
17
|
+
series: list[SeriesItem]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class PieChartDataItem(TypedDict):
|
|
21
|
+
label: str
|
|
22
|
+
value: float
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ColumnDefinition(TypedDict):
|
|
26
|
+
key: str
|
|
27
|
+
label: str
|
|
28
|
+
type: Literal["string", "number", "date", "boolean"] | None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class UIToolsApp(BaseApplication):
|
|
32
|
+
"""An application for creating UI tools"""
|
|
33
|
+
|
|
34
|
+
def __init__(self):
|
|
35
|
+
"""Initialize the DefaultToolsApp"""
|
|
36
|
+
super().__init__(name="ui_tools")
|
|
37
|
+
self.markitdown = MarkItDown(enable_plugins=True)
|
|
38
|
+
|
|
39
|
+
def create_bar_chart(
|
|
40
|
+
self,
|
|
41
|
+
title: str,
|
|
42
|
+
data: list[ChartDataItem],
|
|
43
|
+
description: str | None = None,
|
|
44
|
+
y_axis_label: str | None = None,
|
|
45
|
+
):
|
|
46
|
+
"""Create a bar chart with multiple data series.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
title (str): The title of the chart.
|
|
50
|
+
data (List[ChartDataItem]): Chart data with x-axis labels and series values.
|
|
51
|
+
description (Optional[str]): Optional description for the chart.
|
|
52
|
+
y_axis_label (Optional[str]): Optional label for the Y-axis.
|
|
53
|
+
|
|
54
|
+
Tags:
|
|
55
|
+
important
|
|
56
|
+
"""
|
|
57
|
+
return "Success"
|
|
58
|
+
|
|
59
|
+
def create_line_chart(
|
|
60
|
+
self,
|
|
61
|
+
title: str,
|
|
62
|
+
data: list[ChartDataItem],
|
|
63
|
+
description: str | None = None,
|
|
64
|
+
y_axis_label: str | None = None,
|
|
65
|
+
):
|
|
66
|
+
"""Create a line chart with multiple data series.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
title (str): The title of the chart.
|
|
70
|
+
data (List[ChartDataItem]): Chart data with x-axis labels and series values.
|
|
71
|
+
description (Optional[str]): Optional description for the chart.
|
|
72
|
+
y_axis_label (Optional[str]): Optional label for the Y-axis.
|
|
73
|
+
|
|
74
|
+
Tags:
|
|
75
|
+
important
|
|
76
|
+
"""
|
|
77
|
+
return "Success"
|
|
78
|
+
|
|
79
|
+
def create_pie_chart(
|
|
80
|
+
self,
|
|
81
|
+
title: str,
|
|
82
|
+
data: list[PieChartDataItem],
|
|
83
|
+
description: str | None = None,
|
|
84
|
+
unit: str | None = None,
|
|
85
|
+
):
|
|
86
|
+
"""Create a pie chart.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
title (str): The title of the chart.
|
|
90
|
+
data (List[PieChartDataItem]): Data for the pie chart with labels and values.
|
|
91
|
+
description (Optional[str]): Optional description for the chart.
|
|
92
|
+
unit (Optional[str]): Optional unit for the values.
|
|
93
|
+
|
|
94
|
+
Tags:
|
|
95
|
+
important
|
|
96
|
+
"""
|
|
97
|
+
return "Success"
|
|
98
|
+
|
|
99
|
+
def create_table(
|
|
100
|
+
self,
|
|
101
|
+
title: str,
|
|
102
|
+
columns: list[ColumnDefinition],
|
|
103
|
+
data: list[dict],
|
|
104
|
+
description: str | None = None,
|
|
105
|
+
):
|
|
106
|
+
"""Create an interactive table with data.
|
|
107
|
+
|
|
108
|
+
The table will automatically have sorting, filtering, and search functionality.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
title (str): The title of the table.
|
|
112
|
+
columns (List[ColumnDefinition]): Column configuration array.
|
|
113
|
+
data (List[dict]): Array of row objects. Each object should have keys matching the column keys.
|
|
114
|
+
description (Optional[str]): Optional description for the table.
|
|
115
|
+
|
|
116
|
+
Tags:
|
|
117
|
+
important
|
|
118
|
+
"""
|
|
119
|
+
return "Success"
|
|
120
|
+
|
|
121
|
+
def _handle_response(self, response: httpx.Response):
|
|
122
|
+
"""
|
|
123
|
+
Handle the HTTP response, returning JSON if possible, otherwise text.
|
|
124
|
+
"""
|
|
125
|
+
try:
|
|
126
|
+
return response.json()
|
|
127
|
+
except Exception:
|
|
128
|
+
logger.warning(
|
|
129
|
+
f"Response is not JSON, returning text. Content-Type: {response.headers.get('content-type')}"
|
|
130
|
+
)
|
|
131
|
+
return {
|
|
132
|
+
"text": response.text,
|
|
133
|
+
"status_code": response.status_code,
|
|
134
|
+
"headers": dict(response.headers),
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
def http_get(
|
|
138
|
+
self, url: str, headers: dict | None = None, query_params: dict | None = None
|
|
139
|
+
):
|
|
140
|
+
"""
|
|
141
|
+
Perform a GET request to the specified URL with optional parameters.
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
url (str): The URL to send the GET request to. Example: "https://api.example.com/data"
|
|
145
|
+
headers (dict, optional): Optional HTTP headers to include in the request. Example: {"Authorization": "Bearer token"}
|
|
146
|
+
query_params (dict, optional): Optional dictionary of query parameters to include in the request. Example: {"page": 1}
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
dict: The JSON response from the GET request, or text if not JSON.
|
|
150
|
+
Tags:
|
|
151
|
+
get, important
|
|
152
|
+
"""
|
|
153
|
+
logger.debug(
|
|
154
|
+
f"GET request to {url} with headers {headers} and query params {query_params}"
|
|
155
|
+
)
|
|
156
|
+
response = httpx.get(url, params=query_params, headers=headers)
|
|
157
|
+
response.raise_for_status()
|
|
158
|
+
return self._handle_response(response)
|
|
159
|
+
|
|
160
|
+
def http_post(
|
|
161
|
+
self, url: str, headers: dict | None = None, body: dict | None = None
|
|
162
|
+
):
|
|
163
|
+
"""
|
|
164
|
+
Perform a POST request to the specified URL with optional parameters.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
url (str): The URL to send the POST request to. Example: "https://api.example.com/data"
|
|
168
|
+
headers (dict, optional): Optional HTTP headers to include in the request. Example: {"Content-Type": "application/json"}
|
|
169
|
+
body (dict, optional): Optional JSON body to include in the request. Example: {"name": "John"}
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
dict: The JSON response from the POST request, or text if not JSON.
|
|
173
|
+
Tags:
|
|
174
|
+
post, important
|
|
175
|
+
"""
|
|
176
|
+
logger.debug(f"POST request to {url} with headers {headers} and body {body}")
|
|
177
|
+
response = httpx.post(url, json=body, headers=headers)
|
|
178
|
+
response.raise_for_status()
|
|
179
|
+
return self._handle_response(response)
|
|
180
|
+
|
|
181
|
+
def http_put(self, url: str, headers: dict | None = None, body: dict | None = None):
|
|
182
|
+
"""
|
|
183
|
+
Perform a PUT request to the specified URL with optional parameters.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
url (str): The URL to send the PUT request to. Example: "https://api.example.com/data/1"
|
|
187
|
+
headers (dict, optional): Optional HTTP headers to include in the request. Example: {"Authorization": "Bearer token"}
|
|
188
|
+
body (dict, optional): Optional JSON body to include in the request. Example: {"name": "Jane"}
|
|
189
|
+
|
|
190
|
+
Returns:
|
|
191
|
+
dict: The JSON response from the PUT request, or text if not JSON.
|
|
192
|
+
Tags:
|
|
193
|
+
put, important
|
|
194
|
+
"""
|
|
195
|
+
logger.debug(f"PUT request to {url} with headers {headers} and body {body}")
|
|
196
|
+
response = httpx.put(url, json=body, headers=headers)
|
|
197
|
+
response.raise_for_status()
|
|
198
|
+
return self._handle_response(response)
|
|
199
|
+
|
|
200
|
+
def http_delete(
|
|
201
|
+
self, url: str, headers: dict | None = None, body: dict | None = None
|
|
202
|
+
):
|
|
203
|
+
"""
|
|
204
|
+
Perform a DELETE request to the specified URL with optional parameters.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
url (str): The URL to send the DELETE request to. Example: "https://api.example.com/data/1"
|
|
208
|
+
headers (dict, optional): Optional HTTP headers to include in the request. Example: {"Authorization": "Bearer token"}
|
|
209
|
+
body (dict, optional): Optional JSON body to include in the request. Example: {"reason": "obsolete"}
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
dict: The JSON response from the DELETE request, or text if not JSON.
|
|
213
|
+
Tags:
|
|
214
|
+
delete, important
|
|
215
|
+
"""
|
|
216
|
+
logger.debug(f"DELETE request to {url} with headers {headers} and body {body}")
|
|
217
|
+
response = httpx.delete(url, json=body, headers=headers)
|
|
218
|
+
response.raise_for_status()
|
|
219
|
+
return self._handle_response(response)
|
|
220
|
+
|
|
221
|
+
def http_patch(
|
|
222
|
+
self, url: str, headers: dict | None = None, body: dict | None = None
|
|
223
|
+
):
|
|
224
|
+
"""
|
|
225
|
+
Perform a PATCH request to the specified URL with optional parameters.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
url (str): The URL to send the PATCH request to. Example: "https://api.example.com/data/1"
|
|
229
|
+
headers (dict, optional): Optional HTTP headers to include in the request. Example: {"Authorization": "Bearer token"}
|
|
230
|
+
body (dict, optional): Optional JSON body to include in the request. Example: {"status": "active"}
|
|
231
|
+
|
|
232
|
+
Returns:
|
|
233
|
+
dict: The JSON response from the PATCH request, or text if not JSON.
|
|
234
|
+
Tags:
|
|
235
|
+
patch, important
|
|
236
|
+
"""
|
|
237
|
+
logger.debug(f"PATCH request to {url} with headers {headers} and body {body}")
|
|
238
|
+
response = httpx.patch(url, json=body, headers=headers)
|
|
239
|
+
response.raise_for_status()
|
|
240
|
+
return self._handle_response(response)
|
|
241
|
+
|
|
242
|
+
async def read_file(self, uri: str) -> str:
|
|
243
|
+
"""
|
|
244
|
+
This tool aims to extract the main text content from any url.
|
|
245
|
+
When faced with a question you do not know the answer to, call this tool as often as
|
|
246
|
+
needed to get the full context from any file in the user file attachments section.
|
|
247
|
+
|
|
248
|
+
Asynchronously converts a URI or local file path to markdown format
|
|
249
|
+
using the markitdown converter.
|
|
250
|
+
Args:
|
|
251
|
+
uri (str): The URI pointing to the resource or a local file path.
|
|
252
|
+
Supported schemes:
|
|
253
|
+
- http:// or https:// (Web pages, feeds, APIs)
|
|
254
|
+
- file:// (Local or accessible network files)
|
|
255
|
+
- data: (Embedded data)
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
A string containing the markdown representation of the content at the specified URI
|
|
259
|
+
|
|
260
|
+
Raises:
|
|
261
|
+
ValueError: If the URI is invalid, empty, or uses an unsupported scheme
|
|
262
|
+
after automatic prefixing.
|
|
263
|
+
|
|
264
|
+
Tags:
|
|
265
|
+
convert, markdown, async, uri, transform, document, important
|
|
266
|
+
"""
|
|
267
|
+
if not uri:
|
|
268
|
+
raise ValueError("URI cannot be empty")
|
|
269
|
+
|
|
270
|
+
known_schemes = ["http://", "https://", "file://", "data:"]
|
|
271
|
+
has_scheme = any(uri.lower().startswith(scheme) for scheme in known_schemes)
|
|
272
|
+
if not has_scheme and not re.match(r"^[a-zA-Z]+:", uri):
|
|
273
|
+
if re.match(r"^[a-zA-Z]:[\\/]", uri): # Check for Windows drive letter path
|
|
274
|
+
normalized_path = uri.replace("\\", "/") # Normalize backslashes
|
|
275
|
+
processed_uri = f"file:///{normalized_path}"
|
|
276
|
+
else: # Assume Unix-like path or simple relative path
|
|
277
|
+
processed_uri = (
|
|
278
|
+
f"file://{uri}" if uri.startswith("/") else f"file:///{uri}"
|
|
279
|
+
) # Add leading slash if missing for absolute paths
|
|
280
|
+
|
|
281
|
+
uri_to_process = processed_uri
|
|
282
|
+
else:
|
|
283
|
+
# Use the uri as provided
|
|
284
|
+
uri_to_process = uri
|
|
285
|
+
|
|
286
|
+
return self.markitdown.convert_uri(uri_to_process).markdown
|
|
287
|
+
|
|
288
|
+
def list_tools(self):
|
|
289
|
+
"""List all available tool methods in this application.
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
list: A list of callable tool methods.
|
|
293
|
+
"""
|
|
294
|
+
return [
|
|
295
|
+
self.create_bar_chart,
|
|
296
|
+
self.create_line_chart,
|
|
297
|
+
self.create_pie_chart,
|
|
298
|
+
self.create_table,
|
|
299
|
+
self.http_get,
|
|
300
|
+
self.http_post,
|
|
301
|
+
self.http_put,
|
|
302
|
+
self.http_delete,
|
|
303
|
+
self.http_patch,
|
|
304
|
+
self.read_file,
|
|
305
|
+
]
|
universal_mcp/agents/utils.py
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from contextlib import contextmanager
|
|
3
3
|
|
|
4
|
+
from langchain_core.messages.base import BaseMessage
|
|
4
5
|
from rich.console import Console
|
|
5
6
|
from rich.live import Live
|
|
6
7
|
from rich.markdown import Markdown
|
|
7
8
|
from rich.panel import Panel
|
|
8
9
|
from rich.prompt import Prompt
|
|
9
10
|
from rich.table import Table
|
|
11
|
+
from universal_mcp.tools.manager import ToolManager
|
|
12
|
+
from universal_mcp.types import ToolFormat
|
|
13
|
+
|
|
14
|
+
from universal_mcp.agents.ui_tools import UIToolsApp
|
|
10
15
|
|
|
11
16
|
|
|
12
17
|
class RichCLI:
|
|
@@ -24,11 +29,14 @@ Available commands:
|
|
|
24
29
|
- `/tools` - List available tools
|
|
25
30
|
- `/exit` - Exit the application
|
|
26
31
|
"""
|
|
27
|
-
self.console.print(
|
|
32
|
+
self.console.print(
|
|
33
|
+
Panel(Markdown(welcome_text), title="🤖 AI Agent CLI", border_style="blue")
|
|
34
|
+
)
|
|
28
35
|
|
|
29
36
|
def display_agent_response(self, response: str, agent_name: str):
|
|
30
37
|
"""Display agent response with formatting"""
|
|
31
|
-
self.console.print(
|
|
38
|
+
self.console.print(f"[green]🤖 {agent_name}:[/green]")
|
|
39
|
+
self.console.print(Markdown(response), style="green")
|
|
32
40
|
|
|
33
41
|
@contextmanager
|
|
34
42
|
def display_agent_response_streaming(self, agent_name: str):
|
|
@@ -37,24 +45,35 @@ Available commands:
|
|
|
37
45
|
with Live(refresh_per_second=10, console=self.console) as live:
|
|
38
46
|
|
|
39
47
|
class StreamUpdater:
|
|
48
|
+
type_ = ""
|
|
40
49
|
content = []
|
|
41
50
|
|
|
42
|
-
def update(self, chunk: str):
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
def update(self, chunk: str, type_: str):
|
|
52
|
+
if not chunk:
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
# Check if type has changed and reset content if so
|
|
56
|
+
if self.type_ != type_:
|
|
57
|
+
if type_ == "thinking":
|
|
58
|
+
self.content += (
|
|
59
|
+
"\n[bold yellow]💭 Thinking:[/bold yellow] :"
|
|
60
|
+
)
|
|
61
|
+
elif type_ == "text":
|
|
62
|
+
self.content += (
|
|
63
|
+
f"\n[bold green]🤖 {agent_name}[/bold green] :"
|
|
64
|
+
)
|
|
65
|
+
self.type_ = type_
|
|
66
|
+
self.content += chunk
|
|
67
|
+
content_text = "".join(self.content)
|
|
68
|
+
live.update(content_text)
|
|
51
69
|
|
|
52
70
|
yield StreamUpdater()
|
|
53
71
|
|
|
54
72
|
def display_thinking(self, thought: str):
|
|
55
73
|
"""Display agent's thinking process"""
|
|
56
74
|
if thought:
|
|
57
|
-
self.console.print(
|
|
75
|
+
self.console.print("[bold yellow]💭 Thinking:[/bold yellow]")
|
|
76
|
+
self.console.print(thought, style="yellow")
|
|
58
77
|
|
|
59
78
|
def display_tools(self, tools: list):
|
|
60
79
|
"""Display available tools in a table"""
|
|
@@ -71,16 +90,18 @@ Available commands:
|
|
|
71
90
|
def display_tool_call(self, tool_call: dict):
|
|
72
91
|
"""Display tool call"""
|
|
73
92
|
tool_call_str = json.dumps(tool_call, indent=2)
|
|
74
|
-
self.console.print(
|
|
93
|
+
self.console.print("[green]🛠️ Tool Call:[/green]")
|
|
94
|
+
self.console.print(tool_call_str, style="green")
|
|
75
95
|
|
|
76
96
|
def display_tool_result(self, tool_result: dict):
|
|
77
97
|
"""Display tool result"""
|
|
78
98
|
tool_result_str = json.dumps(tool_result, indent=2)
|
|
79
|
-
self.console.print(
|
|
99
|
+
self.console.print("[green]🛠️ Tool Result:[/green]")
|
|
100
|
+
self.console.print(tool_result_str, style="green")
|
|
80
101
|
|
|
81
102
|
def display_error(self, error: str):
|
|
82
103
|
"""Display error message"""
|
|
83
|
-
self.console.print(
|
|
104
|
+
self.console.print(f"[red]❌ Error: {error}[/red]")
|
|
84
105
|
|
|
85
106
|
def get_user_input(self) -> str:
|
|
86
107
|
"""Get user input with rich prompt"""
|
|
@@ -100,12 +121,29 @@ Available commands:
|
|
|
100
121
|
value = Prompt.ask(interrupt.value["question"])
|
|
101
122
|
return value
|
|
102
123
|
elif interrupt_type == "bool":
|
|
103
|
-
value = Prompt.ask(
|
|
124
|
+
value = Prompt.ask(
|
|
125
|
+
interrupt.value["question"], choices=["y", "n"], default="y"
|
|
126
|
+
)
|
|
104
127
|
return value
|
|
105
128
|
elif interrupt_type == "choice":
|
|
106
129
|
value = Prompt.ask(
|
|
107
|
-
interrupt.value["question"],
|
|
130
|
+
interrupt.value["question"],
|
|
131
|
+
choices=interrupt.value["choices"],
|
|
132
|
+
default=interrupt.value["choices"][0],
|
|
108
133
|
)
|
|
109
134
|
return value
|
|
110
135
|
else:
|
|
111
136
|
raise ValueError(f"Invalid interrupt type: {interrupt.value['type']}")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def messages_to_list(messages: list[BaseMessage]):
|
|
140
|
+
return [{"type": message.type, "content": message.content} for message in messages]
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def initialize_ui_tools() -> list:
|
|
144
|
+
"""
|
|
145
|
+
Initialize and return UI tools in a langchain compatible format.
|
|
146
|
+
"""
|
|
147
|
+
tool_manager = ToolManager(default_format=ToolFormat.LANGCHAIN)
|
|
148
|
+
tool_manager.register_tools_from_app(UIToolsApp())
|
|
149
|
+
return tool_manager.list_tools()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: universal-mcp-agents
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Project-URL: Homepage, https://github.com/universal-mcp/applications
|
|
6
6
|
Project-URL: Repository, https://github.com/universal-mcp/applications
|
|
@@ -11,11 +11,12 @@ Requires-Dist: langchain-anthropic>=0.3.19
|
|
|
11
11
|
Requires-Dist: langchain-google-genai>=2.1.10
|
|
12
12
|
Requires-Dist: langchain-openai>=0.3.32
|
|
13
13
|
Requires-Dist: langgraph>=0.6.6
|
|
14
|
-
Requires-Dist: universal-mcp-applications>=0.1.
|
|
14
|
+
Requires-Dist: universal-mcp-applications>=0.1.4
|
|
15
15
|
Requires-Dist: universal-mcp>=0.1.24rc17
|
|
16
16
|
Provides-Extra: dev
|
|
17
17
|
Requires-Dist: pre-commit; extra == 'dev'
|
|
18
18
|
Requires-Dist: ruff; extra == 'dev'
|
|
19
19
|
Provides-Extra: test
|
|
20
|
+
Requires-Dist: pytest-asyncio>=1.1.0; extra == 'test'
|
|
20
21
|
Requires-Dist: pytest-cov; extra == 'test'
|
|
21
22
|
Requires-Dist: pytest<9.0.0,>=7.0.0; extra == 'test'
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
universal_mcp/agents/__init__.py,sha256=QfYDUZxIYQSqbpGt6NZ3U5tjf7SS1Y9uPzAwmaRoDrA,1186
|
|
2
|
+
universal_mcp/agents/base.py,sha256=uJQnOwsggbvRpPwUkZ4QWgHBMrPVf2gJC8QbKglxlrM,6841
|
|
3
|
+
universal_mcp/agents/builder.py,sha256=X3GETG465ifiJxWqk6ZxTlDvI48osHgaFbDGzc10Rsg,7640
|
|
4
|
+
universal_mcp/agents/cli.py,sha256=_rJV6TxBG2amH3o8mVs4pxViaTfkBhz6n5l6xhv4Z3g,1014
|
|
5
|
+
universal_mcp/agents/hil.py,sha256=XfQT8QcuDbiIpUU9N4WSbO2Tm9YNSuwRqyCTWmCWaZo,3818
|
|
6
|
+
universal_mcp/agents/llm.py,sha256=hVRwjZs3MHl5_3BWedmurs2Jt1oZDfFX0Zj9F8KH7fk,1787
|
|
7
|
+
universal_mcp/agents/react.py,sha256=6zwb-yPor86-bDOrrDaZl8MxyWL1ReikCkFs3noOwU4,2885
|
|
8
|
+
universal_mcp/agents/simple.py,sha256=Z5Ja12vJIhIHhB68WWH_5opln7FMDUiRfztKOj2Rx-U,1941
|
|
9
|
+
universal_mcp/agents/tools.py,sha256=ysSwOYnpyoXA2Y1XcBFuYKKv-mUu-BYNUecpdRTK2fM,1406
|
|
10
|
+
universal_mcp/agents/ui_tools.py,sha256=rNSXRHminXKvwGZISZ58qpnHQ8c6gPanXbu1icBXGFY,11224
|
|
11
|
+
universal_mcp/agents/utils.py,sha256=bEQvI-dNo4sOj1te3ARmWnDSg9nFccfLiJ4baXEutoA,5323
|
|
12
|
+
universal_mcp/agents/autoagent/__init__.py,sha256=fDiruZjxHhGPa6gg88as0SKHV8c3Mq56CCshZDIcLt8,836
|
|
13
|
+
universal_mcp/agents/autoagent/__main__.py,sha256=S_inq-PR6KgJqcDhoXp_-PCehORF6WGputQ_hTrJOl0,654
|
|
14
|
+
universal_mcp/agents/autoagent/context.py,sha256=RgjW1uCslucxYJpdmi4govd-0V1_9e6Y_kjWl3FpLrE,847
|
|
15
|
+
universal_mcp/agents/autoagent/graph.py,sha256=JKdQy21w5jXyjyICTrhKS4MXHth6kHzREhR-DCU3Dws,6928
|
|
16
|
+
universal_mcp/agents/autoagent/prompts.py,sha256=v-EwzZ_0XPuBNd_r8aWxmKMSQlZLTVBr0o-dmTQMN1w,892
|
|
17
|
+
universal_mcp/agents/autoagent/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
18
|
+
universal_mcp/agents/autoagent/studio.py,sha256=ZxiC9C2xdOhZ4Qb5fKoAci3TOhcdKlpiTT_5C3CF_AI,639
|
|
19
|
+
universal_mcp/agents/autoagent/utils.py,sha256=AFq-8scw_WlSZxDnTzxSNrOSiGYsIlqkqtQLDWf_rMU,431
|
|
20
|
+
universal_mcp/agents/bigtool/__init__.py,sha256=Qw2C29q6R7TXmpzlSStwYM9Rbv9Iguj7U0p0CPy7thY,1782
|
|
21
|
+
universal_mcp/agents/bigtool/__main__.py,sha256=WkPJl8r7L0CZXoFCU8w7eFEejLI8KIflkWnvLFt8jdA,660
|
|
22
|
+
universal_mcp/agents/bigtool/graph.py,sha256=JAw7waUrAA7t6ZpbPcbnSu3sh6MhYfIUkJJfYc9mHCc,8528
|
|
23
|
+
universal_mcp/agents/bigtool/prompts.py,sha256=pzLNaLg5ftv8B8k7McpDrSkos0N5eR6rKcw5psudBFg,1662
|
|
24
|
+
universal_mcp/agents/bigtool/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
25
|
+
universal_mcp/agents/bigtool2/__init__.py,sha256=3BESPudZ_eAu3LOkNHWlabp_4Y6ioQmLXOgA5AKzKvs,2024
|
|
26
|
+
universal_mcp/agents/bigtool2/__main__.py,sha256=fYWqoaJw10KsjDETbNM0yX61KXvinIm5jiwSuBcNNKY,669
|
|
27
|
+
universal_mcp/agents/bigtool2/agent.py,sha256=4GIQIy2VQgdXOezmET8G7tvP_37Vv8C027bGdGXJbTI,437
|
|
28
|
+
universal_mcp/agents/bigtool2/graph.py,sha256=i06Uoelw2lKgllO2REnvfDpV8T1AuAuCVJS45DIH8aY,9046
|
|
29
|
+
universal_mcp/agents/bigtool2/prompts.py,sha256=UBOfJQOknNyNLaz_38CaBXsFOocbDQEKC59_mM_kpCQ,1640
|
|
30
|
+
universal_mcp/agents/bigtool2/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
31
|
+
universal_mcp/agents/bigtoolcache/__init__.py,sha256=UeebKmlLdgyZfpjO1cB1ZmbYnfleKPvyi_XHegmHdPk,1844
|
|
32
|
+
universal_mcp/agents/bigtoolcache/__main__.py,sha256=oldL6enfW_2UhyK1mW0UTBV_ww4PW2k_j187Hx_i8YI,622
|
|
33
|
+
universal_mcp/agents/bigtoolcache/agent.py,sha256=ZRpPykErFcsV-YJCAV-3mCEkczvML9iwLcFEgEwbFfE,461
|
|
34
|
+
universal_mcp/agents/bigtoolcache/context.py,sha256=ny7gd-vvVpUOYAeQbAEUT0A6Vm6Nn2qGywxTzPBzYFg,929
|
|
35
|
+
universal_mcp/agents/bigtoolcache/graph.py,sha256=oFV24ap3xPwds6k5El9m28mf29Z3jzhYWc4XgNYn7pU,8694
|
|
36
|
+
universal_mcp/agents/bigtoolcache/prompts.py,sha256=XDU2uJWzwGwt8t3zGjOH16YIrHJCdPuLP5lyJ2llXFg,3226
|
|
37
|
+
universal_mcp/agents/bigtoolcache/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
38
|
+
universal_mcp/agents/bigtoolcache/tools_all.txt,sha256=g52i00AOh9VTDsAtIAF8vhqtTHQVmzTn61k724niEA0,95408
|
|
39
|
+
universal_mcp/agents/bigtoolcache/tools_important.txt,sha256=PD4klowvARwhbC8dcXMm_sGUWH7cAynX40nXLqeRbdQ,38593
|
|
40
|
+
universal_mcp/agents/codeact/__init__.py,sha256=qm06CsIodscl-XFfriYiPMDn7I_aIg48TTIw2ESgU2w,10263
|
|
41
|
+
universal_mcp/agents/codeact/sandbox.py,sha256=lGRzhuXTHCB1qauuOI3bH1-fPTsyL6Lf9EmMIz4C2xQ,1039
|
|
42
|
+
universal_mcp/agents/codeact/test.py,sha256=MT0v4HChoJU4MGb7oIDlG8lvBUymroXjAkP-ELu2fKw,498
|
|
43
|
+
universal_mcp/agents/codeact/utils.py,sha256=VuMvLTxBBh3pgaJk8RWj5AK8XZFF-1gnZJ6jFLeM_CI,1690
|
|
44
|
+
universal_mcp/agents/planner/__init__.py,sha256=b5HnTHXvs0y5KBwy9yr8d96MbyObUZ8QWrCFbUhdgGo,1335
|
|
45
|
+
universal_mcp/agents/planner/__main__.py,sha256=OfhTfYDZK_ZUfc8sX-Sa6TWk-dNqD2rl13Ln64mNAtw,771
|
|
46
|
+
universal_mcp/agents/planner/graph.py,sha256=qTXUVXiPWZP73GsY9mQEGmBtA-C1t06jpzgJINNpMFU,3241
|
|
47
|
+
universal_mcp/agents/planner/prompts.py,sha256=_JoHqiAvswtqCDu90AGUHmfsu8eWE1-_yI4LLn3pqMU,657
|
|
48
|
+
universal_mcp/agents/planner/state.py,sha256=qqyp-jSGsCxe1US-PRLT4-y1sITAcVE6nCMlQLnvop0,278
|
|
49
|
+
universal_mcp/agents/shared/tool_node.py,sha256=FiKY0AhxKIFpzGKGnyRL-6Dzuf0KUDmiQo7IhXmE27s,8861
|
|
50
|
+
universal_mcp_agents-0.1.5.dist-info/METADATA,sha256=RQnfekXpQJ0KkapTG_IQUXYPPd4tNcNGzpNaGLkFNcU,847
|
|
51
|
+
universal_mcp_agents-0.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
52
|
+
universal_mcp_agents-0.1.5.dist-info/RECORD,,
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass, field
|
|
2
|
-
|
|
3
|
-
from .prompts import SYSTEM_PROMPT
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@dataclass(kw_only=True)
|
|
7
|
-
class Context:
|
|
8
|
-
"""The context for the agent."""
|
|
9
|
-
|
|
10
|
-
system_prompt: str = field(
|
|
11
|
-
default=SYSTEM_PROMPT,
|
|
12
|
-
metadata={
|
|
13
|
-
"description": "The system prompt to use for the agent's interactions. "
|
|
14
|
-
"This prompt sets the context and behavior for the agent."
|
|
15
|
-
},
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
model: str = field(
|
|
19
|
-
default="anthropic/claude-4-sonnet-20250514",
|
|
20
|
-
metadata={
|
|
21
|
-
"description": "The name of the language model to use for the agent's main interactions. "
|
|
22
|
-
"Should be in the form: provider/model-name."
|
|
23
|
-
},
|
|
24
|
-
)
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass, field
|
|
2
|
-
|
|
3
|
-
from .prompts import SYSTEM_PROMPT
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
@dataclass(kw_only=True)
|
|
7
|
-
class Context:
|
|
8
|
-
"""The context for the agent."""
|
|
9
|
-
|
|
10
|
-
system_prompt: str = field(
|
|
11
|
-
default=SYSTEM_PROMPT,
|
|
12
|
-
metadata={
|
|
13
|
-
"description": "The system prompt to use for the agent's interactions. "
|
|
14
|
-
"This prompt sets the context and behavior for the agent."
|
|
15
|
-
},
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
model: str = field(
|
|
19
|
-
default="anthropic/claude-4-sonnet-20250514",
|
|
20
|
-
metadata={
|
|
21
|
-
"description": "The name of the language model to use for the agent's main interactions. "
|
|
22
|
-
"Should be in the form: provider/model-name."
|
|
23
|
-
},
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
recursion_limit: int = field(
|
|
27
|
-
default=10,
|
|
28
|
-
metadata={
|
|
29
|
-
"description": "The maximum number of times the agent can call itself recursively. "
|
|
30
|
-
"This is to prevent infinite recursion."
|
|
31
|
-
},
|
|
32
|
-
)
|
|
33
|
-
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
universal_mcp/agents/__init__.py,sha256=s50fHbQ3ufC_7mwQydHoua4KJOjKjKcUrAgMN0A_34M,588
|
|
2
|
-
universal_mcp/agents/base.py,sha256=zNYbzV1KY0OM-lDvLBMpdDpueKc6Wy54kbuzjFmBa5w,5170
|
|
3
|
-
universal_mcp/agents/builder.py,sha256=duPULxwOEt6IFMK9n0yvaeOFW3Js50WucFi224BMwG8,5956
|
|
4
|
-
universal_mcp/agents/cli.py,sha256=7GdRBpu9rhZPiC2vaNQXWI7K-0yCnvdlmE0IFpvy2Gk,539
|
|
5
|
-
universal_mcp/agents/hil.py,sha256=6xi0hhK5g-rhCrAMcGbjcKMReLWPC8rnFZMBOF3N_cY,3687
|
|
6
|
-
universal_mcp/agents/llm.py,sha256=P03zoUxBfivMa3djt2kmWANxGLg77Tapx1aQJEPVTCo,1592
|
|
7
|
-
universal_mcp/agents/react.py,sha256=EVk59XVelBFV13us3CG-RolzRmu8v7FrhlR7m2QIYUY,2526
|
|
8
|
-
universal_mcp/agents/simple.py,sha256=JL8TFyXlA1F4zcArgKhlqVIbLWXetwM05z4MPDJgFeI,1367
|
|
9
|
-
universal_mcp/agents/tools.py,sha256=J8VdS1xnSEFeEVSmp5Hb47J2-4WJWtsIidUP1lFXhds,1341
|
|
10
|
-
universal_mcp/agents/utils.py,sha256=7kwFpD0Rv6JqHG-LlNCVwSu_xRX-N119mUmiBroHJL4,4109
|
|
11
|
-
universal_mcp/agents/autoagent/__init__.py,sha256=RruAbcjyMTB-dIRkzFZYtQxrTpZetynBRYd1xD9noj8,836
|
|
12
|
-
universal_mcp/agents/autoagent/__main__.py,sha256=HH5D5gSw6xirrSoj_0CCmQlVq_wfp--b6hZdiHGfXD8,654
|
|
13
|
-
universal_mcp/agents/autoagent/context.py,sha256=RgjW1uCslucxYJpdmi4govd-0V1_9e6Y_kjWl3FpLrE,847
|
|
14
|
-
universal_mcp/agents/autoagent/graph.py,sha256=zQ8XDPELK5MbdMy5hy9rkJtgd71I1RdPlpbNkqvXtuM,6645
|
|
15
|
-
universal_mcp/agents/autoagent/prompts.py,sha256=v-EwzZ_0XPuBNd_r8aWxmKMSQlZLTVBr0o-dmTQMN1w,892
|
|
16
|
-
universal_mcp/agents/autoagent/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
17
|
-
universal_mcp/agents/autoagent/studio.py,sha256=nfVRzPXwBjDORHA0wln2k3Nz-zQXNKgZMvgeqBvkdtM,644
|
|
18
|
-
universal_mcp/agents/autoagent/utils.py,sha256=AFq-8scw_WlSZxDnTzxSNrOSiGYsIlqkqtQLDWf_rMU,431
|
|
19
|
-
universal_mcp/agents/bigtool/__init__.py,sha256=gKSEOmOE5ZsIypxu1sUibzJ8acbk83DjApxE0Adawro,1853
|
|
20
|
-
universal_mcp/agents/bigtool/__main__.py,sha256=_4HBqnlmdJwXOgeMITjBgaDHihED-aEgQmSXL9xcj0Y,602
|
|
21
|
-
universal_mcp/agents/bigtool/context.py,sha256=KM_B-rvEulrvXSBrXAJpwxGHVMW0HgiYKMnmrL2pUEQ,688
|
|
22
|
-
universal_mcp/agents/bigtool/graph.py,sha256=fOr0p547kjpM_CkRyyEcDxmTZ5lEKaTAR98nRCkgsks,8284
|
|
23
|
-
universal_mcp/agents/bigtool/prompts.py,sha256=A6El6Qw9r_D8OD4IZKuYqvrJFJZZmUhrTKlyqFPf6c0,1666
|
|
24
|
-
universal_mcp/agents/bigtool/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
25
|
-
universal_mcp/agents/bigtool2/__init__.py,sha256=uP52BOl0z1n_ECbybf6lxVvC0PAjNMrBUcXUOibXjvA,1779
|
|
26
|
-
universal_mcp/agents/bigtool2/__main__.py,sha256=C4Mi8vM9kuGa_CryzIc9nL4-u73ZvSK5tOTbMDMN54I,605
|
|
27
|
-
universal_mcp/agents/bigtool2/agent.py,sha256=iwn2kyC-Wft40f_QHlLtg7fPpFUpwkjk7I5LJrrS4i8,434
|
|
28
|
-
universal_mcp/agents/bigtool2/context.py,sha256=1DMp8g4Gb6UUxVh8bcqafV2WpTGKo6GlaDN6Ey7cAbo,930
|
|
29
|
-
universal_mcp/agents/bigtool2/graph.py,sha256=l6LBWmBCsjO0r1TZUXAQHXvz_iqkW_9tGJSlySkcG7A,8373
|
|
30
|
-
universal_mcp/agents/bigtool2/prompts.py,sha256=Kn1sDrjH2xb3js_MPPu5PJHMP45unl93CdOC97Q_hzw,1652
|
|
31
|
-
universal_mcp/agents/bigtool2/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
32
|
-
universal_mcp/agents/bigtoolcache/__init__.py,sha256=dTPxrFIJGaJKb67a935UEkgqnBGdN9q1ba2HnpNAuq4,1792
|
|
33
|
-
universal_mcp/agents/bigtoolcache/__main__.py,sha256=HkPEQqsdnWtDzWSbYdVBBc_JhpRi82TYuaubxNMtt4w,622
|
|
34
|
-
universal_mcp/agents/bigtoolcache/agent.py,sha256=xLTymzsmpNpJf8-y1Mi8BbuWl09kXsk1sdhbJyVwASU,446
|
|
35
|
-
universal_mcp/agents/bigtoolcache/context.py,sha256=1DMp8g4Gb6UUxVh8bcqafV2WpTGKo6GlaDN6Ey7cAbo,930
|
|
36
|
-
universal_mcp/agents/bigtoolcache/graph.py,sha256=--CuUEc2IKGdKeMueEvsQ-GxCYZVlDclQdKhrf0ctvU,8418
|
|
37
|
-
universal_mcp/agents/bigtoolcache/prompts.py,sha256=bIbuktsi0EkOXxYGkyB-e_rmolllrHo4kDsvWO5p_1c,1874
|
|
38
|
-
universal_mcp/agents/bigtoolcache/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
39
|
-
universal_mcp/agents/codeact/__init__.py,sha256=5D_I3lI_3tWjZERRoFav_bPe9UDaJ53pDzZYtyixg3E,10097
|
|
40
|
-
universal_mcp/agents/codeact/sandbox.py,sha256=lGRzhuXTHCB1qauuOI3bH1-fPTsyL6Lf9EmMIz4C2xQ,1039
|
|
41
|
-
universal_mcp/agents/codeact/test.py,sha256=AI3qWszpM46hF4wzuQm6A8g_UkhGmcg9KhHtk9u14ro,497
|
|
42
|
-
universal_mcp/agents/codeact/utils.py,sha256=VuMvLTxBBh3pgaJk8RWj5AK8XZFF-1gnZJ6jFLeM_CI,1690
|
|
43
|
-
universal_mcp/agents/planner/__init__.py,sha256=VTLVqIWkVh5SAuFoFupxByoqyNS1vCuc14mdUSr-vKE,1090
|
|
44
|
-
universal_mcp/agents/planner/__main__.py,sha256=nAFabo6SVZh4_4GV-SWCpnGg5GsVXgiHYpm9mhCQ6zw,685
|
|
45
|
-
universal_mcp/agents/planner/graph.py,sha256=Cj5Y1BI9uJvrYsr4JrQSPRSszznjdVD2dJHWHHJhxp0,3101
|
|
46
|
-
universal_mcp/agents/planner/prompts.py,sha256=vLViZ4BeinqUe8gXACLl04UUnH-Hie5L2qDyhCmSNe0,32
|
|
47
|
-
universal_mcp/agents/planner/state.py,sha256=EdrIELvxzBZtdC1FpmErYnCC7OSJ3Irx9QGiCBCeomA,279
|
|
48
|
-
universal_mcp/agents/shared/tool_node.py,sha256=IkjEcgzRAgjQTqcoa-i1dDY2LJfgOGj9HF8vihYuk_s,8678
|
|
49
|
-
universal_mcp_agents-0.1.3.dist-info/METADATA,sha256=2f3oKTOzRHYoo7I8JXDJWklC09SHF0IWVzj0MljFGfg,793
|
|
50
|
-
universal_mcp_agents-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
51
|
-
universal_mcp_agents-0.1.3.dist-info/RECORD,,
|
|
File without changes
|