






















@@ -63,7 +63,7 @@ vi.mock("openclaw/plugin-sdk/channel-targets", () => ({
6363normalizeChannelId: (channel: string | undefined) => channel?.trim().toLowerCase() ?? null,
6464resolveChannelTtsVoiceDelivery: (channel: string | undefined) => {
6565const normalized = channel?.trim().toLowerCase();
66-if (normalized === "bluebubbles") {
66+if (normalized === "voice-memo-chat") {
6767return {
6868synthesisTarget: "audio-file",
6969audioFileFormats: ["mp3", "caf", "audio/mpeg", "audio/x-caf"],
@@ -116,14 +116,7 @@ const {
116116 textToSpeechTelephony,
117117} = await import("./tts.js");
118118119-const nativeVoiceNoteChannels = [
120-"bluebubbles",
121-"discord",
122-"feishu",
123-"matrix",
124-"telegram",
125-"whatsapp",
126-] as const;
119+const nativeVoiceNoteChannels = ["discord", "feishu", "matrix", "telegram", "whatsapp"] as const;
127120128121function createMockSpeechProvider(
129122id = "mock",
@@ -222,11 +215,11 @@ describe("speech-core native voice-note routing", () => {
222215});
223216});
224217225-it("keeps BlueBubbles synthesis on mp3 audio-file output but delivers it as a voice memo", async () => {
218+it("keeps compatible audio-file synthesis deliverable as a voice memo", async () => {
226219await expectTtsPayloadResult({
227-channel: "bluebubbles",
228-prefsName: "openclaw-speech-core-tts-bluebubbles-mp3-test",
229-text: "This BlueBubbles reply should be delivered as an iMessage voice memo.",
220+channel: "voice-memo-chat",
221+prefsName: "openclaw-speech-core-tts-voice-memo-mp3-test",
222+text: "This reply should be delivered as a native voice memo.",
230223target: "audio-file",
231224audioAsVoice: true,
232225mediaExtension: "mp3",
@@ -239,25 +232,25 @@ describe("speech-core native voice-note routing", () => {
239232});
240233});
241234242-it("does not mark unsupported BlueBubbles audio-file output as a voice memo", async () => {
235+it("does not mark unsupported audio-file output as a voice memo", async () => {
243236await expectTtsPayloadResult({
244-channel: "bluebubbles",
245-prefsName: "openclaw-speech-core-tts-bluebubbles-ogg-test",
246-text: "This BlueBubbles reply should stay a regular audio attachment.",
237+channel: "voice-memo-chat",
238+prefsName: "openclaw-speech-core-tts-voice-memo-ogg-test",
239+text: "This reply should stay a regular audio attachment.",
247240target: "audio-file",
248241audioAsVoice: undefined,
249242});
250243});
251244252-it("pre-transcodes BlueBubbles synthesized mp3 to opus-in-CAF when the host can satisfy preferAudioFileFormat", async () => {
245+it("pre-transcodes synthesized mp3 to opus-in-CAF when the host can satisfy preferAudioFileFormat", async () => {
253246transcodeAudioBufferMock.mockResolvedValueOnce({
254247ok: true,
255248buffer: Buffer.from("transcoded-caf"),
256249});
257250await expectTtsPayloadResult({
258-channel: "bluebubbles",
259-prefsName: "openclaw-speech-core-tts-bluebubbles-caf-transcode-test",
260-text: "This BlueBubbles reply should be pre-transcoded to a native voice-memo CAF.",
251+channel: "voice-memo-chat",
252+prefsName: "openclaw-speech-core-tts-voice-memo-caf-transcode-test",
253+text: "This reply should be pre-transcoded to a native voice-memo CAF.",
261254target: "audio-file",
262255audioAsVoice: true,
263256mediaExtension: "caf",
@@ -279,15 +272,14 @@ describe("speech-core native voice-note routing", () => {
279272reason: "transcoder-failed",
280273detail: "exit-1",
281274});
282-// Even though the transcode failed, the original mp3 still satisfies
283-// BlueBubbles' audioFileFormats list, so the channel still flips
284-// audioAsVoice. The user gets the v2026.4.26 PCM-CAF behavior (a voice
285-// memo bubble, possibly with bad duration) instead of a regression — and
286-// the failure is logged via the call site in tts.ts so it isn't silent.
275+// Even though the transcode failed, the original mp3 still satisfies the
276+// channel audioFileFormats list, so the channel still flips audioAsVoice.
277+// The user gets a voice memo bubble, possibly with bad duration, instead
278+// of a regression. The failure is logged via the call site in tts.ts.
287279await expectTtsPayloadResult({
288-channel: "bluebubbles",
289-prefsName: "openclaw-speech-core-tts-bluebubbles-caf-fallback-test",
290-text: "This BlueBubbles reply should fall back to the original mp3.",
280+channel: "voice-memo-chat",
281+prefsName: "openclaw-speech-core-tts-voice-memo-caf-fallback-test",
282+text: "This reply should fall back to the original mp3.",
291283target: "audio-file",
292284audioAsVoice: true,
293285mediaExtension: "mp3",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。