@arbidocs/cli 0.3.13 → 0.3.15
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 +84 -2
- package/dist/index.js +365 -22
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,94 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.3.15
|
|
4
|
+
|
|
5
|
+
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.14...HEAD)
|
|
6
|
+
|
|
7
|
+
### 🚀 Enhancements
|
|
8
|
+
|
|
9
|
+
- Adopt message status field for failed message UI ([b267e7b8](https://github.com/arbicity/ARBI-frontend/commit/b267e7b8))
|
|
10
|
+
|
|
11
|
+
### 🩹 Fixes
|
|
12
|
+
|
|
13
|
+
- **cli:** Always start fresh conversation for background queries ([891ed884](https://github.com/arbicity/ARBI-frontend/commit/891ed884))
|
|
14
|
+
|
|
15
|
+
## v0.3.14
|
|
16
|
+
|
|
17
|
+
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.13...HEAD)
|
|
18
|
+
|
|
19
|
+
### 🚀 Enhancements
|
|
20
|
+
|
|
21
|
+
- **cli:** Verbose default, configurable watch, default notifications ([22f0faea](https://github.com/arbicity/ARBI-frontend/commit/22f0faea))
|
|
22
|
+
- **cli:** Add response summary line and per-step token usage ([506c723d](https://github.com/arbicity/ARBI-frontend/commit/506c723d))
|
|
23
|
+
- **cli:** Add `arbi task` command for background query submission ([fb492311](https://github.com/arbicity/ARBI-frontend/commit/fb492311))
|
|
24
|
+
- Update schema, SSE token context, and context usage display ([9f908e99](https://github.com/arbicity/ARBI-frontend/commit/9f908e99))
|
|
25
|
+
|
|
26
|
+
### 🩹 Fixes
|
|
27
|
+
|
|
28
|
+
- Remove stray fi in publish script causing exit code 2 ([7739d8de](https://github.com/arbicity/ARBI-frontend/commit/7739d8de))
|
|
29
|
+
- Changelog generation and enforce conventional commits ([ac5b2e75](https://github.com/arbicity/ARBI-frontend/commit/ac5b2e75))
|
|
30
|
+
|
|
31
|
+
### 💅 Refactors
|
|
32
|
+
|
|
33
|
+
- **cli:** Move background mode to `arbi ask -b`, simplify task command ([2b9a1a51](https://github.com/arbicity/ARBI-frontend/commit/2b9a1a51))
|
|
34
|
+
|
|
3
35
|
## v0.3.13
|
|
4
36
|
|
|
5
|
-
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.
|
|
37
|
+
[compare changes](https://github.com/arbicity/ARBI-frontend/compare/v0.3.10...v0.3.13)
|
|
38
|
+
|
|
39
|
+
### 🚀 Enhancements
|
|
40
|
+
|
|
41
|
+
- Tool-specific icons and labels for agent step rendering ([22377ee4](https://github.com/arbicity/ARBI-frontend/commit/22377ee4))
|
|
42
|
+
- Move TOOL_LABELS and LIFECYCLE_LABELS to SDK as single source of truth ([b180663f](https://github.com/arbicity/ARBI-frontend/commit/b180663f))
|
|
43
|
+
- Move templates to agentic mode with get_full_document ([9e625515](https://github.com/arbicity/ARBI-frontend/commit/9e625515))
|
|
44
|
+
- CLI DX improvements: error messages, JWT caching, auto-detect, watch flags, quickstart & agent-create ([eefcc3ef](https://github.com/arbicity/ARBI-frontend/commit/eefcc3ef))
|
|
45
|
+
- Add comprehensive CLI integration tests ([bb5088d2](https://github.com/arbicity/ARBI-frontend/commit/bb5088d2))
|
|
46
|
+
- Simplified template modals v2 ([b2639ea7](https://github.com/arbicity/ARBI-frontend/commit/b2639ea7))
|
|
47
|
+
- Searchable document combobox for Summarise and Translate templates ([880db107](https://github.com/arbicity/ARBI-frontend/commit/880db107))
|
|
48
|
+
- Document page/token counts with size warnings ([49c72ab8](https://github.com/arbicity/ARBI-frontend/commit/49c72ab8))
|
|
49
|
+
- Preserve folder structure on upload ([dc09dbfa](https://github.com/arbicity/ARBI-frontend/commit/dc09dbfa))
|
|
50
|
+
- Folder UI for Documents page ([aaf08dbc](https://github.com/arbicity/ARBI-frontend/commit/aaf08dbc))
|
|
51
|
+
- Uploaded/generated toggle and folder tree in FilterDropdown ([87351c31](https://github.com/arbicity/ARBI-frontend/commit/87351c31))
|
|
52
|
+
- Add text search to Documents page ([bda72622](https://github.com/arbicity/ARBI-frontend/commit/bda72622))
|
|
53
|
+
- Add search field selector and expose folder/content_hash columns ([595d02eb](https://github.com/arbicity/ARBI-frontend/commit/595d02eb))
|
|
54
|
+
- Agentic mode toggle and agent step text handling ([22852e84](https://github.com/arbicity/ARBI-frontend/commit/22852e84))
|
|
55
|
+
- Add Duplicates tri-state filter for documents ([e1682939](https://github.com/arbicity/ARBI-frontend/commit/e1682939))
|
|
56
|
+
- Home page cards: left-align, group by matter ID with collapsible sub-sections ([f3e51750](https://github.com/arbicity/ARBI-frontend/commit/f3e51750))
|
|
57
|
+
- Documents grid improvements, collapsible folder filter, agent step durations ([735f066b](https://github.com/arbicity/ARBI-frontend/commit/735f066b))
|
|
58
|
+
- Developer tab: nested schema fields, footer layout, Apply button ([7daac802](https://github.com/arbicity/ARBI-frontend/commit/7daac802))
|
|
59
|
+
- Redesign templates as horizontal rows with pin button ([8ed4c4e1](https://github.com/arbicity/ARBI-frontend/commit/8ed4c4e1))
|
|
60
|
+
- Make @arbidocs/sdk WebContainer-compatible ([2e5446f3](https://github.com/arbicity/ARBI-frontend/commit/2e5446f3))
|
|
61
|
+
- Optimize HtmlViewer for large documents with lazy loading ([aa3f7733](https://github.com/arbicity/ARBI-frontend/commit/aa3f7733))
|
|
62
|
+
|
|
63
|
+
### 🩹 Fixes
|
|
64
|
+
|
|
65
|
+
- Fix stale cached token after login/workspace switch ([ef222604](https://github.com/arbicity/ARBI-frontend/commit/ef222604))
|
|
66
|
+
- Fix CI publish: restore PAT_PUBLISH, fail loudly on push errors ([15b8d8e8](https://github.com/arbicity/ARBI-frontend/commit/15b8d8e8))
|
|
67
|
+
- Fix bulk actions toolbar hidden in document modals ([fcf70be3](https://github.com/arbicity/ARBI-frontend/commit/fcf70be3))
|
|
68
|
+
- Resolve document titles in agent step display ([71da1b41](https://github.com/arbicity/ARBI-frontend/commit/71da1b41))
|
|
69
|
+
- Fix document grid in modals by using fixed height ([0e5ed342](https://github.com/arbicity/ARBI-frontend/commit/0e5ed342))
|
|
70
|
+
- Fix citation scroll-to-chunk and show page nav for HTML view ([624a6cfc](https://github.com/arbicity/ARBI-frontend/commit/624a6cfc))
|
|
71
|
+
- Fix citation scroll-to-passage and remove markdown arrow artifacts ([3ce0d32d](https://github.com/arbicity/ARBI-frontend/commit/3ce0d32d))
|
|
72
|
+
- Fix Apply button: stop resetting newConfigId on parentMessageId change ([729f30e9](https://github.com/arbicity/ARBI-frontend/commit/729f30e9))
|
|
73
|
+
- Fix streaming content truncated in non-agentic mode ([7f338f25](https://github.com/arbicity/ARBI-frontend/commit/7f338f25))
|
|
74
|
+
- Prevent agent step preamble from appearing in message body ([0e99e3ed](https://github.com/arbicity/ARBI-frontend/commit/0e99e3ed))
|
|
75
|
+
- Fix model selector resets on messageHistory/parentConfig changes ([c30e4d7c](https://github.com/arbicity/ARBI-frontend/commit/c30e4d7c))
|
|
76
|
+
- Fix workspace switch revert when triggered from home page ([370a46a5](https://github.com/arbicity/ARBI-frontend/commit/370a46a5))
|
|
77
|
+
- Sanitize folder paths for backend API ([70dc0f4a](https://github.com/arbicity/ARBI-frontend/commit/70dc0f4a))
|
|
78
|
+
- Remove selectedThreadId, unify into parentMessageId ([c20f0785](https://github.com/arbicity/ARBI-frontend/commit/c20f0785))
|
|
79
|
+
- Extract metadata from response.completed SSE event ([e8bff08d](https://github.com/arbicity/ARBI-frontend/commit/e8bff08d))
|
|
80
|
+
- Extract conversation documents from last user message instead of leaf ([b3d2718e](https://github.com/arbicity/ARBI-frontend/commit/b3d2718e))
|
|
81
|
+
- CLI integration test failures ([b092962e](https://github.com/arbicity/ARBI-frontend/commit/b092962e))
|
|
82
|
+
- Handle protected branches in publish script ([7746517e](https://github.com/arbicity/ARBI-frontend/commit/7746517e))
|
|
6
83
|
|
|
7
84
|
### 🏡 Chore
|
|
8
85
|
|
|
9
|
-
-
|
|
86
|
+
- Update schema: add scores to CitationData, chunker tokenizer config ([7fc18309](https://github.com/arbicity/ARBI-frontend/commit/7fc18309))
|
|
87
|
+
- Schema updates ([ab08dc54](https://github.com/arbicity/ARBI-frontend/commit/ab08dc54), [76046067](https://github.com/arbicity/ARBI-frontend/commit/76046067))
|
|
88
|
+
- Remove MemoryLLM from schema ([6806daea](https://github.com/arbicity/ARBI-frontend/commit/6806daea))
|
|
89
|
+
- CI: move integration tests off PR triggers, gate deploy behind them ([ff23f07a](https://github.com/arbicity/ARBI-frontend/commit/ff23f07a))
|
|
90
|
+
- Move PA mode toggle behind experimental feature flag ([2f00bce8](https://github.com/arbicity/ARBI-frontend/commit/2f00bce8))
|
|
91
|
+
- Replace MCP references with TUI in SDK comments ([42683222](https://github.com/arbicity/ARBI-frontend/commit/42683222))
|
|
10
92
|
|
|
11
93
|
## v0.3.10
|
|
12
94
|
|
package/dist/index.js
CHANGED
|
@@ -125,7 +125,9 @@ function registerConfigCommand(program2) {
|
|
|
125
125
|
label("Server URL:", cfg.baseUrl);
|
|
126
126
|
label("Domain:", cfg.deploymentDomain);
|
|
127
127
|
label("Auto-update:", cfg.autoUpdate ? "on" : "off");
|
|
128
|
-
label("
|
|
128
|
+
label("Verbose:", cfg.verbose !== false ? "on" : "off");
|
|
129
|
+
label("Watch:", cfg.watch !== false ? "on" : "off");
|
|
130
|
+
label("Notifications:", cfg.notifications !== false ? "on" : "off");
|
|
129
131
|
if (cfg.selectedWorkspaceId) {
|
|
130
132
|
label("Workspace:", cfg.selectedWorkspaceId);
|
|
131
133
|
}
|
|
@@ -133,7 +135,7 @@ function registerConfigCommand(program2) {
|
|
|
133
135
|
config.command("notifications [on|off]").description("Toggle background WebSocket notifications").action((toggle) => {
|
|
134
136
|
const cfg = getConfig();
|
|
135
137
|
if (!toggle) {
|
|
136
|
-
label("Notifications:", cfg?.notifications ? "on" : "off");
|
|
138
|
+
label("Notifications:", cfg?.notifications !== false ? "on" : "off");
|
|
137
139
|
return;
|
|
138
140
|
}
|
|
139
141
|
if (toggle !== "on" && toggle !== "off") {
|
|
@@ -143,6 +145,32 @@ function registerConfigCommand(program2) {
|
|
|
143
145
|
updateConfig({ notifications: toggle === "on" });
|
|
144
146
|
success(`Notifications: ${toggle}`);
|
|
145
147
|
});
|
|
148
|
+
config.command("verbose [on|off]").description("Toggle verbose agent steps in ask (default: on)").action((toggle) => {
|
|
149
|
+
const cfg = getConfig();
|
|
150
|
+
if (!toggle) {
|
|
151
|
+
label("Verbose:", cfg?.verbose !== false ? "on" : "off");
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (toggle !== "on" && toggle !== "off") {
|
|
155
|
+
error("Usage: arbi config verbose [on|off]");
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
updateConfig({ verbose: toggle === "on" });
|
|
159
|
+
success(`Verbose: ${toggle}`);
|
|
160
|
+
});
|
|
161
|
+
config.command("watch [on|off]").description("Toggle upload watch (default: on)").action((toggle) => {
|
|
162
|
+
const cfg = getConfig();
|
|
163
|
+
if (!toggle) {
|
|
164
|
+
label("Watch:", cfg?.watch !== false ? "on" : "off");
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
if (toggle !== "on" && toggle !== "off") {
|
|
168
|
+
error("Usage: arbi config watch [on|off]");
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
updateConfig({ watch: toggle === "on" });
|
|
172
|
+
success(`Watch: ${toggle}`);
|
|
173
|
+
});
|
|
146
174
|
config.command("alias").description('Set up shell alias A for "arbi ask"').action(() => {
|
|
147
175
|
const rcPath = getShellRcPath();
|
|
148
176
|
if (isAliasInstalled(rcPath)) {
|
|
@@ -3509,7 +3537,7 @@ function getLatestVersion(skipCache = false) {
|
|
|
3509
3537
|
}
|
|
3510
3538
|
}
|
|
3511
3539
|
function getCurrentVersion() {
|
|
3512
|
-
return "0.3.
|
|
3540
|
+
return "0.3.15";
|
|
3513
3541
|
}
|
|
3514
3542
|
function readChangelog(fromVersion, toVersion) {
|
|
3515
3543
|
try {
|
|
@@ -3562,17 +3590,17 @@ function showChangelog(fromVersion, toVersion) {
|
|
|
3562
3590
|
async function checkForUpdates(autoUpdate) {
|
|
3563
3591
|
try {
|
|
3564
3592
|
const latest = getLatestVersion();
|
|
3565
|
-
if (!latest || latest === "0.3.
|
|
3593
|
+
if (!latest || latest === "0.3.15") return;
|
|
3566
3594
|
if (autoUpdate) {
|
|
3567
3595
|
warn(`
|
|
3568
|
-
Your arbi version is out of date (${"0.3.
|
|
3596
|
+
Your arbi version is out of date (${"0.3.15"} \u2192 ${latest}). Updating...`);
|
|
3569
3597
|
child_process.execSync("npm install -g @arbidocs/cli@latest", { stdio: "inherit" });
|
|
3570
|
-
showChangelog("0.3.
|
|
3598
|
+
showChangelog("0.3.15", latest);
|
|
3571
3599
|
console.log(`Updated to ${latest}.`);
|
|
3572
3600
|
} else {
|
|
3573
3601
|
warn(
|
|
3574
3602
|
`
|
|
3575
|
-
Your arbi version is out of date (${"0.3.
|
|
3603
|
+
Your arbi version is out of date (${"0.3.15"} \u2192 ${latest}).
|
|
3576
3604
|
Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
3577
3605
|
);
|
|
3578
3606
|
}
|
|
@@ -3582,9 +3610,9 @@ Run "arbi update" to upgrade, or "arbi update auto" to always stay up to date.`
|
|
|
3582
3610
|
function hintUpdateOnError() {
|
|
3583
3611
|
try {
|
|
3584
3612
|
const cached = readCache();
|
|
3585
|
-
if (cached && cached.latest !== "0.3.
|
|
3613
|
+
if (cached && cached.latest !== "0.3.15") {
|
|
3586
3614
|
warn(
|
|
3587
|
-
`Your arbi version is out of date (${"0.3.
|
|
3615
|
+
`Your arbi version is out of date (${"0.3.15"} \u2192 ${cached.latest}). Run "arbi update".`
|
|
3588
3616
|
);
|
|
3589
3617
|
}
|
|
3590
3618
|
} catch {
|
|
@@ -3852,6 +3880,54 @@ function registerStatusCommand(program2) {
|
|
|
3852
3880
|
}
|
|
3853
3881
|
});
|
|
3854
3882
|
}
|
|
3883
|
+
var MAX_TASKS = 50;
|
|
3884
|
+
var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
3885
|
+
function getTasksFile() {
|
|
3886
|
+
const configDir = process.env.ARBI_CONFIG_DIR ?? path__default.default.join(os__default.default.homedir(), ".arbi");
|
|
3887
|
+
return path__default.default.join(configDir, "tasks.json");
|
|
3888
|
+
}
|
|
3889
|
+
function ensureDir(filePath) {
|
|
3890
|
+
const dir = path__default.default.dirname(filePath);
|
|
3891
|
+
if (!fs__default.default.existsSync(dir)) {
|
|
3892
|
+
fs__default.default.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
3893
|
+
}
|
|
3894
|
+
}
|
|
3895
|
+
function readTasks() {
|
|
3896
|
+
try {
|
|
3897
|
+
const content = fs__default.default.readFileSync(getTasksFile(), "utf-8");
|
|
3898
|
+
return JSON.parse(content);
|
|
3899
|
+
} catch {
|
|
3900
|
+
return [];
|
|
3901
|
+
}
|
|
3902
|
+
}
|
|
3903
|
+
function writeTasks(tasks) {
|
|
3904
|
+
const filePath = getTasksFile();
|
|
3905
|
+
ensureDir(filePath);
|
|
3906
|
+
fs__default.default.writeFileSync(filePath, JSON.stringify(tasks, null, 2) + "\n", { mode: 384 });
|
|
3907
|
+
}
|
|
3908
|
+
function getTasks() {
|
|
3909
|
+
const now = Date.now();
|
|
3910
|
+
const tasks = readTasks().filter((t) => now - new Date(t.submittedAt).getTime() < MAX_AGE_MS);
|
|
3911
|
+
return tasks;
|
|
3912
|
+
}
|
|
3913
|
+
function addTask(task) {
|
|
3914
|
+
const tasks = [task, ...getTasks().filter((t) => t.id !== task.id)].slice(0, MAX_TASKS);
|
|
3915
|
+
writeTasks(tasks);
|
|
3916
|
+
}
|
|
3917
|
+
function updateTaskStatus(id, status2) {
|
|
3918
|
+
const tasks = readTasks();
|
|
3919
|
+
const task = tasks.find((t) => t.id === id);
|
|
3920
|
+
if (task) {
|
|
3921
|
+
task.status = status2;
|
|
3922
|
+
writeTasks(tasks);
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
function getLatestTask() {
|
|
3926
|
+
const tasks = getTasks();
|
|
3927
|
+
return tasks[0] ?? null;
|
|
3928
|
+
}
|
|
3929
|
+
|
|
3930
|
+
// src/notifications.ts
|
|
3855
3931
|
var activeConnection = null;
|
|
3856
3932
|
function timestamp() {
|
|
3857
3933
|
return (/* @__PURE__ */ new Date()).toLocaleTimeString("en-GB", { hour12: false });
|
|
@@ -3869,6 +3945,9 @@ async function startBackgroundNotifications(baseUrl, accessToken) {
|
|
|
3869
3945
|
baseUrl,
|
|
3870
3946
|
accessToken,
|
|
3871
3947
|
onMessage: (msg) => {
|
|
3948
|
+
if (client.isMessageType(msg, "response_complete")) {
|
|
3949
|
+
updateTaskStatus(msg.response_id, msg.status);
|
|
3950
|
+
}
|
|
3872
3951
|
const { text, level } = sdk.formatWsMessage(msg);
|
|
3873
3952
|
process.stderr.write(`
|
|
3874
3953
|
${colorize(level, `[${timestamp()}] ${text}`)}
|
|
@@ -3973,7 +4052,7 @@ async function resolveWorkspace(workspaceOpt) {
|
|
|
3973
4052
|
try {
|
|
3974
4053
|
resolveConfig();
|
|
3975
4054
|
const ctx = await sdk.resolveWorkspace(store, workspaceOpt);
|
|
3976
|
-
if (getConfig()?.notifications) {
|
|
4055
|
+
if (getConfig()?.notifications !== false) {
|
|
3977
4056
|
startBackgroundNotifications(ctx.config.baseUrl, ctx.accessToken).catch(() => {
|
|
3978
4057
|
});
|
|
3979
4058
|
}
|
|
@@ -4367,7 +4446,7 @@ function registerDocsCommand(program2) {
|
|
|
4367
4446
|
);
|
|
4368
4447
|
}
|
|
4369
4448
|
function registerUploadCommand(program2) {
|
|
4370
|
-
program2.command("
|
|
4449
|
+
program2.command("add <paths...>").alias("upload").description("Add files, directories, or zip archives to the active workspace").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").option("-W, --watch", "Watch document processing progress after upload").option("--no-watch", "Skip watching document processing").action(
|
|
4371
4450
|
(paths, opts) => runAction(async () => {
|
|
4372
4451
|
for (const p of paths) {
|
|
4373
4452
|
if (!fs__default.default.existsSync(p)) {
|
|
@@ -4426,7 +4505,8 @@ function registerUploadCommand(program2) {
|
|
|
4426
4505
|
}
|
|
4427
4506
|
}
|
|
4428
4507
|
const isInteractive = process.stdout.isTTY === true;
|
|
4429
|
-
const
|
|
4508
|
+
const watchPref = getConfig()?.watch !== false;
|
|
4509
|
+
const shouldWatch = opts.watch === false ? false : opts.watch === true || watchPref && isInteractive;
|
|
4430
4510
|
if (shouldWatch && uploadedDocs.size > 0) {
|
|
4431
4511
|
const pending = new Set(uploadedDocs.keys());
|
|
4432
4512
|
const failed = /* @__PURE__ */ new Map();
|
|
@@ -4524,22 +4604,55 @@ function registerDownloadCommand(program2) {
|
|
|
4524
4604
|
);
|
|
4525
4605
|
}
|
|
4526
4606
|
function registerAskCommand(program2) {
|
|
4527
|
-
program2.command("ask <question...>").description("Ask the RAG assistant a question (no quotes needed)").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").option("-c, --config <id>", "Config ext_id to use (e.g. cfg-xxx)").option("-n, --new", "Start a new conversation (ignore previous context)").option("-
|
|
4607
|
+
program2.command("ask <question...>").description("Ask the RAG assistant a question (no quotes needed)").option("-w, --workspace <id>", "Workspace ID (defaults to selected workspace)").option("-c, --continue <msg-id>", "Continue from a specific message ID").option("--config <id>", "Config ext_id to use (e.g. cfg-xxx)").option("-n, --new", "Start a new conversation (ignore previous context)").option("-b, --background", "Submit as background task (fire and forget)").option("-q, --quiet", "Suppress agent steps and tool calls").option("--json", "Output in JSON format (background mode only)").action(
|
|
4528
4608
|
(words, opts) => runAction(async () => {
|
|
4529
4609
|
const question = words.join(" ");
|
|
4530
4610
|
const { arbi, accessToken, workspaceKeyHeader, workspaceId, config } = await resolveWorkspace(opts.workspace);
|
|
4531
|
-
const session = getChatSession();
|
|
4532
|
-
const workspaceChanged = session.lastMessageExtId && session.workspaceId && session.workspaceId !== workspaceId;
|
|
4533
4611
|
let previousResponseId = null;
|
|
4534
|
-
if (opts.
|
|
4535
|
-
|
|
4536
|
-
} else if (
|
|
4612
|
+
if (opts.continue) {
|
|
4613
|
+
previousResponseId = opts.continue;
|
|
4614
|
+
} else if (opts.new) {
|
|
4537
4615
|
clearChatSession();
|
|
4538
|
-
} else
|
|
4539
|
-
|
|
4616
|
+
} else {
|
|
4617
|
+
const session = getChatSession();
|
|
4618
|
+
const workspaceChanged = session.lastMessageExtId && session.workspaceId && session.workspaceId !== workspaceId;
|
|
4619
|
+
if (workspaceChanged) {
|
|
4620
|
+
clearChatSession();
|
|
4621
|
+
} else if (session.lastMessageExtId) {
|
|
4622
|
+
previousResponseId = session.lastMessageExtId;
|
|
4623
|
+
}
|
|
4540
4624
|
}
|
|
4541
4625
|
const docs = await sdk.documents.listDocuments(arbi);
|
|
4542
4626
|
const docIds = docs.map((d) => d.external_id);
|
|
4627
|
+
if (opts.background) {
|
|
4628
|
+
const result2 = await sdk.responses.submitBackgroundQuery({
|
|
4629
|
+
baseUrl: config.baseUrl,
|
|
4630
|
+
accessToken,
|
|
4631
|
+
workspaceKeyHeader,
|
|
4632
|
+
workspaceId,
|
|
4633
|
+
question,
|
|
4634
|
+
docIds,
|
|
4635
|
+
previousResponseId: null,
|
|
4636
|
+
model: opts.config
|
|
4637
|
+
});
|
|
4638
|
+
addTask({
|
|
4639
|
+
id: result2.id,
|
|
4640
|
+
question: question.slice(0, 200),
|
|
4641
|
+
workspaceId,
|
|
4642
|
+
submittedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4643
|
+
status: "queued",
|
|
4644
|
+
model: result2.model
|
|
4645
|
+
});
|
|
4646
|
+
if (opts.json) {
|
|
4647
|
+
console.log(JSON.stringify({ id: result2.id, status: result2.status }));
|
|
4648
|
+
} else {
|
|
4649
|
+
console.log(`Task queued: ${chalk2__default.default.cyan(result2.id)}`);
|
|
4650
|
+
console.log(
|
|
4651
|
+
chalk2__default.default.dim("Use `arbi task status` or `arbi task result` to check progress.")
|
|
4652
|
+
);
|
|
4653
|
+
}
|
|
4654
|
+
return;
|
|
4655
|
+
}
|
|
4543
4656
|
let res;
|
|
4544
4657
|
try {
|
|
4545
4658
|
res = await sdk.assistant.queryAssistant({
|
|
@@ -4567,19 +4680,47 @@ function registerAskCommand(program2) {
|
|
|
4567
4680
|
model: opts.config
|
|
4568
4681
|
});
|
|
4569
4682
|
}
|
|
4683
|
+
const verbose = opts.quiet === true ? false : getConfig()?.verbose !== false;
|
|
4684
|
+
let elapsedTime = null;
|
|
4570
4685
|
const result = await sdk.streamSSE(res, {
|
|
4571
4686
|
onToken: (content) => process.stdout.write(content),
|
|
4572
4687
|
onAgentStep: (data) => {
|
|
4573
|
-
if (
|
|
4688
|
+
if (verbose) {
|
|
4574
4689
|
const label2 = sdk.formatAgentStepLabel(data);
|
|
4575
4690
|
if (label2) console.error(chalk2__default.default.dim(`
|
|
4576
4691
|
[agent] ${label2}`));
|
|
4577
4692
|
}
|
|
4578
4693
|
},
|
|
4694
|
+
onElapsedTime: (t) => {
|
|
4695
|
+
elapsedTime = t;
|
|
4696
|
+
},
|
|
4579
4697
|
onError: (message) => console.error(chalk2__default.default.red(`
|
|
4580
4698
|
Error: ${message}`))
|
|
4581
4699
|
});
|
|
4582
4700
|
process.stdout.write("\n");
|
|
4701
|
+
const parts = [];
|
|
4702
|
+
if (result.agentSteps.length > 0) {
|
|
4703
|
+
let stepLabel = `${result.agentSteps.length} step${result.agentSteps.length === 1 ? "" : "s"}`;
|
|
4704
|
+
if (result.toolCallCount > 0) {
|
|
4705
|
+
stepLabel += ` (${result.toolCallCount} tool call${result.toolCallCount === 1 ? "" : "s"})`;
|
|
4706
|
+
}
|
|
4707
|
+
parts.push(stepLabel);
|
|
4708
|
+
}
|
|
4709
|
+
if (result.usage) {
|
|
4710
|
+
parts.push(`${result.usage.total_tokens.toLocaleString()} tokens`);
|
|
4711
|
+
}
|
|
4712
|
+
if (result.context && result.context.context_window > 0) {
|
|
4713
|
+
const used = result.context.all_llm_calls?.last_input_tokens ?? result.context.total_input;
|
|
4714
|
+
parts.push(
|
|
4715
|
+
`${used.toLocaleString()}/${result.context.context_window.toLocaleString()} context`
|
|
4716
|
+
);
|
|
4717
|
+
}
|
|
4718
|
+
if (elapsedTime != null) {
|
|
4719
|
+
parts.push(`${elapsedTime.toFixed(1)}s`);
|
|
4720
|
+
}
|
|
4721
|
+
if (parts.length > 0) {
|
|
4722
|
+
console.error(chalk2__default.default.dim(`[${parts.join(" \xB7 ")}]`));
|
|
4723
|
+
}
|
|
4583
4724
|
if (result.assistantMessageExtId) {
|
|
4584
4725
|
const updates = {
|
|
4585
4726
|
lastMessageExtId: result.assistantMessageExtId,
|
|
@@ -4594,6 +4735,109 @@ Error: ${message}`))
|
|
|
4594
4735
|
})()
|
|
4595
4736
|
);
|
|
4596
4737
|
}
|
|
4738
|
+
function chunkScore(chunk) {
|
|
4739
|
+
return chunk.metadata.rerank_score ?? chunk.metadata.score ?? 0;
|
|
4740
|
+
}
|
|
4741
|
+
function truncate(text, max) {
|
|
4742
|
+
const oneLine = text.replace(/\n/g, " ").trim();
|
|
4743
|
+
return oneLine.length > max ? oneLine.slice(0, max - 1) + "\u2026" : oneLine;
|
|
4744
|
+
}
|
|
4745
|
+
function fmtScore(score) {
|
|
4746
|
+
const pct = Math.min(Math.round(score * 100), 100);
|
|
4747
|
+
return `[${pct}%]`;
|
|
4748
|
+
}
|
|
4749
|
+
function registerFindCommand(program2) {
|
|
4750
|
+
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("-d, --docs <ids>", "Comma-separated document IDs to search within").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(
|
|
4751
|
+
(words, opts) => runAction(async () => {
|
|
4752
|
+
const query = words.join(" ");
|
|
4753
|
+
const { arbi, workspaceId } = await resolveWorkspace(opts.workspace);
|
|
4754
|
+
let docIds;
|
|
4755
|
+
if (opts.docs) {
|
|
4756
|
+
docIds = opts.docs.split(",").map((id) => id.trim());
|
|
4757
|
+
} else {
|
|
4758
|
+
const docs = await sdk.documents.listDocuments(arbi);
|
|
4759
|
+
docIds = docs.map((d) => d.external_id);
|
|
4760
|
+
}
|
|
4761
|
+
if (docIds.length === 0) {
|
|
4762
|
+
console.log("No documents found in workspace.");
|
|
4763
|
+
return;
|
|
4764
|
+
}
|
|
4765
|
+
const searchMode = opts.mode ?? "semantic";
|
|
4766
|
+
const tocDocIds = opts.toc ? opts.toc.split(",").map((id) => id.trim()) : void 0;
|
|
4767
|
+
const fullContextDocIds = opts.fullContext ? opts.fullContext.split(",").map((id) => id.trim()) : void 0;
|
|
4768
|
+
const result = await sdk.assistant.retrieve({
|
|
4769
|
+
arbi,
|
|
4770
|
+
workspaceId,
|
|
4771
|
+
query,
|
|
4772
|
+
docIds,
|
|
4773
|
+
searchMode,
|
|
4774
|
+
tocDocIds,
|
|
4775
|
+
fullContextDocIds
|
|
4776
|
+
});
|
|
4777
|
+
const allChunks = [];
|
|
4778
|
+
if (result.retrieval_chunk?.tool_responses) {
|
|
4779
|
+
for (const chunks of Object.values(result.retrieval_chunk.tool_responses)) {
|
|
4780
|
+
allChunks.push(...chunks);
|
|
4781
|
+
}
|
|
4782
|
+
}
|
|
4783
|
+
const minScore = parseFloat(opts.minScore ?? "0.2");
|
|
4784
|
+
const limit = parseInt(opts.limit ?? "20", 10);
|
|
4785
|
+
const filtered = allChunks.filter((c) => chunkScore(c) >= minScore).sort((a, b) => chunkScore(b) - chunkScore(a)).slice(0, limit);
|
|
4786
|
+
const uniqueDocs = new Set(filtered.map((c) => c.metadata.doc_ext_id));
|
|
4787
|
+
if (opts.json) {
|
|
4788
|
+
console.log(JSON.stringify(result, null, 2));
|
|
4789
|
+
return;
|
|
4790
|
+
}
|
|
4791
|
+
if (filtered.length === 0) {
|
|
4792
|
+
console.log("No results found.");
|
|
4793
|
+
return;
|
|
4794
|
+
}
|
|
4795
|
+
console.log(
|
|
4796
|
+
`
|
|
4797
|
+
Found ${chalk2__default.default.bold(String(filtered.length))} result${filtered.length === 1 ? "" : "s"} across ${chalk2__default.default.bold(String(uniqueDocs.size))} document${uniqueDocs.size === 1 ? "" : "s"}
|
|
4798
|
+
`
|
|
4799
|
+
);
|
|
4800
|
+
if (opts.flat) {
|
|
4801
|
+
for (let i = 0; i < filtered.length; i++) {
|
|
4802
|
+
const chunk = filtered[i];
|
|
4803
|
+
const score = fmtScore(chunkScore(chunk));
|
|
4804
|
+
const doc = chunk.metadata.doc_title ?? chunk.metadata.doc_ext_id ?? "";
|
|
4805
|
+
const page = chunk.metadata.page_number ? `p.${chunk.metadata.page_number}` : "";
|
|
4806
|
+
const preview = truncate(chunk.content, 80);
|
|
4807
|
+
console.log(
|
|
4808
|
+
` ${chalk2__default.default.dim(String(i + 1).padStart(2, " "))}. ${chalk2__default.default.yellow(score)} ${chalk2__default.default.cyan(doc)} ${chalk2__default.default.dim(page)}`
|
|
4809
|
+
);
|
|
4810
|
+
console.log(` ${chalk2__default.default.dim(preview)}`);
|
|
4811
|
+
}
|
|
4812
|
+
console.log();
|
|
4813
|
+
return;
|
|
4814
|
+
}
|
|
4815
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
4816
|
+
for (const chunk of filtered) {
|
|
4817
|
+
const key = chunk.metadata.doc_ext_id ?? "unknown";
|
|
4818
|
+
if (!grouped.has(key)) grouped.set(key, []);
|
|
4819
|
+
grouped.get(key).push(chunk);
|
|
4820
|
+
}
|
|
4821
|
+
for (const [, chunks] of grouped) {
|
|
4822
|
+
const docTitle = chunks[0].metadata.doc_title ?? chunks[0].metadata.doc_ext_id ?? "Unknown";
|
|
4823
|
+
const hitCount = chunks.length;
|
|
4824
|
+
const header = `${docTitle} (${hitCount} hit${hitCount === 1 ? "" : "s"})`;
|
|
4825
|
+
console.log(
|
|
4826
|
+
`${chalk2__default.default.dim("\u2500\u2500")} ${chalk2__default.default.bold(header)} ${chalk2__default.default.dim("\u2500".repeat(Math.max(0, 50 - header.length)))}`
|
|
4827
|
+
);
|
|
4828
|
+
for (const chunk of chunks) {
|
|
4829
|
+
const score = fmtScore(chunkScore(chunk));
|
|
4830
|
+
const page = chunk.metadata.page_number ? `p.${chunk.metadata.page_number}` : "";
|
|
4831
|
+
const preview = truncate(chunk.content, 72);
|
|
4832
|
+
console.log(
|
|
4833
|
+
` ${chalk2__default.default.yellow(score)} ${chalk2__default.default.dim(page.padEnd(6))} ${chalk2__default.default.dim(preview)}`
|
|
4834
|
+
);
|
|
4835
|
+
}
|
|
4836
|
+
console.log();
|
|
4837
|
+
}
|
|
4838
|
+
})()
|
|
4839
|
+
);
|
|
4840
|
+
}
|
|
4597
4841
|
function colorize2(level, text) {
|
|
4598
4842
|
if (level === "success") return chalk2__default.default.green(text);
|
|
4599
4843
|
if (level === "error") return chalk2__default.default.red(text);
|
|
@@ -5711,6 +5955,103 @@ function registerAgentCreateCommand(program2) {
|
|
|
5711
5955
|
}
|
|
5712
5956
|
);
|
|
5713
5957
|
}
|
|
5958
|
+
function formatAge(isoDate) {
|
|
5959
|
+
const ms = Date.now() - new Date(isoDate).getTime();
|
|
5960
|
+
if (ms < 6e4) return `${Math.round(ms / 1e3)}s`;
|
|
5961
|
+
if (ms < 36e5) return `${Math.round(ms / 6e4)}m`;
|
|
5962
|
+
if (ms < 864e5) return `${Math.round(ms / 36e5)}h`;
|
|
5963
|
+
return `${Math.round(ms / 864e5)}d`;
|
|
5964
|
+
}
|
|
5965
|
+
function resolveTaskId(taskIdArg) {
|
|
5966
|
+
if (taskIdArg) return taskIdArg;
|
|
5967
|
+
const latest = getLatestTask();
|
|
5968
|
+
if (!latest) {
|
|
5969
|
+
console.error(chalk2__default.default.red('No tasks found. Submit one with: arbi ask -b "your question"'));
|
|
5970
|
+
process.exit(1);
|
|
5971
|
+
}
|
|
5972
|
+
return latest.id;
|
|
5973
|
+
}
|
|
5974
|
+
function statusColor(s) {
|
|
5975
|
+
if (s === "completed") return chalk2__default.default.green(s);
|
|
5976
|
+
if (s === "failed") return chalk2__default.default.red(s);
|
|
5977
|
+
if (s === "queued" || s === "in_progress") return chalk2__default.default.yellow(s);
|
|
5978
|
+
return s;
|
|
5979
|
+
}
|
|
5980
|
+
function registerTaskCommand(program2) {
|
|
5981
|
+
const task = program2.command("task").description("Manage background tasks");
|
|
5982
|
+
task.action(async (_opts, cmd) => {
|
|
5983
|
+
await cmd.commands.find((c) => c.name() === "list").parseAsync([], { from: "user" });
|
|
5984
|
+
});
|
|
5985
|
+
task.command("list").description("List background tasks").action(
|
|
5986
|
+
() => runAction(async () => {
|
|
5987
|
+
const tasks = getTasks();
|
|
5988
|
+
if (tasks.length === 0) {
|
|
5989
|
+
console.log('No tasks. Submit one with: arbi ask -b "your question"');
|
|
5990
|
+
return;
|
|
5991
|
+
}
|
|
5992
|
+
printTable(
|
|
5993
|
+
[
|
|
5994
|
+
{ header: "ID", width: 20, value: (r) => r.id },
|
|
5995
|
+
{ header: "STATUS", width: 14, value: (r) => statusColor(r.status) },
|
|
5996
|
+
{ header: "QUESTION", width: 42, value: (r) => r.question },
|
|
5997
|
+
{ header: "AGE", width: 6, value: (r) => formatAge(r.submittedAt) }
|
|
5998
|
+
],
|
|
5999
|
+
tasks
|
|
6000
|
+
);
|
|
6001
|
+
})()
|
|
6002
|
+
);
|
|
6003
|
+
task.command("status [task-id]").description("Check current task status (defaults to most recent)").option("-w, --workspace <id>", "Workspace ID").option("--json", "Output in JSON format").action(
|
|
6004
|
+
(taskId, opts) => runAction(async () => {
|
|
6005
|
+
const id = resolveTaskId(taskId);
|
|
6006
|
+
const { accessToken, workspaceKeyHeader, config } = await resolveWorkspace(opts?.workspace);
|
|
6007
|
+
const result = await sdk.responses.getResponse(
|
|
6008
|
+
{ baseUrl: config.baseUrl, accessToken, workspaceKeyHeader },
|
|
6009
|
+
id
|
|
6010
|
+
);
|
|
6011
|
+
if (result.status === "completed" || result.status === "failed") {
|
|
6012
|
+
updateTaskStatus(id, result.status);
|
|
6013
|
+
}
|
|
6014
|
+
if (opts?.json) {
|
|
6015
|
+
console.log(JSON.stringify(result, null, 2));
|
|
6016
|
+
} else {
|
|
6017
|
+
console.log(`${chalk2__default.default.bold("ID:")} ${result.id}`);
|
|
6018
|
+
console.log(`${chalk2__default.default.bold("Status:")} ${statusColor(result.status)}`);
|
|
6019
|
+
if (result.model) console.log(`${chalk2__default.default.bold("Model:")} ${result.model}`);
|
|
6020
|
+
if (result.usage) {
|
|
6021
|
+
console.log(`${chalk2__default.default.bold("Tokens:")} ${result.usage.total_tokens.toLocaleString()}`);
|
|
6022
|
+
}
|
|
6023
|
+
}
|
|
6024
|
+
})()
|
|
6025
|
+
);
|
|
6026
|
+
task.command("result [task-id]").description("Fetch and print the completed task result").option("-w, --workspace <id>", "Workspace ID").option("--json", "Output in JSON format").action(
|
|
6027
|
+
(taskId, opts) => runAction(async () => {
|
|
6028
|
+
const id = resolveTaskId(taskId);
|
|
6029
|
+
const { accessToken, workspaceKeyHeader, config } = await resolveWorkspace(opts?.workspace);
|
|
6030
|
+
const result = await sdk.responses.getResponse(
|
|
6031
|
+
{ baseUrl: config.baseUrl, accessToken, workspaceKeyHeader },
|
|
6032
|
+
id
|
|
6033
|
+
);
|
|
6034
|
+
if (result.status === "completed" || result.status === "failed") {
|
|
6035
|
+
updateTaskStatus(id, result.status);
|
|
6036
|
+
}
|
|
6037
|
+
if (opts?.json) {
|
|
6038
|
+
console.log(JSON.stringify(result, null, 2));
|
|
6039
|
+
return;
|
|
6040
|
+
}
|
|
6041
|
+
if (result.status !== "completed") {
|
|
6042
|
+
console.error(
|
|
6043
|
+
chalk2__default.default.yellow(`Task is ${result.status}. Use \`arbi task status\` to check progress.`)
|
|
6044
|
+
);
|
|
6045
|
+
process.exit(1);
|
|
6046
|
+
}
|
|
6047
|
+
const text = sdk.responses.extractResponseText(result);
|
|
6048
|
+
process.stdout.write(text + "\n");
|
|
6049
|
+
if (result.usage) {
|
|
6050
|
+
console.error(chalk2__default.default.dim(`[${result.usage.total_tokens.toLocaleString()} tokens]`));
|
|
6051
|
+
}
|
|
6052
|
+
})()
|
|
6053
|
+
);
|
|
6054
|
+
}
|
|
5714
6055
|
|
|
5715
6056
|
// src/index.ts
|
|
5716
6057
|
console.debug = () => {
|
|
@@ -5721,7 +6062,7 @@ console.info = (...args) => {
|
|
|
5721
6062
|
_origInfo(...args);
|
|
5722
6063
|
};
|
|
5723
6064
|
var program = new commander.Command();
|
|
5724
|
-
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.
|
|
6065
|
+
program.name("arbi").description("ARBI CLI \u2014 interact with ARBI from the terminal").version("0.3.15");
|
|
5725
6066
|
registerConfigCommand(program);
|
|
5726
6067
|
registerLoginCommand(program);
|
|
5727
6068
|
registerRegisterCommand(program);
|
|
@@ -5732,6 +6073,7 @@ registerDocsCommand(program);
|
|
|
5732
6073
|
registerUploadCommand(program);
|
|
5733
6074
|
registerDownloadCommand(program);
|
|
5734
6075
|
registerAskCommand(program);
|
|
6076
|
+
registerFindCommand(program);
|
|
5735
6077
|
registerWatchCommand(program);
|
|
5736
6078
|
registerContactsCommand(program);
|
|
5737
6079
|
registerDmCommand(program);
|
|
@@ -5745,6 +6087,7 @@ registerTuiCommand(program);
|
|
|
5745
6087
|
registerUpdateCommand(program);
|
|
5746
6088
|
registerQuickstartCommand(program);
|
|
5747
6089
|
registerAgentCreateCommand(program);
|
|
6090
|
+
registerTaskCommand(program);
|
|
5748
6091
|
program.parse();
|
|
5749
6092
|
//# sourceMappingURL=index.js.map
|
|
5750
6093
|
//# sourceMappingURL=index.js.map
|