NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
PyPI · #3132 most downloaded on PyPI
Test agent for Datadog APM client libraries
Last release 13 days ago
21 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
5 years old
105 releases · first in 2021
One column per quarter.
The ddapm-test-agent --lapdog-mode entry point is deprecated, use python -m lapdog.server instead (including in Docker commands). The preferred way of…
--version and --help flags for the lapdog CLI (e.g. lapdog --version).ddapm-test-agent --lapdog-mode entry point is deprecated, use python -m lapdog.server instead (including in Docker commands). The preferred way of using Lapdog is via the CLI lapdog binary. It remains available as a compatibility alias.meta["span.kind"] form (instead of the nested meta["span"]["kind"] form the ddtrace LLMObs writer emits today) now have their kind preserved through the lapdog UI trace and list endpoints. Previously tool, agent, workflow, retrieval, and embedding spans submitted in the flat form were silently rendered as kind="llm".lapdog codex from capturing unrelated Codex sessions in the same working directory.DD_AGENT_URL. The forwarded body is re-serialized with json.dumps, making it longer than the agent's compact JSON, but the agent's Content-Length was relayed verbatim. The response was cut to that length and tracers failed to parse it. The headers describing the original encoding are now recomputed from the body actually sent.Add cost tracking for more of the latest Claude and Codex models. Claude: claude-sonnet-5 (\$3 / \$15 per Mtok) and claude-fable-5 / claude-mythos-5 (
claude-sonnet-5 ($3 / $15 per Mtok) and claude-fable-5 / claude-mythos-5 ($10 / $50). Codex/OpenAI: gpt-5.6 and gpt-5.6-terra, plus gpt-5.3-codex (the current Codex CLI default). Without these entries, spans for the newest models fell through and were reported with no estimated cost. Where a rate was ambiguous (Sonnet 5's introductory price, the disputed gpt-5.6 "Luna" tier) the higher estimate is used, since these costs are only estimates.Include native v1 trace requests in the /test/session/requests response.
v1 trace requests in the /test/session/requests response.Add a lapdog tags set command to allow agents to add custom tags to their own Lapdog spans.
lapdog tags set command to allow agents to add custom tags to their own Lapdog spans.lapdog: Route path-form launcher invocations (e.g. lapdog ~/.local/bin/claude) to the dedicated launcher instead of the generic exec wrapper, which pr
lapdog ~/.local/bin/claude) to the dedicated launcher instead of the generic exec wrapper, which previously broke Python subprocesses with [lapdog] ddtrace is not installed.vcr: Add support for normalizing parts of JSON request bodies via regular expression when recording requests via --vcr-body-regex-normalizers or VCR_B
--vcr-body-regex-normalizers or VCR_BODY_REGEX_NORMALIZERS. This option should take a comma-separated list of regular expressions to normalize, e.g. agentId: [a-f0-9]+,duration_ms: \\d+.DD_APM_RECEIVER_SOCKET (or --trace-uds-socket) replaced the TCP listener with a socket-only listener, so clients and container healthchecks reaching the agent over the published port received "connection refused". This restores the historical behavior where both transports are bound together.Add support for span events with array attributes (for example a list of strings or numbers) in v1 trace payloads. These were previously unsupported;
v1 trace payloads. These were previously unsupported; they are now decoded the same way as in v0.4/v0.7 payloads, including arrays that mix value types.The sampling mechanism (field 7) should only be represented on the first span in a chunk
Added the new environment variable DD_AGENT_EXTRA_INFO to allow adding entries to the /info response.
DD_AGENT_EXTRA_INFO to allow adding entries to the /info response.Explore / Task) under the step span that launched them, in the same trace and session. Previously each subagent session was backfilled as its own standalone session.Added a --host command-line argument (and HOST environment variable) to control the interface all servers bind to. Defaults to 127.0.0.1.
--host command-line argument (and HOST environment variable) to control the interface all servers bind to. Defaults to 127.0.0.1.lapdog --backfill claude, lapdog --backfill codex, and lapdog --backfill pi for one-shot ingestion of historical agent sessions from disk.127.0.0.1 instead of all interfaces. To accept connections from other hosts (for example when running outside of a container and pointing a remote tracer at the agent), pass --host 0.0.0.0 or set HOST=0.0.0.0. The published Docker images set HOST=0.0.0.0 automatically, so their published ports keep working.127.0.0.1 (loopback) by default instead of all network interfaces. Previously the HTTP, OTLP HTTP, OTLP gRPC, and Web UI servers were reachable from any host on the network, which could expose captured data (including lapdog Claude Code / Codex / Pi session content) to other machines on the same network.span_kind set to 0 (unspecified) and convert them without emitting a span.kind tag, matching the behavior of equivalent v0.4 payloads.Sampling mechanism for ETP is represented only when it is not 0
Represent trace IDs as hex strings (without the 0x) for ETP traces.
0x) for ETP traces.Lapdog (pi): a failed LLM call now produces an LLM span marked as an error (with the provider error message) instead of an empty step. Covers both pi'
stopReason: "error" path and the case where an exception unwinds the agent loop before message_end is emitted.agent_start events emitted by agent.continue() (after auto-compaction or auto-retry) no longer create new, input-less traces. They now extend the current trace so each trace maps to one user turn and always carries the user's prompt as input.turn_end events no longer close the next active turn, preventing extra empty step spans.Lapdog: Support tagging coding agent spans with commit hashes (using the git.commit.sha tag).
git.commit.sha tag).meta_struct["_llmobs"] on v0.4 traces) to look identical to LLM Observability sent via the EVP proxy (/evp_proxy/v4/api/v2/llmobs), so tests can assert on a single format regardless of how the tracer delivered the spans./model switch. The session span now reflects the model selected during the session rather than always showing the model set at session start.lapdog start, lapdog stop, and lapdog claude work on Windows. Previously the launcher used POSIX-only primitives (os.fork, start_new_session=True) so the background agent process was killed when the launcher exited, and the banner printed by lapdog claude crashed Python on the default Windows cp1252 stdout encoding. The Bun preload path passed to Claude via BUN_OPTIONS also had its backslashes stripped on Windows.Lapdog: Add claude-opus-4-8 to the Claude Code cost tracking table and 1M-token context model set. Regular-usage pricing matches Opus 4.7 (\$5 / \$25
claude-opus-4-8 to the Claude Code cost tracking table and 1M-token context model set. Regular-usage pricing matches Opus 4.7 ($5 / $25 / $0.50 cache-read / $6.25 cache-write per Mtok). Previously Opus 4.8 spans fell through the pricing table and received no cost estimate.DD_GIT_REPOSITORY_URL environment variable, the local git remote, or the working directory basename (in that order) and attached to spans as project_name / git.repository_url tags plus matching meta.metadata fields.Lapdog: adds a lapdog uninstall command that kills the running lapdog process, removes its working directory, and uninstalls all relevant coding agent
lapdog uninstall command that kills the running lapdog process, removes its working directory, and uninstalls all relevant coding agent plugins, extensions, and hooks.lapdog codex app so Codex Desktop sessions from launched and newly created workspaces are captured in Lapdog. App launches now resolve Desktop workspace paths, keep an all-workspace Codex JSONL watcher alive after the short-lived launcher exits, reuse active app watchers, and replace stale or legacy watchers.OSErrors ([Errno 22] Invalid argument)lapdog.Advertise /v1.0/traces in the endpoints list returned by /info so tracers using the standard V1 enablement flow (DD_TRACE_AGENT_PROTOCOL_VERSION=1.0)
/v1.0/traces in the endpoints list returned by /info so tracers using the standard V1 enablement flow (DD_TRACE_AGENT_PROTOCOL_VERSION=1.0) can negotiate V1 against the test-agent without client-side overrides.10) in V1 trace payloads. Attributes such as _dd.apm_mode and _dd.git.commit.sha are now propagated to every span in the payload, matching the behavior of the upstream Datadog Agent.Add lapdog codex command for tracing Codex coding agent sessions through the test agent. The command watches Codex session logs, forwards hook events
Add lapdog codex command for tracing Codex coding agent sessions through the test agent. The command watches Codex session logs, forwards hook events to the local test agent, and records current model/provider details on agent, LLM, and tool spans.
Ship a lapdog Claude Code plugin from a marketplace homed in this repository. After claude plugin marketplace add DataDog/dd-apm-test-agent and claude plugin install lapdog@lapdog, Claude Code POSTs every hook event (PreToolUse, PostToolUse, UserPromptSubmit, SessionStart, ...) to http://localhost:8126/claude/hooks without lapdog claude
having to mutate ~/.claude/settings.json.
lapdog claude now auto-installs the lapdog Claude Code plugin from the in-repo marketplace if it is not already installed (runs claude plugin marketplace add DataDog/dd-apm-test-agent and claude plugin install lapdog@lapdog). Detection is via ~/.claude/plugins/installed_plugins.json, so already-installed users pay no overhead. Skip the auto-install with --no-plugin-install. Install failures print the manual commands and continue launching Claude uninstrumented rather than blocking the session.
lapdog claude no longer writes Claude Code hook entries to ~/.claude/settings.json. The previous --disable-claude-code-hooks flag has been removed and replaced by the auto-installed Claude Code plugin, which is now the only integration path. The lapdog/hooks.py helper that mutated ~/.claude/settings.json is deleted. Users who previously ran lapdog claude with the older default (or with the short-lived --hooks opt-in) should delete the stale hook entries that POST to localhost:8126/claude/hooks from their ~/.claude/settings.json — otherwise, once the plugin auto-installs, both the plugin's hooks and the settings.json hooks will fire on every event and produce duplicate instrumentation.Adds lapdog_forwarded tags to all payloads forwarded from the test agent to DD when run from the lapdog binary
lapdog_forwarded tags to all payloads forwarded from the test agent to DD when run from the lapdog binaryFixes an issue where lapdog would not properly instrument applications or warn where no ddtrace was available
lapdog would not properly instrument applications or warn where no ddtrace was availableAdd org_prop_marker field to the /info endpoint, configurable via the ORG_PROP_MARKER environment variable or --org-prop-marker CLI flag.
org_prop_marker field to the /info endpoint, configurable via the ORG_PROP_MARKER environment variable or --org-prop-marker CLI flag.lapdog properly prioritizes using a user's ddtrace dependency before trying its own, and on any issues, logs an instruction to install ddtrace, when using lapdog to instrument Python applications or processes.lapdog can instrument any Python application (or process that spawns a Python application). Install via pip install ddapm-test-agent[ddtrace], and run
lapdog can instrument any Python application (or process that spawns a Python application). Install via pip install ddapm-test-agent[ddtrace], and run lapdog [your app command].Add claude-opus-4-7 to the set of models recognized as having a 1M token context window.
claude-opus-4-7 to the set of models recognized as having a 1M token context window.claude-opus-4-7 and claude-opus-4-1 to the cost tracking table.authenticated field to the /info endpoint that is true if the test agent is configured with a valid Datadog API key and site.context_delta is now correctly reported on agent spans in instrumented Claude Code sessions that nest llm spans within step spans.claude-opus-4-5 entry has been added so it no longer falls through to the claude-opus-4 prefix.input.messages list, losing the user prompt and never recording the system prompt. The pi lapdog extension now captures the system prompt from before_agent_start and snapshots the messages array from each context event, forwarding both with message_start so each LLM span records the system, user, assistant, and toolResult messages sent to the model.claude hooks: Insert a step span between the agent span and its llm/tool children for instrumented Claude Code sessions.
step span between the agent span and its llm/tool children for instrumented Claude Code sessions.ml_app to pi-coding-agent instead of inheriting the Claude Code value. Override with DD_PI_CODING_AGENT_ML_APP.ml_app tag now fall back to lapdog (previously unknown), so unattributed lapdog traffic is grouped under a meaningful app name.llmobs: support min/max/sum/avg aggregations on the /api/v1/logs-analytics/aggregate endpoint and expose timestamp (start_ns in milliseconds) as a res
min/max/sum/avg aggregations on the /api/v1/logs-analytics/aggregate endpoint and expose timestamp (start_ns in milliseconds) as a resolvable field so the static app's sessions table can compute session duration. Also fixes earliest / latest so a value of 0 is no longer collapsed to an empty string.token_usage onto the root (agent) span's metrics dict from the claude and pi hook handlers. The trace aggregate builder sums metrics.total_tokens across every span in the trace, so writing the rollup on the root caused session-table token totals to double-count relative to the per-span values.POST /api/ui/query/scalar no longer filters LLMObs spans by the request's from/to window. The sibling list and aggregate endpoints ignore the time window, so filtering here caused the LLMObs Sessions table to render rows for older sessions with blank cost and token columns whenever the UI sent a short (e.g. 15 minute) timeframe. Aggregates are now computed over all tracked spans, consistent with the other endpoints.Attaches the proper session id for Claude Code LLM spans
Emit step spans for pi coding agent sessions.
POST /api/ui/query/scalar for LLM Observability data sources. Supports count/cardinality/sum/avg/min/max/median/percentile aggregations, group_by, search filters, per-request time windows, and formula references over the spans tracked by the test agent. Unknown data sources return a zero-valued scalar response instead of erroring.DD_SITE and DD_API_KEY on startup if LLM Observability data forwarding is enabled, and disables it if not validAdd lapdog pi command for tracing pi coding agent sessions through the dd-apm-test-agent. The command installs the bundled pi extension, launches pi w
lapdog pi command for tracing pi coding agent sessions through the dd-apm-test-agent. The command installs the bundled pi extension, launches pi with LAPDOG_URL configured, and records current model/provider details on agent, LLM, and tool spans.Add DD_CLAUDE_CODE_ML_APP environment variable to configure the ml_app field for Claude Code traces. Defaults to "claude-code" for backwards compatibi
DD_CLAUDE_CODE_ML_APP environment variable to configure the ml_app field for Claude Code traces. Defaults to "claude-code" for backwards compatibility.vcr: Add support for normalizing parts of JSON request bodies when recording requests via --vcr-json-body-normalizers or VCR_JSON_BODY_NORMALIZERS. Th
--vcr-json-body-normalizers or VCR_JSON_BODY_NORMALIZERS. This option should take a comma-separated list of JSON paths to normalize, e.g. request.user.id.Calculates cost estimation for a handful of popular Anthropic models for Claude Code CLI instrumentation.
Fixed an issue where using Python 3.8 or 3.9 would result in TypeErrors when running the test agent or lapdog.
Adds a --enable-claude-code-hooks option to insert the test agent's Claude Code hooks on startup.
--enable-claude-code-hooks option to insert the test agent's Claude Code hooks on startup.lapdog startup command which starts up the test agent with Claude Code hooks enabled.lapdog commands:
lapdog start now launches the test agent with --enable-claude-code-hooks in the background.lapdog stop stops that test agent instancelapdog status logs the current status (url, pid, and logs file) of the lapdog instancelapdog claude starts a claude session through lapdog, starting lapdog locally if not started by lapdog startclaude hooks: Enrich tool and subagent span names with human-readable intent extracted from tool input (e.g., "Read - claude_hooks.py" instead of "Rea
tool_name tag for faceting.ddapm-test-agent-run CLI launcher and Javascript fetch interceptor for routing Claude Code API calls through the test agent proxy. This replaces the ANTHROPIC_BASE_URL approach which can be overridden by managed settings. Usage: ddapm-test-agent-run claude.OTLP: Add support for OpenTelemetry Protocol (OTLP) traces via HTTP endpoint v1/traces on port 4318 and GRPC server on port 4317. The endpoint accepts
v1/traces on port 4318 and GRPC server on port 4317. The endpoint accepts both application/json and application/x-protobuf content types. Session endpoint /test/session/traces allows retrieval of captured traces for validation.meta_events_is_valid_json check that validates meta.events contains a valid JSON array when present. Normalize meta.events attribute key ordering during snapshot generation and comparison to ensure snapshot tests pass regardless of the iteration order of tracer-side hash maps.Add support for /evp_proxy/v4/api/v2/llmobs and /evp_proxy/v4/api/v2/llmobs/update endpoints. Requests are handled by the same logic as the v2 llmobs
/evp_proxy/v4/api/v2/llmobs and /evp_proxy/v4/api/v2/llmobs/update endpoints. Requests are handled by the same logic as the v2 llmobs endpoints (stored, forwarded when configured, and included in LLM Observability query-rewriter results).Add Claude Code hooks integration that receives Claude Code lifecycle events and assembles them into LLM Observability traces, enabling visibility int
Forwards LLM Observability span events to Datadog by default. Uses either the configured --agent-url or the --dd-site and --dd-api-key command-line ar
--agent-url or the --dd-site and --dd-api-key command-line arguments. This can be disabled by setting the DISABLE_LLMOBS_DATA_FORWARDING environment variable or --disable-llmobs-data-forwarding command-line argument to <span class="title-ref">true</span>.Add support for controlling the test agent version via the TEST_AGENT_VERSION environment variable. The version is returned in the /info endpoint resp
VCR has been removed as a dependency, and instead JSON cassettes are produced. Legacy VCR cassettes are converted to JSON on first use, and the old VC
Add /evp_proxy/v2/api/v2/exposures endpoint to collect feature flag exposures requests.
Add support for /evp_proxy/v4/api/v2/errorsintake endpoint to collect errors intake payload requests.
/evp_proxy/v4/api/v2/errorsintake endpoint to collect errors intake payload requests.Add support for running the test agent over a Windows named pipe.
--vcr-provider-map flag or VCR_PROVIDER_MAP environment variable. The list should take the form of provider1=http://provider1.com/,provider2=http://provider2.com/.--vcr-ignore-headers flag or VCR_IGNORE_HEADERS environment variable. The list should take the form of header1,header2,header3.vcr: adds a new --vcr-ci-mode flag and accompanying VCR_CI_MODE environment variable that, when set to true (defaults to false), will throw a 404 erro
--vcr-ci-mode flag and accompanying VCR_CI_MODE environment variable that, when set to true (defaults to false), will throw a 404 error if a cassette is not found in CI mode to ensure that all cassettes are generated locally and committed.vcr: fixes a bug where the aws signature recalculation would always happen, even if the cassette already existed.
vcr: adds support for proxying aws bedrock runtime. to record cassettes for the first time, the AWS_SECRET_ACCESS_KEY environment variable must be set
otel: Adds OpenTelemetry Protocol (OTLP) v1.7.0 logs support via HTTP endpoint /v1/logs on port 4318.
/v1/logs on port 4318./v1/metrics on port 4318 and GRPC on port 4317. Supports receiving all OTLP metric types including Gauge, Sum, Histogram, ExponentialHistogram, and Summary.vcr: fixes an issue where the vcr cassette name middleware would not properly ignore decoding errors for request bodies that were not associated with
/vcr/test/start path.vcr: test_name specified in /vcr/test/start is now used as a prefix for generated cassette names instead of a suffix.
test_name specified in /vcr/test/start is now used as a prefix for generated cassette names instead of a suffix.Fixes windows docker image tagging to avoid having only linux or windows images published for latest and vx.y.z tags.
latest and vx.y.z tags.Add Windows container support to Docker images.
vcr: fixes a bug where the vcr cassette would cause unnecessary 400s from proxied providers.
vcr: adds support for recording requests from google genai/gemini.
/vcr/test/start and /vcr/test/stop, which capture all proxy requests made in between these two requests with a test name specified in /vcr/test/start.BREAKING CHANGE: Test snapshots must be updated as field comparisons on stats payload will fail between "" and None values.
"" and None values.VCR: add support for query strings.
Add OpenAI vcr cassettes for responses api prompt caching, responses api streaming prompt caching, and chat completions with tool calls.
The agent requires any span_event array_value to be wrapped in a {values: \[...\]} object. This reflects this requirement from the SpanEvent prototype
Ensures runc and containerd are installed in the docker image.
runc and containerd are installed in the docker image.Support a vcr cassette for OpenAI from Vercel AI SDK requests.
Support a vcr cassette for openai responses api streams that end with an incomplete chunk.
Your coding agent can read these notes before it upgrades. Set up the MCP server →