agentscope-ai / agentscope-ai/agentscope-java
[Bug]: ACCEPT_EDITS ignores working directories — in-scope edit tools always ask
- Linguagem predominante
- Java
- Estrelas
- 5.6k
- Forks
- 1.3k
- Merge médio
- 4d 12h
- PRs com merge (30d)
- 77
Descrição
**AgentScope-Java is an open-source project. To involve a broader community, we recommend asking your questions in English.**
**Describe the bug**
Under `PermissionMode.ACCEPT_EDITS`, edit tools (`write_file`, `edit_file`, `write_text_file`, `insert_text_file`, …) operating on files **inside a configured working directory** return **ASK** instead of the documented **ALLOW**. Configured working directories are effectively dead configuration — nothing in the permission evaluation path ever consumes `PermissionContextState#getWorkingDirectories()`.
This breaks the contract declared consistently in three places:
- `PermissionMode.java:27` — *"`ACCEPT_EDITS`: file edits inside working directories are auto-allowed"*
- `AdditionalWorkingDirectory.java:25` — *"Working directories drive the auto-allow behaviour of `ACCEPT_EDITS`"*
- `docs/v2/{en,zh}/docs/building-blocks/permission-system.md` — mode table: "Auto-allow file ops inside the working directory", plus the decision-flow diagram ("ACCEPT_EDITS + safe file op? → ALLOW")
A side effect: under `DONT_ASK`, the wrongly-produced ASK is demoted to **DENY**, so unattended runs silently reject in-scope edits.
**To Reproduce**
Steps to reproduce the behavior:
1. Your code — a minimal JUnit test against the current engine (verified on current `main`):
```java
import io.agentscope.core.permission.*;
import io.agentscope.core.tool.ToolBase;
import io.agentscope.core.tool.Toolkit;
import io.agentscope.core.tool.file.WriteFileTool;
import java.nio.file.Path;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
class AcceptEditsReproTest {
@Test
void acceptEditsAsksForInScopeEdit(@TempDir Path workDir) {
PermissionContextState context = PermissionContextState.builder()
.mode(PermissionMode.ACCEPT_EDITS)
.addWorkingDirectory(workDir.toString(),
new AdditionalWorkingDirectory(workDir.toString(), "session"))
.build();
PermissionEngine engine = new PermissionEngine(context);
Toolkit toolkit = new Toolkit();
toolkit.registerTool(new WriteFileTool());
ToolBase writeTextFile = (ToolBase) toolkit.getTool("write_text_file");
PermissionDecision decision = engine.checkPermission(
writeTextFile,
Map.of("file_path", workDir.resolve("demo.txt").toString(),
"content", "hello"))
.block();
// Expected: ALLOW | Actual: ASK
System.out.println(decision.getBehavior() + " | " + decision.getMessage());
}
}
```
2. How to execute:
```bash
mvn -pl agentscope-core test -Dtest=AcceptEditsReproTest
```
3. See error (actual console output):
```
ASK | Permission required for write_text_file
```
**Expected behavior**
`ACCEPT_EDITS` + an edit tool + every operated path resolving inside a configured working directory → **ALLOW**, exactly as the `PermissionMode` / `AdditionalWorkingDirectory` javadoc and the permission-system documentation promise. Paths outside every working directory should keep falling through to the default ASK.
**Error messages**
No exception — the failure is a wrong decision rather than an error. The engine returns:
- behavior: `ASK`
- message: `Permission required for write_text_file`
- decision_reason: `Mode: accept_edits`
**Environment (please complete the following information):**
- AgentScope-Jafe Version: 2.0.3-SNAPSHOT (main @ `c32de522`; also confirmed unchanged on latest main `a37bfa85`)
- Java Version: 21 (Temurin 21.0.11)
- OS: macOS 26.2 (logic-only bug, OS-independent)
**Additional context**
Root cause (traced through `PermissionEngine.checkPermission`):
1. `PermissionEngine#checkExploreMode` handles `ACCEPT_EDITS` only for `tool.isReadOnly()` tools; edit tools get `null` and fall through.
2. `PermissionEngine` never reads `context.getWorkingDirectories()` — a global search shows no production consumer of the working-directory map in the permission path (`AgentSpawnTool` only merges the map into child contexts).
3. The default `ToolBase#checkPermissions` returns plain `PASSTHROUGH` and the engine has no way to know which tool argument is a file path — so step 4 (allow rules), step 5 (BYPASS) and step 6 (default ASK) decide, yielding ASK.
I have a working fix on a local branch and would be happy to open a PR: a declarative tool-side path contract (`@Tool(filePathParams = {...})` / `ToolBase.builder().filePathParams(...)`) that enables a path-aware default `checkPermissions` in `ToolBase` (dangerous path → bypass-immune Safety-ASK; `ACCEPT_EDITS` + all declared paths inside a working directory → ALLOW; otherwise PASSTHROUGH), leaving `PermissionEngine` untouched. The built-in edit tools then simply declare their path parameter.
Related: #2137 asks for propagating parent working directories into spawned subagent contexts. That is a different layer (context propagation vs. engine enforcement) and the two compose — once child contexts receive working directories, the fix proposed here makes the engine actually honor them.
Guia de contribuição
Avaliação
Esta issue ainda não foi avaliada.