@agentunion/fastaun-browser 0.3.6 → 0.4.1
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 +24 -0
- package/_packed_docs/AUN_SDK_/351/207/215/346/236/204/345/256/236/346/226/275/350/256/241/345/210/222.md +596 -0
- package/_packed_docs/AUN_SDK_/351/207/215/346/236/204/350/256/276/350/256/241/346/226/271/346/241/210_v3.md +1697 -0
- package/_packed_docs/CHANGELOG.md +24 -0
- package/_packed_docs/INDEX.md +17 -11
- package/_packed_docs/KITE_DOCS_GUIDE.md +11 -10
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +134 -158
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +11 -7
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +98 -119
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +147 -374
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +153 -153
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +168 -1383
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +71 -91
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +76 -63
- package/_packed_docs/sdk/09-custody-api-manual.md +7 -6
- package/_packed_docs/sdk/09-meta-rpc-manual.md +13 -14
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +37 -49
- package/_packed_docs/sdk/INDEX.md +72 -98
- package/_packed_docs/sdk/README.md +85 -266
- package/dist/aid-store.d.ts +125 -0
- package/dist/aid-store.d.ts.map +1 -0
- package/dist/aid-store.js +841 -0
- package/dist/aid-store.js.map +1 -0
- package/dist/aid.d.ts +56 -0
- package/dist/aid.d.ts.map +1 -0
- package/dist/aid.js +112 -0
- package/dist/aid.js.map +1 -0
- package/dist/auth.js +1 -1
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +1630 -1901
- package/dist/cert-utils.d.ts +26 -0
- package/dist/cert-utils.d.ts.map +1 -0
- package/dist/cert-utils.js +221 -0
- package/dist/cert-utils.js.map +1 -0
- package/dist/client.d.ts +89 -60
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +568 -160
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +0 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -2
- package/dist/config.js.map +1 -1
- package/dist/error-codes.d.ts +25 -0
- package/dist/error-codes.d.ts.map +1 -0
- package/dist/error-codes.js +31 -0
- package/dist/error-codes.js.map +1 -0
- package/dist/errors.d.ts +4 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/keystore/index.d.ts +1 -1
- package/dist/keystore/index.d.ts.map +1 -1
- package/dist/result.d.ts +19 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +10 -0
- package/dist/result.js.map +1 -0
- package/dist/transport.d.ts +3 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +16 -1
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +13 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -1
- package/dist/v2/e2ee/encrypt-p2p.js +1 -1
- package/dist/v2/e2ee/encrypt-p2p.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -1
|
@@ -1,52 +1,50 @@
|
|
|
1
|
-
# AUN SDK
|
|
1
|
+
# AUN SDK - 错误处理
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
## 错误类层级
|
|
6
6
|
|
|
7
|
-
```
|
|
7
|
+
```text
|
|
8
8
|
AUNError
|
|
9
|
-
├── ConnectionError
|
|
10
|
-
├── TimeoutError
|
|
11
|
-
├── AuthError
|
|
12
|
-
│ ├── CertificateRevokedError
|
|
13
|
-
│ └── IdentityConflictError
|
|
14
|
-
├── PermissionError
|
|
15
|
-
├── ValidationError
|
|
16
|
-
├── NotFoundError
|
|
17
|
-
├── RateLimitError
|
|
18
|
-
├── VersionConflictError
|
|
19
|
-
├── StateError
|
|
20
|
-
├── SerializationError
|
|
21
|
-
├── SessionError
|
|
22
|
-
├── ClientSignatureError
|
|
9
|
+
├── ConnectionError
|
|
10
|
+
├── TimeoutError
|
|
11
|
+
├── AuthError
|
|
12
|
+
│ ├── CertificateRevokedError
|
|
13
|
+
│ └── IdentityConflictError
|
|
14
|
+
├── PermissionError
|
|
15
|
+
├── ValidationError
|
|
16
|
+
├── NotFoundError
|
|
17
|
+
├── RateLimitError
|
|
18
|
+
├── VersionConflictError
|
|
19
|
+
├── StateError
|
|
20
|
+
├── SerializationError
|
|
21
|
+
├── SessionError
|
|
22
|
+
├── ClientSignatureError
|
|
23
23
|
├── GroupError
|
|
24
|
-
│ ├── GroupNotFoundError # code: -33001
|
|
25
|
-
│ └── GroupStateError # code: -33002/-33003
|
|
26
24
|
└── E2EEError
|
|
27
|
-
├── E2EEDecryptFailedError # P2P 消息解密失败
|
|
28
|
-
├── E2EEDegradedError # E2EE 降级为 long_term_key(无 prekey 可用)
|
|
29
|
-
├── E2EEGroupSecretMissingError # code: -32040,缺少群密钥
|
|
30
|
-
├── E2EEGroupEpochMismatchError # code: -32041,epoch 不匹配
|
|
31
|
-
├── E2EEGroupCommitmentInvalidError # code: -32042,成员承诺验证失败
|
|
32
|
-
├── E2EEGroupNotMemberError # code: -32043,请求者非群成员
|
|
33
|
-
└── E2EEGroupDecryptFailedError # code: -32044,群消息解密失败
|
|
34
25
|
```
|
|
35
26
|
|
|
36
|
-
|
|
27
|
+
`AIDStore` / `AID` 的可失败方法优先返回 Result 字典;`AUNClient.connect()` / `call()` 等会话方法保留抛异常风格。
|
|
28
|
+
|
|
29
|
+
Result 格式:
|
|
37
30
|
|
|
38
31
|
```python
|
|
39
|
-
|
|
32
|
+
loaded = store.load("alice.agentid.pub")
|
|
33
|
+
if not loaded["ok"]:
|
|
34
|
+
print(loaded["error"]["code"], loaded["error"]["message"])
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
异常属性:
|
|
40
38
|
|
|
39
|
+
```python
|
|
41
40
|
try:
|
|
42
|
-
await client.call("
|
|
41
|
+
await client.call("message.send", params)
|
|
43
42
|
except AUNError as e:
|
|
44
|
-
e.code
|
|
45
|
-
e.data # Any,附加数据
|
|
46
|
-
e.retryable # bool,是否可重试
|
|
47
|
-
e.trace_id # str | None,追踪 ID
|
|
43
|
+
print(e.code, e.data, e.retryable, e.trace_id)
|
|
48
44
|
```
|
|
49
45
|
|
|
46
|
+
---
|
|
47
|
+
|
|
50
48
|
## 错误码速查
|
|
51
49
|
|
|
52
50
|
| 范围 | 含义 | 对应异常 |
|
|
@@ -56,24 +54,20 @@ except AUNError as e:
|
|
|
56
54
|
| 4030 / 403 | 权限不足 | `PermissionError` |
|
|
57
55
|
| 4040 / 404 | 资源不存在 | `NotFoundError` |
|
|
58
56
|
| 4290 / 429 | 请求限流 | `RateLimitError` |
|
|
59
|
-
| -32001 / -32003 |
|
|
60
|
-
| -32004 |
|
|
61
|
-
| -32008 |
|
|
57
|
+
| -32001 / -32003 | 认证失败 | `AuthError` |
|
|
58
|
+
| -32004 | 权限不足 | `PermissionError` |
|
|
59
|
+
| -32008 | 资源不存在 | `NotFoundError` |
|
|
62
60
|
| -32009 | 版本冲突 | `VersionConflictError` |
|
|
63
61
|
| -32010 / -32011 / -32013 | 会话错误 | `SessionError` |
|
|
64
|
-
| -32029 |
|
|
62
|
+
| -32029 | 请求限流 | `RateLimitError` |
|
|
65
63
|
| -32600 / -32601 / -32602 | JSON-RPC 参数错误 | `ValidationError` |
|
|
66
|
-
| -32040 |
|
|
67
|
-
| -32041 | 群 epoch 不匹配 | `E2EEGroupEpochMismatchError` |
|
|
68
|
-
| -32042 | 成员承诺验证失败 | `E2EEGroupCommitmentInvalidError` |
|
|
69
|
-
| -32043 | 密钥请求者非群成员 | `E2EEGroupNotMemberError` |
|
|
70
|
-
| -32044 | 群消息解密失败 | `E2EEGroupDecryptFailedError` |
|
|
64
|
+
| -32040 ~ -32044 | E2EE 群组错误 | `E2EEError` 子类 |
|
|
71
65
|
| 4090 | 身份冲突 | `IdentityConflictError` |
|
|
72
66
|
| -32050 | 证书已吊销 | `CertificateRevokedError` |
|
|
73
67
|
| -32051 | 客户端签名验证失败 | `ClientSignatureError` |
|
|
74
|
-
| -33001 |
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
| -33001 ~ -33009 | 群组错误 | `GroupError` 子类 |
|
|
69
|
+
|
|
70
|
+
---
|
|
77
71
|
|
|
78
72
|
## 重试策略
|
|
79
73
|
|
|
@@ -87,82 +81,68 @@ async def send_with_retry(client, params, max_retries=3):
|
|
|
87
81
|
except RateLimitError:
|
|
88
82
|
await asyncio.sleep(2 ** i)
|
|
89
83
|
except AuthError:
|
|
90
|
-
raise
|
|
84
|
+
raise
|
|
91
85
|
except AUNError as e:
|
|
92
86
|
if not e.retryable or i == max_retries - 1:
|
|
93
87
|
raise
|
|
94
88
|
await asyncio.sleep(0.5)
|
|
95
89
|
```
|
|
96
90
|
|
|
91
|
+
---
|
|
92
|
+
|
|
97
93
|
## 常见错误场景
|
|
98
94
|
|
|
99
|
-
###
|
|
95
|
+
### 未加载身份
|
|
100
96
|
|
|
101
97
|
```python
|
|
102
|
-
# ❌ 错误:跳过认证直接操作
|
|
103
98
|
client = AUNClient()
|
|
104
|
-
await client.
|
|
105
|
-
|
|
106
|
-
# ✅ 正确:先认证再操作
|
|
107
|
-
auth = await client.auth.authenticate({"aid": MY_AID})
|
|
108
|
-
await client.connect(auth, {})
|
|
109
|
-
await client.call("message.send", {...})
|
|
99
|
+
await client.connect() # StateError: no_identity
|
|
110
100
|
```
|
|
111
101
|
|
|
112
|
-
|
|
102
|
+
修复方式:
|
|
113
103
|
|
|
114
104
|
```python
|
|
115
|
-
|
|
116
|
-
|
|
105
|
+
loaded = store.load(MY_AID)
|
|
106
|
+
client.load_identity(loaded["data"]["aid"])
|
|
107
|
+
await client.connect({"auto_reconnect": True})
|
|
117
108
|
```
|
|
118
109
|
|
|
119
|
-
###
|
|
110
|
+
### 传入字符串 AID 构造客户端
|
|
120
111
|
|
|
121
112
|
```python
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
# SDK 会抛出此异常,调用方可捕获后等待密钥恢复完成再重试
|
|
125
|
-
# SDK 自动编排:建群后自动 create_epoch;缺密钥时自动发起恢复请求
|
|
126
|
-
|
|
127
|
-
# E2EEGroupDecryptFailedError — 群消息解密失败(密钥不匹配或密文损坏)
|
|
128
|
-
# 协议层定义的错误语义,当前 Python SDK 的部分路径表现为返回 None、拒绝状态或跳过自动解密,不一定抛出对应异常
|
|
129
|
-
|
|
130
|
-
# E2EEGroupEpochMismatchError — 收到的密钥分发 epoch 低于当前 epoch
|
|
131
|
-
# 协议层定义的错误语义,当前 Python SDK 的部分路径表现为返回 None、拒绝状态或跳过自动解密,不一定抛出对应异常
|
|
113
|
+
AUNClient("alice.agentid.pub") # TypeError / ValidationError
|
|
114
|
+
```
|
|
132
115
|
|
|
133
|
-
|
|
134
|
-
# 协议层定义的错误语义,当前 Python SDK 的部分路径表现为返回 None、拒绝状态或跳过自动解密,不一定抛出对应异常
|
|
135
|
-
# 可能原因:中间人篡改、成员列表不一致
|
|
116
|
+
AID 必须来自 `AIDStore.load()`:
|
|
136
117
|
|
|
137
|
-
|
|
138
|
-
|
|
118
|
+
```python
|
|
119
|
+
me = store.load("alice.agentid.pub")["data"]["aid"]
|
|
120
|
+
client = AUNClient(me)
|
|
139
121
|
```
|
|
140
122
|
|
|
141
|
-
###
|
|
123
|
+
### 身份冲突
|
|
142
124
|
|
|
143
125
|
```python
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
await client.auth.register_aid({"aid": "alice.agentid.pub"})
|
|
148
|
-
except IdentityConflictError as e:
|
|
149
|
-
# e.code == 4090
|
|
150
|
-
# 场景 1:AID 已被他人注册(公钥不匹配)→ 换一个 AID
|
|
151
|
-
# 场景 2:本地有身份但服务端无记录 → 清理本地目录后重试
|
|
152
|
-
print(f"身份冲突: {e}")
|
|
126
|
+
registered = await store.register("alice.agentid.pub")
|
|
127
|
+
if not registered["ok"] and registered["error"]["code"] == "IDENTITY_CONFLICT":
|
|
128
|
+
print("AID 已被其他密钥注册,换名或恢复原私钥")
|
|
153
129
|
```
|
|
154
130
|
|
|
155
|
-
|
|
131
|
+
不要通过删除本地 `AIDs/` 目录解决冲突;私钥丢失后无法证明原 AID 所有权。
|
|
156
132
|
|
|
157
133
|
### 连接状态错误
|
|
158
134
|
|
|
159
135
|
```python
|
|
160
|
-
#
|
|
161
|
-
await client.call("message.send", {...}) # → ConnectionError("client is not connected")
|
|
162
|
-
|
|
163
|
-
# ✅ 正确:重新认证并启用自动重连
|
|
164
|
-
auth = await client.auth.authenticate({"aid": MY_AID})
|
|
165
|
-
await client.connect(auth, {
|
|
166
|
-
"auto_reconnect": True,
|
|
167
|
-
})
|
|
136
|
+
await client.call("message.send", params) # 非 ready 状态会抛 ConnectionError / StateError
|
|
168
137
|
```
|
|
138
|
+
|
|
139
|
+
发送前检查:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
if not client.can_send:
|
|
143
|
+
await client.connect({"auto_reconnect": True})
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### E2EE 解密失败
|
|
147
|
+
|
|
148
|
+
P2P 或群消息解密失败通常由 prekey 不匹配、AAD 篡改、密文损坏或群 epoch 不一致引起。SDK 会发布 `message.undecryptable` / `group.message_undecryptable` 事件,应用可记录并继续处理其他消息。
|
|
@@ -1,104 +1,117 @@
|
|
|
1
|
-
# AUN SDK
|
|
1
|
+
# AUN SDK - 最佳实践
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
## 1.
|
|
5
|
+
## 1. 幂等加载身份并连接
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```python
|
|
8
|
+
async def ensure_ready(aid: str) -> AUNClient:
|
|
9
|
+
store = AIDStore(aun_path="~/.aun/myapp", encryption_seed="")
|
|
10
|
+
|
|
11
|
+
loaded = store.load(aid)
|
|
12
|
+
if not loaded["ok"]:
|
|
13
|
+
registered = await store.register(aid)
|
|
14
|
+
if not registered["ok"]:
|
|
15
|
+
raise RuntimeError(registered["error"]["message"])
|
|
16
|
+
loaded = store.load(aid)
|
|
17
|
+
|
|
18
|
+
me = loaded["data"]["aid"]
|
|
19
|
+
client = AUNClient(me, debug=True)
|
|
20
|
+
await client.connect({"slot_id": "main", "auto_reconnect": True})
|
|
21
|
+
return client
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
要点:
|
|
25
|
+
|
|
26
|
+
- 先 `load()`,只有本地身份不存在时才 `register()`。
|
|
27
|
+
- 注册后重新 `load()`,不要把字符串 AID 直接传给 `AUNClient`。
|
|
28
|
+
- 连接前先订阅关键事件,避免漏掉首个状态变更或消息推送。
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 2. 多 AID 管理
|
|
8
33
|
|
|
9
34
|
```python
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
auth = await client.auth.authenticate({"aid": aid})
|
|
17
|
-
await client.connect(auth, {"auto_reconnect": True})
|
|
18
|
-
return aid
|
|
35
|
+
store = AIDStore(aun_path="~/.aun/myapp", encryption_seed="")
|
|
36
|
+
alice = store.load("alice.agentid.pub")["data"]["aid"]
|
|
37
|
+
bob = store.load("bob.agentid.pub")["data"]["aid"]
|
|
38
|
+
|
|
39
|
+
alice_client = AUNClient(alice)
|
|
40
|
+
bob_client = AUNClient(bob)
|
|
19
41
|
```
|
|
20
42
|
|
|
21
|
-
|
|
43
|
+
一个 `aun_path` 可管理多个 AID。不要把 `aun_path` 命名为某个 AID,否则会产生冗余嵌套路径。
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. 安全关闭
|
|
22
48
|
|
|
23
49
|
```python
|
|
24
50
|
async def close_all(*clients: AUNClient):
|
|
25
|
-
for
|
|
51
|
+
for client in clients:
|
|
26
52
|
try:
|
|
27
|
-
await
|
|
53
|
+
await client.close()
|
|
28
54
|
except Exception:
|
|
29
55
|
pass
|
|
30
56
|
```
|
|
31
57
|
|
|
32
|
-
|
|
58
|
+
`close()` 后客户端进入 `closed` 状态。若要复用对象,必须重新 `load_identity(AID对象)`。
|
|
33
59
|
|
|
34
|
-
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 4. E2EE 幂等运行
|
|
35
63
|
|
|
36
64
|
```python
|
|
37
|
-
# 清除旧 prekey 缓存
|
|
38
65
|
sender.e2ee.invalidate_prekey_cache(peer_aid=receiver_aid)
|
|
39
66
|
receiver.e2ee.invalidate_prekey_cache(peer_aid=sender_aid)
|
|
40
67
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
recv_cursor = r.get("latest_seq", 0)
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## 4. 多 AID 管理
|
|
47
|
-
|
|
48
|
-
一个 `aun_path` 可管理多个 AID,每个 AID 数据隔离在 `{aun_path}/AIDs/{aid}/` 下:
|
|
49
|
-
|
|
50
|
-
```python
|
|
51
|
-
# 推荐:用应用名作为 aun_path,多个 AID 共存于同一目录
|
|
52
|
-
client = AUNClient({"aun_path": "~/.aun/myapp"})
|
|
53
|
-
|
|
54
|
-
# 注册不同的 AID,各自数据自动隔离
|
|
55
|
-
await client.auth.register_aid({"aid": "alice.agentid.pub"})
|
|
56
|
-
await client.auth.register_aid({"aid": "bob.agentid.pub"})
|
|
57
|
-
# 数据分别在 ~/.aun/myapp/AIDs/alice.agentid.pub/ 和 bob.agentid.pub/ 下
|
|
68
|
+
cursor = await receiver.call("message.pull", {"after_seq": 0, "limit": 1})
|
|
69
|
+
recv_cursor = cursor.get("latest_seq", 0)
|
|
58
70
|
```
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
## 5. 环境变量驱动配置
|
|
72
|
+
测试和 demo 中建议跳过历史消息,避免旧消息、旧 prekey、旧游标影响当前断言。
|
|
63
73
|
|
|
64
|
-
|
|
65
|
-
import os
|
|
66
|
-
from pathlib import Path
|
|
74
|
+
---
|
|
67
75
|
|
|
68
|
-
|
|
69
|
-
```
|
|
76
|
+
## 5. protected_headers
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
实例级 `protected_headers` 适合放 SDK 版本、运行环境、调用方链路标识等需要签名保护的元数据:
|
|
72
79
|
|
|
73
80
|
```python
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
try:
|
|
77
|
-
await ensure_connected(client, aid)
|
|
78
|
-
# ... 业务逻辑
|
|
79
|
-
finally:
|
|
80
|
-
await client.close()
|
|
81
|
+
client = AUNClient(me, protected_headers={"sdk": "python", "app": "demo"})
|
|
82
|
+
client.set_protected_headers({"sdk": "python", "trace": "abc"})
|
|
81
83
|
```
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
- 协议文档:`../src/aun_core/docs/protocol/`
|
|
86
|
-
- SDK 架构文档:`../src/aun_core/docs/skill/sdk-core/`
|
|
87
|
-
- RPC 方法手册:`../src/aun_core/docs/skill/rpc-manual/`
|
|
88
|
-
- 可运行示例:`../src/aun_core/docs/skill/examples/`
|
|
89
|
-
- GitHub:https://github.com/ModelUnion/aun-sdk-core
|
|
85
|
+
只对 `message.send`、`group.send`、`message.thought.put`、`group.thought.put` 生效。
|
|
90
86
|
|
|
91
87
|
---
|
|
92
88
|
|
|
93
|
-
##
|
|
89
|
+
## 6. Flow Control
|
|
94
90
|
|
|
95
91
|
SDK 内部自动管理 RPC 并发,应用层无需配置:
|
|
96
92
|
|
|
97
93
|
| 机制 | 说明 |
|
|
98
94
|
|------|------|
|
|
99
95
|
| RPC 并发上限 | 全局最多 16 个并发 RPC 请求 |
|
|
100
|
-
| 后台 RPC 限制 |
|
|
101
|
-
| Pull Gate | 同一 namespace/group 的 pull
|
|
102
|
-
| 队列超时 |
|
|
96
|
+
| 后台 RPC 限制 | 后台任务额外限制为 8 个 |
|
|
97
|
+
| Pull Gate | 同一 namespace/group 的 pull 操作自动序列化 |
|
|
98
|
+
| 队列超时 | 排队超过 timeout 抛 `TimeoutError` |
|
|
99
|
+
|
|
100
|
+
应用层保持普通 `await client.call(...)` 即可。
|
|
103
101
|
|
|
104
|
-
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 7. 测试数据保护
|
|
105
|
+
|
|
106
|
+
- 不要删除 `AIDs/` 下的私钥、证书、seed、数据库或 token 文件。
|
|
107
|
+
- 不要并行跑共享同一身份材料的集成 / E2E / 跨域测试。
|
|
108
|
+
- 需要换身份时使用新的 AID 名称,避免制造不可恢复的 key mismatch。
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 参考
|
|
113
|
+
|
|
114
|
+
- 协议文档:`../src/aun_core/docs/protocol/`
|
|
115
|
+
- RPC 方法手册:`09-*-rpc-manual.md`
|
|
116
|
+
- E2EE 说明:[05-E2EE加密通信.md](05-E2EE加密通信.md)
|
|
117
|
+
- API 手册:[06-API手册.md](06-API手册.md)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
AID Custody 是 AUN AP 可选提供的 AID 备份、恢复与跨设备复制服务,不属于 AUN 核心协议强制能力。当前阶段定义两条主流程:通过手机号和验证码上传、下载 AID 证书以及客户端加密后的私钥文件;以及旧设备通过 AID token 授权,新设备凭一次性复制码领取 OTP 加密材料的跨设备复制流程。
|
|
4
4
|
|
|
5
|
-
用户也可以部署自己的 AID 托管服务。只要服务地址发现格式和本手册定义的 HTTP 接口、请求响应语义保持一致,SDK 即可通过
|
|
5
|
+
用户也可以部署自己的 AID 托管服务。只要服务地址发现格式和本手册定义的 HTTP 接口、请求响应语义保持一致,SDK 即可通过 custody 辅助客户端或 well-known 自动发现接入自部署服务。
|
|
6
6
|
|
|
7
7
|
核心原则:
|
|
8
8
|
|
|
@@ -19,8 +19,9 @@ https://aid_custody.{issuer_domain}:{port}
|
|
|
19
19
|
SDK 使用约束:
|
|
20
20
|
|
|
21
21
|
- `custody_url` 不作为 `AUNClient` 构造配置参数传入。
|
|
22
|
-
-
|
|
23
|
-
-
|
|
22
|
+
- Python SDK 不在 `AUNClient` 上挂载 custody namespace;需要时使用独立 custody 辅助客户端或直接按本手册 HTTP API 调用。
|
|
23
|
+
- TS / JS / Go 仍保留历史 custody namespace 兼容层;新代码应避免把 custody 当作 AUNClient 核心会话能力。
|
|
24
|
+
- 可通过 `https://{aid}/.well-known/aun-custody` 自动发现官方托管服务地址,并缓存发现结果。
|
|
24
25
|
|
|
25
26
|
## 手机号验证码备份/恢复时序
|
|
26
27
|
|
|
@@ -94,9 +95,9 @@ SDK 方法:
|
|
|
94
95
|
|
|
95
96
|
| 语言 | 发起复制 | 上传复制材料 | 领取复制材料 |
|
|
96
97
|
|------|----------|--------------|--------------|
|
|
97
|
-
| Python |
|
|
98
|
-
| JS/TS |
|
|
99
|
-
| Go |
|
|
98
|
+
| Python | 独立 custody 辅助客户端或 HTTP API | 独立 custody 辅助客户端或 HTTP API | 独立 custody 辅助客户端或 HTTP API |
|
|
99
|
+
| JS/TS | 历史 custody namespace 兼容层或 HTTP API | 历史 custody namespace 兼容层或 HTTP API | 历史 custody namespace 兼容层或 HTTP API |
|
|
100
|
+
| Go | 历史 custody namespace 兼容层或 HTTP API | 历史 custody namespace 兼容层或 HTTP API | 历史 custody namespace 兼容层或 HTTP API |
|
|
100
101
|
|
|
101
102
|
复制请求:
|
|
102
103
|
|
|
@@ -74,7 +74,7 @@ print(f"模式: {status['mode']}")
|
|
|
74
74
|
|
|
75
75
|
该 RPC 适合已连接客户端查询。首次信任根更新应优先使用公开 HTTP 端点 `GET https://trust.aun.network/.well-known/aun/trust-roots.json`,不可达时可使用 Issuer PKI 泛域名端点 `GET https://pki.{issuer}/trust-root.json` 或 Gateway 镜像 `GET https://gateway.{issuer}/pki/trust-roots.json`。无论来源是 RPC 还是 HTTP,客户端导入前都必须验证 `authority_signature`。
|
|
76
76
|
|
|
77
|
-
Issuer PKI 泛域名服务还必须公开 `GET https://pki.{issuer}/root.crt`,用于下载该 issuer 证书链锚定的 Root CA PEM
|
|
77
|
+
Issuer PKI 泛域名服务还必须公开 `GET https://pki.{issuer}/root.crt`,用于下载该 issuer 证书链锚定的 Root CA PEM。SDK 在 `AIDStore.load()` / `resolve()` 的证书链验证流程中按需更新指定 issuer 的根证书;写入本地信任锚前必须确认该证书指纹存在于已验签的受信根列表中。
|
|
78
78
|
|
|
79
79
|
### 参数
|
|
80
80
|
|
|
@@ -120,23 +120,22 @@ Issuer PKI 泛域名服务还必须公开 `GET https://pki.{issuer}/root.crt`,
|
|
|
120
120
|
### 示例
|
|
121
121
|
|
|
122
122
|
```python
|
|
123
|
-
trust_list = await client.meta.trust_roots
|
|
124
|
-
|
|
123
|
+
trust_list = await client.call("meta.trust_roots", {})
|
|
124
|
+
# 信任根验证、导入和 issuer root 更新由 AIDStore 内部证书链验证流程按需处理。
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
---
|
|
128
128
|
|
|
129
|
-
##
|
|
129
|
+
## SDK 信任根辅助能力
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
以下能力属于 SDK 本地证书链验证流程,不是新的服务端 RPC;底层只在需要时调用 `meta.trust_roots` 或公开 HTTP 端点。
|
|
132
132
|
|
|
133
|
-
|
|
|
133
|
+
| 能力 | 说明 |
|
|
134
134
|
|------|------|
|
|
135
|
-
|
|
|
136
|
-
|
|
|
137
|
-
|
|
|
138
|
-
| `
|
|
139
|
-
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
`update_issuer_root_cert()` 不信任下载来源本身;它必须以已验签的受信根列表为准,确认 `root.crt` 的 SHA-256 指纹已列入 `root_cas` 后才能写入本地信任锚。
|
|
135
|
+
| 下载受信根列表 | 从管理局权威端点、`pki.{issuer}` 或 Gateway 镜像下载 |
|
|
136
|
+
| 验证受信根列表 | 校验结构、签名、证书 CA 约束、有效期和 SHA-256 指纹 |
|
|
137
|
+
| 导入受信根列表 | 验证后写入本地 `trust-roots.json` / `trust-roots.pem` 并刷新缓存 |
|
|
138
|
+
| 下载 issuer root | 从 `https://pki.{issuer}/root.crt` 下载指定 issuer 的 Root CA PEM |
|
|
139
|
+
| 更新 issuer root | 校验证书为自签 Root CA,且指纹存在于已验签受信根列表后导入本地 |
|
|
140
|
+
|
|
141
|
+
更新 issuer root 时不信任下载来源本身;必须以已验签的受信根列表为准,确认 `root.crt` 的 SHA-256 指纹已列入 `root_cas` 后才能写入本地信任锚。
|
|
@@ -1,74 +1,62 @@
|
|
|
1
|
-
# AUN SDK
|
|
1
|
+
# AUN SDK 文档查阅指南
|
|
2
2
|
|
|
3
|
-
AUN SDK
|
|
4
|
-
|
|
5
|
-
行区间格式:`L43-49` 表示用 Read 工具读取时读取第 43 行到 49 行。
|
|
3
|
+
AUN SDK 文档位于 `docs/sdk/`,索引文件 `docs/sdk/INDEX.md` 分三层:Layer 1 地图、Layer 2 主题索引、Layer 3 单篇摘要。按需逐层读取,避免一次性加载整套文档。
|
|
6
4
|
|
|
7
5
|
## SDK 文档定位
|
|
8
6
|
|
|
9
|
-
SDK
|
|
10
|
-
|
|
11
|
-
其他业务操作(消息、群组、存储等)通过 `client.call(method, params)` 调用 RPC 方法,参数和响应格式见 `docs/sdk/09-*-rpc-manual.md`;`message.send` / `message.thought.put` / `group.send` / `group.thought.put` 的业务 payload 共用格式见 `docs/sdk/09-payload-reference.md`。
|
|
12
|
-
|
|
13
|
-
## 渐进式查阅流程
|
|
14
|
-
|
|
15
|
-
### Step 1:只读 Layer 1(L7-34)
|
|
7
|
+
当前 SDK 聚焦三主体模型:
|
|
16
8
|
|
|
17
|
-
|
|
9
|
+
- `AIDStore`:注册、加载、列举、解析和证书运维。
|
|
10
|
+
- `AID`:不可变身份值对象,负责签名、验签和 agent.md 签验。
|
|
11
|
+
- `AUNClient`:认证、连接、状态机、事件和 RPC。
|
|
18
12
|
|
|
19
|
-
|
|
13
|
+
业务操作统一通过 `client.call(method, params)` 调用;消息、群组、存储、meta、stream 的参数见 `09-*-rpc-manual.md`。`message.send`、`message.thought.put`、`group.send`、`group.thought.put` 的业务 payload 见 `09-payload-reference.md`。
|
|
20
14
|
|
|
21
|
-
|
|
15
|
+
## 渐进式查阅流程
|
|
22
16
|
|
|
23
|
-
|
|
17
|
+
### Step 1:读 Layer 1
|
|
24
18
|
|
|
25
|
-
|
|
19
|
+
查看文档地图,能定位目标就直接读目标文档。
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
### Step 2:按主题读 Layer 2
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
常见主题:
|
|
30
24
|
|
|
31
|
-
|
|
25
|
+
- 身份与认证:AIDStore / AID / 注册 / 加载 / 证书
|
|
26
|
+
- 连接与状态:AUNClient / 九态状态机 / Gateway / 重连
|
|
27
|
+
- E2EE:默认加密、ProtectedHeaders、P2P / Group V2
|
|
28
|
+
- RPC 与事件:`client.call()`、`client.on()`、RPC 手册
|
|
29
|
+
- 错误处理:Result、异常、错误码、重试
|
|
32
30
|
|
|
33
|
-
### Step
|
|
31
|
+
### Step 3:读 Layer 3 摘要
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
不确定哪篇文档包含细节时,先看单篇摘要,再打开原文目标章节。
|
|
36
34
|
|
|
37
35
|
## 文档总览
|
|
38
36
|
|
|
39
37
|
| 编号 | 文档 | 定位 |
|
|
40
38
|
|------|------|------|
|
|
41
|
-
| 01 | [快速开始](01-快速开始.md) |
|
|
42
|
-
| 02 | [WebSocket协议](02-WebSocket协议.md) | 握手流程、消息格式、裸 WebSocket
|
|
39
|
+
| 01 | [快速开始](01-快速开始.md) | 安装、三主体模型、最小示例 |
|
|
40
|
+
| 02 | [WebSocket协议](02-WebSocket协议.md) | 握手流程、消息格式、裸 WebSocket |
|
|
43
41
|
| 03 | [核心概念](03-核心概念.md) | AID、状态机、认证、E2EE |
|
|
44
|
-
| 04 | [连接与认证](04-连接与认证.md) |
|
|
45
|
-
| 05 | [E2EE加密通信](05-E2EE加密通信.md) | E2EE
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
| 08 | [最佳实践](08-最佳实践.md) | 幂等、隔离、资源清理 |
|
|
52
|
-
| 10 | [AID托管API手册](10-custody-api-manual.md) | 手机号验证码、证书与加密私钥备份恢复、跨设备复制 |
|
|
53
|
-
| - | [09-payload-reference](09-payload-reference.md) | `message.send` / `message.thought.put` / `group.send` / `group.thought.put` 共用业务负载格式、类型总览、思考内容、交互卡片/action_card_reply、任务事件、附件引用 |
|
|
54
|
-
| - | [多语言SDK使用场景与调用链路对齐审查清单](多语言SDK使用场景与调用链路对齐审查清单.md) | 多语言场景、调用链路、字段对齐、竞态和服务端风险总表 |
|
|
42
|
+
| 04 | [连接与认证](04-连接与认证.md) | AIDStore、连接、网关发现、事件 |
|
|
43
|
+
| 05 | [E2EE加密通信](05-E2EE加密通信.md) | E2EE、ProtectedHeaders、密钥管理 |
|
|
44
|
+
| 06 | [API手册](06-API手册.md) | AIDStore / AID / AUNClient / 事件 / RPC |
|
|
45
|
+
| 07 | [错误处理](07-错误处理.md) | Result、异常、错误码、重试 |
|
|
46
|
+
| 08 | [最佳实践](08-最佳实践.md) | 幂等、多 AID、资源清理、测试数据 |
|
|
47
|
+
| 09 | `09-*-rpc-manual.md` | 各服务 RPC 参数和响应 |
|
|
48
|
+
| 09 | [AID托管API手册](09-custody-api-manual.md) | 可选 custody HTTP 服务 |
|
|
55
49
|
|
|
56
50
|
## 常见查阅场景
|
|
57
51
|
|
|
58
52
|
| 场景 | 推荐路径 |
|
|
59
53
|
|------|----------|
|
|
60
|
-
| 首次使用 SDK | 01-快速开始
|
|
61
|
-
|
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
|
|
|
66
|
-
|
|
|
67
|
-
|
|
|
68
|
-
|
|
|
69
|
-
| 查某个方法的签名 | 06-API手册 |
|
|
70
|
-
| 遇到报错需排查 | 07-错误处理 |
|
|
71
|
-
| 部署前检查 | 08-最佳实践 |
|
|
72
|
-
| AID 证书和加密私钥托管恢复/跨设备复制 | 10-custody-api-manual |
|
|
73
|
-
| 查 RPC 方法参数 | `docs/sdk/*-rpc-manual.md` |
|
|
74
|
-
| 多语言 SDK 功能 gap / 字段和事件对齐 / 失败分支审查 | [多语言SDK使用场景与调用链路对齐审查清单](多语言SDK使用场景与调用链路对齐审查清单.md) |
|
|
54
|
+
| 首次使用 SDK | [01-快速开始](01-快速开始.md) |
|
|
55
|
+
| 理解新构造入口 | [01-快速开始](01-快速开始.md)、[06-API手册](06-API手册.md) |
|
|
56
|
+
| 注册或加载 AID | [04-连接与认证](04-连接与认证.md) |
|
|
57
|
+
| 状态机和重连 | [03-核心概念](03-核心概念.md)、[04-连接与认证](04-连接与认证.md) |
|
|
58
|
+
| 查方法签名 | [06-API手册](06-API手册.md) |
|
|
59
|
+
| 查消息或群组 RPC | 对应 `09-*-rpc-manual.md` |
|
|
60
|
+
| 查 payload 格式 | [09-payload-reference.md](09-payload-reference.md) |
|
|
61
|
+
| 排查错误 | [07-错误处理](07-错误处理.md) |
|
|
62
|
+
| 写测试或 demo | [08-最佳实践](08-最佳实践.md) |
|