Skip to content

Commit a7ed7ed

Browse files
authored
feat: add error handling for approval response attempt (#4326)
* feat: add error handling for approval response attempt * add one more error case * improve error messages
1 parent 531425d commit a7ed7ed

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

letta/agents/helpers.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,27 @@ async def _prepare_in_context_messages_no_persist_async(
148148
# Otherwise, include the full list of messages by ID for context
149149
current_in_context_messages = await message_manager.get_messages_by_ids_async(message_ids=agent_state.message_ids, actor=actor)
150150

151+
# Check for approval-related message validation
152+
if len(input_messages) == 1 and input_messages[0].type == "approval":
153+
# User is trying to send an approval response
154+
if current_in_context_messages[-1].role != "approval":
155+
raise ValueError(
156+
"Cannot process approval response: No tool call is currently awaiting approval. "
157+
"Please send a regular message to interact with the agent."
158+
)
159+
if input_messages[0].approval_request_id != current_in_context_messages[-1].id:
160+
raise ValueError(
161+
f"Invalid approval request ID. Expected '{current_in_context_messages[-1].id}' "
162+
f"but received '{input_messages[0].approval_request_id}'."
163+
)
164+
else:
165+
# User is trying to send a regular message
166+
if current_in_context_messages[-1].role == "approval":
167+
raise ValueError(
168+
"Cannot send a new message: The agent is waiting for approval on a tool call. "
169+
"Please approve or deny the pending request before continuing."
170+
)
171+
151172
# Create a new user message from the input but dont store it yet
152173
new_in_context_messages = create_input_messages(
153174
input_messages=input_messages, agent_id=agent_state.id, timezone=agent_state.timezone, actor=actor

tests/integration_test_human_in_the_loop.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
import pytest
88
import requests
99
from dotenv import load_dotenv
10-
from letta_client import Letta, MessageCreate
10+
from letta_client import ApprovalCreate, Letta, MessageCreate
11+
from letta_client.core.api_error import ApiError
1112

1213
from letta.log import get_logger
1314
from letta.schemas.agent import AgentState
@@ -98,7 +99,7 @@ def approval_tool_fixture(client: Letta):
9899
client.tools.upsert_base_tools()
99100
approval_tool = client.tools.upsert_from_function(
100101
func=requires_approval_tool,
101-
# default_requires_approval=True,
102+
# default_requires_approval=True, switch to this once it is supported in sdk
102103
)
103104
yield approval_tool
104105

@@ -118,6 +119,11 @@ def agent(client: Letta, approval_tool_fixture) -> AgentState:
118119
embedding="openai/text-embedding-3-small",
119120
tags=["approval_test"],
120121
)
122+
client.agents.tools.modify_approval(
123+
agent_id=agent_state.id,
124+
tool_name=approval_tool_fixture.name,
125+
requires_approval=True,
126+
)
121127
yield agent_state
122128

123129

@@ -136,6 +142,13 @@ def test_send_message_with_approval_tool(
136142
This test just verifies that the agent can send a message successfully.
137143
The actual approval logic testing will be filled out by the user.
138144
"""
145+
# Attempt to send approval without pending request
146+
with pytest.raises(ApiError, match="No tool call is currently awaiting approval"):
147+
client.agents.messages.create(
148+
agent_id=agent.id,
149+
messages=[ApprovalCreate(approve=True, approval_request_id="fake_id")],
150+
)
151+
139152
# Send a simple greeting message to test basic functionality
140153
response = client.agents.messages.create(
141154
agent_id=agent.id,
@@ -147,3 +160,17 @@ def test_send_message_with_approval_tool(
147160
assert len(response.messages) == 2
148161
assert response.messages[0].message_type == "reasoning_message"
149162
assert response.messages[1].message_type == "approval_request_message"
163+
164+
# Attempt to send user message - should fail
165+
with pytest.raises(ApiError, match="Please approve or deny the pending request before continuing"):
166+
client.agents.messages.create(
167+
agent_id=agent.id,
168+
messages=[MessageCreate(role="user", content="hi")],
169+
)
170+
171+
# Attempt to send approval with incorrect id
172+
with pytest.raises(ApiError, match="Invalid approval request ID"):
173+
client.agents.messages.create(
174+
agent_id=agent.id,
175+
messages=[ApprovalCreate(approve=True, approval_request_id="fake_id")],
176+
)

0 commit comments

Comments
 (0)