mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-27 15:51:33 +02:00
Fix bug with duplicate behavior == ignore
This commit is contained in:
parent
9d8f237b82
commit
6e309e1354
12 changed files with 333 additions and 116 deletions
|
|
@ -15,8 +15,19 @@ logger = get_logger(__name__)
|
|||
class PromptManager:
|
||||
"""Manages FastMCP prompts."""
|
||||
|
||||
def __init__(self, duplicate_behavior: DuplicateBehavior = DuplicateBehavior.WARN):
|
||||
def __init__(self, duplicate_behavior: DuplicateBehavior | None = None):
|
||||
self._prompts: dict[str, Prompt] = {}
|
||||
|
||||
# Default to "warn" if None is provided
|
||||
if duplicate_behavior is None:
|
||||
duplicate_behavior = "warn"
|
||||
|
||||
if duplicate_behavior not in DuplicateBehavior.__args__:
|
||||
raise ValueError(
|
||||
f"Invalid duplicate_behavior: {duplicate_behavior}. "
|
||||
f"Must be one of: {', '.join(DuplicateBehavior.__args__)}"
|
||||
)
|
||||
|
||||
self.duplicate_behavior = duplicate_behavior
|
||||
|
||||
def get_prompt(self, name: str) -> Prompt | None:
|
||||
|
|
@ -44,17 +55,17 @@ class PromptManager:
|
|||
# Check for duplicates
|
||||
existing = self._prompts.get(prompt.name)
|
||||
if existing:
|
||||
if self.duplicate_behavior == DuplicateBehavior.WARN:
|
||||
if self.duplicate_behavior == "warn":
|
||||
logger.warning(f"Prompt already exists: {prompt.name}")
|
||||
self._prompts[prompt.name] = prompt
|
||||
elif self.duplicate_behavior == DuplicateBehavior.REPLACE:
|
||||
elif self.duplicate_behavior == "replace":
|
||||
self._prompts[prompt.name] = prompt
|
||||
elif self.duplicate_behavior == DuplicateBehavior.ERROR:
|
||||
elif self.duplicate_behavior == "error":
|
||||
raise ValueError(f"Prompt already exists: {prompt.name}")
|
||||
elif self.duplicate_behavior == DuplicateBehavior.IGNORE:
|
||||
pass
|
||||
|
||||
self._prompts[prompt.name] = prompt
|
||||
elif self.duplicate_behavior == "ignore":
|
||||
return existing
|
||||
else:
|
||||
self._prompts[prompt.name] = prompt
|
||||
return prompt
|
||||
|
||||
async def render_prompt(
|
||||
|
|
|
|||
|
|
@ -19,9 +19,20 @@ logger = get_logger(__name__)
|
|||
class ResourceManager:
|
||||
"""Manages FastMCP resources."""
|
||||
|
||||
def __init__(self, duplicate_behavior: DuplicateBehavior = DuplicateBehavior.WARN):
|
||||
def __init__(self, duplicate_behavior: DuplicateBehavior | None = None):
|
||||
self._resources: dict[str, Resource] = {}
|
||||
self._templates: dict[str, ResourceTemplate] = {}
|
||||
|
||||
# Default to "warn" if None is provided
|
||||
if duplicate_behavior is None:
|
||||
duplicate_behavior = "warn"
|
||||
|
||||
if duplicate_behavior not in DuplicateBehavior.__args__:
|
||||
raise ValueError(
|
||||
f"Invalid duplicate_behavior: {duplicate_behavior}. "
|
||||
f"Must be one of: {', '.join(DuplicateBehavior.__args__)}"
|
||||
)
|
||||
|
||||
self.duplicate_behavior = duplicate_behavior
|
||||
|
||||
def add_resource_or_template_from_fn(
|
||||
|
|
@ -114,16 +125,17 @@ class ResourceManager:
|
|||
)
|
||||
existing = self._resources.get(str(resource.uri))
|
||||
if existing:
|
||||
if self.duplicate_behavior == DuplicateBehavior.WARN:
|
||||
if self.duplicate_behavior == "warn":
|
||||
logger.warning(f"Resource already exists: {resource.uri}")
|
||||
self._resources[str(resource.uri)] = resource
|
||||
elif self.duplicate_behavior == DuplicateBehavior.REPLACE:
|
||||
elif self.duplicate_behavior == "replace":
|
||||
self._resources[str(resource.uri)] = resource
|
||||
elif self.duplicate_behavior == DuplicateBehavior.ERROR:
|
||||
elif self.duplicate_behavior == "error":
|
||||
raise ValueError(f"Resource already exists: {resource.uri}")
|
||||
elif self.duplicate_behavior == DuplicateBehavior.IGNORE:
|
||||
pass
|
||||
self._resources[str(resource.uri)] = resource
|
||||
elif self.duplicate_behavior == "ignore":
|
||||
return existing
|
||||
else:
|
||||
self._resources[str(resource.uri)] = resource
|
||||
return resource
|
||||
|
||||
def add_template_from_fn(
|
||||
|
|
@ -167,16 +179,17 @@ class ResourceManager:
|
|||
)
|
||||
existing = self._templates.get(str(template.uri_template))
|
||||
if existing:
|
||||
if self.duplicate_behavior == DuplicateBehavior.WARN:
|
||||
if self.duplicate_behavior == "warn":
|
||||
logger.warning(f"Resource already exists: {template.uri_template}")
|
||||
self._templates[str(template.uri_template)] = template
|
||||
elif self.duplicate_behavior == DuplicateBehavior.REPLACE:
|
||||
elif self.duplicate_behavior == "replace":
|
||||
self._templates[str(template.uri_template)] = template
|
||||
elif self.duplicate_behavior == DuplicateBehavior.ERROR:
|
||||
elif self.duplicate_behavior == "error":
|
||||
raise ValueError(f"Resource already exists: {template.uri_template}")
|
||||
elif self.duplicate_behavior == DuplicateBehavior.IGNORE:
|
||||
pass
|
||||
self._templates[template.uri_template] = template
|
||||
elif self.duplicate_behavior == "ignore":
|
||||
return existing
|
||||
else:
|
||||
self._templates[template.uri_template] = template
|
||||
return template
|
||||
|
||||
async def get_resource(self, uri: AnyUrl | str) -> Resource | None:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
from __future__ import annotations as _annotations
|
||||
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
from pydantic import Field
|
||||
|
|
@ -11,12 +10,7 @@ if TYPE_CHECKING:
|
|||
|
||||
LOG_LEVEL = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
||||
|
||||
|
||||
class DuplicateBehavior(Enum):
|
||||
WARN = "warn"
|
||||
ERROR = "error"
|
||||
REPLACE = "replace"
|
||||
IGNORE = "ignore"
|
||||
DuplicateBehavior = Literal["warn", "error", "replace", "ignore"]
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
|
|
@ -55,13 +49,13 @@ class ServerSettings(BaseSettings):
|
|||
debug: bool = False
|
||||
|
||||
# resource settings
|
||||
on_duplicate_resources: DuplicateBehavior = DuplicateBehavior.WARN
|
||||
on_duplicate_resources: DuplicateBehavior = "warn"
|
||||
|
||||
# tool settings
|
||||
on_duplicate_tools: DuplicateBehavior = DuplicateBehavior.WARN
|
||||
on_duplicate_tools: DuplicateBehavior = "warn"
|
||||
|
||||
# prompt settings
|
||||
on_duplicate_prompts: DuplicateBehavior = DuplicateBehavior.WARN
|
||||
on_duplicate_prompts: DuplicateBehavior = "warn"
|
||||
|
||||
dependencies: list[str] = Field(
|
||||
default_factory=list,
|
||||
|
|
|
|||
|
|
@ -21,8 +21,19 @@ logger = get_logger(__name__)
|
|||
class ToolManager:
|
||||
"""Manages FastMCP tools."""
|
||||
|
||||
def __init__(self, duplicate_behavior: DuplicateBehavior = DuplicateBehavior.WARN):
|
||||
def __init__(self, duplicate_behavior: DuplicateBehavior | None = None):
|
||||
self._tools: dict[str, Tool] = {}
|
||||
|
||||
# Default to "warn" if None is provided
|
||||
if duplicate_behavior is None:
|
||||
duplicate_behavior = "warn"
|
||||
|
||||
if duplicate_behavior not in DuplicateBehavior.__args__:
|
||||
raise ValueError(
|
||||
f"Invalid duplicate_behavior: {duplicate_behavior}. "
|
||||
f"Must be one of: {', '.join(DuplicateBehavior.__args__)}"
|
||||
)
|
||||
|
||||
self.duplicate_behavior = duplicate_behavior
|
||||
|
||||
def get_tool(self, name: str) -> Tool | None:
|
||||
|
|
@ -57,16 +68,17 @@ class ToolManager:
|
|||
name = name or tool.name
|
||||
existing = self._tools.get(name)
|
||||
if existing:
|
||||
if self.duplicate_behavior == DuplicateBehavior.WARN:
|
||||
if self.duplicate_behavior == "warn":
|
||||
logger.warning(f"Tool already exists: {name}")
|
||||
self._tools[name] = tool
|
||||
elif self.duplicate_behavior == DuplicateBehavior.REPLACE:
|
||||
elif self.duplicate_behavior == "replace":
|
||||
self._tools[name] = tool
|
||||
elif self.duplicate_behavior == DuplicateBehavior.ERROR:
|
||||
elif self.duplicate_behavior == "error":
|
||||
raise ValueError(f"Tool already exists: {name}")
|
||||
elif self.duplicate_behavior == DuplicateBehavior.IGNORE:
|
||||
pass
|
||||
self._tools[name] = tool
|
||||
elif self.duplicate_behavior == "ignore":
|
||||
return existing
|
||||
else:
|
||||
self._tools[name] = tool
|
||||
return tool
|
||||
|
||||
async def call_tool(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue