Repository navigation
Description
Describe the bug
With prompt and model-context capture both off (OPENCODE_CAPTURE_PROMPT_IN_LOGS and OPENCODE_CAPTURE_MODEL_CONTEXT unset), spans still record prompt text and tool inputs. The README describes prompt logging as off by default. Today those flags only gate the prompt attribute on the user_prompt log event; nothing gates the span attributes.
In the published @devtheops/opencode-plugin-otel@2.1.0 dist/index.js:
handleToolCalledsetstool.parametersandinput.valuetosafeJson(d.input)after the span is constructed, so it also overrides anything set throughspanAttributes. For a subagent or task call,d.inputincludes the full subagent prompt.handleExecutionStartedsetsinput.valueandllm.input_messagesto the session's prompt text.handleStepStarteddoes the same for LLM spans.- Output text is also attached to spans without a content check.
Neither handler reads capturePromptInLogs / captureModelContext. The only way to keep prompt content out of exported telemetry is OPENCODE_DISABLE_TRACES, which drops the spans entirely.
Steps to reproduce
- Enable telemetry with both capture flags unset.
- Run a session that dispatches a subagent with a distinctive prompt.
- Inspect the exported
opencode.tool.*span for the subagent call, and theopencode.sessionspan.tool.parameters/input.valueandllm.input_messagescontain the prompt text.
We also reproduced it offline by running the published handleToolCalled body against an in-memory span sink with capturePromptInLogs: false and captureModelContext: false. Both input.value and tool.parameters contained the synthetic prompt. They still did when spanAttributes set those keys to empty strings, because the later setAttributes call wins.
Expected behavior
Prompt-bearing and content-bearing span attributes follow the same opt-in as prompt logging:
- With content capture off: spans still emit, with structure, timings, token counts, tool name and agent name. Content attributes are omitted or replaced with lengths or hashes. That covers
input.value,tool.parameters,llm.input_messages, and output values. - With content capture on: today's behaviour.
A single switch for span content, such as OPENCODE_CAPTURE_SPAN_CONTENT or reusing OPENCODE_CAPTURE_MODEL_CONTEXT, would work. Off by default would match the README's privacy stance.
Environment
@devtheops/opencode-plugin-otel2.1.0- OpenCode 2.2.7 (
@opencode/cli) - OTLP
http/protobuf
Additional context
For now our deployment disables every trace type unless the operator opts in to content capture, keeping metrics and logs. We'd switch traces back on by default once spans can run content-free. We're also following #109; per-session trace context would let these spans nest under the calling service's trace.
Activity
jasoncarreira commentedon Nov 11, 2026
The same applies to OTLP logs in 2.1.0, not only spans:
errorSummary) concatenate the error type with the rawerror.message, which is unrestricted text. They're emitted as log attributes, for example thesession.errorevent and the tool result error attribute, and also written to the console.logsEnabled, not by the capture flags ordisabledTraces.So the only way to keep content out of exported telemetry today is to disable both traces and logs and keep metrics only, which is what we've done.
It would help if failure text followed the same content gate: with capture off, export the error type, a code and a hashed or length-only message.