@moda-ai/cli 1.55.14 → 1.55.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/{agent-y47qgmf1.js → agent-a2xwfeeh.js} +9 -9
- package/dist/{cli-ryd7nzke.js → cli-2ars875d.js} +2 -2
- package/dist/{cli-bfmn3bsk.js → cli-3gwbg0xp.js} +2 -2
- package/dist/{cli-4qe6n8am.js → cli-438g4nwh.js} +122 -2
- package/dist/{cli-k7vwt56h.js → cli-53mvsfgn.js} +3 -3
- package/dist/{cli-ssqb8bfw.js → cli-6ca1sz0a.js} +1 -1
- package/dist/{cli-k9nae6t9.js → cli-7fc44hhq.js} +1123 -187
- package/dist/{cli-ndn5m6wn.js → cli-86q35fpq.js} +8 -8
- package/dist/{cli-09rr5smg.js → cli-atx672xv.js} +1 -1
- package/dist/{cli-kwz900s4.js → cli-b3cxcxgn.js} +5 -4
- package/dist/{cli-4x9w6ey7.js → cli-kf3d6y8c.js} +1 -1
- package/dist/{cli-weqp7xc1.js → cli-xy6zn80e.js} +5 -5
- package/dist/{cli-y8gbbe9k.js → cli-zdeywyn9.js} +4 -4
- package/dist/cli.js +299 -94
- package/dist/{doctor-grvx6xx0.js → doctor-e2xrbpmp.js} +9 -9
- package/dist/{fix-91sr76gw.js → fix-v8xka487.js} +7 -7
- package/dist/{harness-vm0xd80p.js → harness-28wbzncq.js} +6 -6
- package/dist/{harness-github-actions-tmy3gqwa.js → harness-github-actions-301nak95.js} +6 -6
- package/dist/{index-f6cydfxg.js → index-ccdpy9ma.js} +11 -11
- package/dist/{production-intelligence-mg3qp2dg.js → production-intelligence-0wqcvvxk.js} +6 -5
- package/dist/{profile-commands-2g5bjzj2.js → profile-commands-f5kysjrv.js} +3 -3
- package/dist/prompt-source-mcp.js +6 -6
- package/dist/{prompts-kw5kzm39.js → prompts-jg0stjfb.js} +7 -7
- package/dist/{provision-rm0yc08f.js → provision-25bw5rd7.js} +4 -4
- package/dist/{registry-mbz65bjy.js → registry-39xzetsc.js} +4 -4
- package/dist/{skills-sagxq9sc.js → skills-gjesa81c.js} +6 -6
- package/dist/{sync-xv04wnth.js → sync-7ts9psky.js} +8 -8
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +31 -4
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
BATCH_CONCURRENCY,
|
|
4
|
+
BATCH_MAX_TARGETS,
|
|
3
5
|
MODA_INTELLIGENCE_V1_JSON_SCHEMA,
|
|
4
6
|
asNumber,
|
|
5
7
|
asRecord,
|
|
6
8
|
asString,
|
|
9
|
+
collectBatchTargets,
|
|
10
|
+
contextTarget,
|
|
7
11
|
embeddedWindowSize,
|
|
8
12
|
frustrationsFromEmotions,
|
|
13
|
+
mapWithConcurrency,
|
|
14
|
+
parseBatchTarget,
|
|
9
15
|
trimToolFailureConversations,
|
|
10
16
|
withFrustrationAnchors,
|
|
11
17
|
withToolFailureAnchors
|
|
12
|
-
} from "./cli-
|
|
18
|
+
} from "./cli-438g4nwh.js";
|
|
13
19
|
import {
|
|
14
20
|
createCommandContext,
|
|
15
21
|
parseBooleanFlagValue
|
|
16
|
-
} from "./cli-
|
|
22
|
+
} from "./cli-kf3d6y8c.js";
|
|
17
23
|
import {
|
|
18
24
|
SIGNALS_MANAGEMENT_SUBCOMMANDS,
|
|
19
25
|
assertFlags,
|
|
@@ -23,17 +29,17 @@ import {
|
|
|
23
29
|
runUserCommand,
|
|
24
30
|
runUsersCommand,
|
|
25
31
|
unknownSignalsSubcommandError
|
|
26
|
-
} from "./cli-
|
|
32
|
+
} from "./cli-53mvsfgn.js";
|
|
27
33
|
import {
|
|
28
34
|
ApiError,
|
|
29
35
|
callControlAPI,
|
|
30
36
|
callDataAPI
|
|
31
|
-
} from "./cli-
|
|
37
|
+
} from "./cli-2ars875d.js";
|
|
32
38
|
import {
|
|
33
39
|
apiKeyHeaders,
|
|
34
40
|
isPlatformApiKey,
|
|
35
41
|
setPlatformTenantOverride
|
|
36
|
-
} from "./cli-
|
|
42
|
+
} from "./cli-atx672xv.js";
|
|
37
43
|
import {
|
|
38
44
|
AGENT_ERROR_CODES,
|
|
39
45
|
CliAccessError,
|
|
@@ -55,6 +61,7 @@ import {
|
|
|
55
61
|
apiErrorStatus,
|
|
56
62
|
createCliOutput,
|
|
57
63
|
embeddedTenantIdFromApiKey,
|
|
64
|
+
errorToAgentError,
|
|
58
65
|
getApiRequestCount,
|
|
59
66
|
getModaDir,
|
|
60
67
|
isApiLikeError,
|
|
@@ -70,7 +77,7 @@ import {
|
|
|
70
77
|
setAgentUpdateNotice,
|
|
71
78
|
validateConfig,
|
|
72
79
|
wasOutputCancelled
|
|
73
|
-
} from "./cli-
|
|
80
|
+
} from "./cli-b3cxcxgn.js";
|
|
74
81
|
import {
|
|
75
82
|
__require
|
|
76
83
|
} from "./cli-0v6na3yp.js";
|
|
@@ -142,7 +149,8 @@ var ContextSchema = z.object({
|
|
|
142
149
|
metadata_only: boolFlag(),
|
|
143
150
|
all: boolFlag(),
|
|
144
151
|
from: z.number().int().min(0).optional(),
|
|
145
|
-
max_messages: z.number().int().min(1).max(5000).optional()
|
|
152
|
+
max_messages: z.number().int().min(1).max(5000).optional(),
|
|
153
|
+
ids_from: z.string().min(1).optional()
|
|
146
154
|
});
|
|
147
155
|
var FrustrationsSchema = z.object({
|
|
148
156
|
days_back: daysBackFlag(7),
|
|
@@ -378,7 +386,8 @@ var AuditSchema = z.object({
|
|
|
378
386
|
include_raw: boolFlag(),
|
|
379
387
|
include_bodies: boolFlag(),
|
|
380
388
|
limit: z.number().min(1).max(1000).default(200).optional(),
|
|
381
|
-
cursor: z.string().min(1).max(512).optional()
|
|
389
|
+
cursor: z.string().min(1).max(512).optional(),
|
|
390
|
+
ids_from: z.string().min(1).optional()
|
|
382
391
|
});
|
|
383
392
|
var TIME_RANGES = ["all", "1h", "3d", "7d", "24h", "30d", "90d"];
|
|
384
393
|
var SEARCH_MODES = ["keyword", "semantic", "hybrid"];
|
|
@@ -2081,46 +2090,46 @@ function exitCodesForCommand(command) {
|
|
|
2081
2090
|
import { fileURLToPath } from "url";
|
|
2082
2091
|
import { realpathSync } from "fs";
|
|
2083
2092
|
async function runPromptsCommand(...args) {
|
|
2084
|
-
return (await import("./prompts-
|
|
2093
|
+
return (await import("./prompts-jg0stjfb.js")).runPromptsCommand(...args);
|
|
2085
2094
|
}
|
|
2086
2095
|
async function runSkillsCommand(...args) {
|
|
2087
|
-
return (await import("./skills-
|
|
2096
|
+
return (await import("./skills-gjesa81c.js")).runSkillsCommand(...args);
|
|
2088
2097
|
}
|
|
2089
2098
|
async function runFixCommand(...args) {
|
|
2090
|
-
return (await import("./fix-
|
|
2099
|
+
return (await import("./fix-v8xka487.js")).runFixCommand(...args);
|
|
2091
2100
|
}
|
|
2092
2101
|
async function runFixesCommand(...args) {
|
|
2093
|
-
return (await import("./fix-
|
|
2102
|
+
return (await import("./fix-v8xka487.js")).runFixesCommand(...args);
|
|
2094
2103
|
}
|
|
2095
2104
|
async function runHarnessCommand(...args) {
|
|
2096
|
-
return (await import("./harness-
|
|
2105
|
+
return (await import("./harness-28wbzncq.js")).runHarnessCommand(...args);
|
|
2097
2106
|
}
|
|
2098
2107
|
async function runSyncCommand(...args) {
|
|
2099
|
-
return (await import("./sync-
|
|
2108
|
+
return (await import("./sync-7ts9psky.js")).runSyncCommand(...args);
|
|
2100
2109
|
}
|
|
2101
2110
|
async function runRegistryCommand(...args) {
|
|
2102
|
-
return (await import("./registry-
|
|
2111
|
+
return (await import("./registry-39xzetsc.js")).runRegistryCommand(...args);
|
|
2103
2112
|
}
|
|
2104
2113
|
async function runDoctorCommand(...args) {
|
|
2105
|
-
return (await import("./doctor-
|
|
2114
|
+
return (await import("./doctor-e2xrbpmp.js")).runDoctorCommand(...args);
|
|
2106
2115
|
}
|
|
2107
2116
|
async function runStatusCommand(...args) {
|
|
2108
|
-
return (await import("./doctor-
|
|
2117
|
+
return (await import("./doctor-e2xrbpmp.js")).runStatusCommand(...args);
|
|
2109
2118
|
}
|
|
2110
2119
|
async function runAuthCommand(...args) {
|
|
2111
|
-
return (await import("./profile-commands-
|
|
2120
|
+
return (await import("./profile-commands-f5kysjrv.js")).runAuthCommand(...args);
|
|
2112
2121
|
}
|
|
2113
2122
|
async function runConfigCommand(...args) {
|
|
2114
|
-
return (await import("./profile-commands-
|
|
2123
|
+
return (await import("./profile-commands-f5kysjrv.js")).runConfigCommand(...args);
|
|
2115
2124
|
}
|
|
2116
2125
|
async function runProfilesCommand(...args) {
|
|
2117
|
-
return (await import("./profile-commands-
|
|
2126
|
+
return (await import("./profile-commands-f5kysjrv.js")).runProfilesCommand(...args);
|
|
2118
2127
|
}
|
|
2119
2128
|
async function runAgentCommand(...args) {
|
|
2120
|
-
return (await import("./agent-
|
|
2129
|
+
return (await import("./agent-a2xwfeeh.js")).runAgentCommand(...args);
|
|
2121
2130
|
}
|
|
2122
2131
|
async function runProductionCommand(...args) {
|
|
2123
|
-
return (await import("./production-intelligence-
|
|
2132
|
+
return (await import("./production-intelligence-0wqcvvxk.js")).runProductionCommand(...args);
|
|
2124
2133
|
}
|
|
2125
2134
|
function parseArgs(argv) {
|
|
2126
2135
|
const args = argv.slice(2);
|
|
@@ -2376,7 +2385,9 @@ Commands:
|
|
|
2376
2385
|
world-state <conversation_id> Get a trace's world state (slots/threads/events)
|
|
2377
2386
|
context <conversation_id> Get windowed trace context (--metadata-only: summary + counts only)
|
|
2378
2387
|
context <conversation_id> --all Whole transcript in order (first 500; --from=N --max-messages=N to continue)
|
|
2388
|
+
context <id>[@N] <id>[@N] ... Batch: up to 25 traces in one call (or --ids-from=-|<file>)
|
|
2379
2389
|
audit <conversation_id|trace_id> Raw span audit (spans, hierarchy, orphans, duplicates)
|
|
2390
|
+
audit <id> <id> ... Batch audit: up to 25 ids in one call (or --ids-from=-|<file>)
|
|
2380
2391
|
frustrations Frustration detections (same data as emotions --family=frustration)
|
|
2381
2392
|
emotions Multi-family emotion detections (frustration, disapproval, sadness, confusion, anxiety, trust, positive)
|
|
2382
2393
|
hallucinations Grounding detections: contradicted/verified outputs with rule breakdown
|
|
@@ -2825,7 +2836,7 @@ function noWorldStateWarnings(conversationId, isMissing) {
|
|
|
2825
2836
|
return;
|
|
2826
2837
|
return {
|
|
2827
2838
|
warnings: [
|
|
2828
|
-
`No world state for trace "${conversationId}": the trace may not exist in this tenant, or its world state has not been generated yet. Check the trace exists with: moda context ${conversationId} --metadata-only`
|
|
2839
|
+
`No world state for trace "${conversationId}": the trace may not exist in this tenant, or its world state has not been generated yet. Check the trace exists with: moda context ${shellArg(contextTarget(conversationId))} --metadata-only`
|
|
2829
2840
|
]
|
|
2830
2841
|
};
|
|
2831
2842
|
}
|
|
@@ -3550,6 +3561,7 @@ function processingDisabledWarning(data, family) {
|
|
|
3550
3561
|
}
|
|
3551
3562
|
var CONTEXT_USAGE = "Usage: moda context <conversation_id> [--msg-index=N (alias --message-index)] [--window=0-5 | --metadata-only]";
|
|
3552
3563
|
var CONTEXT_ALL_USAGE = "Usage: moda context <conversation_id> --all [--from=N] [--max-messages=N]";
|
|
3564
|
+
var CONTEXT_BATCH_USAGE = `Usage: moda context <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)`;
|
|
3553
3565
|
var CONTEXT_FLAG_ALIASES = { "message-index": "msg-index" };
|
|
3554
3566
|
var CONTEXT_MAX_WINDOW = 5;
|
|
3555
3567
|
var EMPTY_ANCHOR_VALUES = new Set(["", "null", "undefined", "none"]);
|
|
@@ -3723,7 +3735,7 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
3723
3735
|
if (next !== null) {
|
|
3724
3736
|
const last = asNumber(returned[returned.length - 1]?.index) ?? next - 1;
|
|
3725
3737
|
const nextMax = firstMissing !== null ? Math.min(pageSize, Math.max(kept * 2, 50)) : pageSize;
|
|
3726
|
-
const continueWith = `moda context ${shellArg(conversationId)} --all --from=${next} --max-messages=${nextMax}`;
|
|
3738
|
+
const continueWith = `moda context ${shellArg(contextTarget(conversationId))} --all --from=${next} --max-messages=${nextMax}`;
|
|
3727
3739
|
out.push(`Trace has ${total} messages; returned messages ${start}-${last}. ` + (firstMissing !== null ? `Stopped at ${kept} of the ${messages.length} messages read to stay under the agent output byte limit (--json has no limit). ` : "") + `Continue with: ${continueWith}`);
|
|
3728
3740
|
nextCommands.push({
|
|
3729
3741
|
command: continueWith,
|
|
@@ -3768,6 +3780,249 @@ async function readFullTranscript(conversationId, opts = {}) {
|
|
|
3768
3780
|
}
|
|
3769
3781
|
return build(low);
|
|
3770
3782
|
}
|
|
3783
|
+
async function readContextItem(command, params, inputWarnings, fits) {
|
|
3784
|
+
if (params.all === true) {
|
|
3785
|
+
const full = await readFullTranscript(params.conversation_id, {
|
|
3786
|
+
from: params.from,
|
|
3787
|
+
maxMessages: params.max_messages,
|
|
3788
|
+
fits: fits ? (page) => fits(page.data, { warnings: page.warnings, nextCommands: page.nextCommands }) : undefined
|
|
3789
|
+
});
|
|
3790
|
+
const fullWarnings = [...inputWarnings, ...full.warnings];
|
|
3791
|
+
return {
|
|
3792
|
+
data: full.data,
|
|
3793
|
+
options: {
|
|
3794
|
+
...fullWarnings.length > 0 ? { warnings: fullWarnings } : {},
|
|
3795
|
+
...full.nextCommands.length > 0 ? { nextCommands: full.nextCommands } : {}
|
|
3796
|
+
}
|
|
3797
|
+
};
|
|
3798
|
+
}
|
|
3799
|
+
const query2 = new URLSearchParams;
|
|
3800
|
+
if (params.msg_index !== undefined)
|
|
3801
|
+
query2.set("msg_index", params.msg_index.toString());
|
|
3802
|
+
if (params.metadata_only === true)
|
|
3803
|
+
query2.set("metadata_only", "1");
|
|
3804
|
+
const window = params.window === undefined ? undefined : Math.min(params.window, CONTEXT_MAX_WINDOW);
|
|
3805
|
+
if (window !== undefined)
|
|
3806
|
+
query2.set("window", window.toString());
|
|
3807
|
+
const queryString = query2.toString() ? `?${query2.toString()}` : "";
|
|
3808
|
+
const contextPath = `/conversations/${encodeURIComponent(params.conversation_id)}/context`;
|
|
3809
|
+
const data = params.metadata_only === true ? await readContextMetadataOnly(contextPath, query2) : await callDataAPI(`${contextPath}${queryString}`);
|
|
3810
|
+
const ctxRecord = asRecord(data) ?? {};
|
|
3811
|
+
throwIfNotFound("trace", params.conversation_id, asNumber(ctxRecord.total_messages) === 0);
|
|
3812
|
+
const warnings = [...inputWarnings];
|
|
3813
|
+
const nextCommands = [];
|
|
3814
|
+
if (params.window !== undefined && params.window > CONTEXT_MAX_WINDOW) {
|
|
3815
|
+
const center = asNumber(asRecord(ctxRecord.context)?.center_index) ?? params.msg_index ?? 0;
|
|
3816
|
+
const span = Math.min(params.window * 2 + 1, CONTEXT_ALL_MAX_MESSAGES);
|
|
3817
|
+
const from = Math.max(0, center - Math.floor((span - 1) / 2));
|
|
3818
|
+
const wide = `moda context ${shellArg(contextTarget(params.conversation_id))} --all --from=${from} --max-messages=${span}`;
|
|
3819
|
+
warnings.push(`--window=${params.window} is above the maximum of ${CONTEXT_MAX_WINDOW}, so this shows ±${CONTEXT_MAX_WINDOW} messages. For a wider slice run: ${wide}`);
|
|
3820
|
+
nextCommands.push({ command: wide, purpose: `Read ±${params.window} messages around the anchor.`, mutability: "read", requires_approval: false });
|
|
3821
|
+
}
|
|
3822
|
+
return {
|
|
3823
|
+
data,
|
|
3824
|
+
options: {
|
|
3825
|
+
...warnings.length > 0 ? { warnings } : {},
|
|
3826
|
+
...nextCommands.length > 0 ? { nextCommands } : {}
|
|
3827
|
+
}
|
|
3828
|
+
};
|
|
3829
|
+
}
|
|
3830
|
+
var AUDIT_USAGE = "Usage: moda audit <conversation_id|trace_id> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] [--cursor=<next_cursor>]";
|
|
3831
|
+
var AUDIT_BATCH_USAGE = `Usage: moda audit <id> <id> ... | --ids-from=-|<file> [--kind=auto|trace|conversation] [--include-raw] [--include-bodies] [--limit=N] (max ${BATCH_MAX_TARGETS} targets)`;
|
|
3832
|
+
async function readAuditItem(command, params, budget) {
|
|
3833
|
+
const query2 = new URLSearchParams;
|
|
3834
|
+
if (params.kind && params.kind !== "auto")
|
|
3835
|
+
query2.set("kind", params.kind);
|
|
3836
|
+
if (params.include_raw === true)
|
|
3837
|
+
query2.set("include_raw", "1");
|
|
3838
|
+
if (params.include_bodies === true)
|
|
3839
|
+
query2.set("include_bodies", "1");
|
|
3840
|
+
if (params.limit)
|
|
3841
|
+
query2.set("limit", params.limit.toString());
|
|
3842
|
+
if (params.cursor)
|
|
3843
|
+
query2.set("cursor", params.cursor);
|
|
3844
|
+
let maxBytes = budget?.maxBytes;
|
|
3845
|
+
let page = auditOutput(command, params, await fetchAudit(params.id, query2, maxBytes));
|
|
3846
|
+
while (budget && maxBytes !== undefined && maxBytes > AUDIT_MIN_PAGE_BYTES && !budget.fits(page.data, page.options)) {
|
|
3847
|
+
maxBytes = Math.max(AUDIT_MIN_PAGE_BYTES, Math.floor(maxBytes / 2));
|
|
3848
|
+
page = auditOutput(command, params, await fetchAudit(params.id, query2, maxBytes));
|
|
3849
|
+
}
|
|
3850
|
+
if (budget && !budget.fits(page.data, page.options)) {
|
|
3851
|
+
page.options.warnings = [
|
|
3852
|
+
...page.options.warnings ?? [],
|
|
3853
|
+
"This page is a single ingest row larger than the agent output budget, so some of its spans are cut from this output. Rerun this command with --json (no byte limit) or a higher MODA_AGENT_MAX_OUTPUT_BYTES to see the whole row before following next_cursor."
|
|
3854
|
+
];
|
|
3855
|
+
}
|
|
3856
|
+
return page;
|
|
3857
|
+
}
|
|
3858
|
+
var IDS_FROM_KEYS = ["ids-from", "ids_from"];
|
|
3859
|
+
function singleContextTarget(positional, flags) {
|
|
3860
|
+
if (positional === undefined)
|
|
3861
|
+
return [positional, flags];
|
|
3862
|
+
const target = parseBatchTarget(positional, true, CONTEXT_USAGE);
|
|
3863
|
+
if (target.msgIndex === undefined)
|
|
3864
|
+
return [target.id, flags];
|
|
3865
|
+
if (Object.keys(flags).some((key) => ["msg-index", "message-index"].includes(key.replace(/_/g, "-")))) {
|
|
3866
|
+
throw new CliInputError(`${JSON.stringify(positional)} already anchors at message ${target.msgIndex}; drop --msg-index, or pass {"id": "..."} if the id itself ends in @<digits>.`, CONTEXT_USAGE, "flag_conflict");
|
|
3867
|
+
}
|
|
3868
|
+
return [target.id, { ...flags, "msg-index": String(target.msgIndex) }];
|
|
3869
|
+
}
|
|
3870
|
+
function isBatchRead(positionals, flags) {
|
|
3871
|
+
return positionals.length > 1 || IDS_FROM_KEYS.some((key) => flags[key] !== undefined);
|
|
3872
|
+
}
|
|
3873
|
+
function splitIdsFrom(flags) {
|
|
3874
|
+
let idsFrom;
|
|
3875
|
+
const rest = {};
|
|
3876
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
3877
|
+
if (IDS_FROM_KEYS.includes(key))
|
|
3878
|
+
idsFrom = value;
|
|
3879
|
+
else
|
|
3880
|
+
rest[key] = value;
|
|
3881
|
+
}
|
|
3882
|
+
return { idsFrom, rest };
|
|
3883
|
+
}
|
|
3884
|
+
function auditItemByteShare(count) {
|
|
3885
|
+
return Math.max(AUDIT_MIN_PAGE_BYTES, Math.floor((agentMaxOutputBytes() - AUDIT_AGENT_RESERVE_BYTES) / count));
|
|
3886
|
+
}
|
|
3887
|
+
var BATCH_ENVELOPE_RESERVE_BYTES = 4096;
|
|
3888
|
+
var BATCH_ENVELOPE_RESERVE_PER_TARGET_BYTES = 256;
|
|
3889
|
+
function contextItemByteShare(count) {
|
|
3890
|
+
const reserve = BATCH_ENVELOPE_RESERVE_BYTES + BATCH_ENVELOPE_RESERVE_PER_TARGET_BYTES * count;
|
|
3891
|
+
return Math.max(1, Math.floor((agentMaxOutputBytes() - reserve) / count));
|
|
3892
|
+
}
|
|
3893
|
+
function fitsShare(share) {
|
|
3894
|
+
return (data, options) => Buffer.byteLength(JSON.stringify({ data, ...options }) ?? "", "utf8") <= share;
|
|
3895
|
+
}
|
|
3896
|
+
function isBatchFatal(error) {
|
|
3897
|
+
const type = classifyCliError(error);
|
|
3898
|
+
return type === "auth_error" || type === "access_error" || error instanceof CliInputError;
|
|
3899
|
+
}
|
|
3900
|
+
async function readBatchItem(target, read) {
|
|
3901
|
+
try {
|
|
3902
|
+
const item = await read();
|
|
3903
|
+
return {
|
|
3904
|
+
target: target.raw,
|
|
3905
|
+
ok: true,
|
|
3906
|
+
data: item.data,
|
|
3907
|
+
...item.options.warnings?.length ? { warnings: item.options.warnings } : {},
|
|
3908
|
+
...item.options.nextCommands?.length ? { next_commands: item.options.nextCommands } : {}
|
|
3909
|
+
};
|
|
3910
|
+
} catch (error) {
|
|
3911
|
+
if (isBatchFatal(error))
|
|
3912
|
+
throw error;
|
|
3913
|
+
const agentError = errorToAgentError(error);
|
|
3914
|
+
const code = classifyCliError(error) === "api_not_found" ? "not_found" : agentError.code;
|
|
3915
|
+
return {
|
|
3916
|
+
target: target.raw,
|
|
3917
|
+
ok: false,
|
|
3918
|
+
error: {
|
|
3919
|
+
code,
|
|
3920
|
+
message: agentError.message,
|
|
3921
|
+
...agentError.cause ? { cause: agentError.cause } : {},
|
|
3922
|
+
...agentError.suggested_commands?.length ? { suggested_commands: agentError.suggested_commands } : {}
|
|
3923
|
+
}
|
|
3924
|
+
};
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
function renderBatchFlags(flags) {
|
|
3928
|
+
return Object.entries(flags).map(([key, value]) => value === "true" ? `--${key}` : `--${key}=${shellArg(value)}`);
|
|
3929
|
+
}
|
|
3930
|
+
function writeBatchResult(command, context, targets, results, batchWarnings, flags) {
|
|
3931
|
+
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
3932
|
+
const build = (kept2) => {
|
|
3933
|
+
const returned = results.slice(0, kept2);
|
|
3934
|
+
const remaining = targets.slice(kept2);
|
|
3935
|
+
const failed = returned.filter((result) => !result.ok);
|
|
3936
|
+
const allFailed = failed.length === returned.length;
|
|
3937
|
+
const warnings = [...batchWarnings];
|
|
3938
|
+
if (failed.length > 0 && failed.length < returned.length) {
|
|
3939
|
+
warnings.push(`${failed.length} of ${returned.length} targets failed: ` + failed.map((result) => `${result.target} (${result.error?.code ?? "error"})`).join(", ") + ".");
|
|
3940
|
+
}
|
|
3941
|
+
const nextCommands = [];
|
|
3942
|
+
if (remaining.length > 0) {
|
|
3943
|
+
const lines = remaining.map((target) => shellArg(target.raw)).join(" ");
|
|
3944
|
+
const continueWith = [`printf '%s\\n' ${lines} |`, `moda ${command}`, "--ids-from=-", ...renderBatchFlags(flags)].join(" ");
|
|
3945
|
+
warnings.push(`Returned ${kept2} of ${targets.length} targets to stay under the agent output byte limit (--json has no limit). Read the other ${remaining.length} with: ${continueWith}`);
|
|
3946
|
+
nextCommands.push({
|
|
3947
|
+
command: continueWith,
|
|
3948
|
+
purpose: `Read the remaining ${remaining.length} target(s) of this batch.`,
|
|
3949
|
+
mutability: "read",
|
|
3950
|
+
requires_approval: false
|
|
3951
|
+
});
|
|
3952
|
+
}
|
|
3953
|
+
return {
|
|
3954
|
+
data: {
|
|
3955
|
+
results: returned,
|
|
3956
|
+
requested: targets.length,
|
|
3957
|
+
returned: returned.length,
|
|
3958
|
+
succeeded: returned.length - failed.length,
|
|
3959
|
+
failed: failed.length,
|
|
3960
|
+
has_more: remaining.length > 0,
|
|
3961
|
+
remaining_targets: remaining.map((target) => target.raw)
|
|
3962
|
+
},
|
|
3963
|
+
options: {
|
|
3964
|
+
summary: `Read ${returned.length - failed.length} of ${targets.length} targets` + (failed.length > 0 ? ` (${failed.length} failed)` : "") + (remaining.length > 0 ? `; ${remaining.length} left for a follow-up call` : "") + ".",
|
|
3965
|
+
...warnings.length > 0 ? { warnings } : {},
|
|
3966
|
+
...nextCommands.length > 0 ? { nextCommands } : {},
|
|
3967
|
+
...allFailed ? {
|
|
3968
|
+
status: "error",
|
|
3969
|
+
errors: returned.map((result) => ({
|
|
3970
|
+
code: result.error?.code ?? "unknown_error",
|
|
3971
|
+
message: clipText(`${result.target}: ${result.error?.message ?? "failed"}`, BATCH_ERROR_MESSAGE_CHARS),
|
|
3972
|
+
blocking: false
|
|
3973
|
+
}))
|
|
3974
|
+
} : failed.length > 0 ? { status: "degraded" } : {}
|
|
3975
|
+
}
|
|
3976
|
+
};
|
|
3977
|
+
};
|
|
3978
|
+
let kept = results.length;
|
|
3979
|
+
let page = build(kept);
|
|
3980
|
+
while (agentMode && kept > 1 && !agentEnvelopeFits(command, page.data, page.options)) {
|
|
3981
|
+
kept -= 1;
|
|
3982
|
+
page = build(kept);
|
|
3983
|
+
}
|
|
3984
|
+
const failedPage = page.options.status === "error";
|
|
3985
|
+
context.output.writeData(page.data, { ...page.options, ...failedPage ? { bypassQuiet: true } : {} });
|
|
3986
|
+
return failedPage ? 1 : 0;
|
|
3987
|
+
}
|
|
3988
|
+
var BATCH_ERROR_MESSAGE_CHARS = 300;
|
|
3989
|
+
function clipText(text, max) {
|
|
3990
|
+
return text.length <= max ? text : `${text.slice(0, max - 3)}...`;
|
|
3991
|
+
}
|
|
3992
|
+
async function runContextBatch(command, positionals, flags, context) {
|
|
3993
|
+
const { idsFrom, rest } = splitIdsFrom(flags);
|
|
3994
|
+
if (Object.keys(rest).some((key) => key.replace(/_/g, "-") === "conversation-id")) {
|
|
3995
|
+
throw new CliInputError("Batch reads take ids as positionals or --ids-from, not --conversation-id; drop --conversation-id.", CONTEXT_BATCH_USAGE, "flag_conflict");
|
|
3996
|
+
}
|
|
3997
|
+
const targets = await collectBatchTargets(positionals, idsFrom, { anchors: true, usage: CONTEXT_BATCH_USAGE, command });
|
|
3998
|
+
const { params: base, warnings: inputWarnings } = parseContextRequest(targets[0].id, rest);
|
|
3999
|
+
if ((base.all === true || base.metadata_only === true) && targets.some((target) => target.msgIndex !== undefined)) {
|
|
4000
|
+
throw new CliInputError(`${base.all === true ? "--all reads whole traces" : "--metadata-only reads no messages"}, so targets cannot carry an @msg_index anchor; drop the flag or the anchors.`, CONTEXT_BATCH_USAGE, "flag_conflict");
|
|
4001
|
+
}
|
|
4002
|
+
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
4003
|
+
const share = agentMode ? contextItemByteShare(targets.length) : undefined;
|
|
4004
|
+
const results = await mapWithConcurrency(targets, BATCH_CONCURRENCY, (target) => readBatchItem(target, () => {
|
|
4005
|
+
const params = {
|
|
4006
|
+
...base,
|
|
4007
|
+
conversation_id: target.id,
|
|
4008
|
+
...target.msgIndex !== undefined ? { msg_index: target.msgIndex } : {}
|
|
4009
|
+
};
|
|
4010
|
+
return readContextItem(command, params, [], share !== undefined ? fitsShare(share) : undefined);
|
|
4011
|
+
}));
|
|
4012
|
+
return writeBatchResult(command, context, targets, results, inputWarnings, rest);
|
|
4013
|
+
}
|
|
4014
|
+
async function runAuditBatch(command, positionals, flags, context) {
|
|
4015
|
+
const { idsFrom, rest } = splitIdsFrom(flags);
|
|
4016
|
+
if (rest.cursor !== undefined) {
|
|
4017
|
+
throw new CliInputError("--cursor continues one trace, so it cannot be used with several ids; follow each item's next_commands instead.", AUDIT_BATCH_USAGE, "flag_conflict");
|
|
4018
|
+
}
|
|
4019
|
+
const targets = await collectBatchTargets(positionals, idsFrom, { anchors: false, usage: AUDIT_BATCH_USAGE, command });
|
|
4020
|
+
const base = parseCommandFlags(AuditSchema, flagsToArgs(rest, "id", targets[0].id), command, { positionalKey: "id" });
|
|
4021
|
+
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
4022
|
+
const share = agentMode ? auditItemByteShare(targets.length) : undefined;
|
|
4023
|
+
const results = await mapWithConcurrency(targets, BATCH_CONCURRENCY, (target) => readBatchItem(target, () => readAuditItem(command, { ...base, id: target.id }, share !== undefined ? { maxBytes: share, fits: fitsShare(share) } : undefined)));
|
|
4024
|
+
return writeBatchResult(command, context, targets, results, [], rest);
|
|
4025
|
+
}
|
|
3771
4026
|
async function runCommand(command, positional, flags, positionals = positional ? [positional] : [], context = createCommandContext({ command, positional, positionals, flags })) {
|
|
3772
4027
|
assertHandParsedFlags(command, flags, positionals);
|
|
3773
4028
|
switch (command) {
|
|
@@ -3988,81 +4243,28 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
3988
4243
|
break;
|
|
3989
4244
|
}
|
|
3990
4245
|
case "context": {
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
|
|
3997
|
-
fits: agentMode ? (page) => agentEnvelopeFits(command, page.data, { warnings: page.warnings, nextCommands: page.nextCommands }) : undefined
|
|
3998
|
-
});
|
|
3999
|
-
const fullWarnings = [...inputWarnings, ...full.warnings];
|
|
4000
|
-
context.output.writeData(full.data, {
|
|
4001
|
-
...fullWarnings.length > 0 ? { warnings: fullWarnings } : {},
|
|
4002
|
-
...full.nextCommands.length > 0 ? { nextCommands: full.nextCommands } : {}
|
|
4003
|
-
});
|
|
4004
|
-
break;
|
|
4005
|
-
}
|
|
4006
|
-
const query2 = new URLSearchParams;
|
|
4007
|
-
if (params.msg_index !== undefined)
|
|
4008
|
-
query2.set("msg_index", params.msg_index.toString());
|
|
4009
|
-
if (params.metadata_only === true)
|
|
4010
|
-
query2.set("metadata_only", "1");
|
|
4011
|
-
const window = params.window === undefined ? undefined : Math.min(params.window, CONTEXT_MAX_WINDOW);
|
|
4012
|
-
if (window !== undefined)
|
|
4013
|
-
query2.set("window", window.toString());
|
|
4014
|
-
const queryString = query2.toString() ? `?${query2.toString()}` : "";
|
|
4015
|
-
const contextPath = `/conversations/${encodeURIComponent(params.conversation_id)}/context`;
|
|
4016
|
-
const data = params.metadata_only === true ? await readContextMetadataOnly(contextPath, query2) : await callDataAPI(`${contextPath}${queryString}`);
|
|
4017
|
-
const ctxRecord = asRecord(data) ?? {};
|
|
4018
|
-
throwIfNotFound("trace", params.conversation_id, asNumber(ctxRecord.total_messages) === 0);
|
|
4019
|
-
const warnings = [...inputWarnings];
|
|
4020
|
-
const nextCommands = [];
|
|
4021
|
-
if (params.window !== undefined && params.window > CONTEXT_MAX_WINDOW) {
|
|
4022
|
-
const center = asNumber(asRecord(ctxRecord.context)?.center_index) ?? params.msg_index ?? 0;
|
|
4023
|
-
const span = Math.min(params.window * 2 + 1, CONTEXT_ALL_MAX_MESSAGES);
|
|
4024
|
-
const from = Math.max(0, center - Math.floor((span - 1) / 2));
|
|
4025
|
-
const wide = `moda context ${shellArg(params.conversation_id)} --all --from=${from} --max-messages=${span}`;
|
|
4026
|
-
warnings.push(`--window=${params.window} is above the maximum of ${CONTEXT_MAX_WINDOW}, so this shows ±${CONTEXT_MAX_WINDOW} messages. For a wider slice run: ${wide}`);
|
|
4027
|
-
nextCommands.push({ command: wide, purpose: `Read ±${params.window} messages around the anchor.`, mutability: "read", requires_approval: false });
|
|
4028
|
-
}
|
|
4029
|
-
context.output.writeData(data, {
|
|
4030
|
-
...warnings.length > 0 ? { warnings } : {},
|
|
4031
|
-
...nextCommands.length > 0 ? { nextCommands } : {}
|
|
4032
|
-
});
|
|
4246
|
+
if (isBatchRead(positionals, flags))
|
|
4247
|
+
return runContextBatch(command, positionals, flags, context);
|
|
4248
|
+
const { params, warnings: inputWarnings } = parseContextRequest(...singleContextTarget(positional, flags));
|
|
4249
|
+
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
4250
|
+
const item = await readContextItem(command, params, inputWarnings, agentMode ? (data, options) => agentEnvelopeFits(command, data, options) : undefined);
|
|
4251
|
+
context.output.writeData(item.data, item.options);
|
|
4033
4252
|
break;
|
|
4034
4253
|
}
|
|
4035
4254
|
case "audit":
|
|
4036
4255
|
case "trace": {
|
|
4256
|
+
if (isBatchRead(positionals, flags))
|
|
4257
|
+
return runAuditBatch(command, positionals, flags, context);
|
|
4037
4258
|
if (!positional) {
|
|
4038
|
-
throw new CliInputError("<conversation_id|trace_id> is required",
|
|
4259
|
+
throw new CliInputError("<conversation_id|trace_id> is required", AUDIT_USAGE);
|
|
4039
4260
|
}
|
|
4040
4261
|
const args = flagsToArgs(flags, "id", positional);
|
|
4041
4262
|
const params = parseCommandFlags(AuditSchema, args, command, { positionalKey: "id" });
|
|
4042
|
-
const query2 = new URLSearchParams;
|
|
4043
|
-
if (params.kind && params.kind !== "auto")
|
|
4044
|
-
query2.set("kind", params.kind);
|
|
4045
|
-
if (params.include_raw === true)
|
|
4046
|
-
query2.set("include_raw", "1");
|
|
4047
|
-
if (params.include_bodies === true)
|
|
4048
|
-
query2.set("include_bodies", "1");
|
|
4049
|
-
if (params.limit)
|
|
4050
|
-
query2.set("limit", params.limit.toString());
|
|
4051
|
-
if (params.cursor)
|
|
4052
|
-
query2.set("cursor", params.cursor);
|
|
4053
4263
|
const agentMode = context.output.mode === "agent" || context.output.mode === "agent-stream";
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
page = auditOutput(command, params, await fetchAudit(params.id, query2, maxBytes));
|
|
4059
|
-
}
|
|
4060
|
-
if (maxBytes !== undefined && !agentEnvelopeFits(command, page.data, page.options)) {
|
|
4061
|
-
page.options.warnings = [
|
|
4062
|
-
...page.options.warnings ?? [],
|
|
4063
|
-
"This page is a single ingest row larger than the agent output budget, so some of its spans are cut from this output. Rerun this command with --json (no byte limit) or a higher MODA_AGENT_MAX_OUTPUT_BYTES to see the whole row before following next_cursor."
|
|
4064
|
-
];
|
|
4065
|
-
}
|
|
4264
|
+
const page = await readAuditItem(command, params, agentMode ? {
|
|
4265
|
+
maxBytes: Math.max(AUDIT_MIN_PAGE_BYTES, agentMaxOutputBytes() - AUDIT_AGENT_RESERVE_BYTES),
|
|
4266
|
+
fits: (data, options) => agentEnvelopeFits(command, data, options)
|
|
4267
|
+
} : undefined);
|
|
4066
4268
|
context.output.writeData(page.data, page.options);
|
|
4067
4269
|
break;
|
|
4068
4270
|
}
|
|
@@ -4773,7 +4975,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
4773
4975
|
resetApiRequestCountBeforeRun: true,
|
|
4774
4976
|
telemetry: "result",
|
|
4775
4977
|
handler: async (context) => {
|
|
4776
|
-
const { runInit } = await import("./index-
|
|
4978
|
+
const { runInit } = await import("./index-ccdpy9ma.js");
|
|
4777
4979
|
if (context.outputMode === "agent-stream") {
|
|
4778
4980
|
context.output.writeEvent({
|
|
4779
4981
|
event: "started",
|
|
@@ -4814,7 +5016,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
4814
5016
|
resetApiRequestCountBeforeRun: true,
|
|
4815
5017
|
telemetry: "result-and-error",
|
|
4816
5018
|
handler: async (context) => {
|
|
4817
|
-
const { runProvision } = await import("./provision-
|
|
5019
|
+
const { runProvision } = await import("./provision-25bw5rd7.js");
|
|
4818
5020
|
return runProvision(context, {
|
|
4819
5021
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
4820
5022
|
});
|
|
@@ -5270,7 +5472,9 @@ var commandRegistry = createCommandRegistry([
|
|
|
5270
5472
|
"moda context <conversation_id> --msg-index=40 --window=0 # --message-index is an alias",
|
|
5271
5473
|
"moda context <conversation_id> --metadata-only # summary + total_messages, no messages",
|
|
5272
5474
|
"moda context <conversation_id> --all",
|
|
5273
|
-
"moda context <conversation_id> --all --from=500 --max-messages=500"
|
|
5475
|
+
"moda context <conversation_id> --all --from=500 --max-messages=500",
|
|
5476
|
+
"moda context <id>@12 <id2>@3 <id3> --window=2 # batch: up to 25 targets, one envelope; id@N anchors at message N",
|
|
5477
|
+
"moda context --ids-from=ids.txt --window=1 # one target per line (id or id@N); --ids-from=- reads stdin"
|
|
5274
5478
|
],
|
|
5275
5479
|
...dataApiDefaults
|
|
5276
5480
|
}),
|
|
@@ -5284,7 +5488,8 @@ var commandRegistry = createCommandRegistry([
|
|
|
5284
5488
|
"moda audit <conversation_id> --include-raw",
|
|
5285
5489
|
"moda audit <conversation_id> --include-bodies # keep prompt/response bodies (omitted by default; long strings truncated)",
|
|
5286
5490
|
"moda audit <conversation_id> --limit=1000 # ingest rows to read (default 200, max 1000); warns when capped",
|
|
5287
|
-
"moda audit <conversation_id> --cursor=<next_cursor> # next page of a capped audit"
|
|
5491
|
+
"moda audit <conversation_id> --cursor=<next_cursor> # next page of a capped audit",
|
|
5492
|
+
"moda audit <id1> <id2> <id3> # batch: up to 25 ids, one envelope (or --ids-from=-|<file>)"
|
|
5288
5493
|
],
|
|
5289
5494
|
...dataApiDefaults
|
|
5290
5495
|
}),
|
|
@@ -3,17 +3,17 @@ import {
|
|
|
3
3
|
promptsDiscoveredCheck,
|
|
4
4
|
runDoctorCommand,
|
|
5
5
|
runStatusCommand
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
8
|
-
import"./cli-
|
|
6
|
+
} from "./cli-xy6zn80e.js";
|
|
7
|
+
import"./cli-6ca1sz0a.js";
|
|
8
|
+
import"./cli-86q35fpq.js";
|
|
9
9
|
import"./cli-mm48br00.js";
|
|
10
|
-
import"./cli-
|
|
10
|
+
import"./cli-7fc44hhq.js";
|
|
11
11
|
import"./cli-97fnztpy.js";
|
|
12
|
-
import"./cli-
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
15
|
-
import"./cli-
|
|
16
|
-
import"./cli-
|
|
12
|
+
import"./cli-kf3d6y8c.js";
|
|
13
|
+
import"./cli-53mvsfgn.js";
|
|
14
|
+
import"./cli-2ars875d.js";
|
|
15
|
+
import"./cli-atx672xv.js";
|
|
16
|
+
import"./cli-b3cxcxgn.js";
|
|
17
17
|
import"./cli-0v6na3yp.js";
|
|
18
18
|
export {
|
|
19
19
|
runStatusCommand,
|
|
@@ -2,18 +2,18 @@ import {
|
|
|
2
2
|
DEFAULT_POLL_INTERVAL_MS,
|
|
3
3
|
DEFAULT_WAIT_TIMEOUT_MS,
|
|
4
4
|
fetchLatestRun
|
|
5
|
-
} from "./cli-
|
|
5
|
+
} from "./cli-86q35fpq.js";
|
|
6
6
|
import"./cli-mm48br00.js";
|
|
7
|
-
import"./cli-
|
|
7
|
+
import"./cli-7fc44hhq.js";
|
|
8
8
|
import"./cli-97fnztpy.js";
|
|
9
|
-
import"./cli-
|
|
9
|
+
import"./cli-kf3d6y8c.js";
|
|
10
10
|
import {
|
|
11
11
|
assertFlags
|
|
12
|
-
} from "./cli-
|
|
12
|
+
} from "./cli-53mvsfgn.js";
|
|
13
13
|
import {
|
|
14
14
|
callControlAPI
|
|
15
|
-
} from "./cli-
|
|
16
|
-
import"./cli-
|
|
15
|
+
} from "./cli-2ars875d.js";
|
|
16
|
+
import"./cli-atx672xv.js";
|
|
17
17
|
import {
|
|
18
18
|
CliInputError,
|
|
19
19
|
EXIT_DEGRADED,
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
getModaPaths,
|
|
23
23
|
resolveApiTenantId,
|
|
24
24
|
validateConfig
|
|
25
|
-
} from "./cli-
|
|
25
|
+
} from "./cli-b3cxcxgn.js";
|
|
26
26
|
import"./cli-0v6na3yp.js";
|
|
27
27
|
|
|
28
28
|
// src/fix.ts
|
|
@@ -42,13 +42,13 @@ import {
|
|
|
42
42
|
writeHarnessAnalyzeResult,
|
|
43
43
|
writeHarnessArtifacts,
|
|
44
44
|
writeHumanProgress
|
|
45
|
-
} from "./cli-
|
|
45
|
+
} from "./cli-7fc44hhq.js";
|
|
46
46
|
import"./cli-97fnztpy.js";
|
|
47
|
-
import"./cli-
|
|
48
|
-
import"./cli-
|
|
49
|
-
import"./cli-
|
|
50
|
-
import"./cli-
|
|
51
|
-
import"./cli-
|
|
47
|
+
import"./cli-kf3d6y8c.js";
|
|
48
|
+
import"./cli-53mvsfgn.js";
|
|
49
|
+
import"./cli-2ars875d.js";
|
|
50
|
+
import"./cli-atx672xv.js";
|
|
51
|
+
import"./cli-b3cxcxgn.js";
|
|
52
52
|
import"./cli-0v6na3yp.js";
|
|
53
53
|
export {
|
|
54
54
|
writeHumanProgress,
|