opencode-feishu-plugin 0.2.12 → 0.2.13

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/index.js +81 -24
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -146625,13 +146625,49 @@ function trailingText(blocks) {
146625
146625
  }
146626
146626
  return parts.join("\n\n").trim();
146627
146627
  }
146628
+ function isActivityEvent(type) {
146629
+ return type === "text.started" || type === "text.delta" || type === "text.ended" || type === "tool.input.started" || type === "tool.input.ended" || type === "tool.success" || type === "tool.error";
146630
+ }
146631
+ var QUEUED_DRAIN_GRACE_MS = 3e3;
146628
146632
  function createRunController(deps) {
146629
146633
  const sessions = /* @__PURE__ */ new Map();
146630
146634
  const throttlers = /* @__PURE__ */ new Map();
146631
146635
  const sessionModels = /* @__PURE__ */ new Map();
146632
146636
  const notifiedQueued = /* @__PURE__ */ new Set();
146637
+ const drainTimers = /* @__PURE__ */ new Map();
146633
146638
  const throttleMs = Math.max(400, deps.throttleMs);
146634
146639
  let disposed = false;
146640
+ const cancelDrain = (sessionID) => {
146641
+ const timer = drainTimers.get(sessionID);
146642
+ if (timer) {
146643
+ clearTimeout(timer);
146644
+ drainTimers.delete(sessionID);
146645
+ }
146646
+ };
146647
+ const scheduleDrain = (sessionID, runs) => {
146648
+ if (runs.queued.length === 0) {
146649
+ cancelDrain(sessionID);
146650
+ return;
146651
+ }
146652
+ cancelDrain(sessionID);
146653
+ const timer = setTimeout(() => {
146654
+ drainTimers.delete(sessionID);
146655
+ if (disposed) return;
146656
+ const live = sessions.get(sessionID);
146657
+ if (!live || live.queued.length === 0) return;
146658
+ deps.log.info("\u6392\u961F\u5361\u6309\u300C\u5DF2\u968F\u672C\u8F6E\u5904\u7406\u300D\u6536\u5C3E\uFF08\u961F\u5217\u6D88\u606F\u5728\u5F53\u524D\u6267\u884C\u5185\u88AB\u6D88\u8D39\uFF09", {
146659
+ sessionID,
146660
+ count: live.queued.length
146661
+ });
146662
+ for (const card of live.queued) {
146663
+ card.state = reduce6(card.state, { type: "execution.succeeded" });
146664
+ finalize2(card);
146665
+ }
146666
+ live.queued.length = 0;
146667
+ }, QUEUED_DRAIN_GRACE_MS);
146668
+ timer.unref?.();
146669
+ drainTimers.set(sessionID, timer);
146670
+ };
146635
146671
  const sessionRuns = (sessionID) => {
146636
146672
  let runs = sessions.get(sessionID);
146637
146673
  if (!runs) {
@@ -146739,6 +146775,7 @@ function createRunController(deps) {
146739
146775
  if (!runs) return;
146740
146776
  if (event.type === "execution.started") {
146741
146777
  notifiedQueued.delete(sessionID);
146778
+ cancelDrain(sessionID);
146742
146779
  if (runs.active) {
146743
146780
  update2(runs.active, event, true);
146744
146781
  return;
@@ -146746,40 +146783,52 @@ function createRunController(deps) {
146746
146783
  const next = runs.queued.shift();
146747
146784
  if (next) {
146748
146785
  runs.active = next;
146786
+ deps.log.debug("\u6392\u961F\u5361\u664B\u5347\u4E3A\u8FD0\u884C\u5361", { sessionID, runID: next.runID });
146749
146787
  update2(next, event, true);
146750
146788
  }
146789
+ if (runs.queued.length > 0) scheduleDrain(sessionID, runs);
146751
146790
  return;
146752
146791
  }
146792
+ if (!runs.active && runs.queued.length > 0 && isActivityEvent(event.type)) {
146793
+ const next = runs.queued.shift();
146794
+ runs.active = next;
146795
+ deps.log.info("\u6536\u5230\u6D3B\u52A8\u4E8B\u4EF6\u4F46\u65E0\u8FD0\u884C\u5361\uFF1A\u664B\u5347\u961F\u9996\u6392\u961F\u5361", {
146796
+ sessionID,
146797
+ runID: next.runID,
146798
+ event: event.type
146799
+ });
146800
+ next.state = reduce6(next.state, { type: "execution.started" });
146801
+ }
146753
146802
  const card = runs.active;
146754
- if (!card) return;
146755
- if (event.type === "execution.succeeded") {
146756
- const text = trailingText(card.state.blocks);
146757
- const long = deps.sendFinalAnswer !== void 0 && deps.finalAnswer !== void 0 && text.length >= deps.finalAnswer.minChars;
146758
- if (long) {
146759
- card.state = reduce6(reduce6(card.state, { type: "final.separated" }), event);
146803
+ if (event.type === "execution.succeeded" || event.type === "execution.failed") {
146804
+ if (card) {
146805
+ if (event.type === "execution.succeeded") {
146806
+ const text = trailingText(card.state.blocks);
146807
+ const long = deps.sendFinalAnswer !== void 0 && deps.finalAnswer !== void 0 && text.length >= deps.finalAnswer.minChars;
146808
+ if (long) {
146809
+ card.state = reduce6(reduce6(card.state, { type: "final.separated" }), event);
146810
+ finalize2(card);
146811
+ runs.active = void 0;
146812
+ void deps.sendFinalAnswer({
146813
+ sessionID,
146814
+ chatId: card.chatId,
146815
+ ...card.replyToMessageId ? { replyToMessageId: card.replyToMessageId } : {},
146816
+ text
146817
+ }).catch((err2) => {
146818
+ deps.log.warn("\u6700\u7EC8\u7B54\u6848\u53D1\u9001\u5931\u8D25", { sessionID, error: errorMessage(err2) });
146819
+ });
146820
+ scheduleDrain(sessionID, runs);
146821
+ return;
146822
+ }
146823
+ }
146824
+ update2(card, event, true);
146760
146825
  finalize2(card);
146761
146826
  runs.active = void 0;
146762
- void deps.sendFinalAnswer({
146763
- sessionID,
146764
- chatId: card.chatId,
146765
- ...card.replyToMessageId ? { replyToMessageId: card.replyToMessageId } : {},
146766
- text
146767
- }).catch((err2) => {
146768
- deps.log.warn("\u6700\u7EC8\u7B54\u6848\u53D1\u9001\u5931\u8D25", { sessionID, error: errorMessage(err2) });
146769
- });
146770
- return;
146771
146827
  }
146772
- update2(card, event, true);
146773
- finalize2(card);
146774
- runs.active = void 0;
146775
- return;
146776
- }
146777
- if (event.type === "execution.failed") {
146778
- update2(card, event, true);
146779
- finalize2(card);
146780
- runs.active = void 0;
146828
+ scheduleDrain(sessionID, runs);
146781
146829
  return;
146782
146830
  }
146831
+ if (!card) return;
146783
146832
  update2(card, event, false);
146784
146833
  },
146785
146834
  hasActive(sessionID) {
@@ -146818,6 +146867,8 @@ function createRunController(deps) {
146818
146867
  disposed = true;
146819
146868
  sessionModels.clear();
146820
146869
  notifiedQueued.clear();
146870
+ for (const timer of drainTimers.values()) clearTimeout(timer);
146871
+ drainTimers.clear();
146821
146872
  for (const throttler of throttlers.values()) throttler.cancel();
146822
146873
  throttlers.clear();
146823
146874
  for (const runs of sessions.values()) {
@@ -150916,18 +150967,21 @@ async function routeEvent(event, deps) {
150916
150967
  }
150917
150968
  case "session.execution.started": {
150918
150969
  const data = event.data;
150970
+ deps.log.debug("execution.started", { sessionID: data.sessionID });
150919
150971
  deps.markStarted(data.sessionID);
150920
150972
  deps.applyRun(data.sessionID, { type: "execution.started" });
150921
150973
  break;
150922
150974
  }
150923
150975
  case "session.execution.succeeded": {
150924
150976
  const data = event.data;
150977
+ deps.log.debug("execution.succeeded", { sessionID: data.sessionID });
150925
150978
  deps.markEnded(data.sessionID);
150926
150979
  deps.applyRun(data.sessionID, { type: "execution.succeeded" });
150927
150980
  break;
150928
150981
  }
150929
150982
  case "session.execution.failed": {
150930
150983
  const data = event.data;
150984
+ deps.log.debug("execution.failed", { sessionID: data.sessionID });
150931
150985
  deps.markEnded(data.sessionID);
150932
150986
  deps.applyRun(data.sessionID, { type: "execution.failed", error: extractErrorText(data.error) });
150933
150987
  void deps.notifyFailure(data.sessionID, data.error);
@@ -150935,6 +150989,7 @@ async function routeEvent(event, deps) {
150935
150989
  }
150936
150990
  case "session.execution.interrupted": {
150937
150991
  const data = event.data;
150992
+ deps.log.debug("execution.interrupted", { sessionID: data.sessionID, reason: data.reason });
150938
150993
  deps.markEnded(data.sessionID);
150939
150994
  deps.applyRun(data.sessionID, { type: "execution.failed", error: `\u5DF2\u4E2D\u65AD\uFF08${data.reason ?? "unknown"}\uFF09` });
150940
150995
  break;
@@ -150942,6 +150997,7 @@ async function routeEvent(event, deps) {
150942
150997
  case "session.status": {
150943
150998
  const data = event.data;
150944
150999
  const statusType = data.status?.type;
151000
+ deps.log.debug("session.status", { sessionID: data.sessionID, status: statusType });
150945
151001
  if (statusType === "idle") {
150946
151002
  deps.markEnded(data.sessionID);
150947
151003
  deps.applyRun(data.sessionID, { type: "execution.succeeded" });
@@ -150952,6 +151008,7 @@ async function routeEvent(event, deps) {
150952
151008
  }
150953
151009
  case "session.idle": {
150954
151010
  const data = event.data;
151011
+ deps.log.debug("session.idle", { sessionID: data.sessionID });
150955
151012
  deps.markEnded(data.sessionID);
150956
151013
  deps.applyRun(data.sessionID, { type: "execution.succeeded" });
150957
151014
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-feishu-plugin",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "description": "Feishu/Lark plugin for OpenCode V2 — single-user topics as sessions, in-card permission approvals, streaming cards. Minimal permissions, no public endpoint.",
5
5
  "type": "module",
6
6
  "main": "index.js",