@bytevion/cli 0.5.0 → 0.5.2
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/commands/compare.js +38 -3
- package/dist/commands/connect.d.ts +3 -0
- package/dist/commands/connect.js +50 -19
- package/dist/commands/integrate.js +4 -4
- package/dist/commands/metrics.d.ts +9 -0
- package/dist/commands/metrics.js +39 -0
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.js +4 -3
- package/dist/lib/api.d.ts +1 -0
- package/dist/lib/api.js +3 -0
- package/dist/lib/home.js +7 -1
- package/oclif.manifest.json +77 -5
- package/package.json +1 -1
package/dist/commands/compare.js
CHANGED
|
@@ -41,6 +41,42 @@ const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : Number(v)
|
|
|
41
41
|
const usd = (v) => `$${num(v).toFixed(6)}`;
|
|
42
42
|
const tokensOf = (m) => num(m?.tokens_in) + num(m?.tokens_out);
|
|
43
43
|
const pad = (s, n) => s.padEnd(n);
|
|
44
|
+
const QUALITY_PASS = new Set(['quality_held', 'quality_improved', 'passed_verification']);
|
|
45
|
+
// The gateway scores each lane's quality in isolation; a soft "failed_verification" means
|
|
46
|
+
// an automated claim check was inconclusive, not that the answer is wrong or worse than
|
|
47
|
+
// direct. Render it as unverified rather than a scary raw state.
|
|
48
|
+
const qualityLabel = (s) => {
|
|
49
|
+
switch (s) {
|
|
50
|
+
case 'quality_held':
|
|
51
|
+
case 'quality_improved':
|
|
52
|
+
case 'passed_verification':
|
|
53
|
+
return 'held';
|
|
54
|
+
case 'failed_verification':
|
|
55
|
+
return 'unverified (auto-check inconclusive)';
|
|
56
|
+
case 'review':
|
|
57
|
+
return 'needs review';
|
|
58
|
+
case 'failed_guard':
|
|
59
|
+
return 'failed — output unusable';
|
|
60
|
+
case 'not_measured':
|
|
61
|
+
return 'not measured';
|
|
62
|
+
default:
|
|
63
|
+
return s;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const verdictLine = (dominance, quality, savingsPct, latencySaved) => {
|
|
67
|
+
const cheaper = savingsPct > 0;
|
|
68
|
+
const faster = latencySaved > 0;
|
|
69
|
+
const held = QUALITY_PASS.has(quality);
|
|
70
|
+
if (dominance === 'dominant')
|
|
71
|
+
return ui.theme.ok('Byte wins — cheaper, faster, quality held');
|
|
72
|
+
if (dominance === 'regressed')
|
|
73
|
+
return ui.theme.bad('Regressed — direct was the better choice here');
|
|
74
|
+
if (cheaper || faster) {
|
|
75
|
+
const wins = [cheaper ? `${savingsPct.toFixed(0)}% cheaper` : '', faster ? `${Math.abs(latencySaved)}ms faster` : ''].filter(Boolean).join(', ');
|
|
76
|
+
return ui.theme.ok(`Byte wins — ${wins}`) + (held ? '' : ui.theme.muted(' · quality unverified'));
|
|
77
|
+
}
|
|
78
|
+
return ui.theme.muted('Neutral — no clear difference');
|
|
79
|
+
};
|
|
44
80
|
class Compare extends base_1.BaseCommand {
|
|
45
81
|
static description = 'Prove the win: run a prompt direct vs through Byte and compare cost, latency, and quality.';
|
|
46
82
|
static examples = [
|
|
@@ -94,9 +130,8 @@ class Compare extends base_1.BaseCommand {
|
|
|
94
130
|
const sign = latencySaved >= 0 ? '−' : '+';
|
|
95
131
|
this.log(` Savings ${usd(savings)} (${savingsPct.toFixed(1)}%)`);
|
|
96
132
|
this.log(` Latency ${sign}${Math.abs(latencySaved)} ms`);
|
|
97
|
-
this.log(` Quality ${quality}`);
|
|
98
|
-
|
|
99
|
-
this.log(` Verdict ${verdict}`);
|
|
133
|
+
this.log(` Quality ${qualityLabel(quality)}`);
|
|
134
|
+
this.log(` Verdict ${verdictLine(dominance, quality, savingsPct, latencySaved)}`);
|
|
100
135
|
this.log('');
|
|
101
136
|
return { direct, byte, summary };
|
|
102
137
|
}
|
|
@@ -6,7 +6,10 @@ export default class Connect extends BaseCommand {
|
|
|
6
6
|
model: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
7
|
preset: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
8
|
only: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
+
all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
write: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
11
|
yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
12
|
};
|
|
11
13
|
run(): Promise<unknown>;
|
|
14
|
+
private smokeTest;
|
|
12
15
|
}
|
package/dist/commands/connect.js
CHANGED
|
@@ -7,22 +7,26 @@ class Connect extends base_1.BaseCommand {
|
|
|
7
7
|
static description = 'Detect installed coding agents and wire every one Byte can auto-configure — in one shot.';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> connect',
|
|
10
|
-
'<%= config.bin %> connect --
|
|
10
|
+
'<%= config.bin %> connect --all --write',
|
|
11
11
|
'<%= config.bin %> connect --only opencode,codex',
|
|
12
12
|
];
|
|
13
13
|
static flags = {
|
|
14
|
-
model: core_1.Flags.string({ description: 'Model
|
|
14
|
+
model: core_1.Flags.string({ description: 'Model to wire (default: auto — Byte routes to your enabled model)' }),
|
|
15
15
|
preset: core_1.Flags.string({
|
|
16
16
|
description: 'Optimization preset to apply before wiring',
|
|
17
17
|
options: ['maximum', 'balanced', 'max_savings', 'lowest_latency', 'reliability_first'],
|
|
18
18
|
}),
|
|
19
19
|
only: core_1.Flags.string({ description: 'Comma-separated subset of tool keys to wire' }),
|
|
20
|
+
all: core_1.Flags.boolean({ description: 'Wire every detected auto-configurable tool (this is the default)' }),
|
|
21
|
+
write: core_1.Flags.boolean({ description: 'Write tool config files (the default for connect)' }),
|
|
20
22
|
yes: core_1.Flags.boolean({ char: 'y', description: 'Skip confirmation prompts' }),
|
|
21
23
|
};
|
|
22
24
|
async run() {
|
|
23
25
|
const { flags } = await this.parse(Connect);
|
|
24
26
|
// A Byte key is what gets written into each tool's config, so require one up front.
|
|
25
|
-
this.requireByteKey(flags);
|
|
27
|
+
const byteKey = this.requireByteKey(flags);
|
|
28
|
+
const model = flags.model || 'auto';
|
|
29
|
+
const bin = this.config.bin;
|
|
26
30
|
const only = flags.only ? new Set(flags.only.split(',').map((s) => s.trim()).filter(Boolean)) : null;
|
|
27
31
|
const detected = (0, detect_1.detectTools)().filter((d) => d.installed && (!only || only.has(d.key)));
|
|
28
32
|
const targets = detected.filter((d) => d.canAutoWrite);
|
|
@@ -31,34 +35,61 @@ class Connect extends base_1.BaseCommand {
|
|
|
31
35
|
if (!this.jsonEnabled()) {
|
|
32
36
|
this.log('No auto-configurable coding agents detected.');
|
|
33
37
|
if (manual.length)
|
|
34
|
-
this.log(`Installed but manual: ${manual.join(', ')} — run
|
|
38
|
+
this.log(`Installed but manual: ${manual.join(', ')} — run \`${bin} integrate <tool>\`.`);
|
|
35
39
|
else
|
|
36
|
-
this.log(
|
|
40
|
+
this.log(`Install one (e.g. opencode) or wire manually with \`${bin} integrate --list\`.`);
|
|
37
41
|
}
|
|
38
42
|
return { wired: [], manual };
|
|
39
43
|
}
|
|
40
44
|
const wired = [];
|
|
41
45
|
for (const target of targets) {
|
|
42
|
-
const argv = [
|
|
43
|
-
target.key,
|
|
44
|
-
'--write',
|
|
45
|
-
'--yes',
|
|
46
|
-
...(flags.model ? ['--model', flags.model] : []),
|
|
47
|
-
...(flags.preset ? ['--preset', flags.preset] : []),
|
|
48
|
-
];
|
|
46
|
+
const argv = [target.key, '--write', '--yes', '--model', model, ...(flags.preset ? ['--preset', flags.preset] : [])];
|
|
49
47
|
// sequential keeps config writes + their backups ordered and surfaces the first failure clearly
|
|
50
48
|
// eslint-disable-next-line no-await-in-loop
|
|
51
49
|
await this.config.runCommand('integrate', argv);
|
|
52
50
|
wired.push(target.key);
|
|
53
51
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
// Real smoke test of the shared gateway every config points at: list models, then send a
|
|
53
|
+
// model=auto completion. Only claim "connected" if both pass.
|
|
54
|
+
const probe = await this.smokeTest(byteKey, flags);
|
|
55
|
+
if (this.jsonEnabled())
|
|
56
|
+
return { wired, manual, model, verified: probe.ok, probe };
|
|
57
|
+
this.log('');
|
|
58
|
+
if (probe.ok) {
|
|
59
|
+
this.log(`Connected ${wired.length} tool(s): ${wired.join(', ')} ✓ gateway verified (model: ${model}).`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.log(`Wired ${wired.length} tool(s): ${wired.join(', ')} — gateway smoke test did not pass: ${probe.reason}.`);
|
|
63
|
+
this.log(`Resolve that, then confirm with \`${bin} run "hi"\` or \`${bin} doctor\`.`);
|
|
64
|
+
}
|
|
65
|
+
if (manual.length)
|
|
66
|
+
this.log(`Manual setup needed for: ${manual.join(', ')} — run \`${bin} integrate <tool>\`.`);
|
|
67
|
+
this.log(`Export the Byte key in your shell (see \`${bin} env\`) and start coding.`);
|
|
68
|
+
return { wired, manual, model, verified: probe.ok };
|
|
69
|
+
}
|
|
70
|
+
// GET /v1/models then POST /v1/chat/completions model=auto, both with the Byte key. Returns
|
|
71
|
+
// a clear reason on failure so connect never prints "connected" for a wiring that won't work.
|
|
72
|
+
async smokeTest(byteKey, flags) {
|
|
73
|
+
const api = this.api(flags);
|
|
74
|
+
try {
|
|
75
|
+
await api.models(byteKey);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
const e = err;
|
|
79
|
+
return { ok: false, reason: `GET /v1/models failed (${e?.code || e?.message || 'unreachable'})` };
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const res = (await api.chat(byteKey, { model: 'auto', max_tokens: 1, messages: [{ role: 'user', content: 'ping' }] }));
|
|
83
|
+
if (res?.choices?.length || res?.id)
|
|
84
|
+
return { ok: true, reason: '' };
|
|
85
|
+
return { ok: false, reason: 'chat returned no choices' };
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
const e = err;
|
|
89
|
+
const code = String(e?.code || e?.message || 'error');
|
|
90
|
+
const reason = code.includes('NOT_CONFIGURED') ? `no model enabled yet — run \`${this.config.bin} setup\` or enable a model` : `POST /v1/chat/completions model=auto failed (${code})`;
|
|
91
|
+
return { ok: false, reason };
|
|
60
92
|
}
|
|
61
|
-
return { wired, manual };
|
|
62
93
|
}
|
|
63
94
|
}
|
|
64
95
|
exports.default = Connect;
|
|
@@ -64,7 +64,7 @@ class Integrate extends base_1.BaseCommand {
|
|
|
64
64
|
write: core_1.Flags.boolean({ description: 'Write tool config files (a timestamped .bak is kept)' }),
|
|
65
65
|
yes: core_1.Flags.boolean({ char: 'y', description: 'Skip confirmation prompts' }),
|
|
66
66
|
key: core_1.Flags.string({ description: 'Byte API key to use (defaults to the saved profile key)' }),
|
|
67
|
-
model: core_1.Flags.string({ description: 'Model
|
|
67
|
+
model: core_1.Flags.string({ description: 'Model to wire (default: auto — Byte routes to your enabled model)' }),
|
|
68
68
|
preset: core_1.Flags.string({
|
|
69
69
|
description: 'Apply this optimization preset to the org before wiring',
|
|
70
70
|
options: ['balanced', 'max_savings', 'lowest_latency', 'reliability_first'],
|
|
@@ -90,11 +90,11 @@ class Integrate extends base_1.BaseCommand {
|
|
|
90
90
|
}
|
|
91
91
|
const integ = (0, integrations_1.findIntegration)(target);
|
|
92
92
|
if (!integ)
|
|
93
|
-
return this.error(`Unknown target "${target}". Run
|
|
93
|
+
return this.error(`Unknown target "${target}". Run \`${this.config.bin} integrate --list\`.`, { exit: 2 });
|
|
94
94
|
const byteKey = flags.key || this.requireByteKey(flags);
|
|
95
95
|
const base = this.baseUrlFrom(flags);
|
|
96
96
|
const shell = (0, shell_1.detectShell)(flags.shell);
|
|
97
|
-
const modelAlias = flags.model || '
|
|
97
|
+
const modelAlias = flags.model || 'auto';
|
|
98
98
|
if (flags.preset) {
|
|
99
99
|
this.requireToken(flags);
|
|
100
100
|
await this.api(flags).optPatch({ default_mode: flags.preset });
|
|
@@ -191,7 +191,7 @@ class Integrate extends base_1.BaseCommand {
|
|
|
191
191
|
const rows = (0, detect_1.detectTools)().map((d) => {
|
|
192
192
|
let wired = false;
|
|
193
193
|
const integ = (0, integrations_1.findIntegration)(d.key);
|
|
194
|
-
const file = integ?.build({ baseUrl: base, byteKey, modelAlias: '
|
|
194
|
+
const file = integ?.build({ baseUrl: base, byteKey, modelAlias: 'auto' }).settingsFile;
|
|
195
195
|
if (file && (0, node_fs_1.existsSync)(file.path)) {
|
|
196
196
|
try {
|
|
197
197
|
wired = (0, node_fs_1.readFileSync)(file.path, 'utf8').toLowerCase().includes('byte');
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseCommand } from '../base';
|
|
2
|
+
export default class Metrics extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
run(): Promise<unknown>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_1 = require("../base");
|
|
5
|
+
const output_1 = require("../lib/output");
|
|
6
|
+
const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : Number(v) || 0);
|
|
7
|
+
const pad = (s) => s.padEnd(12);
|
|
8
|
+
class Metrics extends base_1.BaseCommand {
|
|
9
|
+
static description = 'Full cost / latency / quality breakdown for a single request.';
|
|
10
|
+
static examples = ['<%= config.bin %> metrics 1429', '<%= config.bin %> requests # to find an id'];
|
|
11
|
+
static args = {
|
|
12
|
+
id: core_1.Args.string({ description: 'Request id (from the requests list or the dashboard)', required: true }),
|
|
13
|
+
};
|
|
14
|
+
async run() {
|
|
15
|
+
const { args, flags } = await this.parse(Metrics);
|
|
16
|
+
this.requireToken(flags);
|
|
17
|
+
const d = await this.api(flags).requestDetail(args.id);
|
|
18
|
+
if (this.jsonEnabled())
|
|
19
|
+
return d;
|
|
20
|
+
const cost = d.cost ?? {};
|
|
21
|
+
const tok = d.tokens ?? {};
|
|
22
|
+
const lat = d.latency ?? {};
|
|
23
|
+
const cache = d.cache ?? {};
|
|
24
|
+
const routedFrom = d.requested_model && d.requested_model !== d.routed_model ? ` (routed from: ${d.requested_model})` : '';
|
|
25
|
+
const layers = Array.isArray(d.layers) ? d.layers : [];
|
|
26
|
+
this.log('');
|
|
27
|
+
this.log(` ${pad('Model')}${d.routed_model ?? d.selected_alias ?? '-'}${routedFrom}`);
|
|
28
|
+
this.log(` ${pad('Cost')}direct ${(0, output_1.fmtUsd)(cost.raw_usd)} → byte ${(0, output_1.fmtUsd)(cost.byte_usd)} save ${num(cost.savings_pct).toFixed(1)}%`);
|
|
29
|
+
this.log(` ${pad('Tokens')}in ${num(tok.in)} out ${num(tok.out)}${num(tok.cached_in) ? ` (cached in ${num(tok.cached_in)})` : ''}`);
|
|
30
|
+
this.log(` ${pad('Latency')}${num(lat.total_ms)}ms · ttft ${num(lat.ttft_ms)}ms${num(lat.saved_ms) ? ` · saved ${num(lat.saved_ms)}ms` : ''}`);
|
|
31
|
+
this.log(` ${pad('Cache')}tier=${cache.layer ?? 'miss'} · quality=${d.quality_gate_state || 'n/a'}`);
|
|
32
|
+
if (layers.length)
|
|
33
|
+
this.log(` ${pad('Layers')}${layers.map((l) => `${l.layer}(${(0, output_1.fmtUsd)(l.savings_usd)})`).join(' ')}`);
|
|
34
|
+
this.log(` ${pad('Verdict')}${d.dominance_status || '-'}`);
|
|
35
|
+
this.log('');
|
|
36
|
+
return d;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.default = Metrics;
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export default class Sync extends BaseCommand {
|
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
6
|
model: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
+
all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
7
8
|
yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
8
9
|
};
|
|
9
10
|
run(): Promise<unknown>;
|
package/dist/commands/sync.js
CHANGED
|
@@ -7,7 +7,8 @@ class Sync extends base_1.BaseCommand {
|
|
|
7
7
|
static description = 'Re-apply your current Byte key/model to every wired coding agent (run after rotating a key or switching model).';
|
|
8
8
|
static examples = ['<%= config.bin %> sync', '<%= config.bin %> sync --model byte-2-deepseek-v4-flash'];
|
|
9
9
|
static flags = {
|
|
10
|
-
model: core_1.Flags.string({ description: 'Model
|
|
10
|
+
model: core_1.Flags.string({ description: 'Model to wire (default: the last wired model, or auto)' }),
|
|
11
|
+
all: core_1.Flags.boolean({ description: 'Re-apply to every wired tool (this is the default)' }),
|
|
11
12
|
yes: core_1.Flags.boolean({ char: 'y', description: 'Skip confirmation prompts' }),
|
|
12
13
|
};
|
|
13
14
|
async run() {
|
|
@@ -18,10 +19,10 @@ class Sync extends base_1.BaseCommand {
|
|
|
18
19
|
const tools = wiring.tools || [];
|
|
19
20
|
if (!tools.length) {
|
|
20
21
|
if (!this.jsonEnabled())
|
|
21
|
-
this.log(
|
|
22
|
+
this.log(`No wired tools yet. Run \`${this.config.bin} connect\` first.`);
|
|
22
23
|
return { synced: [] };
|
|
23
24
|
}
|
|
24
|
-
const model = flags.model || wiring.model;
|
|
25
|
+
const model = flags.model || wiring.model || 'auto';
|
|
25
26
|
if (flags.model)
|
|
26
27
|
(0, wiring_1.setSelectedModel)(profile, flags.model);
|
|
27
28
|
const synced = [];
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export declare class ByteApi {
|
|
|
34
34
|
usage(granularity: string): Promise<any>;
|
|
35
35
|
dashboard(): Promise<any>;
|
|
36
36
|
requests(): Promise<any>;
|
|
37
|
+
requestDetail(id: string | number): Promise<any>;
|
|
37
38
|
cacheStats(): Promise<any>;
|
|
38
39
|
costs(): Promise<any>;
|
|
39
40
|
health(): Promise<any>;
|
package/dist/lib/api.js
CHANGED
|
@@ -138,6 +138,9 @@ class ByteApi {
|
|
|
138
138
|
requests() {
|
|
139
139
|
return this.request('GET', '/api/v1/requests');
|
|
140
140
|
}
|
|
141
|
+
requestDetail(id) {
|
|
142
|
+
return this.request('GET', `/api/v1/requests/${encodeURIComponent(String(id))}`);
|
|
143
|
+
}
|
|
141
144
|
cacheStats() {
|
|
142
145
|
return this.request('GET', '/api/v1/cache/stats');
|
|
143
146
|
}
|
package/dist/lib/home.js
CHANGED
|
@@ -68,7 +68,13 @@ async function loadHomeData(api, byteKey, fallbackId) {
|
|
|
68
68
|
providers: conns.length || undefined,
|
|
69
69
|
models: models || undefined,
|
|
70
70
|
byteKey,
|
|
71
|
-
|
|
71
|
+
// The control plane reports a ready gateway as status:"ready" (and mirrors it in
|
|
72
|
+
// health.gateway). Accept "ready"/"ok"/ok so a healthy gateway is never shown as down.
|
|
73
|
+
gateway: health
|
|
74
|
+
? health.status === 'ready' || health.status === 'ok' || health.gateway === 'ready' || health.gateway === 'ok' || health.ok
|
|
75
|
+
? 'healthy'
|
|
76
|
+
: 'down'
|
|
77
|
+
: 'unknown',
|
|
72
78
|
savingsSeries: series.map((p) => num(p.savings_usd)),
|
|
73
79
|
savedTotal: series.reduce((a, p) => a + num(p.savings_usd), 0),
|
|
74
80
|
tokensTotal: series.reduce((a, p) => a + num(p.tokens_in) + num(p.tokens_out), 0),
|
package/oclif.manifest.json
CHANGED
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"description": "Detect installed coding agents and wire every one Byte can auto-configure — in one shot.",
|
|
69
69
|
"examples": [
|
|
70
70
|
"<%= config.bin %> connect",
|
|
71
|
-
"<%= config.bin %> connect --
|
|
71
|
+
"<%= config.bin %> connect --all --write",
|
|
72
72
|
"<%= config.bin %> connect --only opencode,codex"
|
|
73
73
|
],
|
|
74
74
|
"flags": {
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"type": "option"
|
|
97
97
|
},
|
|
98
98
|
"model": {
|
|
99
|
-
"description": "Model
|
|
99
|
+
"description": "Model to wire (default: auto — Byte routes to your enabled model)",
|
|
100
100
|
"name": "model",
|
|
101
101
|
"hasDynamicHelp": false,
|
|
102
102
|
"multiple": false,
|
|
@@ -123,6 +123,18 @@
|
|
|
123
123
|
"multiple": false,
|
|
124
124
|
"type": "option"
|
|
125
125
|
},
|
|
126
|
+
"all": {
|
|
127
|
+
"description": "Wire every detected auto-configurable tool (this is the default)",
|
|
128
|
+
"name": "all",
|
|
129
|
+
"allowNo": false,
|
|
130
|
+
"type": "boolean"
|
|
131
|
+
},
|
|
132
|
+
"write": {
|
|
133
|
+
"description": "Write tool config files (the default for connect)",
|
|
134
|
+
"name": "write",
|
|
135
|
+
"allowNo": false,
|
|
136
|
+
"type": "boolean"
|
|
137
|
+
},
|
|
126
138
|
"yes": {
|
|
127
139
|
"char": "y",
|
|
128
140
|
"description": "Skip confirmation prompts",
|
|
@@ -479,7 +491,7 @@
|
|
|
479
491
|
"type": "option"
|
|
480
492
|
},
|
|
481
493
|
"model": {
|
|
482
|
-
"description": "Model
|
|
494
|
+
"description": "Model to wire (default: auto — Byte routes to your enabled model)",
|
|
483
495
|
"name": "model",
|
|
484
496
|
"hasDynamicHelp": false,
|
|
485
497
|
"multiple": false,
|
|
@@ -612,6 +624,60 @@
|
|
|
612
624
|
"logout.js"
|
|
613
625
|
]
|
|
614
626
|
},
|
|
627
|
+
"metrics": {
|
|
628
|
+
"aliases": [],
|
|
629
|
+
"args": {
|
|
630
|
+
"id": {
|
|
631
|
+
"description": "Request id (from the requests list or the dashboard)",
|
|
632
|
+
"name": "id",
|
|
633
|
+
"required": true
|
|
634
|
+
}
|
|
635
|
+
},
|
|
636
|
+
"description": "Full cost / latency / quality breakdown for a single request.",
|
|
637
|
+
"examples": [
|
|
638
|
+
"<%= config.bin %> metrics 1429",
|
|
639
|
+
"<%= config.bin %> requests # to find an id"
|
|
640
|
+
],
|
|
641
|
+
"flags": {
|
|
642
|
+
"json": {
|
|
643
|
+
"description": "Format output as json.",
|
|
644
|
+
"helpGroup": "GLOBAL",
|
|
645
|
+
"name": "json",
|
|
646
|
+
"allowNo": false,
|
|
647
|
+
"type": "boolean"
|
|
648
|
+
},
|
|
649
|
+
"profile": {
|
|
650
|
+
"description": "Configuration profile to use",
|
|
651
|
+
"env": "BYTE_PROFILE",
|
|
652
|
+
"name": "profile",
|
|
653
|
+
"hasDynamicHelp": false,
|
|
654
|
+
"multiple": false,
|
|
655
|
+
"type": "option"
|
|
656
|
+
},
|
|
657
|
+
"base-url": {
|
|
658
|
+
"description": "Override the API base URL",
|
|
659
|
+
"env": "BYTE_BASE_URL",
|
|
660
|
+
"name": "base-url",
|
|
661
|
+
"hasDynamicHelp": false,
|
|
662
|
+
"multiple": false,
|
|
663
|
+
"type": "option"
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
"hasDynamicHelp": false,
|
|
667
|
+
"hiddenAliases": [],
|
|
668
|
+
"id": "metrics",
|
|
669
|
+
"pluginAlias": "@bytevion/cli",
|
|
670
|
+
"pluginName": "@bytevion/cli",
|
|
671
|
+
"pluginType": "core",
|
|
672
|
+
"strict": true,
|
|
673
|
+
"enableJsonFlag": true,
|
|
674
|
+
"isESM": false,
|
|
675
|
+
"relativePath": [
|
|
676
|
+
"dist",
|
|
677
|
+
"commands",
|
|
678
|
+
"metrics.js"
|
|
679
|
+
]
|
|
680
|
+
},
|
|
615
681
|
"run": {
|
|
616
682
|
"aliases": [],
|
|
617
683
|
"args": {
|
|
@@ -874,12 +940,18 @@
|
|
|
874
940
|
"type": "option"
|
|
875
941
|
},
|
|
876
942
|
"model": {
|
|
877
|
-
"description": "Model
|
|
943
|
+
"description": "Model to wire (default: the last wired model, or auto)",
|
|
878
944
|
"name": "model",
|
|
879
945
|
"hasDynamicHelp": false,
|
|
880
946
|
"multiple": false,
|
|
881
947
|
"type": "option"
|
|
882
948
|
},
|
|
949
|
+
"all": {
|
|
950
|
+
"description": "Re-apply to every wired tool (this is the default)",
|
|
951
|
+
"name": "all",
|
|
952
|
+
"allowNo": false,
|
|
953
|
+
"type": "boolean"
|
|
954
|
+
},
|
|
883
955
|
"yes": {
|
|
884
956
|
"char": "y",
|
|
885
957
|
"description": "Skip confirmation prompts",
|
|
@@ -2200,5 +2272,5 @@
|
|
|
2200
2272
|
]
|
|
2201
2273
|
}
|
|
2202
2274
|
},
|
|
2203
|
-
"version": "0.5.
|
|
2275
|
+
"version": "0.5.2"
|
|
2204
2276
|
}
|