Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -276,6 +288,13 @@ internal object SessionUpdateSerializer : KSerializer<SessionUpdate> {
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 {
Expand Down Expand Up @@ -364,6 +383,10 @@ internal object SessionUpdateSerializer : KSerializer<SessionUpdate> {
SessionUpdate.AgentThoughtChunk.serializer(),
jsonObject
)
"agent_message_clear" -> ACPJson.decodeFromJsonElement(
SessionUpdate.AgentMessageClear.serializer(),
jsonObject
)
"tool_call" -> ACPJson.decodeFromJsonElement(
SessionUpdate.ToolCall.serializer(),
jsonObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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(
Expand Down Expand Up @@ -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": []}""",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:")
}
Expand Down
Loading