Describe the bug
The LangChain usage extractors (provider_usage_extractors in the Python SDK) discard an already-extracted usage payload whenever the model-name or provider lookup raises. In try_extract_provider_usage_data, the orchestrator catches exceptions from get_llm_usage_info and returns None, so the span is emitted with no usage/cost even though the tokens were extractable.
Affected lookups (all unguarded against missing keys):
openai_usage_extractor: run_dict["extra"], run_dict["outputs"]["generations"][-1][-1]["generation_info"], and _get_provider's run_dict["extra"]
groq_usage_extractor, vertexai_usage_extractor, anthropic_vertexai_usage_extractor, google_generative_ai_usage_extractor: run_dict["extra"]
anthropic_usage_extractor: streaming path raises IndexError on empty generations (only KeyError is caught)
Reproduction: a streaming-shape OpenAI run whose usage sits in the message usage_metadata but whose generation dict has no generation_info key — try_extract_provider_usage_data returns None instead of the usage.
Expected behavior
Usage extraction should not depend on model metadata being present: extract the usage and return it with model=None when the model name cannot be resolved.
Describe the bug
The LangChain usage extractors (
provider_usage_extractorsin the Python SDK) discard an already-extracted usage payload whenever the model-name or provider lookup raises. Intry_extract_provider_usage_data, the orchestrator catches exceptions fromget_llm_usage_infoand returnsNone, so the span is emitted with no usage/cost even though the tokens were extractable.Affected lookups (all unguarded against missing keys):
openai_usage_extractor:run_dict["extra"],run_dict["outputs"]["generations"][-1][-1]["generation_info"], and_get_provider'srun_dict["extra"]groq_usage_extractor,vertexai_usage_extractor,anthropic_vertexai_usage_extractor,google_generative_ai_usage_extractor:run_dict["extra"]anthropic_usage_extractor: streaming path raisesIndexErroron empty generations (onlyKeyErroris caught)Reproduction: a streaming-shape OpenAI run whose usage sits in the message
usage_metadatabut whose generation dict has nogeneration_infokey —try_extract_provider_usage_datareturnsNoneinstead of the usage.Expected behavior
Usage extraction should not depend on model metadata being present: extract the usage and return it with
model=Nonewhen the model name cannot be resolved.