engine7 7.1.58 → 7.1.60
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/cli.mjs +142 -6
- package/dist/engine-startup.mjs +4580 -4411
- package/dist/main.mjs +5173 -5004
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -9422,13 +9422,17 @@ function isDestructiveCommand(command) {
|
|
|
9422
9422
|
function sanitizeEnv(env) {
|
|
9423
9423
|
const result = {};
|
|
9424
9424
|
for (const [k, v] of Object.entries(env)) {
|
|
9425
|
+
if (ENV_ALLOW_KEYS.includes(k)) {
|
|
9426
|
+
result[k] = v;
|
|
9427
|
+
continue;
|
|
9428
|
+
}
|
|
9425
9429
|
if (!BLOCKED_ENV_KEYS.some((b) => k.toUpperCase().includes(b))) {
|
|
9426
9430
|
result[k] = v;
|
|
9427
9431
|
}
|
|
9428
9432
|
}
|
|
9429
9433
|
return result;
|
|
9430
9434
|
}
|
|
9431
|
-
var DANGEROUS_COMMANDS, DESTRUCTIVE_PATTERNS, BLOCKED_ENV_KEYS;
|
|
9435
|
+
var DANGEROUS_COMMANDS, DESTRUCTIVE_PATTERNS, BLOCKED_ENV_KEYS, ENV_ALLOW_KEYS;
|
|
9432
9436
|
var init_bashSecurity = __esm({
|
|
9433
9437
|
"src/tools/BashTool/bashSecurity.ts"() {
|
|
9434
9438
|
"use strict";
|
|
@@ -9479,6 +9483,7 @@ var init_bashSecurity = __esm({
|
|
|
9479
9483
|
"PASSWORD",
|
|
9480
9484
|
"PRIVATE_KEY"
|
|
9481
9485
|
];
|
|
9486
|
+
ENV_ALLOW_KEYS = ["MULTICA_TOKEN"];
|
|
9482
9487
|
}
|
|
9483
9488
|
});
|
|
9484
9489
|
|
|
@@ -12267,8 +12272,14 @@ var init_my_eyes = __esm({
|
|
|
12267
12272
|
return { content: "Error: my_eyes \u672A\u914D\u7F6E\u3002\u8BF7\u5728 config.tools.my_eyes.model \u8BBE\u7F6E\uFF08\u683C\u5F0F\uFF1Aprovider/model\uFF09\u3002", isError: true };
|
|
12268
12273
|
}
|
|
12269
12274
|
const slashIdx = modelRef.indexOf("/");
|
|
12275
|
+
const providerId = modelRef.slice(0, slashIdx);
|
|
12270
12276
|
const modelId = modelRef.slice(slashIdx + 1);
|
|
12271
|
-
const
|
|
12277
|
+
const providerCfg = (liveConfig.get("providers") || {})[providerId];
|
|
12278
|
+
if (!providerCfg) {
|
|
12279
|
+
return { content: `Error: tools.my_eyes.model \u7684 provider "${providerId}" \u4E0D\u5B58\u5728\u4E8E providers \u914D\u7F6E\u3002\u68C0\u67E5 config \u91CC models.providers.${providerId}\u3002`, isError: true };
|
|
12280
|
+
}
|
|
12281
|
+
const { createProvider: createProvider2 } = await Promise.resolve().then(() => (init_provider_factory(), provider_factory_exports));
|
|
12282
|
+
const provider = createProvider2(providerCfg);
|
|
12272
12283
|
if (!provider?.streamChat) {
|
|
12273
12284
|
return { content: "Error: provider \u4E0D\u53EF\u7528\u3002", isError: true };
|
|
12274
12285
|
}
|
|
@@ -12776,6 +12787,115 @@ async function wavToOggOpus(wavPath) {
|
|
|
12776
12787
|
fs18.unlinkSync(wavPath);
|
|
12777
12788
|
return oggPath;
|
|
12778
12789
|
}
|
|
12790
|
+
async function sendVoiceToMulticaIssue(text, issueId, opts) {
|
|
12791
|
+
const vc = liveConfig.get("tools.my_voice");
|
|
12792
|
+
let audioPath = "";
|
|
12793
|
+
let actualEngine = opts.engine || vc?.provider || "edge";
|
|
12794
|
+
try {
|
|
12795
|
+
if (actualEngine === "qwen3-3060" && vc?.url) {
|
|
12796
|
+
try {
|
|
12797
|
+
const { oggPath } = await ttsQwen3Opus(text, { url: vc.url, voice: vc.voice, lang: vc.lang });
|
|
12798
|
+
audioPath = oggPath;
|
|
12799
|
+
} catch (e) {
|
|
12800
|
+
console.warn(`[my-voice:multaca] qwen3 opus failed (${e.message}), trying PCM`);
|
|
12801
|
+
const pcmChunks = [];
|
|
12802
|
+
await ttsQwen3Local(text, { url: vc.url, voice: vc.voice, lang: vc.lang }, (pcm2) => pcmChunks.push(pcm2));
|
|
12803
|
+
const pcm = Buffer.concat(pcmChunks);
|
|
12804
|
+
fs18.mkdirSync(VOICE_DIR, { recursive: true });
|
|
12805
|
+
const wavPath = path19.join(VOICE_DIR, `tts_mc_${Date.now()}.wav`);
|
|
12806
|
+
const header = Buffer.alloc(44);
|
|
12807
|
+
header.write("RIFF", 0);
|
|
12808
|
+
header.writeUInt32LE(36 + pcm.length, 4);
|
|
12809
|
+
header.write("WAVE", 8);
|
|
12810
|
+
header.write("fmt ", 12);
|
|
12811
|
+
header.writeUInt32LE(16, 16);
|
|
12812
|
+
header.writeUInt16LE(1, 20);
|
|
12813
|
+
header.writeUInt16LE(1, 22);
|
|
12814
|
+
header.writeUInt32LE(24e3, 24);
|
|
12815
|
+
header.writeUInt32LE(48e3, 28);
|
|
12816
|
+
header.writeUInt16LE(2, 32);
|
|
12817
|
+
header.writeUInt16LE(16, 34);
|
|
12818
|
+
header.write("data", 36);
|
|
12819
|
+
header.writeUInt32LE(pcm.length, 40);
|
|
12820
|
+
fs18.writeFileSync(wavPath, Buffer.concat([header, pcm]));
|
|
12821
|
+
audioPath = wavPath;
|
|
12822
|
+
}
|
|
12823
|
+
} else if (actualEngine === "cosyvoice" && vc?.apiKey) {
|
|
12824
|
+
audioPath = await ttsCosyvoice(text, vc.apiKey, vc.model || "cosyvoice-v1", vc.voice, vc.workspaceId, vc.instruction);
|
|
12825
|
+
} else if (actualEngine === "gptsovits") {
|
|
12826
|
+
audioPath = await ttsGptsovits(text);
|
|
12827
|
+
} else {
|
|
12828
|
+
audioPath = await ttsEdge(text);
|
|
12829
|
+
actualEngine = "edge";
|
|
12830
|
+
}
|
|
12831
|
+
} catch (e) {
|
|
12832
|
+
return { content: `\u8BED\u97F3\u751F\u6210\u5931\u8D25\uFF08headless\u2192multaca\uFF09\uFF1A${e.message}\u3002\u8BF7\u7528\u6587\u5B57\u56DE\u590D\u4EE3\u66FF\u3002`, isError: true };
|
|
12833
|
+
}
|
|
12834
|
+
if (!audioPath || !fs18.existsSync(audioPath)) {
|
|
12835
|
+
return { content: "\u8BED\u97F3\u751F\u6210\u5931\u8D25\uFF08headless\u2192multaca\uFF09\uFF1ATTS \u672A\u4EA7\u51FA\u6587\u4EF6\u3002\u8BF7\u7528\u6587\u5B57\u56DE\u590D\u4EE3\u66FF\u3002", isError: true };
|
|
12836
|
+
}
|
|
12837
|
+
if (audioPath.endsWith(".wav")) {
|
|
12838
|
+
try {
|
|
12839
|
+
audioPath = await wavToOggOpus(audioPath);
|
|
12840
|
+
} catch (e) {
|
|
12841
|
+
console.warn(`[my-voice:multaca] opus encode failed (${e.message}), attaching wav`);
|
|
12842
|
+
}
|
|
12843
|
+
}
|
|
12844
|
+
const ext = path19.extname(audioPath).toLowerCase();
|
|
12845
|
+
const sizeKB = fs18.statSync(audioPath).size / 1024;
|
|
12846
|
+
const voiceFile = `voice_${Date.now()}${ext}`;
|
|
12847
|
+
const cwdCopy = path19.join(process.cwd(), voiceFile);
|
|
12848
|
+
try {
|
|
12849
|
+
fs18.copyFileSync(audioPath, cwdCopy);
|
|
12850
|
+
} catch (e) {
|
|
12851
|
+
try {
|
|
12852
|
+
fs18.unlinkSync(audioPath);
|
|
12853
|
+
} catch {
|
|
12854
|
+
}
|
|
12855
|
+
return { content: `\u8BED\u97F3\u6302\u8F7D\u5931\u8D25\uFF08\u62F7\u8D1D\u5230\u5DE5\u4F5C\u76EE\u5F55\uFF09\uFF1A${e.message}`, isError: true };
|
|
12856
|
+
}
|
|
12857
|
+
try {
|
|
12858
|
+
fs18.unlinkSync(audioPath);
|
|
12859
|
+
} catch {
|
|
12860
|
+
}
|
|
12861
|
+
const content = opts.caption || `\u{1F399}\uFE0F \u8BED\u97F3\u6D88\u606F\uFF08${text.length} \u5B57\uFF09`;
|
|
12862
|
+
try {
|
|
12863
|
+
const { execFile: execFile3 } = await import("node:child_process");
|
|
12864
|
+
const { promisify: promisify3 } = await import("node:util");
|
|
12865
|
+
const execFileA = promisify3(execFile3);
|
|
12866
|
+
const { stdout } = await execFileA("multica", [
|
|
12867
|
+
"issue",
|
|
12868
|
+
"comment",
|
|
12869
|
+
"add",
|
|
12870
|
+
issueId,
|
|
12871
|
+
"--content",
|
|
12872
|
+
content,
|
|
12873
|
+
"--attachment",
|
|
12874
|
+
voiceFile,
|
|
12875
|
+
"--output",
|
|
12876
|
+
"json"
|
|
12877
|
+
], { timeout: 6e4 });
|
|
12878
|
+
let ok = false;
|
|
12879
|
+
try {
|
|
12880
|
+
const parsed = JSON.parse(stdout);
|
|
12881
|
+
ok = !!(parsed?.comment_id || parsed?.id || parsed?.attachments && parsed.attachments.length > 0);
|
|
12882
|
+
} catch {
|
|
12883
|
+
ok = stdout.includes("Comment added");
|
|
12884
|
+
}
|
|
12885
|
+
if (!ok) throw new Error(`unexpected CLI output: ${String(stdout).slice(0, 200)}`);
|
|
12886
|
+
try {
|
|
12887
|
+
fs18.unlinkSync(cwdCopy);
|
|
12888
|
+
} catch {
|
|
12889
|
+
}
|
|
12890
|
+
return { content: `Voice sent to multaca issue ${issueId}! (${actualEngine}, ${sizeKB.toFixed(0)}KB, \u9644\u4EF6\u5DF2\u6302\u5230\u8BC4\u8BBA\u2014\u2014\u5728 multaca \u5BA2\u6237\u7AEF\u64AD\u653E)` };
|
|
12891
|
+
} catch (e) {
|
|
12892
|
+
try {
|
|
12893
|
+
fs18.unlinkSync(cwdCopy);
|
|
12894
|
+
} catch {
|
|
12895
|
+
}
|
|
12896
|
+
return { content: `\u8BED\u97F3\u6302\u5230 multaca issue \u5931\u8D25\uFF1A${e.message}\u3002\u8BF7\u7528\u6587\u5B57\u56DE\u590D\u4EE3\u66FF\u3002`, isError: true };
|
|
12897
|
+
}
|
|
12898
|
+
}
|
|
12779
12899
|
var execFileAsync, VOICE_DIR, _pyCache, GPTSOVITS_API, GPTSOVITS_REF_WAV, GPTSOVITS_REF_TEXT, GPTSOVITS_REF_LANG, EDGE_VOICE;
|
|
12780
12900
|
var init_my_voice = __esm({
|
|
12781
12901
|
"src/tools/my-voice.ts"() {
|
|
@@ -12801,7 +12921,8 @@ var init_my_voice = __esm({
|
|
|
12801
12921
|
text: { type: "string", description: "What to say (Chinese text)." },
|
|
12802
12922
|
engine: { type: "string", enum: ["cosyvoice", "gptsovits", "qwen3-3060", "edge"], description: "TTS engine. cosyvoice = \u767E\u70BCAPI (default if configured), gptsovits = local voice clone, qwen3-3060 = \u672C\u5730 GGML Q8_0 (3060), edge = backup." },
|
|
12803
12923
|
channel: { type: "string", enum: ["weixin", "feishu", "discord"], description: "Target channel. Default: current channel." },
|
|
12804
|
-
to: { type: "string", description: "Recipient ID. \u5FAE\u4FE1\u683C\u5F0F o\u5F00\u5934@im.wechat\u7ED3\u5C3E\uFF0C\u98DE\u4E66\u683C\u5F0F ou_\u5F00\u5934 open_id\u3002\u4E0D\u786E\u5B9A\u5C31\u5148 read prompts/contacts.md \u67E5\u6536\u4EF6\u4EBA ID\u3002" },
|
|
12924
|
+
to: { type: "string", description: "Recipient ID. \u5FAE\u4FE1\u683C\u5F0F o\u5F00\u5934@im.wechat\u7ED3\u5C3E\uFF0C\u98DE\u4E66\u683C\u5F0F ou_\u5F00\u5934 open_id\u3002\u4E0D\u786E\u5B9A\u5C31\u5148 read prompts/contacts.md \u67E5\u6536\u4EF6\u4EBA ID\u3002multaca \u4EFB\u52A1\u91CC\u4E0D\u9700\u8981\u586B to\u2014\u2014\u8BED\u97F3\u4F1A\u6302\u5230\u5F53\u524D issue \u8BC4\u8BBA\uFF0C\u586B issueId \u6307\u5B9A\u76EE\u6807 issue\u3002" },
|
|
12925
|
+
issueId: { type: "string", description: 'multaca headless \u4E13\u7528\uFF1A\u76EE\u6807 issue ID\uFF08\u4EFB\u52A1 prompt \u91CC\u7684 "Your assigned issue ID"\uFF09\u3002\u666E\u901A\u98DE\u4E66/\u5FAE\u4FE1\u573A\u666F\u4E0D\u8981\u586B\u3002' },
|
|
12805
12926
|
caption: { type: "string", description: "Optional text to accompany the voice message." }
|
|
12806
12927
|
},
|
|
12807
12928
|
required: ["text"]
|
|
@@ -12812,7 +12933,17 @@ var init_my_voice = __esm({
|
|
|
12812
12933
|
const requestedEngine = args.engine || "";
|
|
12813
12934
|
const caption = args.caption || "";
|
|
12814
12935
|
const mgr = ctx.channelManager;
|
|
12815
|
-
if (!mgr)
|
|
12936
|
+
if (!mgr) {
|
|
12937
|
+
const multicaTaskId = process.env.MULTICA_TASK_ID || "";
|
|
12938
|
+
const issueId = args.issueId || multicaTaskId;
|
|
12939
|
+
if (multicaTaskId && issueId) {
|
|
12940
|
+
return await sendVoiceToMulticaIssue(text, issueId, { engine: requestedEngine, caption });
|
|
12941
|
+
}
|
|
12942
|
+
return {
|
|
12943
|
+
content: "\u8BED\u97F3\u672A\u53D1\u9001\uFF1A\u5F53\u524D\u662F\u65E0\u6E20\u9053\u73AF\u5883\uFF08headless/CLI\uFF09\uFF0C\u4E14\u6CA1\u6709 multaca \u4EFB\u52A1\u4E0A\u4E0B\u6587\uFF08MULTICA_TASK_ID\uFF09\u6216 issueId\u3002\u6CA1\u6709\u53EF\u7528\u7684\u53D1\u9001\u51FA\u53E3\uFF0C\u8BF7\u7528\u6587\u5B57\u56DE\u590D\u4EE3\u66FF\u3002",
|
|
12944
|
+
isError: true
|
|
12945
|
+
};
|
|
12946
|
+
}
|
|
12816
12947
|
const resolvedChannelRaw = args.channel || (ctx.channel === "deskBuddy" ? "feishu" : ctx.channel) || "feishu";
|
|
12817
12948
|
const resolvedChannel = resolvedChannelRaw === "weixin" ? "wechat" : resolvedChannelRaw;
|
|
12818
12949
|
let target = args.to || ctx.channelTarget || ctx.from;
|
|
@@ -19561,6 +19692,7 @@ function parseCcRunArgs(argv) {
|
|
|
19561
19692
|
verbose: false,
|
|
19562
19693
|
sessionId: "",
|
|
19563
19694
|
maxTurns: void 0,
|
|
19695
|
+
noRecall: false,
|
|
19564
19696
|
stateDir: "",
|
|
19565
19697
|
configName: "",
|
|
19566
19698
|
agentName: ""
|
|
@@ -19595,6 +19727,8 @@ function parseCcRunArgs(argv) {
|
|
|
19595
19727
|
args.sessionId = takeValue();
|
|
19596
19728
|
} else if (a === "--max-turns") {
|
|
19597
19729
|
args.maxTurns = parseInt(takeValue(), 10) || void 0;
|
|
19730
|
+
} else if (a === "--no-recall") {
|
|
19731
|
+
args.noRecall = true;
|
|
19598
19732
|
} else if (a === "--state-dir") {
|
|
19599
19733
|
args.stateDir = takeValue().trim();
|
|
19600
19734
|
} else if (a === "--config") {
|
|
@@ -19734,6 +19868,8 @@ async function runQuery(args) {
|
|
|
19734
19868
|
await Promise.resolve().then(() => (init_tools_bundle(), tools_bundle_exports));
|
|
19735
19869
|
const { registry: registry2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
|
|
19736
19870
|
registry2.config = config;
|
|
19871
|
+
const { liveConfig: liveConfig2 } = await Promise.resolve().then(() => (init_live(), live_exports));
|
|
19872
|
+
liveConfig2.init(config);
|
|
19737
19873
|
const { handleQuery: handleQuery2 } = await Promise.resolve().then(() => (init_handle_query(), handle_query_exports));
|
|
19738
19874
|
const deps = {
|
|
19739
19875
|
engine,
|
|
@@ -19772,8 +19908,8 @@ async function runQuery(args) {
|
|
|
19772
19908
|
// channelTarget
|
|
19773
19909
|
void 0,
|
|
19774
19910
|
// inboundMeta
|
|
19775
|
-
|
|
19776
|
-
// skipRecall
|
|
19911
|
+
args.noRecall || /quick-create assistant/i.test(args.prompt),
|
|
19912
|
+
// skipRecall(--no-recall 或建单任务自动跳过:daemon 拼的 quick-create prompt 是机械转述,recall sideQuery 在子进程里拖 30-65s)
|
|
19777
19913
|
"cc-run"
|
|
19778
19914
|
// source
|
|
19779
19915
|
);
|