update to RMCP 0.6.2 (#4523)
This commit is contained in:
Generated
+4
-4
@@ -5467,9 +5467,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmcp"
|
name = "rmcp"
|
||||||
version = "0.6.0"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb21cd3555f1059f27e4813827338dec44429a08ecd0011acc41d9907b160c00"
|
checksum = "817ef98583b16628962dd8214ee89e9a9df6a79de9b487eb29ceddb1f610a7f6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"chrono",
|
"chrono",
|
||||||
@@ -5495,9 +5495,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rmcp-macros"
|
name = "rmcp-macros"
|
||||||
version = "0.6.0"
|
version = "0.6.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ab5d16ae1ff3ce2c5fd86c37047b2869b75bec795d53a4b1d8257b15415a2354"
|
checksum = "9712e19c12a2812bffa85ab71714e2a342a9d7e79656e6f74f650475b8094090"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling 0.21.0",
|
"darling 0.21.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ description = "An AI agent"
|
|||||||
uninlined_format_args = "allow"
|
uninlined_format_args = "allow"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
rmcp = { version = "0.6.0", features = ["schemars", "auth"] }
|
rmcp = { version = "0.6.2", features = ["schemars", "auth"] }
|
||||||
|
|
||||||
# Patch for Windows cross-compilation issue with crunchy
|
# Patch for Windows cross-compilation issue with crunchy
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
|
|||||||
@@ -95,9 +95,10 @@ impl McpClientTrait for MockClient {
|
|||||||
if let Some(handler) = self.handlers.get(name) {
|
if let Some(handler) = self.handlers.get(name) {
|
||||||
match handler(&arguments) {
|
match handler(&arguments) {
|
||||||
Ok(content) => Ok(CallToolResult {
|
Ok(content) => Ok(CallToolResult {
|
||||||
content: content,
|
content,
|
||||||
is_error: None,
|
is_error: None,
|
||||||
structured_content: None,
|
structured_content: None,
|
||||||
|
meta: None,
|
||||||
}),
|
}),
|
||||||
Err(_e) => Err(Error::UnexpectedResponse),
|
Err(_e) => Err(Error::UnexpectedResponse),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,6 +256,7 @@ pub fn tool_response_to_markdown(resp: &ToolResponse, export_all_content: bool)
|
|||||||
uri,
|
uri,
|
||||||
mime_type,
|
mime_type,
|
||||||
text,
|
text,
|
||||||
|
meta: _,
|
||||||
} => {
|
} => {
|
||||||
// Extract file extension from the URI for syntax highlighting
|
// Extract file extension from the URI for syntax highlighting
|
||||||
let file_extension = uri.split('.').next_back().unwrap_or("");
|
let file_extension = uri.split('.').next_back().unwrap_or("");
|
||||||
@@ -287,6 +288,7 @@ pub fn tool_response_to_markdown(resp: &ToolResponse, export_all_content: bool)
|
|||||||
uri,
|
uri,
|
||||||
mime_type,
|
mime_type,
|
||||||
blob,
|
blob,
|
||||||
|
..
|
||||||
} => {
|
} => {
|
||||||
md.push_str(&format!(
|
md.push_str(&format!(
|
||||||
"**Binary File:** `{}` (type: {}, {} bytes)\n\n",
|
"**Binary File:** `{}` (type: {}, {} bytes)\n\n",
|
||||||
@@ -297,6 +299,10 @@ pub fn tool_response_to_markdown(resp: &ToolResponse, export_all_content: bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RawContent::ResourceLink(_link) => {
|
||||||
|
// Show a simple placeholder for resource links when exporting
|
||||||
|
md.push_str("[resource link]\n\n");
|
||||||
|
}
|
||||||
RawContent::Audio(_) => {
|
RawContent::Audio(_) => {
|
||||||
md.push_str("[audio content not displayed in Markdown export]\n\n")
|
md.push_str("[audio content not displayed in Markdown export]\n\n")
|
||||||
}
|
}
|
||||||
@@ -527,6 +533,7 @@ mod tests {
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: "Command executed successfully".to_string(),
|
text: "Command executed successfully".to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -546,6 +553,7 @@ mod tests {
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: json_text.to_string(),
|
text: json_text.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -650,6 +658,7 @@ if __name__ == "__main__":
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: python_code.to_string(),
|
text: python_code.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -689,6 +698,7 @@ if __name__ == "__main__":
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: git_output.to_string(),
|
text: git_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -736,6 +746,7 @@ warning: unused variable `x`
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: build_output.to_string(),
|
text: build_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -781,6 +792,7 @@ warning: unused variable `x`
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: api_response.to_string(),
|
text: api_response.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -815,6 +827,7 @@ warning: unused variable `x`
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: "File created successfully".to_string(),
|
text: "File created successfully".to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -870,6 +883,7 @@ def process_data(data: List[Dict]) -> List[Dict]:
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: python_code.to_string(),
|
text: python_code.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -905,6 +919,7 @@ Command failed with exit code 2"#;
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: error_output.to_string(),
|
text: error_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -943,6 +958,7 @@ Command failed with exit code 2"#;
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: script_output.to_string(),
|
text: script_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -988,6 +1004,7 @@ drwx------ 3 user staff 96 Dec 6 16:20 com.apple.launchd.abc
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: multi_output.to_string(),
|
text: multi_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -1029,6 +1046,7 @@ src/middleware.rs:12:async fn auth_middleware(req: Request, next: Next) -> Resul
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: grep_output.to_string(),
|
text: grep_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -1067,6 +1085,7 @@ src/middleware.rs:12:async fn auth_middleware(req: Request, next: Next) -> Resul
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: json_output.to_string(),
|
text: json_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
@@ -1106,6 +1125,7 @@ found 0 vulnerabilities"#;
|
|||||||
let text_content = TextContent {
|
let text_content = TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: npm_output.to_string(),
|
text: npm_output.to_string(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -642,6 +642,7 @@ impl AutoVisualiserRouter {
|
|||||||
uri: "ui://sankey/diagram".to_string(),
|
uri: "ui://sankey/diagram".to_string(),
|
||||||
mime_type: Some("text/html".to_string()),
|
mime_type: Some("text/html".to_string()),
|
||||||
blob: base64_encoded,
|
blob: base64_encoded,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
@@ -686,6 +687,7 @@ impl AutoVisualiserRouter {
|
|||||||
uri: "ui://radar/chart".to_string(),
|
uri: "ui://radar/chart".to_string(),
|
||||||
mime_type: Some("text/html".to_string()),
|
mime_type: Some("text/html".to_string()),
|
||||||
blob: base64_encoded,
|
blob: base64_encoded,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
@@ -730,6 +732,7 @@ impl AutoVisualiserRouter {
|
|||||||
uri: "ui://treemap/visualization".to_string(),
|
uri: "ui://treemap/visualization".to_string(),
|
||||||
mime_type: Some("text/html".to_string()),
|
mime_type: Some("text/html".to_string()),
|
||||||
blob: base64_encoded,
|
blob: base64_encoded,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
@@ -774,6 +777,7 @@ impl AutoVisualiserRouter {
|
|||||||
uri: "ui://chord/diagram".to_string(),
|
uri: "ui://chord/diagram".to_string(),
|
||||||
mime_type: Some("text/html".to_string()),
|
mime_type: Some("text/html".to_string()),
|
||||||
blob: base64_encoded,
|
blob: base64_encoded,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
@@ -818,6 +822,7 @@ impl AutoVisualiserRouter {
|
|||||||
uri: "ui://donut/chart".to_string(),
|
uri: "ui://donut/chart".to_string(),
|
||||||
mime_type: Some("text/html".to_string()),
|
mime_type: Some("text/html".to_string()),
|
||||||
blob: base64_encoded,
|
blob: base64_encoded,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
@@ -879,6 +884,7 @@ impl AutoVisualiserRouter {
|
|||||||
uri: "ui://map/visualization".to_string(),
|
uri: "ui://map/visualization".to_string(),
|
||||||
mime_type: Some("text/html".to_string()),
|
mime_type: Some("text/html".to_string()),
|
||||||
blob: base64_encoded,
|
blob: base64_encoded,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
@@ -923,6 +929,7 @@ impl AutoVisualiserRouter {
|
|||||||
uri: "ui://chart/interactive".to_string(),
|
uri: "ui://chart/interactive".to_string(),
|
||||||
mime_type: Some("text/html".to_string()),
|
mime_type: Some("text/html".to_string()),
|
||||||
blob: base64_encoded,
|
blob: base64_encoded,
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
@@ -1175,8 +1182,8 @@ mod tests {
|
|||||||
assert_eq!(content[0].audience().unwrap(), &vec![Role::User]);
|
assert_eq!(content[0].audience().unwrap(), &vec![Role::User]);
|
||||||
|
|
||||||
// Check it's a resource with HTML content
|
// Check it's a resource with HTML content
|
||||||
// Content is Annotated<RawContent>, deref to get RawContent
|
// Content is Annotated<RawContent>, access underlying RawContent via *
|
||||||
if let RawContent::Resource(resource) = &**&content[0] {
|
if let RawContent::Resource(resource) = &*content[0] {
|
||||||
if let ResourceContents::BlobResourceContents { uri, mime_type, .. } =
|
if let ResourceContents::BlobResourceContents { uri, mime_type, .. } =
|
||||||
&resource.resource
|
&resource.resource
|
||||||
{
|
{
|
||||||
@@ -1212,12 +1219,13 @@ mod tests {
|
|||||||
assert_eq!(content[0].audience().unwrap(), &vec![Role::User]);
|
assert_eq!(content[0].audience().unwrap(), &vec![Role::User]);
|
||||||
|
|
||||||
// Check it's a resource with HTML content
|
// Check it's a resource with HTML content
|
||||||
// Content is Annotated<RawContent>, deref to get RawContent
|
// Content is Annotated<RawContent>, access underlying RawContent via *
|
||||||
if let RawContent::Resource(resource) = &**&content[0] {
|
if let RawContent::Resource(resource) = &*content[0] {
|
||||||
if let ResourceContents::BlobResourceContents {
|
if let ResourceContents::BlobResourceContents {
|
||||||
uri,
|
uri,
|
||||||
mime_type,
|
mime_type,
|
||||||
blob,
|
blob,
|
||||||
|
..
|
||||||
} = &resource.resource
|
} = &resource.resource
|
||||||
{
|
{
|
||||||
assert_eq!(uri, "ui://radar/chart");
|
assert_eq!(uri, "ui://radar/chart");
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use ignore::gitignore::{Gitignore, GitignoreBuilder};
|
|||||||
use include_dir::{include_dir, Dir};
|
use include_dir::{include_dir, Dir};
|
||||||
use indoc::{formatdoc, indoc};
|
use indoc::{formatdoc, indoc};
|
||||||
use rmcp::{
|
use rmcp::{
|
||||||
handler::server::{router::tool::ToolRouter, tool::Parameters},
|
handler::server::{router::tool::ToolRouter, wrapper::Parameters},
|
||||||
model::{
|
model::{
|
||||||
CallToolResult, Content, ErrorCode, ErrorData, GetPromptRequestParam, GetPromptResult,
|
CallToolResult, Content, ErrorCode, ErrorData, GetPromptRequestParam, GetPromptResult,
|
||||||
Implementation, ListPromptsResult, LoggingLevel, LoggingMessageNotificationParam,
|
Implementation, ListPromptsResult, LoggingLevel, LoggingMessageNotificationParam,
|
||||||
@@ -1242,7 +1242,7 @@ impl DeveloperServer {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use rmcp::handler::server::tool::Parameters;
|
use rmcp::handler::server::wrapper::Parameters;
|
||||||
use rmcp::model::NumberOrString;
|
use rmcp::model::NumberOrString;
|
||||||
use rmcp::service::serve_directly;
|
use rmcp::service::serve_directly;
|
||||||
use serial_test::serial;
|
use serial_test::serial;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use goose::session::info::SessionInfo;
|
|||||||
use goose::session::SessionMetadata;
|
use goose::session::SessionMetadata;
|
||||||
use rmcp::model::{
|
use rmcp::model::{
|
||||||
Annotations, Content, EmbeddedResource, ImageContent, RawEmbeddedResource, RawImageContent,
|
Annotations, Content, EmbeddedResource, ImageContent, RawEmbeddedResource, RawImageContent,
|
||||||
RawTextContent, ResourceContents, Role, TextContent, Tool, ToolAnnotations,
|
RawResource, RawTextContent, ResourceContents, Role, TextContent, Tool, ToolAnnotations,
|
||||||
};
|
};
|
||||||
use utoipa::{OpenApi, ToSchema};
|
use utoipa::{OpenApi, ToSchema};
|
||||||
|
|
||||||
@@ -319,6 +319,7 @@ derive_utoipa!(TextContent as TextContentSchema);
|
|||||||
derive_utoipa!(RawTextContent as RawTextContentSchema);
|
derive_utoipa!(RawTextContent as RawTextContentSchema);
|
||||||
derive_utoipa!(RawImageContent as RawImageContentSchema);
|
derive_utoipa!(RawImageContent as RawImageContentSchema);
|
||||||
derive_utoipa!(RawEmbeddedResource as RawEmbeddedResourceSchema);
|
derive_utoipa!(RawEmbeddedResource as RawEmbeddedResourceSchema);
|
||||||
|
derive_utoipa!(RawResource as RawResourceSchema);
|
||||||
derive_utoipa!(Tool as ToolSchema);
|
derive_utoipa!(Tool as ToolSchema);
|
||||||
derive_utoipa!(ToolAnnotations as ToolAnnotationsSchema);
|
derive_utoipa!(ToolAnnotations as ToolAnnotationsSchema);
|
||||||
derive_utoipa!(Annotations as AnnotationsSchema);
|
derive_utoipa!(Annotations as AnnotationsSchema);
|
||||||
@@ -425,6 +426,7 @@ impl<'__s> ToSchema<'__s> for AnnotatedSchema {
|
|||||||
RawTextContentSchema,
|
RawTextContentSchema,
|
||||||
RawImageContentSchema,
|
RawImageContentSchema,
|
||||||
RawEmbeddedResourceSchema,
|
RawEmbeddedResourceSchema,
|
||||||
|
RawResourceSchema,
|
||||||
AnnotatedSchema,
|
AnnotatedSchema,
|
||||||
ToolResponse,
|
ToolResponse,
|
||||||
ToolRequest,
|
ToolRequest,
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ rmcp = { workspace = true, features = [
|
|||||||
"reqwest",
|
"reqwest",
|
||||||
"transport-child-process",
|
"transport-child-process",
|
||||||
"transport-sse-client",
|
"transport-sse-client",
|
||||||
|
"transport-sse-client-reqwest",
|
||||||
"transport-streamable-http-client",
|
"transport-streamable-http-client",
|
||||||
|
"transport-streamable-http-client-reqwest",
|
||||||
] }
|
] }
|
||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|||||||
@@ -1154,6 +1154,7 @@ mod tests {
|
|||||||
content: vec![],
|
content: vec![],
|
||||||
is_error: None,
|
is_error: None,
|
||||||
structured_content: None,
|
structured_content: None,
|
||||||
|
meta: None,
|
||||||
}),
|
}),
|
||||||
_ => Err(Error::TransportClosed),
|
_ => Err(Error::TransportClosed),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ mod tests {
|
|||||||
vec![MessageContent::Text(
|
vec![MessageContent::Text(
|
||||||
RawTextContent {
|
RawTextContent {
|
||||||
text: "Summary of conversation".to_string(),
|
text: "Summary of conversation".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
)],
|
)],
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ mod tests {
|
|||||||
vec![MessageContent::Text(
|
vec![MessageContent::Text(
|
||||||
RawTextContent {
|
RawTextContent {
|
||||||
text: "Summarized content".to_string(),
|
text: "Summarized content".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
)],
|
)],
|
||||||
|
|||||||
@@ -168,7 +168,13 @@ impl fmt::Display for MessageContent {
|
|||||||
|
|
||||||
impl MessageContent {
|
impl MessageContent {
|
||||||
pub fn text<S: Into<String>>(text: S) -> Self {
|
pub fn text<S: Into<String>>(text: S) -> Self {
|
||||||
MessageContent::Text(RawTextContent { text: text.into() }.no_annotation())
|
MessageContent::Text(
|
||||||
|
RawTextContent {
|
||||||
|
text: text.into(),
|
||||||
|
meta: None,
|
||||||
|
}
|
||||||
|
.no_annotation(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn image<S: Into<String>, T: Into<String>>(data: S, mime_type: T) -> Self {
|
pub fn image<S: Into<String>, T: Into<String>>(data: S, mime_type: T) -> Self {
|
||||||
@@ -176,6 +182,7 @@ impl MessageContent {
|
|||||||
RawImageContent {
|
RawImageContent {
|
||||||
data: data.into(),
|
data: data.into(),
|
||||||
mime_type: mime_type.into(),
|
mime_type: mime_type.into(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
)
|
)
|
||||||
@@ -317,6 +324,7 @@ impl From<Content> for MessageContent {
|
|||||||
RawContent::Image(image) => {
|
RawContent::Image(image) => {
|
||||||
MessageContent::Image(image.optional_annotate(content.annotations))
|
MessageContent::Image(image.optional_annotate(content.annotations))
|
||||||
}
|
}
|
||||||
|
RawContent::ResourceLink(_link) => MessageContent::text("[Resource link]"),
|
||||||
RawContent::Resource(resource) => {
|
RawContent::Resource(resource) => {
|
||||||
let text = match &resource.resource {
|
let text = match &resource.resource {
|
||||||
ResourceContents::TextResourceContents { text, .. } => text.clone(),
|
ResourceContents::TextResourceContents { text, .. } => text.clone(),
|
||||||
@@ -347,6 +355,7 @@ impl From<PromptMessage> for Message {
|
|||||||
PromptMessageContent::Image { image } => {
|
PromptMessageContent::Image { image } => {
|
||||||
MessageContent::image(image.data.clone(), image.mime_type.clone())
|
MessageContent::image(image.data.clone(), image.mime_type.clone())
|
||||||
}
|
}
|
||||||
|
PromptMessageContent::ResourceLink { .. } => MessageContent::text("[Resource link]"),
|
||||||
PromptMessageContent::Resource { resource } => {
|
PromptMessageContent::Resource { resource } => {
|
||||||
// For resources, convert to text content with the resource text
|
// For resources, convert to text content with the resource text
|
||||||
match &resource.resource {
|
match &resource.resource {
|
||||||
@@ -445,6 +454,7 @@ impl Message {
|
|||||||
self.with_content(MessageContent::Text(
|
self.with_content(MessageContent::Text(
|
||||||
RawTextContent {
|
RawTextContent {
|
||||||
text: sanitized_text,
|
text: sanitized_text,
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
))
|
))
|
||||||
@@ -756,6 +766,7 @@ mod tests {
|
|||||||
image: RawImageContent {
|
image: RawImageContent {
|
||||||
data: "base64data".to_string(),
|
data: "base64data".to_string(),
|
||||||
mime_type: "image/jpeg".to_string(),
|
mime_type: "image/jpeg".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
};
|
};
|
||||||
@@ -781,10 +792,15 @@ mod tests {
|
|||||||
uri: "file:///test.txt".to_string(),
|
uri: "file:///test.txt".to_string(),
|
||||||
mime_type: Some("text/plain".to_string()),
|
mime_type: Some("text/plain".to_string()),
|
||||||
text: "Resource content".to_string(),
|
text: "Resource content".to_string(),
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let prompt_content = PromptMessageContent::Resource {
|
let prompt_content = PromptMessageContent::Resource {
|
||||||
resource: RawEmbeddedResource { resource }.no_annotation(),
|
resource: RawEmbeddedResource {
|
||||||
|
resource,
|
||||||
|
meta: None,
|
||||||
|
}
|
||||||
|
.no_annotation(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let prompt_message = PromptMessage {
|
let prompt_message = PromptMessage {
|
||||||
@@ -807,10 +823,15 @@ mod tests {
|
|||||||
uri: "file:///test.bin".to_string(),
|
uri: "file:///test.bin".to_string(),
|
||||||
mime_type: Some("application/octet-stream".to_string()),
|
mime_type: Some("application/octet-stream".to_string()),
|
||||||
blob: "binary_data".to_string(),
|
blob: "binary_data".to_string(),
|
||||||
|
meta: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let prompt_content = PromptMessageContent::Resource {
|
let prompt_content = PromptMessageContent::Resource {
|
||||||
resource: RawEmbeddedResource { resource }.no_annotation(),
|
resource: RawEmbeddedResource {
|
||||||
|
resource,
|
||||||
|
meta: None,
|
||||||
|
}
|
||||||
|
.no_annotation(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let prompt_message = PromptMessage {
|
let prompt_message = PromptMessage {
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ mod tests {
|
|||||||
"Response from {} with model {}",
|
"Response from {} with model {}",
|
||||||
self.name, self.model_config.model_name
|
self.name, self.model_config.model_name
|
||||||
),
|
),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
)],
|
)],
|
||||||
|
|||||||
@@ -124,6 +124,9 @@ pub fn to_bedrock_tool_result_content_block(
|
|||||||
RawContent::Image(image) => {
|
RawContent::Image(image) => {
|
||||||
bedrock::ToolResultContentBlock::Image(to_bedrock_image(&image.data, &image.mime_type)?)
|
bedrock::ToolResultContentBlock::Image(to_bedrock_image(&image.data, &image.mime_type)?)
|
||||||
}
|
}
|
||||||
|
RawContent::ResourceLink(_link) => {
|
||||||
|
bedrock::ToolResultContentBlock::Text("[Resource link]".to_string())
|
||||||
|
}
|
||||||
RawContent::Resource(resource) => match &resource.resource {
|
RawContent::Resource(resource) => match &resource.resource {
|
||||||
ResourceContents::TextResourceContents { text, .. } => {
|
ResourceContents::TextResourceContents { text, .. } => {
|
||||||
match to_bedrock_document(tool_use_id, &resource.resource)? {
|
match to_bedrock_document(tool_use_id, &resource.resource)? {
|
||||||
@@ -381,6 +384,7 @@ mod tests {
|
|||||||
let image = RawImageContent {
|
let image = RawImageContent {
|
||||||
data: TEST_IMAGE_BASE64.to_string(),
|
data: TEST_IMAGE_BASE64.to_string(),
|
||||||
mime_type: mime_type.to_string(),
|
mime_type: mime_type.to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation();
|
.no_annotation();
|
||||||
|
|
||||||
@@ -396,6 +400,7 @@ mod tests {
|
|||||||
let image = RawImageContent {
|
let image = RawImageContent {
|
||||||
data: TEST_IMAGE_BASE64.to_string(),
|
data: TEST_IMAGE_BASE64.to_string(),
|
||||||
mime_type: "image/bmp".to_string(),
|
mime_type: "image/bmp".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation();
|
.no_annotation();
|
||||||
|
|
||||||
@@ -411,6 +416,7 @@ mod tests {
|
|||||||
let image = RawImageContent {
|
let image = RawImageContent {
|
||||||
data: "invalid_base64_data!!!".to_string(),
|
data: "invalid_base64_data!!!".to_string(),
|
||||||
mime_type: "image/png".to_string(),
|
mime_type: "image/png".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation();
|
.no_annotation();
|
||||||
|
|
||||||
@@ -425,6 +431,7 @@ mod tests {
|
|||||||
let image = RawImageContent {
|
let image = RawImageContent {
|
||||||
data: TEST_IMAGE_BASE64.to_string(),
|
data: TEST_IMAGE_BASE64.to_string(),
|
||||||
mime_type: "image/png".to_string(),
|
mime_type: "image/png".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation();
|
.no_annotation();
|
||||||
|
|
||||||
|
|||||||
@@ -490,6 +490,7 @@ mod tests {
|
|||||||
vec![MessageContent::Text(
|
vec![MessageContent::Text(
|
||||||
RawTextContent {
|
RawTextContent {
|
||||||
text: format!("Response from {}", self.name),
|
text: format!("Response from {}", self.name),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
)],
|
)],
|
||||||
@@ -656,6 +657,7 @@ mod tests {
|
|||||||
vec![MessageContent::Text(
|
vec![MessageContent::Text(
|
||||||
RawTextContent {
|
RawTextContent {
|
||||||
text: format!("Response from {}", self.name),
|
text: format!("Response from {}", self.name),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
)],
|
)],
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ mod tests {
|
|||||||
vec![MessageContent::Text(TextContent {
|
vec![MessageContent::Text(TextContent {
|
||||||
raw: RawTextContent {
|
raw: RawTextContent {
|
||||||
text: self.response.clone(),
|
text: self.response.clone(),
|
||||||
|
meta: None,
|
||||||
},
|
},
|
||||||
annotations: None,
|
annotations: None,
|
||||||
})],
|
})],
|
||||||
|
|||||||
@@ -374,6 +374,7 @@ pub fn load_image_file(path: &str) -> Result<ImageContent, ProviderError> {
|
|||||||
Ok(RawImageContent {
|
Ok(RawImageContent {
|
||||||
mime_type: mime_type.to_string(),
|
mime_type: mime_type.to_string(),
|
||||||
data,
|
data,
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation())
|
.no_annotation())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1406,6 +1406,7 @@ mod tests {
|
|||||||
vec![MessageContent::Text(
|
vec![MessageContent::Text(
|
||||||
RawTextContent {
|
RawTextContent {
|
||||||
text: "Mocked scheduled response".to_string(),
|
text: "Mocked scheduled response".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation(),
|
.no_annotation(),
|
||||||
)],
|
)],
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ impl ProviderTester {
|
|||||||
let image_content = RawImageContent {
|
let image_content = RawImageContent {
|
||||||
data: base64_image,
|
data: base64_image,
|
||||||
mime_type: "image/png".to_string(),
|
mime_type: "image/png".to_string(),
|
||||||
|
meta: None,
|
||||||
}
|
}
|
||||||
.no_annotation();
|
.no_annotation();
|
||||||
|
|
||||||
|
|||||||
@@ -220,8 +220,6 @@ where
|
|||||||
}
|
}
|
||||||
JsonRpcMessage::Response(_)
|
JsonRpcMessage::Response(_)
|
||||||
| JsonRpcMessage::Notification(_)
|
| JsonRpcMessage::Notification(_)
|
||||||
| JsonRpcMessage::BatchRequest(_)
|
|
||||||
| JsonRpcMessage::BatchResponse(_)
|
|
||||||
| JsonRpcMessage::Error(_) => {
|
| JsonRpcMessage::Error(_) => {
|
||||||
// Ignore responses, notifications, batch messages and error messages for now
|
// Ignore responses, notifications, batch messages and error messages for now
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -235,6 +235,7 @@ pub trait Router: Send + Sync + 'static {
|
|||||||
uri: uri.to_string(),
|
uri: uri.to_string(),
|
||||||
mime_type: Some("text/plain".to_string()),
|
mime_type: Some("text/plain".to_string()),
|
||||||
text: contents,
|
text: contents,
|
||||||
|
meta: None,
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+68
-4
@@ -1559,12 +1559,12 @@
|
|||||||
"$ref": "#/components/schemas/Role"
|
"$ref": "#/components/schemas/Role"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"priority": {
|
"lastModified": {
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time"
|
"format": "date-time"
|
||||||
|
},
|
||||||
|
"priority": {
|
||||||
|
"type": "number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1683,6 +1683,13 @@
|
|||||||
"$ref": "#/components/schemas/Annotated"
|
"$ref": "#/components/schemas/Annotated"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/RawResource"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1893,6 +1900,10 @@
|
|||||||
"resource"
|
"resource"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
@@ -2390,6 +2401,10 @@
|
|||||||
"mimeType"
|
"mimeType"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
@@ -2877,6 +2892,10 @@
|
|||||||
"resource"
|
"resource"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"resource": {
|
"resource": {
|
||||||
"$ref": "#/components/schemas/ResourceContents"
|
"$ref": "#/components/schemas/ResourceContents"
|
||||||
}
|
}
|
||||||
@@ -2889,6 +2908,10 @@
|
|||||||
"mimeType"
|
"mimeType"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -2897,12 +2920,41 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"RawResource": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"uri",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mimeType": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "integer",
|
||||||
|
"minimum": 0
|
||||||
|
},
|
||||||
|
"uri": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"RawTextContent": {
|
"RawTextContent": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
"text"
|
"text"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"text": {
|
"text": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
@@ -3102,6 +3154,10 @@
|
|||||||
"text"
|
"text"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"mimeType": {
|
"mimeType": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -3120,6 +3176,10 @@
|
|||||||
"blob"
|
"blob"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"blob": {
|
"blob": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -3643,6 +3703,10 @@
|
|||||||
"text"
|
"text"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"_meta": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
"annotations": {
|
"annotations": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
"start-alpha-gui": "ALPHA=true npm run start-gui"
|
"start-alpha-gui": "ALPHA=true npm run start-gui"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tanstack/react-form": "^0.13.0",
|
||||||
"@ai-sdk/openai": "^2.0.14",
|
"@ai-sdk/openai": "^2.0.14",
|
||||||
"@ai-sdk/ui-utils": "^1.2.11",
|
"@ai-sdk/ui-utils": "^1.2.11",
|
||||||
"@mcp-ui/client": "^5.9.0",
|
"@mcp-ui/client": "^5.9.0",
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ export type Annotated = RawTextContent | RawImageContent | RawEmbeddedResource;
|
|||||||
|
|
||||||
export type Annotations = {
|
export type Annotations = {
|
||||||
audience?: Array<Role>;
|
audience?: Array<Role>;
|
||||||
|
lastModified?: string;
|
||||||
priority?: number;
|
priority?: number;
|
||||||
timestamp?: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Author = {
|
export type Author = {
|
||||||
@@ -65,7 +65,7 @@ export type ConfigResponse = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Content = RawTextContent | RawImageContent | RawEmbeddedResource | Annotated;
|
export type Content = RawTextContent | RawImageContent | RawEmbeddedResource | Annotated | RawResource;
|
||||||
|
|
||||||
export type ContextLengthExceeded = {
|
export type ContextLengthExceeded = {
|
||||||
msg: string;
|
msg: string;
|
||||||
@@ -141,6 +141,9 @@ export type DeleteRecipeRequest = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type EmbeddedResource = {
|
export type EmbeddedResource = {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
annotations?: Annotations | {
|
annotations?: Annotations | {
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
};
|
};
|
||||||
@@ -322,6 +325,9 @@ export type GetToolsQuery = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type ImageContent = {
|
export type ImageContent = {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
annotations?: Annotations | {
|
annotations?: Annotations | {
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
};
|
};
|
||||||
@@ -472,15 +478,32 @@ export type ProvidersResponse = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type RawEmbeddedResource = {
|
export type RawEmbeddedResource = {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
resource: ResourceContents;
|
resource: ResourceContents;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RawImageContent = {
|
export type RawImageContent = {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
data: string;
|
data: string;
|
||||||
mimeType: string;
|
mimeType: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type RawResource = {
|
||||||
|
description?: string;
|
||||||
|
mimeType?: string;
|
||||||
|
name: string;
|
||||||
|
size?: number;
|
||||||
|
uri: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type RawTextContent = {
|
export type RawTextContent = {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
text: string;
|
text: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -580,10 +603,16 @@ export type RedactedThinkingContent = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type ResourceContents = {
|
export type ResourceContents = {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
mimeType?: string;
|
mimeType?: string;
|
||||||
text: string;
|
text: string;
|
||||||
uri: string;
|
uri: string;
|
||||||
} | {
|
} | {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
blob: string;
|
blob: string;
|
||||||
mimeType?: string;
|
mimeType?: string;
|
||||||
uri: string;
|
uri: string;
|
||||||
@@ -790,6 +819,9 @@ export type SummarizationRequested = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type TextContent = {
|
export type TextContent = {
|
||||||
|
_meta?: {
|
||||||
|
[key: string]: unknown;
|
||||||
|
};
|
||||||
annotations?: Annotations | {
|
annotations?: Annotations | {
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user