diff --git a/packages/agents-a365-observability/src/tracing/constants.ts b/packages/agents-a365-observability/src/tracing/constants.ts index 162c91a2..c1539d8b 100644 --- a/packages/agents-a365-observability/src/tracing/constants.ts +++ b/packages/agents-a365-observability/src/tracing/constants.ts @@ -83,6 +83,7 @@ export class OpenTelemetryConstants { 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 GEN_AI_ICON_URI_KEY = 'gen_ai.agent365.icon_uri'; public static readonly TENANT_ID_KEY = 'tenant.id'; diff --git a/packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts b/packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts index d7feb434..f0640fd4 100644 --- a/packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts +++ b/packages/agents-a365-observability/src/tracing/middleware/BaggageBuilder.ts @@ -149,6 +149,16 @@ export class BaggageBuilder { return this; } + /** + * Set the session description baggage value. + * @param value The session description + * @returns Self for method chaining + */ + sessionDescription(value: string | null | undefined): BaggageBuilder { + this.set(OpenTelemetryConstants.SESSION_DESCRIPTION_KEY, value); + return this; + } + /** * Set the caller name baggage value. * @param value The caller name diff --git a/packages/agents-a365-observability/src/tracing/processors/util.ts b/packages/agents-a365-observability/src/tracing/processors/util.ts index 4b960dae..3738842c 100644 --- a/packages/agents-a365-observability/src/tracing/processors/util.ts +++ b/packages/agents-a365-observability/src/tracing/processors/util.ts @@ -19,6 +19,7 @@ export const GENERIC_ATTRIBUTES: readonly string[] = [ consts.GEN_AI_AGENT_ID_KEY, consts.GEN_AI_AGENT_NAME_KEY, consts.GEN_AI_AGENT_DESCRIPTION_KEY, + consts.SESSION_DESCRIPTION_KEY, consts.GEN_AI_AGENT_USER_ID_KEY, consts.GEN_AI_AGENT_UPN_KEY, consts.GEN_AI_AGENT_BLUEPRINT_ID_KEY, diff --git a/tests-agent/basic-agent-sdk-sample/src/agent.ts b/tests-agent/basic-agent-sdk-sample/src/agent.ts index 75df9d42..c4ac4c16 100644 --- a/tests-agent/basic-agent-sdk-sample/src/agent.ts +++ b/tests-agent/basic-agent-sdk-sample/src/agent.ts @@ -61,6 +61,7 @@ agentApplication.onActivity( .agentId(agentInfo.agentId) .correlationId("7ff6dca0-917c-4bb0-b31a-794e533d8aad") .agentName(agentInfo.agentName) + .sessionDescription('Initial onboarding session') .conversationId(context.activity.conversation?.id) .callerId(context.activity.from?.aadObjectId) .callerUpn(context.activity.from?.id) diff --git a/tests/observability/core/BaggageBuilder.test.ts b/tests/observability/core/BaggageBuilder.test.ts index e3afd04a..43f255c5 100644 --- a/tests/observability/core/BaggageBuilder.test.ts +++ b/tests/observability/core/BaggageBuilder.test.ts @@ -140,9 +140,11 @@ describe('BaggageBuilder', () => { .agentId('agent-456') .correlationId('corr-789') .sessionId('session-0001') + .sessionDescription('My session desc') .build(); const bag = propagation.getBaggage((scope as any).contextWithBaggage); expect(bag?.getEntry(OpenTelemetryConstants.SESSION_ID_KEY)?.value).toBe('session-0001'); + expect(bag?.getEntry(OpenTelemetryConstants.SESSION_DESCRIPTION_KEY)?.value).toBe('My session desc'); }); it('should omit empty sessionId value', () => { @@ -152,8 +154,15 @@ describe('BaggageBuilder', () => { const bag = propagation.getBaggage((scope as any).contextWithBaggage); expect(bag?.getEntry(OpenTelemetryConstants.SESSION_ID_KEY)).toBeUndefined(); }); - }); + it('should omit null sessionDescription value', () => { + const scope = new BaggageBuilder() + .sessionDescription(null) + .build(); + const bag = propagation.getBaggage((scope as any).contextWithBaggage); + expect(bag?.getEntry(OpenTelemetryConstants.SESSION_DESCRIPTION_KEY)).toBeUndefined(); + }); + }); }); describe('BaggageScope', () => { diff --git a/tests/observability/core/SpanProcessor.test.ts b/tests/observability/core/SpanProcessor.test.ts index 2b175904..784694be 100644 --- a/tests/observability/core/SpanProcessor.test.ts +++ b/tests/observability/core/SpanProcessor.test.ts @@ -68,6 +68,19 @@ describe('SpanProcessor', () => { expect(attrs[OpenTelemetryConstants.SESSION_ID_KEY]).toBe('session-abc'); }); + it('should copy sessionDescription from baggage to span', () => { + let baggage = propagation.createBaggage(); + baggage = baggage.setEntry(OpenTelemetryConstants.SESSION_DESCRIPTION_KEY, { value: 'Test session description' }); + + const ctx = propagation.setBaggage(context.active(), baggage); + const tracer = provider.getTracer('test'); + const testSpan = tracer.startSpan('test-span', { kind: SpanKind.CLIENT }, ctx as any); + testSpan.end(); + + const attrs = (testSpan as any)._attributes ?? (testSpan as any).attributes ?? {}; + expect(attrs[OpenTelemetryConstants.SESSION_DESCRIPTION_KEY]).toBe('Test session description'); + }); + it('should copy invoke agent attributes for invoke_agent operations', () => { // Set baggage with invoke agent specific fields const baggageEntries = {