From a4df28ffd48a2a65107d9710ec7b8cc8eb3fab56 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 16:22:21 +0000 Subject: [PATCH 1/3] Initial plan From 8c4c912a29435d43ea30df30df10296cf130aa2c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 16:31:17 +0000 Subject: [PATCH 2/3] Default exporter to custom domain endpoint, update URL paths to include tenantId - Remove PowerPlatformApiDiscovery from exporter, always use custom domain - Endpoint resolution: domain override > resolveAgent365Endpoint() - Update URL paths: /observability/tenants/{tenantId}/agents/{agentId}/traces - S2S paths: /observabilityService/tenants/{tenantId}/agents/{agentId}/traces - Always include x-ms-tenant-id header - Update tests to reflect new default behavior Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com> --- .../src/tracing/exporter/Agent365Exporter.ts | 30 +++++-------- .../exporter/Agent365ExporterOptions.ts | 2 +- .../core/agent365-exporter.test.ts | 45 +++++++------------ 3 files changed, 28 insertions(+), 49 deletions(-) diff --git a/packages/agents-a365-observability/src/tracing/exporter/Agent365Exporter.ts b/packages/agents-a365-observability/src/tracing/exporter/Agent365Exporter.ts index 1083f83c..0839f07b 100644 --- a/packages/agents-a365-observability/src/tracing/exporter/Agent365Exporter.ts +++ b/packages/agents-a365-observability/src/tracing/exporter/Agent365Exporter.ts @@ -6,7 +6,7 @@ import { ExportResult, ExportResultCode } from '@opentelemetry/core'; import { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base'; -import { PowerPlatformApiDiscovery, ClusterCategory, IConfigurationProvider } from '@microsoft/agents-a365-runtime'; +import { ClusterCategory, IConfigurationProvider } from '@microsoft/agents-a365-runtime'; import type { ObservabilityConfiguration } from '../../configuration'; import { partitionByIdentity, @@ -15,7 +15,6 @@ import { hexSpanId, kindName, statusName, - useCustomDomainForObservability, resolveAgent365Endpoint, getAgent365ObservabilityDomainOverride, isPerRequestExportEnabled @@ -82,8 +81,8 @@ interface OTLPStatus { * Observability span exporter for Agent365: * - Partitions spans by (tenantId, agentId) * - Builds OTLP-like JSON: resourceSpans -> scopeSpans -> spans - * - POSTs per group to https://{endpoint}/maven/agent365/agents/{agentId}/traces?api-version=1 - * or, when useS2SEndpoint is true, https://{endpoint}/maven/agent365/service/agents/{agentId}/traces?api-version=1 + * - POSTs per group to https://{endpoint}/observability/tenants/{tenantId}/agents/{agentId}/traces?api-version=1 + * or, when useS2SEndpoint is true, https://{endpoint}/observabilityService/tenants/{tenantId}/agents/{agentId}/traces?api-version=1 * - Adds Bearer token via token_resolver(agentId, tenantId) */ export class Agent365Exporter implements SpanExporter { @@ -170,27 +169,20 @@ export class Agent365Exporter implements SpanExporter { const payload = this.buildExportRequest(spans); const body = JSON.stringify(payload); - const usingCustomServiceEndpoint = useCustomDomainForObservability(this.configProvider); - // Select endpoint path based on S2S flag + // Select endpoint path based on S2S flag (includes tenantId in path) const endpointRelativePath = this.options.useS2SEndpoint - ? `/maven/agent365/service/agents/${agentId}/traces` - : `/maven/agent365/agents/${agentId}/traces`; + ? `/observabilityService/tenants/${tenantId}/agents/${agentId}/traces` + : `/observability/tenants/${tenantId}/agents/${agentId}/traces`; let url: string; const domainOverride = getAgent365ObservabilityDomainOverride(this.configProvider); if (domainOverride) { url = `${domainOverride}${endpointRelativePath}?api-version=1`; - } else if (usingCustomServiceEndpoint) { + } else { const base = resolveAgent365Endpoint(this.options.clusterCategory as ClusterCategory); url = `${base}${endpointRelativePath}?api-version=1`; - logger.info(`[Agent365Exporter] Using custom domain endpoint: ${url}`); - } else { - // Default behavior: discover PPAPI gateway endpoint per-tenant - const discovery = new PowerPlatformApiDiscovery(this.options.clusterCategory as ClusterCategory); - const endpoint = discovery.getTenantIslandClusterEndpoint(tenantId); - url = `https://${endpoint}${endpointRelativePath}?api-version=1`; - logger.info(`[Agent365Exporter] Resolved endpoint: ${url}`); + logger.info(`[Agent365Exporter] Using default endpoint: ${url}`); } const headers: Record = { @@ -229,10 +221,8 @@ export class Agent365Exporter implements SpanExporter { return; } - // Add tenant id to headers when using custom domain - if (usingCustomServiceEndpoint) { - headers['x-ms-tenant-id'] = tenantId; - } + // Always include tenant id header + headers['x-ms-tenant-id'] = tenantId; // Basic retry loop const { ok, correlationId } = await this.postWithRetries(url, body, headers); diff --git a/packages/agents-a365-observability/src/tracing/exporter/Agent365ExporterOptions.ts b/packages/agents-a365-observability/src/tracing/exporter/Agent365ExporterOptions.ts index 886103e5..37382bdc 100644 --- a/packages/agents-a365-observability/src/tracing/exporter/Agent365ExporterOptions.ts +++ b/packages/agents-a365-observability/src/tracing/exporter/Agent365ExporterOptions.ts @@ -21,7 +21,7 @@ export type TokenResolver = (agentId: string, tenantId: string) => string | null * @property {ClusterCategory | string} clusterCategory Environment / cluster category (e.g. ClusterCategory.preprod, ClusterCategory.prod, default to ClusterCategory.prod). * @property {TokenResolver} [tokenResolver] Optional delegate to obtain an auth token. If omitted the exporter will * fall back to reading the cached token (AgenticTokenCacheInstance.getObservabilityToken). - * @property {boolean} [useS2SEndpoint] When true, exporter will POST to the S2S path (/maven/agent365/service/agents/{agentId}/traces). + * @property {boolean} [useS2SEndpoint] When true, exporter will POST to the S2S path (/observabilityService/tenants/{tenantId}/agents/{agentId}/traces). * @property {number} maxQueueSize Maximum span queue size before drops occur (passed to BatchSpanProcessor). * @property {number} scheduledDelayMilliseconds Delay between automatic batch flush attempts. * @property {number} exporterTimeoutMilliseconds Per-export timeout (abort if exceeded). diff --git a/tests/observability/core/agent365-exporter.test.ts b/tests/observability/core/agent365-exporter.test.ts index 858eb672..6b0116d0 100644 --- a/tests/observability/core/agent365-exporter.test.ts +++ b/tests/observability/core/agent365-exporter.test.ts @@ -118,9 +118,8 @@ describe('Agent365Exporter', () => { it.each([ { cluster: 'prod', expectedUrl: 'https://agent365.svc.cloud.microsoft', token: 'tok-prod' }, { cluster: 'preprod', expectedUrl: 'https://agent365.svc.cloud.microsoft', token: 'tok-preprod' } - ])('exports to custom domain when enabled (cluster=%s)', async ({ cluster, expectedUrl, token }) => { + ])('exports to custom domain by default (cluster=%s)', async ({ cluster, expectedUrl, token }) => { mockFetchSequence([200]); - process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN = 'true'; const opts = new Agent365ExporterOptions(); opts.clusterCategory = cluster; opts.tokenResolver = () => token; @@ -138,14 +137,14 @@ describe('Agent365Exporter', () => { expect(fetchCalls.length).toBe(1); const urlArg = fetchCalls[0][0]; const headersArg = fetchCalls[0][1].headers; - expect(urlArg).toBe(`${expectedUrl}/maven/agent365/agents/${agentId}/traces?api-version=1`); + expect(urlArg).toBe(`${expectedUrl}/observability/tenants/${tenantId}/agents/${agentId}/traces?api-version=1`); expect(headersArg['x-ms-tenant-id']).toBe(tenantId); expect(headersArg['authorization']).toBe(`Bearer ${token}`); }); it.each([ { - description: 'set to non-empty value and A365_OBSERVABILITY_USE_CUSTOM_DOMAIN is true', + description: 'set to non-empty value', override: 'https://custom-observability.internal', expectedBaseUrl: 'https://custom-observability.internal' }, @@ -164,15 +163,8 @@ describe('Agent365Exporter', () => { override: undefined, expectedBaseUrl: 'https://agent365.svc.cloud.microsoft' }, - { - description: 'set to non-empty value and A365_OBSERVABILITY_USE_CUSTOM_DOMAIN is false', - override: 'https://custom-observability.internal', - expectedBaseUrl: 'https://custom-observability.internal', - notUseCustomDomain: true - }, - ])('uses correct domain when A365_OBSERVABILITY_DOMAIN_OVERRIDE is $description', async ({ override, expectedBaseUrl, notUseCustomDomain }) => { + ])('uses correct domain when A365_OBSERVABILITY_DOMAIN_OVERRIDE is $description', async ({ override, expectedBaseUrl }) => { mockFetchSequence([200]); - process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN = notUseCustomDomain ? 'false' : 'true'; if (override !== undefined) { process.env.A365_OBSERVABILITY_DOMAIN_OVERRIDE = override as string; @@ -200,19 +192,15 @@ describe('Agent365Exporter', () => { const urlArg = fetchCalls[0][0] as string; const headersArg = fetchCalls[0][1].headers as Record; - expect(urlArg).toBe(`${expectedBaseUrl}/maven/agent365/agents/${agentId}/traces?api-version=1`); - if (!notUseCustomDomain) { - expect(headersArg['x-ms-tenant-id']).toBe(tenantId); - } else { - expect(headersArg['x-ms-tenant-id']).toBeUndefined(); - } + expect(urlArg).toBe(`${expectedBaseUrl}/observability/tenants/${tenantId}/agents/${agentId}/traces?api-version=1`); + expect(headersArg['x-ms-tenant-id']).toBe(tenantId); expect(headersArg['authorization']).toBe(`Bearer ${token}`); }); - it('exports to discovery endpoint when custom domain disabled', async () => { + it('exports to default custom domain endpoint when no env vars set', async () => { mockFetchSequence([200]); delete process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN; - const token = 'tok-prod-disabled'; + const token = 'tok-prod-default'; const opts = new Agent365ExporterOptions(); opts.clusterCategory = 'prod'; opts.tokenResolver = () => token; @@ -230,9 +218,8 @@ describe('Agent365Exporter', () => { expect(fetchCalls.length).toBe(1); const urlArg = fetchCalls[0][0]; const headersArg = fetchCalls[0][1].headers; - const discoveryRegex = new RegExp(`^https://[\\w.-]+/maven/agent365/agents/${agentId}/traces\\?api-version=1$`, 'i'); - expect(urlArg).toMatch(discoveryRegex); - expect(headersArg['x-ms-tenant-id']).toBeUndefined(); + expect(urlArg).toBe(`https://agent365.svc.cloud.microsoft/observability/tenants/${tenantId}/agents/${agentId}/traces?api-version=1`); + expect(headersArg['x-ms-tenant-id']).toBe(tenantId); expect(headersArg['authorization']).toBe(`Bearer ${token}`); }); @@ -242,7 +229,7 @@ describe('Agent365Exporter', () => { // Intentionally omit tokenResolver expect(() => new Agent365Exporter(opts)).toThrow(/tokenResolver must be provided/); }); - it('uses S2S endpoint path when useS2SEndpoint is true (discovery flow)', async () => { + it('uses S2S endpoint path when useS2SEndpoint is true', async () => { mockFetchSequence([200]); const token = 'tok-s2s'; const opts = new Agent365ExporterOptions(); @@ -266,14 +253,15 @@ describe('Agent365Exporter', () => { expect(fetchCalls.length).toBe(1); const urlArg = fetchCalls[0][0] as string; - expect(urlArg).toMatch(`/maven/agent365/service/agents/${agentId}/traces?api-version=1`); + expect(urlArg).toMatch(`/observabilityService/tenants/${tenantId}/agents/${agentId}/traces?api-version=1`); const headersArg = fetchCalls[0][1].headers as Record; expect(headersArg['authorization']).toBe(`Bearer ${token}`); + expect(headersArg['x-ms-tenant-id']).toBe(tenantId); }); - it('uses S2S endpoint path with custom domain and sets x-ms-tenant-id', async () => { + it('uses S2S endpoint path with domain override and sets x-ms-tenant-id', async () => { mockFetchSequence([200]); - process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN = 'true'; + process.env.A365_OBSERVABILITY_DOMAIN_OVERRIDE = 'https://custom.domain'; const token = 'tok-s2s-custom'; const opts = new Agent365ExporterOptions(); opts.clusterCategory = 'prod'; @@ -294,7 +282,8 @@ describe('Agent365Exporter', () => { const fetchCalls = getFetchCalls(); expect(fetchCalls.length).toBe(1); const urlArg = fetchCalls[0][0] as string; - expect(urlArg).toMatch(`/maven/agent365/service/agents/${agentId}/traces?api-version=1`); + expect(urlArg).toMatch(`/observabilityService/tenants/${tenantId}/agents/${agentId}/traces?api-version=1`); + expect(urlArg).toContain('https://custom.domain'); const headersArg = fetchCalls[0][1].headers as Record; expect(headersArg['authorization']).toBe(`Bearer ${token}`); expect(headersArg['x-ms-tenant-id']).toBe(tenantId); From 31ad864dffc92e1068788ca3e90da6df9f989d44 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 21:10:11 +0000 Subject: [PATCH 3/3] Remove useCustomDomainForObservability from configuration, utils, tests, and docs Co-authored-by: nikhilNava <211831449+nikhilNava@users.noreply.github.com> --- CLAUDE.md | 1 - docs/prd-configuration-provider.md | 13 ----- .../OpenAIObservabilityConfiguration.ts | 3 +- .../agents-a365-observability/docs/design.md | 2 - .../ObservabilityConfiguration.ts | 6 -- .../ObservabilityConfigurationOptions.ts | 11 ---- .../src/tracing/exporter/utils.ts | 15 ----- .../OpenAIObservabilityConfiguration.test.ts | 7 --- .../ObservabilityConfiguration.test.ts | 42 -------------- .../core/agent365-exporter.test.ts | 2 - .../tracing/exporter-utils.test.ts | 55 ------------------- 11 files changed, 1 insertion(+), 156 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bfbf86bc..0ba2b924 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -213,7 +213,6 @@ The keyword "Kairo" is legacy and should not appear in any code. Flag and remove | `A365_OBSERVABILITY_SCOPES_OVERRIDE` | Override observability auth scopes | Space-separated scope strings | | `ENABLE_A365_OBSERVABILITY_EXPORTER` | Enable Agent365 exporter | `true`, `false` (default) | | `ENABLE_A365_OBSERVABILITY_PER_REQUEST_EXPORT` | Enable per-request export mode | `true`, `false` (default) | -| `A365_OBSERVABILITY_USE_CUSTOM_DOMAIN` | Use custom domain for export | `true`, `false` (default) | | `A365_OBSERVABILITY_DOMAIN_OVERRIDE` | Custom domain URL override | URL string | | `A365_OBSERVABILITY_LOG_LEVEL` | Internal logging level | `none` (default), `error`, `warn`, `info`, `debug` | | `A365_PER_REQUEST_MAX_TRACES` | Max buffered traces per request (`PerRequestSpanProcessorConfiguration`) | Number (default: 1000) | diff --git a/docs/prd-configuration-provider.md b/docs/prd-configuration-provider.md index 6bc24ab3..9c3854d4 100644 --- a/docs/prd-configuration-provider.md +++ b/docs/prd-configuration-provider.md @@ -66,7 +66,6 @@ The Agent365 SDK currently relies on environment variables for all configuration |---------|--------------|---------|------|---------| | `observabilityAuthenticationScopes` | `A365_OBSERVABILITY_SCOPES_OVERRIDE` | `['https://api.powerplatform.com/.default']` | `string[]` | ObservabilityConfiguration | | `isObservabilityExporterEnabled` | `ENABLE_A365_OBSERVABILITY_EXPORTER` | `false` | `boolean` | ObservabilityConfiguration | -| `useCustomDomainForObservability` | `A365_OBSERVABILITY_USE_CUSTOM_DOMAIN` | `false` | `boolean` | ObservabilityConfiguration | | `observabilityDomainOverride` | `A365_OBSERVABILITY_DOMAIN_OVERRIDE` | `null` | `string \| null` | ObservabilityConfiguration | | `observabilityLogLevel` | `A365_OBSERVABILITY_LOG_LEVEL` | `'none'` | `string` | ObservabilityConfiguration | @@ -392,7 +391,6 @@ export type ObservabilityConfigurationOptions = RuntimeConfigurationOptions & { */ observabilityAuthenticationScopes?: () => string[]; isObservabilityExporterEnabled?: () => boolean; - useCustomDomainForObservability?: () => boolean; observabilityDomainOverride?: () => string | null; observabilityLogLevel?: () => string; }; @@ -449,15 +447,6 @@ export class ObservabilityConfiguration extends RuntimeConfiguration { return ['true', '1', 'yes', 'on'].includes(value); } - get useCustomDomainForObservability(): boolean { - const result = this.observabilityOverrides.useCustomDomainForObservability?.(); - if (result !== undefined) { - return result; - } - const value = process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN?.toLowerCase() ?? ''; - return ['true', '1', 'yes', 'on'].includes(value); - } - get observabilityDomainOverride(): string | null { const result = this.observabilityOverrides.observabilityDomainOverride?.(); if (result !== undefined) { @@ -666,7 +655,6 @@ packages/agents-a365-observability-extensions-openai/src/ 2. **`tests/observability/tracing/exporter-utils.test.ts`** (NEW) - `isAgent365ExporterEnabled()` with all boolean variants - `isPerRequestExportEnabled()` with all boolean variants - - `useCustomDomainForObservability()` edge cases - `getAgent365ObservabilityDomainOverride()` edge cases - `resolveAgent365Endpoint()` for all cluster categories @@ -1173,7 +1161,6 @@ These methods remain available for backward compatibility but should not be used | `A365_OBSERVABILITY_SCOPES_OVERRIDE` | string (space-sep) | prod scope | observability | | `ENABLE_A365_OBSERVABILITY_EXPORTER` | boolean | `false` | observability | | `ENABLE_A365_OBSERVABILITY_PER_REQUEST_EXPORT` | boolean | `false` | observability (PerRequestSpanProcessorConfiguration) | -| `A365_OBSERVABILITY_USE_CUSTOM_DOMAIN` | boolean | `false` | observability | | `A365_OBSERVABILITY_DOMAIN_OVERRIDE` | string | `null` | observability | | `A365_OBSERVABILITY_LOG_LEVEL` | string | `'none'` | observability | | `A365_PER_REQUEST_MAX_TRACES` | number | `1000` | observability (PerRequestSpanProcessorConfiguration) | diff --git a/packages/agents-a365-observability-extensions-openai/src/configuration/OpenAIObservabilityConfiguration.ts b/packages/agents-a365-observability-extensions-openai/src/configuration/OpenAIObservabilityConfiguration.ts index 5618c1d0..b59cdb71 100644 --- a/packages/agents-a365-observability-extensions-openai/src/configuration/OpenAIObservabilityConfiguration.ts +++ b/packages/agents-a365-observability-extensions-openai/src/configuration/OpenAIObservabilityConfiguration.ts @@ -57,6 +57,5 @@ export class OpenAIObservabilityConfiguration extends ObservabilityConfiguration } // Inherited: clusterCategory, isDevelopmentEnvironment, observabilityAuthenticationScopes, - // isObservabilityExporterEnabled, useCustomDomainForObservability, - // observabilityDomainOverride, observabilityLogLevel + // isObservabilityExporterEnabled, observabilityDomainOverride, observabilityLogLevel } diff --git a/packages/agents-a365-observability/docs/design.md b/packages/agents-a365-observability/docs/design.md index 8a16d793..341f1d3b 100644 --- a/packages/agents-a365-observability/docs/design.md +++ b/packages/agents-a365-observability/docs/design.md @@ -444,7 +444,6 @@ const customConfig = new ObservabilityConfiguration({ |----------|--------------|---------|-------------| | `observabilityAuthenticationScopes` | `A365_OBSERVABILITY_SCOPES_OVERRIDE` | `['https://api.powerplatform.com/.default']` | OAuth scopes for observability auth | | `isObservabilityExporterEnabled` | `ENABLE_A365_OBSERVABILITY_EXPORTER` | `false` | Enable Agent365 exporter | -| `useCustomDomainForObservability` | `A365_OBSERVABILITY_USE_CUSTOM_DOMAIN` | `false` | Use custom domain for export | | `observabilityDomainOverride` | `A365_OBSERVABILITY_DOMAIN_OVERRIDE` | `null` | Custom domain URL override | | `observabilityLogLevel` | `A365_OBSERVABILITY_LOG_LEVEL` | `none` | Internal logging level | | `clusterCategory` | `CLUSTER_CATEGORY` | `prod` | (Inherited) Environment cluster | @@ -482,7 +481,6 @@ console.log(config.perRequestMaxTraces); // Max buffered traces (default: 1000) | `ENABLE_A365_OBSERVABILITY_EXPORTER` | Enable/disable Agent365 exporter | `false` | | `A365_OBSERVABILITY_SCOPES_OVERRIDE` | Override auth scopes (space-separated) | Production scope | | `ENABLE_A365_OBSERVABILITY_PER_REQUEST_EXPORT` | Enable per-request export mode | `false` | -| `A365_OBSERVABILITY_USE_CUSTOM_DOMAIN` | Use custom domain for export | `false` | | `A365_OBSERVABILITY_DOMAIN_OVERRIDE` | Custom domain URL | - | | `A365_OBSERVABILITY_LOG_LEVEL` | Internal log level | `none` | | `A365_PER_REQUEST_MAX_TRACES` | Max buffered traces (`PerRequestSpanProcessorConfiguration`) | `1000` | diff --git a/packages/agents-a365-observability/src/configuration/ObservabilityConfiguration.ts b/packages/agents-a365-observability/src/configuration/ObservabilityConfiguration.ts index 8060b83e..2e6f143e 100644 --- a/packages/agents-a365-observability/src/configuration/ObservabilityConfiguration.ts +++ b/packages/agents-a365-observability/src/configuration/ObservabilityConfiguration.ts @@ -44,12 +44,6 @@ export class ObservabilityConfiguration extends RuntimeConfiguration { return RuntimeConfiguration.parseEnvBoolean(process.env.ENABLE_A365_OBSERVABILITY_EXPORTER); } - get useCustomDomainForObservability(): boolean { - const result = this.observabilityOverrides.useCustomDomainForObservability?.(); - if (result !== undefined) return result; - return RuntimeConfiguration.parseEnvBoolean(process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN); - } - get observabilityDomainOverride(): string | null { const result = this.observabilityOverrides.observabilityDomainOverride?.(); if (result !== undefined) { diff --git a/packages/agents-a365-observability/src/configuration/ObservabilityConfigurationOptions.ts b/packages/agents-a365-observability/src/configuration/ObservabilityConfigurationOptions.ts index c9c2e3e3..a22f7d40 100644 --- a/packages/agents-a365-observability/src/configuration/ObservabilityConfigurationOptions.ts +++ b/packages/agents-a365-observability/src/configuration/ObservabilityConfigurationOptions.ts @@ -35,19 +35,8 @@ export type ObservabilityConfigurationOptions = RuntimeConfigurationOptions & { */ isObservabilityExporterEnabled?: () => boolean; - /** - * Override to enable/disable custom domain for observability endpoints. - * When enabled, uses `observabilityDomainOverride` instead of the default endpoint. - * - * @returns `true` to use custom domain, `false` to use default. - * @envvar A365_OBSERVABILITY_USE_CUSTOM_DOMAIN - 'true', '1', 'yes', 'on' to enable. - * @default false - */ - useCustomDomainForObservability?: () => boolean; - /** * Override for the custom observability domain/endpoint. - * Only used when `useCustomDomainForObservability` is true. * Trailing slashes are automatically removed. * * @returns Custom domain URL string, or `null` for no override. diff --git a/packages/agents-a365-observability/src/tracing/exporter/utils.ts b/packages/agents-a365-observability/src/tracing/exporter/utils.ts index 5ba74953..f75b1fe9 100644 --- a/packages/agents-a365-observability/src/tracing/exporter/utils.ts +++ b/packages/agents-a365-observability/src/tracing/exporter/utils.ts @@ -156,21 +156,6 @@ export function isPerRequestExportEnabled( return enabled; } -/** - * Single toggle to use custom domain for observability export. - * When true exporter will send traces to custom Agent365 service endpoint - * and include x-ms-tenant-id in headers. - * @param configProvider Optional configuration provider. Defaults to defaultObservabilityConfigurationProvider if not specified. - */ -export function useCustomDomainForObservability( - configProvider?: IConfigurationProvider -): boolean { - const provider = configProvider ?? defaultObservabilityConfigurationProvider; - const enabled = provider.getConfiguration().useCustomDomainForObservability; - logger.info(`[Agent365Exporter] Use custom domain for observability: ${enabled}`); - return enabled; -} - /** * Resolve the Agent365 service endpoint base URI for a given cluster category. * When an explicit override is not configured, this determines the default base URI. diff --git a/tests/observability-extensions-openai/configuration/OpenAIObservabilityConfiguration.test.ts b/tests/observability-extensions-openai/configuration/OpenAIObservabilityConfiguration.test.ts index 0ed960f4..ae9075ae 100644 --- a/tests/observability-extensions-openai/configuration/OpenAIObservabilityConfiguration.test.ts +++ b/tests/observability-extensions-openai/configuration/OpenAIObservabilityConfiguration.test.ts @@ -71,13 +71,6 @@ describe('OpenAIObservabilityConfiguration', () => { expect(config.observabilityAuthenticationScopes).toEqual(['custom-scope/.default']); }); - it('should inherit useCustomDomainForObservability from override', () => { - const config = new OpenAIObservabilityConfiguration({ - useCustomDomainForObservability: () => true - }); - expect(config.useCustomDomainForObservability).toBe(true); - }); - it('should inherit observabilityDomainOverride from override', () => { const config = new OpenAIObservabilityConfiguration({ observabilityDomainOverride: () => 'https://custom.domain' diff --git a/tests/observability/configuration/ObservabilityConfiguration.test.ts b/tests/observability/configuration/ObservabilityConfiguration.test.ts index fc83817b..5c3ad7cf 100644 --- a/tests/observability/configuration/ObservabilityConfiguration.test.ts +++ b/tests/observability/configuration/ObservabilityConfiguration.test.ts @@ -131,48 +131,6 @@ describe('ObservabilityConfiguration', () => { }); }); - describe('useCustomDomainForObservability', () => { - it('should use override function when provided', () => { - const config = new ObservabilityConfiguration({ - useCustomDomainForObservability: () => true - }); - expect(config.useCustomDomainForObservability).toBe(true); - }); - - it.each([ - ['true', true], - ['1', true], - ['yes', true], - ['on', true], - ['false', false], - ['0', false], - ['', false] - ])('should return %s when env var is "%s"', (envValue, expected) => { - process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN = envValue; - const config = new ObservabilityConfiguration({}); - expect(config.useCustomDomainForObservability).toBe(expected); - }); - - it('should return false when env var is not set', () => { - delete process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN; - const config = new ObservabilityConfiguration({}); - expect(config.useCustomDomainForObservability).toBe(false); - }); - - it('should call override function on each access (dynamic resolution)', () => { - let callCount = 0; - const config = new ObservabilityConfiguration({ - useCustomDomainForObservability: () => { - callCount++; - return true; - } - }); - void config.useCustomDomainForObservability; - void config.useCustomDomainForObservability; - expect(callCount).toBe(2); - }); - }); - describe('observabilityDomainOverride', () => { it('should use override function when provided', () => { const config = new ObservabilityConfiguration({ diff --git a/tests/observability/core/agent365-exporter.test.ts b/tests/observability/core/agent365-exporter.test.ts index 6b0116d0..778ea104 100644 --- a/tests/observability/core/agent365-exporter.test.ts +++ b/tests/observability/core/agent365-exporter.test.ts @@ -64,7 +64,6 @@ describe('Agent365Exporter', () => { jest.clearAllTimers(); jest.useRealTimers(); global.fetch = originalFetch; - delete process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN; delete process.env.A365_OBSERVABILITY_DOMAIN_OVERRIDE; delete process.env.ENABLE_A365_OBSERVABILITY_PER_REQUEST_EXPORT; }); @@ -199,7 +198,6 @@ describe('Agent365Exporter', () => { it('exports to default custom domain endpoint when no env vars set', async () => { mockFetchSequence([200]); - delete process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN; const token = 'tok-prod-default'; const opts = new Agent365ExporterOptions(); opts.clusterCategory = 'prod'; diff --git a/tests/observability/tracing/exporter-utils.test.ts b/tests/observability/tracing/exporter-utils.test.ts index 6dd9b365..d9a9fcc1 100644 --- a/tests/observability/tracing/exporter-utils.test.ts +++ b/tests/observability/tracing/exporter-utils.test.ts @@ -267,61 +267,6 @@ describe('exporter/utils', () => { }); }); - describe('useCustomDomainForObservability', () => { - it.each([ - { value: 'true', expected: true }, - { value: 'TRUE', expected: true }, - { value: '1', expected: true }, - { value: 'yes', expected: true }, - { value: 'on', expected: true }, - ])('should return $expected when A365_OBSERVABILITY_USE_CUSTOM_DOMAIN is "$value"', async ({ value, expected }) => { - process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN = value; - const { useCustomDomainForObservability } = await import('@microsoft/agents-a365-observability/src/tracing/exporter/utils'); - expect(useCustomDomainForObservability()).toBe(expected); - }); - - it.each([ - { value: 'false', expected: false }, - { value: '0', expected: false }, - { value: '', expected: false }, - ])('should return $expected when A365_OBSERVABILITY_USE_CUSTOM_DOMAIN is "$value"', async ({ value, expected }) => { - process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN = value; - const { useCustomDomainForObservability } = await import('@microsoft/agents-a365-observability/src/tracing/exporter/utils'); - expect(useCustomDomainForObservability()).toBe(expected); - }); - - it('should return false when env var is not set', async () => { - delete process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN; - const { useCustomDomainForObservability } = await import('@microsoft/agents-a365-observability/src/tracing/exporter/utils'); - expect(useCustomDomainForObservability()).toBe(false); - }); - - it('should use configProvider override when provided (enabled)', async () => { - delete process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN; - const provider = new DefaultConfigurationProvider(() => new ObservabilityConfiguration({ - useCustomDomainForObservability: () => true, - })); - const { useCustomDomainForObservability } = await import('@microsoft/agents-a365-observability/src/tracing/exporter/utils'); - expect(useCustomDomainForObservability(provider)).toBe(true); - }); - - it('should use configProvider override when provided (disabled)', async () => { - process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN = 'true'; - const provider = new DefaultConfigurationProvider(() => new ObservabilityConfiguration({ - useCustomDomainForObservability: () => false, - })); - const { useCustomDomainForObservability } = await import('@microsoft/agents-a365-observability/src/tracing/exporter/utils'); - expect(useCustomDomainForObservability(provider)).toBe(false); - }); - - it('should return false when no env var is set and configProvider has no override', async () => { - delete process.env.A365_OBSERVABILITY_USE_CUSTOM_DOMAIN; - const provider = new DefaultConfigurationProvider(() => new ObservabilityConfiguration()); - const { useCustomDomainForObservability } = await import('@microsoft/agents-a365-observability/src/tracing/exporter/utils'); - expect(useCustomDomainForObservability(provider)).toBe(false); - }); - }); - describe('resolveAgent365Endpoint', () => { it('should return production endpoint for prod cluster', async () => { const { resolveAgent365Endpoint } = await import('@microsoft/agents-a365-observability/src/tracing/exporter/utils');