chore: add #[non_exhaustive] and mutation methods to improve compatibility (#715)
* chore: add #[non_exhaustive] to reduce backwards-incompatible changes going forward * fix: remove ProtocolVersion import * fix: add a few more with_ mutator methods --------- Co-authored-by: Alex Hancock <alexhancock@block.xyz>
This commit is contained in:
parent
79834b6211
commit
f63718d202
1 changed files with 1568 additions and 1110 deletions
|
|
@ -306,6 +306,7 @@ pub struct ProgressToken(pub NumberOrString);
|
|||
/// - `extensions`: Additional context data (similar to HTTP headers)
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct Request<M = String, P = JsonObject> {
|
||||
pub method: M,
|
||||
pub params: P,
|
||||
|
|
@ -379,6 +380,7 @@ impl<M> GetExtensions for RequestNoParam<M> {
|
|||
}
|
||||
#[derive(Debug, Clone, Default)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct Notification<M = String, P = JsonObject> {
|
||||
pub method: M,
|
||||
pub params: P,
|
||||
|
|
@ -419,6 +421,17 @@ pub struct JsonRpcRequest<R = Request> {
|
|||
pub request: R,
|
||||
}
|
||||
|
||||
impl<R> JsonRpcRequest<R> {
|
||||
/// Create a new JsonRpcRequest.
|
||||
pub fn new(id: RequestId, request: R) -> Self {
|
||||
Self {
|
||||
jsonrpc: JsonRpcVersion2_0,
|
||||
id,
|
||||
request,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type DefaultResponse = JsonObject;
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
|
@ -436,6 +449,17 @@ pub struct JsonRpcError {
|
|||
pub error: ErrorData,
|
||||
}
|
||||
|
||||
impl JsonRpcError {
|
||||
/// Create a new JsonRpcError.
|
||||
pub fn new(id: RequestId, error: ErrorData) -> Self {
|
||||
Self {
|
||||
jsonrpc: JsonRpcVersion2_0,
|
||||
id,
|
||||
error,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct JsonRpcNotification<N = Notification> {
|
||||
|
|
@ -467,7 +491,7 @@ impl ErrorCode {
|
|||
///
|
||||
/// This structure follows the JSON-RPC 2.0 specification for error reporting,
|
||||
/// providing a standardized way to communicate errors between clients and servers.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ErrorData {
|
||||
/// The error type that occurred (using standard JSON-RPC error codes)
|
||||
|
|
@ -745,6 +769,7 @@ pub type InitializedNotification = NotificationNoParam<InitializedNotificationMe
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct InitializeRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -757,6 +782,23 @@ pub struct InitializeRequestParams {
|
|||
pub client_info: Implementation,
|
||||
}
|
||||
|
||||
impl InitializeRequestParams {
|
||||
/// Create a new InitializeRequestParams.
|
||||
pub fn new(capabilities: ClientCapabilities, client_info: Implementation) -> Self {
|
||||
Self {
|
||||
meta: None,
|
||||
protocol_version: ProtocolVersion::default(),
|
||||
capabilities,
|
||||
client_info,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_protocol_version(mut self, protocol_version: ProtocolVersion) -> Self {
|
||||
self.protocol_version = protocol_version;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for InitializeRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -777,6 +819,7 @@ pub type InitializeRequestParam = InitializeRequestParams;
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct InitializeResult {
|
||||
/// The MCP protocol version this server supports
|
||||
pub protocol_version: ProtocolVersion,
|
||||
|
|
@ -789,6 +832,36 @@ pub struct InitializeResult {
|
|||
pub instructions: Option<String>,
|
||||
}
|
||||
|
||||
impl InitializeResult {
|
||||
/// Create a new `InitializeResult` with default protocol version and the given capabilities.
|
||||
pub fn new(capabilities: ServerCapabilities) -> Self {
|
||||
Self {
|
||||
protocol_version: ProtocolVersion::default(),
|
||||
capabilities,
|
||||
server_info: Implementation::from_build_env(),
|
||||
instructions: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set instructions on this result.
|
||||
pub fn with_instructions(mut self, instructions: impl Into<String>) -> Self {
|
||||
self.instructions = Some(instructions.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the server info on this result.
|
||||
pub fn with_server_info(mut self, server_info: Implementation) -> Self {
|
||||
self.server_info = server_info;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the protocol version on this result.
|
||||
pub fn with_protocol_version(mut self, protocol_version: ProtocolVersion) -> Self {
|
||||
self.protocol_version = protocol_version;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub type ServerInfo = InitializeResult;
|
||||
pub type ClientInfo = InitializeRequestParams;
|
||||
|
||||
|
|
@ -828,6 +901,7 @@ impl Default for ClientInfo {
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct Icon {
|
||||
/// A standard URI pointing to an icon resource
|
||||
pub src: String,
|
||||
|
|
@ -839,9 +913,33 @@ pub struct Icon {
|
|||
pub sizes: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl Icon {
|
||||
/// Create a new Icon with the given source URL.
|
||||
pub fn new(src: impl Into<String>) -> Self {
|
||||
Self {
|
||||
src: src.into(),
|
||||
mime_type: None,
|
||||
sizes: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the MIME type.
|
||||
pub fn with_mime_type(mut self, mime_type: impl Into<String>) -> Self {
|
||||
self.mime_type = Some(mime_type.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the sizes.
|
||||
pub fn with_sizes(mut self, sizes: Vec<String>) -> Self {
|
||||
self.sizes = Some(sizes);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct Implementation {
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -862,6 +960,18 @@ impl Default for Implementation {
|
|||
}
|
||||
|
||||
impl Implementation {
|
||||
/// Create a new Implementation.
|
||||
pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
title: None,
|
||||
version: version.into(),
|
||||
description: None,
|
||||
icons: None,
|
||||
website_url: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_build_env() -> Self {
|
||||
Implementation {
|
||||
name: env!("CARGO_CRATE_NAME").to_owned(),
|
||||
|
|
@ -872,11 +982,36 @@ impl Implementation {
|
|||
website_url: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the human-readable title.
|
||||
pub fn with_title(mut self, title: impl Into<String>) -> Self {
|
||||
self.title = Some(title.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the description.
|
||||
pub fn with_description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the icons.
|
||||
pub fn with_icons(mut self, icons: Vec<Icon>) -> Self {
|
||||
self.icons = Some(icons);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the website URL.
|
||||
pub fn with_website_url(mut self, website_url: impl Into<String>) -> Self {
|
||||
self.website_url = Some(website_url.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct PaginatedRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -885,6 +1020,13 @@ pub struct PaginatedRequestParams {
|
|||
pub cursor: Option<String>,
|
||||
}
|
||||
|
||||
impl PaginatedRequestParams {
|
||||
pub fn with_cursor(mut self, cursor: Option<String>) -> Self {
|
||||
self.cursor = cursor;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for PaginatedRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -920,6 +1062,30 @@ pub struct ProgressNotificationParam {
|
|||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
impl ProgressNotificationParam {
|
||||
/// Create a new ProgressNotificationParam with required fields.
|
||||
pub fn new(progress_token: ProgressToken, progress: f64) -> Self {
|
||||
Self {
|
||||
progress_token,
|
||||
progress,
|
||||
total: None,
|
||||
message: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the total number of items to process.
|
||||
pub fn with_total(mut self, total: f64) -> Self {
|
||||
self.total = Some(total);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set a message describing the current progress.
|
||||
pub fn with_message(mut self, message: impl Into<String>) -> Self {
|
||||
self.message = Some(message.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub type ProgressNotification = Notification<ProgressNotificationMethod, ProgressNotificationParam>;
|
||||
|
||||
pub type Cursor = String;
|
||||
|
|
@ -980,6 +1146,7 @@ const_string!(ReadResourceRequestMethod = "resources/read");
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct ReadResourceRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -988,6 +1155,22 @@ pub struct ReadResourceRequestParams {
|
|||
pub uri: String,
|
||||
}
|
||||
|
||||
impl ReadResourceRequestParams {
|
||||
/// Create a new ReadResourceRequestParams with the given URI.
|
||||
pub fn new(uri: impl Into<String>) -> Self {
|
||||
Self {
|
||||
meta: None,
|
||||
uri: uri.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the metadata for this request.
|
||||
pub fn with_meta(mut self, meta: Meta) -> Self {
|
||||
self.meta = Some(meta);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for ReadResourceRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -1004,11 +1187,19 @@ pub type ReadResourceRequestParam = ReadResourceRequestParams;
|
|||
/// Result containing the contents of a read resource
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct ReadResourceResult {
|
||||
/// The actual content of the resource
|
||||
pub contents: Vec<ResourceContents>,
|
||||
}
|
||||
|
||||
impl ReadResourceResult {
|
||||
/// Create a new ReadResourceResult with the given contents.
|
||||
pub fn new(contents: Vec<ResourceContents>) -> Self {
|
||||
Self { contents }
|
||||
}
|
||||
}
|
||||
|
||||
/// Request to read a specific resource
|
||||
pub type ReadResourceRequest = Request<ReadResourceRequestMethod, ReadResourceRequestParams>;
|
||||
|
||||
|
|
@ -1022,6 +1213,7 @@ const_string!(SubscribeRequestMethod = "resources/subscribe");
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct SubscribeRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1030,6 +1222,16 @@ pub struct SubscribeRequestParams {
|
|||
pub uri: String,
|
||||
}
|
||||
|
||||
impl SubscribeRequestParams {
|
||||
/// Create a new SubscribeRequestParams.
|
||||
pub fn new(uri: impl Into<String>) -> Self {
|
||||
Self {
|
||||
meta: None,
|
||||
uri: uri.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for SubscribeRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -1051,6 +1253,7 @@ const_string!(UnsubscribeRequestMethod = "resources/unsubscribe");
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct UnsubscribeRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1084,6 +1287,14 @@ pub struct ResourceUpdatedNotificationParam {
|
|||
/// The URI of the resource that was updated
|
||||
pub uri: String,
|
||||
}
|
||||
|
||||
impl ResourceUpdatedNotificationParam {
|
||||
/// Create a new ResourceUpdatedNotificationParam.
|
||||
pub fn new(uri: impl Into<String>) -> Self {
|
||||
Self { uri: uri.into() }
|
||||
}
|
||||
}
|
||||
|
||||
/// Notification sent when a subscribed resource is updated
|
||||
pub type ResourceUpdatedNotification =
|
||||
Notification<ResourceUpdatedNotificationMethod, ResourceUpdatedNotificationParam>;
|
||||
|
|
@ -1103,9 +1314,10 @@ paginated_result!(ListPromptsResult {
|
|||
|
||||
const_string!(GetPromptRequestMethod = "prompts/get");
|
||||
/// Parameters for retrieving a specific prompt
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct GetPromptRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1115,6 +1327,29 @@ pub struct GetPromptRequestParams {
|
|||
pub arguments: Option<JsonObject>,
|
||||
}
|
||||
|
||||
impl GetPromptRequestParams {
|
||||
/// Create a new `GetPromptRequestParams` with the given prompt name.
|
||||
pub fn new(name: impl Into<String>) -> Self {
|
||||
Self {
|
||||
meta: None,
|
||||
name: name.into(),
|
||||
arguments: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the arguments for this prompt request.
|
||||
pub fn with_arguments(mut self, arguments: JsonObject) -> Self {
|
||||
self.arguments = Some(arguments);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the metadata for this request.
|
||||
pub fn with_meta(mut self, meta: Meta) -> Self {
|
||||
self.meta = Some(meta);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for GetPromptRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -1163,6 +1398,7 @@ const_string!(SetLevelRequestMethod = "logging/setLevel");
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct SetLevelRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1171,6 +1407,13 @@ pub struct SetLevelRequestParams {
|
|||
pub level: LoggingLevel,
|
||||
}
|
||||
|
||||
impl SetLevelRequestParams {
|
||||
/// Create a new SetLevelRequestParams with the given logging level.
|
||||
pub fn new(level: LoggingLevel) -> Self {
|
||||
Self { meta: None, level }
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for SetLevelRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -1201,6 +1444,27 @@ pub struct LoggingMessageNotificationParam {
|
|||
/// The actual log data
|
||||
pub data: Value,
|
||||
}
|
||||
|
||||
impl LoggingMessageNotificationParam {
|
||||
/// Create a new LoggingMessageNotificationParam.
|
||||
pub fn new(level: LoggingLevel, data: Value) -> Self {
|
||||
Self {
|
||||
level,
|
||||
logger: None,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create with a logger name.
|
||||
pub fn with_logger(level: LoggingLevel, logger: impl Into<String>, data: Value) -> Self {
|
||||
Self {
|
||||
level,
|
||||
logger: Some(logger.into()),
|
||||
data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Notification containing a log message
|
||||
pub type LoggingMessageNotification =
|
||||
Notification<LoggingMessageNotificationMethod, LoggingMessageNotificationParam>;
|
||||
|
|
@ -1249,6 +1513,7 @@ impl Default for ToolChoiceMode {
|
|||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct ToolChoice {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub mode: Option<ToolChoiceMode>,
|
||||
|
|
@ -1379,6 +1644,7 @@ impl<T> From<Vec<T>> for SamplingContent<T> {
|
|||
/// for generating appropriate responses.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct SamplingMessage {
|
||||
/// The role of the message sender (User or Assistant)
|
||||
pub role: Role,
|
||||
|
|
@ -1539,9 +1805,10 @@ pub enum ContextInclusion {
|
|||
///
|
||||
/// This implements `TaskAugmentedRequestParamsMeta` as sampling requests can be
|
||||
/// long-running and may benefit from task-based execution.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct CreateMessageRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1598,6 +1865,72 @@ impl TaskAugmentedRequestParamsMeta for CreateMessageRequestParams {
|
|||
}
|
||||
|
||||
impl CreateMessageRequestParams {
|
||||
/// Create a new CreateMessageRequestParams with required fields.
|
||||
pub fn new(messages: Vec<SamplingMessage>, max_tokens: u32) -> Self {
|
||||
Self {
|
||||
meta: None,
|
||||
task: None,
|
||||
messages,
|
||||
model_preferences: None,
|
||||
system_prompt: None,
|
||||
include_context: None,
|
||||
temperature: None,
|
||||
max_tokens,
|
||||
stop_sequences: None,
|
||||
metadata: None,
|
||||
tools: None,
|
||||
tool_choice: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set model preferences.
|
||||
pub fn with_model_preferences(mut self, model_preferences: ModelPreferences) -> Self {
|
||||
self.model_preferences = Some(model_preferences);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set system prompt.
|
||||
pub fn with_system_prompt(mut self, system_prompt: impl Into<String>) -> Self {
|
||||
self.system_prompt = Some(system_prompt.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set include context.
|
||||
pub fn with_include_context(mut self, include_context: ContextInclusion) -> Self {
|
||||
self.include_context = Some(include_context);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set temperature.
|
||||
pub fn with_temperature(mut self, temperature: f32) -> Self {
|
||||
self.temperature = Some(temperature);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set stop sequences.
|
||||
pub fn with_stop_sequences(mut self, stop_sequences: Vec<String>) -> Self {
|
||||
self.stop_sequences = Some(stop_sequences);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set metadata.
|
||||
pub fn with_metadata(mut self, metadata: Value) -> Self {
|
||||
self.metadata = Some(metadata);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set tools.
|
||||
pub fn with_tools(mut self, tools: Vec<Tool>) -> Self {
|
||||
self.tools = Some(tools);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set tool choice.
|
||||
pub fn with_tool_choice(mut self, tool_choice: ToolChoice) -> Self {
|
||||
self.tool_choice = Some(tool_choice);
|
||||
self
|
||||
}
|
||||
|
||||
/// Validate the sampling request parameters per SEP-1577 spec requirements.
|
||||
///
|
||||
/// Checks:
|
||||
|
|
@ -1688,6 +2021,7 @@ pub type CreateMessageRequestParam = CreateMessageRequestParams;
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct ModelPreferences {
|
||||
/// Specific model names or families to prefer (e.g., "claude", "gpt")
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1703,18 +2037,70 @@ pub struct ModelPreferences {
|
|||
pub intelligence_priority: Option<f32>,
|
||||
}
|
||||
|
||||
impl ModelPreferences {
|
||||
/// Create a new default ModelPreferences.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
hints: None,
|
||||
cost_priority: None,
|
||||
speed_priority: None,
|
||||
intelligence_priority: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set hints for model selection.
|
||||
pub fn with_hints(mut self, hints: Vec<ModelHint>) -> Self {
|
||||
self.hints = Some(hints);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set cost priority (0.0 to 1.0).
|
||||
pub fn with_cost_priority(mut self, cost_priority: f32) -> Self {
|
||||
self.cost_priority = Some(cost_priority);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set speed priority (0.0 to 1.0).
|
||||
pub fn with_speed_priority(mut self, speed_priority: f32) -> Self {
|
||||
self.speed_priority = Some(speed_priority);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set intelligence priority (0.0 to 1.0).
|
||||
pub fn with_intelligence_priority(mut self, intelligence_priority: f32) -> Self {
|
||||
self.intelligence_priority = Some(intelligence_priority);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ModelPreferences {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// A hint suggesting a preferred model name or family.
|
||||
///
|
||||
/// Model hints are advisory suggestions that help clients choose appropriate
|
||||
/// models. They can be specific model names or general families like "claude" or "gpt".
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct ModelHint {
|
||||
/// The suggested model name or family identifier
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub name: Option<String>,
|
||||
}
|
||||
|
||||
impl ModelHint {
|
||||
/// Create a new ModelHint with a name.
|
||||
pub fn new(name: impl Into<String>) -> Self {
|
||||
Self {
|
||||
name: Some(name.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// COMPLETION AND AUTOCOMPLETE
|
||||
// =============================================================================
|
||||
|
|
@ -1768,6 +2154,7 @@ impl CompletionContext {
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct CompleteRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1779,6 +2166,24 @@ pub struct CompleteRequestParams {
|
|||
pub context: Option<CompletionContext>,
|
||||
}
|
||||
|
||||
impl CompleteRequestParams {
|
||||
/// Create a new CompleteRequestParams with required fields.
|
||||
pub fn new(r#ref: Reference, argument: ArgumentInfo) -> Self {
|
||||
Self {
|
||||
meta: None,
|
||||
r#ref,
|
||||
argument,
|
||||
context: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the completion context
|
||||
pub fn with_context(mut self, context: CompletionContext) -> Self {
|
||||
self.context = Some(context);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for CompleteRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -1875,10 +2280,18 @@ impl CompletionInfo {
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct CompleteResult {
|
||||
pub completion: CompletionInfo,
|
||||
}
|
||||
|
||||
impl CompleteResult {
|
||||
/// Create a new CompleteResult with the given completion info.
|
||||
pub fn new(completion: CompletionInfo) -> Self {
|
||||
Self { completion }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(tag = "type")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
|
|
@ -1939,6 +2352,7 @@ pub struct ResourceReference {
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct PromptReference {
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1960,6 +2374,7 @@ pub struct ArgumentInfo {
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct Root {
|
||||
pub uri: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -1972,6 +2387,7 @@ pub type ListRootsRequest = RequestNoParam<ListRootsRequestMethod>;
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct ListRootsResult {
|
||||
pub roots: Vec<Root>,
|
||||
}
|
||||
|
|
@ -2180,18 +2596,45 @@ pub struct CreateElicitationResult {
|
|||
pub content: Option<Value>,
|
||||
}
|
||||
|
||||
impl CreateElicitationResult {
|
||||
/// Create a new CreateElicitationResult.
|
||||
pub fn new(action: ElicitationAction) -> Self {
|
||||
Self {
|
||||
action,
|
||||
content: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create with content.
|
||||
pub fn with_content(action: ElicitationAction, content: Value) -> Self {
|
||||
Self {
|
||||
action,
|
||||
content: Some(content),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Request type for creating an elicitation to gather user input
|
||||
pub type CreateElicitationRequest =
|
||||
Request<ElicitationCreateRequestMethod, CreateElicitationRequestParams>;
|
||||
|
||||
/// Notification parameters for an url elicitation completion notification.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub struct ElicitationResponseNotificationParam {
|
||||
pub elicitation_id: String,
|
||||
}
|
||||
|
||||
impl ElicitationResponseNotificationParam {
|
||||
/// Create a new ElicitationResponseNotificationParam.
|
||||
pub fn new(elicitation_id: impl Into<String>) -> Self {
|
||||
Self {
|
||||
elicitation_id: elicitation_id.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Notification sent when an url elicitation process is completed.
|
||||
pub type ElicitationCompletionNotification =
|
||||
Notification<ElicitationCompletionNotificationMethod, ElicitationResponseNotificationParam>;
|
||||
|
|
@ -2204,9 +2647,10 @@ pub type ElicitationCompletionNotification =
|
|||
///
|
||||
/// Contains the content returned by the tool execution and an optional
|
||||
/// flag indicating whether the operation resulted in an error.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct CallToolResult {
|
||||
/// The content returned by the tool (text, images, etc.)
|
||||
pub content: Vec<Content>,
|
||||
|
|
@ -2289,6 +2733,12 @@ impl CallToolResult {
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the metadata on this result
|
||||
pub fn with_meta(mut self, meta: Option<Meta>) -> Self {
|
||||
self.meta = meta;
|
||||
self
|
||||
}
|
||||
|
||||
/// Convert the `structured_content` part of response into a certain type.
|
||||
///
|
||||
/// # About json schema validation
|
||||
|
|
@ -2336,9 +2786,10 @@ const_string!(CallToolRequestMethod = "tools/call");
|
|||
///
|
||||
/// This implements `TaskAugmentedRequestParamsMeta` as tool calls can be
|
||||
/// long-running and may benefit from task-based execution.
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct CallToolRequestParams {
|
||||
/// Protocol-level metadata for this request (SEP-1319)
|
||||
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -2353,6 +2804,30 @@ pub struct CallToolRequestParams {
|
|||
pub task: Option<JsonObject>,
|
||||
}
|
||||
|
||||
impl CallToolRequestParams {
|
||||
/// Creates a new `CallToolRequestParams` with the given tool name.
|
||||
pub fn new(name: impl Into<Cow<'static, str>>) -> Self {
|
||||
Self {
|
||||
meta: None,
|
||||
name: name.into(),
|
||||
arguments: None,
|
||||
task: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the arguments for this tool call.
|
||||
pub fn with_arguments(mut self, arguments: JsonObject) -> Self {
|
||||
self.arguments = Some(arguments);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the task metadata for this tool call.
|
||||
pub fn with_task(mut self, task: Option<JsonObject>) -> Self {
|
||||
self.task = task;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl RequestParamsMeta for CallToolRequestParams {
|
||||
fn meta(&self) -> Option<&Meta> {
|
||||
self.meta.as_ref()
|
||||
|
|
@ -2386,6 +2861,7 @@ pub type CallToolRequest = Request<CallToolRequestMethod, CallToolRequestParams>
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct CreateMessageResult {
|
||||
/// The identifier of the model that generated the response
|
||||
pub model: String,
|
||||
|
|
@ -2398,11 +2874,32 @@ pub struct CreateMessageResult {
|
|||
}
|
||||
|
||||
impl CreateMessageResult {
|
||||
/// Create a new CreateMessageResult with required fields.
|
||||
pub fn new(message: SamplingMessage, model: String) -> Self {
|
||||
Self {
|
||||
message,
|
||||
model,
|
||||
stop_reason: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const STOP_REASON_END_TURN: &str = "endTurn";
|
||||
pub const STOP_REASON_END_SEQUENCE: &str = "stopSequence";
|
||||
pub const STOP_REASON_END_MAX_TOKEN: &str = "maxTokens";
|
||||
pub const STOP_REASON_TOOL_USE: &str = "toolUse";
|
||||
|
||||
/// Set the stop reason.
|
||||
pub fn with_stop_reason(mut self, stop_reason: Option<String>) -> Self {
|
||||
self.stop_reason = stop_reason;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the model identifier.
|
||||
pub fn with_model(mut self, model: impl Into<String>) -> Self {
|
||||
self.model = model.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Validate the result per SEP-1577: role must be "assistant".
|
||||
pub fn validate(&self) -> Result<(), String> {
|
||||
if self.message.role != Role::Assistant {
|
||||
|
|
@ -2412,15 +2909,32 @@ impl CreateMessageResult {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct GetPromptResult {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<String>,
|
||||
pub messages: Vec<PromptMessage>,
|
||||
}
|
||||
|
||||
impl GetPromptResult {
|
||||
/// Create a new GetPromptResult with required fields.
|
||||
pub fn new(messages: Vec<PromptMessage>) -> Self {
|
||||
Self {
|
||||
description: None,
|
||||
messages,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the description
|
||||
pub fn with_description<D: Into<String>>(mut self, description: D) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// TASK MANAGEMENT
|
||||
// =============================================================================
|
||||
|
|
@ -2512,6 +3026,7 @@ pub type GetTaskInfoResult = GetTaskResult;
|
|||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
#[non_exhaustive]
|
||||
pub struct ListTasksResult {
|
||||
pub tasks: Vec<crate::model::Task>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
|
|
@ -2520,6 +3035,17 @@ pub struct ListTasksResult {
|
|||
pub total: Option<u64>,
|
||||
}
|
||||
|
||||
impl ListTasksResult {
|
||||
/// Create a new ListTasksResult.
|
||||
pub fn new(tasks: Vec<crate::model::Task>) -> Self {
|
||||
Self {
|
||||
tasks,
|
||||
next_cursor: None,
|
||||
total: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// MESSAGE TYPE UNIONS
|
||||
// =============================================================================
|
||||
|
|
|
|||
Loading…
Reference in a new issue