fix(experiments): emit v4 trace attributes - #119
Merged
Merged
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c758d74. Configure here.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

TL;DREmit the Langfuse v4 attributes that make Ruby SDK experiment runs visible with complete observation attribution.
WhyLangfuse v4 discovers experiments from OpenTelemetry attributes. Ruby experiment runs linked dataset items, but their observations did not carry the experiment identity, item identity, expected output, or metadata that v4 requires.
The attribute layout matches the local JavaScript and Python SDK behavior. Each run selects its first valid server dataset run ID or a generated fallback ID, then keeps that identity for every item. A later link cannot split the run or redirect its URL and run-level scores to another identity. Identity and metadata propagate to child observations; descriptions and expected outputs remain on each item root. Item scores now target both the trace and root observation.
Manual
item.linkanditem.runflows remain link-only because they cannot retroactively add attributes to an observation that already started.ChecklistVerificationThe complete RSpec suite passed with 1,653 examples and 97.01% line coverage. RuboCop inspected all 110 files with no offenses. Two-item regression tests cover successful and failed dataset links in both orders.
I ran dataset-backed and local-data experiments against Langfuse Cloud using the SDK code from this branch and credentials from
.env. Independent Langfuse CLI queries found both v4 experiments. The managed run used its dataset run ID, and the local run used a generated 16-character hexadecimal ID with the expected deterministic item ID.I also forced the first dataset link to fail and allowed the second link to succeed. The CLI found one experiment with two items. Both roots and both children used the same fallback ID. The late server ID did not create a second v4 experiment, and the SDK did not expose that different ID as a URL or run-score target. The mixed-link validation experiment remains available for inspection.
The CLI also confirmed that root and nested child observations shared experiment identity and metadata. Expected output and description appeared only on the root. The evaluator score targeted that root observation. The managed validation experiment remains available for inspection.
I compared the behavior with the current local JavaScript and Python SDK implementations. I did not run their test suites because this change does not modify either sibling repository.
Closes #118
Note
Medium Risk
Changes experiment tracing, OTel propagation, dataset-link ordering, and score targeting; behavior is well-tested but affects observability and experiment identity in production runs.
Overview
run_experimentnow stamps observations with the OpenTelemetry attributes Langfuse v4 uses to discover experiments, aligning Ruby with the JS/Python SDKs.A new
ExperimentAttributeshelper builds experiment/item identity, metadata (with masking), root-only description and expected output, and thesdk-experimentenvironment.ExperimentRunnerapplies these at trace start via aprepare_contexthook onTracedExecution, links dataset items before the task runs, and propagates shared attributes to child spans throughPropagation._with_experiment_attributes. Dataset-backed runs use the server dataset run ID when linking succeeds, with a per-run fallback hex ID if not; the first resolved ID is kept even when later links fail. Local runs share one generated experiment ID and deterministic item IDs from hashed inputs.ExperimentResultexposesexperiment_id. Item-level evaluator scores are persisted with bothtrace_idandobservation_id. Docs note thatitem.run/ manuallinkcannot retrofit v4 experiment attributes after a span has started.Reviewed by Cursor Bugbot for commit f6472ea. Bugbot is set up for automated code reviews on this repo. Configure here.