promptimizer-cli 0.1.23 → 0.1.25
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/README.md +21 -11
- package/bin/promptimizer.mjs +194 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
# promptimizer-cli
|
|
2
2
|
|
|
3
|
-
Gemini-style interactive routing CLI for Promptimizer.
|
|
3
|
+
Gemini-style interactive routing CLI for Promptimizer. Multi-host fleets: add and remove providers; the router picks across the merged model set.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npm install -g
|
|
6
|
+
npm install -g ./packages/cli
|
|
7
|
+
# or after publish: npm install -g promptimizer-cli@latest
|
|
7
8
|
promptimizer
|
|
8
9
|
```
|
|
9
10
|
|
|
10
|
-
Requires **≥ 0.1.
|
|
11
|
+
Requires **≥ 0.1.23** for `/hosts`, `/connect`, `/disconnect`.
|
|
11
12
|
|
|
12
13
|
```text
|
|
13
|
-
Promptimizer v0.1.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
Promptimizer v0.1.23
|
|
15
|
+
● Baseten (16) · NVIDIA NIM (74) · 90 models
|
|
16
|
+
2 hosts merged · router picks across all
|
|
17
|
+
› /hosts
|
|
18
|
+
✓ Baseten 16 models
|
|
19
|
+
✓ NVIDIA NIM 74 models
|
|
19
20
|
```
|
|
20
21
|
|
|
21
22
|
## Commands
|
|
@@ -25,9 +26,18 @@ Requires **≥ 0.1.22** for REPL `/logout`. If `/help` does not list `/logout`,
|
|
|
25
26
|
| `promptimizer` | Interactive multi-turn session |
|
|
26
27
|
| `promptimizer login --key pmz_live_…` | Save API key |
|
|
27
28
|
| `promptimizer logout` / REPL `/logout` | Remove `~/.promptimizer/config.json` |
|
|
28
|
-
| `promptimizer connect baseten --key $BASETEN_API_KEY` |
|
|
29
|
+
| `promptimizer connect baseten --key $BASETEN_API_KEY` | **Add** a host (keeps existing) |
|
|
30
|
+
| `promptimizer connect nvidia --key $NVIDIA_API_KEY` | Add another host |
|
|
31
|
+
| `promptimizer disconnect nvidia` | **Remove** a host |
|
|
32
|
+
| `promptimizer hosts` | List connected hosts |
|
|
33
|
+
| `promptimizer models` | List merged fleet (tier · host · id) |
|
|
29
34
|
| `promptimizer chat "…"` | One-shot completion |
|
|
30
|
-
| `promptimizer models` | List fleet |
|
|
31
35
|
| `promptimizer savings` | Account ledger |
|
|
32
36
|
|
|
37
|
+
Aliases: `add` → connect, `remove` / `rm` → disconnect.
|
|
38
|
+
|
|
39
|
+
### REPL slash commands
|
|
40
|
+
|
|
41
|
+
`/hosts` · `/models` · `/connect <host> --key …` · `/disconnect <host>` · `/savings` · `/clear` · `/logout` · `/quit`
|
|
42
|
+
|
|
33
43
|
Defaults to the hosted gateway. Override with `--url` or `PROMPTIMIZER_URL`.
|
package/bin/promptimizer.mjs
CHANGED
|
@@ -30,9 +30,11 @@ const COMMANDS = [
|
|
|
30
30
|
["", "Start interactive session (Gemini-style REPL)"],
|
|
31
31
|
["login", "Save a Promptimizer API key"],
|
|
32
32
|
["logout", "Remove the saved key"],
|
|
33
|
-
["connect", "
|
|
33
|
+
["connect", "Add a model host (keeps existing hosts)"],
|
|
34
|
+
["disconnect", "Remove a model host from the fleet"],
|
|
35
|
+
["hosts", "List connected hosts"],
|
|
34
36
|
["chat", "Route one completion"],
|
|
35
|
-
["models", "List the
|
|
37
|
+
["models", "List the merged fleet"],
|
|
36
38
|
["savings", "Show account savings"],
|
|
37
39
|
["providers", "List known provider URLs"],
|
|
38
40
|
];
|
|
@@ -50,7 +52,20 @@ const COMMAND_HELP = {
|
|
|
50
52
|
" promptimizer connect <provider> --key <vendor-key>",
|
|
51
53
|
" promptimizer connect custom --base-url <url> --key <vendor-key>",
|
|
52
54
|
" promptimizer connect simulator",
|
|
55
|
+
"",
|
|
56
|
+
"Adds a host to your fleet without replacing others.",
|
|
57
|
+
"Aliases: add",
|
|
58
|
+
],
|
|
59
|
+
disconnect: [
|
|
60
|
+
"Usage",
|
|
61
|
+
" promptimizer disconnect <provider>",
|
|
62
|
+
" promptimizer disconnect baseten",
|
|
63
|
+
" promptimizer disconnect nvidia",
|
|
64
|
+
"",
|
|
65
|
+
"Removes that host and its models. Other hosts stay.",
|
|
66
|
+
"Aliases: remove, rm",
|
|
53
67
|
],
|
|
68
|
+
hosts: ["Usage", " promptimizer hosts", "", "Show connected hosts and model counts."],
|
|
54
69
|
chat: [
|
|
55
70
|
"Usage",
|
|
56
71
|
' promptimizer chat "What is 17 * 24?"',
|
|
@@ -103,6 +118,15 @@ function parse(argv) {
|
|
|
103
118
|
return { flags, positional };
|
|
104
119
|
}
|
|
105
120
|
|
|
121
|
+
/** Parse slash-command args inside the REPL: `/connect baseten --key sk-…` */
|
|
122
|
+
function parseLineArgs(line) {
|
|
123
|
+
const parts = [];
|
|
124
|
+
const re = /"([^"]*)"|'([^']*)'|(\S+)/g;
|
|
125
|
+
let m;
|
|
126
|
+
while ((m = re.exec(line))) parts.push(m[1] ?? m[2] ?? m[3]);
|
|
127
|
+
return parse(parts);
|
|
128
|
+
}
|
|
129
|
+
|
|
106
130
|
function readConfig() {
|
|
107
131
|
try {
|
|
108
132
|
return JSON.parse(readFileSync(CONFIG_PATH, "utf8"));
|
|
@@ -133,10 +157,24 @@ function printVersion() {
|
|
|
133
157
|
return pkg.version;
|
|
134
158
|
}
|
|
135
159
|
|
|
160
|
+
function hostSummary(session) {
|
|
161
|
+
const connections = session?.connections ?? [];
|
|
162
|
+
if (connections.length) {
|
|
163
|
+
return connections
|
|
164
|
+
.map((c) => {
|
|
165
|
+
const count = (session.models ?? []).filter((m) => m.provider_id === c.id).length;
|
|
166
|
+
return `${c.label}${count ? ` (${count})` : ""}`;
|
|
167
|
+
})
|
|
168
|
+
.join(" · ");
|
|
169
|
+
}
|
|
170
|
+
return session?.label || "not connected";
|
|
171
|
+
}
|
|
172
|
+
|
|
136
173
|
function banner(session, version) {
|
|
137
|
-
const
|
|
174
|
+
const hosts = hostSummary(session);
|
|
138
175
|
const models = session?.models?.length ?? 0;
|
|
139
176
|
const baseline = session?.baseline_model || "—";
|
|
177
|
+
const hostCount = session?.connections?.length ?? 0;
|
|
140
178
|
out();
|
|
141
179
|
out(color(ANSI.cyan, " ██████╗ ███╗ ███╗███████╗"));
|
|
142
180
|
out(color(ANSI.cyan, " ██╔══██╗████╗ ████║╚══███╔╝"));
|
|
@@ -148,14 +186,30 @@ function banner(session, version) {
|
|
|
148
186
|
out(` ${color(ANSI.bold, "Promptimizer")} ${color(ANSI.dim, `v${version}`)}`);
|
|
149
187
|
out(` ${color(ANSI.dim, "Quality-aware routing · OpenAI-compatible")}`);
|
|
150
188
|
out();
|
|
151
|
-
out(` ${color(ANSI.green, "●")} ${
|
|
189
|
+
out(` ${color(ANSI.green, "●")} ${hosts}${models ? ` · ${models} models` : ""}`);
|
|
190
|
+
if (hostCount > 1) out(` ${color(ANSI.dim, `${hostCount} hosts merged · router picks across all`)}`);
|
|
152
191
|
out(` ${color(ANSI.dim, `baseline ${baseline}`)}`);
|
|
153
192
|
out();
|
|
154
|
-
out(
|
|
193
|
+
out(
|
|
194
|
+
` ${color(ANSI.dim, "Type a prompt, or /help /hosts /models /connect /disconnect /clear /quit")}`,
|
|
195
|
+
);
|
|
155
196
|
out(` ${color(ANSI.dim, "Cache keys on full history — /clear then repeat a prompt to see cache hit")}`);
|
|
156
197
|
out();
|
|
157
198
|
}
|
|
158
199
|
|
|
200
|
+
function printFleetSummary(session, { added, removed } = {}) {
|
|
201
|
+
const connections = session.connections ?? [];
|
|
202
|
+
if (added) out(`${color(ANSI.green, "✓")} Added ${added}`);
|
|
203
|
+
if (removed) out(`${color(ANSI.green, "✓")} Removed ${removed}`);
|
|
204
|
+
if (!added && !removed) out(`${color(ANSI.green, "✓")} ${session.label}`);
|
|
205
|
+
if (connections.length) {
|
|
206
|
+
out(` hosts ${connections.map((c) => c.label).join(" · ")}`);
|
|
207
|
+
} else {
|
|
208
|
+
out(` ${session.label} ${session.base_url}`);
|
|
209
|
+
}
|
|
210
|
+
out(` models ${session.models?.length ?? 0} · baseline ${session.baseline_model ?? "—"}`);
|
|
211
|
+
}
|
|
212
|
+
|
|
159
213
|
function help() {
|
|
160
214
|
out("Usage: promptimizer [--url <gateway>] [command] [options]");
|
|
161
215
|
out();
|
|
@@ -178,8 +232,10 @@ function help() {
|
|
|
178
232
|
out(" promptimizer");
|
|
179
233
|
out(" promptimizer login --key pmz_live_…");
|
|
180
234
|
out(" promptimizer connect baseten --key $BASETEN_API_KEY");
|
|
235
|
+
out(" promptimizer connect nvidia --key $NVIDIA_API_KEY");
|
|
236
|
+
out(" promptimizer hosts");
|
|
237
|
+
out(" promptimizer disconnect nvidia");
|
|
181
238
|
out(' promptimizer chat "What is 17 * 24?"');
|
|
182
|
-
out(" promptimizer savings");
|
|
183
239
|
out();
|
|
184
240
|
}
|
|
185
241
|
|
|
@@ -243,6 +299,7 @@ function printMeta(result) {
|
|
|
243
299
|
const saved = result.usage?.cost?.saved_usd;
|
|
244
300
|
const bits = [meta.model || result.model, meta.tier].filter(Boolean);
|
|
245
301
|
if (meta.routing_policy) bits.push(String(meta.routing_policy));
|
|
302
|
+
if (meta.provider_id || meta.host) bits.push(String(meta.provider_id || meta.host));
|
|
246
303
|
if (saved != null) bits.push(`saved ${usd(saved)}`);
|
|
247
304
|
if (meta.exact_cache_hit) bits.push(color(ANSI.green, "cache hit"));
|
|
248
305
|
else if (meta.prefix_cache_hit) bits.push(color(ANSI.green, "prefix cache"));
|
|
@@ -303,11 +360,14 @@ async function cmdConnect(flags, positional) {
|
|
|
303
360
|
const provider = String(flags.provider || positional[0] || "").trim();
|
|
304
361
|
const baseURL = flags["base-url"] || flags.baseUrl;
|
|
305
362
|
if (!provider && !baseURL) {
|
|
306
|
-
die(
|
|
363
|
+
die(
|
|
364
|
+
"Usage: promptimizer connect <provider> --key <vendor-key>\n promptimizer connect custom --base-url https://… --key …",
|
|
365
|
+
);
|
|
307
366
|
}
|
|
308
367
|
|
|
309
368
|
const mock = provider === "simulator" || provider === "mock";
|
|
310
369
|
let vendorKey = flags.key || flags.k;
|
|
370
|
+
let label = flags.label;
|
|
311
371
|
if (!mock && !baseURL && provider && provider !== "custom") {
|
|
312
372
|
const catalog = await request("/v1/providers", { gatewayURL });
|
|
313
373
|
const found = (catalog.data ?? []).find(
|
|
@@ -318,6 +378,7 @@ async function cmdConnect(flags, positional) {
|
|
|
318
378
|
if (!vendorKey && found.id !== "ollama") {
|
|
319
379
|
die(`Missing API key for ${found.label}. Pass --key or set ${found.env}.`);
|
|
320
380
|
}
|
|
381
|
+
label = label || found.label;
|
|
321
382
|
} else if (!mock && !vendorKey && provider !== "ollama") {
|
|
322
383
|
die("Missing provider key. Pass --key.");
|
|
323
384
|
}
|
|
@@ -331,6 +392,7 @@ async function cmdConnect(flags, positional) {
|
|
|
331
392
|
? { mode: "mock", label: "Promptimizer simulator" }
|
|
332
393
|
: {
|
|
333
394
|
mode: "byok",
|
|
395
|
+
label,
|
|
334
396
|
provider: provider && provider !== "custom" ? provider : undefined,
|
|
335
397
|
base_url: baseURL,
|
|
336
398
|
api_key: vendorKey,
|
|
@@ -338,8 +400,57 @@ async function cmdConnect(flags, positional) {
|
|
|
338
400
|
});
|
|
339
401
|
|
|
340
402
|
writeConfig({ ...config, gatewayURL, apiKey, sessionId: session.session_id });
|
|
341
|
-
out(
|
|
342
|
-
|
|
403
|
+
out();
|
|
404
|
+
printFleetSummary(session, { added: label || provider || session.label });
|
|
405
|
+
out();
|
|
406
|
+
return session;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
async function cmdDisconnect(flags, positional) {
|
|
410
|
+
const config = readConfig();
|
|
411
|
+
const gatewayURL = gateway(flags, config);
|
|
412
|
+
const provider = String(flags.provider || flags.host || positional[0] || "").trim();
|
|
413
|
+
if (!provider) die("Usage: promptimizer disconnect <provider>\n promptimizer disconnect baseten");
|
|
414
|
+
|
|
415
|
+
const { apiKey, sessionId } = authFromConfig(flags, config);
|
|
416
|
+
const session = await request("/v1/providers/disconnect", {
|
|
417
|
+
method: "POST",
|
|
418
|
+
gatewayURL,
|
|
419
|
+
apiKey,
|
|
420
|
+
sessionId,
|
|
421
|
+
body: { provider },
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
writeConfig({ ...config, gatewayURL, apiKey, sessionId: session.session_id ?? sessionId });
|
|
425
|
+
out();
|
|
426
|
+
printFleetSummary(session, { removed: session.removed?.label || provider });
|
|
427
|
+
out();
|
|
428
|
+
return session;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
async function cmdHosts(flags) {
|
|
432
|
+
const config = readConfig();
|
|
433
|
+
const session = await loadSession(flags, config);
|
|
434
|
+
const connections = session.connections ?? [];
|
|
435
|
+
out();
|
|
436
|
+
if (!connections.length) {
|
|
437
|
+
out(` ${session.label} (simulator)`);
|
|
438
|
+
out(` ${session.models?.length ?? 0} models`);
|
|
439
|
+
out();
|
|
440
|
+
return session;
|
|
441
|
+
}
|
|
442
|
+
const width = Math.max(8, ...connections.map((c) => String(c.label).length));
|
|
443
|
+
for (const c of connections) {
|
|
444
|
+
const count = (session.models ?? []).filter((m) => m.provider_id === c.id).length;
|
|
445
|
+
out(` ${color(ANSI.green, "✓")} ${c.label.padEnd(width + 2)}${count} models`);
|
|
446
|
+
out(` ${color(ANSI.dim, c.base_url)}`);
|
|
447
|
+
}
|
|
448
|
+
out();
|
|
449
|
+
out(` ${session.models?.length ?? 0} models total · baseline ${session.baseline_model ?? "—"}`);
|
|
450
|
+
out(` ${color(ANSI.dim, "Add: promptimizer connect <host> --key …")}`);
|
|
451
|
+
out(` ${color(ANSI.dim, "Remove: promptimizer disconnect <host>")}`);
|
|
452
|
+
out();
|
|
453
|
+
return session;
|
|
343
454
|
}
|
|
344
455
|
|
|
345
456
|
async function cmdChat(flags, positional) {
|
|
@@ -359,15 +470,30 @@ async function cmdModels(flags) {
|
|
|
359
470
|
const config = readConfig();
|
|
360
471
|
const gatewayURL = gateway(flags, config);
|
|
361
472
|
const { apiKey, sessionId } = authFromConfig(flags, config);
|
|
362
|
-
const data = await
|
|
473
|
+
const [data, session] = await Promise.all([
|
|
474
|
+
request("/v1/models", { gatewayURL, apiKey, sessionId }),
|
|
475
|
+
request("/v1/session", { gatewayURL, apiKey, sessionId }).catch(() => null),
|
|
476
|
+
]);
|
|
363
477
|
const models = data.data ?? [];
|
|
364
|
-
const
|
|
478
|
+
const labelById = new Map((session?.connections ?? []).map((c) => [c.id, c.label]));
|
|
479
|
+
const hostWidth = Math.max(
|
|
480
|
+
4,
|
|
481
|
+
...models.map((m) => String(m.provider_label || labelById.get(m.provider_id) || m.provider_id || "—").length),
|
|
482
|
+
);
|
|
483
|
+
const tierWidth = Math.max(8, ...models.map((m) => String(m.tier).length));
|
|
365
484
|
out();
|
|
366
485
|
for (const model of models) {
|
|
486
|
+
const host = model.provider_label || labelById.get(model.provider_id) || model.provider_id || "—";
|
|
367
487
|
const mark = model.id === data.baseline_model ? color(ANSI.yellow, " baseline") : "";
|
|
368
|
-
out(
|
|
488
|
+
out(
|
|
489
|
+
` ${color(ANSI.dim, String(model.tier).padEnd(tierWidth + 2))}${color(ANSI.cyan, String(host).padEnd(hostWidth + 2))}${model.id}${mark}`,
|
|
490
|
+
);
|
|
369
491
|
}
|
|
370
492
|
out();
|
|
493
|
+
if (session?.connections?.length) {
|
|
494
|
+
out(color(ANSI.dim, ` ${session.connections.length} host(s) · ${models.length} models`));
|
|
495
|
+
out();
|
|
496
|
+
}
|
|
371
497
|
}
|
|
372
498
|
|
|
373
499
|
async function cmdSavings(flags) {
|
|
@@ -419,13 +545,16 @@ async function interactive(flags) {
|
|
|
419
545
|
|
|
420
546
|
const slashHelp = () => {
|
|
421
547
|
out();
|
|
422
|
-
out(` ${color(ANSI.bold, "/help")}
|
|
423
|
-
out(` ${color(ANSI.bold, "/
|
|
424
|
-
out(` ${color(ANSI.bold, "/
|
|
425
|
-
out(` ${color(ANSI.bold, "/
|
|
426
|
-
out(` ${color(ANSI.bold, "/
|
|
427
|
-
out(` ${color(ANSI.bold, "/
|
|
428
|
-
out(` ${color(ANSI.bold, "/
|
|
548
|
+
out(` ${color(ANSI.bold, "/help")} this list`);
|
|
549
|
+
out(` ${color(ANSI.bold, "/hosts")} connected hosts`);
|
|
550
|
+
out(` ${color(ANSI.bold, "/models")} fleet + host + tier`);
|
|
551
|
+
out(` ${color(ANSI.bold, "/connect <host> --key …")} add a host (keeps others)`);
|
|
552
|
+
out(` ${color(ANSI.bold, "/disconnect <host>")} remove a host`);
|
|
553
|
+
out(` ${color(ANSI.bold, "/savings")} account ledger`);
|
|
554
|
+
out(` ${color(ANSI.bold, "/session")} provider status`);
|
|
555
|
+
out(` ${color(ANSI.bold, "/clear")} clear chat history`);
|
|
556
|
+
out(` ${color(ANSI.bold, "/logout")} remove saved API key and exit`);
|
|
557
|
+
out(` ${color(ANSI.bold, "/quit")} exit`);
|
|
429
558
|
out();
|
|
430
559
|
};
|
|
431
560
|
|
|
@@ -463,8 +592,15 @@ async function interactive(flags) {
|
|
|
463
592
|
try {
|
|
464
593
|
session = await loadSession(flags, readConfig());
|
|
465
594
|
out();
|
|
466
|
-
out(` ${session
|
|
467
|
-
|
|
595
|
+
out(` ${hostSummary(session)} · ${session.mode}`);
|
|
596
|
+
if (session.connections?.length) {
|
|
597
|
+
for (const c of session.connections) {
|
|
598
|
+
const count = session.models.filter((m) => m.provider_id === c.id).length;
|
|
599
|
+
out(` ${color(ANSI.green, "✓")} ${c.label} · ${count} models`);
|
|
600
|
+
}
|
|
601
|
+
} else {
|
|
602
|
+
out(` ${session.base_url}`);
|
|
603
|
+
}
|
|
468
604
|
out(` ${session.models.length} models · baseline ${session.baseline_model}`);
|
|
469
605
|
out();
|
|
470
606
|
} catch (error) {
|
|
@@ -473,6 +609,15 @@ async function interactive(flags) {
|
|
|
473
609
|
continue;
|
|
474
610
|
}
|
|
475
611
|
|
|
612
|
+
if (trimmed === "/hosts" || trimmed === "/providers") {
|
|
613
|
+
try {
|
|
614
|
+
session = await cmdHosts(flags);
|
|
615
|
+
} catch (error) {
|
|
616
|
+
out(color(ANSI.yellow, ` ${error instanceof Error ? error.message : String(error)}`));
|
|
617
|
+
}
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
|
|
476
621
|
if (trimmed === "/models") {
|
|
477
622
|
try {
|
|
478
623
|
await cmdModels(flags);
|
|
@@ -491,6 +636,29 @@ async function interactive(flags) {
|
|
|
491
636
|
continue;
|
|
492
637
|
}
|
|
493
638
|
|
|
639
|
+
if (
|
|
640
|
+
trimmed.startsWith("/connect") ||
|
|
641
|
+
trimmed.startsWith("/add ") ||
|
|
642
|
+
trimmed === "/add" ||
|
|
643
|
+
trimmed.startsWith("/disconnect") ||
|
|
644
|
+
trimmed.startsWith("/remove") ||
|
|
645
|
+
trimmed.startsWith("/rm ")
|
|
646
|
+
) {
|
|
647
|
+
const body = trimmed.replace(/^\/(connect|add|disconnect|remove|rm)\s*/i, "");
|
|
648
|
+
const { flags: slashFlags, positional } = parseLineArgs(body);
|
|
649
|
+
const mergedFlags = { ...flags, ...slashFlags };
|
|
650
|
+
const isDisconnect = /^\/(disconnect|remove|rm)\b/i.test(trimmed);
|
|
651
|
+
try {
|
|
652
|
+
session = isDisconnect
|
|
653
|
+
? await cmdDisconnect(mergedFlags, positional)
|
|
654
|
+
: await cmdConnect(mergedFlags, positional);
|
|
655
|
+
} catch (error) {
|
|
656
|
+
out(color(ANSI.yellow, ` ${error instanceof Error ? error.message : String(error)}`));
|
|
657
|
+
out();
|
|
658
|
+
}
|
|
659
|
+
continue;
|
|
660
|
+
}
|
|
661
|
+
|
|
494
662
|
if (trimmed.startsWith("/")) {
|
|
495
663
|
out(color(ANSI.dim, " Unknown command. Try /help"));
|
|
496
664
|
continue;
|
|
@@ -550,7 +718,11 @@ async function main() {
|
|
|
550
718
|
if (command === "login") return await cmdLogin(flags);
|
|
551
719
|
if (command === "logout") return cmdLogout();
|
|
552
720
|
if (command === "providers") return await cmdProviders(flags);
|
|
553
|
-
if (command === "connect") return await cmdConnect(flags, rest);
|
|
721
|
+
if (command === "connect" || command === "add") return await cmdConnect(flags, rest);
|
|
722
|
+
if (command === "disconnect" || command === "remove" || command === "rm") {
|
|
723
|
+
return await cmdDisconnect(flags, rest);
|
|
724
|
+
}
|
|
725
|
+
if (command === "hosts") return await cmdHosts(flags);
|
|
554
726
|
if (command === "chat") return await cmdChat(flags, rest);
|
|
555
727
|
if (command === "models") return await cmdModels(flags);
|
|
556
728
|
if (command === "savings") return await cmdSavings(flags);
|