核心授权逻辑。源码: permissions.rs:89-134 决策流程: 1. Allow 模式 → 放行(跳过一切检查) 2. current >= required → 放行(权限足够) 3. Prompt 模式 → 询问用户 4. WorkspaceWrite + 需要 DangerFullAccess → 询问用户 (最常见: 普通模式下执行危险命令,弹窗确认) 5. 其他 → 拒绝
(
self,
tool_name: str,
input_str: str,
prompter: Optional[PermissionPrompter] = None,
)
| 149 | return self._tool_requirements.get(tool_name, PermissionMode.DANGER_FULL_ACCESS) |
| 150 | |
| 151 | def authorize( |
| 152 | self, |
| 153 | tool_name: str, |
| 154 | input_str: str, |
| 155 | prompter: Optional[PermissionPrompter] = None, |
| 156 | ) -> PermissionResult: |
| 157 | """核心授权逻辑。源码: permissions.rs:89-134 |
| 158 | |
| 159 | 决策流程: |
| 160 | 1. Allow 模式 → 放行(跳过一切检查) |
| 161 | 2. current >= required → 放行(权限足够) |
| 162 | 3. Prompt 模式 → 询问用户 |
| 163 | 4. WorkspaceWrite + 需要 DangerFullAccess → 询问用户 |
| 164 | (最常见: 普通模式下执行危险命令,弹窗确认) |
| 165 | 5. 其他 → 拒绝 |
| 166 | """ |
| 167 | current = self._active_mode |
| 168 | required = self.required_mode_for(tool_name) |
| 169 | |
| 170 | # 1 & 2: Allow 直接放行,或权限足够 |
| 171 | if current == PermissionMode.ALLOW or current >= required: |
| 172 | return PermissionResult.allow() |
| 173 | |
| 174 | # 3 & 4: 需要询问用户的场景 |
| 175 | need_prompt = ( |
| 176 | current == PermissionMode.PROMPT |
| 177 | or (current == PermissionMode.WORKSPACE_WRITE |
| 178 | and required == PermissionMode.DANGER_FULL_ACCESS) |
| 179 | ) |
| 180 | |
| 181 | if need_prompt: |
| 182 | if prompter is not None: |
| 183 | request = PermissionRequest( |
| 184 | tool_name=tool_name, |
| 185 | input=input_str, |
| 186 | current_mode=current, |
| 187 | required_mode=required, |
| 188 | ) |
| 189 | return prompter.decide(request) |
| 190 | # 没有 prompter → 需要升级但没人可问 → 拒绝 |
| 191 | return PermissionResult.deny( |
| 192 | f"tool '{tool_name}' requires approval to escalate " |
| 193 | f"from {current.as_str()} to {required.as_str()}" |
| 194 | ) |
| 195 | |
| 196 | # 5: 其他情况 → 拒绝 |
| 197 | return PermissionResult.deny( |
| 198 | f"tool '{tool_name}' requires {required.as_str()} permission; " |
| 199 | f"current mode is {current.as_str()}" |
| 200 | ) |
no test coverage detected