Problem
AgentMiddleware has a fully-implemented human-in-the-loop approval flow: when a SafetyRule returns PermissionResult.NEEDS_APPROVAL, the middleware calls an ApprovalCallback to get user confirmation before executing the tool call.
The infrastructure is all there:
AgentMiddleware.__init__ accepts approval_callback: ApprovalCallback | None
AgentMiddleware.awrap_tool_call uses it correctly
LangChainSubagentRunner.__init__ accepts and forwards it to subagent middleware
test_middleware.py tests it
But create_agent() — the only public entry point — never accepts or passes this parameter. Users have no way to enable human-in-the-loop approval without forking the factory.
Root Cause
In langchain/agent.py, steps 8 and 13 both omit approval_callback:
# Step 8 — LangChainSubagentRunner is constructed without approval_callback
runner = LangChainSubagentRunner(
...,
permission_gate=permission_gate,
# approval_callback not passed
)
# Step 13 — AgentMiddleware is constructed without approval_callback
middleware = AgentMiddleware(
...,
permission_gate=permission_gate,
# approval_callback not passed
)
Proposed Fix
Add approval_callback: ApprovalCallback | None = None to create_agent() and thread it through:
async def create_agent(
model,
computer,
*,
...
approval_callback: ApprovalCallback | None = None, # ← add this
) -> Agent:
Then pass it in steps 8 and 13. Three lines of change total.
Impact
Without this fix, any SafetyRule that returns NEEDS_APPROVAL silently denies the tool call (see middleware.py line ~502: if self._approval_callback is None: return _create_denied_response(...)). Users cannot implement interactive approval flows using the public API.
Alternatives
None — the workaround requires accessing private internals.
Problem
AgentMiddlewarehas a fully-implemented human-in-the-loop approval flow: when aSafetyRulereturnsPermissionResult.NEEDS_APPROVAL, the middleware calls anApprovalCallbackto get user confirmation before executing the tool call.The infrastructure is all there:
AgentMiddleware.__init__acceptsapproval_callback: ApprovalCallback | NoneAgentMiddleware.awrap_tool_calluses it correctlyLangChainSubagentRunner.__init__accepts and forwards it to subagent middlewaretest_middleware.pytests itBut
create_agent()— the only public entry point — never accepts or passes this parameter. Users have no way to enable human-in-the-loop approval without forking the factory.Root Cause
In
langchain/agent.py, steps 8 and 13 both omitapproval_callback:Proposed Fix
Add
approval_callback: ApprovalCallback | None = Nonetocreate_agent()and thread it through:Then pass it in steps 8 and 13. Three lines of change total.
Impact
Without this fix, any
SafetyRulethat returnsNEEDS_APPROVALsilently denies the tool call (seemiddleware.pyline ~502:if self._approval_callback is None: return _create_denied_response(...)). Users cannot implement interactive approval flows using the public API.Alternatives
None — the workaround requires accessing private internals.