diff --git a/packages/mnemopi/src/core/local-llm.ts b/packages/mnemopi/src/core/local-llm.ts index 00817c49c..66fb39647 100644 --- a/packages/mnemopi/src/core/local-llm.ts +++ b/packages/mnemopi/src/core/local-llm.ts @@ -254,7 +254,7 @@ export function cleanOutput(text: string): string { .replaceAll("<|user|>", "") .replaceAll("", "") .trim() - .replace(/[\s\S]*?<\/think>/gi, "") + .replace(/^(?:\s*[\s\S]*?<\/think>)+\s*/i, "") .replace(/^(Summarize the following memories.*?[.!?:]\s*)/is, "") .replace(/^(Preserve facts.*?[.!?:]\s*)/is, "") .replace(/^Source:.*?\n/im, "") diff --git a/packages/mnemopi/test/local-llm.test.ts b/packages/mnemopi/test/local-llm.test.ts index a8b80d2b9..e3f94135a 100644 --- a/packages/mnemopi/test/local-llm.test.ts +++ b/packages/mnemopi/test/local-llm.test.ts @@ -11,6 +11,7 @@ import { callLocalLlm, callRemoteLlm, chunkMemoriesByBudget, + cleanOutput, complete, llmAvailable, localGgufAvailable, @@ -83,6 +84,10 @@ describe("local LLM TypeScript port", () => { ); }); + it("preserves a literal think tag that follows real content", () => { + expect(cleanOutput("The XML tag is keep")).toBe("The XML tag is keep"); + }); + it("keeps local GGUF unavailable and returns null for local completion", async () => { expect(localGgufAvailable()).toBe(false); expect(await callLocalLlm("prompt")).toBeNull();