Configuration options for the middleware
A middleware instance that can be passed to createAgent
Basic usage with selective tool approval
import { humanInTheLoopMiddleware } from "langchain";
import { createAgent } from "langchain";
const hitlMiddleware = humanInTheLoopMiddleware({
interruptOn: {
// Interrupt write_file tool and allow edits or accepts
"write_file": {
allowEdit: true,
allowAccept: true,
description: "⚠️ File write operation requires approval"
},
// Auto-approve read_file tool
"read_file": false
}
});
const agent = createAgent({
model: "openai:gpt-4",
tools: [writeFileTool, readFileTool],
middleware: [hitlMiddleware]
});
Handling approval requests
import { type HumanInTheLoopRequest, type Interrupt } from "langchain";
import { Command } from "@langchain/langgraph";
// Initial agent invocation
const result = await agent.invoke({
messages: [new HumanMessage("Write 'Hello' to output.txt")]
}, config);
// Check if agent is paused for approval
if (result.__interrupt__) {
const interruptRequest = initialResult.__interrupt__?.[0] as Interrupt<
HumanInTheLoopRequest[]
>;
// Show tool call details to user
console.log("Tool:", interruptRequest.value[0].actionRequest);
console.log("Allowed actions:", interruptRequest.value[0].config);
// Resume with approval
await agent.invoke(
new Command({ resume: [{ type: "accept" }] }),
config
);
}
Different response types
// Accept the tool call as-is
new Command({ resume: [{ type: "accept" }] })
// Edit the tool arguments
new Command({
resume: [{
type: "edit",
args: { action: "write_file", args: { filename: "safe.txt", content: "Modified" } }
}]
})
// Skip tool and terminate agent
new Command({ resume: [{ type: "response" }] })
// Provide manual response
new Command({
resume: [{
type: "response",
// this must be a string
args: "File operation not allowed in demo mode"
}]
})
Production use case with database operations
const hitlMiddleware = humanInTheLoopMiddleware({
interruptOn: {
"execute_sql": {
allowAccept: true,
allowEdit: true,
allowRespond: true,
description: "🚨 SQL query requires DBA approval\nPlease review for safety and performance"
},
"read_schema": false // Reading metadata is safe
"delete_records": {
allowAccept: true,
description: "⛔ DESTRUCTIVE OPERATION - Requires manager approval"
}
},
messagePrefix: "Database operation pending approval"
});
afterModel
phase, intercepting before tool execution
Creates a Human-in-the-Loop (HITL) middleware for tool approval and oversight.
This middleware intercepts tool calls made by an AI agent and provides human oversight capabilities before execution. It enables selective approval workflows where certain tools require human intervention while others can execute automatically.
A invocation result that has been interrupted by the middleware will have a
__interrupt__
property that contains the interrupt request. You can loop over the request to determine which tools were interrupted, and how to handle them separately.Features
Response Types
When a tool requires approval, the human operator can respond with:
accept
: Execute the tool with original argumentsedit
: Modify the tool arguments before executionignore
: Skip the tool and terminate the agentresponse
: Provide a manual response instead of executing the tool