universal-mcp-agents 0.1.19rc1__py3-none-any.whl → 0.1.20rc1__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 universal-mcp-agents might be problematic. Click here for more details.
- universal_mcp/agents/__init__.py +5 -9
- universal_mcp/agents/base.py +4 -1
- universal_mcp/agents/cli.py +0 -3
- universal_mcp/agents/codeact0/__init__.py +2 -3
- universal_mcp/agents/codeact0/__main__.py +2 -2
- universal_mcp/agents/codeact0/agent.py +231 -83
- universal_mcp/agents/codeact0/langgraph_agent.py +1 -1
- universal_mcp/agents/codeact0/prompts.py +38 -5
- universal_mcp/agents/codeact0/sandbox.py +31 -1
- universal_mcp/agents/codeact0/state.py +3 -1
- universal_mcp/agents/codeact0/tools.py +200 -85
- {universal_mcp_agents-0.1.19rc1.dist-info → universal_mcp_agents-0.1.20rc1.dist-info}/METADATA +1 -1
- universal_mcp_agents-0.1.20rc1.dist-info/RECORD +44 -0
- universal_mcp/agents/codeact/__init__.py +0 -3
- universal_mcp/agents/codeact/__main__.py +0 -33
- universal_mcp/agents/codeact/agent.py +0 -240
- universal_mcp/agents/codeact/models.py +0 -11
- universal_mcp/agents/codeact/prompts.py +0 -82
- universal_mcp/agents/codeact/sandbox.py +0 -85
- universal_mcp/agents/codeact/state.py +0 -11
- universal_mcp/agents/codeact/utils.py +0 -68
- universal_mcp/agents/codeact0/playbook_agent.py +0 -355
- universal_mcp/agents/unified/README.md +0 -45
- universal_mcp/agents/unified/__init__.py +0 -3
- universal_mcp/agents/unified/__main__.py +0 -28
- universal_mcp/agents/unified/agent.py +0 -289
- universal_mcp/agents/unified/langgraph_agent.py +0 -14
- universal_mcp/agents/unified/llm_tool.py +0 -25
- universal_mcp/agents/unified/prompts.py +0 -192
- universal_mcp/agents/unified/sandbox.py +0 -101
- universal_mcp/agents/unified/state.py +0 -42
- universal_mcp/agents/unified/tools.py +0 -188
- universal_mcp/agents/unified/utils.py +0 -388
- universal_mcp_agents-0.1.19rc1.dist-info/RECORD +0 -64
- {universal_mcp_agents-0.1.19rc1.dist-info → universal_mcp_agents-0.1.20rc1.dist-info}/WHEEL +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
+
import json
|
|
2
3
|
from collections import defaultdict
|
|
3
|
-
from typing import Any
|
|
4
|
+
from typing import Annotated, Any
|
|
4
5
|
|
|
5
6
|
from langchain_core.tools import tool
|
|
6
|
-
from
|
|
7
|
+
from pydantic import Field
|
|
8
|
+
from universal_mcp.agentr.registry import AgentrRegistry
|
|
7
9
|
from universal_mcp.types import ToolFormat
|
|
8
10
|
|
|
9
|
-
MAX_LENGHT = 100
|
|
10
|
-
|
|
11
11
|
|
|
12
12
|
def enter_playbook_mode():
|
|
13
13
|
"""Call this function to enter playbook mode. Playbook mode is when the user wants to store a repeated task as a script with some inputs for the future."""
|
|
@@ -19,77 +19,180 @@ def exit_playbook_mode():
|
|
|
19
19
|
return
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def create_meta_tools(tool_registry:
|
|
22
|
+
def create_meta_tools(tool_registry: AgentrRegistry) -> dict[str, Any]:
|
|
23
23
|
"""Create the meta tools for searching and loading tools"""
|
|
24
24
|
|
|
25
25
|
@tool
|
|
26
|
-
async def search_functions(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
26
|
+
async def search_functions(
|
|
27
|
+
queries: Annotated[
|
|
28
|
+
list[str] | str | None,
|
|
29
|
+
Field(description="A single query or a list of queries to search for relevant functions"),
|
|
30
|
+
] = None,
|
|
31
|
+
app_id: Annotated[
|
|
32
|
+
str | None,
|
|
33
|
+
Field(description="The ID or common name of a specific application to search within"),
|
|
34
|
+
] = None,
|
|
35
|
+
) -> str:
|
|
36
|
+
"""
|
|
37
|
+
Searches for relevant functions across applications based on queries and/or a specific app.
|
|
38
|
+
This function operates in three modes:
|
|
39
|
+
|
|
40
|
+
1. **Global Search (provide `queries` only):**
|
|
41
|
+
- Use when the user wants to perform an action without specifying an application.
|
|
42
|
+
- The system will search across all available functions.
|
|
43
|
+
- Example: For "how can I create a presentation?", call with queries=["create presentation"].
|
|
44
|
+
|
|
45
|
+
2. **App Discovery (provide `app_id` only):**
|
|
46
|
+
- Use when the user asks about the capabilities of a specific application.
|
|
47
|
+
- The `app_id` can be the common name of the app (e.g., "Gmail", "Google Drive").
|
|
48
|
+
- This will return all available functions for that application, up to a limit.
|
|
49
|
+
- Example: For "what can you do with Gmail?", call with app_id="Gmail".
|
|
50
|
+
|
|
51
|
+
3. **Scoped Search (provide `queries` AND `app_id`):**
|
|
52
|
+
- Use when the user wants to perform an action within a specific application.
|
|
53
|
+
- This performs a targeted search only within the specified app's functions.
|
|
54
|
+
- Example: For "how do I find an email in Gmail?", call with queries=["find email"], app_id="Gmail".
|
|
55
|
+
"""
|
|
56
|
+
if isinstance(queries, str): # Handle JSON string input
|
|
57
|
+
try:
|
|
58
|
+
queries = json.loads(queries)
|
|
59
|
+
except json.JSONDecodeError:
|
|
60
|
+
# If it's a single query as a string, convert to list
|
|
61
|
+
queries = [queries] if queries else None
|
|
62
|
+
|
|
63
|
+
if not queries and not app_id:
|
|
64
|
+
raise ValueError("You must provide 'queries', an 'app_id', or both.")
|
|
65
|
+
|
|
66
|
+
registry = tool_registry
|
|
67
|
+
connections = await registry.list_connected_apps()
|
|
68
|
+
connected_app_ids = {connection["app_id"] for connection in connections}
|
|
69
|
+
|
|
70
|
+
canonical_app_id = None
|
|
71
|
+
found_tools_result = []
|
|
72
|
+
|
|
73
|
+
if app_id:
|
|
74
|
+
relevant_apps = await registry.search_apps(query=app_id, distance_threshold=0.7)
|
|
75
|
+
if not relevant_apps:
|
|
76
|
+
return {
|
|
77
|
+
"found_tools": [],
|
|
78
|
+
"message": f"Search failed. Application '{app_id}' was not found.",
|
|
79
|
+
}
|
|
80
|
+
canonical_app_id = relevant_apps[0]["id"]
|
|
81
|
+
|
|
82
|
+
if canonical_app_id and not queries:
|
|
83
|
+
all_app_tools = await registry.search_tools(query="", app_id=canonical_app_id, limit=20)
|
|
84
|
+
|
|
85
|
+
tool_list = []
|
|
86
|
+
for tool in all_app_tools:
|
|
87
|
+
cleaned_description = tool.get("description", "").split("Context:")[0].strip()
|
|
88
|
+
tool_list.append({"id": tool["id"], "description": cleaned_description})
|
|
89
|
+
|
|
90
|
+
found_tools_result.append(
|
|
91
|
+
{
|
|
92
|
+
"app_id": canonical_app_id,
|
|
93
|
+
"connection_status": "connected" if canonical_app_id in connected_app_ids else "not_connected",
|
|
94
|
+
"tools": tool_list,
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
query_results = []
|
|
100
|
+
prioritized_app_id_list = []
|
|
101
|
+
|
|
102
|
+
if canonical_app_id:
|
|
103
|
+
prioritized_app_id_list = [canonical_app_id]
|
|
104
|
+
else:
|
|
105
|
+
# 1. Perform an initial broad search for tools.
|
|
106
|
+
initial_tool_search_tasks = [registry.search_tools(query=q, distance_threshold=0.7) for q in queries]
|
|
107
|
+
initial_tool_results = await asyncio.gather(*initial_tool_search_tasks)
|
|
108
|
+
|
|
109
|
+
# 2. Search for relevant apps.
|
|
110
|
+
app_search_tasks = [registry.search_apps(query=q, distance_threshold=0.7) for q in queries]
|
|
111
|
+
app_search_results = await asyncio.gather(*app_search_tasks)
|
|
112
|
+
|
|
113
|
+
# 3. Create a prioritized list of app IDs for the final search.
|
|
114
|
+
# Apps found via search_apps are considered higher priority and come first.
|
|
115
|
+
app_ids_from_apps = {app["id"] for result_list in app_search_results for app in result_list}
|
|
116
|
+
# Use a list to maintain order.
|
|
117
|
+
prioritized_app_id_list.extend(list(app_ids_from_apps))
|
|
118
|
+
|
|
119
|
+
# Add app_ids from the initial tool search, ensuring no duplicates.
|
|
120
|
+
app_ids_from_tools = {tool["app_id"] for result_list in initial_tool_results for tool in result_list}
|
|
121
|
+
|
|
122
|
+
for tool_app_id in app_ids_from_tools:
|
|
123
|
+
if tool_app_id not in app_ids_from_apps:
|
|
124
|
+
prioritized_app_id_list.append(tool_app_id)
|
|
125
|
+
|
|
126
|
+
# 4. Perform the final, comprehensive tool search across the prioritized list of apps.
|
|
127
|
+
if prioritized_app_id_list:
|
|
128
|
+
# print(f"Prioritized app IDs for final search: {prioritized_app_id_list}")
|
|
129
|
+
final_tool_search_tasks = []
|
|
130
|
+
for app_id_to_search in prioritized_app_id_list:
|
|
131
|
+
for query in queries:
|
|
132
|
+
final_tool_search_tasks.append(
|
|
133
|
+
registry.search_tools(query=query, app_id=app_id_to_search, distance_threshold=0.7)
|
|
134
|
+
)
|
|
135
|
+
query_results = await asyncio.gather(*final_tool_search_tasks)
|
|
136
|
+
|
|
137
|
+
# 5. Aggregate all found tools for easy lookup.
|
|
138
|
+
aggregated_tools = defaultdict(dict)
|
|
139
|
+
for tool_list in query_results:
|
|
140
|
+
for tool in tool_list:
|
|
141
|
+
app_id_from_tool = tool.get("app_id", "unknown")
|
|
142
|
+
tool_id = tool.get("id")
|
|
143
|
+
if not tool_id or tool_id in aggregated_tools[app_id_from_tool]:
|
|
144
|
+
continue
|
|
145
|
+
cleaned_description = tool.get("description", "").split("Context:")[0].strip()
|
|
146
|
+
aggregated_tools[app_id_from_tool][tool_id] = {
|
|
147
|
+
"id": tool_id,
|
|
148
|
+
"description": cleaned_description,
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# 6. Build the final results list, respecting the prioritized app order.
|
|
152
|
+
for app_id_from_list in prioritized_app_id_list:
|
|
153
|
+
if app_id_from_list in aggregated_tools and aggregated_tools[app_id_from_list]:
|
|
154
|
+
found_tools_result.append(
|
|
155
|
+
{
|
|
156
|
+
"app_id": app_id_from_list,
|
|
157
|
+
"connection_status": "connected"
|
|
158
|
+
if app_id_from_list in connected_app_ids
|
|
159
|
+
else "not_connected",
|
|
160
|
+
"tools": list(aggregated_tools[app_id_from_list].values()),
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# Build result string efficiently
|
|
165
|
+
result_parts = []
|
|
166
|
+
apps_in_results = {app["app_id"] for app in found_tools_result}
|
|
167
|
+
connected_apps_in_results = apps_in_results.intersection(connected_app_ids)
|
|
168
|
+
|
|
169
|
+
for app in found_tools_result:
|
|
170
|
+
app_id = app["app_id"]
|
|
171
|
+
connection_status = app["connection_status"]
|
|
172
|
+
tools = app["tools"]
|
|
173
|
+
|
|
174
|
+
app_status = "connected" if connection_status == "connected" else "NOT connected"
|
|
175
|
+
result_parts.append(f"Tools from {app_id} (status: {app_status} by user):")
|
|
176
|
+
|
|
177
|
+
for tool in tools:
|
|
178
|
+
tool_id = tool["id"]
|
|
179
|
+
description = tool["description"]
|
|
180
|
+
result_parts.append(f" - {tool_id}: {description}")
|
|
181
|
+
result_parts.append("") # Empty line between apps
|
|
182
|
+
|
|
183
|
+
# Add connection status information
|
|
184
|
+
if len(connected_apps_in_results) == 0 and len(apps_in_results) > 0:
|
|
185
|
+
result_parts.append(
|
|
186
|
+
"Connection Status: None of the apps in the results are connected. You must ask the user to choose the application."
|
|
187
|
+
)
|
|
188
|
+
elif len(connected_apps_in_results) > 1:
|
|
189
|
+
connected_list = ", ".join(connected_apps_in_results)
|
|
190
|
+
result_parts.append(
|
|
191
|
+
f"Connection Status: Multiple apps are connected ({connected_list}). You must ask the user to select which application they want to use."
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
result_parts.append("Call load_functions to select the required functions only.")
|
|
195
|
+
return "\n".join(result_parts)
|
|
93
196
|
|
|
94
197
|
@tool
|
|
95
198
|
async def load_functions(tool_ids: list[str]) -> str:
|
|
@@ -105,34 +208,46 @@ def create_meta_tools(tool_registry: ToolRegistry) -> dict[str, Any]:
|
|
|
105
208
|
|
|
106
209
|
@tool
|
|
107
210
|
async def web_search(query: str) -> dict:
|
|
108
|
-
"""
|
|
109
|
-
|
|
211
|
+
"""Get an LLM answer to a question informed by Perplexity web search results.
|
|
212
|
+
Useful when you need information from a wide range of real-time sources on the web.
|
|
213
|
+
Do not use this when you need to access contents of a specific webpage.
|
|
110
214
|
|
|
111
|
-
This tool performs
|
|
112
|
-
1. Provides a **direct answer** for factual queries (
|
|
215
|
+
This tool performs a Perplexity request via `perplexity__answer_with_search`, which:
|
|
216
|
+
1. Provides a **direct answer** for factual queries with citation(s)
|
|
113
217
|
2. Generates a **summary with citations** for open-ended questions
|
|
114
|
-
(e.g., "What is the state of AI in healthcare?" → A detailed summary with source links)
|
|
115
218
|
|
|
116
219
|
Args:
|
|
117
220
|
query (str): The question or topic to answer.
|
|
221
|
+
|
|
118
222
|
Returns:
|
|
119
|
-
dict: A structured response containing
|
|
120
|
-
- answer (str): Generated answer
|
|
121
|
-
- citations (list[
|
|
223
|
+
dict: A structured response containing:
|
|
224
|
+
- answer (str): Generated answer with markdown formatting and citation numbers [1][2]
|
|
225
|
+
- citations (list[str]): List of source URLs corresponding to citation numbers
|
|
122
226
|
"""
|
|
123
|
-
await tool_registry.export_tools(["
|
|
124
|
-
|
|
227
|
+
await tool_registry.export_tools(["perplexity__answer_with_search"], ToolFormat.LANGCHAIN)
|
|
228
|
+
|
|
229
|
+
response = await tool_registry.call_tool(
|
|
230
|
+
"perplexity__answer_with_search",
|
|
231
|
+
{
|
|
232
|
+
"query": query,
|
|
233
|
+
"model": "sonar",
|
|
234
|
+
"temperature": 1.0,
|
|
235
|
+
"system_prompt": (
|
|
236
|
+
"You are a helpful AI assistant that answers questions using real-time information from the web."
|
|
237
|
+
),
|
|
238
|
+
},
|
|
239
|
+
)
|
|
125
240
|
|
|
126
241
|
# Extract only desired fields
|
|
127
242
|
return {
|
|
128
|
-
"answer": response.get("
|
|
243
|
+
"answer": response.get("content"),
|
|
129
244
|
"citations": response.get("citations", []),
|
|
130
245
|
}
|
|
131
246
|
|
|
132
247
|
return {"search_functions": search_functions, "load_functions": load_functions, "web_search": web_search}
|
|
133
248
|
|
|
134
249
|
|
|
135
|
-
async def get_valid_tools(tool_ids: list[str], registry:
|
|
250
|
+
async def get_valid_tools(tool_ids: list[str], registry: AgentrRegistry) -> tuple[list[str], list[str]]:
|
|
136
251
|
"""For a given list of tool_ids, validates the tools and returns a list of links for the apps that have not been logged in"""
|
|
137
252
|
correct, incorrect = [], []
|
|
138
253
|
connections = await registry.list_connected_apps()
|
|
@@ -173,7 +288,7 @@ async def get_valid_tools(tool_ids: list[str], registry: ToolRegistry) -> tuple[
|
|
|
173
288
|
continue
|
|
174
289
|
if app not in connected_apps and app not in unconnected:
|
|
175
290
|
unconnected.add(app)
|
|
176
|
-
text = registry.
|
|
291
|
+
text = registry.authorise_app(app_id=app)
|
|
177
292
|
start = text.find(":") + 1
|
|
178
293
|
end = text.find(". R", start)
|
|
179
294
|
url = text[start:end].strip()
|
{universal_mcp_agents-0.1.19rc1.dist-info → universal_mcp_agents-0.1.20rc1.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: universal-mcp-agents
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.20rc1
|
|
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
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
universal_mcp/agents/__init__.py,sha256=Rh6vKqpwuZ2joC9nzLFHUI1G7jzbwwC3p0mgpH5qRgo,1112
|
|
2
|
+
universal_mcp/agents/base.py,sha256=wkqa_W2R6sFgjTMXn2bWVfjarHYDsLvGbG8nN-jRp6E,7175
|
|
3
|
+
universal_mcp/agents/cli.py,sha256=bXdpgxsOMjclm1STHJgx10ocX9EebQ11DrxH0p6KMZk,943
|
|
4
|
+
universal_mcp/agents/hil.py,sha256=_5PCK6q0goGm8qylJq44aSp2MadP-yCPvhOJYKqWLMo,3808
|
|
5
|
+
universal_mcp/agents/llm.py,sha256=hVRwjZs3MHl5_3BWedmurs2Jt1oZDfFX0Zj9F8KH7fk,1787
|
|
6
|
+
universal_mcp/agents/react.py,sha256=8XQvJ0HLVgc-K0qn9Ml48WGcgUGuIKtL67HatlT6Da0,3334
|
|
7
|
+
universal_mcp/agents/sandbox.py,sha256=Int2O8JNFPlB8c7gb86KRxlNbuV0zdz5_NCo_GMcCds,2876
|
|
8
|
+
universal_mcp/agents/simple.py,sha256=NSATg5TWzsRNS7V3LFiDG28WSOCIwCdcC1g7NRwg2nM,2095
|
|
9
|
+
universal_mcp/agents/utils.py,sha256=P6W9k6XAOBp6tdjC2VTP4tE0B2M4-b1EDmr-ylJ47Pw,7765
|
|
10
|
+
universal_mcp/agents/bigtool/__init__.py,sha256=mZG8dsaCVyKlm82otxtiTA225GIFLUCUUYPEIPF24uw,2299
|
|
11
|
+
universal_mcp/agents/bigtool/__main__.py,sha256=0i-fbd2yQ90qa8n2nM3luqoJVN9Reh5HZXR5oK7SAck,445
|
|
12
|
+
universal_mcp/agents/bigtool/agent.py,sha256=mtCDNN8WjE2hjJjooDqusmbferKBHeJMHrhXUPUWaVc,252
|
|
13
|
+
universal_mcp/agents/bigtool/context.py,sha256=ny7gd-vvVpUOYAeQbAEUT0A6Vm6Nn2qGywxTzPBzYFg,929
|
|
14
|
+
universal_mcp/agents/bigtool/graph.py,sha256=2Sy0dtevTWeT3hJDq4BDerZFvk_zJqx15j8VH2XLq8Y,5848
|
|
15
|
+
universal_mcp/agents/bigtool/prompts.py,sha256=Joi5mCzZX63aM_6eBrMOKuNRHjTkceVIibSsGBGqhYE,2041
|
|
16
|
+
universal_mcp/agents/bigtool/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
17
|
+
universal_mcp/agents/bigtool/tools.py,sha256=-u80ta6xEaqzEMSzDVe3QZiTZm3YlgLkBD8WTghzClw,6315
|
|
18
|
+
universal_mcp/agents/builder/__main__.py,sha256=VJDJOr-dJJerT53ibh5LVqIsMJ0m0sG2UlzFB784pKw,11680
|
|
19
|
+
universal_mcp/agents/builder/builder.py,sha256=mh3MZpMVB1FE1DWzvMW9NnfiaF145VGn8cJzKSYUlzY,8587
|
|
20
|
+
universal_mcp/agents/builder/helper.py,sha256=8igR1b3Gy_N2u3WxHYKIWzvw7F5BMnfpO2IU74v6vsw,2680
|
|
21
|
+
universal_mcp/agents/builder/prompts.py,sha256=8Xs6uzTUHguDRngVMLak3lkXFkk2VV_uQXaDllzP5cI,4670
|
|
22
|
+
universal_mcp/agents/builder/state.py,sha256=7DeWllxfN-yD6cd9wJ3KIgjO8TctkJvVjAbZT8W_zqk,922
|
|
23
|
+
universal_mcp/agents/codeact0/__init__.py,sha256=8-fvUo1Sm6dURGI-lW-X3Kd78LqySYbb5NMkNJ4NDwg,76
|
|
24
|
+
universal_mcp/agents/codeact0/__main__.py,sha256=_7qSz97YnRgYJTESkALS5_eBIGHiMjA5rhr3IAeBvVo,896
|
|
25
|
+
universal_mcp/agents/codeact0/agent.py,sha256=qUcNniw8DyvEfpEuaWA9LDqDe0eiRPEHrZtysfdKY8k,14238
|
|
26
|
+
universal_mcp/agents/codeact0/config.py,sha256=H-1woj_nhSDwf15F63WYn723y4qlRefXzGxuH81uYF0,2215
|
|
27
|
+
universal_mcp/agents/codeact0/langgraph_agent.py,sha256=8nz2wq-LexImx-l1y9_f81fK72IQetnCeljwgnduNGY,420
|
|
28
|
+
universal_mcp/agents/codeact0/llm_tool.py,sha256=q-hiqkKtjVmpyNceFoRgo7hvKh4HtQf_I1VudRUEPR0,11075
|
|
29
|
+
universal_mcp/agents/codeact0/prompts.py,sha256=IZwiGLYISr_oXeNwhPJLNpE5wYd5zyntEdEUGH21OD8,10720
|
|
30
|
+
universal_mcp/agents/codeact0/sandbox.py,sha256=Xw4tbUV_6haYIZZvteJi6lIYsW6ni_3DCRCOkslTKgM,4459
|
|
31
|
+
universal_mcp/agents/codeact0/state.py,sha256=B1XF5ni9RvN6p5POHkPTm-KjEx5c8wRB7O1EJM8pbSQ,1297
|
|
32
|
+
universal_mcp/agents/codeact0/tools.py,sha256=G580vy-m_BqlHc_j0yvLV5T_2d2G0JrD_eDhvDdJ9JA,13614
|
|
33
|
+
universal_mcp/agents/codeact0/utils.py,sha256=jAZItSd3KGDkY9PquSWRIFCj9N26K9Kt0HKQ_jwvvSQ,15944
|
|
34
|
+
universal_mcp/agents/shared/__main__.py,sha256=XxH5qGDpgFWfq7fwQfgKULXGiUgeTp_YKfcxftuVZq8,1452
|
|
35
|
+
universal_mcp/agents/shared/prompts.py,sha256=yjP3zbbuKi87qCj21qwTTicz8TqtkKgnyGSeEjMu3ho,3761
|
|
36
|
+
universal_mcp/agents/shared/tool_node.py,sha256=DC9F-Ri28Pam0u3sXWNODVgmj9PtAEUb5qP1qOoGgfs,9169
|
|
37
|
+
universal_mcp/applications/filesystem/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
|
+
universal_mcp/applications/filesystem/app.py,sha256=0TRjjm8YnslVRSmfkXI7qQOAlqWlD1eEn8Jm0xBeigs,5561
|
|
39
|
+
universal_mcp/applications/llm/__init__.py,sha256=_XGRxN3O1--ZS5joAsPf8IlI9Qa6negsJrwJ5VJXno0,46
|
|
40
|
+
universal_mcp/applications/llm/app.py,sha256=oqX3byvlFRmeRo4jJJxUBGy-iTDGm2fplMEKA2pcMtw,12743
|
|
41
|
+
universal_mcp/applications/ui/app.py,sha256=c7OkZsO2fRtndgAzAQbKu-1xXRuRp9Kjgml57YD2NR4,9459
|
|
42
|
+
universal_mcp_agents-0.1.20rc1.dist-info/METADATA,sha256=49lAde7iqPxxgwPAb7BZCERlIkajP0EoiiuvtA7hy24,881
|
|
43
|
+
universal_mcp_agents-0.1.20rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
44
|
+
universal_mcp_agents-0.1.20rc1.dist-info/RECORD,,
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
|
|
3
|
-
from langgraph.checkpoint.memory import MemorySaver
|
|
4
|
-
from rich import print
|
|
5
|
-
from universal_mcp.agentr.registry import AgentrRegistry
|
|
6
|
-
|
|
7
|
-
from universal_mcp.agents.codeact.agent import CodeActAgent
|
|
8
|
-
from universal_mcp.agents.utils import messages_to_list
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
async def main():
|
|
12
|
-
memory = MemorySaver()
|
|
13
|
-
agent = CodeActAgent(
|
|
14
|
-
name="CodeAct Agent",
|
|
15
|
-
instructions="Be very concise in your answers.",
|
|
16
|
-
model="anthropic:claude-4-sonnet-20250514",
|
|
17
|
-
tools={"google_mail": ["list_messages"]},
|
|
18
|
-
registry=AgentrRegistry(),
|
|
19
|
-
memory=memory,
|
|
20
|
-
)
|
|
21
|
-
print("Starting agent...")
|
|
22
|
-
# await agent.ainit()
|
|
23
|
-
# await agent.run_interactive()
|
|
24
|
-
# async for event in agent.stream(
|
|
25
|
-
# user_input="Fetch unsubscribe links from my Gmail inbox for promo emails I have received in the last 7 days"
|
|
26
|
-
# ):
|
|
27
|
-
# print(event.content, end="")
|
|
28
|
-
result = await agent.invoke(user_input="Get the 50th fibonacci number")
|
|
29
|
-
print(messages_to_list(result["messages"]))
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if __name__ == "__main__":
|
|
33
|
-
asyncio.run(main())
|