diff --git a/.gitignore b/.gitignore index 2e20f10d..dd12de0d 100644 --- a/.gitignore +++ b/.gitignore @@ -98,7 +98,6 @@ CLAUDE.md # Codex CLI local artifacts .codex/ -.superpowers/ # Sync tooling local state (generated each run; report is intentionally tracked) scripts/.*-sync-state.json diff --git a/mateclaw-server/src/main/java/vip/mate/wiki/service/WikiTransformationExecutor.java b/mateclaw-server/src/main/java/vip/mate/wiki/service/WikiTransformationExecutor.java index fa4c16a4..63848986 100644 --- a/mateclaw-server/src/main/java/vip/mate/wiki/service/WikiTransformationExecutor.java +++ b/mateclaw-server/src/main/java/vip/mate/wiki/service/WikiTransformationExecutor.java @@ -144,12 +144,16 @@ public class WikiTransformationExecutor { ChatResponse resp = chatModel.call(new Prompt(List.of( new SystemMessage(systemPrompt), new UserMessage(userPrompt)))); - String output = (resp == null || resp.getResult() == null + String rawOutput = (resp == null || resp.getResult() == null || resp.getResult().getOutput() == null) ? null : resp.getResult().getOutput().getText(); - if (output == null || output.isBlank()) { + if (rawOutput == null || rawOutput.isBlank()) { throw new IllegalStateException("LLM returned empty output"); } + String output = cleanLlmOutput(rawOutput); + if (output.isBlank()) { + throw new IllegalStateException("LLM output was empty after cleanup"); + } // Honour a mid-flight cancel: the cancel endpoint flipped the run // row to 'cancelled' while the LLM was still working. Drop the // output and stop here rather than overwrite the cancelled state. @@ -252,6 +256,51 @@ public class WikiTransformationExecutor { return (t == null || t.isBlank()) ? ("raw#" + raw.getId()) : t; } + /** Recognises the conversational openers LLMs sometimes prepend even when + * the system prompt told them not to. Lines matching this pattern at the + * very start of the output are dropped. */ + private static final java.util.regex.Pattern PREAMBLE_PATTERN = + java.util.regex.Pattern.compile( + "^\\s*(以下是|下面是|这是|根据您的要求|Sure(?:!|,)?|Of course[!,]?|Here(?:'s| is| are)|Certainly[!,]?|Got it[!,]?)[^\\n]*[::][^\\n]*\\n+", + java.util.regex.Pattern.CASE_INSENSITIVE); + + /** + * Normalise raw LLM output before persisting: + *