@vibe-lark/larkpal 0.1.52 → 0.1.53
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 +195 -4
- package/package.json +1 -1
package/dist/main.mjs
CHANGED
|
@@ -2419,6 +2419,33 @@ function buildVerifierAuditMetadata(result) {
|
|
|
2419
2419
|
if (result.missingArtifacts) metadata.missingArtifacts = summarizeForAudit(result.missingArtifacts);
|
|
2420
2420
|
return metadata;
|
|
2421
2421
|
}
|
|
2422
|
+
function buildRuntimeEventAuditMetadata(event) {
|
|
2423
|
+
const metadata = {
|
|
2424
|
+
runtimeEventType: event.type,
|
|
2425
|
+
runtimeEvent: summarizeForAudit(event)
|
|
2426
|
+
};
|
|
2427
|
+
for (const key of [
|
|
2428
|
+
"scenarioId",
|
|
2429
|
+
"traceId",
|
|
2430
|
+
"phaseId",
|
|
2431
|
+
"artifactName",
|
|
2432
|
+
"artifactNames",
|
|
2433
|
+
"capabilityId",
|
|
2434
|
+
"repairActionId",
|
|
2435
|
+
"repairAttempt",
|
|
2436
|
+
"targetPhase",
|
|
2437
|
+
"requiredNextPhases",
|
|
2438
|
+
"plannerInstruction",
|
|
2439
|
+
"reasonCode",
|
|
2440
|
+
"verifierReasonCode",
|
|
2441
|
+
"missingPhases",
|
|
2442
|
+
"failedGates",
|
|
2443
|
+
"missingArtifacts",
|
|
2444
|
+
"status",
|
|
2445
|
+
"finalStatus"
|
|
2446
|
+
]) if (event[key] !== void 0) metadata[key] = summarizeForAudit(event[key]);
|
|
2447
|
+
return metadata;
|
|
2448
|
+
}
|
|
2422
2449
|
function buildAuthHeaders(params) {
|
|
2423
2450
|
const headers = {
|
|
2424
2451
|
"x-tenant-key": params.tenantKey,
|
|
@@ -2669,6 +2696,7 @@ async function handleExecute(req, res, processManager) {
|
|
|
2669
2696
|
try {
|
|
2670
2697
|
logRunStarted(config);
|
|
2671
2698
|
const result = await executeAndWaitResult$1(taskId, config, processManager);
|
|
2699
|
+
const completedTask = taskStore.get(taskId);
|
|
2672
2700
|
logger$8.info("同步任务执行完成", {
|
|
2673
2701
|
taskId,
|
|
2674
2702
|
resultSubtype: result?.subtype
|
|
@@ -2676,10 +2704,12 @@ async function handleExecute(req, res, processManager) {
|
|
|
2676
2704
|
res.status(200).json({
|
|
2677
2705
|
task_id: taskId,
|
|
2678
2706
|
status: result?.isError ? "failed" : "completed",
|
|
2679
|
-
result
|
|
2707
|
+
result,
|
|
2708
|
+
...completedTask?.runtimeEvents?.length ? { runtime_events: completedTask.runtimeEvents } : {}
|
|
2680
2709
|
});
|
|
2681
2710
|
} catch (err) {
|
|
2682
2711
|
const errorMsg = err instanceof Error ? err.message : String(err);
|
|
2712
|
+
const failedTask = taskStore.get(taskId);
|
|
2683
2713
|
logger$8.error("同步任务执行失败", {
|
|
2684
2714
|
taskId,
|
|
2685
2715
|
error: errorMsg
|
|
@@ -2687,7 +2717,8 @@ async function handleExecute(req, res, processManager) {
|
|
|
2687
2717
|
res.status(500).json({
|
|
2688
2718
|
task_id: taskId,
|
|
2689
2719
|
status: "failed",
|
|
2690
|
-
error: errorMsg
|
|
2720
|
+
error: errorMsg,
|
|
2721
|
+
...failedTask?.runtimeEvents?.length ? { runtime_events: failedTask.runtimeEvents } : {}
|
|
2691
2722
|
});
|
|
2692
2723
|
} finally {
|
|
2693
2724
|
releaseTaskIfRunning(taskId);
|
|
@@ -2826,6 +2857,7 @@ function handleGetTask(req, res) {
|
|
|
2826
2857
|
};
|
|
2827
2858
|
if (taskInfo.result) response.result = taskInfo.result;
|
|
2828
2859
|
if (taskInfo.error) response.error = taskInfo.error;
|
|
2860
|
+
if (taskInfo.runtimeEvents?.length) response.runtime_events = taskInfo.runtimeEvents;
|
|
2829
2861
|
res.status(200).json(response);
|
|
2830
2862
|
}
|
|
2831
2863
|
/**
|
|
@@ -2922,6 +2954,29 @@ function logRunStarted(config) {
|
|
|
2922
2954
|
function logAuditEvent(event) {
|
|
2923
2955
|
logger$8.info("Agent audit event", { ...event });
|
|
2924
2956
|
}
|
|
2957
|
+
function recordRuntimeEvent(taskId, config, event) {
|
|
2958
|
+
const eventSummary = summarizeForAudit(event);
|
|
2959
|
+
const taskInfo = taskStore.get(taskId);
|
|
2960
|
+
if (taskInfo) {
|
|
2961
|
+
taskInfo.runtimeEvents = taskInfo.runtimeEvents || [];
|
|
2962
|
+
taskInfo.runtimeEvents.push({
|
|
2963
|
+
type: event.type,
|
|
2964
|
+
event: eventSummary
|
|
2965
|
+
});
|
|
2966
|
+
}
|
|
2967
|
+
logger$8.info("Agent runtime event", {
|
|
2968
|
+
taskId,
|
|
2969
|
+
type: event.type,
|
|
2970
|
+
traceId: config.runContext?.traceId,
|
|
2971
|
+
scenarioId: event.scenarioId || config.runContext?.scenarioId,
|
|
2972
|
+
phaseId: event.phaseId,
|
|
2973
|
+
reasonCode: event.reasonCode || event.verifierReasonCode
|
|
2974
|
+
});
|
|
2975
|
+
if (config.requestContext) logAuditEvent(buildAuditEvent(config.requestContext, "runtime_event", {
|
|
2976
|
+
resultSummary: eventSummary,
|
|
2977
|
+
metadata: buildRuntimeEventAuditMetadata(event)
|
|
2978
|
+
}));
|
|
2979
|
+
}
|
|
2925
2980
|
/**
|
|
2926
2981
|
* 创建任务级别的流回调
|
|
2927
2982
|
*
|
|
@@ -3021,6 +3076,12 @@ function createTaskCallbacks(taskId, config) {
|
|
|
3021
3076
|
metadata: buildVerifierAuditMetadata(result)
|
|
3022
3077
|
}));
|
|
3023
3078
|
},
|
|
3079
|
+
onRuntimeEvent: (event) => {
|
|
3080
|
+
recordRuntimeEvent(taskId, config, event);
|
|
3081
|
+
},
|
|
3082
|
+
onScenarioEvent: (event) => {
|
|
3083
|
+
recordRuntimeEvent(taskId, config, event);
|
|
3084
|
+
},
|
|
3024
3085
|
onBlocked: handleBlockedEvent,
|
|
3025
3086
|
onBlockedEvent: handleBlockedEvent
|
|
3026
3087
|
};
|
|
@@ -4825,6 +4886,27 @@ function isChatSessionRunning(sessionId, processManager) {
|
|
|
4825
4886
|
function logChatAudit(event) {
|
|
4826
4887
|
log$25.info("[stream] Agent audit event", { ...event });
|
|
4827
4888
|
}
|
|
4889
|
+
function buildRuntimeEventMessageMetadata(event, runtimeConfig) {
|
|
4890
|
+
return {
|
|
4891
|
+
runtimeEventType: event.type,
|
|
4892
|
+
requestId: runtimeConfig.runContext?.requestId,
|
|
4893
|
+
traceId: runtimeConfig.runContext?.traceId,
|
|
4894
|
+
scenarioId: event.scenarioId || runtimeConfig.runContext?.scenarioId,
|
|
4895
|
+
phaseId: event.phaseId,
|
|
4896
|
+
artifactName: event.artifactName,
|
|
4897
|
+
artifactNames: event.artifactNames,
|
|
4898
|
+
targetPhase: event.targetPhase,
|
|
4899
|
+
requiredNextPhases: event.requiredNextPhases,
|
|
4900
|
+
plannerInstruction: event.plannerInstruction,
|
|
4901
|
+
verifierReasonCode: event.verifierReasonCode,
|
|
4902
|
+
reasonCode: event.reasonCode,
|
|
4903
|
+
missingPhases: event.missingPhases,
|
|
4904
|
+
failedGates: event.failedGates,
|
|
4905
|
+
missingArtifacts: event.missingArtifacts,
|
|
4906
|
+
repairAttempt: event.repairAttempt,
|
|
4907
|
+
finalStatus: event.finalStatus
|
|
4908
|
+
};
|
|
4909
|
+
}
|
|
4828
4910
|
/**
|
|
4829
4911
|
* 创建 Chat 流式对话 + 历史查询路由
|
|
4830
4912
|
*
|
|
@@ -4953,6 +5035,32 @@ function createChatRouter(config) {
|
|
|
4953
5035
|
clientDisconnected = true;
|
|
4954
5036
|
log$25.info("[stream] 客户端断开连接", { sessionId });
|
|
4955
5037
|
});
|
|
5038
|
+
const handleRuntimeEvent = (event) => {
|
|
5039
|
+
const eventSummary = summarizeForAudit(event);
|
|
5040
|
+
if (runtimeConfig.requestContext) logChatAudit(buildAuditEvent(runtimeConfig.requestContext, "runtime_event", {
|
|
5041
|
+
resultSummary: eventSummary,
|
|
5042
|
+
metadata: buildRuntimeEventAuditMetadata(event)
|
|
5043
|
+
}));
|
|
5044
|
+
messageStore.appendMessage({
|
|
5045
|
+
sessionId,
|
|
5046
|
+
role: "tool",
|
|
5047
|
+
content: JSON.stringify({
|
|
5048
|
+
runtimeEventType: event.type,
|
|
5049
|
+
event: eventSummary
|
|
5050
|
+
}),
|
|
5051
|
+
channel: "web",
|
|
5052
|
+
metadata: buildRuntimeEventMessageMetadata(event, runtimeConfig)
|
|
5053
|
+
}).catch((err) => {
|
|
5054
|
+
log$25.error("[stream] 保存 runtime event 消息失败", {
|
|
5055
|
+
sessionId,
|
|
5056
|
+
error: err
|
|
5057
|
+
});
|
|
5058
|
+
});
|
|
5059
|
+
if (!clientDisconnected) sendSSE(res, "runtime-event", {
|
|
5060
|
+
type: event.type,
|
|
5061
|
+
event: eventSummary
|
|
5062
|
+
});
|
|
5063
|
+
};
|
|
4956
5064
|
const callbacks = {
|
|
4957
5065
|
onTextDelta: (text) => {
|
|
4958
5066
|
accumText += text;
|
|
@@ -5091,6 +5199,8 @@ function createChatRouter(config) {
|
|
|
5091
5199
|
}));
|
|
5092
5200
|
if (!clientDisconnected) sendSSE(res, "verifier-result", { result: resultSummary });
|
|
5093
5201
|
},
|
|
5202
|
+
onRuntimeEvent: handleRuntimeEvent,
|
|
5203
|
+
onScenarioEvent: handleRuntimeEvent,
|
|
5094
5204
|
onBlocked: handleBlockedEvent,
|
|
5095
5205
|
onBlockedEvent: handleBlockedEvent
|
|
5096
5206
|
};
|
|
@@ -11117,6 +11227,8 @@ function buildAuthCard(ctx) {
|
|
|
11117
11227
|
const openPlatformHost = ctx.brand === "lark" ? "https://open.larksuite.com" : "https://open.feishu.cn";
|
|
11118
11228
|
const scopeQuery = ctx.scopes.join(",");
|
|
11119
11229
|
const authUrl = `${openPlatformHost}/app/${ctx.appId}/auth?q=${encodeURIComponent(scopeQuery)}`;
|
|
11230
|
+
const scopeList = ctx.scopes.map((s) => `• \`${s}\``).join("\n");
|
|
11231
|
+
const reason = ctx.reason?.trim();
|
|
11120
11232
|
const card = {
|
|
11121
11233
|
schema: "2.0",
|
|
11122
11234
|
config: {
|
|
@@ -11131,8 +11243,12 @@ function buildAuthCard(ctx) {
|
|
|
11131
11243
|
},
|
|
11132
11244
|
{
|
|
11133
11245
|
tag: "markdown",
|
|
11134
|
-
content: `当前操作需要以下飞书权限,请应用管理员前往开放平台申请:\n\n${
|
|
11246
|
+
content: `当前操作需要以下飞书权限,请应用管理员前往开放平台申请:\n\n${scopeList}`
|
|
11135
11247
|
},
|
|
11248
|
+
...reason ? [{
|
|
11249
|
+
tag: "markdown",
|
|
11250
|
+
content: `**申请原因:** ${reason}`
|
|
11251
|
+
}] : [],
|
|
11136
11252
|
{ tag: "hr" },
|
|
11137
11253
|
{
|
|
11138
11254
|
tag: "markdown",
|
|
@@ -11140,11 +11256,13 @@ function buildAuthCard(ctx) {
|
|
|
11140
11256
|
},
|
|
11141
11257
|
{
|
|
11142
11258
|
tag: "button",
|
|
11259
|
+
name: getAuthButtonName("open"),
|
|
11143
11260
|
text: {
|
|
11144
11261
|
tag: "plain_text",
|
|
11145
11262
|
content: "去申请权限 ↗"
|
|
11146
11263
|
},
|
|
11147
11264
|
type: "primary",
|
|
11265
|
+
width: "default",
|
|
11148
11266
|
multi_url: {
|
|
11149
11267
|
url: authUrl,
|
|
11150
11268
|
pc_url: authUrl,
|
|
@@ -11158,12 +11276,14 @@ function buildAuthCard(ctx) {
|
|
|
11158
11276
|
},
|
|
11159
11277
|
{
|
|
11160
11278
|
tag: "button",
|
|
11279
|
+
name: getAuthButtonName("complete"),
|
|
11161
11280
|
text: {
|
|
11162
11281
|
tag: "plain_text",
|
|
11163
11282
|
content: "✓ 已完成权限配置"
|
|
11164
11283
|
},
|
|
11165
11284
|
type: "text",
|
|
11166
11285
|
size: "small",
|
|
11286
|
+
width: "default",
|
|
11167
11287
|
behaviors: [{
|
|
11168
11288
|
type: "callback",
|
|
11169
11289
|
value: {
|
|
@@ -11195,6 +11315,9 @@ function buildAuthCard(ctx) {
|
|
|
11195
11315
|
operationId
|
|
11196
11316
|
};
|
|
11197
11317
|
}
|
|
11318
|
+
function getAuthButtonName(action) {
|
|
11319
|
+
return `auth_${action}`;
|
|
11320
|
+
}
|
|
11198
11321
|
/**
|
|
11199
11322
|
* 构建多 phase 提问卡片(CardKit v2 格式)
|
|
11200
11323
|
*
|
|
@@ -12091,6 +12214,49 @@ async function dispatchToCC(params) {
|
|
|
12091
12214
|
log$12.warn("记录飞书 assistant 消息到 store 失败", { error: String(err) });
|
|
12092
12215
|
});
|
|
12093
12216
|
};
|
|
12217
|
+
const appendRuntimeEventMessage = (event) => {
|
|
12218
|
+
const eventSummary = summarizeForAudit(event);
|
|
12219
|
+
log$12.info("CC onRuntimeEvent", {
|
|
12220
|
+
sessionId: route.sessionId,
|
|
12221
|
+
type: event.type,
|
|
12222
|
+
traceId: runtimeConfig.runContext?.traceId,
|
|
12223
|
+
scenarioId: event.scenarioId || runtimeConfig.runContext?.scenarioId,
|
|
12224
|
+
phaseId: event.phaseId,
|
|
12225
|
+
reasonCode: event.reasonCode || event.verifierReasonCode,
|
|
12226
|
+
event: eventSummary
|
|
12227
|
+
});
|
|
12228
|
+
if (!params.messageStore) return;
|
|
12229
|
+
params.messageStore.appendMessage({
|
|
12230
|
+
sessionId: route.sessionId,
|
|
12231
|
+
role: "tool",
|
|
12232
|
+
content: JSON.stringify({
|
|
12233
|
+
runtimeEventType: event.type,
|
|
12234
|
+
event: eventSummary
|
|
12235
|
+
}),
|
|
12236
|
+
channel: "feishu-bot",
|
|
12237
|
+
metadata: {
|
|
12238
|
+
runtimeEventType: event.type,
|
|
12239
|
+
requestId: runtimeConfig.runContext?.requestId,
|
|
12240
|
+
traceId: runtimeConfig.runContext?.traceId,
|
|
12241
|
+
scenarioId: event.scenarioId || runtimeConfig.runContext?.scenarioId,
|
|
12242
|
+
phaseId: event.phaseId,
|
|
12243
|
+
artifactName: event.artifactName,
|
|
12244
|
+
artifactNames: event.artifactNames,
|
|
12245
|
+
targetPhase: event.targetPhase,
|
|
12246
|
+
requiredNextPhases: event.requiredNextPhases,
|
|
12247
|
+
plannerInstruction: event.plannerInstruction,
|
|
12248
|
+
verifierReasonCode: event.verifierReasonCode,
|
|
12249
|
+
reasonCode: event.reasonCode,
|
|
12250
|
+
missingPhases: event.missingPhases,
|
|
12251
|
+
failedGates: event.failedGates,
|
|
12252
|
+
missingArtifacts: event.missingArtifacts,
|
|
12253
|
+
repairAttempt: event.repairAttempt,
|
|
12254
|
+
finalStatus: event.finalStatus
|
|
12255
|
+
}
|
|
12256
|
+
}).catch((err) => {
|
|
12257
|
+
log$12.warn("记录飞书 runtime event 到 store 失败", { error: String(err) });
|
|
12258
|
+
});
|
|
12259
|
+
};
|
|
12094
12260
|
const handleResult = async (result) => {
|
|
12095
12261
|
log$12.info("CC onResult", {
|
|
12096
12262
|
sessionId: route.sessionId,
|
|
@@ -12228,6 +12394,8 @@ async function dispatchToCC(params) {
|
|
|
12228
12394
|
resultSummary: summarizeForAudit(event.resultSummary)
|
|
12229
12395
|
});
|
|
12230
12396
|
},
|
|
12397
|
+
onRuntimeEvent: appendRuntimeEventMessage,
|
|
12398
|
+
onScenarioEvent: appendRuntimeEventMessage,
|
|
12231
12399
|
onBlocked: handleBlockedEvent,
|
|
12232
12400
|
onBlockedEvent: handleBlockedEvent
|
|
12233
12401
|
};
|
|
@@ -12505,6 +12673,28 @@ async function dispatchTeammateEval(params) {
|
|
|
12505
12673
|
resultSummary: summarizeForAudit(event.resultSummary)
|
|
12506
12674
|
});
|
|
12507
12675
|
},
|
|
12676
|
+
onRuntimeEvent: (event) => {
|
|
12677
|
+
log$12.info("teammate onRuntimeEvent", {
|
|
12678
|
+
type: event.type,
|
|
12679
|
+
chatId,
|
|
12680
|
+
traceId: runtimeConfig.runContext?.traceId,
|
|
12681
|
+
scenarioId: event.scenarioId || runtimeConfig.runContext?.scenarioId,
|
|
12682
|
+
phaseId: event.phaseId,
|
|
12683
|
+
reasonCode: event.reasonCode || event.verifierReasonCode,
|
|
12684
|
+
event: summarizeForAudit(event)
|
|
12685
|
+
});
|
|
12686
|
+
},
|
|
12687
|
+
onScenarioEvent: (event) => {
|
|
12688
|
+
log$12.info("teammate onScenarioEvent", {
|
|
12689
|
+
type: event.type,
|
|
12690
|
+
chatId,
|
|
12691
|
+
traceId: runtimeConfig.runContext?.traceId,
|
|
12692
|
+
scenarioId: event.scenarioId || runtimeConfig.runContext?.scenarioId,
|
|
12693
|
+
phaseId: event.phaseId,
|
|
12694
|
+
reasonCode: event.reasonCode || event.verifierReasonCode,
|
|
12695
|
+
event: summarizeForAudit(event)
|
|
12696
|
+
});
|
|
12697
|
+
},
|
|
12508
12698
|
onBlocked: (event) => {
|
|
12509
12699
|
const sanitized = sanitizeBlockedEvent(event);
|
|
12510
12700
|
log$12.warn("teammate onBlocked", {
|
|
@@ -12587,6 +12777,7 @@ async function handleMcpToolCallback(req, ctx) {
|
|
|
12587
12777
|
sessionId: req.sessionId,
|
|
12588
12778
|
appId: ctx.appId,
|
|
12589
12779
|
scopes: params.scopes,
|
|
12780
|
+
reason: params.reason,
|
|
12590
12781
|
brand: ctx.brand
|
|
12591
12782
|
});
|
|
12592
12783
|
mcpOperationMap.set(operationId, req.requestId);
|
|
@@ -15442,7 +15633,7 @@ function enqueueFeishuChatTask(params) {
|
|
|
15442
15633
|
*/
|
|
15443
15634
|
const log$1 = larkLogger("channel/interactive-card-handler");
|
|
15444
15635
|
async function handleAuthCompleteAction(_ctx, data) {
|
|
15445
|
-
const operationId = data?.
|
|
15636
|
+
const operationId = extractActionValue$1(data)?.operationId;
|
|
15446
15637
|
if (!operationId) return { toast: {
|
|
15447
15638
|
type: "error",
|
|
15448
15639
|
content: "操作参数缺失"
|