Skip to content

feat(aiguard): send evaluations through the Agent when the service has no keys - #21595

Open
florentinl wants to merge 12 commits into
mainfrom
florentin.labelle/aiguard-agent-data-path
Open

florentinl wants to merge 12 commits into
mainfrom
florentin.labelle/aiguard-agent-data-path

Conversation

@florentinl

@florentinl florentinl commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

Allow services without both Datadog credentials to send AI Guard evaluations through the local Agent when it advertises the proxy route. Services with both keys continue calling AI Guard directly. Discovery is shared across clients, evaluations wait within the Agent timeout for pending discovery, and transient failures can be retried on the next evaluation. Includes Unix socket support and transport telemetry.

Original PR: #21569 by @eliottness. Eliott Bouhana remains credited as co-author.

Testing

All 561 AI Guard API and Agent-helper tests pass on Python 3.12, including concurrent startup, bounded waits, invalidation, transient recovery, a forked-child regression, advertised endpoint normalization, native HTTP requests through reverse-proxy paths, unsupported /info responses, cross-client isolation, and background-thread resource failures. All local repository checks pass, including typing, security, spelling, and ast-grep. Import analysis found no new cycles or dependency-direction violations.

Discovery performance has not been benchmarked.

Risks

Requires an Agent that supports the AI Guard proxy route. Missing credentials now produce evaluation-time errors instead of preventing client initialization. Evaluations fail if discovery cannot complete within the Agent timeout or no supported route exists.

florentinl and others added 2 commits November 9, 2026 11:03
…s no keys

A service instrumented by Single Step Instrumentation never gets DD_API_KEY and DD_APP_KEY, so AI Guard stayed off. When both keys are missing and the Agent advertises /ai_guard/proxy/ in its /info endpoint list, the client now sends evaluations to that route and the Agent attaches its own credentials. Services that set both keys keep calling the API directly.

Adds the two SDK metrics the RFC defines: an ai_guard.transport gauge tagged with the transport in use, and an ai_guard.agent.requests count per evaluation sent to the Agent, tagged with the status code, the error type and the Agent's own error code.

Original PR: #21569

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
@florentinl
florentinl marked this pull request as ready for review November 9, 2026 10:17
@florentinl
florentinl requested review from a team as code owners November 9, 2026 10:17
@florentinl
florentinl requested review from christophe-papazian and removed request for a team November 9, 2026 10:17
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T13:42:04.923542Z 59f1205 New commits
🔒 Security Review ✅ Completed 2026-11-09T13:44:19.617271Z 59f1205 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Codeowners resolved as

Resolved from the full PR diff against main using the target branch CODEOWNERS file.
CODEOWNERS team requests not listed below are not required by the current file set.

.cursor/rules/ai-guard.mdc                                              @DataDog/asm-python
ddtrace/aiguard/_api_client.py                                          @DataDog/asm-python
ddtrace/aiguard/_constants.py                                           @DataDog/asm-python
ddtrace/internal/agent.py                                               @DataDog/apm-core-python
docs/configuration.rst                                                  @DataDog/python-guild
releasenotes/notes/aiguard-agent-data-path-6a3f91b74c2d5e08.yaml        @DataDog/apm-python
tests/aiguard/api/conftest.py                                           @DataDog/asm-python
tests/aiguard/api/test_agent_route.py                                   @DataDog/asm-python
tests/aiguard/api/test_api_client.py                                    @DataDog/asm-python
tests/tracer/test_agent.py                                              @DataDog/apm-sdk-capabilities

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Dependency direction analysis

⚠️ Existing dependency direction violations

There are 83 dependency direction violations that already exist on the base branch and have not been changed by this PR.

Show existing violations (showing 5 of 83 highest severity)
ddtrace.internal.tracemethods -×-> ddtrace.trace  (internal-core -> product:tracing, score=120)
ddtrace.llmobs._telemetry -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=118)
ddtrace.llmobs._integrations.vertexai -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=118)
ddtrace.llmobs._integrations.google_adk -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=118)
ddtrace.llmobs._integrations.base -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=118)

To see all violations, download the layers-base.json and layers-pr.json artifacts from this CI job and run:

uv run --script scripts/import-analysis/layers.py compare layers-base.json layers-pr.json

@datadog-prod-us1-6

datadog-prod-us1-6 Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Pipelines  Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 59f1205 | Docs | View more details | Give us feedback!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 452e8f64db

ℹ️ 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".

Comment thread ddtrace/aiguard/_api_client.py Resolved
Comment thread ddtrace/aiguard/_api_client.py Resolved
Comment thread ddtrace/aiguard/_api_client.py Resolved
Comment thread ddtrace/aiguard/_api_client.py Resolved
Comment thread ddtrace/aiguard/_api_client.py Resolved
Use the internal one-shot thread for Agent discovery and give transport errors and Agent info their expected types.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
@florentinl
florentinl requested a review from a team as a code owner November 9, 2026 10:25
@florentinl
florentinl requested review from juanjux and removed request for a team November 9, 2026 10:25
datadog-prod-us1-6[bot]

This comment was marked as resolved.

@pr-commenter

pr-commenter Bot commented Nov 9, 2026 •

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-11-09 14:01:54

Comparing candidate commit 59f1205 in PR branch florentin.labelle/aiguard-agent-data-path with baseline commit 5449321 in branch main.

📊 Benchmarking dashboard

Found 0 performance improvements and 0 performance regressions! Performance is the same for 619 metrics, 9 unstable metrics, 1 flaky benchmarks without significant changes.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

Unstable benchmarks

These benchmarks have a confidence interval too wide to call a change; treat them as noise rather than signal.

scenario:coreapiscenario-context_with_data_listeners

  • unstable execution_time [-771.467ns; +624.659ns] or [-7.150%; +5.790%]

scenario:coreapiscenario-core_dispatch_50_listeners

  • unstable execution_time [-1911.336ns; +1795.480ns] or [-9.475%; +8.901%]

scenario:coreapiscenario-core_dispatch_exception_listeners

  • unstable execution_time [-1854.129ns; +1693.039ns] or [-9.514%; +8.688%]

scenario:coreapiscenario-core_dispatch_listeners

  • unstable execution_time [-371.678ns; +345.445ns] or [-8.549%; +7.945%]

scenario:coreapiscenario-core_dispatch_no_args_listeners

  • unstable execution_time [-219.963ns; +215.746ns] or [-8.059%; +7.904%]

scenario:coreapiscenario-core_dispatch_with_results_1_listener

  • unstable execution_time [-90.372ns; +85.897ns] or [-6.146%; +5.842%]

scenario:coreapiscenario-core_dispatch_with_results_50_listeners

  • unstable execution_time [-4558.839ns; +4855.833ns] or [-8.973%; +9.558%]

scenario:coreapiscenario-core_dispatch_with_results_listeners

  • unstable execution_time [-1015.459ns; +888.683ns] or [-9.394%; +8.221%]

scenario:packagesupdateimporteddependencies-import_many_stdlib_cached

  • unstable execution_time [-53.070µs; +56.828µs] or [-9.114%; +9.759%]

Known flaky benchmarks

These benchmarks are marked as flaky and will not trigger a failure. Modify FLAKY_BENCHMARKS_REGEX to control which benchmarks are marked as flaky.

Known flaky benchmarks without significant changes:

  • scenario:packagespackageforrootmodulemapping-cache_off

florentinl and others added 3 commits November 9, 2026 11:56
Bound waits for background discovery, start it once per generation, and wake callers when discovery is reset or invalidated. Reset discovery after fork and discard late probe results.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
Cache only confirmed unsupported Agents. Retry unreadable info on the next evaluation and verify forked children do not inherit the parent absence backoff.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
Document credential precedence, evaluation-time discovery errors, and the endpoint override scope.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
@florentinl
florentinl requested a review from a team as a code owner November 9, 2026 11:00

@datadog-prod-us1-6 datadog-prod-us1-6 Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bits Code Review: PASS

More details

Concurrent evaluations share pending Agent discovery, and transient discovery failures remain retryable. Runtime behavior could not be verified because required dependencies were unavailable.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Bits Code Review · Commit 9ed8af8

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ed8af8795

ℹ️ 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".

Comment thread ddtrace/aiguard/_api_client.py Resolved
Comment thread ddtrace/aiguard/_api_client.py Resolved
Comment thread ddtrace/aiguard/_api_client.py Resolved
florentinl and others added 3 commits November 9, 2026 12:32
Accept Agent info endpoints with or without a leading slash.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
Use the shared Agent base-path helper for evaluation targets while keeping Unix socket locations separate.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
Let callers opt in to a distinct /info 404 error while preserving the existing info() default. Cache confirmed unsupported Agents and keep transient failures retryable.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
@florentinl
florentinl requested a review from a team as a code owner November 9, 2026 11:35
@florentinl
florentinl requested review from mtoffl01 and removed request for a team November 9, 2026 11:35
chatgpt-codex-connector[bot]

This comment was marked as resolved.

datadog-prod-us1-6[bot]

This comment was marked as resolved.

florentinl and others added 3 commits November 9, 2026 13:15
Let the native HTTP client preserve the base path instead of prepending it to the target again. Add real HTTP-server regressions for root and prefixed Agent URLs, including a trailing slash.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
A 404 from a pinned connection base must not invalidate the process-wide route used by factory clients. Cover the failure and a subsequent successful evaluation on the discovered route.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
Treat native thread resource failures as an optional background-probe failure. Install AI Guard listeners and let evaluations discover the Agent synchronously.

Co-authored-by: Eliott B <eliott.bouhana@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant