Skip to content

feat(genai): surface usage_metadata.traffic_type in response_metadata - #1948

Open
koenroelofs-taktile wants to merge 2 commits into
langchain-ai:mainfrom
koenroelofs-taktile:feat/genai-traffic-type
Open

feat(genai): surface usage_metadata.traffic_type in response_metadata#1948
koenroelofs-taktile wants to merge 2 commits into
langchain-ai:mainfrom
koenroelofs-taktile:feat/genai-traffic-type

Conversation

@koenroelofs-taktile

@koenroelofs-taktile koenroelofs-taktile commented Aug 17, 2026

Copy link
Copy Markdown

Description

On the Vertex AI backend, GenerateContentResponse.usage_metadata includes traffic_type (ON_DEMAND, ON_DEMAND_PRIORITY, ON_DEMAND_FLEX, PROVISIONED_THROUGHPUT), reporting which quota served the request. _response_to_result reads token counts off that same object but drops this field, so there is no supported way to tell (e.g.) whether Priority Pay-as-you-go was granted for a given request. The raw response isn't kept on the ChatResult, so the value is unrecoverable downstream without monkeypatching.

This PR copies usage_metadata.traffic_type (as the enum name) onto message.response_metadata["traffic_type"] and generation_info["traffic_type"].

Areas for careful review: placement is gated on candidate.finish_reason so the value only appears on the final chunk when streaming — the same pattern model_name uses to avoid string duplication when chunks are concatenated with +=. When the backend doesn't report a traffic type (Gemini Developer API), the key is omitted entirely; an explicit TRAFFIC_TYPE_UNSPECIFIED is passed through as-is rather than filtered.

Relevant issues

Fixes #1947

Type

🆕 New Feature

Changes(optional)

  • _response_to_result: extract traffic_type from response.usage_metadata (via .name) and attach it to generation_info and response_metadata in a single finish_reason-gated block (final chunk only).
  • Class docstring: traffic_type added to the response metadata example (noted as Vertex-only).
  • Unit tests: happy path (both locations populated), omission when absent, and streaming (intermediate chunks clean, no duplication after += concatenation).

Testing(optional)

  • make test: 385 passed
  • make lint: ruff format, ruff check, and mypy all clean

Note(optional)

Disclaimer: this contribution was developed with the assistance of an AI agent (Claude Code), reviewed and directed by the issue author.

🤖 Generated with Claude Code

koenroelofs-taktile and others added 2 commits August 17, 2026 09:30
On the Vertex AI backend, GenerateContentResponse.usage_metadata includes
traffic_type (ON_DEMAND, ON_DEMAND_PRIORITY, ON_DEMAND_FLEX,
PROVISIONED_THROUGHPUT), reporting which quota served the request.
_response_to_result read token counts off that object but dropped this
field, leaving no supported way to read it downstream.

Copy it (as the enum name) onto response_metadata and generation_info,
gated on finish_reason so it only appears on the final chunk when
streaming - mirroring how model_name avoids duplication under chunk
concatenation with +=.

Fixes langchain-ai#1947

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ignment

TrafficType is a CaseInSensitiveEnum that coerces even unknown API values
to members with a .name, so the getattr/str fallback was dead code. Both
generation_info and response_metadata assignments now live in one
finish_reason-gated block (like grounding_metadata), and the class
docstring's response metadata example documents the new key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Surface Vertex usage_metadata.traffic_type on response_metadata in ChatGoogleGenerativeAI

1 participant