dsh-line-bot 0.10.3 → 0.10.4
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/CHANGELOG.md +5 -0
- package/lib/host.mjs +1 -1
- package/lib/tts.mjs +39 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/lib/host.mjs
CHANGED
|
@@ -51,7 +51,7 @@ const { createVision } = visionMod
|
|
|
51
51
|
const { createTts } = ttsMod
|
|
52
52
|
const { chunkText, clip, inQuietWindow, jsonFail, jsonOk, maskSecret, readJsonBody, safeArray, sleep, readJsonSafe } = utilMod
|
|
53
53
|
|
|
54
|
-
export const VERSION = '0.10.
|
|
54
|
+
export const VERSION = '0.10.4'
|
|
55
55
|
|
|
56
56
|
// 環境變數提供的 Cloudflare API Token(方便用 shell 注入、不用把 token 寫進設定檔)。
|
|
57
57
|
// 設定檔裡的 token 優先;兩者都沒有時才用環境變數。
|
package/lib/tts.mjs
CHANGED
|
@@ -212,6 +212,18 @@ export function createTts({ dir, logger, getConfig }) {
|
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
function hasWindowsRuntime(exe) {
|
|
216
|
+
if (!isWin()) return true
|
|
217
|
+
try {
|
|
218
|
+
const names = fs.readdirSync(path.dirname(exe)).map((item) => String(item).toLowerCase())
|
|
219
|
+
// Windows CPU 版 CrispASR 需要同資料夾的 openblas.dll。舊安裝可能留下
|
|
220
|
+
// 只有 exe 的裸副本,不能只憑「檔案存在」就選它。
|
|
221
|
+
return names.includes('openblas.dll')
|
|
222
|
+
} catch {
|
|
223
|
+
return false
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
215
227
|
function findCrispExe(dir, depth = 3) {
|
|
216
228
|
if (depth < 0) return ''
|
|
217
229
|
let entries = []
|
|
@@ -220,19 +232,38 @@ export function createTts({ dir, logger, getConfig }) {
|
|
|
220
232
|
} catch {
|
|
221
233
|
return ''
|
|
222
234
|
}
|
|
235
|
+
const candidates = []
|
|
223
236
|
for (const entry of entries) {
|
|
224
|
-
if (entry.isFile() && /^crispasr\.exe$/i.test(entry.name))
|
|
237
|
+
if (entry.isFile() && /^crispasr\.exe$/i.test(entry.name)) candidates.push(path.join(dir, entry.name))
|
|
225
238
|
}
|
|
226
239
|
for (const entry of entries) {
|
|
227
240
|
if (!entry.isDirectory()) continue
|
|
228
241
|
const hit = findCrispExe(path.join(dir, entry.name), depth - 1)
|
|
229
|
-
if (hit)
|
|
242
|
+
if (hit) candidates.push(hit)
|
|
243
|
+
}
|
|
244
|
+
// 優先完整 bundle;舊的裸 exe 即使存在也不選。
|
|
245
|
+
return candidates.find((item) => hasWindowsRuntime(item)) || candidates[0] || ''
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function crispVersion(exe) {
|
|
249
|
+
try {
|
|
250
|
+
const output = execFileSync(exe, ['--version'], {
|
|
251
|
+
encoding: 'utf8',
|
|
252
|
+
timeout: 15000,
|
|
253
|
+
cwd: path.dirname(exe),
|
|
254
|
+
})
|
|
255
|
+
return { ok: true, output: String(output || '') }
|
|
256
|
+
} catch (error) {
|
|
257
|
+
return {
|
|
258
|
+
ok: false,
|
|
259
|
+
error: String(error?.stderr || error?.message || error).slice(0, 500),
|
|
260
|
+
}
|
|
230
261
|
}
|
|
231
|
-
return ''
|
|
232
262
|
}
|
|
233
263
|
|
|
234
264
|
function ggufBinary() {
|
|
235
|
-
|
|
265
|
+
// 忽略舊 Windows 安裝留下的裸 exe:它存在但載不到同 bundle 的 DLL。
|
|
266
|
+
if (state.ggufBinary && fileExists(state.ggufBinary) && hasWindowsRuntime(state.ggufBinary)) return state.ggufBinary
|
|
236
267
|
if (isWin()) {
|
|
237
268
|
const found = findCrispExe(paths.winDir)
|
|
238
269
|
if (found) return found
|
|
@@ -245,12 +276,7 @@ export function createTts({ dir, logger, getConfig }) {
|
|
|
245
276
|
const bin = ggufBinary()
|
|
246
277
|
if (!bin) return false
|
|
247
278
|
if (!validate) return true
|
|
248
|
-
|
|
249
|
-
execFileSync(bin, ['--version'], { stdio: 'ignore', timeout: 8000 })
|
|
250
|
-
return true
|
|
251
|
-
} catch {
|
|
252
|
-
return false
|
|
253
|
-
}
|
|
279
|
+
return crispVersion(bin).ok
|
|
254
280
|
}
|
|
255
281
|
|
|
256
282
|
function detect({ force = false, validate = false } = {}) {
|
|
@@ -418,11 +444,9 @@ export function createTts({ dir, logger, getConfig }) {
|
|
|
418
444
|
await run('powershell', ['-NoProfile', '-Command', `Expand-Archive -LiteralPath ${JSON.stringify(zip)} -DestinationPath ${JSON.stringify(paths.winDir)} -Force`], { timeout: 300000 })
|
|
419
445
|
const exe = findCrispExe(paths.winDir)
|
|
420
446
|
if (!exe) throw new Error('解壓縮後找不到 crispasr.exe')
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const detail = String(error?.stderr || error?.message || error).slice(0, 300)
|
|
425
|
-
throw new Error(`crispasr.exe 無法執行(可能是缺少 DLL):${detail}`)
|
|
447
|
+
const version = crispVersion(exe)
|
|
448
|
+
if (!version.ok) {
|
|
449
|
+
throw new Error(`crispasr.exe 無法執行(可能是缺少 DLL):${version.error}`)
|
|
426
450
|
}
|
|
427
451
|
state.ggufBinary = exe
|
|
428
452
|
return 'gguf'
|