fix(chat): show blocked and redirected custom tool calls as failed

Merged
RO
1d ago
+191-25

Description

Part 3 of the ENG-4416 stack. A custom tool call blocked by the SSRF check (or answered with a redirect) raised ToolCallException before any CustomToolDelta, so the step list said "get_meta_data completed".

  • CustomTool.run() now returns a failed CustomToolCallSummary and emits a CustomToolDelta with CustomToolErrorInfo for blocked destinations (status_code=None) and redirects (the 3xx code). This reuses the existing 401/403 error path, so the error also persists in history.
  • CustomToolRenderer shows "{tool} was blocked" with the error icon and error surface. HTTP failures keep "{tool} failed ({code})".
  • The LLM gets the same short message the user sees.
BeforeAfterAfter reloadMobile
beforeafterreloadmobile

flow

The last "Done" row is the timeline's turn-finished step (showDoneStep in useTimelineUIState), shown for every finished turn. It no longer reads as the tool's result.

How Has This Been Tested?

  • Local ODS stack + gpt-4.1-mini: an OpenAPI plugin on 169.254.169.254.nip.io; asked chat to call it. Desktop, reload and mobile show "was blocked" and no "completed"; API log shows the metadata-IP refusal.
  • pytest backend/tests/unit/onyx/tools/custom: 105 passed (blocked, redirect, and delta/summary parity cases).
  • New CustomToolRenderer.test.tsx (blocked + HTTP failure).
  • pre-commit (ty, ruff, tsc, oxlint) on touched files.

Additional Options

  • [Optional] Please cherry-pick this PR to the latest release version.

Link to Devin session: https://app.devin.ai/sessions/09df74c24e19407bbf0e7ab775b5cb0a
Open in Devin Desktop: https://app.devin.ai/desktop/session/09df74c24e19407bbf0e7ab775b5cb0a?variant=devin
Requested by: @rohoswagger


Summary by cubic

Fixes custom tool calls blocked by the SSRF check or answered with a redirect so they show as failed instead of "completed" in the chat step list.

  • CustomTool.run() now returns a failed CustomToolCallSummary and emits a CustomToolDelta with error info for blocked destinations and redirects instead of raising ToolCallException, reusing the existing 401/403 error path so the error persists in history.
  • CustomToolRenderer shows "{tool} was blocked" with the error icon and error surface; HTTP failures keep "{tool} failed ({code})".
  • The LLM receives the same short message the user sees.

Summary by CodeRabbit

  • Bug Fixes

    • Custom tool requests blocked by security checks or redirects now appear as structured failures instead of unexpected errors.
    • Error details, including HTTP status codes where available, are consistently shown in the conversation.
    • Blocked and authentication-related errors now display clear, non-collapsible status messages.
  • Localization

    • Added blocked-tool status translations across supported languages.
  • Tests

    • Added coverage for blocked destinations, redirects, HTTP failures, and error rendering.