Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ override-dependencies = [
"google-genai>=1.33.0", # Override mcpuniverse's google-genai==1.16.1 constraint
"mistralai>=1.7.0", # Override mcpuniverse's mistralai==1.6.0 constraint
"python-dotenv>=1.1.0", # Override mcpuniverse's python-dotenv==1.0.1 constraint
"uvicorn>=0.35.0", # Override mcpuniverse's uvicorn==0.34.0 constraint
"mcp @ git+https://github.com/chughtapan/python-sdk.git@wags-dev", # Align with core dependency
]

Expand Down
12 changes: 6 additions & 6 deletions src/wags/utils/handlers_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,13 @@ def generate_method_stub(tool: Tool) -> str:
"""Generate a method stub for a tool."""
method_name = sanitize_method_name(tool.name)

# Parse parameters from input_schema
# Parse parameters from inputSchema
params = []
params.append("self")

if tool.input_schema and isinstance(tool.input_schema, dict):
properties = tool.input_schema.get("properties", {})
required = tool.input_schema.get("required", [])
if tool.inputSchema and isinstance(tool.inputSchema, dict):
properties = tool.inputSchema.get("properties", {})
required = tool.inputSchema.get("required", [])

# Process required parameters first
for param_name in required:
Expand Down Expand Up @@ -119,8 +119,8 @@ def generate_handlers_class(class_name: str, tools: list[Tool]) -> str:
needs_literal = any(
"enum" in prop
for tool in tools
if tool.input_schema and isinstance(tool.input_schema, dict)
for prop in tool.input_schema.get("properties", {}).values()
if tool.inputSchema and isinstance(tool.inputSchema, dict)
for prop in tool.inputSchema.get("properties", {}).values()
)

# Generate imports
Expand Down
2 changes: 1 addition & 1 deletion tests/benchmarks/appworld/mcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ async def list_tools() -> list[Tool]:
tool = Tool(
name=api_doc["name"],
description=api_doc["description"],
input_schema=api_doc["input_schema"],
inputSchema=api_doc["input_schema"],
outputSchema=api_doc["output_schema"],
)
tools.append(tool)
Expand Down
3 changes: 1 addition & 2 deletions tests/benchmarks/bfcl/elicitation.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,7 @@ async def handle(
func_name = self.extract_function_name(message)
self.structured_logger.log_elicitation(func_name, "accepted", ground_truth_params)
return ElicitResult(
action="accept",
content=cast(dict[str, str | int | float | bool | list[str] | None], ground_truth_params),
action="accept", content=cast(dict[str, str | int | float | bool | None], ground_truth_params)
)

# No matching function found or no text params
Expand Down
4 changes: 2 additions & 2 deletions tests/benchmarks/mcp_universe/test_mcp_universe.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def _log_message(msg: Any, turn_idx: int, logger: StructuredEventLogger) -> int:
if hasattr(msg, "tool_results") and msg.tool_results:
for tool_id, result in msg.tool_results.items():
content = _extract_text_content(result.content) if hasattr(result, "content") else []
is_error = getattr(result, "is_error", False)
is_error = getattr(result, "isError", False)
logger.log_tool_result(turn_idx, tool_id, content or str(result), is_error)

if getattr(msg, "role", None) == "assistant" and hasattr(msg, "content"):
Expand Down Expand Up @@ -139,7 +139,7 @@ async def _run_mcp_universe_test(test_id: str, model: str, temperature: float, o
servers=["github"],
tools=tools_config,
instruction=test_dir / "instruction.txt",
request_params=RequestParams(max_tokens=MAX_TOKENS, max_iterations=MAX_ITERATIONS),
request_params=RequestParams(maxTokens=MAX_TOKENS, max_iterations=MAX_ITERATIONS),
)
async def run_test() -> Path:
async with agent.run() as agent_app:
Expand Down
6 changes: 3 additions & 3 deletions tests/e2e/test_github_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async def test_function() -> None:
# Verify successful response (not blocked by middleware)
assert tool_id in tool_results
result = tool_results[tool_id]
assert not result.is_error
assert not result.isError

await test_function()

Expand Down Expand Up @@ -99,7 +99,7 @@ async def test_function() -> None:
# Verify middleware denied access (error response)
assert tool_id in tool_results
result = tool_results[tool_id]
assert result.is_error
assert result.isError

# Verify error message indicates access denial
error_text = get_result_text(result)
Expand Down Expand Up @@ -141,7 +141,7 @@ async def test_function() -> None:
# Check if the call succeeded
if tool_id in tool_results:
result = tool_results[tool_id]
if not result.is_error:
if not result.isError:
success_found = True
break

Expand Down
20 changes: 8 additions & 12 deletions tests/unit/test_proxy.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Tests for proxy server with todo support."""

import pytest
from fastmcp import Client, FastMCP
from fastmcp import FastMCP

from wags.proxy import create_proxy

Expand Down Expand Up @@ -51,13 +51,11 @@ def test_tool() -> str:
assert "TodoWrite" in proxy.instructions
assert "Task Management" in proxy.instructions

# Should have todo tools available via client connection
async with Client(proxy) as client:
tools = await client.list_tools()
tool_names = {t.name for t in tools}
assert "TodoWrite" in tool_names
# Should have todo tools available
tools = await proxy._tool_manager.get_tools()
assert "TodoWrite" in tools
# Should also have original tool
assert "test_tool" in tool_names
assert "test_tool" in tools

def test_create_proxy_with_todos_rejects_instructions(self) -> None:
"""Test that enable_todos=True raises error if server has instructions."""
Expand All @@ -77,13 +75,11 @@ async def test_todo_tools_no_prefix(self) -> None:
server = FastMCP("test-server")
proxy = create_proxy(server, enable_todos=True)

async with Client(proxy) as client:
tools = await client.list_tools()
tool_names = {t.name for t in tools}
tools = await proxy._tool_manager.get_tools()

# Tools should be TodoWrite, not todo_TodoWrite
assert "TodoWrite" in tool_names
assert "todo_TodoWrite" not in tool_names
assert "TodoWrite" in tools
assert "todo_TodoWrite" not in tools

def test_custom_server_name(self) -> None:
"""Test creating proxy with custom name."""
Expand Down
14 changes: 7 additions & 7 deletions tests/unit/utils/test_handlers_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def basic_tool() -> Tool:
return Tool(
name="test_tool",
description="Test tool description",
input_schema={"type": "object", "properties": {}},
inputSchema={"type": "object", "properties": {}},
)


Expand All @@ -31,7 +31,7 @@ def tool_with_params() -> Tool:
return Tool(
name="create_item",
description="Create a new item",
input_schema={
inputSchema={
"type": "object",
"properties": {"name": {"type": "string"}, "quantity": {"type": "integer"}},
"required": ["name"],
Expand All @@ -45,7 +45,7 @@ def tool_with_enum() -> Tool:
return Tool(
name="status_tool",
description="Tool with status enum",
input_schema={
inputSchema={
"type": "object",
"properties": {"status": {"type": "string", "enum": ["active", "inactive"]}},
"required": ["status"],
Expand All @@ -58,7 +58,7 @@ def tool_with_boolean() -> Tool:
"""Create a Tool with boolean parameter."""
return Tool(
name="flag_tool",
input_schema={
inputSchema={
"type": "object",
"properties": {"enabled": {"type": "boolean"}},
"required": [],
Expand All @@ -69,15 +69,15 @@ def tool_with_boolean() -> Tool:
@pytest.fixture
def empty_tool() -> Tool:
"""Create a Tool without parameters."""
return Tool(name="empty_tool", input_schema={"type": "object", "properties": {}})
return Tool(name="empty_tool", inputSchema={"type": "object", "properties": {}})


@pytest.fixture
def tool_with_literal() -> Tool:
"""Create a Tool with Literal type enum."""
return Tool(
name="tool_with_literal",
input_schema={
inputSchema={
"type": "object",
"properties": {"choice": {"type": "string", "enum": ["a", "b", "c"]}},
},
Expand Down Expand Up @@ -222,7 +222,7 @@ async def test_generate_stub_to_file(self, tmp_path: Any, empty_tool: Tool) -> N
config_file.write_text(json.dumps(config_data))

# Rename the tool for this test
test_tool = Tool(name="my_tool", input_schema=empty_tool.input_schema)
test_tool = Tool(name="my_tool", inputSchema=empty_tool.inputSchema)

# Mock Client
mock_mcp = AsyncMock()
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/fastagent_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def _serialize_tool_results(tool_results: dict[str, CallToolResult] | None) -> d
serialized = {}
for tool_id, result in tool_results.items():
result_content = [MessageSerializer._serialize_content_item(c) for c in result.content]
serialized[tool_id] = {"content": result_content, "is_error": result.is_error}
serialized[tool_id] = {"content": result_content, "is_error": result.isError}
return serialized

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/test_fastagent_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def test_preserves_tool_calls(self) -> None:
def test_preserves_tool_results(self) -> None:
"""Test that tool results are preserved in serialization."""
# Create a message with tool results
tool_result = CallToolResult(content=[TextContent(type="text", text="Tool output")], is_error=False)
tool_result = CallToolResult(content=[TextContent(type="text", text="Tool output")], isError=False)

msg = PromptMessageExtended(role="user", content=[], tool_results={"tool_123": tool_result})

Expand Down
Loading
Loading