@perkos/perkos-a2a 0.12.59 → 0.12.61
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/README.md +6 -0
- package/dist/bridge-agent.js +8 -0
- package/dist/bridge-agent.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +146 -274
- package/dist/index.js.map +4 -4
- package/dist/voice-capability.d.ts +19 -0
- package/dist/voice-capability.d.ts.map +1 -0
- package/dist/voice-capability.js +78 -0
- package/dist/voice-capability.js.map +1 -0
- package/dist/voice-capability.test.d.ts +2 -0
- package/dist/voice-capability.test.d.ts.map +1 -0
- package/dist/voice-capability.test.js +32 -0
- package/dist/voice-capability.test.js.map +1 -0
- package/docs/plans/2026-09-01-optional-voice-package-resolution-design.md +24 -0
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -14235,12 +14235,15 @@ var require_json = __commonJS({
|
|
|
14235
14235
|
var JSON_SYNTAX_REGEXP = /#+/g;
|
|
14236
14236
|
function json(options) {
|
|
14237
14237
|
var opts = options || {};
|
|
14238
|
-
var limit = typeof opts.limit
|
|
14238
|
+
var limit = typeof opts.limit === "undefined" || opts.limit === null ? 102400 : bytes.parse(opts.limit);
|
|
14239
14239
|
var inflate = opts.inflate !== false;
|
|
14240
14240
|
var reviver = opts.reviver;
|
|
14241
14241
|
var strict = opts.strict !== false;
|
|
14242
14242
|
var type = opts.type || "application/json";
|
|
14243
14243
|
var verify = opts.verify || false;
|
|
14244
|
+
if (limit === null) {
|
|
14245
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid');
|
|
14246
|
+
}
|
|
14244
14247
|
if (verify !== false && typeof verify !== "function") {
|
|
14245
14248
|
throw new TypeError("option verify must be function");
|
|
14246
14249
|
}
|
|
@@ -14362,9 +14365,12 @@ var require_raw = __commonJS({
|
|
|
14362
14365
|
function raw(options) {
|
|
14363
14366
|
var opts = options || {};
|
|
14364
14367
|
var inflate = opts.inflate !== false;
|
|
14365
|
-
var limit = typeof opts.limit
|
|
14368
|
+
var limit = typeof opts.limit === "undefined" || opts.limit === null ? 102400 : bytes.parse(opts.limit);
|
|
14366
14369
|
var type = opts.type || "application/octet-stream";
|
|
14367
14370
|
var verify = opts.verify || false;
|
|
14371
|
+
if (limit === null) {
|
|
14372
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid');
|
|
14373
|
+
}
|
|
14368
14374
|
if (verify !== false && typeof verify !== "function") {
|
|
14369
14375
|
throw new TypeError("option verify must be function");
|
|
14370
14376
|
}
|
|
@@ -14420,9 +14426,12 @@ var require_text = __commonJS({
|
|
|
14420
14426
|
var opts = options || {};
|
|
14421
14427
|
var defaultCharset = opts.defaultCharset || "utf-8";
|
|
14422
14428
|
var inflate = opts.inflate !== false;
|
|
14423
|
-
var limit = typeof opts.limit
|
|
14429
|
+
var limit = typeof opts.limit === "undefined" || opts.limit === null ? 102400 : bytes.parse(opts.limit);
|
|
14424
14430
|
var type = opts.type || "text/plain";
|
|
14425
14431
|
var verify = opts.verify || false;
|
|
14432
|
+
if (limit === null) {
|
|
14433
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid');
|
|
14434
|
+
}
|
|
14426
14435
|
if (verify !== false && typeof verify !== "function") {
|
|
14427
14436
|
throw new TypeError("option verify must be function");
|
|
14428
14437
|
}
|
|
@@ -17028,9 +17037,12 @@ var require_urlencoded = __commonJS({
|
|
|
17028
17037
|
}
|
|
17029
17038
|
var extended = opts.extended !== false;
|
|
17030
17039
|
var inflate = opts.inflate !== false;
|
|
17031
|
-
var limit = typeof opts.limit
|
|
17040
|
+
var limit = typeof opts.limit === "undefined" || opts.limit === null ? 102400 : bytes.parse(opts.limit);
|
|
17032
17041
|
var type = opts.type || "application/x-www-form-urlencoded";
|
|
17033
17042
|
var verify = opts.verify || false;
|
|
17043
|
+
if (limit === null) {
|
|
17044
|
+
throw new TypeError('option limit "' + String(opts.limit) + '" is invalid');
|
|
17045
|
+
}
|
|
17034
17046
|
if (verify !== false && typeof verify !== "function") {
|
|
17035
17047
|
throw new TypeError("option verify must be function");
|
|
17036
17048
|
}
|
|
@@ -22632,218 +22644,6 @@ var require_constants = __commonJS({
|
|
|
22632
22644
|
}
|
|
22633
22645
|
});
|
|
22634
22646
|
|
|
22635
|
-
// ../../../../node_modules/node-gyp-build/node-gyp-build.js
|
|
22636
|
-
var require_node_gyp_build = __commonJS({
|
|
22637
|
-
"../../../../node_modules/node-gyp-build/node-gyp-build.js"(exports, module) {
|
|
22638
|
-
var fs = __require("fs");
|
|
22639
|
-
var path = __require("path");
|
|
22640
|
-
var os = __require("os");
|
|
22641
|
-
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
22642
|
-
var vars = process.config && process.config.variables || {};
|
|
22643
|
-
var prebuildsOnly = !!process.env.PREBUILDS_ONLY;
|
|
22644
|
-
var abi = process.versions.modules;
|
|
22645
|
-
var runtime = isElectron() ? "electron" : isNwjs() ? "node-webkit" : "node";
|
|
22646
|
-
var arch = process.env.npm_config_arch || os.arch();
|
|
22647
|
-
var platform = process.env.npm_config_platform || os.platform();
|
|
22648
|
-
var libc = process.env.LIBC || (isAlpine(platform) ? "musl" : "glibc");
|
|
22649
|
-
var armv = process.env.ARM_VERSION || (arch === "arm64" ? "8" : vars.arm_version) || "";
|
|
22650
|
-
var uv = (process.versions.uv || "").split(".")[0];
|
|
22651
|
-
module.exports = load;
|
|
22652
|
-
function load(dir) {
|
|
22653
|
-
return runtimeRequire(load.resolve(dir));
|
|
22654
|
-
}
|
|
22655
|
-
load.resolve = load.path = function(dir) {
|
|
22656
|
-
dir = path.resolve(dir || ".");
|
|
22657
|
-
try {
|
|
22658
|
-
var name = runtimeRequire(path.join(dir, "package.json")).name.toUpperCase().replace(/-/g, "_");
|
|
22659
|
-
if (process.env[name + "_PREBUILD"]) dir = process.env[name + "_PREBUILD"];
|
|
22660
|
-
} catch (err) {
|
|
22661
|
-
}
|
|
22662
|
-
if (!prebuildsOnly) {
|
|
22663
|
-
var release = getFirst(path.join(dir, "build/Release"), matchBuild);
|
|
22664
|
-
if (release) return release;
|
|
22665
|
-
var debug = getFirst(path.join(dir, "build/Debug"), matchBuild);
|
|
22666
|
-
if (debug) return debug;
|
|
22667
|
-
}
|
|
22668
|
-
var prebuild = resolve4(dir);
|
|
22669
|
-
if (prebuild) return prebuild;
|
|
22670
|
-
var nearby = resolve4(path.dirname(process.execPath));
|
|
22671
|
-
if (nearby) return nearby;
|
|
22672
|
-
var target = [
|
|
22673
|
-
"platform=" + platform,
|
|
22674
|
-
"arch=" + arch,
|
|
22675
|
-
"runtime=" + runtime,
|
|
22676
|
-
"abi=" + abi,
|
|
22677
|
-
"uv=" + uv,
|
|
22678
|
-
armv ? "armv=" + armv : "",
|
|
22679
|
-
"libc=" + libc,
|
|
22680
|
-
"node=" + process.versions.node,
|
|
22681
|
-
process.versions.electron ? "electron=" + process.versions.electron : "",
|
|
22682
|
-
typeof __webpack_require__ === "function" ? "webpack=true" : ""
|
|
22683
|
-
// eslint-disable-line
|
|
22684
|
-
].filter(Boolean).join(" ");
|
|
22685
|
-
throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
|
|
22686
|
-
function resolve4(dir2) {
|
|
22687
|
-
var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple);
|
|
22688
|
-
var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
|
|
22689
|
-
if (!tuple) return;
|
|
22690
|
-
var prebuilds = path.join(dir2, "prebuilds", tuple.name);
|
|
22691
|
-
var parsed = readdirSync(prebuilds).map(parseTags);
|
|
22692
|
-
var candidates = parsed.filter(matchTags(runtime, abi));
|
|
22693
|
-
var winner = candidates.sort(compareTags(runtime))[0];
|
|
22694
|
-
if (winner) return path.join(prebuilds, winner.file);
|
|
22695
|
-
}
|
|
22696
|
-
};
|
|
22697
|
-
function readdirSync(dir) {
|
|
22698
|
-
try {
|
|
22699
|
-
return fs.readdirSync(dir);
|
|
22700
|
-
} catch (err) {
|
|
22701
|
-
return [];
|
|
22702
|
-
}
|
|
22703
|
-
}
|
|
22704
|
-
function getFirst(dir, filter) {
|
|
22705
|
-
var files = readdirSync(dir).filter(filter);
|
|
22706
|
-
return files[0] && path.join(dir, files[0]);
|
|
22707
|
-
}
|
|
22708
|
-
function matchBuild(name) {
|
|
22709
|
-
return /\.node$/.test(name);
|
|
22710
|
-
}
|
|
22711
|
-
function parseTuple(name) {
|
|
22712
|
-
var arr = name.split("-");
|
|
22713
|
-
if (arr.length !== 2) return;
|
|
22714
|
-
var platform2 = arr[0];
|
|
22715
|
-
var architectures = arr[1].split("+");
|
|
22716
|
-
if (!platform2) return;
|
|
22717
|
-
if (!architectures.length) return;
|
|
22718
|
-
if (!architectures.every(Boolean)) return;
|
|
22719
|
-
return { name, platform: platform2, architectures };
|
|
22720
|
-
}
|
|
22721
|
-
function matchTuple(platform2, arch2) {
|
|
22722
|
-
return function(tuple) {
|
|
22723
|
-
if (tuple == null) return false;
|
|
22724
|
-
if (tuple.platform !== platform2) return false;
|
|
22725
|
-
return tuple.architectures.includes(arch2);
|
|
22726
|
-
};
|
|
22727
|
-
}
|
|
22728
|
-
function compareTuples(a, b) {
|
|
22729
|
-
return a.architectures.length - b.architectures.length;
|
|
22730
|
-
}
|
|
22731
|
-
function parseTags(file) {
|
|
22732
|
-
var arr = file.split(".");
|
|
22733
|
-
var extension2 = arr.pop();
|
|
22734
|
-
var tags = { file, specificity: 0 };
|
|
22735
|
-
if (extension2 !== "node") return;
|
|
22736
|
-
for (var i = 0; i < arr.length; i++) {
|
|
22737
|
-
var tag = arr[i];
|
|
22738
|
-
if (tag === "node" || tag === "electron" || tag === "node-webkit") {
|
|
22739
|
-
tags.runtime = tag;
|
|
22740
|
-
} else if (tag === "napi") {
|
|
22741
|
-
tags.napi = true;
|
|
22742
|
-
} else if (tag.slice(0, 3) === "abi") {
|
|
22743
|
-
tags.abi = tag.slice(3);
|
|
22744
|
-
} else if (tag.slice(0, 2) === "uv") {
|
|
22745
|
-
tags.uv = tag.slice(2);
|
|
22746
|
-
} else if (tag.slice(0, 4) === "armv") {
|
|
22747
|
-
tags.armv = tag.slice(4);
|
|
22748
|
-
} else if (tag === "glibc" || tag === "musl") {
|
|
22749
|
-
tags.libc = tag;
|
|
22750
|
-
} else {
|
|
22751
|
-
continue;
|
|
22752
|
-
}
|
|
22753
|
-
tags.specificity++;
|
|
22754
|
-
}
|
|
22755
|
-
return tags;
|
|
22756
|
-
}
|
|
22757
|
-
function matchTags(runtime2, abi2) {
|
|
22758
|
-
return function(tags) {
|
|
22759
|
-
if (tags == null) return false;
|
|
22760
|
-
if (tags.runtime && tags.runtime !== runtime2 && !runtimeAgnostic(tags)) return false;
|
|
22761
|
-
if (tags.abi && tags.abi !== abi2 && !tags.napi) return false;
|
|
22762
|
-
if (tags.uv && tags.uv !== uv) return false;
|
|
22763
|
-
if (tags.armv && tags.armv !== armv) return false;
|
|
22764
|
-
if (tags.libc && tags.libc !== libc) return false;
|
|
22765
|
-
return true;
|
|
22766
|
-
};
|
|
22767
|
-
}
|
|
22768
|
-
function runtimeAgnostic(tags) {
|
|
22769
|
-
return tags.runtime === "node" && tags.napi;
|
|
22770
|
-
}
|
|
22771
|
-
function compareTags(runtime2) {
|
|
22772
|
-
return function(a, b) {
|
|
22773
|
-
if (a.runtime !== b.runtime) {
|
|
22774
|
-
return a.runtime === runtime2 ? -1 : 1;
|
|
22775
|
-
} else if (a.abi !== b.abi) {
|
|
22776
|
-
return a.abi ? -1 : 1;
|
|
22777
|
-
} else if (a.specificity !== b.specificity) {
|
|
22778
|
-
return a.specificity > b.specificity ? -1 : 1;
|
|
22779
|
-
} else {
|
|
22780
|
-
return 0;
|
|
22781
|
-
}
|
|
22782
|
-
};
|
|
22783
|
-
}
|
|
22784
|
-
function isNwjs() {
|
|
22785
|
-
return !!(process.versions && process.versions.nw);
|
|
22786
|
-
}
|
|
22787
|
-
function isElectron() {
|
|
22788
|
-
if (process.versions && process.versions.electron) return true;
|
|
22789
|
-
if (process.env.ELECTRON_RUN_AS_NODE) return true;
|
|
22790
|
-
return typeof window !== "undefined" && window.process && window.process.type === "renderer";
|
|
22791
|
-
}
|
|
22792
|
-
function isAlpine(platform2) {
|
|
22793
|
-
return platform2 === "linux" && fs.existsSync("/etc/alpine-release");
|
|
22794
|
-
}
|
|
22795
|
-
load.parseTags = parseTags;
|
|
22796
|
-
load.matchTags = matchTags;
|
|
22797
|
-
load.compareTags = compareTags;
|
|
22798
|
-
load.parseTuple = parseTuple;
|
|
22799
|
-
load.matchTuple = matchTuple;
|
|
22800
|
-
load.compareTuples = compareTuples;
|
|
22801
|
-
}
|
|
22802
|
-
});
|
|
22803
|
-
|
|
22804
|
-
// ../../../../node_modules/node-gyp-build/index.js
|
|
22805
|
-
var require_node_gyp_build2 = __commonJS({
|
|
22806
|
-
"../../../../node_modules/node-gyp-build/index.js"(exports, module) {
|
|
22807
|
-
var runtimeRequire = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
22808
|
-
if (typeof runtimeRequire.addon === "function") {
|
|
22809
|
-
module.exports = runtimeRequire.addon.bind(runtimeRequire);
|
|
22810
|
-
} else {
|
|
22811
|
-
module.exports = require_node_gyp_build();
|
|
22812
|
-
}
|
|
22813
|
-
}
|
|
22814
|
-
});
|
|
22815
|
-
|
|
22816
|
-
// ../../../../node_modules/bufferutil/fallback.js
|
|
22817
|
-
var require_fallback = __commonJS({
|
|
22818
|
-
"../../../../node_modules/bufferutil/fallback.js"(exports, module) {
|
|
22819
|
-
"use strict";
|
|
22820
|
-
var mask = (source, mask2, output, offset, length) => {
|
|
22821
|
-
for (var i = 0; i < length; i++) {
|
|
22822
|
-
output[offset + i] = source[i] ^ mask2[i & 3];
|
|
22823
|
-
}
|
|
22824
|
-
};
|
|
22825
|
-
var unmask = (buffer, mask2) => {
|
|
22826
|
-
const length = buffer.length;
|
|
22827
|
-
for (var i = 0; i < length; i++) {
|
|
22828
|
-
buffer[i] ^= mask2[i & 3];
|
|
22829
|
-
}
|
|
22830
|
-
};
|
|
22831
|
-
module.exports = { mask, unmask };
|
|
22832
|
-
}
|
|
22833
|
-
});
|
|
22834
|
-
|
|
22835
|
-
// ../../../../node_modules/bufferutil/index.js
|
|
22836
|
-
var require_bufferutil = __commonJS({
|
|
22837
|
-
"../../../../node_modules/bufferutil/index.js"(exports, module) {
|
|
22838
|
-
"use strict";
|
|
22839
|
-
try {
|
|
22840
|
-
module.exports = require_node_gyp_build2()(__dirname);
|
|
22841
|
-
} catch (e) {
|
|
22842
|
-
module.exports = require_fallback();
|
|
22843
|
-
}
|
|
22844
|
-
}
|
|
22845
|
-
});
|
|
22846
|
-
|
|
22847
22647
|
// node_modules/ws/lib/buffer-util.js
|
|
22848
22648
|
var require_buffer_util = __commonJS({
|
|
22849
22649
|
"node_modules/ws/lib/buffer-util.js"(exports, module) {
|
|
@@ -22904,7 +22704,7 @@ var require_buffer_util = __commonJS({
|
|
|
22904
22704
|
};
|
|
22905
22705
|
if (!process.env.WS_NO_BUFFER_UTIL) {
|
|
22906
22706
|
try {
|
|
22907
|
-
const bufferUtil =
|
|
22707
|
+
const bufferUtil = __require("bufferutil");
|
|
22908
22708
|
module.exports.mask = function(source, mask, output, offset, length) {
|
|
22909
22709
|
if (length < 48) _mask(source, mask, output, offset, length);
|
|
22910
22710
|
else bufferUtil.mask(source, mask, output, offset, length);
|
|
@@ -23098,7 +22898,7 @@ var require_permessage_deflate = __commonJS({
|
|
|
23098
22898
|
acceptAsServer(offers) {
|
|
23099
22899
|
const opts = this._options;
|
|
23100
22900
|
const accepted = offers.find((params) => {
|
|
23101
|
-
if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && !params.client_max_window_bits) {
|
|
22901
|
+
if (opts.serverNoContextTakeover === false && params.server_no_context_takeover || params.server_max_window_bits && (opts.serverMaxWindowBits === false || typeof opts.serverMaxWindowBits === "number" && opts.serverMaxWindowBits > params.server_max_window_bits) || typeof opts.clientMaxWindowBits === "number" && (typeof params.client_max_window_bits === "number" ? opts.clientMaxWindowBits > params.client_max_window_bits : !params.client_max_window_bits)) {
|
|
23102
22902
|
return false;
|
|
23103
22903
|
}
|
|
23104
22904
|
return true;
|
|
@@ -23352,55 +23152,6 @@ var require_permessage_deflate = __commonJS({
|
|
|
23352
23152
|
}
|
|
23353
23153
|
});
|
|
23354
23154
|
|
|
23355
|
-
// ../../../../node_modules/utf-8-validate/fallback.js
|
|
23356
|
-
var require_fallback2 = __commonJS({
|
|
23357
|
-
"../../../../node_modules/utf-8-validate/fallback.js"(exports, module) {
|
|
23358
|
-
"use strict";
|
|
23359
|
-
function isValidUTF8(buf) {
|
|
23360
|
-
const len = buf.length;
|
|
23361
|
-
let i = 0;
|
|
23362
|
-
while (i < len) {
|
|
23363
|
-
if ((buf[i] & 128) === 0) {
|
|
23364
|
-
i++;
|
|
23365
|
-
} else if ((buf[i] & 224) === 192) {
|
|
23366
|
-
if (i + 1 === len || (buf[i + 1] & 192) !== 128 || (buf[i] & 254) === 192) {
|
|
23367
|
-
return false;
|
|
23368
|
-
}
|
|
23369
|
-
i += 2;
|
|
23370
|
-
} else if ((buf[i] & 240) === 224) {
|
|
23371
|
-
if (i + 2 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || buf[i] === 224 && (buf[i + 1] & 224) === 128 || // overlong
|
|
23372
|
-
buf[i] === 237 && (buf[i + 1] & 224) === 160) {
|
|
23373
|
-
return false;
|
|
23374
|
-
}
|
|
23375
|
-
i += 3;
|
|
23376
|
-
} else if ((buf[i] & 248) === 240) {
|
|
23377
|
-
if (i + 3 >= len || (buf[i + 1] & 192) !== 128 || (buf[i + 2] & 192) !== 128 || (buf[i + 3] & 192) !== 128 || buf[i] === 240 && (buf[i + 1] & 240) === 128 || // overlong
|
|
23378
|
-
buf[i] === 244 && buf[i + 1] > 143 || buf[i] > 244) {
|
|
23379
|
-
return false;
|
|
23380
|
-
}
|
|
23381
|
-
i += 4;
|
|
23382
|
-
} else {
|
|
23383
|
-
return false;
|
|
23384
|
-
}
|
|
23385
|
-
}
|
|
23386
|
-
return true;
|
|
23387
|
-
}
|
|
23388
|
-
module.exports = isValidUTF8;
|
|
23389
|
-
}
|
|
23390
|
-
});
|
|
23391
|
-
|
|
23392
|
-
// ../../../../node_modules/utf-8-validate/index.js
|
|
23393
|
-
var require_utf_8_validate = __commonJS({
|
|
23394
|
-
"../../../../node_modules/utf-8-validate/index.js"(exports, module) {
|
|
23395
|
-
"use strict";
|
|
23396
|
-
try {
|
|
23397
|
-
module.exports = require_node_gyp_build2()(__dirname);
|
|
23398
|
-
} catch (e) {
|
|
23399
|
-
module.exports = require_fallback2();
|
|
23400
|
-
}
|
|
23401
|
-
}
|
|
23402
|
-
});
|
|
23403
|
-
|
|
23404
23155
|
// node_modules/ws/lib/validation.js
|
|
23405
23156
|
var require_validation = __commonJS({
|
|
23406
23157
|
"node_modules/ws/lib/validation.js"(exports, module) {
|
|
@@ -23592,7 +23343,7 @@ var require_validation = __commonJS({
|
|
|
23592
23343
|
};
|
|
23593
23344
|
} else if (!process.env.WS_NO_UTF_8_VALIDATE) {
|
|
23594
23345
|
try {
|
|
23595
|
-
const isValidUTF8 =
|
|
23346
|
+
const isValidUTF8 = __require("utf-8-validate");
|
|
23596
23347
|
module.exports.isValidUTF8 = function(buf) {
|
|
23597
23348
|
return buf.length < 32 ? _isValidUTF8(buf) : isValidUTF8(buf);
|
|
23598
23349
|
};
|
|
@@ -23637,6 +23388,10 @@ var require_receiver = __commonJS({
|
|
|
23637
23388
|
* extensions
|
|
23638
23389
|
* @param {Boolean} [options.isServer=false] Specifies whether to operate in
|
|
23639
23390
|
* client or server mode
|
|
23391
|
+
* @param {Number} [options.maxBufferedChunks=0] The maximum number of
|
|
23392
|
+
* buffered data chunks
|
|
23393
|
+
* @param {Number} [options.maxFragments=0] The maximum number of message
|
|
23394
|
+
* fragments
|
|
23640
23395
|
* @param {Number} [options.maxPayload=0] The maximum allowed message length
|
|
23641
23396
|
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
23642
23397
|
* not to skip UTF-8 validation for text and close messages
|
|
@@ -23647,6 +23402,8 @@ var require_receiver = __commonJS({
|
|
|
23647
23402
|
this._binaryType = options.binaryType || BINARY_TYPES[0];
|
|
23648
23403
|
this._extensions = options.extensions || {};
|
|
23649
23404
|
this._isServer = !!options.isServer;
|
|
23405
|
+
this._maxBufferedChunks = options.maxBufferedChunks | 0;
|
|
23406
|
+
this._maxFragments = options.maxFragments | 0;
|
|
23650
23407
|
this._maxPayload = options.maxPayload | 0;
|
|
23651
23408
|
this._skipUTF8Validation = !!options.skipUTF8Validation;
|
|
23652
23409
|
this[kWebSocket] = void 0;
|
|
@@ -23661,6 +23418,7 @@ var require_receiver = __commonJS({
|
|
|
23661
23418
|
this._opcode = 0;
|
|
23662
23419
|
this._totalPayloadLength = 0;
|
|
23663
23420
|
this._messageLength = 0;
|
|
23421
|
+
this._numFragments = 0;
|
|
23664
23422
|
this._fragments = [];
|
|
23665
23423
|
this._errored = false;
|
|
23666
23424
|
this._loop = false;
|
|
@@ -23676,6 +23434,18 @@ var require_receiver = __commonJS({
|
|
|
23676
23434
|
*/
|
|
23677
23435
|
_write(chunk, encoding, cb) {
|
|
23678
23436
|
if (this._opcode === 8 && this._state == GET_INFO) return cb();
|
|
23437
|
+
if (this._maxBufferedChunks > 0 && this._buffers.length >= this._maxBufferedChunks) {
|
|
23438
|
+
cb(
|
|
23439
|
+
this.createError(
|
|
23440
|
+
RangeError,
|
|
23441
|
+
"Too many buffered chunks",
|
|
23442
|
+
false,
|
|
23443
|
+
1008,
|
|
23444
|
+
"WS_ERR_TOO_MANY_BUFFERED_PARTS"
|
|
23445
|
+
)
|
|
23446
|
+
);
|
|
23447
|
+
return;
|
|
23448
|
+
}
|
|
23679
23449
|
this._bufferedBytes += chunk.length;
|
|
23680
23450
|
this._buffers.push(chunk);
|
|
23681
23451
|
this.startLoop(cb);
|
|
@@ -23999,6 +23769,17 @@ var require_receiver = __commonJS({
|
|
|
23999
23769
|
this.controlMessage(data, cb);
|
|
24000
23770
|
return;
|
|
24001
23771
|
}
|
|
23772
|
+
if (this._maxFragments > 0 && ++this._numFragments > this._maxFragments) {
|
|
23773
|
+
const error = this.createError(
|
|
23774
|
+
RangeError,
|
|
23775
|
+
"Too many message fragments",
|
|
23776
|
+
false,
|
|
23777
|
+
1008,
|
|
23778
|
+
"WS_ERR_TOO_MANY_BUFFERED_PARTS"
|
|
23779
|
+
);
|
|
23780
|
+
cb(error);
|
|
23781
|
+
return;
|
|
23782
|
+
}
|
|
24002
23783
|
if (this._compressed) {
|
|
24003
23784
|
this._state = INFLATING;
|
|
24004
23785
|
this.decompress(data, cb);
|
|
@@ -24056,6 +23837,7 @@ var require_receiver = __commonJS({
|
|
|
24056
23837
|
this._totalPayloadLength = 0;
|
|
24057
23838
|
this._messageLength = 0;
|
|
24058
23839
|
this._fragmented = 0;
|
|
23840
|
+
this._numFragments = 0;
|
|
24059
23841
|
this._fragments = [];
|
|
24060
23842
|
if (this._opcode === 2) {
|
|
24061
23843
|
let data;
|
|
@@ -25240,6 +25022,10 @@ var require_websocket = __commonJS({
|
|
|
25240
25022
|
* multiple times in the same tick
|
|
25241
25023
|
* @param {Function} [options.generateMask] The function used to generate the
|
|
25242
25024
|
* masking key
|
|
25025
|
+
* @param {Number} [options.maxBufferedChunks=0] The maximum number of
|
|
25026
|
+
* buffered data chunks
|
|
25027
|
+
* @param {Number} [options.maxFragments=0] The maximum number of message
|
|
25028
|
+
* fragments
|
|
25243
25029
|
* @param {Number} [options.maxPayload=0] The maximum allowed message size
|
|
25244
25030
|
* @param {Boolean} [options.skipUTF8Validation=false] Specifies whether or
|
|
25245
25031
|
* not to skip UTF-8 validation for text and close messages
|
|
@@ -25251,6 +25037,8 @@ var require_websocket = __commonJS({
|
|
|
25251
25037
|
binaryType: this.binaryType,
|
|
25252
25038
|
extensions: this._extensions,
|
|
25253
25039
|
isServer: this._isServer,
|
|
25040
|
+
maxBufferedChunks: options.maxBufferedChunks,
|
|
25041
|
+
maxFragments: options.maxFragments,
|
|
25254
25042
|
maxPayload: options.maxPayload,
|
|
25255
25043
|
skipUTF8Validation: options.skipUTF8Validation
|
|
25256
25044
|
});
|
|
@@ -25550,6 +25338,8 @@ var require_websocket = __commonJS({
|
|
|
25550
25338
|
autoPong: true,
|
|
25551
25339
|
closeTimeout: CLOSE_TIMEOUT,
|
|
25552
25340
|
protocolVersion: protocolVersions[1],
|
|
25341
|
+
maxBufferedChunks: 256 * 1024,
|
|
25342
|
+
maxFragments: 16 * 1024,
|
|
25553
25343
|
maxPayload: 100 * 1024 * 1024,
|
|
25554
25344
|
skipUTF8Validation: false,
|
|
25555
25345
|
perMessageDeflate: true,
|
|
@@ -25792,6 +25582,8 @@ var require_websocket = __commonJS({
|
|
|
25792
25582
|
websocket.setSocket(socket, head, {
|
|
25793
25583
|
allowSynchronousEvents: opts.allowSynchronousEvents,
|
|
25794
25584
|
generateMask: opts.generateMask,
|
|
25585
|
+
maxBufferedChunks: opts.maxBufferedChunks,
|
|
25586
|
+
maxFragments: opts.maxFragments,
|
|
25795
25587
|
maxPayload: opts.maxPayload,
|
|
25796
25588
|
skipUTF8Validation: opts.skipUTF8Validation
|
|
25797
25589
|
});
|
|
@@ -26134,6 +25926,10 @@ var require_websocket_server = __commonJS({
|
|
|
26134
25926
|
* called
|
|
26135
25927
|
* @param {Function} [options.handleProtocols] A hook to handle protocols
|
|
26136
25928
|
* @param {String} [options.host] The hostname where to bind the server
|
|
25929
|
+
* @param {Number} [options.maxBufferedChunks=262144] The maximum number of
|
|
25930
|
+
* buffered data chunks
|
|
25931
|
+
* @param {Number} [options.maxFragments=16384] The maximum number of message
|
|
25932
|
+
* fragments
|
|
26137
25933
|
* @param {Number} [options.maxPayload=104857600] The maximum allowed message
|
|
26138
25934
|
* size
|
|
26139
25935
|
* @param {Boolean} [options.noServer=false] Enable no server mode
|
|
@@ -26155,6 +25951,8 @@ var require_websocket_server = __commonJS({
|
|
|
26155
25951
|
options = {
|
|
26156
25952
|
allowSynchronousEvents: true,
|
|
26157
25953
|
autoPong: true,
|
|
25954
|
+
maxBufferedChunks: 256 * 1024,
|
|
25955
|
+
maxFragments: 16 * 1024,
|
|
26158
25956
|
maxPayload: 100 * 1024 * 1024,
|
|
26159
25957
|
skipUTF8Validation: false,
|
|
26160
25958
|
perMessageDeflate: false,
|
|
@@ -26434,6 +26232,8 @@ var require_websocket_server = __commonJS({
|
|
|
26434
26232
|
socket.removeListener("error", socketOnError);
|
|
26435
26233
|
ws.setSocket(socket, head, {
|
|
26436
26234
|
allowSynchronousEvents: this.options.allowSynchronousEvents,
|
|
26235
|
+
maxBufferedChunks: this.options.maxBufferedChunks,
|
|
26236
|
+
maxFragments: this.options.maxFragments,
|
|
26437
26237
|
maxPayload: this.options.maxPayload,
|
|
26438
26238
|
skipUTF8Validation: this.options.skipUTF8Validation
|
|
26439
26239
|
});
|
|
@@ -29444,6 +29244,68 @@ function usesHttpDelivery(runtimeKind) {
|
|
|
29444
29244
|
return runtimeKind === "hermes" || runtimeKind === "hermes-api" || runtimeKind === "zeroclaw" || runtimeKind === "custom";
|
|
29445
29245
|
}
|
|
29446
29246
|
|
|
29247
|
+
// src/voice-capability.ts
|
|
29248
|
+
var PERKOS_VOICE_PROBE_MARKER = "PERKOS_VOICE_PROBE";
|
|
29249
|
+
var PERKOS_VOICE_ENROLL_MARKER = "PERKOS_VOICE_ENROLL";
|
|
29250
|
+
function runtime(runtimeKind) {
|
|
29251
|
+
if (runtimeKind === "hermes" || runtimeKind === "hermes-api") return "hermes";
|
|
29252
|
+
if (runtimeKind === "openclaw") return "openclaw";
|
|
29253
|
+
if (runtimeKind === "zeroclaw") return "zeroclaw";
|
|
29254
|
+
return null;
|
|
29255
|
+
}
|
|
29256
|
+
function controlPlane(config) {
|
|
29257
|
+
const heartbeat = config.platform?.heartbeatUrl;
|
|
29258
|
+
const relayApiKey = config.relay?.apiKey || config.chat?.apiKey;
|
|
29259
|
+
if (!heartbeat || !relayApiKey) return null;
|
|
29260
|
+
let url;
|
|
29261
|
+
try {
|
|
29262
|
+
url = new URL(heartbeat);
|
|
29263
|
+
} catch {
|
|
29264
|
+
return null;
|
|
29265
|
+
}
|
|
29266
|
+
const match = url.pathname.match(/^(.*)\/agents\/([^/]+)\/heartbeat\/?$/u);
|
|
29267
|
+
const agentId = config.platform?.agentId || (match ? decodeURIComponent(match[2]) : "");
|
|
29268
|
+
if (!match || !agentId) return null;
|
|
29269
|
+
return { apiBaseUrl: `${url.origin}${match[1]}`, agentId, relayApiKey };
|
|
29270
|
+
}
|
|
29271
|
+
async function reportPluginMissing(message, config) {
|
|
29272
|
+
if (message !== PERKOS_VOICE_PROBE_MARKER) return "PERKOS_VOICE_FAILED:voice_plugin_missing";
|
|
29273
|
+
const target = controlPlane(config);
|
|
29274
|
+
if (!target) return "PERKOS_VOICE_FAILED:a2a_identity_unavailable";
|
|
29275
|
+
const response = await fetch(`${target.apiBaseUrl}/agents/${encodeURIComponent(target.agentId)}/voice-credential/capability-report`, {
|
|
29276
|
+
method: "POST",
|
|
29277
|
+
headers: { authorization: `Bearer ${target.relayApiKey}`, "content-type": "application/json" },
|
|
29278
|
+
body: JSON.stringify({ state: "unsupported", reasonCode: "voice_plugin_missing" })
|
|
29279
|
+
}).catch(() => null);
|
|
29280
|
+
return response?.ok ? "PERKOS_VOICE_UNSUPPORTED:voice_plugin_missing" : "PERKOS_VOICE_FAILED:control_plane_unavailable";
|
|
29281
|
+
}
|
|
29282
|
+
async function defaultLoader() {
|
|
29283
|
+
const specifier = "@perkos/perkos-voice/a2a";
|
|
29284
|
+
return import(specifier);
|
|
29285
|
+
}
|
|
29286
|
+
async function tryHandleInstalledVoiceMarker(message, config, loadVoice = defaultLoader) {
|
|
29287
|
+
const marker = message.trim();
|
|
29288
|
+
if (marker !== PERKOS_VOICE_PROBE_MARKER && marker !== PERKOS_VOICE_ENROLL_MARKER) return null;
|
|
29289
|
+
const target = controlPlane(config);
|
|
29290
|
+
if (!target) return "PERKOS_VOICE_FAILED:a2a_identity_unavailable";
|
|
29291
|
+
const runtimeKind = runtime(config.runtime?.kind);
|
|
29292
|
+
if (!runtimeKind) return reportPluginMissing(marker, config);
|
|
29293
|
+
let voice;
|
|
29294
|
+
try {
|
|
29295
|
+
voice = await loadVoice();
|
|
29296
|
+
} catch {
|
|
29297
|
+
return reportPluginMissing(marker, config);
|
|
29298
|
+
}
|
|
29299
|
+
if (typeof voice.handleA2AVoiceMarker !== "function" || typeof voice.configureA2AVoiceEnrollment !== "function") {
|
|
29300
|
+
return reportPluginMissing(marker, config);
|
|
29301
|
+
}
|
|
29302
|
+
return voice.handleA2AVoiceMarker(marker, {
|
|
29303
|
+
...target,
|
|
29304
|
+
runtime: runtimeKind,
|
|
29305
|
+
configure: voice.configureA2AVoiceEnrollment
|
|
29306
|
+
});
|
|
29307
|
+
}
|
|
29308
|
+
|
|
29447
29309
|
// src/chat-client.ts
|
|
29448
29310
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
29449
29311
|
var DEFAULT_URL = "wss://chat.perkos.xyz/chat";
|
|
@@ -30237,11 +30099,11 @@ function formatRecentChatContext(messages, currentMessageId) {
|
|
|
30237
30099
|
return transcript.length <= CHAT_CONTEXT_CHAR_LIMIT ? transcript : `\u2026${transcript.slice(-CHAT_CONTEXT_CHAR_LIMIT)}`;
|
|
30238
30100
|
}
|
|
30239
30101
|
async function deliverToHermes(config, message, logger) {
|
|
30240
|
-
const
|
|
30241
|
-
const baseUrl = (
|
|
30242
|
-
const endpoint =
|
|
30243
|
-
const sessionKey =
|
|
30244
|
-
const token =
|
|
30102
|
+
const runtime2 = config.runtime || {};
|
|
30103
|
+
const baseUrl = (runtime2.hermesUrl || "http://127.0.0.1:8642").replace(/\/+$/, "");
|
|
30104
|
+
const endpoint = runtime2.hermesEndpoint || "/v1/responses";
|
|
30105
|
+
const sessionKey = runtime2.sessionKey || "a2a";
|
|
30106
|
+
const token = runtime2.hermesToken;
|
|
30245
30107
|
const url = `${baseUrl}${endpoint.startsWith("/") ? endpoint : `/${endpoint}`}`;
|
|
30246
30108
|
const headers = {
|
|
30247
30109
|
"content-type": "application/json",
|
|
@@ -30250,7 +30112,7 @@ async function deliverToHermes(config, message, logger) {
|
|
|
30250
30112
|
};
|
|
30251
30113
|
if (token) headers.authorization = `Bearer ${token}`;
|
|
30252
30114
|
const normalizedEndpoint = endpoint.replace(/^\/?/, "/");
|
|
30253
|
-
const model =
|
|
30115
|
+
const model = runtime2.model?.trim();
|
|
30254
30116
|
const body = normalizedEndpoint.startsWith("/v1/chat/completions") ? { ...model ? { model } : {}, messages: [{ role: "user", content: message }], stream: false } : normalizedEndpoint.startsWith("/v1/runs") ? { input: message, session_id: sessionKey } : normalizedEndpoint.startsWith("/v1/responses") ? { ...model ? { model } : {}, input: message, store: true } : { sessionKey, message };
|
|
30255
30117
|
const response = await fetch(url, {
|
|
30256
30118
|
method: "POST",
|
|
@@ -30487,6 +30349,13 @@ function register(api) {
|
|
|
30487
30349
|
let supervisorClient;
|
|
30488
30350
|
const handleSupervisorChatDeliver = async (frame) => {
|
|
30489
30351
|
const walletAddress = parseWalletFromIdentity(frame.from);
|
|
30352
|
+
const voiceReply = await tryHandleInstalledVoiceMarker(frame.text, pluginConfig);
|
|
30353
|
+
if (voiceReply) {
|
|
30354
|
+
if (walletAddress) {
|
|
30355
|
+
await supervisorClient.sendChatReply({ convId: frame.convId, walletAddress, text: voiceReply, replyTo: frame.id });
|
|
30356
|
+
}
|
|
30357
|
+
return;
|
|
30358
|
+
}
|
|
30490
30359
|
const marker = `[PERKOS_CHAT:${frame.convId}]`;
|
|
30491
30360
|
const recentPage = await chatStore?.readPage(frame.convId, {
|
|
30492
30361
|
limit: CHAT_CONTEXT_MESSAGE_LIMIT + 1
|
|
@@ -31018,6 +30887,8 @@ export {
|
|
|
31018
30887
|
A2AServer,
|
|
31019
30888
|
ChatClient,
|
|
31020
30889
|
ChatStore,
|
|
30890
|
+
PERKOS_VOICE_ENROLL_MARKER,
|
|
30891
|
+
PERKOS_VOICE_PROBE_MARKER,
|
|
31021
30892
|
RelayClient,
|
|
31022
30893
|
RelayHub,
|
|
31023
30894
|
a2aLifecycleKey,
|
|
@@ -31034,6 +30905,7 @@ export {
|
|
|
31034
30905
|
resolveOpenClawRuntimeModelRoute,
|
|
31035
30906
|
runOpenClawChatTurn,
|
|
31036
30907
|
stripPerkosChatTransportMarker,
|
|
30908
|
+
tryHandleInstalledVoiceMarker,
|
|
31037
30909
|
useNativeHarnessForResolvedRoute
|
|
31038
30910
|
};
|
|
31039
30911
|
/*! Bundled license information:
|