@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.
- package/CHANGELOG.md +77 -0
- package/_packed_docs/CHANGELOG.md +77 -0
- package/_packed_docs/INDEX.md +37 -14
- package/_packed_docs/KITE_DOCS_GUIDE.md +23 -15
- 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
- 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
- package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +20 -9
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +57 -12
- 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
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +2 -2
- 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
- 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
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +13 -9
- package/_packed_docs/sdk/INDEX.md +23 -13
- 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
- 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
- package/dist/agent-md-changes.d.ts +42 -0
- package/dist/agent-md-changes.js +339 -0
- package/dist/agent-md-changes.js.map +1 -0
- package/dist/agent-md-schema.d.ts +1 -0
- package/dist/agent-md-schema.js +31 -14
- package/dist/agent-md-schema.js.map +1 -1
- package/dist/agent-md.d.ts +11 -0
- package/dist/agent-md.js +91 -15
- package/dist/agent-md.js.map +1 -1
- package/dist/aid-store.d.ts +11 -0
- package/dist/aid-store.js +102 -21
- package/dist/aid-store.js.map +1 -1
- package/dist/aid.js +3 -3
- package/dist/aid.js.map +1 -1
- package/dist/auth.d.ts +10 -0
- package/dist/auth.js +65 -23
- package/dist/auth.js.map +1 -1
- package/dist/cert-utils.d.ts +1 -1
- package/dist/cert-utils.js +4 -4
- package/dist/cert-utils.js.map +1 -1
- package/dist/client/control-messages.d.ts +31 -0
- package/dist/client/control-messages.js +474 -0
- package/dist/client/control-messages.js.map +1 -0
- package/dist/client/delivery.js +10 -2
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/lifecycle.d.ts +1 -1
- package/dist/client/lifecycle.js +10 -0
- package/dist/client/lifecycle.js.map +1 -1
- package/dist/client/rpc-pipeline.js +84 -14
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.d.ts +3 -0
- package/dist/client/v2-e2ee.js +12 -0
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +38 -0
- package/dist/client.js +572 -36
- package/dist/client.js.map +1 -1
- package/dist/discovery.d.ts +3 -0
- package/dist/discovery.js +52 -2
- package/dist/discovery.js.map +1 -1
- package/dist/events.js +14 -1
- package/dist/events.js.map +1 -1
- package/dist/facades.d.ts +38 -0
- package/dist/facades.js +49 -5
- package/dist/facades.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/org-protocol.d.ts +1 -0
- package/dist/org-protocol.js +39 -36
- package/dist/org-protocol.js.map +1 -1
- package/dist/ownership-v21.js +7 -7
- package/dist/ownership-v21.js.map +1 -1
- package/dist/register-flow.js +2 -2
- package/dist/register-flow.js.map +1 -1
- package/dist/risk-control.d.ts +68 -0
- package/dist/risk-control.js +344 -0
- package/dist/risk-control.js.map +1 -0
- package/dist/semantic-facade.d.ts +176 -0
- package/dist/semantic-facade.js +611 -0
- package/dist/semantic-facade.js.map +1 -0
- package/dist/semantic-protocol.d.ts +810 -0
- package/dist/semantic-protocol.js +894 -0
- package/dist/semantic-protocol.js.map +1 -0
- package/dist/storage/lowlevel.d.ts +1 -0
- package/dist/storage/lowlevel.js +2 -2
- package/dist/storage/lowlevel.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +11 -1
- package/dist/tools/cross-sdk-agent.js +388 -7
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/transport.d.ts +22 -1
- package/dist/transport.js +227 -22
- package/dist/transport.js.map +1 -1
- package/dist/v2/e2ee/decrypt.d.ts +5 -0
- package/dist/v2/e2ee/decrypt.js +22 -2
- package/dist/v2/e2ee/decrypt.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/transport.d.ts
CHANGED
|
@@ -56,9 +56,15 @@ export declare class RPCTransport {
|
|
|
56
56
|
private _drainingRpcQueue;
|
|
57
57
|
_onForegroundDrained?: () => void;
|
|
58
58
|
_onRpcResponse?: () => void;
|
|
59
|
-
private
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
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
|
|
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
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
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
|
-
|
|
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}`, () =>
|
|
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.
|
|
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 ?? ''));
|