@moda-ai/cli 1.55.36 → 1.55.38
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-g07tg64w.js → agent-9r58v0bc.js} +8 -8
- package/dist/{cli-e23g9ywa.js → cli-3n040fp2.js} +1 -1
- package/dist/{cli-k007ztbs.js → cli-93926afn.js} +4 -4
- package/dist/{cli-97jew729.js → cli-9g5kzsg6.js} +1 -1
- package/dist/{cli-dr6x0zv7.js → cli-b7nyw498.js} +1 -1
- package/dist/{cli-6j8h2ave.js → cli-dmnayt2r.js} +8 -8
- package/dist/{cli-fwpqghgc.js → cli-n311b8g0.js} +112 -2
- package/dist/{cli-602yx84w.js → cli-nh23q6ay.js} +5 -5
- package/dist/{cli-99p2jh28.js → cli-rcjhfts4.js} +24 -10
- package/dist/{cli-9bgnvth2.js → cli-sk1p71wr.js} +1 -1
- package/dist/{cli-x9cwat4a.js → cli-skvvwp2q.js} +5 -5
- package/dist/{cli-9bgk5jeh.js → cli-tdcx8yz9.js} +3 -3
- package/dist/{cli-n2hng3gv.js → cli-xheg54qc.js} +80 -7
- package/dist/{cli-yz8xcpyk.js → cli-xk630wjq.js} +1 -1
- package/dist/{cli-5fstvkva.js → cli-xtyszvq1.js} +5 -5
- package/dist/cli.js +319 -39
- package/dist/{doctor-tvre7zvk.js → doctor-xq5bjvpq.js} +7 -7
- package/dist/{fix-w5z02wt4.js → fix-kvszavm1.js} +4 -4
- package/dist/{harness-github-actions-6gdrpn4m.js → harness-github-actions-drbkcb8d.js} +5 -5
- package/dist/{harness-6vwehf47.js → harness-qatnwxrz.js} +5 -5
- package/dist/{index-75vcntpe.js → index-y5jnz2t2.js} +11 -11
- package/dist/{production-intelligence-7wb1djy2.js → production-intelligence-j55vaw6t.js} +61 -4
- package/dist/{profile-commands-h8evz9x0.js → profile-commands-skdxe17v.js} +3 -3
- package/dist/{prompt-attribution-t0eq8gn8.js → prompt-attribution-zq38actx.js} +5 -5
- package/dist/prompt-source-mcp.js +5 -5
- package/dist/{prompts-ab-t7xptf0c.js → prompts-ab-yd2dawe3.js} +7 -7
- package/dist/{prompts-b8qx3mrv.js → prompts-cwqn8a57.js} +5 -5
- package/dist/{prompts-propose-8feadk2t.js → prompts-propose-11dj9ked.js} +7 -7
- package/dist/{provision-y5bdbh4y.js → provision-ghca9d54.js} +5 -5
- package/dist/{registry-ctnn8e26.js → registry-76sngjw6.js} +3 -3
- package/dist/{skills-96z55tj4.js → skills-btn9r48v.js} +5 -5
- package/dist/{sync-drz7req6.js → sync-ye7nxeen.js} +7 -7
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +5 -2
- package/skills/moda-cli/references/commands.md +3 -0
- package/skills/moda-cli/references/dashboard-parity.md +4 -0
- package/skills/moda-cli/references/detections.md +93 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isAuthSessionValid,
|
|
3
3
|
loadAuthSession
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-sk1p71wr.js";
|
|
5
5
|
import {
|
|
6
6
|
inspectPromptManifest
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-dmnayt2r.js";
|
|
8
8
|
import {
|
|
9
9
|
readHarnessSyncState,
|
|
10
10
|
renderDoctorHuman,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "./cli-xq45etg1.js";
|
|
13
13
|
import {
|
|
14
14
|
callDataAPI
|
|
15
|
-
} from "./cli-
|
|
15
|
+
} from "./cli-3n040fp2.js";
|
|
16
16
|
import {
|
|
17
17
|
ensureSecretFilePermissions,
|
|
18
18
|
getActiveProfile,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
resolveSecretReference,
|
|
27
27
|
resolveTenantId,
|
|
28
28
|
secretFilePathFromRef
|
|
29
|
-
} from "./cli-
|
|
29
|
+
} from "./cli-rcjhfts4.js";
|
|
30
30
|
import {
|
|
31
31
|
__require
|
|
32
32
|
} from "./cli-0v6na3yp.js";
|
|
@@ -376,7 +376,7 @@ async function harnessCurrentCheck(cwd, manifestPath, manifestExists, tenantId)
|
|
|
376
376
|
};
|
|
377
377
|
}
|
|
378
378
|
try {
|
|
379
|
-
const { scanHarness } = await import("./harness-
|
|
379
|
+
const { scanHarness } = await import("./harness-qatnwxrz.js");
|
|
380
380
|
const current = scanHarness({
|
|
381
381
|
rootDir: cwd,
|
|
382
382
|
scannerVersion: "doctor",
|
package/dist/cli.js
CHANGED
|
@@ -13,11 +13,14 @@ import {
|
|
|
13
13
|
frustrationsFromEmotions,
|
|
14
14
|
mapWithConcurrency,
|
|
15
15
|
parseBatchTarget,
|
|
16
|
+
shapeToolCatalogDetail,
|
|
17
|
+
toolCatalogGetCommand,
|
|
18
|
+
toolFailureExamplesCommand,
|
|
16
19
|
trimToolFailureConversations,
|
|
17
20
|
withFrustrationAnchors,
|
|
18
21
|
withToolFailureAnchors,
|
|
19
22
|
withoutDetectionWindows
|
|
20
|
-
} from "./cli-
|
|
23
|
+
} from "./cli-n311b8g0.js";
|
|
21
24
|
import {
|
|
22
25
|
createCommandContext,
|
|
23
26
|
envOptOutSet,
|
|
@@ -25,7 +28,7 @@ import {
|
|
|
25
28
|
optOutFlagSet,
|
|
26
29
|
parseBooleanFlagValue,
|
|
27
30
|
withoutFlag
|
|
28
|
-
} from "./cli-
|
|
31
|
+
} from "./cli-b7nyw498.js";
|
|
29
32
|
import {
|
|
30
33
|
AuditSchema,
|
|
31
34
|
COMMAND_FLAG_SPECS,
|
|
@@ -44,6 +47,7 @@ import {
|
|
|
44
47
|
SIGNALS_MANAGEMENT_SUBCOMMANDS,
|
|
45
48
|
SignalLabelSchema,
|
|
46
49
|
StepScoresSchema,
|
|
50
|
+
TRACE_GRAIN_FLAGS,
|
|
47
51
|
UUID_RE,
|
|
48
52
|
assertFlags,
|
|
49
53
|
assertPositionals,
|
|
@@ -67,12 +71,12 @@ import {
|
|
|
67
71
|
unknownSignalsSubcommandError,
|
|
68
72
|
usageLine,
|
|
69
73
|
writeDryRun
|
|
70
|
-
} from "./cli-
|
|
74
|
+
} from "./cli-xheg54qc.js";
|
|
71
75
|
import {
|
|
72
76
|
ApiError,
|
|
73
77
|
callControlAPI,
|
|
74
78
|
callDataAPI
|
|
75
|
-
} from "./cli-
|
|
79
|
+
} from "./cli-3n040fp2.js";
|
|
76
80
|
import {
|
|
77
81
|
AGENT_ERROR_CODES,
|
|
78
82
|
EXIT_AUTH_REQUIRED,
|
|
@@ -109,7 +113,7 @@ import {
|
|
|
109
113
|
shellArg,
|
|
110
114
|
validateConfig,
|
|
111
115
|
wasOutputCancelled
|
|
112
|
-
} from "./cli-
|
|
116
|
+
} from "./cli-rcjhfts4.js";
|
|
113
117
|
import {
|
|
114
118
|
CliAccessError,
|
|
115
119
|
CliAuthError,
|
|
@@ -1242,6 +1246,24 @@ var CANONICAL_LEAVES = [
|
|
|
1242
1246
|
summary: "Tool failure leaderboard, or one tool's failure examples",
|
|
1243
1247
|
examples: ["moda detections tools --days-back=14", "moda detections tools <tool_name> --limit=3"]
|
|
1244
1248
|
},
|
|
1249
|
+
{
|
|
1250
|
+
noun: "tools",
|
|
1251
|
+
verb: "list",
|
|
1252
|
+
path: "tools list",
|
|
1253
|
+
args: "",
|
|
1254
|
+
handler: "tool-catalog",
|
|
1255
|
+
summary: "Every tool called in the window: calls, failed calls, success rate, effect direction, last seen",
|
|
1256
|
+
examples: ["moda tools list --days-back=7", "moda tools list --sort=failure_rate --limit=10", "moda tools list --search=calendar --direction=write"]
|
|
1257
|
+
},
|
|
1258
|
+
{
|
|
1259
|
+
noun: "tools",
|
|
1260
|
+
verb: "get",
|
|
1261
|
+
path: "tools get",
|
|
1262
|
+
args: "<tool_name>",
|
|
1263
|
+
handler: "tool-catalog-detail",
|
|
1264
|
+
summary: "One tool: calls, recorded schema and payload fields, usage over time, top failure categories",
|
|
1265
|
+
examples: ["moda tools get <tool_name>", "moda tools get <tool_name> --days-back=30 --full"]
|
|
1266
|
+
},
|
|
1245
1267
|
{
|
|
1246
1268
|
noun: "review",
|
|
1247
1269
|
verb: "",
|
|
@@ -1275,11 +1297,12 @@ var CANONICAL_LEAVES = [
|
|
|
1275
1297
|
examples: ["moda skills push --dry-run", "moda skills push"]
|
|
1276
1298
|
}
|
|
1277
1299
|
];
|
|
1278
|
-
var CANONICAL_NOUNS = ["traces", "problems", "detections", "review", "reviews", "skills"];
|
|
1300
|
+
var CANONICAL_NOUNS = ["traces", "problems", "detections", "tools", "review", "reviews", "skills"];
|
|
1279
1301
|
var NOUN_SUMMARIES = {
|
|
1280
1302
|
traces: "Traces (agent runs): list, search, read, world state, raw spans",
|
|
1281
1303
|
problems: "Problems ranked by root cause, their evidence, impact and lifecycle",
|
|
1282
1304
|
detections: "Detections of every family, and the tool failure leaderboard",
|
|
1305
|
+
tools: "The Tool catalog: every tool with calls and success rate, and one tool's schema, usage and failure categories",
|
|
1283
1306
|
review: "Mark a detection a false positive, correct, or clear the mark",
|
|
1284
1307
|
reviews: "List false-positive marks and detection reviews",
|
|
1285
1308
|
skills: "Generate, pull, push, and install agent skills"
|
|
@@ -2959,46 +2982,46 @@ function leafManifestFields(leaf, commands) {
|
|
|
2959
2982
|
import { fileURLToPath } from "url";
|
|
2960
2983
|
import { realpathSync } from "fs";
|
|
2961
2984
|
async function runPromptsCommand(...args) {
|
|
2962
|
-
return (await import("./prompts-
|
|
2985
|
+
return (await import("./prompts-cwqn8a57.js")).runPromptsCommand(...args);
|
|
2963
2986
|
}
|
|
2964
2987
|
async function runSkillsCommand(...args) {
|
|
2965
|
-
return (await import("./skills-
|
|
2988
|
+
return (await import("./skills-btn9r48v.js")).runSkillsCommand(...args);
|
|
2966
2989
|
}
|
|
2967
2990
|
async function runFixCommand(...args) {
|
|
2968
|
-
return (await import("./fix-
|
|
2991
|
+
return (await import("./fix-kvszavm1.js")).runFixCommand(...args);
|
|
2969
2992
|
}
|
|
2970
2993
|
async function runFixesCommand(...args) {
|
|
2971
|
-
return (await import("./fix-
|
|
2994
|
+
return (await import("./fix-kvszavm1.js")).runFixesCommand(...args);
|
|
2972
2995
|
}
|
|
2973
2996
|
async function runHarnessCommand(...args) {
|
|
2974
|
-
return (await import("./harness-
|
|
2997
|
+
return (await import("./harness-qatnwxrz.js")).runHarnessCommand(...args);
|
|
2975
2998
|
}
|
|
2976
2999
|
async function runSyncCommand(...args) {
|
|
2977
|
-
return (await import("./sync-
|
|
3000
|
+
return (await import("./sync-ye7nxeen.js")).runSyncCommand(...args);
|
|
2978
3001
|
}
|
|
2979
3002
|
async function runRegistryCommand(...args) {
|
|
2980
|
-
return (await import("./registry-
|
|
3003
|
+
return (await import("./registry-76sngjw6.js")).runRegistryCommand(...args);
|
|
2981
3004
|
}
|
|
2982
3005
|
async function runDoctorCommand(...args) {
|
|
2983
|
-
return (await import("./doctor-
|
|
3006
|
+
return (await import("./doctor-xq5bjvpq.js")).runDoctorCommand(...args);
|
|
2984
3007
|
}
|
|
2985
3008
|
async function runStatusCommand(...args) {
|
|
2986
|
-
return (await import("./doctor-
|
|
3009
|
+
return (await import("./doctor-xq5bjvpq.js")).runStatusCommand(...args);
|
|
2987
3010
|
}
|
|
2988
3011
|
async function runAuthCommand(...args) {
|
|
2989
|
-
return (await import("./profile-commands-
|
|
3012
|
+
return (await import("./profile-commands-skdxe17v.js")).runAuthCommand(...args);
|
|
2990
3013
|
}
|
|
2991
3014
|
async function runConfigCommand(...args) {
|
|
2992
|
-
return (await import("./profile-commands-
|
|
3015
|
+
return (await import("./profile-commands-skdxe17v.js")).runConfigCommand(...args);
|
|
2993
3016
|
}
|
|
2994
3017
|
async function runProfilesCommand(...args) {
|
|
2995
|
-
return (await import("./profile-commands-
|
|
3018
|
+
return (await import("./profile-commands-skdxe17v.js")).runProfilesCommand(...args);
|
|
2996
3019
|
}
|
|
2997
3020
|
async function runAgentCommand(...args) {
|
|
2998
|
-
return (await import("./agent-
|
|
3021
|
+
return (await import("./agent-9r58v0bc.js")).runAgentCommand(...args);
|
|
2999
3022
|
}
|
|
3000
3023
|
async function runProductionCommand(...args) {
|
|
3001
|
-
return (await import("./production-intelligence-
|
|
3024
|
+
return (await import("./production-intelligence-j55vaw6t.js")).runProductionCommand(...args);
|
|
3002
3025
|
}
|
|
3003
3026
|
function parseArgs(argv) {
|
|
3004
3027
|
const args = argv.slice(2);
|
|
@@ -3285,6 +3308,7 @@ Start here (goal -> command):
|
|
|
3285
3308
|
read one trace moda traces get <conversation_id> (whole trace: --all)
|
|
3286
3309
|
what is broken moda overview, then moda problems list
|
|
3287
3310
|
tool errors moda detections tools, then moda detections tools <tool_name>
|
|
3311
|
+
tool calls, success rate, schema moda tools list, then moda tools get <tool_name>
|
|
3288
3312
|
user emotion and frustration moda detections list --family=emotion (or --family=frustration)
|
|
3289
3313
|
raw spans for one trace moda traces spans <conversation_id|trace_id>
|
|
3290
3314
|
a detection is wrong moda review <kind> <target> --reason=TEXT
|
|
@@ -3300,7 +3324,7 @@ Production data:
|
|
|
3300
3324
|
users / user <user_id> End users with health and activity (the dashboard Users page)
|
|
3301
3325
|
tail Live-tail new traces/detections as NDJSON (one line per item)
|
|
3302
3326
|
|
|
3303
|
-
Traces, Problems, detections and review (moda <noun> --help lists the verbs):
|
|
3327
|
+
Traces, Problems, detections, tools and review (moda <noun> --help lists the verbs):
|
|
3304
3328
|
${canonicalTreeHelpLines().join(`
|
|
3305
3329
|
`)}
|
|
3306
3330
|
|
|
@@ -3650,7 +3674,9 @@ async function attachWindows(rows, windowSize, budgetBytes) {
|
|
|
3650
3674
|
}
|
|
3651
3675
|
var TOOL_FAILURE_DETAIL_DEFAULT_LIMIT = 5;
|
|
3652
3676
|
var TOOL_FAILURE_AGENT_SUBTYPES = 20;
|
|
3653
|
-
|
|
3677
|
+
var TOOL_FAILURE_CATALOG_LINKS = 3;
|
|
3678
|
+
var TOOL_CATALOG_DEFAULT_LIMIT = 25;
|
|
3679
|
+
async function printWithOptionalWindows(enriched, listKey, includeWindow, windowSize, output, warnings, finalize, nextCommands = [], summary) {
|
|
3654
3680
|
const allWarnings = [...warnings ?? []];
|
|
3655
3681
|
let data = enriched;
|
|
3656
3682
|
if (includeWindow) {
|
|
@@ -3660,7 +3686,12 @@ async function printWithOptionalWindows(enriched, listKey, includeWindow, window
|
|
|
3660
3686
|
}
|
|
3661
3687
|
if (finalize)
|
|
3662
3688
|
data = finalize(data, allWarnings);
|
|
3663
|
-
|
|
3689
|
+
const options = {
|
|
3690
|
+
...summary ? { summary } : {},
|
|
3691
|
+
...allWarnings.length > 0 ? { warnings: allWarnings } : {},
|
|
3692
|
+
...nextCommands.length > 0 ? { nextCommands } : {}
|
|
3693
|
+
};
|
|
3694
|
+
output.writeData(data, Object.keys(options).length > 0 ? options : undefined);
|
|
3664
3695
|
}
|
|
3665
3696
|
function withoutRepeatedFrustrationWindow(data) {
|
|
3666
3697
|
if (!Array.isArray(data.frustrations))
|
|
@@ -4506,6 +4537,91 @@ function processingDisabledWarning(data, family) {
|
|
|
4506
4537
|
`${family === "emotion" ? "Emotion" : "Frustration"} analysis is disabled for this tenant (${setting} = false), ` + "so zero results do NOT mean users are not frustrated. Enable it in Settings → Account → Signal processing; " + "only traces ingested after enabling are analyzed."
|
|
4507
4538
|
];
|
|
4508
4539
|
}
|
|
4540
|
+
function readsPerTrace(command, params, perRowScopes) {
|
|
4541
|
+
const filters = TRACE_GRAIN_FLAGS[command].filter((key) => params[key] !== undefined);
|
|
4542
|
+
const grain = params.group_by;
|
|
4543
|
+
if (grain !== undefined && grain !== "trace" && filters.length > 0) {
|
|
4544
|
+
rejectInapplicableFlags(command, params, filters, `with --group-by=${grain}; they filter the per-trace list (--group-by=trace)`);
|
|
4545
|
+
}
|
|
4546
|
+
const perTrace = grain === "trace" || filters.length > 0;
|
|
4547
|
+
if (perTrace) {
|
|
4548
|
+
rejectInapplicableFlags(command, params, perRowScopes, "to the per-trace list (--group-by=trace, or a filter that implies it); drop --group-by and the trace filters to use them");
|
|
4549
|
+
}
|
|
4550
|
+
return perTrace;
|
|
4551
|
+
}
|
|
4552
|
+
function setTraceFilters(query2, params, keys) {
|
|
4553
|
+
query2.set("group_by", "trace");
|
|
4554
|
+
for (const key of keys) {
|
|
4555
|
+
const value = params[key];
|
|
4556
|
+
if (value === undefined)
|
|
4557
|
+
continue;
|
|
4558
|
+
if (key === "signal")
|
|
4559
|
+
query2.set("signals", String(value).split(",").map((part) => part.trim()).join(","));
|
|
4560
|
+
else
|
|
4561
|
+
query2.set(key, String(value));
|
|
4562
|
+
}
|
|
4563
|
+
}
|
|
4564
|
+
function countingSummary(data) {
|
|
4565
|
+
const record = asRecord(data);
|
|
4566
|
+
const counting = asString(record?.counting);
|
|
4567
|
+
const total = asNumber(asRecord(record?.pagination)?.total);
|
|
4568
|
+
if (!counting || total === null)
|
|
4569
|
+
return;
|
|
4570
|
+
switch (counting) {
|
|
4571
|
+
case "per_trace":
|
|
4572
|
+
return `${total} trace(s) match. Counting: per trace, as the dashboard counts (pagination.total = traces).`;
|
|
4573
|
+
case "per_detection":
|
|
4574
|
+
return `${total} detection(s) match. Counting: per detection (one row per trace and family), not per trace; add --group-by=trace for the dashboard's per-trace count.`;
|
|
4575
|
+
case "per_message":
|
|
4576
|
+
return `${total} message detection(s) match. Counting: per scored message, not per trace; add --group-by=trace for the dashboard's per-trace count.`;
|
|
4577
|
+
default:
|
|
4578
|
+
return;
|
|
4579
|
+
}
|
|
4580
|
+
}
|
|
4581
|
+
function traceStateWarnings(data) {
|
|
4582
|
+
const record = asRecord(data);
|
|
4583
|
+
if (asString(record?.trace_state) === "unavailable") {
|
|
4584
|
+
return ["Trace processing state could not be read, so processing_status is null on every row; do not read missing detections as clean."];
|
|
4585
|
+
}
|
|
4586
|
+
const rows = Array.isArray(record?.conversations) ? record.conversations.map(asRecord) : [];
|
|
4587
|
+
const pending = rows.filter((row) => asString(row?.processing_status) === "pending").length;
|
|
4588
|
+
const errored = rows.filter((row) => asString(row?.error_message)).length;
|
|
4589
|
+
const warnings = [];
|
|
4590
|
+
if (pending > 0) {
|
|
4591
|
+
warnings.push(`${pending} of ${rows.length} trace(s) on this page are not fully processed yet (processing_status=pending), so their detections may be incomplete; missing detections do not mean they are clean.`);
|
|
4592
|
+
}
|
|
4593
|
+
if (errored > 0) {
|
|
4594
|
+
warnings.push(`${errored} trace(s) on this page have a processing error (error_message); their detections may be missing.`);
|
|
4595
|
+
}
|
|
4596
|
+
return warnings;
|
|
4597
|
+
}
|
|
4598
|
+
function singleTraceStateWarnings(value) {
|
|
4599
|
+
const traceState = asRecord(value);
|
|
4600
|
+
const warnings = [];
|
|
4601
|
+
if (asString(traceState?.processing_status) === "pending") {
|
|
4602
|
+
warnings.push("This trace is not fully processed yet (trace_state.processing_status=pending), so its detections may be incomplete; missing detections do not mean it is clean.");
|
|
4603
|
+
}
|
|
4604
|
+
if (asString(traceState?.error_message)) {
|
|
4605
|
+
warnings.push("This trace has a processing error (trace_state.error_message); its detections may be missing.");
|
|
4606
|
+
}
|
|
4607
|
+
return warnings;
|
|
4608
|
+
}
|
|
4609
|
+
function customSignalProcessingWarning(data, rows) {
|
|
4610
|
+
const record = asRecord(data);
|
|
4611
|
+
const processing = asRecord(record?.processing);
|
|
4612
|
+
const list = record?.[rows];
|
|
4613
|
+
if (!processing || !Array.isArray(list) || list.length > 0)
|
|
4614
|
+
return [];
|
|
4615
|
+
if (processing.enabled === false) {
|
|
4616
|
+
return [
|
|
4617
|
+
"Custom-signal judging is disabled for this tenant (signals.custom_signals = false), so no hits does NOT mean the traces are clean. " + "Enable it in Settings → Account → Signal processing; only conversations judged after enabling get hits."
|
|
4618
|
+
];
|
|
4619
|
+
}
|
|
4620
|
+
if (processing.enabled === null) {
|
|
4621
|
+
return ["Could not confirm whether custom-signal judging is enabled for this tenant, so treat no hits with caution."];
|
|
4622
|
+
}
|
|
4623
|
+
return [];
|
|
4624
|
+
}
|
|
4509
4625
|
var CONTEXT_USAGE = "Usage: moda traces get <conversation_id> [--msg-index=N (alias --message-index)] [--window=0-5 | --metadata-only]";
|
|
4510
4626
|
var CONTEXT_ALL_USAGE = "Usage: moda traces get <conversation_id> --all [--from=N] [--max-messages=N]";
|
|
4511
4627
|
var CONTEXT_BATCH_USAGE = `Usage: moda traces get <id>[@msg_index] <id>[@msg_index] ... | --ids-from=-|<file> [--window=0-5 | --metadata-only | --all [--from=N] [--max-messages=N]] (max ${BATCH_MAX_TARGETS} targets)`;
|
|
@@ -4611,6 +4727,7 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4611
4727
|
let total = 0;
|
|
4612
4728
|
let summary = null;
|
|
4613
4729
|
let ordering;
|
|
4730
|
+
let traceState;
|
|
4614
4731
|
let nextFrom = null;
|
|
4615
4732
|
let cursor = start;
|
|
4616
4733
|
let readBytes = 0;
|
|
@@ -4627,6 +4744,7 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4627
4744
|
total = asNumber(page.total_messages) ?? 0;
|
|
4628
4745
|
summary = stripLoneSurrogates(page.summary ?? null);
|
|
4629
4746
|
ordering = stripLoneSurrogates(asRecord(page.ordering) ?? undefined);
|
|
4747
|
+
traceState = page.trace_state;
|
|
4630
4748
|
}
|
|
4631
4749
|
const batch = stripLoneSurrogates(pageMessages(page));
|
|
4632
4750
|
messages.push(...batch);
|
|
@@ -4678,6 +4796,7 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
4678
4796
|
next_from: next,
|
|
4679
4797
|
summary,
|
|
4680
4798
|
...ordering ? { ordering } : {},
|
|
4799
|
+
...traceState !== undefined ? { trace_state: traceState } : {},
|
|
4681
4800
|
messages: returned
|
|
4682
4801
|
},
|
|
4683
4802
|
warnings: out,
|
|
@@ -4699,7 +4818,7 @@ async function readContextItem(params, inputWarnings, budget) {
|
|
|
4699
4818
|
fits: fits ? (page) => fits(page.data, { warnings: page.warnings, nextCommands: page.nextCommands }) : undefined,
|
|
4700
4819
|
maxBytes: budget?.maxBytes
|
|
4701
4820
|
});
|
|
4702
|
-
const fullWarnings = [...inputWarnings, ...full.warnings];
|
|
4821
|
+
const fullWarnings = [...inputWarnings, ...singleTraceStateWarnings(asRecord(full.data)?.trace_state), ...full.warnings];
|
|
4703
4822
|
return {
|
|
4704
4823
|
data: full.data,
|
|
4705
4824
|
options: {
|
|
@@ -4721,7 +4840,7 @@ async function readContextItem(params, inputWarnings, budget) {
|
|
|
4721
4840
|
const data = params.metadata_only === true ? await readContextMetadataOnly(contextPath, query2) : await callDataAPI(`${contextPath}${queryString}`);
|
|
4722
4841
|
const ctxRecord = asRecord(data) ?? {};
|
|
4723
4842
|
throwIfNotFound("trace", params.conversation_id, asNumber(ctxRecord.total_messages) === 0);
|
|
4724
|
-
const warnings = [...inputWarnings];
|
|
4843
|
+
const warnings = [...inputWarnings, ...singleTraceStateWarnings(ctxRecord.trace_state)];
|
|
4725
4844
|
const nextCommands = [];
|
|
4726
4845
|
if (params.window !== undefined && params.window > CONTEXT_MAX_WINDOW) {
|
|
4727
4846
|
const center = asNumber(asRecord(ctxRecord.context)?.center_index) ?? params.msg_index ?? 0;
|
|
@@ -5160,6 +5279,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5160
5279
|
searchWarnings.push("--sort=slowest: no trace in this page has a known duration (synthetic timestamps), so the order is not by duration. Use --sort=longest (message count) instead.");
|
|
5161
5280
|
}
|
|
5162
5281
|
}
|
|
5282
|
+
searchWarnings.push(...traceStateWarnings(data));
|
|
5163
5283
|
const writeOptions = searchWarnings.length > 0 ? { warnings: searchWarnings } : undefined;
|
|
5164
5284
|
if (params.include_world_state === true) {
|
|
5165
5285
|
const enriched = asRecord(data) ?? {};
|
|
@@ -5327,6 +5447,15 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5327
5447
|
query2.set("limit", params.limit.toString());
|
|
5328
5448
|
if (params.offset !== undefined)
|
|
5329
5449
|
query2.set("offset", params.offset.toString());
|
|
5450
|
+
if (readsPerTrace("frustrations", params, ["user_id", "conversation_id", "include_window"])) {
|
|
5451
|
+
query2.set("family", "frustration");
|
|
5452
|
+
setTraceFilters(query2, params, TRACE_GRAIN_FLAGS.frustrations);
|
|
5453
|
+
const data2 = await callDataAPI(`/emotions?${query2.toString()}`);
|
|
5454
|
+
const warnings = processingDisabledWarning(data2, "frustration");
|
|
5455
|
+
const summary = countingSummary(data2);
|
|
5456
|
+
context.output.writeData(data2, { ...summary ? { summary } : {}, ...warnings.length > 0 ? { warnings } : {} });
|
|
5457
|
+
break;
|
|
5458
|
+
}
|
|
5330
5459
|
if (params.user_id)
|
|
5331
5460
|
query2.set("user_id", params.user_id);
|
|
5332
5461
|
if (params.conversation_id)
|
|
@@ -5338,7 +5467,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5338
5467
|
query2.set("include_context", "0");
|
|
5339
5468
|
const data = frustrationsFromEmotions(await callDataAPI(`/emotions?${query2.toString()}`));
|
|
5340
5469
|
const anchored = withFrustrationAnchors(data);
|
|
5341
|
-
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);
|
|
5470
|
+
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));
|
|
5342
5471
|
break;
|
|
5343
5472
|
}
|
|
5344
5473
|
case "tool-failures": {
|
|
@@ -5346,7 +5475,98 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5346
5475
|
const params = parseSpecFlags("tool-failures", args, command);
|
|
5347
5476
|
const queryString = params.days_back ? `?days_back=${params.days_back}` : "";
|
|
5348
5477
|
const data = await callDataAPI(`/tool-failures${queryString}`);
|
|
5349
|
-
|
|
5478
|
+
const daysBack = params.days_back ?? 7;
|
|
5479
|
+
const failing = (Array.isArray(asRecord(data)?.tools) ? asRecord(data).tools : []).map((row) => asString(asRecord(row)?.tool_name)).filter((name) => Boolean(name)).slice(0, TOOL_FAILURE_CATALOG_LINKS);
|
|
5480
|
+
const nextCommands = failing.flatMap((name, index) => [
|
|
5481
|
+
...index === 0 ? [{ command: toolFailureExamplesCommand(name, daysBack), purpose: `Read failure examples of ${name}, the tool with the most failures.`, mutability: "read", requires_approval: false }] : [],
|
|
5482
|
+
{ command: toolCatalogGetCommand(name, daysBack), purpose: `Calls, recorded schema, usage over time and failure categories of ${name}.`, mutability: "read", requires_approval: false }
|
|
5483
|
+
]);
|
|
5484
|
+
context.output.writeData(data, nextCommands.length > 0 ? { nextCommands } : undefined);
|
|
5485
|
+
break;
|
|
5486
|
+
}
|
|
5487
|
+
case "tool-catalog": {
|
|
5488
|
+
const params = parseSpecFlags("tool-catalog", flagsToArgs(flags), command);
|
|
5489
|
+
const daysBack = params.days_back ?? 7;
|
|
5490
|
+
const limit = params.limit ?? TOOL_CATALOG_DEFAULT_LIMIT;
|
|
5491
|
+
const offset = params.offset ?? 0;
|
|
5492
|
+
const sort = params.sort ?? "calls";
|
|
5493
|
+
const query2 = new URLSearchParams({ days_back: String(daysBack), sort, limit: String(limit), offset: String(offset) });
|
|
5494
|
+
if (params.search)
|
|
5495
|
+
query2.set("search", params.search);
|
|
5496
|
+
if (params.direction)
|
|
5497
|
+
query2.set("direction", params.direction);
|
|
5498
|
+
const data = asRecord(await callDataAPI(`/tools?${query2.toString()}`)) ?? {};
|
|
5499
|
+
const pagination = asRecord(data.pagination);
|
|
5500
|
+
const tools = Array.isArray(data.tools) ? data.tools.map((row) => asRecord(row)).filter((row) => row !== null) : [];
|
|
5501
|
+
const listFlags = [
|
|
5502
|
+
`--days-back=${daysBack}`,
|
|
5503
|
+
...sort !== "calls" ? [`--sort=${sort}`] : [],
|
|
5504
|
+
...params.search ? [`--search=${shellArg(params.search)}`] : [],
|
|
5505
|
+
...params.direction ? [`--direction=${params.direction}`] : []
|
|
5506
|
+
];
|
|
5507
|
+
const nextCommands = [];
|
|
5508
|
+
const nextOffset = asNumber(pagination?.next_offset);
|
|
5509
|
+
if (pagination?.has_more === true && nextOffset !== null && nextOffset <= 1e4) {
|
|
5510
|
+
nextCommands.push({
|
|
5511
|
+
command: ["moda tools list", ...listFlags, `--limit=${limit}`, `--offset=${nextOffset}`].join(" "),
|
|
5512
|
+
purpose: `Read the next page: tools ${nextOffset + 1}-${Math.min(nextOffset + limit, asNumber(pagination.total) ?? nextOffset + limit)} of ${asNumber(pagination.total) ?? "more"}.`,
|
|
5513
|
+
mutability: "read",
|
|
5514
|
+
requires_approval: false
|
|
5515
|
+
});
|
|
5516
|
+
}
|
|
5517
|
+
const top = asString(tools[0]?.tool_name);
|
|
5518
|
+
if (top) {
|
|
5519
|
+
nextCommands.push({ command: toolCatalogGetCommand(top, daysBack), purpose: `Recorded schema, usage over time and failure categories of ${top}, the first tool on this page.`, mutability: "read", requires_approval: false });
|
|
5520
|
+
}
|
|
5521
|
+
const warnings = tools.length === 0 ? [`No tool calls recorded in the last ${daysBack} day(s)${params.search || params.direction ? " that match the filters" : ""}. Widen --days-back${params.search || params.direction ? " or drop --search/--direction" : ""}.`] : [];
|
|
5522
|
+
context.output.writeData(data, {
|
|
5523
|
+
...warnings.length > 0 ? { warnings } : {},
|
|
5524
|
+
...nextCommands.length > 0 ? { nextCommands } : {}
|
|
5525
|
+
});
|
|
5526
|
+
break;
|
|
5527
|
+
}
|
|
5528
|
+
case "tool-catalog-detail": {
|
|
5529
|
+
if (!positional) {
|
|
5530
|
+
throw new CliInputError("<tool_name> is required", "Usage: moda tools get <tool_name> [--days-back=N] [--full]", "missing_positional", {
|
|
5531
|
+
field: "<tool_name>",
|
|
5532
|
+
suggestedCommands: ["moda tools list"]
|
|
5533
|
+
});
|
|
5534
|
+
}
|
|
5535
|
+
const params = parseSpecFlags("tool-catalog-detail", flagsToArgs(flags, "tool_name", positional), command);
|
|
5536
|
+
const daysBack = params.days_back ?? 7;
|
|
5537
|
+
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
5538
|
+
let raw;
|
|
5539
|
+
try {
|
|
5540
|
+
raw = asRecord(await callDataAPI(`/tools/${encodeURIComponent(params.tool_name)}?days_back=${daysBack}`)) ?? {};
|
|
5541
|
+
} catch (error) {
|
|
5542
|
+
if (!(error instanceof ApiError) || error.statusCode !== 404)
|
|
5543
|
+
throw error;
|
|
5544
|
+
throw new CliNotFoundError("tool", params.tool_name, `Tool "${params.tool_name}" has no recorded calls in the last ${daysBack} day(s): the name may be mistyped, or the tool was not called in this window.`, `moda tools list --search=${shellArg(params.tool_name)} --days-back=${daysBack}`);
|
|
5545
|
+
}
|
|
5546
|
+
const { data, shortened } = shapeToolCatalogDetail(raw, { daysBack, shorten: agentMode && params.full !== true });
|
|
5547
|
+
const warnings = [];
|
|
5548
|
+
if (shortened > 0) {
|
|
5549
|
+
warnings.push(`Agent output capped ${shortened} list(s) or value(s): at most 20 observed fields with 3 common values each, 5 recent calls, and 200 characters per input or sample error (the *_total fields give the full counts). Add --full for everything. The registered schema is never cut.`);
|
|
5550
|
+
}
|
|
5551
|
+
const definition = asRecord(data.definition);
|
|
5552
|
+
if (definition && definition.registered === null) {
|
|
5553
|
+
warnings.push(`No registered definition for "${params.tool_name}"; definition.observed_fields is the payload shape seen in recorded calls. Register tools with \`moda registry push\`.`);
|
|
5554
|
+
}
|
|
5555
|
+
const failureBlock = asRecord(data.failure_categories);
|
|
5556
|
+
const totalFailures = asNumber(failureBlock?.total_failures) ?? 0;
|
|
5557
|
+
const nextCommands = [];
|
|
5558
|
+
if (totalFailures > 0) {
|
|
5559
|
+
nextCommands.push({ command: toolFailureExamplesCommand(params.tool_name, daysBack), purpose: `Read the ${totalFailures} failure detection row(s) of ${params.tool_name}, with error text and tool input.`, mutability: "read", requires_approval: false });
|
|
5560
|
+
const first = asRecord(Array.isArray(failureBlock?.categories) ? failureBlock.categories[0] : undefined);
|
|
5561
|
+
const contextCommand = asString(first?.context_command);
|
|
5562
|
+
if (contextCommand) {
|
|
5563
|
+
nextCommands.push({ command: contextCommand, purpose: `Open the newest failure of the top category (${asString(first?.category) ?? "unknown"}) in its trace.`, mutability: "read", requires_approval: false });
|
|
5564
|
+
}
|
|
5565
|
+
}
|
|
5566
|
+
context.output.writeData(data, {
|
|
5567
|
+
...warnings.length > 0 ? { warnings } : {},
|
|
5568
|
+
...nextCommands.length > 0 ? { nextCommands } : {}
|
|
5569
|
+
});
|
|
5350
5570
|
break;
|
|
5351
5571
|
}
|
|
5352
5572
|
case "tool-failure-detail": {
|
|
@@ -5401,7 +5621,12 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5401
5621
|
out.push(`Showing the ${TOOL_FAILURE_AGENT_SUBTYPES} most frequent of ${subtypes.length} failure subtypes; --json lists all of them.`);
|
|
5402
5622
|
}
|
|
5403
5623
|
return trimmed;
|
|
5404
|
-
}
|
|
5624
|
+
}, [{
|
|
5625
|
+
command: toolCatalogGetCommand(params.tool_name, params.days_back ?? 7),
|
|
5626
|
+
purpose: subtypeCount === 0 && exampleCount === 0 ? `Check whether ${params.tool_name} was called at all in this window (it answers not found when it was not).` : `Call count, success rate, recorded schema and usage over time of ${params.tool_name}.`,
|
|
5627
|
+
mutability: "read",
|
|
5628
|
+
requires_approval: false
|
|
5629
|
+
}]);
|
|
5405
5630
|
break;
|
|
5406
5631
|
}
|
|
5407
5632
|
case "problem-impact": {
|
|
@@ -5678,7 +5903,8 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5678
5903
|
query2.set("offset", params.offset.toString());
|
|
5679
5904
|
const queryString = query2.toString() ? `?${query2.toString()}` : "";
|
|
5680
5905
|
const data = await callDataAPI(`/custom-signals/${id}/detections${queryString}`);
|
|
5681
|
-
|
|
5906
|
+
const warnings = customSignalProcessingWarning(data, "detections");
|
|
5907
|
+
context.output.writeData(data, warnings.length > 0 ? { warnings } : undefined);
|
|
5682
5908
|
break;
|
|
5683
5909
|
}
|
|
5684
5910
|
case "trace-signals": {
|
|
@@ -5686,7 +5912,8 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5686
5912
|
throw new CliInputError("<conversation_id> is required", "Usage: moda detections list --family=custom_signal --conversation-id=<conversation_id>");
|
|
5687
5913
|
}
|
|
5688
5914
|
const data = await callDataAPI(`/conversations/${encodeURIComponent(positional)}/custom-signals`);
|
|
5689
|
-
|
|
5915
|
+
const warnings = customSignalProcessingWarning(data, "detections");
|
|
5916
|
+
context.output.writeData(data, warnings.length > 0 ? { warnings } : undefined);
|
|
5690
5917
|
break;
|
|
5691
5918
|
}
|
|
5692
5919
|
case "signal-label": {
|
|
@@ -5904,6 +6131,14 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5904
6131
|
query2.set("offset", params.offset.toString());
|
|
5905
6132
|
if (params.family)
|
|
5906
6133
|
query2.set("family", params.family);
|
|
6134
|
+
if (readsPerTrace("emotions", params, ["user_id", "conversation_id", "include_window"])) {
|
|
6135
|
+
setTraceFilters(query2, params, TRACE_GRAIN_FLAGS.emotions);
|
|
6136
|
+
const data2 = await callDataAPI(`/emotions?${query2.toString()}`);
|
|
6137
|
+
const warnings = processingDisabledWarning(data2, "emotion");
|
|
6138
|
+
const summary2 = countingSummary(data2);
|
|
6139
|
+
context.output.writeData(data2, { ...summary2 ? { summary: summary2 } : {}, ...warnings.length > 0 ? { warnings } : {} });
|
|
6140
|
+
break;
|
|
6141
|
+
}
|
|
5907
6142
|
if (params.user_id)
|
|
5908
6143
|
query2.set("user_id", params.user_id);
|
|
5909
6144
|
if (params.conversation_id)
|
|
@@ -5916,7 +6151,8 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5916
6151
|
const processingWarnings = processingDisabledWarning(raw, "emotion");
|
|
5917
6152
|
const record = asRecord(raw);
|
|
5918
6153
|
const data = agentMode && params.include_window !== true && record ? withoutDetectionWindows(record, "detections", "conversation_context") : raw;
|
|
5919
|
-
|
|
6154
|
+
const summary = countingSummary(data);
|
|
6155
|
+
context.output.writeData(data, summary || processingWarnings.length > 0 ? { ...summary ? { summary } : {}, ...processingWarnings.length > 0 ? { warnings: processingWarnings } : {} } : undefined);
|
|
5920
6156
|
break;
|
|
5921
6157
|
}
|
|
5922
6158
|
case "laziness": {
|
|
@@ -5933,9 +6169,21 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5933
6169
|
query2.set("conversation_id", params.conversation_id);
|
|
5934
6170
|
if (params.family)
|
|
5935
6171
|
query2.set("family", params.family);
|
|
6172
|
+
if (params.conversation_id) {
|
|
6173
|
+
rejectInapplicableFlags(command, params, ["search", "status", "sort", "order"], "to one trace's detections (--conversation-id); they filter and order the trace list");
|
|
6174
|
+
}
|
|
6175
|
+
if (params.search)
|
|
6176
|
+
query2.set("search", params.search);
|
|
6177
|
+
if (params.status)
|
|
6178
|
+
query2.set("status", params.status);
|
|
6179
|
+
if (params.sort)
|
|
6180
|
+
query2.set("sort", params.sort);
|
|
6181
|
+
if (params.order)
|
|
6182
|
+
query2.set("order", params.order);
|
|
5936
6183
|
const queryString = query2.toString() ? `?${query2.toString()}` : "";
|
|
5937
6184
|
const data = await callDataAPI(`/laziness${queryString}`);
|
|
5938
|
-
|
|
6185
|
+
const summary = countingSummary(data);
|
|
6186
|
+
context.output.writeData(data, summary ? { summary } : undefined);
|
|
5939
6187
|
break;
|
|
5940
6188
|
}
|
|
5941
6189
|
case "hallucinations": {
|
|
@@ -5948,13 +6196,18 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
5948
6196
|
query2.set("limit", params.limit.toString());
|
|
5949
6197
|
if (params.offset !== undefined)
|
|
5950
6198
|
query2.set("offset", params.offset.toString());
|
|
5951
|
-
if (params
|
|
5952
|
-
query2
|
|
5953
|
-
|
|
5954
|
-
|
|
6199
|
+
if (readsPerTrace("hallucinations", params, ["conversation_id", "kind"])) {
|
|
6200
|
+
setTraceFilters(query2, params, TRACE_GRAIN_FLAGS.hallucinations);
|
|
6201
|
+
} else {
|
|
6202
|
+
if (params.conversation_id)
|
|
6203
|
+
query2.set("conversation_id", params.conversation_id);
|
|
6204
|
+
if (params.kind)
|
|
6205
|
+
query2.set("kind", params.kind);
|
|
6206
|
+
}
|
|
5955
6207
|
const queryString = query2.toString() ? `?${query2.toString()}` : "";
|
|
5956
6208
|
const data = await callDataAPI(`/hallucinations${queryString}`);
|
|
5957
|
-
|
|
6209
|
+
const summary = countingSummary(data);
|
|
6210
|
+
context.output.writeData(data, summary ? { summary } : undefined);
|
|
5958
6211
|
break;
|
|
5959
6212
|
}
|
|
5960
6213
|
case "step-scores": {
|
|
@@ -6143,7 +6396,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6143
6396
|
resetApiRequestCountBeforeRun: true,
|
|
6144
6397
|
telemetry: "result-and-error",
|
|
6145
6398
|
handler: async (context) => {
|
|
6146
|
-
const { runInit } = await import("./index-
|
|
6399
|
+
const { runInit } = await import("./index-y5jnz2t2.js");
|
|
6147
6400
|
if (context.outputMode === "agent-stream") {
|
|
6148
6401
|
context.output.writeEvent({
|
|
6149
6402
|
event: "started",
|
|
@@ -6193,7 +6446,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
6193
6446
|
resetApiRequestCountBeforeRun: true,
|
|
6194
6447
|
telemetry: "result-and-error",
|
|
6195
6448
|
handler: async (context) => {
|
|
6196
|
-
const { runProvision } = await import("./provision-
|
|
6449
|
+
const { runProvision } = await import("./provision-ghca9d54.js");
|
|
6197
6450
|
return runProvision(context, {
|
|
6198
6451
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
6199
6452
|
});
|
|
@@ -6919,6 +7172,33 @@ var commandRegistry = createCommandRegistry([
|
|
|
6919
7172
|
telemetry: "result-and-error",
|
|
6920
7173
|
handler: canonicalNounHandler
|
|
6921
7174
|
},
|
|
7175
|
+
{
|
|
7176
|
+
name: "tools",
|
|
7177
|
+
description: NOUN_SUMMARIES.tools,
|
|
7178
|
+
examples: [...leavesOf("tools").flatMap((leaf) => leaf.examples.slice(0, 2))],
|
|
7179
|
+
subcommands: treeSubcommandHelp("tools"),
|
|
7180
|
+
auth: "api-key",
|
|
7181
|
+
outputModes: ["human", "json", "agent"],
|
|
7182
|
+
mutability: "read",
|
|
7183
|
+
validateConfigBeforeRun: false,
|
|
7184
|
+
resetApiRequestCountBeforeRun: false,
|
|
7185
|
+
telemetry: "result-and-error",
|
|
7186
|
+
handler: canonicalNounHandler
|
|
7187
|
+
},
|
|
7188
|
+
legacyCommand({
|
|
7189
|
+
name: "tool-catalog",
|
|
7190
|
+
description: "The Tool catalog: every tool called in the window with calls, failed calls, success rate, effect direction and last seen",
|
|
7191
|
+
examples: ["moda tools list --sort=failure_rate --limit=10"],
|
|
7192
|
+
hidden: true,
|
|
7193
|
+
...dataApiDefaults
|
|
7194
|
+
}),
|
|
7195
|
+
legacyCommand({
|
|
7196
|
+
name: "tool-catalog-detail",
|
|
7197
|
+
description: "One tool's calls, recorded schema and observed payload fields, usage over time and top failure categories",
|
|
7198
|
+
examples: ["moda tools get <tool_name>"],
|
|
7199
|
+
hidden: true,
|
|
7200
|
+
...dataApiDefaults
|
|
7201
|
+
}),
|
|
6922
7202
|
{
|
|
6923
7203
|
name: "review",
|
|
6924
7204
|
description: NOUN_SUMMARIES.review,
|