Clarify MEMORY guidance over generic TTS hints (#81930)

This commit is contained in:
Gio Della-Libera
2026-05-16 19:21:24 -07:00
committed by GitHub
parent 9e67f53b91
commit 6821fbcfba
4 changed files with 44 additions and 0 deletions

View File

@@ -108,6 +108,7 @@ vi.mock("../api.js", async () => {
const {
_test,
buildTtsSystemPromptHint,
getTtsPersona,
getTtsProvider,
maybeApplyTtsToPayload,
@@ -238,6 +239,18 @@ describe("speech-core native voice-note routing", () => {
expect(_test.supportsNativeVoiceNoteTts(undefined)).toBe(false);
});
it("tells generic TTS guidance to defer to MEMORY voice-delivery instructions", () => {
const hint = buildTtsSystemPromptHint(createTtsConfig("openclaw-speech-core-tts-hint-test"));
expect(hint).toContain("Voice (TTS) is enabled.");
expect(hint).toContain(
"If workspace context (especially MEMORY.md) tells you not to use [[tts:...]] or to use a local/non-tagged voice workflow, follow that workspace instruction instead.",
);
expect(hint).toContain(
"Use [[tts:...]] and optional [[tts:text]]...[[/tts:text]] to control voice/expressiveness.",
);
});
it("marks Discord auto TTS replies as native voice messages", async () => {
await expectTtsPayloadResult({
channel: "discord",

View File

@@ -557,6 +557,7 @@ export function buildTtsSystemPromptHint(
? `Active TTS persona: ${persona.label ?? persona.id}${persona.description ? ` - ${persona.description}` : ""}.`
: undefined,
`Keep spoken text ≤${maxLength} chars to avoid auto-summary (summary ${summarize}).`,
"If workspace context (especially MEMORY.md) tells you not to use [[tts:...]] or to use a local/non-tagged voice workflow, follow that workspace instruction instead.",
"Use [[tts:...]] and optional [[tts:text]]...[[/tts:text]] to control voice/expressiveness.",
]
.filter(Boolean)

View File

@@ -734,6 +734,28 @@ describe("buildAgentSystemPrompt", () => {
);
});
it("adds MEMORY guidance when a memory file is present", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/openclaw",
contextFiles: [
{
path: "MEMORY.md",
content: "NEVER use [[tts:...]] or TTS commands; ALWAYS use local Piper.",
},
],
ttsHint:
"Voice (TTS) is enabled.\nUse [[tts:...]] and optional [[tts:text]]...[[/tts:text]] to control voice/expressiveness.",
});
expect(prompt).toContain(
"MEMORY.md: durable user preferences and behavior guidance. Keep following it throughout the session unless higher-priority instructions override.",
);
expect(prompt.indexOf("NEVER use [[tts:...]]")).toBeGreaterThan(-1);
expect(prompt.lastIndexOf("## Voice (TTS)")).toBeGreaterThan(
prompt.indexOf("NEVER use [[tts:...]]"),
);
});
it("omits project context when no context files are injected", () => {
const prompt = buildAgentSystemPrompt({
workspaceDir: "/tmp/openclaw",

View File

@@ -186,10 +186,18 @@ function buildProjectContextSection(params: {
const hasSoulFile = params.files.some(
(file) => getContextFileBasename(file.path) === "soul.md",
);
const hasMemoryFile = params.files.some(
(file) => getContextFileBasename(file.path) === "memory.md",
);
lines.push("The following project context files have been loaded:");
if (hasSoulFile) {
lines.push("SOUL.md: persona/tone. Follow it unless higher-priority instructions override.");
}
if (hasMemoryFile) {
lines.push(
"MEMORY.md: durable user preferences and behavior guidance. Keep following it throughout the session unless higher-priority instructions override.",
);
}
lines.push("");
}
for (const file of params.files) {