@zhin.js/adapter-lark 6.0.13 → 7.0.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.
- package/CHANGELOG.md +53 -0
- package/README.md +2 -0
- package/adapters/lark.js +5 -1
- package/adapters/lark.ts +5 -1
- package/lib/endpoint.d.ts +4 -2
- package/lib/endpoint.js +2 -0
- package/lib/protocol.js +15 -0
- package/package.json +14 -14
- package/src/endpoint.ts +11 -2
- package/src/protocol.ts +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
# @zhin.js/adapter-lark
|
|
2
2
|
|
|
3
|
+
## 7.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f2c532f: Expose exact per-Endpoint message operations through one validated Adapter capability model, route Core control calls through declared active capabilities, and connect existing recall, edit, reaction, and typing implementations across platform adapters.
|
|
8
|
+
- Updated dependencies [b10d058]
|
|
9
|
+
- Updated dependencies [f2c532f]
|
|
10
|
+
- Updated dependencies [3dbf990]
|
|
11
|
+
- @zhin.js/host-http@1.0.12
|
|
12
|
+
- @zhin.js/adapter@1.2.0
|
|
13
|
+
- @zhin.js/core@1.5.13
|
|
14
|
+
- @zhin.js/agent@1.1.15
|
|
15
|
+
- zhin.js@6.0.13
|
|
16
|
+
|
|
17
|
+
## 6.0.14
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 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.
|
|
22
|
+
|
|
23
|
+
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.
|
|
24
|
+
|
|
25
|
+
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.
|
|
26
|
+
|
|
27
|
+
- 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.
|
|
28
|
+
- Updated dependencies [5969c5b]
|
|
29
|
+
- Updated dependencies [d336a3f]
|
|
30
|
+
- Updated dependencies [0c82a7e]
|
|
31
|
+
- Updated dependencies [b9217e4]
|
|
32
|
+
- Updated dependencies [5969c5b]
|
|
33
|
+
- Updated dependencies [5969c5b]
|
|
34
|
+
- Updated dependencies [974772e]
|
|
35
|
+
- Updated dependencies [5969c5b]
|
|
36
|
+
- Updated dependencies [5969c5b]
|
|
37
|
+
- Updated dependencies [2f786bd]
|
|
38
|
+
- Updated dependencies [63d89f9]
|
|
39
|
+
- Updated dependencies [71c7cdd]
|
|
40
|
+
- Updated dependencies [3cca0ea]
|
|
41
|
+
- Updated dependencies [1312ca0]
|
|
42
|
+
- Updated dependencies [985fa22]
|
|
43
|
+
- Updated dependencies [04b861d]
|
|
44
|
+
- Updated dependencies [a23d544]
|
|
45
|
+
- Updated dependencies [8cddabf]
|
|
46
|
+
- Updated dependencies [dbe5081]
|
|
47
|
+
- @zhin.js/im-contract@1.0.4
|
|
48
|
+
- @zhin.js/core@1.5.12
|
|
49
|
+
- @zhin.js/adapter@1.1.11
|
|
50
|
+
- @zhin.js/agent@1.1.14
|
|
51
|
+
- @zhin.js/host-http@1.0.11
|
|
52
|
+
- @zhin.js/command@1.0.15
|
|
53
|
+
- zhin.js@6.0.12
|
|
54
|
+
- @zhin.js/permission@1.0.3
|
|
55
|
+
|
|
3
56
|
## 6.0.13
|
|
4
57
|
|
|
5
58
|
### 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";
|
|
@@ -11,12 +11,15 @@ import { larkRuntimeStateToken } from "../lib/lark-runtime-state.js";
|
|
|
11
11
|
export { LarkEndpoint } from "../lib/endpoint.js";
|
|
12
12
|
export default defineAdapter({
|
|
13
13
|
capabilities: ['inbound', 'outbound'],
|
|
14
|
+
operations: ['recall'],
|
|
14
15
|
// image 段 canonical MediaRef 经 /im/v1/images 物化为 image_key
|
|
15
16
|
// (base64 解码 / path 读盘 / url 下载后上传,kind=file 平台引用直通);
|
|
17
|
+
// canonical Markdown 由 endpoint codec 转为 lark_md 消息卡片;
|
|
16
18
|
// 卡片交互未接入出站通道,交互段降级纯文本。
|
|
17
19
|
segments: {
|
|
18
20
|
outboundMedia: ['url', 'upload'],
|
|
19
21
|
interactive: 'text',
|
|
22
|
+
markdown: 'native',
|
|
20
23
|
},
|
|
21
24
|
create(context) {
|
|
22
25
|
const config = resolveLarkConfig(context.config);
|
|
@@ -28,6 +31,7 @@ export default defineAdapter({
|
|
|
28
31
|
return new LarkEndpoint({
|
|
29
32
|
id: context.id,
|
|
30
33
|
gateway: context.use(messageGatewayToken),
|
|
34
|
+
sideEvents: context.use(sideEventGatewayToken),
|
|
31
35
|
http: context.use(httpHostToken),
|
|
32
36
|
config,
|
|
33
37
|
});
|
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 {
|
|
@@ -16,12 +16,15 @@ export type { LarkEndpointOptions, LarkFetch } from '../src/endpoint.js';
|
|
|
16
16
|
|
|
17
17
|
export default defineAdapter<LarkAdapterConfig>({
|
|
18
18
|
capabilities: ['inbound', 'outbound'],
|
|
19
|
+
operations: ['recall'],
|
|
19
20
|
// image 段 canonical MediaRef 经 /im/v1/images 物化为 image_key
|
|
20
21
|
// (base64 解码 / path 读盘 / url 下载后上传,kind=file 平台引用直通);
|
|
22
|
+
// canonical Markdown 由 endpoint codec 转为 lark_md 消息卡片;
|
|
21
23
|
// 卡片交互未接入出站通道,交互段降级纯文本。
|
|
22
24
|
segments: {
|
|
23
25
|
outboundMedia: ['url', 'upload'],
|
|
24
26
|
interactive: 'text',
|
|
27
|
+
markdown: 'native',
|
|
25
28
|
},
|
|
26
29
|
create(context) {
|
|
27
30
|
const config = resolveLarkConfig(context.config);
|
|
@@ -33,6 +36,7 @@ export default defineAdapter<LarkAdapterConfig>({
|
|
|
33
36
|
return new LarkEndpoint({
|
|
34
37
|
id: context.id,
|
|
35
38
|
gateway: context.use(messageGatewayToken),
|
|
39
|
+
sideEvents: context.use(sideEventGatewayToken),
|
|
36
40
|
http: context.use(httpHostToken),
|
|
37
41
|
config,
|
|
38
42
|
});
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { MessageGateway } from '@zhin.js/core/runtime';
|
|
1
|
+
import { type EndpointControl, type EndpointInstance, type EndpointManagement, type EndpointSendRequest } from 'zhin.js/adapter';
|
|
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;
|
|
@@ -32,6 +33,7 @@ export declare class LarkEndpoint implements EndpointInstance {
|
|
|
32
33
|
* listChannels(无频道/guild 概念)、写操作(审批/踢人/禁言等本轮不在范围内)。
|
|
33
34
|
*/
|
|
34
35
|
readonly management: EndpointManagement;
|
|
36
|
+
readonly control: EndpointControl;
|
|
35
37
|
constructor(options: LarkEndpointOptions);
|
|
36
38
|
/** Used by webhook handler. */
|
|
37
39
|
get isOpen(): boolean;
|
package/lib/endpoint.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
5
|
import { basename } from 'node:path';
|
|
6
|
+
import { createRecallEndpointControl, } from 'zhin.js/adapter';
|
|
6
7
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
7
8
|
import { registerLarkAgentEndpoint } from './lark-agent-deps.js';
|
|
8
9
|
import { buildImageUploadForm, readOutboundImageMedia, resolveMediaBinary, } from './media-upload.js';
|
|
@@ -38,6 +39,7 @@ export class LarkEndpoint {
|
|
|
38
39
|
},
|
|
39
40
|
listGroupMembers: (groupId) => this.#listAllPages(`/im/v1/chats/${encodeURIComponent(groupId)}/members`, { member_id_type: 'open_id' }),
|
|
40
41
|
});
|
|
42
|
+
control = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
41
43
|
#routeReleases = [];
|
|
42
44
|
#accessToken = { token: '', expires_in: 0, timestamp: 0 };
|
|
43
45
|
#refreshPromise = null;
|
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": "
|
|
3
|
+
"version": "7.0.0",
|
|
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.
|
|
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.2.0",
|
|
38
|
+
"@zhin.js/core": "1.5.13",
|
|
39
|
+
"@zhin.js/host-http": "1.0.12",
|
|
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.
|
|
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.2.0",
|
|
46
|
+
"@zhin.js/agent": "1.1.15",
|
|
47
|
+
"@zhin.js/command": "1.0.15",
|
|
48
|
+
"@zhin.js/core": "1.5.13",
|
|
49
|
+
"@zhin.js/host-http": "1.0.12",
|
|
50
|
+
"@zhin.js/permission": "1.0.3",
|
|
51
|
+
"zhin.js": "6.0.13"
|
|
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.15",
|
|
73
|
+
"zhin.js": "6.0.13"
|
|
74
74
|
},
|
|
75
75
|
"files": [
|
|
76
76
|
"adapters",
|
package/src/endpoint.ts
CHANGED
|
@@ -3,8 +3,15 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
5
|
import { basename } from 'node:path';
|
|
6
|
-
import
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
createRecallEndpointControl,
|
|
8
|
+
type EndpointControl,
|
|
9
|
+
type EndpointGroup,
|
|
10
|
+
type EndpointInstance,
|
|
11
|
+
type EndpointManagement,
|
|
12
|
+
type EndpointSendRequest,
|
|
13
|
+
} from 'zhin.js/adapter';
|
|
14
|
+
import type { MessageGateway, SideEventGateway } from '@zhin.js/core/runtime';
|
|
8
15
|
import type { HttpHost, HttpRouteRegistration } from '@zhin.js/host-http';
|
|
9
16
|
import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
|
|
10
17
|
import type { CapabilityId } from 'zhin.js';
|
|
@@ -49,6 +56,7 @@ export type LarkFetch = (
|
|
|
49
56
|
export interface LarkEndpointOptions {
|
|
50
57
|
readonly id: CapabilityId;
|
|
51
58
|
readonly gateway: MessageGateway;
|
|
59
|
+
readonly sideEvents?: SideEventGateway;
|
|
52
60
|
readonly http: HttpHost;
|
|
53
61
|
readonly config: ResolvedLarkConfig;
|
|
54
62
|
readonly fetch?: LarkFetch;
|
|
@@ -85,6 +93,7 @@ export class LarkEndpoint implements EndpointInstance {
|
|
|
85
93
|
{ member_id_type: 'open_id' },
|
|
86
94
|
),
|
|
87
95
|
});
|
|
96
|
+
readonly control: EndpointControl = createRecallEndpointControl((id) => this.recallMessage(id));
|
|
88
97
|
#routeReleases: HttpRouteRegistration[] = [];
|
|
89
98
|
#accessToken: AccessToken = { token: '', expires_in: 0, timestamp: 0 };
|
|
90
99
|
#refreshPromise: Promise<string> | null = null;
|
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('') }),
|