Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix: handle Map type in getChatUsage() after deserialization#1118

Merged
LearningGp merged 2 commits into
agentscope-ai:mainfrom
mvanhorn:fix/chat-usage-map-deserialization
Apr 20, 2026
Merged

fix: handle Map type in getChatUsage() after deserialization#1118
LearningGp merged 2 commits into
agentscope-ai:mainfrom
mvanhorn:fix/chat-usage-map-deserialization

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

@mvanhorn mvanhorn commented Apr 3, 2026

Summary

getChatUsage() returns null when _chat_usage metadata is a Map (after session persistence/reload) instead of a ChatUsage object.

Why this matters

When messages are persisted via agent.loadFrom() and reloaded, JSON deserialization converts the _chat_usage metadata value to a Map<String, Object> instead of a ChatUsage instance. The existing instanceof ChatUsage check fails, returning null even though the token usage data exists in the metadata.

Changes

agentscope-core/src/main/java/io/agentscope/core/message/Msg.java:

  • Added Map handling in getChatUsage() (line 413): when the metadata value is a Map, extract inputTokens, outputTokens, and time fields, build a ChatUsage via the builder, and cache it back in metadata for subsequent calls
  • Added toInt() and toDouble() helper methods for safe numeric conversion from deserialized values (handles Integer, Long, Double from JSON)

Testing

  • When _chat_usage is a ChatUsage object: unchanged behavior
  • When _chat_usage is a Map (post-deserialization): converts to ChatUsage and returns it
  • When _chat_usage is null or absent: returns null (unchanged)
  • The converted ChatUsage is cached back in metadata so the conversion only happens once

Fixes #1115

This contribution was developed with AI assistance (Claude Code).

When messages are persisted and reloaded, the _chat_usage metadata
value may be deserialized as a Map instead of a ChatUsage object.
The getter now detects this case, converts the Map to ChatUsage, and
caches the result back in metadata for subsequent calls.

Fixes agentscope-ai#1115
@mvanhorn mvanhorn requested a review from a team April 3, 2026 07:03
@cla-assistant
Copy link
Copy Markdown

cla-assistant Bot commented Apr 3, 2026

CLA assistant check
All committers have signed the CLA.

@yadavsharn
Copy link
Copy Markdown

Hey @mvanhorn, great fix 👍

I noticed the CI build is failing—this might be due to type casting issues when converting values from the Map. Since JSON deserialization can produce Integer, Long, or Double, direct casting might cause failures.

Maybe using Number and converting via .intValue() / .doubleValue() could make it safer.

Happy to help test or contribute improvements if needed 🚀

@mvanhorn
Copy link
Copy Markdown
Contributor Author

mvanhorn commented Apr 4, 2026

Thanks for the review! The Number casting approach is actually already in place (using .intValue() / .doubleValue()), so the type safety concern should be covered.

The CI failure was a spotless formatting issue with the builder chain indentation. Fixed in 536b3c8.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 16.66667% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../src/main/java/io/agentscope/core/message/Msg.java 16.66% 14 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Collaborator

@LearningGp LearningGp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@LearningGp LearningGp merged commit 9f9e69a into agentscope-ai:main Apr 20, 2026
5 of 6 checks passed
@mvanhorn
Copy link
Copy Markdown
Contributor Author

Thanks for the merge, @LearningGp. Map handling in getChatUsage was a real corner case.

liangxingguang pushed a commit to liangxingguang/agentscope-java that referenced this pull request May 21, 2026
…ope-ai#1118)

## Summary

`getChatUsage()` returns null when `_chat_usage` metadata is a Map
(after session persistence/reload) instead of a ChatUsage object.

## Why this matters

When messages are persisted via `agent.loadFrom()` and reloaded, JSON
deserialization converts the `_chat_usage` metadata value to a
`Map<String, Object>` instead of a `ChatUsage` instance. The existing
`instanceof ChatUsage` check fails, returning null even though the token
usage data exists in the metadata.

## Changes

`agentscope-core/src/main/java/io/agentscope/core/message/Msg.java`:

- Added Map handling in `getChatUsage()` (line 413): when the metadata
value is a Map, extract `inputTokens`, `outputTokens`, and `time`
fields, build a ChatUsage via the builder, and cache it back in metadata
for subsequent calls
- Added `toInt()` and `toDouble()` helper methods for safe numeric
conversion from deserialized values (handles Integer, Long, Double from
JSON)

## Testing

- When `_chat_usage` is a ChatUsage object: unchanged behavior
- When `_chat_usage` is a Map (post-deserialization): converts to
ChatUsage and returns it
- When `_chat_usage` is null or absent: returns null (unchanged)
- The converted ChatUsage is cached back in metadata so the conversion
only happens once

Fixes agentscope-ai#1115

This contribution was developed with AI assistance (Claude Code).

---------

Co-authored-by: Matt Van Horn <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: getChatUsage

3 participants