@vibe-lark/larkpal 0.1.60 → 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.
- package/dist/main.mjs +91 -79
- 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
|
|
@@ -3463,7 +3541,7 @@ function serializeChatRun(run) {
|
|
|
3463
3541
|
lastEventType: run.lastEventType,
|
|
3464
3542
|
lastToolName: run.lastToolName,
|
|
3465
3543
|
idleSeconds,
|
|
3466
|
-
adapterBusy: run.adapterBusy,
|
|
3544
|
+
adapterBusy: run.status === "running" ? run.adapterBusy : false,
|
|
3467
3545
|
staleReason: run.staleReason
|
|
3468
3546
|
};
|
|
3469
3547
|
}
|
|
@@ -3577,6 +3655,7 @@ async function markRunTerminal(run, messageStore, status, params) {
|
|
|
3577
3655
|
run.finalStatus = params.finalStatus;
|
|
3578
3656
|
run.error = params.error;
|
|
3579
3657
|
run.staleReason = params.staleReason;
|
|
3658
|
+
run.adapterBusy = false;
|
|
3580
3659
|
recordRunEvent(run, `run-${status}`);
|
|
3581
3660
|
broadcastRunStatus(run);
|
|
3582
3661
|
await appendRunStatusMessage(run, messageStore);
|
|
@@ -10876,26 +10955,6 @@ async function sendCardByCardId(params) {
|
|
|
10876
10955
|
chatId: response?.data?.chat_id ?? ""
|
|
10877
10956
|
};
|
|
10878
10957
|
}
|
|
10879
|
-
/**
|
|
10880
|
-
* Close (or open) the streaming mode on a CardKit card.
|
|
10881
|
-
*
|
|
10882
|
-
* Must be called after streaming is complete to restore normal card
|
|
10883
|
-
* behaviour (forwarding, interaction callbacks, etc.).
|
|
10884
|
-
*/
|
|
10885
|
-
async function setCardStreamingMode(params) {
|
|
10886
|
-
const { cfg, cardId, streamingMode, sequence, accountId } = params;
|
|
10887
|
-
logCardKitResponse({
|
|
10888
|
-
resp: await resolveLarkSdk(cfg, accountId).cardkit.v1.card.settings({
|
|
10889
|
-
data: {
|
|
10890
|
-
settings: JSON.stringify({ streaming_mode: streamingMode }),
|
|
10891
|
-
sequence
|
|
10892
|
-
},
|
|
10893
|
-
path: { card_id: cardId }
|
|
10894
|
-
}),
|
|
10895
|
-
api: "card.settings",
|
|
10896
|
-
context: `seq=${sequence}, streaming_mode=${streamingMode}`
|
|
10897
|
-
});
|
|
10898
|
-
}
|
|
10899
10958
|
//#endregion
|
|
10900
10959
|
//#region src/card/reply-dispatcher-types.ts
|
|
10901
10960
|
const TERMINAL_PHASES = new Set([
|
|
@@ -11881,7 +11940,7 @@ var StreamingCardController = class StreamingCardController {
|
|
|
11881
11940
|
footer: this.deps.resolvedFooter,
|
|
11882
11941
|
footerMetrics
|
|
11883
11942
|
});
|
|
11884
|
-
if (errorEffectiveCardId) await this.
|
|
11943
|
+
if (errorEffectiveCardId) await this.updateStreamingCard(errorEffectiveCardId, errorCard, "onError");
|
|
11885
11944
|
else await updateCardFeishu({
|
|
11886
11945
|
cfg: this.deps.cfg,
|
|
11887
11946
|
messageId: this.cardKit.cardMessageId,
|
|
@@ -11949,20 +12008,6 @@ var StreamingCardController = class StreamingCardController {
|
|
|
11949
12008
|
const FINAL_UPDATE_RETRY_DELAY_MS = 2e3;
|
|
11950
12009
|
for (let attempt = 1; attempt <= MAX_FINAL_UPDATE_RETRIES; attempt++) try {
|
|
11951
12010
|
if (idleEffectiveCardId) {
|
|
11952
|
-
const seqBeforeClose = this.cardKit.cardKitSequence;
|
|
11953
|
-
this.cardKit.cardKitSequence += 1;
|
|
11954
|
-
log$16.info("onIdle: closing streaming mode", {
|
|
11955
|
-
attempt,
|
|
11956
|
-
seqBefore: seqBeforeClose,
|
|
11957
|
-
seqAfter: this.cardKit.cardKitSequence
|
|
11958
|
-
});
|
|
11959
|
-
await setCardStreamingMode({
|
|
11960
|
-
cfg: this.deps.cfg,
|
|
11961
|
-
cardId: idleEffectiveCardId,
|
|
11962
|
-
streamingMode: false,
|
|
11963
|
-
sequence: this.cardKit.cardKitSequence,
|
|
11964
|
-
accountId: this.deps.accountId
|
|
11965
|
-
});
|
|
11966
12011
|
const seqBeforeUpdate = this.cardKit.cardKitSequence;
|
|
11967
12012
|
this.cardKit.cardKitSequence += 1;
|
|
11968
12013
|
log$16.info("onIdle: updating final card", {
|
|
@@ -12047,7 +12092,7 @@ var StreamingCardController = class StreamingCardController {
|
|
|
12047
12092
|
footer: this.deps.resolvedFooter,
|
|
12048
12093
|
footerMetrics
|
|
12049
12094
|
});
|
|
12050
|
-
await this.
|
|
12095
|
+
await this.updateStreamingCard(effectiveCardId, abortCardContent, "abortCard");
|
|
12051
12096
|
log$16.info("abortCard completed", { effectiveCardId });
|
|
12052
12097
|
} else if (this.cardKit.cardMessageId) {
|
|
12053
12098
|
const abortCard = buildCardContent("complete", {
|
|
@@ -12085,20 +12130,6 @@ var StreamingCardController = class StreamingCardController {
|
|
|
12085
12130
|
if (this.cardCreationPromise) await this.cardCreationPromise;
|
|
12086
12131
|
const effectiveCardId = this.cardKit.cardKitCardId ?? this.cardKit.originalCardKitCardId;
|
|
12087
12132
|
if (effectiveCardId) {
|
|
12088
|
-
const seqBeforeClose = this.cardKit.cardKitSequence;
|
|
12089
|
-
this.cardKit.cardKitSequence += 1;
|
|
12090
|
-
log$16.info("replaceWithClarificationCard: closing streaming mode", {
|
|
12091
|
-
cardId: effectiveCardId,
|
|
12092
|
-
seqBefore: seqBeforeClose,
|
|
12093
|
-
seqAfter: this.cardKit.cardKitSequence
|
|
12094
|
-
});
|
|
12095
|
-
await setCardStreamingMode({
|
|
12096
|
-
cfg: this.deps.cfg,
|
|
12097
|
-
cardId: effectiveCardId,
|
|
12098
|
-
streamingMode: false,
|
|
12099
|
-
sequence: this.cardKit.cardKitSequence,
|
|
12100
|
-
accountId: this.deps.accountId
|
|
12101
|
-
});
|
|
12102
12133
|
const seqBeforeUpdate = this.cardKit.cardKitSequence;
|
|
12103
12134
|
this.cardKit.cardKitSequence += 1;
|
|
12104
12135
|
await updateCardKitCard({
|
|
@@ -12145,10 +12176,10 @@ var StreamingCardController = class StreamingCardController {
|
|
|
12145
12176
|
}
|
|
12146
12177
|
}
|
|
12147
12178
|
/**
|
|
12148
|
-
*
|
|
12179
|
+
* 强制终态化 streaming 卡片(兜底方法)。
|
|
12149
12180
|
*
|
|
12150
|
-
* 当进程已退出且卡片可能因 API
|
|
12151
|
-
* 由 session-control-handler
|
|
12181
|
+
* 当进程已退出且卡片可能因 API 调用失败仍停留在中间态时,
|
|
12182
|
+
* 由 session-control-handler 调用,直接更新卡片内容并保留 streaming mode。
|
|
12152
12183
|
* 即使已经是 terminal phase 也会尝试执行 API 调用。
|
|
12153
12184
|
*/
|
|
12154
12185
|
async forceCloseStreaming() {
|
|
@@ -12157,7 +12188,7 @@ var StreamingCardController = class StreamingCardController {
|
|
|
12157
12188
|
log$16.warn("forceCloseStreaming: no card to close");
|
|
12158
12189
|
return;
|
|
12159
12190
|
}
|
|
12160
|
-
log$16.info("forceCloseStreaming:
|
|
12191
|
+
log$16.info("forceCloseStreaming: 强制终态化 streaming 卡片", {
|
|
12161
12192
|
cardId: effectiveCardId,
|
|
12162
12193
|
messageId: this.cardKit.cardMessageId,
|
|
12163
12194
|
phase: this.phase
|
|
@@ -12185,14 +12216,6 @@ var StreamingCardController = class StreamingCardController {
|
|
|
12185
12216
|
showUndoButton: false
|
|
12186
12217
|
});
|
|
12187
12218
|
if (effectiveCardId) {
|
|
12188
|
-
this.cardKit.cardKitSequence += 1;
|
|
12189
|
-
await setCardStreamingMode({
|
|
12190
|
-
cfg: this.deps.cfg,
|
|
12191
|
-
cardId: effectiveCardId,
|
|
12192
|
-
streamingMode: false,
|
|
12193
|
-
sequence: this.cardKit.cardKitSequence,
|
|
12194
|
-
accountId: this.deps.accountId
|
|
12195
|
-
});
|
|
12196
12219
|
this.cardKit.cardKitSequence += 1;
|
|
12197
12220
|
await updateCardKitCard({
|
|
12198
12221
|
cfg: this.deps.cfg,
|
|
@@ -12506,22 +12529,9 @@ var StreamingCardController = class StreamingCardController {
|
|
|
12506
12529
|
this.onEnterTerminalPhase();
|
|
12507
12530
|
}
|
|
12508
12531
|
/**
|
|
12509
|
-
*
|
|
12532
|
+
* Update terminal card content while keeping CardKit streaming mode enabled.
|
|
12510
12533
|
*/
|
|
12511
|
-
async
|
|
12512
|
-
const seqBeforeClose = this.cardKit.cardKitSequence;
|
|
12513
|
-
this.cardKit.cardKitSequence += 1;
|
|
12514
|
-
log$16.info(`${label}: closing streaming mode`, {
|
|
12515
|
-
seqBefore: seqBeforeClose,
|
|
12516
|
-
seqAfter: this.cardKit.cardKitSequence
|
|
12517
|
-
});
|
|
12518
|
-
await setCardStreamingMode({
|
|
12519
|
-
cfg: this.deps.cfg,
|
|
12520
|
-
cardId,
|
|
12521
|
-
streamingMode: false,
|
|
12522
|
-
sequence: this.cardKit.cardKitSequence,
|
|
12523
|
-
accountId: this.deps.accountId
|
|
12524
|
-
});
|
|
12534
|
+
async updateStreamingCard(cardId, card, label) {
|
|
12525
12535
|
const seqBeforeUpdate = this.cardKit.cardKitSequence;
|
|
12526
12536
|
this.cardKit.cardKitSequence += 1;
|
|
12527
12537
|
log$16.info(`${label}: updating card`, {
|
|
@@ -13478,6 +13488,8 @@ async function dispatchToCC(params) {
|
|
|
13478
13488
|
const base64Data = buffer.toString("base64");
|
|
13479
13489
|
imageBlocks.push({
|
|
13480
13490
|
type: "image",
|
|
13491
|
+
filePath: imgFilePath,
|
|
13492
|
+
fileKey: imgRes.fileKey,
|
|
13481
13493
|
source: {
|
|
13482
13494
|
type: "base64",
|
|
13483
13495
|
media_type: mediaType,
|