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 @@ -809,7 +809,8 @@ public record Annotations(@JsonProperty("audience") List<Role> audience, @JsonPr
@JsonSubTypes.Type(value = ToolCallUpdateNotification.class, name = "tool_call_update"),
@JsonSubTypes.Type(value = Plan.class, name = "plan"),
@JsonSubTypes.Type(value = AvailableCommandsUpdate.class, name = "available_commands_update"),
@JsonSubTypes.Type(value = CurrentModeUpdate.class, name = "current_mode_update") })
@JsonSubTypes.Type(value = CurrentModeUpdate.class, name = "current_mode_update"),
@JsonSubTypes.Type(value = UsageUpdate.class, name = "usage_update") })
public interface SessionUpdate {

}
Expand Down Expand Up @@ -932,6 +933,20 @@ public CurrentModeUpdate(String sessionUpdate, String currentModeId) {
}
}

/**
* Usage update - reports token/resource usage for the session
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public record UsageUpdate(@JsonProperty("sessionUpdate") String sessionUpdate,
@JsonProperty("used") Long used,
@JsonProperty("size") Long size,
@JsonProperty("_meta") Map<String, Object> meta) implements SessionUpdate {
public UsageUpdate(String sessionUpdate, Long used, Long size) {
this(sessionUpdate, used, size, null);
}
}

// ---------------------------
// Tool Call Types
// ---------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import static org.assertj.core.api.Assertions.assertThat;

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

// ---------------------------
// UsageUpdate Tests
// ---------------------------

@Test
void usageUpdateDeserialization() throws IOException {
String json = loadGolden("session-update-usage-update.json");

// The golden file is a full JSON-RPC notification; extract the inner update
com.fasterxml.jackson.databind.JsonNode root = new com.fasterxml.jackson.databind.ObjectMapper().readTree(json);
String updateJson = root.get("params").get("update").toString();

AcpSchema.SessionUpdate update = deserializeSessionUpdate(updateJson);

assertThat(update).isInstanceOf(AcpSchema.UsageUpdate.class);
AcpSchema.UsageUpdate usageUpdate = (AcpSchema.UsageUpdate) update;
assertThat(usageUpdate.sessionUpdate()).isEqualTo("usage_update");
assertThat(usageUpdate.used()).isEqualTo(53000L);
assertThat(usageUpdate.size()).isEqualTo(200000L);
}

// ---------------------------
// All Status Values Tests
// ---------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ void parseSessionUpdateNotification() throws IOException {
assertThat(node.get("params").get("update").get("sessionUpdate").asText()).isEqualTo("agentMessage");
}

@Test
void parseSessionUpdateUsageUpdate() throws IOException {
String json = loadGoldenFile("session-update-usage-update.json");
JsonNode node = objectMapper.readTree(json);

assertThat(node.get("method").asText()).isEqualTo("session/update");
assertThat(node.has("id")).isFalse();
assertThat(node.get("params").get("sessionId").asText()).isEqualTo("sess_abc123");
JsonNode update = node.get("params").get("update");
assertThat(update.get("sessionUpdate").asText()).isEqualTo("usage_update");
assertThat(update.get("used").asLong()).isEqualTo(53000L);
assertThat(update.get("size").asLong()).isEqualTo(200000L);
}

@Test
void serializeInitializeRequestMatchesExpectedStructure() throws IOException {
AcpSchema.InitializeRequest request = new AcpSchema.InitializeRequest(1, new AcpSchema.ClientCapabilities());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"jsonrpc": "2.0",
"method": "session/update",
"params": {
"sessionId": "sess_abc123",
"update": {
"sessionUpdate": "usage_update",
"used": 53000,
"size": 200000
}
}
}