@agentunion/fastaun 0.5.25 → 0.5.27

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 (76) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/_packed_docs/CHANGELOG.md +41 -0
  3. package/_packed_docs/INDEX.md +22 -14
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +11 -6
  5. package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +16 -1
  6. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +37 -9
  7. package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +20 -9
  8. package/_packed_docs/cli/CLI/346/211/213/345/206/214.md +57 -12
  9. package/_packed_docs/cli//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241CLI/345/274/200/345/217/221/344/270/216/344/275/277/347/224/250/346/214/207/345/215/227.md +869 -0
  10. package/_packed_docs/sdk/0.5.22-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +2 -2
  11. package/_packed_docs/sdk/0.5.27-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +408 -0
  12. package/_packed_docs/sdk/0.5.27-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +410 -0
  13. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +2 -2
  14. package/_packed_docs/sdk/09-/345/207/255/350/257/201/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +187 -73
  15. package/_packed_docs/sdk/09-/347/273/204/347/273/207/346/234/215/345/212/241RPC/346/211/213/345/206/214.md +1 -1
  16. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +13 -9
  17. package/_packed_docs/sdk/INDEX.md +21 -13
  18. package/_packed_docs/sdk/agent.md/344/270/216group.index/347/232/204ETag/350/247/202/345/257/237/344/270/216/345/220/214/346/255/245/346/234/272/345/210/266.md +240 -0
  19. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +973 -266
  20. package/_packed_docs/sdk//345/207/255/350/257/201/344/270/216/347/273/204/347/273/207/346/234/215/345/212/241SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +950 -242
  21. package/dist/agent-md-schema.js +1 -1
  22. package/dist/agent-md-schema.js.map +1 -1
  23. package/dist/agent-md.js +5 -0
  24. package/dist/agent-md.js.map +1 -1
  25. package/dist/aid.js +3 -3
  26. package/dist/aid.js.map +1 -1
  27. package/dist/auth.js +21 -19
  28. package/dist/auth.js.map +1 -1
  29. package/dist/cert-utils.d.ts +1 -1
  30. package/dist/cert-utils.js +4 -4
  31. package/dist/cert-utils.js.map +1 -1
  32. package/dist/client/lifecycle.d.ts +1 -1
  33. package/dist/client/lifecycle.js.map +1 -1
  34. package/dist/client/rpc-pipeline.js +8 -1
  35. package/dist/client/rpc-pipeline.js.map +1 -1
  36. package/dist/client/v2-e2ee.js +7 -0
  37. package/dist/client/v2-e2ee.js.map +1 -1
  38. package/dist/client.d.ts +12 -0
  39. package/dist/client.js +305 -29
  40. package/dist/client.js.map +1 -1
  41. package/dist/facades.d.ts +38 -0
  42. package/dist/facades.js +49 -5
  43. package/dist/facades.js.map +1 -1
  44. package/dist/index.d.ts +4 -0
  45. package/dist/index.js +3 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/keystore/local-identity-store.js +16 -1
  48. package/dist/keystore/local-identity-store.js.map +1 -1
  49. package/dist/keystore/local-token-store.js +16 -1
  50. package/dist/keystore/local-token-store.js.map +1 -1
  51. package/dist/org-protocol.d.ts +1 -0
  52. package/dist/org-protocol.js +39 -36
  53. package/dist/org-protocol.js.map +1 -1
  54. package/dist/ownership-v21.js +7 -7
  55. package/dist/ownership-v21.js.map +1 -1
  56. package/dist/register-flow.js +2 -2
  57. package/dist/register-flow.js.map +1 -1
  58. package/dist/semantic-facade.d.ts +176 -0
  59. package/dist/semantic-facade.js +611 -0
  60. package/dist/semantic-facade.js.map +1 -0
  61. package/dist/semantic-protocol.d.ts +810 -0
  62. package/dist/semantic-protocol.js +894 -0
  63. package/dist/semantic-protocol.js.map +1 -0
  64. package/dist/tools/cross-sdk-agent.d.ts +11 -1
  65. package/dist/tools/cross-sdk-agent.js +388 -7
  66. package/dist/tools/cross-sdk-agent.js.map +1 -1
  67. package/dist/transport.d.ts +1 -0
  68. package/dist/transport.js +28 -2
  69. package/dist/transport.js.map +1 -1
  70. package/dist/v2/e2ee/decrypt.d.ts +5 -0
  71. package/dist/v2/e2ee/decrypt.js +22 -2
  72. package/dist/v2/e2ee/decrypt.js.map +1 -1
  73. package/dist/version.d.ts +1 -1
  74. package/dist/version.js +1 -1
  75. package/package.json +2 -1
  76. package/src/certs/root.crt +13 -0
@@ -0,0 +1,240 @@
1
+ # agent.md 与 group.index 的 ETag 观察与同步机制
2
+
3
+ ## 1. 先看结论
4
+
5
+ | 对象 | ETag 权威来源 | 观察入口 | 正文/设置何时更新 |
6
+ |---|---|---|---|
7
+ | `agent.md` | Nameservice 对当前 HTTP 表示的完整响应正文计算 SHA-256,返回带引号的十六进制 ETag | Gateway RPC `_meta`、消息信封 `agent_md` | 观察只更新 `remote_etag`;显式下载或“本地无正文”的自动补拉完成验签后才更新正文 |
8
+ | `group.index` | Group 服务对签名 JSONL entries 的 canonical bytes 计算 `"sha256:<hex>"` | RPC 响应 `_meta.group_indexes` | 观察只标记 stale;`getGroupIndex` 显式拉取并验签,`updateGroupIndex` 以 ETag CAS 提交 |
9
+
10
+ `remote_etag` 是远端版本提示,`local_etag` 是当前本地已验证正文/索引的版本。两者不能混用。观察到新 ETag 不等于已经下载了新正文,也不等于应自动覆盖应用缓存。
11
+
12
+ ## 2. 总体流程
13
+
14
+ ```mermaid
15
+ flowchart LR
16
+ W[写入 agent.md / group.index] --> A[服务端生成权威 ETag]
17
+ A --> P[Gateway RPC _meta / 消息信封携带版本提示]
18
+ P --> O[SDK observer 保存 remote_etag 或 remote_meta]
19
+ O --> C{本地版本相同?}
20
+ C -->|是| K[保持正文/设置缓存]
21
+ C -->|否| D{资源类型与本地状态}
22
+ D -->|agent.md 无正文| G[自动 GET + 验签]
23
+ D -->|agent.md 已有正文| H[仅标记待更新,由应用显式 download/check]
24
+ D -->|group.index| I[仅标记 stale]
25
+ G --> U[写入 content/local_etag]
26
+ I --> J[getGroupIndex 显式拉取、验签、hydrate]
27
+ J --> U2[写入 settings/local_etag]
28
+ ```
29
+
30
+ ## 3. agent.md
31
+
32
+ ### 3.1 服务端写入和版本发布
33
+
34
+ ```mermaid
35
+ sequenceDiagram
36
+ participant SDK as SDK
37
+ participant NS as Nameservice
38
+ participant GW as Gateway
39
+ participant MSG as Message Service
40
+
41
+ SDK->>NS: PUT /agent.md
42
+ NS->>NS: 保存权威正文并计算 HTTP ETag
43
+ NS-->>SDK: 200 + ETag + Last-Modified
44
+ NS-->>GW: nameservice.agent_md_updated(aid)
45
+ GW->>GW: 清除该 AID 的 agent.md 元数据缓存和发送节流
46
+ GW-->>SDK: 后续 RPC response 的 _meta.agent_md_etags
47
+ MSG-->>SDK: message envelope.agent_md.sender/group
48
+ ```
49
+
50
+ Nameservice 的 `GET`/`HEAD` 对相同请求头返回同一表示的 ETag;`HEAD` 不返回正文,并支持 `If-None-Match`/`If-Modified-Since`。成功写入会发 `nameservice.agent_md_updated`,Gateway 用它清理自己的 ETag 元数据缓存;该通知不是 SDK 的版本事件。当前已确认的 Gateway 下发入口是后续 RPC response 的 `_meta`;消息信封也会携带发送者观察值。SDK 能解析事件 `_meta`,但当前服务端链路未确认普通事件推送会注入 agent.md ETag。四个 SDK 的下载 GET 不主动发送条件头;对代理返回的 304 仅做兼容处理。
51
+
52
+ 事件 payload 中的 ETag 针对 Nameservice 保存的完整记录;HTTP ETag 针对本次请求的响应表示,签名格式投影可能使两者不同。事件的可靠用途是让 Gateway 失效并重新读取元数据,SDK 不应把它当作已下载正文。
53
+
54
+ Gateway 元数据示例:
55
+
56
+ ```json
57
+ {
58
+ "_meta": {
59
+ "agent_md_etag": "\"<sha256-hex>\"",
60
+ "agent_md_etags": {
61
+ "requester": {"aid": "alice.agentid.pub", "etag": "\"<sha256-hex>\""},
62
+ "peer": {"aid": "bob.agentid.pub", "etag": "\"<sha256-hex>\"", "last_modified": "..."},
63
+ "group": {"aid": "team.agentid.pub", "etag": "\"<sha256-hex>\""}
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ 消息信封只承载观察值,不承载正文:
70
+
71
+ ```json
72
+ {"agent_md":{"sender":{"aid":"bob.agentid.pub","etag":"\"<sha256-hex>\""}}}
73
+ ```
74
+
75
+ ### 3.2 SDK 观察和下载判定
76
+
77
+ 四个 SDK 都在传输层注册 observer,读取 `_meta.agent_md_etag`、`_meta.agent_md_etags`,并读取信封的 `agent_md.sender`/`group`。记录至少区分:
78
+
79
+ ```text
80
+ remote_etag 观察到的服务端版本
81
+ local_etag 本地已验证 content 的版本
82
+ observed_at 最近观察时间
83
+ observation_version 观察代次
84
+ fetched_at 正文最近成功下载时间
85
+ verify_status 最近一次验签结果
86
+ ```
87
+
88
+ 观察流程:
89
+
90
+ ```mermaid
91
+ flowchart TD
92
+ E[收到 RPC _meta 或 message envelope 的 ETag] --> S[保存 remote_etag/observed_at]
93
+ S --> Q{本地是否已有已验证正文?}
94
+ Q -->|否| F[单飞 GET /agent.md]
95
+ Q -->|是| N[不 HEAD、不自动 GET;触发 changed/待更新标记]
96
+ F --> V[校验 AID、Schema、签名]
97
+ V -->|成功| L[保存正文、local_etag、fetched_at]
98
+ V -->|失败| R[记录错误并退避;等待新观察或显式重试]
99
+ ```
100
+
101
+ SDK 也能解析带 `_meta` 的事件,但当前服务端实现中已确认的 agent.md ETag 下发路径是 Gateway RPC 响应;普通事件推送不作为同步保证。`check_agent_md`/`checkAgentMd`/`CheckAgentMD` 是检查入口:本地 ETag 与观察值一致且检查 TTL 未过时可直接返回缓存;否则发一次 `HEAD`,只报告 `needs_update`,不会自动跟随 GET。Python、TS、JS 管理器可按 TTL 短路;Go 管理器的 `Check` 支持 TTL,但公开 `AIDStore.CheckAgentMD` 直接发 HEAD。`download_agent_md`/`downloadAgentMd`/`DownloadAgentMD` 才是正文下载入口。
102
+
103
+ 四端当前实现位置:
104
+
105
+ - Python:`python/src/aun_core/agent_md.py` 的 `observe_meta`、`observe_rpc_meta`、`check`、`download`。
106
+ - Go:`go/agent_md_manager.go` 的观察、`Check`、下载;公开 `AIDStore.CheckAgentMD` 是直接 HEAD 的低层入口。
107
+ - TypeScript:`ts/src/agent-md.ts` 的 `observeMeta`、`observeRpcMeta`、`check`、`download`。
108
+ - JavaScript:`js/src/agent-md.ts` 的同名逻辑;浏览器记录存 IndexedDB,缺少持久层时退化为内存。
109
+
110
+ 应用层按需同步示例(`AIDStore`):
111
+
112
+ ```ts
113
+ const state = await store.checkAgentMd(peerAid, 1);
114
+ if (state.ok && state.data.needs_update) {
115
+ await store.downloadAgentMd(peerAid);
116
+ }
117
+ ```
118
+
119
+ ```python
120
+ checked = await store.check_agent_md(peer_aid, ttl_days=1)
121
+ if checked.ok and checked.data["needs_update"]:
122
+ await store.download_agent_md(peer_aid)
123
+ ```
124
+
125
+ ```go
126
+ checked := store.CheckAgentMD(ctx, peerAid)
127
+ if checked.Ok && checked.Data.NeedsUpdate {
128
+ downloaded := store.DownloadAgentMD(ctx, peerAid)
129
+ if !downloaded.Ok { /* handle downloaded.Error */ }
130
+ }
131
+ ```
132
+
133
+ Go 的公开 `AIDStore.CheckAgentMD` 每次都执行 HEAD;`maxUnsyncedDays` 不会让该入口跳过 HEAD。
134
+
135
+ 不要把 `remote_etag` 放进 `If-None-Match`,也不要因为每次 RPC 都收到相同 ETag 就重复下载。SDK 已按 AID、身份存储范围和观察代次做单飞/退避。
136
+
137
+ ## 4. group.index
138
+
139
+ ### 4.1 服务端协议
140
+
141
+ `group.index` 是 owner/admin SDK 生成并签名的 canonical JSONL。服务端不根据数据库重建正文,只做签名、Schema、`body_hash`、ETag、权限和 CAS 校验。
142
+
143
+ ```mermaid
144
+ sequenceDiagram
145
+ participant SDK as Owner/Admin SDK
146
+ participant G as Group Service
147
+ participant DB as Group DB
148
+
149
+ SDK->>G: group.set_settings(indexed settings + signed group.index + expected_index_etag)
150
+ G->>DB: 事务内锁定 group.index
151
+ G->>DB: 比较当前 etag
152
+ alt ETag 匹配
153
+ G->>DB: 写 indexed settings 和 group.index
154
+ G-->>SDK: 成功 + _meta.group_indexes
155
+ else 冲突
156
+ G-->>SDK: group.index etag conflict
157
+ end
158
+ ```
159
+
160
+ 索引元数据示例:
161
+
162
+ ```json
163
+ {
164
+ "type": "index_meta",
165
+ "group_aid": "team.agentid.pub",
166
+ "etag": "\"sha256:...\"",
167
+ "last_modified": 1780000000000,
168
+ "body_hash": "sha256:...",
169
+ "schema": "aun.group.index.v1",
170
+ "signed_by": "alice.agentid.pub",
171
+ "sig_alg": "ECDSA-P256-SHA256",
172
+ "signature": "base64..."
173
+ }
174
+ ```
175
+
176
+ 响应版本提示:
177
+
178
+ ```json
179
+ {"_meta":{"group_indexes":{"team.agentid.pub":{
180
+ "etag":"\"sha256:...\"",
181
+ "last_modified":1780000000000,
182
+ "schema":"aun.group.index.v1"
183
+ }}}}
184
+ ```
185
+
186
+ ### 4.2 SDK 观察、读取和写入
187
+
188
+ ```mermaid
189
+ flowchart TD
190
+ M[收到 _meta.group_indexes] --> R[保存 remote_meta]
191
+ R --> E{remote etag == local_etag?}
192
+ E -->|是| F[本地快照 fresh]
193
+ E -->|否| T[标记 stale]
194
+ T --> A{应用需要最新设置?}
195
+ A -->|否| W[继续使用已验证本地快照,并暴露 stale]
196
+ A -->|是| P[getGroupIndex: group.get_settings(group.index)]
197
+ P --> V[验签、校验 entry etag、校验 signer 权限]
198
+ V --> U[保存 settings、entry_etags、index.jsonl、local_etag]
199
+ U --> F[结束:本地快照 fresh]
200
+ ```
201
+
202
+ 四端共同规则:
203
+
204
+ TypeScript/JavaScript 按需读取:
205
+
206
+ ```ts
207
+ const state = await client.group.checkGroupIndex({ group_id: groupAid });
208
+ if (state.needs_update) {
209
+ await client.group.getGroupIndex({ group_id: groupAid });
210
+ }
211
+ ```
212
+
213
+ Python 与 Go 分别调用 `client.group.check_group_index(...)` / `client.Group().CheckGroupIndex(...)`,需同步时调用对应的 `get_group_index` / `GetGroupIndex`。`updateGroupIndex` / `update_group_index` / `UpdateGroupIndex` 才执行签名写入和 `expected_index_etag` CAS。
214
+
215
+ - `checkGroupIndex` 只比较本地 `local_etag` 与已观察的 `remote_meta.etag`,不发 RPC;尚未观察到远端 meta 时,不能据此确认远端最新版本。
216
+ - `getGroupIndex` 才拉正文;成功验签后才把 `local_etag` 标为 fresh。
217
+ - `updateGroupIndex` 先读取最新索引、合并设置、重新签名,再提交 CAS;遇到 `group.index etag conflict` 重新读取并重试。
218
+ - indexed settings 的便捷读取可能使用已验证本地缓存;收到新远端 ETag 不会自动 pull 覆盖缓存,应用需显式调用 `getGroupIndex` 获取最新快照。
219
+ - 本地缓存按 `local_aid + group_aid` 隔离。Python/Go/TS 使用文件缓存;JS 使用 IndexedDB。
220
+ - `_meta.group_indexes` 不是索引正文;Gateway/Message 只透传或合并 meta,不生成索引。
221
+
222
+ Go/Python/TS/JS 的门面名称分别为 `check_group_index`/`CheckGroupIndex`/`checkGroupIndex`、`get_group_index`/`GetGroupIndex`/`getGroupIndex`、`update_group_index`/`UpdateGroupIndex`/`updateGroupIndex`。
223
+
224
+ ## 5. 规范与实现边界
225
+
226
+ - `agent.md` 格式和发现规则见 [06-服务协议](../../../docs/aun文档/aun协议/06-服务协议.md#641-agentmd-规范);显式 `/agent.md` 访问见 [附录 K](../../../docs/aun文档/aun协议/附录K-Agent_Web发现协议.md#1342-显式访问-agentmd)。
227
+ - `group.index`、`expected_index_etag`、`_meta.group_indexes` 和冲突处理见 [Group 子协议 §10.13](../../../docs/aun文档/aun协议/10-Group-子协议.md#1013-群设置与-groupindex)。
228
+ - SDK agent.md 上传/下载/检查及被动观察见 [API 手册](06-API手册.md#agentmd)。
229
+ - Storage 的 `if_sha256` 是另一套 RPC 条件读取语义,不等于 agent.md 的 HTTP ETag,也不等于 group.index 的 CAS ETag。
230
+
231
+ 源码索引:
232
+
233
+ | 链路 | 主要实现 |
234
+ |---|---|
235
+ | agent.md 服务端写入/HTTP ETag | `extensions/services/nameservice/go/internal/httpserver/agentmd.go` |
236
+ | Gateway agent.md meta | `extensions/services/gateway/go/internal/httpserver/server.go` |
237
+ | group.index ETag/签验 | `extensions/services/group/go/internal/groupindex/index.go` |
238
+ | group.index CAS | `extensions/services/group/go/internal/store/group_index_cas.go` |
239
+ | Group meta 注入 | `extensions/services/group/go/internal/settings/get_settings.go` |
240
+