lua-cli 3.35.0 → 3.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -658,6 +658,274 @@ function isDesktopFileSessionId(value3) {
658
658
  }
659
659
  __name(isDesktopFileSessionId, "isDesktopFileSessionId");
660
660
  __name2(isDesktopFileSessionId, "isDesktopFileSessionId");
661
+ var WORKFLOW_RETRY_BACKOFFS = [
662
+ "fixed",
663
+ "exponential"
664
+ ];
665
+ var WORKFLOW_RETRY_MIN_ATTEMPTS = 1;
666
+ var WORKFLOW_RETRY_POLICY_KEYS = [
667
+ "maxAttempts",
668
+ "backoffSeconds",
669
+ "backoff",
670
+ "maxBackoffSeconds"
671
+ ];
672
+ var WORKFLOW_RETRY_MAX_ATTEMPTS = 20;
673
+ function workflowRetryMaxAttemptsMessage(got) {
674
+ const tail = got === void 0 ? "" : ` (got ${JSON.stringify(got)})`;
675
+ return `\`retry.maxAttempts\` must be an integer ${WORKFLOW_RETRY_MIN_ATTEMPTS}..${WORKFLOW_RETRY_MAX_ATTEMPTS}${tail}`;
676
+ }
677
+ __name(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
678
+ __name2(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
679
+ function isWithinWorkflowRetryAttempts(value3) {
680
+ return typeof value3 === "number" && Number.isInteger(value3) && value3 >= WORKFLOW_RETRY_MIN_ATTEMPTS && value3 <= WORKFLOW_RETRY_MAX_ATTEMPTS;
681
+ }
682
+ __name(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
683
+ __name2(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
684
+ var WORKFLOW_RETRY_ENGINE_KEYS = [
685
+ "budgetBaseAttempt"
686
+ ];
687
+ function workflowRetryUnknownMembersMessage(keys) {
688
+ const named = keys.map((k) => {
689
+ const engine = WORKFLOW_RETRY_ENGINE_KEYS.includes(k);
690
+ return `\`${k}\`${engine ? " (engine-owned \u2014 stamped by resetAttempts, never authored)" : ""}`;
691
+ });
692
+ return `\`retry\` has no member ${named.join(", ")}; members: ${WORKFLOW_RETRY_POLICY_KEYS.join(", ")}`;
693
+ }
694
+ __name(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
695
+ __name2(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
696
+ function unknownWorkflowRetryMembers(retry) {
697
+ if (!retry || typeof retry !== "object" || Array.isArray(retry)) return [];
698
+ return Object.keys(retry).filter((k) => !WORKFLOW_RETRY_POLICY_KEYS.includes(k));
699
+ }
700
+ __name(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
701
+ __name2(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
702
+ function authoredRetryPolicy(retry) {
703
+ if (!retry || typeof retry !== "object" || Array.isArray(retry)) return void 0;
704
+ const src = retry;
705
+ const out = {};
706
+ for (const k of WORKFLOW_RETRY_POLICY_KEYS) if (src[k] !== void 0) out[k] = src[k];
707
+ return Object.keys(out).length ? out : void 0;
708
+ }
709
+ __name(authoredRetryPolicy, "authoredRetryPolicy");
710
+ __name2(authoredRetryPolicy, "authoredRetryPolicy");
711
+ function retryBudgetBaseAttempt(row) {
712
+ const base = row.retry?.budgetBaseAttempt;
713
+ return typeof base === "number" && Number.isSafeInteger(base) && base > 0 ? base : 0;
714
+ }
715
+ __name(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
716
+ __name2(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
717
+ function retryBudgetAttempt(row) {
718
+ return Math.max(0, row.attempt - retryBudgetBaseAttempt(row));
719
+ }
720
+ __name(retryBudgetAttempt, "retryBudgetAttempt");
721
+ __name2(retryBudgetAttempt, "retryBudgetAttempt");
722
+ function retryBudgetMaxAttempts(row) {
723
+ const max = row.retry?.maxAttempts;
724
+ return typeof max === "number" && Number.isFinite(max) && max >= 1 ? max : 1;
725
+ }
726
+ __name(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
727
+ __name2(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
728
+ function retryBudgetRemaining(row) {
729
+ return retryBudgetAttempt(row) < retryBudgetMaxAttempts(row);
730
+ }
731
+ __name(retryBudgetRemaining, "retryBudgetRemaining");
732
+ __name2(retryBudgetRemaining, "retryBudgetRemaining");
733
+ function retriesRemaining(row) {
734
+ return Math.max(0, retryBudgetMaxAttempts(row) - retryBudgetAttempt(row));
735
+ }
736
+ __name(retriesRemaining, "retriesRemaining");
737
+ __name2(retriesRemaining, "retriesRemaining");
738
+ var WORKFLOW_JOB_RESOURCES = [
739
+ "small",
740
+ "medium",
741
+ "large"
742
+ ];
743
+ var WORKFLOW_SIDE_EFFECTS = [
744
+ "none",
745
+ "external"
746
+ ];
747
+ var WORKFLOW_MODEL_CLASSES = [
748
+ "fast",
749
+ "balanced",
750
+ "strong"
751
+ ];
752
+ function workflowModelCostComparison(estimate, onAgentModel, agentModel) {
753
+ if (agentModel === void 0 || onAgentModel === void 0 || !(onAgentModel > 0)) return void 0;
754
+ const ratio = Math.round(estimate / onAgentModel * 10) / 10;
755
+ return `\u2248 ${ratio}\xD7 the cost of running every step on ${agentModel}`;
756
+ }
757
+ __name(workflowModelCostComparison, "workflowModelCostComparison");
758
+ __name2(workflowModelCostComparison, "workflowModelCostComparison");
759
+ var WORKFLOW_DEFAULT_TASK_CLASS_MAP = Object.freeze({
760
+ classify: "fast",
761
+ extract: "fast",
762
+ transform: "fast",
763
+ draft: "balanced",
764
+ research: "balanced",
765
+ judge: "balanced",
766
+ reason: "strong",
767
+ code: "strong"
768
+ });
769
+ var WORKFLOW_MODELS_MAX_CLASS_DEFAULT = WORKFLOW_MODEL_CLASSES[WORKFLOW_MODEL_CLASSES.length - 1];
770
+ function modelClassRank(modelClass) {
771
+ return WORKFLOW_MODEL_CLASSES.indexOf(modelClass);
772
+ }
773
+ __name(modelClassRank, "modelClassRank");
774
+ __name2(modelClassRank, "modelClassRank");
775
+ function modelClassesAtOrBelow(maxClass) {
776
+ const ceiling = modelClassRank(maxClass);
777
+ return WORKFLOW_MODEL_CLASSES.filter((c) => modelClassRank(c) <= ceiling);
778
+ }
779
+ __name(modelClassesAtOrBelow, "modelClassesAtOrBelow");
780
+ __name2(modelClassesAtOrBelow, "modelClassesAtOrBelow");
781
+ var WORKFLOW_AUTONOMY_NUMERIC_KEYS = [
782
+ "maxCredits",
783
+ "maxSteps",
784
+ "maxDurationSeconds",
785
+ "maxActions",
786
+ "maxRunsPerHour"
787
+ ];
788
+ var WORKFLOW_AUTONOMY_ENVELOPE_KEYS = [
789
+ "enabled",
790
+ ...WORKFLOW_AUTONOMY_NUMERIC_KEYS,
791
+ "forms"
792
+ ];
793
+ var WORKFLOW_AUTONOMY_DEFAULTS = Object.freeze({
794
+ maxCredits: 20,
795
+ maxSteps: 15,
796
+ maxDurationSeconds: 86400,
797
+ maxRunsPerHour: 20
798
+ });
799
+ var WORKFLOW_AUTONOMY_CEILINGS = Object.freeze({
800
+ maxSteps: 40,
801
+ maxDurationSeconds: 604800
802
+ });
803
+ var WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV = "LUA_WF_AUTONOMY_MAX_RUNS_PER_HOUR";
804
+ var WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING = 200;
805
+ function workflowAutonomyMaxRunsPerHourCeiling(env) {
806
+ const raw = Number((env ?? process.env)[WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_ENV]);
807
+ return Number.isFinite(raw) && raw > 0 ? raw : WORKFLOW_AUTONOMY_MAX_RUNS_PER_HOUR_CEILING;
808
+ }
809
+ __name(workflowAutonomyMaxRunsPerHourCeiling, "workflowAutonomyMaxRunsPerHourCeiling");
810
+ __name2(workflowAutonomyMaxRunsPerHourCeiling, "workflowAutonomyMaxRunsPerHourCeiling");
811
+ var WORKFLOW_AUTONOMY_FORMS_DEFAULT = Object.freeze([
812
+ "graph",
813
+ "static"
814
+ ]);
815
+ var WORKFLOW_AUTONOMY_MIN_VALUE = 1;
816
+ function isWithinWorkflowAutonomyRange(value3, ceiling) {
817
+ return typeof value3 === "number" && Number.isInteger(value3) && value3 >= WORKFLOW_AUTONOMY_MIN_VALUE && value3 <= ceiling;
818
+ }
819
+ __name(isWithinWorkflowAutonomyRange, "isWithinWorkflowAutonomyRange");
820
+ __name2(isWithinWorkflowAutonomyRange, "isWithinWorkflowAutonomyRange");
821
+ function workflowAutonomyRangeMessage(key, ceiling) {
822
+ return `\`${key}\` must be an integer ${WORKFLOW_AUTONOMY_MIN_VALUE}..${ceiling}`;
823
+ }
824
+ __name(workflowAutonomyRangeMessage, "workflowAutonomyRangeMessage");
825
+ __name2(workflowAutonomyRangeMessage, "workflowAutonomyRangeMessage");
826
+ var WORKFLOW_JOB_RANGES = Object.freeze({
827
+ /** Coding-turn cap (`claude -p --max-turns`); absent ⇒ the cluster default (LUA_WF_JOB_MAX_TURNS). */
828
+ maxTurns: Object.freeze({
829
+ min: 1,
830
+ max: 500
831
+ }),
832
+ /** Harness messages per attempt (one per content block); absent ⇒ the cluster default (400). */
833
+ maxMessages: Object.freeze({
834
+ min: 1,
835
+ max: 5e3
836
+ }),
837
+ /** Input-side tokens per attempt (prompt + cache); absent ⇒ the cluster default (4M — LUA-708, was 30M). */
838
+ maxInputTokens: Object.freeze({
839
+ min: 1e6,
840
+ max: 5e8
841
+ })
842
+ });
843
+ var WORKFLOW_JOB_RANGE_MEMBERS = Object.keys(WORKFLOW_JOB_RANGES);
844
+ function isWithinWorkflowJobRange(member, value3) {
845
+ const { min, max } = WORKFLOW_JOB_RANGES[member];
846
+ return typeof value3 === "number" && Number.isInteger(value3) && value3 >= min && value3 <= max;
847
+ }
848
+ __name(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
849
+ __name2(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
850
+ function workflowJobRangeMessage(member) {
851
+ const { min, max } = WORKFLOW_JOB_RANGES[member];
852
+ return `\`${member}\` must be an integer ${min}..${max}`;
853
+ }
854
+ __name(workflowJobRangeMessage, "workflowJobRangeMessage");
855
+ __name2(workflowJobRangeMessage, "workflowJobRangeMessage");
856
+ var WORKFLOW_SINGLE_STEP_TYPES = [
857
+ "agent",
858
+ "tool",
859
+ "workflow",
860
+ "step"
861
+ ];
862
+ var WORKFLOW_HITL_ENTRY_TYPES = [
863
+ "approval",
864
+ "waitForSignal"
865
+ ];
866
+ var WORKFLOW_ARM_ENTRY_TYPES = [
867
+ ...WORKFLOW_SINGLE_STEP_TYPES,
868
+ ...WORKFLOW_HITL_ENTRY_TYPES
869
+ ];
870
+ var WORKFLOW_HITL_ARM_CONTAINERS = [
871
+ "parallel",
872
+ "conditional",
873
+ "foreach"
874
+ ];
875
+ function isWorkflowSingleStepType(type) {
876
+ return typeof type === "string" && WORKFLOW_SINGLE_STEP_TYPES.includes(type);
877
+ }
878
+ __name(isWorkflowSingleStepType, "isWorkflowSingleStepType");
879
+ __name2(isWorkflowSingleStepType, "isWorkflowSingleStepType");
880
+ function isWorkflowHitlEntryType(type) {
881
+ return typeof type === "string" && WORKFLOW_HITL_ENTRY_TYPES.includes(type);
882
+ }
883
+ __name(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
884
+ __name2(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
885
+ function isWorkflowArmEntryType(type) {
886
+ return typeof type === "string" && WORKFLOW_ARM_ENTRY_TYPES.includes(type);
887
+ }
888
+ __name(isWorkflowArmEntryType, "isWorkflowArmEntryType");
889
+ __name2(isWorkflowArmEntryType, "isWorkflowArmEntryType");
890
+ function workflowContainerRunsHitlArm(container) {
891
+ return typeof container === "string" && WORKFLOW_HITL_ARM_CONTAINERS.includes(container);
892
+ }
893
+ __name(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
894
+ __name2(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
895
+ function workflowHitlArmUnsupportedMessage(type, id, container) {
896
+ const legal = WORKFLOW_HITL_ARM_CONTAINERS.map((c) => `\`${c}\``).join(" / ");
897
+ 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\``;
898
+ }
899
+ __name(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
900
+ __name2(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
901
+ function workflowHitlArmShapeMessage(type, id, shape) {
902
+ 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\``;
903
+ }
904
+ __name(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
905
+ __name2(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
906
+ var WORKFLOW_GRAPH_ENTRY_STEP_KINDS = Object.freeze({
907
+ agent: "agent",
908
+ tool: "tool",
909
+ workflow: "subrun",
910
+ step: "code",
911
+ mapping: "map",
912
+ sleep: "sleep",
913
+ sleepUntil: "sleepUntil",
914
+ parallel: null,
915
+ conditional: "branch",
916
+ foreach: "foreach",
917
+ loop: "loop",
918
+ approval: "approval",
919
+ waitForSignal: "signal"
920
+ });
921
+ var WORKFLOW_ARM_ENTRY_STEP_KINDS = Object.freeze(Object.fromEntries(WORKFLOW_ARM_ENTRY_TYPES.map((t) => [
922
+ t,
923
+ WORKFLOW_GRAPH_ENTRY_STEP_KINDS[t]
924
+ ])));
925
+ var WORKFLOW_BUDGET_MAX_DURATION_SECONDS = Object.freeze({
926
+ min: 60,
927
+ max: 2592e3
928
+ });
661
929
  var MODEL_ID_BYOK_PROVIDERS = [
662
930
  "azure",
663
931
  "bedrock"
@@ -668,6 +936,25 @@ function isModelIdSentinel(input) {
668
936
  }
669
937
  __name(isModelIdSentinel, "isModelIdSentinel");
670
938
  __name2(isModelIdSentinel, "isModelIdSentinel");
939
+ var MODEL_CLASS_REF_PREFIX = "class/";
940
+ function isModelClassRef(input) {
941
+ return modelClassOf(input) !== void 0;
942
+ }
943
+ __name(isModelClassRef, "isModelClassRef");
944
+ __name2(isModelClassRef, "isModelClassRef");
945
+ function modelClassOf(input) {
946
+ const lower = (input ?? "").trim().toLowerCase();
947
+ if (!lower.startsWith(MODEL_CLASS_REF_PREFIX)) return void 0;
948
+ const c = lower.slice(MODEL_CLASS_REF_PREFIX.length);
949
+ return WORKFLOW_MODEL_CLASSES.includes(c) ? c : void 0;
950
+ }
951
+ __name(modelClassOf, "modelClassOf");
952
+ __name2(modelClassOf, "modelClassOf");
953
+ function modelClassRef(modelClass) {
954
+ return `${MODEL_CLASS_REF_PREFIX}${modelClass}`;
955
+ }
956
+ __name(modelClassRef, "modelClassRef");
957
+ __name2(modelClassRef, "modelClassRef");
671
958
  function normalizeModelId(input, registry) {
672
959
  const requested = typeof input === "string" ? input.trim() : "";
673
960
  if (!requested) return {
@@ -682,6 +969,11 @@ function normalizeModelId(input, registry) {
682
969
  id: lower,
683
970
  form: "sentinel"
684
971
  };
972
+ if (modelClassOf(lower) !== void 0) return {
973
+ ok: true,
974
+ id: lower,
975
+ form: "class"
976
+ };
685
977
  const slash = requested.indexOf("/");
686
978
  const malformed = slash === 0;
687
979
  const provider = slash > 0 ? lower.slice(0, slash) : void 0;
@@ -746,6 +1038,11 @@ function modelUnresolvedMessage(r) {
746
1038
  }
747
1039
  __name(modelUnresolvedMessage, "modelUnresolvedMessage");
748
1040
  __name2(modelUnresolvedMessage, "modelUnresolvedMessage");
1041
+ function modelClassUnresolvedMessage(ref) {
1042
+ 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`;
1043
+ }
1044
+ __name(modelClassUnresolvedMessage, "modelClassUnresolvedMessage");
1045
+ __name2(modelClassUnresolvedMessage, "modelClassUnresolvedMessage");
749
1046
  function providerModelId(code) {
750
1047
  const requested = typeof code === "string" ? code.trim() : "";
751
1048
  if (!requested || isModelIdSentinel(requested)) return requested;
@@ -1599,7 +1896,15 @@ var ProjectedOrgSchema = z3.object({
1599
1896
  "org-grant",
1600
1897
  "agent-grant-only"
1601
1898
  ]).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."),
1602
- anomalies: z3.array(ProjectionAnomalySchema).optional()
1899
+ anomalies: z3.array(ProjectionAnomalySchema).optional(),
1900
+ /**
1901
+ * How many agents and Spaces in this org the caller can read — the size of
1902
+ * the org's resource page under the same discovery rule, without paging it.
1903
+ */
1904
+ resourceCounts: z3.object({
1905
+ agents: z3.number().int().nonnegative(),
1906
+ spaces: z3.number().int().nonnegative()
1907
+ }).optional()
1603
1908
  }).passthrough();
1604
1909
  var ProjectedResourceSchema = z3.object({
1605
1910
  resourceType: z3.literal("agent"),
@@ -1638,7 +1943,21 @@ var ProjectedResourceSchema = z3.object({
1638
1943
  id: z3.string().min(1).max(256),
1639
1944
  name: z3.string().optional(),
1640
1945
  email: z3.string().optional()
1641
- }).optional()
1946
+ }).optional(),
1947
+ /**
1948
+ * Presentation enrichment (PRO-1994), product data only — never influences
1949
+ * discovery. These moved off the O(orgs) `/context` roster onto the bounded
1950
+ * per-active-org resource page so Desktop stops paying an org-count-scaled
1951
+ * cost at sign-in. `persona`/`avatar` are loose (`PersonaText` / `AgentAvatar`
1952
+ * are structured-or-string), `platform` marks the org's Designer agent
1953
+ * (previously stamped only by `/context`; retires with PRO-1657).
1954
+ */
1955
+ persona: z3.unknown().optional(),
1956
+ description: z3.string().optional(),
1957
+ avatar: z3.unknown().nullish(),
1958
+ platform: z3.boolean().optional(),
1959
+ /** A Space's supervised agent ids (`kind: 'space'` rows only). */
1960
+ supervisedAgents: z3.array(z3.string()).optional()
1642
1961
  }).passthrough();
1643
1962
  var CapabilityProfilesSchema = z3.record(z3.string().min(1).max(64), z3.array(ProjectedScopeSchema));
1644
1963
  var RoleCatalogSchema = z3.record(z3.string().min(1).max(128), z3.object({
@@ -1824,7 +2143,8 @@ var WORKFLOW_RUN_GATE_KINDS = [
1824
2143
  "org_archived",
1825
2144
  "disabled",
1826
2145
  "exception",
1827
- "budget"
2146
+ "budget",
2147
+ "model_policy"
1828
2148
  ];
1829
2149
  var WORKFLOW_STEP_STATUSES = [
1830
2150
  "pending",
@@ -1981,195 +2301,6 @@ var WORKFLOW_RUN_NOTIFICATION_SUSPENDED_KINDS = [
1981
2301
  ];
1982
2302
  var WORKFLOW_SIGNAL_PAYLOAD_MAX_BYTES = 64 * 1024;
1983
2303
  var WORKFLOW_RESOLVE_OUTPUT_MAX_BYTES = 256 * 1024;
1984
- var WORKFLOW_RETRY_BACKOFFS = [
1985
- "fixed",
1986
- "exponential"
1987
- ];
1988
- var WORKFLOW_RETRY_MIN_ATTEMPTS = 1;
1989
- var WORKFLOW_RETRY_POLICY_KEYS = [
1990
- "maxAttempts",
1991
- "backoffSeconds",
1992
- "backoff",
1993
- "maxBackoffSeconds"
1994
- ];
1995
- var WORKFLOW_RETRY_MAX_ATTEMPTS = 20;
1996
- function workflowRetryMaxAttemptsMessage(got) {
1997
- const tail = got === void 0 ? "" : ` (got ${JSON.stringify(got)})`;
1998
- return `\`retry.maxAttempts\` must be an integer ${WORKFLOW_RETRY_MIN_ATTEMPTS}..${WORKFLOW_RETRY_MAX_ATTEMPTS}${tail}`;
1999
- }
2000
- __name(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
2001
- __name2(workflowRetryMaxAttemptsMessage, "workflowRetryMaxAttemptsMessage");
2002
- function isWithinWorkflowRetryAttempts(value3) {
2003
- return typeof value3 === "number" && Number.isInteger(value3) && value3 >= WORKFLOW_RETRY_MIN_ATTEMPTS && value3 <= WORKFLOW_RETRY_MAX_ATTEMPTS;
2004
- }
2005
- __name(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
2006
- __name2(isWithinWorkflowRetryAttempts, "isWithinWorkflowRetryAttempts");
2007
- var WORKFLOW_RETRY_ENGINE_KEYS = [
2008
- "budgetBaseAttempt"
2009
- ];
2010
- function workflowRetryUnknownMembersMessage(keys) {
2011
- const named = keys.map((k) => {
2012
- const engine = WORKFLOW_RETRY_ENGINE_KEYS.includes(k);
2013
- return `\`${k}\`${engine ? " (engine-owned \u2014 stamped by resetAttempts, never authored)" : ""}`;
2014
- });
2015
- return `\`retry\` has no member ${named.join(", ")}; members: ${WORKFLOW_RETRY_POLICY_KEYS.join(", ")}`;
2016
- }
2017
- __name(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
2018
- __name2(workflowRetryUnknownMembersMessage, "workflowRetryUnknownMembersMessage");
2019
- function unknownWorkflowRetryMembers(retry) {
2020
- if (!retry || typeof retry !== "object" || Array.isArray(retry)) return [];
2021
- return Object.keys(retry).filter((k) => !WORKFLOW_RETRY_POLICY_KEYS.includes(k));
2022
- }
2023
- __name(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
2024
- __name2(unknownWorkflowRetryMembers, "unknownWorkflowRetryMembers");
2025
- function authoredRetryPolicy(retry) {
2026
- if (!retry || typeof retry !== "object" || Array.isArray(retry)) return void 0;
2027
- const src = retry;
2028
- const out = {};
2029
- for (const k of WORKFLOW_RETRY_POLICY_KEYS) if (src[k] !== void 0) out[k] = src[k];
2030
- return Object.keys(out).length ? out : void 0;
2031
- }
2032
- __name(authoredRetryPolicy, "authoredRetryPolicy");
2033
- __name2(authoredRetryPolicy, "authoredRetryPolicy");
2034
- function retryBudgetBaseAttempt(row) {
2035
- const base = row.retry?.budgetBaseAttempt;
2036
- return typeof base === "number" && Number.isSafeInteger(base) && base > 0 ? base : 0;
2037
- }
2038
- __name(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
2039
- __name2(retryBudgetBaseAttempt, "retryBudgetBaseAttempt");
2040
- function retryBudgetAttempt(row) {
2041
- return Math.max(0, row.attempt - retryBudgetBaseAttempt(row));
2042
- }
2043
- __name(retryBudgetAttempt, "retryBudgetAttempt");
2044
- __name2(retryBudgetAttempt, "retryBudgetAttempt");
2045
- function retryBudgetMaxAttempts(row) {
2046
- const max = row.retry?.maxAttempts;
2047
- return typeof max === "number" && Number.isFinite(max) && max >= 1 ? max : 1;
2048
- }
2049
- __name(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
2050
- __name2(retryBudgetMaxAttempts, "retryBudgetMaxAttempts");
2051
- function retryBudgetRemaining(row) {
2052
- return retryBudgetAttempt(row) < retryBudgetMaxAttempts(row);
2053
- }
2054
- __name(retryBudgetRemaining, "retryBudgetRemaining");
2055
- __name2(retryBudgetRemaining, "retryBudgetRemaining");
2056
- function retriesRemaining(row) {
2057
- return Math.max(0, retryBudgetMaxAttempts(row) - retryBudgetAttempt(row));
2058
- }
2059
- __name(retriesRemaining, "retriesRemaining");
2060
- __name2(retriesRemaining, "retriesRemaining");
2061
- var WORKFLOW_JOB_RESOURCES = [
2062
- "small",
2063
- "medium",
2064
- "large"
2065
- ];
2066
- var WORKFLOW_SIDE_EFFECTS = [
2067
- "none",
2068
- "external"
2069
- ];
2070
- var WORKFLOW_JOB_RANGES = Object.freeze({
2071
- /** Coding-turn cap (`claude -p --max-turns`); absent ⇒ the cluster default (LUA_WF_JOB_MAX_TURNS). */
2072
- maxTurns: Object.freeze({
2073
- min: 1,
2074
- max: 500
2075
- }),
2076
- /** Harness messages per attempt (one per content block); absent ⇒ the cluster default (400). */
2077
- maxMessages: Object.freeze({
2078
- min: 1,
2079
- max: 5e3
2080
- }),
2081
- /** Input-side tokens per attempt (prompt + cache); absent ⇒ the cluster default (4M — LUA-708, was 30M). */
2082
- maxInputTokens: Object.freeze({
2083
- min: 1e6,
2084
- max: 5e8
2085
- })
2086
- });
2087
- var WORKFLOW_JOB_RANGE_MEMBERS = Object.keys(WORKFLOW_JOB_RANGES);
2088
- function isWithinWorkflowJobRange(member, value3) {
2089
- const { min, max } = WORKFLOW_JOB_RANGES[member];
2090
- return typeof value3 === "number" && Number.isInteger(value3) && value3 >= min && value3 <= max;
2091
- }
2092
- __name(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
2093
- __name2(isWithinWorkflowJobRange, "isWithinWorkflowJobRange");
2094
- function workflowJobRangeMessage(member) {
2095
- const { min, max } = WORKFLOW_JOB_RANGES[member];
2096
- return `\`${member}\` must be an integer ${min}..${max}`;
2097
- }
2098
- __name(workflowJobRangeMessage, "workflowJobRangeMessage");
2099
- __name2(workflowJobRangeMessage, "workflowJobRangeMessage");
2100
- var WORKFLOW_SINGLE_STEP_TYPES = [
2101
- "agent",
2102
- "tool",
2103
- "workflow",
2104
- "step"
2105
- ];
2106
- var WORKFLOW_HITL_ENTRY_TYPES = [
2107
- "approval",
2108
- "waitForSignal"
2109
- ];
2110
- var WORKFLOW_ARM_ENTRY_TYPES = [
2111
- ...WORKFLOW_SINGLE_STEP_TYPES,
2112
- ...WORKFLOW_HITL_ENTRY_TYPES
2113
- ];
2114
- var WORKFLOW_HITL_ARM_CONTAINERS = [
2115
- "parallel",
2116
- "conditional",
2117
- "foreach"
2118
- ];
2119
- function isWorkflowSingleStepType(type) {
2120
- return typeof type === "string" && WORKFLOW_SINGLE_STEP_TYPES.includes(type);
2121
- }
2122
- __name(isWorkflowSingleStepType, "isWorkflowSingleStepType");
2123
- __name2(isWorkflowSingleStepType, "isWorkflowSingleStepType");
2124
- function isWorkflowHitlEntryType(type) {
2125
- return typeof type === "string" && WORKFLOW_HITL_ENTRY_TYPES.includes(type);
2126
- }
2127
- __name(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
2128
- __name2(isWorkflowHitlEntryType, "isWorkflowHitlEntryType");
2129
- function isWorkflowArmEntryType(type) {
2130
- return typeof type === "string" && WORKFLOW_ARM_ENTRY_TYPES.includes(type);
2131
- }
2132
- __name(isWorkflowArmEntryType, "isWorkflowArmEntryType");
2133
- __name2(isWorkflowArmEntryType, "isWorkflowArmEntryType");
2134
- function workflowContainerRunsHitlArm(container) {
2135
- return typeof container === "string" && WORKFLOW_HITL_ARM_CONTAINERS.includes(container);
2136
- }
2137
- __name(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
2138
- __name2(workflowContainerRunsHitlArm, "workflowContainerRunsHitlArm");
2139
- function workflowHitlArmUnsupportedMessage(type, id, container) {
2140
- const legal = WORKFLOW_HITL_ARM_CONTAINERS.map((c) => `\`${c}\``).join(" / ");
2141
- 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\``;
2142
- }
2143
- __name(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
2144
- __name2(workflowHitlArmUnsupportedMessage, "workflowHitlArmUnsupportedMessage");
2145
- function workflowHitlArmShapeMessage(type, id, shape) {
2146
- 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\``;
2147
- }
2148
- __name(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
2149
- __name2(workflowHitlArmShapeMessage, "workflowHitlArmShapeMessage");
2150
- var WORKFLOW_GRAPH_ENTRY_STEP_KINDS = Object.freeze({
2151
- agent: "agent",
2152
- tool: "tool",
2153
- workflow: "subrun",
2154
- step: "code",
2155
- mapping: "map",
2156
- sleep: "sleep",
2157
- sleepUntil: "sleepUntil",
2158
- parallel: null,
2159
- conditional: "branch",
2160
- foreach: "foreach",
2161
- loop: "loop",
2162
- approval: "approval",
2163
- waitForSignal: "signal"
2164
- });
2165
- var WORKFLOW_ARM_ENTRY_STEP_KINDS = Object.freeze(Object.fromEntries(WORKFLOW_ARM_ENTRY_TYPES.map((t) => [
2166
- t,
2167
- WORKFLOW_GRAPH_ENTRY_STEP_KINDS[t]
2168
- ])));
2169
- var WORKFLOW_BUDGET_MAX_DURATION_SECONDS = Object.freeze({
2170
- min: 60,
2171
- max: 2592e3
2172
- });
2173
2304
  var WORKFLOW_GOAL_JUDGE_SELF = "$self";
2174
2305
  function workflowGoalJudgeKind(judge) {
2175
2306
  return judge && typeof judge === "object" && judge.predicate !== void 0 ? "predicate" : "agent";
@@ -2457,7 +2588,20 @@ var WORKFLOW_AUDIT_EVENTS = [
2457
2588
  "workflow.export.auto_pushed",
2458
2589
  "workflow.retention.restamped",
2459
2590
  "workflow.retention.reaped",
2460
- "workflow.run.schema_migrated"
2591
+ "workflow.run.schema_migrated",
2592
+ // --- per-step model selection (Workflow Model Selection plan 6.5 / Appendix C.4) ---
2593
+ /** A `PATCH /admin/orgs/:orgId/workflow-policy` that changed the `models` block (who, what moved). */
2594
+ "workflow.policy.models_changed",
2595
+ /** A step's invocation hopped to another leg of its class — `{from, to, reason}`, priced at the served model. */
2596
+ "workflow.step.model_fallback",
2597
+ // --- autonomy envelope (Workflow autonomy plan A1; research/consent-gates.md §H2) ---
2598
+ /**
2599
+ * A start the consent ladder would have PARKED was admitted by `workflowPolicy.autonomy` instead —
2600
+ * `WorkflowRunAutonomyAppliedPayload`. Deliberately NOT `workflow.run.gate_cleared`: nothing was
2601
+ * gated and nobody approved it, and conflating the two would make "who approved this run"
2602
+ * unanswerable for every run of either kind (§H2 "Audit").
2603
+ */
2604
+ "workflow.run.autonomy_applied"
2461
2605
  ];
2462
2606
  var WORKFLOW_AUDIT_METADATA_MAX_BYTES = 4 * 1024;
2463
2607
  function isWorkflowAuditEvent(action) {
@@ -3233,7 +3377,7 @@ function modelTemplateInvalidMessage(model, why) {
3233
3377
  __name(modelTemplateInvalidMessage, "modelTemplateInvalidMessage");
3234
3378
  __name4(modelTemplateInvalidMessage, "modelTemplateInvalidMessage");
3235
3379
  function modelTemplateDefaultRequiredMessage(model) {
3236
- 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>}")}`;
3380
+ 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)`;
3237
3381
  }
3238
3382
  __name(modelTemplateDefaultRequiredMessage, "modelTemplateDefaultRequiredMessage");
3239
3383
  __name4(modelTemplateDefaultRequiredMessage, "modelTemplateDefaultRequiredMessage");
@@ -4008,6 +4152,21 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4008
4152
  err("required-connection-unknown", `requiredConnections ${JSON.stringify(unknown)} are neither declared connections[].key values nor connections the owner can mount`, `${path}.requiredConnections`, singleId(node));
4009
4153
  }
4010
4154
  }, "checkRequiredConnections");
4155
+ const jobClassifiablePin = /* @__PURE__ */ __name4((model) => {
4156
+ const pin = staticModelPin(model);
4157
+ const modelClass = modelClassOf(pin);
4158
+ if (modelClass === void 0) return pin;
4159
+ const codes = opts.classMap?.[modelClass];
4160
+ if (!codes) return void 0;
4161
+ const jobProviders = opts.policy?.jobProviders;
4162
+ for (const code of codes) {
4163
+ const p = classifyModelProvider(code);
4164
+ if (p === null) continue;
4165
+ if (jobProviders && !jobProviders.includes(p)) continue;
4166
+ return code;
4167
+ }
4168
+ return void 0;
4169
+ }, "jobClassifiablePin");
4011
4170
  const checkTier = /* @__PURE__ */ __name4((node, path) => {
4012
4171
  const id = singleId(node);
4013
4172
  if (node.workspace && node.workspace !== "inherit" && node.tier !== void 0 && node.tier !== "job") {
@@ -4016,7 +4175,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4016
4175
  if (node.harness !== void 0 && node.tier !== "job") {
4017
4176
  err("harness-requires-job-tier", "`harness` is only legal on a tier:'job' agent step", `${path}.harness`, id);
4018
4177
  }
4019
- const provider = node.type === "agent" ? classifyModelProvider(staticModelPin(node.model)) : null;
4178
+ const provider = node.type === "agent" ? classifyModelProvider(jobClassifiablePin(node.model)) : null;
4020
4179
  if (node.harness === "claude-code" && provider !== null && provider !== "anthropic") {
4021
4180
  err("harness-provider-mismatch", `harness:'claude-code' needs an Anthropic model (model "${node.type === "agent" ? node.model : ""}" is ${provider})`, `${path}.harness`, id);
4022
4181
  }
@@ -4040,6 +4199,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4040
4199
  }
4041
4200
  const pin = parsed.kind === "template" ? parsed.template.default : node.model;
4042
4201
  if (pin === void 0) return;
4202
+ if (isModelClassRef(pin)) return;
4043
4203
  const inContext = /* @__PURE__ */ __name4((message) => parsed.kind === "template" ? `${message} (the default of ${parsed.template.placeholder})` : message, "inContext");
4044
4204
  const registry = opts.approvedModels;
4045
4205
  if (registry === void 0) return;
@@ -4053,6 +4213,12 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4053
4213
  const resolved = normalizeModelId(pin, registry);
4054
4214
  if (!resolved.ok) err("model-unresolved", inContext(modelUnresolvedMessage(resolved)), `${path}.model`, id);
4055
4215
  }, "checkModel");
4216
+ const checkTaskClass = /* @__PURE__ */ __name4((node, path) => {
4217
+ if (node.type !== "agent" || node.taskClass === void 0) return;
4218
+ if (!opts.static) return;
4219
+ if (typeof node.model === "string" && node.model.trim()) return;
4220
+ 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`, `${path}.taskClass`, singleId(node));
4221
+ }, "checkTaskClass");
4056
4222
  const checkWorkspace = /* @__PURE__ */ __name4((node, path) => {
4057
4223
  const id = singleId(node);
4058
4224
  const ws = workspaceOf(node);
@@ -4139,6 +4305,7 @@ function validateLuaExtensions(g, caps = WORKFLOW_CAPS_DEFAULT, opts = {
4139
4305
  checkTimeout(node, path);
4140
4306
  checkTier(node, path);
4141
4307
  checkModel(node, path);
4308
+ checkTaskClass(node, path);
4142
4309
  checkRetry(node, path);
4143
4310
  checkWorkspace(node, path);
4144
4311
  if (!opts.static) {
@@ -7294,6 +7461,10 @@ var LuaWorkflow = class {
7294
7461
  maxDurationSeconds: cfg.budget?.maxDurationSeconds ?? (hitl ? WORKFLOW_HITL_MAX_DURATION_SECONDS : WORKFLOW_DEFAULT_MAX_DURATION_SECONDS)
7295
7462
  });
7296
7463
  const envelope = {
7464
+ // A plain build/push is ALWAYS marker 1 (plan 6.4's compatibility row: "a CLI test that a plain push of
7465
+ // such a definition stays at 1"). Moving a definition to 2 — the effort marker — is an explicit act
7466
+ // (`lua push --apply-effort`, or a new compose while assignment is on), never a side effect of the SDK
7467
+ // gaining an `effort` member.
7297
7468
  luaWorkflow: 1,
7298
7469
  budget,
7299
7470
  definition: defined({
@@ -7688,6 +7859,10 @@ var WorkflowBuilderImpl = class WorkflowBuilderImpl2 {
7688
7859
  promptTemplate: templateText(opts.prompt),
7689
7860
  outputSchema: schemaToJson(opts.outputSchema),
7690
7861
  model: opts.model,
7862
+ taskClass: opts.taskClass,
7863
+ requires: opts.requires,
7864
+ modelReason: opts.modelReason,
7865
+ effort: opts.effort,
7691
7866
  toolScope: opts.toolScope,
7692
7867
  systemPrompt: opts.systemPrompt,
7693
7868
  timeoutSeconds: opts.timeoutSeconds,