@agentunion/fastaun-browser 0.3.6 → 0.4.0
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/_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 +1633 -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 +163 -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 +64 -0
- package/dist/aid-store.d.ts.map +1 -0
- package/dist/aid-store.js +855 -0
- package/dist/aid-store.js.map +1 -0
- package/dist/aid.d.ts +50 -0
- package/dist/aid.d.ts.map +1 -0
- package/dist/aid.js +106 -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 +1626 -1885
- 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 +558 -154
- package/dist/client.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 +1 -1
|
@@ -1,469 +1,242 @@
|
|
|
1
|
-
# AUN SDK
|
|
1
|
+
# AUN SDK - 连接与认证
|
|
2
2
|
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 当前公开流程
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
重构后,注册、身份加载、会话连接分离:
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```python
|
|
10
|
+
store = AIDStore(aun_path="~/.aun/myapp", encryption_seed="")
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
loaded = store.load(aid)
|
|
13
|
+
if not loaded["ok"]:
|
|
14
|
+
registered = await store.register(aid)
|
|
15
|
+
if not registered["ok"]:
|
|
16
|
+
raise RuntimeError(registered["error"]["message"])
|
|
17
|
+
loaded = store.load(aid)
|
|
12
18
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
await client.connect(auth, {}) # 3. 连接
|
|
19
|
+
me = loaded["data"]["aid"]
|
|
20
|
+
client = AUNClient(me, debug=True)
|
|
21
|
+
await client.connect({"slot_id": "main", "auto_reconnect": True})
|
|
17
22
|
```
|
|
18
23
|
|
|
19
|
-
|
|
24
|
+
关键约束:
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
- `AIDStore.register(aid)` 只负责生成本地密钥、申请证书并落盘。
|
|
27
|
+
- `AIDStore.load(aid)` 返回 AID 值对象;AID 对象加载后不可变。
|
|
28
|
+
- `AUNClient` 只接收 AID 对象,不接收字符串 AID 或配置字典里的 `aid` 字段。
|
|
29
|
+
- `connect(options)` 内部会按需认证、建立 WebSocket、初始化 E2EE 和后台任务。
|
|
22
30
|
|
|
23
|
-
|
|
31
|
+
---
|
|
24
32
|
|
|
25
|
-
|
|
26
|
-
# 加载身份(不存在时抛 StateError)
|
|
27
|
-
identity = client.auth.load_identity({"aid": aid})
|
|
33
|
+
## AIDStore
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
identity = client.auth.load_identity_or_none({"aid": aid})
|
|
35
|
+
### 构造
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
```python
|
|
38
|
+
store = AIDStore(
|
|
39
|
+
aun_path="~/.aun/myapp",
|
|
40
|
+
encryption_seed="",
|
|
41
|
+
device_id=None,
|
|
42
|
+
slot_id="default",
|
|
43
|
+
debug=True,
|
|
44
|
+
)
|
|
34
45
|
```
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
| 参数 | 说明 |
|
|
48
|
+
|------|------|
|
|
49
|
+
| `aun_path` | 应用级数据目录 |
|
|
50
|
+
| `encryption_seed` | 本地密钥保护种子 |
|
|
51
|
+
| `device_id` | 可选设备 ID;不传时从 `{aun_path}/.device_id` 读取或生成 |
|
|
52
|
+
| `slot_id` | 默认连接槽位 |
|
|
53
|
+
| `debug` | 是否输出 DEBUG 日志和文件日志 |
|
|
37
54
|
|
|
38
|
-
|
|
39
|
-
|---|---|
|
|
40
|
-
| `create_aid()` | `register_aid()`(已移除 `create_aid`) |
|
|
41
|
-
| `authenticate()` 自动注册 | 必须先显式调用 `register_aid()` |
|
|
55
|
+
### 常用方法
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
| 方法 | 说明 |
|
|
58
|
+
|------|------|
|
|
59
|
+
| `load(aid)` | 从本地加载 AID,返回 Result |
|
|
60
|
+
| `register(aid)` | 注册新 AID,返回 Result |
|
|
61
|
+
| `list()` | 列出本地身份 |
|
|
62
|
+
| `exists(aid)` | HEAD PKI 端点,判断 AID 是否已注册 |
|
|
63
|
+
| `resolve(aid, opts=None)` | 拉取并缓存对端证书和 agent.md |
|
|
64
|
+
| `fetch_agent_md(aid)` | 下载并验签对端 agent.md |
|
|
65
|
+
| `check_agent_md(aid, ttl_days=1)` | 检查本地缓存与远端 agent.md 状态 |
|
|
66
|
+
| `diagnose(aid)` | 本地和远端一致性诊断 |
|
|
67
|
+
| `renew_cert(aid)` / `rekey(aid)` | 证书续签和换钥,成功后重新 `load()` |
|
|
44
68
|
|
|
45
|
-
|
|
69
|
+
Result 使用方式:
|
|
46
70
|
|
|
47
71
|
```python
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
client = AUNClient() # 默认 aun_path: ~/.aun
|
|
52
|
-
|
|
53
|
-
# 注册 AID
|
|
54
|
-
try:
|
|
55
|
-
result = await client.auth.register_aid({"aid": aid})
|
|
56
|
-
# result: {"aid": ..., "cert_pem": ..., "gateway": ...}
|
|
57
|
-
except Exception as e:
|
|
58
|
-
print(f"注册 AID 失败: {e}")
|
|
59
|
-
raise
|
|
60
|
-
|
|
61
|
-
auth = await client.auth.authenticate({"aid": aid})
|
|
62
|
-
# auth: {"aid": ..., "access_token": ..., "refresh_token": ...,
|
|
63
|
-
# "expires_at": ..., "gateway": ...}
|
|
64
|
-
return client, auth
|
|
72
|
+
result = await store.exists("alice.agentid.pub")
|
|
73
|
+
if result["ok"] and not result["data"]["exists"]:
|
|
74
|
+
await store.register("alice.agentid.pub")
|
|
65
75
|
```
|
|
66
76
|
|
|
67
77
|
---
|
|
68
78
|
|
|
69
|
-
##
|
|
70
|
-
|
|
71
|
-
**必须先调用 `client.auth.authenticate()` 获取令牌和网关地址,再调用 `connect()`,此步骤不可跳过。** `authenticate()` 返回的 `gateway` 字段即为网关 WebSocket 地址。
|
|
72
|
-
|
|
73
|
-
> 当前各语言 SDK 的稳定连接模式都是 Gateway。协议层虽然定义了 Peer / Relay,但 Python SDK 的 `connect(topology=...)` 目前会对 `peer` / `relay` 明确返回未实现。
|
|
79
|
+
## AUNClient
|
|
74
80
|
|
|
75
|
-
###
|
|
81
|
+
### 构造与身份加载
|
|
76
82
|
|
|
77
83
|
```python
|
|
78
|
-
#
|
|
79
|
-
|
|
80
|
-
# auth["access_token"] — 访问令牌
|
|
81
|
-
# auth["gateway"] — 网关 WebSocket 地址
|
|
84
|
+
client = AUNClient() # no_identity
|
|
85
|
+
client.load_identity(me) # standby
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
await client.connect(auth, {})
|
|
87
|
+
client = AUNClient(me) # standby
|
|
85
88
|
```
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
`load_identity()` 只允许在 `no_identity` 或 `closed` 状态调用;传入对象必须是私钥有效的 AID。
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
# 以下为可选覆盖值;不传时默认 auto_reconnect=true、heartbeat_interval=30、
|
|
91
|
-
# token_refresh_before=60、retry.initial_delay=1.0、retry.max_delay=64.0、
|
|
92
|
-
# timeouts={connect:5, call:10, http:30}
|
|
93
|
-
await client.connect(auth, {
|
|
94
|
-
"auto_reconnect": True, # 断线自动重连
|
|
95
|
-
"heartbeat_interval": 30.0, # 心跳间隔(秒)
|
|
96
|
-
"token_refresh_before": 60.0, # 令牌刷新提前量(秒)
|
|
97
|
-
"connection_kind": "long", # 可选,"long"(默认)或 "short"
|
|
98
|
-
"short_ttl_ms": 30000, # 可选,仅 kind=short 时有效,服务端兜底超时
|
|
99
|
-
"retry": {
|
|
100
|
-
"initial_delay": 1.0, # 初始退避延迟
|
|
101
|
-
"max_delay": 64.0, # 最大退避延迟
|
|
102
|
-
},
|
|
103
|
-
"timeouts": {
|
|
104
|
-
"connect": 5.0, # WebSocket 连接超时
|
|
105
|
-
"call": 10.0, # RPC 调用超时
|
|
106
|
-
"http": 30.0, # HTTP 请求超时
|
|
107
|
-
},
|
|
108
|
-
})
|
|
109
|
-
```
|
|
92
|
+
### 显式认证
|
|
110
93
|
|
|
111
|
-
|
|
94
|
+
通常不需要单独调用认证,`connect()` 会自动完成。需要提前获取 token 或检查认证链路时可调用:
|
|
112
95
|
|
|
113
|
-
|
|
96
|
+
```python
|
|
97
|
+
auth = await client.authenticate()
|
|
98
|
+
print(auth["access_token"], auth["gateway"])
|
|
99
|
+
```
|
|
114
100
|
|
|
115
|
-
|
|
101
|
+
认证成功后状态进入 `authenticated`,随后调用 `connect()` 建立会话。
|
|
116
102
|
|
|
117
|
-
|
|
103
|
+
### 连接
|
|
118
104
|
|
|
119
105
|
```python
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
client = AUNClient({"aun_path": "/home/alice/.aun/alice"})
|
|
123
|
-
# 首次:走完整 login + discovery;之后:复用 keystore 里的 cached token + gateway_url
|
|
124
|
-
auth = await client.auth.authenticate({"aid": "alice.example.com"})
|
|
125
|
-
await client.connect(auth, {
|
|
126
|
-
"connection_kind": "long", # 默认值,可省略
|
|
106
|
+
await client.connect({
|
|
127
107
|
"slot_id": "main",
|
|
108
|
+
"connection_kind": "long",
|
|
128
109
|
"auto_reconnect": True,
|
|
110
|
+
"heartbeat_interval": 30.0,
|
|
111
|
+
"token_refresh_before": 60.0,
|
|
112
|
+
"retry": {
|
|
113
|
+
"initial_delay": 1.0,
|
|
114
|
+
"max_delay": 64.0,
|
|
115
|
+
},
|
|
116
|
+
"timeouts": {
|
|
117
|
+
"connect": 5.0,
|
|
118
|
+
"call": 10.0,
|
|
119
|
+
"http": 30.0,
|
|
120
|
+
},
|
|
129
121
|
})
|
|
130
|
-
|
|
131
|
-
# 监听消息推送
|
|
132
|
-
client.on("message.received", lambda data: print(data["payload"]))
|
|
133
|
-
|
|
134
|
-
# 常驻
|
|
135
|
-
await asyncio.Event().wait()
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
#### 短连接(CLI 工具:发完即退)
|
|
139
|
-
|
|
140
|
-
```python
|
|
141
|
-
from aun_core import AUNClient
|
|
142
|
-
|
|
143
|
-
# 关键:使用与长连接守护进程相同的 aun_path → 共享 keystore → 自动复用 token
|
|
144
|
-
client = AUNClient({"aun_path": "/home/alice/.aun/alice"})
|
|
145
|
-
|
|
146
|
-
# authenticate 自动从 keystore 读 cached access_token,跳过两阶段 login
|
|
147
|
-
auth = await client.auth.authenticate({"aid": "alice.example.com"})
|
|
148
|
-
|
|
149
|
-
# connect 时声明 short kind + 同 slot_id(与长连接共存于同一槽位)
|
|
150
|
-
await client.connect(auth, {
|
|
151
|
-
"connection_kind": "short",
|
|
152
|
-
"slot_id": "main", # 与长连接同 slot
|
|
153
|
-
"short_ttl_ms": 30000, # 服务端兜底超时(防 CLI 异常退出占名额)
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
# 发 RPC,响应原路返回到这条短连接
|
|
157
|
-
result = await client.call("message.send", {
|
|
158
|
-
"to": "bob.example.com",
|
|
159
|
-
"payload": {"type": "text", "text": "hello"},
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
# 短连接发完立即关闭(不影响长连接守护进程)
|
|
163
|
-
await client.close()
|
|
164
122
|
```
|
|
165
123
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
`
|
|
124
|
+
| 选项 | 说明 |
|
|
125
|
+
|------|------|
|
|
126
|
+
| `slot_id` | 同一设备内的实例槽位 |
|
|
127
|
+
| `connection_kind` | `"long"` 或 `"short"` |
|
|
128
|
+
| `short_ttl_ms` | 短连接服务端兜底超时 |
|
|
129
|
+
| `delivery_mode` | 连接级投递语义 |
|
|
130
|
+
| `auto_reconnect` | 断线后是否自动重连 |
|
|
131
|
+
| `heartbeat_interval` | 心跳间隔,秒 |
|
|
132
|
+
| `token_refresh_before` | token 过期前刷新提前量,秒 |
|
|
133
|
+
| `retry.initial_delay` / `retry.max_delay` | 退避重连参数 |
|
|
134
|
+
| `timeouts.connect/call/http` | 连接、RPC、HTTP 超时 |
|
|
176
135
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
token 过期或 refresh 失败时,SDK 自动 fallback:cached_token → refresh_token → 完整两阶段 login,应用层无感。
|
|
180
|
-
|
|
181
|
-
#### 三种典型场景
|
|
182
|
-
|
|
183
|
-
| 场景 | aun_path | connection_kind | slot_id |
|
|
184
|
-
|---|---|---|---|
|
|
185
|
-
| 守护进程常驻接收 | `/home/alice/.aun/alice` | `"long"` | `"main"` |
|
|
186
|
-
| CLI 工具发消息 | `/home/alice/.aun/alice`(同上) | `"short"` | `"main"`(同上) |
|
|
187
|
-
| 多实例独立运行 | `/home/alice/.aun/instance-N`(不同) | `"long"` | 自定义 |
|
|
188
|
-
|
|
189
|
-
> 跨语言用法:TS / JS 用 `connectionKind` / `slotId`(camelCase),Go 用 `ConnectionKind` / `SlotID`(PascalCase),其余语义一致。
|
|
190
|
-
|
|
191
|
-
### 查看状态
|
|
192
|
-
|
|
193
|
-
```python
|
|
194
|
-
print(client.state) # "connected"
|
|
195
|
-
print(client.aid) # "alice.agentid.pub"
|
|
196
|
-
```
|
|
136
|
+
当前稳定实现为 Gateway 模式;Peer / Relay 仍是协议能力定义,SDK 连接层会明确返回未实现。
|
|
197
137
|
|
|
198
138
|
---
|
|
199
139
|
|
|
200
|
-
##
|
|
201
|
-
|
|
202
|
-
`register_aid()` / `authenticate()` 内部会自动发现 Gateway。
|
|
203
|
-
|
|
204
|
-
- 生产配置(`verify_ssl=true`)下,优先尝试 `https://{aid}/.well-known/aun-gateway`
|
|
205
|
-
- 若失败,则回退到 `https://gateway.{issuer}/.well-known/aun-gateway`
|
|
206
|
-
- 开发配置(`verify_ssl=false`)下,为兼容未启用泛域名的环境,尝试顺序相反
|
|
207
|
-
|
|
208
|
-
发现到的 Gateway URL 会缓存在客户端内部,后续 `connect()` 默认复用。
|
|
140
|
+
## 长短连接共存
|
|
209
141
|
|
|
210
|
-
|
|
142
|
+
同一 `(aid, device_id, slot_id)` 槽位下允许 1 条长连接 + 最多 10 条短连接。
|
|
211
143
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
当发送消息到不同 Issuer 的 AID 时(如 `alice.aid.pub` 发送给 `bob.example.com`),调用方式对用户保持一致:
|
|
215
|
-
|
|
216
|
-
1. 应用层仍通过当前 Gateway 会话调用 `message.send`
|
|
217
|
-
2. 需要对端证书/预密钥时,SDK 会根据目标 AID 的 issuer 派生或发现目标 Gateway 的 HTTP 端点
|
|
218
|
-
3. 真正的跨域消息路由由 Gateway / Federation 服务端链路完成,而不是由 SDK 为每个目标额外建立一个远端 WebSocket 会话
|
|
219
|
-
|
|
220
|
-
**对用户完全透明**,无需额外配置。跨域消息和本域消息使用相同的 API:
|
|
144
|
+
长连接:
|
|
221
145
|
|
|
222
146
|
```python
|
|
223
|
-
|
|
224
|
-
await
|
|
225
|
-
|
|
226
|
-
# 跨域消息(自动路由)
|
|
227
|
-
await client.call("message.send", {"to": "charlie.example.com", ...})
|
|
147
|
+
daemon = AUNClient(me)
|
|
148
|
+
await daemon.connect({"connection_kind": "long", "slot_id": "main"})
|
|
149
|
+
daemon.on("message.received", lambda e: print(e["payload"]))
|
|
228
150
|
```
|
|
229
151
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
---
|
|
233
|
-
|
|
234
|
-
## Agent Web / agent.md
|
|
235
|
-
|
|
236
|
-
Name Service 同时提供面向 Agent Web 的标准 HTTP 资源:
|
|
237
|
-
|
|
238
|
-
- `PUT https://{aid}/agent.md`
|
|
239
|
-
需要 `Authorization: Bearer <access_token>`,用于上传或覆盖当前 AID 的公开 `agent.md`
|
|
240
|
-
- `GET https://{aid}/agent.md`
|
|
241
|
-
匿名下载指定 AID 的 `agent.md`
|
|
242
|
-
- `HEAD https://{aid}/agent.md`
|
|
243
|
-
匿名查询是否存在,并获取 `ETag`、`Last-Modified`、`Cache-Control`
|
|
244
|
-
|
|
245
|
-
### 推荐主 API(自 v0.x 起)
|
|
246
|
-
|
|
247
|
-
SDK 在 `AUNClient` 上提供三个一站式主方法,分别封装"发布"、"下载"、"一致性检查"三条主线。文件统一存放在 `{aun_path}/AgentMDs/{aid}/agent.md`,由 SDK 管理;元数据持久化到 `agent_md_cache` 表 / `agentmd.json`。
|
|
152
|
+
短连接:
|
|
248
153
|
|
|
249
154
|
```python
|
|
250
|
-
|
|
251
|
-
await
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
state = await client.check_agent_md("bob.agentid.pub", max_unsynced_days=3)
|
|
255
|
-
|
|
256
|
-
# 下载并自动验签(自动写到 SDK 管理的目录)
|
|
257
|
-
if state["remote_found"] and not state["in_sync"]:
|
|
258
|
-
info = await client.fetch_agent_md("bob.agentid.pub")
|
|
259
|
-
print(info["signature"]["status"], info["in_sync"], info["saved_to"])
|
|
155
|
+
cli = AUNClient(me)
|
|
156
|
+
await cli.connect({"connection_kind": "short", "slot_id": "main", "short_ttl_ms": 30000})
|
|
157
|
+
await cli.call("message.send", {"to": peer, "payload": {"type": "text", "text": "hello"}})
|
|
158
|
+
await cli.close()
|
|
260
159
|
```
|
|
261
160
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
| SDK | publish | fetch | check |
|
|
265
|
-
|------|---------|-------|-------|
|
|
266
|
-
| Python | `client.publish_agent_md()` | `client.fetch_agent_md(aid?)` | `client.check_agent_md(aid?, max_unsynced_days=0)` |
|
|
267
|
-
| TypeScript(Node) | `client.publishAgentMd()` | `client.fetchAgentMd(aid?)` | `client.checkAgentMd(aid?, maxUnsyncedDays=0)` |
|
|
268
|
-
| Go | `client.PublishAgentMD(ctx)` | `client.FetchAgentMD(ctx, aid)` | `client.CheckAgentMD(ctx, aid, maxUnsyncedDays...)` |
|
|
269
|
-
| C++ | `client.PublishAgentMd(out)` | `client.FetchAgentMd(aid, out)` | `client.CheckAgentMd(aid, max_days, out)` |
|
|
270
|
-
| JavaScript(浏览器) | `client.publishAgentMd(content?)` | `client.fetchAgentMd(aid?)` | `client.checkAgentMd(aid?, maxUnsyncedDays=0)` |
|
|
271
|
-
|
|
272
|
-
> **`check_agent_md` 不主动下载**:仅当远程存在且本地从未保存过该 aid 时,SDK 才异步触发后台 fetch;其他场景由应用层根据返回值决定是否调 `fetch_agent_md`。
|
|
273
|
-
|
|
274
|
-
### Deprecated(保留代码、未来版本将移除)
|
|
275
|
-
|
|
276
|
-
| 旧方法 | 推荐替代 |
|
|
277
|
-
|--------|----------|
|
|
278
|
-
| `client.auth.sign_agent_md` | `client.publish_agent_md` 内部已包含 |
|
|
279
|
-
| `client.auth.verify_agent_md` | `client.fetch_agent_md` 内部已包含 |
|
|
280
|
-
| `client.auth.upload_agent_md` | `client.publish_agent_md` |
|
|
281
|
-
| `client.auth.download_agent_md` | `client.fetch_agent_md` |
|
|
282
|
-
| `client.auth.head_agent_md` | `client.check_agent_md`(带缓存窗口) |
|
|
283
|
-
|
|
284
|
-
底层方法仅推荐用于离线签名 / 纯文本验签等特殊场景。
|
|
161
|
+
同一个 `AIDStore` / `aun_path` 下的 token、gateway、证书和 E2EE 材料会被复用。
|
|
285
162
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
### Gateway 多 AID etag 推送(v0.x+)
|
|
289
|
-
|
|
290
|
-
Gateway 在 RPC response 和事件通知的 `_meta` 中**最多同时注入两个 AID** 的 agent.md 元数据,每个条目都带 `aid` 字段:
|
|
291
|
-
|
|
292
|
-
- **requester**:调用者 / 事件订阅方(自身)
|
|
293
|
-
- **peer**:RPC 对端 / 事件源(仅当 `peer_aid != requester_aid` 时注入;否则该条目省略)
|
|
294
|
-
|
|
295
|
-
```json
|
|
296
|
-
{
|
|
297
|
-
"_meta": {
|
|
298
|
-
"agent_md_etag": "\"requester-etag\"",
|
|
299
|
-
"agent_md_etags": {
|
|
300
|
-
"requester": {"aid": "alice.agentid.pub", "etag": "\"...\"", "last_modified": "..."},
|
|
301
|
-
"peer": {"aid": "bob.agentid.pub", "etag": "\"...\"", "last_modified": "..."}
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
```
|
|
163
|
+
---
|
|
306
164
|
|
|
307
|
-
|
|
308
|
-
|------|-----------|------|
|
|
309
|
-
| RPC response | 调用者 | RPC 涉及的 `to_aid`(不等于调用者时) |
|
|
310
|
-
| 事件通知 | 订阅方 | 事件源(存在且不等于订阅方时) |
|
|
165
|
+
## 网关发现
|
|
311
166
|
|
|
312
|
-
|
|
167
|
+
注册、解析和认证会根据 AID 的 issuer 自动发现 Gateway:
|
|
313
168
|
|
|
314
|
-
|
|
169
|
+
- 生产模式:优先 `https://{aid}/.well-known/aun-gateway`,失败后回退到 `https://gateway.{issuer}/.well-known/aun-gateway`
|
|
170
|
+
- 开发模式:优先 `gateway.{issuer}`,兼容没有泛域名的本地环境
|
|
315
171
|
|
|
316
|
-
|
|
172
|
+
`verify_ssl` 由 `AUN_ENV` / `KITE_ENV` 控制。`development`、`dev`、`local` 会关闭校验,其余情况开启。
|
|
317
173
|
|
|
318
|
-
|
|
319
|
-
- `GET/HEAD /agent.md` 在目标尚未发布时返回 `404`
|
|
320
|
-
- 主 API 在上述场景抛对应异常(NotFoundError / AUNError 等)
|
|
174
|
+
发现成功后,SDK 会基于 WebSocket URL 推导 `/health` 地址,并通过 `gateway_health` 读取最近健康检查结果。
|
|
321
175
|
|
|
322
176
|
---
|
|
323
177
|
|
|
324
|
-
##
|
|
325
|
-
|
|
326
|
-
### `client.call(method, params)` — 通用 RPC 接口
|
|
327
|
-
|
|
328
|
-
认证连接后,所有业务操作通过 `client.call()` 调用服务端 RPC 方法:
|
|
178
|
+
## 状态与事件
|
|
329
179
|
|
|
330
180
|
```python
|
|
331
|
-
|
|
181
|
+
print(client.state)
|
|
182
|
+
print(client.can_connect, client.can_send, client.is_online)
|
|
332
183
|
```
|
|
333
184
|
|
|
334
|
-
|
|
185
|
+
常用事件:
|
|
335
186
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
# 拉取消息
|
|
345
|
-
result = await client.call("message.pull", {"after_seq": 0, "limit": 20})
|
|
346
|
-
print(result) # {"messages": [...], "count": 5, "latest_seq": 128}
|
|
187
|
+
| 事件 | 说明 |
|
|
188
|
+
|------|------|
|
|
189
|
+
| `connection.state` | 状态变化,payload 中的 `state` 是九态公开值 |
|
|
190
|
+
| `connection.error` | 连接、认证、重连错误 |
|
|
191
|
+
| `token.refreshed` | token 自动刷新完成 |
|
|
192
|
+
| `message.received` | 收到消息 |
|
|
193
|
+
| `group.changed` | 群组事件 |
|
|
194
|
+
| `message.undecryptable` / `group.message_undecryptable` | E2EE 解密失败 |
|
|
347
195
|
|
|
348
|
-
|
|
349
|
-
result = await client.call("group.create", {
|
|
350
|
-
"name": "项目组",
|
|
351
|
-
"members": ["bob.agentid.pub", "carol.agentid.pub"],
|
|
352
|
-
})
|
|
353
|
-
print(result) # {"group_id": "...", "created_at": ...}
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
**错误处理:**
|
|
357
|
-
|
|
358
|
-
```python
|
|
359
|
-
from aun_core import AUNError, NotFoundError, RateLimitError
|
|
360
|
-
|
|
361
|
-
try:
|
|
362
|
-
result = await client.call("message.send", {...})
|
|
363
|
-
except NotFoundError as e:
|
|
364
|
-
print(f"目标不存在: {e.code}")
|
|
365
|
-
except RateLimitError as e:
|
|
366
|
-
print(f"请求限流,{e.data['retry_after']}秒后重试")
|
|
367
|
-
except AUNError as e:
|
|
368
|
-
print(f"RPC 错误: code={e.code}, retryable={e.retryable}")
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
**RPC 方法完整参数和响应格式见 RPC 手册:**
|
|
372
|
-
|
|
373
|
-
| 领域 | 手册 | 涵盖方法 |
|
|
374
|
-
|------|------|----------|
|
|
375
|
-
| 消息 | [09-message-rpc-manual.md](09-message-rpc-manual.md) | message.send / pull / ack / recall / thought.put / thought.get |
|
|
376
|
-
| 群组 | [09-group-rpc-manual.md](09-group-rpc-manual.md) | 群组生命周期、成员管理、群设置、群消息、群 thought |
|
|
377
|
-
| 存储 | [09-storage-rpc-manual.md](09-storage-rpc-manual.md) | 文件上传下载、对象存储 |
|
|
378
|
-
| 元信息 | [09-meta-rpc-manual.md](09-meta-rpc-manual.md) | meta.ping / status / trust_roots |
|
|
196
|
+
建议在 `connect()` 前注册事件处理器。
|
|
379
197
|
|
|
380
198
|
---
|
|
381
199
|
|
|
382
|
-
##
|
|
383
|
-
|
|
384
|
-
### `client.on(event, handler)` — 订阅事件
|
|
385
|
-
|
|
386
|
-
**`on()` 应在 `connect()` 之前调用**,否则连接建立瞬间触发的事件(如 `connection.state`)会丢失。
|
|
387
|
-
|
|
388
|
-
服务端推送的事件通过 `client.on()` 订阅,支持同步和异步 handler:
|
|
389
|
-
|
|
390
|
-
```python
|
|
391
|
-
subscription = client.on(event: str, handler: Callable) -> Subscription
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
**同步 handler:**
|
|
395
|
-
|
|
396
|
-
```python
|
|
397
|
-
def on_message(event):
|
|
398
|
-
print(f"收到消息: {event['payload']}")
|
|
399
|
-
|
|
400
|
-
sub = client.on("message.received", on_message)
|
|
401
|
-
```
|
|
200
|
+
## Agent Web / agent.md
|
|
402
201
|
|
|
403
|
-
|
|
202
|
+
发布自己的 agent.md:
|
|
404
203
|
|
|
405
204
|
```python
|
|
406
|
-
|
|
407
|
-
await process_message(event)
|
|
408
|
-
await client.call("message.ack", {"seq": event["seq"]})
|
|
409
|
-
|
|
410
|
-
sub = client.on("message.received", on_message)
|
|
205
|
+
await client.publish_agent_md(content)
|
|
411
206
|
```
|
|
412
207
|
|
|
413
|
-
|
|
208
|
+
解析对端并验签 agent.md:
|
|
414
209
|
|
|
415
210
|
```python
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
sub = client.on("connection.state", on_state_change)
|
|
211
|
+
resolved = await store.resolve("bob.agentid.pub")
|
|
212
|
+
if resolved["ok"]:
|
|
213
|
+
print(resolved["data"]["agent_md"]["signature"]["status"])
|
|
421
214
|
```
|
|
422
215
|
|
|
423
|
-
|
|
216
|
+
只检查远端是否存在:
|
|
424
217
|
|
|
425
218
|
```python
|
|
426
|
-
|
|
427
|
-
# ... 稍后
|
|
428
|
-
sub.unsubscribe()
|
|
219
|
+
head = await store.head_agent_md("bob.agentid.pub")
|
|
429
220
|
```
|
|
430
221
|
|
|
431
|
-
|
|
222
|
+
---
|
|
432
223
|
|
|
433
|
-
|
|
434
|
-
# 同一事件可注册多个 handler,按注册顺序依次调用
|
|
435
|
-
client.on("message.received", log_message)
|
|
436
|
-
client.on("message.received", update_ui)
|
|
437
|
-
client.on("message.received", send_notification)
|
|
438
|
-
```
|
|
224
|
+
## RPC 调用
|
|
439
225
|
|
|
440
|
-
|
|
226
|
+
认证连接后,所有业务操作通过 `client.call()`:
|
|
441
227
|
|
|
442
228
|
```python
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
client.on("message.received", handle_new_message)
|
|
448
|
-
|
|
449
|
-
# 群组变更
|
|
450
|
-
client.on("group.changed", lambda e: print(f"群组 {e['group_id']} 已更新"))
|
|
451
|
-
|
|
452
|
-
# 令牌刷新
|
|
453
|
-
client.on("token.refreshed", lambda e: print(f"令牌已刷新: {e['aid']}"))
|
|
454
|
-
|
|
455
|
-
# 连接错误
|
|
456
|
-
client.on("connection.error", lambda e: print(f"连接错误: {e}"))
|
|
229
|
+
result = await client.call("message.send", {
|
|
230
|
+
"to": "bob.agentid.pub",
|
|
231
|
+
"payload": {"type": "text", "text": "Hello!"},
|
|
232
|
+
})
|
|
457
233
|
```
|
|
458
234
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
---
|
|
462
|
-
|
|
463
|
-
## 关闭连接
|
|
464
|
-
|
|
465
|
-
```python
|
|
466
|
-
await client.close()
|
|
467
|
-
```
|
|
235
|
+
RPC 方法完整参数和响应格式见:
|
|
468
236
|
|
|
469
|
-
|
|
237
|
+
| 领域 | 手册 |
|
|
238
|
+
|------|------|
|
|
239
|
+
| 消息 | [09-message-rpc-manual.md](09-message-rpc-manual.md) |
|
|
240
|
+
| 群组 | [09-group-rpc-manual.md](09-group-rpc-manual.md) |
|
|
241
|
+
| 存储 | [09-storage-rpc-manual.md](09-storage-rpc-manual.md) |
|
|
242
|
+
| 元信息 | [09-meta-rpc-manual.md](09-meta-rpc-manual.md) |
|