Skip to content

[Bug]: 桌面端点击"总是允许"后,同一会话内后续其他工具调用仍然弹窗 #3607

@HorusJiang

Description

@HorusJiang

Version line

v2 — Go rewrite (1.x), main-v2 (active development)

Exact version

v1.3.0

What happened?

在桌面端会话中,触发一个工具调用(如 write_file)后,点击权限确认弹窗中的"总是允许"(Allow Persistently)按钮。该工具调用被放行,但模型继续执行到调用另一个不同的工具时(如 bash),再次弹出权限确认框。用户预期"总是允许"意味着会话内不再被打扰,但实际上每个不同工具都需要单独点一次"总是允许",且 persist 写入配置后当前会话内并未生效。会话始终没有关闭,问题发生在同一会话的持续交互过程中。

代码分析:
前端 ApprovalModal.tsx 在点击"总是允许"时调用 onAnswer(true, true, true),对应 allow=true, session=true, persist=true。

后端 controller.go 的 requestApproval() 中有两段逻辑:

  1. Session 级 grant 是按工具名分别存储的:
    key := tool
    if r.allow && r.session && tool != planApprovalTool {
    c.granted[key] = true // 只允许了当前这一个工具
    }
    c.granted["write_file"] 不会放行 bash,所以不同工具需要分别授权。

  2. Persist(持久化到配置)在当前会话内不生效:
    persist=true 时调用 OnRemember(toolName) 将规则写入 reasonix.toml 的 [permissions].allow,但 Gate.Policy 是一个值类型 struct,写入配置后并没有重新加载到当前会话的 Policy 中,因此 Policy.Decide() 在当前会话内依然看不到新写入的 allow 规则。

两个问题叠加的结果:每个工具都要单独点一次"总是允许",而且即使都点了,当前会话内 persist 规则不重新加载,导致用户觉得"总是允许"根本没用。

另有一个相关 issue #3271 提到了类似问题,但该 issue 侧重 plan mode 流程中的权限差异,而本 issue 侧重的是"总是允许"按钮的实际行为与用户预期不符。

Steps to reproduce

  1. 桌面端新建一个会话
  2. 触发一个工具调用(如 write_file)
  3. 在弹出的权限确认框中点击"总是允许"(Allow Persistently,key "3")
  4. 该工具调用被放行,当前会话内该工具不再弹窗 ✅
  5. 模型继续执行,调用另一个不同的工具(如 bash)
  6. 再次弹出权限确认框 ❌(用户预期"总是允许"后应不再弹窗)
  7. 用户再次点击"总是允许",后续又遇到第三个工具时仍然弹窗

OS / platform

Windows 11

Relevant logs or output

Metadata

Metadata

Assignees

No one assigned

    Labels

    agentCore agent loop (internal/agent, internal/control)bugSomething isn't workingdesktopWails desktop app (desktop/**)v2Go rewrite (1.x) — main-v2 branch, active developmentwindowsWindows-specific

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions