@ycodium-ai/plugin-im 0.2.2978 → 0.2.2984

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 +86 -32
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -128602,9 +128602,8 @@ var makeInbound = (core, deps) => {
128602
128602
  );
128603
128603
  const projectPromptCooldown = makeCooldown(PROJECT_PROMPT_COOLDOWN_MS, () => Date.now());
128604
128604
  const handledMessages = makeBoundedSeen(SEEN_MESSAGE_LIMIT);
128605
- const alreadyHandled = (target2, messageId) => {
128606
- return !handledMessages.claim(`${chatKeyOf(target2)}:${messageId}`);
128607
- };
128605
+ const alreadyHandled = (key) => !handledMessages.claim(key);
128606
+ const claimCallback = (rowId, callbackId) => callbackId === void 0 || callbackId === "" || !alreadyHandled(`c:${rowId}:${callbackId}`);
128608
128607
  const turnAwayStranger = (target2, sender) => {
128609
128608
  host.log.warn("chat ignored a message from someone not on the allow list", {
128610
128609
  bot: target2.displayName,
@@ -128651,10 +128650,14 @@ var makeInbound = (core, deps) => {
128651
128650
  bot: bot.displayName,
128652
128651
  message
128653
128652
  }),
128654
- onButton: handleButtonClick,
128653
+ onButton: (token, operatorId, callbackId) => {
128654
+ if (!claimCallback(bot.rowId, callbackId)) return null;
128655
+ return handleButtonClick(token, operatorId);
128656
+ },
128655
128657
  onPanelClick: (click) => {
128656
128658
  const current = currentBot(bot.rowId);
128657
- return current === void 0 ? null : handlePanelClick(current, click);
128659
+ if (current === void 0 || !claimCallback(current.rowId, click.callbackId)) return null;
128660
+ return handlePanelClick(current, click);
128658
128661
  },
128659
128662
  noteChatAlias: (alias, chatId) => noteChatAlias(bot, alias, chatId),
128660
128663
  knowsChatAlias: (alias) => chatAliasOf(core.state, bot.rowId, alias) !== void 0,
@@ -128663,7 +128666,7 @@ var makeInbound = (core, deps) => {
128663
128666
  if (current === void 0) return;
128664
128667
  const message = settleChat(current, received);
128665
128668
  const arrived = bindingOf2(current, message.chatId);
128666
- if (alreadyHandled(arrived, message.messageId)) return;
128669
+ if (alreadyHandled(`m:${chatKeyOf(arrived)}:${message.messageId}`)) return;
128667
128670
  if (message.chatKind !== void 0 && chatOf(core.state, chatKeyOf(arrived)).chatKind !== message.chatKind) {
128668
128671
  commit("chat-updated", { chatKey: chatKeyOf(arrived), chatKind: message.chatKind });
128669
128672
  }
@@ -140136,12 +140139,22 @@ var makeReplyCards = (core, failures, anchors) => {
140136
140139
  const cards = binding === void 0 ? void 0 : adapterFor(binding.platform)?.turnCards;
140137
140140
  if (binding === void 0 || cards === void 0) return null;
140138
140141
  let anchored;
140142
+ const chatKey = chatKeyOf(binding);
140139
140143
  return {
140140
- chatKey: chatKeyOf(binding),
140144
+ chatKey,
140141
140145
  throttleMs: cards.throttleMs,
140142
140146
  rotates: cards.rotatesOnInteraction === true,
140143
140147
  open: async (view) => cards.open(await (anchored ??= anchors.anchored(binding, threadId, turnId)), view),
140144
- update: (cardId, view) => cards.update(binding, cardId, view)
140148
+ // 每次改卡按聊天键重取机器人的配置:开卡时那份上的令牌和代理会过期。卡是哪个平台的开卡时就定了:
140149
+ // 机器人行已经不在、或被改成了别的平台,就用原来那份——别的平台的配置不能交给这个平台的适配器。
140150
+ update: (cardId, view) => {
140151
+ const current = bindingForChatKey(chatKey);
140152
+ return cards.update(
140153
+ current?.platform === binding.platform ? current : binding,
140154
+ cardId,
140155
+ view
140156
+ );
140157
+ }
140145
140158
  };
140146
140159
  },
140147
140160
  readText: async (messageId) => (await host.projections.getThreadMessage(messageId))?.text ?? null,
@@ -140824,11 +140837,11 @@ var makeTelegramApi = (input) => {
140824
140837
  * `allowed_updates` 必须列全:它是服务端白名单,不写 `callback_query` 的话按钮点击
140825
140838
  * 根本不会投递过来,而且不会有任何报错。
140826
140839
  */
140827
- getUpdates: (offset) => call(
140840
+ getUpdates: (offset, timeoutSeconds = POLL_TIMEOUT_SECONDS) => call(
140828
140841
  "getUpdates",
140829
140842
  {
140830
140843
  offset,
140831
- timeout: POLL_TIMEOUT_SECONDS,
140844
+ timeout: timeoutSeconds,
140832
140845
  allowed_updates: ["message", "callback_query"]
140833
140846
  },
140834
140847
  POLL_CALL_TIMEOUT_MS
@@ -141128,7 +141141,8 @@ var makeTelegramAdapter = (deps) => {
141128
141141
  cardId: String(messageId),
141129
141142
  operatorId,
141130
141143
  op: action.op,
141131
- arg: action.arg ?? null
141144
+ arg: action.arg ?? null,
141145
+ callbackId: callback.id
141132
141146
  }) ?? null;
141133
141147
  };
141134
141148
  const apiFor = (binding) => {
@@ -141144,20 +141158,24 @@ var makeTelegramAdapter = (deps) => {
141144
141158
  });
141145
141159
  return api;
141146
141160
  };
141147
- const makeWriter = (api, chatId, resume) => makeTurnWriter({
141161
+ const makeWriter = (slot, chatId, resume) => makeTurnWriter({
141148
141162
  t,
141149
141163
  limit: TELEGRAM_TEXT_MAX_CHARS,
141150
141164
  ...resume === void 0 ? {} : { resume },
141151
141165
  messages: {
141152
141166
  send: (text3) => withRichFallback(
141153
141167
  toTelegramRichMarkdown(text3),
141154
- (markdown) => api.sendRichOne(chatId, markdown),
141155
- () => api.sendOne(chatId, text3)
141168
+ async (markdown) => (await apiFor(slot.binding)).sendRichOne(chatId, markdown),
141169
+ async () => (await apiFor(slot.binding)).sendOne(chatId, text3)
141156
141170
  ),
141157
141171
  edit: (messageId, text3) => withRichFallback(
141158
141172
  toTelegramRichMarkdown(text3),
141159
- (markdown) => api.editRich(chatId, messageId, markdown),
141160
- () => api.editMessage(chatId, messageId, text3)
141173
+ async (markdown) => {
141174
+ await (await apiFor(slot.binding)).editRich(chatId, messageId, markdown);
141175
+ },
141176
+ async () => {
141177
+ await (await apiFor(slot.binding)).editMessage(chatId, messageId, text3);
141178
+ }
141161
141179
  )
141162
141180
  }
141163
141181
  });
@@ -141174,19 +141192,31 @@ var makeTelegramAdapter = (deps) => {
141174
141192
  const stopped = new Promise((resolve) => stop = resolve);
141175
141193
  let running = true;
141176
141194
  let offset = 0;
141195
+ let acknowledged = 0;
141177
141196
  let backoff = BACKOFF_START_MS;
141178
141197
  let botUsername;
141179
141198
  let menuSent = false;
141199
+ let liveApi;
141180
141200
  const isSoloGroup = makeSoloGroupCheck(async (chatId) => {
141181
141201
  const count = await (await apiFor(binding)).getChatMemberCount(chatId);
141182
141202
  return Number.isFinite(count) ? count <= 2 : void 0;
141183
141203
  });
141204
+ const publishAck = () => {
141205
+ const api = liveApi;
141206
+ if (api === void 0 || offset <= acknowledged) return;
141207
+ const next = offset;
141208
+ acknowledged = next;
141209
+ void api.getUpdates(next, 0).catch(() => void 0);
141210
+ };
141184
141211
  const poll = async () => {
141185
141212
  for (; ; ) {
141186
141213
  if (!running) return;
141187
141214
  try {
141188
141215
  const api = await apiFor(binding);
141216
+ liveApi = api;
141217
+ if (!running) return;
141189
141218
  botUsername ??= (await api.getMe()).username ?? null;
141219
+ if (!running) return;
141190
141220
  if (!menuSent) {
141191
141221
  menuSent = true;
141192
141222
  void api.setMyCommands(telegramCommandMenu(t)).catch((error) => {
@@ -141196,26 +141226,34 @@ var makeTelegramAdapter = (deps) => {
141196
141226
  });
141197
141227
  });
141198
141228
  }
141229
+ acknowledged = offset;
141199
141230
  const updates = await api.getUpdates(offset);
141200
141231
  if (!running) return;
141201
141232
  backoff = BACKOFF_START_MS;
141202
- offset = nextOffset(updates, offset);
141203
141233
  for (const update of updates) {
141234
+ if (!running) break;
141204
141235
  const callback = update.callback_query;
141205
141236
  if (callback?.data !== void 0) {
141206
141237
  const operatorId = callback.from === void 0 ? null : String(callback.from.id);
141207
- const notice = callback.data.startsWith(PANEL_DATA_PREFIX) ? panelClick(binding.rowId, callback, operatorId, handlers) : handlers.onButton(callback.data, operatorId);
141238
+ const notice = callback.data.startsWith(PANEL_DATA_PREFIX) ? panelClick(binding.rowId, callback, operatorId, handlers) : handlers.onButton(callback.data, operatorId, callback.id);
141239
+ offset = nextOffset([update], offset);
141208
141240
  await api.answerCallback(callback.id, notice ?? void 0).catch(() => void 0);
141209
141241
  continue;
141210
141242
  }
141211
141243
  const message = update.message;
141212
- if (message === void 0) continue;
141244
+ if (message === void 0) {
141245
+ offset = nextOffset([update], offset);
141246
+ continue;
141247
+ }
141213
141248
  const resource = resourceOf2(message);
141214
141249
  const text3 = commandForBot(
141215
141250
  (message.text ?? message.caption ?? "").trim(),
141216
141251
  botUsername
141217
141252
  );
141218
- if (text3 === null) continue;
141253
+ if (text3 === null) {
141254
+ offset = nextOffset([update], offset);
141255
+ continue;
141256
+ }
141219
141257
  const gated = !passesGroupGate2({
141220
141258
  message,
141221
141259
  text: text3,
@@ -141223,18 +141261,27 @@ var makeTelegramAdapter = (deps) => {
141223
141261
  botUsername: botUsername ?? null,
141224
141262
  groupMention: binding.groupMention
141225
141263
  });
141226
- if (gated && !(binding.groupMention === "always" && await isSoloGroup(String(message.chat.id)))) {
141227
- continue;
141264
+ if (gated) {
141265
+ const solo = binding.groupMention === "always" && await isSoloGroup(String(message.chat.id));
141266
+ if (!running) break;
141267
+ if (!solo) {
141268
+ offset = nextOffset([update], offset);
141269
+ continue;
141270
+ }
141228
141271
  }
141272
+ if (!running) break;
141273
+ offset = nextOffset([update], offset);
141274
+ const senderId = message.from === void 0 ? null : String(message.from.id);
141275
+ const chatKind = message.chat.type === "private" ? "private" : "group";
141229
141276
  if (text3 === "" && resource === null) {
141230
141277
  const unsupported = unsupportedTypeOf(message);
141231
141278
  if (unsupported === null) continue;
141232
141279
  handlers.onMessage({
141233
141280
  messageId: String(message.message_id),
141234
141281
  chatId: chatIdOf(message),
141235
- senderId: message.from === void 0 ? null : String(message.from.id),
141282
+ senderId,
141236
141283
  text: "",
141237
- chatKind: message.chat.type === "private" ? "private" : "group",
141284
+ chatKind,
141238
141285
  resources: [],
141239
141286
  unsupportedType: unsupported
141240
141287
  });
@@ -141245,9 +141292,9 @@ var makeTelegramAdapter = (deps) => {
141245
141292
  messageId: String(message.message_id),
141246
141293
  chatId: chatIdOf(message),
141247
141294
  ...parentChatId === void 0 ? {} : { parentChatId },
141248
- senderId: message.from === void 0 ? null : String(message.from.id),
141295
+ senderId,
141249
141296
  text: text3,
141250
- chatKind: message.chat.type === "private" ? "private" : "group",
141297
+ chatKind,
141251
141298
  resources: resource === null ? [] : [
141252
141299
  {
141253
141300
  key: resource.fileId,
@@ -141273,6 +141320,7 @@ var makeTelegramAdapter = (deps) => {
141273
141320
  close: () => {
141274
141321
  running = false;
141275
141322
  stop();
141323
+ publishAck();
141276
141324
  apis.delete(binding.rowId);
141277
141325
  }
141278
141326
  };
@@ -141383,8 +141431,8 @@ ${line}`
141383
141431
  turnCards: {
141384
141432
  throttleMs: TELEGRAM_CARD_THROTTLE_MS,
141385
141433
  open: async (binding, view) => {
141386
- const api = await apiFor(binding);
141387
- const writer = makeWriter(api, binding.chatId);
141434
+ const slot = { binding };
141435
+ const writer = makeWriter(slot, binding.chatId);
141388
141436
  try {
141389
141437
  await writer.write(view);
141390
141438
  } catch (error) {
@@ -141395,16 +141443,22 @@ ${line}`
141395
141443
  }
141396
141444
  const cardId = writer.firstId();
141397
141445
  if (cardId !== null && view.status === "working") {
141398
- turnWriters.set(`${binding.rowId}:${binding.chatId}:${cardId}`, writer);
141446
+ turnWriters.set(`${binding.rowId}:${binding.chatId}:${cardId}`, { slot, writer });
141399
141447
  }
141400
141448
  return cardId;
141401
141449
  },
141402
141450
  update: async (binding, cardId, view) => {
141403
141451
  const key = `${binding.rowId}:${binding.chatId}:${cardId}`;
141404
- const writer = turnWriters.get(key) ?? makeWriter(await apiFor(binding), binding.chatId, cardId);
141405
- await writer.write(view);
141452
+ let stored = turnWriters.get(key);
141453
+ if (stored === void 0) {
141454
+ const slot = { binding };
141455
+ stored = { slot, writer: makeWriter(slot, binding.chatId, cardId) };
141456
+ } else {
141457
+ stored.slot.binding = binding;
141458
+ }
141459
+ await stored.writer.write(view);
141406
141460
  if (view.status !== "working") turnWriters.delete(key);
141407
- else turnWriters.set(key, writer);
141461
+ else turnWriters.set(key, stored);
141408
141462
  }
141409
141463
  },
141410
141464
  panel: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/plugin-im",
3
- "version": "0.2.2978",
3
+ "version": "0.2.2984",
4
4
  "description": "Talk to your agents from Telegram, WeCom, Lark, or WeChat (experimental).",
5
5
  "keywords": [
6
6
  "im",
@@ -32,7 +32,7 @@
32
32
  "markdown-it": "^15.0.2",
33
33
  "react": "19.2.6",
34
34
  "vite-plus": "0.2.2",
35
- "@ycodium-ai/plugin-api": "0.2.2978"
35
+ "@ycodium-ai/plugin-api": "0.2.2984"
36
36
  },
37
37
  "ycodium": {
38
38
  "plugin": "./dist/index.js",