Skip to content

fix(llmobs): fix missing estimated cost on Bedrock LLM spans [MLOB-7008]#17293

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 2 commits intomainfrom
grace.williams/fix-bedrock-cost-mlob-7008
Apr 3, 2026
Merged

fix(llmobs): fix missing estimated cost on Bedrock LLM spans [MLOB-7008]#17293
gh-worker-dd-mergequeue-cf854d[bot] merged 2 commits intomainfrom
grace.williams/fix-bedrock-cost-mlob-7008

Conversation

@heyitsgrace996
Copy link
Copy Markdown
Contributor

@heyitsgrace996 heyitsgrace996 commented Apr 3, 2026

Problem

Estimated cost is missing or incorrect on Bedrock LLM spans. All Bedrock models tested were impacted - either with no cost data match, or matched direct-API pricing instead of Bedrock pricing.

Root Cause

parse_model_id() splits model IDs like "amazon.nova-lite-v1:0" into model_provider="amazon" and model_name="nova-lite-v1:0" for APM span tags. The LLMObs integration passed these split values through to the backend cost estimator, which couldn't match either:

  • Provider "amazon" doesn't match the AWS Bedrock provider (provider_match: contains "bedrock")
  • Model name "nova-lite-v1:0" doesn't match pricing entries (match: contains "amazon.nova-lite")

For vendors with their own direct-API provider (anthropic, mistral, deepseek, openai), the split provider name matched the wrong provider, resulting in direct-API pricing instead of Bedrock pricing.

Fix

Pass the original model_id through the execution context to LLMObs instead of the split values. Set model_provider to "amazon_bedrock" for all Bedrock LLM spans.

  • model_provider: "amazon" -> "amazon_bedrock" (matches backend cost estimator and existing UI icon mapping)
  • model_name: "nova-lite-v1:0" -> "amazon.nova-lite-v1:0" (matches backend pricing entries)

"amazon_bedrock" was chosen over "bedrock" because the frontend already maps "amazon_bedrock" to the LlmType.AMAZON_BEDROCK icon (source). Using "bedrock" would have required a separate frontend change.

APM span tags bedrock.request.model_provider and bedrock.request.model are unchanged.

Testing

Updated assertions in tests/contrib/botocore/test_bedrock_llmobs.py (44 passed, 9 skipped - botocore version gating).

Tested 29 Bedrock models across 7 vendors (amazon, anthropic, meta, mistral, deepseek, openai, qwen) with AWS Bedrock calls. Fix validated locally - confirmed correct cost estimation and UI icon rendering in LLMObs traces explorer.

Codex automated review completed on final commit - no blocking issues found.

Before change:
image

image

After change:
image

image

Risks

  • Changes meta.model_provider and meta.model_name on LLMObs span events. Customers filtering by @meta.model_provider:anthropic for Bedrock models would need to update to @meta.model_provider:amazon_bedrock. However, those customers were getting incorrect pricing, so the filter was already misleading.
  • Internal telemetry model_provider tag changes from vendor names to amazon_bedrock for Bedrock spans, but again before it was not being marked as Bedrock at all.
  • ARN-format model IDs (e.g., arn:aws:bedrock:us-west-2:...:inference-profile/...) will see the full ARN string as model_name in the LLMObs UI.
    Cost matching still works for system inference profiles (the model name is embedded in the ARN and matched via contains clauses).

Release note included.

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented Apr 3, 2026

Codeowners resolved as

ddtrace/contrib/internal/botocore/services/bedrock.py                   @DataDog/ml-observability
ddtrace/llmobs/_integrations/bedrock.py                                 @DataDog/ml-observability
releasenotes/notes/llmobs-fix-bedrock-cost-estimation-19af7556637be09e.yaml  @DataDog/apm-python
tests/contrib/botocore/test_bedrock_llmobs.py                           @DataDog/ml-observability

@heyitsgrace996 heyitsgrace996 force-pushed the grace.williams/fix-bedrock-cost-mlob-7008 branch 5 times, most recently from e0d0215 to 928513f Compare April 3, 2026 00:32
@heyitsgrace996 heyitsgrace996 marked this pull request as ready for review April 3, 2026 00:38
@heyitsgrace996 heyitsgrace996 requested review from a team as code owners April 3, 2026 00:38
@heyitsgrace996
Copy link
Copy Markdown
Contributor Author

@codex

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

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

Pass the original model_id through the execution context to LLMObs
instead of the split values from parse_model_id(). Set model_provider
to "amazon_bedrock" for all Bedrock spans.

All Bedrock models tested were impacted - either with no cost data
match, or a direct API provider match resulting in incorrect pricing.
@heyitsgrace996 heyitsgrace996 force-pushed the grace.williams/fix-bedrock-cost-mlob-7008 branch from 928513f to 2c51872 Compare April 3, 2026 01:39
@datadog-official
Copy link
Copy Markdown
Contributor

datadog-official Bot commented Apr 3, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 75d46d4 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@heyitsgrace996 heyitsgrace996 requested review from XG-xin and Yun-Kim April 3, 2026 08:06
Copy link
Copy Markdown
Contributor

@Yun-Kim Yun-Kim left a comment

Choose a reason for hiding this comment

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

Great change! Just a small comment on the release note but otherwise LGTM 👍

Comment thread releasenotes/notes/llmobs-fix-bedrock-cost-estimation-19af7556637be09e.yaml Outdated
@Yun-Kim
Copy link
Copy Markdown
Contributor

Yun-Kim commented Apr 3, 2026

/merge

@gh-worker-devflow-routing-ef8351
Copy link
Copy Markdown

gh-worker-devflow-routing-ef8351 Bot commented Apr 3, 2026

View all feedbacks in Devflow UI.

2026-04-03 18:53:31 UTC ℹ️ Start processing command /merge


2026-04-03 18:53:39 UTC ℹ️ MergeQueue: waiting for PR to be ready

This pull request is not mergeable according to GitHub. Common reasons include pending required checks, missing approvals, or merge conflicts — but it could also be blocked by other repository rules or settings.
It will be added to the queue as soon as checks pass and/or get approvals. View in MergeQueue UI.
Note: if you pushed new commits since the last approval, you may need additional approval.
You can remove it from the waiting list with /remove command.


2026-04-03 19:12:09 UTC ℹ️ MergeQueue: merge request added to the queue

The expected merge time in main is approximately 57m (p90).


2026-04-03 21:12:56 UTCMergeQueue: The build pipeline has timeout

The merge request has been interrupted because the build 106012690 took longer than expected. The current limit for the base branch 'main' is 120 minutes.

@Yun-Kim
Copy link
Copy Markdown
Contributor

Yun-Kim commented Apr 3, 2026

/merge

@gh-worker-devflow-routing-ef8351
Copy link
Copy Markdown

gh-worker-devflow-routing-ef8351 Bot commented Apr 3, 2026

View all feedbacks in Devflow UI.

2026-04-03 22:41:57 UTC ℹ️ Start processing command /merge


2026-04-03 22:42:01 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in main is approximately 57m (p90).


2026-04-03 23:22:18 UTC ℹ️ MergeQueue: This merge request was merged

@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot merged commit 005967b into main Apr 3, 2026
537 of 539 checks passed
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot deleted the grace.williams/fix-bedrock-cost-mlob-7008 branch April 3, 2026 23:22
dubloom pushed a commit that referenced this pull request Apr 7, 2026
…08] (#17293)

## Problem

Estimated cost is missing or incorrect on Bedrock LLM spans. All Bedrock models tested were impacted - either with no cost data match, or matched direct-API pricing instead of Bedrock pricing.

## Root Cause

`parse_model_id()` splits model IDs like `"amazon.nova-lite-v1:0"` into `model_provider="amazon"` and `model_name="nova-lite-v1:0"` for APM span tags. The LLMObs integration passed these split values through to the backend cost estimator, which couldn't match either:

- Provider `"amazon"` doesn't match the AWS Bedrock provider (`provider_match: contains "bedrock"`)
- Model name `"nova-lite-v1:0"` doesn't match pricing entries (`match: contains "amazon.nova-lite"`)

For vendors with their own direct-API provider (anthropic, mistral, deepseek, openai), the split provider name matched the wrong provider, resulting in direct-API pricing instead of Bedrock pricing.

## Fix

Pass the original `model_id` through the execution context to LLMObs instead of the split values. Set `model_provider` to `"amazon_bedrock"` for all Bedrock LLM spans.

- `model_provider`: `"amazon"` -> `"amazon_bedrock"` (matches backend cost estimator and existing UI icon mapping)
- `model_name`: `"nova-lite-v1:0"` -> `"amazon.nova-lite-v1:0"` (matches backend pricing entries)

`"amazon_bedrock"` was chosen over `"bedrock"` because the frontend already maps `"amazon_bedrock"` to the `LlmType.AMAZON_BEDROCK` icon ([source](https://github.com/DataDog/web-ui/blob/prod/packages/apps/llm/lib/utils/get-llm-type-from-source.ts)). Using `"bedrock"` would have required a separate frontend change.

APM span tags `bedrock.request.model_provider` and `bedrock.request.model` are unchanged.

## Testing

Updated assertions in `tests/contrib/botocore/test_bedrock_llmobs.py` (44 passed, 9 skipped - botocore version gating).

Tested 29 Bedrock models across 7 vendors (amazon, anthropic, meta, mistral, deepseek, openai, qwen) with AWS Bedrock calls. Fix validated locally - confirmed correct cost estimation and UI icon rendering in LLMObs traces explorer.

Codex automated review completed on final commit - no blocking issues found.

**Before change:**
<img width="1057" height="598" alt="image" src="https://github.com/user-attachments/assets/8dfc3403-bc78-4f8f-b08b-028c8253dba0" />

<img width="1114" height="621" alt="image" src="https://github.com/user-attachments/assets/3893f580-51c6-4849-b091-24f428d81552" />

**After change:**
<img width="1058" height="614" alt="image" src="https://github.com/user-attachments/assets/a37c65e8-47f1-41a1-8348-077313adfefa" />

<img width="1116" height="671" alt="image" src="https://github.com/user-attachments/assets/061f75e6-d01a-4b1b-a42f-076bccfee083" />



## Risks

- Changes `meta.model_provider` and `meta.model_name` on LLMObs span events. Customers filtering by `@meta.model_provider:anthropic` for Bedrock models would need to update to `@meta.model_provider:amazon_bedrock`. However, those customers were getting incorrect pricing, so the filter was already misleading.
- Internal telemetry `model_provider` tag changes from vendor names to `amazon_bedrock` for Bedrock spans, but again before it was not being marked as Bedrock at all.
- ARN-format model IDs (e.g., `arn:aws:bedrock:us-west-2:...:inference-profile/...`) will see the full ARN string as `model_name` in the LLMObs UI.
   Cost matching still works for system inference profiles (the model name is embedded in the ARN and matched via `contains` clauses).

Release note included.

Co-authored-by: Yun-Kim <35776586+Yun-Kim@users.noreply.github.com>
Co-authored-by: yun.kim <yun.kim@datadoghq.com>
heyitsgrace996 added a commit to DataDog/dd-trace-js that referenced this pull request Apr 8, 2026
Pass the full modelId and "amazon_bedrock" as model_provider to
LLMObs instead of the split values from parseModelId(). The split
values prevented the backend cost estimator from matching Bedrock
pricing entries.

Mirrors the Python tracer fix in DataDog/dd-trace-py#17293.
sabrenner pushed a commit to DataDog/dd-trace-js that referenced this pull request Apr 8, 2026
Pass the full modelId and "amazon_bedrock" as model_provider to
LLMObs instead of the split values from parseModelId(). The split
values prevented the backend cost estimator from matching Bedrock
pricing entries.

Mirrors the Python tracer fix in DataDog/dd-trace-py#17293.
dd-octo-sts Bot pushed a commit to DataDog/dd-trace-js that referenced this pull request Apr 9, 2026
Pass the full modelId and "amazon_bedrock" as model_provider to
LLMObs instead of the split values from parseModelId(). The split
values prevented the backend cost estimator from matching Bedrock
pricing entries.

Mirrors the Python tracer fix in DataDog/dd-trace-py#17293.
juan-fernandez pushed a commit to DataDog/dd-trace-js that referenced this pull request Apr 10, 2026
Pass the full modelId and "amazon_bedrock" as model_provider to
LLMObs instead of the split values from parseModelId(). The split
values prevented the backend cost estimator from matching Bedrock
pricing entries.

Mirrors the Python tracer fix in DataDog/dd-trace-py#17293.
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.

2 participants