refactor: use snake case instead of camel case in types (#1894)

This commit is contained in:
Marcelo Trylesinski 2026-01-16 15:51:27 +01:00 • committed by GitHub
commit e94b386a13
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
63 changed files with 1063 additions and 1057 deletions

View file

@ -61,7 +61,7 @@ def run_unicode_server(port: int) -> None: # pragma: no cover
Tool(
name="echo_unicode",
description="🔤 Echo Unicode text - Hello 👋 World 🌍 - Testing 🧪 Unicode ✨",
inputSchema={
input_schema={
"type": "object",
"properties": {
"text": {"type": "string", "description": "Text to echo back"},

View file

@ -45,7 +45,7 @@ async def test_list_roots_callback():
async with create_session(server._mcp_server, list_roots_callback=list_roots_callback) as client_session:
# Make a request to trigger sampling callback
result = await client_session.call_tool("test_list_roots", {"message": "test message"})
assert result.isError is False
assert result.is_error is False
assert isinstance(result.content[0], TextContent)
assert result.content[0].text == "true"
@ -53,6 +53,6 @@ async def test_list_roots_callback():
async with create_session(server._mcp_server) as client_session:
# Make a request to trigger sampling callback
result = await client_session.call_tool("test_list_roots", {"message": "test message"})
assert result.isError is True
assert result.is_error is True
assert isinstance(result.content[0], TextContent)
assert result.content[0].text == "Error executing tool test_list_roots: List roots not supported"

View file

@ -78,7 +78,7 @@ async def test_logging_callback():
) as client_session:
# First verify our test tool works
result = await client_session.call_tool("test_tool", {})
assert result.isError is False
assert result.is_error is False
assert isinstance(result.content[0], TextContent)
assert result.content[0].text == "true"
@ -101,8 +101,8 @@ async def test_logging_callback():
"extra_dict": {"a": 1, "b": 2, "c": 3},
},
)
assert log_result.isError is False
assert log_result_with_extra.isError is False
assert log_result.is_error is False
assert log_result_with_extra.is_error is False
assert len(logging_collector.log_messages) == 2
# Create meta object with related_request_id added dynamically
log = logging_collector.log_messages[0]

View file

@ -66,8 +66,8 @@ class TestClientOutputSchemaValidation:
Tool(
name="get_user",
description="Get user data",
inputSchema={"type": "object"},
outputSchema=output_schema,
input_schema={"type": "object"},
output_schema=output_schema,
)
]
@ -105,8 +105,8 @@ class TestClientOutputSchemaValidation:
Tool(
name="calculate",
description="Calculate something",
inputSchema={"type": "object"},
outputSchema=output_schema,
input_schema={"type": "object"},
output_schema=output_schema,
)
]
@ -136,8 +136,8 @@ class TestClientOutputSchemaValidation:
Tool(
name="get_scores",
description="Get scores",
inputSchema={"type": "object"},
outputSchema=output_schema,
input_schema={"type": "object"},
output_schema=output_schema,
)
]
@ -171,8 +171,8 @@ class TestClientOutputSchemaValidation:
Tool(
name="get_person",
description="Get person data",
inputSchema={"type": "object"},
outputSchema=output_schema,
input_schema={"type": "object"},
output_schema=output_schema,
)
]
@ -190,7 +190,7 @@ class TestClientOutputSchemaValidation:
@pytest.mark.anyio
async def test_tool_not_listed_warning(self, caplog: pytest.LogCaptureFixture):
"""Test that client logs warning when tool is not in list_tools but has outputSchema"""
"""Test that client logs warning when tool is not in list_tools but has output_schema"""
server = Server("test-server")
@server.list_tools()
@ -210,8 +210,8 @@ class TestClientOutputSchemaValidation:
async with client_session(server) as client:
# Call a tool that wasn't listed
result = await client.call_tool("mystery_tool", {})
assert result.structuredContent == {"result": 42}
assert result.isError is False
assert result.structured_content == {"result": 42}
assert result.is_error is False
# Check that warning was logged
assert "Tool mystery_tool not listed" in caplog.text

View file

@ -25,7 +25,7 @@ async def test_sampling_callback():
role="assistant",
content=TextContent(type="text", text="This is a response from the sampling callback"),
model="test-model",
stopReason="endTurn",
stop_reason="endTurn",
)
async def sampling_callback(
@ -47,7 +47,7 @@ async def test_sampling_callback():
async with create_session(server._mcp_server, sampling_callback=sampling_callback) as client_session:
# Make a request to trigger sampling callback
result = await client_session.call_tool("test_sampling", {"message": "Test message for sampling"})
assert result.isError is False
assert result.is_error is False
assert isinstance(result.content[0], TextContent)
assert result.content[0].text == "true"
@ -55,7 +55,7 @@ async def test_sampling_callback():
async with create_session(server._mcp_server) as client_session:
# Make a request to trigger sampling callback
result = await client_session.call_tool("test_sampling", {"message": "Test message for sampling"})
assert result.isError is True
assert result.is_error is True
assert isinstance(result.content[0], TextContent)
assert result.content[0].text == "Error executing tool test_sampling: Sampling not supported"
@ -72,7 +72,7 @@ async def test_create_message_backwards_compat_single_content():
role="assistant",
content=TextContent(type="text", text="Hello from LLM"),
model="test-model",
stopReason="endTurn",
stop_reason="endTurn",
)
async def sampling_callback(
@ -99,7 +99,7 @@ async def test_create_message_backwards_compat_single_content():
async with create_session(server._mcp_server, sampling_callback=sampling_callback) as client_session:
result = await client_session.call_tool("test_backwards_compat", {"message": "Test"})
assert result.isError is False
assert result.is_error is False
assert isinstance(result.content[0], TextContent)
assert result.content[0].text == "true"
@ -112,7 +112,7 @@ async def test_create_message_result_with_tools_type():
role="assistant",
content=ToolUseContent(type="tool_use", id="call_123", name="get_weather", input={"city": "SF"}),
model="test-model",
stopReason="toolUse",
stop_reason="toolUse",
)
# CreateMessageResultWithTools should have content_as_list
@ -128,7 +128,7 @@ async def test_create_message_result_with_tools_type():
ToolUseContent(type="tool_use", id="call_456", name="get_weather", input={"city": "NYC"}),
],
model="test-model",
stopReason="toolUse",
stop_reason="toolUse",
)
content_list_array = result_array.content_as_list
assert len(content_list_array) == 2

View file

@ -49,7 +49,7 @@ async def test_client_session_initialize():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(
logging=None,
resources=None,
@ -57,7 +57,7 @@ async def test_client_session_initialize():
experimental=None,
prompts=None,
),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
instructions="The server instructions.",
)
)
@ -105,9 +105,9 @@ async def test_client_session_initialize():
# Assert the result
assert isinstance(result, InitializeResult)
assert result.protocolVersion == LATEST_PROTOCOL_VERSION
assert result.protocol_version == LATEST_PROTOCOL_VERSION
assert isinstance(result.capabilities, ServerCapabilities)
assert result.serverInfo == Implementation(name="mock-server", version="0.1.0")
assert result.server_info == Implementation(name="mock-server", version="0.1.0")
assert result.instructions == "The server instructions."
# Check that the client sent the initialized notification
@ -133,13 +133,13 @@ async def test_client_session_custom_client_info():
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
)
assert isinstance(request.root, InitializeRequest)
received_client_info = request.root.params.clientInfo
received_client_info = request.root.params.client_info
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -194,13 +194,13 @@ async def test_client_session_default_client_info():
jsonrpc_request.model_dump(by_alias=True, mode="json", exclude_none=True)
)
assert isinstance(request.root, InitializeRequest)
received_client_info = request.root.params.clientInfo
received_client_info = request.root.params.client_info
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -254,14 +254,14 @@ async def test_client_session_version_negotiation_success():
assert isinstance(request.root, InitializeRequest)
# Verify client sent the latest protocol version
assert request.root.params.protocolVersion == LATEST_PROTOCOL_VERSION
assert request.root.params.protocol_version == LATEST_PROTOCOL_VERSION
# Server responds with a supported older version
result = ServerResult(
InitializeResult(
protocolVersion="2024-11-05",
protocol_version="2024-11-05",
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -296,8 +296,8 @@ async def test_client_session_version_negotiation_success():
# Assert the result with negotiated version
assert isinstance(result, InitializeResult)
assert result.protocolVersion == "2024-11-05"
assert result.protocolVersion in SUPPORTED_PROTOCOL_VERSIONS
assert result.protocol_version == "2024-11-05"
assert result.protocol_version in SUPPORTED_PROTOCOL_VERSIONS
@pytest.mark.anyio
@ -318,9 +318,9 @@ async def test_client_session_version_negotiation_failure():
# Server responds with an unsupported version
result = ServerResult(
InitializeResult(
protocolVersion="2020-01-01", # Unsupported old version
protocol_version="2020-01-01", # Unsupported old version
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -377,9 +377,9 @@ async def test_client_capabilities_default():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -455,9 +455,9 @@ async def test_client_capabilities_with_custom_callbacks():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -503,7 +503,7 @@ async def test_client_capabilities_with_custom_callbacks():
assert received_capabilities.roots is not None
assert isinstance(received_capabilities.roots, types.RootsCapability)
# Should be True for custom callback
assert received_capabilities.roots.listChanged is True
assert received_capabilities.roots.list_changed is True
@pytest.mark.anyio
@ -538,9 +538,9 @@ async def test_client_capabilities_with_sampling_tools():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -592,9 +592,9 @@ async def test_get_server_capabilities():
expected_capabilities = ServerCapabilities(
logging=types.LoggingCapability(),
prompts=types.PromptsCapability(listChanged=True),
resources=types.ResourcesCapability(subscribe=True, listChanged=True),
tools=types.ToolsCapability(listChanged=False),
prompts=types.PromptsCapability(list_changed=True),
resources=types.ResourcesCapability(subscribe=True, list_changed=True),
tools=types.ToolsCapability(list_changed=False),
)
async def mock_server():
@ -608,9 +608,9 @@ async def test_get_server_capabilities():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=expected_capabilities,
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -649,11 +649,11 @@ async def test_get_server_capabilities():
assert capabilities == expected_capabilities
assert capabilities.logging is not None
assert capabilities.prompts is not None
assert capabilities.prompts.listChanged is True
assert capabilities.prompts.list_changed is True
assert capabilities.resources is not None
assert capabilities.resources.subscribe is True
assert capabilities.tools is not None
assert capabilities.tools.listChanged is False
assert capabilities.tools.list_changed is False
@pytest.mark.anyio
@ -663,7 +663,7 @@ async def test_client_tool_call_with_meta(meta: dict[str, Any] | None):
client_to_server_send, client_to_server_receive = anyio.create_memory_object_stream[SessionMessage](1)
server_to_client_send, server_to_client_receive = anyio.create_memory_object_stream[SessionMessage](1)
mocked_tool = types.Tool(name="sample_tool", inputSchema={})
mocked_tool = types.Tool(name="sample_tool", input_schema={})
async def mock_server():
# Receive initialization request from client
@ -677,9 +677,9 @@ async def test_client_tool_call_with_meta(meta: dict[str, Any] | None):
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -712,7 +712,7 @@ async def test_client_tool_call_with_meta(meta: dict[str, Any] | None):
assert jsonrpc_request.root.params["_meta"] == meta
result = ServerResult(
CallToolResult(content=[TextContent(type="text", text="Called successfully")], isError=False)
CallToolResult(content=[TextContent(type="text", text="Called successfully")], is_error=False)
)
# Send the tools/call result

View file

@ -59,7 +59,7 @@ class TestClientSessionGroup:
return f"{(server_info.name)}-{name}"
mcp_session_group = ClientSessionGroup(component_name_hook=hook)
mcp_session_group._tools = {"server1-my_tool": types.Tool(name="my_tool", inputSchema={})}
mcp_session_group._tools = {"server1-my_tool": types.Tool(name="my_tool", input_schema={})}
mcp_session_group._tool_to_session = {"server1-my_tool": mock_session}
text_content = types.TextContent(type="text", text="OK")
mock_session.call_tool.return_value = types.CallToolResult(content=[text_content])
@ -324,7 +324,7 @@ class TestClientSessionGroup:
# Mock session.initialize()
mock_initialize_result = mock.AsyncMock(name="InitializeResult")
mock_initialize_result.serverInfo = types.Implementation(name="foo", version="1")
mock_initialize_result.server_info = types.Implementation(name="foo", version="1")
mock_entered_session.initialize.return_value = mock_initialize_result
# --- Test Execution ---
@ -381,5 +381,5 @@ class TestClientSessionGroup:
mock_entered_session.initialize.assert_awaited_once()
# 3. Assert returned values
assert returned_server_info is mock_initialize_result.serverInfo
assert returned_server_info is mock_initialize_result.server_info
assert returned_session is mock_entered_session

View file

@ -45,9 +45,9 @@ async def test_client_capabilities_without_tasks():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -119,9 +119,9 @@ async def test_client_capabilities_with_tasks():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -203,9 +203,9 @@ async def test_client_capabilities_auto_built_from_handlers():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)
@ -283,9 +283,9 @@ async def test_client_capabilities_with_task_augmented_handlers():
result = ServerResult(
InitializeResult(
protocolVersion=LATEST_PROTOCOL_VERSION,
protocol_version=LATEST_PROTOCOL_VERSION,
capabilities=ServerCapabilities(),
serverInfo=Implementation(name="mock-server", version="0.1.0"),
server_info=Implementation(name="mock-server", version="0.1.0"),
)
)

View file

@ -117,17 +117,17 @@ async def test_client_handles_get_task_request(client_streams: ClientTestStreams
params: GetTaskRequestParams,
) -> GetTaskResult | ErrorData:
nonlocal received_task_id
received_task_id = params.taskId
task = await store.get_task(params.taskId)
assert task is not None, f"Test setup error: task {params.taskId} should exist"
received_task_id = params.task_id
task = await store.get_task(params.task_id)
assert task is not None, f"Test setup error: task {params.task_id} should exist"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=task.pollInterval,
poll_interval=task.poll_interval,
)
await store.create_task(TaskMetadata(ttl=60000), task_id="test-task-123")
@ -150,7 +150,7 @@ async def test_client_handles_get_task_request(client_streams: ClientTestStreams
tg.start_soon(run_client)
await client_ready.wait()
typed_request = GetTaskRequest(params=GetTaskRequestParams(taskId="test-task-123"))
typed_request = GetTaskRequest(params=GetTaskRequestParams(task_id="test-task-123"))
request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-1",
@ -164,7 +164,7 @@ async def test_client_handles_get_task_request(client_streams: ClientTestStreams
assert response.id == "req-1"
result = GetTaskResult.model_validate(response.result)
assert result.taskId == "test-task-123"
assert result.task_id == "test-task-123"
assert result.status == "working"
assert received_task_id == "test-task-123"
@ -183,8 +183,8 @@ async def test_client_handles_get_task_result_request(client_streams: ClientTest
context: RequestContext[ClientSession, None],
params: GetTaskPayloadRequestParams,
) -> GetTaskPayloadResult | ErrorData:
result = await store.get_result(params.taskId)
assert result is not None, f"Test setup error: result for {params.taskId} should exist"
result = await store.get_result(params.task_id)
assert result is not None, f"Test setup error: result for {params.task_id} should exist"
assert isinstance(result, types.CallToolResult)
return GetTaskPayloadResult(**result.model_dump())
@ -213,7 +213,7 @@ async def test_client_handles_get_task_result_request(client_streams: ClientTest
tg.start_soon(run_client)
await client_ready.wait()
typed_request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId="test-task-456"))
typed_request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id="test-task-456"))
request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-2",
@ -248,7 +248,7 @@ async def test_client_handles_list_tasks_request(client_streams: ClientTestStrea
) -> ListTasksResult | ErrorData:
cursor = params.cursor if params else None
tasks_list, next_cursor = await store.list_tasks(cursor=cursor)
return ListTasksResult(tasks=tasks_list, nextCursor=next_cursor)
return ListTasksResult(tasks=tasks_list, next_cursor=next_cursor)
await store.create_task(TaskMetadata(ttl=60000), task_id="task-1")
await store.create_task(TaskMetadata(ttl=60000), task_id="task-2")
@ -301,16 +301,16 @@ async def test_client_handles_cancel_task_request(client_streams: ClientTestStre
context: RequestContext[ClientSession, None],
params: CancelTaskRequestParams,
) -> CancelTaskResult | ErrorData:
task = await store.get_task(params.taskId)
assert task is not None, f"Test setup error: task {params.taskId} should exist"
await store.update_task(params.taskId, status="cancelled")
updated = await store.get_task(params.taskId)
task = await store.get_task(params.task_id)
assert task is not None, f"Test setup error: task {params.task_id} should exist"
await store.update_task(params.task_id, status="cancelled")
updated = await store.get_task(params.task_id)
assert updated is not None
return CancelTaskResult(
taskId=updated.taskId,
task_id=updated.task_id,
status=updated.status,
createdAt=updated.createdAt,
lastUpdatedAt=updated.lastUpdatedAt,
created_at=updated.created_at,
last_updated_at=updated.last_updated_at,
ttl=updated.ttl,
)
@ -334,7 +334,7 @@ async def test_client_handles_cancel_task_request(client_streams: ClientTestStre
tg.start_soon(run_client)
await client_ready.wait()
typed_request = CancelTaskRequest(params=CancelTaskRequestParams(taskId="task-to-cancel"))
typed_request = CancelTaskRequest(params=CancelTaskRequestParams(task_id="task-to-cancel"))
request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-4",
@ -347,7 +347,7 @@ async def test_client_handles_cancel_task_request(client_streams: ClientTestStre
assert isinstance(response, types.JSONRPCResponse)
result = CancelTaskResult.model_validate(response.result)
assert result.taskId == "task-to-cancel"
assert result.task_id == "task-to-cancel"
assert result.status == "cancelled"
tg.cancel_scope.cancel()
@ -370,17 +370,17 @@ async def test_client_task_augmented_sampling(client_streams: ClientTestStreams)
task_metadata: TaskMetadata,
) -> CreateTaskResult:
task = await store.create_task(task_metadata)
created_task_id[0] = task.taskId
created_task_id[0] = task.task_id
async def do_sampling() -> None:
result = CreateMessageResult(
role="assistant",
content=TextContent(type="text", text="Sampled response"),
model="test-model",
stopReason="endTurn",
stop_reason="endTurn",
)
await store.store_result(task.taskId, result)
await store.update_task(task.taskId, status="completed")
await store.store_result(task.task_id, result)
await store.update_task(task.task_id, status="completed")
sampling_completed.set()
assert background_tg[0] is not None
@ -391,24 +391,24 @@ async def test_client_task_augmented_sampling(client_streams: ClientTestStreams)
context: RequestContext[ClientSession, None],
params: GetTaskRequestParams,
) -> GetTaskResult | ErrorData:
task = await store.get_task(params.taskId)
assert task is not None, f"Test setup error: task {params.taskId} should exist"
task = await store.get_task(params.task_id)
assert task is not None, f"Test setup error: task {params.task_id} should exist"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=task.pollInterval,
poll_interval=task.poll_interval,
)
async def get_task_result_handler(
context: RequestContext[ClientSession, None],
params: GetTaskPayloadRequestParams,
) -> GetTaskPayloadResult | ErrorData:
result = await store.get_result(params.taskId)
assert result is not None, f"Test setup error: result for {params.taskId} should exist"
result = await store.get_result(params.task_id)
assert result is not None, f"Test setup error: result for {params.task_id} should exist"
assert isinstance(result, CreateMessageResult)
return GetTaskPayloadResult(**result.model_dump())
@ -439,7 +439,7 @@ async def test_client_task_augmented_sampling(client_streams: ClientTestStreams)
typed_request = CreateMessageRequest(
params=CreateMessageRequestParams(
messages=[SamplingMessage(role="user", content=TextContent(type="text", text="Hello"))],
maxTokens=100,
max_tokens=100,
task=TaskMetadata(ttl=60000),
)
)
@ -456,14 +456,14 @@ async def test_client_task_augmented_sampling(client_streams: ClientTestStreams)
assert isinstance(response, types.JSONRPCResponse)
task_result = CreateTaskResult.model_validate(response.result)
task_id = task_result.task.taskId
task_id = task_result.task.task_id
assert task_id == created_task_id[0]
# Step 3: Wait for background sampling
await sampling_completed.wait()
# Step 4: Server polls task status
typed_poll = GetTaskRequest(params=GetTaskRequestParams(taskId=task_id))
typed_poll = GetTaskRequest(params=GetTaskRequestParams(task_id=task_id))
poll_request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-poll",
@ -479,7 +479,7 @@ async def test_client_task_augmented_sampling(client_streams: ClientTestStreams)
assert status.status == "completed"
# Step 5: Server gets result
typed_result_req = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=task_id))
typed_result_req = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=task_id))
result_request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-result",
@ -514,13 +514,13 @@ async def test_client_task_augmented_elicitation(client_streams: ClientTestStrea
task_metadata: TaskMetadata,
) -> CreateTaskResult | ErrorData:
task = await store.create_task(task_metadata)
created_task_id[0] = task.taskId
created_task_id[0] = task.task_id
async def do_elicitation() -> None:
# Simulate user providing elicitation response
result = ElicitResult(action="accept", content={"name": "Test User"})
await store.store_result(task.taskId, result)
await store.update_task(task.taskId, status="completed")
await store.store_result(task.task_id, result)
await store.update_task(task.task_id, status="completed")
elicitation_completed.set()
assert background_tg[0] is not None
@ -531,24 +531,24 @@ async def test_client_task_augmented_elicitation(client_streams: ClientTestStrea
context: RequestContext[ClientSession, None],
params: GetTaskRequestParams,
) -> GetTaskResult | ErrorData:
task = await store.get_task(params.taskId)
assert task is not None, f"Test setup error: task {params.taskId} should exist"
task = await store.get_task(params.task_id)
assert task is not None, f"Test setup error: task {params.task_id} should exist"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=task.pollInterval,
poll_interval=task.poll_interval,
)
async def get_task_result_handler(
context: RequestContext[ClientSession, None],
params: GetTaskPayloadRequestParams,
) -> GetTaskPayloadResult | ErrorData:
result = await store.get_result(params.taskId)
assert result is not None, f"Test setup error: result for {params.taskId} should exist"
result = await store.get_result(params.task_id)
assert result is not None, f"Test setup error: result for {params.task_id} should exist"
assert isinstance(result, ElicitResult)
return GetTaskPayloadResult(**result.model_dump())
@ -579,7 +579,7 @@ async def test_client_task_augmented_elicitation(client_streams: ClientTestStrea
typed_request = ElicitRequest(
params=ElicitRequestFormParams(
message="What is your name?",
requestedSchema={"type": "object", "properties": {"name": {"type": "string"}}},
requested_schema={"type": "object", "properties": {"name": {"type": "string"}}},
task=TaskMetadata(ttl=60000),
)
)
@ -596,14 +596,14 @@ async def test_client_task_augmented_elicitation(client_streams: ClientTestStrea
assert isinstance(response, types.JSONRPCResponse)
task_result = CreateTaskResult.model_validate(response.result)
task_id = task_result.task.taskId
task_id = task_result.task.task_id
assert task_id == created_task_id[0]
# Step 3: Wait for background elicitation
await elicitation_completed.wait()
# Step 4: Server polls task status
typed_poll = GetTaskRequest(params=GetTaskRequestParams(taskId=task_id))
typed_poll = GetTaskRequest(params=GetTaskRequestParams(task_id=task_id))
poll_request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-poll",
@ -619,7 +619,7 @@ async def test_client_task_augmented_elicitation(client_streams: ClientTestStrea
assert status.status == "completed"
# Step 5: Server gets result
typed_result_req = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=task_id))
typed_result_req = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=task_id))
result_request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-result",
@ -661,7 +661,7 @@ async def test_client_returns_error_for_unhandled_task_request(client_streams: C
tg.start_soon(run_client)
await client_ready.wait()
typed_request = GetTaskRequest(params=GetTaskRequestParams(taskId="nonexistent"))
typed_request = GetTaskRequest(params=GetTaskRequestParams(task_id="nonexistent"))
request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-unhandled",
@ -700,7 +700,7 @@ async def test_client_returns_error_for_unhandled_task_result_request(client_str
tg.start_soon(run_client)
await client_ready.wait()
typed_request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId="nonexistent"))
typed_request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id="nonexistent"))
request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-result",
@ -772,7 +772,7 @@ async def test_client_returns_error_for_unhandled_cancel_task_request(client_str
tg.start_soon(run_client)
await client_ready.wait()
typed_request = CancelTaskRequest(params=CancelTaskRequestParams(taskId="nonexistent"))
typed_request = CancelTaskRequest(params=CancelTaskRequestParams(task_id="nonexistent"))
request = types.JSONRPCRequest(
jsonrpc="2.0",
id="req-cancel",
@ -813,7 +813,7 @@ async def test_client_returns_error_for_unhandled_task_augmented_sampling(client
typed_request = CreateMessageRequest(
params=CreateMessageRequestParams(
messages=[SamplingMessage(role="user", content=TextContent(type="text", text="Hello"))],
maxTokens=100,
max_tokens=100,
task=TaskMetadata(ttl=60000),
)
)
@ -859,7 +859,7 @@ async def test_client_returns_error_for_unhandled_task_augmented_elicitation(
typed_request = ElicitRequest(
params=ElicitRequestFormParams(
message="What is your name?",
requestedSchema={"type": "object", "properties": {"name": {"type": "string"}}},
requested_schema={"type": "object", "properties": {"name": {"type": "string"}}},
task=TaskMetadata(ttl=60000),
)
)

View file

@ -20,13 +20,13 @@ def make_task_result(
"""Create GetTaskResult with sensible defaults."""
now = datetime.now(timezone.utc)
return GetTaskResult(
taskId=task_id,
task_id=task_id,
status=status,
statusMessage=status_message,
createdAt=now,
lastUpdatedAt=now,
status_message=status_message,
created_at=now,
last_updated_at=now,
ttl=60000,
pollInterval=poll_interval,
poll_interval=poll_interval,
)
@ -117,5 +117,5 @@ async def test_poll_task_yields_full_result(features: ExperimentalClientFeatures
assert len(results) == 1
assert results[0].status == "completed"
assert results[0].statusMessage == "All done!"
assert results[0].taskId == "test-task"
assert results[0].status_message == "All done!"
assert results[0].task_id == "test-task"

View file

@ -58,7 +58,7 @@ async def test_session_experimental_get_task() -> None:
@server.list_tools()
async def list_tools():
return [Tool(name="test_tool", description="Test", inputSchema={"type": "object"})]
return [Tool(name="test_tool", description="Test", input_schema={"type": "object"})]
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent] | CreateTaskResult:
@ -70,10 +70,10 @@ async def test_session_experimental_get_task() -> None:
task = await app.store.create_task(task_metadata)
done_event = Event()
app.task_done_events[task.taskId] = done_event
app.task_done_events[task.task_id] = done_event
async def do_work():
async with task_execution(task.taskId, app.store) as task_ctx:
async with task_execution(task.task_id, app.store) as task_ctx:
await task_ctx.complete(CallToolResult(content=[TextContent(type="text", text="Done")]))
done_event.set()
@ -85,16 +85,16 @@ async def test_session_experimental_get_task() -> None:
@server.experimental.get_task()
async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
app = server.request_context.lifespan_context
task = await app.store.get_task(request.params.taskId)
assert task is not None, f"Test setup error: task {request.params.taskId} should exist"
task = await app.store.get_task(request.params.task_id)
assert task is not None, f"Test setup error: task {request.params.task_id} should exist"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=task.pollInterval,
poll_interval=task.poll_interval,
)
# Set up streams
@ -145,7 +145,7 @@ async def test_session_experimental_get_task() -> None:
),
CreateTaskResult,
)
task_id = create_result.task.taskId
task_id = create_result.task.task_id
# Wait for task to complete
await app_context.task_done_events[task_id].wait()
@ -153,7 +153,7 @@ async def test_session_experimental_get_task() -> None:
# Use session.experimental to get task status
task_status = await client_session.experimental.get_task(task_id)
assert task_status.taskId == task_id
assert task_status.task_id == task_id
assert task_status.status == "completed"
tg.cancel_scope.cancel()
@ -167,7 +167,7 @@ async def test_session_experimental_get_task_result() -> None:
@server.list_tools()
async def list_tools():
return [Tool(name="test_tool", description="Test", inputSchema={"type": "object"})]
return [Tool(name="test_tool", description="Test", input_schema={"type": "object"})]
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent] | CreateTaskResult:
@ -179,10 +179,10 @@ async def test_session_experimental_get_task_result() -> None:
task = await app.store.create_task(task_metadata)
done_event = Event()
app.task_done_events[task.taskId] = done_event
app.task_done_events[task.task_id] = done_event
async def do_work():
async with task_execution(task.taskId, app.store) as task_ctx:
async with task_execution(task.task_id, app.store) as task_ctx:
await task_ctx.complete(
CallToolResult(content=[TextContent(type="text", text="Task result content")])
)
@ -198,8 +198,8 @@ async def test_session_experimental_get_task_result() -> None:
request: GetTaskPayloadRequest,
) -> GetTaskPayloadResult:
app = server.request_context.lifespan_context
result = await app.store.get_result(request.params.taskId)
assert result is not None, f"Test setup error: result for {request.params.taskId} should exist"
result = await app.store.get_result(request.params.task_id)
assert result is not None, f"Test setup error: result for {request.params.task_id} should exist"
assert isinstance(result, CallToolResult)
return GetTaskPayloadResult(**result.model_dump())
@ -251,7 +251,7 @@ async def test_session_experimental_get_task_result() -> None:
),
CreateTaskResult,
)
task_id = create_result.task.taskId
task_id = create_result.task.task_id
# Wait for task to complete
await app_context.task_done_events[task_id].wait()
@ -275,7 +275,7 @@ async def test_session_experimental_list_tasks() -> None:
@server.list_tools()
async def list_tools():
return [Tool(name="test_tool", description="Test", inputSchema={"type": "object"})]
return [Tool(name="test_tool", description="Test", input_schema={"type": "object"})]
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent] | CreateTaskResult:
@ -287,10 +287,10 @@ async def test_session_experimental_list_tasks() -> None:
task = await app.store.create_task(task_metadata)
done_event = Event()
app.task_done_events[task.taskId] = done_event
app.task_done_events[task.task_id] = done_event
async def do_work():
async with task_execution(task.taskId, app.store) as task_ctx:
async with task_execution(task.task_id, app.store) as task_ctx:
await task_ctx.complete(CallToolResult(content=[TextContent(type="text", text="Done")]))
done_event.set()
@ -303,7 +303,7 @@ async def test_session_experimental_list_tasks() -> None:
async def handle_list_tasks(request: ListTasksRequest) -> ListTasksResult:
app = server.request_context.lifespan_context
tasks_list, next_cursor = await app.store.list_tasks(cursor=request.params.cursor if request.params else None)
return ListTasksResult(tasks=tasks_list, nextCursor=next_cursor)
return ListTasksResult(tasks=tasks_list, next_cursor=next_cursor)
# Set up streams
server_to_client_send, server_to_client_receive = anyio.create_memory_object_stream[SessionMessage](10)
@ -354,7 +354,7 @@ async def test_session_experimental_list_tasks() -> None:
),
CreateTaskResult,
)
await app_context.task_done_events[create_result.task.taskId].wait()
await app_context.task_done_events[create_result.task.task_id].wait()
# Use TaskClient to list tasks
list_result = await client_session.experimental.list_tasks()
@ -372,7 +372,7 @@ async def test_session_experimental_cancel_task() -> None:
@server.list_tools()
async def list_tools():
return [Tool(name="test_tool", description="Test", inputSchema={"type": "object"})]
return [Tool(name="test_tool", description="Test", input_schema={"type": "object"})]
@server.call_tool()
async def handle_call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent] | CreateTaskResult:
@ -390,32 +390,32 @@ async def test_session_experimental_cancel_task() -> None:
@server.experimental.get_task()
async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
app = server.request_context.lifespan_context
task = await app.store.get_task(request.params.taskId)
assert task is not None, f"Test setup error: task {request.params.taskId} should exist"
task = await app.store.get_task(request.params.task_id)
assert task is not None, f"Test setup error: task {request.params.task_id} should exist"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=task.pollInterval,
poll_interval=task.poll_interval,
)
@server.experimental.cancel_task()
async def handle_cancel_task(request: CancelTaskRequest) -> CancelTaskResult:
app = server.request_context.lifespan_context
task = await app.store.get_task(request.params.taskId)
assert task is not None, f"Test setup error: task {request.params.taskId} should exist"
await app.store.update_task(request.params.taskId, status="cancelled")
task = await app.store.get_task(request.params.task_id)
assert task is not None, f"Test setup error: task {request.params.task_id} should exist"
await app.store.update_task(request.params.task_id, status="cancelled")
# CancelTaskResult extends Task, so we need to return the updated task info
updated_task = await app.store.get_task(request.params.taskId)
updated_task = await app.store.get_task(request.params.task_id)
assert updated_task is not None
return CancelTaskResult(
taskId=updated_task.taskId,
task_id=updated_task.task_id,
status=updated_task.status,
createdAt=updated_task.createdAt,
lastUpdatedAt=updated_task.lastUpdatedAt,
created_at=updated_task.created_at,
last_updated_at=updated_task.last_updated_at,
ttl=updated_task.ttl,
)
@ -467,7 +467,7 @@ async def test_session_experimental_cancel_task() -> None:
),
CreateTaskResult,
)
task_id = create_result.task.taskId
task_id = create_result.task.task_id
# Verify task is working
status_before = await client_session.experimental.get_task(task_id)

View file

@ -15,8 +15,8 @@ async def test_task_context_properties() -> None:
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
ctx = TaskContext(task, store)
assert ctx.task_id == task.taskId
assert ctx.task.taskId == task.taskId
assert ctx.task_id == task.task_id
assert ctx.task.task_id == task.task_id
assert ctx.task.status == "working"
assert ctx.is_cancelled is False
@ -33,9 +33,9 @@ async def test_task_context_update_status() -> None:
await ctx.update_status("Processing step 1...")
# Check status message was updated
updated = await store.get_task(task.taskId)
updated = await store.get_task(task.task_id)
assert updated is not None
assert updated.statusMessage == "Processing step 1..."
assert updated.status_message == "Processing step 1..."
store.cleanup()
@ -51,12 +51,12 @@ async def test_task_context_complete() -> None:
await ctx.complete(result)
# Check task status
updated = await store.get_task(task.taskId)
updated = await store.get_task(task.task_id)
assert updated is not None
assert updated.status == "completed"
# Check result is stored
stored_result = await store.get_result(task.taskId)
stored_result = await store.get_result(task.task_id)
assert stored_result is not None
store.cleanup()
@ -72,10 +72,10 @@ async def test_task_context_fail() -> None:
await ctx.fail("Something went wrong!")
# Check task status
updated = await store.get_task(task.taskId)
updated = await store.get_task(task.task_id)
assert updated is not None
assert updated.status == "failed"
assert updated.statusMessage == "Something went wrong!"
assert updated.status_message == "Something went wrong!"
store.cleanup()
@ -101,13 +101,13 @@ def test_create_task_state_generates_id() -> None:
task1 = create_task_state(TaskMetadata(ttl=60000))
task2 = create_task_state(TaskMetadata(ttl=60000))
assert task1.taskId != task2.taskId
assert task1.task_id != task2.task_id
def test_create_task_state_uses_provided_id() -> None:
"""create_task_state uses the provided task ID."""
task = create_task_state(TaskMetadata(ttl=60000), task_id="my-task-123")
assert task.taskId == "my-task-123"
assert task.task_id == "my-task-123"
def test_create_task_state_null_ttl() -> None:
@ -119,7 +119,7 @@ def test_create_task_state_null_ttl() -> None:
def test_create_task_state_has_created_at() -> None:
"""create_task_state sets createdAt timestamp."""
task = create_task_state(TaskMetadata(ttl=60000))
assert task.createdAt is not None
assert task.created_at is not None
@pytest.mark.anyio
@ -148,7 +148,7 @@ async def test_task_execution_auto_fails_on_exception() -> None:
failed_task = await store.get_task("exec-fail-1")
assert failed_task is not None
assert failed_task.status == "failed"
assert "Oops!" in (failed_task.statusMessage or "")
assert "Oops!" in (failed_task.status_message or "")
store.cleanup()

View file

@ -81,11 +81,11 @@ async def test_task_lifecycle_with_task_execution() -> None:
Tool(
name="process_data",
description="Process data asynchronously",
inputSchema={
input_schema={
"type": "object",
"properties": {"input": {"type": "string"}},
},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -101,11 +101,11 @@ async def test_task_lifecycle_with_task_execution() -> None:
# 2. Create event to signal completion (for testing)
done_event = Event()
app.task_done_events[task.taskId] = done_event
app.task_done_events[task.task_id] = done_event
# 3. Define work function using task_execution for safety
async def do_work():
async with task_execution(task.taskId, app.store) as task_ctx:
async with task_execution(task.task_id, app.store) as task_ctx:
await task_ctx.update_status("Processing input...")
# Simulate work
input_value = arguments.get("input", "")
@ -126,16 +126,16 @@ async def test_task_lifecycle_with_task_execution() -> None:
@server.experimental.get_task()
async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
app = server.request_context.lifespan_context
task = await app.store.get_task(request.params.taskId)
assert task is not None, f"Test setup error: task {request.params.taskId} should exist"
task = await app.store.get_task(request.params.task_id)
assert task is not None, f"Test setup error: task {request.params.task_id} should exist"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=task.pollInterval,
poll_interval=task.poll_interval,
)
@server.experimental.get_task_result()
@ -143,8 +143,8 @@ async def test_task_lifecycle_with_task_execution() -> None:
request: GetTaskPayloadRequest,
) -> GetTaskPayloadResult:
app = server.request_context.lifespan_context
result = await app.store.get_result(request.params.taskId)
assert result is not None, f"Test setup error: result for {request.params.taskId} should exist"
result = await app.store.get_result(request.params.task_id)
assert result is not None, f"Test setup error: result for {request.params.task_id} should exist"
assert isinstance(result, CallToolResult)
# Return as GetTaskPayloadResult (which accepts extra fields)
return GetTaskPayloadResult(**result.model_dump())
@ -205,22 +205,22 @@ async def test_task_lifecycle_with_task_execution() -> None:
assert isinstance(create_result, CreateTaskResult)
assert create_result.task.status == "working"
task_id = create_result.task.taskId
task_id = create_result.task.task_id
# === Step 2: Wait for task to complete ===
await app_context.task_done_events[task_id].wait()
task_status = await client_session.send_request(
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(taskId=task_id))),
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(task_id=task_id))),
GetTaskResult,
)
assert task_status.taskId == task_id
assert task_status.task_id == task_id
assert task_status.status == "completed"
# === Step 3: Retrieve the actual result ===
task_result = await client_session.send_request(
ClientRequest(GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=task_id))),
ClientRequest(GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=task_id))),
CallToolResult,
)
@ -245,7 +245,7 @@ async def test_task_auto_fails_on_exception() -> None:
Tool(
name="failing_task",
description="A task that fails",
inputSchema={"type": "object", "properties": {}},
input_schema={"type": "object", "properties": {}},
)
]
@ -260,10 +260,10 @@ async def test_task_auto_fails_on_exception() -> None:
# Create event to signal completion (for testing)
done_event = Event()
app.task_done_events[task.taskId] = done_event
app.task_done_events[task.task_id] = done_event
async def do_failing_work():
async with task_execution(task.taskId, app.store) as task_ctx:
async with task_execution(task.task_id, app.store) as task_ctx:
await task_ctx.update_status("About to fail...")
raise RuntimeError("Something went wrong!")
# Note: complete() is never called, but task_execution
@ -279,16 +279,16 @@ async def test_task_auto_fails_on_exception() -> None:
@server.experimental.get_task()
async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
app = server.request_context.lifespan_context
task = await app.store.get_task(request.params.taskId)
assert task is not None, f"Test setup error: task {request.params.taskId} should exist"
task = await app.store.get_task(request.params.task_id)
assert task is not None, f"Test setup error: task {request.params.task_id} should exist"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=task.pollInterval,
poll_interval=task.poll_interval,
)
# Set up streams
@ -340,18 +340,18 @@ async def test_task_auto_fails_on_exception() -> None:
CreateTaskResult,
)
task_id = create_result.task.taskId
task_id = create_result.task.task_id
# Wait for task to complete (even though it fails)
await app_context.task_done_events[task_id].wait()
# Check that task was auto-failed
task_status = await client_session.send_request(
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(taskId=task_id))),
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(task_id=task_id))),
GetTaskResult,
)
assert task_status.status == "failed"
assert task_status.statusMessage == "Something went wrong!"
assert task_status.status_message == "Something went wrong!"
tg.cancel_scope.cancel()

View file

@ -69,8 +69,8 @@ async def test_run_task_basic_flow() -> None:
Tool(
name="simple_task",
description="A simple task",
inputSchema={"type": "object", "properties": {"input": {"type": "string"}}},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object", "properties": {"input": {"type": "string"}}},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -119,7 +119,7 @@ async def test_run_task_basic_flow() -> None:
)
# Should get CreateTaskResult
task_id = result.task.taskId
task_id = result.task.task_id
assert result.task.status == "working"
# Wait for work to complete
@ -157,8 +157,8 @@ async def test_run_task_auto_fails_on_exception() -> None:
Tool(
name="failing_task",
description="A task that fails",
inputSchema={"type": "object"},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object"},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -188,7 +188,7 @@ async def test_run_task_auto_fails_on_exception() -> None:
await client_session.initialize()
result = await client_session.experimental.call_tool_as_task("failing_task", {})
task_id = result.task.taskId
task_id = result.task.task_id
# Wait for work to fail
with anyio.fail_after(5):
@ -201,7 +201,7 @@ async def test_run_task_auto_fails_on_exception() -> None:
if task_status.status == "failed": # pragma: no branch
break
assert "Something went wrong" in (task_status.statusMessage or "")
assert "Something went wrong" in (task_status.status_message or "")
async with anyio.create_task_group() as tg:
tg.start_soon(run_server)
@ -363,8 +363,8 @@ async def test_run_task_with_model_immediate_response() -> None:
Tool(
name="task_with_immediate",
description="A task with immediate response",
inputSchema={"type": "object"},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object"},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -422,8 +422,8 @@ async def test_run_task_doesnt_complete_if_already_terminal() -> None:
Tool(
name="manual_complete_task",
description="A task that manually completes",
inputSchema={"type": "object"},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object"},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -457,7 +457,7 @@ async def test_run_task_doesnt_complete_if_already_terminal() -> None:
await client_session.initialize()
result = await client_session.experimental.call_tool_as_task("manual_complete_task", {})
task_id = result.task.taskId
task_id = result.task.task_id
with anyio.fail_after(5):
await work_completed.wait()
@ -488,8 +488,8 @@ async def test_run_task_doesnt_fail_if_already_terminal() -> None:
Tool(
name="manual_cancel_task",
description="A task that manually cancels then raises",
inputSchema={"type": "object"},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object"},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -522,7 +522,7 @@ async def test_run_task_doesnt_fail_if_already_terminal() -> None:
await client_session.initialize()
result = await client_session.experimental.call_tool_as_task("manual_cancel_task", {})
task_id = result.task.taskId
task_id = result.task.task_id
with anyio.fail_after(5):
await work_completed.wait()
@ -535,7 +535,7 @@ async def test_run_task_doesnt_fail_if_already_terminal() -> None:
break
# Task should still be failed (from manual fail, not auto-fail from exception)
assert status.statusMessage == "Manually failed" # Not "This error should not change status"
assert status.status_message == "Manually failed" # Not "This error should not change status"
async with anyio.create_task_group() as tg:
tg.start_soon(run_server)

View file

@ -64,20 +64,20 @@ async def test_list_tasks_handler() -> None:
now = datetime.now(timezone.utc)
test_tasks = [
Task(
taskId="task-1",
task_id="task-1",
status="working",
createdAt=now,
lastUpdatedAt=now,
created_at=now,
last_updated_at=now,
ttl=60000,
pollInterval=1000,
poll_interval=1000,
),
Task(
taskId="task-2",
task_id="task-2",
status="completed",
createdAt=now,
lastUpdatedAt=now,
created_at=now,
last_updated_at=now,
ttl=60000,
pollInterval=1000,
poll_interval=1000,
),
]
@ -92,8 +92,8 @@ async def test_list_tasks_handler() -> None:
assert isinstance(result, ServerResult)
assert isinstance(result.root, ListTasksResult)
assert len(result.root.tasks) == 2
assert result.root.tasks[0].taskId == "task-1"
assert result.root.tasks[1].taskId == "task-2"
assert result.root.tasks[0].task_id == "task-1"
assert result.root.tasks[1].task_id == "task-2"
@pytest.mark.anyio
@ -105,24 +105,24 @@ async def test_get_task_handler() -> None:
async def handle_get_task(request: GetTaskRequest) -> GetTaskResult:
now = datetime.now(timezone.utc)
return GetTaskResult(
taskId=request.params.taskId,
task_id=request.params.task_id,
status="working",
createdAt=now,
lastUpdatedAt=now,
created_at=now,
last_updated_at=now,
ttl=60000,
pollInterval=1000,
poll_interval=1000,
)
handler = server.request_handlers[GetTaskRequest]
request = GetTaskRequest(
method="tasks/get",
params=GetTaskRequestParams(taskId="test-task-123"),
params=GetTaskRequestParams(task_id="test-task-123"),
)
result = await handler(request)
assert isinstance(result, ServerResult)
assert isinstance(result.root, GetTaskResult)
assert result.root.taskId == "test-task-123"
assert result.root.task_id == "test-task-123"
assert result.root.status == "working"
@ -138,7 +138,7 @@ async def test_get_task_result_handler() -> None:
handler = server.request_handlers[GetTaskPayloadRequest]
request = GetTaskPayloadRequest(
method="tasks/result",
params=GetTaskPayloadRequestParams(taskId="test-task-123"),
params=GetTaskPayloadRequestParams(task_id="test-task-123"),
)
result = await handler(request)
@ -155,23 +155,23 @@ async def test_cancel_task_handler() -> None:
async def handle_cancel_task(request: CancelTaskRequest) -> CancelTaskResult:
now = datetime.now(timezone.utc)
return CancelTaskResult(
taskId=request.params.taskId,
task_id=request.params.task_id,
status="cancelled",
createdAt=now,
lastUpdatedAt=now,
created_at=now,
last_updated_at=now,
ttl=60000,
)
handler = server.request_handlers[CancelTaskRequest]
request = CancelTaskRequest(
method="tasks/cancel",
params=CancelTaskRequestParams(taskId="test-task-123"),
params=CancelTaskRequestParams(task_id="test-task-123"),
)
result = await handler(request)
assert isinstance(result, ServerResult)
assert isinstance(result.root, CancelTaskResult)
assert result.root.taskId == "test-task-123"
assert result.root.task_id == "test-task-123"
assert result.root.status == "cancelled"
@ -232,20 +232,20 @@ async def test_tool_with_task_execution_metadata() -> None:
Tool(
name="quick_tool",
description="Fast tool",
inputSchema={"type": "object", "properties": {}},
execution=ToolExecution(taskSupport=TASK_FORBIDDEN),
input_schema={"type": "object", "properties": {}},
execution=ToolExecution(task_support=TASK_FORBIDDEN),
),
Tool(
name="long_tool",
description="Long running tool",
inputSchema={"type": "object", "properties": {}},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object", "properties": {}},
execution=ToolExecution(task_support=TASK_REQUIRED),
),
Tool(
name="flexible_tool",
description="Can be either",
inputSchema={"type": "object", "properties": {}},
execution=ToolExecution(taskSupport=TASK_OPTIONAL),
input_schema={"type": "object", "properties": {}},
execution=ToolExecution(task_support=TASK_OPTIONAL),
),
]
@ -258,11 +258,11 @@ async def test_tool_with_task_execution_metadata() -> None:
tools = result.root.tools
assert tools[0].execution is not None
assert tools[0].execution.taskSupport == TASK_FORBIDDEN
assert tools[0].execution.task_support == TASK_FORBIDDEN
assert tools[1].execution is not None
assert tools[1].execution.taskSupport == TASK_REQUIRED
assert tools[1].execution.task_support == TASK_REQUIRED
assert tools[2].execution is not None
assert tools[2].execution.taskSupport == TASK_OPTIONAL
assert tools[2].execution.task_support == TASK_OPTIONAL
@pytest.mark.anyio
@ -277,8 +277,8 @@ async def test_task_metadata_in_call_tool_request() -> None:
Tool(
name="long_task",
description="A long running task",
inputSchema={"type": "object", "properties": {}},
execution=ToolExecution(taskSupport="optional"),
input_schema={"type": "object", "properties": {}},
execution=ToolExecution(task_support="optional"),
)
]
@ -361,7 +361,7 @@ async def test_task_metadata_is_task_property() -> None:
Tool(
name="test_tool",
description="Test tool",
inputSchema={"type": "object", "properties": {}},
input_schema={"type": "object", "properties": {}},
)
]
@ -513,33 +513,35 @@ async def test_default_task_handlers_via_enable_tasks() -> None:
ListTasksResult,
)
assert len(list_result.tasks) == 1
assert list_result.tasks[0].taskId == task.taskId
assert list_result.tasks[0].task_id == task.task_id
# Test get_task (default handler - found)
get_result = await client_session.send_request(
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(taskId=task.taskId))),
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(task_id=task.task_id))),
GetTaskResult,
)
assert get_result.taskId == task.taskId
assert get_result.task_id == task.task_id
assert get_result.status == "working"
# Test get_task (default handler - not found path)
with pytest.raises(McpError, match="not found"):
await client_session.send_request(
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(taskId="nonexistent-task"))),
ClientRequest(GetTaskRequest(params=GetTaskRequestParams(task_id="nonexistent-task"))),
GetTaskResult,
)
# Create a completed task to test get_task_result
completed_task = await store.create_task(TaskMetadata(ttl=60000))
await store.store_result(
completed_task.taskId, CallToolResult(content=[TextContent(type="text", text="Test result")])
completed_task.task_id, CallToolResult(content=[TextContent(type="text", text="Test result")])
)
await store.update_task(completed_task.taskId, status="completed")
await store.update_task(completed_task.task_id, status="completed")
# Test get_task_result (default handler)
payload_result = await client_session.send_request(
ClientRequest(GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=completed_task.taskId))),
ClientRequest(
GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=completed_task.task_id))
),
GetTaskPayloadResult,
)
# The result should have the related-task metadata
@ -548,10 +550,10 @@ async def test_default_task_handlers_via_enable_tasks() -> None:
# Test cancel_task (default handler)
cancel_result = await client_session.send_request(
ClientRequest(CancelTaskRequest(params=CancelTaskRequestParams(taskId=task.taskId))),
ClientRequest(CancelTaskRequest(params=CancelTaskRequestParams(task_id=task.task_id))),
CancelTaskResult,
)
assert cancel_result.taskId == task.taskId
assert cancel_result.task_id == task.task_id
assert cancel_result.status == "cancelled"
tg.cancel_scope.cancel()
@ -576,7 +578,7 @@ async def test_build_elicit_form_request() -> None:
# Test without task_id
request = server_session._build_elicit_form_request(
message="Test message",
requestedSchema={"type": "object", "properties": {"answer": {"type": "string"}}},
requested_schema={"type": "object", "properties": {"answer": {"type": "string"}}},
)
assert request.method == "elicitation/create"
assert request.params is not None
@ -585,7 +587,7 @@ async def test_build_elicit_form_request() -> None:
# Test with related_task_id (adds related-task metadata)
request_with_task = server_session._build_elicit_form_request(
message="Task message",
requestedSchema={"type": "object"},
requested_schema={"type": "object"},
related_task_id="test-task-123",
)
assert request_with_task.method == "elicitation/create"

View file

@ -45,7 +45,7 @@ async def test_server_task_context_properties() -> None:
)
assert ctx.task_id == "test-123"
assert ctx.task.taskId == "test-123"
assert ctx.task.task_id == "test-123"
assert ctx.is_cancelled is False
store.cleanup()
@ -181,7 +181,7 @@ async def test_elicit_raises_when_client_lacks_capability() -> None:
)
with pytest.raises(McpError) as exc_info:
await ctx.elicit(message="Test?", requestedSchema={"type": "object"})
await ctx.elicit(message="Test?", requested_schema={"type": "object"})
assert "elicitation capability" in exc_info.value.error.message
mock_session.check_client_capability.assert_called_once()
@ -232,7 +232,7 @@ async def test_elicit_raises_without_handler() -> None:
)
with pytest.raises(RuntimeError, match="handler is required"):
await ctx.elicit(message="Test?", requestedSchema={"type": "object"})
await ctx.elicit(message="Test?", requested_schema={"type": "object"})
store.cleanup()
@ -320,22 +320,22 @@ async def test_elicit_queues_request_and_waits_for_response() -> None:
nonlocal elicit_result
elicit_result = await ctx.elicit(
message="Test?",
requestedSchema={"type": "object"},
requested_schema={"type": "object"},
)
async with anyio.create_task_group() as tg:
tg.start_soon(run_elicit)
# Wait for request to be queued
await queue.wait_for_message(task.taskId)
await queue.wait_for_message(task.task_id)
# Verify task is in input_required status
updated_task = await store.get_task(task.taskId)
updated_task = await store.get_task(task.task_id)
assert updated_task is not None
assert updated_task.status == "input_required"
# Dequeue and simulate response
msg = await queue.dequeue(task.taskId)
msg = await queue.dequeue(task.task_id)
assert msg is not None
assert msg.resolver is not None
@ -348,7 +348,7 @@ async def test_elicit_queues_request_and_waits_for_response() -> None:
assert elicit_result.content == {"name": "Alice"}
# Verify task is back to working
final_task = await store.get_task(task.taskId)
final_task = await store.get_task(task.task_id)
assert final_task is not None
assert final_task.status == "working"
@ -396,15 +396,15 @@ async def test_elicit_url_queues_request_and_waits_for_response() -> None:
tg.start_soon(run_elicit_url)
# Wait for request to be queued
await queue.wait_for_message(task.taskId)
await queue.wait_for_message(task.task_id)
# Verify task is in input_required status
updated_task = await store.get_task(task.taskId)
updated_task = await store.get_task(task.task_id)
assert updated_task is not None
assert updated_task.status == "input_required"
# Dequeue and simulate response
msg = await queue.dequeue(task.taskId)
msg = await queue.dequeue(task.task_id)
assert msg is not None
assert msg.resolver is not None
@ -416,7 +416,7 @@ async def test_elicit_url_queues_request_and_waits_for_response() -> None:
assert elicit_result.action == "accept"
# Verify task is back to working
final_task = await store.get_task(task.taskId)
final_task = await store.get_task(task.task_id)
assert final_task is not None
assert final_task.status == "working"
@ -463,15 +463,15 @@ async def test_create_message_queues_request_and_waits_for_response() -> None:
tg.start_soon(run_sampling)
# Wait for request to be queued
await queue.wait_for_message(task.taskId)
await queue.wait_for_message(task.task_id)
# Verify task is in input_required status
updated_task = await store.get_task(task.taskId)
updated_task = await store.get_task(task.task_id)
assert updated_task is not None
assert updated_task.status == "input_required"
# Dequeue and simulate response
msg = await queue.dequeue(task.taskId)
msg = await queue.dequeue(task.task_id)
assert msg is not None
assert msg.resolver is not None
@ -491,7 +491,7 @@ async def test_create_message_queues_request_and_waits_for_response() -> None:
assert sampling_result.model == "test-model"
# Verify task is back to working
final_task = await store.get_task(task.taskId)
final_task = await store.get_task(task.task_id)
assert final_task is not None
assert final_task.status == "working"
@ -534,7 +534,7 @@ async def test_elicit_restores_status_on_cancellation() -> None:
try:
await ctx.elicit(
message="Test?",
requestedSchema={"type": "object"},
requested_schema={"type": "object"},
)
except anyio.get_cancelled_exc_class():
cancelled_error_raised = True
@ -543,15 +543,15 @@ async def test_elicit_restores_status_on_cancellation() -> None:
tg.start_soon(do_elicit)
# Wait for request to be queued
await queue.wait_for_message(task.taskId)
await queue.wait_for_message(task.task_id)
# Verify task is in input_required status
updated_task = await store.get_task(task.taskId)
updated_task = await store.get_task(task.task_id)
assert updated_task is not None
assert updated_task.status == "input_required"
# Get the queued message and set cancellation exception on its resolver
msg = await queue.dequeue(task.taskId)
msg = await queue.dequeue(task.task_id)
assert msg is not None
assert msg.resolver is not None
@ -559,7 +559,7 @@ async def test_elicit_restores_status_on_cancellation() -> None:
msg.resolver.set_exception(asyncio.CancelledError())
# Verify task is back to working after cancellation
final_task = await store.get_task(task.taskId)
final_task = await store.get_task(task.task_id)
assert final_task is not None
assert final_task.status == "working"
assert cancelled_error_raised
@ -612,15 +612,15 @@ async def test_create_message_restores_status_on_cancellation() -> None:
tg.start_soon(do_sampling)
# Wait for request to be queued
await queue.wait_for_message(task.taskId)
await queue.wait_for_message(task.task_id)
# Verify task is in input_required status
updated_task = await store.get_task(task.taskId)
updated_task = await store.get_task(task.task_id)
assert updated_task is not None
assert updated_task.status == "input_required"
# Get the queued message and set cancellation exception on its resolver
msg = await queue.dequeue(task.taskId)
msg = await queue.dequeue(task.task_id)
assert msg is not None
assert msg.resolver is not None
@ -628,7 +628,7 @@ async def test_create_message_restores_status_on_cancellation() -> None:
msg.resolver.set_exception(asyncio.CancelledError())
# Verify task is back to working after cancellation
final_task = await store.get_task(task.taskId)
final_task = await store.get_task(task.task_id)
assert final_task is not None
assert final_task.status == "working"
assert cancelled_error_raised
@ -646,7 +646,7 @@ async def test_elicit_as_task_raises_without_handler() -> None:
# Create mock session with proper client capabilities
mock_session = Mock()
mock_session.client_params = InitializeRequestParams(
protocolVersion="2025-01-01",
protocol_version="2025-01-01",
capabilities=ClientCapabilities(
tasks=ClientTasksCapability(
requests=ClientTasksRequestsCapability(
@ -654,7 +654,7 @@ async def test_elicit_as_task_raises_without_handler() -> None:
)
)
),
clientInfo=Implementation(name="test", version="1.0"),
client_info=Implementation(name="test", version="1.0"),
)
ctx = ServerTaskContext(
@ -666,7 +666,7 @@ async def test_elicit_as_task_raises_without_handler() -> None:
)
with pytest.raises(RuntimeError, match="handler is required for elicit_as_task"):
await ctx.elicit_as_task(message="Test?", requestedSchema={"type": "object"})
await ctx.elicit_as_task(message="Test?", requested_schema={"type": "object"})
store.cleanup()
@ -681,15 +681,15 @@ async def test_create_message_as_task_raises_without_handler() -> None:
# Create mock session with proper client capabilities
mock_session = Mock()
mock_session.client_params = InitializeRequestParams(
protocolVersion="2025-01-01",
protocol_version="2025-01-01",
capabilities=ClientCapabilities(
tasks=ClientTasksCapability(
requests=ClientTasksRequestsCapability(
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability())
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability())
)
)
),
clientInfo=Implementation(name="test", version="1.0"),
client_info=Implementation(name="test", version="1.0"),
)
ctx = ServerTaskContext(

View file

@ -24,13 +24,13 @@ async def test_create_and_get(store: InMemoryTaskStore) -> None:
"""Test InMemoryTaskStore create and get operations."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
assert task.taskId is not None
assert task.task_id is not None
assert task.status == "working"
assert task.ttl == 60000
retrieved = await store.get_task(task.taskId)
retrieved = await store.get_task(task.task_id)
assert retrieved is not None
assert retrieved.taskId == task.taskId
assert retrieved.task_id == task.task_id
assert retrieved.status == "working"
@ -42,12 +42,12 @@ async def test_create_with_custom_id(store: InMemoryTaskStore) -> None:
task_id="my-custom-id",
)
assert task.taskId == "my-custom-id"
assert task.task_id == "my-custom-id"
assert task.status == "working"
retrieved = await store.get_task("my-custom-id")
assert retrieved is not None
assert retrieved.taskId == "my-custom-id"
assert retrieved.task_id == "my-custom-id"
@pytest.mark.anyio
@ -71,15 +71,15 @@ async def test_update_status(store: InMemoryTaskStore) -> None:
"""Test InMemoryTaskStore status updates."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
updated = await store.update_task(task.taskId, status="completed", status_message="All done!")
updated = await store.update_task(task.task_id, status="completed", status_message="All done!")
assert updated.status == "completed"
assert updated.statusMessage == "All done!"
assert updated.status_message == "All done!"
retrieved = await store.get_task(task.taskId)
retrieved = await store.get_task(task.task_id)
assert retrieved is not None
assert retrieved.status == "completed"
assert retrieved.statusMessage == "All done!"
assert retrieved.status_message == "All done!"
@pytest.mark.anyio
@ -96,10 +96,10 @@ async def test_store_and_get_result(store: InMemoryTaskStore) -> None:
# Store result
result = CallToolResult(content=[TextContent(type="text", text="Result data")])
await store.store_result(task.taskId, result)
await store.store_result(task.task_id, result)
# Retrieve result
retrieved_result = await store.get_result(task.taskId)
retrieved_result = await store.get_result(task.task_id)
assert retrieved_result == result
@ -114,7 +114,7 @@ async def test_get_result_nonexistent_returns_none(store: InMemoryTaskStore) ->
async def test_get_result_no_result_returns_none(store: InMemoryTaskStore) -> None:
"""Test that getting result when none stored returns None."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
result = await store.get_result(task.taskId)
result = await store.get_result(task.task_id)
assert result is None
@ -172,14 +172,14 @@ async def test_delete_task(store: InMemoryTaskStore) -> None:
"""Test InMemoryTaskStore delete operation."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
deleted = await store.delete_task(task.taskId)
deleted = await store.delete_task(task.task_id)
assert deleted is True
retrieved = await store.get_task(task.taskId)
retrieved = await store.get_task(task.task_id)
assert retrieved is None
# Delete non-existent
deleted = await store.delete_task(task.taskId)
deleted = await store.delete_task(task.task_id)
assert deleted is False
@ -210,7 +210,7 @@ async def test_create_task_with_null_ttl(store: InMemoryTaskStore) -> None:
assert task.ttl is None
# Task should persist (not expire)
retrieved = await store.get_task(task.taskId)
retrieved = await store.get_task(task.task_id)
assert retrieved is not None
@ -221,19 +221,19 @@ async def test_task_expiration_cleanup(store: InMemoryTaskStore) -> None:
task = await store.create_task(metadata=TaskMetadata(ttl=1)) # 1ms TTL
# Manually force the expiry to be in the past
stored = store._tasks.get(task.taskId)
stored = store._tasks.get(task.task_id)
assert stored is not None
stored.expires_at = datetime.now(timezone.utc) - timedelta(seconds=10)
# Task should still exist in internal dict but be expired
assert task.taskId in store._tasks
assert task.task_id in store._tasks
# Any access operation should clean up expired tasks
# list_tasks triggers cleanup
tasks, _ = await store.list_tasks()
# Expired task should be cleaned up
assert task.taskId not in store._tasks
assert task.task_id not in store._tasks
assert len(tasks) == 0
@ -244,17 +244,17 @@ async def test_task_with_null_ttl_never_expires(store: InMemoryTaskStore) -> Non
task = await store.create_task(metadata=TaskMetadata(ttl=None))
# Verify internal storage has no expiry
stored = store._tasks.get(task.taskId)
stored = store._tasks.get(task.task_id)
assert stored is not None
assert stored.expires_at is None
# Access operations should NOT remove this task
await store.list_tasks()
await store.get_task(task.taskId)
await store.get_task(task.task_id)
# Task should still exist
assert task.taskId in store._tasks
retrieved = await store.get_task(task.taskId)
assert task.task_id in store._tasks
retrieved = await store.get_task(task.task_id)
assert retrieved is not None
@ -265,13 +265,13 @@ async def test_terminal_task_ttl_reset(store: InMemoryTaskStore) -> None:
task = await store.create_task(metadata=TaskMetadata(ttl=60000)) # 60s
# Get the initial expiry
stored = store._tasks.get(task.taskId)
stored = store._tasks.get(task.task_id)
assert stored is not None
initial_expiry = stored.expires_at
assert initial_expiry is not None
# Update to terminal state (completed)
await store.update_task(task.taskId, status="completed")
await store.update_task(task.task_id, status="completed")
# Expiry should be reset to a new time (from now + TTL)
new_expiry = stored.expires_at
@ -291,16 +291,16 @@ async def test_terminal_status_transition_rejected(store: InMemoryTaskStore) ->
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
# Move to terminal state
await store.update_task(task.taskId, status=terminal_status)
await store.update_task(task.task_id, status=terminal_status)
# Attempting to transition to any other status should raise
with pytest.raises(ValueError, match="Cannot transition from terminal status"):
await store.update_task(task.taskId, status="working")
await store.update_task(task.task_id, status="working")
# Also test transitioning to another terminal state
other_terminal = "failed" if terminal_status != "failed" else "completed"
with pytest.raises(ValueError, match="Cannot transition from terminal status"):
await store.update_task(task.taskId, status=other_terminal)
await store.update_task(task.task_id, status=other_terminal)
@pytest.mark.anyio
@ -310,15 +310,15 @@ async def test_terminal_status_allows_same_status(store: InMemoryTaskStore) -> N
This is not a transition, so it should be allowed (no-op).
"""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
await store.update_task(task.taskId, status="completed")
await store.update_task(task.task_id, status="completed")
# Setting the same status should not raise
updated = await store.update_task(task.taskId, status="completed")
updated = await store.update_task(task.task_id, status="completed")
assert updated.status == "completed"
# Updating just the message should also work
updated = await store.update_task(task.taskId, status_message="Updated message")
assert updated.statusMessage == "Updated message"
updated = await store.update_task(task.task_id, status_message="Updated message")
assert updated.status_message == "Updated message"
@pytest.mark.anyio
@ -334,13 +334,13 @@ async def test_cancel_task_succeeds_for_working_task(store: InMemoryTaskStore) -
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
assert task.status == "working"
result = await cancel_task(store, task.taskId)
result = await cancel_task(store, task.task_id)
assert result.taskId == task.taskId
assert result.task_id == task.task_id
assert result.status == "cancelled"
# Verify store is updated
retrieved = await store.get_task(task.taskId)
retrieved = await store.get_task(task.task_id)
assert retrieved is not None
assert retrieved.status == "cancelled"
@ -359,10 +359,10 @@ async def test_cancel_task_rejects_nonexistent_task(store: InMemoryTaskStore) ->
async def test_cancel_task_rejects_completed_task(store: InMemoryTaskStore) -> None:
"""Test cancel_task raises McpError with INVALID_PARAMS for completed task."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
await store.update_task(task.taskId, status="completed")
await store.update_task(task.task_id, status="completed")
with pytest.raises(McpError) as exc_info:
await cancel_task(store, task.taskId)
await cancel_task(store, task.task_id)
assert exc_info.value.error.code == INVALID_PARAMS
assert "terminal state 'completed'" in exc_info.value.error.message
@ -372,10 +372,10 @@ async def test_cancel_task_rejects_completed_task(store: InMemoryTaskStore) -> N
async def test_cancel_task_rejects_failed_task(store: InMemoryTaskStore) -> None:
"""Test cancel_task raises McpError with INVALID_PARAMS for failed task."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
await store.update_task(task.taskId, status="failed")
await store.update_task(task.task_id, status="failed")
with pytest.raises(McpError) as exc_info:
await cancel_task(store, task.taskId)
await cancel_task(store, task.task_id)
assert exc_info.value.error.code == INVALID_PARAMS
assert "terminal state 'failed'" in exc_info.value.error.message
@ -385,10 +385,10 @@ async def test_cancel_task_rejects_failed_task(store: InMemoryTaskStore) -> None
async def test_cancel_task_rejects_already_cancelled_task(store: InMemoryTaskStore) -> None:
"""Test cancel_task raises McpError with INVALID_PARAMS for already cancelled task."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
await store.update_task(task.taskId, status="cancelled")
await store.update_task(task.task_id, status="cancelled")
with pytest.raises(McpError) as exc_info:
await cancel_task(store, task.taskId)
await cancel_task(store, task.task_id)
assert exc_info.value.error.code == INVALID_PARAMS
assert "terminal state 'cancelled'" in exc_info.value.error.message
@ -398,9 +398,9 @@ async def test_cancel_task_rejects_already_cancelled_task(store: InMemoryTaskSto
async def test_cancel_task_succeeds_for_input_required_task(store: InMemoryTaskStore) -> None:
"""Test cancel_task helper succeeds for a task in input_required status."""
task = await store.create_task(metadata=TaskMetadata(ttl=60000))
await store.update_task(task.taskId, status="input_required")
await store.update_task(task.task_id, status="input_required")
result = await cancel_task(store, task.taskId)
result = await cancel_task(store, task.task_id)
assert result.taskId == task.taskId
assert result.task_id == task.task_id
assert result.status == "cancelled"

View file

@ -53,13 +53,13 @@ async def test_handle_returns_result_for_completed_task(
"""Test that handle() returns the stored result for a completed task."""
task = await store.create_task(TaskMetadata(ttl=60000), task_id="test-task")
result = CallToolResult(content=[TextContent(type="text", text="Done!")])
await store.store_result(task.taskId, result)
await store.update_task(task.taskId, status="completed")
await store.store_result(task.task_id, result)
await store.update_task(task.task_id, status="completed")
mock_session = Mock()
mock_session.send_message = AsyncMock()
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=task.taskId))
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=task.task_id))
response = await handler.handle(request, mock_session, "req-1")
assert response is not None
@ -73,7 +73,7 @@ async def test_handle_raises_for_nonexistent_task(
) -> None:
"""Test that handle() raises McpError for nonexistent task."""
mock_session = Mock()
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId="nonexistent"))
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id="nonexistent"))
with pytest.raises(McpError) as exc_info:
await handler.handle(request, mock_session, "req-1")
@ -87,12 +87,12 @@ async def test_handle_returns_empty_result_when_no_result_stored(
) -> None:
"""Test that handle() returns minimal result when task completed without stored result."""
task = await store.create_task(TaskMetadata(ttl=60000), task_id="test-task")
await store.update_task(task.taskId, status="completed")
await store.update_task(task.task_id, status="completed")
mock_session = Mock()
mock_session.send_message = AsyncMock()
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=task.taskId))
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=task.task_id))
response = await handler.handle(request, mock_session, "req-1")
assert response is not None
@ -116,8 +116,8 @@ async def test_handle_delivers_queued_messages(
params={},
),
)
await queue.enqueue(task.taskId, queued_msg)
await store.update_task(task.taskId, status="completed")
await queue.enqueue(task.task_id, queued_msg)
await store.update_task(task.task_id, status="completed")
sent_messages: list[SessionMessage] = []
@ -127,7 +127,7 @@ async def test_handle_delivers_queued_messages(
mock_session = Mock()
mock_session.send_message = track_send
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=task.taskId))
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=task.task_id))
await handler.handle(request, mock_session, "req-1")
assert len(sent_messages) == 1
@ -143,7 +143,7 @@ async def test_handle_waits_for_task_completion(
mock_session = Mock()
mock_session.send_message = AsyncMock()
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(taskId=task.taskId))
request = GetTaskPayloadRequest(params=GetTaskPayloadRequestParams(task_id=task.task_id))
result_holder: list[GetTaskPayloadResult | None] = [None]
async def run_handle() -> None:
@ -153,11 +153,11 @@ async def test_handle_waits_for_task_completion(
tg.start_soon(run_handle)
# Wait for handler to start waiting (event gets created when wait starts)
while task.taskId not in store._update_events:
while task.task_id not in store._update_events:
await anyio.sleep(0)
await store.store_result(task.taskId, CallToolResult(content=[TextContent(type="text", text="Done")]))
await store.update_task(task.taskId, status="completed")
await store.store_result(task.task_id, CallToolResult(content=[TextContent(type="text", text="Done")]))
await store.update_task(task.task_id, status="completed")
assert result_holder[0] is not None
@ -248,12 +248,12 @@ async def test_deliver_registers_resolver_for_request_messages(
resolver=resolver,
original_request_id="inner-req-1",
)
await queue.enqueue(task.taskId, queued_msg)
await queue.enqueue(task.task_id, queued_msg)
mock_session = Mock()
mock_session.send_message = AsyncMock()
await handler._deliver_queued_messages(task.taskId, mock_session, "outer-req-1")
await handler._deliver_queued_messages(task.task_id, mock_session, "outer-req-1")
assert "inner-req-1" in handler._pending_requests
assert handler._pending_requests["inner-req-1"] is resolver
@ -278,12 +278,12 @@ async def test_deliver_skips_resolver_registration_when_no_original_id(
resolver=resolver,
original_request_id=None, # No original request ID
)
await queue.enqueue(task.taskId, queued_msg)
await queue.enqueue(task.task_id, queued_msg)
mock_session = Mock()
mock_session.send_message = AsyncMock()
await handler._deliver_queued_messages(task.taskId, mock_session, "outer-req-1")
await handler._deliver_queued_messages(task.task_id, mock_session, "outer-req-1")
# Resolver should NOT be registered since original_request_id is None
assert len(handler._pending_requests) == 0
@ -307,10 +307,10 @@ async def test_wait_for_task_update_handles_store_exception(
# Queue a message to unblock the race via the queue path
async def enqueue_later() -> None:
# Wait for queue to start waiting (event gets created when wait starts)
while task.taskId not in queue._events:
while task.task_id not in queue._events:
await anyio.sleep(0)
await queue.enqueue(
task.taskId,
task.task_id,
QueuedMessage(
type="notification",
message=JSONRPCRequest(
@ -325,7 +325,7 @@ async def test_wait_for_task_update_handles_store_exception(
async with anyio.create_task_group() as tg:
tg.start_soon(enqueue_later)
# This should complete via the queue path even though store raises
await handler._wait_for_task_update(task.taskId)
await handler._wait_for_task_update(task.task_id)
@pytest.mark.anyio
@ -344,11 +344,11 @@ async def test_wait_for_task_update_handles_queue_exception(
# Update the store to unblock the race via the store path
async def update_later() -> None:
# Wait for store to start waiting (event gets created when wait starts)
while task.taskId not in store._update_events:
while task.task_id not in store._update_events:
await anyio.sleep(0)
await store.update_task(task.taskId, status="completed")
await store.update_task(task.task_id, status="completed")
async with anyio.create_task_group() as tg:
tg.start_soon(update_later)
# This should complete via the store path even though queue raises
await handler._wait_for_task_update(task.taskId)
await handler._wait_for_task_update(task.task_id)

View file

@ -82,7 +82,7 @@ class TestCheckTasksCapability:
"""When sampling.createMessage is required but client doesn't have it."""
required = ClientTasksCapability(
requests=ClientTasksRequestsCapability(
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability())
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability())
)
)
client = ClientTasksCapability(
@ -96,12 +96,12 @@ class TestCheckTasksCapability:
"""When sampling.createMessage is required and client has it."""
required = ClientTasksCapability(
requests=ClientTasksRequestsCapability(
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability())
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability())
)
)
client = ClientTasksCapability(
requests=ClientTasksRequestsCapability(
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability())
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability())
)
)
assert check_tasks_capability(required, client) is True
@ -111,13 +111,13 @@ class TestCheckTasksCapability:
required = ClientTasksCapability(
requests=ClientTasksRequestsCapability(
elicitation=TasksElicitationCapability(create=TasksCreateElicitationCapability()),
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability()),
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability()),
)
)
client = ClientTasksCapability(
requests=ClientTasksRequestsCapability(
elicitation=TasksElicitationCapability(create=TasksCreateElicitationCapability()),
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability()),
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability()),
)
)
assert check_tasks_capability(required, client) is True
@ -145,7 +145,7 @@ class TestCheckTasksCapability:
)
client = ClientTasksCapability(
requests=ClientTasksRequestsCapability(
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability())
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability())
)
)
assert check_tasks_capability(required, client) is True
@ -220,7 +220,7 @@ class TestHasTaskAugmentedSampling:
caps = ClientCapabilities(
tasks=ClientTasksCapability(
requests=ClientTasksRequestsCapability(
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability())
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability())
)
)
)
@ -276,7 +276,7 @@ class TestRequireTaskAugmentedSampling:
caps = ClientCapabilities(
tasks=ClientTasksCapability(
requests=ClientTasksRequestsCapability(
sampling=TasksSamplingCapability(createMessage=TasksCreateMessageCapability())
sampling=TasksSamplingCapability(create_message=TasksCreateMessageCapability())
)
)
)

View file

@ -61,13 +61,13 @@ def create_client_task_handlers(
"""Handle task-augmented elicitation by creating a client-side task."""
elicit_received.set()
task = await client_task_store.create_task(task_metadata)
task_complete_events[task.taskId] = Event()
task_complete_events[task.task_id] = Event()
async def complete_task() -> None:
# Store result before updating status to avoid race condition
await client_task_store.store_result(task.taskId, elicit_response)
await client_task_store.update_task(task.taskId, status="completed")
task_complete_events[task.taskId].set()
await client_task_store.store_result(task.task_id, elicit_response)
await client_task_store.update_task(task.task_id, status="completed")
task_complete_events[task.task_id].set()
context.session._task_group.start_soon(complete_task) # pyright: ignore[reportPrivateUsage]
return CreateTaskResult(task=task)
@ -77,16 +77,16 @@ def create_client_task_handlers(
params: Any,
) -> GetTaskResult:
"""Handle tasks/get from server."""
task = await client_task_store.get_task(params.taskId)
assert task is not None, f"Task not found: {params.taskId}"
task = await client_task_store.get_task(params.task_id)
assert task is not None, f"Task not found: {params.task_id}"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=100,
poll_interval=100,
)
async def handle_get_task_result(
@ -94,11 +94,11 @@ def create_client_task_handlers(
params: Any,
) -> GetTaskPayloadResult | ErrorData:
"""Handle tasks/result from server."""
event = task_complete_events.get(params.taskId)
assert event is not None, f"No completion event for task: {params.taskId}"
event = task_complete_events.get(params.task_id)
assert event is not None, f"No completion event for task: {params.task_id}"
await event.wait()
result = await client_task_store.get_result(params.taskId)
assert result is not None, f"Result not found for task: {params.taskId}"
result = await client_task_store.get_result(params.task_id)
assert result is not None, f"Result not found for task: {params.task_id}"
return GetTaskPayloadResult.model_validate(result.model_dump(by_alias=True))
return ExperimentalTaskHandlers(
@ -129,13 +129,13 @@ def create_sampling_task_handlers(
"""Handle task-augmented sampling by creating a client-side task."""
sampling_received.set()
task = await client_task_store.create_task(task_metadata)
task_complete_events[task.taskId] = Event()
task_complete_events[task.task_id] = Event()
async def complete_task() -> None:
# Store result before updating status to avoid race condition
await client_task_store.store_result(task.taskId, sampling_response)
await client_task_store.update_task(task.taskId, status="completed")
task_complete_events[task.taskId].set()
await client_task_store.store_result(task.task_id, sampling_response)
await client_task_store.update_task(task.task_id, status="completed")
task_complete_events[task.task_id].set()
context.session._task_group.start_soon(complete_task) # pyright: ignore[reportPrivateUsage]
return CreateTaskResult(task=task)
@ -145,16 +145,16 @@ def create_sampling_task_handlers(
params: Any,
) -> GetTaskResult:
"""Handle tasks/get from server."""
task = await client_task_store.get_task(params.taskId)
assert task is not None, f"Task not found: {params.taskId}"
task = await client_task_store.get_task(params.task_id)
assert task is not None, f"Task not found: {params.task_id}"
return GetTaskResult(
taskId=task.taskId,
task_id=task.task_id,
status=task.status,
statusMessage=task.statusMessage,
createdAt=task.createdAt,
lastUpdatedAt=task.lastUpdatedAt,
status_message=task.status_message,
created_at=task.created_at,
last_updated_at=task.last_updated_at,
ttl=task.ttl,
pollInterval=100,
poll_interval=100,
)
async def handle_get_task_result(
@ -162,11 +162,11 @@ def create_sampling_task_handlers(
params: Any,
) -> GetTaskPayloadResult | ErrorData:
"""Handle tasks/result from server."""
event = task_complete_events.get(params.taskId)
assert event is not None, f"No completion event for task: {params.taskId}"
event = task_complete_events.get(params.task_id)
assert event is not None, f"No completion event for task: {params.task_id}"
await event.wait()
result = await client_task_store.get_result(params.taskId)
assert result is not None, f"Result not found for task: {params.taskId}"
result = await client_task_store.get_result(params.task_id)
assert result is not None, f"Result not found for task: {params.task_id}"
return GetTaskPayloadResult.model_validate(result.model_dump(by_alias=True))
return ExperimentalTaskHandlers(
@ -193,7 +193,7 @@ async def test_scenario1_normal_tool_normal_elicitation() -> None:
Tool(
name="confirm_action",
description="Confirm an action",
inputSchema={"type": "object"},
input_schema={"type": "object"},
)
]
@ -204,7 +204,7 @@ async def test_scenario1_normal_tool_normal_elicitation() -> None:
# Normal elicitation - expects immediate response
result = await ctx.session.elicit(
message="Please confirm the action",
requestedSchema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
requested_schema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
)
confirmed = result.content.get("confirm", False) if result.content else False
@ -278,7 +278,7 @@ async def test_scenario2_normal_tool_task_augmented_elicitation() -> None:
Tool(
name="confirm_action",
description="Confirm an action",
inputSchema={"type": "object"},
input_schema={"type": "object"},
)
]
@ -289,7 +289,7 @@ async def test_scenario2_normal_tool_task_augmented_elicitation() -> None:
# Task-augmented elicitation - server polls client
result = await ctx.session.experimental.elicit_as_task(
message="Please confirm the action",
requestedSchema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
requested_schema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
ttl=60000,
)
@ -358,8 +358,8 @@ async def test_scenario3_task_augmented_tool_normal_elicitation() -> None:
Tool(
name="confirm_action",
description="Confirm an action",
inputSchema={"type": "object"},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object"},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -372,7 +372,7 @@ async def test_scenario3_task_augmented_tool_normal_elicitation() -> None:
# Normal elicitation within task - queued and delivered via tasks/result
result = await task.elicit(
message="Please confirm the action",
requestedSchema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
requested_schema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
)
confirmed = result.content.get("confirm", False) if result.content else False
@ -413,7 +413,7 @@ async def test_scenario3_task_augmented_tool_normal_elicitation() -> None:
# Call tool as task
create_result = await client_session.experimental.call_tool_as_task("confirm_action", {})
task_id = create_result.task.taskId
task_id = create_result.task.task_id
assert create_result.task.status == "working"
# Poll until input_required, then call tasks/result
@ -472,8 +472,8 @@ async def test_scenario4_task_augmented_tool_task_augmented_elicitation() -> Non
Tool(
name="confirm_action",
description="Confirm an action",
inputSchema={"type": "object"},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object"},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -486,7 +486,7 @@ async def test_scenario4_task_augmented_tool_task_augmented_elicitation() -> Non
# Task-augmented elicitation within task - server polls client
result = await task.elicit_as_task(
message="Please confirm the action",
requestedSchema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
requested_schema={"type": "object", "properties": {"confirm": {"type": "boolean"}}},
ttl=60000,
)
@ -522,7 +522,7 @@ async def test_scenario4_task_augmented_tool_task_augmented_elicitation() -> Non
# Call tool as task
create_result = await client_session.experimental.call_tool_as_task("confirm_action", {})
task_id = create_result.task.taskId
task_id = create_result.task.task_id
assert create_result.task.status == "working"
# Poll until input_required or terminal, then call tasks/result
@ -572,7 +572,7 @@ async def test_scenario2_sampling_normal_tool_task_augmented_sampling() -> None:
Tool(
name="generate_text",
description="Generate text using sampling",
inputSchema={"type": "object"},
input_schema={"type": "object"},
)
]
@ -658,8 +658,8 @@ async def test_scenario4_sampling_task_augmented_tool_task_augmented_sampling()
Tool(
name="generate_text",
description="Generate text using sampling",
inputSchema={"type": "object"},
execution=ToolExecution(taskSupport=TASK_REQUIRED),
input_schema={"type": "object"},
execution=ToolExecution(task_support=TASK_REQUIRED),
)
]
@ -710,7 +710,7 @@ async def test_scenario4_sampling_task_augmented_tool_task_augmented_sampling()
# Call tool as task
create_result = await client_session.experimental.call_tool_as_task("generate_text", {})
task_id = create_result.task.taskId
task_id = create_result.task.task_id
assert create_result.task.status == "working"
# Poll until input_required or terminal

Some files were not shown because too many files have changed in this diff Show more