feat: add opencode-ai instrumentation (LAM-1513)#287
Open
laminar-coding-agent[bot] wants to merge 1 commit into
Open
feat: add opencode-ai instrumentation (LAM-1513)#287laminar-coding-agent[bot] wants to merge 1 commit into
laminar-coding-agent[bot] wants to merge 1 commit into
Conversation
Mirrors the lmnr-ts OpencodeInstrumentation: wraps SessionResource.chat (sync + async) and appends a synthetic text part carrying the current Laminar span context, so the Opencode server can re-parent the downstream LLM span onto the caller's trace. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
OpencodeInstrumentationto Python. Wrapsopencode_ai.resources.session.SessionResource.chatand its async counterpart so that when a Laminar span context is active, a synthetic{type: "text", text: "", synthetic: True, ignored: True, metadata: {lmnrSpanContext: ...}}part is appended to the outgoingparts. The Opencode server forwards the metadata back so the downstream LLM span re-parents onto the caller's trace.Instruments.OPENCODEinto the enum,INSTRUMENTATION_INITIALIZERS, and a newOpencodeInstrumentorInitializer(only activates whenopencode-aiis installed).opencode-ai==0.1.0a36to[dependency-groups].devand pins the_instrumentsspec toopencode-ai >= 0.1.0a0(the SDK only ships pre-release alphas right now — a plain>= 0.1.0failsBaseInstrumentor.instrument()'s version check and silently leaveschatunwrapped).tests/test_instrumentations/test_opencode/driving the realopencode_aiclient overhttpx.MockTransport, mirroring the TS suite'snock-based assertions (span-context injection sync + async, no-injection-without-active-span, preserves existing parts, does not mutate caller's list, trace_id matches the observe span, nested observe uses the innermost span, response pass-through, sync/async coexistence).Test plan
uv run pytest tests/test_instrumentations/test_opencode/ -v— 10/10 passuv run pytest tests/test_instrument_initializers.py— passes (enum/initializer length check)test_langchain*cases are pre-existing onmain(verified withgit stash).🤖 Generated with Claude Code
Note
Medium Risk
Moderate risk: introduces new runtime monkey-wrapping of
opencode_aisync/asyncSessionResource.chat, which could affect request payloads and compatibility as the upstream SDK evolves; changes are gated on package presence and covered by targeted tests.Overview
Adds a new
opencode-aiOpenTelemetry instrumentor that wrapsSessionResource.chat(sync + async) to conditionally inject a syntheticpartsentry containing the active Laminar span context, enabling downstream Opencode model spans to re-parent onto the caller’s trace.Wires the new instrument into
Instruments/initializer registration (activated only whenopencode-aiis installed), pinsopencode-ai==0.1.0a36for dev testing, and adds a dedicated test suite validating injection behavior (including no-op without an active span, no mutation of callerparts, nested span selection, response passthrough, and sync/async coexistence).Reviewed by Cursor Bugbot for commit 062b448. Bugbot is set up for automated code reviews on this repo. Configure here.