@moda-ai/cli 1.55.44 → 1.55.46
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 +7 -8
- package/dist/{agent-5ax7fqhe.js → agent-aewgndk0.js} +16 -16
- package/dist/{cli-tztzrh6b.js → cli-4kf462jq.js} +3 -3
- package/dist/{cli-xcpwp0gb.js → cli-d6gfxx8t.js} +1 -1
- package/dist/{cli-t4xfvrry.js → cli-dxbd1xxs.js} +5 -5
- package/dist/{cli-wwbr5caw.js → cli-fqc02t6h.js} +12 -91
- package/dist/{cli-sejqvvhv.js → cli-h1z9yyqk.js} +1 -1
- package/dist/{cli-dmm9jm9m.js → cli-j08a1mam.js} +1 -1
- package/dist/{cli-8pcq2et6.js → cli-m4474bnj.js} +1 -1
- package/dist/{cli-xx0pjzkh.js → cli-s7d069g0.js} +5 -19
- package/dist/{cli-k2ka2kjb.js → cli-sqnw96gj.js} +7 -2
- package/dist/{cli-d4cdczhe.js → cli-x7rc3twr.js} +42 -42
- package/dist/{cli-5aa48ry5.js → cli-xctqdn42.js} +3 -3
- package/dist/cli.js +227 -630
- package/dist/{doctor-k4tdgvgv.js → doctor-fz5kq44d.js} +8 -8
- package/dist/{harness-avynbq4f.js → harness-cy0gpyhj.js} +10 -10
- package/dist/{harness-github-actions-gd6vyxb0.js → harness-github-actions-aac3tn96.js} +9 -9
- package/dist/{index-63k2a6gb.js → index-5eyq3ykt.js} +26 -26
- package/dist/{production-intelligence-sv3qx7f4.js → production-intelligence-8j8008d2.js} +6 -4
- package/dist/{profile-commands-mh3kfqkn.js → profile-commands-zbyn9xg2.js} +5 -5
- package/dist/{prompt-attribution-wvvnzw4m.js → prompt-attribution-g9gtv191.js} +9 -9
- package/dist/prompt-source-mcp.js +9 -9
- package/dist/{prompts-snnbyxmz.js → prompts-b6awryvv.js} +9 -13
- package/dist/{provision-t1dpzcjp.js → provision-xkhwz86g.js} +6 -6
- package/dist/{registry-8zkxefjs.js → registry-d7xdm4dw.js} +4 -4
- package/dist/{skills-d4215fa9.js → skills-zfenne8w.js} +6 -6
- package/dist/{sync-17f9yxb1.js → sync-5vd8gwte.js} +12 -12
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +7 -10
- package/skills/moda-cli/references/commands.md +1 -2
- package/skills/moda-cli/references/dashboard-parity.md +2 -3
- package/skills/moda-cli/references/output-protocol.md +1 -1
- package/skills/moda-cli/references/production-intelligence.md +0 -4
- package/skills/moda-cli/references/prompts.md +1 -27
- package/skills/moda-cli/references/{replays-and-registry.md → registry.md} +15 -59
- package/dist/cli-4pc0a18x.js +0 -12
- package/dist/cli-8pksf2x7.js +0 -754
- package/dist/fix-nk5xffz8.js +0 -1440
- package/dist/prompts-ab-y7egdzg4.js +0 -64
- package/dist/prompts-propose-5nw25v9a.js +0 -256
- package/dist/{cli-e24fjyrb.js → cli-da3h2p6w.js} +28 -28
package/dist/cli.js
CHANGED
|
@@ -26,10 +26,10 @@ import {
|
|
|
26
26
|
withSummaryCompare,
|
|
27
27
|
withToolFailureAnchors,
|
|
28
28
|
withoutDetectionWindows
|
|
29
|
-
} from "./cli-
|
|
29
|
+
} from "./cli-sqnw96gj.js";
|
|
30
30
|
import {
|
|
31
31
|
createCommandContext
|
|
32
|
-
} from "./cli-
|
|
32
|
+
} from "./cli-m4474bnj.js";
|
|
33
33
|
import {
|
|
34
34
|
envOptOutSet,
|
|
35
35
|
envSwitchedOff,
|
|
@@ -64,8 +64,6 @@ import {
|
|
|
64
64
|
TRACE_GRAIN_FLAGS,
|
|
65
65
|
TraceFindingsSchema,
|
|
66
66
|
UUID_RE,
|
|
67
|
-
assertFlags,
|
|
68
|
-
assertPositionals,
|
|
69
67
|
buildFeedbackRequest,
|
|
70
68
|
closestMatches,
|
|
71
69
|
describeField,
|
|
@@ -87,12 +85,11 @@ import {
|
|
|
87
85
|
unknownSignalsSubcommandError,
|
|
88
86
|
usageLine,
|
|
89
87
|
writeDryRun
|
|
90
|
-
} from "./cli-
|
|
88
|
+
} from "./cli-4kf462jq.js";
|
|
91
89
|
import {
|
|
92
90
|
ApiError,
|
|
93
|
-
callControlAPI,
|
|
94
91
|
callDataAPI
|
|
95
|
-
} from "./cli-
|
|
92
|
+
} from "./cli-j08a1mam.js";
|
|
96
93
|
import {
|
|
97
94
|
AGENT_ERROR_CODES,
|
|
98
95
|
EXIT_AUTH_REQUIRED,
|
|
@@ -109,27 +106,24 @@ import {
|
|
|
109
106
|
apiKeyHeaders,
|
|
110
107
|
canonicalCommandText,
|
|
111
108
|
createCliOutput,
|
|
112
|
-
embeddedTenantIdFromApiKey,
|
|
113
109
|
errorToAgentError,
|
|
114
110
|
getActiveProfile,
|
|
115
111
|
getApiRequestCount,
|
|
116
112
|
getModaDir,
|
|
117
|
-
isPlatformApiKey,
|
|
118
113
|
loadProfileConfig,
|
|
119
114
|
resetApiRequestCount,
|
|
120
115
|
resolveApiKey,
|
|
121
|
-
resolveApiTenantId,
|
|
122
116
|
resolveModaBaseUrl,
|
|
123
117
|
resolveModaBaseUrlStrict,
|
|
124
118
|
resolveOutputMode,
|
|
125
119
|
safeWriteStderr,
|
|
126
120
|
safeWriteStdout,
|
|
127
121
|
setAgentUpdateNotice,
|
|
128
|
-
setPlatformTenantOverride,
|
|
129
122
|
shellArg,
|
|
130
123
|
validateConfig,
|
|
131
124
|
wasOutputCancelled
|
|
132
|
-
} from "./cli-
|
|
125
|
+
} from "./cli-da3h2p6w.js";
|
|
126
|
+
import"./cli-ns5fcnkz.js";
|
|
133
127
|
import {
|
|
134
128
|
CliAccessError,
|
|
135
129
|
CliAuthError,
|
|
@@ -143,7 +137,6 @@ import {
|
|
|
143
137
|
isApiLikeError,
|
|
144
138
|
isNetworkLikeError
|
|
145
139
|
} from "./cli-k4tqwah4.js";
|
|
146
|
-
import"./cli-ns5fcnkz.js";
|
|
147
140
|
import {
|
|
148
141
|
__require
|
|
149
142
|
} from "./cli-0v6na3yp.js";
|
|
@@ -321,185 +314,6 @@ function batchNotRunWarning(results) {
|
|
|
321
314
|
return [`Families not run (detector off or trace not processed yet), so no detections there does not mean clean: ${notRun.join("; ")}.`];
|
|
322
315
|
}
|
|
323
316
|
|
|
324
|
-
// src/replays.ts
|
|
325
|
-
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
326
|
-
var PLAYOUT_ID_RE = /^[0-9a-f]{64}$/i;
|
|
327
|
-
var ARMS = ["prod", "proposed"];
|
|
328
|
-
var REPLAYS_SUBCOMMANDS = ["sets", "runs", "run", "playouts", "playout"];
|
|
329
|
-
var REPLAYS_SUBCOMMAND_HELP = [
|
|
330
|
-
{
|
|
331
|
-
name: "sets",
|
|
332
|
-
description: "List replay sets (ids, names, case counts)",
|
|
333
|
-
usage: "moda replays sets",
|
|
334
|
-
examples: ["moda replays sets --json"]
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
name: "runs",
|
|
338
|
-
description: "Run history for a set, newest first, every status",
|
|
339
|
-
usage: "moda replays runs <set_id> [--limit=N]",
|
|
340
|
-
flags: [{ name: "--limit=N", description: "Runs to return (default 20, max 100)." }],
|
|
341
|
-
examples: ["moda replays runs <set_id> --limit=5 --json"]
|
|
342
|
-
},
|
|
343
|
-
{
|
|
344
|
-
name: "run",
|
|
345
|
-
description: "One run: summary, per-case aggregate, every case x arm x seed verdict, playout count",
|
|
346
|
-
usage: "moda replays run <set_id> <run_id|latest>",
|
|
347
|
-
examples: ["moda replays run <set_id> <run_id> --json", "moda replays run <set_id> latest --json"]
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
name: "playouts",
|
|
351
|
-
description: "Playouts of a run (one per case x arm x seed) with verdicts; --transcript inlines what was said and every tool call",
|
|
352
|
-
usage: "moda replays playouts <set_id> <run_id> [--case=<case_id>] [--arm=prod|proposed] [--seed=N] [--transcript] [--max-chars=N] [--limit=N] [--cursor=<next_cursor>]",
|
|
353
|
-
flags: [
|
|
354
|
-
{ name: "--case=<case_id>", description: "Only this case." },
|
|
355
|
-
{ name: "--arm=prod|proposed", description: "Only this arm (prod = baseline, proposed = candidate)." },
|
|
356
|
-
{ name: "--seed=N", description: "Only this seed." },
|
|
357
|
-
{ name: "--transcript", description: "Inline each transcript (messages, tool calls with served output and provenance, criteria). Page cap 10." },
|
|
358
|
-
{ name: "--max-chars=N", description: "Per-field cap for message text and tool JSON (default 4000, 100-32000)." },
|
|
359
|
-
{ name: "--limit=N", description: "Page size (default 50, max 200; 10 with --transcript)." },
|
|
360
|
-
{ name: "--cursor=<next_cursor>", description: "Next page: the previous response's nextCursor." }
|
|
361
|
-
],
|
|
362
|
-
examples: [
|
|
363
|
-
"moda replays playouts <set_id> <run_id> --json",
|
|
364
|
-
"moda replays playouts <set_id> <run_id> --case=<case_id> --arm=proposed --seed=1 --transcript --json"
|
|
365
|
-
]
|
|
366
|
-
},
|
|
367
|
-
{
|
|
368
|
-
name: "playout",
|
|
369
|
-
description: "One playout with its full transcript",
|
|
370
|
-
usage: "moda replays playout <set_id> <run_id> <playout_id> [--max-chars=N]",
|
|
371
|
-
flags: [{ name: "--max-chars=N", description: "Per-field cap (default 4000, 100-32000)." }],
|
|
372
|
-
examples: ["moda replays playout <set_id> <run_id> <playout_id> --json"]
|
|
373
|
-
}
|
|
374
|
-
];
|
|
375
|
-
function profileOptions(context) {
|
|
376
|
-
return { profile: context.profile, env: context.env };
|
|
377
|
-
}
|
|
378
|
-
function requireTenant(context) {
|
|
379
|
-
const key = resolveApiKey(profileOptions(context));
|
|
380
|
-
if (!key) {
|
|
381
|
-
throw new CliInputError("No Moda API key found for moda replays.", "Set MODA_API_KEY, run `moda auth login --api-key`, or select a profile with an API key.");
|
|
382
|
-
}
|
|
383
|
-
const keyTenant = embeddedTenantIdFromApiKey(key);
|
|
384
|
-
const flagTenant = context.flags["tenant-id"];
|
|
385
|
-
if (flagTenant && keyTenant && flagTenant !== keyTenant) {
|
|
386
|
-
throw new CliInputError(`--tenant-id=${flagTenant} does not match this API key's tenant (${keyTenant}), so nothing was sent.`, "Drop --tenant-id (the key names its tenant) or use a key for that tenant.");
|
|
387
|
-
}
|
|
388
|
-
const tenantId = flagTenant || resolveApiTenantId(profileOptions(context));
|
|
389
|
-
if (!tenantId) {
|
|
390
|
-
throw new CliInputError("Could not determine the tenant.", "Use a signed API key (it names its tenant), set MODA_TENANT_ID, or pass --tenant-id=<id>.");
|
|
391
|
-
}
|
|
392
|
-
if (isPlatformApiKey(key))
|
|
393
|
-
setPlatformTenantOverride(tenantId);
|
|
394
|
-
return tenantId;
|
|
395
|
-
}
|
|
396
|
-
function intFlag(name, value, min, max) {
|
|
397
|
-
if (value === undefined)
|
|
398
|
-
return;
|
|
399
|
-
const parsed = Number(value);
|
|
400
|
-
if (!Number.isInteger(parsed) || parsed < min || parsed > max) {
|
|
401
|
-
throw new CliInputError(`--${name} must be an integer from ${min} to ${max} (got '${value}').`);
|
|
402
|
-
}
|
|
403
|
-
return String(parsed);
|
|
404
|
-
}
|
|
405
|
-
function query(params) {
|
|
406
|
-
const search = new URLSearchParams(Object.entries(params).filter((entry) => entry[1] !== undefined)).toString();
|
|
407
|
-
return search ? `?${search}` : "";
|
|
408
|
-
}
|
|
409
|
-
function needArg(value, name, usage) {
|
|
410
|
-
if (!value)
|
|
411
|
-
throw new CliInputError(`<${name}> is required.`, `Usage: ${usage}`);
|
|
412
|
-
return value;
|
|
413
|
-
}
|
|
414
|
-
function needRunId(value, usage, allowLatest = false) {
|
|
415
|
-
const runId = needArg(value, "run_id", usage);
|
|
416
|
-
if (allowLatest && runId === "latest")
|
|
417
|
-
return runId;
|
|
418
|
-
if (!UUID_RE2.test(runId)) {
|
|
419
|
-
throw new CliInputError(`<run_id> must be a run UUID (got '${runId}').`, "List runs with `moda replays runs <set_id>`.");
|
|
420
|
-
}
|
|
421
|
-
return runId;
|
|
422
|
-
}
|
|
423
|
-
async function runReplaysCommand(context) {
|
|
424
|
-
const [subcommand, ...args] = context.positionals;
|
|
425
|
-
const flags = context.flags;
|
|
426
|
-
const help = REPLAYS_SUBCOMMAND_HELP.find((entry) => entry.name === subcommand);
|
|
427
|
-
if (!subcommand || !help) {
|
|
428
|
-
throw new CliInputError(subcommand ? `Unknown replays command '${subcommand}'.` : "A replays subcommand is required.", `Use one of: ${REPLAYS_SUBCOMMANDS.join(", ")}. See \`moda replays --help\`.`);
|
|
429
|
-
}
|
|
430
|
-
const usage = help.usage;
|
|
431
|
-
const allowed = {
|
|
432
|
-
sets: [],
|
|
433
|
-
runs: ["limit"],
|
|
434
|
-
run: [],
|
|
435
|
-
playouts: ["case", "arm", "seed", "transcript", "max-chars", "limit", "cursor"],
|
|
436
|
-
playout: ["max-chars"]
|
|
437
|
-
};
|
|
438
|
-
const name = subcommand;
|
|
439
|
-
assertFlags(`replays ${name}`, flags, [...allowed[name], "tenant-id"]);
|
|
440
|
-
const maxArgs = { sets: 0, runs: 1, run: 2, playouts: 2, playout: 3 }[name];
|
|
441
|
-
assertPositionals(`replays ${name}`, args, maxArgs, usage);
|
|
442
|
-
const tenantId = requireTenant(context);
|
|
443
|
-
const base = `/tenants/${encodeURIComponent(tenantId)}/replay-sets`;
|
|
444
|
-
let endpoint;
|
|
445
|
-
switch (name) {
|
|
446
|
-
case "sets":
|
|
447
|
-
endpoint = base;
|
|
448
|
-
break;
|
|
449
|
-
case "runs": {
|
|
450
|
-
const setId = needArg(args[0], "set_id", usage);
|
|
451
|
-
endpoint = `${base}/${encodeURIComponent(setId)}/runs${query({ limit: intFlag("limit", flags.limit, 1, 100) })}`;
|
|
452
|
-
break;
|
|
453
|
-
}
|
|
454
|
-
case "run": {
|
|
455
|
-
const setId = needArg(args[0], "set_id", usage);
|
|
456
|
-
const runId = needRunId(args[1], usage, true);
|
|
457
|
-
endpoint = runId === "latest" ? `${base}/${encodeURIComponent(setId)}/runs/latest` : `${base}/${encodeURIComponent(setId)}/runs/${encodeURIComponent(runId)}`;
|
|
458
|
-
break;
|
|
459
|
-
}
|
|
460
|
-
case "playouts": {
|
|
461
|
-
const setId = needArg(args[0], "set_id", usage);
|
|
462
|
-
const runId = needRunId(args[1], usage);
|
|
463
|
-
const arm = flags.arm;
|
|
464
|
-
if (arm !== undefined && !ARMS.includes(arm)) {
|
|
465
|
-
throw new CliInputError(`--arm must be one of ${ARMS.join(", ")} (got '${arm}').`);
|
|
466
|
-
}
|
|
467
|
-
if (flags.case !== undefined && (flags.case.length === 0 || flags.case.length > 128)) {
|
|
468
|
-
throw new CliInputError("--case must be a case id of 1 to 128 characters.");
|
|
469
|
-
}
|
|
470
|
-
if (flags.cursor !== undefined && !/^\d{1,9}$/.test(flags.cursor)) {
|
|
471
|
-
throw new CliInputError(`--cursor must be the nextCursor of a previous page (got '${flags.cursor}').`);
|
|
472
|
-
}
|
|
473
|
-
const transcript = flags.transcript === "true";
|
|
474
|
-
endpoint = `${base}/${encodeURIComponent(setId)}/runs/${encodeURIComponent(runId)}/playouts${query({
|
|
475
|
-
caseId: flags.case,
|
|
476
|
-
arm,
|
|
477
|
-
seed: intFlag("seed", flags.seed, 0, 1000),
|
|
478
|
-
include: transcript ? "transcript" : undefined,
|
|
479
|
-
maxChars: intFlag("max-chars", flags["max-chars"], 100, 32000),
|
|
480
|
-
limit: intFlag("limit", flags.limit, 1, transcript ? 10 : 200),
|
|
481
|
-
cursor: flags.cursor
|
|
482
|
-
})}`;
|
|
483
|
-
break;
|
|
484
|
-
}
|
|
485
|
-
case "playout": {
|
|
486
|
-
const setId = needArg(args[0], "set_id", usage);
|
|
487
|
-
const runId = needRunId(args[1], usage);
|
|
488
|
-
const playoutId = needArg(args[2], "playout_id", usage);
|
|
489
|
-
if (!PLAYOUT_ID_RE.test(playoutId)) {
|
|
490
|
-
throw new CliInputError(`<playout_id> must be a 64-character hex id (got '${playoutId}').`, "List playouts with `moda replays playouts <set_id> <run_id>`.");
|
|
491
|
-
}
|
|
492
|
-
endpoint = `${base}/${encodeURIComponent(setId)}/runs/${encodeURIComponent(runId)}/playouts/${encodeURIComponent(playoutId)}${query({
|
|
493
|
-
maxChars: intFlag("max-chars", flags["max-chars"], 100, 32000)
|
|
494
|
-
})}`;
|
|
495
|
-
break;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
const data = await callControlAPI(endpoint, { method: "GET" }, profileOptions(context), { timeoutMs: 60000 });
|
|
499
|
-
context.output.writeData(data ?? {});
|
|
500
|
-
return { exitCode: 0 };
|
|
501
|
-
}
|
|
502
|
-
|
|
503
317
|
// src/telemetry.ts
|
|
504
318
|
import { spawn as spawn2 } from "node:child_process";
|
|
505
319
|
|
|
@@ -808,8 +622,8 @@ var SEARCH_SURFACE_BY_COMMAND = {
|
|
|
808
622
|
context: "context"
|
|
809
623
|
};
|
|
810
624
|
var SEARCH_MODES = ["keyword", "semantic", "hybrid"];
|
|
811
|
-
function termCount(
|
|
812
|
-
return
|
|
625
|
+
function termCount(query) {
|
|
626
|
+
return query.trim().split(/\s+/).filter(Boolean).length;
|
|
813
627
|
}
|
|
814
628
|
function clampInt(value, min, max) {
|
|
815
629
|
if (typeof value !== "number" || !Number.isFinite(value))
|
|
@@ -2117,17 +1931,13 @@ var SKILLS_SUBCOMMAND_HELP = [
|
|
|
2117
1931
|
{
|
|
2118
1932
|
name: "gen",
|
|
2119
1933
|
description: "Generate skills from production traces (paid: clustering + LLM distillation; no dry-run)",
|
|
2120
|
-
usage: "moda skills gen [--source=all|sdk] [--max-sessions=N] [--lookback-hours=N] [--max-traces=N] [--
|
|
1934
|
+
usage: "moda skills gen [--source=all|sdk] [--max-sessions=N] [--lookback-hours=N] [--max-traces=N] [--start-at=ISO] [--end-at=ISO] [--wait]",
|
|
2121
1935
|
flags: [
|
|
2122
1936
|
{ name: "--source=all|sdk", description: "Which traces to learn from (default all)." },
|
|
2123
1937
|
{ name: "--max-sessions=<n>", description: "Sessions to process (server default 200). Must be 1 or more." },
|
|
2124
1938
|
{ name: "--lookback-hours=<n>", description: "Window to read (server default 720 = 30 days). Must be 1 or more." },
|
|
2125
1939
|
{ name: "--start-at=<iso>, --end-at=<iso>", description: "Explicit window instead of --lookback-hours." },
|
|
2126
1940
|
{ name: "--max-traces=<n>", description: "Cap on cluster traces loaded for distillation." },
|
|
2127
|
-
{ name: "--improve-candidates", description: "Run improvement rounds on candidate skills." },
|
|
2128
|
-
{ name: "--improvement-rounds=<1-3>", description: "Improvement rounds (default 2, max 3)." },
|
|
2129
|
-
{ name: "--replay", description: "Replay candidates against a replay set (extra paid playouts)." },
|
|
2130
|
-
{ name: "--replay-set-id=<id>", description: "Replay set for --replay." },
|
|
2131
1941
|
{ name: "--reprocess-segments", description: "Re-segment sessions that were already processed." },
|
|
2132
1942
|
{ name: "--force-reprocess", description: "Reprocess everything in the window (implies --reprocess-segments)." },
|
|
2133
1943
|
{ name: "--no-clustering", description: "Skip clustering; reuse --clustering-run-id." },
|
|
@@ -2235,12 +2045,6 @@ var PROMPTS_REGISTRY_SUBCOMMAND_HELP = [
|
|
|
2235
2045
|
usage: "moda prompts usage <key_or_id>",
|
|
2236
2046
|
examples: ["moda prompts usage support.triage"]
|
|
2237
2047
|
},
|
|
2238
|
-
{
|
|
2239
|
-
name: "replay-runs",
|
|
2240
|
-
description: "List replay (A/B) runs for a prompt (read-only)",
|
|
2241
|
-
usage: "moda prompts replay-runs <key_or_id>",
|
|
2242
|
-
examples: ["moda prompts replay-runs support.triage"]
|
|
2243
|
-
},
|
|
2244
2048
|
{
|
|
2245
2049
|
name: "decide",
|
|
2246
2050
|
description: "Merge, reject, or reopen a prompt revision proposal",
|
|
@@ -2457,91 +2261,6 @@ var HARNESS_SUBCOMMAND_HELP = [
|
|
|
2457
2261
|
examples: ["moda harness diff my-harness-key --from=hver_a --to=hver_b"]
|
|
2458
2262
|
}
|
|
2459
2263
|
];
|
|
2460
|
-
var FIX_TIMEOUT = { name: "--timeout=<ms>", description: "How long to wait, in milliseconds (max 86400000)." };
|
|
2461
|
-
var FIX_POLL = { name: "--poll-interval=<ms>", description: "Polling interval while waiting, in milliseconds." };
|
|
2462
|
-
var FIXES_SUBCOMMAND_HELP = [
|
|
2463
|
-
{
|
|
2464
|
-
name: "draft-batch",
|
|
2465
|
-
description: "Draft Fixes for the top unfixed Problems (no LLM call itself; spend happens when they are driven)",
|
|
2466
|
-
usage: "moda fixes draft-batch [--limit=N]",
|
|
2467
|
-
flags: [{ name: "--limit=N", description: "How many Problems to draft for (1-25, default 5)." }, TENANT_ID],
|
|
2468
|
-
examples: ["moda fixes draft-batch --limit=3"]
|
|
2469
|
-
},
|
|
2470
|
-
{
|
|
2471
|
-
name: "drive",
|
|
2472
|
-
description: "Advance active Fixes through scoping, proposing, and gating (paid: each fix runs LLM calls and replay playouts)",
|
|
2473
|
-
usage: "moda fixes drive [--status=S] [--max-fixes=N] [--timeout=ms] [--pass-interval=ms]",
|
|
2474
|
-
flags: [
|
|
2475
|
-
{ name: "--max-fixes=N", description: "Spend cap: advance at most N fixes this run (1-10, default 3). GATING fixes count too; each run takes the least-recently-driven fixes first, so re-runs reach every fix." },
|
|
2476
|
-
{ name: "--status=S", description: "Only drive fixes in this status." },
|
|
2477
|
-
FIX_TIMEOUT,
|
|
2478
|
-
{ name: "--pass-interval=<ms>", description: "Pause between passes, in milliseconds." },
|
|
2479
|
-
TENANT_ID
|
|
2480
|
-
],
|
|
2481
|
-
examples: ["moda fixes drive", "moda fixes drive --max-fixes=1 --status=SCOPING"]
|
|
2482
|
-
}
|
|
2483
|
-
];
|
|
2484
|
-
var FIX_SUBCOMMAND_HELP = [
|
|
2485
|
-
{
|
|
2486
|
-
name: "start",
|
|
2487
|
-
description: "Start a Fix for a Problem (paid: scoping, a proposal, and a replay gate)",
|
|
2488
|
-
usage: "moda fix start <problem_id> [--type=auto|prompt] [--wait] [--timeout=ms]",
|
|
2489
|
-
flags: [
|
|
2490
|
-
{ name: "--type=auto|prompt", description: "Fix type (default auto)." },
|
|
2491
|
-
{ name: "--wait", description: "Wait for the gate verdict." },
|
|
2492
|
-
FIX_TIMEOUT,
|
|
2493
|
-
FIX_POLL,
|
|
2494
|
-
TENANT_ID
|
|
2495
|
-
],
|
|
2496
|
-
examples: ["moda fix start <problem_id> --wait"]
|
|
2497
|
-
},
|
|
2498
|
-
{
|
|
2499
|
-
name: "verify",
|
|
2500
|
-
description: "Re-gate a Fix, optionally with a new candidate prompt (paid: replay playouts)",
|
|
2501
|
-
usage: "moda fix verify <fix_id> [--prompt-file=PATH] [--no-wait] [--timeout=ms] [--yes]",
|
|
2502
|
-
flags: [
|
|
2503
|
-
{ name: "--prompt-file=PATH", description: "Candidate prompt to gate. New content skips the 10-minute re-gate cooldown; unchanged content does not." },
|
|
2504
|
-
{ name: "--no-wait", description: "Return once the gate is enqueued." },
|
|
2505
|
-
{ name: "--yes", description: "Re-gate inside the 10-minute cooldown anyway." },
|
|
2506
|
-
FIX_TIMEOUT,
|
|
2507
|
-
FIX_POLL,
|
|
2508
|
-
TENANT_ID
|
|
2509
|
-
],
|
|
2510
|
-
examples: ["moda fix verify <fix_id> --prompt-file=prompts/agent.prompt.md"]
|
|
2511
|
-
},
|
|
2512
|
-
{
|
|
2513
|
-
name: "checkout",
|
|
2514
|
-
description: "Write the Fix's candidate into your working tree",
|
|
2515
|
-
usage: "moda fix checkout <fix_id>",
|
|
2516
|
-
flags: [TENANT_ID],
|
|
2517
|
-
examples: ["moda fix checkout <fix_id>"]
|
|
2518
|
-
},
|
|
2519
|
-
{
|
|
2520
|
-
name: "submit",
|
|
2521
|
-
description: "Open a PR for a verified Fix, or record a local branch",
|
|
2522
|
-
usage: "moda fix submit <fix_id> --pr | --local-ref=<branch>",
|
|
2523
|
-
flags: [
|
|
2524
|
-
{ name: "--pr", description: "Open a pull request." },
|
|
2525
|
-
{ name: "--local-ref=<branch>", description: "Record a branch you pushed yourself." },
|
|
2526
|
-
TENANT_ID
|
|
2527
|
-
],
|
|
2528
|
-
examples: ["moda fix submit <fix_id> --pr"]
|
|
2529
|
-
},
|
|
2530
|
-
{
|
|
2531
|
-
name: "mark-applied",
|
|
2532
|
-
description: "Mark a Fix as applied outside Moda",
|
|
2533
|
-
usage: "moda fix mark-applied <fix_id> [--note=TEXT]",
|
|
2534
|
-
flags: [{ name: "--note=TEXT", description: "Where or how it was applied." }, TENANT_ID],
|
|
2535
|
-
examples: ['moda fix mark-applied <fix_id> --note="tool description updated in our agent config"']
|
|
2536
|
-
},
|
|
2537
|
-
{
|
|
2538
|
-
name: "dismiss",
|
|
2539
|
-
description: "Dismiss a Fix (no dry-run mode)",
|
|
2540
|
-
usage: "moda fix dismiss <fix_id> --reason=TEXT",
|
|
2541
|
-
flags: [{ name: "--reason=TEXT", description: "Required. Why it is dismissed." }, TENANT_ID],
|
|
2542
|
-
examples: ['moda fix dismiss <fix_id> --reason="not actionable"']
|
|
2543
|
-
}
|
|
2544
|
-
];
|
|
2545
2264
|
|
|
2546
2265
|
// src/agent-schemas.ts
|
|
2547
2266
|
var agentSummarySchema = {
|
|
@@ -3248,46 +2967,40 @@ function leafManifestFields(leaf, commands) {
|
|
|
3248
2967
|
import { fileURLToPath } from "url";
|
|
3249
2968
|
import { realpathSync } from "fs";
|
|
3250
2969
|
async function runPromptsCommand(...args) {
|
|
3251
|
-
return (await import("./prompts-
|
|
2970
|
+
return (await import("./prompts-b6awryvv.js")).runPromptsCommand(...args);
|
|
3252
2971
|
}
|
|
3253
2972
|
async function runSkillsCommand(...args) {
|
|
3254
|
-
return (await import("./skills-
|
|
3255
|
-
}
|
|
3256
|
-
async function runFixCommand(...args) {
|
|
3257
|
-
return (await import("./fix-nk5xffz8.js")).runFixCommand(...args);
|
|
3258
|
-
}
|
|
3259
|
-
async function runFixesCommand(...args) {
|
|
3260
|
-
return (await import("./fix-nk5xffz8.js")).runFixesCommand(...args);
|
|
2973
|
+
return (await import("./skills-zfenne8w.js")).runSkillsCommand(...args);
|
|
3261
2974
|
}
|
|
3262
2975
|
async function runHarnessCommand(...args) {
|
|
3263
|
-
return (await import("./harness-
|
|
2976
|
+
return (await import("./harness-cy0gpyhj.js")).runHarnessCommand(...args);
|
|
3264
2977
|
}
|
|
3265
2978
|
async function runSyncCommand(...args) {
|
|
3266
|
-
return (await import("./sync-
|
|
2979
|
+
return (await import("./sync-5vd8gwte.js")).runSyncCommand(...args);
|
|
3267
2980
|
}
|
|
3268
2981
|
async function runRegistryCommand(...args) {
|
|
3269
|
-
return (await import("./registry-
|
|
2982
|
+
return (await import("./registry-d7xdm4dw.js")).runRegistryCommand(...args);
|
|
3270
2983
|
}
|
|
3271
2984
|
async function runDoctorCommand(...args) {
|
|
3272
|
-
return (await import("./doctor-
|
|
2985
|
+
return (await import("./doctor-fz5kq44d.js")).runDoctorCommand(...args);
|
|
3273
2986
|
}
|
|
3274
2987
|
async function runStatusCommand(...args) {
|
|
3275
|
-
return (await import("./doctor-
|
|
2988
|
+
return (await import("./doctor-fz5kq44d.js")).runStatusCommand(...args);
|
|
3276
2989
|
}
|
|
3277
2990
|
async function runAuthCommand(...args) {
|
|
3278
|
-
return (await import("./profile-commands-
|
|
2991
|
+
return (await import("./profile-commands-zbyn9xg2.js")).runAuthCommand(...args);
|
|
3279
2992
|
}
|
|
3280
2993
|
async function runConfigCommand(...args) {
|
|
3281
|
-
return (await import("./profile-commands-
|
|
2994
|
+
return (await import("./profile-commands-zbyn9xg2.js")).runConfigCommand(...args);
|
|
3282
2995
|
}
|
|
3283
2996
|
async function runProfilesCommand(...args) {
|
|
3284
|
-
return (await import("./profile-commands-
|
|
2997
|
+
return (await import("./profile-commands-zbyn9xg2.js")).runProfilesCommand(...args);
|
|
3285
2998
|
}
|
|
3286
2999
|
async function runAgentCommand(...args) {
|
|
3287
|
-
return (await import("./agent-
|
|
3000
|
+
return (await import("./agent-aewgndk0.js")).runAgentCommand(...args);
|
|
3288
3001
|
}
|
|
3289
3002
|
async function runProductionCommand(...args) {
|
|
3290
|
-
return (await import("./production-intelligence-
|
|
3003
|
+
return (await import("./production-intelligence-8j8008d2.js")).runProductionCommand(...args);
|
|
3291
3004
|
}
|
|
3292
3005
|
function parseArgs(argv) {
|
|
3293
3006
|
const args = argv.slice(2);
|
|
@@ -3332,27 +3045,18 @@ var RAW_BOOLEAN_FLAGS = new Set([
|
|
|
3332
3045
|
"live",
|
|
3333
3046
|
"local",
|
|
3334
3047
|
"watch",
|
|
3335
|
-
"promote",
|
|
3336
|
-
"no-promote",
|
|
3337
|
-
"promote-on-win",
|
|
3338
3048
|
"undo",
|
|
3339
3049
|
"all",
|
|
3340
3050
|
"wait",
|
|
3341
|
-
"no-wait",
|
|
3342
3051
|
"wait-for-completion",
|
|
3343
3052
|
"summary",
|
|
3344
3053
|
"list",
|
|
3345
3054
|
"save",
|
|
3346
3055
|
"sync",
|
|
3347
3056
|
"replay",
|
|
3348
|
-
"no-replay",
|
|
3349
3057
|
"remote",
|
|
3350
3058
|
"no-remote",
|
|
3351
3059
|
"raw",
|
|
3352
|
-
"pr",
|
|
3353
|
-
"packet",
|
|
3354
|
-
"transcript",
|
|
3355
|
-
"gate",
|
|
3356
3060
|
"discover",
|
|
3357
3061
|
"experimental",
|
|
3358
3062
|
"force",
|
|
@@ -3369,10 +3073,7 @@ var RAW_BOOLEAN_FLAGS = new Set([
|
|
|
3369
3073
|
"github-actions",
|
|
3370
3074
|
"no-clustering",
|
|
3371
3075
|
"no-analyze",
|
|
3372
|
-
"improve-candidates",
|
|
3373
|
-
"auto-generate",
|
|
3374
3076
|
"allow-no-agents",
|
|
3375
|
-
"allow-any-model",
|
|
3376
3077
|
"json",
|
|
3377
3078
|
"human",
|
|
3378
3079
|
"prose",
|
|
@@ -3613,8 +3314,7 @@ Setup:
|
|
|
3613
3314
|
|
|
3614
3315
|
Groups with their own subcommands (run 'moda <group> --help'):
|
|
3615
3316
|
harness Analyze, scan, validate, approve, sync and register the agent harness
|
|
3616
|
-
prompts Code-first prompt versions: init, status, sync, promote,
|
|
3617
|
-
replays Replay results: sets, runs, playouts and transcripts
|
|
3317
|
+
prompts Code-first prompt versions: init, status, sync, promote, list, show
|
|
3618
3318
|
skills Generate skills; pull (download), push (upload), install
|
|
3619
3319
|
sync Sync the harness graph and prompts to Moda Cloud
|
|
3620
3320
|
registry Push prompts, skills, tools and agent wiring from one JSON manifest
|
|
@@ -3928,10 +3628,10 @@ async function attachWindows(rows, windowSize, budgetBytes) {
|
|
|
3928
3628
|
return { ...row, window: conversation };
|
|
3929
3629
|
}
|
|
3930
3630
|
try {
|
|
3931
|
-
const
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
const data = await callDataAPI(`/conversations/${conv_id}/context?${
|
|
3631
|
+
const query = new URLSearchParams;
|
|
3632
|
+
query.set("msg_index", msg_index.toString());
|
|
3633
|
+
query.set("window", windowSize.toString());
|
|
3634
|
+
const data = await callDataAPI(`/conversations/${conv_id}/context?${query.toString()}`);
|
|
3935
3635
|
return { ...row, window: data };
|
|
3936
3636
|
} catch (err) {
|
|
3937
3637
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -4014,8 +3714,8 @@ var AUDIT_AGENT_RESERVE_BYTES = 16384;
|
|
|
4014
3714
|
function auditMaxBytes(budgetBytes) {
|
|
4015
3715
|
return Math.max(1, budgetBytes - Math.min(AUDIT_AGENT_RESERVE_BYTES, Math.floor(budgetBytes / 4)));
|
|
4016
3716
|
}
|
|
4017
|
-
async function fetchAudit(id,
|
|
4018
|
-
const pageQuery = new URLSearchParams(
|
|
3717
|
+
async function fetchAudit(id, query, maxBytes) {
|
|
3718
|
+
const pageQuery = new URLSearchParams(query);
|
|
4019
3719
|
if (maxBytes !== undefined)
|
|
4020
3720
|
pageQuery.set("max_bytes", maxBytes.toString());
|
|
4021
3721
|
const queryString = pageQuery.toString() ? `?${pageQuery.toString()}` : "";
|
|
@@ -4518,7 +4218,7 @@ function searchDegradeWarning(reason, requestedMode, coverage) {
|
|
|
4518
4218
|
return `${lead} the requested ${requestedMode} ranking did not run, and ${notComparable}. Use --mode=keyword with exact identifiers.`;
|
|
4519
4219
|
}
|
|
4520
4220
|
}
|
|
4521
|
-
function searchOutcomeWarnings(record, requestedFlag,
|
|
4221
|
+
function searchOutcomeWarnings(record, requestedFlag, query) {
|
|
4522
4222
|
const warnings = [];
|
|
4523
4223
|
const requested = asString(record.requested_mode) ?? requestedFlag ?? "hybrid";
|
|
4524
4224
|
const actual = asString(record.search_mode);
|
|
@@ -4533,7 +4233,7 @@ function searchOutcomeWarnings(record, requestedFlag, query2) {
|
|
|
4533
4233
|
const match = asRecord(asRecord(record.coverage)?.keyword_match);
|
|
4534
4234
|
const minTerms = asNumber(match?.min_terms) ?? undefined;
|
|
4535
4235
|
const dropped = asNumber(match?.dropped_non_matching) ?? 0;
|
|
4536
|
-
warnings.push(`No message in this window contains "${
|
|
4236
|
+
warnings.push(`No message in this window contains "${query}"` + (minTerms !== undefined ? ` or at least ${minTerms} of its significant terms` : "") + ` (case-insensitive substring match${degraded ? `, served as keyword because the ${requested} ranking did not run` : ""}).` + (dropped > 0 ? ` ${dropped} index neighbour(s) that only shared a word were not returned.` : "") + " Retry with a shorter exact phrase or identifier, widen --time-range, add --include-tool-io for tool calls/results, or rephrase.");
|
|
4537
4237
|
}
|
|
4538
4238
|
return warnings;
|
|
4539
4239
|
}
|
|
@@ -4557,19 +4257,19 @@ function searchCoverageWarnings(coverage, timeRange) {
|
|
|
4557
4257
|
async function searchFallbackToTraces(params) {
|
|
4558
4258
|
const limit = Math.min(params.limit ?? 20, 100);
|
|
4559
4259
|
const offset = params.offset ?? 0;
|
|
4560
|
-
const
|
|
4561
|
-
|
|
4260
|
+
const query = new URLSearchParams;
|
|
4261
|
+
query.set("search", params.q);
|
|
4562
4262
|
if (params.user_id)
|
|
4563
|
-
|
|
4263
|
+
query.set("user_id", params.user_id);
|
|
4564
4264
|
if (params.time_range)
|
|
4565
|
-
|
|
4265
|
+
query.set("time_range", params.time_range);
|
|
4566
4266
|
if (params.since)
|
|
4567
|
-
|
|
4267
|
+
query.set("since", params.since);
|
|
4568
4268
|
if (params.until)
|
|
4569
|
-
|
|
4570
|
-
|
|
4269
|
+
query.set("until", params.until);
|
|
4270
|
+
query.set("limit", String(limit));
|
|
4571
4271
|
if (offset > 0)
|
|
4572
|
-
|
|
4272
|
+
query.set("offset", String(offset));
|
|
4573
4273
|
const tracesCommand = [
|
|
4574
4274
|
`moda traces --search=${shellArg(params.q)}`,
|
|
4575
4275
|
params.user_id ? `--user-id=${shellArg(params.user_id)}` : "",
|
|
@@ -4587,7 +4287,7 @@ async function searchFallbackToTraces(params) {
|
|
|
4587
4287
|
}
|
|
4588
4288
|
let traces;
|
|
4589
4289
|
try {
|
|
4590
|
-
traces = asRecord(await callDataAPI(`/conversations?${
|
|
4290
|
+
traces = asRecord(await callDataAPI(`/conversations?${query.toString()}`)) ?? {};
|
|
4591
4291
|
} catch (error) {
|
|
4592
4292
|
const reason = error instanceof Error ? error.message : String(error);
|
|
4593
4293
|
return {
|
|
@@ -4776,16 +4476,16 @@ function normalizeBooleanFlags(target) {
|
|
|
4776
4476
|
var PROFILE_MANAGING_COMMANDS = new Set(["profiles", "auth", "init", "provision", "status", "config", "manifest", "agent", "doctor"]);
|
|
4777
4477
|
async function runProblemsRemainder(flags, context) {
|
|
4778
4478
|
const params = parseCommandFlags(ProblemsRemainderSchema, flagsToArgs(flags), "problems remainder", specParseOptions(COMMAND_FLAG_SPECS.problems.subcommands.remainder));
|
|
4779
|
-
const
|
|
4479
|
+
const query = new URLSearchParams;
|
|
4780
4480
|
if (params.days_back)
|
|
4781
|
-
|
|
4481
|
+
query.set("days_back", params.days_back.toString());
|
|
4782
4482
|
if (params.limit)
|
|
4783
|
-
|
|
4483
|
+
query.set("limit", params.limit.toString());
|
|
4784
4484
|
if (params.family)
|
|
4785
|
-
|
|
4485
|
+
query.set("family", params.family);
|
|
4786
4486
|
if (params.cursor)
|
|
4787
|
-
|
|
4788
|
-
const queryString =
|
|
4487
|
+
query.set("cursor", params.cursor);
|
|
4488
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
4789
4489
|
context.output.writeData(await callDataAPI(`/problems/remainder${queryString}`));
|
|
4790
4490
|
}
|
|
4791
4491
|
var isDreamOnlySort = (sort) => sort === "severity" || sort === "silent";
|
|
@@ -4841,24 +4541,24 @@ async function runProblemsList(flags, context, command) {
|
|
|
4841
4541
|
throw new CliInputError("--list-version pages a list: pass it with the --offset of the next page (next_offset).");
|
|
4842
4542
|
}
|
|
4843
4543
|
if (view !== "book") {
|
|
4844
|
-
const
|
|
4544
|
+
const query2 = new URLSearchParams;
|
|
4845
4545
|
if (daysGiven && params.days_back !== undefined)
|
|
4846
|
-
|
|
4546
|
+
query2.set("days_back", String(params.days_back));
|
|
4847
4547
|
if (params.cohort)
|
|
4848
|
-
|
|
4548
|
+
query2.set("cohort", params.cohort);
|
|
4849
4549
|
const bookOnly = isBookOnlySort(params.sort);
|
|
4850
|
-
|
|
4550
|
+
query2.set("limit", String(bookOnly ? 1 : limit));
|
|
4851
4551
|
if (!bookOnly) {
|
|
4852
4552
|
if (offset > 0)
|
|
4853
|
-
|
|
4553
|
+
query2.set("offset", String(offset));
|
|
4854
4554
|
if (params.list_version)
|
|
4855
|
-
|
|
4555
|
+
query2.set("list_version", params.list_version);
|
|
4856
4556
|
if (params.sort && params.sort !== "rank")
|
|
4857
|
-
|
|
4557
|
+
query2.set("sort", params.sort);
|
|
4858
4558
|
if (params.dir)
|
|
4859
|
-
|
|
4559
|
+
query2.set("dir", params.dir);
|
|
4860
4560
|
}
|
|
4861
|
-
const dream = asRecord(await callDataAPI(`/problems/dream?${
|
|
4561
|
+
const dream = asRecord(await callDataAPI(`/problems/dream?${query2.toString()}`)) ?? {};
|
|
4862
4562
|
if (dream.available === true) {
|
|
4863
4563
|
if (bookOnly) {
|
|
4864
4564
|
throw new CliInputError(`This tenant's dashboard shows the dream grouping of its Problems, which --sort=${params.sort} does not order.`, `Use --sort=rank|${DREAM_PROBLEM_SORTS.join("|")} for the dream view, or --view=book --sort=${params.sort} for the Book's ranked list.`);
|
|
@@ -4877,20 +4577,20 @@ async function runProblemsList(flags, context, command) {
|
|
|
4877
4577
|
if (isDreamOnlySort(params.sort)) {
|
|
4878
4578
|
throw new CliInputError(`This tenant has no dream grouping published, so its Problems are the Book's ranked list, which --sort=${params.sort} does not order.`, `Use --sort=${BOOK_PROBLEM_SORTS.join("|")} or signal:<family>.`);
|
|
4879
4579
|
}
|
|
4880
|
-
const
|
|
4881
|
-
|
|
4882
|
-
|
|
4580
|
+
const query = new URLSearchParams;
|
|
4581
|
+
query.set("days_back", String(params.days_back ?? 30));
|
|
4582
|
+
query.set("limit", String(limit));
|
|
4883
4583
|
if (offset > 0)
|
|
4884
|
-
|
|
4584
|
+
query.set("offset", String(offset));
|
|
4885
4585
|
if (params.list_version)
|
|
4886
|
-
|
|
4586
|
+
query.set("list_version", params.list_version);
|
|
4887
4587
|
if (params.sort)
|
|
4888
|
-
|
|
4588
|
+
query.set("sort", params.sort);
|
|
4889
4589
|
if (params.dir)
|
|
4890
|
-
|
|
4590
|
+
query.set("dir", params.dir);
|
|
4891
4591
|
if (params.cohort)
|
|
4892
|
-
|
|
4893
|
-
const data = await callDataAPI(`/problems?${
|
|
4592
|
+
query.set("cohort", params.cohort);
|
|
4593
|
+
const data = await callDataAPI(`/problems?${query.toString()}`);
|
|
4894
4594
|
const { payload: capped, truncated } = capProblemsBlocks(asRecord(data) ?? {}, limit);
|
|
4895
4595
|
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
4896
4596
|
const payload = agentMode ? hierarchyForPage(capped) : capped;
|
|
@@ -4988,13 +4688,13 @@ async function runDreamProblem(params, context, command) {
|
|
|
4988
4688
|
}
|
|
4989
4689
|
const limit = params.limit ?? DREAM_INCIDENTS_DEFAULT_LIMIT;
|
|
4990
4690
|
const offset = params.offset ?? 0;
|
|
4991
|
-
const
|
|
4691
|
+
const query = new URLSearchParams({ limit: String(limit) });
|
|
4992
4692
|
if (offset > 0)
|
|
4993
|
-
|
|
4693
|
+
query.set("offset", String(offset));
|
|
4994
4694
|
if (params.days_back !== undefined)
|
|
4995
|
-
|
|
4695
|
+
query.set("days_back", String(params.days_back));
|
|
4996
4696
|
const id = shellArg(params.id);
|
|
4997
|
-
const data = asRecord(await callDataAPI(`/problems/dream/${encodeURIComponent(params.id)}?${
|
|
4697
|
+
const data = asRecord(await callDataAPI(`/problems/dream/${encodeURIComponent(params.id)}?${query.toString()}`).catch((error) => {
|
|
4998
4698
|
if (error instanceof ApiError && error.statusCode === 404) {
|
|
4999
4699
|
throwIfNotFound("problem", params.id, true, `Problem "${params.id}" is not in this tenant's dream grouping; read its dossier with: moda problems get ${id}`);
|
|
5000
4700
|
}
|
|
@@ -5067,16 +4767,16 @@ function readsPerTrace(command, params, perRowScopes) {
|
|
|
5067
4767
|
}
|
|
5068
4768
|
return perTrace;
|
|
5069
4769
|
}
|
|
5070
|
-
function setTraceFilters(
|
|
5071
|
-
|
|
4770
|
+
function setTraceFilters(query, params, keys) {
|
|
4771
|
+
query.set("group_by", "trace");
|
|
5072
4772
|
for (const key of keys) {
|
|
5073
4773
|
const value = params[key];
|
|
5074
4774
|
if (value === undefined)
|
|
5075
4775
|
continue;
|
|
5076
4776
|
if (key === "signal")
|
|
5077
|
-
|
|
4777
|
+
query.set("signals", String(value).split(",").map((part) => part.trim()).join(","));
|
|
5078
4778
|
else
|
|
5079
|
-
|
|
4779
|
+
query.set(key, String(value));
|
|
5080
4780
|
}
|
|
5081
4781
|
}
|
|
5082
4782
|
function cohortScope(cohort, data) {
|
|
@@ -5210,13 +4910,13 @@ function parseContextRequest(positional, rawFlags) {
|
|
|
5210
4910
|
}
|
|
5211
4911
|
return { params, warnings };
|
|
5212
4912
|
}
|
|
5213
|
-
async function readContextMetadataOnly(contextPath,
|
|
4913
|
+
async function readContextMetadataOnly(contextPath, query) {
|
|
5214
4914
|
try {
|
|
5215
|
-
return await callDataAPI(`${contextPath}?${
|
|
4915
|
+
return await callDataAPI(`${contextPath}?${query.toString()}`);
|
|
5216
4916
|
} catch (error) {
|
|
5217
4917
|
if (!(error instanceof ApiError) || error.statusCode !== 400 || !/metadata_only/.test(error.message))
|
|
5218
4918
|
throw error;
|
|
5219
|
-
const legacy = new URLSearchParams(
|
|
4919
|
+
const legacy = new URLSearchParams(query);
|
|
5220
4920
|
legacy.delete("metadata_only");
|
|
5221
4921
|
legacy.set("window", "0");
|
|
5222
4922
|
const data = asRecord(await callDataAPI(`${contextPath}?${legacy.toString()}`)) ?? {};
|
|
@@ -5366,17 +5066,17 @@ async function readContextItem(params, inputWarnings, budget) {
|
|
|
5366
5066
|
}
|
|
5367
5067
|
};
|
|
5368
5068
|
}
|
|
5369
|
-
const
|
|
5069
|
+
const query = new URLSearchParams;
|
|
5370
5070
|
if (params.msg_index !== undefined)
|
|
5371
|
-
|
|
5071
|
+
query.set("msg_index", params.msg_index.toString());
|
|
5372
5072
|
if (params.metadata_only === true)
|
|
5373
|
-
|
|
5073
|
+
query.set("metadata_only", "1");
|
|
5374
5074
|
const window = params.window === undefined ? undefined : Math.min(params.window, CONTEXT_MAX_WINDOW);
|
|
5375
5075
|
if (window !== undefined)
|
|
5376
|
-
|
|
5377
|
-
const queryString =
|
|
5076
|
+
query.set("window", window.toString());
|
|
5077
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
5378
5078
|
const contextPath = `/conversations/${encodeURIComponent(params.conversation_id)}/context`;
|
|
5379
|
-
const data = params.metadata_only === true ? await readContextMetadataOnly(contextPath,
|
|
5079
|
+
const data = params.metadata_only === true ? await readContextMetadataOnly(contextPath, query) : await callDataAPI(`${contextPath}${queryString}`);
|
|
5380
5080
|
const ctxRecord = asRecord(data) ?? {};
|
|
5381
5081
|
throwIfNotFound("trace", params.conversation_id, asNumber(ctxRecord.total_messages) === 0);
|
|
5382
5082
|
const warnings = [...inputWarnings, ...singleTraceStateWarnings(ctxRecord.trace_state)];
|
|
@@ -5465,19 +5165,19 @@ function trimContextWindow(conversationId, record, requestedAnchor, fits) {
|
|
|
5465
5165
|
var AUDIT_USAGE = "Usage: moda traces spans <conversation_id|trace_id> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] [--cursor=<next_cursor>]";
|
|
5466
5166
|
var AUDIT_BATCH_USAGE = `Usage: moda traces spans <id> <id> ... | --ids-from=-|<file> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] (max ${BATCH_MAX_TARGETS} targets)`;
|
|
5467
5167
|
async function readAuditItem(command, params, budget) {
|
|
5468
|
-
const
|
|
5168
|
+
const query = new URLSearchParams;
|
|
5469
5169
|
if (params.kind && params.kind !== "auto")
|
|
5470
|
-
|
|
5170
|
+
query.set("kind", params.kind);
|
|
5471
5171
|
if (params.include_raw === true)
|
|
5472
|
-
|
|
5172
|
+
query.set("include_raw", "1");
|
|
5473
5173
|
if (params.include_bodies === true)
|
|
5474
|
-
|
|
5174
|
+
query.set("include_bodies", "1");
|
|
5475
5175
|
if (params.limit)
|
|
5476
|
-
|
|
5176
|
+
query.set("limit", params.limit.toString());
|
|
5477
5177
|
if (params.cursor)
|
|
5478
|
-
|
|
5178
|
+
query.set("cursor", params.cursor);
|
|
5479
5179
|
const pageBytes = params.page_bytes ?? (budget ? auditMaxBytes(budget.maxBytes) : undefined);
|
|
5480
|
-
const raw = await fetchAudit(params.id,
|
|
5180
|
+
const raw = await fetchAudit(params.id, query, pageBytes);
|
|
5481
5181
|
params = { ...params, page_bytes: pageBytes };
|
|
5482
5182
|
const whole = auditOutput(command, params, raw);
|
|
5483
5183
|
if (!budget || budget.fits(whole.data, whole.options))
|
|
@@ -5799,20 +5499,20 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5799
5499
|
}
|
|
5800
5500
|
if (params.search !== undefined || params.node_id !== undefined) {
|
|
5801
5501
|
rejectInapplicableFlags(command, params, params.cohort ? ["parent_id"] : ["parent_id", "time_range"], "to a cluster search (--search/--node-id); they page the cluster hierarchy");
|
|
5802
|
-
const
|
|
5502
|
+
const query2 = new URLSearchParams;
|
|
5803
5503
|
if (params.search !== undefined)
|
|
5804
|
-
|
|
5504
|
+
query2.set("q", params.search);
|
|
5805
5505
|
if (params.node_id !== undefined)
|
|
5806
|
-
|
|
5506
|
+
query2.set("node_id", params.node_id);
|
|
5807
5507
|
if (params.mode)
|
|
5808
|
-
|
|
5508
|
+
query2.set("mode", params.mode);
|
|
5809
5509
|
if (params.limit)
|
|
5810
|
-
|
|
5510
|
+
query2.set("limit", params.limit.toString());
|
|
5811
5511
|
if (params.cohort)
|
|
5812
|
-
|
|
5512
|
+
query2.set("cohort", params.cohort);
|
|
5813
5513
|
if (params.cohort && params.time_range)
|
|
5814
|
-
|
|
5815
|
-
const data2 = await callDataAPI(`/task-clusters/search?${
|
|
5514
|
+
query2.set("time_range", params.time_range);
|
|
5515
|
+
const data2 = await callDataAPI(`/task-clusters/search?${query2.toString()}`);
|
|
5816
5516
|
const record = asRecord(data2) ?? {};
|
|
5817
5517
|
const matches = Array.isArray(record.matches) ? record.matches : [];
|
|
5818
5518
|
const warnings = params.node_id !== undefined && matches.length === 0 ? [`No cluster matched node id "${params.node_id}" for this search${params.cohort ? " within the cohort" : ""}. ${NOT_FOUND_HINTS.cluster}`] : [];
|
|
@@ -5820,14 +5520,14 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5820
5520
|
break;
|
|
5821
5521
|
}
|
|
5822
5522
|
rejectInapplicableFlags(command, params, ["mode", "limit"], "without --search or --node-id; they shape a cluster search");
|
|
5823
|
-
const
|
|
5523
|
+
const query = new URLSearchParams;
|
|
5824
5524
|
if (params.parent_id)
|
|
5825
|
-
|
|
5525
|
+
query.set("parent_id", params.parent_id);
|
|
5826
5526
|
if (params.time_range)
|
|
5827
|
-
|
|
5527
|
+
query.set("time_range", params.time_range);
|
|
5828
5528
|
if (params.cohort)
|
|
5829
|
-
|
|
5830
|
-
const queryString =
|
|
5529
|
+
query.set("cohort", params.cohort);
|
|
5530
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
5831
5531
|
const data = await callDataAPI(`/clusters${queryString}`);
|
|
5832
5532
|
context.output.writeData(data, withCohortScope(params.cohort, data));
|
|
5833
5533
|
break;
|
|
@@ -5839,12 +5539,12 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5839
5539
|
}
|
|
5840
5540
|
const args = flagsToArgs(flags, "node_id", positional);
|
|
5841
5541
|
const params = parseSpecFlags("cluster-traces", args, command);
|
|
5842
|
-
const
|
|
5542
|
+
const query = new URLSearchParams;
|
|
5843
5543
|
if (params.limit)
|
|
5844
|
-
|
|
5544
|
+
query.set("limit", params.limit.toString());
|
|
5845
5545
|
if (params.offset !== undefined)
|
|
5846
|
-
|
|
5847
|
-
const queryString =
|
|
5546
|
+
query.set("offset", params.offset.toString());
|
|
5547
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
5848
5548
|
const data = await callDataAPI(`/clusters/${encodeURIComponent(params.node_id)}/conversations${queryString}`);
|
|
5849
5549
|
const clusterRecord = asRecord(data) ?? {};
|
|
5850
5550
|
throwIfNotFound("cluster", params.node_id, clusterRecord.cluster === null || clusterRecord.cluster === undefined);
|
|
@@ -5855,34 +5555,34 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5855
5555
|
case "conversations": {
|
|
5856
5556
|
const args = flagsToArgs(flags);
|
|
5857
5557
|
const params = parseSpecFlags("traces", args, command);
|
|
5858
|
-
const
|
|
5558
|
+
const query = new URLSearchParams;
|
|
5859
5559
|
if (params.search)
|
|
5860
|
-
|
|
5560
|
+
query.set("search", params.search);
|
|
5861
5561
|
if (params.cluster_id)
|
|
5862
|
-
|
|
5562
|
+
query.set("cluster_id", params.cluster_id);
|
|
5863
5563
|
if (params.user_id)
|
|
5864
|
-
|
|
5564
|
+
query.set("user_id", params.user_id);
|
|
5865
5565
|
if (params.time_range)
|
|
5866
|
-
|
|
5566
|
+
query.set("time_range", params.time_range);
|
|
5867
5567
|
if (params.since)
|
|
5868
|
-
|
|
5568
|
+
query.set("since", params.since);
|
|
5869
5569
|
if (params.until)
|
|
5870
|
-
|
|
5570
|
+
query.set("until", params.until);
|
|
5871
5571
|
if (params.environment)
|
|
5872
|
-
|
|
5572
|
+
query.set("environment", params.environment);
|
|
5873
5573
|
if (params.world_state)
|
|
5874
|
-
|
|
5574
|
+
query.set("world_state", params.world_state);
|
|
5875
5575
|
if (params.outcome && params.outcome !== "any")
|
|
5876
|
-
|
|
5576
|
+
query.set("outcome", params.outcome);
|
|
5877
5577
|
if (params.sort)
|
|
5878
|
-
|
|
5578
|
+
query.set("sort_by", params.sort);
|
|
5879
5579
|
if (params.cohort)
|
|
5880
|
-
|
|
5580
|
+
query.set("cohort", params.cohort);
|
|
5881
5581
|
if (params.limit)
|
|
5882
|
-
|
|
5582
|
+
query.set("limit", params.limit.toString());
|
|
5883
5583
|
if (params.offset !== undefined)
|
|
5884
|
-
|
|
5885
|
-
const queryString =
|
|
5584
|
+
query.set("offset", params.offset.toString());
|
|
5585
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
5886
5586
|
const raw = await callDataAPI(`/conversations${queryString}`);
|
|
5887
5587
|
recordConversationsTelemetry(context, raw);
|
|
5888
5588
|
const searchWarnings = [];
|
|
@@ -5922,25 +5622,25 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5922
5622
|
}
|
|
5923
5623
|
const args = flagsToArgs(flags, "q", queryText);
|
|
5924
5624
|
const params = parseSpecFlags("search", args, command);
|
|
5925
|
-
const
|
|
5926
|
-
|
|
5625
|
+
const query = new URLSearchParams;
|
|
5626
|
+
query.set("q", params.q);
|
|
5927
5627
|
if (params.mode)
|
|
5928
|
-
|
|
5628
|
+
query.set("mode", params.mode);
|
|
5929
5629
|
if (params.user_id)
|
|
5930
|
-
|
|
5630
|
+
query.set("user_id", params.user_id);
|
|
5931
5631
|
if (params.conversation_id)
|
|
5932
|
-
|
|
5632
|
+
query.set("conversation_id", params.conversation_id);
|
|
5933
5633
|
if (params.time_range)
|
|
5934
|
-
|
|
5634
|
+
query.set("time_range", params.time_range);
|
|
5935
5635
|
if (params.since)
|
|
5936
|
-
|
|
5636
|
+
query.set("since", params.since);
|
|
5937
5637
|
if (params.until)
|
|
5938
|
-
|
|
5638
|
+
query.set("until", params.until);
|
|
5939
5639
|
if (params.limit)
|
|
5940
|
-
|
|
5640
|
+
query.set("limit", params.limit.toString());
|
|
5941
5641
|
if (params.include_tool_io)
|
|
5942
|
-
|
|
5943
|
-
const data = await callDataAPI(`/search?${
|
|
5642
|
+
query.set("include_tool_io", "true");
|
|
5643
|
+
const data = await callDataAPI(`/search?${query.toString()}`);
|
|
5944
5644
|
recordSearchTelemetry(context, data);
|
|
5945
5645
|
const searchRecord = asRecord(data) ?? {};
|
|
5946
5646
|
const warnings = searchOutcomeWarnings(searchRecord, params.mode, params.q);
|
|
@@ -6004,13 +5704,13 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6004
5704
|
throw new CliInputError("Choose either --snapshot or --replay, not both.", "Usage: moda traces state <conversation_id> [--snapshot --msg-index=N [--block-index=M] [--segment-index=K]] | [--replay --message-count=N [--format=frames|fold-inputs]]");
|
|
6005
5705
|
}
|
|
6006
5706
|
if (params.snapshot === true) {
|
|
6007
|
-
const
|
|
6008
|
-
|
|
5707
|
+
const query2 = new URLSearchParams;
|
|
5708
|
+
query2.set("msg_index", (params.msg_index ?? 0).toString());
|
|
6009
5709
|
if (params.block_index !== undefined)
|
|
6010
|
-
|
|
5710
|
+
query2.set("block_index", params.block_index.toString());
|
|
6011
5711
|
if (params.segment_index !== undefined)
|
|
6012
|
-
|
|
6013
|
-
const data2 = await callDataAPI(`/conversations/${encodeURIComponent(params.conversation_id)}/world-state/snapshot?${
|
|
5712
|
+
query2.set("segment_index", params.segment_index.toString());
|
|
5713
|
+
const data2 = await callDataAPI(`/conversations/${encodeURIComponent(params.conversation_id)}/world-state/snapshot?${query2.toString()}`);
|
|
6014
5714
|
const snapshotRecord = asRecord(data2) ?? {};
|
|
6015
5715
|
context.output.writeData(data2, noWorldStateWarnings(params.conversation_id, snapshotRecord.found === false));
|
|
6016
5716
|
break;
|
|
@@ -6020,21 +5720,21 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6020
5720
|
if (format === "frames" && params.message_count === undefined) {
|
|
6021
5721
|
throw new CliInputError("--message-count=N is required with --replay in frames mode (the API returns no frames without it). Use --format=fold-inputs for the raw keyframes/events without a count.");
|
|
6022
5722
|
}
|
|
6023
|
-
const
|
|
6024
|
-
|
|
5723
|
+
const query2 = new URLSearchParams;
|
|
5724
|
+
query2.set("format", format === "fold-inputs" ? "fold_inputs" : "frames");
|
|
6025
5725
|
if (params.message_count !== undefined)
|
|
6026
|
-
|
|
6027
|
-
const data2 = await callDataAPI(`/conversations/${encodeURIComponent(params.conversation_id)}/world-state/replay?${
|
|
5726
|
+
query2.set("message_count", params.message_count.toString());
|
|
5727
|
+
const data2 = await callDataAPI(`/conversations/${encodeURIComponent(params.conversation_id)}/world-state/replay?${query2.toString()}`);
|
|
6028
5728
|
const replayRecord = asRecord(data2) ?? {};
|
|
6029
5729
|
context.output.writeData(data2, noWorldStateWarnings(params.conversation_id, replayRecord.hasData === false));
|
|
6030
5730
|
break;
|
|
6031
5731
|
}
|
|
6032
|
-
const
|
|
5732
|
+
const query = new URLSearchParams;
|
|
6033
5733
|
if (params.summary_only === true)
|
|
6034
|
-
|
|
5734
|
+
query.set("summary_only", "1");
|
|
6035
5735
|
if (params.event_limit)
|
|
6036
|
-
|
|
6037
|
-
const queryString =
|
|
5736
|
+
query.set("event_limit", params.event_limit.toString());
|
|
5737
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6038
5738
|
const data = await callDataAPI(`/conversations/${encodeURIComponent(params.conversation_id)}/world-state${queryString}`);
|
|
6039
5739
|
const wsRecord = asRecord(data) ?? {};
|
|
6040
5740
|
context.output.writeData(data, noWorldStateWarnings(params.conversation_id, wsRecord.hasData === false));
|
|
@@ -6070,34 +5770,34 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6070
5770
|
const args = flagsToArgs(flags);
|
|
6071
5771
|
const params = parseSpecFlags("frustrations", args, command);
|
|
6072
5772
|
const compare = params.compare === true ? await loadFamilyCompare("frustrations", params) : undefined;
|
|
6073
|
-
const
|
|
5773
|
+
const query = new URLSearchParams;
|
|
6074
5774
|
if (params.days_back)
|
|
6075
|
-
|
|
5775
|
+
query.set("days_back", params.days_back.toString());
|
|
6076
5776
|
if (params.limit)
|
|
6077
|
-
|
|
5777
|
+
query.set("limit", params.limit.toString());
|
|
6078
5778
|
if (params.offset !== undefined)
|
|
6079
|
-
|
|
5779
|
+
query.set("offset", params.offset.toString());
|
|
6080
5780
|
if (readsPerTrace("frustrations", params, ["user_id", "conversation_id", "conversation_ids", "ids_from", "include_window"])) {
|
|
6081
|
-
|
|
6082
|
-
setTraceFilters(
|
|
6083
|
-
const data2 = withSummaryCompare(await callDataAPI(`/emotions?${
|
|
5781
|
+
query.set("family", "frustration");
|
|
5782
|
+
setTraceFilters(query, params, TRACE_GRAIN_FLAGS.frustrations);
|
|
5783
|
+
const data2 = withSummaryCompare(await callDataAPI(`/emotions?${query.toString()}`), compare);
|
|
6084
5784
|
const warnings = processingDisabledWarning(data2, "frustration");
|
|
6085
5785
|
context.output.writeData(data2, withCohortScope(params.cohort, data2, { summary: countingSummary(data2), warnings }));
|
|
6086
5786
|
break;
|
|
6087
5787
|
}
|
|
6088
5788
|
if (params.user_id)
|
|
6089
|
-
|
|
5789
|
+
query.set("user_id", params.user_id);
|
|
6090
5790
|
if (params.conversation_id)
|
|
6091
|
-
|
|
5791
|
+
query.set("conversation_id", params.conversation_id);
|
|
6092
5792
|
const frustrationIds = await conversationIdsFilter(params, context);
|
|
6093
5793
|
if (frustrationIds)
|
|
6094
|
-
|
|
6095
|
-
|
|
5794
|
+
query.set("conversation_ids", frustrationIds.join(","));
|
|
5795
|
+
query.set("family", "frustration");
|
|
6096
5796
|
const includeWindow = params.include_window === true;
|
|
6097
5797
|
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
6098
5798
|
if (agentMode && !includeWindow)
|
|
6099
|
-
|
|
6100
|
-
const data = frustrationsFromEmotions(await callDataAPI(`/emotions?${
|
|
5799
|
+
query.set("include_context", "0");
|
|
5800
|
+
const data = frustrationsFromEmotions(await callDataAPI(`/emotions?${query.toString()}`));
|
|
6101
5801
|
const anchored = withSummaryCompare(withFrustrationAnchors(data), compare);
|
|
6102
5802
|
await printWithOptionalWindows(agentMode && !includeWindow ? withoutDetectionWindows(anchored, "frustrations", "conversation") : anchored, "frustrations", includeWindow, params.window ?? 1, context.output, processingDisabledWarning(data, "frustration"), agentMode && includeWindow ? (payload) => withoutRepeatedFrustrationWindow(payload) : undefined, [], countingSummary(data));
|
|
6103
5803
|
break;
|
|
@@ -6133,12 +5833,12 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6133
5833
|
const limit = params.limit ?? TOOL_CATALOG_DEFAULT_LIMIT;
|
|
6134
5834
|
const offset = params.offset ?? 0;
|
|
6135
5835
|
const sort = params.sort ?? "calls";
|
|
6136
|
-
const
|
|
5836
|
+
const query = new URLSearchParams({ days_back: String(daysBack), sort, limit: String(limit), offset: String(offset) });
|
|
6137
5837
|
if (params.search)
|
|
6138
|
-
|
|
5838
|
+
query.set("search", params.search);
|
|
6139
5839
|
if (params.direction)
|
|
6140
|
-
|
|
6141
|
-
const data = asRecord(await callDataAPI(`/tools?${
|
|
5840
|
+
query.set("direction", params.direction);
|
|
5841
|
+
const data = asRecord(await callDataAPI(`/tools?${query.toString()}`)) ?? {};
|
|
6142
5842
|
const pagination = asRecord(data.pagination);
|
|
6143
5843
|
const tools = Array.isArray(data.tools) ? data.tools.map((row) => asRecord(row)).filter((row) => row !== null) : [];
|
|
6144
5844
|
const listFlags = [
|
|
@@ -6229,17 +5929,17 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6229
5929
|
if (params.compact === true && params.include_window === true) {
|
|
6230
5930
|
throw new CliInputError("--compact drops the conversation window; drop --include-window, or drop --compact.");
|
|
6231
5931
|
}
|
|
6232
|
-
const
|
|
5932
|
+
const query = new URLSearchParams;
|
|
6233
5933
|
if (params.subtype)
|
|
6234
|
-
|
|
5934
|
+
query.set("subtype", params.subtype);
|
|
6235
5935
|
if (params.days_back)
|
|
6236
|
-
|
|
6237
|
-
|
|
5936
|
+
query.set("days_back", params.days_back.toString());
|
|
5937
|
+
query.set("limit", (params.limit ?? TOOL_FAILURE_DETAIL_DEFAULT_LIMIT).toString());
|
|
6238
5938
|
if (params.offset !== undefined)
|
|
6239
|
-
|
|
5939
|
+
query.set("offset", params.offset.toString());
|
|
6240
5940
|
if (dropConversation)
|
|
6241
|
-
|
|
6242
|
-
const queryString =
|
|
5941
|
+
query.set("include_context", "0");
|
|
5942
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6243
5943
|
const data = await callDataAPI(`/tool-failures/${encodeURIComponent(params.tool_name)}${queryString}`);
|
|
6244
5944
|
const tfRecord = asRecord(data) ?? {};
|
|
6245
5945
|
const subtypeCount = Array.isArray(tfRecord.subtypes) ? tfRecord.subtypes.length : 0;
|
|
@@ -6274,7 +5974,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6274
5974
|
}
|
|
6275
5975
|
case "problem-impact": {
|
|
6276
5976
|
const params = ProblemImpactSchema.parse(Object.fromEntries(Object.entries(flags).map(([key, value]) => [key.replace(/-/g, "_"), value])));
|
|
6277
|
-
const
|
|
5977
|
+
const query = new URLSearchParams({ days: String(params.days_back), mode: params.mode });
|
|
6278
5978
|
for (const [key, value] of Object.entries({
|
|
6279
5979
|
nodeId: params.node_id,
|
|
6280
5980
|
problemId: params.problem_id,
|
|
@@ -6284,8 +5984,8 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6284
5984
|
conversationIds: params.conversation_ids ? JSON.stringify(params.conversation_ids) : undefined
|
|
6285
5985
|
}))
|
|
6286
5986
|
if (value !== undefined)
|
|
6287
|
-
|
|
6288
|
-
const data = asRecord(await callDataAPI(`/problem-impact?${
|
|
5987
|
+
query.set(key, value);
|
|
5988
|
+
const data = asRecord(await callDataAPI(`/problem-impact?${query}`)) ?? {};
|
|
6289
5989
|
const link = new URLSearchParams({ impactDays: String(params.days_back) });
|
|
6290
5990
|
const window = asRecord(data.window);
|
|
6291
5991
|
const resolvedRun = asString(data.runId);
|
|
@@ -6325,8 +6025,8 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6325
6025
|
const params = parseSpecFlags("problem", args, command);
|
|
6326
6026
|
if (params.trend === true) {
|
|
6327
6027
|
rejectInapplicableFlags(command, params, ["evidence", "reports", "traces", "conversations", "feedback", "full", "limit", "cursor", "family", "door", "view", "offset"], "with --trend; it reads the Problem's per-day history (only --days-back applies)");
|
|
6328
|
-
const
|
|
6329
|
-
const data2 = await callDataAPI(`/problems/${encodeURIComponent(params.id)}/history${
|
|
6028
|
+
const query2 = params.days_back ? `?days_back=${params.days_back}` : "";
|
|
6029
|
+
const data2 = await callDataAPI(`/problems/${encodeURIComponent(params.id)}/history${query2}`);
|
|
6330
6030
|
context.output.writeData(data2, {
|
|
6331
6031
|
summary: problemTrendSummary(data2),
|
|
6332
6032
|
nextCommands: [{ command: `moda problems get ${shellArg(params.id)}`, purpose: "Open the Problem dossier.", mutability: "read", requires_approval: false }]
|
|
@@ -6376,18 +6076,18 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6376
6076
|
const viewFlag = view === "conversations" ? "--traces" : `--${view}`;
|
|
6377
6077
|
throw new CliInputError(`${viewFlag} requires a canonical problem UUID; got "${params.id}". Run \`moda problems\` or \`moda problems get <id>\` first to resolve the id.`);
|
|
6378
6078
|
}
|
|
6379
|
-
const
|
|
6079
|
+
const query = new URLSearchParams;
|
|
6380
6080
|
if (params.limit)
|
|
6381
|
-
|
|
6081
|
+
query.set("limit", params.limit.toString());
|
|
6382
6082
|
if (params.cursor)
|
|
6383
|
-
|
|
6083
|
+
query.set("cursor", params.cursor);
|
|
6384
6084
|
if (view === "conversations") {
|
|
6385
6085
|
if (params.family)
|
|
6386
|
-
|
|
6086
|
+
query.set("family", params.family);
|
|
6387
6087
|
if (params.door)
|
|
6388
|
-
|
|
6088
|
+
query.set("door", params.door);
|
|
6389
6089
|
}
|
|
6390
|
-
const queryString =
|
|
6090
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6391
6091
|
const data = await callDataAPI(`/problems/${encodeURIComponent(params.id)}/${view}${queryString}`);
|
|
6392
6092
|
context.output.writeData(data);
|
|
6393
6093
|
break;
|
|
@@ -6536,16 +6236,16 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6536
6236
|
context.output.writeData(data2);
|
|
6537
6237
|
break;
|
|
6538
6238
|
}
|
|
6539
|
-
const
|
|
6239
|
+
const query = new URLSearchParams;
|
|
6540
6240
|
if (params.days_back)
|
|
6541
|
-
|
|
6241
|
+
query.set("days_back", params.days_back.toString());
|
|
6542
6242
|
if (params.limit)
|
|
6543
|
-
|
|
6243
|
+
query.set("limit", params.limit.toString());
|
|
6544
6244
|
if (params.offset !== undefined)
|
|
6545
|
-
|
|
6245
|
+
query.set("offset", params.offset.toString());
|
|
6546
6246
|
if (params.cohort)
|
|
6547
|
-
|
|
6548
|
-
const queryString =
|
|
6247
|
+
query.set("cohort", params.cohort);
|
|
6248
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6549
6249
|
const data = await callDataAPI(`/custom-signals/${id}/detections${queryString}`);
|
|
6550
6250
|
const warnings = customSignalProcessingWarning(data, "detections");
|
|
6551
6251
|
context.output.writeData(data, withCohortScope(params.cohort, data, { warnings }));
|
|
@@ -6737,23 +6437,23 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6737
6437
|
case "false-positives": {
|
|
6738
6438
|
if (!positional) {
|
|
6739
6439
|
const kinds = { quote: "frustration_quote", tool: "tool_call", laziness: "laziness", hallucination: "hallucination", "custom-signal": "custom_signal" };
|
|
6740
|
-
const
|
|
6440
|
+
const query = new URLSearchParams;
|
|
6741
6441
|
if (flags.kind !== undefined) {
|
|
6742
6442
|
if (flags.kind === "problem" || flags.kind === "problem-detection") {
|
|
6743
6443
|
throw new CliInputError(`'moda reviews list' cannot list --kind=${flags.kind}: ${flags.kind === "problem" ? "a dismissed Problem is recorded as Problem feedback" : "a problem-detection false positive is recorded as a detection review on its Problem"}, not in the false-positive log this command reads. Nothing was sent.`, flags.kind === "problem" ? "Read it with 'moda problems get <problem_id> --feedback'. --kind for this list takes " + Object.keys(kinds).join("|") + "." : "Read them per trace with 'moda reviews list <conversation_id> --kind=problem-detection' or 'moda reviews list <conversation_id>'. --kind for this list takes " + Object.keys(kinds).join("|") + ".", "unsupported_kind");
|
|
6744
6444
|
}
|
|
6745
6445
|
if (!kinds[flags.kind])
|
|
6746
6446
|
throw new CliInputError(`--kind must be one of ${Object.keys(kinds).join("|")}`);
|
|
6747
|
-
|
|
6447
|
+
query.set("kind", kinds[flags.kind]);
|
|
6748
6448
|
}
|
|
6749
6449
|
if (flags.limit !== undefined) {
|
|
6750
6450
|
if (!/^\d+$/.test(flags.limit) || Number(flags.limit) < 1 || Number(flags.limit) > 200)
|
|
6751
6451
|
throw new CliInputError("--limit must be 1-200");
|
|
6752
|
-
|
|
6452
|
+
query.set("limit", flags.limit);
|
|
6753
6453
|
}
|
|
6754
6454
|
if (flags.all !== undefined && flags.all !== "false")
|
|
6755
|
-
|
|
6756
|
-
const queryString =
|
|
6455
|
+
query.set("include_cleared", "true");
|
|
6456
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6757
6457
|
const data2 = await callDataAPI(`/false-positives${queryString}`);
|
|
6758
6458
|
context.output.writeData(data2);
|
|
6759
6459
|
break;
|
|
@@ -6767,33 +6467,33 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6767
6467
|
const args = flagsToArgs(flags);
|
|
6768
6468
|
const params = parseSpecFlags("emotions", args, command);
|
|
6769
6469
|
const compare = params.compare === true ? await loadFamilyCompare("emotions", params) : undefined;
|
|
6770
|
-
const
|
|
6470
|
+
const query = new URLSearchParams;
|
|
6771
6471
|
if (params.days_back)
|
|
6772
|
-
|
|
6472
|
+
query.set("days_back", params.days_back.toString());
|
|
6773
6473
|
if (params.limit)
|
|
6774
|
-
|
|
6474
|
+
query.set("limit", params.limit.toString());
|
|
6775
6475
|
if (params.offset !== undefined)
|
|
6776
|
-
|
|
6476
|
+
query.set("offset", params.offset.toString());
|
|
6777
6477
|
if (params.family)
|
|
6778
|
-
|
|
6478
|
+
query.set("family", params.family);
|
|
6779
6479
|
if (readsPerTrace("emotions", params, ["user_id", "conversation_id", "conversation_ids", "ids_from", "include_window"])) {
|
|
6780
|
-
setTraceFilters(
|
|
6781
|
-
const data2 = withSummaryCompare(await callDataAPI(`/emotions?${
|
|
6480
|
+
setTraceFilters(query, params, TRACE_GRAIN_FLAGS.emotions);
|
|
6481
|
+
const data2 = withSummaryCompare(await callDataAPI(`/emotions?${query.toString()}`), compare);
|
|
6782
6482
|
const warnings = processingDisabledWarning(data2, "emotion");
|
|
6783
6483
|
context.output.writeData(data2, withCohortScope(params.cohort, data2, { summary: countingSummary(data2), warnings }));
|
|
6784
6484
|
break;
|
|
6785
6485
|
}
|
|
6786
6486
|
if (params.user_id)
|
|
6787
|
-
|
|
6487
|
+
query.set("user_id", params.user_id);
|
|
6788
6488
|
if (params.conversation_id)
|
|
6789
|
-
|
|
6489
|
+
query.set("conversation_id", params.conversation_id);
|
|
6790
6490
|
const emotionIds = await conversationIdsFilter(params, context);
|
|
6791
6491
|
if (emotionIds)
|
|
6792
|
-
|
|
6492
|
+
query.set("conversation_ids", emotionIds.join(","));
|
|
6793
6493
|
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
6794
6494
|
if (agentMode && params.include_window !== true)
|
|
6795
|
-
|
|
6796
|
-
const queryString =
|
|
6495
|
+
query.set("include_context", "0");
|
|
6496
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6797
6497
|
const raw = withSummaryCompare(await callDataAPI(`/emotions${queryString}`), compare);
|
|
6798
6498
|
const processingWarnings = processingDisabledWarning(raw, "emotion");
|
|
6799
6499
|
const record = asRecord(raw);
|
|
@@ -6805,34 +6505,34 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6805
6505
|
case "laziness": {
|
|
6806
6506
|
const args = flagsToArgs(flags);
|
|
6807
6507
|
const params = parseSpecFlags("laziness", args, command);
|
|
6808
|
-
const
|
|
6508
|
+
const query = new URLSearchParams;
|
|
6809
6509
|
if (params.days_back)
|
|
6810
|
-
|
|
6510
|
+
query.set("days_back", params.days_back.toString());
|
|
6811
6511
|
if (params.limit)
|
|
6812
|
-
|
|
6512
|
+
query.set("limit", params.limit.toString());
|
|
6813
6513
|
if (params.offset !== undefined)
|
|
6814
|
-
|
|
6514
|
+
query.set("offset", params.offset.toString());
|
|
6815
6515
|
if (params.conversation_id)
|
|
6816
|
-
|
|
6516
|
+
query.set("conversation_id", params.conversation_id);
|
|
6817
6517
|
const lazinessIds = await conversationIdsFilter(params, context);
|
|
6818
6518
|
if (lazinessIds)
|
|
6819
|
-
|
|
6519
|
+
query.set("conversation_ids", lazinessIds.join(","));
|
|
6820
6520
|
if (params.family)
|
|
6821
|
-
|
|
6521
|
+
query.set("family", params.family);
|
|
6822
6522
|
if (params.conversation_id) {
|
|
6823
6523
|
rejectInapplicableFlags(command, params, ["search", "status", "sort", "order", "cohort"], "to one trace's detections (--conversation-id); they filter and order the trace list");
|
|
6824
6524
|
}
|
|
6825
6525
|
if (params.cohort)
|
|
6826
|
-
|
|
6526
|
+
query.set("cohort", params.cohort);
|
|
6827
6527
|
if (params.search)
|
|
6828
|
-
|
|
6528
|
+
query.set("search", params.search);
|
|
6829
6529
|
if (params.status)
|
|
6830
|
-
|
|
6530
|
+
query.set("status", params.status);
|
|
6831
6531
|
if (params.sort)
|
|
6832
|
-
|
|
6532
|
+
query.set("sort", params.sort);
|
|
6833
6533
|
if (params.order)
|
|
6834
|
-
|
|
6835
|
-
const queryString =
|
|
6534
|
+
query.set("order", params.order);
|
|
6535
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6836
6536
|
if (params.compare === true)
|
|
6837
6537
|
assertCompareScope("laziness", params);
|
|
6838
6538
|
const [listed, compare] = await Promise.all([
|
|
@@ -6846,25 +6546,25 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6846
6546
|
case "hallucinations": {
|
|
6847
6547
|
const args = flagsToArgs(flags);
|
|
6848
6548
|
const params = parseSpecFlags("hallucinations", args, command);
|
|
6849
|
-
const
|
|
6549
|
+
const query = new URLSearchParams;
|
|
6850
6550
|
if (params.days_back)
|
|
6851
|
-
|
|
6551
|
+
query.set("days_back", params.days_back.toString());
|
|
6852
6552
|
if (params.limit)
|
|
6853
|
-
|
|
6553
|
+
query.set("limit", params.limit.toString());
|
|
6854
6554
|
if (params.offset !== undefined)
|
|
6855
|
-
|
|
6555
|
+
query.set("offset", params.offset.toString());
|
|
6856
6556
|
if (readsPerTrace("hallucinations", params, ["conversation_id", "conversation_ids", "ids_from", "kind"])) {
|
|
6857
|
-
setTraceFilters(
|
|
6557
|
+
setTraceFilters(query, params, TRACE_GRAIN_FLAGS.hallucinations);
|
|
6858
6558
|
} else {
|
|
6859
6559
|
if (params.conversation_id)
|
|
6860
|
-
|
|
6560
|
+
query.set("conversation_id", params.conversation_id);
|
|
6861
6561
|
const hallucinationIds = await conversationIdsFilter(params, context);
|
|
6862
6562
|
if (hallucinationIds)
|
|
6863
|
-
|
|
6563
|
+
query.set("conversation_ids", hallucinationIds.join(","));
|
|
6864
6564
|
if (params.kind)
|
|
6865
|
-
|
|
6565
|
+
query.set("kind", params.kind);
|
|
6866
6566
|
}
|
|
6867
|
-
const queryString =
|
|
6567
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6868
6568
|
if (params.compare === true)
|
|
6869
6569
|
assertCompareScope("hallucinations", params);
|
|
6870
6570
|
const [listed, compare] = await Promise.all([
|
|
@@ -7061,7 +6761,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
7061
6761
|
resetApiRequestCountBeforeRun: true,
|
|
7062
6762
|
telemetry: "result-and-error",
|
|
7063
6763
|
handler: async (context) => {
|
|
7064
|
-
const { runInit } = await import("./index-
|
|
6764
|
+
const { runInit } = await import("./index-5eyq3ykt.js");
|
|
7065
6765
|
if (context.outputMode === "agent-stream") {
|
|
7066
6766
|
context.output.writeEvent({
|
|
7067
6767
|
event: "started",
|
|
@@ -7111,7 +6811,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
7111
6811
|
resetApiRequestCountBeforeRun: true,
|
|
7112
6812
|
telemetry: "result-and-error",
|
|
7113
6813
|
handler: async (context) => {
|
|
7114
|
-
const { runProvision } = await import("./provision-
|
|
6814
|
+
const { runProvision } = await import("./provision-xkhwz86g.js");
|
|
7115
6815
|
return runProvision(context, {
|
|
7116
6816
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
7117
6817
|
});
|
|
@@ -7409,23 +7109,6 @@ var commandRegistry = createCommandRegistry([
|
|
|
7409
7109
|
telemetry: "result-and-error",
|
|
7410
7110
|
handler: runCohortCommand
|
|
7411
7111
|
})),
|
|
7412
|
-
{
|
|
7413
|
-
name: "replays",
|
|
7414
|
-
description: "Read replay results: sets, run history, per-seed verdicts, and playout transcripts",
|
|
7415
|
-
examples: [
|
|
7416
|
-
"moda replays runs <set_id>",
|
|
7417
|
-
"moda replays run <set_id> <run_id> --json",
|
|
7418
|
-
"moda replays playouts <set_id> <run_id> --case=<case_id> --arm=proposed --transcript --json"
|
|
7419
|
-
],
|
|
7420
|
-
subcommands: REPLAYS_SUBCOMMAND_HELP,
|
|
7421
|
-
auth: "api-key",
|
|
7422
|
-
outputModes: ["human", "json", "agent"],
|
|
7423
|
-
mutability: "read",
|
|
7424
|
-
validateConfigBeforeRun: false,
|
|
7425
|
-
resetApiRequestCountBeforeRun: false,
|
|
7426
|
-
telemetry: "result-and-error",
|
|
7427
|
-
handler: runReplaysCommand
|
|
7428
|
-
},
|
|
7429
7112
|
{
|
|
7430
7113
|
name: "problem-reopen",
|
|
7431
7114
|
description: "Reopen a problem that was marked fixed (resolved problems return only via re-detection)",
|
|
@@ -7944,7 +7627,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
7944
7627
|
'moda feedback "trace is about refunds, not this problem" --category=false_positive_attribution --problem-id=<id> --conversation-id=<id>'
|
|
7945
7628
|
],
|
|
7946
7629
|
helpNotes: [
|
|
7947
|
-
"Any other id flag (--problem-id, --
|
|
7630
|
+
"Any other id flag (--problem-id, --attribution-id, --trace-id, --span-id, --message-index, ...) is attached as a ref. Set MODA_CLI_TIPS=0 to hide the feedback tip line."
|
|
7948
7631
|
],
|
|
7949
7632
|
...dataApiDefaults,
|
|
7950
7633
|
mutability: "write"
|
|
@@ -7952,7 +7635,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
7952
7635
|
legacyCommand({
|
|
7953
7636
|
name: "prompts",
|
|
7954
7637
|
description: "Manage prompt versions and labels",
|
|
7955
|
-
examples: ["moda prompts init", "moda prompts status", "moda prompts migrate --dry-run", "moda prompts sync", "moda prompts
|
|
7638
|
+
examples: ["moda prompts init", "moda prompts status", "moda prompts migrate --dry-run", "moda prompts sync", "moda prompts promote support.triage --label=prod --version=pver_abc123"],
|
|
7956
7639
|
subcommands: [
|
|
7957
7640
|
{
|
|
7958
7641
|
name: "init",
|
|
@@ -8008,45 +7691,6 @@ var commandRegistry = createCommandRegistry([
|
|
|
8008
7691
|
],
|
|
8009
7692
|
examples: ["moda prompts promote support.triage --label=prod --version=pver_abc123"]
|
|
8010
7693
|
},
|
|
8011
|
-
{
|
|
8012
|
-
name: "ab",
|
|
8013
|
-
description: "Run a judged prompt A/B replay experiment",
|
|
8014
|
-
usage: "moda prompts ab --baseline=<path> --candidate=<path> [--traces=<ids>|--problem=<problem_id> [--max-cases=<n>]|--set-id=<id>|--auto-generate] [--yes]",
|
|
8015
|
-
flags: [
|
|
8016
|
-
{ name: "--baseline=<path>", description: "Prompt file to treat as the control." },
|
|
8017
|
-
{ name: "--candidate=<path>", description: "Prompt file to treat as the variant." },
|
|
8018
|
-
{ name: "--traces=<ids>", description: "Comma-separated trace ids (conversation_id values) to replay, at most 100. Each case uses Moda's distilled scenario and success criteria for the trace; a trace that cannot be distilled falls back to its opening user message with generic criteria, and the run warns. Legacy alias: --conversations=<ids>." },
|
|
8019
|
-
{ name: "--problem=<problem_id>", description: "Replay the Problem's failing traces: one case per affected trace, starting at its evidence msg_index (like --traces=<id>@<n>), read from `moda problems get <id> --evidence`, then `--traces` if needed. Prints the traces it chose. Not combinable with --traces, --set-id, --auto-generate, or --cases." },
|
|
8020
|
-
{ name: "--max-cases=<n>", description: "With --problem: replay at most this many traces (default 10, max 100)." },
|
|
8021
|
-
{ name: "--cases=<n>", description: "Cases to auto-generate (default 5, max 100)." },
|
|
8022
|
-
{ name: "--seeds=<n>", description: "Repeats per case per arm (default 3, max 10)." },
|
|
8023
|
-
{ name: "--model=<slug>", description: "Assistant model for both arms; must be in the replay allowlist unless --allow-any-model." },
|
|
8024
|
-
{ name: "--yes", description: "Confirm a run above 200 planned playouts (cases x seeds x 2 arms), or one whose case count is unknown." },
|
|
8025
|
-
{ name: "--promote", description: "Make this run's replay set the tenant's primary replay set. Off by default, so an ad-hoc A/B never replaces it." }
|
|
8026
|
-
],
|
|
8027
|
-
examples: [
|
|
8028
|
-
"moda prompts ab --baseline=prompts/agent.prompt.md --candidate=prompts/agent-v2.prompt.md --traces=conv_1,conv_2",
|
|
8029
|
-
"moda prompts ab --baseline=prompts/agent.prompt.md --candidate=prompts/agent-v2.prompt.md --problem=<problem_id>"
|
|
8030
|
-
]
|
|
8031
|
-
},
|
|
8032
|
-
{
|
|
8033
|
-
name: "propose",
|
|
8034
|
-
description: "Revise a prompt from a run's failures (one LLM call; --gate adds paid replays)",
|
|
8035
|
-
usage: "moda prompts propose --prompt-key=<key> --from-run=<run_id> --set-id=<replay_set_id> [--max-dossiers=N] [--model=<slug>] [--out=<path>] [--gate [--seeds=N] [--yes]] [--promote-on-win]",
|
|
8036
|
-
flags: [
|
|
8037
|
-
{ name: "--prompt-key=<key>", description: "Required. Registered prompt to revise." },
|
|
8038
|
-
{ name: "--from-run=<run_id>", description: "Required. The `prompts ab` run whose failures drive the revision." },
|
|
8039
|
-
{ name: "--set-id=<replay_set_id>", description: "Required. The replay set that run used; --gate replays all of it. A set that does not exist fails before anything is sent." },
|
|
8040
|
-
{ name: "--max-dossiers=<n>", description: "Failure dossiers to revise from (default 8, max 16)." },
|
|
8041
|
-
{ name: "--model=<slug>", description: "Revision model (replay allowlist unless --allow-any-model)." },
|
|
8042
|
-
{ name: "--out=<path>", description: "Write the candidate prompt to this file." },
|
|
8043
|
-
{ name: "--seeds=<n>", description: "Gate: repeats per case per arm (default 3, max 10)." },
|
|
8044
|
-
{ name: "--gate", description: "Automatically A/B the proposed revision over the full --set-id (planned playouts = cases x seeds x 2; above 200 needs --yes)." },
|
|
8045
|
-
{ name: "--yes", description: "Confirm a gate above 200 planned playouts, or one whose case count is unknown." },
|
|
8046
|
-
{ name: "--promote-on-win", description: "Promote the candidate if it wins the gate." }
|
|
8047
|
-
],
|
|
8048
|
-
examples: ["moda prompts propose --prompt-key=support.triage --from-run=<run_id> --set-id=<set_id> --gate --promote-on-win"]
|
|
8049
|
-
},
|
|
8050
7694
|
...PROMPTS_REGISTRY_SUBCOMMAND_HELP
|
|
8051
7695
|
],
|
|
8052
7696
|
auth: "api-key",
|
|
@@ -8080,53 +7724,6 @@ var commandRegistry = createCommandRegistry([
|
|
|
8080
7724
|
handler: async (context) => ({
|
|
8081
7725
|
exitCode: await runSkillsCommand(context)
|
|
8082
7726
|
})
|
|
8083
|
-
},
|
|
8084
|
-
{
|
|
8085
|
-
name: "fixes",
|
|
8086
|
-
hidden: true,
|
|
8087
|
-
description: 'List the ranked queue of Fixes ("a fix with proof"); campaign mode batch-drafts and drives them',
|
|
8088
|
-
examples: [
|
|
8089
|
-
"moda fixes",
|
|
8090
|
-
"moda fixes --status=VERIFIED",
|
|
8091
|
-
"moda fixes draft-batch --limit=5",
|
|
8092
|
-
"moda fixes drive",
|
|
8093
|
-
"moda fixes drive --status=SCOPING"
|
|
8094
|
-
],
|
|
8095
|
-
auth: "api-key",
|
|
8096
|
-
outputModes: ["human", "json", "agent"],
|
|
8097
|
-
mutability: "write",
|
|
8098
|
-
subcommands: FIXES_SUBCOMMAND_HELP,
|
|
8099
|
-
defaultSubcommand: "list",
|
|
8100
|
-
validateConfigBeforeRun: false,
|
|
8101
|
-
resetApiRequestCountBeforeRun: false,
|
|
8102
|
-
telemetry: "result-and-error",
|
|
8103
|
-
handler: async (context) => ({
|
|
8104
|
-
exitCode: await runFixesCommand(context)
|
|
8105
|
-
})
|
|
8106
|
-
},
|
|
8107
|
-
{
|
|
8108
|
-
name: "fix",
|
|
8109
|
-
hidden: true,
|
|
8110
|
-
description: 'Draft, verify, check out, submit, and dismiss Fixes ("a fix with proof")',
|
|
8111
|
-
subcommands: FIX_SUBCOMMAND_HELP,
|
|
8112
|
-
examples: [
|
|
8113
|
-
"moda fix start <problem_id> --wait",
|
|
8114
|
-
"moda fix <fix_id> --packet",
|
|
8115
|
-
"moda fix verify <fix_id> --prompt-file=prompts/agent.prompt.md",
|
|
8116
|
-
"moda fix checkout <fix_id>",
|
|
8117
|
-
"moda fix submit <fix_id> --pr",
|
|
8118
|
-
'moda fix mark-applied <fix_id> --note="tool description updated in our agent config"',
|
|
8119
|
-
'moda fix dismiss <fix_id> --reason="not actionable"'
|
|
8120
|
-
],
|
|
8121
|
-
auth: "api-key",
|
|
8122
|
-
outputModes: ["human", "json", "agent"],
|
|
8123
|
-
mutability: "write",
|
|
8124
|
-
validateConfigBeforeRun: false,
|
|
8125
|
-
resetApiRequestCountBeforeRun: false,
|
|
8126
|
-
telemetry: "result-and-error",
|
|
8127
|
-
handler: async (context) => ({
|
|
8128
|
-
exitCode: await runFixCommand(context)
|
|
8129
|
-
})
|
|
8130
7727
|
}
|
|
8131
7728
|
]);
|
|
8132
7729
|
function apiErrorType(status) {
|