External Tool Execution

Human-in-the-Loop: Execute a tool call outside of the agent.

1"""
2External Tool Execution
3=============================
4
5Human-in-the-Loop: Execute a tool call outside of the agent.
6"""
7
8import subprocess
9
10from kern.agent import Agent
11from kern.db.sqlite import SqliteDb
12from kern.models.openai import OpenAIResponses
13from kern.tools import tool
14from kern.utils import pprint
15
16
17# We have to create a tool with the correct name, arguments and docstring for the agent to know what to call.
18@tool(external_execution=True)
19def execute_shell_command(command: str) -> str:
20 """Execute a shell command.
21
22 Args:
23 command (str): The shell command to execute
24
25 Returns:
26 str: The output of the shell command
27 """
28 if command.startswith("ls"):
29 return subprocess.check_output(command, shell=True).decode("utf-8")
30 else:
31 raise Exception(f"Unsupported command: {command}")
32
33
34# ---------------------------------------------------------------------------
35# Create Agent
36# ---------------------------------------------------------------------------
37agent = Agent(
38 model=OpenAIResponses(id="gpt-5-mini"),
39 tools=[execute_shell_command],
40 markdown=True,
41 db=SqliteDb(session_table="test_session", db_file="tmp/example.db"),
42)
43
44# ---------------------------------------------------------------------------
45# Run Agent
46# ---------------------------------------------------------------------------
47if __name__ == "__main__":
48 run_response = agent.run("What files do I have in my current directory?")
49
50 if run_response.is_paused:
51 for requirement in run_response.active_requirements:
52 if requirement.needs_external_execution:
53 if requirement.tool_execution.tool_name == execute_shell_command.name:
54 print(
55 f"Executing {requirement.tool_execution.tool_name} with args {requirement.tool_execution.tool_args} externally"
56 )
57 # We execute the tool ourselves. You can also execute something completely external here.
58 result = execute_shell_command.entrypoint(
59 **requirement.tool_execution.tool_args
60 ) # type: ignore
61 # We have to set the result on the tool execution object so that the agent can continue
62 requirement.set_external_execution_result(result)
63
64 run_response = agent.continue_run(
65 run_id=run_response.run_id,
66 requirements=run_response.requirements,
67 )
68 pprint.pprint_run_response(run_response)
69
70 # Or for simple debug flow
71 # agent.print_response("What files do I have in my current directory?")

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 external_tool_execution.py