@agentunion/fastaun-browser 0.5.1 → 0.5.2
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 +548 -518
- package/_packed_docs/CHANGELOG-validators.md +134 -131
- package/_packed_docs/CHANGELOG.md +548 -518
- package/_packed_docs/INDEX.md +51 -44
- package/_packed_docs/KITE_DOCS_GUIDE.md +19 -16
- 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 +169 -116
- package/_packed_docs/aun-perf-audit-critical-bugs.md +315 -0
- package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +263 -261
- package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +328 -328
- package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +2 -2
- package/_packed_docs/protocol/00A-/350/256/276/350/256/241/345/216/237/345/210/231-/344/270/272Agent/350/200/214/347/224/237.md +1 -1
- 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 +39 -16
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +8 -5
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +18 -19
- package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +1 -1
- package/_packed_docs/protocol/08-AUN-E2EE-Group.md +293 -294
- package/_packed_docs/protocol/08-AUN-E2EE.md +12 -10
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +85 -89
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +4 -4
- 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 +1 -1
- package/_packed_docs/protocol/16-/347/263/273/347/273/237/347/233/256/345/275/225/344/277/235/346/212/244/346/226/271/346/241/210.md +177 -177
- package/_packed_docs/protocol/README.md +4 -4
- package/_packed_docs/protocol/aun-docs-guide.md +2 -2
- package/_packed_docs/protocol/index.md +4 -4
- package/_packed_docs/protocol//350/215/211/346/241/210-/346/213/222/347/273/235/344/277/241/345/217/267/345/215/217/350/256/256.md +1 -1
- package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +13 -13
- package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +9 -9
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +15 -13
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +26 -18
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +33 -34
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +22 -17
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +11 -7
- package/_packed_docs/sdk/09-group-rpc-manual.md +135 -114
- package/_packed_docs/sdk/09-message-rpc-manual.md +50 -28
- package/_packed_docs/sdk/09-payload-reference.md +3 -3
- package/_packed_docs/sdk/09-storage-rpc-manual.md +1 -1
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +11 -10
- 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 +3 -2
- package/_packed_docs/sdk/INDEX.md +15 -14
- package/_packed_docs/sdk/Notify/351/200/232/347/237/245/346/226/271/346/241/210.md +6 -2
- package/dist/agent-md.d.ts.map +1 -1
- package/dist/agent-md.js +18 -9
- package/dist/agent-md.js.map +1 -1
- package/dist/bundle.js +104 -24
- package/dist/client/v2-e2ee.d.ts.map +1 -1
- package/dist/client/v2-e2ee.js +78 -7
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 远程 agent.md 缓存与 ETag 透传方案
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
状态:已实现(以当前 Gateway / Message Service / SDK 代码为准)
|
|
4
4
|
|
|
5
5
|
## 目标
|
|
6
6
|
|
|
@@ -10,56 +10,94 @@
|
|
|
10
10
|
|
|
11
11
|
- 每个远程 AID 在 SDK 本地维护一条 `agent.md` 记录,包含 `remote_etag`、`local_etag`、`content`、`last_modified` 等字段。
|
|
12
12
|
- Python / TypeScript / Go 将正文和元数据持久化到 `{aun_path}/AIDs/{aid}/agent.md` 与 `agentmd.json`;浏览器 JavaScript 使用 IndexedDB 等价 key,存储不可用时退化为内存缓存。
|
|
13
|
-
- `
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
## 可行性结论
|
|
18
|
-
|
|
19
|
-
方案可行。服务端已有 `agent.md` HEAD/ETag 能力,Gateway 当前也已经在 RPC response `_meta.agent_md_etag` 中注入“请求者自己”的服务端 ETag。需要扩展两条路径:
|
|
20
|
-
|
|
21
|
-
1. `message.send` / V2 P2P send:把 `from` 的 `agent.md` ETag 注入消息信封,随消息到达接收端。
|
|
22
|
-
2. `message.send` RPC response:把 `to` 的 `agent.md` ETag 注入响应 `_meta`,返回发送端。
|
|
13
|
+
- Gateway 在 RPC 响应和事件推送 `_meta.agent_md_etags` 中携带 `requester`、`peer` 和 `group` 的云端 `agent.md` 元数据。
|
|
14
|
+
- `message.send` 的 RPC 响应可让发送方观察到对端和群自身的云端版本;事件推送可让接收方观察到订阅方、事件源和群自身的云端版本。
|
|
15
|
+
- Message Service V2 P2P 信封携带发送方 `agent.md` ETag;四端 SDK 也能识别信封中的 `agent_md.group`。
|
|
16
|
+
- ETag 只作为版本提示,不替代 `agent.md` 内容下载和验签。
|
|
23
17
|
|
|
18
|
+
## 实现结论
|
|
19
|
+
|
|
20
|
+
服务端已有 `agent.md` HEAD/ETag 能力,当前实现已经覆盖三条观察路径:
|
|
21
|
+
|
|
22
|
+
1. Gateway RPC response:在 `_meta.agent_md_etag` 保留旧的请求方 ETag,同时在 `_meta.agent_md_etags` 注入结构化角色元数据。
|
|
23
|
+
2. Gateway event push:在事件通知 `_meta.agent_md_etags` 注入订阅方、事件源和群自身元数据。
|
|
24
|
+
3. Message Service V2 P2P envelope:将 `from_aid` 的 ETag 持久化到 `envelope.agent_md.sender`,随 `message.v2.pull` 到达接收端。
|
|
25
|
+
|
|
24
26
|
注意:服务端注入的 ETag 只能代表云端版本。SDK 本地必须区分“观察到的远端云端 ETag”和“当前本地内容对应的 ETag”。字段命名固定为 `remote_etag` 和 `local_etag`,其中 `remote_etag` 表示远端云端版本,`local_etag` 表示本地 `content` 对应版本。下载必须始终使用无条件 GET,不能把 `remote_etag` 或 `local_etag` 放进 `If-None-Match` / `If-Modified-Since`,否则会把版本提示误用成 HTTP 缓存状态。
|
|
25
|
-
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```json
|
|
31
|
-
{
|
|
32
|
-
"agent_md": {
|
|
33
|
-
"sender": {
|
|
34
|
-
"aid": "alice.agentid.pub",
|
|
35
|
-
"etag": "\"sha256...\""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
27
|
+
|
|
28
|
+
## 字段结构
|
|
29
|
+
|
|
30
|
+
消息信封中的 `agent_md` 字段:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"agent_md": {
|
|
35
|
+
"sender": {
|
|
36
|
+
"aid": "alice.agentid.pub",
|
|
37
|
+
"etag": "\"sha256...\"",
|
|
38
|
+
"last_modified": "Sat, 01 Jan 2026 12:00:00 GMT"
|
|
39
|
+
},
|
|
40
|
+
"group": {
|
|
41
|
+
"aid": "team.agentid.pub",
|
|
42
|
+
"etag": "\"sha256...\"",
|
|
43
|
+
"last_modified": "Sat, 01 Jan 2026 12:00:00 GMT"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
当前 Message Service V2 P2P 路径实际持久化 `agent_md.sender`。四端 SDK 已支持提取 `agent_md.group`;当群消息信封或后续服务端路径携带该字段时,会按同一缓存模型写入群 AID 的 `remote_etag`。
|
|
50
|
+
|
|
51
|
+
Gateway RPC response 和 event push 的 `_meta` 字段:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{
|
|
55
|
+
"_meta": {
|
|
56
|
+
"agent_md_etag": "\"requester-etag\"",
|
|
57
|
+
"agent_md_etags": {
|
|
58
|
+
"requester": {
|
|
59
|
+
"aid": "alice.agentid.pub",
|
|
60
|
+
"etag": "\"sha256...\"",
|
|
61
|
+
"last_modified": "Sat, 01 Jan 2026 12:00:00 GMT"
|
|
62
|
+
},
|
|
63
|
+
"peer": {
|
|
64
|
+
"aid": "bob.agentid.pub",
|
|
65
|
+
"etag": "\"sha256...\"",
|
|
66
|
+
"last_modified": "Sat, 01 Jan 2026 12:00:00 GMT"
|
|
67
|
+
},
|
|
68
|
+
"group": {
|
|
69
|
+
"aid": "team.agentid.pub",
|
|
70
|
+
"etag": "\"sha256...\"",
|
|
71
|
+
"last_modified": "Sat, 01 Jan 2026 12:00:00 GMT"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
角色语义:
|
|
79
|
+
|
|
80
|
+
| 角色键 | 含义 | 注入场景 |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| `requester` | 请求方 / 事件订阅方 | RPC response、event push |
|
|
83
|
+
| `peer` | 对端 / 事件源 | RPC response、event push |
|
|
84
|
+
| `group` | 群自身 `group_aid` / `group_id` 对应的 `agent.md` | 群 RPC response、群事件推送、群通知 |
|
|
85
|
+
|
|
86
|
+
兼容别名:
|
|
87
|
+
|
|
88
|
+
| 别名 | 指向 | 说明 |
|
|
89
|
+
| --- | --- | --- |
|
|
90
|
+
| `receiver` / `target` | `requester` | 旧 SDK 对响应/事件接收方的命名 |
|
|
91
|
+
| `sender` / `from` | `peer` | 旧 SDK 对事件源 / 消息发送方的命名 |
|
|
92
|
+
| `to` | `peer` | 旧 SDK 在 `message.send` 响应中读取目标 AID 的命名 |
|
|
93
|
+
|
|
94
|
+
每个角色对象至少包含 `aid`;`etag` 和 `last_modified` 只有在 HEAD/cache 命中时出现。
|
|
95
|
+
|
|
96
|
+
- `_meta.agent_md_etag` 保持现有语义,仍表示请求者自己在服务端的 `agent.md` ETag。
|
|
97
|
+
- `_meta.agent_md_etags.peer` 表示本次 RPC 对端或事件源的 `agent.md` ETag。
|
|
98
|
+
- `_meta.agent_md_etags.group` 表示群自身 `group_aid` / `group_id` 的 `agent.md` ETag。
|
|
99
|
+
- `envelope.agent_md.sender` 表示本条消息发送方的 `agent.md` ETag。
|
|
100
|
+
- 字段缺失、ETag 为空、HEAD 失败均不影响消息收发。
|
|
63
101
|
|
|
64
102
|
## SDK 缓存模型
|
|
65
103
|
|
|
@@ -70,7 +108,7 @@
|
|
|
70
108
|
| `aid` | 远程 AID |
|
|
71
109
|
| `content` | 本地缓存的完整 `agent.md` 内容,可为空 |
|
|
72
110
|
| `local_etag` | 当前 `content` 对应的 ETag,由成功 GET 200 内容确认;304 复用本地内容时沿用原值 |
|
|
73
|
-
| `remote_etag` |
|
|
111
|
+
| `remote_etag` | 从消息信封、RPC response `_meta` 或 event push `_meta` 观察到的远端云端 ETag |
|
|
74
112
|
| `last_modified` | GET 响应的 `Last-Modified` |
|
|
75
113
|
| `fetched_at` | 最近一次成功确认内容的本机时间 |
|
|
76
114
|
| `checked_at` | 最近一次 HEAD / GET 确认远端状态的本机时间 |
|
|
@@ -90,7 +128,7 @@
|
|
|
90
128
|
|
|
91
129
|
## 时序图
|
|
92
130
|
|
|
93
|
-
### 发送消息时,发送端获得
|
|
131
|
+
### 发送消息时,发送端获得 peer / group 的 agent.md ETag
|
|
94
132
|
|
|
95
133
|
```mermaid
|
|
96
134
|
sequenceDiagram
|
|
@@ -100,18 +138,17 @@ sequenceDiagram
|
|
|
100
138
|
participant NS as NameService
|
|
101
139
|
participant DB as Message DB
|
|
102
140
|
|
|
103
|
-
A->>GW: RPC message.send(to=B
|
|
104
|
-
GW->>MSG: 转发 send,附带 _auth.aid=A
|
|
105
|
-
MSG->>NS: HEAD https://A/agent.md<br/>取 sender ETag(缓存命中则不请求)
|
|
106
|
-
NS-->>MSG: ETag(A)
|
|
107
|
-
MSG->>MSG: 注入 envelope.agent_md.sender={aid:A, etag}
|
|
108
|
-
MSG->>DB: 持久化 envelope / wraps
|
|
109
|
-
MSG-->>GW: send result
|
|
110
|
-
GW->>
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
```
|
|
141
|
+
A->>GW: RPC message.send(to=B)<br/>或 group.send(group_id=G)
|
|
142
|
+
GW->>MSG: 转发 send,附带 _auth.aid=A
|
|
143
|
+
MSG->>NS: HEAD https://A/agent.md<br/>取 sender ETag(缓存命中则不请求)
|
|
144
|
+
NS-->>MSG: ETag(A)
|
|
145
|
+
MSG->>MSG: 注入 envelope.agent_md.sender={aid:A, etag}
|
|
146
|
+
MSG->>DB: 持久化 envelope / wraps
|
|
147
|
+
MSG-->>GW: send result
|
|
148
|
+
GW->>GW: 只读本地 agent.md meta cache<br/>miss 时后台预热,不等待 HEAD
|
|
149
|
+
GW-->>A: RPC response + _meta.agent_md_etags.peer/group
|
|
150
|
+
A->>A: observeRemoteAgentMdEtag(B/G, etag)<br/>更新内存 + agentmd.json/IndexedDB remote_etag
|
|
151
|
+
```
|
|
115
152
|
|
|
116
153
|
### 接收消息时,接收端获得 from 的 agent.md ETag
|
|
117
154
|
|
|
@@ -135,8 +172,22 @@ sequenceDiagram
|
|
|
135
172
|
NS-->>B: 200 content + ETag,或异常 304/404/error
|
|
136
173
|
B->>B: verify_agent_md(content, aid=A)
|
|
137
174
|
B->>Cache: 写内存 + agentmd.json/IndexedDB
|
|
138
|
-
end
|
|
139
|
-
```
|
|
175
|
+
end
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 事件推送时,接收端获得 requester / peer / group 的 agent.md ETag
|
|
179
|
+
|
|
180
|
+
```mermaid
|
|
181
|
+
sequenceDiagram
|
|
182
|
+
participant GW as Gateway
|
|
183
|
+
participant R as Receiver SDK
|
|
184
|
+
participant Cache as SDK AgentMdCache
|
|
185
|
+
|
|
186
|
+
GW->>GW: 构造 event/notification<br/>读取 receiver_aid / sender_aid / group_aid
|
|
187
|
+
GW->>GW: 只读本地 agent.md meta cache<br/>按接收方+角色+aid 节流
|
|
188
|
+
GW-->>R: event push + _meta.agent_md_etags
|
|
189
|
+
R->>Cache: observe requester / peer / group
|
|
190
|
+
```
|
|
140
191
|
|
|
141
192
|
### SDK 本地缓存按需加载
|
|
142
193
|
|
|
@@ -181,45 +232,38 @@ sequenceDiagram
|
|
|
181
232
|
A->>NS: PUT /agent.md
|
|
182
233
|
NS->>NS: 保存 content,生成新 ETag
|
|
183
234
|
NS-->>A: upload result + ETag
|
|
184
|
-
NS-->>GW: event nameservice.agent_md_updated(aid=A)
|
|
185
|
-
GW->>GW: invalidate agent_md_etag_cache[A]
|
|
186
|
-
NS-->>MSG:
|
|
187
|
-
MSG->>MSG: invalidate message-side agent_md_etag_cache[A]
|
|
188
|
-
```
|
|
235
|
+
NS-->>GW: event nameservice.agent_md_updated(aid=A)
|
|
236
|
+
GW->>GW: invalidate agent_md_etag_cache[A]<br/>同时清理该 aid 的 emit 节流记录
|
|
237
|
+
NS-->>MSG: event nameservice.agent_md_updated(aid=A)
|
|
238
|
+
MSG->>MSG: invalidate message-side agent_md_etag_cache[A]
|
|
239
|
+
```
|
|
189
240
|
|
|
190
241
|
## 服务端流程细化
|
|
191
242
|
|
|
192
243
|
### Gateway
|
|
193
244
|
|
|
194
|
-
现有行为:
|
|
195
|
-
|
|
196
|
-
- `deliver_response_to_client`
|
|
197
|
-
-
|
|
198
|
-
- `
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
-
|
|
203
|
-
-
|
|
204
|
-
- 注入逻辑应使用同一套 ETag 缓存和 HEAD fetcher。
|
|
205
|
-
- 如果缓存 miss,第一轮响应可以不带 `to` ETag;后台预热后下一次消息或 RPC 再带上。
|
|
206
|
-
- 如果产品希望“发送后立即拿到 to ETag”,可对 message send 做同步 HEAD,但应设置短超时并保证失败不影响发送。
|
|
245
|
+
现有行为:
|
|
246
|
+
|
|
247
|
+
- `deliver_response_to_client` 在 RPC response `_meta.agent_md_etag` 中保留请求者自己的 `agent.md` ETag。
|
|
248
|
+
- RPC response `_meta.agent_md_etags` 使用标准角色键 `requester`、`peer`、`group`,并保留 `receiver` / `target` / `to` / `sender` / `from` 兼容别名。
|
|
249
|
+
- Event push 构造时同样注入 `_meta.agent_md_etags`:`requester` 是事件订阅方,`peer` 是事件源,`group` 是事件数据中的 `group_aid` / `group_id`。
|
|
250
|
+
- ETag 获取采用本地 TTL 缓存:正缓存 300 秒,负缓存 60 秒;miss 时只按配置触发后台 HEAD 预热,不阻塞 RPC response 或 event push 热路径。
|
|
251
|
+
- 默认只有缓存已存在或启用后台刷新时才注入;`AUN_GATEWAY_AGENT_MD_BACKGROUND_REFRESH` / `AUN_AGENT_MD_BACKGROUND_REFRESH` 可启用后台预热。
|
|
252
|
+
- 注入发送本身有节流:按 `recipient_scope + role + aid` 记录最近发送状态,默认 60 秒;首次、`etag` 变化或 `last_modified` 变化立即注入。
|
|
253
|
+
- 注入节流间隔可由 `AUN_GATEWAY_AGENT_MD_META_EMIT_INTERVAL_SECONDS` 或 `AUN_AGENT_MD_META_EMIT_INTERVAL_SECONDS` 覆盖,取值被限制在 `0..86400` 秒。
|
|
254
|
+
- `nameservice.agent_md_updated` 事件会失效对应 AID 的 Gateway ETag 缓存,并清理该 AID 的注入节流记录。
|
|
207
255
|
|
|
208
256
|
### Message Service
|
|
209
257
|
|
|
210
|
-
现有 V2 路径:
|
|
211
|
-
|
|
212
|
-
- SDK 加密 P2P 消息当前实际调用 `message.send`。
|
|
213
|
-
- 服务端通过 payload `type=e2ee.p2p_encrypted` 且 `version=v2` 进入 `_rpc_send_v2_p2p`。
|
|
214
|
-
- `_rpc_send_v2_p2p` 持久化 `protected_headers`、`context`,并在 `message.v2.pull` 时重建 `envelope_json`。
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
-
|
|
219
|
-
- 将结果注入 envelope 顶层 `agent_md.sender`。
|
|
220
|
-
- `agent_md` 应随 envelope 持久化并在 `_rebuild_v2_envelope_json` 中恢复。
|
|
221
|
-
- 在线 push 事件可以只带 seq,不强制带完整 ETag;接收端通过 pull 取得完整信封即可。
|
|
222
|
-
- V1 明文/旧 `message.send` 如需同样能力,可在传统 message envelope 中透传同等 `agent_md.sender` 字段。
|
|
258
|
+
现有 V2 路径:
|
|
259
|
+
|
|
260
|
+
- SDK 加密 P2P 消息当前实际调用 `message.send`。
|
|
261
|
+
- 服务端通过 payload `type=e2ee.p2p_encrypted` 且 `version=v2` 进入 `_rpc_send_v2_p2p`。
|
|
262
|
+
- `_rpc_send_v2_p2p` 持久化 `protected_headers`、`context`、`agent_md_json`,并在 `message.v2.pull` 时重建 `envelope_json`。
|
|
263
|
+
- `_rpc_send_v2_p2p` 写入共享体前为 `from_aid` 查询 `agent.md` ETag,并将结果注入 envelope 顶层 `agent_md.sender`。
|
|
264
|
+
- Message Service 的 ETag 缓存同样使用正缓存 300 秒、负缓存 60 秒;热路径可用 `AUN_MESSAGE_AGENT_MD_BACKGROUND_REFRESH` 或 `agent_md_background_refresh` 配置控制后台刷新。
|
|
265
|
+
- 在线 push 事件可以只带 seq,不强制带完整 ETag;接收端通过 pull 取得完整信封即可。
|
|
266
|
+
- 当前群自身 `group` 元数据主要由 Gateway 在 RPC response / event push `_meta.agent_md_etags.group` 中注入;SDK 已兼容信封 `agent_md.group`。
|
|
223
267
|
|
|
224
268
|
### NameService
|
|
225
269
|
|
|
@@ -229,33 +273,38 @@ sequenceDiagram
|
|
|
229
273
|
- `PUT /agent.md` 上传后生成新 ETag。
|
|
230
274
|
- 上传后发布 `nameservice.agent_md_updated` 事件,Gateway 已订阅并失效缓存。
|
|
231
275
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
-
|
|
235
|
-
- HEAD 失败、404、超时返回空 ETag,不影响消息主链路。
|
|
276
|
+
运行约束:
|
|
277
|
+
|
|
278
|
+
- Message Service 维护自己的 ETag 缓存时,应继续订阅 `nameservice.agent_md_updated`。
|
|
279
|
+
- HEAD 失败、404、超时返回空 ETag,不影响消息主链路。
|
|
236
280
|
|
|
237
281
|
## SDK 流程细化
|
|
238
282
|
|
|
239
283
|
### 观察远端 ETag
|
|
240
284
|
|
|
241
|
-
SDK
|
|
285
|
+
SDK 内部使用统一观察入口:
|
|
242
286
|
|
|
243
287
|
```text
|
|
244
288
|
observe_remote_agent_md_etag(aid, etag, source)
|
|
245
289
|
```
|
|
246
290
|
|
|
247
|
-
触发来源:
|
|
248
|
-
|
|
249
|
-
- RPC response `_meta.agent_md_etags.
|
|
250
|
-
-
|
|
251
|
-
-
|
|
291
|
+
触发来源:
|
|
292
|
+
|
|
293
|
+
- RPC response / event push `_meta.agent_md_etags.requester`:观察请求方 / 订阅方。
|
|
294
|
+
- RPC response / event push `_meta.agent_md_etags.peer`:观察对端 / 事件源。
|
|
295
|
+
- RPC response / event push `_meta.agent_md_etags.group`:观察群自身 `group_aid` / `group_id`。
|
|
296
|
+
- 兼容别名 `_meta.agent_md_etags.receiver`、`target`、`to`、`sender`、`from`:四端 SDK 均继续读取。
|
|
297
|
+
- 消息信封 `agent_md.sender`:收到消息后观察 `from`;缺少 `aid` 时从 envelope 顶层或 AAD 的 `from` 兜底。
|
|
298
|
+
- 消息信封 `agent_md.group`:观察群自身;缺少 `aid` 时从 envelope 顶层或 AAD 的 `group_aid` / `group_id` 兜底。
|
|
299
|
+
- 现有 `_meta.agent_md_etag`:仍用于当前客户端自己的云端 ETag。
|
|
252
300
|
|
|
253
301
|
处理规则:
|
|
254
302
|
|
|
255
|
-
- aid
|
|
256
|
-
- etag 与当前 `remote_etag`
|
|
257
|
-
- etag 变化:更新 `remote_etag`、`observed_at`,并根据 `local_etag` 推导是否需要更新。
|
|
303
|
+
- aid 为空,或 `etag` / `last_modified` 都为空时忽略。
|
|
304
|
+
- etag 与当前 `remote_etag` 相同且 `last_modified` 未变化:保持记录并触发缺内容检查。
|
|
305
|
+
- etag 或 `last_modified` 变化:更新 `remote_etag`、`last_modified`、`observed_at`,并根据 `local_etag` 推导是否需要更新。
|
|
258
306
|
- 变更需要同时写入内存和 agentmd.json / IndexedDB。
|
|
307
|
+
- 本地没有 `content` 时,SDK 会按各语言实现触发去重后的后台下载;下载仍使用无条件 GET。
|
|
259
308
|
|
|
260
309
|
### 按需下载
|
|
261
310
|
|
|
@@ -301,19 +350,23 @@ agent.md 不写入 SQLite。当前 SDK 使用以下持久化位置:
|
|
|
301
350
|
- 多个协程同时触发同一 AID 下载:需要 per-AID in-flight 去重。
|
|
302
351
|
- 观察到 ETag A 后开始下载,期间又观察到 ETag B:下载完成时只更新 `local_etag=A`,随后仍可由 `remote_etag != local_etag` 推导为需要更新,下一轮继续拉 B。
|
|
303
352
|
- 304 但本地 content 缺失:不能返回空内容,必须再无条件 GET 一次。
|
|
304
|
-
- 信封里的 ETag 不参与 AAD,不作为安全声明;安全性仍依赖 `agent.md` 签名和证书校验。
|
|
305
|
-
-
|
|
306
|
-
-
|
|
353
|
+
- 信封里的 ETag 不参与 AAD,不作为安全声明;安全性仍依赖 `agent.md` 签名和证书校验。
|
|
354
|
+
- Gateway `_meta` 里的 ETag 也不参与 E2EE AAD 或业务鉴权,只是版本提示。
|
|
355
|
+
- HEAD/GET 超时不影响 message send 和 message pull。
|
|
356
|
+
- 跨域场景中,目标域 Message Service 注入 sender ETag 时可能需要跨域 HEAD;失败时允许缺字段。
|
|
307
357
|
|
|
308
358
|
## 测试要点
|
|
309
359
|
|
|
310
|
-
- 发送方收到 `message.send` 响应后,能把 `to` 的 ETag 写入本地缓存 `remote_etag`。
|
|
311
|
-
-
|
|
360
|
+
- 发送方收到 `message.send` 响应后,能把 `peer` / `to` 的 ETag 写入本地缓存 `remote_etag`。
|
|
361
|
+
- 群 RPC response 或群事件 push 带 `_meta.agent_md_etags.group` 时,四端 SDK 都能把群 AID 的 ETag 写入本地缓存 `remote_etag`。
|
|
362
|
+
- 接收方 `message.v2.pull` 后,能从 `envelope.agent_md.sender` 写入 `from` 的 `remote_etag`。
|
|
363
|
+
- 信封带 `agent_md.group` 且缺少 `aid` 时,四端 SDK 能从 `group_aid` / `group_id` 兜底识别群 AID。
|
|
312
364
|
- ETag 变化但内容未下载时,可由 `remote_etag != local_etag` 推导为需要更新。
|
|
313
365
|
- 本地文件 / IndexedDB 有缓存、内存为空时,SDK 能按需加载。
|
|
314
366
|
- 304 且本地有内容时复用内容;304 但本地无内容时再无条件 GET 一次。
|
|
315
|
-
- `agent.md` 上传后,Gateway 缓存失效,后续消息能看到新 ETag。
|
|
316
|
-
-
|
|
367
|
+
- `agent.md` 上传后,Gateway 缓存失效,后续消息能看到新 ETag。
|
|
368
|
+
- Gateway 元数据注入在未变化时默认 60 秒内不重复发送,ETag 或 `last_modified` 变化时立即发送。
|
|
369
|
+
- HEAD/GET 404、超时、网络错误不影响消息收发主链路。
|
|
317
370
|
- Python / TS / JS / Go 四个 SDK 对 `remote_etag`、`local_etag`、`content`、`remote_status`、`verify_status` 语义一致。
|
|
318
371
|
|
|
319
372
|
|