From fd0afee155f21efa83c819121d2785fe7487ad1d Mon Sep 17 00:00:00 2001 From: Avi Alpert Date: Fri, 10 Jul 2026 17:15:09 -0400 Subject: [PATCH] fix: agentcore dev overrides otel env vars --- src/cli/commands/dev/browser-mode.ts | 13 +++++-- src/cli/commands/dev/command.tsx | 4 +-- .../dev/__tests__/otel-collector.test.ts | 34 +++++++++++++++++++ src/cli/operations/dev/otel/collector.ts | 5 +++ src/cli/operations/dev/otel/index.ts | 2 +- 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 src/cli/operations/dev/__tests__/otel-collector.test.ts diff --git a/src/cli/commands/dev/browser-mode.ts b/src/cli/commands/dev/browser-mode.ts index db18915c1..ba33d4e5d 100644 --- a/src/cli/commands/dev/browser-mode.ts +++ b/src/cli/commands/dev/browser-mode.ts @@ -3,7 +3,7 @@ import type { AgentCoreProjectSpec } from '../../../schema'; import { ANSI } from '../../constants'; import { isDeploySkippable } from '../../operations/deploy/change-detection'; import { getDevConfig, getDevSupportedAgents, loadDevEnv, loadProjectConfig } from '../../operations/dev'; -import { type OtelCollector, startOtelCollector } from '../../operations/dev/otel'; +import { type OtelCollector, hasExternalOtelEndpoint, startOtelCollector } from '../../operations/dev/otel'; import { type AgentInfo, type ListMemoryRecordsHandler, @@ -142,8 +142,15 @@ export async function launchBrowserDev(): Promise { } const configRoot = findConfigRoot(workingDir); - const persistTracesDir = path.join(configRoot ?? workingDir, '.cli', 'traces'); - const { collector, otelEnvVars } = await startOtelCollector(persistTracesDir); + let collector: OtelCollector | undefined; + let otelEnvVars: Record = {}; + + if (!hasExternalOtelEndpoint()) { + const persistTracesDir = path.join(configRoot ?? workingDir, '.cli', 'traces'); + const result = await startOtelCollector(persistTracesDir); + collector = result.collector; + otelEnvVars = result.otelEnvVars; + } await runBrowserMode({ workingDir, diff --git a/src/cli/commands/dev/command.tsx b/src/cli/commands/dev/command.tsx index 41176398b..05a3bbef6 100644 --- a/src/cli/commands/dev/command.tsx +++ b/src/cli/commands/dev/command.tsx @@ -28,7 +28,7 @@ import { loadProjectConfig, onShutdownSignal, } from '../../operations/dev'; -import { OtelCollector, startOtelCollector } from '../../operations/dev/otel'; +import { OtelCollector, hasExternalOtelEndpoint, startOtelCollector } from '../../operations/dev/otel'; import { withCommandRunTelemetry } from '../../telemetry/cli-command-run.js'; import { AgentProtocol, standardize } from '../../telemetry/schemas/common-shapes.js'; import { LayoutProvider } from '../../tui/context'; @@ -358,7 +358,7 @@ export const registerDev = (program: Command) => { let otelEnvVars: Record = {}; let collector: OtelCollector | undefined; - if (opts.traces !== false) { + if (opts.traces !== false && !hasExternalOtelEndpoint()) { const persistTracesDir = path.join(configRoot ?? workingDir, '.cli', 'traces'); const otelResult = await startOtelCollector(persistTracesDir); collector = otelResult.collector; diff --git a/src/cli/operations/dev/__tests__/otel-collector.test.ts b/src/cli/operations/dev/__tests__/otel-collector.test.ts new file mode 100644 index 000000000..20f895b42 --- /dev/null +++ b/src/cli/operations/dev/__tests__/otel-collector.test.ts @@ -0,0 +1,34 @@ +import { hasExternalOtelEndpoint } from '../otel'; +import { afterEach, describe, expect, it } from 'vitest'; + +describe('hasExternalOtelEndpoint', () => { + const savedEnv = { ...process.env }; + + afterEach(() => { + process.env = { ...savedEnv }; + }); + + it('returns false when no OTEL endpoint env vars are set', () => { + delete process.env.OTEL_EXPORTER_OTLP_ENDPOINT; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT; + expect(hasExternalOtelEndpoint()).toBe(false); + }); + + it('returns true when OTEL_EXPORTER_OTLP_ENDPOINT is set', () => { + process.env.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://localhost:4318'; + delete process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT; + expect(hasExternalOtelEndpoint()).toBe(true); + }); + + it('returns true when OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is set', () => { + delete process.env.OTEL_EXPORTER_OTLP_ENDPOINT; + process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://localhost:4318/v1/traces'; + expect(hasExternalOtelEndpoint()).toBe(true); + }); + + it('returns true when both are set', () => { + process.env.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://localhost:4318'; + process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = 'http://localhost:4318/v1/traces'; + expect(hasExternalOtelEndpoint()).toBe(true); + }); +}); diff --git a/src/cli/operations/dev/otel/collector.ts b/src/cli/operations/dev/otel/collector.ts index ee3ad7838..f54ba1a19 100644 --- a/src/cli/operations/dev/otel/collector.ts +++ b/src/cli/operations/dev/otel/collector.ts @@ -285,6 +285,11 @@ function readBodyAsBuffer(req: IncomingMessage): Promise { }); } +/** Returns true if the user has already configured an external OTLP endpoint. */ +export function hasExternalOtelEndpoint(): boolean { + return !!process.env.OTEL_EXPORTER_OTLP_ENDPOINT || !!process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT; +} + /** * Start an OTEL collector and return it along with the env vars agents need * to export traces to it. diff --git a/src/cli/operations/dev/otel/index.ts b/src/cli/operations/dev/otel/index.ts index 529967bd2..73f8997eb 100644 --- a/src/cli/operations/dev/otel/index.ts +++ b/src/cli/operations/dev/otel/index.ts @@ -1,2 +1,2 @@ -export { OtelCollector, startOtelCollector } from './collector'; +export { OtelCollector, hasExternalOtelEndpoint, startOtelCollector } from './collector'; export type { OtlpResourceSpan, OtlpResourceLog } from './types';