engine7 7.1.59 → 7.1.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/dist/cli.mjs CHANGED
@@ -12272,8 +12272,14 @@ var init_my_eyes = __esm({
12272
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 };
12273
12273
  }
12274
12274
  const slashIdx = modelRef.indexOf("/");
12275
+ const providerId = modelRef.slice(0, slashIdx);
12275
12276
  const modelId = modelRef.slice(slashIdx + 1);
12276
- const provider = ctx.provider;
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);
12277
12283
  if (!provider?.streamChat) {
12278
12284
  return { content: "Error: provider \u4E0D\u53EF\u7528\u3002", isError: true };
12279
12285
  }
@@ -12781,6 +12787,115 @@ async function wavToOggOpus(wavPath) {
12781
12787
  fs18.unlinkSync(wavPath);
12782
12788
  return oggPath;
12783
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
+ }
12784
12899
  var execFileAsync, VOICE_DIR, _pyCache, GPTSOVITS_API, GPTSOVITS_REF_WAV, GPTSOVITS_REF_TEXT, GPTSOVITS_REF_LANG, EDGE_VOICE;
12785
12900
  var init_my_voice = __esm({
12786
12901
  "src/tools/my-voice.ts"() {
@@ -12806,7 +12921,8 @@ var init_my_voice = __esm({
12806
12921
  text: { type: "string", description: "What to say (Chinese text)." },
12807
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." },
12808
12923
  channel: { type: "string", enum: ["weixin", "feishu", "discord"], description: "Target channel. Default: current channel." },
12809
- 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' },
12810
12926
  caption: { type: "string", description: "Optional text to accompany the voice message." }
12811
12927
  },
12812
12928
  required: ["text"]
@@ -12817,7 +12933,17 @@ var init_my_voice = __esm({
12817
12933
  const requestedEngine = args.engine || "";
12818
12934
  const caption = args.caption || "";
12819
12935
  const mgr = ctx.channelManager;
12820
- if (!mgr) return { content: "\u53D1\u9001\u5931\u8D25: \u6CA1\u6709 ChannelManager", isError: true };
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
+ }
12821
12947
  const resolvedChannelRaw = args.channel || (ctx.channel === "deskBuddy" ? "feishu" : ctx.channel) || "feishu";
12822
12948
  const resolvedChannel = resolvedChannelRaw === "weixin" ? "wechat" : resolvedChannelRaw;
12823
12949
  let target = args.to || ctx.channelTarget || ctx.from;
@@ -19566,6 +19692,7 @@ function parseCcRunArgs(argv) {
19566
19692
  verbose: false,
19567
19693
  sessionId: "",
19568
19694
  maxTurns: void 0,
19695
+ noRecall: false,
19569
19696
  stateDir: "",
19570
19697
  configName: "",
19571
19698
  agentName: ""
@@ -19600,12 +19727,16 @@ function parseCcRunArgs(argv) {
19600
19727
  args.sessionId = takeValue();
19601
19728
  } else if (a === "--max-turns") {
19602
19729
  args.maxTurns = parseInt(takeValue(), 10) || void 0;
19730
+ } else if (a === "--no-recall") {
19731
+ args.noRecall = true;
19603
19732
  } else if (a === "--state-dir") {
19604
19733
  args.stateDir = takeValue().trim();
19605
19734
  } else if (a === "--config") {
19606
19735
  args.configName = takeValue().trim();
19607
19736
  } else if (a === "--agent") {
19608
19737
  args.agentName = takeValue().trim();
19738
+ } else if (a === "--resume") {
19739
+ takeValue();
19609
19740
  }
19610
19741
  }
19611
19742
  if (!hasPrompt) {
@@ -19739,6 +19870,8 @@ async function runQuery(args) {
19739
19870
  await Promise.resolve().then(() => (init_tools_bundle(), tools_bundle_exports));
19740
19871
  const { registry: registry2 } = await Promise.resolve().then(() => (init_registry(), registry_exports));
19741
19872
  registry2.config = config;
19873
+ const { liveConfig: liveConfig2 } = await Promise.resolve().then(() => (init_live(), live_exports));
19874
+ liveConfig2.init(config);
19742
19875
  const { handleQuery: handleQuery2 } = await Promise.resolve().then(() => (init_handle_query(), handle_query_exports));
19743
19876
  const deps = {
19744
19877
  engine,
@@ -19754,6 +19887,14 @@ async function runQuery(args) {
19754
19887
  systemPrompt,
19755
19888
  channels: config.channels,
19756
19889
  config,
19890
+ // 0902 修2: recall 走 everos——之前 deps 没传 everosCfg,handle-query 每单打
19891
+ // "everosCfg not configured, falling back to LLM recall",sideQuery 拿整个任务
19892
+ // prompt 当查询词(查"赢男"召回"cc-run 协议")+ 拖 30-65s。装配对齐 engine-startup:680。
19893
+ everosCfg: config.everos ? {
19894
+ ...config.everos,
19895
+ llm: config.everos.llm?.provider && config.providers?.[config.everos.llm.provider] ? { ...config.everos.llm, apiKey: config.providers[config.everos.llm.provider].apiKey } : config.everos.llm,
19896
+ rerank: config.everos.rerank?.provider && config.providers?.[config.everos.rerank.provider] ? { ...config.everos.rerank, apiKey: config.providers[config.everos.rerank.provider].apiKey } : config.everos.rerank
19897
+ } : void 0,
19757
19898
  mcpManager: void 0
19758
19899
  };
19759
19900
  let thinking = "";
@@ -19777,8 +19918,8 @@ async function runQuery(args) {
19777
19918
  // channelTarget
19778
19919
  void 0,
19779
19920
  // inboundMeta
19780
- void 0,
19781
- // skipRecall
19921
+ args.noRecall || /quick-create assistant/i.test(args.prompt),
19922
+ // skipRecall(--no-recall 或建单任务自动跳过:daemon 拼的 quick-create prompt 是机械转述,recall sideQuery 在子进程里拖 30-65s)
19782
19923
  "cc-run"
19783
19924
  // source
19784
19925
  );