Skip to content

Commit f4bca6b

Browse files
committed
fix(openai-agents): apply content tracing flag to content
1 parent f782741 commit f4bca6b

File tree

5 files changed

+63
-15
lines changed

5 files changed

+63
-15
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ npm-debug.log
3333
yarn-error.log
3434
testem.log
3535
/typings
36+
.tool-versions
3637

3738
# System Files
3839
.DS_Store

CONTRIBUTING.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,35 @@ Thanks for taking the time to contribute! 😃 🚀
44

55
Please refer to our [Contributing Guide](https://traceloop.com/docs/openllmetry/contributing/overview) for instructions on how to contribute.
66

7+
## Local Testing and Linting in this Repo
8+
9+
A few steps to set up this repo locally.
10+
11+
Run the following at repo root to setup the yarn dependencies.
12+
```shell
13+
npm ci
14+
```
15+
16+
Install `poetry` (version 2) at the system-level (e.g. using `pipx` or `brew`).
17+
18+
For setting up and testing an individual package, run the following from repo root.
19+
20+
```shell
21+
npx nx run opentelemetry-instrumentation-openai:install --with dev,test
22+
npx nx run opentelemetry-instrumentation-openai:lint
23+
npx nx run opentelemetry-instrumentation-openai:test
24+
```
25+
26+
Or you can run the following to automatically setup all affected packages.
27+
```shell
28+
npx nx affected -t install --with dev,test
29+
npx nx affected -t lint
30+
npx nx affected -t test
31+
```
32+
33+
## Build Errors
34+
35+
If encountering local build errors in environment setup, try a lower python version, e.g. 3.11.
36+
There are `.python-version` files in individual package directories, but poetry may not reliably respect it.
37+
Depending on your python installation, you may need to set your python version accordingly at repo root (e.g. with a `.python-version` or `.tool-versions`).
38+
The `.venv` dir within each package must be deleted before you retry the poetry/nx command, as it will not clear the existing venv and pick up the updated, lower version specified until the existing venv has been deleted manually.

packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/_hooks.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Hook-based instrumentation for OpenAI Agents using the SDK's native callback system."""
22

3-
from typing import Dict, Any
3+
from typing import Dict, Any, Final
44
import json
55
import time
66
from collections import OrderedDict
@@ -11,7 +11,7 @@
1111
gen_ai_attributes as GenAIAttributes
1212
)
1313
from agents.tracing.processors import TracingProcessor
14-
from .utils import dont_throw
14+
from .utils import dont_throw, should_send_prompts
1515

1616
from traceloop.sdk.tracing import set_agent_name
1717

@@ -233,6 +233,7 @@ def on_span_end(self, span):
233233
if span in self._otel_spans:
234234
otel_span = self._otel_spans[span]
235235
span_data = getattr(span, 'span_data', None)
236+
should_trace_content: Final[bool] = should_send_prompts()
236237
if span_data and (
237238
type(span_data).__name__ == 'ResponseSpanData' or isinstance(
238239
span_data,
@@ -298,7 +299,7 @@ def on_span_end(self, span):
298299
otel_span.set_attribute(f"{prefix}.role", role)
299300

300301
# Set content attribute
301-
if content is not None:
302+
if should_trace_content and content is not None:
302303
if not isinstance(content, str):
303304
content = json.dumps(content)
304305
otel_span.set_attribute(f"{prefix}.content", content)
@@ -399,7 +400,7 @@ def on_span_end(self, span):
399400
if hasattr(response, 'output') and response.output:
400401
for i, output in enumerate(response.output):
401402
# Handle different output types
402-
if hasattr(output, 'content') and output.content:
403+
if should_trace_content and hasattr(output, 'content') and output.content:
403404
# Text message with content array (ResponseOutputMessage)
404405
content_text = ""
405406
for content_item in output.content:
@@ -430,7 +431,7 @@ def on_span_end(self, span):
430431
otel_span.set_attribute(
431432
f"{GenAIAttributes.GEN_AI_COMPLETION}.{i}.tool_calls.0.id", tool_call_id)
432433

433-
elif hasattr(output, 'text'):
434+
elif should_trace_content and hasattr(output, 'text'):
434435
# Direct text content
435436
otel_span.set_attribute(f"{GenAIAttributes.GEN_AI_COMPLETION}.{i}.content", output.text)
436437
otel_span.set_attribute(
@@ -466,7 +467,7 @@ def on_span_end(self, span):
466467
elif span_data:
467468
# Extract prompt data from input and add to response span (legacy support)
468469
input_data = getattr(span_data, 'input', [])
469-
if input_data:
470+
if should_trace_content and input_data:
470471
for i, message in enumerate(input_data):
471472
if hasattr(message, 'role') and hasattr(message, 'content'):
472473
otel_span.set_attribute(f"gen_ai.prompt.{i}.role", message.role)
@@ -508,7 +509,7 @@ def on_span_end(self, span):
508509
if hasattr(response, 'output') and response.output:
509510
for i, output in enumerate(response.output):
510511
# Handle different output types
511-
if hasattr(output, 'content') and output.content:
512+
if should_trace_content and hasattr(output, 'content') and output.content:
512513
# Text message with content array (ResponseOutputMessage)
513514
content_text = ""
514515
for content_item in output.content:
@@ -539,7 +540,7 @@ def on_span_end(self, span):
539540
otel_span.set_attribute(
540541
f"{GenAIAttributes.GEN_AI_COMPLETION}.{i}.tool_calls.0.id", tool_call_id)
541542

542-
elif hasattr(output, 'text'):
543+
elif should_trace_content and hasattr(output, 'text'):
543544
# Direct text content
544545
otel_span.set_attribute(f"{GenAIAttributes.GEN_AI_COMPLETION}.{i}.content", output.text)
545546
otel_span.set_attribute(

packages/opentelemetry-instrumentation-openai-agents/opentelemetry/instrumentation/openai_agents/utils.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import traceback
77
from opentelemetry import context as context_api
88

9+
_TRACELOOP_TRACE_CONTENT = "TRACELOOP_TRACE_CONTENT"
10+
911

1012
def set_span_attribute(span, name, value):
1113
if value is not None:
@@ -18,10 +20,14 @@ def _is_truthy(value):
1820
return str(value).strip().lower() in ("true", "1", "yes", "on")
1921

2022

21-
def should_send_prompts():
22-
env_setting = os.getenv("TRACELOOP_TRACE_CONTENT", "true")
23+
def should_send_prompts() -> bool:
24+
"""Determine if LLM content tracing should be enabled.
25+
26+
Content includes not only prompts, but also responses.
27+
"""
28+
env_setting = os.getenv(_TRACELOOP_TRACE_CONTENT, "true")
2329
override = context_api.get_value("override_enable_content_tracing")
24-
return _is_truthy(env_setting) or bool(override)
30+
return _is_truthy(env_setting) or _is_truthy(override)
2531

2632

2733
class JSONEncoder(json.JSONEncoder):

packages/opentelemetry-instrumentation-openai/opentelemetry/instrumentation/openai/utils.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,18 @@ def run_async(method):
174174
asyncio.run(method)
175175

176176

177-
def should_send_prompts():
178-
return (
179-
os.getenv(TRACELOOP_TRACE_CONTENT) or "true"
180-
).lower() == "true" or context_api.get_value("override_enable_content_tracing")
177+
def _is_truthy(value):
178+
return str(value).strip().lower() in ("true", "1", "yes", "on")
179+
180+
181+
def should_send_prompts() -> bool:
182+
"""Determine if LLM content tracing should be enabled.
183+
184+
Content includes not only prompts, but also responses.
185+
"""
186+
env_setting = os.getenv(TRACELOOP_TRACE_CONTENT, "true")
187+
override = context_api.get_value("override_enable_content_tracing")
188+
return _is_truthy(env_setting) or _is_truthy(override)
181189

182190

183191
def should_emit_events() -> bool:

0 commit comments

Comments
 (0)