Skip to content

fix(agentscope): support QwenPaw v2 task handoffs - #255

Merged
sipercai merged 5 commits into
mainfrom
fix/agentscope-v2-cross-context-round
Jul 30, 2026
Merged

fix(agentscope): support QwenPaw v2 task handoffs#255
sipercai merged 5 commits into
mainfrom
fix/agentscope-v2-cross-context-round

Conversation

@sipercai

@sipercai sipercai commented Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Description

QwenPaw 2 advances the AgentScope reply async generator through a heartbeat
layer that may call __anext__() and aclose() from different
asyncio.Task contexts. The original AgentScope v2 instrumentation kept
OpenTelemetry and probe-owned ContextVar.Token values across yields, so a
later Task could attempt to reset a token created by another Context.

QwenPaw 2 also closes downstream AgentScope iterators when its ENTRY stream is
closed. Before this follow-up, AgentScope treated the resulting
GeneratorExit as a tool/ReAct failure, and nested LLM/STEP/TOOL spans could
lose the active AGENT parent after a Task handoff.

This change:

  • removes the probe-owned ReAct round ContextVar lifecycle and derives the
    1-based round from AgentScope v2's agent.state.cur_iter;
  • instruments QwenPaw 2 qwenpaw.runtime.runtime.Runtime.run while preserving
    QwenPaw 1 and CoPaw compatibility;
  • keeps ENTRY, AGENT, ReAct, and tool contexts attached only while one
    underlying __anext__() or aclose() is executing, then detaches them in
    the same Task before yielding to the caller;
  • treats GeneratorExit from a normal downstream aclose() as successful
    completion while preserving a real error raised by the downstream close;
  • restores the QwenPaw ENTRY context while it closes the downstream iterator;
  • uses the shared hook_advice fail-open boundary for probe-owned lifecycle
    operations while leaving business iteration and close operations outside
    advice;
  • records QwenPaw 2 TTFT only after a non-empty text/tool delta or completed
    assistant output, ignoring response-created, in-progress, and heartbeat
    envelopes;
  • preserves the original business result, yielded chunks, cancellation, and
    exception identity when instrumentation callbacks fail;
  • adds a combined QwenPaw Runtime plus real AgentScope v2 middleware regression
    that validates ENTRY -> AGENT -> LLM and
    ENTRY -> AGENT -> STEP -> TOOL across fresh Tasks;
  • pins mcp<2 only in the AgentScope-oldest and QwenPaw v1/legacy test
    environments because those framework versions use the MCP 1.x API.

This addresses the cross-Context crash, missing QwenPaw 2 request root,
incorrect GeneratorExit error statuses, and broken nested AgentScope
parentage reported in #252. Duplicate instrumentation remains an independent
follow-up and is not claimed as fixed here.

Addresses #252

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

  • Reproduced the old behavior on the previous PR head: successful tool and
    ReAct spans ended as ERROR / GeneratorExit, the nested child was parented
    directly to ENTRY, and cross-Task token detach was logged.
  • Re-ran the same lifecycle reproduction on the follow-up: tool and ReAct
    spans end as UNSET, the child is parented to AGENT, and
    child_parent_is_agent=true.
  • AgentScope latest:
    py311/py312/py313-test-loongsuite-instrumentation-agentscope-latest
    24 passed per environment.
  • AgentScope oldest:
    py310/py313-test-loongsuite-instrumentation-agentscope-oldest
    94 passed per environment.
  • QwenPaw 2.0.1:
    py312-test-loongsuite-instrumentation-qwenpaw-latest
    22 passed, 4 skipped.
  • QwenPaw 1 and CoPaw legacy:
    py310-test-loongsuite-instrumentation-qwenpaw-{v1,legacy}
    14 passed, 1 skipped per environment.
  • Fresh-cache tox -e precommit.
  • Static LoongSuite PR readiness checker, branch-diff privacy scan,
    cassette privacy scan, and git diff --check.
  • Weaver live-check of emitted AgentScope AGENT/LLM/STEP/TOOL spans:
    no violations; only existing development-stability and provider-enum advice.

Validation Evidence

Spec and Scope

Local Checks

Check Command Result Notes
Static readiness python3 "$PIPELINE_SKILL_DIR/scripts/check_loongsuite_pr_readiness.py" --repo . pass No readiness errors or warnings.
Precommit PRE_COMMIT_HOME="$(mktemp -d /tmp/loongsuite-precommit.XXXXXX)" uvx --from 'tox<5' tox -e precommit pass Fresh hook cache; no hook-generated changes.
AgentScope latest uvx --from 'tox<5' tox -c tox-loongsuite.ini -p auto -e py311-test-loongsuite-instrumentation-agentscope-latest,py312-test-loongsuite-instrumentation-agentscope-latest,py313-test-loongsuite-instrumentation-agentscope-latest pass 24 passed per environment.
AgentScope oldest uvx --from 'tox<5' tox -c tox-loongsuite.ini -p auto -e py310-test-loongsuite-instrumentation-agentscope-oldest,py313-test-loongsuite-instrumentation-agentscope-oldest pass 94 passed per environment.
QwenPaw latest uvx --from 'tox<5' tox -c tox-loongsuite.ini -e py312-test-loongsuite-instrumentation-qwenpaw-latest pass 22 passed, 4 skipped.
QwenPaw compatibility uvx --from 'tox<5' tox -c tox-loongsuite.ini -p auto -e py310-test-loongsuite-instrumentation-qwenpaw-v1,py310-test-loongsuite-instrumentation-qwenpaw-legacy pass 14 passed, 1 skipped per environment.
Plugin lint uvx --from 'tox<5' tox -c tox-loongsuite.ini -p auto -e lint-loongsuite-instrumentation-agentscope,lint-loongsuite-instrumentation-qwenpaw pass Both ruff environments passed.
Privacy scan git diff origin/main -- . | rg -q '<credential-and-local-path-patterns>' pass No credentials, tokens, private paths, or user-name matches.
Independent review bounded implementation review partial Blocking lifecycle and compatibility findings were applied; the final automated refresh timed out and is not counted as a pass.

Business Isolation

Scenario Status Evidence
prepare/start fault pass Injected Agent start failure preserves the business stream and leaves no current-span leak.
response mapping/stop fault pass Finish callback failure does not replace the business result.
fail callback fault pass The original business exception object remains observable.
normal early close/GeneratorExit pass Fresh-Task aclose() closes downstream once; ENTRY/AGENT/STEP/TOOL remain UNSET.
downstream close error pass The original close exception object is re-raised and affected spans are marked ERROR with the real error type.
cancellation pass Cancellation identity is preserved and Agent cleanup completes.
cross-task stream pass __anext__() and aclose() run in fresh Tasks without an instrumentation detach warning or current-span leak.
clean sibling after fault pass Sequential requests finish as separate root traces with no leaked parent.

Functional Matrix

Scenario Status Evidence
non-streaming model call pass AgentScope v2 focused model-call tests.
streaming reply/tool flow pass Cross-Task reply and acting async-generator tests.
agent/tool/ReAct pass Combined QwenPaw Runtime plus real AgentScope middleware test emits AGENT, LLM, STEP, and TOOL.
error path pass Business iteration errors, cancellation, callback faults, and close errors are covered.
concurrency/context isolation pass Fresh Tasks advance and close streams; concurrent tools share the same agent iteration round.
dependency bounds pass AgentScope latest/oldest plus QwenPaw latest/v1/legacy environments pass.

Real E2E Matrix

Scenario Status Command or Demo Evidence
non-streaming N/A QwenPaw 2 Runtime.run is an async iterator only. The final-message-only path is covered against installed QwenPaw 2.0.1.
streaming blocked LOONGSUITE_PYTHON_SITE_BOOTSTRAP=True OTEL_TRACES_EXPORTER=console OTEL_METRICS_EXPORTER=none qwenpaw app A disposable provider-backed workspace was not configured for this follow-up.
concurrency blocked Same app command, then submit concurrent turns. Cross-Task isolation is covered deterministically; provider-backed concurrency was not rerun.
agent/tool/ReAct blocked Same app command, then submit a tool-using turn. The real middleware composition is covered locally; provider-backed tool execution was not rerun.
tool-heavy blocked Same app command, then submit a bounded multi-tool turn. Requires a configured tool-capable workspace.
error path blocked Same app command with a provider/tool failure fixture. Business and probe error isolation are covered locally; provider-backed failure was not rerun.

Telemetry and Weaver

Check Status Command or Artifact Notes
Span tree / span kinds pass Combined QwenPaw Runtime plus AgentScope middleware regression Validates ENTRY -> AGENT -> LLM and ENTRY -> AGENT -> STEP -> TOOL.
Normal-close statuses pass Cross-Task combined regression ENTRY, AGENT, LLM, STEP, and TOOL remain UNSET; no error.type.
Error statuses pass Downstream close-error regressions Preserves the real exception and records ValueError.
Context isolation pass Fresh-Task __anext__()/aclose() regressions No instrumentation detach log or current-span leak.
Weaver live-check pass weaver registry live-check -r <registry>/model --advice-profile loongsuite-genai --input-format json ... AgentScope AGENT/LLM/STEP/TOOL sample had no violations. Development-stability and existing agentscope provider-enum advice remain.
QwenPaw custom attributes follow-up Full ENTRY sample Existing qwenpaw.* and copaw.* custom attributes still need registry registration or a compatibility decision.

CI

  • GitHub checks: all checks passed on remote head 3ffb1c50.
  • The local lifecycle follow-up commit is not yet pushed; pushing it will
    trigger a fresh CI run.
  • Known unrelated failures: none.
  • Merge state remains Draft / review required.

Does This PR Require a Core Repo Change?

  • Yes. - Link to PR:
  • No.

Checklist:

See contributing.md for styleguide, changelog guidelines, and more.

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added
  • Documentation has been updated

@ralf0131 ralf0131 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Summary

Well-structured fix for cross-Task context safety in AgentScope v2 and QwenPaw v2 instrumentation. The refactoring correctly addresses the GeneratorExit handling, context token lifecycle, and nested span parentage issues reported in #252.

Review Highlights

  • Correctness: Proper context attach/detach pattern using dataclasses (_AgentState, _ActingState, _EntryState) to track state across async boundaries. The hook_advice fail-open boundary is correctly applied to probe-owned lifecycle operations.
  • GeneratorExit handling: Distinguishes between normal downstream aclose() (successful completion) and real errors — critical for QwenPaw v2's heartbeat layer.
  • Backward compatibility: Preserves QwenPaw 1 and CoPaw compatibility while adding v2 support.
  • Tests: Comprehensive regression tests validate ENTRY -> AGENT -> LLM and ENTRY -> AGENT -> STEP -> TOOL across fresh Tasks.

Minor Note

The large diff is mostly CI workflow configuration (1500+ lines). Core logic changes are focused and well-scoped.


Automated review by github-manager-bot

@sipercai
sipercai merged commit be07f6b into main Jul 30, 2026
40 checks passed
@sipercai
sipercai deleted the fix/agentscope-v2-cross-context-round branch July 30, 2026 11:34
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.

4 participants