@openclaw/fish-audio-speech 2026.8.1-beta.2 → 2026.8.1
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/dist/tts.js +9 -73
- package/package.json +4 -4
package/dist/tts.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
2
|
import { MAX_AUDIO_BYTES } from "openclaw/plugin-sdk/media-runtime";
|
|
3
|
+
import { createBoundedProviderBinaryStream } from "openclaw/plugin-sdk/provider-binary-stream";
|
|
3
4
|
import { assertOkOrThrowProviderError, assertProviderBinaryResponseContent, readProviderBinaryResponse, readProviderJsonResponse } from "openclaw/plugin-sdk/provider-http";
|
|
4
5
|
import { trimToUndefined } from "openclaw/plugin-sdk/speech";
|
|
5
6
|
import { fetchWithSsrFGuard, ssrfPolicyFromHttpBaseUrlAllowedHostname } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
@@ -52,65 +53,6 @@ async function fishAudioTts(params) {
|
|
|
52
53
|
await release();
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
|
-
function createBoundedFishAudioStream(stream, maxBytes) {
|
|
56
|
-
let reader;
|
|
57
|
-
let totalBytes = 0;
|
|
58
|
-
const releaseReader = (activeReader) => {
|
|
59
|
-
if (reader === activeReader) {
|
|
60
|
-
reader = void 0;
|
|
61
|
-
activeReader.releaseLock();
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
const cancelReader = async (reason) => {
|
|
65
|
-
const activeReader = reader;
|
|
66
|
-
if (!activeReader) return;
|
|
67
|
-
try {
|
|
68
|
-
await activeReader.cancel(reason).catch(() => void 0);
|
|
69
|
-
} finally {
|
|
70
|
-
releaseReader(activeReader);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
return {
|
|
74
|
-
audioStream: new ReadableStream({
|
|
75
|
-
start() {
|
|
76
|
-
reader = stream.getReader();
|
|
77
|
-
},
|
|
78
|
-
async pull(controller) {
|
|
79
|
-
const activeReader = reader;
|
|
80
|
-
if (!activeReader) {
|
|
81
|
-
controller.close();
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
try {
|
|
85
|
-
const chunk = await activeReader.read();
|
|
86
|
-
if (chunk.done) {
|
|
87
|
-
releaseReader(activeReader);
|
|
88
|
-
controller.close();
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
const remaining = maxBytes - totalBytes;
|
|
92
|
-
if (chunk.value.byteLength > remaining) {
|
|
93
|
-
if (remaining > 0) controller.enqueue(chunk.value.subarray(0, remaining));
|
|
94
|
-
const error = /* @__PURE__ */ new Error(`Fish Audio TTS API error: audio response exceeds ${maxBytes} bytes`);
|
|
95
|
-
await activeReader.cancel(error).catch(() => void 0);
|
|
96
|
-
releaseReader(activeReader);
|
|
97
|
-
controller.error(error);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
totalBytes += chunk.value.byteLength;
|
|
101
|
-
controller.enqueue(chunk.value);
|
|
102
|
-
} catch (error) {
|
|
103
|
-
releaseReader(activeReader);
|
|
104
|
-
controller.error(error);
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
async cancel(reason) {
|
|
108
|
-
await cancelReader(reason);
|
|
109
|
-
}
|
|
110
|
-
}),
|
|
111
|
-
release: () => cancelReader(/* @__PURE__ */ new Error("Fish Audio TTS stream released"))
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
56
|
async function fishAudioTtsStream(params) {
|
|
115
57
|
const { response, release } = await requestFishAudioTts(params);
|
|
116
58
|
let handedOff = false;
|
|
@@ -118,22 +60,16 @@ async function fishAudioTtsStream(params) {
|
|
|
118
60
|
await assertOkOrThrowProviderError(response, "Fish Audio TTS API error");
|
|
119
61
|
assertProviderBinaryResponseContent(response, "Fish Audio TTS API error", "audio");
|
|
120
62
|
if (!response.body) throw new Error("Fish Audio TTS API response missing audio stream");
|
|
121
|
-
const bounded =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
} finally {
|
|
128
|
-
await release();
|
|
129
|
-
}
|
|
130
|
-
})();
|
|
131
|
-
return releasePromise;
|
|
132
|
-
};
|
|
63
|
+
const bounded = createBoundedProviderBinaryStream(response.body, {
|
|
64
|
+
maxBytes: params.maxBytes,
|
|
65
|
+
createOverflowError: ({ maxBytes }) => /* @__PURE__ */ new Error(`Fish Audio TTS API error: audio response exceeds ${maxBytes} bytes`),
|
|
66
|
+
createReleaseError: () => /* @__PURE__ */ new Error("Fish Audio TTS stream released"),
|
|
67
|
+
cleanup: release
|
|
68
|
+
});
|
|
133
69
|
handedOff = true;
|
|
134
70
|
return {
|
|
135
|
-
audioStream: bounded.
|
|
136
|
-
release:
|
|
71
|
+
audioStream: bounded.stream,
|
|
72
|
+
release: bounded.release
|
|
137
73
|
};
|
|
138
74
|
} finally {
|
|
139
75
|
if (!handedOff) await release();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/fish-audio-speech",
|
|
3
|
-
"version": "2026.8.1
|
|
3
|
+
"version": "2026.8.1",
|
|
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.8.1
|
|
21
|
+
"pluginApi": ">=2026.8.1"
|
|
22
22
|
},
|
|
23
23
|
"build": {
|
|
24
|
-
"openclawVersion": "2026.8.1
|
|
24
|
+
"openclawVersion": "2026.8.1",
|
|
25
25
|
"bundledDist": false
|
|
26
26
|
},
|
|
27
27
|
"release": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"README.md"
|
|
39
39
|
],
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"openclaw": ">=2026.8.1
|
|
41
|
+
"openclaw": ">=2026.8.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependenciesMeta": {
|
|
44
44
|
"openclaw": {
|