""" Tests for SEP-1686 background task support for prompts. Tests that prompts with task=True can execute in background. """ import pytest from fastmcp import FastMCP from fastmcp.client import Client @pytest.fixture async def prompt_server(): """Create a FastMCP server with task-enabled prompts.""" mcp = FastMCP("prompt-test-server") @mcp.prompt() async def simple_prompt(topic: str) -> str: """A simple prompt template.""" return f"Write about: {topic}" @mcp.prompt(task=True) async def background_prompt(topic: str, depth: str = "detailed") -> str: """A prompt that can execute in background.""" return f"Write a {depth} analysis of: {topic}" return mcp async def test_synchronous_prompt_unchanged(prompt_server): """Prompts without task metadata execute synchronously as before.""" async with Client(prompt_server) as client: # Regular call without task metadata result = await client.get_prompt("simple_prompt", {"topic": "AI"}) # Should execute immediately and return result assert "Write about: AI" in str(result) async def test_prompt_with_task_metadata_returns_immediately(prompt_server): """Prompts with task metadata return immediately with PromptTask object.""" async with Client(prompt_server) as client: # Call with task metadata task = await client.get_prompt("background_prompt", {"topic": "AI"}, task=True) # Should return a PromptTask object immediately from fastmcp.client.client import PromptTask assert isinstance(task, PromptTask) assert isinstance(task.task_id, str) assert len(task.task_id) > 0 async def test_prompt_task_executes_in_background(prompt_server): """Prompt task executes via Docket in background.""" async with Client(prompt_server) as client: task = await client.get_prompt( "background_prompt", {"topic": "Machine Learning", "depth": "comprehensive"}, task=True, ) # Verify background execution assert not task.returned_immediately # Get the result result = await task.result() assert "comprehensive" in result.messages[0].content.text.lower() async def test_graceful_degradation_prompt_without_task_flag(prompt_server): """Prompts with task=False execute synchronously even with task metadata.""" @prompt_server.prompt(task=False) # Explicitly disable task support async def sync_only_prompt(topic: str) -> str: return f"Sync prompt: {topic}" async with Client(prompt_server) as client: # Try to call with task metadata - should execute synchronously task = await client.get_prompt("sync_only_prompt", {"topic": "test"}, task=True) # Should have executed immediately (graceful degradation) assert task.returned_immediately # Can get result without waiting result = await task.result() assert "Sync prompt: test" in result.messages[0].content.text