fix: propagate Reactor context to chunk event hooks in ReActAgent#1762
fix: propagate Reactor context to chunk event hooks in ReActAgent#1762Vinke2 wants to merge 2 commits into
Conversation
Three bare .subscribe() calls in ReActAgent (fireReasoningChunk, fireActingChunk, fireSummaryChunk) created new subscription chains without the parent Reactor context, causing ReasoningChunkEvent, ActingChunkEvent, and SummaryChunkEvent to have an empty ContextView in downstream hooks. Fix each with Flux.deferContextual + contextWrite to capture and propagate the parent context, matching the existing pattern used by executeToolCalls at line 2389-2391.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
AgentScopeJavaBot
left a comment
There was a problem hiding this comment.
🤖 AI Review
This is a well-targeted bug fix that correctly addresses Reactor context loss in three fire-and-forget .subscribe() calls within ReActAgent. The bare .subscribe() calls for fireReasoningChunk, fireActingChunk, and fireSummaryChunk created independent subscription chains that did not inherit the parent Reactor context, causing downstream hooks to see an empty ContextView — notably losing access to the SubagentEventBus. The fix applies Flux.deferContextual + contextWrite to capture and propagate the parent context, matching the existing pattern already established for executeToolCalls in the same file. The approach is correct, consistent, and minimal in scope.
| ctx -> | ||
| ctx.putAll( | ||
| parentCtx)) | ||
| .subscribe(); |
There was a problem hiding this comment.
[minor] The .subscribe() call remains bare — no error consumer is provided. If a hook's onEvent throws (or the Mono<Void> signals an error), Reactor will invoke onErrorDropped, silently swallowing the exception. This is a pre-existing issue, not introduced by this PR, but since you're already touching this line, consider adding a minimal error handler (e.g. .subscribe(v -> {}, e -> log.warn("Reasoning chunk hook failed", e))) to surface failures. Same applies to lines 2463 and 2975.
| mci.model().getModelName()) | ||
| .subscribe(); | ||
| } | ||
| return Flux.deferContextual( |
There was a problem hiding this comment.
[nit] Consider adding a brief inline comment explaining why Flux.deferContextual is needed here (e.g. // Propagate parent Reactor context so chunk hooks can access SubagentEventBus), similar to the existing comment at line 2402–2406 for executeToolCalls. This helps future readers understand the non-obvious context-propagation requirement without having to trace the full call chain.
AgentScopeJavaBot
left a comment
There was a problem hiding this comment.
🤖 AI Review
This is a well-targeted bug fix that correctly addresses Reactor context loss in three fire-and-forget .subscribe() calls within ReActAgent. The bare .subscribe() calls for fireReasoningChunk, fireActingChunk, and fireSummaryChunk created independent subscription chains that did not inherit the parent Reactor context, causing downstream hooks to see an empty ContextView — notably losing access to the SubagentEventBus. The fix applies Flux.deferContextual + contextWrite to capture and propagate the parent context, matching the existing pattern already established for executeToolCalls in the same file. The approach is correct, consistent, and minimal in scope.
| ctx -> | ||
| ctx.putAll( | ||
| parentCtx)) | ||
| .subscribe(); |
There was a problem hiding this comment.
[minor] The .subscribe() call remains bare — no error consumer is provided. If a hook's onEvent throws (or the Mono<Void> signals an error), Reactor will invoke onErrorDropped, silently swallowing the exception. This is a pre-existing issue, not introduced by this PR, but since you're already touching this line, consider adding a minimal error handler (e.g. .subscribe(v -> {}, e -> log.warn("Reasoning chunk hook failed", e))) to surface failures. Same applies to lines 2463 and 2975.
| mci.model().getModelName()) | ||
| .subscribe(); | ||
| } | ||
| return Flux.deferContextual( |
There was a problem hiding this comment.
[nit] Consider adding a brief inline comment explaining why Flux.deferContextual is needed here (e.g. // Propagate parent Reactor context so chunk hooks can access SubagentEventBus), similar to the existing comment at line 2402–2406 for executeToolCalls. This helps future readers understand the non-obvious context-propagation requirement without having to trace the full call chain.
Three bare .subscribe() calls in ReActAgent (fireReasoningChunk, fireActingChunk, fireSummaryChunk) created new subscription chains without the parent Reactor context, causing ReasoningChunkEvent, ActingChunkEvent, and SummaryChunkEvent to have an empty ContextView in downstream hooks.
Fix each with Flux.deferContextual + contextWrite to capture and propagate the parent context, matching the existing pattern used by executeToolCalls at line 2389-2391.
AgentScope-Java Version
[The version of AgentScope-Java you are working on, e.g. 1.0.12, check your pom.xml dependency version or run
mvn dependency:tree | grep agentscope-parent:pom(only mac/linux)]Description
[Please describe the background, purpose, changes made, and how to test this PR]
Checklist
Please check the following items before code is ready to be reviewed.
mvn spotless:applymvn test)