@mingxy/ocosay 1.0.34 → 1.1.0
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/config.d.ts.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/core/backends/index.d.ts.map +1 -1
- package/dist/core/backends/index.js +8 -3
- package/dist/core/backends/index.js.map +1 -1
- package/dist/core/backends/powershell-backend.d.ts.map +1 -1
- package/dist/core/backends/powershell-backend.js +6 -1
- package/dist/core/backends/powershell-backend.js.map +1 -1
- package/dist/core/speaker.d.ts.map +1 -1
- package/dist/core/speaker.js +1 -0
- package/dist/core/speaker.js.map +1 -1
- package/dist/core/streaming-synthesizer.d.ts.map +1 -1
- package/dist/core/streaming-synthesizer.js +2 -0
- package/dist/core/streaming-synthesizer.js.map +1 -1
- package/dist/index.d.ts +0 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -23
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +962 -577
- package/dist/plugin.js.map +4 -4
- package/dist/providers/minimax.d.ts.map +1 -1
- package/dist/providers/minimax.js +43 -20
- package/dist/providers/minimax.js.map +1 -1
- package/dist/services/notification-service.d.ts +17 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +74 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/speaker-service.d.ts +34 -0
- package/dist/services/speaker-service.d.ts.map +1 -0
- package/dist/services/speaker-service.js +74 -0
- package/dist/services/speaker-service.js.map +1 -0
- package/dist/services/streaming-service.d.ts +109 -0
- package/dist/services/streaming-service.d.ts.map +1 -0
- package/dist/services/streaming-service.js +281 -0
- package/dist/services/streaming-service.js.map +1 -0
- package/dist/tools/tts.d.ts.map +1 -1
- package/dist/tools/tts.js +32 -19
- package/dist/tools/tts.js.map +1 -1
- package/package.json +2 -2
- package/tsconfig.jest.json +21 -0
- package/dist/core/logger.d.ts +0 -46
- package/dist/core/logger.d.ts.map +0 -1
- package/dist/core/logger.js +0 -126
- package/dist/core/logger.js.map +0 -1
package/dist/plugin.js
CHANGED
|
@@ -593,17 +593,17 @@ var require_howler = __commonJS({
|
|
|
593
593
|
var duration = Math.max(0, (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1e3 - seek);
|
|
594
594
|
var timeout = duration * 1e3 / Math.abs(sound._rate);
|
|
595
595
|
var start = self._sprite[sprite][0] / 1e3;
|
|
596
|
-
var
|
|
596
|
+
var stop3 = (self._sprite[sprite][0] + self._sprite[sprite][1]) / 1e3;
|
|
597
597
|
sound._sprite = sprite;
|
|
598
598
|
sound._ended = false;
|
|
599
599
|
var setParams = function() {
|
|
600
600
|
sound._paused = false;
|
|
601
601
|
sound._seek = seek;
|
|
602
602
|
sound._start = start;
|
|
603
|
-
sound._stop =
|
|
603
|
+
sound._stop = stop3;
|
|
604
604
|
sound._loop = !!(sound._loop || self._sprite[sprite][2]);
|
|
605
605
|
};
|
|
606
|
-
if (seek >=
|
|
606
|
+
if (seek >= stop3) {
|
|
607
607
|
self._ended(sound);
|
|
608
608
|
return;
|
|
609
609
|
}
|
|
@@ -3418,7 +3418,7 @@ var require_sonic_boom = __commonJS({
|
|
|
3418
3418
|
"node_modules/sonic-boom/index.js"(exports, module) {
|
|
3419
3419
|
"use strict";
|
|
3420
3420
|
var fs3 = __require("fs");
|
|
3421
|
-
var
|
|
3421
|
+
var EventEmitter7 = __require("events");
|
|
3422
3422
|
var inherits = __require("util").inherits;
|
|
3423
3423
|
var path2 = __require("path");
|
|
3424
3424
|
var sleep = require_atomic_sleep();
|
|
@@ -3655,7 +3655,7 @@ var require_sonic_boom = __commonJS({
|
|
|
3655
3655
|
sonic._asyncDrainScheduled = false;
|
|
3656
3656
|
sonic.emit("drain");
|
|
3657
3657
|
}
|
|
3658
|
-
inherits(SonicBoom,
|
|
3658
|
+
inherits(SonicBoom, EventEmitter7);
|
|
3659
3659
|
function mergeBuf(bufs, len) {
|
|
3660
3660
|
if (bufs.length === 0) {
|
|
3661
3661
|
return kEmptyBuffer;
|
|
@@ -4223,7 +4223,7 @@ var require_thread_stream = __commonJS({
|
|
|
4223
4223
|
"node_modules/thread-stream/index.js"(exports, module) {
|
|
4224
4224
|
"use strict";
|
|
4225
4225
|
var { version } = require_package();
|
|
4226
|
-
var { EventEmitter:
|
|
4226
|
+
var { EventEmitter: EventEmitter7 } = __require("events");
|
|
4227
4227
|
var { Worker } = __require("worker_threads");
|
|
4228
4228
|
var { join: join8 } = __require("path");
|
|
4229
4229
|
var { pathToFileURL } = __require("url");
|
|
@@ -4258,7 +4258,7 @@ var require_thread_stream = __commonJS({
|
|
|
4258
4258
|
}
|
|
4259
4259
|
worker.terminate();
|
|
4260
4260
|
});
|
|
4261
|
-
function createWorker(
|
|
4261
|
+
function createWorker(stream2, opts) {
|
|
4262
4262
|
const { filename, workerData } = opts;
|
|
4263
4263
|
const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
|
|
4264
4264
|
const toExecute = bundlerOverrides["thread-stream-worker"] || join8(__dirname, "lib", "worker.js");
|
|
@@ -4267,8 +4267,8 @@ var require_thread_stream = __commonJS({
|
|
|
4267
4267
|
trackUnmanagedFds: false,
|
|
4268
4268
|
workerData: {
|
|
4269
4269
|
filename: filename.indexOf("file://") === 0 ? filename : pathToFileURL(filename).href,
|
|
4270
|
-
dataBuf:
|
|
4271
|
-
stateBuf:
|
|
4270
|
+
dataBuf: stream2[kImpl].dataBuf,
|
|
4271
|
+
stateBuf: stream2[kImpl].stateBuf,
|
|
4272
4272
|
workerData: {
|
|
4273
4273
|
$context: {
|
|
4274
4274
|
threadStreamVersion: version
|
|
@@ -4277,111 +4277,111 @@ var require_thread_stream = __commonJS({
|
|
|
4277
4277
|
}
|
|
4278
4278
|
}
|
|
4279
4279
|
});
|
|
4280
|
-
worker.stream = new FakeWeakRef(
|
|
4280
|
+
worker.stream = new FakeWeakRef(stream2);
|
|
4281
4281
|
worker.on("message", onWorkerMessage);
|
|
4282
4282
|
worker.on("exit", onWorkerExit);
|
|
4283
|
-
registry.register(
|
|
4283
|
+
registry.register(stream2, worker);
|
|
4284
4284
|
return worker;
|
|
4285
4285
|
}
|
|
4286
|
-
function drain(
|
|
4287
|
-
assert(!
|
|
4288
|
-
if (
|
|
4289
|
-
|
|
4290
|
-
|
|
4286
|
+
function drain(stream2) {
|
|
4287
|
+
assert(!stream2[kImpl].sync);
|
|
4288
|
+
if (stream2[kImpl].needDrain) {
|
|
4289
|
+
stream2[kImpl].needDrain = false;
|
|
4290
|
+
stream2.emit("drain");
|
|
4291
4291
|
}
|
|
4292
4292
|
}
|
|
4293
|
-
function nextFlush(
|
|
4294
|
-
const writeIndex = Atomics.load(
|
|
4295
|
-
let leftover =
|
|
4293
|
+
function nextFlush(stream2) {
|
|
4294
|
+
const writeIndex = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
|
|
4295
|
+
let leftover = stream2[kImpl].data.length - writeIndex;
|
|
4296
4296
|
if (leftover > 0) {
|
|
4297
|
-
if (
|
|
4298
|
-
|
|
4299
|
-
if (
|
|
4300
|
-
end(
|
|
4301
|
-
} else if (
|
|
4302
|
-
process.nextTick(drain,
|
|
4297
|
+
if (stream2[kImpl].buf.length === 0) {
|
|
4298
|
+
stream2[kImpl].flushing = false;
|
|
4299
|
+
if (stream2[kImpl].ending) {
|
|
4300
|
+
end(stream2);
|
|
4301
|
+
} else if (stream2[kImpl].needDrain) {
|
|
4302
|
+
process.nextTick(drain, stream2);
|
|
4303
4303
|
}
|
|
4304
4304
|
return;
|
|
4305
4305
|
}
|
|
4306
|
-
let toWrite =
|
|
4306
|
+
let toWrite = stream2[kImpl].buf.slice(0, leftover);
|
|
4307
4307
|
let toWriteBytes = Buffer.byteLength(toWrite);
|
|
4308
4308
|
if (toWriteBytes <= leftover) {
|
|
4309
|
-
|
|
4310
|
-
write(
|
|
4309
|
+
stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
|
|
4310
|
+
write(stream2, toWrite, nextFlush.bind(null, stream2));
|
|
4311
4311
|
} else {
|
|
4312
|
-
|
|
4313
|
-
if (
|
|
4312
|
+
stream2.flush(() => {
|
|
4313
|
+
if (stream2.destroyed) {
|
|
4314
4314
|
return;
|
|
4315
4315
|
}
|
|
4316
|
-
Atomics.store(
|
|
4317
|
-
Atomics.store(
|
|
4318
|
-
Atomics.notify(
|
|
4319
|
-
while (toWriteBytes >
|
|
4316
|
+
Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
|
|
4317
|
+
Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
|
|
4318
|
+
Atomics.notify(stream2[kImpl].state, READ_INDEX);
|
|
4319
|
+
while (toWriteBytes > stream2[kImpl].data.length) {
|
|
4320
4320
|
leftover = leftover / 2;
|
|
4321
|
-
toWrite =
|
|
4321
|
+
toWrite = stream2[kImpl].buf.slice(0, leftover);
|
|
4322
4322
|
toWriteBytes = Buffer.byteLength(toWrite);
|
|
4323
4323
|
}
|
|
4324
|
-
|
|
4325
|
-
write(
|
|
4324
|
+
stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
|
|
4325
|
+
write(stream2, toWrite, nextFlush.bind(null, stream2));
|
|
4326
4326
|
});
|
|
4327
4327
|
}
|
|
4328
4328
|
} else if (leftover === 0) {
|
|
4329
|
-
if (writeIndex === 0 &&
|
|
4329
|
+
if (writeIndex === 0 && stream2[kImpl].buf.length === 0) {
|
|
4330
4330
|
return;
|
|
4331
4331
|
}
|
|
4332
|
-
|
|
4333
|
-
Atomics.store(
|
|
4334
|
-
Atomics.store(
|
|
4335
|
-
Atomics.notify(
|
|
4336
|
-
nextFlush(
|
|
4332
|
+
stream2.flush(() => {
|
|
4333
|
+
Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
|
|
4334
|
+
Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
|
|
4335
|
+
Atomics.notify(stream2[kImpl].state, READ_INDEX);
|
|
4336
|
+
nextFlush(stream2);
|
|
4337
4337
|
});
|
|
4338
4338
|
} else {
|
|
4339
|
-
destroy(
|
|
4339
|
+
destroy(stream2, new Error("overwritten"));
|
|
4340
4340
|
}
|
|
4341
4341
|
}
|
|
4342
4342
|
function onWorkerMessage(msg) {
|
|
4343
|
-
const
|
|
4344
|
-
if (
|
|
4343
|
+
const stream2 = this.stream.deref();
|
|
4344
|
+
if (stream2 === void 0) {
|
|
4345
4345
|
this.exited = true;
|
|
4346
4346
|
this.terminate();
|
|
4347
4347
|
return;
|
|
4348
4348
|
}
|
|
4349
4349
|
switch (msg.code) {
|
|
4350
4350
|
case "READY":
|
|
4351
|
-
this.stream = new WeakRef2(
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4351
|
+
this.stream = new WeakRef2(stream2);
|
|
4352
|
+
stream2.flush(() => {
|
|
4353
|
+
stream2[kImpl].ready = true;
|
|
4354
|
+
stream2.emit("ready");
|
|
4355
4355
|
});
|
|
4356
4356
|
break;
|
|
4357
4357
|
case "ERROR":
|
|
4358
|
-
destroy(
|
|
4358
|
+
destroy(stream2, msg.err);
|
|
4359
4359
|
break;
|
|
4360
4360
|
case "EVENT":
|
|
4361
4361
|
if (Array.isArray(msg.args)) {
|
|
4362
|
-
|
|
4362
|
+
stream2.emit(msg.name, ...msg.args);
|
|
4363
4363
|
} else {
|
|
4364
|
-
|
|
4364
|
+
stream2.emit(msg.name, msg.args);
|
|
4365
4365
|
}
|
|
4366
4366
|
break;
|
|
4367
4367
|
case "WARNING":
|
|
4368
4368
|
process.emitWarning(msg.err);
|
|
4369
4369
|
break;
|
|
4370
4370
|
default:
|
|
4371
|
-
destroy(
|
|
4371
|
+
destroy(stream2, new Error("this should not happen: " + msg.code));
|
|
4372
4372
|
}
|
|
4373
4373
|
}
|
|
4374
4374
|
function onWorkerExit(code) {
|
|
4375
|
-
const
|
|
4376
|
-
if (
|
|
4375
|
+
const stream2 = this.stream.deref();
|
|
4376
|
+
if (stream2 === void 0) {
|
|
4377
4377
|
return;
|
|
4378
4378
|
}
|
|
4379
|
-
registry.unregister(
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
destroy(
|
|
4379
|
+
registry.unregister(stream2);
|
|
4380
|
+
stream2.worker.exited = true;
|
|
4381
|
+
stream2.worker.off("exit", onWorkerExit);
|
|
4382
|
+
destroy(stream2, code !== 0 ? new Error("the worker thread exited") : null);
|
|
4383
4383
|
}
|
|
4384
|
-
var ThreadStream = class extends
|
|
4384
|
+
var ThreadStream = class extends EventEmitter7 {
|
|
4385
4385
|
constructor(opts = {}) {
|
|
4386
4386
|
super();
|
|
4387
4387
|
if (opts.bufferSize < 4) {
|
|
@@ -4512,127 +4512,127 @@ var require_thread_stream = __commonJS({
|
|
|
4512
4512
|
return this[kImpl].errored;
|
|
4513
4513
|
}
|
|
4514
4514
|
};
|
|
4515
|
-
function error(
|
|
4515
|
+
function error(stream2, err) {
|
|
4516
4516
|
setImmediate(() => {
|
|
4517
|
-
|
|
4517
|
+
stream2.emit("error", err);
|
|
4518
4518
|
});
|
|
4519
4519
|
}
|
|
4520
|
-
function destroy(
|
|
4521
|
-
if (
|
|
4520
|
+
function destroy(stream2, err) {
|
|
4521
|
+
if (stream2[kImpl].destroyed) {
|
|
4522
4522
|
return;
|
|
4523
4523
|
}
|
|
4524
|
-
|
|
4524
|
+
stream2[kImpl].destroyed = true;
|
|
4525
4525
|
if (err) {
|
|
4526
|
-
|
|
4527
|
-
error(
|
|
4526
|
+
stream2[kImpl].errored = err;
|
|
4527
|
+
error(stream2, err);
|
|
4528
4528
|
}
|
|
4529
|
-
if (!
|
|
4530
|
-
|
|
4529
|
+
if (!stream2.worker.exited) {
|
|
4530
|
+
stream2.worker.terminate().catch(() => {
|
|
4531
4531
|
}).then(() => {
|
|
4532
|
-
|
|
4533
|
-
|
|
4532
|
+
stream2[kImpl].closed = true;
|
|
4533
|
+
stream2.emit("close");
|
|
4534
4534
|
});
|
|
4535
4535
|
} else {
|
|
4536
4536
|
setImmediate(() => {
|
|
4537
|
-
|
|
4538
|
-
|
|
4537
|
+
stream2[kImpl].closed = true;
|
|
4538
|
+
stream2.emit("close");
|
|
4539
4539
|
});
|
|
4540
4540
|
}
|
|
4541
4541
|
}
|
|
4542
|
-
function write(
|
|
4543
|
-
const current = Atomics.load(
|
|
4542
|
+
function write(stream2, data, cb) {
|
|
4543
|
+
const current = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
|
|
4544
4544
|
const length = Buffer.byteLength(data);
|
|
4545
|
-
|
|
4546
|
-
Atomics.store(
|
|
4547
|
-
Atomics.notify(
|
|
4545
|
+
stream2[kImpl].data.write(data, current);
|
|
4546
|
+
Atomics.store(stream2[kImpl].state, WRITE_INDEX, current + length);
|
|
4547
|
+
Atomics.notify(stream2[kImpl].state, WRITE_INDEX);
|
|
4548
4548
|
cb();
|
|
4549
4549
|
return true;
|
|
4550
4550
|
}
|
|
4551
|
-
function end(
|
|
4552
|
-
if (
|
|
4551
|
+
function end(stream2) {
|
|
4552
|
+
if (stream2[kImpl].ended || !stream2[kImpl].ending || stream2[kImpl].flushing) {
|
|
4553
4553
|
return;
|
|
4554
4554
|
}
|
|
4555
|
-
|
|
4555
|
+
stream2[kImpl].ended = true;
|
|
4556
4556
|
try {
|
|
4557
|
-
|
|
4558
|
-
let readIndex = Atomics.load(
|
|
4559
|
-
Atomics.store(
|
|
4560
|
-
Atomics.notify(
|
|
4557
|
+
stream2.flushSync();
|
|
4558
|
+
let readIndex = Atomics.load(stream2[kImpl].state, READ_INDEX);
|
|
4559
|
+
Atomics.store(stream2[kImpl].state, WRITE_INDEX, -1);
|
|
4560
|
+
Atomics.notify(stream2[kImpl].state, WRITE_INDEX);
|
|
4561
4561
|
let spins = 0;
|
|
4562
4562
|
while (readIndex !== -1) {
|
|
4563
|
-
Atomics.wait(
|
|
4564
|
-
readIndex = Atomics.load(
|
|
4563
|
+
Atomics.wait(stream2[kImpl].state, READ_INDEX, readIndex, 1e3);
|
|
4564
|
+
readIndex = Atomics.load(stream2[kImpl].state, READ_INDEX);
|
|
4565
4565
|
if (readIndex === -2) {
|
|
4566
|
-
destroy(
|
|
4566
|
+
destroy(stream2, new Error("end() failed"));
|
|
4567
4567
|
return;
|
|
4568
4568
|
}
|
|
4569
4569
|
if (++spins === 10) {
|
|
4570
|
-
destroy(
|
|
4570
|
+
destroy(stream2, new Error("end() took too long (10s)"));
|
|
4571
4571
|
return;
|
|
4572
4572
|
}
|
|
4573
4573
|
}
|
|
4574
4574
|
process.nextTick(() => {
|
|
4575
|
-
|
|
4576
|
-
|
|
4575
|
+
stream2[kImpl].finished = true;
|
|
4576
|
+
stream2.emit("finish");
|
|
4577
4577
|
});
|
|
4578
4578
|
} catch (err) {
|
|
4579
|
-
destroy(
|
|
4579
|
+
destroy(stream2, err);
|
|
4580
4580
|
}
|
|
4581
4581
|
}
|
|
4582
|
-
function writeSync(
|
|
4582
|
+
function writeSync(stream2) {
|
|
4583
4583
|
const cb = () => {
|
|
4584
|
-
if (
|
|
4585
|
-
end(
|
|
4586
|
-
} else if (
|
|
4587
|
-
process.nextTick(drain,
|
|
4584
|
+
if (stream2[kImpl].ending) {
|
|
4585
|
+
end(stream2);
|
|
4586
|
+
} else if (stream2[kImpl].needDrain) {
|
|
4587
|
+
process.nextTick(drain, stream2);
|
|
4588
4588
|
}
|
|
4589
4589
|
};
|
|
4590
|
-
|
|
4591
|
-
while (
|
|
4592
|
-
const writeIndex = Atomics.load(
|
|
4593
|
-
let leftover =
|
|
4590
|
+
stream2[kImpl].flushing = false;
|
|
4591
|
+
while (stream2[kImpl].buf.length !== 0) {
|
|
4592
|
+
const writeIndex = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
|
|
4593
|
+
let leftover = stream2[kImpl].data.length - writeIndex;
|
|
4594
4594
|
if (leftover === 0) {
|
|
4595
|
-
flushSync(
|
|
4596
|
-
Atomics.store(
|
|
4597
|
-
Atomics.store(
|
|
4598
|
-
Atomics.notify(
|
|
4595
|
+
flushSync(stream2);
|
|
4596
|
+
Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
|
|
4597
|
+
Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
|
|
4598
|
+
Atomics.notify(stream2[kImpl].state, READ_INDEX);
|
|
4599
4599
|
continue;
|
|
4600
4600
|
} else if (leftover < 0) {
|
|
4601
4601
|
throw new Error("overwritten");
|
|
4602
4602
|
}
|
|
4603
|
-
let toWrite =
|
|
4603
|
+
let toWrite = stream2[kImpl].buf.slice(0, leftover);
|
|
4604
4604
|
let toWriteBytes = Buffer.byteLength(toWrite);
|
|
4605
4605
|
if (toWriteBytes <= leftover) {
|
|
4606
|
-
|
|
4607
|
-
write(
|
|
4606
|
+
stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
|
|
4607
|
+
write(stream2, toWrite, cb);
|
|
4608
4608
|
} else {
|
|
4609
|
-
flushSync(
|
|
4610
|
-
Atomics.store(
|
|
4611
|
-
Atomics.store(
|
|
4612
|
-
Atomics.notify(
|
|
4613
|
-
while (toWriteBytes >
|
|
4609
|
+
flushSync(stream2);
|
|
4610
|
+
Atomics.store(stream2[kImpl].state, READ_INDEX, 0);
|
|
4611
|
+
Atomics.store(stream2[kImpl].state, WRITE_INDEX, 0);
|
|
4612
|
+
Atomics.notify(stream2[kImpl].state, READ_INDEX);
|
|
4613
|
+
while (toWriteBytes > stream2[kImpl].buf.length) {
|
|
4614
4614
|
leftover = leftover / 2;
|
|
4615
|
-
toWrite =
|
|
4615
|
+
toWrite = stream2[kImpl].buf.slice(0, leftover);
|
|
4616
4616
|
toWriteBytes = Buffer.byteLength(toWrite);
|
|
4617
4617
|
}
|
|
4618
|
-
|
|
4619
|
-
write(
|
|
4618
|
+
stream2[kImpl].buf = stream2[kImpl].buf.slice(leftover);
|
|
4619
|
+
write(stream2, toWrite, cb);
|
|
4620
4620
|
}
|
|
4621
4621
|
}
|
|
4622
4622
|
}
|
|
4623
|
-
function flushSync(
|
|
4624
|
-
if (
|
|
4623
|
+
function flushSync(stream2) {
|
|
4624
|
+
if (stream2[kImpl].flushing) {
|
|
4625
4625
|
throw new Error("unable to flush while flushing");
|
|
4626
4626
|
}
|
|
4627
|
-
const writeIndex = Atomics.load(
|
|
4627
|
+
const writeIndex = Atomics.load(stream2[kImpl].state, WRITE_INDEX);
|
|
4628
4628
|
let spins = 0;
|
|
4629
4629
|
while (true) {
|
|
4630
|
-
const readIndex = Atomics.load(
|
|
4630
|
+
const readIndex = Atomics.load(stream2[kImpl].state, READ_INDEX);
|
|
4631
4631
|
if (readIndex === -2) {
|
|
4632
4632
|
throw Error("_flushSync failed");
|
|
4633
4633
|
}
|
|
4634
4634
|
if (readIndex !== writeIndex) {
|
|
4635
|
-
Atomics.wait(
|
|
4635
|
+
Atomics.wait(stream2[kImpl].state, READ_INDEX, readIndex, 1e3);
|
|
4636
4636
|
} else {
|
|
4637
4637
|
break;
|
|
4638
4638
|
}
|
|
@@ -4657,11 +4657,11 @@ var require_transport = __commonJS({
|
|
|
4657
4657
|
var sleep = require_atomic_sleep();
|
|
4658
4658
|
var onExit = require_on_exit_leak_free();
|
|
4659
4659
|
var ThreadStream = require_thread_stream();
|
|
4660
|
-
function setupOnExit(
|
|
4661
|
-
onExit.register(
|
|
4662
|
-
onExit.registerBeforeExit(
|
|
4663
|
-
|
|
4664
|
-
onExit.unregister(
|
|
4660
|
+
function setupOnExit(stream2) {
|
|
4661
|
+
onExit.register(stream2, autoEnd);
|
|
4662
|
+
onExit.registerBeforeExit(stream2, flush);
|
|
4663
|
+
stream2.on("close", function() {
|
|
4664
|
+
onExit.unregister(stream2);
|
|
4665
4665
|
});
|
|
4666
4666
|
}
|
|
4667
4667
|
function hasPreloadFlags() {
|
|
@@ -4754,44 +4754,44 @@ var require_transport = __commonJS({
|
|
|
4754
4754
|
}
|
|
4755
4755
|
}
|
|
4756
4756
|
workerOpts = { ...workerOpts, name };
|
|
4757
|
-
const
|
|
4757
|
+
const stream2 = new ThreadStream({
|
|
4758
4758
|
filename,
|
|
4759
4759
|
workerData,
|
|
4760
4760
|
workerOpts,
|
|
4761
4761
|
sync
|
|
4762
4762
|
});
|
|
4763
|
-
|
|
4764
|
-
|
|
4763
|
+
stream2.on("ready", onReady);
|
|
4764
|
+
stream2.on("close", function() {
|
|
4765
4765
|
process.removeListener("exit", onExit2);
|
|
4766
4766
|
});
|
|
4767
4767
|
process.on("exit", onExit2);
|
|
4768
4768
|
function onReady() {
|
|
4769
4769
|
process.removeListener("exit", onExit2);
|
|
4770
|
-
|
|
4770
|
+
stream2.unref();
|
|
4771
4771
|
if (workerOpts.autoEnd !== false) {
|
|
4772
|
-
setupOnExit(
|
|
4772
|
+
setupOnExit(stream2);
|
|
4773
4773
|
}
|
|
4774
4774
|
}
|
|
4775
4775
|
function onExit2() {
|
|
4776
|
-
if (
|
|
4776
|
+
if (stream2.closed) {
|
|
4777
4777
|
return;
|
|
4778
4778
|
}
|
|
4779
|
-
|
|
4779
|
+
stream2.flushSync();
|
|
4780
4780
|
sleep(100);
|
|
4781
|
-
|
|
4781
|
+
stream2.end();
|
|
4782
4782
|
}
|
|
4783
|
-
return
|
|
4783
|
+
return stream2;
|
|
4784
4784
|
}
|
|
4785
|
-
function autoEnd(
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4785
|
+
function autoEnd(stream2) {
|
|
4786
|
+
stream2.ref();
|
|
4787
|
+
stream2.flushSync();
|
|
4788
|
+
stream2.end();
|
|
4789
|
+
stream2.once("close", function() {
|
|
4790
|
+
stream2.unref();
|
|
4791
4791
|
});
|
|
4792
4792
|
}
|
|
4793
|
-
function flush(
|
|
4794
|
-
|
|
4793
|
+
function flush(stream2) {
|
|
4794
|
+
stream2.flushSync();
|
|
4795
4795
|
}
|
|
4796
4796
|
function transport(fullOptions) {
|
|
4797
4797
|
const { pipeline, targets, levels, dedupe, worker = {}, caller = getCallers(), sync = false } = fullOptions;
|
|
@@ -5049,15 +5049,15 @@ var require_tools = __commonJS({
|
|
|
5049
5049
|
return data + propStr + msgStr + end;
|
|
5050
5050
|
}
|
|
5051
5051
|
}
|
|
5052
|
-
function asChindings(
|
|
5052
|
+
function asChindings(instance2, bindings) {
|
|
5053
5053
|
let value;
|
|
5054
|
-
let data =
|
|
5055
|
-
const stringify2 =
|
|
5056
|
-
const stringifySafe =
|
|
5057
|
-
const stringifiers =
|
|
5054
|
+
let data = instance2[chindingsSym];
|
|
5055
|
+
const stringify2 = instance2[stringifySym];
|
|
5056
|
+
const stringifySafe = instance2[stringifySafeSym];
|
|
5057
|
+
const stringifiers = instance2[stringifiersSym];
|
|
5058
5058
|
const wildcardStringifier = stringifiers[wildcardFirstSym];
|
|
5059
|
-
const serializers =
|
|
5060
|
-
const formatter =
|
|
5059
|
+
const serializers = instance2[serializersSym];
|
|
5060
|
+
const formatter = instance2[formattersSym].bindings;
|
|
5061
5061
|
bindings = formatter(bindings);
|
|
5062
5062
|
for (const key in bindings) {
|
|
5063
5063
|
value = bindings[key];
|
|
@@ -5071,56 +5071,56 @@ var require_tools = __commonJS({
|
|
|
5071
5071
|
}
|
|
5072
5072
|
return data;
|
|
5073
5073
|
}
|
|
5074
|
-
function hasBeenTampered(
|
|
5075
|
-
return
|
|
5074
|
+
function hasBeenTampered(stream2) {
|
|
5075
|
+
return stream2.write !== stream2.constructor.prototype.write;
|
|
5076
5076
|
}
|
|
5077
5077
|
function buildSafeSonicBoom(opts) {
|
|
5078
|
-
const
|
|
5079
|
-
|
|
5078
|
+
const stream2 = new SonicBoom(opts);
|
|
5079
|
+
stream2.on("error", filterBrokenPipe);
|
|
5080
5080
|
if (!opts.sync && isMainThread) {
|
|
5081
|
-
onExit.register(
|
|
5082
|
-
|
|
5083
|
-
onExit.unregister(
|
|
5081
|
+
onExit.register(stream2, autoEnd);
|
|
5082
|
+
stream2.on("close", function() {
|
|
5083
|
+
onExit.unregister(stream2);
|
|
5084
5084
|
});
|
|
5085
5085
|
}
|
|
5086
|
-
return
|
|
5086
|
+
return stream2;
|
|
5087
5087
|
function filterBrokenPipe(err) {
|
|
5088
5088
|
if (err.code === "EPIPE") {
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5089
|
+
stream2.write = noop;
|
|
5090
|
+
stream2.end = noop;
|
|
5091
|
+
stream2.flushSync = noop;
|
|
5092
|
+
stream2.destroy = noop;
|
|
5093
5093
|
return;
|
|
5094
5094
|
}
|
|
5095
|
-
|
|
5096
|
-
|
|
5095
|
+
stream2.removeListener("error", filterBrokenPipe);
|
|
5096
|
+
stream2.emit("error", err);
|
|
5097
5097
|
}
|
|
5098
5098
|
}
|
|
5099
|
-
function autoEnd(
|
|
5100
|
-
if (
|
|
5099
|
+
function autoEnd(stream2, eventName) {
|
|
5100
|
+
if (stream2.destroyed) {
|
|
5101
5101
|
return;
|
|
5102
5102
|
}
|
|
5103
5103
|
if (eventName === "beforeExit") {
|
|
5104
|
-
|
|
5105
|
-
|
|
5106
|
-
|
|
5104
|
+
stream2.flush();
|
|
5105
|
+
stream2.on("drain", function() {
|
|
5106
|
+
stream2.end();
|
|
5107
5107
|
});
|
|
5108
5108
|
} else {
|
|
5109
|
-
|
|
5109
|
+
stream2.flushSync();
|
|
5110
5110
|
}
|
|
5111
5111
|
}
|
|
5112
5112
|
function createArgsNormalizer(defaultOptions) {
|
|
5113
|
-
return function normalizeArgs(
|
|
5113
|
+
return function normalizeArgs(instance2, caller, opts = {}, stream2) {
|
|
5114
5114
|
if (typeof opts === "string") {
|
|
5115
|
-
|
|
5115
|
+
stream2 = buildSafeSonicBoom({ dest: opts });
|
|
5116
5116
|
opts = {};
|
|
5117
|
-
} else if (typeof
|
|
5117
|
+
} else if (typeof stream2 === "string") {
|
|
5118
5118
|
if (opts && opts.transport) {
|
|
5119
5119
|
throw Error("only one of option.transport or stream can be specified");
|
|
5120
5120
|
}
|
|
5121
|
-
|
|
5121
|
+
stream2 = buildSafeSonicBoom({ dest: stream2 });
|
|
5122
5122
|
} else if (opts instanceof SonicBoom || opts.writable || opts._writableState) {
|
|
5123
|
-
|
|
5123
|
+
stream2 = opts;
|
|
5124
5124
|
opts = {};
|
|
5125
5125
|
} else if (opts.transport) {
|
|
5126
5126
|
if (opts.transport instanceof SonicBoom || opts.transport.writable || opts.transport._writableState) {
|
|
@@ -5133,7 +5133,7 @@ var require_tools = __commonJS({
|
|
|
5133
5133
|
if (opts.customLevels) {
|
|
5134
5134
|
customLevels = opts.useOnlyCustomLevels ? opts.customLevels : Object.assign({}, opts.levels, opts.customLevels);
|
|
5135
5135
|
}
|
|
5136
|
-
|
|
5136
|
+
stream2 = transport({ caller, ...opts.transport, levels: customLevels });
|
|
5137
5137
|
}
|
|
5138
5138
|
opts = Object.assign({}, defaultOptions, opts);
|
|
5139
5139
|
opts.serializers = Object.assign({}, defaultOptions.serializers, opts.serializers);
|
|
@@ -5144,14 +5144,14 @@ var require_tools = __commonJS({
|
|
|
5144
5144
|
const { enabled, onChild } = opts;
|
|
5145
5145
|
if (enabled === false) opts.level = "silent";
|
|
5146
5146
|
if (!onChild) opts.onChild = noop;
|
|
5147
|
-
if (!
|
|
5147
|
+
if (!stream2) {
|
|
5148
5148
|
if (!hasBeenTampered(process.stdout)) {
|
|
5149
|
-
|
|
5149
|
+
stream2 = buildSafeSonicBoom({ fd: process.stdout.fd || 1 });
|
|
5150
5150
|
} else {
|
|
5151
|
-
|
|
5151
|
+
stream2 = process.stdout;
|
|
5152
5152
|
}
|
|
5153
5153
|
}
|
|
5154
|
-
return { opts, stream };
|
|
5154
|
+
return { opts, stream: stream2 };
|
|
5155
5155
|
};
|
|
5156
5156
|
}
|
|
5157
5157
|
function stringify(obj, stringifySafeFn) {
|
|
@@ -5238,11 +5238,11 @@ var require_levels = __commonJS({
|
|
|
5238
5238
|
fatal: (hook) => {
|
|
5239
5239
|
const logFatal = genLog(DEFAULT_LEVELS.fatal, hook);
|
|
5240
5240
|
return function(...args) {
|
|
5241
|
-
const
|
|
5241
|
+
const stream2 = this[streamSym];
|
|
5242
5242
|
logFatal.call(this, ...args);
|
|
5243
|
-
if (typeof
|
|
5243
|
+
if (typeof stream2.flushSync === "function") {
|
|
5244
5244
|
try {
|
|
5245
|
-
|
|
5245
|
+
stream2.flushSync();
|
|
5246
5246
|
} catch (e) {
|
|
5247
5247
|
}
|
|
5248
5248
|
}
|
|
@@ -5262,16 +5262,16 @@ var require_levels = __commonJS({
|
|
|
5262
5262
|
o[k] = '{"level":' + Number(k);
|
|
5263
5263
|
return o;
|
|
5264
5264
|
}, {});
|
|
5265
|
-
function genLsCache(
|
|
5266
|
-
const formatter =
|
|
5267
|
-
const { labels } =
|
|
5265
|
+
function genLsCache(instance2) {
|
|
5266
|
+
const formatter = instance2[formattersSym].level;
|
|
5267
|
+
const { labels } = instance2.levels;
|
|
5268
5268
|
const cache = {};
|
|
5269
5269
|
for (const label in labels) {
|
|
5270
5270
|
const level2 = formatter(labels[label], Number(label));
|
|
5271
5271
|
cache[label] = JSON.stringify(level2).slice(0, -1);
|
|
5272
5272
|
}
|
|
5273
|
-
|
|
5274
|
-
return
|
|
5273
|
+
instance2[lsCacheSym] = cache;
|
|
5274
|
+
return instance2;
|
|
5275
5275
|
}
|
|
5276
5276
|
function isStandardLevel(level2, useOnlyCustomLevels) {
|
|
5277
5277
|
if (useOnlyCustomLevels) {
|
|
@@ -5424,7 +5424,7 @@ var require_meta = __commonJS({
|
|
|
5424
5424
|
var require_proto = __commonJS({
|
|
5425
5425
|
"node_modules/pino/lib/proto.js"(exports, module) {
|
|
5426
5426
|
"use strict";
|
|
5427
|
-
var { EventEmitter:
|
|
5427
|
+
var { EventEmitter: EventEmitter7 } = __require("node:events");
|
|
5428
5428
|
var {
|
|
5429
5429
|
lsCacheSym,
|
|
5430
5430
|
levelValSym,
|
|
@@ -5505,7 +5505,7 @@ var require_proto = __commonJS({
|
|
|
5505
5505
|
[getLevelSym]: getLevel,
|
|
5506
5506
|
[setLevelSym]: setLevel
|
|
5507
5507
|
};
|
|
5508
|
-
Object.setPrototypeOf(prototype,
|
|
5508
|
+
Object.setPrototypeOf(prototype, EventEmitter7.prototype);
|
|
5509
5509
|
module.exports = function() {
|
|
5510
5510
|
return Object.create(prototype);
|
|
5511
5511
|
};
|
|
@@ -5516,49 +5516,49 @@ var require_proto = __commonJS({
|
|
|
5516
5516
|
}
|
|
5517
5517
|
const serializers = this[serializersSym];
|
|
5518
5518
|
const formatters = this[formattersSym];
|
|
5519
|
-
const
|
|
5519
|
+
const instance2 = Object.create(this);
|
|
5520
5520
|
if (options == null) {
|
|
5521
|
-
if (
|
|
5522
|
-
|
|
5521
|
+
if (instance2[formattersSym].bindings !== resetChildingsFormatter) {
|
|
5522
|
+
instance2[formattersSym] = buildFormatters(
|
|
5523
5523
|
formatters.level,
|
|
5524
5524
|
resetChildingsFormatter,
|
|
5525
5525
|
formatters.log
|
|
5526
5526
|
);
|
|
5527
5527
|
}
|
|
5528
|
-
|
|
5528
|
+
instance2[chindingsSym] = asChindings(instance2, bindings2);
|
|
5529
5529
|
if (this.onChild !== noop) {
|
|
5530
|
-
this.onChild(
|
|
5530
|
+
this.onChild(instance2);
|
|
5531
5531
|
}
|
|
5532
|
-
return
|
|
5532
|
+
return instance2;
|
|
5533
5533
|
}
|
|
5534
5534
|
if (options.hasOwnProperty("serializers") === true) {
|
|
5535
|
-
|
|
5535
|
+
instance2[serializersSym] = /* @__PURE__ */ Object.create(null);
|
|
5536
5536
|
for (const k in serializers) {
|
|
5537
|
-
|
|
5537
|
+
instance2[serializersSym][k] = serializers[k];
|
|
5538
5538
|
}
|
|
5539
5539
|
const parentSymbols = Object.getOwnPropertySymbols(serializers);
|
|
5540
5540
|
for (var i = 0; i < parentSymbols.length; i++) {
|
|
5541
5541
|
const ks = parentSymbols[i];
|
|
5542
|
-
|
|
5542
|
+
instance2[serializersSym][ks] = serializers[ks];
|
|
5543
5543
|
}
|
|
5544
5544
|
for (const bk in options.serializers) {
|
|
5545
|
-
|
|
5545
|
+
instance2[serializersSym][bk] = options.serializers[bk];
|
|
5546
5546
|
}
|
|
5547
5547
|
const bindingsSymbols = Object.getOwnPropertySymbols(options.serializers);
|
|
5548
5548
|
for (var bi = 0; bi < bindingsSymbols.length; bi++) {
|
|
5549
5549
|
const bks = bindingsSymbols[bi];
|
|
5550
|
-
|
|
5550
|
+
instance2[serializersSym][bks] = options.serializers[bks];
|
|
5551
5551
|
}
|
|
5552
|
-
} else
|
|
5552
|
+
} else instance2[serializersSym] = serializers;
|
|
5553
5553
|
if (options.hasOwnProperty("formatters")) {
|
|
5554
5554
|
const { level: level2, bindings: chindings, log } = options.formatters;
|
|
5555
|
-
|
|
5555
|
+
instance2[formattersSym] = buildFormatters(
|
|
5556
5556
|
level2 || formatters.level,
|
|
5557
5557
|
chindings || resetChildingsFormatter,
|
|
5558
5558
|
log || formatters.log
|
|
5559
5559
|
);
|
|
5560
5560
|
} else {
|
|
5561
|
-
|
|
5561
|
+
instance2[formattersSym] = buildFormatters(
|
|
5562
5562
|
formatters.level,
|
|
5563
5563
|
resetChildingsFormatter,
|
|
5564
5564
|
formatters.log
|
|
@@ -5566,27 +5566,27 @@ var require_proto = __commonJS({
|
|
|
5566
5566
|
}
|
|
5567
5567
|
if (options.hasOwnProperty("customLevels") === true) {
|
|
5568
5568
|
assertNoLevelCollisions(this.levels, options.customLevels);
|
|
5569
|
-
|
|
5570
|
-
genLsCache(
|
|
5569
|
+
instance2.levels = mappings(options.customLevels, instance2[useOnlyCustomLevelsSym]);
|
|
5570
|
+
genLsCache(instance2);
|
|
5571
5571
|
}
|
|
5572
5572
|
if (typeof options.redact === "object" && options.redact !== null || Array.isArray(options.redact)) {
|
|
5573
|
-
|
|
5574
|
-
const stringifiers = redaction(
|
|
5573
|
+
instance2.redact = options.redact;
|
|
5574
|
+
const stringifiers = redaction(instance2.redact, stringify);
|
|
5575
5575
|
const formatOpts = { stringify: stringifiers[redactFmtSym] };
|
|
5576
|
-
|
|
5577
|
-
|
|
5578
|
-
|
|
5576
|
+
instance2[stringifySym] = stringify;
|
|
5577
|
+
instance2[stringifiersSym] = stringifiers;
|
|
5578
|
+
instance2[formatOptsSym] = formatOpts;
|
|
5579
5579
|
}
|
|
5580
5580
|
if (typeof options.msgPrefix === "string") {
|
|
5581
|
-
|
|
5581
|
+
instance2[msgPrefixSym] = (this[msgPrefixSym] || "") + options.msgPrefix;
|
|
5582
5582
|
}
|
|
5583
|
-
|
|
5583
|
+
instance2[chindingsSym] = asChindings(instance2, bindings2);
|
|
5584
5584
|
if (options.level !== void 0 && options.level !== this.level || options.hasOwnProperty("customLevels")) {
|
|
5585
5585
|
const childLevel = options.level || this.level;
|
|
5586
|
-
|
|
5586
|
+
instance2[setLevelSym](childLevel);
|
|
5587
5587
|
}
|
|
5588
|
-
this.onChild(
|
|
5589
|
-
return
|
|
5588
|
+
this.onChild(instance2);
|
|
5589
|
+
return instance2;
|
|
5590
5590
|
}
|
|
5591
5591
|
function bindings() {
|
|
5592
5592
|
const chindings = this[chindingsSym];
|
|
@@ -5628,23 +5628,23 @@ var require_proto = __commonJS({
|
|
|
5628
5628
|
obj = mixinMergeStrategy(obj, mixin(obj, num, this));
|
|
5629
5629
|
}
|
|
5630
5630
|
const s = this[asJsonSym](obj, msg, num, t);
|
|
5631
|
-
const
|
|
5632
|
-
if (
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5631
|
+
const stream2 = this[streamSym];
|
|
5632
|
+
if (stream2[needsMetadataGsym] === true) {
|
|
5633
|
+
stream2.lastLevel = num;
|
|
5634
|
+
stream2.lastObj = obj;
|
|
5635
|
+
stream2.lastMsg = msg;
|
|
5636
|
+
stream2.lastTime = t.slice(this[timeSliceIndexSym]);
|
|
5637
|
+
stream2.lastLogger = this;
|
|
5638
5638
|
}
|
|
5639
|
-
|
|
5639
|
+
stream2.write(streamWriteHook ? streamWriteHook(s) : s);
|
|
5640
5640
|
}
|
|
5641
5641
|
function flush(cb) {
|
|
5642
5642
|
if (cb != null && typeof cb !== "function") {
|
|
5643
5643
|
throw Error("callback must be a function");
|
|
5644
5644
|
}
|
|
5645
|
-
const
|
|
5646
|
-
if (typeof
|
|
5647
|
-
|
|
5645
|
+
const stream2 = this[streamSym];
|
|
5646
|
+
if (typeof stream2.flush === "function") {
|
|
5647
|
+
stream2.flush(cb || noop);
|
|
5648
5648
|
} else if (cb) cb();
|
|
5649
5649
|
}
|
|
5650
5650
|
}
|
|
@@ -6289,23 +6289,23 @@ var require_multistream = __commonJS({
|
|
|
6289
6289
|
const level2 = this.lastLevel;
|
|
6290
6290
|
const { streams: streams2 } = this;
|
|
6291
6291
|
let recordedLevel = 0;
|
|
6292
|
-
let
|
|
6292
|
+
let stream2;
|
|
6293
6293
|
for (let i = initLoopVar(streams2.length, opts.dedupe); checkLoopVar(i, streams2.length, opts.dedupe); i = adjustLoopVar(i, opts.dedupe)) {
|
|
6294
6294
|
dest = streams2[i];
|
|
6295
6295
|
if (dest.level <= level2) {
|
|
6296
6296
|
if (recordedLevel !== 0 && recordedLevel !== dest.level) {
|
|
6297
6297
|
break;
|
|
6298
6298
|
}
|
|
6299
|
-
|
|
6300
|
-
if (
|
|
6299
|
+
stream2 = dest.stream;
|
|
6300
|
+
if (stream2[metadata]) {
|
|
6301
6301
|
const { lastTime, lastMsg, lastObj, lastLogger } = this;
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6302
|
+
stream2.lastLevel = level2;
|
|
6303
|
+
stream2.lastTime = lastTime;
|
|
6304
|
+
stream2.lastMsg = lastMsg;
|
|
6305
|
+
stream2.lastObj = lastObj;
|
|
6306
|
+
stream2.lastLogger = lastLogger;
|
|
6307
6307
|
}
|
|
6308
|
-
|
|
6308
|
+
stream2.write(data);
|
|
6309
6309
|
if (opts.dedupe) {
|
|
6310
6310
|
recordedLevel = dest.level;
|
|
6311
6311
|
}
|
|
@@ -6315,16 +6315,16 @@ var require_multistream = __commonJS({
|
|
|
6315
6315
|
}
|
|
6316
6316
|
}
|
|
6317
6317
|
function emit(...args) {
|
|
6318
|
-
for (const { stream } of this.streams) {
|
|
6319
|
-
if (typeof
|
|
6320
|
-
|
|
6318
|
+
for (const { stream: stream2 } of this.streams) {
|
|
6319
|
+
if (typeof stream2.emit === "function") {
|
|
6320
|
+
stream2.emit(...args);
|
|
6321
6321
|
}
|
|
6322
6322
|
}
|
|
6323
6323
|
}
|
|
6324
6324
|
function flushSync() {
|
|
6325
|
-
for (const { stream } of this.streams) {
|
|
6326
|
-
if (typeof
|
|
6327
|
-
|
|
6325
|
+
for (const { stream: stream2 } of this.streams) {
|
|
6326
|
+
if (typeof stream2.flushSync === "function") {
|
|
6327
|
+
stream2.flushSync();
|
|
6328
6328
|
}
|
|
6329
6329
|
}
|
|
6330
6330
|
}
|
|
@@ -6370,11 +6370,11 @@ var require_multistream = __commonJS({
|
|
|
6370
6370
|
return res;
|
|
6371
6371
|
}
|
|
6372
6372
|
function end() {
|
|
6373
|
-
for (const { stream } of this.streams) {
|
|
6374
|
-
if (typeof
|
|
6375
|
-
|
|
6373
|
+
for (const { stream: stream2 } of this.streams) {
|
|
6374
|
+
if (typeof stream2.flushSync === "function") {
|
|
6375
|
+
stream2.flushSync();
|
|
6376
6376
|
}
|
|
6377
|
-
|
|
6377
|
+
stream2.end();
|
|
6378
6378
|
}
|
|
6379
6379
|
}
|
|
6380
6380
|
function clone(level2) {
|
|
@@ -6502,8 +6502,8 @@ var require_pino = __commonJS({
|
|
|
6502
6502
|
var normalize = createArgsNormalizer(defaultOptions);
|
|
6503
6503
|
var serializers = Object.assign(/* @__PURE__ */ Object.create(null), stdSerializers);
|
|
6504
6504
|
function pino2(...args) {
|
|
6505
|
-
const
|
|
6506
|
-
const { opts, stream } = normalize(
|
|
6505
|
+
const instance2 = {};
|
|
6506
|
+
const { opts, stream: stream2 } = normalize(instance2, caller(), ...args);
|
|
6507
6507
|
if (opts.level && typeof opts.level === "string" && DEFAULT_LEVELS[opts.level.toLowerCase()] !== void 0) opts.level = opts.level.toLowerCase();
|
|
6508
6508
|
const {
|
|
6509
6509
|
redact,
|
|
@@ -6566,16 +6566,16 @@ var require_pino = __commonJS({
|
|
|
6566
6566
|
if (msgPrefix && typeof msgPrefix !== "string") throw Error(`Unknown msgPrefix type "${typeof msgPrefix}" - expected "string"`);
|
|
6567
6567
|
assertDefaultLevelFound(level2, customLevels, useOnlyCustomLevels);
|
|
6568
6568
|
const levels = mappings(customLevels, useOnlyCustomLevels);
|
|
6569
|
-
if (typeof
|
|
6570
|
-
|
|
6569
|
+
if (typeof stream2.emit === "function") {
|
|
6570
|
+
stream2.emit("message", { code: "PINO_CONFIG", config: { levels, messageKey, errorKey } });
|
|
6571
6571
|
}
|
|
6572
6572
|
assertLevelComparison(levelComparison);
|
|
6573
6573
|
const levelCompFunc = genLevelComparison(levelComparison);
|
|
6574
|
-
Object.assign(
|
|
6574
|
+
Object.assign(instance2, {
|
|
6575
6575
|
levels,
|
|
6576
6576
|
[levelCompSym]: levelCompFunc,
|
|
6577
6577
|
[useOnlyCustomLevelsSym]: useOnlyCustomLevels,
|
|
6578
|
-
[streamSym]:
|
|
6578
|
+
[streamSym]: stream2,
|
|
6579
6579
|
[timeSym]: time2,
|
|
6580
6580
|
[timeSliceIndexSym]: timeSliceIndex,
|
|
6581
6581
|
[stringifySym]: stringify,
|
|
@@ -6598,10 +6598,10 @@ var require_pino = __commonJS({
|
|
|
6598
6598
|
onChild,
|
|
6599
6599
|
[msgPrefixSym]: msgPrefix
|
|
6600
6600
|
});
|
|
6601
|
-
Object.setPrototypeOf(
|
|
6602
|
-
genLsCache(
|
|
6603
|
-
|
|
6604
|
-
return
|
|
6601
|
+
Object.setPrototypeOf(instance2, proto());
|
|
6602
|
+
genLsCache(instance2);
|
|
6603
|
+
instance2[setLevelSym](level2);
|
|
6604
|
+
return instance2;
|
|
6605
6605
|
}
|
|
6606
6606
|
module.exports = pino2;
|
|
6607
6607
|
module.exports.destination = (dest = process.stdout.fd) => {
|
|
@@ -6738,7 +6738,7 @@ import { EventEmitter } from "events";
|
|
|
6738
6738
|
import fs from "fs";
|
|
6739
6739
|
import { createWriteStream } from "fs";
|
|
6740
6740
|
import { tmpdir as tmpdir4 } from "os";
|
|
6741
|
-
import { join as
|
|
6741
|
+
import { join as join5 } from "path";
|
|
6742
6742
|
|
|
6743
6743
|
// src/core/backends/naudiodon-backend.ts
|
|
6744
6744
|
var UnsupportedError = class extends Error {
|
|
@@ -7087,7 +7087,7 @@ import { spawn } from "child_process";
|
|
|
7087
7087
|
import { tmpdir as tmpdir3 } from "os";
|
|
7088
7088
|
import { join as join3 } from "path";
|
|
7089
7089
|
import { writeFileSync as writeFileSync3, unlinkSync as unlinkSync3, existsSync as existsSync3 } from "fs";
|
|
7090
|
-
var SAFE_PATH_REGEX3 = /^[\w\:\\_
|
|
7090
|
+
var SAFE_PATH_REGEX3 = /^[\w\:\\_.\-$@\/]+$/i;
|
|
7091
7091
|
function wslPathToWindows(wslPath) {
|
|
7092
7092
|
if (wslPath.startsWith("//wsl$/")) {
|
|
7093
7093
|
return wslPath;
|
|
@@ -7095,6 +7095,9 @@ function wslPathToWindows(wslPath) {
|
|
|
7095
7095
|
if (/^\/mnt\/[a-z]\//.test(wslPath)) {
|
|
7096
7096
|
return wslPath.replace(/^\/mnt\/([a-z])\//, "$1:/").replace(/\//g, "\\");
|
|
7097
7097
|
}
|
|
7098
|
+
if (wslPath.startsWith("/tmp/")) {
|
|
7099
|
+
return wslPath.replace(/^\/tmp\//, "//wsl$/Ubuntu/tmp/");
|
|
7100
|
+
}
|
|
7098
7101
|
return wslPath;
|
|
7099
7102
|
}
|
|
7100
7103
|
var UnsupportedError2 = class extends Error {
|
|
@@ -7386,12 +7389,43 @@ var HowlerBackend = class {
|
|
|
7386
7389
|
}
|
|
7387
7390
|
};
|
|
7388
7391
|
|
|
7392
|
+
// src/utils/logger.ts
|
|
7393
|
+
var import_pino = __toESM(require_pino(), 1);
|
|
7394
|
+
import { homedir } from "os";
|
|
7395
|
+
import { join as join4 } from "path";
|
|
7396
|
+
import { existsSync as existsSync4, mkdirSync } from "fs";
|
|
7397
|
+
var logDir = join4(homedir(), ".ocosay");
|
|
7398
|
+
var logFile = join4(logDir, "ocosay.log");
|
|
7399
|
+
if (!existsSync4(logDir)) {
|
|
7400
|
+
try {
|
|
7401
|
+
mkdirSync(logDir, { recursive: true });
|
|
7402
|
+
} catch {
|
|
7403
|
+
}
|
|
7404
|
+
}
|
|
7405
|
+
var streams = [
|
|
7406
|
+
{ stream: process.stdout }
|
|
7407
|
+
];
|
|
7408
|
+
try {
|
|
7409
|
+
streams.push({ stream: import_pino.default.destination({ dest: logFile, mkdir: true }) });
|
|
7410
|
+
} catch {
|
|
7411
|
+
}
|
|
7412
|
+
var level = process.env.NODE_ENV !== "production" ? "debug" : process.env.OCOSAY_LOG_LEVEL || "info";
|
|
7413
|
+
var logger = (0, import_pino.default)(
|
|
7414
|
+
{
|
|
7415
|
+
level,
|
|
7416
|
+
base: { service: "ocosay" },
|
|
7417
|
+
timestamp: import_pino.default.stdTimeFunctions.isoTime
|
|
7418
|
+
},
|
|
7419
|
+
import_pino.default.multistream(streams)
|
|
7420
|
+
);
|
|
7421
|
+
|
|
7389
7422
|
// src/core/backends/index.ts
|
|
7390
7423
|
function isNaudiodonAvailable() {
|
|
7391
7424
|
try {
|
|
7392
7425
|
__require.resolve("naudiodon");
|
|
7393
7426
|
return true;
|
|
7394
|
-
} catch (
|
|
7427
|
+
} catch (err) {
|
|
7428
|
+
logger.debug({ err }, "naudiodon not available");
|
|
7395
7429
|
return false;
|
|
7396
7430
|
}
|
|
7397
7431
|
}
|
|
@@ -7414,7 +7448,8 @@ function createBackend(type = "auto" /* AUTO */, options = {}) {
|
|
|
7414
7448
|
if (naudiodon) {
|
|
7415
7449
|
return new NaudiodonBackend(options);
|
|
7416
7450
|
}
|
|
7417
|
-
} catch (
|
|
7451
|
+
} catch (err) {
|
|
7452
|
+
logger.warn({ err }, "failed to initialize naudiodon backend");
|
|
7418
7453
|
}
|
|
7419
7454
|
}
|
|
7420
7455
|
switch (platform) {
|
|
@@ -7507,7 +7542,7 @@ var AudioPlayer = class extends EventEmitter {
|
|
|
7507
7542
|
this._playing = true;
|
|
7508
7543
|
this._paused = false;
|
|
7509
7544
|
try {
|
|
7510
|
-
const tempFile =
|
|
7545
|
+
const tempFile = join5(tmpdir4(), `ocosay-${Date.now()}.${format}`);
|
|
7511
7546
|
this.currentFile = tempFile;
|
|
7512
7547
|
if (Buffer.isBuffer(audioData)) {
|
|
7513
7548
|
fs.writeFileSync(tempFile, audioData);
|
|
@@ -7604,42 +7639,12 @@ var AudioPlayer = class extends EventEmitter {
|
|
|
7604
7639
|
}
|
|
7605
7640
|
};
|
|
7606
7641
|
|
|
7607
|
-
// src/utils/logger.ts
|
|
7608
|
-
var import_pino = __toESM(require_pino(), 1);
|
|
7609
|
-
import { homedir } from "os";
|
|
7610
|
-
import { join as join5 } from "path";
|
|
7611
|
-
import { existsSync as existsSync4, mkdirSync } from "fs";
|
|
7612
|
-
var logDir = join5(homedir(), ".ocosay");
|
|
7613
|
-
var logFile = join5(logDir, "ocosay.log");
|
|
7614
|
-
if (!existsSync4(logDir)) {
|
|
7615
|
-
try {
|
|
7616
|
-
mkdirSync(logDir, { recursive: true });
|
|
7617
|
-
} catch {
|
|
7618
|
-
}
|
|
7619
|
-
}
|
|
7620
|
-
var streams = [
|
|
7621
|
-
{ stream: process.stdout }
|
|
7622
|
-
];
|
|
7623
|
-
try {
|
|
7624
|
-
streams.push({ stream: import_pino.default.destination({ dest: logFile, mkdir: true }) });
|
|
7625
|
-
} catch {
|
|
7626
|
-
}
|
|
7627
|
-
var level = process.env.NODE_ENV !== "production" ? "debug" : process.env.OCOSAY_LOG_LEVEL || "info";
|
|
7628
|
-
var logger = (0, import_pino.default)(
|
|
7629
|
-
{
|
|
7630
|
-
level,
|
|
7631
|
-
base: { service: "ocosay" },
|
|
7632
|
-
timestamp: import_pino.default.stdTimeFunctions.isoTime
|
|
7633
|
-
},
|
|
7634
|
-
import_pino.default.multistream(streams)
|
|
7635
|
-
);
|
|
7636
|
-
|
|
7637
7642
|
// src/core/speaker.ts
|
|
7638
7643
|
function toast(options) {
|
|
7639
|
-
const
|
|
7640
|
-
if (
|
|
7644
|
+
const tui2 = global.__opencode_tui__;
|
|
7645
|
+
if (tui2?.showToast) {
|
|
7641
7646
|
try {
|
|
7642
|
-
|
|
7647
|
+
tui2.showToast({
|
|
7643
7648
|
title: options.title,
|
|
7644
7649
|
message: options.body,
|
|
7645
7650
|
variant: options.type,
|
|
@@ -7730,6 +7735,7 @@ var Speaker = class extends EventEmitter2 {
|
|
|
7730
7735
|
}
|
|
7731
7736
|
} catch (error) {
|
|
7732
7737
|
this.isSpeaking = false;
|
|
7738
|
+
logger.error({ error }, "speak failed");
|
|
7733
7739
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
7734
7740
|
toast({
|
|
7735
7741
|
title: "TTS playback error",
|
|
@@ -7806,50 +7812,512 @@ var Speaker = class extends EventEmitter2 {
|
|
|
7806
7812
|
return provider.getCapabilities();
|
|
7807
7813
|
}
|
|
7808
7814
|
/**
|
|
7809
|
-
* 获取所有已注册的 Provider
|
|
7815
|
+
* 获取所有已注册的 Provider
|
|
7816
|
+
*/
|
|
7817
|
+
getProviders() {
|
|
7818
|
+
return listProviders();
|
|
7819
|
+
}
|
|
7820
|
+
/**
|
|
7821
|
+
* 是否正在播放
|
|
7822
|
+
*/
|
|
7823
|
+
isPlaying() {
|
|
7824
|
+
return this.isSpeaking && !this.isPaused;
|
|
7825
|
+
}
|
|
7826
|
+
/**
|
|
7827
|
+
* 是否暂停
|
|
7828
|
+
*/
|
|
7829
|
+
isPausedState() {
|
|
7830
|
+
return this.isPaused;
|
|
7831
|
+
}
|
|
7832
|
+
};
|
|
7833
|
+
var defaultSpeaker;
|
|
7834
|
+
function getDefaultSpeaker() {
|
|
7835
|
+
if (!defaultSpeaker) {
|
|
7836
|
+
defaultSpeaker = new Speaker();
|
|
7837
|
+
}
|
|
7838
|
+
return defaultSpeaker;
|
|
7839
|
+
}
|
|
7840
|
+
async function speak(text, options) {
|
|
7841
|
+
const speaker2 = getDefaultSpeaker();
|
|
7842
|
+
return speaker2.speak(text, options);
|
|
7843
|
+
}
|
|
7844
|
+
async function stop() {
|
|
7845
|
+
const speaker2 = getDefaultSpeaker();
|
|
7846
|
+
return speaker2.stop();
|
|
7847
|
+
}
|
|
7848
|
+
function pause() {
|
|
7849
|
+
const speaker2 = getDefaultSpeaker();
|
|
7850
|
+
speaker2.pause();
|
|
7851
|
+
}
|
|
7852
|
+
function resume() {
|
|
7853
|
+
const speaker2 = getDefaultSpeaker();
|
|
7854
|
+
speaker2.resume();
|
|
7855
|
+
}
|
|
7856
|
+
async function listVoices(providerName) {
|
|
7857
|
+
const speaker2 = getDefaultSpeaker();
|
|
7858
|
+
return speaker2.listVoices(providerName);
|
|
7859
|
+
}
|
|
7860
|
+
|
|
7861
|
+
// src/services/speaker-service.ts
|
|
7862
|
+
var SpeakerService = class {
|
|
7863
|
+
constructor(options = {}) {
|
|
7864
|
+
this.options = options;
|
|
7865
|
+
this.speaker = getDefaultSpeaker();
|
|
7866
|
+
}
|
|
7867
|
+
options;
|
|
7868
|
+
speaker;
|
|
7869
|
+
async speak(text, options) {
|
|
7870
|
+
const timestamp = this.getTimestamp();
|
|
7871
|
+
logger.info(`[Ocosay][${timestamp}][INFO][Speaker] \u5BF9\u5E94\u4E8B\u4EF6{\u64AD\u653E\u5F00\u59CB} - \u6587\u672C\u957F\u5EA6: ${text.length}`);
|
|
7872
|
+
return this.speaker.speak(text, options);
|
|
7873
|
+
}
|
|
7874
|
+
pause() {
|
|
7875
|
+
this.speaker.pause();
|
|
7876
|
+
}
|
|
7877
|
+
resume() {
|
|
7878
|
+
this.speaker.resume();
|
|
7879
|
+
}
|
|
7880
|
+
async stop() {
|
|
7881
|
+
return this.speaker.stop();
|
|
7882
|
+
}
|
|
7883
|
+
async listVoices(providerName) {
|
|
7884
|
+
return this.speaker.listVoices(providerName);
|
|
7885
|
+
}
|
|
7886
|
+
getCapabilities(providerName) {
|
|
7887
|
+
return this.speaker.getCapabilities(providerName);
|
|
7888
|
+
}
|
|
7889
|
+
getProviders() {
|
|
7890
|
+
return this.speaker.getProviders();
|
|
7891
|
+
}
|
|
7892
|
+
isPlaying() {
|
|
7893
|
+
return this.speaker.isPlaying();
|
|
7894
|
+
}
|
|
7895
|
+
isPausedState() {
|
|
7896
|
+
return this.speaker.isPausedState();
|
|
7897
|
+
}
|
|
7898
|
+
async destroy() {
|
|
7899
|
+
return this.speaker.destroy();
|
|
7900
|
+
}
|
|
7901
|
+
getTimestamp() {
|
|
7902
|
+
const now = /* @__PURE__ */ new Date();
|
|
7903
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
7904
|
+
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
|
|
7905
|
+
}
|
|
7906
|
+
};
|
|
7907
|
+
var defaultSpeakerService;
|
|
7908
|
+
function getDefaultSpeakerService() {
|
|
7909
|
+
if (!defaultSpeakerService) {
|
|
7910
|
+
defaultSpeakerService = new SpeakerService();
|
|
7911
|
+
}
|
|
7912
|
+
return defaultSpeakerService;
|
|
7913
|
+
}
|
|
7914
|
+
async function speak2(text, options) {
|
|
7915
|
+
if (options) {
|
|
7916
|
+
return speak(text, options);
|
|
7917
|
+
}
|
|
7918
|
+
return speak(text);
|
|
7919
|
+
}
|
|
7920
|
+
async function stop2() {
|
|
7921
|
+
return stop();
|
|
7922
|
+
}
|
|
7923
|
+
function pause2() {
|
|
7924
|
+
pause();
|
|
7925
|
+
}
|
|
7926
|
+
function resume2() {
|
|
7927
|
+
resume();
|
|
7928
|
+
}
|
|
7929
|
+
async function listVoices2(providerName) {
|
|
7930
|
+
return listVoices(providerName);
|
|
7931
|
+
}
|
|
7932
|
+
|
|
7933
|
+
// src/services/streaming-service.ts
|
|
7934
|
+
import { EventEmitter as EventEmitter4 } from "events";
|
|
7935
|
+
|
|
7936
|
+
// src/core/stream-player.ts
|
|
7937
|
+
import { EventEmitter as EventEmitter3 } from "events";
|
|
7938
|
+
var StreamPlayer = class extends EventEmitter3 {
|
|
7939
|
+
backend = null;
|
|
7940
|
+
_bytesWritten = 0;
|
|
7941
|
+
_started = false;
|
|
7942
|
+
_paused = false;
|
|
7943
|
+
_stopped = false;
|
|
7944
|
+
format = "mp3";
|
|
7945
|
+
events;
|
|
7946
|
+
constructor(options = {}) {
|
|
7947
|
+
super();
|
|
7948
|
+
this.format = options.format || "mp3";
|
|
7949
|
+
this.events = options.events;
|
|
7950
|
+
const backendType = options.backendType || "naudiodon" /* NAUDIODON */;
|
|
7951
|
+
this.backend = createBackend(backendType, {
|
|
7952
|
+
format: this.format,
|
|
7953
|
+
events: {
|
|
7954
|
+
onStart: () => {
|
|
7955
|
+
this.events?.onStart?.();
|
|
7956
|
+
this.emit("start");
|
|
7957
|
+
},
|
|
7958
|
+
onEnd: () => {
|
|
7959
|
+
this.events?.onEnd?.();
|
|
7960
|
+
this.emit("end");
|
|
7961
|
+
},
|
|
7962
|
+
onError: (error) => {
|
|
7963
|
+
this.handleError(error);
|
|
7964
|
+
},
|
|
7965
|
+
onPause: () => {
|
|
7966
|
+
this._paused = true;
|
|
7967
|
+
this.events?.onPause?.();
|
|
7968
|
+
this.emit("pause");
|
|
7969
|
+
},
|
|
7970
|
+
onResume: () => {
|
|
7971
|
+
this._paused = false;
|
|
7972
|
+
this.events?.onResume?.();
|
|
7973
|
+
this.emit("resume");
|
|
7974
|
+
},
|
|
7975
|
+
onStop: () => {
|
|
7976
|
+
this.events?.onStop?.();
|
|
7977
|
+
this.emit("stop");
|
|
7978
|
+
},
|
|
7979
|
+
onProgress: (bytes) => {
|
|
7980
|
+
this.events?.onProgress?.(bytes);
|
|
7981
|
+
this.emit("progress", bytes);
|
|
7982
|
+
}
|
|
7983
|
+
}
|
|
7984
|
+
});
|
|
7985
|
+
}
|
|
7986
|
+
/**
|
|
7987
|
+
* 开始播放
|
|
7988
|
+
* 初始化后端,准备接收音频数据
|
|
7989
|
+
*/
|
|
7990
|
+
start() {
|
|
7991
|
+
if (this._started) {
|
|
7992
|
+
return;
|
|
7993
|
+
}
|
|
7994
|
+
if (!this.backend) {
|
|
7995
|
+
this.handleError(new Error("Audio backend not initialized"));
|
|
7996
|
+
return;
|
|
7997
|
+
}
|
|
7998
|
+
this.backend.start("");
|
|
7999
|
+
this._started = true;
|
|
8000
|
+
this._stopped = false;
|
|
8001
|
+
this._paused = false;
|
|
8002
|
+
this._bytesWritten = 0;
|
|
8003
|
+
}
|
|
8004
|
+
/**
|
|
8005
|
+
* 写入音频数据块(边收边播)
|
|
8006
|
+
* 如果尚未 start(),会自动调用
|
|
8007
|
+
*/
|
|
8008
|
+
write(chunk) {
|
|
8009
|
+
if (this._stopped) {
|
|
8010
|
+
return;
|
|
8011
|
+
}
|
|
8012
|
+
if (!this._started) {
|
|
8013
|
+
this.start();
|
|
8014
|
+
}
|
|
8015
|
+
if (this.backend) {
|
|
8016
|
+
this.backend.write(chunk);
|
|
8017
|
+
this._bytesWritten += chunk.length;
|
|
8018
|
+
this.events?.onProgress?.(this._bytesWritten);
|
|
8019
|
+
this.emit("progress", this._bytesWritten);
|
|
8020
|
+
}
|
|
8021
|
+
}
|
|
8022
|
+
/**
|
|
8023
|
+
* 结束写入
|
|
8024
|
+
* 通知后端写入完成,但保持播放直到结束
|
|
8025
|
+
*/
|
|
8026
|
+
end() {
|
|
8027
|
+
if (this.backend) {
|
|
8028
|
+
this.backend.end();
|
|
8029
|
+
}
|
|
8030
|
+
}
|
|
8031
|
+
/**
|
|
8032
|
+
* 停止播放
|
|
8033
|
+
* 立即停止播放并释放资源
|
|
8034
|
+
*/
|
|
8035
|
+
stop() {
|
|
8036
|
+
this._stopped = true;
|
|
8037
|
+
this._started = false;
|
|
8038
|
+
this._paused = false;
|
|
8039
|
+
if (this.backend) {
|
|
8040
|
+
this.backend.stop();
|
|
8041
|
+
}
|
|
8042
|
+
this._bytesWritten = 0;
|
|
8043
|
+
this.events?.onStop?.();
|
|
8044
|
+
this.emit("stop");
|
|
8045
|
+
}
|
|
8046
|
+
/**
|
|
8047
|
+
* 暂停播放
|
|
8048
|
+
*/
|
|
8049
|
+
pause() {
|
|
8050
|
+
if (!this._started || this._paused || this._stopped) {
|
|
8051
|
+
return;
|
|
8052
|
+
}
|
|
8053
|
+
if (this.backend) {
|
|
8054
|
+
this.backend.pause();
|
|
8055
|
+
}
|
|
8056
|
+
}
|
|
8057
|
+
/**
|
|
8058
|
+
* 恢复播放
|
|
8059
|
+
*/
|
|
8060
|
+
resume() {
|
|
8061
|
+
if (!this._paused || this._stopped) {
|
|
8062
|
+
return;
|
|
8063
|
+
}
|
|
8064
|
+
if (this.backend) {
|
|
8065
|
+
this.backend.resume();
|
|
8066
|
+
}
|
|
8067
|
+
}
|
|
8068
|
+
/**
|
|
8069
|
+
* 是否已启动
|
|
8070
|
+
*/
|
|
8071
|
+
isStarted() {
|
|
8072
|
+
return this._started;
|
|
8073
|
+
}
|
|
8074
|
+
/**
|
|
8075
|
+
* 是否暂停
|
|
8076
|
+
*/
|
|
8077
|
+
isPaused() {
|
|
8078
|
+
return this._paused;
|
|
8079
|
+
}
|
|
8080
|
+
/**
|
|
8081
|
+
* 是否已停止
|
|
8082
|
+
*/
|
|
8083
|
+
isStopped() {
|
|
8084
|
+
return this._stopped;
|
|
8085
|
+
}
|
|
8086
|
+
/**
|
|
8087
|
+
* 获取已写入的字节数
|
|
8088
|
+
*/
|
|
8089
|
+
getBytesWritten() {
|
|
8090
|
+
return this._bytesWritten;
|
|
8091
|
+
}
|
|
8092
|
+
/**
|
|
8093
|
+
* 处理错误
|
|
8094
|
+
*/
|
|
8095
|
+
handleError(error) {
|
|
8096
|
+
this.events?.onError?.(error);
|
|
8097
|
+
this.emit("error", error);
|
|
8098
|
+
}
|
|
8099
|
+
};
|
|
8100
|
+
|
|
8101
|
+
// src/services/streaming-service.ts
|
|
8102
|
+
var StreamingService = class extends EventEmitter4 {
|
|
8103
|
+
player = null;
|
|
8104
|
+
providerName;
|
|
8105
|
+
voice;
|
|
8106
|
+
speed;
|
|
8107
|
+
volume;
|
|
8108
|
+
pitch;
|
|
8109
|
+
backendType;
|
|
8110
|
+
_isActive = false;
|
|
8111
|
+
_bytesWritten = 0;
|
|
8112
|
+
constructor(options = {}) {
|
|
8113
|
+
super();
|
|
8114
|
+
this.providerName = options.provider || "minimax";
|
|
8115
|
+
this.voice = options.voice;
|
|
8116
|
+
this.speed = options.speed;
|
|
8117
|
+
this.volume = options.volume;
|
|
8118
|
+
this.pitch = options.pitch;
|
|
8119
|
+
this.backendType = options.backendType || "naudiodon" /* NAUDIODON */;
|
|
8120
|
+
}
|
|
8121
|
+
/**
|
|
8122
|
+
* 获取时间戳
|
|
8123
|
+
*/
|
|
8124
|
+
getTimestamp() {
|
|
8125
|
+
const now = /* @__PURE__ */ new Date();
|
|
8126
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8127
|
+
return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
|
|
8128
|
+
}
|
|
8129
|
+
/**
|
|
8130
|
+
* 初始化播放器
|
|
8131
|
+
*/
|
|
8132
|
+
initPlayer() {
|
|
8133
|
+
if (this.player) {
|
|
8134
|
+
this.player.stop();
|
|
8135
|
+
this.player = null;
|
|
8136
|
+
}
|
|
8137
|
+
const playerOptions = {
|
|
8138
|
+
format: "mp3",
|
|
8139
|
+
backendType: this.backendType,
|
|
8140
|
+
events: {
|
|
8141
|
+
onStart: () => {
|
|
8142
|
+
const timestamp = this.getTimestamp();
|
|
8143
|
+
logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u5F00\u59CB}`);
|
|
8144
|
+
this.emit("start");
|
|
8145
|
+
},
|
|
8146
|
+
onEnd: () => {
|
|
8147
|
+
const timestamp = this.getTimestamp();
|
|
8148
|
+
logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u7ED3\u675F}`);
|
|
8149
|
+
this._isActive = false;
|
|
8150
|
+
this.emit("end");
|
|
8151
|
+
},
|
|
8152
|
+
onError: (error) => {
|
|
8153
|
+
const timestamp = this.getTimestamp();
|
|
8154
|
+
logger.error(`[Ocosay][${timestamp}][ERROR][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u9519\u8BEF} - ${error.message}`);
|
|
8155
|
+
this._isActive = false;
|
|
8156
|
+
this.emit("error", error);
|
|
8157
|
+
},
|
|
8158
|
+
onProgress: (bytes) => {
|
|
8159
|
+
this._bytesWritten = bytes;
|
|
8160
|
+
this.emit("progress", bytes);
|
|
8161
|
+
},
|
|
8162
|
+
onPause: () => {
|
|
8163
|
+
const timestamp = this.getTimestamp();
|
|
8164
|
+
logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u6682\u505C}`);
|
|
8165
|
+
this.emit("pause");
|
|
8166
|
+
},
|
|
8167
|
+
onResume: () => {
|
|
8168
|
+
const timestamp = this.getTimestamp();
|
|
8169
|
+
logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u6062\u590D}`);
|
|
8170
|
+
this.emit("resume");
|
|
8171
|
+
},
|
|
8172
|
+
onStop: () => {
|
|
8173
|
+
const timestamp = this.getTimestamp();
|
|
8174
|
+
logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u505C\u6B62}`);
|
|
8175
|
+
this._isActive = false;
|
|
8176
|
+
this._bytesWritten = 0;
|
|
8177
|
+
this.emit("stop");
|
|
8178
|
+
}
|
|
8179
|
+
}
|
|
8180
|
+
};
|
|
8181
|
+
this.player = new StreamPlayer(playerOptions);
|
|
8182
|
+
return this.player;
|
|
8183
|
+
}
|
|
8184
|
+
/**
|
|
8185
|
+
* 流式播放文本
|
|
8186
|
+
* 边接收边播放(豆包模式)
|
|
8187
|
+
*/
|
|
8188
|
+
async stream(text) {
|
|
8189
|
+
if (!text || text.trim().length === 0) {
|
|
8190
|
+
const timestamp2 = this.getTimestamp();
|
|
8191
|
+
logger.warn(`[Ocosay][${timestamp2}][WARNING][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u7A7A\u6587\u672C\u8DF3\u8FC7}`);
|
|
8192
|
+
return;
|
|
8193
|
+
}
|
|
8194
|
+
const timestamp = this.getTimestamp();
|
|
8195
|
+
logger.info(`[Ocosay][${timestamp}][INFO][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u5F00\u59CB} - \u6587\u672C\u957F\u5EA6: ${text.length}`);
|
|
8196
|
+
try {
|
|
8197
|
+
const provider = getProvider(this.providerName);
|
|
8198
|
+
if (!provider) {
|
|
8199
|
+
throw new TTSError(
|
|
8200
|
+
`Provider ${this.providerName} not found`,
|
|
8201
|
+
"UNKNOWN" /* UNKNOWN */,
|
|
8202
|
+
this.providerName
|
|
8203
|
+
);
|
|
8204
|
+
}
|
|
8205
|
+
const player = this.initPlayer();
|
|
8206
|
+
player.start();
|
|
8207
|
+
this._isActive = true;
|
|
8208
|
+
this._bytesWritten = 0;
|
|
8209
|
+
const result = await provider.speak(text, {
|
|
8210
|
+
voice: this.voice,
|
|
8211
|
+
model: "stream",
|
|
8212
|
+
speed: this.speed,
|
|
8213
|
+
volume: this.volume,
|
|
8214
|
+
pitch: this.pitch
|
|
8215
|
+
});
|
|
8216
|
+
await this.processAudioResult(result, player);
|
|
8217
|
+
} catch (error) {
|
|
8218
|
+
const ts = this.getTimestamp();
|
|
8219
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
8220
|
+
logger.error(`[Ocosay][${ts}][ERROR][Streaming] \u5BF9\u5E94\u4E8B\u4EF6{\u6D41\u5F0F\u64AD\u653E\u9519\u8BEF} - ${errorMsg}`);
|
|
8221
|
+
this._isActive = false;
|
|
8222
|
+
throw error;
|
|
8223
|
+
}
|
|
8224
|
+
}
|
|
8225
|
+
/**
|
|
8226
|
+
* 处理音频结果
|
|
8227
|
+
*/
|
|
8228
|
+
async processAudioResult(result, player) {
|
|
8229
|
+
if (result.isStream && result.audioData instanceof ReadableStream) {
|
|
8230
|
+
await this.streamAudioChunks(result.audioData, player);
|
|
8231
|
+
} else if (Buffer.isBuffer(result.audioData)) {
|
|
8232
|
+
player.write(result.audioData);
|
|
8233
|
+
player.end();
|
|
8234
|
+
}
|
|
8235
|
+
}
|
|
8236
|
+
/**
|
|
8237
|
+
* 流式处理音频chunk
|
|
8238
|
+
*/
|
|
8239
|
+
async streamAudioChunks(stream2, player) {
|
|
8240
|
+
const reader = stream2.getReader();
|
|
8241
|
+
try {
|
|
8242
|
+
while (true) {
|
|
8243
|
+
const { done, value } = await reader.read();
|
|
8244
|
+
if (done) {
|
|
8245
|
+
break;
|
|
8246
|
+
}
|
|
8247
|
+
if (value) {
|
|
8248
|
+
const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
|
8249
|
+
player.write(chunk);
|
|
8250
|
+
}
|
|
8251
|
+
}
|
|
8252
|
+
} finally {
|
|
8253
|
+
reader.releaseLock();
|
|
8254
|
+
player.end();
|
|
8255
|
+
}
|
|
8256
|
+
}
|
|
8257
|
+
/**
|
|
8258
|
+
* 停止流式播放
|
|
8259
|
+
*/
|
|
8260
|
+
stop() {
|
|
8261
|
+
if (this.player) {
|
|
8262
|
+
this.player.stop();
|
|
8263
|
+
}
|
|
8264
|
+
this._isActive = false;
|
|
8265
|
+
this._bytesWritten = 0;
|
|
8266
|
+
}
|
|
8267
|
+
/**
|
|
8268
|
+
* 暂停流式播放
|
|
8269
|
+
*/
|
|
8270
|
+
pause() {
|
|
8271
|
+
if (this.player) {
|
|
8272
|
+
this.player.pause();
|
|
8273
|
+
}
|
|
8274
|
+
}
|
|
8275
|
+
/**
|
|
8276
|
+
* 恢复流式播放
|
|
8277
|
+
*/
|
|
8278
|
+
resume() {
|
|
8279
|
+
if (this.player) {
|
|
8280
|
+
this.player.resume();
|
|
8281
|
+
}
|
|
8282
|
+
}
|
|
8283
|
+
/**
|
|
8284
|
+
* 获取流式播放状态
|
|
7810
8285
|
*/
|
|
7811
|
-
|
|
7812
|
-
return
|
|
8286
|
+
getStatus() {
|
|
8287
|
+
return {
|
|
8288
|
+
isActive: this._isActive,
|
|
8289
|
+
bytesWritten: this._bytesWritten,
|
|
8290
|
+
state: this.player?.isStopped() ? "stopped" : this.player?.isPaused() ? "paused" : this._isActive ? "playing" : "idle"
|
|
8291
|
+
};
|
|
7813
8292
|
}
|
|
7814
8293
|
/**
|
|
7815
|
-
*
|
|
8294
|
+
* 是否处于活跃状态
|
|
7816
8295
|
*/
|
|
7817
|
-
|
|
7818
|
-
return this.
|
|
8296
|
+
isActive() {
|
|
8297
|
+
return this._isActive;
|
|
7819
8298
|
}
|
|
7820
8299
|
/**
|
|
7821
|
-
*
|
|
8300
|
+
* 销毁服务
|
|
7822
8301
|
*/
|
|
7823
|
-
|
|
7824
|
-
|
|
8302
|
+
async destroy() {
|
|
8303
|
+
if (this.player) {
|
|
8304
|
+
this.player.stop();
|
|
8305
|
+
this.player = null;
|
|
8306
|
+
}
|
|
8307
|
+
this._isActive = false;
|
|
8308
|
+
this._bytesWritten = 0;
|
|
7825
8309
|
}
|
|
7826
8310
|
};
|
|
7827
|
-
var
|
|
7828
|
-
function
|
|
7829
|
-
if (!
|
|
7830
|
-
|
|
8311
|
+
var defaultStreamingService;
|
|
8312
|
+
function getDefaultStreamingService() {
|
|
8313
|
+
if (!defaultStreamingService) {
|
|
8314
|
+
defaultStreamingService = new StreamingService();
|
|
7831
8315
|
}
|
|
7832
|
-
return
|
|
7833
|
-
}
|
|
7834
|
-
async function speak(text, options) {
|
|
7835
|
-
const speaker2 = getDefaultSpeaker();
|
|
7836
|
-
return speaker2.speak(text, options);
|
|
7837
|
-
}
|
|
7838
|
-
async function stop() {
|
|
7839
|
-
const speaker2 = getDefaultSpeaker();
|
|
7840
|
-
return speaker2.stop();
|
|
7841
|
-
}
|
|
7842
|
-
function pause() {
|
|
7843
|
-
const speaker2 = getDefaultSpeaker();
|
|
7844
|
-
speaker2.pause();
|
|
7845
|
-
}
|
|
7846
|
-
function resume() {
|
|
7847
|
-
const speaker2 = getDefaultSpeaker();
|
|
7848
|
-
speaker2.resume();
|
|
8316
|
+
return defaultStreamingService;
|
|
7849
8317
|
}
|
|
7850
|
-
async function
|
|
7851
|
-
const
|
|
7852
|
-
return
|
|
8318
|
+
async function stream(text, options) {
|
|
8319
|
+
const service = options ? new StreamingService(options) : getDefaultStreamingService();
|
|
8320
|
+
return service.stream(text);
|
|
7853
8321
|
}
|
|
7854
8322
|
|
|
7855
8323
|
// src/tools/tts.ts
|
|
@@ -7863,19 +8331,29 @@ function extractTextArg(args) {
|
|
|
7863
8331
|
return text.trim();
|
|
7864
8332
|
}
|
|
7865
8333
|
const text7 = argObj.text7;
|
|
7866
|
-
if (text7
|
|
8334
|
+
if (text7 != null) {
|
|
7867
8335
|
if (typeof text7 === "string" && text7.trim().length > 0) {
|
|
7868
8336
|
logger.warn("received text7 instead of text from OpenCode framework");
|
|
7869
8337
|
return text7.trim();
|
|
7870
8338
|
}
|
|
7871
|
-
if (typeof text7 === "object"
|
|
7872
|
-
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
8339
|
+
if (typeof text7 === "object") {
|
|
8340
|
+
if ("split" in text7 && "content" in text7) {
|
|
8341
|
+
const content = text7.content;
|
|
8342
|
+
if (typeof content === "string" && content.trim().length > 0) {
|
|
8343
|
+
logger.info("text7 split format detected");
|
|
8344
|
+
return content.trim();
|
|
8345
|
+
}
|
|
8346
|
+
}
|
|
8347
|
+
if ("content" in text7) {
|
|
8348
|
+
const content = text7.content;
|
|
8349
|
+
if (typeof content === "string" && content.trim().length > 0) {
|
|
8350
|
+
logger.info("text7 content format detected");
|
|
8351
|
+
return content.trim();
|
|
8352
|
+
}
|
|
7876
8353
|
}
|
|
7877
8354
|
}
|
|
7878
8355
|
logger.warn({ type: typeof text7 }, "text7 is not a valid string or object with content");
|
|
8356
|
+
return void 0;
|
|
7879
8357
|
}
|
|
7880
8358
|
for (const key of Object.keys(argObj)) {
|
|
7881
8359
|
if (key.startsWith("text") && key !== "text" && key !== "text7") {
|
|
@@ -7898,29 +8376,29 @@ async function handleToolCall(toolName, args) {
|
|
|
7898
8376
|
if (!text) {
|
|
7899
8377
|
return { success: false, error: "No valid text found in args" };
|
|
7900
8378
|
}
|
|
7901
|
-
await
|
|
8379
|
+
await speak2(text);
|
|
7902
8380
|
return { success: true, message: "Speech completed" };
|
|
7903
8381
|
}
|
|
7904
8382
|
case "tts_stop":
|
|
7905
|
-
await
|
|
8383
|
+
await stop2();
|
|
7906
8384
|
return { success: true, message: "Stopped" };
|
|
7907
8385
|
case "tts_pause":
|
|
7908
|
-
|
|
8386
|
+
pause2();
|
|
7909
8387
|
return { success: true, message: "Paused" };
|
|
7910
8388
|
case "tts_resume":
|
|
7911
|
-
|
|
8389
|
+
resume2();
|
|
7912
8390
|
return { success: true, message: "Resumed" };
|
|
7913
8391
|
case "tts_list_voices": {
|
|
7914
|
-
const voices = await
|
|
8392
|
+
const voices = await listVoices2(args?.provider);
|
|
7915
8393
|
return { success: true, voices };
|
|
7916
8394
|
}
|
|
7917
8395
|
case "tts_list_providers": {
|
|
7918
|
-
const speaker2 =
|
|
8396
|
+
const speaker2 = getDefaultSpeakerService();
|
|
7919
8397
|
const providers2 = speaker2.getProviders();
|
|
7920
8398
|
return { success: true, providers: providers2 };
|
|
7921
8399
|
}
|
|
7922
8400
|
case "tts_status": {
|
|
7923
|
-
const s =
|
|
8401
|
+
const s = getDefaultSpeakerService();
|
|
7924
8402
|
return {
|
|
7925
8403
|
success: true,
|
|
7926
8404
|
isPlaying: s.isPlaying(),
|
|
@@ -7942,14 +8420,14 @@ async function handleToolCall(toolName, args) {
|
|
|
7942
8420
|
"tts_stream"
|
|
7943
8421
|
);
|
|
7944
8422
|
}
|
|
7945
|
-
const
|
|
7946
|
-
|
|
7947
|
-
if (streamReader2 && synthesizer) {
|
|
7948
|
-
streamReader2.start();
|
|
8423
|
+
const streamingService = getDefaultStreamingService();
|
|
8424
|
+
if (streamingService) {
|
|
7949
8425
|
const textArg = extractTextArg(args);
|
|
7950
8426
|
if (textArg && typeof textArg === "string" && textArg.trim().length > 0) {
|
|
7951
8427
|
logger.info({ text: textArg.substring(0, 50) + "..." }, "synthesizing text");
|
|
7952
|
-
|
|
8428
|
+
stream(textArg).catch((error) => {
|
|
8429
|
+
logger.error({ error }, "stream failed");
|
|
8430
|
+
});
|
|
7953
8431
|
}
|
|
7954
8432
|
return { success: true, message: "Stream speak started" };
|
|
7955
8433
|
}
|
|
@@ -7967,13 +8445,13 @@ async function handleToolCall(toolName, args) {
|
|
|
7967
8445
|
"tts_stream"
|
|
7968
8446
|
);
|
|
7969
8447
|
}
|
|
7970
|
-
const
|
|
7971
|
-
if (
|
|
7972
|
-
|
|
8448
|
+
const streamingService = getDefaultStreamingService();
|
|
8449
|
+
if (streamingService) {
|
|
8450
|
+
streamingService.stop();
|
|
7973
8451
|
return { success: true, message: "Stream stopped" };
|
|
7974
8452
|
}
|
|
7975
8453
|
throw new TTSError(
|
|
7976
|
-
"Stream
|
|
8454
|
+
"Stream service not available",
|
|
7977
8455
|
"UNKNOWN" /* UNKNOWN */,
|
|
7978
8456
|
"tts_stream"
|
|
7979
8457
|
);
|
|
@@ -8101,34 +8579,39 @@ var MiniMaxProvider = class extends BaseTTSProvider {
|
|
|
8101
8579
|
},
|
|
8102
8580
|
responseType: "stream"
|
|
8103
8581
|
});
|
|
8104
|
-
const
|
|
8582
|
+
const stream2 = response.data;
|
|
8105
8583
|
const audioChunks = [];
|
|
8584
|
+
let lineBuffer = "";
|
|
8106
8585
|
return new Promise((resolve, reject) => {
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8586
|
+
stream2.on("data", (chunk) => {
|
|
8587
|
+
lineBuffer += chunk.toString();
|
|
8588
|
+
while (true) {
|
|
8589
|
+
const lineEnd = lineBuffer.indexOf("\n");
|
|
8590
|
+
if (lineEnd === -1) break;
|
|
8591
|
+
const line = lineBuffer.slice(0, lineEnd).trim();
|
|
8592
|
+
lineBuffer = lineBuffer.slice(lineEnd + 1);
|
|
8593
|
+
if (!line || !line.startsWith("data:")) continue;
|
|
8594
|
+
const jsonStr = line.slice(5).trim();
|
|
8595
|
+
if (!jsonStr) continue;
|
|
8596
|
+
try {
|
|
8597
|
+
const data = JSON.parse(jsonStr);
|
|
8598
|
+
if (data.audio) {
|
|
8599
|
+
audioChunks.push(Buffer.from(data.audio, "hex"));
|
|
8600
|
+
}
|
|
8601
|
+
if (data.is_final === true) {
|
|
8602
|
+
const fullAudio = Buffer.concat(audioChunks);
|
|
8603
|
+
resolve({
|
|
8604
|
+
audioData: fullAudio,
|
|
8605
|
+
format: this.audioFormat,
|
|
8606
|
+
isStream: true,
|
|
8607
|
+
duration: this.estimateDuration(fullAudio.length)
|
|
8608
|
+
});
|
|
8125
8609
|
}
|
|
8610
|
+
} catch (e) {
|
|
8126
8611
|
}
|
|
8127
|
-
} catch (e) {
|
|
8128
|
-
audioChunks.push(chunk);
|
|
8129
8612
|
}
|
|
8130
8613
|
});
|
|
8131
|
-
|
|
8614
|
+
stream2.on("error", (err) => {
|
|
8132
8615
|
reject(new TTSError(
|
|
8133
8616
|
"Stream error",
|
|
8134
8617
|
"NETWORK" /* NETWORK */,
|
|
@@ -8136,7 +8619,19 @@ var MiniMaxProvider = class extends BaseTTSProvider {
|
|
|
8136
8619
|
err
|
|
8137
8620
|
));
|
|
8138
8621
|
});
|
|
8139
|
-
|
|
8622
|
+
stream2.on("end", () => {
|
|
8623
|
+
if (lineBuffer.trim() && lineBuffer.startsWith("data:")) {
|
|
8624
|
+
const jsonStr = lineBuffer.slice(5).trim();
|
|
8625
|
+
if (jsonStr) {
|
|
8626
|
+
try {
|
|
8627
|
+
const data = JSON.parse(jsonStr);
|
|
8628
|
+
if (data.audio) {
|
|
8629
|
+
audioChunks.push(Buffer.from(data.audio, "hex"));
|
|
8630
|
+
}
|
|
8631
|
+
} catch (e) {
|
|
8632
|
+
}
|
|
8633
|
+
}
|
|
8634
|
+
}
|
|
8140
8635
|
if (audioChunks.length > 0) {
|
|
8141
8636
|
const fullAudio = Buffer.concat(audioChunks);
|
|
8142
8637
|
resolve({
|
|
@@ -8426,8 +8921,8 @@ var MINIMAX_VOICES = [
|
|
|
8426
8921
|
];
|
|
8427
8922
|
|
|
8428
8923
|
// src/core/stream-reader.ts
|
|
8429
|
-
import { EventEmitter as
|
|
8430
|
-
var StreamReader = class extends
|
|
8924
|
+
import { EventEmitter as EventEmitter5 } from "events";
|
|
8925
|
+
var StreamReader = class extends EventEmitter5 {
|
|
8431
8926
|
constructor(bufferSize = 30, bufferTimeout = 2e3) {
|
|
8432
8927
|
super();
|
|
8433
8928
|
this.bufferSize = bufferSize;
|
|
@@ -8591,8 +9086,8 @@ var StreamReader = class extends EventEmitter3 {
|
|
|
8591
9086
|
};
|
|
8592
9087
|
|
|
8593
9088
|
// src/core/streaming-synthesizer.ts
|
|
8594
|
-
import { EventEmitter as
|
|
8595
|
-
var StreamingSynthesizer = class extends
|
|
9089
|
+
import { EventEmitter as EventEmitter6 } from "events";
|
|
9090
|
+
var StreamingSynthesizer = class extends EventEmitter6 {
|
|
8596
9091
|
constructor(options) {
|
|
8597
9092
|
super();
|
|
8598
9093
|
this.options = options;
|
|
@@ -8618,6 +9113,7 @@ var StreamingSynthesizer = class extends EventEmitter4 {
|
|
|
8618
9113
|
await this.processAudioResult(result);
|
|
8619
9114
|
this.emit("done");
|
|
8620
9115
|
} catch (error) {
|
|
9116
|
+
logger.error({ error }, "synthesize failed");
|
|
8621
9117
|
const ttsError = error instanceof TTSError ? error : new TTSError(
|
|
8622
9118
|
error instanceof Error ? error.message : "Synthesis failed",
|
|
8623
9119
|
"UNKNOWN",
|
|
@@ -8640,8 +9136,8 @@ var StreamingSynthesizer = class extends EventEmitter4 {
|
|
|
8640
9136
|
/**
|
|
8641
9137
|
* 处理 ReadableStream,逐chunk emit
|
|
8642
9138
|
*/
|
|
8643
|
-
async processReadableStream(
|
|
8644
|
-
const reader =
|
|
9139
|
+
async processReadableStream(stream2) {
|
|
9140
|
+
const reader = stream2.getReader();
|
|
8645
9141
|
try {
|
|
8646
9142
|
while (true) {
|
|
8647
9143
|
const { done, value } = await reader.read();
|
|
@@ -8680,171 +9176,6 @@ var StreamingSynthesizer = class extends EventEmitter4 {
|
|
|
8680
9176
|
}
|
|
8681
9177
|
};
|
|
8682
9178
|
|
|
8683
|
-
// src/core/stream-player.ts
|
|
8684
|
-
import { EventEmitter as EventEmitter5 } from "events";
|
|
8685
|
-
var StreamPlayer = class extends EventEmitter5 {
|
|
8686
|
-
backend = null;
|
|
8687
|
-
_bytesWritten = 0;
|
|
8688
|
-
_started = false;
|
|
8689
|
-
_paused = false;
|
|
8690
|
-
_stopped = false;
|
|
8691
|
-
format = "mp3";
|
|
8692
|
-
events;
|
|
8693
|
-
constructor(options = {}) {
|
|
8694
|
-
super();
|
|
8695
|
-
this.format = options.format || "mp3";
|
|
8696
|
-
this.events = options.events;
|
|
8697
|
-
const backendType = options.backendType || "naudiodon" /* NAUDIODON */;
|
|
8698
|
-
this.backend = createBackend(backendType, {
|
|
8699
|
-
format: this.format,
|
|
8700
|
-
events: {
|
|
8701
|
-
onStart: () => {
|
|
8702
|
-
this.events?.onStart?.();
|
|
8703
|
-
this.emit("start");
|
|
8704
|
-
},
|
|
8705
|
-
onEnd: () => {
|
|
8706
|
-
this.events?.onEnd?.();
|
|
8707
|
-
this.emit("end");
|
|
8708
|
-
},
|
|
8709
|
-
onError: (error) => {
|
|
8710
|
-
this.handleError(error);
|
|
8711
|
-
},
|
|
8712
|
-
onPause: () => {
|
|
8713
|
-
this._paused = true;
|
|
8714
|
-
this.events?.onPause?.();
|
|
8715
|
-
this.emit("pause");
|
|
8716
|
-
},
|
|
8717
|
-
onResume: () => {
|
|
8718
|
-
this._paused = false;
|
|
8719
|
-
this.events?.onResume?.();
|
|
8720
|
-
this.emit("resume");
|
|
8721
|
-
},
|
|
8722
|
-
onStop: () => {
|
|
8723
|
-
this.events?.onStop?.();
|
|
8724
|
-
this.emit("stop");
|
|
8725
|
-
},
|
|
8726
|
-
onProgress: (bytes) => {
|
|
8727
|
-
this.events?.onProgress?.(bytes);
|
|
8728
|
-
this.emit("progress", bytes);
|
|
8729
|
-
}
|
|
8730
|
-
}
|
|
8731
|
-
});
|
|
8732
|
-
}
|
|
8733
|
-
/**
|
|
8734
|
-
* 开始播放
|
|
8735
|
-
* 初始化后端,准备接收音频数据
|
|
8736
|
-
*/
|
|
8737
|
-
start() {
|
|
8738
|
-
if (this._started) {
|
|
8739
|
-
return;
|
|
8740
|
-
}
|
|
8741
|
-
if (!this.backend) {
|
|
8742
|
-
this.handleError(new Error("Audio backend not initialized"));
|
|
8743
|
-
return;
|
|
8744
|
-
}
|
|
8745
|
-
this.backend.start("");
|
|
8746
|
-
this._started = true;
|
|
8747
|
-
this._stopped = false;
|
|
8748
|
-
this._paused = false;
|
|
8749
|
-
this._bytesWritten = 0;
|
|
8750
|
-
}
|
|
8751
|
-
/**
|
|
8752
|
-
* 写入音频数据块(边收边播)
|
|
8753
|
-
* 如果尚未 start(),会自动调用
|
|
8754
|
-
*/
|
|
8755
|
-
write(chunk) {
|
|
8756
|
-
if (this._stopped) {
|
|
8757
|
-
return;
|
|
8758
|
-
}
|
|
8759
|
-
if (!this._started) {
|
|
8760
|
-
this.start();
|
|
8761
|
-
}
|
|
8762
|
-
if (this.backend) {
|
|
8763
|
-
this.backend.write(chunk);
|
|
8764
|
-
this._bytesWritten += chunk.length;
|
|
8765
|
-
this.events?.onProgress?.(this._bytesWritten);
|
|
8766
|
-
this.emit("progress", this._bytesWritten);
|
|
8767
|
-
}
|
|
8768
|
-
}
|
|
8769
|
-
/**
|
|
8770
|
-
* 结束写入
|
|
8771
|
-
* 通知后端写入完成,但保持播放直到结束
|
|
8772
|
-
*/
|
|
8773
|
-
end() {
|
|
8774
|
-
if (this.backend) {
|
|
8775
|
-
this.backend.end();
|
|
8776
|
-
}
|
|
8777
|
-
}
|
|
8778
|
-
/**
|
|
8779
|
-
* 停止播放
|
|
8780
|
-
* 立即停止播放并释放资源
|
|
8781
|
-
*/
|
|
8782
|
-
stop() {
|
|
8783
|
-
this._stopped = true;
|
|
8784
|
-
this._started = false;
|
|
8785
|
-
this._paused = false;
|
|
8786
|
-
if (this.backend) {
|
|
8787
|
-
this.backend.stop();
|
|
8788
|
-
}
|
|
8789
|
-
this._bytesWritten = 0;
|
|
8790
|
-
this.events?.onStop?.();
|
|
8791
|
-
this.emit("stop");
|
|
8792
|
-
}
|
|
8793
|
-
/**
|
|
8794
|
-
* 暂停播放
|
|
8795
|
-
*/
|
|
8796
|
-
pause() {
|
|
8797
|
-
if (!this._started || this._paused || this._stopped) {
|
|
8798
|
-
return;
|
|
8799
|
-
}
|
|
8800
|
-
if (this.backend) {
|
|
8801
|
-
this.backend.pause();
|
|
8802
|
-
}
|
|
8803
|
-
}
|
|
8804
|
-
/**
|
|
8805
|
-
* 恢复播放
|
|
8806
|
-
*/
|
|
8807
|
-
resume() {
|
|
8808
|
-
if (!this._paused || this._stopped) {
|
|
8809
|
-
return;
|
|
8810
|
-
}
|
|
8811
|
-
if (this.backend) {
|
|
8812
|
-
this.backend.resume();
|
|
8813
|
-
}
|
|
8814
|
-
}
|
|
8815
|
-
/**
|
|
8816
|
-
* 是否已启动
|
|
8817
|
-
*/
|
|
8818
|
-
isStarted() {
|
|
8819
|
-
return this._started;
|
|
8820
|
-
}
|
|
8821
|
-
/**
|
|
8822
|
-
* 是否暂停
|
|
8823
|
-
*/
|
|
8824
|
-
isPaused() {
|
|
8825
|
-
return this._paused;
|
|
8826
|
-
}
|
|
8827
|
-
/**
|
|
8828
|
-
* 是否已停止
|
|
8829
|
-
*/
|
|
8830
|
-
isStopped() {
|
|
8831
|
-
return this._stopped;
|
|
8832
|
-
}
|
|
8833
|
-
/**
|
|
8834
|
-
* 获取已写入的字节数
|
|
8835
|
-
*/
|
|
8836
|
-
getBytesWritten() {
|
|
8837
|
-
return this._bytesWritten;
|
|
8838
|
-
}
|
|
8839
|
-
/**
|
|
8840
|
-
* 处理错误
|
|
8841
|
-
*/
|
|
8842
|
-
handleError(error) {
|
|
8843
|
-
this.events?.onError?.(error);
|
|
8844
|
-
this.emit("error", error);
|
|
8845
|
-
}
|
|
8846
|
-
};
|
|
8847
|
-
|
|
8848
9179
|
// src/index.ts
|
|
8849
9180
|
var speaker;
|
|
8850
9181
|
var streamReader;
|
|
@@ -8978,15 +9309,6 @@ function getStreamStatus() {
|
|
|
8978
9309
|
state: streamReader.getState()
|
|
8979
9310
|
};
|
|
8980
9311
|
}
|
|
8981
|
-
function getStreamReader() {
|
|
8982
|
-
return streamReader;
|
|
8983
|
-
}
|
|
8984
|
-
function getStreamingSynthesizer() {
|
|
8985
|
-
return streamingSynthesizer;
|
|
8986
|
-
}
|
|
8987
|
-
function getStreamPlayer() {
|
|
8988
|
-
return streamPlayer;
|
|
8989
|
-
}
|
|
8990
9312
|
|
|
8991
9313
|
// src/config.ts
|
|
8992
9314
|
import * as fs2 from "fs";
|
|
@@ -9090,6 +9412,7 @@ function loadOrCreateConfig() {
|
|
|
9090
9412
|
try {
|
|
9091
9413
|
fs2.mkdirSync(configDir, { recursive: true });
|
|
9092
9414
|
} catch (err) {
|
|
9415
|
+
logger.error({ err }, "failed to create config directory");
|
|
9093
9416
|
throw new Error(`[ocosay] \u65E0\u6CD5\u521B\u5EFA\u914D\u7F6E\u76EE\u5F55 ${configDir}: ${err}`);
|
|
9094
9417
|
}
|
|
9095
9418
|
}
|
|
@@ -9105,6 +9428,7 @@ function loadOrCreateConfig() {
|
|
|
9105
9428
|
logger.warn({ err }, "failed to set config file permissions");
|
|
9106
9429
|
}
|
|
9107
9430
|
} catch (err) {
|
|
9431
|
+
logger.error({ err }, "failed to write config file");
|
|
9108
9432
|
throw new Error(`[ocosay] cannot write config file ${CONFIG_PATH}: ${err}`);
|
|
9109
9433
|
}
|
|
9110
9434
|
logger.info({ path: CONFIG_PATH }, "config file created");
|
|
@@ -9135,6 +9459,87 @@ function loadOrCreateConfig() {
|
|
|
9135
9459
|
}
|
|
9136
9460
|
}
|
|
9137
9461
|
|
|
9462
|
+
// src/services/notification-service.ts
|
|
9463
|
+
var instance;
|
|
9464
|
+
var tui = null;
|
|
9465
|
+
var initialized2 = false;
|
|
9466
|
+
var NotificationService = class _NotificationService {
|
|
9467
|
+
constructor() {
|
|
9468
|
+
}
|
|
9469
|
+
static getInstance() {
|
|
9470
|
+
if (!instance) {
|
|
9471
|
+
instance = new _NotificationService();
|
|
9472
|
+
}
|
|
9473
|
+
return instance;
|
|
9474
|
+
}
|
|
9475
|
+
initialize(tuiInstance) {
|
|
9476
|
+
if (initialized2) return;
|
|
9477
|
+
tui = tuiInstance;
|
|
9478
|
+
initialized2 = true;
|
|
9479
|
+
logger.debug("NotificationService initialized");
|
|
9480
|
+
}
|
|
9481
|
+
isReady() {
|
|
9482
|
+
return initialized2 && tui !== null;
|
|
9483
|
+
}
|
|
9484
|
+
showToast(message, type = "info") {
|
|
9485
|
+
const title = this.getTitleForType(type);
|
|
9486
|
+
if (tui?.showToast) {
|
|
9487
|
+
try {
|
|
9488
|
+
tui.showToast({
|
|
9489
|
+
title,
|
|
9490
|
+
message,
|
|
9491
|
+
variant: type,
|
|
9492
|
+
duration: type === "error" ? 8e3 : 5e3
|
|
9493
|
+
});
|
|
9494
|
+
return;
|
|
9495
|
+
} catch (err) {
|
|
9496
|
+
logger.warn({ err }, "tui.showToast failed");
|
|
9497
|
+
}
|
|
9498
|
+
}
|
|
9499
|
+
this.fallbackLog(type, title, message);
|
|
9500
|
+
}
|
|
9501
|
+
success(message) {
|
|
9502
|
+
this.showToast(message, "success");
|
|
9503
|
+
}
|
|
9504
|
+
error(message) {
|
|
9505
|
+
this.showToast(message, "error");
|
|
9506
|
+
}
|
|
9507
|
+
warning(message) {
|
|
9508
|
+
this.showToast(message, "warning");
|
|
9509
|
+
}
|
|
9510
|
+
info(message) {
|
|
9511
|
+
this.showToast(message, "info");
|
|
9512
|
+
}
|
|
9513
|
+
getTitleForType(type) {
|
|
9514
|
+
const titles = {
|
|
9515
|
+
success: "Success",
|
|
9516
|
+
error: "Error",
|
|
9517
|
+
warning: "Warning",
|
|
9518
|
+
info: "Info"
|
|
9519
|
+
};
|
|
9520
|
+
return titles[type];
|
|
9521
|
+
}
|
|
9522
|
+
fallbackLog(type, title, message) {
|
|
9523
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
9524
|
+
switch (type) {
|
|
9525
|
+
case "error":
|
|
9526
|
+
logger.error({ title, message, timestamp }, "Toast (fallback)");
|
|
9527
|
+
break;
|
|
9528
|
+
case "warning":
|
|
9529
|
+
logger.warn({ title, message, timestamp }, "Toast (fallback)");
|
|
9530
|
+
break;
|
|
9531
|
+
default:
|
|
9532
|
+
logger.info({ title, message, timestamp }, "Toast (fallback)");
|
|
9533
|
+
}
|
|
9534
|
+
}
|
|
9535
|
+
};
|
|
9536
|
+
function showToast(message, type = "info") {
|
|
9537
|
+
NotificationService.getInstance().showToast(message, type);
|
|
9538
|
+
}
|
|
9539
|
+
function initializeNotificationService(tuiInstance) {
|
|
9540
|
+
NotificationService.getInstance().initialize(tuiInstance);
|
|
9541
|
+
}
|
|
9542
|
+
|
|
9138
9543
|
// src/plugin.ts
|
|
9139
9544
|
import { readFileSync as readFileSync2 } from "fs";
|
|
9140
9545
|
import { fileURLToPath } from "url";
|
|
@@ -9282,24 +9687,12 @@ var server = (async (input, _options) => {
|
|
|
9282
9687
|
}
|
|
9283
9688
|
const opencodeTui = input.client?.tui;
|
|
9284
9689
|
global.__opencode_tui__ = opencodeTui;
|
|
9690
|
+
initializeNotificationService(opencodeTui);
|
|
9285
9691
|
setTimeout(async () => {
|
|
9286
|
-
if (!opencodeTui?.showToast) return;
|
|
9287
9692
|
if (initError) {
|
|
9288
|
-
|
|
9289
|
-
body: {
|
|
9290
|
-
title: `Ocosay v${pluginVersion} Initialization Failed`,
|
|
9291
|
-
message: "Initialization failed, please check config",
|
|
9292
|
-
variant: "error"
|
|
9293
|
-
}
|
|
9294
|
-
});
|
|
9693
|
+
showToast(`Ocosay v${pluginVersion} Initialization Failed: please check config`, "error");
|
|
9295
9694
|
} else {
|
|
9296
|
-
|
|
9297
|
-
body: {
|
|
9298
|
-
title: `Ocosay v${pluginVersion} Plugin Loaded`,
|
|
9299
|
-
message: `Auto-read: ${config.autoRead ? "ON" : "OFF"}`,
|
|
9300
|
-
variant: "success"
|
|
9301
|
-
}
|
|
9302
|
-
});
|
|
9695
|
+
showToast(`Ocosay v${pluginVersion} Plugin Loaded (Auto-read: ${config.autoRead ? "ON" : "OFF"})`, "success");
|
|
9303
9696
|
}
|
|
9304
9697
|
}, 7e3);
|
|
9305
9698
|
return {
|
|
@@ -9334,15 +9727,7 @@ var server = (async (input, _options) => {
|
|
|
9334
9727
|
});
|
|
9335
9728
|
initError = null;
|
|
9336
9729
|
} catch (err) {
|
|
9337
|
-
|
|
9338
|
-
await opencodeTui.showToast({
|
|
9339
|
-
body: {
|
|
9340
|
-
title: `Ocosay v${pluginVersion} Initialization Failed`,
|
|
9341
|
-
message: "Initialization failed, please check config",
|
|
9342
|
-
variant: "error"
|
|
9343
|
-
}
|
|
9344
|
-
});
|
|
9345
|
-
}
|
|
9730
|
+
showToast(`Ocosay v${pluginVersion} Initialization Failed: please check config`, "error");
|
|
9346
9731
|
}
|
|
9347
9732
|
}
|
|
9348
9733
|
}
|