Skip to content

Commit c1572e8

Browse files
committed
Add support for UsageUpdate in SessionUpdate interface and related tests
1 parent a3e979e commit c1572e8

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

acp-core/src/main/java/com/agentclientprotocol/sdk/spec/AcpSchema.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,8 @@ public record Annotations(@JsonProperty("audience") List<Role> audience, @JsonPr
809809
@JsonSubTypes.Type(value = ToolCallUpdateNotification.class, name = "tool_call_update"),
810810
@JsonSubTypes.Type(value = Plan.class, name = "plan"),
811811
@JsonSubTypes.Type(value = AvailableCommandsUpdate.class, name = "available_commands_update"),
812-
@JsonSubTypes.Type(value = CurrentModeUpdate.class, name = "current_mode_update") })
812+
@JsonSubTypes.Type(value = CurrentModeUpdate.class, name = "current_mode_update"),
813+
@JsonSubTypes.Type(value = UsageUpdate.class, name = "usage_update") })
813814
public interface SessionUpdate {
814815

815816
}
@@ -932,6 +933,20 @@ public CurrentModeUpdate(String sessionUpdate, String currentModeId) {
932933
}
933934
}
934935

936+
/**
937+
* Usage update - reports token/resource usage for the session
938+
*/
939+
@JsonIgnoreProperties(ignoreUnknown = true)
940+
@JsonInclude(JsonInclude.Include.NON_NULL)
941+
public record UsageUpdate(@JsonProperty("sessionUpdate") String sessionUpdate,
942+
@JsonProperty("used") Long used,
943+
@JsonProperty("size") Long size,
944+
@JsonProperty("_meta") Map<String, Object> meta) implements SessionUpdate {
945+
public UsageUpdate(String sessionUpdate, Long used, Long size) {
946+
this(sessionUpdate, used, size, null);
947+
}
948+
}
949+
935950
// ---------------------------
936951
// Tool Call Types
937952
// ---------------------------

acp-core/src/test/java/com/agentclientprotocol/sdk/spec/SessionUpdateDeserializationTest.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import static org.assertj.core.api.Assertions.assertThat;
1616

1717
/**
18-
* Tests for deserializing all 8 SessionUpdate types from JSON.
18+
* Tests for deserializing all 9 SessionUpdate types from JSON.
1919
*
2020
* <p>
2121
* These tests verify that each SessionUpdate type can be correctly deserialized from JSON,
@@ -258,6 +258,27 @@ void currentModeUpdateDeserialization() throws IOException {
258258
assertThat(modeUpdate.currentModeId()).isEqualTo("architect");
259259
}
260260

261+
// ---------------------------
262+
// UsageUpdate Tests
263+
// ---------------------------
264+
265+
@Test
266+
void usageUpdateDeserialization() throws IOException {
267+
String json = loadGolden("session-update-usage-update.json");
268+
269+
// The golden file is a full JSON-RPC notification; extract the inner update
270+
com.fasterxml.jackson.databind.JsonNode root = new com.fasterxml.jackson.databind.ObjectMapper().readTree(json);
271+
String updateJson = root.get("params").get("update").toString();
272+
273+
AcpSchema.SessionUpdate update = deserializeSessionUpdate(updateJson);
274+
275+
assertThat(update).isInstanceOf(AcpSchema.UsageUpdate.class);
276+
AcpSchema.UsageUpdate usageUpdate = (AcpSchema.UsageUpdate) update;
277+
assertThat(usageUpdate.sessionUpdate()).isEqualTo("usage_update");
278+
assertThat(usageUpdate.used()).isEqualTo(53000L);
279+
assertThat(usageUpdate.size()).isEqualTo(200000L);
280+
}
281+
261282
// ---------------------------
262283
// All Status Values Tests
263284
// ---------------------------

acp-core/src/test/java/com/agentclientprotocol/sdk/test/GoldenFileTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ void parseSessionUpdateNotification() throws IOException {
8686
assertThat(node.get("params").get("update").get("sessionUpdate").asText()).isEqualTo("agentMessage");
8787
}
8888

89+
@Test
90+
void parseSessionUpdateUsageUpdate() throws IOException {
91+
String json = loadGoldenFile("session-update-usage-update.json");
92+
JsonNode node = objectMapper.readTree(json);
93+
94+
assertThat(node.get("method").asText()).isEqualTo("session/update");
95+
assertThat(node.has("id")).isFalse();
96+
assertThat(node.get("params").get("sessionId").asText()).isEqualTo("sess_abc123");
97+
JsonNode update = node.get("params").get("update");
98+
assertThat(update.get("sessionUpdate").asText()).isEqualTo("usage_update");
99+
assertThat(update.get("used").asLong()).isEqualTo(53000L);
100+
assertThat(update.get("size").asLong()).isEqualTo(200000L);
101+
}
102+
89103
@Test
90104
void serializeInitializeRequestMatchesExpectedStructure() throws IOException {
91105
AcpSchema.InitializeRequest request = new AcpSchema.InitializeRequest(1, new AcpSchema.ClientCapabilities());
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"jsonrpc": "2.0",
3+
"method": "session/update",
4+
"params": {
5+
"sessionId": "sess_abc123",
6+
"update": {
7+
"sessionUpdate": "usage_update",
8+
"used": 53000,
9+
"size": 200000
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)