diff --git a/src/main/java/com/volcengine/ark/runtime/selfhosted/DefaultTools.java b/src/main/java/com/volcengine/ark/runtime/selfhosted/DefaultTools.java index ce3ca82..f036e53 100644 --- a/src/main/java/com/volcengine/ark/runtime/selfhosted/DefaultTools.java +++ b/src/main/java/com/volcengine/ark/runtime/selfhosted/DefaultTools.java @@ -172,7 +172,7 @@ public String name() { public ToolResult execute(Object input, ToolContext context) { try { Map args = asMap(input); - Path path = safePath(context, readFilePath(args)); + Path path = safePath(context, filePath(args)); List viewRange = readViewRange(args.get("view_range")); boolean hasViewRange = viewRange != null && !viewRange.isEmpty(); Long offset = optionalLong(args, "offset"); @@ -250,7 +250,7 @@ public String name() { public ToolResult execute(Object input, ToolContext context) { try { Map args = asMap(input); - String rawPath = firstNonEmpty(stringValue(args.get("path")), stringValue(args.get("file"))); + String rawPath = filePath(args); Path path = safePath(context, rawPath); String content = stringValue(args.get("content")); Files.createDirectories(path.getParent()); @@ -276,7 +276,7 @@ public String name() { public ToolResult execute(Object input, ToolContext context) { try { Map args = asMap(input); - String rawPath = firstNonEmpty(stringValue(args.get("path")), stringValue(args.get("file"))); + String rawPath = filePath(args); Path path = safePath(context, rawPath); String oldString = firstNonEmpty(stringValue(args.get("old_string")), stringValue(args.get("old"))); String newString = firstNonEmpty(stringValue(args.get("new_string")), stringValue(args.get("new"))); @@ -494,7 +494,7 @@ private static long longValue(Object value, String name) { } } - private static String readFilePath(Map args) { + private static String filePath(Map args) { String path = ""; for (String name : new String[] {"file_path", "path", "file"}) { Object value = args.get(name); diff --git a/src/test/java/com/volcengine/ark/runtime/selfhosted/DefaultToolsTest.java b/src/test/java/com/volcengine/ark/runtime/selfhosted/DefaultToolsTest.java index 063f01c..aa3eedc 100644 --- a/src/test/java/com/volcengine/ark/runtime/selfhosted/DefaultToolsTest.java +++ b/src/test/java/com/volcengine/ark/runtime/selfhosted/DefaultToolsTest.java @@ -172,6 +172,69 @@ public void readKeepsLegacyInputsWithoutAmbiguity() throws Exception { rangeConflict.getContent().get(0).getText()); } + @Test + public void fileToolsAcceptPathAliases() throws Exception { + Path workdir = Files.createTempDirectory("ark-java-file-aliases-"); + ToolContext context = new ToolContext(workdir.toString()); + + for (String key : new String[] {"file_path", "path", "file"}) { + String name = key + ".txt"; + Map writeInput = new LinkedHashMap<>(); + writeInput.put(key, name); + writeInput.put("content", "old"); + assertFalse(new DefaultTools.WriteTool().execute(writeInput, context).isError()); + + assertFalse(new DefaultTools.ReadTool() + .execute(Collections.singletonMap(key, name), context) + .isError()); + + Map editInput = new LinkedHashMap<>(); + editInput.put(key, name); + editInput.put("old_string", "old"); + editInput.put("new_string", "new"); + assertFalse(new DefaultTools.EditTool().execute(editInput, context).isError()); + assertEquals( + "new", + new String(Files.readAllBytes(workdir.resolve(name)), java.nio.charset.StandardCharsets.UTF_8)); + } + } + + @Test + public void fileToolsValidatePathAliases() throws Exception { + Path workdir = Files.createTempDirectory("ark-java-file-alias-validation-"); + Files.write(workdir.resolve("example.txt"), "old".getBytes(java.nio.charset.StandardCharsets.UTF_8)); + ToolContext context = new ToolContext(workdir.toString()); + Map common = new LinkedHashMap<>(); + common.put("file_path", "example.txt"); + common.put("path", "example.txt"); + common.put("file", "example.txt"); + common.put("content", "old"); + common.put("old_string", "old"); + common.put("new_string", "new"); + + for (Tool tool : new Tool[] { + new DefaultTools.ReadTool(), new DefaultTools.WriteTool(), new DefaultTools.EditTool() + }) { + assertFalse(tool.execute(common, context).isError()); + + Map conflictInput = new LinkedHashMap<>(common); + conflictInput.put("path", "other.txt"); + ToolResult conflict = tool.execute(conflictInput, context); + assertTrue(conflict.isError()); + assertEquals( + "file_path, path, and file must not conflict", + conflict.getContent().get(0).getText()); + + Map missingInput = new LinkedHashMap<>(); + missingInput.put("content", "new"); + missingInput.put("old_string", "old"); + missingInput.put("new_string", "new"); + ToolResult missing = tool.execute(missingInput, context); + assertTrue(missing.isError()); + assertEquals("file_path is required", missing.getContent().get(0).getText()); + } + } + @Test public void bashScrubsSensitiveExplicitEnvironment() throws Exception { Path workdir = Files.createTempDirectory("ark-java-tools-");