mirror of
https://github.com/neuml/txtai.git
synced 2026-10-12 02:19:52 +00:00
Add support for MCP servers to Agent Framework, closes #898
This commit is contained in:
@@ -34,18 +34,20 @@ def today() -> str:
|
||||
return datetime.today().isoformat()
|
||||
|
||||
agent = Agent(
|
||||
model="hugging-quants/Meta-Llama-3.1-8B-Instruct-AWQ-INT4",
|
||||
tools=[today, wikipedia, arxiv, "websearch"],
|
||||
llm="hugging-quants/Meta-Llama-3.1-8B-Instruct-AWQ-INT4",
|
||||
)
|
||||
```
|
||||
|
||||
## llm
|
||||
## model
|
||||
|
||||
```yaml
|
||||
llm: string|llm instance
|
||||
model: string|llm instance
|
||||
```
|
||||
|
||||
LLM path or LLM pipeline instance. See the [LLM pipeline](../../pipeline/text/llm) for more information.
|
||||
LLM model path or LLM pipeline instance. The `llm` parameter is also supported for backwards compatibility.
|
||||
|
||||
See the [LLM pipeline](../../pipeline/text/llm) for more information.
|
||||
|
||||
## tools
|
||||
|
||||
@@ -83,7 +85,10 @@ A tool instance can be provided. Additionally, the following strings load tools
|
||||
|
||||
| Tool | Description |
|
||||
|:------------|:----------------------------------------------------------|
|
||||
| http.* | HTTP Path to a Model Context Protocol (MCP) server |
|
||||
| python | Runs a Python action |
|
||||
| websearch | Runs a websearch using the built-in websearch tool |
|
||||
| webview | Extracts content from a web page |
|
||||
|
||||
## method
|
||||
|
||||
|
||||
+7
-7
@@ -41,9 +41,9 @@ def today() -> str:
|
||||
return datetime.today().isoformat()
|
||||
|
||||
agent = Agent(
|
||||
model="hugging-quants/Meta-Llama-3.1-8B-Instruct-AWQ-INT4",
|
||||
tools=[today, wikipedia, arxiv, "websearch"],
|
||||
llm="hugging-quants/Meta-Llama-3.1-8B-Instruct-AWQ-INT4",
|
||||
max_iterations=10,
|
||||
max_steps=10,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -86,31 +86,32 @@ from txtai import Agent, LLM
|
||||
llm = LLM("hugging-quants/Meta-Llama-3.1-8B-Instruct-AWQ-INT4")
|
||||
|
||||
websearcher = Agent(
|
||||
model=llm,
|
||||
tools=["websearch"],
|
||||
llm=llm,
|
||||
)
|
||||
|
||||
wikiman = Agent(
|
||||
model=llm,
|
||||
tools=[{
|
||||
"name": "wikipedia",
|
||||
"description": "Searches a Wikipedia database",
|
||||
"provider": "huggingface-hub",
|
||||
"container": "neuml/txtai-wikipedia"
|
||||
}],
|
||||
llm=llm,
|
||||
)
|
||||
|
||||
researcher = Agent(
|
||||
model=llm,
|
||||
tools=[{
|
||||
"name": "arxiv",
|
||||
"description": "Searches a database of scientific papers",
|
||||
"provider": "huggingface-hub",
|
||||
"container": "neuml/txtai-arxiv"
|
||||
}],
|
||||
llm=llm,
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
model=llm,
|
||||
tools=[{
|
||||
"name": "websearcher",
|
||||
"description": "I run web searches, there is no answer a web search can't solve!",
|
||||
@@ -124,8 +125,7 @@ agent = Agent(
|
||||
"description": "I'm a science guy. I search arXiv to get all my answers.",
|
||||
"target": researcher
|
||||
}],
|
||||
llm=llm,
|
||||
max_iterations=10
|
||||
max_steps=10
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ extras["dev"] = [
|
||||
"pylint",
|
||||
]
|
||||
|
||||
extras["agent"] = ["smolagents>=1.13"]
|
||||
extras["agent"] = ["mcpadapt>=0.1.0", "smolagents>=1.13"]
|
||||
|
||||
extras["ann"] = [
|
||||
"annoy>=1.16.3",
|
||||
|
||||
@@ -32,8 +32,8 @@ class ProcessFactory:
|
||||
constructor = CodeAgent
|
||||
|
||||
# Create model backed by LLM pipeline
|
||||
llm = config.pop("llm")
|
||||
llm = PipelineModel(**llm) if isinstance(llm, dict) else PipelineModel(llm)
|
||||
model = config.pop("model", config.pop("llm", None))
|
||||
model = PipelineModel(**model) if isinstance(model, dict) else PipelineModel(model)
|
||||
|
||||
# Create the agent process
|
||||
return constructor(tools=ToolFactory.create(config), model=llm, **config)
|
||||
return constructor(tools=ToolFactory.create(config), model=model, **config)
|
||||
|
||||
@@ -6,7 +6,10 @@ import inspect
|
||||
|
||||
from types import FunctionType, MethodType
|
||||
|
||||
from smolagents import DuckDuckGoSearchTool, Tool, tool as CreateTool
|
||||
import mcpadapt.core
|
||||
|
||||
from mcpadapt.smolagents_adapter import SmolAgentsAdapter
|
||||
from smolagents import DuckDuckGoSearchTool, PythonInterpreterTool, Tool, tool as CreateTool, VisitWebpageTool
|
||||
from transformers.utils import chat_template_utils, TypeHintParsingException
|
||||
|
||||
from ...embeddings import Embeddings
|
||||
@@ -20,7 +23,7 @@ class ToolFactory:
|
||||
"""
|
||||
|
||||
# Default toolkit
|
||||
DEFAULTS = {"websearch": DuckDuckGoSearchTool()}
|
||||
DEFAULTS = {"python": PythonInterpreterTool(), "websearch": DuckDuckGoSearchTool(), "webview": VisitWebpageTool()}
|
||||
|
||||
@staticmethod
|
||||
def create(config):
|
||||
@@ -58,8 +61,14 @@ class ToolFactory:
|
||||
elif isinstance(tool, str) and tool in ToolFactory.DEFAULTS:
|
||||
tool = ToolFactory.DEFAULTS[tool]
|
||||
|
||||
# Support importing MCP tool collections
|
||||
elif isinstance(tool, str) and tool.startswith("http"):
|
||||
tools.extend(mcpadapt.core.MCPAdapt({"url": tool}, SmolAgentsAdapter()).tools())
|
||||
tool = None
|
||||
|
||||
# Add tool
|
||||
tools.append(tool)
|
||||
if tool:
|
||||
tools.append(tool)
|
||||
|
||||
return tools
|
||||
|
||||
|
||||
@@ -6,9 +6,11 @@ import os
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from smolagents import CodeAgent
|
||||
from smolagents import CodeAgent, PythonInterpreterTool
|
||||
|
||||
from txtai.agent import Agent
|
||||
from txtai.embeddings import Embeddings
|
||||
@@ -107,3 +109,23 @@ class TestAgent(unittest.TestCase):
|
||||
|
||||
self.assertIsNotNone(agent)
|
||||
self.assertIsInstance(agent.tools["embeddings1"]("test"), list)
|
||||
|
||||
# pylint: disable=C0115,C0116
|
||||
@patch("mcpadapt.core.MCPAdapt")
|
||||
def testToolsMCP(self, mcp):
|
||||
"""
|
||||
Test adding a MCP tool collection
|
||||
"""
|
||||
|
||||
class MCPAdapt:
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
|
||||
def tools(self):
|
||||
return [PythonInterpreterTool()]
|
||||
|
||||
# Patch MCP adapter for testing
|
||||
mcp.side_effect = MCPAdapt
|
||||
|
||||
agent = Agent(tools=["http://localhost:8000/mcp"], llm="hf-internal-testing/tiny-random-LlamaForCausalLM", max_steps=1)
|
||||
self.assertEqual(len(agent.tools), 2)
|
||||
|
||||
Reference in New Issue
Block a user