@agentunion/fastaun 0.5.26 → 0.5.28

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.
Files changed (94) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/_packed_docs/CHANGELOG.md +77 -0
  3. package/_packed_docs/INDEX.md +37 -14
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +23 -15
  5. package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +16 -1
  6. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +37 -9
  7. package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +20 -9
  8. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +57 -12
  9. package/_packed_docs/sdk/0.5.22-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +2 -2
  10. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +2 -2
  11. package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +187 -73
  12. package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +1 -1
  13. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +13 -9
  14. package/_packed_docs/sdk/INDEX.md +23 -13
  15. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +973 -266
  16. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +950 -242
  17. package/dist/agent-md-changes.d.ts +42 -0
  18. package/dist/agent-md-changes.js +339 -0
  19. package/dist/agent-md-changes.js.map +1 -0
  20. package/dist/agent-md-schema.d.ts +1 -0
  21. package/dist/agent-md-schema.js +31 -14
  22. package/dist/agent-md-schema.js.map +1 -1
  23. package/dist/agent-md.d.ts +11 -0
  24. package/dist/agent-md.js +91 -15
  25. package/dist/agent-md.js.map +1 -1
  26. package/dist/aid-store.d.ts +11 -0
  27. package/dist/aid-store.js +102 -21
  28. package/dist/aid-store.js.map +1 -1
  29. package/dist/aid.js +3 -3
  30. package/dist/aid.js.map +1 -1
  31. package/dist/auth.d.ts +10 -0
  32. package/dist/auth.js +65 -23
  33. package/dist/auth.js.map +1 -1
  34. package/dist/cert-utils.d.ts +1 -1
  35. package/dist/cert-utils.js +4 -4
  36. package/dist/cert-utils.js.map +1 -1
  37. package/dist/client/control-messages.d.ts +31 -0
  38. package/dist/client/control-messages.js +474 -0
  39. package/dist/client/control-messages.js.map +1 -0
  40. package/dist/client/delivery.js +10 -2
  41. package/dist/client/delivery.js.map +1 -1
  42. package/dist/client/lifecycle.d.ts +1 -1
  43. package/dist/client/lifecycle.js +10 -0
  44. package/dist/client/lifecycle.js.map +1 -1
  45. package/dist/client/rpc-pipeline.js +84 -14
  46. package/dist/client/rpc-pipeline.js.map +1 -1
  47. package/dist/client/v2-e2ee.d.ts +3 -0
  48. package/dist/client/v2-e2ee.js +12 -0
  49. package/dist/client/v2-e2ee.js.map +1 -1
  50. package/dist/client.d.ts +38 -0
  51. package/dist/client.js +572 -36
  52. package/dist/client.js.map +1 -1
  53. package/dist/discovery.d.ts +3 -0
  54. package/dist/discovery.js +52 -2
  55. package/dist/discovery.js.map +1 -1
  56. package/dist/events.js +14 -1
  57. package/dist/events.js.map +1 -1
  58. package/dist/facades.d.ts +38 -0
  59. package/dist/facades.js +49 -5
  60. package/dist/facades.js.map +1 -1
  61. package/dist/index.d.ts +4 -0
  62. package/dist/index.js +3 -0
  63. package/dist/index.js.map +1 -1
  64. package/dist/org-protocol.d.ts +1 -0
  65. package/dist/org-protocol.js +39 -36
  66. package/dist/org-protocol.js.map +1 -1
  67. package/dist/ownership-v21.js +7 -7
  68. package/dist/ownership-v21.js.map +1 -1
  69. package/dist/register-flow.js +2 -2
  70. package/dist/register-flow.js.map +1 -1
  71. package/dist/risk-control.d.ts +68 -0
  72. package/dist/risk-control.js +344 -0
  73. package/dist/risk-control.js.map +1 -0
  74. package/dist/semantic-facade.d.ts +176 -0
  75. package/dist/semantic-facade.js +611 -0
  76. package/dist/semantic-facade.js.map +1 -0
  77. package/dist/semantic-protocol.d.ts +810 -0
  78. package/dist/semantic-protocol.js +894 -0
  79. package/dist/semantic-protocol.js.map +1 -0
  80. package/dist/storage/lowlevel.d.ts +1 -0
  81. package/dist/storage/lowlevel.js +2 -2
  82. package/dist/storage/lowlevel.js.map +1 -1
  83. package/dist/tools/cross-sdk-agent.d.ts +11 -1
  84. package/dist/tools/cross-sdk-agent.js +388 -7
  85. package/dist/tools/cross-sdk-agent.js.map +1 -1
  86. package/dist/transport.d.ts +22 -1
  87. package/dist/transport.js +227 -22
  88. package/dist/transport.js.map +1 -1
  89. package/dist/v2/e2ee/decrypt.d.ts +5 -0
  90. package/dist/v2/e2ee/decrypt.js +22 -2
  91. package/dist/v2/e2ee/decrypt.js.map +1 -1
  92. package/dist/version.d.ts +1 -1
  93. package/dist/version.js +1 -1
  94. package/package.json +1 -1
@@ -56,9 +56,15 @@ export declare class RPCTransport {
56
56
  private _drainingRpcQueue;
57
57
  _onForegroundDrained?: () => void;
58
58
  _onRpcResponse?: () => void;
59
- private _sendChain;
59
+ private _sendQueue;
60
+ private _sending;
61
+ private _riskDeliveries;
60
62
  private _idCounter;
61
63
  private _metaObserver;
64
+ private _requestAdmission;
65
+ private _requestCheck;
66
+ private _riskControlHandler;
67
+ private _classMessageHandler;
62
68
  private _protocolMetaObserver;
63
69
  private _traceMode;
64
70
  private _traceObserver;
@@ -106,8 +112,18 @@ export declare class RPCTransport {
106
112
  * 不影响 RPC 结果返回。
107
113
  */
108
114
  setMetaObserver(observer: MetaObserver | null): void;
115
+ setRequestAdmission(admission: ((request: string) => () => void) | null): void;
116
+ setRequestCheck(check: (request: string) => void): void;
117
+ setClassMessageHandler(handler: (event: string, payload: JsonObject) => boolean): void;
118
+ private _routeClassMessage;
119
+ setRiskSnapshot(state: JsonObject): Promise<void>;
120
+ setRiskControlHandler(handler: ((payload: JsonObject) => void | Promise<void>) | null): void;
121
+ private _finishRiskDelivery;
122
+ private _receiveRiskControl;
123
+ private _dispatchRiskControl;
109
124
  setProtocolMetaObserver(observer: MetaObserver | null): void;
110
125
  setProtocolDisconnectCallback(callback: DisconnectCallback | null): void;
126
+ waitForPending(timeoutMs: number, signal?: AbortSignal): Promise<void>;
111
127
  getTraceMode(): string;
112
128
  /** 设置 trace 模式:off / log / diag */
113
129
  setTraceMode(mode: string): void;
@@ -145,11 +161,16 @@ export declare class RPCTransport {
145
161
  call(method: string, params?: RpcParams, timeout?: number, trace?: string, background?: boolean): Promise<RpcResult>;
146
162
  private _callWithSent;
147
163
  private _call;
164
+ private _callAdmitted;
148
165
  private _callLocal;
149
166
  /** 发送 JSON-RPC 2.0 Notification,不分配 id,也不等待响应。 */
150
167
  notify(method: string, params?: RpcParams | null): Promise<void>;
168
+ private _notifyAdmitted;
151
169
  private _notifyLocal;
170
+ private _messagePriority;
171
+ private _isRiskControlMethod;
152
172
  private _enqueueSend;
173
+ private _startSendQueue;
153
174
  private _sendText;
154
175
  private _sendFailureError;
155
176
  private _waitForCloseCodeIfClosing;
package/dist/transport.js CHANGED
@@ -14,6 +14,8 @@ import { AUNError, AuthError, CertificateRevokedError, ClientSignatureError, Con
14
14
  import { trafficLogContext, withLogContext } from './logger.js';
15
15
  import { isJsonObject } from './types.js';
16
16
  import { parseJsonStrict, validateOrgRequestJSON } from './org-protocol.js';
17
+ import { RiskController } from './risk-control.js';
18
+ import { messageClassOf } from './client/control-messages.js';
17
19
  const MAX_WS_PAYLOAD_SIZE = 1_000_000;
18
20
  const MAX_RPC_INFLIGHT = 16;
19
21
  const MAX_BACKGROUND_RPC_INFLIGHT = 8;
@@ -572,11 +574,17 @@ export class RPCTransport {
572
574
  _drainingRpcQueue = false;
573
575
  _onForegroundDrained;
574
576
  _onRpcResponse;
575
- _sendChain = Promise.resolve();
577
+ _sendQueue = [];
578
+ _sending = false;
579
+ _riskDeliveries = 0;
576
580
  _idCounter = 0;
577
581
  // Gateway 在 RPC envelope 注入 _meta 字段(与 result 同级),由 client 层 observer 接收。
578
582
  // observer 抛异常会被吞掉,不影响 RPC result 返回。
579
583
  _metaObserver = null;
584
+ _requestAdmission = null;
585
+ _requestCheck = null;
586
+ _riskControlHandler = null;
587
+ _classMessageHandler = null;
580
588
  _protocolMetaObserver = false;
581
589
  // Trace 模式:off / log / diag
582
590
  _traceMode = 'off';
@@ -829,6 +837,16 @@ export class RPCTransport {
829
837
  }
830
838
  if (this._workerGeneration === null || message.generation !== this._workerGeneration)
831
839
  return;
840
+ if (message.event === '_transport.risk_control') {
841
+ this._dispatchRiskControl(message.payload, () => message.generation === this._workerGeneration);
842
+ return;
843
+ }
844
+ if (message.event === '_transport.class_message') {
845
+ const value = message.payload;
846
+ if (value && typeof value.event === 'string')
847
+ this._routeClassMessage(value.event, value.payload);
848
+ return;
849
+ }
832
850
  if (message.event === '_transport.observer') {
833
851
  const item = message.payload;
834
852
  const observer = item?.kind?.includes('trace') ? this._traceObserver : this._metaObserver;
@@ -858,7 +876,8 @@ export class RPCTransport {
858
876
  this._dispatcher.enqueue(message.event, message.payload);
859
877
  }
860
878
  else {
861
- this._dispatcher.enqueueProtocol(message.event, message.payload);
879
+ const migration = message.event === 'notification' && message.payload?.method === 'gateway.migrate';
880
+ this._dispatcher.enqueueProtocol(message.event, message.payload, migration ? () => message.generation === this._workerGeneration : undefined);
862
881
  }
863
882
  }
864
883
  }
@@ -996,6 +1015,66 @@ export class RPCTransport {
996
1015
  this._metaObserver = observer;
997
1016
  this._protocolMetaObserver = false;
998
1017
  }
1018
+ setRequestAdmission(admission) { this._requestAdmission = admission; }
1019
+ setRequestCheck(check) { this._requestCheck = check; }
1020
+ setClassMessageHandler(handler) { this._classMessageHandler = handler; }
1021
+ _routeClassMessage(event, payload) {
1022
+ if (!['message.received', 'group.message_created'].includes(event) || !isJsonObject(payload))
1023
+ return false;
1024
+ const value = payload;
1025
+ const messageClass = messageClassOf(value);
1026
+ if (value.delivery_class === 'normal' && messageClass !== 'sdk_control')
1027
+ return false;
1028
+ if (messageClass === 'normal' && !(event === 'group.message_created' && (value.storage === 'volatile' || value.volatile === true)))
1029
+ return false;
1030
+ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
1031
+ parentPort.postMessage({ type: 'event', generation: this._connectionGeneration, event: '_transport.class_message', payload: { event, payload: value } });
1032
+ }
1033
+ else {
1034
+ try {
1035
+ this._classMessageHandler?.(event, value);
1036
+ }
1037
+ catch { /* 控制正文保持内部隔离 */ }
1038
+ }
1039
+ return true;
1040
+ }
1041
+ async setRiskSnapshot(state) {
1042
+ if (this._worker)
1043
+ await this._workerCommand({ type: 'risk_snapshot', riskState: state });
1044
+ }
1045
+ setRiskControlHandler(handler) {
1046
+ this._riskControlHandler = handler;
1047
+ }
1048
+ _finishRiskDelivery() {
1049
+ this._riskDeliveries = Math.max(0, this._riskDeliveries - 1);
1050
+ if (this._riskDeliveries === 0)
1051
+ this._startSendQueue();
1052
+ }
1053
+ _receiveRiskControl(payload) {
1054
+ if (!isJsonObject(payload))
1055
+ return;
1056
+ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
1057
+ this._riskDeliveries += 1;
1058
+ parentPort.postMessage({ type: 'event', generation: this._connectionGeneration, event: '_transport.risk_control', payload });
1059
+ }
1060
+ else {
1061
+ const generation = this._connectionGeneration;
1062
+ this._dispatchRiskControl(payload, () => generation === this._connectionGeneration);
1063
+ }
1064
+ }
1065
+ _dispatchRiskControl(payload, current) {
1066
+ const handler = this._riskControlHandler;
1067
+ this._riskDeliveries += 1;
1068
+ const value = structuredClone(payload);
1069
+ void Promise.resolve().then(() => {
1070
+ if (current() && handler && this._riskControlHandler === handler && isJsonObject(value))
1071
+ return handler(value);
1072
+ }).catch(() => { }).finally(() => {
1073
+ this._finishRiskDelivery();
1074
+ if (current() && this._worker)
1075
+ this._worker.postMessage({ type: 'risk_release', generation: this._workerGeneration ?? undefined });
1076
+ });
1077
+ }
999
1078
  setProtocolMetaObserver(observer) {
1000
1079
  this._metaObserver = observer;
1001
1080
  this._protocolMetaObserver = true;
@@ -1006,6 +1085,21 @@ export class RPCTransport {
1006
1085
  this._onDisconnect = callback;
1007
1086
  this._protocolDisconnectCallback = callback !== null;
1008
1087
  }
1088
+ async waitForPending(timeoutMs, signal) {
1089
+ const deadline = Date.now() + Math.max(0, timeoutMs);
1090
+ while (!signal?.aborted && Date.now() < deadline) {
1091
+ const active = this._worker
1092
+ ? [...this._workerPending.values()].some((entry) => entry.commandType === 'call' || entry.commandType === 'notify')
1093
+ : this._pending.size > 0 || this._rpcQueue.length > 0 || this._backgroundRpcQueue.length > 0;
1094
+ if (!active)
1095
+ return;
1096
+ await new Promise((resolve) => {
1097
+ const finish = () => { clearTimeout(timer); signal?.removeEventListener('abort', finish); resolve(); };
1098
+ const timer = setTimeout(finish, Math.min(10, deadline - Date.now()));
1099
+ signal?.addEventListener('abort', finish, { once: true });
1100
+ });
1101
+ }
1102
+ }
1009
1103
  getTraceMode() {
1010
1104
  return this._traceMode;
1011
1105
  }
@@ -1437,6 +1531,8 @@ export class RPCTransport {
1437
1531
  this._handshakeAbort = null;
1438
1532
  abortHandshake?.();
1439
1533
  this._closed = true;
1534
+ this._riskDeliveries = 0;
1535
+ this._startSendQueue();
1440
1536
  this._connectionGeneration += 1;
1441
1537
  this._stopWebSocketHeartbeat();
1442
1538
  // 取消所有待处理的 RPC
@@ -1532,6 +1628,20 @@ export class RPCTransport {
1532
1628
  return Object.assign(result, { cancel: request.cancel });
1533
1629
  }
1534
1630
  _call(method, params, timeout, trace, background = false, onSent, sentCheckpoint) {
1631
+ if (!this._requestAdmission)
1632
+ return this._callAdmitted(method, params, timeout, trace, background, onSent, sentCheckpoint);
1633
+ let release;
1634
+ try {
1635
+ release = this._requestAdmission?.(`rpc:${method}`);
1636
+ const request = this._callAdmitted(method, params, timeout, trace, background, onSent, sentCheckpoint);
1637
+ return Object.assign(request.finally(() => release?.()), { cancel: request.cancel });
1638
+ }
1639
+ catch (error) {
1640
+ release?.();
1641
+ return Promise.reject(error);
1642
+ }
1643
+ }
1644
+ _callAdmitted(method, params, timeout, trace, background = false, onSent, sentCheckpoint) {
1535
1645
  if (this._worker) {
1536
1646
  const requestContext = trafficLogContext('outbound', params ?? {});
1537
1647
  const requestLog = withLogContext(this._logger, requestContext);
@@ -1664,6 +1774,7 @@ export class RPCTransport {
1664
1774
  tStart,
1665
1775
  timeoutMs: effectiveTimeout,
1666
1776
  background: backgroundRpc,
1777
+ priority: this._messagePriority(localParams.message_class),
1667
1778
  logger: requestLog,
1668
1779
  onSent,
1669
1780
  });
@@ -1677,6 +1788,7 @@ export class RPCTransport {
1677
1788
  tStart,
1678
1789
  timeoutMs: effectiveTimeout,
1679
1790
  background: true,
1791
+ priority: this._messagePriority(localParams.message_class),
1680
1792
  logger: requestLog,
1681
1793
  onSent,
1682
1794
  });
@@ -1687,6 +1799,15 @@ export class RPCTransport {
1687
1799
  }
1688
1800
  /** 发送 JSON-RPC 2.0 Notification,不分配 id,也不等待响应。 */
1689
1801
  async notify(method, params) {
1802
+ const release = this._requestAdmission?.(`rpc:${String(method).replace(/^(notification|event)\//, '')}`);
1803
+ try {
1804
+ await this._notifyAdmitted(method, params);
1805
+ }
1806
+ finally {
1807
+ release?.();
1808
+ }
1809
+ }
1810
+ async _notifyAdmitted(method, params) {
1690
1811
  if (this._worker) {
1691
1812
  await this._workerCommand({ type: 'notify', method, params });
1692
1813
  return;
@@ -1717,15 +1838,43 @@ export class RPCTransport {
1717
1838
  throw new ValidationError('payload is too large');
1718
1839
  }
1719
1840
  const notifyLog = withLogContext(this._logger, trafficLogContext('outbound', params ?? {}));
1720
- await this._sendText(payload, `notification ${normalizedMethod}`);
1841
+ await this._sendText(payload, `notification ${normalizedMethod}`, () => { this._requestCheck?.(`rpc:${normalizedMethod.replace(/^(notification|event)\//, '')}`); return true; }, this._messagePriority(params?.message_class));
1721
1842
  notifyLog.debug(`notification sent: method=${normalizedMethod}, size=${payloadSize}`);
1722
1843
  }
1723
- _enqueueSend(task) {
1724
- const run = this._sendChain.then(task, task);
1725
- this._sendChain = run.catch(() => { });
1726
- return run;
1844
+ _messagePriority(messageClass) { return messageClass === 'sdk_control' ? 2 : messageClass === 'control' ? 1 : 0; }
1845
+ _isRiskControlMethod(method) { return ['gateway.risk_ack', 'meta.ping', 'system.ping', 'ping', 'auth.disconnect', 'gateway.risk_status'].includes(method); }
1846
+ _enqueueSend(task, priority = 0) {
1847
+ const result = new Promise((resolve, reject) => { this._sendQueue.push({ task, priority, resolve, reject }); });
1848
+ this._startSendQueue();
1849
+ return result;
1850
+ }
1851
+ _startSendQueue() {
1852
+ if (this._sending)
1853
+ return;
1854
+ this._sending = true;
1855
+ void Promise.resolve().then(async () => {
1856
+ try {
1857
+ while (this._sendQueue.length) {
1858
+ this._sendQueue.sort((left, right) => right.priority - left.priority);
1859
+ const index = this._riskDeliveries > 0 ? this._sendQueue.findIndex(entry => entry.priority === 3) : 0;
1860
+ if (index < 0)
1861
+ break;
1862
+ const entry = this._sendQueue.splice(index, 1)[0];
1863
+ try {
1864
+ await entry.task();
1865
+ entry.resolve();
1866
+ }
1867
+ catch (error) {
1868
+ entry.reject(error);
1869
+ }
1870
+ }
1871
+ }
1872
+ finally {
1873
+ this._sending = false;
1874
+ }
1875
+ });
1727
1876
  }
1728
- _sendText(payload, context, beforeSend) {
1877
+ _sendText(payload, context, beforeSend, priority = 0) {
1729
1878
  return this._enqueueSend(async () => {
1730
1879
  if (beforeSend && !beforeSend()) {
1731
1880
  throw new ConnectionError(`send cancelled before write: ${context}`);
@@ -1751,7 +1900,7 @@ export class RPCTransport {
1751
1900
  this._sendFailureError(context, err, ws).then(reject, reject);
1752
1901
  }
1753
1902
  });
1754
- });
1903
+ }, priority);
1755
1904
  }
1756
1905
  async _sendFailureError(context, err, ws) {
1757
1906
  const original = err instanceof Error ? err.message : String(err);
@@ -1823,19 +1972,29 @@ export class RPCTransport {
1823
1972
  this._drainingRpcQueue = true;
1824
1973
  let foregroundDrained = false;
1825
1974
  try {
1826
- while (!this._closed && this._ws && this._pending.size < MAX_RPC_INFLIGHT) {
1975
+ while (!this._closed && this._ws) {
1976
+ const controlOnly = this._pending.size >= MAX_RPC_INFLIGHT;
1977
+ if (controlOnly && (!this._rpcQueue.some(entry => this._isRiskControlMethod(entry.method)) || Array.from(this._pendingMeta.values()).filter(entry => this._isRiskControlMethod(entry.method)).length >= 4))
1978
+ break;
1827
1979
  let entry;
1828
- if (this._rpcQueue.length > 0) {
1829
- entry = this._rpcQueue.shift();
1830
- if (this._rpcQueue.length === 0)
1831
- foregroundDrained = true;
1832
- }
1833
- else if (this._backgroundRpcQueue.length > 0 && this._pendingBackground.size < MAX_BACKGROUND_RPC_INFLIGHT) {
1834
- entry = this._backgroundRpcQueue.shift();
1980
+ let selectedQueue;
1981
+ let selectedIndex = -1;
1982
+ for (const queue of [this._rpcQueue, ...(this._pendingBackground.size < MAX_BACKGROUND_RPC_INFLIGHT ? [this._backgroundRpcQueue] : [])]) {
1983
+ for (let index = 0; index < queue.length; index++) {
1984
+ if (controlOnly && !this._isRiskControlMethod(queue[index].method))
1985
+ continue;
1986
+ if (!entry || queue[index].priority > entry.priority) {
1987
+ entry = queue[index];
1988
+ selectedQueue = queue;
1989
+ selectedIndex = index;
1990
+ }
1991
+ }
1835
1992
  }
1836
- else {
1993
+ if (!entry || !selectedQueue)
1837
1994
  break;
1838
- }
1995
+ selectedQueue.splice(selectedIndex, 1);
1996
+ if (selectedQueue === this._rpcQueue && this._rpcQueue.length === 0)
1997
+ foregroundDrained = true;
1839
1998
  const elapsed = Date.now() - entry.tStart;
1840
1999
  if (elapsed >= entry.timeoutMs) {
1841
2000
  clearTimeout(entry.pending.timer);
@@ -1854,7 +2013,12 @@ export class RPCTransport {
1854
2013
  if (entry.background) {
1855
2014
  this._pendingBackground.add(entry.rpcId);
1856
2015
  }
1857
- this._sendText(entry.payload, `rpc ${entry.method}`, () => this._pending.get(entry.rpcId) === entry.pending).then(() => {
2016
+ this._sendText(entry.payload, `rpc ${entry.method}`, () => {
2017
+ if (this._pending.get(entry.rpcId) !== entry.pending)
2018
+ return false;
2019
+ this._requestCheck?.(`rpc:${entry.method}`);
2020
+ return true;
2021
+ }, this._isRiskControlMethod(entry.method) ? 3 : entry.priority).then(() => {
1858
2022
  entry.logger.debug(`RPC request sent: method=${entry.method}, id=${entry.rpcId}, background=${entry.background}`);
1859
2023
  return entry.onSent?.();
1860
2024
  }).catch((err) => {
@@ -1862,7 +2026,7 @@ export class RPCTransport {
1862
2026
  return;
1863
2027
  this._removeRpc(entry.rpcId, entry.pending);
1864
2028
  entry.logger.error(`RPC send failed: method=${entry.method}, id=${entry.rpcId}, error=${err instanceof Error ? err.message : String(err)}`);
1865
- entry.pending.reject(err instanceof ConnectionError
2029
+ entry.pending.reject(err instanceof ConnectionError || err instanceof StateError
1866
2030
  ? err
1867
2031
  : new ConnectionError(`failed to send rpc ${entry.method}: ${err instanceof Error ? err.message : String(err)}`));
1868
2032
  this._drainRpcQueue();
@@ -1964,7 +2128,9 @@ export class RPCTransport {
1964
2128
  _startWebSocketHeartbeat(ws) {
1965
2129
  this._stopWebSocketHeartbeat();
1966
2130
  this._heartbeatWs = ws;
2131
+ let failures = 0;
1967
2132
  const onPong = () => {
2133
+ failures = 0;
1968
2134
  if (this._pongTimeout !== null) {
1969
2135
  clearTimeout(this._pongTimeout);
1970
2136
  this._pongTimeout = null;
@@ -1972,6 +2138,7 @@ export class RPCTransport {
1972
2138
  };
1973
2139
  this._pongListener = onPong;
1974
2140
  ws.on('pong', onPong);
2141
+ ws.on('message', onPong);
1975
2142
  const ping = () => {
1976
2143
  if (this._closed || this._ws !== ws || ws.readyState !== WebSocket.OPEN)
1977
2144
  return;
@@ -1981,6 +2148,8 @@ export class RPCTransport {
1981
2148
  this._pongTimeout = null;
1982
2149
  if (this._closed || this._ws !== ws)
1983
2150
  return;
2151
+ if (++failures < 3)
2152
+ return;
1984
2153
  this._logger.warn('WebSocket pong timeout; terminating half-open connection');
1985
2154
  try {
1986
2155
  ws.terminate?.();
@@ -2036,6 +2205,10 @@ export class RPCTransport {
2036
2205
  target.removeListener('pong', this._pongListener);
2037
2206
  }
2038
2207
  catch { /* noop */ }
2208
+ try {
2209
+ target.removeListener('message', this._pongListener);
2210
+ }
2211
+ catch { /* noop */ }
2039
2212
  }
2040
2213
  this._pongListener = null;
2041
2214
  this._heartbeatWs = null;
@@ -2048,6 +2221,14 @@ export class RPCTransport {
2048
2221
  this._logger.debug(`_routeMessage enter: has_id=${hasId}, method=${methodStr || '<none>'}`);
2049
2222
  // RPC 响应(有 id 字段)
2050
2223
  if ('id' in message) {
2224
+ const error = message.error;
2225
+ if (isJsonObject(error) && isJsonObject(error.data) && isJsonObject(error.data.risk_state)) {
2226
+ const states = error.data.risk_state.states;
2227
+ if (Array.isArray(states))
2228
+ for (const state of states)
2229
+ this._receiveRiskControl(state);
2230
+ delete error.data.risk_state;
2231
+ }
2051
2232
  const rpcId = String(message.id);
2052
2233
  const pending = this._pending.get(rpcId);
2053
2234
  if (pending) {
@@ -2061,6 +2242,10 @@ export class RPCTransport {
2061
2242
  return;
2062
2243
  }
2063
2244
  const method = String(message.method ?? '');
2245
+ if (method === 'event/gateway.risk_control' || method === 'gateway.risk_control') {
2246
+ this._receiveRiskControl(message.params);
2247
+ return;
2248
+ }
2064
2249
  // Challenge 消息
2065
2250
  if (method === 'challenge') {
2066
2251
  this._challenge = message;
@@ -2102,6 +2287,8 @@ export class RPCTransport {
2102
2287
  eventLog.info(`[trace=${String(traceObj.trace_id ?? '')}] event_recv event=${sdkEvent}`);
2103
2288
  }
2104
2289
  }
2290
+ if (this._routeClassMessage(sdkEvent, params))
2291
+ return;
2105
2292
  // 发布为 _raw.{event},由 AUNClient 处理后再发布用户可见的事件
2106
2293
  if (sdkEvent.startsWith('app.') || sdkEvent.startsWith('org.member.') || sdkEvent.startsWith('org.lifecycle.')) {
2107
2294
  this._dispatcher.enqueue(sdkEvent, params);
@@ -2115,7 +2302,8 @@ export class RPCTransport {
2115
2302
  if (this._metaObserver !== null && meta !== null && typeof meta === 'object' && !Array.isArray(meta)) {
2116
2303
  this._queueObserver('notification meta_observer', this._metaObserver, meta);
2117
2304
  }
2118
- this._dispatcher.enqueueProtocol('notification', message);
2305
+ const generation = this._connectionGeneration;
2306
+ this._dispatcher.enqueueProtocol('notification', message, method === 'gateway.migrate' ? () => generation === this._connectionGeneration : undefined);
2119
2307
  }
2120
2308
  /** 解码 WebSocket 消息为 JSON 对象 */
2121
2309
  _decodeMessage(raw) {
@@ -2212,6 +2400,8 @@ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
2212
2400
  onDisconnect: () => { },
2213
2401
  });
2214
2402
  workerActor = actor;
2403
+ const riskGate = new RiskController();
2404
+ actor.setRequestCheck((request) => riskGate.check(request));
2215
2405
  actor._onForegroundDrained = () => parentPort.postMessage({
2216
2406
  type: 'foreground_drained', generation: bridgeGeneration(),
2217
2407
  });
@@ -2234,6 +2424,11 @@ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
2234
2424
  parentPort.on('message', async (command) => {
2235
2425
  const id = command.id;
2236
2426
  try {
2427
+ if (command.type === 'risk_release') {
2428
+ if (command.generation === bridgeGeneration())
2429
+ actor['_finishRiskDelivery']();
2430
+ return;
2431
+ }
2237
2432
  if (command.type === 'cancel') {
2238
2433
  const pending = active.get(String(command.targetId ?? ''));
2239
2434
  pending?.cancel?.();
@@ -2241,6 +2436,16 @@ if (!isMainThread && Boolean(workerData?.aunTransportWorker) && parentPort) {
2241
2436
  }
2242
2437
  let result;
2243
2438
  switch (command.type) {
2439
+ case 'risk_snapshot': {
2440
+ const state = command.riskState;
2441
+ const target = state.target;
2442
+ const [keyId, key] = Object.entries(state.signing_keys)[0] ?? [];
2443
+ riskGate.configure({ aid: String(target.aid), device_id: String(target.device_id ?? ''), slot_id: String(target.slot_id ?? ''), connection_id: String(target.connection_id ?? '') }, { key_id: keyId, public_key: Buffer.from(key).toString('base64url'), algorithm: 'ECDSA-P256-SHA256' }, Number(state.server_time_ms));
2444
+ await riskGate.restore(state);
2445
+ riskGate.close();
2446
+ result = null;
2447
+ break;
2448
+ }
2244
2449
  case 'connect': {
2245
2450
  dnsFallback = command.dnsFallback ?? null;
2246
2451
  const request = actor.connect(String(command.url ?? ''));