@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.
Files changed (75) hide show
  1. package/CHANGELOG.md +24 -0
  2. 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
  3. 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
  4. package/_packed_docs/CHANGELOG.md +24 -0
  5. package/_packed_docs/INDEX.md +17 -11
  6. package/_packed_docs/KITE_DOCS_GUIDE.md +11 -10
  7. package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +134 -158
  8. package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +11 -7
  9. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +98 -119
  10. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +147 -374
  11. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +153 -153
  12. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +168 -1383
  13. package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +71 -91
  14. package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +76 -63
  15. package/_packed_docs/sdk/09-custody-api-manual.md +7 -6
  16. package/_packed_docs/sdk/09-meta-rpc-manual.md +13 -14
  17. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +37 -49
  18. package/_packed_docs/sdk/INDEX.md +72 -98
  19. package/_packed_docs/sdk/README.md +85 -266
  20. package/dist/aid-store.d.ts +125 -0
  21. package/dist/aid-store.d.ts.map +1 -0
  22. package/dist/aid-store.js +841 -0
  23. package/dist/aid-store.js.map +1 -0
  24. package/dist/aid.d.ts +56 -0
  25. package/dist/aid.d.ts.map +1 -0
  26. package/dist/aid.js +112 -0
  27. package/dist/aid.js.map +1 -0
  28. package/dist/auth.js +1 -1
  29. package/dist/auth.js.map +1 -1
  30. package/dist/bundle.js +1630 -1901
  31. package/dist/cert-utils.d.ts +26 -0
  32. package/dist/cert-utils.d.ts.map +1 -0
  33. package/dist/cert-utils.js +221 -0
  34. package/dist/cert-utils.js.map +1 -0
  35. package/dist/client.d.ts +89 -60
  36. package/dist/client.d.ts.map +1 -1
  37. package/dist/client.js +568 -160
  38. package/dist/client.js.map +1 -1
  39. package/dist/config.d.ts +0 -2
  40. package/dist/config.d.ts.map +1 -1
  41. package/dist/config.js +0 -2
  42. package/dist/config.js.map +1 -1
  43. package/dist/error-codes.d.ts +25 -0
  44. package/dist/error-codes.d.ts.map +1 -0
  45. package/dist/error-codes.js +31 -0
  46. package/dist/error-codes.js.map +1 -0
  47. package/dist/errors.d.ts +4 -0
  48. package/dist/errors.d.ts.map +1 -1
  49. package/dist/errors.js +4 -0
  50. package/dist/errors.js.map +1 -1
  51. package/dist/index.d.ts +6 -6
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +5 -5
  54. package/dist/index.js.map +1 -1
  55. package/dist/keystore/index.d.ts +1 -1
  56. package/dist/keystore/index.d.ts.map +1 -1
  57. package/dist/result.d.ts +19 -0
  58. package/dist/result.d.ts.map +1 -0
  59. package/dist/result.js +10 -0
  60. package/dist/result.js.map +1 -0
  61. package/dist/transport.d.ts +3 -0
  62. package/dist/transport.d.ts.map +1 -1
  63. package/dist/transport.js +16 -1
  64. package/dist/transport.js.map +1 -1
  65. package/dist/types.d.ts +13 -2
  66. package/dist/types.d.ts.map +1 -1
  67. package/dist/types.js +22 -0
  68. package/dist/types.js.map +1 -1
  69. package/dist/v2/e2ee/encrypt-p2p.js +1 -1
  70. package/dist/v2/e2ee/encrypt-p2p.js.map +1 -1
  71. package/dist/version.d.ts +2 -0
  72. package/dist/version.d.ts.map +1 -0
  73. package/dist/version.js +5 -0
  74. package/dist/version.js.map +1 -0
  75. package/package.json +2 -1
@@ -6,6 +6,30 @@
6
6
 
7
7
  ---
8
8
 
9
+ ## 0.4.0 — 2026-05-30
10
+
11
+ > **破坏性重构版本。** 与 Python SDK 0.4.0 对齐:身份管理剥离为 `AID` / `AIDStore`;删除 `auth` / `custody` / `meta` 公开命名空间;引入 `Result` 与字符串错误码;连接状态机扩展为 9 态。浏览器环境下 `AID` 创建和签名/验证均为异步。
12
+
13
+ ### Breaking Changes
14
+ - **删除公开命名空间**:移除 `client.auth` / `client.custody` / `client.meta`。身份相关功能迁移到 `AIDStore` 与 `AID`,其余 RPC 走 `client.call()`。
15
+ - **`AID` 创建改为异步**:使用 `await AID.create(...)` 工厂方法(浏览器 Web Crypto API 限制);`sign` / `verify` / `signAgentMd` / `verifyAgentMd` 均为 `async`。
16
+ - **目录约定变更**:`{aun_path}/AgentMDs/` → `{aun_path}/AIDs/`(IndexedDB key 前缀同步变更)。
17
+
18
+ ### Added
19
+ - **`AID` 类**(异步):`AID.create()` 工厂方法;`sign` / `verify` / `signAgentMd` / `verifyAgentMd` 均返回 Promise;`isCertValid` / `isPrivateKeyValid` 同步。
20
+ - **`AIDStore` 类**:离线 `load` / `list` / `exists`,联网 `register` / `resolve` / `fetchAgentMd` / `checkAgentMd` / `diagnose` / `renewCert` / `rekey` / `changeSeed`;存储后端为 IndexedDB。
21
+ - **`Result<T>` 类型**:统一结果类型(`{ ok: true; data: T }` 或 `{ ok: false; error: ErrorInfo }`)。
22
+ - **新增错误类**:`NotFoundError` / `IdentityConflictError` / `E2EEGroupSecretMissingError` / `E2EEGroupEpochMismatchError`。
23
+ - **`ConnectionState` 枚举**:9 态(`NO_IDENTITY` / `STANDBY` / `CONNECTING` / `READY` / `RETRY_BACKOFF` / `RECONNECTING` / `CONNECTION_FAILED` / `CLOSED`)。
24
+ - **实例级 `protected_headers`**:`setProtectedHeaders()` 自动合并到 `message.send` / `group.send` / `*.thought.put`。
25
+ - **重连状态可观测**:`nextRetryAt` / `retryAttempt` / `retryMaxAttempts` / `lastError` / `lastErrorCode` 属性。
26
+ - **导出**:`__version__` 常量、`STATE_TO_PUBLIC` 映射表、`ROOT_CA_PEM` 根证书。
27
+
28
+ ### Removed
29
+ - 删除 `js/src/namespaces/auth.ts`、`js/src/namespaces/custody.ts`、`js/src/namespaces/meta.ts`。
30
+
31
+ ---
32
+
9
33
  ## 0.3.6 — 2026-05-28
10
34
 
11
35
  ### Added
@@ -8,8 +8,9 @@
8
8
 
9
9
  | 文档 | 定位 |
10
10
  | --- | --- |
11
- | [aun测试运行指南](aun测试运行指南.md) | 当前 Docker 单域、双域、多语言 SDK 测试运行命令 |
12
- | [跨语言容器E2E测试方案](design/跨语言容器E2E测试方案.md) | 多语言 SDK 同网同服、test-runner 控制面的跨语言 E2E 方案 |
11
+ | [aun测试运行指南](aun测试运行指南.md) | 当前 Docker 单域、双域、多语言 SDK 测试运行命令 |
12
+ | [AUN SDK 重构修改清单](AUN_SDK_重构修改清单.md) | 本轮 SDK 重构的实际修改点、测试结果和遗留事项 |
13
+ | [跨语言容器E2E测试方案](design/跨语言容器E2E测试方案.md) | 多语言 SDK 同网同服、test-runner 控制面的跨语言 E2E 方案 |
13
14
  | [E2EE V2 简化为 1DH + Per-AID Wrap 方案](design/E2EE_V2简化为1DH加Per-AID_Wrap方案.md) | SDK bootstrap 能力声明 + 服务端 policy 控制 1DH/per-AID wrap 的兼容方案 |
14
15
  | [AUN RPC Trace 增强设计](design/2026-05-22-aun-rpc-trace-enhancement.md) | RPC trace 诊断字段与 enter/exit span 设计 |
15
16
  | [远程 agent.md 缓存与 ETag 透传方案](agent.md/远程agent.md缓存与etag透传方案.md) | 远程 agent.md per-AID 缓存、SQLite 表、消息信封与 RPC 响应 ETag 透传方案 |
@@ -25,8 +26,9 @@
25
26
 
26
27
  ### 测试与 E2E
27
28
 
28
- - 现有测试命令、容器名、单域/双域运行入口 → [aun测试运行指南](aun测试运行指南.md)
29
- - Python / TypeScript / Go / C++ 跨语言容器 E2E、test-runner、test-control API、用例矩阵 → [aun测试运行指南](aun测试运行指南.md)、[跨语言容器E2E测试方案](design/跨语言容器E2E测试方案.md)
29
+ - 现有测试命令、容器名、单域/双域运行入口 → [aun测试运行指南](aun测试运行指南.md)
30
+ - 本轮 SDK 重构阶段进度、修改点和测试结果 [AUN SDK 重构修改清单](AUN_SDK_重构修改清单.md)
31
+ - Python / TypeScript / Go / C++ 跨语言容器 E2E、test-runner、test-control API、用例矩阵 → [aun测试运行指南](aun测试运行指南.md)、[跨语言容器E2E测试方案](design/跨语言容器E2E测试方案.md)
30
32
  - 多语言 SDK 测试缺口与补测清单 → [审查与路线图目录](audit/)
31
33
 
32
34
  ### SDK 使用与协议
@@ -52,13 +54,17 @@
52
54
 
53
55
  ## Layer 3:重点文档摘要
54
56
 
55
- ### aun测试运行指南
56
-
57
- 记录当前 AUN 服务与 SDK 在 Docker 单域、双域环境中的实际测试入口。包含 Python、TypeScript、Go、JavaScript、C++ 五语言测试矩阵,Python / TypeScript / Go / C++ 跨语言容器 E2E 的 69 用例矩阵,覆盖 P2P 明文/E2EE、群聊 pairwise 明文/E2EE,以及四语言 agent 同群的明文/E2EE 矩阵,另包含固定身份目录、容器名、典型命令、浏览器 E2E、C++ Docker 测试、双域 federation 测试和数据保护规则。
58
-
59
- ### 跨语言容器E2E测试方案
60
-
61
- 定义多语言 SDK 同时作为真实客户端运行的目标测试体系。核心模型是每个语言一个客户端容器,全连接同一 AUN server / gateway;业务消息走 AUN,test-runner 通过每个客户端暴露的 test-control HTTP API 编排动作和断言结果。当前单域落地覆盖 Python / TypeScript / Go / C++,浏览器 JavaScript 仍按宿主机 Playwright 运行。
57
+ ### aun测试运行指南
58
+
59
+ 记录当前 AUN 服务与 SDK 在 Docker 单域、双域环境中的实际测试入口。包含 Python、TypeScript、Go、JavaScript、C++ 五语言测试矩阵,Python / TypeScript / Go / C++ 跨语言容器 E2E 的 69 用例矩阵,覆盖 P2P 明文/E2EE、群聊 pairwise 明文/E2EE,以及四语言 agent 同群的明文/E2EE 矩阵,另包含固定身份目录、容器名、典型命令、浏览器 E2E、C++ Docker 测试、双域 federation 测试和数据保护规则。
60
+
61
+ ### AUN SDK 重构修改清单
62
+
63
+ 记录本轮 AUN SDK 重构执行中的阶段进度、实际修改点、测试命令、测试结果和遗留事项。它是实施过程中的工作清单,最终以 SDK 文档和 skill 同步结果为准。
64
+
65
+ ### 跨语言容器E2E测试方案
66
+
67
+ 定义多语言 SDK 同时作为真实客户端运行的目标测试体系。核心模型是每个语言一个客户端容器,全连接同一 AUN server / gateway;业务消息走 AUN,test-runner 通过每个客户端暴露的 test-control HTTP API 编排动作和断言结果。当前单域落地覆盖 Python / TypeScript / Go / C++,浏览器 JavaScript 仍按宿主机 Playwright 运行。
62
68
 
63
69
  ### E2EE V2 简化为 1DH + Per-AID Wrap 方案
64
70
 
@@ -8,18 +8,18 @@ AUN SDK Core 文档在 `docs/` 下。根级索引为 `docs/INDEX.md`,SDK API
8
8
 
9
9
  ### Step 1:先读根级 Layer 1
10
10
 
11
- - `docs/INDEX.md` L7-20:根级文档地图。
11
+ - `docs/INDEX.md` L7-21:根级文档地图。
12
12
 
13
13
  ### Step 2:按主题读根级 Layer 2
14
14
 
15
- - 测试与 E2E:`docs/INDEX.md` L25-29
16
- - SDK 使用与协议:`docs/INDEX.md` L31-36
17
- - 诊断与可观测性:`docs/INDEX.md` L38-42
18
- - E2EE 与跨语言一致性:`docs/INDEX.md` L45-49
15
+ - 测试与 E2E:`docs/INDEX.md` L27-32
16
+ - SDK 使用与协议:`docs/INDEX.md` L34-39
17
+ - 诊断与可观测性:`docs/INDEX.md` L41-45
18
+ - E2EE 与跨语言一致性:`docs/INDEX.md` L47-51
19
19
 
20
20
  ### Step 3:需要判断文档价值时读 Layer 3 摘要
21
21
 
22
- - `docs/INDEX.md` L53-81:重点文档摘要。
22
+ - `docs/INDEX.md` L55-87:重点文档摘要。
23
23
 
24
24
  ### Step 4:再读目标文档章节
25
25
 
@@ -27,10 +27,11 @@ AUN SDK Core 文档在 `docs/` 下。根级索引为 `docs/INDEX.md`,SDK API
27
27
 
28
28
  ## 常见查阅场景
29
29
 
30
- | 场景 | 推荐读取 |
31
- | --- | --- |
32
- | 当前 Docker 单域/双域测试怎么跑 | `docs/aun测试运行指南.md` L5-46、L65-80 |
33
- | 测试环境数据保护规则 | `docs/aun测试运行指南.md` L48-63 |
30
+ | 场景 | 推荐读取 |
31
+ | --- | --- |
32
+ | 当前 Docker 单域/双域测试怎么跑 | `docs/aun测试运行指南.md` L5-46、L65-80 |
33
+ | 本轮 SDK 重构修改清单 | `docs/AUN_SDK_重构修改清单.md` |
34
+ | 测试环境数据保护规则 | `docs/aun测试运行指南.md` L48-63 |
34
35
  | 单域 Docker 测试容器和命令 | `docs/aun测试运行指南.md` L113-533 |
35
36
  | 跨语言容器 E2E 执行方式 | `docs/aun测试运行指南.md` L146-263 |
36
37
  | 双域 federation 测试容器和命令 | `docs/aun测试运行指南.md` L534-714 |
@@ -1,6 +1,6 @@
1
- # AUN SDK Python - 快速开始
1
+ # AUN SDK - 快速开始
2
2
 
3
- **版本**: 0.2.8 | **Python**: >= 3.11
3
+ **版本**: 0.4.0+ | **Python**: >= 3.11
4
4
 
5
5
  ---
6
6
 
@@ -12,128 +12,87 @@ pip install fastaun
12
12
 
13
13
  ---
14
14
 
15
+ ## 核心模型
16
+
17
+ 重构后的 SDK 分为三个主体:
18
+
19
+ | 主体 | 职责 |
20
+ |------|------|
21
+ | `AIDStore` | 管理本地 keystore,负责注册、加载、解析 AID |
22
+ | `AID` | 不可变身份值对象,持有证书和私钥能力 |
23
+ | `AUNClient` | 管理认证、连接、状态机、RPC 和事件 |
24
+
25
+ 构造规则:
26
+
27
+ - `AUNClient()`:无身份客户端,状态为 `no_identity`,随后用 `load_identity(AID对象)` 加载身份。
28
+ - `AUNClient(aid)`:带身份客户端,`aid` 必须是 `AIDStore.load()` 返回的 AID 对象,状态为 `standby`。
29
+ - TS/JS/Go 同构:只允许 `options` 或 `AID对象 + options`;字符串 AID、把 aid 放进 options、旧 `(config, debug)` 都不是公开入口。
30
+
31
+ ---
32
+
15
33
  ## 最小示例
16
34
 
17
35
  ```python
18
- import asyncio, random
36
+ import asyncio
37
+ import random
19
38
  from datetime import datetime
20
- from aun_core import AUNClient
21
- from aun_core.errors import AUNError, ConnectionError, AuthError
39
+
40
+ from aun_core import AIDStore, AUNClient
41
+ from aun_core.errors import AUNError
42
+
43
+ DOMAIN = "agentid.pub"
44
+ ALICE = f"alice-{random.randint(1000, 9999)}.{DOMAIN}"
45
+ BOB = f"bob-{random.randint(1000, 9999)}.{DOMAIN}"
46
+
22
47
 
23
48
  def ts():
24
49
  return datetime.now().strftime("%H:%M:%S.%f")[:-3]
25
50
 
26
- # ── 配置(按需修改)──
27
- DOMAIN = "agentid.pub" # 也支持其它 AP,如 agentcp.io
28
- ALICE = f"alice{random.randint(1000,9999)}.{DOMAIN}"
29
- BOB = f"bob{random.randint(1000,9999)}.{DOMAIN}"
30
-
31
-
32
- async def create_client(aid: str) -> tuple[AUNClient, dict]:
33
- """创建客户端 → 注册 AID → 认证 → 返回 (client, auth)"""
34
- client = AUNClient() # 默认 aun_path: ~/.aun
35
-
36
- # 先检查本地是否已有该 AID 的身份
37
- known = any(item["aid"] == aid for item in client.list_identities())
38
- if not known:
39
- # 不存在则注册
40
- try:
41
- await client.auth.register_aid({"aid": aid})
42
- except AuthError as e:
43
- print(f"[错误] 注册 AID 失败 ({aid}): {e}")
44
- raise
45
- except ConnectionError as e:
46
- print(f"[错误] 网络连接失败: {e}")
47
- raise
48
- except Exception as e:
49
- print(f"[错误] 未知错误: {e}")
50
- raise
51
51
 
52
- try:
53
- auth = await client.auth.authenticate({"aid": aid})
54
- return client, auth
55
- except AuthError as e:
56
- print(f"[错误] 认证失败 ({aid}): {e}")
57
- raise
58
- except ConnectionError as e:
59
- print(f"[错误] 网络连接失败: {e}")
60
- raise
52
+ async def load_or_register(store: AIDStore, aid: str):
53
+ loaded = store.load(aid)
54
+ if loaded["ok"]:
55
+ return loaded["data"]["aid"]
56
+
57
+ registered = await store.register(aid)
58
+ if not registered["ok"]:
59
+ raise RuntimeError(registered["error"]["message"])
60
+
61
+ loaded = store.load(aid)
62
+ if not loaded["ok"]:
63
+ raise RuntimeError(loaded["error"]["message"])
64
+ return loaded["data"]["aid"]
65
+
66
+
67
+ async def create_client(aid: str) -> AUNClient:
68
+ store = AIDStore(aun_path="~/.aun/myapp", encryption_seed="")
69
+ identity = await load_or_register(store, aid)
70
+ client = AUNClient(identity, debug=True)
71
+ await client.connect({"slot_id": "main", "auto_reconnect": True})
72
+ return client
61
73
 
62
74
 
63
75
  async def main():
64
- alice = None
65
- bob = None
76
+ alice = await create_client(ALICE)
77
+ bob = await create_client(BOB)
78
+
79
+ received = asyncio.Event()
80
+ bob.on("message.received", lambda e: (print(f"[{ts()}] Bob 收到: {e['payload']}"), received.set()))
81
+
82
+ await alice.call("message.send", {
83
+ "to": BOB,
84
+ "payload": {"type": "text", "text": "Hello from Alice!"},
85
+ })
66
86
 
67
87
  try:
68
- # 1. 创建两个客户端
69
- alice, alice_auth = await create_client(ALICE)
70
- bob, bob_auth = await create_client(BOB)
71
-
72
- # 2. Bob 订阅消息事件
73
- received = asyncio.Event()
74
- def on_bob_message(event):
75
- print(f"[{ts()}] [Bob 收到] {event['payload']}")
76
- received.set()
77
-
78
- bob.on("message.received", on_bob_message)
79
-
80
- # 3. 双方连接到网关
81
- try:
82
- await alice.connect(alice_auth, {})
83
- await bob.connect(bob_auth, {})
84
- print(f"[{ts()}] Alice ({ALICE}) 已连接")
85
- print(f"[{ts()}] Bob ({BOB}) 已连接")
86
- except ConnectionError as e:
87
- print(f"[错误] 连接网关失败: {e}")
88
- raise
89
-
90
- # 4. Alice 发消息给 Bob
91
- try:
92
- result = await alice.call("message.send", {
93
- "to": BOB,
94
- "payload": {"type": "text", "text": "Hello from Alice!"},
95
- })
96
- print(f"[{ts()}] [Alice 发送] {result}")
97
- except AUNError as e:
98
- print(f"[错误] 发送消息失败: {e}")
99
- raise
100
-
101
- # 5. 等待 Bob 收到消息(最多 5 秒)
102
- try:
103
- await asyncio.wait_for(received.wait(), timeout=5.0)
104
- except asyncio.TimeoutError:
105
- # 事件推送未触发,尝试主动拉取
106
- try:
107
- pull = await bob.call("message.pull", {"after_seq": 0, "limit": 10})
108
- msgs = pull.get("messages", [])
109
- if msgs:
110
- print(f"[{ts()}] [Bob 拉取] 收到 {len(msgs)} 条消息:")
111
- for m in msgs:
112
- print(f" {m.get('payload')}")
113
- else:
114
- print(f"[{ts()}] [Bob] 未收到消息")
115
- except AUNError as e:
116
- print(f"[错误] 拉取消息失败: {e}")
117
-
118
- print(f"[{ts()}] 完成")
119
-
120
- except KeyboardInterrupt:
121
- print(f"\n[{ts()}] 用户中断")
122
- except Exception as e:
123
- print(f"[{ts()}] 程序异常: {e}")
124
- raise
125
- finally:
126
- # 6. 关闭连接
127
- if alice:
128
- try:
129
- await alice.close()
130
- except Exception:
131
- pass
132
- if bob:
133
- try:
134
- await bob.close()
135
- except Exception:
136
- pass
88
+ await asyncio.wait_for(received.wait(), timeout=5)
89
+ except asyncio.TimeoutError:
90
+ pull = await bob.call("message.pull", {"after_seq": 0, "limit": 10})
91
+ for msg in pull.get("messages", []):
92
+ print(f"[{ts()}] Bob 拉取: {msg.get('payload')}")
93
+
94
+ await alice.close()
95
+ await bob.close()
137
96
 
138
97
 
139
98
  asyncio.run(main())
@@ -143,81 +102,98 @@ asyncio.run(main())
143
102
 
144
103
  ## 配置
145
104
 
146
- ### 构造参数
105
+ `AIDStore` 持有本地数据目录和密钥保护配置:
106
+
107
+ ```python
108
+ store = AIDStore(
109
+ aun_path="~/.aun/myapp",
110
+ encryption_seed="",
111
+ device_id=None,
112
+ slot_id="default",
113
+ debug=True,
114
+ )
115
+ ```
116
+
117
+ `AUNClient` 只接收 AID 对象和连接级选项:
147
118
 
148
119
  ```python
149
- client = AUNClient({
150
- "aun_path": "~/.aun/myapp", # 应用级数据目录(AID 数据在其下的 AIDs/{aid}/ 中)
151
- "root_ca_path": "/path/to/ca.pem", # 额外 Root CA(可选)
152
- "seed_password": "seed", # 本地存储保护口令(可选)
153
- })
120
+ identity = store.load("alice.agentid.pub")["data"]["aid"]
121
+ client = AUNClient(identity, debug=True, protected_headers={"sdk": "python"})
122
+ await client.connect({"slot_id": "main", "connection_kind": "long"})
154
123
  ```
155
124
 
156
- `verify_ssl` 不在构造参数中配置。Python / TS / Go SDK 会根据环境变量自动决定:
125
+ `verify_ssl` 不在 `AUNClient` 构造参数中配置。Python / TS / Go SDK 会根据环境变量自动决定:
157
126
 
158
127
  - `AUN_ENV` 优先,其次 `KITE_ENV`
159
128
  - 值为 `development` / `dev` / `local` 时关闭证书校验
160
129
  - 其他值或未配置时开启证书校验
161
130
 
162
- > **默认行为**:SDK 默认启用 P2P E2EE;Group E2EE 为必选能力并固定启用。`message.send` 和 `group.send` 默认加密发送,`group.thought.put` 强制加密发送;如需发送明文普通消息,显式传入 `encrypt=False`。`slot_id` 和 `delivery_mode` 只在 `connect(...)` 阶段传入。
163
-
164
- 完整参数列表见 [API 手册](06-API手册.md)。
131
+ ---
165
132
 
166
- ### 数据目录布局
133
+ ## 数据目录布局
167
134
 
168
135
  SDK 使用 `{aun_path}/AIDs/{aid}/` 存储每个 AID 的专属数据:
169
136
 
170
- ```
171
- {aun_path}/ # 应用级数据根目录
172
- ├── .device_id # 设备级稳定标识(默认写在 ~/.aun/.device_id)
173
- └── AIDs/ # AID 数据根
174
- ├── alice.agentid.pub/ # Alice 的全部数据
175
- │ ├── private/key.json # ECDSA 私钥(加密保护)
176
- │ ├── public/cert.pem # X.509 证书
177
- │ └── tokens/meta.json # 令牌 + E2EE 密钥 + 元数据
178
- └── bob.agentid.pub/ # Bob 的全部数据(多 AID 共存)
137
+ ```text
138
+ {aun_path}/
139
+ ├── .device_id
140
+ └── AIDs/
141
+ ├── alice.agentid.pub/
142
+ │ ├── private/key.json
143
+ │ ├── public/cert.pem
144
+ │ └── tokens/meta.json
145
+ └── bob.agentid.pub/
179
146
  ├── private/key.json
180
147
  ├── public/cert.pem
181
148
  └── tokens/meta.json
182
149
  ```
183
150
 
184
- **路径模型要点**:
151
+ 要点:
185
152
 
186
- - **`aun_path`** 是应用级目录,不是 AID 级目录。一个 `aun_path` 下可管理多个 AID
187
- - **`aun_path` 不要用 AID 命名**(如 `~/.aun/{aid}`),否则会产生 `~/.aun/{aid}/AIDs/{aid}/` 的冗余嵌套
188
- - 默认路径为 `~/.aun`
189
- - 推荐用应用名或用途命名:`~/.aun/myapp`、`~/.aun/testing`
153
+ - `aun_path` 是应用级目录,一个目录可管理多个 AID
154
+ - 不要用 AID 名称作为 `aun_path`,避免出现 `~/.aun/{aid}/AIDs/{aid}/` 冗余嵌套。
155
+ - 私钥、令牌、群密钥等敏感数据由 SDK 的本地保护机制保存,不应手工删除或迁移单个文件。
190
156
 
191
- ### connect 阶段的多实例参数
157
+ ---
192
158
 
193
- ```python
194
- await client.connect(auth, {
195
- "slot_id": "slot-a",
196
- "delivery_mode": {
197
- "mode": "queue",
198
- "routing": "sender_affinity",
199
- "affinity_ttl_ms": 300000,
200
- },
201
- })
159
+ ## 多语言构造示例
160
+
161
+ TypeScript / Node:
162
+
163
+ ```ts
164
+ const store = new AIDStore({ aunPath: "~/.aun/myapp", encryptionSeed: "" });
165
+ const loaded = store.load("alice.agentid.pub");
166
+ const client = new AUNClient(loaded.data!.aid, { debug: true });
167
+ ```
168
+
169
+ JavaScript / 浏览器:
170
+
171
+ ```js
172
+ const store = new AIDStore({ aunPath: "browser-demo", encryptionSeed: "" });
173
+ const loaded = await store.load("alice.agentid.pub");
174
+ const client = new AUNClient(loaded.data.aid, { debug: true });
202
175
  ```
203
176
 
204
- - `slot_id` 由应用层传入;空字符串表示该设备只运行一个实例
205
- - `delivery_mode` 只在 `connect(...)` 传入;同一 AID 的所有在线实例必须保持一致
177
+ Go:
206
178
 
207
- **敏感数据保护**:`private/key.json` 和 `tokens/meta.json` 中的私钥、令牌、群密钥等敏感字段不以明文存储,而是通过平台密钥链(Windows DPAPI / macOS Keychain / Linux libsecret)加密保护。
179
+ ```go
180
+ store := aun.NewAIDStore("~/.aun/myapp", "")
181
+ aid, err := store.Load("alice.agentid.pub")
182
+ if err != nil {
183
+ return err
184
+ }
185
+ client := aun.NewAUNClient(aid, aun.AUNClientOptions{Debug: true})
186
+ ```
208
187
 
209
188
  ---
210
189
 
211
190
  ## 核心流程
212
191
 
213
- 完整的使用流程见上方"最小示例",核心步骤:
214
-
215
- 1. **创建客户端** - `AUNClient(config)`
216
- 2. **注册 AID** - `check_aid()` → `register_aid()`
217
- 3. **认证** - `authenticate()` 获取令牌
218
- 4. **订阅事件** - `on("message.received", handler)`
219
- 5. **连接** - `connect(auth, options)`
220
- 6. **业务操作** - `call("message.send", params)`
221
- 7. **关闭** - `close()`
192
+ 1. 创建 `AIDStore`。
193
+ 2. `store.load(aid)` 加载本地 AID;本地不存在时调用 `store.register(aid)` 后再次加载。
194
+ 3. AID 对象构造 `AUNClient(aid, ...)`,或先 `AUNClient()` 再 `load_identity(aid)`。
195
+ 4. 先注册事件处理器,再调用 `connect(options)`。
196
+ 5. 通过 `call(method, params)` 执行业务 RPC。
197
+ 6. 通过 `close()` 释放连接和后台任务。
222
198
 
223
- 详细 API 说明见 [06-API手册.md](06-API手册.md),RPC 方法参数见各领域的 RPC 手册。
199
+ 详细 API [06-API手册.md](06-API手册.md),RPC 参数见各领域的 `09-*-rpc-manual.md`。
@@ -185,7 +185,7 @@ sequenceDiagram
185
185
  ```python
186
186
  import asyncio, json, random, secrets
187
187
  from datetime import datetime
188
- from aun_core import AUNClient
188
+ from aun_core import AIDStore, AUNClient
189
189
  from aun_core.errors import AUNError, ConnectionError, AuthError
190
190
  import websockets
191
191
 
@@ -206,13 +206,17 @@ def make_rpc(method: str, params: dict) -> tuple[str, str]:
206
206
 
207
207
 
208
208
  async def authenticate(aid: str) -> dict:
209
- """用 SDK 完成 AID 创建和认证,返回 auth 结果(含 access_token + gateway"""
209
+ """用 SDK 完成 AID 注册/加载和认证,返回 access_token + gateway"""
210
210
  try:
211
- client = AUNClient({"aun_path": f"~/.aun/{aid}"})
212
- if not client._auth.load_identity_or_none(aid):
213
- await client.auth.register_aid({"aid": aid})
214
- auth = await client.auth.authenticate({"aid": aid})
215
- return auth
211
+ store = AIDStore(aun_path="~/.aun/ws-demo", encryption_seed="")
212
+ loaded = store.load(aid)
213
+ if not loaded["ok"]:
214
+ registered = await store.register(aid)
215
+ if not registered["ok"]:
216
+ raise AuthError(registered["error"]["message"])
217
+ loaded = store.load(aid)
218
+ client = AUNClient(loaded["data"]["aid"])
219
+ return await client.authenticate()
216
220
  except AuthError as e:
217
221
  print(f"[错误] 认证失败 ({aid}): {e}")
218
222
  raise