lua-cli 3.34.0 → 3.36.0
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/api-exports.d.ts +298 -20
- package/dist/api-exports.js +438 -198
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +1334 -234
- package/dist/index.js.map +1 -1
- package/dist/voice/test/index.d.ts +18 -18
- package/dist/workflow-builder.d.ts +47 -0
- package/dist/workflow-builder.js +370 -195
- package/dist/workflow-builder.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/api/LuaWorkflow.md +1 -1
- package/docs/api/Workflows.md +1 -1
- package/docs/workflows/migrating-runs.md +1 -1
- package/docs/workflows/recovery.md +4 -4
- package/docs/workflows/testing-offline.md +1 -1
- package/package.json +7 -6
- package/scripts/compat-matrix-previous-cli.mjs +266 -0
- package/template/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1182,10 +1182,113 @@ function isDesktopFileCommandName(value3) {
|
|
|
1182
1182
|
function isDesktopFileSessionId(value3) {
|
|
1183
1183
|
return typeof value3 === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value3);
|
|
1184
1184
|
}
|
|
1185
|
+
function workflowRetryMaxAttemptsMessage(got) {
|
|
1186
|
+
const tail = got === void 0 ? "" : ` (got ${JSON.stringify(got)})`;
|
|
1187
|
+
return `\`retry.maxAttempts\` must be an integer ${WORKFLOW_RETRY_MIN_ATTEMPTS}..${WORKFLOW_RETRY_MAX_ATTEMPTS}${tail}`;
|
|
1188
|
+
}
|
|
1189
|
+
function isWithinWorkflowRetryAttempts(value3) {
|
|
1190
|
+
return typeof value3 === "number" && Number.isInteger(value3) && value3 >= WORKFLOW_RETRY_MIN_ATTEMPTS && value3 <= WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
1191
|
+
}
|
|
1192
|
+
function workflowRetryUnknownMembersMessage(keys) {
|
|
1193
|
+
const named = keys.map((k) => {
|
|
1194
|
+
const engine = WORKFLOW_RETRY_ENGINE_KEYS.includes(k);
|
|
1195
|
+
return `\`${k}\`${engine ? " (engine-owned \u2014 stamped by resetAttempts, never authored)" : ""}`;
|
|
1196
|
+
});
|
|
1197
|
+
return `\`retry\` has no member ${named.join(", ")}; members: ${WORKFLOW_RETRY_POLICY_KEYS.join(", ")}`;
|
|
1198
|
+
}
|
|
1199
|
+
function unknownWorkflowRetryMembers(retry) {
|
|
1200
|
+
if (!retry || typeof retry !== "object" || Array.isArray(retry)) return [];
|
|
1201
|
+
return Object.keys(retry).filter((k) => !WORKFLOW_RETRY_POLICY_KEYS.includes(k));
|
|
1202
|
+
}
|
|
1203
|
+
function authoredRetryPolicy(retry) {
|
|
1204
|
+
if (!retry || typeof retry !== "object" || Array.isArray(retry)) return void 0;
|
|
1205
|
+
const src = retry;
|
|
1206
|
+
const out = {};
|
|
1207
|
+
for (const k of WORKFLOW_RETRY_POLICY_KEYS) if (src[k] !== void 0) out[k] = src[k];
|
|
1208
|
+
return Object.keys(out).length ? out : void 0;
|
|
1209
|
+
}
|
|
1210
|
+
function retryBudgetBaseAttempt(row2) {
|
|
1211
|
+
const base = row2.retry?.budgetBaseAttempt;
|
|
1212
|
+
return typeof base === "number" && Number.isSafeInteger(base) && base > 0 ? base : 0;
|
|
1213
|
+
}
|
|
1214
|
+
function retryBudgetAttempt(row2) {
|
|
1215
|
+
return Math.max(0, row2.attempt - retryBudgetBaseAttempt(row2));
|
|
1216
|
+
}
|
|
1217
|
+
function retryBudgetMaxAttempts(row2) {
|
|
1218
|
+
const max = row2.retry?.maxAttempts;
|
|
1219
|
+
return typeof max === "number" && Number.isFinite(max) && max >= 1 ? max : 1;
|
|
1220
|
+
}
|
|
1221
|
+
function retryBudgetRemaining(row2) {
|
|
1222
|
+
return retryBudgetAttempt(row2) < retryBudgetMaxAttempts(row2);
|
|
1223
|
+
}
|
|
1224
|
+
function retriesRemaining(row2) {
|
|
1225
|
+
return Math.max(0, retryBudgetMaxAttempts(row2) - retryBudgetAttempt(row2));
|
|
1226
|
+
}
|
|
1227
|
+
function workflowModelCostComparison(estimate, onAgentModel, agentModel) {
|
|
1228
|
+
if (agentModel === void 0 || onAgentModel === void 0 || !(onAgentModel > 0)) return void 0;
|
|
1229
|
+
const ratio = Math.round(estimate / onAgentModel * 10) / 10;
|
|
1230
|
+
return `\u2248 ${ratio}\xD7 the cost of running every step on ${agentModel}`;
|
|
1231
|
+
}
|
|
1232
|
+
function modelClassRank(modelClass) {
|
|
1233
|
+
return WORKFLOW_MODEL_CLASSES.indexOf(modelClass);
|
|
1234
|
+
}
|
|
1235
|
+
function modelClassesAtOrBelow(maxClass) {
|
|
1236
|
+
const ceiling = modelClassRank(maxClass);
|
|
1237
|
+
return WORKFLOW_MODEL_CLASSES.filter((c) => modelClassRank(c) <= ceiling);
|
|
1238
|
+
}
|
|
1239
|
+
function workflowAutonomyMaxRunsPerHourCeiling(env) {
|
|
1240
|
+
const raw = Number((env ?? process.env)[WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV]);
|
|
1241
|
+
return Number.isFinite(raw) && raw > 0 ? raw : WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING;
|
|
1242
|
+
}
|
|
1243
|
+
function isWithinWorkflowAutonomyRange(value3, ceiling) {
|
|
1244
|
+
return typeof value3 === "number" && Number.isInteger(value3) && value3 >= WORKFLOW_AUTONOMY_MIN_VALUE && value3 <= ceiling;
|
|
1245
|
+
}
|
|
1246
|
+
function workflowAutonomyRangeMessage(key, ceiling) {
|
|
1247
|
+
return `\`${key}\` must be an integer ${WORKFLOW_AUTONOMY_MIN_VALUE}..${ceiling}`;
|
|
1248
|
+
}
|
|
1249
|
+
function isWithinWorkflowJobRange(member, value3) {
|
|
1250
|
+
const { min, max } = WORKFLOW_JOB_RANGES[member];
|
|
1251
|
+
return typeof value3 === "number" && Number.isInteger(value3) && value3 >= min && value3 <= max;
|
|
1252
|
+
}
|
|
1253
|
+
function workflowJobRangeMessage(member) {
|
|
1254
|
+
const { min, max } = WORKFLOW_JOB_RANGES[member];
|
|
1255
|
+
return `\`${member}\` must be an integer ${min}..${max}`;
|
|
1256
|
+
}
|
|
1257
|
+
function isWorkflowSingleStepType(type) {
|
|
1258
|
+
return typeof type === "string" && WORKFLOW_SINGLE_STEP_TYPES.includes(type);
|
|
1259
|
+
}
|
|
1260
|
+
function isWorkflowHitlEntryType(type) {
|
|
1261
|
+
return typeof type === "string" && WORKFLOW_HITL_ENTRY_TYPES.includes(type);
|
|
1262
|
+
}
|
|
1263
|
+
function isWorkflowArmEntryType(type) {
|
|
1264
|
+
return typeof type === "string" && WORKFLOW_ARM_ENTRY_TYPES.includes(type);
|
|
1265
|
+
}
|
|
1266
|
+
function workflowContainerRunsHitlArm(container) {
|
|
1267
|
+
return typeof container === "string" && WORKFLOW_HITL_ARM_CONTAINERS.includes(container);
|
|
1268
|
+
}
|
|
1269
|
+
function workflowHitlArmUnsupportedMessage(type, id, container) {
|
|
1270
|
+
const legal = WORKFLOW_HITL_ARM_CONTAINERS.map((c) => `\`${c}\``).join(" / ");
|
|
1271
|
+
return `the engine does not run \`${type}\` inside a \`${container}\` yet (node "${id}") \u2014 place it at the top level, as a ${legal} arm, or inside a child \`workflow\``;
|
|
1272
|
+
}
|
|
1273
|
+
function workflowHitlArmShapeMessage(type, id, shape) {
|
|
1274
|
+
return shape === "mapped-arm" ? `\`${type}\` arm "${id}" takes the previous output as its payload \u2014 it cannot head a [mapping, step] chain; map before the container instead` : `a chunked foreach hands each child a slice of items, not one \u2014 \`${type}\` body "${id}" takes one item; drop \`chunk\``;
|
|
1275
|
+
}
|
|
1185
1276
|
function isModelIdSentinel(input) {
|
|
1186
1277
|
const lower = (input ?? "").trim().toLowerCase();
|
|
1187
1278
|
return lower === "auto" || lower.startsWith("auto/");
|
|
1188
1279
|
}
|
|
1280
|
+
function isModelClassRef(input) {
|
|
1281
|
+
return modelClassOf(input) !== void 0;
|
|
1282
|
+
}
|
|
1283
|
+
function modelClassOf(input) {
|
|
1284
|
+
const lower = (input ?? "").trim().toLowerCase();
|
|
1285
|
+
if (!lower.startsWith(MODEL_CLASS_REF_PREFIX)) return void 0;
|
|
1286
|
+
const c = lower.slice(MODEL_CLASS_REF_PREFIX.length);
|
|
1287
|
+
return WORKFLOW_MODEL_CLASSES.includes(c) ? c : void 0;
|
|
1288
|
+
}
|
|
1289
|
+
function modelClassRef(modelClass) {
|
|
1290
|
+
return `${MODEL_CLASS_REF_PREFIX}${modelClass}`;
|
|
1291
|
+
}
|
|
1189
1292
|
function normalizeModelId(input, registry) {
|
|
1190
1293
|
const requested = typeof input === "string" ? input.trim() : "";
|
|
1191
1294
|
if (!requested) return {
|
|
@@ -1200,6 +1303,11 @@ function normalizeModelId(input, registry) {
|
|
|
1200
1303
|
id: lower,
|
|
1201
1304
|
form: "sentinel"
|
|
1202
1305
|
};
|
|
1306
|
+
if (modelClassOf(lower) !== void 0) return {
|
|
1307
|
+
ok: true,
|
|
1308
|
+
id: lower,
|
|
1309
|
+
form: "class"
|
|
1310
|
+
};
|
|
1203
1311
|
const slash = requested.indexOf("/");
|
|
1204
1312
|
const malformed = slash === 0;
|
|
1205
1313
|
const provider = slash > 0 ? lower.slice(0, slash) : void 0;
|
|
@@ -1260,6 +1368,9 @@ function modelUnresolvedMessage(r) {
|
|
|
1260
1368
|
}
|
|
1261
1369
|
return r.candidates.length ? `model "${r.requested}" does not resolve to an approved model \u2014 accepted forms: ${r.candidates.join(", ")}` : `model "${r.requested}" does not resolve to an approved model \u2014 accepted forms are the registry's provider-prefixed ids (provider/model) or a bare id that names exactly one of them`;
|
|
1262
1370
|
}
|
|
1371
|
+
function modelClassUnresolvedMessage(ref) {
|
|
1372
|
+
return `model "${ref.trim()}" is a model-class request that was not resolved before dispatch \u2014 a class is resolved to a concrete approved model by the class map at dispatch, and is never sent to a provider as written; this step refuses rather than run on a substituted model`;
|
|
1373
|
+
}
|
|
1263
1374
|
function providerModelId(code) {
|
|
1264
1375
|
const requested = typeof code === "string" ? code.trim() : "";
|
|
1265
1376
|
if (!requested || isModelIdSentinel(requested)) return requested;
|
|
@@ -1662,75 +1773,6 @@ function scheduledTimeKey(scheduledTime) {
|
|
|
1662
1773
|
function scheduledWorkflowRunIdForTime(jobId, scheduledTime) {
|
|
1663
1774
|
return scheduledWorkflowRunId(jobId, scheduledTime);
|
|
1664
1775
|
}
|
|
1665
|
-
function workflowRetryMaxAttemptsMessage(got) {
|
|
1666
|
-
const tail = got === void 0 ? "" : ` (got ${JSON.stringify(got)})`;
|
|
1667
|
-
return `\`retry.maxAttempts\` must be an integer ${WORKFLOW_RETRY_MIN_ATTEMPTS}..${WORKFLOW_RETRY_MAX_ATTEMPTS}${tail}`;
|
|
1668
|
-
}
|
|
1669
|
-
function isWithinWorkflowRetryAttempts(value3) {
|
|
1670
|
-
return typeof value3 === "number" && Number.isInteger(value3) && value3 >= WORKFLOW_RETRY_MIN_ATTEMPTS && value3 <= WORKFLOW_RETRY_MAX_ATTEMPTS;
|
|
1671
|
-
}
|
|
1672
|
-
function workflowRetryUnknownMembersMessage(keys) {
|
|
1673
|
-
const named = keys.map((k) => {
|
|
1674
|
-
const engine = WORKFLOW_RETRY_ENGINE_KEYS.includes(k);
|
|
1675
|
-
return `\`${k}\`${engine ? " (engine-owned \u2014 stamped by resetAttempts, never authored)" : ""}`;
|
|
1676
|
-
});
|
|
1677
|
-
return `\`retry\` has no member ${named.join(", ")}; members: ${WORKFLOW_RETRY_POLICY_KEYS.join(", ")}`;
|
|
1678
|
-
}
|
|
1679
|
-
function unknownWorkflowRetryMembers(retry) {
|
|
1680
|
-
if (!retry || typeof retry !== "object" || Array.isArray(retry)) return [];
|
|
1681
|
-
return Object.keys(retry).filter((k) => !WORKFLOW_RETRY_POLICY_KEYS.includes(k));
|
|
1682
|
-
}
|
|
1683
|
-
function authoredRetryPolicy(retry) {
|
|
1684
|
-
if (!retry || typeof retry !== "object" || Array.isArray(retry)) return void 0;
|
|
1685
|
-
const src = retry;
|
|
1686
|
-
const out = {};
|
|
1687
|
-
for (const k of WORKFLOW_RETRY_POLICY_KEYS) if (src[k] !== void 0) out[k] = src[k];
|
|
1688
|
-
return Object.keys(out).length ? out : void 0;
|
|
1689
|
-
}
|
|
1690
|
-
function retryBudgetBaseAttempt(row2) {
|
|
1691
|
-
const base = row2.retry?.budgetBaseAttempt;
|
|
1692
|
-
return typeof base === "number" && Number.isSafeInteger(base) && base > 0 ? base : 0;
|
|
1693
|
-
}
|
|
1694
|
-
function retryBudgetAttempt(row2) {
|
|
1695
|
-
return Math.max(0, row2.attempt - retryBudgetBaseAttempt(row2));
|
|
1696
|
-
}
|
|
1697
|
-
function retryBudgetMaxAttempts(row2) {
|
|
1698
|
-
const max = row2.retry?.maxAttempts;
|
|
1699
|
-
return typeof max === "number" && Number.isFinite(max) && max >= 1 ? max : 1;
|
|
1700
|
-
}
|
|
1701
|
-
function retryBudgetRemaining(row2) {
|
|
1702
|
-
return retryBudgetAttempt(row2) < retryBudgetMaxAttempts(row2);
|
|
1703
|
-
}
|
|
1704
|
-
function retriesRemaining(row2) {
|
|
1705
|
-
return Math.max(0, retryBudgetMaxAttempts(row2) - retryBudgetAttempt(row2));
|
|
1706
|
-
}
|
|
1707
|
-
function isWithinWorkflowJobRange(member, value3) {
|
|
1708
|
-
const { min, max } = WORKFLOW_JOB_RANGES[member];
|
|
1709
|
-
return typeof value3 === "number" && Number.isInteger(value3) && value3 >= min && value3 <= max;
|
|
1710
|
-
}
|
|
1711
|
-
function workflowJobRangeMessage(member) {
|
|
1712
|
-
const { min, max } = WORKFLOW_JOB_RANGES[member];
|
|
1713
|
-
return `\`${member}\` must be an integer ${min}..${max}`;
|
|
1714
|
-
}
|
|
1715
|
-
function isWorkflowSingleStepType(type) {
|
|
1716
|
-
return typeof type === "string" && WORKFLOW_SINGLE_STEP_TYPES.includes(type);
|
|
1717
|
-
}
|
|
1718
|
-
function isWorkflowHitlEntryType(type) {
|
|
1719
|
-
return typeof type === "string" && WORKFLOW_HITL_ENTRY_TYPES.includes(type);
|
|
1720
|
-
}
|
|
1721
|
-
function isWorkflowArmEntryType(type) {
|
|
1722
|
-
return typeof type === "string" && WORKFLOW_ARM_ENTRY_TYPES.includes(type);
|
|
1723
|
-
}
|
|
1724
|
-
function workflowContainerRunsHitlArm(container) {
|
|
1725
|
-
return typeof container === "string" && WORKFLOW_HITL_ARM_CONTAINERS.includes(container);
|
|
1726
|
-
}
|
|
1727
|
-
function workflowHitlArmUnsupportedMessage(type, id, container) {
|
|
1728
|
-
const legal = WORKFLOW_HITL_ARM_CONTAINERS.map((c) => `\`${c}\``).join(" / ");
|
|
1729
|
-
return `the engine does not run \`${type}\` inside a \`${container}\` yet (node "${id}") \u2014 place it at the top level, as a ${legal} arm, or inside a child \`workflow\``;
|
|
1730
|
-
}
|
|
1731
|
-
function workflowHitlArmShapeMessage(type, id, shape) {
|
|
1732
|
-
return shape === "mapped-arm" ? `\`${type}\` arm "${id}" takes the previous output as its payload \u2014 it cannot head a [mapping, step] chain; map before the container instead` : `a chunked foreach hands each child a slice of items, not one \u2014 \`${type}\` body "${id}" takes one item; drop \`chunk\``;
|
|
1733
|
-
}
|
|
1734
1776
|
function workflowGoalJudgeKind(judge) {
|
|
1735
1777
|
return judge && typeof judge === "object" && judge.predicate !== void 0 ? "predicate" : "agent";
|
|
1736
1778
|
}
|
|
@@ -2035,7 +2077,7 @@ function effectiveAgentFeatures(base, override, rule) {
|
|
|
2035
2077
|
if (rule === "wholesale") return override || base || void 0;
|
|
2036
2078
|
return effectiveAgentFeatureRows(base, override).rows;
|
|
2037
2079
|
}
|
|
2038
|
-
var __defProp2, __name2, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_STANDING_START_TOOLS, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, MODEL_ID_BYOK_PROVIDERS, MODEL_SNAPSHOT_SUFFIX, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, EventType, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, KEYS, MAX_BODY_BYTES, MAX_ID_LENGTH, UTC_ISO, TEMPLATE_TRIGGER_URL_ENV_PREFIX, TEMPLATE_INSTALL_POLICY_PER_WORKSPACE_VALUES, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, TYPED_API_KEY, IdSchema, SESSION_AUTH_TIME_MAX_S, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, LUA_SESSION_ID_CLAIM, SESSION_REVOKED_CODE, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema, SYSTEM_USER_PREFIX, WORKFLOW_RUN_IN_FLIGHT, WORKFLOW_RUN_IDLE, WORKFLOW_RUN_TERMINAL, WORKFLOW_RUN_STATUSES, WORKFLOW_RUN_GATE_KINDS, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, WORKFLOW_SIGNAL_EVENT_SITES, ARCHIVE_WINDOW_MARGIN_DAYS, WORKFLOW_ORG_PURGING_TTL_S, WORKFLOW_ORG_PURGE_FORCE_AFTER_MS, IDEMPOTENCY_HOLDING_STATUSES, WORKFLOW_SCHEDULED_RUN_ID_PREFIX, CLOUD_TASK_RUN_ID_PREFIX, WORKFLOW_SCHEDULE_KEY_MAX, WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_JOURNAL_PROTOCOL_VERSION, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES,
|
|
2080
|
+
var __defProp2, __name2, REVIEWABLE_ACTION_EXECUTE_TOOL_ALLOWLIST, REVIEWABLE_STANDING_START_TOOLS, REVIEWABLE_MCP_SEND_TOOL_SUFFIX, MCP_TOOL_READ_VERB_RE, MCP_DRAFT_CREATE_VERBS, NON_INTERACTIVE_CHANNELS, RICH_PARTS_MESSAGE_ID_PREFIX, SCREENSHOT_MESSAGE_ID_PREFIX, BROWSER_COMMANDS, BROWSER_COMMAND_NAMES, DESKTOP_FILE_COMMANDS, DESKTOP_FILE_COMMAND_SET, WORKFLOW_RETRY_BACKOFFS, WORKFLOW_RETRY_MIN_ATTEMPTS, WORKFLOW_RETRY_POLICY_KEYS, WORKFLOW_RETRY_MAX_ATTEMPTS, WORKFLOW_RETRY_ENGINE_KEYS, WORKFLOW_JOB_RESOURCES, WORKFLOW_SIDE_EFFECTS, WORKFLOW_AGENT_EFFORTS, WORKFLOW_MODEL_CLASSES, WORKFLOW_TASK_CLASSES, WORKFLOW_MODEL_TRAITS, WORKFLOW_MODEL_REASON_MAX_LENGTH, WORKFLOW_MODELS_COMPOSE_MODES, WORKFLOW_MODELS_PIN_MODES, WORKFLOW_MODELS_FALLBACK_MODES, WORKFLOW_MODELS_CONSENT_ACTIONS_MIN, WORKFLOW_DEFAULT_TASK_CLASS_MAP, WORKFLOW_MODELS_MAX_CLASS_DEFAULT, WORKFLOW_AUTONOMY_FORMS, WORKFLOW_AUTONOMY_NUMERIC_KEYS, WORKFLOW_AUTONOMY_ENVELOPE_KEYS, WORKFLOW_AUTONOMY_ENABLED_DEFAULT, WORKFLOW_AUTONOMY_DEFAULTS, WORKFLOW_AUTONOMY_CEILINGS, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV, WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING, WORKFLOW_AUTONOMY_FORMS_DEFAULT, WORKFLOW_AUTONOMY_MIN_VALUE, WORKFLOW_JOB_RANGES, WORKFLOW_JOB_RANGE_MEMBERS, WORKFLOW_SINGLE_STEP_TYPES, WORKFLOW_HITL_ENTRY_TYPES, WORKFLOW_ARM_ENTRY_TYPES, WORKFLOW_HITL_ARM_CONTAINERS, WORKFLOW_GRAPH_ENTRY_STEP_KINDS, WORKFLOW_ARM_ENTRY_STEP_KINDS, WORKFLOW_BUDGET_MAX_DURATION_SECONDS, MODEL_ID_BYOK_PROVIDERS, MODEL_CLASS_REF_PREFIX, MODEL_SNAPSHOT_SUFFIX, REASONING_EFFORT_VALUES, IMPLICIT_MODEL_SELECTION_SOURCES, PLATFORM_FALLBACK_MODEL_SOURCE, AGENT_NAME_TOKEN, DEFAULT_PERSONA_GUIDE, PERSONAL_SPACE_STARTING_PERSONA, AGENT_LOG_SOURCES, CORE_DRAINING_CODE, CORE_DRAINING_DEFAULT_RETRY_MS, CORE_DRAINING_MAX_RETRY_MS, VoiceNameSchema, PluginProviderSchema, RealtimeProviderSchema, PluginClassSchema, ModelDescriptorSchema, InferenceModelSchema, PluginModelSchema, RealtimeModelSchema, LuaVoiceModelSchema, TurnDetectionSchema, InterruptionSchema, BuiltinAudioClipSchema, AudioConfigSchema, BackgroundAudioEntrySchema, BackgroundAudioSchema, LuaVoiceConfigInnerSchema, LuaVoiceConfigSchema, LuaVoiceRefSchema, EventType, LUA_JOB_DEFAULT_TIMEOUT_SECONDS, LUA_JOB_MIN_TIMEOUT_SECONDS, LUA_JOB_MAX_TIMEOUT_SECONDS, KEYS, MAX_BODY_BYTES, MAX_ID_LENGTH, UTC_ISO, TEMPLATE_TRIGGER_URL_ENV_PREFIX, TEMPLATE_INSTALL_POLICY_PER_WORKSPACE_VALUES, SUBJECT_TYPES, SubjectTypeSchema, CREDENTIAL_TYPES, CredentialTypeSchema, DEVICE_OPERATIONS, DeviceOperationSchema, DEVICE_SCOPE_BY_OPERATION, DeviceBindingSchema, TYPED_API_KEY, IdSchema, SESSION_AUTH_TIME_MAX_S, PrincipalDescriptorSchema, ActorDescriptorSchema, PrincipalOwnerSchema, CredentialLifecycleSchema, GeneralCredentialDescriptorSchema, DeviceCredentialDescriptorSchema, GeneralPrincipalContextSchema, DeviceCredentialPrincipalContextSchema, RawPrincipalContextSchema, PrincipalContextSchema, DeviceCredentialClaimSchema, LUA_CLIENT_HEADER, LUA_CLIENT_APPS, SEMVER_PATTERN, WEB_RELEASE_PATTERN, CLIENT_HEADER_PATTERN, LUA_SESSION_ID_CLAIM, SESSION_REVOKED_CODE, AUTHZ_PROJECTION_VERSION, ProjectedScopeSchema, DisplayRoleSchema, AuthorizationPrincipalSchema, CredentialContextSchema, ProjectionAnomalySchema, ProjectedOrgSchema, ProjectedResourceSchema, CapabilityProfilesSchema, RoleCatalogSchema, EffectiveAuthorizationSchema, ResourcePageSchema, SYSTEM_USER_PREFIX, WORKFLOW_RUN_IN_FLIGHT, WORKFLOW_RUN_IDLE, WORKFLOW_RUN_TERMINAL, WORKFLOW_RUN_STATUSES, WORKFLOW_RUN_GATE_KINDS, WORKFLOW_STEP_STATUSES, WORKFLOW_STEP_IN_FLIGHT, WORKFLOW_SIGNAL_EVENT_SITES, ARCHIVE_WINDOW_MARGIN_DAYS, WORKFLOW_ORG_PURGING_TTL_S, WORKFLOW_ORG_PURGE_FORCE_AFTER_MS, IDEMPOTENCY_HOLDING_STATUSES, WORKFLOW_SCHEDULED_RUN_ID_PREFIX, CLOUD_TASK_RUN_ID_PREFIX, WORKFLOW_SCHEDULE_KEY_MAX, WORKFLOW_SCHEDULE_IDEMPOTENCY_KEY_PREFIX, WORKFLOW_OPERATION_ID_PREFIX, WORKFLOW_JOURNAL_PROTOCOL_VERSION, WORKFLOW_CONNECTION_KEY_RE, WORKFLOW_SUSPEND_KINDS, WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS, WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES, WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES, WORKFLOW_GOAL_JUDGE_SELF, REDACTED_PLACEHOLDER, PROVIDER_MESSAGE_MAX_CHARS, ERROR_MESSAGE_MAX_CHARS, SECRET_LITERAL_PATTERNS, SECRET_NAME, SECRET_PAIR_PATTERNS, GROUP_COUNT, WORKFLOW_SECRET_KEY_RE, WORKFLOW_RESERVED_SECRET_KEYS, SCRUB_INPUT_MAX_CHARS, SCRUB_CUT_BACKOFF_CHARS, WORKFLOW_AUDIT_EVENTS, WORKFLOW_AUDIT_METADATA_MAX_BYTES, INDENT, WRAP_WIDTH, NOUNS, GET_TOOL_NAMES, PREAMBLE, WORKFLOW_APPROVAL_OUTPUT_DECISIONS, WORKFLOW_APPROVAL_OUTPUT_SCHEMA, JSON_FENCE_RE, DEFAULT_ON_AGENT_FEATURES, SUBAGENT_PER_KEY_FLAG_ENV, PER_KEY_FLAG_VALUES;
|
|
2039
2081
|
var init_dist = __esm({
|
|
2040
2082
|
"../shared-types/dist/index.mjs"() {
|
|
2041
2083
|
"use strict";
|
|
@@ -2348,16 +2390,243 @@ var init_dist = __esm({
|
|
|
2348
2390
|
__name2(isDesktopFileCommandName, "isDesktopFileCommandName");
|
|
2349
2391
|
__name(isDesktopFileSessionId, "isDesktopFileSessionId");
|
|
2350
2392
|
__name2(isDesktopFileSessionId, "isDesktopFileSessionId");
|
|
2393
|
+
WORKFLOW_RETRY_BACKOFFS = [
|
|
2394
|
+
"fixed",
|
|
2395
|
+
"exponential"
|
|
2396
|
+
];
|
|
2397
|
+
WORKFLOW_RETRY_MIN_ATTEMPTS = 1;
|
|
2398
|
+
WORKFLOW_RETRY_POLICY_KEYS = [
|
|
2399
|
+
"maxAttempts",
|
|
2400
|
+
"backoffSeconds",
|
|
2401
|
+
"backoff",
|
|
2402
|
+
"maxBackoffSeconds"
|
|
2403
|
+
];
|
|
2404
|
+
WORKFLOW_RETRY_MAX_ATTEMPTS = 20;
|
|
2405
|
+
__name(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
2406
|
+
__name2(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
2407
|
+
__name(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
2408
|
+
__name2(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
2409
|
+
WORKFLOW_RETRY_ENGINE_KEYS = [
|
|
2410
|
+
"budgetBaseAttempt"
|
|
2411
|
+
];
|
|
2412
|
+
__name(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
2413
|
+
__name2(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
2414
|
+
__name(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
2415
|
+
__name2(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
2416
|
+
__name(authoredRetryPolicy, "authoredRetryPolicy");
|
|
2417
|
+
__name2(authoredRetryPolicy, "authoredRetryPolicy");
|
|
2418
|
+
__name(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
2419
|
+
__name2(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
2420
|
+
__name(retryBudgetAttempt, "retryBudgetAttempt");
|
|
2421
|
+
__name2(retryBudgetAttempt, "retryBudgetAttempt");
|
|
2422
|
+
__name(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
2423
|
+
__name2(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
2424
|
+
__name(retryBudgetRemaining, "retryBudgetRemaining");
|
|
2425
|
+
__name2(retryBudgetRemaining, "retryBudgetRemaining");
|
|
2426
|
+
__name(retriesRemaining, "retriesRemaining");
|
|
2427
|
+
__name2(retriesRemaining, "retriesRemaining");
|
|
2428
|
+
WORKFLOW_JOB_RESOURCES = [
|
|
2429
|
+
"small",
|
|
2430
|
+
"medium",
|
|
2431
|
+
"large"
|
|
2432
|
+
];
|
|
2433
|
+
WORKFLOW_SIDE_EFFECTS = [
|
|
2434
|
+
"none",
|
|
2435
|
+
"external"
|
|
2436
|
+
];
|
|
2437
|
+
WORKFLOW_AGENT_EFFORTS = [
|
|
2438
|
+
"low",
|
|
2439
|
+
"medium",
|
|
2440
|
+
"high"
|
|
2441
|
+
];
|
|
2442
|
+
WORKFLOW_MODEL_CLASSES = [
|
|
2443
|
+
"fast",
|
|
2444
|
+
"balanced",
|
|
2445
|
+
"strong"
|
|
2446
|
+
];
|
|
2447
|
+
WORKFLOW_TASK_CLASSES = [
|
|
2448
|
+
"classify",
|
|
2449
|
+
"extract",
|
|
2450
|
+
"transform",
|
|
2451
|
+
"draft",
|
|
2452
|
+
"research",
|
|
2453
|
+
"reason",
|
|
2454
|
+
"code",
|
|
2455
|
+
"judge"
|
|
2456
|
+
];
|
|
2457
|
+
WORKFLOW_MODEL_TRAITS = [
|
|
2458
|
+
"vision",
|
|
2459
|
+
"structured",
|
|
2460
|
+
"largeContext",
|
|
2461
|
+
"codeExecution"
|
|
2462
|
+
];
|
|
2463
|
+
WORKFLOW_MODEL_REASON_MAX_LENGTH = 160;
|
|
2464
|
+
__name(workflowModelCostComparison, "workflowModelCostComparison");
|
|
2465
|
+
__name2(workflowModelCostComparison, "workflowModelCostComparison");
|
|
2466
|
+
WORKFLOW_MODELS_COMPOSE_MODES = [
|
|
2467
|
+
"off",
|
|
2468
|
+
"on"
|
|
2469
|
+
];
|
|
2470
|
+
WORKFLOW_MODELS_PIN_MODES = [
|
|
2471
|
+
"class-only",
|
|
2472
|
+
"allowed"
|
|
2473
|
+
];
|
|
2474
|
+
WORKFLOW_MODELS_FALLBACK_MODES = [
|
|
2475
|
+
"same-class",
|
|
2476
|
+
"same-provider"
|
|
2477
|
+
];
|
|
2478
|
+
WORKFLOW_MODELS_CONSENT_ACTIONS_MIN = 1;
|
|
2479
|
+
WORKFLOW_DEFAULT_TASK_CLASS_MAP = Object.freeze({
|
|
2480
|
+
classify: "fast",
|
|
2481
|
+
extract: "fast",
|
|
2482
|
+
transform: "fast",
|
|
2483
|
+
draft: "balanced",
|
|
2484
|
+
research: "balanced",
|
|
2485
|
+
judge: "balanced",
|
|
2486
|
+
reason: "strong",
|
|
2487
|
+
code: "strong"
|
|
2488
|
+
});
|
|
2489
|
+
WORKFLOW_MODELS_MAX_CLASS_DEFAULT = WORKFLOW_MODEL_CLASSES[WORKFLOW_MODEL_CLASSES.length - 1];
|
|
2490
|
+
__name(modelClassRank, "modelClassRank");
|
|
2491
|
+
__name2(modelClassRank, "modelClassRank");
|
|
2492
|
+
__name(modelClassesAtOrBelow, "modelClassesAtOrBelow");
|
|
2493
|
+
__name2(modelClassesAtOrBelow, "modelClassesAtOrBelow");
|
|
2494
|
+
WORKFLOW_AUTONOMY_FORMS = [
|
|
2495
|
+
"graph",
|
|
2496
|
+
"script",
|
|
2497
|
+
"static"
|
|
2498
|
+
];
|
|
2499
|
+
WORKFLOW_AUTONOMY_NUMERIC_KEYS = [
|
|
2500
|
+
"maxCredits",
|
|
2501
|
+
"maxSteps",
|
|
2502
|
+
"maxDurationSeconds",
|
|
2503
|
+
"maxActions",
|
|
2504
|
+
"maxRunsPerHour"
|
|
2505
|
+
];
|
|
2506
|
+
WORKFLOW_AUTONOMY_ENVELOPE_KEYS = [
|
|
2507
|
+
"enabled",
|
|
2508
|
+
...WORKFLOW_AUTONOMY_NUMERIC_KEYS,
|
|
2509
|
+
"forms"
|
|
2510
|
+
];
|
|
2511
|
+
WORKFLOW_AUTONOMY_ENABLED_DEFAULT = false;
|
|
2512
|
+
WORKFLOW_AUTONOMY_DEFAULTS = Object.freeze({
|
|
2513
|
+
maxCredits: 20,
|
|
2514
|
+
maxSteps: 15,
|
|
2515
|
+
maxDurationSeconds: 86400,
|
|
2516
|
+
maxRunsPerHour: 20
|
|
2517
|
+
});
|
|
2518
|
+
WORKFLOW_AUTONOMY_CEILINGS = Object.freeze({
|
|
2519
|
+
maxSteps: 40,
|
|
2520
|
+
maxDurationSeconds: 604800
|
|
2521
|
+
});
|
|
2522
|
+
WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV = "LUA_WF_AUTONOMY_MAX_RUNS_PER_HOUR";
|
|
2523
|
+
WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING = 200;
|
|
2524
|
+
__name(workflowAutonomyMaxRunsPerHourCeiling, "workflowAutonomyMaxRunsPerHourCeiling");
|
|
2525
|
+
__name2(workflowAutonomyMaxRunsPerHourCeiling, "workflowAutonomyMaxRunsPerHourCeiling");
|
|
2526
|
+
WORKFLOW_AUTONOMY_FORMS_DEFAULT = Object.freeze([
|
|
2527
|
+
"graph",
|
|
2528
|
+
"static"
|
|
2529
|
+
]);
|
|
2530
|
+
WORKFLOW_AUTONOMY_MIN_VALUE = 1;
|
|
2531
|
+
__name(isWithinWorkflowAutonomyRange, "isWithinWorkflowAutonomyRange");
|
|
2532
|
+
__name2(isWithinWorkflowAutonomyRange, "isWithinWorkflowAutonomyRange");
|
|
2533
|
+
__name(workflowAutonomyRangeMessage, "workflowAutonomyRangeMessage");
|
|
2534
|
+
__name2(workflowAutonomyRangeMessage, "workflowAutonomyRangeMessage");
|
|
2535
|
+
WORKFLOW_JOB_RANGES = Object.freeze({
|
|
2536
|
+
/** Coding-turn cap (`claude -p --max-turns`); absent ⇒ the cluster default (LUA_WF_JOB_MAX_TURNS). */
|
|
2537
|
+
maxTurns: Object.freeze({
|
|
2538
|
+
min: 1,
|
|
2539
|
+
max: 500
|
|
2540
|
+
}),
|
|
2541
|
+
/** Harness messages per attempt (one per content block); absent ⇒ the cluster default (400). */
|
|
2542
|
+
maxMessages: Object.freeze({
|
|
2543
|
+
min: 1,
|
|
2544
|
+
max: 5e3
|
|
2545
|
+
}),
|
|
2546
|
+
/** Input-side tokens per attempt (prompt + cache); absent ⇒ the cluster default (4M — LUA-708, was 30M). */
|
|
2547
|
+
maxInputTokens: Object.freeze({
|
|
2548
|
+
min: 1e6,
|
|
2549
|
+
max: 5e8
|
|
2550
|
+
})
|
|
2551
|
+
});
|
|
2552
|
+
WORKFLOW_JOB_RANGE_MEMBERS = Object.keys(WORKFLOW_JOB_RANGES);
|
|
2553
|
+
__name(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
|
|
2554
|
+
__name2(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
|
|
2555
|
+
__name(workflowJobRangeMessage, "workflowJobRangeMessage");
|
|
2556
|
+
__name2(workflowJobRangeMessage, "workflowJobRangeMessage");
|
|
2557
|
+
WORKFLOW_SINGLE_STEP_TYPES = [
|
|
2558
|
+
"agent",
|
|
2559
|
+
"tool",
|
|
2560
|
+
"workflow",
|
|
2561
|
+
"step"
|
|
2562
|
+
];
|
|
2563
|
+
WORKFLOW_HITL_ENTRY_TYPES = [
|
|
2564
|
+
"approval",
|
|
2565
|
+
"waitForSignal"
|
|
2566
|
+
];
|
|
2567
|
+
WORKFLOW_ARM_ENTRY_TYPES = [
|
|
2568
|
+
...WORKFLOW_SINGLE_STEP_TYPES,
|
|
2569
|
+
...WORKFLOW_HITL_ENTRY_TYPES
|
|
2570
|
+
];
|
|
2571
|
+
WORKFLOW_HITL_ARM_CONTAINERS = [
|
|
2572
|
+
"parallel",
|
|
2573
|
+
"conditional",
|
|
2574
|
+
"foreach"
|
|
2575
|
+
];
|
|
2576
|
+
__name(isWorkflowSingleStepType, "isWorkflowSingleStepType");
|
|
2577
|
+
__name2(isWorkflowSingleStepType, "isWorkflowSingleStepType");
|
|
2578
|
+
__name(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
|
|
2579
|
+
__name2(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
|
|
2580
|
+
__name(isWorkflowArmEntryType, "isWorkflowArmEntryType");
|
|
2581
|
+
__name2(isWorkflowArmEntryType, "isWorkflowArmEntryType");
|
|
2582
|
+
__name(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
|
|
2583
|
+
__name2(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
|
|
2584
|
+
__name(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
|
|
2585
|
+
__name2(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
|
|
2586
|
+
__name(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
|
|
2587
|
+
__name2(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
|
|
2588
|
+
WORKFLOW_GRAPH_ENTRY_STEP_KINDS = Object.freeze({
|
|
2589
|
+
agent: "agent",
|
|
2590
|
+
tool: "tool",
|
|
2591
|
+
workflow: "subrun",
|
|
2592
|
+
step: "code",
|
|
2593
|
+
mapping: "map",
|
|
2594
|
+
sleep: "sleep",
|
|
2595
|
+
sleepUntil: "sleepUntil",
|
|
2596
|
+
parallel: null,
|
|
2597
|
+
conditional: "branch",
|
|
2598
|
+
foreach: "foreach",
|
|
2599
|
+
loop: "loop",
|
|
2600
|
+
approval: "approval",
|
|
2601
|
+
waitForSignal: "signal"
|
|
2602
|
+
});
|
|
2603
|
+
WORKFLOW_ARM_ENTRY_STEP_KINDS = Object.freeze(Object.fromEntries(WORKFLOW_ARM_ENTRY_TYPES.map((t) => [
|
|
2604
|
+
t,
|
|
2605
|
+
WORKFLOW_GRAPH_ENTRY_STEP_KINDS[t]
|
|
2606
|
+
])));
|
|
2607
|
+
WORKFLOW_BUDGET_MAX_DURATION_SECONDS = Object.freeze({
|
|
2608
|
+
min: 60,
|
|
2609
|
+
max: 2592e3
|
|
2610
|
+
});
|
|
2351
2611
|
MODEL_ID_BYOK_PROVIDERS = [
|
|
2352
2612
|
"azure",
|
|
2353
2613
|
"bedrock"
|
|
2354
2614
|
];
|
|
2355
2615
|
__name(isModelIdSentinel, "isModelIdSentinel");
|
|
2356
2616
|
__name2(isModelIdSentinel, "isModelIdSentinel");
|
|
2617
|
+
MODEL_CLASS_REF_PREFIX = "class/";
|
|
2618
|
+
__name(isModelClassRef, "isModelClassRef");
|
|
2619
|
+
__name2(isModelClassRef, "isModelClassRef");
|
|
2620
|
+
__name(modelClassOf, "modelClassOf");
|
|
2621
|
+
__name2(modelClassOf, "modelClassOf");
|
|
2622
|
+
__name(modelClassRef, "modelClassRef");
|
|
2623
|
+
__name2(modelClassRef, "modelClassRef");
|
|
2357
2624
|
__name(normalizeModelId, "normalizeModelId");
|
|
2358
2625
|
__name2(normalizeModelId, "normalizeModelId");
|
|
2359
2626
|
__name(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
2360
2627
|
__name2(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
2628
|
+
__name(modelClassUnresolvedMessage, "modelClassUnresolvedMessage");
|
|
2629
|
+
__name2(modelClassUnresolvedMessage, "modelClassUnresolvedMessage");
|
|
2361
2630
|
__name(providerModelId, "providerModelId");
|
|
2362
2631
|
__name2(providerModelId, "providerModelId");
|
|
2363
2632
|
MODEL_SNAPSHOT_SUFFIX = /(?:[-@](?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])|-(?:19|20)\d{2}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01]))$/;
|
|
@@ -3030,7 +3299,15 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3030
3299
|
"org-grant",
|
|
3031
3300
|
"agent-grant-only"
|
|
3032
3301
|
]).describe("For user and staff principals, grant provenance: org-grant means a stored org grant produced the row. For owner-ceiling API keys, effective provenance: org-grant means the credential-owner intersection has org-level capability; agent-grant-only means the intersection reaches only an exact agent inside the org."),
|
|
3033
|
-
anomalies: z3.array(ProjectionAnomalySchema).optional()
|
|
3302
|
+
anomalies: z3.array(ProjectionAnomalySchema).optional(),
|
|
3303
|
+
/**
|
|
3304
|
+
* How many agents and Spaces in this org the caller can read — the size of
|
|
3305
|
+
* the org's resource page under the same discovery rule, without paging it.
|
|
3306
|
+
*/
|
|
3307
|
+
resourceCounts: z3.object({
|
|
3308
|
+
agents: z3.number().int().nonnegative(),
|
|
3309
|
+
spaces: z3.number().int().nonnegative()
|
|
3310
|
+
}).optional()
|
|
3034
3311
|
}).passthrough();
|
|
3035
3312
|
ProjectedResourceSchema = z3.object({
|
|
3036
3313
|
resourceType: z3.literal("agent"),
|
|
@@ -3069,7 +3346,21 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3069
3346
|
id: z3.string().min(1).max(256),
|
|
3070
3347
|
name: z3.string().optional(),
|
|
3071
3348
|
email: z3.string().optional()
|
|
3072
|
-
}).optional()
|
|
3349
|
+
}).optional(),
|
|
3350
|
+
/**
|
|
3351
|
+
* Presentation enrichment (PRO-1994), product data only — never influences
|
|
3352
|
+
* discovery. These moved off the O(orgs) `/context` roster onto the bounded
|
|
3353
|
+
* per-active-org resource page so Desktop stops paying an org-count-scaled
|
|
3354
|
+
* cost at sign-in. `persona`/`avatar` are loose (`PersonaText` / `AgentAvatar`
|
|
3355
|
+
* are structured-or-string), `platform` marks the org's Designer agent
|
|
3356
|
+
* (previously stamped only by `/context`; retires with PRO-1657).
|
|
3357
|
+
*/
|
|
3358
|
+
persona: z3.unknown().optional(),
|
|
3359
|
+
description: z3.string().optional(),
|
|
3360
|
+
avatar: z3.unknown().nullish(),
|
|
3361
|
+
platform: z3.boolean().optional(),
|
|
3362
|
+
/** A Space's supervised agent ids (`kind: 'space'` rows only). */
|
|
3363
|
+
supervisedAgents: z3.array(z3.string()).optional()
|
|
3073
3364
|
}).passthrough();
|
|
3074
3365
|
CapabilityProfilesSchema = z3.record(z3.string().min(1).max(64), z3.array(ProjectedScopeSchema));
|
|
3075
3366
|
RoleCatalogSchema = z3.record(z3.string().min(1).max(128), z3.object({
|
|
@@ -3159,7 +3450,8 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3159
3450
|
"org_archived",
|
|
3160
3451
|
"disabled",
|
|
3161
3452
|
"exception",
|
|
3162
|
-
"budget"
|
|
3453
|
+
"budget",
|
|
3454
|
+
"model_policy"
|
|
3163
3455
|
];
|
|
3164
3456
|
WORKFLOW_STEP_STATUSES = [
|
|
3165
3457
|
"pending",
|
|
@@ -3244,126 +3536,6 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3244
3536
|
];
|
|
3245
3537
|
WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
|
|
3246
3538
|
WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES = 256 * 1024;
|
|
3247
|
-
WORKFLOW_RETRY_BACKOFFS = [
|
|
3248
|
-
"fixed",
|
|
3249
|
-
"exponential"
|
|
3250
|
-
];
|
|
3251
|
-
WORKFLOW_RETRY_MIN_ATTEMPTS = 1;
|
|
3252
|
-
WORKFLOW_RETRY_POLICY_KEYS = [
|
|
3253
|
-
"maxAttempts",
|
|
3254
|
-
"backoffSeconds",
|
|
3255
|
-
"backoff",
|
|
3256
|
-
"maxBackoffSeconds"
|
|
3257
|
-
];
|
|
3258
|
-
WORKFLOW_RETRY_MAX_ATTEMPTS = 20;
|
|
3259
|
-
__name(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
3260
|
-
__name2(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
3261
|
-
__name(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
3262
|
-
__name2(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
3263
|
-
WORKFLOW_RETRY_ENGINE_KEYS = [
|
|
3264
|
-
"budgetBaseAttempt"
|
|
3265
|
-
];
|
|
3266
|
-
__name(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
3267
|
-
__name2(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
3268
|
-
__name(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
3269
|
-
__name2(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
3270
|
-
__name(authoredRetryPolicy, "authoredRetryPolicy");
|
|
3271
|
-
__name2(authoredRetryPolicy, "authoredRetryPolicy");
|
|
3272
|
-
__name(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
3273
|
-
__name2(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
3274
|
-
__name(retryBudgetAttempt, "retryBudgetAttempt");
|
|
3275
|
-
__name2(retryBudgetAttempt, "retryBudgetAttempt");
|
|
3276
|
-
__name(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
3277
|
-
__name2(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
3278
|
-
__name(retryBudgetRemaining, "retryBudgetRemaining");
|
|
3279
|
-
__name2(retryBudgetRemaining, "retryBudgetRemaining");
|
|
3280
|
-
__name(retriesRemaining, "retriesRemaining");
|
|
3281
|
-
__name2(retriesRemaining, "retriesRemaining");
|
|
3282
|
-
WORKFLOW_JOB_RESOURCES = [
|
|
3283
|
-
"small",
|
|
3284
|
-
"medium",
|
|
3285
|
-
"large"
|
|
3286
|
-
];
|
|
3287
|
-
WORKFLOW_SIDE_EFFECTS = [
|
|
3288
|
-
"none",
|
|
3289
|
-
"external"
|
|
3290
|
-
];
|
|
3291
|
-
WORKFLOW_JOB_RANGES = Object.freeze({
|
|
3292
|
-
/** Coding-turn cap (`claude -p --max-turns`); absent ⇒ the cluster default (LUA_WF_JOB_MAX_TURNS). */
|
|
3293
|
-
maxTurns: Object.freeze({
|
|
3294
|
-
min: 1,
|
|
3295
|
-
max: 500
|
|
3296
|
-
}),
|
|
3297
|
-
/** Harness messages per attempt (one per content block); absent ⇒ the cluster default (400). */
|
|
3298
|
-
maxMessages: Object.freeze({
|
|
3299
|
-
min: 1,
|
|
3300
|
-
max: 5e3
|
|
3301
|
-
}),
|
|
3302
|
-
/** Input-side tokens per attempt (prompt + cache); absent ⇒ the cluster default (4M — LUA-708, was 30M). */
|
|
3303
|
-
maxInputTokens: Object.freeze({
|
|
3304
|
-
min: 1e6,
|
|
3305
|
-
max: 5e8
|
|
3306
|
-
})
|
|
3307
|
-
});
|
|
3308
|
-
WORKFLOW_JOB_RANGE_MEMBERS = Object.keys(WORKFLOW_JOB_RANGES);
|
|
3309
|
-
__name(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
|
|
3310
|
-
__name2(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
|
|
3311
|
-
__name(workflowJobRangeMessage, "workflowJobRangeMessage");
|
|
3312
|
-
__name2(workflowJobRangeMessage, "workflowJobRangeMessage");
|
|
3313
|
-
WORKFLOW_SINGLE_STEP_TYPES = [
|
|
3314
|
-
"agent",
|
|
3315
|
-
"tool",
|
|
3316
|
-
"workflow",
|
|
3317
|
-
"step"
|
|
3318
|
-
];
|
|
3319
|
-
WORKFLOW_HITL_ENTRY_TYPES = [
|
|
3320
|
-
"approval",
|
|
3321
|
-
"waitForSignal"
|
|
3322
|
-
];
|
|
3323
|
-
WORKFLOW_ARM_ENTRY_TYPES = [
|
|
3324
|
-
...WORKFLOW_SINGLE_STEP_TYPES,
|
|
3325
|
-
...WORKFLOW_HITL_ENTRY_TYPES
|
|
3326
|
-
];
|
|
3327
|
-
WORKFLOW_HITL_ARM_CONTAINERS = [
|
|
3328
|
-
"parallel",
|
|
3329
|
-
"conditional",
|
|
3330
|
-
"foreach"
|
|
3331
|
-
];
|
|
3332
|
-
__name(isWorkflowSingleStepType, "isWorkflowSingleStepType");
|
|
3333
|
-
__name2(isWorkflowSingleStepType, "isWorkflowSingleStepType");
|
|
3334
|
-
__name(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
|
|
3335
|
-
__name2(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
|
|
3336
|
-
__name(isWorkflowArmEntryType, "isWorkflowArmEntryType");
|
|
3337
|
-
__name2(isWorkflowArmEntryType, "isWorkflowArmEntryType");
|
|
3338
|
-
__name(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
|
|
3339
|
-
__name2(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
|
|
3340
|
-
__name(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
|
|
3341
|
-
__name2(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
|
|
3342
|
-
__name(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
|
|
3343
|
-
__name2(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
|
|
3344
|
-
WORKFLOW_GRAPH_ENTRY_STEP_KINDS = Object.freeze({
|
|
3345
|
-
agent: "agent",
|
|
3346
|
-
tool: "tool",
|
|
3347
|
-
workflow: "subrun",
|
|
3348
|
-
step: "code",
|
|
3349
|
-
mapping: "map",
|
|
3350
|
-
sleep: "sleep",
|
|
3351
|
-
sleepUntil: "sleepUntil",
|
|
3352
|
-
parallel: null,
|
|
3353
|
-
conditional: "branch",
|
|
3354
|
-
foreach: "foreach",
|
|
3355
|
-
loop: "loop",
|
|
3356
|
-
approval: "approval",
|
|
3357
|
-
waitForSignal: "signal"
|
|
3358
|
-
});
|
|
3359
|
-
WORKFLOW_ARM_ENTRY_STEP_KINDS = Object.freeze(Object.fromEntries(WORKFLOW_ARM_ENTRY_TYPES.map((t) => [
|
|
3360
|
-
t,
|
|
3361
|
-
WORKFLOW_GRAPH_ENTRY_STEP_KINDS[t]
|
|
3362
|
-
])));
|
|
3363
|
-
WORKFLOW_BUDGET_MAX_DURATION_SECONDS = Object.freeze({
|
|
3364
|
-
min: 60,
|
|
3365
|
-
max: 2592e3
|
|
3366
|
-
});
|
|
3367
3539
|
WORKFLOW_GOAL_JUDGE_SELF = "$self";
|
|
3368
3540
|
__name(workflowGoalJudgeKind, "workflowGoalJudgeKind");
|
|
3369
3541
|
__name2(workflowGoalJudgeKind, "workflowGoalJudgeKind");
|
|
@@ -3568,7 +3740,20 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3568
3740
|
"workflow.export.auto_pushed",
|
|
3569
3741
|
"workflow.retention.restamped",
|
|
3570
3742
|
"workflow.retention.reaped",
|
|
3571
|
-
"workflow.run.schema_migrated"
|
|
3743
|
+
"workflow.run.schema_migrated",
|
|
3744
|
+
// --- per-step model selection (Workflow Model Selection plan 6.5 / Appendix C.4) ---
|
|
3745
|
+
/** A `PATCH /admin/orgs/:orgId/workflow-policy` that changed the `models` block (who, what moved). */
|
|
3746
|
+
"workflow.policy.models_changed",
|
|
3747
|
+
/** A step's invocation hopped to another leg of its class — `{from, to, reason}`, priced at the served model. */
|
|
3748
|
+
"workflow.step.model_fallback",
|
|
3749
|
+
// --- autonomy envelope (Workflow autonomy plan A1; research/consent-gates.md §H2) ---
|
|
3750
|
+
/**
|
|
3751
|
+
* A start the consent ladder would have PARKED was admitted by `workflowPolicy.autonomy` instead —
|
|
3752
|
+
* `WorkflowRunAutonomyAppliedPayload`. Deliberately NOT `workflow.run.gate_cleared`: nothing was
|
|
3753
|
+
* gated and nobody approved it, and conflating the two would make "who approved this run"
|
|
3754
|
+
* unanswerable for every run of either kind (§H2 "Audit").
|
|
3755
|
+
*/
|
|
3756
|
+
"workflow.run.autonomy_applied"
|
|
3572
3757
|
];
|
|
3573
3758
|
WORKFLOW_AUDIT_METADATA_MAX_BYTES = 4 * 1024;
|
|
3574
3759
|
__name(isWorkflowAuditEvent, "isWorkflowAuditEvent");
|
|
@@ -4629,7 +4814,7 @@ function modelTemplateInvalidMessage(model, why) {
|
|
|
4629
4814
|
return `model "${model.trim()}" is not a valid run-input-bound model placeholder \u2014 ${why}; the forms are \${initData.<path>} and \${initData.<path>|<provider/model default>}`;
|
|
4630
4815
|
}
|
|
4631
4816
|
function modelTemplateDefaultRequiredMessage(model) {
|
|
4632
|
-
return `model "${model}" runs on the Job tier, so its placeholder needs a default \u2014 the harness / provider gates (harness:'claude-code' needs an Anthropic model) classify it at push; write ${model.replace(/\}$/, "|<provider/model>}")}`;
|
|
4817
|
+
return `model "${model}" runs on the Job tier, so its placeholder needs a default \u2014 the harness / provider gates (harness:'claude-code' needs an Anthropic model) classify it at push; write ${model.replace(/\}$/, "|<provider/model>}")} or a class reference (|class/fast, |class/balanced, |class/strong)`;
|
|
4633
4818
|
}
|
|
4634
4819
|
function staticModelPin(model) {
|
|
4635
4820
|
if (typeof model !== "string") return void 0;
|
|
@@ -5221,6 +5406,21 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5221
5406
|
err("required-connection-unknown", `requiredConnections ${JSON.stringify(unknown)} are neither declared connections[].key values nor connections the owner can mount`, `${path26}.requiredConnections`, singleId(node));
|
|
5222
5407
|
}
|
|
5223
5408
|
}, "checkRequiredConnections");
|
|
5409
|
+
const jobClassifiablePin = /* @__PURE__ */ __name4((model) => {
|
|
5410
|
+
const pin = staticModelPin(model);
|
|
5411
|
+
const modelClass = modelClassOf(pin);
|
|
5412
|
+
if (modelClass === void 0) return pin;
|
|
5413
|
+
const codes = opts.classMap?.[modelClass];
|
|
5414
|
+
if (!codes) return void 0;
|
|
5415
|
+
const jobProviders = opts.policy?.jobProviders;
|
|
5416
|
+
for (const code of codes) {
|
|
5417
|
+
const p = classifyModelProvider(code);
|
|
5418
|
+
if (p === null) continue;
|
|
5419
|
+
if (jobProviders && !jobProviders.includes(p)) continue;
|
|
5420
|
+
return code;
|
|
5421
|
+
}
|
|
5422
|
+
return void 0;
|
|
5423
|
+
}, "jobClassifiablePin");
|
|
5224
5424
|
const checkTier = /* @__PURE__ */ __name4((node, path26) => {
|
|
5225
5425
|
const id = singleId(node);
|
|
5226
5426
|
if (node.workspace && node.workspace !== "inherit" && node.tier !== void 0 && node.tier !== "job") {
|
|
@@ -5229,7 +5429,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5229
5429
|
if (node.harness !== void 0 && node.tier !== "job") {
|
|
5230
5430
|
err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path26}.harness`, id);
|
|
5231
5431
|
}
|
|
5232
|
-
const provider = node.type === "agent" ? classifyModelProvider(
|
|
5432
|
+
const provider = node.type === "agent" ? classifyModelProvider(jobClassifiablePin(node.model)) : null;
|
|
5233
5433
|
if (node.harness === "claude-code" && provider !== null && provider !== "anthropic") {
|
|
5234
5434
|
err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path26}.harness`, id);
|
|
5235
5435
|
}
|
|
@@ -5253,6 +5453,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5253
5453
|
}
|
|
5254
5454
|
const pin = parsed.kind === "template" ? parsed.template.default : node.model;
|
|
5255
5455
|
if (pin === void 0) return;
|
|
5456
|
+
if (isModelClassRef(pin)) return;
|
|
5256
5457
|
const inContext = /* @__PURE__ */ __name4((message) => parsed.kind === "template" ? `${message} (the default of ${parsed.template.placeholder})` : message, "inContext");
|
|
5257
5458
|
const registry = opts.approvedModels;
|
|
5258
5459
|
if (registry === void 0) return;
|
|
@@ -5266,6 +5467,12 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5266
5467
|
const resolved = normalizeModelId(pin, registry);
|
|
5267
5468
|
if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path26}.model`, id);
|
|
5268
5469
|
}, "checkModel");
|
|
5470
|
+
const checkTaskClass = /* @__PURE__ */ __name4((node, path26) => {
|
|
5471
|
+
if (node.type !== "agent" || node.taskClass === void 0) return;
|
|
5472
|
+
if (!opts.static) return;
|
|
5473
|
+
if (typeof node.model === "string" && node.model.trim()) return;
|
|
5474
|
+
err("task-class-without-model", `taskClass '${String(node.taskClass)}' needs a \`model\` on a pushed definition \u2014 write a class (model: 'class/fast' | 'class/balanced' | 'class/strong') or an approved provider/model code; nothing maps a task class to a model at dispatch, so a step with neither would run on the agent\u2019s own model`, `${path26}.taskClass`, singleId(node));
|
|
5475
|
+
}, "checkTaskClass");
|
|
5269
5476
|
const checkWorkspace = /* @__PURE__ */ __name4((node, path26) => {
|
|
5270
5477
|
const id = singleId(node);
|
|
5271
5478
|
const ws = workspaceOf(node);
|
|
@@ -5352,6 +5559,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5352
5559
|
checkTimeout(node, path26);
|
|
5353
5560
|
checkTier(node, path26);
|
|
5354
5561
|
checkModel(node, path26);
|
|
5562
|
+
checkTaskClass(node, path26);
|
|
5355
5563
|
checkRetry(node, path26);
|
|
5356
5564
|
checkWorkspace(node, path26);
|
|
5357
5565
|
if (!opts.static) {
|
|
@@ -8921,6 +9129,10 @@ var init_workflow = __esm({
|
|
|
8921
9129
|
maxDurationSeconds: cfg.budget?.maxDurationSeconds ?? (hitl ? WORKFLOW_HITL_MAX_DURATION_SECONDS : WORKFLOW_DEFAULT_MAX_DURATION_SECONDS)
|
|
8922
9130
|
});
|
|
8923
9131
|
const envelope = {
|
|
9132
|
+
// A plain build/push is ALWAYS marker 1 (plan 6.4's compatibility row: "a CLI test that a plain push of
|
|
9133
|
+
// such a definition stays at 1"). Moving a definition to 2 — the effort marker — is an explicit act
|
|
9134
|
+
// (`lua push --apply-effort`, or a new compose while assignment is on), never a side effect of the SDK
|
|
9135
|
+
// gaining an `effort` member.
|
|
8924
9136
|
luaWorkflow: 1,
|
|
8925
9137
|
budget,
|
|
8926
9138
|
definition: defined({
|
|
@@ -9241,6 +9453,10 @@ var init_workflow = __esm({
|
|
|
9241
9453
|
promptTemplate: templateText(opts.prompt),
|
|
9242
9454
|
outputSchema: schemaToJson(opts.outputSchema),
|
|
9243
9455
|
model: opts.model,
|
|
9456
|
+
taskClass: opts.taskClass,
|
|
9457
|
+
requires: opts.requires,
|
|
9458
|
+
modelReason: opts.modelReason,
|
|
9459
|
+
effort: opts.effort,
|
|
9244
9460
|
toolScope: opts.toolScope,
|
|
9245
9461
|
systemPrompt: opts.systemPrompt,
|
|
9246
9462
|
timeoutSeconds: opts.timeoutSeconds,
|
|
@@ -20340,6 +20556,8 @@ function sketchTopology(sourceFile, exportName, name, description) {
|
|
|
20340
20556
|
}
|
|
20341
20557
|
return {
|
|
20342
20558
|
graph: {
|
|
20559
|
+
// 1 is and stays the serializer's marker: the effort marker (2) is opted into by
|
|
20560
|
+
// `lua push --apply-effort` or a new compose (plan 6.4), never by a plain compile.
|
|
20343
20561
|
luaWorkflow: 1,
|
|
20344
20562
|
definition: {
|
|
20345
20563
|
id: name,
|
|
@@ -20465,7 +20683,7 @@ function computeDeferred(graph, opts = {}) {
|
|
|
20465
20683
|
deferred.add("job-tier-provider-unsupported");
|
|
20466
20684
|
}
|
|
20467
20685
|
const modelPin = n2.type === "agent" ? staticModelPin(n2.model) : void 0;
|
|
20468
|
-
if (modelPin !== void 0 && !isModelIdSentinel(modelPin)) deferred.add("model-unresolved");
|
|
20686
|
+
if (modelPin !== void 0 && !isModelIdSentinel(modelPin) && !isModelClassRef(modelPin)) deferred.add("model-unresolved");
|
|
20469
20687
|
if (Array.isArray(n2.requiredConnections) && n2.requiredConnections.some(serverDecides)) deferred.add("required-connection-unknown");
|
|
20470
20688
|
if (n2.type === "approval") {
|
|
20471
20689
|
const a = n2.approver;
|
|
@@ -26430,6 +26648,68 @@ var init_workflow_api_service = __esm({
|
|
|
26430
26648
|
const qs = query.toString();
|
|
26431
26649
|
return this.httpGet(`${this.runs}/${runId}/steps/${pathId(stepId)}/job${qs ? `?${qs}` : ""}`, await this.auth());
|
|
26432
26650
|
}
|
|
26651
|
+
// ─── [WMC-E7] Per-step model selection (§6.5, §6.7) ───
|
|
26652
|
+
/**
|
|
26653
|
+
* §6.5 — the organization's workflow policy, `models` block included. The route is the organization's, not
|
|
26654
|
+
* the agent's, so the orgId comes from the project config rather than from `this.agentId`.
|
|
26655
|
+
*/
|
|
26656
|
+
async getWorkflowPolicy(orgId, opts = {}) {
|
|
26657
|
+
const qs = opts.effective ? "?effective=true" : "";
|
|
26658
|
+
return this.httpGet(`/admin/orgs/${encodeURIComponent(orgId)}/workflow-policy${qs}`, await this.auth());
|
|
26659
|
+
}
|
|
26660
|
+
/**
|
|
26661
|
+
* §6.5 — PATCH the `models` block. Only the members the caller named are sent, so a `set` of one field
|
|
26662
|
+
* never clears the rest; the server validates against the organization's effective model set and refuses
|
|
26663
|
+
* with a code the CLI prints verbatim (a class with no eligible row, a cap the raise would exceed).
|
|
26664
|
+
*/
|
|
26665
|
+
async patchWorkflowPolicyModels(orgId, models) {
|
|
26666
|
+
return this.httpPatch(`/admin/orgs/${encodeURIComponent(orgId)}/workflow-policy`, {
|
|
26667
|
+
models
|
|
26668
|
+
}, await this.auth());
|
|
26669
|
+
}
|
|
26670
|
+
// ─── [WMC-A6] Autonomy — the pre-consented envelope (research §H3) ───
|
|
26671
|
+
/**
|
|
26672
|
+
* PATCH the `autonomy` block of the ORGANIZATION's policy — the same R23 route the `models` block uses, and
|
|
26673
|
+
* a sibling of it in the body, so one PATCH never has to carry two blocks it did not mean to touch.
|
|
26674
|
+
*
|
|
26675
|
+
* A member sent as `null` is CLEARED (`--clear`); a member omitted is left exactly as it was. That
|
|
26676
|
+
* distinction is the route's, not the CLI's — which is why the patch type carries `null` rather than the CLI
|
|
26677
|
+
* collapsing it to an absent key on the way out.
|
|
26678
|
+
*
|
|
26679
|
+
* Every ceiling is the server's: `caps.maxCreditsPerRun`, the organization's own `models.consentActions` and
|
|
26680
|
+
* the platform's runs-per-hour env are all figures this client has never seen, so a value above one comes
|
|
26681
|
+
* back as a typed 400 and is printed verbatim.
|
|
26682
|
+
*/
|
|
26683
|
+
async patchWorkflowPolicyAutonomy(orgId, autonomy) {
|
|
26684
|
+
return this.httpPatch(`/admin/orgs/${encodeURIComponent(orgId)}/workflow-policy`, {
|
|
26685
|
+
autonomy
|
|
26686
|
+
}, await this.auth());
|
|
26687
|
+
}
|
|
26688
|
+
/*
|
|
26689
|
+
* There is deliberately NO per-agent writer here. `SubAgentWorkflowSettings.autonomy` is read by
|
|
26690
|
+
* `effectiveWorkflowAutonomy`, but no HTTP surface writes it: `UpdateSubAgentRequestDto` has no
|
|
26691
|
+
* `workflows` member, so a PATCH carrying one is accepted and DISCARDED. A client method that posted a
|
|
26692
|
+
* narrowing into that hole would return 200 and change nothing, and the CLI would print a success line
|
|
26693
|
+
* over it — on a consent surface, a false confirmation is worse than a missing feature. The read half
|
|
26694
|
+
* already works: `?effective=true` shows a per-agent narrowing when the projection carries one.
|
|
26695
|
+
*/
|
|
26696
|
+
/**
|
|
26697
|
+
* §6.5 — clear a run gate by kind. `model_policy` is the kind a class request that could not be resolved
|
|
26698
|
+
* parks on; the sweep clears it on its own when the switch returns, and this is the by-hand path.
|
|
26699
|
+
*/
|
|
26700
|
+
async clearRunGate(runId, kind) {
|
|
26701
|
+
return this.httpPost(`${this.runs}/${runId}/clear-gate`, {
|
|
26702
|
+
kind
|
|
26703
|
+
}, await this.auth());
|
|
26704
|
+
}
|
|
26705
|
+
/**
|
|
26706
|
+
* §6.4 (Q19) — the deterministic rewrite of a dynamic parent's stored task classes into `class/<c>`.
|
|
26707
|
+
* Not a fresh model composition: the server rewrites and publishes a NEW version on the immutable parent,
|
|
26708
|
+
* and answers with it, so the CLI only has to print the version it got back.
|
|
26709
|
+
*/
|
|
26710
|
+
async recomposeWorkflow(workflowId) {
|
|
26711
|
+
return this.httpPost(`${this.base}/${workflowId}/recompose`, {}, await this.auth());
|
|
26712
|
+
}
|
|
26433
26713
|
};
|
|
26434
26714
|
}
|
|
26435
26715
|
});
|
|
@@ -35510,7 +35790,11 @@ function createSandbox(options) {
|
|
|
35510
35790
|
channel: options.channel ?? "unknown",
|
|
35511
35791
|
webhook: options.webhookPayload ? {
|
|
35512
35792
|
payload: options.webhookPayload
|
|
35513
|
-
} : void 0
|
|
35793
|
+
} : void 0,
|
|
35794
|
+
runtimeContext: options.runtimeContext,
|
|
35795
|
+
threadId: options.threadId,
|
|
35796
|
+
timezone: options.timezone,
|
|
35797
|
+
agentId: options.agentId
|
|
35514
35798
|
}
|
|
35515
35799
|
},
|
|
35516
35800
|
User: userService,
|
|
@@ -36059,6 +36343,117 @@ __name(describeEnvOverlay, "describeEnvOverlay");
|
|
|
36059
36343
|
|
|
36060
36344
|
// src/primitives/workflow.handler.ts
|
|
36061
36345
|
init_base_handler();
|
|
36346
|
+
|
|
36347
|
+
// src/interfaces/workflow-model-classes.ts
|
|
36348
|
+
init_dist();
|
|
36349
|
+
var has = /* @__PURE__ */ __name((tuple, v) => tuple.includes(v), "has");
|
|
36350
|
+
var isWorkflowModelClass = /* @__PURE__ */ __name((v) => has(WORKFLOW_MODEL_CLASSES, v), "isWorkflowModelClass");
|
|
36351
|
+
var isWorkflowTaskClass = /* @__PURE__ */ __name((v) => has(WORKFLOW_TASK_CLASSES, v), "isWorkflowTaskClass");
|
|
36352
|
+
var isWorkflowModelTrait = /* @__PURE__ */ __name((v) => has(WORKFLOW_MODEL_TRAITS, v), "isWorkflowModelTrait");
|
|
36353
|
+
var isWorkflowEffort = /* @__PURE__ */ __name((v) => has(WORKFLOW_AGENT_EFFORTS, v), "isWorkflowEffort");
|
|
36354
|
+
function isWrittenAsModelClassRef(model) {
|
|
36355
|
+
return (model ?? "").trim().toLowerCase().startsWith(MODEL_CLASS_REF_PREFIX);
|
|
36356
|
+
}
|
|
36357
|
+
__name(isWrittenAsModelClassRef, "isWrittenAsModelClassRef");
|
|
36358
|
+
var oneOf = /* @__PURE__ */ __name((tuple) => tuple.map((v) => `\`${v}\``).join(", "), "oneOf");
|
|
36359
|
+
function validateAgentNodeModelMembers(node, path26) {
|
|
36360
|
+
const issues = [];
|
|
36361
|
+
if (typeof node.model === "string" && isWrittenAsModelClassRef(node.model)) {
|
|
36362
|
+
if (!modelClassOf(node.model)) {
|
|
36363
|
+
issues.push({
|
|
36364
|
+
path: `${path26}.model`,
|
|
36365
|
+
code: "model-class-unknown",
|
|
36366
|
+
message: `"${node.model}" is not a model class \u2014 use one of ${oneOf(WORKFLOW_MODEL_CLASSES.map((c) => modelClassRef(c)))}, or pin an approved model code`
|
|
36367
|
+
});
|
|
36368
|
+
}
|
|
36369
|
+
}
|
|
36370
|
+
if (node.taskClass !== void 0) {
|
|
36371
|
+
if (typeof node.taskClass !== "string" || !isWorkflowTaskClass(node.taskClass)) {
|
|
36372
|
+
issues.push({
|
|
36373
|
+
path: `${path26}.taskClass`,
|
|
36374
|
+
code: "task-class-unknown",
|
|
36375
|
+
message: `"${String(node.taskClass)}" is not a task class \u2014 use one of ${oneOf(WORKFLOW_TASK_CLASSES)}`
|
|
36376
|
+
});
|
|
36377
|
+
}
|
|
36378
|
+
}
|
|
36379
|
+
if (node.requires !== void 0) {
|
|
36380
|
+
if (!Array.isArray(node.requires)) {
|
|
36381
|
+
issues.push({
|
|
36382
|
+
path: `${path26}.requires`,
|
|
36383
|
+
code: "requires-invalid",
|
|
36384
|
+
message: `\`requires\` must be an array of ${oneOf(WORKFLOW_MODEL_TRAITS)}`
|
|
36385
|
+
});
|
|
36386
|
+
} else {
|
|
36387
|
+
node.requires.forEach((trait, i) => {
|
|
36388
|
+
if (typeof trait !== "string" || !isWorkflowModelTrait(trait)) {
|
|
36389
|
+
issues.push({
|
|
36390
|
+
path: `${path26}.requires.${i}`,
|
|
36391
|
+
code: "model-trait-unknown",
|
|
36392
|
+
message: `"${String(trait)}" is not a model trait \u2014 use one of ${oneOf(WORKFLOW_MODEL_TRAITS)}`
|
|
36393
|
+
});
|
|
36394
|
+
}
|
|
36395
|
+
});
|
|
36396
|
+
}
|
|
36397
|
+
}
|
|
36398
|
+
if (node.effort !== void 0) {
|
|
36399
|
+
if (typeof node.effort !== "string" || !isWorkflowEffort(node.effort)) {
|
|
36400
|
+
issues.push({
|
|
36401
|
+
path: `${path26}.effort`,
|
|
36402
|
+
code: "effort-unknown",
|
|
36403
|
+
message: `"${String(node.effort)}" is not a workflow effort \u2014 use one of ${oneOf(WORKFLOW_AGENT_EFFORTS)}. (\`off\`, \`minimal\` and \`max\` are the agent-level \`modelSettings.reasoning.effort\` scale, not this one.)`
|
|
36404
|
+
});
|
|
36405
|
+
}
|
|
36406
|
+
}
|
|
36407
|
+
if (node.modelReason !== void 0) {
|
|
36408
|
+
if (typeof node.modelReason !== "string") {
|
|
36409
|
+
issues.push({
|
|
36410
|
+
path: `${path26}.modelReason`,
|
|
36411
|
+
code: "model-reason-invalid",
|
|
36412
|
+
message: "`modelReason` must be a string"
|
|
36413
|
+
});
|
|
36414
|
+
} else if (node.modelReason.length > WORKFLOW_MODEL_REASON_MAX_LENGTH) {
|
|
36415
|
+
issues.push({
|
|
36416
|
+
path: `${path26}.modelReason`,
|
|
36417
|
+
code: "model-reason-too-long",
|
|
36418
|
+
message: `\`modelReason\` is ${node.modelReason.length} characters \u2014 the cap is ${WORKFLOW_MODEL_REASON_MAX_LENGTH}`
|
|
36419
|
+
});
|
|
36420
|
+
}
|
|
36421
|
+
}
|
|
36422
|
+
return issues;
|
|
36423
|
+
}
|
|
36424
|
+
__name(validateAgentNodeModelMembers, "validateAgentNodeModelMembers");
|
|
36425
|
+
var WORKFLOW_MODEL_WALK_MAX_DEPTH = 64;
|
|
36426
|
+
var MEMBERS = [
|
|
36427
|
+
"model",
|
|
36428
|
+
"taskClass",
|
|
36429
|
+
"requires",
|
|
36430
|
+
"effort",
|
|
36431
|
+
"modelReason"
|
|
36432
|
+
];
|
|
36433
|
+
function validateGraphModelMembers(graph) {
|
|
36434
|
+
const issues = [];
|
|
36435
|
+
const seen = /* @__PURE__ */ new Set();
|
|
36436
|
+
const walk3 = /* @__PURE__ */ __name((value3, path26, depth) => {
|
|
36437
|
+
if (depth > WORKFLOW_MODEL_WALK_MAX_DEPTH || value3 === null || typeof value3 !== "object") return;
|
|
36438
|
+
if (seen.has(value3)) return;
|
|
36439
|
+
seen.add(value3);
|
|
36440
|
+
if (Array.isArray(value3)) {
|
|
36441
|
+
value3.forEach((v, i) => walk3(v, `${path26}.${i}`, depth + 1));
|
|
36442
|
+
return;
|
|
36443
|
+
}
|
|
36444
|
+
const node = value3;
|
|
36445
|
+
if (MEMBERS.some((m) => node[m] !== void 0)) {
|
|
36446
|
+
const label2 = typeof node.id === "string" && node.id ? node.id : path26;
|
|
36447
|
+
issues.push(...validateAgentNodeModelMembers(node, label2));
|
|
36448
|
+
}
|
|
36449
|
+
for (const [k, v] of Object.entries(node)) walk3(v, path26 ? `${path26}.${k}` : k, depth + 1);
|
|
36450
|
+
}, "walk");
|
|
36451
|
+
walk3(graph, "", 0);
|
|
36452
|
+
return issues;
|
|
36453
|
+
}
|
|
36454
|
+
__name(validateGraphModelMembers, "validateGraphModelMembers");
|
|
36455
|
+
|
|
36456
|
+
// src/primitives/workflow.handler.ts
|
|
36062
36457
|
var WorkflowHandler = class extends BaseVersionedHandler {
|
|
36063
36458
|
static {
|
|
36064
36459
|
__name(this, "WorkflowHandler");
|
|
@@ -36143,6 +36538,8 @@ var WorkflowHandler = class extends BaseVersionedHandler {
|
|
|
36143
36538
|
const primitive = findPrimitive(manifest, name, this.kind);
|
|
36144
36539
|
if (!primitive) return null;
|
|
36145
36540
|
if (primitive.unplacedStepIds?.length) throw unplacedStepError(primitive.name, primitive.unplacedStepIds);
|
|
36541
|
+
const modelIssues = validateGraphModelMembers(primitive.form === "script" ? primitive.meta : primitive.graph);
|
|
36542
|
+
if (modelIssues.length) throw workflowModelMemberError(primitive.name, modelIssues);
|
|
36146
36543
|
if (primitive.form === "script") return this.buildPushData(primitive, void 0);
|
|
36147
36544
|
const data = super.prepareForPush(manifest, name, projectPath, bundleAccumulator);
|
|
36148
36545
|
if (!data) return null;
|
|
@@ -36289,6 +36686,17 @@ function workflowNameTakenHint(name, error) {
|
|
|
36289
36686
|
return `workflow name "${name}" is held by ${holder}${id} \u2014 ${see}. Push does not replace it: rename this workflow, or delete the other one first.`;
|
|
36290
36687
|
}
|
|
36291
36688
|
__name(workflowNameTakenHint, "workflowNameTakenHint");
|
|
36689
|
+
function workflowModelMemberError(workflowName, issues) {
|
|
36690
|
+
return new CliError("error", `workflow "${workflowName}" is not pushed: ${issues.length} model-selection ${issues.length === 1 ? "value is" : "values are"} not in the vocabulary`, {
|
|
36691
|
+
issues: issues.map((i) => ({
|
|
36692
|
+
path: i.path,
|
|
36693
|
+
code: i.code,
|
|
36694
|
+
message: i.message
|
|
36695
|
+
})),
|
|
36696
|
+
hint: "Fix the values above and push again. Model classes are `class/fast`, `class/balanced` and `class/strong`; a concrete model code is checked by the server against your organization\u2019s approved models."
|
|
36697
|
+
});
|
|
36698
|
+
}
|
|
36699
|
+
__name(workflowModelMemberError, "workflowModelMemberError");
|
|
36292
36700
|
|
|
36293
36701
|
// src/primitives/index.ts
|
|
36294
36702
|
init_skill_handler();
|
|
@@ -36946,10 +37354,20 @@ var ALIAS_MAP = {
|
|
|
36946
37354
|
"jobs",
|
|
36947
37355
|
"job-logs",
|
|
36948
37356
|
"goals",
|
|
36949
|
-
"schedules"
|
|
37357
|
+
"schedules",
|
|
37358
|
+
// [WMC-E7] per-step model selection (§6.5, §6.7): the org's model policy, the `model_policy` gate,
|
|
37359
|
+
// and the deterministic rewrite of a definition composed before class resolution existed.
|
|
37360
|
+
"policy",
|
|
37361
|
+
"clear-gate",
|
|
37362
|
+
"recompose"
|
|
36950
37363
|
],
|
|
36951
37364
|
aliases: lowerKeys({
|
|
36952
37365
|
goal: "goals",
|
|
37366
|
+
policies: "policy",
|
|
37367
|
+
cleargate: "clear-gate",
|
|
37368
|
+
"clear-gates": "clear-gate",
|
|
37369
|
+
ungate: "clear-gate",
|
|
37370
|
+
recompile: "recompose",
|
|
36953
37371
|
schedule: "schedules",
|
|
36954
37372
|
sched: "schedules",
|
|
36955
37373
|
ws: "workspace",
|
|
@@ -37765,7 +38183,16 @@ var WORKFLOW_SCRIPT_REPLAY_SOURCE = String.raw`
|
|
|
37765
38183
|
function resolveModel(opts) {
|
|
37766
38184
|
if (opts && opts.model) return opts.model;
|
|
37767
38185
|
var ph = (opts && opts.phase) || currentPhase; var phases = __input.meta && __input.meta.phases;
|
|
37768
|
-
|
|
38186
|
+
var phase;
|
|
38187
|
+
if (ph && Array.isArray(phases)) for (var i = 0; i < phases.length; i++) if (phases[i] && phases[i].title === ph) { phase = phases[i]; break; }
|
|
38188
|
+
if (phase && phase.model) return phase.model;
|
|
38189
|
+
// WMC (plan 6.3 script-form parity): a task class on the call or on its phase resolves to the SAME
|
|
38190
|
+
// class/<c> sentinel the graph form writes, through the org's map on the tick input. No map (every run
|
|
38191
|
+
// before the feature, and every organisation with assignment off) => undefined, exactly as before.
|
|
38192
|
+
// NB: no backticks in this comment - the wrapper source is itself a template literal.
|
|
38193
|
+
var map = __input.modelClassMap;
|
|
38194
|
+
var tc = (opts && opts.taskClass) || (phase && phase.taskClass);
|
|
38195
|
+
if (tc && map && map[tc]) return 'class/' + map[tc];
|
|
37769
38196
|
return undefined;
|
|
37770
38197
|
}
|
|
37771
38198
|
function resolveRole(role) {
|
|
@@ -37957,6 +38384,12 @@ function computeWorkflowProtocolShipWindow(input) {
|
|
|
37957
38384
|
}
|
|
37958
38385
|
__name(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
|
|
37959
38386
|
__name8(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
|
|
38387
|
+
var WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION = 2;
|
|
38388
|
+
function scriptEffortForwardable(journalProtocolVersion) {
|
|
38389
|
+
return typeof journalProtocolVersion === "number" && journalProtocolVersion >= WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION;
|
|
38390
|
+
}
|
|
38391
|
+
__name(scriptEffortForwardable, "scriptEffortForwardable");
|
|
38392
|
+
__name8(scriptEffortForwardable, "scriptEffortForwardable");
|
|
37960
38393
|
function workflowScriptReplaySource(journalProtocolVersion) {
|
|
37961
38394
|
return WORKFLOW_SCRIPT_PROTOCOL_VERSIONS.includes(journalProtocolVersion) ? WORKFLOW_SCRIPT_REPLAY_SOURCES[journalProtocolVersion] : void 0;
|
|
37962
38395
|
}
|
|
@@ -40394,15 +40827,30 @@ function formatPushFailureSummary(failedItems) {
|
|
|
40394
40827
|
return lines.join("\n");
|
|
40395
40828
|
}
|
|
40396
40829
|
__name(formatPushFailureSummary, "formatPushFailureSummary");
|
|
40830
|
+
var MODEL_CLASS_RESOLUTION_OFF_CODES = [
|
|
40831
|
+
"model-class-resolution-off",
|
|
40832
|
+
"MODEL_CLASS_RESOLUTION_OFF"
|
|
40833
|
+
];
|
|
40834
|
+
function isModelClassResolutionOffCode(code) {
|
|
40835
|
+
if (!code) return false;
|
|
40836
|
+
const normal = code.toLowerCase().replace(/[^a-z]+/g, "-");
|
|
40837
|
+
if (MODEL_CLASS_RESOLUTION_OFF_CODES.some((c) => c.toLowerCase() === code.toLowerCase())) return true;
|
|
40838
|
+
const namesModelClass = normal.includes("model-class") || normal.includes("class-resolution");
|
|
40839
|
+
const namesOff = /(^|-)(off|disabled|unavailable|not-enabled)(-|$)/.test(normal);
|
|
40840
|
+
return namesModelClass && namesOff;
|
|
40841
|
+
}
|
|
40842
|
+
__name(isModelClassResolutionOffCode, "isModelClassResolutionOffCode");
|
|
40843
|
+
var MODEL_CLASS_RESOLUTION_OFF_HINT = "Model classes are not enabled on this environment yet \u2014 remove the `class/\u2026` values (pin an approved model code, or drop `model` to run the step on the agent's own model), or ask your administrator to enable them.";
|
|
40397
40844
|
function pushRefusalError(handler, name, result) {
|
|
40398
40845
|
const reason = result.error || "Unknown error";
|
|
40399
40846
|
const isVersionConflict = reason.toLowerCase().includes("already exists");
|
|
40847
|
+
const classResolutionOff = isModelClassResolutionOffCode(result.code) || !!result.issues?.some((i) => isModelClassResolutionOffCode(i.code));
|
|
40400
40848
|
return new CliError("error", `${handler.displayName.toLowerCase()} "${name}" is not pushed: ${reason}`, {
|
|
40401
40849
|
exitCode: CLI_EXIT.ERROR,
|
|
40402
40850
|
statusCode: result.statusCode,
|
|
40403
40851
|
serverCode: result.code,
|
|
40404
40852
|
issues: result.issues,
|
|
40405
|
-
hint: isVersionConflict ? `Version conflict \u2014 this version already exists on the server. Auto-bump: lua push ${handler.kind} --force \xB7 or push all: lua push all --force` : void 0
|
|
40853
|
+
hint: classResolutionOff ? MODEL_CLASS_RESOLUTION_OFF_HINT : isVersionConflict ? `Version conflict \u2014 this version already exists on the server. Auto-bump: lua push ${handler.kind} --force \xB7 or push all: lua push all --force` : void 0
|
|
40406
40854
|
});
|
|
40407
40855
|
}
|
|
40408
40856
|
__name(pushRefusalError, "pushRefusalError");
|
|
@@ -40415,8 +40863,31 @@ function stalePushEntryError(handler, name, entityId, serverMessage) {
|
|
|
40415
40863
|
});
|
|
40416
40864
|
}
|
|
40417
40865
|
__name(stalePushEntryError, "stalePushEntryError");
|
|
40866
|
+
var WORKFLOW_EFFORT_MARKER = 2;
|
|
40867
|
+
function applyEffortMarker(pushData, applyEffort) {
|
|
40868
|
+
if (!applyEffort) return pushData;
|
|
40869
|
+
const graph = pushData.graph;
|
|
40870
|
+
if (!graph || typeof graph !== "object") return pushData;
|
|
40871
|
+
return {
|
|
40872
|
+
...pushData,
|
|
40873
|
+
graph: {
|
|
40874
|
+
...graph,
|
|
40875
|
+
luaWorkflow: WORKFLOW_EFFORT_MARKER
|
|
40876
|
+
}
|
|
40877
|
+
};
|
|
40878
|
+
}
|
|
40879
|
+
__name(applyEffortMarker, "applyEffortMarker");
|
|
40880
|
+
function effortMarkerNotice(cliVersion2, name) {
|
|
40881
|
+
return `
|
|
40882
|
+
\u2699\uFE0F --apply-effort: "${name}" is pushed with per-step effort ENABLED (lua-cli ${cliVersion2}).
|
|
40883
|
+
From this version on, each agent step's \`effort\` is sent to the model instead of only counted in the estimate.
|
|
40884
|
+
Runs already in flight and every version pushed before this one are unaffected \u2014 they keep their own marker.
|
|
40885
|
+
Push without --apply-effort to go back to estimate-only.`;
|
|
40886
|
+
}
|
|
40887
|
+
__name(effortMarkerNotice, "effortMarkerNotice");
|
|
40418
40888
|
|
|
40419
40889
|
// src/commands/push.ts
|
|
40890
|
+
init_package_root();
|
|
40420
40891
|
function getDeployHint(type) {
|
|
40421
40892
|
const deployableMap = {
|
|
40422
40893
|
skill: "lua deploy skill",
|
|
@@ -40436,6 +40907,11 @@ function getDeployHint(type) {
|
|
|
40436
40907
|
};
|
|
40437
40908
|
}
|
|
40438
40909
|
__name(getDeployHint, "getDeployHint");
|
|
40910
|
+
function writePersonaServedHint(version) {
|
|
40911
|
+
writeInfo(`\u{1F4A1} Persona v${version} is now served \u2014 the push published it and pointed the agent at it.`);
|
|
40912
|
+
writeInfo(" Roll back with `lua deploy persona` (pick an earlier version) or `lua persona production deploy --persona-version <n>`.");
|
|
40913
|
+
}
|
|
40914
|
+
__name(writePersonaServedHint, "writePersonaServedHint");
|
|
40439
40915
|
async function promptVersionConfirmOrUpdate(currentVersion) {
|
|
40440
40916
|
console.log(`
|
|
40441
40917
|
Current version: ${currentVersion || "(none - first push)"}`);
|
|
@@ -40607,12 +41083,13 @@ async function pushVersionedPrimitive(handler, options = {}) {
|
|
|
40607
41083
|
if (confirmedVersion !== selected.version) {
|
|
40608
41084
|
handler.updateVersionInYaml(selected.name, confirmedVersion);
|
|
40609
41085
|
}
|
|
41086
|
+
if (options.applyEffort && handler.kind === "workflow") console.log(effortMarkerNotice(getCliVersion(), selected.name));
|
|
40610
41087
|
writeProgress(`
|
|
40611
41088
|
\u{1F680} Pushing ${selected.name} v${confirmedVersion} to server...`);
|
|
40612
|
-
const result = await handler.pushToServer(apiKey, agentId, entityId, {
|
|
41089
|
+
const result = await handler.pushToServer(apiKey, agentId, entityId, applyEffortMarker({
|
|
40613
41090
|
...pushData,
|
|
40614
41091
|
version: confirmedVersion
|
|
40615
|
-
});
|
|
41092
|
+
}, options.applyEffort));
|
|
40616
41093
|
if (!result.success) {
|
|
40617
41094
|
if (result.statusCode === 404) throw stalePushEntryError(handler, selected.name, entityId, result.error);
|
|
40618
41095
|
throw pushRefusalError(handler, selected.name, result);
|
|
@@ -40695,7 +41172,10 @@ async function pushCommand(type, cmdObj) {
|
|
|
40695
41172
|
// Reading with `!== false` makes the programmatic-default-true path
|
|
40696
41173
|
// explicit: when cmdObj is undefined (rare; programmatic invocation)
|
|
40697
41174
|
// we still default to attaching source.
|
|
40698
|
-
includeSource: cmdObj?.includeSource !== false
|
|
41175
|
+
includeSource: cmdObj?.includeSource !== false,
|
|
41176
|
+
// [WMC-E7] §6.9: a PLAIN push must never set the effort marker, so this reads the flag and nothing else —
|
|
41177
|
+
// no env fallback, no inheritance from a previous push.
|
|
41178
|
+
applyEffort: cmdObj?.applyEffort === true
|
|
40699
41179
|
};
|
|
40700
41180
|
let agentOutcome;
|
|
40701
41181
|
let selectedType;
|
|
@@ -40879,6 +41359,7 @@ Until the backup catches up, \`lua init\` for this agent will restore an older s
|
|
|
40879
41359
|
when: "partial"
|
|
40880
41360
|
});
|
|
40881
41361
|
} else if (selectedType === "backup") {
|
|
41362
|
+
} else if (selectedType === "agent") {
|
|
40882
41363
|
} else if (deployHint) {
|
|
40883
41364
|
writeHintBlock({
|
|
40884
41365
|
headline: "Staged but NOT live yet. To make it active:",
|
|
@@ -41016,7 +41497,7 @@ Model: ${model}`);
|
|
|
41016
41497
|
personaDeployWasAttempted = true;
|
|
41017
41498
|
productionDeployedWithAutoDeploy = await deployPersonaVersionAfterPush(apiKey, agentId, result.persona.version, options.autoDeploy || false);
|
|
41018
41499
|
} else {
|
|
41019
|
-
|
|
41500
|
+
writePersonaServedHint(result.persona.version);
|
|
41020
41501
|
}
|
|
41021
41502
|
}
|
|
41022
41503
|
const personaAutoDeployFailed = Boolean(options.autoDeploy && personaDeployEligible && personaDeployWasAttempted && !productionDeployedWithAutoDeploy);
|
|
@@ -41167,6 +41648,11 @@ async function pushAllCommand(options) {
|
|
|
41167
41648
|
webhookHandler,
|
|
41168
41649
|
triggerHandler,
|
|
41169
41650
|
jobHandler,
|
|
41651
|
+
// BAC — workflows were absent here, so `lua push` / `lua push all` never uploaded a changed
|
|
41652
|
+
// workflow (only the deprecated `lua push workflow` did). A published template then froze the
|
|
41653
|
+
// OLD workflow graph while its jobs advanced — an undetectable jobs-vs-workflows version skew.
|
|
41654
|
+
// Workflows ride the same push here; the deploy step below always activates them (see there).
|
|
41655
|
+
workflowHandler,
|
|
41170
41656
|
preprocessorHandler,
|
|
41171
41657
|
postprocessorHandler,
|
|
41172
41658
|
deviceHandler,
|
|
@@ -41198,6 +41684,9 @@ async function pushAllCommand(options) {
|
|
|
41198
41684
|
const icon = kindIcons[handler.kind] || "\u{1F4E6}";
|
|
41199
41685
|
writeProgress(`
|
|
41200
41686
|
${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
41687
|
+
if (options.applyEffort && handler.kind === "workflow") {
|
|
41688
|
+
console.log(effortMarkerNotice(getCliVersion(), `${items.length} workflow(s)`));
|
|
41689
|
+
}
|
|
41201
41690
|
const handlerVersions = versionLookup.get(handler);
|
|
41202
41691
|
for (const item of items) {
|
|
41203
41692
|
try {
|
|
@@ -41226,20 +41715,20 @@ ${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
|
41226
41715
|
const baseVersion = serverHighest ? maxSemver(item.version, serverHighest) : item.version;
|
|
41227
41716
|
let newVersion = incrementPatchVersion(baseVersion);
|
|
41228
41717
|
writeInfo(` \u{1F4DD} ${item.name}: ${item.version} \u2192 ${newVersion}`);
|
|
41229
|
-
let result = await handler.pushToServer(apiKey, agentId, entityId, {
|
|
41718
|
+
let result = await handler.pushToServer(apiKey, agentId, entityId, applyEffortMarker({
|
|
41230
41719
|
...pushData,
|
|
41231
41720
|
version: newVersion
|
|
41232
|
-
});
|
|
41721
|
+
}, options.applyEffort));
|
|
41233
41722
|
if (!result.success && result.error?.toLowerCase().includes("already exists")) {
|
|
41234
41723
|
console.log(` \u26A0\uFE0F Version collision on ${item.name}, refetching server state and retrying...`);
|
|
41235
41724
|
const freshHighest = await handler.getHighestServerVersion(apiKey, agentId, entityId);
|
|
41236
41725
|
if (freshHighest) {
|
|
41237
41726
|
const retryVersion = incrementPatchVersion(freshHighest);
|
|
41238
41727
|
writeInfo(` \u{1F4DD} ${item.name}: re-bumped ${newVersion} \u2192 ${retryVersion} after collision`);
|
|
41239
|
-
result = await handler.pushToServer(apiKey, agentId, entityId, {
|
|
41728
|
+
result = await handler.pushToServer(apiKey, agentId, entityId, applyEffortMarker({
|
|
41240
41729
|
...pushData,
|
|
41241
41730
|
version: retryVersion
|
|
41242
|
-
});
|
|
41731
|
+
}, options.applyEffort));
|
|
41243
41732
|
if (result.success) {
|
|
41244
41733
|
newVersion = retryVersion;
|
|
41245
41734
|
}
|
|
@@ -41264,7 +41753,7 @@ ${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
|
41264
41753
|
entityId
|
|
41265
41754
|
});
|
|
41266
41755
|
writeSuccess(` \u2705 ${item.name} v${newVersion} pushed`);
|
|
41267
|
-
if (options.autoDeploy) {
|
|
41756
|
+
if (options.autoDeploy || handler.kind === PrimitiveKind.WORKFLOW) {
|
|
41268
41757
|
toDeploy.push({
|
|
41269
41758
|
handler,
|
|
41270
41759
|
name: item.name,
|
|
@@ -41316,11 +41805,11 @@ ${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
|
41316
41805
|
};
|
|
41317
41806
|
}
|
|
41318
41807
|
if (personaPushResult && !options.autoDeploy) {
|
|
41319
|
-
|
|
41320
|
-
writeInfo(" Run `lua deploy` or re-push with `--auto-deploy` to activate it.");
|
|
41808
|
+
writePersonaServedHint(personaPushResult.version);
|
|
41321
41809
|
}
|
|
41322
|
-
if (
|
|
41323
|
-
|
|
41810
|
+
if (toDeploy.length > 0) {
|
|
41811
|
+
const workflowsOnly = !options.autoDeploy;
|
|
41812
|
+
writeProgress(workflowsOnly ? "\n\u{1F680} Activating workflow version(s) \u2014 workflows deploy on their own, not via `lua version promote`..." : "\n\u{1F680} Deploying all pushed versions to production...");
|
|
41324
41813
|
writeInfo("\u23F1\uFE0F Waiting for server to process versions (5 seconds)...\n");
|
|
41325
41814
|
await new Promise((resolve7) => setTimeout(resolve7, 5e3));
|
|
41326
41815
|
for (const item of toDeploy) {
|
|
@@ -51762,6 +52251,30 @@ init_constants();
|
|
|
51762
52251
|
init_command_utils();
|
|
51763
52252
|
init_analytics();
|
|
51764
52253
|
init_workflow_api_service();
|
|
52254
|
+
|
|
52255
|
+
// src/interfaces/workflow-autonomy.ts
|
|
52256
|
+
init_dist();
|
|
52257
|
+
var has2 = /* @__PURE__ */ __name((tuple, v) => tuple.includes(v), "has");
|
|
52258
|
+
var isWorkflowAutonomyForm = /* @__PURE__ */ __name((v) => has2(WORKFLOW_AUTONOMY_FORMS, v), "isWorkflowAutonomyForm");
|
|
52259
|
+
var kebab = /* @__PURE__ */ __name((key) => key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), "kebab");
|
|
52260
|
+
var WORKFLOW_AUTONOMY_CLEAR_KEYS = WORKFLOW_AUTONOMY_ENVELOPE_KEYS.map((k) => kebab(k).replace(/-seconds$/, ""));
|
|
52261
|
+
var CLEAR_ALIASES = Object.freeze(Object.fromEntries(WORKFLOW_AUTONOMY_ENVELOPE_KEYS.flatMap((key) => {
|
|
52262
|
+
const flag = kebab(key).replace(/-seconds$/, "");
|
|
52263
|
+
return [
|
|
52264
|
+
flag,
|
|
52265
|
+
kebab(key),
|
|
52266
|
+
key.toLowerCase()
|
|
52267
|
+
].map((alias) => [
|
|
52268
|
+
alias,
|
|
52269
|
+
key
|
|
52270
|
+
]);
|
|
52271
|
+
})));
|
|
52272
|
+
function autonomyClearKey(raw) {
|
|
52273
|
+
return CLEAR_ALIASES[raw.trim().toLowerCase()];
|
|
52274
|
+
}
|
|
52275
|
+
__name(autonomyClearKey, "autonomyClearKey");
|
|
52276
|
+
|
|
52277
|
+
// src/commands/workflows.ts
|
|
51765
52278
|
init_artifact_loader();
|
|
51766
52279
|
init_types();
|
|
51767
52280
|
init_dist2();
|
|
@@ -51905,6 +52418,7 @@ function exitCodeForRunStatus(status) {
|
|
|
51905
52418
|
if (status === "completed") return WORKFLOW_EXIT.OK;
|
|
51906
52419
|
if (TERMINAL_FAILED.has(status)) return WORKFLOW_EXIT.RUN_FAILED;
|
|
51907
52420
|
if (TERMINAL_CANCELLED.has(status)) return WORKFLOW_EXIT.RUN_CANCELLED;
|
|
52421
|
+
if (status === "gated") return WORKFLOW_EXIT.RUN_GATED;
|
|
51908
52422
|
return void 0;
|
|
51909
52423
|
}
|
|
51910
52424
|
__name(exitCodeForRunStatus, "exitCodeForRunStatus");
|
|
@@ -51956,11 +52470,12 @@ async function workflowsCommand(action, target, extra, cmdObj) {
|
|
|
51956
52470
|
});
|
|
51957
52471
|
return;
|
|
51958
52472
|
}
|
|
51959
|
-
const { agentId, apiKey } = await initializeCommand({
|
|
52473
|
+
const { agentId, orgId, apiKey } = await initializeCommand({
|
|
51960
52474
|
showProgress: !json
|
|
51961
52475
|
});
|
|
51962
52476
|
const ctx = {
|
|
51963
52477
|
agentId,
|
|
52478
|
+
orgId,
|
|
51964
52479
|
apiKey,
|
|
51965
52480
|
api: new WorkflowApi(BASE_URLS.API, apiKey, agentId),
|
|
51966
52481
|
json
|
|
@@ -52075,6 +52590,15 @@ async function executeAction(ctx, action, target, extra, o) {
|
|
|
52075
52590
|
// ── schedules <list|create|patch|pause|resume|delete> (LUA-627 reads + R28; LUA-752 R27 / R56; goal-owned rows refuse) ──
|
|
52076
52591
|
case "schedules":
|
|
52077
52592
|
return schedulesCore(ctx, target, extra, o);
|
|
52593
|
+
// ── policy models <get|set> ([WMC-E7] — §6.5; the org's `models` block) ──
|
|
52594
|
+
case "policy":
|
|
52595
|
+
return policyCore(ctx, target, extra, o);
|
|
52596
|
+
// ── clear-gate ([WMC-E7] — §6.5; `resume` stays the `kind:'input'` resume) ──
|
|
52597
|
+
case "clear-gate":
|
|
52598
|
+
return requireRun(runId, "clear-gate", () => clearGateCore(ctx, runId, o));
|
|
52599
|
+
// ── recompose ([WMC-E7] — §6.4 Q19; a deterministic rewrite, never a fresh composition) ──
|
|
52600
|
+
case "recompose":
|
|
52601
|
+
return requireName(name, "recompose", () => recomposeCore(ctx, name, o));
|
|
52078
52602
|
case "run":
|
|
52079
52603
|
return WORKFLOW_EXIT.OK;
|
|
52080
52604
|
}
|
|
@@ -52258,6 +52782,8 @@ async function viewCore(ctx, name) {
|
|
|
52258
52782
|
if (active?.envTemplateKeys?.length) {
|
|
52259
52783
|
console.log(` Env overlay: ${active.envTemplateKeys.join(", ")}${active.envOverlayHash ? ` \xB7 ${active.envOverlayHash}` : ""}`);
|
|
52260
52784
|
}
|
|
52785
|
+
const agentModels = agentModelsBlock(active?.agentModels);
|
|
52786
|
+
if (agentModels) console.log(agentModels);
|
|
52261
52787
|
printViewSchedules(sched);
|
|
52262
52788
|
printViewGoals(goals);
|
|
52263
52789
|
printVersions(w.versions ?? [], w.activeVersionId);
|
|
@@ -52443,6 +52969,11 @@ async function startCore(ctx, name, o) {
|
|
|
52443
52969
|
const { runId, status } = res.data;
|
|
52444
52970
|
if (!ctx.json) {
|
|
52445
52971
|
writeSuccess(startResultLine(res.data, wf.name));
|
|
52972
|
+
const card = consentCardLines(res.data.modelConsent);
|
|
52973
|
+
if (card.length) {
|
|
52974
|
+
console.log("");
|
|
52975
|
+
for (const line of card) console.log(line);
|
|
52976
|
+
}
|
|
52446
52977
|
if (status === "gated" && !o.follow) {
|
|
52447
52978
|
writeInfo("\u23F8\uFE0F The run is gated awaiting consent \u2014 approve it from the desktop or: lua workflows status " + runId);
|
|
52448
52979
|
}
|
|
@@ -52596,6 +53127,131 @@ function budgetLine(run) {
|
|
|
52596
53127
|
return `${parts.join(" \xB7 ")} (${budgetCopy(run)})`;
|
|
52597
53128
|
}
|
|
52598
53129
|
__name(budgetLine, "budgetLine");
|
|
53130
|
+
function autonomyDurationLabel(seconds) {
|
|
53131
|
+
if (!Number.isFinite(seconds) || seconds < 0) return `${seconds} s`;
|
|
53132
|
+
if (seconds >= 86400 && seconds % 86400 === 0) return `${fmtNum(seconds / 86400)} d`;
|
|
53133
|
+
if (seconds >= 3600 && seconds % 3600 === 0) return `${fmtNum(seconds / 3600)} h`;
|
|
53134
|
+
if (seconds >= 60 && seconds % 60 === 0) return `${fmtNum(seconds / 60)} m`;
|
|
53135
|
+
return `${fmtNum(seconds)} s`;
|
|
53136
|
+
}
|
|
53137
|
+
__name(autonomyDurationLabel, "autonomyDurationLabel");
|
|
53138
|
+
function autonomyEnvelopeSummary(envelope) {
|
|
53139
|
+
if (!envelope) return void 0;
|
|
53140
|
+
const parts = [
|
|
53141
|
+
envelope.maxCredits !== void 0 ? `${fmtNum(envelope.maxCredits)} credits` : void 0,
|
|
53142
|
+
envelope.maxSteps !== void 0 ? `${fmtNum(envelope.maxSteps)} steps` : void 0,
|
|
53143
|
+
envelope.maxDurationSeconds !== void 0 ? autonomyDurationLabel(envelope.maxDurationSeconds) : void 0
|
|
53144
|
+
].filter((p) => !!p);
|
|
53145
|
+
return parts.length ? `\u2264 ${parts.join(" \xB7 ")}` : void 0;
|
|
53146
|
+
}
|
|
53147
|
+
__name(autonomyEnvelopeSummary, "autonomyEnvelopeSummary");
|
|
53148
|
+
var CONSENT_VIA_AUTONOMY = "autonomy";
|
|
53149
|
+
function consentLine(consent) {
|
|
53150
|
+
if (consent?.via !== CONSENT_VIA_AUTONOMY) return void 0;
|
|
53151
|
+
const envelope = autonomyEnvelopeSummary(consent.envelope);
|
|
53152
|
+
return `auto (policy)${envelope ? ` \u2014 ${envelope}` : ""}`;
|
|
53153
|
+
}
|
|
53154
|
+
__name(consentLine, "consentLine");
|
|
53155
|
+
var dash = /* @__PURE__ */ __name((v) => v === void 0 || v === null || v === "" ? "\u2014" : String(v), "dash");
|
|
53156
|
+
function agentModelRow(s) {
|
|
53157
|
+
const effort = s.effort === void 0 ? "\u2014" : s.effortApplied === false ? `${s.effort} (not applied)` : String(s.effort);
|
|
53158
|
+
const requested = s.requires?.length ? `${dash(s.modelRequested)} +${s.requires.join(",")}` : dash(s.modelRequested);
|
|
53159
|
+
return [
|
|
53160
|
+
s.stepId,
|
|
53161
|
+
dash(s.taskClass),
|
|
53162
|
+
requested,
|
|
53163
|
+
dash(s.modelResolved),
|
|
53164
|
+
effort,
|
|
53165
|
+
dash(s.modelReason)
|
|
53166
|
+
];
|
|
53167
|
+
}
|
|
53168
|
+
__name(agentModelRow, "agentModelRow");
|
|
53169
|
+
function agentModelsBlock(steps) {
|
|
53170
|
+
if (!steps?.length) return void 0;
|
|
53171
|
+
const rows3 = steps.map(agentModelRow);
|
|
53172
|
+
const anyUnapplied = steps.some((s) => s.effort !== void 0 && s.effortApplied === false);
|
|
53173
|
+
const table = renderTable([
|
|
53174
|
+
"Step",
|
|
53175
|
+
"Task class",
|
|
53176
|
+
"Requested",
|
|
53177
|
+
"Resolves to today",
|
|
53178
|
+
"Effort",
|
|
53179
|
+
"Reason"
|
|
53180
|
+
], rows3);
|
|
53181
|
+
const note = anyUnapplied ? '\n\u{1F4A1} An effort marked "(not applied)" is recorded and counted in the estimate but not sent to the model. `lua push --apply-effort` applies it from the next push.' : "";
|
|
53182
|
+
return `
|
|
53183
|
+
\u{1F916} Agent steps
|
|
53184
|
+
${table}${note}`;
|
|
53185
|
+
}
|
|
53186
|
+
__name(agentModelsBlock, "agentModelsBlock");
|
|
53187
|
+
function modelRollupRows(run, steps) {
|
|
53188
|
+
const projected = run.usage?.byModel;
|
|
53189
|
+
if (projected?.length) return [
|
|
53190
|
+
...projected
|
|
53191
|
+
];
|
|
53192
|
+
const folded = /* @__PURE__ */ new Map();
|
|
53193
|
+
for (const s of steps ?? []) {
|
|
53194
|
+
const b = s.billing;
|
|
53195
|
+
if (!b?.model) continue;
|
|
53196
|
+
const row2 = folded.get(b.model) ?? {
|
|
53197
|
+
model: b.model,
|
|
53198
|
+
calls: 0
|
|
53199
|
+
};
|
|
53200
|
+
row2.calls = (row2.calls ?? 0) + 1;
|
|
53201
|
+
if (b.credits !== void 0) row2.credits = (row2.credits ?? 0) + b.credits;
|
|
53202
|
+
if (b.actions !== void 0) row2.actions = (row2.actions ?? 0) + b.actions;
|
|
53203
|
+
folded.set(b.model, row2);
|
|
53204
|
+
}
|
|
53205
|
+
return [
|
|
53206
|
+
...folded.values()
|
|
53207
|
+
].sort((a, b) => (b.actions ?? b.credits ?? 0) - (a.actions ?? a.credits ?? 0));
|
|
53208
|
+
}
|
|
53209
|
+
__name(modelRollupRows, "modelRollupRows");
|
|
53210
|
+
function modelRollupBlock(run, steps) {
|
|
53211
|
+
const rows3 = modelRollupRows(run, steps);
|
|
53212
|
+
if (!rows3.length) return void 0;
|
|
53213
|
+
const seat = run.usage?.engine === "seat" || rows3.some((r) => r.actions !== void 0);
|
|
53214
|
+
const unit = seat ? "Actions" : "Credits";
|
|
53215
|
+
const anyClass = rows3.some((r) => r.class !== void 0);
|
|
53216
|
+
const anyFallback = rows3.some((r) => r.fallbacks !== void 0);
|
|
53217
|
+
const head = [
|
|
53218
|
+
"Model",
|
|
53219
|
+
...anyClass ? [
|
|
53220
|
+
"Class"
|
|
53221
|
+
] : [],
|
|
53222
|
+
"Calls",
|
|
53223
|
+
unit,
|
|
53224
|
+
...anyFallback ? [
|
|
53225
|
+
"Fallbacks"
|
|
53226
|
+
] : []
|
|
53227
|
+
];
|
|
53228
|
+
const body = rows3.map((r) => {
|
|
53229
|
+
const spend = seat ? r.actions : r.credits;
|
|
53230
|
+
return [
|
|
53231
|
+
r.model,
|
|
53232
|
+
...anyClass ? [
|
|
53233
|
+
dash(r.class)
|
|
53234
|
+
] : [],
|
|
53235
|
+
r.calls !== void 0 ? fmtNum(r.calls) : "\u2014",
|
|
53236
|
+
spend !== void 0 ? fmtNum(spend) : "\u2014",
|
|
53237
|
+
...anyFallback ? [
|
|
53238
|
+
r.fallbacks !== void 0 ? fmtNum(r.fallbacks) : "\u2014"
|
|
53239
|
+
] : []
|
|
53240
|
+
];
|
|
53241
|
+
});
|
|
53242
|
+
const derived = !run.usage?.byModel?.length;
|
|
53243
|
+
const note = derived ? "\n (derived from the step receipts \u2014 the run has no roll-up of its own)" : "";
|
|
53244
|
+
return `
|
|
53245
|
+
\u{1F9E0} By model
|
|
53246
|
+
${renderTable(head, body)}${note}`;
|
|
53247
|
+
}
|
|
53248
|
+
__name(modelRollupBlock, "modelRollupBlock");
|
|
53249
|
+
function consentCardLines(consent) {
|
|
53250
|
+
return consent?.card?.length ? [
|
|
53251
|
+
...consent.card
|
|
53252
|
+
] : [];
|
|
53253
|
+
}
|
|
53254
|
+
__name(consentCardLines, "consentCardLines");
|
|
52599
53255
|
function printRun(run, withSteps) {
|
|
52600
53256
|
const id = runIdOf(run);
|
|
52601
53257
|
console.log(`
|
|
@@ -52605,6 +53261,8 @@ function printRun(run, withSteps) {
|
|
|
52605
53261
|
console.log(` Created: ${when2(run.createdAt)}${run.startedAt ? ` \xB7 started ${when2(run.startedAt)}` : ""}${run.completedAt ? ` \xB7 completed ${when2(run.completedAt)}` : ""}`);
|
|
52606
53262
|
if (run.lineageId && run.lineageId !== id) console.log(` Lineage: ${run.lineageId}`);
|
|
52607
53263
|
if (run.parentRunId) console.log(` Parent: ${run.parentRunId} \u2014 lua workflows status ${run.parentRunId} --steps`);
|
|
53264
|
+
const consent = consentLine(run.consent);
|
|
53265
|
+
if (consent) console.log(` Consent: ${consent}`);
|
|
52608
53266
|
const budget = budgetLine(run);
|
|
52609
53267
|
if (budget) console.log(` Budget: ${budget}`);
|
|
52610
53268
|
if (run.cancel) console.log(` Cancel: ${formatRunCancel(run.cancel)}`);
|
|
@@ -52614,13 +53272,17 @@ function printRun(run, withSteps) {
|
|
|
52614
53272
|
console.log(run.status === "running" ? "\n\u26A0\uFE0F Needs a decision \u2014 a step is parked on an exception gate (the run continues past it):" : "\n\u26A0\uFE0F Needs a decision \u2014 the run is parked on an exception gate:");
|
|
52615
53273
|
console.log(` lua workflows retry-step ${id} --step <id>`);
|
|
52616
53274
|
console.log(` lua workflows resolve-step ${id} --step <id> --outcome skip|complete|fail [--output <json|@file>]`);
|
|
52617
|
-
console.log(" To start a repair run instead, decide it from the desktop run page.");
|
|
52618
53275
|
} else if (kind === "budget") {
|
|
52619
53276
|
console.log(`
|
|
52620
53277
|
\u23F8\uFE0F Paused \u2014 run budget reached (${budgetCopy(run)}):`);
|
|
52621
53278
|
console.log(` lua workflows raise-budget ${id} --credits <n>`);
|
|
52622
53279
|
} else if (kind === "billing") {
|
|
52623
53280
|
for (const line of billingParkLines(run)) console.log(line);
|
|
53281
|
+
} else if (kind === "model_policy") {
|
|
53282
|
+
console.log(`
|
|
53283
|
+
\u23F8\uFE0F Paused \u2014 a step's model request cannot be resolved under the current policy:`);
|
|
53284
|
+
if (run.gate?.code) console.log(` ${run.gate.code}${run.gate.stepId ? ` \xB7 step ${run.gate.stepId}` : ""}`);
|
|
53285
|
+
console.log(` lua workflows clear-gate ${id} --kind model_policy`);
|
|
52624
53286
|
} else {
|
|
52625
53287
|
console.log(` Gate: ${kind}${run.gate.reason ? ` (${run.gate.reason})` : ""}${run.gate.since ? ` since ${when2(run.gate.since)}` : ""}`);
|
|
52626
53288
|
}
|
|
@@ -52669,6 +53331,8 @@ function printRun(run, withSteps) {
|
|
|
52669
53331
|
for (const s of steps) for (const line of stepAttemptLines(s)) console.log(line);
|
|
52670
53332
|
}
|
|
52671
53333
|
}
|
|
53334
|
+
const rollup = modelRollupBlock(run, steps);
|
|
53335
|
+
if (rollup) console.log(rollup);
|
|
52672
53336
|
}
|
|
52673
53337
|
__name(printRun, "printRun");
|
|
52674
53338
|
function billingParkLines(run) {
|
|
@@ -52698,6 +53362,8 @@ function stepAttemptLines(s) {
|
|
|
52698
53362
|
if (billed) out.push(` $ ${s.stepId}: attempt ${s.billing?.attempt ?? s.attempt ?? 1} billed: ${billed}`);
|
|
52699
53363
|
const fetchable = outputRefLine(s.outputRef);
|
|
52700
53364
|
if (fetchable) out.push(` \u21E9 ${s.stepId}: ${fetchable}`);
|
|
53365
|
+
const escalated = approverFallbackLine(s);
|
|
53366
|
+
if (escalated) out.push(escalated);
|
|
52701
53367
|
for (const a of s.attempts ?? []) {
|
|
52702
53368
|
if (a.status === "completed") continue;
|
|
52703
53369
|
const what = stepErrorCell(a.error) || a.killReason || "\u2014";
|
|
@@ -52707,6 +53373,13 @@ function stepAttemptLines(s) {
|
|
|
52707
53373
|
return out;
|
|
52708
53374
|
}
|
|
52709
53375
|
__name(stepAttemptLines, "stepAttemptLines");
|
|
53376
|
+
function approverFallbackLine(s) {
|
|
53377
|
+
const f = s.suspend?.approverFallback;
|
|
53378
|
+
if (!f?.from || !f.to) return void 0;
|
|
53379
|
+
const why = f.reason === "initiator_excluded" ? "the initiator is excluded (maker-checker)" : f.reason;
|
|
53380
|
+
return ` \u21C5 ${s.stepId}: approver escalated ${f.from} \u2192 ${f.to}${why ? ` \u2014 ${why}` : ""}`;
|
|
53381
|
+
}
|
|
53382
|
+
__name(approverFallbackLine, "approverFallbackLine");
|
|
52710
53383
|
function outputRefLine(ref) {
|
|
52711
53384
|
if (!ref?.artefactId || !ref.url) return void 0;
|
|
52712
53385
|
const gate = "needs workflows:read-outputs";
|
|
@@ -53138,9 +53811,9 @@ async function retryStepCore(ctx, runId, o) {
|
|
|
53138
53811
|
const cap = res.error;
|
|
53139
53812
|
const at = typeof cap?.attempt === "number" && typeof cap?.maxAttempts === "number" ? ` (attempt ${cap.attempt} of ${cap.maxAttempts})` : "";
|
|
53140
53813
|
detail = {
|
|
53141
|
-
message: `step "${o.step}" has reached the retry cap${at} \u2014 resolve it
|
|
53814
|
+
message: `step "${o.step}" has reached the retry cap${at} \u2014 resolve it (skip, complete or fail)`,
|
|
53142
53815
|
hint: `lua workflows resolve-step ${runId} --step ${o.step} --outcome skip|complete|fail
|
|
53143
|
-
|
|
53816
|
+
no repair run exists \u2014 a run is never re-run from its ledger; if the step cannot be resolved, fail it (--outcome fail) and start a new run`
|
|
53144
53817
|
};
|
|
53145
53818
|
}
|
|
53146
53819
|
}
|
|
@@ -53673,6 +54346,26 @@ async function replayChildRun(ctx, childRunId) {
|
|
|
53673
54346
|
};
|
|
53674
54347
|
}
|
|
53675
54348
|
__name(replayChildRun, "replayChildRun");
|
|
54349
|
+
var WORKFLOW_LOG_EVENT_PATTERN = /progress|log|started|completed|failed|skipped|model_resolved|model_policy_warning/;
|
|
54350
|
+
function modelEventDetail(type, data) {
|
|
54351
|
+
if (type !== "step.model_resolved" && type !== "step.model_policy_warning") return void 0;
|
|
54352
|
+
const d = data ?? {};
|
|
54353
|
+
const nested = d.detail ?? {};
|
|
54354
|
+
const str = /* @__PURE__ */ __name((...vals) => {
|
|
54355
|
+
for (const v of vals) if (typeof v === "string" && v) return v;
|
|
54356
|
+
return void 0;
|
|
54357
|
+
}, "str");
|
|
54358
|
+
const requested = str(d.requested, nested.requested, d.modelRequested, nested.modelRequested);
|
|
54359
|
+
const resolved = str(d.resolved, nested.resolved, d.model, nested.model);
|
|
54360
|
+
if (type === "step.model_resolved") {
|
|
54361
|
+
const cls = requested?.startsWith("class/") ? requested.slice("class/".length) : str(d.taskClass, nested.taskClass);
|
|
54362
|
+
return `model resolved \u2192 ${resolved ?? requested ?? "?"}${cls ? ` (${cls})` : ""}`;
|
|
54363
|
+
}
|
|
54364
|
+
const outcome = str(d.outcome, nested.outcome, d.code, nested.code) ?? "unknown";
|
|
54365
|
+
const detail = str(d.message, nested.message) ?? (requested && resolved && requested !== resolved ? `${requested} \u2192 ${resolved}` : requested ?? resolved);
|
|
54366
|
+
return `model policy warning: ${outcome}${detail ? ` ${detail}` : ""}`;
|
|
54367
|
+
}
|
|
54368
|
+
__name(modelEventDetail, "modelEventDetail");
|
|
53676
54369
|
async function logsCore(ctx, runId, o) {
|
|
53677
54370
|
if (o.follow) return watchCore(ctx, runId, o);
|
|
53678
54371
|
const res = await ctx.api.getRunEvents(runId, {
|
|
@@ -53681,10 +54374,11 @@ async function logsCore(ctx, runId, o) {
|
|
|
53681
54374
|
if (!res.success || !res.data) return apiFailure(ctx, res, "logs");
|
|
53682
54375
|
emitJson(ctx, res);
|
|
53683
54376
|
if (ctx.json) return WORKFLOW_EXIT.OK;
|
|
53684
|
-
const events = (res.data.events ?? []).filter((e) => (!o.step || e.stepId === o.step) &&
|
|
54377
|
+
const events = (res.data.events ?? []).filter((e) => (!o.step || e.stepId === o.step) && WORKFLOW_LOG_EVENT_PATTERN.test(e.type));
|
|
53685
54378
|
if (events.length === 0) console.log("(no log events yet)");
|
|
53686
54379
|
for (const e of events) {
|
|
53687
|
-
const
|
|
54380
|
+
const data = scrubEventData(e.data);
|
|
54381
|
+
const msg = modelEventDetail(e.type, data) ?? data?.message ?? subrunEventDetail(e);
|
|
53688
54382
|
console.log(`[${clockOf(e.ts)}] ${e.type}${e.stepId ? ` \xB7 ${e.stepId}` : ""}${msg ? ` \xB7 ${msg}` : ""}`);
|
|
53689
54383
|
}
|
|
53690
54384
|
return WORKFLOW_EXIT.OK;
|
|
@@ -55376,6 +56070,290 @@ async function schedulesPatchCore(ctx, jobId, verb, o) {
|
|
|
55376
56070
|
return WORKFLOW_EXIT.OK;
|
|
55377
56071
|
}
|
|
55378
56072
|
__name(schedulesPatchCore, "schedulesPatchCore");
|
|
56073
|
+
function csvFlag(raw) {
|
|
56074
|
+
if (raw === void 0) return void 0;
|
|
56075
|
+
const parts = (Array.isArray(raw) ? raw : [
|
|
56076
|
+
raw
|
|
56077
|
+
]).flatMap((v) => String(v).split(","));
|
|
56078
|
+
const out = parts.map((v) => v.trim()).filter((v) => v.length > 0);
|
|
56079
|
+
return out;
|
|
56080
|
+
}
|
|
56081
|
+
__name(csvFlag, "csvFlag");
|
|
56082
|
+
function badFlagValue(flag, value3, allowed) {
|
|
56083
|
+
return CliError.usage(`${flag}: "${value3}" is not a valid value`, `${flag} takes one of ${allowed.map((v) => `\`${v}\``).join(", ")}`);
|
|
56084
|
+
}
|
|
56085
|
+
__name(badFlagValue, "badFlagValue");
|
|
56086
|
+
function buildModelsPolicyPatch(o) {
|
|
56087
|
+
const patch = {};
|
|
56088
|
+
if (o.compose !== void 0) {
|
|
56089
|
+
const v = String(o.compose);
|
|
56090
|
+
if (!WORKFLOW_MODELS_COMPOSE_MODES.includes(v)) throw badFlagValue("--compose", v, WORKFLOW_MODELS_COMPOSE_MODES);
|
|
56091
|
+
patch.compose = v;
|
|
56092
|
+
}
|
|
56093
|
+
if (o.maxClass !== void 0) {
|
|
56094
|
+
const v = String(o.maxClass);
|
|
56095
|
+
if (!isWorkflowModelClass(v)) throw badFlagValue("--max-class", v, WORKFLOW_MODEL_CLASSES);
|
|
56096
|
+
patch.maxClass = v;
|
|
56097
|
+
}
|
|
56098
|
+
if (o.consentActions !== void 0) {
|
|
56099
|
+
const n2 = parseIntegerFlag(o.consentActions, "--consent-actions", {
|
|
56100
|
+
min: WORKFLOW_MODELS_CONSENT_ACTIONS_MIN
|
|
56101
|
+
});
|
|
56102
|
+
if (n2 !== void 0) patch.consentActions = n2;
|
|
56103
|
+
}
|
|
56104
|
+
if (o.pins !== void 0) {
|
|
56105
|
+
const v = String(o.pins);
|
|
56106
|
+
if (!WORKFLOW_MODELS_PIN_MODES.includes(v)) throw badFlagValue("--pins", v, WORKFLOW_MODELS_PIN_MODES);
|
|
56107
|
+
patch.pins = v;
|
|
56108
|
+
}
|
|
56109
|
+
if (o.fallback !== void 0) {
|
|
56110
|
+
const v = String(o.fallback);
|
|
56111
|
+
if (!WORKFLOW_MODELS_FALLBACK_MODES.includes(v)) throw badFlagValue("--fallback", v, WORKFLOW_MODELS_FALLBACK_MODES);
|
|
56112
|
+
patch.fallback = v;
|
|
56113
|
+
}
|
|
56114
|
+
const allow = csvFlag(o.allow);
|
|
56115
|
+
if (allow !== void 0) patch.allow = allow;
|
|
56116
|
+
const classes = {};
|
|
56117
|
+
const perClass = {
|
|
56118
|
+
fast: o.classFast,
|
|
56119
|
+
balanced: o.classBalanced,
|
|
56120
|
+
strong: o.classStrong
|
|
56121
|
+
};
|
|
56122
|
+
for (const c of WORKFLOW_MODEL_CLASSES) {
|
|
56123
|
+
const codes = csvFlag(perClass[c]);
|
|
56124
|
+
if (codes !== void 0) classes[c] = codes;
|
|
56125
|
+
}
|
|
56126
|
+
if (Object.keys(classes).length) patch.classes = classes;
|
|
56127
|
+
if (o.classMap !== void 0) {
|
|
56128
|
+
const map = {};
|
|
56129
|
+
for (const entry of csvFlag(o.classMap) ?? []) {
|
|
56130
|
+
const [task, cls] = entry.split("=").map((v) => v.trim());
|
|
56131
|
+
if (!task || !cls) throw CliError.usage(`--class-map: "${entry}" is not a mapping`, "--class-map takes `<taskClass>=<modelClass>` pairs, e.g. --class-map judge=strong,draft=balanced");
|
|
56132
|
+
if (!isWorkflowTaskClass(task)) throw badFlagValue("--class-map", task, WORKFLOW_TASK_CLASSES);
|
|
56133
|
+
if (!isWorkflowModelClass(cls)) throw badFlagValue("--class-map", cls, WORKFLOW_MODEL_CLASSES);
|
|
56134
|
+
map[task] = cls;
|
|
56135
|
+
}
|
|
56136
|
+
if (Object.keys(map).length) patch.classMap = map;
|
|
56137
|
+
}
|
|
56138
|
+
return patch;
|
|
56139
|
+
}
|
|
56140
|
+
__name(buildModelsPolicyPatch, "buildModelsPolicyPatch");
|
|
56141
|
+
function modelsPolicyLines(models) {
|
|
56142
|
+
const lines = [
|
|
56143
|
+
"\n\u{1F9E0} Workflow model policy"
|
|
56144
|
+
];
|
|
56145
|
+
if (!models || Object.keys(models).length === 0) {
|
|
56146
|
+
lines.push(" (not set \u2014 the platform defaults apply: assignment off, no class ceiling, composed steps class-only)");
|
|
56147
|
+
return lines;
|
|
56148
|
+
}
|
|
56149
|
+
const show = /* @__PURE__ */ __name((label2, v, fallback) => {
|
|
56150
|
+
lines.push(` ${label2.padEnd(16)} ${v === void 0 || v === null ? `\u2014 (${fallback})` : String(v)}`);
|
|
56151
|
+
}, "show");
|
|
56152
|
+
show("compose", models.compose, "platform default");
|
|
56153
|
+
show("maxClass", models.maxClass, "no ceiling below `strong`");
|
|
56154
|
+
show("consentActions", models.consentActions, "platform default");
|
|
56155
|
+
show("pins", models.pins, "class-only on composed definitions");
|
|
56156
|
+
show("fallback", models.fallback, "same-class");
|
|
56157
|
+
lines.push(` ${"allow".padEnd(16)} ${models.allow?.length ? models.allow.join(", ") : "\u2014 (all approved, minus the organization\u2019s excluded models)"}`);
|
|
56158
|
+
if (models.classes && Object.keys(models.classes).length) {
|
|
56159
|
+
lines.push(" classes");
|
|
56160
|
+
for (const c of WORKFLOW_MODEL_CLASSES) {
|
|
56161
|
+
const codes = models.classes[c];
|
|
56162
|
+
if (codes?.length) lines.push(` ${c.padEnd(10)} ${codes.join(", ")}`);
|
|
56163
|
+
}
|
|
56164
|
+
}
|
|
56165
|
+
if (models.classMap && Object.keys(models.classMap).length) {
|
|
56166
|
+
lines.push(" classMap (overrides only)");
|
|
56167
|
+
for (const [task, cls] of Object.entries(models.classMap)) lines.push(` ${task.padEnd(10)} \u2192 ${cls}`);
|
|
56168
|
+
}
|
|
56169
|
+
return lines;
|
|
56170
|
+
}
|
|
56171
|
+
__name(modelsPolicyLines, "modelsPolicyLines");
|
|
56172
|
+
var WORKFLOW_AUTONOMY_ENABLED_WORDS = [
|
|
56173
|
+
"on",
|
|
56174
|
+
"off"
|
|
56175
|
+
];
|
|
56176
|
+
var AUTONOMY_NUMERIC_FLAGS = {
|
|
56177
|
+
maxCredits: "--max-credits",
|
|
56178
|
+
maxSteps: "--max-steps",
|
|
56179
|
+
// `--max-duration` takes SECONDS and the wire key says so; `--max-duration-seconds` is `raise-budget`'s
|
|
56180
|
+
// own flag for a different thing (one run's wall), so the two deliberately do not share a spelling.
|
|
56181
|
+
maxDurationSeconds: "--max-duration",
|
|
56182
|
+
maxActions: "--max-actions",
|
|
56183
|
+
maxRunsPerHour: "--max-runs-per-hour"
|
|
56184
|
+
};
|
|
56185
|
+
function buildAutonomyPolicyPatch(o) {
|
|
56186
|
+
const patch = {};
|
|
56187
|
+
if (o.enabled !== void 0) {
|
|
56188
|
+
const v = String(o.enabled).trim().toLowerCase();
|
|
56189
|
+
if (!WORKFLOW_AUTONOMY_ENABLED_WORDS.includes(v)) throw badFlagValue("--enabled", String(o.enabled), WORKFLOW_AUTONOMY_ENABLED_WORDS);
|
|
56190
|
+
patch.enabled = v === "on";
|
|
56191
|
+
}
|
|
56192
|
+
const raw = {
|
|
56193
|
+
maxCredits: o.maxCredits,
|
|
56194
|
+
maxSteps: o.maxSteps,
|
|
56195
|
+
maxDurationSeconds: o.maxDuration,
|
|
56196
|
+
maxActions: o.maxActions,
|
|
56197
|
+
maxRunsPerHour: o.maxRunsPerHour
|
|
56198
|
+
};
|
|
56199
|
+
for (const key of WORKFLOW_AUTONOMY_NUMERIC_KEYS) {
|
|
56200
|
+
const n2 = parseIntegerFlag(raw[key], AUTONOMY_NUMERIC_FLAGS[key], {
|
|
56201
|
+
min: WORKFLOW_AUTONOMY_MIN_VALUE
|
|
56202
|
+
});
|
|
56203
|
+
if (n2 !== void 0) patch[key] = n2;
|
|
56204
|
+
}
|
|
56205
|
+
const forms = csvFlag(o.forms);
|
|
56206
|
+
if (forms !== void 0) {
|
|
56207
|
+
for (const f of forms) if (!isWorkflowAutonomyForm(f)) throw badFlagValue("--forms", f, WORKFLOW_AUTONOMY_FORMS);
|
|
56208
|
+
patch.forms = forms;
|
|
56209
|
+
}
|
|
56210
|
+
for (const token of csvFlag(o.clear) ?? []) {
|
|
56211
|
+
const key = autonomyClearKey(token);
|
|
56212
|
+
if (!key) throw badFlagValue("--clear", token, WORKFLOW_AUTONOMY_CLEAR_KEYS);
|
|
56213
|
+
if (patch[key] !== void 0) throw CliError.usage(`--clear: "${token}" is also being set by ${key === "enabled" ? "--enabled" : key === "forms" ? "--forms" : AUTONOMY_NUMERIC_FLAGS[key]}`, "Clear a member or set it, not both in one call \u2014 `--clear` sends `null` so the platform default applies again.");
|
|
56214
|
+
patch[key] = null;
|
|
56215
|
+
}
|
|
56216
|
+
return patch;
|
|
56217
|
+
}
|
|
56218
|
+
__name(buildAutonomyPolicyPatch, "buildAutonomyPolicyPatch");
|
|
56219
|
+
function autonomyPolicyLines(autonomy, effective, opts = {}) {
|
|
56220
|
+
const lines = [
|
|
56221
|
+
"\n\u{1F6E1}\uFE0F Workflow autonomy (the pre-consented envelope)"
|
|
56222
|
+
];
|
|
56223
|
+
const show = /* @__PURE__ */ __name((target, label2, v, fallback) => {
|
|
56224
|
+
const rendered = v === void 0 || v === null ? `\u2014 (${fallback})` : label2 === "maxDurationSeconds" && typeof v === "number" ? `${fmtNum(v)} (${autonomyDurationLabel(v)})` : Array.isArray(v) ? v.join(", ") : String(v);
|
|
56225
|
+
target.push(` ${label2.padEnd(18)} ${rendered}`);
|
|
56226
|
+
}, "show");
|
|
56227
|
+
const block = /* @__PURE__ */ __name((target, e) => {
|
|
56228
|
+
show(target, "enabled", e.enabled, `${WORKFLOW_AUTONOMY_ENABLED_DEFAULT} \u2014 absent means the organization never opted in`);
|
|
56229
|
+
show(target, "maxCredits", e.maxCredits, `default ${WORKFLOW_AUTONOMY_DEFAULTS.maxCredits}, clamped to caps.maxCreditsPerRun`);
|
|
56230
|
+
show(target, "maxSteps", e.maxSteps, `default ${WORKFLOW_AUTONOMY_DEFAULTS.maxSteps}`);
|
|
56231
|
+
show(target, "maxDurationSeconds", e.maxDurationSeconds, `default ${fmtNum(WORKFLOW_AUTONOMY_DEFAULTS.maxDurationSeconds)} \u2014 ${autonomyDurationLabel(WORKFLOW_AUTONOMY_DEFAULTS.maxDurationSeconds)}`);
|
|
56232
|
+
show(target, "maxActions", e.maxActions, "the organization\u2019s own models.consentActions");
|
|
56233
|
+
show(target, "maxRunsPerHour", e.maxRunsPerHour, `default ${WORKFLOW_AUTONOMY_DEFAULTS.maxRunsPerHour}`);
|
|
56234
|
+
show(target, "forms", e.forms?.length ? e.forms : void 0, `${WORKFLOW_AUTONOMY_FORMS_DEFAULT.join(", ")} \u2014 script opts in`);
|
|
56235
|
+
}, "block");
|
|
56236
|
+
if (!autonomy || Object.keys(autonomy).length === 0) {
|
|
56237
|
+
lines.push(" (not set \u2014 autonomy is OFF for this organization: every start that would ask a person still asks,", " exactly as it does today)");
|
|
56238
|
+
} else {
|
|
56239
|
+
block(lines, autonomy);
|
|
56240
|
+
}
|
|
56241
|
+
if (effective) {
|
|
56242
|
+
lines.push("\n Effective envelope (the server\u2019s own resolution \u2014 org narrowed by agent, defaults applied)");
|
|
56243
|
+
block(lines, effective);
|
|
56244
|
+
if (effective.enabled !== true) lines.push(" (enabled is not true \u2014 nothing is pre-consented; every start that would ask still asks)");
|
|
56245
|
+
} else if (opts.effectiveAsked) {
|
|
56246
|
+
lines.push("\n Effective envelope \u2014 the server served no resolution for it (a server without the envelope, or a", " policy route that does not answer `?effective=true`). What is above is the STORED block only; what a", " start would actually be admitted under is not shown.");
|
|
56247
|
+
}
|
|
56248
|
+
return lines;
|
|
56249
|
+
}
|
|
56250
|
+
__name(autonomyPolicyLines, "autonomyPolicyLines");
|
|
56251
|
+
var POLICY_NOUNS = [
|
|
56252
|
+
"models",
|
|
56253
|
+
"autonomy"
|
|
56254
|
+
];
|
|
56255
|
+
async function autonomyPolicyCore(ctx, verb, o) {
|
|
56256
|
+
const action = verb ?? "get";
|
|
56257
|
+
if (action !== "get" && action !== "set") throw CliError.usage(`policy autonomy: "${action}" is not an action`, "lua workflows policy autonomy get \xB7 lua workflows policy autonomy set \u2026");
|
|
56258
|
+
if (o.agent) throw CliError.usage("policy autonomy: --agent is not supported", "There is no route that WRITES a per-agent workflow setting: the sub-agent PATCH has no `workflows` member, so a narrowing sent that way is accepted and discarded. Set the organization\u2019s envelope instead (lua workflows policy autonomy set \u2026); `policy autonomy get` shows a per-agent narrowing when the effective projection carries one.");
|
|
56259
|
+
if (action === "get") {
|
|
56260
|
+
const res2 = await ctx.api.getWorkflowPolicy(ctx.orgId, {
|
|
56261
|
+
effective: true
|
|
56262
|
+
});
|
|
56263
|
+
if (!res2.success || !res2.data) return apiFailure(ctx, res2, "policy autonomy get");
|
|
56264
|
+
emitJson(ctx, res2);
|
|
56265
|
+
if (!ctx.json) for (const line of autonomyPolicyLines(res2.data.autonomy, res2.data.effective?.autonomy, {
|
|
56266
|
+
effectiveAsked: true
|
|
56267
|
+
})) console.log(line);
|
|
56268
|
+
return WORKFLOW_EXIT.OK;
|
|
56269
|
+
}
|
|
56270
|
+
const patch = parsedOrUsage(() => buildAutonomyPolicyPatch(o));
|
|
56271
|
+
if (Object.keys(patch).length === 0) throw CliError.usage("policy autonomy set: nothing to set", `Name at least one member: --enabled on|off \xB7 --max-credits <n> \xB7 --max-steps <n> \xB7 --max-duration <seconds> \xB7 --max-actions <n> \xB7 --max-runs-per-hour <n> \xB7 --forms ${WORKFLOW_AUTONOMY_FORMS.join(",")} \xB7 --clear <${WORKFLOW_AUTONOMY_CLEAR_KEYS.join("|")}>`);
|
|
56272
|
+
const named = Object.keys(patch).join(", ");
|
|
56273
|
+
const res = await ctx.api.patchWorkflowPolicyAutonomy(ctx.orgId, patch);
|
|
56274
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "policy autonomy set");
|
|
56275
|
+
emitJson(ctx, res);
|
|
56276
|
+
if (!ctx.json) {
|
|
56277
|
+
writeSuccess(`\u2705 Workflow autonomy policy updated (${named})`);
|
|
56278
|
+
for (const line of autonomyPolicyLines(res.data.autonomy, res.data.effective?.autonomy)) console.log(line);
|
|
56279
|
+
console.log("\n\u{1F4A1} A policy change reaches a starting agent within 30 seconds.");
|
|
56280
|
+
console.log(" The platform switch and `dynamic: false` still sit above it, and `askAboveThresholds: false`");
|
|
56281
|
+
console.log(" still refuses \u2014 autonomy turns an \u201Cask\u201D into an \u201Cauto\u201D, never a \u201Crefuse\u201D into either.");
|
|
56282
|
+
}
|
|
56283
|
+
return WORKFLOW_EXIT.OK;
|
|
56284
|
+
}
|
|
56285
|
+
__name(autonomyPolicyCore, "autonomyPolicyCore");
|
|
56286
|
+
async function policyCore(ctx, noun, verb, o) {
|
|
56287
|
+
if (noun === "autonomy") return autonomyPolicyCore(ctx, verb, o);
|
|
56288
|
+
if (noun !== "models") throw CliError.usage(`policy: "${noun ?? ""}" is not a policy noun`, `policy takes one of ${POLICY_NOUNS.map((n2) => `\`${n2}\``).join(", ")} \u2014 lua workflows policy models get \xB7 lua workflows policy autonomy get`);
|
|
56289
|
+
const action = verb ?? "get";
|
|
56290
|
+
if (action !== "get" && action !== "set") throw CliError.usage(`policy models: "${action}" is not an action`, "lua workflows policy models get \xB7 lua workflows policy models set \u2026");
|
|
56291
|
+
if (action === "get") {
|
|
56292
|
+
const res2 = await ctx.api.getWorkflowPolicy(ctx.orgId);
|
|
56293
|
+
if (!res2.success || !res2.data) return apiFailure(ctx, res2, "policy models get");
|
|
56294
|
+
emitJson(ctx, res2);
|
|
56295
|
+
if (!ctx.json) for (const line of modelsPolicyLines(res2.data.models)) console.log(line);
|
|
56296
|
+
return WORKFLOW_EXIT.OK;
|
|
56297
|
+
}
|
|
56298
|
+
const patch = buildModelsPolicyPatch(o);
|
|
56299
|
+
if (Object.keys(patch).length === 0) throw CliError.usage("policy models set: nothing to set", "Name at least one field: --compose on|off \xB7 --max-class fast|balanced|strong \xB7 --consent-actions <n> \xB7 --pins class-only|allowed \xB7 --fallback same-class|same-provider \xB7 --allow <codes> \xB7 --class-fast/--class-balanced/--class-strong <codes> \xB7 --class-map <task>=<class>");
|
|
56300
|
+
const res = await ctx.api.patchWorkflowPolicyModels(ctx.orgId, patch);
|
|
56301
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "policy models set");
|
|
56302
|
+
emitJson(ctx, res);
|
|
56303
|
+
if (!ctx.json) {
|
|
56304
|
+
writeSuccess(`\u2705 Workflow model policy updated (${Object.keys(patch).join(", ")})`);
|
|
56305
|
+
for (const line of modelsPolicyLines(res.data.models)) console.log(line);
|
|
56306
|
+
console.log("\n\u{1F4A1} A policy change reaches a composing agent within 30 seconds.");
|
|
56307
|
+
}
|
|
56308
|
+
return WORKFLOW_EXIT.OK;
|
|
56309
|
+
}
|
|
56310
|
+
__name(policyCore, "policyCore");
|
|
56311
|
+
async function clearGateCore(ctx, runId, o) {
|
|
56312
|
+
const kind = o.kind;
|
|
56313
|
+
if (!kind) throw CliError.usage("clear-gate: --kind is required", `lua workflows clear-gate ${runId} --kind model_policy`);
|
|
56314
|
+
const res = await ctx.api.clearRunGate(runId, String(kind));
|
|
56315
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "clear-gate");
|
|
56316
|
+
emitJson(ctx, res);
|
|
56317
|
+
if (ctx.json) return WORKFLOW_EXIT.OK;
|
|
56318
|
+
if (res.data.cleared) {
|
|
56319
|
+
writeSuccess(`\u2705 Cleared the ${res.data.kind ?? kind} gate on ${runId}${res.data.status ? ` \u2014 ${res.data.status}` : ""}`);
|
|
56320
|
+
console.log(` lua workflows watch ${runId}`);
|
|
56321
|
+
} else {
|
|
56322
|
+
writeInfo(`\u2139\uFE0F ${runId} is not parked on a ${kind} gate${res.data.reason ? ` \u2014 ${res.data.reason}` : ""}. Nothing to clear.`);
|
|
56323
|
+
}
|
|
56324
|
+
return WORKFLOW_EXIT.OK;
|
|
56325
|
+
}
|
|
56326
|
+
__name(clearGateCore, "clearGateCore");
|
|
56327
|
+
function recomposeNextSteps(wf, version) {
|
|
56328
|
+
const lines = [
|
|
56329
|
+
` lua workflows view ${wf.name}`,
|
|
56330
|
+
` lua workflows versions ${wf.name}`
|
|
56331
|
+
];
|
|
56332
|
+
if (wf.dynamic === true) {
|
|
56333
|
+
lines.push(" (this workflow was composed by chat \u2014 `deploy` does not apply to it; the new version is published on the", " same definition, and `versions` shows which one is active)");
|
|
56334
|
+
} else {
|
|
56335
|
+
lines.push(` lua workflows deploy ${wf.name} -v ${version ?? "latest"}`);
|
|
56336
|
+
}
|
|
56337
|
+
return lines;
|
|
56338
|
+
}
|
|
56339
|
+
__name(recomposeNextSteps, "recomposeNextSteps");
|
|
56340
|
+
async function recomposeCore(ctx, name, _o) {
|
|
56341
|
+
const wf = await resolveWorkflow(ctx, name);
|
|
56342
|
+
if (!wf) return WORKFLOW_EXIT.NOT_FOUND;
|
|
56343
|
+
const res = await ctx.api.recomposeWorkflow(wf.id);
|
|
56344
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "recompose");
|
|
56345
|
+
emitJson(ctx, res);
|
|
56346
|
+
if (ctx.json) return WORKFLOW_EXIT.OK;
|
|
56347
|
+
const d = res.data;
|
|
56348
|
+
if (d.unchanged) {
|
|
56349
|
+
writeInfo(`\u2139\uFE0F ${wf.name} already asks for model classes everywhere it can \u2014 no new version was published.`);
|
|
56350
|
+
return WORKFLOW_EXIT.OK;
|
|
56351
|
+
}
|
|
56352
|
+
writeSuccess(`\u2705 ${wf.name} recomposed \u2192 version ${d.version ?? d.versionId ?? "(new)"}` + (d.rewritten !== void 0 ? ` \xB7 ${d.rewritten} agent step${d.rewritten === 1 ? "" : "s"} rewritten` : ""));
|
|
56353
|
+
for (const line of recomposeNextSteps(wf, d.version)) console.log(line);
|
|
56354
|
+
return WORKFLOW_EXIT.OK;
|
|
56355
|
+
}
|
|
56356
|
+
__name(recomposeCore, "recomposeCore");
|
|
55379
56357
|
|
|
55380
56358
|
// src/commands/features.ts
|
|
55381
56359
|
init_cli();
|
|
@@ -64110,6 +65088,69 @@ import chalk4 from "chalk";
|
|
|
64110
65088
|
init_compiler2();
|
|
64111
65089
|
init_artifact_loader();
|
|
64112
65090
|
init_analytics();
|
|
65091
|
+
|
|
65092
|
+
// src/commands/models-workflow-view.ts
|
|
65093
|
+
function classOf(m) {
|
|
65094
|
+
const c = m.fitness?.class;
|
|
65095
|
+
return c && WORKFLOW_MODEL_CLASSES.includes(c) ? c : void 0;
|
|
65096
|
+
}
|
|
65097
|
+
__name(classOf, "classOf");
|
|
65098
|
+
function isAwaitingConfirmation(m) {
|
|
65099
|
+
return m.fitness !== void 0 && m.fitness.confirmed !== true;
|
|
65100
|
+
}
|
|
65101
|
+
__name(isAwaitingConfirmation, "isAwaitingConfirmation");
|
|
65102
|
+
function isPinOnly(m) {
|
|
65103
|
+
return classOf(m) === void 0 || m.calibrated === false || isAwaitingConfirmation(m);
|
|
65104
|
+
}
|
|
65105
|
+
__name(isPinOnly, "isPinOnly");
|
|
65106
|
+
function costCell(m) {
|
|
65107
|
+
if (m.actionMultiplier === void 0) return "\u2014";
|
|
65108
|
+
const rate = `${m.actionMultiplier}\xD7`;
|
|
65109
|
+
if (m.billing === "byok") return `${rate} (own key)`;
|
|
65110
|
+
if (m.calibrated === false) return `${rate} (estimate)`;
|
|
65111
|
+
return rate;
|
|
65112
|
+
}
|
|
65113
|
+
__name(costCell, "costCell");
|
|
65114
|
+
function notesCell(m) {
|
|
65115
|
+
const notes = [];
|
|
65116
|
+
if (isAwaitingConfirmation(m)) notes.push("awaiting confirmation");
|
|
65117
|
+
if (m.billing === "byok") notes.push("own key");
|
|
65118
|
+
if (m.calibrated === false) notes.push("rate not calibrated");
|
|
65119
|
+
if (isPinOnly(m)) notes.push("pin only");
|
|
65120
|
+
return notes.length ? notes.join(" \xB7 ") : "";
|
|
65121
|
+
}
|
|
65122
|
+
__name(notesCell, "notesCell");
|
|
65123
|
+
function workflowModelRows(models) {
|
|
65124
|
+
const order = /* @__PURE__ */ __name((m) => {
|
|
65125
|
+
const c = classOf(m);
|
|
65126
|
+
if (c === void 0) return WORKFLOW_MODEL_CLASSES.length;
|
|
65127
|
+
return WORKFLOW_MODEL_CLASSES.indexOf(c);
|
|
65128
|
+
}, "order");
|
|
65129
|
+
return [
|
|
65130
|
+
...models
|
|
65131
|
+
].sort((a, b) => order(a) - order(b) || (a.actionMultiplier ?? 0) - (b.actionMultiplier ?? 0) || a.code.localeCompare(b.code)).map((m) => ({
|
|
65132
|
+
class: classOf(m) ?? "\u2014",
|
|
65133
|
+
code: m.code,
|
|
65134
|
+
bestFor: m.fitness?.bestFor?.length ? m.fitness.bestFor.join(", ") : "\u2014",
|
|
65135
|
+
speed: m.fitness?.speed ?? "\u2014",
|
|
65136
|
+
cost: costCell(m),
|
|
65137
|
+
efforts: m.reasoning?.efforts?.length ? m.reasoning.efforts.join(", ") : "\u2014",
|
|
65138
|
+
notes: notesCell(m)
|
|
65139
|
+
}));
|
|
65140
|
+
}
|
|
65141
|
+
__name(workflowModelRows, "workflowModelRows");
|
|
65142
|
+
function workflowModelFootnotes(models) {
|
|
65143
|
+
const out = [];
|
|
65144
|
+
if (models.some(isAwaitingConfirmation)) out.push("\u2022 awaiting confirmation \u2014 new to the catalog. It can be pinned by code, but no model class resolves to it yet.");
|
|
65145
|
+
if (models.some((m) => m.billing === "byok")) out.push("\u2022 own key \u2014 served through your organization\u2019s own provider key, shown at that provider\u2019s relative rate because you pay them directly.");
|
|
65146
|
+
if (models.some((m) => m.calibrated === false)) out.push("\u2022 rate not calibrated \u2014 the cost shown is a conservative placeholder, not a measured rate.");
|
|
65147
|
+
if (models.some((m) => m.reasoning?.efforts?.length === 1 || m.reasoning?.supported === false)) out.push("\u2022 a model with no graded effort ladder ignores a step\u2019s `effort`; it is recorded but inert.");
|
|
65148
|
+
out.push("\u2022 cost is a multiple of a small call on the pricing baseline model \u2014 the unit your run budget counts.");
|
|
65149
|
+
return out;
|
|
65150
|
+
}
|
|
65151
|
+
__name(workflowModelFootnotes, "workflowModelFootnotes");
|
|
65152
|
+
|
|
65153
|
+
// src/commands/models.ts
|
|
64113
65154
|
init_cli_error();
|
|
64114
65155
|
function noAgentConfigured() {
|
|
64115
65156
|
return CliError.usage("No agent configured.", "Run `lua init` first to set up a project.");
|
|
@@ -64176,6 +65217,44 @@ async function listModels(models, currentModel, opts) {
|
|
|
64176
65217
|
console.log("");
|
|
64177
65218
|
}
|
|
64178
65219
|
__name(listModels, "listModels");
|
|
65220
|
+
async function listWorkflowModels(models, opts) {
|
|
65221
|
+
const rows3 = models;
|
|
65222
|
+
if (opts.json) {
|
|
65223
|
+
console.log(JSON.stringify({
|
|
65224
|
+
view: "workflows",
|
|
65225
|
+
models
|
|
65226
|
+
}, null, 2));
|
|
65227
|
+
return;
|
|
65228
|
+
}
|
|
65229
|
+
const table = workflowModelRows(rows3);
|
|
65230
|
+
console.log("");
|
|
65231
|
+
console.log(chalk4.bold("\u{1F9ED} Models for workflow steps"));
|
|
65232
|
+
console.log("");
|
|
65233
|
+
console.log(renderTable([
|
|
65234
|
+
"Class",
|
|
65235
|
+
"Model",
|
|
65236
|
+
"Best for",
|
|
65237
|
+
"Speed",
|
|
65238
|
+
"Cost",
|
|
65239
|
+
"Efforts",
|
|
65240
|
+
"Notes"
|
|
65241
|
+
], table.map((r) => [
|
|
65242
|
+
r.class,
|
|
65243
|
+
r.code,
|
|
65244
|
+
r.bestFor,
|
|
65245
|
+
r.speed,
|
|
65246
|
+
r.cost,
|
|
65247
|
+
r.efforts,
|
|
65248
|
+
r.notes
|
|
65249
|
+
])));
|
|
65250
|
+
console.log("");
|
|
65251
|
+
for (const note of workflowModelFootnotes(rows3)) console.log(` ${chalk4.gray(note)}`);
|
|
65252
|
+
console.log("");
|
|
65253
|
+
console.log(` \u{1F4A1} A step asks for a class with ${chalk4.cyan("model: 'class/balanced'")}, or names its work with ${chalk4.cyan("taskClass")}.`);
|
|
65254
|
+
console.log(` ${chalk4.cyan("lua workflows policy models get")} shows the classes and ceilings your organization has set.`);
|
|
65255
|
+
console.log("");
|
|
65256
|
+
}
|
|
65257
|
+
__name(listWorkflowModels, "listWorkflowModels");
|
|
64179
65258
|
async function modelsCommand(action, opts) {
|
|
64180
65259
|
return withErrorHandling(async () => {
|
|
64181
65260
|
const resolvedAction = action ? validateOrSuggest("models.action", action) : "list";
|
|
@@ -64193,6 +65272,16 @@ async function modelsCommand(action, opts) {
|
|
|
64193
65272
|
});
|
|
64194
65273
|
return;
|
|
64195
65274
|
}
|
|
65275
|
+
if (opts.workflows) {
|
|
65276
|
+
await listWorkflowModels(models, opts);
|
|
65277
|
+
trackEvent("cli_models_listed", {
|
|
65278
|
+
models_count: models.length,
|
|
65279
|
+
has_current_model: false,
|
|
65280
|
+
json_output: opts.json ?? false,
|
|
65281
|
+
workflows_view: true
|
|
65282
|
+
});
|
|
65283
|
+
return;
|
|
65284
|
+
}
|
|
64196
65285
|
const currentModel = agentId ? await resolveCurrentModel(apiKey, agentId) : null;
|
|
64197
65286
|
await listModels(models, currentModel, opts);
|
|
64198
65287
|
trackEvent("cli_models_listed", {
|
|
@@ -64383,13 +65472,13 @@ function hasSox() {
|
|
|
64383
65472
|
__name(hasSox, "hasSox");
|
|
64384
65473
|
function detectSoxInstaller() {
|
|
64385
65474
|
const os3 = platform3();
|
|
64386
|
-
const
|
|
65475
|
+
const has3 = /* @__PURE__ */ __name((bin) => spawnSync(bin, [
|
|
64387
65476
|
"--version"
|
|
64388
65477
|
], {
|
|
64389
65478
|
stdio: "ignore"
|
|
64390
65479
|
}).status === 0, "has");
|
|
64391
65480
|
if (os3 === "darwin") {
|
|
64392
|
-
if (
|
|
65481
|
+
if (has3("brew")) return {
|
|
64393
65482
|
manager: "Homebrew",
|
|
64394
65483
|
argv: [
|
|
64395
65484
|
"brew",
|
|
@@ -64400,7 +65489,7 @@ function detectSoxInstaller() {
|
|
|
64400
65489
|
return null;
|
|
64401
65490
|
}
|
|
64402
65491
|
if (os3 === "linux") {
|
|
64403
|
-
if (
|
|
65492
|
+
if (has3("apt-get")) return {
|
|
64404
65493
|
manager: "apt",
|
|
64405
65494
|
argv: [
|
|
64406
65495
|
"sudo",
|
|
@@ -64411,7 +65500,7 @@ function detectSoxInstaller() {
|
|
|
64411
65500
|
],
|
|
64412
65501
|
note: "may prompt for sudo password"
|
|
64413
65502
|
};
|
|
64414
|
-
if (
|
|
65503
|
+
if (has3("apt")) return {
|
|
64415
65504
|
manager: "apt",
|
|
64416
65505
|
argv: [
|
|
64417
65506
|
"sudo",
|
|
@@ -64422,7 +65511,7 @@ function detectSoxInstaller() {
|
|
|
64422
65511
|
],
|
|
64423
65512
|
note: "may prompt for sudo password"
|
|
64424
65513
|
};
|
|
64425
|
-
if (
|
|
65514
|
+
if (has3("dnf")) return {
|
|
64426
65515
|
manager: "dnf",
|
|
64427
65516
|
argv: [
|
|
64428
65517
|
"sudo",
|
|
@@ -64433,7 +65522,7 @@ function detectSoxInstaller() {
|
|
|
64433
65522
|
],
|
|
64434
65523
|
note: "may prompt for sudo password"
|
|
64435
65524
|
};
|
|
64436
|
-
if (
|
|
65525
|
+
if (has3("yum")) return {
|
|
64437
65526
|
manager: "yum",
|
|
64438
65527
|
argv: [
|
|
64439
65528
|
"sudo",
|
|
@@ -64444,7 +65533,7 @@ function detectSoxInstaller() {
|
|
|
64444
65533
|
],
|
|
64445
65534
|
note: "may prompt for sudo password"
|
|
64446
65535
|
};
|
|
64447
|
-
if (
|
|
65536
|
+
if (has3("pacman")) return {
|
|
64448
65537
|
manager: "pacman",
|
|
64449
65538
|
argv: [
|
|
64450
65539
|
"sudo",
|
|
@@ -64455,7 +65544,7 @@ function detectSoxInstaller() {
|
|
|
64455
65544
|
],
|
|
64456
65545
|
note: "may prompt for sudo password"
|
|
64457
65546
|
};
|
|
64458
|
-
if (
|
|
65547
|
+
if (has3("apk")) return {
|
|
64459
65548
|
manager: "apk",
|
|
64460
65549
|
argv: [
|
|
64461
65550
|
"sudo",
|
|
@@ -64468,7 +65557,7 @@ function detectSoxInstaller() {
|
|
|
64468
65557
|
return null;
|
|
64469
65558
|
}
|
|
64470
65559
|
if (os3 === "win32") {
|
|
64471
|
-
if (
|
|
65560
|
+
if (has3("winget")) return {
|
|
64472
65561
|
manager: "winget",
|
|
64473
65562
|
argv: [
|
|
64474
65563
|
"winget",
|
|
@@ -64479,7 +65568,7 @@ function detectSoxInstaller() {
|
|
|
64479
65568
|
"--silent"
|
|
64480
65569
|
]
|
|
64481
65570
|
};
|
|
64482
|
-
if (
|
|
65571
|
+
if (has3("choco")) return {
|
|
64483
65572
|
manager: "Chocolatey",
|
|
64484
65573
|
argv: [
|
|
64485
65574
|
"choco",
|
|
@@ -64488,7 +65577,7 @@ function detectSoxInstaller() {
|
|
|
64488
65577
|
"-y"
|
|
64489
65578
|
]
|
|
64490
65579
|
};
|
|
64491
|
-
if (
|
|
65580
|
+
if (has3("scoop")) return {
|
|
64492
65581
|
manager: "Scoop",
|
|
64493
65582
|
argv: [
|
|
64494
65583
|
"scoop",
|
|
@@ -66463,7 +67552,7 @@ Examples:
|
|
|
66463
67552
|
$ lua test skill --name mySkill --json Output raw JSON for scripting
|
|
66464
67553
|
$ lua test workflow --name outreach --input @leads.json --step-output draftEmail=@draft.json --approve reviewDrafts
|
|
66465
67554
|
`).action(testCommand);
|
|
66466
|
-
program2.command("push [type]").description("\u2601\uFE0F Push skill, agent, webhook, job, MCP server, or backup to server").option("--force", "Skip all confirmation prompts (auto-confirm)").option("--auto-deploy", "Automatically deploy to production after push").option("--name <name>", "Entity name to push").option("--set-version <version>", "Version to set (e.g., 1.0.5)").option("--fresh", "Build backup manifest from disk instead of compiled manifest.json (push backup only)").option("--no-include-source", "Skip the per-skill source attach after push (default: attach, so admin Builder UI sees CLI edits)").addHelpText("after", `
|
|
67555
|
+
program2.command("push [type]").description("\u2601\uFE0F Push skill, agent, webhook, job, MCP server, or backup to server").option("--force", "Skip all confirmation prompts (auto-confirm)").option("--auto-deploy", "Automatically deploy to production after push").option("--name <name>", "Entity name to push").option("--set-version <version>", "Version to set (e.g., 1.0.5)").option("--fresh", "Build backup manifest from disk instead of compiled manifest.json (push backup only)").option("--apply-effort", "push workflow: send each agent step's effort to the model from this version on (a plain push never does)").option("--no-include-source", "Skip the per-skill source attach after push (default: attach, so admin Builder UI sees CLI edits)").addHelpText("after", `
|
|
66467
67556
|
Arguments:
|
|
66468
67557
|
type Optional: 'skill', 'agent', 'persona', 'webhook', 'job', 'preprocessor', 'postprocessor', 'mcp', 'backup', or 'all' (prompts if not provided)
|
|
66469
67558
|
|
|
@@ -66719,7 +67808,7 @@ Examples:
|
|
|
66719
67808
|
$ lua jobs versions -i myJob View job versions
|
|
66720
67809
|
$ lua jobs history -i myJob View execution history
|
|
66721
67810
|
`).action(jobsCommand);
|
|
66722
|
-
program2.command("workflows [action] [target] [extra]").description("\u{1F9ED} Manage workflows and their runs (list, start, watch, cancel, resume, retry-step, resolve-step, raise-budget, approve, signal, replay, export, schedules)").option("-i, --workflow-name <name>", "Workflow name (or id)").option("-r, --run-id <id>", "Run id").option("-v, --workflow-version <ver>", "deploy/start/export/goals create/schedules create: a semver, 'latest' (newest push) or a version id").option("--json", "Print the raw {success,data} envelope").option("--all", "list: include dynamic workflows").option("--input <json|@file>", "start/run/goals create/schedules create: run input").option("--idempotency-key <key>", "start: idempotency key").option("--correlation-key <key>", "start/runs: correlation key").option("--tag <tag>", "start/runs/schedules create: tag (repeatable, \u2264 10)", collect, []).option("--budget-credits <n>", "start/schedules create: run budget (credits)").option("--wait <s>", "start: server long-poll \u2264 55 s").option("--follow", "start/logs: attach watch").option("--status <status>", "runs/goals list: filter by status").option("--workflow <name>", "runs: filter by workflow").option("--limit <n>", "runs/goals list/approval-payload --path: page size").option("--cursor <c>", "runs/goals list/approval-payload --path: page cursor").option("--sort <field>", "runs: -createdAt|createdAt|-durationMs|durationMs").option("--steps", "status: per-step table").option("--strict", "status: exit 4/5 by terminal status").option("--after <seq>", "watch: replay from seq").option("--timeout <s>", "watch / start --follow: give up after s seconds while the run is still live (exit 7)").option("--events", "watch: print raw frames").option("--wait-for-human", "watch / start --follow: keep following through a human boundary (approval, input, signal, park) instead of exiting 8").option("--reason <text>", "cancel: reason").option("--step <id>", "resume/retry-step/resolve-step/logs: step id").option("--outcome <skip|complete|fail>", "resolve-step: the decision on the parked step (--action is accepted too)").option("--action <skip|complete|fail>", "resolve-step: alias of --outcome").option("--output <json|@file>", "resolve-step: the output a completed step would have produced (required with --outcome complete)").option("--credits <n>", "raise-budget: the new credit cap of a budget-parked run (above the current one)").option("--max-steps <n>", "raise-budget: the new step cap").option("--max-job-seconds <n>", "raise-budget: the new Job-tier seconds cap").option("--max-duration-seconds <n>", "raise-budget: the new wall-clock cap").option("--data <json|@file>", "resume: resumeData").option("--approval <id>", "approve/approval-payload: approval id").option("--path <array.path>", "approval-payload: page one array of a large payload (--cursor / --limit inside it)").option("--decision <approve|deny>", "approve: decision (default approve)").option("--note <text>", "approve/retry-step/resolve-step/raise-budget/goals close: note").option("--edit <json|@file>", "approve: edited payload (small inline edits)").option("--fingerprint <f>", "approve: payloadFingerprint (mandatory with --edit)").option("--payload <json|@file>", "signal: payload").option("--dedupe-key <key>", "signal: dedupe key").option("--local", "replay: replay locally against the compiled artifact").option("--since <dur>", "logs: window").option("--yes", "delete/delete-run/schedules delete: skip confirmation").option("--force", "delete: cancel in-flight runs first \xB7 run: seed from a changed graph \xB7 export: overwrite files").option("--step-output <id=json>", "run: complete a step with this output (repeatable)", collect, []).option("--approve <id[=@payload]>", "run: pre-answer an approval (repeatable)", collect, []).option("--deny <id[=@reason]>", "run: pre-deny an approval (repeatable)", collect, []).option("--signal <name=json>", "run: pre-supply a waitForSignal payload (repeatable)", collect, []).option("--from-run <runId>", "run: seed completed steps from a real run").option("--record <dir>", "run: record agent/tool outputs as fixtures").option("--fixtures <dir>", "run: replay recorded fixtures").option("--step-wall <s>", "run: per-step wall in seconds (default 600)").option("--job-wall <s>", "run: virtual wall for tier:'job' steps \u2014 splits at 14400 s segments, > 86400 is exit 2").option("--ledger-out <file>", "run: write the in-memory ledger as JSON").option("--agents <fake|live>", "run: fake agent steps (default) or call the dev API").option("--now <iso>", "run: virtual clock start").option("--park <id>", "run: simulate a platform-fault park of this step (repeatable)", collect, []).option("--fast-retries", "run: collapse retry backoff waits to 0").option("--real-time", "run: actually wait on sleeps/backoffs instead of fast-forwarding").option("--artefacts-dir <dir>", "run: back ctx.artefacts.* on disk").option("--workspace <dir>", "run: the checkout Job-tier code steps run in (ctx.workspace + ctx.exec / ctx.$)").option("--env <KEY=value>", "run: local env.template() overlay (repeatable; missing key \u21D2 exit 2)", collect, []).option("--max-ticks <n>", "run (script form): tick cap before SCRIPT_TICK_LIMIT (default 64)").option("--until <iso>", "archive-runs: window end").option("--out <dir>", "archive-runs: destination dir (archive-index.ndjson + <runId>.zip) \xB7 export: target dir").option("--concurrency <n>", "archive-runs: parallel exports (default 2, max 5)").option("--no-inputs", "archive-runs: exclude run inputs from the bundle").option("--no-artefacts", "archive-runs: exclude artefacts from the bundle").option("--retention-days <n>", "archive-runs: org run retention (default 90) \u2014 --since must fit retention \u2212 7 d").option("--connection <id>", "archive-runs: org storage connection for s3:// / gs:// sinks").option("--release", "workspace: release the run workspace (R42)").option("--attempt <n>", "job-logs: attempt (default latest)").option("--tail <n>", "job-logs: log lines (1..2000, default 200)").option("--objective <text>", "goals create: the objective (\u2264 2000 chars)").option("--judge-predicate <spec>", "goals create: deterministic judge \u2014 '<path> <op> [value]' (e.g. 'output.done truthy'), JSON or @file").option("--judge-agent <agentId|'$self'>", "goals create: judge agent \u2014 write '$self' quoted (or self); it needs --judge-role").option("--judge-role <json|@file>", "goals create: D25 role {name,instructions,tools} for a '$self' judge").option("--schema <json|@file>", "goals create: judge output JsonSchema (must declare a boolean `done`)").option("--cadence <cron|json|@file>", "goals create/schedules create: cadence entry (repeatable, \u2264 5); goals: none \u21D2 immediate", collect, []).option("--timezone <tz>", "goals create/edit/schedules create: IANA timezone for bare cron cadences").option("--notify <emailApp|email|app|off>", "schedules create: where each fire notifies").option("--backfill-on-enable <n|none>", "schedules create/patch/resume: replay \u2264 n missed fires on re-enable (patch: none clears it)").option("--backfill-now", "schedules resume (or patch --paused false): one-shot backfill on THIS re-enable").option("--paused <true|false>", "schedules patch: pause (true) or re-enable (false) the schedule").option("--max-runs <n>", "goals create/edit/raise: iteration cap (1..100)").option("--max-total-credits <n>", "goals create: lineage-wide credit gate").option("--max-credits <n|none>", "goals edit/raise: lineage-wide credit gate (edit: none clears it)").option("--every <interval>", "goals edit/schedules create: interval cadence \u2014 900, 15m, 2h (whole minutes, \u2265 60s)").option("--if-match <updatedAt>", "goals edit/raise: refuse the write if the goal changed since this updatedAt").addHelpText("after", `
|
|
67811
|
+
program2.command("workflows [action] [target] [extra]").description("\u{1F9ED} Manage workflows and their runs (list, start, watch, cancel, resume, retry-step, resolve-step, raise-budget, approve, signal, replay, export, schedules)").option("-i, --workflow-name <name>", "Workflow name (or id)").option("-r, --run-id <id>", "Run id").option("-v, --workflow-version <ver>", "deploy/start/export/goals create/schedules create: a semver, 'latest' (newest push) or a version id").option("--json", "Print the raw {success,data} envelope").option("--all", "list: include dynamic workflows").option("--input <json|@file>", "start/run/goals create/schedules create: run input").option("--idempotency-key <key>", "start: idempotency key").option("--correlation-key <key>", "start/runs: correlation key").option("--tag <tag>", "start/runs/schedules create: tag (repeatable, \u2264 10)", collect, []).option("--budget-credits <n>", "start/schedules create: run budget (credits)").option("--wait <s>", "start: server long-poll \u2264 55 s").option("--follow", "start/logs: attach watch").option("--status <status>", "runs/goals list: filter by status").option("--workflow <name>", "runs: filter by workflow").option("--limit <n>", "runs/goals list/approval-payload --path: page size").option("--cursor <c>", "runs/goals list/approval-payload --path: page cursor").option("--sort <field>", "runs: -createdAt|createdAt|-durationMs|durationMs").option("--steps", "status: per-step table").option("--strict", "status: exit 4/5 by terminal status, 6 for a gated run").option("--compose <on|off>", "policy models set: may the composer be shown the model menu").option("--max-class <fast|balanced|strong>", "policy models set: ceiling for class requests and the class map").option("--consent-actions <n>", "policy models set: estimated actions above which a composed run shows the card").option("--allow <codes>", "policy models set: comma-separated approved codes to narrow the set to").option("--class-fast <codes>", "policy models set: ordered overrides of the fast class (comma-separated)").option("--class-balanced <codes>", "policy models set: ordered overrides of the balanced class (comma-separated)").option("--class-strong <codes>", "policy models set: ordered overrides of the strong class (comma-separated)").option("--class-map <pairs>", "policy models set: comma-separated <taskClass>=<modelClass> pairs").option("--pins <class-only|allowed>", "policy models set: may a composed definition pin a concrete code").option("--fallback <same-class|same-provider>", "policy models set: where a failed leg may hop to").option("--enabled <on|off>", "policy autonomy set: may a start inside the envelope skip the consent card").option("--max-duration <seconds>", "policy autonomy set: the envelope\u2019s duration bound, in seconds").option("--max-actions <n>", "policy autonomy set: the envelope\u2019s estimated-actions bound").option("--max-runs-per-hour <n>", "policy autonomy set: autonomous starts per hour, per agent").option("--forms <list>", "policy autonomy set: comma-separated forms the envelope admits (graph,script,static)").option("--clear <keys>", "policy autonomy set: comma-separated members to clear back to the platform default").option("--agent <agentId>", "policy autonomy: not supported \u2014 no route writes a per-agent envelope (see the refusal)").option("--kind <kind>", "clear-gate: the gate kind to clear (e.g. model_policy)").option("--after <seq>", "watch: replay from seq").option("--timeout <s>", "watch / start --follow: give up after s seconds while the run is still live (exit 7)").option("--events", "watch: print raw frames").option("--wait-for-human", "watch / start --follow: keep following through a human boundary (approval, input, signal, park) instead of exiting 8").option("--reason <text>", "cancel: reason").option("--step <id>", "resume/retry-step/resolve-step/logs: step id").option("--outcome <skip|complete|fail>", "resolve-step: the decision on the parked step (--action is accepted too)").option("--action <skip|complete|fail>", "resolve-step: alias of --outcome").option("--output <json|@file>", "resolve-step: the output a completed step would have produced (required with --outcome complete)").option("--credits <n>", "raise-budget: the new credit cap of a budget-parked run (above the current one)").option("--max-steps <n>", "raise-budget: the new step cap").option("--max-job-seconds <n>", "raise-budget: the new Job-tier seconds cap").option("--max-duration-seconds <n>", "raise-budget: the new wall-clock cap").option("--data <json|@file>", "resume: resumeData").option("--approval <id>", "approve/approval-payload: approval id").option("--path <array.path>", "approval-payload: page one array of a large payload (--cursor / --limit inside it)").option("--decision <approve|deny>", "approve: decision (default approve)").option("--note <text>", "approve/retry-step/resolve-step/raise-budget/goals close: note").option("--edit <json|@file>", "approve: edited payload (small inline edits)").option("--fingerprint <f>", "approve: payloadFingerprint (mandatory with --edit)").option("--payload <json|@file>", "signal: payload").option("--dedupe-key <key>", "signal: dedupe key").option("--local", "replay: replay locally against the compiled artifact").option("--since <dur>", "logs: window").option("--yes", "delete/delete-run/schedules delete: skip confirmation").option("--force", "delete: cancel in-flight runs first \xB7 run: seed from a changed graph \xB7 export: overwrite files").option("--step-output <id=json>", "run: complete a step with this output (repeatable)", collect, []).option("--approve <id[=@payload]>", "run: pre-answer an approval (repeatable)", collect, []).option("--deny <id[=@reason]>", "run: pre-deny an approval (repeatable)", collect, []).option("--signal <name=json>", "run: pre-supply a waitForSignal payload (repeatable)", collect, []).option("--from-run <runId>", "run: seed completed steps from a real run").option("--record <dir>", "run: record agent/tool outputs as fixtures").option("--fixtures <dir>", "run: replay recorded fixtures").option("--step-wall <s>", "run: per-step wall in seconds (default 600)").option("--job-wall <s>", "run: virtual wall for tier:'job' steps \u2014 splits at 14400 s segments, > 86400 is exit 2").option("--ledger-out <file>", "run: write the in-memory ledger as JSON").option("--agents <fake|live>", "run: fake agent steps (default) or call the dev API").option("--now <iso>", "run: virtual clock start").option("--park <id>", "run: simulate a platform-fault park of this step (repeatable)", collect, []).option("--fast-retries", "run: collapse retry backoff waits to 0").option("--real-time", "run: actually wait on sleeps/backoffs instead of fast-forwarding").option("--artefacts-dir <dir>", "run: back ctx.artefacts.* on disk").option("--workspace <dir>", "run: the checkout Job-tier code steps run in (ctx.workspace + ctx.exec / ctx.$)").option("--env <KEY=value>", "run: local env.template() overlay (repeatable; missing key \u21D2 exit 2)", collect, []).option("--max-ticks <n>", "run (script form): tick cap before SCRIPT_TICK_LIMIT (default 64)").option("--until <iso>", "archive-runs: window end").option("--out <dir>", "archive-runs: destination dir (archive-index.ndjson + <runId>.zip) \xB7 export: target dir").option("--concurrency <n>", "archive-runs: parallel exports (default 2, max 5)").option("--no-inputs", "archive-runs: exclude run inputs from the bundle").option("--no-artefacts", "archive-runs: exclude artefacts from the bundle").option("--retention-days <n>", "archive-runs: org run retention (default 90) \u2014 --since must fit retention \u2212 7 d").option("--connection <id>", "archive-runs: org storage connection for s3:// / gs:// sinks").option("--release", "workspace: release the run workspace (R42)").option("--attempt <n>", "job-logs: attempt (default latest)").option("--tail <n>", "job-logs: log lines (1..2000, default 200)").option("--objective <text>", "goals create: the objective (\u2264 2000 chars)").option("--judge-predicate <spec>", "goals create: deterministic judge \u2014 '<path> <op> [value]' (e.g. 'output.done truthy'), JSON or @file").option("--judge-agent <agentId|'$self'>", "goals create: judge agent \u2014 write '$self' quoted (or self); it needs --judge-role").option("--judge-role <json|@file>", "goals create: D25 role {name,instructions,tools} for a '$self' judge").option("--schema <json|@file>", "goals create: judge output JsonSchema (must declare a boolean `done`)").option("--cadence <cron|json|@file>", "goals create/schedules create: cadence entry (repeatable, \u2264 5); goals: none \u21D2 immediate", collect, []).option("--timezone <tz>", "goals create/edit/schedules create: IANA timezone for bare cron cadences").option("--notify <emailApp|email|app|off>", "schedules create: where each fire notifies").option("--backfill-on-enable <n|none>", "schedules create/patch/resume: replay \u2264 n missed fires on re-enable (patch: none clears it)").option("--backfill-now", "schedules resume (or patch --paused false): one-shot backfill on THIS re-enable").option("--paused <true|false>", "schedules patch: pause (true) or re-enable (false) the schedule").option("--max-runs <n>", "goals create/edit/raise: iteration cap (1..100)").option("--max-total-credits <n>", "goals create: lineage-wide credit gate").option("--max-credits <n|none>", "goals edit/raise: lineage-wide credit gate (edit: none clears it)").option("--every <interval>", "goals edit/schedules create: interval cadence \u2014 900, 15m, 2h (whole minutes, \u2265 60s)").option("--if-match <updatedAt>", "goals edit/raise: refuse the write if the goal changed since this updatedAt").addHelpText("after", `
|
|
66723
67812
|
Arguments:
|
|
66724
67813
|
action list \xB7 view \xB7 versions \xB7 deploy \xB7 activate \xB7 deactivate \xB7 start \xB7 run \xB7 runs \xB7 status \xB7
|
|
66725
67814
|
watch \xB7 cancel \xB7 resume \xB7 retry-step \xB7 resolve-step \xB7 raise-budget \xB7 approve \xB7 approval-payload \xB7
|
|
@@ -66776,6 +67865,15 @@ Examples:
|
|
|
66776
67865
|
$ lua workflows goals pause wfg_1234 \xB7 goals resume wfg_1234 \xB7 goals close wfg_1234 --note "shipped"
|
|
66777
67866
|
$ lua workflows schedules list -i outreach
|
|
66778
67867
|
$ lua workflows schedules delete <jobId> --yes (a goal's cadence is refused: goal_schedule)
|
|
67868
|
+
$ lua workflows policy models get
|
|
67869
|
+
$ lua workflows policy models set --compose on --max-class strong --consent-actions 60 --pins class-only
|
|
67870
|
+
$ lua workflows policy models set --class-map judge=strong,draft=balanced --class-fast alibaba/qwen3.8-flash
|
|
67871
|
+
$ lua workflows policy autonomy get (the stored envelope and the one a start is admitted under)
|
|
67872
|
+
$ lua workflows policy autonomy set --enabled on --max-credits 40 --max-steps 20 --max-duration 86400
|
|
67873
|
+
$ lua workflows policy autonomy set --forms graph,static --max-runs-per-hour 20
|
|
67874
|
+
$ lua workflows policy autonomy set --clear max-credits,forms (back to the platform defaults)
|
|
67875
|
+
$ lua workflows clear-gate <runId> --kind model_policy
|
|
67876
|
+
$ lua workflows recompose outreach (rewrites stored task classes into class/<c>; a new version)
|
|
66779
67877
|
`).action(workflowsCommand);
|
|
66780
67878
|
program2.command("features [action]").description("\u{1F3AF} Manage agent features (RAG, webSearch, inquiry, outboundChannels)").option("--feature-name <name>", "Feature name").option("--recipient-scope <scope>", "For configure: outboundChannels recipient scope (current_user | anyone)").addHelpText("after", `
|
|
66781
67879
|
Arguments:
|
|
@@ -66959,18 +68057,20 @@ Examples:
|
|
|
66959
68057
|
$ lua agents List all orgs and agents (formatted)
|
|
66960
68058
|
$ lua agents --json Output as JSON for scripting
|
|
66961
68059
|
`).action(agentsCommand);
|
|
66962
|
-
program2.command("models [action]").description("\u{1F9E0} List and manage LLM models for your agent").option("--model <code>", "Model code for 'set' action (e.g. 'openai/gpt-4o')").option("--json", "Output as JSON").addHelpText("after", `
|
|
68060
|
+
program2.command("models [action]").description("\u{1F9E0} List and manage LLM models for your agent").option("--model <code>", "Model code for 'set' action (e.g. 'openai/gpt-4o')").option("--json", "Output as JSON").option("--workflows", "list: the catalog as a workflow step sees it \u2014 class, best for, speed, cost, efforts").addHelpText("after", `
|
|
66963
68061
|
Arguments:
|
|
66964
68062
|
action Optional: 'list', 'set', or 'unset' (default: list)
|
|
66965
68063
|
|
|
66966
68064
|
Options:
|
|
66967
68065
|
--model <code> Set model non-interactively (use with 'set' action)
|
|
66968
68066
|
--json Output list as JSON (use with 'list' action)
|
|
68067
|
+
--workflows List for workflow steps: class, best for, speed, cost, efforts (use with 'list')
|
|
66969
68068
|
|
|
66970
68069
|
Examples:
|
|
66971
68070
|
$ lua models List available models (formatted)
|
|
66972
68071
|
$ lua models list List available models (explicit)
|
|
66973
68072
|
$ lua models list --json List as JSON for scripting
|
|
68073
|
+
$ lua models list --workflows Class, best for, speed, cost and efforts, for workflow steps
|
|
66974
68074
|
$ lua models set Interactively select a model
|
|
66975
68075
|
$ lua models set --model openai/gpt-4o Set model non-interactively
|
|
66976
68076
|
$ lua models unset Remove model \u2014 use platform default
|