lua-cli 3.35.0 → 3.37.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 +304 -31
- package/dist/api-exports.js +511 -196
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +1536 -239
- 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 +448 -195
- package/dist/workflow-builder.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/api/Workflows.md +1 -1
- package/package.json +4 -3
- 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;
|
|
@@ -1656,81 +1767,15 @@ function workflowOccurrenceId(lineageId, stepId) {
|
|
|
1656
1767
|
function workflowOrgSlotKey(orgId, kind) {
|
|
1657
1768
|
return `wf:org:${orgId}:${kind}`;
|
|
1658
1769
|
}
|
|
1770
|
+
function workflowJobModelSourceLabel(source) {
|
|
1771
|
+
return WORKFLOW_JOB_MODEL_SOURCE_LABELS[source];
|
|
1772
|
+
}
|
|
1659
1773
|
function scheduledTimeKey(scheduledTime) {
|
|
1660
1774
|
return scheduledTime.replace(/[^0-9TZ]/g, "");
|
|
1661
1775
|
}
|
|
1662
1776
|
function scheduledWorkflowRunIdForTime(jobId, scheduledTime) {
|
|
1663
1777
|
return scheduledWorkflowRunId(jobId, scheduledTime);
|
|
1664
1778
|
}
|
|
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
1779
|
function workflowGoalJudgeKind(judge) {
|
|
1735
1780
|
return judge && typeof judge === "object" && judge.predicate !== void 0 ? "predicate" : "agent";
|
|
1736
1781
|
}
|
|
@@ -2035,7 +2080,7 @@ function effectiveAgentFeatures(base, override, rule) {
|
|
|
2035
2080
|
if (rule === "wholesale") return override || base || void 0;
|
|
2036
2081
|
return effectiveAgentFeatureRows(base, override).rows;
|
|
2037
2082
|
}
|
|
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,
|
|
2083
|
+
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_JOB_MODEL_SOURCE_LABELS, 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
2084
|
var init_dist = __esm({
|
|
2040
2085
|
"../shared-types/dist/index.mjs"() {
|
|
2041
2086
|
"use strict";
|
|
@@ -2348,16 +2393,243 @@ var init_dist = __esm({
|
|
|
2348
2393
|
__name2(isDesktopFileCommandName, "isDesktopFileCommandName");
|
|
2349
2394
|
__name(isDesktopFileSessionId, "isDesktopFileSessionId");
|
|
2350
2395
|
__name2(isDesktopFileSessionId, "isDesktopFileSessionId");
|
|
2396
|
+
WORKFLOW_RETRY_BACKOFFS = [
|
|
2397
|
+
"fixed",
|
|
2398
|
+
"exponential"
|
|
2399
|
+
];
|
|
2400
|
+
WORKFLOW_RETRY_MIN_ATTEMPTS = 1;
|
|
2401
|
+
WORKFLOW_RETRY_POLICY_KEYS = [
|
|
2402
|
+
"maxAttempts",
|
|
2403
|
+
"backoffSeconds",
|
|
2404
|
+
"backoff",
|
|
2405
|
+
"maxBackoffSeconds"
|
|
2406
|
+
];
|
|
2407
|
+
WORKFLOW_RETRY_MAX_ATTEMPTS = 20;
|
|
2408
|
+
__name(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
2409
|
+
__name2(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
|
|
2410
|
+
__name(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
2411
|
+
__name2(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
|
|
2412
|
+
WORKFLOW_RETRY_ENGINE_KEYS = [
|
|
2413
|
+
"budgetBaseAttempt"
|
|
2414
|
+
];
|
|
2415
|
+
__name(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
2416
|
+
__name2(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
|
|
2417
|
+
__name(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
2418
|
+
__name2(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
|
|
2419
|
+
__name(authoredRetryPolicy, "authoredRetryPolicy");
|
|
2420
|
+
__name2(authoredRetryPolicy, "authoredRetryPolicy");
|
|
2421
|
+
__name(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
2422
|
+
__name2(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
|
|
2423
|
+
__name(retryBudgetAttempt, "retryBudgetAttempt");
|
|
2424
|
+
__name2(retryBudgetAttempt, "retryBudgetAttempt");
|
|
2425
|
+
__name(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
2426
|
+
__name2(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
|
|
2427
|
+
__name(retryBudgetRemaining, "retryBudgetRemaining");
|
|
2428
|
+
__name2(retryBudgetRemaining, "retryBudgetRemaining");
|
|
2429
|
+
__name(retriesRemaining, "retriesRemaining");
|
|
2430
|
+
__name2(retriesRemaining, "retriesRemaining");
|
|
2431
|
+
WORKFLOW_JOB_RESOURCES = [
|
|
2432
|
+
"small",
|
|
2433
|
+
"medium",
|
|
2434
|
+
"large"
|
|
2435
|
+
];
|
|
2436
|
+
WORKFLOW_SIDE_EFFECTS = [
|
|
2437
|
+
"none",
|
|
2438
|
+
"external"
|
|
2439
|
+
];
|
|
2440
|
+
WORKFLOW_AGENT_EFFORTS = [
|
|
2441
|
+
"low",
|
|
2442
|
+
"medium",
|
|
2443
|
+
"high"
|
|
2444
|
+
];
|
|
2445
|
+
WORKFLOW_MODEL_CLASSES = [
|
|
2446
|
+
"fast",
|
|
2447
|
+
"balanced",
|
|
2448
|
+
"strong"
|
|
2449
|
+
];
|
|
2450
|
+
WORKFLOW_TASK_CLASSES = [
|
|
2451
|
+
"classify",
|
|
2452
|
+
"extract",
|
|
2453
|
+
"transform",
|
|
2454
|
+
"draft",
|
|
2455
|
+
"research",
|
|
2456
|
+
"reason",
|
|
2457
|
+
"code",
|
|
2458
|
+
"judge"
|
|
2459
|
+
];
|
|
2460
|
+
WORKFLOW_MODEL_TRAITS = [
|
|
2461
|
+
"vision",
|
|
2462
|
+
"structured",
|
|
2463
|
+
"largeContext",
|
|
2464
|
+
"codeExecution"
|
|
2465
|
+
];
|
|
2466
|
+
WORKFLOW_MODEL_REASON_MAX_LENGTH = 160;
|
|
2467
|
+
__name(workflowModelCostComparison, "workflowModelCostComparison");
|
|
2468
|
+
__name2(workflowModelCostComparison, "workflowModelCostComparison");
|
|
2469
|
+
WORKFLOW_MODELS_COMPOSE_MODES = [
|
|
2470
|
+
"off",
|
|
2471
|
+
"on"
|
|
2472
|
+
];
|
|
2473
|
+
WORKFLOW_MODELS_PIN_MODES = [
|
|
2474
|
+
"class-only",
|
|
2475
|
+
"allowed"
|
|
2476
|
+
];
|
|
2477
|
+
WORKFLOW_MODELS_FALLBACK_MODES = [
|
|
2478
|
+
"same-class",
|
|
2479
|
+
"same-provider"
|
|
2480
|
+
];
|
|
2481
|
+
WORKFLOW_MODELS_CONSENT_ACTIONS_MIN = 1;
|
|
2482
|
+
WORKFLOW_DEFAULT_TASK_CLASS_MAP = Object.freeze({
|
|
2483
|
+
classify: "fast",
|
|
2484
|
+
extract: "fast",
|
|
2485
|
+
transform: "fast",
|
|
2486
|
+
draft: "balanced",
|
|
2487
|
+
research: "balanced",
|
|
2488
|
+
judge: "balanced",
|
|
2489
|
+
reason: "strong",
|
|
2490
|
+
code: "strong"
|
|
2491
|
+
});
|
|
2492
|
+
WORKFLOW_MODELS_MAX_CLASS_DEFAULT = WORKFLOW_MODEL_CLASSES[WORKFLOW_MODEL_CLASSES.length - 1];
|
|
2493
|
+
__name(modelClassRank, "modelClassRank");
|
|
2494
|
+
__name2(modelClassRank, "modelClassRank");
|
|
2495
|
+
__name(modelClassesAtOrBelow, "modelClassesAtOrBelow");
|
|
2496
|
+
__name2(modelClassesAtOrBelow, "modelClassesAtOrBelow");
|
|
2497
|
+
WORKFLOW_AUTONOMY_FORMS = [
|
|
2498
|
+
"graph",
|
|
2499
|
+
"script",
|
|
2500
|
+
"static"
|
|
2501
|
+
];
|
|
2502
|
+
WORKFLOW_AUTONOMY_NUMERIC_KEYS = [
|
|
2503
|
+
"maxCredits",
|
|
2504
|
+
"maxSteps",
|
|
2505
|
+
"maxDurationSeconds",
|
|
2506
|
+
"maxActions",
|
|
2507
|
+
"maxRunsPerHour"
|
|
2508
|
+
];
|
|
2509
|
+
WORKFLOW_AUTONOMY_ENVELOPE_KEYS = [
|
|
2510
|
+
"enabled",
|
|
2511
|
+
...WORKFLOW_AUTONOMY_NUMERIC_KEYS,
|
|
2512
|
+
"forms"
|
|
2513
|
+
];
|
|
2514
|
+
WORKFLOW_AUTONOMY_ENABLED_DEFAULT = false;
|
|
2515
|
+
WORKFLOW_AUTONOMY_DEFAULTS = Object.freeze({
|
|
2516
|
+
maxCredits: 20,
|
|
2517
|
+
maxSteps: 15,
|
|
2518
|
+
maxDurationSeconds: 86400,
|
|
2519
|
+
maxRunsPerHour: 20
|
|
2520
|
+
});
|
|
2521
|
+
WORKFLOW_AUTONOMY_CEILINGS = Object.freeze({
|
|
2522
|
+
maxSteps: 40,
|
|
2523
|
+
maxDurationSeconds: 604800
|
|
2524
|
+
});
|
|
2525
|
+
WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV = "LUA_WF_AUTONOMY_MAX_RUNS_PER_HOUR";
|
|
2526
|
+
WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING = 200;
|
|
2527
|
+
__name(workflowAutonomyMaxRunsPerHourCeiling, "workflowAutonomyMaxRunsPerHourCeiling");
|
|
2528
|
+
__name2(workflowAutonomyMaxRunsPerHourCeiling, "workflowAutonomyMaxRunsPerHourCeiling");
|
|
2529
|
+
WORKFLOW_AUTONOMY_FORMS_DEFAULT = Object.freeze([
|
|
2530
|
+
"graph",
|
|
2531
|
+
"static"
|
|
2532
|
+
]);
|
|
2533
|
+
WORKFLOW_AUTONOMY_MIN_VALUE = 1;
|
|
2534
|
+
__name(isWithinWorkflowAutonomyRange, "isWithinWorkflowAutonomyRange");
|
|
2535
|
+
__name2(isWithinWorkflowAutonomyRange, "isWithinWorkflowAutonomyRange");
|
|
2536
|
+
__name(workflowAutonomyRangeMessage, "workflowAutonomyRangeMessage");
|
|
2537
|
+
__name2(workflowAutonomyRangeMessage, "workflowAutonomyRangeMessage");
|
|
2538
|
+
WORKFLOW_JOB_RANGES = Object.freeze({
|
|
2539
|
+
/** Coding-turn cap (`claude -p --max-turns`); absent ⇒ the cluster default (LUA_WF_JOB_MAX_TURNS). */
|
|
2540
|
+
maxTurns: Object.freeze({
|
|
2541
|
+
min: 1,
|
|
2542
|
+
max: 500
|
|
2543
|
+
}),
|
|
2544
|
+
/** Harness messages per attempt (one per content block); absent ⇒ the cluster default (400). */
|
|
2545
|
+
maxMessages: Object.freeze({
|
|
2546
|
+
min: 1,
|
|
2547
|
+
max: 5e3
|
|
2548
|
+
}),
|
|
2549
|
+
/** Input-side tokens per attempt (prompt + cache); absent ⇒ the cluster default (4M — LUA-708, was 30M). */
|
|
2550
|
+
maxInputTokens: Object.freeze({
|
|
2551
|
+
min: 1e6,
|
|
2552
|
+
max: 5e8
|
|
2553
|
+
})
|
|
2554
|
+
});
|
|
2555
|
+
WORKFLOW_JOB_RANGE_MEMBERS = Object.keys(WORKFLOW_JOB_RANGES);
|
|
2556
|
+
__name(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
|
|
2557
|
+
__name2(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
|
|
2558
|
+
__name(workflowJobRangeMessage, "workflowJobRangeMessage");
|
|
2559
|
+
__name2(workflowJobRangeMessage, "workflowJobRangeMessage");
|
|
2560
|
+
WORKFLOW_SINGLE_STEP_TYPES = [
|
|
2561
|
+
"agent",
|
|
2562
|
+
"tool",
|
|
2563
|
+
"workflow",
|
|
2564
|
+
"step"
|
|
2565
|
+
];
|
|
2566
|
+
WORKFLOW_HITL_ENTRY_TYPES = [
|
|
2567
|
+
"approval",
|
|
2568
|
+
"waitForSignal"
|
|
2569
|
+
];
|
|
2570
|
+
WORKFLOW_ARM_ENTRY_TYPES = [
|
|
2571
|
+
...WORKFLOW_SINGLE_STEP_TYPES,
|
|
2572
|
+
...WORKFLOW_HITL_ENTRY_TYPES
|
|
2573
|
+
];
|
|
2574
|
+
WORKFLOW_HITL_ARM_CONTAINERS = [
|
|
2575
|
+
"parallel",
|
|
2576
|
+
"conditional",
|
|
2577
|
+
"foreach"
|
|
2578
|
+
];
|
|
2579
|
+
__name(isWorkflowSingleStepType, "isWorkflowSingleStepType");
|
|
2580
|
+
__name2(isWorkflowSingleStepType, "isWorkflowSingleStepType");
|
|
2581
|
+
__name(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
|
|
2582
|
+
__name2(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
|
|
2583
|
+
__name(isWorkflowArmEntryType, "isWorkflowArmEntryType");
|
|
2584
|
+
__name2(isWorkflowArmEntryType, "isWorkflowArmEntryType");
|
|
2585
|
+
__name(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
|
|
2586
|
+
__name2(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
|
|
2587
|
+
__name(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
|
|
2588
|
+
__name2(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
|
|
2589
|
+
__name(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
|
|
2590
|
+
__name2(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
|
|
2591
|
+
WORKFLOW_GRAPH_ENTRY_STEP_KINDS = Object.freeze({
|
|
2592
|
+
agent: "agent",
|
|
2593
|
+
tool: "tool",
|
|
2594
|
+
workflow: "subrun",
|
|
2595
|
+
step: "code",
|
|
2596
|
+
mapping: "map",
|
|
2597
|
+
sleep: "sleep",
|
|
2598
|
+
sleepUntil: "sleepUntil",
|
|
2599
|
+
parallel: null,
|
|
2600
|
+
conditional: "branch",
|
|
2601
|
+
foreach: "foreach",
|
|
2602
|
+
loop: "loop",
|
|
2603
|
+
approval: "approval",
|
|
2604
|
+
waitForSignal: "signal"
|
|
2605
|
+
});
|
|
2606
|
+
WORKFLOW_ARM_ENTRY_STEP_KINDS = Object.freeze(Object.fromEntries(WORKFLOW_ARM_ENTRY_TYPES.map((t) => [
|
|
2607
|
+
t,
|
|
2608
|
+
WORKFLOW_GRAPH_ENTRY_STEP_KINDS[t]
|
|
2609
|
+
])));
|
|
2610
|
+
WORKFLOW_BUDGET_MAX_DURATION_SECONDS = Object.freeze({
|
|
2611
|
+
min: 60,
|
|
2612
|
+
max: 2592e3
|
|
2613
|
+
});
|
|
2351
2614
|
MODEL_ID_BYOK_PROVIDERS = [
|
|
2352
2615
|
"azure",
|
|
2353
2616
|
"bedrock"
|
|
2354
2617
|
];
|
|
2355
2618
|
__name(isModelIdSentinel, "isModelIdSentinel");
|
|
2356
2619
|
__name2(isModelIdSentinel, "isModelIdSentinel");
|
|
2620
|
+
MODEL_CLASS_REF_PREFIX = "class/";
|
|
2621
|
+
__name(isModelClassRef, "isModelClassRef");
|
|
2622
|
+
__name2(isModelClassRef, "isModelClassRef");
|
|
2623
|
+
__name(modelClassOf, "modelClassOf");
|
|
2624
|
+
__name2(modelClassOf, "modelClassOf");
|
|
2625
|
+
__name(modelClassRef, "modelClassRef");
|
|
2626
|
+
__name2(modelClassRef, "modelClassRef");
|
|
2357
2627
|
__name(normalizeModelId, "normalizeModelId");
|
|
2358
2628
|
__name2(normalizeModelId, "normalizeModelId");
|
|
2359
2629
|
__name(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
2360
2630
|
__name2(modelUnresolvedMessage, "modelUnresolvedMessage");
|
|
2631
|
+
__name(modelClassUnresolvedMessage, "modelClassUnresolvedMessage");
|
|
2632
|
+
__name2(modelClassUnresolvedMessage, "modelClassUnresolvedMessage");
|
|
2361
2633
|
__name(providerModelId, "providerModelId");
|
|
2362
2634
|
__name2(providerModelId, "providerModelId");
|
|
2363
2635
|
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 +3302,15 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3030
3302
|
"org-grant",
|
|
3031
3303
|
"agent-grant-only"
|
|
3032
3304
|
]).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()
|
|
3305
|
+
anomalies: z3.array(ProjectionAnomalySchema).optional(),
|
|
3306
|
+
/**
|
|
3307
|
+
* How many agents and Spaces in this org the caller can read — the size of
|
|
3308
|
+
* the org's resource page under the same discovery rule, without paging it.
|
|
3309
|
+
*/
|
|
3310
|
+
resourceCounts: z3.object({
|
|
3311
|
+
agents: z3.number().int().nonnegative(),
|
|
3312
|
+
spaces: z3.number().int().nonnegative()
|
|
3313
|
+
}).optional()
|
|
3034
3314
|
}).passthrough();
|
|
3035
3315
|
ProjectedResourceSchema = z3.object({
|
|
3036
3316
|
resourceType: z3.literal("agent"),
|
|
@@ -3069,7 +3349,21 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3069
3349
|
id: z3.string().min(1).max(256),
|
|
3070
3350
|
name: z3.string().optional(),
|
|
3071
3351
|
email: z3.string().optional()
|
|
3072
|
-
}).optional()
|
|
3352
|
+
}).optional(),
|
|
3353
|
+
/**
|
|
3354
|
+
* Presentation enrichment (PRO-1994), product data only — never influences
|
|
3355
|
+
* discovery. These moved off the O(orgs) `/context` roster onto the bounded
|
|
3356
|
+
* per-active-org resource page so Desktop stops paying an org-count-scaled
|
|
3357
|
+
* cost at sign-in. `persona`/`avatar` are loose (`PersonaText` / `AgentAvatar`
|
|
3358
|
+
* are structured-or-string), `platform` marks the org's Designer agent
|
|
3359
|
+
* (previously stamped only by `/context`; retires with PRO-1657).
|
|
3360
|
+
*/
|
|
3361
|
+
persona: z3.unknown().optional(),
|
|
3362
|
+
description: z3.string().optional(),
|
|
3363
|
+
avatar: z3.unknown().nullish(),
|
|
3364
|
+
platform: z3.boolean().optional(),
|
|
3365
|
+
/** A Space's supervised agent ids (`kind: 'space'` rows only). */
|
|
3366
|
+
supervisedAgents: z3.array(z3.string()).optional()
|
|
3073
3367
|
}).passthrough();
|
|
3074
3368
|
CapabilityProfilesSchema = z3.record(z3.string().min(1).max(64), z3.array(ProjectedScopeSchema));
|
|
3075
3369
|
RoleCatalogSchema = z3.record(z3.string().min(1).max(128), z3.object({
|
|
@@ -3159,7 +3453,8 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3159
3453
|
"org_archived",
|
|
3160
3454
|
"disabled",
|
|
3161
3455
|
"exception",
|
|
3162
|
-
"budget"
|
|
3456
|
+
"budget",
|
|
3457
|
+
"model_policy"
|
|
3163
3458
|
];
|
|
3164
3459
|
WORKFLOW_STEP_STATUSES = [
|
|
3165
3460
|
"pending",
|
|
@@ -3228,6 +3523,16 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3228
3523
|
__name2(workflowOrgSlotKey, "workflowOrgSlotKey");
|
|
3229
3524
|
WORKFLOW_JOURNAL_PROTOCOL_VERSION = 1;
|
|
3230
3525
|
WORKFLOW_CONNECTION_KEY_RE = /^[a-z][a-z0-9_-]{0,63}$/;
|
|
3526
|
+
WORKFLOW_JOB_MODEL_SOURCE_LABELS = {
|
|
3527
|
+
stamp: "lease stamp",
|
|
3528
|
+
initData: "run input",
|
|
3529
|
+
default: "placeholder default",
|
|
3530
|
+
node: "node.model",
|
|
3531
|
+
env: "platform default",
|
|
3532
|
+
org: "org default"
|
|
3533
|
+
};
|
|
3534
|
+
__name(workflowJobModelSourceLabel, "workflowJobModelSourceLabel");
|
|
3535
|
+
__name2(workflowJobModelSourceLabel, "workflowJobModelSourceLabel");
|
|
3231
3536
|
__name(scheduledTimeKey, "scheduledTimeKey");
|
|
3232
3537
|
__name2(scheduledTimeKey, "scheduledTimeKey");
|
|
3233
3538
|
__name(scheduledWorkflowRunIdForTime, "scheduledWorkflowRunIdForTime");
|
|
@@ -3244,126 +3549,6 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3244
3549
|
];
|
|
3245
3550
|
WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
|
|
3246
3551
|
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
3552
|
WORKFLOW_GOAL_JUDGE_SELF = "$self";
|
|
3368
3553
|
__name(workflowGoalJudgeKind, "workflowGoalJudgeKind");
|
|
3369
3554
|
__name2(workflowGoalJudgeKind, "workflowGoalJudgeKind");
|
|
@@ -3568,7 +3753,36 @@ This text is who you are for this person. As you learn them, their name, their w
|
|
|
3568
3753
|
"workflow.export.auto_pushed",
|
|
3569
3754
|
"workflow.retention.restamped",
|
|
3570
3755
|
"workflow.retention.reaped",
|
|
3571
|
-
"workflow.run.schema_migrated"
|
|
3756
|
+
"workflow.run.schema_migrated",
|
|
3757
|
+
// --- per-step model selection (Workflow Model Selection plan 6.5 / Appendix C.4) ---
|
|
3758
|
+
/** A `PATCH /admin/orgs/:orgId/workflow-policy` that changed the `models` block (who, what moved). */
|
|
3759
|
+
"workflow.policy.models_changed",
|
|
3760
|
+
/** A step's invocation hopped to another leg of its class — `{from, to, reason}`, priced at the served model. */
|
|
3761
|
+
"workflow.step.model_fallback",
|
|
3762
|
+
// --- autonomy envelope (Workflow autonomy plan A1; research/consent-gates.md §H2) ---
|
|
3763
|
+
/**
|
|
3764
|
+
* A start the consent ladder would have PARKED was admitted by `workflowPolicy.autonomy` instead —
|
|
3765
|
+
* `WorkflowRunAutonomyAppliedPayload`. Deliberately NOT `workflow.run.gate_cleared`: nothing was
|
|
3766
|
+
* gated and nobody approved it, and conflating the two would make "who approved this run"
|
|
3767
|
+
* unanswerable for every run of either kind (§H2 "Audit").
|
|
3768
|
+
*/
|
|
3769
|
+
"workflow.run.autonomy_applied",
|
|
3770
|
+
// --- run budget cap enforcement (Job-tier billing plan D4; BAC-677) ---
|
|
3771
|
+
/**
|
|
3772
|
+
* The audit twin of the `run.budget_exceeded` run event (WJB-B2a): the run overshot its
|
|
3773
|
+
* `budget.maxCredits` on its LAST step and completed anyway, `budget.exceeded: true`. The budget family
|
|
3774
|
+
* already mirrors run events here — `workflow.run.budget_parked` / `workflow.run.budget_raised` are the
|
|
3775
|
+
* twins of `run.budget_parked` / `run.budget_raised` — and an organisation reviewing what it was charged
|
|
3776
|
+
* needs the overshoot in the audit store beside the raise that preceded it, not only in the run's own
|
|
3777
|
+
* event stream.
|
|
3778
|
+
*
|
|
3779
|
+
* Declared with the run event rather than after it because the emitter port
|
|
3780
|
+
* (`WorkflowAuditPort.action`, typed `workflow.run.${string}`) does not check against this tuple: a name
|
|
3781
|
+
* that is NOT declared here is written to the audit store all the same and no compiler says so.
|
|
3782
|
+
* Declaring it is what makes the later emitter checkable. `workflow.run.budget_parked` is likewise
|
|
3783
|
+
* declared and not yet emitted.
|
|
3784
|
+
*/
|
|
3785
|
+
"workflow.run.budget_exceeded"
|
|
3572
3786
|
];
|
|
3573
3787
|
WORKFLOW_AUDIT_METADATA_MAX_BYTES = 4 * 1024;
|
|
3574
3788
|
__name(isWorkflowAuditEvent, "isWorkflowAuditEvent");
|
|
@@ -4629,7 +4843,7 @@ function modelTemplateInvalidMessage(model, why) {
|
|
|
4629
4843
|
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
4844
|
}
|
|
4631
4845
|
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>}")}`;
|
|
4846
|
+
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
4847
|
}
|
|
4634
4848
|
function staticModelPin(model) {
|
|
4635
4849
|
if (typeof model !== "string") return void 0;
|
|
@@ -5221,6 +5435,21 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5221
5435
|
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
5436
|
}
|
|
5223
5437
|
}, "checkRequiredConnections");
|
|
5438
|
+
const jobClassifiablePin = /* @__PURE__ */ __name4((model) => {
|
|
5439
|
+
const pin = staticModelPin(model);
|
|
5440
|
+
const modelClass = modelClassOf(pin);
|
|
5441
|
+
if (modelClass === void 0) return pin;
|
|
5442
|
+
const codes = opts.classMap?.[modelClass];
|
|
5443
|
+
if (!codes) return void 0;
|
|
5444
|
+
const jobProviders = opts.policy?.jobProviders;
|
|
5445
|
+
for (const code of codes) {
|
|
5446
|
+
const p = classifyModelProvider(code);
|
|
5447
|
+
if (p === null) continue;
|
|
5448
|
+
if (jobProviders && !jobProviders.includes(p)) continue;
|
|
5449
|
+
return code;
|
|
5450
|
+
}
|
|
5451
|
+
return void 0;
|
|
5452
|
+
}, "jobClassifiablePin");
|
|
5224
5453
|
const checkTier = /* @__PURE__ */ __name4((node, path26) => {
|
|
5225
5454
|
const id = singleId(node);
|
|
5226
5455
|
if (node.workspace && node.workspace !== "inherit" && node.tier !== void 0 && node.tier !== "job") {
|
|
@@ -5229,7 +5458,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5229
5458
|
if (node.harness !== void 0 && node.tier !== "job") {
|
|
5230
5459
|
err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path26}.harness`, id);
|
|
5231
5460
|
}
|
|
5232
|
-
const provider = node.type === "agent" ? classifyModelProvider(
|
|
5461
|
+
const provider = node.type === "agent" ? classifyModelProvider(jobClassifiablePin(node.model)) : null;
|
|
5233
5462
|
if (node.harness === "claude-code" && provider !== null && provider !== "anthropic") {
|
|
5234
5463
|
err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path26}.harness`, id);
|
|
5235
5464
|
}
|
|
@@ -5253,6 +5482,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5253
5482
|
}
|
|
5254
5483
|
const pin = parsed.kind === "template" ? parsed.template.default : node.model;
|
|
5255
5484
|
if (pin === void 0) return;
|
|
5485
|
+
if (isModelClassRef(pin)) return;
|
|
5256
5486
|
const inContext = /* @__PURE__ */ __name4((message) => parsed.kind === "template" ? `${message} (the default of ${parsed.template.placeholder})` : message, "inContext");
|
|
5257
5487
|
const registry = opts.approvedModels;
|
|
5258
5488
|
if (registry === void 0) return;
|
|
@@ -5266,6 +5496,12 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5266
5496
|
const resolved = normalizeModelId(pin, registry);
|
|
5267
5497
|
if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path26}.model`, id);
|
|
5268
5498
|
}, "checkModel");
|
|
5499
|
+
const checkTaskClass = /* @__PURE__ */ __name4((node, path26) => {
|
|
5500
|
+
if (node.type !== "agent" || node.taskClass === void 0) return;
|
|
5501
|
+
if (!opts.static) return;
|
|
5502
|
+
if (typeof node.model === "string" && node.model.trim()) return;
|
|
5503
|
+
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));
|
|
5504
|
+
}, "checkTaskClass");
|
|
5269
5505
|
const checkWorkspace = /* @__PURE__ */ __name4((node, path26) => {
|
|
5270
5506
|
const id = singleId(node);
|
|
5271
5507
|
const ws = workspaceOf(node);
|
|
@@ -5352,6 +5588,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
|
|
|
5352
5588
|
checkTimeout(node, path26);
|
|
5353
5589
|
checkTier(node, path26);
|
|
5354
5590
|
checkModel(node, path26);
|
|
5591
|
+
checkTaskClass(node, path26);
|
|
5355
5592
|
checkRetry(node, path26);
|
|
5356
5593
|
checkWorkspace(node, path26);
|
|
5357
5594
|
if (!opts.static) {
|
|
@@ -7784,6 +8021,49 @@ function graphHasJobTierStep(envelopeOrGraph) {
|
|
|
7784
8021
|
const graph = Array.isArray(envelopeOrGraph) ? envelopeOrGraph : env.definition?.graph ?? [];
|
|
7785
8022
|
return Array.isArray(graph) && graph.some(entryHasJobTier);
|
|
7786
8023
|
}
|
|
8024
|
+
function jobTierSteps(envelopeOrGraph) {
|
|
8025
|
+
const out = [];
|
|
8026
|
+
if (!envelopeOrGraph || typeof envelopeOrGraph !== "object") return out;
|
|
8027
|
+
const env = envelopeOrGraph;
|
|
8028
|
+
const graph = Array.isArray(envelopeOrGraph) ? envelopeOrGraph : env.definition?.graph ?? [];
|
|
8029
|
+
if (!Array.isArray(graph)) return out;
|
|
8030
|
+
for (const entry of graph) collectJobTierSteps(entry, out);
|
|
8031
|
+
return out;
|
|
8032
|
+
}
|
|
8033
|
+
function jobTierStepIds(envelopeOrGraph) {
|
|
8034
|
+
return jobTierSteps(envelopeOrGraph).map((s) => s.stepId);
|
|
8035
|
+
}
|
|
8036
|
+
function collectJobTierSteps(entry, out) {
|
|
8037
|
+
const n2 = armEntry2(entry);
|
|
8038
|
+
if (!n2 || typeof n2 !== "object") return;
|
|
8039
|
+
const node = n2;
|
|
8040
|
+
const ws = node.workspace;
|
|
8041
|
+
if (node.tier === "job" || ws !== void 0 && ws !== "inherit") {
|
|
8042
|
+
const stepId = typeof node.id === "string" && node.id ? node.id : "(unnamed)";
|
|
8043
|
+
const model = typeof node.model === "string" && node.model.trim() ? node.model.trim() : void 0;
|
|
8044
|
+
out.push(model === void 0 ? {
|
|
8045
|
+
stepId
|
|
8046
|
+
} : {
|
|
8047
|
+
stepId,
|
|
8048
|
+
model
|
|
8049
|
+
});
|
|
8050
|
+
}
|
|
8051
|
+
switch (node.type) {
|
|
8052
|
+
case "parallel":
|
|
8053
|
+
if (Array.isArray(node.steps)) for (const s of node.steps) collectJobTierSteps(s, out);
|
|
8054
|
+
return;
|
|
8055
|
+
case "conditional":
|
|
8056
|
+
if (Array.isArray(node.steps)) for (const s of node.steps) collectJobTierSteps(s, out);
|
|
8057
|
+
if (node.otherwise !== void 0) collectJobTierSteps(node.otherwise, out);
|
|
8058
|
+
return;
|
|
8059
|
+
case "foreach":
|
|
8060
|
+
case "loop":
|
|
8061
|
+
collectJobTierSteps(node.step, out);
|
|
8062
|
+
return;
|
|
8063
|
+
default:
|
|
8064
|
+
return;
|
|
8065
|
+
}
|
|
8066
|
+
}
|
|
7787
8067
|
var __defProp4, __name4, WorkflowTemplateError, TEMPLATE_PLACEHOLDER, TEMPLATE_NAMESPACES, MAP_DESCRIPTOR_KEYS, MAP_MEMBER_MALFORMED_CODE, fromInit, fromStep, value, template, fromRequest, rows, fromKnowledge, SideEffectsSchema, JobResourcesSchema, WORKFLOW_MODEL_TEMPLATE_ROOT, WORKFLOW_MODEL_TEMPLATE_RE, PATH_SEGMENT_RE, APPROVER_SPEC_MAX_USERS, ESCALATION_MAX_HOPS, TemplateBindingSchema, ApproverSpecSchema, FourEyesSchema, EscalationHopSchema, TerminalOutcomeSchema, ApprovalOnTimeoutSchema, APPROVER_SPEC_SHAPES, APPROVER_WRITTEN_MAX, USER_ID_SHAPED_RE, BINDING_ROOTS, WORKSPACE_TEMPLATE_EXPR_RE, SLEEP_UNTIL_REPLACEMENT, WORKFLOW_CAPS_DEFAULT, WORKFLOW_STEP_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_AGENT_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_JOB_DEFAULT_TIMEOUT_SECONDS, WORKFLOW_FOREACH_DEFAULT_CONCURRENCY, WORKFLOW_FOREACH_DEFAULT_MAX_ITEMS, WORKFLOW_LOOP_DEFAULT_MAX_ITERATIONS, WORKFLOW_SUSPEND_DEFAULT_TIMEOUT_HOURS, WORKFLOW_SIGNAL_DEFAULT_SOURCES, clone, CONNECTION_ID_HEX_RE, WORKFLOW_JOB_MAX_WORKTREE_ARMS, workspaceOf, mountsWorkspace, isJobTier, jobToolsOf, schemaIsArray, isHitlNode, isSingleStep, singleId, armId, TEMPLATE_STEP_REF, EDITABLE_PATH_RE, PREDICATE_OPS, isPredicateScalar, GRAPH_HASH_PREFIX, WorkflowPlanError, isArmStep, armStepId, armStepKind, joinIdOf, containerIdOf, PATH_PLACEHOLDER, MISSING, stepIdOf, cmp, eq, ne, gt, gte, lt, lte, inSet, notIn, exists, notExists, truthy, falsy, and, or, not, CONTINUED_FAILURE_TAG, CONTINUED_FAILURE_DEFAULT_CODE, CONTINUED_FAILURE_OUTPUT_SCHEMA, CONTINUED_FAILURE_LEAF_PATHS, isHitlNode2, nodeIdOf, GOAL_JUDGE_STEP_ID, NON_LEAF_KINDS, CONDITIONAL_JOIN_ID, branchArmId, canonical, sortKeys, JOIN, entryOfJoin, FORCE_CANCEL_STALE_MS, TERMINAL, WORKFLOW_INLINE_RUN_TAG, RUN_ERROR_ISSUES_MAX, IN_FLIGHT, n, STEP_ERROR_DETAIL_KEYS, STEP_ERROR_DETAIL_MAX_BYTES, DETAIL_MAX_DEPTH, DETAIL_MAX_ITEMS, MAX_HOLIDAYS, MAX_WALK_DAYS, HHMM, YMD, MS_PER_MIN, MS_PER_DAY, MON_FRI, supportedTz, fmtCache, WEEKDAYS, JSON_PATCH_OPS, JSON_PATCH_MAX_OPS, JSON_PATCH_MAX_VALUE_BYTES, JSON_PATCH_MAX_TOTAL_BYTES, SEGMENT_RE, WORKFLOW_SCHEDULE_TYPES, WORKFLOW_SCHEDULE_SHAPE_ISSUE, WORKFLOW_SCHEDULE_SHAPES_HINT, WORKFLOW_SCHEDULE_RUN_AS, isObject, WORKFLOW_ENV_OVERLAY_MAX_KEYS, WORKFLOW_ENV_OVERLAY_MAX_VALUE_BYTES, WORKFLOW_ENV_TEMPLATE_SECRET_KEY_RE, isEnvRef, looksLikeEmbeddedJson, ZERO, isRecord2;
|
|
7788
8068
|
var init_dist2 = __esm({
|
|
7789
8069
|
"../workflow-graph/dist/index.mjs"() {
|
|
@@ -8588,6 +8868,12 @@ var init_dist2 = __esm({
|
|
|
8588
8868
|
__name4(entryHasJobTier, "entryHasJobTier");
|
|
8589
8869
|
__name(graphHasJobTierStep, "graphHasJobTierStep");
|
|
8590
8870
|
__name4(graphHasJobTierStep, "graphHasJobTierStep");
|
|
8871
|
+
__name(jobTierSteps, "jobTierSteps");
|
|
8872
|
+
__name4(jobTierSteps, "jobTierSteps");
|
|
8873
|
+
__name(jobTierStepIds, "jobTierStepIds");
|
|
8874
|
+
__name4(jobTierStepIds, "jobTierStepIds");
|
|
8875
|
+
__name(collectJobTierSteps, "collectJobTierSteps");
|
|
8876
|
+
__name4(collectJobTierSteps, "collectJobTierSteps");
|
|
8591
8877
|
}
|
|
8592
8878
|
});
|
|
8593
8879
|
|
|
@@ -8921,6 +9207,10 @@ var init_workflow = __esm({
|
|
|
8921
9207
|
maxDurationSeconds: cfg.budget?.maxDurationSeconds ?? (hitl ? WORKFLOW_HITL_MAX_DURATION_SECONDS : WORKFLOW_DEFAULT_MAX_DURATION_SECONDS)
|
|
8922
9208
|
});
|
|
8923
9209
|
const envelope = {
|
|
9210
|
+
// A plain build/push is ALWAYS marker 1 (plan 6.4's compatibility row: "a CLI test that a plain push of
|
|
9211
|
+
// such a definition stays at 1"). Moving a definition to 2 — the effort marker — is an explicit act
|
|
9212
|
+
// (`lua push --apply-effort`, or a new compose while assignment is on), never a side effect of the SDK
|
|
9213
|
+
// gaining an `effort` member.
|
|
8924
9214
|
luaWorkflow: 1,
|
|
8925
9215
|
budget,
|
|
8926
9216
|
definition: defined({
|
|
@@ -9241,6 +9531,10 @@ var init_workflow = __esm({
|
|
|
9241
9531
|
promptTemplate: templateText(opts.prompt),
|
|
9242
9532
|
outputSchema: schemaToJson(opts.outputSchema),
|
|
9243
9533
|
model: opts.model,
|
|
9534
|
+
taskClass: opts.taskClass,
|
|
9535
|
+
requires: opts.requires,
|
|
9536
|
+
modelReason: opts.modelReason,
|
|
9537
|
+
effort: opts.effort,
|
|
9244
9538
|
toolScope: opts.toolScope,
|
|
9245
9539
|
systemPrompt: opts.systemPrompt,
|
|
9246
9540
|
timeoutSeconds: opts.timeoutSeconds,
|
|
@@ -20340,6 +20634,8 @@ function sketchTopology(sourceFile, exportName, name, description) {
|
|
|
20340
20634
|
}
|
|
20341
20635
|
return {
|
|
20342
20636
|
graph: {
|
|
20637
|
+
// 1 is and stays the serializer's marker: the effort marker (2) is opted into by
|
|
20638
|
+
// `lua push --apply-effort` or a new compose (plan 6.4), never by a plain compile.
|
|
20343
20639
|
luaWorkflow: 1,
|
|
20344
20640
|
definition: {
|
|
20345
20641
|
id: name,
|
|
@@ -20465,7 +20761,7 @@ function computeDeferred(graph, opts = {}) {
|
|
|
20465
20761
|
deferred.add("job-tier-provider-unsupported");
|
|
20466
20762
|
}
|
|
20467
20763
|
const modelPin = n2.type === "agent" ? staticModelPin(n2.model) : void 0;
|
|
20468
|
-
if (modelPin !== void 0 && !isModelIdSentinel(modelPin)) deferred.add("model-unresolved");
|
|
20764
|
+
if (modelPin !== void 0 && !isModelIdSentinel(modelPin) && !isModelClassRef(modelPin)) deferred.add("model-unresolved");
|
|
20469
20765
|
if (Array.isArray(n2.requiredConnections) && n2.requiredConnections.some(serverDecides)) deferred.add("required-connection-unknown");
|
|
20470
20766
|
if (n2.type === "approval") {
|
|
20471
20767
|
const a = n2.approver;
|
|
@@ -26430,6 +26726,68 @@ var init_workflow_api_service = __esm({
|
|
|
26430
26726
|
const qs = query.toString();
|
|
26431
26727
|
return this.httpGet(`${this.runs}/${runId}/steps/${pathId(stepId)}/job${qs ? `?${qs}` : ""}`, await this.auth());
|
|
26432
26728
|
}
|
|
26729
|
+
// ─── [WMC-E7] Per-step model selection (§6.5, §6.7) ───
|
|
26730
|
+
/**
|
|
26731
|
+
* §6.5 — the organization's workflow policy, `models` block included. The route is the organization's, not
|
|
26732
|
+
* the agent's, so the orgId comes from the project config rather than from `this.agentId`.
|
|
26733
|
+
*/
|
|
26734
|
+
async getWorkflowPolicy(orgId, opts = {}) {
|
|
26735
|
+
const qs = opts.effective ? "?effective=true" : "";
|
|
26736
|
+
return this.httpGet(`/admin/orgs/${encodeURIComponent(orgId)}/workflow-policy${qs}`, await this.auth());
|
|
26737
|
+
}
|
|
26738
|
+
/**
|
|
26739
|
+
* §6.5 — PATCH the `models` block. Only the members the caller named are sent, so a `set` of one field
|
|
26740
|
+
* never clears the rest; the server validates against the organization's effective model set and refuses
|
|
26741
|
+
* with a code the CLI prints verbatim (a class with no eligible row, a cap the raise would exceed).
|
|
26742
|
+
*/
|
|
26743
|
+
async patchWorkflowPolicyModels(orgId, models) {
|
|
26744
|
+
return this.httpPatch(`/admin/orgs/${encodeURIComponent(orgId)}/workflow-policy`, {
|
|
26745
|
+
models
|
|
26746
|
+
}, await this.auth());
|
|
26747
|
+
}
|
|
26748
|
+
// ─── [WMC-A6] Autonomy — the pre-consented envelope (research §H3) ───
|
|
26749
|
+
/**
|
|
26750
|
+
* PATCH the `autonomy` block of the ORGANIZATION's policy — the same R23 route the `models` block uses, and
|
|
26751
|
+
* a sibling of it in the body, so one PATCH never has to carry two blocks it did not mean to touch.
|
|
26752
|
+
*
|
|
26753
|
+
* A member sent as `null` is CLEARED (`--clear`); a member omitted is left exactly as it was. That
|
|
26754
|
+
* distinction is the route's, not the CLI's — which is why the patch type carries `null` rather than the CLI
|
|
26755
|
+
* collapsing it to an absent key on the way out.
|
|
26756
|
+
*
|
|
26757
|
+
* Every ceiling is the server's: `caps.maxCreditsPerRun`, the organization's own `models.consentActions` and
|
|
26758
|
+
* the platform's runs-per-hour env are all figures this client has never seen, so a value above one comes
|
|
26759
|
+
* back as a typed 400 and is printed verbatim.
|
|
26760
|
+
*/
|
|
26761
|
+
async patchWorkflowPolicyAutonomy(orgId, autonomy) {
|
|
26762
|
+
return this.httpPatch(`/admin/orgs/${encodeURIComponent(orgId)}/workflow-policy`, {
|
|
26763
|
+
autonomy
|
|
26764
|
+
}, await this.auth());
|
|
26765
|
+
}
|
|
26766
|
+
/*
|
|
26767
|
+
* There is deliberately NO per-agent writer here. `SubAgentWorkflowSettings.autonomy` is read by
|
|
26768
|
+
* `effectiveWorkflowAutonomy`, but no HTTP surface writes it: `UpdateSubAgentRequestDto` has no
|
|
26769
|
+
* `workflows` member, so a PATCH carrying one is accepted and DISCARDED. A client method that posted a
|
|
26770
|
+
* narrowing into that hole would return 200 and change nothing, and the CLI would print a success line
|
|
26771
|
+
* over it — on a consent surface, a false confirmation is worse than a missing feature. The read half
|
|
26772
|
+
* already works: `?effective=true` shows a per-agent narrowing when the projection carries one.
|
|
26773
|
+
*/
|
|
26774
|
+
/**
|
|
26775
|
+
* §6.5 — clear a run gate by kind. `model_policy` is the kind a class request that could not be resolved
|
|
26776
|
+
* parks on; the sweep clears it on its own when the switch returns, and this is the by-hand path.
|
|
26777
|
+
*/
|
|
26778
|
+
async clearRunGate(runId, kind) {
|
|
26779
|
+
return this.httpPost(`${this.runs}/${runId}/clear-gate`, {
|
|
26780
|
+
kind
|
|
26781
|
+
}, await this.auth());
|
|
26782
|
+
}
|
|
26783
|
+
/**
|
|
26784
|
+
* §6.4 (Q19) — the deterministic rewrite of a dynamic parent's stored task classes into `class/<c>`.
|
|
26785
|
+
* Not a fresh model composition: the server rewrites and publishes a NEW version on the immutable parent,
|
|
26786
|
+
* and answers with it, so the CLI only has to print the version it got back.
|
|
26787
|
+
*/
|
|
26788
|
+
async recomposeWorkflow(workflowId) {
|
|
26789
|
+
return this.httpPost(`${this.base}/${workflowId}/recompose`, {}, await this.auth());
|
|
26790
|
+
}
|
|
26433
26791
|
};
|
|
26434
26792
|
}
|
|
26435
26793
|
});
|
|
@@ -36063,6 +36421,117 @@ __name(describeEnvOverlay, "describeEnvOverlay");
|
|
|
36063
36421
|
|
|
36064
36422
|
// src/primitives/workflow.handler.ts
|
|
36065
36423
|
init_base_handler();
|
|
36424
|
+
|
|
36425
|
+
// src/interfaces/workflow-model-classes.ts
|
|
36426
|
+
init_dist();
|
|
36427
|
+
var has = /* @__PURE__ */ __name((tuple, v) => tuple.includes(v), "has");
|
|
36428
|
+
var isWorkflowModelClass = /* @__PURE__ */ __name((v) => has(WORKFLOW_MODEL_CLASSES, v), "isWorkflowModelClass");
|
|
36429
|
+
var isWorkflowTaskClass = /* @__PURE__ */ __name((v) => has(WORKFLOW_TASK_CLASSES, v), "isWorkflowTaskClass");
|
|
36430
|
+
var isWorkflowModelTrait = /* @__PURE__ */ __name((v) => has(WORKFLOW_MODEL_TRAITS, v), "isWorkflowModelTrait");
|
|
36431
|
+
var isWorkflowEffort = /* @__PURE__ */ __name((v) => has(WORKFLOW_AGENT_EFFORTS, v), "isWorkflowEffort");
|
|
36432
|
+
function isWrittenAsModelClassRef(model) {
|
|
36433
|
+
return (model ?? "").trim().toLowerCase().startsWith(MODEL_CLASS_REF_PREFIX);
|
|
36434
|
+
}
|
|
36435
|
+
__name(isWrittenAsModelClassRef, "isWrittenAsModelClassRef");
|
|
36436
|
+
var oneOf = /* @__PURE__ */ __name((tuple) => tuple.map((v) => `\`${v}\``).join(", "), "oneOf");
|
|
36437
|
+
function validateAgentNodeModelMembers(node, path26) {
|
|
36438
|
+
const issues = [];
|
|
36439
|
+
if (typeof node.model === "string" && isWrittenAsModelClassRef(node.model)) {
|
|
36440
|
+
if (!modelClassOf(node.model)) {
|
|
36441
|
+
issues.push({
|
|
36442
|
+
path: `${path26}.model`,
|
|
36443
|
+
code: "model-class-unknown",
|
|
36444
|
+
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`
|
|
36445
|
+
});
|
|
36446
|
+
}
|
|
36447
|
+
}
|
|
36448
|
+
if (node.taskClass !== void 0) {
|
|
36449
|
+
if (typeof node.taskClass !== "string" || !isWorkflowTaskClass(node.taskClass)) {
|
|
36450
|
+
issues.push({
|
|
36451
|
+
path: `${path26}.taskClass`,
|
|
36452
|
+
code: "task-class-unknown",
|
|
36453
|
+
message: `"${String(node.taskClass)}" is not a task class \u2014 use one of ${oneOf(WORKFLOW_TASK_CLASSES)}`
|
|
36454
|
+
});
|
|
36455
|
+
}
|
|
36456
|
+
}
|
|
36457
|
+
if (node.requires !== void 0) {
|
|
36458
|
+
if (!Array.isArray(node.requires)) {
|
|
36459
|
+
issues.push({
|
|
36460
|
+
path: `${path26}.requires`,
|
|
36461
|
+
code: "requires-invalid",
|
|
36462
|
+
message: `\`requires\` must be an array of ${oneOf(WORKFLOW_MODEL_TRAITS)}`
|
|
36463
|
+
});
|
|
36464
|
+
} else {
|
|
36465
|
+
node.requires.forEach((trait, i) => {
|
|
36466
|
+
if (typeof trait !== "string" || !isWorkflowModelTrait(trait)) {
|
|
36467
|
+
issues.push({
|
|
36468
|
+
path: `${path26}.requires.${i}`,
|
|
36469
|
+
code: "model-trait-unknown",
|
|
36470
|
+
message: `"${String(trait)}" is not a model trait \u2014 use one of ${oneOf(WORKFLOW_MODEL_TRAITS)}`
|
|
36471
|
+
});
|
|
36472
|
+
}
|
|
36473
|
+
});
|
|
36474
|
+
}
|
|
36475
|
+
}
|
|
36476
|
+
if (node.effort !== void 0) {
|
|
36477
|
+
if (typeof node.effort !== "string" || !isWorkflowEffort(node.effort)) {
|
|
36478
|
+
issues.push({
|
|
36479
|
+
path: `${path26}.effort`,
|
|
36480
|
+
code: "effort-unknown",
|
|
36481
|
+
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.)`
|
|
36482
|
+
});
|
|
36483
|
+
}
|
|
36484
|
+
}
|
|
36485
|
+
if (node.modelReason !== void 0) {
|
|
36486
|
+
if (typeof node.modelReason !== "string") {
|
|
36487
|
+
issues.push({
|
|
36488
|
+
path: `${path26}.modelReason`,
|
|
36489
|
+
code: "model-reason-invalid",
|
|
36490
|
+
message: "`modelReason` must be a string"
|
|
36491
|
+
});
|
|
36492
|
+
} else if (node.modelReason.length > WORKFLOW_MODEL_REASON_MAX_LENGTH) {
|
|
36493
|
+
issues.push({
|
|
36494
|
+
path: `${path26}.modelReason`,
|
|
36495
|
+
code: "model-reason-too-long",
|
|
36496
|
+
message: `\`modelReason\` is ${node.modelReason.length} characters \u2014 the cap is ${WORKFLOW_MODEL_REASON_MAX_LENGTH}`
|
|
36497
|
+
});
|
|
36498
|
+
}
|
|
36499
|
+
}
|
|
36500
|
+
return issues;
|
|
36501
|
+
}
|
|
36502
|
+
__name(validateAgentNodeModelMembers, "validateAgentNodeModelMembers");
|
|
36503
|
+
var WORKFLOW_MODEL_WALK_MAX_DEPTH = 64;
|
|
36504
|
+
var MEMBERS = [
|
|
36505
|
+
"model",
|
|
36506
|
+
"taskClass",
|
|
36507
|
+
"requires",
|
|
36508
|
+
"effort",
|
|
36509
|
+
"modelReason"
|
|
36510
|
+
];
|
|
36511
|
+
function validateGraphModelMembers(graph) {
|
|
36512
|
+
const issues = [];
|
|
36513
|
+
const seen = /* @__PURE__ */ new Set();
|
|
36514
|
+
const walk3 = /* @__PURE__ */ __name((value3, path26, depth) => {
|
|
36515
|
+
if (depth > WORKFLOW_MODEL_WALK_MAX_DEPTH || value3 === null || typeof value3 !== "object") return;
|
|
36516
|
+
if (seen.has(value3)) return;
|
|
36517
|
+
seen.add(value3);
|
|
36518
|
+
if (Array.isArray(value3)) {
|
|
36519
|
+
value3.forEach((v, i) => walk3(v, `${path26}.${i}`, depth + 1));
|
|
36520
|
+
return;
|
|
36521
|
+
}
|
|
36522
|
+
const node = value3;
|
|
36523
|
+
if (MEMBERS.some((m) => node[m] !== void 0)) {
|
|
36524
|
+
const label2 = typeof node.id === "string" && node.id ? node.id : path26;
|
|
36525
|
+
issues.push(...validateAgentNodeModelMembers(node, label2));
|
|
36526
|
+
}
|
|
36527
|
+
for (const [k, v] of Object.entries(node)) walk3(v, path26 ? `${path26}.${k}` : k, depth + 1);
|
|
36528
|
+
}, "walk");
|
|
36529
|
+
walk3(graph, "", 0);
|
|
36530
|
+
return issues;
|
|
36531
|
+
}
|
|
36532
|
+
__name(validateGraphModelMembers, "validateGraphModelMembers");
|
|
36533
|
+
|
|
36534
|
+
// src/primitives/workflow.handler.ts
|
|
36066
36535
|
var WorkflowHandler = class extends BaseVersionedHandler {
|
|
36067
36536
|
static {
|
|
36068
36537
|
__name(this, "WorkflowHandler");
|
|
@@ -36147,6 +36616,8 @@ var WorkflowHandler = class extends BaseVersionedHandler {
|
|
|
36147
36616
|
const primitive = findPrimitive(manifest, name, this.kind);
|
|
36148
36617
|
if (!primitive) return null;
|
|
36149
36618
|
if (primitive.unplacedStepIds?.length) throw unplacedStepError(primitive.name, primitive.unplacedStepIds);
|
|
36619
|
+
const modelIssues = validateGraphModelMembers(primitive.form === "script" ? primitive.meta : primitive.graph);
|
|
36620
|
+
if (modelIssues.length) throw workflowModelMemberError(primitive.name, modelIssues);
|
|
36150
36621
|
if (primitive.form === "script") return this.buildPushData(primitive, void 0);
|
|
36151
36622
|
const data = super.prepareForPush(manifest, name, projectPath, bundleAccumulator);
|
|
36152
36623
|
if (!data) return null;
|
|
@@ -36293,6 +36764,17 @@ function workflowNameTakenHint(name, error) {
|
|
|
36293
36764
|
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.`;
|
|
36294
36765
|
}
|
|
36295
36766
|
__name(workflowNameTakenHint, "workflowNameTakenHint");
|
|
36767
|
+
function workflowModelMemberError(workflowName, issues) {
|
|
36768
|
+
return new CliError("error", `workflow "${workflowName}" is not pushed: ${issues.length} model-selection ${issues.length === 1 ? "value is" : "values are"} not in the vocabulary`, {
|
|
36769
|
+
issues: issues.map((i) => ({
|
|
36770
|
+
path: i.path,
|
|
36771
|
+
code: i.code,
|
|
36772
|
+
message: i.message
|
|
36773
|
+
})),
|
|
36774
|
+
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."
|
|
36775
|
+
});
|
|
36776
|
+
}
|
|
36777
|
+
__name(workflowModelMemberError, "workflowModelMemberError");
|
|
36296
36778
|
|
|
36297
36779
|
// src/primitives/index.ts
|
|
36298
36780
|
init_skill_handler();
|
|
@@ -36950,10 +37432,20 @@ var ALIAS_MAP = {
|
|
|
36950
37432
|
"jobs",
|
|
36951
37433
|
"job-logs",
|
|
36952
37434
|
"goals",
|
|
36953
|
-
"schedules"
|
|
37435
|
+
"schedules",
|
|
37436
|
+
// [WMC-E7] per-step model selection (§6.5, §6.7): the org's model policy, the `model_policy` gate,
|
|
37437
|
+
// and the deterministic rewrite of a definition composed before class resolution existed.
|
|
37438
|
+
"policy",
|
|
37439
|
+
"clear-gate",
|
|
37440
|
+
"recompose"
|
|
36954
37441
|
],
|
|
36955
37442
|
aliases: lowerKeys({
|
|
36956
37443
|
goal: "goals",
|
|
37444
|
+
policies: "policy",
|
|
37445
|
+
cleargate: "clear-gate",
|
|
37446
|
+
"clear-gates": "clear-gate",
|
|
37447
|
+
ungate: "clear-gate",
|
|
37448
|
+
recompile: "recompose",
|
|
36957
37449
|
schedule: "schedules",
|
|
36958
37450
|
sched: "schedules",
|
|
36959
37451
|
ws: "workspace",
|
|
@@ -37769,7 +38261,16 @@ var WORKFLOW_SCRIPT_REPLAY_SOURCE = String.raw`
|
|
|
37769
38261
|
function resolveModel(opts) {
|
|
37770
38262
|
if (opts && opts.model) return opts.model;
|
|
37771
38263
|
var ph = (opts && opts.phase) || currentPhase; var phases = __input.meta && __input.meta.phases;
|
|
37772
|
-
|
|
38264
|
+
var phase;
|
|
38265
|
+
if (ph && Array.isArray(phases)) for (var i = 0; i < phases.length; i++) if (phases[i] && phases[i].title === ph) { phase = phases[i]; break; }
|
|
38266
|
+
if (phase && phase.model) return phase.model;
|
|
38267
|
+
// WMC (plan 6.3 script-form parity): a task class on the call or on its phase resolves to the SAME
|
|
38268
|
+
// class/<c> sentinel the graph form writes, through the org's map on the tick input. No map (every run
|
|
38269
|
+
// before the feature, and every organisation with assignment off) => undefined, exactly as before.
|
|
38270
|
+
// NB: no backticks in this comment - the wrapper source is itself a template literal.
|
|
38271
|
+
var map = __input.modelClassMap;
|
|
38272
|
+
var tc = (opts && opts.taskClass) || (phase && phase.taskClass);
|
|
38273
|
+
if (tc && map && map[tc]) return 'class/' + map[tc];
|
|
37773
38274
|
return undefined;
|
|
37774
38275
|
}
|
|
37775
38276
|
function resolveRole(role) {
|
|
@@ -37961,6 +38462,12 @@ function computeWorkflowProtocolShipWindow(input) {
|
|
|
37961
38462
|
}
|
|
37962
38463
|
__name(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
|
|
37963
38464
|
__name8(computeWorkflowProtocolShipWindow, "computeWorkflowProtocolShipWindow");
|
|
38465
|
+
var WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION = 2;
|
|
38466
|
+
function scriptEffortForwardable(journalProtocolVersion) {
|
|
38467
|
+
return typeof journalProtocolVersion === "number" && journalProtocolVersion >= WORKFLOW_SCRIPT_EFFORT_PROTOCOL_VERSION;
|
|
38468
|
+
}
|
|
38469
|
+
__name(scriptEffortForwardable, "scriptEffortForwardable");
|
|
38470
|
+
__name8(scriptEffortForwardable, "scriptEffortForwardable");
|
|
37964
38471
|
function workflowScriptReplaySource(journalProtocolVersion) {
|
|
37965
38472
|
return WORKFLOW_SCRIPT_PROTOCOL_VERSIONS.includes(journalProtocolVersion) ? WORKFLOW_SCRIPT_REPLAY_SOURCES[journalProtocolVersion] : void 0;
|
|
37966
38473
|
}
|
|
@@ -40398,15 +40905,30 @@ function formatPushFailureSummary(failedItems) {
|
|
|
40398
40905
|
return lines.join("\n");
|
|
40399
40906
|
}
|
|
40400
40907
|
__name(formatPushFailureSummary, "formatPushFailureSummary");
|
|
40908
|
+
var MODEL_CLASS_RESOLUTION_OFF_CODES = [
|
|
40909
|
+
"model-class-resolution-off",
|
|
40910
|
+
"MODEL_CLASS_RESOLUTION_OFF"
|
|
40911
|
+
];
|
|
40912
|
+
function isModelClassResolutionOffCode(code) {
|
|
40913
|
+
if (!code) return false;
|
|
40914
|
+
const normal = code.toLowerCase().replace(/[^a-z]+/g, "-");
|
|
40915
|
+
if (MODEL_CLASS_RESOLUTION_OFF_CODES.some((c) => c.toLowerCase() === code.toLowerCase())) return true;
|
|
40916
|
+
const namesModelClass = normal.includes("model-class") || normal.includes("class-resolution");
|
|
40917
|
+
const namesOff = /(^|-)(off|disabled|unavailable|not-enabled)(-|$)/.test(normal);
|
|
40918
|
+
return namesModelClass && namesOff;
|
|
40919
|
+
}
|
|
40920
|
+
__name(isModelClassResolutionOffCode, "isModelClassResolutionOffCode");
|
|
40921
|
+
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.";
|
|
40401
40922
|
function pushRefusalError(handler, name, result) {
|
|
40402
40923
|
const reason = result.error || "Unknown error";
|
|
40403
40924
|
const isVersionConflict = reason.toLowerCase().includes("already exists");
|
|
40925
|
+
const classResolutionOff = isModelClassResolutionOffCode(result.code) || !!result.issues?.some((i) => isModelClassResolutionOffCode(i.code));
|
|
40404
40926
|
return new CliError("error", `${handler.displayName.toLowerCase()} "${name}" is not pushed: ${reason}`, {
|
|
40405
40927
|
exitCode: CLI_EXIT.ERROR,
|
|
40406
40928
|
statusCode: result.statusCode,
|
|
40407
40929
|
serverCode: result.code,
|
|
40408
40930
|
issues: result.issues,
|
|
40409
|
-
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
|
|
40931
|
+
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
|
|
40410
40932
|
});
|
|
40411
40933
|
}
|
|
40412
40934
|
__name(pushRefusalError, "pushRefusalError");
|
|
@@ -40419,8 +40941,31 @@ function stalePushEntryError(handler, name, entityId, serverMessage) {
|
|
|
40419
40941
|
});
|
|
40420
40942
|
}
|
|
40421
40943
|
__name(stalePushEntryError, "stalePushEntryError");
|
|
40944
|
+
var WORKFLOW_EFFORT_MARKER = 2;
|
|
40945
|
+
function applyEffortMarker(pushData, applyEffort) {
|
|
40946
|
+
if (!applyEffort) return pushData;
|
|
40947
|
+
const graph = pushData.graph;
|
|
40948
|
+
if (!graph || typeof graph !== "object") return pushData;
|
|
40949
|
+
return {
|
|
40950
|
+
...pushData,
|
|
40951
|
+
graph: {
|
|
40952
|
+
...graph,
|
|
40953
|
+
luaWorkflow: WORKFLOW_EFFORT_MARKER
|
|
40954
|
+
}
|
|
40955
|
+
};
|
|
40956
|
+
}
|
|
40957
|
+
__name(applyEffortMarker, "applyEffortMarker");
|
|
40958
|
+
function effortMarkerNotice(cliVersion2, name) {
|
|
40959
|
+
return `
|
|
40960
|
+
\u2699\uFE0F --apply-effort: "${name}" is pushed with per-step effort ENABLED (lua-cli ${cliVersion2}).
|
|
40961
|
+
From this version on, each agent step's \`effort\` is sent to the model instead of only counted in the estimate.
|
|
40962
|
+
Runs already in flight and every version pushed before this one are unaffected \u2014 they keep their own marker.
|
|
40963
|
+
Push without --apply-effort to go back to estimate-only.`;
|
|
40964
|
+
}
|
|
40965
|
+
__name(effortMarkerNotice, "effortMarkerNotice");
|
|
40422
40966
|
|
|
40423
40967
|
// src/commands/push.ts
|
|
40968
|
+
init_package_root();
|
|
40424
40969
|
function getDeployHint(type) {
|
|
40425
40970
|
const deployableMap = {
|
|
40426
40971
|
skill: "lua deploy skill",
|
|
@@ -40616,12 +41161,13 @@ async function pushVersionedPrimitive(handler, options = {}) {
|
|
|
40616
41161
|
if (confirmedVersion !== selected.version) {
|
|
40617
41162
|
handler.updateVersionInYaml(selected.name, confirmedVersion);
|
|
40618
41163
|
}
|
|
41164
|
+
if (options.applyEffort && handler.kind === "workflow") console.log(effortMarkerNotice(getCliVersion(), selected.name));
|
|
40619
41165
|
writeProgress(`
|
|
40620
41166
|
\u{1F680} Pushing ${selected.name} v${confirmedVersion} to server...`);
|
|
40621
|
-
const result = await handler.pushToServer(apiKey, agentId, entityId, {
|
|
41167
|
+
const result = await handler.pushToServer(apiKey, agentId, entityId, applyEffortMarker({
|
|
40622
41168
|
...pushData,
|
|
40623
41169
|
version: confirmedVersion
|
|
40624
|
-
});
|
|
41170
|
+
}, options.applyEffort));
|
|
40625
41171
|
if (!result.success) {
|
|
40626
41172
|
if (result.statusCode === 404) throw stalePushEntryError(handler, selected.name, entityId, result.error);
|
|
40627
41173
|
throw pushRefusalError(handler, selected.name, result);
|
|
@@ -40704,7 +41250,10 @@ async function pushCommand(type, cmdObj) {
|
|
|
40704
41250
|
// Reading with `!== false` makes the programmatic-default-true path
|
|
40705
41251
|
// explicit: when cmdObj is undefined (rare; programmatic invocation)
|
|
40706
41252
|
// we still default to attaching source.
|
|
40707
|
-
includeSource: cmdObj?.includeSource !== false
|
|
41253
|
+
includeSource: cmdObj?.includeSource !== false,
|
|
41254
|
+
// [WMC-E7] §6.9: a PLAIN push must never set the effort marker, so this reads the flag and nothing else —
|
|
41255
|
+
// no env fallback, no inheritance from a previous push.
|
|
41256
|
+
applyEffort: cmdObj?.applyEffort === true
|
|
40708
41257
|
};
|
|
40709
41258
|
let agentOutcome;
|
|
40710
41259
|
let selectedType;
|
|
@@ -41177,6 +41726,11 @@ async function pushAllCommand(options) {
|
|
|
41177
41726
|
webhookHandler,
|
|
41178
41727
|
triggerHandler,
|
|
41179
41728
|
jobHandler,
|
|
41729
|
+
// BAC — workflows were absent here, so `lua push` / `lua push all` never uploaded a changed
|
|
41730
|
+
// workflow (only the deprecated `lua push workflow` did). A published template then froze the
|
|
41731
|
+
// OLD workflow graph while its jobs advanced — an undetectable jobs-vs-workflows version skew.
|
|
41732
|
+
// Workflows ride the same push here; the deploy step below always activates them (see there).
|
|
41733
|
+
workflowHandler,
|
|
41180
41734
|
preprocessorHandler,
|
|
41181
41735
|
postprocessorHandler,
|
|
41182
41736
|
deviceHandler,
|
|
@@ -41208,6 +41762,9 @@ async function pushAllCommand(options) {
|
|
|
41208
41762
|
const icon = kindIcons[handler.kind] || "\u{1F4E6}";
|
|
41209
41763
|
writeProgress(`
|
|
41210
41764
|
${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
41765
|
+
if (options.applyEffort && handler.kind === "workflow") {
|
|
41766
|
+
console.log(effortMarkerNotice(getCliVersion(), `${items.length} workflow(s)`));
|
|
41767
|
+
}
|
|
41211
41768
|
const handlerVersions = versionLookup.get(handler);
|
|
41212
41769
|
for (const item of items) {
|
|
41213
41770
|
try {
|
|
@@ -41236,20 +41793,20 @@ ${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
|
41236
41793
|
const baseVersion = serverHighest ? maxSemver(item.version, serverHighest) : item.version;
|
|
41237
41794
|
let newVersion = incrementPatchVersion(baseVersion);
|
|
41238
41795
|
writeInfo(` \u{1F4DD} ${item.name}: ${item.version} \u2192 ${newVersion}`);
|
|
41239
|
-
let result = await handler.pushToServer(apiKey, agentId, entityId, {
|
|
41796
|
+
let result = await handler.pushToServer(apiKey, agentId, entityId, applyEffortMarker({
|
|
41240
41797
|
...pushData,
|
|
41241
41798
|
version: newVersion
|
|
41242
|
-
});
|
|
41799
|
+
}, options.applyEffort));
|
|
41243
41800
|
if (!result.success && result.error?.toLowerCase().includes("already exists")) {
|
|
41244
41801
|
console.log(` \u26A0\uFE0F Version collision on ${item.name}, refetching server state and retrying...`);
|
|
41245
41802
|
const freshHighest = await handler.getHighestServerVersion(apiKey, agentId, entityId);
|
|
41246
41803
|
if (freshHighest) {
|
|
41247
41804
|
const retryVersion = incrementPatchVersion(freshHighest);
|
|
41248
41805
|
writeInfo(` \u{1F4DD} ${item.name}: re-bumped ${newVersion} \u2192 ${retryVersion} after collision`);
|
|
41249
|
-
result = await handler.pushToServer(apiKey, agentId, entityId, {
|
|
41806
|
+
result = await handler.pushToServer(apiKey, agentId, entityId, applyEffortMarker({
|
|
41250
41807
|
...pushData,
|
|
41251
41808
|
version: retryVersion
|
|
41252
|
-
});
|
|
41809
|
+
}, options.applyEffort));
|
|
41253
41810
|
if (result.success) {
|
|
41254
41811
|
newVersion = retryVersion;
|
|
41255
41812
|
}
|
|
@@ -41274,7 +41831,7 @@ ${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
|
41274
41831
|
entityId
|
|
41275
41832
|
});
|
|
41276
41833
|
writeSuccess(` \u2705 ${item.name} v${newVersion} pushed`);
|
|
41277
|
-
if (options.autoDeploy) {
|
|
41834
|
+
if (options.autoDeploy || handler.kind === PrimitiveKind.WORKFLOW) {
|
|
41278
41835
|
toDeploy.push({
|
|
41279
41836
|
handler,
|
|
41280
41837
|
name: item.name,
|
|
@@ -41328,8 +41885,9 @@ ${icon} Pushing ${items.length} ${handler.displayName}(s)...`);
|
|
|
41328
41885
|
if (personaPushResult && !options.autoDeploy) {
|
|
41329
41886
|
writePersonaServedHint(personaPushResult.version);
|
|
41330
41887
|
}
|
|
41331
|
-
if (
|
|
41332
|
-
|
|
41888
|
+
if (toDeploy.length > 0) {
|
|
41889
|
+
const workflowsOnly = !options.autoDeploy;
|
|
41890
|
+
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...");
|
|
41333
41891
|
writeInfo("\u23F1\uFE0F Waiting for server to process versions (5 seconds)...\n");
|
|
41334
41892
|
await new Promise((resolve7) => setTimeout(resolve7, 5e3));
|
|
41335
41893
|
for (const item of toDeploy) {
|
|
@@ -51771,6 +52329,30 @@ init_constants();
|
|
|
51771
52329
|
init_command_utils();
|
|
51772
52330
|
init_analytics();
|
|
51773
52331
|
init_workflow_api_service();
|
|
52332
|
+
|
|
52333
|
+
// src/interfaces/workflow-autonomy.ts
|
|
52334
|
+
init_dist();
|
|
52335
|
+
var has2 = /* @__PURE__ */ __name((tuple, v) => tuple.includes(v), "has");
|
|
52336
|
+
var isWorkflowAutonomyForm = /* @__PURE__ */ __name((v) => has2(WORKFLOW_AUTONOMY_FORMS, v), "isWorkflowAutonomyForm");
|
|
52337
|
+
var kebab = /* @__PURE__ */ __name((key) => key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), "kebab");
|
|
52338
|
+
var WORKFLOW_AUTONOMY_CLEAR_KEYS = WORKFLOW_AUTONOMY_ENVELOPE_KEYS.map((k) => kebab(k).replace(/-seconds$/, ""));
|
|
52339
|
+
var CLEAR_ALIASES = Object.freeze(Object.fromEntries(WORKFLOW_AUTONOMY_ENVELOPE_KEYS.flatMap((key) => {
|
|
52340
|
+
const flag = kebab(key).replace(/-seconds$/, "");
|
|
52341
|
+
return [
|
|
52342
|
+
flag,
|
|
52343
|
+
kebab(key),
|
|
52344
|
+
key.toLowerCase()
|
|
52345
|
+
].map((alias) => [
|
|
52346
|
+
alias,
|
|
52347
|
+
key
|
|
52348
|
+
]);
|
|
52349
|
+
})));
|
|
52350
|
+
function autonomyClearKey(raw) {
|
|
52351
|
+
return CLEAR_ALIASES[raw.trim().toLowerCase()];
|
|
52352
|
+
}
|
|
52353
|
+
__name(autonomyClearKey, "autonomyClearKey");
|
|
52354
|
+
|
|
52355
|
+
// src/commands/workflows.ts
|
|
51774
52356
|
init_artifact_loader();
|
|
51775
52357
|
init_types();
|
|
51776
52358
|
init_dist2();
|
|
@@ -51914,6 +52496,7 @@ function exitCodeForRunStatus(status) {
|
|
|
51914
52496
|
if (status === "completed") return WORKFLOW_EXIT.OK;
|
|
51915
52497
|
if (TERMINAL_FAILED.has(status)) return WORKFLOW_EXIT.RUN_FAILED;
|
|
51916
52498
|
if (TERMINAL_CANCELLED.has(status)) return WORKFLOW_EXIT.RUN_CANCELLED;
|
|
52499
|
+
if (status === "gated") return WORKFLOW_EXIT.RUN_GATED;
|
|
51917
52500
|
return void 0;
|
|
51918
52501
|
}
|
|
51919
52502
|
__name(exitCodeForRunStatus, "exitCodeForRunStatus");
|
|
@@ -51965,11 +52548,12 @@ async function workflowsCommand(action, target, extra, cmdObj) {
|
|
|
51965
52548
|
});
|
|
51966
52549
|
return;
|
|
51967
52550
|
}
|
|
51968
|
-
const { agentId, apiKey } = await initializeCommand({
|
|
52551
|
+
const { agentId, orgId, apiKey } = await initializeCommand({
|
|
51969
52552
|
showProgress: !json
|
|
51970
52553
|
});
|
|
51971
52554
|
const ctx = {
|
|
51972
52555
|
agentId,
|
|
52556
|
+
orgId,
|
|
51973
52557
|
apiKey,
|
|
51974
52558
|
api: new WorkflowApi(BASE_URLS.API, apiKey, agentId),
|
|
51975
52559
|
json
|
|
@@ -52084,6 +52668,15 @@ async function executeAction(ctx, action, target, extra, o) {
|
|
|
52084
52668
|
// ── schedules <list|create|patch|pause|resume|delete> (LUA-627 reads + R28; LUA-752 R27 / R56; goal-owned rows refuse) ──
|
|
52085
52669
|
case "schedules":
|
|
52086
52670
|
return schedulesCore(ctx, target, extra, o);
|
|
52671
|
+
// ── policy models <get|set> ([WMC-E7] — §6.5; the org's `models` block) ──
|
|
52672
|
+
case "policy":
|
|
52673
|
+
return policyCore(ctx, target, extra, o);
|
|
52674
|
+
// ── clear-gate ([WMC-E7] — §6.5; `resume` stays the `kind:'input'` resume) ──
|
|
52675
|
+
case "clear-gate":
|
|
52676
|
+
return requireRun(runId, "clear-gate", () => clearGateCore(ctx, runId, o));
|
|
52677
|
+
// ── recompose ([WMC-E7] — §6.4 Q19; a deterministic rewrite, never a fresh composition) ──
|
|
52678
|
+
case "recompose":
|
|
52679
|
+
return requireName(name, "recompose", () => recomposeCore(ctx, name, o));
|
|
52087
52680
|
case "run":
|
|
52088
52681
|
return WORKFLOW_EXIT.OK;
|
|
52089
52682
|
}
|
|
@@ -52267,6 +52860,8 @@ async function viewCore(ctx, name) {
|
|
|
52267
52860
|
if (active?.envTemplateKeys?.length) {
|
|
52268
52861
|
console.log(` Env overlay: ${active.envTemplateKeys.join(", ")}${active.envOverlayHash ? ` \xB7 ${active.envOverlayHash}` : ""}`);
|
|
52269
52862
|
}
|
|
52863
|
+
const agentModels = agentModelsBlock(active?.agentModels);
|
|
52864
|
+
if (agentModels) console.log(agentModels);
|
|
52270
52865
|
printViewSchedules(sched);
|
|
52271
52866
|
printViewGoals(goals);
|
|
52272
52867
|
printVersions(w.versions ?? [], w.activeVersionId);
|
|
@@ -52452,6 +53047,11 @@ async function startCore(ctx, name, o) {
|
|
|
52452
53047
|
const { runId, status } = res.data;
|
|
52453
53048
|
if (!ctx.json) {
|
|
52454
53049
|
writeSuccess(startResultLine(res.data, wf.name));
|
|
53050
|
+
const card = consentCardLines(res.data.modelConsent);
|
|
53051
|
+
if (card.length) {
|
|
53052
|
+
console.log("");
|
|
53053
|
+
for (const line of card) console.log(line);
|
|
53054
|
+
}
|
|
52455
53055
|
if (status === "gated" && !o.follow) {
|
|
52456
53056
|
writeInfo("\u23F8\uFE0F The run is gated awaiting consent \u2014 approve it from the desktop or: lua workflows status " + runId);
|
|
52457
53057
|
}
|
|
@@ -52580,31 +53180,183 @@ function runMetering(run) {
|
|
|
52580
53180
|
return run.usage?.metering === "priced" ? "priced" : "flat";
|
|
52581
53181
|
}
|
|
52582
53182
|
__name(runMetering, "runMetering");
|
|
53183
|
+
var SEAT_COPY = "charged like chat \u2014 actions = the call's price band \xD7 the model's multiplier per model call; cached tokens count at the provider's ratio";
|
|
52583
53184
|
function budgetCopy(run) {
|
|
52584
53185
|
if (runMetering(run) === "priced") {
|
|
52585
|
-
|
|
52586
|
-
if (
|
|
52587
|
-
return "charged like chat \u2014
|
|
53186
|
+
const engine = budgetEngineOf(run);
|
|
53187
|
+
if (engine === "seat") return SEAT_COPY;
|
|
53188
|
+
if (engine === "legacy") return "charged like chat \u2014 a credit is one model reply on a Job step, one agent step otherwise; tokens are never metered";
|
|
53189
|
+
return "charged like chat \u2014 a credit is one model reply on a Job step (one agent step otherwise) on the legacy plan, or actions = price band \xD7 the model's multiplier per model call on a seat plan";
|
|
52588
53190
|
}
|
|
53191
|
+
if (run.budget?.unit === "actions") return SEAT_COPY;
|
|
52589
53192
|
return "a credit is one agent step; a Job-tier attempt is 4 \u2014 tokens are never metered";
|
|
52590
53193
|
}
|
|
52591
53194
|
__name(budgetCopy, "budgetCopy");
|
|
53195
|
+
function budgetEngineOf(run) {
|
|
53196
|
+
const engine = run.usage?.engine;
|
|
53197
|
+
if (engine === "seat" || engine === "legacy") return engine;
|
|
53198
|
+
const unit = run.budget?.unit;
|
|
53199
|
+
return unit === "actions" ? "seat" : unit === "credits" ? "legacy" : void 0;
|
|
53200
|
+
}
|
|
53201
|
+
__name(budgetEngineOf, "budgetEngineOf");
|
|
52592
53202
|
var fmtNum = /* @__PURE__ */ __name((v) => v.toLocaleString("en-US"), "fmtNum");
|
|
52593
53203
|
function budgetLine(run) {
|
|
52594
53204
|
const u = run.usage;
|
|
52595
53205
|
const b = run.budget;
|
|
52596
53206
|
if (!u && !b) return void 0;
|
|
52597
|
-
const seat =
|
|
53207
|
+
const seat = budgetEngineOf(run) === "seat";
|
|
52598
53208
|
const spent = seat ? u?.actionsUsed ?? b?.spent?.actionsEstimate ?? 0 : u?.creditsUsed ?? b?.spent?.credits ?? 0;
|
|
52599
53209
|
const cap = runBudgetCap(b);
|
|
52600
53210
|
const parts = [
|
|
52601
53211
|
`${fmtNum(spent)}${cap !== void 0 ? ` of ${fmtNum(cap)}` : ""} ${seat ? "actions" : "credits"} spent`,
|
|
52602
53212
|
b?.remaining !== void 0 ? `${fmtNum(b.remaining)} remaining` : void 0,
|
|
52603
|
-
seat && u?.creditsUsed ? `${fmtNum(u.creditsUsed)} flat credits` : void 0
|
|
53213
|
+
seat && u?.creditsUsed ? `${fmtNum(u.creditsUsed)} flat credits` : void 0,
|
|
53214
|
+
// [WJB-B5] (BAC-677 / plan D4): the run's own `budget.exceeded` stamp — the last step crossed the cap and
|
|
53215
|
+
// the run finished rather than parking for a raise nobody could act on. Printed only when the server
|
|
53216
|
+
// stamped it (never `false`, never inferred from `spent > cap`, which a concurrent settle can show for a
|
|
53217
|
+
// run that parked legitimately).
|
|
53218
|
+
b?.exceeded === true ? "finished past the cap" : void 0
|
|
52604
53219
|
].filter((p) => !!p);
|
|
52605
53220
|
return `${parts.join(" \xB7 ")} (${budgetCopy(run)})`;
|
|
52606
53221
|
}
|
|
52607
53222
|
__name(budgetLine, "budgetLine");
|
|
53223
|
+
function tokensLine(run) {
|
|
53224
|
+
const t = run.usage?.tokens;
|
|
53225
|
+
if (!t) return void 0;
|
|
53226
|
+
const parts = [
|
|
53227
|
+
typeof t.inputTokens === "number" ? `${fmtNum(t.inputTokens)} uncached in` : void 0,
|
|
53228
|
+
typeof t.cacheReadTokens === "number" ? `${fmtNum(t.cacheReadTokens)} cache read` : void 0,
|
|
53229
|
+
typeof t.cacheCreationTokens === "number" ? `${fmtNum(t.cacheCreationTokens)} cache write` : void 0,
|
|
53230
|
+
typeof t.outputTokens === "number" ? `${fmtNum(t.outputTokens)} out` : void 0
|
|
53231
|
+
].filter((p) => !!p);
|
|
53232
|
+
return parts.length ? parts.join(" \xB7 ") : void 0;
|
|
53233
|
+
}
|
|
53234
|
+
__name(tokensLine, "tokensLine");
|
|
53235
|
+
function autonomyDurationLabel(seconds) {
|
|
53236
|
+
if (!Number.isFinite(seconds) || seconds < 0) return `${seconds} s`;
|
|
53237
|
+
if (seconds >= 86400 && seconds % 86400 === 0) return `${fmtNum(seconds / 86400)} d`;
|
|
53238
|
+
if (seconds >= 3600 && seconds % 3600 === 0) return `${fmtNum(seconds / 3600)} h`;
|
|
53239
|
+
if (seconds >= 60 && seconds % 60 === 0) return `${fmtNum(seconds / 60)} m`;
|
|
53240
|
+
return `${fmtNum(seconds)} s`;
|
|
53241
|
+
}
|
|
53242
|
+
__name(autonomyDurationLabel, "autonomyDurationLabel");
|
|
53243
|
+
function autonomyEnvelopeSummary(envelope) {
|
|
53244
|
+
if (!envelope) return void 0;
|
|
53245
|
+
const parts = [
|
|
53246
|
+
envelope.maxCredits !== void 0 ? `${fmtNum(envelope.maxCredits)} credits` : void 0,
|
|
53247
|
+
envelope.maxSteps !== void 0 ? `${fmtNum(envelope.maxSteps)} steps` : void 0,
|
|
53248
|
+
envelope.maxDurationSeconds !== void 0 ? autonomyDurationLabel(envelope.maxDurationSeconds) : void 0
|
|
53249
|
+
].filter((p) => !!p);
|
|
53250
|
+
return parts.length ? `\u2264 ${parts.join(" \xB7 ")}` : void 0;
|
|
53251
|
+
}
|
|
53252
|
+
__name(autonomyEnvelopeSummary, "autonomyEnvelopeSummary");
|
|
53253
|
+
var CONSENT_VIA_AUTONOMY = "autonomy";
|
|
53254
|
+
function consentLine(consent) {
|
|
53255
|
+
if (consent?.via !== CONSENT_VIA_AUTONOMY) return void 0;
|
|
53256
|
+
const envelope = autonomyEnvelopeSummary(consent.envelope);
|
|
53257
|
+
return `auto (policy)${envelope ? ` \u2014 ${envelope}` : ""}`;
|
|
53258
|
+
}
|
|
53259
|
+
__name(consentLine, "consentLine");
|
|
53260
|
+
var dash = /* @__PURE__ */ __name((v) => v === void 0 || v === null || v === "" ? "\u2014" : String(v), "dash");
|
|
53261
|
+
function agentModelRow(s) {
|
|
53262
|
+
const effort = s.effort === void 0 ? "\u2014" : s.effortApplied === false ? `${s.effort} (not applied)` : String(s.effort);
|
|
53263
|
+
const requested = s.requires?.length ? `${dash(s.modelRequested)} +${s.requires.join(",")}` : dash(s.modelRequested);
|
|
53264
|
+
return [
|
|
53265
|
+
s.stepId,
|
|
53266
|
+
dash(s.taskClass),
|
|
53267
|
+
requested,
|
|
53268
|
+
dash(s.modelResolved),
|
|
53269
|
+
effort,
|
|
53270
|
+
dash(s.modelReason)
|
|
53271
|
+
];
|
|
53272
|
+
}
|
|
53273
|
+
__name(agentModelRow, "agentModelRow");
|
|
53274
|
+
function agentModelsBlock(steps) {
|
|
53275
|
+
if (!steps?.length) return void 0;
|
|
53276
|
+
const rows3 = steps.map(agentModelRow);
|
|
53277
|
+
const anyUnapplied = steps.some((s) => s.effort !== void 0 && s.effortApplied === false);
|
|
53278
|
+
const table = renderTable([
|
|
53279
|
+
"Step",
|
|
53280
|
+
"Task class",
|
|
53281
|
+
"Requested",
|
|
53282
|
+
"Resolves to today",
|
|
53283
|
+
"Effort",
|
|
53284
|
+
"Reason"
|
|
53285
|
+
], rows3);
|
|
53286
|
+
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.' : "";
|
|
53287
|
+
return `
|
|
53288
|
+
\u{1F916} Agent steps
|
|
53289
|
+
${table}${note}`;
|
|
53290
|
+
}
|
|
53291
|
+
__name(agentModelsBlock, "agentModelsBlock");
|
|
53292
|
+
function modelRollupRows(run, steps) {
|
|
53293
|
+
const projected = run.usage?.byModel;
|
|
53294
|
+
if (projected?.length) return [
|
|
53295
|
+
...projected
|
|
53296
|
+
];
|
|
53297
|
+
const folded = /* @__PURE__ */ new Map();
|
|
53298
|
+
for (const s of steps ?? []) {
|
|
53299
|
+
const b = s.billing;
|
|
53300
|
+
if (!b?.model) continue;
|
|
53301
|
+
const row2 = folded.get(b.model) ?? {
|
|
53302
|
+
model: b.model,
|
|
53303
|
+
calls: 0
|
|
53304
|
+
};
|
|
53305
|
+
row2.calls = (row2.calls ?? 0) + 1;
|
|
53306
|
+
if (b.credits !== void 0) row2.credits = (row2.credits ?? 0) + b.credits;
|
|
53307
|
+
if (b.actions !== void 0) row2.actions = (row2.actions ?? 0) + b.actions;
|
|
53308
|
+
folded.set(b.model, row2);
|
|
53309
|
+
}
|
|
53310
|
+
return [
|
|
53311
|
+
...folded.values()
|
|
53312
|
+
].sort((a, b) => (b.actions ?? b.credits ?? 0) - (a.actions ?? a.credits ?? 0));
|
|
53313
|
+
}
|
|
53314
|
+
__name(modelRollupRows, "modelRollupRows");
|
|
53315
|
+
function modelRollupBlock(run, steps) {
|
|
53316
|
+
const rows3 = modelRollupRows(run, steps);
|
|
53317
|
+
if (!rows3.length) return void 0;
|
|
53318
|
+
const seat = run.usage?.engine === "seat" || rows3.some((r) => r.actions !== void 0);
|
|
53319
|
+
const unit = seat ? "Actions" : "Credits";
|
|
53320
|
+
const anyClass = rows3.some((r) => r.class !== void 0);
|
|
53321
|
+
const anyFallback = rows3.some((r) => r.fallbacks !== void 0);
|
|
53322
|
+
const head = [
|
|
53323
|
+
"Model",
|
|
53324
|
+
...anyClass ? [
|
|
53325
|
+
"Class"
|
|
53326
|
+
] : [],
|
|
53327
|
+
"Calls",
|
|
53328
|
+
unit,
|
|
53329
|
+
...anyFallback ? [
|
|
53330
|
+
"Fallbacks"
|
|
53331
|
+
] : []
|
|
53332
|
+
];
|
|
53333
|
+
const body = rows3.map((r) => {
|
|
53334
|
+
const spend = seat ? r.actions : r.credits;
|
|
53335
|
+
return [
|
|
53336
|
+
r.model,
|
|
53337
|
+
...anyClass ? [
|
|
53338
|
+
dash(r.class)
|
|
53339
|
+
] : [],
|
|
53340
|
+
r.calls !== void 0 ? fmtNum(r.calls) : "\u2014",
|
|
53341
|
+
spend !== void 0 ? fmtNum(spend) : "\u2014",
|
|
53342
|
+
...anyFallback ? [
|
|
53343
|
+
r.fallbacks !== void 0 ? fmtNum(r.fallbacks) : "\u2014"
|
|
53344
|
+
] : []
|
|
53345
|
+
];
|
|
53346
|
+
});
|
|
53347
|
+
const derived = !run.usage?.byModel?.length;
|
|
53348
|
+
const note = derived ? "\n (derived from the step receipts \u2014 the run has no roll-up of its own)" : "";
|
|
53349
|
+
return `
|
|
53350
|
+
\u{1F9E0} By model
|
|
53351
|
+
${renderTable(head, body)}${note}`;
|
|
53352
|
+
}
|
|
53353
|
+
__name(modelRollupBlock, "modelRollupBlock");
|
|
53354
|
+
function consentCardLines(consent) {
|
|
53355
|
+
return consent?.card?.length ? [
|
|
53356
|
+
...consent.card
|
|
53357
|
+
] : [];
|
|
53358
|
+
}
|
|
53359
|
+
__name(consentCardLines, "consentCardLines");
|
|
52608
53360
|
function printRun(run, withSteps) {
|
|
52609
53361
|
const id = runIdOf(run);
|
|
52610
53362
|
console.log(`
|
|
@@ -52614,8 +53366,12 @@ function printRun(run, withSteps) {
|
|
|
52614
53366
|
console.log(` Created: ${when2(run.createdAt)}${run.startedAt ? ` \xB7 started ${when2(run.startedAt)}` : ""}${run.completedAt ? ` \xB7 completed ${when2(run.completedAt)}` : ""}`);
|
|
52615
53367
|
if (run.lineageId && run.lineageId !== id) console.log(` Lineage: ${run.lineageId}`);
|
|
52616
53368
|
if (run.parentRunId) console.log(` Parent: ${run.parentRunId} \u2014 lua workflows status ${run.parentRunId} --steps`);
|
|
53369
|
+
const consent = consentLine(run.consent);
|
|
53370
|
+
if (consent) console.log(` Consent: ${consent}`);
|
|
52617
53371
|
const budget = budgetLine(run);
|
|
52618
53372
|
if (budget) console.log(` Budget: ${budget}`);
|
|
53373
|
+
const tokens = tokensLine(run);
|
|
53374
|
+
if (tokens) console.log(` Tokens: ${tokens}`);
|
|
52619
53375
|
if (run.cancel) console.log(` Cancel: ${formatRunCancel(run.cancel)}`);
|
|
52620
53376
|
if (run.gate) {
|
|
52621
53377
|
const kind = run.gate.kind;
|
|
@@ -52626,9 +53382,14 @@ function printRun(run, withSteps) {
|
|
|
52626
53382
|
} else if (kind === "budget") {
|
|
52627
53383
|
console.log(`
|
|
52628
53384
|
\u23F8\uFE0F Paused \u2014 run budget reached (${budgetCopy(run)}):`);
|
|
52629
|
-
console.log(` lua workflows raise-budget ${id} --credits <n
|
|
53385
|
+
console.log(` lua workflows raise-budget ${id} --credits <n> (<n> is the new cap in ${budgetEngineOf(run) === "seat" ? "actions" : "credits"})`);
|
|
52630
53386
|
} else if (kind === "billing") {
|
|
52631
53387
|
for (const line of billingParkLines(run)) console.log(line);
|
|
53388
|
+
} else if (kind === "model_policy") {
|
|
53389
|
+
console.log(`
|
|
53390
|
+
\u23F8\uFE0F Paused \u2014 a step's model request cannot be resolved under the current policy:`);
|
|
53391
|
+
if (run.gate?.code) console.log(` ${run.gate.code}${run.gate.stepId ? ` \xB7 step ${run.gate.stepId}` : ""}`);
|
|
53392
|
+
console.log(` lua workflows clear-gate ${id} --kind model_policy`);
|
|
52632
53393
|
} else {
|
|
52633
53394
|
console.log(` Gate: ${kind}${run.gate.reason ? ` (${run.gate.reason})` : ""}${run.gate.since ? ` since ${when2(run.gate.since)}` : ""}`);
|
|
52634
53395
|
}
|
|
@@ -52655,11 +53416,17 @@ function printRun(run, withSteps) {
|
|
|
52655
53416
|
else {
|
|
52656
53417
|
console.log("");
|
|
52657
53418
|
const withChildren = steps.some((s) => typeof s.childRunId === "string");
|
|
53419
|
+
const withTokens = steps.some((s) => !!s.tokens);
|
|
52658
53420
|
console.log(renderTable([
|
|
52659
53421
|
"Step",
|
|
52660
53422
|
"Kind",
|
|
52661
53423
|
"Status",
|
|
52662
53424
|
"Attempt",
|
|
53425
|
+
...withTokens ? [
|
|
53426
|
+
"Uncached",
|
|
53427
|
+
"Cached",
|
|
53428
|
+
"Output"
|
|
53429
|
+
] : [],
|
|
52663
53430
|
"Error",
|
|
52664
53431
|
...withChildren ? [
|
|
52665
53432
|
"Child run"
|
|
@@ -52669,6 +53436,7 @@ function printRun(run, withSteps) {
|
|
|
52669
53436
|
s.kind ?? "\u2014",
|
|
52670
53437
|
s.status,
|
|
52671
53438
|
stepAttemptCell(s),
|
|
53439
|
+
...withTokens ? stepTokenCells(s) : [],
|
|
52672
53440
|
stepErrorCell(s.error),
|
|
52673
53441
|
...withChildren ? [
|
|
52674
53442
|
s.childRunId ?? ""
|
|
@@ -52677,6 +53445,8 @@ function printRun(run, withSteps) {
|
|
|
52677
53445
|
for (const s of steps) for (const line of stepAttemptLines(s)) console.log(line);
|
|
52678
53446
|
}
|
|
52679
53447
|
}
|
|
53448
|
+
const rollup = modelRollupBlock(run, steps);
|
|
53449
|
+
if (rollup) console.log(rollup);
|
|
52680
53450
|
}
|
|
52681
53451
|
__name(printRun, "printRun");
|
|
52682
53452
|
function billingParkLines(run) {
|
|
@@ -52696,6 +53466,22 @@ function billingParkLines(run) {
|
|
|
52696
53466
|
return out;
|
|
52697
53467
|
}
|
|
52698
53468
|
__name(billingParkLines, "billingParkLines");
|
|
53469
|
+
function stepTokenCells(s) {
|
|
53470
|
+
const t = s.tokens;
|
|
53471
|
+
const cell = /* @__PURE__ */ __name((v) => typeof v === "number" && Number.isFinite(v) ? fmtNum(v) : "\u2014", "cell");
|
|
53472
|
+
if (!t) return [
|
|
53473
|
+
"\u2014",
|
|
53474
|
+
"\u2014",
|
|
53475
|
+
"\u2014"
|
|
53476
|
+
];
|
|
53477
|
+
const cached = typeof t.cacheReadTokens === "number" || typeof t.cacheCreationTokens === "number" ? (t.cacheReadTokens ?? 0) + (t.cacheCreationTokens ?? 0) : void 0;
|
|
53478
|
+
return [
|
|
53479
|
+
cell(t.inputTokens),
|
|
53480
|
+
cell(cached),
|
|
53481
|
+
cell(t.outputTokens)
|
|
53482
|
+
];
|
|
53483
|
+
}
|
|
53484
|
+
__name(stepTokenCells, "stepTokenCells");
|
|
52699
53485
|
function stepAttemptLines(s) {
|
|
52700
53486
|
const out = [];
|
|
52701
53487
|
const cause = stepFailureLine(s.error);
|
|
@@ -52704,8 +53490,12 @@ function stepAttemptLines(s) {
|
|
|
52704
53490
|
if (burned) out.push(` \u03A3 ${s.stepId}: attempt ${s.attempt ?? 1} ${s.status}: ${burned}`);
|
|
52705
53491
|
const billed = stepBillingLine(s.billing);
|
|
52706
53492
|
if (billed) out.push(` $ ${s.stepId}: attempt ${s.billing?.attempt ?? s.attempt ?? 1} billed: ${billed}`);
|
|
53493
|
+
const jobModel = stepJobModelLine(s);
|
|
53494
|
+
if (jobModel) out.push(` \u2699 ${s.stepId}: ${jobModel}`);
|
|
52707
53495
|
const fetchable = outputRefLine(s.outputRef);
|
|
52708
53496
|
if (fetchable) out.push(` \u21E9 ${s.stepId}: ${fetchable}`);
|
|
53497
|
+
const escalated = approverFallbackLine(s);
|
|
53498
|
+
if (escalated) out.push(escalated);
|
|
52709
53499
|
for (const a of s.attempts ?? []) {
|
|
52710
53500
|
if (a.status === "completed") continue;
|
|
52711
53501
|
const what = stepErrorCell(a.error) || a.killReason || "\u2014";
|
|
@@ -52715,6 +53505,29 @@ function stepAttemptLines(s) {
|
|
|
52715
53505
|
return out;
|
|
52716
53506
|
}
|
|
52717
53507
|
__name(stepAttemptLines, "stepAttemptLines");
|
|
53508
|
+
function stepJobModelLine(s) {
|
|
53509
|
+
const j = s.job;
|
|
53510
|
+
if (!j) return void 0;
|
|
53511
|
+
const parts = [
|
|
53512
|
+
j.model ? `model ${j.model}` : void 0,
|
|
53513
|
+
typeof j.multiplier === "number" ? `\xD7${fmtNum(j.multiplier)}` : void 0,
|
|
53514
|
+
j.modelSource ? `chosen by ${jobModelSourceWord(j.modelSource)}` : void 0
|
|
53515
|
+
].filter((p) => !!p);
|
|
53516
|
+
return parts.length ? parts.join(" \xB7 ") : void 0;
|
|
53517
|
+
}
|
|
53518
|
+
__name(stepJobModelLine, "stepJobModelLine");
|
|
53519
|
+
function jobModelSourceWord(source) {
|
|
53520
|
+
const labels = WORKFLOW_JOB_MODEL_SOURCE_LABELS;
|
|
53521
|
+
return labels[source] ?? source;
|
|
53522
|
+
}
|
|
53523
|
+
__name(jobModelSourceWord, "jobModelSourceWord");
|
|
53524
|
+
function approverFallbackLine(s) {
|
|
53525
|
+
const f = s.suspend?.approverFallback;
|
|
53526
|
+
if (!f?.from || !f.to) return void 0;
|
|
53527
|
+
const why = f.reason === "initiator_excluded" ? "the initiator is excluded (maker-checker)" : f.reason;
|
|
53528
|
+
return ` \u21C5 ${s.stepId}: approver escalated ${f.from} \u2192 ${f.to}${why ? ` \u2014 ${why}` : ""}`;
|
|
53529
|
+
}
|
|
53530
|
+
__name(approverFallbackLine, "approverFallbackLine");
|
|
52718
53531
|
function outputRefLine(ref) {
|
|
52719
53532
|
if (!ref?.artefactId || !ref.url) return void 0;
|
|
52720
53533
|
const gate = "needs workflows:read-outputs";
|
|
@@ -53018,7 +53831,7 @@ async function boundaryVerdict(runId, ev, state3, boundary) {
|
|
|
53018
53831
|
return boundary(`\u23F8\uFE0F run parked on a billing gate \u2014 top up the workspace; it resumes within a few minutes (right away: lua workflows retry-step ${runId} --step ${stepId ?? "<stepId>"})`, WORKFLOW_EXIT.RUN_PARKED);
|
|
53019
53832
|
}
|
|
53020
53833
|
if (gate === "budget") {
|
|
53021
|
-
return boundary(`\u23F8\uFE0F run budget reached \u2014 lua workflows raise-budget ${runId} --credits <n> (lua workflows status ${runId} says
|
|
53834
|
+
return boundary(`\u23F8\uFE0F run budget reached \u2014 lua workflows raise-budget ${runId} --credits <n> (the cap is in this run's own budget unit \u2014 credits, or actions on a seat plan; lua workflows status ${runId} says which)`, WORKFLOW_EXIT.RUN_PARKED);
|
|
53022
53835
|
}
|
|
53023
53836
|
return boundary(`\u23F8\uFE0F run gated (${gate ?? "consent"}) \u2014 approve it from the desktop; then: lua workflows watch ${runId}`, WORKFLOW_EXIT.RUN_GATED);
|
|
53024
53837
|
}
|
|
@@ -53035,7 +53848,7 @@ async function boundaryVerdict(runId, ev, state3, boundary) {
|
|
|
53035
53848
|
}
|
|
53036
53849
|
}
|
|
53037
53850
|
if (type === "run.budget_parked") {
|
|
53038
|
-
return boundary(`\u23F8\uFE0F run budget reached \u2014 lua workflows raise-budget ${runId} --credits <n> (lua workflows status ${runId} says
|
|
53851
|
+
return boundary(`\u23F8\uFE0F run budget reached \u2014 lua workflows raise-budget ${runId} --credits <n> (the cap is in this run's own budget unit \u2014 credits, or actions on a seat plan; lua workflows status ${runId} says which)`, WORKFLOW_EXIT.RUN_PARKED);
|
|
53039
53852
|
}
|
|
53040
53853
|
if (type === "run.completed") return WORKFLOW_EXIT.OK;
|
|
53041
53854
|
if (type === "run.failed" || type === "run.timed_out") return WORKFLOW_EXIT.RUN_FAILED;
|
|
@@ -53265,10 +54078,10 @@ function budgetCapFlag(cap) {
|
|
|
53265
54078
|
return "--credits";
|
|
53266
54079
|
}
|
|
53267
54080
|
__name(budgetCapFlag, "budgetCapFlag");
|
|
53268
|
-
function budgetCapsLabel(b) {
|
|
54081
|
+
function budgetCapsLabel(b, unit) {
|
|
53269
54082
|
if (!b) return "";
|
|
53270
54083
|
const parts = [];
|
|
53271
|
-
if (b.maxCredits !== void 0) parts.push(`${b.maxCredits} credits`);
|
|
54084
|
+
if (b.maxCredits !== void 0) parts.push(`${b.maxCredits} ${unit ?? "credits"}`);
|
|
53272
54085
|
if (b.maxSteps !== void 0) parts.push(`${b.maxSteps} steps`);
|
|
53273
54086
|
if (b.maxJobSeconds !== void 0) parts.push(`${b.maxJobSeconds}s job`);
|
|
53274
54087
|
if (b.maxDurationSeconds !== void 0) parts.push(`${b.maxDurationSeconds}s wall`);
|
|
@@ -53334,9 +54147,10 @@ async function raiseBudgetCore(ctx, runId, o) {
|
|
|
53334
54147
|
emitJson(ctx, res);
|
|
53335
54148
|
if (!ctx.json) {
|
|
53336
54149
|
const d = res.data;
|
|
53337
|
-
const
|
|
54150
|
+
const unit = d.unit === "actions" ? "actions" : "credits";
|
|
54151
|
+
const caps = budgetCapsLabel(d.budget ?? d.to, unit);
|
|
53338
54152
|
if (d.raised) {
|
|
53339
|
-
const delta = d.from && d.to ? ` (${budgetCapsLabel(d.from)} \u2192 ${budgetCapsLabel(d.to)})` : caps ? ` to ${caps}` : "";
|
|
54153
|
+
const delta = d.from && d.to ? ` (${budgetCapsLabel(d.from, unit)} \u2192 ${budgetCapsLabel(d.to, unit)})` : caps ? ` to ${caps}` : "";
|
|
53340
54154
|
writeSuccess(`\u2705 budget raised${delta}${d.runStatus ? ` \xB7 run is ${d.runStatus}` : ""}`);
|
|
53341
54155
|
if (d.resumed === false) writeInfo(`\u2139\uFE0F the run did not resume on this raise \u2014 the next step's reserve is still short (raise again), or nothing was parked: lua workflows status ${runId}`);
|
|
53342
54156
|
else if (d.resumed) writeInfo(`\u{1F4A1} Follow it: lua workflows watch ${runId}`);
|
|
@@ -53681,6 +54495,80 @@ async function replayChildRun(ctx, childRunId) {
|
|
|
53681
54495
|
};
|
|
53682
54496
|
}
|
|
53683
54497
|
__name(replayChildRun, "replayChildRun");
|
|
54498
|
+
var WORKFLOW_LOG_EVENT_PATTERN = /progress|log|started|completed|failed|skipped|model_resolved|model_policy_warning|budget_parked|budget_raised|budget_exceeded/;
|
|
54499
|
+
function jobModelEventDetail(data) {
|
|
54500
|
+
const d = data ?? {};
|
|
54501
|
+
const nested = d.detail && typeof d.detail === "object" ? d.detail : {};
|
|
54502
|
+
const pick = /* @__PURE__ */ __name((key) => d[key] !== void 0 ? d[key] : nested[key], "pick");
|
|
54503
|
+
const model = typeof pick("model") === "string" ? pick("model") : void 0;
|
|
54504
|
+
const raw = pick("multiplier");
|
|
54505
|
+
const multiplier = typeof raw === "number" && Number.isFinite(raw) ? raw : void 0;
|
|
54506
|
+
const source = typeof pick("source") === "string" ? pick("source") : void 0;
|
|
54507
|
+
const calibrated = pick("calibrated");
|
|
54508
|
+
if (!model && multiplier === void 0 && !source) return void 0;
|
|
54509
|
+
const tail = [
|
|
54510
|
+
multiplier !== void 0 ? `\xD7${fmtNum(multiplier)}` : void 0,
|
|
54511
|
+
source ? `(${jobModelSourceWord(source)})` : void 0,
|
|
54512
|
+
calibrated === false ? "\u2014 uncalibrated model, fallback rate" : void 0
|
|
54513
|
+
].filter((p) => !!p);
|
|
54514
|
+
return `job model \u2192 ${model ?? "?"}${tail.length ? ` ${tail.join(" ")}` : ""}`;
|
|
54515
|
+
}
|
|
54516
|
+
__name(jobModelEventDetail, "jobModelEventDetail");
|
|
54517
|
+
function budgetEventDetail(type, data) {
|
|
54518
|
+
if (type !== "run.budget_parked" && type !== "run.budget_raised" && type !== "run.budget_exceeded") return void 0;
|
|
54519
|
+
const d = data ?? {};
|
|
54520
|
+
const nested = d.detail && typeof d.detail === "object" ? d.detail : {};
|
|
54521
|
+
const pick = /* @__PURE__ */ __name((key) => d[key] !== void 0 ? d[key] : nested[key], "pick");
|
|
54522
|
+
const numberOf = /* @__PURE__ */ __name((key) => {
|
|
54523
|
+
const v = pick(key);
|
|
54524
|
+
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
54525
|
+
}, "numberOf");
|
|
54526
|
+
const stringOf = /* @__PURE__ */ __name((key) => {
|
|
54527
|
+
const v = pick(key);
|
|
54528
|
+
return typeof v === "string" && v ? v : void 0;
|
|
54529
|
+
}, "stringOf");
|
|
54530
|
+
const stepId = stringOf("stepId");
|
|
54531
|
+
const step3 = stepId ? ` (step ${stepId})` : "";
|
|
54532
|
+
if (type === "run.budget_raised") {
|
|
54533
|
+
const from = numberOf("from");
|
|
54534
|
+
const to = numberOf("to");
|
|
54535
|
+
const move = from !== void 0 && to !== void 0 ? `cap ${fmtNum(from)} \u2192 ${fmtNum(to)}` : "cap raised";
|
|
54536
|
+
const by = stringOf("by");
|
|
54537
|
+
const resumed = pick("resumed") === true ? " \u2014 run resumed" : "";
|
|
54538
|
+
return `${move}${by ? ` by ${by}` : ""}${resumed}`;
|
|
54539
|
+
}
|
|
54540
|
+
const dimension = stringOf("dimension");
|
|
54541
|
+
const spent = numberOf("spent");
|
|
54542
|
+
const cap = numberOf("cap");
|
|
54543
|
+
const figures = spent !== void 0 && cap !== void 0 ? `${fmtNum(spent)} of ${fmtNum(cap)}${dimension ? ` ${dimension}` : ""}` : dimension;
|
|
54544
|
+
const lead = type === "run.budget_exceeded" ? "finished past the cap" : "paused on its run budget";
|
|
54545
|
+
const detail = [
|
|
54546
|
+
figures,
|
|
54547
|
+
stringOf("engine")
|
|
54548
|
+
].filter((p) => !!p).join(", ");
|
|
54549
|
+
return `${lead}${detail ? ` \u2014 ${detail}` : ""}${step3}`;
|
|
54550
|
+
}
|
|
54551
|
+
__name(budgetEventDetail, "budgetEventDetail");
|
|
54552
|
+
function modelEventDetail(type, data) {
|
|
54553
|
+
if (type === "step.job_model_resolved") return jobModelEventDetail(data);
|
|
54554
|
+
if (type !== "step.model_resolved" && type !== "step.model_policy_warning") return void 0;
|
|
54555
|
+
const d = data ?? {};
|
|
54556
|
+
const nested = d.detail ?? {};
|
|
54557
|
+
const str = /* @__PURE__ */ __name((...vals) => {
|
|
54558
|
+
for (const v of vals) if (typeof v === "string" && v) return v;
|
|
54559
|
+
return void 0;
|
|
54560
|
+
}, "str");
|
|
54561
|
+
const requested = str(d.requested, nested.requested, d.modelRequested, nested.modelRequested);
|
|
54562
|
+
const resolved = str(d.resolved, nested.resolved, d.model, nested.model);
|
|
54563
|
+
if (type === "step.model_resolved") {
|
|
54564
|
+
const cls = requested?.startsWith("class/") ? requested.slice("class/".length) : str(d.taskClass, nested.taskClass);
|
|
54565
|
+
return `model resolved \u2192 ${resolved ?? requested ?? "?"}${cls ? ` (${cls})` : ""}`;
|
|
54566
|
+
}
|
|
54567
|
+
const outcome = str(d.outcome, nested.outcome, d.code, nested.code) ?? "unknown";
|
|
54568
|
+
const detail = str(d.message, nested.message) ?? (requested && resolved && requested !== resolved ? `${requested} \u2192 ${resolved}` : requested ?? resolved);
|
|
54569
|
+
return `model policy warning: ${outcome}${detail ? ` ${detail}` : ""}`;
|
|
54570
|
+
}
|
|
54571
|
+
__name(modelEventDetail, "modelEventDetail");
|
|
53684
54572
|
async function logsCore(ctx, runId, o) {
|
|
53685
54573
|
if (o.follow) return watchCore(ctx, runId, o);
|
|
53686
54574
|
const res = await ctx.api.getRunEvents(runId, {
|
|
@@ -53689,10 +54577,13 @@ async function logsCore(ctx, runId, o) {
|
|
|
53689
54577
|
if (!res.success || !res.data) return apiFailure(ctx, res, "logs");
|
|
53690
54578
|
emitJson(ctx, res);
|
|
53691
54579
|
if (ctx.json) return WORKFLOW_EXIT.OK;
|
|
53692
|
-
const events = (res.data.events ?? []).filter((e) => (!o.step || e.stepId === o.step) &&
|
|
54580
|
+
const events = (res.data.events ?? []).filter((e) => (!o.step || e.stepId === o.step) && WORKFLOW_LOG_EVENT_PATTERN.test(e.type));
|
|
53693
54581
|
if (events.length === 0) console.log("(no log events yet)");
|
|
53694
54582
|
for (const e of events) {
|
|
53695
|
-
const
|
|
54583
|
+
const data = scrubEventData(e.data);
|
|
54584
|
+
const msg = modelEventDetail(e.type, data) ?? // [WJB-B5]: the budget events carry no `message` of their own — without a renderer they would print as a
|
|
54585
|
+
// bare type, which is why the pattern admitting them and this line land together.
|
|
54586
|
+
budgetEventDetail(e.type, data) ?? data?.message ?? subrunEventDetail(e);
|
|
53696
54587
|
console.log(`[${clockOf(e.ts)}] ${e.type}${e.stepId ? ` \xB7 ${e.stepId}` : ""}${msg ? ` \xB7 ${msg}` : ""}`);
|
|
53697
54588
|
}
|
|
53698
54589
|
return WORKFLOW_EXIT.OK;
|
|
@@ -55384,6 +56275,290 @@ async function schedulesPatchCore(ctx, jobId, verb, o) {
|
|
|
55384
56275
|
return WORKFLOW_EXIT.OK;
|
|
55385
56276
|
}
|
|
55386
56277
|
__name(schedulesPatchCore, "schedulesPatchCore");
|
|
56278
|
+
function csvFlag(raw) {
|
|
56279
|
+
if (raw === void 0) return void 0;
|
|
56280
|
+
const parts = (Array.isArray(raw) ? raw : [
|
|
56281
|
+
raw
|
|
56282
|
+
]).flatMap((v) => String(v).split(","));
|
|
56283
|
+
const out = parts.map((v) => v.trim()).filter((v) => v.length > 0);
|
|
56284
|
+
return out;
|
|
56285
|
+
}
|
|
56286
|
+
__name(csvFlag, "csvFlag");
|
|
56287
|
+
function badFlagValue(flag, value3, allowed) {
|
|
56288
|
+
return CliError.usage(`${flag}: "${value3}" is not a valid value`, `${flag} takes one of ${allowed.map((v) => `\`${v}\``).join(", ")}`);
|
|
56289
|
+
}
|
|
56290
|
+
__name(badFlagValue, "badFlagValue");
|
|
56291
|
+
function buildModelsPolicyPatch(o) {
|
|
56292
|
+
const patch = {};
|
|
56293
|
+
if (o.compose !== void 0) {
|
|
56294
|
+
const v = String(o.compose);
|
|
56295
|
+
if (!WORKFLOW_MODELS_COMPOSE_MODES.includes(v)) throw badFlagValue("--compose", v, WORKFLOW_MODELS_COMPOSE_MODES);
|
|
56296
|
+
patch.compose = v;
|
|
56297
|
+
}
|
|
56298
|
+
if (o.maxClass !== void 0) {
|
|
56299
|
+
const v = String(o.maxClass);
|
|
56300
|
+
if (!isWorkflowModelClass(v)) throw badFlagValue("--max-class", v, WORKFLOW_MODEL_CLASSES);
|
|
56301
|
+
patch.maxClass = v;
|
|
56302
|
+
}
|
|
56303
|
+
if (o.consentActions !== void 0) {
|
|
56304
|
+
const n2 = parseIntegerFlag(o.consentActions, "--consent-actions", {
|
|
56305
|
+
min: WORKFLOW_MODELS_CONSENT_ACTIONS_MIN
|
|
56306
|
+
});
|
|
56307
|
+
if (n2 !== void 0) patch.consentActions = n2;
|
|
56308
|
+
}
|
|
56309
|
+
if (o.pins !== void 0) {
|
|
56310
|
+
const v = String(o.pins);
|
|
56311
|
+
if (!WORKFLOW_MODELS_PIN_MODES.includes(v)) throw badFlagValue("--pins", v, WORKFLOW_MODELS_PIN_MODES);
|
|
56312
|
+
patch.pins = v;
|
|
56313
|
+
}
|
|
56314
|
+
if (o.fallback !== void 0) {
|
|
56315
|
+
const v = String(o.fallback);
|
|
56316
|
+
if (!WORKFLOW_MODELS_FALLBACK_MODES.includes(v)) throw badFlagValue("--fallback", v, WORKFLOW_MODELS_FALLBACK_MODES);
|
|
56317
|
+
patch.fallback = v;
|
|
56318
|
+
}
|
|
56319
|
+
const allow = csvFlag(o.allow);
|
|
56320
|
+
if (allow !== void 0) patch.allow = allow;
|
|
56321
|
+
const classes = {};
|
|
56322
|
+
const perClass = {
|
|
56323
|
+
fast: o.classFast,
|
|
56324
|
+
balanced: o.classBalanced,
|
|
56325
|
+
strong: o.classStrong
|
|
56326
|
+
};
|
|
56327
|
+
for (const c of WORKFLOW_MODEL_CLASSES) {
|
|
56328
|
+
const codes = csvFlag(perClass[c]);
|
|
56329
|
+
if (codes !== void 0) classes[c] = codes;
|
|
56330
|
+
}
|
|
56331
|
+
if (Object.keys(classes).length) patch.classes = classes;
|
|
56332
|
+
if (o.classMap !== void 0) {
|
|
56333
|
+
const map = {};
|
|
56334
|
+
for (const entry of csvFlag(o.classMap) ?? []) {
|
|
56335
|
+
const [task, cls] = entry.split("=").map((v) => v.trim());
|
|
56336
|
+
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");
|
|
56337
|
+
if (!isWorkflowTaskClass(task)) throw badFlagValue("--class-map", task, WORKFLOW_TASK_CLASSES);
|
|
56338
|
+
if (!isWorkflowModelClass(cls)) throw badFlagValue("--class-map", cls, WORKFLOW_MODEL_CLASSES);
|
|
56339
|
+
map[task] = cls;
|
|
56340
|
+
}
|
|
56341
|
+
if (Object.keys(map).length) patch.classMap = map;
|
|
56342
|
+
}
|
|
56343
|
+
return patch;
|
|
56344
|
+
}
|
|
56345
|
+
__name(buildModelsPolicyPatch, "buildModelsPolicyPatch");
|
|
56346
|
+
function modelsPolicyLines(models) {
|
|
56347
|
+
const lines = [
|
|
56348
|
+
"\n\u{1F9E0} Workflow model policy"
|
|
56349
|
+
];
|
|
56350
|
+
if (!models || Object.keys(models).length === 0) {
|
|
56351
|
+
lines.push(" (not set \u2014 the platform defaults apply: assignment off, no class ceiling, composed steps class-only)");
|
|
56352
|
+
return lines;
|
|
56353
|
+
}
|
|
56354
|
+
const show = /* @__PURE__ */ __name((label2, v, fallback) => {
|
|
56355
|
+
lines.push(` ${label2.padEnd(16)} ${v === void 0 || v === null ? `\u2014 (${fallback})` : String(v)}`);
|
|
56356
|
+
}, "show");
|
|
56357
|
+
show("compose", models.compose, "platform default");
|
|
56358
|
+
show("maxClass", models.maxClass, "no ceiling below `strong`");
|
|
56359
|
+
show("consentActions", models.consentActions, "platform default");
|
|
56360
|
+
show("pins", models.pins, "class-only on composed definitions");
|
|
56361
|
+
show("fallback", models.fallback, "same-class");
|
|
56362
|
+
lines.push(` ${"allow".padEnd(16)} ${models.allow?.length ? models.allow.join(", ") : "\u2014 (all approved, minus the organization\u2019s excluded models)"}`);
|
|
56363
|
+
if (models.classes && Object.keys(models.classes).length) {
|
|
56364
|
+
lines.push(" classes");
|
|
56365
|
+
for (const c of WORKFLOW_MODEL_CLASSES) {
|
|
56366
|
+
const codes = models.classes[c];
|
|
56367
|
+
if (codes?.length) lines.push(` ${c.padEnd(10)} ${codes.join(", ")}`);
|
|
56368
|
+
}
|
|
56369
|
+
}
|
|
56370
|
+
if (models.classMap && Object.keys(models.classMap).length) {
|
|
56371
|
+
lines.push(" classMap (overrides only)");
|
|
56372
|
+
for (const [task, cls] of Object.entries(models.classMap)) lines.push(` ${task.padEnd(10)} \u2192 ${cls}`);
|
|
56373
|
+
}
|
|
56374
|
+
return lines;
|
|
56375
|
+
}
|
|
56376
|
+
__name(modelsPolicyLines, "modelsPolicyLines");
|
|
56377
|
+
var WORKFLOW_AUTONOMY_ENABLED_WORDS = [
|
|
56378
|
+
"on",
|
|
56379
|
+
"off"
|
|
56380
|
+
];
|
|
56381
|
+
var AUTONOMY_NUMERIC_FLAGS = {
|
|
56382
|
+
maxCredits: "--max-credits",
|
|
56383
|
+
maxSteps: "--max-steps",
|
|
56384
|
+
// `--max-duration` takes SECONDS and the wire key says so; `--max-duration-seconds` is `raise-budget`'s
|
|
56385
|
+
// own flag for a different thing (one run's wall), so the two deliberately do not share a spelling.
|
|
56386
|
+
maxDurationSeconds: "--max-duration",
|
|
56387
|
+
maxActions: "--max-actions",
|
|
56388
|
+
maxRunsPerHour: "--max-runs-per-hour"
|
|
56389
|
+
};
|
|
56390
|
+
function buildAutonomyPolicyPatch(o) {
|
|
56391
|
+
const patch = {};
|
|
56392
|
+
if (o.enabled !== void 0) {
|
|
56393
|
+
const v = String(o.enabled).trim().toLowerCase();
|
|
56394
|
+
if (!WORKFLOW_AUTONOMY_ENABLED_WORDS.includes(v)) throw badFlagValue("--enabled", String(o.enabled), WORKFLOW_AUTONOMY_ENABLED_WORDS);
|
|
56395
|
+
patch.enabled = v === "on";
|
|
56396
|
+
}
|
|
56397
|
+
const raw = {
|
|
56398
|
+
maxCredits: o.maxCredits,
|
|
56399
|
+
maxSteps: o.maxSteps,
|
|
56400
|
+
maxDurationSeconds: o.maxDuration,
|
|
56401
|
+
maxActions: o.maxActions,
|
|
56402
|
+
maxRunsPerHour: o.maxRunsPerHour
|
|
56403
|
+
};
|
|
56404
|
+
for (const key of WORKFLOW_AUTONOMY_NUMERIC_KEYS) {
|
|
56405
|
+
const n2 = parseIntegerFlag(raw[key], AUTONOMY_NUMERIC_FLAGS[key], {
|
|
56406
|
+
min: WORKFLOW_AUTONOMY_MIN_VALUE
|
|
56407
|
+
});
|
|
56408
|
+
if (n2 !== void 0) patch[key] = n2;
|
|
56409
|
+
}
|
|
56410
|
+
const forms = csvFlag(o.forms);
|
|
56411
|
+
if (forms !== void 0) {
|
|
56412
|
+
for (const f of forms) if (!isWorkflowAutonomyForm(f)) throw badFlagValue("--forms", f, WORKFLOW_AUTONOMY_FORMS);
|
|
56413
|
+
patch.forms = forms;
|
|
56414
|
+
}
|
|
56415
|
+
for (const token of csvFlag(o.clear) ?? []) {
|
|
56416
|
+
const key = autonomyClearKey(token);
|
|
56417
|
+
if (!key) throw badFlagValue("--clear", token, WORKFLOW_AUTONOMY_CLEAR_KEYS);
|
|
56418
|
+
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.");
|
|
56419
|
+
patch[key] = null;
|
|
56420
|
+
}
|
|
56421
|
+
return patch;
|
|
56422
|
+
}
|
|
56423
|
+
__name(buildAutonomyPolicyPatch, "buildAutonomyPolicyPatch");
|
|
56424
|
+
function autonomyPolicyLines(autonomy, effective, opts = {}) {
|
|
56425
|
+
const lines = [
|
|
56426
|
+
"\n\u{1F6E1}\uFE0F Workflow autonomy (the pre-consented envelope)"
|
|
56427
|
+
];
|
|
56428
|
+
const show = /* @__PURE__ */ __name((target, label2, v, fallback) => {
|
|
56429
|
+
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);
|
|
56430
|
+
target.push(` ${label2.padEnd(18)} ${rendered}`);
|
|
56431
|
+
}, "show");
|
|
56432
|
+
const block = /* @__PURE__ */ __name((target, e) => {
|
|
56433
|
+
show(target, "enabled", e.enabled, `${WORKFLOW_AUTONOMY_ENABLED_DEFAULT} \u2014 absent means the organization never opted in`);
|
|
56434
|
+
show(target, "maxCredits", e.maxCredits, `default ${WORKFLOW_AUTONOMY_DEFAULTS.maxCredits}, clamped to caps.maxCreditsPerRun`);
|
|
56435
|
+
show(target, "maxSteps", e.maxSteps, `default ${WORKFLOW_AUTONOMY_DEFAULTS.maxSteps}`);
|
|
56436
|
+
show(target, "maxDurationSeconds", e.maxDurationSeconds, `default ${fmtNum(WORKFLOW_AUTONOMY_DEFAULTS.maxDurationSeconds)} \u2014 ${autonomyDurationLabel(WORKFLOW_AUTONOMY_DEFAULTS.maxDurationSeconds)}`);
|
|
56437
|
+
show(target, "maxActions", e.maxActions, "the organization\u2019s own models.consentActions");
|
|
56438
|
+
show(target, "maxRunsPerHour", e.maxRunsPerHour, `default ${WORKFLOW_AUTONOMY_DEFAULTS.maxRunsPerHour}`);
|
|
56439
|
+
show(target, "forms", e.forms?.length ? e.forms : void 0, `${WORKFLOW_AUTONOMY_FORMS_DEFAULT.join(", ")} \u2014 script opts in`);
|
|
56440
|
+
}, "block");
|
|
56441
|
+
if (!autonomy || Object.keys(autonomy).length === 0) {
|
|
56442
|
+
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)");
|
|
56443
|
+
} else {
|
|
56444
|
+
block(lines, autonomy);
|
|
56445
|
+
}
|
|
56446
|
+
if (effective) {
|
|
56447
|
+
lines.push("\n Effective envelope (the server\u2019s own resolution \u2014 org narrowed by agent, defaults applied)");
|
|
56448
|
+
block(lines, effective);
|
|
56449
|
+
if (effective.enabled !== true) lines.push(" (enabled is not true \u2014 nothing is pre-consented; every start that would ask still asks)");
|
|
56450
|
+
} else if (opts.effectiveAsked) {
|
|
56451
|
+
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.");
|
|
56452
|
+
}
|
|
56453
|
+
return lines;
|
|
56454
|
+
}
|
|
56455
|
+
__name(autonomyPolicyLines, "autonomyPolicyLines");
|
|
56456
|
+
var POLICY_NOUNS = [
|
|
56457
|
+
"models",
|
|
56458
|
+
"autonomy"
|
|
56459
|
+
];
|
|
56460
|
+
async function autonomyPolicyCore(ctx, verb, o) {
|
|
56461
|
+
const action = verb ?? "get";
|
|
56462
|
+
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");
|
|
56463
|
+
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.");
|
|
56464
|
+
if (action === "get") {
|
|
56465
|
+
const res2 = await ctx.api.getWorkflowPolicy(ctx.orgId, {
|
|
56466
|
+
effective: true
|
|
56467
|
+
});
|
|
56468
|
+
if (!res2.success || !res2.data) return apiFailure(ctx, res2, "policy autonomy get");
|
|
56469
|
+
emitJson(ctx, res2);
|
|
56470
|
+
if (!ctx.json) for (const line of autonomyPolicyLines(res2.data.autonomy, res2.data.effective?.autonomy, {
|
|
56471
|
+
effectiveAsked: true
|
|
56472
|
+
})) console.log(line);
|
|
56473
|
+
return WORKFLOW_EXIT.OK;
|
|
56474
|
+
}
|
|
56475
|
+
const patch = parsedOrUsage(() => buildAutonomyPolicyPatch(o));
|
|
56476
|
+
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("|")}>`);
|
|
56477
|
+
const named = Object.keys(patch).join(", ");
|
|
56478
|
+
const res = await ctx.api.patchWorkflowPolicyAutonomy(ctx.orgId, patch);
|
|
56479
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "policy autonomy set");
|
|
56480
|
+
emitJson(ctx, res);
|
|
56481
|
+
if (!ctx.json) {
|
|
56482
|
+
writeSuccess(`\u2705 Workflow autonomy policy updated (${named})`);
|
|
56483
|
+
for (const line of autonomyPolicyLines(res.data.autonomy, res.data.effective?.autonomy)) console.log(line);
|
|
56484
|
+
console.log("\n\u{1F4A1} A policy change reaches a starting agent within 30 seconds.");
|
|
56485
|
+
console.log(" The platform switch and `dynamic: false` still sit above it, and `askAboveThresholds: false`");
|
|
56486
|
+
console.log(" still refuses \u2014 autonomy turns an \u201Cask\u201D into an \u201Cauto\u201D, never a \u201Crefuse\u201D into either.");
|
|
56487
|
+
}
|
|
56488
|
+
return WORKFLOW_EXIT.OK;
|
|
56489
|
+
}
|
|
56490
|
+
__name(autonomyPolicyCore, "autonomyPolicyCore");
|
|
56491
|
+
async function policyCore(ctx, noun, verb, o) {
|
|
56492
|
+
if (noun === "autonomy") return autonomyPolicyCore(ctx, verb, o);
|
|
56493
|
+
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`);
|
|
56494
|
+
const action = verb ?? "get";
|
|
56495
|
+
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");
|
|
56496
|
+
if (action === "get") {
|
|
56497
|
+
const res2 = await ctx.api.getWorkflowPolicy(ctx.orgId);
|
|
56498
|
+
if (!res2.success || !res2.data) return apiFailure(ctx, res2, "policy models get");
|
|
56499
|
+
emitJson(ctx, res2);
|
|
56500
|
+
if (!ctx.json) for (const line of modelsPolicyLines(res2.data.models)) console.log(line);
|
|
56501
|
+
return WORKFLOW_EXIT.OK;
|
|
56502
|
+
}
|
|
56503
|
+
const patch = buildModelsPolicyPatch(o);
|
|
56504
|
+
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>");
|
|
56505
|
+
const res = await ctx.api.patchWorkflowPolicyModels(ctx.orgId, patch);
|
|
56506
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "policy models set");
|
|
56507
|
+
emitJson(ctx, res);
|
|
56508
|
+
if (!ctx.json) {
|
|
56509
|
+
writeSuccess(`\u2705 Workflow model policy updated (${Object.keys(patch).join(", ")})`);
|
|
56510
|
+
for (const line of modelsPolicyLines(res.data.models)) console.log(line);
|
|
56511
|
+
console.log("\n\u{1F4A1} A policy change reaches a composing agent within 30 seconds.");
|
|
56512
|
+
}
|
|
56513
|
+
return WORKFLOW_EXIT.OK;
|
|
56514
|
+
}
|
|
56515
|
+
__name(policyCore, "policyCore");
|
|
56516
|
+
async function clearGateCore(ctx, runId, o) {
|
|
56517
|
+
const kind = o.kind;
|
|
56518
|
+
if (!kind) throw CliError.usage("clear-gate: --kind is required", `lua workflows clear-gate ${runId} --kind model_policy`);
|
|
56519
|
+
const res = await ctx.api.clearRunGate(runId, String(kind));
|
|
56520
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "clear-gate");
|
|
56521
|
+
emitJson(ctx, res);
|
|
56522
|
+
if (ctx.json) return WORKFLOW_EXIT.OK;
|
|
56523
|
+
if (res.data.cleared) {
|
|
56524
|
+
writeSuccess(`\u2705 Cleared the ${res.data.kind ?? kind} gate on ${runId}${res.data.status ? ` \u2014 ${res.data.status}` : ""}`);
|
|
56525
|
+
console.log(` lua workflows watch ${runId}`);
|
|
56526
|
+
} else {
|
|
56527
|
+
writeInfo(`\u2139\uFE0F ${runId} is not parked on a ${kind} gate${res.data.reason ? ` \u2014 ${res.data.reason}` : ""}. Nothing to clear.`);
|
|
56528
|
+
}
|
|
56529
|
+
return WORKFLOW_EXIT.OK;
|
|
56530
|
+
}
|
|
56531
|
+
__name(clearGateCore, "clearGateCore");
|
|
56532
|
+
function recomposeNextSteps(wf, version) {
|
|
56533
|
+
const lines = [
|
|
56534
|
+
` lua workflows view ${wf.name}`,
|
|
56535
|
+
` lua workflows versions ${wf.name}`
|
|
56536
|
+
];
|
|
56537
|
+
if (wf.dynamic === true) {
|
|
56538
|
+
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)");
|
|
56539
|
+
} else {
|
|
56540
|
+
lines.push(` lua workflows deploy ${wf.name} -v ${version ?? "latest"}`);
|
|
56541
|
+
}
|
|
56542
|
+
return lines;
|
|
56543
|
+
}
|
|
56544
|
+
__name(recomposeNextSteps, "recomposeNextSteps");
|
|
56545
|
+
async function recomposeCore(ctx, name, _o) {
|
|
56546
|
+
const wf = await resolveWorkflow(ctx, name);
|
|
56547
|
+
if (!wf) return WORKFLOW_EXIT.NOT_FOUND;
|
|
56548
|
+
const res = await ctx.api.recomposeWorkflow(wf.id);
|
|
56549
|
+
if (!res.success || !res.data) return apiFailure(ctx, res, "recompose");
|
|
56550
|
+
emitJson(ctx, res);
|
|
56551
|
+
if (ctx.json) return WORKFLOW_EXIT.OK;
|
|
56552
|
+
const d = res.data;
|
|
56553
|
+
if (d.unchanged) {
|
|
56554
|
+
writeInfo(`\u2139\uFE0F ${wf.name} already asks for model classes everywhere it can \u2014 no new version was published.`);
|
|
56555
|
+
return WORKFLOW_EXIT.OK;
|
|
56556
|
+
}
|
|
56557
|
+
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` : ""));
|
|
56558
|
+
for (const line of recomposeNextSteps(wf, d.version)) console.log(line);
|
|
56559
|
+
return WORKFLOW_EXIT.OK;
|
|
56560
|
+
}
|
|
56561
|
+
__name(recomposeCore, "recomposeCore");
|
|
55387
56562
|
|
|
55388
56563
|
// src/commands/features.ts
|
|
55389
56564
|
init_cli();
|
|
@@ -64118,6 +65293,69 @@ import chalk4 from "chalk";
|
|
|
64118
65293
|
init_compiler2();
|
|
64119
65294
|
init_artifact_loader();
|
|
64120
65295
|
init_analytics();
|
|
65296
|
+
|
|
65297
|
+
// src/commands/models-workflow-view.ts
|
|
65298
|
+
function classOf(m) {
|
|
65299
|
+
const c = m.fitness?.class;
|
|
65300
|
+
return c && WORKFLOW_MODEL_CLASSES.includes(c) ? c : void 0;
|
|
65301
|
+
}
|
|
65302
|
+
__name(classOf, "classOf");
|
|
65303
|
+
function isAwaitingConfirmation(m) {
|
|
65304
|
+
return m.fitness !== void 0 && m.fitness.confirmed !== true;
|
|
65305
|
+
}
|
|
65306
|
+
__name(isAwaitingConfirmation, "isAwaitingConfirmation");
|
|
65307
|
+
function isPinOnly(m) {
|
|
65308
|
+
return classOf(m) === void 0 || m.calibrated === false || isAwaitingConfirmation(m);
|
|
65309
|
+
}
|
|
65310
|
+
__name(isPinOnly, "isPinOnly");
|
|
65311
|
+
function costCell(m) {
|
|
65312
|
+
if (m.actionMultiplier === void 0) return "\u2014";
|
|
65313
|
+
const rate = `${m.actionMultiplier}\xD7`;
|
|
65314
|
+
if (m.billing === "byok") return `${rate} (own key)`;
|
|
65315
|
+
if (m.calibrated === false) return `${rate} (estimate)`;
|
|
65316
|
+
return rate;
|
|
65317
|
+
}
|
|
65318
|
+
__name(costCell, "costCell");
|
|
65319
|
+
function notesCell(m) {
|
|
65320
|
+
const notes = [];
|
|
65321
|
+
if (isAwaitingConfirmation(m)) notes.push("awaiting confirmation");
|
|
65322
|
+
if (m.billing === "byok") notes.push("own key");
|
|
65323
|
+
if (m.calibrated === false) notes.push("rate not calibrated");
|
|
65324
|
+
if (isPinOnly(m)) notes.push("pin only");
|
|
65325
|
+
return notes.length ? notes.join(" \xB7 ") : "";
|
|
65326
|
+
}
|
|
65327
|
+
__name(notesCell, "notesCell");
|
|
65328
|
+
function workflowModelRows(models) {
|
|
65329
|
+
const order = /* @__PURE__ */ __name((m) => {
|
|
65330
|
+
const c = classOf(m);
|
|
65331
|
+
if (c === void 0) return WORKFLOW_MODEL_CLASSES.length;
|
|
65332
|
+
return WORKFLOW_MODEL_CLASSES.indexOf(c);
|
|
65333
|
+
}, "order");
|
|
65334
|
+
return [
|
|
65335
|
+
...models
|
|
65336
|
+
].sort((a, b) => order(a) - order(b) || (a.actionMultiplier ?? 0) - (b.actionMultiplier ?? 0) || a.code.localeCompare(b.code)).map((m) => ({
|
|
65337
|
+
class: classOf(m) ?? "\u2014",
|
|
65338
|
+
code: m.code,
|
|
65339
|
+
bestFor: m.fitness?.bestFor?.length ? m.fitness.bestFor.join(", ") : "\u2014",
|
|
65340
|
+
speed: m.fitness?.speed ?? "\u2014",
|
|
65341
|
+
cost: costCell(m),
|
|
65342
|
+
efforts: m.reasoning?.efforts?.length ? m.reasoning.efforts.join(", ") : "\u2014",
|
|
65343
|
+
notes: notesCell(m)
|
|
65344
|
+
}));
|
|
65345
|
+
}
|
|
65346
|
+
__name(workflowModelRows, "workflowModelRows");
|
|
65347
|
+
function workflowModelFootnotes(models) {
|
|
65348
|
+
const out = [];
|
|
65349
|
+
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.");
|
|
65350
|
+
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.");
|
|
65351
|
+
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.");
|
|
65352
|
+
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.");
|
|
65353
|
+
out.push("\u2022 cost is a multiple of a small call on the pricing baseline model \u2014 the unit your run budget counts.");
|
|
65354
|
+
return out;
|
|
65355
|
+
}
|
|
65356
|
+
__name(workflowModelFootnotes, "workflowModelFootnotes");
|
|
65357
|
+
|
|
65358
|
+
// src/commands/models.ts
|
|
64121
65359
|
init_cli_error();
|
|
64122
65360
|
function noAgentConfigured() {
|
|
64123
65361
|
return CliError.usage("No agent configured.", "Run `lua init` first to set up a project.");
|
|
@@ -64184,6 +65422,44 @@ async function listModels(models, currentModel, opts) {
|
|
|
64184
65422
|
console.log("");
|
|
64185
65423
|
}
|
|
64186
65424
|
__name(listModels, "listModels");
|
|
65425
|
+
async function listWorkflowModels(models, opts) {
|
|
65426
|
+
const rows3 = models;
|
|
65427
|
+
if (opts.json) {
|
|
65428
|
+
console.log(JSON.stringify({
|
|
65429
|
+
view: "workflows",
|
|
65430
|
+
models
|
|
65431
|
+
}, null, 2));
|
|
65432
|
+
return;
|
|
65433
|
+
}
|
|
65434
|
+
const table = workflowModelRows(rows3);
|
|
65435
|
+
console.log("");
|
|
65436
|
+
console.log(chalk4.bold("\u{1F9ED} Models for workflow steps"));
|
|
65437
|
+
console.log("");
|
|
65438
|
+
console.log(renderTable([
|
|
65439
|
+
"Class",
|
|
65440
|
+
"Model",
|
|
65441
|
+
"Best for",
|
|
65442
|
+
"Speed",
|
|
65443
|
+
"Cost",
|
|
65444
|
+
"Efforts",
|
|
65445
|
+
"Notes"
|
|
65446
|
+
], table.map((r) => [
|
|
65447
|
+
r.class,
|
|
65448
|
+
r.code,
|
|
65449
|
+
r.bestFor,
|
|
65450
|
+
r.speed,
|
|
65451
|
+
r.cost,
|
|
65452
|
+
r.efforts,
|
|
65453
|
+
r.notes
|
|
65454
|
+
])));
|
|
65455
|
+
console.log("");
|
|
65456
|
+
for (const note of workflowModelFootnotes(rows3)) console.log(` ${chalk4.gray(note)}`);
|
|
65457
|
+
console.log("");
|
|
65458
|
+
console.log(` \u{1F4A1} A step asks for a class with ${chalk4.cyan("model: 'class/balanced'")}, or names its work with ${chalk4.cyan("taskClass")}.`);
|
|
65459
|
+
console.log(` ${chalk4.cyan("lua workflows policy models get")} shows the classes and ceilings your organization has set.`);
|
|
65460
|
+
console.log("");
|
|
65461
|
+
}
|
|
65462
|
+
__name(listWorkflowModels, "listWorkflowModels");
|
|
64187
65463
|
async function modelsCommand(action, opts) {
|
|
64188
65464
|
return withErrorHandling(async () => {
|
|
64189
65465
|
const resolvedAction = action ? validateOrSuggest("models.action", action) : "list";
|
|
@@ -64201,6 +65477,16 @@ async function modelsCommand(action, opts) {
|
|
|
64201
65477
|
});
|
|
64202
65478
|
return;
|
|
64203
65479
|
}
|
|
65480
|
+
if (opts.workflows) {
|
|
65481
|
+
await listWorkflowModels(models, opts);
|
|
65482
|
+
trackEvent("cli_models_listed", {
|
|
65483
|
+
models_count: models.length,
|
|
65484
|
+
has_current_model: false,
|
|
65485
|
+
json_output: opts.json ?? false,
|
|
65486
|
+
workflows_view: true
|
|
65487
|
+
});
|
|
65488
|
+
return;
|
|
65489
|
+
}
|
|
64204
65490
|
const currentModel = agentId ? await resolveCurrentModel(apiKey, agentId) : null;
|
|
64205
65491
|
await listModels(models, currentModel, opts);
|
|
64206
65492
|
trackEvent("cli_models_listed", {
|
|
@@ -64391,13 +65677,13 @@ function hasSox() {
|
|
|
64391
65677
|
__name(hasSox, "hasSox");
|
|
64392
65678
|
function detectSoxInstaller() {
|
|
64393
65679
|
const os3 = platform3();
|
|
64394
|
-
const
|
|
65680
|
+
const has3 = /* @__PURE__ */ __name((bin) => spawnSync(bin, [
|
|
64395
65681
|
"--version"
|
|
64396
65682
|
], {
|
|
64397
65683
|
stdio: "ignore"
|
|
64398
65684
|
}).status === 0, "has");
|
|
64399
65685
|
if (os3 === "darwin") {
|
|
64400
|
-
if (
|
|
65686
|
+
if (has3("brew")) return {
|
|
64401
65687
|
manager: "Homebrew",
|
|
64402
65688
|
argv: [
|
|
64403
65689
|
"brew",
|
|
@@ -64408,7 +65694,7 @@ function detectSoxInstaller() {
|
|
|
64408
65694
|
return null;
|
|
64409
65695
|
}
|
|
64410
65696
|
if (os3 === "linux") {
|
|
64411
|
-
if (
|
|
65697
|
+
if (has3("apt-get")) return {
|
|
64412
65698
|
manager: "apt",
|
|
64413
65699
|
argv: [
|
|
64414
65700
|
"sudo",
|
|
@@ -64419,7 +65705,7 @@ function detectSoxInstaller() {
|
|
|
64419
65705
|
],
|
|
64420
65706
|
note: "may prompt for sudo password"
|
|
64421
65707
|
};
|
|
64422
|
-
if (
|
|
65708
|
+
if (has3("apt")) return {
|
|
64423
65709
|
manager: "apt",
|
|
64424
65710
|
argv: [
|
|
64425
65711
|
"sudo",
|
|
@@ -64430,7 +65716,7 @@ function detectSoxInstaller() {
|
|
|
64430
65716
|
],
|
|
64431
65717
|
note: "may prompt for sudo password"
|
|
64432
65718
|
};
|
|
64433
|
-
if (
|
|
65719
|
+
if (has3("dnf")) return {
|
|
64434
65720
|
manager: "dnf",
|
|
64435
65721
|
argv: [
|
|
64436
65722
|
"sudo",
|
|
@@ -64441,7 +65727,7 @@ function detectSoxInstaller() {
|
|
|
64441
65727
|
],
|
|
64442
65728
|
note: "may prompt for sudo password"
|
|
64443
65729
|
};
|
|
64444
|
-
if (
|
|
65730
|
+
if (has3("yum")) return {
|
|
64445
65731
|
manager: "yum",
|
|
64446
65732
|
argv: [
|
|
64447
65733
|
"sudo",
|
|
@@ -64452,7 +65738,7 @@ function detectSoxInstaller() {
|
|
|
64452
65738
|
],
|
|
64453
65739
|
note: "may prompt for sudo password"
|
|
64454
65740
|
};
|
|
64455
|
-
if (
|
|
65741
|
+
if (has3("pacman")) return {
|
|
64456
65742
|
manager: "pacman",
|
|
64457
65743
|
argv: [
|
|
64458
65744
|
"sudo",
|
|
@@ -64463,7 +65749,7 @@ function detectSoxInstaller() {
|
|
|
64463
65749
|
],
|
|
64464
65750
|
note: "may prompt for sudo password"
|
|
64465
65751
|
};
|
|
64466
|
-
if (
|
|
65752
|
+
if (has3("apk")) return {
|
|
64467
65753
|
manager: "apk",
|
|
64468
65754
|
argv: [
|
|
64469
65755
|
"sudo",
|
|
@@ -64476,7 +65762,7 @@ function detectSoxInstaller() {
|
|
|
64476
65762
|
return null;
|
|
64477
65763
|
}
|
|
64478
65764
|
if (os3 === "win32") {
|
|
64479
|
-
if (
|
|
65765
|
+
if (has3("winget")) return {
|
|
64480
65766
|
manager: "winget",
|
|
64481
65767
|
argv: [
|
|
64482
65768
|
"winget",
|
|
@@ -64487,7 +65773,7 @@ function detectSoxInstaller() {
|
|
|
64487
65773
|
"--silent"
|
|
64488
65774
|
]
|
|
64489
65775
|
};
|
|
64490
|
-
if (
|
|
65776
|
+
if (has3("choco")) return {
|
|
64491
65777
|
manager: "Chocolatey",
|
|
64492
65778
|
argv: [
|
|
64493
65779
|
"choco",
|
|
@@ -64496,7 +65782,7 @@ function detectSoxInstaller() {
|
|
|
64496
65782
|
"-y"
|
|
64497
65783
|
]
|
|
64498
65784
|
};
|
|
64499
|
-
if (
|
|
65785
|
+
if (has3("scoop")) return {
|
|
64500
65786
|
manager: "Scoop",
|
|
64501
65787
|
argv: [
|
|
64502
65788
|
"scoop",
|
|
@@ -66471,7 +67757,7 @@ Examples:
|
|
|
66471
67757
|
$ lua test skill --name mySkill --json Output raw JSON for scripting
|
|
66472
67758
|
$ lua test workflow --name outreach --input @leads.json --step-output draftEmail=@draft.json --approve reviewDrafts
|
|
66473
67759
|
`).action(testCommand);
|
|
66474
|
-
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", `
|
|
67760
|
+
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", `
|
|
66475
67761
|
Arguments:
|
|
66476
67762
|
type Optional: 'skill', 'agent', 'persona', 'webhook', 'job', 'preprocessor', 'postprocessor', 'mcp', 'backup', or 'all' (prompts if not provided)
|
|
66477
67763
|
|
|
@@ -66727,7 +68013,7 @@ Examples:
|
|
|
66727
68013
|
$ lua jobs versions -i myJob View job versions
|
|
66728
68014
|
$ lua jobs history -i myJob View execution history
|
|
66729
68015
|
`).action(jobsCommand);
|
|
66730
|
-
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
|
|
68016
|
+
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 priced cap of a budget-parked run, in the run's own budget unit \u2014 credits, or actions on a seat plan (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", `
|
|
66731
68017
|
Arguments:
|
|
66732
68018
|
action list \xB7 view \xB7 versions \xB7 deploy \xB7 activate \xB7 deactivate \xB7 start \xB7 run \xB7 runs \xB7 status \xB7
|
|
66733
68019
|
watch \xB7 cancel \xB7 resume \xB7 retry-step \xB7 resolve-step \xB7 raise-budget \xB7 approve \xB7 approval-payload \xB7
|
|
@@ -66784,6 +68070,15 @@ Examples:
|
|
|
66784
68070
|
$ lua workflows goals pause wfg_1234 \xB7 goals resume wfg_1234 \xB7 goals close wfg_1234 --note "shipped"
|
|
66785
68071
|
$ lua workflows schedules list -i outreach
|
|
66786
68072
|
$ lua workflows schedules delete <jobId> --yes (a goal's cadence is refused: goal_schedule)
|
|
68073
|
+
$ lua workflows policy models get
|
|
68074
|
+
$ lua workflows policy models set --compose on --max-class strong --consent-actions 60 --pins class-only
|
|
68075
|
+
$ lua workflows policy models set --class-map judge=strong,draft=balanced --class-fast alibaba/qwen3.8-flash
|
|
68076
|
+
$ lua workflows policy autonomy get (the stored envelope and the one a start is admitted under)
|
|
68077
|
+
$ lua workflows policy autonomy set --enabled on --max-credits 40 --max-steps 20 --max-duration 86400
|
|
68078
|
+
$ lua workflows policy autonomy set --forms graph,static --max-runs-per-hour 20
|
|
68079
|
+
$ lua workflows policy autonomy set --clear max-credits,forms (back to the platform defaults)
|
|
68080
|
+
$ lua workflows clear-gate <runId> --kind model_policy
|
|
68081
|
+
$ lua workflows recompose outreach (rewrites stored task classes into class/<c>; a new version)
|
|
66787
68082
|
`).action(workflowsCommand);
|
|
66788
68083
|
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", `
|
|
66789
68084
|
Arguments:
|
|
@@ -66967,18 +68262,20 @@ Examples:
|
|
|
66967
68262
|
$ lua agents List all orgs and agents (formatted)
|
|
66968
68263
|
$ lua agents --json Output as JSON for scripting
|
|
66969
68264
|
`).action(agentsCommand);
|
|
66970
|
-
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", `
|
|
68265
|
+
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", `
|
|
66971
68266
|
Arguments:
|
|
66972
68267
|
action Optional: 'list', 'set', or 'unset' (default: list)
|
|
66973
68268
|
|
|
66974
68269
|
Options:
|
|
66975
68270
|
--model <code> Set model non-interactively (use with 'set' action)
|
|
66976
68271
|
--json Output list as JSON (use with 'list' action)
|
|
68272
|
+
--workflows List for workflow steps: class, best for, speed, cost, efforts (use with 'list')
|
|
66977
68273
|
|
|
66978
68274
|
Examples:
|
|
66979
68275
|
$ lua models List available models (formatted)
|
|
66980
68276
|
$ lua models list List available models (explicit)
|
|
66981
68277
|
$ lua models list --json List as JSON for scripting
|
|
68278
|
+
$ lua models list --workflows Class, best for, speed, cost and efforts, for workflow steps
|
|
66982
68279
|
$ lua models set Interactively select a model
|
|
66983
68280
|
$ lua models set --model openai/gpt-4o Set model non-interactively
|
|
66984
68281
|
$ lua models unset Remove model \u2014 use platform default
|