feat(langchain): emit GenAI request attributes - #213
feat(langchain): emit GenAI request attributes#213Jackson Weber (JacksonWeber) wants to merge 8 commits into
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eb3eb7d to
02f1d14
Compare
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds LangChain instrumentation support for emitting GenAI request-related OpenTelemetry attributes (including output type) from extra.invocation_params, with validation/normalization and expanded unit test coverage.
Changes:
- Introduces new GenAI semantic convention constants for request parameters and
gen_ai.output.type. - Adds
setRequestAttributesto LangChain utils and wires it into the LangChain tracer. - Expands unit tests to cover mapping/normalization and exporter payload preservation.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| test/internal/unit/genai/langchain/utils.test.ts | Adds focused unit tests for setRequestAttributes mapping/validation behavior. |
| test/internal/unit/genai/langchain/tracer.test.ts | Verifies tracer emits request attributes/output type onto spans. |
| test/internal/unit/a365/agent365Exporter.test.ts | Ensures A365 exporter payload preserves new GenAI attributes. |
| src/genai/semconv.ts | Defines new gen_ai.* attribute constants used by instrumentation. |
| src/genai/instrumentations/langchain/utils.ts | Implements request attribute extraction, normalization, and type validation. |
| src/genai/instrumentations/langchain/tracer.ts | Hooks request attribute setting into span creation flow. |
| CHANGELOG.md | Documents the new instrumentation feature under Unreleased. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| ## [Unreleased] | ||
|
|
||
| ### Features Added | ||
| - Emit `gen_ai.output.type` and available GenAI request parameters on LangChain chat spans. |
There was a problem hiding this comment.
Link to the PR is missing.
There was a problem hiding this comment.
Link is added and it looks like the PR change fixed the other CI jobs not running as well.
There was a problem hiding this comment.
I believe that is comperehensive from checking the pr-validation.yml We just have an ES-lint and testing the two LTS versions of Node.js (22 & 24) that we currently support. Although this might not be a bad time to add a Node 26 check as well.
There was a problem hiding this comment.
Nevermind, looks like 26 is current, not LTS yet.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| speech: "speech", | ||
| }; | ||
|
|
||
| function normalizeOutputType(value: unknown): string | undefined { |
There was a problem hiding this comment.
Are none of these helper functions available upstream which we could reuse here?
There was a problem hiding this comment.
LangChain doesn’t provide public helpers for normalizing these provider-specific invocation parameters and OpenTelemetry only validates values after they’ve been normalized, so we still need the small local coercion helpers here.
There was a problem hiding this comment.
So how does opentelemetry (genai js) normalize the values? When I mentioned upstream in my original comment, I was referring to the upstream langchain instrumentation, sorry for the confusion.
There was a problem hiding this comment.
That makes sense. The upstream otel langchain instrumentation doesn't currently emit these attributes, so it doesn't have any normalization logic for them.
Makes sense that we can try to implement these upstream there instead of only in our vendored implementation. But we don't consume that package anywhere in this project, so is the expectation that customers just pull the upstream OTel JS langchain instrumentation to use alongside this distro?
| return strings.length === value.length && strings.length > 0 ? strings : undefined; | ||
| } | ||
|
|
||
| const OUTPUT_TYPES: Readonly<Record<string, string>> = { |
There was a problem hiding this comment.
Per semconv, this is supported list of output types - gen_ai.output.type. Are we planning to support these extras in the distro only? Also, you are missing the image type.
There was a problem hiding this comment.
I've updated the list to support the image type and unify with what's described in sem conv. Does it make sense to support these in our vendored langchain instrumentation for now and then work on supporting them upstream in the future?
There was a problem hiding this comment.
I would suggest the other way around, first upstream (semconv repo) and then support them in the distro. Are there any specific scenarios where you would want to add support for the types not listed in semconv?
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| const seed = integer(firstDefined(params, ["seed"])); | ||
| if (seed !== undefined) span.setAttribute(ATTR_GEN_AI_REQUEST_SEED, seed); | ||
|
|
||
| const topK = integer(firstDefined(params, ["top_k", "topK"])); |
There was a problem hiding this comment.
A little confused why are we supporting the camelCase, shouldn't the attributes satisfy the _ convention?
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This reverts commit 0110be1.
Match upstream OpenTelemetry GenAI instrumentations by accepting typed provider parameters without coercing numeric or boolean strings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>



Summary
extra.invocation_paramson chat spansgen_ai.output.typefrom explicit output types and structured response formatsAttributes
gen_ai.output.typegen_ai.request.temperaturegen_ai.request.top_p/gen_ai.request.top_kgen_ai.request.max_tokensValidation
@langchain/openai1.5.5 and@langchain/core1.2.3; the ingested span retained expected typed values for temperature, top-p, max tokens, penalties, seed, stop sequences, stream, and JSON output typeA365 compatibility
gen_ai.request.temperature,gen_ai.request.top_p, andgen_ai.request.max_tokensare already defined by the upstream Agent365 JS constantsUpstream assessment
Current LangChain.js exposes these values as raw callback
invocation_paramsbut does not map them to OpenTelemetrygen_ai.*attributes, so the distro remains the appropriate implementation layer.