fix(vertexai): include thinking tokens in ChatVertexAI output_tokens - #1932
Open
kurniawan (codechrl) wants to merge 2 commits into
Open
Conversation
added 2 commits
August 7, 2026 16:55
_get_usage_metadata_gemini set output_tokens from candidates_token_count alone, leaving out thoughts_token_count even though total_tokens (the raw API's total) does include it. For any thinking-enabled Gemini call through ChatVertexAI, this breaks the UsageMetadata contract that input_tokens + output_tokens == total_tokens, and undercounts completion cost for anything priced off output_tokens. ChatGoogleGenerativeAI's _response_to_result in the same repo already adds thought_tokens into output_tokens correctly; mirror that here. Added a unit test asserting output_tokens folds in thinking tokens and that input_tokens + output_tokens == total_tokens holds.
…okens The integration tests assumed output_tokens excludes reasoning tokens and added them again when checking total_tokens. Per the UsageMetadata contract, output_tokens already includes reasoning tokens, so total_tokens must equal input_tokens + output_tokens exactly, not exceed it. These tests encoded the same bug this PR's source fix addresses. Verified live against gemini-2.5-flash on Vertex AI: all 6 thinking-related tests pass, including the two negative controls (thinking_budget=0) that were already using the correct assertion.
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.
Why
_get_usage_metadata_gemini(libs/vertexai/langchain_google_vertexai/chat_models.py) setsoutput_tokensfromcandidates_token_countalone:total_token_countfrom the raw Gemini API response already includes thinking tokens, so for any thinking-enabled Gemini call (gemini-2.5-flash/-pro) throughChatVertexAI,input_tokens + output_tokens != total_tokens— breaking theUsageMetadatacontract — and anything pricing offoutput_tokensundercounts completion cost.The sibling
ChatGoogleGenerativeAI._response_to_result(libs/genai/langchain_google_genai/chat_models.py) in this same repo already handles this correctly:What
Fold
thought_tokensintooutput_tokensin_get_usage_metadata_gemini, mirroring the workinggenaiimplementation.output_token_details={"reasoning": ...}is unchanged — it already correctly reports the reasoning subset.Tests
Added
test_get_usage_metadata_gemini_includes_thought_tokens_in_output_tokenstotests/unit_tests/test_chat_models.py, assertingoutput_tokensfolds in thinking tokens andinput_tokens + output_tokens == total_tokens. Confirmed test-first: fails onmain(5 == 25), passes with the fix. Fulltest_chat_models.py: 116 passed.ruff check/ruff format --checkclean.Areas worth a careful look
_get_usage_metadata_geminiis used by both the non-streaming (_gemini_response_to_chat_result) and streaming (_gemini_chunk_to_generation_chunk) paths, so this fixes both at once.thought_tokens == 0) is untouched —output_tokensthere was already correct.Disclaimer: this PR was prepared with the assistance of an AI agent (Claude Code). All code and test changes were reviewed by the author before submission.