Skip to content

feat: add otel_link_id for SDK/trace record deduplication#28

Merged
Yash1hi merged 4 commits intomainfrom
feat/otel-link-id
Mar 6, 2026
Merged

feat: add otel_link_id for SDK/trace record deduplication#28
Yash1hi merged 4 commits intomainfrom
feat/otel-link-id

Conversation

@Yash1hi
Copy link
Contributor

@Yash1hi Yash1hi commented Mar 5, 2026

Add otel_link_id support to run_and_evaluate and async_run_and_evaluate for deduplicating records created by both the SDK and the OTel trace processing pipeline.

Summary

  • Generate a unique otel_link_id (UUID) per testcase execution
  • Pass it to the user's system function via a new SystemOptions TypedDict parameter
  • Include it in the createRecord API call via extra_body={"otelLinkId": otel_link_id}
  • Export SystemOptions from scorecard_ai.lib

Breaking change

The system function signature now includes SystemOptions as the third argument:

# Before:
def system(inputs: dict, system_version: SystemVersion | None) -> dict:
    ...

# After:
def system(inputs: dict, system_version: SystemVersion | None, options: SystemOptions) -> dict:
    otel_link_id = options["otel_link_id"]
    # Set as OTel attribute: span.set_attribute("scorecard.otel_link_id", otel_link_id)
    ...

Users should set scorecard.otel_link_id as an OTel span attribute in their system function to enable deduplication.

Companion PRs

Test plan

  • E2E tested locally with full OTel pipeline (gateway → collector → ClickHouse → Temporal) — single merged record confirmed

Yash1hi added 2 commits March 5, 2026 14:56
Generate a unique otel_link_id per testcase execution in
run_and_evaluate and async_run_and_evaluate, pass it to the user's
system function via SystemOptions, and include it in the createRecord
API call via extra_body.

BREAKING CHANGE: system function signature now includes a SystemOptions
parameter as the third argument containing { otel_link_id: str }.
Use inspect.signature to detect whether the user's system function
accepts 3 positional args. If it does, pass SystemOptions; if not,
call with just (inputs, system_version) as before. Existing 2-arg
system functions continue to work unchanged.
@Yash1hi Yash1hi changed the title feat!: add otel_link_id for SDK/trace record deduplication feat: add otel_link_id for SDK/trace record deduplication Mar 6, 2026
@Yash1hi Yash1hi marked this pull request as ready for review March 6, 2026 23:19
@Yash1hi Yash1hi merged commit f511399 into main Mar 6, 2026
7 checks passed
@Yash1hi Yash1hi deleted the feat/otel-link-id branch March 6, 2026 23:19
@stainless-app stainless-app bot mentioned this pull request Mar 6, 2026
Yash1hi added a commit that referenced this pull request Mar 10, 2026
Automated Release PR
---


## 3.7.0 (2026-03-07)

Full Changelog:
[v3.6.0...v3.7.0](v3.6.0...v3.7.0)

### Features

* add otel_link_id for SDK/trace record deduplication
([#28](#28))
([f511399](f511399))
* add otel_link_id support for SDK/trace record deduplication
([50150ca](50150ca))
* **api:** api update
([8807bde](8807bde))
* **client:** add custom JSON encoder for extended type support
([6308171](6308171))
* **client:** add support for binary request streaming
([dedc776](dedc776))


### Bug Fixes

* **docs:** fix mcp installation instructions for remote servers
([fbe8bce](fbe8bce))
* make SystemOptions a non-breaking optional parameter
([7ce95ac](7ce95ac))
* resolve import sorting lint errors
([75cebe4](75cebe4))
* use length-sorted imports per ruff config
([85214df](85214df))


### Chores

* **ci:** skip uploading artifacts on stainless-internal branches
([1529947](1529947))
* **ci:** upgrade `actions/github-script`
([9ac3a1a](9ac3a1a))
* format all `api.md` files
([d1f94d0](d1f94d0))
* **internal:** add request options to SSE classes
([4f455ba](4f455ba))
* **internal:** bump dependencies
([18a346b](18a346b))
* **internal:** codegen related update
([ac5ea7c](ac5ea7c))
* **internal:** fix lint error on Python 3.14
([04b3ad1](04b3ad1))
* **internal:** make `test_proxy_environment_variables` more resilient
([e438dc1](e438dc1))
* **internal:** make `test_proxy_environment_variables` more resilient
to env
([9624b3c](9624b3c))
* **internal:** update `actions/checkout` version
([2c0cb07](2c0cb07))
* **test:** do not count install time for mock server timeout
([08b509f](08b509f))
* update mock server docs
([e8e3b58](e8e3b58))


### Documentation

* prominently feature MCP server setup in root SDK readmes
([274c2d8](274c2d8))

---
This pull request is managed by Stainless's [GitHub
App](https://github.com/apps/stainless-app).

The [semver version
number](https://semver.org/#semantic-versioning-specification-semver) is
based on included [commit
messages](https://www.conventionalcommits.org/en/v1.0.0/).
Alternatively, you can manually set the version number in the title of
this pull request.

For a better experience, it is recommended to use either rebase-merge or
squash-merge when merging this pull request.

🔗 Stainless [website](https://www.stainlessapi.com)
📚 Read the [docs](https://app.stainlessapi.com/docs)
🙋 [Reach out](mailto:support@stainlessapi.com) for help or questions
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