Skip to content

Commit 57af75f

Browse files
committed
cr 1
1 parent 02edff4 commit 57af75f

1 file changed

Lines changed: 73 additions & 21 deletions

File tree

agents/langgraph/human_in_the_loop/README.md

Lines changed: 73 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
## What this agent does
1212

1313
Agent with **Human-in-the-Loop (HITL) approval** that pauses execution before running sensitive tools (e.g.
14-
`send_email`) and waits for human review. Safe tools (e.g. `search`) run automatically without approval. Built with
15-
LangGraph and LangChain.
14+
`create_file`) and waits for human review. Simple questions are answered directly without triggering the approval loop.
15+
Built with LangGraph and LangChain.
1616

1717
**How it works:**
1818

@@ -28,7 +28,7 @@ User Input → LLM decides tool → Is it sensitive?
2828

2929
### Preconditions:
3030

31-
- You need to change .env.template file to .env
31+
- You need to change template.env file to .env
3232
- Decide what way you want to go `local` or `RH OpenShift Cluster` and fill needed values
3333
- use `./init.sh` that will add those values from .env to environment variables
3434

@@ -162,10 +162,10 @@ uv run examples/execute_ai_service_locally.py
162162

163163
This agent classifies tools into two categories:
164164

165-
| Category | Tools | Behavior |
166-
|---------------|--------------|--------------------------------------------|
167-
| **Safe** | `search` | Executed automatically, no approval needed |
168-
| **Sensitive** | `send_email` | Paused for human review before execution |
165+
| Category | Tools | Behavior |
166+
|---------------|---------------|-------------------------------------------|
167+
| **Safe** | general chat | Responded to directly, no approval needed |
168+
| **Sensitive** | `create_file` | Paused for human review before execution |
169169

170170
When the LLM decides to call a sensitive tool, the agent:
171171

@@ -182,7 +182,7 @@ When the LLM decides to call a sensitive tool, the agent:
182182
curl -X POST http://localhost:8000/chat/completions \
183183
-H "Content-Type: application/json" \
184184
-d '{
185-
"messages": [{"role": "user", "content": "Send an email to alice@example.com about the meeting tomorrow"}],
185+
"messages": [{"role": "user", "content": "Create a file named report.md with info about LangChain"}],
186186
"stream": false,
187187
"thread_id": "conversation-1"
188188
}'
@@ -196,7 +196,7 @@ curl -X POST http://localhost:8000/chat/completions \
196196
{
197197
"message": {
198198
"role": "assistant",
199-
"content": "{\"question\": \"Do you approve the following tool call(s)?\", \"tool_calls\": [\"Tool: send_email, Args: {...}\"], \"options\": [\"yes\", \"no\"]}"
199+
"content": "{\"question\": \"Do you approve the following tool call(s)?\", \"tool_calls\": [\"Tool: create_file, Args: {...}\"], \"options\": [\"yes\", \"no\"]}"
200200
},
201201
"finish_reason": "pending_approval"
202202
}
@@ -299,36 +299,84 @@ COPY the route URL and PASTE into the CURL below
299299
oc get route langgraph-hitl-agent -o jsonpath='{.spec.host}'
300300
```
301301

302-
Send a test request:
302+
Send test requests (3-step HITL flow):
303303

304-
Non-streaming (safe tool - no approval needed)
304+
**Step 1: Ask a general question (no approval needed)**
305305

306306
```bash
307307
curl -X POST https://<YOUR_ROUTE_URL>/chat/completions \
308308
-H "Content-Type: application/json" \
309-
-d '{"messages": [{"role": "user", "content": "Search for RedHat OpenShift"}], "stream": false}'
309+
-d '{
310+
"messages": [{"role": "user", "content": "What is RedHat OpenShift Cluster"}],
311+
"stream": false,
312+
"thread_id": "demo-1"
313+
}'
310314
```
311315

312-
Non-streaming (sensitive tool - triggers approval)
316+
**Step 2: Ask to write that info into a file (triggers approval)**
313317

314318
```bash
315319
curl -X POST https://<YOUR_ROUTE_URL>/chat/completions \
316320
-H "Content-Type: application/json" \
317321
-d '{
318-
"messages": [{"role": "user", "content": "Send an email to alice@example.com about the meeting"}],
322+
"messages": [{"role": "user", "content": "Write that information into a file called demo.md"}],
319323
"stream": false,
320-
"thread_id": "test-hitl-1"
324+
"thread_id": "demo-1"
321325
}'
322326
```
323327

324-
Streaming
328+
The agent will pause and return `finish_reason: "pending_approval"` with the `create_file` tool call details.
329+
330+
**Step 3: Approve the file creation**
325331

326332
```bash
327333
curl -X POST https://<YOUR_ROUTE_URL>/chat/completions \
328334
-H "Content-Type: application/json" \
329335
-d '{
330-
"messages": [{"role": "user", "content": "Search for RedHat OpenShift"}],
331-
"stream": true
336+
"messages": [{"role": "user", "content": ""}],
337+
"thread_id": "demo-1",
338+
"approval": "yes"
339+
}'
340+
```
341+
342+
The agent resumes, executes `create_file`, and returns the final result.
343+
344+
Streaming (3-step HITL flow with `stream: true`):
345+
346+
**Step 1: Ask a general question (no approval needed)**
347+
348+
```bash
349+
curl -X POST https://langgraph-hitl-agent-tguzik-agents.apps.rosa.ai-eng-gpu.socc.p3.openshiftapps.com/chat/completions \
350+
-H "Content-Type: application/json" \
351+
-d '{
352+
"messages": [{"role": "user", "content": "What is RedHat OpenShift Cluster"}],
353+
"stream": true,
354+
"thread_id": "demo-2"
355+
}'
356+
```
357+
358+
**Step 2: Ask to write that info into a file (triggers approval)**
359+
360+
```bash
361+
curl -X POST https://<YOUR_ROUTE_URL>/chat/completions \
362+
-H "Content-Type: application/json" \
363+
-d '{
364+
"messages": [{"role": "user", "content": "Write that information into a file called demo.md"}],
365+
"stream": true,
366+
"thread_id": "demo-2"
367+
}'
368+
```
369+
370+
**Step 3: Approve the file creation**
371+
372+
```bash
373+
curl -X POST https://<YOUR_ROUTE_URL>/chat/completions \
374+
-H "Content-Type: application/json" \
375+
-d '{
376+
"messages": [{"role": "user", "content": ""}],
377+
"stream": true,
378+
"thread_id": "demo-2",
379+
"approval": "yes"
332380
}'
333381
```
334382

@@ -377,11 +425,15 @@ This agent extends the base LangGraph ReAct agent with:
377425

378426
**Customization:**
379427

380-
Edit `src/human_in_the_loop/agent.py`:
428+
Edit `src/human_in_the_loop/agent.py` to add more sensitive tools to the interrupt list:
381429

382430
```python
383-
# Add more sensitive tools that require approval
384-
SENSITIVE_TOOLS = {send_email.name, "delete_record", "transfer_funds"}
431+
hitl_middleware = HumanInTheLoopMiddleware(
432+
interrupt_on={
433+
"create_file": True,
434+
"delete_record": True,
435+
},
436+
)
385437
```
386438

387439
Edit `src/human_in_the_loop/tools.py` to add new tools:

0 commit comments

Comments
 (0)