-
Notifications
You must be signed in to change notification settings - Fork 825
fix: propagate Reactor context to chunk event hooks in ReActAgent #1762
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2050,29 +2050,36 @@ private Flux<AgentEvent> modelCallStream( | |
| .concatMap( | ||
| chunk -> { | ||
| List<Msg> chunkMsgs = context.processChunk(chunk); | ||
| for (Msg msg : chunkMsgs) { | ||
| hookDispatcher | ||
| .fireReasoningChunk( | ||
| msg, | ||
| context, | ||
| mci.model().getModelName()) | ||
| .subscribe(); | ||
| } | ||
| return Flux.deferContextual( | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nit] Consider adding a brief inline comment explaining why |
||
| parentCtx -> { | ||
| for (Msg msg : chunkMsgs) { | ||
| hookDispatcher | ||
| .fireReasoningChunk( | ||
| msg, | ||
| context, | ||
| mci.model().getModelName()) | ||
| .contextWrite( | ||
| ctx -> | ||
| ctx.putAll( | ||
| parentCtx)) | ||
| .subscribe(); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor] The
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [minor] The |
||
| } | ||
|
|
||
| List<AgentEvent> events = new ArrayList<>(); | ||
| for (ContentBlock block : chunk.getContent()) { | ||
| emitBlockEvents( | ||
| block, | ||
| replyId, | ||
| context, | ||
| textStarted, | ||
| thinkingStarted, | ||
| withToolEvents | ||
| ? startedToolCalls | ||
| : new ConcurrentHashMap<>(), | ||
| events); | ||
| } | ||
| return Flux.fromIterable(events); | ||
| List<AgentEvent> events = new ArrayList<>(); | ||
| for (ContentBlock block : chunk.getContent()) { | ||
| emitBlockEvents( | ||
| block, | ||
| replyId, | ||
| context, | ||
| textStarted, | ||
| thinkingStarted, | ||
| withToolEvents | ||
| ? startedToolCalls | ||
| : new ConcurrentHashMap<>(), | ||
| events); | ||
| } | ||
| return Flux.fromIterable(events); | ||
| }); | ||
| }); | ||
|
|
||
| Flux<AgentEvent> endEvents = | ||
|
|
@@ -2449,6 +2456,10 @@ private Flux<AgentEvent> runToolBatch( | |
| hookDispatcher | ||
| .fireActingChunk( | ||
| toolUse, chunk, toolkit) | ||
| .contextWrite( | ||
| ctx -> | ||
| ctx.putAll( | ||
| parentCtx)) | ||
| .subscribe(); | ||
| }); | ||
|
|
||
|
|
@@ -2947,47 +2958,61 @@ private Flux<AgentEvent> summaryModelCallStream( | |
| .concatMap( | ||
| chunk -> { | ||
| List<Msg> chunkMsgs = context.processChunk(chunk); | ||
| for (Msg msg : chunkMsgs) { | ||
| hookDispatcher | ||
| .fireSummaryChunk( | ||
| msg, | ||
| context, | ||
| hookOptions, | ||
| model.getModelName()) | ||
| .subscribe(); | ||
| } | ||
| return Flux.deferContextual( | ||
| parentCtx -> { | ||
| for (Msg msg : chunkMsgs) { | ||
| hookDispatcher | ||
| .fireSummaryChunk( | ||
| msg, | ||
| context, | ||
| hookOptions, | ||
| model.getModelName()) | ||
| .contextWrite( | ||
| ctx -> | ||
| ctx.putAll( | ||
| parentCtx)) | ||
| .subscribe(); | ||
| } | ||
|
|
||
| List<AgentEvent> events = new ArrayList<>(); | ||
| for (ContentBlock block : chunk.getContent()) { | ||
| if (block instanceof TextBlock tb) { | ||
| if (textStarted.compareAndSet(false, true)) { | ||
| events.add( | ||
| new TextBlockStartEvent( | ||
| replyId, "text")); | ||
| } | ||
| if (tb.getText() != null | ||
| && !tb.getText().isEmpty()) { | ||
| events.add( | ||
| new TextBlockDeltaEvent( | ||
| replyId, "text", tb.getText())); | ||
| } | ||
| } else if (block instanceof ThinkingBlock tb) { | ||
| if (thinkingStarted.compareAndSet(false, true)) { | ||
| events.add( | ||
| new ThinkingBlockStartEvent( | ||
| replyId, "thinking")); | ||
| } | ||
| if (tb.getThinking() != null | ||
| && !tb.getThinking().isEmpty()) { | ||
| events.add( | ||
| new ThinkingBlockDeltaEvent( | ||
| replyId, | ||
| "thinking", | ||
| tb.getThinking())); | ||
| } | ||
| } | ||
| } | ||
| return Flux.fromIterable(events); | ||
| List<AgentEvent> events = new ArrayList<>(); | ||
| for (ContentBlock block : chunk.getContent()) { | ||
| if (block instanceof TextBlock tb) { | ||
| if (textStarted.compareAndSet( | ||
| false, true)) { | ||
| events.add( | ||
| new TextBlockStartEvent( | ||
| replyId, "text")); | ||
| } | ||
| if (tb.getText() != null | ||
| && !tb.getText().isEmpty()) { | ||
| events.add( | ||
| new TextBlockDeltaEvent( | ||
| replyId, | ||
| "text", | ||
| tb.getText())); | ||
| } | ||
| } else if (block | ||
| instanceof ThinkingBlock tb) { | ||
| if (thinkingStarted.compareAndSet( | ||
| false, true)) { | ||
| events.add( | ||
| new ThinkingBlockStartEvent( | ||
| replyId, | ||
| "thinking")); | ||
| } | ||
| if (tb.getThinking() != null | ||
| && !tb.getThinking() | ||
| .isEmpty()) { | ||
| events.add( | ||
| new ThinkingBlockDeltaEvent( | ||
| replyId, | ||
| "thinking", | ||
| tb.getThinking())); | ||
| } | ||
| } | ||
| } | ||
| return Flux.fromIterable(events); | ||
| }); | ||
| }); | ||
|
|
||
| Flux<AgentEvent> endEvents = | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] Consider adding a brief inline comment explaining why
Flux.deferContextualis needed here (e.g.// Propagate parent Reactor context so chunk hooks can access SubagentEventBus), similar to the existing comment at line 2402–2406 forexecuteToolCalls. This helps future readers understand the non-obvious context-propagation requirement without having to trace the full call chain.