diff --git a/acp-model/api/acp-model.api b/acp-model/api/acp-model.api index f7af3f2..3c52cc3 100644 --- a/acp-model/api/acp-model.api +++ b/acp-model/api/acp-model.api @@ -6351,17 +6351,19 @@ public abstract class com/agentclientprotocol/model/SessionUpdate { public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$Companion; } -public final class com/agentclientprotocol/model/SessionUpdate$AgentMessageChunk : com/agentclientprotocol/model/SessionUpdate { +public final class com/agentclientprotocol/model/SessionUpdate$AgentMessageChunk : com/agentclientprotocol/model/SessionUpdate, com/agentclientprotocol/model/AcpWithMeta { public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk$Companion; - public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lcom/agentclientprotocol/model/ContentBlock; public final fun component2-f2XpNSU ()Ljava/lang/String; - public final fun copy-eVVbJIE (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;)Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk; - public static synthetic fun copy-eVVbJIE$default (Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk;Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk; + public final fun component3 ()Lkotlinx/serialization/json/JsonElement; + public final fun copy-5MJPFCQ (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk; + public static synthetic fun copy-5MJPFCQ$default (Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk;Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk; public fun equals (Ljava/lang/Object;)Z public final fun getContent ()Lcom/agentclientprotocol/model/ContentBlock; public final fun getMessageId-f2XpNSU ()Ljava/lang/String; + public fun get_meta ()Lkotlinx/serialization/json/JsonElement; public fun hashCode ()I public fun toString ()Ljava/lang/String; } @@ -6381,17 +6383,19 @@ public final class com/agentclientprotocol/model/SessionUpdate$AgentMessageChunk public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public final class com/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk : com/agentclientprotocol/model/SessionUpdate { +public final class com/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk : com/agentclientprotocol/model/SessionUpdate, com/agentclientprotocol/model/AcpWithMeta { public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk$Companion; - public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lcom/agentclientprotocol/model/ContentBlock; public final fun component2-f2XpNSU ()Ljava/lang/String; - public final fun copy-eVVbJIE (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;)Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk; - public static synthetic fun copy-eVVbJIE$default (Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk;Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk; + public final fun component3 ()Lkotlinx/serialization/json/JsonElement; + public final fun copy-5MJPFCQ (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk; + public static synthetic fun copy-5MJPFCQ$default (Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk;Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk; public fun equals (Ljava/lang/Object;)Z public final fun getContent ()Lcom/agentclientprotocol/model/ContentBlock; public final fun getMessageId-f2XpNSU ()Ljava/lang/String; + public fun get_meta ()Lkotlinx/serialization/json/JsonElement; public fun hashCode ()I public fun toString ()Ljava/lang/String; } @@ -6776,17 +6780,19 @@ public final class com/agentclientprotocol/model/SessionUpdate$UsageUpdate$Compa public final fun serializer ()Lkotlinx/serialization/KSerializer; } -public final class com/agentclientprotocol/model/SessionUpdate$UserMessageChunk : com/agentclientprotocol/model/SessionUpdate { +public final class com/agentclientprotocol/model/SessionUpdate$UserMessageChunk : com/agentclientprotocol/model/SessionUpdate, com/agentclientprotocol/model/AcpWithMeta { public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk$Companion; - public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Lcom/agentclientprotocol/model/ContentBlock; public final fun component2-f2XpNSU ()Ljava/lang/String; - public final fun copy-eVVbJIE (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;)Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk; - public static synthetic fun copy-eVVbJIE$default (Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk;Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk; + public final fun component3 ()Lkotlinx/serialization/json/JsonElement; + public final fun copy-5MJPFCQ (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk; + public static synthetic fun copy-5MJPFCQ$default (Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk;Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk; public fun equals (Ljava/lang/Object;)Z public final fun getContent ()Lcom/agentclientprotocol/model/ContentBlock; public final fun getMessageId-f2XpNSU ()Ljava/lang/String; + public fun get_meta ()Lkotlinx/serialization/json/JsonElement; public fun hashCode ()I public fun toString ()Ljava/lang/String; } diff --git a/acp-model/src/commonMain/kotlin/com/agentclientprotocol/model/SessionUpdate.kt b/acp-model/src/commonMain/kotlin/com/agentclientprotocol/model/SessionUpdate.kt index e4a58a4..b641a01 100644 --- a/acp-model/src/commonMain/kotlin/com/agentclientprotocol/model/SessionUpdate.kt +++ b/acp-model/src/commonMain/kotlin/com/agentclientprotocol/model/SessionUpdate.kt @@ -93,8 +93,9 @@ public sealed class SessionUpdate { public data class UserMessageChunk( val content: ContentBlock, @property:UnstableApi - val messageId: MessageId? = null - ) : SessionUpdate() + val messageId: MessageId? = null, + override val _meta: JsonElement? = null + ) : SessionUpdate(), AcpWithMeta /** * A chunk of the agent's response being streamed. @@ -105,8 +106,9 @@ public sealed class SessionUpdate { public data class AgentMessageChunk( val content: ContentBlock, @property:UnstableApi - val messageId: MessageId? = null - ) : SessionUpdate() + val messageId: MessageId? = null, + override val _meta: JsonElement? = null + ) : SessionUpdate(), AcpWithMeta /** * A chunk of the agent's internal reasoning being streamed. @@ -117,8 +119,9 @@ public sealed class SessionUpdate { public data class AgentThoughtChunk( val content: ContentBlock, @property:UnstableApi - val messageId: MessageId? = null - ) : SessionUpdate() + val messageId: MessageId? = null, + override val _meta: JsonElement? = null + ) : SessionUpdate(), AcpWithMeta /** * Notification that a new tool call has been initiated. @@ -470,4 +473,4 @@ internal object SessionUpdateSerializer : KSerializer { } } } -} \ No newline at end of file +} diff --git a/acp-model/src/commonTest/kotlin/com/agentclientprotocol/model/SessionUpdateSerializerTest.kt b/acp-model/src/commonTest/kotlin/com/agentclientprotocol/model/SessionUpdateSerializerTest.kt index 285e5ed..96dac4c 100644 --- a/acp-model/src/commonTest/kotlin/com/agentclientprotocol/model/SessionUpdateSerializerTest.kt +++ b/acp-model/src/commonTest/kotlin/com/agentclientprotocol/model/SessionUpdateSerializerTest.kt @@ -2,6 +2,10 @@ package com.agentclientprotocol.model import com.agentclientprotocol.annotations.UnstableApi import com.agentclientprotocol.rpc.ACPJson +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import kotlinx.serialization.json.put import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotNull @@ -129,6 +133,52 @@ class SessionUpdateSerializerTest { assertEquals("Test message", (decoded.content as ContentBlock.Text).text) } + @Test + fun `message chunks preserve metadata`() { + val metadata = buildJsonObject { + put("provider", buildJsonObject { put("phase", "working") }) + } + val updates = listOf( + SessionUpdate.UserMessageChunk(ContentBlock.Text("User"), _meta = metadata), + SessionUpdate.AgentMessageChunk(ContentBlock.Text("Agent"), _meta = metadata), + SessionUpdate.AgentThoughtChunk(ContentBlock.Text("Thought"), _meta = metadata), + ) + + for (original in updates) { + val encoded = ACPJson.encodeToString(SessionUpdate.serializer(), original) + val decoded = ACPJson.decodeFromString(SessionUpdate.serializer(), encoded) + + assertEquals(metadata, (decoded as AcpWithMeta)._meta) + } + } + + @Test + fun `agent message metadata is preserved inside session notification`() { + val payload = """ + { + "sessionId": "session-123", + "update": { + "sessionUpdate": "agent_message_chunk", + "messageId": "commentary-message", + "content": { + "type": "text", + "text": "Checking the relevant event mapping." + }, + "_meta": { + "codex": { + "phase": "commentary" + } + } + } + } + """.trimIndent() + + val notification = ACPJson.decodeFromString(SessionNotification.serializer(), payload) + val update = notification.update as SessionUpdate.AgentMessageChunk + + assertEquals("commentary", update._meta?.jsonObject?.get("codex")?.jsonObject?.get("phase")?.jsonPrimitive?.content) + } + @Test fun `round-trip serialization for UsageUpdate`() { val original = SessionUpdate.UsageUpdate(