@rethinkingstudio/clawpilot 2.0.0-beta.0 → 2.0.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/dist/commands/pair.js +3 -5
- package/dist/commands/pair.js.map +1 -1
- package/dist/platform/service-manager.js +9 -13
- package/dist/platform/service-manager.js.map +1 -1
- package/package.json +7 -1
- package/rethinkingstudio-clawpilot-1.1.17.tgz +0 -0
- package/src/commands/assistant-send.ts +0 -91
- package/src/commands/install.ts +0 -131
- package/src/commands/local-handlers.ts +0 -533
- package/src/commands/openclaw-cli.ts +0 -354
- package/src/commands/pair.ts +0 -128
- package/src/commands/provider-config.ts +0 -275
- package/src/commands/provider-handlers.ts +0 -184
- package/src/commands/provider-registry.ts +0 -138
- package/src/commands/run.ts +0 -34
- package/src/commands/send.ts +0 -42
- package/src/commands/session-key.ts +0 -77
- package/src/commands/set-token.ts +0 -45
- package/src/commands/status.ts +0 -157
- package/src/commands/upload.ts +0 -141
- package/src/config/config.ts +0 -137
- package/src/generated/build-config.ts +0 -1
- package/src/i18n/index.ts +0 -185
- package/src/index.ts +0 -166
- package/src/media/assistant-attachments.ts +0 -205
- package/src/media/oss-uploader.ts +0 -306
- package/src/platform/service-manager.ts +0 -919
- package/src/relay/gateway-client.ts +0 -359
- package/src/relay/reconnect.ts +0 -37
- package/src/relay/relay-manager.ts +0 -328
- package/test-chat.mjs +0 -64
- package/test-direct.mjs +0 -171
- package/tsconfig.json +0 -16
|
@@ -1,306 +0,0 @@
|
|
|
1
|
-
import { createHmac } from "crypto";
|
|
2
|
-
import { randomUUID } from "crypto";
|
|
3
|
-
import { extname } from "path";
|
|
4
|
-
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
// Types
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
|
|
9
|
-
export interface StsCredentials {
|
|
10
|
-
bucket: string;
|
|
11
|
-
region: string;
|
|
12
|
-
endpoint: string;
|
|
13
|
-
baseUrl: string;
|
|
14
|
-
dirPrefix: string;
|
|
15
|
-
expiresAt: number;
|
|
16
|
-
credentials: {
|
|
17
|
-
accessKeyId: string;
|
|
18
|
-
accessKeySecret: string;
|
|
19
|
-
securityToken: string;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface UploadResult {
|
|
24
|
-
url: string; // public CDN URL
|
|
25
|
-
thumbnailUrl?: string; // OSS snapshot URL (video only)
|
|
26
|
-
mimeType: string;
|
|
27
|
-
size: number;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
// OSS HMAC-SHA1 request signing (with STS security token)
|
|
32
|
-
// ---------------------------------------------------------------------------
|
|
33
|
-
|
|
34
|
-
function ossSign(
|
|
35
|
-
method: string,
|
|
36
|
-
contentMd5: string,
|
|
37
|
-
contentType: string,
|
|
38
|
-
date: string,
|
|
39
|
-
canonicalizedHeaders: string,
|
|
40
|
-
canonicalizedResource: string,
|
|
41
|
-
secretKey: string
|
|
42
|
-
): string {
|
|
43
|
-
const stringToSign = [
|
|
44
|
-
method,
|
|
45
|
-
contentMd5,
|
|
46
|
-
contentType,
|
|
47
|
-
date,
|
|
48
|
-
canonicalizedHeaders + canonicalizedResource,
|
|
49
|
-
].join("\n");
|
|
50
|
-
return createHmac("sha1", secretKey).update(stringToSign).digest("base64");
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function buildBucketEndpoint(endpoint: string, bucket: string): string {
|
|
54
|
-
const url = new URL(endpoint);
|
|
55
|
-
if (!url.hostname.startsWith(`${bucket}.`)) {
|
|
56
|
-
url.hostname = `${bucket}.${url.hostname}`;
|
|
57
|
-
}
|
|
58
|
-
return url.toString().replace(/\/$/, "");
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// ---------------------------------------------------------------------------
|
|
62
|
-
// Simple PutObject upload (images / small files)
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
|
|
65
|
-
export async function putObject(
|
|
66
|
-
sts: StsCredentials,
|
|
67
|
-
data: Buffer,
|
|
68
|
-
ext: string,
|
|
69
|
-
mimeType: string
|
|
70
|
-
): Promise<UploadResult> {
|
|
71
|
-
const { bucket, endpoint, baseUrl, dirPrefix, credentials } = sts;
|
|
72
|
-
const objectKey = `${dirPrefix}/${randomUUID()}${ext}`;
|
|
73
|
-
const date = new Date().toUTCString();
|
|
74
|
-
const canonicalizedResource = `/${bucket}/${objectKey}`;
|
|
75
|
-
const canonicalizedHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
|
|
76
|
-
|
|
77
|
-
const sig = ossSign(
|
|
78
|
-
"PUT",
|
|
79
|
-
"",
|
|
80
|
-
mimeType,
|
|
81
|
-
date,
|
|
82
|
-
canonicalizedHeaders,
|
|
83
|
-
canonicalizedResource,
|
|
84
|
-
credentials.accessKeySecret
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
const url = `${buildBucketEndpoint(endpoint, bucket)}/${objectKey}`;
|
|
88
|
-
const res = await fetch(url, {
|
|
89
|
-
method: "PUT",
|
|
90
|
-
headers: {
|
|
91
|
-
"Content-Type": mimeType,
|
|
92
|
-
"Date": date,
|
|
93
|
-
"x-oss-security-token": credentials.securityToken,
|
|
94
|
-
"Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
|
|
95
|
-
},
|
|
96
|
-
body: data as unknown as BodyInit,
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
if (!res.ok) {
|
|
100
|
-
const text = await res.text().catch(() => "");
|
|
101
|
-
throw new Error(`OSS PutObject failed: ${res.status} ${text}`);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const publicUrl = `${baseUrl.replace(/\/$/, "")}/${objectKey}`;
|
|
105
|
-
return { url: publicUrl, mimeType, size: data.length };
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// ---------------------------------------------------------------------------
|
|
109
|
-
// Multipart upload (videos > 10 MB)
|
|
110
|
-
// ---------------------------------------------------------------------------
|
|
111
|
-
|
|
112
|
-
const PART_SIZE = 5 * 1024 * 1024; // 5 MB per part
|
|
113
|
-
|
|
114
|
-
export async function multipartUpload(
|
|
115
|
-
sts: StsCredentials,
|
|
116
|
-
data: Buffer,
|
|
117
|
-
ext: string,
|
|
118
|
-
mimeType: string
|
|
119
|
-
): Promise<UploadResult> {
|
|
120
|
-
const { bucket, endpoint, baseUrl, dirPrefix, credentials } = sts;
|
|
121
|
-
const objectKey = `${dirPrefix}/${randomUUID()}${ext}`;
|
|
122
|
-
const baseOssUrl = `${buildBucketEndpoint(endpoint, bucket)}/${objectKey}`;
|
|
123
|
-
|
|
124
|
-
function makeHeaders(
|
|
125
|
-
method: string,
|
|
126
|
-
contentType: string,
|
|
127
|
-
extraHeaders: Record<string, string>,
|
|
128
|
-
resource: string
|
|
129
|
-
): Headers {
|
|
130
|
-
const date = new Date().toUTCString();
|
|
131
|
-
const canonicalizedHeaders = [
|
|
132
|
-
"x-oss-security-token:" + credentials.securityToken,
|
|
133
|
-
...Object.entries(extraHeaders)
|
|
134
|
-
.filter(([k]) => k.startsWith("x-oss-"))
|
|
135
|
-
.sort()
|
|
136
|
-
.map(([k, v]) => `${k}:${v}`),
|
|
137
|
-
]
|
|
138
|
-
.sort()
|
|
139
|
-
.join("\n") + "\n";
|
|
140
|
-
|
|
141
|
-
const sig = ossSign(
|
|
142
|
-
method,
|
|
143
|
-
"",
|
|
144
|
-
contentType,
|
|
145
|
-
date,
|
|
146
|
-
canonicalizedHeaders,
|
|
147
|
-
`/${bucket}/${objectKey}`,
|
|
148
|
-
credentials.accessKeySecret
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
const headers = new Headers({
|
|
152
|
-
"Date": date,
|
|
153
|
-
"x-oss-security-token": credentials.securityToken,
|
|
154
|
-
"Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
|
|
155
|
-
...extraHeaders,
|
|
156
|
-
});
|
|
157
|
-
if (contentType) headers.set("Content-Type", contentType);
|
|
158
|
-
return headers;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// 1. Initiate
|
|
162
|
-
const initRes = await fetch(`${baseOssUrl}?uploads`, {
|
|
163
|
-
method: "POST",
|
|
164
|
-
headers: makeHeaders("POST", mimeType, {}, `/${bucket}/${objectKey}`),
|
|
165
|
-
});
|
|
166
|
-
if (!initRes.ok) throw new Error(`OSS InitiateMultipartUpload failed: ${initRes.status}`);
|
|
167
|
-
const initText = await initRes.text();
|
|
168
|
-
const uploadIdMatch = initText.match(/<UploadId>([^<]+)<\/UploadId>/);
|
|
169
|
-
if (!uploadIdMatch) throw new Error("OSS: could not parse UploadId");
|
|
170
|
-
const uploadId = uploadIdMatch[1];
|
|
171
|
-
|
|
172
|
-
// 2. Upload parts
|
|
173
|
-
const parts: Array<{ partNumber: number; etag: string }> = [];
|
|
174
|
-
let partNumber = 1;
|
|
175
|
-
let offset = 0;
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
while (offset < data.length) {
|
|
179
|
-
const chunk = data.slice(offset, offset + PART_SIZE);
|
|
180
|
-
const partDate = new Date().toUTCString();
|
|
181
|
-
const canonicalizedHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
|
|
182
|
-
const sig = ossSign(
|
|
183
|
-
"PUT", "", "application/octet-stream", partDate,
|
|
184
|
-
canonicalizedHeaders, `/${bucket}/${objectKey}`,
|
|
185
|
-
credentials.accessKeySecret
|
|
186
|
-
);
|
|
187
|
-
const partRes = await fetch(
|
|
188
|
-
`${baseOssUrl}?partNumber=${partNumber}&uploadId=${uploadId}`,
|
|
189
|
-
{
|
|
190
|
-
method: "PUT",
|
|
191
|
-
headers: {
|
|
192
|
-
"Content-Type": "application/octet-stream",
|
|
193
|
-
"Date": partDate,
|
|
194
|
-
"x-oss-security-token": credentials.securityToken,
|
|
195
|
-
"Authorization": `OSS ${credentials.accessKeyId}:${sig}`,
|
|
196
|
-
},
|
|
197
|
-
body: chunk as unknown as BodyInit,
|
|
198
|
-
}
|
|
199
|
-
);
|
|
200
|
-
if (!partRes.ok) throw new Error(`OSS UploadPart ${partNumber} failed: ${partRes.status}`);
|
|
201
|
-
const etag = partRes.headers.get("etag") ?? "";
|
|
202
|
-
parts.push({ partNumber, etag });
|
|
203
|
-
partNumber++;
|
|
204
|
-
offset += PART_SIZE;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// 3. Complete
|
|
208
|
-
const completeBody = [
|
|
209
|
-
"<CompleteMultipartUpload>",
|
|
210
|
-
...parts.map(
|
|
211
|
-
(p) => `<Part><PartNumber>${p.partNumber}</PartNumber><ETag>${p.etag}</ETag></Part>`
|
|
212
|
-
),
|
|
213
|
-
"</CompleteMultipartUpload>",
|
|
214
|
-
].join("");
|
|
215
|
-
|
|
216
|
-
const completeDate = new Date().toUTCString();
|
|
217
|
-
const cHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
|
|
218
|
-
const cSig = ossSign(
|
|
219
|
-
"POST", "", "application/xml", completeDate,
|
|
220
|
-
cHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret
|
|
221
|
-
);
|
|
222
|
-
const completeRes = await fetch(`${baseOssUrl}?uploadId=${uploadId}`, {
|
|
223
|
-
method: "POST",
|
|
224
|
-
headers: {
|
|
225
|
-
"Content-Type": "application/xml",
|
|
226
|
-
"Date": completeDate,
|
|
227
|
-
"x-oss-security-token": credentials.securityToken,
|
|
228
|
-
"Authorization": `OSS ${credentials.accessKeyId}:${cSig}`,
|
|
229
|
-
},
|
|
230
|
-
body: completeBody,
|
|
231
|
-
});
|
|
232
|
-
if (!completeRes.ok) throw new Error(`OSS CompleteMultipartUpload failed: ${completeRes.status}`);
|
|
233
|
-
|
|
234
|
-
} catch (err) {
|
|
235
|
-
// Best-effort abort to avoid billing for incomplete upload
|
|
236
|
-
try {
|
|
237
|
-
const abortDate = new Date().toUTCString();
|
|
238
|
-
const aHeaders = `x-oss-security-token:${credentials.securityToken}\n`;
|
|
239
|
-
const aSig = ossSign(
|
|
240
|
-
"DELETE", "", "", abortDate,
|
|
241
|
-
aHeaders, `/${bucket}/${objectKey}`, credentials.accessKeySecret
|
|
242
|
-
);
|
|
243
|
-
await fetch(`${baseOssUrl}?uploadId=${uploadId}`, {
|
|
244
|
-
method: "DELETE",
|
|
245
|
-
headers: {
|
|
246
|
-
"Date": abortDate,
|
|
247
|
-
"x-oss-security-token": credentials.securityToken,
|
|
248
|
-
"Authorization": `OSS ${credentials.accessKeyId}:${aSig}`,
|
|
249
|
-
},
|
|
250
|
-
});
|
|
251
|
-
} catch { /* ignore abort errors */ }
|
|
252
|
-
throw err;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const publicUrl = `${baseUrl.replace(/\/$/, "")}/${objectKey}`;
|
|
256
|
-
// OSS video snapshot thumbnail URL
|
|
257
|
-
const thumbnailUrl = `${publicUrl}?x-oss-process=video/snapshot,t_0,f_jpg,w_0,h_0,m_fast`;
|
|
258
|
-
return { url: publicUrl, thumbnailUrl, mimeType, size: data.length };
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// ---------------------------------------------------------------------------
|
|
262
|
-
// Convenience: auto-select PutObject vs multipart based on size
|
|
263
|
-
// ---------------------------------------------------------------------------
|
|
264
|
-
|
|
265
|
-
const MULTIPART_THRESHOLD = 10 * 1024 * 1024; // 10 MB
|
|
266
|
-
|
|
267
|
-
export async function uploadMedia(
|
|
268
|
-
sts: StsCredentials,
|
|
269
|
-
data: Buffer,
|
|
270
|
-
mimeType: string,
|
|
271
|
-
fileName?: string
|
|
272
|
-
): Promise<UploadResult> {
|
|
273
|
-
const ext = extname(fileName ?? "") || mimeTypeToExt(mimeType);
|
|
274
|
-
if (data.length >= MULTIPART_THRESHOLD) {
|
|
275
|
-
return multipartUpload(sts, data, ext, mimeType);
|
|
276
|
-
}
|
|
277
|
-
return putObject(sts, data, ext, mimeType);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
function mimeTypeToExt(mimeType: string): string {
|
|
281
|
-
const map: Record<string, string> = {
|
|
282
|
-
"image/jpeg": ".jpg",
|
|
283
|
-
"image/png": ".png",
|
|
284
|
-
"image/gif": ".gif",
|
|
285
|
-
"image/webp": ".webp",
|
|
286
|
-
"video/mp4": ".mp4",
|
|
287
|
-
"video/quicktime": ".mov",
|
|
288
|
-
"audio/mpeg": ".mp3",
|
|
289
|
-
"audio/mp4": ".m4a",
|
|
290
|
-
"audio/wav": ".wav",
|
|
291
|
-
"audio/x-wav": ".wav",
|
|
292
|
-
"audio/aac": ".aac",
|
|
293
|
-
"application/pdf": ".pdf",
|
|
294
|
-
"text/plain": ".txt",
|
|
295
|
-
"text/markdown": ".md",
|
|
296
|
-
"application/json": ".json",
|
|
297
|
-
"application/vnd.ms-excel": ".xls",
|
|
298
|
-
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx",
|
|
299
|
-
"application/msword": ".doc",
|
|
300
|
-
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": ".docx",
|
|
301
|
-
"application/vnd.ms-powerpoint": ".ppt",
|
|
302
|
-
"application/vnd.openxmlformats-officedocument.presentationml.presentation": ".pptx",
|
|
303
|
-
"text/csv": ".csv",
|
|
304
|
-
};
|
|
305
|
-
return map[mimeType] ?? ".bin";
|
|
306
|
-
}
|