@zhin.js/adapter-milky 6.0.2 → 6.0.5

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.
@@ -2,10 +2,14 @@
2
2
  * Milky reverse WSS endpoint — httpHostToken WS upgrade inbound + baseUrl HTTP API outbound.
3
3
  */
4
4
  import { clearInterval } from 'node:timers';
5
- import type { EndpointInstance, EndpointManagement } from '@zhin.js/adapter';
5
+ import type {
6
+ EndpointInstance,
7
+ EndpointManagement,
8
+ EndpointSendRequest,
9
+ } from '@zhin.js/adapter';
6
10
  import type { MessageGateway } from '@zhin.js/core/runtime';
7
11
  import type { HttpHost, WsConnection } from '@zhin.js/host-http';
8
- import { formatCompact, getLogger } from '@zhin.js/logger';
12
+ import { formatCompact, getAdapterLogger } from '@zhin.js/logger';
9
13
  import type { CapabilityId } from '@zhin.js/plugin-runtime';
10
14
  import { verifyMilkyAccessToken } from './milky-auth.js';
11
15
  import { createMilkyEndpointManagement } from './endpoint-management.js';
@@ -17,10 +21,10 @@ import {
17
21
  formatInboundContent,
18
22
  formatInboundMessageId,
19
23
  formatInboundSegments,
20
- formatInboundTarget,
21
24
  formatOutboundMessageId,
22
25
  formatOutboundSegments,
23
26
  isMentioned,
27
+ milkyInboundConversation,
24
28
  parseMessageReceiveData,
25
29
  parseMilkyMessageId,
26
30
  senderNickname,
@@ -30,7 +34,6 @@ import {
30
34
  } from './protocol.js';
31
35
  import type { MilkyWsSocket } from './ws-types.js';
32
36
 
33
- const logger = getLogger('milky');
34
37
  const WS_OPEN = 1;
35
38
 
36
39
  export interface MilkyWssEndpointOptions {
@@ -42,6 +45,8 @@ export interface MilkyWssEndpointOptions {
42
45
  }
43
46
 
44
47
  export class MilkyWssEndpoint implements EndpointInstance {
48
+ readonly #logger!: ReturnType<typeof getAdapterLogger>;
49
+
45
50
  readonly #options: MilkyWssEndpointOptions;
46
51
  readonly #callApi: typeof callApi;
47
52
  readonly management: EndpointManagement = createMilkyEndpointManagement(this);
@@ -53,6 +58,7 @@ export class MilkyWssEndpoint implements EndpointInstance {
53
58
  #unregisterAgent?: () => void;
54
59
 
55
60
  constructor(options: MilkyWssEndpointOptions) {
61
+ this.#logger = getAdapterLogger('milky', options.config.id);
56
62
  this.#options = options;
57
63
  this.#callApi = options.callApi ?? callApi;
58
64
  }
@@ -60,14 +66,14 @@ export class MilkyWssEndpoint implements EndpointInstance {
60
66
  async start(): Promise<void> {
61
67
  if (this.#started) return;
62
68
  this.#started = true;
63
- this.#unregisterAgent = registerMilkyAgentEndpoint(this.#options.config.name, this);
69
+ this.#unregisterAgent = registerMilkyAgentEndpoint(this.#options.config.id, this);
64
70
  const handle = this.#options.http.ws(this.#options.config.path);
65
71
  this.#wsRelease = handle.onConnection((connection) => {
66
72
  this.#acceptConnection(connection);
67
73
  });
68
- logger.info(formatCompact({
74
+ this.#logger.info(formatCompact({
69
75
  op: 'listen',
70
- endpoint: this.#options.config.name,
76
+ endpoint: this.#options.config.id,
71
77
  mode: 'wss',
72
78
  path: this.#options.config.path,
73
79
  }));
@@ -102,15 +108,15 @@ export class MilkyWssEndpoint implements EndpointInstance {
102
108
  this.#started = false;
103
109
  }
104
110
 
105
- async send({ target, payload }: { readonly target: string; readonly payload: unknown }): Promise<string> {
111
+ async send({ conversation, payload }: EndpointSendRequest): Promise<string> {
106
112
  const message = formatOutboundSegments(payload);
107
- const { action, params } = buildSendAction(target, message);
113
+ const { action, params } = buildSendAction(conversation, message);
108
114
  const data = await this.callApi(action, params) as { message_seq?: number } | undefined;
109
- const messageId = formatOutboundMessageId(target, data?.message_seq);
110
- logger.debug(formatCompact({
115
+ const messageId = formatOutboundMessageId(conversation, data?.message_seq);
116
+ this.#logger.debug(formatCompact({
111
117
  op: 'milky_send',
112
- endpoint: this.#options.config.name,
113
- target,
118
+ endpoint: this.#options.config.id,
119
+ target: `${conversation.kind}:${conversation.id}`,
114
120
  messageId,
115
121
  }));
116
122
  return messageId;
@@ -213,33 +219,32 @@ export class MilkyWssEndpoint implements EndpointInstance {
213
219
  }
214
220
 
215
221
  #admitMessage(data: MilkyIncomingMessage, event: MilkyEvent): void {
216
- const target = formatInboundTarget(data);
222
+ const conversation = milkyInboundConversation(String(this.#options.id), data);
223
+ const target = `${conversation.kind}:${conversation.id}`;
217
224
  const content = formatInboundContent(data);
218
225
  const segments = formatInboundSegments(data);
219
226
  const audioUrl = extractInboundAudioUrl(data);
220
227
  const nickname = senderNickname(data);
221
228
  const mentioned = isMentioned(data, event.self_id);
222
229
  void this.#options.gateway.receive({
223
- adapter: this.#options.id,
224
- target,
230
+ conversation,
231
+ message: { conversation, id: formatInboundMessageId(data) },
225
232
  content,
226
233
  segments,
227
- sender: String(data.sender_id),
228
- id: formatInboundMessageId(data),
234
+ sender: { id: String(data.sender_id) },
235
+ endpointId: this.#options.config.id,
236
+ ...(mentioned ? { mentioned: true } : {}),
229
237
  metadata: Object.freeze({
230
238
  message_scene: data.message_scene,
231
239
  peer_id: String(data.peer_id),
232
240
  sender_id: String(data.sender_id),
233
241
  message_seq: data.message_seq,
234
- endpoint: this.#options.config.name,
235
242
  time: data.time ?? event.time,
236
243
  self_id: event.self_id != null ? String(event.self_id) : undefined,
237
244
  ...(nickname ? { nickname } : {}),
238
- ...(mentioned ? { mentioned: true } : {}),
239
- ...(audioUrl ? { audio_url: audioUrl } : {}),
240
245
  }),
241
246
  }).catch((err) => {
242
- logger.warn(formatCompact({
247
+ this.#logger.warn(formatCompact({
243
248
  op: 'milky_gateway_receive_failed',
244
249
  target,
245
250
  error: err instanceof Error ? err.message : String(err),
@@ -268,8 +273,8 @@ export class MilkyWssEndpoint implements EndpointInstance {
268
273
  socket.on('close', () => {
269
274
  if (this.#ws === socket) this.#ws = undefined;
270
275
  });
271
- logger.debug(formatCompact({
272
- endpoint: this.#options.config.name,
276
+ this.#logger.debug(formatCompact({
277
+ endpoint: this.#options.config.id,
273
278
  mode: 'wss',
274
279
  peer: connection.request.socket.remoteAddress,
275
280
  }));
@@ -287,9 +292,9 @@ export class MilkyWssEndpoint implements EndpointInstance {
287
292
  const event = JSON.parse(raw) as MilkyEvent;
288
293
  this.admit(event);
289
294
  } catch (error) {
290
- logger.warn(formatCompact({
295
+ this.#logger.warn(formatCompact({
291
296
  op: 'milky_parse_failed',
292
- endpoint: this.#options.config.name,
297
+ endpoint: this.#options.config.id,
293
298
  error: error instanceof Error ? error.message : String(error),
294
299
  }));
295
300
  }