Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7564849
Support new telemetry schema attribute names gated by A365_USE_NEW_TE…
jsl517 Feb 19, 2026
c79dd4f
Derive TELEMETRY_SDK_VERSION_VALUE from package.json version
jsl517 Feb 19, 2026
f3fdb15
Add isolated-module tests for caller attribute key schema mappings
jsl517 Feb 19, 2026
64c28a7
Add back gen_ai.caller.tenantid, add isolated schema tests for caller…
jsl517 Feb 19, 2026
00cd584
Remove GEN_AI_AGENT_USER_ID_KEY constant
jsl517 Feb 19, 2026
7781561
Fix telemetry schema property names to match Common Properties doc
jsl517 Feb 24, 2026
a083413
Remove gen_ai.response.id, rename gen_ai.event.content to gen_ai.tool…
jsl517 Feb 26, 2026
33c4e2d
Remove unused ServiceEndpoint import from InferenceScope
jsl517 Feb 26, 2026
8f648a6
Remove duplicate GEN_AI_EVENT_CONTENT constant, clarify .gitignore co…
jsl517 Feb 26, 2026
92172c9
Remove extra attributes and fix name mismatches per A365 schema
jsl517 Feb 26, 2026
9e9092c
Add agentBlueprintId to base OpenTelemetryScope (common across all sp…
jsl517 Feb 26, 2026
8dae2d1
Fix attribute type mismatches per A365 schema
jsl517 Feb 26, 2026
b76aaf7
Move gen_ai.provider.name from base scope to InvokeAgentScope, add pr…
jsl517 Mar 2, 2026
6f9e872
Revert pnpm-lock.yaml changes from previous commit
jsl517 Mar 2, 2026
a3c7ac0
Merge main into feature/new-telemetry-schema, resolve conflicts
jsl517 Mar 2, 2026
140dd15
Address Copilot review: fix copyright headers, move blueprint ID to g…
jsl517 Mar 2, 2026
121c0ef
Fix remaining review issues: pass callerDetails to OutputScope base, …
jsl517 Mar 2, 2026
c9588c9
Revert pre-existing issue fixes unrelated to this PR
jsl517 Mar 2, 2026
d7bf038
Rename BaggageBuilder sourceMetadataName/Description to channelName/c…
jsl517 Mar 2, 2026
1798f9b
Revert BaggageBuilder channelName/channelLink rename
jsl517 Mar 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class LangChainTracer extends BaseTracer {
const span = this.tracer.startSpan(spanName, {
kind: SpanKind.INTERNAL,
startTime,
attributes: { [OpenTelemetryConstants.GEN_AI_SYSTEM_KEY]: "langchain" },
attributes: { [OpenTelemetryConstants.GEN_AI_PROVIDER_NAME_KEY]: "langchain" },
}, activeContext);

this.runs[run.id] = { run, span, startTime, lastAccessTime: startTime };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export class OpenAIAgentsTraceProcessor implements TracingProcessor {
private readonly spanNames: Map<OtelSpan, string> = new Map();

private readonly keyMappings: Map<string, string> = new Map([
['mcp_tools' + Constants.GEN_AI_RESPONSE_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_EVENT_CONTENT],
['mcp_tools' + Constants.GEN_AI_RESPONSE_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_TOOL_CALL_RESULT_KEY],
['mcp_tools' + Constants.GEN_AI_REQUEST_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_TOOL_ARGS_KEY],
['function' + Constants.GEN_AI_RESPONSE_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_EVENT_CONTENT],
['function' + Constants.GEN_AI_RESPONSE_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_TOOL_CALL_RESULT_KEY],
['function' + Constants.GEN_AI_REQUEST_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_TOOL_ARGS_KEY],
['generation' + Constants.GEN_AI_RESPONSE_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_OUTPUT_MESSAGES_KEY],
['generation' + Constants.GEN_AI_REQUEST_CONTENT_KEY, OpenTelemetryConstants.GEN_AI_INPUT_MESSAGES_KEY],
Expand Down Expand Up @@ -117,7 +117,7 @@ export class OpenAIAgentsTraceProcessor implements TracingProcessor {
startTime,
attributes: {
[OpenTelemetryConstants.GEN_AI_OPERATION_NAME_KEY]: Utils.getSpanKind(spanData),
[OpenTelemetryConstants.GEN_AI_SYSTEM_KEY]: 'openai',
[OpenTelemetryConstants.GEN_AI_PROVIDER_NAME_KEY]: 'openai',
},
},
parentContext
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,6 @@ export function getAttributesFromGenerationSpanData(data: SpanData): Record<stri

if (genData.output) {
attributes[Constants.GEN_AI_RESPONSE_CONTENT_KEY] = safeJsonDumps(genData.output);
const output = genData.output as Record<string, unknown>;
if (output.id) {
attributes[OpenTelemetryConstants.GEN_AI_RESPONSE_ID_KEY] = output.id;
}
}

if (genData.usage) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ export class OutputLoggingMiddleware implements Middleware {
callerDetails,
conversationId,
sourceMetadata,
undefined,
parentSpanRef,
);
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function normalizePairs(pairs: Array<[string, string | undefined]>): Array<[stri
/**
* Extracts caller-related OpenTelemetry baggage pairs from the TurnContext.
* @param turnContext The current TurnContext (activity context)
* @returns Array of [key, value] pairs for caller identity and tenant
* @returns Array of [key, value] pairs for caller identity
*/
export function getCallerBaggagePairs(turnContext: TurnContext): Array<[string, string]> {
if (!turnContext|| !turnContext.activity?.from) {
Expand All @@ -33,7 +33,6 @@ export function getCallerBaggagePairs(turnContext: TurnContext): Array<[string,
[OpenTelemetryConstants.GEN_AI_CALLER_ID_KEY, from.aadObjectId],
[OpenTelemetryConstants.GEN_AI_CALLER_NAME_KEY, from.name],
[OpenTelemetryConstants.GEN_AI_CALLER_UPN_KEY, upn],
[OpenTelemetryConstants.GEN_AI_CALLER_TENANT_ID_KEY, from.tenantId],
[OpenTelemetryConstants.GEN_AI_AGENT_BLUEPRINT_ID_KEY, from.agenticAppBlueprintId]
];
Comment on lines 33 to 37
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function no longer includes a tenant ID baggage pair (the GEN_AI_CALLER_TENANT_ID_KEY entry was removed), but the JSDoc above still says it returns pairs for caller identity and tenant. Update the JSDoc to match, or re-add the tenant pair if it’s still required by the schema/back-end.

Copilot uses AI. Check for mistakes.
return normalizePairs(pairs);
Expand Down Expand Up @@ -124,8 +123,8 @@ export function getSourceMetadataBaggagePairs(turnContext: TurnContext): Array<[
return [];
}
const pairs: Array<[string, string | undefined]> = [
[OpenTelemetryConstants.GEN_AI_EXECUTION_SOURCE_NAME_KEY, turnContext.activity?.channelId],
[OpenTelemetryConstants.GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY, turnContext.activity?.channelIdSubChannel as string | undefined]
[OpenTelemetryConstants.CHANNEL_NAME_KEY, turnContext.activity?.channelId],
[OpenTelemetryConstants.CHANNEL_LINK_KEY, turnContext.activity?.channelIdSubChannel as string | undefined]
];
return normalizePairs(pairs);
}
Expand Down
2 changes: 2 additions & 0 deletions packages/agents-a365-observability/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# The file "src/version.ts" is generated by a prebuild script and should not be committed.
src/version.ts
1 change: 1 addition & 0 deletions packages/agents-a365-observability/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"module": "dist/esm/index.js",
"types": "dist/esm/index.d.ts",
"scripts": {
"prebuild": "node -p \"'export const LIB_VERSION = ' + JSON.stringify(require('./package.json').version) + ';'\" > src/version.ts",
"build:cjs": "npx tsc --project tsconfig.cjs.json",
"build:esm": "npx tsc --project tsconfig.esm.json",
"build": "npm run build:cjs && npm run build:esm",
Expand Down
95 changes: 36 additions & 59 deletions packages/agents-a365-observability/src/tracing/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { LIB_VERSION } from '../version';

/**
* OpenTelemetry constants for Agent 365
Expand Down Expand Up @@ -36,19 +37,15 @@ export class OpenTelemetryConstants {
public static readonly GEN_AI_REQUEST_MODEL_KEY = 'gen_ai.request.model';
public static readonly GEN_AI_REQUEST_TEMPERATURE_KEY = 'gen_ai.request.temperature';
public static readonly GEN_AI_REQUEST_TOP_P_KEY = 'gen_ai.request.top_p';
public static readonly GEN_AI_RESPONSE_ID_KEY = 'gen_ai.response.id';
public static readonly GEN_AI_RESPONSE_FINISH_REASONS_KEY = 'gen_ai.response.finish_reasons';
public static readonly GEN_AI_RESPONSE_MODEL_KEY = 'gen_ai.response.model';
public static readonly GEN_AI_SYSTEM_KEY = 'gen_ai.system';
public static readonly GEN_AI_SYSTEM_VALUE = 'az.ai.agent365';

public static readonly GEN_AI_AGENT_ID_KEY = 'gen_ai.agent.id';
public static readonly GEN_AI_AGENT_NAME_KEY = 'gen_ai.agent.name';
public static readonly GEN_AI_AGENT_TYPE_KEY = 'gen_ai.agent.type';
public static readonly GEN_AI_AGENT_DESCRIPTION_KEY = 'gen_ai.agent.description';
public static readonly GEN_AI_AGENT_PLATFORM_ID_KEY = 'gen_ai.agent.platformid';
public static readonly GEN_AI_AGENT_PLATFORM_ID_KEY = 'microsoft.a365.agent.platform.id';
public static readonly GEN_AI_AGENT_THOUGHT_PROCESS_KEY = 'microsoft.a365.agent.thought.process';
public static readonly GEN_AI_CONVERSATION_ID_KEY = 'gen_ai.conversation.id';
public static readonly GEN_AI_CONVERSATION_ITEM_LINK_KEY = 'gen_ai.conversation.item.link';
public static readonly GEN_AI_CONVERSATION_ITEM_LINK_KEY = 'microsoft.conversation.item.link';
public static readonly GEN_AI_TOKEN_TYPE_KEY = 'gen_ai.token.type';
public static readonly GEN_AI_USAGE_INPUT_TOKENS_KEY = 'gen_ai.usage.input_tokens';
public static readonly GEN_AI_USAGE_OUTPUT_TOKENS_KEY = 'gen_ai.usage.output_tokens';
Expand All @@ -58,80 +55,60 @@ export class OpenTelemetryConstants {
public static readonly GEN_AI_SYSTEM_INSTRUCTIONS_KEY = 'gen_ai.system_instructions';
public static readonly GEN_AI_INPUT_MESSAGES_KEY = 'gen_ai.input.messages';
public static readonly GEN_AI_OUTPUT_MESSAGES_KEY = 'gen_ai.output.messages';
public static readonly GEN_AI_EVENT_CONTENT = 'gen_ai.event.content';

// Tool execution constants
public static readonly GEN_AI_TOOL_CALL_ID_KEY = 'gen_ai.tool.call.id';
public static readonly GEN_AI_TOOL_NAME_KEY = 'gen_ai.tool.name';
public static readonly GEN_AI_TOOL_DESCRIPTION_KEY = 'gen_ai.tool.description';
public static readonly GEN_AI_TOOL_ARGS_KEY = 'gen_ai.tool.call.arguments';
public static readonly GEN_AI_TOOL_CALL_RESULT_KEY = 'gen_ai.event.content'; // GEN_AI_EVENT_CONTENT
public static readonly GEN_AI_TOOL_CALL_RESULT_KEY = 'gen_ai.tool.call.result';
public static readonly GEN_AI_TOOL_TYPE_KEY = 'gen_ai.tool.type';

// Agent user (user tied to agent instance during creation) or caller dimensions
public static readonly GEN_AI_AGENT_USER_ID_KEY = 'gen_ai.agent.userid';
public static readonly GEN_AI_CALLER_TENANT_ID_KEY = 'gen_ai.caller.tenantid';
public static readonly GEN_AI_CALLER_ID_KEY = 'gen_ai.caller.id';
public static readonly GEN_AI_CALLER_NAME_KEY = 'gen_ai.caller.name';
public static readonly GEN_AI_CALLER_UPN_KEY = 'gen_ai.caller.upn';
public static readonly GEN_AI_CALLER_CLIENT_IP_KEY = 'gen_ai.caller.client.ip';
public static readonly GEN_AI_CALLER_ID_KEY = 'microsoft.caller.id';
public static readonly GEN_AI_CALLER_NAME_KEY = 'microsoft.caller.name';
public static readonly GEN_AI_CALLER_UPN_KEY = 'microsoft.caller.upn';
public static readonly GEN_AI_CALLER_CLIENT_IP_KEY = 'client.address';

// Agent to Agent caller agent dimensions
public static readonly GEN_AI_CALLER_AGENT_USER_ID_KEY = 'gen_ai.caller.agent.userid';
public static readonly GEN_AI_CALLER_AGENT_UPN_KEY = 'gen_ai.caller.agent.upn';
public static readonly GEN_AI_CALLER_AGENT_TENANT_ID_KEY = 'gen_ai.caller.agent.tenantid';
public static readonly GEN_AI_CALLER_AGENT_NAME_KEY = 'gen_ai.caller.agent.name';
public static readonly GEN_AI_CALLER_AGENT_ID_KEY = 'gen_ai.caller.agent.id';
public static readonly GEN_AI_CALLER_AGENT_TYPE_KEY = 'gen_ai.caller.agent.type';
public static readonly GEN_AI_CALLER_AGENT_APPLICATION_ID_KEY = 'gen_ai.caller.agent.applicationid';
public static readonly GEN_AI_CALLER_AGENT_CLIENT_IP_KEY = 'gen_ai.caller.agent.user.client.ip';
public static readonly GEN_AI_CALLER_AGENT_PLATFORM_ID_KEY = 'gen_ai.caller.agent.platformid';
public static readonly GEN_AI_CALLER_AGENT_USER_ID_KEY = 'microsoft.a365.caller.agent.user.id';
public static readonly GEN_AI_CALLER_AGENT_UPN_KEY = 'microsoft.a365.caller.agent.user.upn';
public static readonly GEN_AI_CALLER_AGENT_NAME_KEY = 'microsoft.a365.caller.agent.name';
public static readonly GEN_AI_CALLER_AGENT_ID_KEY = 'microsoft.a365.caller.agent.id';
public static readonly GEN_AI_CALLER_AGENT_APPLICATION_ID_KEY = 'microsoft.a365.caller.agent.blueprint.id';
public static readonly GEN_AI_CALLER_AGENT_PLATFORM_ID_KEY = 'microsoft.a365.caller.agent.platform.id';
// Agent-specific dimensions
public static readonly AGENT_ID_KEY = 'gen_ai.agent.id';
public static readonly GEN_AI_TASK_ID_KEY = 'gen_ai.task.id';
public static readonly SESSION_ID_KEY = 'session.id';
public static readonly SESSION_DESCRIPTION_KEY = 'session.description';
public static readonly SESSION_ID_KEY = 'microsoft.session.id';
public static readonly SESSION_DESCRIPTION_KEY = 'microsoft.session.description';
public static readonly GEN_AI_ICON_URI_KEY = 'gen_ai.agent365.icon_uri';
public static readonly TENANT_ID_KEY = 'tenant.id';
public static readonly TENANT_ID_KEY = 'microsoft.tenant.id';

// Baggage keys
public static readonly OPERATION_SOURCE_KEY = 'operation.source';
public static readonly GEN_AI_AGENT_AUID_KEY = 'gen_ai.agent.user.id';
public static readonly GEN_AI_AGENT_UPN_KEY = 'gen_ai.agent.upn';
public static readonly GEN_AI_AGENT_BLUEPRINT_ID_KEY = 'gen_ai.agent.applicationid';
public static readonly CORRELATION_ID_KEY = 'correlation.id';
public static readonly HIRING_MANAGER_ID_KEY = 'hiring.manager.id';
public static readonly GEN_AI_AGENT_AUID_KEY = 'microsoft.agent.user.id';
public static readonly GEN_AI_AGENT_UPN_KEY = 'microsoft.agent.user.upn';
public static readonly GEN_AI_AGENT_BLUEPRINT_ID_KEY = 'microsoft.a365.agent.blueprint.id';

// Execution context dimensions
public static readonly GEN_AI_EXECUTION_TYPE_KEY = 'gen_ai.execution.type';
public static readonly GEN_AI_EXECUTION_PAYLOAD_KEY = 'gen_ai.execution.payload';

// Source metadata dimensions
public static readonly GEN_AI_EXECUTION_SOURCE_ID_KEY = 'gen_ai.execution.sourceMetadata.id';
public static readonly GEN_AI_EXECUTION_SOURCE_NAME_KEY = 'gen_ai.channel.name';
public static readonly GEN_AI_EXECUTION_SOURCE_DESCRIPTION_KEY = 'gen_ai.channel.link';
// Channel dimensions
public static readonly CHANNEL_NAME_KEY = 'microsoft.channel.name';
public static readonly CHANNEL_LINK_KEY = 'microsoft.channel.link';

// Custom parent id and parent name key
public static readonly CUSTOM_PARENT_SPAN_ID_KEY = 'custom.parent.span.id';
public static readonly CUSTOM_SPAN_NAME_KEY = 'custom.span.name';
}

/**
* Enumeration representing the source of an operation.
*/
export enum OperationSource {
/**
* Operation executed by SDK.
*/
SDK = 'SDK',

/**
* Operation executed by Gateway.
*/
GATEWAY = 'Gateway',
// Service attributes
public static readonly SERVICE_NAME_KEY = 'service.name';

/**
* Operation executed by MCP Server.
*/
MCP_SERVER = 'MCPServer',
// Telemetry SDK attributes
public static readonly TELEMETRY_SDK_NAME_KEY = 'telemetry.sdk.name';
public static readonly TELEMETRY_SDK_LANGUAGE_KEY = 'telemetry.sdk.language';
public static readonly TELEMETRY_SDK_VERSION_KEY = 'telemetry.sdk.version';
public static readonly TELEMETRY_SDK_NAME_VALUE = 'A365ObservabilitySDK';
public static readonly TELEMETRY_SDK_LANGUAGE_VALUE = 'nodejs';
public static readonly TELEMETRY_SDK_VERSION_VALUE = LIB_VERSION;
}
14 changes: 7 additions & 7 deletions packages/agents-a365-observability/src/tracing/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,6 @@ export interface AgentDetails {
/** The human-readable name of the AI agent */
agentName?: string;

/** Optional type of the AI agent */
agentType?: string;

/** A description of the AI agent's purpose or capabilities */
agentDescription?: string;

Expand All @@ -129,8 +126,8 @@ export interface AgentDetails {
/** The tenant ID for the agent */
tenantId?: string;

/** The client IP address for the agent user */
agentClientIP?: string;
/** The provider name (e.g., az.ai.agent365, openai, anthropic) */
providerName?: string;
}

/**
Expand Down Expand Up @@ -235,8 +232,11 @@ export interface InferenceDetails {
/** Array of finish reasons */
finishReasons?: string[];

/** Response ID from the model provider */
responseId?: string;
/** The thought process used by the agent */
thoughtProcess?: string;

/** The endpoint for the inference call */
endpoint?: ServiceEndpoint;
}

/**
Expand Down
Loading