-
Notifications
You must be signed in to change notification settings - Fork 632
fix(langchain/createAgent): various code updates after HITL changes #673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -118,8 +118,7 @@ agent = create_agent( | |||
| ::: | ||||
| :::js | ||||
| ```typescript | ||||
| import { createAgent } from "langchain"; | ||||
| import { summarizationMiddleware, humanInTheLoopMiddleware } from "langchain/middleware"; | ||||
| import { createAgent, summarizationMiddleware, humanInTheLoopMiddleware } from "langchain"; | ||||
|
|
||||
| const agent = createAgent({ | ||||
| // ... | ||||
|
|
@@ -190,8 +189,7 @@ agent = create_agent( | |||
|
|
||||
| :::js | ||||
| ```typescript | ||||
| import { createAgent } from "langchain"; | ||||
| import { summarizationMiddleware } from "langchain/middleware"; | ||||
| import { createAgent, summarizationMiddleware } from "langchain"; | ||||
| import { ChatOpenAI } from "@langchain/openai"; | ||||
|
|
||||
| const agent = createAgent({ | ||||
|
|
@@ -276,7 +274,7 @@ agent = create_agent( | |||
| tools=[write_file_tool, execute_sql_tool, read_data_tool], | ||||
| middleware=[ | ||||
| HumanInTheLoopMiddleware( | ||||
| tool_configs={ | ||||
| interrupt_on={ | ||||
| "write_file": { | ||||
| "allow_accept": True, | ||||
| "allow_edit": True, | ||||
|
|
@@ -299,8 +297,7 @@ agent = create_agent( | |||
|
|
||||
| :::js | ||||
| ```typescript | ||||
| import { createAgent } from "langchain"; | ||||
| import { humanInTheLoopMiddleware } from "langchain/middleware"; | ||||
| import { createAgent, humanInTheLoopMiddleware } from "langchain"; | ||||
| import { Command, MemorySaver } from "@langchain/langgraph"; | ||||
|
|
||||
| const agent = createAgent({ | ||||
|
|
@@ -367,33 +364,29 @@ if state.next: | |||
|
|
||||
| :::js | ||||
| ```typescript | ||||
| import { HumanMessage } from "langchain"; | ||||
| import { HumanMessage, HumanInTheLoopRequest, Interrupt } from "langchain"; | ||||
| import { Command } from "@langchain/langgraph"; | ||||
| import type { Interrupt, HumanInTheLoopRequest } from "langchain/middleware"; | ||||
|
|
||||
| // Initial invocation | ||||
| const result = await agent.invoke( | ||||
| { | ||||
| messages: [new HumanMessage("Delete old records from the database")], | ||||
| }, | ||||
| config | ||||
| { | ||||
| messages: [new HumanMessage("Delete old records from the database")], | ||||
| }, | ||||
| config | ||||
| ); | ||||
|
|
||||
| // Check if agent is paused for approval | ||||
| if (result.__interrupt__) { | ||||
| const interruptRequest = result.__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 | ||||
| ); | ||||
| const interruptRequest = result.__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); | ||||
| } | ||||
| ``` | ||||
| ::: | ||||
|
|
@@ -412,7 +405,7 @@ from langgraph.types import Command | |||
|
|
||||
| # Create the human-in-the-loop middleware | ||||
| hitl_middleware = HumanInTheLoopMiddleware( | ||||
| tool_configs={ | ||||
| interrupt_on={ | ||||
| "write_file": { | ||||
| "allow_edit": True, | ||||
| "allow_accept": True, | ||||
|
|
@@ -468,11 +461,18 @@ if state.next: | |||
|
|
||||
| :::js | ||||
| ```typescript | ||||
| import type { Interrupt } from "langchain"; | ||||
| import type { HumanInTheLoopRequest, HumanInTheLoopMiddlewareHumanResponse } from "langchain/middleware"; | ||||
| import { | ||||
| createAgent, | ||||
| humanInTheLoopMiddleware, | ||||
| type HumanInTheLoopMiddlewareHumanResponse, | ||||
| type HumanInTheLoopRequest, | ||||
| HumanMessage, | ||||
| type Interrupt, | ||||
| } from "langchain"; | ||||
| import { Command, MemorySaver } from "@langchain/langgraph"; | ||||
|
|
||||
| const hitlMiddleware = humanInTheLoopMiddleware({ | ||||
| toolConfigs: { | ||||
| interruptOn: { | ||||
| write_file: { | ||||
| allowEdit: true, | ||||
| allowAccept: true, | ||||
|
|
@@ -486,9 +486,9 @@ const checkpointer = new MemorySaver(); | |||
| const agent = createAgent({ | ||||
| model: "openai:gpt-4o", | ||||
| checkpointer, | ||||
| prompt: | ||||
| systemPrompt: | ||||
| "You are a helpful assistant. Use the tools provided to help the user.", | ||||
| tools: [writeFileTool], | ||||
| tools: [/* ... */], | ||||
| middleware: [hitlMiddleware] as const, | ||||
| }); | ||||
|
|
||||
|
|
@@ -501,21 +501,27 @@ const config = { | |||
| // Initial invocation | ||||
| const result = await agent.invoke( | ||||
| { | ||||
| messages: [new HumanMessage("Write to greeting.txt with the content 'Hello, world!'")], | ||||
| messages: [ | ||||
| new HumanMessage( | ||||
| "Write to greeting.txt with the content 'Hello, world!'" | ||||
| ), | ||||
| ], | ||||
| }, | ||||
| config | ||||
| ); | ||||
|
|
||||
| const interruptRequest = result.__interrupt__?.[0] as Interrupt< | ||||
| HumanInTheLoopRequest[] | ||||
| >; | ||||
| const resume: HumanInTheLoopMiddlewareHumanResponse[] = [{ | ||||
| type: "edit", | ||||
| args: { | ||||
| action: "write_file", | ||||
| args: { filename: "greeting.txt", content: "Safe content" }, | ||||
| const resume: HumanInTheLoopMiddlewareHumanResponse[] = [ | ||||
| { | ||||
| type: "edit", | ||||
| args: { | ||||
| action: "write_file", | ||||
| args: { filename: "greeting.txt", content: "Safe content" }, | ||||
| }, | ||||
| }, | ||||
| }]; | ||||
| ]; | ||||
|
|
||||
| // Resume with approval | ||||
| await agent.invoke(new Command({ resume }), config); | ||||
|
|
@@ -539,7 +545,7 @@ from langgraph.checkpoint.memory import InMemorySaver | |||
| from langgraph.types import Command | ||||
|
|
||||
| hitl_middleware = HumanInTheLoopMiddleware( | ||||
| tool_configs={ | ||||
| interrupt_on={ | ||||
| "write_file": True, | ||||
| } | ||||
| ) | ||||
|
|
@@ -587,11 +593,17 @@ if state.next: | |||
|
|
||||
| :::js | ||||
| ```typescript | ||||
| import type { Interrupt } from "langchain"; | ||||
| import type { HumanInTheLoopRequest, HumanInTheLoopMiddlewareHumanResponse } from "langchain/middleware"; | ||||
| import { | ||||
| Interrupt, | ||||
| HumanMessage, | ||||
| HumanInTheLoopRequest, | ||||
| humanInTheLoopMiddleware, | ||||
| } from "langchain"; | ||||
| import { createAgent } from "langchain"; | ||||
|
||||
| import { createAgent } from "langchain"; |
Copilot
AI
Sep 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new keyword is missing when creating the HumanMessage instance. This is inconsistent with other examples in the file and will cause a runtime error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a different PR for HIL