From 870c2cc583608492b680d52feb822b38bf3d18d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=AD=90=E9=BB=98?= <925456043@qq.com> Date: Thu, 20 Aug 2026 11:23:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=BB=9F=E4=B8=80=20Shell=20=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E5=BC=80=E5=85=B3=E8=AF=AD=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 关闭 Shell 审批时移除命令级审批策略与强制审批元数据 - 补充适配器与运行时回归测试 --- .../tool/operate/AgentOperateToolAdapter.java | 11 +++++++---- .../agentscope/AgentScopeStatefulRuntimeTest.java | 12 ++++++------ .../tool/operate/AgentOperateToolAdapterTest.java | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/easy-agents-agent-runtime/src/main/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapter.java b/easy-agents-agent-runtime/src/main/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapter.java index dc33402..516f231 100644 --- a/easy-agents-agent-runtime/src/main/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapter.java +++ b/easy-agents-agent-runtime/src/main/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapter.java @@ -119,7 +119,10 @@ public class AgentOperateToolAdapter { toolkit.registerAgentTool(shellTool); AgentToolSpec shellToolSpec = toolSpec( spec, EXECUTE_SHELL_COMMAND_TOOL, "Execute shell command.", true); - shellToolSpec.setApprovalPolicy(shellTool::approvalEvaluation); + if (shellToolSpec.isApprovalRequired()) { + // 命令级审批策略服从 Agent 的 Shell 审批开关;关闭后仅保留安全校验。 + shellToolSpec.setApprovalPolicy(shellTool::approvalEvaluation); + } toolSpecs.add(shellToolSpec); } default -> throw new AgentRuntimeException("Unsupported agent operate tool type: " + type); @@ -157,7 +160,7 @@ public class AgentOperateToolAdapter { toolSpec.setVisibility(AgentToolVisibility.VISIBLE); toolSpec.setApprovalRequired(approvalRequired); toolSpec.setApprovalRequest(approvalRequest(operateSpec, approvalRequired)); - toolSpec.setMetadata(metadata(operateSpec)); + toolSpec.setMetadata(metadata(operateSpec, approvalRequired)); return toolSpec; } @@ -173,11 +176,11 @@ public class AgentOperateToolAdapter { return defaultRequest; } - private Map metadata(AgentOperateToolSpec spec) { + private Map metadata(AgentOperateToolSpec spec, boolean approvalRequired) { Map metadata = new LinkedHashMap<>(); metadata.put("operateTool", true); metadata.put("operateToolType", spec.getType().name()); - if (spec.getType() == AgentOperateToolType.SHELL) { + if (spec.getType() == AgentOperateToolType.SHELL && approvalRequired) { metadata.put("forceApprovalCommands", List.of("rm")); metadata.put("forceApprovalCommandArgument", "command"); } diff --git a/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/agentscope/AgentScopeStatefulRuntimeTest.java b/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/agentscope/AgentScopeStatefulRuntimeTest.java index 1ee90f9..95886fe 100644 --- a/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/agentscope/AgentScopeStatefulRuntimeTest.java +++ b/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/agentscope/AgentScopeStatefulRuntimeTest.java @@ -282,13 +282,13 @@ public class AgentScopeStatefulRuntimeTest { } @Test - public void shouldForceApprovalForRemoveWhenShellApprovalIsDisabled() { + public void shouldBypassRemoveApprovalWhenShellApprovalIsDisabled() { AgentInitRequest request = initRequest(); AgentOperateToolSpec shell = operateToolSpec(AgentOperateToolType.SHELL); shell.setApprovalRequired(false); request.getAgentDefinition().setOperateToolSpecs(List.of(shell)); AgentScopeReActRuntime runtime = runtimeWithModel(List.of(ChatResponse.builder() - .id("forced-remove-message") + .id("remove-message") .content(List.of(ToolUseBlock.builder() .id("call-remove") .name(AgentOperateToolAdapter.EXECUTE_SHELL_COMMAND_TOOL) @@ -303,11 +303,11 @@ public class AgentScopeStatefulRuntimeTest { .block(Duration.ofSeconds(5)); Assert.assertNotNull(events); - Assert.assertTrue(events.stream() - .anyMatch(event -> event.getEventType() == AgentRuntimeEventType.TOOL_APPROVAL_REQUIRED)); - Assert.assertTrue(events.stream() - .anyMatch(event -> event.getEventType() == AgentRuntimeEventType.SUSPENDED)); Assert.assertFalse(events.stream() + .anyMatch(event -> event.getEventType() == AgentRuntimeEventType.TOOL_APPROVAL_REQUIRED)); + Assert.assertFalse(events.stream() + .anyMatch(event -> event.getEventType() == AgentRuntimeEventType.SUSPENDED)); + Assert.assertTrue(events.stream() .anyMatch(event -> event.getEventType() == AgentRuntimeEventType.TOOL_RESULT)); } diff --git a/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapterTest.java b/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapterTest.java index 537d507..e4c31ee 100644 --- a/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapterTest.java +++ b/easy-agents-agent-runtime/src/test/java/com/easyagents/agent/runtime/tool/operate/AgentOperateToolAdapterTest.java @@ -68,6 +68,21 @@ public class AgentOperateToolAdapterTest { Assert.assertFalse(toolSpecs.get(0).getMetadata().containsKey("baseDir")); } + @Test + public void shouldDisableAllShellApprovalPoliciesWithAgentSwitch() { + Toolkit toolkit = new Toolkit(); + AgentOperateToolSpec spec = spec(AgentOperateToolType.SHELL); + spec.setApprovalRequired(false); + + List toolSpecs = adapter.register(List.of(spec), toolkit); + + Assert.assertEquals(1, toolSpecs.size()); + Assert.assertFalse(toolSpecs.get(0).isApprovalRequired()); + Assert.assertNull(toolSpecs.get(0).getApprovalPolicy()); + Assert.assertFalse(toolSpecs.get(0).getMetadata().containsKey("forceApprovalCommands")); + Assert.assertFalse(toolSpecs.get(0).getMetadata().containsKey("forceApprovalCommandArgument")); + } + @Test public void shouldRegisterPatchWithDefaultHitlDisabled() { Toolkit toolkit = new Toolkit();