@agentunion/fastaun 0.5.24 → 0.5.26
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 +29 -0
- package/_packed_docs/CHANGELOG.md +29 -0
- package/_packed_docs/TS/346/263/250/345/206/214/350/207/252/345/212/250/347/273/221/345/256/232Owner/347/232/204E2E/351/252/214/350/257/201/344/273/243/347/240/201.md +196 -0
- package/_packed_docs/protocol/Ownership/345/215/217/350/256/256/345/256/232/344/271/2112.1.md +2 -2
- package/_packed_docs/sdk/0.5.24-SDK/345/272/224/347/224/250/351/233/206/346/210/220/346/214/207/345/215/227.md +401 -0
- package/_packed_docs/sdk/0.5.24-SDK/345/274/200/345/217/221/344/270/216/347/247/273/346/244/215/346/214/207/345/215/227.md +354 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +4 -0
- package/_packed_docs/sdk/INDEX.md +9 -0
- 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
- package/dist/agent-md.d.ts +1 -0
- package/dist/agent-md.js +38 -10
- package/dist/agent-md.js.map +1 -1
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +44 -10
- package/dist/auth.js.map +1 -1
- package/dist/client/delivery.d.ts +3 -0
- package/dist/client/delivery.js +197 -47
- package/dist/client/delivery.js.map +1 -1
- package/dist/client/rpc-pipeline.js +10 -0
- package/dist/client/rpc-pipeline.js.map +1 -1
- package/dist/client/v2-e2ee.js +17 -5
- package/dist/client/v2-e2ee.js.map +1 -1
- package/dist/client.d.ts +1 -0
- package/dist/client.js +43 -25
- package/dist/client.js.map +1 -1
- package/dist/group-fs.js +5 -0
- package/dist/group-fs.js.map +1 -1
- package/dist/keystore/local-identity-store.js +16 -1
- package/dist/keystore/local-identity-store.js.map +1 -1
- package/dist/keystore/local-token-store.js +16 -1
- package/dist/keystore/local-token-store.js.map +1 -1
- package/dist/ownership-v21.d.ts +2 -0
- package/dist/ownership-v21.js +61 -30
- package/dist/ownership-v21.js.map +1 -1
- package/dist/tools/cross-sdk-agent.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/src/certs/root.crt +13 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
# AUN SDK 0.5.24 应用集成指南
|
|
2
|
+
|
|
3
|
+
面向应用开发者,按当前 `0.5.24` 待发布工作区整理。Node.js 示例使用 `@agentunion/fastaun`,浏览器使用 `@agentunion/fastaun-browser`;使用前核对实际安装产物,本文不表示最终发布包已经完成联网验收。实现契约见 [0.5.24 开发与移植指南](0.5.24-SDK开发与移植指南.md)。
|
|
4
|
+
|
|
5
|
+
## 1. 当前能力与升级范围
|
|
6
|
+
|
|
7
|
+
Python/TypeScript/JavaScript 的升级基线为真实 `0.5.23` 发布包;Go 按本轮约定从 `0.5.22` 对照。详细依据及测试记录见 [版本对照](../../python/CHANGES_FOR_PARITY.md)。
|
|
8
|
+
|
|
9
|
+
| 领域 | 应用接入要求 | 本轮边界 |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| 消息 | 持久处理完成后交付 ACK,业务幂等保存 | 沿用既有 batch、peer Pull、背压和退避 |
|
|
12
|
+
| Ownership | 文件提交与通知当次执行,以 NS 当前事实验收 | 移除专用任务与审批持久化,不维护 WAL 或连接后续跑;增加两种本地编排 |
|
|
13
|
+
| 注册 owner | 注册当次发出绑定,owner 仍须确认 | 不再等待 connect 后补发旧意图 |
|
|
14
|
+
| resolve | 按名片 ETag/正文观察复用展示快照 | 三端 0.5.23 已有观察缓存,本轮修复错配、查询合并与旧结果回填 |
|
|
15
|
+
| PKI/Credential 查询 | 复用不可变材料和受期限约束的验证结果 | 三端 0.5.23 已有;Go 从较早基线补齐对应增量 |
|
|
16
|
+
| Storage/Group FS | 默认 60 秒读缓存,必要时刷新 | 承继能力,与 Ownership 展示快照不是同一策略 |
|
|
17
|
+
| Credential/Org 编排 | 保留身份、原请求、候选密钥和持久 checkpoint | 不随 Ownership 简化删除 |
|
|
18
|
+
|
|
19
|
+
普通聊天先接身份、消息和连接;需要 owner 展示时才启用关系快照。涉及管理、组织和 CAP 的操作,再接相应的权威检查与请求绑定。
|
|
20
|
+
|
|
21
|
+
## 2. 身份、注册与连接
|
|
22
|
+
|
|
23
|
+
### 2.1 Node.js 加载已有身份
|
|
24
|
+
|
|
25
|
+
Node.js 要求 `>=22.16.0`。固定可恢复的 `aunPath`、解密 seed、设备和消费 slot;密钥、token、凭证/组织 checkpoint 由 SDK 管理,应用消息另存业务数据库。TLS 信任配置见 [连接与认证](04-连接与认证.md),服务地址使用 `{svc}.{issuer}`。
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { AIDStore, AUNClient } from '@agentunion/fastaun';
|
|
29
|
+
const store = new AIDStore({
|
|
30
|
+
aunPath: process.env.AUN_PATH!, encryptionSeed: process.env.AUN_SEED ?? '',
|
|
31
|
+
slotId: 'main', verifySsl: true,
|
|
32
|
+
});
|
|
33
|
+
const loaded = store.load('helper.agentid.cn');
|
|
34
|
+
if (!loaded.ok) throw new Error(loaded.error.message);
|
|
35
|
+
if (!loaded.data.aid.isPrivateKeyValid()) throw new Error('本身份私钥不可用');
|
|
36
|
+
const client = new AUNClient(loaded.data.aid);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`AUNClient` 接收 AID 对象,不传 AID 字符串或旧构造配置。已有身份直接加载,不在每次启动时注册;连接前先完成第 3 节订阅。
|
|
40
|
+
|
|
41
|
+
### 2.2 首次注册及带 owner 注册
|
|
42
|
+
|
|
43
|
+
仅在明确创建新身份时执行:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
const registered = await store.register('helper.agentid.cn', { type: 'agent' });
|
|
47
|
+
if (!registered.ok) throw new Error(registered.error.message);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
普通 agent 可省略 owner。需要 human owner 时,也可在首次注册携带它:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
const registered = await store.register('another.agentid.cn', {
|
|
54
|
+
type: 'agent', owner: 'human.agentid.cn',
|
|
55
|
+
});
|
|
56
|
+
if (!registered.ok) throw new Error(registered.error.message);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
带 owner 注册先初始化无关系的 `agent.md`,再于本次调用中使用 `ownership-UUID` 专属短连接提交绑定、发送通知,最后关闭。owner 仍须确认,`registered: true` 不等于归属成立;不要等连接后自动补发。调用失败时身份可能已经注册并保存,先 load、查询 NS,再显式发起绑定,不能直接重注册。`human` 不能声明 owner;Group/Org 使用专属实体生命周期。
|
|
60
|
+
|
|
61
|
+
### 2.3 浏览器身份
|
|
62
|
+
|
|
63
|
+
浏览器 `load()` 需 await;身份、token 和缓存使用 IndexedDB,`aunPath` 是本地命名空间:
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
import { AIDStore as BrowserStore, AUNClient as BrowserClient } from '@agentunion/fastaun-browser';
|
|
67
|
+
const browserStore = new BrowserStore({ aunPath: 'myapp', encryptionSeed: '', slotId: 'main' });
|
|
68
|
+
const browserLoaded = await browserStore.load('helper.agentid.cn');
|
|
69
|
+
if (!browserLoaded.ok) throw new Error(browserLoaded.error.message);
|
|
70
|
+
if (!browserLoaded.data.aid.isPrivateKeyValid()) throw new Error('本身份私钥不可用');
|
|
71
|
+
const browserClient = new BrowserClient(browserLoaded.data.aid);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
浏览器 HTTPS 信任由运行环境控制;不能复制 Node 的磁盘、seed 文件轮换或关闭 TLS 校验方式。后续消息 Facade 用法相同。
|
|
75
|
+
|
|
76
|
+
## 3. 消息持久交付与后台同步
|
|
77
|
+
|
|
78
|
+
### 3.1 先订阅,再连接
|
|
79
|
+
|
|
80
|
+
| 批次事件 | `items` 内的原事件 |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `message.batch` | `message.received`、`message.recalled` |
|
|
83
|
+
| `group.message_batch` | `group.message_created`、`group.message_recalled` |
|
|
84
|
+
| `group.event_batch` | `group.changed` |
|
|
85
|
+
|
|
86
|
+
批次为 `{ namespace, items: [{ event, payload }], source }`,保持页内顺序。`commitDeliveryBatch` 是应用自己的数据库事务:消息、撤回 tombstone 和相关业务记录可靠提交后才完成 Promise。
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
declare function commitDeliveryBatch(batch: unknown): Promise<void>;
|
|
90
|
+
const subscriptions = [
|
|
91
|
+
client.on('message.batch', batch => commitDeliveryBatch(batch)),
|
|
92
|
+
client.on('group.message_batch', batch => commitDeliveryBatch(batch)),
|
|
93
|
+
client.on('group.event_batch', batch => commitDeliveryBatch(batch)),
|
|
94
|
+
];
|
|
95
|
+
await client.connect({ auto_reconnect: true });
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
```mermaid
|
|
99
|
+
flowchart LR
|
|
100
|
+
A[Push 或 Pull 页] --> B[SDK 解密校验并分发批次]
|
|
101
|
+
B --> C[应用事务持久处理]
|
|
102
|
+
C -->|成功返回| D[SDK 推进交付水位与 ACK]
|
|
103
|
+
C -->|抛错或崩溃| E[保留重放责任,应用按业务键幂等]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
必须返回/await 入库 Promise;后台启动写入后立即返回、吞掉异常、空回调均会过早确认交付。按接收身份、会话、消息 ID 和事件语义持久幂等;部分处理成功或事务后崩溃,仍可能整批重放。SDK 运行时去重不替代应用数据库。
|
|
107
|
+
|
|
108
|
+
同类 batch 存在订阅时,该页只发 batch,不再额外发逐条事件;模式在页开始时固定。已有逐条订阅可继续用,详情沿用 [0.5.21 消息契约](0.5.21-SDK应用集成指南.md#3-消息接收发送与同步)。不要在处理器内等待同一实时交付链再次 Pull 分发;不要用页内最大 seq 手动越过未交付消息 ACK。
|
|
109
|
+
|
|
110
|
+
当前 TS/JS 至少需要 `message.received/message.recalled/message.batch` 之一才启动 P2P 后台拉取;仅订阅 `ownership.*` 不够。READY 后补订阅可恢复积压,仍受背压、退避、`background_sync` 与连接代际约束。Ownership 控制消息由 SDK 内部处理,不替应用消费普通消息。
|
|
111
|
+
|
|
112
|
+
### 3.2 发送、peer 与历史
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
const sent = await client.message.send({
|
|
116
|
+
to: 'alice.agentid.cn', payload: { type: 'text', text: '你好' },
|
|
117
|
+
encrypt: true, need_render: true,
|
|
118
|
+
});
|
|
119
|
+
const pendingPeers = await client.message.peers({ filter: 'pending' });
|
|
120
|
+
const peerPage = await client.message.pull({ sender_aid: 'alice.agentid.cn', limit: 200 });
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`need_render` 只影响展示建议,false 仍须正常消费;它不授权业务。发送成功不等于对端入库或已读。`message.peers()` 是服务端消费目录,区别于本地 `client.peers()`;pending 查询不传分页参数,`catalog_ready=false` 须等待,估计跨度不是准确未读数。
|
|
124
|
+
|
|
125
|
+
不带 sender 的 Pull 聚合所有 pending peer,用 `peers/partial` 判断各 peer 结果;指定游标、`force` 或 Tail 时须指定 sender。History 用于浏览,不 ACK、不推进实时水位、不分发实时事件。自动 Pull、手动 Pull 与 Push 共用交付链,返回列表不要重复执行非幂等业务。用户真正阅读后另调 `message.read/group.read`,见 [跨设备已读指南](../跨设备已读未读SDK集成指南.md)。
|
|
126
|
+
|
|
127
|
+
### 3.3 背景退避与界面状态
|
|
128
|
+
|
|
129
|
+
`connect()` 表示连接可用,不表示补拉、凭证续期或应用业务全部完成。连接、`sync.started/progress/stopped` 和业务状态分别展示;`delivery.changed` 仅用于合并刷新,不是当前未读总数。
|
|
130
|
+
|
|
131
|
+
SDK 按 namespace 对可重试后台失败以 1/2/4/8/16/30 秒退避(Python 另有轻微随机抖动),hint 合并需求而不重置尚未到期的退避。无权限、被封禁、群不存在或已解散等群终态停止该群自动同步并保留本地消息。主动操作仍按原错误返回;成功的显式拉取或连接换代可恢复相应门控。不要通过高频手动 Pull、反复 connect 或另建 ACK 循环抵消退避。非 active 群不会按普通 active 群自动恢复提案及追赶;权限以当前服务事实为准。
|
|
132
|
+
|
|
133
|
+
## 4. resolve:名片与按观察复用的关系展示
|
|
134
|
+
|
|
135
|
+
普通 resolve 不额外检查 Ownership,直接读取完整原文及保留 YAML 类型的 frontmatter:
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
const profile = await store.resolve('alice.agentid.cn');
|
|
139
|
+
if (!profile.ok) throw new Error(profile.error.message);
|
|
140
|
+
console.log(profile.data.agent_md?.frontmatter);
|
|
141
|
+
const withOwner = await store.resolve('alice.agentid.cn', { ownership: client });
|
|
142
|
+
if (!withOwner.ok) throw new Error(withOwner.error.message);
|
|
143
|
+
console.log(withOwner.data.ownership?.status, withOwner.data.ownership?.cached);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`ownership` 传已有 client/共识查询器,不是布尔值;不另建连接。自有身份可能返回未发布草稿,扩展 frontmatter 为 unknown,使用前按应用约定收窄类型。
|
|
147
|
+
|
|
148
|
+
| 选项或变化 | 当前行为 |
|
|
149
|
+
| --- | --- |
|
|
150
|
+
| 默认展示快照 | 按 AID、名片 ETag、完整正文 hash 和 observation 复用;没有默认每 60 秒强查 owner.md |
|
|
151
|
+
| `forceRefresh: true` | 刷新远端身份与名片;ETag/正文未变时仍可复用关系快照 |
|
|
152
|
+
| `ownershipTtlMs <= 0` | 显式绕过展示快照,使用内部 fresh checker;正数不恢复旧年龄 TTL 规则 |
|
|
153
|
+
| 名片 ETag/正文变化 | 重新核对快照;查询按 checker 和 observation 合并,旧查询不能覆盖新观察 |
|
|
154
|
+
| `skipAgentMd: true` | 不输出名片;显式 ownership 查询仍可内部读取必要材料 |
|
|
155
|
+
| 额外共识失败 | 外层 resolve 可成功,关系为 unavailable,不能当作 unbound |
|
|
156
|
+
|
|
157
|
+
仅在确实需要最新关系检查时显式调用:
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
const checked = await store.resolve('alice.agentid.cn', {
|
|
161
|
+
forceRefresh: true, ownership: client, ownershipTtlMs: 0,
|
|
162
|
+
});
|
|
163
|
+
if (!checked.ok) throw new Error(checked.error.message);
|
|
164
|
+
console.log(checked.data.ownership?.status);
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`owner.md` 可独立变化,展示快照、`frontmatter.owner` 及 legacy `verification.ownership_status` 不授予权限。公开 `checkOwnershipConsensus()` 每次发 HTTP,携带 Ownership-Check,允许 NS 的 agent.md 缓存;管理流程内部 fresh 检查才要求 no-cache。检查仍读取 Storage owner.md,Storage inline object cache 可以使用。完整返回见 [resolve 输入与输出](06-API手册.md#resolve-输入与输出)。
|
|
168
|
+
|
|
169
|
+
## 5. Ownership:文件提交、NS 验收与本地编排
|
|
170
|
+
|
|
171
|
+
### 5.1 交互绑定、拒绝和转移
|
|
172
|
+
|
|
173
|
+
NS 按当前 sub `agent.md` 和 owner Storage 的 `default/sub_aids/{subAid}/owner.md` 验收;转移另需原 owner 有效授权。SDK 不记录专用任务、WAL 或持久审批,不在 connect 后恢复步骤;当前调用也不先提交 decisions 回执。
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const requested = await client.bindOwneraid('human.agentid.cn');
|
|
177
|
+
if (requested.status === 'error') throw new Error(requested.reason);
|
|
178
|
+
console.log(requested.operation_id, requested.status);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
owner App 在连接前订阅 request,在有权用户点击后才 accept/reject。下面的 `readRequest` 由应用校验通用载荷并提取 ID,`showApproval` 负责界面与异步错误处理:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
declare function readRequest(payload: unknown): { operation_id: string };
|
|
185
|
+
declare function showApproval(request: { operation_id: string }, decide: (accept: boolean) => Promise<void>): void;
|
|
186
|
+
ownerClient.on('ownership.request', payload => {
|
|
187
|
+
const request = readRequest(payload);
|
|
188
|
+
showApproval(request, async accept => {
|
|
189
|
+
const result = accept ? await ownerClient.acceptOwnershipRequest(request.operation_id)
|
|
190
|
+
: await ownerClient.rejectOwnershipRequest(request.operation_id, '用户拒绝');
|
|
191
|
+
console.log(result.status, result.reason);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
```mermaid
|
|
197
|
+
sequenceDiagram
|
|
198
|
+
participant S as sub
|
|
199
|
+
participant O as owner
|
|
200
|
+
participant N as NS
|
|
201
|
+
alt sub 发起
|
|
202
|
+
S->>N: Stage 条件上传本人 agent.md
|
|
203
|
+
S->>O: 加密绑定请求
|
|
204
|
+
O->>O: 用户同意,上传本人 owner.md
|
|
205
|
+
O->>N: 查询/触发验收
|
|
206
|
+
N-->>O: 双文件一致后锁定,sub 无需再次在线
|
|
207
|
+
else owner 发起
|
|
208
|
+
O->>O: 上传本人 owner.md
|
|
209
|
+
O->>S: 加密绑定请求
|
|
210
|
+
S->>N: 用户同意,条件上传本人 agent.md
|
|
211
|
+
N-->>S: 双文件一致后锁定,owner 无需再次在线
|
|
212
|
+
end
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
拒绝只反馈,不删除或回滚文件。未锁定时以最后成功 CAS 上传的 sub 名片为候选:先声明 B 后声明 C,B 同意不能达成当前共识;C 同意可以,C 拒绝则停留单边声明。锁定后迟到 accept/reject 不能改变归属,须释放或转移;锁前不再承诺同一 operation 跨设备唯一决定。
|
|
216
|
+
|
|
217
|
+
| 操作 | 当次行为 |
|
|
218
|
+
| --- | --- |
|
|
219
|
+
| `bindSubaid(subAid)` | owner 上传 owner.md 后通知 sub,同意方上传本人 agent.md |
|
|
220
|
+
| `releaseSubaid(subAid)` | owner 发布同版本 release,sub 可离线;NS released 即失去旧 owner 授权 |
|
|
221
|
+
| `transferSubaid(subAid, newOwnerAid)` | 旧 owner 先发布授权,再分别通知;sub/新 owner 各自同意并上传本人文件,无在线或接受顺序要求 |
|
|
222
|
+
| `acceptOwnershipRequest(id)` | 从已认证原请求执行本人文件动作;SDK 可从正常历史重取,缺失时要求重新发起 |
|
|
223
|
+
| `rejectOwnershipRequest(id, reason)` | 反馈拒绝,不撤销已发布事实或更改已锁归属 |
|
|
224
|
+
|
|
225
|
+
转移材料未齐时,Stage 候选与旧 active 分离,NS 保留旧 owner 锁;一致后原子切换,不走先释放再绑定。合法 release 通知在 sub 当次处理时核验并内部清理;通知无法恢复时可保持 released。普通 `uploadAgentMd` 不能删除关系字段,当前没有公开强制清理 Facade。
|
|
226
|
+
|
|
227
|
+
### 5.2 本地双身份自动绑定
|
|
228
|
+
|
|
229
|
+
Evolcore/EC CLI 持有 daemon 与自己创建的 sub 材料时,使用两个不同普通 agent 的 client。源 client 无须先 connect:
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const bound = await daemonClient.bindLocalSubaid(subClient);
|
|
233
|
+
if (bound.status !== 'completed') throw new Error(bound.reason);
|
|
234
|
+
console.log(bound.sub_aid, bound.owner_aid, bound.target_relation_version);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
```mermaid
|
|
238
|
+
flowchart LR
|
|
239
|
+
A[daemon + sub 两个身份 client] --> B[SDK 创建专属 slot 短连接并认证]
|
|
240
|
+
B --> C[daemon 签发并上传 owner.md]
|
|
241
|
+
C --> D[sub 签发并条件上传 agent.md]
|
|
242
|
+
D --> E[NS 验收目标归属与版本并锁定]
|
|
243
|
+
E --> F[返回并关闭短连接,无 P2P]
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### 5.3 本地三身份自动转移
|
|
247
|
+
|
|
248
|
+
持有当前 owner、sub、新 owner 三个不同 agent 材料时,由当前 owner 调用:
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
const moved = await daemonClient.transferLocalSubaid(subClient, nextAgentClient);
|
|
252
|
+
if (moved.status !== 'completed') throw new Error(moved.reason);
|
|
253
|
+
console.log(moved.sub_aid, moved.new_owner_aid, moved.target_relation_version);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```mermaid
|
|
257
|
+
flowchart LR
|
|
258
|
+
A[旧 owner + sub + 新 owner 三身份 client] --> B[SDK 创建专属短连接并认证]
|
|
259
|
+
B --> C[旧 owner 上传转移授权]
|
|
260
|
+
C --> D[新 owner 上传 owner.md]
|
|
261
|
+
D --> E[sub 条件上传目标 agent.md]
|
|
262
|
+
E --> F[NS 原子切换并核验目标 active]
|
|
263
|
+
F --> G[条件清理旧授权,关闭短连接,无 P2P]
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
两个本地方法为 Facade 编排,各方只签自己的文件;每方须有有效私钥、证书及 NS 已发布的 `type: agent` 名片。SDK 使用 `ownership-UUID` 专属 slot,关闭后台同步与自动重连,在成功或失败时关闭新连接,不占业务长连接 slot。local 的 completed 表示内部已验收目标归属;如已有业务连接,可额外用该连接查询当前共识,不要求未连接的源 client 再做 RPC。human owner 仍走人工确认;daemon 的 owner 是 human,并不授权它代 human 同意。
|
|
267
|
+
|
|
268
|
+
### 5.4 完成依据、故障与跨 SDK 差异
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
const relation = await client.checkOwnershipConsensus('helper.agentid.cn');
|
|
272
|
+
const bound = relation.status === 'consensus' && relation.lock === 'locked'
|
|
273
|
+
&& relation.owner_aid === 'human.agentid.cn';
|
|
274
|
+
console.log(bound, relation.relation_version);
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
只有 NS consensus 且目标 owner、锁和预期版本匹配才确认目标关系。`released/unbound/single_sided/invalid/unavailable` 不能授权;Group/Org 自身返回 not_applicable。两种 local 编排内部会核对目标验收,异常仍可能发生在远端已提交之后。
|
|
278
|
+
|
|
279
|
+
| SDK | 普通交互返回与事件 |
|
|
280
|
+
| --- | --- |
|
|
281
|
+
| Python | completed 可只表示当次动作完成;观测 consensus 才发 completed 事件,否则 progress |
|
|
282
|
+
| TypeScript | completed 可只表示当次动作完成;completed 事件需观测 consensus |
|
|
283
|
+
| JavaScript | 目标 owner/版本已 locked 才返回 completed,否则 pending |
|
|
284
|
+
| Go | completed 返回及 completed 事件都可只表示当次动作完成 |
|
|
285
|
+
|
|
286
|
+
不能把不同语言的返回状态或同名事件统一当作验收证明。通用事件载荷直接传给回调,没有 `event.data` 包装;request 含可信 `requester_aid`。处理调用返回和异常,不依赖所有端都有旧 progress/action_required/stopped/error 事件。
|
|
287
|
+
|
|
288
|
+
```mermaid
|
|
289
|
+
flowchart LR
|
|
290
|
+
A[上传后报错、通知失败或重启] --> B[查询 NS 当前事实]
|
|
291
|
+
B -->|目标已锁定| C[按已完成处理]
|
|
292
|
+
B -->|无锁或单边声明| D[显式重新发起绑定]
|
|
293
|
+
B -->|仍是原 owner| E[按需要重新发起释放或转移]
|
|
294
|
+
B -->|其它归属或不可确认| F[停止旧写入,核对当前关系与依赖]
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
重发可产生新 operation ID;NS 不按消息 ID 决定归属。保留文件 ETag CAS、Storage expected_version、关系版本和 NS 原子锁;删除的是 SDK 任务 CAS。完整交互、self-owner 和文件约束见 [Ownership 应用指南](Ownership2.1-SDK应用集成指南.md)。
|
|
298
|
+
|
|
299
|
+
## 6. Storage 与 Group FS 读缓存
|
|
300
|
+
|
|
301
|
+
| 条件 | 当前策略 |
|
|
302
|
+
| --- | --- |
|
|
303
|
+
| 缺省 read_cache 或为 null | 元数据默认 60 秒;完整正文须实际不超过 65,536 字节并通过 SHA-256 校验 |
|
|
304
|
+
| 显式允许 | 正文还需 inline=true;省略 max_age_ms 默认 60 秒,允许的正数最多 60 秒 |
|
|
305
|
+
| 显式禁止/无效策略 | reusable=false、空策略或非法 TTL 不复用 |
|
|
306
|
+
| `noCache: true` | 本次强制远端校验,可按原 SHA 条件复用验证过的完整正文;不是 no-store |
|
|
307
|
+
| `consistency: 'authoritative'` | 支持该参数的底层 RPC 完全旁路 SDK 读缓存 |
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
const path = 'human.agentid.cn:/sub_aids/helper.agentid.cn/owner.md';
|
|
311
|
+
const bytes = await client.storage.readBytes(path);
|
|
312
|
+
const refreshed = await client.storage.readBytes(path, { noCache: true });
|
|
313
|
+
const stat = await client.storage.stat(path, { noCache: true });
|
|
314
|
+
declare const groupPath: string;
|
|
315
|
+
const groupStat = await client.group.fs.stat(groupPath, { noCache: true });
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
groupPath 使用完整 `group_aid:/notes/readme.md` 等合法群路径。Group FS 支持 noCache 并兼容 no_cache;刷新选项由 SDK 消费,不发成 RPC 业务字段。owner.md 普通文件读取也可缓存,Ownership 管理流程使用权威原件。范围读、大正文和显式预签保留原路径;not_modified 只复用摘要匹配、验证过的完整正文,不能当空文件。
|
|
319
|
+
|
|
320
|
+
缓存按身份、网关和参数隔离;命中与重启不续期,写删、移动及相关权限变更会失效。远端更新或撤权可能到刷新/TTL 到期才观察;本地命中不承担最新授权判断。Node/Python/Go 使用本地持久索引,浏览器用 IndexedDB;缓存可淘汰,不能代替业务数据库。细节见 [Storage 缓存](09-storage-rpc-manual.md#sdk-默认读缓存)、[Group FS 缓存](09-group-rpc-manual.md#sdk-默认读缓存)。
|
|
321
|
+
|
|
322
|
+
## 7. PKI、凭证与组织
|
|
323
|
+
|
|
324
|
+
### 7.1 缓存减少重复查询,不替代新鲜度
|
|
325
|
+
|
|
326
|
+
不可变证书材料、静态验链和同请求在途查询可复用/合并;根、网关、身份、连接代际或证书变化隔离旧结果。一般材料/静态链可复用一小时,并受证书有效期限制;吊销与生命周期按各端严格路径及验证结果有效截止处理。Ownership 新取状态证据的时限不等于所有缓存命中都重新下载全部证据,应用也不能自行延长证据期限。
|
|
327
|
+
|
|
328
|
+
已验证的 credential.status、org.member.get 等内部查询最多复用一分钟,受 proof、签名证书和相关 credential.exp 截止限制;严格登记确认旁路状态缓存,已验证变更事件使相关结果失效。这不表示所有同名 Facade/raw RPC 都自动缓存。不要再写一套长期有效状态缓存,也不把本地 current 当远端授权检查。
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
declare const originalCredentialCid: string;
|
|
332
|
+
const managed = await client.credential.current(originalCredentialCid);
|
|
333
|
+
if (!managed) throw new Error('没有当前托管凭证');
|
|
334
|
+
const credential = managed.credential;
|
|
335
|
+
const membershipBinding = managed.membership_binding;
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
使用当前完整 CAP、binding、terms 与登记回执,不长期复用最初截取的 CAP。verifySignature 只做数学预检;完整 verify 仍核对证书、时间、audience、证明链、当前状态、能力范围及请求绑定。未知或已撤销时暂停依赖该授权的副作用。
|
|
339
|
+
|
|
340
|
+
### 7.2 续期、撤销调度与持久恢复
|
|
341
|
+
|
|
342
|
+
| 数据/机制 | 当前保留规则 |
|
|
343
|
+
| --- | --- |
|
|
344
|
+
| Ownership 操作 | 无专用持久任务、WAL 或后台补偿;失败查 NS 后重发 |
|
|
345
|
+
| 普通消息 | 历史、设备/slot 水位、交付回执和应用事务保留 |
|
|
346
|
+
| Credential/Org | 原已签请求、续期链、登记回执、候选实体密钥及创建/转让 checkpoint 保留 |
|
|
347
|
+
|
|
348
|
+
进入 READY 后恢复受管理的长期凭证续期,在线每分钟检查;long_term=false 不自动续期。SDK 验证并持久合并撤销推送,后台首次撤销补拉延后一小时,此后约每小时。同一 client 的小时截止时间跨断线重连保留,断线取消本代际扫描;新 client/进程重新初始化调度,不能沿用旧文“每次重连重置一小时”的假设。没有受管理记录时不默认扫描本域撤销,后台扫描不能替代当前业务的完整验证。
|
|
349
|
+
|
|
350
|
+
创建/转让故障恢复仍沿用同一请求、proposal、候选密钥和原条件;缺少私钥时不能另造密钥继续原流程,幂等键复用冲突不能换 ID 自动重试。已完成转让重放只返回匹配结果,重连不重做 completed。Ownership 的“重新发起即可”不适用于这些持久编排。
|
|
351
|
+
|
|
352
|
+
### 7.3 组织请求接线
|
|
353
|
+
|
|
354
|
+
Credential/Org 业务 RPC 走 Gateway service-plane,Facade 存在不代表已部署服务。下例 orgParams 由应用提供,包含当前成员 CAP/binding、org_id 及业务字段:
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import type { CredentialSigner, JsonObject } from '@agentunion/fastaun';
|
|
358
|
+
declare const orgParams: JsonObject;
|
|
359
|
+
declare const memberSigner: CredentialSigner;
|
|
360
|
+
declare const orgServiceAid: string;
|
|
361
|
+
const prepared = client.org.prepareRequest('org.member.list', orgParams, orgServiceAid, memberSigner);
|
|
362
|
+
const members = await client.org.member.list(prepared);
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
先准备完整授权包,再生成 AAD 和 request binding;签后不改业务参数,按原请求重试。组织创建/转让/rekey、成员本人签署和实体名片主签沿用专属流程,不走通用 Ownership;详情见 [凭证与组织应用指南](凭证与组织服务SDK应用集成指南.md)。
|
|
366
|
+
|
|
367
|
+
## 8. 旧接口、错误与退出
|
|
368
|
+
|
|
369
|
+
| 接口 | 当前边界 |
|
|
370
|
+
| --- | --- |
|
|
371
|
+
| bindOwner/bindAid/releaseOwnership | 新 SDK 不走 legacy 写入,使用 2.1 Facade |
|
|
372
|
+
| TS resetOwnershipTask/Go ResetOwnershipTask | 公开接口删除,不用于归属管理 |
|
|
373
|
+
| Python reset_ownership_task | 保留空 reset 兼容结果 |
|
|
374
|
+
| JS resetOwnershipTask | 保留空 reset_operation_ids/skipped_operation_ids 兼容结果 |
|
|
375
|
+
| getOwner/getOwnershipStatus 等 legacy getter | 返回空 owner 或 legacy_unbound/unknown 占位,不证明实际归属 |
|
|
376
|
+
|
|
377
|
+
Store Result.ok=false 时先处理 error;RPC/管理方法的 AUNError 用数字 code、字符串 stringCode 和 retryable 分类。CAS conflict 先核对权威事实,不刷新条件强写;unavailable 不能降级为无锁或授权成功。诊断 client.debug.diag 只检查 dry-run,skipped 不是通过,也不等于完整业务执行成功。
|
|
378
|
+
|
|
379
|
+
正常退出先停止业务入口,完成持久交付,再释放订阅和 client:
|
|
380
|
+
|
|
381
|
+
```typescript
|
|
382
|
+
for (const subscription of subscriptions) subscription.unsubscribe();
|
|
383
|
+
await client.close();
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## 9. 服务兼容、升级与验收
|
|
387
|
+
|
|
388
|
+
Gateway/Message 必须支持 peer Pull;Ownership 须有 NS 2.1/Stage、权威 Storage 与条件发布。完整新语义应配套 NS 与四 SDK;只升级 SDK,普通首次绑定和材料先齐的部分 local 路径可能工作,但 sub 先同意转移、Stage 交错及锁后同事实重签需要本轮 NS 修复。新 SDK 不调用 decisions;三端真实 0.5.23 也没有此 RPC,不能说本轮从发布包删除它。依赖过渡接口的旧实现须单独核对。Rust 本轮仅检查,未同步修改。
|
|
389
|
+
|
|
390
|
+
保留原密钥、设备/slot、普通消息数据、Credential/Org checkpoint;无需为删除 Ownership 任务而清库或清理历史表。升级验收按失败点续跑,至少覆盖:
|
|
391
|
+
|
|
392
|
+
1. batch 入库失败、整批重放、撤回幂等、背压、断线补拉和后订阅;业务已读与 ACK 分离。
|
|
393
|
+
2. peer 目录未就绪、不同 sender 消费、群终态门控、后台退避与手动恢复。
|
|
394
|
+
3. resolve 同 ETag 复用、正文变化、forceRefresh 与显式 fresh 的区别、并发旧查询不回填、额外共识 unavailable。
|
|
395
|
+
4. Ownership 两种发起顺序、拒绝不回滚、B/C 候选替换、锁后迟到通知、注册 owner 当次失败后重发。
|
|
396
|
+
5. 两身份 local bind、三身份 local transfer、专属 slot 不顶替长连接、部分提交及旧授权清理失败后查 NS;human owner 仍人工确认。
|
|
397
|
+
6. sub/新 owner 分别先同意转移、旧活动归属隔离、授权过期/撤回、释放通知丢失仍显示 released。
|
|
398
|
+
7. Storage 60 秒缺省策略、64 KiB 边界、noCache、条件正文复用、写后失效与重启不续期。
|
|
399
|
+
8. PKI 吊销/过期新鲜度、Credential 当前完整包、小时补拉跨重连、短期不续期,以及 Org 原 checkpoint/密钥恢复。
|
|
400
|
+
|
|
401
|
+
运行入口见 [测试指南](../aun测试运行指南.md),源码与已有定向结果见 [parity 记录](../../python/CHANGES_FOR_PARITY.md)。历史联网记录针对当时工作区,不代表最终 0.5.24 包已完成全量单元、浏览器、跨 SDK 和双域发布回归。
|