@vibe-lark/larkpal 0.1.23 → 0.1.24

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/main.mjs +37 -11
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -435,7 +435,10 @@ var CCStreamParser = class extends EventEmitter {
435
435
  this.handleResult(msg);
436
436
  break;
437
437
  case "system":
438
- log$28.info("收到 system 消息", { subtype: msg.subtype });
438
+ log$28.info("收到 system 消息", {
439
+ subtype: msg.subtype,
440
+ detail: JSON.stringify(msg).slice(0, 500)
441
+ });
439
442
  this.emit("system", msg);
440
443
  break;
441
444
  default:
@@ -4615,6 +4618,7 @@ function sortTraceValue(value) {
4615
4618
  //#endregion
4616
4619
  //#region src/card/cc-stream-bridge.ts
4617
4620
  const log$18 = larkLogger("card/cc-stream-bridge");
4621
+ const CC_INTERNAL_PLACEHOLDER = "No response requested.";
4618
4622
  /**
4619
4623
  * CCStreamBridge — 将 CC 流事件桥接到 StreamingCardController
4620
4624
  *
@@ -4733,6 +4737,15 @@ var CCStreamBridge = class {
4733
4737
  accumulatedThinkingTextLen: this.accumulatedThinkingText.length
4734
4738
  });
4735
4739
  if (this.options.autoCompleteOnTurnEnd && stopReason === "end_turn") {
4740
+ const trimmedText = this.accumulatedText.trim();
4741
+ if (trimmedText === CC_INTERNAL_PLACEHOLDER || trimmedText === "") {
4742
+ log$18.info("检测到 CC 内部占位消息,静默丢弃", {
4743
+ text: trimmedText.slice(0, 50),
4744
+ sessionKey: this.options.sessionKey
4745
+ });
4746
+ this.controller.abortCard();
4747
+ return;
4748
+ }
4736
4749
  this.controller.markFullyComplete();
4737
4750
  this.controller.onIdle();
4738
4751
  }
@@ -8761,7 +8774,8 @@ async function dispatchToCC(params) {
8761
8774
  const isGroup = chatType === "group";
8762
8775
  const replyInThread = !!threadId;
8763
8776
  const replyToMessageId = threadId ? void 0 : ctx.messageId;
8764
- const textPrompt = formatForCC(ctx, isGroup);
8777
+ let textPrompt = formatForCC(ctx, isGroup);
8778
+ if (isGroup) textPrompt = `[直接@你的消息,请正常回复] ${textPrompt}`;
8765
8779
  const imageResources = ctx.resources.filter((r) => r.type === "image");
8766
8780
  let prompt = textPrompt;
8767
8781
  if (imageResources.length > 0) {
@@ -9007,6 +9021,9 @@ async function dispatchToCC(params) {
9007
9021
  chatId,
9008
9022
  replyToMessageId: cardDeps.replyToMessageId
9009
9023
  });
9024
+ cardController.ensureCardCreated().catch((err) => {
9025
+ log$11.warn("提前创建卡片失败(streaming 回调会重试)", { error: String(err) });
9026
+ });
9010
9027
  const bridge = new CCStreamBridge(cardController, {
9011
9028
  autoCompleteOnTurnEnd: true,
9012
9029
  sessionKey: route.sessionId
@@ -9133,7 +9150,8 @@ async function dispatchTeammateEval(params) {
9133
9150
  const teammateSessionKey = `teammate_${route.sessionId}`;
9134
9151
  startToolUseTraceRun(teammateSessionKey);
9135
9152
  const NO_REPLY_TOKEN = SILENT_REPLY_TOKEN;
9136
- const PREFIX_LEN = NO_REPLY_TOKEN.length;
9153
+ const CC_INTERNAL_PLACEHOLDER = "No response requested.";
9154
+ const PREFIX_LEN = 22;
9137
9155
  /** 缓冲的 thinking 内容 */
9138
9156
  let thinkingBuffer = "";
9139
9157
  /** text 前缀缓冲(用于判断是否为 NO_REPLY) */
@@ -9206,15 +9224,22 @@ async function dispatchTeammateEval(params) {
9206
9224
  }
9207
9225
  textPrefixBuffer += text;
9208
9226
  if (textPrefixBuffer.length >= PREFIX_LEN) {
9209
- if (textPrefixBuffer.trim() === NO_REPLY_TOKEN) {
9227
+ const trimmed = textPrefixBuffer.trim();
9228
+ if (trimmed === NO_REPLY_TOKEN || trimmed === CC_INTERNAL_PLACEHOLDER) {
9210
9229
  silenced = true;
9211
- log$11.info("teammate 前缀检测: NO_REPLY", { chatId });
9230
+ log$11.info("teammate 前缀检测: 静默", {
9231
+ chatId,
9232
+ trimmed: trimmed.slice(0, 30)
9233
+ });
9212
9234
  return;
9213
9235
  }
9214
9236
  confirmReply();
9215
9237
  return;
9216
9238
  }
9217
- if (!NO_REPLY_TOKEN.startsWith(textPrefixBuffer.trim())) confirmReply();
9239
+ const currentTrimmed = textPrefixBuffer.trim();
9240
+ const couldBeNoReply = NO_REPLY_TOKEN.startsWith(currentTrimmed);
9241
+ const couldBePlaceholder = CC_INTERNAL_PLACEHOLDER.startsWith(currentTrimmed);
9242
+ if (!couldBeNoReply && !couldBePlaceholder) confirmReply();
9218
9243
  };
9219
9244
  try {
9220
9245
  await new Promise((resolve) => {
@@ -9261,11 +9286,11 @@ async function dispatchTeammateEval(params) {
9261
9286
  }
9262
9287
  if (!confirmed && !silenced) {
9263
9288
  const trimmed = textPrefixBuffer.trim();
9264
- if (trimmed === NO_REPLY_TOKEN || trimmed === "") {
9289
+ if (trimmed === NO_REPLY_TOKEN || trimmed === CC_INTERNAL_PLACEHOLDER || trimmed === "") {
9265
9290
  silenced = true;
9266
- log$11.info("teammate turnEnd 最终判断: NO_REPLY", {
9291
+ log$11.info("teammate turnEnd 最终判断: 静默", {
9267
9292
  chatId,
9268
- trimmed
9293
+ trimmed: trimmed.slice(0, 30)
9269
9294
  });
9270
9295
  } else {
9271
9296
  confirmReply();
@@ -11976,9 +12001,10 @@ var TeammateBuffer = class {
11976
12001
  */
11977
12002
  buildEvalPrompt(messages) {
11978
12003
  const header = [
11979
- "[系统提示] 以下是群聊中最近的对话,你作为团队成员正在旁听。",
11980
- "请判断是否需要参与讨论。如果不需要,只输出 NO_REPLY。",
12004
+ "[旁听评估任务] 以下是群聊中最近的对话,你作为团队成员正在旁听。",
12005
+ "请判断是否需要主动参与讨论。如果不需要,只输出 NO_REPLY。",
11981
12006
  "如果需要参与,直接输出你的回复内容。",
12007
+ "注意:这是一次旁听评估,仅在本次评估中适用 NO_REPLY 规则。后续如果用户直接 @你 则必须正常回复。",
11982
12008
  "",
11983
12009
  "---"
11984
12010
  ].join("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-lark/larkpal",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "LarkPal - Lark/Feishu bot service",
5
5
  "type": "module",
6
6
  "main": "./dist/main.mjs",