agentscope-ai / agentscope-ai/agentscope-java

[Bug]: ACCEPT_EDITS ignores working directories — in-scope edit tools always ask

Ouverte
#2,870 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
bug
Langage dominant
Java
Étoiles
5.6k
Forks
1.3k
Merge moyen
4 j 12 h
PR mergées (30 j)
77

Description

**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.

Guide de contribution

Ouvrir le guide de contribution

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.