mnemospark 0.6.0 → 0.7.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/cli.js +148 -347
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -2
- package/dist/index.js +148 -347
- package/dist/index.js.map +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
- package/skills/mnemospark/references/state-and-logs.md +17 -13
- package/skills/mnemospark/references/troubleshooting.md +4 -2
- package/skills/mnemospark/scripts/debug-operation.sh +1 -7
package/dist/cli.js
CHANGED
|
@@ -1602,8 +1602,8 @@ import { homedir as homedir2 } from "os";
|
|
|
1602
1602
|
import { basename, dirname as dirname2, join as join3 } from "path";
|
|
1603
1603
|
import { pipeline } from "stream/promises";
|
|
1604
1604
|
var BASE_DIR = join3(homedir2(), ".openclaw", "mnemospark");
|
|
1605
|
-
var MAX_BYTES =
|
|
1606
|
-
var KEEP_ROTATED =
|
|
1605
|
+
var MAX_BYTES = 15 * 1024 * 1024;
|
|
1606
|
+
var KEEP_ROTATED = 12;
|
|
1607
1607
|
function resolvePath(fileName, homeDir) {
|
|
1608
1608
|
const baseDir = homeDir ? join3(homeDir, ".openclaw", "mnemospark") : BASE_DIR;
|
|
1609
1609
|
return join3(baseDir, fileName);
|
|
@@ -1694,10 +1694,11 @@ function logProxyEvent(level, event, fields = {}) {
|
|
|
1694
1694
|
console.info(message);
|
|
1695
1695
|
}
|
|
1696
1696
|
function emitProxyEvent(eventType, status, correlation, details = {}) {
|
|
1697
|
-
void appendJsonlEvent("
|
|
1697
|
+
void appendJsonlEvent("events.jsonl", {
|
|
1698
1698
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1699
1699
|
event_type: eventType,
|
|
1700
1700
|
status,
|
|
1701
|
+
source: "proxy",
|
|
1701
1702
|
trace_id: correlation.trace_id,
|
|
1702
1703
|
operation_id: correlation.operation_id,
|
|
1703
1704
|
quote_id: correlation.quote_id ?? null,
|
|
@@ -3640,7 +3641,6 @@ async function createCloudDatastore(homeDir) {
|
|
|
3640
3641
|
var SUPPORTED_BACKUP_PLATFORMS = /* @__PURE__ */ new Set(["darwin", "linux"]);
|
|
3641
3642
|
var BACKUP_DIR_SUBPATH = join8(".openclaw", "mnemospark", "backup");
|
|
3642
3643
|
var DEFAULT_BACKUP_DIR = join8(homedir6(), BACKUP_DIR_SUBPATH);
|
|
3643
|
-
var OBJECT_LOG_SUBPATH = join8(".openclaw", "mnemospark", "object.log");
|
|
3644
3644
|
var CRON_TABLE_SUBPATH = join8(".openclaw", "mnemospark", "crontab.txt");
|
|
3645
3645
|
var BLOCKRUN_WALLET_KEY_SUBPATH = join8(".openclaw", "blockrun", "wallet.key");
|
|
3646
3646
|
var MNEMOSPARK_WALLET_KEY_SUBPATH = join8(".openclaw", "mnemospark", "wallet", "wallet.key");
|
|
@@ -3648,8 +3648,10 @@ var INLINE_UPLOAD_MAX_BYTES = 45e5;
|
|
|
3648
3648
|
var PAYMENT_REMINDER_INTERVAL_DAYS = 30;
|
|
3649
3649
|
var PAYMENT_DELETE_DEADLINE_DAYS = 32;
|
|
3650
3650
|
var PAYMENT_CRON_SCHEDULE = "0 0 1 * *";
|
|
3651
|
-
var CRON_LOG_ROW_PREFIX = "cron";
|
|
3652
3651
|
var TAR_OVERHEAD_BYTES = 10 * 1024 * 1024;
|
|
3652
|
+
var QUOTE_VALIDITY_USER_NOTE = "Quotes are valid for one hour. Please run price-storage again if you need a new quote.";
|
|
3653
|
+
var MNEMOSPARK_SUPPORT_EMAIL = "pluggedin@mnemospark.ai";
|
|
3654
|
+
var CLOUD_HELP_FOOTER_STATE = "Local state: mnemospark records quotes, objects, payments, cron jobs, friendly names, and operation metadata in ~/.openclaw/mnemospark/state.db (SQLite). For troubleshooting and correlation, commands and the HTTP proxy append structured JSON lines to ~/.openclaw/mnemospark/events.jsonl. Monthly storage billing jobs are listed in ~/.openclaw/mnemospark/crontab.txt for your system scheduler.";
|
|
3653
3655
|
var REQUIRED_PRICE_STORAGE = "--wallet-address, --object-id, --object-id-hash, --gb, --provider, --region";
|
|
3654
3656
|
var REQUIRED_UPLOAD = "--quote-id, --wallet-address, --object-id, --object-id-hash";
|
|
3655
3657
|
var REQUIRED_PAYMENT_SETTLE = "--quote-id and --wallet-address";
|
|
@@ -3678,12 +3680,14 @@ function expandTilde(path) {
|
|
|
3678
3680
|
return path;
|
|
3679
3681
|
}
|
|
3680
3682
|
var CLOUD_HELP_TEXT = [
|
|
3681
|
-
"\u2601\uFE0F **mnemospark
|
|
3683
|
+
"\u2601\uFE0F **mnemospark - Wallet and go.** \u{1F499}",
|
|
3684
|
+
"",
|
|
3685
|
+
"**Cloud Commands**",
|
|
3682
3686
|
"",
|
|
3683
3687
|
"\u2022 `/mnemospark_cloud` or `/mnemospark_cloud help` \u2014 show this message",
|
|
3684
3688
|
"",
|
|
3685
3689
|
"\u2022 `/mnemospark_cloud backup <file|directory> [--name <friendly-name>] [--async] [--orchestrator <inline|subagent>] [--timeout-seconds <n>]`",
|
|
3686
|
-
" Purpose: create a local tar+gzip backup
|
|
3690
|
+
" Purpose: create a local tar+gzip archive under ~/.openclaw/mnemospark/backup and record metadata in SQLite for later price-storage and upload.",
|
|
3687
3691
|
" Required: <file|directory>",
|
|
3688
3692
|
"",
|
|
3689
3693
|
"\u2022 `/mnemospark_cloud price-storage --wallet-address <addr> --object-id <id> --object-id-hash <hash> --gb <gb> --provider <provider> --region <region>`",
|
|
@@ -3732,7 +3736,9 @@ var CLOUD_HELP_TEXT = [
|
|
|
3732
3736
|
"\u2022 `/mnemospark_cloud op-status --operation-id <id>`",
|
|
3733
3737
|
"\u2022 `/mnemospark_cloud op-status --operation-id <id> --cancel`",
|
|
3734
3738
|
"",
|
|
3735
|
-
|
|
3739
|
+
CLOUD_HELP_FOOTER_STATE,
|
|
3740
|
+
"",
|
|
3741
|
+
"Commands price-storage, upload, ls, download, delete, and payment-settle require --wallet-address."
|
|
3736
3742
|
].join("\n");
|
|
3737
3743
|
var UnsupportedBackupPlatformError = class extends Error {
|
|
3738
3744
|
constructor(platform) {
|
|
@@ -4105,19 +4111,9 @@ function parseCloudArgs(args) {
|
|
|
4105
4111
|
}
|
|
4106
4112
|
return { mode: "unknown" };
|
|
4107
4113
|
}
|
|
4108
|
-
function resolveObjectLogPath(homeDir) {
|
|
4109
|
-
return join8(homeDir ?? homedir6(), OBJECT_LOG_SUBPATH);
|
|
4110
|
-
}
|
|
4111
4114
|
function resolveCronTablePath(homeDir) {
|
|
4112
4115
|
return join8(homeDir ?? homedir6(), CRON_TABLE_SUBPATH);
|
|
4113
4116
|
}
|
|
4114
|
-
async function appendObjectLogLine(line, homeDir) {
|
|
4115
|
-
const objectLogPath = resolveObjectLogPath(homeDir);
|
|
4116
|
-
await mkdir5(dirname5(objectLogPath), { recursive: true });
|
|
4117
|
-
await appendFile2(objectLogPath, `${line}
|
|
4118
|
-
`, "utf-8");
|
|
4119
|
-
return objectLogPath;
|
|
4120
|
-
}
|
|
4121
4117
|
async function calculateInputSizeBytes(targetPath) {
|
|
4122
4118
|
const targetStats = await lstat(targetPath);
|
|
4123
4119
|
if (targetStats.isFile() || targetStats.isSymbolicLink()) {
|
|
@@ -4214,38 +4210,17 @@ async function buildBackupObject(targetPathArg, options = {}) {
|
|
|
4214
4210
|
const archiveStats = await stat2(archivePath);
|
|
4215
4211
|
const objectIdHash = await sha256File(archivePath);
|
|
4216
4212
|
const objectSizeGb = toGbString(archiveStats.size);
|
|
4217
|
-
const objectLogPath = await appendObjectLogLine(
|
|
4218
|
-
`${objectId},${objectIdHash},${objectSizeGb}`,
|
|
4219
|
-
options.homeDir
|
|
4220
|
-
);
|
|
4221
4213
|
return {
|
|
4222
4214
|
objectId,
|
|
4223
4215
|
objectIdHash,
|
|
4224
4216
|
objectSizeGb,
|
|
4225
|
-
archivePath
|
|
4226
|
-
objectLogPath
|
|
4217
|
+
archivePath
|
|
4227
4218
|
};
|
|
4228
4219
|
} catch (error) {
|
|
4229
4220
|
await rm(archivePath, { force: true }).catch(() => void 0);
|
|
4230
4221
|
throw error;
|
|
4231
4222
|
}
|
|
4232
4223
|
}
|
|
4233
|
-
async function appendPriceStorageQuoteLog(quote, homeDir) {
|
|
4234
|
-
return appendObjectLogLine(
|
|
4235
|
-
[
|
|
4236
|
-
quote.timestamp,
|
|
4237
|
-
quote.quote_id,
|
|
4238
|
-
quote.storage_price.toString(),
|
|
4239
|
-
quote.addr,
|
|
4240
|
-
quote.object_id,
|
|
4241
|
-
quote.object_id_hash,
|
|
4242
|
-
quote.object_size_gb.toString(),
|
|
4243
|
-
quote.provider,
|
|
4244
|
-
quote.location
|
|
4245
|
-
].join(","),
|
|
4246
|
-
homeDir
|
|
4247
|
-
);
|
|
4248
|
-
}
|
|
4249
4224
|
function formatTimestamp(date) {
|
|
4250
4225
|
const pad = (value) => value.toString().padStart(2, "0");
|
|
4251
4226
|
return [
|
|
@@ -4262,55 +4237,6 @@ function formatTimestamp(date) {
|
|
|
4262
4237
|
pad(date.getSeconds())
|
|
4263
4238
|
].join("");
|
|
4264
4239
|
}
|
|
4265
|
-
function parseLoggedPriceStorageQuote(line) {
|
|
4266
|
-
const parts = line.split(",");
|
|
4267
|
-
if (parts.length < 9) {
|
|
4268
|
-
return null;
|
|
4269
|
-
}
|
|
4270
|
-
const quoteId = parts[1]?.trim() ?? "";
|
|
4271
|
-
const storagePriceRaw = parts[2]?.trim() ?? "";
|
|
4272
|
-
const walletAddress = parts[3]?.trim() ?? "";
|
|
4273
|
-
const objectId = parts[4]?.trim() ?? "";
|
|
4274
|
-
const objectIdHash = parts[5]?.trim() ?? "";
|
|
4275
|
-
const provider = parts[7]?.trim() ?? "";
|
|
4276
|
-
const location = parts[8]?.trim() ?? "";
|
|
4277
|
-
const storagePrice = Number.parseFloat(storagePriceRaw);
|
|
4278
|
-
if (!quoteId || !walletAddress || !objectId || !objectIdHash || !provider || !location) {
|
|
4279
|
-
return null;
|
|
4280
|
-
}
|
|
4281
|
-
if (!Number.isFinite(storagePrice) || storagePrice <= 0) {
|
|
4282
|
-
return null;
|
|
4283
|
-
}
|
|
4284
|
-
return {
|
|
4285
|
-
quoteId,
|
|
4286
|
-
storagePrice,
|
|
4287
|
-
walletAddress,
|
|
4288
|
-
objectId,
|
|
4289
|
-
objectIdHash,
|
|
4290
|
-
provider,
|
|
4291
|
-
location
|
|
4292
|
-
};
|
|
4293
|
-
}
|
|
4294
|
-
function parseLoggedStoragePaymentCron(line) {
|
|
4295
|
-
const parts = line.split(",");
|
|
4296
|
-
if (parts.length < 5) {
|
|
4297
|
-
return null;
|
|
4298
|
-
}
|
|
4299
|
-
if ((parts[0]?.trim() ?? "").toLowerCase() !== CRON_LOG_ROW_PREFIX) {
|
|
4300
|
-
return null;
|
|
4301
|
-
}
|
|
4302
|
-
const cronId = parts[2]?.trim() ?? "";
|
|
4303
|
-
const objectId = parts[3]?.trim() ?? "";
|
|
4304
|
-
const objectKey = parts[4]?.trim() ?? "";
|
|
4305
|
-
if (!cronId || !objectId || !objectKey) {
|
|
4306
|
-
return null;
|
|
4307
|
-
}
|
|
4308
|
-
return {
|
|
4309
|
-
cronId,
|
|
4310
|
-
objectId,
|
|
4311
|
-
objectKey
|
|
4312
|
-
};
|
|
4313
|
-
}
|
|
4314
4240
|
function parseStoragePaymentCronJobLine(line) {
|
|
4315
4241
|
const trimmed = line.trim();
|
|
4316
4242
|
if (!trimmed) {
|
|
@@ -4356,31 +4282,11 @@ function parseStoragePaymentCronJobLine(line) {
|
|
|
4356
4282
|
location
|
|
4357
4283
|
};
|
|
4358
4284
|
}
|
|
4359
|
-
async function
|
|
4360
|
-
const
|
|
4361
|
-
let content;
|
|
4362
|
-
try {
|
|
4363
|
-
content = await readFile3(objectLogPath, "utf-8");
|
|
4364
|
-
} catch (error) {
|
|
4365
|
-
if (error.code === "ENOENT") {
|
|
4366
|
-
return null;
|
|
4367
|
-
}
|
|
4368
|
-
throw error;
|
|
4369
|
-
}
|
|
4370
|
-
const lines = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
4371
|
-
for (let idx = lines.length - 1; idx >= 0; idx -= 1) {
|
|
4372
|
-
const parsed = parseLoggedPriceStorageQuote(lines[idx]);
|
|
4373
|
-
if (parsed && parsed.quoteId === quoteId) {
|
|
4374
|
-
return parsed;
|
|
4375
|
-
}
|
|
4376
|
-
}
|
|
4377
|
-
return null;
|
|
4378
|
-
}
|
|
4379
|
-
async function findLoggedStoragePaymentCronByObjectKey(objectKey, homeDir) {
|
|
4380
|
-
const objectLogPath = resolveObjectLogPath(homeDir);
|
|
4285
|
+
async function findCronJobInCrontabByObjectKey(objectKey, homeDir) {
|
|
4286
|
+
const cronTablePath = resolveCronTablePath(homeDir);
|
|
4381
4287
|
let content;
|
|
4382
4288
|
try {
|
|
4383
|
-
content = await readFile3(
|
|
4289
|
+
content = await readFile3(cronTablePath, "utf-8");
|
|
4384
4290
|
} catch (error) {
|
|
4385
4291
|
if (error.code === "ENOENT") {
|
|
4386
4292
|
return null;
|
|
@@ -4389,9 +4295,13 @@ async function findLoggedStoragePaymentCronByObjectKey(objectKey, homeDir) {
|
|
|
4389
4295
|
}
|
|
4390
4296
|
const lines = content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
4391
4297
|
for (let idx = lines.length - 1; idx >= 0; idx -= 1) {
|
|
4392
|
-
const parsed =
|
|
4298
|
+
const parsed = parseStoragePaymentCronJobLine(lines[idx]);
|
|
4393
4299
|
if (parsed && parsed.objectKey === objectKey) {
|
|
4394
|
-
return
|
|
4300
|
+
return {
|
|
4301
|
+
cronId: parsed.cronId,
|
|
4302
|
+
objectId: parsed.objectId,
|
|
4303
|
+
objectKey: parsed.objectKey
|
|
4304
|
+
};
|
|
4395
4305
|
}
|
|
4396
4306
|
}
|
|
4397
4307
|
return null;
|
|
@@ -4415,20 +4325,6 @@ function buildStoragePaymentCronCommand(job) {
|
|
|
4415
4325
|
quoteCronArgument(job.storagePrice)
|
|
4416
4326
|
].join(" ");
|
|
4417
4327
|
}
|
|
4418
|
-
async function appendStoragePaymentCronLog(cronJob, homeDir) {
|
|
4419
|
-
return appendObjectLogLine(
|
|
4420
|
-
[
|
|
4421
|
-
CRON_LOG_ROW_PREFIX,
|
|
4422
|
-
cronJob.createdAt,
|
|
4423
|
-
cronJob.cronId,
|
|
4424
|
-
cronJob.objectId,
|
|
4425
|
-
cronJob.objectKey,
|
|
4426
|
-
cronJob.quoteId,
|
|
4427
|
-
cronJob.storagePrice.toString()
|
|
4428
|
-
].join(","),
|
|
4429
|
-
homeDir
|
|
4430
|
-
);
|
|
4431
|
-
}
|
|
4432
4328
|
async function appendStoragePaymentCronJob(cronJob, homeDir) {
|
|
4433
4329
|
const cronTablePath = resolveCronTablePath(homeDir);
|
|
4434
4330
|
await mkdir5(dirname5(cronTablePath), { recursive: true });
|
|
@@ -4495,7 +4391,6 @@ async function createStoragePaymentCronJob(upload, storagePrice, homeDir, nowDat
|
|
|
4495
4391
|
location: upload.location
|
|
4496
4392
|
};
|
|
4497
4393
|
await appendStoragePaymentCronJob(cronJob, homeDir);
|
|
4498
|
-
await appendStoragePaymentCronLog(cronJob, homeDir);
|
|
4499
4394
|
return cronJob;
|
|
4500
4395
|
}
|
|
4501
4396
|
async function readWalletKeyIfPresent(walletPath) {
|
|
@@ -4625,24 +4520,6 @@ async function uploadPresignedObjectIfNeeded(uploadResponse, uploadMode, encrypt
|
|
|
4625
4520
|
`Presigned upload failed with status ${firstAttempt.status}${details ? `: ${details}` : ""}`
|
|
4626
4521
|
);
|
|
4627
4522
|
}
|
|
4628
|
-
async function appendStorageUploadLog(upload, homeDir, nowDateFn = () => /* @__PURE__ */ new Date()) {
|
|
4629
|
-
return appendObjectLogLine(
|
|
4630
|
-
[
|
|
4631
|
-
formatTimestamp(nowDateFn()),
|
|
4632
|
-
upload.quote_id,
|
|
4633
|
-
upload.addr,
|
|
4634
|
-
upload.addr_hash ?? "",
|
|
4635
|
-
upload.trans_id ?? "",
|
|
4636
|
-
upload.storage_price?.toString() ?? "",
|
|
4637
|
-
upload.object_id,
|
|
4638
|
-
upload.object_key,
|
|
4639
|
-
upload.provider,
|
|
4640
|
-
upload.bucket_name,
|
|
4641
|
-
upload.location
|
|
4642
|
-
].join(","),
|
|
4643
|
-
homeDir
|
|
4644
|
-
);
|
|
4645
|
-
}
|
|
4646
4523
|
async function maybeCleanupLocalBackupArchive(archivePath) {
|
|
4647
4524
|
const flag = process.env.MNEMOSPARK_DELETE_BACKUP_AFTER_UPLOAD;
|
|
4648
4525
|
if (!flag) {
|
|
@@ -4658,10 +4535,18 @@ async function maybeCleanupLocalBackupArchive(archivePath) {
|
|
|
4658
4535
|
}
|
|
4659
4536
|
}
|
|
4660
4537
|
function formatStorageUploadUserMessage(upload, cronJobId) {
|
|
4538
|
+
const lsLine = `/mnemospark_cloud ls --wallet-address \`${upload.addr}\``;
|
|
4661
4539
|
return [
|
|
4662
4540
|
`Your file \`${upload.object_id}\` with key \`${upload.object_key}\` has been stored using \`${upload.provider}\` in \`${upload.bucket_name}\` \`${upload.location}\``,
|
|
4663
|
-
|
|
4664
|
-
|
|
4541
|
+
"",
|
|
4542
|
+
`A cron job \`${cronJobId}\` has been configured to send payment monthly (on the 1st) for storage services. If payment is not sent, your \`${upload.object_id}\` will be deleted after the ${PAYMENT_DELETE_DEADLINE_DAYS}-day deadline (${PAYMENT_REMINDER_INTERVAL_DAYS}-day billing interval + 2-day grace period).`,
|
|
4543
|
+
"",
|
|
4544
|
+
"To view your cloud storage run the command:",
|
|
4545
|
+
"",
|
|
4546
|
+
lsLine,
|
|
4547
|
+
"",
|
|
4548
|
+
"Thank you for using mnemospark!",
|
|
4549
|
+
`Reach out if you need anything: ${MNEMOSPARK_SUPPORT_EMAIL}`
|
|
4665
4550
|
].join("\n");
|
|
4666
4551
|
}
|
|
4667
4552
|
function formatStorageDeleteUserMessage(objectKey, cronId, cronDeleted) {
|
|
@@ -4708,9 +4593,39 @@ function extractLsErrorMessage(error) {
|
|
|
4708
4593
|
return null;
|
|
4709
4594
|
}
|
|
4710
4595
|
function formatPriceStorageUserMessage(quote) {
|
|
4596
|
+
const uploadLine = `/mnemospark_cloud upload --quote-id \`${quote.quote_id}\` --wallet-address \`${quote.addr}\` --object-id \`${quote.object_id}\` --object-id-hash \`${quote.object_id_hash}\``;
|
|
4597
|
+
return [
|
|
4598
|
+
`Your storage quote \`${quote.quote_id}\`: storage price \`${quote.storage_price}\` for \`${quote.object_id}\` with file size \`${quote.object_size_gb}\` in \`${quote.provider}\` \`${quote.location}\`.`,
|
|
4599
|
+
"",
|
|
4600
|
+
"If you accept this quote, run:",
|
|
4601
|
+
"",
|
|
4602
|
+
uploadLine,
|
|
4603
|
+
"",
|
|
4604
|
+
QUOTE_VALIDITY_USER_NOTE
|
|
4605
|
+
].join("\n");
|
|
4606
|
+
}
|
|
4607
|
+
function quoteLookupMatchesPriceStorageResponse(lookup, quote) {
|
|
4608
|
+
return lookup.quoteId === quote.quote_id && lookup.walletAddress.trim().toLowerCase() === quote.addr.trim().toLowerCase() && lookup.objectId === quote.object_id && lookup.objectIdHash.toLowerCase() === quote.object_id_hash.toLowerCase() && lookup.storagePrice === quote.storage_price && lookup.provider === quote.provider && lookup.location === quote.location;
|
|
4609
|
+
}
|
|
4610
|
+
function formatBackupSuccessUserMessage(result) {
|
|
4611
|
+
const hash = result.objectIdHash.replace(/\s/g, "");
|
|
4612
|
+
const priceStorageLine = `/mnemospark_cloud price-storage --wallet-address <wallet-address> --object-id \`${result.objectId}\` --object-id-hash \`${hash}\` --gb \`${result.objectSizeGb}\` --provider <provider> --region <region>`;
|
|
4711
4613
|
return [
|
|
4712
|
-
`
|
|
4713
|
-
|
|
4614
|
+
`Backup archive: \`${result.archivePath}\``,
|
|
4615
|
+
"",
|
|
4616
|
+
`object-id: ${result.objectId}`,
|
|
4617
|
+
`object-id-hash: ${hash}`,
|
|
4618
|
+
`object-size: ${result.objectSizeGb}`,
|
|
4619
|
+
"",
|
|
4620
|
+
"Next, request a storage quote. Replace `<wallet-address>`, `<provider>`, and `<region>` (one line):",
|
|
4621
|
+
"",
|
|
4622
|
+
priceStorageLine,
|
|
4623
|
+
"",
|
|
4624
|
+
"Region examples (merge into the command above):",
|
|
4625
|
+
"North America: `--provider aws --region us-east-1`",
|
|
4626
|
+
"Europe: `--provider aws --region eu-north-1`",
|
|
4627
|
+
"South America: `--provider aws --region sa-east-1`",
|
|
4628
|
+
"Asia Pacific: `--provider aws --region ap-northeast-1`"
|
|
4714
4629
|
].join("\n");
|
|
4715
4630
|
}
|
|
4716
4631
|
function createInProcessSubagentOrchestrator() {
|
|
@@ -4837,7 +4752,7 @@ function createCloudCommand(options = {}) {
|
|
|
4837
4752
|
requestStorageDownloadFn: options.requestStorageDownloadFn ?? requestStorageDownloadViaProxy,
|
|
4838
4753
|
requestStorageDeleteFn: options.requestStorageDeleteFn ?? requestStorageDeleteViaProxy,
|
|
4839
4754
|
requestPaymentSettleViaProxyFn: options.requestPaymentSettleViaProxyFn ?? requestPaymentSettleViaProxy,
|
|
4840
|
-
|
|
4755
|
+
mnemosparkHomeDir: options.mnemosparkHomeDir ?? options.backupOptions?.homeDir,
|
|
4841
4756
|
backupOptions: options.backupOptions,
|
|
4842
4757
|
proxyQuoteOptions: options.proxyQuoteOptions,
|
|
4843
4758
|
proxyUploadOptions: options.proxyUploadOptions,
|
|
@@ -4853,42 +4768,7 @@ function createCloudCommand(options = {}) {
|
|
|
4853
4768
|
}
|
|
4854
4769
|
};
|
|
4855
4770
|
}
|
|
4856
|
-
async function
|
|
4857
|
-
const manifestPath = join8(homeDir ?? homedir6(), ".openclaw", "mnemospark", "manifest.jsonl");
|
|
4858
|
-
let manifestRaw;
|
|
4859
|
-
try {
|
|
4860
|
-
manifestRaw = await readFile3(manifestPath, "utf-8");
|
|
4861
|
-
} catch {
|
|
4862
|
-
return { objectKey: null, matchCount: 0 };
|
|
4863
|
-
}
|
|
4864
|
-
const wallet = params.walletAddress.trim().toLowerCase();
|
|
4865
|
-
const name = params.friendlyName.trim();
|
|
4866
|
-
const atMs = params.at ? Date.parse(params.at) : Number.NaN;
|
|
4867
|
-
const hasAt = Number.isFinite(atMs);
|
|
4868
|
-
const rows = manifestRaw.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).map((line) => {
|
|
4869
|
-
try {
|
|
4870
|
-
return JSON.parse(line);
|
|
4871
|
-
} catch {
|
|
4872
|
-
return null;
|
|
4873
|
-
}
|
|
4874
|
-
}).filter((row) => Boolean(row)).filter((row) => {
|
|
4875
|
-
if (!row.object_key || !row.friendly_name || !row.wallet_address || !row.created_at)
|
|
4876
|
-
return false;
|
|
4877
|
-
if (row.friendly_name !== name) return false;
|
|
4878
|
-
if (row.wallet_address.trim().toLowerCase() !== wallet) return false;
|
|
4879
|
-
if (params.latest || !hasAt) return true;
|
|
4880
|
-
const createdAtMs = Date.parse(row.created_at);
|
|
4881
|
-
return Number.isFinite(createdAtMs) && createdAtMs <= atMs;
|
|
4882
|
-
}).sort((a, b) => Date.parse(b.created_at ?? "") - Date.parse(a.created_at ?? ""));
|
|
4883
|
-
if (rows.length === 0) {
|
|
4884
|
-
return { objectKey: null, matchCount: 0 };
|
|
4885
|
-
}
|
|
4886
|
-
if (!params.latest && !hasAt && rows.length > 1) {
|
|
4887
|
-
return { objectKey: null, matchCount: rows.length };
|
|
4888
|
-
}
|
|
4889
|
-
return { objectKey: rows[0].object_key ?? null, matchCount: rows.length };
|
|
4890
|
-
}
|
|
4891
|
-
async function resolveNameSelectorIfNeeded(datastore, request, selector, homeDir) {
|
|
4771
|
+
async function resolveNameSelectorIfNeeded(datastore, request, selector) {
|
|
4892
4772
|
if (!selector) {
|
|
4893
4773
|
const walletAddress = request.wallet_address?.trim();
|
|
4894
4774
|
if (!walletAddress) {
|
|
@@ -4912,11 +4792,12 @@ async function resolveNameSelectorIfNeeded(datastore, request, selector, homeDir
|
|
|
4912
4792
|
}
|
|
4913
4793
|
return { request: parsedRequest2 };
|
|
4914
4794
|
}
|
|
4915
|
-
let sqliteUnavailable = false;
|
|
4916
4795
|
try {
|
|
4917
4796
|
await datastore.ensureReady();
|
|
4918
4797
|
} catch {
|
|
4919
|
-
|
|
4798
|
+
return {
|
|
4799
|
+
error: "Cannot resolve --name: local SQLite (~/.openclaw/mnemospark/state.db) is unavailable. Use --object-key or restore SQLite access."
|
|
4800
|
+
};
|
|
4920
4801
|
}
|
|
4921
4802
|
const matches = await datastore.countFriendlyNameMatches(request.wallet_address, selector.name);
|
|
4922
4803
|
if (matches > 1 && !selector.latest && !selector.at) {
|
|
@@ -4930,28 +4811,7 @@ async function resolveNameSelectorIfNeeded(datastore, request, selector, homeDir
|
|
|
4930
4811
|
latest: selector.latest,
|
|
4931
4812
|
at: selector.at
|
|
4932
4813
|
});
|
|
4933
|
-
|
|
4934
|
-
let degradedWarning;
|
|
4935
|
-
if (!resolvedObjectKey && sqliteUnavailable) {
|
|
4936
|
-
const manifestResolved = await resolveFriendlyNameFromManifest(
|
|
4937
|
-
{
|
|
4938
|
-
walletAddress: request.wallet_address,
|
|
4939
|
-
friendlyName: selector.name,
|
|
4940
|
-
latest: selector.latest,
|
|
4941
|
-
at: selector.at
|
|
4942
|
-
},
|
|
4943
|
-
homeDir
|
|
4944
|
-
);
|
|
4945
|
-
if (manifestResolved.matchCount > 1 && !selector.latest && !selector.at) {
|
|
4946
|
-
return {
|
|
4947
|
-
error: `Multiple objects match --name ${selector.name}. Add --latest or --at <timestamp>.`
|
|
4948
|
-
};
|
|
4949
|
-
}
|
|
4950
|
-
resolvedObjectKey = manifestResolved.objectKey;
|
|
4951
|
-
if (resolvedObjectKey) {
|
|
4952
|
-
degradedWarning = "SQLite friendly-name index unavailable; resolved --name via manifest.jsonl fallback.";
|
|
4953
|
-
}
|
|
4954
|
-
}
|
|
4814
|
+
const resolvedObjectKey = resolved?.objectKey ?? null;
|
|
4955
4815
|
if (!resolvedObjectKey) {
|
|
4956
4816
|
return { error: `No object found for --name ${selector.name}.` };
|
|
4957
4817
|
}
|
|
@@ -4962,10 +4822,7 @@ async function resolveNameSelectorIfNeeded(datastore, request, selector, homeDir
|
|
|
4962
4822
|
if (!parsedRequest) {
|
|
4963
4823
|
return { error: "Cannot resolve storage object request." };
|
|
4964
4824
|
}
|
|
4965
|
-
return {
|
|
4966
|
-
request: parsedRequest,
|
|
4967
|
-
degradedWarning
|
|
4968
|
-
};
|
|
4825
|
+
return { request: parsedRequest };
|
|
4969
4826
|
}
|
|
4970
4827
|
function toStorageObjectRequestOrError(request, missingKeyMessage) {
|
|
4971
4828
|
const key = request.object_key?.trim();
|
|
@@ -4988,7 +4845,8 @@ async function emitCloudEvent(eventType, details, homeDir) {
|
|
|
4988
4845
|
{
|
|
4989
4846
|
...details,
|
|
4990
4847
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4991
|
-
event_type: eventType
|
|
4848
|
+
event_type: eventType,
|
|
4849
|
+
source: "command"
|
|
4992
4850
|
},
|
|
4993
4851
|
homeDir
|
|
4994
4852
|
);
|
|
@@ -5005,6 +4863,7 @@ function toOperationEventPayload(eventType, context) {
|
|
|
5005
4863
|
trace_id: context.traceId,
|
|
5006
4864
|
event_type: eventType,
|
|
5007
4865
|
status: context.status,
|
|
4866
|
+
source: "command",
|
|
5008
4867
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5009
4868
|
wallet_address: context.walletAddress ?? void 0,
|
|
5010
4869
|
object_id: context.objectId ?? void 0,
|
|
@@ -5020,10 +4879,7 @@ function toOperationEventPayload(eventType, context) {
|
|
|
5020
4879
|
}
|
|
5021
4880
|
async function emitOperationEvent(eventType, context, homeDir) {
|
|
5022
4881
|
const payload = toOperationEventPayload(eventType, context);
|
|
5023
|
-
await
|
|
5024
|
-
appendJsonlEvent("events.jsonl", payload, homeDir),
|
|
5025
|
-
appendJsonlEvent("proxy-events.jsonl", payload, homeDir)
|
|
5026
|
-
]);
|
|
4882
|
+
await appendJsonlEvent("events.jsonl", payload, homeDir);
|
|
5027
4883
|
}
|
|
5028
4884
|
async function emitOperationEventBestEffort(eventType, context, homeDir) {
|
|
5029
4885
|
try {
|
|
@@ -5049,7 +4905,7 @@ function parseTransIdFromPaymentSettleBody(bodyText) {
|
|
|
5049
4905
|
return null;
|
|
5050
4906
|
}
|
|
5051
4907
|
}
|
|
5052
|
-
async function resolveAmountForPaymentSettle(quoteId, storagePriceFromFlag, datastore
|
|
4908
|
+
async function resolveAmountForPaymentSettle(quoteId, storagePriceFromFlag, datastore) {
|
|
5053
4909
|
if (storagePriceFromFlag !== void 0 && Number.isFinite(storagePriceFromFlag)) {
|
|
5054
4910
|
return storagePriceFromFlag;
|
|
5055
4911
|
}
|
|
@@ -5057,10 +4913,6 @@ async function resolveAmountForPaymentSettle(quoteId, storagePriceFromFlag, data
|
|
|
5057
4913
|
if (quoteLookup && Number.isFinite(quoteLookup.storagePrice)) {
|
|
5058
4914
|
return quoteLookup.storagePrice;
|
|
5059
4915
|
}
|
|
5060
|
-
const logged = await findLoggedPriceStorageQuote(quoteId, homeDir);
|
|
5061
|
-
if (logged && Number.isFinite(logged.storagePrice)) {
|
|
5062
|
-
return logged.storagePrice;
|
|
5063
|
-
}
|
|
5064
4916
|
const payment = await datastore.findPaymentByQuoteId(quoteId);
|
|
5065
4917
|
if (payment && Number.isFinite(payment.amount)) {
|
|
5066
4918
|
return payment.amount;
|
|
@@ -5096,18 +4948,19 @@ async function emitPaymentSettleClientObservationBestEffort(params) {
|
|
|
5096
4948
|
homeDir
|
|
5097
4949
|
);
|
|
5098
4950
|
await appendJsonlEvent(
|
|
5099
|
-
"
|
|
4951
|
+
"events.jsonl",
|
|
5100
4952
|
{
|
|
5101
4953
|
ts,
|
|
5102
4954
|
event_type: "payment.settle",
|
|
5103
4955
|
status: "start",
|
|
4956
|
+
source: "command",
|
|
5104
4957
|
trace_id: correlation.traceId,
|
|
5105
4958
|
operation_id: correlation.operationId,
|
|
5106
4959
|
quote_id: quoteId,
|
|
5107
4960
|
wallet_address: walletAddress,
|
|
5108
4961
|
object_id: objectId ?? null,
|
|
5109
4962
|
object_key: objectKey ?? null,
|
|
5110
|
-
details: {
|
|
4963
|
+
details: { client_observation: true }
|
|
5111
4964
|
},
|
|
5112
4965
|
homeDir
|
|
5113
4966
|
);
|
|
@@ -5129,18 +4982,20 @@ async function emitPaymentSettleClientObservationBestEffort(params) {
|
|
|
5129
4982
|
homeDir
|
|
5130
4983
|
);
|
|
5131
4984
|
await appendJsonlEvent(
|
|
5132
|
-
"
|
|
4985
|
+
"events.jsonl",
|
|
5133
4986
|
{
|
|
5134
4987
|
ts,
|
|
5135
4988
|
event_type: "payment.settle",
|
|
5136
4989
|
status: "result",
|
|
4990
|
+
source: "command",
|
|
5137
4991
|
trace_id: correlation.traceId,
|
|
5138
4992
|
operation_id: correlation.operationId,
|
|
5139
4993
|
quote_id: quoteId,
|
|
5140
4994
|
wallet_address: walletAddress,
|
|
5141
4995
|
object_id: objectId ?? null,
|
|
5142
4996
|
object_key: objectKey ?? null,
|
|
5143
|
-
|
|
4997
|
+
http_status: httpStatus ?? null,
|
|
4998
|
+
details: { client_observation: true }
|
|
5144
4999
|
},
|
|
5145
5000
|
homeDir
|
|
5146
5001
|
);
|
|
@@ -5149,7 +5004,7 @@ async function emitPaymentSettleClientObservationBestEffort(params) {
|
|
|
5149
5004
|
}
|
|
5150
5005
|
async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
5151
5006
|
const parsed = parseCloudArgs(ctx.args);
|
|
5152
|
-
const
|
|
5007
|
+
const mnemosparkHomeDir = options.mnemosparkHomeDir;
|
|
5153
5008
|
const backupBuilder = options.buildBackupObjectFn;
|
|
5154
5009
|
const requestPriceStorageQuote = options.requestPriceStorageQuoteFn;
|
|
5155
5010
|
const requestStorageUpload = options.requestStorageUploadFn;
|
|
@@ -5236,7 +5091,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5236
5091
|
isError: true
|
|
5237
5092
|
};
|
|
5238
5093
|
}
|
|
5239
|
-
const datastore = await createCloudDatastore(
|
|
5094
|
+
const datastore = await createCloudDatastore(mnemosparkHomeDir);
|
|
5240
5095
|
const terminalOperationStatuses = /* @__PURE__ */ new Set(["succeeded", "failed", "cancelled", "timed_out"]);
|
|
5241
5096
|
const isTerminalOperationStatus = (status) => terminalOperationStatuses.has(status);
|
|
5242
5097
|
const formatOperationStatus = (operation) => ({
|
|
@@ -5298,7 +5153,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5298
5153
|
subagentSessionId: operation.subagent_session_id,
|
|
5299
5154
|
timeoutSeconds: operation.timeout_seconds
|
|
5300
5155
|
},
|
|
5301
|
-
|
|
5156
|
+
mnemosparkHomeDir
|
|
5302
5157
|
);
|
|
5303
5158
|
const cancelResult = await subagentOrchestrator.cancel(
|
|
5304
5159
|
operation.subagent_session_id,
|
|
@@ -5335,7 +5190,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5335
5190
|
errorCode: "ASYNC_CANCELLED",
|
|
5336
5191
|
errorMessage: "Operation cancelled by user request."
|
|
5337
5192
|
},
|
|
5338
|
-
|
|
5193
|
+
mnemosparkHomeDir
|
|
5339
5194
|
);
|
|
5340
5195
|
}
|
|
5341
5196
|
}
|
|
@@ -5354,7 +5209,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5354
5209
|
const req = parsed.paymentSettleRequest;
|
|
5355
5210
|
let walletKey;
|
|
5356
5211
|
try {
|
|
5357
|
-
walletKey = await resolveWalletKey(
|
|
5212
|
+
walletKey = await resolveWalletKey(mnemosparkHomeDir);
|
|
5358
5213
|
} catch (err) {
|
|
5359
5214
|
const message = err instanceof Error ? err.message : String(err);
|
|
5360
5215
|
return { text: message.trim() || "Cannot resolve wallet key.", isError: true };
|
|
@@ -5377,7 +5232,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5377
5232
|
walletAddress: req.wallet_address,
|
|
5378
5233
|
objectId,
|
|
5379
5234
|
objectKey,
|
|
5380
|
-
homeDir:
|
|
5235
|
+
homeDir: mnemosparkHomeDir
|
|
5381
5236
|
});
|
|
5382
5237
|
let settleResult;
|
|
5383
5238
|
try {
|
|
@@ -5390,8 +5245,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5390
5245
|
const amountErr = await resolveAmountForPaymentSettle(
|
|
5391
5246
|
req.quote_id,
|
|
5392
5247
|
req.storage_price,
|
|
5393
|
-
datastore
|
|
5394
|
-
objectLogHomeDir
|
|
5248
|
+
datastore
|
|
5395
5249
|
);
|
|
5396
5250
|
await datastore.upsertPayment({
|
|
5397
5251
|
quote_id: req.quote_id,
|
|
@@ -5415,16 +5269,11 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5415
5269
|
objectId,
|
|
5416
5270
|
objectKey,
|
|
5417
5271
|
outcomeStatus: "failed",
|
|
5418
|
-
homeDir:
|
|
5272
|
+
homeDir: mnemosparkHomeDir
|
|
5419
5273
|
});
|
|
5420
5274
|
return { text: `Payment settle failed: ${msg}`, isError: true };
|
|
5421
5275
|
}
|
|
5422
|
-
const amount = await resolveAmountForPaymentSettle(
|
|
5423
|
-
req.quote_id,
|
|
5424
|
-
req.storage_price,
|
|
5425
|
-
datastore,
|
|
5426
|
-
objectLogHomeDir
|
|
5427
|
-
);
|
|
5276
|
+
const amount = await resolveAmountForPaymentSettle(req.quote_id, req.storage_price, datastore);
|
|
5428
5277
|
const transId = settleResult.status === 200 ? parseTransIdFromPaymentSettleBody(settleResult.bodyText ?? "") : null;
|
|
5429
5278
|
if (settleResult.status === 200) {
|
|
5430
5279
|
await datastore.upsertPayment({
|
|
@@ -5449,7 +5298,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5449
5298
|
objectKey,
|
|
5450
5299
|
httpStatus: settleResult.status,
|
|
5451
5300
|
outcomeStatus: "succeeded",
|
|
5452
|
-
homeDir:
|
|
5301
|
+
homeDir: mnemosparkHomeDir
|
|
5453
5302
|
});
|
|
5454
5303
|
return {
|
|
5455
5304
|
text: transId ? `Payment settled for quote ${req.quote_id} (trans_id: ${transId}).` : `Payment settled for quote ${req.quote_id}.`
|
|
@@ -5477,7 +5326,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5477
5326
|
objectKey,
|
|
5478
5327
|
httpStatus: settleResult.status,
|
|
5479
5328
|
outcomeStatus: "failed",
|
|
5480
|
-
homeDir:
|
|
5329
|
+
homeDir: mnemosparkHomeDir
|
|
5481
5330
|
});
|
|
5482
5331
|
const bodySnippet = settleResult.bodyText?.trim();
|
|
5483
5332
|
const detail = bodySnippet && bodySnippet.length > 500 ? `${bodySnippet.slice(0, 500)}\u2026` : bodySnippet;
|
|
@@ -5519,7 +5368,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5519
5368
|
await emitOperationEventBestEffort(
|
|
5520
5369
|
"operation.dispatched",
|
|
5521
5370
|
{ ...eventContextBase, status: "started" },
|
|
5522
|
-
|
|
5371
|
+
mnemosparkHomeDir
|
|
5523
5372
|
);
|
|
5524
5373
|
const syncArgs = stripAsyncControlFlags(ctx.args);
|
|
5525
5374
|
if (orchestratorMode === "subagent") {
|
|
@@ -5571,7 +5420,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5571
5420
|
subagentSessionId: sessionId,
|
|
5572
5421
|
progressMessage: "subagent running"
|
|
5573
5422
|
},
|
|
5574
|
-
|
|
5423
|
+
mnemosparkHomeDir
|
|
5575
5424
|
);
|
|
5576
5425
|
},
|
|
5577
5426
|
onProgress: async (sessionId, message) => {
|
|
@@ -5583,7 +5432,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5583
5432
|
subagentSessionId: sessionId,
|
|
5584
5433
|
progressMessage: message
|
|
5585
5434
|
},
|
|
5586
|
-
|
|
5435
|
+
mnemosparkHomeDir
|
|
5587
5436
|
);
|
|
5588
5437
|
},
|
|
5589
5438
|
onCompleted: async (sessionId) => {
|
|
@@ -5607,7 +5456,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5607
5456
|
status: "succeeded",
|
|
5608
5457
|
subagentSessionId: sessionId
|
|
5609
5458
|
},
|
|
5610
|
-
|
|
5459
|
+
mnemosparkHomeDir
|
|
5611
5460
|
);
|
|
5612
5461
|
},
|
|
5613
5462
|
onFailed: async (sessionId, details) => {
|
|
@@ -5633,7 +5482,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5633
5482
|
errorCode: details.code,
|
|
5634
5483
|
errorMessage: details.message
|
|
5635
5484
|
},
|
|
5636
|
-
|
|
5485
|
+
mnemosparkHomeDir
|
|
5637
5486
|
);
|
|
5638
5487
|
},
|
|
5639
5488
|
onCancelled: async (sessionId, reason) => {
|
|
@@ -5660,7 +5509,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5660
5509
|
errorCode: "ASYNC_CANCELLED",
|
|
5661
5510
|
errorMessage: reason ?? "Operation cancelled."
|
|
5662
5511
|
},
|
|
5663
|
-
|
|
5512
|
+
mnemosparkHomeDir
|
|
5664
5513
|
);
|
|
5665
5514
|
},
|
|
5666
5515
|
onTimedOut: async (sessionId) => {
|
|
@@ -5686,7 +5535,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5686
5535
|
errorCode: "ASYNC_TIMEOUT",
|
|
5687
5536
|
errorMessage: "Operation timed out."
|
|
5688
5537
|
},
|
|
5689
|
-
|
|
5538
|
+
mnemosparkHomeDir
|
|
5690
5539
|
);
|
|
5691
5540
|
}
|
|
5692
5541
|
}
|
|
@@ -5738,7 +5587,7 @@ async function runCloudCommandHandler(ctx, options, executionContext = {}) {
|
|
|
5738
5587
|
errorCode: "ASYNC_DISPATCH_FAILED",
|
|
5739
5588
|
errorMessage: dispatchMessage
|
|
5740
5589
|
},
|
|
5741
|
-
|
|
5590
|
+
mnemosparkHomeDir
|
|
5742
5591
|
);
|
|
5743
5592
|
return {
|
|
5744
5593
|
text: `Cannot dispatch subagent operation: ${dispatchMessage}
|
|
@@ -5785,7 +5634,7 @@ operation-id: ${operationId}`,
|
|
|
5785
5634
|
errorCode: result.isError ? "ASYNC_FAILED" : null,
|
|
5786
5635
|
errorMessage: result.isError ? result.text : null
|
|
5787
5636
|
},
|
|
5788
|
-
|
|
5637
|
+
mnemosparkHomeDir
|
|
5789
5638
|
);
|
|
5790
5639
|
}).catch(async (err) => {
|
|
5791
5640
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
@@ -5808,7 +5657,7 @@ operation-id: ${operationId}`,
|
|
|
5808
5657
|
errorCode: "ASYNC_EXCEPTION",
|
|
5809
5658
|
errorMessage
|
|
5810
5659
|
},
|
|
5811
|
-
|
|
5660
|
+
mnemosparkHomeDir
|
|
5812
5661
|
);
|
|
5813
5662
|
});
|
|
5814
5663
|
return {
|
|
@@ -5828,9 +5677,14 @@ operation-id: ${operationId}`,
|
|
|
5828
5677
|
operation_id: randomUUID3(),
|
|
5829
5678
|
object_id: result.objectId,
|
|
5830
5679
|
status: "succeeded",
|
|
5831
|
-
details: {
|
|
5680
|
+
details: {
|
|
5681
|
+
friendly_name: parsed.friendlyName ?? basename2(parsed.backupTarget),
|
|
5682
|
+
archive_path: result.archivePath,
|
|
5683
|
+
object_id_hash: result.objectIdHash.replace(/\s/g, ""),
|
|
5684
|
+
object_size_gb: result.objectSizeGb
|
|
5685
|
+
}
|
|
5832
5686
|
},
|
|
5833
|
-
|
|
5687
|
+
mnemosparkHomeDir
|
|
5834
5688
|
);
|
|
5835
5689
|
await datastore.upsertObject({
|
|
5836
5690
|
object_id: result.objectId,
|
|
@@ -5854,11 +5708,7 @@ operation-id: ${operationId}`,
|
|
|
5854
5708
|
});
|
|
5855
5709
|
}
|
|
5856
5710
|
return {
|
|
5857
|
-
text:
|
|
5858
|
-
`object-id: ${result.objectId}`,
|
|
5859
|
-
`object-id-hash: ${result.objectIdHash.replace(/\s/g, "")}`,
|
|
5860
|
-
`object-size: ${result.objectSizeGb}`
|
|
5861
|
-
].join("\n")
|
|
5711
|
+
text: formatBackupSuccessUserMessage(result)
|
|
5862
5712
|
};
|
|
5863
5713
|
} catch (err) {
|
|
5864
5714
|
if (err instanceof UnsupportedBackupPlatformError) {
|
|
@@ -5880,7 +5730,7 @@ operation-id: ${operationId}`,
|
|
|
5880
5730
|
...options.proxyQuoteOptions,
|
|
5881
5731
|
correlation
|
|
5882
5732
|
});
|
|
5883
|
-
await
|
|
5733
|
+
await datastore.ensureReady();
|
|
5884
5734
|
await datastore.upsertObject({
|
|
5885
5735
|
object_id: quote.object_id,
|
|
5886
5736
|
object_key: null,
|
|
@@ -5900,6 +5750,13 @@ operation-id: ${operationId}`,
|
|
|
5900
5750
|
network: null,
|
|
5901
5751
|
status: "quoted"
|
|
5902
5752
|
});
|
|
5753
|
+
const verified = await datastore.findQuoteById(quote.quote_id);
|
|
5754
|
+
if (!verified || !quoteLookupMatchesPriceStorageResponse(verified, quote)) {
|
|
5755
|
+
return {
|
|
5756
|
+
text: "Cannot price storage: quote was not saved to local SQLite (~/.openclaw/mnemospark/state.db). Check disk permissions or MNEMOSPARK_DISABLE_SQLITE.",
|
|
5757
|
+
isError: true
|
|
5758
|
+
};
|
|
5759
|
+
}
|
|
5903
5760
|
await emitCloudEventBestEffort(
|
|
5904
5761
|
"price-storage.completed",
|
|
5905
5762
|
{
|
|
@@ -5910,7 +5767,7 @@ operation-id: ${operationId}`,
|
|
|
5910
5767
|
quote_id: quote.quote_id,
|
|
5911
5768
|
status: "succeeded"
|
|
5912
5769
|
},
|
|
5913
|
-
|
|
5770
|
+
mnemosparkHomeDir
|
|
5914
5771
|
);
|
|
5915
5772
|
return {
|
|
5916
5773
|
text: formatPriceStorageUserMessage(quote)
|
|
@@ -5925,7 +5782,7 @@ operation-id: ${operationId}`,
|
|
|
5925
5782
|
object_id: parsed.priceStorageRequest.object_id,
|
|
5926
5783
|
status: "failed"
|
|
5927
5784
|
},
|
|
5928
|
-
|
|
5785
|
+
mnemosparkHomeDir
|
|
5929
5786
|
);
|
|
5930
5787
|
const message = err instanceof Error ? err.message : typeof err === "string" ? err : String(err);
|
|
5931
5788
|
return {
|
|
@@ -5940,10 +5797,10 @@ operation-id: ${operationId}`,
|
|
|
5940
5797
|
executionContext.forcedTraceId
|
|
5941
5798
|
);
|
|
5942
5799
|
try {
|
|
5943
|
-
const loggedQuote = await datastore.findQuoteById(parsed.uploadRequest.quote_id)
|
|
5800
|
+
const loggedQuote = await datastore.findQuoteById(parsed.uploadRequest.quote_id);
|
|
5944
5801
|
if (!loggedQuote) {
|
|
5945
5802
|
return {
|
|
5946
|
-
text: "Cannot upload storage object: quote-id not found in
|
|
5803
|
+
text: "Cannot upload storage object: quote-id not found in local SQLite. Run /mnemospark_cloud price-storage first (quotes expire after about one hour on the server).",
|
|
5947
5804
|
isError: true
|
|
5948
5805
|
};
|
|
5949
5806
|
}
|
|
@@ -5979,7 +5836,7 @@ operation-id: ${operationId}`,
|
|
|
5979
5836
|
isError: true
|
|
5980
5837
|
};
|
|
5981
5838
|
}
|
|
5982
|
-
const walletKey = await resolveWalletKey(
|
|
5839
|
+
const walletKey = await resolveWalletKey(mnemosparkHomeDir);
|
|
5983
5840
|
const walletAccount = privateKeyToAccount5(walletKey);
|
|
5984
5841
|
if (walletAccount.address.toLowerCase() !== parsed.uploadRequest.wallet_address.toLowerCase()) {
|
|
5985
5842
|
return {
|
|
@@ -5990,7 +5847,7 @@ operation-id: ${operationId}`,
|
|
|
5990
5847
|
const preparedPayload = await prepareUploadPayload(
|
|
5991
5848
|
archivePath,
|
|
5992
5849
|
parsed.uploadRequest.wallet_address,
|
|
5993
|
-
|
|
5850
|
+
mnemosparkHomeDir
|
|
5994
5851
|
);
|
|
5995
5852
|
const idempotencyKey = uploadCorrelation.operationId;
|
|
5996
5853
|
const shouldSettleBeforeUpload = requestStorageUpload !== requestStorageUploadViaProxy;
|
|
@@ -6056,13 +5913,12 @@ operation-id: ${operationId}`,
|
|
|
6056
5913
|
);
|
|
6057
5914
|
}
|
|
6058
5915
|
}
|
|
6059
|
-
await appendStorageUploadLog(finalizedUploadResponse, objectLogHomeDir, nowDateFn);
|
|
6060
5916
|
const cronStoragePriceCandidate = finalizedUploadResponse.storage_price ?? loggedQuote.storagePrice;
|
|
6061
5917
|
const cronStoragePrice = Number.isFinite(cronStoragePriceCandidate) && cronStoragePriceCandidate > 0 ? cronStoragePriceCandidate : loggedQuote.storagePrice;
|
|
6062
5918
|
const cronJob = await createStoragePaymentCronJob(
|
|
6063
5919
|
finalizedUploadResponse,
|
|
6064
5920
|
cronStoragePrice,
|
|
6065
|
-
|
|
5921
|
+
mnemosparkHomeDir,
|
|
6066
5922
|
nowDateFn
|
|
6067
5923
|
);
|
|
6068
5924
|
await datastore.upsertObject({
|
|
@@ -6115,7 +5971,7 @@ operation-id: ${operationId}`,
|
|
|
6115
5971
|
friendlyNameVerified = false;
|
|
6116
5972
|
}
|
|
6117
5973
|
if (!friendlyNameVerified) {
|
|
6118
|
-
const warning = "SQLite friendly-name write verification failed;
|
|
5974
|
+
const warning = "SQLite friendly-name write verification failed; --name lookups may not resolve until SQLite is healthy.";
|
|
6119
5975
|
await emitCloudEventBestEffort(
|
|
6120
5976
|
"friendly_name.write_verification_failed",
|
|
6121
5977
|
{
|
|
@@ -6128,27 +5984,12 @@ operation-id: ${operationId}`,
|
|
|
6128
5984
|
friendly_name: normalizedFriendlyName,
|
|
6129
5985
|
warning
|
|
6130
5986
|
},
|
|
6131
|
-
|
|
5987
|
+
mnemosparkHomeDir
|
|
6132
5988
|
);
|
|
6133
5989
|
if (process.env.MNEMOSPARK_SQLITE_STRICT === "1") {
|
|
6134
5990
|
throw new Error(warning);
|
|
6135
5991
|
}
|
|
6136
5992
|
}
|
|
6137
|
-
try {
|
|
6138
|
-
await appendJsonlEvent(
|
|
6139
|
-
"manifest.jsonl",
|
|
6140
|
-
{
|
|
6141
|
-
friendly_name: normalizedFriendlyName,
|
|
6142
|
-
object_id: finalizedUploadResponse.object_id,
|
|
6143
|
-
object_key: finalizedUploadResponse.object_key,
|
|
6144
|
-
quote_id: finalizedUploadResponse.quote_id,
|
|
6145
|
-
wallet_address: finalizedUploadResponse.addr,
|
|
6146
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6147
|
-
},
|
|
6148
|
-
objectLogHomeDir
|
|
6149
|
-
);
|
|
6150
|
-
} catch {
|
|
6151
|
-
}
|
|
6152
5993
|
}
|
|
6153
5994
|
await emitCloudEventBestEffort(
|
|
6154
5995
|
"upload.completed",
|
|
@@ -6161,7 +6002,7 @@ operation-id: ${operationId}`,
|
|
|
6161
6002
|
quote_id: finalizedUploadResponse.quote_id,
|
|
6162
6003
|
status: "succeeded"
|
|
6163
6004
|
},
|
|
6164
|
-
|
|
6005
|
+
mnemosparkHomeDir
|
|
6165
6006
|
);
|
|
6166
6007
|
await maybeCleanupLocalBackupArchive(archivePath);
|
|
6167
6008
|
return {
|
|
@@ -6178,7 +6019,7 @@ operation-id: ${operationId}`,
|
|
|
6178
6019
|
quote_id: parsed.uploadRequest.quote_id,
|
|
6179
6020
|
status: "failed"
|
|
6180
6021
|
},
|
|
6181
|
-
|
|
6022
|
+
mnemosparkHomeDir
|
|
6182
6023
|
);
|
|
6183
6024
|
const uploadErrorMessage = extractUploadErrorMessage(error);
|
|
6184
6025
|
return {
|
|
@@ -6191,24 +6032,12 @@ operation-id: ${operationId}`,
|
|
|
6191
6032
|
const resolved = await resolveNameSelectorIfNeeded(
|
|
6192
6033
|
datastore,
|
|
6193
6034
|
parsed.storageObjectRequest,
|
|
6194
|
-
parsed.nameSelector
|
|
6195
|
-
objectLogHomeDir
|
|
6035
|
+
parsed.nameSelector
|
|
6196
6036
|
);
|
|
6197
6037
|
if (resolved.error || !resolved.request) {
|
|
6198
6038
|
return { text: resolved.error ?? "Cannot resolve storage object request.", isError: true };
|
|
6199
6039
|
}
|
|
6200
6040
|
const resolvedRequest = resolved.request;
|
|
6201
|
-
if (resolved.degradedWarning) {
|
|
6202
|
-
await emitCloudEventBestEffort(
|
|
6203
|
-
"name_resolution.degraded",
|
|
6204
|
-
{
|
|
6205
|
-
wallet_address: resolvedRequest.wallet_address,
|
|
6206
|
-
object_key: resolvedRequest.object_key ?? null,
|
|
6207
|
-
warning: resolved.degradedWarning
|
|
6208
|
-
},
|
|
6209
|
-
objectLogHomeDir
|
|
6210
|
-
);
|
|
6211
|
-
}
|
|
6212
6041
|
const objectKeyForLs = resolvedRequest.object_key?.trim();
|
|
6213
6042
|
const isBucketList = !objectKeyForLs;
|
|
6214
6043
|
const correlation = buildRequestCorrelation();
|
|
@@ -6251,16 +6080,14 @@ operation-id: ${operationId}`,
|
|
|
6251
6080
|
status: "succeeded",
|
|
6252
6081
|
list_mode: isBucketList
|
|
6253
6082
|
},
|
|
6254
|
-
|
|
6083
|
+
mnemosparkHomeDir
|
|
6255
6084
|
);
|
|
6256
6085
|
const lsText = await buildMnemosparkLsMessage(lsResult, {
|
|
6257
6086
|
walletAddress: resolvedRequest.wallet_address,
|
|
6258
6087
|
datastore
|
|
6259
6088
|
});
|
|
6260
6089
|
return {
|
|
6261
|
-
text:
|
|
6262
|
-
|
|
6263
|
-
${lsText}` : lsText
|
|
6090
|
+
text: lsText
|
|
6264
6091
|
};
|
|
6265
6092
|
} catch (error) {
|
|
6266
6093
|
const lsErrorMessage = extractLsErrorMessage(error) ?? "Cannot list storage object";
|
|
@@ -6283,7 +6110,7 @@ ${lsText}` : lsText
|
|
|
6283
6110
|
status: "failed",
|
|
6284
6111
|
list_mode: isBucketList
|
|
6285
6112
|
},
|
|
6286
|
-
|
|
6113
|
+
mnemosparkHomeDir
|
|
6287
6114
|
);
|
|
6288
6115
|
return {
|
|
6289
6116
|
text: lsErrorMessage,
|
|
@@ -6295,8 +6122,7 @@ ${lsText}` : lsText
|
|
|
6295
6122
|
const resolved = await resolveNameSelectorIfNeeded(
|
|
6296
6123
|
datastore,
|
|
6297
6124
|
parsed.storageObjectRequest,
|
|
6298
|
-
parsed.nameSelector
|
|
6299
|
-
objectLogHomeDir
|
|
6125
|
+
parsed.nameSelector
|
|
6300
6126
|
);
|
|
6301
6127
|
if (resolved.error || !resolved.request) {
|
|
6302
6128
|
return { text: resolved.error ?? "Cannot resolve storage object request.", isError: true };
|
|
@@ -6309,17 +6135,6 @@ ${lsText}` : lsText
|
|
|
6309
6135
|
return { text: narrowed.error, isError: true };
|
|
6310
6136
|
}
|
|
6311
6137
|
const resolvedRequest = narrowed.request;
|
|
6312
|
-
if (resolved.degradedWarning) {
|
|
6313
|
-
await emitCloudEventBestEffort(
|
|
6314
|
-
"name_resolution.degraded",
|
|
6315
|
-
{
|
|
6316
|
-
wallet_address: resolvedRequest.wallet_address,
|
|
6317
|
-
object_key: resolvedRequest.object_key,
|
|
6318
|
-
warning: resolved.degradedWarning
|
|
6319
|
-
},
|
|
6320
|
-
objectLogHomeDir
|
|
6321
|
-
);
|
|
6322
|
-
}
|
|
6323
6138
|
const correlation = buildRequestCorrelation(
|
|
6324
6139
|
executionContext.forcedOperationId,
|
|
6325
6140
|
executionContext.forcedTraceId
|
|
@@ -6362,12 +6177,11 @@ ${lsText}` : lsText
|
|
|
6362
6177
|
object_key: resolvedRequest.object_key,
|
|
6363
6178
|
status: "succeeded"
|
|
6364
6179
|
},
|
|
6365
|
-
|
|
6180
|
+
mnemosparkHomeDir
|
|
6366
6181
|
);
|
|
6367
6182
|
const downloadText = `File ${resolvedRequest.object_key} downloaded to ${downloadResult.file_path}`;
|
|
6368
6183
|
return {
|
|
6369
|
-
text:
|
|
6370
|
-
${downloadText}` : downloadText
|
|
6184
|
+
text: downloadText
|
|
6371
6185
|
};
|
|
6372
6186
|
} catch {
|
|
6373
6187
|
await datastore.upsertOperation({
|
|
@@ -6388,7 +6202,7 @@ ${downloadText}` : downloadText
|
|
|
6388
6202
|
object_key: resolvedRequest.object_key,
|
|
6389
6203
|
status: "failed"
|
|
6390
6204
|
},
|
|
6391
|
-
|
|
6205
|
+
mnemosparkHomeDir
|
|
6392
6206
|
);
|
|
6393
6207
|
return {
|
|
6394
6208
|
text: "Cannot download file",
|
|
@@ -6400,8 +6214,7 @@ ${downloadText}` : downloadText
|
|
|
6400
6214
|
const resolved = await resolveNameSelectorIfNeeded(
|
|
6401
6215
|
datastore,
|
|
6402
6216
|
parsed.storageObjectRequest,
|
|
6403
|
-
parsed.nameSelector
|
|
6404
|
-
objectLogHomeDir
|
|
6217
|
+
parsed.nameSelector
|
|
6405
6218
|
);
|
|
6406
6219
|
if (resolved.error || !resolved.request) {
|
|
6407
6220
|
return { text: resolved.error ?? "Cannot resolve storage object request.", isError: true };
|
|
@@ -6414,17 +6227,6 @@ ${downloadText}` : downloadText
|
|
|
6414
6227
|
return { text: narrowedDelete.error, isError: true };
|
|
6415
6228
|
}
|
|
6416
6229
|
const resolvedRequest = narrowedDelete.request;
|
|
6417
|
-
if (resolved.degradedWarning) {
|
|
6418
|
-
await emitCloudEventBestEffort(
|
|
6419
|
-
"name_resolution.degraded",
|
|
6420
|
-
{
|
|
6421
|
-
wallet_address: resolvedRequest.wallet_address,
|
|
6422
|
-
object_key: resolvedRequest.object_key,
|
|
6423
|
-
warning: resolved.degradedWarning
|
|
6424
|
-
},
|
|
6425
|
-
objectLogHomeDir
|
|
6426
|
-
);
|
|
6427
|
-
}
|
|
6428
6230
|
const correlation = buildRequestCorrelation();
|
|
6429
6231
|
const operationId = correlation.operationId;
|
|
6430
6232
|
const existingObjectByKey = await datastore.findObjectByObjectKey(resolvedRequest.object_key);
|
|
@@ -6446,7 +6248,7 @@ ${downloadText}` : downloadText
|
|
|
6446
6248
|
object_key: resolvedRequest.object_key,
|
|
6447
6249
|
status: "failed"
|
|
6448
6250
|
},
|
|
6449
|
-
|
|
6251
|
+
mnemosparkHomeDir
|
|
6450
6252
|
);
|
|
6451
6253
|
return {
|
|
6452
6254
|
text: "Cannot delete file",
|
|
@@ -6465,15 +6267,15 @@ ${downloadText}` : downloadText
|
|
|
6465
6267
|
};
|
|
6466
6268
|
}
|
|
6467
6269
|
if (!cronEntry) {
|
|
6468
|
-
cronEntry = await
|
|
6270
|
+
cronEntry = await findCronJobInCrontabByObjectKey(
|
|
6469
6271
|
resolvedRequest.object_key,
|
|
6470
|
-
|
|
6272
|
+
mnemosparkHomeDir
|
|
6471
6273
|
);
|
|
6472
6274
|
}
|
|
6473
6275
|
if (cronEntry) {
|
|
6474
6276
|
const fileCronDeleted = await removeStoragePaymentCronJob(
|
|
6475
6277
|
cronEntry.cronId,
|
|
6476
|
-
|
|
6278
|
+
mnemosparkHomeDir
|
|
6477
6279
|
);
|
|
6478
6280
|
const dbCronDeleted = await datastore.removeCronJob(cronEntry.cronId);
|
|
6479
6281
|
cronDeleted = fileCronDeleted || dbCronDeleted;
|
|
@@ -6504,7 +6306,7 @@ ${downloadText}` : downloadText
|
|
|
6504
6306
|
object_key: resolvedRequest.object_key,
|
|
6505
6307
|
status: "succeeded"
|
|
6506
6308
|
},
|
|
6507
|
-
|
|
6309
|
+
mnemosparkHomeDir
|
|
6508
6310
|
);
|
|
6509
6311
|
const deleteText = formatStorageDeleteUserMessage(
|
|
6510
6312
|
resolvedRequest.object_key,
|
|
@@ -6512,8 +6314,7 @@ ${downloadText}` : downloadText
|
|
|
6512
6314
|
cronDeleted
|
|
6513
6315
|
);
|
|
6514
6316
|
return {
|
|
6515
|
-
text:
|
|
6516
|
-
${deleteText}` : deleteText
|
|
6317
|
+
text: deleteText
|
|
6517
6318
|
};
|
|
6518
6319
|
}
|
|
6519
6320
|
return {
|