@zhin.js/adapter-onebot11 1.1.20 → 1.1.21

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 CHANGED
@@ -1,5 +1,36 @@
1
1
  # @zhin.js/adapter-onebot11
2
2
 
3
+ ## 1.1.21
4
+
5
+ ### Patch Changes
6
+
7
+ - b88e988: Preserve account-profile write acknowledgements already observed before cancellation, distinguish native Discord REST rejection from unknown outcomes, and retain the last valid profile when a newer concurrent read fails. Keep scene-scoped SOUL presence consistent with the actual prompt and allow discovered URLs to pass through the existing network authorization policy.
8
+ - af8f803: Use the current Endpoint's platform profile for Agent account identity, with per-field configured fallbacks and scoped, identity-approved profile tools. Keep SOUL first-person and independent of account names. Profile ports preserve the source Client, cancellation, truthful update outcomes and private image authority.
9
+
10
+ Adapter Feature API 2.1 and Tool Feature API 1.1 describe the additive profile requirements; new Core, official adapters and generated plugins declare the corresponding floors. Existing compatible API-2.0/API-1.0 plugins remain accepted by the newer providers. npm releases remain patch.
11
+
12
+ Private IM assets now bind to the full canonical conversation and principal. Existing IM asset records that contain only the earlier lossy hash remain on disk until their original expiry, but cannot be safely rebound; recapture them. No automatic file deletion, platform profile mutation or workspace SOUL rewrite occurs during upgrade.
13
+
14
+ - Updated dependencies [b88e988]
15
+ - Updated dependencies [f78eb84]
16
+ - Updated dependencies [c15cef9]
17
+ - Updated dependencies [b0c02a2]
18
+ - Updated dependencies [af8f803]
19
+ - Updated dependencies [26fda97]
20
+ - Updated dependencies [976886c]
21
+ - Updated dependencies [032dc96]
22
+ - @zhin.js/adapter@1.1.27
23
+ - @zhin.js/client@1.1.23
24
+ - @zhin.js/im-contract@1.1.10
25
+ - @zhin.js/core@1.1.55
26
+ - @zhin.js/tool@1.1.14
27
+ - @zhin.js/page@1.1.13
28
+ - @zhin.js/host-http@1.1.13
29
+ - @zhin.js/agent-feature@1.1.12
30
+ - @zhin.js/feature-kit@1.1.11
31
+ - @zhin.js/permission@1.1.11
32
+ - @zhin.js/skill@1.1.12
33
+
3
34
  ## 1.1.20
4
35
 
5
36
  ### Patch Changes
package/lib/protocol.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { EndpointProfileConfiguration } from 'zhin.js/adapter';
1
2
  /**
2
3
  * OneBot 11 protocol helpers (no legacy Adapter/Endpoint / segment-mapper).
3
4
  * Canonicalization is owned by gateway/core before endpoint.send.
@@ -5,7 +6,7 @@
5
6
  */
6
7
  import { type MediaRef, type ConversationRef } from '@zhin.js/im-contract';
7
8
  /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
8
- export interface OneBot11EndpointConfig {
9
+ export interface OneBot11EndpointConfig extends EndpointProfileConfiguration {
9
10
  readonly connection?: 'ws' | 'wss';
10
11
  readonly id: string;
11
12
  readonly access_token?: string;
@@ -0,0 +1,12 @@
1
+ import type { EndpointProfile, PendingRpcRequest } from 'zhin.js/adapter';
2
+ interface Onebot11SelfProfileOptions {
3
+ readonly call: (request: PendingRpcRequest) => Promise<unknown>;
4
+ readonly reportAccount: (id: string | undefined) => void;
5
+ }
6
+ interface Onebot11SelfProfile extends EndpointProfile {
7
+ /** The same verified account observations used by transport ingress and shutdown. */
8
+ reportAccount(id: string | undefined): void;
9
+ }
10
+ /** OneBot11's standard self-information action has no standard profile mutation counterpart. */
11
+ export declare function createOnebot11SelfProfile({ call, reportAccount }: Onebot11SelfProfileOptions): Onebot11SelfProfile;
12
+ export {};
@@ -0,0 +1,56 @@
1
+ /** OneBot11's standard self-information action has no standard profile mutation counterpart. */
2
+ export function createOnebot11SelfProfile({ call, reportAccount }) {
3
+ let nickname;
4
+ let accountId;
5
+ let accountRevision = 0;
6
+ let readSequence = 0;
7
+ let publishedSequence = 0;
8
+ return Object.freeze({
9
+ writableFields: Object.freeze([]),
10
+ get current() { return nickname === undefined ? {} : { nickname }; },
11
+ reportAccount(id) {
12
+ if (id !== accountId || id === undefined) {
13
+ accountId = id;
14
+ nickname = undefined;
15
+ accountRevision++;
16
+ readSequence++;
17
+ publishedSequence = readSequence;
18
+ }
19
+ reportAccount(id);
20
+ },
21
+ async read({ signal }) {
22
+ const revision = accountRevision;
23
+ const sequence = ++readSequence;
24
+ const assertAccount = () => {
25
+ signal.throwIfAborted();
26
+ if (revision !== accountRevision)
27
+ throw new Error('OneBot11 account changed while reading self profile');
28
+ };
29
+ const self = await call({ action: 'get_login_info', signal });
30
+ assertAccount();
31
+ if (!self?.user_id || typeof self.nickname !== 'string')
32
+ throw new Error('OneBot11 returned an incomplete self profile');
33
+ if (sequence > publishedSequence) {
34
+ publishedSequence = sequence;
35
+ accountId = String(self.user_id);
36
+ nickname = self.nickname;
37
+ reportAccount(accountId);
38
+ }
39
+ // Keep confirmed login facts in current, while lookup errors remain lookup errors.
40
+ const details = await call({ action: 'get_stranger_info', params: { user_id: self.user_id, no_cache: true }, signal });
41
+ assertAccount();
42
+ if (!details || String(details.user_id) !== String(self.user_id))
43
+ throw new Error('OneBot11 returned another account profile');
44
+ const observedNickname = typeof details.nickname === 'string' ? details.nickname : self.nickname;
45
+ if (sequence >= publishedSequence) {
46
+ publishedSequence = sequence;
47
+ nickname = observedNickname;
48
+ }
49
+ const profile = { nickname: observedNickname,
50
+ ...(details.sex === 'male' || details.sex === 'female' || details.sex === 'unknown' ? { gender: details.sex } : {}),
51
+ ...(typeof details.age === 'number' && Number.isFinite(details.age) ? { age: details.age } : {}),
52
+ };
53
+ return profile;
54
+ },
55
+ });
56
+ }
@@ -1,3 +1,4 @@
1
+ import { createOnebot11SelfProfile } from './self-profile.js';
1
2
  import { EndpointDeliveryError } from '@zhin.js/im-contract';
2
3
  /**
3
4
  * OneBot11 WS client endpoint — outbound connect to OneBot implementation.
@@ -25,6 +26,7 @@ export class OneBot11WsEndpoint extends Onebot11Client {
25
26
  #ws;
26
27
  #stopped = false;
27
28
  #rpc;
29
+ #profile;
28
30
  constructor(options) {
29
31
  const rpc = createOneBot11Rpc({ endpointId: options.config.id, signal: options.signal,
30
32
  socket: () => this.#lifecycle.state === 'open' ? this.#ws : undefined,
@@ -36,6 +38,7 @@ export class OneBot11WsEndpoint extends Onebot11Client {
36
38
  const callApi = (request) => this.#rpc.call(request).then(readOnebot11Response);
37
39
  this.#management = createOneBot11EndpointManagement({ callApi });
38
40
  this.#content = createOneBot11ContentPort(callApi);
41
+ this.#profile = createOnebot11SelfProfile({ call: callApi, reportAccount: id => this[endpointSpec].reportSelfUserId(id) });
39
42
  const readTransportState = () => this.#lifecycle.state;
40
43
  this[endpointSpec] = createEndpointSpecification(this, {
41
44
  name: options.config.id,
@@ -44,6 +47,7 @@ export class OneBot11WsEndpoint extends Onebot11Client {
44
47
  send: request => this.#send(request),
45
48
  get transportState() { return readTransportState(); },
46
49
  management: this.#management, control: this.#control, content: this.#content,
50
+ profile: this.#profile,
47
51
  });
48
52
  this.#releaseClientEvents = forwardOnebot11ClientEvents(this, (name, payload) => {
49
53
  void this[endpointSpec].events.run(() => {
@@ -106,7 +110,7 @@ export class OneBot11WsEndpoint extends Onebot11Client {
106
110
  this.#rpc.dispose();
107
111
  this.#releaseClientEvents();
108
112
  this.#ws = undefined;
109
- this[endpointSpec].reportSelfUserId(undefined);
113
+ this.#profile.reportAccount(undefined);
110
114
  }
111
115
  }
112
116
  async #send({ conversation, payload, signal }) {
@@ -134,7 +138,7 @@ export class OneBot11WsEndpoint extends Onebot11Client {
134
138
  #admitRaw(ev) {
135
139
  const selfId = resolveOnebot11SelfId(ev.self_id);
136
140
  if (!this.#stopped && selfId)
137
- this[endpointSpec].reportSelfUserId(selfId);
141
+ this.#profile.reportAccount(selfId);
138
142
  if (!isMessageEvent(ev)) {
139
143
  receiveOneBot11SideEvent(ev, {
140
144
  emit: (name, payload) => this[endpointSpec].events.emit(name, payload),
@@ -181,7 +185,7 @@ export class OneBot11WsEndpoint extends Onebot11Client {
181
185
  if (this.#stopped || this.#transportState !== 'open')
182
186
  return;
183
187
  if (selfId)
184
- this[endpointSpec].reportSelfUserId(selfId);
188
+ this.#profile.reportAccount(selfId);
185
189
  }
186
190
  #warnPlatformEvent(error) {
187
191
  this.#logger.warn(formatCompact({
@@ -1,3 +1,4 @@
1
+ import { createOnebot11SelfProfile } from './self-profile.js';
1
2
  import { EndpointDeliveryError } from '@zhin.js/im-contract';
2
3
  /**
3
4
  * OneBot11 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
@@ -26,6 +27,7 @@ export class OneBot11WssEndpoint extends Onebot11Client {
26
27
  #connectionLifecycle;
27
28
  #connectionTask = Promise.resolve();
28
29
  #rpc;
30
+ #profile;
29
31
  #started = false;
30
32
  #stopped = false;
31
33
  constructor(options) {
@@ -44,6 +46,7 @@ export class OneBot11WssEndpoint extends Onebot11Client {
44
46
  const callApi = (request) => this.#rpc.call(request).then(readOnebot11Response);
45
47
  this.#management = createOneBot11EndpointManagement({ callApi });
46
48
  this.#content = createOneBot11ContentPort(callApi);
49
+ this.#profile = createOnebot11SelfProfile({ call: callApi, reportAccount: id => this[endpointSpec].reportSelfUserId(id) });
47
50
  const readTransportState = () => this.#transportState;
48
51
  this[endpointSpec] = createEndpointSpecification(this, {
49
52
  name: options.config.id,
@@ -52,6 +55,7 @@ export class OneBot11WssEndpoint extends Onebot11Client {
52
55
  send: request => this.#send(request),
53
56
  get transportState() { return readTransportState(); },
54
57
  management: this.#management, control: this.#control, content: this.#content,
58
+ profile: this.#profile,
55
59
  });
56
60
  this.#releaseClientEvents = forwardOnebot11ClientEvents(this, (name, payload) => {
57
61
  void this[endpointSpec].events.run(() => {
@@ -121,7 +125,7 @@ export class OneBot11WssEndpoint extends Onebot11Client {
121
125
  this.#releaseClientEvents();
122
126
  this.#ws = undefined;
123
127
  this.#started = false;
124
- this[endpointSpec].reportSelfUserId(undefined);
128
+ this.#profile.reportAccount(undefined);
125
129
  }
126
130
  }
127
131
  async #send({ conversation, payload, signal }) {
@@ -142,7 +146,7 @@ export class OneBot11WssEndpoint extends Onebot11Client {
142
146
  #admitRaw(ev) {
143
147
  const selfId = resolveOnebot11SelfId(ev.self_id);
144
148
  if (!this.#stopped && selfId)
145
- this[endpointSpec].reportSelfUserId(selfId);
149
+ this.#profile.reportAccount(selfId);
146
150
  if (!isMessageEvent(ev)) {
147
151
  receiveOneBot11SideEvent(ev, {
148
152
  emit: (name, payload) => this[endpointSpec].events.emit(name, payload),
@@ -188,7 +192,7 @@ export class OneBot11WssEndpoint extends Onebot11Client {
188
192
  if (this.#stopped || this.#transportState !== 'open')
189
193
  return;
190
194
  if (selfId)
191
- this[endpointSpec].reportSelfUserId(selfId);
195
+ this.#profile.reportAccount(selfId);
192
196
  }
193
197
  #warnPlatformEvent(error) {
194
198
  this.#logger.warn(formatCompact({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-onebot11",
3
- "version": "1.1.20",
3
+ "version": "1.1.21",
4
4
  "description": "Zhin.js OneBot 11 adapter for Plugin Runtime (WebSocket client)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -45,19 +45,19 @@
45
45
  "@imhelper/onebot-v11": "1.0.7",
46
46
  "imhelper": "1.0.7",
47
47
  "ws": "^8.21.1",
48
- "@zhin.js/adapter": "1.1.26",
49
- "@zhin.js/agent-feature": "1.1.11",
50
- "@zhin.js/client": "1.1.22",
48
+ "@zhin.js/adapter": "1.1.27",
49
+ "@zhin.js/client": "1.1.23",
50
+ "@zhin.js/agent-feature": "1.1.12",
51
51
  "@zhin.js/console-contract": "1.1.3",
52
- "@zhin.js/core": "1.1.54",
53
- "@zhin.js/feature-kit": "1.1.10",
54
- "@zhin.js/host-http": "1.1.12",
55
- "@zhin.js/im-contract": "1.1.9",
52
+ "@zhin.js/core": "1.1.55",
53
+ "@zhin.js/feature-kit": "1.1.11",
54
+ "@zhin.js/host-http": "1.1.13",
55
+ "@zhin.js/im-contract": "1.1.10",
56
56
  "@zhin.js/logger": "1.1.2",
57
- "@zhin.js/page": "1.1.12",
58
- "@zhin.js/permission": "1.1.10",
59
- "@zhin.js/skill": "1.1.11",
60
- "@zhin.js/tool": "1.1.13"
57
+ "@zhin.js/permission": "1.1.11",
58
+ "@zhin.js/page": "1.1.13",
59
+ "@zhin.js/skill": "1.1.12",
60
+ "@zhin.js/tool": "1.1.14"
61
61
  },
62
62
  "devDependencies": {
63
63
  "@types/node": "^26.1.2",
@@ -65,15 +65,15 @@
65
65
  "typescript": "^6.0.3",
66
66
  "vitest": "^4.1.10",
67
67
  "zod": "^4.4.3",
68
- "@zhin.js/host-http": "1.1.12",
69
- "zhin.js": "1.1.19"
68
+ "@zhin.js/host-http": "1.1.13",
69
+ "zhin.js": "1.1.20"
70
70
  },
71
71
  "peerDependencies": {
72
72
  "zod": "^4.0.0",
73
- "@zhin.js/adapter": "^1.1.26",
74
- "@zhin.js/command": "^1.1.12",
75
- "@zhin.js/core": "^1.1.54",
76
- "zhin.js": "^1.1.19"
73
+ "@zhin.js/adapter": "^1.1.27",
74
+ "@zhin.js/command": "^1.1.13",
75
+ "@zhin.js/core": "^1.1.55",
76
+ "zhin.js": "^1.1.20"
77
77
  },
78
78
  "peerDependenciesMeta": {
79
79
  "@zhin.js/command": {
@@ -107,7 +107,7 @@
107
107
  "features": [
108
108
  {
109
109
  "package": "@zhin.js/adapter",
110
- "api": "^2.0.0"
110
+ "api": "^2.1.0"
111
111
  },
112
112
  {
113
113
  "package": "@zhin.js/command",
@@ -115,7 +115,7 @@
115
115
  },
116
116
  {
117
117
  "package": "@zhin.js/tool",
118
- "api": "^1.0.0"
118
+ "api": "^1.1.0"
119
119
  },
120
120
  {
121
121
  "package": "@zhin.js/skill",
package/schema.json CHANGED
@@ -115,6 +115,27 @@
115
115
  "id": {
116
116
  "type": "string",
117
117
  "description": "OneBot11 bot name"
118
+ },
119
+ "nickname": {
120
+ "type": [
121
+ "string",
122
+ "null"
123
+ ],
124
+ "description": "账号昵称兜底",
125
+ "x-i18n": {
126
+ "en": {
127
+ "description": "Fallback account nickname"
128
+ }
129
+ }
130
+ },
131
+ "profile": {
132
+ "$ref": "#/$defs/selfProfileFallback",
133
+ "description": "账号资料兜底",
134
+ "x-i18n": {
135
+ "en": {
136
+ "description": "Fallback account profile"
137
+ }
138
+ }
118
139
  }
119
140
  },
120
141
  "required": [
@@ -136,9 +157,93 @@
136
157
  "description": "Command prefix. The default empty string allows unprefixed commands; '/' requires a leading slash. Each endpoints[i] can override it."
137
158
  }
138
159
  }
160
+ },
161
+ "nickname": {
162
+ "type": [
163
+ "string",
164
+ "null"
165
+ ],
166
+ "description": "账号昵称兜底",
167
+ "x-i18n": {
168
+ "en": {
169
+ "description": "Fallback account nickname"
170
+ }
171
+ }
172
+ },
173
+ "profile": {
174
+ "$ref": "#/$defs/selfProfileFallback",
175
+ "description": "账号资料兜底",
176
+ "x-i18n": {
177
+ "en": {
178
+ "description": "Fallback account profile"
179
+ }
180
+ }
139
181
  }
140
182
  },
141
183
  "required": [
142
184
  "endpoints"
143
- ]
185
+ ],
186
+ "$defs": {
187
+ "selfProfileFallback": {
188
+ "type": "object",
189
+ "additionalProperties": false,
190
+ "properties": {
191
+ "gender": {
192
+ "type": [
193
+ "string",
194
+ "null"
195
+ ],
196
+ "enum": [
197
+ "male",
198
+ "female",
199
+ "other",
200
+ "unknown",
201
+ null
202
+ ]
203
+ },
204
+ "age": {
205
+ "type": [
206
+ "integer",
207
+ "null"
208
+ ],
209
+ "minimum": 0
210
+ },
211
+ "birthday": {
212
+ "type": [
213
+ "string",
214
+ "null"
215
+ ],
216
+ "pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$"
217
+ },
218
+ "signature": {
219
+ "type": [
220
+ "string",
221
+ "null"
222
+ ]
223
+ },
224
+ "avatar": {
225
+ "type": [
226
+ "string",
227
+ "null"
228
+ ],
229
+ "pattern": "^(https?://[^\\s/?#]+(?:[/?#].*)?|)$"
230
+ },
231
+ "interests": {
232
+ "type": [
233
+ "array",
234
+ "null"
235
+ ],
236
+ "items": {
237
+ "type": "string"
238
+ }
239
+ },
240
+ "bio": {
241
+ "type": [
242
+ "string",
243
+ "null"
244
+ ]
245
+ }
246
+ }
247
+ }
248
+ }
144
249
  }
package/src/protocol.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { EndpointProfileConfiguration } from 'zhin.js/adapter';
1
2
  /**
2
3
  * OneBot 11 protocol helpers (no legacy Adapter/Endpoint / segment-mapper).
3
4
  * Canonicalization is owned by gateway/core before endpoint.send.
@@ -9,7 +10,7 @@ import { formatCompact, getLogger } from '@zhin.js/logger';
9
10
  const logger = getLogger('onebot11');
10
11
 
11
12
  /** One endpoint config after AdapterIndex expands `plugins.<instanceKey>.endpoints`. */
12
- export interface OneBot11EndpointConfig {
13
+ export interface OneBot11EndpointConfig extends EndpointProfileConfiguration {
13
14
  readonly connection?: 'ws' | 'wss';
14
15
  readonly id: string;
15
16
  readonly access_token?: string;
@@ -0,0 +1,67 @@
1
+ import type { EndpointProfile, PendingRpcRequest } from 'zhin.js/adapter';
2
+ import type { SelfProfile } from '@zhin.js/im-contract';
3
+
4
+ interface Onebot11SelfProfileOptions {
5
+ readonly call: (request: PendingRpcRequest) => Promise<unknown>;
6
+ readonly reportAccount: (id: string | undefined) => void;
7
+ }
8
+ interface Onebot11SelfProfile extends EndpointProfile {
9
+ /** The same verified account observations used by transport ingress and shutdown. */
10
+ reportAccount(id: string | undefined): void;
11
+ }
12
+
13
+ /** OneBot11's standard self-information action has no standard profile mutation counterpart. */
14
+ export function createOnebot11SelfProfile({ call, reportAccount }: Onebot11SelfProfileOptions): Onebot11SelfProfile {
15
+ let nickname: string | undefined;
16
+ let accountId: string | undefined;
17
+ let accountRevision = 0;
18
+ let readSequence = 0;
19
+ let publishedSequence = 0;
20
+ return Object.freeze<Onebot11SelfProfile>({
21
+ writableFields: Object.freeze([]),
22
+ get current() { return nickname === undefined ? {} : { nickname }; },
23
+ reportAccount(id) {
24
+ if (id !== accountId || id === undefined) {
25
+ accountId = id;
26
+ nickname = undefined;
27
+ accountRevision++;
28
+ readSequence++;
29
+ publishedSequence = readSequence;
30
+ }
31
+ reportAccount(id);
32
+ },
33
+ async read({ signal }) {
34
+ const revision = accountRevision;
35
+ const sequence = ++readSequence;
36
+ const assertAccount = () => {
37
+ signal.throwIfAborted();
38
+ if (revision !== accountRevision) throw new Error('OneBot11 account changed while reading self profile');
39
+ };
40
+ const self = await call({ action: 'get_login_info', signal }) as { user_id?: number | string; nickname?: string } | undefined;
41
+ assertAccount();
42
+ if (!self?.user_id || typeof self.nickname !== 'string') throw new Error('OneBot11 returned an incomplete self profile');
43
+ if (sequence > publishedSequence) {
44
+ publishedSequence = sequence;
45
+ accountId = String(self.user_id);
46
+ nickname = self.nickname;
47
+ reportAccount(accountId);
48
+ }
49
+ // Keep confirmed login facts in current, while lookup errors remain lookup errors.
50
+ const details = await call({ action: 'get_stranger_info', params: { user_id: self.user_id, no_cache: true }, signal }) as {
51
+ user_id?: number | string; nickname?: string; sex?: string; age?: number;
52
+ } | undefined;
53
+ assertAccount();
54
+ if (!details || String(details.user_id) !== String(self.user_id)) throw new Error('OneBot11 returned another account profile');
55
+ const observedNickname = typeof details.nickname === 'string' ? details.nickname : self.nickname;
56
+ if (sequence >= publishedSequence) {
57
+ publishedSequence = sequence;
58
+ nickname = observedNickname;
59
+ }
60
+ const profile: SelfProfile = { nickname: observedNickname,
61
+ ...(details.sex === 'male' || details.sex === 'female' || details.sex === 'unknown' ? { gender: details.sex } : {}),
62
+ ...(typeof details.age === 'number' && Number.isFinite(details.age) ? { age: details.age } : {}),
63
+ };
64
+ return profile;
65
+ },
66
+ });
67
+ }
@@ -1,3 +1,4 @@
1
+ import { createOnebot11SelfProfile } from './self-profile.js';
1
2
  import { EndpointDeliveryError } from '@zhin.js/im-contract';
2
3
  /**
3
4
  * OneBot11 WS client endpoint — outbound connect to OneBot implementation.
@@ -68,6 +69,7 @@ export class OneBot11WsEndpoint extends Onebot11Client implements Endpoint {
68
69
  #ws?: OneBot11WsSocket;
69
70
  #stopped = false;
70
71
  readonly #rpc: OneBot11Rpc;
72
+ readonly #profile: ReturnType<typeof createOnebot11SelfProfile>;
71
73
 
72
74
  constructor(options: OneBot11WsEndpointOptions) {
73
75
  const rpc = createOneBot11Rpc({ endpointId: options.config.id, signal: options.signal,
@@ -80,6 +82,7 @@ export class OneBot11WsEndpoint extends Onebot11Client implements Endpoint {
80
82
  const callApi = (request: PendingRpcRequest) => this.#rpc.call(request).then(readOnebot11Response);
81
83
  this.#management = createOneBot11EndpointManagement({ callApi });
82
84
  this.#content = createOneBot11ContentPort(callApi);
85
+ this.#profile = createOnebot11SelfProfile({ call: callApi, reportAccount: id => this[endpointSpec].reportSelfUserId(id) });
83
86
  const readTransportState = () => this.#lifecycle.state;
84
87
  this[endpointSpec] = createEndpointSpecification(this, {
85
88
  name: options.config.id,
@@ -88,6 +91,7 @@ export class OneBot11WsEndpoint extends Onebot11Client implements Endpoint {
88
91
  send: request => this.#send(request),
89
92
  get transportState() { return readTransportState(); },
90
93
  management: this.#management, control: this.#control, content: this.#content,
94
+ profile: this.#profile,
91
95
  });
92
96
  this.#releaseClientEvents = forwardOnebot11ClientEvents(this, (name, payload) => {
93
97
  void this[endpointSpec].events.run(() => {
@@ -145,7 +149,7 @@ export class OneBot11WsEndpoint extends Onebot11Client implements Endpoint {
145
149
  this.#rpc.dispose();
146
150
  this.#releaseClientEvents();
147
151
  this.#ws = undefined;
148
- this[endpointSpec].reportSelfUserId(undefined);
152
+ this.#profile.reportAccount(undefined);
149
153
  }
150
154
  }
151
155
 
@@ -175,7 +179,7 @@ export class OneBot11WsEndpoint extends Onebot11Client implements Endpoint {
175
179
 
176
180
  #admitRaw(ev: OneBot11Event): void {
177
181
  const selfId = resolveOnebot11SelfId(ev.self_id);
178
- if (!this.#stopped && selfId) this[endpointSpec].reportSelfUserId(selfId);
182
+ if (!this.#stopped && selfId) this.#profile.reportAccount(selfId);
179
183
  if (!isMessageEvent(ev)) {
180
184
  receiveOneBot11SideEvent(ev, {
181
185
  emit: (name, payload) => this[endpointSpec].events.emit(name, payload),
@@ -221,7 +225,7 @@ export class OneBot11WsEndpoint extends Onebot11Client implements Endpoint {
221
225
  }));
222
226
  });
223
227
  if (this.#stopped || this.#transportState !== 'open') return;
224
- if (selfId) this[endpointSpec].reportSelfUserId(selfId);
228
+ if (selfId) this.#profile.reportAccount(selfId);
225
229
  }
226
230
 
227
231
  #warnPlatformEvent(error: unknown): void {
@@ -1,3 +1,4 @@
1
+ import { createOnebot11SelfProfile } from './self-profile.js';
1
2
  import { EndpointDeliveryError } from '@zhin.js/im-contract';
2
3
  /**
3
4
  * OneBot11 reverse WSS endpoint — accepts inbound WebSocket from OneBot implementation.
@@ -64,6 +65,7 @@ export class OneBot11WssEndpoint extends Onebot11Client implements Endpoint {
64
65
  readonly #connectionLifecycle: EndpointLifecycle;
65
66
  #connectionTask = Promise.resolve();
66
67
  readonly #rpc: OneBot11Rpc;
68
+ readonly #profile: ReturnType<typeof createOnebot11SelfProfile>;
67
69
  #started = false;
68
70
  #stopped = false;
69
71
 
@@ -83,6 +85,7 @@ export class OneBot11WssEndpoint extends Onebot11Client implements Endpoint {
83
85
  const callApi = (request: PendingRpcRequest) => this.#rpc.call(request).then(readOnebot11Response);
84
86
  this.#management = createOneBot11EndpointManagement({ callApi });
85
87
  this.#content = createOneBot11ContentPort(callApi);
88
+ this.#profile = createOnebot11SelfProfile({ call: callApi, reportAccount: id => this[endpointSpec].reportSelfUserId(id) });
86
89
  const readTransportState = () => this.#transportState;
87
90
  this[endpointSpec] = createEndpointSpecification(this, {
88
91
  name: options.config.id,
@@ -91,6 +94,7 @@ export class OneBot11WssEndpoint extends Onebot11Client implements Endpoint {
91
94
  send: request => this.#send(request),
92
95
  get transportState() { return readTransportState(); },
93
96
  management: this.#management, control: this.#control, content: this.#content,
97
+ profile: this.#profile,
94
98
  });
95
99
  this.#releaseClientEvents = forwardOnebot11ClientEvents(this, (name, payload) => {
96
100
  void this[endpointSpec].events.run(() => {
@@ -155,7 +159,7 @@ export class OneBot11WssEndpoint extends Onebot11Client implements Endpoint {
155
159
  this.#releaseClientEvents();
156
160
  this.#ws = undefined;
157
161
  this.#started = false;
158
- this[endpointSpec].reportSelfUserId(undefined);
162
+ this.#profile.reportAccount(undefined);
159
163
  }
160
164
  }
161
165
 
@@ -178,7 +182,7 @@ export class OneBot11WssEndpoint extends Onebot11Client implements Endpoint {
178
182
 
179
183
  #admitRaw(ev: OneBot11Event): void {
180
184
  const selfId = resolveOnebot11SelfId(ev.self_id);
181
- if (!this.#stopped && selfId) this[endpointSpec].reportSelfUserId(selfId);
185
+ if (!this.#stopped && selfId) this.#profile.reportAccount(selfId);
182
186
  if (!isMessageEvent(ev)) {
183
187
  receiveOneBot11SideEvent(ev, {
184
188
  emit: (name, payload) => this[endpointSpec].events.emit(name, payload),
@@ -223,7 +227,7 @@ export class OneBot11WssEndpoint extends Onebot11Client implements Endpoint {
223
227
  }));
224
228
  });
225
229
  if (this.#stopped || this.#transportState !== 'open') return;
226
- if (selfId) this[endpointSpec].reportSelfUserId(selfId);
230
+ if (selfId) this.#profile.reportAccount(selfId);
227
231
  }
228
232
 
229
233
  #warnPlatformEvent(error: unknown): void {