metainsight-context-engine 0.0.1
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/BOOTSTRAP.md +341 -0
- package/README.md +230 -0
- package/dist/cos-bootstrap.d.ts +221 -0
- package/dist/cos-bootstrap.d.ts.map +1 -0
- package/dist/cos-bootstrap.js +598 -0
- package/dist/cos-bootstrap.js.map +1 -0
- package/dist/cos-operations.d.ts +219 -0
- package/dist/cos-operations.d.ts.map +1 -0
- package/dist/cos-operations.js +583 -0
- package/dist/cos-operations.js.map +1 -0
- package/dist/engine.d.ts +101 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +157 -0
- package/dist/engine.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +993 -0
- package/dist/index.js.map +1 -0
- package/dist/local-memory-sync.d.ts +204 -0
- package/dist/local-memory-sync.d.ts.map +1 -0
- package/dist/local-memory-sync.js +1126 -0
- package/dist/local-memory-sync.js.map +1 -0
- package/openclaw.plugin.json +225 -0
- package/package.json +78 -0
|
@@ -0,0 +1,598 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* COS Bootstrap — Infrastructure Initialization
|
|
3
|
+
*
|
|
4
|
+
* Ensures all preconditions for the Cloud Context Engine are met before
|
|
5
|
+
* the engine starts processing requests:
|
|
6
|
+
*
|
|
7
|
+
* 1. COS SDK instance is initialized (SecretId / SecretKey auth)
|
|
8
|
+
* 2. Target bucket exists (headBucket → putBucket if missing)
|
|
9
|
+
* 3. For each dataset definition:
|
|
10
|
+
* a. Dataset exists (GET /dataset → POST /dataset if missing)
|
|
11
|
+
* b. Dataset ↔ Bucket binding exists (GET /datasetbinding → POST /datasetbinding if missing)
|
|
12
|
+
*
|
|
13
|
+
* The module supports **multiple datasets** per bucket — each dataset has its
|
|
14
|
+
* own COS path prefix and CI template. The default setup includes a "memory"
|
|
15
|
+
* dataset (DocSearch) and an "image" dataset (ImageSearch) for multimodal
|
|
16
|
+
* retrieval. Users can extend it with "knowledge" or any custom datasets.
|
|
17
|
+
*
|
|
18
|
+
* **Multi-agent isolation**: When `agentId` is set, the default cosPrefix
|
|
19
|
+
* becomes `openclaw-{agentId}/workspace/memory/`. This allows multiple
|
|
20
|
+
* agents to share the same bucket without data collisions.
|
|
21
|
+
*
|
|
22
|
+
* The module also exposes a generic `sendCIRequest()` helper for CI API
|
|
23
|
+
* calls (used by cos-operations.ts for hybridsearch, upload, etc.).
|
|
24
|
+
*
|
|
25
|
+
* Supported regions: ap-beijing, ap-shanghai, ap-chengdu
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* // Minimal — uses default datasets (memory)
|
|
30
|
+
* bootstrap({ secretId, secretKey, appId: '1253311026' }, logger);
|
|
31
|
+
*
|
|
32
|
+
* // Extended — add a custom knowledge dataset alongside defaults
|
|
33
|
+
* bootstrap({
|
|
34
|
+
* secretId, secretKey,
|
|
35
|
+
* appId: '1253311026',
|
|
36
|
+
* datasets: [
|
|
37
|
+
* { name: 'my-memory', cosPrefix: 'memory/', templateId: 'Official:DocSearch' },
|
|
38
|
+
* { name: 'my-knowledge', cosPrefix: 'knowledge/', templateId: 'Official:DocSearch' },
|
|
39
|
+
* ],
|
|
40
|
+
* }, logger);
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
// cos-nodejs-sdk-v5 uses `export = COS` (CJS style)
|
|
44
|
+
import COS from 'cos-nodejs-sdk-v5';
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Error serialization helper
|
|
47
|
+
// ============================================================================
|
|
48
|
+
/**
|
|
49
|
+
* Convert an unknown error value into a human-readable string.
|
|
50
|
+
*
|
|
51
|
+
* COS SDK often throws plain objects like `{statusCode, code, message, resource}`
|
|
52
|
+
* instead of Error instances. `String(obj)` on these produces `[object Object]`.
|
|
53
|
+
* This helper extracts the most useful fields for logging/error messages.
|
|
54
|
+
*/
|
|
55
|
+
function serializeError(err) {
|
|
56
|
+
if (err instanceof Error) {
|
|
57
|
+
return err.message;
|
|
58
|
+
}
|
|
59
|
+
if (typeof err === 'string') {
|
|
60
|
+
return err;
|
|
61
|
+
}
|
|
62
|
+
if (typeof err === 'object' && err !== null) {
|
|
63
|
+
const obj = err;
|
|
64
|
+
const parts = [];
|
|
65
|
+
if (obj.code) {
|
|
66
|
+
parts.push(`code=${String(obj.code)}`);
|
|
67
|
+
}
|
|
68
|
+
if (obj.statusCode) {
|
|
69
|
+
parts.push(`status=${String(obj.statusCode)}`);
|
|
70
|
+
}
|
|
71
|
+
if (obj.message) {
|
|
72
|
+
parts.push(String(obj.message));
|
|
73
|
+
}
|
|
74
|
+
if (obj.resource) {
|
|
75
|
+
parts.push(`resource=${String(obj.resource)}`);
|
|
76
|
+
}
|
|
77
|
+
return parts.length > 0 ? parts.join(', ') : JSON.stringify(err);
|
|
78
|
+
}
|
|
79
|
+
return String(err);
|
|
80
|
+
}
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// Constants
|
|
83
|
+
// ============================================================================
|
|
84
|
+
const SUPPORTED_REGIONS = ['ap-beijing', 'ap-shanghai', 'ap-chengdu'];
|
|
85
|
+
/**
|
|
86
|
+
* Default datasets (no agentId):
|
|
87
|
+
* - "openclaw-memory" → COS prefix `memory/` (conversation memory documents, DocSearch)
|
|
88
|
+
* - "openclaw-image" → COS prefix `asset/` (image retrieval dataset, ImageSearch)
|
|
89
|
+
* - "openclaw-document" → COS prefix `asset/` (document retrieval dataset, DocSearch)
|
|
90
|
+
*/
|
|
91
|
+
const DEFAULT_DATASETS = [
|
|
92
|
+
{
|
|
93
|
+
name: 'openclaw-memory',
|
|
94
|
+
cosPrefix: 'memory/',
|
|
95
|
+
templateId: 'Official:DocSearch',
|
|
96
|
+
description: 'OpenClaw Cloud Context Engine — memory document search dataset',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'openclaw-image',
|
|
100
|
+
cosPrefix: 'asset/',
|
|
101
|
+
templateId: 'Official:ImageSearch',
|
|
102
|
+
description: 'OpenClaw Cloud Context Engine — image search dataset',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'openclaw-document',
|
|
106
|
+
cosPrefix: 'asset/',
|
|
107
|
+
templateId: 'Official:DocSearch',
|
|
108
|
+
description: 'OpenClaw Cloud Context Engine — document retrieval dataset',
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
const DEFAULTS = {
|
|
112
|
+
bucket: 'openclaw-metainsight',
|
|
113
|
+
region: 'ap-beijing',
|
|
114
|
+
};
|
|
115
|
+
// ============================================================================
|
|
116
|
+
// Singleton COS instance (per secretId)
|
|
117
|
+
// ============================================================================
|
|
118
|
+
let cosInstance = null;
|
|
119
|
+
let lastSecretId = '';
|
|
120
|
+
/**
|
|
121
|
+
* Get (or create) the COS SDK singleton.
|
|
122
|
+
*/
|
|
123
|
+
export function getCOSInstance(secretId, secretKey) {
|
|
124
|
+
if (cosInstance && lastSecretId === secretId) {
|
|
125
|
+
return cosInstance;
|
|
126
|
+
}
|
|
127
|
+
cosInstance = new COS({
|
|
128
|
+
SecretId: secretId,
|
|
129
|
+
SecretKey: secretKey,
|
|
130
|
+
});
|
|
131
|
+
lastSecretId = secretId;
|
|
132
|
+
return cosInstance;
|
|
133
|
+
}
|
|
134
|
+
// ============================================================================
|
|
135
|
+
// Config resolution
|
|
136
|
+
// ============================================================================
|
|
137
|
+
/**
|
|
138
|
+
* Merge user-provided config with defaults, validate region.
|
|
139
|
+
*
|
|
140
|
+
* The bucket name is automatically resolved to COS format: `{shortName}-{APPID}`.
|
|
141
|
+
* If the user-provided bucket already contains the APPID suffix, it is used as-is.
|
|
142
|
+
*
|
|
143
|
+
* When `datasets` is omitted, three default datasets are created (memory, image, document).
|
|
144
|
+
* Each dataset's `cosPrefix` is normalized to end with "/".
|
|
145
|
+
*/
|
|
146
|
+
export function resolveConfig(input) {
|
|
147
|
+
const region = input.region ?? DEFAULTS.region;
|
|
148
|
+
if (!SUPPORTED_REGIONS.includes(region)) {
|
|
149
|
+
throw new Error(`cos-bootstrap: unsupported region "${region}". Supported: ${SUPPORTED_REGIONS.join(', ')}`);
|
|
150
|
+
}
|
|
151
|
+
if (!input.appId) {
|
|
152
|
+
throw new Error('cos-bootstrap: "appId" is required. '
|
|
153
|
+
+ 'Obtain from https://console.cloud.tencent.com/cam/capi');
|
|
154
|
+
}
|
|
155
|
+
const shortBucket = input.bucket ?? DEFAULTS.bucket;
|
|
156
|
+
// If bucket already ends with `-{appId}`, use as-is; otherwise append
|
|
157
|
+
const bucket = shortBucket.endsWith(`-${input.appId}`)
|
|
158
|
+
? shortBucket
|
|
159
|
+
: `${shortBucket}-${input.appId}`;
|
|
160
|
+
// Resolve datasets — use defaults when omitted.
|
|
161
|
+
// When agentId is set and no explicit datasets are provided, the default
|
|
162
|
+
// cosPrefix becomes `openclaw-{agentId}/workspace/memory/` for multi-agent isolation.
|
|
163
|
+
const agentId = input.agentId?.trim();
|
|
164
|
+
let rawDatasets;
|
|
165
|
+
if (input.datasets && input.datasets.length > 0) {
|
|
166
|
+
rawDatasets = input.datasets;
|
|
167
|
+
}
|
|
168
|
+
else if (agentId) {
|
|
169
|
+
rawDatasets = [
|
|
170
|
+
{
|
|
171
|
+
name: `openclaw-${agentId}-memory`,
|
|
172
|
+
cosPrefix: `openclaw-${agentId}/workspace/`,
|
|
173
|
+
templateId: 'Official:DocSearch',
|
|
174
|
+
description: `OpenClaw Cloud Context Engine — memory dataset for agent "${agentId}"`,
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
name: `openclaw-${agentId}-image`,
|
|
178
|
+
cosPrefix: `openclaw-${agentId}/asset/`,
|
|
179
|
+
templateId: 'Official:ImageSearch',
|
|
180
|
+
description: `OpenClaw Cloud Context Engine — image search dataset for agent "${agentId}"`,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: `openclaw-${agentId}-document`,
|
|
184
|
+
cosPrefix: `openclaw-${agentId}/asset/`,
|
|
185
|
+
templateId: 'Official:DocSearch',
|
|
186
|
+
description: `OpenClaw Cloud Context Engine — document retrieval dataset for agent "${agentId}"`,
|
|
187
|
+
},
|
|
188
|
+
];
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
rawDatasets = DEFAULT_DATASETS;
|
|
192
|
+
}
|
|
193
|
+
const datasets = rawDatasets.map((ds) => {
|
|
194
|
+
if (!ds.name) {
|
|
195
|
+
throw new Error('cos-bootstrap: each dataset must have a non-empty "name"');
|
|
196
|
+
}
|
|
197
|
+
// Ensure cosPrefix ends with "/"
|
|
198
|
+
let cosPrefix = ds.cosPrefix || `${ds.name}/`;
|
|
199
|
+
if (!cosPrefix.endsWith('/')) {
|
|
200
|
+
cosPrefix = `${cosPrefix}/`;
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
name: ds.name,
|
|
204
|
+
cosPrefix,
|
|
205
|
+
templateId: ds.templateId ?? 'Official:DocSearch',
|
|
206
|
+
description: ds.description ?? `OpenClaw dataset — ${ds.name}`,
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
// Validate no duplicate dataset names
|
|
210
|
+
const names = new Set();
|
|
211
|
+
for (const ds of datasets) {
|
|
212
|
+
if (names.has(ds.name)) {
|
|
213
|
+
throw new Error(`cos-bootstrap: duplicate dataset name "${ds.name}"`);
|
|
214
|
+
}
|
|
215
|
+
names.add(ds.name);
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
secretId: input.secretId,
|
|
219
|
+
secretKey: input.secretKey,
|
|
220
|
+
appId: input.appId,
|
|
221
|
+
agentId: agentId || undefined,
|
|
222
|
+
bucket,
|
|
223
|
+
region,
|
|
224
|
+
datasets,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// ============================================================================
|
|
228
|
+
// Generic CI API helper
|
|
229
|
+
// ============================================================================
|
|
230
|
+
/**
|
|
231
|
+
* Construct the CI host for a given bucket and region.
|
|
232
|
+
* Format: `{bucket}.ci.{region}.myqcloud.com`
|
|
233
|
+
*/
|
|
234
|
+
function getCIHost(bucket, region) {
|
|
235
|
+
return `${bucket}.ci.${region}.myqcloud.com`;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Send a request to the COS CI API with automatic SDK signing.
|
|
239
|
+
*
|
|
240
|
+
* @param cos COS SDK instance
|
|
241
|
+
* @param bucket Bucket name
|
|
242
|
+
* @param region COS region
|
|
243
|
+
* @param method HTTP method (GET / POST / PUT / DELETE)
|
|
244
|
+
* @param endpoint CI API endpoint path (e.g. "dataset", "datasetbinding", "datasetquery/hybridsearch")
|
|
245
|
+
* @param body Optional JSON request body
|
|
246
|
+
* @param query Optional query string parameters
|
|
247
|
+
* @returns Parsed JSON response
|
|
248
|
+
*/
|
|
249
|
+
export async function sendCIRequest(cos, bucket, region, method, endpoint, body, query) {
|
|
250
|
+
const host = getCIHost(bucket, region);
|
|
251
|
+
const url = `https://${host}/${endpoint}`;
|
|
252
|
+
const requestConfig = {
|
|
253
|
+
Method: method,
|
|
254
|
+
Key: endpoint,
|
|
255
|
+
Url: url,
|
|
256
|
+
Headers: {
|
|
257
|
+
'Accept': 'application/json',
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
if (query && Object.keys(query).length > 0) {
|
|
261
|
+
requestConfig.Query = query;
|
|
262
|
+
}
|
|
263
|
+
if (body) {
|
|
264
|
+
requestConfig.Headers['Content-Type'] = 'application/json';
|
|
265
|
+
requestConfig.Body = JSON.stringify(body);
|
|
266
|
+
}
|
|
267
|
+
return new Promise((resolve, reject) => {
|
|
268
|
+
cos.request(requestConfig, (err, data) => {
|
|
269
|
+
if (err) {
|
|
270
|
+
reject(err);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
// Attempt to parse JSON body if the response is a string
|
|
274
|
+
const raw = data;
|
|
275
|
+
if (raw && typeof raw.Body === 'string') {
|
|
276
|
+
try {
|
|
277
|
+
resolve(JSON.parse(raw.Body));
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
// fallback — return raw
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
resolve(raw);
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
// ============================================================================
|
|
289
|
+
// Simple retry helper
|
|
290
|
+
// ============================================================================
|
|
291
|
+
async function withRetry(fn, retries = 2, delayMs = 1000) {
|
|
292
|
+
let lastError;
|
|
293
|
+
for (let attempt = 0; attempt <= retries; attempt += 1) {
|
|
294
|
+
try {
|
|
295
|
+
return await fn();
|
|
296
|
+
}
|
|
297
|
+
catch (err) {
|
|
298
|
+
lastError = err;
|
|
299
|
+
if (attempt < retries) {
|
|
300
|
+
await new Promise((r) => setTimeout(r, delayMs * (attempt + 1)));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
throw lastError;
|
|
305
|
+
}
|
|
306
|
+
// ============================================================================
|
|
307
|
+
// Simple cache (TTL-based)
|
|
308
|
+
// ============================================================================
|
|
309
|
+
const cache = new Map();
|
|
310
|
+
const CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
311
|
+
function getCachedData(key) {
|
|
312
|
+
const entry = cache.get(key);
|
|
313
|
+
if (entry && entry.expiresAt > Date.now()) {
|
|
314
|
+
return entry.data;
|
|
315
|
+
}
|
|
316
|
+
cache.delete(key);
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
function setCachedData(key, data) {
|
|
320
|
+
cache.set(key, { data, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
321
|
+
}
|
|
322
|
+
// ============================================================================
|
|
323
|
+
// Bucket operations
|
|
324
|
+
// ============================================================================
|
|
325
|
+
/**
|
|
326
|
+
* Check whether the target bucket exists.
|
|
327
|
+
*/
|
|
328
|
+
async function doesBucketExist(cos, bucket, region) {
|
|
329
|
+
return new Promise((resolve, reject) => {
|
|
330
|
+
cos.headBucket({ Bucket: bucket, Region: region }, (err) => {
|
|
331
|
+
if (!err) {
|
|
332
|
+
resolve(true);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
// Distinguish "not found" from transient server errors
|
|
336
|
+
const error = err;
|
|
337
|
+
const statusCode = error.statusCode;
|
|
338
|
+
if (statusCode === 404 || statusCode === 403) {
|
|
339
|
+
// 404 = not found; 403 = exists but no permission (treat as not found for creation)
|
|
340
|
+
resolve(false);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// 500 / network errors should bubble up rather than falsely claiming "not found"
|
|
344
|
+
reject(new Error(`cos-bootstrap: headBucket failed: ${serializeError(err)}`));
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Create a new COS bucket.
|
|
350
|
+
*
|
|
351
|
+
* `BucketAlreadyOwnedByYou` is treated as success — it means the bucket
|
|
352
|
+
* already exists and is owned by this account (common race condition when
|
|
353
|
+
* multiple callers bootstrap concurrently).
|
|
354
|
+
*/
|
|
355
|
+
async function createBucket(cos, bucket, region) {
|
|
356
|
+
return new Promise((resolve, reject) => {
|
|
357
|
+
cos.putBucket({ Bucket: bucket, Region: region }, (err) => {
|
|
358
|
+
if (err) {
|
|
359
|
+
// BucketAlreadyOwnedByYou means we already own it — treat as success
|
|
360
|
+
const errStr = serializeError(err);
|
|
361
|
+
if (errStr.includes('BucketAlreadyOwnedByYou') || errStr.includes('BucketAlreadyExists')) {
|
|
362
|
+
resolve();
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
reject(new Error(`cos-bootstrap: failed to create bucket "${bucket}": ${errStr}`));
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
resolve();
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
// ============================================================================
|
|
373
|
+
// Dataset operations
|
|
374
|
+
// ============================================================================
|
|
375
|
+
/**
|
|
376
|
+
* Query dataset info (with cache).
|
|
377
|
+
*/
|
|
378
|
+
async function getDatasetInfo(cos, bucket, region, datasetName) {
|
|
379
|
+
const cacheKey = `dataset-info-${datasetName}`;
|
|
380
|
+
const cached = getCachedData(cacheKey);
|
|
381
|
+
if (cached) {
|
|
382
|
+
return cached;
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
const result = await withRetry(async () => {
|
|
386
|
+
return await sendCIRequest(cos, bucket, region, 'GET', 'dataset', undefined, {
|
|
387
|
+
datasetname: datasetName,
|
|
388
|
+
statistics: 'true',
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
// Handle various response shapes from CI API
|
|
392
|
+
const res = result;
|
|
393
|
+
let datasetInfo = null;
|
|
394
|
+
const response = res.Response;
|
|
395
|
+
if (response?.Dataset) {
|
|
396
|
+
datasetInfo = response.Dataset;
|
|
397
|
+
}
|
|
398
|
+
else if (res.Dataset) {
|
|
399
|
+
datasetInfo = res.Dataset;
|
|
400
|
+
}
|
|
401
|
+
else if (res.DatasetName) {
|
|
402
|
+
datasetInfo = res;
|
|
403
|
+
}
|
|
404
|
+
if (datasetInfo) {
|
|
405
|
+
setCachedData(cacheKey, datasetInfo);
|
|
406
|
+
}
|
|
407
|
+
return datasetInfo;
|
|
408
|
+
}
|
|
409
|
+
catch (err) {
|
|
410
|
+
// 404 / 400 / not found → dataset doesn't exist (400 can occur when bucket is freshly created)
|
|
411
|
+
const error = err;
|
|
412
|
+
const statusCode = error.statusCode;
|
|
413
|
+
const code = error.code;
|
|
414
|
+
const msg = typeof error.message === 'string' ? error.message : '';
|
|
415
|
+
if (msg.includes('404')
|
|
416
|
+
|| statusCode === 404
|
|
417
|
+
|| statusCode === 400
|
|
418
|
+
|| code === 'NoSuchDataset') {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
throw new Error(`cos-bootstrap: failed to query dataset "${datasetName}": ${serializeError(err)}`);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Create a new CI dataset.
|
|
426
|
+
*/
|
|
427
|
+
async function createDataset(cos, bucket, region, datasetName, templateId, description) {
|
|
428
|
+
// CI API may return 400/500 right after bucket creation; retry with backoff.
|
|
429
|
+
const result = await withRetry(async () => {
|
|
430
|
+
return await sendCIRequest(cos, bucket, region, 'POST', 'dataset', {
|
|
431
|
+
DatasetName: datasetName,
|
|
432
|
+
Description: description,
|
|
433
|
+
TemplateId: templateId,
|
|
434
|
+
});
|
|
435
|
+
}, 2, 2000);
|
|
436
|
+
const res = result;
|
|
437
|
+
const response = res.Response;
|
|
438
|
+
return (response?.Dataset ?? res.Dataset ?? res);
|
|
439
|
+
}
|
|
440
|
+
// ============================================================================
|
|
441
|
+
// Dataset binding operations
|
|
442
|
+
// ============================================================================
|
|
443
|
+
/**
|
|
444
|
+
* Query dataset ↔ bucket binding (with cache).
|
|
445
|
+
*
|
|
446
|
+
* @param cosPrefix COS key prefix the binding covers (e.g. "memory/")
|
|
447
|
+
*/
|
|
448
|
+
async function getDatasetBinding(cos, bucket, region, datasetName, cosPrefix) {
|
|
449
|
+
const uri = `cos://${bucket}/${cosPrefix}`;
|
|
450
|
+
const cacheKey = `binding-${datasetName}-${bucket}-${cosPrefix}`;
|
|
451
|
+
const cached = getCachedData(cacheKey);
|
|
452
|
+
if (cached) {
|
|
453
|
+
return cached;
|
|
454
|
+
}
|
|
455
|
+
try {
|
|
456
|
+
const result = await withRetry(async () => {
|
|
457
|
+
return await sendCIRequest(cos, bucket, region, 'GET', 'datasetbinding', undefined, {
|
|
458
|
+
datasetname: datasetName,
|
|
459
|
+
uri,
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
const res = result;
|
|
463
|
+
let binding = null;
|
|
464
|
+
const response = res.Response;
|
|
465
|
+
if (response?.Binding) {
|
|
466
|
+
binding = response.Binding;
|
|
467
|
+
}
|
|
468
|
+
else if (res.Binding) {
|
|
469
|
+
binding = res.Binding;
|
|
470
|
+
}
|
|
471
|
+
else if (res.State) {
|
|
472
|
+
binding = res;
|
|
473
|
+
}
|
|
474
|
+
if (binding) {
|
|
475
|
+
setCachedData(cacheKey, binding);
|
|
476
|
+
}
|
|
477
|
+
return binding;
|
|
478
|
+
}
|
|
479
|
+
catch (err) {
|
|
480
|
+
const error = err;
|
|
481
|
+
const statusCode = error.statusCode;
|
|
482
|
+
const code = error.code;
|
|
483
|
+
if (code === 'NoSuchBinding' || statusCode === 404 || statusCode === 400) {
|
|
484
|
+
return null;
|
|
485
|
+
}
|
|
486
|
+
throw new Error(`cos-bootstrap: failed to query dataset binding "${datasetName}": ${serializeError(err)}`);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Create dataset ↔ bucket binding.
|
|
491
|
+
*
|
|
492
|
+
* @param cosPrefix COS key prefix the binding covers (e.g. "memory/")
|
|
493
|
+
*/
|
|
494
|
+
async function createDatasetBinding(cos, bucket, region, datasetName, cosPrefix) {
|
|
495
|
+
// CI API may return 400/500 if dataset was just created; retry with backoff.
|
|
496
|
+
const result = await withRetry(async () => {
|
|
497
|
+
return await sendCIRequest(cos, bucket, region, 'POST', 'datasetbinding', {
|
|
498
|
+
DatasetName: datasetName,
|
|
499
|
+
URI: `cos://${bucket}/${cosPrefix}`,
|
|
500
|
+
Mode: 1,
|
|
501
|
+
});
|
|
502
|
+
}, 2, 2000);
|
|
503
|
+
const res = result;
|
|
504
|
+
const response = res.Response;
|
|
505
|
+
return (response?.Binding ?? res.Binding ?? res);
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Run the full bootstrap sequence:
|
|
509
|
+
* 1. Initialize COS SDK
|
|
510
|
+
* 2. Ensure bucket exists
|
|
511
|
+
* 3. For each dataset in config.datasets:
|
|
512
|
+
* a. Ensure dataset exists (GET → POST if missing)
|
|
513
|
+
* b. Ensure binding exists (GET → POST if missing), bound to `cos://{bucket}/{cosPrefix}`
|
|
514
|
+
*
|
|
515
|
+
* Returns a {@link BootstrapOutcome} with the COS instance and resolved config,
|
|
516
|
+
* ready for use by `CloudClient`.
|
|
517
|
+
*/
|
|
518
|
+
export async function bootstrap(input, logger) {
|
|
519
|
+
// ---- Step 0: Resolve config & create COS instance ----
|
|
520
|
+
const config = resolveConfig(input);
|
|
521
|
+
const cos = getCOSInstance(config.secretId, config.secretKey);
|
|
522
|
+
let bucketCreated = false;
|
|
523
|
+
const datasetOutcomes = [];
|
|
524
|
+
try {
|
|
525
|
+
// ---- Step 1: Ensure bucket exists ----
|
|
526
|
+
logger.info(`cos-bootstrap: checking bucket "${config.bucket}" in ${config.region}...`);
|
|
527
|
+
const bucketExists = await doesBucketExist(cos, config.bucket, config.region);
|
|
528
|
+
if (!bucketExists) {
|
|
529
|
+
logger.info(`cos-bootstrap: bucket not found, creating "${config.bucket}"...`);
|
|
530
|
+
await createBucket(cos, config.bucket, config.region);
|
|
531
|
+
bucketCreated = true;
|
|
532
|
+
logger.info(`cos-bootstrap: bucket "${config.bucket}" created successfully`);
|
|
533
|
+
// CI (data-processing) API may not be immediately available on a freshly
|
|
534
|
+
// created bucket. Wait a short period to reduce 400/500 errors downstream.
|
|
535
|
+
logger.info('cos-bootstrap: waiting for CI API propagation after bucket creation...');
|
|
536
|
+
await new Promise((r) => setTimeout(r, 3000));
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
logger.info(`cos-bootstrap: bucket "${config.bucket}" already exists`);
|
|
540
|
+
}
|
|
541
|
+
// ---- Step 2: For each dataset — ensure dataset + binding ----
|
|
542
|
+
for (const ds of config.datasets) {
|
|
543
|
+
const outcome = {
|
|
544
|
+
name: ds.name,
|
|
545
|
+
cosPrefix: ds.cosPrefix,
|
|
546
|
+
datasetCreated: false,
|
|
547
|
+
bindingCreated: false,
|
|
548
|
+
};
|
|
549
|
+
// 2a. Ensure dataset exists
|
|
550
|
+
logger.info(`cos-bootstrap: [${ds.name}] checking dataset...`);
|
|
551
|
+
const datasetInfo = await getDatasetInfo(cos, config.bucket, config.region, ds.name);
|
|
552
|
+
if (!datasetInfo) {
|
|
553
|
+
logger.info(`cos-bootstrap: [${ds.name}] not found, creating (template: ${ds.templateId})...`);
|
|
554
|
+
await createDataset(cos, config.bucket, config.region, ds.name, ds.templateId, ds.description);
|
|
555
|
+
outcome.datasetCreated = true;
|
|
556
|
+
logger.info(`cos-bootstrap: [${ds.name}] dataset created successfully`);
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
logger.info(`cos-bootstrap: [${ds.name}] dataset already exists`);
|
|
560
|
+
}
|
|
561
|
+
// 2b. Ensure binding exists (bound to cosPrefix)
|
|
562
|
+
logger.info(`cos-bootstrap: [${ds.name}] checking binding → cos://${config.bucket}/${ds.cosPrefix}...`);
|
|
563
|
+
const binding = await getDatasetBinding(cos, config.bucket, config.region, ds.name, ds.cosPrefix);
|
|
564
|
+
if (!binding) {
|
|
565
|
+
logger.info(`cos-bootstrap: [${ds.name}] binding not found, creating → ${ds.cosPrefix}...`);
|
|
566
|
+
await createDatasetBinding(cos, config.bucket, config.region, ds.name, ds.cosPrefix);
|
|
567
|
+
outcome.bindingCreated = true;
|
|
568
|
+
logger.info(`cos-bootstrap: [${ds.name}] binding created successfully`);
|
|
569
|
+
}
|
|
570
|
+
else {
|
|
571
|
+
logger.info(`cos-bootstrap: [${ds.name}] binding already exists (state: ${binding.State ?? 'unknown'})`);
|
|
572
|
+
}
|
|
573
|
+
datasetOutcomes.push(outcome);
|
|
574
|
+
}
|
|
575
|
+
const totalDs = config.datasets.length;
|
|
576
|
+
logger.info(`cos-bootstrap: all preconditions met ✓ (${totalDs} dataset(s))`);
|
|
577
|
+
return {
|
|
578
|
+
success: true,
|
|
579
|
+
cos,
|
|
580
|
+
config,
|
|
581
|
+
bucketCreated,
|
|
582
|
+
datasetOutcomes,
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
catch (err) {
|
|
586
|
+
const message = serializeError(err);
|
|
587
|
+
logger.warn(`cos-bootstrap: initialization failed: ${message}`);
|
|
588
|
+
return {
|
|
589
|
+
success: false,
|
|
590
|
+
cos,
|
|
591
|
+
config,
|
|
592
|
+
bucketCreated,
|
|
593
|
+
datasetOutcomes,
|
|
594
|
+
error: message,
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
//# sourceMappingURL=cos-bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cos-bootstrap.js","sourceRoot":"","sources":["../cos-bootstrap.ts"],"names":[],"mappings":"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"}
|