Skip to content

Commit 4dc7c8e

Browse files
committed
Address feedback
1 parent e7f4520 commit 4dc7c8e

3 files changed

Lines changed: 20 additions & 12 deletions

File tree

instrumentation/opentelemetry-instrumentation-genai-langchain/src/opentelemetry/instrumentation/genai/langchain/callback_handler.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -323,17 +323,19 @@ def on_llm_end(
323323

324324
# Token usage (extracted regardless of whether the message
325325
# produced output parts — some tool-call-only responses can
326-
# still report token counts).
326+
# still report token counts). Only set the counts when the
327+
# provider actually reported them; defaulting to 0 would
328+
# fabricate telemetry when the keys are absent.
327329
if message.usage_metadata:
328-
input_tokens = message.usage_metadata.get(
329-
"input_tokens", 0
330-
)
331-
llm_invocation.input_tokens = input_tokens
330+
input_tokens = message.usage_metadata.get("input_tokens")
331+
if input_tokens is not None:
332+
llm_invocation.input_tokens = input_tokens
332333

333334
output_tokens = message.usage_metadata.get(
334-
"output_tokens", 0
335+
"output_tokens"
335336
)
336-
llm_invocation.output_tokens = output_tokens
337+
if output_tokens is not None:
338+
llm_invocation.output_tokens = output_tokens
337339

338340
llm_invocation.output_messages = output_messages
339341

instrumentation/opentelemetry-instrumentation-genai-langchain/src/opentelemetry/instrumentation/genai/langchain/utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def normalize_provider(metadata: Optional[dict[str, Any]]) -> Optional[str]:
5151
if not metadata:
5252
return None
5353
raw = metadata.get("ls_provider")
54-
if not raw:
54+
if not isinstance(raw, str) or not raw:
5555
return None
5656
return _PROVIDER_NAME_OVERRIDES.get(raw, raw)
5757

@@ -216,7 +216,9 @@ def make_input_message(data: Any) -> list[InputMessage]:
216216
data_dict = cast(dict[str, Any], data)
217217
messages: Any = data_dict.get("messages")
218218
if messages is not None:
219-
if not isinstance(messages, list):
219+
if isinstance(messages, (str, bytes)) or not isinstance(
220+
messages, Iterable
221+
):
220222
return []
221223
return to_input_messages(messages)
222224
# Fallback: serialize non-message state fields as input.
@@ -247,7 +249,11 @@ def make_output_message(data: Any) -> list[OutputMessage]:
247249
return []
248250
data_dict = cast(dict[str, Any], data)
249251
messages: Any = data_dict.get("messages")
250-
if not isinstance(messages, list):
252+
if (
253+
messages is None
254+
or isinstance(messages, (str, bytes))
255+
or not isinstance(messages, Iterable)
256+
):
251257
return []
252258
return to_output_messages(messages)
253259

instrumentation/opentelemetry-instrumentation-genai-langchain/tests/test_llm_call.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ def assert_gemini_completion_attributes(
380380
assert span.attributes["gen_ai.provider.name"] == "gcp.gen_ai"
381381

382382
input_tokens = response.usage_metadata.get("input_tokens")
383-
if input_tokens:
383+
if input_tokens is not None:
384384
assert (
385385
input_tokens
386386
== span.attributes[gen_ai_attributes.GEN_AI_USAGE_INPUT_TOKENS]
@@ -391,7 +391,7 @@ def assert_gemini_completion_attributes(
391391
)
392392

393393
output_tokens = response.usage_metadata.get("output_tokens")
394-
if output_tokens:
394+
if output_tokens is not None:
395395
assert (
396396
output_tokens
397397
== span.attributes[gen_ai_attributes.GEN_AI_USAGE_OUTPUT_TOKENS]

0 commit comments

Comments
 (0)