@paid-ai/paid-node 1.7.0 → 1.7.1
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.
|
@@ -35,6 +35,23 @@ const ATTRIBUTE_MAP = {
|
|
|
35
35
|
function isAISDKSpan(span) {
|
|
36
36
|
const attrs = span.attributes;
|
|
37
37
|
const name = span.name.toLowerCase();
|
|
38
|
+
// The AI SDK emits two spans per call: an outer wrapper (e.g. ai.generateObject)
|
|
39
|
+
// and an inner span that actually hits the provider (e.g. ai.generateObject.doGenerate).
|
|
40
|
+
// Both carry identical token usage attributes, so processing both double-counts costs.
|
|
41
|
+
//
|
|
42
|
+
// We can't use attribute presence to distinguish them — outer and inner spans share
|
|
43
|
+
// the same base attributes (ai.model.id, ai.model.provider), and response-model
|
|
44
|
+
// attributes are only set on LLM inner spans, not embedding inner spans (doEmbed).
|
|
45
|
+
//
|
|
46
|
+
// The AI SDK's naming convention for inner (provider-call) spans is to include a
|
|
47
|
+
// ".do" segment in the operationId (doGenerate, doStream, doEmbed). This is the
|
|
48
|
+
// SDK's structural contract for separating orchestration from provider calls, and
|
|
49
|
+
// is the only reliable discriminator that works across all operation types (LLM,
|
|
50
|
+
// embedding) and telemetry formats (modern GenAI semconv, legacy LegacyOpenTelemetry).
|
|
51
|
+
const operationId = attrs["ai.operationId"];
|
|
52
|
+
if (typeof operationId === "string" && !operationId.includes(".do")) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
38
55
|
// Check for AI SDK specific attributes (most reliable)
|
|
39
56
|
// Also check span name - account for PaidSpanProcessor prefix (paid.trace.ai.xxx)
|
|
40
57
|
return !!(attrs["ai.model.id"] ||
|
|
@@ -32,6 +32,23 @@ const ATTRIBUTE_MAP = {
|
|
|
32
32
|
function isAISDKSpan(span) {
|
|
33
33
|
const attrs = span.attributes;
|
|
34
34
|
const name = span.name.toLowerCase();
|
|
35
|
+
// The AI SDK emits two spans per call: an outer wrapper (e.g. ai.generateObject)
|
|
36
|
+
// and an inner span that actually hits the provider (e.g. ai.generateObject.doGenerate).
|
|
37
|
+
// Both carry identical token usage attributes, so processing both double-counts costs.
|
|
38
|
+
//
|
|
39
|
+
// We can't use attribute presence to distinguish them — outer and inner spans share
|
|
40
|
+
// the same base attributes (ai.model.id, ai.model.provider), and response-model
|
|
41
|
+
// attributes are only set on LLM inner spans, not embedding inner spans (doEmbed).
|
|
42
|
+
//
|
|
43
|
+
// The AI SDK's naming convention for inner (provider-call) spans is to include a
|
|
44
|
+
// ".do" segment in the operationId (doGenerate, doStream, doEmbed). This is the
|
|
45
|
+
// SDK's structural contract for separating orchestration from provider calls, and
|
|
46
|
+
// is the only reliable discriminator that works across all operation types (LLM,
|
|
47
|
+
// embedding) and telemetry formats (modern GenAI semconv, legacy LegacyOpenTelemetry).
|
|
48
|
+
const operationId = attrs["ai.operationId"];
|
|
49
|
+
if (typeof operationId === "string" && !operationId.includes(".do")) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
35
52
|
// Check for AI SDK specific attributes (most reliable)
|
|
36
53
|
// Also check span name - account for PaidSpanProcessor prefix (paid.trace.ai.xxx)
|
|
37
54
|
return !!(attrs["ai.model.id"] ||
|