fix(desktop): render description on inline approval card for plugin approvals - #62411
ethernet8023 wants to merge 1 commit into
Conversation
…pprovals
Plugin `pre_tool_call` hooks that return `{"action": "approve"}` set the
approval's `command` to a synthetic label (`<terminal> (plugin approval
rule)`) while the real info lives in `description`. The inline approval
card only rendered `command`, so users approved without seeing what runs.
- Render `description` as a context line on the inline `ApprovalBar` (same
as the floating fallback bar already does)
- Detect synthetic plugin commands (starting with `<`) and hide the
Command expander and Always-allow dialog `<pre>` block for those cases
- Use `hasCommand` consistently in the Always-allow dialog instead of
raw `request.command.trim()`
Fixes NousResearch#62402
c1bae03 to
3314a9e
Compare
kshitijk4poor
left a comment
There was a problem hiding this comment.
Thanks for the focused fix — the diagnosis is correct: plugin pre_tool_call approvals put the human-readable context in description, and the inline desktop card needs to show it.
I found two changes needed before this is ready:
-
ApprovalBaris shared by the inline card and the floating fallback. The fallback already rendersrequest.descriptionin its header, so the new unconditional description paragraph makes the fallback show the same reason twice. Please restrict the new paragraph tosurface === 'inline', or consolidate the rendering so there is a single source of description text. -
The synthetic-command check is too broad.
request.command.trim().startsWith('<')also matches valid shell commands that begin with input redirection, such as< /dev/null command. That would hide the real command from both the Command disclosure and the “Always allow” confirmation. Please identify the specific backend-generated plugin label (<tool> (plugin approval rule)) rather than every<-prefixed command, or add an explicit field to the approval payload.
One integration note: this overlaps with #62092 in the same two files. That PR also preserves multiline descriptions and bounds long content, so please rebase or coordinate the two changes to avoid a conflicting/duplicated implementation.
The focused desktop test suite (12/12), TypeScript build, eslint, Prettier, and CI otherwise passed.
What does this PR do?
Fixes the desktop inline approval card showing a useless placeholder (
<terminal> (plugin approval rule)) instead of the actual approval context when a pluginpre_tool_callhook escalates a tool call to the human-approval gate.When a plugin returns
{"action": "approve"}, the backend (tools/approval.py:request_tool_approval) sets the approval'scommandfield to a synthetic label and puts the real info indescription. The inlineApprovalBaronly renderedcommand(in the "Command" expander) and never showeddescription, so users approved without seeing what they were approving.Related Issue
Fixes #62402
Type of Change
Changes Made
apps/desktop/src/components/assistant-ui/tool/approval.tsx:descriptionas a context<p>line on the inlineApprovalBar(the floating fallback bar already did this)<) viaisSyntheticCommandand sethasCommand = falsefor those, hiding the "Command" toggle and the<pre>block in the "Always allow" dialoghasCommandconsistently in the "Always allow" dialog instead of rawrequest.command.trim()How to Test
pre_tool_callplugin rule that returns{"action": "approve"}for a command-bearing tool (e.g.terminal)description) is now visible as a context line<terminal> (plugin approval rule)label is no longer shown)command), the description is also shown as context, and the "Command" toggle still works as beforeChecklist
Code
fix(scope):,feat(scope):, etc.)vitest run --environment jsdom— 18/18 passed)Documentation & Housekeeping