@vibe-lark/larkpal 0.1.61 → 0.1.62

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 +89 -78
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -2785,7 +2785,85 @@ async function createLarkpalAgentAdapter() {
2785
2785
  });
2786
2786
  }
2787
2787
  else log$30.warn("未配置 LARKPAL_AGENT_MCP_SERVER_URL,Agent 无远程工具可用");
2788
- return adapter;
2788
+ return wrapLarkpalAgentAdapter(adapter);
2789
+ }
2790
+ function wrapLarkpalAgentAdapter(adapter) {
2791
+ return {
2792
+ get name() {
2793
+ return adapter.name;
2794
+ },
2795
+ executePrompt(config, callbacks) {
2796
+ return adapter.executePrompt(normalizeLarkpalAgentConfig(config), callbacks);
2797
+ },
2798
+ stopProcess(sessionId) {
2799
+ return adapter.stopProcess(sessionId);
2800
+ },
2801
+ stopAll() {
2802
+ return adapter.stopAll();
2803
+ },
2804
+ getProcessInfo(sessionId) {
2805
+ return adapter.getProcessInfo(sessionId);
2806
+ },
2807
+ getAllProcessInfo() {
2808
+ return adapter.getAllProcessInfo();
2809
+ },
2810
+ isSessionBusy(sessionId) {
2811
+ return adapter.isSessionBusy?.(sessionId) ?? false;
2812
+ }
2813
+ };
2814
+ }
2815
+ function normalizeLarkpalAgentConfig(config) {
2816
+ if (!Array.isArray(config.prompt)) return config;
2817
+ const textParts = [];
2818
+ const imageArtifacts = [];
2819
+ const imageLines = [];
2820
+ config.prompt.forEach((block, index) => {
2821
+ if (block.type === "text") {
2822
+ if (block.text.trim()) textParts.push(block.text);
2823
+ return;
2824
+ }
2825
+ if (block.type !== "image") return;
2826
+ const artifact = toAgentImageArtifact(block, index);
2827
+ const label = artifact?.assetId ?? block.fileKey ?? `image_${index + 1}`;
2828
+ if (artifact) imageArtifacts.push(artifact);
2829
+ imageLines.push(artifact ? `- ${label}: ${artifact.path} (${artifact.mimeType})` : `- ${label}: inline image omitted from text prompt (${block.source.media_type})`);
2830
+ });
2831
+ if (imageLines.length === 0) return config;
2832
+ const prompt = [
2833
+ textParts.join("\n\n").trim(),
2834
+ "[Images]",
2835
+ ...imageLines,
2836
+ "The user is asking about these image attachments. Use visual or file tools to inspect the image pixels when needed; do not infer image content from the file name alone."
2837
+ ].filter(Boolean).join("\n");
2838
+ return {
2839
+ ...config,
2840
+ prompt,
2841
+ sourceArtifacts: mergeSourceArtifacts(config.sourceArtifacts, imageArtifacts),
2842
+ metadata: {
2843
+ ...config.metadata,
2844
+ inboundImageCount: imageLines.length,
2845
+ visualAllowedDirs: [config.cwd]
2846
+ }
2847
+ };
2848
+ }
2849
+ function toAgentImageArtifact(block, index) {
2850
+ if (!block.filePath) return null;
2851
+ return {
2852
+ type: "image_asset",
2853
+ assetId: block.fileKey ?? `inbound_image_${index + 1}`,
2854
+ path: block.filePath,
2855
+ mimeType: block.source.media_type.split(";", 1)[0] || "image/png",
2856
+ metadata: {
2857
+ source: "feishu-message",
2858
+ fileKey: block.fileKey
2859
+ }
2860
+ };
2861
+ }
2862
+ function mergeSourceArtifacts(existing, imageArtifacts) {
2863
+ if (imageArtifacts.length === 0) return existing;
2864
+ if (existing === void 0) return imageArtifacts;
2865
+ if (Array.isArray(existing)) return [...existing, ...imageArtifacts];
2866
+ return [existing, ...imageArtifacts];
2789
2867
  }
2790
2868
  //#endregion
2791
2869
  //#region src/routing/session-router.ts
@@ -10877,26 +10955,6 @@ async function sendCardByCardId(params) {
10877
10955
  chatId: response?.data?.chat_id ?? ""
10878
10956
  };
10879
10957
  }
10880
- /**
10881
- * Close (or open) the streaming mode on a CardKit card.
10882
- *
10883
- * Must be called after streaming is complete to restore normal card
10884
- * behaviour (forwarding, interaction callbacks, etc.).
10885
- */
10886
- async function setCardStreamingMode(params) {
10887
- const { cfg, cardId, streamingMode, sequence, accountId } = params;
10888
- logCardKitResponse({
10889
- resp: await resolveLarkSdk(cfg, accountId).cardkit.v1.card.settings({
10890
- data: {
10891
- settings: JSON.stringify({ streaming_mode: streamingMode }),
10892
- sequence
10893
- },
10894
- path: { card_id: cardId }
10895
- }),
10896
- api: "card.settings",
10897
- context: `seq=${sequence}, streaming_mode=${streamingMode}`
10898
- });
10899
- }
10900
10958
  //#endregion
10901
10959
  //#region src/card/reply-dispatcher-types.ts
10902
10960
  const TERMINAL_PHASES = new Set([
@@ -11882,7 +11940,7 @@ var StreamingCardController = class StreamingCardController {
11882
11940
  footer: this.deps.resolvedFooter,
11883
11941
  footerMetrics
11884
11942
  });
11885
- if (errorEffectiveCardId) await this.closeStreamingAndUpdate(errorEffectiveCardId, errorCard, "onError");
11943
+ if (errorEffectiveCardId) await this.updateStreamingCard(errorEffectiveCardId, errorCard, "onError");
11886
11944
  else await updateCardFeishu({
11887
11945
  cfg: this.deps.cfg,
11888
11946
  messageId: this.cardKit.cardMessageId,
@@ -11950,20 +12008,6 @@ var StreamingCardController = class StreamingCardController {
11950
12008
  const FINAL_UPDATE_RETRY_DELAY_MS = 2e3;
11951
12009
  for (let attempt = 1; attempt <= MAX_FINAL_UPDATE_RETRIES; attempt++) try {
11952
12010
  if (idleEffectiveCardId) {
11953
- const seqBeforeClose = this.cardKit.cardKitSequence;
11954
- this.cardKit.cardKitSequence += 1;
11955
- log$16.info("onIdle: closing streaming mode", {
11956
- attempt,
11957
- seqBefore: seqBeforeClose,
11958
- seqAfter: this.cardKit.cardKitSequence
11959
- });
11960
- await setCardStreamingMode({
11961
- cfg: this.deps.cfg,
11962
- cardId: idleEffectiveCardId,
11963
- streamingMode: false,
11964
- sequence: this.cardKit.cardKitSequence,
11965
- accountId: this.deps.accountId
11966
- });
11967
12011
  const seqBeforeUpdate = this.cardKit.cardKitSequence;
11968
12012
  this.cardKit.cardKitSequence += 1;
11969
12013
  log$16.info("onIdle: updating final card", {
@@ -12048,7 +12092,7 @@ var StreamingCardController = class StreamingCardController {
12048
12092
  footer: this.deps.resolvedFooter,
12049
12093
  footerMetrics
12050
12094
  });
12051
- await this.closeStreamingAndUpdate(effectiveCardId, abortCardContent, "abortCard");
12095
+ await this.updateStreamingCard(effectiveCardId, abortCardContent, "abortCard");
12052
12096
  log$16.info("abortCard completed", { effectiveCardId });
12053
12097
  } else if (this.cardKit.cardMessageId) {
12054
12098
  const abortCard = buildCardContent("complete", {
@@ -12086,20 +12130,6 @@ var StreamingCardController = class StreamingCardController {
12086
12130
  if (this.cardCreationPromise) await this.cardCreationPromise;
12087
12131
  const effectiveCardId = this.cardKit.cardKitCardId ?? this.cardKit.originalCardKitCardId;
12088
12132
  if (effectiveCardId) {
12089
- const seqBeforeClose = this.cardKit.cardKitSequence;
12090
- this.cardKit.cardKitSequence += 1;
12091
- log$16.info("replaceWithClarificationCard: closing streaming mode", {
12092
- cardId: effectiveCardId,
12093
- seqBefore: seqBeforeClose,
12094
- seqAfter: this.cardKit.cardKitSequence
12095
- });
12096
- await setCardStreamingMode({
12097
- cfg: this.deps.cfg,
12098
- cardId: effectiveCardId,
12099
- streamingMode: false,
12100
- sequence: this.cardKit.cardKitSequence,
12101
- accountId: this.deps.accountId
12102
- });
12103
12133
  const seqBeforeUpdate = this.cardKit.cardKitSequence;
12104
12134
  this.cardKit.cardKitSequence += 1;
12105
12135
  await updateCardKitCard({
@@ -12146,10 +12176,10 @@ var StreamingCardController = class StreamingCardController {
12146
12176
  }
12147
12177
  }
12148
12178
  /**
12149
- * 强制关闭 streaming 状态(兜底方法)。
12179
+ * 强制终态化 streaming 卡片(兜底方法)。
12150
12180
  *
12151
- * 当进程已退出且卡片可能因 API 调用失败仍停留在 streaming 状态时,
12152
- * 由 session-control-handler 调用,强制调用 closeStreaming + updateCard
12181
+ * 当进程已退出且卡片可能因 API 调用失败仍停留在中间态时,
12182
+ * 由 session-control-handler 调用,直接更新卡片内容并保留 streaming mode
12153
12183
  * 即使已经是 terminal phase 也会尝试执行 API 调用。
12154
12184
  */
12155
12185
  async forceCloseStreaming() {
@@ -12158,7 +12188,7 @@ var StreamingCardController = class StreamingCardController {
12158
12188
  log$16.warn("forceCloseStreaming: no card to close");
12159
12189
  return;
12160
12190
  }
12161
- log$16.info("forceCloseStreaming: 强制终态化卡片", {
12191
+ log$16.info("forceCloseStreaming: 强制终态化 streaming 卡片", {
12162
12192
  cardId: effectiveCardId,
12163
12193
  messageId: this.cardKit.cardMessageId,
12164
12194
  phase: this.phase
@@ -12186,14 +12216,6 @@ var StreamingCardController = class StreamingCardController {
12186
12216
  showUndoButton: false
12187
12217
  });
12188
12218
  if (effectiveCardId) {
12189
- this.cardKit.cardKitSequence += 1;
12190
- await setCardStreamingMode({
12191
- cfg: this.deps.cfg,
12192
- cardId: effectiveCardId,
12193
- streamingMode: false,
12194
- sequence: this.cardKit.cardKitSequence,
12195
- accountId: this.deps.accountId
12196
- });
12197
12219
  this.cardKit.cardKitSequence += 1;
12198
12220
  await updateCardKitCard({
12199
12221
  cfg: this.deps.cfg,
@@ -12507,22 +12529,9 @@ var StreamingCardController = class StreamingCardController {
12507
12529
  this.onEnterTerminalPhase();
12508
12530
  }
12509
12531
  /**
12510
- * Close streaming mode then update card content (shared by onError and abortCard).
12532
+ * Update terminal card content while keeping CardKit streaming mode enabled.
12511
12533
  */
12512
- async closeStreamingAndUpdate(cardId, card, label) {
12513
- const seqBeforeClose = this.cardKit.cardKitSequence;
12514
- this.cardKit.cardKitSequence += 1;
12515
- log$16.info(`${label}: closing streaming mode`, {
12516
- seqBefore: seqBeforeClose,
12517
- seqAfter: this.cardKit.cardKitSequence
12518
- });
12519
- await setCardStreamingMode({
12520
- cfg: this.deps.cfg,
12521
- cardId,
12522
- streamingMode: false,
12523
- sequence: this.cardKit.cardKitSequence,
12524
- accountId: this.deps.accountId
12525
- });
12534
+ async updateStreamingCard(cardId, card, label) {
12526
12535
  const seqBeforeUpdate = this.cardKit.cardKitSequence;
12527
12536
  this.cardKit.cardKitSequence += 1;
12528
12537
  log$16.info(`${label}: updating card`, {
@@ -13479,6 +13488,8 @@ async function dispatchToCC(params) {
13479
13488
  const base64Data = buffer.toString("base64");
13480
13489
  imageBlocks.push({
13481
13490
  type: "image",
13491
+ filePath: imgFilePath,
13492
+ fileKey: imgRes.fileKey,
13482
13493
  source: {
13483
13494
  type: "base64",
13484
13495
  media_type: mediaType,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-lark/larkpal",
3
- "version": "0.1.61",
3
+ "version": "0.1.62",
4
4
  "description": "LarkPal - Lark/Feishu bot service",
5
5
  "type": "module",
6
6
  "main": "./dist/main.mjs",