@letterstory/cli 0.123.0 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli.mjs +5 -1
- package/lib/commands/admin.mjs +79 -0
- package/package.json +1 -1
package/lib/cli.mjs
CHANGED
|
@@ -61,13 +61,15 @@ import {
|
|
|
61
61
|
} from "./commands.mjs";
|
|
62
62
|
|
|
63
63
|
// Keep in sync with cli/package.json.
|
|
64
|
-
export const VERSION = "0.
|
|
64
|
+
export const VERSION = "0.124.0";
|
|
65
65
|
|
|
66
66
|
// Flags that never take a value. Listing them explicitly means `deploy get --json <id>`
|
|
67
67
|
// can't accidentally swallow the id as --json's value. Every `type: "bool"` flag (and its
|
|
68
68
|
// `negate` spelling) in a command's ARGS map must be listed; boolean-flags.test.ts enforces it.
|
|
69
69
|
export const BOOLEAN_FLAGS = new Set([
|
|
70
70
|
"json",
|
|
71
|
+
// admin models runs: only the starred ones.
|
|
72
|
+
"starred",
|
|
71
73
|
// shredder file / arena file: save the version as a candidate beside live.
|
|
72
74
|
"candidate",
|
|
73
75
|
// site tree: include children a fold-by-default family would hide; items over the whole subtree.
|
|
@@ -843,6 +845,8 @@ Admin (STAFF key — --staff-key / LETTERSTORY_STAFF_API_KEY; acts before an org
|
|
|
843
845
|
session (a trial per arm), linked to its
|
|
844
846
|
ledger entry. Written by \`npm run lab --
|
|
845
847
|
publish\` in the kernels repo.
|
|
848
|
+
admin models runs [--model M] [--starred] | run <id> | star|unstar <id> | scoreboard --model M
|
|
849
|
+
The model hub's saved runs and blind arena (models.letter.dev)
|
|
846
850
|
admin spend summary [--range day|week|month|year | --from D --to D] [--grain day|week|month]
|
|
847
851
|
| reconcile [--from D --to D] | pnl [--range day|week|month|year | --from D --to D]
|
|
848
852
|
| reference add --vendor V [--key K] --metric billed_usd --value N --from D [--to D] --ref "…"
|
package/lib/commands/admin.mjs
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
// admin brand-detection <org-id> (fleet:read)
|
|
20
20
|
// admin brand-detection <org-id> [--term t]... [--exact t]... [--exclude p]... [--note "…"] | --clear [--note "…"] (fleet:instrument)
|
|
21
21
|
// admin recipes list|show|vocab|export|import|save|delete … (recipes:read / recipes:write)
|
|
22
|
+
// admin models runs|run|star|unstar|scoreboard … (models:read / models:write)
|
|
22
23
|
// admin replays [--org <id>] [--target <id>] [--status …] [--limit n] (fleet:read)
|
|
23
24
|
// admin replay --org <id> [<response-id> | --target <id>] [--surface …] (fleet:replay)
|
|
24
25
|
// admin create-org --domain acme.com [--name "Acme"] [--test] [--no-key] [--key-name N]
|
|
@@ -3962,6 +3963,83 @@ function spendEntryFromFlags(flags) {
|
|
|
3962
3963
|
});
|
|
3963
3964
|
}
|
|
3964
3965
|
|
|
3966
|
+
const MODELS = "/api/superadmin/models";
|
|
3967
|
+
const MODELS_USAGE =
|
|
3968
|
+
"Usage: admin models runs [--model ballpoint-1] [--starred] [--limit N] | run <id> | star <id> | unstar <id> | scoreboard --model ballpoint-1";
|
|
3969
|
+
|
|
3970
|
+
/** The model hub's saved runs and blind arena (models.letter.dev), same functions as its pages. */
|
|
3971
|
+
async function cmdAdminModels(ctx) {
|
|
3972
|
+
const { flags, positionals, io } = ctx;
|
|
3973
|
+
const sub = positionals[0];
|
|
3974
|
+
switch (sub) {
|
|
3975
|
+
case "runs": {
|
|
3976
|
+
const params = new URLSearchParams(
|
|
3977
|
+
compact({
|
|
3978
|
+
model: flagStr(flags.model),
|
|
3979
|
+
starred: flagBool(flags.starred) ? "true" : undefined,
|
|
3980
|
+
limit: flagNum(flags.limit)?.toString(),
|
|
3981
|
+
})
|
|
3982
|
+
);
|
|
3983
|
+
const result = await staffRequest(ctx, "GET", `${MODELS}/runs${params.size ? `?${params}` : ""}`);
|
|
3984
|
+
printResult(io, flags, result, (r) =>
|
|
3985
|
+
(r.runs ?? [])
|
|
3986
|
+
.map(
|
|
3987
|
+
(x) =>
|
|
3988
|
+
`${x.created_at.slice(0, 16)} ${x.starred ? "★" : " "} ${x.model.padEnd(14)} ${String(x.outputs).padStart(3)} outputs ${String(x.votes).padStart(3)} votes ${x.contenders.join(", ")} ${x.id}`
|
|
3989
|
+
)
|
|
3990
|
+
.join("\n")
|
|
3991
|
+
);
|
|
3992
|
+
return 0;
|
|
3993
|
+
}
|
|
3994
|
+
case "run": {
|
|
3995
|
+
const id = positionals[1];
|
|
3996
|
+
if (!id) throw new CliError("Usage: admin models run <id>");
|
|
3997
|
+
const result = await staffRequest(ctx, "GET", `${MODELS}/runs/${id}`);
|
|
3998
|
+
printResult(io, flags, result, (r) =>
|
|
3999
|
+
[
|
|
4000
|
+
`${r.model} · ${r.created_at} · ${JSON.stringify(r.input)}`,
|
|
4001
|
+
...(r.outputs ?? []).map(
|
|
4002
|
+
(o) =>
|
|
4003
|
+
` [${o.slot}] ${o.contender}${o.ours ? " (ours)" : ""}: ${o.error ? `error: ${o.error}` : Object.values(o.output).join(" — ")}`
|
|
4004
|
+
),
|
|
4005
|
+
].join("\n")
|
|
4006
|
+
);
|
|
4007
|
+
return 0;
|
|
4008
|
+
}
|
|
4009
|
+
case "star":
|
|
4010
|
+
case "unstar": {
|
|
4011
|
+
const id = positionals[1];
|
|
4012
|
+
if (!id) throw new CliError(`Usage: admin models ${sub} <id>`);
|
|
4013
|
+
const result = await staffRequest(ctx, "PATCH", `${MODELS}/runs/${id}`, { starred: sub === "star" });
|
|
4014
|
+
ok(ctx, `${sub === "star" ? "Starred" : "Unstarred"} ${result.id}`);
|
|
4015
|
+
printResult(io, flags, result, () => "");
|
|
4016
|
+
return 0;
|
|
4017
|
+
}
|
|
4018
|
+
case "scoreboard": {
|
|
4019
|
+
const model = flagStr(flags.model);
|
|
4020
|
+
if (!model) throw new CliError("Usage: admin models scoreboard --model ballpoint-1");
|
|
4021
|
+
const result = await staffRequest(
|
|
4022
|
+
ctx,
|
|
4023
|
+
"GET",
|
|
4024
|
+
`${MODELS}/arena/scoreboard?model=${encodeURIComponent(model)}`
|
|
4025
|
+
);
|
|
4026
|
+
printResult(io, flags, result, (r) =>
|
|
4027
|
+
(r.opponents ?? []).length
|
|
4028
|
+
? r.opponents
|
|
4029
|
+
.map(
|
|
4030
|
+
(o) =>
|
|
4031
|
+
`${r.model} vs ${o.opponent}: ${o.wins}-${o.losses} (${o.ties} ties, ${o.both_bad} both bad) · ${o.win_rate == null ? "—" : `${Math.round(o.win_rate * 100)}% [${Math.round(o.low * 100)}–${Math.round(o.high * 100)}]`} · ${o.voters} voters`
|
|
4032
|
+
)
|
|
4033
|
+
.join("\n")
|
|
4034
|
+
: `No votes on ${r.model} yet.`
|
|
4035
|
+
);
|
|
4036
|
+
return 0;
|
|
4037
|
+
}
|
|
4038
|
+
default:
|
|
4039
|
+
throw new CliError(MODELS_USAGE);
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
|
|
3965
4043
|
async function cmdAdminSpend(ctx) {
|
|
3966
4044
|
const { flags, positionals, io } = ctx;
|
|
3967
4045
|
const sub = positionals[0];
|
|
@@ -4767,6 +4845,7 @@ export async function cmdAdmin(ctx) {
|
|
|
4767
4845
|
return cmdAdminReplays({ ...ctx, positionals: ctx.positionals.slice(1) }, sub);
|
|
4768
4846
|
if (sub === "crm") return cmdAdminCrm({ ...ctx, positionals: ctx.positionals.slice(1) });
|
|
4769
4847
|
if (sub === "spend") return cmdAdminSpend({ ...ctx, positionals: ctx.positionals.slice(1) });
|
|
4848
|
+
if (sub === "models") return cmdAdminModels({ ...ctx, positionals: ctx.positionals.slice(1) });
|
|
4770
4849
|
if (sub === "create-org") return cmdAdminCreateOrg({ ...ctx, positionals: ctx.positionals.slice(1) });
|
|
4771
4850
|
if (sub === "ask") return cmdAdminAsk({ ...ctx, positionals: ctx.positionals.slice(1) });
|
|
4772
4851
|
if (sub === "patterns") return cmdAdminPatterns({ ...ctx, positionals: ctx.positionals.slice(1) });
|