Skip to content

Add QwenPaw 2.x runtime support - #994

Open
123liuziming wants to merge 7 commits into
open-telemetry:mainfrom
123liuziming:codex/qwenpaw-2x-support
Open

123liuziming wants to merge 7 commits into
open-telemetry:mainfrom
123liuziming:codex/qwenpaw-2x-support

Conversation

@123liuziming

@123liuziming 123liuziming commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Adds QwenPaw 2.x Runtime.run support to the existing QwenPawInstrumentor, retaining the original 1.x AgentRunner.query_handler instrumentation. Captures streamed envelopes, propagates conversation IDs, and tests both runtime generations.

Follow-up to #969.

Validation on current main: QwenPaw 1.1.0, 1.1.12.post3, 2.0.0, and 2.2.2.post1 pass all 10 Weaver conformance scenarios with no skips. Real DashScope qwen-plus requests on all four versions pass span/message/duration assertions and Weaver live-check with zero violations in Kubernetes. Pre-commit and README rendering pass.

WIP: requires unreleased util-genai 1.4b0. The 1.1.0 live environment uses OpenAI SDK 2.x because its pinned AgentScope fails to parse streams with OpenAI SDK 3.x. The combined workspace retains QwenPaw 1.x for CrewAI dependency compatibility; isolated environments test both major versions.

@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Waiting on the author · refreshed 2026-11-03 06:34 UTC

Resolve merge conflicts.

Respond to 4 review items (e.g. link a commit, explain why not, ask a follow-up):

  • Inline threads: 1, 2, 3, 4
Status above doesn't look right?
  • Just replied or pushed? Anything around or after the refresh time above may not be picked up yet — give it a few minutes.
  • Should this be with reviewers? Comment /dashboard route:reviewers to route it to them.
  • Anything wrong — including the routing? Report it with what you expected; it helps us improve the dashboard.

Retain hook context across stream reads, merge partial message snapshots, and use shared media conversion. Cover both runtime generations and keep fixture-specific assertions in unit tests.

Assisted-by: GPT-6.1 Sol
@123liuziming 123liuziming changed the title [WIP] Add QwenPaw 2.x runtime support Add QwenPaw 2.x runtime support Nov 1, 2026
@123liuziming
123liuziming marked this pull request as ready for review November 1, 2026 09:34
Copilot AI balanced review requested due to automatic review settings November 1, 2026 09:34
@123liuziming
123liuziming requested a review from a team as a code owner November 1, 2026 09:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Snapshot capture overwrites valid media content when text and media block indexes collide, causing finished spans and completion hooks to lose content.

1 open issue
What changed in this PR

Extends the existing QwenPaw instrumentation to support the 2.x Runtime.run entry point while retaining 1.x runner support.

Changes:

  • Adds lazy runtime tracing, conversation propagation, and streamed message capture.
  • Expands unit and conformance coverage across both runtime generations.
  • Updates dependency ranges, examples, and documentation for 2.x support.

Paths below are relative to instrumentation/opentelemetry-instrumentation-genai-qwenpaw/, except those marked repository root.

File Description
uv.lock (repository root) Updates the supported QwenPaw range.
tox.ini (repository root) Adds version-specific test environments and shared dependency constraints.
README.md (repository root) Updates the instrumentation compatibility table.
tests/​test_runtime.py Tests runtime tracing, lifecycle, context, and message capture.
tests/​test_message_mapping.py Uses structured user-message content.
tests/​test_instrumentor.py Adjusts dependency and instrumentation lifecycle tests.
tests/​test_instrumentation_scope.py Removes the legacy-runner fixture requirement.
tests/​test_conformance.py Registers error and rich-message scenarios.
tests/​requirements.v2.txt Adds the QwenPaw 2.0.0 test dependencies.
tests/​requirements.v1.txt Adds latest-1.x test dependencies.
tests/​requirements.oldest.txt Uses the unreleased workspace utility package.
tests/​requirements.latest.txt Moves latest-version testing to QwenPaw 2.x.
tests/​harness.py Adds runtime and request construction helpers.
tests/​conftest.py Selects fixtures by runtime generation.
tests/​conformance/​runtime_messages.py Exercises rich messages through runtime envelopes.
tests/​conformance/​runtime_error.py Exercises failed turns in both generations.
tests/​conformance/​invoke_agent.py Supports successful turns in both generations.
src/​opentelemetry/​instrumentation/​genai/​qwenpaw/​runtime.py Implements lazy runtime tracing and envelope capture.
src/​opentelemetry/​instrumentation/​genai/​qwenpaw/​package.py Broadens declared QwenPaw compatibility.
src/​opentelemetry/​instrumentation/​genai/​qwenpaw/​__init__.py Selects and unwraps version-specific instrumentation.
README.rst Documents runtime support, captured content, and test environments.
pyproject.toml Broadens QwenPaw support and raises the utility dependency floor.
examples/​zero-code/​requirements.txt Updates automatic-instrumentation examples to 2.x.
examples/​manual/​requirements.txt Updates manual-instrumentation examples to 2.x.
.changelog/​994.added Records added 2.x support and retained 1.x compatibility.

Review effort: Balanced

Distinguish text and media block indexes and preserve snapshot ordering without dropping unfinished content. Cover complete, early-close, and failed streams using real QwenPaw envelopes.

Assisted-by: GPT-6.1 Sol
Comment on lines +276 to +284
arguments = (
self._self_tool_arguments.get(message_id, "") + delta
)
self._self_tool_arguments[message_id] = arguments
part = ToolCallRequestPart(
name=previous.name,
id=previous.id,
arguments=_json_value(arguments),
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This re-concatenates and re-parses (json.loads on partial JSON, which mostly raises) the whole argument string on every delta, so a long tool call is quadratic. Could we just append the delta here and parse once when the message snapshot arrives or in _on_stream_end/_on_stream_error?

and isinstance(previous, (TextPart, ReasoningPart))
and part.type == previous.type
):
part = type(part)(content=previous.content + part.content)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for text: each token delta copies the full accumulated text (and rebuilds the OutputMessage), which is O(n^2) on long replies. Collecting deltas in a list per block and joining at finalization would keep the per-chunk cost constant.

_RUNTIME_MODULE = "qwenpaw.runtime.runtime"


def _runtime_v2() -> bool:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: keying off distribution metadata breaks with skip_dep_check=True or a source install (PackageNotFoundError in _instrument/_uninstrument). Feature-detecting the entry point avoids that:

def _runtime_v2() -> bool:
    return find_spec("qwenpaw.runtime.runtime") is not None

Comment on lines +48 to +49
Version 2.x support requires ``opentelemetry-util-genai`` 1.4b0 or newer
(``1.4b0.dev`` from this workspace during development). QwenPaw 2.x requires Python >= 3.11,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the workspace dev note will end up on PyPI.

Suggested change
Version 2.x support requires ``opentelemetry-util-genai`` 1.4b0 or newer
(``1.4b0.dev`` from this workspace during development). QwenPaw 2.x requires Python >= 3.11,
Version 2.x support requires ``opentelemetry-util-genai`` 1.4b0 or newer.
QwenPaw 2.x requires Python >= 3.11,

@lmolkova lmolkova mentioned this pull request Nov 3, 2026
1 task

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants