v6.7.0 proposal#9523
Conversation
* test: stop peer service checks racing operation spans The shared helper started the operation before registering its trace expectation and only inspected the first span of each payload. MongoDB connection traffic could therefore consume the payload containing the expected operation span, leaving the test to time out. * test: bind peer service checks to their operation spans Delayed setup traces can carry the same peer-service tags as the operation under test, allowing the shared matcher to pass without observing that operation. Run each generator under a unique parent and match its child span instead. Generator throws and invalid return values can bypass assertion cleanup. Keep the whole operation inside the cleanup boundary so the original failure is not replaced by a leaked-expectation teardown error. * test: match peer service spans by trace Peer-service spans can be nested below integration spans, so requiring a direct parent excluded valid operations. Match the generated trace to keep setup traffic isolated without constraining span depth. * test: stop correlation spans delaying trace export Keeping the correlation parent open until the operation settled delayed trace export. Integrations that publish duplicate finish notifications could then recompute `_dd.peer.service.source` before the trace was sent. * fix(tracing): make peer service finalization idempotent Repeated finish notifications can reach an outbound span before an ancestor lets the trace flush. The second pass treats the computed peer service as preconfigured and rewrites its source to `peer.service`; an existing source now marks finalization. The peer-service assertion keeps its correlation parent open through completion and matches the integration component, so delayed setup traces and spans from another integration cannot satisfy it. * test(mongodb): target bulkWrite peer service parent
…with 5 updates (#9478) * chore(deps): bump the gh-actions-packages group across 6 directories with 5 updates Bumps the gh-actions-packages group with 4 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action). Bumps the gh-actions-packages group with 1 update in the /.github/actions/datadog-ci directory: [actions/setup-node](https://github.com/actions/setup-node). Bumps the gh-actions-packages group with 1 update in the /.github/actions/node/setup directory: [actions/setup-node](https://github.com/actions/setup-node). Bumps the gh-actions-packages group with 1 update in the /.github/actions/testagent/logs directory: [actions/checkout](https://github.com/actions/checkout). Bumps the gh-actions-packages group with 1 update in the /.github/actions/testagent/start directory: [actions/checkout](https://github.com/actions/checkout). Bumps the gh-actions-packages group with 4 updates in the /.github/workflows directory: [actions/checkout](https://github.com/actions/checkout), [github/codeql-action/init](https://github.com/github/codeql-action), [github/codeql-action/analyze](https://github.com/github/codeql-action) and [slackapi/slack-github-action](https://github.com/slackapi/slack-github-action). Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@9c091bb...3d3c42e) Updates `github/codeql-action/init` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@99df26d...7188fc3) Updates `github/codeql-action/analyze` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@99df26d...7188fc3) Updates `slackapi/slack-github-action` from 3.0.4 to 4.0.0 - [Release notes](https://github.com/slackapi/slack-github-action/releases) - [Changelog](https://github.com/slackapi/slack-github-action/blob/main/CHANGELOG.md) - [Commits](slackapi/slack-github-action@fc46ded...dcb1066) Updates `actions/setup-node` from 6.4.0 to 7.0.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@48b55a0...8207627) Updates `actions/setup-node` from 6.4.0 to 7.0.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@48b55a0...8207627) Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@9c091bb...3d3c42e) Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@9c091bb...3d3c42e) Updates `actions/checkout` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](actions/checkout@9c091bb...3d3c42e) Updates `github/codeql-action/init` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@99df26d...7188fc3) Updates `github/codeql-action/analyze` from 4.37.0 to 4.37.1 - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](github/codeql-action@99df26d...7188fc3) Updates `slackapi/slack-github-action` from 3.0.4 to 4.0.0 - [Release notes](https://github.com/slackapi/slack-github-action/releases) - [Changelog](https://github.com/slackapi/slack-github-action/blob/main/CHANGELOG.md) - [Commits](slackapi/slack-github-action@fc46ded...dcb1066) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: github/codeql-action/init dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: github/codeql-action/analyze dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: slackapi/slack-github-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: gh-actions-packages - dependency-name: actions/setup-node dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: gh-actions-packages - dependency-name: actions/setup-node dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: gh-actions-packages - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: actions/checkout dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: github/codeql-action/init dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: github/codeql-action/analyze dependency-version: 4.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages - dependency-name: slackapi/slack-github-action dependency-version: 4.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: gh-actions-packages ... Signed-off-by: dependabot[bot] <support@github.com> * attempt to fix jobs --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Thomas Hunter II <tlhunter@datadog.com>
* feat(llmobs): add OpenAI Agents trace-processor integration * ci(llmobs): test OpenAI Agents integration
* separate llmobs trace ids * update exportSpan * tests * add tagger test * additional fixups * update tests from rebase
* fix(openfeature): support custom agentless endpoints * fix(openfeature): never send API keys to custom endpoints * fix(openfeature): clarify default endpoint error
Overall package sizeSelf size: 7.52 MB Dependency sizes| name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 3.3.2 | 124.41 kB | 440.65 kB | | opentracing | 0.14.7 | 194.81 kB | 194.81 kB | | dc-polyfill | 0.1.11 | 25.74 kB | 25.74 kB |🤖 This report was automatically generated by heaviest-objects-in-the-universe |
There was a problem hiding this comment.
More details
The changed runtime paths behaved correctly across focused LLMObs, OpenAI provider, OpenFeature, peer-service, span-processor, and plugin-structure scenarios. The only unavailable check was the versioned OpenAI Agents integration suite because its external fixtures are not materialized in this sandbox.
📊 Validated against 8 scenarios · Open Bits AI session
🤖 Datadog Autotest · Commit 3adb270 · What is Autotest? · @DataDog review to ask questions · Any feedback? Reach out in #autotest
BenchmarksBenchmark execution time: 2026-07-24 17:34:59 Comparing candidate commit 3adb270 in PR branch Found 3 performance improvements and 0 performance regressions! Performance is the same for 2311 metrics, 44 unstable metrics.
|
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 3adb270 | Docs | Datadog PR Page | Give us feedback! |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## v6.x #9523 +/- ##
=======================================
Coverage ? 98.44%
=======================================
Files ? 947
Lines ? 128035
Branches ? 10722
=======================================
Hits ? 126046
Misses ? 1989
Partials ? 0 Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3adb2703d3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!traceId) return | ||
|
|
||
| const name = oaiTrace.name || 'Agent workflow' | ||
| const ddSpan = this.#tracer.startSpan(name, { |
There was a problem hiding this comment.
Parent agent workflows to the active span
When an OpenAI Agents run is started inside an already traced request or job, this direct core-tracer startSpan() call does not inherit the active legacy scope, so the workflow span (and all of its agent/LLM/tool children) becomes a separate root trace instead of staying under the surrounding application span. Pass the active span as childOf for the workflow root, or create it through the plugin tracing helper that applies the active parent.
Useful? React with 👍 / 👎.
| llmobsOptions.modelProvider = this.#modelProvider | ||
| } | ||
|
|
||
| this.#tagger.registerLLMObsSpan(ddSpan, llmobsOptions) |
There was a problem hiding this comment.
Suppress duplicate OpenAI LLMObs model spans
When LLMObs is enabled for the normal OpenAIResponsesModel path, the underlying openai client still goes through the OpenAI plugin's responses.create LLMObs registration while this code also registers the agents-core response span as an LLM span. One model invocation therefore emits two LLMObs model-call events (and the lower-level one is not parented through the agents LLMObs hierarchy), which can double-count requests/tokens; add a suppression flag around the agent-owned model call or otherwise skip the OpenAI LLMObs span while keeping its APM span.
Useful? React with 👍 / 👎.
| const parentSpan = this.#resolveParent(oaiSpan) | ||
| const spanName = deriveSpanName(oaiSpan) | ||
|
|
||
| const ddSpan = this.#tracer.startSpan(spanName, { |
There was a problem hiding this comment.
Stamp spans with the openai-agents integration
These direct core-tracer spans only set the component tag; because no integrationName is passed, Span.finish() stamps _dd.integration as the default opentracing instead of openai-agents. In traced agent runs this breaks per-integration attribution/telemetry for every agent, tool, and LLM span, so pass integrationName: COMPONENT (or route span creation through the plugin tracing helper) for these spans as well as the workflow root.
Useful? React with 👍 / 👎.
| @nats-io/nats-core,nats,3.0.0,3.4.0,True | ||
| @nats-io/transport-node,nats,3.0.0,3.4.0,True | ||
| @node-redis/client,redis,1.0.0,1.0.6,True | ||
| @openai/agents,openai-agents,0.7.0,0.13.5,True |
There was a problem hiding this comment.
Add the plugin to APM integration CI
This adds openai-agents to the supported integration list, but .github/workflows/apm-integrations.yml has no matching openai-agents/@openai/agents job or PLUGINS entry, so the new package tests will not be exercised by the APM integration matrix. Please register the new plugin in that workflow alongside the other plugin registration points.
Useful? React with 👍 / 👎.
| handoff: 'tool', | ||
| guardrail: 'task', | ||
| custom: 'task', | ||
| response: 'llm', |
There was a problem hiding this comment.
Handle Chat Completions model spans
The supported Agents SDK also exposes OpenAIChatCompletionsModel, and that path emits agents-core spans with spanData.type === 'generation' instead of response; because this map has no generation entry, onSpanStart() drops those model calls before creating any dd-trace/LLMObs model span. Agents configured for Chat Completions will therefore miss token/model events, so map generation to the LLM kind and tag its input/output/model fields like the response path.
Useful? React with 👍 / 👎.
| if (patchedMods.has(mod)) return mod | ||
| if (typeof mod?.addTraceProcessor !== 'function' && typeof mod?.getGlobalTraceProvider !== 'function') return mod | ||
| patchedMods.add(mod) | ||
| agentsMod = mod |
There was a problem hiding this comment.
Keep the agents provider paired per module copy
In a process with two installed copies of @openai/agents, this single module-level reference is overwritten by whichever copy loads last, while every patched @openai/agents-openai model wrapper reads it later. A call from the earlier copy then asks the wrong trace provider for getCurrentSpan(), so agentsCoreSpanId is missing or from another run and the OpenAI request span is no longer bound under the correct agent span; keep the provider/module reference scoped to the patched model copy instead of one global.
Useful? React with 👍 / 👎.
|
|
||
| constructor ({ tracer, config } = {}) { | ||
| this.#tracer = tracer | ||
| this.#tagger = config?.llmobs?.DD_LLMOBS_ENABLED ? new LLMObsTagger(config, true) : undefined |
There was a problem hiding this comment.
Create the LLMObs tagger when LLMObs is enabled
If the tracer starts with LLMObs disabled and the app later uses the still-supported llmobs.enable() API after this plugin has been constructed, the shared config flips DD_LLMOBS_ENABLED to true but #tagger stays undefined forever because it was only initialized here. In that scenario openai-agents continues to emit APM spans but never registers or tags LLMObs events, unlike the other LLMObs plugins that keep a tagger and let it read the updated config; instantiate the tagger unconditionally or when enabling.
Useful? React with 👍 / 👎.
Features
Fixes