What happened?
In ACP mode, when a tool requires confirmation, runTool() sends session/request_permission but never sends a preceding tool_call session update. The if/else in runTool treats them as mutually exclusive:
- If
confirmationDetails is truthy: sends request_permission only (no tool_call)
- If
confirmationDetails is falsy: sends tool_call only (no request_permission)
After permission is granted, it sends tool_call_update (completed), but the client never saw a tool_call (pending) to associate it with.
This is easiest to reproduce with MCP tools from session/new. Since ACP doesn't pass trust to MCPServerConfig, MCP tools always need confirmation via the policy engine. The debug log shows the expected path:
[MESSAGE_BUS] publish: {"type":"tool-confirmation-request",...}
[PolicyEngine.check] toolCall.name: mcp_lookup_get_code, stringifiedArgs: {}
[PolicyEngine.check] NO MATCH - using default decision: ask_user
But the client only sees:
{"sessionUpdate": "tool_call_update", "status": "completed", "toolCallId": "mcp_lookup_get_code-..."}
No tool_call with status pending or in_progress is ever emitted.
What did you expect to happen?
Per the ACP tool calls spec, the Agent SHOULD report a tool_call session update when the model requests a tool invocation. This should happen before requesting permission, so the client can track the tool call lifecycle:
tool_call (pending) -> request_permission -> tool_call_update (completed)
The fix is to send tool_call in both branches of the if/else, not just the else. Something like:
// Always notify the client about the tool call first
await this.sendUpdate({
sessionUpdate: 'tool_call',
toolCallId: callId,
status: confirmationDetails ? 'pending' : 'in_progress',
title: invocation.getDescription(),
content: [],
locations: invocation.toolLocations(),
kind: toAcpToolKind(tool.kind),
});
if (confirmationDetails) {
// then request permission...
}
Note: #14957 shows tool_call with in_progress was being emitted for MCP tools in earlier versions, so this may be a regression from the confirmation refactor.
Client information
Client Information
Built from source, commit 1fd4280.
Platform: macOS (Darwin, aarch64)
Login information
Google account.
Anything else we need to know?
How to validate:
- Start gemini in ACP mode with an MCP server via
session/new
- Prompt to use an MCP tool
- Observe: client receives
session/request_permission but no preceding tool_call session update
- After approval, client receives
tool_call_update (completed) with no matching tool_call
Related: #14957 (tool_call title issue, which shows MCP tools were emitting tool_call in earlier versions), #17952 (30s confirmation delay, same code path)
What happened?
In ACP mode, when a tool requires confirmation,
runTool()sendssession/request_permissionbut never sends a precedingtool_callsession update. The if/else in runTool treats them as mutually exclusive:confirmationDetailsis truthy: sendsrequest_permissiononly (notool_call)confirmationDetailsis falsy: sendstool_callonly (norequest_permission)After permission is granted, it sends
tool_call_update(completed), but the client never saw atool_call(pending) to associate it with.This is easiest to reproduce with MCP tools from
session/new. Since ACP doesn't passtrusttoMCPServerConfig, MCP tools always need confirmation via the policy engine. The debug log shows the expected path:But the client only sees:
{"sessionUpdate": "tool_call_update", "status": "completed", "toolCallId": "mcp_lookup_get_code-..."}No
tool_callwith status pending or in_progress is ever emitted.What did you expect to happen?
Per the ACP tool calls spec, the Agent SHOULD report a
tool_callsession update when the model requests a tool invocation. This should happen before requesting permission, so the client can track the tool call lifecycle:The fix is to send
tool_callin both branches of the if/else, not just the else. Something like:Note: #14957 shows
tool_callwithin_progresswas being emitted for MCP tools in earlier versions, so this may be a regression from the confirmation refactor.Client information
Client Information
Built from source, commit 1fd4280.
Platform: macOS (Darwin, aarch64)
Login information
Google account.
Anything else we need to know?
How to validate:
session/newsession/request_permissionbut no precedingtool_callsession updatetool_call_update(completed) with no matchingtool_callRelated: #14957 (tool_call title issue, which shows MCP tools were emitting tool_call in earlier versions), #17952 (30s confirmation delay, same code path)