@zhin.js/core 1.5.13 → 1.5.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/lib/adapter.d.ts CHANGED
@@ -41,9 +41,10 @@ export declare abstract class Adapter<R extends Endpoint = Endpoint, const Caps
41
41
  /** 当前正在处理的消息数 */
42
42
  get pendingMessages(): number;
43
43
  /**
44
- * 构造函数
44
+ * 创建一个适配器运行实例。
45
+ * @param plugin 拥有该适配器的插件实例
45
46
  * @param name 适配器名称(如 'process'、'qq' 等)
46
- * @param endpointFactory Bot工厂函数或构造器
47
+ * @param config Endpoint 配置列表
47
48
  */
48
49
  constructor(plugin: Plugin, name: keyof Plugin.Contexts, config: Adapter.EndpointConfig<R>[]);
49
50
  /** 入站消息管线(替代 emit override 的隐式管线) */
package/lib/adapter.js CHANGED
@@ -55,9 +55,10 @@ export class Adapter extends EventEmitter {
55
55
  return this.#pendingMessages;
56
56
  }
57
57
  /**
58
- * 构造函数
58
+ * 创建一个适配器运行实例。
59
+ * @param plugin 拥有该适配器的插件实例
59
60
  * @param name 适配器名称(如 'process'、'qq' 等)
60
- * @param endpointFactory Bot工厂函数或构造器
61
+ * @param config Endpoint 配置列表
61
62
  */
62
63
  constructor(plugin, name, config) {
63
64
  super();
@@ -80,7 +80,7 @@ export type AITriggerMatcher = (message: Message<any>) => {
80
80
  */
81
81
  export type GroupPassiveContextHandler = (message: Message<any>) => MaybePromise<void>;
82
82
  export type GuardrailMiddleware = MessageMiddleware<RegisteredAdapter>;
83
- /** @alias OutboundReplySource:出站回复来源(指令 / AI */
83
+ /** Backward-compatible name for the command or AI outbound reply source. */
84
84
  export type ReplySource = OutboundReplySource;
85
85
  /** replyWithPolish 可选参数 */
86
86
  export interface ReplyWithPolishOptions {
@@ -1,10 +1,52 @@
1
1
  /** Authoring API for Handler Feature — implementation in `@zhin.js/handler`. */
2
- export { defineHandler, parseHandlerDefinition, HandlerIndex, isHandlerIndex, handlerFeatureId, handlerFeature, handlerEventFromLocalName, resolveHandlerEvent, type HandlerEventMap, type HandlerDefinition, type HandlerDescriptor, type HandlerContext, type HandlerDispatchOptions, } from '@zhin.js/handler';
2
+ export { parseHandlerDefinition, HandlerIndex, isHandlerIndex, handlerFeatureId, handlerFeature, handlerEventFromLocalName, resolveHandlerEvent, type HandlerEventMap, type HandlerDefinition, type HandlerDescriptor, type HandlerContext, type HandlerDispatchOptions, } from '@zhin.js/handler';
3
+ import { type HandlerContext, type HandlerDefinition, type HandlerEventMap } from '@zhin.js/handler';
3
4
  import type { Plugin } from '../plugin.js';
5
+ import type { Message } from '../plugin-runtime/im/contracts.js';
6
+ import type { Notice } from '../notice.js';
7
+ import type { Request } from '../request.js';
8
+ import type { SystemEvent } from '../system-event.js';
9
+ import type { AdapterClient, AdapterEvents, EndpointEvent, EndpointIdentity, PlatformEvent, RegisteredAdapterName } from '@zhin.js/adapter';
4
10
  type KnownKeys<T> = {
5
11
  [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
6
12
  };
7
13
  declare module '@zhin.js/handler' {
8
- interface HandlerEventMap extends KnownKeys<Plugin.Lifecycle> {
14
+ interface HandlerEventMap extends KnownKeys<Omit<Plugin.Lifecycle, 'message.receive' | 'notice.receive' | 'request.receive' | 'system.receive'>> {
15
+ 'message.receive': [event: EndpointEvent<Message>];
16
+ 'notice.receive': [event: EndpointEvent<Notice>];
17
+ 'request.receive': [event: EndpointEvent<Request>];
18
+ 'system.receive': [event: EndpointEvent<SystemEvent>];
19
+ 'platform.receive': [event: EndpointEvent<PlatformEvent>];
9
20
  }
10
21
  }
22
+ type NativeEventName<TAdapter extends RegisteredAdapterName> = Extract<keyof AdapterEvents<TAdapter>, string>;
23
+ /** Fully inferred native platform event exposed to plugin handlers. */
24
+ export interface ClientHandlerEvent<TAdapter extends RegisteredAdapterName, TName extends NativeEventName<TAdapter> = NativeEventName<TAdapter>> {
25
+ readonly name: TName;
26
+ readonly event: AdapterEvents<TAdapter>[TName];
27
+ readonly endpoint: EndpointIdentity;
28
+ readonly client: AdapterClient<TAdapter>;
29
+ }
30
+ export interface ClientHandlerOptions<TAdapter extends RegisteredAdapterName, TName extends NativeEventName<TAdapter>> {
31
+ readonly adapter: TAdapter;
32
+ readonly event: TName;
33
+ handle(this: HandlerContext, event: ClientHandlerEvent<TAdapter, TName>): void | Promise<void>;
34
+ }
35
+ export interface ClientHandlerWildcardEvent<TAdapter extends RegisteredAdapterName> {
36
+ readonly name: string;
37
+ readonly event: unknown;
38
+ readonly endpoint: EndpointIdentity;
39
+ readonly client: AdapterClient<TAdapter>;
40
+ }
41
+ export interface ClientHandlerWildcardOptions<TAdapter extends RegisteredAdapterName> {
42
+ readonly adapter: TAdapter;
43
+ readonly event: '*';
44
+ handle(this: HandlerContext, event: ClientHandlerWildcardEvent<TAdapter>): void | Promise<void>;
45
+ }
46
+ export declare function defineHandler<TAdapter extends RegisteredAdapterName, TName extends NativeEventName<TAdapter>>(options: ClientHandlerOptions<TAdapter, TName>): Readonly<HandlerDefinition<'platform.receive'>>;
47
+ /** Handle every native event from one Client without pretending unknown payloads are typed. */
48
+ export declare function defineHandler<TAdapter extends RegisteredAdapterName>(options: ClientHandlerWildcardOptions<TAdapter>): Readonly<HandlerDefinition<'platform.receive'>>;
49
+ export declare function defineHandler<K extends keyof HandlerEventMap & string>(options: {
50
+ readonly event: K;
51
+ handle(this: HandlerContext, ...args: HandlerEventMap[K] extends unknown[] ? HandlerEventMap[K] : unknown[]): void | Promise<void>;
52
+ }): Readonly<HandlerDefinition<K>>;
@@ -1,2 +1,26 @@
1
1
  /** Authoring API for Handler Feature — implementation in `@zhin.js/handler`. */
2
- export { defineHandler, parseHandlerDefinition, HandlerIndex, isHandlerIndex, handlerFeatureId, handlerFeature, handlerEventFromLocalName, resolveHandlerEvent, } from '@zhin.js/handler';
2
+ export { parseHandlerDefinition, HandlerIndex, isHandlerIndex, handlerFeatureId, handlerFeature, handlerEventFromLocalName, resolveHandlerEvent, } from '@zhin.js/handler';
3
+ import { defineHandler as defineHandlerFeature, } from '@zhin.js/handler';
4
+ export function defineHandler(options) {
5
+ if (!('adapter' in options) || typeof options.adapter !== 'string') {
6
+ return defineHandlerFeature(options);
7
+ }
8
+ const adapter = options.adapter;
9
+ const expectedName = options.event === '*' ? undefined : options.event;
10
+ return defineHandlerFeature({
11
+ event: 'platform.receive',
12
+ async handle(source) {
13
+ if (source.endpoint.adapter !== adapter)
14
+ return;
15
+ if (expectedName !== undefined && source.payload.name !== expectedName)
16
+ return;
17
+ const event = Object.freeze({
18
+ name: source.payload.name,
19
+ event: source.payload.event,
20
+ endpoint: source.endpoint,
21
+ client: source.client,
22
+ });
23
+ await options.handle.call(this, event);
24
+ },
25
+ });
26
+ }
package/lib/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Canonical IM messages, Endpoints, rendering, and plugin-facing core types.
3
+ * @module @zhin.js/core
4
+ */
1
5
  export * from './endpoint.js';
2
6
  export * from './endpoint-capabilities.js';
3
7
  export * from './plugin.js';
@@ -13,7 +17,6 @@ export * from './side-event/index.js';
13
17
  export * from './schema-interaction.js';
14
18
  export type * from '@zhin.js/interaction';
15
19
  export * from './types.js';
16
- export * from './agent-prompt.js';
17
20
  export * from './utils.js';
18
21
  export * from './errors.js';
19
22
  export * from './built/config.js';
package/lib/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Canonical IM messages, Endpoints, rendering, and plugin-facing core types.
3
+ * @module @zhin.js/core
4
+ */
1
5
  // ── Core 类模块 ──────────────────────────────────────────────────────
2
6
  export * from './endpoint.js';
3
7
  export * from './endpoint-capabilities.js';
@@ -13,7 +17,6 @@ export * from './system-event.js';
13
17
  export * from './side-event/index.js';
14
18
  export * from './schema-interaction.js';
15
19
  export * from './types.js';
16
- export * from './agent-prompt.js';
17
20
  export * from './utils.js';
18
21
  export * from './errors.js';
19
22
  // ── Built 模块 ──────────────────────────────────────────────────────
package/lib/message.d.ts CHANGED
@@ -49,6 +49,7 @@ export interface MessageBase {
49
49
  * 完整消息类型,支持扩展
50
50
  */
51
51
  export type Message<T extends object = {}> = MessageBase & T;
52
+ /** @internal Legacy static helpers; not part of Agent resource authoring. */
52
53
  export declare namespace Message {
53
54
  /**
54
55
  * 工具方法:合并自定义字段与基础消息结构
package/lib/message.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { isActionMessage as isActionMessageImpl } from "./built/interactive-segments/action.js";
2
+ /** @internal Legacy static helpers; not part of Agent resource authoring. */
2
3
  export var Message;
3
4
  (function (Message) {
4
5
  /**
@@ -81,10 +81,14 @@ export interface OutboundEnvelope {
81
81
  readonly requester: PluginId;
82
82
  readonly generation: number;
83
83
  readonly payload: unknown;
84
+ /** Native platform Client for the Endpoint selected by `conversation`. */
85
+ readonly $client: unknown;
86
+ /** Literal adapter name used to validate adapter-bound middleware. */
87
+ readonly clientAdapter?: string;
84
88
  replace(payload: unknown): void;
85
89
  }
86
- export interface MessageGateway {
87
- receive(input: IncomingMessage): Promise<MessageDispatchResult>;
90
+ /** @public Stable IM gateway contract resolved through `outboundMessageToken`. */
91
+ export interface OutboundMessageService {
88
92
  send(request: SendRequest): Promise<DeliveryReceipt>;
89
93
  /**
90
94
  * 注册 interactive action 回跳 handler(prefix 最长匹配;返回注销函数)。
@@ -100,6 +104,7 @@ export interface MessageDispatchResult {
100
104
  readonly value?: unknown;
101
105
  }
102
106
  export declare class Message {
107
+ #private;
103
108
  readonly conversation: ConversationRef;
104
109
  readonly content: string;
105
110
  readonly generation: number;
@@ -117,6 +122,8 @@ export declare class Message {
117
122
  readonly replyTo?: {
118
123
  readonly id: string;
119
124
  } | undefined;
125
+ readonly clientAdapter?: string | undefined;
126
+ /** @internal Constructed only by the generation-owned IM Runtime. */
120
127
  constructor(conversation: ConversationRef, content: string, generation: number, reply: (content: SendContent, requester?: PluginId, targetConversation?: ConversationAddress) => Promise<DeliveryReceipt>, sender?: MessageSenderRef | undefined, metadata?: Readonly<Record<string, unknown>>,
121
128
  /**
122
129
  * 结构化段视图(与 `content` 纯文本视图同源,见 IncomingMessage.segments)。
@@ -126,10 +133,15 @@ export declare class Message {
126
133
  /** 结构化入站消息身份(平台原生 message id 经 MessageRef 传递)。 */
127
134
  message?: MessageRef | undefined, endpointId?: string | undefined, mentioned?: boolean | undefined, replyTo?: {
128
135
  readonly id: string;
129
- } | undefined);
136
+ } | undefined, client?: () => unknown, clientAdapter?: string | undefined);
130
137
  /** 平台原生消息 id(`message` 未提供时为 undefined)。 */
131
138
  get id(): string | undefined;
132
139
  readonly $reply: (content: SendContent) => Promise<DeliveryReceipt>;
140
+ /**
141
+ * Platform-native Client that received this message. The getter is
142
+ * generation-scoped; retaining the returned Client after dispatch is invalid.
143
+ */
144
+ get $client(): unknown;
133
145
  readonly $replyFrom: (requester: PluginId, content: SendContent) => Promise<DeliveryReceipt>;
134
146
  /**
135
147
  * 向同 Endpoint 的另一个通道发送消息(通用)。
@@ -176,4 +188,4 @@ export declare class Message {
176
188
  */
177
189
  readonly $replyToChannel: (channelId: string, guildId: string, content: SendContent, threadId?: string) => Promise<DeliveryReceipt>;
178
190
  }
179
- export declare function createOutboundEnvelope(request: Omit<OutboundEnvelope, 'payload' | 'replace'>, initialPayload: unknown): OutboundEnvelope;
191
+ export declare function createOutboundEnvelope(request: Omit<OutboundEnvelope, 'payload' | '$client' | 'replace'>, initialPayload: unknown, resolveClient?: () => unknown): OutboundEnvelope;
@@ -43,6 +43,9 @@ export class Message {
43
43
  endpointId;
44
44
  mentioned;
45
45
  replyTo;
46
+ clientAdapter;
47
+ #resolveClient;
48
+ /** @internal Constructed only by the generation-owned IM Runtime. */
46
49
  constructor(conversation, content, generation, reply, sender, metadata = Object.freeze({}),
47
50
  /**
48
51
  * 结构化段视图(与 `content` 纯文本视图同源,见 IncomingMessage.segments)。
@@ -50,7 +53,9 @@ export class Message {
50
53
  */
51
54
  segments,
52
55
  /** 结构化入站消息身份(平台原生 message id 经 MessageRef 传递)。 */
53
- message, endpointId, mentioned, replyTo) {
56
+ message, endpointId, mentioned, replyTo, client = () => {
57
+ throw new Error('Message has no Endpoint Client context');
58
+ }, clientAdapter) {
54
59
  this.conversation = conversation;
55
60
  this.content = content;
56
61
  this.generation = generation;
@@ -61,6 +66,8 @@ export class Message {
61
66
  this.endpointId = endpointId;
62
67
  this.mentioned = mentioned;
63
68
  this.replyTo = replyTo;
69
+ this.clientAdapter = clientAdapter;
70
+ this.#resolveClient = client;
64
71
  this.$reply = (content) => reply(content);
65
72
  this.$replyFrom = (requester, content) => reply(content, requester);
66
73
  this.$sendTo = (target, content) => reply(content, undefined, target);
@@ -101,6 +108,13 @@ export class Message {
101
108
  return this.message?.id;
102
109
  }
103
110
  $reply;
111
+ /**
112
+ * Platform-native Client that received this message. The getter is
113
+ * generation-scoped; retaining the returned Client after dispatch is invalid.
114
+ */
115
+ get $client() {
116
+ return this.#resolveClient();
117
+ }
104
118
  $replyFrom;
105
119
  /**
106
120
  * 向同 Endpoint 的另一个通道发送消息(通用)。
@@ -144,11 +158,12 @@ export class Message {
144
158
  */
145
159
  $replyToChannel;
146
160
  }
147
- export function createOutboundEnvelope(request, initialPayload) {
161
+ export function createOutboundEnvelope(request, initialPayload, resolveClient = () => undefined) {
148
162
  let payload = initialPayload;
149
163
  return Object.freeze({
150
164
  ...request,
151
165
  get payload() { return payload; },
166
+ get $client() { return resolveClient(); },
152
167
  replace(next) { payload = next; },
153
168
  });
154
169
  }
@@ -1,16 +1,14 @@
1
1
  import { Scope, generationAdmissionBinder, type GenerationAdmissionGate, type PluginId, type RuntimeSnapshot, type SnapshotLease, type SnapshotReader } from '@zhin.js/plugin-runtime';
2
2
  import { MessageBus } from './message-bus.js';
3
- import { type AdapterOperation, type EndpointManagement, type EndpointManagementCapability, type AdapterEndpointPhase, type EndpointContentResolveContext } from '@zhin.js/adapter';
4
- import { type ConversationEventStore, type ConversationContextBlock, type ConversationReference, type ConversationResolution, type ConversationRef, type DeliveryReceipt, type MessageRef } from '@zhin.js/im-contract';
5
- import { Message, type ConversationAddress, type IncomingMessage, type MessageDispatchResult, type MessageGateway, type MessageSenderRef, type SendRequest } from './contracts.js';
3
+ import { type AdapterOperation, type EndpointManagement, type EndpointManagementCapability, type AdapterEndpointPhase, type EndpointContentResolveContext, type EndpointEvent, type EndpointEventGateway } from '@zhin.js/adapter';
4
+ import { type ConversationEventStore, type ConversationContextBlock, type ConversationReference, type ConversationResolution, type ConversationRef, type DeliveryReceipt, type EndpointCapabilities, type MessageRef } from '@zhin.js/im-contract';
5
+ import { Message, type ConversationAddress, type IncomingMessage, type OutboundMessageService, type MessageSenderRef, type SendRequest } from './contracts.js';
6
6
  import { LoginAssist } from '../../built/login-assist.js';
7
- import type { Notice } from '../../notice.js';
8
- import type { Request } from '../../request.js';
9
- import type { SystemEvent } from '../../system-event.js';
10
7
  import type { UserInteraction } from '@zhin.js/interaction';
11
8
  import { OutboundRenderer } from './outbound-renderer.js';
12
9
  import { type RuntimeInteractiveHandler } from './interactive.js';
13
- export declare const messageGatewayToken: import("@zhin.js/plugin-runtime").Token<MessageGateway>;
10
+ /** @public Stable inbound and outbound IM gateway token for Adapter integrations. */
11
+ export declare const outboundMessageToken: import("@zhin.js/plugin-runtime").Token<OutboundMessageService>;
14
12
  /** Generation-owned ingress hooks before ordinary dispatch and after it misses. */
15
13
  export interface IngressRoute {
16
14
  preRoute?(message: Message, lease: SnapshotLease, requester: PluginId, conversationSequence: number | undefined): Promise<boolean>;
@@ -49,12 +47,14 @@ export interface ImRuntimeOptions {
49
47
  */
50
48
  readonly enrichSender?: (sender: MessageSenderRef | undefined, conversation: IncomingMessage['conversation'], snapshot: RuntimeSnapshot) => MessageSenderRef | undefined;
51
49
  }
52
- export declare class ImRuntime implements MessageGateway {
50
+ export declare class ImRuntime implements OutboundMessageService {
53
51
  #private;
54
52
  conversationEvents: ConversationEventStore;
55
53
  constructor(options?: ImRuntimeOptions);
56
54
  /** Process composition replaces the bootstrap memory store after required DB activation. */
57
55
  replaceConversationEventStore(store: ConversationEventStore): void;
56
+ /** Pins all nested IM operations to the snapshot current at operation ingress. */
57
+ runWithSnapshotView<T>(operation: () => Promise<T>): Promise<T>;
58
58
  resolveConversationReference(lease: SnapshotLease, reference: ConversationReference, context: EndpointContentResolveContext): Promise<ConversationResolution>;
59
59
  readConversationContext(conversation: ConversationRef, consumer: string, throughSequence: number, limit?: number, excludeMessageId?: string): Promise<Readonly<{
60
60
  blocks: readonly ConversationContextBlock[];
@@ -66,7 +66,11 @@ export declare class ImRuntime implements MessageGateway {
66
66
  readonly messageBus: MessageBus;
67
67
  readonly loginAssist: LoginAssist;
68
68
  install(resources: Scope): void;
69
- [generationAdmissionBinder](gate: GenerationAdmissionGate): MessageGateway;
69
+ /** The sole Adapter ingress, also installed as endpointEventGatewayToken. */
70
+ readonly endpointEvents: EndpointEventGateway & {
71
+ [generationAdmissionBinder](gate: GenerationAdmissionGate): EndpointEventGateway;
72
+ };
73
+ [generationAdmissionBinder](gate: GenerationAdmissionGate): OutboundMessageService;
70
74
  /**
71
75
  * 注册 interactive action 回跳 handler(prefix 最长匹配;返回注销函数)。
72
76
  * 在 Command dispatch 之前路由:action 段 / 数字回跳 / 指令预填 payload。
@@ -84,11 +88,8 @@ export declare class ImRuntime implements MessageGateway {
84
88
  * 返回注销函数。listener 抛错不会阻断消息链路。
85
89
  */
86
90
  onMessage(listener: (event: RuntimeMessageEvent) => void): () => void;
87
- receive(input: IncomingMessage): Promise<MessageDispatchResult>;
88
91
  send(request: SendRequest): Promise<DeliveryReceipt>;
89
- receiveNotice(notice: Notice): Promise<void>;
90
- receiveRequest(request: Request): Promise<void>;
91
- receiveSystem(event: SystemEvent): Promise<void>;
92
+ receiveEndpointEvent(event: EndpointEvent, admission?: GenerationAdmissionGate): Promise<unknown>;
92
93
  /** Console `endpoint.list` — empty until Adapter Feature projection is ready. */
93
94
  listEndpoints(): readonly {
94
95
  readonly id: string;
@@ -101,6 +102,11 @@ export declare class ImRuntime implements MessageGateway {
101
102
  readonly operations: readonly AdapterOperation[];
102
103
  readonly managementCapabilities: readonly EndpointManagementCapability[];
103
104
  }[];
105
+ /** Exact operation capabilities for one concrete live Endpoint. */
106
+ endpointCapabilities(input: {
107
+ readonly adapter: string;
108
+ readonly endpointKey: string;
109
+ }): EndpointCapabilities | undefined;
104
110
  /**
105
111
  * Console `GET /api/stats` 同源计数:非 root 插件节点 + AdapterIndex endpoints。
106
112
  * 供命令 / 状态卡等在 Plugin Runtime 下读取(legacy `root.adapters` / `root.children` 已不存在)。
@@ -1,14 +1,14 @@
1
1
  import { createToken, generationAdmissionBinder, htmlRendererToken, } from '@zhin.js/plugin-runtime';
2
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
3
  import { createPermissionHost, permissionHostToken } from '@zhin.js/permission';
3
4
  import { MessageBus, messageBusToken } from './message-bus.js';
4
- import { adapterFeatureId, isAdapterIndex, resolveEndpointManagement, } from '@zhin.js/adapter';
5
+ import { adapterFeatureId, isAdapterIndex, resolveEndpointManagement, endpointEventGatewayToken, } from '@zhin.js/adapter';
5
6
  import { MemoryConversationEventStore, conversationRefKey, messageRefKey, } from '@zhin.js/im-contract';
6
7
  import { segmentsToPlainText } from '../../built/segment-contract/text.js';
7
8
  import { isMiddlewareIndex, middlewareFeatureId } from '@zhin.js/middleware';
8
9
  import { isHandlerIndex, handlerFeatureId } from '../../feature/handler.js';
9
10
  import { formatCompact, getLogger, truncatePreview } from '@zhin.js/logger';
10
11
  import { Message, createOutboundEnvelope, } from './contracts.js';
11
- import { sideEventGatewayToken, } from './side-event-gateway.js';
12
12
  import { loginAssistToken } from './login-assist-host.js';
13
13
  import { LoginAssist } from '../../built/login-assist.js';
14
14
  import { sideEventSendChannel } from '../../side-event/base.js';
@@ -20,7 +20,8 @@ import { keyboardFallbackStore } from '../../built/interactive-segments/fallback
20
20
  import { assertUserInteractionRequest, parseUserInteractionAnswer, projectUserInteraction, renderUserInteraction, } from '../../built/user-interaction.js';
21
21
  import { findRuntimeInteractiveHandler, resolveRuntimeInteractivePayload, runtimeInteractiveConversationKey, } from './interactive.js';
22
22
  const logger = getLogger('im');
23
- export const messageGatewayToken = createToken('zhin.im.message-gateway');
23
+ /** @public Stable inbound and outbound IM gateway token for Adapter integrations. */
24
+ export const outboundMessageToken = createToken('zhin.im.outbound-message');
24
25
  export const ingressRouteToken = createToken('zhin.im.ingress-route');
25
26
  export const messagePreviewLimit = 200;
26
27
  class UserInteractionTimeoutError extends Error {
@@ -47,6 +48,7 @@ export class ImRuntime {
47
48
  #messageListeners = new Set();
48
49
  #interactiveHandlers = [];
49
50
  #interactionClaims = new Map();
51
+ #operationSnapshot = new AsyncLocalStorage();
50
52
  #snapshots;
51
53
  #inboundClaim;
52
54
  #enrichSender;
@@ -64,6 +66,21 @@ export class ImRuntime {
64
66
  replaceConversationEventStore(store) {
65
67
  this.conversationEvents = store;
66
68
  }
69
+ /** Pins all nested IM operations to the snapshot current at operation ingress. */
70
+ async runWithSnapshotView(operation) {
71
+ const inherited = this.#operationSnapshot.getStore();
72
+ if (inherited?.active)
73
+ return operation();
74
+ if (!this.#snapshots)
75
+ throw new Error('ImRuntime is not attached to a Root');
76
+ const lease = this.#snapshots.acquire();
77
+ try {
78
+ return await this.#operationSnapshot.run(lease, operation);
79
+ }
80
+ finally {
81
+ lease.release();
82
+ }
83
+ }
67
84
  async resolveConversationReference(lease, reference, context) {
68
85
  if (!this.#snapshots?.owns(lease) || !lease.active) {
69
86
  return Object.freeze({ status: 'expired', code: 'generation_lease_expired' });
@@ -102,29 +119,20 @@ export class ImRuntime {
102
119
  messageBus = new MessageBus();
103
120
  loginAssist = new LoginAssist();
104
121
  install(resources) {
105
- resources.provide(messageGatewayToken, this);
106
- resources.provide(sideEventGatewayToken, this.#sideEventGateway);
122
+ resources.provide(outboundMessageToken, this);
123
+ resources.provide(endpointEventGatewayToken, this.endpointEvents);
107
124
  resources.provide(loginAssistToken, this.loginAssist);
108
125
  resources.provide(permissionHostToken, this.permissionHost);
109
126
  resources.provide(messageBusToken, this.messageBus);
110
127
  }
111
- #sideEventGateway = (() => {
128
+ /** The sole Adapter ingress, also installed as endpointEventGatewayToken. */
129
+ endpointEvents = (() => {
112
130
  const self = this;
113
131
  const gateway = {
114
- receiveNotice: (notice) => self.receiveNotice(notice),
115
- receiveRequest: (request) => self.receiveRequest(request),
116
- receiveSystem: (event) => self.receiveSystem(event),
132
+ receive: (event) => self.receiveEndpointEvent(event),
117
133
  [generationAdmissionBinder](gate) {
118
134
  return Object.freeze({
119
- receiveNotice: async (notice) => {
120
- await gate.enter(() => self.receiveNotice(notice));
121
- },
122
- receiveRequest: async (request) => {
123
- await gate.enter(() => self.receiveRequest(request));
124
- },
125
- receiveSystem: async (event) => {
126
- await gate.enter(() => self.receiveSystem(event));
127
- },
135
+ receive: async (event) => gate.enter(() => self.receiveEndpointEvent(event, gate)),
128
136
  });
129
137
  },
130
138
  };
@@ -132,8 +140,6 @@ export class ImRuntime {
132
140
  })();
133
141
  [generationAdmissionBinder](gate) {
134
142
  const gateway = {
135
- receive: async (input) => gate.enter(() => this.#receive(input, gate))
136
- ?? Object.freeze({ matched: false }),
137
143
  send: async (request) => gate.enter(() => this.send(request))
138
144
  ?? failedReceipt('generation_not_admitted'),
139
145
  registerInteractiveHandler: (prefix, handler) => this.#registerInteractiveHandler(prefix, handler, gate),
@@ -315,10 +321,8 @@ export class ImRuntime {
315
321
  }
316
322
  }
317
323
  }
318
- async receive(input) {
319
- return this.#receive(input);
320
- }
321
- async #receive(input, admission) {
324
+ async #receive(source, admission) {
325
+ const input = source.payload;
322
326
  const lease = this.#acquire();
323
327
  let active = true;
324
328
  try {
@@ -354,7 +358,11 @@ export class ImRuntime {
354
358
  mentioned: input.mentioned,
355
359
  },
356
360
  }, lease.value);
357
- }, enrichedSender, Object.freeze({ ...input.metadata }), input.segments ? Object.freeze([...input.segments]) : undefined, input.message, input.endpointId, input.mentioned, input.replyTo);
361
+ }, enrichedSender, Object.freeze({ ...input.metadata }), input.segments ? Object.freeze([...input.segments]) : undefined, input.message, input.endpointId, input.mentioned, input.replyTo, () => {
362
+ if (!active)
363
+ throw new Error('Message Client scope has ended');
364
+ return source.client;
365
+ }, source.endpoint.adapter);
358
366
  let conversationSequence;
359
367
  if (input.message?.id) {
360
368
  const appended = await this.conversationEvents.append(Object.freeze({
@@ -394,7 +402,9 @@ export class ImRuntime {
394
402
  result = Object.freeze({ matched: true, command: 'pre-route', owner: requester });
395
403
  return;
396
404
  }
397
- await this.#runHandlers(lease.value, 'message.receive', [message]);
405
+ await this.#runHandlers(lease.value, 'message.receive', [
406
+ withEndpointEventPayload(source, message),
407
+ ]);
398
408
  result = await this.#dispatchInteractive(message, requester, admission)
399
409
  ?? await this.#dispatcher.dispatch(message, lease.value, interactionFactory);
400
410
  if (!result.matched && ingressRoute) {
@@ -425,7 +435,7 @@ export class ImRuntime {
425
435
  }
426
436
  finally {
427
437
  active = false;
428
- lease.release();
438
+ this.#release(lease);
429
439
  }
430
440
  }
431
441
  async send(request) {
@@ -434,18 +444,19 @@ export class ImRuntime {
434
444
  return await this.#sendWithSnapshot(request, lease.value);
435
445
  }
436
446
  finally {
437
- lease.release();
447
+ this.#release(lease);
438
448
  }
439
449
  }
440
- async receiveNotice(notice) {
450
+ async #receiveNotice(source) {
451
+ const notice = source.payload;
441
452
  const event = conversationEventFromNotice(notice);
442
453
  if (event)
443
454
  await this.conversationEvents.append(event);
444
- await this.#receiveSideEvent('notice.receive', notice);
455
+ await this.#receiveSideEvent(withEndpointEventPayload(source, notice));
445
456
  }
446
- async receiveRequest(request) {
447
- await this.#withRequestActionScope(request, async (scoped) => {
448
- await this.#receiveSideEvent('request.receive', scoped);
457
+ async #receiveRequest(source) {
458
+ await this.#withRequestActionScope(source.payload, async (scoped) => {
459
+ await this.#receiveSideEvent(withEndpointEventPayload(source, scoped));
449
460
  });
450
461
  }
451
462
  async #withRequestActionScope(request, dispatch) {
@@ -471,16 +482,38 @@ export class ImRuntime {
471
482
  await Promise.allSettled([...actions]);
472
483
  }
473
484
  }
474
- async receiveSystem(event) {
475
- await this.#receiveSideEvent('system.receive', event);
485
+ async #receiveSystem(source) {
486
+ await this.#receiveSideEvent(source);
476
487
  }
477
- async #receiveSideEvent(event, payload) {
488
+ async #receiveSideEvent(event) {
478
489
  const lease = this.#acquire();
479
490
  try {
480
- await this.#runHandlers(lease.value, event, [payload]);
491
+ await this.#runHandlers(lease.value, event.name, [event]);
481
492
  }
482
493
  finally {
483
- lease.release();
494
+ this.#release(lease);
495
+ }
496
+ }
497
+ async receiveEndpointEvent(event, admission) {
498
+ switch (event.name) {
499
+ case 'message.receive':
500
+ return this.#receive(event, admission);
501
+ case 'notice.receive':
502
+ return this.#receiveNotice(event);
503
+ case 'request.receive':
504
+ return this.#receiveRequest(event);
505
+ case 'system.receive':
506
+ return this.#receiveSystem(event);
507
+ default: {
508
+ const lease = this.#acquire();
509
+ try {
510
+ await this.#runHandlers(lease.value, event.name, [event]);
511
+ return undefined;
512
+ }
513
+ finally {
514
+ this.#release(lease);
515
+ }
516
+ }
484
517
  }
485
518
  }
486
519
  /**
@@ -518,7 +551,8 @@ export class ImRuntime {
518
551
  return;
519
552
  const options = {
520
553
  resolveInteraction: (name, interactionArgs) => {
521
- const payload = interactionArgs[0];
554
+ const context = interactionArgs[0];
555
+ const payload = context?.payload;
522
556
  if (name === 'message.receive' && payload instanceof Message) {
523
557
  return this.createInteraction(payload);
524
558
  }
@@ -551,13 +585,30 @@ export class ImRuntime {
551
585
  }));
552
586
  }
553
587
  finally {
554
- lease.release();
588
+ this.#release(lease);
555
589
  }
556
590
  }
557
591
  catch {
558
592
  return Object.freeze([]);
559
593
  }
560
594
  }
595
+ /** Exact operation capabilities for one concrete live Endpoint. */
596
+ endpointCapabilities(input) {
597
+ try {
598
+ const lease = this.#acquire();
599
+ try {
600
+ const index = requireAdapters(lease.value);
601
+ const id = index.resolve(input.adapter, input.endpointKey);
602
+ return id ? index.capabilities(id) : undefined;
603
+ }
604
+ finally {
605
+ this.#release(lease);
606
+ }
607
+ }
608
+ catch {
609
+ return undefined;
610
+ }
611
+ }
561
612
  /**
562
613
  * Console `GET /api/stats` 同源计数:非 root 插件节点 + AdapterIndex endpoints。
563
614
  * 供命令 / 状态卡等在 Plugin Runtime 下读取(legacy `root.adapters` / `root.children` 已不存在)。
@@ -578,7 +629,7 @@ export class ImRuntime {
578
629
  });
579
630
  }
580
631
  finally {
581
- lease.release();
632
+ this.#release(lease);
582
633
  }
583
634
  }
584
635
  catch {
@@ -612,7 +663,7 @@ export class ImRuntime {
612
663
  });
613
664
  }
614
665
  finally {
615
- lease.release();
666
+ this.#release(lease);
616
667
  }
617
668
  }
618
669
  catch {
@@ -640,7 +691,7 @@ export class ImRuntime {
640
691
  return { messageId: result.message?.id ?? '' };
641
692
  }
642
693
  finally {
643
- lease.release();
694
+ this.#release(lease);
644
695
  }
645
696
  }
646
697
  /** Activity-feedback: add a message reaction when the live Endpoint supports it. */
@@ -678,7 +729,7 @@ export class ImRuntime {
678
729
  return control ? await run(control) : fallback;
679
730
  }
680
731
  finally {
681
- lease.release();
732
+ this.#release(lease);
682
733
  }
683
734
  }
684
735
  /** Run one management operation while the Endpoint generation stays leased. */
@@ -691,13 +742,13 @@ export class ImRuntime {
691
742
  return null;
692
743
  }
693
744
  try {
694
- const endpoint = requireAdapters(lease.value).instance(adapter, endpointKey);
745
+ const endpoint = requireAdapters(lease.value).connection(adapter, endpointKey);
695
746
  if (!endpoint)
696
747
  return null;
697
748
  return await run(resolveEndpointManagement(endpoint) ?? Object.freeze({}));
698
749
  }
699
750
  finally {
700
- lease.release();
751
+ this.#release(lease);
701
752
  }
702
753
  }
703
754
  async #sendWithSnapshot(request, snapshot) {
@@ -710,11 +761,19 @@ export class ImRuntime {
710
761
  catch {
711
762
  return rejectedReceipt('outbound_payload_rejected');
712
763
  }
764
+ let adapters;
765
+ try {
766
+ adapters = requireAdapters(snapshot);
767
+ }
768
+ catch (error) {
769
+ return receiptFromEndpointError(error);
770
+ }
713
771
  const envelope = createOutboundEnvelope({
714
772
  conversation: request.conversation,
715
773
  requester: request.requester,
716
774
  generation: snapshot.generation,
717
- }, initialPayload);
775
+ clientAdapter: adapters.clientAdapter(adapter),
776
+ }, initialPayload, () => adapters.clientById(adapter));
718
777
  let terminalEntered = false;
719
778
  let receipt;
720
779
  try {
@@ -787,10 +846,18 @@ export class ImRuntime {
787
846
  return receipt ?? failedReceipt('outbound_delivery_incomplete');
788
847
  }
789
848
  #acquire() {
849
+ const inherited = this.#operationSnapshot.getStore();
850
+ if (inherited?.active)
851
+ return inherited;
790
852
  if (!this.#snapshots)
791
853
  throw new Error('ImRuntime is not attached to a Root');
792
854
  return this.#snapshots.acquire();
793
855
  }
856
+ #release(lease) {
857
+ if (this.#operationSnapshot.getStore() === lease)
858
+ return;
859
+ lease.release();
860
+ }
794
861
  /**
795
862
  * interactive 回跳分发(Command dispatch 之前):action 段 / 中央 fallback
796
863
  * 数字回跳 / 指令预填 payload → prefix 最长匹配 handler。
@@ -1113,3 +1180,11 @@ function abortError(signal, fallback) {
1113
1180
  return signal.reason;
1114
1181
  return new Error(fallback);
1115
1182
  }
1183
+ function withEndpointEventPayload(source, payload) {
1184
+ return Object.freeze({
1185
+ name: source.name,
1186
+ payload,
1187
+ endpoint: source.endpoint,
1188
+ client: source.client,
1189
+ });
1190
+ }
@@ -7,4 +7,3 @@ export * from './message-dispatcher.js';
7
7
  export * from './outbound-renderer.js';
8
8
  export * from './outbound-segments.js';
9
9
  export * from './service-tokens.js';
10
- export * from './side-event-gateway.js';
@@ -7,4 +7,3 @@ export * from './message-dispatcher.js';
7
7
  export * from './outbound-renderer.js';
8
8
  export * from './outbound-segments.js';
9
9
  export * from './service-tokens.js';
10
- export * from './side-event-gateway.js';
@@ -1,6 +1,6 @@
1
1
  import { LoginAssist } from '../../built/login-assist.js';
2
2
  /**
3
- * Plugin Runtime login-assist port(与 messageGatewayToken / sideEventGatewayToken 并列)。
3
+ * Plugin Runtime login-assist port(与出站消息服务并列)。
4
4
  * 适配器 waitForInput;Console / stdin 经 listPending + submit 消费。
5
5
  */
6
6
  export declare const loginAssistToken: import("@zhin.js/plugin-runtime").Token<LoginAssist>;
@@ -1,6 +1,6 @@
1
1
  import { createToken } from '@zhin.js/plugin-runtime';
2
2
  /**
3
- * Plugin Runtime login-assist port(与 messageGatewayToken / sideEventGatewayToken 并列)。
3
+ * Plugin Runtime login-assist port(与出站消息服务并列)。
4
4
  * 适配器 waitForInput;Console / stdin 经 listPending + submit 消费。
5
5
  */
6
6
  export const loginAssistToken = createToken('zhin.im.login-assist');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Public IM gateway contract exposed from `zhin.js/core/runtime`.
3
+ * @module zhin.js/core/runtime
4
+ */
5
+ export { outboundMessageToken } from './im-runtime.js';
6
+ export { Message, type ComponentCall, type ConversationAddress, type IncomingContext, type IncomingMessage, type MessageDispatchResult, type OutboundMessageService, type MessageSenderRef, type OutboundEnvelope, type RawContent, type SendContent, type SendRequest, } from './contracts.js';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Public IM gateway contract exposed from `zhin.js/core/runtime`.
3
+ * @module zhin.js/core/runtime
4
+ */
5
+ export { outboundMessageToken } from './im-runtime.js';
6
+ export { Message, } from './contracts.js';
@@ -1,4 +1,4 @@
1
- import type { SideEventGateway } from '../plugin-runtime/im/side-event-gateway.js';
1
+ import type { EndpointEventEmitter } from '@zhin.js/adapter';
2
2
  import { type OneBotLikeRawEvent, type SideEventPlatform } from './normalize.js';
3
3
  export interface OneBotLikeSideEventInput {
4
4
  readonly adapter: string;
@@ -9,7 +9,7 @@ export interface OneBotLikeSideEventInput {
9
9
  readonly reject?: (flag: string, reason?: string) => void | Promise<void>;
10
10
  }
11
11
  /**
12
- * Normalize OneBot / icqq-style notice|request|meta payloads and forward to SideEventGateway.
12
+ * Normalize OneBot / icqq-style notice|request|meta payloads and feed Endpoint.emit().
13
13
  * Returns which kind was dispatched, or null when the payload is not a side event.
14
14
  */
15
- export declare function receiveOneBotLikeSideEvent(gateway: SideEventGateway, input: OneBotLikeSideEventInput): Promise<'notice' | 'request' | 'system' | null>;
15
+ export declare function receiveOneBotLikeSideEvent(emit: EndpointEventEmitter, input: OneBotLikeSideEventInput): Promise<'notice' | 'request' | 'system' | null>;
@@ -1,9 +1,9 @@
1
1
  import { buildNotice, buildRequest, buildSystem, mapNoticeParts, mapRequestParts, resolveSideEventDedupeKey, senderFromId, } from './normalize.js';
2
2
  /**
3
- * Normalize OneBot / icqq-style notice|request|meta payloads and forward to SideEventGateway.
3
+ * Normalize OneBot / icqq-style notice|request|meta payloads and feed Endpoint.emit().
4
4
  * Returns which kind was dispatched, or null when the payload is not a side event.
5
5
  */
6
- export async function receiveOneBotLikeSideEvent(gateway, input) {
6
+ export async function receiveOneBotLikeSideEvent(emit, input) {
7
7
  const raw = input.raw;
8
8
  const platform = input.platform ?? 'onebot';
9
9
  const postType = String(raw.post_type ?? raw.type ?? '');
@@ -47,7 +47,7 @@ export async function receiveOneBotLikeSideEvent(gateway, input) {
47
47
  ? { $role: 'admin', $enabled: String(raw.sub_type ?? '') === 'set' }
48
48
  : {}),
49
49
  });
50
- await gateway.receiveNotice(notice);
50
+ await emit('notice.receive', notice);
51
51
  return 'notice';
52
52
  }
53
53
  if (postType === 'request' || postType.startsWith('request.')) {
@@ -96,7 +96,7 @@ export async function receiveOneBotLikeSideEvent(gateway, input) {
96
96
  },
97
97
  });
98
98
  try {
99
- await gateway.receiveRequest(request);
99
+ await emit('request.receive', request);
100
100
  }
101
101
  finally {
102
102
  active = false;
@@ -127,7 +127,7 @@ export async function receiveOneBotLikeSideEvent(gateway, input) {
127
127
  $sub_type: subType ?? metaType,
128
128
  $timestamp: toMillis(raw.time),
129
129
  });
130
- await gateway.receiveSystem(system);
130
+ await emit('system.receive', system);
131
131
  return 'system';
132
132
  }
133
133
  return null;
package/lib/utils.d.ts CHANGED
@@ -70,7 +70,7 @@ export declare namespace segment {
70
70
  backgroundColor?: string;
71
71
  fileName?: string;
72
72
  }): HtmlSegment;
73
- /** @alias htmlCard */
73
+ /** Short alias for {@link htmlCard}. */
74
74
  const html: typeof htmlCard;
75
75
  /** 出站 Markdown 段(Adapter policy 决定 image/text/origin) */
76
76
  function markdown(content: string, options?: Omit<MarkdownSegment['data'], 'content'>): MarkdownSegment;
package/lib/utils.js CHANGED
@@ -98,7 +98,7 @@ export function segment(type, data) {
98
98
  return new HtmlSegment(options);
99
99
  }
100
100
  segment.htmlCard = htmlCard;
101
- /** @alias htmlCard */
101
+ /** Short alias for {@link htmlCard}. */
102
102
  segment.html = htmlCard;
103
103
  /** 出站 Markdown 段(Adapter policy 决定 image/text/origin) */
104
104
  function markdown(content, options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/core",
3
- "version": "1.5.13",
3
+ "version": "1.5.14",
4
4
  "description": "Zhin机器人核心框架",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -75,18 +75,18 @@
75
75
  "segment-matcher": "^1.0.5",
76
76
  "smol-toml": "^1.7.1",
77
77
  "yaml": "^2.9.0",
78
- "@zhin.js/adapter": "1.2.0",
79
- "@zhin.js/component": "1.0.12",
80
- "@zhin.js/command": "1.0.15",
81
- "@zhin.js/database": "1.0.79",
82
- "@zhin.js/handler": "1.0.3",
78
+ "@zhin.js/adapter": "1.2.1",
79
+ "@zhin.js/command": "1.0.16",
80
+ "@zhin.js/component": "1.0.13",
81
+ "@zhin.js/database": "1.0.80",
82
+ "@zhin.js/handler": "1.0.4",
83
83
  "@zhin.js/im-contract": "1.0.4",
84
84
  "@zhin.js/interaction": "1.0.1",
85
- "@zhin.js/kernel": "1.0.7",
86
- "@zhin.js/logger": "1.0.76",
87
- "@zhin.js/middleware": "1.0.12",
88
- "@zhin.js/plugin-runtime": "1.1.7",
89
- "@zhin.js/permission": "1.0.3",
85
+ "@zhin.js/kernel": "1.0.8",
86
+ "@zhin.js/logger": "1.0.77",
87
+ "@zhin.js/middleware": "1.0.13",
88
+ "@zhin.js/permission": "1.0.4",
89
+ "@zhin.js/plugin-runtime": "1.1.8",
90
90
  "@zhin.js/schema": "1.0.73"
91
91
  },
92
92
  "peerDependencies": {
@@ -102,7 +102,7 @@
102
102
  "@types/qrcode": "^1.5.6",
103
103
  "ajv": "8.18.0",
104
104
  "typescript": "^6.0.3",
105
- "@zhin.js/ai": "1.5.6"
105
+ "@zhin.js/ai": "1.5.7"
106
106
  },
107
107
  "repository": {
108
108
  "type": "git",
@@ -1,39 +0,0 @@
1
- /**
2
- * Agent system-prompt extension contract (per IM platform / adapter).
3
- *
4
- * Implementations live in adapter plugins; resolution runs in @zhin.js/agent.
5
- */
6
- export type AgentPromptSlot = 'orchestrator' | 'deferred_worker';
7
- /** Minimal tool shape for deferred catalog selection (no @zhin.js/ai import). */
8
- export interface DeferredToolCatalogItem {
9
- name: string;
10
- description: string;
11
- }
12
- export interface AgentPromptBuildContext {
13
- slot: AgentPromptSlot;
14
- /** Authenticated IM platform projected by the ingress adapter. */
15
- platform: string;
16
- /** Truncated user message for intent hints (~500 chars). */
17
- userMessagePreview?: string;
18
- deferred?: {
19
- goal: string;
20
- toolQuery?: string;
21
- domainStats?: string;
22
- };
23
- }
24
- export interface AgentPromptSection {
25
- /** Stable id for debug / logs (e.g. platform.icqq.orchestrator). */
26
- id: string;
27
- title?: string;
28
- body: string;
29
- /** Lower sorts earlier; default 100. */
30
- priority?: number;
31
- }
32
- export interface AgentPromptContributor {
33
- readonly platform: string;
34
- buildSections(ctx: AgentPromptBuildContext): Promise<AgentPromptSection[] | null>;
35
- /** When true, platform may supply selectDeferredTools for this task. */
36
- matchesDeferredTask?(ctx: AgentPromptBuildContext): boolean;
37
- /** Non-null replaces default TF-IDF deferred tool selection. */
38
- selectDeferredTools?(query: string, goal: string, catalog: DeferredToolCatalogItem[], maxTools: number): DeferredToolCatalogItem[] | null;
39
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Agent system-prompt extension contract (per IM platform / adapter).
3
- *
4
- * Implementations live in adapter plugins; resolution runs in @zhin.js/agent.
5
- */
6
- export {};
@@ -1,13 +0,0 @@
1
- import type { Notice } from '../../notice.js';
2
- import type { Request } from '../../request.js';
3
- import type { SystemEvent } from '../../system-event.js';
4
- /**
5
- * Plugin Runtime 侧事件入站口(与 messageGatewayToken 并列)。
6
- * 适配器归一 Notice / Request / SystemEvent 后调用,由 ImRuntime 分发给 HandlerIndex。
7
- */
8
- export interface SideEventGateway {
9
- receiveNotice(notice: Notice): Promise<void>;
10
- receiveRequest(request: Request): Promise<void>;
11
- receiveSystem(event: SystemEvent): Promise<void>;
12
- }
13
- export declare const sideEventGatewayToken: import("@zhin.js/plugin-runtime").Token<SideEventGateway>;
@@ -1,2 +0,0 @@
1
- import { createToken } from '@zhin.js/plugin-runtime';
2
- export const sideEventGatewayToken = createToken('zhin.im.side-event-gateway');