fix(tts): use resolved config for tool synthesis

This commit is contained in:
Peter Steinberger
2026-04-25 05:18:34 +01:00
parent c2139635ff
commit b84e57fca3
3 changed files with 64 additions and 1 deletions

View File

@@ -77,6 +77,7 @@ Docs: https://docs.openclaw.ai
- Exec approvals: allow bare command-name allowlist patterns to match PATH-resolved executable basenames without trusting `./tool` or absolute path-selected binaries. Fixes #71315. Thanks @chen-zhang-cs-code and @dengluozhang.
- Config/recovery: skip whole-file last-known-good rollback when invalidity is scoped to `plugins.entries.*`, preserving unrelated user settings during plugin schema or host-version skew. Fixes #71289. Thanks @jalehman.
- Agents/tools: keep resolved reply-run configs from being overwritten by stale runtime snapshots, and let empty web runtime metadata fall back to configured provider auto-detection so standard and queued turns expose the same tool set. Fixes #71355. Thanks @c-g14.
- Agents/TTS: pass the resolved shared config into the `tts` tool, so tool-triggered speech uses configured providers and voices instead of falling back to a fresh config load.
- Agents/TTS: preserve voice media when a tool-generated reply is paired with an exact `NO_REPLY` sentinel, stripping the sentinel text instead of dropping the audio payload. Fixes #66092.
- Compaction: honor explicit `agents.defaults.compaction.keepRecentTokens` for manual `/compact`, re-distill safeguard summaries instead of snowballing previous summaries, and enable safeguard summary quality checks by default. Fixes #71357. Thanks @WhiteGiverMa.
- Sessions: honor configured `session.maintenance` settings during load-time maintenance instead of falling back to default entry caps. Fixes #71356. Thanks @comolago.

View File

@@ -246,7 +246,7 @@ export function createOpenClawTools(
...(!embedded && messageTool ? [messageTool] : []),
createTtsTool({
agentChannel: options?.agentChannel,
config: options?.config,
config: resolvedConfig,
}),
...collectPresentOpenClawTools([imageGenerateTool, musicGenerateTool, videoGenerateTool]),
...(embedded

View File

@@ -0,0 +1,62 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/types.openclaw.js";
const mocks = vi.hoisted(() => ({
textToSpeech: vi.fn(async () => ({
success: true,
audioPath: "/tmp/openclaw/tts-config-test.opus",
provider: "microsoft",
voiceCompatible: true,
})),
}));
vi.mock("../tts/tts.js", () => ({
textToSpeech: mocks.textToSpeech,
}));
describe("createOpenClawTools TTS config wiring", () => {
beforeEach(() => {
mocks.textToSpeech.mockClear();
});
it("passes the resolved shared config into the tts tool", async () => {
const injectedConfig = {
messages: {
tts: {
auto: "always",
provider: "microsoft",
providers: {
microsoft: {
voice: "en-US-AvaNeural",
},
},
},
},
} satisfies OpenClawConfig;
const { __testing, createOpenClawTools } = await import("./openclaw-tools.js");
__testing.setDepsForTest({ config: injectedConfig });
try {
const tool = createOpenClawTools({
disableMessageTool: true,
disablePluginTools: true,
}).find((candidate) => candidate.name === "tts");
if (!tool) {
throw new Error("missing tts tool");
}
await tool.execute("call-1", { text: "hello from config" });
expect(mocks.textToSpeech).toHaveBeenCalledWith(
expect.objectContaining({
text: "hello from config",
cfg: injectedConfig,
}),
);
} finally {
__testing.setDepsForTest();
}
});
});