Confirmation Required

Human-in-the-Loop (HITL): Adding User Confirmation to Tool Calls.

1"""
2Confirmation Required
3=============================
4
5Human-in-the-Loop (HITL): Adding User Confirmation to Tool Calls.
6"""
7
8import json
9
10import httpx
11from kern.agent import Agent
12from kern.db.sqlite import SqliteDb
13from kern.models.openai import OpenAIResponses
14from kern.tools import tool
15from kern.utils import pprint
16from rich.console import Console
17from rich.prompt import Prompt
18
19console = Console()
20
21
22# This tool will require user confirmation before execution
23@tool(requires_confirmation=True)
24def get_top_hackernews_stories(num_stories: int) -> str:
25 """Fetch top stories from Hacker News.
26
27 Args:
28 num_stories (int): Number of stories to retrieve
29
30 Returns:
31 str: JSON string containing story details
32 """
33 # Fetch top story IDs
34 response = httpx.get("https://hacker-news.firebaseio.com/v0/topstories.json")
35 story_ids = response.json()
36
37 # Yield story details
38 all_stories = []
39 for story_id in story_ids[:num_stories]:
40 story_response = httpx.get(
41 f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json"
42 )
43 story = story_response.json()
44 if "text" in story:
45 story.pop("text", None)
46 all_stories.append(story)
47 return json.dumps(all_stories)
48
49
50# ---------------------------------------------------------------------------
51# Create Agent
52# ---------------------------------------------------------------------------
53agent = Agent(
54 model=OpenAIResponses(id="gpt-5-mini"),
55 tools=[get_top_hackernews_stories],
56 markdown=True,
57 db=SqliteDb(session_table="test_session", db_file="tmp/example.db"),
58)
59
60# ---------------------------------------------------------------------------
61# Run Agent
62# ---------------------------------------------------------------------------
63if __name__ == "__main__":
64 run_response = agent.run("Fetch the top 2 hackernews stories.")
65
66 for requirement in run_response.active_requirements:
67 if requirement.needs_confirmation:
68 # Ask for confirmation
69 console.print(
70 f"Tool name [bold blue]{requirement.tool_execution.tool_name}({requirement.tool_execution.tool_args})[/] requires confirmation."
71 )
72 message = (
73 Prompt.ask("Do you want to continue?", choices=["y", "n"], default="y")
74 .strip()
75 .lower()
76 )
77
78 # Confirm or reject the requirement
79 if message == "n":
80 requirement.reject()
81 else:
82 requirement.confirm()
83
84 run_response = agent.continue_run(
85 run_id=run_response.run_id,
86 requirements=run_response.requirements,
87 )
88
89 # You can also pass the updated tools when continuing the run:
90 # run_response = agent.continue_run(
91 # run_id=run_response.run_id,
92 # updated_tools=run_response.tools,
93 # )
94
95 pprint.pprint_run_response(run_response)

Run the Example

1# Clone and setup repo
2git clone https://github.com/kern-ai/kern.git
3cd kern/cookbook/02_agents/10_human_in_the_loop
4
5# Create and activate virtual environment
6./scripts/demo_setup.sh
7source .venvs/demo/bin/activate
8
9python confirmation_required.py