feat: backwards-compatible create_message overloads for SEP-1577 (#1713)
This commit is contained in:
parent
f82b0c9371
commit
fa851d93a2
3 changed files with 209 additions and 32 deletions
|
|
@ -13,6 +13,7 @@ from .types import (
|
|||
CompleteRequest,
|
||||
CreateMessageRequest,
|
||||
CreateMessageResult,
|
||||
CreateMessageResultWithTools,
|
||||
ErrorData,
|
||||
GetPromptRequest,
|
||||
GetPromptResult,
|
||||
|
|
@ -42,6 +43,7 @@ from .types import (
|
|||
ResourceUpdatedNotification,
|
||||
RootsCapability,
|
||||
SamplingCapability,
|
||||
SamplingContent,
|
||||
SamplingContextCapability,
|
||||
SamplingMessage,
|
||||
SamplingMessageContentBlock,
|
||||
|
|
@ -75,6 +77,7 @@ __all__ = [
|
|||
"CompleteRequest",
|
||||
"CreateMessageRequest",
|
||||
"CreateMessageResult",
|
||||
"CreateMessageResultWithTools",
|
||||
"ErrorData",
|
||||
"GetPromptRequest",
|
||||
"GetPromptResult",
|
||||
|
|
@ -105,6 +108,7 @@ __all__ = [
|
|||
"ResourceUpdatedNotification",
|
||||
"RootsCapability",
|
||||
"SamplingCapability",
|
||||
"SamplingContent",
|
||||
"SamplingContextCapability",
|
||||
"SamplingMessage",
|
||||
"SamplingMessageContentBlock",
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ be instantiated directly by users of the MCP framework.
|
|||
"""
|
||||
|
||||
from enum import Enum
|
||||
from typing import Any, TypeVar
|
||||
from typing import Any, TypeVar, overload
|
||||
|
||||
import anyio
|
||||
import anyio.lowlevel
|
||||
|
|
@ -233,6 +233,44 @@ class ServerSession(
|
|||
)
|
||||
)
|
||||
|
||||
@overload
|
||||
async def create_message(
|
||||
self,
|
||||
messages: list[types.SamplingMessage],
|
||||
*,
|
||||
max_tokens: int,
|
||||
system_prompt: str | None = None,
|
||||
include_context: types.IncludeContext | None = None,
|
||||
temperature: float | None = None,
|
||||
stop_sequences: list[str] | None = None,
|
||||
metadata: dict[str, Any] | None = None,
|
||||
model_preferences: types.ModelPreferences | None = None,
|
||||
tools: None = None,
|
||||
tool_choice: types.ToolChoice | None = None,
|
||||
related_request_id: types.RequestId | None = None,
|
||||
) -> types.CreateMessageResult:
|
||||
"""Overload: Without tools, returns single content."""
|
||||
...
|
||||
|
||||
@overload
|
||||
async def create_message(
|
||||
self,
|
||||
messages: list[types.SamplingMessage],
|
||||
*,
|
||||
max_tokens: int,
|
||||
system_prompt: str | None = None,
|
||||
include_context: types.IncludeContext | None = None,
|
||||
temperature: float | None = None,
|
||||
stop_sequences: list[str] | None = None,
|
||||
metadata: dict[str, Any] | None = None,
|
||||
model_preferences: types.ModelPreferences | None = None,
|
||||
tools: list[types.Tool],
|
||||
tool_choice: types.ToolChoice | None = None,
|
||||
related_request_id: types.RequestId | None = None,
|
||||
) -> types.CreateMessageResultWithTools:
|
||||
"""Overload: With tools, returns array-capable content."""
|
||||
...
|
||||
|
||||
async def create_message(
|
||||
self,
|
||||
messages: list[types.SamplingMessage],
|
||||
|
|
@ -247,7 +285,7 @@ class ServerSession(
|
|||
tools: list[types.Tool] | None = None,
|
||||
tool_choice: types.ToolChoice | None = None,
|
||||
related_request_id: types.RequestId | None = None,
|
||||
) -> types.CreateMessageResult:
|
||||
) -> types.CreateMessageResult | types.CreateMessageResultWithTools:
|
||||
"""Send a sampling/create_message request.
|
||||
|
||||
Args:
|
||||
|
|
@ -278,27 +316,35 @@ class ServerSession(
|
|||
validate_sampling_tools(client_caps, tools, tool_choice)
|
||||
validate_tool_use_result_messages(messages)
|
||||
|
||||
request = types.ServerRequest(
|
||||
types.CreateMessageRequest(
|
||||
params=types.CreateMessageRequestParams(
|
||||
messages=messages,
|
||||
systemPrompt=system_prompt,
|
||||
includeContext=include_context,
|
||||
temperature=temperature,
|
||||
maxTokens=max_tokens,
|
||||
stopSequences=stop_sequences,
|
||||
metadata=metadata,
|
||||
modelPreferences=model_preferences,
|
||||
tools=tools,
|
||||
toolChoice=tool_choice,
|
||||
),
|
||||
)
|
||||
)
|
||||
metadata_obj = ServerMessageMetadata(related_request_id=related_request_id)
|
||||
|
||||
# Use different result types based on whether tools are provided
|
||||
if tools is not None:
|
||||
return await self.send_request(
|
||||
request=request,
|
||||
result_type=types.CreateMessageResultWithTools,
|
||||
metadata=metadata_obj,
|
||||
)
|
||||
return await self.send_request(
|
||||
request=types.ServerRequest(
|
||||
types.CreateMessageRequest(
|
||||
params=types.CreateMessageRequestParams(
|
||||
messages=messages,
|
||||
systemPrompt=system_prompt,
|
||||
includeContext=include_context,
|
||||
temperature=temperature,
|
||||
maxTokens=max_tokens,
|
||||
stopSequences=stop_sequences,
|
||||
metadata=metadata,
|
||||
modelPreferences=model_preferences,
|
||||
tools=tools,
|
||||
toolChoice=tool_choice,
|
||||
),
|
||||
)
|
||||
),
|
||||
request=request,
|
||||
result_type=types.CreateMessageResult,
|
||||
metadata=ServerMessageMetadata(
|
||||
related_request_id=related_request_id,
|
||||
),
|
||||
metadata=metadata_obj,
|
||||
)
|
||||
|
||||
async def list_roots(self) -> types.ListRootsResult:
|
||||
|
|
|
|||
|
|
@ -1146,6 +1146,10 @@ class ToolResultContent(BaseModel):
|
|||
SamplingMessageContentBlock: TypeAlias = TextContent | ImageContent | AudioContent | ToolUseContent | ToolResultContent
|
||||
"""Content block types allowed in sampling messages."""
|
||||
|
||||
SamplingContent: TypeAlias = TextContent | ImageContent | AudioContent
|
||||
"""Basic content types for sampling responses (without tool use).
|
||||
Used for backwards-compatible CreateMessageResult when tools are not used."""
|
||||
|
||||
|
||||
class SamplingMessage(BaseModel):
|
||||
"""Describes a message issued to or received from an LLM API."""
|
||||
|
|
@ -1543,7 +1547,27 @@ StopReason = Literal["endTurn", "stopSequence", "maxTokens", "toolUse"] | str
|
|||
|
||||
|
||||
class CreateMessageResult(Result):
|
||||
"""The client's response to a sampling/create_message request from the server."""
|
||||
"""The client's response to a sampling/create_message request from the server.
|
||||
|
||||
This is the backwards-compatible version that returns single content (no arrays).
|
||||
Used when the request does not include tools.
|
||||
"""
|
||||
|
||||
role: Role
|
||||
"""The role of the message sender (typically 'assistant' for LLM responses)."""
|
||||
content: SamplingContent
|
||||
"""Response content. Single content block (text, image, or audio)."""
|
||||
model: str
|
||||
"""The name of the model that generated the message."""
|
||||
stopReason: StopReason | None = None
|
||||
"""The reason why sampling stopped, if known."""
|
||||
|
||||
|
||||
class CreateMessageResultWithTools(Result):
|
||||
"""The client's response to a sampling/create_message request when tools were provided.
|
||||
|
||||
This version supports array content for tool use flows.
|
||||
"""
|
||||
|
||||
role: Role
|
||||
"""The role of the message sender (typically 'assistant' for LLM responses)."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue