@moda-ai/cli 1.34.1 → 1.36.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/dist/{cli-8q7jffnj.js → cli-0p6n391h.js} +89 -89
- package/dist/{cli-cagbc7wz.js → cli-7qkhy41j.js} +76 -76
- package/dist/{cli-0h32yvwq.js → cli-drabjmaj.js} +3 -3
- package/dist/{cli-4ycvzfdg.js → cli-scjxgaba.js} +2 -2
- package/dist/{cli-eggpzt87.js → cli-yz99t7n8.js} +1 -1
- package/dist/cli.js +435 -8
- package/dist/{harness-github-actions-xk7n788g.js → harness-github-actions-tk17mnge.js} +2 -2
- package/dist/{harness-1xj4f0qp.js → harness-heasma1f.js} +2 -2
- package/dist/{index-h6gg66n5.js → index-pf2hvadv.js} +5 -5
- package/dist/prompt-source-mcp.js +91 -91
- package/dist/{provision-c5sx3s32.js → provision-d242y9qd.js} +3 -3
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +90 -5
|
@@ -648,7 +648,7 @@ function validateConfig() {
|
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
|
|
651
|
-
//
|
|
651
|
+
// ../../packages/harness-snapshot/src/policy.ts
|
|
652
652
|
var MAX_SCANNED_FILE_BYTES = 512 * 1024;
|
|
653
653
|
var DEFAULT_MAX_INVENTORY_FILES = 12000;
|
|
654
654
|
var DEFAULT_MAX_INVENTORY_TEXT_BYTES = 48 * 1024 * 1024;
|
|
@@ -790,7 +790,7 @@ function isSecretishPath(path) {
|
|
|
790
790
|
return name === ".env" || name.startsWith(".env.") || name.includes("secret") || name.includes("private-key") || name.endsWith(".pem");
|
|
791
791
|
}
|
|
792
792
|
|
|
793
|
-
//
|
|
793
|
+
// ../../packages/harness-snapshot/src/redact.ts
|
|
794
794
|
var REDACTED = "[REDACTED]";
|
|
795
795
|
var MAX_DEPTH = 256;
|
|
796
796
|
var SECRET_KEYS = new Set([
|
|
@@ -887,7 +887,7 @@ function redactSnapshotText(text) {
|
|
|
887
887
|
return { text: parts.join(""), redactionCount };
|
|
888
888
|
}
|
|
889
889
|
|
|
890
|
-
//
|
|
890
|
+
// ../../packages/harness-snapshot/src/pack.ts
|
|
891
891
|
function utf8ByteLength(value) {
|
|
892
892
|
let bytes = 0;
|
|
893
893
|
for (let index = 0;index < value.length; index += 1) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
authFetch,
|
|
3
3
|
getCachedLoginContext
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-yz99t7n8.js";
|
|
5
5
|
import {
|
|
6
6
|
CliAccessError,
|
|
7
7
|
CliInputError,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
resolveTenantIdFromActiveProfile,
|
|
16
16
|
saveCliConfig,
|
|
17
17
|
writeSecretJsonFile
|
|
18
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-drabjmaj.js";
|
|
19
19
|
|
|
20
20
|
// src/init/tenant.ts
|
|
21
21
|
import { randomUUID } from "node:crypto";
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
runPromptsCommand,
|
|
9
9
|
runSkillsCommand,
|
|
10
10
|
runStatusCommand
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-7qkhy41j.js";
|
|
12
12
|
import {
|
|
13
13
|
ApiError,
|
|
14
14
|
HARNESS_REPORT_APPROVAL_PATH,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
summarizeHarness,
|
|
30
30
|
terminalStyles,
|
|
31
31
|
validateHarnessReport
|
|
32
|
-
} from "./cli-
|
|
32
|
+
} from "./cli-0p6n391h.js";
|
|
33
33
|
import {
|
|
34
34
|
authFetch,
|
|
35
35
|
clearAuthSession,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
loadAuthSession,
|
|
38
38
|
login,
|
|
39
39
|
revokeCliSessionToken
|
|
40
|
-
} from "./cli-
|
|
40
|
+
} from "./cli-yz99t7n8.js";
|
|
41
41
|
import {
|
|
42
42
|
AGENT_ERROR_CODES,
|
|
43
43
|
CliAccessError,
|
|
@@ -84,9 +84,10 @@ import {
|
|
|
84
84
|
validateConfig,
|
|
85
85
|
wasOutputCancelled,
|
|
86
86
|
writeSecretJsonFile
|
|
87
|
-
} from "./cli-
|
|
87
|
+
} from "./cli-drabjmaj.js";
|
|
88
88
|
|
|
89
89
|
// src/cli.ts
|
|
90
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
90
91
|
import { z as z2 } from "zod";
|
|
91
92
|
|
|
92
93
|
// src/schemas.ts
|
|
@@ -209,6 +210,70 @@ var ProblemFeedbackSchema = z.object({
|
|
|
209
210
|
new_name: z.string().max(255).optional(),
|
|
210
211
|
actor: z.string().max(255).optional()
|
|
211
212
|
});
|
|
213
|
+
var SignalSchema = z.object({
|
|
214
|
+
id: z.string().min(1).max(255),
|
|
215
|
+
detections: boolFlag(),
|
|
216
|
+
days_back: z.number().min(1).max(90).optional(),
|
|
217
|
+
limit: z.number().min(1).max(20).optional(),
|
|
218
|
+
offset: z.number().min(0).max(1e4).optional()
|
|
219
|
+
});
|
|
220
|
+
var SIGNAL_LABELS = ["fits", "does_not_fit"];
|
|
221
|
+
var SignalLabelSchema = z.object({
|
|
222
|
+
id: z.string().min(1).max(255),
|
|
223
|
+
conversation_id: z.string().min(1).max(255),
|
|
224
|
+
label: z.enum(SIGNAL_LABELS),
|
|
225
|
+
note: z.string().max(2000).optional(),
|
|
226
|
+
msg_index: z.preprocess((v) => typeof v === "string" && /^\d+$/.test(v.trim()) ? Number(v) : v, z.number().int().min(0).optional()),
|
|
227
|
+
msg_dedup_token: z.string().min(1).max(200).optional()
|
|
228
|
+
});
|
|
229
|
+
var DETECTION_VERDICTS = ["correct", "false_positive", "clear"];
|
|
230
|
+
var DetectionReviewSchema = z.object({
|
|
231
|
+
id: z.string().regex(UUID_RE, "Problem id must be a canonical UUID"),
|
|
232
|
+
conversation_id: z.string().min(1).max(255),
|
|
233
|
+
attribution_id: z.string().regex(UUID_RE, "Attribution id must be a UUID"),
|
|
234
|
+
verdict: z.enum(DETECTION_VERDICTS),
|
|
235
|
+
note: z.string().max(2000).optional()
|
|
236
|
+
});
|
|
237
|
+
var FALSE_POSITIVE_KINDS = ["problem", "problem-detection", "quote", "tool", "laziness", "hallucination", "custom-signal"];
|
|
238
|
+
var FalsePositiveSchema = z.object({
|
|
239
|
+
kind: z.enum(FALSE_POSITIVE_KINDS),
|
|
240
|
+
target: z.string().min(1).max(255),
|
|
241
|
+
undo: z.boolean(),
|
|
242
|
+
reason: z.string().max(2000).optional(),
|
|
243
|
+
conversation_id: z.string().min(1).max(255).optional(),
|
|
244
|
+
attribution_id: z.string().regex(UUID_RE, "Attribution id must be a UUID").optional(),
|
|
245
|
+
family: z.string().regex(/^[a-z_]{1,64}$/, "Family must be a lowercase emotion family").optional(),
|
|
246
|
+
turn: z.preprocess((v) => typeof v === "string" && /^\d+$/.test(v.trim()) ? Number(v) : v, z.number().int().min(0).optional()),
|
|
247
|
+
quote: z.string().min(1).max(4000).optional(),
|
|
248
|
+
tool: z.string().min(1).max(255).optional(),
|
|
249
|
+
tool_use_id: z.string().min(1).max(255).optional(),
|
|
250
|
+
msg_index: z.preprocess((v) => typeof v === "string" && /^\d+$/.test(v.trim()) ? Number(v) : v, z.number().int().min(0).optional()),
|
|
251
|
+
msg_dedup_token: z.string().min(1).max(200).optional()
|
|
252
|
+
}).superRefine((v, ctx) => {
|
|
253
|
+
const need = (ok, message) => {
|
|
254
|
+
if (!ok)
|
|
255
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, message });
|
|
256
|
+
};
|
|
257
|
+
if (v.kind === "problem") {
|
|
258
|
+
need(UUID_RE.test(v.target), "Problem id must be a canonical UUID");
|
|
259
|
+
need(!v.undo, "A problem dismissal cannot be undone from the CLI");
|
|
260
|
+
}
|
|
261
|
+
if (v.kind === "problem-detection") {
|
|
262
|
+
need(UUID_RE.test(v.target), "Problem id must be a canonical UUID");
|
|
263
|
+
need(v.conversation_id, "--conversation-id is required for problem-detection");
|
|
264
|
+
need(v.attribution_id, "--attribution-id is required for problem-detection");
|
|
265
|
+
}
|
|
266
|
+
if (v.kind === "quote") {
|
|
267
|
+
need(v.family && v.turn !== undefined && v.quote, "--family, --turn and --quote are required for quote (copy them from moda emotions)");
|
|
268
|
+
}
|
|
269
|
+
if (v.kind === "tool") {
|
|
270
|
+
need(v.tool, "--tool is required for tool (the failing tool name)");
|
|
271
|
+
need(v.tool_use_id || v.msg_index !== undefined, "--tool-use-id or --msg-index is required for tool (from moda tool-failure-detail)");
|
|
272
|
+
}
|
|
273
|
+
if (v.kind === "custom-signal") {
|
|
274
|
+
need(v.conversation_id, "--conversation-id is required for custom-signal");
|
|
275
|
+
}
|
|
276
|
+
});
|
|
212
277
|
var EMOTION_FAMILIES = [
|
|
213
278
|
"frustration",
|
|
214
279
|
"sadness",
|
|
@@ -230,6 +295,13 @@ var HallucinationsSchema = z.object({
|
|
|
230
295
|
conversation_id: z.string().max(200).optional(),
|
|
231
296
|
kind: z.enum(["contradicted", "verified"]).optional()
|
|
232
297
|
});
|
|
298
|
+
var LazinessSchema = z.object({
|
|
299
|
+
days_back: z.number().min(1).max(90).default(7).optional(),
|
|
300
|
+
limit: z.number().min(1).max(50).default(10).optional(),
|
|
301
|
+
offset: z.number().min(0).max(1e4).optional(),
|
|
302
|
+
conversation_id: z.string().max(200).optional(),
|
|
303
|
+
family: z.string().regex(/^[a-z_]{1,64}$/, "Family must be a lowercase laziness family").optional()
|
|
304
|
+
});
|
|
233
305
|
var StepScoresSchema = z.object({
|
|
234
306
|
conversation_id: z.string().min(1)
|
|
235
307
|
});
|
|
@@ -5376,12 +5448,21 @@ Commands:
|
|
|
5376
5448
|
frustrations Get user frustration detections (legacy single-family; see emotions)
|
|
5377
5449
|
emotions Multi-family emotion detections (frustration, sadness, confusion, anxiety, trust, positive)
|
|
5378
5450
|
hallucinations Grounding detections: contradicted/verified outputs with rule breakdown
|
|
5451
|
+
laziness Laziness detections per trace (repeated calls, premature handoffs, ...)
|
|
5379
5452
|
tool-failures Get tool failure overview
|
|
5380
5453
|
tool-failure-detail <tool_name> Get per-tool failure detail
|
|
5381
5454
|
problems Rank cross-signal Problems by root cause (what to fix first)
|
|
5382
5455
|
problem-impact Live problem/use-case impact (--node-id, --problem-id, --mode, --days-back)
|
|
5383
5456
|
problem <problem_id> Open one Problem: dossier, or --evidence/--reports/--traces/--feedback
|
|
5384
5457
|
problem-feedback <problem_id> Mark a Problem fixed, dismiss, rename, or flag a bad attribution
|
|
5458
|
+
false-positive <kind> <target> Mark any detection as a false positive, optional --reason (problem, problem-detection, quote, tool, laziness, hallucination, custom-signal)
|
|
5459
|
+
false-positives [conv_id] Current false-positive marks: all (--kind, --all, --limit) or one trace
|
|
5460
|
+
detection-reviews <conv_id> Problem detections on a trace with their review state
|
|
5461
|
+
detection-review <problem_id> Mark a problem detection correct, a false positive, or clear the review
|
|
5462
|
+
signals List custom signals (name, criteria, status, 7-day stats)
|
|
5463
|
+
signal <signal_id> One custom signal, or --detections for its recent hits
|
|
5464
|
+
trace-signals <conversation_id> Custom signal hits on one trace
|
|
5465
|
+
signal-label <signal_id> Label a trace fits / does_not_fit (false positive) for a signal
|
|
5385
5466
|
step-scores <conversation_id> Graph-PRM step scores (per-segment curves, first bad step, rollup)
|
|
5386
5467
|
tail Live-tail new traces/detections as NDJSON (one line per item)
|
|
5387
5468
|
feedback "<note>" Flag wrong/missing data or CLI quirks to the Moda team
|
|
@@ -5485,6 +5566,11 @@ Emotions flags:
|
|
|
5485
5566
|
--days-back=N --limit=N Window 1-90 (default 7); page size 1-20 (default 10)
|
|
5486
5567
|
--offset=N Skip N detections (0-10000)
|
|
5487
5568
|
|
|
5569
|
+
Laziness flags:
|
|
5570
|
+
--family=F Narrow to one laziness family
|
|
5571
|
+
--conversation-id=ID One trace's detections
|
|
5572
|
+
--days-back=N --limit=N Window 1-90 (default 7); page size 1-50 (default 10)
|
|
5573
|
+
|
|
5488
5574
|
Hallucinations flags:
|
|
5489
5575
|
--kind=contradicted|verified Narrow the detections list
|
|
5490
5576
|
--conversation-id=ID Scope summary + list to one trace ID
|
|
@@ -5498,10 +5584,39 @@ Problem flags (moda problem <id>):
|
|
|
5498
5584
|
|
|
5499
5585
|
Problem-feedback flags:
|
|
5500
5586
|
--action=A mark_fixed|dismiss|flag_attribution|rename (required)
|
|
5501
|
-
--reason=TEXT Required for
|
|
5587
|
+
--reason=TEXT Required for flag_attribution; optional for dismiss
|
|
5502
5588
|
--attribution-id=UUID Required for flag_attribution (ids come from problem --evidence)
|
|
5503
5589
|
--new-name=NAME Required for rename
|
|
5504
5590
|
|
|
5591
|
+
False-positive flags (moda false-positive <kind> <target>):
|
|
5592
|
+
--reason=TEXT Why it is wrong (optional)
|
|
5593
|
+
--undo Remove an earlier mark (every kind except problem)
|
|
5594
|
+
problem <problem_id> Dismiss the problem: hidden at once, logged for review, folded into reconcile
|
|
5595
|
+
problem-detection <problem_id> One detection on a trace; needs --conversation-id and --attribution-id; teaches the problem
|
|
5596
|
+
quote <conversation_id> A user quote; needs --family, --turn and --quote (from moda emotions); audit only
|
|
5597
|
+
tool <conversation_id> One failing tool call; needs --tool and --tool-use-id (or --msg-index); audit only
|
|
5598
|
+
laziness <conversation_id> Laziness on that trace; audit only
|
|
5599
|
+
hallucination <conversation_id> Hallucinations on that trace; audit only
|
|
5600
|
+
custom-signal <signal_id> A hit on that trace (--conversation-id); saved as does_not_fit so the signal learns
|
|
5601
|
+
|
|
5602
|
+
Detection-review flags (moda detection-review <problem_id>):
|
|
5603
|
+
--conversation-id=ID Trace the detection is on (required)
|
|
5604
|
+
--attribution-id=UUID Detection id (from problem --evidence or detection-reviews; required)
|
|
5605
|
+
--verdict=V correct|false_positive|clear (required; clear undoes a review)
|
|
5606
|
+
--note=TEXT Why (optional; kept with the review)
|
|
5607
|
+
|
|
5608
|
+
Signal flags:
|
|
5609
|
+
--detections moda signal <id>: list recent hits instead of the summary
|
|
5610
|
+
--days-back=N --limit=N --offset=N
|
|
5611
|
+
Hits window 1-90 (default 7); page size 1-20 (default 10)
|
|
5612
|
+
|
|
5613
|
+
Signal-label flags (moda signal-label <signal_id>):
|
|
5614
|
+
--conversation-id=ID Trace to label (required)
|
|
5615
|
+
--label=fits|does_not_fit does_not_fit marks a false positive and retracts the hit (required)
|
|
5616
|
+
--note=TEXT Why (recommended for does_not_fit)
|
|
5617
|
+
--msg-index=N --msg-dedup-token=T
|
|
5618
|
+
Anchor message (from the hit's anchor_msg_index / anchor_dedup_token)
|
|
5619
|
+
|
|
5505
5620
|
Tail flags:
|
|
5506
5621
|
--signal=S traces|emotions|all (default traces)
|
|
5507
5622
|
--interval=N Poll every N seconds (5-3600, default 15)
|
|
@@ -5626,6 +5741,11 @@ Examples:
|
|
|
5626
5741
|
moda problems --days-back=7
|
|
5627
5742
|
moda problem <problem_id> --evidence --limit=10
|
|
5628
5743
|
moda problem-feedback <problem_id> --action=mark_fixed
|
|
5744
|
+
moda detection-reviews <conversation_id>
|
|
5745
|
+
moda detection-review <problem_id> --conversation-id=<id> --attribution-id=<uuid> --verdict=false_positive --note="expected retry"
|
|
5746
|
+
moda signals
|
|
5747
|
+
moda signal <signal_id> --detections --days-back=30
|
|
5748
|
+
moda signal-label <signal_id> --conversation-id=<id> --label=does_not_fit --note="refund was approved"
|
|
5629
5749
|
moda step-scores <conversation_id>
|
|
5630
5750
|
moda tail --signal=all --interval=30
|
|
5631
5751
|
moda frustrations --days-back=14 --limit=20
|
|
@@ -6350,7 +6470,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6350
6470
|
throw new CliInputError(`Problem id must be a canonical UUID; got "${params.id}".`);
|
|
6351
6471
|
}
|
|
6352
6472
|
const reason = params.reason?.trim() ?? "";
|
|
6353
|
-
if (
|
|
6473
|
+
if (params.action === "flag_attribution" && reason === "") {
|
|
6354
6474
|
throw new CliInputError(`--reason is required for --action=${params.action}.`);
|
|
6355
6475
|
}
|
|
6356
6476
|
if (params.action === "rename" && (params.new_name?.trim() ?? "") === "") {
|
|
@@ -6378,6 +6498,205 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6378
6498
|
context.output.writeData(data);
|
|
6379
6499
|
break;
|
|
6380
6500
|
}
|
|
6501
|
+
case "signals": {
|
|
6502
|
+
const data = await callDataAPI("/custom-signals");
|
|
6503
|
+
context.output.writeData(data);
|
|
6504
|
+
break;
|
|
6505
|
+
}
|
|
6506
|
+
case "signal": {
|
|
6507
|
+
if (!positional) {
|
|
6508
|
+
throw new CliInputError("<signal_id> is required", "Usage: moda signal <signal_id> [--detections] [--days-back=N] [--limit=N] [--offset=N]");
|
|
6509
|
+
}
|
|
6510
|
+
const args = flagsToArgs(flags, "id", positional);
|
|
6511
|
+
args.id = positional;
|
|
6512
|
+
const params = SignalSchema.parse(args);
|
|
6513
|
+
const id = encodeURIComponent(params.id);
|
|
6514
|
+
if (params.detections !== true) {
|
|
6515
|
+
const data2 = await callDataAPI(`/custom-signals/${id}`);
|
|
6516
|
+
context.output.writeData(data2);
|
|
6517
|
+
break;
|
|
6518
|
+
}
|
|
6519
|
+
const query = new URLSearchParams;
|
|
6520
|
+
if (params.days_back)
|
|
6521
|
+
query.set("days_back", params.days_back.toString());
|
|
6522
|
+
if (params.limit)
|
|
6523
|
+
query.set("limit", params.limit.toString());
|
|
6524
|
+
if (params.offset !== undefined)
|
|
6525
|
+
query.set("offset", params.offset.toString());
|
|
6526
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6527
|
+
const data = await callDataAPI(`/custom-signals/${id}/detections${queryString}`);
|
|
6528
|
+
context.output.writeData(data);
|
|
6529
|
+
break;
|
|
6530
|
+
}
|
|
6531
|
+
case "trace-signals": {
|
|
6532
|
+
if (!positional) {
|
|
6533
|
+
throw new CliInputError("<conversation_id> is required", "Usage: moda trace-signals <conversation_id>");
|
|
6534
|
+
}
|
|
6535
|
+
const data = await callDataAPI(`/conversations/${encodeURIComponent(positional)}/custom-signals`);
|
|
6536
|
+
context.output.writeData(data);
|
|
6537
|
+
break;
|
|
6538
|
+
}
|
|
6539
|
+
case "signal-label": {
|
|
6540
|
+
const usage = `Usage: moda signal-label <signal_id> --conversation-id=ID --label=${SIGNAL_LABELS.join("|")} [--note=TEXT] [--msg-index=N] [--msg-dedup-token=T]`;
|
|
6541
|
+
if (!positional) {
|
|
6542
|
+
throw new CliInputError("<signal_id> is required", usage);
|
|
6543
|
+
}
|
|
6544
|
+
const params = SignalLabelSchema.parse({
|
|
6545
|
+
id: positional,
|
|
6546
|
+
...flags["conversation-id"] !== undefined ? { conversation_id: flags["conversation-id"] } : {},
|
|
6547
|
+
...flags.label !== undefined ? { label: flags.label } : {},
|
|
6548
|
+
...flags.note !== undefined ? { note: flags.note } : {},
|
|
6549
|
+
...flags["msg-index"] !== undefined ? { msg_index: flags["msg-index"] } : {},
|
|
6550
|
+
...flags["msg-dedup-token"] !== undefined ? { msg_dedup_token: flags["msg-dedup-token"] } : {}
|
|
6551
|
+
});
|
|
6552
|
+
const note = params.note?.trim() ?? "";
|
|
6553
|
+
const data = await callDataAPI(`/custom-signals/${encodeURIComponent(params.id)}/labels`, {
|
|
6554
|
+
method: "POST",
|
|
6555
|
+
body: JSON.stringify({
|
|
6556
|
+
conversation_id: params.conversation_id,
|
|
6557
|
+
label: params.label,
|
|
6558
|
+
...note !== "" ? { note } : {},
|
|
6559
|
+
...params.msg_index !== undefined ? { msg_index: params.msg_index } : {},
|
|
6560
|
+
...params.msg_dedup_token ? { msg_dedup_token: params.msg_dedup_token } : {}
|
|
6561
|
+
}),
|
|
6562
|
+
headers: { "Content-Type": "application/json" }
|
|
6563
|
+
}, { retries: 0 });
|
|
6564
|
+
context.output.writeData(data);
|
|
6565
|
+
break;
|
|
6566
|
+
}
|
|
6567
|
+
case "detection-reviews": {
|
|
6568
|
+
if (!positional) {
|
|
6569
|
+
throw new CliInputError("<conversation_id> is required", "Usage: moda detection-reviews <conversation_id> [--attribution-id=UUID]");
|
|
6570
|
+
}
|
|
6571
|
+
const attributionId = flags["attribution-id"];
|
|
6572
|
+
if (attributionId !== undefined && !UUID_RE.test(attributionId)) {
|
|
6573
|
+
throw new CliInputError("--attribution-id must be a UUID.");
|
|
6574
|
+
}
|
|
6575
|
+
const queryString = attributionId ? `?attribution_id=${encodeURIComponent(attributionId)}` : "";
|
|
6576
|
+
const data = await callDataAPI(`/conversations/${encodeURIComponent(positional)}/detection-reviews${queryString}`);
|
|
6577
|
+
context.output.writeData(data);
|
|
6578
|
+
break;
|
|
6579
|
+
}
|
|
6580
|
+
case "detection-review": {
|
|
6581
|
+
const usage = `Usage: moda detection-review <problem_id> --conversation-id=ID --attribution-id=UUID --verdict=${DETECTION_VERDICTS.join("|")} [--note=TEXT]`;
|
|
6582
|
+
if (!positional) {
|
|
6583
|
+
throw new CliInputError("<problem_id> is required", usage);
|
|
6584
|
+
}
|
|
6585
|
+
const params = DetectionReviewSchema.parse({
|
|
6586
|
+
id: positional,
|
|
6587
|
+
...flags["conversation-id"] !== undefined ? { conversation_id: flags["conversation-id"] } : {},
|
|
6588
|
+
...flags["attribution-id"] !== undefined ? { attribution_id: flags["attribution-id"] } : {},
|
|
6589
|
+
...flags.verdict !== undefined ? { verdict: flags.verdict } : {},
|
|
6590
|
+
...flags.note !== undefined ? { note: flags.note } : {}
|
|
6591
|
+
});
|
|
6592
|
+
const note = params.verdict === "clear" ? "" : params.note?.trim() ?? "";
|
|
6593
|
+
const data = await callDataAPI(`/problems/${params.id}/detection-reviews`, {
|
|
6594
|
+
method: "POST",
|
|
6595
|
+
body: JSON.stringify({
|
|
6596
|
+
conversation_id: params.conversation_id,
|
|
6597
|
+
attribution_id: params.attribution_id,
|
|
6598
|
+
verdict: params.verdict,
|
|
6599
|
+
...note !== "" ? { note } : {},
|
|
6600
|
+
request_nonce: randomUUID2()
|
|
6601
|
+
}),
|
|
6602
|
+
headers: { "Content-Type": "application/json" }
|
|
6603
|
+
});
|
|
6604
|
+
context.output.writeData(data);
|
|
6605
|
+
break;
|
|
6606
|
+
}
|
|
6607
|
+
case "false-positive": {
|
|
6608
|
+
const usage = `Usage: moda false-positive <${FALSE_POSITIVE_KINDS.join("|")}> <target> --reason=TEXT [--undo]`;
|
|
6609
|
+
const [kind, target] = positionals;
|
|
6610
|
+
if (!kind || !target)
|
|
6611
|
+
throw new CliInputError("<kind> and <target> are required", usage);
|
|
6612
|
+
const params = FalsePositiveSchema.parse({
|
|
6613
|
+
kind,
|
|
6614
|
+
target,
|
|
6615
|
+
undo: flags.undo !== undefined && flags.undo !== "false",
|
|
6616
|
+
...flags.reason !== undefined ? { reason: flags.reason } : {},
|
|
6617
|
+
...flags["conversation-id"] !== undefined ? { conversation_id: flags["conversation-id"] } : {},
|
|
6618
|
+
...flags["attribution-id"] !== undefined ? { attribution_id: flags["attribution-id"] } : {},
|
|
6619
|
+
...flags.family !== undefined ? { family: flags.family } : {},
|
|
6620
|
+
...flags.turn !== undefined ? { turn: flags.turn } : {},
|
|
6621
|
+
...flags.quote !== undefined ? { quote: flags.quote } : {},
|
|
6622
|
+
...flags.tool !== undefined ? { tool: flags.tool } : {},
|
|
6623
|
+
...flags["tool-use-id"] !== undefined ? { tool_use_id: flags["tool-use-id"] } : {},
|
|
6624
|
+
...flags["msg-index"] !== undefined ? { msg_index: flags["msg-index"] } : {},
|
|
6625
|
+
...flags["msg-dedup-token"] !== undefined ? { msg_dedup_token: flags["msg-dedup-token"] } : {}
|
|
6626
|
+
});
|
|
6627
|
+
const reason = params.reason?.trim() ?? "";
|
|
6628
|
+
const post = (path, body, retries) => callDataAPI(path, { method: "POST", body: JSON.stringify(body), headers: { "Content-Type": "application/json" } }, retries === undefined ? undefined : { retries });
|
|
6629
|
+
let data;
|
|
6630
|
+
switch (params.kind) {
|
|
6631
|
+
case "problem":
|
|
6632
|
+
data = await post(`/problems/${params.target}/feedback`, { action: "dismiss", reason, actor: "moda-cli" }, 0);
|
|
6633
|
+
break;
|
|
6634
|
+
case "problem-detection":
|
|
6635
|
+
data = await post(`/problems/${params.target}/detection-reviews`, {
|
|
6636
|
+
conversation_id: params.conversation_id,
|
|
6637
|
+
attribution_id: params.attribution_id,
|
|
6638
|
+
verdict: params.undo ? "clear" : "false_positive",
|
|
6639
|
+
...params.undo ? {} : { note: reason },
|
|
6640
|
+
request_nonce: randomUUID2()
|
|
6641
|
+
});
|
|
6642
|
+
break;
|
|
6643
|
+
case "custom-signal":
|
|
6644
|
+
if (params.undo) {
|
|
6645
|
+
data = await callDataAPI(`/custom-signals/${encodeURIComponent(params.target)}/labels/${encodeURIComponent(params.conversation_id ?? "")}`, { method: "DELETE" }, { retries: 0 });
|
|
6646
|
+
break;
|
|
6647
|
+
}
|
|
6648
|
+
data = await post(`/custom-signals/${encodeURIComponent(params.target)}/labels`, {
|
|
6649
|
+
conversation_id: params.conversation_id,
|
|
6650
|
+
label: "does_not_fit",
|
|
6651
|
+
note: reason,
|
|
6652
|
+
...params.msg_index !== undefined ? { msg_index: params.msg_index } : {},
|
|
6653
|
+
...params.msg_dedup_token ? { msg_dedup_token: params.msg_dedup_token } : {}
|
|
6654
|
+
}, 0);
|
|
6655
|
+
break;
|
|
6656
|
+
default: {
|
|
6657
|
+
const apiKind = { quote: "frustration_quote", tool: "tool_call", laziness: "laziness", hallucination: "hallucination" }[params.kind];
|
|
6658
|
+
data = await post("/false-positives", {
|
|
6659
|
+
kind: apiKind,
|
|
6660
|
+
verdict: params.undo ? "clear" : "false_positive",
|
|
6661
|
+
...params.undo ? {} : { note: reason },
|
|
6662
|
+
conversation_id: params.target,
|
|
6663
|
+
...params.kind === "tool" ? {
|
|
6664
|
+
tool_name: params.tool,
|
|
6665
|
+
...params.tool_use_id ? { tool_use_id: params.tool_use_id } : { msg_index: params.msg_index }
|
|
6666
|
+
} : {},
|
|
6667
|
+
...params.kind === "quote" ? { family: params.family, turn: params.turn, quote: params.quote } : {},
|
|
6668
|
+
request_nonce: randomUUID2()
|
|
6669
|
+
});
|
|
6670
|
+
}
|
|
6671
|
+
}
|
|
6672
|
+
context.output.writeData(data);
|
|
6673
|
+
break;
|
|
6674
|
+
}
|
|
6675
|
+
case "false-positives": {
|
|
6676
|
+
if (!positional) {
|
|
6677
|
+
const kinds = { quote: "frustration_quote", tool: "tool_call", laziness: "laziness", hallucination: "hallucination", "custom-signal": "custom_signal" };
|
|
6678
|
+
const query = new URLSearchParams;
|
|
6679
|
+
if (flags.kind !== undefined) {
|
|
6680
|
+
if (!kinds[flags.kind])
|
|
6681
|
+
throw new CliInputError(`--kind must be one of ${Object.keys(kinds).join("|")}`);
|
|
6682
|
+
query.set("kind", kinds[flags.kind]);
|
|
6683
|
+
}
|
|
6684
|
+
if (flags.limit !== undefined) {
|
|
6685
|
+
if (!/^\d+$/.test(flags.limit) || Number(flags.limit) < 1 || Number(flags.limit) > 200)
|
|
6686
|
+
throw new CliInputError("--limit must be 1-200");
|
|
6687
|
+
query.set("limit", flags.limit);
|
|
6688
|
+
}
|
|
6689
|
+
if (flags.all !== undefined && flags.all !== "false")
|
|
6690
|
+
query.set("include_cleared", "true");
|
|
6691
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6692
|
+
const data2 = await callDataAPI(`/false-positives${queryString}`);
|
|
6693
|
+
context.output.writeData(data2);
|
|
6694
|
+
break;
|
|
6695
|
+
}
|
|
6696
|
+
const data = await callDataAPI(`/conversations/${encodeURIComponent(positional)}/false-positives`);
|
|
6697
|
+
context.output.writeData(data);
|
|
6698
|
+
break;
|
|
6699
|
+
}
|
|
6381
6700
|
case "emotions": {
|
|
6382
6701
|
const args = flagsToArgs(flags);
|
|
6383
6702
|
const params = EmotionsSchema.parse(args);
|
|
@@ -6395,6 +6714,28 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6395
6714
|
context.output.writeData(data);
|
|
6396
6715
|
break;
|
|
6397
6716
|
}
|
|
6717
|
+
case "laziness": {
|
|
6718
|
+
const args = flagsToArgs(flags);
|
|
6719
|
+
if (flags["conversation-id"] !== undefined) {
|
|
6720
|
+
args.conversation_id = flags["conversation-id"];
|
|
6721
|
+
}
|
|
6722
|
+
const params = LazinessSchema.parse(args);
|
|
6723
|
+
const query = new URLSearchParams;
|
|
6724
|
+
if (params.days_back)
|
|
6725
|
+
query.set("days_back", params.days_back.toString());
|
|
6726
|
+
if (params.limit)
|
|
6727
|
+
query.set("limit", params.limit.toString());
|
|
6728
|
+
if (params.offset !== undefined)
|
|
6729
|
+
query.set("offset", params.offset.toString());
|
|
6730
|
+
if (params.conversation_id)
|
|
6731
|
+
query.set("conversation_id", params.conversation_id);
|
|
6732
|
+
if (params.family)
|
|
6733
|
+
query.set("family", params.family);
|
|
6734
|
+
const queryString = query.toString() ? `?${query.toString()}` : "";
|
|
6735
|
+
const data = await callDataAPI(`/laziness${queryString}`);
|
|
6736
|
+
context.output.writeData(data);
|
|
6737
|
+
break;
|
|
6738
|
+
}
|
|
6398
6739
|
case "hallucinations": {
|
|
6399
6740
|
const args = flagsToArgs(flags);
|
|
6400
6741
|
if (flags["conversation-id"] !== undefined) {
|
|
@@ -6580,7 +6921,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6580
6921
|
resetApiRequestCountBeforeRun: true,
|
|
6581
6922
|
telemetry: "result",
|
|
6582
6923
|
handler: async (context) => {
|
|
6583
|
-
const { runInit } = await import("./index-
|
|
6924
|
+
const { runInit } = await import("./index-pf2hvadv.js");
|
|
6584
6925
|
if (context.outputMode === "agent-stream") {
|
|
6585
6926
|
context.output.writeEvent({
|
|
6586
6927
|
event: "started",
|
|
@@ -6621,7 +6962,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6621
6962
|
resetApiRequestCountBeforeRun: true,
|
|
6622
6963
|
telemetry: "result-and-error",
|
|
6623
6964
|
handler: async (context) => {
|
|
6624
|
-
const { runProvision } = await import("./provision-
|
|
6965
|
+
const { runProvision } = await import("./provision-d242y9qd.js");
|
|
6625
6966
|
return runProvision(context, {
|
|
6626
6967
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
6627
6968
|
});
|
|
@@ -7001,6 +7342,83 @@ var commandRegistry = createCommandRegistry([
|
|
|
7001
7342
|
...dataApiDefaults,
|
|
7002
7343
|
mutability: "write"
|
|
7003
7344
|
}),
|
|
7345
|
+
legacyCommand({
|
|
7346
|
+
name: "detection-reviews",
|
|
7347
|
+
description: "List problem detections on a trace with their review state (correct / false_positive / clear)",
|
|
7348
|
+
examples: [
|
|
7349
|
+
"moda detection-reviews <conversation_id>",
|
|
7350
|
+
"moda detection-reviews <conversation_id> --attribution-id=<uuid>"
|
|
7351
|
+
],
|
|
7352
|
+
...dataApiDefaults
|
|
7353
|
+
}),
|
|
7354
|
+
legacyCommand({
|
|
7355
|
+
name: "detection-review",
|
|
7356
|
+
description: "Review a problem detection on a trace: mark it correct, a false positive, or clear the review",
|
|
7357
|
+
examples: [
|
|
7358
|
+
'moda detection-review <problem_id> --conversation-id=<id> --attribution-id=<uuid> --verdict=false_positive --note="expected retry"',
|
|
7359
|
+
"moda detection-review <problem_id> --conversation-id=<id> --attribution-id=<uuid> --verdict=correct",
|
|
7360
|
+
"moda detection-review <problem_id> --conversation-id=<id> --attribution-id=<uuid> --verdict=clear"
|
|
7361
|
+
],
|
|
7362
|
+
...dataApiDefaults,
|
|
7363
|
+
mutability: "write"
|
|
7364
|
+
}),
|
|
7365
|
+
legacyCommand({
|
|
7366
|
+
name: "false-positive",
|
|
7367
|
+
description: "Flag a detection as a false positive with a reason: problem, problem-detection, quote, tool, laziness, hallucination, or custom-signal",
|
|
7368
|
+
examples: [
|
|
7369
|
+
'moda false-positive problem <problem_id> --reason="two unrelated tools"',
|
|
7370
|
+
'moda false-positive problem-detection <problem_id> --conversation-id=<id> --attribution-id=<uuid> --reason="refund was approved"',
|
|
7371
|
+
'moda false-positive quote <conversation_id> --family=frustration --turn=3 --quote="this is useless lol" --reason="joking"',
|
|
7372
|
+
'moda false-positive tool <conversation_id> --tool=send_invoice --tool-use-id=<id> --reason="retried upstream"',
|
|
7373
|
+
'moda false-positive laziness <conversation_id> --reason="reload after context reset is expected"',
|
|
7374
|
+
"moda false-positive hallucination <conversation_id> --undo",
|
|
7375
|
+
"moda false-positive custom-signal <signal_id> --conversation-id=<id> --undo",
|
|
7376
|
+
'moda false-positive custom-signal <signal_id> --conversation-id=<id> --reason="refund was approved"'
|
|
7377
|
+
],
|
|
7378
|
+
...dataApiDefaults,
|
|
7379
|
+
mutability: "write"
|
|
7380
|
+
}),
|
|
7381
|
+
legacyCommand({
|
|
7382
|
+
name: "false-positives",
|
|
7383
|
+
description: "List current false-positive marks across the workspace, or on one trace (with problem detection reviews)",
|
|
7384
|
+
examples: [
|
|
7385
|
+
"moda false-positives",
|
|
7386
|
+
"moda false-positives --kind=tool --all",
|
|
7387
|
+
"moda false-positives <conversation_id>"
|
|
7388
|
+
],
|
|
7389
|
+
...dataApiDefaults
|
|
7390
|
+
}),
|
|
7391
|
+
legacyCommand({
|
|
7392
|
+
name: "signals",
|
|
7393
|
+
description: "List custom signals with criteria, status, and 7-day judged/matched stats",
|
|
7394
|
+
examples: ["moda signals"],
|
|
7395
|
+
...dataApiDefaults
|
|
7396
|
+
}),
|
|
7397
|
+
legacyCommand({
|
|
7398
|
+
name: "signal",
|
|
7399
|
+
description: "Open one custom signal, or --detections for its recent hits (paged)",
|
|
7400
|
+
examples: [
|
|
7401
|
+
"moda signal <signal_id>",
|
|
7402
|
+
"moda signal <signal_id> --detections --days-back=30 --limit=20"
|
|
7403
|
+
],
|
|
7404
|
+
...dataApiDefaults
|
|
7405
|
+
}),
|
|
7406
|
+
legacyCommand({
|
|
7407
|
+
name: "trace-signals",
|
|
7408
|
+
description: "Custom signal hits on one trace",
|
|
7409
|
+
examples: ["moda trace-signals <conversation_id>"],
|
|
7410
|
+
...dataApiDefaults
|
|
7411
|
+
}),
|
|
7412
|
+
legacyCommand({
|
|
7413
|
+
name: "signal-label",
|
|
7414
|
+
description: "Label a trace for a custom signal: fits, or does_not_fit to mark a false positive",
|
|
7415
|
+
examples: [
|
|
7416
|
+
'moda signal-label <signal_id> --conversation-id=<id> --label=does_not_fit --note="refund was approved"',
|
|
7417
|
+
"moda signal-label <signal_id> --conversation-id=<id> --label=fits --msg-index=12"
|
|
7418
|
+
],
|
|
7419
|
+
...dataApiDefaults,
|
|
7420
|
+
mutability: "write"
|
|
7421
|
+
}),
|
|
7004
7422
|
legacyCommand({
|
|
7005
7423
|
name: "emotions",
|
|
7006
7424
|
description: "Multi-family emotion detections (frustration, sadness, confusion, anxiety, trust, positive)",
|
|
@@ -7010,6 +7428,15 @@ var commandRegistry = createCommandRegistry([
|
|
|
7010
7428
|
],
|
|
7011
7429
|
...dataApiDefaults
|
|
7012
7430
|
}),
|
|
7431
|
+
legacyCommand({
|
|
7432
|
+
name: "laziness",
|
|
7433
|
+
description: "Laziness detections per trace: repeated tool calls, premature handoffs, and other lazy patterns",
|
|
7434
|
+
examples: [
|
|
7435
|
+
"moda laziness --days-back=30",
|
|
7436
|
+
"moda laziness --conversation-id=<id>"
|
|
7437
|
+
],
|
|
7438
|
+
...dataApiDefaults
|
|
7439
|
+
}),
|
|
7013
7440
|
legacyCommand({
|
|
7014
7441
|
name: "hallucinations",
|
|
7015
7442
|
description: "Grounding detections: contradicted/verified outputs with rule breakdown",
|
|
@@ -42,8 +42,8 @@ import {
|
|
|
42
42
|
writeHarnessAnalyzeResult,
|
|
43
43
|
writeHarnessArtifacts,
|
|
44
44
|
writeHumanProgress
|
|
45
|
-
} from "./cli-
|
|
46
|
-
import"./cli-
|
|
45
|
+
} from "./cli-0p6n391h.js";
|
|
46
|
+
import"./cli-drabjmaj.js";
|
|
47
47
|
export {
|
|
48
48
|
writeHumanProgress,
|
|
49
49
|
writeHarnessArtifacts,
|