Skip to content

Commit 79895cb

Browse files
committed
Enhance OpenAI Stream Wrapper to Include Token Count Metrics
1 parent 0257808 commit 79895cb

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

agentops/instrumentation/openai/stream_wrapper.py

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from agentops.logging import logger
1616
from agentops.instrumentation.common.wrappers import _with_tracer_wrapper
17+
from agentops.instrumentation.openai.utils import is_metrics_enabled
1718
from agentops.instrumentation.openai.wrappers.chat import handle_chat_attributes
1819
from agentops.semconv import SpanAttributes, LLMRequestTypeValues, MessageAttributes
1920

@@ -195,22 +196,22 @@ def _finalize_stream(self) -> None:
195196
if len(self._tool_calls) > 0:
196197
for idx, tool_call in self._tool_calls.items():
197198
# Only set attributes if values are not None
198-
if tool_call["id"]:
199+
if tool_call["id"] is not None:
199200
self._span.set_attribute(
200201
MessageAttributes.COMPLETION_TOOL_CALL_ID.format(i=0, j=idx), tool_call["id"]
201202
)
202203

203-
if tool_call["type"]:
204+
if tool_call["type"] is not None:
204205
self._span.set_attribute(
205206
MessageAttributes.COMPLETION_TOOL_CALL_TYPE.format(i=0, j=idx), tool_call["type"]
206207
)
207208

208-
if tool_call["function"]["name"]:
209+
if tool_call["function"]["name"] is not None:
209210
self._span.set_attribute(
210211
MessageAttributes.COMPLETION_TOOL_CALL_NAME.format(i=0, j=idx), tool_call["function"]["name"]
211212
)
212213

213-
if tool_call["function"]["arguments"]:
214+
if tool_call["function"]["arguments"] is not None:
214215
self._span.set_attribute(
215216
MessageAttributes.COMPLETION_TOOL_CALL_ARGUMENTS.format(i=0, j=idx),
216217
tool_call["function"]["arguments"],
@@ -339,6 +340,19 @@ def chat_completion_stream_wrapper(tracer, wrapped, instance, args, kwargs):
339340
for key, value in request_attributes.items():
340341
span.set_attribute(key, value)
341342

343+
# Add include_usage to get token counts for streaming responses
344+
if is_streaming and is_metrics_enabled():
345+
# Add stream_options if it doesn't exist
346+
if "stream_options" not in kwargs:
347+
kwargs["stream_options"] = {"include_usage": True}
348+
logger.debug("[OPENAI WRAPPER] Adding stream_options.include_usage=True to get token counts")
349+
# If stream_options exists but doesn't have include_usage, add it
350+
elif isinstance(kwargs["stream_options"], dict) and "include_usage" not in kwargs["stream_options"]:
351+
kwargs["stream_options"]["include_usage"] = True
352+
logger.debug(
353+
"[OPENAI WRAPPER] Adding include_usage=True to existing stream_options to get token counts"
354+
)
355+
342356
# Call the original method
343357
response = wrapped(*args, **kwargs)
344358

@@ -395,6 +409,15 @@ async def async_chat_completion_stream_wrapper(tracer, wrapped, instance, args,
395409
for key, value in request_attributes.items():
396410
span.set_attribute(key, value)
397411

412+
# Add include_usage to get token counts for streaming responses
413+
if is_streaming and is_metrics_enabled():
414+
# Add stream_options if it doesn't exist
415+
if "stream_options" not in kwargs:
416+
kwargs["stream_options"] = {"include_usage": True}
417+
# If stream_options exists but doesn't have include_usage, add it
418+
elif isinstance(kwargs["stream_options"], dict) and "include_usage" not in kwargs["stream_options"]:
419+
kwargs["stream_options"]["include_usage"] = True
420+
398421
# Call the original method
399422
response = await wrapped(*args, **kwargs)
400423

agentops/instrumentation/openai/wrappers/chat.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def handle_chat_attributes(
137137
attributes[SpanAttributes.LLM_RESPONSE_ID] = response_dict["id"]
138138
if "model" in response_dict:
139139
attributes[SpanAttributes.LLM_RESPONSE_MODEL] = response_dict["model"]
140-
if "system_fingerprint" in response_dict:
140+
if "system_fingerprint" in response_dict and response_dict["system_fingerprint"] is not None:
141141
attributes[SpanAttributes.LLM_OPENAI_RESPONSE_SYSTEM_FINGERPRINT] = response_dict["system_fingerprint"]
142142

143143
# Usage
@@ -176,9 +176,9 @@ def handle_chat_attributes(
176176
if message:
177177
if "role" in message:
178178
attributes[f"{prefix}.role"] = message["role"]
179-
if "content" in message:
179+
if "content" in message and message["content"] is not None:
180180
attributes[f"{prefix}.content"] = message["content"]
181-
if "refusal" in message:
181+
if "refusal" in message and message["refusal"] is not None:
182182
attributes[f"{prefix}.refusal"] = message["refusal"]
183183

184184
# Function call

0 commit comments

Comments
 (0)