Skip to content

fix(llm): surface structured provider refusals - #944

Merged
bearsyankees merged 2 commits into
mainfrom
agent/surface-provider-refusals
Jul 31, 2026
Merged

fix(llm): surface structured provider refusals#944
bearsyankees merged 2 commits into
mainfrom
agent/surface-provider-refusals

Conversation

@bearsyankees

Copy link
Copy Markdown
Collaborator

Summary

  • detect structured ResponseOutputRefusal items after a streamed run completes
  • route provider refusals through the existing agent failure path so the TUI displays them in red
  • preserve the provider's refusal text as the agent error

Why

Some providers return policy refusals as successful response output rather than raising an API exception. Strix previously treated those turns as normal final output and parked the interactive agent in waiting, hiding the actual failure.

Testing

  • poetry run pytest tests/test_execution.py tests/test_execution_transient_retry.py tests/test_e2e_budget_lifecycle.py -q (44 passed)
  • poetry run ruff check strix/core/execution.py tests/test_execution.py
  • poetry run mypy strix/core/execution.py
  • live OpenRouter/Anthropic structured refusal: agent rendered red as failed with the full provider message

@bearsyankees
bearsyankees marked this pull request as ready for review July 31, 2026 14:34
@greptile-apps

greptile-apps Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR now handles structured model-provider refusals through the normal agent failure lifecycle.

  • Detects refusal output after streamed execution completes.
  • Preserves the provider’s refusal text as the agent error.
  • Marks interactive and non-interactive agents as failed and notifies child agents’ parents.
  • Adds coverage for root-agent and child-agent refusal handling.

Confidence Score: 5/5

The PR appears safe to merge.

The previously reported non-interactive refusal issue is fixed: the refusal handler now records a failed terminal status and notifies the parent before returning, so the generic non-interactive re-raise is no longer reached.

Important Files Changed

Filename Overview
strix/core/execution.py Detects structured refusal items and routes them through terminal failure handling, including non-interactive child status updates and parent notification.
tests/test_execution.py Adds focused tests confirming refusal text preservation, failed status transitions, and parent notification for non-interactive children.

Reviews (2): Last reviewed commit: "fix(llm): settle refused autonomous agen..." | Re-trigger Greptile

Comment thread strix/core/execution.py
@bearsyankees

Copy link
Copy Markdown
Collaborator Author

@greptileai

@bearsyankees
bearsyankees merged commit a9deb84 into main Jul 31, 2026
1 check passed
5hy7xz92nd-oss

This comment was marked as spam.

devin-ai-integration Bot pushed a commit that referenced this pull request Aug 1, 2026
Resolves the overlap with #944 (structured provider refusals), which edits the
same terminal-error block in _run_cycle:

- keep #944's ProviderRefusalError park (visible failure + parent notice)
- keep this branch's removal of the guardrail special case, so a guardrail
  rejection flows through normal classification like any other model error
- run _salvage_stream_to_session before the refusal park so a refusal-parked
  agent keeps its context on revival
- keep both sides' tests; restore the MagicMock import and make the refusal
  stream helper type-check
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants