@vibe-lark/larkpal 0.1.91-issue71.0 → 0.1.91-issue83.0

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 (3) hide show
  1. package/README.md +43 -0
  2. package/dist/main.mjs +40 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -88,6 +88,7 @@ lark-cli auth login
88
88
  | `LARKPAL_EXTERNAL_URL` | 外部可访问的网关 URL | - |
89
89
  | `LARKPAL_PUBLIC_URL` | OAuth 回调公开 URL | `http://localhost:3000` |
90
90
  | `LARKPAL_API_SECRET` | Agent Completion API 鉴权密钥 | `dev-internal-secret` |
91
+ | `LARKPAL_BUSINESS_EVENT_CALLBACK_URL` | 飞书固定菜单和业务卡片回调转发地址 | 未配置 |
91
92
  | `LARKPAL_COMPLETION_CWD` | Agent Completion 工作目录 | `/tmp/larkpal-completion` |
92
93
  | `LARKPAL_CC_IDLE_TIMEOUT` | CC 进程空闲超时(秒) | `0`(永不超时) |
93
94
  | `LARKPAL_ENCRYPTION_KEY` | 用户凭证加密密钥(32字节 hex) | 未设置(明文,仅限开发) |
@@ -112,6 +113,48 @@ lark-cli auth login
112
113
 
113
114
  ---
114
115
 
116
+ ## Business Event Callback
117
+
118
+ 设置 `LARKPAL_BUSINESS_EVENT_CALLBACK_URL` 后,LarkPal 会把未被内置处理器消费的飞书固定菜单事件和业务卡片交互事件 POST 到该地址。
119
+
120
+ `card.action.trigger` 的请求体包含稳定的 `action` 字段:
121
+
122
+ ```json
123
+ {
124
+ "eventType": "card.action.trigger",
125
+ "trigger": {
126
+ "kind": "card_action",
127
+ "key": "card.action.update_draft",
128
+ "value": {
129
+ "action": "card.action.update_draft",
130
+ "eventId": "rd_assistant_create_formula",
131
+ "draftId": "...",
132
+ "status": "drafting"
133
+ }
134
+ },
135
+ "action": {
136
+ "value": {
137
+ "action": "card.action.update_draft",
138
+ "eventId": "rd_assistant_create_formula",
139
+ "draftId": "...",
140
+ "status": "drafting"
141
+ },
142
+ "inputValue": {
143
+ "project_id": "selected-project-id"
144
+ },
145
+ "formValue": {
146
+ "project_id": "selected-project-id"
147
+ }
148
+ }
149
+ }
150
+ ```
151
+
152
+ `action.value` 原样保留卡片组件配置里的 callback metadata。`select_static` 等带 `name` 的输入组件会把选中值规范化到 `action.inputValue[name]`;`action.formValue` 同步提供同一组表单值,方便业务侧按字段名读取。
153
+
154
+ 业务回调返回 `{"kind":"card_update","card":{...}}` 时,LarkPal 会用返回的 `card` patch 原始飞书卡片;返回 `toast` 时会继续作为卡片交互响应返回。
155
+
156
+ ---
157
+
115
158
  ## Agent Completion API
116
159
 
117
160
  外部业务方作为 AI 能力消费方,调用 LarkPal 的通用 AI 补全接口。
package/dist/main.mjs CHANGED
@@ -18349,6 +18349,9 @@ function buildBusinessEventEnvelope(params) {
18349
18349
  const openMessageId = readString(raw.open_message_id, context.open_message_id, event.open_message_id);
18350
18350
  const cardId = readString(raw.card_id, raw.cardId, context.card_id, event.card_id);
18351
18351
  const action = asRecord(raw.action);
18352
+ const actionName = readString(action.name);
18353
+ const inputValue = normalizeActionInputValue(action);
18354
+ const formValue = normalizeActionFormValue(action, inputValue);
18352
18355
  const sessionId = readString(actionValue.sessionId, actionValue.session_id, raw.session_id, event.session_id);
18353
18356
  const conversationId = readString(openChatId, chatId);
18354
18357
  return {
@@ -18368,8 +18371,11 @@ function buildBusinessEventEnvelope(params) {
18368
18371
  card: { cardId },
18369
18372
  action: {
18370
18373
  value: action.value,
18371
- formValue: action.form_value,
18372
- inputValue: action.input_value
18374
+ formValue,
18375
+ inputValue,
18376
+ name: actionName,
18377
+ option: action.option,
18378
+ options: action.options
18373
18379
  },
18374
18380
  conversationId,
18375
18381
  sessionId,
@@ -18399,6 +18405,38 @@ function asRecord(value) {
18399
18405
  function isObject(value) {
18400
18406
  return value != null && typeof value === "object" && !Array.isArray(value);
18401
18407
  }
18408
+ function normalizeActionInputValue(action) {
18409
+ const inputValue = readFirstDefined(action.input_value, action.inputValue);
18410
+ if (inputValue !== void 0) return inputValue;
18411
+ const name = readString(action.name);
18412
+ if (!name) return void 0;
18413
+ const selected = extractSelectedActionValue(action);
18414
+ if (selected === void 0) return void 0;
18415
+ return { [name]: selected };
18416
+ }
18417
+ function normalizeActionFormValue(action, inputValue) {
18418
+ const formValue = readFirstDefined(action.form_value, action.formValue);
18419
+ if (formValue !== void 0) return formValue;
18420
+ return isObject(inputValue) ? inputValue : void 0;
18421
+ }
18422
+ function extractSelectedActionValue(action) {
18423
+ const directValue = readFirstDefined(action.selected_value, action.selectedValue);
18424
+ if (directValue !== void 0) return directValue;
18425
+ const optionValue = extractOptionValue(action.option);
18426
+ if (optionValue !== void 0) return optionValue;
18427
+ const options = Array.isArray(action.options) ? action.options : void 0;
18428
+ if (options?.length) {
18429
+ const values = options.map(extractOptionValue).filter((value) => value !== void 0);
18430
+ if (values.length) return values;
18431
+ }
18432
+ }
18433
+ function extractOptionValue(option) {
18434
+ if (!isObject(option)) return void 0;
18435
+ return readFirstDefined(option.value, option.id, option.key);
18436
+ }
18437
+ function readFirstDefined(...values) {
18438
+ for (const value of values) if (value != null) return value;
18439
+ }
18402
18440
  function readString(...values) {
18403
18441
  for (const value of values) if (typeof value === "string" && value.trim()) return value;
18404
18442
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-lark/larkpal",
3
- "version": "0.1.91-issue71.0",
3
+ "version": "0.1.91-issue83.0",
4
4
  "description": "LarkPal - Lark/Feishu bot service",
5
5
  "type": "module",
6
6
  "main": "./dist/main.mjs",