universal-mcp-agents 0.1.5__py3-none-any.whl → 0.1.7__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/base.py +1 -2
- universal_mcp/agents/bigtool2/__init__.py +10 -5
- universal_mcp/agents/bigtool2/__main__.py +1 -1
- universal_mcp/agents/bigtool2/agent.py +0 -1
- universal_mcp/agents/bigtool2/graph.py +47 -10
- universal_mcp/agents/bigtool2/prompts.py +7 -4
- universal_mcp/agents/bigtoolcache/__init__.py +2 -2
- universal_mcp/agents/bigtoolcache/__main__.py +1 -1
- universal_mcp/agents/bigtoolcache/agent.py +0 -1
- universal_mcp/agents/bigtoolcache/graph.py +11 -13
- universal_mcp/agents/builder.py +6 -1
- universal_mcp/agents/llm.py +1 -1
- universal_mcp/agents/react.py +4 -5
- universal_mcp/agents/utils.py +0 -10
- universal_mcp/{agents/ui_tools.py → applications/ui/app.py} +3 -3
- {universal_mcp_agents-0.1.5.dist-info → universal_mcp_agents-0.1.7.dist-info}/METADATA +1 -2
- {universal_mcp_agents-0.1.5.dist-info → universal_mcp_agents-0.1.7.dist-info}/RECORD +18 -20
- universal_mcp/agents/autoagent/studio.py +0 -20
- universal_mcp/agents/tools.py +0 -40
- {universal_mcp_agents-0.1.5.dist-info → universal_mcp_agents-0.1.7.dist-info}/WHEEL +0 -0
universal_mcp/agents/base.py
CHANGED
|
@@ -73,7 +73,7 @@ class BaseAgent:
|
|
|
73
73
|
# Ignore intermeddite finish messages
|
|
74
74
|
if "finish_reason" in event.response_metadata:
|
|
75
75
|
# Got LLM finish reason ignore it
|
|
76
|
-
logger.
|
|
76
|
+
logger.error(f"Finish event: {event}, reason: {event.response_metadata['finish_reason']}, Metadata: {metadata}")
|
|
77
77
|
pass
|
|
78
78
|
else:
|
|
79
79
|
logger.debug(f"Event: {event}, Metadata: {metadata}")
|
|
@@ -89,7 +89,6 @@ class BaseAgent:
|
|
|
89
89
|
await self.ainit()
|
|
90
90
|
with self.cli.display_agent_response_streaming(self.name) as stream_updater:
|
|
91
91
|
async for event in self.stream(thread_id, user_input):
|
|
92
|
-
|
|
93
92
|
if isinstance(event.content, list):
|
|
94
93
|
thinking_content = "".join([c.get("thinking", "") for c in event.content])
|
|
95
94
|
stream_updater.update(thinking_content, type_="thinking")
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from langgraph.checkpoint.base import BaseCheckpointSaver
|
|
2
|
-
from universal_mcp.logger import logger
|
|
3
|
-
from universal_mcp.tools.registry import ToolRegistry
|
|
4
2
|
|
|
5
3
|
from universal_mcp.agents.base import BaseAgent
|
|
6
4
|
from universal_mcp.agents.llm import load_chat_model
|
|
7
|
-
from universal_mcp.
|
|
5
|
+
from universal_mcp.logger import logger
|
|
6
|
+
from universal_mcp.tools.registry import ToolRegistry
|
|
7
|
+
from universal_mcp.types import ToolConfig, ToolFormat
|
|
8
8
|
|
|
9
9
|
from .graph import build_graph
|
|
10
10
|
from .prompts import SYSTEM_PROMPT
|
|
@@ -18,6 +18,7 @@ class BigToolAgent2(BaseAgent):
|
|
|
18
18
|
model: str,
|
|
19
19
|
registry: ToolRegistry,
|
|
20
20
|
memory: BaseCheckpointSaver | None = None,
|
|
21
|
+
tools: ToolConfig | None = None,
|
|
21
22
|
**kwargs,
|
|
22
23
|
):
|
|
23
24
|
super().__init__(name, instructions, model, memory, **kwargs)
|
|
@@ -25,7 +26,10 @@ class BigToolAgent2(BaseAgent):
|
|
|
25
26
|
self.registry = registry
|
|
26
27
|
self.llm = load_chat_model(self.model)
|
|
27
28
|
self.recursion_limit = kwargs.get("recursion_limit", 10)
|
|
28
|
-
self.
|
|
29
|
+
self.tools = tools or {}
|
|
30
|
+
if "ui" not in self.tools:
|
|
31
|
+
# self.tools["ui"] = ["create_bar_chart", "create_line_chart", "create_pie_chart", "create_table", "http_get", "http_post", "http_put", "http_delete", "http_patch", "read_file"]
|
|
32
|
+
self.tools["ui"] = ["create_table"]
|
|
29
33
|
|
|
30
34
|
logger.info(
|
|
31
35
|
f"BigToolAgent '{self.name}' initialized with model '{self.model}'."
|
|
@@ -41,11 +45,12 @@ class BigToolAgent2(BaseAgent):
|
|
|
41
45
|
"""Build the bigtool agent graph using the existing create_agent function."""
|
|
42
46
|
logger.info(f"Building graph for BigToolAgent '{self.name}'...")
|
|
43
47
|
try:
|
|
48
|
+
default_tools = await self.registry.export_tools(self.tools, ToolFormat.LANGCHAIN)
|
|
44
49
|
graph_builder = build_graph(
|
|
45
50
|
tool_registry=self.registry,
|
|
46
51
|
llm=self.llm,
|
|
47
52
|
system_prompt=self._build_system_message(),
|
|
48
|
-
|
|
53
|
+
default_tools=default_tools,
|
|
49
54
|
)
|
|
50
55
|
|
|
51
56
|
compiled_graph = graph_builder.compile(checkpointer=self.memory)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
|
|
3
3
|
from loguru import logger
|
|
4
|
-
from universal_mcp.agentr.registry import AgentrRegistry
|
|
5
4
|
|
|
5
|
+
from universal_mcp.agentr.registry import AgentrRegistry
|
|
6
6
|
from universal_mcp.agents.bigtool2 import BigToolAgent2
|
|
7
7
|
from universal_mcp.agents.utils import messages_to_list
|
|
8
8
|
|
|
@@ -4,18 +4,18 @@ from typing import Literal, cast
|
|
|
4
4
|
|
|
5
5
|
from langchain_core.language_models import BaseChatModel
|
|
6
6
|
from langchain_core.messages import AIMessage, ToolMessage
|
|
7
|
-
from langchain_core.tools import tool
|
|
7
|
+
from langchain_core.tools import BaseTool, tool
|
|
8
8
|
from langgraph.graph import StateGraph
|
|
9
9
|
from langgraph.types import Command
|
|
10
|
+
|
|
11
|
+
from universal_mcp.agents.bigtool2.state import State
|
|
10
12
|
from universal_mcp.logger import logger
|
|
11
13
|
from universal_mcp.tools.registry import ToolRegistry
|
|
12
14
|
from universal_mcp.types import ToolFormat
|
|
13
15
|
|
|
14
|
-
from universal_mcp.agents.bigtool2.state import State
|
|
15
|
-
|
|
16
16
|
|
|
17
17
|
def build_graph(
|
|
18
|
-
tool_registry: ToolRegistry, llm: BaseChatModel, system_prompt: str,
|
|
18
|
+
tool_registry: ToolRegistry, llm: BaseChatModel, system_prompt: str, default_tools: list[BaseTool]
|
|
19
19
|
):
|
|
20
20
|
@tool
|
|
21
21
|
async def search_tools(queries: list[str]) -> str:
|
|
@@ -36,17 +36,18 @@ def build_graph(
|
|
|
36
36
|
]
|
|
37
37
|
app_tools = {}
|
|
38
38
|
for task_query in queries:
|
|
39
|
-
|
|
39
|
+
apps_list = await tool_registry.search_apps(task_query, limit=5)
|
|
40
|
+
tools_list = []
|
|
41
|
+
for app in apps_list:
|
|
42
|
+
tools_list.extend(await tool_registry.search_tools(task_query, limit=5, app_id=app["id"]))
|
|
40
43
|
tool_candidates = [
|
|
41
44
|
f"{tool['id']}: {tool['description']}" for tool in tools_list
|
|
42
45
|
]
|
|
43
46
|
for tool in tool_candidates:
|
|
44
47
|
app = tool.split("__")[0]
|
|
45
48
|
if app not in app_tools:
|
|
46
|
-
if len(app_tools.keys()) >= 10:
|
|
47
|
-
break
|
|
48
49
|
app_tools[app] = []
|
|
49
|
-
if len(app_tools[app]) <
|
|
50
|
+
if len(app_tools[app]) < 5:
|
|
50
51
|
app_tools[app].append(tool)
|
|
51
52
|
for app in app_tools:
|
|
52
53
|
app_status = "connected" if app in connected_apps else "NOT connected"
|
|
@@ -64,9 +65,19 @@ def build_graph(
|
|
|
64
65
|
|
|
65
66
|
@tool
|
|
66
67
|
async def load_tools(tool_ids: list[str]) -> list[str]:
|
|
67
|
-
"""Load the tools for the given tool ids. Returns the tool ids."""
|
|
68
|
+
"""Load the tools for the given tool ids. Returns the tool ids after loading them. Note that tool ids are the complete tool ids, with both the app name and the tool name separated by double underscore (__). e.g. google_mail__send_email"""
|
|
68
69
|
return tool_ids
|
|
69
70
|
|
|
71
|
+
@tool
|
|
72
|
+
async def web_search(query: str) -> str:
|
|
73
|
+
"""Search the web for the given query. Returns the search results."""
|
|
74
|
+
tool = await tool_registry.export_tools(
|
|
75
|
+
["exa__search_with_filters"], ToolFormat.LANGCHAIN
|
|
76
|
+
)
|
|
77
|
+
response = await tool_registry.call_tool("exa__search_with_filters", {"query": query, "contents": {"summary": True}})
|
|
78
|
+
return response
|
|
79
|
+
|
|
80
|
+
|
|
70
81
|
async def call_model(
|
|
71
82
|
state: State,
|
|
72
83
|
) -> Command[Literal["select_tools", "call_tools"]]:
|
|
@@ -91,8 +102,17 @@ def build_graph(
|
|
|
91
102
|
|
|
92
103
|
model = llm
|
|
93
104
|
|
|
105
|
+
tools = [search_tools, load_tools, web_search, *default_tools, *selected_tools]
|
|
106
|
+
# Remove duplicates based on tool name
|
|
107
|
+
seen_names = set()
|
|
108
|
+
unique_tools = []
|
|
109
|
+
for tool in tools:
|
|
110
|
+
if tool.name not in seen_names:
|
|
111
|
+
seen_names.add(tool.name)
|
|
112
|
+
unique_tools.append(tool)
|
|
113
|
+
tools = unique_tools
|
|
94
114
|
model_with_tools = model.bind_tools(
|
|
95
|
-
|
|
115
|
+
tools,
|
|
96
116
|
tool_choice="auto",
|
|
97
117
|
)
|
|
98
118
|
response = cast(AIMessage, await model_with_tools.ainvoke(messages))
|
|
@@ -124,6 +144,23 @@ def build_graph(
|
|
|
124
144
|
},
|
|
125
145
|
)
|
|
126
146
|
|
|
147
|
+
elif tool_call["name"] == web_search.name:
|
|
148
|
+
logger.info(f"Tool '{tool_call['name']}' is a web search tool. Proceeding to call.")
|
|
149
|
+
web_search_result = await web_search.ainvoke(input=tool_call["args"])
|
|
150
|
+
tool_msg = ToolMessage(
|
|
151
|
+
f"Web search result: {web_search_result}", tool_call_id=tool_call["id"]
|
|
152
|
+
)
|
|
153
|
+
return Command(goto="call_model", update={"messages": [response, tool_msg]})
|
|
154
|
+
|
|
155
|
+
elif "ui_tools" in tool_call["name"]:
|
|
156
|
+
logger.info(f"Tool '{tool_call['name']}' is a UI tool. Proceeding to call.")
|
|
157
|
+
ui_tool_result = await ui_tools_dict[tool_call["name"]].ainvoke(input=tool_call["args"])
|
|
158
|
+
tool_msg = ToolMessage(
|
|
159
|
+
f"UI tool result: {ui_tool_result}", tool_call_id=tool_call["id"]
|
|
160
|
+
)
|
|
161
|
+
return Command(goto="call_model", update={"messages": [response, tool_msg]})
|
|
162
|
+
|
|
163
|
+
|
|
127
164
|
elif tool_call["name"] not in state["selected_tool_ids"]:
|
|
128
165
|
try:
|
|
129
166
|
await tool_registry.export_tools(
|
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
SYSTEM_PROMPT = """You are a helpful AI assistant.
|
|
4
4
|
|
|
5
5
|
**Core Directives:**
|
|
6
|
-
1. **Always Use Tools for Tasks:** For any user request that requires an action (e.g., sending an email, searching for information, creating an event), you MUST use a tool. Do not
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
1. **Always Use Tools for Tasks:** For any user request that requires an action (e.g., sending an email, searching for information, creating an event, displaying a chart), you MUST use a tool. Do not refuse a task if a tool might exist for it.
|
|
7
|
+
|
|
8
|
+
2. Check if your existing tools or knowledge can handle the user's request. If they can, use them. If they cannot, you must call the `search_tools` function to find the right tools for the user's request.You must not use the same/similar query multiple times in the list. The list should have multiple queries only if the task has clearly different sub-tasks. If you do not find any specific relevant tools, use the pre-loaded generic tools.
|
|
9
|
+
|
|
10
|
+
3. **Load Tools:** After looking at the output of `search_tools`, you MUST call the `load_tools` function to load only the tools you want to use. Provide the full tool ids, not just the app names. Use your judgement to eliminate irrelevant apps that came up just because of semantic similarity. However, sometimes, multiple apps might be relevant for the same task. Prefer connected apps over unconnected apps while breaking a tie. If more than one relevant app (or none of the relevant apps) are connected, you must ask the user to choose the app. In case the user asks you to use an app that is not connected, call the apps tools normally. The tool will return a link for connecting that you should pass on to the user.
|
|
11
|
+
|
|
12
|
+
4. **Strictly Follow the Process:** Your only job in your first turn is to analyze the user's request and answer using existing tools/knowledge or `search_tools` with a concise query describing the core task. Do not engage in conversation, or extend the conversation beyond the user's request.
|
|
10
13
|
|
|
11
14
|
{instructions}
|
|
12
15
|
"""
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from langgraph.checkpoint.base import BaseCheckpointSaver
|
|
2
|
-
from universal_mcp.logger import logger
|
|
3
|
-
from universal_mcp.tools.registry import ToolRegistry
|
|
4
2
|
|
|
5
3
|
from universal_mcp.agents.base import BaseAgent
|
|
6
4
|
from universal_mcp.agents.llm import load_chat_model
|
|
5
|
+
from universal_mcp.logger import logger
|
|
6
|
+
from universal_mcp.tools.registry import ToolRegistry
|
|
7
7
|
|
|
8
8
|
from .graph import build_graph
|
|
9
9
|
from .prompts import SYSTEM_PROMPT
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from datetime import UTC, datetime
|
|
3
|
-
from typing import Literal, TypedDict, cast
|
|
3
|
+
from typing import Any, Literal, TypedDict, cast
|
|
4
4
|
|
|
5
5
|
from langchain_anthropic import ChatAnthropic
|
|
6
6
|
from langchain_core.language_models import BaseChatModel
|
|
@@ -11,12 +11,11 @@ from langgraph.runtime import Runtime
|
|
|
11
11
|
from langgraph.types import Command
|
|
12
12
|
|
|
13
13
|
from universal_mcp.agents.bigtoolcache.context import Context
|
|
14
|
+
from universal_mcp.agents.bigtoolcache.prompts import TOOLS_LIST
|
|
14
15
|
from universal_mcp.agents.bigtoolcache.state import State
|
|
15
16
|
from universal_mcp.logger import logger
|
|
16
17
|
from universal_mcp.tools.registry import ToolRegistry
|
|
17
18
|
from universal_mcp.types import ToolFormat
|
|
18
|
-
from universal_mcp.agents.bigtoolcache.prompts import TOOLS_LIST
|
|
19
|
-
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class ToolSelectionOutput(TypedDict):
|
|
@@ -180,16 +179,15 @@ def build_graph(tool_registry: ToolRegistry, llm: BaseChatModel):
|
|
|
180
179
|
content=json.dumps(tool_result),
|
|
181
180
|
name=tool_id,
|
|
182
181
|
tool_call_id=tool_call["id"],
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
)
|
|
182
|
+
))
|
|
183
|
+
recent_tool_ids.append(tool_call["name"])
|
|
184
|
+
except Exception as e:
|
|
185
|
+
logger.error(f"Error executing tool '{tool_call['name']}': {e}")
|
|
186
|
+
outputs.append(
|
|
187
|
+
ToolMessage(
|
|
188
|
+
content=json.dumps("Error: " + str(e)),
|
|
189
|
+
name=tool_call["name"],
|
|
190
|
+
tool_call_id=tool_call["id"],
|
|
193
191
|
)
|
|
194
192
|
)
|
|
195
193
|
return Command(
|
universal_mcp/agents/builder.py
CHANGED
|
@@ -14,6 +14,7 @@ from universal_mcp.types import ToolConfig
|
|
|
14
14
|
from universal_mcp.agents.base import BaseAgent
|
|
15
15
|
from universal_mcp.agents.llm import load_chat_model
|
|
16
16
|
from universal_mcp.agents.shared.tool_node import build_tool_node_graph
|
|
17
|
+
from universal_mcp.agents.utils import messages_to_list
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
class Agent(BaseModel):
|
|
@@ -179,9 +180,13 @@ async def main():
|
|
|
179
180
|
model="gemini/gemini-1.5-pro",
|
|
180
181
|
registry=registry,
|
|
181
182
|
)
|
|
182
|
-
await agent.invoke(
|
|
183
|
+
result = await agent.invoke(
|
|
183
184
|
"Send a daily email to manoj@agentr.dev with daily agenda of the day",
|
|
184
185
|
)
|
|
186
|
+
from rich import print
|
|
187
|
+
print(messages_to_list(result["messages"]))
|
|
188
|
+
print(result["generated_agent"])
|
|
189
|
+
print(result["tool_config"])
|
|
185
190
|
|
|
186
191
|
|
|
187
192
|
if __name__ == "__main__":
|
universal_mcp/agents/llm.py
CHANGED
|
@@ -8,7 +8,7 @@ from langchain_openai import AzureChatOpenAI
|
|
|
8
8
|
|
|
9
9
|
@lru_cache(maxsize=8)
|
|
10
10
|
def load_chat_model(
|
|
11
|
-
fully_specified_name: str, temperature: float = 1.0, tags: list[str] | None = None, thinking: bool =
|
|
11
|
+
fully_specified_name: str, temperature: float = 1.0, tags: list[str] | None = None, thinking: bool = False
|
|
12
12
|
) -> BaseChatModel:
|
|
13
13
|
"""Load a chat model from a fully specified name.
|
|
14
14
|
Args:
|
universal_mcp/agents/react.py
CHANGED
|
@@ -7,7 +7,7 @@ from universal_mcp.types import ToolConfig, ToolFormat
|
|
|
7
7
|
|
|
8
8
|
from universal_mcp.agents.base import BaseAgent
|
|
9
9
|
from universal_mcp.agents.llm import load_chat_model
|
|
10
|
-
from universal_mcp.agents.utils import
|
|
10
|
+
from universal_mcp.agents.utils import messages_to_list
|
|
11
11
|
|
|
12
12
|
DEVELOPER_PROMPT = """You are {name}.
|
|
13
13
|
|
|
@@ -38,8 +38,9 @@ class ReactAgent(BaseAgent):
|
|
|
38
38
|
):
|
|
39
39
|
super().__init__(name, instructions, model, memory, **kwargs)
|
|
40
40
|
self.llm = load_chat_model(model)
|
|
41
|
-
self.tools = tools
|
|
42
|
-
self.
|
|
41
|
+
self.tools = tools or {}
|
|
42
|
+
if "ui" not in self.tools:
|
|
43
|
+
self.tools["ui"] = ["create_bar_chart", "create_line_chart", "create_pie_chart", "create_table", "http_get", "http_post", "http_put", "http_delete", "http_patch", "read_file"]
|
|
43
44
|
self.max_iterations = max_iterations
|
|
44
45
|
self.registry = registry
|
|
45
46
|
|
|
@@ -48,13 +49,11 @@ class ReactAgent(BaseAgent):
|
|
|
48
49
|
if self.tools:
|
|
49
50
|
if not self.registry:
|
|
50
51
|
raise ValueError("Tools are configured but no registry is provided")
|
|
51
|
-
|
|
52
52
|
tools = await self.registry.export_tools(self.tools, ToolFormat.LANGCHAIN)
|
|
53
53
|
logger.debug(tools)
|
|
54
54
|
else:
|
|
55
55
|
tools = []
|
|
56
56
|
|
|
57
|
-
tools.extend(self.ui_tools)
|
|
58
57
|
|
|
59
58
|
logger.debug(f"Initialized ReactAgent: name={self.name}, model={self.model}")
|
|
60
59
|
return create_react_agent(
|
universal_mcp/agents/utils.py
CHANGED
|
@@ -11,7 +11,6 @@ from rich.table import Table
|
|
|
11
11
|
from universal_mcp.tools.manager import ToolManager
|
|
12
12
|
from universal_mcp.types import ToolFormat
|
|
13
13
|
|
|
14
|
-
from universal_mcp.agents.ui_tools import UIToolsApp
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
class RichCLI:
|
|
@@ -138,12 +137,3 @@ Available commands:
|
|
|
138
137
|
|
|
139
138
|
def messages_to_list(messages: list[BaseMessage]):
|
|
140
139
|
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()
|
|
@@ -28,12 +28,12 @@ class ColumnDefinition(TypedDict):
|
|
|
28
28
|
type: Literal["string", "number", "date", "boolean"] | None
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
class
|
|
31
|
+
class UiApp(BaseApplication):
|
|
32
32
|
"""An application for creating UI tools"""
|
|
33
33
|
|
|
34
|
-
def __init__(self):
|
|
34
|
+
def __init__(self, **kwargs):
|
|
35
35
|
"""Initialize the DefaultToolsApp"""
|
|
36
|
-
super().__init__(name="
|
|
36
|
+
super().__init__(name="ui")
|
|
37
37
|
self.markitdown = MarkItDown(enable_plugins=True)
|
|
38
38
|
|
|
39
39
|
def create_bar_chart(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: universal-mcp-agents
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
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,7 +11,6 @@ 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.4
|
|
15
14
|
Requires-Dist: universal-mcp>=0.1.24rc17
|
|
16
15
|
Provides-Extra: dev
|
|
17
16
|
Requires-Dist: pre-commit; extra == 'dev'
|
|
@@ -1,38 +1,35 @@
|
|
|
1
1
|
universal_mcp/agents/__init__.py,sha256=QfYDUZxIYQSqbpGt6NZ3U5tjf7SS1Y9uPzAwmaRoDrA,1186
|
|
2
|
-
universal_mcp/agents/base.py,sha256=
|
|
3
|
-
universal_mcp/agents/builder.py,sha256=
|
|
2
|
+
universal_mcp/agents/base.py,sha256=h_FDAclpFKpaMCSNhBcwIMF0DLbZtyyoy_l71UxY4Aw,6892
|
|
3
|
+
universal_mcp/agents/builder.py,sha256=4RTROLljLzF4S3qrQrkl_mS3EipBBvqnvJflJ45oYCs,7850
|
|
4
4
|
universal_mcp/agents/cli.py,sha256=_rJV6TxBG2amH3o8mVs4pxViaTfkBhz6n5l6xhv4Z3g,1014
|
|
5
5
|
universal_mcp/agents/hil.py,sha256=XfQT8QcuDbiIpUU9N4WSbO2Tm9YNSuwRqyCTWmCWaZo,3818
|
|
6
|
-
universal_mcp/agents/llm.py,sha256=
|
|
7
|
-
universal_mcp/agents/react.py,sha256=
|
|
6
|
+
universal_mcp/agents/llm.py,sha256=gnyCYW8Ohax8S9CXIfeI7hoBYNO0fa_1hJkIabCGoKY,1788
|
|
7
|
+
universal_mcp/agents/react.py,sha256=jH42VFAB-BuPUVpaMIspBjjukYEJan-DQxtNamD1o0I,3010
|
|
8
8
|
universal_mcp/agents/simple.py,sha256=Z5Ja12vJIhIHhB68WWH_5opln7FMDUiRfztKOj2Rx-U,1941
|
|
9
|
-
universal_mcp/agents/
|
|
10
|
-
universal_mcp/agents/ui_tools.py,sha256=rNSXRHminXKvwGZISZ58qpnHQ8c6gPanXbu1icBXGFY,11224
|
|
11
|
-
universal_mcp/agents/utils.py,sha256=bEQvI-dNo4sOj1te3ARmWnDSg9nFccfLiJ4baXEutoA,5323
|
|
9
|
+
universal_mcp/agents/utils.py,sha256=g_v7IEKtx6CBQK-Nue_weVVie62KQLQjz7izU3kOWPQ,4988
|
|
12
10
|
universal_mcp/agents/autoagent/__init__.py,sha256=fDiruZjxHhGPa6gg88as0SKHV8c3Mq56CCshZDIcLt8,836
|
|
13
11
|
universal_mcp/agents/autoagent/__main__.py,sha256=S_inq-PR6KgJqcDhoXp_-PCehORF6WGputQ_hTrJOl0,654
|
|
14
12
|
universal_mcp/agents/autoagent/context.py,sha256=RgjW1uCslucxYJpdmi4govd-0V1_9e6Y_kjWl3FpLrE,847
|
|
15
13
|
universal_mcp/agents/autoagent/graph.py,sha256=JKdQy21w5jXyjyICTrhKS4MXHth6kHzREhR-DCU3Dws,6928
|
|
16
14
|
universal_mcp/agents/autoagent/prompts.py,sha256=v-EwzZ_0XPuBNd_r8aWxmKMSQlZLTVBr0o-dmTQMN1w,892
|
|
17
15
|
universal_mcp/agents/autoagent/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
18
|
-
universal_mcp/agents/autoagent/studio.py,sha256=ZxiC9C2xdOhZ4Qb5fKoAci3TOhcdKlpiTT_5C3CF_AI,639
|
|
19
16
|
universal_mcp/agents/autoagent/utils.py,sha256=AFq-8scw_WlSZxDnTzxSNrOSiGYsIlqkqtQLDWf_rMU,431
|
|
20
17
|
universal_mcp/agents/bigtool/__init__.py,sha256=Qw2C29q6R7TXmpzlSStwYM9Rbv9Iguj7U0p0CPy7thY,1782
|
|
21
18
|
universal_mcp/agents/bigtool/__main__.py,sha256=WkPJl8r7L0CZXoFCU8w7eFEejLI8KIflkWnvLFt8jdA,660
|
|
22
19
|
universal_mcp/agents/bigtool/graph.py,sha256=JAw7waUrAA7t6ZpbPcbnSu3sh6MhYfIUkJJfYc9mHCc,8528
|
|
23
20
|
universal_mcp/agents/bigtool/prompts.py,sha256=pzLNaLg5ftv8B8k7McpDrSkos0N5eR6rKcw5psudBFg,1662
|
|
24
21
|
universal_mcp/agents/bigtool/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
25
|
-
universal_mcp/agents/bigtool2/__init__.py,sha256=
|
|
26
|
-
universal_mcp/agents/bigtool2/__main__.py,sha256=
|
|
27
|
-
universal_mcp/agents/bigtool2/agent.py,sha256=
|
|
28
|
-
universal_mcp/agents/bigtool2/graph.py,sha256=
|
|
29
|
-
universal_mcp/agents/bigtool2/prompts.py,sha256=
|
|
22
|
+
universal_mcp/agents/bigtool2/__init__.py,sha256=wkhjOeAHhIpuciLTbKZT3J2uPIJ0KFZpCDn0xX2plNs,2421
|
|
23
|
+
universal_mcp/agents/bigtool2/__main__.py,sha256=SAHfoLqDEhUj3dF3vSzfetCzPGMC3UPJxBySHujSrDY,669
|
|
24
|
+
universal_mcp/agents/bigtool2/agent.py,sha256=ef9IIxgJmr26eYWQdazrIA-IXHGRwT0XNyPThJR55Tk,436
|
|
25
|
+
universal_mcp/agents/bigtool2/graph.py,sha256=GrFYoV2KDyUuutbiS4xrLk6V-x5LftGenZRuTSLRL30,11126
|
|
26
|
+
universal_mcp/agents/bigtool2/prompts.py,sha256=rQFtZDkwU9z8d4PWdt6jpohGhyab658Xvk8hvNVBFBA,1843
|
|
30
27
|
universal_mcp/agents/bigtool2/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
31
|
-
universal_mcp/agents/bigtoolcache/__init__.py,sha256=
|
|
32
|
-
universal_mcp/agents/bigtoolcache/__main__.py,sha256=
|
|
33
|
-
universal_mcp/agents/bigtoolcache/agent.py,sha256=
|
|
28
|
+
universal_mcp/agents/bigtoolcache/__init__.py,sha256=YY7X8-XQ3AC2t_Y9MN9dZk5wTPu7iU6YS8Yhn_akgC0,1844
|
|
29
|
+
universal_mcp/agents/bigtoolcache/__main__.py,sha256=HkPEQqsdnWtDzWSbYdVBBc_JhpRi82TYuaubxNMtt4w,622
|
|
30
|
+
universal_mcp/agents/bigtoolcache/agent.py,sha256=GdIT7RZQ6SCIMrNUs4amZijBQk8d6YVh1fiYzLcUyO8,460
|
|
34
31
|
universal_mcp/agents/bigtoolcache/context.py,sha256=ny7gd-vvVpUOYAeQbAEUT0A6Vm6Nn2qGywxTzPBzYFg,929
|
|
35
|
-
universal_mcp/agents/bigtoolcache/graph.py,sha256=
|
|
32
|
+
universal_mcp/agents/bigtoolcache/graph.py,sha256=9BrHPEl7oUPvVy_gIQ3ewwK4oz9-0yElR2G8yAsaLA8,8645
|
|
36
33
|
universal_mcp/agents/bigtoolcache/prompts.py,sha256=XDU2uJWzwGwt8t3zGjOH16YIrHJCdPuLP5lyJ2llXFg,3226
|
|
37
34
|
universal_mcp/agents/bigtoolcache/state.py,sha256=TQeGZD99okclkoCh5oz-VYIlEsC9yLQyDpnBnm7QCN8,759
|
|
38
35
|
universal_mcp/agents/bigtoolcache/tools_all.txt,sha256=g52i00AOh9VTDsAtIAF8vhqtTHQVmzTn61k724niEA0,95408
|
|
@@ -47,6 +44,7 @@ universal_mcp/agents/planner/graph.py,sha256=qTXUVXiPWZP73GsY9mQEGmBtA-C1t06jpzg
|
|
|
47
44
|
universal_mcp/agents/planner/prompts.py,sha256=_JoHqiAvswtqCDu90AGUHmfsu8eWE1-_yI4LLn3pqMU,657
|
|
48
45
|
universal_mcp/agents/planner/state.py,sha256=qqyp-jSGsCxe1US-PRLT4-y1sITAcVE6nCMlQLnvop0,278
|
|
49
46
|
universal_mcp/agents/shared/tool_node.py,sha256=FiKY0AhxKIFpzGKGnyRL-6Dzuf0KUDmiQo7IhXmE27s,8861
|
|
50
|
-
|
|
51
|
-
universal_mcp_agents-0.1.
|
|
52
|
-
universal_mcp_agents-0.1.
|
|
47
|
+
universal_mcp/applications/ui/app.py,sha256=y1DcnX1Vg-d1cBtEP0_jUOR2ypbB0X7q4YiQNAg9WdY,11223
|
|
48
|
+
universal_mcp_agents-0.1.7.dist-info/METADATA,sha256=ZIkbodKsCGXwZ3iWEbJ9i5jpZ0F6xrLtlLu-jhgjYPo,798
|
|
49
|
+
universal_mcp_agents-0.1.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
50
|
+
universal_mcp_agents-0.1.7.dist-info/RECORD,,
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
|
|
3
|
-
from universal_mcp.agentr.registry import AgentrRegistry
|
|
4
|
-
from universal_mcp.tools import ToolManager
|
|
5
|
-
|
|
6
|
-
from universal_mcp.agents.autoagent import build_graph
|
|
7
|
-
|
|
8
|
-
tool_registry = AgentrRegistry()
|
|
9
|
-
tool_manager = ToolManager()
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
async def main():
|
|
13
|
-
instructions = """
|
|
14
|
-
You are a helpful assistant that can use tools to help the user. If a task requires multiple steps, you should perform separate different searches for different actions. Prefer completing one action before searching for another.
|
|
15
|
-
"""
|
|
16
|
-
graph = await build_graph(tool_registry, instructions=instructions)
|
|
17
|
-
return graph
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
graph = asyncio.run(main())
|
universal_mcp/agents/tools.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
|
|
3
|
-
from langchain_mcp_adapters.client import MultiServerMCPClient
|
|
4
|
-
from universal_mcp.agentr.integration import AgentrIntegration
|
|
5
|
-
from universal_mcp.applications.utils import app_from_slug
|
|
6
|
-
from universal_mcp.tools.adapters import ToolFormat
|
|
7
|
-
from universal_mcp.tools.manager import ToolManager
|
|
8
|
-
from universal_mcp.types import ToolConfig
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
async def load_agentr_tools(agentr_servers: dict):
|
|
12
|
-
tool_manager = ToolManager()
|
|
13
|
-
for app_name, tool_names in agentr_servers.items():
|
|
14
|
-
app = app_from_slug(app_name)
|
|
15
|
-
integration = AgentrIntegration(name=app_name)
|
|
16
|
-
app_instance = app(integration=integration)
|
|
17
|
-
tool_manager.register_tools_from_app(
|
|
18
|
-
app_instance, tool_names=tool_names["tools"]
|
|
19
|
-
)
|
|
20
|
-
tools = tool_manager.list_tools(format=ToolFormat.LANGCHAIN)
|
|
21
|
-
return tools
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
async def load_mcp_tools(mcp_servers: dict):
|
|
25
|
-
client = MultiServerMCPClient(mcp_servers)
|
|
26
|
-
tools = await client.get_tools()
|
|
27
|
-
return tools
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
async def load_tools(path: str) -> ToolConfig:
|
|
31
|
-
with open(path) as f:
|
|
32
|
-
data = json.load(f)
|
|
33
|
-
config = ToolConfig.model_validate(data)
|
|
34
|
-
agentr_tools = await load_agentr_tools(
|
|
35
|
-
config.model_dump(exclude_none=True)["agentrServers"]
|
|
36
|
-
)
|
|
37
|
-
mcp_tools = await load_mcp_tools(
|
|
38
|
-
config.model_dump(exclude_none=True)["mcpServers"]
|
|
39
|
-
)
|
|
40
|
-
return agentr_tools + mcp_tools
|
|
File without changes
|