@zhin.js/adapter-lark 6.0.12 → 6.0.14
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/CHANGELOG.md +47 -0
- package/README.md +2 -0
- package/adapters/lark.js +4 -1
- package/adapters/lark.ts +4 -1
- package/lib/endpoint.d.ts +2 -1
- package/lib/protocol.js +15 -0
- package/package.json +14 -14
- package/src/endpoint.ts +2 -1
- package/src/protocol.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# @zhin.js/adapter-lark
|
|
2
2
|
|
|
3
|
+
## 6.0.14
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 974772e: Replace the user-facing `Prompt` vocabulary with the `UserInteraction` authoring surface for input, confirmation, and selection. Commands and handlers now expose `interaction`; IM Runtime exposes `createInteraction`; schema-driven endpoint collection is named `SchemaInteraction`. The old prompt-named interaction types and properties are removed rather than aliased. User interactions render through one canonical Markdown and keyboard/list presentation module shared by commands and Agent `ask_user` turns.
|
|
8
|
+
|
|
9
|
+
Extract the transport-neutral interaction contract into `@zhin.js/interaction`. A discriminated `ask()` API supports text, number, confirmation, single-select, multi-select, and typed lists with structured `title`, `description`, and `tip` content. Typed `sequence()` interactions return one result object keyed by step id, render progress, and retry invalid replies without leaking invalid values to callers.
|
|
10
|
+
|
|
11
|
+
Preserve AI Markdown and card command actions through outbound publishing. QQ delivers Markdown with native command buttons; KOOK, Discord, Telegram, DingTalk, and Lark/Feishu now declare and encode their native Markdown dialects while retaining each adapter's interaction policy. Correct QQ callback button action encoding and button style mapping.
|
|
12
|
+
|
|
13
|
+
- 5969c5b: Add SideEventGateway so adapters forward notice/request/system into HandlerIndex. HandlerContext now exposes only generation-safe capabilities and prompt ports; live Endpoint escape hatches are removed.
|
|
14
|
+
- Updated dependencies [5969c5b]
|
|
15
|
+
- Updated dependencies [d336a3f]
|
|
16
|
+
- Updated dependencies [0c82a7e]
|
|
17
|
+
- Updated dependencies [b9217e4]
|
|
18
|
+
- Updated dependencies [5969c5b]
|
|
19
|
+
- Updated dependencies [5969c5b]
|
|
20
|
+
- Updated dependencies [974772e]
|
|
21
|
+
- Updated dependencies [5969c5b]
|
|
22
|
+
- Updated dependencies [5969c5b]
|
|
23
|
+
- Updated dependencies [2f786bd]
|
|
24
|
+
- Updated dependencies [63d89f9]
|
|
25
|
+
- Updated dependencies [71c7cdd]
|
|
26
|
+
- Updated dependencies [3cca0ea]
|
|
27
|
+
- Updated dependencies [1312ca0]
|
|
28
|
+
- Updated dependencies [985fa22]
|
|
29
|
+
- Updated dependencies [04b861d]
|
|
30
|
+
- Updated dependencies [a23d544]
|
|
31
|
+
- Updated dependencies [8cddabf]
|
|
32
|
+
- Updated dependencies [dbe5081]
|
|
33
|
+
- @zhin.js/im-contract@1.0.4
|
|
34
|
+
- @zhin.js/core@1.5.12
|
|
35
|
+
- @zhin.js/adapter@1.1.11
|
|
36
|
+
- @zhin.js/agent@1.1.14
|
|
37
|
+
- @zhin.js/host-http@1.0.11
|
|
38
|
+
- @zhin.js/command@1.0.15
|
|
39
|
+
- zhin.js@6.0.12
|
|
40
|
+
- @zhin.js/permission@1.0.3
|
|
41
|
+
|
|
42
|
+
## 6.0.13
|
|
43
|
+
|
|
44
|
+
### Patch Changes
|
|
45
|
+
|
|
46
|
+
- @zhin.js/core@1.5.11
|
|
47
|
+
- @zhin.js/agent@1.1.13
|
|
48
|
+
- zhin.js@6.0.11
|
|
49
|
+
|
|
3
50
|
## 6.0.12
|
|
4
51
|
|
|
5
52
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ Zhin.js 飞书 / Lark 适配器(Plugin Runtime),通过 Runtime Host HTTP W
|
|
|
8
8
|
- URL 验证挑战(`url_verification`)
|
|
9
9
|
- Tenant Access Token 自动刷新
|
|
10
10
|
- 支持飞书与 Lark 国际版 API 基址
|
|
11
|
+
- canonical `markdown` 段编码为 `interactive` 卡片中的 `lark_md`
|
|
11
12
|
- 约定式 `defineAdapter` / `definePlugin`(无需 `usePlugin`)
|
|
12
13
|
|
|
13
14
|
## 安装
|
|
@@ -70,6 +71,7 @@ plugins:
|
|
|
70
71
|
| 飞书类型 | 入站 content(文本摘要) | 出站 wire |
|
|
71
72
|
|----------|--------------------------|-----------|
|
|
72
73
|
| text | 原文 | text |
|
|
74
|
+
| markdown | 原文 | interactive(`lark_md`) |
|
|
73
75
|
| image | `[image]` | image(需 `file_key`) |
|
|
74
76
|
| file | `[file: name]` | file |
|
|
75
77
|
| audio / video / sticker | `[audio]` / `[video]` / `[sticker]` | — |
|
package/adapters/lark.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Convention entry: discover `adapters/lark.ts` → defineAdapter.
|
|
4
4
|
*/
|
|
5
5
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
6
|
-
import { messageGatewayToken } from '@zhin.js/core/runtime';
|
|
6
|
+
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
7
7
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
8
8
|
import { LarkEndpoint } from "../lib/endpoint.js";
|
|
9
9
|
import { resolveLarkConfig, } from "../lib/protocol.js";
|
|
@@ -13,10 +13,12 @@ export default defineAdapter({
|
|
|
13
13
|
capabilities: ['inbound', 'outbound'],
|
|
14
14
|
// image 段 canonical MediaRef 经 /im/v1/images 物化为 image_key
|
|
15
15
|
// (base64 解码 / path 读盘 / url 下载后上传,kind=file 平台引用直通);
|
|
16
|
+
// canonical Markdown 由 endpoint codec 转为 lark_md 消息卡片;
|
|
16
17
|
// 卡片交互未接入出站通道,交互段降级纯文本。
|
|
17
18
|
segments: {
|
|
18
19
|
outboundMedia: ['url', 'upload'],
|
|
19
20
|
interactive: 'text',
|
|
21
|
+
markdown: 'native',
|
|
20
22
|
},
|
|
21
23
|
create(context) {
|
|
22
24
|
const config = resolveLarkConfig(context.config);
|
|
@@ -28,6 +30,7 @@ export default defineAdapter({
|
|
|
28
30
|
return new LarkEndpoint({
|
|
29
31
|
id: context.id,
|
|
30
32
|
gateway: context.use(messageGatewayToken),
|
|
33
|
+
sideEvents: context.use(sideEventGatewayToken),
|
|
31
34
|
http: context.use(httpHostToken),
|
|
32
35
|
config,
|
|
33
36
|
});
|
package/adapters/lark.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Convention entry: discover `adapters/lark.ts` → defineAdapter.
|
|
3
3
|
*/
|
|
4
4
|
import { defineAdapter } from 'zhin.js/adapter';
|
|
5
|
-
import { messageGatewayToken } from '@zhin.js/core/runtime';
|
|
5
|
+
import { messageGatewayToken, sideEventGatewayToken } from '@zhin.js/core/runtime';
|
|
6
6
|
import { httpHostToken } from '@zhin.js/host-http';
|
|
7
7
|
import { LarkEndpoint } from '../src/endpoint.js';
|
|
8
8
|
import {
|
|
@@ -18,10 +18,12 @@ export default defineAdapter<LarkAdapterConfig>({
|
|
|
18
18
|
capabilities: ['inbound', 'outbound'],
|
|
19
19
|
// image 段 canonical MediaRef 经 /im/v1/images 物化为 image_key
|
|
20
20
|
// (base64 解码 / path 读盘 / url 下载后上传,kind=file 平台引用直通);
|
|
21
|
+
// canonical Markdown 由 endpoint codec 转为 lark_md 消息卡片;
|
|
21
22
|
// 卡片交互未接入出站通道,交互段降级纯文本。
|
|
22
23
|
segments: {
|
|
23
24
|
outboundMedia: ['url', 'upload'],
|
|
24
25
|
interactive: 'text',
|
|
26
|
+
markdown: 'native',
|
|
25
27
|
},
|
|
26
28
|
create(context) {
|
|
27
29
|
const config = resolveLarkConfig(context.config);
|
|
@@ -33,6 +35,7 @@ export default defineAdapter<LarkAdapterConfig>({
|
|
|
33
35
|
return new LarkEndpoint({
|
|
34
36
|
id: context.id,
|
|
35
37
|
gateway: context.use(messageGatewayToken),
|
|
38
|
+
sideEvents: context.use(sideEventGatewayToken),
|
|
36
39
|
http: context.use(httpHostToken),
|
|
37
40
|
config,
|
|
38
41
|
});
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { EndpointInstance, EndpointManagement, EndpointSendRequest } from 'zhin.js/adapter';
|
|
2
|
-
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
2
|
+
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
3
3
|
import type { HttpHost } from '@zhin.js/host-http';
|
|
4
4
|
import type { CapabilityId } from 'zhin.js';
|
|
5
5
|
import { resolveMediaBinary } from './media-upload.js';
|
|
@@ -18,6 +18,7 @@ export type LarkFetch = (url: string, init?: {
|
|
|
18
18
|
export interface LarkEndpointOptions {
|
|
19
19
|
readonly id: CapabilityId;
|
|
20
20
|
readonly gateway: MessageGateway;
|
|
21
|
+
readonly sideEvents?: SideEventGateway;
|
|
21
22
|
readonly http: HttpHost;
|
|
22
23
|
readonly config: ResolvedLarkConfig;
|
|
23
24
|
readonly fetch?: LarkFetch;
|
package/lib/protocol.js
CHANGED
|
@@ -153,6 +153,7 @@ export function formatOutboundBody(payload) {
|
|
|
153
153
|
: payload && typeof payload === 'object' && 'type' in payload
|
|
154
154
|
? [payload]
|
|
155
155
|
: [];
|
|
156
|
+
const hasMarkdown = items.some((item) => typeof item !== 'string' && item.type === 'markdown');
|
|
156
157
|
if (items.length === 0) {
|
|
157
158
|
const text = payload == null
|
|
158
159
|
? ''
|
|
@@ -176,6 +177,9 @@ export function formatOutboundBody(payload) {
|
|
|
176
177
|
case 'text':
|
|
177
178
|
textParts.push(String(data.content ?? data.text ?? ''));
|
|
178
179
|
break;
|
|
180
|
+
case 'markdown':
|
|
181
|
+
textParts.push(String(data.content ?? data.text ?? ''));
|
|
182
|
+
break;
|
|
179
183
|
case 'at':
|
|
180
184
|
textParts.push(`<at user_id="${String(data.id ?? '')}">${String(data.name || data.id || '')}</at>`);
|
|
181
185
|
break;
|
|
@@ -230,6 +234,17 @@ export function formatOutboundBody(payload) {
|
|
|
230
234
|
}
|
|
231
235
|
if (media)
|
|
232
236
|
return media;
|
|
237
|
+
if (hasMarkdown) {
|
|
238
|
+
return {
|
|
239
|
+
msg_type: 'interactive',
|
|
240
|
+
content: JSON.stringify({
|
|
241
|
+
elements: [{
|
|
242
|
+
tag: 'div',
|
|
243
|
+
text: { tag: 'lark_md', content: textParts.join('') },
|
|
244
|
+
}],
|
|
245
|
+
}),
|
|
246
|
+
};
|
|
247
|
+
}
|
|
233
248
|
return {
|
|
234
249
|
msg_type: 'text',
|
|
235
250
|
content: JSON.stringify({ text: textParts.join('') }),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/adapter-lark",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.14",
|
|
4
4
|
"description": "Zhin.js Lark/Feishu (飞书) adapter for Plugin Runtime (HTTP webhook)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -34,21 +34,21 @@
|
|
|
34
34
|
"directory": "plugins/adapters/lark"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@zhin.js/adapter": "1.1.
|
|
38
|
-
"@zhin.js/core": "1.5.
|
|
39
|
-
"@zhin.js/host-http": "1.0.
|
|
40
|
-
"@zhin.js/im-contract": "1.0.
|
|
37
|
+
"@zhin.js/adapter": "1.1.11",
|
|
38
|
+
"@zhin.js/core": "1.5.12",
|
|
39
|
+
"@zhin.js/host-http": "1.0.11",
|
|
40
|
+
"@zhin.js/im-contract": "1.0.4",
|
|
41
41
|
"@zhin.js/logger": "1.0.76"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"zod": "^4.0.0",
|
|
45
|
-
"@zhin.js/adapter": "1.1.
|
|
46
|
-
"@zhin.js/agent": "1.1.
|
|
47
|
-
"@zhin.js/command": "1.0.
|
|
48
|
-
"@zhin.js/core": "1.5.
|
|
49
|
-
"@zhin.js/host-http": "1.0.
|
|
50
|
-
"@zhin.js/permission": "1.0.
|
|
51
|
-
"zhin.js": "6.0.
|
|
45
|
+
"@zhin.js/adapter": "1.1.11",
|
|
46
|
+
"@zhin.js/agent": "1.1.14",
|
|
47
|
+
"@zhin.js/command": "1.0.15",
|
|
48
|
+
"@zhin.js/core": "1.5.12",
|
|
49
|
+
"@zhin.js/host-http": "1.0.11",
|
|
50
|
+
"@zhin.js/permission": "1.0.3",
|
|
51
|
+
"zhin.js": "6.0.12"
|
|
52
52
|
},
|
|
53
53
|
"peerDependenciesMeta": {
|
|
54
54
|
"@zhin.js/agent": {
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"typescript": "^6.0.3",
|
|
70
70
|
"vitest": "^4.1.10",
|
|
71
71
|
"zod": "^4.4.3",
|
|
72
|
-
"@zhin.js/agent": "1.1.
|
|
73
|
-
"zhin.js": "6.0.
|
|
72
|
+
"@zhin.js/agent": "1.1.14",
|
|
73
|
+
"zhin.js": "6.0.12"
|
|
74
74
|
},
|
|
75
75
|
"files": [
|
|
76
76
|
"adapters",
|
package/src/endpoint.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
5
|
import { basename } from 'node:path';
|
|
6
6
|
import type { EndpointGroup, EndpointInstance, EndpointManagement, EndpointSendRequest } from 'zhin.js/adapter';
|
|
7
|
-
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
7
|
+
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
8
8
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
9
9
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
10
10
|
import type { CapabilityId } from 'zhin.js';
|
|
@@ -49,6 +49,7 @@ export type LarkFetch = (
|
|
|
49
49
|
export interface LarkEndpointOptions {
|
|
50
50
|
readonly id: CapabilityId;
|
|
51
51
|
readonly gateway: MessageGateway;
|
|
52
|
+
readonly sideEvents?: SideEventGateway;
|
|
52
53
|
readonly http: HttpHost;
|
|
53
54
|
readonly config: ResolvedLarkConfig;
|
|
54
55
|
readonly fetch?: LarkFetch;
|
package/src/protocol.ts
CHANGED
|
@@ -272,6 +272,7 @@ export function formatOutboundBody(payload: unknown): LarkSendBody {
|
|
|
272
272
|
: payload && typeof payload === 'object' && 'type' in (payload as object)
|
|
273
273
|
? [payload as LarkWireSegment]
|
|
274
274
|
: [];
|
|
275
|
+
const hasMarkdown = items.some((item) => typeof item !== 'string' && item.type === 'markdown');
|
|
275
276
|
|
|
276
277
|
if (items.length === 0) {
|
|
277
278
|
const text = payload == null
|
|
@@ -298,6 +299,9 @@ export function formatOutboundBody(payload: unknown): LarkSendBody {
|
|
|
298
299
|
case 'text':
|
|
299
300
|
textParts.push(String(data.content ?? data.text ?? ''));
|
|
300
301
|
break;
|
|
302
|
+
case 'markdown':
|
|
303
|
+
textParts.push(String(data.content ?? data.text ?? ''));
|
|
304
|
+
break;
|
|
301
305
|
case 'at':
|
|
302
306
|
textParts.push(
|
|
303
307
|
`<at user_id="${String(data.id ?? '')}">${String(data.name || data.id || '')}</at>`,
|
|
@@ -352,6 +356,17 @@ export function formatOutboundBody(payload: unknown): LarkSendBody {
|
|
|
352
356
|
}
|
|
353
357
|
|
|
354
358
|
if (media) return media;
|
|
359
|
+
if (hasMarkdown) {
|
|
360
|
+
return {
|
|
361
|
+
msg_type: 'interactive',
|
|
362
|
+
content: JSON.stringify({
|
|
363
|
+
elements: [{
|
|
364
|
+
tag: 'div',
|
|
365
|
+
text: { tag: 'lark_md', content: textParts.join('') },
|
|
366
|
+
}],
|
|
367
|
+
}),
|
|
368
|
+
};
|
|
369
|
+
}
|
|
355
370
|
return {
|
|
356
371
|
msg_type: 'text',
|
|
357
372
|
content: JSON.stringify({ text: textParts.join('') }),
|