A passive OpenInference/OTLP tracing adapter for Deep Agents Code (dcode) Hooks v2.
It reconstructs agent-turn, tool, and subagent spans without importing or patching
Deep Agents internals.
Status: alpha. The supported producer is deepagents-code==0.1.51 and its public
Hooks v2 wire contract. The in-process deepagents SDK is a separate integration
surface and is not instrumented by this package.
deepagents.turn (AGENT)
├── Bash / Read / Write / nested subagent tools / ... (TOOL)
└── task (TOOL)
└── subagent:<type> (AGENT)
Correlation uses producer-owned IDs: session_id, prompt_id, tool_use_id, and
agent_id. Trace and span IDs are deterministic derivatives of those values. In
deepagents-code==0.1.51, nested tool hook inputs do not carry the current subagent's
agent_id, so those tools remain direct children of the turn; the adapter will parent a
tool under a subagent when a future producer supplies that identity.
Every Stop event is exported as a separate attempt so a continuation requested by
another stop hook never creates duplicate OTLP span IDs.
The adapter also records session, permission, notification, and compaction lifecycle
signals as span events. SessionStart is attached to the first exported attempt;
SessionEnd emits a final lifecycle attempt and finalizes local session state. It does
not claim LLM spans, model-call usage, or tool failure status because Hooks v2 does not
expose those facts.
Requirements: Python 3.11+, a POSIX platform, and Deep Agents Code with Hooks v2.
In deepagents-code==0.1.51, the Hooks v2 runtime is experimental and must be enabled
in the environment of the dcode process:
uv tool install git+https://github.com/trashchenkov/deepagents-code-tracing.git
deepagents-code-tracing install
deepagents-code-tracing status
export DEEPAGENTS_CODE_EXPERIMENTAL=1The installer idempotently merges one direct-exec handler into each supported event in
~/.deepagents/hooks.json. Existing hooks are preserved. Malformed JSON is never
overwritten. Uninstall only removes entries marked as managed by this adapter:
deepagents-code-tracing uninstallPhoenix example:
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:6006
export OTEL_SERVICE_NAME=deepagents-code
export DEEPAGENTS_CODE_EXPERIMENTAL=1
deepagents-code-tracing doctor
dcodeOTEL_EXPORTER_OTLP_TRACES_ENDPOINT takes precedence and is used verbatim.
For OTEL_EXPORTER_OTLP_ENDPOINT, the adapter appends /v1/traces when needed. Requests
use standard OTLP JSON with Content-Type: application/json; a user-supplied
Content-Type header is ignored.
Supported environment variables:
| Variable | Default | Purpose |
|---|---|---|
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
unset | Exact traces endpoint |
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:6006 |
OTLP base endpoint |
OTEL_EXPORTER_OTLP_HEADERS |
unset | URL-encoded comma-separated headers |
OTEL_SERVICE_NAME |
deepagents-code |
Resource service name |
DEEPAGENTS_TRACE_ENABLED |
true |
Disable all state and export |
DEEPAGENTS_TRACE_CAPTURE_CONTENT |
false |
Include prompts/tool I/O/answers |
DEEPAGENTS_TRACE_EXPORT_TIMEOUT |
2 |
Per-request timeout in seconds |
DEEPAGENTS_TRACE_STATE_DIR |
XDG state directory | Correlation state location |
See .env.example; it contains no credentials.
Content capture is off by default. With that default, prompts, assistant messages, tool
inputs, tool responses, permission suggestions, notification text, transcript content,
and custom compaction instructions are not exported. Metadata such as working
directory, tool names, IDs, durations, model name from SessionStart, and allowlisted
lifecycle fields can still be sensitive.
The hook is passive: malformed input, unknown future events, state corruption, timeout, and exporter failure all produce exit code 0 and no stdout. This prevents telemetry from blocking or changing dcode decisions. Export is currently best-effort; a failed HTTP request is not durably retried.
State files are mode 0600 under the XDG state directory and contain correlation data.
They may contain content when capture is enabled. SessionEnd removes the completed
session state; interrupted sessions may leave state for a later event or manual cleanup.
The implementation is grounded in the upstream schema at
langchain-ai/deepagents@f4cc5160c75eb44e8ddee8b049048690ea0f8616:
libs/code/HOOKS.mdlibs/code/deepagents_code/hooks/models/wire.pylibs/code/deepagents_code/hooks/projection.pylibs/code/deepagents_code/hooks/server_middleware.py
See docs/contract.md for the field mapping and explicit fidelity boundary.
Important limitations:
- Hooks v2 has no model-call event or token usage.
- There is no distinct failed-tool event in the public wire contract.
- Hook inputs have no event timestamp; the adapter records local observation time.
- Matching hooks execute concurrently. A passive hook cannot know whether another Stop hook will request continuation, hence the explicit attempt model. Concurrent export completion order is not guaranteed.
- The adapter does not parse Deep Agents transcripts; their schema differs from Claude Code transcripts and does not contain complete model/tool envelopes.
env -u VIRTUAL_ENV UV_PROJECT_ENVIRONMENT=.venv uv sync --extra dev
env -u VIRTUAL_ENV UV_PROJECT_ENVIRONMENT=.venv uv run pytest
env -u VIRTUAL_ENV UV_PROJECT_ENVIRONMENT=.venv uv run ruff check .
env -u VIRTUAL_ENV UV_PROJECT_ENVIRONMENT=.venv uv run ruff format --check .
env -u VIRTUAL_ENV UV_PROJECT_ENVIRONMENT=.venv uv run mypyThe test suite validates span topology, privacy defaults, out-of-order events, installer merge/uninstall behavior, CLI fail-soft behavior, OTLP HTTP transport, and protobuf JSON conformance.
Apache-2.0.