autotel-genai 0.6.1 → 0.6.2

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/README.md CHANGED
@@ -254,7 +254,8 @@ const honeyToken = createHoneyTokenTool({
254
254
  ### Vercel AI SDK
255
255
 
256
256
  Register `autotelTelemetry()` once and every `generateText` / `streamText` /
257
- `embed` call streams a canonical `gen_ai.*` span tree. Live, as it runs:
257
+ `generateObject` / `streamObject` / `embed` call streams a canonical `gen_ai.*`
258
+ span tree. Live, as it runs:
258
259
 
259
260
  ```ts
260
261
  import { registerTelemetry } from 'ai';
@@ -279,7 +280,10 @@ on every `chat` span:
279
280
  It is push-based and concurrency-safe (every event carries the SDK `callId`),
280
281
  and it pulls in **no** dependency on `ai`. The returned object satisfies the
281
282
  `Telemetry` interface structurally, so the snippet above type-checks as-is.
282
- `rerank` has no canonical `gen_ai` operation and is intentionally not mapped.
283
+ Embeddings open on `onEmbedStart` so span duration is the real model call.
284
+ `runtimeContext.userId` / `sessionId` become `user.id` /
285
+ `gen_ai.conversation.id`; other keys are dropped. `rerank` has no canonical
286
+ `gen_ai` operation and is intentionally not mapped.
283
287
 
284
288
  **Nested traces.** It implements the SDK's `executeTool` / `executeLanguageModelCall`
285
289
  context runners, so a tool whose `execute` calls `generateText`. And the
@@ -332,6 +332,11 @@ interface OperationStartEvent {
332
332
  modelId?: string;
333
333
  /** From telemetry settings — used as the agent name. */
334
334
  functionId?: string;
335
+ /**
336
+ * Call-level context already filtered by the SDK. Only `userId` and
337
+ * `sessionId` are recorded (`user.id`, `gen_ai.conversation.id`).
338
+ */
339
+ runtimeContext?: Record<string, unknown>;
335
340
  }
336
341
  interface LanguageModelCallStartEventView {
337
342
  callId: string;
@@ -387,6 +392,24 @@ interface ToolExecutionEndEventView {
387
392
  toolOutput: ToolOutputView;
388
393
  recordOutputs?: boolean;
389
394
  }
395
+ interface ObjectStepStartEventView {
396
+ callId: string;
397
+ provider?: string;
398
+ modelId?: string;
399
+ }
400
+ interface ObjectStepEndEventView {
401
+ callId: string;
402
+ finishReason?: string;
403
+ response?: {
404
+ id?: string;
405
+ modelId?: string;
406
+ };
407
+ usage?: AiSdkUsageFields;
408
+ objectText?: string;
409
+ /** Whether the SDK call permits recording outputs (default true). */
410
+ recordOutputs?: boolean;
411
+ msToFirstChunk?: number;
412
+ }
390
413
  interface OperationEndEventView {
391
414
  callId: string;
392
415
  }
@@ -394,6 +417,12 @@ interface AbortEventView {
394
417
  callId: string;
395
418
  reason?: unknown;
396
419
  }
420
+ interface EmbeddingModelCallStartEventView {
421
+ callId: string;
422
+ embedCallId?: string;
423
+ provider?: string;
424
+ modelId?: string;
425
+ }
397
426
  interface EmbeddingModelCallEndEventView {
398
427
  callId: string;
399
428
  embedCallId?: string;
@@ -413,6 +442,9 @@ interface AutotelTelemetryIntegration {
413
442
  onLanguageModelCallEnd(event: LanguageModelCallEndEventView): void;
414
443
  onToolExecutionStart(event: ToolExecutionStartEventView): void;
415
444
  onToolExecutionEnd(event: ToolExecutionEndEventView): void;
445
+ onObjectStepStart(event: ObjectStepStartEventView): void;
446
+ onObjectStepEnd(event: ObjectStepEndEventView): void;
447
+ onEmbedStart(event: EmbeddingModelCallStartEventView): void;
416
448
  onEmbedEnd(event: EmbeddingModelCallEndEventView): void;
417
449
  onEnd(event: OperationEndEventView): void;
418
450
  onAbort(event: AbortEventView): void;
@@ -332,6 +332,11 @@ interface OperationStartEvent {
332
332
  modelId?: string;
333
333
  /** From telemetry settings — used as the agent name. */
334
334
  functionId?: string;
335
+ /**
336
+ * Call-level context already filtered by the SDK. Only `userId` and
337
+ * `sessionId` are recorded (`user.id`, `gen_ai.conversation.id`).
338
+ */
339
+ runtimeContext?: Record<string, unknown>;
335
340
  }
336
341
  interface LanguageModelCallStartEventView {
337
342
  callId: string;
@@ -387,6 +392,24 @@ interface ToolExecutionEndEventView {
387
392
  toolOutput: ToolOutputView;
388
393
  recordOutputs?: boolean;
389
394
  }
395
+ interface ObjectStepStartEventView {
396
+ callId: string;
397
+ provider?: string;
398
+ modelId?: string;
399
+ }
400
+ interface ObjectStepEndEventView {
401
+ callId: string;
402
+ finishReason?: string;
403
+ response?: {
404
+ id?: string;
405
+ modelId?: string;
406
+ };
407
+ usage?: AiSdkUsageFields;
408
+ objectText?: string;
409
+ /** Whether the SDK call permits recording outputs (default true). */
410
+ recordOutputs?: boolean;
411
+ msToFirstChunk?: number;
412
+ }
390
413
  interface OperationEndEventView {
391
414
  callId: string;
392
415
  }
@@ -394,6 +417,12 @@ interface AbortEventView {
394
417
  callId: string;
395
418
  reason?: unknown;
396
419
  }
420
+ interface EmbeddingModelCallStartEventView {
421
+ callId: string;
422
+ embedCallId?: string;
423
+ provider?: string;
424
+ modelId?: string;
425
+ }
397
426
  interface EmbeddingModelCallEndEventView {
398
427
  callId: string;
399
428
  embedCallId?: string;
@@ -413,6 +442,9 @@ interface AutotelTelemetryIntegration {
413
442
  onLanguageModelCallEnd(event: LanguageModelCallEndEventView): void;
414
443
  onToolExecutionStart(event: ToolExecutionStartEventView): void;
415
444
  onToolExecutionEnd(event: ToolExecutionEndEventView): void;
445
+ onObjectStepStart(event: ObjectStepStartEventView): void;
446
+ onObjectStepEnd(event: ObjectStepEndEventView): void;
447
+ onEmbedStart(event: EmbeddingModelCallStartEventView): void;
416
448
  onEmbedEnd(event: EmbeddingModelCallEndEventView): void;
417
449
  onEnd(event: OperationEndEventView): void;
418
450
  onAbort(event: AbortEventView): void;
package/dist/index.cjs CHANGED
@@ -8,7 +8,7 @@ const require_streaming = require('./streaming.cjs');
8
8
  const require_trace = require('./trace.cjs');
9
9
  const require_guard = require('./guard.cjs');
10
10
  const require_ai_sdk_bridge = require('./ai-sdk-bridge.cjs');
11
- const require_observer = require('./observer-Cic24A8t.cjs');
11
+ const require_observer = require('./observer-DdR8r0Ht.cjs');
12
12
  const require_agent = require('./agent-CpucMj6w.cjs');
13
13
 
14
14
  exports.AGENT_AUDIT_SCHEMA_VERSION = require_agent.AGENT_AUDIT_SCHEMA_VERSION;
package/dist/index.d.cts CHANGED
@@ -9,5 +9,5 @@ import { CONTEXT_LIMITS, GenAiBudgetOptions, GenAiGuard, GenAiGuardOptions, GenA
9
9
  import { GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, GenAiHistogramKind, GenAiMetricInput, genAiMetricViews, llmHistogramAdvice, recordGenAiMetrics, resetGenAiInstruments } from "./metrics.cjs";
10
10
  import { ChunkIntervalStats, ComputeStreamTimingInput, StreamTimer, StreamTiming, chunkIntervalStats, computeStreamTiming, createStreamTimer, recordStreamTiming } from "./streaming.cjs";
11
11
  import { TraceGenAIConfig, recordGenAiResponse, recordGenAiUsage, traceGenAI, traceLLM } from "./trace.cjs";
12
- import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, o as LangChainObserverHandler, p as autotelTelemetry, s as LangChainObserverOptions, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "./index-Ii-vG7B4.cjs";
12
+ import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, o as LangChainObserverHandler, p as autotelTelemetry, s as LangChainObserverOptions, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "./index-CzA5zqGK.cjs";
13
13
  export { AGENT_AUDIT_SCHEMA_VERSION, AI_SDK_ATTR, AUTOTEL_ENRICHED_ATTR, type AgentActionFactory, type AgentActionMetadata, type AgentActionOptions, type AgentAiMetadata, type AgentAuditEventEnvelope, type AgentContext, type AgentDecisionMetadata, type AgentEndEvent, type AgentEventKind, type AgentHandler, type AgentIdentity, type AgentIdentityRecord, type AgentIdentityRegistry, type AgentIdentityStatus, type AgentMetadataInput, type AgentOutcome, type AgentSessionActionMetadata, type AgentSessionMetadata, type AgentSessionStatus, type AgentStartEvent, type AgentToolCallActionMetadata, type AgentToolCallOptions, type AiLifecycleStage, type AiSdkEnrichContext, type AiSdkResult, type AiSdkSpanType, type AiSdkStep, type AiSdkToolCall, type AiSdkToolResult, type AiSdkUsage, type AutotelEnrichOptions, type AutotelTelemetryIntegration, type AutotelTelemetryOptions, CONTEXT_LIMITS, type ChatEndEvent, type ChatStartEvent, type ChatStreamTiming, type ChunkIntervalStats, type ComputeStreamTimingInput, type ContentCaptureSettings, type ConvertedPrompt, type CreateSignedEventEnvelopeOptions, type DelegateToAgentInput, type DelegationContext, type EstimateCostOptions, type EvaluationResultEvent, GEN_AI, GEN_AI_COST_ATTRIBUTE, GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_EVENT, GEN_AI_EXT_EVENT, GEN_AI_GUARD_EVENT, GEN_AI_METRIC, GEN_AI_OPERATION, GEN_AI_OUTPUT_TYPE, GEN_AI_PROVIDER, GEN_AI_TOKEN_TYPE, GEN_AI_TOKEN_USAGE_BUCKETS, GEN_AI_TOOL_TYPE, type GenAiAgentInput, type GenAiAttributeKey, type GenAiAttributeMap, type GenAiBudgetOptions, type GenAiContentSink, type GenAiGuard, type GenAiGuardOptions, type GenAiGuardRule, type GenAiGuardStep, type GenAiHistogramKind, type GenAiMemoryInput, type GenAiMessage, type GenAiMessagePart, type GenAiMetricInput, type GenAiObserver, type GenAiObserverEvent, type GenAiObserverOptions, type GenAiOperationExceptionEvent, type GenAiOperationName, type GenAiOutputType, type GenAiProviderName, type GenAiRequestInput, type GenAiResponseInput, type GenAiRetrievalInput, type GenAiTokenType, type GenAiToolIdentity, type GenAiToolInput, type GenAiToolType, type GenAiUsageInput, type GenAiWarning, type GenAiWorkflowInput, type GovernanceMetadata, type GuardAction, type GuardSink, type GuardState, type GuardStopBehavior, type GuardUsage, type GuardViolation, type HashPayloadOptions, type InferenceDetailsEvent, type LangChainObserverHandler, type LangChainObserverOptions, MODEL_PRICING, type ModelPricing, type ObserveAiSdkOptions, type PolicyDecision, type PolicyMetadata, type PrivacyProfile, type PrivacyProfileInput, type PrivacyProfileName, type ProvisionAgentIdentityInput, type RecordAgentHandoffMetadata, type RevokeAgentIdentityInput, type RotateAgentIdentityInput, type ScopedToolDefinition, type SpanEnd, SpanRegistry, type SpanStart, type StreamTimer, type StreamTiming, type SubscribeAiTelemetryOptions, type TokenUsage, type ToolCallMetadata, type ToolEndEvent, type ToolStartEvent, type ToolStatus, type TraceGenAIConfig, type WorkflowEndEvent, type WorkflowStartEvent, autotelEnrich, autotelTelemetry, canonicalizeForHash, chunkIntervalStats, computeStreamTiming, contentToGenAiMessage, contextBudget, costCeiling, createAgentAuditMetadata, createAgentIdentityRegistry, createGenAiBudget, createGenAiGuard, createGenAiObserver, createLangChainObserver, createSignedEventEnvelope, createStreamTimer, defineAgentAction, defineAgentToolCall, delegateToAgent, errorLoop, estimateAiSdkCost, estimateLLMCost, extractAiSdkModel, extractAiSdkUsage, flattenAgentAttributes, genAiAgentAttributes, genAiMemoryAttributes, genAiMetricViews, genAiRequestAttributes, genAiResponseAttributes, genAiRetrievalAttributes, genAiSpanName, genAiToolAttributes, genAiUsageAttributes, genAiWorkflowAttributes, hashPayload, llmHistogramAdvice, mapAiSdkAttributes, maxDuration, maxSteps, maxToolCalls, normalizeAiSdkProvider, observeAiSdkResult, parseGuardRules, promptToGenAiMessages, recordAgentHandoff, recordAiSdkCost, recordDecisionBasis, recordEvaluationResult, recordGenAiMetrics, recordGenAiResponse, recordGenAiUsage, recordInferenceDetails, recordLLMCost, recordModelWarnings, recordOperationException, recordPolicyDecision, recordStreamTiming, resetGenAiInstruments, resolvePrivacyProfile, sanitizeAuditPayload, setAgentAttributes, setGenAiContent, spinLoop, subscribeAiTelemetry, tokenCeiling, traceGenAI, traceLLM, verifyEventEnvelopeHash, withAgentAction, withAgentSession, withAgentToolCall, withScopedTool };
package/dist/index.d.ts CHANGED
@@ -9,5 +9,5 @@ import { CONTEXT_LIMITS, GenAiBudgetOptions, GenAiGuard, GenAiGuardOptions, GenA
9
9
  import { GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_TOKEN_USAGE_BUCKETS, GenAiHistogramKind, GenAiMetricInput, genAiMetricViews, llmHistogramAdvice, recordGenAiMetrics, resetGenAiInstruments } from "./metrics.js";
10
10
  import { ChunkIntervalStats, ComputeStreamTimingInput, StreamTimer, StreamTiming, chunkIntervalStats, computeStreamTiming, createStreamTimer, recordStreamTiming } from "./streaming.js";
11
11
  import { TraceGenAIConfig, recordGenAiResponse, recordGenAiUsage, traceGenAI, traceLLM } from "./trace.js";
12
- import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, o as LangChainObserverHandler, p as autotelTelemetry, s as LangChainObserverOptions, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "./index-C-Ovf1nB.js";
12
+ import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, o as LangChainObserverHandler, p as autotelTelemetry, s as LangChainObserverOptions, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "./index-ZYigQnta.js";
13
13
  export { AGENT_AUDIT_SCHEMA_VERSION, AI_SDK_ATTR, AUTOTEL_ENRICHED_ATTR, type AgentActionFactory, type AgentActionMetadata, type AgentActionOptions, type AgentAiMetadata, type AgentAuditEventEnvelope, type AgentContext, type AgentDecisionMetadata, type AgentEndEvent, type AgentEventKind, type AgentHandler, type AgentIdentity, type AgentIdentityRecord, type AgentIdentityRegistry, type AgentIdentityStatus, type AgentMetadataInput, type AgentOutcome, type AgentSessionActionMetadata, type AgentSessionMetadata, type AgentSessionStatus, type AgentStartEvent, type AgentToolCallActionMetadata, type AgentToolCallOptions, type AiLifecycleStage, type AiSdkEnrichContext, type AiSdkResult, type AiSdkSpanType, type AiSdkStep, type AiSdkToolCall, type AiSdkToolResult, type AiSdkUsage, type AutotelEnrichOptions, type AutotelTelemetryIntegration, type AutotelTelemetryOptions, CONTEXT_LIMITS, type ChatEndEvent, type ChatStartEvent, type ChatStreamTiming, type ChunkIntervalStats, type ComputeStreamTimingInput, type ContentCaptureSettings, type ConvertedPrompt, type CreateSignedEventEnvelopeOptions, type DelegateToAgentInput, type DelegationContext, type EstimateCostOptions, type EvaluationResultEvent, GEN_AI, GEN_AI_COST_ATTRIBUTE, GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_EVENT, GEN_AI_EXT_EVENT, GEN_AI_GUARD_EVENT, GEN_AI_METRIC, GEN_AI_OPERATION, GEN_AI_OUTPUT_TYPE, GEN_AI_PROVIDER, GEN_AI_TOKEN_TYPE, GEN_AI_TOKEN_USAGE_BUCKETS, GEN_AI_TOOL_TYPE, type GenAiAgentInput, type GenAiAttributeKey, type GenAiAttributeMap, type GenAiBudgetOptions, type GenAiContentSink, type GenAiGuard, type GenAiGuardOptions, type GenAiGuardRule, type GenAiGuardStep, type GenAiHistogramKind, type GenAiMemoryInput, type GenAiMessage, type GenAiMessagePart, type GenAiMetricInput, type GenAiObserver, type GenAiObserverEvent, type GenAiObserverOptions, type GenAiOperationExceptionEvent, type GenAiOperationName, type GenAiOutputType, type GenAiProviderName, type GenAiRequestInput, type GenAiResponseInput, type GenAiRetrievalInput, type GenAiTokenType, type GenAiToolIdentity, type GenAiToolInput, type GenAiToolType, type GenAiUsageInput, type GenAiWarning, type GenAiWorkflowInput, type GovernanceMetadata, type GuardAction, type GuardSink, type GuardState, type GuardStopBehavior, type GuardUsage, type GuardViolation, type HashPayloadOptions, type InferenceDetailsEvent, type LangChainObserverHandler, type LangChainObserverOptions, MODEL_PRICING, type ModelPricing, type ObserveAiSdkOptions, type PolicyDecision, type PolicyMetadata, type PrivacyProfile, type PrivacyProfileInput, type PrivacyProfileName, type ProvisionAgentIdentityInput, type RecordAgentHandoffMetadata, type RevokeAgentIdentityInput, type RotateAgentIdentityInput, type ScopedToolDefinition, type SpanEnd, SpanRegistry, type SpanStart, type StreamTimer, type StreamTiming, type SubscribeAiTelemetryOptions, type TokenUsage, type ToolCallMetadata, type ToolEndEvent, type ToolStartEvent, type ToolStatus, type TraceGenAIConfig, type WorkflowEndEvent, type WorkflowStartEvent, autotelEnrich, autotelTelemetry, canonicalizeForHash, chunkIntervalStats, computeStreamTiming, contentToGenAiMessage, contextBudget, costCeiling, createAgentAuditMetadata, createAgentIdentityRegistry, createGenAiBudget, createGenAiGuard, createGenAiObserver, createLangChainObserver, createSignedEventEnvelope, createStreamTimer, defineAgentAction, defineAgentToolCall, delegateToAgent, errorLoop, estimateAiSdkCost, estimateLLMCost, extractAiSdkModel, extractAiSdkUsage, flattenAgentAttributes, genAiAgentAttributes, genAiMemoryAttributes, genAiMetricViews, genAiRequestAttributes, genAiResponseAttributes, genAiRetrievalAttributes, genAiSpanName, genAiToolAttributes, genAiUsageAttributes, genAiWorkflowAttributes, hashPayload, llmHistogramAdvice, mapAiSdkAttributes, maxDuration, maxSteps, maxToolCalls, normalizeAiSdkProvider, observeAiSdkResult, parseGuardRules, promptToGenAiMessages, recordAgentHandoff, recordAiSdkCost, recordDecisionBasis, recordEvaluationResult, recordGenAiMetrics, recordGenAiResponse, recordGenAiUsage, recordInferenceDetails, recordLLMCost, recordModelWarnings, recordOperationException, recordPolicyDecision, recordStreamTiming, resetGenAiInstruments, resolvePrivacyProfile, sanitizeAuditPayload, setAgentAttributes, setGenAiContent, spinLoop, subscribeAiTelemetry, tokenCeiling, traceGenAI, traceLLM, verifyEventEnvelopeHash, withAgentAction, withAgentSession, withAgentToolCall, withScopedTool };
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { chunkIntervalStats, computeStreamTiming, createStreamTimer, recordStrea
7
7
  import { recordGenAiResponse, recordGenAiUsage, traceGenAI, traceLLM } from "./trace.js";
8
8
  import { CONTEXT_LIMITS, contextBudget, costCeiling, createGenAiBudget, createGenAiGuard, errorLoop, maxDuration, maxSteps, maxToolCalls, parseGuardRules, spinLoop, tokenCeiling } from "./guard.js";
9
9
  import { AI_SDK_ATTR, AUTOTEL_ENRICHED_ATTR, autotelEnrich, estimateAiSdkCost, extractAiSdkModel, extractAiSdkUsage, mapAiSdkAttributes, normalizeAiSdkProvider, recordAiSdkCost } from "./ai-sdk-bridge.js";
10
- import { a as contentToGenAiMessage, c as createGenAiObserver, i as autotelTelemetry, l as SpanRegistry, n as createLangChainObserver, o as promptToGenAiMessages, r as subscribeAiTelemetry, s as observeAiSdkResult } from "./observer-JHxvq8sM.js";
10
+ import { a as contentToGenAiMessage, c as createGenAiObserver, i as autotelTelemetry, l as SpanRegistry, n as createLangChainObserver, o as promptToGenAiMessages, r as subscribeAiTelemetry, s as observeAiSdkResult } from "./observer-CZWloojM.js";
11
11
  import { A as createAgentAuditMetadata, C as defineAgentToolCall, D as withAgentToolCall, E as withAgentAction, M as hashPayload, N as AGENT_AUDIT_SCHEMA_VERSION, O as flattenAgentAttributes, S as defineAgentAction, T as recordPolicyDecision, _ as sanitizeAuditPayload, b as delegateToAgent, g as resolvePrivacyProfile, h as verifyEventEnvelopeHash, j as canonicalizeForHash, k as setAgentAttributes, m as createSignedEventEnvelope, p as withScopedTool, v as createAgentIdentityRegistry, w as recordDecisionBasis, x as recordAgentHandoff, y as withAgentSession } from "./agent-DYs6JLN5.js";
12
12
 
13
13
  export { AGENT_AUDIT_SCHEMA_VERSION, AI_SDK_ATTR, AUTOTEL_ENRICHED_ATTR, CONTEXT_LIMITS, GEN_AI, GEN_AI_COST_ATTRIBUTE, GEN_AI_COST_USD_BUCKETS, GEN_AI_DURATION_BUCKETS_SECONDS, GEN_AI_EVENT, GEN_AI_EXT_EVENT, GEN_AI_GUARD_EVENT, GEN_AI_METRIC, GEN_AI_OPERATION, GEN_AI_OUTPUT_TYPE, GEN_AI_PROVIDER, GEN_AI_TOKEN_TYPE, GEN_AI_TOKEN_USAGE_BUCKETS, GEN_AI_TOOL_TYPE, MODEL_PRICING, SpanRegistry, autotelEnrich, autotelTelemetry, canonicalizeForHash, chunkIntervalStats, computeStreamTiming, contentToGenAiMessage, contextBudget, costCeiling, createAgentAuditMetadata, createAgentIdentityRegistry, createGenAiBudget, createGenAiGuard, createGenAiObserver, createLangChainObserver, createSignedEventEnvelope, createStreamTimer, defineAgentAction, defineAgentToolCall, delegateToAgent, errorLoop, estimateAiSdkCost, estimateLLMCost, extractAiSdkModel, extractAiSdkUsage, flattenAgentAttributes, genAiAgentAttributes, genAiMemoryAttributes, genAiMetricViews, genAiRequestAttributes, genAiResponseAttributes, genAiRetrievalAttributes, genAiSpanName, genAiToolAttributes, genAiUsageAttributes, genAiWorkflowAttributes, hashPayload, llmHistogramAdvice, mapAiSdkAttributes, maxDuration, maxSteps, maxToolCalls, normalizeAiSdkProvider, observeAiSdkResult, parseGuardRules, promptToGenAiMessages, recordAgentHandoff, recordAiSdkCost, recordDecisionBasis, recordEvaluationResult, recordGenAiMetrics, recordGenAiResponse, recordGenAiUsage, recordInferenceDetails, recordLLMCost, recordModelWarnings, recordOperationException, recordPolicyDecision, recordStreamTiming, resetGenAiInstruments, resolvePrivacyProfile, sanitizeAuditPayload, setAgentAttributes, setGenAiContent, spinLoop, subscribeAiTelemetry, tokenCeiling, traceGenAI, traceLLM, verifyEventEnvelopeHash, withAgentAction, withAgentSession, withAgentToolCall, withScopedTool };
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_observer = require('../observer-Cic24A8t.cjs');
2
+ const require_observer = require('../observer-DdR8r0Ht.cjs');
3
3
 
4
4
  exports.SpanRegistry = require_observer.SpanRegistry;
5
5
  exports.autotelTelemetry = require_observer.autotelTelemetry;
@@ -1,2 +1,2 @@
1
- import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, a as createMastraObserver, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, i as MastraTracingEvent, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, n as MastraObserverExporter, o as LangChainObserverHandler, p as autotelTelemetry, r as MastraObserverOptions, s as LangChainObserverOptions, t as MastraExportedSpan, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "../index-Ii-vG7B4.cjs";
1
+ import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, a as createMastraObserver, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, i as MastraTracingEvent, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, n as MastraObserverExporter, o as LangChainObserverHandler, p as autotelTelemetry, r as MastraObserverOptions, s as LangChainObserverOptions, t as MastraExportedSpan, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "../index-CzA5zqGK.cjs";
2
2
  export { type AgentEndEvent, type AgentStartEvent, type AiSdkResult, type AiSdkStep, type AiSdkToolCall, type AiSdkToolResult, type AiSdkUsage, type AutotelTelemetryIntegration, type AutotelTelemetryOptions, type ChatEndEvent, type ChatStartEvent, type ChatStreamTiming, type ConvertedPrompt, type GenAiObserver, type GenAiObserverEvent, type GenAiObserverOptions, type GenAiToolIdentity, type LangChainObserverHandler, type LangChainObserverOptions, type MastraExportedSpan, type MastraObserverExporter, type MastraObserverOptions, type MastraTracingEvent, type ObserveAiSdkOptions, type SpanEnd, SpanRegistry, type SpanStart, type SubscribeAiTelemetryOptions, type ToolEndEvent, type ToolStartEvent, type WorkflowEndEvent, type WorkflowStartEvent, autotelTelemetry, contentToGenAiMessage, createGenAiObserver, createLangChainObserver, createMastraObserver, observeAiSdkResult, promptToGenAiMessages, subscribeAiTelemetry };
@@ -1,2 +1,2 @@
1
- import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, a as createMastraObserver, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, i as MastraTracingEvent, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, n as MastraObserverExporter, o as LangChainObserverHandler, p as autotelTelemetry, r as MastraObserverOptions, s as LangChainObserverOptions, t as MastraExportedSpan, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "../index-C-Ovf1nB.js";
1
+ import { A as ChatStreamTiming, B as WorkflowStartEvent, C as observeAiSdkResult, D as AgentStartEvent, E as AgentEndEvent, F as SpanEnd, I as SpanStart, L as ToolEndEvent, M as GenAiObserverEvent, N as GenAiObserverOptions, O as ChatEndEvent, P as GenAiToolIdentity, R as ToolStartEvent, S as ObserveAiSdkOptions, T as createGenAiObserver, _ as AiSdkResult, a as createMastraObserver, b as AiSdkToolResult, c as createLangChainObserver, d as AutotelTelemetryIntegration, f as AutotelTelemetryOptions, g as promptToGenAiMessages, h as contentToGenAiMessage, i as MastraTracingEvent, j as GenAiObserver, k as ChatStartEvent, l as SubscribeAiTelemetryOptions, m as ConvertedPrompt, n as MastraObserverExporter, o as LangChainObserverHandler, p as autotelTelemetry, r as MastraObserverOptions, s as LangChainObserverOptions, t as MastraExportedSpan, u as subscribeAiTelemetry, v as AiSdkStep, w as SpanRegistry, x as AiSdkUsage, y as AiSdkToolCall, z as WorkflowEndEvent } from "../index-ZYigQnta.js";
2
2
  export { type AgentEndEvent, type AgentStartEvent, type AiSdkResult, type AiSdkStep, type AiSdkToolCall, type AiSdkToolResult, type AiSdkUsage, type AutotelTelemetryIntegration, type AutotelTelemetryOptions, type ChatEndEvent, type ChatStartEvent, type ChatStreamTiming, type ConvertedPrompt, type GenAiObserver, type GenAiObserverEvent, type GenAiObserverOptions, type GenAiToolIdentity, type LangChainObserverHandler, type LangChainObserverOptions, type MastraExportedSpan, type MastraObserverExporter, type MastraObserverOptions, type MastraTracingEvent, type ObserveAiSdkOptions, type SpanEnd, SpanRegistry, type SpanStart, type SubscribeAiTelemetryOptions, type ToolEndEvent, type ToolStartEvent, type WorkflowEndEvent, type WorkflowStartEvent, autotelTelemetry, contentToGenAiMessage, createGenAiObserver, createLangChainObserver, createMastraObserver, observeAiSdkResult, promptToGenAiMessages, subscribeAiTelemetry };
@@ -1,3 +1,3 @@
1
- import { a as contentToGenAiMessage, c as createGenAiObserver, i as autotelTelemetry, l as SpanRegistry, n as createLangChainObserver, o as promptToGenAiMessages, r as subscribeAiTelemetry, s as observeAiSdkResult, t as createMastraObserver } from "../observer-JHxvq8sM.js";
1
+ import { a as contentToGenAiMessage, c as createGenAiObserver, i as autotelTelemetry, l as SpanRegistry, n as createLangChainObserver, o as promptToGenAiMessages, r as subscribeAiTelemetry, s as observeAiSdkResult, t as createMastraObserver } from "../observer-CZWloojM.js";
2
2
 
3
3
  export { SpanRegistry, autotelTelemetry, contentToGenAiMessage, createGenAiObserver, createLangChainObserver, createMastraObserver, observeAiSdkResult, promptToGenAiMessages, subscribeAiTelemetry };
@@ -1,4 +1,4 @@
1
- import { GEN_AI, GEN_AI_OPERATION, GEN_AI_TOOL_TYPE, genAiSpanName } from "./semconv.js";
1
+ import { GEN_AI, GEN_AI_OPERATION, GEN_AI_OUTPUT_TYPE, GEN_AI_TOOL_TYPE, genAiSpanName } from "./semconv.js";
2
2
  import { estimateLLMCost } from "./cost.js";
3
3
  import { c as genAiWorkflowAttributes, i as genAiResponseAttributes, o as genAiToolAttributes, r as genAiRequestAttributes, s as genAiUsageAttributes, t as genAiAgentAttributes } from "./attributes-CVOD1BG1.js";
4
4
  import { i as asString, n as asNumber, o as nonEmptyString, r as asRecord, s as readProperty } from "./values-CLNajs9_.js";
@@ -556,9 +556,10 @@ function partToGenAi(part) {
556
556
  * `autotelTelemetry` — a Vercel AI SDK telemetry integration.
557
557
  *
558
558
  * Implements the AI SDK's `Telemetry` lifecycle interface (stable since ai v7)
559
- * so you register it once and every `generateText` / `streamText` / `embed`
560
- * call streams a canonical `gen_ai.*` span tree — live, as the operation runs,
561
- * not reconstructed after the fact:
559
+ * so you register it once and every `generateText` / `streamText` /
560
+ * `generateObject` / `streamObject` / `embed` call streams a canonical
561
+ * `gen_ai.*` span tree — live, as the operation runs, not reconstructed after
562
+ * the fact:
562
563
  *
563
564
  * ```ts
564
565
  * import { registerTelemetry } from 'ai';
@@ -587,8 +588,11 @@ function partToGenAi(part) {
587
588
  * is a superset of the fields read here), so `registerTelemetry(autotelTelemetry())`
588
589
  * type-checks without importing the interface.
589
590
  *
590
- * Scope: `generateText` / `streamText` (incl. tool loops and `output`) and
591
- * `embed` / `embedMany`. A tool's nested `generateText` and the provider's own
591
+ * Scope: `generateText` / `streamText` (incl. tool loops and `output`),
592
+ * `generateObject` / `streamObject`, and `embed` / `embedMany`. Embeddings
593
+ * open on `onEmbedStart` so duration is real. `userId` / `sessionId` on
594
+ * `runtimeContext` become `user.id` / `gen_ai.conversation.id`; leftover
595
+ * keys are dropped. A tool's nested `generateText` and the provider's own
592
596
  * HTTP spans parent correctly via the `executeTool` / `executeLanguageModelCall`
593
597
  * context runners. `rerank` has no canonical `gen_ai` operation in the v1.42.0
594
598
  * registry and is intentionally not mapped.
@@ -638,24 +642,95 @@ function autotelTelemetry(options = {}) {
638
642
  if (!span) return execute();
639
643
  return context.with(trace.setSpan(context.active(), span), execute);
640
644
  }
645
+ function applyRuntimeContext(state, runtimeContext) {
646
+ if (!runtimeContext) return;
647
+ const userId = readContextId(runtimeContext.userId);
648
+ const conversationId = readContextId(runtimeContext.sessionId);
649
+ if (userId !== undefined) state.userId = userId;
650
+ if (conversationId !== undefined) state.conversationId = conversationId;
651
+ }
652
+ function stampIdentity(id, state) {
653
+ if (!state) return;
654
+ const span = spans.get(id);
655
+ if (!span) return;
656
+ if (state.userId !== undefined) span.setAttribute("user.id", state.userId);
657
+ if (state.conversationId !== undefined) {
658
+ span.setAttribute(GEN_AI.CONVERSATION_ID, state.conversationId);
659
+ }
660
+ }
661
+ /**
662
+ * The AI SDK reports an embedding attempt that succeeded and says nothing
663
+ * about one that threw — the retry just starts a new attempt. A span still
664
+ * open when the call is over therefore never completed, whatever ended the
665
+ * call, so closing it clean turns an abandoned attempt into a healthy span
666
+ * as long as everything that followed it.
667
+ */
668
+ const ABANDONED_EMBED = "embedding attempt did not complete";
669
+ /**
670
+ * Duration here is an upper bound, not a measurement.
671
+ *
672
+ * Nothing says when an abandoned attempt stopped running, and for a parallel
673
+ * operation nothing says which later attempt replaced it — a second batch
674
+ * starting looks exactly like a retry starting. Guessing "the next start"
675
+ * truncates a real concurrent batch to the moment an unrelated one began,
676
+ * which reads as a fast failure and is worse than an honest overestimate.
677
+ * The ERROR status is what marks these spans as unusable for latency.
678
+ */
679
+ function closeOpenEmbeds(state, error) {
680
+ for (const id of state.openEmbed) {
681
+ observe({
682
+ type: "chat.end",
683
+ id,
684
+ error: error ?? ABANDONED_EMBED
685
+ });
686
+ spans.delete(id);
687
+ }
688
+ state.openEmbed = [];
689
+ }
690
+ /**
691
+ * Close the attempt a retry has just replaced.
692
+ *
693
+ * Waiting until the call ends would stretch the failed attempt's duration
694
+ * across the backoff and every later attempt, which is the opposite of the
695
+ * real model-call duration these spans are for. The next attempt starting is
696
+ * the tightest upper bound the SDK gives us.
697
+ */
698
+ function failPreviousEmbedAttempt(state, startingId) {
699
+ state.openEmbed = state.openEmbed.filter((id) => {
700
+ const isRetry = id === startingId || !state.parallelEmbeds;
701
+ if (!isRetry) return true;
702
+ observe({
703
+ type: "chat.end",
704
+ id,
705
+ error: ABANDONED_EMBED
706
+ });
707
+ spans.delete(id);
708
+ return false;
709
+ });
710
+ }
641
711
  return {
642
712
  onStart(event) {
643
- if (isNonAgentOperation(event.operationId)) return;
713
+ const hasAgent = !isNonAgentOperation(event.operationId);
644
714
  const state = {
645
- hasAgent: true,
715
+ hasAgent,
646
716
  stream: event.operationId?.includes("stream"),
717
+ parallelEmbeds: event.operationId?.includes("embedMany"),
647
718
  openLm: [],
648
719
  lmSeq: 0,
649
720
  anonymousToolIds: [],
650
- toolSeq: 0
721
+ toolSeq: 0,
722
+ openEmbed: []
651
723
  };
652
724
  calls.set(event.callId, state);
725
+ applyRuntimeContext(state, event.runtimeContext);
726
+ if (!hasAgent) return;
653
727
  observe({
654
728
  type: "agent.start",
655
729
  id: event.callId,
656
730
  provider: normalizeProvider(event.provider),
657
731
  agent: { name: event.functionId ?? event.modelId ?? AI_SDK_AGENT_NAME$1 }
658
732
  });
733
+ stampIdentity(event.callId, state);
659
734
  },
660
735
  onLanguageModelCallStart(event) {
661
736
  const state = calls.get(event.callId);
@@ -668,11 +743,13 @@ function autotelTelemetry(options = {}) {
668
743
  parentId: state?.hasAgent ? event.callId : undefined,
669
744
  request: {
670
745
  ...toChatRequest(event),
671
- stream: state?.stream
746
+ stream: state?.stream,
747
+ conversationId: state?.conversationId
672
748
  },
673
749
  inputMessages: content?.messages,
674
750
  systemInstructions: content?.systemInstructions
675
751
  });
752
+ stampIdentity(id, state);
676
753
  },
677
754
  onLanguageModelCallEnd(event) {
678
755
  const state = calls.get(event.callId);
@@ -721,8 +798,51 @@ function autotelTelemetry(options = {}) {
721
798
  });
722
799
  spans.delete(id);
723
800
  },
724
- onEmbedEnd(event) {
725
- const id = `${event.callId}:embed:${event.embedCallId ?? "0"}`;
801
+ onObjectStepStart(event) {
802
+ const state = calls.get(event.callId);
803
+ const id = `${event.callId}:object`;
804
+ observe({
805
+ type: "chat.start",
806
+ id,
807
+ parentId: state?.hasAgent ? event.callId : undefined,
808
+ request: {
809
+ operation: GEN_AI_OPERATION.CHAT,
810
+ provider: normalizeProvider(event.provider),
811
+ model: event.modelId,
812
+ outputType: GEN_AI_OUTPUT_TYPE.JSON,
813
+ conversationId: state?.conversationId
814
+ }
815
+ });
816
+ stampIdentity(id, state);
817
+ },
818
+ onObjectStepEnd(event) {
819
+ const id = `${event.callId}:object`;
820
+ const outputMessage = captureContent && event.recordOutputs !== false && event.objectText !== undefined ? contentToGenAiMessage([{
821
+ type: "text",
822
+ text: event.objectText
823
+ }], event.finishReason) : undefined;
824
+ observe({
825
+ type: "chat.end",
826
+ id,
827
+ response: {
828
+ model: event.response?.modelId,
829
+ id: event.response?.id,
830
+ finishReasons: event.finishReason ? [event.finishReason] : undefined,
831
+ timeToFirstChunk: msToSeconds(event.msToFirstChunk)
832
+ },
833
+ usage: toTokenUsage(event.usage),
834
+ costModel: event.response?.modelId,
835
+ outputMessages: outputMessage ? [outputMessage] : undefined
836
+ });
837
+ spans.delete(id);
838
+ },
839
+ onEmbedStart(event) {
840
+ const id = embedSpanId(event);
841
+ const state = calls.get(event.callId);
842
+ if (state) {
843
+ failPreviousEmbedAttempt(state, id);
844
+ state.openEmbed.push(id);
845
+ }
726
846
  observe({
727
847
  type: "chat.start",
728
848
  id,
@@ -732,6 +852,25 @@ function autotelTelemetry(options = {}) {
732
852
  model: event.modelId
733
853
  }
734
854
  });
855
+ },
856
+ onEmbedEnd(event) {
857
+ const id = embedSpanId(event);
858
+ const state = calls.get(event.callId);
859
+ if (state) {
860
+ const index = state.openEmbed.indexOf(id);
861
+ if (index !== -1) state.openEmbed.splice(index, 1);
862
+ }
863
+ if (!spans.has(id)) {
864
+ observe({
865
+ type: "chat.start",
866
+ id,
867
+ request: {
868
+ operation: GEN_AI_OPERATION.EMBEDDINGS,
869
+ provider: normalizeProvider(event.provider),
870
+ model: event.modelId
871
+ }
872
+ });
873
+ }
735
874
  observe({
736
875
  type: "chat.end",
737
876
  id,
@@ -742,7 +881,11 @@ function autotelTelemetry(options = {}) {
742
881
  spans.delete(id);
743
882
  },
744
883
  onEnd(event) {
745
- if (!calls.delete(event.callId)) return;
884
+ const state = calls.get(event.callId);
885
+ if (!state) return;
886
+ calls.delete(event.callId);
887
+ closeOpenEmbeds(state);
888
+ if (!state.hasAgent) return;
746
889
  observe({
747
890
  type: "agent.end",
748
891
  id: event.callId
@@ -750,21 +893,32 @@ function autotelTelemetry(options = {}) {
750
893
  spans.delete(event.callId);
751
894
  },
752
895
  onAbort(event) {
753
- if (!calls.delete(event.callId)) return;
896
+ const state = calls.get(event.callId);
897
+ if (!state) return;
898
+ calls.delete(event.callId);
899
+ const error = event.reason ?? "aborted";
900
+ closeOpenEmbeds(state, error);
901
+ if (!state.hasAgent) return;
754
902
  observe({
755
903
  type: "agent.end",
756
904
  id: event.callId,
757
- error: event.reason ?? "aborted"
905
+ error
758
906
  });
759
907
  spans.delete(event.callId);
760
908
  },
761
909
  onError(event) {
762
910
  const callId = errorCallId(event);
763
- if (callId === undefined || !calls.delete(callId)) return;
911
+ if (callId === undefined) return;
912
+ const state = calls.get(callId);
913
+ if (!state) return;
914
+ calls.delete(callId);
915
+ const error = errorValue(event) ?? event;
916
+ closeOpenEmbeds(state, error);
917
+ if (!state.hasAgent) return;
764
918
  observe({
765
919
  type: "agent.end",
766
920
  id: callId,
767
- error: errorValue(event) ?? event
921
+ error
768
922
  });
769
923
  spans.delete(callId);
770
924
  },
@@ -779,6 +933,16 @@ function autotelTelemetry(options = {}) {
779
933
  }
780
934
  };
781
935
  }
936
+ function readContextId(value) {
937
+ if (typeof value === "string" && value.length > 0) return value;
938
+ if (typeof value === "number" || typeof value === "bigint") {
939
+ return String(value);
940
+ }
941
+ return undefined;
942
+ }
943
+ function embedSpanId(event) {
944
+ return `${event.callId}:embed:${event.embedCallId ?? "0"}`;
945
+ }
782
946
  /** Operations that are not `invoke_agent` roots (embeddings, rerank). */
783
947
  function isNonAgentOperation(operationId) {
784
948
  if (!operationId) return false;
@@ -556,9 +556,10 @@ function partToGenAi(part) {
556
556
  * `autotelTelemetry` — a Vercel AI SDK telemetry integration.
557
557
  *
558
558
  * Implements the AI SDK's `Telemetry` lifecycle interface (stable since ai v7)
559
- * so you register it once and every `generateText` / `streamText` / `embed`
560
- * call streams a canonical `gen_ai.*` span tree — live, as the operation runs,
561
- * not reconstructed after the fact:
559
+ * so you register it once and every `generateText` / `streamText` /
560
+ * `generateObject` / `streamObject` / `embed` call streams a canonical
561
+ * `gen_ai.*` span tree — live, as the operation runs, not reconstructed after
562
+ * the fact:
562
563
  *
563
564
  * ```ts
564
565
  * import { registerTelemetry } from 'ai';
@@ -587,8 +588,11 @@ function partToGenAi(part) {
587
588
  * is a superset of the fields read here), so `registerTelemetry(autotelTelemetry())`
588
589
  * type-checks without importing the interface.
589
590
  *
590
- * Scope: `generateText` / `streamText` (incl. tool loops and `output`) and
591
- * `embed` / `embedMany`. A tool's nested `generateText` and the provider's own
591
+ * Scope: `generateText` / `streamText` (incl. tool loops and `output`),
592
+ * `generateObject` / `streamObject`, and `embed` / `embedMany`. Embeddings
593
+ * open on `onEmbedStart` so duration is real. `userId` / `sessionId` on
594
+ * `runtimeContext` become `user.id` / `gen_ai.conversation.id`; leftover
595
+ * keys are dropped. A tool's nested `generateText` and the provider's own
592
596
  * HTTP spans parent correctly via the `executeTool` / `executeLanguageModelCall`
593
597
  * context runners. `rerank` has no canonical `gen_ai` operation in the v1.42.0
594
598
  * registry and is intentionally not mapped.
@@ -638,24 +642,95 @@ function autotelTelemetry(options = {}) {
638
642
  if (!span) return execute();
639
643
  return _opentelemetry_api.context.with(_opentelemetry_api.trace.setSpan(_opentelemetry_api.context.active(), span), execute);
640
644
  }
645
+ function applyRuntimeContext(state, runtimeContext) {
646
+ if (!runtimeContext) return;
647
+ const userId = readContextId(runtimeContext.userId);
648
+ const conversationId = readContextId(runtimeContext.sessionId);
649
+ if (userId !== undefined) state.userId = userId;
650
+ if (conversationId !== undefined) state.conversationId = conversationId;
651
+ }
652
+ function stampIdentity(id, state) {
653
+ if (!state) return;
654
+ const span = spans.get(id);
655
+ if (!span) return;
656
+ if (state.userId !== undefined) span.setAttribute("user.id", state.userId);
657
+ if (state.conversationId !== undefined) {
658
+ span.setAttribute(require_semconv.GEN_AI.CONVERSATION_ID, state.conversationId);
659
+ }
660
+ }
661
+ /**
662
+ * The AI SDK reports an embedding attempt that succeeded and says nothing
663
+ * about one that threw — the retry just starts a new attempt. A span still
664
+ * open when the call is over therefore never completed, whatever ended the
665
+ * call, so closing it clean turns an abandoned attempt into a healthy span
666
+ * as long as everything that followed it.
667
+ */
668
+ const ABANDONED_EMBED = "embedding attempt did not complete";
669
+ /**
670
+ * Duration here is an upper bound, not a measurement.
671
+ *
672
+ * Nothing says when an abandoned attempt stopped running, and for a parallel
673
+ * operation nothing says which later attempt replaced it — a second batch
674
+ * starting looks exactly like a retry starting. Guessing "the next start"
675
+ * truncates a real concurrent batch to the moment an unrelated one began,
676
+ * which reads as a fast failure and is worse than an honest overestimate.
677
+ * The ERROR status is what marks these spans as unusable for latency.
678
+ */
679
+ function closeOpenEmbeds(state, error) {
680
+ for (const id of state.openEmbed) {
681
+ observe({
682
+ type: "chat.end",
683
+ id,
684
+ error: error ?? ABANDONED_EMBED
685
+ });
686
+ spans.delete(id);
687
+ }
688
+ state.openEmbed = [];
689
+ }
690
+ /**
691
+ * Close the attempt a retry has just replaced.
692
+ *
693
+ * Waiting until the call ends would stretch the failed attempt's duration
694
+ * across the backoff and every later attempt, which is the opposite of the
695
+ * real model-call duration these spans are for. The next attempt starting is
696
+ * the tightest upper bound the SDK gives us.
697
+ */
698
+ function failPreviousEmbedAttempt(state, startingId) {
699
+ state.openEmbed = state.openEmbed.filter((id) => {
700
+ const isRetry = id === startingId || !state.parallelEmbeds;
701
+ if (!isRetry) return true;
702
+ observe({
703
+ type: "chat.end",
704
+ id,
705
+ error: ABANDONED_EMBED
706
+ });
707
+ spans.delete(id);
708
+ return false;
709
+ });
710
+ }
641
711
  return {
642
712
  onStart(event) {
643
- if (isNonAgentOperation(event.operationId)) return;
713
+ const hasAgent = !isNonAgentOperation(event.operationId);
644
714
  const state = {
645
- hasAgent: true,
715
+ hasAgent,
646
716
  stream: event.operationId?.includes("stream"),
717
+ parallelEmbeds: event.operationId?.includes("embedMany"),
647
718
  openLm: [],
648
719
  lmSeq: 0,
649
720
  anonymousToolIds: [],
650
- toolSeq: 0
721
+ toolSeq: 0,
722
+ openEmbed: []
651
723
  };
652
724
  calls.set(event.callId, state);
725
+ applyRuntimeContext(state, event.runtimeContext);
726
+ if (!hasAgent) return;
653
727
  observe({
654
728
  type: "agent.start",
655
729
  id: event.callId,
656
730
  provider: normalizeProvider(event.provider),
657
731
  agent: { name: event.functionId ?? event.modelId ?? AI_SDK_AGENT_NAME$1 }
658
732
  });
733
+ stampIdentity(event.callId, state);
659
734
  },
660
735
  onLanguageModelCallStart(event) {
661
736
  const state = calls.get(event.callId);
@@ -668,11 +743,13 @@ function autotelTelemetry(options = {}) {
668
743
  parentId: state?.hasAgent ? event.callId : undefined,
669
744
  request: {
670
745
  ...toChatRequest(event),
671
- stream: state?.stream
746
+ stream: state?.stream,
747
+ conversationId: state?.conversationId
672
748
  },
673
749
  inputMessages: content?.messages,
674
750
  systemInstructions: content?.systemInstructions
675
751
  });
752
+ stampIdentity(id, state);
676
753
  },
677
754
  onLanguageModelCallEnd(event) {
678
755
  const state = calls.get(event.callId);
@@ -721,8 +798,51 @@ function autotelTelemetry(options = {}) {
721
798
  });
722
799
  spans.delete(id);
723
800
  },
724
- onEmbedEnd(event) {
725
- const id = `${event.callId}:embed:${event.embedCallId ?? "0"}`;
801
+ onObjectStepStart(event) {
802
+ const state = calls.get(event.callId);
803
+ const id = `${event.callId}:object`;
804
+ observe({
805
+ type: "chat.start",
806
+ id,
807
+ parentId: state?.hasAgent ? event.callId : undefined,
808
+ request: {
809
+ operation: require_semconv.GEN_AI_OPERATION.CHAT,
810
+ provider: normalizeProvider(event.provider),
811
+ model: event.modelId,
812
+ outputType: require_semconv.GEN_AI_OUTPUT_TYPE.JSON,
813
+ conversationId: state?.conversationId
814
+ }
815
+ });
816
+ stampIdentity(id, state);
817
+ },
818
+ onObjectStepEnd(event) {
819
+ const id = `${event.callId}:object`;
820
+ const outputMessage = captureContent && event.recordOutputs !== false && event.objectText !== undefined ? contentToGenAiMessage([{
821
+ type: "text",
822
+ text: event.objectText
823
+ }], event.finishReason) : undefined;
824
+ observe({
825
+ type: "chat.end",
826
+ id,
827
+ response: {
828
+ model: event.response?.modelId,
829
+ id: event.response?.id,
830
+ finishReasons: event.finishReason ? [event.finishReason] : undefined,
831
+ timeToFirstChunk: msToSeconds(event.msToFirstChunk)
832
+ },
833
+ usage: toTokenUsage(event.usage),
834
+ costModel: event.response?.modelId,
835
+ outputMessages: outputMessage ? [outputMessage] : undefined
836
+ });
837
+ spans.delete(id);
838
+ },
839
+ onEmbedStart(event) {
840
+ const id = embedSpanId(event);
841
+ const state = calls.get(event.callId);
842
+ if (state) {
843
+ failPreviousEmbedAttempt(state, id);
844
+ state.openEmbed.push(id);
845
+ }
726
846
  observe({
727
847
  type: "chat.start",
728
848
  id,
@@ -732,6 +852,25 @@ function autotelTelemetry(options = {}) {
732
852
  model: event.modelId
733
853
  }
734
854
  });
855
+ },
856
+ onEmbedEnd(event) {
857
+ const id = embedSpanId(event);
858
+ const state = calls.get(event.callId);
859
+ if (state) {
860
+ const index = state.openEmbed.indexOf(id);
861
+ if (index !== -1) state.openEmbed.splice(index, 1);
862
+ }
863
+ if (!spans.has(id)) {
864
+ observe({
865
+ type: "chat.start",
866
+ id,
867
+ request: {
868
+ operation: require_semconv.GEN_AI_OPERATION.EMBEDDINGS,
869
+ provider: normalizeProvider(event.provider),
870
+ model: event.modelId
871
+ }
872
+ });
873
+ }
735
874
  observe({
736
875
  type: "chat.end",
737
876
  id,
@@ -742,7 +881,11 @@ function autotelTelemetry(options = {}) {
742
881
  spans.delete(id);
743
882
  },
744
883
  onEnd(event) {
745
- if (!calls.delete(event.callId)) return;
884
+ const state = calls.get(event.callId);
885
+ if (!state) return;
886
+ calls.delete(event.callId);
887
+ closeOpenEmbeds(state);
888
+ if (!state.hasAgent) return;
746
889
  observe({
747
890
  type: "agent.end",
748
891
  id: event.callId
@@ -750,21 +893,32 @@ function autotelTelemetry(options = {}) {
750
893
  spans.delete(event.callId);
751
894
  },
752
895
  onAbort(event) {
753
- if (!calls.delete(event.callId)) return;
896
+ const state = calls.get(event.callId);
897
+ if (!state) return;
898
+ calls.delete(event.callId);
899
+ const error = event.reason ?? "aborted";
900
+ closeOpenEmbeds(state, error);
901
+ if (!state.hasAgent) return;
754
902
  observe({
755
903
  type: "agent.end",
756
904
  id: event.callId,
757
- error: event.reason ?? "aborted"
905
+ error
758
906
  });
759
907
  spans.delete(event.callId);
760
908
  },
761
909
  onError(event) {
762
910
  const callId = errorCallId(event);
763
- if (callId === undefined || !calls.delete(callId)) return;
911
+ if (callId === undefined) return;
912
+ const state = calls.get(callId);
913
+ if (!state) return;
914
+ calls.delete(callId);
915
+ const error = errorValue(event) ?? event;
916
+ closeOpenEmbeds(state, error);
917
+ if (!state.hasAgent) return;
764
918
  observe({
765
919
  type: "agent.end",
766
920
  id: callId,
767
- error: errorValue(event) ?? event
921
+ error
768
922
  });
769
923
  spans.delete(callId);
770
924
  },
@@ -779,6 +933,16 @@ function autotelTelemetry(options = {}) {
779
933
  }
780
934
  };
781
935
  }
936
+ function readContextId(value) {
937
+ if (typeof value === "string" && value.length > 0) return value;
938
+ if (typeof value === "number" || typeof value === "bigint") {
939
+ return String(value);
940
+ }
941
+ return undefined;
942
+ }
943
+ function embedSpanId(event) {
944
+ return `${event.callId}:embed:${event.embedCallId ?? "0"}`;
945
+ }
782
946
  /** Operations that are not `invoke_agent` roots (embeddings, rerank). */
783
947
  function isNonAgentOperation(operationId) {
784
948
  if (!operationId) return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel-genai",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Gold-standard OpenTelemetry GenAI semantic-convention instrumentation for LLM calls, tools, and agents — cost, tokens, metrics, events, and agent governance.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -83,8 +83,8 @@
83
83
  "author": "Jag Reehal <jag@jagreehal.com> (https://jagreehal.com)",
84
84
  "license": "Apache-2.0",
85
85
  "dependencies": {
86
- "autotel": "7.0.0",
87
- "autotel-audit": "1.0.0"
86
+ "autotel": "7.0.1",
87
+ "autotel-audit": "1.0.1"
88
88
  },
89
89
  "peerDependencies": {
90
90
  "@opentelemetry/api": "*",