Describe the bug
In internal/llminternal/base_flow.go, runOneStep currently yields a generated adk_request_confirmation event before yielding the merged function-response event returned from tool execution:
toolConfirmationEvent := generateRequestConfirmationEvent(ctx, modelResponseEvent, ev)
if toolConfirmationEvent != nil {
if !yield(toolConfirmationEvent, nil) {
return
}
}
if !yield(ev, nil) {
return
}
This ordering can lose function-response history for consumers that intentionally stop iterating when they receive a tool confirmation request so they can pause execution and ask a user to approve or reject the pending action.
In that flow, the confirmation event is yielded and persisted, but the function-response event (ev) may never be yielded. The session history is then incomplete when execution resumes.
To Reproduce
- Create an agent with at least one regular tool and one tool that requests confirmation.
- Run the agent through a consumer that pauses as soon as it receives an
adk_request_confirmation event.
- Let the confirmed tool path generate both:
- a normal function-response event for already executed tools
- an
adk_request_confirmation event for the pending tool approval
- Stop consuming the iterator after the confirmation event, as a UI or human-in-the-loop integration commonly would.
- Inspect the session history before resuming.
Expected behavior
All completed tool function responses should be yielded and persisted before the confirmation request is yielded. A consumer that pauses on the confirmation boundary should still have complete function-response history for work that already happened.
Observed behavior
The confirmation request is yielded first. If the consumer pauses immediately, the merged function-response event is not yielded and may not be persisted to the session.
Proposed fix
Yield the merged function-response event before yielding the generated adk_request_confirmation event:
toolConfirmationEvent := generateRequestConfirmationEvent(ctx, modelResponseEvent, ev)
if !yield(ev, nil) {
return
}
if toolConfirmationEvent != nil {
if !yield(toolConfirmationEvent, nil) {
return
}
}
This preserves completed tool results before entering the human-confirmation pause.
Testing
Add a runner-level regression test where the consumer stops after receiving adk_request_confirmation. The test should assert that the function-response event is yielded before the confirmation request so it can be persisted even when the consumer pauses at the confirmation boundary.
Alignment with adk-python
This is specific to ADK Go's runner iterator/yield ordering. The cross-language invariant is that completed tool results should be persisted before execution pauses for human confirmation.
Describe the bug
In
internal/llminternal/base_flow.go,runOneStepcurrently yields a generatedadk_request_confirmationevent before yielding the merged function-response event returned from tool execution:This ordering can lose function-response history for consumers that intentionally stop iterating when they receive a tool confirmation request so they can pause execution and ask a user to approve or reject the pending action.
In that flow, the confirmation event is yielded and persisted, but the function-response event (
ev) may never be yielded. The session history is then incomplete when execution resumes.To Reproduce
adk_request_confirmationevent.adk_request_confirmationevent for the pending tool approvalExpected behavior
All completed tool function responses should be yielded and persisted before the confirmation request is yielded. A consumer that pauses on the confirmation boundary should still have complete function-response history for work that already happened.
Observed behavior
The confirmation request is yielded first. If the consumer pauses immediately, the merged function-response event is not yielded and may not be persisted to the session.
Proposed fix
Yield the merged function-response event before yielding the generated
adk_request_confirmationevent:This preserves completed tool results before entering the human-confirmation pause.
Testing
Add a runner-level regression test where the consumer stops after receiving
adk_request_confirmation. The test should assert that the function-response event is yielded before the confirmation request so it can be persisted even when the consumer pauses at the confirmation boundary.Alignment with adk-python
This is specific to ADK Go's runner iterator/yield ordering. The cross-language invariant is that completed tool results should be persisted before execution pauses for human confirmation.