Conversation
… review Drop json.dumps's default=str so an unserializable argument is omitted rather than counted (TypeScript and Go already omit it), and encode with surrogatepass so a lone surrogate off the wire counts its 3 bytes instead of dropping the whole field. Add coverage for both, add a truncation leg to the tools/call ordering test, and note the two Go-only edge cases (empty-object counting, isError responses) plus serialization corner cases in the cross-SDK brief.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Tool-call events now carry
input_tokensandoutput_tokens: estimates of how many tokens the calling model spent on the tool arguments and how many it reads back from the tool result. AgentCat uses them for the oversized-tool-response rule and for per-tool token trends, and until now the server estimated both from the stored, redacted event payload. The SDK is the one place where the raw strings exist, so the estimate now happens there.This is a patch release:
agentcat2.1.1 on PyPI.What changes for you
mcp:tools/callevent includesinput_tokensandoutput_tokens. No configuration is needed and no option changes.context,session_id, andagent_id), and the output side counts only the text in the result'scontentblocks. The tool name, transport headers,structuredContent,isError, and the session mint-back text do not count.redact_sensitive_informationandredact_eventhooks run and before sanitization and truncation, so they describe the original size even when the stored strings are redacted or truncated. If that size must not leave your server, drop the two fields inredact_event.How the estimate works
ceil(utf8_bytes / 3.5), clamped to the server's integer column. The divisor comes from a measurement of 1,240 production tool responses: the text a model reads runs 3.71 bytes per token on OpenAI-family tokenizers and roughly 3.15 on Anthropic-family tokenizers, so 3.5 splits the difference. The same rules and the same test vectors are pinned across the TypeScript, Python, and Go SDKs, so all three report identical numbers for identical payloads.Dependency
Requires
agentcat-api1.0.2, which adds the two fields to the publish request. This PR pins the version once the package is published; until then it stays a draft.Testing
tests/test_token_estimate.py: the shared vector table (ASCII, accented and CJK text, HTML characters, empty and image-only content, resource blocks, the fallback for results without acontentlist, the int32 clamp, and the never-throw guards).tests/test_token_estimates_integration.py: real tool calls through every supported server flavor and MCP generation, asserting the counts on captured events, the error-result path, that redaction and truncation leave the counts unchanged, and that a broken estimator never breaks the tool call.mcpgeneration. A cross-SDK brief,2026-09-19-cross-sdk-token-estimates.md, documents the shared rules and vectors for maintainers of the other SDKs.