agentscope-ai / agentscope-ai/agentscope-java

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

オープン
#2,870 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
bug
主要言語
Java
スター
5.6k
フォーク
1.3k
平均マージ
4日 12時間
マージ済み PR(30日)
77

説明

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

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。