@agentunion/fastaun 0.5.32 → 0.5.33
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 +30 -0
- package/_packed_docs/CHANGELOG.md +30 -0
- package/_packed_docs/sdk/0.5.33-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +316 -0
- package/_packed_docs/sdk/0.5.33-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +304 -0
- package/_packed_docs/sdk/09-storage-rpc-manual.md +33 -16
- package/dist/agent-md.d.ts +2 -1
- package/dist/agent-md.js +17 -0
- package/dist/agent-md.js.map +1 -1
- package/dist/client/control-messages.js +2 -2
- package/dist/client/control-messages.js.map +1 -1
- package/dist/client/rpc-pipeline.js +27 -5
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client.d.ts +7 -4
- package/dist/client.js +64 -16
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/ownership-workflow.d.ts +23 -3
- package/dist/ownership-workflow.js +36 -13
- package/dist/ownership-workflow.js.map +1 -1
- package/dist/storage/lowlevel.d.ts +4 -2
- package/dist/storage/lowlevel.js +2 -0
- package/dist/storage/lowlevel.js.map +1 -1
- package/dist/storage/read-cache.js +12 -0
- package/dist/storage/read-cache.js.map +1 -1
- package/dist/storage/vfs.d.ts +4 -2
- package/dist/storage/vfs.js +2 -2
- package/dist/storage/vfs.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +8 -2
- package/dist/tools/cross-sdk-agent.js +81 -16
- package/dist/tools/cross-sdk-agent.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# AUN SDK 0.5.33 开发与移植指南
|
|
2
|
+
|
|
3
|
+
面向 Python、Go、TypeScript、浏览器 JavaScript SDK 维护者及新语言移植者。以仓库 `072b7c69f`(0.5.32)对照截至 2026-11-07 的未提交变更,包含已暂存脚本和相关未跟踪的 Python 压测源码。应用接线见 [0.5.33 应用集成指南](0.5.33-SDK应用集成指南.md),完整改动索引见 [parity 0.5.33](../../python/CHANGES_FOR_PARITY.md#v0533)。
|
|
4
|
+
|
|
5
|
+
## 1. 范围与实现分层
|
|
6
|
+
|
|
7
|
+
| 本轮工作 | SDK 负责 | 配套服务负责 |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| 控制消息兼容 | 发送前核对能力、准备类别、解密后分派 | Gateway 可信会话;Message/Group 兼容选择投递通道 |
|
|
10
|
+
| Ownership 批次 | 批次上下文、归组事件、逐项审批与结果汇总 | NS 继续处理原有单项关系与名片提交 |
|
|
11
|
+
| 本地共识优先 | 恢复并核验本地快照,按需查询 | NS 返回当前权威事实,管理提交仍做原有校验 |
|
|
12
|
+
| 批量 ACL | VFS/LowLevel 参数贯通、失败时定向失效缓存 | Storage 合并授权对象、逐项处理及权限计数 |
|
|
13
|
+
| Python 专项 | 群 Pull 去重复闸门、退避区分、容量压测 CLI | 保持现有服务接口 |
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
%%{init: {"theme":"base","flowchart":{"curve":"linear","nodeSpacing":24,"rankSpacing":32}}}%%
|
|
17
|
+
flowchart TB
|
|
18
|
+
A["宿主应用"]:::app
|
|
19
|
+
subgraph SDK["每个 AID 进程中的 SDK"]
|
|
20
|
+
direction TB
|
|
21
|
+
F["AUNClient 门面"]:::entry
|
|
22
|
+
O["Ownership<br/>批次 / 单项审批 / 共识"]:::logic
|
|
23
|
+
V["Storage VFS / LowLevel<br/>多 AID ACL"]:::logic
|
|
24
|
+
E["已有 EventService<br/>Pub / Bus / Sub"]:::inherited
|
|
25
|
+
L["本地身份仓库<br/>agent.md / 共识快照 / 读缓存"]:::local
|
|
26
|
+
P["RPC 准备与分类交付<br/>能力 / E2EE / 内部消费"]:::entry
|
|
27
|
+
F --> O & V & E
|
|
28
|
+
O & V --> L
|
|
29
|
+
O & V & E --> P
|
|
30
|
+
end
|
|
31
|
+
G["Gateway<br/>认证身份 / 设备 / RPC 转发"]:::infra
|
|
32
|
+
subgraph SERVICES["AUN 服务"]
|
|
33
|
+
direction LR
|
|
34
|
+
M["Message / Group<br/>消息通道与 TTL"]:::infra
|
|
35
|
+
N["NS<br/>名片与 Ownership 事实"]:::infra
|
|
36
|
+
S["Storage<br/>对象 / ACL / CAS"]:::infra
|
|
37
|
+
C["Credential<br/>登记 / 状态 / 撤销"]:::infra
|
|
38
|
+
end
|
|
39
|
+
A --> F
|
|
40
|
+
P --> G
|
|
41
|
+
G --> M & N & S & C
|
|
42
|
+
classDef app fill:#eff6ff,stroke:#60a5fa,color:#1e3a8a,rx:10,ry:10
|
|
43
|
+
classDef entry fill:#eef2ff,stroke:#818cf8,color:#312e81,rx:10,ry:10
|
|
44
|
+
classDef logic fill:#ecfdf5,stroke:#6ee7b7,color:#065f46,rx:10,ry:10
|
|
45
|
+
classDef local fill:#fff7ed,stroke:#fdba74,color:#9a3412,rx:10,ry:10
|
|
46
|
+
classDef inherited fill:#f8fafc,stroke:#cbd5e1,color:#475569,rx:10,ry:10
|
|
47
|
+
classDef infra fill:#f8fafc,stroke:#94a3b8,color:#334155,rx:10,ry:10
|
|
48
|
+
style SDK fill:#ffffff,stroke:#e2e8f0,rx:12,ry:12
|
|
49
|
+
style SERVICES fill:#f8fafc,stroke:#e2e8f0,rx:12,ry:12
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
EventService、VFS 定向缓存、RPC `16/8/4/4` 预算及 Bus 单实例机制沿用 0.5.32;本版不重新定义事件目录或 fanout。Pub/Bus/Sub 使用 `client.EventService`(Go 为 `EventService()`),详细约束见 [0.5.32 移植指南](0.5.32-SDK开发与移植指南.md)与[事件服务移植指南](AUN事件发布订阅开发移植指南.md)。
|
|
53
|
+
|
|
54
|
+
## 2. 控制消息:先准备语义,再决定传输类别
|
|
55
|
+
|
|
56
|
+
### 2.1 共同契约与字段位置
|
|
57
|
+
|
|
58
|
+
| 内容与场景 | 能力已协商 | 类别或 SDK 协议未协商 |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| 普通消息,P2P/群,明文/加密 | 普通路径 | 普通路径;群普通 TTL 不因控制能力缺失而被阻断 |
|
|
61
|
+
| 应用 `control`,P2P/群,明文/加密 | 保留类别 | 构造请求时移除外层类别和可改写保护头类别,走普通投递 |
|
|
62
|
+
| P2P 加密 `sdk_control` | 保留类别、协议与版本 | 移除外层路由类别;E2EE 内部类别、协议与版本保留 |
|
|
63
|
+
| 明文 `sdk_control`、群 `sdk_control` | 本地拒绝 | 本地拒绝 |
|
|
64
|
+
|
|
65
|
+
| 位置 | 含义与检查 |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| RPC 参数 `message_class` | 请求投递类别;降级可省略,Go 不重新补为空字符串或 `normal` |
|
|
68
|
+
| 明文 RPC 参数 `protected_headers` | 明文元数据所在层;服务端直接解析,并结合可信会话身份处理 |
|
|
69
|
+
| E2EE 信封 `protected_headers` | 受认证的消息语义;P2P 通常在 `payload` 信封内,群 V2 在 `envelope` 内 |
|
|
70
|
+
| 送达记录 `delivery_class` | 服务端实际选择的通道;普通通道不抹去信封中的 SDK 语义 |
|
|
71
|
+
|
|
72
|
+
类别和协议冲突继续报参数错误。信封已加密签名时保持原样;降级调整路由,接收侧仍校验原受保护内容。普通加密信封未声明类别时按 `normal` 校验,不能将缺字段当作解密失败。
|
|
73
|
+
|
|
74
|
+
### 2.2 发送与交付顺序
|
|
75
|
+
|
|
76
|
+
```mermaid
|
|
77
|
+
sequenceDiagram
|
|
78
|
+
autonumber
|
|
79
|
+
participant A as 应用或 SDK 内部模块
|
|
80
|
+
participant P as 发送准备
|
|
81
|
+
participant G as Gateway
|
|
82
|
+
participant M as Message / Group
|
|
83
|
+
participant R as 接收 SDK
|
|
84
|
+
participant D as 接收应用
|
|
85
|
+
A->>P: method / class / encrypt / payload / TTL
|
|
86
|
+
P->>P: 合并元数据,检查参数和当前协商结果
|
|
87
|
+
alt 明文或群 sdk_control
|
|
88
|
+
P-->>A: 本地拒绝,不进入传输
|
|
89
|
+
else 合法消息
|
|
90
|
+
alt 应用 control 未协商
|
|
91
|
+
P->>P: 移除可变类别,保留其它参数
|
|
92
|
+
else 加密 sdk_control 未协商
|
|
93
|
+
P->>P: 省略外层类别,保留 SDK 保护头
|
|
94
|
+
end
|
|
95
|
+
P->>G: 发送请求与明文正文或 E2EE 信封
|
|
96
|
+
G->>M: 转发可信身份与请求
|
|
97
|
+
M->>M: 选择通道,保留 TTL 与信封
|
|
98
|
+
M-->>R: 实际投递类别与消息
|
|
99
|
+
R->>R: 明文使用可信投递身份;加密核验信封
|
|
100
|
+
alt 已认证的 sdk_control
|
|
101
|
+
R->>R: 交给 SDK 协议处理器
|
|
102
|
+
else 应用 control 或 normal
|
|
103
|
+
R-->>D: 应用消息事件
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
以下是语义顺序,不是要求四端照搬同一函数:
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
校验 class、场景、SDK 协议及版本
|
|
112
|
+
若 sdk_control 为明文或群消息:拒绝
|
|
113
|
+
若 control 未协商:移除可改写的类别字段
|
|
114
|
+
若 sdk_control 未协商:仅省略传输类别
|
|
115
|
+
明文直接发送;待加密正文按准备结果构造信封
|
|
116
|
+
已签名信封保持不变,交配套服务选择通道
|
|
117
|
+
接收按可信身份与受保护语义分派
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Python 群分类 Pull 已由外层序列化,内部直接 fetch,避免同一请求重复进入同一闸门等待自身。移植时保留原有 Pull/ACK、水位与设备范围检查,只移除这一层重复等待。
|
|
121
|
+
|
|
122
|
+
实现入口:[Python 准备与接收](../../python/src/aun_core/_client/control_messages.py)/[RPC](../../python/src/aun_core/_client/rpc_pipeline.py)、[TS RPC](../../ts/src/client/rpc-pipeline.ts)/[接收](../../ts/src/client/control-messages.ts)、[JS RPC](../../js/src/client/rpc-pipeline.ts)/[接收](../../js/src/client/control-messages.ts)、[Go 类别](../../go/control_messages.go)/[V2 路由](../../go/v2_routing.go)/[P2P](../../go/client_v2_e2ee.go)/[群](../../go/v2_group.go)。
|
|
123
|
+
|
|
124
|
+
## 3. Ownership:批次归组,单项仍独立完成
|
|
125
|
+
|
|
126
|
+
### 3.1 API 和固定上下文
|
|
127
|
+
|
|
128
|
+
| 层 | Python | TS/JS | Go |
|
|
129
|
+
| --- | --- | --- | --- |
|
|
130
|
+
| 申请选项 | `batch_id` 关键字 | `OwnershipRequestOptions.batchId` | `OwnershipRequestOptions.BatchID` |
|
|
131
|
+
| 绑定/转移 | `bind_owner_aid/bind_sub_aid/transfer_sub_aid` | `bindOwneraid/bindSubaid/transferSubaid` | `BindOwneraid/BindSubaid/TransferSubaid` |
|
|
132
|
+
| 批量审批 | `accept_ownership_requests/reject_ownership_requests` | `acceptOwnershipRequests/rejectOwnershipRequests` | `AcceptOwnershipRequests/RejectOwnershipRequests` |
|
|
133
|
+
| 传输字段 | 可选 UUIDv4 `batch_id` | 同左 | 同左 |
|
|
134
|
+
|
|
135
|
+
原单项调用兼容。`batch_id` 贯穿任务上下文、Ownership 请求和应用事件;同一批次可涉及多个 AID,但每项保持自己的 `operation_id`。批次不是审批权限,也不替代已认证的原始请求。
|
|
136
|
+
|
|
137
|
+
同一操作的发送者或原始上下文发生变化,包括增删/修改 `batch_id`,按冲突处理。应用将选择的操作 ID 列表交给审批接口;SDK 去重、逐项检查当前身份及代际,Go 还检查 context,返回 `total/succeeded/failed/results`。
|
|
138
|
+
|
|
139
|
+
### 3.2 请求与审批链路
|
|
140
|
+
|
|
141
|
+
```mermaid
|
|
142
|
+
sequenceDiagram
|
|
143
|
+
autonumber
|
|
144
|
+
participant I as 多个申请 AID 的 SDK
|
|
145
|
+
participant M as AUN 消息投递
|
|
146
|
+
participant O as Owner SDK
|
|
147
|
+
participant A as Owner 应用
|
|
148
|
+
participant N as NS / 名片提交
|
|
149
|
+
loop 每个绑定或转移请求
|
|
150
|
+
I->>M: 独立 operation_id,共用 batch_id
|
|
151
|
+
M-->>O: 原始请求与认证发送方
|
|
152
|
+
O->>O: 核对固定上下文,保存请求
|
|
153
|
+
O-->>A: ownership.request,携带 batch_id
|
|
154
|
+
end
|
|
155
|
+
A->>A: 按批次展示,冻结本次选择的操作 ID
|
|
156
|
+
A->>O: accept / reject requests(operation_ids)
|
|
157
|
+
O->>O: 去重并固定执行身份
|
|
158
|
+
loop 每个 operation_id
|
|
159
|
+
O->>O: 检查原请求、当前身份及代际
|
|
160
|
+
O->>N: 沿用单项刷新、校验与提交流程
|
|
161
|
+
N-->>O: 单项当前结果
|
|
162
|
+
O->>O: 保存该项结果或错误,继续其它项
|
|
163
|
+
end
|
|
164
|
+
O-->>A: 汇总与逐项结果
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
批量返回中的成功数表示本次单项接口执行结果,后续关系是否已达共识仍以单项状态/既有工作流为准;`waiting` 不能被应用解释为全部关系已绑定完成。中途失败不会将整个批次回滚,身份变化后剩余项按错误记录。
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
ids = 按首次出现顺序去重(operation_ids)
|
|
171
|
+
identity = 当前 AID 与身份代际
|
|
172
|
+
对每个 id:
|
|
173
|
+
核对 identity 与原始认证请求
|
|
174
|
+
执行原有单项 accept 或 reject
|
|
175
|
+
记录单项结果或错误
|
|
176
|
+
返回汇总和 results
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
实现:[Python 消息校验](../../python/src/aun_core/ownership_v21.py)/[workflow](../../python/src/aun_core/ownership_workflow.py)/[门面](../../python/src/aun_core/client.py)、[TS workflow](../../ts/src/ownership-workflow.ts)/[门面](../../ts/src/client.ts)、[JS workflow](../../js/src/ownership-workflow.ts)/[门面](../../js/src/client.ts)、[Go workflow](../../go/ownership_workflow.go)。该批次扩展不新增服务器批量审批 RPC。
|
|
180
|
+
|
|
181
|
+
## 4. 本地 agent.md 与共识:有效快照优先,管理仍刷新
|
|
182
|
+
|
|
183
|
+
启动/连接后先读取本地名片。新的 Client 首次查询也可恢复已保存的 `ownership_snapshot`;恢复条件须同时成立:
|
|
184
|
+
|
|
185
|
+
| 核对项 | 要求 |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| 共识和范围 | `status=consensus`、锁定、目标 AID 一致 |
|
|
188
|
+
| 远端观察 | 快照 ETag 非空,与记录已观察远端 ETag 一致,记录不为 missing |
|
|
189
|
+
| 本地正文 | 正文 SHA256 与快照摘要一致 |
|
|
190
|
+
| 关系声明 | 名片中 owner、关系版本与快照一致 |
|
|
191
|
+
|
|
192
|
+
```mermaid
|
|
193
|
+
sequenceDiagram
|
|
194
|
+
autonumber
|
|
195
|
+
participant A as 连接 / 查询调用方
|
|
196
|
+
participant C as Client / AgentMdManager
|
|
197
|
+
participant L as 本地身份仓库
|
|
198
|
+
participant N as NS
|
|
199
|
+
A->>C: 连接后读取或首次共识查询
|
|
200
|
+
C->>L: 载入正文、观察记录与快照
|
|
201
|
+
L-->>C: 本地记录
|
|
202
|
+
alt 非 force,内存或持久快照有效
|
|
203
|
+
C-->>A: 复用本地结果
|
|
204
|
+
else 未达共识、记录变化或 force
|
|
205
|
+
C->>N: 原有权威读取
|
|
206
|
+
N-->>C: 当前关系与名片
|
|
207
|
+
C->>C: 核对关系、正文和观察代际
|
|
208
|
+
C->>L: 仅当前观察仍匹配时保存快照
|
|
209
|
+
C-->>A: 当前结果
|
|
210
|
+
end
|
|
211
|
+
Note over C,N: 绑定、审批、转移、释放等管理流程继续强制刷新
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
这里的 ETag 是 SDK 已观察到的状态;本地复用不会主动证明远端此刻没有变化。收到名片/Ownership 变化后清理相关快照,未达共识或显式强刷再查询,保持事件驱动,不新增周期首查任务。
|
|
215
|
+
|
|
216
|
+
查询完成写回前要核对 Client、manager/存储根、缓存对象及观察版本,避免旧身份或旧请求覆盖新记录。群/组织首次访问同样复用有效本地共识;管理方法内部的强制刷新保持不变。
|
|
217
|
+
|
|
218
|
+
实现:[Python manager](../../python/src/aun_core/agent_md.py)/[client](../../python/src/aun_core/client.py)、[TS manager](../../ts/src/agent-md.ts)/[client](../../ts/src/client.ts)、[JS manager](../../js/src/agent-md.ts)/[client](../../js/src/client.ts)、[Go client](../../go/client.go)。
|
|
219
|
+
|
|
220
|
+
## 5. Storage ACL:从门面贯通到 RPC
|
|
221
|
+
|
|
222
|
+
| 层 | 新列表参数 | 旧参数兼容 |
|
|
223
|
+
| --- | --- | --- |
|
|
224
|
+
| Python VFS/LowLevel | `grantee_aids` | `grantee_aid` |
|
|
225
|
+
| TS/JS VFS/LowLevel | `granteeAids` | `granteeAid` |
|
|
226
|
+
| Go VFS 选项 | `GranteeAIDs` | `GranteeAID` |
|
|
227
|
+
| Go LowLevel | 原位置参数后可选 `[]string` | 原位置参数原样可用 |
|
|
228
|
+
| RPC `storage.set_acl/remove_acl` | `grantee_aids` 数组,允许单元素 | `grantee_aid` |
|
|
229
|
+
|
|
230
|
+
Storage 服务合并并归一化、去重两种字段,owner/grantee 的数据库访问和缓存键统一大小写;`max_uses` 对每个 AID 分别计数。SDK 透传授权意图,权限和次数判断留在服务端。
|
|
231
|
+
|
|
232
|
+
```mermaid
|
|
233
|
+
sequenceDiagram
|
|
234
|
+
autonumber
|
|
235
|
+
participant A as 应用
|
|
236
|
+
participant V as VFS / LowLevel
|
|
237
|
+
participant C as SDK 读缓存包装层
|
|
238
|
+
participant S as Storage,经 Gateway
|
|
239
|
+
A->>V: set / remove ACL,多 AID
|
|
240
|
+
V->>C: path + grantee_aids,兼容旧单值
|
|
241
|
+
C->>S: storage.set_acl / remove_acl
|
|
242
|
+
S->>S: 归一化、去重,逐项写入
|
|
243
|
+
alt 全部完成
|
|
244
|
+
S-->>C: 成功结果
|
|
245
|
+
C->>C: 定向失效受影响路径
|
|
246
|
+
C-->>A: 原结果
|
|
247
|
+
else 中途失败,可能已有部分写入
|
|
248
|
+
S-->>C: 原 RPC 错误
|
|
249
|
+
C->>C: 同样定向失效受影响路径
|
|
250
|
+
C-->>A: 继续抛出原错误
|
|
251
|
+
end
|
|
252
|
+
Note over C,S: 保留无关路径缓存;不承诺整个批次事务回滚
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
缓存失效需覆盖 Raw 调用、LowLevel 与 VFS。Go 的 mock/自定义 client LowLevel 路径也在错误返回前失效;Python 异常路径含取消后仍可能已有写入的情况。复用原有资源范围与在途回填保护,避免清空整个 Storage 缓存。
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
尝试执行 ACL RPC
|
|
259
|
+
成功:按既有规则失效相关路径并返回
|
|
260
|
+
异常:对 set_acl / remove_acl 失效同一资源范围
|
|
261
|
+
重新抛出原异常
|
|
262
|
+
保留无关资源缓存
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
入口:[Python VFS](../../python/src/aun_core/storage/vfs.py)/[LowLevel](../../python/src/aun_core/storage/lowlevel.py)/[cache](../../python/src/aun_core/storage/cache.py)、[TS VFS](../../ts/src/storage/vfs.ts)/[LowLevel](../../ts/src/storage/lowlevel.ts)/[cache](../../ts/src/storage/read-cache.ts)、[JS VFS](../../js/src/storage/vfs.ts)/[LowLevel](../../js/src/storage/lowlevel.ts)/[cache](../../js/src/storage/read-cache.ts)、[Go VFS](../../go/storage_vfs.go)/[LowLevel](../../go/storage_lowlevel.go)/[Call](../../go/client.go)。
|
|
266
|
+
|
|
267
|
+
对象上传、下载票据及共享链接的冗余返回字段精简属于配套服务响应契约变化,元数据保存方式保持原有设计。字段以 [Storage RPC 手册](09-storage-rpc-manual.md)为准;移植者不要重新依赖已移除的空值或重复 URL 字段。
|
|
268
|
+
|
|
269
|
+
## 6. Python 独有实现与工具
|
|
270
|
+
|
|
271
|
+
| 改动 | 当前行为 | 移植边界 |
|
|
272
|
+
| --- | --- | --- |
|
|
273
|
+
| 退避提示 | 有效正数 `retry_after_seconds/retry_after_ms` 优先,多个取较长值 | 本轮其它 SDK 没有相同退避调整 |
|
|
274
|
+
| 缺少提示的拥塞 | `-32029/-32429` 且消息含 queue、backpressure、capacity 等拥塞标记,默认 1 秒 | 其它限流默认 60 秒;不因此自动重试应用写请求 |
|
|
275
|
+
| 群分类 Pull | 外层已串行时内部直接 fetch | 保留 cursor/ACK 检查及原调度预算 |
|
|
276
|
+
| 容量压测 | `aun bench run/report`,16 场景、多进程/身份通道、预算与续跑、JSON/HTML | Python CLI 能力,不是要求四端新增网络协议 |
|
|
277
|
+
|
|
278
|
+
退避入口为 [transport](../../python/src/aun_core/transport.py)。容量工具由 [bench](../../python/src/aun_cli/commands/bench.py)注册 [bench_capacity](../../python/src/aun_cli/commands/bench_capacity.py),实现拆分为[场景](../../python/src/aun_cli/benchmark/scenarios.py)、[执行与报告](../../python/src/aun_cli/benchmark/runner.py)、[节奏统计](../../python/src/aun_cli/benchmark/runtime.py)、[搜索](../../python/src/aun_cli/benchmark/search.py)。多进程入口与结果协议由工具自行处理,不影响 SDK Client 的单进程 API。
|
|
279
|
+
|
|
280
|
+
报告区分有效完成量、延迟达标容量、稳态吞吐与发压端瓶颈;`pubsub` 场景包含发压端 Bus,不能解释为纯服务端容量。生成器不足、搜索未界定或持续验证未通过时,保留相应边界,不标记为已确认容量。
|
|
281
|
+
|
|
282
|
+
## 7. 四端回归与移植验收
|
|
283
|
+
|
|
284
|
+
| 范围 | Python | TS/JS | Go |
|
|
285
|
+
| --- | --- | --- | --- |
|
|
286
|
+
| 发送/接收类别 | [components](../../python/tests/unit/test_client_components.py) | 各端 `tests/unit/rpc-pipeline.test.ts`、`client.test.ts` | [client](../../go/client_test.go)、[V2 parity](../../go/v2_python_parity_test.go) |
|
|
287
|
+
| 批次与审批 | [workflow](../../python/tests/unit/test_ownership_workflow.py) | 各端 `tests/unit/ownership-workflow.test.ts` | [workflow](../../go/ownership_workflow_test.go) |
|
|
288
|
+
| 本地共识/管理强刷 | [agent.md](../../python/tests/unit/test_client_agent_md_api.py) | 各端 `tests/unit/client-agent-md-api.test.ts` | [agent.md](../../go/client_agent_md_api_test.go) |
|
|
289
|
+
| ACL 与错误缓存 | [cache](../../python/tests/unit/test_storage_read_cache.py)、VFS 测试 | TS `storage-read-cache.test.ts`;JS `storage-vfs-read-cache.test.ts`;各端 VFS 测试 | [cache](../../go/storage_read_cache_test.go)、[VFS](../../go/storage_vfs_test.go) |
|
|
290
|
+
|
|
291
|
+
实现验收按顺序检查:
|
|
292
|
+
|
|
293
|
+
1. 明文/加密应用控制消息在 P2P 和群中均可发送;能力缺失时走普通通道,TTL 保留,普通消息继续交付。
|
|
294
|
+
2. P2P 加密 SDK 控制降级后仍经 SDK 消费;群及明文 SDK 控制发送前拒绝;冲突元数据不被静默改写。
|
|
295
|
+
3. 同批绑定与转移贯穿 UUIDv4 批次,原调用兼容;重复 ID 去重,失败结果逐项保留,身份变化后不继续以旧身份审批。
|
|
296
|
+
4. 新 Client/重连复用有效本地记录;改变 ETag/正文/关系或显式 force 时查询;管理流程仍刷新,旧异步结果不覆盖新观察。
|
|
297
|
+
5. VFS/LowLevel/Raw 批量 ACL、单元素列表和旧单值均有效;每 AID 独立计数,部分失败后相关缓存失效、无关缓存保留。
|
|
298
|
+
6. 分别验收四端,再用跨 SDK runner 验证互通;保留实际版本、服务端版本、失败项和结果产物。
|
|
299
|
+
|
|
300
|
+
[控制消息矩阵 runner](../../tests/cross-sdk/runner/run_control_matrix_e2e.py)定义 96 格:4 发送 SDK × 2 发送端能力状态 × 3 类别 × 2 加密状态 × P2P/群。合法格检查其它三个 SDK 接收,无效格预期发送前拒绝;首失败停止并保存断点。
|
|
301
|
+
|
|
302
|
+
该矩阵使用 TTL=60、`aun.agent_md.changed` v1,接收端保持能力启用,未覆盖接收端单独缺能力或两端均缺能力的全部组合,也不替代 EventService `aun.pubsub` 验收。Go 观察点与能力开关受 `crosssdk` 构建标签控制,普通构建走 stub。
|
|
303
|
+
|
|
304
|
+
本轮仅编写指南并做文档校验,没有重新执行 SDK 全量、跨 SDK E2E 或容量压测。既有版本校验和定向测试记录见 [parity 验证边界](../../python/CHANGES_FOR_PARITY.md#v0533),不能将 runner 中的成功输出条件当作已取得的 96/96 通过产物。
|
|
@@ -197,19 +197,32 @@ Node.js TypeScript、Python、Go 的索引位于 `{aunPath}/.cache/storage/index
|
|
|
197
197
|
|
|
198
198
|
### 响应
|
|
199
199
|
|
|
200
|
+
返回写入后的对象元数据。URL 字段收敛为 `url` 和 `logical_url`,供后续 HTTP 读取使用;私有对象仍须通过访问鉴权。SDK 需要 HTTP 下载时,使用 `storage.create_download_ticket` 响应中的地址。
|
|
201
|
+
|
|
200
202
|
| 字段 | 类型 | 说明 |
|
|
201
203
|
|------|------|------|
|
|
202
204
|
| `url` | string | **AID 风格 URL(默认/推荐)**:`https://{owner_aid}/{object_key}`,经 NameService fallback 302 跳转到 storage 服务 |
|
|
203
205
|
| `logical_url` | string | 直链 URL:`https://storage.{issuer}/{user}/{object_key}`,直达 storage 服务,无跳转 |
|
|
206
|
+
| `node_type` | string | 固定为 `"object"` |
|
|
207
|
+
| `type` | string | 固定为 `"file"` |
|
|
208
|
+
| `object_id` | string | 对象 ID |
|
|
204
209
|
| `owner_aid` | string | 所有者 AID |
|
|
205
210
|
| `bucket` | string | 存储桶 |
|
|
206
211
|
| `object_key` | string | 对象路径 |
|
|
212
|
+
| `parent_folder_id` | string | 父目录 ID |
|
|
213
|
+
| `name` | string | 文件名 |
|
|
214
|
+
| `path` | string | 对象路径,与 `object_key` 相同 |
|
|
207
215
|
| `size_bytes` | integer | 对象大小(字节) |
|
|
208
216
|
| `content_type` | string | MIME 类型 |
|
|
209
217
|
| `sha256` | string | SHA-256 哈希 |
|
|
210
218
|
| `version` | integer | 版本号 |
|
|
211
219
|
| `etag` | string | 实体标签 |
|
|
212
|
-
| `
|
|
220
|
+
| `is_private` | boolean | 是否私有 |
|
|
221
|
+
| `expire_at` | integer | 过期时间戳(秒),`0` 表示不过期 |
|
|
222
|
+
| `created_at` | integer | 创建时间戳(毫秒) |
|
|
223
|
+
| `updated_at` | integer | 更新时间戳(毫秒) |
|
|
224
|
+
| `status` | string | 对象状态,通常为 `"active"` |
|
|
225
|
+
| `metadata` | object | 自定义元数据,未设置时为 `{}` |
|
|
213
226
|
|
|
214
227
|
### 示例
|
|
215
228
|
|
|
@@ -883,16 +896,14 @@ else:
|
|
|
883
896
|
| 字段 | 类型 | 说明 |
|
|
884
897
|
|------|------|------|
|
|
885
898
|
| `share_id` | string | 10 位 Base62 分享短码 |
|
|
886
|
-
| `url` | string |
|
|
887
|
-
| `
|
|
888
|
-
| `
|
|
889
|
-
| `share_url` | string | storage 直链:`https://storage.{issuer}/s/{share_id}`,兼容字段 |
|
|
890
|
-
| `expire_at` | integer | 过期时间戳(Unix 秒),`0` 表示永不过期 |
|
|
899
|
+
| `url` | string | 默认分享 URL:`https://{owner_aid}/s/{share_id}`,经 NameService 跳转 |
|
|
900
|
+
| `share_url` | string | Storage 直链:`https://storage.{issuer}/s/{share_id}`,直接访问 Storage 服务 |
|
|
901
|
+
| `expire_at` | integer | 分享链接过期时间戳(Unix 秒),`0` 表示永不过期 |
|
|
891
902
|
| `max_uses` | integer | 最大使用次数,`0` 表示无限制 |
|
|
892
903
|
| `allowed_aids` | string[] | 授权 AID 列表,`["*"]` 表示公开 |
|
|
904
|
+
| `target` | object | 被分享对象的元数据,不包含空 URL 字段;其中 `expire_at` 为对象过期时间 |
|
|
893
905
|
|
|
894
|
-
>
|
|
895
|
-
> 访问 `url` 时经 NameService 302 跳转到 `storage.{issuer}/s/{share_id}`;访问 `path_url` 时经 NameService fallback 到 storage,由 `?t=` token 鉴权。
|
|
906
|
+
> `url` 经 NameService 302 跳转到 `share_url`;两者都通过 `share_id` 定位到同一条分享记录鉴权。
|
|
896
907
|
> share_id 指向 `(owner_aid, bucket, object_key)` 逻辑引用,非内容快照:对象改名/移动后原 share_id 失效,内容覆盖后下载到新内容。
|
|
897
908
|
|
|
898
909
|
### 示例
|
|
@@ -932,10 +943,10 @@ share_url = result["url"] # https://alice.agentid.pub/s/Ab3xK9mZ2q
|
|
|
932
943
|
|------|------|------|
|
|
933
944
|
| `share_id` | string | 分享短码 |
|
|
934
945
|
| `url` | string | 默认分享 URL(隐藏路径):`https://{owner_aid}/s/{share_id}` |
|
|
935
|
-
| `
|
|
936
|
-
| `aid_share_url` | string | 同 `url`(兼容旧字段) |
|
|
937
|
-
| `share_url` | string | storage 直链(兼容) |
|
|
946
|
+
| `share_url` | string | Storage 直链:`https://storage.{issuer}/s/{share_id}` |
|
|
938
947
|
| `object_key` | string | 被分享对象路径 |
|
|
948
|
+
| `target_type` | string | 分享目标类型 |
|
|
949
|
+
| `target_id` | string | 分享目标 ID |
|
|
939
950
|
| `bucket` | string | 存储桶 |
|
|
940
951
|
| `allowed_aids` | string[] | 授权 AID 列表,`["*"]` 表示公开 |
|
|
941
952
|
| `expire_at` | integer | 过期时间戳(秒),`0` 表示永不过期 |
|
|
@@ -1424,16 +1435,19 @@ fs 目录节点视图。
|
|
|
1424
1435
|
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
|
1425
1436
|
|------|------|------|------|------|
|
|
1426
1437
|
| `path` | string | 是 | — | 授权路径前缀 |
|
|
1427
|
-
| `
|
|
1438
|
+
| `grantee_aids` | string[] | 二选一 | — | 一个或多个被授权 AID;优先于兼容字段;`role:*` 仅限 group 内部调用 |
|
|
1439
|
+
| `grantee_aid` | string | 二选一 | — | 兼容旧调用的单个 AID;未提供 `grantee_aids` 时使用 |
|
|
1428
1440
|
| `perms` | string | 是 | — | 权限位:`r` 读取、`w` 写入、`x` 删除,可组合 |
|
|
1429
1441
|
| `owner_aid` | string | 否 | 当前用户 | 所有者 AID |
|
|
1430
1442
|
| `bucket` | string | 否 | `"default"` | 存储桶 |
|
|
1431
1443
|
| `expires_at` | integer | 否 | — | 授权过期时间 |
|
|
1432
|
-
| `max_uses` | integer | 否 | — |
|
|
1444
|
+
| `max_uses` | integer | 否 | — | 每个被授权 AID 的最大使用次数,分别计数;0 表示不限次数 |
|
|
1433
1445
|
|
|
1434
1446
|
### 响应
|
|
1435
1447
|
|
|
1436
|
-
ACL
|
|
1448
|
+
使用 `grantee_aids` 返回 `{acls: [ACL视图, ...]}`,单元素数组也返回此结构;仅使用兼容字段 `grantee_aid` 时仍返回单条 ACL 视图。每个 AID 独立保存 `max_uses` 和 `used_count`。
|
|
1449
|
+
|
|
1450
|
+
`grantee_aids` 不能为空数组,元素不能为空;重复 AID 去重并保留首次顺序。先校验整批参数,再逐项写入;存储错误会中断,已完成项保留。
|
|
1437
1451
|
|
|
1438
1452
|
---
|
|
1439
1453
|
|
|
@@ -1446,13 +1460,16 @@ ACL 视图。
|
|
|
1446
1460
|
| 参数 | 类型 | 必填 | 默认 | 说明 |
|
|
1447
1461
|
|------|------|------|------|------|
|
|
1448
1462
|
| `path` | string | 是 | — | 授权路径前缀 |
|
|
1449
|
-
| `
|
|
1463
|
+
| `grantee_aids` | string[] | 二选一 | — | 一个或多个待撤销 AID;优先于兼容字段 |
|
|
1464
|
+
| `grantee_aid` | string | 二选一 | — | 兼容旧调用的单个 AID;未提供 `grantee_aids` 时使用 |
|
|
1450
1465
|
| `owner_aid` | string | 否 | 当前用户 | 所有者 AID |
|
|
1451
1466
|
| `bucket` | string | 否 | `"default"` | 存储桶 |
|
|
1452
1467
|
|
|
1453
1468
|
### 响应
|
|
1454
1469
|
|
|
1455
|
-
`{removed: boolean, owner_aid, bucket, path, grantee_aid}`。
|
|
1470
|
+
使用 `grantee_aids` 返回 `{results: [{removed: boolean, owner_aid, bucket, path, grantee_aid}, ...]}`;单元素数组也返回此结构。仅使用 `grantee_aid` 时仍返回 `{removed: boolean, owner_aid, bucket, path, grantee_aid}`。
|
|
1471
|
+
|
|
1472
|
+
数组校验和去重规则与 `storage.set_acl` 一致;逐项撤销,存储错误会中断并保留已完成项。
|
|
1456
1473
|
|
|
1457
1474
|
---
|
|
1458
1475
|
|
package/dist/agent-md.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AID } from './aid.js';
|
|
2
2
|
import { type OwnershipRelease, type OwnershipVerificationStatus } from './ownership-proof.js';
|
|
3
3
|
import type { ModuleLogger } from './logger.js';
|
|
4
|
-
import { type OwnershipAgentObservation, type OwnershipSavedFile } from './ownership-v21.js';
|
|
4
|
+
import { type OwnershipAgentObservation, type OwnershipConsensusResult, type OwnershipSavedFile } from './ownership-v21.js';
|
|
5
5
|
export declare function buildOwnershipReleaseAgentMd(content: string, release: OwnershipRelease): string;
|
|
6
6
|
export declare function buildOwnershipAgentMd(content: string, owner: string, proof: Record<string, unknown>): string;
|
|
7
7
|
export declare function updateOwnershipAgentMd(content: string, fields: Record<string, unknown>): string;
|
|
@@ -137,6 +137,7 @@ export declare class AgentMdManager {
|
|
|
137
137
|
version: number;
|
|
138
138
|
content_hash: string;
|
|
139
139
|
}): boolean;
|
|
140
|
+
localOwnershipConsensus(aid: string, record: Record<string, unknown> | null): OwnershipConsensusResult | null;
|
|
140
141
|
private _clearConfirmedDraft;
|
|
141
142
|
upload(content?: string | null, originalCondition?: OwnershipSavedFile['condition']): Promise<Record<string, unknown>>;
|
|
142
143
|
readAgentMdFresh(aid: string): Promise<{
|
package/dist/agent-md.js
CHANGED
|
@@ -440,6 +440,23 @@ export class AgentMdManager {
|
|
|
440
440
|
return true;
|
|
441
441
|
});
|
|
442
442
|
}
|
|
443
|
+
localOwnershipConsensus(aid, record) {
|
|
444
|
+
const snapshot = record?.ownership_snapshot;
|
|
445
|
+
if (!snapshot || snapshot.status !== 'consensus' || snapshot.sub_aid !== aid || snapshot.lock !== 'locked'
|
|
446
|
+
|| !snapshot.agent_md_etag || snapshot.agent_md_etag !== record?.remote_etag || record.remote_status === 'missing'
|
|
447
|
+
|| typeof record.content !== 'string' || AgentMdManager.contentEtag(record.content).slice(1, -1) !== snapshot.agent_md_sha256)
|
|
448
|
+
return null;
|
|
449
|
+
try {
|
|
450
|
+
const statement = parseOwnershipFile(record.content, 'agent', { expectedSubAid: aid }).statement;
|
|
451
|
+
if (!statement || statement.owner_aid !== snapshot.owner_aid || statement.relation_version !== snapshot.relation_version)
|
|
452
|
+
return null;
|
|
453
|
+
return { status: 'consensus', sub_aid: aid, owner_aid: statement.owner_aid, relation_version: statement.relation_version,
|
|
454
|
+
lock: 'locked', agent_md_etag: snapshot.agent_md_etag, agent_md_sha256: snapshot.agent_md_sha256 };
|
|
455
|
+
}
|
|
456
|
+
catch {
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
443
460
|
_clearConfirmedDraft(aid, content) {
|
|
444
461
|
this._withRecordLock(aid, () => {
|
|
445
462
|
const record = this._readRecordUnlocked(aid, true);
|