Skip to content

Commit 3a56116

Browse files
nikita-ashihminanna239
authored andcommitted
Preserve metadata on session message chunks
Make user, agent, and thought message chunks implement AcpWithMeta so provider metadata survives serialization and active prompt delivery. Add round-trip coverage for nested session notification metadata.
1 parent 9b30995 commit 3a56116

3 files changed

Lines changed: 81 additions & 22 deletions

File tree

acp-model/api/acp-model.api

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6351,17 +6351,19 @@ public abstract class com/agentclientprotocol/model/SessionUpdate {
63516351
public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$Companion;
63526352
}
63536353

6354-
public final class com/agentclientprotocol/model/SessionUpdate$AgentMessageChunk : com/agentclientprotocol/model/SessionUpdate {
6354+
public final class com/agentclientprotocol/model/SessionUpdate$AgentMessageChunk : com/agentclientprotocol/model/SessionUpdate, com/agentclientprotocol/model/AcpWithMeta {
63556355
public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk$Companion;
6356-
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6357-
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
6356+
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6357+
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
63586358
public final fun component1 ()Lcom/agentclientprotocol/model/ContentBlock;
63596359
public final fun component2-f2XpNSU ()Ljava/lang/String;
6360-
public final fun copy-eVVbJIE (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;)Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk;
6361-
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;
6360+
public final fun component3 ()Lkotlinx/serialization/json/JsonElement;
6361+
public final fun copy-5MJPFCQ (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionUpdate$AgentMessageChunk;
6362+
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;
63626363
public fun equals (Ljava/lang/Object;)Z
63636364
public final fun getContent ()Lcom/agentclientprotocol/model/ContentBlock;
63646365
public final fun getMessageId-f2XpNSU ()Ljava/lang/String;
6366+
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
63656367
public fun hashCode ()I
63666368
public fun toString ()Ljava/lang/String;
63676369
}
@@ -6381,17 +6383,19 @@ public final class com/agentclientprotocol/model/SessionUpdate$AgentMessageChunk
63816383
public final fun serializer ()Lkotlinx/serialization/KSerializer;
63826384
}
63836385

6384-
public final class com/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk : com/agentclientprotocol/model/SessionUpdate {
6386+
public final class com/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk : com/agentclientprotocol/model/SessionUpdate, com/agentclientprotocol/model/AcpWithMeta {
63856387
public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk$Companion;
6386-
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6387-
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
6388+
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6389+
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
63886390
public final fun component1 ()Lcom/agentclientprotocol/model/ContentBlock;
63896391
public final fun component2-f2XpNSU ()Ljava/lang/String;
6390-
public final fun copy-eVVbJIE (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;)Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk;
6391-
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;
6392+
public final fun component3 ()Lkotlinx/serialization/json/JsonElement;
6393+
public final fun copy-5MJPFCQ (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionUpdate$AgentThoughtChunk;
6394+
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;
63926395
public fun equals (Ljava/lang/Object;)Z
63936396
public final fun getContent ()Lcom/agentclientprotocol/model/ContentBlock;
63946397
public final fun getMessageId-f2XpNSU ()Ljava/lang/String;
6398+
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
63956399
public fun hashCode ()I
63966400
public fun toString ()Ljava/lang/String;
63976401
}
@@ -6776,17 +6780,19 @@ public final class com/agentclientprotocol/model/SessionUpdate$UsageUpdate$Compa
67766780
public final fun serializer ()Lkotlinx/serialization/KSerializer;
67776781
}
67786782

6779-
public final class com/agentclientprotocol/model/SessionUpdate$UserMessageChunk : com/agentclientprotocol/model/SessionUpdate {
6783+
public final class com/agentclientprotocol/model/SessionUpdate$UserMessageChunk : com/agentclientprotocol/model/SessionUpdate, com/agentclientprotocol/model/AcpWithMeta {
67806784
public static final field Companion Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk$Companion;
6781-
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6782-
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
6785+
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
6786+
public synthetic fun <init> (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
67836787
public final fun component1 ()Lcom/agentclientprotocol/model/ContentBlock;
67846788
public final fun component2-f2XpNSU ()Ljava/lang/String;
6785-
public final fun copy-eVVbJIE (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;)Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk;
6786-
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;
6789+
public final fun component3 ()Lkotlinx/serialization/json/JsonElement;
6790+
public final fun copy-5MJPFCQ (Lcom/agentclientprotocol/model/ContentBlock;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/SessionUpdate$UserMessageChunk;
6791+
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;
67876792
public fun equals (Ljava/lang/Object;)Z
67886793
public final fun getContent ()Lcom/agentclientprotocol/model/ContentBlock;
67896794
public final fun getMessageId-f2XpNSU ()Ljava/lang/String;
6795+
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
67906796
public fun hashCode ()I
67916797
public fun toString ()Ljava/lang/String;
67926798
}

acp-model/src/commonMain/kotlin/com/agentclientprotocol/model/SessionUpdate.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ public sealed class SessionUpdate {
9393
public data class UserMessageChunk(
9494
val content: ContentBlock,
9595
@property:UnstableApi
96-
val messageId: MessageId? = null
97-
) : SessionUpdate()
96+
val messageId: MessageId? = null,
97+
override val _meta: JsonElement? = null
98+
) : SessionUpdate(), AcpWithMeta
9899

99100
/**
100101
* A chunk of the agent's response being streamed.
@@ -105,8 +106,9 @@ public sealed class SessionUpdate {
105106
public data class AgentMessageChunk(
106107
val content: ContentBlock,
107108
@property:UnstableApi
108-
val messageId: MessageId? = null
109-
) : SessionUpdate()
109+
val messageId: MessageId? = null,
110+
override val _meta: JsonElement? = null
111+
) : SessionUpdate(), AcpWithMeta
110112

111113
/**
112114
* A chunk of the agent's internal reasoning being streamed.
@@ -117,8 +119,9 @@ public sealed class SessionUpdate {
117119
public data class AgentThoughtChunk(
118120
val content: ContentBlock,
119121
@property:UnstableApi
120-
val messageId: MessageId? = null
121-
) : SessionUpdate()
122+
val messageId: MessageId? = null,
123+
override val _meta: JsonElement? = null
124+
) : SessionUpdate(), AcpWithMeta
122125

123126
/**
124127
* Notification that a new tool call has been initiated.
@@ -470,4 +473,4 @@ internal object SessionUpdateSerializer : KSerializer<SessionUpdate> {
470473
}
471474
}
472475
}
473-
}
476+
}

acp-model/src/commonTest/kotlin/com/agentclientprotocol/model/SessionUpdateSerializerTest.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ package com.agentclientprotocol.model
22

33
import com.agentclientprotocol.annotations.UnstableApi
44
import com.agentclientprotocol.rpc.ACPJson
5+
import kotlinx.serialization.json.buildJsonObject
6+
import kotlinx.serialization.json.jsonObject
7+
import kotlinx.serialization.json.jsonPrimitive
8+
import kotlinx.serialization.json.put
59
import kotlin.test.Test
610
import kotlin.test.assertEquals
711
import kotlin.test.assertNotNull
@@ -129,6 +133,52 @@ class SessionUpdateSerializerTest {
129133
assertEquals("Test message", (decoded.content as ContentBlock.Text).text)
130134
}
131135

136+
@Test
137+
fun `message chunks preserve metadata`() {
138+
val metadata = buildJsonObject {
139+
put("provider", buildJsonObject { put("phase", "working") })
140+
}
141+
val updates = listOf(
142+
SessionUpdate.UserMessageChunk(ContentBlock.Text("User"), _meta = metadata),
143+
SessionUpdate.AgentMessageChunk(ContentBlock.Text("Agent"), _meta = metadata),
144+
SessionUpdate.AgentThoughtChunk(ContentBlock.Text("Thought"), _meta = metadata),
145+
)
146+
147+
for (original in updates) {
148+
val encoded = ACPJson.encodeToString(SessionUpdate.serializer(), original)
149+
val decoded = ACPJson.decodeFromString(SessionUpdate.serializer(), encoded)
150+
151+
assertEquals(metadata, (decoded as AcpWithMeta)._meta)
152+
}
153+
}
154+
155+
@Test
156+
fun `agent message metadata is preserved inside session notification`() {
157+
val payload = """
158+
{
159+
"sessionId": "session-123",
160+
"update": {
161+
"sessionUpdate": "agent_message_chunk",
162+
"messageId": "commentary-message",
163+
"content": {
164+
"type": "text",
165+
"text": "Checking the relevant event mapping."
166+
},
167+
"_meta": {
168+
"codex": {
169+
"phase": "commentary"
170+
}
171+
}
172+
}
173+
}
174+
""".trimIndent()
175+
176+
val notification = ACPJson.decodeFromString(SessionNotification.serializer(), payload)
177+
val update = notification.update as SessionUpdate.AgentMessageChunk
178+
179+
assertEquals("commentary", update._meta?.jsonObject?.get("codex")?.jsonObject?.get("phase")?.jsonPrimitive?.content)
180+
}
181+
132182
@Test
133183
fun `round-trip serialization for UsageUpdate`() {
134184
val original = SessionUpdate.UsageUpdate(

0 commit comments

Comments
 (0)