mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-27 00:52:05 +00:00
fix: preserve talk provider and speaking state
This commit is contained in:
@@ -748,7 +748,7 @@ class TalkModeManager(
|
||||
|
||||
private suspend fun playGatewaySpeech(speech: GatewayTalkSpeech, playbackToken: Long) {
|
||||
ensurePlaybackActive(playbackToken)
|
||||
stopSpeaking(resetInterrupt = false)
|
||||
cleanupPlayer()
|
||||
ensurePlaybackActive(playbackToken)
|
||||
|
||||
val audioBytes =
|
||||
|
||||
@@ -171,8 +171,6 @@ function buildTalkTtsConfig(
|
||||
...(proxy == null ? {} : { proxy }),
|
||||
...(timeoutMs == null ? {} : { timeoutMs }),
|
||||
};
|
||||
} else {
|
||||
return { error: `talk.speak unavailable: unsupported talk provider '${resolved.provider}'` };
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -6,6 +6,8 @@ import {
|
||||
publicKeyRawBase64UrlFromPem,
|
||||
signDevicePayload,
|
||||
} from "../infra/device-identity.js";
|
||||
import { createEmptyPluginRegistry } from "../plugins/registry-empty.js";
|
||||
import { getActivePluginRegistry, setActivePluginRegistry } from "../plugins/runtime.js";
|
||||
import { withEnvAsync } from "../test-utils/env.js";
|
||||
import { buildDeviceAuthPayload } from "./device-auth.js";
|
||||
import { validateTalkConfigResult } from "./protocol/index.js";
|
||||
@@ -348,4 +350,54 @@ describe("gateway talk.config", () => {
|
||||
globalThis.fetch = originalFetch;
|
||||
}
|
||||
});
|
||||
|
||||
it("allows extension speech providers through talk.speak", async () => {
|
||||
const { writeConfigFile } = await import("../config/config.js");
|
||||
await writeConfigFile({
|
||||
talk: {
|
||||
provider: "acme",
|
||||
providers: {
|
||||
acme: {
|
||||
voiceId: "plugin-voice",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const previousRegistry = getActivePluginRegistry() ?? createEmptyPluginRegistry();
|
||||
setActivePluginRegistry({
|
||||
...createEmptyPluginRegistry(),
|
||||
speechProviders: [
|
||||
{
|
||||
pluginId: "acme-plugin",
|
||||
source: "test",
|
||||
provider: {
|
||||
id: "acme",
|
||||
label: "Acme Speech",
|
||||
isConfigured: () => true,
|
||||
synthesize: async () => ({
|
||||
audioBuffer: Buffer.from([7, 8, 9]),
|
||||
outputFormat: "mp3",
|
||||
fileExtension: ".mp3",
|
||||
voiceCompatible: false,
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
try {
|
||||
await withServer(async (ws) => {
|
||||
await connectOperator(ws, ["operator.read", "operator.write"]);
|
||||
const res = await fetchTalkSpeak(ws, {
|
||||
text: "Hello from plugin talk mode.",
|
||||
});
|
||||
expect(res.ok).toBe(true);
|
||||
expect(res.payload?.provider).toBe("acme");
|
||||
expect(res.payload?.audioBase64).toBe(Buffer.from([7, 8, 9]).toString("base64"));
|
||||
});
|
||||
} finally {
|
||||
setActivePluginRegistry(previousRegistry);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user