Skip to content

wrapAnthropic + LANGSMITH_TRACING_MODE=otel traces don't auto-resolve in Playground #2936

Description

Summary

When tracing direct Anthropic SDK calls with wrapAnthropic under LANGSMITH_TRACING_MODE=otel, the resulting ChatAnthropic runs land in LangSmith correctly but the Playground tab cannot auto-resolve the model dropdown — it falls back to the workspace default model. Equivalent runs produced by LangChain Python's ChatAnthropic (also via the OTel ingest path) DO resolve correctly, and wrapOpenAI + OTel under the same setup also resolves correctly. The gap appears to be Anthropic-specific.

For background, see the original (broader) report and bisection at #2923 — that issue covered both OpenAI and Anthropic, and the OpenAI half is healthy at the SDK level.

Environment

  • langsmith JS: 0.7.2 (latest at time of report)
  • @anthropic-ai/sdk: 0.95.x
  • Node 22 / TypeScript
  • OTel pipeline initialized via initializeOTEL() from langsmith/experimental/otel/setup
  • LANGSMITH_TRACING_MODE=otel, LANGSMITH_TRACING=true

Minimal reproduction

import { initializeOTEL } from "langsmith/experimental/otel/setup"
initializeOTEL()

import Anthropic from "@anthropic-ai/sdk"
import { wrapAnthropic } from "langsmith/wrappers/anthropic"

const anthropic = wrapAnthropic(new Anthropic())
await anthropic.messages.create({
  model: "claude-haiku-4-5",       // also tried "claude-haiku-4-5-20251001"
  max_tokens: 100,
  messages: [{ role: "user", content: "Say hi." }],
})

Open the resulting ChatAnthropic run in LangSmith → Playground tab.

Observed: model dropdown falls back to workspace default.
Expected: dropdown resolves to the Claude variant used.

The same harness with wrapOpenAI(new OpenAI()) + chat.completions.create resolves correctly — so the OTel pipeline, initializeOTEL, and Playground itself are all functional in this workspace. The variable is wrapAnthropic vs. wrapOpenAI.

What the trace contains

Tried two variants, both as root runs (no parent_run_id):

Variant extra.metadata.ls_model_name extra.invocation_params.model Playground
A: requested claude-haiku-4-5 (alias) claude-haiku-4-5 claude-haiku-4-5-20251001 (dated, from response) Falls back
B: requested claude-haiku-4-5-20251001 (dated) claude-haiku-4-5-20251001 claude-haiku-4-5-20251001 Falls back

Both traces have extra.metadata.ls_provider = "anthropic", ls_model_type = "chat", run_type = "llm", name = "ChatAnthropic" — matching the shape wrapOpenAI produces (just with ls_provider = "openai") where Playground auto-resolves. So the surface metadata looks complete from this side.

Contrast with LangChain Python ChatAnthropic under the same workspace and same OTel ingest path — those traces DO auto-resolve. So Playground UI supports Anthropic dropdown resolution, but the wrapAnthropic+OTel emission is missing whatever signal it relies on.

Asks

  1. Is wrapAnthropic + OTel + Playground intended to be supported the same way the OpenAI counterpart is? If not, calling that out in the wrapper docs would help.
  2. If yes, what attribute / metadata field is the LangChain Python ChatAnthropic path emitting that wrapAnthropic isn't? Once identified, either wrapAnthropic could emit it directly, or a documented metadata key (settable from the call site) would unblock OTel users.

Reproduction harness ready for any candidate fix.

Metadata

Metadata

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions