@getmagical/cli 0.9.1 → 0.9.2
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 +25 -0
- package/dist/index.js +101 -15
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,6 +28,31 @@ mgcl automations run-draft --draft-automation-id ... --agent-id ... --idempotenc
|
|
|
28
28
|
mgcl automations publish --draft-automation-id ... # non-production only: mgcl refuses against the production API, and the API rejects it too
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
## Regression tests
|
|
32
|
+
|
|
33
|
+
Choose how many historical baseline runs to test per pathway:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
mgcl regression run \
|
|
37
|
+
--automation-version <automation-version-id> \
|
|
38
|
+
--agent-version <agent-version-id> \
|
|
39
|
+
--runs-per-path 5 \
|
|
40
|
+
--json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`--runs-per-path` accepts integers from 1 to 20 and defaults to 2. This is an
|
|
44
|
+
upper limit: pathways with fewer eligible historical runs use the available
|
|
45
|
+
runs. Each selected baseline gets 30 replay attempts by default, so five
|
|
46
|
+
baselines produce up to 150 attempts per pathway.
|
|
47
|
+
|
|
48
|
+
The count applies only when creating a regression test. Repeating the command
|
|
49
|
+
for the same automation and agent version pair returns the existing test;
|
|
50
|
+
changing the count does not expand or rerun it.
|
|
51
|
+
|
|
52
|
+
`mgcl pathway-regression preview --runs-per-path <count>` remains a historical
|
|
53
|
+
coverage lookup, accepting 1–50 with a default of 2. It does not configure a
|
|
54
|
+
later regression test.
|
|
55
|
+
|
|
31
56
|
## Typed classification
|
|
32
57
|
|
|
33
58
|
Use `mgcl classify` for focused typed judgments over context you already have.
|
package/dist/index.js
CHANGED
|
@@ -7889,6 +7889,53 @@ function safeJsonParseWithoutLogging(json) {
|
|
|
7889
7889
|
}
|
|
7890
7890
|
}
|
|
7891
7891
|
|
|
7892
|
+
// ../common/dist/src/constants/agent-node-presets.js
|
|
7893
|
+
var AGENT_NODE_PRESET_TYPES = {
|
|
7894
|
+
minimal: "minimal",
|
|
7895
|
+
browser: "browser",
|
|
7896
|
+
desktop: "desktop",
|
|
7897
|
+
voice: "voice"
|
|
7898
|
+
};
|
|
7899
|
+
var agentNodePresetOrder = [
|
|
7900
|
+
AGENT_NODE_PRESET_TYPES.minimal,
|
|
7901
|
+
AGENT_NODE_PRESET_TYPES.browser,
|
|
7902
|
+
AGENT_NODE_PRESET_TYPES.desktop,
|
|
7903
|
+
AGENT_NODE_PRESET_TYPES.voice
|
|
7904
|
+
];
|
|
7905
|
+
var presetToEnvironmentMap = {
|
|
7906
|
+
[AGENT_NODE_PRESET_TYPES.minimal]: ["minimal"],
|
|
7907
|
+
[AGENT_NODE_PRESET_TYPES.browser]: ["browser", "browserCoordinates"],
|
|
7908
|
+
[AGENT_NODE_PRESET_TYPES.desktop]: ["desktop", "desktopApp"],
|
|
7909
|
+
[AGENT_NODE_PRESET_TYPES.voice]: ["voice"]
|
|
7910
|
+
};
|
|
7911
|
+
var environmentToPresetMap = {
|
|
7912
|
+
minimal: AGENT_NODE_PRESET_TYPES.minimal,
|
|
7913
|
+
browser: AGENT_NODE_PRESET_TYPES.browser,
|
|
7914
|
+
browserCoordinates: AGENT_NODE_PRESET_TYPES.browser,
|
|
7915
|
+
desktop: AGENT_NODE_PRESET_TYPES.desktop,
|
|
7916
|
+
desktopApp: AGENT_NODE_PRESET_TYPES.desktop,
|
|
7917
|
+
voice: AGENT_NODE_PRESET_TYPES.voice
|
|
7918
|
+
};
|
|
7919
|
+
|
|
7920
|
+
// ../common/dist/src/constants/agents.js
|
|
7921
|
+
var defaultAgentNamesByType = {
|
|
7922
|
+
trigger: "Trigger Agent",
|
|
7923
|
+
worker: "Worker Agent",
|
|
7924
|
+
specialist: "Specialist Agent",
|
|
7925
|
+
asset: "Library Asset",
|
|
7926
|
+
code: "Code Agent",
|
|
7927
|
+
extract: "Extract Agent",
|
|
7928
|
+
branch: "Decision Agent",
|
|
7929
|
+
api: "API Agent",
|
|
7930
|
+
specialized: "Specialized Agent",
|
|
7931
|
+
[AGENT_NODE_PRESET_TYPES.minimal]: "Orchestrate Agent",
|
|
7932
|
+
[AGENT_NODE_PRESET_TYPES.browser]: "Browser Agent",
|
|
7933
|
+
[AGENT_NODE_PRESET_TYPES.desktop]: "Desktop Agent",
|
|
7934
|
+
[AGENT_NODE_PRESET_TYPES.voice]: "Voice Agent"
|
|
7935
|
+
};
|
|
7936
|
+
var PATHWAY_REGRESSION_RUNS_PER_PATH_DEFAULT = 2;
|
|
7937
|
+
var PATHWAY_REGRESSION_MAX_RUNS_PER_PATH = 20;
|
|
7938
|
+
|
|
7892
7939
|
// ../common/dist/src/constants/automation.js
|
|
7893
7940
|
var AUTOMATION_BRANCH_NAME_MAX_LENGTH = 100;
|
|
7894
7941
|
var AUTOMATION_BRANCH_NAME_MAX_LENGTH_MESSAGE = `Branch name must be ${AUTOMATION_BRANCH_NAME_MAX_LENGTH} characters or fewer.`;
|
|
@@ -13232,7 +13279,7 @@ var magicalBaseModels = [
|
|
|
13232
13279
|
];
|
|
13233
13280
|
var DEFAULT_MODEL = "gemini-2.5-flash";
|
|
13234
13281
|
var modelOptionsSchema = z11.object({
|
|
13235
|
-
reasoningEffort: z11.enum(["low", "medium", "high", "xhigh"]).optional().describe("Reasoning effort level for models that support it. Higher effort may produce better results but takes longer. The xhigh
|
|
13282
|
+
reasoningEffort: z11.enum(["low", "medium", "high", "xhigh", "max"]).optional().describe("Reasoning effort level for models that support it. Higher effort may produce better results but takes longer. The xhigh and max levels are available on supported OpenAI models."),
|
|
13236
13283
|
temperature: z11.number().min(0).max(2).optional().describe("Controls randomness in model output. 0 is deterministic, higher values (up to 2) increase creativity and randomness."),
|
|
13237
13284
|
timeoutMs: z11.number().int().min(1).optional().describe("Maximum time to wait for an LLM provider request before failing through the normal result path.")
|
|
13238
13285
|
});
|
|
@@ -14066,6 +14113,15 @@ var baseToolDeclarations = {
|
|
|
14066
14113
|
...reportStopDataSchema.shape
|
|
14067
14114
|
})
|
|
14068
14115
|
},
|
|
14116
|
+
handOff: {
|
|
14117
|
+
id: "handOff",
|
|
14118
|
+
description: "Hand off this work item to another root agent of the same automation and end this run.",
|
|
14119
|
+
parameters: z16.object({
|
|
14120
|
+
[COMMON_PARAMETERS_KEY]: DEFAULT_COMMON_PARAMETERS,
|
|
14121
|
+
agentId: z16.string(),
|
|
14122
|
+
input: z16.record(z16.string(), z16.unknown()).optional()
|
|
14123
|
+
})
|
|
14124
|
+
},
|
|
14069
14125
|
terminateRun: {
|
|
14070
14126
|
id: "terminateRun",
|
|
14071
14127
|
description: "End the whole run early using a configured termination code. This stops every agent in the run, not just the current one, and marks the run as early-terminated.",
|
|
@@ -15256,6 +15312,7 @@ var baseAgentConfigFieldsSchema = z25.object({
|
|
|
15256
15312
|
taskQueue: z25.string().optional().describe("Temporal task queue name for this agent. If specified, queued child agents run on this queue instead of the parent queue."),
|
|
15257
15313
|
waitUponQueueing: z25.boolean().optional().default(false).describe("If true, wait for queued child agents to complete before proceeding."),
|
|
15258
15314
|
queueableAgentIds: z25.array(brandedStringValidator("agentId")).optional().default(() => []).describe("List of agent IDs that this agent can queue using the queueAgents tool. Enables the agent to run a new automation with a different agent as the starting point."),
|
|
15315
|
+
handOffAgentIds: z25.array(brandedStringValidator("agentId")).optional().describe("Other root agents in this automation that can receive this agent\u2019s work item through handOff. Requires root agent handoff to be enabled; targets always use the latest version."),
|
|
15259
15316
|
callableAgentIds: z25.array(brandedStringValidator("agentId")).optional().describe("List of external root agent IDs that this agent can call using the callSpecializedAgent tool. Same-automation callable agents continue to be configured by graph connections."),
|
|
15260
15317
|
queuedAgentVariables: z25.record(brandedStringValidator("agentId"), z25.record(z25.string(), z25.unknown())).optional().describe("Static automation variable values to pass when this agent queues another automation by target agent ID."),
|
|
15261
15318
|
checkpoint: z25.object({
|
|
@@ -15266,7 +15323,7 @@ var baseAgentConfigFieldsSchema = z25.object({
|
|
|
15266
15323
|
additionalSystemPrompt: z25.string().optional().describe("Additional instructions appended to the system prompt for this agent. Combined with automation-level additionalSystemPrompt."),
|
|
15267
15324
|
// Backlinking metadata for imported agents
|
|
15268
15325
|
importedFrom: z25.object({
|
|
15269
|
-
automationId: brandedStringValidator("
|
|
15326
|
+
automationId: brandedStringValidator("automationId").describe("ID of the source automation from which this agent was imported."),
|
|
15270
15327
|
originalAgentId: brandedStringValidator("agentId").describe("Original agent ID in the source automation.")
|
|
15271
15328
|
}).optional().describe("Metadata for agents imported from another automation. Used for traceability and updates."),
|
|
15272
15329
|
ignoreUnstableSessionState: z25.boolean().optional().describe("When true, skips screenshot consistency checks before tool execution. Overrides the automation-level ignoreUnstableSessionState setting."),
|
|
@@ -15340,10 +15397,11 @@ var OutcomePayloadSchema = z25.object({
|
|
|
15340
15397
|
input: z25.record(z25.string(), z25.unknown()).describe("Input data for the outcome. Maps parameter keys to values."),
|
|
15341
15398
|
preview: z25.string().describe("Rendered text representation of the outcome.")
|
|
15342
15399
|
});
|
|
15400
|
+
var decisionIncludeScreenshotDescription = "Requires screenshot context from the calling agent. Every way this Decision can be invoked must provide one.";
|
|
15343
15401
|
var branchAgentConfigSchema = baseAgentConfigFieldsSchema.safeExtend({
|
|
15344
15402
|
type: z25.literal("branch").describe("Decision agent type - makes decisions to route to different agents."),
|
|
15345
15403
|
model: agentModelConfigSchema.describe("LLM model configuration for this decision agent."),
|
|
15346
|
-
includeScreenshot: z25.boolean().optional().describe(
|
|
15404
|
+
includeScreenshot: z25.boolean().optional().describe(decisionIncludeScreenshotDescription),
|
|
15347
15405
|
conditionsAndOutcomes: z25.object({
|
|
15348
15406
|
if: z25.array(z25.object({
|
|
15349
15407
|
caseName: z25.string().describe("Name of the condition case."),
|
|
@@ -15356,7 +15414,7 @@ var branchAgentConfigSchema = baseAgentConfigFieldsSchema.safeExtend({
|
|
|
15356
15414
|
var draftBranchAgentConfigSchema = baseAgentConfigFieldsSchema.safeExtend({
|
|
15357
15415
|
type: z25.literal("branch").describe("Decision agent draft configuration. Allows incomplete conditions and outcomes while the agent is still being authored."),
|
|
15358
15416
|
model: agentModelConfigSchema.describe("LLM model configuration for this decision agent."),
|
|
15359
|
-
includeScreenshot: z25.boolean().optional().describe(
|
|
15417
|
+
includeScreenshot: z25.boolean().optional().describe(decisionIncludeScreenshotDescription),
|
|
15360
15418
|
conditionsAndOutcomes: z25.object({
|
|
15361
15419
|
if: z25.array(z25.object({
|
|
15362
15420
|
caseName: z25.string().describe("Name of the condition case."),
|
|
@@ -15589,6 +15647,13 @@ var automationRunConfigBaseSchema = z27.object({
|
|
|
15589
15647
|
captureActions: z27.boolean().default(false).describe("When true, attach an action recording while a draft run is paused in takeover mode."),
|
|
15590
15648
|
runDraftQueuedAgents: z27.boolean().optional().describe("Draft-run-only option. When false, queue-agent actions in the draft run report success without starting downstream queued draft child runs. Omit or true preserves queueing."),
|
|
15591
15649
|
allowPointOfNoReturnOverride: z27.boolean().optional().describe("Internal rerun authorization. When true, the rerun and its queued descendants may proceed past a point-of-no-return crossing owned by an earlier run."),
|
|
15650
|
+
rootAgentHandoffEnabled: z27.literal(true).optional().describe("Infrastructure-owned capability captured when a work-item-backed run is created. Only these runs can hand off to another root agent."),
|
|
15651
|
+
rootAgentHandoff: z27.object({
|
|
15652
|
+
automationBranchId: z27.uuid().optional().describe("Draft branch captured at run creation. Draft handoffs resolve the current head of this branch."),
|
|
15653
|
+
sourceAutomationRunId: z27.uuid().optional().describe("Predecessor run for an admitted handoff. This run executes the latest version resolved at admission."),
|
|
15654
|
+
successorAutomationRunId: z27.uuid().optional().describe("Accepted handoff receipt. The source can no longer mutate the shared Store once this is recorded."),
|
|
15655
|
+
stopRequestedAt: z27.iso.datetime().optional().describe("Time a stop request was recorded, preventing subsequent handoff admission.")
|
|
15656
|
+
}).optional().describe("Infrastructure-owned durable handoff receipt and stop-intent fence. Updated only while holding the source run lock."),
|
|
15592
15657
|
pointOfNoReturnGateEnabled: z27.literal(true).optional().describe("Infrastructure-owned rollout marker. PONR is enforced only for run trees created after the gate rollout."),
|
|
15593
15658
|
sla: automationRunSlaSchema.optional(),
|
|
15594
15659
|
networkTrafficCapture: networkTrafficCaptureSchema.optional(),
|
|
@@ -15622,7 +15687,9 @@ var automationRunStartConfigSchema = automationRunConfigBaseSchema.omit({
|
|
|
15622
15687
|
queueResourcePools: true,
|
|
15623
15688
|
resolvedRunSettings: true,
|
|
15624
15689
|
resolvedRunSettingsSource: true,
|
|
15625
|
-
pointOfNoReturnGateEnabled: true
|
|
15690
|
+
pointOfNoReturnGateEnabled: true,
|
|
15691
|
+
rootAgentHandoffEnabled: true,
|
|
15692
|
+
rootAgentHandoff: true
|
|
15626
15693
|
}).extend({
|
|
15627
15694
|
networkTrafficCapture: networkTrafficCaptureSchema.nullable().optional().describe("Network traffic capture preference for this run. Omit to apply the implicit recording policy, pass null to explicitly disable capture, or pass a record/replay config to explicitly enable capture.")
|
|
15628
15695
|
});
|
|
@@ -20700,7 +20767,7 @@ ${evalRunExportSelection}
|
|
|
20700
20767
|
];
|
|
20701
20768
|
|
|
20702
20769
|
// src/program.ts
|
|
20703
|
-
import { Command as Command6, InvalidArgumentError as
|
|
20770
|
+
import { Command as Command6, InvalidArgumentError as InvalidArgumentError3, Option as Option7 } from "commander";
|
|
20704
20771
|
|
|
20705
20772
|
// src/api.ts
|
|
20706
20773
|
import { randomUUID } from "node:crypto";
|
|
@@ -22145,8 +22212,12 @@ function createMagicalApiClient({
|
|
|
22145
22212
|
agentVersionId,
|
|
22146
22213
|
automationVersionId,
|
|
22147
22214
|
impersonatedOrganizationId,
|
|
22148
|
-
organizationId
|
|
22215
|
+
organizationId,
|
|
22216
|
+
runsPerPath
|
|
22149
22217
|
}) {
|
|
22218
|
+
const query = new URLSearchParams(
|
|
22219
|
+
runsPerPath === void 0 ? {} : { runsPerPath: String(runsPerPath) }
|
|
22220
|
+
);
|
|
22150
22221
|
const parsedResponse = regressionTestKickoffResponseSchema.safeParse(
|
|
22151
22222
|
await fetchJson({
|
|
22152
22223
|
accessToken,
|
|
@@ -22155,7 +22226,7 @@ function createMagicalApiClient({
|
|
|
22155
22226
|
...organizationId ? { organizationId } : {},
|
|
22156
22227
|
path: `/pathway-regression/tests/automation-versions/${encodeURIComponent(
|
|
22157
22228
|
automationVersionId
|
|
22158
|
-
)}/agent-versions/${encodeURIComponent(agentVersionId)}/run`,
|
|
22229
|
+
)}/agent-versions/${encodeURIComponent(agentVersionId)}/run${query.size > 0 ? `?${query.toString()}` : ""}`,
|
|
22159
22230
|
init: {
|
|
22160
22231
|
method: "POST"
|
|
22161
22232
|
}
|
|
@@ -27943,14 +28014,14 @@ async function prepareFileUpload(inputPath, workingDirectory) {
|
|
|
27943
28014
|
);
|
|
27944
28015
|
}
|
|
27945
28016
|
const checksum = await (async () => {
|
|
27946
|
-
let value = 0;
|
|
28017
|
+
let value = void 0;
|
|
27947
28018
|
for await (const chunk of createReadStream2(filePath)) {
|
|
27948
28019
|
if (!(chunk instanceof Uint8Array)) {
|
|
27949
28020
|
throw new CliError("Upload file stream returned invalid bytes.");
|
|
27950
28021
|
}
|
|
27951
28022
|
value = updateS3Crc32Checksum(chunk, value);
|
|
27952
28023
|
}
|
|
27953
|
-
return value;
|
|
28024
|
+
return value ?? updateS3Crc32Checksum(new Uint8Array());
|
|
27954
28025
|
})().catch((error) => {
|
|
27955
28026
|
throw new CliError(`Failed to checksum upload file "${filePath}".`, {
|
|
27956
28027
|
cause: error
|
|
@@ -28977,7 +29048,7 @@ var SESSION_ONLY_API_KEY_MANAGEMENT_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
28977
29048
|
|
|
28978
29049
|
// src/regression-commands.ts
|
|
28979
29050
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
28980
|
-
import { Command as Command4, Option as Option4 } from "commander";
|
|
29051
|
+
import { Command as Command4, InvalidArgumentError as InvalidArgumentError2, Option as Option4 } from "commander";
|
|
28981
29052
|
var REGRESSION_TEST_TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
28982
29053
|
"matched",
|
|
28983
29054
|
"deviated",
|
|
@@ -29104,7 +29175,8 @@ async function handleRegressionRunCommand({
|
|
|
29104
29175
|
input: {
|
|
29105
29176
|
...authParams,
|
|
29106
29177
|
agentVersionId: options.agentVersion,
|
|
29107
|
-
automationVersionId: options.automationVersion
|
|
29178
|
+
automationVersionId: options.automationVersion,
|
|
29179
|
+
...options.runsPerPath === void 0 ? {} : { runsPerPath: options.runsPerPath }
|
|
29108
29180
|
},
|
|
29109
29181
|
startRegressionTest: startAgentVersionRegressionTest
|
|
29110
29182
|
});
|
|
@@ -29191,6 +29263,7 @@ function addRegressionCommands({
|
|
|
29191
29263
|
`
|
|
29192
29264
|
${formatExamples("Examples", [
|
|
29193
29265
|
"mgcl regression run --automation-version <id> --agent-version <id>",
|
|
29266
|
+
"mgcl regression run --automation-version <id> --agent-version <id> --runs-per-path 5",
|
|
29194
29267
|
"mgcl regression show <testId>",
|
|
29195
29268
|
"mgcl regression show <testId> --pathway <pathwayId>"
|
|
29196
29269
|
])}`
|
|
@@ -29209,6 +29282,19 @@ ${formatExamples("Examples", [
|
|
|
29209
29282
|
).helpGroup("Regression options:").makeOptionMandatory(true)
|
|
29210
29283
|
).addOption(
|
|
29211
29284
|
new Option4("--agent-version <id>", "Agent version to test.").helpGroup("Regression options:").makeOptionMandatory(true)
|
|
29285
|
+
).addOption(
|
|
29286
|
+
new Option4(
|
|
29287
|
+
"--runs-per-path <count>",
|
|
29288
|
+
`Maximum historical baseline runs per pathway (1\u2013${PATHWAY_REGRESSION_MAX_RUNS_PER_PATH}; default: ${PATHWAY_REGRESSION_RUNS_PER_PATH_DEFAULT}). Applies only to new tests; existing tests are reused unchanged.`
|
|
29289
|
+
).helpGroup("Regression options:").argParser((rawValue) => {
|
|
29290
|
+
const count = Number(rawValue);
|
|
29291
|
+
if (!Number.isInteger(count) || count < 1 || count > PATHWAY_REGRESSION_MAX_RUNS_PER_PATH) {
|
|
29292
|
+
throw new InvalidArgumentError2(
|
|
29293
|
+
`Expected an integer from 1 to ${PATHWAY_REGRESSION_MAX_RUNS_PER_PATH}.`
|
|
29294
|
+
);
|
|
29295
|
+
}
|
|
29296
|
+
return count;
|
|
29297
|
+
})
|
|
29212
29298
|
).action(async function() {
|
|
29213
29299
|
await handleRegressionRunCommand({
|
|
29214
29300
|
dependencies,
|
|
@@ -31053,7 +31139,7 @@ function parseCommandOptionValue(rawValue, optionSpec) {
|
|
|
31053
31139
|
case "number": {
|
|
31054
31140
|
const parsedNumber = Number(rawValue);
|
|
31055
31141
|
if (Number.isNaN(parsedNumber)) {
|
|
31056
|
-
throw new
|
|
31142
|
+
throw new InvalidArgumentError3(
|
|
31057
31143
|
`Expected a number for --${optionSpec.flagName}.`
|
|
31058
31144
|
);
|
|
31059
31145
|
}
|
|
@@ -31065,7 +31151,7 @@ function parseCommandOptionValue(rawValue, optionSpec) {
|
|
|
31065
31151
|
case "json": {
|
|
31066
31152
|
const parsedJson = safeJsonParse(rawValue);
|
|
31067
31153
|
if (isErr(parsedJson)) {
|
|
31068
|
-
throw new
|
|
31154
|
+
throw new InvalidArgumentError3(
|
|
31069
31155
|
`Expected valid JSON for --${optionSpec.flagName}.`
|
|
31070
31156
|
);
|
|
31071
31157
|
}
|
|
@@ -31098,7 +31184,7 @@ function createCliCommanderOption(optionSpec, helpGroup) {
|
|
|
31098
31184
|
function parsePositiveIntegerOption(rawValue) {
|
|
31099
31185
|
const parsedValue = Number(rawValue);
|
|
31100
31186
|
if (!Number.isInteger(parsedValue) || parsedValue < 1) {
|
|
31101
|
-
throw new
|
|
31187
|
+
throw new InvalidArgumentError3("Expected a positive integer.");
|
|
31102
31188
|
}
|
|
31103
31189
|
return parsedValue;
|
|
31104
31190
|
}
|