@modelzen/feishu-codex-bridge 0.3.7-test.0 → 0.3.8

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.
Files changed (2) hide show
  1. package/dist/cli.js +53 -15
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -111,11 +111,13 @@ function getMaxConcurrentRuns(cfg) {
111
111
  function getPendingPolicy(cfg) {
112
112
  return cfg.preferences?.pendingPolicy === "queue" ? "queue" : "steer";
113
113
  }
114
+ var RUN_IDLE_TIMEOUT_MIN_SEC = 10;
115
+ var RUN_IDLE_TIMEOUT_MAX_SEC = 3600;
114
116
  function getRunIdleTimeoutMs(cfg) {
115
117
  const raw = cfg.preferences?.runIdleTimeoutSeconds;
116
118
  if (raw === 0) return void 0;
117
119
  if (typeof raw !== "number" || !Number.isFinite(raw) || raw < 0) return 12e4;
118
- const clamped = Math.min(Math.max(Math.floor(raw), 10), 1800);
120
+ const clamped = Math.min(Math.max(Math.floor(raw), RUN_IDLE_TIMEOUT_MIN_SEC), RUN_IDLE_TIMEOUT_MAX_SEC);
119
121
  return clamped * 1e3;
120
122
  }
121
123
  function isChatAllowed(cfg, chatId) {
@@ -2004,14 +2006,14 @@ function markInterrupted(state) {
2004
2006
  footer: null
2005
2007
  };
2006
2008
  }
2007
- function markIdleTimeout(state, minutes) {
2009
+ function markIdleTimeout(state, seconds) {
2008
2010
  return {
2009
2011
  ...state,
2010
2012
  blocks: closeStreamingText(state.blocks),
2011
2013
  reasoningActive: false,
2012
2014
  terminal: "idle_timeout",
2013
2015
  footer: null,
2014
- idleTimeoutMinutes: minutes
2016
+ idleTimeoutSeconds: seconds
2015
2017
  };
2016
2018
  }
2017
2019
  function finalizeIfRunning(state) {
@@ -2042,8 +2044,8 @@ var RunRender = class {
2042
2044
  return this.state.terminal;
2043
2045
  }
2044
2046
  /** Mark the run as watchdog-killed (idle timeout). */
2045
- timeout(minutes) {
2046
- this.state = markIdleTimeout(this.state, minutes);
2047
+ timeout(seconds) {
2048
+ this.state = markIdleTimeout(this.state, seconds);
2047
2049
  }
2048
2050
  /** Mark the run as user-interrupted (⏹). */
2049
2051
  interrupt() {
@@ -2691,7 +2693,9 @@ function renderTerminal(state, rc) {
2691
2693
  if (state.terminal === "interrupted") {
2692
2694
  elements.push(noteMd("_\u23F9 \u5DF2\u88AB\u4E2D\u65AD_"));
2693
2695
  } else if (state.terminal === "idle_timeout") {
2694
- elements.push(noteMd(`_\u23F1 ${state.idleTimeoutMinutes ?? 0} \u5206\u949F\u65E0\u54CD\u5E94\uFF0C\u5DF2\u81EA\u52A8\u7EC8\u6B62_`));
2696
+ const s = state.idleTimeoutSeconds ?? 0;
2697
+ const idleLabel = s > 0 && s % 60 === 0 ? `${s / 60} \u5206\u949F` : `${s} \u79D2`;
2698
+ elements.push(noteMd(`_\u23F1 ${idleLabel}\u65E0\u54CD\u5E94\uFF0C\u5DF2\u81EA\u52A8\u7EC8\u6B62_`));
2695
2699
  } else if (state.terminal === "error" && state.errorMsg) {
2696
2700
  elements.push(noteMd(`\u26A0\uFE0F agent \u5931\u8D25\uFF1A${state.errorMsg}`));
2697
2701
  } else if (state.terminal === "done" && !answer) {
@@ -3266,6 +3270,9 @@ var DM = {
3266
3270
  rmCancel: "dm.rmCancel",
3267
3271
  setTools: "dm.set.tools",
3268
3272
  setWatchdog: "dm.set.watchdog",
3273
+ // 假死超时「自定义…」:watchdogCustom 打开输入卡,watchdogCustomSubmit 保存任意秒数
3274
+ watchdogCustom: "dm.set.watchdog.custom",
3275
+ watchdogCustomSubmit: "dm.set.watchdog.customSubmit",
3269
3276
  setPending: "dm.set.pending",
3270
3277
  setConcurrency: "dm.set.concurrency",
3271
3278
  // 权限管理:全局 admins(settings 卡进入)+ 项目响应白名单(项目列表 / 建项目完成卡进入)
@@ -3624,11 +3631,12 @@ function buildSettingsCard(cfg) {
3624
3631
  { label: "\u663E\u793A", value: "on" },
3625
3632
  { label: "\u9690\u85CF", value: "off" }
3626
3633
  ]),
3627
- ...optionRow("\u23F1 \u5047\u6B7B\u8D85\u65F6", DM.setWatchdog, String(watchdogSec), [
3628
- { label: "\u5173\u95ED", value: "0" },
3629
- { label: "60\u79D2", value: "60" },
3630
- { label: "120\u79D2", value: "120" },
3631
- { label: "300\u79D2", value: "300" }
3634
+ md(`\u23F1 \u5047\u6B7B\u8D85\u65F6\uFF08\u5F53\u524D **${watchdogSec === 0 ? "\u5173\u95ED" : `${watchdogSec} \u79D2`}**\uFF09`),
3635
+ actions([
3636
+ ...[0, 120, 300].map(
3637
+ (v) => button(v === 0 ? "\u5173\u95ED" : `${v}\u79D2`, { a: DM.setWatchdog, v: String(v) }, v === watchdogSec ? "primary" : "default")
3638
+ ),
3639
+ button("\u81EA\u5B9A\u4E49\u2026", { a: DM.watchdogCustom })
3632
3640
  ]),
3633
3641
  ...optionRow("\u{1F4E5} \u8FD0\u884C\u4E2D\u65B0\u6D88\u606F", DM.setPending, getPendingPolicy(cfg), [
3634
3642
  { label: "\u5F15\u5BFC", value: "steer" },
@@ -3640,13 +3648,30 @@ function buildSettingsCard(cfg) {
3640
3648
  { label: "10", value: "10" },
3641
3649
  { label: "20", value: "20" }
3642
3650
  ]),
3643
- note("\u26A0\uFE0F \u5047\u6B7B\u8D85\u65F6 / \u5E76\u53D1\u4E0A\u9650 \u6539\u540E\u9700**\u91CD\u542F**\u751F\u6548\uFF1B\u5DE5\u5177\u663E\u793A / \u8FD0\u884C\u4E2D\u65B0\u6D88\u606F \u5373\u65F6\u751F\u6548\u3002"),
3651
+ note("\u26A0\uFE0F \u5E76\u53D1\u4E0A\u9650 \u6539\u540E\u9700**\u91CD\u542F**\u751F\u6548\uFF1B\u5176\u4F59\u8BBE\u7F6E\uFF08\u542B\u5047\u6B7B\u8D85\u65F6\uFF09\u5373\u65F6\u751F\u6548\uFF0C\u6240\u6709\u7FA4\u7ACB\u5373\u5957\u7528\u3002"),
3644
3652
  hr(),
3645
3653
  actions([button("\u{1F46E} \u7BA1\u7406\u5458", { a: DM.admins }), button("\u2B05\uFE0F \u83DC\u5355", { a: DM.menu })])
3646
3654
  ],
3647
3655
  { header: { title: "\u2699\uFE0F \u8BBE\u7F6E", template: "blue" } }
3648
3656
  );
3649
3657
  }
3658
+ function buildWatchdogCustomCard(cfg) {
3659
+ const cur = cfg.preferences?.runIdleTimeoutSeconds ?? 120;
3660
+ return card(
3661
+ [
3662
+ md("**\u81EA\u5B9A\u4E49\u5047\u6B7B\u8D85\u65F6**"),
3663
+ note(
3664
+ `\u591A\u5C11\u79D2\u6CA1\u6709\u4EFB\u4F55\u8F93\u51FA\u5C31\u81EA\u52A8\u7EC8\u6B62\u672C\u8F6E\u3002\u8303\u56F4 ${RUN_IDLE_TIMEOUT_MIN_SEC}\u2013${RUN_IDLE_TIMEOUT_MAX_SEC} \u79D2\uFF1B\u586B 0 \u5173\u95ED\u3002`
3665
+ ),
3666
+ form("watchdog_custom", [
3667
+ input({ name: "sec", label: "\u8D85\u65F6\u79D2\u6570", placeholder: "\u4F8B\u5982 600", value: String(cur), required: true }),
3668
+ actions([submitButton("\u2705 \u4FDD\u5B58", { a: DM.watchdogCustomSubmit }, "primary", "submit_watchdog")])
3669
+ ]),
3670
+ actions([button("\u2B05\uFE0F \u8FD4\u56DE\u8BBE\u7F6E", { a: DM.settings })])
3671
+ ],
3672
+ { header: { title: "\u23F1 \u81EA\u5B9A\u4E49\u8D85\u65F6", template: "blue" } }
3673
+ );
3674
+ }
3650
3675
  function buildGroupSettingsCard(project) {
3651
3676
  const kind = project.kind ?? "multi";
3652
3677
  const noMention = project.noMention ?? defaultNoMention(project);
@@ -6093,7 +6118,7 @@ function createOrchestrator(channel, cfg, fallbackCwd) {
6093
6118
  const active = /* @__PURE__ */ new Map();
6094
6119
  const docLocks = /* @__PURE__ */ new Map();
6095
6120
  const sema = new Semaphore(getMaxConcurrentRuns(cfg));
6096
- const idleMs = getRunIdleTimeoutMs(cfg) ?? 0;
6121
+ const currentIdleMs = () => getRunIdleTimeoutMs(cfg) ?? 0;
6097
6122
  const resumePending = /* @__PURE__ */ new Map();
6098
6123
  const modelPending = /* @__PURE__ */ new Map();
6099
6124
  const runsByCard = /* @__PURE__ */ new Map();
@@ -6875,6 +6900,18 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
6875
6900
  }).on(DM.setWatchdog, ({ evt, value }) => {
6876
6901
  const n = Number(value.v);
6877
6902
  if (Number.isFinite(n)) applyPref(evt, (p) => p.runIdleTimeoutSeconds = n);
6903
+ }).on(DM.watchdogCustom, ({ evt }) => {
6904
+ if (!dmAdmin(evt.operator?.openId)) return;
6905
+ void patch(evt, buildWatchdogCustomCard(cfg));
6906
+ }).on(DM.watchdogCustomSubmit, ({ evt, formValue }) => {
6907
+ const raw = String(formValue?.sec ?? "").trim();
6908
+ const n = Number(raw);
6909
+ if (!Number.isFinite(n) || n < 0) {
6910
+ void patch(evt, buildWatchdogCustomCard(cfg));
6911
+ return;
6912
+ }
6913
+ const sec = n === 0 ? 0 : Math.min(Math.max(Math.floor(n), RUN_IDLE_TIMEOUT_MIN_SEC), RUN_IDLE_TIMEOUT_MAX_SEC);
6914
+ applyPref(evt, (p) => p.runIdleTimeoutSeconds = sec);
6878
6915
  }).on(DM.setPending, ({ evt, value }) => {
6879
6916
  if (value.v === "steer" || value.v === "queue") applyPref(evt, (p) => p.pendingPolicy = value.v);
6880
6917
  }).on(DM.setConcurrency, ({ evt, value }) => {
@@ -7158,6 +7195,7 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
7158
7195
  interrupted = true;
7159
7196
  resolveStop();
7160
7197
  };
7198
+ const idleMs = currentIdleMs();
7161
7199
  const guarded = withIdleTimeout(
7162
7200
  run.events,
7163
7201
  idleMs,
@@ -7191,7 +7229,7 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
7191
7229
  await stream2.drain();
7192
7230
  state.interrupt = void 0;
7193
7231
  const killed = interrupted || timedOut;
7194
- if (timedOut) render.timeout(Math.max(1, Math.round(idleMs / 6e4)));
7232
+ if (timedOut) render.timeout(Math.round(idleMs / 1e3));
7195
7233
  else if (interrupted) render.interrupt();
7196
7234
  else render.finalize();
7197
7235
  rc.rs = render.snapshot();
@@ -7284,7 +7322,7 @@ ${tail}` }, { replyTo: evt.messageId }).catch(() => void 0);
7284
7322
  const run = thread.runStreamed({ text: prompt }, { model: rec?.model, effort: rec?.effort });
7285
7323
  let state = initialState;
7286
7324
  let timedOut = false;
7287
- const guarded = withIdleTimeout(run.events, idleMs, () => {
7325
+ const guarded = withIdleTimeout(run.events, currentIdleMs(), () => {
7288
7326
  timedOut = true;
7289
7327
  });
7290
7328
  for await (const ev of guarded) state = reduce(state, ev);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelzen/feishu-codex-bridge",
3
- "version": "0.3.7-test.0",
3
+ "version": "0.3.8",
4
4
  "description": "Bridge Feishu/Lark messenger with local Codex via app-server (project=group, thread=session)",
5
5
  "type": "module",
6
6
  "bin": {