@agentunion/fastaun-browser 0.4.2 → 0.4.4
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 +190 -164
- package/_packed_docs/0.4.0_/345/267/256/345/274/202/346/240/270/345/256/236/345/206/263/347/255/226/350/256/260/345/275/225.md +302 -0
- package/_packed_docs/AUN_SDK_0.4.0_/350/256/276/350/256/241/345/257/271/346/257/224/345/210/206/346/236/220.md +194 -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 -596
- 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 +1698 -1697
- package/_packed_docs/CHANGELOG.md +190 -164
- package/_packed_docs/INDEX.md +17 -17
- package/_packed_docs/KITE_DOCS_GUIDE.md +11 -11
- package/_packed_docs/agent.md/SCHEMA.md +49 -49
- package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +22 -22
- package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +327 -327
- package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +686 -686
- package/_packed_docs/design/2026-05-22-aun-rpc-trace-enhancement.md +542 -542
- package/_packed_docs/design/E2EE_V2/347/256/200/345/214/226/344/270/2721DH/345/212/240Per-AID_Wrap/346/226/271/346/241/210.md +124 -124
- package/_packed_docs/design//350/267/250/350/257/255/350/250/200/345/256/271/345/231/250E2E/346/265/213/350/257/225/346/226/271/346/241/210.md +665 -665
- package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +2 -2
- package/_packed_docs/protocol/14-/344/272/244/344/272/222/346/234/272/345/210/266-/345/223/215/345/272/224/346/250/241/345/274/217/344/270/216/350/207/252/344/270/273/346/250/241/345/274/217.md +170 -170
- package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +419 -419
- package/_packed_docs/protocol/README.md +1 -1
- package/_packed_docs/protocol/aun-docs-guide.md +1 -1
- package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +15 -15
- package/_packed_docs/protocol//351/231/204/345/275/225B-/346/211/251/345/261/225/346/200/247/346/214/207/345/215/227.md +4 -4
- package/_packed_docs/protocol//351/231/204/345/275/225J-/345/256/242/346/210/267/347/253/257/346/216/245/345/205/245/347/244/272/344/276/213.md +98 -98
- package/_packed_docs/protocol//351/231/204/345/275/225M-JWT/350/256/244/350/257/201/345/256/236/347/216/260/346/214/207/345/215/227.md +46 -46
- package/_packed_docs/protocol//351/231/204/345/275/225N-/345/210/206/345/270/203/345/274/217Trace/345/215/217/350/256/256.md +257 -257
- package/_packed_docs/python-sdk-v2-only-changelog.md +189 -189
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +7 -3
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +1 -1
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +3 -1
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +1 -1
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +63 -15
- package/_packed_docs/sdk/09-payload-reference.md +13 -13
- package/_packed_docs/sdk/E2EE_V2/346/266/210/346/201/257/351/200/232/344/277/241/346/227/266/345/272/217/345/233/276.md +171 -171
- package/_packed_docs/sdk/README.md +5 -5
- package/dist/aid-store.d.ts.map +1 -1
- package/dist/aid-store.js +5 -6
- package/dist/aid-store.js.map +1 -1
- package/dist/aid.d.ts +2 -1
- package/dist/aid.d.ts.map +1 -1
- package/dist/aid.js +7 -6
- package/dist/aid.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +4 -0
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +292 -188
- package/dist/client.d.ts +13 -17
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +275 -190
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +4 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -1
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/indexeddb.js +5 -5
- package/dist/keystore/indexeddb.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,189 +1,189 @@
|
|
|
1
|
-
# Python SDK V2-Only 改动清单
|
|
2
|
-
|
|
3
|
-
基线:`d8b79f44` (v0.2.20 之后,master_1.0.0 分支)
|
|
4
|
-
日期:2026-05-20
|
|
5
|
-
|
|
6
|
-
## 一、源码改动(`python/src/aun_core/`)
|
|
7
|
-
|
|
8
|
-
### 1. client.py:8588 行 → 4502 行(净删 4086 行)
|
|
9
|
-
|
|
10
|
-
#### 删除的 V1 E2EE 代码(共 ~95 个方法)
|
|
11
|
-
|
|
12
|
-
**V1 P2P 加密:**
|
|
13
|
-
- `_send_encrypted`, `_build_self_sync_copies`, `_build_recipient_device_copies`
|
|
14
|
-
- `_encrypt_copy_payload`, `_ensure_encrypt_result`, `_resolve_self_copy_peer_cert`
|
|
15
|
-
- `_log_e2ee_error`
|
|
16
|
-
|
|
17
|
-
**V1 群组加密:**
|
|
18
|
-
- `_send_group_encrypted`, `_put_group_thought_encrypted`, `_put_message_thought_encrypted`
|
|
19
|
-
- `_call_group_encrypted_rpc`, `_prepare_group_encrypted_rpc_params`
|
|
20
|
-
|
|
21
|
-
**V1 Epoch 管理:**
|
|
22
|
-
- `_recover_group_epoch_key`, `_do_recover_group_epoch_key`, `_try_recover_epoch_key_from_server`
|
|
23
|
-
- `_recover_initial_group_epoch_if_needed`, `_request_group_key_from_candidates`
|
|
24
|
-
- `_request_group_key_from_online`, `_request_group_key_from`
|
|
25
|
-
- `_group_epoch_secret_ready_for_recovery`, `_pending_group_secret_still_current`
|
|
26
|
-
- `_ensure_group_epoch_ready`, `_wait_for_group_membership_epoch_floor`
|
|
27
|
-
- `_committed_group_epoch`, `_committed_group_epoch_state`
|
|
28
|
-
- `_ensure_committed_group_secret_for_send`, `_committed_rotation_membership_gap`
|
|
29
|
-
|
|
30
|
-
**V1 密钥控制面:**
|
|
31
|
-
- `_try_handle_group_key_message`, `_verify_active_group_rotation_distribution`
|
|
32
|
-
- `_verify_group_key_response_epoch`, `_discard_group_distribution_if_stale`
|
|
33
|
-
- `_ack_group_rotation_key`
|
|
34
|
-
|
|
35
|
-
**V1 Epoch 轮换:**
|
|
36
|
-
- `_build_rotation_signature`, `_attach_rotation_id`, `_build_epoch_encrypted_keys`
|
|
37
|
-
- `_distribute_group_epoch_key`, `_heartbeat_group_rotation`, `_abort_group_rotation`
|
|
38
|
-
- `_schedule_group_rotation_retry`, `_sync_epoch_to_server`
|
|
39
|
-
- `_maybe_lead_rotate_group_epoch`, `_ranked_group_rotation_candidates`, `_rotate_group_epoch`
|
|
40
|
-
- `_delayed_rotate_after_join`, `_maybe_backfill_key_to_joined_member`
|
|
41
|
-
- `_distribute_key_to_new_member`, `_start_group_epoch_tasks`
|
|
42
|
-
- `_is_rotation_leader`, `_group_epoch_rotate_loop`, `_group_epoch_cleanup_loop`
|
|
43
|
-
|
|
44
|
-
**V1 解密:**
|
|
45
|
-
- `_decrypt_messages`, `_decrypt_single_message`
|
|
46
|
-
- `_decrypt_group_message`, `_decrypt_group_messages`
|
|
47
|
-
- `_decrypt_group_thoughts`, `_decrypt_message_thoughts`
|
|
48
|
-
|
|
49
|
-
**V1 Pending queue:**
|
|
50
|
-
- `_enqueue_pending_decrypt`, `_schedule_retry_pending_decrypt_msgs`
|
|
51
|
-
- `_retry_pending_decrypt_msgs`, `_schedule_recovery_timeout`, `_cleanup_group_state`
|
|
52
|
-
|
|
53
|
-
**V1 Prekey:**
|
|
54
|
-
- `_upload_prekey`, `_prekey_refresh_loop`, `_start_prekey_refresh_task`
|
|
55
|
-
- `_schedule_prekey_replenish_if_consumed`, `_invalidate_peer_prekey_cache`
|
|
56
|
-
- `_fetch_peer_prekeys`, `_fetch_peer_prekey`, `_normalize_peer_prekeys`
|
|
57
|
-
- `_refresh_peer_prekeys`, `_clear_peer_cert_cache`
|
|
58
|
-
|
|
59
|
-
**V1 错误辅助:**
|
|
60
|
-
- `_is_group_epoch_too_old_error`, `_is_group_epoch_rotation_pending_error`
|
|
61
|
-
- `_is_group_epoch_changed_during_send_error`, `_is_recoverable_group_epoch_error`
|
|
62
|
-
- `_is_expected_group_rotation_skip_error`
|
|
63
|
-
|
|
64
|
-
**V1 成员轮换辅助:**
|
|
65
|
-
- `_membership_rotation_trigger_id`, `_membership_rotation_changed`
|
|
66
|
-
- `_membership_rotation_expected_epoch`, `_extract_group_id_from_result`
|
|
67
|
-
- `_get_group_member_aids`, `_local_group_members_match`, `_extract_group_join_mode`
|
|
68
|
-
- `_group_allows_member_epoch_rotation`, `_group_key_recovery_candidates`
|
|
69
|
-
- `_joined_member_aids_from_payload`
|
|
70
|
-
|
|
71
|
-
**V1 群组推送处理:**
|
|
72
|
-
- `_process_and_publish_group_message`, `_auto_pull_group_messages`, `_fill_group_gap`
|
|
73
|
-
|
|
74
|
-
**V1 公开 API:**
|
|
75
|
-
- `e2ee` property, `group_e2ee` property
|
|
76
|
-
- `send_v2`, `pull_v2`, `ack_v2`, `send_group_v2`, `pull_group_v2`, `ack_group_v2`
|
|
77
|
-
(独立方法合并进 `call()` 路由)
|
|
78
|
-
|
|
79
|
-
#### 删除的 V1 实例变量
|
|
80
|
-
|
|
81
|
-
- `self._e2ee` (E2EEManager)
|
|
82
|
-
- `self._group_e2ee` (GroupE2EEManager)
|
|
83
|
-
- `self._pending_decrypt_msgs`
|
|
84
|
-
- `self._recovery_timeout_scheduled`
|
|
85
|
-
- `self._group_epoch_rotation_inflight`
|
|
86
|
-
- `self._group_epoch_rotation_retry_tasks`
|
|
87
|
-
- `self._group_epoch_recovery_inflight`
|
|
88
|
-
- `self._group_membership_rotation_done`
|
|
89
|
-
- `self._group_member_key_backfill_done`
|
|
90
|
-
|
|
91
|
-
#### 新增/修改的逻辑
|
|
92
|
-
|
|
93
|
-
- `_on_raw_group_message_created`:简化为明文消息透传 + seq 跟踪(不再做 V1 解密)
|
|
94
|
-
- `_process_and_publish_message`:移除 V1 解密调用,明文直接透传
|
|
95
|
-
- `_on_raw_group_changed`:移除 V1 epoch 轮换编排,保留 V2 `_v2_auto_propose_state` + event gap 检测
|
|
96
|
-
- `call()` 中 `message.pull` / `group.pull` 后处理:移除 V1 解密,保留 seq 跟踪 + auto-ack
|
|
97
|
-
- `_stop_background_tasks`:移除 V1 epoch 任务清理
|
|
98
|
-
- `_start_background_tasks`:移除 `_start_group_epoch_tasks()` 调用
|
|
99
|
-
- V2 解密元数据:`e2ee` 字段增加 `encryption_mode` 和 `forward_secrecy`
|
|
100
|
-
- V2 group pull:移除返回值去重(pull 始终返回所有解密成功的消息)
|
|
101
|
-
|
|
102
|
-
### 2. seq_tracker.py:+14 行
|
|
103
|
-
|
|
104
|
-
- `on_pull_result` 新增 `after_seq` 参数
|
|
105
|
-
- gap fill 场景(`after_seq == contiguous_seq`):直接把 pull 到的最大 seq 作为新 `contiguous_seq`,跳过服务端永久空洞
|
|
106
|
-
|
|
107
|
-
### 3. `__init__.py`:无变化(`ProtectedHeaders` 保留)
|
|
108
|
-
|
|
109
|
-
### 4. `e2ee.py`:不动(3544 行保留作为参考)
|
|
110
|
-
|
|
111
|
-
### 5. 保留的 e2ee.py 引用(非 E2EE 加解密)
|
|
112
|
-
|
|
113
|
-
- `from .e2ee import ProtectedHeaders` — 纯数据类,V2 也用
|
|
114
|
-
- `from .e2ee import compute_state_hash` (2处) — 群组 state hash 验证工具函数
|
|
115
|
-
|
|
116
|
-
## 二、测试改动(`python/tests/`)
|
|
117
|
-
|
|
118
|
-
### 删除的测试文件(纯 V1 E2EE)
|
|
119
|
-
|
|
120
|
-
- `e2e_test_epoch_key_server.py` — V1 epoch key 服务端托管
|
|
121
|
-
- `integration_test_e2ee.py` — V1 P2P E2EE 集成
|
|
122
|
-
- `integration_test_multi_device_e2ee.py` — V1 多设备 E2EE
|
|
123
|
-
- `unit/test_client_group_e2ee.py` — V1 群组 E2EE 单元测试(93 个用例)
|
|
124
|
-
|
|
125
|
-
### 删除的测试用例(从现有文件中移除)
|
|
126
|
-
|
|
127
|
-
- `test_client.py`:24 个 V1 测试(prekey、send_encrypted V1、decrypt_group 等)
|
|
128
|
-
- `test_py_issues.py`:`TestPY004PrekeyRefreshLoop`
|
|
129
|
-
- `test_py_issues_batch2.py`:`TestPY001DecryptFailStillAutoAck`、`TestPY002KeyRecoveryRetry`、`TestPY003DissolveCleanup`、`TestPY005RotateLoopLeaderElection`
|
|
130
|
-
- `test_py_issues_batch3.py`:`TestPY002PushedSeqsLimit`、`TestPY005EpochWait`
|
|
131
|
-
|
|
132
|
-
### 修改的测试
|
|
133
|
-
|
|
134
|
-
- `test_client.py`:`test_e2ee_property` 改为断言 `e2ee` 属性不存在
|
|
135
|
-
- `integration_test_storage.py`:自定义 redirect handler 支持 PUT 302 重定向
|
|
136
|
-
|
|
137
|
-
## 三、服务端改动(`extensions/services/`)
|
|
138
|
-
|
|
139
|
-
| 文件 | 改动 |
|
|
140
|
-
|------|------|
|
|
141
|
-
| `gateway/entry.py` | kernel event 订阅补全 V2 事件(fallback);`_handle_event_notification` 路由补全 V2 事件 |
|
|
142
|
-
| `gateway/ws_server.py` | `_dispatch_event_from_service` 白名单补全 `group.state_committed` |
|
|
143
|
-
| `gateway/relay.py` | `_should_forward_event` 补全 `group.state_committed`;`_V2_ONLY_GROUP_METHODS` 补全 `propose_state/confirm_state/get_proposal` |
|
|
144
|
-
| `message/entry.py` | `AUN_DIRECT_EVENT_MESSAGE` 默认改为 True;V2 send 返回 status 对齐 V1 语义(`delivered`/`sent`) |
|
|
145
|
-
| `group/entry.py` | `AUN_DIRECT_EVENT_GROUP` 默认改为 True;`_targets_for_group_event` / `is_client_event` 补全 `group.state_committed`;`_rpc_v2_pull` / `_rpc_v2_ack` 补全成员权限检查 |
|
|
146
|
-
|
|
147
|
-
## 四、Bug 修复(需要其它 SDK 对齐)
|
|
148
|
-
|
|
149
|
-
### BUG-1: gap fill 时 contiguous_seq 卡死
|
|
150
|
-
|
|
151
|
-
**根因:** `on_pull_result` 从 `contiguous_seq` 开始 pull,如果服务端返回的消息跳过了某些 seq(永久空洞:竞态跳跃/未持久化/过期清理),`_try_advance` 逐个检查时会卡在第一个缺失的 seq 上,永远无法推进。新消息被阻塞在 SDK 内部有序队列中,上层收不到。
|
|
152
|
-
|
|
153
|
-
**修复:** `on_pull_result` 新增 `after_seq` 参数。当 `after_seq == contiguous_seq`(gap fill 场景)时,直接把 pull 到的最大 seq 作为新的 `contiguous_seq`。
|
|
154
|
-
|
|
155
|
-
**影响范围:** P2P pull、group pull、event pull 三条路径。
|
|
156
|
-
|
|
157
|
-
### BUG-2: V2 group pull 返回值去重导致手动 pull 拿不到已 push 的消息
|
|
158
|
-
|
|
159
|
-
**根因:** `_pull_group_v2_internal` 中 `_is_published_seq` 去重导致已通过 push 自动 pull 消费的消息在手动 pull 时被跳过,返回空列表。
|
|
160
|
-
|
|
161
|
-
**修复:** pull 返回值不再做 `_is_published_seq` 去重。`_publish_ordered_message` 内部仍做事件投递去重(防止重复触发应用层回调),但 pull 的返回值始终包含所有解密成功的消息。
|
|
162
|
-
|
|
163
|
-
### BUG-3: V2 message.send 返回 status 不对齐 V1 语义
|
|
164
|
-
|
|
165
|
-
**根因:** V2 send 返回 `"status": "accepted"`,但 SDK 和应用层已按 V1 语义(`sent`/`delivered`)实现。
|
|
166
|
-
|
|
167
|
-
**修复:** 服务端 `delivered_count > 0` 时返回 `delivered`,否则返回 `sent`。
|
|
168
|
-
|
|
169
|
-
### BUG-4: V2 解密元数据缺少 encryption_mode
|
|
170
|
-
|
|
171
|
-
**根因:** V2 解密后 `e2ee` 字段只有 `version` + `suite`,缺少 `encryption_mode` 和 `forward_secrecy`,导致依赖这些字段的测试/应用层判断失败。
|
|
172
|
-
|
|
173
|
-
**修复:** 补全 `encryption_mode: "v2_{suite}"` 和 `forward_secrecy: True`。
|
|
174
|
-
|
|
175
|
-
## 五、验证结果
|
|
176
|
-
|
|
177
|
-
| 测试 | 结果 |
|
|
178
|
-
|------|------|
|
|
179
|
-
| 单元测试 | 501 passed |
|
|
180
|
-
| V2 P2P E2EE | 12/12 |
|
|
181
|
-
| V2 Group E2EE | 8/8 |
|
|
182
|
-
| V2 Multi-device | 6/6 |
|
|
183
|
-
| Echo | 5/5 |
|
|
184
|
-
| Message Ack | 4/4 |
|
|
185
|
-
| Storage | 4/4 |
|
|
186
|
-
| 双域明文 | PASS |
|
|
187
|
-
| 双域加密 | PASS |
|
|
188
|
-
| 双域离线 | PASS |
|
|
189
|
-
| 双域群组 | 2/2 |
|
|
1
|
+
# Python SDK V2-Only 改动清单
|
|
2
|
+
|
|
3
|
+
基线:`d8b79f44` (v0.2.20 之后,master_1.0.0 分支)
|
|
4
|
+
日期:2026-05-20
|
|
5
|
+
|
|
6
|
+
## 一、源码改动(`python/src/aun_core/`)
|
|
7
|
+
|
|
8
|
+
### 1. client.py:8588 行 → 4502 行(净删 4086 行)
|
|
9
|
+
|
|
10
|
+
#### 删除的 V1 E2EE 代码(共 ~95 个方法)
|
|
11
|
+
|
|
12
|
+
**V1 P2P 加密:**
|
|
13
|
+
- `_send_encrypted`, `_build_self_sync_copies`, `_build_recipient_device_copies`
|
|
14
|
+
- `_encrypt_copy_payload`, `_ensure_encrypt_result`, `_resolve_self_copy_peer_cert`
|
|
15
|
+
- `_log_e2ee_error`
|
|
16
|
+
|
|
17
|
+
**V1 群组加密:**
|
|
18
|
+
- `_send_group_encrypted`, `_put_group_thought_encrypted`, `_put_message_thought_encrypted`
|
|
19
|
+
- `_call_group_encrypted_rpc`, `_prepare_group_encrypted_rpc_params`
|
|
20
|
+
|
|
21
|
+
**V1 Epoch 管理:**
|
|
22
|
+
- `_recover_group_epoch_key`, `_do_recover_group_epoch_key`, `_try_recover_epoch_key_from_server`
|
|
23
|
+
- `_recover_initial_group_epoch_if_needed`, `_request_group_key_from_candidates`
|
|
24
|
+
- `_request_group_key_from_online`, `_request_group_key_from`
|
|
25
|
+
- `_group_epoch_secret_ready_for_recovery`, `_pending_group_secret_still_current`
|
|
26
|
+
- `_ensure_group_epoch_ready`, `_wait_for_group_membership_epoch_floor`
|
|
27
|
+
- `_committed_group_epoch`, `_committed_group_epoch_state`
|
|
28
|
+
- `_ensure_committed_group_secret_for_send`, `_committed_rotation_membership_gap`
|
|
29
|
+
|
|
30
|
+
**V1 密钥控制面:**
|
|
31
|
+
- `_try_handle_group_key_message`, `_verify_active_group_rotation_distribution`
|
|
32
|
+
- `_verify_group_key_response_epoch`, `_discard_group_distribution_if_stale`
|
|
33
|
+
- `_ack_group_rotation_key`
|
|
34
|
+
|
|
35
|
+
**V1 Epoch 轮换:**
|
|
36
|
+
- `_build_rotation_signature`, `_attach_rotation_id`, `_build_epoch_encrypted_keys`
|
|
37
|
+
- `_distribute_group_epoch_key`, `_heartbeat_group_rotation`, `_abort_group_rotation`
|
|
38
|
+
- `_schedule_group_rotation_retry`, `_sync_epoch_to_server`
|
|
39
|
+
- `_maybe_lead_rotate_group_epoch`, `_ranked_group_rotation_candidates`, `_rotate_group_epoch`
|
|
40
|
+
- `_delayed_rotate_after_join`, `_maybe_backfill_key_to_joined_member`
|
|
41
|
+
- `_distribute_key_to_new_member`, `_start_group_epoch_tasks`
|
|
42
|
+
- `_is_rotation_leader`, `_group_epoch_rotate_loop`, `_group_epoch_cleanup_loop`
|
|
43
|
+
|
|
44
|
+
**V1 解密:**
|
|
45
|
+
- `_decrypt_messages`, `_decrypt_single_message`
|
|
46
|
+
- `_decrypt_group_message`, `_decrypt_group_messages`
|
|
47
|
+
- `_decrypt_group_thoughts`, `_decrypt_message_thoughts`
|
|
48
|
+
|
|
49
|
+
**V1 Pending queue:**
|
|
50
|
+
- `_enqueue_pending_decrypt`, `_schedule_retry_pending_decrypt_msgs`
|
|
51
|
+
- `_retry_pending_decrypt_msgs`, `_schedule_recovery_timeout`, `_cleanup_group_state`
|
|
52
|
+
|
|
53
|
+
**V1 Prekey:**
|
|
54
|
+
- `_upload_prekey`, `_prekey_refresh_loop`, `_start_prekey_refresh_task`
|
|
55
|
+
- `_schedule_prekey_replenish_if_consumed`, `_invalidate_peer_prekey_cache`
|
|
56
|
+
- `_fetch_peer_prekeys`, `_fetch_peer_prekey`, `_normalize_peer_prekeys`
|
|
57
|
+
- `_refresh_peer_prekeys`, `_clear_peer_cert_cache`
|
|
58
|
+
|
|
59
|
+
**V1 错误辅助:**
|
|
60
|
+
- `_is_group_epoch_too_old_error`, `_is_group_epoch_rotation_pending_error`
|
|
61
|
+
- `_is_group_epoch_changed_during_send_error`, `_is_recoverable_group_epoch_error`
|
|
62
|
+
- `_is_expected_group_rotation_skip_error`
|
|
63
|
+
|
|
64
|
+
**V1 成员轮换辅助:**
|
|
65
|
+
- `_membership_rotation_trigger_id`, `_membership_rotation_changed`
|
|
66
|
+
- `_membership_rotation_expected_epoch`, `_extract_group_id_from_result`
|
|
67
|
+
- `_get_group_member_aids`, `_local_group_members_match`, `_extract_group_join_mode`
|
|
68
|
+
- `_group_allows_member_epoch_rotation`, `_group_key_recovery_candidates`
|
|
69
|
+
- `_joined_member_aids_from_payload`
|
|
70
|
+
|
|
71
|
+
**V1 群组推送处理:**
|
|
72
|
+
- `_process_and_publish_group_message`, `_auto_pull_group_messages`, `_fill_group_gap`
|
|
73
|
+
|
|
74
|
+
**V1 公开 API:**
|
|
75
|
+
- `e2ee` property, `group_e2ee` property
|
|
76
|
+
- `send_v2`, `pull_v2`, `ack_v2`, `send_group_v2`, `pull_group_v2`, `ack_group_v2`
|
|
77
|
+
(独立方法合并进 `call()` 路由)
|
|
78
|
+
|
|
79
|
+
#### 删除的 V1 实例变量
|
|
80
|
+
|
|
81
|
+
- `self._e2ee` (E2EEManager)
|
|
82
|
+
- `self._group_e2ee` (GroupE2EEManager)
|
|
83
|
+
- `self._pending_decrypt_msgs`
|
|
84
|
+
- `self._recovery_timeout_scheduled`
|
|
85
|
+
- `self._group_epoch_rotation_inflight`
|
|
86
|
+
- `self._group_epoch_rotation_retry_tasks`
|
|
87
|
+
- `self._group_epoch_recovery_inflight`
|
|
88
|
+
- `self._group_membership_rotation_done`
|
|
89
|
+
- `self._group_member_key_backfill_done`
|
|
90
|
+
|
|
91
|
+
#### 新增/修改的逻辑
|
|
92
|
+
|
|
93
|
+
- `_on_raw_group_message_created`:简化为明文消息透传 + seq 跟踪(不再做 V1 解密)
|
|
94
|
+
- `_process_and_publish_message`:移除 V1 解密调用,明文直接透传
|
|
95
|
+
- `_on_raw_group_changed`:移除 V1 epoch 轮换编排,保留 V2 `_v2_auto_propose_state` + event gap 检测
|
|
96
|
+
- `call()` 中 `message.pull` / `group.pull` 后处理:移除 V1 解密,保留 seq 跟踪 + auto-ack
|
|
97
|
+
- `_stop_background_tasks`:移除 V1 epoch 任务清理
|
|
98
|
+
- `_start_background_tasks`:移除 `_start_group_epoch_tasks()` 调用
|
|
99
|
+
- V2 解密元数据:`e2ee` 字段增加 `encryption_mode` 和 `forward_secrecy`
|
|
100
|
+
- V2 group pull:移除返回值去重(pull 始终返回所有解密成功的消息)
|
|
101
|
+
|
|
102
|
+
### 2. seq_tracker.py:+14 行
|
|
103
|
+
|
|
104
|
+
- `on_pull_result` 新增 `after_seq` 参数
|
|
105
|
+
- gap fill 场景(`after_seq == contiguous_seq`):直接把 pull 到的最大 seq 作为新 `contiguous_seq`,跳过服务端永久空洞
|
|
106
|
+
|
|
107
|
+
### 3. `__init__.py`:无变化(`ProtectedHeaders` 保留)
|
|
108
|
+
|
|
109
|
+
### 4. `e2ee.py`:不动(3544 行保留作为参考)
|
|
110
|
+
|
|
111
|
+
### 5. 保留的 e2ee.py 引用(非 E2EE 加解密)
|
|
112
|
+
|
|
113
|
+
- `from .e2ee import ProtectedHeaders` — 纯数据类,V2 也用
|
|
114
|
+
- `from .e2ee import compute_state_hash` (2处) — 群组 state hash 验证工具函数
|
|
115
|
+
|
|
116
|
+
## 二、测试改动(`python/tests/`)
|
|
117
|
+
|
|
118
|
+
### 删除的测试文件(纯 V1 E2EE)
|
|
119
|
+
|
|
120
|
+
- `e2e_test_epoch_key_server.py` — V1 epoch key 服务端托管
|
|
121
|
+
- `integration_test_e2ee.py` — V1 P2P E2EE 集成
|
|
122
|
+
- `integration_test_multi_device_e2ee.py` — V1 多设备 E2EE
|
|
123
|
+
- `unit/test_client_group_e2ee.py` — V1 群组 E2EE 单元测试(93 个用例)
|
|
124
|
+
|
|
125
|
+
### 删除的测试用例(从现有文件中移除)
|
|
126
|
+
|
|
127
|
+
- `test_client.py`:24 个 V1 测试(prekey、send_encrypted V1、decrypt_group 等)
|
|
128
|
+
- `test_py_issues.py`:`TestPY004PrekeyRefreshLoop`
|
|
129
|
+
- `test_py_issues_batch2.py`:`TestPY001DecryptFailStillAutoAck`、`TestPY002KeyRecoveryRetry`、`TestPY003DissolveCleanup`、`TestPY005RotateLoopLeaderElection`
|
|
130
|
+
- `test_py_issues_batch3.py`:`TestPY002PushedSeqsLimit`、`TestPY005EpochWait`
|
|
131
|
+
|
|
132
|
+
### 修改的测试
|
|
133
|
+
|
|
134
|
+
- `test_client.py`:`test_e2ee_property` 改为断言 `e2ee` 属性不存在
|
|
135
|
+
- `integration_test_storage.py`:自定义 redirect handler 支持 PUT 302 重定向
|
|
136
|
+
|
|
137
|
+
## 三、服务端改动(`extensions/services/`)
|
|
138
|
+
|
|
139
|
+
| 文件 | 改动 |
|
|
140
|
+
|------|------|
|
|
141
|
+
| `gateway/entry.py` | kernel event 订阅补全 V2 事件(fallback);`_handle_event_notification` 路由补全 V2 事件 |
|
|
142
|
+
| `gateway/ws_server.py` | `_dispatch_event_from_service` 白名单补全 `group.state_committed` |
|
|
143
|
+
| `gateway/relay.py` | `_should_forward_event` 补全 `group.state_committed`;`_V2_ONLY_GROUP_METHODS` 补全 `propose_state/confirm_state/get_proposal` |
|
|
144
|
+
| `message/entry.py` | `AUN_DIRECT_EVENT_MESSAGE` 默认改为 True;V2 send 返回 status 对齐 V1 语义(`delivered`/`sent`) |
|
|
145
|
+
| `group/entry.py` | `AUN_DIRECT_EVENT_GROUP` 默认改为 True;`_targets_for_group_event` / `is_client_event` 补全 `group.state_committed`;`_rpc_v2_pull` / `_rpc_v2_ack` 补全成员权限检查 |
|
|
146
|
+
|
|
147
|
+
## 四、Bug 修复(需要其它 SDK 对齐)
|
|
148
|
+
|
|
149
|
+
### BUG-1: gap fill 时 contiguous_seq 卡死
|
|
150
|
+
|
|
151
|
+
**根因:** `on_pull_result` 从 `contiguous_seq` 开始 pull,如果服务端返回的消息跳过了某些 seq(永久空洞:竞态跳跃/未持久化/过期清理),`_try_advance` 逐个检查时会卡在第一个缺失的 seq 上,永远无法推进。新消息被阻塞在 SDK 内部有序队列中,上层收不到。
|
|
152
|
+
|
|
153
|
+
**修复:** `on_pull_result` 新增 `after_seq` 参数。当 `after_seq == contiguous_seq`(gap fill 场景)时,直接把 pull 到的最大 seq 作为新的 `contiguous_seq`。
|
|
154
|
+
|
|
155
|
+
**影响范围:** P2P pull、group pull、event pull 三条路径。
|
|
156
|
+
|
|
157
|
+
### BUG-2: V2 group pull 返回值去重导致手动 pull 拿不到已 push 的消息
|
|
158
|
+
|
|
159
|
+
**根因:** `_pull_group_v2_internal` 中 `_is_published_seq` 去重导致已通过 push 自动 pull 消费的消息在手动 pull 时被跳过,返回空列表。
|
|
160
|
+
|
|
161
|
+
**修复:** pull 返回值不再做 `_is_published_seq` 去重。`_publish_ordered_message` 内部仍做事件投递去重(防止重复触发应用层回调),但 pull 的返回值始终包含所有解密成功的消息。
|
|
162
|
+
|
|
163
|
+
### BUG-3: V2 message.send 返回 status 不对齐 V1 语义
|
|
164
|
+
|
|
165
|
+
**根因:** V2 send 返回 `"status": "accepted"`,但 SDK 和应用层已按 V1 语义(`sent`/`delivered`)实现。
|
|
166
|
+
|
|
167
|
+
**修复:** 服务端 `delivered_count > 0` 时返回 `delivered`,否则返回 `sent`。
|
|
168
|
+
|
|
169
|
+
### BUG-4: V2 解密元数据缺少 encryption_mode
|
|
170
|
+
|
|
171
|
+
**根因:** V2 解密后 `e2ee` 字段只有 `version` + `suite`,缺少 `encryption_mode` 和 `forward_secrecy`,导致依赖这些字段的测试/应用层判断失败。
|
|
172
|
+
|
|
173
|
+
**修复:** 补全 `encryption_mode: "v2_{suite}"` 和 `forward_secrecy: True`。
|
|
174
|
+
|
|
175
|
+
## 五、验证结果
|
|
176
|
+
|
|
177
|
+
| 测试 | 结果 |
|
|
178
|
+
|------|------|
|
|
179
|
+
| 单元测试 | 501 passed |
|
|
180
|
+
| V2 P2P E2EE | 12/12 |
|
|
181
|
+
| V2 Group E2EE | 8/8 |
|
|
182
|
+
| V2 Multi-device | 6/6 |
|
|
183
|
+
| Echo | 5/5 |
|
|
184
|
+
| Message Ack | 4/4 |
|
|
185
|
+
| Storage | 4/4 |
|
|
186
|
+
| 双域明文 | PASS |
|
|
187
|
+
| 双域加密 | PASS |
|
|
188
|
+
| 双域离线 | PASS |
|
|
189
|
+
| 双域群组 | 2/2 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# AUN SDK - 快速开始
|
|
2
2
|
|
|
3
|
-
**版本**: 0.4.
|
|
3
|
+
**版本**: 0.4.4+ | **Python**: >= 3.11
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -110,6 +110,8 @@ store = AIDStore(
|
|
|
110
110
|
encryption_seed="",
|
|
111
111
|
device_id=None,
|
|
112
112
|
slot_id="default",
|
|
113
|
+
verify_ssl=None, # None=自动(AUN_ENV/KITE_ENV=dev/local 时关闭),True/False=强制
|
|
114
|
+
root_ca_path=None, # 私有部署时指定自定义根证书路径,如 "/path/to/ca.crt"
|
|
113
115
|
debug=True,
|
|
114
116
|
)
|
|
115
117
|
```
|
|
@@ -122,12 +124,14 @@ client = AUNClient(identity, debug=True, protected_headers={"sdk": "python"})
|
|
|
122
124
|
await client.connect({"slot_id": "main", "connection_kind": "long"})
|
|
123
125
|
```
|
|
124
126
|
|
|
125
|
-
`verify_ssl`
|
|
127
|
+
`verify_ssl` 在 `AIDStore` 构造时配置,不在 `AUNClient` 中配置。自动模式下 SDK 根据环境变量决定:
|
|
126
128
|
|
|
127
129
|
- `AUN_ENV` 优先,其次 `KITE_ENV`
|
|
128
130
|
- 值为 `development` / `dev` / `local` 时关闭证书校验
|
|
129
131
|
- 其他值或未配置时开启证书校验
|
|
130
132
|
|
|
133
|
+
> **v0.4.2 变更**:`discoveryPort` 已移除,Gateway 地址由 SDK 根据 AID issuer 自动发现。
|
|
134
|
+
|
|
131
135
|
---
|
|
132
136
|
|
|
133
137
|
## 数据目录布局
|
|
@@ -182,7 +186,7 @@ aid, err := store.Load("alice.agentid.pub")
|
|
|
182
186
|
if err != nil {
|
|
183
187
|
return err
|
|
184
188
|
}
|
|
185
|
-
client := aun.NewAUNClient(aid
|
|
189
|
+
client := aun.NewAUNClient(aid.Data.AID)
|
|
186
190
|
```
|
|
187
191
|
|
|
188
192
|
---
|
|
@@ -144,7 +144,7 @@ await client.call("message.send", {
|
|
|
144
144
|
事件通过 `client.on(event, handler)` 订阅:
|
|
145
145
|
|
|
146
146
|
```python
|
|
147
|
-
client.on("
|
|
147
|
+
client.on("state_change", lambda e: print(e["state"]))
|
|
148
148
|
client.on("message.received", lambda e: print(e["payload"]))
|
|
149
149
|
```
|
|
150
150
|
|
|
@@ -50,6 +50,8 @@ store = AIDStore(
|
|
|
50
50
|
| `encryption_seed` | 本地密钥保护种子 |
|
|
51
51
|
| `device_id` | 可选设备 ID;不传时从 `{aun_path}/.device_id` 读取或生成 |
|
|
52
52
|
| `slot_id` | 默认连接槽位 |
|
|
53
|
+
| `verify_ssl` | `None`=自动(`AUN_ENV`/`KITE_ENV` 为 `dev`/`local` 时关闭),`True`/`False`=强制 |
|
|
54
|
+
| `root_ca_path` | 私有部署时指定自定义根证书路径 |
|
|
53
55
|
| `debug` | 是否输出 DEBUG 日志和文件日志 |
|
|
54
56
|
|
|
55
57
|
### 常用方法
|
|
@@ -186,7 +188,7 @@ print(client.can_connect, client.can_send, client.is_online)
|
|
|
186
188
|
|
|
187
189
|
| 事件 | 说明 |
|
|
188
190
|
|------|------|
|
|
189
|
-
| `
|
|
191
|
+
| `state_change` | 状态变化,payload 中的 `state` 是九态公开值 |
|
|
190
192
|
| `connection.error` | 连接、认证、重连错误 |
|
|
191
193
|
| `token.refreshed` | token 自动刷新完成 |
|
|
192
194
|
| `message.received` | 收到消息 |
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
- [RPC 方法参考](#rpc-方法参考)
|
|
13
13
|
- [Stream 使用指南](#stream-使用指南)
|
|
14
14
|
|
|
15
|
+
> **多语言命名约定**:Python 使用 `snake_case`(如 `aun_path`、`fetch_agent_md`),TS/JS 使用 `camelCase`(如 `aunPath`、`fetchAgentMd`),Go 使用 `PascalCase` 公开方法(如 `Load`、`Register`)。本手册表格中各列对应各语言的实际命名。
|
|
16
|
+
|
|
15
17
|
---
|
|
16
18
|
|
|
17
19
|
## AIDStore
|
|
@@ -19,19 +21,40 @@
|
|
|
19
21
|
Python:
|
|
20
22
|
|
|
21
23
|
```python
|
|
22
|
-
store = AIDStore(
|
|
24
|
+
store = AIDStore(
|
|
25
|
+
aun_path: str,
|
|
26
|
+
encryption_seed: str,
|
|
27
|
+
*,
|
|
28
|
+
device_id=None,
|
|
29
|
+
slot_id="default",
|
|
30
|
+
verify_ssl=None, # None=自动(由 AUN_ENV/KITE_ENV 决定),True/False=强制
|
|
31
|
+
root_ca_path=None, # 私有部署时指定自定义根证书路径
|
|
32
|
+
debug=False,
|
|
33
|
+
)
|
|
23
34
|
```
|
|
24
35
|
|
|
25
36
|
TypeScript / JavaScript:
|
|
26
37
|
|
|
27
38
|
```ts
|
|
28
|
-
const store = new AIDStore({
|
|
39
|
+
const store = new AIDStore({
|
|
40
|
+
aunPath, encryptionSeed,
|
|
41
|
+
deviceId, slotId,
|
|
42
|
+
verifySsl, // 同 Python verify_ssl
|
|
43
|
+
rootCaPath, // 同 Python root_ca_path
|
|
44
|
+
debug,
|
|
45
|
+
});
|
|
29
46
|
```
|
|
30
47
|
|
|
31
48
|
Go:
|
|
32
49
|
|
|
33
50
|
```go
|
|
34
51
|
store := aun.NewAIDStore(aunPath, encryptionSeed)
|
|
52
|
+
// 可选配置通过 AIDStoreOptions 传入
|
|
53
|
+
store := aun.NewAIDStore(aunPath, encryptionSeed, aun.AIDStoreOptions{
|
|
54
|
+
VerifySSL: &[]bool{true}[0],
|
|
55
|
+
RootCaPath: "/path/to/ca.crt",
|
|
56
|
+
Debug: true,
|
|
57
|
+
})
|
|
35
58
|
```
|
|
36
59
|
|
|
37
60
|
### 方法
|
|
@@ -42,16 +65,39 @@ store := aun.NewAIDStore(aunPath, encryptionSeed)
|
|
|
42
65
|
| `register(aid)` | `register(aid)` | `Register(ctx, aid)` | 注册并落盘证书和私钥 |
|
|
43
66
|
| `list()` | `list()` | `List()` | 列出本地 AID |
|
|
44
67
|
| `exists(aid)` | `exists(aid)` | `Exists(ctx, aid)` | 远端存在性检查 |
|
|
45
|
-
| `resolve(aid, opts=None)` | `resolve(aid, opts?)` |
|
|
46
|
-
| `fetch_agent_md(aid)` | `fetchAgentMd(aid)` |
|
|
47
|
-
| `head_agent_md(aid)` | `headAgentMd(aid)` |
|
|
48
|
-
| `check_agent_md(aid, ttl_days=1)` | `checkAgentMd(aid, ttlDays?)` |
|
|
49
|
-
| `diagnose(aid)` | `diagnose(aid)` |
|
|
50
|
-
| `renew_cert(aid)` / `rekey(aid)` | `renewCert(aid)` / `rekey(aid)` |
|
|
68
|
+
| `resolve(aid, opts=None)` | `resolve(aid, opts?)` | `Resolve(ctx, aid, opts...)` | 拉证书、缓存、拉 agent.md 并验签;`opts.timeout` / `context.WithTimeout` 控制超时 |
|
|
69
|
+
| `fetch_agent_md(aid, timeout_ms=30000)` | `fetchAgentMd(aid, timeoutMs=30000)` | `FetchAgentMd(ctx, aid)` | 下载 agent.md,返回 `FetchAgentMdResult` / `AgentMDInfo` |
|
|
70
|
+
| `head_agent_md(aid)` | `headAgentMd(aid)` | `HeadAgentMd(ctx, aid)` | HEAD agent.md |
|
|
71
|
+
| `check_agent_md(aid, ttl_days=1)` | `checkAgentMd(aid, ttlDays?)` | `CheckAgentMd(ctx, aid, maxUnsyncedDays...)` | 缓存一致性检查 |
|
|
72
|
+
| `diagnose(aid)` | `diagnose(aid)` | `Diagnose(ctx, aid)` | 本地 + 远端诊断 |
|
|
73
|
+
| `renew_cert(aid)` / `rekey(aid)` | `renewCert(aid)` / `rekey(aid)` | `RenewCert(ctx, aid)` / `Rekey(ctx, aid)` | 证书运维 |
|
|
51
74
|
| `change_seed(old, new)` | `changeSeed(old, new)` | `ChangeSeed(old, new)` | 本地密钥保护种子迁移 |
|
|
52
75
|
|
|
53
76
|
Python / TS / JS 返回 Result 对象;Go 使用惯用 `(value, error)`。
|
|
54
77
|
|
|
78
|
+
### Result 类型
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
# ok=True 时
|
|
82
|
+
{"ok": True, "data": {...}}
|
|
83
|
+
|
|
84
|
+
# ok=False 时
|
|
85
|
+
{"ok": False, "error": {"code": "ERROR_CODE", "message": "..."}}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### FetchAgentMdResult
|
|
89
|
+
|
|
90
|
+
| 字段 | 类型 | 说明 |
|
|
91
|
+
|------|------|------|
|
|
92
|
+
| `aid` | str | AID 字符串 |
|
|
93
|
+
| `content` | str | agent.md 原始内容 |
|
|
94
|
+
| `verification` | `{status, reason?}` | 验签结果;`status` 为 `"ok"` / `"no_cert"` / `"invalid"` 等 |
|
|
95
|
+
| `cert_pem` | str | 签名所用证书 PEM |
|
|
96
|
+
| `etag` | str | HTTP ETag |
|
|
97
|
+
| `last_modified` | str | HTTP Last-Modified |
|
|
98
|
+
|
|
99
|
+
> **v0.4.2 变更**:`discoveryPort` 配置项已移除,Gateway 地址完全由 SDK 根据 AID issuer 自动发现,无需手动指定端口。
|
|
100
|
+
|
|
55
101
|
---
|
|
56
102
|
|
|
57
103
|
## AID
|
|
@@ -72,6 +118,7 @@ AID 由 `AIDStore.load()` 返回,应用层不直接构造。
|
|
|
72
118
|
| `verify_ssl` | `verifySsl` | `VerifySSL` | 是否校验 TLS 证书 |
|
|
73
119
|
| `root_ca_path` | `rootCaPath` | `RootCaPath` | 自定义根证书路径 |
|
|
74
120
|
| `debug` | `debug` | `Debug` | 是否开启调试日志 |
|
|
121
|
+
| `private_key_pem` | `privateKeyPem` | `PrivateKeyPem` | 明文私钥 PEM(由 `AIDStore.load()` 注入,空字符串表示无私钥)|
|
|
75
122
|
|
|
76
123
|
### 方法
|
|
77
124
|
|
|
@@ -94,26 +141,26 @@ Python:
|
|
|
94
141
|
|
|
95
142
|
```python
|
|
96
143
|
client = AUNClient()
|
|
97
|
-
client = AUNClient(aid
|
|
144
|
+
client = AUNClient(aid)
|
|
98
145
|
```
|
|
99
146
|
|
|
100
147
|
TS/JS:
|
|
101
148
|
|
|
102
149
|
```ts
|
|
103
|
-
const client = new AUNClient(
|
|
104
|
-
const client = new AUNClient(aid
|
|
150
|
+
const client = new AUNClient();
|
|
151
|
+
const client = new AUNClient(aid);
|
|
105
152
|
```
|
|
106
153
|
|
|
107
154
|
Go:
|
|
108
155
|
|
|
109
156
|
```go
|
|
110
|
-
client := aun.
|
|
111
|
-
client := aun.NewAUNClient(aid
|
|
157
|
+
client := aun.NewAUNClientEmpty()
|
|
158
|
+
client := aun.NewAUNClient(aid)
|
|
112
159
|
```
|
|
113
160
|
|
|
114
161
|
构造约束:
|
|
115
162
|
|
|
116
|
-
- `aid` 必须是 AID
|
|
163
|
+
- `aid` 必须是 AID 对象(由 `AIDStore.load()` 返回)。
|
|
117
164
|
- 不接受字符串 AID。
|
|
118
165
|
- 不接受把 aid 放进 options。
|
|
119
166
|
- 不接受旧的 `(config, debug)` 或 `(config, true)` 形态。
|
|
@@ -124,6 +171,7 @@ client := aun.NewAUNClient(aid, aun.AUNClientOptions{Debug: true})
|
|
|
124
171
|
|--------|-------|----|------|
|
|
125
172
|
| `load_identity(aid)` | `loadIdentity(aid)` | `LoadIdentityFromAID(aid)` | 在 `no_identity` / `closed` 状态加载身份 |
|
|
126
173
|
| `state` | `state` | `ConnectionState()` | 九态公开状态 |
|
|
174
|
+
| `gateway_url` | `gatewayUrl` | `GetGatewayURL()` | 当前连接的 Gateway URL(只读,自动发现,连接前为空) |
|
|
127
175
|
| `current_aid` | `currentAid` | `CurrentAID()` | 当前 AID 对象 |
|
|
128
176
|
| `aid` | `aid` | `AID()` | 当前 AID 字符串 |
|
|
129
177
|
| `has_identity` | `hasIdentity` | `HasIdentity()` | 是否已加载身份 |
|
|
@@ -214,7 +262,7 @@ sub.unsubscribe()
|
|
|
214
262
|
|
|
215
263
|
| 事件 | 说明 |
|
|
216
264
|
|------|------|
|
|
217
|
-
| `
|
|
265
|
+
| `state_change` | 状态变化,`state` 为九态公开值 |
|
|
218
266
|
| `connection.error` | 连接或重连错误 |
|
|
219
267
|
| `token.refreshed` | token 刷新完成 |
|
|
220
268
|
| `message.received` | 收到 P2P 消息 |
|