Skip to content
Merged
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
52 changes: 47 additions & 5 deletions acp-model/api/acp-model.api
Original file line number Diff line number Diff line change
Expand Up @@ -4885,15 +4885,17 @@ public final class com/agentclientprotocol/model/PromptRequest$Companion {

public final class com/agentclientprotocol/model/PromptResponse : com/agentclientprotocol/model/AcpResponse {
public static final field Companion Lcom/agentclientprotocol/model/PromptResponse$Companion;
public synthetic fun <init> (Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lcom/agentclientprotocol/model/Usage;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lcom/agentclientprotocol/model/Usage;Lkotlinx/serialization/json/JsonElement;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lcom/agentclientprotocol/model/StopReason;
public final fun component2-f2XpNSU ()Ljava/lang/String;
public final fun component3 ()Lkotlinx/serialization/json/JsonElement;
public final fun copy-5MJPFCQ (Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/PromptResponse;
public static synthetic fun copy-5MJPFCQ$default (Lcom/agentclientprotocol/model/PromptResponse;Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/PromptResponse;
public final fun component3 ()Lcom/agentclientprotocol/model/Usage;
public final fun component4 ()Lkotlinx/serialization/json/JsonElement;
public final fun copy-hdWohc0 (Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lcom/agentclientprotocol/model/Usage;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/PromptResponse;
public static synthetic fun copy-hdWohc0$default (Lcom/agentclientprotocol/model/PromptResponse;Lcom/agentclientprotocol/model/StopReason;Ljava/lang/String;Lcom/agentclientprotocol/model/Usage;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/PromptResponse;
public fun equals (Ljava/lang/Object;)Z
public final fun getStopReason ()Lcom/agentclientprotocol/model/StopReason;
public final fun getUsage ()Lcom/agentclientprotocol/model/Usage;
public final fun getUserMessageId-f2XpNSU ()Ljava/lang/String;
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
public fun hashCode ()I
Expand Down Expand Up @@ -7483,6 +7485,46 @@ public final class com/agentclientprotocol/model/UrlElicitationRequiredItem$Comp
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/Usage : com/agentclientprotocol/model/AcpWithMeta {
public static final field Companion Lcom/agentclientprotocol/model/Usage$Companion;
public fun <init> (JJJLjava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Lkotlinx/serialization/json/JsonElement;)V
public synthetic fun <init> (JJJLjava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()J
public final fun component2 ()J
public final fun component3 ()J
public final fun component4 ()Ljava/lang/Long;
public final fun component5 ()Ljava/lang/Long;
public final fun component6 ()Ljava/lang/Long;
public final fun component7 ()Lkotlinx/serialization/json/JsonElement;
public final fun copy (JJJLjava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Lkotlinx/serialization/json/JsonElement;)Lcom/agentclientprotocol/model/Usage;
public static synthetic fun copy$default (Lcom/agentclientprotocol/model/Usage;JJJLjava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Lkotlinx/serialization/json/JsonElement;ILjava/lang/Object;)Lcom/agentclientprotocol/model/Usage;
public fun equals (Ljava/lang/Object;)Z
public final fun getCachedReadTokens ()Ljava/lang/Long;
public final fun getCachedWriteTokens ()Ljava/lang/Long;
public final fun getInputTokens ()J
public final fun getOutputTokens ()J
public final fun getThoughtTokens ()Ljava/lang/Long;
public final fun getTotalTokens ()J
public fun get_meta ()Lkotlinx/serialization/json/JsonElement;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final synthetic class com/agentclientprotocol/model/Usage$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
public static final field INSTANCE Lcom/agentclientprotocol/model/Usage$$serializer;
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lcom/agentclientprotocol/model/Usage;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lcom/agentclientprotocol/model/Usage;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/Usage$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class com/agentclientprotocol/model/WaitForTerminalExitRequest : com/agentclientprotocol/model/AcpRequest, com/agentclientprotocol/model/AcpWithSessionId {
public static final field Companion Lcom/agentclientprotocol/model/WaitForTerminalExitRequest$Companion;
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Lkotlinx/serialization/json/JsonElement;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,25 @@ public data class NewSessionResponse(
override val _meta: JsonElement? = null
) : AcpCreatedSessionResponse, AcpResponse, AcpWithSessionId

/**
* **UNSTABLE**
*
* This capability is not part of the spec yet, and may be removed or changed at any point.
*
* Token usage for a prompt turn.
*/
@UnstableApi
@Serializable
public data class Usage(
val inputTokens: Long,
val outputTokens: Long,
val totalTokens: Long,
val thoughtTokens: Long? = null,
val cachedReadTokens: Long? = null,
val cachedWriteTokens: Long? = null,
override val _meta: JsonElement? = null
) : AcpWithMeta

/**
* Response from processing a user prompt.
*
Expand All @@ -698,6 +717,8 @@ public data class PromptResponse(
val stopReason: StopReason,
@property:UnstableApi
val userMessageId: MessageId? = null,
@property:UnstableApi
val usage: Usage? = null,
override val _meta: JsonElement? = null
) : AcpResponse

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.agentclientprotocol.model
import com.agentclientprotocol.rpc.ACPJson
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
import kotlin.test.assertTrue

class SerializationTests {
Expand Down Expand Up @@ -140,4 +141,73 @@ class SerializationTests {
assertEquals(500000L, update.size)
assertEquals(null, update.cost)
}

@Test
fun `decodes PromptResponse with usage`() {
val payload = """
{
"stopReason": "end_turn",
"usage": {
"inputTokens": 100,
"outputTokens": 200,
"totalTokens": 300,
"thoughtTokens": 50,
"cachedReadTokens": 10,
"cachedWriteTokens": 5
}
}
""".trimIndent()

val response = ACPJson.decodeFromString(PromptResponse.serializer(), payload)

assertEquals(StopReason.END_TURN, response.stopReason)
val usage = response.usage
assertTrue(usage != null)
assertEquals(100L, usage.inputTokens)
assertEquals(200L, usage.outputTokens)
assertEquals(300L, usage.totalTokens)
assertEquals(50L, usage.thoughtTokens)
assertEquals(10L, usage.cachedReadTokens)
assertEquals(5L, usage.cachedWriteTokens)
}

@Test
fun `decodes PromptResponse with usage omitting optional fields`() {
val payload = """
{
"stopReason": "end_turn",
"usage": {
"inputTokens": 100,
"outputTokens": 200,
"totalTokens": 300
}
}
""".trimIndent()

val response = ACPJson.decodeFromString(PromptResponse.serializer(), payload)

assertEquals(StopReason.END_TURN, response.stopReason)
val usage = response.usage
assertTrue(usage != null)
assertEquals(100L, usage.inputTokens)
assertEquals(200L, usage.outputTokens)
assertEquals(300L, usage.totalTokens)
assertNull(usage.thoughtTokens)
assertNull(usage.cachedReadTokens)
assertNull(usage.cachedWriteTokens)
}

@Test
fun `decodes PromptResponse without usage`() {
val payload = """
{
"stopReason": "end_turn"
}
""".trimIndent()

val response = ACPJson.decodeFromString(PromptResponse.serializer(), payload)

assertEquals(StopReason.END_TURN, response.stopReason)
assertNull(response.usage)
}
}
Loading