@arbidocs/cli 0.3.49 → 0.3.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/index.js +165 -22
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.3.51
|
|
4
|
+
|
|
5
|
+
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.50...HEAD)
|
|
6
|
+
|
|
7
|
+
### 🔥 Performance
|
|
8
|
+
|
|
9
|
+
- Stop auto-refetching workspace documents/conversations/tags ([#650](https://github.com/arbicity/ARBI-frontend/pull/650), [#651](https://github.com/arbicity/ARBI-frontend/pull/651))
|
|
10
|
+
|
|
11
|
+
### 🩹 Fixes
|
|
12
|
+
|
|
13
|
+
- Exclude /arbi-files/ from static-asset nginx location so image uploads reach MinIO ([#646](https://github.com/arbicity/ARBI-frontend/pull/646))
|
|
14
|
+
- Make workspace switch sequential and race-free ([#648](https://github.com/arbicity/ARBI-frontend/pull/648), [#649](https://github.com/arbicity/ARBI-frontend/pull/649))
|
|
15
|
+
- Omit doc_ext_ids by default in retrieve, cap explicit selection at 5000 ([#652](https://github.com/arbicity/ARBI-frontend/pull/652))
|
|
16
|
+
|
|
17
|
+
## v0.3.50
|
|
18
|
+
|
|
19
|
+
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.49...HEAD)
|
|
20
|
+
|
|
21
|
+
### 🚀 Enhancements
|
|
22
|
+
|
|
23
|
+
- Use FileX icon for empty document status ([#643](https://github.com/arbicity/ARBI-frontend/pull/643))
|
|
24
|
+
- **cli:** Improve reprocess progress with two-phase reporting ([#584](https://github.com/arbicity/ARBI-frontend/pull/584))
|
|
25
|
+
|
|
3
26
|
## v0.3.49
|
|
4
27
|
|
|
5
28
|
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.48...HEAD)
|
package/dist/index.js
CHANGED
|
@@ -3641,7 +3641,7 @@ function getLatestVersion(skipCache = false) {
|
|
|
3641
3641
|
}
|
|
3642
3642
|
}
|
|
3643
3643
|
function getCurrentVersion() {
|
|
3644
|
-
return "0.3.
|
|
3644
|
+
return "0.3.51";
|
|
3645
3645
|
}
|
|
3646
3646
|
function readChangelog(fromVersion, toVersion) {
|
|
3647
3647
|
try {
|
|
@@ -3694,17 +3694,17 @@ function showChangelog(fromVersion, toVersion) {
|
|
|
3694
3694
|
async function checkForUpdates(autoUpdate) {
|
|
3695
3695
|
try {
|
|
3696
3696
|
const latest = getLatestVersion();
|
|
3697
|
-
if (!latest || latest === "0.3.
|
|
3697
|
+
if (!latest || latest === "0.3.51") return;
|
|
3698
3698
|
if (autoUpdate) {
|
|
3699
3699
|
warn(`
|
|
3700
|
-
Your arbi version is out of date (${"0.3.
|
|
3700
|
+
Your arbi version is out of date (${"0.3.51"} \u2192 ${latest}). Updating...`);
|
|
3701
3701
|
child_process.execSync("npm install -g @arbidocs/cli@latest", { stdio: "inherit" });
|
|
3702
|
-
showChangelog("0.3.
|
|
3702
|
+
showChangelog("0.3.51", latest);
|
|
3703
3703
|
console.log(`Updated to ${latest}.`);
|
|
3704
3704
|
} else {
|
|
3705
3705
|
warn(
|
|
3706
3706
|
`
|
|
3707
|
-
Your arbi version is out of date (${"0.3.
|
|
3707
|
+
Your arbi version is out of date (${"0.3.51"} \u2192 ${latest}).
|
|
3708
3708
|
Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
3709
3709
|
);
|
|
3710
3710
|
}
|
|
@@ -3714,9 +3714,9 @@ Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
|
3714
3714
|
function hintUpdateOnError() {
|
|
3715
3715
|
try {
|
|
3716
3716
|
const cached = readCache();
|
|
3717
|
-
if (cached && cached.latest !== "0.3.
|
|
3717
|
+
if (cached && cached.latest !== "0.3.51") {
|
|
3718
3718
|
warn(
|
|
3719
|
-
`Your arbi version is out of date (${"0.3.
|
|
3719
|
+
`Your arbi version is out of date (${"0.3.51"} \u2192 ${cached.latest}). Run "arbi update".`
|
|
3720
3720
|
);
|
|
3721
3721
|
}
|
|
3722
3722
|
} catch {
|
|
@@ -5338,10 +5338,16 @@ function registerDocsCommand(program2) {
|
|
|
5338
5338
|
"--status-interval <seconds>",
|
|
5339
5339
|
"Seconds between progress lines (0 to disable periodic printing).",
|
|
5340
5340
|
"5"
|
|
5341
|
-
).option("-v, --verbose", "Print a log line after each batch in addition to periodic stats.").option("-q, --quiet", "Suppress periodic progress lines \u2014 only print the final summary.").action(
|
|
5341
|
+
).option("-v, --verbose", "Print a log line after each batch in addition to periodic stats.").option("-q, --quiet", "Suppress periodic progress lines \u2014 only print the final summary.").option("-W, --watch", "Watch document processing progress after submission").option("--no-watch", "Skip watching document processing").action(
|
|
5342
5342
|
(ids, opts) => runAction(async () => {
|
|
5343
|
-
const
|
|
5343
|
+
const isInteractive = process.stdout.isTTY === true;
|
|
5344
|
+
const watchPref = getConfig()?.watch !== false;
|
|
5345
|
+
const willWatch = opts.watch === false ? false : opts.watch === true || watchPref && isInteractive;
|
|
5346
|
+
const { arbi, config, accessToken } = await resolveWorkspace(void 0, {
|
|
5347
|
+
skipNotifications: true
|
|
5348
|
+
});
|
|
5344
5349
|
let docIds;
|
|
5350
|
+
const docNames = /* @__PURE__ */ new Map();
|
|
5345
5351
|
if (ids && ids.length > 0) {
|
|
5346
5352
|
if (opts.ext || opts.folder) {
|
|
5347
5353
|
warn("--ext/--folder are ignored when explicit IDs are given.");
|
|
@@ -5366,6 +5372,9 @@ function registerDocsCommand(program2) {
|
|
|
5366
5372
|
);
|
|
5367
5373
|
}
|
|
5368
5374
|
docIds = filtered.map((d) => d.external_id);
|
|
5375
|
+
for (const d of filtered) {
|
|
5376
|
+
docNames.set(d.external_id, d.file_name ?? "Unnamed");
|
|
5377
|
+
}
|
|
5369
5378
|
} else {
|
|
5370
5379
|
error("Provide document IDs or use --status to select documents to reprocess.");
|
|
5371
5380
|
process.exit(1);
|
|
@@ -5406,11 +5415,21 @@ function registerDocsCommand(program2) {
|
|
|
5406
5415
|
const pad = (n) => n.toString().padStart(2, "0");
|
|
5407
5416
|
return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
5408
5417
|
};
|
|
5418
|
+
let procCompleted = 0;
|
|
5419
|
+
let procFailed = 0;
|
|
5420
|
+
const procPending = /* @__PURE__ */ new Set();
|
|
5421
|
+
const procFailedDetails = /* @__PURE__ */ new Map();
|
|
5409
5422
|
const printStatus = (prefix = "") => {
|
|
5410
5423
|
const now = Date.now();
|
|
5411
5424
|
const elapsed = now - startMs;
|
|
5412
|
-
const
|
|
5413
|
-
|
|
5425
|
+
const submitRate = submitted > 0 ? submitted / elapsed * 1e3 : 0;
|
|
5426
|
+
let bar = `[${formatClock(now)}] submitted=${submitted}/${total} api_ok=${succeeded} api_err=${failed} rate=${submitRate.toFixed(1)}/s elapsed=${formatDuration(elapsed)}`;
|
|
5427
|
+
if (willWatch) {
|
|
5428
|
+
const procRate = procCompleted > 0 ? procCompleted / elapsed * 1e3 : 0;
|
|
5429
|
+
const pendingCount = procPending.size;
|
|
5430
|
+
const eta = procRate > 0 ? pendingCount / procRate : 0;
|
|
5431
|
+
bar += ` | proc_ok=${procCompleted} proc_err=${procFailed} proc_pending=${pendingCount} rate(proc)=${procRate.toFixed(1)}/s eta(processing)=${formatDuration(eta * 1e3)}`;
|
|
5432
|
+
}
|
|
5414
5433
|
console.log(`${prefix}${bar}`);
|
|
5415
5434
|
};
|
|
5416
5435
|
let statusTimer;
|
|
@@ -5437,6 +5456,65 @@ function registerDocsCommand(program2) {
|
|
|
5437
5456
|
return false;
|
|
5438
5457
|
}
|
|
5439
5458
|
};
|
|
5459
|
+
let conn = null;
|
|
5460
|
+
let onWatchDone = null;
|
|
5461
|
+
let watchDonePromise = null;
|
|
5462
|
+
let submissionDone = false;
|
|
5463
|
+
if (willWatch) {
|
|
5464
|
+
watchDonePromise = new Promise((r) => {
|
|
5465
|
+
onWatchDone = r;
|
|
5466
|
+
});
|
|
5467
|
+
try {
|
|
5468
|
+
conn = await sdk.connectWithReconnect({
|
|
5469
|
+
baseUrl: config.baseUrl,
|
|
5470
|
+
accessToken,
|
|
5471
|
+
onReconnecting: (attempt, max) => {
|
|
5472
|
+
warn(` WebSocket reconnecting (${attempt}/${max})...`);
|
|
5473
|
+
},
|
|
5474
|
+
onReconnectFailed: () => {
|
|
5475
|
+
error(' WebSocket reconnection failed. Run "arbi watch" to resume monitoring.');
|
|
5476
|
+
},
|
|
5477
|
+
onMessage: (msg) => {
|
|
5478
|
+
if (!client.isMessageType(msg, "task_update")) return;
|
|
5479
|
+
if (!procPending.has(msg.doc_ext_id)) return;
|
|
5480
|
+
const docName = docNames.get(msg.doc_ext_id) || msg.file_name;
|
|
5481
|
+
const extra = msg;
|
|
5482
|
+
if (msg.status === "failed") {
|
|
5483
|
+
procFailed += 1;
|
|
5484
|
+
procPending.delete(msg.doc_ext_id);
|
|
5485
|
+
const wsReason = extra.error_reason || extra.status_details || extra.detail || "";
|
|
5486
|
+
const logFailure = (reason) => {
|
|
5487
|
+
const suffix = reason ? ` \u2014 ${reason}` : "";
|
|
5488
|
+
procFailedDetails.set(msg.doc_ext_id, `${docName}${suffix}`);
|
|
5489
|
+
console.log(` ${docName}: ${chalk2__default.default.red("processing failed")}${suffix}`);
|
|
5490
|
+
if (submissionDone && procPending.size === 0) conn?.close();
|
|
5491
|
+
};
|
|
5492
|
+
if (wsReason) {
|
|
5493
|
+
logFailure(wsReason);
|
|
5494
|
+
} else {
|
|
5495
|
+
sdk.documents.getDocuments(arbi, [msg.doc_ext_id]).then((docs) => {
|
|
5496
|
+
const d = docs[0];
|
|
5497
|
+
logFailure(d?.error_message || "");
|
|
5498
|
+
}).catch(() => logFailure(""));
|
|
5499
|
+
}
|
|
5500
|
+
} else if (msg.status === "completed" || msg.status === "skipped" || msg.status === "empty") {
|
|
5501
|
+
procCompleted += 1;
|
|
5502
|
+
procPending.delete(msg.doc_ext_id);
|
|
5503
|
+
}
|
|
5504
|
+
if (msg.status !== "failed" && submissionDone && procPending.size === 0) {
|
|
5505
|
+
conn?.close();
|
|
5506
|
+
}
|
|
5507
|
+
},
|
|
5508
|
+
onClose: () => {
|
|
5509
|
+
onWatchDone?.();
|
|
5510
|
+
}
|
|
5511
|
+
});
|
|
5512
|
+
} catch {
|
|
5513
|
+
warn("WebSocket connection failed. Proceeding without processing watch.");
|
|
5514
|
+
conn = null;
|
|
5515
|
+
watchDonePromise = null;
|
|
5516
|
+
}
|
|
5517
|
+
}
|
|
5440
5518
|
try {
|
|
5441
5519
|
for (let i = 0; i < docIds.length; i += batchSize) {
|
|
5442
5520
|
const batch = docIds.slice(i, i + batchSize);
|
|
@@ -5451,6 +5529,7 @@ function registerDocsCommand(program2) {
|
|
|
5451
5529
|
if (batchOk) {
|
|
5452
5530
|
succeeded += batch.length;
|
|
5453
5531
|
submitted += batch.length;
|
|
5532
|
+
for (const id of batch) procPending.add(id);
|
|
5454
5533
|
if (opts.verbose) {
|
|
5455
5534
|
console.log(` [${submitted}/${total}] Triggered reprocessing...`);
|
|
5456
5535
|
}
|
|
@@ -5465,6 +5544,7 @@ function registerDocsCommand(program2) {
|
|
|
5465
5544
|
const docOk = await submitBatch([id]);
|
|
5466
5545
|
if (docOk) {
|
|
5467
5546
|
succeeded += 1;
|
|
5547
|
+
procPending.add(id);
|
|
5468
5548
|
} else {
|
|
5469
5549
|
failed += 1;
|
|
5470
5550
|
failedIds.push(id);
|
|
@@ -5482,10 +5562,11 @@ function registerDocsCommand(program2) {
|
|
|
5482
5562
|
} finally {
|
|
5483
5563
|
if (statusTimer) clearInterval(statusTimer);
|
|
5484
5564
|
}
|
|
5565
|
+
submissionDone = true;
|
|
5485
5566
|
console.log("");
|
|
5486
5567
|
printStatus();
|
|
5487
5568
|
if (failed > 0) {
|
|
5488
|
-
warn(`${failed} document(s) failed to
|
|
5569
|
+
warn(`${failed} document(s) failed to submit.`);
|
|
5489
5570
|
const preview = failedIds.slice(0, 20);
|
|
5490
5571
|
preview.forEach((id) => console.log(` ${chalk2__default.default.red("\u2717")} ${id}`));
|
|
5491
5572
|
if (failedIds.length > preview.length) {
|
|
@@ -5493,7 +5574,60 @@ function registerDocsCommand(program2) {
|
|
|
5493
5574
|
}
|
|
5494
5575
|
}
|
|
5495
5576
|
if (succeeded > 0) {
|
|
5496
|
-
success(`
|
|
5577
|
+
success(`Submitted ${succeeded} document(s) for reprocessing.`);
|
|
5578
|
+
}
|
|
5579
|
+
if (watchDonePromise && conn && procPending.size > 0) {
|
|
5580
|
+
console.log(chalk2__default.default.bold(`
|
|
5581
|
+
Watching processing for ${procPending.size} document(s)...`));
|
|
5582
|
+
let watchTimer;
|
|
5583
|
+
if (!opts.quiet && statusIntervalMs > 0) {
|
|
5584
|
+
watchTimer = setInterval(() => printStatus(" "), statusIntervalMs);
|
|
5585
|
+
}
|
|
5586
|
+
await watchDonePromise;
|
|
5587
|
+
if (watchTimer) clearInterval(watchTimer);
|
|
5588
|
+
const totalElapsed = formatDuration(Date.now() - startMs);
|
|
5589
|
+
if (procFailedDetails.size > 0) {
|
|
5590
|
+
console.log(
|
|
5591
|
+
`
|
|
5592
|
+
Processing complete: completed=${procCompleted} failed=${procFailed} elapsed=${totalElapsed}`
|
|
5593
|
+
);
|
|
5594
|
+
error("Failed documents:");
|
|
5595
|
+
for (const [, detail] of procFailedDetails) {
|
|
5596
|
+
error(` ${detail}`);
|
|
5597
|
+
}
|
|
5598
|
+
} else if (procPending.size > 0) {
|
|
5599
|
+
warn(`
|
|
5600
|
+
Disconnected. ${procPending.size} document(s) still processing.`);
|
|
5601
|
+
dim('Run "arbi watch" to continue monitoring, or "arbi docs" to check status.');
|
|
5602
|
+
} else {
|
|
5603
|
+
success(
|
|
5604
|
+
`
|
|
5605
|
+
Processing complete: completed=${procCompleted} failed=0 elapsed=${totalElapsed} ${chalk2__default.default.green("\u2713 all ok")}`
|
|
5606
|
+
);
|
|
5607
|
+
}
|
|
5608
|
+
} else if (succeeded > 0 && !willWatch) {
|
|
5609
|
+
dim(
|
|
5610
|
+
'Tip: Use -W/--watch to monitor processing progress, or run "arbi docs" to check status.'
|
|
5611
|
+
);
|
|
5612
|
+
} else if (watchDonePromise && conn && procPending.size === 0) {
|
|
5613
|
+
conn.close();
|
|
5614
|
+
await watchDonePromise;
|
|
5615
|
+
const totalElapsed = formatDuration(Date.now() - startMs);
|
|
5616
|
+
if (procFailedDetails.size > 0) {
|
|
5617
|
+
console.log(
|
|
5618
|
+
`
|
|
5619
|
+
Processing complete: completed=${procCompleted} failed=${procFailed} elapsed=${totalElapsed}`
|
|
5620
|
+
);
|
|
5621
|
+
error("Failed documents:");
|
|
5622
|
+
for (const [, detail] of procFailedDetails) {
|
|
5623
|
+
error(` ${detail}`);
|
|
5624
|
+
}
|
|
5625
|
+
} else {
|
|
5626
|
+
success(
|
|
5627
|
+
`
|
|
5628
|
+
Processing complete: completed=${procCompleted} failed=0 elapsed=${totalElapsed} ${chalk2__default.default.green("\u2713 all ok")}`
|
|
5629
|
+
);
|
|
5630
|
+
}
|
|
5497
5631
|
}
|
|
5498
5632
|
})()
|
|
5499
5633
|
);
|
|
@@ -6790,6 +6924,7 @@ function printCitationDetail(num, resolved) {
|
|
|
6790
6924
|
console.log(chalk2__default.default.dim(" (no passage data available)"));
|
|
6791
6925
|
}
|
|
6792
6926
|
}
|
|
6927
|
+
var MAX_INDIVIDUALLY_SELECTED_DOCS = 5e3;
|
|
6793
6928
|
function chunkScore(chunk) {
|
|
6794
6929
|
return chunk.metadata.rerank_score ?? chunk.metadata.score ?? 0;
|
|
6795
6930
|
}
|
|
@@ -6802,20 +6937,28 @@ function fmtScore(score) {
|
|
|
6802
6937
|
return `[${pct}%]`;
|
|
6803
6938
|
}
|
|
6804
6939
|
function registerFindCommand(program2) {
|
|
6805
|
-
program2.command("find <query...>").description("Search documents without LLM generation (retrieve only)").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").option("-m, --mode <mode>", "Search mode: semantic, keyword, hybrid", "semantic").option(
|
|
6940
|
+
program2.command("find <query...>").description("Search documents without LLM generation (retrieve only)").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").option("-m, --mode <mode>", "Search mode: semantic, keyword, hybrid", "semantic").option(
|
|
6941
|
+
"-d, --docs <ids>",
|
|
6942
|
+
`Comma-separated document IDs to search within (omit to search the whole workspace; max ${MAX_INDIVIDUALLY_SELECTED_DOCS} when set)`
|
|
6943
|
+
).option("--min-score <n>", "Minimum relevance score 0-1", "0.2").option("-l, --limit <n>", "Max results to display", "20").option("--flat", "Flat list sorted by relevance (instead of grouped by document)").option("--toc <ids>", "Comma-separated doc IDs to fetch table of contents for").option("--full-context <ids>", "Comma-separated doc IDs to fetch full content for").option("--json", "Raw JSON output for scripting").action(
|
|
6806
6944
|
(words, opts) => runAction(async () => {
|
|
6807
6945
|
const query = words.join(" ");
|
|
6808
6946
|
const { arbi, workspaceId } = await resolveWorkspace(opts.workspace);
|
|
6809
6947
|
let docIds;
|
|
6810
6948
|
if (opts.docs) {
|
|
6811
|
-
docIds = opts.docs.split(",").map((id) => id.trim());
|
|
6949
|
+
docIds = opts.docs.split(",").map((id) => id.trim()).filter((id) => id.length > 0);
|
|
6950
|
+
if (docIds.length > MAX_INDIVIDUALLY_SELECTED_DOCS) {
|
|
6951
|
+
console.error(
|
|
6952
|
+
chalk2__default.default.red(
|
|
6953
|
+
`Error: ${docIds.length.toLocaleString()} document IDs supplied \u2014 maximum is ${MAX_INDIVIDUALLY_SELECTED_DOCS.toLocaleString()}.
|
|
6954
|
+
Narrow your selection, or omit -d to search the whole workspace.`
|
|
6955
|
+
)
|
|
6956
|
+
);
|
|
6957
|
+
process.exitCode = 1;
|
|
6958
|
+
return;
|
|
6959
|
+
}
|
|
6812
6960
|
} else {
|
|
6813
|
-
|
|
6814
|
-
docIds = docs.map((d) => d.external_id);
|
|
6815
|
-
}
|
|
6816
|
-
if (docIds.length === 0) {
|
|
6817
|
-
console.log("No documents found in workspace.");
|
|
6818
|
-
return;
|
|
6961
|
+
docIds = [];
|
|
6819
6962
|
}
|
|
6820
6963
|
const searchMode = opts.mode ?? "semantic";
|
|
6821
6964
|
const tocDocIds = opts.toc ? opts.toc.split(",").map((id) => id.trim()) : void 0;
|
|
@@ -8606,7 +8749,7 @@ console.info = (...args) => {
|
|
|
8606
8749
|
_origInfo(...args);
|
|
8607
8750
|
};
|
|
8608
8751
|
var program = new commander.Command();
|
|
8609
|
-
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.
|
|
8752
|
+
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.51");
|
|
8610
8753
|
registerConfigCommand(program);
|
|
8611
8754
|
registerLoginCommand(program);
|
|
8612
8755
|
registerRegisterCommand(program);
|