mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-26 15:34:18 +02:00
Decorators return functions instead of component objects (#2856)
This commit is contained in:
parent
766641a1a5
commit
1b723f302d
38 changed files with 2406 additions and 1606 deletions
|
|
@ -21,7 +21,8 @@ from pydantic import AnyUrl, BaseModel
|
|||
from fastmcp import Context, FastMCP
|
||||
from fastmcp.client.client import CallToolResult, Client
|
||||
from fastmcp.client.transports import FastMCPTransport
|
||||
from fastmcp.prompts.prompt import FunctionPrompt, Message, Prompt
|
||||
from fastmcp.prompts.function_prompt import FunctionPrompt
|
||||
from fastmcp.prompts.prompt import Message, Prompt
|
||||
from fastmcp.resources.resource import Resource
|
||||
from fastmcp.server.middleware.caching import (
|
||||
CachableToolResult,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ from fastmcp.server.middleware.tool_injection import (
|
|||
ResourceToolMiddleware,
|
||||
ToolInjectionMiddleware,
|
||||
)
|
||||
from fastmcp.tools.tool import FunctionTool, Tool
|
||||
from fastmcp.tools.function_tool import FunctionTool
|
||||
from fastmcp.tools.tool import Tool
|
||||
|
||||
|
||||
def multiply_fn(a: int, b: int) -> int:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ from mcp.types import TextContent
|
|||
|
||||
from fastmcp import Client, Context, FastMCP
|
||||
from fastmcp.exceptions import NotFoundError
|
||||
from fastmcp.prompts.prompt import FunctionPrompt, Prompt
|
||||
from fastmcp.prompts.prompt import Prompt
|
||||
|
||||
|
||||
class TestPromptContext:
|
||||
|
|
@ -247,6 +247,10 @@ class TestPromptDecorator:
|
|||
|
||||
async def test_prompt_direct_function_call(self):
|
||||
"""Test that prompts can be registered via direct function call."""
|
||||
from typing import cast
|
||||
|
||||
from fastmcp.prompts.function_prompt import DecoratedPrompt
|
||||
|
||||
mcp = FastMCP()
|
||||
|
||||
def standalone_function() -> str:
|
||||
|
|
@ -255,11 +259,16 @@ class TestPromptDecorator:
|
|||
|
||||
result_fn = mcp.prompt(standalone_function, name="direct_call_prompt")
|
||||
|
||||
assert isinstance(result_fn, FunctionPrompt)
|
||||
# In new decorator mode, returns the function with metadata
|
||||
decorated = cast(DecoratedPrompt, result_fn)
|
||||
assert hasattr(result_fn, "__fastmcp__")
|
||||
assert decorated.__fastmcp__.name == "direct_call_prompt"
|
||||
assert result_fn is standalone_function
|
||||
|
||||
prompts = await mcp.get_prompts()
|
||||
prompt = next(p for p in prompts if p.name == "direct_call_prompt")
|
||||
assert prompt is result_fn
|
||||
# Prompt is registered separately, not same object as decorated function
|
||||
assert prompt.name == "direct_call_prompt"
|
||||
|
||||
result = await mcp.render_prompt("direct_call_prompt")
|
||||
assert len(result.messages) == 1
|
||||
|
|
|
|||
|
|
@ -793,6 +793,10 @@ class TestToolOutputSchema:
|
|||
assert result.structured_content is None
|
||||
|
||||
async def test_manual_structured_content(self):
|
||||
from typing import cast
|
||||
|
||||
from fastmcp.tools.function_tool import DecoratedTool
|
||||
|
||||
mcp = FastMCP()
|
||||
|
||||
@mcp.tool
|
||||
|
|
@ -801,7 +805,12 @@ class TestToolOutputSchema:
|
|||
content="Hello, world!", structured_content={"message": "Hello, world!"}
|
||||
)
|
||||
|
||||
assert f.output_schema is None
|
||||
# In new decorator mode, check metadata instead of attributes
|
||||
from fastmcp.utilities.types import NotSet
|
||||
|
||||
decorated = cast(DecoratedTool, f)
|
||||
assert hasattr(f, "__fastmcp__")
|
||||
assert decorated.__fastmcp__.output_schema is NotSet
|
||||
|
||||
result = await mcp.call_tool("f", {})
|
||||
assert isinstance(result.content, list)
|
||||
|
|
@ -1312,7 +1321,9 @@ class TestToolDecorator:
|
|||
|
||||
async def test_tool_direct_function_call(self):
|
||||
"""Test that tools can be registered via direct function call."""
|
||||
from fastmcp.tools import FunctionTool
|
||||
from typing import cast
|
||||
|
||||
from fastmcp.tools.function_tool import DecoratedTool
|
||||
|
||||
mcp = FastMCP()
|
||||
|
||||
|
|
@ -1322,11 +1333,16 @@ class TestToolDecorator:
|
|||
|
||||
result_fn = mcp.tool(standalone_function, name="direct_call_tool")
|
||||
|
||||
assert isinstance(result_fn, FunctionTool)
|
||||
# In new decorator mode, returns the function with metadata
|
||||
decorated = cast(DecoratedTool, result_fn)
|
||||
assert hasattr(result_fn, "__fastmcp__")
|
||||
assert decorated.__fastmcp__.name == "direct_call_tool"
|
||||
assert result_fn is standalone_function
|
||||
|
||||
tools = await mcp.get_tools()
|
||||
tool = next(t for t in tools if t.name == "direct_call_tool")
|
||||
assert tool is result_fn
|
||||
# Tool is registered separately, not same object as decorated function
|
||||
assert tool.name == "direct_call_tool"
|
||||
|
||||
result = await mcp.call_tool("direct_call_tool", {"x": 5, "y": 3})
|
||||
assert result.structured_content == {"result": 8}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ ValueError when task=True is used with a sync function.
|
|||
import pytest
|
||||
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.prompts.prompt import FunctionPrompt
|
||||
from fastmcp.resources.resource import FunctionResource
|
||||
from fastmcp.tools.tool import FunctionTool
|
||||
from fastmcp.prompts.function_prompt import FunctionPrompt
|
||||
from fastmcp.resources.function_resource import FunctionResource
|
||||
from fastmcp.tools.function_tool import FunctionTool
|
||||
|
||||
|
||||
async def test_sync_tool_with_explicit_task_true_raises():
|
||||
|
|
|
|||
|
|
@ -7,8 +7,10 @@ import pytest
|
|||
from mcp.types import AnyUrl, TextContent
|
||||
|
||||
from fastmcp import FastMCP
|
||||
from fastmcp.prompts.prompt import FunctionPrompt, Prompt
|
||||
from fastmcp.resources.resource import FunctionResource, Resource
|
||||
from fastmcp.prompts.function_prompt import FunctionPrompt
|
||||
from fastmcp.prompts.prompt import Prompt
|
||||
from fastmcp.resources.function_resource import FunctionResource
|
||||
from fastmcp.resources.resource import Resource
|
||||
from fastmcp.resources.template import FunctionResourceTemplate, ResourceTemplate
|
||||
from fastmcp.server.providers import Provider
|
||||
from fastmcp.tools.tool import Tool, ToolResult
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue