Skip to content

Better log the usage: tokens, cost #6

Description

@cmoulliard

Improvement: Add proper UsageUpdate type and PromptResponse usage field - ACP

Context

The ACP agent (Claude) sends two forms of usage data that are currently not properly handled:

  1. usage_update session notifications — streamed during prompt processing with fields used, size, cost. Currently deserialized as a raw Map causing a DEBUG log: "Unknown session update type: usage_update". Handled via instanceof Map in the client default branch.

  2. usage field in the final PromptResponse — returned in the JSON-RPC result with token details (inputTokens, outputTokens, cachedReadTokens, cachedWriteTokens, totalTokens). Currently
    silently dropped because PromptResponse only has stopReason.

Neither type is defined in the ACP schema JSON — they are agent extensions. We add Java records to handle them properly.

Changes

1. Create UsageUpdate record

File: schema/src/main/java/io/quarkiverse/agentclientprotocol/sdk/spec/schema/v1/UsageUpdate.java

Fields based on observed JSON: _meta, used (Integer), size (Integer), cost (Map<String, Object> — contains amount and currency).

Follows the same pattern as ConfigOptionUpdate, CurrentModeUpdate, etc.

2. Register usage_update in SESSION_UPDATE_TYPES

File: core/src/main/java/io/quarkiverse/agentclientprotocol/sdk/client/AcpAsyncClient.java

Add: Map.entry("usage_update", UsageUpdate.class) to the map.

This eliminates the "Unknown session update type" debug log.

3. Add usage field to PromptResponse

File: schema/src/main/java/io/quarkiverse/agentclientprotocol/sdk/spec/schema/v1/PromptResponse.java

Add @JsonProperty("usage") Map<String, Object> usage to capture token data. Using Map<String, Object> since this is an agent extension not standardized in the schema.

4. Update handleSessionUpdate in both clients

Files:

  • client/src/main/java/io/quarkiverse/acp/AcpAgentCommand.java
  • client/src/main/java/io/quarkiverse/acp/AcpAgentCli.java

Replace the default branch instanceof Map check with a typed case UsageUpdate branch. Log: [Usage] used=X size=Y cost=Z.

5. Log token usage from PromptResponse

Files:

  • client/src/main/java/io/quarkiverse/acp/AcpAgentCommand.java
  • client/src/main/java/io/quarkiverse/acp/AcpAgentCli.java

After logging stop reason, log response.usage() if present. Example:
Done! Stop reason: END_TURN
[Tokens] input=9 output=3972 cachedRead=176852 cachedWrite=35080 total=215913

Verification

  • mvn compile -pl client -am should succeed
  • Run with -l DEBUG — no more "Unknown session update type: usage_update" log
  • [Usage] line should still appear with used, size, cost
  • After "Done!" line, token details should be logged

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions