Share via


@microsoft/agents-a365-observability package

Classes

Agent365ExporterOptions

Maximum number of spans per export batch.

BaggageBuilder

Per request baggage builder for OpenTelemetry context propagation.

This class provides a fluent API for setting baggage values that will be propagated in the OpenTelemetry context.

Example

const scope = new BaggageBuilder()
  .tenantId("tenant-123")
  .agentId("agent-456")
  .build();

scope.enter();
// Baggage is set in this context
// ... do work ...
scope.exit();
// Baggage is restored after exiting the context
BaggageScope

Context manager for baggage scope.

This class manages the lifecycle of baggage values, setting them on enter and restoring the previous context on exit.

Builder

Builder for configuring Agent 365 with OpenTelemetry tracing

ExecuteToolScope

Provides OpenTelemetry tracing scope for AI tool execution operations.

InferenceScope

Provides OpenTelemetry tracing scope for generative AI inference operations.

InvokeAgentScope

Provides OpenTelemetry tracing scope for AI agent invocation operations.

ObservabilityConfiguration

Configuration for observability package. Inherits runtime settings and adds observability-specific settings.

ObservabilityManager

Main entry point for Agent 365 providing OpenTelemetry tracing for AI agents and tools

OpenTelemetryConstants

OpenTelemetry constants for Agent 365

OpenTelemetryScope

Base class for OpenTelemetry tracing scopes

OutputScope

Provides OpenTelemetry tracing scope for output message tracing with parent span linking.

PerRequestSpanProcessorConfiguration

Configuration for PerRequestSpanProcessor. Inherits runtime settings (clusterCategory, isNodeEnvDevelopment) and adds per-request processor guardrails.

This is separated from ObservabilityConfiguration because PerRequestSpanProcessor is used only in specific scenarios and these settings should not be exposed in the common ObservabilityConfiguration.

Interfaces

AgentDetails

Details about an AI agent

BlobPart

Inline binary data (base64-encoded).

BuilderOptions

Configuration options for Agent 365 Observability Builder

CallerDetails

Caller details for scope creation. Supports human callers, agent callers, or both (A2A with a human in the chain).

Migration note: In v1 the name CallerDetails referred to human caller identity (now UserDetails). In v2 it was repurposed as a wrapper that groups both human and agent caller information.

See UserDetails — human caller identity (previously CallerDetails) See CHANGELOG.md — breaking changes section for migration guidance

Channel

Represents channel for an invocation

ChatMessage

An input message sent to a model (OTEL gen-ai semantic conventions).

FilePart

Reference to a pre-uploaded file.

GenericPart

Extensible part for custom / future types.

GenericServerToolCall

Extensible server tool call details with a type discriminator.

GenericServerToolCallResponse

Extensible server tool call response with a type discriminator.

ILogger

Custom logger interface for Agent 365 observability Implement this interface to support logging backends

InferenceDetails

Details for an inference call

InferenceResponse

Details for recording the response from an inference call

InputMessages
InvokeAgentScopeDetails

Details for invoking agent scope.

OutputMessage

An output message produced by a model (OTEL gen-ai semantic conventions).

OutputMessages
OutputResponse

Represents a response containing output messages from an agent. Used with OutputScope for output message tracing. Accepts plain strings, structured OTEL OutputMessage objects, or a raw dict (treated as a tool call result per OTEL spec).

ParentSpanRef

Reference to a parent span for explicit parent-child linking across async boundaries. Used when automatic context propagation fails (e.g., WebSocket callbacks, external event handlers).

ReasoningPart

Model reasoning / chain-of-thought content.

Request

Represents a request with telemetry context. Used across all scope types for channel and conversation tracking.

ServerToolCallPart

Server-side tool invocation.

ServerToolCallResponsePart

Server-side tool response.

ServiceEndpoint

Represents an endpoint for agent invocation

SpanDetails

Span configuration details for scope creation. Groups OpenTelemetry span options into a single object so the scope method signature remains stable as new options are added.

TextPart

Plain text content.

ToolCallDetails

Details of a tool call made by an agent

ToolCallRequestPart

A tool call requested by the model.

ToolCallResponsePart

Result of a tool call.

UriPart

External URI reference.

UserDetails

Details about the human user caller.

Type Aliases

EnhancedAgentDetails
HeadersCarrier

Carrier type for HTTP headers used in trace context propagation. Compatible with Node.js IncomingHttpHeaders and plain string maps.

InputMessagesParam

Accepted input for recordInputMessages. Supports a single string, an array of strings (backward compat), or the versioned wrapper.

MessagePart

Union of all message part types per OTEL gen-ai semantic conventions.

Note: GenericPart acts as a catch-all for forward compatibility with custom or future part types. Because its type is string (not a literal), exhaustive switch/case on part.type will not produce compile-time errors for unhandled cases.

ObservabilityConfigurationOptions

Observability configuration options - extends runtime options. All overrides are functions called on each property access.

Inherited from RuntimeConfigurationOptions:

  • clusterCategory
  • isNodeEnvDevelopment

Note: isDevelopmentEnvironment is a derived getter on the configuration class (based on clusterCategory), not an overridable option.

OutputMessagesParam

Accepted input for recordOutputMessages. Supports a single string, an array of strings (backward compat), or the versioned wrapper.

ParentContext

A parent context for span creation. Accepts either:

PerRequestSpanProcessorConfigurationOptions

Configuration options for PerRequestSpanProcessor - extends runtime options. All overrides are functions called on each property access.

Inherited from RuntimeConfigurationOptions:

  • clusterCategory, isNodeEnvDevelopment
ResponseMessagesParam

Accepted input for OutputResponse.messages. Supports plain strings, structured OutputMessages, or a raw dict (treated as a tool call result per OTEL spec and serialized directly via JSON.stringify).

Enums

ExporterEventNames

Event names used by Agent365Exporter for logging and monitoring. These are low-cardinality event types to ensure efficient monitoring and aggregation.

FinishReason

Reason a model stopped generating per OTEL gen-ai semantic conventions.

InferenceOperationType

Represents different operation for types for model inference

InvocationRole

Represents different roles that can invoke an agent

MessageRole

Role of a message participant per OTEL gen-ai semantic conventions.

Modality

Media modality for blob, file, and URI parts.

Functions

createContextWithParentSpanRef(Context, ParentSpanRef)

Creates a new Context with an explicit parent span reference. This allows child spans to be correctly parented even when async context is broken.

extractContextFromHeaders(HeadersCarrier, Context)

Extracts trace context from incoming HTTP headers using the globally registered W3C propagator. Returns an OTel ParentContext that can be passed to scope classes as a ParentContext.

Example

const parentCtx = extractContextFromHeaders(req.headers);
const scope = InvokeAgentScope.start(request, scopeDetails, agentDetails, undefined, { parentContext: parentCtx });
formatError(unknown)

Format error object for logging with message and stack trace

getExportToken(Context)

Retrieve the per-request export token from a given OTel Context (or the active one).

getLogger()

Get the current logger instance

injectContextToHeaders(Record<string, string>, Context)

Injects the current trace context (traceparent/tracestate headers) into the provided headers object using the globally registered W3C propagator.

Example

const headers: Record<string, string> = {};
injectContextToHeaders(headers);
await fetch('http://service-b/process', { headers });
isPerRequestExportEnabled(IConfigurationProvider<PerRequestSpanProcessorConfiguration>)

Check if per-request export is enabled. Precedence: internal overrides > configuration provider > environment variable. When enabled, the PerRequestSpanProcessor is used instead of BatchSpanProcessor. The token is passed via OTel Context (async local storage) at export time.

normalizeInputMessages(InputMessagesParam)

Normalizes an InputMessagesParam to a versioned InputMessages wrapper.

  • string / string[] → converted to ChatMessage[] and wrapped
  • InputMessages → returned as-is
normalizeOutputMessages(OutputMessagesParam)

Normalizes an OutputMessagesParam to a versioned OutputMessages wrapper.

  • string / string[] → converted to OutputMessage[] and wrapped
  • OutputMessages → returned as-is
resetLogger()

Reset to the default console logger (mainly for testing)

runWithExportToken<T>(string, () => T)

Run a function within a Context that carries the per-request export token. This keeps the token only in OTel Context (ALS), never in any registry.

The token can be updated later via updateExportToken() before the trace is flushed — useful when the callback is long-running and the original token may expire before export.

runWithExtractedTraceContext<T>(HeadersCarrier, () => T)

Extracts trace context from incoming HTTP headers and runs the callback within that context. Any spans created inside the callback will be parented to the extracted trace.

Example

runWithExtractedTraceContext(req.headers, () => {
  const scope = InvokeAgentScope.start(request, scopeDetails, agentDetails);
  scope.dispose();
});
runWithParentSpanRef<T>(ParentSpanRef, () => T)

Runs a callback function within a context that has an explicit parent span reference. This is useful for creating child spans in async callbacks where context propagation is broken.

safeSerializeToJson(string | Record<string, unknown>, string)

Ensures the value is always a JSON-parseable string.

  • Objects are serialized via JSON.stringify.
  • Strings that are already valid JSON objects/arrays are passed through.
  • All other strings (including bare JSON primitives) are wrapped: { [key]: value }.
serializeMessages(InputMessages | OutputMessages)

Serializes a versioned message wrapper to JSON.

The output is the full wrapper object: {"version":"0.1.0","messages":[...]}.

The try/catch ensures telemetry recording is non-throwing even when message parts contain non-JSON-serializable values (e.g. BigInt, circular refs).

setLogger(ILogger)

Set a custom logger implementation for the observability SDK

Example with Winston:

import * as winston from 'winston';
import { setLogger } from '@microsoft/agents-a365-observability';

const winstonLogger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

setLogger({
  info: (msg, ...args) => winstonLogger.info(msg, ...args),
  warn: (msg, ...args) => winstonLogger.warn(msg, ...args),
  error: (msg, ...args) => winstonLogger.error(msg, ...args),
  event: (eventType, isSuccess, durationMs, message, details) => {
    // eventType is ExporterEventNames enum value
    winstonLogger.log({ level: isSuccess ? 'info' : 'error', eventType, isSuccess, durationMs, message, ...details });
  }
});
truncateValue(string)

Truncate a string value to MAX_ATTRIBUTE_LENGTH characters. If the value exceeds the limit, it is trimmed and a truncation suffix is appended, with the total length capped at exactly MAX_ATTRIBUTE_LENGTH.

updateExportToken(string)

Update the export token in the active OTel Context. Call this to refresh the token before ending the root span when the original token may have expired during a long-running request.

Must be called within the same async context created by runWithExportToken.

Variables

A365_MESSAGE_SCHEMA_VERSION
MAX_ATTRIBUTE_LENGTH

Maximum length for span attribute values. Values exceeding this limit will be truncated with a suffix.

defaultObservabilityConfigurationProvider

Shared default provider for ObservabilityConfiguration.

defaultPerRequestSpanProcessorConfigurationProvider

Shared default provider for PerRequestSpanProcessorConfiguration.

logger

Default logger instance for backward compatibility. Delegates to the global logger which can be replaced via setLogger().

Function Details

createContextWithParentSpanRef(Context, ParentSpanRef)

Creates a new Context with an explicit parent span reference. This allows child spans to be correctly parented even when async context is broken.

function createContextWithParentSpanRef(base: Context, parent: ParentSpanRef): Context

Parameters

base

Context

The base context to extend (typically context.active())

parent
ParentSpanRef

The parent span reference containing traceId and spanId

Returns

Context

A new Context with the parent span set

extractContextFromHeaders(HeadersCarrier, Context)

Extracts trace context from incoming HTTP headers using the globally registered W3C propagator. Returns an OTel ParentContext that can be passed to scope classes as a ParentContext.

Example

const parentCtx = extractContextFromHeaders(req.headers);
const scope = InvokeAgentScope.start(request, scopeDetails, agentDetails, undefined, { parentContext: parentCtx });
function extractContextFromHeaders(headers: HeadersCarrier, baseCtx?: Context): Context

Parameters

headers
HeadersCarrier

The incoming HTTP request headers containing traceparent/tracestate.

baseCtx

Context

Optional base context to extend. Defaults to the active context.

Returns

Context

An OTel Context containing the extracted trace information.

formatError(unknown)

Format error object for logging with message and stack trace

function formatError(error: unknown): string

Parameters

error

unknown

Returns

string

getExportToken(Context)

Retrieve the per-request export token from a given OTel Context (or the active one).

function getExportToken(ctx?: Context): string | undefined

Parameters

ctx

Context

Returns

string | undefined

getLogger()

Get the current logger instance

function getLogger(): ILogger

Returns

injectContextToHeaders(Record<string, string>, Context)

Injects the current trace context (traceparent/tracestate headers) into the provided headers object using the globally registered W3C propagator.

Example

const headers: Record<string, string> = {};
injectContextToHeaders(headers);
await fetch('http://service-b/process', { headers });
function injectContextToHeaders(headers: Record<string, string>, ctx?: Context): Record<string, string>

Parameters

headers

Record<string, string>

Mutable object where trace context headers will be written.

ctx

Context

Optional OTel Context to inject from. Defaults to the active context.

Returns

Record<string, string>

The same headers object, for chaining convenience.

isPerRequestExportEnabled(IConfigurationProvider<PerRequestSpanProcessorConfiguration>)

Check if per-request export is enabled. Precedence: internal overrides > configuration provider > environment variable. When enabled, the PerRequestSpanProcessor is used instead of BatchSpanProcessor. The token is passed via OTel Context (async local storage) at export time.

function isPerRequestExportEnabled(configProvider?: IConfigurationProvider<PerRequestSpanProcessorConfiguration>): boolean

Parameters

configProvider

IConfigurationProvider<PerRequestSpanProcessorConfiguration>

Optional configuration provider. Defaults to defaultPerRequestSpanProcessorConfigurationProvider if not specified.

Returns

boolean

normalizeInputMessages(InputMessagesParam)

Normalizes an InputMessagesParam to a versioned InputMessages wrapper.

  • string / string[] → converted to ChatMessage[] and wrapped
  • InputMessages → returned as-is
function normalizeInputMessages(param: InputMessagesParam): InputMessages

Parameters

Returns

normalizeOutputMessages(OutputMessagesParam)

Normalizes an OutputMessagesParam to a versioned OutputMessages wrapper.

  • string / string[] → converted to OutputMessage[] and wrapped
  • OutputMessages → returned as-is
function normalizeOutputMessages(param: OutputMessagesParam): OutputMessages

Parameters

Returns

resetLogger()

Reset to the default console logger (mainly for testing)

function resetLogger()

runWithExportToken<T>(string, () => T)

Run a function within a Context that carries the per-request export token. This keeps the token only in OTel Context (ALS), never in any registry.

The token can be updated later via updateExportToken() before the trace is flushed — useful when the callback is long-running and the original token may expire before export.

function runWithExportToken<T>(token: string, fn: () => T): T

Parameters

token

string

fn

() => T

Returns

T

runWithExtractedTraceContext<T>(HeadersCarrier, () => T)

Extracts trace context from incoming HTTP headers and runs the callback within that context. Any spans created inside the callback will be parented to the extracted trace.

Example

runWithExtractedTraceContext(req.headers, () => {
  const scope = InvokeAgentScope.start(request, scopeDetails, agentDetails);
  scope.dispose();
});
function runWithExtractedTraceContext<T>(headers: HeadersCarrier, callback: () => T): T

Parameters

headers
HeadersCarrier

The incoming HTTP request headers containing traceparent/tracestate.

callback

() => T

The function to execute within the extracted context.

Returns

T

The result of the callback.

runWithParentSpanRef<T>(ParentSpanRef, () => T)

Runs a callback function within a context that has an explicit parent span reference. This is useful for creating child spans in async callbacks where context propagation is broken.

function runWithParentSpanRef<T>(parent: ParentSpanRef, callback: () => T): T

Parameters

parent
ParentSpanRef

The parent span reference

callback

() => T

The function to execute with the parent context

Returns

T

The result of the callback

safeSerializeToJson(string | Record<string, unknown>, string)

Ensures the value is always a JSON-parseable string.

  • Objects are serialized via JSON.stringify.
  • Strings that are already valid JSON objects/arrays are passed through.
  • All other strings (including bare JSON primitives) are wrapped: { [key]: value }.
function safeSerializeToJson(value: string | Record<string, unknown>, key: string): string

Parameters

value

string | Record<string, unknown>

The value to serialize.

key

string

The key to use when wrapping a plain string.

Returns

string

serializeMessages(InputMessages | OutputMessages)

Serializes a versioned message wrapper to JSON.

The output is the full wrapper object: {"version":"0.1.0","messages":[...]}.

The try/catch ensures telemetry recording is non-throwing even when message parts contain non-JSON-serializable values (e.g. BigInt, circular refs).

function serializeMessages(wrapper: InputMessages | OutputMessages): string

Parameters

Returns

string

setLogger(ILogger)

Set a custom logger implementation for the observability SDK

Example with Winston:

import * as winston from 'winston';
import { setLogger } from '@microsoft/agents-a365-observability';

const winstonLogger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

setLogger({
  info: (msg, ...args) => winstonLogger.info(msg, ...args),
  warn: (msg, ...args) => winstonLogger.warn(msg, ...args),
  error: (msg, ...args) => winstonLogger.error(msg, ...args),
  event: (eventType, isSuccess, durationMs, message, details) => {
    // eventType is ExporterEventNames enum value
    winstonLogger.log({ level: isSuccess ? 'info' : 'error', eventType, isSuccess, durationMs, message, ...details });
  }
});
function setLogger(customLogger: ILogger)

Parameters

customLogger
ILogger

The custom logger implementation

truncateValue(string)

Truncate a string value to MAX_ATTRIBUTE_LENGTH characters. If the value exceeds the limit, it is trimmed and a truncation suffix is appended, with the total length capped at exactly MAX_ATTRIBUTE_LENGTH.

function truncateValue(value: string): string

Parameters

value

string

The string to truncate

Returns

string

The original string if within limits, otherwise the truncated string

updateExportToken(string)

Update the export token in the active OTel Context. Call this to refresh the token before ending the root span when the original token may have expired during a long-running request.

Must be called within the same async context created by runWithExportToken.

function updateExportToken(token: string): boolean

Parameters

token

string

The fresh token to use for export.

Returns

boolean

true if the token was updated successfully, false if no token holder was found.

Variable Details

A365_MESSAGE_SCHEMA_VERSION

A365_MESSAGE_SCHEMA_VERSION: "0.1.0"

Type

string

MAX_ATTRIBUTE_LENGTH

Maximum length for span attribute values. Values exceeding this limit will be truncated with a suffix.

MAX_ATTRIBUTE_LENGTH: 8192

Type

8192

defaultObservabilityConfigurationProvider

Shared default provider for ObservabilityConfiguration.

defaultObservabilityConfigurationProvider: DefaultConfigurationProvider<ObservabilityConfiguration>

Type

defaultPerRequestSpanProcessorConfigurationProvider

Shared default provider for PerRequestSpanProcessorConfiguration.

defaultPerRequestSpanProcessorConfigurationProvider: DefaultConfigurationProvider<PerRequestSpanProcessorConfiguration>

Type

logger

Default logger instance for backward compatibility. Delegates to the global logger which can be replaced via setLogger().

logger: ILogger

Type