Skip to content

Commit fa73d91

Browse files
authored
fix(sdk): manual report of usage data (#3045)
1 parent 8449df8 commit fa73d91

File tree

4 files changed

+47
-206
lines changed

4 files changed

+47
-206
lines changed

packages/traceloop-sdk/tests/cassettes/test_manual/test_manual_report.yaml

Lines changed: 0 additions & 98 deletions
This file was deleted.

packages/traceloop-sdk/tests/cassettes/test_manual/test_resource_attributes.yaml

Lines changed: 0 additions & 98 deletions
This file was deleted.

packages/traceloop-sdk/tests/test_manual.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
from opentelemetry.semconv_ai import SpanAttributes
22
import pytest
33
from openai import OpenAI
4-
from traceloop.sdk.tracing.manual import LLMMessage, track_llm_call
4+
from traceloop.sdk.tracing.manual import LLMMessage, LLMUsage, track_llm_call
55

66

77
@pytest.fixture
88
def openai_client():
99
return OpenAI()
1010

1111

12-
@pytest.mark.vcr
1312
def test_manual_report(exporter, openai_client):
1413
with track_llm_call(vendor="openai", type="chat") as span:
1514
span.report_request(
@@ -19,14 +18,21 @@ def test_manual_report(exporter, openai_client):
1918
],
2019
)
2120

22-
res = openai_client.chat.completions.create(
23-
model="gpt-3.5-turbo",
24-
messages=[
25-
{"role": "user", "content": "Tell me a joke about opentelemetry"}
26-
],
27-
)
21+
res = [
22+
"Why did the opentelemetry developer break up with their partner? Because they were tired"
23+
+ " of constantly tracing their every move!",
24+
]
2825

29-
span.report_response(res.model, [text.message.content for text in res.choices])
26+
span.report_response("gpt-3.5-turbo-0125", res)
27+
span.report_usage(
28+
LLMUsage(
29+
prompt_tokens=15,
30+
completion_tokens=24,
31+
total_tokens=39,
32+
cache_creation_input_tokens=15,
33+
cache_read_input_tokens=18,
34+
)
35+
)
3036

3137
spans = exporter.get_finished_spans()
3238
open_ai_span = spans[0]
@@ -46,3 +52,13 @@ def test_manual_report(exporter, openai_client):
4652
+ " of constantly tracing their every move!"
4753
)
4854
assert open_ai_span.end_time > open_ai_span.start_time
55+
assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_PROMPT_TOKENS] == 15
56+
assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_COMPLETION_TOKENS] == 24
57+
assert open_ai_span.attributes[SpanAttributes.LLM_USAGE_TOTAL_TOKENS] == 39
58+
assert (
59+
open_ai_span.attributes[SpanAttributes.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS]
60+
== 15
61+
)
62+
assert (
63+
open_ai_span.attributes[SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS] == 18
64+
)

packages/traceloop-sdk/traceloop/sdk/tracing/manual.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class LLMUsage(BaseModel):
1414
prompt_tokens: int
1515
completion_tokens: int
1616
total_tokens: int
17+
cache_creation_input_tokens: int
18+
cache_read_input_tokens: int
1719

1820

1921
class LLMSpan:
@@ -40,9 +42,28 @@ def report_response(self, model: str, completions: list[str]):
4042
f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.role", "assistant"
4143
)
4244
self._span.set_attribute(
43-
f"{SpanAttributes.LLM_COMPLETIONS}.{idx}", completion
45+
f"{SpanAttributes.LLM_COMPLETIONS}.{idx}.content", completion
4446
)
4547

48+
def report_usage(self, usage: LLMUsage):
49+
self._span.set_attribute(
50+
SpanAttributes.LLM_USAGE_PROMPT_TOKENS, usage.prompt_tokens
51+
)
52+
self._span.set_attribute(
53+
SpanAttributes.LLM_USAGE_COMPLETION_TOKENS, usage.completion_tokens
54+
)
55+
self._span.set_attribute(
56+
SpanAttributes.LLM_USAGE_TOTAL_TOKENS, usage.total_tokens
57+
)
58+
self._span.set_attribute(
59+
SpanAttributes.LLM_USAGE_CACHE_CREATION_INPUT_TOKENS,
60+
usage.cache_creation_input_tokens,
61+
)
62+
self._span.set_attribute(
63+
SpanAttributes.LLM_USAGE_CACHE_READ_INPUT_TOKENS,
64+
usage.cache_read_input_tokens,
65+
)
66+
4667

4768
@contextmanager
4869
def track_llm_call(vendor: str, type: str):

0 commit comments

Comments
 (0)