mirror of
https://github.com/PrefectHQ/fastmcp.git
synced 2026-08-23 14:04:18 +02:00
Make transformed tool required order deterministic (#4564)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
33ed688a8f
commit
7934124fb5
2 changed files with 24 additions and 2 deletions
|
|
@ -707,7 +707,8 @@ class TransformedTool(Tool):
|
|||
schema = {
|
||||
"type": "object",
|
||||
"properties": new_props,
|
||||
"required": list(new_required),
|
||||
# Iterate props (not the set) for deterministic ordering
|
||||
"required": [p for p in new_props if p in new_required],
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
|
@ -899,7 +900,11 @@ class TransformedTool(Tool):
|
|||
result = {
|
||||
"type": "object",
|
||||
"properties": merged_props,
|
||||
"required": list(final_required),
|
||||
# Iterate props (not the set) for deterministic ordering; keep any
|
||||
# required names not present in properties (sorted) rather than
|
||||
# silently dropping them.
|
||||
"required": [p for p in merged_props if p in final_required]
|
||||
+ sorted(final_required - set(merged_props)),
|
||||
"additionalProperties": False,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,23 @@ def test_tool_from_tool_no_change(add_tool):
|
|||
assert new_tool.description == add_tool.description
|
||||
|
||||
|
||||
def test_transformed_tool_required_order_is_deterministic():
|
||||
"""`required` must follow property order, not set iteration order.
|
||||
|
||||
Set iteration order varies with PYTHONHASHSEED, which broke snapshot
|
||||
tests of tools/list output across processes.
|
||||
"""
|
||||
|
||||
def fn(alpha: int, beta: str, gamma: float, delta: bool, epsilon: int) -> str:
|
||||
return "x"
|
||||
|
||||
base = Tool.from_function(fn)
|
||||
transformed = Tool.from_tool(base, transform_args={"alpha": ArgTransform(name="a")})
|
||||
props = list(transformed.parameters["properties"])
|
||||
assert transformed.parameters["required"] == props
|
||||
assert props == ["a", "beta", "gamma", "delta", "epsilon"]
|
||||
|
||||
|
||||
def test_from_tool_accepts_decorated_function():
|
||||
@tool
|
||||
def search(q: str, limit: int = 10) -> list[str]:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue