diff --git a/opencode/.opencode/plugin/phoenix-bridge.js b/opencode/.opencode/plugin/phoenix-bridge.js index 6a9adba..a5229d9 100644 --- a/opencode/.opencode/plugin/phoenix-bridge.js +++ b/opencode/.opencode/plugin/phoenix-bridge.js @@ -40,17 +40,8 @@ export const PhoenixBridge = async ({ project, directory, worktree }) => { // Phoenix 15.x serves OTLP/HTTP at /v1/traces on the same port as the UI // (6006). Earlier versions used a separate 4318 — override here if you // ever pin Phoenix < 15.0. - const phoenixEndpoint = + const endpoint = process.env.PHOENIX_OTLP_ENDPOINT || "http://framework:6006/v1/traces"; - // OpenLIT's OTLP/HTTP receiver, host-mapped to 4328 in - // pyinfra/framework/compose/openlit.yml. Set OPENLIT_OTLP_ENDPOINT to - // an empty string (or "off") to disable the secondary export. - const openlitEndpointRaw = - process.env.OPENLIT_OTLP_ENDPOINT === undefined - ? "http://framework:4328/v1/traces" - : process.env.OPENLIT_OTLP_ENDPOINT; - const openlitEndpoint = - openlitEndpointRaw && openlitEndpointRaw !== "off" ? openlitEndpointRaw : null; const serviceName = process.env.PHOENIX_SERVICE_NAME || "opencode"; // NodeSDK's `serviceName` constructor option is ignored in some // versions; setting OTEL_SERVICE_NAME forces the resource attribute @@ -58,15 +49,12 @@ export const PhoenixBridge = async ({ project, directory, worktree }) => { if (!process.env.OTEL_SERVICE_NAME) { process.env.OTEL_SERVICE_NAME = serviceName; } - log( - `phoenix=${phoenixEndpoint} openlit=${openlitEndpoint || "off"} serviceName=${serviceName}`, - ); + log(`endpoint=${endpoint} serviceName=${serviceName}`); // Dynamic imports so a missing dep produces a warning, not a freeze. let NodeSDK, OTLPTraceExporter, BatchSpanProcessor, - SimpleSpanProcessor, trace, context, diag, @@ -79,9 +67,7 @@ export const PhoenixBridge = async ({ project, directory, worktree }) => { ({ OTLPTraceExporter } = await import( "@opentelemetry/exporter-trace-otlp-proto" )); - ({ BatchSpanProcessor, SimpleSpanProcessor } = await import( - "@opentelemetry/sdk-trace-base" - )); + ({ BatchSpanProcessor } = await import("@opentelemetry/sdk-trace-base")); ({ trace, context, diag, DiagLogLevel } = await import( "@opentelemetry/api" )); @@ -116,18 +102,16 @@ export const PhoenixBridge = async ({ project, directory, worktree }) => { // NodeSDK accepts `serviceName` directly, sidestepping the Resource API // (which broke between @opentelemetry/resources v1.x and v2.x). - // BatchSpanProcessor batches spans and flushes every ~5s — fine in - // steady state. Each destination gets its own processor + exporter so - // a hiccup at one (e.g. OpenLIT down) doesn't block the other. - const spanProcessors = [ - new BatchSpanProcessor(new OTLPTraceExporter({ url: phoenixEndpoint })), - ]; - if (openlitEndpoint) { - spanProcessors.push( - new BatchSpanProcessor(new OTLPTraceExporter({ url: openlitEndpoint })), - ); - } - const sdk = new NodeSDK({ serviceName, spanProcessors }); + // Single Phoenix destination — the dual-export to OpenLIT regressed + // tool-call parsing in OpenCode (the failing OpenLIT exporter cascaded + // into the AI SDK telemetry pipeline). Re-add once OpenLIT has a + // proper OTLP receiver (otel-collector sidecar in openlit.yml). + const sdk = new NodeSDK({ + serviceName, + spanProcessors: [ + new BatchSpanProcessor(new OTLPTraceExporter({ url: endpoint })), + ], + }); sdk.start(); log("sdk.start() returned"); diff --git a/opencode/README.md b/opencode/README.md index 448e661..4388aae 100644 --- a/opencode/README.md +++ b/opencode/README.md @@ -75,17 +75,18 @@ The plugin uses `@opentelemetry/exporter-trace-otlp-proto` (not `-http`) because Phoenix's OTLP receiver only speaks protobuf — the JSON variant returns 415. -Spans are dual-exported: Phoenix (per-trace waterfall) and OpenLIT (fleet -metrics). Each destination has its own batch processor so a hiccup at -one doesn't block the other. +Spans go to Phoenix only. Earlier versions of this plugin dual-exported +to OpenLIT as well, but OpenLIT's container doesn't currently host an +OTLP receiver — the failing exporter cascaded into OpenCode's tool-call +parsing pipeline and broke tool use. Re-enable once `openlit.yml` adds +an `otel-collector` sidecar. Defaults can be overridden via env vars (set before launching opencode): | Variable | Default | Purpose | |---|---|---| | `PHOENIX_OTLP_ENDPOINT` | `http://framework:6006/v1/traces` | Phoenix HTTP target | -| `OPENLIT_OTLP_ENDPOINT` | `http://framework:4328/v1/traces` | OpenLIT HTTP target. Set to `off` to disable. | -| `PHOENIX_SERVICE_NAME` | `opencode` | Service / project name (both backends) | +| `PHOENIX_SERVICE_NAME` | `opencode` | Phoenix project name | | `PHOENIX_OTEL_DEBUG` | unset | `1` to surface OTel internal logs | ### Verifying