@@ -479,6 +479,28 @@ public record Annotations( // @formatter:off
479479 @ JsonProperty ("priority" ) Double priority ) {
480480 } // @formatter:on
481481
482+ /**
483+ * A common interface for resource content, which includes metadata about the resource
484+ * such as its URI, name, description, MIME type, size, and annotations. This
485+ * interface is implemented by both {@link Resource} and {@link ResourceLink} to
486+ * provide a consistent way to access resource metadata.
487+ */
488+ public interface ResourceContent {
489+
490+ String uri ();
491+
492+ String name ();
493+
494+ String description ();
495+
496+ String mimeType ();
497+
498+ Long size ();
499+
500+ Annotations annotations ();
501+
502+ }
503+
482504 /**
483505 * A known resource that the server is capable of reading.
484506 *
@@ -503,7 +525,7 @@ public record Resource( // @formatter:off
503525 @ JsonProperty ("description" ) String description ,
504526 @ JsonProperty ("mimeType" ) String mimeType ,
505527 @ JsonProperty ("size" ) Long size ,
506- @ JsonProperty ("annotations" ) Annotations annotations ) implements Annotated {
528+ @ JsonProperty ("annotations" ) Annotations annotations ) implements Annotated , ResourceContent {
507529
508530 /**
509531 * @deprecated Only exists for backwards-compatibility purposes. Use
@@ -1473,8 +1495,9 @@ public record CompleteCompletion(
14731495 @ JsonSubTypes ({ @ JsonSubTypes .Type (value = TextContent .class , name = "text" ),
14741496 @ JsonSubTypes .Type (value = ImageContent .class , name = "image" ),
14751497 @ JsonSubTypes .Type (value = AudioContent .class , name = "audio" ),
1476- @ JsonSubTypes .Type (value = EmbeddedResource .class , name = "resource" ) })
1477- public sealed interface Content permits TextContent , ImageContent , AudioContent , EmbeddedResource {
1498+ @ JsonSubTypes .Type (value = EmbeddedResource .class , name = "resource" ),
1499+ @ JsonSubTypes .Type (value = ResourceLink .class , name = "resource_link" ) })
1500+ public sealed interface Content permits TextContent , ImageContent , AudioContent , EmbeddedResource , ResourceLink {
14781501
14791502 default String type () {
14801503 if (this instanceof TextContent ) {
@@ -1489,6 +1512,9 @@ else if (this instanceof AudioContent) {
14891512 else if (this instanceof EmbeddedResource ) {
14901513 return "resource" ;
14911514 }
1515+ else if (this instanceof ResourceLink ) {
1516+ return "resource_link" ;
1517+ }
14921518 throw new IllegalArgumentException ("Unknown content type: " + this );
14931519 }
14941520
@@ -1601,6 +1627,90 @@ public Double priority() {
16011627 }
16021628 }
16031629
1630+ /**
1631+ * A known resource that the server is capable of reading.
1632+ *
1633+ * @param uri the URI of the resource.
1634+ * @param name A human-readable name for this resource. This can be used by clients to
1635+ * populate UI elements.
1636+ * @param description A description of what this resource represents. This can be used
1637+ * by clients to improve the LLM's understanding of available resources. It can be
1638+ * thought of like a "hint" to the model.
1639+ * @param mimeType The MIME type of this resource, if known.
1640+ * @param size The size of the raw resource content, in bytes (i.e., before base64
1641+ * encoding or any tokenization), if known. This can be used by Hosts to display file
1642+ * sizes and estimate context window usage.
1643+ * @param annotations Optional annotations for the client. The client can use
1644+ * annotations to inform how objects are used or displayed.
1645+ */
1646+ @ JsonInclude (JsonInclude .Include .NON_ABSENT )
1647+ @ JsonIgnoreProperties (ignoreUnknown = true )
1648+ public record ResourceLink ( // @formatter:off
1649+ @ JsonProperty ("name" ) String name ,
1650+ @ JsonProperty ("uri" ) String uri ,
1651+ @ JsonProperty ("description" ) String description ,
1652+ @ JsonProperty ("mimeType" ) String mimeType ,
1653+ @ JsonProperty ("size" ) Long size ,
1654+ @ JsonProperty ("annotations" ) Annotations annotations ) implements Annotated , Content , ResourceContent { // @formatter:on
1655+
1656+ public static Builder builder () {
1657+ return new Builder ();
1658+ }
1659+
1660+ public static class Builder {
1661+
1662+ private String name ;
1663+
1664+ private String uri ;
1665+
1666+ private String description ;
1667+
1668+ private String mimeType ;
1669+
1670+ private Annotations annotations ;
1671+
1672+ private Long size ;
1673+
1674+ public Builder name (String name ) {
1675+ this .name = name ;
1676+ return this ;
1677+ }
1678+
1679+ public Builder uri (String uri ) {
1680+ this .uri = uri ;
1681+ return this ;
1682+ }
1683+
1684+ public Builder description (String description ) {
1685+ this .description = description ;
1686+ return this ;
1687+ }
1688+
1689+ public Builder mimeType (String mimeType ) {
1690+ this .mimeType = mimeType ;
1691+ return this ;
1692+ }
1693+
1694+ public Builder annotations (Annotations annotations ) {
1695+ this .annotations = annotations ;
1696+ return this ;
1697+ }
1698+
1699+ public Builder size (Long size ) {
1700+ this .size = size ;
1701+ return this ;
1702+ }
1703+
1704+ public ResourceLink build () {
1705+ Assert .hasText (uri , "uri must not be empty" );
1706+ Assert .hasText (name , "name must not be empty" );
1707+
1708+ return new ResourceLink (name , uri , description , mimeType , size , annotations );
1709+ }
1710+
1711+ }
1712+ }
1713+
16041714 // ---------------------------
16051715 // Roots
16061716 // ---------------------------
0 commit comments