Replace mcp_core::prompt with rmcp::model types (#3561)

This commit is contained in:
Jack Amadeo
2025-07-21 21:33:33 -04:00
committed by GitHub
parent 09e555941d
commit 0a98f431c6
18 changed files with 23 additions and 234 deletions
+2 -1
View File
@@ -397,9 +397,10 @@ impl Validator for GooseCompleter {
#[cfg(test)]
mod tests {
use rmcp::model::PromptArgument;
use super::*;
use crate::session::output;
use mcp_core::prompt::PromptArgument;
use std::sync::{Arc, RwLock};
// Helper function to create a test completion cache
+1 -28
View File
@@ -362,34 +362,7 @@ impl Session {
}
pub async fn get_prompt(&mut self, name: &str, arguments: Value) -> Result<Vec<PromptMessage>> {
let result = self.agent.get_prompt(name, arguments).await?;
// Convert mcp_core::prompt::PromptMessage to rmcp::model::PromptMessage
let converted_messages = result
.messages
.into_iter()
.map(|msg| rmcp::model::PromptMessage {
role: match msg.role {
mcp_core::prompt::PromptMessageRole::User => {
rmcp::model::PromptMessageRole::User
}
mcp_core::prompt::PromptMessageRole::Assistant => {
rmcp::model::PromptMessageRole::Assistant
}
},
content: match msg.content {
mcp_core::prompt::PromptMessageContent::Text { text } => {
rmcp::model::PromptMessageContent::Text { text }
}
mcp_core::prompt::PromptMessageContent::Image { image } => {
rmcp::model::PromptMessageContent::Image { image }
}
mcp_core::prompt::PromptMessageContent::Resource { resource } => {
rmcp::model::PromptMessageContent::Resource { resource }
}
},
})
.collect();
Ok(converted_messages)
Ok(self.agent.get_prompt(name, arguments).await?.messages)
}
/// Process a single message and get the response
+1 -1
View File
@@ -4,9 +4,9 @@ use goose::config::Config;
use goose::message::{Message, MessageContent, ToolRequest, ToolResponse};
use goose::providers::pricing::get_model_pricing;
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use mcp_core::prompt::PromptArgument;
use mcp_core::tool::ToolCall;
use regex::Regex;
use rmcp::model::PromptArgument;
use serde_json::Value;
use std::cell::RefCell;
use std::collections::HashMap;
@@ -13,14 +13,13 @@ use std::os::unix::fs::PermissionsExt;
use mcp_core::{
handler::{PromptError, ResourceError, ToolError},
prompt::Prompt,
protocol::{JsonRpcMessage, ServerCapabilities},
resource::Resource,
tool::{Tool, ToolAnnotations},
};
use mcp_server::router::CapabilitiesBuilder;
use mcp_server::Router;
use rmcp::model::Content;
use rmcp::model::{Content, Prompt};
mod docx_tool;
mod pdf_tool;
+2 -5
View File
@@ -22,19 +22,16 @@ use tokio::{
use url::Url;
use include_dir::{include_dir, Dir};
use mcp_core::tool::ToolAnnotations;
use mcp_core::{
handler::{PromptError, ResourceError, ToolError},
protocol::{JsonRpcMessage, JsonRpcNotification, ServerCapabilities},
resource::Resource,
tool::Tool,
};
use mcp_core::{
prompt::{Prompt, PromptArgument, PromptTemplate},
tool::ToolAnnotations,
};
use mcp_server::router::CapabilitiesBuilder;
use mcp_server::Router;
use rmcp::model::Content;
use rmcp::model::{Content, Prompt, PromptArgument, PromptTemplate};
use rmcp::model::Role;
+1 -2
View File
@@ -11,7 +11,7 @@ use mcp_core::protocol::JsonRpcMessage;
use mcp_core::tool::ToolAnnotations;
use oauth_pkce::PkceOAuth2Client;
use regex::Regex;
use rmcp::model::Content;
use rmcp::model::{Content, Prompt};
use serde_json::{json, Value};
use std::io::Cursor;
use std::{env, fs, future::Future, path::Path, pin::Pin, sync::Arc};
@@ -20,7 +20,6 @@ use tokio::sync::mpsc;
use mcp_core::{
handler::{PromptError, ResourceError, ToolError},
prompt::Prompt,
protocol::ServerCapabilities,
resource::Resource,
tool::Tool,
+1 -2
View File
@@ -14,14 +14,13 @@ use tokio::sync::mpsc;
use mcp_core::{
handler::{PromptError, ResourceError, ToolError},
prompt::Prompt,
protocol::{JsonRpcMessage, ServerCapabilities},
resource::Resource,
tool::{Tool, ToolAnnotations, ToolCall},
};
use mcp_server::router::CapabilitiesBuilder;
use mcp_server::Router;
use rmcp::model::Content;
use rmcp::model::{Content, Prompt};
// MemoryRouter implementation
#[derive(Clone)]
+1 -3
View File
@@ -1,17 +1,15 @@
use anyhow::Result;
use include_dir::{include_dir, Dir};
use indoc::formatdoc;
use rmcp::model::Content;
use rmcp::model::{Content, Prompt, Role};
use serde_json::{json, Value};
use std::{future::Future, pin::Pin};
use tokio::sync::mpsc;
use mcp_core::{
handler::{PromptError, ResourceError, ToolError},
prompt::Prompt,
protocol::{JsonRpcMessage, ServerCapabilities},
resource::Resource,
role::Role,
tool::{Tool, ToolAnnotations},
};
use mcp_server::router::CapabilitiesBuilder;
+2 -2
View File
@@ -18,8 +18,8 @@ use goose::{
permission::{Permission, PermissionConfirmation},
session,
};
use mcp_core::{protocol::JsonRpcMessage, role::Role, ToolResult};
use rmcp::model::Content;
use mcp_core::{protocol::JsonRpcMessage, ToolResult};
use rmcp::model::{Content, Role};
use serde::{Deserialize, Serialize};
use serde_json::json;
use serde_json::Value;
+2 -2
View File
@@ -48,8 +48,8 @@ use crate::agents::tool_router_index_manager::ToolRouterIndexManager;
use crate::agents::tool_vectordb::generate_table_id;
use crate::agents::types::SessionConfig;
use crate::agents::types::{FrontendTool, ToolResultReceiver};
use mcp_core::{prompt::Prompt, protocol::GetPromptResult, tool::Tool, ToolError, ToolResult};
use rmcp::model::Content;
use mcp_core::{protocol::GetPromptResult, tool::Tool, ToolError, ToolResult};
use rmcp::model::{Content, Prompt};
use super::final_output_tool::FinalOutputTool;
use super::platform_tools;
+2 -2
View File
@@ -19,8 +19,8 @@ use crate::config::{Config, ExtensionConfigManager};
use crate::prompt_template;
use mcp_client::client::{ClientCapabilities, ClientInfo, McpClient, McpClientTrait};
use mcp_client::transport::{SseTransport, StdioTransport, StreamableHttpTransport, Transport};
use mcp_core::{prompt::Prompt, Tool, ToolCall, ToolError};
use rmcp::model::Content;
use mcp_core::{Tool, ToolCall, ToolError};
use rmcp::model::{Content, Prompt};
use serde_json::Value;
// By default, we set it to Jan 1, 2020 if the resource does not have a timestamp
+3 -3
View File
@@ -1,5 +1,6 @@
use anyhow::Result;
use async_trait::async_trait;
use rmcp::model::Role;
use serde_json::{json, Value};
use std::path::PathBuf;
use std::process::Stdio;
@@ -13,7 +14,6 @@ use crate::config::Config;
use crate::message::{Message, MessageContent};
use crate::model::ModelConfig;
use mcp_core::tool::Tool;
use mcp_core::Role;
pub const CLAUDE_CODE_DEFAULT_MODEL: &str = "claude-3-5-sonnet-latest";
pub const CLAUDE_CODE_KNOWN_MODELS: &[&str] = &["sonnet", "opus", "claude-3-5-sonnet-latest"];
@@ -412,7 +412,7 @@ impl ClaudeCodeProvider {
// Extract the first user message text
let description = messages
.iter()
.find(|m| m.role == mcp_core::Role::User)
.find(|m| m.role == Role::User)
.and_then(|m| {
m.content.iter().find_map(|c| match c {
MessageContent::Text(text_content) => Some(&text_content.text),
@@ -437,7 +437,7 @@ impl ClaudeCodeProvider {
let message = Message {
id: None,
role: mcp_core::Role::Assistant,
role: Role::Assistant,
created: chrono::Utc::now().timestamp(),
content: vec![MessageContent::text(description.clone())],
};
-3
View File
@@ -1,10 +1,7 @@
pub mod handler;
pub mod role;
pub use role::Role;
pub mod tool;
pub use tool::{Tool, ToolCall};
pub mod resource;
pub use resource::{Resource, ResourceContents};
pub mod protocol;
pub use handler::{ToolError, ToolResult};
pub mod prompt;
-164
View File
@@ -1,164 +0,0 @@
use crate::handler::PromptError;
use base64::engine::{general_purpose::STANDARD as BASE64_STANDARD, Engine};
use rmcp::model::{Annotations, EmbeddedResource, ImageContent};
use serde::{Deserialize, Serialize};
/// A prompt that can be used to generate text from a model
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Prompt {
/// The name of the prompt
pub name: String,
/// Optional description of what the prompt does
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// Optional arguments that can be passed to customize the prompt
#[serde(skip_serializing_if = "Option::is_none")]
pub arguments: Option<Vec<PromptArgument>>,
}
impl Prompt {
/// Create a new prompt with the given name, description and arguments
pub fn new<N, D>(
name: N,
description: Option<D>,
arguments: Option<Vec<PromptArgument>>,
) -> Self
where
N: Into<String>,
D: Into<String>,
{
Prompt {
name: name.into(),
description: description.map(Into::into),
arguments,
}
}
}
/// Represents a prompt argument that can be passed to customize the prompt
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PromptArgument {
/// The name of the argument
pub name: String,
/// A description of what the argument is used for
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
/// Whether this argument is required
#[serde(skip_serializing_if = "Option::is_none")]
pub required: Option<bool>,
}
/// Represents the role of a message sender in a prompt conversation
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum PromptMessageRole {
User,
Assistant,
}
/// Content types that can be included in prompt messages
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
pub enum PromptMessageContent {
/// Plain text content
Text { text: String },
/// Image content with base64-encoded data
Image { image: ImageContent },
/// Embedded server-side resource
Resource { resource: EmbeddedResource },
}
/// A message in a prompt conversation
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PromptMessage {
/// The role of the message sender
pub role: PromptMessageRole,
/// The content of the message
pub content: PromptMessageContent,
}
impl PromptMessage {
/// Create a new text message with the given role and text content
pub fn new_text<S: Into<String>>(role: PromptMessageRole, text: S) -> Self {
Self {
role,
content: PromptMessageContent::Text { text: text.into() },
}
}
pub fn new_image<S: Into<String>>(
role: PromptMessageRole,
data: S,
mime_type: S,
annotations: Option<Annotations>,
) -> Result<Self, PromptError> {
let data = data.into();
let mime_type = mime_type.into();
// Validate base64 data
BASE64_STANDARD.decode(&data).map_err(|_| {
PromptError::InvalidParameters("Image data must be valid base64".to_string())
})?;
// Validate mime type
if !mime_type.starts_with("image/") {
return Err(PromptError::InvalidParameters(
"MIME type must be a valid image type (e.g. image/jpeg)".to_string(),
));
}
Ok(Self {
role,
content: PromptMessageContent::Image {
image: ImageContent {
raw: rmcp::model::RawImageContent { data, mime_type },
annotations,
},
},
})
}
/// Create a new resource message
pub fn new_resource(
role: PromptMessageRole,
uri: String,
mime_type: String,
text: Option<String>,
annotations: Option<Annotations>,
) -> Self {
let resource_contents = rmcp::model::ResourceContents::TextResourceContents {
uri,
mime_type: Some(mime_type),
text: text.unwrap_or_default(),
};
Self {
role,
content: PromptMessageContent::Resource {
resource: EmbeddedResource {
raw: rmcp::model::RawEmbeddedResource {
resource: resource_contents,
},
annotations,
},
},
}
}
}
/// A template for a prompt
#[derive(Debug, Serialize, Deserialize)]
pub struct PromptTemplate {
pub id: String,
pub template: String,
pub arguments: Vec<PromptArgumentTemplate>,
}
/// A template for a prompt argument, this should be identical to PromptArgument
#[derive(Debug, Serialize, Deserialize)]
pub struct PromptArgumentTemplate {
pub name: String,
pub description: Option<String>,
pub required: Option<bool>,
}
+2 -7
View File
@@ -1,11 +1,6 @@
/// The protocol messages exchanged between client and server
use crate::{
prompt::{Prompt, PromptMessage},
resource::Resource,
resource::ResourceContents,
tool::Tool,
};
use rmcp::model::Content;
use crate::{resource::Resource, resource::ResourceContents, tool::Tool};
use rmcp::model::{Content, Prompt, PromptMessage};
use serde::{Deserialize, Serialize};
use serde_json::Value;
-3
View File
@@ -1,3 +0,0 @@
// passthrough, which will be deleted with the rest of the mcp-core crate after it is no longer used
// needed because it has internal references in this crate which leak out to usages used in goose etc crates
pub use rmcp::model::Role;
+1 -2
View File
@@ -1,12 +1,11 @@
use anyhow::Result;
use mcp_core::handler::{PromptError, ResourceError};
use mcp_core::prompt::{Prompt, PromptArgument};
use mcp_core::protocol::JsonRpcMessage;
use mcp_core::tool::ToolAnnotations;
use mcp_core::{handler::ToolError, protocol::ServerCapabilities, resource::Resource, tool::Tool};
use mcp_server::router::{CapabilitiesBuilder, RouterService};
use mcp_server::{ByteTransport, Router, Server};
use rmcp::model::Content;
use rmcp::model::{Content, Prompt, PromptArgument};
use serde_json::Value;
use std::{future::Future, pin::Pin, sync::Arc};
use tokio::sync::mpsc;
+1 -2
View File
@@ -8,7 +8,6 @@ type PromptFuture = Pin<Box<dyn Future<Output = Result<String, PromptError>> + S
use mcp_core::{
handler::{PromptError, ResourceError, ToolError},
prompt::{Prompt, PromptMessage, PromptMessageRole},
protocol::{
CallToolResult, GetPromptResult, Implementation, InitializeResult, JsonRpcMessage,
JsonRpcRequest, JsonRpcResponse, ListPromptsResult, ListResourcesResult, ListToolsResult,
@@ -17,7 +16,7 @@ use mcp_core::{
},
ResourceContents,
};
use rmcp::model::Content;
use rmcp::model::{Content, Prompt, PromptMessage, PromptMessageRole};
use serde_json::Value;
use tokio::sync::mpsc;
use tower_service::Service;