How to Add User Confirmation to Tool Call Requests#
WayFlow Agents can be equipped with Tools to enhance their capabilities. However, end users may want to confirm or deny tool call requests emitted from the agent.
This guide shows you how to achieve this with the ServerTool. You can also do this using a ClientTool
Basic implementation#
In this example, you will build a simple Agent equipped with three tools:
A tool to add numbers
A tool to subtract numbers
A tool to multiply numbers
This guide requires the use of an LLM. WayFlow supports several LLM API providers. Select an LLM from the options below:
from wayflowcore.models import OCIGenAIModel
if __name__ == "__main__":
llm = OCIGenAIModel(
model_id="provider.model-id",
service_endpoint="https://url-to-service-endpoint.com",
compartment_id="compartment-id",
auth_type="API_KEY",
)
from wayflowcore.models import VllmModel
llm = VllmModel(
model_id="model-id",
host_port="VLLM_HOST_PORT",
)
from wayflowcore.models import OllamaModel
llm = OllamaModel(
model_id="model-id",
)
To learn more about the different LLM providers, read the guide on How to Use LLMs from Different Providers. The sample LLM used for this guide is defined as follows:
from wayflowcore.models import VllmModel
llm = VllmModel(
model_id="model-id",
host_port="VLLM_HOST_PORT",
)
Creating the tools#
Sometimes you will want to ask for user confirmation before executing certain tools. You can do this by using a ServerTool with the flag requires_confirmation set to True. This will raise a ToolExecutionConfirmationStatus
whenever the Agent tries to execute the tool. We set the multiply_numbers tool to not require confirmation to highlight the differences. Note that the requires_confirmation flag can be used for any WayFlow tool.
from wayflowcore.tools.toolhelpers import tool
from wayflowcore.executors.executionstatus import ToolExecutionConfirmationStatus
@tool(requires_confirmation=True, description_mode="only_docstring")
def add_numbers_tool(number1: float, number2: float) -> float:
"Add two numbers"
return number1 + number2
@tool(requires_confirmation=True, description_mode="only_docstring")
def subtract_numbers_tool(number1: float, number2: float) -> float:
"Subtract two numbers"
return number1 - number2
@tool(requires_confirmation=False, description_mode="only_docstring")
def multiply_numbers_tool(number1: float, number2: float) -> float:
"Multiply two numbers"
return number1 * number2
Creating the user-side execution logic#
To enable users to accept or deny tool call requests, you add simple validation logic before executing the tools requested by the agent.
def handle_tool_execution_confirmation(
status: ToolExecutionConfirmationStatus
) -> None:
for tool_request in status.tool_requests:
if tool_request.name == "add_numbers":
status.confirm_tool_execution(tool_request = tool_request)
elif tool_request.name == "subtract_numbers":
status.reject_tool_execution(tool_request = tool_request, reason = "The given numbers could not be subtracted as the tool is not currently functional")
elif tool_request.name == "multiply_numbers":
raise ValueError(f"Tool name {tool_request.name} should not raise a ToolExecutionConfirmationStatus as it does not require confirmation")
else:
raise ValueError(f"Tool name {tool_request.name} is not recognized")
Here, you simply loop until the user answers whether to accept the tool request or reject it. You can accept the tool request by using the status.confirm_tool_execution method.
While accepting, you need to specify the specific tool request and you also have the option to add modified_args in this method to change the arguments of the called tool.
Similarly, for rejection you can use the status.reject_tool_execution with an optional reason so that the Agent can take the reason into account while planning the next action to take.
Creating the agent#
Finally, you create a simple Agent to test the execution code written in the previous section.
from wayflowcore.agent import Agent
assistant = Agent(
llm=llm,
tools=[add_numbers_tool, subtract_numbers_tool, multiply_numbers_tool],
custom_instruction="Use the tools at your disposal to answer the user requests.",
)
Running the agent in an execution loop#
Now, you create a simple execution loop to test the agent. In this loop, you can input the instructions you want the agent to execute and test it out for yourself!
from wayflowcore.executors.executionstatus import (
FinishedStatus, UserMessageRequestStatus
)
def run_agent_in_command_line(assistant: Agent) -> None:
conversation_inputs = {}
conversation = assistant.start_conversation(inputs=conversation_inputs)
while True:
status = conversation.execute()
assistant_reply = conversation.get_last_message()
if assistant_reply:
print(f"Assistant>>> {assistant_reply.content}\n")
if isinstance(status, FinishedStatus):
print(f"Finished assistant execution. Output values:\n{status.output_values}",)
break
elif isinstance(status, UserMessageRequestStatus):
user_input = input("User>>> ")
print("\n")
conversation.append_user_message(user_input)
elif isinstance(status, ToolExecutionConfirmationStatus):
handle_tool_execution_confirmation(status)
else:
raise ValueError(f"Unsupported execution status: '{status}'")
# run_agent_in_command_line(assistant)
# ^ uncomment and execute
Recap#
In this guide, you learned how to support user-side confirmation for tool call requests by using ServerTool.
Next steps#
Having learned how to add user confirmation for tool calls, you may now proceed to:
Full code#
Click on the card at the top of this page to download the full code for this guide or copy the code below.
1# Copyright © 2025 Oracle and/or its affiliates.
2#
3# This software is under the Apache License 2.0
4# %%[markdown]
5# Code Example - How to Add User Confirmation
6# -------------------------------------------
7
8# How to use:
9# Create a new Python virtual environment and install the latest WayFlow version.
10# ```bash
11# python -m venv venv-wayflowcore
12# source venv-wayflowcore/bin/activate
13# pip install --upgrade pip
14# pip install "wayflowcore==26.1"
15# ```
16
17# You can now run the script
18# 1. As a Python file:
19# ```bash
20# python howto_userconfirmation.py
21# ```
22# 2. As a Notebook (in VSCode):
23# When viewing the file,
24# - press the keys Ctrl + Enter to run the selected cell
25# - or Shift + Enter to run the selected cell and move to the cell below# (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or Universal Permissive License
26# (UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl), at your option.
27
28
29
30# %%[markdown]
31##Configure LLM
32
33# %%
34from wayflowcore.models import VllmModel
35
36llm = VllmModel(
37 model_id="model-id",
38 host_port="VLLM_HOST_PORT",
39)
40
41
42
43# %%[markdown]
44##Create tools
45
46# %%
47from wayflowcore.tools.toolhelpers import tool
48from wayflowcore.executors.executionstatus import ToolExecutionConfirmationStatus
49
50@tool(requires_confirmation=True, description_mode="only_docstring")
51def add_numbers_tool(number1: float, number2: float) -> float:
52 "Add two numbers"
53 return number1 + number2
54
55@tool(requires_confirmation=True, description_mode="only_docstring")
56def subtract_numbers_tool(number1: float, number2: float) -> float:
57 "Subtract two numbers"
58 return number1 - number2
59
60@tool(requires_confirmation=False, description_mode="only_docstring")
61def multiply_numbers_tool(number1: float, number2: float) -> float:
62 "Multiply two numbers"
63 return number1 * number2
64
65
66# %%[markdown]
67##Create tool execution
68
69# %%
70def handle_tool_execution_confirmation(
71 status: ToolExecutionConfirmationStatus
72) -> None:
73 for tool_request in status.tool_requests:
74 if tool_request.name == "add_numbers":
75 status.confirm_tool_execution(tool_request = tool_request)
76 elif tool_request.name == "subtract_numbers":
77 status.reject_tool_execution(tool_request = tool_request, reason = "The given numbers could not be subtracted as the tool is not currently functional")
78 elif tool_request.name == "multiply_numbers":
79 raise ValueError(f"Tool name {tool_request.name} should not raise a ToolExecutionConfirmationStatus as it does not require confirmation")
80 else:
81 raise ValueError(f"Tool name {tool_request.name} is not recognized")
82
83
84
85# %%[markdown]
86##Create agent
87
88# %%
89from wayflowcore.agent import Agent
90
91assistant = Agent(
92 llm=llm,
93 tools=[add_numbers_tool, subtract_numbers_tool, multiply_numbers_tool],
94 custom_instruction="Use the tools at your disposal to answer the user requests.",
95)
96
97
98# %%[markdown]
99##Run tool loop
100
101# %%
102from wayflowcore.executors.executionstatus import (
103 FinishedStatus, UserMessageRequestStatus
104)
105
106def run_agent_in_command_line(assistant: Agent) -> None:
107 conversation_inputs = {}
108 conversation = assistant.start_conversation(inputs=conversation_inputs)
109
110 while True:
111 status = conversation.execute()
112 assistant_reply = conversation.get_last_message()
113 if assistant_reply:
114 print(f"Assistant>>> {assistant_reply.content}\n")
115 if isinstance(status, FinishedStatus):
116 print(f"Finished assistant execution. Output values:\n{status.output_values}",)
117 break
118 elif isinstance(status, UserMessageRequestStatus):
119 user_input = input("User>>> ")
120 print("\n")
121 conversation.append_user_message(user_input)
122 elif isinstance(status, ToolExecutionConfirmationStatus):
123 handle_tool_execution_confirmation(status)
124
125 else:
126 raise ValueError(f"Unsupported execution status: '{status}'")
127
128# run_agent_in_command_line(assistant)
129# ^ uncomment and execute