@openclaw/fish-audio-speech 2026.9.6 → 2026.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/icon.png +0 -0
- package/dist/speech-provider.js +56 -37
- package/dist/tts.js +4 -6
- package/package.json +4 -4
package/assets/icon.png
CHANGED
|
Binary file
|
package/dist/speech-provider.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fishAudioTts, fishAudioTtsStream, listFishAudioVoices, normalizeFishAudioBaseUrl } from "./tts.js";
|
|
2
2
|
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
3
|
-
import { parseSpeechDirectiveNumberOverride, resolveSpeechProviderApiKey } from "openclaw/plugin-sdk/speech-provider";
|
|
4
|
-
import { asBoolean, asFiniteNumberInRange, asOptionalRecord, normalizeOptionalString, parseBooleanValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import { MAX_AUDIO_BYTES, parseSpeechDirectiveNumberOverride, resolveSpeechProviderApiKey } from "openclaw/plugin-sdk/speech-provider";
|
|
4
|
+
import { asBoolean, asFiniteNumberInRange, asOptionalRecord, filterStringRecord, normalizeOptionalString, parseBooleanValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
//#region extensions/fish-audio-speech/speech-provider.ts
|
|
6
6
|
const FISH_AUDIO_MODELS = [
|
|
7
7
|
"s2.1-pro-free",
|
|
@@ -24,12 +24,6 @@ function normalizeLatency(value) {
|
|
|
24
24
|
if (latency === "low" || latency === "balanced" || latency === "normal") return latency;
|
|
25
25
|
throw new Error(`invalid Fish Audio latency "${latency}"`);
|
|
26
26
|
}
|
|
27
|
-
function normalizeNumber(value, min, max) {
|
|
28
|
-
return asFiniteNumberInRange(value, {
|
|
29
|
-
min,
|
|
30
|
-
max
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
27
|
function resolveReferenceId(raw) {
|
|
34
28
|
return normalizeOptionalString(raw?.speakerVoiceId ?? raw?.voiceId ?? raw?.referenceId);
|
|
35
29
|
}
|
|
@@ -45,26 +39,26 @@ function normalizeProviderConfig(rawConfig) {
|
|
|
45
39
|
model: normalizeModel(raw?.model ?? raw?.modelId),
|
|
46
40
|
referenceId: resolveReferenceId(raw),
|
|
47
41
|
latency: normalizeLatency(raw?.latency),
|
|
48
|
-
speed:
|
|
49
|
-
|
|
50
|
-
|
|
42
|
+
speed: asFiniteNumberInRange(raw?.speed, {
|
|
43
|
+
min: .5,
|
|
44
|
+
max: 2
|
|
45
|
+
}),
|
|
46
|
+
temperature: asFiniteNumberInRange(raw?.temperature, {
|
|
47
|
+
min: 0,
|
|
48
|
+
max: 1
|
|
49
|
+
}),
|
|
50
|
+
topP: asFiniteNumberInRange(raw?.topP ?? raw?.top_p, {
|
|
51
|
+
min: 0,
|
|
52
|
+
max: 1
|
|
53
|
+
}),
|
|
51
54
|
normalize: asBoolean(raw?.normalize)
|
|
52
55
|
};
|
|
53
56
|
}
|
|
54
57
|
function readProviderConfig(config) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
baseUrl: normalizeFishAudioBaseUrl(normalizeOptionalString(raw.baseUrl) ?? defaults.baseUrl),
|
|
60
|
-
model: normalizeModel(raw.model ?? raw.modelId ?? defaults.model),
|
|
61
|
-
referenceId: resolveReferenceId(raw) ?? defaults.referenceId,
|
|
62
|
-
latency: normalizeLatency(raw.latency ?? defaults.latency),
|
|
63
|
-
speed: normalizeNumber(raw.speed, .5, 2) ?? defaults.speed,
|
|
64
|
-
temperature: normalizeNumber(raw.temperature, 0, 1) ?? defaults.temperature,
|
|
65
|
-
topP: normalizeNumber(raw.topP ?? raw.top_p, 0, 1) ?? defaults.topP,
|
|
66
|
-
normalize: asBoolean(raw.normalize) ?? defaults.normalize
|
|
67
|
-
};
|
|
58
|
+
return normalizeProviderConfig({ "fish-audio": {
|
|
59
|
+
...config,
|
|
60
|
+
apiKey: normalizeOptionalString(config.apiKey)
|
|
61
|
+
} });
|
|
68
62
|
}
|
|
69
63
|
function readOverrides(overrides) {
|
|
70
64
|
const raw = asOptionalRecord(overrides) ?? {};
|
|
@@ -72,9 +66,18 @@ function readOverrides(overrides) {
|
|
|
72
66
|
model: normalizeOptionalString(raw.model ?? raw.modelId) ? normalizeModel(raw.model ?? raw.modelId) : void 0,
|
|
73
67
|
referenceId: resolveReferenceId(raw),
|
|
74
68
|
latency: normalizeOptionalString(raw.latency) ? normalizeLatency(raw.latency) : void 0,
|
|
75
|
-
speed:
|
|
76
|
-
|
|
77
|
-
|
|
69
|
+
speed: asFiniteNumberInRange(raw.speed, {
|
|
70
|
+
min: .5,
|
|
71
|
+
max: 2
|
|
72
|
+
}),
|
|
73
|
+
temperature: asFiniteNumberInRange(raw.temperature, {
|
|
74
|
+
min: 0,
|
|
75
|
+
max: 1
|
|
76
|
+
}),
|
|
77
|
+
topP: asFiniteNumberInRange(raw.topP ?? raw.top_p, {
|
|
78
|
+
min: 0,
|
|
79
|
+
max: 1
|
|
80
|
+
}),
|
|
78
81
|
normalize: asBoolean(raw.normalize)
|
|
79
82
|
};
|
|
80
83
|
}
|
|
@@ -241,17 +244,33 @@ function buildFishAudioSpeechProvider() {
|
|
|
241
244
|
value: talkProviderConfig.apiKey,
|
|
242
245
|
path: "talk.providers.fish-audio.apiKey"
|
|
243
246
|
}) },
|
|
244
|
-
...
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
247
|
+
...filterStringRecord({
|
|
248
|
+
baseUrl: normalizeOptionalString(talkProviderConfig.baseUrl) ? normalizeFishAudioBaseUrl(normalizeOptionalString(talkProviderConfig.baseUrl)) : void 0,
|
|
249
|
+
model: normalizeOptionalString(talkProviderConfig.modelId ?? talkProviderConfig.model) ? normalizeModel(talkProviderConfig.modelId ?? talkProviderConfig.model) : void 0,
|
|
250
|
+
referenceId: resolveReferenceId(talkProviderConfig),
|
|
251
|
+
latency: normalizeOptionalString(talkProviderConfig.latency) ? normalizeLatency(talkProviderConfig.latency) : void 0
|
|
252
|
+
}),
|
|
253
|
+
...asFiniteNumberInRange(talkProviderConfig.speed, {
|
|
254
|
+
min: .5,
|
|
255
|
+
max: 2
|
|
256
|
+
}) == null ? {} : { speed: asFiniteNumberInRange(talkProviderConfig.speed, {
|
|
257
|
+
min: .5,
|
|
258
|
+
max: 2
|
|
259
|
+
}) }
|
|
249
260
|
};
|
|
250
261
|
},
|
|
251
262
|
resolveTalkOverrides: ({ params }) => ({
|
|
252
|
-
...
|
|
253
|
-
|
|
254
|
-
|
|
263
|
+
...filterStringRecord({
|
|
264
|
+
model: normalizeOptionalString(params.modelId ?? params.model) ? normalizeModel(params.modelId ?? params.model) : void 0,
|
|
265
|
+
referenceId: resolveReferenceId(params)
|
|
266
|
+
}),
|
|
267
|
+
...asFiniteNumberInRange(params.speed, {
|
|
268
|
+
min: .5,
|
|
269
|
+
max: 2
|
|
270
|
+
}) == null ? {} : { speed: asFiniteNumberInRange(params.speed, {
|
|
271
|
+
min: .5,
|
|
272
|
+
max: 2
|
|
273
|
+
}) }
|
|
255
274
|
}),
|
|
256
275
|
listVoices: async (req) => {
|
|
257
276
|
const config = readProviderConfig(req.providerConfig ?? {});
|
|
@@ -282,7 +301,7 @@ function buildFishAudioSpeechProvider() {
|
|
|
282
301
|
const { resolveGeneratedMediaMaxBytes } = await import("openclaw/plugin-sdk/media-generation-runtime");
|
|
283
302
|
const stream = await fishAudioTtsStream({
|
|
284
303
|
...params,
|
|
285
|
-
maxBytes: Math.min(resolveGeneratedMediaMaxBytes(req.cfg, "audio"),
|
|
304
|
+
maxBytes: Math.min(resolveGeneratedMediaMaxBytes(req.cfg, "audio"), MAX_AUDIO_BYTES)
|
|
286
305
|
});
|
|
287
306
|
return {
|
|
288
307
|
audioStream: stream.audioStream,
|
package/dist/tts.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
1
|
+
import { asOptionalRecord, normalizeOptionalString, normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
2
|
//#region extensions/fish-audio-speech/tts.ts
|
|
4
3
|
const FISH_AUDIO_BASE_URL = "https://api.fish.audio";
|
|
5
4
|
const FISH_AUDIO_VOICES_MAX_BYTES = 2097152;
|
|
@@ -79,8 +78,8 @@ function parseVoiceItem(value) {
|
|
|
79
78
|
const item = asOptionalRecord(value);
|
|
80
79
|
const id = normalizeOptionalString(item?.["_id"]);
|
|
81
80
|
if (!id) return;
|
|
82
|
-
const languages =
|
|
83
|
-
const tags =
|
|
81
|
+
const languages = normalizeTrimmedStringList(item?.languages);
|
|
82
|
+
const tags = normalizeTrimmedStringList(item?.tags);
|
|
84
83
|
return {
|
|
85
84
|
id,
|
|
86
85
|
name: normalizeOptionalString(item?.title),
|
|
@@ -141,6 +140,5 @@ async function listFishAudioVoices(params) {
|
|
|
141
140
|
return true;
|
|
142
141
|
});
|
|
143
142
|
}
|
|
144
|
-
const FISH_AUDIO_STREAM_MAX_BYTES = MAX_AUDIO_BYTES;
|
|
145
143
|
//#endregion
|
|
146
|
-
export {
|
|
144
|
+
export { fishAudioTts, fishAudioTtsStream, listFishAudioVoices, normalizeFishAudioBaseUrl };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/fish-audio-speech",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.7",
|
|
4
4
|
"description": "OpenClaw Fish Audio speech plugin.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
"minHostVersion": ">=2026.7.2"
|
|
19
19
|
},
|
|
20
20
|
"compat": {
|
|
21
|
-
"pluginApi": ">=2026.9.
|
|
21
|
+
"pluginApi": ">=2026.9.7"
|
|
22
22
|
},
|
|
23
23
|
"build": {
|
|
24
|
-
"openclawVersion": "2026.9.
|
|
24
|
+
"openclawVersion": "2026.9.7",
|
|
25
25
|
"bundledDist": false
|
|
26
26
|
},
|
|
27
27
|
"release": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"assets/activity.svg"
|
|
41
41
|
],
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"openclaw": ">=2026.9.
|
|
43
|
+
"openclaw": ">=2026.9.7"
|
|
44
44
|
},
|
|
45
45
|
"peerDependenciesMeta": {
|
|
46
46
|
"openclaw": {
|