惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

Recent Commits to openclaw:main

fix(gateway): make bare reset commands fast docs: update crabbox skill cache-volume guidance fix(agents): route per-turn media task hints below the cache boundary… · openclaw/openclaw@778c4f9 docs: clarify message-tool-only visible replies · openclaw/openclaw@75ea8b5 feat: scope group mention patterns by channel fix(cron): accept sub-second --at datetimes resolved in a timezone (#… fix(infra): guard against overwriting corrupt target session store du… feat(workboard): add worker dispatch CLI fix(memory): respect QMD status timeout · openclaw/openclaw@1d55caa fix(ui): prefer Talk source-reply final text · openclaw/openclaw@17c2e95 fix(scripts): timeout crabbox wrapper sanity checks · openclaw/openclaw@a0d2feb refactor(telegram): keep topic thread mapping plugin-local fix(memory): fail open when embedding recall stalls feat(doctor): expose UI freshness health findings · openclaw/openclaw@2d3fa48 docs: expand MCP operator guide chore(ui): refresh fa control ui locale chore(ui): refresh nl control ui locale · openclaw/openclaw@53e0639 chore(ui): refresh vi control ui locale chore(ui): refresh pl control ui locale · openclaw/openclaw@ee39aa8 chore(ui): refresh th control ui locale chore(ui): refresh id control ui locale · openclaw/openclaw@fce45a2 chore(ui): refresh uk control ui locale chore(ui): refresh tr control ui locale · openclaw/openclaw@b335018 chore(ui): refresh ar control ui locale chore(ui): refresh it control ui locale · openclaw/openclaw@20ab73e chore(ui): refresh fr control ui locale · openclaw/openclaw@a041e39 chore(ui): refresh ko control ui locale · openclaw/openclaw@2e0d191 chore(ui): refresh ja-JP control ui locale · openclaw/openclaw@ec949a8 chore(ui): refresh es control ui locale · openclaw/openclaw@0b9193c chore(ui): refresh pt-BR control ui locale · openclaw/openclaw@aa56f59 chore(ui): refresh zh-TW control ui locale · openclaw/openclaw@10b4057 chore(ui): refresh zh-CN control ui locale · openclaw/openclaw@ecef6ae chore(ui): refresh de control ui locale · openclaw/openclaw@f456114 feat: improve MCP operator controls (#88536) · openclaw/openclaw@617c658 chore(lint): clean sms lint fallout · openclaw/openclaw@3258338 fix(ci): repair sms channel checks · openclaw/openclaw@3a4943e fix(e2e): make plugin sweep wrappers executable · openclaw/openclaw@84b025e fix(auto-reply): redact secrets in config show output (#88496) · openclaw/openclaw@a776de2 fix(ci): repair copilot sdk drift chore(lint): enable object and reassignment rules · openclaw/openclaw@f5eca3f docs: expand SMS channel setup guide · openclaw/openclaw@ea11b8a ci: harden Crabbox Testbox runs · openclaw/openclaw@d4f78c9 fix(webchat): preserve refresh-visible history and composer state (#8… fix(check): restore core typecheck feat: add Twilio SMS channel fix(telegram): support media message edits chore: remove stale unsafe assertion suppressions Revert "fix(ci): annotate unsafe boundary casts" fix(ci): keep unsafe assertion lint disabled Revert "fix(ci): clean core unsafe assertions" · openclaw/openclaw@4471335 test: remove channel test isolation hack fix(agents): clear stale compaction bindings fix(agents): skip below-target CLI compaction failures · openclaw/openclaw@5e1e029 chore: update dependencies · openclaw/openclaw@48ccc50 docs: add Skill Workshop guide docs: remove divider comments (#88115) fix(ci): clean core unsafe assertions fix(discord): deliver same-session channel replies fix(ci): annotate unsafe boundary casts · openclaw/openclaw@8a40f90 docs: add permission modes page · openclaw/openclaw@ae651e7 fix(ci): repair extension type drift · openclaw/openclaw@4d95ae3 perf: avoid blocking gateway bind on control ui build · openclaw/openclaw@e678225 chore(lint): enable structured clone rules · openclaw/openclaw@59694e8 Fix iMessage startup watch replay (#88406) · openclaw/openclaw@87664ed fix(ci): isolate timer-sensitive tests perf: lazy-load agent reply payload formatter · openclaw/openclaw@122ae5d refactor(telegram): persist plugin state in sqlite · openclaw/openclaw@930b371 chore(lint): enable additional cleanup rules · openclaw/openclaw@b9fe089 chore: remove stale dead code · openclaw/openclaw@444562b fix(ci): stabilize ui paste and telegram types · openclaw/openclaw@ce547bf fix(ci): satisfy strict nullish guards · openclaw/openclaw@d4d7fdb build(OpenClawKit): make ElevenLabsKit optional behind Talk trait · openclaw/openclaw@096bd13 chore(lint): enable more readability rules fix(ci): stop channel timers holding vitest open chore(lint): enable readability lint rules · openclaw/openclaw@deb7bc6 fix(ci): restore main validation · openclaw/openclaw@0211a3a perf: prewarm gateway runtime plugins · openclaw/openclaw@ade6e77 fix(slack): keep DM thread turns out of active steering · openclaw/openclaw@f1cb9f2 fix(commands): make /skill load workspace skills · openclaw/openclaw@667393b fix(telegram): align DM topic session routing · openclaw/openclaw@72c61bc test: keep timeout clamp checks under one second · openclaw/openclaw@b372af6 test: keep vitest cases under one second test: restore marketplace cleanup coverage · openclaw/openclaw@9f99acf fix(shared): restore number coercion barrel fix: clarify generated media reply prompts (#88458) · openclaw/openclaw@8a46790 fix(qa): clamp transport wait intervals fix(qa): clamp gateway restart polling fix(channels): clamp typing timers · openclaw/openclaw@92f1d90 fix(agents): clamp embedded run drain polling fix(sqlite): clamp WAL checkpoint intervals · openclaw/openclaw@287f531 fix(onboard): clamp gateway reachability polling · openclaw/openclaw@bb680a8 fix(nostr): bound seen tracker capacity · openclaw/openclaw@5b0036f fix(agents): clamp session suspension TTLs · openclaw/openclaw@11c050d fix(memory): clamp batch timeout minutes · openclaw/openclaw@84061c1 fix(gateway): clamp auth limiter prune intervals · openclaw/openclaw@a1d7a75 fix(memory): clamp sync interval timers · openclaw/openclaw@5c38c0c fix(gateway): clamp auth limiter durations fix(qa): clamp cron run poll intervals · openclaw/openclaw@83597b7 fix(gateway): bound health monitor intervals fix(auto-reply): clamp typing timers · openclaw/openclaw@db94eac
fix(xiaomi): support MiMo voicedesign TTS · openclaw/openclaw@f94512c
GimingRao · 2026-05-31 · via Recent Commits to openclaw:main

@@ -18,6 +18,7 @@ describe("buildXiaomiSpeechProvider", () => {

1818

expect(provider.aliases).toContain("mimo");

1919

expect(provider.models).toContain("mimo-v2.5-tts");

2020

expect(provider.models).toContain("mimo-v2-tts");

21+

expect(provider.models).toContain("mimo-v2.5-tts-voicedesign");

2122

expect(provider.voices).toContain("mimo_default");

2223

});

2324

});

@@ -81,6 +82,24 @@ describe("buildXiaomiSpeechProvider", () => {

8182

});

8283

expect(config.voice).toBe("default_zh");

8384

});

85+86+

it("accepts generic model and speaker voice aliases", () => {

87+

const config = provider.resolveConfig!({

88+

rawConfig: {

89+

providers: {

90+

xiaomi: {

91+

modelId: "mimo-v2.5-tts-voicedesign",

92+

speakerVoice: "Chloe",

93+

},

94+

},

95+

},

96+

cfg: {} as never,

97+

timeoutMs: 30000,

98+

});

99+100+

expect(config.model).toBe("mimo-v2.5-tts-voicedesign");

101+

expect(config.voice).toBe("Chloe");

102+

});

84103

});

8510486105

describe("parseDirectiveToken", () => {

@@ -179,6 +198,80 @@ describe("buildXiaomiSpeechProvider", () => {

179198

expect(transcodeAudioBufferToOpusMock).not.toHaveBeenCalled();

180199

});

181200201+

it("omits voice and uses configured style for Xiaomi voice design models", async () => {

202+

const audio = Buffer.from("fake-wav-audio").toString("base64");

203+

const mockFetch = vi.mocked(globalThis.fetch);

204+

mockFetch.mockResolvedValueOnce(

205+

new Response(JSON.stringify({ choices: [{ message: { audio: { data: audio } } }] }), {

206+

status: 200,

207+

headers: { "Content-Type": "application/json" },

208+

}),

209+

);

210+211+

const result = await provider.synthesize({

212+

text: "Hello from OpenClaw.",

213+

cfg: {} as never,

214+

providerConfig: {

215+

apiKey: "sk-test",

216+

modelId: "mimo-v2.5-tts-voicedesign",

217+

speakerVoice: "Chloe",

218+

format: "wav",

219+

style: "Warm, bright, natural voice.",

220+

},

221+

target: "audio-file",

222+

timeoutMs: 30000,

223+

});

224+225+

expect(result.outputFormat).toBe("wav");

226+

expect(result.fileExtension).toBe(".wav");

227+

expect(result.voiceCompatible).toBe(false);

228+

expect(result.audioBuffer.toString()).toBe("fake-wav-audio");

229+230+

expect(mockFetch).toHaveBeenCalledOnce();

231+

const [, init] = mockFetch.mock.calls[0] ?? [];

232+

const body = JSON.parse(init!.body as string);

233+

expect(body.model).toBe("mimo-v2.5-tts-voicedesign");

234+

expect(body.messages).toEqual([

235+

{ role: "user", content: "Warm, bright, natural voice." },

236+

{ role: "assistant", content: "Hello from OpenClaw." },

237+

]);

238+

expect(body.audio).toEqual({ format: "wav" });

239+

});

240+241+

it("uses a default style for Xiaomi voice design models", async () => {

242+

const audio = Buffer.from("fake-mp3-audio").toString("base64");

243+

const mockFetch = vi.mocked(globalThis.fetch);

244+

mockFetch.mockResolvedValueOnce(

245+

new Response(JSON.stringify({ choices: [{ message: { audio: { data: audio } } }] }), {

246+

status: 200,

247+

headers: { "Content-Type": "application/json" },

248+

}),

249+

);

250+251+

await provider.synthesize({

252+

text: "Hello from OpenClaw.",

253+

cfg: {} as never,

254+

providerConfig: {

255+

apiKey: "sk-test",

256+

model: "mimo-v2.5-tts-voicedesign",

257+

},

258+

target: "audio-file",

259+

timeoutMs: 30000,

260+

});

261+262+

expect(mockFetch).toHaveBeenCalledOnce();

263+

const [, init] = mockFetch.mock.calls[0] ?? [];

264+

const body = JSON.parse(init!.body as string);

265+

expect(body.messages).toHaveLength(2);

266+

expect(body.messages[0]?.role).toBe("user");

267+

expect(body.messages[0]?.content).toContain("natural");

268+

expect(body.messages[1]).toEqual({

269+

role: "assistant",

270+

content: "Hello from OpenClaw.",

271+

});

272+

expect(body.audio).toEqual({ format: "mp3" });

273+

});

274+182275

it("transcodes Xiaomi output to Opus for voice-note targets", async () => {

183276

const audio = Buffer.from("fake-mp3-audio").toString("base64");

184277

vi.mocked(globalThis.fetch).mockResolvedValueOnce(

@@ -209,6 +302,43 @@ describe("buildXiaomiSpeechProvider", () => {

209302

});

210303

});

211304305+

it("transcodes Xiaomi voice design output to Opus for voice-note targets", async () => {

306+

const audio = Buffer.from("fake-wav-audio").toString("base64");

307+

vi.mocked(globalThis.fetch).mockResolvedValueOnce(

308+

new Response(JSON.stringify({ choices: [{ message: { audio: { data: audio } } }] }), {

309+

status: 200,

310+

headers: { "Content-Type": "application/json" },

311+

}),

312+

);

313+

transcodeAudioBufferToOpusMock.mockResolvedValueOnce(Buffer.from("fake-opus-audio"));

314+315+

const result = await provider.synthesize({

316+

text: "Hello from OpenClaw.",

317+

cfg: {} as never,

318+

providerConfig: {

319+

apiKey: "sk-test",

320+

model: "mimo-v2.5-tts-voicedesign",

321+

format: "wav",

322+

},

323+

target: "voice-note",

324+

timeoutMs: 30000,

325+

});

326+327+

expect(result.outputFormat).toBe("opus");

328+

expect(result.fileExtension).toBe(".opus");

329+

expect(result.voiceCompatible).toBe(true);

330+

expect(result.audioBuffer.toString()).toBe("fake-opus-audio");

331+

expect(transcodeAudioBufferToOpusMock).toHaveBeenCalledWith({

332+

audioBuffer: Buffer.from("fake-wav-audio"),

333+

inputExtension: "wav",

334+

tempPrefix: "tts-xiaomi-",

335+

timeoutMs: 30000,

336+

});

337+

const [, init] = vi.mocked(globalThis.fetch).mock.calls[0] ?? [];

338+

const body = JSON.parse(init!.body as string);

339+

expect(body.audio).toEqual({ format: "wav" });

340+

});

341+212342

it("caps oversized TTS request timeouts before scheduling or fetching", async () => {

213343

const audio = Buffer.from("fake-mp3-audio").toString("base64");

214344

const timeoutSpy = vi