@agentunion/fastaun-browser 0.2.19 → 0.3.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/CHANGELOG.md +50 -0
- package/_packed_docs/CHANGELOG.md +50 -0
- package/_packed_docs/agent.md/SCHEMA.md +173 -0
- package/_packed_docs/agent.md/examples/codeagent-claudecode.md +61 -0
- package/_packed_docs/agent.md/examples/human-developer.md +60 -0
- package/_packed_docs/agent.md/examples/openclaw-lobster.md +52 -0
- package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +43 -0
- package/_packed_docs/protocol/00-/346/200/273/350/247/210/344/270/216/345/210/206/345/261/202.md +205 -0
- 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 +197 -0
- 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 +549 -0
- package/_packed_docs/protocol/02-/350/257/201/344/271/246/344/270/216/344/277/241/344/273/273/344/275/223/347/263/273.md +810 -0
- package/_packed_docs/protocol/03-Gateway-/350/277/236/346/216/245/346/250/241/345/274/217.md +262 -0
- package/_packed_docs/protocol/04-Peer-/345/255/220/345/215/217/350/256/256.md +180 -0
- package/_packed_docs/protocol/05-Relay-/345/255/220/345/215/217/350/256/256.md +164 -0
- package/_packed_docs/protocol/06-/346/234/215/345/212/241/345/215/217/350/256/256.md +1135 -0
- 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 +234 -0
- package/_packed_docs/protocol/08-AUN-E2EE-Group.md +900 -0
- package/_packed_docs/protocol/08-AUN-E2EE.md +413 -0
- package/_packed_docs/protocol/09-/345/256/211/345/205/250/350/200/203/350/231/221.md +316 -0
- package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +804 -0
- package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +271 -0
- package/_packed_docs/protocol/12-Stream-/345/255/220/345/215/217/350/256/256.md +329 -0
- package/_packed_docs/protocol/13-Agent/350/241/214/344/270/272/350/247/204/350/214/203.md +141 -0
- package/_packed_docs/protocol/14-/344/272/244/344/272/222/346/234/272/345/210/266-/345/223/215/345/272/224/346/250/241/345/274/217/344/270/216/350/207/252/344/270/273/346/250/241/345/274/217.md +170 -0
- 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 +419 -0
- package/_packed_docs/protocol/README.md +71 -0
- package/_packed_docs/protocol/agent.md/SCHEMA.md +118 -0
- package/_packed_docs/protocol/agent.md/examples/codeagent-claudecode.md +61 -0
- package/_packed_docs/protocol/agent.md/examples/human-developer.md +60 -0
- package/_packed_docs/protocol/agent.md/examples/openclaw-lobster.md +52 -0
- package/_packed_docs/protocol/aun-docs-guide.md +49 -0
- package/_packed_docs/protocol/index.md +124 -0
- package/_packed_docs/protocol//350/215/211/346/241/210-agent.md/347/255/276/345/220/215/345/215/217/350/256/256.md +205 -0
- 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 +249 -0
- package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +337 -0
- package/_packed_docs/protocol//351/231/204/345/275/225B-/346/211/251/345/261/225/346/200/247/346/214/207/345/215/227.md +80 -0
- package/_packed_docs/protocol//351/231/204/345/275/225C-/347/247/201/351/222/245/347/256/241/347/220/206/344/270/216/350/272/253/344/273/275/346/201/242/345/244/215.md +704 -0
- package/_packed_docs/protocol//351/231/204/345/275/225D-Root_CA_/346/262/273/347/220/206/346/234/272/345/210/266.md +620 -0
- package/_packed_docs/protocol//351/231/204/345/275/225E-Root_CA_/345/207/206/345/205/245/346/265/201/347/250/213.md +605 -0
- package/_packed_docs/protocol//351/231/204/345/275/225F-Issuer_CA_/347/224/263/350/257/267/346/265/201/347/250/213.md +548 -0
- package/_packed_docs/protocol//351/231/204/345/275/225G-AID_/345/255/244/345/204/277/351/242/204/351/230/262/344/270/216/346/225/221/346/217/264/346/234/272/345/210/266.md +513 -0
- package/_packed_docs/protocol//351/231/204/345/275/225H-Identity/346/234/215/345/212/241/345/256/236/347/216/260/346/214/207/345/215/227.md +619 -0
- package/_packed_docs/protocol//351/231/204/345/275/225I-/350/267/250/345/237/237/346/266/210/346/201/257/350/267/257/347/224/261/345/256/236/347/216/260/346/214/207/345/215/227.md +492 -0
- package/_packed_docs/protocol//351/231/204/345/275/225J-/345/256/242/346/210/267/347/253/257/346/216/245/345/205/245/347/244/272/344/276/213.md +402 -0
- package/_packed_docs/protocol//351/231/204/345/275/225K-Agent_Web/345/217/221/347/216/260/345/215/217/350/256/256.md +130 -0
- package/_packed_docs/protocol//351/231/204/345/275/225L-E2EE/345/256/236/347/216/260/346/214/207/345/215/227.md +267 -0
- package/_packed_docs/protocol//351/231/204/345/275/225M-JWT/350/256/244/350/257/201/345/256/236/347/216/260/346/214/207/345/215/227.md +367 -0
- package/_packed_docs/python-sdk-v2-only-changelog.md +189 -0
- package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +223 -0
- package/_packed_docs/sdk/02-WebSocket/345/215/217/350/256/256.md +354 -0
- package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +172 -0
- package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +396 -0
- package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +611 -0
- package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +1203 -0
- package/_packed_docs/sdk/07-/351/224/231/350/257/257/345/244/204/347/220/206.md +150 -0
- package/_packed_docs/sdk/08-/346/234/200/344/275/263/345/256/236/350/267/265.md +89 -0
- package/_packed_docs/sdk/09-custody-api-manual.md +445 -0
- package/_packed_docs/sdk/09-group-rpc-manual.md +1895 -0
- package/_packed_docs/sdk/09-message-rpc-manual.md +597 -0
- package/_packed_docs/sdk/09-meta-rpc-manual.md +142 -0
- package/_packed_docs/sdk/09-payload-reference.md +702 -0
- package/_packed_docs/sdk/09-storage-rpc-manual.md +408 -0
- package/_packed_docs/sdk/09-stream-rpc-manual.md +275 -0
- package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +72 -0
- package/_packed_docs/sdk/INDEX.md +131 -0
- package/_packed_docs/sdk/README.md +307 -0
- package/dist/auth.d.ts +2 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +33 -14
- package/dist/auth.js.map +1 -1
- package/dist/bundle.js +14300 -0
- package/dist/client.d.ts +200 -178
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3096 -4019
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +0 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -4
- package/dist/config.js.map +1 -1
- package/dist/crypto.d.ts +8 -1
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +114 -1
- package/dist/crypto.js.map +1 -1
- package/dist/e2ee.d.ts +5 -210
- package/dist/e2ee.d.ts.map +1 -1
- package/dist/e2ee.js +4 -1379
- package/dist/e2ee.js.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index.js.map +1 -1
- package/dist/namespaces/auth.d.ts +1 -0
- package/dist/namespaces/auth.d.ts.map +1 -1
- package/dist/namespaces/auth.js +23 -8
- package/dist/namespaces/auth.js.map +1 -1
- package/dist/protected-headers.d.ts +14 -0
- package/dist/protected-headers.d.ts.map +1 -0
- package/dist/protected-headers.js +47 -0
- package/dist/protected-headers.js.map +1 -0
- package/dist/seq-tracker.d.ts +7 -2
- package/dist/seq-tracker.d.ts.map +1 -1
- package/dist/seq-tracker.js +31 -10
- package/dist/seq-tracker.js.map +1 -1
- package/dist/transport.d.ts +9 -1
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +24 -0
- package/dist/transport.js.map +1 -1
- package/dist/v2/crypto/aead.d.ts +26 -0
- package/dist/v2/crypto/aead.d.ts.map +1 -0
- package/dist/v2/crypto/aead.js +63 -0
- package/dist/v2/crypto/aead.js.map +1 -0
- package/dist/v2/crypto/canonical.d.ts +21 -0
- package/dist/v2/crypto/canonical.d.ts.map +1 -0
- package/dist/v2/crypto/canonical.js +111 -0
- package/dist/v2/crypto/canonical.js.map +1 -0
- package/dist/v2/crypto/dh-path.d.ts +21 -0
- package/dist/v2/crypto/dh-path.d.ts.map +1 -0
- package/dist/v2/crypto/dh-path.js +50 -0
- package/dist/v2/crypto/dh-path.js.map +1 -0
- package/dist/v2/crypto/ecdh.d.ts +19 -0
- package/dist/v2/crypto/ecdh.d.ts.map +1 -0
- package/dist/v2/crypto/ecdh.js +101 -0
- package/dist/v2/crypto/ecdh.js.map +1 -0
- package/dist/v2/crypto/ecdsa.d.ts +16 -0
- package/dist/v2/crypto/ecdsa.d.ts.map +1 -0
- package/dist/v2/crypto/ecdsa.js +52 -0
- package/dist/v2/crypto/ecdsa.js.map +1 -0
- package/dist/v2/crypto/hkdf.d.ts +21 -0
- package/dist/v2/crypto/hkdf.d.ts.map +1 -0
- package/dist/v2/crypto/hkdf.js +32 -0
- package/dist/v2/crypto/hkdf.js.map +1 -0
- package/dist/v2/crypto/index.d.ts +9 -0
- package/dist/v2/crypto/index.d.ts.map +1 -0
- package/dist/v2/crypto/index.js +8 -0
- package/dist/v2/crypto/index.js.map +1 -0
- package/dist/v2/crypto/recipients.d.ts +43 -0
- package/dist/v2/crypto/recipients.d.ts.map +1 -0
- package/dist/v2/crypto/recipients.js +188 -0
- package/dist/v2/crypto/recipients.js.map +1 -0
- package/dist/v2/e2ee/decrypt.d.ts +13 -0
- package/dist/v2/e2ee/decrypt.d.ts.map +1 -0
- package/dist/v2/e2ee/decrypt.js +176 -0
- package/dist/v2/e2ee/decrypt.js.map +1 -0
- package/dist/v2/e2ee/encrypt-group.d.ts +14 -0
- package/dist/v2/e2ee/encrypt-group.d.ts.map +1 -0
- package/dist/v2/e2ee/encrypt-group.js +196 -0
- package/dist/v2/e2ee/encrypt-group.js.map +1 -0
- package/dist/v2/e2ee/encrypt-p2p.d.ts +15 -0
- package/dist/v2/e2ee/encrypt-p2p.d.ts.map +1 -0
- package/dist/v2/e2ee/encrypt-p2p.js +240 -0
- package/dist/v2/e2ee/encrypt-p2p.js.map +1 -0
- package/dist/v2/e2ee/index.d.ts +9 -0
- package/dist/v2/e2ee/index.d.ts.map +1 -0
- package/dist/v2/e2ee/index.js +9 -0
- package/dist/v2/e2ee/index.js.map +1 -0
- package/dist/v2/e2ee/metadata-auth.d.ts +9 -0
- package/dist/v2/e2ee/metadata-auth.d.ts.map +1 -0
- package/dist/v2/e2ee/metadata-auth.js +60 -0
- package/dist/v2/e2ee/metadata-auth.js.map +1 -0
- package/dist/v2/e2ee/types.d.ts +57 -0
- package/dist/v2/e2ee/types.d.ts.map +1 -0
- package/dist/v2/e2ee/types.js +7 -0
- package/dist/v2/e2ee/types.js.map +1 -0
- package/dist/v2/session/index.d.ts +4 -0
- package/dist/v2/session/index.d.ts.map +1 -0
- package/dist/v2/session/index.js +3 -0
- package/dist/v2/session/index.js.map +1 -0
- package/dist/v2/session/keystore.d.ts +48 -0
- package/dist/v2/session/keystore.d.ts.map +1 -0
- package/dist/v2/session/keystore.js +184 -0
- package/dist/v2/session/keystore.js.map +1 -0
- package/dist/v2/session/session.d.ts +98 -0
- package/dist/v2/session/session.d.ts.map +1 -0
- package/dist/v2/session/session.js +270 -0
- package/dist/v2/session/session.js.map +1 -0
- package/dist/v2/state/commitment.d.ts +10 -0
- package/dist/v2/state/commitment.d.ts.map +1 -0
- package/dist/v2/state/commitment.js +86 -0
- package/dist/v2/state/commitment.js.map +1 -0
- package/dist/v2/state/index.d.ts +2 -0
- package/dist/v2/state/index.d.ts.map +1 -0
- package/dist/v2/state/index.js +2 -0
- package/dist/v2/state/index.js.map +1 -0
- package/package.json +43 -37
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# 存储 — RPC Manual
|
|
2
|
+
|
|
3
|
+
## 方法索引
|
|
4
|
+
|
|
5
|
+
### 控制面方法
|
|
6
|
+
|
|
7
|
+
| 方法 | 说明 |
|
|
8
|
+
|------|------|
|
|
9
|
+
| [storage.put_object](#storageput_object) | Inline 写入小对象 |
|
|
10
|
+
| [storage.get_object](#storageget_object) | Inline 读取小对象 |
|
|
11
|
+
| [storage.head_object](#storagehead_object) | 查询元数据 |
|
|
12
|
+
| [storage.delete_object](#storagedelete_object) | 删除对象 |
|
|
13
|
+
| [storage.list_objects](#storagelist_objects) | 列举对象 |
|
|
14
|
+
| [storage.list_prefixes](#storagelist_prefixes) | 列举子目录 |
|
|
15
|
+
| [storage.get_quota](#storageget_quota) | 查询配额 |
|
|
16
|
+
|
|
17
|
+
### 数据面协调方法
|
|
18
|
+
|
|
19
|
+
| 方法 | 说明 |
|
|
20
|
+
|------|------|
|
|
21
|
+
| [storage.create_upload_session](#storagecreate_upload_session) | 申请上传 URL |
|
|
22
|
+
| [storage.complete_upload](#storagecomplete_upload) | 确认上传完成 |
|
|
23
|
+
| [storage.create_download_ticket](#storagecreate_download_ticket) | 申请下载 URL |
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
> `object_key` 当前仅支持 ASCII 安全字符集合 `[A-Za-z0-9._/-]`,且不允许空路径段、`..`、反斜杠转义后的非法段。
|
|
28
|
+
|
|
29
|
+
## storage.put_object
|
|
30
|
+
|
|
31
|
+
上传小对象(内容 base64 编码通过 RPC 传输)。
|
|
32
|
+
|
|
33
|
+
### 参数
|
|
34
|
+
|
|
35
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
36
|
+
|------|------|------|------|
|
|
37
|
+
| `object_key` | string | 是 | 对象路径 |
|
|
38
|
+
| `content` | string | 是 | base64 编码内容 |
|
|
39
|
+
| `content_type` | string | 否 | MIME 类型,默认 `"application/octet-stream"` |
|
|
40
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
41
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
42
|
+
| `is_private` | boolean | 否 | 是否私有,默认 `true` |
|
|
43
|
+
| `overwrite` | boolean | 否 | 是否覆盖已有对象,默认 `true` |
|
|
44
|
+
| `expected_version` | integer | 否 | 乐观并发控制版本号 |
|
|
45
|
+
| `expire_in_seconds` | integer | 否 | 过期时间(秒),0 表示不过期 |
|
|
46
|
+
| `metadata` | object | 否 | 自定义元数据 |
|
|
47
|
+
|
|
48
|
+
### 响应
|
|
49
|
+
|
|
50
|
+
| 字段 | 类型 | 说明 |
|
|
51
|
+
|------|------|------|
|
|
52
|
+
| `owner_aid` | string | 所有者 AID |
|
|
53
|
+
| `bucket` | string | 存储桶 |
|
|
54
|
+
| `object_key` | string | 对象路径 |
|
|
55
|
+
| `size_bytes` | integer | 对象大小(字节) |
|
|
56
|
+
| `content_type` | string | MIME 类型 |
|
|
57
|
+
| `sha256` | string | SHA-256 哈希 |
|
|
58
|
+
| `version` | integer | 版本号 |
|
|
59
|
+
| `etag` | string | 实体标签 |
|
|
60
|
+
| `updated_at` | integer | 更新时间戳 |
|
|
61
|
+
|
|
62
|
+
### 示例
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
import base64
|
|
66
|
+
|
|
67
|
+
content = base64.b64encode(b"Hello World").decode()
|
|
68
|
+
result = await client.call("storage.put_object", {
|
|
69
|
+
"object_key": "notes/hello.txt",
|
|
70
|
+
"content": content,
|
|
71
|
+
"content_type": "text/plain",
|
|
72
|
+
})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## storage.get_object
|
|
78
|
+
|
|
79
|
+
读取小对象,返回 base64 编码内容。
|
|
80
|
+
|
|
81
|
+
### 参数
|
|
82
|
+
|
|
83
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
84
|
+
|------|------|------|------|
|
|
85
|
+
| `object_key` | string | 是 | 对象路径 |
|
|
86
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
87
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
88
|
+
|
|
89
|
+
### 响应
|
|
90
|
+
|
|
91
|
+
| 字段 | 类型 | 说明 |
|
|
92
|
+
|------|------|------|
|
|
93
|
+
| `owner_aid` | string | 所有者 AID |
|
|
94
|
+
| `bucket` | string | 存储桶 |
|
|
95
|
+
| `object_key` | string | 对象路径 |
|
|
96
|
+
| `content` | string | base64 编码内容 |
|
|
97
|
+
| `content_type` | string | MIME 类型 |
|
|
98
|
+
| `size_bytes` | integer | 对象大小(字节) |
|
|
99
|
+
| `sha256` | string | SHA-256 哈希 |
|
|
100
|
+
| `version` | integer | 版本号 |
|
|
101
|
+
| `updated_at` | integer | 更新时间戳 |
|
|
102
|
+
|
|
103
|
+
> **注意**:实现不返回 `etag`(与 put_object/head_object 不同)。
|
|
104
|
+
|
|
105
|
+
### 示例
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
result = await client.call("storage.get_object", {
|
|
109
|
+
"object_key": "notes/hello.txt",
|
|
110
|
+
})
|
|
111
|
+
content = base64.b64decode(result["content"])
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## storage.head_object
|
|
117
|
+
|
|
118
|
+
查询对象元数据,不返回内容。
|
|
119
|
+
|
|
120
|
+
### 参数
|
|
121
|
+
|
|
122
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
123
|
+
|------|------|------|------|
|
|
124
|
+
| `object_key` | string | 是 | 对象路径 |
|
|
125
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
126
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
127
|
+
|
|
128
|
+
### 响应
|
|
129
|
+
|
|
130
|
+
| 字段 | 类型 | 说明 |
|
|
131
|
+
|------|------|------|
|
|
132
|
+
| `owner_aid` | string | 所有者 AID |
|
|
133
|
+
| `bucket` | string | 存储桶 |
|
|
134
|
+
| `object_key` | string | 对象路径 |
|
|
135
|
+
| `content_type` | string | MIME 类型 |
|
|
136
|
+
| `size_bytes` | integer | 对象大小(字节) |
|
|
137
|
+
| `sha256` | string | SHA-256 哈希 |
|
|
138
|
+
| `version` | integer | 版本号 |
|
|
139
|
+
| `etag` | string | 实体标签 |
|
|
140
|
+
| `is_private` | boolean | 是否私有 |
|
|
141
|
+
| `expire_at` | integer | 过期时间戳(0 表示不过期) |
|
|
142
|
+
| `created_at` | integer | 创建时间戳 |
|
|
143
|
+
| `updated_at` | integer | 更新时间戳 |
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## storage.delete_object
|
|
148
|
+
|
|
149
|
+
删除对象。
|
|
150
|
+
|
|
151
|
+
### 参数
|
|
152
|
+
|
|
153
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
154
|
+
|------|------|------|------|
|
|
155
|
+
| `object_key` | string | 是 | 对象路径 |
|
|
156
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
157
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
158
|
+
|
|
159
|
+
### 响应
|
|
160
|
+
|
|
161
|
+
| 字段 | 类型 | 说明 |
|
|
162
|
+
|------|------|------|
|
|
163
|
+
| `deleted` | boolean | 是否成功删除(`false` 表示对象不存在) |
|
|
164
|
+
| `owner_aid` | string | 所有者 AID |
|
|
165
|
+
| `object_key` | string | 对象路径 |
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## storage.list_objects
|
|
170
|
+
|
|
171
|
+
列出对象。
|
|
172
|
+
|
|
173
|
+
> 权限:仅允许查询自己的对象(`owner_aid` 默认为当前用户,不可指定他人的 AID)
|
|
174
|
+
|
|
175
|
+
### 参数
|
|
176
|
+
|
|
177
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
178
|
+
|------|------|------|------|
|
|
179
|
+
| `prefix` | string | 否 | 路径前缀过滤 |
|
|
180
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
181
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
182
|
+
| `page` | integer | 否 | 页码,默认 1 |
|
|
183
|
+
| `size` | integer | 否 | 每页条数,默认 50(最大 200) |
|
|
184
|
+
| `marker` | string | 否 | 深度分页游标;传入时优先按游标分页 |
|
|
185
|
+
|
|
186
|
+
### 响应
|
|
187
|
+
|
|
188
|
+
| 字段 | 类型 | 说明 |
|
|
189
|
+
|------|------|------|
|
|
190
|
+
| `items` | array | 对象元数据列表 |
|
|
191
|
+
| `total` | integer | 总条数 |
|
|
192
|
+
| `page` | integer | 当前页码 |
|
|
193
|
+
| `size` | integer | 每页条数 |
|
|
194
|
+
| `marker` | string | 当前游标标记 |
|
|
195
|
+
| `next_marker` | string | 下一页游标标记(为空表示无更多数据) |
|
|
196
|
+
|
|
197
|
+
每个 item 包含:
|
|
198
|
+
|
|
199
|
+
| 字段 | 类型 | 说明 |
|
|
200
|
+
|------|------|------|
|
|
201
|
+
| `object_key` | string | 对象路径 |
|
|
202
|
+
| `size_bytes` | integer | 对象大小(字节) |
|
|
203
|
+
| `content_type` | string | MIME 类型 |
|
|
204
|
+
| `sha256` | string | SHA-256 哈希 |
|
|
205
|
+
| `version` | integer | 版本号 |
|
|
206
|
+
| `is_private` | boolean | 是否私有 |
|
|
207
|
+
| `updated_at` | integer | 更新时间戳 |
|
|
208
|
+
|
|
209
|
+
### 示例
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
result = await client.call("storage.list_objects", {
|
|
213
|
+
"prefix": "notes/",
|
|
214
|
+
"size": 20,
|
|
215
|
+
})
|
|
216
|
+
for obj in result["items"]:
|
|
217
|
+
print(f"{obj['object_key']} ({obj['size_bytes']} bytes)")
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## storage.list_prefixes
|
|
223
|
+
|
|
224
|
+
列出直接子目录(前缀)。
|
|
225
|
+
|
|
226
|
+
> 权限:仅允许查询自己的对象(`owner_aid` 默认为当前用户,不可指定他人的 AID)
|
|
227
|
+
|
|
228
|
+
### 参数
|
|
229
|
+
|
|
230
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
231
|
+
|------|------|------|------|
|
|
232
|
+
| `prefix` | string | 否 | 路径前缀过滤 |
|
|
233
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
234
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
235
|
+
| `size` | integer | 否 | 每页条数上限 |
|
|
236
|
+
|
|
237
|
+
### 响应
|
|
238
|
+
|
|
239
|
+
| 字段 | 类型 | 说明 |
|
|
240
|
+
|------|------|------|
|
|
241
|
+
| `prefixes` | string[] | 直接子目录列表 |
|
|
242
|
+
| `count` | integer | 子目录数量 |
|
|
243
|
+
| `size` | integer | 实际生效的每页上限 |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## storage.get_quota
|
|
248
|
+
|
|
249
|
+
查询存储配额。
|
|
250
|
+
|
|
251
|
+
### 参数
|
|
252
|
+
|
|
253
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
254
|
+
|------|------|------|------|
|
|
255
|
+
| `owner_aid` | string | 否 | 查询指定 AID 的配额(默认为当前用户,仅允许查询自己的配额) |
|
|
256
|
+
|
|
257
|
+
### 响应
|
|
258
|
+
|
|
259
|
+
| 字段 | 类型 | 说明 |
|
|
260
|
+
|------|------|------|
|
|
261
|
+
| `owner_aid` | string | 所有者 AID |
|
|
262
|
+
| `used_bytes` | integer | 已使用空间(字节) |
|
|
263
|
+
| `object_count` | integer | 对象数量 |
|
|
264
|
+
| `quota_bytes` | integer | 配额上限(字节),0 表示无限制 |
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## storage.create_upload_session
|
|
269
|
+
|
|
270
|
+
获取上传用 presigned URL。
|
|
271
|
+
|
|
272
|
+
### 参数
|
|
273
|
+
|
|
274
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
275
|
+
|------|------|------|------|
|
|
276
|
+
| `object_key` | string | 是 | 对象路径 |
|
|
277
|
+
| `size_bytes` | integer | 否 | 声明的文件大小(字节)。当前实现允许省略,但建议传入用于客户端追踪与最终校验 |
|
|
278
|
+
| `content_type` | string | 否 | MIME 类型,默认 `"application/octet-stream"` |
|
|
279
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
280
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
281
|
+
| `expected_version` | integer | 否 | 乐观并发控制版本号 |
|
|
282
|
+
| `expire_in_seconds` | integer | 否 | URL 有效期(秒),默认 3600 |
|
|
283
|
+
|
|
284
|
+
### 响应
|
|
285
|
+
|
|
286
|
+
| 字段 | 类型 | 说明 |
|
|
287
|
+
|------|------|------|
|
|
288
|
+
| `upload_url` | string | 上传用 presigned URL |
|
|
289
|
+
| `blob_key` | string | Blob 存储 key |
|
|
290
|
+
| `expire_at` | integer | URL 过期时间戳 |
|
|
291
|
+
| `owner_aid` | string | 所有者 AID |
|
|
292
|
+
| `bucket` | string | 存储桶 |
|
|
293
|
+
| `object_key` | string | 对象路径 |
|
|
294
|
+
| `content_type` | string | MIME 类型 |
|
|
295
|
+
| `size_bytes` | integer | 声明的文件大小 |
|
|
296
|
+
|
|
297
|
+
客户端获得 `upload_url` 后,通过 HTTP PUT 上传文件数据。
|
|
298
|
+
|
|
299
|
+
> 当前实现会对 BlobStore 返回的 loopback URL 做对外地址规范化:优先使用 `KITE_STORAGE_EXTERNAL_URL`,否则按 `storage.{issuer}` 形式改写。对外地址不可使用 `127.0.0.1` 或 `localhost`。
|
|
300
|
+
|
|
301
|
+
> 当前实现不会在 `create_upload_session` 阶段强校验配额或最终文件大小;这些检查会在 `storage.complete_upload` 阶段执行。
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## storage.complete_upload
|
|
306
|
+
|
|
307
|
+
完成上传,提交校验信息。
|
|
308
|
+
|
|
309
|
+
### 参数
|
|
310
|
+
|
|
311
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
312
|
+
|------|------|------|------|
|
|
313
|
+
| `object_key` | string | 是 | 对象路径 |
|
|
314
|
+
| `sha256` | string | 是 | 文件 SHA-256 哈希 |
|
|
315
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
316
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户 |
|
|
317
|
+
| `content_type` | string | 否 | MIME 类型,默认 `"application/octet-stream"` |
|
|
318
|
+
| `is_private` | boolean | 否 | 是否私有,默认 `true` |
|
|
319
|
+
| `size_bytes` | integer | 否 | 预期文件大小(用于校验) |
|
|
320
|
+
| `expected_version` | integer | 否 | 乐观并发控制版本号 |
|
|
321
|
+
| `expire_in_seconds` | integer | 否 | 过期时间(秒) |
|
|
322
|
+
| `metadata` | object | 否 | 自定义元数据 |
|
|
323
|
+
|
|
324
|
+
### 响应
|
|
325
|
+
|
|
326
|
+
| 字段 | 类型 | 说明 |
|
|
327
|
+
|------|------|------|
|
|
328
|
+
| `owner_aid` | string | 所有者 AID |
|
|
329
|
+
| `bucket` | string | 存储桶 |
|
|
330
|
+
| `object_key` | string | 对象路径 |
|
|
331
|
+
| `size_bytes` | integer | 对象大小(字节) |
|
|
332
|
+
| `content_type` | string | MIME 类型 |
|
|
333
|
+
| `sha256` | string | SHA-256 哈希 |
|
|
334
|
+
| `version` | integer | 版本号 |
|
|
335
|
+
| `etag` | string | 实体标签 |
|
|
336
|
+
| `updated_at` | integer | 更新时间戳 |
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## storage.create_download_ticket
|
|
341
|
+
|
|
342
|
+
获取下载 URL。
|
|
343
|
+
|
|
344
|
+
### 参数
|
|
345
|
+
|
|
346
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
347
|
+
|------|------|------|------|
|
|
348
|
+
| `object_key` | string | 是 | 对象路径 |
|
|
349
|
+
| `bucket` | string | 否 | 存储桶,默认 `"default"` |
|
|
350
|
+
| `owner_aid` | string | 否 | 所有者 AID,默认当前用户(公开对象可指定其他 AID) |
|
|
351
|
+
| `expire_in_seconds` | integer | 否 | URL 有效期(秒),默认 3600 |
|
|
352
|
+
|
|
353
|
+
### 响应
|
|
354
|
+
|
|
355
|
+
| 字段 | 类型 | 说明 |
|
|
356
|
+
|------|------|------|
|
|
357
|
+
| `download_url` | string | 下载用 presigned URL |
|
|
358
|
+
| `expire_at` | integer | URL 过期时间戳 |
|
|
359
|
+
| `file_name` | string | 文件名(从 object_key 提取) |
|
|
360
|
+
| `size_bytes` | integer | 文件大小(字节) |
|
|
361
|
+
| `content_type` | string | MIME 类型 |
|
|
362
|
+
| `sha256` | string | SHA-256 哈希 |
|
|
363
|
+
| `version` | integer | 版本号 |
|
|
364
|
+
| `etag` | string | 实体标签 |
|
|
365
|
+
|
|
366
|
+
客户端获得 `download_url` 后,通过 HTTP GET 下载文件。
|
|
367
|
+
|
|
368
|
+
> 当前实现会对 BlobStore 返回的 loopback URL 做对外地址规范化:优先使用 `KITE_STORAGE_EXTERNAL_URL`,否则按 `storage.{issuer}` 形式改写。对外地址不可使用 `127.0.0.1` 或 `localhost`。
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## 事件
|
|
373
|
+
|
|
374
|
+
### event/storage.object_changed
|
|
375
|
+
|
|
376
|
+
对象变更时推送。
|
|
377
|
+
|
|
378
|
+
**Payload**:
|
|
379
|
+
|
|
380
|
+
```json
|
|
381
|
+
{
|
|
382
|
+
"module_id": "storage",
|
|
383
|
+
"action": "put",
|
|
384
|
+
"owner_aid": "alice.agentid.pub",
|
|
385
|
+
"object_key": "notes/hello.txt"
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
| 字段 | 类型 | 说明 |
|
|
390
|
+
|------|------|------|
|
|
391
|
+
| `module_id` | string | 当前模块 ID,通常为 `"storage"` |
|
|
392
|
+
| `action` | string | `"put"` 或 `"delete"` |
|
|
393
|
+
| `owner_aid` | string | 对象所有者 AID |
|
|
394
|
+
| `object_key` | string | 对象路径 |
|
|
395
|
+
|
|
396
|
+
> 当前实现在 `storage.put_object` 成功后推送 `action="put"`,`storage.delete_object` 返回 `deleted=true` 时推送 `action="delete"`,`storage.complete_upload` 成功后也会推送 `action="put"` 事件。
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## 错误码
|
|
401
|
+
|
|
402
|
+
| code | 说明 |
|
|
403
|
+
|------|------|
|
|
404
|
+
| -32002 | 服务暂不可用(数据库未连接) |
|
|
405
|
+
| -32004 | 权限拒绝(requester 不是对象 owner,或非公开对象的读权限不足) |
|
|
406
|
+
| -32008 | 对象不存在(`ErrNotFound`) |
|
|
407
|
+
| -32009 | 版本冲突(`ErrVersionConflict`,`expected_version` 与实际版本不匹配) |
|
|
408
|
+
| -32000 | 通用错误(参数校验失败、配额不足、base64 解码失败、文件大小超限等) |
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# 实时流 — RPC Manual
|
|
2
|
+
|
|
3
|
+
## 方法索引
|
|
4
|
+
|
|
5
|
+
### 控制面方法(通过 Gateway JSON-RPC)
|
|
6
|
+
|
|
7
|
+
| 方法 | 说明 |
|
|
8
|
+
|------|------|
|
|
9
|
+
| [stream.create](#streamcreate) | 创建流,返回推流/拉流 URL |
|
|
10
|
+
| [stream.close](#streamclose) | 关闭流(仅创建者) |
|
|
11
|
+
| [stream.get_info](#streamget_info) | 获取流状态和统计 |
|
|
12
|
+
| [stream.list_active](#streamlist_active) | 列出当前 AID 的活跃流 |
|
|
13
|
+
|
|
14
|
+
### 数据面端点(独立端口,默认 9490)
|
|
15
|
+
|
|
16
|
+
| 端点 | 协议 | 说明 |
|
|
17
|
+
|------|------|------|
|
|
18
|
+
| `/push/{stream_id}` | WebSocket | 推流。推荐使用 `Authorization: Bearer {push_token}`,query token 仅为兼容旧客户端 |
|
|
19
|
+
| `/pull/{stream_id}` | HTTP SSE | 拉流。推荐使用 `Authorization: Bearer {pull_token}`,可跨域 |
|
|
20
|
+
| `/health` | HTTP GET | 健康检查 |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## stream.create
|
|
25
|
+
|
|
26
|
+
创建一条新的流,返回推流和拉流地址。推流方通过 WebSocket 连接 push_url 发送数据帧,拉流方通过 HTTP SSE 连接 pull_url 接收数据。
|
|
27
|
+
|
|
28
|
+
### 参数
|
|
29
|
+
|
|
30
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
31
|
+
|------|------|------|------|
|
|
32
|
+
| `content_type` | string | 否 | 内容类型,默认 `"text/plain"`。常用值:`text/plain`(文本流)、`application/json-stream`(JSON 对象流)、`text/event-stream`(SSE 风格事件流) |
|
|
33
|
+
| `metadata` | object | 否 | 自定义元数据,如 `{"model": "gpt-4", "task_id": "xxx"}` |
|
|
34
|
+
| `target_aid` | string | 否 | 绑定拉流方 AID。当前实现中,只有拉流方显式提供 `aid` 时才会做该匹配校验 |
|
|
35
|
+
|
|
36
|
+
### 响应
|
|
37
|
+
|
|
38
|
+
| 字段 | 类型 | 说明 |
|
|
39
|
+
|------|------|------|
|
|
40
|
+
| `stream_id` | string | 流唯一 ID(16 位 hex) |
|
|
41
|
+
| `push_url` | string | 推流 WebSocket URL(含 push_token) |
|
|
42
|
+
| `pull_url` | string | 拉流 HTTP SSE URL(含 pull_token) |
|
|
43
|
+
| `push_token` | string | 推流凭证 |
|
|
44
|
+
| `pull_token` | string | 拉流凭证,便于通过 message.send 单独传递 |
|
|
45
|
+
| `push_headers` | object | 推流 Authorization header(`{"Authorization": "Bearer {push_token}"}`) |
|
|
46
|
+
| `pull_headers` | object | 拉流 Authorization header(`{"Authorization": "Bearer {pull_token}"}`) |
|
|
47
|
+
|
|
48
|
+
### 调用示例
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
result = await client.call("stream.create", {
|
|
52
|
+
"content_type": "text/plain",
|
|
53
|
+
"metadata": {"model": "gpt-4"},
|
|
54
|
+
})
|
|
55
|
+
# result = {
|
|
56
|
+
# "stream_id": "4d5067f203cf42ba",
|
|
57
|
+
# "push_url": "wss://stream.aid.com:9490/push/4d5067f203cf42ba?token=ec80...",
|
|
58
|
+
# "pull_url": "https://stream.aid.com:9490/pull/4d5067f203cf42ba?token=c438...",
|
|
59
|
+
# "push_token": "ec80...",
|
|
60
|
+
# "pull_token": "c438953be0ca887b...",
|
|
61
|
+
# "push_headers": {"Authorization": "Bearer ec80..."},
|
|
62
|
+
# "pull_headers": {"Authorization": "Bearer c438..."}
|
|
63
|
+
# }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
> 当前实现中,`push_url` / `pull_url` 仍会附带 query token 以兼容旧客户端;新客户端优先使用返回的 `push_headers` / `pull_headers`。
|
|
67
|
+
|
|
68
|
+
### 错误
|
|
69
|
+
|
|
70
|
+
| code | message | 原因 |
|
|
71
|
+
|------|---------|------|
|
|
72
|
+
| -33402 | Stream limit exceeded | 活跃流数超过服务配置上限 |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## stream.close
|
|
77
|
+
|
|
78
|
+
关闭流。仅流的创建者可调用。关闭后所有拉流端收到 SSE `event: done`。
|
|
79
|
+
|
|
80
|
+
### 参数
|
|
81
|
+
|
|
82
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
83
|
+
|------|------|------|------|
|
|
84
|
+
| `stream_id` | string | 是 | 要关闭的流 ID |
|
|
85
|
+
|
|
86
|
+
### 响应
|
|
87
|
+
|
|
88
|
+
| 字段 | 类型 | 说明 |
|
|
89
|
+
|------|------|------|
|
|
90
|
+
| `success` | boolean | `true` |
|
|
91
|
+
|
|
92
|
+
### 调用示例
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
await client.call("stream.close", {"stream_id": "4d5067f203cf42ba"})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 错误
|
|
99
|
+
|
|
100
|
+
| code | message | 原因 |
|
|
101
|
+
|------|---------|------|
|
|
102
|
+
| -33405 | Stream invalid params | 缺少 stream_id |
|
|
103
|
+
| -33403 | Stream permission denied | 非创建者调用 |
|
|
104
|
+
|
|
105
|
+
> 流不存在时幂等返回 `{"success": true}`,不抛错误。
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## stream.get_info
|
|
110
|
+
|
|
111
|
+
获取流的状态和统计信息。仅流的创建者或 `target_aid` 可调用。
|
|
112
|
+
|
|
113
|
+
### 参数
|
|
114
|
+
|
|
115
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
116
|
+
|------|------|------|------|
|
|
117
|
+
| `stream_id` | string | 是 | 流 ID |
|
|
118
|
+
|
|
119
|
+
### 响应
|
|
120
|
+
|
|
121
|
+
| 字段 | 类型 | 说明 |
|
|
122
|
+
|------|------|------|
|
|
123
|
+
| `stream_id` | string | 流 ID |
|
|
124
|
+
| `creator_aid` | string | 创建者 AID |
|
|
125
|
+
| `content_type` | string | 内容类型 |
|
|
126
|
+
| `metadata` | object | 自定义元数据 |
|
|
127
|
+
| `status` | string | `"waiting"` / `"active"` / `"done"` |
|
|
128
|
+
| `is_online` | boolean | 推流端是否在线 |
|
|
129
|
+
| `seq` | integer | 当前最大序列号 |
|
|
130
|
+
| `frames_pushed` | integer | 已推送帧数 |
|
|
131
|
+
| `bytes_pushed` | integer | 已推送字节数 |
|
|
132
|
+
| `puller_count` | integer | 当前拉流端数量 |
|
|
133
|
+
| `age_seconds` | float | 流存活时间(秒) |
|
|
134
|
+
| `idle_seconds` | float | 距最近活动的秒数 |
|
|
135
|
+
|
|
136
|
+
### 调用示例
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
info = await client.call("stream.get_info", {"stream_id": "4d5067f203cf42ba"})
|
|
140
|
+
# info["status"] == "active"
|
|
141
|
+
# info["frames_pushed"] == 42
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## stream.list_active
|
|
147
|
+
|
|
148
|
+
列出当前 AID 创建的所有活跃流。需要有效认证身份。
|
|
149
|
+
|
|
150
|
+
### 参数
|
|
151
|
+
|
|
152
|
+
无。
|
|
153
|
+
|
|
154
|
+
### 响应
|
|
155
|
+
|
|
156
|
+
| 字段 | 类型 | 说明 |
|
|
157
|
+
|------|------|------|
|
|
158
|
+
| `streams` | array | StreamInfo 对象数组(同 get_info 响应格式) |
|
|
159
|
+
|
|
160
|
+
### 调用示例
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
result = await client.call("stream.list_active", {})
|
|
164
|
+
for s in result["streams"]:
|
|
165
|
+
print(f"{s['stream_id']}: {s['status']}, {s['frames_pushed']} frames")
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 数据面:推流 WebSocket
|
|
171
|
+
|
|
172
|
+
连接 `stream.create` 返回的 `push_url`,通过 WebSocket 发送 JSON 帧。当前实现优先从 `Authorization: Bearer` 读取 token,query string 仅作兼容回退。
|
|
173
|
+
|
|
174
|
+
### 帧格式
|
|
175
|
+
|
|
176
|
+
**数据帧**:
|
|
177
|
+
```json
|
|
178
|
+
{"cmd": "data", "data": "chunk内容", "seq": 1}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
182
|
+
|------|------|------|------|
|
|
183
|
+
| `cmd` | string | 是 | 固定 `"data"` |
|
|
184
|
+
| `data` | string | 是 | 数据内容,无大小限制(WS 帧上限 64MB) |
|
|
185
|
+
| `seq` | integer | 否 | 序列号,不提供则服务端自增 |
|
|
186
|
+
|
|
187
|
+
**关闭帧**:
|
|
188
|
+
```json
|
|
189
|
+
{"cmd": "close"}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 完整示例
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
import websockets, json
|
|
196
|
+
|
|
197
|
+
async with websockets.connect(push_url, ssl=ssl_ctx) as ws:
|
|
198
|
+
for i, token in enumerate(llm_tokens, 1):
|
|
199
|
+
await ws.send(json.dumps({"cmd": "data", "data": token, "seq": i}))
|
|
200
|
+
await ws.send(json.dumps({"cmd": "close"}))
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 断线重连
|
|
204
|
+
|
|
205
|
+
WebSocket 断开后,服务端保留流状态最多 120 秒。重连后继续从断点 seq 推送即可。
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## 数据面:拉流 HTTP SSE
|
|
210
|
+
|
|
211
|
+
连接 `stream.create` 返回的 `pull_url`,接收标准 SSE 流。
|
|
212
|
+
|
|
213
|
+
当前实现优先从 `Authorization: Bearer` 读取 pull token;若提供拉流方 AID,优先使用 `X-Stream-AID` 请求头,query 参数仅作兼容回退。
|
|
214
|
+
|
|
215
|
+
### SSE 格式
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
data: Hello
|
|
219
|
+
|
|
220
|
+
data: World
|
|
221
|
+
|
|
222
|
+
event: done
|
|
223
|
+
data: {}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
- `data:` — 原始数据内容
|
|
227
|
+
- `event: done` — 流结束信号
|
|
228
|
+
- `: keep-alive` — 心跳注释(每 10 秒)
|
|
229
|
+
|
|
230
|
+
### 断线续拉
|
|
231
|
+
|
|
232
|
+
当前实现支持标准 SSE 的 `Last-Event-ID` 续拉:
|
|
233
|
+
|
|
234
|
+
- 服务端在每个 SSE 数据块中写入 `id: {seq}`
|
|
235
|
+
- 客户端重连时可携带 `Last-Event-ID`
|
|
236
|
+
- 服务端会跳过 `seq <= Last-Event-ID` 的缓冲数据,再继续实时推送
|
|
237
|
+
|
|
238
|
+
注意:这只覆盖仍保留在当前流内存缓冲中的历史数据,不是持久化重放。
|
|
239
|
+
如果请求的 seq 早于当前内存缓冲最小值,服务端不会返回显式 gap 错误,而是从仍保留的最早帧继续推送。
|
|
240
|
+
|
|
241
|
+
### 完整示例
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
import aiohttp
|
|
245
|
+
|
|
246
|
+
async with aiohttp.ClientSession() as session:
|
|
247
|
+
async with session.get(pull_url, headers={"Accept": "text/event-stream"}) as resp:
|
|
248
|
+
buffer = ""
|
|
249
|
+
async for chunk in resp.content.iter_any():
|
|
250
|
+
buffer += chunk.decode()
|
|
251
|
+
# 解析 SSE 帧...
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### HTTP 错误码
|
|
255
|
+
|
|
256
|
+
| 状态码 | 说明 |
|
|
257
|
+
|--------|------|
|
|
258
|
+
| 403 | pull_token 无效,或显式提供的 aid 与 target_aid 不匹配 |
|
|
259
|
+
| 404 | 流不存在 |
|
|
260
|
+
| 410 | 流已关闭 |
|
|
261
|
+
| 429 | 拉流端数量已达上限 |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 控制面错误码汇总
|
|
266
|
+
|
|
267
|
+
| code | message | 说明 |
|
|
268
|
+
|------|---------|------|
|
|
269
|
+
| -33401 | Stream not found | stream_id 无效或流已被清理 |
|
|
270
|
+
| -33402 | Stream limit exceeded | 活跃流数超过上限 |
|
|
271
|
+
| -33403 | Stream permission denied | 非创建者执行受限操作 |
|
|
272
|
+
| -33404 | Stream already closed | 流已关闭 |
|
|
273
|
+
| -33405 | Stream invalid params | 参数无效(如缺少 stream_id) |
|
|
274
|
+
| -33406 | Stream rate limited | 速率限制 |
|
|
275
|
+
| -33407 | Stream internal error | 服务内部错误 |
|