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 d300b36..95e1ecd 100644 --- a/acp-model/src/commonMain/kotlin/com/agentclientprotocol/model/SessionUpdate.kt +++ b/acp-model/src/commonMain/kotlin/com/agentclientprotocol/model/SessionUpdate.kt @@ -111,6 +111,18 @@ public sealed class SessionUpdate { val content: ContentBlock ) : SessionUpdate() + /** + * Clears the accumulated streamed content for the current agent message. + * + * Instructs the client to clear the content built from previous [AgentMessageChunk] updates. + * Subsequent [AgentMessageChunk] updates will append from empty again. + * + * See: [agent_message_clear RFD](https://github.com/agentclientprotocol/agent-client-protocol/pull/465) + */ + @Serializable + @SerialName("agent_message_clear") + public data class AgentMessageClear() : SessionUpdate() + /** * Notification that a new tool call has been initiated. */ @@ -276,6 +288,13 @@ internal object SessionUpdateSerializer : KSerializer { base.forEach { (k, v) -> put(k, v) } } } + is SessionUpdate.AgentMessageClear -> { + val base = ACPJson.encodeToJsonElement(SessionUpdate.AgentMessageClear.serializer(), value).jsonObject + buildJsonObject { + put(SESSION_UPDATE_DISCRIMINATOR, "agent_message_clear") + base.forEach { (k, v) -> put(k, v) } + } + } is SessionUpdate.ToolCall -> { val base = ACPJson.encodeToJsonElement(SessionUpdate.ToolCall.serializer(), value).jsonObject buildJsonObject { @@ -364,6 +383,10 @@ internal object SessionUpdateSerializer : KSerializer { SessionUpdate.AgentThoughtChunk.serializer(), jsonObject ) + "agent_message_clear" -> ACPJson.decodeFromJsonElement( + SessionUpdate.AgentMessageClear.serializer(), + jsonObject + ) "tool_call" -> ACPJson.decodeFromJsonElement( SessionUpdate.ToolCall.serializer(), jsonObject 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 8e18318..7d6186f 100644 --- a/acp-model/src/commonTest/kotlin/com/agentclientprotocol/model/SessionUpdateSerializerTest.kt +++ b/acp-model/src/commonTest/kotlin/com/agentclientprotocol/model/SessionUpdateSerializerTest.kt @@ -115,6 +115,19 @@ class SessionUpdateSerializerTest { // Round-trip serialization tests + @Test + fun `decodes agent_message_clear correctly`() { + val payload = """ + { + "sessionUpdate": "agent_message_clear" + } + """.trimIndent() + + val update = ACPJson.decodeFromString(SessionUpdate.serializer(), payload) + + assertTrue(update is SessionUpdate.AgentMessageClear) + } + @Test fun `round-trip serialization for known types`() { val original = SessionUpdate.AgentMessageChunk( @@ -129,6 +142,17 @@ class SessionUpdateSerializerTest { assertEquals("Test message", (decoded.content as ContentBlock.Text).text) } + @Test + fun `round-trip serialization for AgentMessageClear`() { + val original = SessionUpdate.AgentMessageClear() + + val encoded = ACPJson.encodeToString(SessionUpdate.serializer(), original) + assertTrue(encoded.contains("\"sessionUpdate\":\"agent_message_clear\"")) + + val decoded = ACPJson.decodeFromString(SessionUpdate.serializer(), encoded) + assertTrue(decoded is SessionUpdate.AgentMessageClear) + } + @Test fun `round-trip serialization for UsageUpdate`() { val original = SessionUpdate.UsageUpdate( @@ -257,6 +281,7 @@ class SessionUpdateSerializerTest { """{"sessionUpdate": "user_message_chunk", "content": {"type": "text", "text": "test"}}""", """{"sessionUpdate": "agent_message_chunk", "content": {"type": "text", "text": "test"}}""", """{"sessionUpdate": "agent_thought_chunk", "content": {"type": "text", "text": "test"}}""", + """{"sessionUpdate": "agent_message_clear"}""", """{"sessionUpdate": "tool_call", "toolCallId": "t1", "title": "test"}""", """{"sessionUpdate": "tool_call_update", "toolCallId": "t1"}""", """{"sessionUpdate": "plan", "entries": []}""", diff --git a/samples/kotlin-acp-client-sample/src/main/kotlin/com/agentclientprotocol/samples/util.kt b/samples/kotlin-acp-client-sample/src/main/kotlin/com/agentclientprotocol/samples/util.kt index 4d36884..68e52fd 100644 --- a/samples/kotlin-acp-client-sample/src/main/kotlin/com/agentclientprotocol/samples/util.kt +++ b/samples/kotlin-acp-client-sample/src/main/kotlin/com/agentclientprotocol/samples/util.kt @@ -13,6 +13,10 @@ fun SessionUpdate.render() { println("Agent thinks: ${this.content.render()}") } + is SessionUpdate.AgentMessageClear -> { + println("Agent message cleared") + } + is SessionUpdate.AvailableCommandsUpdate -> { println("Available commands updated:") }