@moda-ai/cli 1.55.39 → 1.55.41
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/{agent-bhe95ae8.js → agent-ck6y31n2.js} +8 -8
- package/dist/{cli-qzag917n.js → cli-0xc5htv7.js} +1 -1
- package/dist/{cli-39617gab.js → cli-1z1sx8dg.js} +3 -3
- package/dist/{cli-jmbt1hf9.js → cli-4tg0hkbz.js} +8 -8
- package/dist/{cli-4hkesrkq.js → cli-77ekrx7d.js} +1 -1
- package/dist/{cli-6gtgm2gx.js → cli-7bn406mt.js} +4 -4
- package/dist/{cli-msgp78ag.js → cli-a8nxbtpk.js} +5 -5
- package/dist/{cli-c7vj8tq1.js → cli-azage7s0.js} +5 -5
- package/dist/{cli-2h2nvq6w.js → cli-daqkdnm1.js} +1 -1
- package/dist/{cli-k9se46y4.js → cli-f1jfrqgf.js} +21 -4
- package/dist/{cli-1vqq24qh.js → cli-gt3yq1y5.js} +2 -2
- package/dist/{cli-ptm7pwqg.js → cli-pmzh2qjy.js} +1 -1
- package/dist/{cli-wr6f0kyw.js → cli-t0pb7qbs.js} +1 -0
- package/dist/{cli-jkza0bj6.js → cli-xddtv3yn.js} +1 -1
- package/dist/{cli-as4c1xwm.js → cli-ypqwcf9n.js} +5 -5
- package/dist/cli.js +313 -26
- package/dist/{doctor-3v20hc26.js → doctor-p8sp6cbk.js} +7 -7
- package/dist/{fix-s3zkjt69.js → fix-0r974yge.js} +4 -4
- package/dist/{harness-n4569wbm.js → harness-72ejenza.js} +5 -5
- package/dist/{harness-github-actions-mcy21e4d.js → harness-github-actions-2qc4gg2w.js} +5 -5
- package/dist/{index-2qm3h7v2.js → index-w7v472w4.js} +11 -11
- package/dist/{production-intelligence-z2cad1hv.js → production-intelligence-e5vsc6cw.js} +143 -30
- package/dist/{profile-commands-7ck1tqfv.js → profile-commands-se9947c1.js} +3 -3
- package/dist/{prompt-attribution-dm50am6e.js → prompt-attribution-3987hhqz.js} +5 -5
- package/dist/prompt-source-mcp.js +5 -5
- package/dist/{prompts-ab-9e0dsmce.js → prompts-ab-gmd10n5d.js} +7 -7
- package/dist/{prompts-propose-91qrjpd0.js → prompts-propose-q626zmm4.js} +7 -7
- package/dist/{prompts-p9hhxx0c.js → prompts-ysm9ra72.js} +5 -5
- package/dist/{provision-x4wkyw60.js → provision-cya5rpxa.js} +5 -5
- package/dist/{registry-nq8qsqtv.js → registry-7xz09ry0.js} +3 -3
- package/dist/{skills-rk2pmwx8.js → skills-x6yszxxn.js} +5 -5
- package/dist/{sync-xxbfjcz5.js → sync-trjzvam9.js} +7 -7
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +8 -4
- package/skills/moda-cli/references/commands.md +1 -0
- package/skills/moda-cli/references/detections.md +29 -0
- package/skills/moda-cli/references/production-intelligence.md +5 -1
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,8 @@ import {
|
|
|
13
13
|
frustrationsFromEmotions,
|
|
14
14
|
mapWithConcurrency,
|
|
15
15
|
parseBatchTarget,
|
|
16
|
+
parseTargetLines,
|
|
17
|
+
readIdsFrom,
|
|
16
18
|
shapeToolCatalogDetail,
|
|
17
19
|
toolCatalogGetCommand,
|
|
18
20
|
toolFailureExamplesCommand,
|
|
@@ -20,7 +22,7 @@ import {
|
|
|
20
22
|
withFrustrationAnchors,
|
|
21
23
|
withToolFailureAnchors,
|
|
22
24
|
withoutDetectionWindows
|
|
23
|
-
} from "./cli-
|
|
25
|
+
} from "./cli-gt3yq1y5.js";
|
|
24
26
|
import {
|
|
25
27
|
createCommandContext,
|
|
26
28
|
envOptOutSet,
|
|
@@ -28,7 +30,7 @@ import {
|
|
|
28
30
|
optOutFlagSet,
|
|
29
31
|
parseBooleanFlagValue,
|
|
30
32
|
withoutFlag
|
|
31
|
-
} from "./cli-
|
|
33
|
+
} from "./cli-xddtv3yn.js";
|
|
32
34
|
import {
|
|
33
35
|
AuditSchema,
|
|
34
36
|
BOOK_PROBLEM_SORTS,
|
|
@@ -41,6 +43,7 @@ import {
|
|
|
41
43
|
FEEDBACK_USAGE,
|
|
42
44
|
FalsePositiveSchema,
|
|
43
45
|
LAZINESS_FAMILIES,
|
|
46
|
+
MAX_CONVERSATION_IDS_FILTER,
|
|
44
47
|
PROBLEMS_DEFAULT_LIMIT,
|
|
45
48
|
PROBLEMS_MAX_LIMIT,
|
|
46
49
|
PROBLEM_FEEDBACK_ACTIONS,
|
|
@@ -52,6 +55,7 @@ import {
|
|
|
52
55
|
SignalLabelSchema,
|
|
53
56
|
StepScoresSchema,
|
|
54
57
|
TRACE_GRAIN_FLAGS,
|
|
58
|
+
TraceFindingsSchema,
|
|
55
59
|
UUID_RE,
|
|
56
60
|
assertFlags,
|
|
57
61
|
assertPositionals,
|
|
@@ -75,12 +79,12 @@ import {
|
|
|
75
79
|
unknownSignalsSubcommandError,
|
|
76
80
|
usageLine,
|
|
77
81
|
writeDryRun
|
|
78
|
-
} from "./cli-
|
|
82
|
+
} from "./cli-f1jfrqgf.js";
|
|
79
83
|
import {
|
|
80
84
|
ApiError,
|
|
81
85
|
callControlAPI,
|
|
82
86
|
callDataAPI
|
|
83
|
-
} from "./cli-
|
|
87
|
+
} from "./cli-0xc5htv7.js";
|
|
84
88
|
import {
|
|
85
89
|
AGENT_ERROR_CODES,
|
|
86
90
|
EXIT_AUTH_REQUIRED,
|
|
@@ -117,7 +121,7 @@ import {
|
|
|
117
121
|
shellArg,
|
|
118
122
|
validateConfig,
|
|
119
123
|
wasOutputCancelled
|
|
120
|
-
} from "./cli-
|
|
124
|
+
} from "./cli-t0pb7qbs.js";
|
|
121
125
|
import {
|
|
122
126
|
CliAccessError,
|
|
123
127
|
CliAuthError,
|
|
@@ -140,6 +144,175 @@ import {
|
|
|
140
144
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
141
145
|
import { z } from "zod";
|
|
142
146
|
|
|
147
|
+
// src/trace-findings.ts
|
|
148
|
+
var FINDINGS_FAMILIES = ["emotion", "laziness", "hallucination", "tool_failure", "custom_signal"];
|
|
149
|
+
var FINDINGS_DEFAULT_LIMIT = 3;
|
|
150
|
+
var NEXT_COMMANDS_SINGLE = 8;
|
|
151
|
+
var NEXT_COMMANDS_BATCH = 2;
|
|
152
|
+
var TEXT_CHARS = 160;
|
|
153
|
+
function familyState(entry) {
|
|
154
|
+
const count = asNumber(entry.count) ?? 0;
|
|
155
|
+
if (count > 0)
|
|
156
|
+
return "found";
|
|
157
|
+
const enabled = asRecord(entry.detector)?.enabled;
|
|
158
|
+
if (enabled === false || entry.processed === false)
|
|
159
|
+
return "not_run";
|
|
160
|
+
if (entry.processed === true)
|
|
161
|
+
return "none";
|
|
162
|
+
return "unknown";
|
|
163
|
+
}
|
|
164
|
+
function clip(value, max = TEXT_CHARS) {
|
|
165
|
+
const text = asString(value);
|
|
166
|
+
if (!text)
|
|
167
|
+
return;
|
|
168
|
+
return text.length <= max ? text : `${text.slice(0, max - 3)}...`;
|
|
169
|
+
}
|
|
170
|
+
function stripUndefined(row) {
|
|
171
|
+
return Object.fromEntries(Object.entries(row).filter(([, value]) => value !== undefined && value !== ""));
|
|
172
|
+
}
|
|
173
|
+
function compactRow(family, row) {
|
|
174
|
+
const msgIndex = asNumber(row.msg_index);
|
|
175
|
+
switch (family) {
|
|
176
|
+
case "emotion": {
|
|
177
|
+
const quote = asRecord(Array.isArray(row.user_quotes) ? row.user_quotes[0] : undefined);
|
|
178
|
+
return stripUndefined({
|
|
179
|
+
msg_index: msgIndex,
|
|
180
|
+
family: row.family,
|
|
181
|
+
polarity: row.polarity,
|
|
182
|
+
score: row.score,
|
|
183
|
+
trajectory: row.trajectory,
|
|
184
|
+
cause: clip(row.primary_cause),
|
|
185
|
+
quote: clip(quote?.quote)
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
case "laziness":
|
|
189
|
+
return stripUndefined({ msg_index: msgIndex, family: row.family, pattern: row.pattern_id, confidence: row.confidence, snippet: clip(row.snippet) });
|
|
190
|
+
case "hallucination":
|
|
191
|
+
return stripUndefined({ msg_index: msgIndex, rule: row.rule_id, confidence: row.confidence, claim: clip(row.offending_substring), evidence: clip(row.evidence_quote) });
|
|
192
|
+
case "tool_failure":
|
|
193
|
+
return stripUndefined({ msg_index: msgIndex, tool: row.tool_name, tool_use_id: row.tool_use_id, category: row.category, error: clip(row.error_message) });
|
|
194
|
+
case "custom_signal":
|
|
195
|
+
return stripUndefined({ msg_index: msgIndex, signal: row.signal_name, signal_id: row.signal_id, confidence: row.confidence, rationale: clip(row.rationale) });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function anchorCommand(conversationId, msgIndex) {
|
|
199
|
+
return `moda traces get ${shellArg(contextTarget(conversationId))} --msg-index=${msgIndex} --window=2`;
|
|
200
|
+
}
|
|
201
|
+
function compactFindings(raw, opts) {
|
|
202
|
+
const record = asRecord(raw) ?? {};
|
|
203
|
+
const conversationId = asString(record.conversation_id) ?? "";
|
|
204
|
+
const families = asRecord(record.families) ?? {};
|
|
205
|
+
const out = {};
|
|
206
|
+
const anchors = [];
|
|
207
|
+
const byFamily = {};
|
|
208
|
+
const states = {};
|
|
209
|
+
for (const family of FINDINGS_FAMILIES) {
|
|
210
|
+
const entry = asRecord(families[family]);
|
|
211
|
+
if (!entry)
|
|
212
|
+
continue;
|
|
213
|
+
const rows = (Array.isArray(entry.detections) ? entry.detections : []).map((row) => asRecord(row)).filter((row) => row !== null);
|
|
214
|
+
const count = asNumber(entry.count) ?? rows.length;
|
|
215
|
+
const state = familyState(entry);
|
|
216
|
+
const detector = asRecord(entry.detector) ?? {};
|
|
217
|
+
const top = rows.slice(0, opts.limit).map((row) => compactRow(family, row));
|
|
218
|
+
for (const row of top) {
|
|
219
|
+
const msgIndex = asNumber(row.msg_index);
|
|
220
|
+
if (msgIndex !== null)
|
|
221
|
+
anchors.push({ family, msgIndex, label: String(row.family ?? row.tool ?? row.signal ?? row.rule ?? family) });
|
|
222
|
+
}
|
|
223
|
+
byFamily[family] = count;
|
|
224
|
+
states[family] = state;
|
|
225
|
+
out[family] = stripUndefined({
|
|
226
|
+
state,
|
|
227
|
+
count,
|
|
228
|
+
...opts.batch ? {} : { enabled: detector.enabled ?? null, processed: entry.processed ?? null },
|
|
229
|
+
...family === "hallucination" && asNumber(entry.verified_claims) ? { verified_claims: entry.verified_claims } : {},
|
|
230
|
+
top: opts.batch && top.length === 0 ? undefined : top,
|
|
231
|
+
more: count > top.length ? count - top.length : undefined
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
const problemsBlock = asRecord(record.problems) ?? {};
|
|
235
|
+
const problemRows = (Array.isArray(problemsBlock.problems) ? problemsBlock.problems : []).map((row) => asRecord(row)).filter((row) => row !== null);
|
|
236
|
+
const problemCount = asNumber(problemsBlock.count) ?? problemRows.length;
|
|
237
|
+
const problems = stripUndefined({
|
|
238
|
+
count: problemCount,
|
|
239
|
+
processed: problemsBlock.processed ?? null,
|
|
240
|
+
top: problemRows.slice(0, opts.limit).map((row) => stripUndefined({
|
|
241
|
+
problem_id: row.problem_id,
|
|
242
|
+
title: clip(row.title),
|
|
243
|
+
attribution_count: row.attribution_count,
|
|
244
|
+
lifecycle: row.lifecycle ?? undefined,
|
|
245
|
+
in_book: row.in_book
|
|
246
|
+
})),
|
|
247
|
+
more: problemCount > Math.min(problemRows.length, opts.limit) ? problemCount - Math.min(problemRows.length, opts.limit) : undefined
|
|
248
|
+
});
|
|
249
|
+
const total = Object.values(byFamily).reduce((sum, value) => sum + value, 0);
|
|
250
|
+
const data = opts.batch ? { detections: total, families: out, problems } : {
|
|
251
|
+
conversation_id: conversationId,
|
|
252
|
+
window: "all",
|
|
253
|
+
summary: { detections: total, by_family: byFamily, problems: problemCount },
|
|
254
|
+
families: out,
|
|
255
|
+
problems
|
|
256
|
+
};
|
|
257
|
+
const nextCommands = [];
|
|
258
|
+
const seen = new Set;
|
|
259
|
+
for (const anchor of anchors) {
|
|
260
|
+
if (seen.has(anchor.msgIndex))
|
|
261
|
+
continue;
|
|
262
|
+
seen.add(anchor.msgIndex);
|
|
263
|
+
nextCommands.push({
|
|
264
|
+
command: anchorCommand(conversationId, anchor.msgIndex),
|
|
265
|
+
purpose: `Read message ${anchor.msgIndex} (${anchor.family}: ${anchor.label}) with 2 messages either side.`,
|
|
266
|
+
mutability: "read",
|
|
267
|
+
requires_approval: false
|
|
268
|
+
});
|
|
269
|
+
if (nextCommands.length >= (opts.batch ? NEXT_COMMANDS_BATCH : NEXT_COMMANDS_SINGLE))
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
if (!opts.batch) {
|
|
273
|
+
const topProblem = asString(problemRows[0]?.problem_id);
|
|
274
|
+
if (topProblem) {
|
|
275
|
+
nextCommands.push({
|
|
276
|
+
command: `moda problems get ${shellArg(topProblem)}`,
|
|
277
|
+
purpose: "Open the Problem this trace is most evidence for.",
|
|
278
|
+
mutability: "read",
|
|
279
|
+
requires_approval: false
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const notRun = FINDINGS_FAMILIES.filter((family) => states[family] === "not_run");
|
|
284
|
+
const unknown = FINDINGS_FAMILIES.filter((family) => states[family] === "unknown");
|
|
285
|
+
const found = FINDINGS_FAMILIES.filter((family) => states[family] === "found").map((family) => `${byFamily[family]} ${family}`);
|
|
286
|
+
const summary = `${conversationId}: ${total} detection${total === 1 ? "" : "s"}` + (found.length > 0 ? ` (${found.join(", ")})` : "") + `, evidence for ${problemCount} Problem${problemCount === 1 ? "" : "s"}. No time window.`;
|
|
287
|
+
const warnings = [];
|
|
288
|
+
if (notRun.length > 0) {
|
|
289
|
+
warnings.push(`Not run on this trace (detector off or not processed yet): ${notRun.join(", ")}. No detections there does not mean clean.`);
|
|
290
|
+
}
|
|
291
|
+
if (unknown.length > 0 && total === 0) {
|
|
292
|
+
warnings.push(`Nothing flagged, and ${unknown.join(", ")} record nothing for a clean trace, so whether they ran is not known.`);
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
data,
|
|
296
|
+
options: {
|
|
297
|
+
summary,
|
|
298
|
+
...warnings.length > 0 && !opts.batch ? { warnings } : {},
|
|
299
|
+
...nextCommands.length > 0 ? { nextCommands } : {}
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
function batchNotRunWarning(results) {
|
|
304
|
+
const notRun = results.flatMap((result) => {
|
|
305
|
+
const families = asRecord(asRecord(result.data)?.families);
|
|
306
|
+
if (!result.ok || !families)
|
|
307
|
+
return [];
|
|
308
|
+
const names = FINDINGS_FAMILIES.filter((family) => asRecord(families[family])?.state === "not_run");
|
|
309
|
+
return names.length > 0 ? [`${result.target} (${names.join(", ")})`] : [];
|
|
310
|
+
});
|
|
311
|
+
if (notRun.length === 0)
|
|
312
|
+
return [];
|
|
313
|
+
return [`Families not run (detector off or trace not processed yet), so no detections there does not mean clean: ${notRun.join("; ")}.`];
|
|
314
|
+
}
|
|
315
|
+
|
|
143
316
|
// src/replays.ts
|
|
144
317
|
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
145
318
|
var PLAYOUT_ID_RE = /^[0-9a-f]{64}$/i;
|
|
@@ -1145,6 +1318,18 @@ var CANONICAL_LEAVES = [
|
|
|
1145
1318
|
summary: "A trace's world state (slots, threads, events)",
|
|
1146
1319
|
examples: ["moda traces state <conversation_id> --summary-only", "moda traces state <conversation_id> --snapshot --msg-index=12"]
|
|
1147
1320
|
},
|
|
1321
|
+
{
|
|
1322
|
+
noun: "traces",
|
|
1323
|
+
verb: "findings",
|
|
1324
|
+
path: "traces findings",
|
|
1325
|
+
args: "<conversation_id>...",
|
|
1326
|
+
handler: "trace-findings",
|
|
1327
|
+
summary: "Everything flagged on a trace (every detector family and its Problems), no time window; up to 25 ids per call",
|
|
1328
|
+
examples: [
|
|
1329
|
+
"moda traces findings <conversation_id>",
|
|
1330
|
+
"moda traces findings <id1> <id2> <id3> # batch: up to 25 ids (or --ids-from=-|<file>)"
|
|
1331
|
+
]
|
|
1332
|
+
},
|
|
1148
1333
|
{
|
|
1149
1334
|
noun: "traces",
|
|
1150
1335
|
verb: "spans",
|
|
@@ -1303,7 +1488,7 @@ var CANONICAL_LEAVES = [
|
|
|
1303
1488
|
];
|
|
1304
1489
|
var CANONICAL_NOUNS = ["traces", "problems", "detections", "tools", "review", "reviews", "skills"];
|
|
1305
1490
|
var NOUN_SUMMARIES = {
|
|
1306
|
-
traces: "Traces (agent runs): list, search, read, world state, raw spans",
|
|
1491
|
+
traces: "Traces (agent runs): list, search, read, findings, world state, raw spans",
|
|
1307
1492
|
problems: "Problems ranked by root cause, their evidence, impact and lifecycle",
|
|
1308
1493
|
detections: "Detections of every family, and the tool failure leaderboard",
|
|
1309
1494
|
tools: "The Tool catalog: every tool with calls and success rate, and one tool's schema, usage and failure categories",
|
|
@@ -1414,6 +1599,10 @@ function routeDetectionsList(leaf, rest, flags) {
|
|
|
1414
1599
|
throw inputError(`'moda detections list' takes no arguments, but got '${rest.join(" ")}'.`, DETECTIONS_LIST_USAGE, "unexpected_positional");
|
|
1415
1600
|
}
|
|
1416
1601
|
const label = `detections list --family=${family}`;
|
|
1602
|
+
const severalTraces = ["conversation-ids", "conversation_ids", "ids-from", "ids_from"].find((key) => flags[key] !== undefined);
|
|
1603
|
+
if (severalTraces && (family === "custom_signal" || family === "tool_failure")) {
|
|
1604
|
+
throw inputError(`--${severalTraces.replace(/_/g, "-")} is not available with --family=${family}. Read several traces' ${family === "custom_signal" ? "custom signal hits" : "tool failures"} with 'moda traces findings <id> <id> ...' (up to 25 ids).`, DETECTIONS_LIST_USAGE, `inapplicable_flag:${severalTraces.replace(/_/g, "-")}`, { field: `--${severalTraces.replace(/_/g, "-")}`, suggestedCommands: ["moda traces findings --help"] });
|
|
1605
|
+
}
|
|
1417
1606
|
if (family === "custom_signal") {
|
|
1418
1607
|
const signalId = flags["signal-id"];
|
|
1419
1608
|
const traceId = flags["conversation-id"];
|
|
@@ -2986,46 +3175,46 @@ function leafManifestFields(leaf, commands) {
|
|
|
2986
3175
|
import { fileURLToPath } from "url";
|
|
2987
3176
|
import { realpathSync } from "fs";
|
|
2988
3177
|
async function runPromptsCommand(...args) {
|
|
2989
|
-
return (await import("./prompts-
|
|
3178
|
+
return (await import("./prompts-ysm9ra72.js")).runPromptsCommand(...args);
|
|
2990
3179
|
}
|
|
2991
3180
|
async function runSkillsCommand(...args) {
|
|
2992
|
-
return (await import("./skills-
|
|
3181
|
+
return (await import("./skills-x6yszxxn.js")).runSkillsCommand(...args);
|
|
2993
3182
|
}
|
|
2994
3183
|
async function runFixCommand(...args) {
|
|
2995
|
-
return (await import("./fix-
|
|
3184
|
+
return (await import("./fix-0r974yge.js")).runFixCommand(...args);
|
|
2996
3185
|
}
|
|
2997
3186
|
async function runFixesCommand(...args) {
|
|
2998
|
-
return (await import("./fix-
|
|
3187
|
+
return (await import("./fix-0r974yge.js")).runFixesCommand(...args);
|
|
2999
3188
|
}
|
|
3000
3189
|
async function runHarnessCommand(...args) {
|
|
3001
|
-
return (await import("./harness-
|
|
3190
|
+
return (await import("./harness-72ejenza.js")).runHarnessCommand(...args);
|
|
3002
3191
|
}
|
|
3003
3192
|
async function runSyncCommand(...args) {
|
|
3004
|
-
return (await import("./sync-
|
|
3193
|
+
return (await import("./sync-trjzvam9.js")).runSyncCommand(...args);
|
|
3005
3194
|
}
|
|
3006
3195
|
async function runRegistryCommand(...args) {
|
|
3007
|
-
return (await import("./registry-
|
|
3196
|
+
return (await import("./registry-7xz09ry0.js")).runRegistryCommand(...args);
|
|
3008
3197
|
}
|
|
3009
3198
|
async function runDoctorCommand(...args) {
|
|
3010
|
-
return (await import("./doctor-
|
|
3199
|
+
return (await import("./doctor-p8sp6cbk.js")).runDoctorCommand(...args);
|
|
3011
3200
|
}
|
|
3012
3201
|
async function runStatusCommand(...args) {
|
|
3013
|
-
return (await import("./doctor-
|
|
3202
|
+
return (await import("./doctor-p8sp6cbk.js")).runStatusCommand(...args);
|
|
3014
3203
|
}
|
|
3015
3204
|
async function runAuthCommand(...args) {
|
|
3016
|
-
return (await import("./profile-commands-
|
|
3205
|
+
return (await import("./profile-commands-se9947c1.js")).runAuthCommand(...args);
|
|
3017
3206
|
}
|
|
3018
3207
|
async function runConfigCommand(...args) {
|
|
3019
|
-
return (await import("./profile-commands-
|
|
3208
|
+
return (await import("./profile-commands-se9947c1.js")).runConfigCommand(...args);
|
|
3020
3209
|
}
|
|
3021
3210
|
async function runProfilesCommand(...args) {
|
|
3022
|
-
return (await import("./profile-commands-
|
|
3211
|
+
return (await import("./profile-commands-se9947c1.js")).runProfilesCommand(...args);
|
|
3023
3212
|
}
|
|
3024
3213
|
async function runAgentCommand(...args) {
|
|
3025
|
-
return (await import("./agent-
|
|
3214
|
+
return (await import("./agent-ck6y31n2.js")).runAgentCommand(...args);
|
|
3026
3215
|
}
|
|
3027
3216
|
async function runProductionCommand(...args) {
|
|
3028
|
-
return (await import("./production-intelligence-
|
|
3217
|
+
return (await import("./production-intelligence-e5vsc6cw.js")).runProductionCommand(...args);
|
|
3029
3218
|
}
|
|
3030
3219
|
function parseArgs(argv) {
|
|
3031
3220
|
const args = argv.slice(2);
|
|
@@ -4451,7 +4640,7 @@ function rejectInapplicableFlags(command, params, keys, why) {
|
|
|
4451
4640
|
const shown = canonicalCommandText(`moda ${command}`);
|
|
4452
4641
|
throw new CliInputError(`${names.join(", ")} ${given.length > 1 ? "do" : "does"} not apply ${why}, so nothing was sent.`, `Drop ${names.join(", ")}, or pick the mode that uses ${given.length > 1 ? "them" : "it"}. See '${shown} --help'.`, `inapplicable_flag:${names[0].slice(2)}`, { field: names[0], suggestedCommands: [`${shown} --help`] });
|
|
4453
4642
|
}
|
|
4454
|
-
var BATCH_POSITIONAL_COMMANDS = new Set(["context", "audit", "trace"]);
|
|
4643
|
+
var BATCH_POSITIONAL_COMMANDS = new Set(["context", "audit", "trace", "trace-findings"]);
|
|
4455
4644
|
function assertPositionalArity(command, positionals) {
|
|
4456
4645
|
const spec = flagSpecFor(command);
|
|
4457
4646
|
const expected = spec?.positionals ?? [];
|
|
@@ -5410,6 +5599,79 @@ async function runContextBatch(command, positionals, flags, context) {
|
|
|
5410
5599
|
});
|
|
5411
5600
|
return writeBatchResult(command, context, targets, results, inputWarnings, rest);
|
|
5412
5601
|
}
|
|
5602
|
+
var CONVERSATION_IDS_USAGE = `Usage: moda detections list --family=emotion|frustration|laziness|hallucination --conversation-ids=<id>,<id>,... | --ids-from=-|<file> (up to ${MAX_CONVERSATION_IDS_FILTER} ids)`;
|
|
5603
|
+
async function conversationIdsFilter(params, context) {
|
|
5604
|
+
if (params.conversation_ids === undefined && params.ids_from === undefined)
|
|
5605
|
+
return;
|
|
5606
|
+
if (params.conversation_ids !== undefined && params.ids_from !== undefined) {
|
|
5607
|
+
throw new CliInputError("Pass --conversation-ids or --ids-from, not both.", CONVERSATION_IDS_USAGE, "flag_conflict");
|
|
5608
|
+
}
|
|
5609
|
+
if (params.conversation_id !== undefined) {
|
|
5610
|
+
throw new CliInputError("--conversation-id reads one trace and --conversation-ids/--ids-from several; pass one of them.", CONVERSATION_IDS_USAGE, "flag_conflict");
|
|
5611
|
+
}
|
|
5612
|
+
let ids;
|
|
5613
|
+
if (params.ids_from !== undefined) {
|
|
5614
|
+
ids = parseTargetLines(await readIdsFrom(params.ids_from, CONVERSATION_IDS_USAGE), false, CONVERSATION_IDS_USAGE).map((target) => target.id);
|
|
5615
|
+
} else {
|
|
5616
|
+
const text = params.conversation_ids.trim();
|
|
5617
|
+
let parsed = undefined;
|
|
5618
|
+
if (text.startsWith("[")) {
|
|
5619
|
+
try {
|
|
5620
|
+
parsed = JSON.parse(text);
|
|
5621
|
+
} catch {
|
|
5622
|
+
throw new CliInputError("--conversation-ids starts with [ but is not a JSON array of ids.", CONVERSATION_IDS_USAGE, "bad_value:conversation-ids");
|
|
5623
|
+
}
|
|
5624
|
+
}
|
|
5625
|
+
ids = Array.isArray(parsed) ? parsed.map((id) => String(id).trim()) : text.split(",").map((id) => id.trim());
|
|
5626
|
+
}
|
|
5627
|
+
const unique = [...new Set(ids.filter((id) => id !== ""))];
|
|
5628
|
+
if (unique.length === 0) {
|
|
5629
|
+
throw new CliInputError("No trace ids: --conversation-ids/--ids-from gave none.", CONVERSATION_IDS_USAGE, "missing_value:conversation-ids");
|
|
5630
|
+
}
|
|
5631
|
+
if (unique.length > MAX_CONVERSATION_IDS_FILTER) {
|
|
5632
|
+
throw new CliInputError(`Got ${unique.length} trace ids; the detection lists take at most ${MAX_CONVERSATION_IDS_FILTER} per call, so nothing was read. Split them into calls of ${MAX_CONVERSATION_IDS_FILTER} or fewer.`, CONVERSATION_IDS_USAGE, "batch_too_large");
|
|
5633
|
+
}
|
|
5634
|
+
const withComma = unique.find((id) => id.includes(","));
|
|
5635
|
+
if (withComma !== undefined) {
|
|
5636
|
+
throw new CliInputError(`Trace id ${JSON.stringify(withComma)} has a comma, which the several-trace filter cannot carry. Read it with --conversation-id instead.`, CONVERSATION_IDS_USAGE, "bad_value:conversation-ids");
|
|
5637
|
+
}
|
|
5638
|
+
if (params.ids_from !== undefined && context.invocation) {
|
|
5639
|
+
for (const key of IDS_FROM_KEYS)
|
|
5640
|
+
delete context.invocation.flags[key];
|
|
5641
|
+
context.invocation.flags["conversation-ids"] = unique.join(",");
|
|
5642
|
+
}
|
|
5643
|
+
return unique;
|
|
5644
|
+
}
|
|
5645
|
+
var TRACE_FINDINGS_USAGE = `Usage: moda traces findings <conversation_id> [<conversation_id> ...] | --ids-from=-|<file> [--limit=N] (max ${BATCH_MAX_TARGETS} ids)`;
|
|
5646
|
+
async function runTraceFindings(command, positionals, flags, context) {
|
|
5647
|
+
const { idsFrom, rest } = splitIdsFrom(flags);
|
|
5648
|
+
if (positionals.length === 0 && idsFrom === undefined) {
|
|
5649
|
+
throw new CliInputError("<conversation_id> is required", TRACE_FINDINGS_USAGE, "missing_positional");
|
|
5650
|
+
}
|
|
5651
|
+
const targets = await collectBatchTargets(positionals, idsFrom, { anchors: false, usage: TRACE_FINDINGS_USAGE, command });
|
|
5652
|
+
const base = parseCommandFlags(TraceFindingsSchema, flagsToArgs(rest, "conversation_id", targets[0].id), command, { positionalKey: "conversation_id" });
|
|
5653
|
+
const limit = base.limit ?? FINDINGS_DEFAULT_LIMIT;
|
|
5654
|
+
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
5655
|
+
const full = context.output.mode === "json";
|
|
5656
|
+
const batch = isBatchRead(positionals, flags);
|
|
5657
|
+
const read = async (id, budget) => {
|
|
5658
|
+
const raw = await callDataAPI(`/conversations/${encodeURIComponent(id)}/findings`);
|
|
5659
|
+
if (full)
|
|
5660
|
+
return { data: raw, options: {} };
|
|
5661
|
+
let item = compactFindings(raw, { limit, batch });
|
|
5662
|
+
for (let shown = limit - 1;budget && shown >= 0 && !budget.fits(item.data, item.options); shown -= 1) {
|
|
5663
|
+
item = compactFindings(raw, { limit: shown, batch });
|
|
5664
|
+
}
|
|
5665
|
+
return item;
|
|
5666
|
+
};
|
|
5667
|
+
if (!batch) {
|
|
5668
|
+
const item = await read(targets[0].id, agentMode ? { fits: (data, options) => agentEnvelopeFits(command, data, options), maxBytes: agentMaxOutputBytes() } : undefined);
|
|
5669
|
+
context.output.writeData(item.data, item.options);
|
|
5670
|
+
return 0;
|
|
5671
|
+
}
|
|
5672
|
+
const results = await readBatchTargets(targets, agentMode, (target, budget) => read(target.id, budget));
|
|
5673
|
+
return writeBatchResult("traces findings", context, targets, results, full ? [] : batchNotRunWarning(results), rest);
|
|
5674
|
+
}
|
|
5413
5675
|
async function runAuditBatch(command, positionals, flags, context) {
|
|
5414
5676
|
const { idsFrom, rest } = splitIdsFrom(flags);
|
|
5415
5677
|
if (rest.cursor !== undefined || Object.keys(rest).some((key) => key.replace(/_/g, "-") === "span-offset")) {
|
|
@@ -5681,6 +5943,8 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5681
5943
|
context.output.writeData(item.data, item.options);
|
|
5682
5944
|
break;
|
|
5683
5945
|
}
|
|
5946
|
+
case "trace-findings":
|
|
5947
|
+
return runTraceFindings(command, positionals, flags, context);
|
|
5684
5948
|
case "audit":
|
|
5685
5949
|
case "trace": {
|
|
5686
5950
|
if (isBatchRead(positionals, flags))
|
|
@@ -5705,7 +5969,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5705
5969
|
query2.set("limit", params.limit.toString());
|
|
5706
5970
|
if (params.offset !== undefined)
|
|
5707
5971
|
query2.set("offset", params.offset.toString());
|
|
5708
|
-
if (readsPerTrace("frustrations", params, ["user_id", "conversation_id", "include_window"])) {
|
|
5972
|
+
if (readsPerTrace("frustrations", params, ["user_id", "conversation_id", "conversation_ids", "ids_from", "include_window"])) {
|
|
5709
5973
|
query2.set("family", "frustration");
|
|
5710
5974
|
setTraceFilters(query2, params, TRACE_GRAIN_FLAGS.frustrations);
|
|
5711
5975
|
const data2 = await callDataAPI(`/emotions?${query2.toString()}`);
|
|
@@ -5718,6 +5982,9 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5718
5982
|
query2.set("user_id", params.user_id);
|
|
5719
5983
|
if (params.conversation_id)
|
|
5720
5984
|
query2.set("conversation_id", params.conversation_id);
|
|
5985
|
+
const frustrationIds = await conversationIdsFilter(params, context);
|
|
5986
|
+
if (frustrationIds)
|
|
5987
|
+
query2.set("conversation_ids", frustrationIds.join(","));
|
|
5721
5988
|
query2.set("family", "frustration");
|
|
5722
5989
|
const includeWindow = params.include_window === true;
|
|
5723
5990
|
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
@@ -6378,7 +6645,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6378
6645
|
query2.set("offset", params.offset.toString());
|
|
6379
6646
|
if (params.family)
|
|
6380
6647
|
query2.set("family", params.family);
|
|
6381
|
-
if (readsPerTrace("emotions", params, ["user_id", "conversation_id", "include_window"])) {
|
|
6648
|
+
if (readsPerTrace("emotions", params, ["user_id", "conversation_id", "conversation_ids", "ids_from", "include_window"])) {
|
|
6382
6649
|
setTraceFilters(query2, params, TRACE_GRAIN_FLAGS.emotions);
|
|
6383
6650
|
const data2 = await callDataAPI(`/emotions?${query2.toString()}`);
|
|
6384
6651
|
const warnings = processingDisabledWarning(data2, "emotion");
|
|
@@ -6390,6 +6657,9 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6390
6657
|
query2.set("user_id", params.user_id);
|
|
6391
6658
|
if (params.conversation_id)
|
|
6392
6659
|
query2.set("conversation_id", params.conversation_id);
|
|
6660
|
+
const emotionIds = await conversationIdsFilter(params, context);
|
|
6661
|
+
if (emotionIds)
|
|
6662
|
+
query2.set("conversation_ids", emotionIds.join(","));
|
|
6393
6663
|
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
6394
6664
|
if (agentMode && params.include_window !== true)
|
|
6395
6665
|
query2.set("include_context", "0");
|
|
@@ -6414,6 +6684,9 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6414
6684
|
query2.set("offset", params.offset.toString());
|
|
6415
6685
|
if (params.conversation_id)
|
|
6416
6686
|
query2.set("conversation_id", params.conversation_id);
|
|
6687
|
+
const lazinessIds = await conversationIdsFilter(params, context);
|
|
6688
|
+
if (lazinessIds)
|
|
6689
|
+
query2.set("conversation_ids", lazinessIds.join(","));
|
|
6417
6690
|
if (params.family)
|
|
6418
6691
|
query2.set("family", params.family);
|
|
6419
6692
|
if (params.conversation_id) {
|
|
@@ -6443,11 +6716,14 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
6443
6716
|
query2.set("limit", params.limit.toString());
|
|
6444
6717
|
if (params.offset !== undefined)
|
|
6445
6718
|
query2.set("offset", params.offset.toString());
|
|
6446
|
-
if (readsPerTrace("hallucinations", params, ["conversation_id", "kind"])) {
|
|
6719
|
+
if (readsPerTrace("hallucinations", params, ["conversation_id", "conversation_ids", "ids_from", "kind"])) {
|
|
6447
6720
|
setTraceFilters(query2, params, TRACE_GRAIN_FLAGS.hallucinations);
|
|
6448
6721
|
} else {
|
|
6449
6722
|
if (params.conversation_id)
|
|
6450
6723
|
query2.set("conversation_id", params.conversation_id);
|
|
6724
|
+
const hallucinationIds = await conversationIdsFilter(params, context);
|
|
6725
|
+
if (hallucinationIds)
|
|
6726
|
+
query2.set("conversation_ids", hallucinationIds.join(","));
|
|
6451
6727
|
if (params.kind)
|
|
6452
6728
|
query2.set("kind", params.kind);
|
|
6453
6729
|
}
|
|
@@ -6643,7 +6919,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6643
6919
|
resetApiRequestCountBeforeRun: true,
|
|
6644
6920
|
telemetry: "result-and-error",
|
|
6645
6921
|
handler: async (context) => {
|
|
6646
|
-
const { runInit } = await import("./index-
|
|
6922
|
+
const { runInit } = await import("./index-w7v472w4.js");
|
|
6647
6923
|
if (context.outputMode === "agent-stream") {
|
|
6648
6924
|
context.output.writeEvent({
|
|
6649
6925
|
event: "started",
|
|
@@ -6693,7 +6969,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6693
6969
|
resetApiRequestCountBeforeRun: true,
|
|
6694
6970
|
telemetry: "result-and-error",
|
|
6695
6971
|
handler: async (context) => {
|
|
6696
|
-
const { runProvision } = await import("./provision-
|
|
6972
|
+
const { runProvision } = await import("./provision-cya5rpxa.js");
|
|
6697
6973
|
return runProvision(context, {
|
|
6698
6974
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
6699
6975
|
});
|
|
@@ -7181,6 +7457,17 @@ var commandRegistry = createCommandRegistry([
|
|
|
7181
7457
|
],
|
|
7182
7458
|
...dataApiDefaults
|
|
7183
7459
|
}),
|
|
7460
|
+
legacyCommand({
|
|
7461
|
+
name: "trace-findings",
|
|
7462
|
+
description: "Everything flagged on a trace: every detector family with its message anchors, and the Problems it is evidence for (no time window)",
|
|
7463
|
+
examples: [
|
|
7464
|
+
"moda traces findings <conversation_id>",
|
|
7465
|
+
"moda traces findings <conversation_id> --limit=10 # more rows per family (counts always cover all)",
|
|
7466
|
+
"moda traces findings <id1> <id2> <id3> # batch: up to 25 ids, one envelope (or --ids-from=-|<file>)"
|
|
7467
|
+
],
|
|
7468
|
+
hidden: true,
|
|
7469
|
+
...dataApiDefaults
|
|
7470
|
+
}),
|
|
7184
7471
|
legacyCommand({
|
|
7185
7472
|
name: "frustrations",
|
|
7186
7473
|
description: "User frustration detections: the frustration family of `emotions` (same data as the dashboard), legacy field names",
|
|
@@ -3,15 +3,15 @@ import {
|
|
|
3
3
|
promptsDiscoveredCheck,
|
|
4
4
|
runDoctorCommand,
|
|
5
5
|
runStatusCommand
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
8
|
-
import"./cli-
|
|
6
|
+
} from "./cli-a8nxbtpk.js";
|
|
7
|
+
import"./cli-pmzh2qjy.js";
|
|
8
|
+
import"./cli-4tg0hkbz.js";
|
|
9
9
|
import"./cli-mm48br00.js";
|
|
10
10
|
import"./cli-xq45etg1.js";
|
|
11
|
-
import"./cli-
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
11
|
+
import"./cli-xddtv3yn.js";
|
|
12
|
+
import"./cli-f1jfrqgf.js";
|
|
13
|
+
import"./cli-0xc5htv7.js";
|
|
14
|
+
import"./cli-t0pb7qbs.js";
|
|
15
15
|
import"./cli-k4tqwah4.js";
|
|
16
16
|
import"./cli-9kfxkxmk.js";
|
|
17
17
|
import"./cli-ns5fcnkz.js";
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
DEFAULT_POLL_INTERVAL_MS,
|
|
3
3
|
DEFAULT_WAIT_TIMEOUT_MS,
|
|
4
4
|
fetchLatestRun
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-daqkdnm1.js";
|
|
6
6
|
import {
|
|
7
7
|
assertFlags
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-f1jfrqgf.js";
|
|
9
9
|
import {
|
|
10
10
|
callControlAPI
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-0xc5htv7.js";
|
|
12
12
|
import {
|
|
13
13
|
EXIT_DEGRADED,
|
|
14
14
|
EXIT_ERROR,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
resolveApiTenantId,
|
|
18
18
|
shellArg,
|
|
19
19
|
validateConfig
|
|
20
|
-
} from "./cli-
|
|
20
|
+
} from "./cli-t0pb7qbs.js";
|
|
21
21
|
import {
|
|
22
22
|
CliInputError
|
|
23
23
|
} from "./cli-k4tqwah4.js";
|
|
@@ -40,17 +40,17 @@ import {
|
|
|
40
40
|
writeHarnessAnalyzeResult,
|
|
41
41
|
writeHarnessArtifacts,
|
|
42
42
|
writeHumanProgress
|
|
43
|
-
} from "./cli-
|
|
43
|
+
} from "./cli-azage7s0.js";
|
|
44
44
|
import"./cli-xq45etg1.js";
|
|
45
45
|
import"./cli-97fnztpy.js";
|
|
46
46
|
import {
|
|
47
47
|
HARNESS_ANALYZE_CONCERNS
|
|
48
48
|
} from "./cli-cesds766.js";
|
|
49
49
|
import"./cli-qpq84eee.js";
|
|
50
|
-
import"./cli-
|
|
51
|
-
import"./cli-
|
|
52
|
-
import"./cli-
|
|
53
|
-
import"./cli-
|
|
50
|
+
import"./cli-xddtv3yn.js";
|
|
51
|
+
import"./cli-f1jfrqgf.js";
|
|
52
|
+
import"./cli-0xc5htv7.js";
|
|
53
|
+
import"./cli-t0pb7qbs.js";
|
|
54
54
|
import"./cli-k4tqwah4.js";
|
|
55
55
|
import"./cli-9kfxkxmk.js";
|
|
56
56
|
import"./cli-ns5fcnkz.js";
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildSourceSnapshot
|
|
3
|
-
} from "./cli-
|
|
3
|
+
} from "./cli-azage7s0.js";
|
|
4
4
|
import"./cli-xq45etg1.js";
|
|
5
5
|
import"./cli-97fnztpy.js";
|
|
6
6
|
import"./cli-cesds766.js";
|
|
7
7
|
import"./cli-qpq84eee.js";
|
|
8
|
-
import"./cli-
|
|
9
|
-
import"./cli-
|
|
10
|
-
import"./cli-
|
|
8
|
+
import"./cli-xddtv3yn.js";
|
|
9
|
+
import"./cli-f1jfrqgf.js";
|
|
10
|
+
import"./cli-0xc5htv7.js";
|
|
11
11
|
import {
|
|
12
12
|
recordApiRequest
|
|
13
|
-
} from "./cli-
|
|
13
|
+
} from "./cli-t0pb7qbs.js";
|
|
14
14
|
import"./cli-k4tqwah4.js";
|
|
15
15
|
import"./cli-9kfxkxmk.js";
|
|
16
16
|
import"./cli-ns5fcnkz.js";
|