1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson →
Edit decisions: changing a tool call before it runs
An edit decision resumes a paused tool call with arguments you changed, so the tool runs with your version instead of the model's.
Last updated: 29 Sep, 2026 · Deep Agents 0.7
Approve and reject, from Human-in-the-loop: approving a booking, are yes or no. Often the agent's call is nearly right: the right hotel for the wrong number of nights. An edit fixes it in place, without another round with the model.
The edit decision syntax
request = result["__interrupt__"][0].value["action_requests"][0]
edited = {"type": "edit",
"edited_action": {"name": request["name"], "args": {**request["args"], "nights": 2}}}
agent.invoke(Command(resume={"decisions": [edited]}), config=config)The same booking agent
Start trip.py with search_travel and book_hotel, as in Human-in-the-loop: approving a booking:
from langchain.tools import tool
CATALOG = {
"paris": {
"flight": ["Return flight Delhi to Paris: 42,000 rupees"],
"hotel": ["Seine Budget Inn, Latin Quarter: 5,200 rupees a night",
"Hotel Lumiere, Montmartre: 7,500 rupees a night",
"Le Grand Opera Hotel: 16,000 rupees a night"],
"sight": ["Eiffel Tower summit: 3,100 rupees", "Louvre Museum: 2,000 rupees",
"Seine river cruise: 1,500 rupees", "Versailles day trip: 2,600 rupees",
"Montmartre walking tour: free"],
"food": ["Cafe breakfast and bistro dinner: 3,000 rupees a day"],
},
}
@tool
def search_travel(city: str, kind: str) -> str:
"""Search the travel catalog. kind is "flight", "hotel", "sight" or "food". Prices are in rupees."""
entries = CATALOG.get(city.lower(), {}).get(kind)
return "\n".join(entries) if entries else f"The catalog has no {kind} entries for {city}."
@tool
def book_hotel(hotel: str, nights: int) -> str:
"""Book a hotel for a number of nights. This spends the traveller's money."""
return f"Booked {hotel} for {nights} nights."from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model
model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0, max_retries=6)from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import Command
agent = create_deep_agent(
model=model,
tools=[search_travel, book_hotel],
interrupt_on={"book_hotel": True}, # pause before every booking
checkpointer=InMemorySaver(), # a pause needs saved state
system_prompt="You book trips. Look up prices with search_travel. Reply in one short sentence.",
)Cutting a booking from 3 nights to 2
The traveller asks for 3 nights; the person reviewing knows the dates changed and books 2.
config = {"configurable": {"thread_id": "edit"}}
result = agent.invoke({"messages": [{"role": "user", "content": "Book Hotel Lumiere, Montmartre for 3 nights."}]}, config=config)
request = result["__interrupt__"][0].value["action_requests"][0]
print("agent asked:", request["name"], request["args"])
edited = {"type": "edit", "edited_action": {"name": "book_hotel", "args": {**request["args"], "nights": 2}}}
result = agent.invoke(Command(resume={"decisions": [edited]}), config=config)
print("tool said: ", result["messages"][-2].text)
print("agent said: ", result["messages"][-1].text)Output
agent asked: book_hotel {'hotel': 'Hotel Lumiere, Montmartre', 'nights': 3}
tool said: Note: a human reviewer replaced this tool call before it ran. The call recorded in your message is the one you produced, not the one that executed. This was intentional and authorized. Do not re-issue your original call. Executed instead: book_hotel with arguments {"hotel": "Hotel Lumiere, Montmartre", "nights": 2}.
Tool response:
Booked Hotel Lumiere, Montmartre for 2 nights.
agent said: Hotel Lumiere in Montmartre has been booked for 2 nights.What the edit changed
- The agent asked for Hotel Lumiere with
nights3, as the traveller said. - The tool ran with 2 nights. The tool message starts with a note from the middleware telling the model that a reviewer replaced its call, so it does not send the original again, then the booking result.
- The agent's reply reports the booking the tool made, not the one it had asked for.
Edit vs reject and ask again
| edit | reject, then a new request | |
|---|---|---|
| Model calls | None extra | At least one more |
| Who decides the final arguments | The reviewer | The model, again |
| Good for | Small fixes: a number, a date | Wrong tool or wrong idea |
Where edits help
- Fixing a quantity, a date or a recipient before an action runs.
- Letting an assistant draft a message that a person corrects before it is sent.
- Keeping a human in charge of the final values without rewriting the whole request.
Watch out. Keep edits small. The docs warn that a large change to the arguments can make the model rethink its approach and call the tool again.
Related
- Previous: Human-in-the-loop: approving a booking
- Next: Permissions: rules for file writes
- Reference: Human-in-the-loop: edit tool arguments
Try it yourself
- Edit the hotel name to "Seine Budget Inn, Latin Quarter" instead of the nights.
- Allow only approve and reject for
book_hotel, then try the edit and read the error. - Print
result["messages"][-3].tool_callsto see what the model originally asked for.
Little by little, you're building something great.