Skip to content

feat(agent): expose approval_callback in create_agent() — human-in-the-loop unusable via public API #30

@caoergou

Description

@caoergou

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions