@mastra/observability 1.22.0-alpha.3 → 1.23.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/exporters/test.d.ts.map +1 -1
- package/dist/index.cjs +285 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +285 -60
- package/dist/index.js.map +1 -1
- package/dist/instances/base.d.ts.map +1 -1
- package/dist/metrics/pricing-data.json +739 -805
- package/dist/model-tracing.d.ts +24 -9
- package/dist/model-tracing.d.ts.map +1 -1
- package/dist/span_processors/sensitive-data-filter.d.ts.map +1 -1
- package/dist/spans/base.d.ts +14 -5
- package/dist/spans/base.d.ts.map +1 -1
- package/dist/spans/default.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2292,9 +2292,10 @@ function addUsageStats(a, b) {
|
|
|
2292
2292
|
* Provides span tracking for Model generations, including:
|
|
2293
2293
|
* - MODEL_STEP spans (one per Model API call - includes processors and tool executions)
|
|
2294
2294
|
* - MODEL_INFERENCE spans (the provider call itself - model latency only)
|
|
2295
|
-
* - MODEL_CHUNK spans (
|
|
2295
|
+
* - MODEL_CHUNK spans (processed streaming content within a logical step)
|
|
2296
2296
|
*
|
|
2297
|
-
* Hierarchy: MODEL_GENERATION -> MODEL_STEP -> MODEL_INFERENCE
|
|
2297
|
+
* Hierarchy: MODEL_GENERATION -> MODEL_STEP -> MODEL_INFERENCE (provider timing)
|
|
2298
|
+
* -> MODEL_CHUNK (processed content)
|
|
2298
2299
|
*
|
|
2299
2300
|
* Processors and tool executions remain children of MODEL_STEP (siblings of
|
|
2300
2301
|
* MODEL_INFERENCE), so MODEL_INFERENCE measures pure model time.
|
|
@@ -2311,6 +2312,12 @@ function addUsageStats(a, b) {
|
|
|
2311
2312
|
function supportsModelInference() {
|
|
2312
2313
|
return coreFeatures.has("model-inference-span");
|
|
2313
2314
|
}
|
|
2315
|
+
function interruptedByRun(termination) {
|
|
2316
|
+
return termination.outcome === "abort" || termination.stopReason === "timeout" && termination.stopReasonContext && "timeoutType" in termination.stopReasonContext && termination.stopReasonContext.timeoutType === "total" ? {
|
|
2317
|
+
...termination,
|
|
2318
|
+
outcome: "interrupted"
|
|
2319
|
+
} : termination;
|
|
2320
|
+
}
|
|
2314
2321
|
function parseGatewayCost(providerMetadata) {
|
|
2315
2322
|
const rawCost = providerMetadata?.gateway?.cost;
|
|
2316
2323
|
const cost = typeof rawCost === "number" ? rawCost : typeof rawCost === "string" && rawCost.trim().length > 0 ? Number(rawCost) : void 0;
|
|
@@ -2501,13 +2508,17 @@ var ModelSpanTracker = class {
|
|
|
2501
2508
|
#modelSpan;
|
|
2502
2509
|
#currentStepSpan;
|
|
2503
2510
|
#currentInferenceSpan;
|
|
2511
|
+
#stepHasInference = false;
|
|
2512
|
+
#tracksProviderStream = false;
|
|
2504
2513
|
#currentChunkSpan;
|
|
2505
2514
|
#currentChunkType;
|
|
2506
2515
|
#accumulator = {};
|
|
2507
2516
|
#stepIndex = 0;
|
|
2508
2517
|
#chunkSequence = 0;
|
|
2509
2518
|
#completionStartTime;
|
|
2519
|
+
#timeToFirstTokenMs;
|
|
2510
2520
|
#inferenceCompletionStartTime;
|
|
2521
|
+
#inferenceTimeToFirstTokenMs;
|
|
2511
2522
|
/**
|
|
2512
2523
|
* True between a step's `step-start` and `step-finish` chunks, the window in which
|
|
2513
2524
|
* the provider responds. Chunks outside it, such as a `tool-call` replayed for a
|
|
@@ -2536,22 +2547,41 @@ var ModelSpanTracker = class {
|
|
|
2536
2547
|
this.#inferenceContext = context;
|
|
2537
2548
|
}
|
|
2538
2549
|
/**
|
|
2539
|
-
* Record when the provider's first chunk arrived
|
|
2540
|
-
*
|
|
2541
|
-
*
|
|
2542
|
-
*
|
|
2550
|
+
* Record when the provider's first chunk arrived. Time to first token is measured
|
|
2551
|
+
* once here, from the start of the inference that streamed the chunk; the inference
|
|
2552
|
+
* reports it when it ends, and the number is copied up the agent's own chain
|
|
2553
|
+
* (step → generation → agent run) with the chunk's clock, first write wins at each
|
|
2554
|
+
* level. Time to first chunk is `completionStartTime - startTime` on whichever span
|
|
2555
|
+
* is being read.
|
|
2543
2556
|
*/
|
|
2544
2557
|
#captureCompletionStartTime() {
|
|
2545
2558
|
this.#ensureStepAndInference();
|
|
2546
2559
|
if (this.#inferenceCompletionStartTime) return;
|
|
2547
2560
|
const now = /* @__PURE__ */ new Date();
|
|
2561
|
+
const inference = this.#currentInferenceSpan;
|
|
2562
|
+
const timeToFirstTokenMs = inference ? now.getTime() - inference.startTime.getTime() : void 0;
|
|
2548
2563
|
this.#inferenceCompletionStartTime = now;
|
|
2564
|
+
this.#inferenceTimeToFirstTokenMs = timeToFirstTokenMs;
|
|
2549
2565
|
this.#completionStartTime ??= now;
|
|
2566
|
+
this.#timeToFirstTokenMs ??= timeToFirstTokenMs;
|
|
2550
2567
|
for (const span of [
|
|
2551
2568
|
this.#currentStepSpan,
|
|
2552
2569
|
this.#modelSpan,
|
|
2553
2570
|
this.#agentRunSpan
|
|
2554
|
-
])
|
|
2571
|
+
]) {
|
|
2572
|
+
if (!span || span.attributes?.completionStartTime) continue;
|
|
2573
|
+
span.update({ attributes: {
|
|
2574
|
+
completionStartTime: now,
|
|
2575
|
+
...timeToFirstTokenMs !== void 0 ? { timeToFirstTokenMs } : {}
|
|
2576
|
+
} });
|
|
2577
|
+
}
|
|
2578
|
+
}
|
|
2579
|
+
/** What the current inference streamed so far, for whichever way it ends. */
|
|
2580
|
+
#inferenceStreamAttributes() {
|
|
2581
|
+
return {
|
|
2582
|
+
...this.#inferenceCompletionStartTime ? { completionStartTime: this.#inferenceCompletionStartTime } : {},
|
|
2583
|
+
...this.#inferenceTimeToFirstTokenMs !== void 0 ? { timeToFirstTokenMs: this.#inferenceTimeToFirstTokenMs } : {}
|
|
2584
|
+
};
|
|
2555
2585
|
}
|
|
2556
2586
|
/**
|
|
2557
2587
|
* Get the tracing context for creating child spans.
|
|
@@ -2566,21 +2596,33 @@ var ModelSpanTracker = class {
|
|
|
2566
2596
|
* doesn't leave them dangling. No-op if they were already closed.
|
|
2567
2597
|
*/
|
|
2568
2598
|
reportGenerationError(options) {
|
|
2599
|
+
this.#endChunkSpan();
|
|
2600
|
+
const termination = options.outcome != null ? {
|
|
2601
|
+
outcome: options.outcome,
|
|
2602
|
+
stopReason: options.stopReason,
|
|
2603
|
+
stopReasonContext: options.stopReasonContext
|
|
2604
|
+
} : coreObservability.executionFailureTermination?.(options.error);
|
|
2569
2605
|
if (this.#currentInferenceSpan) {
|
|
2570
2606
|
this.#currentInferenceSpan.error({
|
|
2571
2607
|
error: options.error,
|
|
2572
|
-
|
|
2608
|
+
...termination ? interruptedByRun(termination) : {},
|
|
2609
|
+
endSpan: true,
|
|
2610
|
+
attributes: this.#inferenceStreamAttributes()
|
|
2573
2611
|
});
|
|
2574
2612
|
this.#currentInferenceSpan = void 0;
|
|
2575
2613
|
}
|
|
2576
2614
|
if (this.#currentStepSpan) {
|
|
2577
2615
|
this.#currentStepSpan.error({
|
|
2578
2616
|
error: options.error,
|
|
2617
|
+
...termination ? interruptedByRun(termination) : {},
|
|
2579
2618
|
endSpan: true
|
|
2580
2619
|
});
|
|
2581
2620
|
this.#currentStepSpan = void 0;
|
|
2582
2621
|
}
|
|
2583
|
-
this.#modelSpan?.error(
|
|
2622
|
+
this.#modelSpan?.error({
|
|
2623
|
+
...options,
|
|
2624
|
+
...termination
|
|
2625
|
+
});
|
|
2584
2626
|
}
|
|
2585
2627
|
/**
|
|
2586
2628
|
* End the generation span with optional raw usage data.
|
|
@@ -2595,16 +2637,37 @@ var ModelSpanTracker = class {
|
|
|
2595
2637
|
}, model);
|
|
2596
2638
|
if (providerCostContext && !spanOptions.attributes) spanOptions.attributes = {};
|
|
2597
2639
|
if (spanOptions.attributes) {
|
|
2598
|
-
|
|
2640
|
+
if (this.#completionStartTime) {
|
|
2641
|
+
spanOptions.attributes.completionStartTime = this.#completionStartTime;
|
|
2642
|
+
spanOptions.attributes.timeToFirstTokenMs = this.#timeToFirstTokenMs;
|
|
2643
|
+
}
|
|
2599
2644
|
spanOptions.attributes.usage = extractUsageMetrics(usage, providerMetadata);
|
|
2600
2645
|
spanOptions.attributes.costContext = providerCostContext ?? spanOptions.attributes.costContext;
|
|
2601
2646
|
if (!spanOptions.attributes.costContext) spanOptions.attributes.costContext = getGatewayCostContext({ stepProviderMetadata });
|
|
2602
2647
|
}
|
|
2648
|
+
if (spanOptions.outcome === "abort" || spanOptions.stopReason === "timeout") {
|
|
2649
|
+
const termination = {
|
|
2650
|
+
outcome: spanOptions.outcome,
|
|
2651
|
+
stopReason: spanOptions.stopReason,
|
|
2652
|
+
stopReasonContext: spanOptions.stopReasonContext
|
|
2653
|
+
};
|
|
2654
|
+
this.#endChunkSpan();
|
|
2655
|
+
this.#currentStepSpan?.end({
|
|
2656
|
+
...interruptedByRun(termination),
|
|
2657
|
+
endTree: true
|
|
2658
|
+
});
|
|
2659
|
+
this.#currentStepSpan = void 0;
|
|
2660
|
+
this.#currentInferenceSpan = void 0;
|
|
2661
|
+
this.#currentStepInputIsFinal = false;
|
|
2662
|
+
}
|
|
2603
2663
|
this.#modelSpan?.end(spanOptions);
|
|
2604
2664
|
}
|
|
2605
2665
|
getCompletionStartTime() {
|
|
2606
2666
|
return this.#completionStartTime;
|
|
2607
2667
|
}
|
|
2668
|
+
getTimeToFirstTokenMs() {
|
|
2669
|
+
return this.#timeToFirstTokenMs;
|
|
2670
|
+
}
|
|
2608
2671
|
/**
|
|
2609
2672
|
* Update the generation span
|
|
2610
2673
|
*/
|
|
@@ -2658,10 +2721,12 @@ var ModelSpanTracker = class {
|
|
|
2658
2721
|
*/
|
|
2659
2722
|
startStep(payload) {
|
|
2660
2723
|
if (this.#currentStepSpan) return;
|
|
2724
|
+
this.#stepHasInference = false;
|
|
2661
2725
|
const input = extractStepInput(payload);
|
|
2662
2726
|
this.#currentStepSpan = this.#modelSpan?.createChildSpan({
|
|
2663
2727
|
name: `step: ${this.#stepIndex}`,
|
|
2664
2728
|
type: SpanType.MODEL_STEP,
|
|
2729
|
+
...typeof coreObservability.agentLoopTermination === "function" ? { outcome: null } : {},
|
|
2665
2730
|
attributes: {
|
|
2666
2731
|
stepIndex: this.#stepIndex,
|
|
2667
2732
|
...payload?.messageId ? { messageId: payload.messageId } : {},
|
|
@@ -2673,6 +2738,7 @@ var ModelSpanTracker = class {
|
|
|
2673
2738
|
this.#currentStepInputIsFinal = Array.isArray(payload?.inputMessages);
|
|
2674
2739
|
this.#chunkSequence = 0;
|
|
2675
2740
|
this.#inferenceCompletionStartTime = void 0;
|
|
2741
|
+
this.#inferenceTimeToFirstTokenMs = void 0;
|
|
2676
2742
|
}
|
|
2677
2743
|
/**
|
|
2678
2744
|
* End the current MODEL_INFERENCE span when the provider stream finishes.
|
|
@@ -2682,22 +2748,31 @@ var ModelSpanTracker = class {
|
|
|
2682
2748
|
*
|
|
2683
2749
|
* Safe to call multiple times - no-ops if the span is already closed.
|
|
2684
2750
|
*/
|
|
2685
|
-
#endInferenceSpan(payload) {
|
|
2751
|
+
#endInferenceSpan(payload, captureOutput = true) {
|
|
2686
2752
|
if (!this.#currentInferenceSpan) return;
|
|
2687
2753
|
const { usage: rawUsage, ...otherOutput } = payload.output;
|
|
2688
2754
|
const usage = extractUsageMetrics(rawUsage, payload.metadata?.providerMetadata);
|
|
2689
2755
|
const responseModel = typeof payload.metadata?.modelId === "string" ? payload.metadata.modelId : void 0;
|
|
2690
2756
|
this.#currentInferenceSpan.end({
|
|
2691
|
-
|
|
2757
|
+
...coreObservability.agentLoopTermination?.({
|
|
2758
|
+
stopCause: "model_finished",
|
|
2759
|
+
finishReason: payload.stepResult.reason
|
|
2760
|
+
}),
|
|
2761
|
+
...payload.stepResult.reason === "error" ? {
|
|
2762
|
+
outcome: "error",
|
|
2763
|
+
stopReason: "model_error"
|
|
2764
|
+
} : {},
|
|
2765
|
+
...captureOutput ? { output: otherOutput } : {},
|
|
2692
2766
|
attributes: {
|
|
2693
2767
|
usage,
|
|
2694
2768
|
finishReason: payload.stepResult.reason,
|
|
2695
2769
|
warnings: payload.stepResult.warnings,
|
|
2696
|
-
|
|
2770
|
+
...this.#inferenceStreamAttributes(),
|
|
2697
2771
|
...responseModel?.trim() ? { responseModel } : {}
|
|
2698
2772
|
}
|
|
2699
2773
|
});
|
|
2700
2774
|
this.#currentInferenceSpan = void 0;
|
|
2775
|
+
this.#inferenceCompletionStartTime = void 0;
|
|
2701
2776
|
}
|
|
2702
2777
|
/**
|
|
2703
2778
|
* Open the MODEL_INFERENCE span for the current step. Chunks (including tool-call
|
|
@@ -2715,31 +2790,56 @@ var ModelSpanTracker = class {
|
|
|
2715
2790
|
* start time.
|
|
2716
2791
|
*
|
|
2717
2792
|
* `payload.modelId` / `payload.provider` name the model the caller is about
|
|
2718
|
-
* to invoke and are recorded on MODEL_STEP
|
|
2719
|
-
*
|
|
2720
|
-
* a
|
|
2793
|
+
* to invoke and are recorded on MODEL_STEP and the inference. A named call
|
|
2794
|
+
* while an inference is still open is the next attempt of the same step (a
|
|
2795
|
+
* fallback model after a failure): that inference ends as failed and the
|
|
2796
|
+
* attempt gets its own, so its timing and model are its own. The safety net
|
|
2797
|
+
* never records them: a replayed step-start chunk names the model of the
|
|
2798
|
+
* original call.
|
|
2721
2799
|
*/
|
|
2722
2800
|
startInference(payload) {
|
|
2723
|
-
if (payload?.modelId && payload.provider)
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2801
|
+
if (payload?.modelId && payload.provider) {
|
|
2802
|
+
this.#currentStepSpan?.update({ attributes: {
|
|
2803
|
+
model: payload.modelId,
|
|
2804
|
+
provider: payload.provider
|
|
2805
|
+
} });
|
|
2806
|
+
this.failInference(/* @__PURE__ */ new Error("Model call ended without a result before the next attempt started"));
|
|
2807
|
+
}
|
|
2727
2808
|
this.#openInference(payload);
|
|
2728
2809
|
}
|
|
2810
|
+
/** End the current attempt only; generation and agent spans belong to their owners. */
|
|
2811
|
+
endAttempt(termination) {
|
|
2812
|
+
termination = interruptedByRun(termination);
|
|
2813
|
+
const payload = this.#pendingStepFinishPayload;
|
|
2814
|
+
if (payload) this.#endStepSpan(payload, termination);
|
|
2815
|
+
else {
|
|
2816
|
+
this.#endChunkSpan();
|
|
2817
|
+
this.#currentInferenceSpan?.end(termination);
|
|
2818
|
+
this.#currentStepSpan?.end(termination);
|
|
2819
|
+
this.#currentStepSpan = void 0;
|
|
2820
|
+
this.#currentInferenceSpan = void 0;
|
|
2821
|
+
}
|
|
2822
|
+
this.#pendingStepFinishPayload = void 0;
|
|
2823
|
+
this.#inferenceCompletionStartTime = void 0;
|
|
2824
|
+
this.#currentStepInputIsFinal = false;
|
|
2825
|
+
}
|
|
2729
2826
|
#openInference(payload) {
|
|
2730
2827
|
if (!supportsModelInference()) return;
|
|
2731
2828
|
if (!this.#currentStepSpan || this.#currentInferenceSpan) return;
|
|
2732
2829
|
this.#inferenceCompletionStartTime = void 0;
|
|
2830
|
+
this.#inferenceTimeToFirstTokenMs = void 0;
|
|
2733
2831
|
const input = extractStepInput(payload);
|
|
2734
2832
|
const generationAttrs = this.#modelSpan?.attributes;
|
|
2735
2833
|
const ctx = this.#inferenceContext;
|
|
2834
|
+
this.#stepHasInference = true;
|
|
2736
2835
|
this.#currentInferenceSpan = this.#currentStepSpan.createChildSpan({
|
|
2737
2836
|
name: `inference: ${this.#stepIndex}`,
|
|
2738
2837
|
type: SpanType.MODEL_INFERENCE,
|
|
2838
|
+
...typeof coreObservability.agentLoopTermination === "function" ? { outcome: null } : {},
|
|
2739
2839
|
attributes: {
|
|
2740
2840
|
stepIndex: this.#stepIndex,
|
|
2741
|
-
model: generationAttrs?.model,
|
|
2742
|
-
provider: generationAttrs?.provider,
|
|
2841
|
+
model: payload?.modelId ?? generationAttrs?.model,
|
|
2842
|
+
provider: payload?.provider ?? generationAttrs?.provider,
|
|
2743
2843
|
streaming: generationAttrs?.streaming,
|
|
2744
2844
|
...ctx?.parameters !== void 0 ? { parameters: ctx.parameters } : {},
|
|
2745
2845
|
...ctx?.providerOptions !== void 0 ? { providerOptions: ctx.providerOptions } : {},
|
|
@@ -2756,11 +2856,37 @@ var ModelSpanTracker = class {
|
|
|
2756
2856
|
* End the open MODEL_INFERENCE span as interrupted while keeping MODEL_STEP open,
|
|
2757
2857
|
* so a replacement request for the same step gets its own inference span.
|
|
2758
2858
|
*/
|
|
2759
|
-
interruptInference() {
|
|
2859
|
+
interruptInference(termination) {
|
|
2860
|
+
this.#endChunkSpan();
|
|
2861
|
+
if (!this.#currentInferenceSpan) return;
|
|
2862
|
+
this.#currentInferenceSpan.end({
|
|
2863
|
+
attributes: {
|
|
2864
|
+
finishReason: "interrupted",
|
|
2865
|
+
...this.#inferenceStreamAttributes()
|
|
2866
|
+
},
|
|
2867
|
+
...termination ?? (typeof coreObservability.agentLoopTermination === "function" ? {
|
|
2868
|
+
outcome: "interrupted",
|
|
2869
|
+
stopReason: null,
|
|
2870
|
+
stopReasonContext: null
|
|
2871
|
+
} : {})
|
|
2872
|
+
});
|
|
2873
|
+
this.#currentInferenceSpan = void 0;
|
|
2874
|
+
this.#inferenceCompletionStartTime = void 0;
|
|
2875
|
+
this.#inferenceTimeToFirstTokenMs = void 0;
|
|
2876
|
+
}
|
|
2877
|
+
/** End the open inference span, if any, with `error` and what it streamed. */
|
|
2878
|
+
failInference(error) {
|
|
2760
2879
|
this.#endChunkSpan();
|
|
2761
2880
|
if (!this.#currentInferenceSpan) return;
|
|
2762
|
-
this.#currentInferenceSpan.
|
|
2881
|
+
this.#currentInferenceSpan.error({
|
|
2882
|
+
error,
|
|
2883
|
+
...coreObservability.executionFailureTermination?.(error, "model_error"),
|
|
2884
|
+
endSpan: true,
|
|
2885
|
+
attributes: this.#inferenceStreamAttributes()
|
|
2886
|
+
});
|
|
2887
|
+
this.#inferenceTimeToFirstTokenMs = void 0;
|
|
2763
2888
|
this.#currentInferenceSpan = void 0;
|
|
2889
|
+
this.#inferenceCompletionStartTime = void 0;
|
|
2764
2890
|
}
|
|
2765
2891
|
/**
|
|
2766
2892
|
* Update the current step span with additional payload data.
|
|
@@ -2782,10 +2908,11 @@ var ModelSpanTracker = class {
|
|
|
2782
2908
|
/**
|
|
2783
2909
|
* End the current Model execution step with token usage, finish reason, output, and metadata
|
|
2784
2910
|
*/
|
|
2785
|
-
#endStepSpan(payload) {
|
|
2911
|
+
#endStepSpan(payload, termination) {
|
|
2786
2912
|
this.#endChunkSpan();
|
|
2787
2913
|
if (!this.#currentStepSpan) return;
|
|
2788
|
-
const
|
|
2914
|
+
const output = payload.output;
|
|
2915
|
+
const { usage: rawUsage, ...otherOutput } = output;
|
|
2789
2916
|
const stepResult = payload.stepResult;
|
|
2790
2917
|
const metadata = payload.metadata;
|
|
2791
2918
|
const usage = extractUsageMetrics(rawUsage, metadata?.providerMetadata);
|
|
@@ -2801,6 +2928,11 @@ var ModelSpanTracker = class {
|
|
|
2801
2928
|
]) delete cleanMetadata[key];
|
|
2802
2929
|
this.#endInferenceSpan(payload);
|
|
2803
2930
|
this.#currentStepSpan.end({
|
|
2931
|
+
...termination ?? coreObservability.agentLoopTermination?.({
|
|
2932
|
+
stopCause: "model_finished",
|
|
2933
|
+
finishReason: stepResult.reason,
|
|
2934
|
+
tripwire: output.steps?.at(-1)?.tripwire
|
|
2935
|
+
}),
|
|
2804
2936
|
output: otherOutput,
|
|
2805
2937
|
attributes: {
|
|
2806
2938
|
usage,
|
|
@@ -2832,26 +2964,23 @@ var ModelSpanTracker = class {
|
|
|
2832
2964
|
warnings: []
|
|
2833
2965
|
},
|
|
2834
2966
|
metadata: {}
|
|
2835
|
-
}
|
|
2967
|
+
}, coreObservability.agentLoopTermination?.({
|
|
2968
|
+
finishReason: "suspended",
|
|
2969
|
+
suspension: {
|
|
2970
|
+
approvalRequired: chunk.type === "tool-call-approval",
|
|
2971
|
+
toolCallId: chunk.payload.toolCallId,
|
|
2972
|
+
toolName: chunk.payload.toolName
|
|
2973
|
+
}
|
|
2974
|
+
}));
|
|
2836
2975
|
}
|
|
2837
|
-
/**
|
|
2838
|
-
* Returns the parent span for chunks. Chunks parent under MODEL_INFERENCE
|
|
2839
|
-
* (the provider call) when available, falling back to MODEL_STEP only if
|
|
2840
|
-
* startStep() was bypassed.
|
|
2841
|
-
*/
|
|
2976
|
+
/** Processed content belongs to the logical step, independently of provider timing. */
|
|
2842
2977
|
#chunkParent() {
|
|
2843
|
-
return this.#
|
|
2978
|
+
return this.#currentStepSpan?.endTime ? void 0 : this.#currentStepSpan;
|
|
2844
2979
|
}
|
|
2845
|
-
/**
|
|
2846
|
-
* Safety-net invoked from chunk handlers: auto-create MODEL_STEP and
|
|
2847
|
-
* MODEL_INFERENCE if a chunk arrives before the loop has explicitly opened
|
|
2848
|
-
* them, so chunks parent under MODEL_INFERENCE rather than falling through
|
|
2849
|
-
* to MODEL_STEP. Idempotent — each public start* method is itself a no-op
|
|
2850
|
-
* when its span is already live.
|
|
2851
|
-
*/
|
|
2980
|
+
/** Ensure a logical step and provider timing span exist for legacy stream callers. */
|
|
2852
2981
|
#ensureStepAndInference() {
|
|
2853
2982
|
if (!this.#currentStepSpan) this.startStep();
|
|
2854
|
-
if (!this.#currentInferenceSpan) this.#openInference();
|
|
2983
|
+
if (!this.#currentInferenceSpan && !this.#stepHasInference) this.#openInference();
|
|
2855
2984
|
}
|
|
2856
2985
|
/**
|
|
2857
2986
|
* Create a new chunk span (for multi-part chunks like text-start/delta/end)
|
|
@@ -3012,20 +3141,39 @@ var ModelSpanTracker = class {
|
|
|
3012
3141
|
tracingPolicy: this.#modelSpan?.tracingPolicy
|
|
3013
3142
|
})) this.#chunkSequence++;
|
|
3014
3143
|
}
|
|
3144
|
+
/** Track provider timing and completion without recording unprocessed content. */
|
|
3145
|
+
wrapInferenceStream(stream) {
|
|
3146
|
+
this.#tracksProviderStream = true;
|
|
3147
|
+
return this.wrapStream(stream, true);
|
|
3148
|
+
}
|
|
3015
3149
|
/**
|
|
3016
3150
|
* Wraps a stream with model tracing transform to track MODEL_STEP and MODEL_CHUNK spans.
|
|
3017
3151
|
*
|
|
3018
3152
|
* This should be added to the stream pipeline to automatically
|
|
3019
3153
|
* create MODEL_STEP and MODEL_CHUNK spans for each semantic unit in the stream.
|
|
3020
3154
|
*/
|
|
3021
|
-
wrapStream(stream) {
|
|
3155
|
+
wrapStream(stream, inferenceOnly = false) {
|
|
3022
3156
|
return stream.pipeThrough(new TransformStream({ transform: (chunk, controller) => {
|
|
3023
|
-
if (
|
|
3157
|
+
if (inferenceOnly) {
|
|
3158
|
+
try {
|
|
3159
|
+
if (MODEL_RESPONSE_CHUNK_TYPES.has(chunk.type)) this.#captureCompletionStartTime();
|
|
3160
|
+
if (chunk.type === "finish") this.#endInferenceSpan(chunk.payload, false);
|
|
3161
|
+
} catch {}
|
|
3162
|
+
controller.enqueue(chunk);
|
|
3163
|
+
return;
|
|
3164
|
+
}
|
|
3165
|
+
this.recordChunk(chunk);
|
|
3166
|
+
controller.enqueue(chunk);
|
|
3167
|
+
} }));
|
|
3168
|
+
}
|
|
3169
|
+
/** @internal Record a chunk only after output processors accept it. */
|
|
3170
|
+
recordChunk(chunk) {
|
|
3171
|
+
try {
|
|
3172
|
+
if (!this.#tracksProviderStream && (this.#inModelResponse || this.#deferStepClose) && MODEL_RESPONSE_CHUNK_TYPES.has(chunk.type)) this.#captureCompletionStartTime();
|
|
3024
3173
|
if (chunk.type === "tool-call-suspended" || chunk.type === "tool-call-approval") {
|
|
3025
3174
|
if (chunk.type === "tool-call-approval") this.#handleToolApprovalChunk(chunk);
|
|
3026
3175
|
this.#endSuspendedStep(chunk);
|
|
3027
3176
|
}
|
|
3028
|
-
controller.enqueue(chunk);
|
|
3029
3177
|
switch (chunk.type) {
|
|
3030
3178
|
case "text-start":
|
|
3031
3179
|
case "text-delta":
|
|
@@ -3051,7 +3199,7 @@ var ModelSpanTracker = class {
|
|
|
3051
3199
|
this.#inModelResponse = true;
|
|
3052
3200
|
if (this.#currentStepSpan) this.updateStep(chunk.payload);
|
|
3053
3201
|
else this.startStep(chunk.payload);
|
|
3054
|
-
if (!this.#currentInferenceSpan) this.#openInference(chunk.payload);
|
|
3202
|
+
if (!this.#currentInferenceSpan && !this.#stepHasInference) this.#openInference(chunk.payload);
|
|
3055
3203
|
break;
|
|
3056
3204
|
case "step-finish":
|
|
3057
3205
|
this.#inModelResponse = false;
|
|
@@ -3061,15 +3209,20 @@ var ModelSpanTracker = class {
|
|
|
3061
3209
|
this.#endInferenceSpan(chunk.payload);
|
|
3062
3210
|
} else this.#endStepSpan(chunk.payload);
|
|
3063
3211
|
break;
|
|
3212
|
+
case "tripwire": {
|
|
3213
|
+
const termination = coreObservability.agentLoopTermination?.({ tripwire: chunk.payload });
|
|
3214
|
+
if (!termination) break;
|
|
3215
|
+
this.endAttempt(termination);
|
|
3216
|
+
break;
|
|
3217
|
+
}
|
|
3218
|
+
case "finish": break;
|
|
3064
3219
|
case "raw":
|
|
3065
3220
|
case "start":
|
|
3066
|
-
case "finish":
|
|
3067
3221
|
case "response-metadata":
|
|
3068
3222
|
case "source":
|
|
3069
3223
|
case "file":
|
|
3070
3224
|
case "error":
|
|
3071
3225
|
case "abort":
|
|
3072
|
-
case "tripwire":
|
|
3073
3226
|
case "watch":
|
|
3074
3227
|
case "tool-error":
|
|
3075
3228
|
case "reasoning-signature":
|
|
@@ -3094,7 +3247,7 @@ var ModelSpanTracker = class {
|
|
|
3094
3247
|
break;
|
|
3095
3248
|
}
|
|
3096
3249
|
}
|
|
3097
|
-
} }
|
|
3250
|
+
} catch {}
|
|
3098
3251
|
}
|
|
3099
3252
|
};
|
|
3100
3253
|
// src/spans/metadata.ts
|
|
@@ -3283,6 +3436,9 @@ var BaseSpan = class BaseSpan {
|
|
|
3283
3436
|
observabilityInstance;
|
|
3284
3437
|
input;
|
|
3285
3438
|
output;
|
|
3439
|
+
outcome;
|
|
3440
|
+
stopReason;
|
|
3441
|
+
stopReasonContext;
|
|
3286
3442
|
errorInfo;
|
|
3287
3443
|
metadata;
|
|
3288
3444
|
requestContext;
|
|
@@ -3299,6 +3455,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3299
3455
|
parentSpanId;
|
|
3300
3456
|
/** Parent from an external tracing system (ambient OTel / dd-trace span) that Mastra did not create; carried for external correlation, not part of Mastra's own parent/child linkage */
|
|
3301
3457
|
externalParentSpanId;
|
|
3458
|
+
resumedFromSpanId;
|
|
3302
3459
|
/** Deep clean options for serialization */
|
|
3303
3460
|
deepCleanOptions;
|
|
3304
3461
|
/**
|
|
@@ -3326,6 +3483,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3326
3483
|
* live `parent`, so its original ancestors are only known from the cached export.
|
|
3327
3484
|
*/
|
|
3328
3485
|
restoredLineage;
|
|
3486
|
+
restoredIsRootSpan;
|
|
3329
3487
|
/**
|
|
3330
3488
|
* Version declared for this span's own entity, or inherited from a parent span
|
|
3331
3489
|
* of the same entity. Unlike `metadata.entityVersionId`, never an ancestor's
|
|
@@ -3346,6 +3504,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3346
3504
|
constructor(options, observabilityInstance) {
|
|
3347
3505
|
const observabilityConfig = observabilityInstance.getConfig();
|
|
3348
3506
|
this.deepCleanOptions = mergeSerializationOptions(observabilityConfig.serializationOptions);
|
|
3507
|
+
this.applyOutcome(options);
|
|
3349
3508
|
this.name = options.name;
|
|
3350
3509
|
this.type = options.type;
|
|
3351
3510
|
this.isInternal = isSpanInternal(this.type, options.tracingPolicy?.internal);
|
|
@@ -3365,6 +3524,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3365
3524
|
}
|
|
3366
3525
|
this.tags = !options.parent && options.tags?.length ? options.tags : void 0;
|
|
3367
3526
|
this.links = validLinks(options.links);
|
|
3527
|
+
this.resumedFromSpanId = options.resumedFromSpanId;
|
|
3368
3528
|
const entityParent = this.getParentSpan(false);
|
|
3369
3529
|
this.entityType = options.entityType ?? entityParent?.entityType;
|
|
3370
3530
|
this.entityId = options.entityId ?? entityParent?.entityId;
|
|
@@ -3406,14 +3566,49 @@ var BaseSpan = class BaseSpan {
|
|
|
3406
3566
|
return value;
|
|
3407
3567
|
}
|
|
3408
3568
|
}
|
|
3409
|
-
/**
|
|
3569
|
+
/** Preserve explicitly supplied native fields; never derive results from payloads/errors. */
|
|
3570
|
+
applyOutcome(options) {
|
|
3571
|
+
if (this.endTime) return;
|
|
3572
|
+
if (options.outcome !== void 0) {
|
|
3573
|
+
this.outcome = options.outcome;
|
|
3574
|
+
this.stopReason = options.stopReason ?? null;
|
|
3575
|
+
this.stopReasonContext = options.stopReasonContext == null ? null : deepClean(options.stopReasonContext, this.deepCleanOptions);
|
|
3576
|
+
return;
|
|
3577
|
+
}
|
|
3578
|
+
if (options.stopReason !== void 0 && options.stopReason !== this.stopReason) this.stopReasonContext = null;
|
|
3579
|
+
if (options.stopReason !== void 0) this.stopReason = options.stopReason;
|
|
3580
|
+
if (options.stopReasonContext !== void 0) this.stopReasonContext = options.stopReasonContext == null ? null : deepClean(options.stopReasonContext, this.deepCleanOptions);
|
|
3581
|
+
}
|
|
3582
|
+
/** Forward options to open descendants, with interruption outcomes for cascading termination. */
|
|
3410
3583
|
endTree(options) {
|
|
3411
|
-
|
|
3584
|
+
this.endOpenDescendants(options, true);
|
|
3412
3585
|
this.end(options);
|
|
3413
3586
|
}
|
|
3414
|
-
/**
|
|
3415
|
-
endOpenDescendants() {
|
|
3416
|
-
|
|
3587
|
+
/** Preserve completed children; only known cascading termination interrupts open work. */
|
|
3588
|
+
endOpenDescendants(options, forwardOptions = false) {
|
|
3589
|
+
const outcome = options?.outcome !== void 0 ? options.outcome : this.outcome;
|
|
3590
|
+
const stopReason = options?.stopReason !== void 0 ? options.stopReason : this.stopReason;
|
|
3591
|
+
const stopReasonContext = options?.stopReasonContext !== void 0 ? options.stopReasonContext : this.stopReasonContext;
|
|
3592
|
+
const interrupts = outcome === "abort" || outcome === "interrupted" || outcome === "limit" && stopReason === "timeout";
|
|
3593
|
+
const forwarded = forwardOptions ? { ...options } : {};
|
|
3594
|
+
delete forwarded.outcome;
|
|
3595
|
+
delete forwarded.stopReason;
|
|
3596
|
+
delete forwarded.stopReasonContext;
|
|
3597
|
+
if (this.#openChildren) for (const child of [...this.#openChildren]) {
|
|
3598
|
+
const childOptions = {
|
|
3599
|
+
...forwarded,
|
|
3600
|
+
...interrupts ? {
|
|
3601
|
+
outcome: "interrupted",
|
|
3602
|
+
stopReason,
|
|
3603
|
+
stopReasonContext
|
|
3604
|
+
} : {}
|
|
3605
|
+
};
|
|
3606
|
+
if (forwardOptions) child.endTree(childOptions);
|
|
3607
|
+
else child.end({
|
|
3608
|
+
...childOptions,
|
|
3609
|
+
endTree: true
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3417
3612
|
}
|
|
3418
3613
|
/**
|
|
3419
3614
|
* Release this span from its parent's open-child set once it has ended.
|
|
@@ -3464,7 +3659,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3464
3659
|
}
|
|
3465
3660
|
/** Returns `TRUE` if the span is the root span of a trace */
|
|
3466
3661
|
get isRootSpan() {
|
|
3467
|
-
return !this.parent;
|
|
3662
|
+
return this.restoredIsRootSpan ?? !this.parent;
|
|
3468
3663
|
}
|
|
3469
3664
|
/**
|
|
3470
3665
|
* Get the closest parent span.
|
|
@@ -3528,6 +3723,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3528
3723
|
*/
|
|
3529
3724
|
restoreEntityLineage(cached) {
|
|
3530
3725
|
this.ownEntityVersionId = cached.ownEntityVersionId ?? void 0;
|
|
3726
|
+
this.restoredIsRootSpan = cached.isRootSpan;
|
|
3531
3727
|
const lineage = definedLineage(cached);
|
|
3532
3728
|
if (Object.keys(lineage).length > 0) {
|
|
3533
3729
|
this.restoredLineage = lineage;
|
|
@@ -3610,6 +3806,7 @@ var BaseSpan = class BaseSpan {
|
|
|
3610
3806
|
const nestedUnderParent = this.traceState?.nestedUnderParent ?? false;
|
|
3611
3807
|
const links = validLinks(this.links);
|
|
3612
3808
|
const correlation = this.getCorrelationContext();
|
|
3809
|
+
const timeToFirstTokenMs = this.attributes?.timeToFirstTokenMs;
|
|
3613
3810
|
return {
|
|
3614
3811
|
id: this.id,
|
|
3615
3812
|
traceId: this.traceId,
|
|
@@ -3625,6 +3822,9 @@ var BaseSpan = class BaseSpan {
|
|
|
3625
3822
|
input: hideInput ? void 0 : this.input,
|
|
3626
3823
|
output: hideOutput ? void 0 : this.output,
|
|
3627
3824
|
errorInfo: this.errorInfo,
|
|
3825
|
+
...this.outcome !== void 0 ? { outcome: this.outcome } : {},
|
|
3826
|
+
...this.stopReason !== void 0 ? { stopReason: this.stopReason } : {},
|
|
3827
|
+
...this.stopReasonContext !== void 0 ? { stopReasonContext: this.stopReasonContext } : {},
|
|
3628
3828
|
requestContext: this.requestContext,
|
|
3629
3829
|
isEvent: this.isEvent,
|
|
3630
3830
|
isRootSpan: this.isRootSpan,
|
|
@@ -3633,6 +3833,8 @@ var BaseSpan = class BaseSpan {
|
|
|
3633
3833
|
...definedLineage(correlation),
|
|
3634
3834
|
parentSpanId: this.getParentSpanId(includeInternalSpans),
|
|
3635
3835
|
externalParentSpanId: this.getExportedExternalParentSpanId(includeInternalSpans),
|
|
3836
|
+
...this.resumedFromSpanId !== void 0 ? { resumedFromSpanId: this.resumedFromSpanId } : {},
|
|
3837
|
+
...typeof timeToFirstTokenMs === "number" ? { timeToFirstTokenMs } : {},
|
|
3636
3838
|
...nestedUnderParent ? { nestedUnderParent: true } : {},
|
|
3637
3839
|
...links ? { links } : {},
|
|
3638
3840
|
...this.isRootSpan && !nestedUnderParent && this.tags?.length ? { tags: this.tags } : {}
|
|
@@ -3742,7 +3944,9 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
3742
3944
|
end(options) {
|
|
3743
3945
|
if (this.isEvent) return;
|
|
3744
3946
|
if (this.endTime) return;
|
|
3745
|
-
if (options?.endTree) this.endOpenDescendants();
|
|
3947
|
+
if (options?.endTree) this.endOpenDescendants(options);
|
|
3948
|
+
if (options) this.applyOutcome(options);
|
|
3949
|
+
if (this.outcome === null) this.outcome = "unknown";
|
|
3746
3950
|
this.endTime = /* @__PURE__ */ new Date();
|
|
3747
3951
|
this.detachFromParent();
|
|
3748
3952
|
if (options?.metadata) this.metadata = {
|
|
@@ -3757,8 +3961,9 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
3757
3961
|
};
|
|
3758
3962
|
}
|
|
3759
3963
|
error(options) {
|
|
3760
|
-
if (this.isEvent) return;
|
|
3964
|
+
if (this.isEvent || this.endTime) return;
|
|
3761
3965
|
const { error, endSpan = true, endTree, attributes, metadata } = options;
|
|
3966
|
+
this.applyOutcome(options);
|
|
3762
3967
|
if (metadata) this.metadata = {
|
|
3763
3968
|
...this.metadata,
|
|
3764
3969
|
...deepClean(this.prepareSpanMetadata(metadata), this.deepCleanOptions)
|
|
@@ -3793,6 +3998,7 @@ var DefaultSpan = class extends BaseSpan {
|
|
|
3793
3998
|
}
|
|
3794
3999
|
update(options) {
|
|
3795
4000
|
if (this.isEvent) return;
|
|
4001
|
+
this.applyOutcome(options);
|
|
3796
4002
|
if (options.name !== void 0) this.name = options.name;
|
|
3797
4003
|
if (options.metadata) this.metadata = {
|
|
3798
4004
|
...this.metadata,
|
|
@@ -3861,7 +4067,7 @@ function isValidSpanId(spanId) {
|
|
|
3861
4067
|
function getOrCreateTraceId(options) {
|
|
3862
4068
|
if (options.traceId) {
|
|
3863
4069
|
if (isValidTraceId(options.traceId)) return options.traceId;
|
|
3864
|
-
|
|
4070
|
+
console.error(`[Mastra Tracing] Invalid traceId: must be 1-32 hexadecimal characters, got "${options.traceId}". Generating new trace ID.`);
|
|
3865
4071
|
}
|
|
3866
4072
|
return generateTraceId();
|
|
3867
4073
|
}
|
|
@@ -5262,13 +5468,13 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
5262
5468
|
...rest,
|
|
5263
5469
|
metadata
|
|
5264
5470
|
}, this);
|
|
5265
|
-
} else if (!this.shouldSample(customSamplerOptions)) return new NoOpSpan({
|
|
5471
|
+
} else if (!(options.samplingDecision ?? this.shouldSample(customSamplerOptions))) return new NoOpSpan({
|
|
5266
5472
|
...rest,
|
|
5267
5473
|
metadata
|
|
5268
5474
|
}, this);
|
|
5269
5475
|
let traceState;
|
|
5270
5476
|
if (options.parent) traceState = options.parent.traceState;
|
|
5271
|
-
else traceState = this.computeTraceState(tracingOptions);
|
|
5477
|
+
else traceState = options.traceState ?? this.computeTraceState(tracingOptions);
|
|
5272
5478
|
const tracingMetadata = !options.parent ? tracingOptions?.metadata : void 0;
|
|
5273
5479
|
const mergedMetadata = mergeMetadata$1(stripUndefined(metadata), stripUndefined(tracingMetadata));
|
|
5274
5480
|
const enrichedMetadata = this.extractMetadataFromRequestContext(requestContext, mergedMetadata, traceState);
|
|
@@ -5323,6 +5529,11 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
5323
5529
|
* @returns A span that can have lifecycle methods called on it
|
|
5324
5530
|
*/
|
|
5325
5531
|
rebuildSpan(cached) {
|
|
5532
|
+
if (cached.id === "no-op" && cached.traceId === "no-op-trace") return new NoOpSpan({
|
|
5533
|
+
name: cached.name,
|
|
5534
|
+
type: cached.type,
|
|
5535
|
+
traceState: cached.traceState
|
|
5536
|
+
}, this);
|
|
5326
5537
|
const span = this.createSpan({
|
|
5327
5538
|
name: cached.name,
|
|
5328
5539
|
type: cached.type,
|
|
@@ -5330,6 +5541,10 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
5330
5541
|
spanId: cached.id,
|
|
5331
5542
|
parentSpanId: cached.parentSpanId,
|
|
5332
5543
|
externalParentSpanId: cached.externalParentSpanId,
|
|
5544
|
+
resumedFromSpanId: cached.resumedFromSpanId,
|
|
5545
|
+
outcome: cached.outcome,
|
|
5546
|
+
stopReason: cached.stopReason,
|
|
5547
|
+
stopReasonContext: cached.stopReasonContext,
|
|
5333
5548
|
links: cached.links,
|
|
5334
5549
|
startTime: cached.startTime instanceof Date ? cached.startTime : new Date(cached.startTime),
|
|
5335
5550
|
input: cached.input,
|
|
@@ -5342,6 +5557,11 @@ var BaseObservabilityInstance = class extends MastraBase {
|
|
|
5342
5557
|
traceState: this.rebuildTraceState(cached)
|
|
5343
5558
|
});
|
|
5344
5559
|
if (span instanceof BaseSpan) span.restoreEntityLineage(cached);
|
|
5560
|
+
if (cached.endTime) {
|
|
5561
|
+
span.endTime = cached.endTime instanceof Date ? cached.endTime : new Date(cached.endTime);
|
|
5562
|
+
span.output = cached.output;
|
|
5563
|
+
span.errorInfo = cached.errorInfo;
|
|
5564
|
+
}
|
|
5345
5565
|
this.wireSpanLifecycle(span);
|
|
5346
5566
|
return span;
|
|
5347
5567
|
}
|
|
@@ -9106,7 +9326,11 @@ var TestExporter = class extends BaseExporter {
|
|
|
9106
9326
|
if (span.parentSpanId && spanIdMap.has(span.parentSpanId)) normalizedSpan.parentId = spanIdMap.get(span.parentSpanId);
|
|
9107
9327
|
if (span.entityType) normalizedSpan.entityType = span.entityType;
|
|
9108
9328
|
if (span.entityId) normalizedSpan.entityId = normalizeValue(span.entityId, "entityId");
|
|
9109
|
-
if (span.attributes && Object.keys(span.attributes).length > 0)
|
|
9329
|
+
if (span.attributes && Object.keys(span.attributes).length > 0) {
|
|
9330
|
+
const attributes = normalizeValue(span.attributes);
|
|
9331
|
+
if (typeof attributes.timeToFirstTokenMs === "number") attributes.timeToFirstTokenMs = "<ms>";
|
|
9332
|
+
normalizedSpan.attributes = attributes;
|
|
9333
|
+
}
|
|
9110
9334
|
if (span.metadata && Object.keys(span.metadata).length > 0) normalizedSpan.metadata = normalizeValue(span.metadata);
|
|
9111
9335
|
if (span.input !== void 0) normalizedSpan.input = normalizeValue(span.input);
|
|
9112
9336
|
if (span.output !== void 0) normalizedSpan.output = normalizeValue(span.output);
|
|
@@ -9998,6 +10222,7 @@ var SensitiveDataFilter = class {
|
|
|
9998
10222
|
span.input = this.tryFilter(span.input, indexedState);
|
|
9999
10223
|
span.output = this.tryFilter(span.output, indexedState);
|
|
10000
10224
|
span.errorInfo = this.tryFilter(span.errorInfo, indexedState);
|
|
10225
|
+
span.stopReasonContext = this.tryFilter(span.stopReasonContext, indexedState);
|
|
10001
10226
|
span.requestContext = this.tryFilter(span.requestContext, indexedState);
|
|
10002
10227
|
return span;
|
|
10003
10228
|
}
|