fix: honor gen_ai payload capture disable regardless of OTel env vars - #18
Merged
shreyas-n-harness merged 1 commit intoJul 27, 2026
Conversation
Payload capture only worked in the enable direction: genai_env checked pre-existing OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT / OTEL_SEMCONV_STABILITY_OPT_IN before reading config and returned without forcing anything off, the LiteLLM wrapper gated gen_ai.input.messages only on litellm's own flags, and the MCP mirror skipped TRACELOOP_TRACE_CONTENT when preset. Deployments that set those OTel vars themselves kept shipping prompts even with payload_capture_enabled=false. Disable is a privacy control, so config now wins over the environment: it forces NO_CONTENT and a non-experimental semconv mode, gates the LiteLLM input attribute on config, and force-disables Traceloop content capture. A scrub span processor in the default pipeline strips payload attributes before export as a backstop for instrumentations the SDK does not wrap. Co-authored-by: Cursor <cursoragent@cursor.com>
|
|
t-santoshsahu
approved these changes
Jul 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
gen_ai_input.messagekeeps showing up in UDP for services that set GenAI payload capture to false (HARNESS_GEN_AI_PAYLOAD_CAPTURE_ENABLED=false/gen_ai.payload_capture_enabled: false).The flag only ever worked in the enable direction. Three leaks:
genai_env.maybe_set_genai_payload_capture_env_vars()checked pre-existingOTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT/OTEL_SEMCONV_STABILITY_OPT_INbefore reading config and bailed out. On disable it also just returned without forcing anything off. Any deployment that sets those OTel vars itself (shared base image, another auto-instrumentation layer) keeps capturing content, so OpenAI / Anthropic / Google GenAI wrappers emitgen_ai.input.messages.gen_ai.input.messagesgated only onlitellm.turn_off_message_logging/otel_logger.message_logging— it never consulted Harness config.TRACELOOP_TRACE_CONTENT.Fix
Payload capture is a privacy control, so false must mean false: config now wins over the environment in the disable direction, while the enable path keeps supplying defaults only (user-set env still wins).
genai_env.py— config checked first; disabling forcesOTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=NO_CONTENTand patches the cached semconv stability mode forGEN_AItoDEFAULT, overwriting whatever the environment had.litellm/__init__.py— explicitpayload_capture_enabledgate before settinggen_ai.input.messages.mcp/gen_ai_mirror.py— forceTRACELOOP_TRACE_CONTENT=falsewhen disabled, even if preset.GenAiPayloadScrubSpanProcessor, wired as the outermost layer of the default pipeline. When capture is disabled it stripsgen_ai.input.messages,gen_ai.output.messages,gen_ai.system_instruction,gen_ai.prompt*,gen_ai.completion*,traceloop.entity.input/outputaton_end. This is the backstop for third-party OTel contrib instrumentations the SDK does not wrap. Cheap no-op when capture is enabled.Test plan
./scripts/run-unit-tests.sh— 219 passed, 1 skipped. The 2 gRPC failures (test_grpc_1,test_grpc_2) reproduce on unmodifiedmainin the same sandbox (local port binding), unrelated to this change.NO_CONTENT; LiteLLM emits no input messages when disabled; MCP forcesTRACELOOP_TRACE_CONTENT=false; enabled path leaves user env untouched; scrub processor strips attributes when disabled and no-ops when enabled.HARNESS_GEN_AI_PAYLOAD_CAPTURE_ENABLED=falsethatgen_ai_input.messageno longer reaches UDP.Note
test/conftest.py'sreset_singletonsdoes not reset the module-level_appliedflag ingenai_env.py, so in a full run that function's logic executes only once. The new tests reset it locally. Worth a separate cleanup.Made with Cursor