001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.rest.server.mcp;
018
019/**
020 * Revision-neutral content block returned by tool calls and prompt messages.
021 *
022 * <p>
023 * Carries all three variants supported today — text, image, and embedded resource — so a handler
024 * cannot express less through the neutral model than it can through a wire bean. Supersedes the
025 * wire-level {@code Content} dictionary and its three leaf types.
026 */
027public final class McpContentBlock {
028
029   /** Which content variant is populated. */
030   public enum Kind {
031      /** {@link McpContentBlock#text()} is populated. */
032      TEXT,
033      /** {@link McpContentBlock#data()} and {@link McpContentBlock#mimeType()} are populated. */
034      IMAGE,
035      /** {@link McpContentBlock#resource()} is populated. */
036      RESOURCE
037   }
038
039   private final Kind kind;
040   private final String text;
041   private final String data;
042   private final String mimeType;
043   private final McpResourceContents resource;
044
045   private McpContentBlock(Kind kind, String text, String data, String mimeType, McpResourceContents resource) {
046      this.kind = kind;
047      this.text = text;
048      this.data = data;
049      this.mimeType = mimeType;
050      this.resource = resource;
051   }
052
053   /**
054    * Creates a text content block.
055    *
056    * @param text The text. Can be <jk>null</jk>.
057    * @return A new block. Never <jk>null</jk>.
058    */
059   public static McpContentBlock text(String text) {
060      return new McpContentBlock(Kind.TEXT, text, null, null, null);
061   }
062
063   /**
064    * Creates an image content block.
065    *
066    * @param data Base64-encoded image bytes. Can be <jk>null</jk>.
067    * @param mimeType The image media type. Can be <jk>null</jk>.
068    * @return A new block. Never <jk>null</jk>.
069    */
070   public static McpContentBlock image(String data, String mimeType) {
071      return new McpContentBlock(Kind.IMAGE, null, data, mimeType, null);
072   }
073
074   /**
075    * Creates an embedded-resource content block.
076    *
077    * @param resource The embedded payload. Can be <jk>null</jk>.
078    * @return A new block. Never <jk>null</jk>.
079    */
080   public static McpContentBlock resource(McpResourceContents resource) {
081      return new McpContentBlock(Kind.RESOURCE, null, null, null, resource);
082   }
083
084   /**
085    * Which variant this block carries.
086    *
087    * @return The variant. Never <jk>null</jk>.
088    */
089   public Kind kind() {
090      return kind;
091   }
092
093   /**
094    * The text payload.
095    *
096    * @return The text, or <jk>null</jk> unless this is a {@link Kind#TEXT} block.
097    */
098   public String text() {
099      return text;
100   }
101
102   /**
103    * The base64 image payload.
104    *
105    * @return The data, or <jk>null</jk> unless this is a {@link Kind#IMAGE} block.
106    */
107   public String data() {
108      return data;
109   }
110
111   /**
112    * The image media type.
113    *
114    * @return The media type, or <jk>null</jk> unless this is a {@link Kind#IMAGE} block.
115    */
116   public String mimeType() {
117      return mimeType;
118   }
119
120   /**
121    * The embedded resource payload.
122    *
123    * @return The payload, or <jk>null</jk> unless this is a {@link Kind#RESOURCE} block.
124    */
125   public McpResourceContents resource() {
126      return resource;
127   }
128}