Skip to content

Commit e24b5a5

Browse files
author
yuweihong.666
committed
fix: use only DecisionType for AgentSentry V3 moderation decisions
1 parent e5bfe04 commit e24b5a5

2 files changed

Lines changed: 43 additions & 16 deletions

File tree

‎tests/test_agentsentry_v3_transport.py‎

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,18 @@ def client(mod):
4343

4444

4545
@pytest.mark.parametrize(
46-
"result,blocked",
46+
"result,expected",
4747
[
48-
({"Degraded": False, "Decision": {"DecisionType": 1}}, False),
49-
({"Degraded": False, "Decision": {"DecisionType": 2}}, True),
50-
({"Degraded": True, "Decision": {"DecisionType": 1}}, True),
51-
({"Decision": {"DecisionType": 1}}, True),
52-
({"Degraded": False, "Decision": {"DecisionType": 4}}, True),
53-
({"Degraded": False, "Decision": {"DecisionType": True}}, True),
48+
({"Degraded": False, "Decision": {"DecisionType": 1}}, None),
49+
({"Degraded": False, "Decision": {"DecisionType": 2}}, "BLOCK"),
50+
({"Decision": {"DecisionType": 1}}, None),
51+
({"Degraded": "false", "Decision": {"DecisionType": 1}}, None),
52+
({"Degraded": False, "Decision": {"DecisionType": 4}}, "UNAVAILABLE"),
53+
({"Degraded": False, "Decision": {"DecisionType": True}}, "UNAVAILABLE"),
54+
({"Degraded": True}, "UNAVAILABLE"),
5455
],
5556
)
56-
def test_decisions(mod, result, blocked):
57+
def test_decisions(mod, result, expected):
5758
response = SimpleNamespace(status_code=200, json=lambda: {"Result": result})
5859
with patch.object(mod.requests, "post", return_value=response) as post:
5960
value = client(mod).moderate(
@@ -63,7 +64,7 @@ def test_decisions(mod, result, blocked):
6364
session_info={"SessionID": "session", "RunID": "run"},
6465
tool_calls=[{"ID": "call"}],
6566
)
66-
assert bool(value) == blocked
67+
assert value == (getattr(mod, expected) if expected else None)
6768
request = post.call_args
6869
body = json.loads(request.kwargs["data"])
6970
assert body["SessionID"] == "session"
@@ -75,6 +76,31 @@ def test_decisions(mod, result, blocked):
7576
assert request.kwargs["allow_redirects"] is False
7677

7778

79+
@pytest.mark.parametrize(
80+
"action,decision,expected",
81+
[
82+
("pass_and_writeback", 1, None),
83+
("pass_and_writeback", 2, "BLOCK"),
84+
("block_and_writeback", 1, None),
85+
("block_and_writeback", 2, "BLOCK"),
86+
(None, 1, None),
87+
("unknown", 1, None),
88+
("pass_and_writeback", 4, "UNAVAILABLE"),
89+
],
90+
)
91+
def test_decision_takes_precedence_over_degraded_action(mod, action, decision, expected):
92+
result = {
93+
"Decision": {"DecisionType": decision},
94+
"Degraded": True,
95+
}
96+
if action is not None:
97+
result["DegradeAction"] = action
98+
response = SimpleNamespace(status_code=200, json=lambda: {"Result": result})
99+
with patch.object(mod.requests, "post", return_value=response):
100+
value = client(mod).moderate("hello", role="user", hook_name="before_dispatch")
101+
assert value == (getattr(mod, expected) if expected else None)
102+
103+
78104
def test_missing_plan_and_wrong_hook(mod):
79105
with patch.object(mod.requests, "post") as post:
80106
assert (

‎veadk/tools/builtin_tools/agentsentry_v3.py‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,19 @@ def moderate(self, text, *, role, hook_name, session_info=None, tool_calls=None)
152152
return UNAVAILABLE
153153
data = response.json()
154154
result = data.get("Result") or {}
155+
metadata = data.get("ResponseMetadata") or {}
156+
request_id = metadata.get("RequestId")
157+
if metadata.get("Error"):
158+
logger.warning("AgentSentry V3 API error request_id=%s", request_id)
159+
return UNAVAILABLE
160+
decision = (result.get("Decision") or {}).get("DecisionType")
155161
logger.info(
156162
"AgentSentry V3 hook=%s request_id=%s decision=%s degraded=%s",
157163
hook_name,
158-
(data.get("ResponseMetadata") or {}).get("RequestId"),
159-
(result.get("Decision") or {}).get("DecisionType"),
164+
request_id,
165+
decision,
160166
result.get("Degraded"),
161167
)
162-
if (data.get("ResponseMetadata") or {}).get("Error"):
163-
return UNAVAILABLE
164-
if result.get("Degraded") is not False:
165-
return UNAVAILABLE
166-
decision = (result.get("Decision") or {}).get("DecisionType")
167168
if type(decision) is int and decision == 1:
168169
return None
169170
if type(decision) is int and decision == 2:

0 commit comments

Comments
 (0)