Spec conformance: meta support and spec updates (#415)

* feat: add _meta to content blocks and embedded resources; update schemas

* feat: set default protocol version; add _meta to content blocks/resources; update schemas

* chore: format content.rs via rustfmt

* chore(protocol): keep LATEST at 2025-03-26 per review until full 2025-06-18 compliance

* feat(prompt): add constructors with optional meta for image and resource

- Keep text helper; meta is currently ignored for text until schema supports it.

* refactor(prompt): simplify constructors so meta is optional; remove duplicate non-meta variants

* fix: modify code comment about version

* refactor(prompt): rename meta parameters in new_resource function for clarity
This commit is contained in:
Andrew Harvard 2025-09-04 14:23:36 -04:00 • committed by GitHub
commit 4eb413b6c6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 3427 additions and 47 deletions

View file

@ -4,20 +4,20 @@ use serde_json::json;
#[test]
fn serialize_embedded_text_resource_with_meta() {
// Inner contents meta
let mut inner_meta = Meta::new();
inner_meta.insert("inner".to_string(), json!(2));
let mut resource_content_meta = Meta::new();
resource_content_meta.insert("inner".to_string(), json!(2));
// Top-level embedded resource meta
let mut top_meta = Meta::new();
top_meta.insert("top".to_string(), json!(1));
let mut resource_meta = Meta::new();
resource_meta.insert("top".to_string(), json!(1));
let content: Content = RawContent::Resource(rmcp::model::RawEmbeddedResource {
meta: Some(top_meta),
meta: Some(resource_meta),
resource: ResourceContents::TextResourceContents {
uri: "str://example".to_string(),
mime_type: Some("text/plain".to_string()),
text: "hello".to_string(),
meta: Some(inner_meta),
meta: Some(resource_content_meta),
},
})
.no_annotation();
@ -97,19 +97,19 @@ fn deserialize_embedded_text_resource_with_meta() {
#[test]
fn serialize_embedded_blob_resource_with_meta() {
let mut inner_meta = Meta::new();
inner_meta.insert("blob_inner".to_string(), json!(true));
let mut resource_content_meta = Meta::new();
resource_content_meta.insert("blob_inner".to_string(), json!(true));
let mut top_meta = Meta::new();
top_meta.insert("blob_top".to_string(), json!("t"));
let mut resource_meta = Meta::new();
resource_meta.insert("blob_top".to_string(), json!("t"));
let content: Content = RawContent::Resource(rmcp::model::RawEmbeddedResource {
meta: Some(top_meta),
meta: Some(resource_meta),
resource: ResourceContents::BlobResourceContents {
uri: "str://blob".to_string(),
mime_type: Some("application/octet-stream".to_string()),
blob: "Zm9v".to_string(),
meta: Some(inner_meta),
meta: Some(resource_content_meta),
},
})
.no_annotation();

View file

@ -176,19 +176,19 @@
"$ref": "#/definitions/Role"
}
},
"lastModified": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"priority": {
"type": [
"number",
"null"
],
"format": "float"
},
"timestamp": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
@ -859,6 +859,7 @@
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
@ -876,6 +877,14 @@
"RawImageContent": {
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
],
"additionalProperties": true
},
"data": {
"description": "The base64-encoded image",
"type": "string"
@ -933,6 +942,14 @@
"RawTextContent": {
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
],
"additionalProperties": true
},
"text": {
"type": "string"
}

File diff suppressed because it is too large Load diff

View file

@ -168,6 +168,7 @@
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
@ -292,19 +293,19 @@
"$ref": "#/definitions/Role"
}
},
"lastModified": {
"type": [
"string",
"null"
],
"format": "date-time"
},
"priority": {
"type": [
"number",
"null"
],
"format": "float"
},
"timestamp": {
"type": [
"string",
"null"
],
"format": "date-time"
}
}
},
@ -1232,6 +1233,14 @@
"description": "Image content with base64-encoded data",
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
],
"additionalProperties": true
},
"annotations": {
"anyOf": [
{
@ -1362,6 +1371,7 @@
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
@ -1379,6 +1389,14 @@
"RawImageContent": {
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
],
"additionalProperties": true
},
"data": {
"description": "The base64-encoded image",
"type": "string"
@ -1436,6 +1454,14 @@
"RawTextContent": {
"type": "object",
"properties": {
"_meta": {
"description": "Optional protocol-level metadata for this content block",
"type": [
"object",
"null"
],
"additionalProperties": true
},
"text": {
"type": "string"
}

File diff suppressed because it is too large Load diff