docs: finalize AI test plugin usage and CodeFree protocol

This commit is contained in:
张家训
2026-08-04 17:28:58 +08:00
parent c8e114e700
commit 556ab32e5f
5 changed files with 72 additions and 8 deletions
@@ -27,9 +27,9 @@ public class CodeFreeCliTestGenerationProvider implements TestGenerationProvider
command.add("/c");
}
command.add(request.codeFreeCommand());
command.add(request.prompt());
command.addAll(List.of("--channel", "CI", "--approval-mode", "plan",
"--max-session-turns", "1", "--output-format", "json"));
command.add(request.prompt());
CommandResult result = processExecutor.execute(new CommandSpec(request.workingDirectory(),
command, Map.of(), request.timeout()), output);
if (!result.successful()) {
@@ -31,8 +31,14 @@ public class CodeFreeResultParser {
throw new IllegalArgumentException("CodeFree output has no successful result record");
}
String innerText = resultRecord.getString("result");
if (innerText == null || innerText.contains("```")) {
throw new IllegalArgumentException("CodeFree result must be plain JSON without Markdown fences");
if (innerText == null) {
throw new IllegalArgumentException("CodeFree result payload is required");
}
innerText = innerText.trim();
if (innerText.startsWith("```json") && innerText.endsWith("```")) {
innerText = innerText.substring("```json".length(), innerText.length() - 3).trim();
} else if (innerText.contains("```")) {
throw new IllegalArgumentException("CodeFree result contains an unsupported Markdown fence");
}
final JSONObject inner;
try {
@@ -32,15 +32,18 @@ class CodeFreeCliTestGenerationProviderTest {
};
CodeFreeCliTestGenerationProvider provider =
new CodeFreeCliTestGenerationProvider(executor, new CodeFreeResultParser());
String prompt = "return-json";
TestGenerationResult result = provider.generate(new TestGenerationRequest(
workingDirectory, "codefree", "只返回JSON", Duration.ofMinutes(5)), ignored -> { });
workingDirectory, "codefree", prompt, Duration.ofMinutes(5)), ignored -> { });
assertTrue(result.successful());
assertTrue(captured.get().command().containsAll(java.util.List.of(
"--channel", "CI", "--approval-mode", "plan", "--max-session-turns", "1",
"--output-format", "json")));
assertFalse(captured.get().command().contains("--model"));
assertTrue(captured.get().command().contains("只返回JSON"));
assertTrue(captured.get().command().contains(prompt));
assertTrue(captured.get().command().indexOf("--output-format")
< captured.get().command().indexOf(prompt));
}
}
@@ -28,10 +28,14 @@ class CodeFreeResultParserTest {
}
@Test
void rejectsMarkdownWrappedOrMalformedInnerResults() {
String outer = "[{\"type\":\"result\",\"subtype\":\"success\",\"result\":\"```json {} ```\"}]";
void acceptsSingleJsonFenceButRejectsProseOrMalformedResults() {
String fenced = "```json\n{\"action\":\"DIAGNOSE_ONLY\",\"tests\":[]}\n```";
String outer = "[{\"type\":\"result\",\"subtype\":\"success\",\"result\":"
+ com.alibaba.fastjson.JSON.toJSONString(fenced) + "}]";
String prose = "[{\"type\":\"result\",\"subtype\":\"success\",\"result\":\"Here: {}\"}]";
assertThrows(IllegalArgumentException.class, () -> parser.parse(outer));
assertEquals("DIAGNOSE_ONLY", parser.parse(outer).action());
assertThrows(IllegalArgumentException.class, () -> parser.parse(prose));
assertThrows(IllegalArgumentException.class, () -> parser.parse("not-json"));
}
}