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.
- package/dist/api-exports.d.ts +278 -18
- package/dist/api-exports.js +433 -196
- package/dist/api-exports.js.map +1 -1
- package/dist/index.js +1319 -227
- package/dist/index.js.map +1 -1
- package/dist/voice/test/index.d.ts +18 -18
- package/dist/workflow-builder.d.ts +47 -0
- package/dist/workflow-builder.js +370 -195
- package/dist/workflow-builder.js.map +1 -1
- package/docs/README.md +2 -2
- package/docs/api/Workflows.md +1 -1
- package/package.json +3 -2
- package/scripts/compat-matrix-previous-cli.mjs +266 -0
- package/template/package.json +1 -1
package/dist/workflow-builder.js
CHANGED
|
@@ -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(
|
|
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,
|