@@ -258,6 +258,58 @@ func TestStartSpan(t *testing.T) {
258258 assert .Equal (t , llmWorkflow1 .ParentID , llmLLM1 .SpanID , "workflow-1 parent ID should be the llm-1 span ID" )
259259 assert .Equal (t , llmAgent1 .ParentID , llmWorkflow1 .SpanID , "agent-1 parent ID should be the workflow-1 span ID" )
260260 })
261+ t .Run ("distributed-context-propagation-experiment-baggage" , func (t * testing.T ) {
262+ tt , ll := testTracer (t )
263+
264+ experimentID := "exp-dist-123"
265+ experimentRunID := "run-uuid-xyz"
266+ experimentRunIteration := 3
267+
268+ h := http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
269+ ctx := req .Context ()
270+ serverSpan , _ := ll .StartSpan (ctx , llmobs .SpanKindLLM , "server-llm" , llmobs.StartSpanConfig {})
271+ defer serverSpan .Finish (llmobs.FinishSpanConfig {})
272+ w .Write ([]byte ("ok" ))
273+ })
274+ srv , cl := testClientServer (t , h )
275+
276+ genSpans := func () {
277+ experimentSpan , ctx := ll .StartExperimentSpan (context .Background (), "client-experiment" , llmobs.ExperimentInfo {
278+ ID : experimentID ,
279+ RunID : experimentRunID ,
280+ RunIteration : experimentRunIteration ,
281+ }, llmobs.StartSpanConfig {})
282+ defer experimentSpan .Finish (llmobs.FinishSpanConfig {})
283+
284+ req , err := http .NewRequestWithContext (ctx , http .MethodGet , srv .URL + "/" , nil )
285+ require .NoError (t , err )
286+ resp , err := cl .Do (req )
287+ require .NoError (t , err )
288+ require .Equal (t , http .StatusOK , resp .StatusCode )
289+ _ = resp .Body .Close ()
290+ }
291+ genSpans ()
292+
293+ _ = tt .WaitForSpans (t , 4 ) // experiment + server-llm (LLMObs) + HTTP client + HTTP server (APM)
294+ llmSpans := tt .WaitForLLMObsSpans (t , 2 )
295+
296+ var experimentLLM , serverLLM * llmobstransport.LLMObsSpanEvent
297+ for i := range llmSpans {
298+ switch llmSpans [i ].Name {
299+ case "client-experiment" :
300+ experimentLLM = & llmSpans [i ]
301+ case "server-llm" :
302+ serverLLM = & llmSpans [i ]
303+ }
304+ }
305+ require .NotNil (t , experimentLLM , "client experiment span should exist" )
306+ require .NotNil (t , serverLLM , "server LLM span should exist" )
307+
308+ assert .Equal (t , "experiments" , serverLLM .DDAttributes .Scope , "server span should inherit experiments scope via baggage" )
309+ assert .Equal (t , experimentID , findTag (serverLLM .Tags , "experiment_id" ), "server span should inherit experiment_id via baggage" )
310+ assert .Equal (t , experimentRunID , findTag (serverLLM .Tags , "run_id" ), "server span should inherit run_id via baggage" )
311+ assert .Equal (t , fmt .Sprintf ("%d" , experimentRunIteration ), findTag (serverLLM .Tags , "run_iteration" ), "server span should inherit run_iteration via baggage" )
312+ })
261313 t .Run ("custom-start-and-finish-times" , func (t * testing.T ) {
262314 tt , ll := testTracer (t )
263315
@@ -2080,7 +2132,7 @@ func TestDDAttributes(t *testing.T) {
20802132 ctx := context .Background ()
20812133
20822134 experimentID := "test-experiment-123"
2083- span , _ := ll .StartExperimentSpan (ctx , "test-experiment" , experimentID , llmobs.StartSpanConfig {})
2135+ span , _ := ll .StartExperimentSpan (ctx , "test-experiment" , llmobs. ExperimentInfo { ID : experimentID } , llmobs.StartSpanConfig {})
20842136 span .Finish (llmobs.FinishSpanConfig {})
20852137
20862138 apmSpans := tt .WaitForSpans (t , 1 )
@@ -2107,7 +2159,7 @@ func TestDDAttributes(t *testing.T) {
21072159 ctx := context .Background ()
21082160
21092161 experimentID := "test-experiment-456"
2110- parentSpan , ctx := ll .StartExperimentSpan (ctx , "parent-experiment" , experimentID , llmobs.StartSpanConfig {})
2162+ parentSpan , ctx := ll .StartExperimentSpan (ctx , "parent-experiment" , llmobs. ExperimentInfo { ID : experimentID } , llmobs.StartSpanConfig {})
21112163 childSpan , _ := ll .StartSpan (ctx , llmobs .SpanKindLLM , "child-llm" , llmobs.StartSpanConfig {})
21122164
21132165 childSpan .Finish (llmobs.FinishSpanConfig {})
@@ -2129,6 +2181,36 @@ func TestDDAttributes(t *testing.T) {
21292181
21302182 assert .Equal (t , "experiments" , parentLLM .DDAttributes .Scope , "Parent scope should be 'experiments'" )
21312183 assert .Equal (t , "experiments" , childLLM .DDAttributes .Scope , "Child scope should be 'experiments' via baggage propagation" )
2184+ assert .Contains (t , childLLM .Tags , "experiment_id:" + experimentID , "Child span should inherit experiment_id tag from baggage" )
2185+ })
2186+ t .Run ("child-span-inherits-run-id-and-run-iteration-from-baggage" , func (t * testing.T ) {
2187+ tt , ll := testTracer (t )
2188+ ctx := context .Background ()
2189+
2190+ experimentID := "test-experiment-789"
2191+ experimentRunID := "run-uuid-abc"
2192+ experimentRunIteration := 2
2193+ parentSpan , ctx := ll .StartExperimentSpan (ctx , "parent-experiment" , llmobs.ExperimentInfo {
2194+ ID : experimentID ,
2195+ RunID : experimentRunID ,
2196+ RunIteration : experimentRunIteration ,
2197+ }, llmobs.StartSpanConfig {})
2198+ childSpan , _ := ll .StartSpan (ctx , llmobs .SpanKindLLM , "child-llm" , llmobs.StartSpanConfig {})
2199+
2200+ childSpan .Finish (llmobs.FinishSpanConfig {})
2201+ parentSpan .Finish (llmobs.FinishSpanConfig {})
2202+
2203+ llmSpans := tt .WaitForLLMObsSpans (t , 2 )
2204+
2205+ var childLLM * llmobstransport.LLMObsSpanEvent
2206+ for i := range llmSpans {
2207+ if llmSpans [i ].Name == "child-llm" {
2208+ childLLM = & llmSpans [i ]
2209+ }
2210+ }
2211+ require .NotNil (t , childLLM , "Child LLM span should exist" )
2212+ assert .Contains (t , childLLM .Tags , "run_id:" + experimentRunID , "Child span should inherit run_id from baggage" )
2213+ assert .Contains (t , childLLM .Tags , "run_iteration:2" , "Child span should inherit run_iteration from baggage" )
21322214 })
21332215 t .Run ("child-span-trace-ids" , func (t * testing.T ) {
21342216 tt , ll := testTracer (t )
0 commit comments