From 4b3bd22844e89662c707de51a2ec689880a8392b Mon Sep 17 00:00:00 2001 From: Asadullo Ganiev <62354884+solvemproblr@users.noreply.github.com> Date: Thu, 10 Sep 2026 14:56:53 +0500 Subject: [PATCH 1/2] fix(agents): persist Anthropic refusal explanations on Claude traces HTTP 200 refusals put the policy category and explanation on stop_details; copy that onto AgentStep.refusal so the trace UI can show the real reason. Co-authored-by: Cursor --- hud/agents/claude/agent.py | 6 ++++ hud/agents/tests/test_claude_agent.py | 45 ++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/hud/agents/claude/agent.py b/hud/agents/claude/agent.py index 41c3d1ff5..e2692adab 100644 --- a/hud/agents/claude/agent.py +++ b/hud/agents/claude/agent.py @@ -403,6 +403,12 @@ async def get_response( if thinking_parts: result.reasoning = "\n".join(thinking_parts) result.finish_reason = response.stop_reason + if response.stop_reason == "refusal" and response.stop_details is not None: + explanation = response.stop_details.explanation + if explanation: + result.refusal = explanation + elif response.stop_details.category is not None: + result.refusal = f"This request was refused ({response.stop_details.category})." return result @staticmethod diff --git a/hud/agents/tests/test_claude_agent.py b/hud/agents/tests/test_claude_agent.py index 40025f051..353f8d6b0 100644 --- a/hud/agents/tests/test_claude_agent.py +++ b/hud/agents/tests/test_claude_agent.py @@ -54,11 +54,12 @@ def __init__(self, *outcomes: Any) -> None: self.beta = SimpleNamespace(messages=FakeMessages(*outcomes)) -def _final(*content: Any, stop_reason: str) -> Any: +def _final(*content: Any, stop_reason: str, stop_details: Any = None) -> Any: """A fake ``BetaMessage``: content blocks plus the always-present envelope.""" return SimpleNamespace( content=list(content), stop_reason=stop_reason, + stop_details=stop_details, model="claude-test-v9", usage=SimpleNamespace(input_tokens=11, output_tokens=7, cache_read_input_tokens=3), ) @@ -128,6 +129,48 @@ async def test_get_response_done_on_text_only() -> None: assert result.done is True assert result.content == "done" assert result.tool_calls == [] + assert result.refusal is None + + +async def test_get_response_surfaces_refusal_explanation() -> None: + explanation = ( + "This request triggered restrictions on violative cyber content and was " + "blocked under Anthropic's Usage Policy." + ) + final = _final( + stop_reason="refusal", + stop_details=SimpleNamespace( + type="refusal", + category="cyber", + explanation=explanation, + ), + ) + agent = _agent(final) + result = await agent.get_response(_state(agent)) + + assert result.finish_reason == "refusal" + assert result.refusal == explanation + assert result.done is True + assert result.tool_calls == [] + + +async def test_get_response_surfaces_refusal_category_when_explanation_missing() -> None: + final = _final( + stop_reason="refusal", + stop_details=SimpleNamespace( + type="refusal", + category="cyber", + explanation=None, + ), + ) + agent = _agent(final) + result = await agent.get_response(_state(agent)) + + assert result.finish_reason == "refusal" + assert result.refusal is not None + assert "cyber" in result.refusal + assert result.done is True + assert result.tool_calls == [] async def test_get_response_collects_thinking() -> None: From 52df528dcccf3a4f818fad3840414e362b956e50 Mon Sep 17 00:00:00 2001 From: Jaideep <67646710+jdchawla29@users.noreply.github.com> Date: Thu, 10 Sep 2026 23:51:04 -0700 Subject: [PATCH 2/2] fix(deps): require Anthropic streaming refusal support --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 58b8f8f08..e08f31077 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ dependencies = [ "fastmcp==3.2.0", # For all inference agents "openai>=2.45.0", - "anthropic>=0.78.0", + "anthropic>=0.98.0", "google-genai", # CLI dependencies "typer>=0.9.0", @@ -122,7 +122,7 @@ agents = [] # AWS Bedrock support for ClaudeAgent bedrock = [ - "anthropic[bedrock]>=0.78.0", + "anthropic[bedrock]>=0.98.0", ] # Development dependencies - includes testing, linting, and automation tools