Skip to content

Commit 3a8f6bb

Browse files
Fix failing unit tests for security risk extraction
- Fix _extract_security_risk method to always pop security_risk from arguments before checking readOnlyHint - Update test calls to include the new readOnlyHint parameter (3rd argument) - Add comprehensive test for readOnlyHint=True scenario - Ensure security_risk is properly removed from arguments in all cases Co-authored-by: openhands <openhands@all-hands.dev>
1 parent 4b3e817 commit 3a8f6bb

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

openhands-sdk/openhands/sdk/agent/agent.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,14 +313,14 @@ def _extract_security_risk(
313313
tool_name: str,
314314
readOnlyHint: bool,
315315
) -> risk.SecurityRisk:
316+
requires_sr = isinstance(self.security_analyzer, LLMSecurityAnalyzer)
317+
raw = arguments.pop("security_risk", None)
318+
316319
# Default risk value for action event
317320
# Tool is marked as read-only so security risk can be ignored
318321
if readOnlyHint:
319322
return risk.SecurityRisk.UNKNOWN
320323

321-
requires_sr = isinstance(self.security_analyzer, LLMSecurityAnalyzer)
322-
raw = arguments.pop("security_risk", None)
323-
324324
# Raises exception if failed to pass risk field when expected
325325
# Exception will be sent back to agent as error event
326326
# Strong models like GPT-5 can correct itself by retrying

tests/sdk/agent/test_extract_security_risk.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ def test_extract_security_risk(
9595

9696
if should_raise:
9797
with pytest.raises(ValueError):
98-
agent._extract_security_risk(arguments, tool_name)
98+
agent._extract_security_risk(arguments, tool_name, False)
9999
else:
100-
result = agent._extract_security_risk(arguments, tool_name)
100+
result = agent._extract_security_risk(arguments, tool_name, False)
101101
assert result == expected_result
102102

103103
# Verify that security_risk was popped from arguments
@@ -115,7 +115,7 @@ def test_extract_security_risk_error_messages(agent_with_llm_analyzer):
115115
with pytest.raises(
116116
ValueError, match="Failed to provide security_risk field in tool 'test_tool'"
117117
):
118-
agent_with_llm_analyzer._extract_security_risk(arguments, tool_name)
118+
agent_with_llm_analyzer._extract_security_risk(arguments, tool_name, False)
119119

120120

121121
def test_extract_security_risk_arguments_mutation():
@@ -133,7 +133,7 @@ def test_extract_security_risk_arguments_mutation():
133133
arguments = {"param1": "value1", "security_risk": "LOW", "param2": "value2"}
134134
original_args = arguments.copy()
135135

136-
result = agent._extract_security_risk(arguments, "test_tool")
136+
result = agent._extract_security_risk(arguments, "test_tool", False)
137137

138138
# Verify result
139139
assert result == SecurityRisk.LOW
@@ -159,8 +159,31 @@ def test_extract_security_risk_with_empty_arguments():
159159
)
160160

161161
arguments = {}
162-
result = agent._extract_security_risk(arguments, "test_tool")
162+
result = agent._extract_security_risk(arguments, "test_tool", False)
163163

164164
# Should return UNKNOWN when no analyzer and no security_risk
165165
assert result == SecurityRisk.UNKNOWN
166166
assert arguments == {} # Should remain empty
167+
168+
169+
def test_extract_security_risk_with_readonly_hint():
170+
"""Test _extract_security_risk with readOnlyHint=True."""
171+
agent = Agent(
172+
llm=LLM(
173+
usage_id="test-llm",
174+
model="test-model",
175+
api_key=SecretStr("test-key"),
176+
base_url="http://test",
177+
),
178+
security_analyzer=LLMSecurityAnalyzer(),
179+
)
180+
181+
# Test with readOnlyHint=True - should return UNKNOWN regardless of security_risk
182+
arguments = {"param1": "value1", "security_risk": "HIGH"}
183+
result = agent._extract_security_risk(arguments, "test_tool", True)
184+
185+
# Should return UNKNOWN when readOnlyHint is True
186+
assert result == SecurityRisk.UNKNOWN
187+
# security_risk should still be popped from arguments
188+
assert "security_risk" not in arguments
189+
assert arguments["param1"] == "value1"

0 commit comments

Comments
 (0)