Skip to content

Commit 9f00f22

Browse files
SeanChinJunKaie5l
andauthored
feat: Add audio type according to 2025-03-26 spec (#68)
* feat: Add audio type according to 2025-03-26 spec * chore: update documentation * feat: add unit test * chore: commit api dump * feat: Add audio type according to 2025-03-26 spec * chore: update documentation * feat: add unit test * chore: rebase and commit api dump --------- Co-authored-by: Leonid Stashevsky <e5l@users.noreply.github.com>
1 parent c582a8c commit 9f00f22

File tree

4 files changed

+119
-29
lines changed

4 files changed

+119
-29
lines changed

api/kotlin-sdk.api

+48-17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
public final class io/modelcontextprotocol/kotlin/sdk/AudioContent : io/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal {
2+
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/AudioContent$Companion;
3+
public static final field TYPE Ljava/lang/String;
4+
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
5+
public final fun component1 ()Ljava/lang/String;
6+
public final fun component2 ()Ljava/lang/String;
7+
public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lio/modelcontextprotocol/kotlin/sdk/AudioContent;
8+
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/AudioContent;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/AudioContent;
9+
public fun equals (Ljava/lang/Object;)Z
10+
public final fun getData ()Ljava/lang/String;
11+
public final fun getMimeType ()Ljava/lang/String;
12+
public fun getType ()Ljava/lang/String;
13+
public fun hashCode ()I
14+
public fun toString ()Ljava/lang/String;
15+
}
16+
17+
public synthetic class io/modelcontextprotocol/kotlin/sdk/AudioContent$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
18+
public static final field INSTANCE Lio/modelcontextprotocol/kotlin/sdk/AudioContent$$serializer;
19+
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
20+
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lio/modelcontextprotocol/kotlin/sdk/AudioContent;
21+
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
22+
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
23+
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lio/modelcontextprotocol/kotlin/sdk/AudioContent;)V
24+
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
25+
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
26+
}
27+
28+
public final class io/modelcontextprotocol/kotlin/sdk/AudioContent$Companion {
29+
public final fun serializer ()Lkotlinx/serialization/KSerializer;
30+
}
31+
132
public final class io/modelcontextprotocol/kotlin/sdk/BlobResourceContents : io/modelcontextprotocol/kotlin/sdk/ResourceContents {
233
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/BlobResourceContents$Companion;
334
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
@@ -413,17 +444,17 @@ public final class io/modelcontextprotocol/kotlin/sdk/CreateMessageRequest$Inclu
413444

414445
public final class io/modelcontextprotocol/kotlin/sdk/CreateMessageResult : io/modelcontextprotocol/kotlin/sdk/ClientResult {
415446
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/CreateMessageResult$Companion;
416-
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;Lkotlinx/serialization/json/JsonObject;)V
417-
public synthetic fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
447+
public fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;Lkotlinx/serialization/json/JsonObject;)V
448+
public synthetic fun <init> (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;Lkotlinx/serialization/json/JsonObject;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
418449
public final fun component1 ()Ljava/lang/String;
419450
public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/StopReason;
420451
public final fun component3 ()Lio/modelcontextprotocol/kotlin/sdk/Role;
421-
public final fun component4 ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;
452+
public final fun component4 ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;
422453
public final fun component5 ()Lkotlinx/serialization/json/JsonObject;
423-
public final fun copy (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/CreateMessageResult;
424-
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/CreateMessageResult;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/CreateMessageResult;
454+
public final fun copy (Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;Lkotlinx/serialization/json/JsonObject;)Lio/modelcontextprotocol/kotlin/sdk/CreateMessageResult;
455+
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/CreateMessageResult;Ljava/lang/String;Lio/modelcontextprotocol/kotlin/sdk/StopReason;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/CreateMessageResult;
425456
public fun equals (Ljava/lang/Object;)Z
426-
public final fun getContent ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;
457+
public final fun getContent ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;
427458
public final fun getModel ()Ljava/lang/String;
428459
public final fun getRole ()Lio/modelcontextprotocol/kotlin/sdk/Role;
429460
public final fun getStopReason ()Lio/modelcontextprotocol/kotlin/sdk/StopReason;
@@ -663,7 +694,7 @@ public final class io/modelcontextprotocol/kotlin/sdk/GetPromptResult$Companion
663694
public final fun serializer ()Lkotlinx/serialization/KSerializer;
664695
}
665696

666-
public final class io/modelcontextprotocol/kotlin/sdk/ImageContent : io/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage {
697+
public final class io/modelcontextprotocol/kotlin/sdk/ImageContent : io/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal {
667698
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/ImageContent$Companion;
668699
public static final field TYPE Ljava/lang/String;
669700
public fun <init> (Ljava/lang/String;Ljava/lang/String;)V
@@ -1669,11 +1700,11 @@ public final class io/modelcontextprotocol/kotlin/sdk/PromptMessageContent$Compa
16691700
public final fun serializer ()Lkotlinx/serialization/KSerializer;
16701701
}
16711702

1672-
public abstract interface class io/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage : io/modelcontextprotocol/kotlin/sdk/PromptMessageContent {
1673-
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage$Companion;
1703+
public abstract interface class io/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal : io/modelcontextprotocol/kotlin/sdk/PromptMessageContent {
1704+
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal$Companion;
16741705
}
16751706

1676-
public final class io/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage$Companion {
1707+
public final class io/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal$Companion {
16771708
public final fun serializer ()Lkotlinx/serialization/KSerializer;
16781709
}
16791710

@@ -2079,13 +2110,13 @@ public final class io/modelcontextprotocol/kotlin/sdk/RootsListChangedNotificati
20792110

20802111
public final class io/modelcontextprotocol/kotlin/sdk/SamplingMessage {
20812112
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/SamplingMessage$Companion;
2082-
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;)V
2113+
public fun <init> (Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;)V
20832114
public final fun component1 ()Lio/modelcontextprotocol/kotlin/sdk/Role;
2084-
public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;
2085-
public final fun copy (Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;)Lio/modelcontextprotocol/kotlin/sdk/SamplingMessage;
2086-
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/SamplingMessage;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/SamplingMessage;
2115+
public final fun component2 ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;
2116+
public final fun copy (Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;)Lio/modelcontextprotocol/kotlin/sdk/SamplingMessage;
2117+
public static synthetic fun copy$default (Lio/modelcontextprotocol/kotlin/sdk/SamplingMessage;Lio/modelcontextprotocol/kotlin/sdk/Role;Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/SamplingMessage;
20872118
public fun equals (Ljava/lang/Object;)Z
2088-
public final fun getContent ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage;
2119+
public final fun getContent ()Lio/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal;
20892120
public final fun getRole ()Lio/modelcontextprotocol/kotlin/sdk/Role;
20902121
public fun hashCode ()I
20912122
public fun toString ()Ljava/lang/String;
@@ -2344,7 +2375,7 @@ public final class io/modelcontextprotocol/kotlin/sdk/SubscribeRequest$Companion
23442375
public final fun serializer ()Lkotlinx/serialization/KSerializer;
23452376
}
23462377

2347-
public final class io/modelcontextprotocol/kotlin/sdk/TextContent : io/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage {
2378+
public final class io/modelcontextprotocol/kotlin/sdk/TextContent : io/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal {
23482379
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/TextContent$Companion;
23492380
public static final field TYPE Ljava/lang/String;
23502381
public fun <init> ()V
@@ -2503,7 +2534,7 @@ public final class io/modelcontextprotocol/kotlin/sdk/Types_utilKt {
25032534
public static synthetic fun ok$default (Lio/modelcontextprotocol/kotlin/sdk/CallToolResult$Companion;Ljava/lang/String;Lkotlinx/serialization/json/JsonObject;ILjava/lang/Object;)Lio/modelcontextprotocol/kotlin/sdk/CallToolResult;
25042535
}
25052536

2506-
public final class io/modelcontextprotocol/kotlin/sdk/UnknownContent : io/modelcontextprotocol/kotlin/sdk/PromptMessageContentTextOrImage {
2537+
public final class io/modelcontextprotocol/kotlin/sdk/UnknownContent : io/modelcontextprotocol/kotlin/sdk/PromptMessageContentMultimodal {
25072538
public static final field Companion Lio/modelcontextprotocol/kotlin/sdk/UnknownContent$Companion;
25082539
public fun <init> (Ljava/lang/String;)V
25092540
public final fun component1 ()Ljava/lang/String;

src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.kt

+32-9
Original file line numberDiff line numberDiff line change
@@ -897,10 +897,10 @@ public sealed interface PromptMessageContent {
897897
}
898898

899899
/**
900-
* Represents prompt message content that is either text or an image.
900+
* Represents prompt message content that is either text, image or audio.
901901
*/
902-
@Serializable(with = PromptMessageContentTextOrImagePolymorphicSerializer::class)
903-
public sealed interface PromptMessageContentTextOrImage : PromptMessageContent
902+
@Serializable(with = PromptMessageContentMultimodalPolymorphicSerializer::class)
903+
public sealed interface PromptMessageContentMultimodal : PromptMessageContent
904904

905905
/**
906906
* Text provided to or from an LLM.
@@ -911,7 +911,7 @@ public data class TextContent(
911911
* The text content of the message.
912912
*/
913913
val text: String? = null,
914-
) : PromptMessageContentTextOrImage {
914+
) : PromptMessageContentMultimodal {
915915
override val type: String = TYPE
916916

917917
public companion object {
@@ -933,7 +933,7 @@ public data class ImageContent(
933933
* The MIME type of the image. Different providers may support different image types.
934934
*/
935935
val mimeType: String,
936-
) : PromptMessageContentTextOrImage {
936+
) : PromptMessageContentMultimodal {
937937
override val type: String = TYPE
938938

939939
public companion object {
@@ -942,12 +942,35 @@ public data class ImageContent(
942942
}
943943

944944
/**
945-
* An image provided to or from an LLM.
945+
* Audio provided to or from an LLM.
946+
*/
947+
@Serializable
948+
public data class AudioContent(
949+
/**
950+
* The base64-encoded audio data.
951+
*/
952+
val data: String,
953+
954+
/**
955+
* The MIME type of the audio. Different providers may support different audio types.
956+
*/
957+
val mimeType: String,
958+
) : PromptMessageContentMultimodal {
959+
override val type: String = TYPE
960+
961+
public companion object {
962+
public const val TYPE: String = "audio"
963+
}
964+
}
965+
966+
967+
/**
968+
* Unknown content provided to or from an LLM.
946969
*/
947970
@Serializable
948971
public data class UnknownContent(
949972
override val type: String,
950-
) : PromptMessageContentTextOrImage
973+
) : PromptMessageContentMultimodal
951974

952975
/**
953976
* The contents of a resource, embedded into a prompt or tool call result.
@@ -1217,7 +1240,7 @@ public class ModelPreferences(
12171240
@Serializable
12181241
public data class SamplingMessage(
12191242
val role: Role,
1220-
val content: PromptMessageContentTextOrImage,
1243+
val content: PromptMessageContentMultimodal,
12211244
)
12221245

12231246
/**
@@ -1299,7 +1322,7 @@ public data class CreateMessageResult(
12991322
*/
13001323
val stopReason: StopReason? = null,
13011324
val role: Role,
1302-
val content: PromptMessageContentTextOrImage,
1325+
val content: PromptMessageContentMultimodal,
13031326
override val _meta: JsonObject = EmptyJsonObject,
13041327
) : ClientResult
13051328

src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/types.util.kt

+5-3
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,19 @@ internal object PromptMessageContentPolymorphicSerializer :
8080
ImageContent.TYPE -> ImageContent.serializer()
8181
TextContent.TYPE -> TextContent.serializer()
8282
EmbeddedResource.TYPE -> EmbeddedResource.serializer()
83+
AudioContent.TYPE -> AudioContent.serializer()
8384
else -> UnknownContent.serializer()
8485
}
8586
}
8687
}
8788

88-
internal object PromptMessageContentTextOrImagePolymorphicSerializer :
89-
JsonContentPolymorphicSerializer<PromptMessageContentTextOrImage>(PromptMessageContentTextOrImage::class) {
90-
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<PromptMessageContentTextOrImage> {
89+
internal object PromptMessageContentMultimodalPolymorphicSerializer :
90+
JsonContentPolymorphicSerializer<PromptMessageContentMultimodal>(PromptMessageContentMultimodal::class) {
91+
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<PromptMessageContentMultimodal> {
9192
return when (element.jsonObject.getValue("type").jsonPrimitive.content) {
9293
ImageContent.TYPE -> ImageContent.serializer()
9394
TextContent.TYPE -> TextContent.serializer()
95+
AudioContent.TYPE -> AudioContent.serializer()
9496
else -> UnknownContent.serializer()
9597
}
9698
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.modelcontextprotocol.kotlin.sdk
2+
3+
import io.kotest.assertions.json.shouldEqualJson
4+
import io.modelcontextprotocol.kotlin.sdk.shared.McpJson
5+
import kotlinx.serialization.encodeToString
6+
import kotlin.test.Test
7+
import kotlin.test.assertEquals
8+
9+
class AudioContentSerializationTest {
10+
11+
private val audioContentJson = """
12+
{
13+
"data": "base64-encoded-audio-data",
14+
"mimeType": "audio/wav",
15+
"type": "audio"
16+
}
17+
""".trimIndent()
18+
19+
private val audioContent = AudioContent(
20+
data = "base64-encoded-audio-data",
21+
mimeType = "audio/wav"
22+
)
23+
24+
@Test
25+
fun `should serialize audio content`() {
26+
McpJson.encodeToString(audioContent) shouldEqualJson audioContentJson
27+
}
28+
29+
@Test
30+
fun `should deserialize audio content`() {
31+
val content = McpJson.decodeFromString<AudioContent>(audioContentJson)
32+
assertEquals(expected = audioContent, actual = content)
33+
}
34+
}

0 commit comments

Comments
 (0)