@ishlabs/cli 0.14.0 → 0.14.1
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/commands/study-run.js +33 -14
- package/package.json +1 -1
|
@@ -21,6 +21,23 @@ function parseMaxInteractions(value) {
|
|
|
21
21
|
throw new Error(`Invalid --max-interactions value: ${value}`);
|
|
22
22
|
return n;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Default cap the CLI sends when neither `--max-interactions` nor the
|
|
26
|
+
* iteration carries its own value. Picked to match the frontend's
|
|
27
|
+
* conservative interactive launchers and to prevent runaway spend when an
|
|
28
|
+
* iteration runs against a broken or non-responsive surface — without a
|
|
29
|
+
* cap, a stuck tester can rack up hundreds of steps before the SDK gives
|
|
30
|
+
* up.
|
|
31
|
+
*/
|
|
32
|
+
const DEFAULT_MAX_INTERACTIONS = 20;
|
|
33
|
+
function resolveMaxInteractions(optsValue, iterationDetails) {
|
|
34
|
+
if (optsValue)
|
|
35
|
+
return parseMaxInteractions(optsValue);
|
|
36
|
+
if (typeof iterationDetails?.max_interactions === "number") {
|
|
37
|
+
return iterationDetails.max_interactions;
|
|
38
|
+
}
|
|
39
|
+
return DEFAULT_MAX_INTERACTIONS;
|
|
40
|
+
}
|
|
24
41
|
function parseSlowMo(value) {
|
|
25
42
|
const n = parseInt(value, 10);
|
|
26
43
|
if (isNaN(n) || n < 0)
|
|
@@ -162,7 +179,7 @@ export function attachStudyRunCommands(study) {
|
|
|
162
179
|
allFlagDescription: "Use every AI profile matching the filters (workspace-wide if no filters set)",
|
|
163
180
|
})
|
|
164
181
|
.option("--config <id>", "Simulation config ID (required for media unless every profile has one)")
|
|
165
|
-
.option("--max-interactions <n>",
|
|
182
|
+
.option("--max-interactions <n>", `Max interactions per tester (interactive / media only). Precedence: flag > iteration's stored value > CLI default (${DEFAULT_MAX_INTERACTIONS}).`)
|
|
166
183
|
.option("--max-turns <n>", "Max conversation turns per tester (chat studies only)")
|
|
167
184
|
.option("--early-termination", "Allow chat agent to end the conversation early when goals are met (chat studies only)")
|
|
168
185
|
.option("--language <lang>", "Language code (e.g. en, sv)")
|
|
@@ -208,6 +225,10 @@ Examples:
|
|
|
208
225
|
# Override the simulation config (e.g. for a media study):
|
|
209
226
|
$ ish study run --config c-c3c
|
|
210
227
|
|
|
228
|
+
# Cap interactions per tester (default 20 — pass higher to allow deeper
|
|
229
|
+
# exploration, lower to cap spend on a known-broken surface):
|
|
230
|
+
$ ish study run --max-interactions 30
|
|
231
|
+
|
|
211
232
|
# Block until all simulations finish (or timeout):
|
|
212
233
|
$ ish study run --wait
|
|
213
234
|
$ ish study run --wait --timeout 600
|
|
@@ -499,11 +520,13 @@ Examples:
|
|
|
499
520
|
}
|
|
500
521
|
}
|
|
501
522
|
else {
|
|
502
|
-
const stepsForMedia = opts.maxInteractions
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
523
|
+
const stepsForMedia = resolveMaxInteractions(opts.maxInteractions, iteration.details);
|
|
524
|
+
const source = opts.maxInteractions
|
|
525
|
+
? "from --max-interactions"
|
|
526
|
+
: typeof iteration.details?.max_interactions === "number"
|
|
527
|
+
? "from iteration"
|
|
528
|
+
: `CLI default — pass --max-interactions to override`;
|
|
529
|
+
log(` Max steps: ${stepsForMedia} (${source})`);
|
|
507
530
|
if (Number.isFinite(stepsForMedia)) {
|
|
508
531
|
const est = estimateMediaRun({ testerCount, maxInteractions: stepsForMedia });
|
|
509
532
|
log(` Credits (est): ≈ ${est.upper_bound} credit(s) upper bound — ${est.breakdown}`);
|
|
@@ -638,7 +661,7 @@ Examples:
|
|
|
638
661
|
url: detailsView.url,
|
|
639
662
|
screenFormat: detailsView.screenFormat,
|
|
640
663
|
locale: detailsView.locale,
|
|
641
|
-
maxInteractions: opts.maxInteractions
|
|
664
|
+
maxInteractions: resolveMaxInteractions(opts.maxInteractions, iteration.details),
|
|
642
665
|
headed: !!opts.headed,
|
|
643
666
|
slowMo: opts.slowMo ? parseSlowMo(opts.slowMo) : undefined,
|
|
644
667
|
devtools: opts.devtools,
|
|
@@ -758,7 +781,7 @@ Examples:
|
|
|
758
781
|
const simResult = await dispatchAttempt(() => client.post("/simulation/media/start/batch", {
|
|
759
782
|
product_id: resolvedWorkspace,
|
|
760
783
|
simulations: mediaBatchItems,
|
|
761
|
-
|
|
784
|
+
max_interactions: resolveMaxInteractions(opts.maxInteractions, iteration.details),
|
|
762
785
|
}, { timeout: dispatchTimeoutMs }));
|
|
763
786
|
simResults = simResult.results;
|
|
764
787
|
}
|
|
@@ -776,7 +799,7 @@ Examples:
|
|
|
776
799
|
platform: detailsView.platform || "browser",
|
|
777
800
|
...(detailsView.url && { url: detailsView.url }),
|
|
778
801
|
screen_format: detailsView.screenFormat || "desktop",
|
|
779
|
-
|
|
802
|
+
max_interactions: resolveMaxInteractions(opts.maxInteractions, iteration.details),
|
|
780
803
|
}, { timeout: dispatchTimeoutMs }));
|
|
781
804
|
simResults = simResult.results;
|
|
782
805
|
}
|
|
@@ -843,11 +866,7 @@ Examples:
|
|
|
843
866
|
return null;
|
|
844
867
|
return estimateChatSolo({ testerCount, maxTurns: turns });
|
|
845
868
|
}
|
|
846
|
-
const steps = opts.maxInteractions
|
|
847
|
-
? parseMaxInteractions(opts.maxInteractions)
|
|
848
|
-
: (typeof iteration.details?.max_interactions === "number"
|
|
849
|
-
? iteration.details.max_interactions
|
|
850
|
-
: 30);
|
|
869
|
+
const steps = resolveMaxInteractions(opts.maxInteractions, iteration.details);
|
|
851
870
|
if (!Number.isFinite(steps))
|
|
852
871
|
return null;
|
|
853
872
|
return estimateMediaRun({ testerCount, maxInteractions: steps });
|