@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.
Files changed (2) hide show
  1. package/dist/main.mjs +195 -4
  2. 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${ctx.scopes.map((s) => `• \`${s}\``).join("\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?.action?.value?.operationId;
15636
+ const operationId = extractActionValue$1(data)?.operationId;
15446
15637
  if (!operationId) return { toast: {
15447
15638
  type: "error",
15448
15639
  content: "操作参数缺失"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-lark/larkpal",
3
- "version": "0.1.52",
3
+ "version": "0.1.53",
4
4
  "description": "LarkPal - Lark/Feishu bot service",
5
5
  "type": "module",
6
6
  "main": "./dist/main.mjs",