@zhin.js/core 1.5.2 → 1.5.4
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/README.md +2 -2
- package/lib/adapter.d.ts +7 -1
- package/lib/adapter.js +28 -24
- package/lib/agent-prompt.d.ts +2 -3
- package/lib/agent-prompt.js +5 -0
- package/lib/built/ai-outbound/parse.d.ts +1 -1
- package/lib/built/ai-outbound/parse.js +2 -6
- package/lib/built/ai-outbound/plain-mention-rewrite.js +4 -4
- package/lib/built/ai-outbound/resolve.js +8 -8
- package/lib/built/ai-outbound/types.d.ts +3 -3
- package/lib/built/ai-trigger.d.ts +5 -0
- package/lib/built/ai-trigger.js +40 -13
- package/lib/built/authorization.js +4 -4
- package/lib/built/command.d.ts +2 -2
- package/lib/built/command.js +2 -2
- package/lib/built/common-adapter-tools.d.ts +11 -11
- package/lib/built/common-adapter-tools.js +13 -13
- package/lib/built/config.d.ts +0 -4
- package/lib/built/config.js +0 -4
- package/lib/built/dispatcher.d.ts +2 -0
- package/lib/built/dispatcher.js +1 -1
- package/lib/built/endpoint-commands.js +2 -2
- package/lib/built/endpoint-lifecycle-service.js +13 -13
- package/lib/built/endpoint-lifecycle.d.ts +3 -3
- package/lib/built/endpoint-lifecycle.js +2 -2
- package/lib/built/endpoint-manager.d.ts +1 -1
- package/lib/built/interactive-segments/index.d.ts +1 -1
- package/lib/built/interactive-segments/index.js +1 -1
- package/lib/built/interactive-segments/keyboard-segment.d.ts +0 -1
- package/lib/built/interactive-segments/keyboard-segment.js +0 -1
- package/lib/built/interactive-segments/onebot-keyboard.d.ts +0 -3
- package/lib/built/interactive-segments/onebot-keyboard.js +0 -2
- package/lib/built/interactive-segments/resolve.d.ts +0 -3
- package/lib/built/interactive-segments/resolve.js +0 -3
- package/lib/built/interactive-segments/types.d.ts +8 -20
- package/lib/built/interactive-segments/types.js +0 -4
- package/lib/built/login-assist.d.ts +2 -2
- package/lib/built/login-assist.js +2 -2
- package/lib/built/message-enrich.d.ts +1 -1
- package/lib/built/message-enrich.js +2 -7
- package/lib/built/permission.d.ts +0 -4
- package/lib/built/permission.js +0 -4
- package/lib/built/prepend-quote-context.js +5 -5
- package/lib/built/rich-segments/capabilities.js +0 -1
- package/lib/built/rich-segments/html-segment.js +1 -4
- package/lib/built/rich-segments/markdown-segment.js +1 -4
- package/lib/built/rich-segments/types.d.ts +0 -5
- package/lib/built/schema-endpoint-manager.js +6 -6
- package/lib/built/tool.d.ts +5 -3
- package/lib/built/tool.js +14 -23
- package/lib/command.d.ts +4 -4
- package/lib/command.js +8 -11
- package/lib/endpoint-capabilities.d.ts +2 -3
- package/lib/endpoint-capabilities.js +4 -4
- package/lib/endpoint.d.ts +2 -0
- package/lib/endpoint.js +1 -0
- package/lib/errors.d.ts +2 -2
- package/lib/errors.js +4 -4
- package/lib/host-plugin-registry.d.ts +6 -5
- package/lib/host-plugin-registry.js +9 -4
- package/lib/im-scene.d.ts +1 -1
- package/lib/im-scene.js +5 -5
- package/lib/im-session-id.d.ts +2 -2
- package/lib/im-session-id.js +4 -4
- package/lib/index.d.ts +1 -2
- package/lib/index.js +0 -2
- package/lib/jsx-runtime.d.ts +1 -0
- package/lib/jsx.d.ts +19 -21
- package/lib/message.d.ts +1 -1
- package/lib/message.js +1 -1
- package/lib/notice.d.ts +2 -2
- package/lib/plugin-context.d.ts +11 -13
- package/lib/plugin-context.js +21 -18
- package/lib/plugin-runtime/im/contracts.d.ts +91 -12
- package/lib/plugin-runtime/im/contracts.js +79 -1
- package/lib/plugin-runtime/im/im-runtime.d.ts +33 -23
- package/lib/plugin-runtime/im/im-runtime.js +104 -63
- package/lib/plugin-runtime/im/index.d.ts +2 -0
- package/lib/plugin-runtime/im/index.js +2 -0
- package/lib/plugin-runtime/im/message-bus.d.ts +38 -0
- package/lib/plugin-runtime/im/message-bus.js +40 -0
- package/lib/plugin-runtime/im/message-dispatcher.js +13 -73
- package/lib/plugin-runtime/im/outbound-renderer.d.ts +3 -2
- package/lib/plugin-runtime/im/outbound-renderer.js +44 -8
- package/lib/plugin-runtime/im/service-tokens.d.ts +18 -0
- package/lib/plugin-runtime/im/service-tokens.js +13 -0
- package/lib/plugin.d.ts +4 -7
- package/lib/plugin.js +7 -30
- package/lib/request.d.ts +2 -2
- package/lib/side-event/types.d.ts +0 -4
- package/lib/types.d.ts +6 -11
- package/lib/utils.js +3 -1
- package/package.json +13 -12
- package/lib/built/qrcode-segment.d.ts +0 -18
- package/lib/built/qrcode-segment.js +0 -78
- package/lib/types-generator.d.ts +0 -5
- package/lib/types-generator.js +0 -71
package/lib/command.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SegmentMatcher } from 'segment-matcher';
|
|
2
|
+
import { toPermissionSubject } from '@zhin.js/permission';
|
|
2
3
|
/**
|
|
3
4
|
* MessageCommand类:经典命令系统(segment-matcher)。
|
|
4
5
|
*
|
|
@@ -75,26 +76,22 @@ export class MessageCommand extends SegmentMatcher {
|
|
|
75
76
|
return this.#permissions;
|
|
76
77
|
}
|
|
77
78
|
/** 与 handle 一致的 permit 校验,供帮助菜单等场景过滤不可见命令 */
|
|
78
|
-
async checkPermits(message,
|
|
79
|
+
async checkPermits(message, host) {
|
|
79
80
|
if (!this.#permissions.length)
|
|
80
81
|
return true;
|
|
81
|
-
|
|
82
|
-
if (!auth)
|
|
82
|
+
if (!host)
|
|
83
83
|
return false;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
return true;
|
|
84
|
+
const subject = toPermissionSubject(message);
|
|
85
|
+
return host.checkAll(this.#permissions, subject);
|
|
89
86
|
}
|
|
90
87
|
/**
|
|
91
88
|
* 处理消息,自动匹配命令并执行回调
|
|
92
89
|
* @param message 消息对象
|
|
93
|
-
* @param
|
|
90
|
+
* @param host PermissionHost(null 时有 permit 的命令 fail-closed)
|
|
94
91
|
* @returns 命令返回内容或undefined
|
|
95
92
|
*/
|
|
96
|
-
async handle(message,
|
|
97
|
-
if (!(await this.checkPermits(message,
|
|
93
|
+
async handle(message, host) {
|
|
94
|
+
if (!(await this.checkPermits(message, host))) {
|
|
98
95
|
return;
|
|
99
96
|
}
|
|
100
97
|
const matched = this.match(message.$content);
|
|
@@ -22,15 +22,14 @@ export interface OutboundEndpoint<Config extends object = object> {
|
|
|
22
22
|
$config: Config;
|
|
23
23
|
$connected: boolean;
|
|
24
24
|
$sendMessage(options: SendOptions): Promise<string>;
|
|
25
|
-
$recallMessage(id: string): Promise<void>;
|
|
26
25
|
}
|
|
27
26
|
export type FullEndpoint<Config extends object = object, Event extends object = object> = InboundEndpoint<Config, Event> & OutboundEndpoint<Config>;
|
|
28
27
|
export type CapableEndpoint<Config extends object, Event extends object, Caps extends readonly EndpointCapability[]> = ('inbound' extends Caps[number] ? InboundEndpoint<Config, Event> : object) & ('outbound' extends Caps[number] ? OutboundEndpoint<Config> : object);
|
|
29
28
|
export declare class OutboundNotSupportedError extends Error {
|
|
30
|
-
constructor(
|
|
29
|
+
constructor(endpointKey?: string);
|
|
31
30
|
}
|
|
32
31
|
export declare class InboundNotSupportedError extends Error {
|
|
33
|
-
constructor(
|
|
32
|
+
constructor(endpointKey?: string);
|
|
34
33
|
}
|
|
35
34
|
export declare function registerEndpointCapabilities(endpoint: object, caps: readonly EndpointCapability[]): void;
|
|
36
35
|
export declare function getEndpointCapabilities(endpoint: object): readonly EndpointCapability[] | undefined;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
export const DEFAULT_ENDPOINT_CAPABILITIES = ['inbound', 'outbound'];
|
|
2
2
|
export class OutboundNotSupportedError extends Error {
|
|
3
|
-
constructor(
|
|
4
|
-
super(
|
|
3
|
+
constructor(endpointKey) {
|
|
4
|
+
super(endpointKey ? `Endpoint ${endpointKey} does not support outbound` : 'Outbound not supported');
|
|
5
5
|
this.name = 'OutboundNotSupportedError';
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
8
|
export class InboundNotSupportedError extends Error {
|
|
9
|
-
constructor(
|
|
10
|
-
super(
|
|
9
|
+
constructor(endpointKey) {
|
|
10
|
+
super(endpointKey ? `Endpoint ${endpointKey} does not support inbound` : 'Inbound not supported');
|
|
11
11
|
this.name = 'InboundNotSupportedError';
|
|
12
12
|
}
|
|
13
13
|
}
|
package/lib/endpoint.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type { EndpointCapabilitiesConfig, FullEndpoint } from './endpoint-capabi
|
|
|
3
3
|
import type { EndpointWithManagement } from '@zhin.js/adapter';
|
|
4
4
|
export type { EndpointChannel, EndpointChannelParent, EndpointFriend, EndpointGroup, EndpointManagement, EndpointWithManagement, EndpointManagementCapability, } from '@zhin.js/adapter';
|
|
5
5
|
export { endpointManagementCapabilityIds, listEndpointManagementCapabilities, resolveEndpointManagement, } from '@zhin.js/adapter';
|
|
6
|
+
export type { EndpointControl, EndpointWithControl } from '@zhin.js/adapter';
|
|
7
|
+
export { resolveEndpointControl } from '@zhin.js/adapter';
|
|
6
8
|
export type { EndpointCapability, EndpointCapabilitiesConfig, InboundEndpoint, OutboundEndpoint, FullEndpoint, CapableEndpoint, } from './endpoint-capabilities.js';
|
|
7
9
|
export { DEFAULT_ENDPOINT_CAPABILITIES, OutboundNotSupportedError, InboundNotSupportedError, resolveEndpointCapabilities, registerEndpointCapabilities, getEndpointCapabilities, getAdapterCapabilities, hasInbound, hasOutbound, assertInbound, assertOutbound, } from './endpoint-capabilities.js';
|
|
8
10
|
/**
|
package/lib/endpoint.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { endpointManagementCapabilityIds, listEndpointManagementCapabilities, resolveEndpointManagement, } from '@zhin.js/adapter';
|
|
2
|
+
export { resolveEndpointControl } from '@zhin.js/adapter';
|
|
2
3
|
export { DEFAULT_ENDPOINT_CAPABILITIES, OutboundNotSupportedError, InboundNotSupportedError, resolveEndpointCapabilities, registerEndpointCapabilities, getEndpointCapabilities, getAdapterCapabilities, hasInbound, hasOutbound, assertInbound, assertOutbound, } from './endpoint-capabilities.js';
|
package/lib/errors.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ import { ZhinError } from '@zhin.js/kernel';
|
|
|
8
8
|
*/
|
|
9
9
|
export declare class AdapterError extends ZhinError {
|
|
10
10
|
readonly adapterName: string;
|
|
11
|
-
readonly
|
|
12
|
-
constructor(message: string, adapterName: string,
|
|
11
|
+
readonly endpointKey?: string;
|
|
12
|
+
constructor(message: string, adapterName: string, endpointKey?: string, context?: Record<string, any>);
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
15
|
* 消息处理错误
|
package/lib/errors.js
CHANGED
|
@@ -8,11 +8,11 @@ import { ZhinError } from '@zhin.js/kernel';
|
|
|
8
8
|
*/
|
|
9
9
|
export class AdapterError extends ZhinError {
|
|
10
10
|
adapterName;
|
|
11
|
-
|
|
12
|
-
constructor(message, adapterName,
|
|
13
|
-
super(message, 'ADAPTER_ERROR', { ...context, adapterName,
|
|
11
|
+
endpointKey;
|
|
12
|
+
constructor(message, adapterName, endpointKey, context) {
|
|
13
|
+
super(message, 'ADAPTER_ERROR', { ...context, adapterName, endpointKey });
|
|
14
14
|
this.adapterName = adapterName;
|
|
15
|
-
this.
|
|
15
|
+
this.endpointKey = endpointKey;
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
2
|
+
* @deprecated **已删除**。全局根插件注册表已移除;服务通过 Scope+Token 提供。
|
|
3
|
+
* 保留 no-op 签名供编译期过渡。
|
|
4
4
|
*/
|
|
5
|
-
|
|
6
|
-
export declare function setHostRootPlugin(
|
|
7
|
-
|
|
5
|
+
/** @deprecated 已删除——不做任何事。 */
|
|
6
|
+
export declare function setHostRootPlugin(_plugin: unknown): void;
|
|
7
|
+
/** @deprecated 已删除——总是返回 null。 */
|
|
8
|
+
export declare function getHostRootPlugin(): null;
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated **已删除**。全局根插件注册表已移除;服务通过 Scope+Token 提供。
|
|
3
|
+
* 保留 no-op 签名供编译期过渡。
|
|
4
|
+
*/
|
|
5
|
+
/** @deprecated 已删除——不做任何事。 */
|
|
6
|
+
export function setHostRootPlugin(_plugin) {
|
|
7
|
+
// no-op: legacy host root plugin registry has been removed
|
|
4
8
|
}
|
|
9
|
+
/** @deprecated 已删除——总是返回 null。 */
|
|
5
10
|
export function getHostRootPlugin() {
|
|
6
|
-
return
|
|
11
|
+
return null;
|
|
7
12
|
}
|
package/lib/im-scene.d.ts
CHANGED
package/lib/im-scene.js
CHANGED
|
@@ -12,9 +12,9 @@ export function normalizeIMSceneParentKind(value) {
|
|
|
12
12
|
}
|
|
13
13
|
export function sceneRefFromMessage(message) {
|
|
14
14
|
const platform = nonEmptyString(message.$adapter);
|
|
15
|
-
const
|
|
15
|
+
const endpointKey = nonEmptyString(message.$endpoint);
|
|
16
16
|
const kind = message.$channel?.type;
|
|
17
|
-
if (!platform || !
|
|
17
|
+
if (!platform || !endpointKey || !kind)
|
|
18
18
|
return undefined;
|
|
19
19
|
const senderId = nonEmptyString(message.$sender?.id);
|
|
20
20
|
const channelId = nonEmptyString(message.$channel?.id);
|
|
@@ -34,7 +34,7 @@ export function sceneRefFromMessage(message) {
|
|
|
34
34
|
: undefined;
|
|
35
35
|
return {
|
|
36
36
|
platform,
|
|
37
|
-
|
|
37
|
+
endpointKey,
|
|
38
38
|
sceneId,
|
|
39
39
|
kind,
|
|
40
40
|
...(senderId ? { senderId } : {}),
|
|
@@ -45,7 +45,7 @@ export function sceneRefToSendOptions(target, content) {
|
|
|
45
45
|
const { scene } = target;
|
|
46
46
|
return {
|
|
47
47
|
context: scene.platform,
|
|
48
|
-
endpoint: scene.
|
|
48
|
+
endpoint: scene.endpointKey,
|
|
49
49
|
id: scene.sceneId,
|
|
50
50
|
type: scene.kind,
|
|
51
51
|
parent: scene.parent
|
|
@@ -59,7 +59,7 @@ export function sceneRefToSendOptions(target, content) {
|
|
|
59
59
|
export function resolveIMSceneSessionId(scene) {
|
|
60
60
|
return resolveIMSceneSessionIdKernel({
|
|
61
61
|
platform: scene.platform,
|
|
62
|
-
|
|
62
|
+
endpointKey: scene.endpointKey,
|
|
63
63
|
sceneId: scene.sceneId,
|
|
64
64
|
kind: scene.kind,
|
|
65
65
|
});
|
package/lib/im-session-id.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* IM 会话 ID 解析(SSOT 在 @zhin.js/kernel + im-scene)
|
|
3
3
|
*
|
|
4
|
-
* 格式:`platform:
|
|
4
|
+
* 格式:`platform:endpointKey:kind:sceneId`
|
|
5
5
|
*/
|
|
6
6
|
import { type ResolveIMSessionIdInput } from '@zhin.js/kernel';
|
|
7
7
|
import { type IMSceneKind, type IMSceneRef } from './im-scene.js';
|
|
@@ -33,7 +33,7 @@ export declare function resolveSceneFieldsFromMessage(message: {
|
|
|
33
33
|
};
|
|
34
34
|
}): {
|
|
35
35
|
platform: string;
|
|
36
|
-
|
|
36
|
+
endpointKey: string;
|
|
37
37
|
sceneId: string;
|
|
38
38
|
sceneType: IMSceneKind;
|
|
39
39
|
};
|
package/lib/im-session-id.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* IM 会话 ID 解析(SSOT 在 @zhin.js/kernel + im-scene)
|
|
3
3
|
*
|
|
4
|
-
* 格式:`platform:
|
|
4
|
+
* 格式:`platform:endpointKey:kind:sceneId`
|
|
5
5
|
*/
|
|
6
6
|
import { resolveIMSceneIdForSession as resolveIMSceneIdForSessionKernel, resolveIMSessionId as resolveIMSessionIdKernel, } from '@zhin.js/kernel';
|
|
7
7
|
import { resolveIMSceneSessionId, sceneRefFromMessage, } from './im-scene.js';
|
|
@@ -21,7 +21,7 @@ export function resolveIMSessionIdFromMessage(message) {
|
|
|
21
21
|
const kind = (message.$channel?.type || 'private');
|
|
22
22
|
return resolveIMSessionId({
|
|
23
23
|
platform: String(message.$adapter || ''),
|
|
24
|
-
|
|
24
|
+
endpointKey: String(message.$endpoint || ''),
|
|
25
25
|
kind,
|
|
26
26
|
sceneId: resolveIMSceneIdForSession(kind, message.$channel?.id, message.$sender?.id),
|
|
27
27
|
});
|
|
@@ -32,7 +32,7 @@ export function resolveSceneFieldsFromMessage(message) {
|
|
|
32
32
|
if (scene) {
|
|
33
33
|
return {
|
|
34
34
|
platform: scene.platform,
|
|
35
|
-
|
|
35
|
+
endpointKey: scene.endpointKey,
|
|
36
36
|
sceneId: scene.sceneId,
|
|
37
37
|
sceneType: scene.kind,
|
|
38
38
|
};
|
|
@@ -40,7 +40,7 @@ export function resolveSceneFieldsFromMessage(message) {
|
|
|
40
40
|
const sceneType = (message.$channel?.type || 'private');
|
|
41
41
|
return {
|
|
42
42
|
platform: String(message.$adapter || ''),
|
|
43
|
-
|
|
43
|
+
endpointKey: String(message.$endpoint || ''),
|
|
44
44
|
sceneType,
|
|
45
45
|
sceneId: resolveIMSceneIdForSession(sceneType, message.$channel?.id, message.$sender?.id),
|
|
46
46
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -20,7 +20,6 @@ export * from './built/schedule.js';
|
|
|
20
20
|
export type { ScheduleDescriptor, ScheduleHandle, ScheduleContextExtensions } from './built/schedule.js';
|
|
21
21
|
export * from './models/system-log.js';
|
|
22
22
|
export * from './models/user.js';
|
|
23
|
-
export * from './built/permission.js';
|
|
24
23
|
export * from './built/permit-parse.js';
|
|
25
24
|
export * from './built/permit-check.js';
|
|
26
25
|
export * from './built/platform-permit.js';
|
|
@@ -42,7 +41,6 @@ export * from './built/dispatcher.js';
|
|
|
42
41
|
export * from './built/schema-feature.js';
|
|
43
42
|
export * from './built/login-assist.js';
|
|
44
43
|
export * from './built/generated-qrcode.js';
|
|
45
|
-
export * from './built/qrcode-segment.js';
|
|
46
44
|
export * from './built/rich-segments/index.js';
|
|
47
45
|
export * from './built/interactive-segments/index.js';
|
|
48
46
|
export * from './built/ai-outbound/index.js';
|
|
@@ -52,6 +50,7 @@ export * from './built/outbound-media-utils.js';
|
|
|
52
50
|
export * from './built/outbound-media-contract.js';
|
|
53
51
|
export * from './built/interactive-segment-contract.js';
|
|
54
52
|
export * from './built/segment-contract/index.js';
|
|
53
|
+
export type { SegmentMediaRef } from './built/segment-contract/media.js';
|
|
55
54
|
export * from './built/generic-segment-mapper.js';
|
|
56
55
|
export * from './built/adapter-process.js';
|
|
57
56
|
export * from './built/component.js';
|
package/lib/index.js
CHANGED
|
@@ -22,7 +22,6 @@ export * from './built/schedule.js';
|
|
|
22
22
|
// Models
|
|
23
23
|
export * from './models/system-log.js';
|
|
24
24
|
export * from './models/user.js';
|
|
25
|
-
export * from './built/permission.js';
|
|
26
25
|
export * from './built/permit-parse.js';
|
|
27
26
|
export * from './built/permit-check.js';
|
|
28
27
|
export * from './built/platform-permit.js';
|
|
@@ -43,7 +42,6 @@ export * from './built/dispatcher.js';
|
|
|
43
42
|
export * from './built/schema-feature.js';
|
|
44
43
|
export * from './built/login-assist.js';
|
|
45
44
|
export * from './built/generated-qrcode.js';
|
|
46
|
-
export * from './built/qrcode-segment.js';
|
|
47
45
|
export * from './built/rich-segments/index.js';
|
|
48
46
|
export * from './built/interactive-segments/index.js';
|
|
49
47
|
export * from './built/ai-outbound/index.js';
|
package/lib/jsx-runtime.d.ts
CHANGED
package/lib/jsx.d.ts
CHANGED
|
@@ -1,30 +1,28 @@
|
|
|
1
|
-
import { SendContent, MessageElement } from './types.js';
|
|
2
|
-
import { MessageComponent } from './message.js';
|
|
3
|
-
import { Component, ComponentContext } from './component.js';
|
|
1
|
+
import type { SendContent, MessageElement } from './types.js';
|
|
2
|
+
import type { MessageComponent } from './message.js';
|
|
3
|
+
import type { Component, ComponentContext } from './component.js';
|
|
4
4
|
export type JSXChildren = MessageElement | string | number | boolean | null | undefined | JSXChildren[];
|
|
5
5
|
export type JSXElementType = string | Component<any>;
|
|
6
6
|
export type JSXProps = Record<string, any> & {
|
|
7
7
|
children?: JSXChildren;
|
|
8
8
|
};
|
|
9
9
|
export { Fragment } from './component.js';
|
|
10
|
-
declare
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
key?: string | number;
|
|
27
|
-
}
|
|
10
|
+
export declare namespace JSX {
|
|
11
|
+
type Element = SendContent | Promise<SendContent>;
|
|
12
|
+
interface ElementClass {
|
|
13
|
+
render(props: any, context?: ComponentContext): Element;
|
|
14
|
+
}
|
|
15
|
+
interface ElementAttributesProperty {
|
|
16
|
+
data: {};
|
|
17
|
+
}
|
|
18
|
+
interface ElementChildrenAttribute {
|
|
19
|
+
children: {};
|
|
20
|
+
}
|
|
21
|
+
interface IntrinsicElements {
|
|
22
|
+
[elemName: string]: any;
|
|
23
|
+
}
|
|
24
|
+
interface IntrinsicAttributes {
|
|
25
|
+
key?: string | number;
|
|
28
26
|
}
|
|
29
27
|
}
|
|
30
28
|
export declare function jsx(type: JSXElementType, data: JSXProps): MessageComponent<any>;
|
package/lib/message.d.ts
CHANGED
package/lib/message.js
CHANGED
package/lib/notice.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Adapters } from './adapter.js';
|
|
2
2
|
import type { NoticeKind } from './side-event/types.js';
|
|
3
3
|
import type { SideEventBase } from './side-event/base.js';
|
|
4
|
-
export type { NoticeKind, ComposedNoticeName
|
|
4
|
+
export type { NoticeKind, ComposedNoticeName } from './side-event/types.js';
|
|
5
5
|
export type { SideEventBase } from './side-event/base.js';
|
|
6
6
|
export { composeSideEventName, formatSideEventName, matchesSideEventName, parseSideEventName, sideEventSendChannel, } from './side-event/base.js';
|
|
7
7
|
/**
|
|
@@ -12,7 +12,7 @@ export { composeSideEventName, formatSideEventName, matchesSideEventName, parseS
|
|
|
12
12
|
* const notice = Notice.from(rawEvent, {
|
|
13
13
|
* $id: rawEvent.id,
|
|
14
14
|
* $adapter: 'icqq',
|
|
15
|
-
* $endpoint:
|
|
15
|
+
* $endpoint: endpointKey,
|
|
16
16
|
* $type: 'notice',
|
|
17
17
|
* $scene_id: groupId,
|
|
18
18
|
* $scene_type: 'group',
|
package/lib/plugin-context.d.ts
CHANGED
|
@@ -7,23 +7,21 @@
|
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
8
|
import type { Plugin } from "./plugin.js";
|
|
9
9
|
export declare const storage: AsyncLocalStorage<Plugin>;
|
|
10
|
+
/**
|
|
11
|
+
* Plugin Runtime (`zhin runtime start`) 启动时调用。
|
|
12
|
+
* 标记后 getPlugin()/usePlugin() 在 ALS 为空时抛出更明确的迁移提示,
|
|
13
|
+
* 而非通用的 "must be called within a plugin context"。
|
|
14
|
+
*/
|
|
15
|
+
export declare function markPluginRuntimeActive(): void;
|
|
16
|
+
export declare function isPluginRuntimeActive(): boolean;
|
|
17
|
+
/** 测试重置 */
|
|
18
|
+
export declare function resetPluginRuntimeFlag(): void;
|
|
10
19
|
/**
|
|
11
20
|
* 获取当前文件路径(调用者)
|
|
12
21
|
*/
|
|
13
22
|
export declare function getCurrentFile(metaUrl?: string): string;
|
|
14
23
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* **调用时机(重要)**
|
|
18
|
-
* - ✅ 插件**初始化/装配**阶段:模块顶层、register/init 函数内、注册命令/中间件/工具**之前**
|
|
19
|
-
* - ❌ **运行时回调**内严禁调用:中间件、命令 `.action()`、工具 `.execute()`、Cron、生命周期 `.on()` 等
|
|
20
|
-
*
|
|
21
|
-
* 运行时回调应使用初始化时捕获的 `plugin` / `root` 闭包引用,而非再次 `getPlugin()`。
|
|
22
|
-
* AsyncLocalStorage 在跨 await、线程池、部分平台适配器回调中可能丢失,导致线上 `getPlugin() must be called within a plugin context`。
|
|
23
|
-
*
|
|
24
|
-
* 插件作者优先在模块顶层使用 `usePlugin()` 解构 API,一般不需要 `getPlugin()`。
|
|
25
|
-
* Bot 启动时框架调用 `setHostRootPlugin(root)`;运行时模块用 `getHostRootPlugin()` 代替 `getPlugin()`。
|
|
26
|
-
*
|
|
27
|
-
* @see docs/guide/plugin-development.md#getplugin-与-useplugin
|
|
24
|
+
* @deprecated **已删除**。请使用 `definePlugin` + 约定目录;运行时通过 Scope+Token 访问服务。
|
|
25
|
+
* @throws 总是抛出——仅保留签名供编译期过渡。
|
|
28
26
|
*/
|
|
29
27
|
export declare function getPlugin(): Plugin;
|
package/lib/plugin-context.js
CHANGED
|
@@ -11,6 +11,22 @@ import { fileURLToPath } from "node:url";
|
|
|
11
11
|
// AsyncLocalStorage 上下文
|
|
12
12
|
// ============================================================================
|
|
13
13
|
export const storage = new AsyncLocalStorage();
|
|
14
|
+
let _pluginRuntimeActive = false;
|
|
15
|
+
/**
|
|
16
|
+
* Plugin Runtime (`zhin runtime start`) 启动时调用。
|
|
17
|
+
* 标记后 getPlugin()/usePlugin() 在 ALS 为空时抛出更明确的迁移提示,
|
|
18
|
+
* 而非通用的 "must be called within a plugin context"。
|
|
19
|
+
*/
|
|
20
|
+
export function markPluginRuntimeActive() {
|
|
21
|
+
_pluginRuntimeActive = true;
|
|
22
|
+
}
|
|
23
|
+
export function isPluginRuntimeActive() {
|
|
24
|
+
return _pluginRuntimeActive;
|
|
25
|
+
}
|
|
26
|
+
/** 测试重置 */
|
|
27
|
+
export function resetPluginRuntimeFlag() {
|
|
28
|
+
_pluginRuntimeActive = false;
|
|
29
|
+
}
|
|
14
30
|
/**
|
|
15
31
|
* 获取当前文件路径(调用者)
|
|
16
32
|
*/
|
|
@@ -38,24 +54,11 @@ export function getCurrentFile(metaUrl = import.meta.url) {
|
|
|
38
54
|
}
|
|
39
55
|
}
|
|
40
56
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* **调用时机(重要)**
|
|
44
|
-
* - ✅ 插件**初始化/装配**阶段:模块顶层、register/init 函数内、注册命令/中间件/工具**之前**
|
|
45
|
-
* - ❌ **运行时回调**内严禁调用:中间件、命令 `.action()`、工具 `.execute()`、Cron、生命周期 `.on()` 等
|
|
46
|
-
*
|
|
47
|
-
* 运行时回调应使用初始化时捕获的 `plugin` / `root` 闭包引用,而非再次 `getPlugin()`。
|
|
48
|
-
* AsyncLocalStorage 在跨 await、线程池、部分平台适配器回调中可能丢失,导致线上 `getPlugin() must be called within a plugin context`。
|
|
49
|
-
*
|
|
50
|
-
* 插件作者优先在模块顶层使用 `usePlugin()` 解构 API,一般不需要 `getPlugin()`。
|
|
51
|
-
* Bot 启动时框架调用 `setHostRootPlugin(root)`;运行时模块用 `getHostRootPlugin()` 代替 `getPlugin()`。
|
|
52
|
-
*
|
|
53
|
-
* @see docs/guide/plugin-development.md#getplugin-与-useplugin
|
|
57
|
+
* @deprecated **已删除**。请使用 `definePlugin` + 约定目录;运行时通过 Scope+Token 访问服务。
|
|
58
|
+
* @throws 总是抛出——仅保留签名供编译期过渡。
|
|
54
59
|
*/
|
|
55
60
|
export function getPlugin() {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
return plugin;
|
|
61
|
+
throw new Error('getPlugin() has been removed. Use `definePlugin` + convention directories, '
|
|
62
|
+
+ 'and access services via Scope+Token. '
|
|
63
|
+
+ 'See docs/contributing/public-api-surface.md');
|
|
61
64
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PluginId
|
|
1
|
+
import type { PluginId } from '@zhin.js/plugin-runtime';
|
|
2
2
|
import type { ConversationRef, DeliveryReceipt, MessageRef } from '@zhin.js/im-contract';
|
|
3
3
|
import type { MediaRef, Segment } from '../../built/segment-contract/types.js';
|
|
4
4
|
export type { MediaRef, Segment };
|
|
@@ -24,22 +24,56 @@ export declare function isComponentCall(value: SendContent): value is ComponentC
|
|
|
24
24
|
export declare function isRawContent(value: SendContent): value is RawContent;
|
|
25
25
|
/** canonical Segment 一等公民判定(与 ComponentCall/RawContent 的 $content brand 互斥)。 */
|
|
26
26
|
export declare function isSegmentContent(value: unknown): value is Segment;
|
|
27
|
+
export interface MessageSenderRef {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly name?: string;
|
|
30
|
+
readonly roles?: readonly string[];
|
|
31
|
+
}
|
|
27
32
|
export interface IncomingMessage {
|
|
28
33
|
readonly conversation: ConversationRef;
|
|
29
34
|
readonly message?: MessageRef;
|
|
30
35
|
readonly content: string;
|
|
31
36
|
readonly segments?: readonly Segment[];
|
|
32
|
-
readonly sender?:
|
|
37
|
+
readonly sender?: MessageSenderRef;
|
|
38
|
+
/** Endpoint 实例名(如 ICQQ uin、sandbox bot name),区别于 conversation.endpoint.id(CapabilityId)。 */
|
|
39
|
+
readonly endpointId?: string;
|
|
40
|
+
/** 消息是否 @了机器人。 */
|
|
41
|
+
readonly mentioned?: boolean;
|
|
42
|
+
/** 引用/回复的原始消息。 */
|
|
43
|
+
readonly replyTo?: {
|
|
44
|
+
readonly id: string;
|
|
45
|
+
};
|
|
33
46
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
34
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* 入站消息上下文快照 — 由 reply 闭包捕获,沿出站链路传递到模板编译。
|
|
50
|
+
* 定时任务 / 跨通道发送时整个 incoming 为 undefined。
|
|
51
|
+
*/
|
|
52
|
+
export interface IncomingContext {
|
|
53
|
+
readonly sender?: MessageSenderRef;
|
|
54
|
+
/** 收到的消息纯文本内容。 */
|
|
55
|
+
readonly content: string;
|
|
56
|
+
/** 结构化消息段(图片、@、引用等)。 */
|
|
57
|
+
readonly segments?: readonly Segment[];
|
|
58
|
+
/** 平台原生消息 ID。 */
|
|
59
|
+
readonly messageId?: string;
|
|
60
|
+
/** 消息到达时间戳(ms)。 */
|
|
61
|
+
readonly timestamp: number;
|
|
62
|
+
/** Endpoint 实例名(如 ICQQ uin、sandbox bot name)。 */
|
|
63
|
+
readonly endpointId?: string;
|
|
64
|
+
/** 消息是否 @了机器人。 */
|
|
65
|
+
readonly mentioned?: boolean;
|
|
66
|
+
}
|
|
35
67
|
export interface SendRequest {
|
|
36
68
|
readonly conversation: ConversationRef;
|
|
37
69
|
readonly requester: PluginId;
|
|
38
70
|
readonly content: SendContent;
|
|
71
|
+
/** Incoming message context (absent for scheduled / cross-channel sends). */
|
|
72
|
+
readonly incoming?: IncomingContext;
|
|
39
73
|
}
|
|
40
74
|
/**
|
|
41
75
|
* Host 侧未锚定 endpoint 的会话地址(Console RPC / OutboundHost 入参);
|
|
42
|
-
* ImRuntime 解析 adapter/
|
|
76
|
+
* ImRuntime 解析 adapter/endpointKey 后锚定为完整 ConversationRef。
|
|
43
77
|
*/
|
|
44
78
|
export type ConversationAddress = Omit<ConversationRef, 'endpoint'>;
|
|
45
79
|
export interface OutboundEnvelope {
|
|
@@ -58,12 +92,6 @@ export interface MessageGateway {
|
|
|
58
92
|
* payload 都会路由到这里。
|
|
59
93
|
*/
|
|
60
94
|
registerInteractiveHandler(prefix: string, handler: (message: Message) => Promise<boolean> | boolean): () => void;
|
|
61
|
-
/**
|
|
62
|
-
* Command miss(或非前缀文本)后的回退处理:Host AI 对话、单文件 bot 用。
|
|
63
|
-
* 返回 true 表示已处理(回复已发送);后注册者覆盖前者。
|
|
64
|
-
* `requester` 是消息所属 Adapter Endpoint 的 owner(用于 CapabilityIngress 继承)。
|
|
65
|
-
*/
|
|
66
|
-
setUnmatchedHandler(handler: (message: Message, snapshot: RuntimeSnapshot, requester: PluginId) => Promise<boolean>): void;
|
|
67
95
|
}
|
|
68
96
|
export interface MessageDispatchResult {
|
|
69
97
|
readonly matched: boolean;
|
|
@@ -75,7 +103,7 @@ export declare class Message {
|
|
|
75
103
|
readonly conversation: ConversationRef;
|
|
76
104
|
readonly content: string;
|
|
77
105
|
readonly generation: number;
|
|
78
|
-
readonly sender?:
|
|
106
|
+
readonly sender?: MessageSenderRef | undefined;
|
|
79
107
|
readonly metadata: Readonly<Record<string, unknown>>;
|
|
80
108
|
/**
|
|
81
109
|
* 结构化段视图(与 `content` 纯文本视图同源,见 IncomingMessage.segments)。
|
|
@@ -84,17 +112,68 @@ export declare class Message {
|
|
|
84
112
|
readonly segments?: readonly Segment[] | undefined;
|
|
85
113
|
/** 结构化入站消息身份(平台原生 message id 经 MessageRef 传递)。 */
|
|
86
114
|
readonly message?: MessageRef | undefined;
|
|
87
|
-
|
|
115
|
+
readonly endpointId?: string | undefined;
|
|
116
|
+
readonly mentioned?: boolean | undefined;
|
|
117
|
+
readonly replyTo?: {
|
|
118
|
+
readonly id: string;
|
|
119
|
+
} | undefined;
|
|
120
|
+
constructor(conversation: ConversationRef, content: string, generation: number, reply: (content: SendContent, requester?: PluginId, targetConversation?: ConversationAddress) => Promise<DeliveryReceipt>, sender?: MessageSenderRef | undefined, metadata?: Readonly<Record<string, unknown>>,
|
|
88
121
|
/**
|
|
89
122
|
* 结构化段视图(与 `content` 纯文本视图同源,见 IncomingMessage.segments)。
|
|
90
123
|
* Command dispatcher 优先使用此字段,以支持 mention、image 等结构化参数。
|
|
91
124
|
*/
|
|
92
125
|
segments?: readonly Segment[] | undefined,
|
|
93
126
|
/** 结构化入站消息身份(平台原生 message id 经 MessageRef 传递)。 */
|
|
94
|
-
message?: MessageRef | undefined
|
|
127
|
+
message?: MessageRef | undefined, endpointId?: string | undefined, mentioned?: boolean | undefined, replyTo?: {
|
|
128
|
+
readonly id: string;
|
|
129
|
+
} | undefined);
|
|
95
130
|
/** 平台原生消息 id(`message` 未提供时为 undefined)。 */
|
|
96
131
|
get id(): string | undefined;
|
|
97
132
|
readonly $reply: (content: SendContent) => Promise<DeliveryReceipt>;
|
|
98
133
|
readonly $replyFrom: (requester: PluginId, content: SendContent) => Promise<DeliveryReceipt>;
|
|
134
|
+
/**
|
|
135
|
+
* 向同 Endpoint 的另一个通道发送消息(通用)。
|
|
136
|
+
*
|
|
137
|
+
* ```ts
|
|
138
|
+
* await message.$sendTo({ kind: 'channel', id: 'ch-1', parent: { kind: 'channel', id: 'guild-1' } }, '频道通知');
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
readonly $sendTo: (conversation: ConversationAddress, content: SendContent) => Promise<DeliveryReceipt>;
|
|
142
|
+
/**
|
|
143
|
+
* 私信当前消息的发送者(同 Endpoint)。
|
|
144
|
+
*
|
|
145
|
+
* @param content 消息内容
|
|
146
|
+
* @param from 会话上下文:
|
|
147
|
+
* - `true` — 用当前群/频道作为 parent(要求当前不在私聊中)
|
|
148
|
+
* - `{ kind, id }` — 显式指定 parent(群或子频道)
|
|
149
|
+
* - 省略 — 直接私信
|
|
150
|
+
*
|
|
151
|
+
* ```ts
|
|
152
|
+
* await message.$replyToPrivate('直接私信');
|
|
153
|
+
* await message.$replyToPrivate('群临时私信', true);
|
|
154
|
+
* await message.$replyToPrivate('频道私信', { kind: 'channel', id: '子频道ID' });
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
readonly $replyToPrivate: (content: SendContent, from?: boolean | {
|
|
158
|
+
readonly kind: 'group' | 'channel';
|
|
159
|
+
readonly id: string;
|
|
160
|
+
}) => Promise<DeliveryReceipt>;
|
|
161
|
+
/**
|
|
162
|
+
* 向指定群发送消息(同 Endpoint)。
|
|
163
|
+
*
|
|
164
|
+
* ```ts
|
|
165
|
+
* await message.$replyToGroup('67890', '群通知');
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
readonly $replyToGroup: (groupId: string, content: SendContent) => Promise<DeliveryReceipt>;
|
|
169
|
+
/**
|
|
170
|
+
* 向指定频道/子频道发送消息(同 Endpoint)。
|
|
171
|
+
*
|
|
172
|
+
* ```ts
|
|
173
|
+
* await message.$replyToChannel('channel-1', 'guild-1', '频道通知');
|
|
174
|
+
* await message.$replyToChannel('channel-1', 'guild-1', '话题回复', 'thread-1');
|
|
175
|
+
* ```
|
|
176
|
+
*/
|
|
177
|
+
readonly $replyToChannel: (channelId: string, guildId: string, content: SendContent, threadId?: string) => Promise<DeliveryReceipt>;
|
|
99
178
|
}
|
|
100
179
|
export declare function createOutboundEnvelope(request: Omit<OutboundEnvelope, 'payload' | 'replace'>, initialPayload: unknown): OutboundEnvelope;
|